mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
Refactor the Copy expression to use a CopyDef struct.
This commit is contained in:
parent
b3677861c6
commit
42fe368dae
11
src/ast.rs
11
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<Expression>);
|
||||
|
||||
#[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<Expression>),
|
||||
|
||||
Format(String, Vec<Expression>),
|
||||
|
28
src/build.rs
28
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::<String, Rc<Val>>::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))),
|
||||
|
10
src/parse.rs
10
src/parse.rs
@ -277,7 +277,7 @@ named!(grouped_expression<Expression>,
|
||||
named!(selector_list<SelectorList>, separated_nonempty_list!(dot, field));
|
||||
|
||||
fn tuple_to_copy(t: (SelectorList, FieldList)) -> ParseResult<Expression> {
|
||||
Ok(Expression::Copy(t.0, t.1))
|
||||
Ok(Expression::Copy(CopyDef{selector: t.0, fields: t.1}))
|
||||
}
|
||||
|
||||
named!(copy_expression<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))))]})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user