Add parsing for for/while loops

This commit is contained in:
Sofia 2025-07-23 20:13:58 +03:00
parent 431aae0b0d
commit ef4964ed86
7 changed files with 54 additions and 4 deletions

View File

@ -2,7 +2,7 @@
fn main() -> u32 { fn main() -> u32 {
for i in [0, 1, 2, 3, 4, 5, 6, 7, 9, 10] { for i in 0 to 10 {
print("hello") print("hello")
} }

View File

@ -178,7 +178,7 @@ pub enum BlockLevelStatement {
}, },
Expression(Expression), Expression(Expression),
Return(ReturnType, Expression), Return(ReturnType, Expression),
ForLoop(String, Expression, Block), ForLoop(String, Expression, Expression, Block),
WhileLoop(Expression, Block), WhileLoop(Expression, Block),
} }

View File

@ -667,6 +667,14 @@ impl Parse for BlockLevelStatement {
stream.expect(Token::Semi)?; stream.expect(Token::Semi)?;
Stmt::Return(ReturnType::Hard, exp) Stmt::Return(ReturnType::Hard, exp)
} }
Some(Token::For) => {
let for_stmt = stream.parse::<ForStatement>()?;
Stmt::ForLoop(for_stmt.0, for_stmt.1, for_stmt.2, for_stmt.3)
}
Some(Token::While) => {
let while_stmt = stream.parse::<WhileStatement>()?;
Stmt::WhileLoop(while_stmt.0, while_stmt.1)
}
_ => { _ => {
if let Ok(SetStatement(ident, expr, range)) = stream.parse() { if let Ok(SetStatement(ident, expr, range)) = stream.parse() {
Stmt::Set(ident, expr, range) Stmt::Set(ident, expr, range)
@ -683,6 +691,34 @@ impl Parse for BlockLevelStatement {
} }
} }
#[derive(Debug)]
pub struct ForStatement(String, Expression, Expression, Block);
#[derive(Debug)]
pub struct WhileStatement(Expression, Block);
impl Parse for ForStatement {
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
stream.expect(Token::For)?;
let Some(Token::Identifier(idx)) = stream.next() else {
return Err(stream.expected_err("loop counter")?);
};
stream.expect(Token::In)?;
let start = stream.parse()?;
stream.expect(Token::To)?;
let end = stream.parse()?;
Ok(ForStatement(idx, start, end, stream.parse()?))
}
}
impl Parse for WhileStatement {
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
stream.expect(Token::While)?;
Ok(WhileStatement(stream.parse()?, stream.parse()?))
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct SetStatement(Expression, Expression, TokenRange); pub struct SetStatement(Expression, Expression, TokenRange);

View File

@ -148,7 +148,7 @@ impl ast::Block {
ast::BlockLevelStatement::Return(_, e) => { ast::BlockLevelStatement::Return(_, e) => {
(StmtKind::Expression(e.process(module_id)), e.1) (StmtKind::Expression(e.process(module_id)), e.1)
} }
ast::BlockLevelStatement::ForLoop(expression, expression1, block) => { ast::BlockLevelStatement::ForLoop(counter, start, end, block) => {
todo!() todo!()
} }
ast::BlockLevelStatement::WhileLoop(expression, block) => todo!(), ast::BlockLevelStatement::WhileLoop(expression, block) => todo!(),

View File

@ -46,6 +46,12 @@ pub enum Token {
While, While,
/// `for` /// `for`
For, For,
/// `from`
From,
/// `to`
To,
/// `to`
In,
// Symbols // Symbols
/// `;` /// `;`
@ -141,6 +147,9 @@ impl ToString for Token {
Token::Struct => String::from("struct"), Token::Struct => String::from("struct"),
Token::AsKeyword => String::from("as"), Token::AsKeyword => String::from("as"),
Token::For => String::from("for"), Token::For => String::from("for"),
Token::From => String::from("from"),
Token::In => String::from("in"),
Token::To => String::from("to"),
Token::While => String::from("while"), Token::While => String::from("while"),
Token::Semi => String::from(';'), Token::Semi => String::from(';'),
Token::Equals => String::from('='), Token::Equals => String::from('='),
@ -330,6 +339,9 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Error
"as" => Token::AsKeyword, "as" => Token::AsKeyword,
"for" => Token::For, "for" => Token::For,
"while" => Token::While, "while" => Token::While,
"in" => Token::In,
"from" => Token::From,
"to" => Token::To,
_ => Token::Identifier(value), _ => Token::Identifier(value),
}; };
variant variant

View File

@ -112,6 +112,9 @@ pub fn compile_module<'map>(
is_main, is_main,
}; };
#[cfg(debug_assertions)]
dbg!(&ast_module);
Ok(ast_module.process(module_id)) Ok(ast_module.process(module_id))
} }

View File

@ -188,7 +188,6 @@ impl<'map> Pass for LinkerPass<'map> {
.borrow_mut(); .borrow_mut();
let func_name = unsafe { path.get_unchecked(1) }; let func_name = unsafe { path.get_unchecked(1) };
let imported_mod_name = imported.name.clone();
let Some(func) = imported.functions.iter_mut().find(|f| f.name == *func_name) let Some(func) = imported.functions.iter_mut().find(|f| f.name == *func_name)
else { else {