Boolean patterns

This commit is contained in:
greg 2018-10-17 12:43:09 -07:00
parent dc9e493fa1
commit baf51fb147
2 changed files with 38 additions and 6 deletions

View File

@ -236,23 +236,24 @@ impl<'a> State<'a> {
return inner_state.block(alt.item)
}
}
return Err(format!("Failed pattern match"));
return Err(format!("PrimObject failed pattern match"));
},
Node::PrimTuple { .. } => Err(format!("Tuples not implemented")), //TODO make a distinction between not yet implemented and an actual runtime error
Node::Expr(e) => {
for alt in alternatives {
match alt.guard {
Some(ref guard_expr) if alt.tag.is_none() => {
match (alt.guard, alt.tag) {
(Some(ref guard_expr), None) => {
match self.expression(guard_expr.clone().to_node())? {
Node::Expr(Expr::Lit(::reduced_ast::Lit::Bool(true))) =>
return self.block(alt.item),
_ => continue,
}
},
_ => ()
(None, None) => return self.block(alt.item),
_ => return Err(format!("Shouldn't match an expr against a pattern"))
}
}
return Err(format!("Failed pattern match"));
return Err(format!("Expr Failed pattern match"));
}
},
UnimplementedSigilValue => Err(format!("Sigil value eval not implemented"))
@ -526,6 +527,24 @@ if a { is 10 -> "x", is 4 -> "y" }
let source = r#"
let a = 10
if a { is 15 -> "x", is 10 -> "y" }
"#;
test_in_fresh_env!(source, "\"y\"");
}
#[test]
fn boolean_pattern() {
let source = r#"
let a = true
if a { is true -> "x", is false -> "y" }
"#;
test_in_fresh_env!(source, "\"x\"");
}
#[test]
fn boolean_pattern_2() {
let source = r#"
let a = false
if a { is true -> "x", is false -> "y" }
"#;
test_in_fresh_env!(source, "\"y\"");
}

View File

@ -240,7 +240,20 @@ impl Pattern {
},
PatternLiteral::StringPattern(_s) => unimplemented!(),
PatternLiteral::BoolPattern(b) => {
unimplemented!()
let guard = Some(if *b {
*cond.clone()
} else {
Expr::Call {
f: Box::new(Expr::Func(Func::BuiltIn(Rc::new("!".to_string())))),
args: vec![*cond.clone()]
}
});
Alternative {
tag: None,
guard,
bound_vars: vec![],
item
}
},
PatternLiteral::VarPattern(var) => match symbol_table.lookup_by_name(var) {
Some(symbol) => handle_symbol(symbol, &vec![], item),