diff --git a/reid/src/ast/mod.rs b/reid/src/ast/mod.rs index 038e4b9..3995f95 100644 --- a/reid/src/ast/mod.rs +++ b/reid/src/ast/mod.rs @@ -178,7 +178,7 @@ pub enum BlockLevelStatement { }, Expression(Expression), Return(ReturnType, Expression), - ForLoop(String, Expression, Expression, Block), + ForLoop(String, TokenRange, Expression, Expression, Block), WhileLoop(Expression, Block), } diff --git a/reid/src/ast/parse.rs b/reid/src/ast/parse.rs index 96fe0b6..34edad4 100644 --- a/reid/src/ast/parse.rs +++ b/reid/src/ast/parse.rs @@ -669,7 +669,7 @@ impl Parse for BlockLevelStatement { } Some(Token::For) => { let for_stmt = stream.parse::()?; - Stmt::ForLoop(for_stmt.0, for_stmt.1, for_stmt.2, for_stmt.3) + Stmt::ForLoop(for_stmt.0, for_stmt.1, for_stmt.2, for_stmt.3, for_stmt.4) } Some(Token::While) => { let while_stmt = stream.parse::()?; @@ -692,7 +692,7 @@ impl Parse for BlockLevelStatement { } #[derive(Debug)] -pub struct ForStatement(String, Expression, Expression, Block); +pub struct ForStatement(String, TokenRange, Expression, Expression, Block); #[derive(Debug)] pub struct WhileStatement(Expression, Block); @@ -703,12 +703,13 @@ impl Parse for ForStatement { let Some(Token::Identifier(idx)) = stream.next() else { return Err(stream.expected_err("loop counter")?); }; + let start_range = stream.get_range().unwrap(); stream.expect(Token::In)?; let start = stream.parse()?; stream.expect(Token::To)?; let end = stream.parse()?; - Ok(ForStatement(idx, start, end, stream.parse()?)) + Ok(ForStatement(idx, start_range, start, end, stream.parse()?)) } } diff --git a/reid/src/ast/process.rs b/reid/src/ast/process.rs index b9d9317..929a86f 100644 --- a/reid/src/ast/process.rs +++ b/reid/src/ast/process.rs @@ -3,8 +3,8 @@ use std::path::PathBuf; use crate::{ ast::{self}, mir::{ - self, CustomTypeKey, ModuleMap, NamedVariableRef, SourceModuleId, StmtKind, StructField, - StructType, + self, CustomTypeKey, ForStatement, ModuleMap, NamedVariableRef, SourceModuleId, StmtKind, + StructField, StructType, WhileStatement, }, }; @@ -148,10 +148,28 @@ impl ast::Block { ast::BlockLevelStatement::Return(_, e) => { (StmtKind::Expression(e.process(module_id)), e.1) } - ast::BlockLevelStatement::ForLoop(counter, start, end, block) => { - todo!() - } - ast::BlockLevelStatement::WhileLoop(expression, block) => todo!(), + ast::BlockLevelStatement::ForLoop(counter, counter_range, start, end, block) => ( + StmtKind::For(ForStatement { + counter: NamedVariableRef( + mir::TypeKind::Vague(mir::VagueType::Unknown), + counter.clone(), + counter_range.as_meta(module_id), + ), + start: start.process(module_id), + end: end.process(module_id), + block: block.into_mir(module_id), + meta: self.2.as_meta(module_id), + }), + self.2, + ), + ast::BlockLevelStatement::WhileLoop(expression, block) => ( + StmtKind::While(WhileStatement { + condition: expression.process(module_id), + block: block.into_mir(module_id), + meta: self.2.as_meta(module_id), + }), + self.2, + ), }; mir_statements.push(mir::Statement(kind, range.as_meta(module_id))); diff --git a/reid/src/codegen.rs b/reid/src/codegen.rs index 6abc671..2b270ca 100644 --- a/reid/src/codegen.rs +++ b/reid/src/codegen.rs @@ -598,6 +598,8 @@ impl mir::Statement { } mir::StmtKind::Import(_) => todo!(), mir::StmtKind::Expression(expression) => expression.codegen(scope, state), + mir::StmtKind::For(for_statement) => todo!(), + mir::StmtKind::While(while_statement) => todo!(), } } } diff --git a/reid/src/mir/fmt.rs b/reid/src/mir/fmt.rs index 53e5417..4bf9b98 100644 --- a/reid/src/mir/fmt.rs +++ b/reid/src/mir/fmt.rs @@ -147,7 +147,7 @@ impl Display for Statement { impl Display for StmtKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Self::Let(var, mutable, block) => { + StmtKind::Let(var, mutable, block) => { write!( f, "let{} {} = {}", @@ -156,9 +156,26 @@ impl Display for StmtKind { block ) } - Self::Set(var, expr) => write!(f, "{} = {}", var, expr), - Self::Import(n) => write!(f, "import {}", n), - Self::Expression(exp) => Display::fmt(exp, f), + StmtKind::Set(var, expr) => write!(f, "{} = {}", var, expr), + StmtKind::Import(n) => write!(f, "import {}", n), + StmtKind::Expression(exp) => Display::fmt(exp, f), + StmtKind::For(for_statement) => { + write!( + f, + "for {} in {} to {} {}", + for_statement.counter, + for_statement.start, + for_statement.end, + for_statement.block + ) + } + StmtKind::While(while_statement) => { + write!( + f, + "while {} {}", + while_statement.condition, while_statement.block, + ) + } } } } diff --git a/reid/src/mir/implement.rs b/reid/src/mir/implement.rs index 7f36ec3..18ee891 100644 --- a/reid/src/mir/implement.rs +++ b/reid/src/mir/implement.rs @@ -9,6 +9,7 @@ pub enum ReturnTypeOther { NoBlockReturn(Metadata), IndexingNonArray(Metadata), DerefNonBorrow(Metadata), + Loop, } impl TypeKind { @@ -374,6 +375,8 @@ impl Statement { ), Import(_) => todo!(), Expression(expression) => expression.return_type(refs, mod_id), + For(_) => Err(ReturnTypeOther::Loop), + While(_) => Err(ReturnTypeOther::Loop), } } @@ -383,6 +386,8 @@ impl Statement { StmtKind::Set(_, _) => None, StmtKind::Import(_) => None, StmtKind::Expression(expr) => expr.backing_var(), + StmtKind::For(_) => None, + StmtKind::While(_) => None, } } } diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index 1372bbd..4229b19 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -338,6 +338,24 @@ pub enum StmtKind { Set(Expression, Expression), Import(Import), Expression(Expression), + For(ForStatement), + While(WhileStatement), +} + +#[derive(Debug)] +pub struct ForStatement { + pub counter: NamedVariableRef, + pub start: Expression, + pub end: Expression, + pub block: Block, + pub meta: Metadata, +} + +#[derive(Debug)] +pub struct WhileStatement { + pub condition: Expression, + pub block: Block, + pub meta: Metadata, } #[derive(Debug, Clone)] diff --git a/reid/src/mir/pass.rs b/reid/src/mir/pass.rs index 5409d80..ac7ee85 100644 --- a/reid/src/mir/pass.rs +++ b/reid/src/mir/pass.rs @@ -390,10 +390,19 @@ impl Statement { StmtKind::Set(_, expression) => { expression.pass(pass, state, scope, mod_id)?; } - StmtKind::Import(_) => {} // Never exists at this stage + StmtKind::Import(_) => {} StmtKind::Expression(expression) => { expression.pass(pass, state, scope, mod_id)?; } + StmtKind::For(for_statement) => { + for_statement.start.pass(pass, state, scope, mod_id); + for_statement.end.pass(pass, state, scope, mod_id); + for_statement.block.pass(pass, state, scope, mod_id); + } + StmtKind::While(while_statement) => { + while_statement.condition.pass(pass, state, scope, mod_id); + while_statement.block.pass(pass, state, scope, mod_id); + } } pass.stmt(self, PassState::from(state, scope, Some(mod_id)))?; @@ -412,8 +421,10 @@ impl Statement { .ok(); } StmtKind::Set(_, _) => {} - StmtKind::Import(_) => {} // Never exists at this stage + StmtKind::Import(_) => {} StmtKind::Expression(_) => {} + StmtKind::For(_) => {} + StmtKind::While(_) => {} }; Ok(()) } diff --git a/reid/src/mir/typecheck.rs b/reid/src/mir/typecheck.rs index 9d8dfc0..f3582c6 100644 --- a/reid/src/mir/typecheck.rs +++ b/reid/src/mir/typecheck.rs @@ -323,7 +323,7 @@ impl Block { None } - StmtKind::Import(_) => todo!(), // TODO + StmtKind::Import(_) => todo!(), StmtKind::Expression(expression) => { let res = expression.typecheck(&mut state, &typerefs, None); state.or_else(res, TypeKind::Void, expression.1); @@ -335,6 +335,8 @@ impl Block { None } } + StmtKind::For(for_statement) => todo!(), + StmtKind::While(while_statement) => todo!(), }; if let Some((ReturnKind::Hard, _)) = ret { diff --git a/reid/src/mir/typeinference.rs b/reid/src/mir/typeinference.rs index 35bf42f..22379c9 100644 --- a/reid/src/mir/typeinference.rs +++ b/reid/src/mir/typeinference.rs @@ -126,6 +126,8 @@ impl Block { let expr_res = expr.infer_types(&mut state, &inner_refs); state.ok(expr_res, expr.1); } + StmtKind::For(for_statement) => todo!(), + StmtKind::While(while_statement) => todo!(), }; }