While statements

This commit is contained in:
mars 2022-03-26 23:50:37 -06:00
parent f8ec9c19d6
commit 243990971d
2 changed files with 47 additions and 1 deletions

View File

@ -190,4 +190,24 @@ mod tests {
assert_eq!(code_fn((2, 4)), 12);
assert_eq!(code_fn((7, 3)), 30);
}
#[test]
fn while_statement() {
let source = r#"
iterative_fibonacci(i64 iterations) i64 {
let mut a = 0;
let mut b = 1;
let mut i = 0;
while i < iterations {
let c = a + b;
a = b;
b = c;
i = (i + 1);
}
b
}"#;
let code_fn = jit_fn::<i64, i64>(source);
assert_eq!(code_fn(10), 89);
}
}

View File

@ -94,13 +94,16 @@ impl<'a> FunctionTranslator<'a> {
Expr(expr) => {
self.translate_expr(expr);
}
While {
test_expr,
loop_body,
} => self.translate_while_stmt(test_expr, loop_body),
Let { var, mutable, expr } => {
let val = self.translate_expr(expr);
let var = self.add_local(self.int, var, *mutable);
self.builder.def_var(var, val);
}
If(if_stmt) => self.translate_if_stmt(if_stmt),
_ => unimplemented!(),
}
}
@ -196,6 +199,29 @@ impl<'a> FunctionTranslator<'a> {
self.builder.seal_block(merge_block);
}
pub fn translate_while_stmt(&mut self, test_expr: &ast::Expr, loop_body: &ast::BranchBody) {
let header_block = self.builder.create_block();
let body_block = self.builder.create_block();
let exit_block = self.builder.create_block();
self.builder.ins().jump(header_block, &[]);
self.builder.switch_to_block(header_block);
let test_val = self.translate_expr(test_expr);
self.builder.ins().brz(test_val, exit_block, &[]);
self.builder.ins().jump(body_block, &[]);
self.builder.switch_to_block(body_block);
self.builder.seal_block(body_block);
let val = self.translate_branch_body(loop_body);
assert_eq!(val, None, "While statement body has tail expression");
self.builder.ins().jump(header_block, &[]);
self.builder.switch_to_block(exit_block);
self.builder.seal_block(header_block);
self.builder.seal_block(exit_block);
}
pub fn translate_branch_body(&mut self, branch_body: &ast::BranchBody) -> Option<Value> {
let scope_size = self.locals.len();