commit cd1031f472022d176d8a00ec00ab6b0d68db2ed7
parent b9d302c027021d4ec9af4749ad49810104e71083
Author: Drew DeVault <sir@cmpwn.com>
Date: Wed, 13 Jan 2021 10:01:23 -0500
Implement call argument variadism
Diffstat:
3 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/src/check.c b/src/check.c
@@ -383,11 +383,11 @@ check_expr_call(struct context *ctx,
struct type_func_param *param = fntype->func.params;
while (param && aarg) {
trenter(TR_CHECK, "arg");
- assert(!aarg->variadic); // TODO
arg = *next = xcalloc(1, sizeof(struct call_argument));
arg->value = xcalloc(1, sizeof(struct expression));
- if (!param->next && fntype->func.variadism == VARIADISM_HARE) {
+ if (!param->next && fntype->func.variadism == VARIADISM_HARE
+ && !aarg->variadic) {
lower_vaargs(ctx, aarg, arg->value,
param->type->array.members);
arg->value = lower_implicit_cast(param->type, arg->value);
diff --git a/src/type_store.c b/src/type_store.c
@@ -58,6 +58,7 @@ type_is_assignable(struct type_store *store,
return true;
}
+ const struct type *to_secondary, *from_secondary;
switch (to->storage) {
case TYPE_STORAGE_I8:
case TYPE_STORAGE_I16:
@@ -130,8 +131,13 @@ type_is_assignable(struct type_store *store,
case TYPE_STORAGE_VOID:
return true;
case TYPE_STORAGE_SLICE:
+ // XXX: This is not quite right
+ to_secondary = type_store_lookup_with_flags(store,
+ to->array.members, to->array.members->flags & ~TYPE_CONST);
+ from_secondary = type_store_lookup_with_flags(store,
+ from->array.members, from->array.members->flags & ~TYPE_CONST);
return from->storage == TYPE_STORAGE_ARRAY
- && to->array.members == from->array.members;
+ && to_secondary == from_secondary;
case TYPE_STORAGE_ARRAY:
return to->array.length == SIZE_UNDEFINED
&& from->array.length != SIZE_UNDEFINED;
diff --git a/tests/09-funcs.ha b/tests/09-funcs.ha
@@ -16,13 +16,19 @@ fn pointers() void = {
assert(x == 3);
};
-fn vaargs(expected: []int, values: int...) void = {
+fn vafn(expected: []int, values: int...) void = {
assert(len(expected) == len(values));
for (let i = 0z; i < len(values); i += 1z) {
assert(expected[i] == values[i]);
};
};
+fn vaargs() void = {
+ vafn([1, 2, 3], 1, 2, 3);
+ let data = [1, 2, 3];
+ vafn(data, data...);
+};
+
let x: int = 42;
@init fn init() void = {
@@ -35,6 +41,6 @@ let x: int = 42;
export fn main() void = {
pointers();
- vaargs([1, 2, 3], 1, 2, 3);
+ vaargs();
assert(x == 1337);
};