diff --git a/src/ast.rs b/src/ast.rs index 71c0ab9..4728a50 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -105,6 +105,7 @@ impl Value { pub struct CallDef { pub macroref: SelectorList, pub arglist: Vec, + pub pos: Option, } /// SelectDef selects a value from a tuple with a default if the value doesn't @@ -114,6 +115,7 @@ pub struct SelectDef { pub val: Box, pub default: Box, pub tuple: FieldList, + pub pos: Option, } /// MacroDef is a pure function that always returns a Tuple. @@ -124,6 +126,7 @@ pub struct SelectDef { pub struct MacroDef { pub argdefs: Vec, pub fields: FieldList, + pub pos: Option, } impl MacroDef { @@ -232,19 +235,22 @@ pub enum BinaryExprType { pub struct BinaryExpression { pub kind: BinaryExprType, pub left: Value, - pub right: Box + pub right: Box, + pub pos: Option, } #[derive(Debug,PartialEq,Clone)] pub struct CopyDef { pub selector: SelectorList, - pub fields: FieldList + pub fields: FieldList, + pub pos: Option, } #[derive(Debug,PartialEq,Clone)] pub struct FormatDef { pub template: String, - pub args: Vec + pub args: Vec, + pub pos: Option, } /// Expression encodes an expression. Expressions compute a value from operands. @@ -300,8 +306,11 @@ mod ast_test { ("f1".to_string(), Expression::Binary(BinaryExpression{ kind: BinaryExprType::Add, left: Value::Symbol(make_value_node("foo".to_string())), - right: Box::new(Expression::Simple(Value::Int(make_value_node(1))))})), + right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + pos: None, + })), ], + pos: None, }; assert!(def.validate_symbols().unwrap() == ()); } @@ -316,8 +325,11 @@ mod ast_test { ("f1".to_string(), Expression::Binary(BinaryExpression{ kind: BinaryExprType::Add, left: Value::Symbol(make_value_node("bar".to_string())), - right: Box::new(Expression::Simple(Value::Int(make_value_node(1))))})), + right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + pos: None, + })), ], + pos: None, }; let mut expected = HashSet::new(); @@ -335,8 +347,11 @@ mod ast_test { ("f1".to_string(), Expression::Binary(BinaryExpression{ kind: BinaryExprType::Add, left: Value::Selector(make_value_node(vec!["foo".to_string(), "quux".to_string()])), - right: Box::new(Expression::Simple(Value::Int(make_value_node(1))))})), + right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + pos: None, + })), ], + pos: None, }; assert!(def.validate_symbols().unwrap() == ()); } @@ -351,8 +366,11 @@ mod ast_test { ("f1".to_string(), Expression::Binary(BinaryExpression{ kind: BinaryExprType::Add, left: Value::Selector(make_value_node(vec!["bar".to_string(), "quux".to_string()])), - right: Box::new(Expression::Simple(Value::Int(make_value_node(1))))})), + right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + pos: None, + })), ], + pos: None, }; let mut expected = HashSet::new(); expected.insert("bar".to_string()); diff --git a/src/build.rs b/src/build.rs index c1172f0..900bbc9 100644 --- a/src/build.rs +++ b/src/build.rs @@ -407,7 +407,10 @@ impl Builder { Expression::Simple(val) => { self.value_to_val(val) }, - Expression::Binary(BinaryExpression{kind, left: v, right: expr}) => { + Expression::Binary(def) => { + let kind = def.kind; + let v = def.left; + let expr = def.right; let expr_result = try!(self.eval_expr(*expr)); let v = try!(self.value_to_val(v)); match kind { @@ -554,7 +557,9 @@ impl Builder { let formatter = format::Formatter::new(tmpl, vals); Ok(Rc::new(Val::String(try!(formatter.render())))) }, - Expression::Call(CallDef{macroref: sel, arglist: mut args}) => { + Expression::Call(def) => { + let sel = def.macroref; + let mut args = def.arglist; let v = try!(self.lookup_selector(sel)); if let &Val::Macro(ref m) = v.deref() { // Congratulations this is actually a macro. @@ -578,7 +583,10 @@ impl Builder { format!("Macro has the following undefined symbols: {:?}", set)))), } }, - Expression::Select(SelectDef{val: target, default: def_expr, tuple: mut fields}) => { + Expression::Select(def) => { + let target = def.val; + let def_expr = def.default; + let mut fields = def.tuple; // First resolve the target expression. let v = try!(self.eval_expr(*target)); // Second ensure that the expression resolves to a string. @@ -625,6 +633,7 @@ mod test { kind: BinaryExprType::Div, left: Value::Int(make_value_node(2)), right: Box::new(Expression::Simple(Value::Int(make_value_node(2)))), + pos: None, }), Val::Int(1)), (Expression::Binary( @@ -632,6 +641,7 @@ mod test { kind: BinaryExprType::Div, left: Value::Float(make_value_node(2.0)), right: Box::new(Expression::Simple(Value::Float(make_value_node(2.0)))), + pos: None, }), Val::Float(1.0)), ], b); @@ -646,7 +656,8 @@ mod test { BinaryExpression{ kind: BinaryExprType::Div, left: Value::Float(make_value_node(2.0)), - right: Box::new(Expression::Simple(Value::Int(make_value_node(2)))) + right: Box::new(Expression::Simple(Value::Int(make_value_node(2)))), + pos: None, }), Val::Float(1.0)), ], b); @@ -660,14 +671,16 @@ mod test { BinaryExpression{ kind: BinaryExprType::Mul, left: Value::Int(make_value_node(2)), - right: Box::new(Expression::Simple(Value::Int(make_value_node(2)))) + right: Box::new(Expression::Simple(Value::Int(make_value_node(2)))), + pos: None, }), Val::Int(4)), (Expression::Binary( BinaryExpression{ kind: BinaryExprType::Mul, left: Value::Float(make_value_node(2.0)), - right: Box::new(Expression::Simple(Value::Float(make_value_node(2.0)))) + right: Box::new(Expression::Simple(Value::Float(make_value_node(2.0)))), + pos: None, }), Val::Float(4.0)), ], b); @@ -682,7 +695,8 @@ mod test { BinaryExpression{ kind: BinaryExprType::Mul, left: Value::Float(make_value_node(2.0)), - right: Box::new(Expression::Simple(Value::Int(make_value_node(20)))) + right: Box::new(Expression::Simple(Value::Int(make_value_node(20)))), + pos: None, }), Val::Float(1.0)), ], b); @@ -697,13 +711,15 @@ mod test { kind: BinaryExprType::Sub, left: Value::Int(make_value_node(2)), right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + pos: None, }), Val::Int(1)), (Expression::Binary( BinaryExpression{ kind: BinaryExprType::Sub, left: Value::Float(make_value_node(2.0)), - right: Box::new(Expression::Simple(Value::Float(make_value_node(1.0)))) + right: Box::new(Expression::Simple(Value::Float(make_value_node(1.0)))), + pos: None, }), Val::Float(1.0)), ], b); @@ -718,7 +734,8 @@ mod test { BinaryExpression{ kind: BinaryExprType::Sub, left: Value::Float(make_value_node(2.0)), - right: Box::new(Expression::Simple(Value::Int(make_value_node(2)))) + right: Box::new(Expression::Simple(Value::Int(make_value_node(2)))), + pos: None, }), Val::Float(1.0)), ], b); @@ -732,7 +749,8 @@ mod test { BinaryExpression{ kind: BinaryExprType::Add, left: Value::Int(make_value_node(1)), - right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))) + right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + pos: None, }), Val::Int(2)), (Expression::Binary( @@ -740,6 +758,7 @@ mod test { kind: BinaryExprType::Add, left: Value::Float(make_value_node(1.0)), right: Box::new(Expression::Simple(Value::Float(make_value_node(1.0)))), + pos: None, }), Val::Float(2.0)), (Expression::Binary( @@ -747,6 +766,7 @@ mod test { 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())))), + pos: None, }), Val::String("foobar".to_string())), ], b); @@ -762,6 +782,7 @@ mod test { kind: BinaryExprType::Add, left: Value::Float(make_value_node(2.0)), right: Box::new(Expression::Simple(Value::Int(make_value_node(2)))), + pos: None, }), Val::Float(1.0)), ], b); @@ -845,7 +866,7 @@ mod test { fn test_expr_copy_no_such_tuple() { let b = Builder::new(); test_expr_to_val(vec![ - (Expression::Copy(CopyDef{selector: vec!["tpl1".to_string()], fields: Vec::new()}), + (Expression::Copy(CopyDef{selector: vec!["tpl1".to_string()], fields: Vec::new(), pos: None}), Val::Tuple(Vec::new())), ], b); } @@ -856,7 +877,7 @@ mod test { let mut b = Builder::new(); b.out.entry("tpl1".to_string()).or_insert(Rc::new(Val::Int(1))); test_expr_to_val(vec![ - (Expression::Copy(CopyDef{selector: vec!["tpl1".to_string()], fields: Vec::new()}), + (Expression::Copy(CopyDef{selector: vec!["tpl1".to_string()], fields: Vec::new(), pos: None}), Val::Tuple(Vec::new())), ], b); } @@ -869,9 +890,12 @@ mod test { ("fld1".to_string(), Rc::new(Val::Int(1))), ]))); test_expr_to_val(vec![ - (Expression::Copy(CopyDef{selector: vec!["tpl1".to_string()], - fields: vec![("fld1".to_string(), - Expression::Simple(Value::String(make_value_node("2".to_string()))))]}), + (Expression::Copy( + CopyDef{ + selector: vec!["tpl1".to_string()], + fields: vec![("fld1".to_string(), + Expression::Simple(Value::String(make_value_node("2".to_string()))))], + pos: None}), Val::Tuple( vec![ ("fld1".to_string(), Rc::new(Val::String("2".to_string()))), @@ -890,9 +914,13 @@ mod test { ("fld1".to_string(), Rc::new(Val::Int(1))), ]))); test_expr_to_val(vec![ - (Expression::Copy(CopyDef{selector: vec!["tpl1".to_string()], - fields: vec![("fld2".to_string(), - Expression::Simple(Value::String(make_value_node("2".to_string()))))]}), + (Expression::Copy( + CopyDef{ + selector: vec!["tpl1".to_string()], + fields: vec![("fld2".to_string(), + Expression::Simple(Value::String(make_value_node("2".to_string()))))], + pos: None, + }), // Add a new field to the copy Val::Tuple( // NOTE(jwall): The order of these is important in order to ensure @@ -904,13 +932,17 @@ mod test { ], )), // Overwrite a field in the copy - (Expression::Copy(CopyDef{selector: vec!["tpl1".to_string()], - fields: vec![ - ("fld1".to_string(), - Expression::Simple(Value::Int(make_value_node(3)))), - ("fld2".to_string(), - Expression::Simple(Value::String(make_value_node("2".to_string())))), - ]}), + (Expression::Copy( + CopyDef{ + selector: vec!["tpl1".to_string()], + fields: vec![ + ("fld1".to_string(), + Expression::Simple(Value::Int(make_value_node(3)))), + ("fld2".to_string(), + Expression::Simple(Value::String(make_value_node("2".to_string())))), + ], + pos: None, + }), Val::Tuple( vec![ ("fld1".to_string(), Rc::new(Val::Int(3))), @@ -935,11 +967,13 @@ mod test { fields: vec![ ("foo".to_string(), Expression::Simple(Value::Symbol(make_value_node("arg1".to_string())))), ], + pos: None, }))); test_expr_to_val(vec![ (Expression::Call(CallDef{ macroref: vec!["tstmac".to_string()], arglist: vec![Expression::Simple(Value::String(make_value_node("bar".to_string())))], + pos: None, }), Val::Tuple(vec![ ("foo".to_string(), Rc::new(Val::String("bar".to_string()))), @@ -957,11 +991,13 @@ mod test { fields: vec![ ("foo".to_string(), Expression::Simple(Value::Symbol(make_value_node("arg1".to_string())))), ], + pos: None, }))); test_expr_to_val(vec![ (Expression::Call(CallDef{ macroref: vec!["tstmac".to_string()], arglist: vec![Expression::Simple(Value::String(make_value_node("bar".to_string())))], + pos: None, }), Val::Tuple(vec![ ("foo".to_string(), Rc::new(Val::String("bar".to_string()))), @@ -982,6 +1018,7 @@ mod test { ("bar".to_string(), Expression::Simple(Value::Int(make_value_node(2)))), ("quux".to_string(), Expression::Simple(Value::String(make_value_node("2".to_string())))), ], + pos: None, }), Val::Int(2)), (Expression::Select(SelectDef{ @@ -991,6 +1028,7 @@ mod test { ("bar".to_string(), Expression::Simple(Value::Int(make_value_node(2)))), ("quux".to_string(), Expression::Simple(Value::String(make_value_node("2".to_string())))), ], + pos: None, }), // If the field doesn't exist then we get the default. Val::Int(1)), @@ -1010,6 +1048,7 @@ mod test { ("bar".to_string(), Expression::Simple(Value::Int(make_value_node(2)))), ("quux".to_string(), Expression::Simple(Value::String(make_value_node("2".to_string())))), ], + pos: None, }), Val::Int(2)), ], b); diff --git a/src/parse.rs b/src/parse.rs index f1ef257..a9d5682 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -204,6 +204,7 @@ fn tuple_to_binary_expression(tpl: (BinaryExprType, Value, Expression)) -> Parse kind: tpl.0, left: tpl.1, right: Box::new(tpl.2), + pos: None, })) } @@ -269,7 +270,7 @@ named!(grouped_expression, named!(selector_list, separated_nonempty_list!(dot, field)); fn tuple_to_copy(t: (SelectorList, FieldList)) -> ParseResult { - Ok(Expression::Copy(CopyDef{selector: t.0, fields: t.1})) + Ok(Expression::Copy(CopyDef{selector: t.0, fields: t.1, pos: None})) } named!(copy_expression, @@ -291,6 +292,7 @@ fn tuple_to_macro(mut t: (Vec, Value)) -> ParseResult { Ok(Expression::Macro(MacroDef { argdefs: t.0.drain(0..).map(|s| s.to_string()).collect(), fields: v.val, + pos: None, })) } // TODO(jwall): Show a better version of the unexpected parsed value. @@ -325,6 +327,7 @@ fn tuple_to_select(t: (Expression, Expression, Value)) val: Box::new(t.0), default: Box::new(t.1), tuple: v.val, + pos: None, })) } // TODO(jwall): Show a better version of the unexpected parsed value. @@ -348,7 +351,7 @@ named!(select_expression, ); fn tuple_to_format(t: (String, Vec)) -> ParseResult { - Ok(Expression::Format(FormatDef{template: t.0, args: t.1})) + Ok(Expression::Format(FormatDef{template: t.0, args: t.1, pos: None})) } named!(format_expression, @@ -370,6 +373,7 @@ fn tuple_to_call(t: (Value, Vec)) -> ParseResult { Ok(Expression::Call(CallDef{ macroref: sl.val, arglist: t.1, + pos: None, })) } else { Err(Box::new(ParseError::UnexpectedToken("Selector".to_string(), format!("{:?}", t.0)))) @@ -619,6 +623,7 @@ mod test { kind: BinaryExprType::Add, left: Value::Int(make_value_node(1)), right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + pos: None, }))); assert_eq!(expression(&b"1 - 1"[..]), IResult::Done(&b""[..], @@ -626,6 +631,7 @@ mod test { kind: BinaryExprType::Sub, left: Value::Int(make_value_node(1)), right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + pos: None, }))); assert_eq!(expression(&b"1 * 1"[..]), IResult::Done(&b""[..], @@ -633,6 +639,7 @@ mod test { kind: BinaryExprType::Mul, left: Value::Int(make_value_node(1)), right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + pos: None, }))); assert_eq!(expression(&b"1 / 1"[..]), IResult::Done(&b""[..], @@ -640,6 +647,7 @@ mod test { kind: BinaryExprType::Div, left: Value::Int(make_value_node(1)), right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + pos: None, }))); assert_eq!(expression(&b"1+1"[..]), @@ -648,6 +656,7 @@ mod test { kind: BinaryExprType::Add, left: Value::Int(make_value_node(1)), right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + pos: None, }))); assert_eq!(expression(&b"1-1"[..]), IResult::Done(&b""[..], @@ -655,6 +664,7 @@ mod test { kind: BinaryExprType::Sub, left: Value::Int(make_value_node(1)), right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + pos: None, }))); assert_eq!(expression(&b"1*1"[..]), IResult::Done(&b""[..], @@ -662,6 +672,7 @@ mod test { kind: BinaryExprType::Mul, left: Value::Int(make_value_node(1)), right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + pos: None, }))); assert_eq!(expression(&b"1/1"[..]), IResult::Done(&b""[..], @@ -669,6 +680,7 @@ mod test { kind: BinaryExprType::Div, left: Value::Int(make_value_node(1)), right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + pos: None, }))); assert_eq!(expression(&b"macro (arg1, arg2) => { foo = arg1 }"[..]), IResult::Done(&b""[..], @@ -680,6 +692,7 @@ mod test { fields: vec![ ("foo".to_string(), Expression::Simple(Value::Symbol(make_value_node("arg1".to_string())))), ], + pos: None, }) ) ); @@ -690,7 +703,8 @@ mod test { default: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), tuple: vec![ ("foo".to_string(), Expression::Simple(Value::Int(make_value_node(2)))) - ] + ], + pos: None, }) ) ); @@ -702,6 +716,7 @@ mod test { Expression::Simple(Value::Int(make_value_node(1))), Expression::Simple(Value::String(make_value_node("foo".to_string()))), ], + pos: None, }) ) ); @@ -714,6 +729,7 @@ mod test { kind: BinaryExprType::Add, left: Value::Int(make_value_node(1)), right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + pos: None, } ) ) @@ -731,16 +747,24 @@ mod test { assert_eq!(format_expression(&b"\"foo @ @\" % (1, 2)"[..]), IResult::Done(&b""[..], - Expression::Format(FormatDef{template: "foo @ @".to_string(), - args: vec![Expression::Simple(Value::Int(make_value_node(1))), - Expression::Simple(Value::Int(make_value_node(2)))]}) + Expression::Format( + FormatDef{ + template: "foo @ @".to_string(), + args: vec![Expression::Simple(Value::Int(make_value_node(1))), + Expression::Simple(Value::Int(make_value_node(2)))], + pos: None, + }) ) ); assert_eq!(format_expression(&b"\"foo @ @\"%(1, 2)"[..]), IResult::Done(&b""[..], - Expression::Format(FormatDef{template: "foo @ @".to_string(), - args: vec![Expression::Simple(Value::Int(make_value_node(1))), - Expression::Simple(Value::Int(make_value_node(2)))]}) + Expression::Format( + FormatDef{ + template: "foo @ @".to_string(), + args: vec![Expression::Simple(Value::Int(make_value_node(1))), + Expression::Simple(Value::Int(make_value_node(2)))], + pos: None, + }) ) ); } @@ -761,6 +785,7 @@ mod test { Expression::Simple(Value::Int(make_value_node(1))), Expression::Simple(Value::String(make_value_node("foo".to_string()))), ], + pos: None, }) ) ); @@ -773,6 +798,7 @@ mod test { Expression::Simple(Value::Int(make_value_node(1))), Expression::Simple(Value::String(make_value_node("foo".to_string()))), ], + pos: None, }) ) ); @@ -792,7 +818,8 @@ mod test { default: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), tuple: vec![ ("foo".to_string(), Expression::Simple(Value::Int(make_value_node(2)))) - ] + ], + pos: None, }) ) ); @@ -819,7 +846,8 @@ mod test { "arg2".to_string()], fields: vec![("foo".to_string(), Expression::Simple(Value::Int(make_value_node(1)))), ("bar".to_string(), Expression::Simple(Value::Int(make_value_node(2)))) - ] + ], + pos: None, }) ) ); @@ -843,14 +871,21 @@ mod test { assert!(copy_expression(&b"foo{"[..]).is_incomplete() ); assert_eq!(copy_expression(&b"foo{}"[..]), IResult::Done(&b""[..], - Expression::Copy(CopyDef{selector: vec!["foo".to_string()], - fields: Vec::new()}) + Expression::Copy(CopyDef{ + selector: vec!["foo".to_string()], + fields: Vec::new(), + pos: None, + }) ) ); assert_eq!(copy_expression(&b"foo{bar=1}"[..]), IResult::Done(&b""[..], - Expression::Copy(CopyDef{selector: vec!["foo".to_string()], - fields: vec![("bar".to_string(), Expression::Simple(Value::Int(make_value_node(1))))]}) + Expression::Copy(CopyDef{ + selector: vec!["foo".to_string()], + fields: vec![("bar".to_string(), + Expression::Simple(Value::Int(make_value_node(1))))], + pos: None, + }) ) ); } @@ -876,6 +911,7 @@ mod test { left: Value::Int(make_value_node(1)), right: Box::new(Expression::Simple( Value::Int(make_value_node(1)))), + pos: None, } ) ) @@ -990,6 +1026,7 @@ mod test { kind: BinaryExprType::Add, left: Value::Int(make_value_node(1)), right: Box::new(Expression::Simple(Value::Int(make_value_node(1)))), + pos: None, }) ) ]);