chiark / gitweb /
floats rust compiles
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 4 Oct 2020 17:36:52 +0000 (18:36 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 4 Oct 2020 17:36:52 +0000 (18:36 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/bigfloat.rs

index d5714ebd3febcc896408c8b0376857ac9e1b40dd..914494cdff7dcacf59365fe83d52704a6e257a26 100644 (file)
@@ -119,14 +119,60 @@ impl Bigfloat {
 impl Bigfloat {
   #[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()? {
-      b'+' => Pos,
-      b'!' => Neg,
+    struct P<'s> (&'s str);
+    impl P<'_> {
+      #[throws(as Option)]
+      fn hex16(&mut self) -> u16 {
+        const L : usize = 4;
+        if self.0.len() < L { None? }
+        let (l, r) = self.0.split_at(L);
+        self.0 = r;
+        Sz::from_str_radix(l, 16).ok()?
+      }
+
+      #[throws(as Option)]
+      fn next(&mut self) -> char {
+        let r = self.0.chars().next()?;
+        self.0 = &self.0[1..];
+        r
+      }
+
+      #[throws(as Option)]
+      fn hex16_(&mut self) -> u16 {
+        let r = self.hex16()?;
+        if !matches!(self.next(), Some('_')) { None? }
+        r
+      }
+    }
+
+    let mut p = P(s);
+    let sign = match p.next()? {
+      '+' => Pos,
+      '!' => Neg,
       _ => None?,
     };
-    let limbs = vec![];
+    let exp = p.hex16();
+
+    let mut limbs = Vec::with_capacity(p.0.len() / 15);
+    loop {
+      match p.next() {
+        None => break,
+        Some(' ') => (),
+        _ => None?,
+      };
+      limbs.push([
+        p.hex16_()?,
+        p.hex16_()?,
+        p.hex16()?,
+      ]);
+    }
     Bigfloat::from_parts(sign, 0, &limbs)
   }
 }
+
+#[cfg(test)]
+mod test {
+  #[test]
+  fn bfparse() {
+  }
+}