Change eval strategy to use conditional sigil
This commit is contained in:
parent
d7f0147a4f
commit
b8df09e956
@ -116,6 +116,23 @@ impl Expr {
|
||||
_ => 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> {
|
||||
@ -194,7 +211,7 @@ impl<'a> State<'a> {
|
||||
Assign { box val, box expr } => self.assign_expression(val, expr),
|
||||
Unit => Ok(Node::Expr(Unit)),
|
||||
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")),
|
||||
}
|
||||
}
|
||||
@ -379,11 +396,12 @@ fn case_match_expression(&mut self, cond: Expr, alternatives: Vec<Alternative>)
|
||||
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::Expr(_e) => {
|
||||
Node::Expr(e) => {
|
||||
for alt in alternatives {
|
||||
match (alt.guard, alt.tag) {
|
||||
(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))) =>
|
||||
return self.block(alt.item),
|
||||
_ => continue,
|
||||
|
@ -48,7 +48,7 @@ pub enum Expr {
|
||||
then_clause: Vec<Stmt>,
|
||||
else_clause: Vec<Stmt>,
|
||||
},
|
||||
ConditionalTargetPlaceholder,
|
||||
ConditionalTargetSigilValue,
|
||||
CaseMatch {
|
||||
cond: Box<Expr>,
|
||||
alternatives: Vec<Alternative>
|
||||
@ -163,7 +163,7 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody,
|
||||
};
|
||||
|
||||
let alternatives = vec![
|
||||
pat.to_alternative(&cond, then_clause, symbol_table),
|
||||
pat.to_alternative(then_clause, symbol_table),
|
||||
Alternative::default(else_clause),
|
||||
];
|
||||
|
||||
@ -178,7 +178,7 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody,
|
||||
match arm.guard {
|
||||
Guard::Pat(ref p) => {
|
||||
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);
|
||||
},
|
||||
Guard::HalfExpr(HalfExpr { op: _, expr: _ }) => {
|
||||
@ -196,7 +196,7 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody,
|
||||
|
||||
|
||||
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::*;
|
||||
|
||||
fn handle_symbol(symbol: &Symbol, subpatterns: &Vec<Pattern>, item: Vec<Stmt>) -> Alternative {
|
||||
@ -253,7 +253,7 @@ impl Pattern {
|
||||
});
|
||||
let guard = Some(Expr::Call {
|
||||
f: Box::new(Expr::Func(Func::BuiltIn(Rc::new("==".to_string())))),
|
||||
args: vec![comparison, *cond.clone()]
|
||||
args: vec![comparison, Expr::ConditionalTargetSigilValue],
|
||||
});
|
||||
Alternative {
|
||||
tag: None,
|
||||
@ -266,11 +266,11 @@ impl Pattern {
|
||||
PatternLiteral::StringPattern(_s) => unimplemented!(),
|
||||
PatternLiteral::BoolPattern(b) => {
|
||||
let guard = Some(if *b {
|
||||
*cond.clone()
|
||||
Expr::ConditionalTargetSigilValue
|
||||
} else {
|
||||
Expr::Call {
|
||||
f: Box::new(Expr::Func(Func::BuiltIn(Rc::new("!".to_string())))),
|
||||
args: vec![*cond.clone()]
|
||||
args: vec![Expr::ConditionalTargetSigilValue]
|
||||
}
|
||||
});
|
||||
Alternative {
|
||||
|
Loading…
Reference in New Issue
Block a user