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))
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user