From: Ian Jackson Date: Sun, 4 Oct 2020 15:40:27 +0000 (+0100) Subject: wip bigfloat Rust X-Git-Tag: otter-0.2.0~767 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=b954cf8da448a53ca598b9db2eb00b5cd13275a3;p=otter.git wip bigfloat Rust Signed-off-by: Ian Jackson --- diff --git a/src/bigfloat.rs b/src/bigfloat.rs index d39244b6..21a40729 100644 --- a/src/bigfloat.rs +++ b/src/bigfloat.rs @@ -3,18 +3,72 @@ #![allow(unused_variables)] #![allow(dead_code)] #![allow(unused_mut)] +#![allow(unused_imports)] + +use crate::imports::*; enum Sign { Pos, Neg, } use Sign::*; -struct Bigfloat { - sign: Sign, - exp: u16, - limbs: [[u16;3]], +type Sz = u16; +type Limb = [u16;3]; + +pub struct Bigfloat(innards::Innards); + +mod innards { + use super::*; + use std::mem::{self, align_of, size_of}; + use std::ptr::{self, NonNull}; + use std::alloc::{alloc, Layout}; + + pub type Innards = NonNull; + + struct Header { + sign: Sign, + exp: Sz, + nlimbs: Sz, + } + + #[repr(C)] + struct Repr { + h: Header, + limbs: [Limb], + } + + const OFFSET : usize = { + let h_size = size_of::
(); + let l_align = align_of::(); + l_align * ((h_size + l_align - 1) / l_align) + }; + + impl Bigfloat { + pub(in super) fn from_parts(sign: Sign, exp: Sz, limbs: &[Limb]) -> Bigfloat { + let nlimbs_u = limbs.len(); + let nlimbs_sz : Sz = nlimbs_u.try_into().expect("limb count overflow"); + let limbs_nbytes = nlimbs_u * size_of::(); + let all_nbytes = OFFSET + limbs_nbytes; + let align = max(align_of::
(), align_of::()); + let layout = Layout::from_size_align(all_nbytes, align).unwrap(); + unsafe { + let p = alloc(layout); + let p_header : *mut Header = mem::transmute(p); + let p_limbs : *mut Limb = mem::transmute(p.add(OFFSET)); + ptr::write(p_header, Header { sign, exp, nlimbs: nlimbs_sz }); + ptr::copy_nonoverlapping(limbs.as_ptr(), p_limbs, nlimbs_u); + Bigfloat(NonNull::new(p).unwrap()) + } + } + } } +/*/ +impl Bigfloat { + fn from_parts(sign: Sign, exp: Sz, limbs: &[Limb]) { + Bigfloat(Innards::from_parts(sign, exp, limbs)) +*/ impl Bigfloat { - fn from_str(s: &str) -> Option> { + #[throws(as Option)] + fn from_str(s: &str) -> Self { let mut s = s.as_bytes(); let mut s = s.iter(); let sign = match *s.next()? { @@ -22,6 +76,7 @@ impl Bigfloat { b'!' => Neg, _ => None?, }; - panic!(); + let limbs = vec![]; + Bigfloat::from_parts(sign, 0, &limbs) } }