From 5adfb75a2556a1bf2df6190fc41fafcc0e51d949 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Thu, 19 Dec 2024 18:59:53 -0600 Subject: [PATCH] Revert some changes. --- CHANGELOG.md | 4 +++- src/boot/boot.janet | 18 ++++-------------- src/core/struct.c | 11 +++++++++++ test/suite-boot.janet | 12 ++++++------ test/suite-marsh.janet | 8 ++++---- 5 files changed, 28 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13145525..5ac48db1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,9 @@ All notable changes to this project will be documented in this file. ## ??? - Unreleased -- Fix `deep=` and `deep-not=` to better handle degenerate cases with mutable table keys +- Add `struct/rawget` to get values from a struct without a prototype. +- Fix `deep=` and `deep-not=` to better handle degenerate cases with mutable table keys. Keys are now compared by value rather than + structure to avoid degenerate cases. - Long strings will now dedent on `\r\n` instead of just `\n`. - Add `ev/to-file` for synchronous resource operations diff --git a/src/boot/boot.janet b/src/boot/boot.janet index dc16fec4..8d756870 100644 --- a/src/boot/boot.janet +++ b/src/boot/boot.janet @@ -2247,8 +2247,6 @@ :string (buffer ds) ds)) -(def- mutable-types {:table true :array true :buffer true}) - (defn deep-not= ``Like `not=`, but mutable types (arrays, tables, buffers) are considered equal if they have identical structure. Much slower than `not=`.`` @@ -2270,20 +2268,12 @@ (or (= tx :struct) (= tx :table)) (or (not= (length x) (length y)) (do + (def rawget (if (= tx :table) table/rawget struct/rawget)) (var ret false) - (def mut-keys-x @{}) (eachp [k v] x - (if (get mutable-types (type k)) - (let [kk (freeze k)] - (put mut-keys-x kk (put (get mut-keys-x kk @{}) (freeze v) true))) - (if (deep-not= (get y k) v) (break (set ret true))))) - (when (next mut-keys-x) # handle case when we have mutable keys separately - (def mut-keys-y @{}) - (eachp [k v] y - (if (get mutable-types (type k)) - (let [kk (freeze k)] - (put mut-keys-y kk (put (get mut-keys-y kk @{}) (freeze v) true))))) - (set ret (deep-not= mut-keys-x mut-keys-y))) + (def yv (rawget y k)) + (if (= nil yv) (break (set ret true))) + (if (deep-not= yv v) (break (set ret true)))) ret)) (= tx :buffer) (not= 0 (- (length x) (length y)) (memcmp x y)) (not= x y)))) diff --git a/src/core/struct.c b/src/core/struct.c index acc9a921..2e4be627 100644 --- a/src/core/struct.c +++ b/src/core/struct.c @@ -294,6 +294,16 @@ JANET_CORE_FN(cfun_struct_to_table, return janet_wrap_table(tab); } +JANET_CORE_FN(cfun_struct_rawget, + "(struct/rawget st key)", + "Gets a value from a struct `st` without looking at the prototype struct. " + "If `st` does not contain the key directly, the function will return " + "nil without checking the prototype. Returns the value in the struct.") { + janet_fixarity(argc, 2); + JanetStruct st = janet_getstruct(argv, 0); + return janet_struct_rawget(st, argv[1]); +} + /* Load the struct module */ void janet_lib_struct(JanetTable *env) { JanetRegExt struct_cfuns[] = { @@ -301,6 +311,7 @@ void janet_lib_struct(JanetTable *env) { JANET_CORE_REG("struct/getproto", cfun_struct_getproto), JANET_CORE_REG("struct/proto-flatten", cfun_struct_flatten), JANET_CORE_REG("struct/to-table", cfun_struct_to_table), + JANET_CORE_REG("struct/rawget", cfun_struct_rawget), JANET_REG_END }; janet_core_cfuns_ext(env, NULL, struct_cfuns); diff --git a/test/suite-boot.janet b/test/suite-boot.janet index d77611a6..c9c2e26c 100644 --- a/test/suite-boot.janet +++ b/test/suite-boot.janet @@ -997,12 +997,12 @@ # issue #1535 (loop [i :range [1 1000]] - (assert (deep= @{:key1 "value1" @"key" "value2"} - @{:key1 "value1" @"key" "value2"}) "deep= mutable keys")) + (assert (deep-not= @{:key1 "value1" @"key" "value2"} + @{:key1 "value1" @"key" "value2"}) "deep= mutable keys")) (assert (deep-not= {"abc" 123} {@"abc" 123}) "deep= mutable keys vs immutable key") -(assert (deep= {@"" 1 @"" 2 @"" 3} {@"" 1 @"" 2 @"" 3}) "deep= duplicate mutable keys") -(assert (deep= {@"" @"" @"" @"" @"" 3} {@"" @"" @"" @"" @"" 3}) "deep= duplicate mutable keys 2") -(assert (deep= {@[] @"" @[] @"" @[] 3} {@[] @"" @[] @"" @[] 3}) "deep= duplicate mutable keys 3") -(assert (deep= {@{} @"" @{} @"" @{} 3} {@{} @"" @{} @"" @{} 3}) "deep= duplicate mutable keys 4") +(assert (deep-not= {@"" 1 @"" 2 @"" 3} {@"" 1 @"" 2 @"" 3}) "deep= duplicate mutable keys") +(def k1 @"") +(def k2 @"") +(assert (deep= {k1 1 k2 2} {k1 1 k2 2}) "deep= duplicate mutable keys 2") (end-suite) diff --git a/test/suite-marsh.janet b/test/suite-marsh.janet index b9f4d277..90405200 100644 --- a/test/suite-marsh.janet +++ b/test/suite-marsh.janet @@ -168,7 +168,7 @@ neldb\0\0\0\xD8\x05printG\x01\0\xDE\xDE\xDE'\x03\0marshal_tes/\x02 (assert (= 1 (length a)) "array/weak marsh 4") (assert (= nil (get a 0)) "array/weak marsh 5") (assert (= nil (get aclone 0)) "array/weak marsh 6") -(assert (deep= a aclone) "array/weak marsh 7") +(assert (deep= (freeze a) (freeze aclone)) "array/weak marsh 7") # table weak keys and values (def t (table/weak 1)) @@ -196,7 +196,7 @@ neldb\0\0\0\xD8\x05printG\x01\0\xDE\xDE\xDE'\x03\0marshal_tes/\x02 (gccollect) (assert (= 1 (length tclone)) "table/weak-keys marsh 3") (assert (= 1 (length t)) "table/weak-keys marsh 4") -(assert (deep= t tclone) "table/weak-keys marsh 5") +(assert (deep= (freeze t) (freeze tclone)) "table/weak-keys marsh 5") # table weak values (def t (table/weak-values 1)) @@ -207,7 +207,7 @@ neldb\0\0\0\xD8\x05printG\x01\0\xDE\xDE\xDE'\x03\0marshal_tes/\x02 (assert (= 2 (length tclone)) "table/weak-values marsh 2") (gccollect) (assert (= 1 (length t)) "table/weak-value marsh 3") -(assert (deep= t tclone) "table/weak-values marsh 4") +(assert (deep= (freeze t) (freeze tclone)) "table/weak-values marsh 4") # tables with prototypes (def t (table/weak-values 1)) @@ -219,7 +219,7 @@ neldb\0\0\0\xD8\x05printG\x01\0\xDE\xDE\xDE'\x03\0marshal_tes/\x02 (assert (= 2 (length tclone)) "marsh weak tables with prototypes 2") (gccollect) (assert (= 1 (length t)) "marsh weak tables with prototypes 3") -(assert (deep= t tclone) "marsh weak tables with prototypes 4") +(assert (deep= (freeze t) (freeze tclone)) "marsh weak tables with prototypes 4") (assert (deep= (getproto t) (getproto tclone)) "marsh weak tables with prototypes 5") (end-suite)