diff --git a/schala-lang/language/src/eval.rs b/schala-lang/language/src/eval.rs index 60e635b..50a51dd 100644 --- a/schala-lang/language/src/eval.rs +++ b/schala-lang/language/src/eval.rs @@ -372,6 +372,7 @@ impl<'a> State<'a> { fn case_match_expression(&mut self, cond: Expr, alternatives: Vec) -> EvalResult { let cond = self.expression(Node::Expr(cond))?; for alt in alternatives { + println!("ALT: {:?}", alt); // no matter what type of condition we have, ignore alternative if the guard evaluates false if let Some(ref guard_expr) = alt.guard { let guard_expr = match &cond { @@ -406,7 +407,7 @@ impl<'a> State<'a> { return inner_state.block(alt.item) } }, - Node::PrimTuple { .. } => { + Node::PrimTuple { ref items } => { return Err(format!("Prim tuple not done")) }, Node::Expr(ref _e) => { diff --git a/schala-lang/language/src/reduced_ast.rs b/schala-lang/language/src/reduced_ast.rs index 112dc43..fcf8c86 100644 --- a/schala-lang/language/src/reduced_ast.rs +++ b/schala-lang/language/src/reduced_ast.rs @@ -65,12 +65,6 @@ pub struct Alternative { pub item: Vec, } -impl Alternative { - fn default(item: Vec) -> Alternative { - Alternative { tag: None, subpatterns: vec![], guard: None, bound_vars: vec![], item } - } -} - #[derive(Debug, Clone)] pub struct Subpattern { pub tag: Option, @@ -172,7 +166,13 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody, let alternatives = vec![ pat.to_alternative(then_clause, symbol_table), - Alternative::default(else_clause), + Alternative { + tag: None, + subpatterns: vec![], + bound_vars: vec![], + guard: None, + item: else_clause + }, ]; Expr::CaseMatch { @@ -202,17 +202,27 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody, * x is SomeBigOldEnum(_, x, Some(t)) */ -fn handle_symbol(symbol: Option<&Symbol>, subpatterns: &Vec) -> Subpattern { +fn handle_symbol(symbol: Option<&Symbol>, inner_patterns: &Vec, symbol_table: &SymbolTable) -> Subpattern { use self::Pattern::*; let tag = symbol.map(|symbol| match symbol.spec { SymbolSpec::DataConstructor { index, .. } => index.clone(), _ => panic!("Symbol is not a data constructor - this should've been caught in type-checking"), }); - let bound_vars = subpatterns.iter().map(|p| match p { + let bound_vars = inner_patterns.iter().map(|p| match p { Literal(PatternLiteral::VarPattern(var)) => Some(var.clone()), _ => None, }).collect(); + let subpatterns = inner_patterns.iter().map(|p| match p { + Ignored => None, + Literal(PatternLiteral::VarPattern(_)) => None, + Literal(other) => Some(other.to_subpattern(symbol_table)), + tp @ TuplePattern(_) => Some(tp.to_subpattern(symbol_table)), + ts @ TupleStruct(_, _) => Some(ts.to_subpattern(symbol_table)), + Record(..) => unimplemented!(), + }).collect(); + + let guard = None; /* let guard_equality_exprs: Vec = subpatterns.iter().map(|p| match p { Literal(lit) => match lit { @@ -222,9 +232,6 @@ fn handle_symbol(symbol: Option<&Symbol>, subpatterns: &Vec) -> Subpatt }).collect(); */ - let guard = None; - let subpatterns = vec![]; - Subpattern { tag, subpatterns, @@ -235,43 +242,30 @@ fn handle_symbol(symbol: Option<&Symbol>, subpatterns: &Vec) -> Subpatt impl Pattern { fn to_alternative(&self, item: Vec, symbol_table: &SymbolTable) -> Alternative { + use self::Pattern::*; + let s = self.to_subpattern(symbol_table); + Alternative { + tag: s.tag, + subpatterns: s.subpatterns, + bound_vars: s.bound_vars, + guard: s.guard, + item + } + } + + fn to_subpattern(&self, symbol_table: &SymbolTable) -> Subpattern { use self::Pattern::*; match self { - TupleStruct(name, subpatterns) => { + TupleStruct(name, inner_patterns) => { let symbol = symbol_table.lookup_by_name(name).expect(&format!("Symbol {} not found", name)); - let s = handle_symbol(Some(symbol), subpatterns); - Alternative { - tag: s.tag, - subpatterns: s.subpatterns, - guard: s.guard, - bound_vars: s.bound_vars, - item - } - }, - TuplePattern(subpatterns) => { - let s = handle_symbol(None, subpatterns); - Alternative { - tag: s.tag, - subpatterns: s.subpatterns, - guard: s.guard, - bound_vars: s.bound_vars, - item - } + handle_symbol(Some(symbol), inner_patterns, symbol_table) }, + TuplePattern(inner_patterns) => handle_symbol(None, inner_patterns, symbol_table), Record(_name, _pairs) => { unimplemented!() }, - Ignored => Alternative::default(item), - Literal(lit) => { - let s = lit.to_subpattern(symbol_table); - Alternative { - tag: s.tag, - subpatterns: s.subpatterns, - bound_vars: s.bound_vars, - guard: s.guard, - item - } - }, + Ignored => Subpattern { tag: None, subpatterns: vec![], guard: None, bound_vars: vec![] }, + Literal(lit) => lit.to_subpattern(symbol_table), } } } @@ -329,7 +323,7 @@ impl PatternLiteral { } }, VarPattern(var) => match symbol_table.lookup_by_name(var) { - Some(symbol) => handle_symbol(Some(symbol), &vec![]), + Some(symbol) => handle_symbol(Some(symbol), &vec![], symbol_table), None => Subpattern { tag: None, subpatterns: vec![],