Starting on pattern-matching tuples
Lots of duplicated code here
This commit is contained in:
parent
bada386979
commit
62043ac2d1
@ -72,6 +72,12 @@ impl Node {
|
|||||||
Node::PrimTuple { items } => format!("{}", paren_wrapped_vec(items.iter().map(|x| x.to_repl()))),
|
Node::PrimTuple { items } => format!("{}", paren_wrapped_vec(items.iter().map(|x| x.to_repl()))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn is_true(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Node::Expr(Expr::Lit(::reduced_ast::Lit::Bool(true))) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -372,16 +378,16 @@ impl<'a> State<'a> {
|
|||||||
fn case_match_expression(&mut self, cond: Expr, alternatives: Vec<Alternative>) -> EvalResult<Node> {
|
fn case_match_expression(&mut self, cond: Expr, alternatives: Vec<Alternative>) -> EvalResult<Node> {
|
||||||
let cond = self.expression(Node::Expr(cond))?;
|
let cond = self.expression(Node::Expr(cond))?;
|
||||||
for alt in alternatives {
|
for alt in alternatives {
|
||||||
println!("ALT: {:?}", alt);
|
println!("ALTERNATIVE: {:?}", alt);
|
||||||
// no matter what type of condition we have, ignore alternative if the guard evaluates false
|
// no matter what type of condition we have, ignore alternative if the guard evaluates false
|
||||||
if let Some(ref guard_expr) = alt.guard {
|
if let Some(ref guard_expr) = alt.guard {
|
||||||
let guard_expr = match &cond {
|
let guard_expr = match &cond {
|
||||||
Node::Expr(ref e) => guard_expr.clone().replace_conditional_target_sigil(e),
|
Node::Expr(ref e) => guard_expr.clone().replace_conditional_target_sigil(e),
|
||||||
_ => guard_expr.clone()
|
_ => guard_expr.clone()
|
||||||
};
|
};
|
||||||
match self.expression(guard_expr.to_node())? {
|
|
||||||
Node::Expr(Expr::Lit(::reduced_ast::Lit::Bool(true))) => (),
|
if !self.expression(guard_expr.to_node())?.is_true() {
|
||||||
_ => continue,
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,17 +404,43 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(guard_expr) = alt.guard {
|
|
||||||
let evaled_guard = inner_state.expression(guard_expr.to_node());
|
|
||||||
println!("EVALED GUARD: {:?}", evaled_guard);
|
|
||||||
//continue
|
|
||||||
}
|
|
||||||
|
|
||||||
return inner_state.block(alt.item)
|
return inner_state.block(alt.item)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Node::PrimTuple { ref items } => {
|
Node::PrimTuple { ref items } => {
|
||||||
return Err(format!("Prim tuple not done"))
|
if items.len() != alt.subpatterns.len() {
|
||||||
|
return Err(format!("Subpattern length isn't correct"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut inner_state = State {
|
||||||
|
values: self.values.new_scope(None),
|
||||||
|
symbol_table_handle: self.symbol_table_handle.clone(),
|
||||||
|
};
|
||||||
|
for (bound_var, val) in alt.bound_vars.iter().zip(items.iter()) {
|
||||||
|
if let Some(bv) = bound_var.as_ref() {
|
||||||
|
inner_state.values.insert(bv.clone(), ValueEntry::Binding { constant: true, val: val.clone() });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut passes = true;
|
||||||
|
for (maybe_subp, cond) in alt.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 !inner_state.expression(guard_expr.to_node())?.is_true() {
|
||||||
|
passes = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !passes {
|
||||||
|
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