Pattern-match on structured objects
This commit is contained in:
parent
1bd48ed5db
commit
77d2826918
@ -403,6 +403,15 @@ impl<'a> State<'a> {
|
|||||||
|
|
||||||
//TODO need to handle recursive subpatterns
|
//TODO need to handle recursive subpatterns
|
||||||
let all_subpatterns_pass = |state: &mut State, subpatterns: &Vec<Option<Subpattern>>, items: &Vec<Node>| -> EvalResult<bool> {
|
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()) {
|
for (maybe_subp, cond) in subpatterns.iter().zip(items.iter()) {
|
||||||
if let Some(subp) = maybe_subp {
|
if let Some(subp) = maybe_subp {
|
||||||
if !state.guard_passes(&subp.guard, &cond)? {
|
if !state.guard_passes(&subp.guard, &cond)? {
|
||||||
@ -425,19 +434,20 @@ impl<'a> State<'a> {
|
|||||||
Node::PrimObject { ref tag, ref items, .. } => {
|
Node::PrimObject { ref tag, ref items, .. } => {
|
||||||
if alt.tag.map(|t| t == *tag).unwrap_or(true) {
|
if alt.tag.map(|t| t == *tag).unwrap_or(true) {
|
||||||
let mut inner_state = self.new_frame(items, &alt.bound_vars);
|
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 } => {
|
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);
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
return inner_state.block(alt.item)
|
|
||||||
},
|
},
|
||||||
Node::Expr(ref _e) => {
|
Node::Expr(ref _e) => {
|
||||||
if let None = alt.tag {
|
if let None = alt.tag {
|
||||||
|
Loading…
Reference in New Issue
Block a user