More pattern-matching
This commit is contained in:
parent
ec29077247
commit
c394b81746
@ -387,37 +387,38 @@ impl<'a> State<'a> {
|
|||||||
Ok(Node::Expr(Expr::Unit))
|
Ok(Node::Expr(Expr::Unit))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn guard_passes(&mut self, guard: &Option<Expr>, cond: &Node) -> EvalResult<bool> {
|
||||||
|
if let Some(ref guard_expr) = guard {
|
||||||
|
let guard_expr = match cond {
|
||||||
|
Node::Expr(ref e) => guard_expr.clone().replace_conditional_target_sigil(e),
|
||||||
|
_ => guard_expr.clone()
|
||||||
|
};
|
||||||
|
Ok(self.expression(guard_expr.to_node())?.is_true())
|
||||||
|
} else {
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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> {
|
||||||
|
|
||||||
|
//TODO need to handle recursive subpatterns
|
||||||
|
let all_subpatterns_pass = |state: &mut State, subpatterns: &Vec<Option<Subpattern>>, items: &Vec<Node>| -> EvalResult<bool> {
|
||||||
|
for (maybe_subp, cond) in subpatterns.iter().zip(items.iter()) {
|
||||||
|
if let Some(subp) = maybe_subp {
|
||||||
|
if !state.guard_passes(&subp.guard, &cond)? {
|
||||||
|
return Ok(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(true)
|
||||||
|
};
|
||||||
|
|
||||||
let cond = self.expression(Node::Expr(cond))?;
|
let cond = self.expression(Node::Expr(cond))?;
|
||||||
for alt in alternatives {
|
for alt in alternatives {
|
||||||
println!("ALTERNATIVE: {:?}", alt);
|
println!("ALTERNATIVE: {:?}", alt);
|
||||||
// no matter what type of condition we have, ignore alternative if the guard evaluates false
|
// no matter what type of condition we have, ignore alternative if the guard evaluates false
|
||||||
if let Some(ref guard_expr) = alt.guard {
|
if !self.guard_passes(&alt.guard, &cond)? {
|
||||||
let guard_expr = match &cond {
|
continue;
|
||||||
Node::Expr(ref e) => guard_expr.clone().replace_conditional_target_sigil(e),
|
|
||||||
_ => guard_expr.clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
if !self.expression(guard_expr.to_node())?.is_true() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn all_subpatterns_pass(state: &mut State, subpatterns: &Vec<Option<Subpattern>>, items: &Vec<Node>) -> EvalResult<bool> {
|
|
||||||
for (maybe_subp, cond) in subpatterns.iter().zip(items.iter()) {
|
|
||||||
if let Some(subp) = maybe_subp {
|
|
||||||
if let Some(ref guard) = subp.guard {
|
|
||||||
let guard_expr = match &cond {
|
|
||||||
Node::Expr(ref e) => guard.clone().replace_conditional_target_sigil(e),
|
|
||||||
_ => guard.clone()
|
|
||||||
};
|
|
||||||
if !state.expression(guard_expr.to_node())?.is_true() {
|
|
||||||
return Ok(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match cond {
|
match cond {
|
||||||
|
@ -244,7 +244,6 @@ fn handle_symbol(symbol: Option<&Symbol>, inner_patterns: &Vec<Pattern>, symbol_
|
|||||||
|
|
||||||
impl Pattern {
|
impl Pattern {
|
||||||
fn to_alternative(&self, item: Vec<Stmt>, symbol_table: &SymbolTable) -> Alternative {
|
fn to_alternative(&self, item: Vec<Stmt>, symbol_table: &SymbolTable) -> Alternative {
|
||||||
use self::Pattern::*;
|
|
||||||
let s = self.to_subpattern(symbol_table);
|
let s = self.to_subpattern(symbol_table);
|
||||||
Alternative {
|
Alternative {
|
||||||
tag: s.tag,
|
tag: s.tag,
|
||||||
|
Loading…
Reference in New Issue
Block a user