diff --git a/TODO.md b/TODO.md index a380b8e..21ab78b 100644 --- a/TODO.md +++ b/TODO.md @@ -16,7 +16,6 @@ organiztion for a given configuration structure. Some options here could be # Minor Fixes and Polish * Full selector support. (i.e. expressions in the selector parts) -* JSON export -* YAML export * Error Reporting with Line, Column, and File information. -* All enums should use the tuple wrapping a concrete type pattern. \ No newline at end of file +* JSON export +* YAML export \ No newline at end of file diff --git a/src/ast.rs b/src/ast.rs index cf4f0bd..44155b7 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -395,6 +395,18 @@ pub enum Expression { Select(SelectDef), } +#[derive(Debug,PartialEq)] +pub struct LetDef { + pub name: Token, + pub value: Expression, +} + +#[derive(Debug,PartialEq)] +pub struct ImportDef { + pub path: Token, + pub name: Token, +} + /// Statement encodes a parsed Statement in the UCG AST. #[derive(Debug,PartialEq)] pub enum Statement { @@ -402,16 +414,10 @@ pub enum Statement { Expression(Expression), // Named bindings - Let { - name: Token, - value: Expression, - }, + Let(LetDef), // Include a file. - Import { - path: String, - name: Token, - }, + Import(ImportDef), } #[cfg(test)] diff --git a/src/build.rs b/src/build.rs index e07ea11..a8f3a75 100644 --- a/src/build.rs +++ b/src/build.rs @@ -355,7 +355,7 @@ impl Builder { fn build_stmt(&mut self, stmt: &Statement) -> BuildResult { match stmt { - &Statement::Let { name: ref sym, value: ref expr } => { + &Statement::Let(LetDef{ name: ref sym, value: ref expr }) => { let val = try!(self.eval_expr(expr)); self.last = Some(val.clone()); match self.out.entry(sym.into()) { @@ -370,17 +370,17 @@ impl Builder { } } } - &Statement::Import { path: ref val, name: ref sym } => { - if !self.files.contains(val) { + &Statement::Import(ImportDef{ path: ref val, name: ref sym }) => { + if !self.files.contains(&val.fragment) { // Only parse the file once on import. let positioned_sym = sym.into(); if self.assets.get(&positioned_sym).is_none() { let mut b = Self::new(); - try!(b.build_file(&val)); + try!(b.build_file(&val.fragment)); let fields: Vec<(Positioned, Rc)> = b.out.drain().collect(); let result = Rc::new(Val::Tuple(fields)); self.assets.entry(positioned_sym).or_insert(result.clone()); - self.files.insert(val.clone()); + self.files.insert(val.fragment.clone()); self.last = Some(result); } } @@ -1241,14 +1241,14 @@ mod test { #[test] fn test_let_statement() { let mut b = Builder::new(); - let stmt = Statement::Let { + let stmt = Statement::Let(LetDef { name: Token::new("foo", Position { line: 1, column: 1, }), value: Expression::Simple(Value::String(make_value_node("bar".to_string(), 1, 1))), - }; + }); b.build_stmt(&stmt).unwrap(); test_expr_to_val(vec![ (Expression::Simple(Value::Symbol(make_value_node("foo".to_string(), 1, 1))), diff --git a/src/parse.rs b/src/parse.rs index 17a046d..f30c8be 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -501,10 +501,10 @@ named!(expression_statement( Span ) -> Statement, ); fn tuple_to_let(t: (Token, Expression)) -> ParseResult { - Ok(Statement::Let { + Ok(Statement::Let(LetDef { name: t.0, value: t.1, - }) + })) } named!(let_statement( Span ) -> Statement, @@ -521,10 +521,10 @@ named!(let_statement( Span ) -> Statement, ); fn tuple_to_import(t: (Token, Token)) -> ParseResult { - Ok(Statement::Import { + Ok(Statement::Import(ImportDef { name: t.0, - path: t.1.fragment.to_string(), - }) + path: t.1, + })) } named!(import_statement( Span ) -> Statement, @@ -645,8 +645,14 @@ mod test { line: 1, fragment: "", }, - Statement::Import{ - path: "foo".to_string(), + Statement::Import(ImportDef{ + path: Token{ + fragment: "foo".to_string(), + pos: Position { + line: 1, + column: 8, + } + }, name: Token{ fragment: "foo".to_string(), pos: Position{ @@ -654,7 +660,7 @@ mod test { column: 17, }, } - } + }) ) ); @@ -669,7 +675,7 @@ mod test { line: 1, fragment: "", }, - Statement::Let{ + Statement::Let(LetDef{ name: Token{ fragment: "foo".to_string(), pos: Position { @@ -678,7 +684,7 @@ mod test { }, }, value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 11}))) - })); + }))); stmt = "1.0;"; let input = LocatedSpan::new(stmt); assert_eq!(statement(input), @@ -706,8 +712,14 @@ mod test { line: 1, offset: import_stmt.len(), }, - Statement::Import{ - path: "foo".to_string(), + Statement::Import(ImportDef{ + path: Token{ + fragment: "foo".to_string(), + pos: Position{ + line: 1, + column: 8, + }, + }, name: Token{ fragment: "foo".to_string(), pos: Position{ @@ -715,7 +727,7 @@ mod test { column: 17, }, } - } + }) ) ); } @@ -738,7 +750,7 @@ mod test { offset: let_stmt.len(), line: 1, }, - Statement::Let{name: Token{ + Statement::Let(LetDef{name: Token{ fragment: "foo".to_string(), pos: Position{ line: 1, @@ -746,7 +758,7 @@ mod test { }, }, value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 11}))) - })); + }))); let_stmt = "let foo= 1.0;"; assert_eq!(let_statement(LocatedSpan::new(let_stmt)), @@ -755,14 +767,14 @@ mod test { offset: let_stmt.len(), line: 1, }, - Statement::Let{name: Token{ + Statement::Let(LetDef{name: Token{ fragment: "foo".to_string(), pos: Position{ line: 1, column: 5, } }, - value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 10})))})); + value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 10})))}))); let_stmt = "let foo =1.0;"; assert_eq!(let_statement(LocatedSpan::new(let_stmt)), IResult::Done(LocatedSpan{ @@ -770,14 +782,14 @@ mod test { offset: let_stmt.len(), line: 1, }, - Statement::Let{name: Token{ + Statement::Let(LetDef{name: Token{ fragment: "foo".to_string(), pos: Position{ line: 1, column: 5, } }, - value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 10})))})); + value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 10})))}))); } #[test] @@ -1444,8 +1456,14 @@ mod test { assert_eq!(tpl.0.fragment, ""); assert_eq!(tpl.1, vec![ - Statement::Import{ - path: "mylib".to_string(), + Statement::Import(ImportDef{ + path: Token{ + fragment: "mylib".to_string(), + pos: Position{ + line: 1, + column: 8, + } + }, name: Token{ fragment: "lib".to_string(), pos: Position{ @@ -1453,8 +1471,8 @@ mod test { column: 19, } } - }, - Statement::Let{ + }), + Statement::Let(LetDef{ name: Token{ fragment: "foo".to_string(), pos: Position{ @@ -1463,7 +1481,7 @@ mod test { } }, value: Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 33}))) - }, + }), Statement::Expression( Expression::Binary( BinaryOpDef{