From 77d2826918e9013efaf70bfe7884aaeb46075feb Mon Sep 17 00:00:00 2001 From: greg Date: Mon, 5 Nov 2018 14:01:14 -0800 Subject: [PATCH] Pattern-match on structured objects --- schala-lang/language/src/eval.rs | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/schala-lang/language/src/eval.rs b/schala-lang/language/src/eval.rs index ec820f6..a10e538 100644 --- a/schala-lang/language/src/eval.rs +++ b/schala-lang/language/src/eval.rs @@ -403,6 +403,15 @@ impl<'a> State<'a> { //TODO need to handle recursive subpatterns let all_subpatterns_pass = |state: &mut State, subpatterns: &Vec>, items: &Vec| -> EvalResult { + + if subpatterns.len() == 0 { + return Ok(true) + } + + if items.len() != subpatterns.len() { + return Err(format!("Subpattern length isn't correct items {} subpatterns {}", items.len(), subpatterns.len())); + } + for (maybe_subp, cond) in subpatterns.iter().zip(items.iter()) { if let Some(subp) = maybe_subp { if !state.guard_passes(&subp.guard, &cond)? { @@ -425,19 +434,20 @@ impl<'a> State<'a> { Node::PrimObject { ref tag, ref items, .. } => { if alt.tag.map(|t| t == *tag).unwrap_or(true) { let mut inner_state = self.new_frame(items, &alt.bound_vars); - return inner_state.block(alt.item) + if all_subpatterns_pass(&mut inner_state, &alt.subpatterns, items)? { + return inner_state.block(alt.item); + } else { + continue; + } } }, Node::PrimTuple { ref items } => { - if items.len() != alt.subpatterns.len() { - return Err(format!("Subpattern length isn't correct")); - } - let mut inner_state = self.new_frame(items, &alt.bound_vars); - if !all_subpatterns_pass(&mut inner_state, &alt.subpatterns, items)? { + if all_subpatterns_pass(&mut inner_state, &alt.subpatterns, items)? { + return inner_state.block(alt.item); + } else { continue; } - return inner_state.block(alt.item) }, Node::Expr(ref _e) => { if let None = alt.tag {