diff --git a/schala-lang/src/eval.rs b/schala-lang/src/eval.rs index 42880aa..8a2af41 100644 --- a/schala-lang/src/eval.rs +++ b/schala-lang/src/eval.rs @@ -216,7 +216,7 @@ impl<'a> State<'a> { CaseMatch { box cond, alternatives } => match self.expression(Node::Expr(cond))? { Node::PrimObject { name, tag, items } => { for alt in alternatives { - if alt.tag.map(|t| t == tag).unwrap_or(true) { + if alt.tag.map(|t| t == tag).unwrap_or(true) { //TODO add guard check - the semantics let mut inner_state = State { values: self.values.new_scope(None), symbol_table_handle: self.symbol_table_handle.clone(), diff --git a/schala-lang/src/reduced_ast.rs b/schala-lang/src/reduced_ast.rs index 96a46eb..60ecf9c 100644 --- a/schala-lang/src/reduced_ast.rs +++ b/schala-lang/src/reduced_ast.rs @@ -1,6 +1,6 @@ use std::rc::Rc; -use ast::{AST, Statement, Expression, Declaration, Discriminator, IfExpressionBody, Pattern, PatternLiteral, Guard, HalfExpr}; +use ast::{AST, Statement, Expression, ExpressionType, Declaration, Discriminator, IfExpressionBody, Pattern, PatternLiteral, Guard, HalfExpr}; use symbol_table::{Symbol, SymbolSpec, SymbolTable}; use builtin::{BinOp, PrefixOp}; @@ -136,9 +136,7 @@ impl Expression { fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody, symbol_table: &SymbolTable) -> Expr { let cond = Box::new(match *discriminator { Discriminator::Simple(ref expr) => expr.reduce(symbol_table), - Discriminator::BinOp(ref expr, ref binop) => { - panic!() - } + Discriminator::BinOp(ref expr, ref binop) => panic!("Can't yet handle binop discriminators") }); match *body { IfExpressionBody::SimpleConditional(ref then_clause, ref else_clause) => { @@ -157,7 +155,7 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody, }; let alternatives = vec![ - pat.to_alternative(then_clause, symbol_table), + pat.to_alternative(&cond, then_clause, symbol_table), Alternative { tag: None, guard: None, @@ -175,7 +173,7 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody, let alternatives = guard_arms.iter().map(|arm| match arm.guard { Guard::Pat(ref p) => { let item = arm.body.iter().map(|expr| expr.reduce(symbol_table)).collect(); - p.to_alternative(item, symbol_table) + p.to_alternative(&cond, item, symbol_table) }, Guard::HalfExpr(HalfExpr { op: _, expr: _ }) => { unimplemented!() @@ -187,7 +185,7 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody, } impl Pattern { - fn to_alternative(&self, item: Vec, symbol_table: &SymbolTable) -> Alternative { + fn to_alternative(&self, cond: &Box, item: Vec, symbol_table: &SymbolTable) -> Alternative { use self::Pattern::*; fn handle_symbol(symbol: &Symbol, subpatterns: &Vec, item: Vec) -> Alternative { @@ -221,7 +219,25 @@ impl Pattern { }, Ignored => unimplemented!(), Literal(lit) => match lit { - PatternLiteral::NumPattern { neg, num } => unimplemented!(), + PatternLiteral::NumPattern { neg, num } => { + let comparison = Expr::Lit(match (neg, num) { + (false, ExpressionType::NatLiteral(n)) => Lit::Nat(*n), + (false, ExpressionType::FloatLiteral(f)) => Lit::Float(*f), + (true, ExpressionType::NatLiteral(n)) => Lit::Int(-1*(*n as i64)), + (true, ExpressionType::FloatLiteral(f)) => Lit::Float(-1.0*f), + _ => panic!("This should never happen") + }); + let guard = Some(Expr::Call { + f: Box::new(Expr::Func(Func::BuiltIn(Rc::new("=".to_string())))), + args: vec![comparison, *cond.clone()] + }); + Alternative { + tag: None, + guard, + bound_vars: vec![], + item + } + }, PatternLiteral::StringPattern(_s) => unimplemented!(), PatternLiteral::BoolPattern(_b) => unimplemented!(), PatternLiteral::VarPattern(var) => match symbol_table.lookup_by_name(var) {