mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-15 15:41:26 -07:00
Replace compile_assert with #assert
This commit is contained in:
+48
-43
@@ -2813,28 +2813,49 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
case BuiltinProc_DIRECTIVE: {
|
||||
ast_node(bd, BasicDirective, ce->proc);
|
||||
String name = bd->name;
|
||||
GB_ASSERT(name == "location");
|
||||
if (ce->args.count > 1) {
|
||||
error(ce->args[0], "'#location' expects either 0 or 1 arguments, got %td", ce->args.count);
|
||||
}
|
||||
if (ce->args.count > 0) {
|
||||
AstNode *arg = ce->args[0];
|
||||
Entity *e = nullptr;
|
||||
Operand o = {};
|
||||
if (arg->kind == AstNode_Ident) {
|
||||
e = check_ident(c, &o, arg, nullptr, nullptr, true);
|
||||
} else if (arg->kind == AstNode_SelectorExpr) {
|
||||
e = check_selector(c, &o, arg, nullptr);
|
||||
if (name == "location") {
|
||||
if (ce->args.count > 1) {
|
||||
error(ce->args[0], "'#location' expects either 0 or 1 arguments, got %td", ce->args.count);
|
||||
}
|
||||
if (e == nullptr) {
|
||||
error(ce->args[0], "'#location' expected a valid entity name");
|
||||
if (ce->args.count > 0) {
|
||||
AstNode *arg = ce->args[0];
|
||||
Entity *e = nullptr;
|
||||
Operand o = {};
|
||||
if (arg->kind == AstNode_Ident) {
|
||||
e = check_ident(c, &o, arg, nullptr, nullptr, true);
|
||||
} else if (arg->kind == AstNode_SelectorExpr) {
|
||||
e = check_selector(c, &o, arg, nullptr);
|
||||
}
|
||||
if (e == nullptr) {
|
||||
error(ce->args[0], "'#location' expected a valid entity name");
|
||||
}
|
||||
}
|
||||
|
||||
operand->type = t_source_code_location;
|
||||
operand->mode = Addressing_Value;
|
||||
} else if (name == "assert") {
|
||||
if (ce->args.count != 1) {
|
||||
error(call, "'#assert' expects at 1 argument, got %td", ce->args.count);
|
||||
return false;
|
||||
}
|
||||
if (!is_type_boolean(operand->type) && operand->mode != Addressing_Constant) {
|
||||
gbString str = expr_to_string(ce->args[0]);
|
||||
error(call, "'%s' is not a constant boolean", str);
|
||||
gb_string_free(str);
|
||||
return false;
|
||||
}
|
||||
if (!operand->value.value_bool) {
|
||||
gbString arg = expr_to_string(ce->args[0]);
|
||||
error(call, "Compile time assertion: %s", arg);
|
||||
gb_string_free(arg);
|
||||
}
|
||||
|
||||
operand->type = t_untyped_bool;
|
||||
operand->mode = Addressing_Constant;
|
||||
} else {
|
||||
GB_PANIC("Unhandled #%.*s", LIT(name));
|
||||
}
|
||||
|
||||
|
||||
operand->type = t_source_code_location;
|
||||
operand->mode = Addressing_Value;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3321,25 +3342,6 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_compile_assert:
|
||||
// proc compile_assert(cond: bool) -> bool
|
||||
|
||||
if (!is_type_boolean(operand->type) && operand->mode != Addressing_Constant) {
|
||||
gbString str = expr_to_string(ce->args[0]);
|
||||
error(call, "'%s' is not a constant boolean", str);
|
||||
gb_string_free(str);
|
||||
return false;
|
||||
}
|
||||
if (!operand->value.value_bool) {
|
||||
gbString str = expr_to_string(ce->args[0]);
|
||||
error(call, "Compile time assertion: '%s'", str);
|
||||
gb_string_free(str);
|
||||
}
|
||||
|
||||
operand->mode = Addressing_Constant;
|
||||
operand->type = t_untyped_bool;
|
||||
break;
|
||||
|
||||
case BuiltinProc_swizzle: {
|
||||
// proc swizzle(v: [N]T, ...int) -> [M]T
|
||||
Type *type = base_type(operand->type);
|
||||
@@ -4805,12 +4807,15 @@ ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) {
|
||||
ce->proc->kind == AstNode_BasicDirective) {
|
||||
ast_node(bd, BasicDirective, ce->proc);
|
||||
String name = bd->name;
|
||||
GB_ASSERT(name == "location");
|
||||
operand->mode = Addressing_Builtin;
|
||||
operand->builtin_id = BuiltinProc_DIRECTIVE;
|
||||
operand->expr = ce->proc;
|
||||
operand->type = t_invalid;
|
||||
add_type_and_value(&c->info, ce->proc, operand->mode, operand->type, operand->value);
|
||||
if (name == "location" || name == "assert") {
|
||||
operand->mode = Addressing_Builtin;
|
||||
operand->builtin_id = BuiltinProc_DIRECTIVE;
|
||||
operand->expr = ce->proc;
|
||||
operand->type = t_invalid;
|
||||
add_type_and_value(&c->info, ce->proc, operand->mode, operand->type, operand->value);
|
||||
} else {
|
||||
GB_PANIC("Unhandled #%.*s", LIT(name));
|
||||
}
|
||||
} else {
|
||||
check_expr_or_type(c, operand, ce->proc);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "entity.cpp"
|
||||
#include "types.cpp"
|
||||
|
||||
void check_expr(Checker *c, Operand *operand, AstNode *expression);
|
||||
|
||||
|
||||
bool is_operand_value(Operand o) {
|
||||
switch (o.mode) {
|
||||
@@ -272,6 +274,7 @@ void destroy_scope(Scope *scope) {
|
||||
map_destroy(&scope->elements);
|
||||
array_free(&scope->shared);
|
||||
array_free(&scope->delayed_file_decls);
|
||||
array_free(&scope->delayed_asserts);
|
||||
ptr_set_destroy(&scope->implicit);
|
||||
ptr_set_destroy(&scope->imported);
|
||||
ptr_set_destroy(&scope->exported);
|
||||
@@ -444,6 +447,7 @@ GB_COMPARE_PROC(entity_variable_pos_cmp) {
|
||||
return token_pos_cmp(x->token.pos, y->token.pos);
|
||||
}
|
||||
|
||||
|
||||
void check_scope_usage(Checker *c, Scope *scope) {
|
||||
// TODO(bill): Use this?
|
||||
#if 0
|
||||
@@ -2678,6 +2682,14 @@ bool collect_file_decls(Checker *c, Array<AstNode *> decls) {
|
||||
}
|
||||
}
|
||||
case_end;
|
||||
|
||||
case_ast_node(ce, CallExpr, decl);
|
||||
if (ce->proc->kind == AstNode_BasicDirective &&
|
||||
ce->proc->BasicDirective.name == "assert") {
|
||||
Operand o = {};
|
||||
check_expr(c, &o, decl);
|
||||
}
|
||||
case_end;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-4
@@ -90,8 +90,6 @@ enum BuiltinProcId {
|
||||
BuiltinProc_type_of,
|
||||
BuiltinProc_type_info_of,
|
||||
|
||||
BuiltinProc_compile_assert,
|
||||
|
||||
BuiltinProc_swizzle,
|
||||
|
||||
BuiltinProc_complex,
|
||||
@@ -134,8 +132,6 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
|
||||
{STR_LIT("type_of"), 1, false, Expr_Expr},
|
||||
{STR_LIT("type_info_of"), 1, false, Expr_Expr},
|
||||
|
||||
{STR_LIT("compile_assert"), 1, false, Expr_Expr},
|
||||
|
||||
{STR_LIT("swizzle"), 1, true, Expr_Expr},
|
||||
|
||||
{STR_LIT("complex"), 2, false, Expr_Expr},
|
||||
@@ -221,6 +217,7 @@ struct Scope {
|
||||
|
||||
Array<Scope *> shared;
|
||||
Array<AstNode *> delayed_file_decls;
|
||||
Array<AstNode *> delayed_asserts;
|
||||
PtrSet<Scope *> imported;
|
||||
PtrSet<Scope *> exported; // NOTE(bhall): Contains 'using import' too
|
||||
bool is_proc;
|
||||
|
||||
@@ -303,8 +303,6 @@ Entity *make_entity_label(gbAllocator a, Scope *scope, Token token, Type *type,
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Entity *make_entity_dummy_variable(gbAllocator a, Scope *scope, Token token) {
|
||||
token.string = str_lit("_");
|
||||
return make_entity_variable(a, scope, token, nullptr, false);
|
||||
|
||||
@@ -1659,6 +1659,9 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
|
||||
} else if (name.string == "location") {
|
||||
AstNode *tag = ast_basic_directive(f, token, name.string);
|
||||
return parse_call_expr(f, tag);
|
||||
} else if (name.string == "assert") {
|
||||
AstNode *tag = ast_basic_directive(f, token, name.string);
|
||||
return parse_call_expr(f, tag);
|
||||
} else {
|
||||
operand = ast_tag_expr(f, token, name, parse_expr(f, false));
|
||||
}
|
||||
@@ -3735,6 +3738,9 @@ AstNode *parse_stmt(AstFile *f) {
|
||||
break;
|
||||
}
|
||||
return s;
|
||||
} else if (tag == "assert") {
|
||||
AstNode *t = ast_basic_directive(f, hash_token, tag);
|
||||
return parse_call_expr(f, t);
|
||||
}
|
||||
|
||||
if (tag == "include") {
|
||||
@@ -4058,6 +4064,14 @@ void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Array<AstNod
|
||||
node->kind != AstNode_EmptyStmt &&
|
||||
node->kind != AstNode_WhenStmt) {
|
||||
// NOTE(bill): Sanity check
|
||||
|
||||
if (node->kind == AstNode_CallExpr &&
|
||||
node->CallExpr.proc->kind == AstNode_BasicDirective &&
|
||||
node->CallExpr.proc->BasicDirective.name == "assert") {
|
||||
// NOTE(bill): Okay!
|
||||
continue;
|
||||
}
|
||||
|
||||
syntax_error(node, "Only declarations are allowed at file scope, got %.*s", LIT(ast_node_strings[node->kind]));
|
||||
} else if (node->kind == AstNode_ImportDecl) {
|
||||
ast_node(id, ImportDecl, node);
|
||||
|
||||
Reference in New Issue
Block a user