aboutsummaryrefslogtreecommitdiff
path: root/src/check_builtin.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2024-06-10 15:02:34 +0100
committergingerBill <bill@gingerbill.org>2024-06-10 15:02:34 +0100
commitfa3cae2bb04db76f52f1b2288a9c858f20332b8a (patch)
tree063118fd6e63aab004680be7a87e1a7670fe4a09 /src/check_builtin.cpp
parent1945218f6df814ea95233035d0b51585e2522b2e (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.cpp46
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 = {};