Translate if statements

This commit is contained in:
mars 2022-03-26 23:27:02 -06:00
parent 2098fef856
commit f8ec9c19d6
2 changed files with 55 additions and 0 deletions

View File

@ -171,4 +171,23 @@ mod tests {
assert_eq!(code_fn((2, 4)), 22); // Test 1
assert_eq!(code_fn((7, 3)), 65); // Test 2
}
#[test]
fn if_statement() {
let source = r#"
if_statement(i64 a, i64 b) i64 {
let mut c = a + b;
if a < b {
c = (c * a);
} else {
c = (c * b);
}
c
}"#;
let code_fn = jit_fn::<(i64, i64), i64>(source);
assert_eq!(code_fn((2, 4)), 12);
assert_eq!(code_fn((7, 3)), 30);
}
}

View File

@ -99,6 +99,7 @@ impl<'a> FunctionTranslator<'a> {
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!(),
}
}
@ -160,6 +161,41 @@ impl<'a> FunctionTranslator<'a> {
self.builder.block_params(merge_block)[0]
}
pub fn translate_if_stmt(&mut self, if_stmt: &ast::IfStmt) {
let ast::IfStmt {
test_expr,
then_body,
else_body,
} = if_stmt;
let test_val = self.translate_expr(test_expr);
let then_block = self.builder.create_block();
let else_info = else_body.as_ref().map(|b| (b, self.builder.create_block()));
let merge_block = self.builder.create_block();
let else_jump = else_info.map(|b| b.1).unwrap_or(merge_block);
self.builder.ins().brz(test_val, else_jump, &[]);
self.builder.ins().jump(then_block, &[]);
let mut translate_branch = |block, body| {
self.builder.switch_to_block(block);
self.builder.seal_block(block);
let val = self.translate_branch_body(body);
assert_eq!(val, None, "If statement branch has tail expression");
self.builder.ins().jump(merge_block, &[]);
};
translate_branch(then_block, then_body);
if let Some((else_body, else_block)) = else_info {
translate_branch(else_block, else_body);
}
self.builder.switch_to_block(merge_block);
self.builder.seal_block(merge_block);
}
pub fn translate_branch_body(&mut self, branch_body: &ast::BranchBody) -> Option<Value> {
let scope_size = self.locals.len();