From baf51fb1471f0c666908ccef49687d7f38cd9298 Mon Sep 17 00:00:00 2001 From: greg Date: Wed, 17 Oct 2018 12:43:09 -0700 Subject: [PATCH] Boolean patterns --- schala-lang/src/eval.rs | 29 ++++++++++++++++++++++++----- schala-lang/src/reduced_ast.rs | 15 ++++++++++++++- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/schala-lang/src/eval.rs b/schala-lang/src/eval.rs index 17daee1..de5b58f 100644 --- a/schala-lang/src/eval.rs +++ b/schala-lang/src/eval.rs @@ -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")) @@ -529,4 +530,22 @@ 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\""); + } } diff --git a/schala-lang/src/reduced_ast.rs b/schala-lang/src/reduced_ast.rs index f761a01..12613d7 100644 --- a/schala-lang/src/reduced_ast.rs +++ b/schala-lang/src/reduced_ast.rs @@ -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),