Refactor Add position fields to our Expression Definition Structs

This commit is contained in:
Jeremy Wall 2017-09-21 08:10:09 -05:00
parent f95ecddea2
commit 53d598b773
3 changed files with 141 additions and 47 deletions

View File

@ -105,6 +105,7 @@ impl Value {
pub struct CallDef {
pub macroref: SelectorList,
pub arglist: Vec<Expression>,
pub pos: Option<Position>,
}
/// 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<Expression>,
pub default: Box<Expression>,
pub tuple: FieldList,
pub pos: Option<Position>,
}
/// MacroDef is a pure function that always returns a Tuple.
@ -124,6 +126,7 @@ pub struct SelectDef {
pub struct MacroDef {
pub argdefs: Vec<String>,
pub fields: FieldList,
pub pos: Option<Position>,
}
impl MacroDef {
@ -232,19 +235,22 @@ pub enum BinaryExprType {
pub struct BinaryExpression {
pub kind: BinaryExprType,
pub left: Value,
pub right: Box<Expression>
pub right: Box<Expression>,
pub pos: Option<Position>,
}
#[derive(Debug,PartialEq,Clone)]
pub struct CopyDef {
pub selector: SelectorList,
pub fields: FieldList
pub fields: FieldList,
pub pos: Option<Position>,
}
#[derive(Debug,PartialEq,Clone)]
pub struct FormatDef {
pub template: String,
pub args: Vec<Expression>
pub args: Vec<Expression>,
pub pos: Option<Position>,
}
/// 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());

View File

@ -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);

View File

@ -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<Expression>,
named!(selector_list<SelectorList>, separated_nonempty_list!(dot, field));
fn tuple_to_copy(t: (SelectorList, FieldList)) -> ParseResult<Expression> {
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<Expression>,
@ -291,6 +292,7 @@ fn tuple_to_macro(mut t: (Vec<Value>, Value)) -> ParseResult<Expression> {
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<Expression>,
);
fn tuple_to_format(t: (String, Vec<Expression>)) -> ParseResult<Expression> {
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<Expression>,
@ -370,6 +373,7 @@ fn tuple_to_call(t: (Value, Vec<Expression>)) -> ParseResult<Expression> {
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,
})
)
]);