From 47a0bb9226af187f2c08a7b5a82488f69dcadd72 Mon Sep 17 00:00:00 2001 From: Pranav Verma Date: Thu, 10 Jul 2025 00:29:30 +0530 Subject: [PATCH 01/12] Update: Add initial AST structure with Program and Statement enums --- src/ast.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/ast.rs diff --git a/src/ast.rs b/src/ast.rs new file mode 100644 index 0000000..cb34ec5 --- /dev/null +++ b/src/ast.rs @@ -0,0 +1,13 @@ +#[derive(Debug, Clone, PartialEq)] +pub struct Program { + pub statements: Vec, +} + +#[derive(Debug, Clone, PartialEq)] +pub enum Statement { + Let(LetStatement), + Show(ShowStatement), + When(WhenStatement), + FunctionDef(FunctionDef), + Expression(Expression), +} \ No newline at end of file From 11bc78c16c92131b66c6abe916f8379885d59182 Mon Sep 17 00:00:00 2001 From: Pranav Verma Date: Thu, 10 Jul 2025 00:30:55 +0530 Subject: [PATCH 02/12] Update: Added `LetStatement` and `ShowStatement` Structs to AST. --- src/ast.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/ast.rs b/src/ast.rs index cb34ec5..ef2a84b 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -10,4 +10,15 @@ pub enum Statement { When(WhenStatement), FunctionDef(FunctionDef), Expression(Expression), +} + +#[derive(Debug, Clone, PartialEq)] +pub struct LetStatement { + pub identifier: String, + pub value : Expression, +} + +#[derive(Debug, Clone, PartialEq)] +pub struct ShowStatement { + pub value: Expression, } \ No newline at end of file From a26bf255e00ce0ae4291c55843a858ee4b519c76 Mon Sep 17 00:00:00 2001 From: Pranav Verma Date: Thu, 10 Jul 2025 12:32:21 +0530 Subject: [PATCH 03/12] Update: Add WhenStatement and FunctionDef structs to AST --- src/ast.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/ast.rs b/src/ast.rs index ef2a84b..24f5d4f 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -21,4 +21,27 @@ pub struct LetStatement { #[derive(Debug, Clone, PartialEq)] pub struct ShowStatement { pub value: Expression, +} + +#[derive(Debug, Clone, PartialEq)] +pub struct WhenStatement { + pub condition: Expression, + pub then_block: Vec, + pub otherwise_block: Option>, +} + +#[derive(Debug, Clone, PartialEq)] +pub struct FunctionDef { + pub name: String, + pub parameters: Vec, + pub body : Vec, +} + +#[derive(Debug, Clone, PartialEq)] +pub enum Expression { + Number(f64), + String(String), + Identifier(String), + BinaryOp(BinaryOperation), + FunctionCall(FunctionCall), } \ No newline at end of file From 48bb544fe197682193a88c56760f872fb5fb45b2 Mon Sep 17 00:00:00 2001 From: Pranav Verma Date: Thu, 10 Jul 2025 12:33:37 +0530 Subject: [PATCH 04/12] Update: Add BinaryOperation and FunctionCall structs to AST --- src/ast.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/ast.rs b/src/ast.rs index 24f5d4f..5f1dd65 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -44,4 +44,31 @@ pub enum Expression { Identifier(String), BinaryOp(BinaryOperation), FunctionCall(FunctionCall), +} + +#[derive(Debug, Clone, PartialEq)] +pub struct BinaryOperation { + pub left: Box, + pub operator: BinaryOperator, + pub right: Box, +} + +#[derive(Debug, Clone, PartialEq)] +pub enum BinaryOperator { + GreaterThan, + LessThan, + GreaterThanOrEqual, + LessThanOrEqual, + Equal, + NotEqual, + Add, + Subtract, + Multiply, + Divide, +} + +#[derive(Debug, Clone, PartialEq)] +pub struct FunctionCall { + pub name: String, + pub arguments: Vec, } \ No newline at end of file From 547fe3c35ac95598e85df952a86e2169ace073fe Mon Sep 17 00:00:00 2001 From: Pranav Verma Date: Thu, 10 Jul 2025 12:35:37 +0530 Subject: [PATCH 05/12] Update: Implement Parser struct with token handling --- src/parser.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/parser.rs diff --git a/src/parser.rs b/src/parser.rs new file mode 100644 index 0000000..3e3541c --- /dev/null +++ b/src/parser.rs @@ -0,0 +1,13 @@ +use crate::ast::*; +use crate::lexer::Token; + +pub struct Parser { + tokens: Vec, + current: usize, +} + +impl Parser { + pub fn new(tokens: Vec) -> Self { + Parser { tokens, current: 0 } + } + } \ No newline at end of file From 55cad198256b9ce30269b3b3bcc40f80e2b90336 Mon Sep 17 00:00:00 2001 From: Pranav Verma Date: Thu, 10 Jul 2025 12:39:29 +0530 Subject: [PATCH 06/12] Update: Add methods for token handling in Parser struct --- src/parser.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/parser.rs b/src/parser.rs index 3e3541c..2363df3 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -10,4 +10,24 @@ impl Parser { pub fn new(tokens: Vec) -> Self { Parser { tokens, current: 0 } } - } \ No newline at end of file + + fn current_token(&self) -> &Token { + self.tokens.get(self.current).unwrap_or(&Token::Eof) + } + + fn advance(&mut self) -> &Token { + if self.current < self.tokens.len() { + self.current = self.current + 1; + } + self.current_token() + } + + fn expect(&mut self, expected: Token) -> Result<(), String> { + if std::mem::discriminant(self.current_token()) == std::mem::discriminant(&expected) { + self.advance(); + Ok(()) + } else { + Err(format!("Expected {:?}, found {:?}", expected, self.current_token())) + } + } +} \ No newline at end of file From 28fd6c487031ac6dccd8e303bcc40c4a7b63c3ce Mon Sep 17 00:00:00 2001 From: Pranav Verma Date: Thu, 10 Jul 2025 12:42:25 +0530 Subject: [PATCH 07/12] Update: Implement skip_newlines and parse methods in Parser struct --- src/parser.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/parser.rs b/src/parser.rs index 2363df3..f233098 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -30,4 +30,22 @@ impl Parser { Err(format!("Expected {:?}, found {:?}", expected, self.current_token())) } } + + fn skip_newlines(&mut self) { + while matches!(self.current_token(), Token::NewLine) { + self.advance(); + } + } + + pub fn parse(&mut self) -> Result { + let mut statements = Vec::new(); + self.skip_newlines(); + + while !matches!(self.current_token(), Token::Eof) { + statements.push(self.parse_statement()?); + self.skip_newlines(); + } + + Ok(Program { statements }) + } } \ No newline at end of file From 4ec3ad4461609ecfb87819fa0cf29b398fde2db3 Mon Sep 17 00:00:00 2001 From: Pranav Verma Date: Thu, 10 Jul 2025 12:47:13 +0530 Subject: [PATCH 08/12] Update: Implement parse_statement and parse_let_statement methods in Parser struct --- src/parser.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/parser.rs b/src/parser.rs index f233098..b0e8746 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -48,4 +48,34 @@ impl Parser { Ok(Program { statements }) } + + fn parse_statement(&mut self) -> Result { + match self.current_token() { + // TODO: Add Matches + Token::Let => self.parse_let_statement(), + _ => { + let expr = self.parse_expression()?; + Ok(Statement::Expression(expr)) + } + } + } + + fn parse_let_statement(&mut self) -> Result { + self.expect(Token::Let)?; + + let identifier = match self.current_token() { + Token::Identifier(name) => { + let name = name.clone(); + self.advance(); + name + } + _ => return Err("Expected identifier after 'let'".to_string()), + }; + + self.expect(Token::Be)?; + + let value = self.parse_expression()?; + + Ok(Statement::Let(LetStatement { identifier, value })) + } } \ No newline at end of file From a50cca1067668f6e74cef680ee54191357f8e73f Mon Sep 17 00:00:00 2001 From: Pranav Verma Date: Thu, 10 Jul 2025 12:48:10 +0530 Subject: [PATCH 09/12] Update: Implement parse_show_statement and parse_when_statement methods in Parser struct --- src/parser.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/parser.rs b/src/parser.rs index b0e8746..eb0f64c 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -53,6 +53,8 @@ impl Parser { match self.current_token() { // TODO: Add Matches Token::Let => self.parse_let_statement(), + Token::Show => self.parse_show_statement(), + Token::When => self.parse_when_statement(), _ => { let expr = self.parse_expression()?; Ok(Statement::Expression(expr)) @@ -78,4 +80,56 @@ impl Parser { Ok(Statement::Let(LetStatement { identifier, value })) } + + fn parse_show_statement(&mut self) -> Result { + self.expect(Token::Show)?; + let value = self.parse_expression()?; + Ok(Statement::Show(ShowStatement { value })) + } + + fn parse_when_statement(&mut self) -> Result { + self.expect(Token::When)?; + + let condition = self.parse_expression()?; + + self.expect(Token::Then)?; + self.skip_newlines(); + self.expect(Token::Indent)?; + + let mut then_block = Vec::new(); + while !matches!(self.current_token(), Token::Dedent | Token::Otherwise | Token::Eof) { + then_block.push(self.parse_statement()?); + self.skip_newlines(); + } + + let otherwise_block = if matches!(self.current_token(), Token::Otherwise) { + self.advance(); // consume 'otherwise' + self.skip_newlines(); + self.expect(Token::Indent)?; + + let mut otherwise_statements = Vec::new(); + while !matches!(self.current_token(), Token::Dedent | Token::Eof) { + otherwise_statements.push(self.parse_statement()?); + self.skip_newlines(); + } + + if matches!(self.current_token(), Token::Dedent) { + self.advance(); + } + + Some(otherwise_statements) + } else { + None + }; + + if matches!(self.current_token(), Token::Dedent) { + self.advance(); + } + + Ok(Statement::When(WhenStatement { + condition, + then_block, + otherwise_block, + })) + } } \ No newline at end of file From 1be19c87838eb11ce6078f275bcdf4a93b710159 Mon Sep 17 00:00:00 2001 From: Pranav Verma Date: Thu, 10 Jul 2025 12:49:05 +0530 Subject: [PATCH 10/12] Update: Implement parse_function_def method and extend parse_statement to handle function definitions --- src/parser.rs | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/src/parser.rs b/src/parser.rs index eb0f64c..603995a 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -51,10 +51,10 @@ impl Parser { fn parse_statement(&mut self) -> Result { match self.current_token() { - // TODO: Add Matches Token::Let => self.parse_let_statement(), Token::Show => self.parse_show_statement(), Token::When => self.parse_when_statement(), + Token::Define => self.parse_function_def(), _ => { let expr = self.parse_expression()?; Ok(Statement::Expression(expr)) @@ -132,4 +132,78 @@ impl Parser { otherwise_block, })) } + + fn parse_function_def(&mut self) -> Result { + self.expect(Token::Define)?; + + let name = match self.current_token() { + Token::Identifier(name) => { + let name = name.clone(); + self.advance(); + name + } + _ => return Err("Expected function name after 'define'".to_string()), + }; + + let mut parameters = Vec::new(); + + if matches!(self.current_token(), Token::With) { + self.advance(); // consume 'with' + + loop { + match self.current_token() { + Token::Identifier(param) => { + parameters.push(param.clone()); + self.advance(); + } + _ => break, + } + + // Check for more parameters (basic implementation) + if !matches!(self.current_token(), Token::Identifier(_)) { + break; + } + } + } + + self.skip_newlines(); + self.expect(Token::Indent)?; + + let mut body = Vec::new(); + while !matches!(self.current_token(), Token::End | Token::Dedent | Token::Eof) { + body.push(self.parse_statement()?); + self.skip_newlines(); + } + + if matches!(self.current_token(), Token::End) { + self.advance(); + } else if matches!(self.current_token(), Token::Dedent) { + self.advance(); + } + + Ok(Statement::FunctionDef(FunctionDef { + name, + parameters, + body, + })) + } + + fn parse_expression(&mut self) -> Result { + self.parse_comparison() + } + + fn parse_comparison(&mut self) -> Result { + let mut left = self.parse_primary()?; + + while let Some(op) = self.parse_comparison_operator() { + let right = self.parse_primary()?; + left = Expression::BinaryOp(BinaryOperation { + left: Box::new(left), + operator: op, + right: Box::new(right), + }); + } + + Ok(left) + } } \ No newline at end of file From 9bad85281b529308a1fa25560cb2ec60f7ec4f35 Mon Sep 17 00:00:00 2001 From: Pranav Verma Date: Thu, 10 Jul 2025 12:50:04 +0530 Subject: [PATCH 11/12] Update: Implement parse_comparison_operator and parse_primary methods in Parser struct --- src/parser.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/parser.rs b/src/parser.rs index 603995a..691a925 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -206,4 +206,54 @@ impl Parser { Ok(left) } + + fn parse_comparison_operator(&mut self) -> Option { + match self.current_token() { + Token::IsGreaterThan => { + self.advance(); + Some(BinaryOperator::GreaterThan) + } + Token::IsLessThan => { + self.advance(); + Some(BinaryOperator::LessThan) + } + Token::IsGreaterThanOrEqual => { + self.advance(); + Some(BinaryOperator::GreaterThanOrEqual) + } + Token::IsLessThanOrEqual => { + self.advance(); + Some(BinaryOperator::LessThanOrEqual) + } + Token::IsEqual => { + self.advance(); + Some(BinaryOperator::Equal) + } + Token::IsNotEqual => { + self.advance(); + Some(BinaryOperator::NotEqual) + } + _ => None, + } + } + + // The `parse_primary` function is Generated by AI. + fn parse_primary(&mut self) -> Result { + match self.current_token().clone() { + Token::Number(n) => { + self.advance(); + Ok(Expression::Number(n)) + } + Token::String(s) => { + self.advance(); + Ok(Expression::String(s)) + } + Token::Identifier(name) => { + self.advance(); + // Check if this is a function call (basic implementation) + Ok(Expression::Identifier(name)) + } + _ => Err(format!("Unexpected token in expression: {:?}", self.current_token())), + } + } } \ No newline at end of file From 28bffde13baa64f6205a63b71d60dd96dd6dc0d5 Mon Sep 17 00:00:00 2001 From: Pranav Verma Date: Thu, 10 Jul 2025 13:28:01 +0530 Subject: [PATCH 12/12] Fix: Fixed Parser & AST Errors. --- src/ast.rs | 2 +- src/main.rs | 16 ++++++++++++++++ src/parser.rs | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index 5f1dd65..9669522 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -1,6 +1,6 @@ #[derive(Debug, Clone, PartialEq)] pub struct Program { - pub statements: Vec, + pub statements: Vec, } #[derive(Debug, Clone, PartialEq)] diff --git a/src/main.rs b/src/main.rs index c6e1f3a..4776b17 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,8 +3,11 @@ use std::fs; use std::process; mod lexer; +mod parser; +mod ast; use lexer::Lexer; +use parser::Parser; fn main() { let args: Vec = env::args().collect(); @@ -35,4 +38,17 @@ fn main() { }; println!("Tokens: {:?}", tokens); + + // Step 2: Parse into AST + let mut parser = Parser::new(tokens); + let ast = match parser.parse() { + Ok(ast) => ast, + Err(err) => { + eprintln!("Parser error: {}", err); + process::exit(1); + } + }; + + // Step 3: Print AST (debug output) + println!("AST: {:#?}", ast); } diff --git a/src/parser.rs b/src/parser.rs index 691a925..866b7d9 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -32,7 +32,7 @@ impl Parser { } fn skip_newlines(&mut self) { - while matches!(self.current_token(), Token::NewLine) { + while matches!(self.current_token(), Token::Newline) { self.advance(); } }