mirror of https://github.com/rm-dr/daisy
Added decimal -> rational parsing
parent
f97805b24e
commit
bb48a09cc7
|
@ -73,19 +73,21 @@ impl PreToken {
|
||||||
pub fn to_token(self) -> Result<Token, (LineLocation, ParserError)>{
|
pub fn to_token(self) -> Result<Token, (LineLocation, ParserError)>{
|
||||||
match self {
|
match self {
|
||||||
PreToken::PreNumber(l, s) => {
|
PreToken::PreNumber(l, s) => {
|
||||||
let n: f64 = match s.parse() {
|
|
||||||
Ok(n) => n,
|
let r = Quantity::new_rational_from_float_string(&s);
|
||||||
Err(_) => return Err((l, ParserError::BadNumber))
|
if r.is_none() {
|
||||||
};
|
return Err((l, ParserError::BadNumber))
|
||||||
return Ok(Token::Number(Quantity::new_rational_from_f64(n).unwrap()));
|
}
|
||||||
|
return Ok(Token::Number(r.unwrap()));
|
||||||
},
|
},
|
||||||
|
|
||||||
PreToken::PreWord(l, s) => {
|
PreToken::PreWord(l, s) => {
|
||||||
return Ok(match &s[..] {
|
return Ok(match &s[..] {
|
||||||
// Mathematical constants
|
// Mathematical constants
|
||||||
// 100 digits of each.
|
// 100 digits of each.
|
||||||
"π"|"pi" => { Token::Constant(Quantity::float_from_string("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067"), String::from("π")) },
|
"π"|"pi" => { Token::Constant(Quantity::new_float_from_string("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067"), String::from("π")) },
|
||||||
"e" => { Token::Constant(Quantity::float_from_string("2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713 8217852516642"), String::from("e")) },
|
"e" => { Token::Constant(Quantity::new_float_from_string("2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713 8217852516642"), String::from("e")) },
|
||||||
"phi"|"φ" => { Token::Constant(Quantity::float_from_string("1.618033988749894848204586834365638117720309179805762862135448622705260462818902449707207204189391137"), String::from("φ")) },
|
"phi"|"φ" => { Token::Constant(Quantity::new_float_from_string("1.618033988749894848204586834365638117720309179805762862135448622705260462818902449707207204189391137"), String::from("φ")) },
|
||||||
|
|
||||||
_ => { return Err((l, ParserError::Undefined(s))); }
|
_ => { return Err((l, ParserError::Undefined(s))); }
|
||||||
});
|
});
|
||||||
|
|
|
@ -101,7 +101,7 @@ impl Quantity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn float_from_string(s: &str) -> Quantity {
|
pub fn new_float_from_string(s: &str) -> Quantity {
|
||||||
let v = Float::parse(s);
|
let v = Float::parse(s);
|
||||||
return Quantity::Float {
|
return Quantity::Float {
|
||||||
v: Float::with_val(FLOAT_PRECISION, v.unwrap())
|
v: Float::with_val(FLOAT_PRECISION, v.unwrap())
|
||||||
|
@ -115,6 +115,12 @@ impl Quantity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_rational_from_string(s: &str) -> Quantity {
|
||||||
|
return Quantity::Rational {
|
||||||
|
v: RationalQ::from_string(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new_rational_from_f64(f: f64) ->
|
pub fn new_rational_from_f64(f: f64) ->
|
||||||
Option<Quantity> {
|
Option<Quantity> {
|
||||||
let r = RationalQ::from_f64(f);
|
let r = RationalQ::from_f64(f);
|
||||||
|
@ -128,6 +134,24 @@ impl Quantity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_rational_from_float_string(s: &str) -> Option<Quantity> {
|
||||||
|
|
||||||
|
let mut q = s.split(".");
|
||||||
|
let a = q.next().unwrap();
|
||||||
|
let b = q.next();
|
||||||
|
let b = if b.is_some() {b.unwrap()} else {""};
|
||||||
|
|
||||||
|
// Error conditions
|
||||||
|
if {
|
||||||
|
q.next().is_some() || // We should have at most one `.`
|
||||||
|
a.len() == 0 // We need something in the numerator
|
||||||
|
} { return None; }
|
||||||
|
|
||||||
|
return Some(Quantity::new_rational_from_string(
|
||||||
|
&format!("{a}{b}/1{}", "0".repeat(b.len()))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
pub fn to_float(&self) -> Float {
|
pub fn to_float(&self) -> Float {
|
||||||
match self {
|
match self {
|
||||||
Quantity::Float { v } => {v.clone()},
|
Quantity::Float { v } => {v.clone()},
|
||||||
|
|
|
@ -63,6 +63,11 @@ impl RationalQ {
|
||||||
return Some(RationalQ{ val: v.unwrap() });
|
return Some(RationalQ{ val: v.unwrap() });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_string(s: &str) -> RationalQ {
|
||||||
|
let v = Rational::from_str_radix(s, 10);
|
||||||
|
return RationalQ{ val: v.unwrap() };
|
||||||
|
}
|
||||||
|
|
||||||
pub fn to_float(&self) -> Float {
|
pub fn to_float(&self) -> Float {
|
||||||
Float::with_val(FLOAT_PRECISION, self.val.numer()) /
|
Float::with_val(FLOAT_PRECISION, self.val.numer()) /
|
||||||
Float::with_val(FLOAT_PRECISION, self.val.denom())
|
Float::with_val(FLOAT_PRECISION, self.val.denom())
|
||||||
|
|
Loading…
Reference in New Issue