From c394b8174656484bb3d2fec03c8af831503f8417 Mon Sep 17 00:00:00 2001 From: greg Date: Mon, 5 Nov 2018 04:02:04 -0800 Subject: [PATCH] More pattern-matching --- schala-lang/language/src/eval.rs | 53 +++++++++++++------------ schala-lang/language/src/reduced_ast.rs | 1 - 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/schala-lang/language/src/eval.rs b/schala-lang/language/src/eval.rs index 44e266a..63dbdff 100644 --- a/schala-lang/language/src/eval.rs +++ b/schala-lang/language/src/eval.rs @@ -387,37 +387,38 @@ impl<'a> State<'a> { Ok(Node::Expr(Expr::Unit)) } + fn guard_passes(&mut self, guard: &Option, cond: &Node) -> EvalResult { + 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) -> EvalResult { + + //TODO need to handle recursive subpatterns + let all_subpatterns_pass = |state: &mut State, subpatterns: &Vec>, items: &Vec| -> EvalResult { + 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>, items: &Vec) -> EvalResult { - 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 { diff --git a/schala-lang/language/src/reduced_ast.rs b/schala-lang/language/src/reduced_ast.rs index 05fab9d..96e0a5c 100644 --- a/schala-lang/language/src/reduced_ast.rs +++ b/schala-lang/language/src/reduced_ast.rs @@ -244,7 +244,6 @@ fn handle_symbol(symbol: Option<&Symbol>, inner_patterns: &Vec, symbol_ impl Pattern { fn to_alternative(&self, item: Vec, symbol_table: &SymbolTable) -> Alternative { - use self::Pattern::*; let s = self.to_subpattern(symbol_table); Alternative { tag: s.tag,