From 6162d05b6064cb743b085c0006b556a031c640b5 Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Mon, 25 Oct 2021 21:19:26 -0700 Subject: [PATCH] Starting on case-matching --- schala-lang/language/src/reduced_ast/mod.rs | 5 +- schala-lang/language/src/reduced_ir/mod.rs | 87 ++++++++++++++++++- schala-lang/language/src/reduced_ir/types.rs | 18 ++++ .../language/src/tree_walk_eval/mod.rs | 3 + 4 files changed, 108 insertions(+), 5 deletions(-) diff --git a/schala-lang/language/src/reduced_ast/mod.rs b/schala-lang/language/src/reduced_ast/mod.rs index 12ac4cd..107e29b 100644 --- a/schala-lang/language/src/reduced_ast/mod.rs +++ b/schala-lang/language/src/reduced_ast/mod.rs @@ -243,9 +243,8 @@ impl<'a> Reducer<'a> { item: else_clause, }, ]; - - Expr::CaseMatch { cond, alternatives } - } + Expression::CaseMatch { cond, alternatives } + }, IfExpressionBody::CondList(ref condition_arms) => { let mut alternatives = vec![]; for arm in condition_arms { diff --git a/schala-lang/language/src/reduced_ir/mod.rs b/schala-lang/language/src/reduced_ir/mod.rs index c203563..13f0333 100644 --- a/schala-lang/language/src/reduced_ir/mod.rs +++ b/schala-lang/language/src/reduced_ir/mod.rs @@ -148,12 +148,14 @@ impl<'a> Reducer<'a> { } fn reduce_if_expression(&mut self, discriminator: Option<&ast::Expression>, body: &ast::IfExpressionBody) -> Expression { + use ast::IfExpressionBody::*; + let cond = Box::new(match discriminator { Some(expr) => self.expression(expr), None => return Expression::ReductionError("blank cond if-expr not supported".to_string()), }); match body { - ast::IfExpressionBody::SimpleConditional { + SimpleConditional { then_case, else_case, } => { @@ -168,7 +170,34 @@ impl<'a> Reducer<'a> { else_clause, } }, - _ => Expression::ReductionError("if expr".to_string()) + SimplePatternMatch { + pattern, + then_case, + else_case, + } => { + let alternatives = vec![ + Alternative { + matchable: pattern.to_subpattern(self.symbol_table), + item: self.function_internal_block(then_case), + }, + Alternative { + matchable: Subpattern { + tag: None, + subpatterns: vec![], + guard: None, + }, + item: match else_case.as_ref() { + Some(else_case) => self.function_internal_block(else_case), + None => vec![], + }, + }, + ]; + + Expression::CaseMatch { cond, alternatives } + }, + CondList(ref condition_arms) => { + Expression::ReductionError("if expr".to_string()) + } } } @@ -258,3 +287,57 @@ impl<'a> Reducer<'a> { } } } + +impl ast::Pattern { + + fn to_subpattern(&self, symbol_table: &SymbolTable) -> Subpattern { + Subpattern { + tag: None, + subpatterns: vec![], + guard: None, + } + /* + use self::Pattern::*; + match self { + TupleStruct(QualifiedName { components, id }, inner_patterns) => { + match symbol_table.lookup_symbol(id) { + Some(symbol) => handle_symbol(Some(symbol), inner_patterns, symbol_table), + None => panic!("Symbol {:?} not found", components), + } + } + TuplePattern(inner_patterns) => handle_symbol(None, inner_patterns, symbol_table), + Record(_name, _pairs) => { + unimplemented!() + } + Ignored => Subpattern { + tag: None, + subpatterns: vec![], + guard: None, + bound_vars: vec![], + }, + Literal(lit) => lit.to_subpattern(symbol_table), + VarOrName(QualifiedName { components, id }) => { + // if symbol is Some, treat this as a symbol pattern. If it's None, treat it + // as a variable. + match symbol_table.lookup_symbol(id) { + Some(symbol) => handle_symbol(Some(symbol), &[], symbol_table), + None => { + println!("Components: {:?}", components); + let name = if components.len() == 1 { + components[0].clone() + } else { + panic!("check this line of code yo"); + }; + Subpattern { + tag: None, + subpatterns: vec![], + guard: None, + bound_vars: vec![Some(name)], + } + } + } + } + } + */ + } +} diff --git a/schala-lang/language/src/reduced_ir/types.rs b/schala-lang/language/src/reduced_ir/types.rs index 9e0dca7..f046971 100644 --- a/schala-lang/language/src/reduced_ir/types.rs +++ b/schala-lang/language/src/reduced_ir/types.rs @@ -66,6 +66,10 @@ pub enum Expression { then_clause: Vec, else_clause: Vec, }, + CaseMatch { + cond: Box, + alternatives: Vec, + }, ReductionError(String), } @@ -111,3 +115,17 @@ pub enum Literal { Bool(bool), StringLit(Rc), } + +#[derive(Debug, Clone)] +pub struct Alternative { + pub matchable: Subpattern, + pub item: Vec, +} + +#[derive(Debug, Clone)] +pub struct Subpattern { + pub tag: Option, + pub subpatterns: Vec>, + //pub bound_vars: BoundVars, + pub guard: Option, +} diff --git a/schala-lang/language/src/tree_walk_eval/mod.rs b/schala-lang/language/src/tree_walk_eval/mod.rs index 3d59b9c..7afe402 100644 --- a/schala-lang/language/src/tree_walk_eval/mod.rs +++ b/schala-lang/language/src/tree_walk_eval/mod.rs @@ -270,6 +270,9 @@ impl<'a> State<'a> { v => return Err(format!("Non-boolean value {:?} in if-statement", v).into()) } }, + Expression::CaseMatch { cond, alternatives } => { + panic!() + }, Expression::ReductionError(e) => return Err(e.into()), }) }