diff --git a/schala-lang/language/src/reduced_ir/mod.rs b/schala-lang/language/src/reduced_ir/mod.rs index c46572f..a244c6b 100644 --- a/schala-lang/language/src/reduced_ir/mod.rs +++ b/schala-lang/language/src/reduced_ir/mod.rs @@ -289,8 +289,35 @@ impl<'a> Reducer<'a> { impl ast::Pattern { fn reduce(&self, symbol_table: &SymbolTable) -> Result { + Ok(match self { + ast::Pattern::Ignored => { + unimplemented!() + }, + ast::Pattern::TuplePattern(/*Vec*/..) => { + unimplemented!() - Ok(Pattern::Ignored) + }, + ast::Pattern::Literal(lit) => Pattern::Literal(match lit { + ast::PatternLiteral::NumPattern { neg, num } => match (neg, num) { + (false, ast::ExpressionKind::NatLiteral(n)) => Literal::Nat(*n), + (false, ast::ExpressionKind::FloatLiteral(f)) => Literal::Float(*f), + (true, ast::ExpressionKind::NatLiteral(n)) => Literal::Int(-(*n as i64)), + (true, ast::ExpressionKind::FloatLiteral(f)) => Literal::Float(-f), + (_, e) => return Err(format!("Internal error, unexpected pattern literal: {:?}", e).into()) + }, + ast::PatternLiteral::StringPattern(s) => Literal::StringLit(s.clone()), + ast::PatternLiteral::BoolPattern(b) => Literal::Bool(*b), + }), + ast::Pattern::TupleStruct(_name, _subpatterns) => { + unimplemented!() + }, + ast::Pattern::Record(name, /*Vec<(Rc, Pattern)>*/ _) => { + unimplemented!() + }, + ast::Pattern::VarOrName(_name) => { + unimplemented!() + }, + }) } } diff --git a/schala-lang/language/src/reduced_ir/types.rs b/schala-lang/language/src/reduced_ir/types.rs index b384134..bf52baa 100644 --- a/schala-lang/language/src/reduced_ir/types.rs +++ b/schala-lang/language/src/reduced_ir/types.rs @@ -108,7 +108,7 @@ pub enum Lookup { Param(u8), } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub enum Literal { Nat(u64), Int(i64), @@ -149,3 +149,9 @@ impl From<&str> for PatternError { Self { msg: s.to_string() } } } + +impl From for PatternError { + fn from(msg: String) -> Self { + Self { msg } + } +} diff --git a/schala-lang/language/src/tree_walk_eval/mod.rs b/schala-lang/language/src/tree_walk_eval/mod.rs index f3f7152..a41d5eb 100644 --- a/schala-lang/language/src/tree_walk_eval/mod.rs +++ b/schala-lang/language/src/tree_walk_eval/mod.rs @@ -277,12 +277,17 @@ impl<'a> State<'a> { fn case_match_expression(&mut self, cond: Expression, alternatives: Vec) -> EvalResult { - fn matches(cond: &Expression, matcher: &Pattern) -> bool { - - - - false + fn matches(scrut: &Primitive, pat: &Pattern) -> bool { + match pat { + Pattern::Ignored => true, + Pattern::Literal(pat_literal) => if let Primitive::Literal(scrut_literal) = scrut { + pat_literal == scrut_literal + } else { + false + }, + } } + let cond = self.expression(cond)?; for alt in alternatives.into_iter() { if matches(&cond, &alt.pattern) { diff --git a/schala-lang/language/src/tree_walk_eval/test.rs b/schala-lang/language/src/tree_walk_eval/test.rs index 40a1646..9287920 100644 --- a/schala-lang/language/src/tree_walk_eval/test.rs +++ b/schala-lang/language/src/tree_walk_eval/test.rs @@ -85,6 +85,19 @@ fn basic_if_statement() { eval_assert(source, "69"); } +#[test] +fn basic_patterns() { + let source =r#" +let x = 10 +let a = if x is 10 then { 255 } else { 256 } +let b = if 23 is 99 then { 255 } else { 256 } +let c = if true is false then { 9 } else { 10 } +let d = if "xxx" is "yyy" then { 20 } else { 30 } +(a, b, c, d) + "#; + eval_assert(source, "(255, 256, 10, 30)"); +} + #[test] fn if_is_patterns() { let source = r#"