mirror of
https://github.com/tiffany352/rink-rs
synced 2024-11-10 13:44:15 +00:00
Handle prefixes better
This commit is contained in:
parent
ba948c7ae8
commit
4cc6fd4e59
2 changed files with 29 additions and 38 deletions
28
src/eval.rs
28
src/eval.rs
|
@ -11,7 +11,7 @@ pub struct Context {
|
|||
dimensions: Vec<String>,
|
||||
units: HashMap<String, Value>,
|
||||
aliases: HashMap<Unit, String>,
|
||||
prefixes: Vec<(String, f64)>,
|
||||
prefixes: Vec<(String, Value)>,
|
||||
}
|
||||
|
||||
impl Value {
|
||||
|
@ -143,11 +143,10 @@ impl Context {
|
|||
return Some(v)
|
||||
}
|
||||
}
|
||||
for &(ref pre, value) in &self.prefixes {
|
||||
for &(ref pre, ref value) in &self.prefixes {
|
||||
if name.starts_with(pre) {
|
||||
if let Some(mut v) = self.lookup(&name[pre.len()..]) {
|
||||
v.0 *= value;
|
||||
return Some(v)
|
||||
if let Some(v) = self.lookup(&name[pre.len()..]) {
|
||||
return Some(v.mul(&value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -201,9 +200,11 @@ impl Context {
|
|||
dimensions: Vec::new(),
|
||||
units: HashMap::new(),
|
||||
aliases: HashMap::new(),
|
||||
prefixes: defs.prefixes,
|
||||
prefixes: Vec::new(),
|
||||
};
|
||||
|
||||
ctx.prefixes.sort_by(|a, b| a.0.cmp(&b.0));
|
||||
|
||||
for (name, def) in defs.defs {
|
||||
match *def {
|
||||
Def::Dimension(ref name) => {
|
||||
|
@ -215,6 +216,19 @@ impl Context {
|
|||
},
|
||||
Err(e) => println!("Unit {} is malformed: {}", name, e)
|
||||
},
|
||||
Def::Prefix(ref expr) => match ctx.eval(expr) {
|
||||
Ok(v) => {
|
||||
ctx.prefixes.push((name.clone(), v));
|
||||
},
|
||||
Err(e) => println!("Prefix {} is malformed: {}", name, e)
|
||||
},
|
||||
Def::SPrefix(ref expr) => match ctx.eval(expr) {
|
||||
Ok(v) => {
|
||||
ctx.prefixes.push((name.clone(), v.clone()));
|
||||
ctx.units.insert(name.clone(), v);
|
||||
},
|
||||
Err(e) => println!("Prefix {} is malformed: {}", name, e)
|
||||
},
|
||||
Def::Error(ref err) => println!("Def {}: {}", name, err),
|
||||
};
|
||||
}
|
||||
|
@ -228,8 +242,6 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
ctx.prefixes.sort_by(|a, b| a.0.cmp(&b.0));
|
||||
|
||||
ctx
|
||||
}
|
||||
}
|
||||
|
|
|
@ -175,7 +175,7 @@ impl<'a> Iterator for TokenIterator<'a> {
|
|||
|
||||
pub type Iter<'a> = Peekable<TokenIterator<'a>>;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Expr {
|
||||
Unit(String),
|
||||
Const(f64),
|
||||
|
@ -190,6 +190,8 @@ pub enum Expr {
|
|||
#[derive(Debug)]
|
||||
pub enum Def {
|
||||
Dimension(String),
|
||||
Prefix(Expr),
|
||||
SPrefix(Expr),
|
||||
Unit(Expr),
|
||||
Error(String),
|
||||
}
|
||||
|
@ -198,7 +200,6 @@ pub enum Def {
|
|||
pub struct Defs {
|
||||
pub defs: Vec<(String, Rc<Def>)>,
|
||||
pub aliases: Vec<(Expr, String)>,
|
||||
pub prefixes: Vec<(String, f64)>,
|
||||
}
|
||||
|
||||
fn parse_term(mut iter: &mut Iter) -> Expr {
|
||||
|
@ -293,7 +294,6 @@ fn parse_alias(mut iter: &mut Iter) -> Option<(Expr, String)> {
|
|||
pub fn parse(mut iter: &mut Iter) -> Defs {
|
||||
let mut map = vec![];
|
||||
let mut aliases = vec![];
|
||||
let mut prefixes = vec![];
|
||||
loop {
|
||||
let mut copy = iter.clone();
|
||||
if let Some(a) = parse_alias(&mut copy) {
|
||||
|
@ -307,33 +307,13 @@ pub fn parse(mut iter: &mut Iter) -> Defs {
|
|||
Token::Eof => break,
|
||||
Token::Ident(name) => {
|
||||
let def = match iter.next().unwrap() {
|
||||
Token::ColonDash => match iter.next().unwrap() {
|
||||
Token::Number(n) => {
|
||||
prefixes.push((name, n));
|
||||
continue
|
||||
},
|
||||
Token::Ident(ref n) => {
|
||||
let mut found = None;
|
||||
for &(ref n2, value) in &prefixes {
|
||||
if n == n2 {
|
||||
found = Some(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if let Some(found) = found {
|
||||
prefixes.push((name, found));
|
||||
continue
|
||||
}
|
||||
Def::Error(format!("No such prefix {}", n))
|
||||
},
|
||||
x => Def::Error(format!("Expected number, got {:?}", x))
|
||||
Token::ColonDash => {
|
||||
let expr = parse_expr(iter);
|
||||
Def::Prefix(expr)
|
||||
},
|
||||
Token::DColonDash => match iter.next().unwrap() {
|
||||
Token::Number(n) => {
|
||||
prefixes.push((name.clone(), n));
|
||||
Def::Unit(Expr::Const(n))
|
||||
},
|
||||
x => Def::Error(format!("Expected number, got {:?}", x))
|
||||
Token::DColonDash => {
|
||||
let expr = parse_expr(iter);
|
||||
Def::SPrefix(expr)
|
||||
},
|
||||
Token::EqBangEq => match iter.next().unwrap() {
|
||||
Token::Ident(val) => Def::Dimension(val),
|
||||
|
@ -371,7 +351,6 @@ pub fn parse(mut iter: &mut Iter) -> Defs {
|
|||
Defs {
|
||||
defs: map,
|
||||
aliases: aliases,
|
||||
prefixes: prefixes,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue