diff --git a/src/boot/boot.janet b/src/boot/boot.janet index 78c009f26..f0b586319 100644 --- a/src/boot/boot.janet +++ b/src/boot/boot.janet @@ -2230,8 +2230,16 @@ (tuple/slice (map freeze x)) (or (= tx :table) (= tx :struct)) - (let [sorted-kvs (array/join @[] ;(sort (map freeze (pairs x))))] - (struct/with-proto (freeze (getproto x)) ;sorted-kvs)) + (let [temp-tab @{}] + # Handle multiple unique keys that freeze. Result should + # be independent of iteration order. + (eachp [k v] x + (def kk (freeze k)) + (def vv (freeze v)) + (def old (get temp-tab kk)) + (def new (if (= nil old) vv (max vv old))) + (put temp-tab kk new)) + (table/to-struct temp-tab (freeze (getproto x)))) (= tx :buffer) (string x) diff --git a/src/core/table.c b/src/core/table.c index 2e82b1ab6..229d8fa30 100644 --- a/src/core/table.c +++ b/src/core/table.c @@ -372,12 +372,14 @@ JANET_CORE_FN(cfun_table_setproto, } JANET_CORE_FN(cfun_table_tostruct, - "(table/to-struct tab)", - "Convert a table to a struct. Returns a new struct. This function " - "does not take into account prototype tables.") { - janet_fixarity(argc, 1); + "(table/to-struct tab &opt proto)", + "Convert a table to a struct. Returns a new struct.") { + janet_arity(argc, 1, 2); JanetTable *t = janet_gettable(argv, 0); - return janet_wrap_struct(janet_table_to_struct(t)); + JanetStruct proto = janet_optstruct(argv, argc, 1, NULL); + JanetStruct st = janet_table_to_struct(t); + janet_struct_proto(st) = proto; + return janet_wrap_struct(st); } JANET_CORE_FN(cfun_table_rawget,