From a38cc0444456392fba6949367e4073ee9df149bf Mon Sep 17 00:00:00 2001 From: ychenfo Date: Tue, 29 Mar 2022 00:13:47 +0800 Subject: [PATCH] nac3core: assert statement --- nac3core/src/codegen/expr.rs | 14 ++++++++++++- nac3core/src/codegen/stmt.rs | 20 ++++++++++++++++++- nac3core/src/typecheck/type_inferencer/mod.rs | 7 +++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/nac3core/src/codegen/expr.rs b/nac3core/src/codegen/expr.rs index 09ae3125..3a1ca2ae 100644 --- a/nac3core/src/codegen/expr.rs +++ b/nac3core/src/codegen/expr.rs @@ -410,6 +410,19 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { err_msg: &str, params: [Option>; 3], 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( + &mut self, + generator: &mut G, + cond: IntValue<'ctx>, + err_name: &str, + err_msg: BasicValueEnum<'ctx>, + params: [Option>; 3], + loc: Location, ) { let i1 = self.ctx.bool_type(); 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"); self.builder.build_conditional_branch(cond, then_block, 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.builder.position_at_end(then_block); } diff --git a/nac3core/src/codegen/stmt.rs b/nac3core/src/codegen/stmt.rs index fa869d30..18ffc823 100644 --- a/nac3core/src/codegen/stmt.rs +++ b/nac3core/src/codegen/stmt.rs @@ -975,7 +975,25 @@ pub fn gen_stmt<'ctx, 'a, G: CodeGenerator>( 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(()) } diff --git a/nac3core/src/typecheck/type_inferencer/mod.rs b/nac3core/src/typecheck/type_inferencer/mod.rs index 1e99ae29..510a0f09 100644 --- a/nac3core/src/typecheck/type_inferencer/mod.rs +++ b/nac3core/src/typecheck/type_inferencer/mod.rs @@ -426,6 +426,13 @@ impl<'a> fold::Fold<()> for Inferencer<'a> { let res_ty = self.infer_bin_ops(stmt.location, target, op, value)?; 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), }; Ok(stmt)