Change eval strategy to use conditional sigil

This commit is contained in:
greg 2018-10-29 01:50:43 -07:00
parent d7f0147a4f
commit b8df09e956
2 changed files with 28 additions and 10 deletions

View File

@ -116,6 +116,23 @@ impl Expr {
_ => format!("{:?}", self), _ => format!("{:?}", self),
} }
} }
fn replace_conditional_target_sigil(self, replacement: &Expr) -> Expr {
use self::Expr::*;
match self {
ConditionalTargetSigilValue => replacement.clone(),
Unit | Lit(_) | Func(_) | Val(_) | Constructor { .. } |
CaseMatch { .. } | UnimplementedSigilValue => self,
Tuple(exprs) => Tuple(exprs.into_iter().map(|e| e.replace_conditional_target_sigil(replacement)).collect()),
Call { f, args } => {
let new_args = args.into_iter().map(|e| e.replace_conditional_target_sigil(replacement)).collect();
Call { f, args: new_args }
},
Conditional { .. } => panic!("Dunno if I need this, but if so implement"),
Assign { .. } => panic!("I'm pretty sure I don't need this"),
}
}
} }
impl<'a> State<'a> { impl<'a> State<'a> {
@ -194,7 +211,7 @@ impl<'a> State<'a> {
Assign { box val, box expr } => self.assign_expression(val, expr), Assign { box val, box expr } => self.assign_expression(val, expr),
Unit => Ok(Node::Expr(Unit)), Unit => Ok(Node::Expr(Unit)),
CaseMatch { box cond, alternatives } => self.case_match_expression(cond, alternatives), CaseMatch { box cond, alternatives } => self.case_match_expression(cond, alternatives),
ConditionalTargetPlaceholder => Err(format!("This value shouldn't exist here")), ConditionalTargetSigilValue => Ok(Node::Expr(ConditionalTargetSigilValue)),
UnimplementedSigilValue => Err(format!("Sigil value eval not implemented")), UnimplementedSigilValue => Err(format!("Sigil value eval not implemented")),
} }
} }
@ -379,11 +396,12 @@ fn case_match_expression(&mut self, cond: Expr, alternatives: Vec<Alternative>)
return Err(format!("PrimObject failed pattern match")); return Err(format!("PrimObject failed pattern match"));
}, },
Node::PrimTuple { .. } => Err(format!("Tuples not implemented")), //TODO make a distinction between not yet implemented and an actual runtime error Node::PrimTuple { .. } => Err(format!("Tuples not implemented")), //TODO make a distinction between not yet implemented and an actual runtime error
Node::Expr(_e) => { Node::Expr(e) => {
for alt in alternatives { for alt in alternatives {
match (alt.guard, alt.tag) { match (alt.guard, alt.tag) {
(Some(ref guard_expr), None) => { (Some(ref guard_expr), None) => {
match self.expression(guard_expr.clone().to_node())? { let guard_expr = guard_expr.clone().replace_conditional_target_sigil(&e);
match self.expression(guard_expr.to_node())? {
Node::Expr(Expr::Lit(::reduced_ast::Lit::Bool(true))) => Node::Expr(Expr::Lit(::reduced_ast::Lit::Bool(true))) =>
return self.block(alt.item), return self.block(alt.item),
_ => continue, _ => continue,

View File

@ -48,7 +48,7 @@ pub enum Expr {
then_clause: Vec<Stmt>, then_clause: Vec<Stmt>,
else_clause: Vec<Stmt>, else_clause: Vec<Stmt>,
}, },
ConditionalTargetPlaceholder, ConditionalTargetSigilValue,
CaseMatch { CaseMatch {
cond: Box<Expr>, cond: Box<Expr>,
alternatives: Vec<Alternative> alternatives: Vec<Alternative>
@ -163,7 +163,7 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody,
}; };
let alternatives = vec![ let alternatives = vec![
pat.to_alternative(&cond, then_clause, symbol_table), pat.to_alternative(then_clause, symbol_table),
Alternative::default(else_clause), Alternative::default(else_clause),
]; ];
@ -178,7 +178,7 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody,
match arm.guard { match arm.guard {
Guard::Pat(ref p) => { Guard::Pat(ref p) => {
let item = arm.body.iter().map(|expr| expr.reduce(symbol_table)).collect(); let item = arm.body.iter().map(|expr| expr.reduce(symbol_table)).collect();
let alt = p.to_alternative(&cond, item, symbol_table); let alt = p.to_alternative(item, symbol_table);
alternatives.push(alt); alternatives.push(alt);
}, },
Guard::HalfExpr(HalfExpr { op: _, expr: _ }) => { Guard::HalfExpr(HalfExpr { op: _, expr: _ }) => {
@ -196,7 +196,7 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody,
impl Pattern { impl Pattern {
fn to_alternative(&self, cond: &Box<Expr>, item: Vec<Stmt>, symbol_table: &SymbolTable) -> Alternative { fn to_alternative(&self, item: Vec<Stmt>, symbol_table: &SymbolTable) -> Alternative {
use self::Pattern::*; use self::Pattern::*;
fn handle_symbol(symbol: &Symbol, subpatterns: &Vec<Pattern>, item: Vec<Stmt>) -> Alternative { fn handle_symbol(symbol: &Symbol, subpatterns: &Vec<Pattern>, item: Vec<Stmt>) -> Alternative {
@ -253,7 +253,7 @@ impl Pattern {
}); });
let guard = Some(Expr::Call { let guard = Some(Expr::Call {
f: Box::new(Expr::Func(Func::BuiltIn(Rc::new("==".to_string())))), f: Box::new(Expr::Func(Func::BuiltIn(Rc::new("==".to_string())))),
args: vec![comparison, *cond.clone()] args: vec![comparison, Expr::ConditionalTargetSigilValue],
}); });
Alternative { Alternative {
tag: None, tag: None,
@ -266,11 +266,11 @@ impl Pattern {
PatternLiteral::StringPattern(_s) => unimplemented!(), PatternLiteral::StringPattern(_s) => unimplemented!(),
PatternLiteral::BoolPattern(b) => { PatternLiteral::BoolPattern(b) => {
let guard = Some(if *b { let guard = Some(if *b {
*cond.clone() Expr::ConditionalTargetSigilValue
} else { } else {
Expr::Call { Expr::Call {
f: Box::new(Expr::Func(Func::BuiltIn(Rc::new("!".to_string())))), f: Box::new(Expr::Func(Func::BuiltIn(Rc::new("!".to_string())))),
args: vec![*cond.clone()] args: vec![Expr::ConditionalTargetSigilValue]
} }
}); });
Alternative { Alternative {