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:
@@ -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!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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()?;
|
||||
|
||||
Reference in New Issue
Block a user