Pattern-match on structured objects

This commit is contained in:
greg 2018-11-05 14:01:14 -08:00
parent 1bd48ed5db
commit 77d2826918
1 changed files with 17 additions and 7 deletions

View File

@ -403,6 +403,15 @@ impl<'a> State<'a> {
//TODO need to handle recursive subpatterns
let all_subpatterns_pass = |state: &mut State, subpatterns: &Vec<Option<Subpattern>>, items: &Vec<Node>| -> EvalResult<bool> {
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 {