Codegen for/while loops
This commit is contained in:
parent
a251be2715
commit
c4017715d2
@ -696,7 +696,7 @@ impl Parse for BlockLevelStatement {
|
|||||||
pub struct ForStatement(String, TokenRange, Expression, Expression, Block);
|
pub struct ForStatement(String, TokenRange, Expression, Expression, Block);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct WhileStatement(Expression, Block);
|
pub struct WhileStatement(pub Expression, pub Block);
|
||||||
|
|
||||||
impl Parse for ForStatement {
|
impl Parse for ForStatement {
|
||||||
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
|
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
|
||||||
|
@ -19,6 +19,7 @@ use crate::{
|
|||||||
mir::{
|
mir::{
|
||||||
self, implement::TypeCategory, CustomTypeKey, Metadata, NamedVariableRef, SourceModuleId,
|
self, implement::TypeCategory, CustomTypeKey, Metadata, NamedVariableRef, SourceModuleId,
|
||||||
StructField, StructType, TypeDefinition, TypeDefinitionKind, TypeKind, VagueLiteral,
|
StructField, StructType, TypeDefinition, TypeDefinitionKind, TypeKind, VagueLiteral,
|
||||||
|
WhileStatement,
|
||||||
},
|
},
|
||||||
util::try_all,
|
util::try_all,
|
||||||
};
|
};
|
||||||
@ -598,7 +599,54 @@ impl mir::Statement {
|
|||||||
}
|
}
|
||||||
mir::StmtKind::Import(_) => todo!(),
|
mir::StmtKind::Import(_) => todo!(),
|
||||||
mir::StmtKind::Expression(expression) => expression.codegen(scope, state),
|
mir::StmtKind::Expression(expression) => expression.codegen(scope, state),
|
||||||
mir::StmtKind::While(_) => todo!(),
|
mir::StmtKind::While(WhileStatement {
|
||||||
|
condition, block, ..
|
||||||
|
}) => {
|
||||||
|
let condition_block = scope.function.ir.block("condition_block");
|
||||||
|
let condition_true_block = scope.function.ir.block("condition_true");
|
||||||
|
let condition_failed_block = scope.function.ir.block("condition_failed");
|
||||||
|
|
||||||
|
scope
|
||||||
|
.block
|
||||||
|
.terminate(Term::Br(condition_block.value()))
|
||||||
|
.unwrap();
|
||||||
|
let mut condition_scope = scope.with_block(condition_block);
|
||||||
|
let condition_res = condition.codegen(&mut condition_scope, state)?.unwrap();
|
||||||
|
let true_instr = condition_scope
|
||||||
|
.block
|
||||||
|
.build(Instr::Constant(ConstValue::Bool(true)))
|
||||||
|
.unwrap();
|
||||||
|
let check = condition_scope
|
||||||
|
.block
|
||||||
|
.build(Instr::ICmp(
|
||||||
|
CmpPredicate::EQ,
|
||||||
|
condition_res.instr(),
|
||||||
|
true_instr,
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
condition_scope
|
||||||
|
.block
|
||||||
|
.terminate(Term::CondBr(
|
||||||
|
check,
|
||||||
|
condition_true_block.value(),
|
||||||
|
condition_failed_block.value(),
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut condition_true_scope = scope.with_block(condition_true_block);
|
||||||
|
block.codegen(&mut condition_true_scope, state)?;
|
||||||
|
|
||||||
|
condition_true_scope
|
||||||
|
.block
|
||||||
|
.terminate(Term::Br(condition_scope.block.value()))
|
||||||
|
// Can hard return inside the condition_true_scope
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
scope.swap_block(condition_failed_block);
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -336,9 +336,19 @@ impl Block {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
StmtKind::While(WhileStatement {
|
StmtKind::While(WhileStatement {
|
||||||
condition, block, ..
|
condition,
|
||||||
|
block,
|
||||||
|
meta,
|
||||||
}) => {
|
}) => {
|
||||||
|
let condition_ty =
|
||||||
condition.typecheck(&mut state, typerefs, Some(&TypeKind::Bool))?;
|
condition.typecheck(&mut state, typerefs, Some(&TypeKind::Bool))?;
|
||||||
|
if condition_ty.assert_known(typerefs, &state)? != TypeKind::Bool {
|
||||||
|
state.note_errors(
|
||||||
|
&vec![ErrorKind::TypesIncompatible(condition_ty, TypeKind::Bool)],
|
||||||
|
*meta,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
block.typecheck(&mut state, typerefs, None)?;
|
block.typecheck(&mut state, typerefs, None)?;
|
||||||
|
|
||||||
None
|
None
|
||||||
|
@ -120,3 +120,7 @@ fn strings_compiles_well() {
|
|||||||
fn struct_compiles_well() {
|
fn struct_compiles_well() {
|
||||||
test(include_str!("../../examples/struct.reid"), "test", 17);
|
test(include_str!("../../examples/struct.reid"), "test", 17);
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
fn loops_compiles_well() {
|
||||||
|
test(include_str!("../../examples/loops.reid"), "test", 10);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user