diff options
| author | gingerBill <bill@gingerbill.org> | 2024-08-24 14:36:18 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2024-08-24 14:36:18 +0100 |
| commit | d0eaf7642dcf38f6f98c50e4daa53d31e2fadd71 (patch) | |
| tree | a6339a1045d65eb90ecc3fd8ffba0dd354c49b44 /src | |
| parent | eb799393d58c6246a1726113694ce3d252752fc5 (diff) | |
Add `intrinsics.type_has_shared_fields`
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_builtin.cpp | 53 | ||||
| -rw-r--r-- | src/checker_builtin_procs.hpp | 3 |
2 files changed, 56 insertions, 0 deletions
diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 1c4b88101..fa03da946 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -5665,6 +5665,59 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As break; } break; + + case BuiltinProc_type_has_shared_fields: + { + Type *u = check_type(c, ce->args[0]); + Type *ut = base_type(u); + if (ut == nullptr || ut == t_invalid) { + error(ce->args[0], "Expected a type for '%.*s'", LIT(builtin_name)); + return false; + } + if (ut->kind != Type_Struct || ut->Struct.soa_kind != StructSoa_None) { + gbString t = type_to_string(ut); + error(ce->args[0], "Expected a struct type for '%.*s', got %s", LIT(builtin_name), t); + gb_string_free(t); + return false; + } + + Type *v = check_type(c, ce->args[1]); + Type *vt = base_type(v); + if (vt == nullptr || vt == t_invalid) { + error(ce->args[1], "Expected a type for '%.*s'", LIT(builtin_name)); + return false; + } + if (vt->kind != Type_Struct || vt->Struct.soa_kind != StructSoa_None) { + gbString t = type_to_string(vt); + error(ce->args[1], "Expected a struct type for '%.*s', got %s", LIT(builtin_name), t); + gb_string_free(t); + return false; + } + + bool is_shared = true; + + for (Entity *v_field : vt->Struct.fields) { + bool found = false; + for (Entity *u_field : ut->Struct.fields) { + if (v_field->token.string == u_field->token.string && + are_types_identical(v_field->type, u_field->type)) { + found = true; + break; + } + } + + if (!found) { + is_shared = false; + break; + } + } + + operand->mode = Addressing_Constant; + operand->value = exact_value_bool(is_shared); + operand->type = t_untyped_bool; + break; + } + case BuiltinProc_type_field_type: { Operand op = {}; diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index ef07938c7..300397be9 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -313,6 +313,8 @@ BuiltinProc__type_simple_boolean_end, BuiltinProc_type_map_info, BuiltinProc_type_map_cell_info, + BuiltinProc_type_has_shared_fields, + BuiltinProc__type_end, BuiltinProc_procedure_of, @@ -647,6 +649,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("type_map_info"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_map_cell_info"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_has_shared_fields"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, |