1
0
mirror of https://github.com/janet-lang/janet synced 2024-12-01 04:19:55 +00:00

(struct ...) with duped keys will use last value.

This commit is contained in:
Calvin Rose 2020-04-11 12:49:39 -05:00
parent 5ed76f197a
commit 8bc2987a71
4 changed files with 18 additions and 7 deletions

View File

@ -2,6 +2,8 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## Unreleased - ??? ## Unreleased - ???
- A struct/table literal/constructor with duplicate keys will use the last value given.
Previously, this was inconsistent between tables and structs, literals and constructor functions.
- Add debugger to core. The debugger functions are only available - Add debugger to core. The debugger functions are only available
in a debug repl, and are prefixed by a `.`. in a debug repl, and are prefixed by a `.`.
- Add `sort-by` and `sorted-by` to core. - Add `sort-by` and `sorted-by` to core.

View File

@ -437,21 +437,23 @@ static Janet close_array(JanetParser *p, JanetParseState *state) {
static Janet close_struct(JanetParser *p, JanetParseState *state) { static Janet close_struct(JanetParser *p, JanetParseState *state) {
JanetKV *st = janet_struct_begin(state->argn >> 1); JanetKV *st = janet_struct_begin(state->argn >> 1);
for (int32_t i = state->argn; i > 0; i -= 2) { for (size_t i = p->argcount - state->argn; i < p->argcount; i += 2) {
Janet value = p->args[--p->argcount]; Janet key = p->args[i];
Janet key = p->args[--p->argcount]; Janet value = p->args[i + 1];
janet_struct_put(st, key, value); janet_struct_put(st, key, value);
} }
p->argcount -= state->argn;
return janet_wrap_struct(janet_struct_end(st)); return janet_wrap_struct(janet_struct_end(st));
} }
static Janet close_table(JanetParser *p, JanetParseState *state) { static Janet close_table(JanetParser *p, JanetParseState *state) {
JanetTable *table = janet_table(state->argn >> 1); JanetTable *table = janet_table(state->argn >> 1);
for (int32_t i = state->argn; i > 0; i -= 2) { for (size_t i = p->argcount - state->argn; i < p->argcount; i += 2) {
Janet value = p->args[--p->argcount]; Janet key = p->args[i];
Janet key = p->args[--p->argcount]; Janet value = p->args[i + 1];
janet_table_put(table, key, value); janet_table_put(table, key, value);
} }
p->argcount -= state->argn;
return janet_wrap_table(table); return janet_wrap_table(table);
} }

View File

@ -123,7 +123,8 @@ void janet_struct_put(JanetKV *st, Janet key, Janet value) {
dist = otherdist; dist = otherdist;
hash = otherhash; hash = otherhash;
} else if (status == 0) { } else if (status == 0) {
/* A key was added to the struct more than once */ /* A key was added to the struct more than once - replace old value */
kv->value = value;
return; return;
} }
} }

View File

@ -328,5 +328,11 @@
(assert (= true ;(map truthy? [0 "" true @{} {} [] '()])) "truthy values") (assert (= true ;(map truthy? [0 "" true @{} {} [] '()])) "truthy values")
(assert (= false ;(map truthy? [nil false])) "non-truthy values") (assert (= false ;(map truthy? [nil false])) "non-truthy values")
# Struct and Table duplicate elements
(assert (= {:a 3 :b 2} {:a 1 :b 2 :a 3}) "struct literal duplicate keys")
(assert (= {:a 3 :b 2} (struct :a 1 :b 2 :a 3)) "struct constructor duplicate keys")
(assert (deep= @{:a 3 :b 2} @{:a 1 :b 2 :a 3}) "table literal duplicate keys")
(assert (deep= @{:a 3 :b 2} (table :a 1 :b 2 :a 3)) "table constructor duplicate keys")
(end-suite) (end-suite)