Parser - Handle super.method

This commit is contained in:
Emmanuel BENOîT 2023-01-15 18:58:29 +01:00
parent 2a8230ac80
commit d6f03f1429

View file

@ -3,7 +3,7 @@ use std::collections::HashSet;
use crate::{ use crate::{
ast::{ ast::{
BinaryExpr, ClassDecl, ClassMemberDecl, ClassMemberKind, ExprNode, FunDecl, GetExpr, BinaryExpr, ClassDecl, ClassMemberDecl, ClassMemberKind, ExprNode, FunDecl, GetExpr,
ProgramNode, SetExpr, StmtNode, VariableExpr, ProgramNode, SetExpr, StmtNode, SuperExpr, VariableExpr,
}, },
errors::{ErrorHandler, ErrorKind, SloxError, SloxResult}, errors::{ErrorHandler, ErrorKind, SloxError, SloxResult},
tokens::{Token, TokenType}, tokens::{Token, TokenType},
@ -738,22 +738,35 @@ impl Parser {
/// primary := FALSE | TRUE | NIL | STRING | NUMBER /// primary := FALSE | TRUE | NIL | STRING | NUMBER
/// primary := IDENTIFIER /// primary := IDENTIFIER
/// primary := "fun" function_info /// primary := "fun" function_info
/// primary := "super" "." IDENTIFIER
/// ``` /// ```
fn parse_primary(&mut self) -> SloxResult<ExprNode> { fn parse_primary(&mut self) -> SloxResult<ExprNode> {
if self.expect(&[TokenType::LeftParen]).is_some() { if self.expect(&[TokenType::LeftParen]).is_some() {
// "(" expression ")"
let expr = self.parse_expression()?; let expr = self.parse_expression()?;
self.consume(&TokenType::RightParen, "expected ')' after expression")?; self.consume(&TokenType::RightParen, "expected ')' after expression")?;
Ok(ExprNode::Grouping { Ok(ExprNode::Grouping {
expression: Box::new(expr), expression: Box::new(expr),
}) })
} else if let Some(super_token) = self.expect(&[TokenType::Super]) {
// "super" "." IDENTIFIER
self.consume(&TokenType::Dot, "expected '.' after 'super'")?;
let identifier = self.consume_identifier("expected method name")?;
Ok(ExprNode::Super(SuperExpr {
keyword: super_token,
method: identifier,
}))
} else if self.expect(&[TokenType::Fun]).is_some() { } else if self.expect(&[TokenType::Fun]).is_some() {
// "fun" function_info
let (params, body) = self.parse_function_info(FunctionKind::Lambda)?; let (params, body) = self.parse_function_info(FunctionKind::Lambda)?;
Ok(ExprNode::Lambda { params, body }) Ok(ExprNode::Lambda { params, body })
} else if let Some(token) = } else if let Some(token) =
self.expect(&[TokenType::False, TokenType::True, TokenType::Nil]) self.expect(&[TokenType::False, TokenType::True, TokenType::Nil])
{ {
// TRUE | FALSE | NIL
Ok(ExprNode::Litteral { value: token }) Ok(ExprNode::Litteral { value: token })
} else { } else {
// STRING | NUMBER | IDENTIFIER | "this"
match &self.peek().token_type { match &self.peek().token_type {
TokenType::Number(_) | &TokenType::String(_) => Ok(ExprNode::Litteral { TokenType::Number(_) | &TokenType::String(_) => Ok(ExprNode::Litteral {
value: self.advance().clone(), value: self.advance().clone(),