From fdb3bfb1e0bf0eea64a9aad0f81d305728daedc2 Mon Sep 17 00:00:00 2001 From: ghostlyzsh Date: Thu, 1 Aug 2024 22:41:13 -0500 Subject: [PATCH] functions added --- kabel/grammar.ebnf | 1 - kabel/src/macros.rs | 16 ++++ kabel/src/parser.rs | 182 +++++++++++++------------------------------- 3 files changed, 70 insertions(+), 129 deletions(-) diff --git a/kabel/grammar.ebnf b/kabel/grammar.ebnf index 79aae95d9ca3cc59aee9dab77b5f48eb1a150ac8..bbe350b6fc4fd820eef32f24e09d276be368212b 100644 --- a/kabel/grammar.ebnf +++ b/kabel/grammar.ebnf @@ -4,7 +4,6 @@ statement = function | loop | while | if | expression_statement ; function = "function" , identifier , "(" , { identifier , "," , } ")" , block -(* implemented *) loop = "loop" , block ; while = "while" , "(" , expression , ")" , block ; diff --git a/kabel/src/macros.rs b/kabel/src/macros.rs index 35012ac73aa5112f59dbd272bd02d3aac781070d..c1b513564a0ce53163f112f0290b30dd318a09cf 100644 --- a/kabel/src/macros.rs +++ b/kabel/src/macros.rs @@ -24,3 +24,19 @@ macro_rules! lit { } }; } + +#[macro_export] +macro_rules! unexpected_token { + ($self:expr, $message:expr, $token:expr) => { + $crate::error::KabelError::new( + $crate::error::ErrorKind::UnexpectedToken, + format!( + $message, + $self.text[$token.start..$token.end].to_string() + ), + $token.line, + $token.column, + $self.text[$token.line_start..$token.end].to_string(), + ) + }; +} diff --git a/kabel/src/parser.rs b/kabel/src/parser.rs index f43a5c7f866b96ba33d1c61eb81f3747042c9f50..09c312993b275ab1d4d15d25612a96df38f6852a 100644 --- a/kabel/src/parser.rs +++ b/kabel/src/parser.rs @@ -1,7 +1,7 @@ use crate::{ error::{ErrorKind, KabelError}, lexer::{Token, TokenType}, - lit, + lit, unexpected_token, }; pub struct Parser { @@ -48,6 +48,7 @@ impl Parser { pub fn statement(&mut self) -> Result { match self.peek()?.token_type { TokenType::Ident(ident) => match ident.as_str() { + "function" => self.function_statement(), "loop" => self.loop_statement(), "while" => self.while_statement(), "if" => self.if_statement(), @@ -57,6 +58,40 @@ impl Parser { } } + pub fn function_statement(&mut self) -> Result { + let function_ident = self.read_token()?; + let ident = self.read_token()?; + if let TokenType::Ident(name) = ident.token_type { + let left_paren = self.read_token()?; + if let TokenType::LeftParen = left_paren.token_type { + let mut expressions = Vec::new(); + while self.peek()?.token_type != TokenType::RightParen { + expressions.push(self.expression()?); + if let TokenType::Comma = self.peek()?.token_type { + self.read_token()?; + } + } + let right_paren = self.read_token()?; + if let TokenType::RightParen = right_paren.token_type { + let block = self.block()?; + return Ok(AST { + ast_type: ASTType::Function(Box::new(lit!(Ident, name, ident)), expressions, Box::new(block.clone())), + start: function_ident.start, + end: block.end, + line: function_ident.line, + column: function_ident.column, + }); + } else { + return Err(unexpected_token!(self, "Expected ) found {}", right_paren)); + } + } else { + return Err(unexpected_token!(self, "Expected ( found {}", left_paren)); + } + } else { + return Err(unexpected_token!(self, "Expected identifier found {}", ident)); + } + } + pub fn loop_statement(&mut self) -> Result { let loop_ident = self.read_token()?; let block = self.block()?; @@ -85,28 +120,10 @@ impl Parser { column: while_ident.column, }); } else { - return Err(KabelError::new( - ErrorKind::UnexpectedToken, - format!( - "Expected ) found {}", - self.text[right_paren.start..right_paren.end].to_string() - ), - right_paren.line, - right_paren.column, - self.text[right_paren.line_start..right_paren.end].to_string(), - )); + return Err(unexpected_token!(self, "Expected ) found {}", right_paren)); } } else { - return Err(KabelError::new( - ErrorKind::UnexpectedToken, - format!( - "Expected ( found {}", - self.text[left_paren.start..left_paren.end].to_string() - ), - left_paren.line, - left_paren.column, - self.text[left_paren.line_start..left_paren.end].to_string(), - )); + return Err(unexpected_token!(self, "Expected ( found {}", left_paren)); } } @@ -152,30 +169,10 @@ impl Parser { column: if_ident.column, }); } else { - return Err(KabelError::new( - ErrorKind::UnexpectedToken, - format!( - "Expected if found {}", - self.text[else_if_ident.start..else_if_ident.end] - .to_string() - ), - else_if_ident.line, - else_if_ident.column, - self.text[else_if_ident.line_start..else_if_ident.end] - .to_string(), - )); + return Err(unexpected_token!(self, "Expected if found {}", else_if_ident)); } } - return Err(KabelError::new( - ErrorKind::UnexpectedToken, - format!( - "Unexpected token {}", - self.text[else_ident.start..else_ident.end].to_string() - ), - else_ident.line, - else_ident.column, - self.text[else_ident.line_start..else_ident.end].to_string(), - )); + return Err(unexpected_token!(self, "Unexpected token {}", else_ident)); } else { self.current -= 1; } @@ -189,28 +186,10 @@ impl Parser { column: if_ident.column, }); } else { - return Err(KabelError::new( - ErrorKind::UnexpectedToken, - format!( - "Expected ) found {}", - self.text[right_paren.start..right_paren.end].to_string() - ), - right_paren.line, - right_paren.column, - self.text[right_paren.line_start..right_paren.end].to_string(), - )); + return Err(unexpected_token!(self, "Expected ) found {}", right_paren)); } } else { - return Err(KabelError::new( - ErrorKind::UnexpectedToken, - format!( - "Expected ( found {}", - self.text[left_paren.start..left_paren.end].to_string() - ), - left_paren.line, - left_paren.column, - self.text[left_paren.line_start..left_paren.end].to_string(), - )); + return Err(unexpected_token!(self, "Expected ( found {}", left_paren)); } } @@ -230,16 +209,7 @@ impl Parser { column: left_brace.column, }); } else { - return Err(KabelError::new( - ErrorKind::UnexpectedToken, - format!( - "Expected {{ found {}", - self.text[left_brace.start..left_brace.end].to_string() - ), - left_brace.line, - left_brace.column, - self.text[left_brace.line_start..left_brace.end].to_string(), - )); + return Err(unexpected_token!(self, "Expected {{ found {}", left_brace)); } } @@ -260,16 +230,7 @@ impl Parser { return Ok(expression); } else { self.current -= 1; - return Err(KabelError::new( - ErrorKind::UnexpectedToken, - format!( - "Expected ; found {}", - self.text[semicolon.start..semicolon.end].to_string() - ), - semicolon.line, - semicolon.column, - self.text[semicolon.line_start..semicolon.end].to_string(), - )); + return Err(unexpected_token!(self, "Expected ; found {}", semicolon)); } } @@ -301,28 +262,10 @@ impl Parser { column: var.column, }); } else { - return Err(KabelError::new( - ErrorKind::UnexpectedToken, - format!( - "Expected equals, found {}", - self.text[equal.start..equal.end].to_string() - ), - equal.line, - equal.column, - self.text[equal.line_start..equal.end].to_string(), - )); + return Err(unexpected_token!(self, "Expected = found {}", equal)); } } else { - return Err(KabelError::new( - ErrorKind::UnexpectedToken, - format!( - "Expected identifier, found {}", - self.text[ident.start..ident.end].to_string() - ), - ident.line, - ident.column, - self.text[ident.line_start..ident.end].to_string(), - )); + return Err(unexpected_token!(self, "Expected identifier found {}", ident)); } } @@ -645,16 +588,7 @@ impl Parser { return Ok(self.group(token)?); } _ => { - return Err(KabelError::new( - ErrorKind::UnexpectedToken, - format!( - "Unexpected token {}", - self.text[token.start..token.end].to_string() - ), - token.line, - token.column, - self.text[token.line_start..token.end].to_string(), - )); + return Err(unexpected_token!(self, "Unexpected token {}", token)); } } } @@ -696,16 +630,7 @@ impl Parser { column: expr.column, }; } else { - return Err(KabelError::new( - ErrorKind::UnexpectedToken, - format!( - "Unexpected token {}", - self.text[child.start..child.end].to_string() - ), - child.line, - child.column, - self.text[child.line_start..child.end].to_string(), - )); + return Err(unexpected_token!(self, "Unexpected token {}", child)); } if self.current >= self.input.len() { break; @@ -815,12 +740,13 @@ pub struct AST { pub enum ASTType { Program(Vec), - Loop(Box), - While(Box, Box), - If(Box, Box, Option>), - Block(Vec), + Function(Box, Vec, Box), // name, args, block + Loop(Box), // block + While(Box, Box), // condition, block + If(Box, Box, Option>), // condition, block, else/else if + Block(Vec), // statements - Decl(Box, Box), + Decl(Box, Box), // identifier, expression Binary(Box, BinOp, Box), Unary(UnOp, Box),