From e006a12c807c06c8067b07cd7a3f8ebcf7602f00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Sun, 8 Jan 2023 11:22:49 +0100 Subject: [PATCH] Parser - Support for get expressions --- src/parser.rs | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 3d2de45..d3e9b7f 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,7 +1,7 @@ use std::collections::HashSet; use crate::{ - ast::{ClassDecl, ExprNode, FunDecl, ProgramNode, StmtNode}, + ast::{ClassDecl, ExprNode, FunDecl, GetExpr, ProgramNode, StmtNode}, errors::{ErrorHandler, ErrorKind, SloxError, SloxResult}, tokens::{Token, TokenType}, }; @@ -674,11 +674,13 @@ impl Parser { Ok(expr) } - /// Parse the following rule: + /// Parse the following rules: /// ``` /// unary := "-" unary /// unary := "!" unary - /// unary := primary call_arguments* + /// unary := primary call_or_get* + /// call_or_get := call_arguments + /// call_or_get := "." IDENTIFIER /// ``` fn parse_unary(&mut self) -> SloxResult { if let Some(operator) = self.expect(&[TokenType::Bang, TokenType::Minus]) { @@ -688,8 +690,20 @@ impl Parser { }) } else { let mut expr = self.parse_primary()?; - while self.expect(&[TokenType::LeftParen]).is_some() { - expr = self.parse_call_arguments(expr)?; + while let Some(token) = self.expect(&[TokenType::LeftParen, TokenType::Dot]) { + expr = match token.token_type { + TokenType::LeftParen => self.parse_call_arguments(expr)?, + TokenType::Dot => { + if !self.peek().is_identifier() { + return self.error("property name expected"); + } + ExprNode::Get(GetExpr { + instance: Box::new(expr), + name: self.advance().clone(), + }) + } + _ => panic!("unexpected token type"), + } } Ok(expr) }