Separate Value and NamedStruct syntactic categories

This commit is contained in:
greg 2018-02-26 18:12:37 -08:00
parent 522d9fc951
commit d69970a806
2 changed files with 17 additions and 12 deletions

View File

@ -121,7 +121,7 @@ impl<'a> State<'a> {
BoolLiteral(b) => Ok(Bool(b)), BoolLiteral(b) => Ok(Bool(b)),
PrefixExp(op, expr) => self.eval_prefix_exp(op, expr), PrefixExp(op, expr) => self.eval_prefix_exp(op, expr),
BinExp(op, lhs, rhs) => self.eval_binexp(op, lhs, rhs), BinExp(op, lhs, rhs) => self.eval_binexp(op, lhs, rhs),
Value(name, _) => self.eval_value(name), Value(name) => self.eval_value(name),
TupleLiteral(expressions) => { TupleLiteral(expressions) => {
let mut evals = Vec::new(); let mut evals = Vec::new();
for expr in expressions { for expr in expressions {
@ -140,7 +140,7 @@ impl<'a> State<'a> {
fn eval_application(&mut self, f: Expression, _arguments: Vec<Expression>) -> EvalResult<FullyEvaluatedExpr> { fn eval_application(&mut self, f: Expression, _arguments: Vec<Expression>) -> EvalResult<FullyEvaluatedExpr> {
use self::ExpressionType::*; use self::ExpressionType::*;
match f { match f {
Expression(Value(identifier, _), _) => { Expression(Value(identifier), _) => {
match self.values.get(&identifier) { match self.values.get(&identifier) {
Some(&ValueEntry::Function { ref body }) => { Some(&ValueEntry::Function { ref body }) => {
let mut new_state = State::new_with_parent(self); let mut new_state = State::new_with_parent(self);

View File

@ -229,7 +229,11 @@ pub enum ExpressionType {
BinExp(BinOp, Box<Expression>, Box<Expression>), BinExp(BinOp, Box<Expression>, Box<Expression>),
PrefixExp(PrefixOp, Box<Expression>), PrefixExp(PrefixOp, Box<Expression>),
TupleLiteral(Vec<Expression>), TupleLiteral(Vec<Expression>),
Value(Rc<String>, Vec<(Rc<String>, Expression)>), Value(Rc<String>),
NamedStruct {
name: Rc<String>,
fields: Vec<(Rc<String>, Expression)>,
},
Call { Call {
f: Box<Expression>, f: Box<Expression>,
arguments: Vec<Expression>, arguments: Vec<Expression>,
@ -603,22 +607,22 @@ impl Parser {
Ok(match self.peek() { Ok(match self.peek() {
LCurlyBrace if !self.restrictions.no_struct_literal => { LCurlyBrace if !self.restrictions.no_struct_literal => {
let fields = self.record_block()?; let fields = self.record_block()?;
Expression(Value(identifier, fields), None) Expression(NamedStruct { name: identifier, fields }, None)
}, },
LParen => { LParen => {
let arguments = self.call_expr()?; let arguments = self.call_expr()?;
//TODO make this be more general //TODO make this be more general
let f = bx!(Expression(Value(identifier, vec![]), None)); let f = bx!(Expression(Value(identifier), None));
Expression(Call { f, arguments }, None) Expression(Call { f, arguments }, None)
}, },
LSquareBracket => { LSquareBracket => {
let indexers = self.index_expr()?; let indexers = self.index_expr()?;
Expression(Index { Expression(Index {
indexee: bx!(Expression(Value(identifier, vec![]), None)), indexee: bx!(Expression(Value(identifier), None)),
indexers, indexers,
}, None) }, None)
} }
_ => Expression(Value(identifier, vec![]), None) _ => Expression(Value(identifier), None)
}) })
}); });
@ -857,7 +861,7 @@ mod parse_tests {
($op:expr, $lhs:expr) => { PrefixExp(PrefixOp::from_sigil($op), bx!(Expression($lhs, None))) } ($op:expr, $lhs:expr) => { PrefixExp(PrefixOp::from_sigil($op), bx!(Expression($lhs, None))) }
} }
macro_rules! val { macro_rules! val {
($var:expr) => { Value(Rc::new($var.to_string()), vec![]) } ($var:expr) => { Value(Rc::new($var.to_string())) }
} }
macro_rules! exprstatement { macro_rules! exprstatement {
($expr_type:expr) => { Statement::ExpressionStatement(Expression($expr_type, None)) }; ($expr_type:expr) => { Statement::ExpressionStatement(Expression($expr_type, None)) };
@ -938,7 +942,8 @@ mod parse_tests {
parse_test!("None", AST(vec![exprstatement!(val!("None"))])); parse_test!("None", AST(vec![exprstatement!(val!("None"))]));
parse_test!("Pandas { a: x + y }", AST(vec![ parse_test!("Pandas { a: x + y }", AST(vec![
exprstatement!(Value(rc!(Pandas), vec![(rc!(a), ex!(binexp!("+", val!("x"), val!("y"))))]))])); exprstatement!(NamedStruct { name: rc!(Pandas), fields: vec![(rc!(a), ex!(binexp!("+", val!("x"), val!("y"))))]})
]));
} }
#[test] #[test]
@ -1035,8 +1040,8 @@ mod parse_tests {
}"#, }"#,
AST(vec![exprstatement!(IfExpression(bx!(ex!(BoolLiteral(true))), AST(vec![exprstatement!(IfExpression(bx!(ex!(BoolLiteral(true))),
vec![Declaration(Binding { name: rc!(a), constant: true, expr: ex!(IntLiteral(10)) }), vec![Declaration(Binding { name: rc!(a), constant: true, expr: ex!(IntLiteral(10)) }),
exprstatement!(Value(rc!(b), vec![]))], exprstatement!(val!(rc!(b)))],
Some(vec![exprstatement!(Value(rc!(c), vec![]))])))]) Some(vec![exprstatement!(val!(rc!(c)))])))])
); );
parse_test!("if a { b } else { c }", AST(vec![exprstatement!( parse_test!("if a { b } else { c }", AST(vec![exprstatement!(
@ -1045,7 +1050,7 @@ mod parse_tests {
Some(vec![exprstatement!(val!("c"))])))])); Some(vec![exprstatement!(val!("c"))])))]));
parse_test!("if (A {a: 1}) { b } else { c }", AST(vec![exprstatement!( parse_test!("if (A {a: 1}) { b } else { c }", AST(vec![exprstatement!(
IfExpression(bx!(ex!(Value(rc!(A), vec![(rc!(a), ex!(IntLiteral(1)))]))), IfExpression(bx!(ex!(NamedStruct { name: rc!(A), fields: vec![(rc!(a), ex!(IntLiteral(1)))]})),
vec![exprstatement!(val!("b"))], vec![exprstatement!(val!("b"))],
Some(vec![exprstatement!(val!("c"))])))])); Some(vec![exprstatement!(val!("c"))])))]));