aboutsummaryrefslogtreecommitdiff
path: root/src/check_builtin.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-08-09 19:37:58 +0100
committergingerBill <bill@gingerbill.org>2021-08-09 19:37:58 +0100
commit01f431b01fea18b0844d0475839c68426e95fd2c (patch)
tree7420e056934a923083249fa4863b168877b9855f /src/check_builtin.cpp
parentaebfa4b28e5d92e493010593f4177f53249aa6b2 (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.cpp25
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;
}