Change eval strategy to use conditional sigil
This commit is contained in:
parent
d7f0147a4f
commit
b8df09e956
@ -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,
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user