diff options
| author | gingerBill <bill@gingerbill.org> | 2024-06-10 15:02:34 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2024-06-10 15:02:34 +0100 |
| commit | fa3cae2bb04db76f52f1b2288a9c858f20332b8a (patch) | |
| tree | 063118fd6e63aab004680be7a87e1a7670fe4a09 /src/check_builtin.cpp | |
| parent | 1945218f6df814ea95233035d0b51585e2522b2e (diff) | |
Add `intrinsics.procedure_of`
```odin
foo :: proc(x: $T) { fmt.println(x) }
bar :: intrinsics.procedure_of(foo(int(123))) // parameters are never ran at compile time, similar to `size_of`
bar(333) // prints 333
```
Diffstat (limited to 'src/check_builtin.cpp')
| -rw-r--r-- | src/check_builtin.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 98c695a2c..3aee804df 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -1843,6 +1843,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As case BuiltinProc_objc_register_class: case BuiltinProc_atomic_type_is_lock_free: case BuiltinProc_has_target_feature: + case BuiltinProc_procedure_of: // NOTE(bill): The first arg may be a Type, this will be checked case by case break; @@ -6157,6 +6158,51 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As break; } + case BuiltinProc_procedure_of: + { + Ast *call_expr = unparen_expr(ce->args[0]); + Operand op = {}; + check_expr_base(c, &op, ce->args[0], nullptr); + if (op.mode != Addressing_Value && !(call_expr && call_expr->kind == Ast_CallExpr)) { + error(ce->args[0], "Expected a call expression for '%.*s'", LIT(builtin_name)); + return false; + } + + Ast *proc = call_expr->CallExpr.proc; + Entity *e = entity_of_node(proc); + + if (e == nullptr) { + error(ce->args[0], "Invalid procedure value, expected a regular/specialized procedure"); + return false; + } + + TypeAndValue tav = proc->tav; + + + operand->type = e->type; + operand->mode = Addressing_Value; + operand->value = tav.value; + operand->builtin_id = BuiltinProc_Invalid; + operand->proc_group = nullptr; + + if (tav.mode == Addressing_Builtin) { + operand->mode = tav.mode; + operand->builtin_id = cast(BuiltinProcId)e->Builtin.id; + break; + } + + if (!is_type_proc(e->type)) { + gbString s = type_to_string(e->type); + error(ce->args[0], "Expected a procedure value, got '%s'", s); + gb_string_free(s); + return false; + } + + + ce->entity_procedure_of = e; + break; + } + case BuiltinProc_constant_utf16_cstring: { String value = {}; |