Skip to content

Commit f22ceb0

Browse files
gh-132: Fix KEYS handling of mixed key types.
1 parent 3439092 commit f22ceb0

1 file changed

Lines changed: 14 additions & 11 deletions

File tree

src/builtins.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6908,26 +6908,29 @@ static Value builtin_keys(Interpreter* interp, Value* args, int argc, Expr** arg
69086908
size_t shape[1] = {0};
69096909
return value_tns_new(TYPE_INT, 1, shape);
69106910
}
6911-
// determine key type
6912-
ValueType kt = m->items[0].key.type;
6913-
DeclType dt = TYPE_UNKNOWN;
6914-
if (kt == VAL_INT) dt = TYPE_INT;
6915-
else if (kt == VAL_FLT) dt = TYPE_FLT;
6916-
else if (kt == VAL_STR) dt = TYPE_STR;
6917-
else RUNTIME_ERROR(interp, "KEYS: unsupported key type", line, col);
6918-
6911+
// determine element DeclType for keys; allow mixed types (use TYPE_UNKNOWN)
69196912
Value* items = malloc(sizeof(Value) * count);
69206913
if (!items) RUNTIME_ERROR(interp, "Out of memory", line, col);
6914+
6915+
DeclType elem_type = TYPE_UNKNOWN;
69216916
for (size_t i = 0; i < count; i++) {
6922-
if (m->items[i].key.type != kt) {
6917+
ValueType kt = m->items[i].key.type;
6918+
DeclType cur_dt = TYPE_UNKNOWN;
6919+
if (kt == VAL_INT) cur_dt = TYPE_INT;
6920+
else if (kt == VAL_FLT) cur_dt = TYPE_FLT;
6921+
else if (kt == VAL_STR) cur_dt = TYPE_STR;
6922+
else {
69236923
for (size_t j = 0; j < i; j++) value_free(items[j]);
69246924
free(items);
6925-
RUNTIME_ERROR(interp, "KEYS: mixed key types in map", line, col);
6925+
RUNTIME_ERROR(interp, "KEYS: unsupported key type", line, col);
69266926
}
69276927
items[i] = value_copy(m->items[i].key);
6928+
if (i == 0) elem_type = cur_dt;
6929+
else if (elem_type != cur_dt) elem_type = TYPE_UNKNOWN;
69286930
}
6931+
69296932
size_t shape[1] = { count };
6930-
Value out = value_tns_from_values(dt, 1, shape, items, count);
6933+
Value out = value_tns_from_values(elem_type, 1, shape, items, count);
69316934
for (size_t i = 0; i < count; i++) value_free(items[i]);
69326935
free(items);
69336936
return out;

0 commit comments

Comments
 (0)