From 24160e4edc4a7c5fb01735650a8a1f4363725c18 Mon Sep 17 00:00:00 2001 From: ghostlyzsh Date: Fri, 2 Aug 2024 08:51:05 -0500 Subject: [PATCH] for --- kabel/grammar.ebnf | 4 +++- kabel/src/parser.rs | 55 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/kabel/grammar.ebnf b/kabel/grammar.ebnf index f87c4963c54aa2b93e855cb5d8fa57028ec60d99..da8f0f1581b4df92b7153eb8fde713803c7ef081 100644 --- a/kabel/grammar.ebnf +++ b/kabel/grammar.ebnf @@ -1,12 +1,14 @@ program = { statement } ; -statement = function | return | loop | while | if | expression_statement ; +statement = function | return | loop | while | for | break | continue + | if | expression_statement ; function = "function" , identifier , "(" , { identifier , "," , } ")" , block return = "return" , expression , ";" ; loop = "loop" , block ; while = "while" , "(" , expression , ")" , block ; +for = "for" , "(" , [ expression ] , ";" , [ expression ] , ";" , [ expression ] , ")" , block break = "break" , ";" ; continue = "continue" , ";" ; diff --git a/kabel/src/parser.rs b/kabel/src/parser.rs index 609357379c38d0640f54449765f00c86aa5b525d..b32224e09531f4593beee13c8964a036e110954f 100644 --- a/kabel/src/parser.rs +++ b/kabel/src/parser.rs @@ -52,6 +52,7 @@ impl Parser { "return" => self.return_statement(), "loop" => self.loop_statement(), "while" => self.while_statement(), + "for" => self.for_statement(), "break" => self.break_statement(), "continue" => self.continue_statement(), "if" => self.if_statement(), @@ -165,6 +166,56 @@ impl Parser { } } + pub fn for_statement(&mut self) -> Result { + let for_ident = self.read_token()?; + let left_paren = self.read_token()?; + if let TokenType::LeftParen = left_paren.token_type { + let expression1; + if let TokenType::Semicolon = self.peek()?.token_type { + expression1 = None; + } else { + expression1 = Some(self.expression()?); + } + let semicolon = self.read_token()?; + if let TokenType::Semicolon = semicolon.token_type { + let expression2; + if let TokenType::Semicolon = self.peek()?.token_type { + expression2 = None; + } else { + expression2 = Some(self.expression()?); + } + let semicolon = self.read_token()?; + if let TokenType::Semicolon = semicolon.token_type { + let expression3; + if let TokenType::RightParen = self.peek()?.token_type { + expression3 = None; + } else { + expression3 = Some(self.expression()?); + } + let right_paren = self.read_token()?; + if let TokenType::RightParen = right_paren.token_type { + let block = self.block()?; + return Ok(AST { + ast_type: ASTType::For(Box::new(expression1), Box::new(expression2), Box::new(expression3), Box::new(block.clone())), + start: for_ident.start, + end: block.end, + line: for_ident.line, + column: for_ident.column, + }); + } else { + return Err(unexpected_token!(self, "Expected ) found {}", right_paren)); + } + } else { + return Err(unexpected_token!(self, "Expected ; found {}", semicolon)); + } + } else { + return Err(unexpected_token!(self, "Expected ; found {}", semicolon)); + } + } else { + return Err(unexpected_token!(self, "Expected ( found {}", left_paren)); + } + } + pub fn break_statement(&mut self) -> Result { let break_ident = self.read_token()?; let semicolon = self.read_token()?; @@ -626,8 +677,7 @@ impl Parser { pub fn subscript(&mut self) -> Result { let mut primary = self.primary()?; - while self.current < self.input.len() && - self.peek()?.token_type == TokenType::LeftSquare { + while self.current < self.input.len() && self.peek()?.token_type == TokenType::LeftSquare { self.read_token()?; let expr = self.expression()?; let right_brace = self.read_token()?; @@ -867,6 +917,7 @@ pub enum ASTType { Return(Option>), // expression Loop(Box), // block While(Box, Box), // condition, block + For(Box>, Box>, Box>, Box), // expr1, expr2, expr3, block Break, Continue, If(Box, Box, Option>), // condition, block, else/else if