diff --git a/src/ast.rs b/src/ast.rs index 64dae2c..7687bab 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -204,7 +204,8 @@ impl MacroDef { stack.push(expr); } }, - &Expression::Copy(_, ref fields) => { + &Expression::Copy(ref def) => { + let fields = &def.fields; for &(_, ref expr) in fields.iter() { stack.push(expr); } @@ -236,6 +237,12 @@ impl MacroDef { #[derive(Debug,PartialEq,Clone)] pub struct BinaryExpression(pub Value, pub Box); +#[derive(Debug,PartialEq,Clone)] +pub struct CopyDef { + pub selector: SelectorList, + pub fields: FieldList +} + /// Expression encodes an expression. Expressions compute a value from operands. #[derive(Debug,PartialEq,Clone)] pub enum Expression { @@ -250,7 +257,7 @@ pub enum Expression { Div(BinaryExpression), // Complex Expressions - Copy(SelectorList, FieldList), + Copy(CopyDef), Grouped(Box), Format(String, Vec), diff --git a/src/build.rs b/src/build.rs index d5dada0..feeeb59 100644 --- a/src/build.rs +++ b/src/build.rs @@ -496,8 +496,8 @@ impl Builder { } } }, - Expression::Copy(sel, mut fields) => { - let v = try!(self.lookup_selector(sel)); + Expression::Copy(mut def) => { + let v = try!(self.lookup_selector(def.selector)); if let Val::Tuple(ref src_fields) = *v { let mut m = HashMap::>::new(); // loop through fields and build up a hasmap @@ -510,7 +510,7 @@ impl Builder { format!("Duplicate field: {} in tuple", *key)))); } } - for (key, val) in fields.drain(0..) { + for (key, val) in def.fields.drain(0..) { let expr_result = try!(self.eval_expr(val)); match m.entry(key.clone()) { Entry::Vacant(v) => { @@ -793,7 +793,7 @@ mod test { fn test_expr_copy_no_such_tuple() { let b = Builder::new(); test_expr_to_val(vec![ - (Expression::Copy(vec!["tpl1".to_string()], Vec::new()), + (Expression::Copy(CopyDef{selector: vec!["tpl1".to_string()], fields: Vec::new()}), Val::Tuple(Vec::new())), ], b); } @@ -804,7 +804,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(vec!["tpl1".to_string()], Vec::new()), + (Expression::Copy(CopyDef{selector: vec!["tpl1".to_string()], fields: Vec::new()}), Val::Tuple(Vec::new())), ], b); } @@ -817,9 +817,9 @@ mod test { ("fld1".to_string(), Rc::new(Val::Int(1))), ]))); test_expr_to_val(vec![ - (Expression::Copy(vec!["tpl1".to_string()], - 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()))))]}), Val::Tuple( vec![ ("fld1".to_string(), Rc::new(Val::String("2".to_string()))), @@ -838,9 +838,9 @@ mod test { ("fld1".to_string(), Rc::new(Val::Int(1))), ]))); test_expr_to_val(vec![ - (Expression::Copy(vec!["tpl1".to_string()], - 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()))))]}), // Add a new field to the copy Val::Tuple( // NOTE(jwall): The order of these is important in order to ensure @@ -852,13 +852,13 @@ mod test { ], )), // Overwrite a field in the copy - (Expression::Copy(vec!["tpl1".to_string()], - vec![ + (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())))), - ]), + ]}), Val::Tuple( vec![ ("fld1".to_string(), Rc::new(Val::Int(3))), diff --git a/src/parse.rs b/src/parse.rs index cb12a70..0c9f149 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -277,7 +277,7 @@ named!(grouped_expression, named!(selector_list, separated_nonempty_list!(dot, field)); fn tuple_to_copy(t: (SelectorList, FieldList)) -> ParseResult { - Ok(Expression::Copy(t.0, t.1)) + Ok(Expression::Copy(CopyDef{selector: t.0, fields: t.1})) } named!(copy_expression, @@ -824,14 +824,14 @@ mod test { assert!(copy_expression(&b"foo{"[..]).is_incomplete() ); assert_eq!(copy_expression(&b"foo{}"[..]), IResult::Done(&b""[..], - Expression::Copy(vec!["foo".to_string()], - Vec::new()) + Expression::Copy(CopyDef{selector: vec!["foo".to_string()], + fields: Vec::new()}) ) ); assert_eq!(copy_expression(&b"foo{bar=1}"[..]), IResult::Done(&b""[..], - Expression::Copy(vec!["foo".to_string()], - 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))))]}) ) ); }