Assert Statement Support #251

Merged
sb10q merged 1 commits from assert into master 2022-03-29 06:56:40 +08:00
3 changed files with 39 additions and 2 deletions

View File

@ -410,6 +410,19 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
err_msg: &str, err_msg: &str,
params: [Option<IntValue<'ctx>>; 3], params: [Option<IntValue<'ctx>>; 3],
loc: Location, loc: Location,
) {
let err_msg = self.gen_string(generator, err_msg);
self.make_assert_impl(generator, cond, err_name, err_msg, params, loc)
}
pub fn make_assert_impl<G: CodeGenerator>(
&mut self,
generator: &mut G,
cond: IntValue<'ctx>,
err_name: &str,
err_msg: BasicValueEnum<'ctx>,
params: [Option<IntValue<'ctx>>; 3],
loc: Location,
) { ) {
let i1 = self.ctx.bool_type(); let i1 = self.ctx.bool_type();
let i1_true = i1.const_all_ones(); let i1_true = i1.const_all_ones();
@ -436,7 +449,6 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
let exn_block = self.ctx.append_basic_block(current_fun, "fail"); let exn_block = self.ctx.append_basic_block(current_fun, "fail");
self.builder.build_conditional_branch(cond, then_block, exn_block); self.builder.build_conditional_branch(cond, then_block, exn_block);
self.builder.position_at_end(exn_block); self.builder.position_at_end(exn_block);
let err_msg = self.gen_string(generator, err_msg);
self.raise_exn(generator, err_name, err_msg, params, loc); self.raise_exn(generator, err_name, err_msg, params, loc);
self.builder.position_at_end(then_block); self.builder.position_at_end(then_block);
} }

View File

@ -975,7 +975,25 @@ pub fn gen_stmt<'ctx, 'a, G: CodeGenerator>(
gen_raise(generator, ctx, None, stmt.location); gen_raise(generator, ctx, None, stmt.location);
} }
} }
_ => unimplemented!(), StmtKind::Assert { test, msg, .. } => {
let test =
generator.gen_expr(ctx, test)?.unwrap().to_basic_value_enum(ctx, generator)?;
let err_msg = match msg {
Some(msg) => {
generator.gen_expr(ctx, msg)?.unwrap().to_basic_value_enum(ctx, generator)?
}
None => ctx.gen_string(generator, ""),
};
ctx.make_assert_impl(
generator,
test.into_int_value(),
"0:AssertionError",
err_msg,
[None, None, None],
stmt.location,
)
}
_ => unimplemented!()
}; };
Ok(()) Ok(())
} }

View File

@ -426,6 +426,13 @@ impl<'a> fold::Fold<()> for Inferencer<'a> {
let res_ty = self.infer_bin_ops(stmt.location, target, op, value)?; let res_ty = self.infer_bin_ops(stmt.location, target, op, value)?;
self.unify(res_ty, target.custom.unwrap(), &stmt.location)?; self.unify(res_ty, target.custom.unwrap(), &stmt.location)?;
} }
ast::StmtKind::Assert { test, msg, .. } => {
self.unify(test.custom.unwrap(), self.primitives.bool, &test.location)?;
match msg {
Some(m) => self.unify(m.custom.unwrap(), self.primitives.str, &m.location)?,
None => ()
}
}
_ => return report_error("Unsupported statement type", stmt.location), _ => return report_error("Unsupported statement type", stmt.location),
}; };
Ok(stmt) Ok(stmt)