From 031217f6c6e4161a49d00fe96486250bc02f3a62 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Tue, 2 Nov 2021 23:01:20 +0100 Subject: [PATCH] parse calls --- src/ast.rs | 15 +++++++++++++++ src/parse/mod.rs | 41 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index 058ccd4..6d9ecbe 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -93,6 +93,7 @@ pub enum Expr { Literal(Literal), UnaryOp(Box), BinaryOp(Box), + Call(Box), } impl Expr { @@ -102,6 +103,7 @@ impl Expr { Expr::UnaryOp(unary) => unary.span, Expr::BinaryOp(binary) => binary.span, Expr::Ident(Ident { span, .. }) => *span, + Expr::Call(call) => call.span, } } } @@ -166,3 +168,16 @@ pub enum BinaryOpKind { Div, Mod, } + +#[derive(Debug, Clone, PartialEq)] +pub struct Call { + pub callee: Expr, + pub span: Span, + pub kind: CallKind, +} + +#[derive(Debug, Clone, PartialEq)] +pub enum CallKind { + Field(Ident), + Fn(Vec), +} diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 77ab4c3..e3b1b8d 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -286,7 +286,7 @@ impl<'code> Parser<'code> { match self.peek_kind() { Some(TokenType::Not) => { let unary_op_span = self.next().unwrap().span; - let expr = self.unary()?; + let expr = self.call()?; Ok(Expr::UnaryOp(Box::new(UnaryOp { span: unary_op_span.extend(expr.span()), expr, @@ -295,18 +295,51 @@ impl<'code> Parser<'code> { } Some(TokenType::Minus) => { let unary_op_span = self.next().unwrap().span; - let expr = self.unary()?; + let expr = self.call()?; Ok(Expr::UnaryOp(Box::new(UnaryOp { span: unary_op_span.extend(expr.span()), expr, kind: UnaryOpKind::Neg, }))) } - _ => self.primary(), + _ => self.call(), } } - fn primary<'parser>(&'parser mut self) -> ParseResult<'code, Expr> { + fn call(&mut self) -> ParseResult<'code, Expr> { + let mut expr = self.primary()?; + + loop { + expr = match self.peek_kind() { + Some(TokenType::ParenO) => { + let open_span = self.expect(TokenType::ParenO)?.span; + let args = self.parse_list(TokenType::ParenC, Self::expression)?; + let close_span = self.expect(TokenType::ParenC)?.span; + + Expr::Call(Box::new(Call { + callee: expr, + span: open_span.extend(close_span), + kind: CallKind::Fn(args), + })) + } + Some(TokenType::Dot) => { + let dot_span = self.expect(TokenType::Dot)?.span; + let field = self.ident()?; + + Expr::Call(Box::new(Call { + callee: expr, + span: dot_span.extend(field.span), + kind: CallKind::Field(field), + })) + } + _ => break, + } + } + + Ok(expr) + } + + fn primary(&mut self) -> ParseResult<'code, Expr> { let next = self.next().ok_or(ParseErr::Eof("primary"))?; match next.kind { TokenType::String(literal) => Ok(Expr::Literal(Literal::String(literal, next.span))),