Runtime assert

This commit is contained in:
Ginger Bill
2016-09-02 15:51:48 +01:00
parent 25e9b9bc87
commit e1a6775661
6 changed files with 122 additions and 51 deletions
+2 -2
View File
@@ -132,7 +132,7 @@ enum BuiltinProcId {
BuiltinProc_align_of_val,
BuiltinProc_offset_of,
BuiltinProc_offset_of_val,
BuiltinProc_static_assert,
BuiltinProc_assert,
BuiltinProc_len,
BuiltinProc_cap,
@@ -170,7 +170,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
{STR_LIT("align_of_val"), 1, false, Expr_Expr},
{STR_LIT("offset_of"), 2, false, Expr_Expr},
{STR_LIT("offset_of_val"), 1, false, Expr_Expr},
{STR_LIT("static_assert"), 1, false, Expr_Stmt},
{STR_LIT("assert"), 1, false, Expr_Stmt},
{STR_LIT("len"), 1, false, Expr_Expr},
{STR_LIT("cap"), 1, false, Expr_Expr},
+27 -15
View File
@@ -123,6 +123,8 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n
return;
}
if (type != NULL) {
if (!check_is_assignable_to(c, operand, type, is_argument)) {
gbString type_string = type_to_string(type);
@@ -132,16 +134,23 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n
defer (gb_string_free(op_type_string));
defer (gb_string_free(expr_str));
// TODO(bill): is this a good enough error message?
error(&c->error_collector, ast_node_token(operand->expr),
"Cannot assign value `%s` of type `%s` to `%s` in %.*s",
expr_str,
op_type_string,
type_string,
LIT(context_name));
if (operand->mode == Addressing_Builtin) {
// TODO(bill): is this a good enough error message?
error(&c->error_collector, ast_node_token(operand->expr),
"Cannot assign builtin procedure `%s` in %.*s",
expr_str,
LIT(context_name));
} else {
// TODO(bill): is this a good enough error message?
error(&c->error_collector, ast_node_token(operand->expr),
"Cannot assign value `%s` of type `%s` to `%s` in %.*s",
expr_str,
op_type_string,
type_string,
LIT(context_name));
}
operand->mode = Addressing_Invalid;
return;
}
}
}
@@ -1987,24 +1996,27 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
operand->type = t_int;
} break;
case BuiltinProc_static_assert:
// static_assert :: proc(cond: bool)
case BuiltinProc_assert:
// assert :: proc(cond: bool)
if (operand->mode != Addressing_Constant ||
!is_type_boolean(operand->type)) {
if (!is_type_boolean(operand->type)) {
gbString str = expr_to_string(ce->arg_list);
defer (gb_string_free(str));
error(&c->error_collector, ast_node_token(call),
"`%s` is not a constant boolean", str);
"`%s` is not a boolean", str);
return false;
}
if (!operand->value.value_bool) {
if (operand->mode == Addressing_Constant &&
!operand->value.value_bool) {
gbString str = expr_to_string(ce->arg_list);
defer (gb_string_free(str));
error(&c->error_collector, ast_node_token(call),
"Static assertion: `%s`", str);
return true;
}
if (operand->mode != Addressing_Constant) {
operand->mode = Addressing_NoValue;
}
break;
// TODO(bill): Should these be procedures and are their names appropriate?
+18 -3
View File
@@ -203,6 +203,21 @@ Type *check_init_variable(Checker *c, Entity *e, Operand *operand, String contex
if (operand->mode == Addressing_Invalid ||
operand->type == t_invalid ||
e->type == t_invalid) {
if (operand->mode == Addressing_Builtin) {
gbString expr_str = expr_to_string(operand->expr);
defer (gb_string_free(expr_str));
// TODO(bill): is this a good enough error message?
error(&c->error_collector, ast_node_token(operand->expr),
"Cannot assign builtin procedure `%s` in %.*s",
expr_str,
LIT(context_name));
operand->mode = Addressing_Invalid;
}
if (e->type == NULL)
e->type = t_invalid;
return NULL;
@@ -530,7 +545,7 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type, Cyc
void check_var_decl(Checker *c, AstNode *node) {
void check_var_decl_node(Checker *c, AstNode *node) {
ast_node(vd, VarDecl, node);
isize entity_count = vd->name_count;
isize entity_index = 0;
@@ -1150,7 +1165,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
if (vd->name_count > 1 && vd->type != NULL) {
error(&c->error_collector, us->token, "`using` can only be applied to one variable of the same type");
}
check_var_decl(c, us->node);
check_var_decl_node(c, us->node);
for (AstNode *item = vd->name_list; item != NULL; item = item->next) {
ast_node(i, Ident, item);
@@ -1191,7 +1206,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
case_ast_node(vd, VarDecl, node);
check_var_decl(c, node);
check_var_decl_node(c, node);
case_end;
case_ast_node(pd, ProcDecl, node);