diff options
| author | gingerBill <bill@gingerbill.org> | 2021-08-09 19:37:58 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-08-09 19:37:58 +0100 |
| commit | 01f431b01fea18b0844d0475839c68426e95fd2c (patch) | |
| tree | 7420e056934a923083249fa4863b168877b9855f /src/check_builtin.cpp | |
| parent | aebfa4b28e5d92e493010593f4177f53249aa6b2 (diff) | |
Unify semantics of the built-in `swizzle` procedure with the selector expression semantics e.g. `.xyz`
Diffstat (limited to 'src/check_builtin.cpp')
| -rw-r--r-- | src/check_builtin.cpp | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index ea89ec007..c0ba40503 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -778,12 +778,31 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 if (arg_count < max_count) { operand->type = alloc_type_array(elem_type, arg_count); } - operand->mode = Addressing_Value; + if (type->kind == Type_Array) { + if (operand->mode == Addressing_Variable) { + operand->mode = Addressing_SwizzleVariable; + } else { + operand->mode = Addressing_SwizzleValue; + } + } else { + operand->mode = Addressing_Value; + } - if (type_hint != nullptr && check_is_castable_to(c, operand, type_hint)) { - operand->type = type_hint; + Type *array_type = base_type(type_deref(operand->type)); + GB_ASSERT(array_type->kind == Type_Array); + + Type *swizzle_array_type = nullptr; + Type *bth = base_type(type_hint); + if (bth != nullptr && bth->kind == Type_Array && + bth->Array.count == arg_count && + are_types_identical(bth->Array.elem, array_type->Array.elem)) { + swizzle_array_type = type_hint; + } else { + swizzle_array_type = alloc_type_array(array_type->Array.elem, arg_count); } + operand->type = swizzle_array_type; + break; } |