From 55a8cabd7c291d34e5be4271aa492935cc696c2c Mon Sep 17 00:00:00 2001 From: greg Date: Sun, 1 Jul 2018 01:26:19 -0700 Subject: [PATCH] Some basic pattern stuff --- schala-lang/src/ast.rs | 16 +++++++++-- schala-lang/src/parsing.rs | 58 ++++++++++++++++++++++++++++++++++---- 2 files changed, 66 insertions(+), 8 deletions(-) diff --git a/schala-lang/src/ast.rs b/schala-lang/src/ast.rs index e04d7fb..df4a28f 100644 --- a/schala-lang/src/ast.rs +++ b/schala-lang/src/ast.rs @@ -131,9 +131,19 @@ pub struct Guard { } #[derive(Debug, PartialEq, Clone)] -pub struct Pattern { - pub free_vars: Vec>, - pub var: Variant, +pub enum Pattern { + TuplePattern(Vec), + Literal(PatternLiteral), + TupleStruct(Rc, Vec), + Record(Rc, Vec<(Rc, Pattern)>), +} + +#[derive(Debug, PartialEq, Clone)] +pub enum PatternLiteral { + NumPattern(ExpressionType), + StringPattern(Rc), + BoolPattern(bool), + VarPattern(Rc) } #[derive(Debug, PartialEq, Clone)] diff --git a/schala-lang/src/parsing.rs b/schala-lang/src/parsing.rs index 8846bd9..15f6f59 100644 --- a/schala-lang/src/parsing.rs +++ b/schala-lang/src/parsing.rs @@ -107,10 +107,17 @@ else_clause := ε | 'else' block match_expr := 'match' expression match_body match_body := '{' (match_arm)* '}' match_arm := pattern '=>' expression -pattern := identifier //TODO NOT DONE /* NEW GOOD */ +/* Pattern syntax */ +pattern := '(' (pattern, ',')* ')' | simple_pattern +simple_pattern := pattern_literal | record_pattern | tuple_struct_pattern +pattern_literal := 'true' | 'false' | number_literal | STR_LITERAL | IDENTIFIER +record_pattern := IDENTIFIER '{' (record_pattern_entry, ',')* '}' +record_pattern_entry := ??? +tuple_struct_pattern := IDENTIFIER '(' (pattern, ',')* ')' + /* Expression - If */ if_expr := 'if' discriminator ('then' condititional | 'is' simple_pattern_match | guard_block) discriminator := modified_precedence_expression @@ -678,10 +685,51 @@ impl Parser { }); parse_method!(pattern(&mut self) -> ParseResult { - let identifier = self.identifier()?; - Ok(Pattern { - free_vars: vec![], - var: Variant::UnitStruct(identifier) + if let LParen = self.peek() { + let tuple_pattern_variants = delimited!(self, LParen, pattern, Comma, RParen); + Ok(Pattern::TuplePattern(tuple_pattern_variants)) + } else { + self.simple_pattern() + } + }); + + parse_method!(simple_pattern(&mut self) -> ParseResult { + /* + let name = self.identifier()?; + match self.peek() { + LParen => { + let tuple_members = delimited!(self, LParen, type_name, Comma, RParen); + Ok(TupleStruct(name, tuple_members)) + }, + LCurlyBrace => { + let typed_identifier_list = delimited!(self, LCurlyBrace, typed_identifier, Comma, RCurlyBrace); + Ok(Record(name, typed_identifier_list)) + }, + _ => Ok(UnitStruct(name)) + } + */ + + Ok(match self.peek() { + Identifier(_) => { + let id = self.identifier()?; + match self.peek() { + LCurlyBrace => { unimplemented!() }, + LParen => { + let members = delimited!(self, LParen, pattern, Comma, RParen); + Pattern::TupleStruct(id, members) + }, + _ => Pattern::Literal(PatternLiteral::VarPattern(id)) + } + }, + Keyword(Kw::True) => Pattern::Literal(PatternLiteral::BoolPattern(true)), + Keyword(Kw::False) => Pattern::Literal(PatternLiteral::BoolPattern(false)), + StrLiteral(s) => Pattern::Literal(PatternLiteral::StringPattern(s)), + DigitGroup(_) | HexLiteral(_) | BinNumberSigil | Period => { + //TODO handle negatives + let Expression(expr_type, _) = self.number_literal()?; + Pattern::Literal(PatternLiteral::NumPattern(expr_type)) + }, + other => return ParseError::new(&format!("{:?} is not a valid Pattern", other)) }) });