From 558cbbc0d2435a3f9dc1eb5debc6259caa3c67d0 Mon Sep 17 00:00:00 2001 From: Tristan Date: Mon, 26 May 2025 13:05:38 -0400 Subject: [PATCH] for --- .kdev4/fddl.kdev4 | 5 ++ fddl.kdev4 | 4 + src/lexer/lexer.rs | 60 ++++++++++--- src/parser/parser.rs | 182 +++++++++++++++++++++++++++++++++++++-- src/parser/parser.rs_bak | 164 ----------------------------------- 5 files changed, 231 insertions(+), 184 deletions(-) create mode 100644 .kdev4/fddl.kdev4 create mode 100644 fddl.kdev4 delete mode 100644 src/parser/parser.rs_bak diff --git a/.kdev4/fddl.kdev4 b/.kdev4/fddl.kdev4 new file mode 100644 index 0000000..77a959d --- /dev/null +++ b/.kdev4/fddl.kdev4 @@ -0,0 +1,5 @@ +[Buildset] +BuildItems=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x01\x00\x00\x00\x08\x00f\x00d\x00d\x00l) + +[Project] +VersionControlSupport=kdevgit diff --git a/fddl.kdev4 b/fddl.kdev4 new file mode 100644 index 0000000..323c0f2 --- /dev/null +++ b/fddl.kdev4 @@ -0,0 +1,4 @@ +[Project] +CreatedFrom= +Manager=KDevGenericManager +Name=fddl diff --git a/src/lexer/lexer.rs b/src/lexer/lexer.rs index fce3555..e5f92d4 100644 --- a/src/lexer/lexer.rs +++ b/src/lexer/lexer.rs @@ -60,18 +60,29 @@ impl Lexer { } else { Some(Token::Tilde) } - }, + }, + '/' => { - if self.match_char('/') { - // Line comment starting with // - self.line_comment() // Generate Comment token + if self.match_char('/') { // For line comments // + // Consume the rest of the line + let mut comment_text = String::new(); + while self.peek() != '\n' && !self.is_at_end() { + comment_text.push(self.advance()); + } + Some(Token::Comment(comment_text)) // Or None if you want to skip comments + } else if self.match_char('*') { // For block comments /* ... */ + self.consume_block_comment() // Call a new helper function } else { - Some(Token::Slash) + Some(Token::Slash) // Division operator } }, + '#' => { - // Line comment starting with # - self.line_comment() // Generate Comment token + let mut comment_text = String::new(); + while self.peek() != '\n' && !self.is_at_end() { + comment_text.push(self.advance()); + } + Some(Token::Comment(comment_text)) }, // One or two character tokens @@ -124,8 +135,34 @@ impl Lexer { } } - // Helper methods - // Consume the current character and return it + fn consume_block_comment(&mut self) -> Option { + let mut comment_text = String::new(); + let start_line = self.line; + + loop { + if self.is_at_end() { + eprintln!("Error (L{}): Unterminated block comment", start_line); + if !comment_text.is_empty() { + return Some(Token::Comment(comment_text)); + } + return None; + } + + let current_char = self.peek(); + if current_char == '*' && self.peek_next() == '/' { + self.advance(); // Consume '*' + self.advance(); // Consume '/' + return Some(Token::Comment(comment_text)); + } else { + if current_char == '\n' { + self.line += 1; + } + comment_text.push(self.advance()); + + } + } + } + fn advance(&mut self) -> char { if self.is_at_end() { return '\0'; @@ -135,7 +172,6 @@ impl Lexer { c } - // Check if the current character matches the expected character fn match_char(&mut self, expected: char) -> bool { if self.is_at_end() { return false; @@ -149,7 +185,6 @@ impl Lexer { true } - // Look at current character fn peek(&self) -> char { if self.is_at_end() { '\0' @@ -158,7 +193,6 @@ impl Lexer { } } - // Look ahead by one character fn peek_next(&self) -> char { if self.current + 1 >= self.source.len() { '\0' @@ -167,12 +201,10 @@ impl Lexer { } } - // Check if we have reached the end of the source fn is_at_end(&self) -> bool { self.current >= self.source.len() } - // Function to handle string literals fn string(&mut self) -> Option { while self.peek() != '"' && !self.is_at_end() { if self.peek() == '\n' { diff --git a/src/parser/parser.rs b/src/parser/parser.rs index 97b59ef..37057c2 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -17,7 +17,7 @@ impl Parser { } } - fn parse_for_statement(&mut self) -> Option { + /* fn parse_for_statement(&mut self) -> Option { if !self.match_token(Token::LeftParen) { eprintln!("Error: Expected '(' after 'for'."); return None; @@ -59,7 +59,7 @@ impl Parser { eprintln!("Warning: For statement AST structure might need review."); None - } + } */ fn parse_expression_statement(&mut self) -> Option { let expr = self.parse_expression()?; @@ -309,7 +309,14 @@ impl Parser { } pub fn parse_statement(&mut self) -> Option { - if self.check(&Token::Print) { + self.skip_comments(); + if self.is_at_end() { return None; } + + if self.check(&Token::For) { + self.parse_for_statement() + } else if self.check(&Token::Func) { + self.parse_function_declaration() + } else if self.check(&Token::Print) { self.parse_print_statement() } else if self.check(&Token::Let) { self.parse_variable_declaration() @@ -319,13 +326,82 @@ impl Parser { self.parse_if_statement() } else if self.check(&Token::While) { self.parse_while_statement() - } else if self.check(&Token::For) { - self.parse_for_statement() } else { self.parse_expression_statement() } } + fn parse_function_declaration(&mut self) -> Option { + if !self.match_token(Token::Func) { + eprintln!("Internal parser error: Expected 'func' token in parse_function_declaration."); + return None; + } + + let name = match self.peek_and_advance() { + Some(Token::Identifier(name_str)) => name_str, + _ => { + eprintln!("Error: Expected function name (identifier) after 'func'."); + return None; + } + }; + + if !self.match_token(Token::LeftParen) { + eprintln!("Error: Expected '(' after function name '{}'.", name); + return None; + } + + let params = self.parse_parameters()?; + + if !self.match_token(Token::RightParen) { + eprintln!("Error: Expected ')' after function parameters for function '{}'.", name); + return None; + } + + if !self.check(&Token::LeftBrace) { + eprintln!("Error: Expected '{{' for function body of '{}'.", name); + return None; + } + + let body_statement = self.parse_statement()?; + + match body_statement { + Statement::Block(body_statements) => { + Some(Statement::FunctionDeclaration { name, params, body: body_statements }) + } + _ => { + eprintln!("Error: Function body must be a block statement for function '{}'.", name); + None + } + } + } + + fn parse_parameters(&mut self) -> Option> { + let mut parameters = Vec::new(); + + if self.check(&Token::RightParen) { + return Some(parameters); + } + + match self.peek_and_advance() { + Some(Token::Identifier(param_name)) => parameters.push(param_name), + _ => { + eprintln!("Error: Expected parameter name (identifier) in function parameter list."); + return None; + } + } + + while self.match_token(Token::Comma) { + match self.peek_and_advance() { + Some(Token::Identifier(param_name)) => parameters.push(param_name), + _ => { + eprintln!("Error: Expected parameter name (identifier) after comma in function parameter list."); + return None; + } + } + } + Some(parameters) + } + fn parse_block_statement(&mut self) -> Option { if !self.match_token(Token::LeftBrace) { eprintln!("Error: Expected '{{' to start a block."); @@ -388,7 +464,7 @@ impl Parser { Some(Statement::IfStatement(condition, then_branch, else_branch_opt)) } - fn parse_while_statement(&mut self) -> Option { + fn parse_while_statement(&mut self) -> Option { if !self.match_token(Token::While) { eprintln!("Internal parser error: Expected 'while' token in parse_while_statement."); return None; @@ -413,6 +489,94 @@ impl Parser { Some(Statement::WhileStatement(condition, body)) } + fn parse_for_statement(&mut self) -> Option { + if !self.match_token(Token::For) { return None; } // Consume 'for' + + if !self.match_token(Token::LeftParen) { + eprintln!("Error: Expected '(' after 'for'."); + return None; + } + + // 1. Initializer Statement + self.skip_comments(); // Skip comments before initializer part + let initializer: Box; + if self.check(&Token::Let) { + self.advance(); // Consume 'let' + let var_name = match self.peek_and_advance() { + Some(Token::Identifier(name_str)) => name_str, + _ => { + eprintln!("Error: Expected variable name after 'let' in for-loop initializer."); + return None; + } + }; + let var_initializer_expr: Option = if self.match_token(Token::Equal) { + self.skip_comments(); // Skip comments before the expression value + self.parse_expression() + } else { + None + }; + initializer = Box::new(Statement::VariableDeclaration(var_name, var_initializer_expr)); + self.skip_comments(); // Skip comments before the semicolon separator + if !self.match_token(Token::Semicolon) { + eprintln!("Error: Expected ';' after 'let' declaration in for-loop initializer."); + return None; + } + } else if self.check(&Token::Semicolon) { // Check for ';' for empty initializer + self.advance(); // Consume the ';' + initializer = Box::new(Statement::ExpressionStatement(Expression::Literal(Literal::Nil))); + } else { // Expression initializer + let init_expr = self.parse_expression()?; + initializer = Box::new(Statement::ExpressionStatement(init_expr)); + self.skip_comments(); // Skip comments before the semicolon separator + if !self.match_token(Token::Semicolon) { + eprintln!("Error: Expected ';' after for-loop initializer expression."); + return None; + } + } + + // 2. Condition Expression + self.skip_comments(); // Skip comments before condition part + let condition: Expression; + if self.check(&Token::Semicolon) { // Check for ';' for empty condition + self.advance(); // Consume the ';' + condition = Expression::Literal(Literal::Boolean(true)); // Default to true + } else { + condition = self.parse_expression()?; + self.skip_comments(); // Skip comments before the semicolon separator + if !self.match_token(Token::Semicolon) { + eprintln!("Error: Expected ';' after for-loop condition."); + return None; + } + } + + // 3. Increment Statement + self.skip_comments(); // <--- CRUCIAL FIX: Skip comments before increment part + let increment: Box; + if self.check(&Token::RightParen) { // Empty increment (if ')' is next) + increment = Box::new(Statement::ExpressionStatement(Expression::Literal(Literal::Nil))); + } else { + let incr_expr = self.parse_expression()?; // Now this will see past the comment + increment = Box::new(Statement::ExpressionStatement(incr_expr)); + } + + self.skip_comments(); // Skip comments before ')' + if !self.match_token(Token::RightParen) { + eprintln!("Error: Expected ')' after for-loop clauses."); + return None; + } + + // 4. Body Statement (must be a block) + self.skip_comments(); // Skip comments before '{' + if !self.check(&Token::LeftBrace) { + eprintln!("Error: Expected '{{' for for-loop body."); + return None; + } + // parse_statement() already calls skip_comments() at its beginning + let body = Box::new(self.parse_statement()?); + + Some(Statement::ForStatement(initializer, condition, increment, body)) + } + fn parse_print_statement(&mut self) -> Option { if !self.match_token(Token::Print) { return None; } let value = self.parse_expression()?; @@ -479,6 +643,12 @@ impl Parser { } } + fn skip_comments(&mut self) { + while !self.is_at_end() && matches!(self.current_token(), Token::Comment(_)) { + self.advance(); + } + } + fn match_token(&mut self, expected: Token) -> bool { let current_matches = match (self.current_token(), &expected) { (Token::LeftParen, Token::LeftParen) => true, diff --git a/src/parser/parser.rs_bak b/src/parser/parser.rs_bak deleted file mode 100644 index cfe6737..0000000 --- a/src/parser/parser.rs_bak +++ /dev/null @@ -1,164 +0,0 @@ - use crate::lexer::token::Token; - use crate::parser::ast::Expression; - use crate::parser::ast::Statement; - use crate::lexer::Lexer; - - pub struct Parser { - tokens: Vec, - current: usize, - } - - #[allow(dead_code)] - - impl Parser { - fn parse_statement(&mut self) -> Option { - if self.match_token(Token::Print) { - self.parse_print_statement() - } else if self.match_token(Token::Let) { - self.parse_variable_declaration() - } else if self.match_token(Token::If) { - self.parse_if_statement() - } else if self.match_token(Token::While) { - self.parse_while_statement() - } else if self.match_token(Token::For) { - self.parse_for_statement() - } else { - self.parse_expression_statement() - } - } - - fn parse_print_statement(&mut self) -> Option { - let value = self.parse_expression()?; - if self.match_token(Token::Semicolon) { - Some(Statement::PrintStatement(value)) - } else { - None - } - } - - fn parse_variable_declaration(&mut self) -> Option { - let token = self.advance().clone(); - - if let Token::Identifier(name) = token { - let has_initializer = self.match_token(Token::Equal); - - let initializer = if has_initializer { - self.parse_expression() - } else { - None - }; - - if self.match_token(Token::Semicolon) { - Some(Statement::VariableDeclaration(name, initializer)) - } else { - None - } - } else { - None - } - } - - fn parse_if_statement(&mut self) -> Option { - self.match_token(Token::LeftParen); - let condition = self.parse_expression()?; - self.match_token(Token::RightParen); - - let then_branch = Box::new(self.parse_statement()?); - let else_branch = if self.match_token(Token::Else) { - Some(Box::new(self.parse_statement()?)) - } else { - None - }; - - Some(Statement::IfStatement(condition, then_branch, else_branch)) - } - - fn parse_while_statement(&mut self) -> Option { - self.match_token(Token::LeftParen); - let condition = self.parse_expression()?; - self.match_token(Token::RightParen); - - let body = Box::new(self.parse_statement()?); - - Some(Statement::WhileStatement(condition, body)) - } - - fn parse_for_statement(&mut self) -> Option { - self.match_token(Token::LeftParen); - - let initializer = Box::new(self.parse_statement()?); - let condition = self.parse_expression()?; - self.match_token(Token::Semicolon); - let increment = Box::new(self.parse_statement()?); - - self.match_token(Token::RightParen); - let body = Box::new(self.parse_statement()?); - - Some(Statement::ForStatement(initializer, condition, increment, body)) - } - - fn parse_expression_statement(&mut self) -> Option { - let expr = self.parse_expression()?; - if self.match_token(Token::Semicolon) { - Some(Statement::ExpressionStatement(expr)) - } else { - None - } - } - - fn parse_expression(&mut self) -> Option { - // Placeholder for expression parsing logic - None - } - - pub fn new(tokens: Vec) -> Self { - Parser { - tokens, - current: 0, - } - } - - fn current_token(&self) -> &Token { - &self.tokens[self.current] - } - - fn peek(&self) -> &Token { - &self.tokens[self.current + 1] - } - - fn is_at_end(&self) -> bool { - matches!(self.current_token(), Token::EOF) - } - - fn advance(&mut self) -> &Token { - if !self.is_at_end() { - self.current += 1; - } - self.current_token() - } - - fn match_token(&mut self, expected: Token) -> bool { - if self.current_token() == &expected { - self.advance(); - true - } else { - false - } - } - - fn previous_token(&self) -> &Token { - &self.tokens[self.current - 1] - } - } - - fn main() { - let source = String::from("let x = 10;"); - let mut lexer = Lexer::new(source); - let tokens = lexer.scan_tokens(); - let mut parser = Parser::new(tokens); - - while !parser.is_at_end() { - println!("{:?}", parser.current_token()); - parser.advance(); - } - }