Refactoring matching - WIP
doesn't work yet
This commit is contained in:
parent
ec5a9d457e
commit
cab4702bd6
@ -369,10 +369,20 @@ impl<'a> State<'a> {
|
|||||||
Ok(Node::Expr(Expr::Unit))
|
Ok(Node::Expr(Expr::Unit))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn case_match_expression(&mut self, cond: Expr, alternatives: Vec<Alternative>) -> EvalResult<Node> {
|
fn case_match_expression(&mut self, cond: Expr, alternatives: Vec<Alternative>) -> EvalResult<Node> {
|
||||||
match self.expression(Node::Expr(cond))? {
|
let cond = self.expression(Node::Expr(cond))?;
|
||||||
Node::PrimObject { tag, items, .. } => {
|
|
||||||
for alt in alternatives {
|
for alt in alternatives {
|
||||||
|
// no matter what type of condition we have, ignore alternative if the guard evaluates false
|
||||||
|
if let Some(guard_expr) = alt.guard {
|
||||||
|
let guard_expr = guard_expr.clone().replace_conditional_target_sigil(&cond);
|
||||||
|
match self.expression(guard_expr.to_node())? {
|
||||||
|
Node::Expr(Expr::Lit(::reduced_ast::Lit::Bool(true))) => (),
|
||||||
|
_ => continue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match cond {
|
||||||
|
Node::PrimObject { tag, items, .. } => {
|
||||||
if alt.tag.map(|t| t == tag).unwrap_or(true) {
|
if alt.tag.map(|t| t == tag).unwrap_or(true) {
|
||||||
let mut inner_state = State {
|
let mut inner_state = State {
|
||||||
values: self.values.new_scope(None),
|
values: self.values.new_scope(None),
|
||||||
@ -392,30 +402,19 @@ fn case_match_expression(&mut self, cond: Expr, alternatives: Vec<Alternative>)
|
|||||||
|
|
||||||
return inner_state.block(alt.item)
|
return inner_state.block(alt.item)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
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 { .. } => {
|
||||||
|
return Err(format!("Prim tuple not done"))
|
||||||
|
},
|
||||||
Node::Expr(e) => {
|
Node::Expr(e) => {
|
||||||
for alt in alternatives {
|
if let None = alt.tag {
|
||||||
match (alt.guard, alt.tag) {
|
return self.block(alt.item)
|
||||||
(Some(ref guard_expr), None) => {
|
|
||||||
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,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(None, None) => return self.block(alt.item),
|
|
||||||
_ => return Err(format!("Shouldn't match an expr against a pattern"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Err(format!("Expr Failed pattern match"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
Err(format!("{:?} failed pattern match", cond))
|
||||||
|
}
|
||||||
|
|
||||||
fn value(&mut self, name: Rc<String>) -> EvalResult<Node> {
|
fn value(&mut self, name: Rc<String>) -> EvalResult<Node> {
|
||||||
use self::ValueEntry::*;
|
use self::ValueEntry::*;
|
||||||
|
@ -248,8 +248,15 @@ impl Pattern {
|
|||||||
item
|
item
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
TuplePattern(_items) => {
|
TuplePattern(subpatterns) => {
|
||||||
unimplemented!()
|
let s = handle_symbol(None, subpatterns);
|
||||||
|
Alternative {
|
||||||
|
tag: s.tag,
|
||||||
|
subpatterns: s.subpatterns,
|
||||||
|
guard: s.guard,
|
||||||
|
bound_vars: s.bound_vars,
|
||||||
|
item
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Record(_name, _pairs) => {
|
Record(_name, _pairs) => {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
|
Loading…
Reference in New Issue
Block a user