mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-25 18:49:50 -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);
|
stack.push(expr);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
&Expression::Copy(_, ref fields) => {
|
&Expression::Copy(ref def) => {
|
||||||
|
let fields = &def.fields;
|
||||||
for &(_, ref expr) in fields.iter() {
|
for &(_, ref expr) in fields.iter() {
|
||||||
stack.push(expr);
|
stack.push(expr);
|
||||||
}
|
}
|
||||||
@ -236,6 +237,12 @@ impl MacroDef {
|
|||||||
#[derive(Debug,PartialEq,Clone)]
|
#[derive(Debug,PartialEq,Clone)]
|
||||||
pub struct BinaryExpression(pub Value, pub Box<Expression>);
|
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.
|
/// Expression encodes an expression. Expressions compute a value from operands.
|
||||||
#[derive(Debug,PartialEq,Clone)]
|
#[derive(Debug,PartialEq,Clone)]
|
||||||
pub enum Expression {
|
pub enum Expression {
|
||||||
@ -250,7 +257,7 @@ pub enum Expression {
|
|||||||
Div(BinaryExpression),
|
Div(BinaryExpression),
|
||||||
|
|
||||||
// Complex Expressions
|
// Complex Expressions
|
||||||
Copy(SelectorList, FieldList),
|
Copy(CopyDef),
|
||||||
Grouped(Box<Expression>),
|
Grouped(Box<Expression>),
|
||||||
|
|
||||||
Format(String, Vec<Expression>),
|
Format(String, Vec<Expression>),
|
||||||
|
28
src/build.rs
28
src/build.rs
@ -496,8 +496,8 @@ impl Builder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Expression::Copy(sel, mut fields) => {
|
Expression::Copy(mut def) => {
|
||||||
let v = try!(self.lookup_selector(sel));
|
let v = try!(self.lookup_selector(def.selector));
|
||||||
if let Val::Tuple(ref src_fields) = *v {
|
if let Val::Tuple(ref src_fields) = *v {
|
||||||
let mut m = HashMap::<String, Rc<Val>>::new();
|
let mut m = HashMap::<String, Rc<Val>>::new();
|
||||||
// loop through fields and build up a hasmap
|
// loop through fields and build up a hasmap
|
||||||
@ -510,7 +510,7 @@ impl Builder {
|
|||||||
format!("Duplicate field: {} in tuple", *key))));
|
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));
|
let expr_result = try!(self.eval_expr(val));
|
||||||
match m.entry(key.clone()) {
|
match m.entry(key.clone()) {
|
||||||
Entry::Vacant(v) => {
|
Entry::Vacant(v) => {
|
||||||
@ -793,7 +793,7 @@ mod test {
|
|||||||
fn test_expr_copy_no_such_tuple() {
|
fn test_expr_copy_no_such_tuple() {
|
||||||
let b = Builder::new();
|
let b = Builder::new();
|
||||||
test_expr_to_val(vec![
|
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())),
|
Val::Tuple(Vec::new())),
|
||||||
], b);
|
], b);
|
||||||
}
|
}
|
||||||
@ -804,7 +804,7 @@ mod test {
|
|||||||
let mut b = Builder::new();
|
let mut b = Builder::new();
|
||||||
b.out.entry("tpl1".to_string()).or_insert(Rc::new(Val::Int(1)));
|
b.out.entry("tpl1".to_string()).or_insert(Rc::new(Val::Int(1)));
|
||||||
test_expr_to_val(vec![
|
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())),
|
Val::Tuple(Vec::new())),
|
||||||
], b);
|
], b);
|
||||||
}
|
}
|
||||||
@ -817,9 +817,9 @@ mod test {
|
|||||||
("fld1".to_string(), Rc::new(Val::Int(1))),
|
("fld1".to_string(), Rc::new(Val::Int(1))),
|
||||||
])));
|
])));
|
||||||
test_expr_to_val(vec![
|
test_expr_to_val(vec![
|
||||||
(Expression::Copy(vec!["tpl1".to_string()],
|
(Expression::Copy(CopyDef{selector: vec!["tpl1".to_string()],
|
||||||
vec![("fld1".to_string(),
|
fields: vec![("fld1".to_string(),
|
||||||
Expression::Simple(Value::String(make_value_node("2".to_string()))))]),
|
Expression::Simple(Value::String(make_value_node("2".to_string()))))]}),
|
||||||
Val::Tuple(
|
Val::Tuple(
|
||||||
vec![
|
vec![
|
||||||
("fld1".to_string(), Rc::new(Val::String("2".to_string()))),
|
("fld1".to_string(), Rc::new(Val::String("2".to_string()))),
|
||||||
@ -838,9 +838,9 @@ mod test {
|
|||||||
("fld1".to_string(), Rc::new(Val::Int(1))),
|
("fld1".to_string(), Rc::new(Val::Int(1))),
|
||||||
])));
|
])));
|
||||||
test_expr_to_val(vec![
|
test_expr_to_val(vec![
|
||||||
(Expression::Copy(vec!["tpl1".to_string()],
|
(Expression::Copy(CopyDef{selector: vec!["tpl1".to_string()],
|
||||||
vec![("fld2".to_string(),
|
fields: vec![("fld2".to_string(),
|
||||||
Expression::Simple(Value::String(make_value_node("2".to_string()))))]),
|
Expression::Simple(Value::String(make_value_node("2".to_string()))))]}),
|
||||||
// Add a new field to the copy
|
// Add a new field to the copy
|
||||||
Val::Tuple(
|
Val::Tuple(
|
||||||
// NOTE(jwall): The order of these is important in order to ensure
|
// NOTE(jwall): The order of these is important in order to ensure
|
||||||
@ -852,13 +852,13 @@ mod test {
|
|||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
// Overwrite a field in the copy
|
// Overwrite a field in the copy
|
||||||
(Expression::Copy(vec!["tpl1".to_string()],
|
(Expression::Copy(CopyDef{selector: vec!["tpl1".to_string()],
|
||||||
vec![
|
fields: vec![
|
||||||
("fld1".to_string(),
|
("fld1".to_string(),
|
||||||
Expression::Simple(Value::Int(make_value_node(3)))),
|
Expression::Simple(Value::Int(make_value_node(3)))),
|
||||||
("fld2".to_string(),
|
("fld2".to_string(),
|
||||||
Expression::Simple(Value::String(make_value_node("2".to_string())))),
|
Expression::Simple(Value::String(make_value_node("2".to_string())))),
|
||||||
]),
|
]}),
|
||||||
Val::Tuple(
|
Val::Tuple(
|
||||||
vec![
|
vec![
|
||||||
("fld1".to_string(), Rc::new(Val::Int(3))),
|
("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));
|
named!(selector_list<SelectorList>, separated_nonempty_list!(dot, field));
|
||||||
|
|
||||||
fn tuple_to_copy(t: (SelectorList, FieldList)) -> ParseResult<Expression> {
|
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>,
|
named!(copy_expression<Expression>,
|
||||||
@ -824,14 +824,14 @@ mod test {
|
|||||||
assert!(copy_expression(&b"foo{"[..]).is_incomplete() );
|
assert!(copy_expression(&b"foo{"[..]).is_incomplete() );
|
||||||
assert_eq!(copy_expression(&b"foo{}"[..]),
|
assert_eq!(copy_expression(&b"foo{}"[..]),
|
||||||
IResult::Done(&b""[..],
|
IResult::Done(&b""[..],
|
||||||
Expression::Copy(vec!["foo".to_string()],
|
Expression::Copy(CopyDef{selector: vec!["foo".to_string()],
|
||||||
Vec::new())
|
fields: Vec::new()})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
assert_eq!(copy_expression(&b"foo{bar=1}"[..]),
|
assert_eq!(copy_expression(&b"foo{bar=1}"[..]),
|
||||||
IResult::Done(&b""[..],
|
IResult::Done(&b""[..],
|
||||||
Expression::Copy(vec!["foo".to_string()],
|
Expression::Copy(CopyDef{selector: vec!["foo".to_string()],
|
||||||
vec![("bar".to_string(), Expression::Simple(Value::Int(make_value_node(1))))])
|
fields: vec![("bar".to_string(), Expression::Simple(Value::Int(make_value_node(1))))]})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user