From fc6c630d5d2c2b2b9808622c58ae8c349c1f3269 Mon Sep 17 00:00:00 2001 From: Yogthos Date: Thu, 4 Jun 2026 14:34:53 -0400 Subject: [PATCH] feat: assoc-in/update-in/fnil; fix update to use immutable assoc; fix latent core-assoc table-copy bug (splice of pairs) --- ...jolt.lang.persistent-hash-map.transit.json | 1 + .clj-kondo/.cache/v1/clj/user.transit.json | 1 + .lsp/.cache/db.transit.json | 1 + src/jolt/compiler.janet | 3 ++ src/jolt/core.janet | 36 ++++++++++++++++--- 5 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 .clj-kondo/.cache/v1/clj/jolt.lang.persistent-hash-map.transit.json create mode 100644 .clj-kondo/.cache/v1/clj/user.transit.json create mode 100644 .lsp/.cache/db.transit.json diff --git a/.clj-kondo/.cache/v1/clj/jolt.lang.persistent-hash-map.transit.json b/.clj-kondo/.cache/v1/clj/jolt.lang.persistent-hash-map.transit.json new file mode 100644 index 0000000..e10a83e --- /dev/null +++ b/.clj-kondo/.cache/v1/clj/jolt.lang.persistent-hash-map.transit.json @@ -0,0 +1 @@ +["^ ","~$bucket-count",["^ ","~:row",4,"~:col",1,"~:name","^0","~:ns","~$jolt.lang.persistent-hash-map","~:top-ns","^5","~:type","~:pos-int"],"~$bucket-contains?",["^ ","~:fixed-arities",["~#set",[2]],"~:private",true,"^4","^5","^3","^9","^7","~:fn","^2",1,"^6","^5","^1",71],"~$phm-empty",["^ ","^1",128,"^2",1,"^:",["^;",[1]],"^3","^>","^4","^5","^6","^5","^7","^="],"~$bucket-entries",["^ ","^:",["^;",[1]],"^<",true,"^4","^5","^3","^?","^7","^=","^2",1,"^6","^5","^1",52],"~$bucket-keys",["^ ","^:",["^;",[1]],"^<",true,"^4","^5","^3","^@","^7","^=","^2",1,"^6","^5","^1",59],"~$phm-count",["^ ","^1",125,"^2",1,"^:",["^;",[1]],"^3","^A","^4","^5","^6","^5","^7","^="],"~$copy-buckets",["^ ","^:",["^;",[3]],"^<",true,"^4","^5","^3","^B","^7","^=","^2",1,"^6","^5","^1",88],"~$map?",["^ ","^1",170,"^2",1,"^:",["^;",[1]],"^3","^C","^4","^5","^6","^5","^7","^="],"~$phm-conj",["^ ","^1",167,"^2",1,"^:",["^;",[2]],"^3","^D","^4","^5","^6","^5","^7","^="],"~$phm-dissoc",["^ ","^1",108,"^2",1,"^:",["^;",[2]],"^3","^E","^4","^5","^6","^5","^7","^="],"~$phm-seq",["^ ","^1",131,"^2",1,"^:",["^;",[1]],"^3","^F","^4","^5","^6","^5","^7","^="],"~$bucket-dissoc",["^ ","^:",["^;",[2]],"^<",true,"^4","^5","^3","^G","^7","^=","^2",1,"^6","^5","^1",37],"~$PersistentHashMap",["^ ","^1",6,"^2",1,"^3","^H","^4","^5","^6","^5","~:class",true],"~$phm-assoc",["^ ","^1",97,"^2",1,"^:",["^;",[3]],"^3","^J","^4","^5","^6","^5","^7","^="],"~$phm-from-pairs",["^ ","^:",["^;",[1]],"^<",true,"^4","^5","^3","^K","^7","^=","^2",1,"^6","^5","^1",158],"~$->PersistentHashMap",["^ ","^1",6,"^2",1,"^:",["^;",[3]],"^3","^L","^4","^5","^6","^5"],"~:filename","/Users/yogthos/src/jolt/src/jolt/clojure/lang/persistent_hash_map.clj","~$bucket-vals",["^ ","^:",["^;",[1]],"^<",true,"^4","^5","^3","^N","^7","^=","^2",1,"^6","^5","^1",65],"~$hash-key",["^ ","^:",["^;",[1]],"^<",true,"^4","^5","^3","^O","^7","^=","^2",1,"^6","^5","~:arities",["^ ","~i1",["^ ","~:ret",["^;",["~:number","~:nat-int"]],"~:arglist-str","[k]"]],"^1",10],"~$phm-get",["^ ","^1",79,"^2",1,"^:",["^;",[3,2]],"^3","^U","^4","^5","^6","^5","^7","^="],"~$phm-contains?",["^ ","^1",121,"^2",1,"^:",["^;",[2]],"^3","^V","^4","^5","^6","^5","^P",["^ ","~i2",["^ ","^Q",["^;",["~:boolean"]],"^T","[m k]"]],"^7","^="],"~$hash-map",["^ ","^1",164,"^2",1,"~:varargs-min-arity",0,"^3","^X","^4","^5","^6","^5","^7","^="],"~$phm-keys",["^ ","^1",140,"^2",1,"^:",["^;",[1]],"^3","^Z","^4","^5","^6","^5","^7","^="],"~$bucket-find",["^ ","^:",["^;",[2]],"^<",true,"^4","^5","^3","^[","^7","^=","^2",1,"^6","^5","^1",13],"~$phm-vals",["^ ","^1",149,"^2",1,"^:",["^;",[1]],"^3","^10","^4","^5","^6","^5","^7","^="],"~$bucket-assoc",["^ ","^:",["^;",[3]],"^<",true,"^4","^5","^3","^11","^7","^=","^2",1,"^6","^5","^1",21],"~$EMPTY-PHM",["^ ","^1",8,"^2",1,"^3","^12","^4","^5","^6","^5"]] \ No newline at end of file diff --git a/.clj-kondo/.cache/v1/clj/user.transit.json b/.clj-kondo/.cache/v1/clj/user.transit.json new file mode 100644 index 0000000..f45bc1f --- /dev/null +++ b/.clj-kondo/.cache/v1/clj/user.transit.json @@ -0,0 +1 @@ +["^ ","~$core-map",["^ ","~:row",262,"~:col",1,"~:varargs-min-arity",1,"~:name","^0","~:ns","~$user","~:top-ns",null,"~:type","~:fn"],"~$core-not",["^ ","^1",12,"^2",1,"~:fixed-arities",["~#set",[1]],"^4","^:","^5","^6","^7",null,"~:arities",["^ ","~i1",["^ ","~:ret",["^<",["~:boolean"]],"~:arglist-str","[x]"]],"^8","^9"],"~$core->=",["^ ","^1",98,"^2",1,"^;",["^<",[2]],"^4","^A","^5","^6","^7",null,"^=",["^ ","~i2",["^ ","^>","^?","^@","[a b]"]],"^8","^9"],"~$core-quot",["^ ","^1",70,"^2",1,"^;",["^<",[2]],"^4","^B","^5","^6","^7",null,"^8","^9"],"~$core-sub",["^ ","^;",["^<",[]],"^5","^6","^4","^C","^8","^9","^2",1,"^7",null,"^3",0,"^1",51],"~$core-<=",["^ ","^1",97,"^2",1,"^;",["^<",[2]],"^4","^D","^5","^6","^7",null,"^=",["^ ","~i2",["^ ","^>","^?","^@","[a b]"]],"^8","^9"],"~$core-not=",["^ ","^1",93,"^2",1,"^3",0,"^4","^E","^5","^6","^7",null,"^=",["^ ","~:varargs",["^ ","^>","^?","~:min-arity",0,"^@","[& args]"]],"^8","^9"],"~$core-inc",["^ ","^1",66,"^2",1,"^4","^H","^5","^6","^7",null],"~$core-rem",["^ ","^1",69,"^2",1,"^4","^I","^5","^6","^7",null],"~$core-false?",["^ ","^1",25,"^2",1,"^;",["^<",[1]],"^4","^J","^5","^6","^7",null,"^=",["^ ","~i1",["^ ","^>","^?","^@","[x]"]],"^8","^9"],"~$core-=",["^ ","^1",79,"^2",1,"^3",0,"^4","^K","^5","^6","^7",null,"^8","^9"],"~$core-zipmap",["^ ","^1",250,"^2",1,"^;",["^<",[2]],"^4","^L","^5","^6","^7",null,"^8","^9"],"~$core-dec",["^ ","^1",67,"^2",1,"^4","^M","^5","^6","^7",null],"~$core-zero?",["^ ","^1",28,"^2",1,"^;",["^<",[1]],"^4","^N","^5","^6","^7",null,"^=",["^ ","~i1",["^ ","^>",["^<",["~:nil","^?"]],"^@","[x]"]],"^8","^9"],"~$core-contains?",["^ ","^1",161,"^2",1,"^;",["^<",[2]],"^4","^P","^5","^6","^7",null,"^8","^9"],"~$core-every?",["^ ","^1",40,"^2",1,"^;",["^<",[2]],"^4","^Q","^5","^6","^7",null,"^8","^9"],"~$core-mod",["^ ","^1",68,"^2",1,"^4","^R","^5","^6","^7",null],"~$core-neg?",["^ ","^1",30,"^2",1,"^;",["^<",[1]],"^4","^S","^5","^6","^7",null,"^=",["^ ","~i1",["^ ","^>",["^<",["^O","^?"]],"^@","[x]"]],"^8","^9"],"~$core-vector?",["^ ","^1",19,"^2",1,"^;",["^<",[1]],"^4","^T","^5","^6","^7",null,"^8","^9"],"~$core-coll?",["^ ","^1",22,"^2",1,"^;",["^<",[1]],"^4","^U","^5","^6","^7",null,"^8","^9"],"~$core-count",["^ ","^1",169,"^2",1,"^;",["^<",[1]],"^4","^V","^5","^6","^7",null,"^8","^9"],"~$core-empty?",["^ ","^1",34,"^2",1,"^;",["^<",[1]],"^4","^W","^5","^6","^7",null,"^=",["^ ","~i1",["^ ","^>",["^<",["^?"]],"^@","[coll]"]],"^8","^9"],"~$core-max",["^ ","^1",72,"^2",1,"^3",0,"^4","^X","^5","^6","^7",null,"^8","^9"],"~$core-identical?",["^ ","^1",26,"^2",1,"^;",["^<",[2]],"^4","^Y","^5","^6","^7",null,"^=",["^ ","~i2",["^ ","^>","^?","^@","[a b]"]],"^8","^9"],"~$core-number?",["^ ","^1",15,"^2",1,"^;",["^<",[1]],"^4","^Z","^5","^6","^7",null,"^=",["^ ","~i1",["^ ","^>","^?","^@","[x]"]],"^8","^9"],"~$core-odd?",["^ ","^1",32,"^2",1,"^;",["^<",[1]],"^4","^[","^5","^6","^7",null,"^=",["^ ","~i1",["^ ","^>","^?","^@","[n]"]],"^8","^9"],"~$core->",["^ ","^1",96,"^2",1,"^;",["^<",[2]],"^4","^10","^5","^6","^7",null,"^=",["^ ","~i2",["^ ","^>","^?","^@","[a b]"]],"^8","^9"],"~$core-pos?",["^ ","^1",29,"^2",1,"^;",["^<",[1]],"^4","^11","^5","^6","^7",null,"^=",["^ ","~i1",["^ ","^>",["^<",["^O","^?"]],"^@","[x]"]],"^8","^9"],"~$core-even?",["^ ","^1",31,"^2",1,"^;",["^<",[1]],"^4","^12","^5","^6","^7",null,"^=",["^ ","~i1",["^ ","^>","^?","^@","[n]"]],"^8","^9"],"~$core-get-in",["^ ","^1",151,"^2",1,"^;",["^<",[4]],"^4","^13","^5","^6","^7",null,"^8","^9"],"~$core-conj",["^ ","^1",104,"^2",1,"^3",1,"^4","^14","^5","^6","^7",null,"^8","^9"],"~$core-min",["^ ","^1",73,"^2",1,"^3",0,"^4","^15","^5","^6","^7",null,"^8","^9"],"~:filename","/Users/yogthos/src/jolt/src/jolt/core.janet","~$core-map?",["^ ","^1",20,"^2",1,"^;",["^<",[1]],"^4","^17","^5","^6","^7",null,"^8","^9"],"~$core-keys",["^ ","^1",237,"^2",1,"^;",["^<",[1]],"^4","^18","^5","^6","^7",null,"^8","^9"],"~$core-symbol?",["^ ","^1",18,"^2",1,"^;",["^<",[1]],"^4","^19","^5","^6","^7",null,"^8","^9"],"~$core-merge",["^ ","^1",224,"^2",1,"^3",0,"^4","^1:","^5","^6","^7",null,"^8","^9"],"~$core-assoc",["^ ","^1",127,"^2",1,"^3",1,"^4","^1;","^5","^6","^7",null,"^8","^9"],"~$s",["^ ","^1",241,"^2",20,"^4","~$s","^5","^6","^7",null],"~$core-dissoc",["^ ","^1",134,"^2",1,"^3",1,"^4","^1<","^5","^6","^7",null,"^8","^9"],"~$core-+",["^ ","^;",["^<",[]],"^5","^6","^4","^1=","^8","^9","^2",1,"^7",null,"^=",["^ ","^F",["^ ","^>",["^<",["~:number","~:nat-int"]],"^G",0,"^@","[& args]"]],"^3",0,"^1",49],"~$core-cons",["^ ","^1",189,"^2",1,"^;",["^<",[2]],"^4","^1@","^5","^6","^7",null,"^8","^9"],"~$core-true?",["^ ","^1",24,"^2",1,"^;",["^<",[1]],"^4","^1A","^5","^6","^7",null,"^=",["^ ","~i1",["^ ","^>","^?","^@","[x]"]],"^8","^9"],"~$core-into",["^ ","^1",211,"^2",1,"^;",["^<",[2]],"^4","^1B","^5","^6","^7",null,"^8","^9"],"~$core-seq?",["^ ","^1",21,"^2",1,"^;",["^<",[1]],"^4","^1C","^5","^6","^7",null,"^8","^9"],"~$core-*",["^ ","^;",["^<",[]],"^5","^6","^4","^1D","^8","^9","^2",1,"^7",null,"^=",["^ ","^F",["^ ","^>",["^<",["^1>","~:pos-int"]],"^G",0,"^@","[& args]"]],"^3",0,"^1",57],"~$core-some?",["^ ","^1",13,"^2",1,"^;",["^<",[1]],"^4","^1F","^5","^6","^7",null,"^=",["^ ","~i1",["^ ","^>","^?","^@","[x]"]],"^8","^9"],"~$core-nil?",["^ ","^1",11,"^2",1,"^;",["^<",[1]],"^4","^1G","^5","^6","^7",null,"^=",["^ ","~i1",["^ ","^>","^?","^@","[x]"]],"^8","^9"],"~$core-select-keys",["^ ","^1",243,"^2",1,"^;",["^<",[2]],"^4","^1H","^5","^6","^7",null,"^8","^9"],"~$core-merge-with",["^ ","^1",229,"^2",1,"^3",1,"^4","^1I","^5","^6","^7",null,"^8","^9"],"~$core-rest",["^ ","^1",178,"^2",1,"^;",["^<",[1]],"^4","^1J","^5","^6","^7",null,"^8","^9"],"~$core-<",["^ ","^1",95,"^2",1,"^;",["^<",[2]],"^4","^1K","^5","^6","^7",null,"^=",["^ ","~i2",["^ ","^>","^?","^@","[a b]"]],"^8","^9"],"~$core-keyword?",["^ ","^1",17,"^2",1,"^;",["^<",[1]],"^4","^1L","^5","^6","^7",null,"^=",["^ ","~i1",["^ ","^>","^?","^@","[x]"]],"^8","^9"],"~$core-first",["^ ","^1",174,"^2",1,"^;",["^<",[1]],"^4","^1M","^5","^6","^7",null,"^8","^9"],"~$core-seq",["^ ","^1",196,"^2",1,"^;",["^<",[1]],"^4","^1N","^5","^6","^7",null,"^8","^9"],"~$core-get",["^ ","^1",140,"^2",1,"^;",["^<",[4]],"^4","^1O","^5","^6","^7",null,"^8","^9"],"~$core-fn?",["^ ","^1",16,"^2",1,"^;",["^<",[1]],"^4","^1P","^5","^6","^7",null,"^8","^9"],"~$core-next",["^ ","^1",185,"^2",1,"^;",["^<",[1]],"^4","^1Q","^5","^6","^7",null,"^8","^9"],"~$core-vals",["^ ","^1",240,"^2",1,"^;",["^<",[1]],"^4","^1R","^5","^6","^7",null,"^8","^9"],"~$core-vec",["^ ","^1",205,"^2",1,"^;",["^<",[1]],"^4","^1S","^5","^6","^7",null,"^8","^9"],"~$core-string?",["^ ","^1",14,"^2",1,"^;",["^<",[1]],"^4","^1T","^5","^6","^7",null,"^=",["^ ","~i1",["^ ","^>","^?","^@","[x]"]],"^8","^9"]] \ No newline at end of file diff --git a/.lsp/.cache/db.transit.json b/.lsp/.cache/db.transit.json new file mode 100644 index 0000000..48e5620 --- /dev/null +++ b/.lsp/.cache/db.transit.json @@ -0,0 +1 @@ +["^ ","~:classpath",["~#set",[]],"~:project-hash","","~:project-root","/Users/yogthos/src/jolt","~:settings-hash","99914b932bd37a50b983c5e7c90ae93b","~:kondo-config-hash","a5ffe1b0410baf2fa8f60d5a7fcf416d8516c8422ab9d3ed5b4f53e9bb3ddf3f","~:dependency-scheme","zipfile","~:analysis",null,"~:analysis-checksums",["^ "],"~:project-analysis-type","~:project-and-full-dependencies","~:version",13,"~:stubs-generation-namespaces",["^1",[]]] \ No newline at end of file diff --git a/src/jolt/compiler.janet b/src/jolt/compiler.janet index 1ebbe9f..72e75df 100644 --- a/src/jolt/compiler.janet +++ b/src/jolt/compiler.janet @@ -41,6 +41,9 @@ "dissoc" "core-dissoc" "get" "core-get" "get-in" "core-get-in" + "assoc-in" "core-assoc-in" + "update-in" "core-update-in" + "fnil" "core-fnil" "contains?" "core-contains?" "count" "core-count" "empty?" "core-empty?" diff --git a/src/jolt/core.janet b/src/jolt/core.janet index 056f092..084662a 100644 --- a/src/jolt/core.janet +++ b/src/jolt/core.janet @@ -158,7 +158,7 @@ (defn core-assoc [m & kvs] (if (phm? m) (do (var result m) (var i 0) (while (< i (length kvs)) (set result (phm-assoc result (kvs i) (kvs (+ i 1)))) (+= i 2)) result) - (do (var result @{}) (when m (each k (if (struct? m) (keys m) (keys (table ;(pairs m)))) (put result k (get m k)))) + (do (var result @{}) (when m (each k (keys m) (put result k (get m k)))) (var i 0) (while (< i (length kvs)) (let [k (kvs i) v (kvs (+ i 1))] (put result k v) (+= i 2))) (if (struct? m) (table/to-struct result) result)))) @@ -1650,9 +1650,34 @@ # update — works on both structs and tables (defn core-update [m k f & args] - (let [current (get m k) - new-val (apply f current args)] - (put m k new-val))) + (core-assoc m k (apply f (core-get m k) args))) + +(defn- ks-rest [ks] + (if (tuple? ks) (tuple/slice ks 1) (array/slice ks 1))) + +(defn core-assoc-in [m ks v] + (let [k (in ks 0)] + (if (<= (length ks) 1) + (core-assoc m k v) + (let [sub (core-get m k)] + (core-assoc m k (core-assoc-in (if (nil? sub) {} sub) (ks-rest ks) v)))))) + +(defn core-update-in [m ks f & args] + (let [k (in ks 0)] + (if (<= (length ks) 1) + (core-assoc m k (apply f (core-get m k) args)) + (let [sub (core-get m k)] + (core-assoc m k (apply core-update-in (if (nil? sub) {} sub) (ks-rest ks) f args)))))) + +(defn core-fnil [f & defaults] + (fn [& args] + (def new-args (array/slice args)) + (var i 0) + (each d defaults + (when (and (< i (length new-args)) (nil? (in new-args i))) + (put new-args i d)) + (++ i)) + (apply f new-args))) # copy-var stubs for sci.impl.copy-vars (used by sci.impl.namespaces) (defn core-copy-core-var [sym] nil) @@ -2025,6 +2050,9 @@ "comment" core-comment "resolve" core-resolve "update" core-update + "update-in" core-update-in + "assoc-in" core-assoc-in + "fnil" core-fnil "copy-core-var" core-copy-core-var "copy-var" core-copy-var "macrofy" core-macrofy