diff --git a/schala-lang/language/src/reduced_ast.rs b/schala-lang/language/src/reduced_ast.rs index 7fbd7a8..8189ae6 100644 --- a/schala-lang/language/src/reduced_ast.rs +++ b/schala-lang/language/src/reduced_ast.rs @@ -202,41 +202,40 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody, * x is SomeBigOldEnum(_, x, Some(t)) */ +fn handle_symbol(symbol: &Symbol, subpatterns: &Vec) -> Subpattern { + use self::Pattern::*; + let tag = 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 { + Literal(PatternLiteral::VarPattern(var)) => Some(var.clone()), + _ => None, + }).collect(); + + /* + let guard_equality_exprs: Vec = subpatterns.iter().map(|p| match p { + Literal(lit) => match lit { + _ => unimplemented!() + }, + _ => unimplemented!() + }).collect(); + */ + + let guard = None; + let subpatterns = vec![]; + + Subpattern { + tag: Some(tag), + subpatterns, + guard, + bound_vars, + } +} impl Pattern { fn to_alternative(&self, item: Vec, symbol_table: &SymbolTable) -> Alternative { use self::Pattern::*; - - fn handle_symbol(symbol: &Symbol, subpatterns: &Vec) -> Subpattern { - let tag = 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 { - Literal(PatternLiteral::VarPattern(var)) => Some(var.clone()), - _ => None, - }).collect(); - - /* - let guard_equality_exprs: Vec = subpatterns.iter().map(|p| match p { - Literal(lit) => match lit { - _ => unimplemented!() - }, - _ => unimplemented!() - }).collect(); - */ - - let guard = None; - let subpatterns = vec![]; - - Subpattern { - tag: Some(tag), - subpatterns, - guard, - bound_vars, - } - } - match self { TupleStruct(name, subpatterns) => { let symbol = symbol_table.lookup_by_name(name).expect(&format!("Symbol {} not found", name)); @@ -256,69 +255,73 @@ impl Pattern { unimplemented!() }, Ignored => Alternative::default(item), - Literal(lit) => match lit { - 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, Expr::ConditionalTargetSigilValue], - }); - Alternative { - tag: None, - subpatterns: vec![], - guard, - bound_vars: vec![], - item - } - }, - PatternLiteral::StringPattern(_s) => unimplemented!(), - PatternLiteral::BoolPattern(b) => { - let guard = Some(if *b { - Expr::ConditionalTargetSigilValue - } else { - Expr::Call { - f: Box::new(Expr::Func(Func::BuiltIn(Rc::new("!".to_string())))), - args: vec![Expr::ConditionalTargetSigilValue] - } - }); - Alternative { - tag: None, - subpatterns: vec![], - guard, - bound_vars: vec![], - item - } - }, - PatternLiteral::VarPattern(var) => match symbol_table.lookup_by_name(var) { - Some(symbol) => { - let s = handle_symbol(symbol, &vec![]); - Alternative { - tag: s.tag, - subpatterns: s.subpatterns, - guard: s.guard, - bound_vars: s.bound_vars, - item - } - }, - None => Alternative { - tag: None, - subpatterns: vec![], - guard: None, - bound_vars: vec![Some(var.clone())], - 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 } }, } } } +impl PatternLiteral { + fn to_subpattern(&self, symbol_table: &SymbolTable) -> Subpattern { + use self::PatternLiteral::*; + match self { + 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, Expr::ConditionalTargetSigilValue], + }); + Subpattern { + tag: None, + subpatterns: vec![], + guard, + bound_vars: vec![], + } + }, + StringPattern(_s) => unimplemented!(), + BoolPattern(b) => { + let guard = Some(if *b { + Expr::ConditionalTargetSigilValue + } else { + Expr::Call { + f: Box::new(Expr::Func(Func::BuiltIn(Rc::new("!".to_string())))), + args: vec![Expr::ConditionalTargetSigilValue] + } + }); + Subpattern { + tag: None, + subpatterns: vec![], + guard, + bound_vars: vec![], + } + }, + VarPattern(var) => match symbol_table.lookup_by_name(var) { + Some(symbol) => handle_symbol(symbol, &vec![]), + None => Subpattern { + tag: None, + subpatterns: vec![], + guard: None, + bound_vars: vec![Some(var.clone())], + } + } + } + } +} + impl Declaration { fn reduce(&self, symbol_table: &SymbolTable) -> Stmt { use self::Declaration::*;