From ed945e4b6e21f31c81cd5548d9cb09a4b61b5ea7 Mon Sep 17 00:00:00 2001 From: Tiffany Bennett Date: Tue, 27 Sep 2016 10:58:17 -0400 Subject: [PATCH] Add parsing for substance definitions --- src/ast.rs | 9 +++++++++ src/gnu_units.rs | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ src/load.rs | 4 ++++ 3 files changed, 65 insertions(+) diff --git a/src/ast.rs b/src/ast.rs index af54976..91b740a 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -81,6 +81,14 @@ pub enum DatePattern { Space, } +#[derive(Debug)] +pub struct Property { + pub name: String, + pub input: Expr, + pub output: Expr, + pub doc: Option, +} + #[derive(Debug)] pub enum Def { Dimension, @@ -89,6 +97,7 @@ pub enum Def { SPrefix(Expr), Unit(Expr), Quantity(Expr), + Substance(Vec), Error(String), } diff --git a/src/gnu_units.rs b/src/gnu_units.rs index f40da9a..684ebbb 100644 --- a/src/gnu_units.rs +++ b/src/gnu_units.rs @@ -25,6 +25,8 @@ pub enum Token { Dash, Asterisk, Question, + LeftBrace, + RightBrace, Error(String), } @@ -65,6 +67,8 @@ impl<'a> Iterator for TokenIterator<'a> { '-' => Token::Dash, '+' => Token::Plus, '*' => Token::Asterisk, + '{' => Token::LeftBrace, + '}' => Token::RightBrace, '?' => if self.0.peek() == Some(&'?') { self.0.next(); let mut out = String::new(); @@ -315,6 +319,54 @@ pub fn parse(mut iter: &mut Iter) -> Defs { iter.next(); let expr = parse_expr(iter); map.push((name, Rc::new(Def::Quantity(expr)), doc.take())); + } else if let Some(&Token::LeftBrace) = iter.peek() { + // substance + iter.next(); + let mut props = vec![]; + let mut prop_doc = None; + loop { + let name = match iter.next().unwrap() { + Token::Ident(name) => name, + Token::Newline => { + line += 1; + continue + }, + Token::Eof => break, + Token::Doc(line) => { + prop_doc = match prop_doc.take() { + None => Some(line.trim().to_owned()), + Some(old) => Some(format!( + "{} {}", old.trim(), line.trim())), + }; + continue + }, + Token::RightBrace => + break, + x => { + println!("Expected property, got {:?}", x); + break + }, + }; + let input = parse_mul(iter); + match iter.next().unwrap() { + Token::Slash => (), + x => { + println!("Expected /, got {:?}", x); + break + } + } + let output = parse_mul(iter); + props.push(Property { + name: name, + input: input, + output: output, + doc: prop_doc.take() + }); + } + map.push(( + name, + Rc::new(Def::Substance(props)), + doc.take())); } else { // derived let expr = parse_expr(iter); diff --git a/src/load.rs b/src/load.rs index 7ed4933..ca5eab5 100644 --- a/src/load.rs +++ b/src/load.rs @@ -268,6 +268,10 @@ impl Context { Ok(_) => println!("Quantity {} is not a number", name), Err(e) => println!("Quantity {} is malformed: {}", name, e) }, + Def::Substance(ref props) => { + println!("{:#?}", props); + unimplemented!() + }, Def::Error(ref err) => println!("Def {}: {}", name, err), }; }