From 927f427a862b2da5ee9e10bcd37a0c225650450f Mon Sep 17 00:00:00 2001 From: greg Date: Wed, 20 Jun 2018 02:07:11 -0700 Subject: [PATCH] Starting work on patterns --- schala-lang/src/ast.rs | 1 + schala-lang/src/parsing.rs | 28 +++++++++++++++++++--------- schala-lang/src/reduced_ast.rs | 8 ++++++++ 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/schala-lang/src/ast.rs b/schala-lang/src/ast.rs index f01258f..b1e728a 100644 --- a/schala-lang/src/ast.rs +++ b/schala-lang/src/ast.rs @@ -120,6 +120,7 @@ pub enum Discriminator { #[derive(Debug, PartialEq, Clone)] pub enum IfExpressionBody { SimpleConditional(Block, Option), + SimplePatternMatch(Pattern, Block, Option), GuardList(Vec) } diff --git a/schala-lang/src/parsing.rs b/schala-lang/src/parsing.rs index 7018e2d..429cc42 100644 --- a/schala-lang/src/parsing.rs +++ b/schala-lang/src/parsing.rs @@ -112,7 +112,7 @@ pattern := identifier //TODO NOT DONE /* NEW GOOD */ /* Expression - If */ -if_expr := 'if' discriminator ('then' condititional | guard_block) +if_expr := 'if' discriminator ('then' condititional | 'is' pattern 'then' conditional | guard_block) discriminator := modified_precedence_expression conditional := block else_clause else_clause := ε | 'else' block @@ -634,10 +634,10 @@ impl Parser { x? }); - let body = Box::new(if let Keyword(Kw::Then) = self.peek() { - self.conditional()? - } else { - self.guard_block()? + let body = Box::new(match self.peek() { + Keyword(Kw::Then) => self.conditional()?, + Keyword(Kw::Is) => self.simple_pattern_match()? , + _ => self.guard_block()? }); Ok(Expression(ExpressionType::IfExpression { discriminator, body }, None)) @@ -654,6 +654,15 @@ impl Parser { Ok(IfExpressionBody::SimpleConditional(then_clause, else_clause)) }); + parse_method!(simple_pattern_match(&mut self) -> ParseResult { + expect!(self, Keyword(Kw::Is)); + let pat = self.pattern()?; + expect!(self, Keyword(Kw::Then)); + let then_clause = self.block()?; //TODO should be block_or_expr + let else_clause = self.else_clause()?; + Ok(IfExpressionBody::SimplePatternMatch(pat, then_clause, else_clause)) + }); + parse_method!(guard_block(&mut self) -> ParseResult { ParseError::new("Rest of if not done") }); @@ -667,6 +676,11 @@ impl Parser { }) }); + parse_method!(pattern(&mut self) -> ParseResult { + let identifier = self.identifier()?; + Ok(Pattern { }) + }); + parse_method!(block(&mut self) -> ParseResult { Ok(delimited!(self, LCurlyBrace, statement, Newline | Semicolon, RCurlyBrace, nonstrict)) }); @@ -695,10 +709,6 @@ impl Parser { Ok(MatchArm { pat, expr }) }); - parse_method!(pattern(&mut self) -> ParseResult { - let identifier = self.identifier()?; - Ok(Pattern(identifier)) - }); */ parse_method!(while_expr(&mut self) -> ParseResult { diff --git a/schala-lang/src/reduced_ast.rs b/schala-lang/src/reduced_ast.rs index 518d116..854fb36 100644 --- a/schala-lang/src/reduced_ast.rs +++ b/schala-lang/src/reduced_ast.rs @@ -126,6 +126,14 @@ impl Expression { }; Expr::Conditional { cond, then_clause, else_clause } }, + IfExpressionBody::SimplePatternMatch(ref pat, ref then_clause, ref else_clause) => { + let then_clause = then_clause.iter().map(|expr| expr.reduce(symbol_table)).collect(); + let else_clause = match else_clause { + None => vec![], + Some(stmts) => stmts.iter().map(|expr| expr.reduce(symbol_table)).collect(), + }; + Expr::Conditional { cond, then_clause, else_clause } + }, _ => panic!(), } },