From 4f3cc3dbf6773d6d8471b4f6b0476ba29614da70 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Mon, 6 Nov 2017 21:06:30 -0600 Subject: [PATCH] Thread position information through to more places. --- src/ast.rs | 101 ++++++---- src/build.rs | 236 +++++++++++------------ src/parse.rs | 535 ++++++++++++++++++++++++++------------------------- 3 files changed, 453 insertions(+), 419 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index d23ac6c..2e24b4f 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -14,6 +14,12 @@ use std::collections::HashSet; use std::borrow::Borrow; use std::convert::Into; +use std::cmp::Ordering; +use std::cmp::PartialOrd; +use std::cmp::Eq; +use std::cmp::PartialEq; +use std::hash::Hasher; +use std::hash::Hash; #[derive(Debug,PartialEq,Eq,Clone,PartialOrd,Ord,Hash)] pub struct Position { @@ -28,15 +34,7 @@ pub struct Token { } impl Token { - pub fn new(f: &str) -> Self { - Self::new_with_pos(f, - Position { - line: 0, - column: 0, - }) - } - - pub fn new_with_pos(f: &str, pos: Position) -> Self { + pub fn new(f: &str, pos: Position) -> Self { Token { fragment: f.to_string(), pos: pos, @@ -51,11 +49,8 @@ impl Borrow for Token { } macro_rules! value_node { - ($v:expr) => { - LocatedNode::new($v) - }; ($v:expr, $p:expr) => { - LocatedNode::new_with_pos($v, $p) + LocatedNode::new($v, $p) }; } @@ -64,21 +59,15 @@ pub type SelectorList = Vec; // str is expected to always be a symbol. #[derive(Debug,PartialEq,Clone)] pub struct LocatedNode { - pub pos: Option, + // TODO(jwall): Make this non-optional, Should we just use positioned instead? + pub pos: Position, pub val: T, } impl LocatedNode { - pub fn new(v: T) -> Self { + pub fn new>(v: T, pos: P) -> Self { Self { - pos: None, - val: v, - } - } - - pub fn new_with_pos>(v: T, pos: P) -> Self { - Self { - pos: Some(pos.into()), + pos: pos.into(), val: v, } } @@ -89,8 +78,9 @@ impl LocatedNode { } -pub fn make_value_node(v: T) -> LocatedNode { - LocatedNode::new(v) +// TODO(jwall): This should take a line and a column as argumentsn now. +pub fn make_value_node(v: T, line: usize, column: usize) -> LocatedNode { + LocatedNode::new(v, Position{line: line, column: column}) } /// Value represents a Value in the UCG parsed AST. @@ -141,7 +131,7 @@ impl Value { } } - pub fn pos(&self) -> &Option { + pub fn pos(&self) -> &Position { match self { &Value::Int(ref i) => &i.pos, &Value::Float(ref f) => &f.pos, @@ -173,7 +163,7 @@ pub struct SelectDef { } // TODO(jwall): This should have a way of rendering with position information. -#[derive(PartialEq,Debug,Eq,PartialOrd,Ord,Clone,Hash)] +#[derive(Debug,Clone)] pub struct Positioned { pub pos: Option, pub val: T, @@ -195,6 +185,33 @@ impl Positioned { } } +impl PartialEq for Positioned { + fn eq(&self, other: &Self) -> bool { + self.val == other.val + } +} + +impl Eq for Positioned { +} + +impl Ord for Positioned { + fn cmp(&self, other: &Self) -> Ordering { + self.val.cmp(&other.val) + } +} + +impl PartialOrd for Positioned { + fn partial_cmp(&self, other: &Self) -> Option { + self.val.partial_cmp(&other.val) + } +} + +impl Hash for Positioned { + fn hash(&self, state: &mut H) { + self.val.hash(state); + } +} + impl<'a> From<&'a Token> for Positioned { fn from(t: &'a Token) -> Positioned { Positioned { @@ -207,7 +224,7 @@ impl<'a> From<&'a Token> for Positioned { impl<'a> From<&'a LocatedNode> for Positioned { fn from(t: &LocatedNode) -> Positioned { Positioned { - pos: t.pos.clone(), + pos: Some(t.pos.clone()), val: t.val.clone(), } } @@ -401,10 +418,10 @@ mod ast_test { Positioned::new("foo".to_string()) ], fields: vec![ - (Token::new("f1"), Expression::Binary(BinaryOpDef{ + (Token::new("f1", Position { line: 1, column: 1}), Expression::Binary(BinaryOpDef{ kind: BinaryExprType::Add, - left: Value::Symbol(make_value_node("foo".to_string())), - right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + left: Value::Symbol(make_value_node("foo".to_string(), 1, 1)), + right: Box::new(Expression::Simple(Value::Int(make_value_node(1, 1, 1)))), pos: None, })), ], @@ -420,10 +437,10 @@ mod ast_test { Positioned::new("foo".to_string()) ], fields: vec![ - (Token::new("f1"), Expression::Binary(BinaryOpDef{ + (Token::new("f1", Position{line: 1, column: 1}), Expression::Binary(BinaryOpDef{ kind: BinaryExprType::Add, - left: Value::Symbol(make_value_node("bar".to_string())), - right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + left: Value::Symbol(make_value_node("bar".to_string(), 1, 1)), + right: Box::new(Expression::Simple(Value::Int(make_value_node(1, 1, 1)))), pos: None, })), ], @@ -441,10 +458,12 @@ mod ast_test { Positioned::new("foo".to_string()) ], fields: vec![ - (Token::new("f1"), Expression::Binary(BinaryOpDef{ + (Token::new("f1", Position{line: 1, column: 1}), Expression::Binary(BinaryOpDef{ kind: BinaryExprType::Add, - left: Value::Selector(make_value_node(vec![Token::new("foo"), Token::new("quux")])), - right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + left: Value::Selector(make_value_node(vec![ + Token::new("foo", Position{line: 1, column: 1}), + Token::new("quux", Position{line: 1, column: 1})], 1, 1)), + right: Box::new(Expression::Simple(Value::Int(make_value_node(1, 1, 1)))), pos: None, })), ], @@ -460,10 +479,12 @@ mod ast_test { Positioned::new("foo".to_string()), ], fields: vec![ - (Token::new("f1"), Expression::Binary(BinaryOpDef{ + (Token::new("f1", Position{line: 1, column: 1}), Expression::Binary(BinaryOpDef{ kind: BinaryExprType::Add, - left: Value::Selector(make_value_node(vec![Token::new("bar"), Token::new("quux")])), - right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + left: Value::Selector(make_value_node(vec![ + Token::new("bar", Position{line: 1, column: 1}), + Token::new("quux", Position{line: 1, column: 1})], 1, 1)), + right: Box::new(Expression::Simple(Value::Int(make_value_node(1, 1, 1)))), pos: None, })), ], diff --git a/src/build.rs b/src/build.rs index 0bb0ec9..6fa8a3f 100644 --- a/src/build.rs +++ b/src/build.rs @@ -43,9 +43,9 @@ impl MacroDef { // If the expressions reference Symbols not defined in the MacroDef that is also an error. // TODO(jwall): We should probably enforce that the Expression Symbols must be in argdefs rules // at Macro definition time not evaluation time. - let mut scope = HashMap::>::new(); + let mut scope = HashMap::, Rc>::new(); for (i, arg) in args.drain(0..).enumerate() { - scope.entry(self.argdefs[i].val.clone()).or_insert(arg.clone()); + scope.entry(self.argdefs[i].clone()).or_insert(arg.clone()); } let b = Builder::new_with_scope(scope); let mut result: Vec<(Positioned, Rc)> = Vec::new(); @@ -217,7 +217,7 @@ impl From for String { } /// ValueMap defines a set of values in a parsed file. -type ValueMap = HashMap>; +type ValueMap = HashMap, Rc>; /// Builder parses one or more statements into a out Tuple. pub struct Builder { @@ -285,7 +285,7 @@ impl Builder { } } - pub fn new_with_scope(scope: HashMap>) -> Self { + pub fn new_with_scope(scope: ValueMap) -> Self { Builder { assets: HashMap::new(), files: HashSet::new(), @@ -331,7 +331,7 @@ impl Builder { &Statement::Let { name: ref sym, value: ref expr } => { let val = try!(self.eval_expr(expr)); self.last = Some(val.clone()); - match self.out.entry(sym.fragment.clone()) { + match self.out.entry(sym.into()) { Entry::Occupied(e) => { return Err(Box::new(BuildError::DuplicateBinding(format!("Let binding \ for {:?} already \ @@ -346,14 +346,14 @@ impl Builder { &Statement::Import { path: ref val, name: ref sym } => { if !self.files.contains(val) { // Only parse the file once on import. - if self.assets.get(&sym.fragment).is_none() { + let positioned_sym = sym.into(); + if self.assets.get(&positioned_sym).is_none() { let mut b = Self::new(); try!(b.build_file(&val)); let fields: Vec<(Positioned, Rc)> = - b.out.drain().map(|t| (Positioned::new(t.0), t.1)) - .collect(); + b.out.drain().collect(); let result = Rc::new(Val::Tuple(fields)); - self.assets.entry(sym.fragment.clone()).or_insert(result.clone()); + self.assets.entry(positioned_sym).or_insert(result.clone()); self.files.insert(val.clone()); self.last = Some(result); } @@ -367,11 +367,11 @@ impl Builder { } fn lookup_sym(&self, sym: &Positioned) -> Option> { - if self.out.contains_key(&sym.val) { - return Some(self.out[&sym.val].clone()); + if self.out.contains_key(sym) { + return Some(self.out[sym].clone()); } - if self.assets.contains_key(&sym.val) { - return Some(self.assets[&sym.val].clone()); + if self.assets.contains_key(sym) { + return Some(self.assets[sym].clone()); } None } @@ -569,10 +569,10 @@ impl Builder { &Expression::Copy(ref def) => { let v = try!(self.lookup_selector(&def.selector)); if let Val::Tuple(ref src_fields) = *v { - let mut m = HashMap::<&String, Rc>::new(); - // loop through fields and build up a hasmap + let mut m = HashMap::, Rc>::new(); + // loop through fields and build up a hahsmap for &(ref key, ref val) in src_fields.iter() { - if let Entry::Vacant(v) = m.entry(&key.val) { + if let Entry::Vacant(v) = m.entry(key.clone()) { v.insert(val.clone()); } else { return Err(Box::new(BuildError::TypeFail(format!("Duplicate \ @@ -583,7 +583,7 @@ impl Builder { } for &(ref key, ref val) in def.fields.iter() { let expr_result = try!(self.eval_expr(val)); - match m.entry(&key.fragment) { + match m.entry(key.into()) { Entry::Vacant(v) => { v.insert(expr_result); } @@ -601,9 +601,7 @@ impl Builder { } }; } - let mut new_fields: Vec<(Positioned, Rc)> = m.drain() - .map(|(s, v)| (Positioned::new(s.to_string()), v)) - .collect(); + let mut new_fields: Vec<(Positioned, Rc)> = m.drain().collect(); // We want a stable order for the fields to make comparing tuples // easier in later code. So we sort by the field name before constructing a new tuple. new_fields.sort_by(|a, b| a.0.cmp(&b.0)); @@ -697,16 +695,16 @@ mod test { (Expression::Binary( BinaryOpDef{ kind: BinaryExprType::Div, - left: Value::Int(make_value_node(2)), - right: Box::new(Expression::Simple(Value::Int(make_value_node(2)))), + left: Value::Int(make_value_node(2, 1, 1)), + right: Box::new(Expression::Simple(Value::Int(make_value_node(2, 1, 1)))), pos: None, }), Val::Int(1)), (Expression::Binary( BinaryOpDef{ kind: BinaryExprType::Div, - left: Value::Float(make_value_node(2.0)), - right: Box::new(Expression::Simple(Value::Float(make_value_node(2.0)))), + left: Value::Float(make_value_node(2.0, 1, 1)), + right: Box::new(Expression::Simple(Value::Float(make_value_node(2.0, 1, 1)))), pos: None, }), Val::Float(1.0)), @@ -722,8 +720,8 @@ mod test { (Expression::Binary( BinaryOpDef{ kind: BinaryExprType::Div, - left: Value::Float(make_value_node(2.0)), - right: Box::new(Expression::Simple(Value::Int(make_value_node(2)))), + left: Value::Float(make_value_node(2.0, 1, 1)), + right: Box::new(Expression::Simple(Value::Int(make_value_node(2, 1, 1)))), pos: None, }), Val::Float(1.0)), @@ -738,16 +736,16 @@ mod test { (Expression::Binary( BinaryOpDef{ kind: BinaryExprType::Mul, - left: Value::Int(make_value_node(2)), - right: Box::new(Expression::Simple(Value::Int(make_value_node(2)))), + left: Value::Int(make_value_node(2, 1, 1)), + right: Box::new(Expression::Simple(Value::Int(make_value_node(2, 1, 1)))), pos: None, }), Val::Int(4)), (Expression::Binary( BinaryOpDef{ kind: BinaryExprType::Mul, - left: Value::Float(make_value_node(2.0)), - right: Box::new(Expression::Simple(Value::Float(make_value_node(2.0)))), + left: Value::Float(make_value_node(2.0, 1, 1)), + right: Box::new(Expression::Simple(Value::Float(make_value_node(2.0, 1, 1)))), pos: None, }), Val::Float(4.0)), @@ -763,8 +761,8 @@ mod test { (Expression::Binary( BinaryOpDef{ kind: BinaryExprType::Mul, - left: Value::Float(make_value_node(2.0)), - right: Box::new(Expression::Simple(Value::Int(make_value_node(20)))), + left: Value::Float(make_value_node(2.0, 1, 1)), + right: Box::new(Expression::Simple(Value::Int(make_value_node(20, 1, 1)))), pos: None, }), Val::Float(1.0)), @@ -779,16 +777,16 @@ mod test { (Expression::Binary( BinaryOpDef{ kind: BinaryExprType::Sub, - left: Value::Int(make_value_node(2)), - right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + left: Value::Int(make_value_node(2, 1, 1)), + right: Box::new(Expression::Simple(Value::Int(make_value_node(1, 1, 1)))), pos: None, }), Val::Int(1)), (Expression::Binary( BinaryOpDef{ kind: BinaryExprType::Sub, - left: Value::Float(make_value_node(2.0)), - right: Box::new(Expression::Simple(Value::Float(make_value_node(1.0)))), + left: Value::Float(make_value_node(2.0, 1, 1)), + right: Box::new(Expression::Simple(Value::Float(make_value_node(1.0, 1, 1)))), pos: None, }), Val::Float(1.0)), @@ -804,8 +802,8 @@ mod test { (Expression::Binary( BinaryOpDef{ kind: BinaryExprType::Sub, - left: Value::Float(make_value_node(2.0)), - right: Box::new(Expression::Simple(Value::Int(make_value_node(2)))), + left: Value::Float(make_value_node(2.0, 1, 1)), + right: Box::new(Expression::Simple(Value::Int(make_value_node(2, 1, 1)))), pos: None, }), Val::Float(1.0)), @@ -820,24 +818,24 @@ mod test { (Expression::Binary( BinaryOpDef{ kind: BinaryExprType::Add, - left: Value::Int(make_value_node(1)), - right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + left: Value::Int(make_value_node(1, 1, 1)), + right: Box::new(Expression::Simple(Value::Int(make_value_node(1, 1, 1)))), pos: None, }), Val::Int(2)), (Expression::Binary( BinaryOpDef{ kind: BinaryExprType::Add, - left: Value::Float(make_value_node(1.0)), - right: Box::new(Expression::Simple(Value::Float(make_value_node(1.0)))), + left: Value::Float(make_value_node(1.0, 1, 1)), + right: Box::new(Expression::Simple(Value::Float(make_value_node(1.0, 1, 1)))), pos: None, }), Val::Float(2.0)), (Expression::Binary( BinaryOpDef{ kind: BinaryExprType::Add, - left: Value::String(make_value_node("foo".to_string())), - right: Box::new(Expression::Simple(Value::String(make_value_node("bar".to_string())))), + left: Value::String(make_value_node("foo".to_string(), 1, 1)), + right: Box::new(Expression::Simple(Value::String(make_value_node("bar".to_string(), 1, 1)))), pos: None, }), Val::String("foobar".to_string())), @@ -852,8 +850,8 @@ mod test { (Expression::Binary( BinaryOpDef{ kind: BinaryExprType::Add, - left: Value::Float(make_value_node(2.0)), - right: Box::new(Expression::Simple(Value::Int(make_value_node(2)))), + left: Value::Float(make_value_node(2.0, 1, 1)), + right: Box::new(Expression::Simple(Value::Int(make_value_node(2, 1, 1)))), pos: None, }), Val::Float(1.0)), @@ -864,14 +862,14 @@ mod test { #[test] fn test_eval_simple_expr() { test_expr_to_val(vec![ - (Expression::Simple(Value::Int(make_value_node(1))), Val::Int(1)), - (Expression::Simple(Value::Float(make_value_node(2.0))), Val::Float(2.0)), - (Expression::Simple(Value::String(make_value_node("foo".to_string()))), + (Expression::Simple(Value::Int(make_value_node(1, 1, 1))), Val::Int(1)), + (Expression::Simple(Value::Float(make_value_node(2.0, 1, 1))), Val::Float(2.0)), + (Expression::Simple(Value::String(make_value_node("foo".to_string(), 1, 1))), Val::String("foo".to_string())), (Expression::Simple(Value::Tuple(make_value_node(vec![ - (Token::new("bar"), Expression::Simple(Value::Int(make_value_node(1)))) - ]))), - Val::Tuple(vec![(Positioned::new_with_pos("bar".to_string(), Position{line: 0, column: 0}), + (Token::new("bar", Position{line: 1, column: 1}), Expression::Simple(Value::Int(make_value_node(1, 1, 1)))) + ], 1, 1))), + Val::Tuple(vec![(Positioned::new_with_pos("bar".to_string(), Position{line: 1, column: 1}), Rc::new(Val::Int(1)))])), ], Builder::new()); @@ -880,9 +878,9 @@ mod test { #[test] fn test_eval_simple_lookup_expr() { let mut b = Builder::new(); - b.out.entry("var1".to_string()).or_insert(Rc::new(Val::Int(1))); + b.out.entry(Positioned::new("var1".to_string())).or_insert(Rc::new(Val::Int(1))); test_expr_to_val(vec![ - (Expression::Simple(Value::Symbol(make_value_node("var1".to_string()))), Val::Int(1)), + (Expression::Simple(Value::Symbol(make_value_node("var1".to_string(), 1, 1))), Val::Int(1)), ], b); } @@ -890,8 +888,8 @@ mod test { #[test] fn test_eval_simple_lookup_error() { let mut b = Builder::new(); - b.out.entry("var1".to_string()).or_insert(Rc::new(Val::Int(1))); - let expr = Expression::Simple(Value::Symbol(make_value_node("var".to_string()))); + b.out.entry(Positioned::new("var1".to_string())).or_insert(Rc::new(Val::Int(1))); + let expr = Expression::Simple(Value::Symbol(make_value_node("var".to_string(), 1, 1))); assert!(b.eval_expr(&expr).is_err()); } @@ -899,20 +897,20 @@ mod test { fn test_eval_selector_expr() { // TODO(jwall): Tests for this expression. let mut b = Builder::new(); - b.out.entry("var1".to_string()).or_insert(Rc::new(Val::Tuple(vec![ + b.out.entry(Positioned::new("var1".to_string())).or_insert(Rc::new(Val::Tuple(vec![ (Positioned::new("lvl1".to_string()), Rc::new(Val::Tuple( vec![ (Positioned::new("lvl2".to_string()), Rc::new(Val::Int(3))), ] ))), ]))); - b.out.entry("var2".to_string()).or_insert(Rc::new(Val::Int(2))); + b.out.entry(Positioned::new("var2".to_string())).or_insert(Rc::new(Val::Int(2))); b.out - .entry("var3".to_string()) + .entry(Positioned::new("var3".to_string())) .or_insert(Rc::new(Val::Tuple(vec![(Positioned::new("lvl1".to_string()), Rc::new(Val::Int(4)))]))); test_expr_to_val(vec![ - (Expression::Simple(Value::Selector(make_value_node(vec![Token::new("var1")]))), Val::Tuple( + (Expression::Simple(Value::Selector(make_value_node(vec![Token::new("var1", Position{line: 1, column: 1})], 1, 1))), Val::Tuple( vec![ (Positioned::new("lvl1".to_string()), Rc::new(Val::Tuple( vec![ @@ -921,21 +919,21 @@ mod test { ))), ] )), - (Expression::Simple(Value::Selector(make_value_node(vec![Token::new("var1"), - Token::new("lvl1")]))), + (Expression::Simple(Value::Selector(make_value_node(vec![Token::new("var1", Position{line: 1, column: 1}), + Token::new("lvl1", Position{line: 1, column: 1})], 1, 1))), Val::Tuple( vec![ (Positioned::new("lvl2".to_string()), Rc::new(Val::Int(3))), ] )), - (Expression::Simple(Value::Selector(make_value_node(vec![Token::new("var1"), - Token::new("lvl1"), - Token::new("lvl2")]))), + (Expression::Simple(Value::Selector(make_value_node(vec![Token::new("var1", Position{line: 1, column: 1}), + Token::new("lvl1", Position{line: 1, column: 1}), + Token::new("lvl2", Position{line: 1, column: 1})], 1, 1))), Val::Int(3)), - (Expression::Simple(Value::Selector(make_value_node(vec![Token::new("var2")]))), + (Expression::Simple(Value::Selector(make_value_node(vec![Token::new("var2", Position{line: 1, column: 1})], 1, 1))), Val::Int(2)), - (Expression::Simple(Value::Selector(make_value_node(vec![Token::new("var3"), - Token::new("lvl1")]))), + (Expression::Simple(Value::Selector(make_value_node(vec![Token::new("var3", Position{line: 1, column: 1}), + Token::new("lvl1", Position{line: 1, column: 1})], 1, 1))), Val::Int(4)), ], b); } @@ -945,7 +943,7 @@ mod test { fn test_expr_copy_no_such_tuple() { let b = Builder::new(); test_expr_to_val(vec![ - (Expression::Copy(CopyDef{selector: vec![Token::new("tpl1")], fields: Vec::new(), pos: None}), + (Expression::Copy(CopyDef{selector: vec![Token::new("tpl1", Position{line: 1, column: 1})], fields: Vec::new(), pos: None}), Val::Tuple(Vec::new())), ], b); } @@ -954,9 +952,9 @@ mod test { #[should_panic(expected = "Expected Tuple got Integer")] fn test_expr_copy_not_a_tuple() { let mut b = Builder::new(); - b.out.entry("tpl1".to_string()).or_insert(Rc::new(Val::Int(1))); + b.out.entry(Positioned::new("tpl1".to_string())).or_insert(Rc::new(Val::Int(1))); test_expr_to_val(vec![ - (Expression::Copy(CopyDef{selector: vec![Token::new("tpl1")], fields: Vec::new(), pos: None}), + (Expression::Copy(CopyDef{selector: vec![Token::new("tpl1", Position{line: 1, column: 1})], fields: Vec::new(), pos: None}), Val::Tuple(Vec::new())), ], b); } @@ -965,19 +963,19 @@ mod test { #[should_panic(expected = "Expected type Integer for field fld1 but got String")] fn test_expr_copy_field_type_error() { let mut b = Builder::new(); - b.out.entry("tpl1".to_string()).or_insert(Rc::new(Val::Tuple(vec![ + b.out.entry(Positioned::new("tpl1".to_string())).or_insert(Rc::new(Val::Tuple(vec![ (Positioned::new("fld1".to_string()), Rc::new(Val::Int(1))), ]))); test_expr_to_val(vec![ (Expression::Copy( CopyDef{ - selector: vec![Token::new("tpl1")], - fields: vec![(Token::new("fld1"), - Expression::Simple(Value::String(make_value_node("2".to_string()))))], + selector: vec![Token::new("tpl1", Position{line: 1, column: 1})], + fields: vec![(Token::new("fld1", Position{line: 1, column: 1}), + Expression::Simple(Value::String(make_value_node("2".to_string(), 1, 1))))], pos: None}), Val::Tuple( vec![ - (Positioned::new("fld1".to_string()), Rc::new(Val::String("2".to_string()))), + (Positioned::new_with_pos("fld1".to_string(), Position{line: 1, column: 1}), Rc::new(Val::String("2".to_string()))), ], )), ], b); @@ -989,15 +987,15 @@ mod test { fn test_expr_copy() { // TODO(jwall): Tests for this expression. let mut b = Builder::new(); - b.out.entry("tpl1".to_string()).or_insert(Rc::new(Val::Tuple(vec![ + b.out.entry(Positioned::new("tpl1".to_string())).or_insert(Rc::new(Val::Tuple(vec![ (Positioned::new("fld1".to_string()), Rc::new(Val::Int(1))), ]))); test_expr_to_val(vec![ (Expression::Copy( CopyDef{ - selector: vec![Token::new("tpl1")], - fields: vec![(Token::new("fld2"), - Expression::Simple(Value::String(make_value_node("2".to_string()))))], + selector: vec![Token::new("tpl1", Position{line: 1, column: 1})], + fields: vec![(Token::new("fld2", Position{line: 1, column: 1}), + Expression::Simple(Value::String(make_value_node("2".to_string(), 1, 1))))], pos: None, }), // Add a new field to the copy @@ -1007,18 +1005,18 @@ mod test { // semantics though so at some point we should probably be less restrictive. vec![ (Positioned::new("fld1".to_string()), Rc::new(Val::Int(1))), - (Positioned::new("fld2".to_string()), Rc::new(Val::String("2".to_string()))), + (Positioned::new_with_pos("fld2".to_string(), Position{line: 1, column: 1}), Rc::new(Val::String("2".to_string()))), ], )), // Overwrite a field in the copy (Expression::Copy( CopyDef{ - selector: vec![Token::new("tpl1")], + selector: vec![Token::new("tpl1", Position{line: 1, column: 1})], fields: vec![ - (Token::new("fld1"), - Expression::Simple(Value::Int(make_value_node(3)))), - (Token::new("fld2"), - Expression::Simple(Value::String(make_value_node("2".to_string())))), + (Token::new("fld1", Position{line: 1, column: 1}), + Expression::Simple(Value::Int(make_value_node(3, 1, 1)))), + (Token::new("fld2", Position{line: 1, column: 1}), + Expression::Simple(Value::String(make_value_node("2".to_string(), 1, 1)))), ], pos: None, }), @@ -1029,7 +1027,7 @@ mod test { ], )), // The source tuple is still unmodified. - (Expression::Simple(Value::Selector(make_value_node(vec![Token::new("tpl1")]))), + (Expression::Simple(Value::Selector(make_value_node(vec![Token::new("tpl1", Position{line: 1, column: 1})], 1, 1))), Val::Tuple( vec![ (Positioned::new("fld1".to_string()), Rc::new(Val::Int(1))), @@ -1041,21 +1039,21 @@ mod test { #[test] fn test_macro_call() { let mut b = Builder::new(); - b.out.entry("tstmac".to_string()).or_insert(Rc::new(Val::Macro(MacroDef{ + b.out.entry(Positioned::new("tstmac".to_string())).or_insert(Rc::new(Val::Macro(MacroDef{ argdefs: vec![Positioned::new("arg1".to_string())], fields: vec![ - (Token::new("foo"), Expression::Simple(Value::Symbol(make_value_node("arg1".to_string())))), + (Token::new("foo", Position{line: 1, column: 1}), Expression::Simple(Value::Symbol(make_value_node("arg1".to_string(), 1, 1)))), ], pos: None, }))); test_expr_to_val(vec![ (Expression::Call(CallDef{ - macroref: vec![Token::new("tstmac")], - arglist: vec![Expression::Simple(Value::String(make_value_node("bar".to_string())))], + macroref: vec![Token::new("tstmac", Position{line: 1, column: 1})], + arglist: vec![Expression::Simple(Value::String(make_value_node("bar".to_string(), 1, 1)))], pos: None, }), Val::Tuple(vec![ - (Positioned::new_with_pos("foo".to_string(), Position{line: 0, column: 0}), + (Positioned::new_with_pos("foo".to_string(), Position{line: 1, column: 1}), Rc::new(Val::String("bar".to_string()))), ])), ], b); @@ -1066,19 +1064,19 @@ mod test { fn test_macro_hermetic() { let mut b = Builder::new(); b.out - .entry("arg1".to_string()) + .entry(Positioned::new("arg1".to_string())) .or_insert(Rc::new(Val::String("bar".to_string()))); - b.out.entry("tstmac".to_string()).or_insert(Rc::new(Val::Macro(MacroDef{ + b.out.entry(Positioned::new("tstmac".to_string())).or_insert(Rc::new(Val::Macro(MacroDef{ argdefs: vec![Positioned::new("arg2".to_string())], fields: vec![ - (Token::new("foo"), Expression::Simple(Value::Symbol(make_value_node("arg1".to_string())))), + (Token::new("foo", Position{line: 1, column: 1}), Expression::Simple(Value::Symbol(make_value_node("arg1".to_string(), 1, 1)))), ], pos: None, }))); test_expr_to_val(vec![ (Expression::Call(CallDef{ - macroref: vec![Token::new("tstmac")], - arglist: vec![Expression::Simple(Value::String(make_value_node("bar".to_string())))], + macroref: vec![Token::new("tstmac", Position{line: 1, column: 1})], + arglist: vec![Expression::Simple(Value::String(make_value_node("bar".to_string(), 1, 1)))], pos: None, }), Val::Tuple(vec![ @@ -1091,28 +1089,28 @@ mod test { fn test_select_expr() { let mut b = Builder::new(); b.out - .entry("foo".to_string()) + .entry(Positioned::new("foo".to_string())) .or_insert(Rc::new(Val::String("bar".to_string()))); b.out - .entry("baz".to_string()) + .entry(Positioned::new("baz".to_string())) .or_insert(Rc::new(Val::String("boo".to_string()))); test_expr_to_val(vec![ (Expression::Select(SelectDef{ - val: Box::new(Expression::Simple(Value::Symbol(make_value_node("foo".to_string())))), - default: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + val: Box::new(Expression::Simple(Value::Symbol(make_value_node("foo".to_string(), 1, 1)))), + default: Box::new(Expression::Simple(Value::Int(make_value_node(1, 1, 1)))), tuple: vec![ - (Token::new("foo"), Expression::Simple(Value::String(make_value_node("2".to_string())))), - (Token::new("bar"), Expression::Simple(Value::Int(make_value_node(2)))), + (Token::new("foo", Position{line: 1, column: 1}), Expression::Simple(Value::String(make_value_node("2".to_string(), 1, 1)))), + (Token::new("bar", Position{line: 1, column: 1}), Expression::Simple(Value::Int(make_value_node(2, 1, 1)))), ], pos: None, }), Val::Int(2)), (Expression::Select(SelectDef{ - val: Box::new(Expression::Simple(Value::Symbol(make_value_node("baz".to_string())))), - default: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + val: Box::new(Expression::Simple(Value::Symbol(make_value_node("baz".to_string(), 1, 1)))), + default: Box::new(Expression::Simple(Value::Int(make_value_node(1, 1, 1)))), tuple: vec![ - (Token::new("bar"), Expression::Simple(Value::Int(make_value_node(2)))), - (Token::new("quux"), Expression::Simple(Value::String(make_value_node("2".to_string())))), + (Token::new("bar", Position{line: 1, column: 1}), Expression::Simple(Value::Int(make_value_node(2, 1, 1)))), + (Token::new("quux", Position{line: 1, column: 1}), Expression::Simple(Value::String(make_value_node("2".to_string(), 1, 1)))), ], pos: None, }), @@ -1125,14 +1123,14 @@ mod test { #[should_panic(expected ="Expected String but got Integer in Select expression")] fn test_select_expr_not_a_string() { let mut b = Builder::new(); - b.out.entry("foo".to_string()).or_insert(Rc::new(Val::Int(4))); + b.out.entry(Positioned::new("foo".to_string())).or_insert(Rc::new(Val::Int(4))); test_expr_to_val(vec![ (Expression::Select(SelectDef{ - val: Box::new(Expression::Simple(Value::Symbol(make_value_node("foo".to_string())))), - default: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + val: Box::new(Expression::Simple(Value::Symbol(make_value_node("foo".to_string(), 1, 1)))), + default: Box::new(Expression::Simple(Value::Int(make_value_node(1, 1, 1)))), tuple: vec![ - (Token::new("bar"), Expression::Simple(Value::Int(make_value_node(2)))), - (Token::new("quux"), Expression::Simple(Value::String(make_value_node("2".to_string())))), + (Token::new("bar", Position{line: 1, column: 1}), Expression::Simple(Value::Int(make_value_node(2, 1, 1)))), + (Token::new("quux", Position{line: 1, column: 1}), Expression::Simple(Value::String(make_value_node("2".to_string(), 1, 1)))), ], pos: None, }), @@ -1144,12 +1142,12 @@ mod test { fn test_let_statement() { let mut b = Builder::new(); let stmt = Statement::Let { - name: Token::new("foo"), - value: Expression::Simple(Value::String(make_value_node("bar".to_string()))), + 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()))), + (Expression::Simple(Value::Symbol(make_value_node("foo".to_string(), 1, 1))), Val::String("bar".to_string())), ], b); @@ -1159,20 +1157,20 @@ mod test { fn test_build_file_string() { let mut b = Builder::new(); b.build_file_string("foo.ucg", "let foo = 1;".to_string()).unwrap(); - let key = "foo"; - assert!(b.out.contains_key(key)); + let key = Positioned::new("foo".to_string()); + assert!(b.out.contains_key(&key)); } #[test] fn test_asset_symbol_lookups() { let mut b = Builder::new(); - b.assets.entry("foo".to_string()).or_insert(Rc::new(Val::Tuple(vec![ + b.assets.entry(Positioned::new("foo".to_string())).or_insert(Rc::new(Val::Tuple(vec![ (Positioned::new("bar".to_string()), Rc::new(Val::Tuple(vec![ (Positioned::new("quux".to_string()), Rc::new(Val::Int(1))), ]))), ]))); test_expr_to_val(vec![ - (Expression::Simple(Value::Symbol(make_value_node("foo".to_string()))), + (Expression::Simple(Value::Symbol(make_value_node("foo".to_string(), 1, 1))), Val::Tuple(vec![ (Positioned::new("bar".to_string()), Rc::new(Val::Tuple(vec![ (Positioned::new("quux".to_string()), Rc::new(Val::Int(1))), diff --git a/src/parse.rs b/src/parse.rs index 9202721..bd5d269 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -13,6 +13,7 @@ // limitations under the License. use std::str::FromStr; use std::error::Error; +use std::borrow::Borrow; use ast::*; use tokenizer::*; @@ -32,20 +33,19 @@ quick_error! { } -// TODO(jwall): Convert to tokenizer steps followed by parser steps. // TODO(jwall): Error Reporting with Line and Column information. type ParseResult = Result>; fn symbol_to_value(s: Token) -> ParseResult { - Ok(Value::Symbol(value_node!(s.fragment.to_string()))) + Ok(Value::Symbol(value_node!(s.fragment.to_string(), s.pos))) } // symbol is a bare unquoted field. named!(symbol( Span ) -> Value, map_res!(barewordtok, symbol_to_value)); fn str_to_value(s: Token) -> ParseResult { - Ok(Value::String(value_node!(s.fragment.to_string()))) + Ok(Value::String(value_node!(s.fragment.to_string(), s.pos))) } // quoted_value is a quoted string. @@ -55,25 +55,30 @@ named!(quoted_value( Span ) -> Value, // Helper function to make the return types work for down below. fn triple_to_number(v: (Option, Option, Option)) -> ParseResult { - let pref = match v.0 { - None => "", - Some(ref bs) => &bs.fragment, + let (pref, mut pref_pos) = match v.0 { + None => ("", Position{line: 0, column: 0}), + Some(ref bs) => (bs.fragment.borrow(), bs.pos.clone()), }; let has_dot = v.1.is_some(); if v.0.is_some() && !has_dot && v.2.is_none() { - return Ok(Value::Int(value_node!(try!(FromStr::from_str(pref))))); + return Ok(Value::Int(value_node!(try!(FromStr::from_str(pref)), pref_pos))); } + if v.0.is_none() && has_dot { + pref_pos = v.1.unwrap().pos; + } + let suf = match v.2 { None => "", Some(ref bs) => &bs.fragment, }; let to_parse = pref.to_string() + "." + suf; + // TODO(jwall): if there is an error we should report where that error occured. let f = try!(FromStr::from_str(&to_parse)); - return Ok(Value::Float(value_node!(f))); + return Ok(Value::Float(value_node!(f, pref_pos))); } // NOTE(jwall): HERE THERE BE DRAGONS. The order for these matters @@ -130,8 +135,8 @@ named!( ); // Helper function to make the return types work for down below. -fn vec_to_tuple(v: FieldList) -> ParseResult { - Ok(Value::Tuple(value_node!(v))) +fn vec_to_tuple(t: (Span, FieldList)) -> ParseResult { + Ok(Value::Tuple(value_node!(t.1, Position{line: t.0.line as usize, column: t.0.offset as usize}))) } named!(field_list( Span ) -> FieldList, @@ -141,9 +146,13 @@ named!( #[doc="Capture a tuple of named fields with values. {=,...}"], tuple( Span ) -> Value, map_res!( - delimited!(lbracetok, + do_parse!( + pos: position!() >> + v: delimited!(lbracetok, ws!(field_list), - rbracetok), + rbracetok) >> + (pos, v) + ), vec_to_tuple ) ); @@ -161,12 +170,12 @@ named!(simple_expression( Span ) -> Expression, ) ); -fn tuple_to_binary_expression(tpl: (BinaryExprType, Value, Expression)) -> ParseResult { +fn tuple_to_binary_expression(tpl: (Span, BinaryExprType, Value, Expression)) -> ParseResult { Ok(Expression::Binary(BinaryOpDef { - kind: tpl.0, - left: tpl.1, - right: Box::new(tpl.2), - pos: None, + kind: tpl.1, + left: tpl.2, + right: Box::new(tpl.3), + pos: Some(Position{line: tpl.0.line as usize, column: tpl.0.offset as usize}), })) } @@ -178,10 +187,11 @@ macro_rules! do_binary_expr { // particularly like this but I'm living with it for now. map_res!( $i, do_parse!( + pos: position!() >> left: value >> ws!($fn) >> right: expression >> - ($typ, left, right) + (pos, $typ, left, right) ), tuple_to_binary_expression ) @@ -222,7 +232,6 @@ fn assert_nonempty_list(v: Vec) -> ParseResult> { return Ok(v); } -// TODO(jwall): We should assert that this is a nonempty list that comes out of here. named!(selector_list( Span ) -> SelectorList, map_res!( separated_list!(dottok, barewordtok), @@ -230,43 +239,43 @@ named!(selector_list( Span ) -> SelectorList, ) ); -fn tuple_to_copy(t: (SelectorList, FieldList)) -> ParseResult { +fn tuple_to_copy(t: (Span, SelectorList, FieldList)) -> ParseResult { Ok(Expression::Copy(CopyDef { - selector: t.0, - fields: t.1, - pos: None, + selector: t.1, + fields: t.2, + pos: Some(Position{line: t.0.line as usize, column: t.0.offset as usize}), })) } named!(copy_expression( Span ) -> Expression, map_res!( do_parse!( + pos: position!() >> selector: selector_list >> - lbracetok >> - fields: ws!(field_list) >> - rbracetok >> - (selector, fields) + lbracetok >> + fields: ws!(field_list) >> + rbracetok >> + (pos, selector, fields) ), tuple_to_copy ) ); -fn tuple_to_macro(mut t: (Vec, Value)) -> ParseResult { - match t.1 { +fn tuple_to_macro(mut t: (Span, Vec, Value)) -> ParseResult { + match t.2 { Value::Tuple(v) => { Ok(Expression::Macro(MacroDef { - // TODO(jwall): The position information here is not as accurate as we might want. - argdefs: t.0 + argdefs: t.1 .drain(0..) .map(|s| { Positioned { - pos: v.pos.clone(), + pos: Some(s.pos().clone()), val: s.to_string(), } }) .collect(), fields: v.val, - pos: v.pos, + pos: Some(Position{line: t.0.line as usize, column: t.0.offset as usize}), })) } // TODO(jwall): Show a better version of the unexpected parsed value. @@ -281,26 +290,27 @@ named!(arglist( Span ) -> Vec, separated_list!(ws!(commatok), symbol)); named!(macro_expression( Span ) -> Expression, map_res!( do_parse!( - macrotok >> - ws!(lparentok) >> - arglist: ws!(arglist) >> - rparentok >> - ws!(fatcommatok) >> - map: tuple >> - (arglist, map) + pos: position!() >> + macrotok >> + ws!(lparentok) >> + arglist: ws!(arglist) >> + rparentok >> + ws!(fatcommatok) >> + map: tuple >> + (pos, arglist, map) ), tuple_to_macro ) ); -fn tuple_to_select(t: (Expression, Expression, Value)) -> ParseResult { - match t.2 { +fn tuple_to_select(t: (Span, Expression, Expression, Value)) -> ParseResult { + match t.3 { Value::Tuple(v) => { Ok(Expression::Select(SelectDef { - val: Box::new(t.0), - default: Box::new(t.1), + val: Box::new(t.1), + default: Box::new(t.2), tuple: v.val, - pos: None, + pos: Some(Position{line: t.0.line as usize, column: t.0.offset as usize}), })) } // TODO(jwall): Show a better version of the unexpected parsed value. @@ -313,11 +323,12 @@ fn tuple_to_select(t: (Expression, Expression, Value)) -> ParseResult Expression, map_res!( do_parse!( + pos: position!() >> selecttok >> - val: ws!(terminated!(expression, commatok)) >> - default: ws!(terminated!(expression, commatok)) >> - map: ws!(tuple) >> - (val, default, map) + val: ws!(terminated!(expression, commatok)) >> + default: ws!(terminated!(expression, commatok)) >> + map: ws!(tuple) >> + (pos, val, default, map) ), tuple_to_select ) @@ -345,25 +356,29 @@ named!(format_expression( Span ) -> Expression, ) ); -fn tuple_to_call(t: (Value, Vec)) -> ParseResult { - if let Value::Selector(sl) = t.0 { +fn tuple_to_call(t: (Span, Value, Vec)) -> ParseResult { + if let Value::Selector(sl) = t.1 { Ok(Expression::Call(CallDef { macroref: sl.val, - arglist: t.1, - pos: None, + arglist: t.2, + pos: Some(Position{line: t.0.line as usize, column: t.0.offset as usize}), })) } else { Err(Box::new(ParseError::UnexpectedToken("Selector".to_string(), format!("{:?}", t.0)))) } } -fn vec_to_selector_value(v: SelectorList) -> ParseResult { - Ok(Value::Selector(value_node!(v))) +fn vec_to_selector_value(t: (Span, SelectorList)) -> ParseResult { + Ok(Value::Selector(value_node!(t.1, Position{line: t.0.line as usize, column: t.0.offset as usize}))) } named!(selector_value( Span ) -> Value, map_res!( - ws!(selector_list), + do_parse!( + pos: position!() >> + sl: ws!(selector_list) >> + (pos, sl) + ), vec_to_selector_value ) ); @@ -371,11 +386,12 @@ named!(selector_value( Span ) -> Value, named!(call_expression( Span ) -> Expression, map_res!( do_parse!( + pos: position!() >> macroname: selector_value >> - lparentok >> - args: ws!(separated_list!(ws!(commatok), expression)) >> - rparentok >> - (macroname, args) + lparentok >> + args: ws!(separated_list!(ws!(commatok), expression)) >> + rparentok >> + (pos, macroname, args) ), tuple_to_call ) @@ -468,8 +484,6 @@ named!(statement( Span ) -> Statement, named!(pub parse( Span ) -> Vec, many1!(ws!(statement))); -// TODO(jwall): Full Statement parsing tests. - #[cfg(test)] mod test { use super::{Statement, Expression, Value, MacroDef, SelectDef, CallDef}; @@ -525,7 +539,7 @@ mod test { column: 5, }, }, - value: Expression::Simple(Value::Float(value_node!(1.0))) + value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 11}))) })); stmt = "1.0;"; let input = LocatedSpan::new(stmt); @@ -537,7 +551,7 @@ mod test { fragment: "", }, Statement::Expression( - Expression::Simple(Value::Float(value_node!(1.0)))))); + Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 1})))))); } #[test] @@ -593,7 +607,7 @@ mod test { column: 5, }, }, - value: Expression::Simple(Value::Float(value_node!(1.0))) + value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 11}))) })); let_stmt = "let foo= 1.0;"; @@ -610,7 +624,7 @@ mod test { column: 5, } }, - value: Expression::Simple(Value::Float(value_node!(1.0)))})); + 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{ @@ -625,7 +639,7 @@ mod test { column: 5, } }, - value: Expression::Simple(Value::Float(value_node!(1.0)))})); + value: Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 10})))})); } #[test] @@ -638,7 +652,7 @@ mod test { line: 1, }, Statement::Expression( - Expression::Simple(Value::Float(value_node!(1.0)))))); + Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 1})))))); assert_eq!(expression_statement(LocatedSpan::new("1.0 ;")), IResult::Done(LocatedSpan { fragment: "", @@ -646,7 +660,7 @@ mod test { line: 1, }, Statement::Expression( - Expression::Simple(Value::Float(value_node!(1.0)))))); + Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 1})))))); assert_eq!(expression_statement(LocatedSpan::new(" 1.0;")), IResult::Done(LocatedSpan { fragment: "", @@ -654,7 +668,7 @@ mod test { line: 1, }, Statement::Expression( - Expression::Simple(Value::Float(value_node!(1.0)))))); + Expression::Simple(Value::Float(value_node!(1.0, Position{line: 1, column: 2})))))); assert_eq!(expression_statement(LocatedSpan::new("foo;")), IResult::Done(LocatedSpan { fragment: "", @@ -662,7 +676,7 @@ mod test { line: 1, }, Statement::Expression( - Expression::Simple(Value::Symbol(value_node!("foo".to_string())))))); + Expression::Simple(Value::Symbol(value_node!("foo".to_string(), Position{line: 1, column: 1})))))); assert_eq!(expression_statement(LocatedSpan::new("foo ;")), IResult::Done(LocatedSpan { fragment: "", @@ -670,7 +684,7 @@ mod test { line: 1, }, Statement::Expression( - Expression::Simple(Value::Symbol(value_node!("foo".to_string())))))); + Expression::Simple(Value::Symbol(value_node!("foo".to_string(), Position{line: 1, column: 1})))))); assert_eq!(expression_statement(LocatedSpan::new(" foo;")), IResult::Done(LocatedSpan { fragment: "", @@ -678,7 +692,7 @@ mod test { line: 1, }, Statement::Expression( - Expression::Simple(Value::Symbol(value_node!("foo".to_string())))))); + Expression::Simple(Value::Symbol(value_node!("foo".to_string(), Position{line: 1, column: 2})))))); assert_eq!(expression_statement(LocatedSpan::new("\"foo\";")), IResult::Done(LocatedSpan { fragment: "", @@ -686,7 +700,7 @@ mod test { line: 1, }, Statement::Expression( - Expression::Simple(Value::String(value_node!("foo".to_string())))))); + Expression::Simple(Value::String(value_node!("foo".to_string(), Position{line: 1, column: 1})))))); assert_eq!(expression_statement(LocatedSpan::new("\"foo\" ;")), IResult::Done(LocatedSpan { fragment: "", @@ -694,7 +708,7 @@ mod test { line: 1, }, Statement::Expression( - Expression::Simple(Value::String(value_node!("foo".to_string())))))); + Expression::Simple(Value::String(value_node!("foo".to_string(), Position{line: 1, column: 1})))))); assert_eq!(expression_statement(LocatedSpan::new(" \"foo\";")), IResult::Done(LocatedSpan { fragment: "", @@ -702,7 +716,7 @@ mod test { line: 1, }, Statement::Expression( - Expression::Simple(Value::String(value_node!("foo".to_string())))))); + Expression::Simple(Value::String(value_node!("foo".to_string(), Position{line: 1, column: 2})))))); } #[test] @@ -713,186 +727,187 @@ mod test { offset: 1, line: 1, }, - Expression::Simple(Value::Int(value_node!(1))))); + Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 1}))))); assert_eq!(expression(LocatedSpan::new("foo")), IResult::Done(LocatedSpan { fragment: "", offset: 3, line: 1, }, - Expression::Simple(Value::Symbol(value_node!("foo".to_string()))))); + Expression::Simple(Value::Symbol(value_node!("foo".to_string(), Position{line: 1, column: 1}))))); assert_eq!(expression(LocatedSpan::new("1 + 1")), IResult::Done(LocatedSpan { fragment: "", offset: 5, line: 1, }, - Expression::Binary(BinaryOpDef{ - kind: BinaryExprType::Add, - left: Value::Int(value_node!(1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1)))), - pos: None, - }))); + Expression::Binary(BinaryOpDef{ + kind: BinaryExprType::Add, + left: Value::Int(value_node!(1, Position{line: 1, column: 1})), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 5})))), + pos: Some(Position { line: 1, column: 0 }), + }))); assert_eq!(expression(LocatedSpan::new("1 - 1")), IResult::Done(LocatedSpan { fragment: "", offset: 5, line: 1, }, - Expression::Binary(BinaryOpDef{ - kind: BinaryExprType::Sub, - left: Value::Int(value_node!(1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1)))), - pos: None, - }))); + Expression::Binary(BinaryOpDef{ + kind: BinaryExprType::Sub, + left: Value::Int(value_node!(1, Position{line: 1, column: 1})), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 5})))), + pos: Some(Position { line: 1, column: 0 }), + }))); assert_eq!(expression(LocatedSpan::new("1 * 1")), - IResult::Done(LocatedSpan { + IResult::Done(LocatedSpan { fragment: "", offset: 5, line: 1, }, - Expression::Binary(BinaryOpDef{ - kind: BinaryExprType::Mul, - left: Value::Int(value_node!(1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1)))), - pos: None, - }))); + Expression::Binary(BinaryOpDef{ + kind: BinaryExprType::Mul, + left: Value::Int(value_node!(1, Position{line: 1, column: 1})), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 5})))), + pos: Some(Position { line: 1, column: 0 }), + }))); assert_eq!(expression(LocatedSpan::new("1 / 1")), - IResult::Done(LocatedSpan { + IResult::Done(LocatedSpan { fragment: "", offset: 5, line: 1, }, - Expression::Binary(BinaryOpDef{ - kind: BinaryExprType::Div, - left: Value::Int(value_node!(1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1)))), - pos: None, - }))); + Expression::Binary(BinaryOpDef{ + kind: BinaryExprType::Div, + left: Value::Int(value_node!(1, Position{line: 1, column: 1})), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 5})))), + pos: Some(Position { line: 1, column: 0 }), + }))); assert_eq!(expression(LocatedSpan::new("1+1")), - IResult::Done(LocatedSpan { + IResult::Done(LocatedSpan { fragment: "", offset: 3, line: 1, }, - Expression::Binary(BinaryOpDef{ - kind: BinaryExprType::Add, - left: Value::Int(value_node!(1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1)))), - pos: None, - }))); + Expression::Binary(BinaryOpDef{ + kind: BinaryExprType::Add, + left: Value::Int(value_node!(1, Position{line: 1, column: 1})), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 3})))), + pos: Some(Position { line: 1, column: 0 }), + }))); assert_eq!(expression(LocatedSpan::new("1-1")), - IResult::Done(LocatedSpan { + IResult::Done(LocatedSpan { fragment: "", offset: 3, line: 1, }, - Expression::Binary(BinaryOpDef{ - kind: BinaryExprType::Sub, - left: Value::Int(value_node!(1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1)))), - pos: None, - }))); + Expression::Binary(BinaryOpDef{ + kind: BinaryExprType::Sub, + left: Value::Int(value_node!(1, Position{line: 1, column: 1})), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 3})))), + pos: Some(Position { line: 1, column: 0 }), + }))); assert_eq!(expression(LocatedSpan::new("1*1")), - IResult::Done(LocatedSpan { + IResult::Done(LocatedSpan { fragment: "", offset: 3, line: 1, }, - Expression::Binary(BinaryOpDef{ - kind: BinaryExprType::Mul, - left: Value::Int(value_node!(1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1)))), - pos: None, - }))); + Expression::Binary(BinaryOpDef{ + kind: BinaryExprType::Mul, + left: Value::Int(value_node!(1, Position{line: 1, column: 1})), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 3})))), + pos: Some(Position { line: 1, column: 0 }), + }))); assert_eq!(expression(LocatedSpan::new("1/1")), - IResult::Done(LocatedSpan { + IResult::Done(LocatedSpan { fragment: "", offset: 3, line: 1, }, - Expression::Binary(BinaryOpDef{ - kind: BinaryExprType::Div, - left: Value::Int(value_node!(1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1)))), - pos: None, - }))); + Expression::Binary(BinaryOpDef{ + kind: BinaryExprType::Div, + left: Value::Int(value_node!(1, Position{line: 1, column: 1})), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 3})))), + pos: Some(Position { line: 1, column: 0 }), + }))); let macro_expr = "macro (arg1, arg2) => { foo = arg1 }"; assert_eq!(expression(LocatedSpan::new(macro_expr)), - IResult::Done(LocatedSpan { + IResult::Done(LocatedSpan { fragment: "", offset: macro_expr.len(), line: 1, }, - Expression::Macro(MacroDef{ - argdefs: vec![ - Positioned::new("arg1".to_string()), - Positioned::new("arg2".to_string()), - ], - fields: vec![ - (Token::new_with_pos("foo", Position{line: 1, column: 25}), - Expression::Simple(Value::Symbol(value_node!("arg1".to_string())))), - ], - pos: None, - }) + Expression::Macro(MacroDef{ + argdefs: vec![ + Positioned::new_with_pos("arg1".to_string(), Position{line: 1, column: 8}), + Positioned::new_with_pos("arg2".to_string(), Position{line: 1, column: 14}), + ], + fields: vec![ + (Token::new("foo", Position{line: 1, column: 25}), + Expression::Simple(Value::Symbol(value_node!("arg1".to_string(), Position{line: 1, column: 31})))), + ], + // FIXME(jwall): I think this is incorrect. + pos: Some(Position{line: 1, column: 0}), + }) ) ); let select_expr = "select foo, 1, { foo = 2 }"; assert_eq!(expression(LocatedSpan::new(select_expr)), - IResult::Done(LocatedSpan { + IResult::Done(LocatedSpan { fragment: "", offset: select_expr.len(), line: 1, }, - Expression::Select(SelectDef{ - val: Box::new(Expression::Simple(Value::Symbol(value_node!("foo".to_string())))), - default: Box::new(Expression::Simple(Value::Int(value_node!(1)))), - tuple: vec![ - (Token::new_with_pos("foo", Position{line: 1, column: 18}), - Expression::Simple(Value::Int(value_node!(2)))) - ], - pos: None, - }) + Expression::Select(SelectDef{ + val: Box::new(Expression::Simple(Value::Symbol(value_node!("foo".to_string(), Position{line: 1, column: 8})))), + default: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 13})))), + tuple: vec![ + (Token::new("foo", Position{line: 1, column: 18}), + Expression::Simple(Value::Int(value_node!(2, Position{line: 1, column: 24})))) + ], + pos: Some(Position{line: 1, column: 0}), + }) ) ); - let call_expr = "foo.bar (1, \"foo\")"; - assert_eq!(expression(LocatedSpan::new(call_expr)), - IResult::Done(LocatedSpan { - fragment: "", - offset: call_expr.len(), - line: 1, - }, - Expression::Call(CallDef{ - macroref: vec![Token::new_with_pos("foo", Position{line:1,column: 1}), - Token::new_with_pos("bar", Position{line:1,column: 5})], - arglist: vec![ - Expression::Simple(Value::Int(value_node!(1))), - Expression::Simple(Value::String(value_node!("foo".to_string()))), - ], - pos: None, - }) - ) + let call_expr = "foo.bar (1, \"foo\")"; + assert_eq!(expression(LocatedSpan::new(call_expr)), + IResult::Done(LocatedSpan { + fragment: "", + offset: call_expr.len(), + line: 1, + }, + Expression::Call(CallDef{ + macroref: vec![Token::new("foo", Position{line:1,column: 1}), + Token::new("bar", Position{line:1,column: 5})], + arglist: vec![ + Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 10}))), + Expression::Simple(Value::String(value_node!("foo".to_string(), Position{line: 1, column: 13}))), + ], + pos: Some(Position{line: 1, column: 0}), + }) + ) ); - assert_eq!(expression(LocatedSpan::new("(1 + 1)")), - IResult::Done(LocatedSpan { - fragment: "", - offset: 7, - line: 1, - }, - Expression::Grouped( - Box::new( - Expression::Binary( - BinaryOpDef{ - kind: BinaryExprType::Add, - left: Value::Int(value_node!(1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1)))), - pos: None, - } - ) - ) - ) + assert_eq!(expression(LocatedSpan::new("(1 + 1)")), + IResult::Done(LocatedSpan { + fragment: "", + offset: 7, + line: 1, + }, + Expression::Grouped( + Box::new( + Expression::Binary( + BinaryOpDef{ + kind: BinaryExprType::Add, + left: Value::Int(value_node!(1, Position{line: 1, column: 2})), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 6})))), + pos: Some(Position { line: 1, column: 1 }), + } + ) + ) ) + ) ); } @@ -913,8 +928,8 @@ mod test { Expression::Format( FormatDef{ template: "foo @ @".to_string(), - args: vec![Expression::Simple(Value::Int(value_node!(1))), - Expression::Simple(Value::Int(value_node!(2)))], + args: vec![Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 14}))), + Expression::Simple(Value::Int(value_node!(2, Position{line: 1, column: 17})))], pos: Some(Position{line: 1, column: 1}), } ) @@ -931,8 +946,8 @@ mod test { Expression::Format( FormatDef{ template: "foo @ @".to_string(), - args: vec![Expression::Simple(Value::Int(value_node!(1))), - Expression::Simple(Value::Int(value_node!(2)))], + args: vec![Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 12}))), + Expression::Simple(Value::Int(value_node!(2, Position{line: 1, column: 15})))], pos: Some(Position { line: 1, column: 1 }), } ) @@ -957,12 +972,12 @@ mod test { offset: copy_expr.len(), }, Expression::Call(CallDef{ - macroref: vec![Token::new_with_pos("foo", Position{line:1, column: 1})], + macroref: vec![Token::new("foo", Position{line:1, column: 1})], arglist: vec![ - Expression::Simple(Value::Int(value_node!(1))), - Expression::Simple(Value::String(value_node!("foo".to_string()))), + Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 6}))), + Expression::Simple(Value::String(value_node!("foo".to_string(), Position{line: 1, column: 9}))), ], - pos: None, + pos: Some(Position{line: 1, column: 0}), }) ) ); @@ -976,13 +991,13 @@ mod test { offset: copy_expr.len(), }, Expression::Call(CallDef{ - macroref: vec![Token::new_with_pos("foo", Position{line: 1, column: 1}), - Token::new_with_pos("bar", Position{line: 1, column: 5})], + macroref: vec![Token::new("foo", Position{line: 1, column: 1}), + Token::new("bar", Position{line: 1, column: 5})], arglist: vec![ - Expression::Simple(Value::Int(value_node!(1))), - Expression::Simple(Value::String(value_node!("foo".to_string()))), + Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 10}))), + Expression::Simple(Value::String(value_node!("foo".to_string(), Position{line: 1, column: 13}))), ], - pos: None, + pos: Some(Position{line: 1, column: 0}), }) ) ); @@ -997,19 +1012,19 @@ mod test { let select_expr = "select foo, 1, { foo = 2 }"; assert_eq!(select_expression(LocatedSpan::new(select_expr)), - IResult::Done(LocatedSpan { + IResult::Done(LocatedSpan { fragment: "", offset: select_expr.len(), line: 1, }, - Expression::Select(SelectDef{ - val: Box::new(Expression::Simple(Value::Symbol(value_node!("foo".to_string())))), - default: Box::new(Expression::Simple(Value::Int(value_node!(1)))), - tuple: vec![ - (Token::new_with_pos("foo", Position{line: 1, column: 18}), Expression::Simple(Value::Int(value_node!(2)))) - ], - pos: None, - }) + Expression::Select(SelectDef{ + val: Box::new(Expression::Simple(Value::Symbol(value_node!("foo".to_string(), Position{line: 1, column: 8})))), + default: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 13})))), + tuple: vec![ + (Token::new("foo", Position{line: 1, column: 18}), Expression::Simple(Value::Int(value_node!(2, Position{line: 1, column: 24})))) + ], + pos: Some(Position{line: 1, column: 0}), + }) ) ); } @@ -1037,12 +1052,12 @@ mod test { line: 1 }, Expression::Macro(MacroDef{ - argdefs: vec![Positioned::new("arg1".to_string()), - Positioned::new("arg2".to_string())], - fields: vec![(Token::new_with_pos("foo", Position{line: 1, column: 24}), Expression::Simple(Value::Int(value_node!(1)))), - (Token::new_with_pos("bar", Position{line: 1, column: 30}), Expression::Simple(Value::Int(value_node!(2)))) + argdefs: vec![Positioned::new_with_pos("arg1".to_string(), Position{line: 1, column: 8}), + Positioned::new_with_pos("arg2".to_string(), Position{line: 1, column: 14})], + fields: vec![(Token::new("foo", Position{line: 1, column: 24}), Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 28})))), + (Token::new("bar", Position{line: 1, column: 30}), Expression::Simple(Value::Int(value_node!(2, Position{line: 1, column: 34})))) ], - pos: None, + pos: Some(Position{line: 1, column: 0}), }) ) ); @@ -1063,9 +1078,9 @@ mod test { line: 1 }, Expression::Copy(CopyDef{ - selector: vec![Token::new_with_pos("foo", Position{line: 1, column: 1})], + selector: vec![Token::new("foo", Position{line: 1, column: 1})], fields: Vec::new(), - pos: None, + pos: Some(Position{line: 1, column: 0}), }) ) ); @@ -1079,10 +1094,10 @@ mod test { line: 1 }, Expression::Copy(CopyDef{ - selector: vec![Token::new_with_pos("foo", Position{line: 1, column: 1})], - fields: vec![(Token::new_with_pos("bar", Position{line: 1, column: 5}), - Expression::Simple(Value::Int(value_node!(1))))], - pos: None, + selector: vec![Token::new("foo", Position{line: 1, column: 1})], + fields: vec![(Token::new("bar", Position{line: 1, column: 5}), + Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 9}))))], + pos: Some(Position{line: 1, column: 0}), }) ) ); @@ -1097,7 +1112,7 @@ mod test { Expression::Grouped( Box::new( Expression::Simple( - Value::Symbol(value_node!("foo".to_string())))))) + Value::Symbol(value_node!("foo".to_string(), Position{line: 1, column: 2})))))) ); assert_eq!(grouped_expression(LocatedSpan::new("(1 + 1)")), IResult::Done(LocatedSpan{fragment: "", offset: 7, line: 1}, @@ -1106,10 +1121,10 @@ mod test { Expression::Binary( BinaryOpDef{ kind: BinaryExprType::Add, - left: Value::Int(value_node!(1)), + left: Value::Int(value_node!(1, Position{line: 1, column: 2})), right: Box::new(Expression::Simple( - Value::Int(value_node!(1)))), - pos: None, + Value::Int(value_node!(1, Position{line: 1, column: 6})))), + pos: Some(Position { line: 1, column: 1 }), } ) ) @@ -1135,7 +1150,7 @@ mod test { line: 1, }, Value::Tuple( - value_node!(vec![])))); + value_node!(vec![], Position{line: 1, column: 0})))); tuple_expr = "{ foo = 1 }"; assert_eq!(tuple(LocatedSpan::new(tuple_expr)), @@ -1146,9 +1161,9 @@ mod test { }, Value::Tuple( value_node!(vec![ - (Token::new_with_pos("foo", Position{line:1, column: 3}), - Expression::Simple(Value::Int(value_node!(1)))) - ])))); + (Token::new("foo", Position{line:1, column: 3}), + Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 9})))) + ], Position{line: 1, column: 0})))); tuple_expr = "{ foo = 1, bar = \"1\" }"; assert_eq!(tuple(LocatedSpan::new(tuple_expr)), @@ -1159,13 +1174,13 @@ mod test { }, Value::Tuple( value_node!(vec![ - (Token::new_with_pos("foo", Position{line: 1, column: 3}), - Expression::Simple(Value::Int(value_node!(1)))), - (Token::new_with_pos("bar", Position{line: 1, column: 12}), - Expression::Simple(Value::String(value_node!("1".to_string())))) - ])))); + (Token::new("foo", Position{line: 1, column: 3}), + Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 9})))), + (Token::new("bar", Position{line: 1, column: 12}), + Expression::Simple(Value::String(value_node!("1".to_string(), Position{line: 1, column: 18})))) + ], Position{line: 1, column: 0})))); tuple_expr = "{ foo = 1, bar = {} }"; - assert_eq!(tuple(LocatedSpan::new(tuple_expr)), + assert_eq!(tuple(LocatedSpan::new(tuple_expr)), IResult::Done(LocatedSpan { fragment: "", offset: tuple_expr.len(), @@ -1173,11 +1188,11 @@ mod test { }, Value::Tuple( value_node!(vec![ - (Token::new_with_pos("foo", Position{line: 1, column: 3}), - Expression::Simple(Value::Int(value_node!(1)))), - (Token::new_with_pos("bar", Position{line: 1, column: 12}), - Expression::Simple(Value::Tuple(value_node!(Vec::new())))) - ])))); + (Token::new("foo", Position{line: 1, column: 3}), + Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 9})))), + (Token::new("bar", Position{line: 1, column: 12}), + Expression::Simple(Value::Tuple(value_node!(Vec::new(), Position{line: 1, column: 17})))) + ], Position{line: 1, column: 0})))); } #[test] @@ -1187,20 +1202,20 @@ mod test { assert_eq!(field_value(LocatedSpan::new("foo = 1")), IResult::Done(LocatedSpan { offset: 7, line: 1, fragment: "" }, - (Token::new_with_pos("foo", Position{line: 1, column: 1}), - Expression::Simple(Value::Int(value_node!(1))))) ); + (Token::new("foo", Position{line: 1, column: 1}), + Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 7}))))) ); assert_eq!(field_value(LocatedSpan::new("foo = \"1\"")), IResult::Done(LocatedSpan { offset: 9, line: 1, fragment: "" }, - (Token::new_with_pos("foo", Position{line: 1, column: 1}), - Expression::Simple(Value::String(value_node!("1".to_string()))))) ); + (Token::new("foo", Position{line: 1, column: 1}), + Expression::Simple(Value::String(value_node!("1".to_string(), Position{line: 1, column: 7}))))) ); assert_eq!(field_value(LocatedSpan::new("foo = bar")), IResult::Done(LocatedSpan { offset: 9, line: 1, fragment: "" }, - (Token::new_with_pos("foo", Position{line: 1, column: 1}), - Expression::Simple(Value::Symbol(value_node!("bar".to_string()))))) ); + (Token::new("foo", Position{line: 1, column: 1}), + Expression::Simple(Value::Symbol(value_node!("bar".to_string(), Position{line: 1, column: 7}))))) ); assert_eq!(field_value(LocatedSpan::new("foo = bar ")), IResult::Done(LocatedSpan { offset: 10, line: 1, fragment: "" }, - (Token::new_with_pos("foo", Position{line: 1, column: 1}), - Expression::Simple(Value::Symbol(value_node!("bar".to_string()))))) ); + (Token::new("foo", Position{line: 1, column: 1}), + Expression::Simple(Value::Symbol(value_node!("bar".to_string(), Position{line: 1, column: 7}))))) ); } #[test] @@ -1209,29 +1224,29 @@ mod test { assert!(number(LocatedSpan::new(". ")).is_err() ); assert_eq!(number(LocatedSpan::new("1.0")), IResult::Done(LocatedSpan{fragment: "", offset: 3, line: 1}, - Value::Float(value_node!(1.0))) ); + Value::Float(value_node!(1.0, Position{line: 1, column: 1}))) ); assert_eq!(number(LocatedSpan::new("1.")), IResult::Done(LocatedSpan{fragment: "", offset: 2, line: 1}, - Value::Float(value_node!(1.0))) ); + Value::Float(value_node!(1.0, Position{line: 1, column: 1}))) ); assert_eq!(number(LocatedSpan::new("1")), IResult::Done(LocatedSpan{fragment: "", offset: 1, line: 1}, - Value::Int(value_node!(1))) ); + Value::Int(value_node!(1, Position{line: 1, column: 1}))) ); assert_eq!(number(LocatedSpan::new(".1")), IResult::Done(LocatedSpan{fragment: "", offset: 2, line: 1}, - Value::Float(value_node!(0.1))) ); + Value::Float(value_node!(0.1, Position{line: 1, column: 1}))) ); } #[test] fn test_symbol_parsing() { assert_eq!(symbol(LocatedSpan::new("foo")), IResult::Done(LocatedSpan{fragment: "", offset: 3, line: 1}, - Value::Symbol(value_node!("foo".to_string()))) ); + Value::Symbol(value_node!("foo".to_string(), Position{line: 1, column: 1}))) ); assert_eq!(symbol(LocatedSpan::new("foo-bar")), IResult::Done(LocatedSpan{fragment: "", offset: 7, line: 1}, - Value::Symbol(value_node!("foo-bar".to_string()))) ); + Value::Symbol(value_node!("foo-bar".to_string(), Position{line: 1, column: 1}))) ); assert_eq!(symbol(LocatedSpan::new("foo_bar")), IResult::Done(LocatedSpan{fragment: "", offset: 7, line: 1}, - Value::Symbol(value_node!("foo_bar".to_string()))) ); + Value::Symbol(value_node!("foo_bar".to_string(), Position{line: 1, column: 1}))) ); } #[test] @@ -1267,15 +1282,15 @@ mod test { column: 27, } }, - value: Expression::Simple(Value::Int(value_node!(1))) + value: Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 33}))) }, Statement::Expression( Expression::Binary( BinaryOpDef{ kind: BinaryExprType::Add, - left: Value::Int(value_node!(1)), - right: Box::new(Expression::Simple(Value::Int(value_node!(1)))), - pos: None, + left: Value::Int(value_node!(1, Position{line: 1, column: 35})), + right: Box::new(Expression::Simple(Value::Int(value_node!(1, Position{line: 1, column: 37})))), + pos: Some(Position { line: 1, column: 34 }), }) ) ]);