More pattern-matching

This commit is contained in:
greg 2018-11-05 04:02:04 -08:00
parent ec29077247
commit c394b81746
2 changed files with 27 additions and 27 deletions

View File

@ -387,37 +387,38 @@ impl<'a> State<'a> {
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> {
//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))?;
for alt in alternatives {
println!("ALTERNATIVE: {:?}", alt);
// no matter what type of condition we have, ignore alternative if the guard evaluates false
if let Some(ref guard_expr) = alt.guard {
let guard_expr = match &cond {
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)
if !self.guard_passes(&alt.guard, &cond)? {
continue;
}
match cond {

View File

@ -244,7 +244,6 @@ fn handle_symbol(symbol: Option<&Symbol>, inner_patterns: &Vec<Pattern>, symbol_
impl Pattern {
fn to_alternative(&self, item: Vec<Stmt>, symbol_table: &SymbolTable) -> Alternative {
use self::Pattern::*;
let s = self.to_subpattern(symbol_table);
Alternative {
tag: s.tag,