Add while loop support and token pretty printing

The commit adds while loop statements and improves token display
formatting:

- Implements while loop syntax and evaluation - Adds a new token pretty
printing module with configurable formatting - Improves token display
with colors and different output modes
This commit is contained in:
Giulio Agostini
2025-10-03 19:40:25 +02:00
parent a7df45dc72
commit 113a683beb
8 changed files with 463 additions and 8 deletions
+28
View File
@@ -19,6 +19,7 @@ use std::fmt::{Debug, Display};
* assignment_statement -> IDENTIFIER "=" expression ";"
* block_statement -> "do" statement* "end"
* if_statement -> "if" expression "then" statement ("elif" expression "then" statement)* ("else" statement)? "end"
* while_statement -> "while" expression "do" statement "end"
*
* expression -> assignment
* assignment -> IDENTIFIER "=" assignment | logical_or
@@ -145,6 +146,15 @@ pub enum Stmt {
elif_branch: Vec<(Box<Expr>, Box<Stmt>)>,
else_branch: Option<Box<Stmt>>,
},
While {
condition: Box<Expr>,
body: Box<Stmt>,
},
For {
variable: Box<Expr>,
iterable: Box<Expr>,
body: Box<Stmt>,
},
}
impl Display for Stmt {
@@ -182,6 +192,12 @@ impl Display for Stmt {
.collect::<Vec<_>>()
.join("\n")
),
Stmt::While { condition, body } => todo!(),
Stmt::For {
variable,
iterable,
body,
} => todo!(),
}
}
}
@@ -221,6 +237,12 @@ impl Debug for Stmt {
.collect::<Vec<_>>()
.join("\t\t\n")
),
Stmt::While { condition, body } => todo!(),
Stmt::For {
variable,
iterable,
body,
} => todo!(),
}
}
}
@@ -267,6 +289,12 @@ impl AstNodeKind for Stmt {
} => "if statement",
Stmt::Print { expression: _ } => "print statement",
Stmt::Stmt { expression: _ } => "statement",
Stmt::While { condition, body } => todo!(),
Stmt::For {
variable,
iterable,
body,
} => todo!(),
}
}
}
+2 -1
View File
@@ -1,5 +1,6 @@
use crate::frontend::source_registry::{SourceId, SourcePosition, SourceSlice};
use crate::frontend::tokens::{LiteralValue, Token, TokenType};
use crate::logging::display_token::TokenPrettyPrintExt;
use crate::result::{LoxError, LoxResult};
pub struct Lexer {
@@ -74,7 +75,7 @@ impl Lexer {
}
tokens.push(self.make_token(TokenType::Eof));
println!("Tokens:");
tokens.iter().for_each(|val| println!("{}", val));
tokens.iter().for_each(|val| println!("{}", val.pretty()));
Ok(tokens)
}
+14
View File
@@ -81,6 +81,10 @@ impl Parser {
self.if_statement()?,
self.peek().source_slice.clone(),
)),
(TokenType::While, _) => Ok(AstNode::new(
self.while_statement()?,
self.peek().source_slice.clone(),
)),
_ => Ok(AstNode::new(
self.expression_statement()?,
self.peek().source_slice.clone(),
@@ -88,6 +92,16 @@ impl Parser {
}
}
fn while_statement(&mut self) -> LoxResult<Stmt> {
self.advance();
let condition = self.expression()?;
let body = self.block_statement()?;
Ok(Stmt::While {
condition: Box::new(condition),
body: Box::new(body),
})
}
fn if_statement(&mut self) -> LoxResult<Stmt> {
self.advance();
let condition = self.expression()?;