Skip to content

Commit 1b49934

Browse files
committed
Allow table/to-struct to take a prototype.
Use this prototype struct in freeze.
1 parent 682f0f5 commit 1b49934

File tree

2 files changed

+17
-7
lines changed

2 files changed

+17
-7
lines changed

src/boot/boot.janet

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2230,8 +2230,16 @@
22302230
(tuple/slice (map freeze x))
22312231

22322232
(or (= tx :table) (= tx :struct))
2233-
(let [sorted-kvs (array/join @[] ;(sort (map freeze (pairs x))))]
2234-
(struct/with-proto (freeze (getproto x)) ;sorted-kvs))
2233+
(let [temp-tab @{}]
2234+
# Handle multiple unique keys that freeze. Result should
2235+
# be independent of iteration order.
2236+
(eachp [k v] x
2237+
(def kk (freeze k))
2238+
(def vv (freeze v))
2239+
(def old (get temp-tab kk))
2240+
(def new (if (= nil old) vv (max vv old)))
2241+
(put temp-tab kk new))
2242+
(table/to-struct temp-tab (freeze (getproto x))))
22352243

22362244
(= tx :buffer)
22372245
(string x)

src/core/table.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -372,12 +372,14 @@ JANET_CORE_FN(cfun_table_setproto,
372372
}
373373

374374
JANET_CORE_FN(cfun_table_tostruct,
375-
"(table/to-struct tab)",
376-
"Convert a table to a struct. Returns a new struct. This function "
377-
"does not take into account prototype tables.") {
378-
janet_fixarity(argc, 1);
375+
"(table/to-struct tab &opt proto)",
376+
"Convert a table to a struct. Returns a new struct.") {
377+
janet_arity(argc, 1, 2);
379378
JanetTable *t = janet_gettable(argv, 0);
380-
return janet_wrap_struct(janet_table_to_struct(t));
379+
JanetStruct proto = janet_optstruct(argv, argc, 1, NULL);
380+
JanetStruct st = janet_table_to_struct(t);
381+
janet_struct_proto(st) = proto;
382+
return janet_wrap_struct(st);
381383
}
382384

383385
JANET_CORE_FN(cfun_table_rawget,

0 commit comments

Comments
 (0)