From 522ff10d62be14f47ae85ecad273419b0c9d87af Mon Sep 17 00:00:00 2001 From: Yogthos Date: Sat, 27 Jun 2026 21:56:04 -0400 Subject: [PATCH] spec.alpha: reify ILookup get, NPE/CCE, quoted #inst/#uuid, anon-fn class, kwargs map MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Close clojure.spec.alpha's remaining gaps — its conform/explain/describe/multi-spec suite (clojure.test-clojure.spec, multi-spec) now passes fully. - (get reify k) / (:k reify) routes to a reify's clojure.lang.ILookup valAt. spec reifies fspec/regex specs as ILookup and reads (:args spec) off them, so before this instrument never saw the args spec. - A failed numeric comparison reports the JVM class: a nil operand is NullPointerException, a non-number is ClassCastException (was an opaque :object condition). conform-explain checks the thrown class. - A quoted / macro-form #inst / #uuid literal constructs its Date/UUID value, like the JVM reader (which builds it at read time). emit-quoted was emitting the raw tagged form, so #inst "1939" and #inst "1939-01-01T00:00:00.000-00:00" weren't =. - An anonymous fn reports class clojure.lang.AFunction$fn (the $fn marker), so spec's fn-sym returns ::s/unknown for it, matching the JVM's ns$fn__N. - A fn with & {:as m} kwargs accepts a trailing map (Clojure 1.11): (f :a 1 {:b 2}) and (f {:a 1}) both bind m, by merging an odd trailing map over the pairs. - A thread responds to .getStackTrace (empty — jolt does TCO). clojure.test-clojure.instr does not fully pass: its ::caller assertions need the calling fn's stack frame, which TCO erases (an inherent host divergence, like the JVM keeping tail frames). make test green (+4 corpus rows, 0 new divergences), shakesmoke byte-identical. Re-mint (backend emit-quoted + the destructure macro). --- host/chez/java/host-class.ss | 11 +++++++---- host/chez/java/io.ss | 5 +++++ host/chez/java/records-interop.ss | 12 ++++++++++++ host/chez/records.ss | 6 ++++++ host/chez/seed/image.ss | 2 +- host/chez/seed/prelude.ss | 2 +- jolt-core/clojure/core/00-syntax.clj | 18 +++++++++--------- jolt-core/jolt/backend_scheme.clj | 8 +++++++- test/chez/corpus.edn | 4 ++++ 9 files changed, 52 insertions(+), 16 deletions(-) diff --git a/host/chez/java/host-class.ss b/host/chez/java/host-class.ss index 1043322..10d8940 100644 --- a/host/chez/java/host-class.ss +++ b/host/chez/java/host-class.ss @@ -35,7 +35,11 @@ ((jolt-atom? x) "clojure.lang.Atom") ((char? x) "java.lang.Character") ((regex-t? x) "java.util.regex.Pattern") - ((procedure? x) "clojure.lang.IFn") + ;; an anonymous / unregistered fn — like the JVM, where (class #(..)) is a + ;; concrete ns$fn__N subclass. The $fn marker lets clojure.spec.alpha's fn-sym + ;; recognize it as anonymous and return ::s/unknown. A named fn is registered + ;; (proc-name-tbl) and handled by a class-arm with its real ns$name. + ((procedure? x) "clojure.lang.AFunction$fn") ;; an exception value (ex-info / host-constructed throwable) reports its JVM ;; class, so (= clojure.lang.ExceptionInfo (class e)) and clojure.test's ;; (thrown? Class …) match (records.ss ex-info-map?/ex-info-class). @@ -59,9 +63,8 @@ ;; (thrown? ArityException …) test match — not the opaque :object fallback. (register-class-arm! (lambda (x) (and (chez-condition-exc-class x) #t)) - (lambda (x) (if (string=? (chez-condition-exc-class x) "ArityException") - "clojure.lang.ArityException" - "java.lang.IllegalArgumentException"))) + (lambda (x) (let ((p (assoc (chez-condition-exc-class x) class-token-alist))) + (if p (cdr p) "java.lang.IllegalArgumentException")))) ;; A fn def'd into a var reports a JVM-style class name "ns$munged-name" (the ;; forward CHAR_MAP), so clojure.spec.alpha's fn-sym (which splits on $ and ;; demunges) recovers the predicate's symbol. Anonymous / unregistered fns stay diff --git a/host/chez/java/io.ss b/host/chez/java/io.ss index f23bcbd..aa3ac33 100644 --- a/host/chez/java/io.ss +++ b/host/chez/java/io.ss @@ -487,6 +487,11 @@ (register-host-methods! "thread" (list (cons "getContextClassLoader" (lambda (self) the-classloader)) (cons "getName" (lambda (self) "main")) + ;; no reified call stack (jolt does TCO, so caller frames are erased) — an + ;; empty StackTraceElement[]. clojure.spec.test.alpha's instrument reads it + ;; to name the caller var; it degrades to no ::caller, the conform error + ;; (the ExceptionInfo) is still thrown. + (cons "getStackTrace" (lambda (self) (jolt-vector))) (cons "interrupt" (lambda (self) (when (box? (jhost-state self)) (set-box! (jhost-state self) #t)) jolt-nil)) diff --git a/host/chez/java/records-interop.ss b/host/chez/java/records-interop.ss index 8b17636..c54d2b2 100644 --- a/host/chez/java/records-interop.ss +++ b/host/chez/java/records-interop.ss @@ -68,6 +68,18 @@ (and (string? m) (cond ((ri-substring? "incorrect number of arguments" m) "ArityException") ((ri-substring? "not seqable" m) "IllegalArgumentException") + ;; Chez's numeric ops raise "~s is not a real number" on a bad + ;; operand. The JVM throws NullPointerException for a nil operand + ;; (null deref) and ClassCastException for a non-number (can't + ;; cast to Number) — clojure.spec.alpha's conform-explain relies + ;; on the distinction. The offending value rides in the irritants. + ((or (ri-substring? "is not a real number" m) + (ri-substring? "is not a number" m)) + (if (and (irritants-condition? v) + (let loop ((xs (condition-irritants v))) + (and (pair? xs) (or (jolt-nil? (car xs)) (loop (cdr xs)))))) + "NullPointerException" + "ClassCastException")) (else #f)))))) ;; instance-check: (type-sym val) — type/protocol membership. Host shims loaded diff --git a/host/chez/records.ss b/host/chez/records.ss index 7be2c04..e306faa 100644 --- a/host/chez/records.ss +++ b/host/chez/records.ss @@ -926,6 +926,12 @@ ;; the protocol short-names it implements (for satisfies?/instance?). (define-record-type jreify (fields methods protos) (nongenerative chez-jreify-v1)) (define (reified-methods obj) (and (jreify? obj) (jreify-methods obj))) +;; (get reify k) / (:k reify) routes to a reify's ILookup valAt — clojure.spec.alpha +;; reifies fspec/regex specs as clojure.lang.ILookup and reads (:args spec) off them. +(register-get-arm! jreify? + (lambda (coll k d) + (let ((m (and (reified-methods coll) (hashtable-ref (reified-methods coll) "valAt" #f)))) + (if m (jolt-invoke m coll k d) d)))) (define (make-reified methods-map . proto-names) (let ((ht (make-hashtable string-hash string=?)) (protos (if (and (pair? proto-names) (null? (cdr proto-names)) (jolt-coll-pred? (car proto-names))) diff --git a/host/chez/seed/image.ss b/host/chez/seed/image.ss index 632f66f..47f2286 100644 --- a/host/chez/seed/image.ss +++ b/host/chez/seed/image.ss @@ -209,7 +209,7 @@ (guard (e (#t #f)) (def-var-with-meta! "jolt.backend-scheme" "emit-quoted-map-value" (letrec ((emit-quoted-map-value (lambda (m) (let fnrec7679 ((m m)) (let* ((pairs (jolt-invoke (var-deref "clojure.core" "sort") (let* ((_a$7685 (lambda (k) (let fnrec7680 ((k k)) (let* ((_a$7681 (var-deref "clojure.core" "str")) (_a$7682 (jolt-invoke (var-deref "jolt.backend-scheme" "emit-quoted") k)) (_a$7683 " ") (_a$7684 (jolt-invoke (var-deref "jolt.backend-scheme" "emit-quoted") (jolt-get m k)))) (jolt-invoke _a$7681 _a$7682 _a$7683 _a$7684))))) (_a$7686 (jolt-keys m))) (jolt-map _a$7685 _a$7686))))) (jolt-invoke (var-deref "clojure.core" "str") "(jolt-hash-map " (jolt-invoke (var-deref "clojure.string" "join") " " pairs) ")")))))) emit-quoted-map-value) (let* ((_o$7687 (keyword #f "private")) (_o$7688 #t)) (jolt-hash-map _o$7687 _o$7688)))) (guard (e (#t #f)) - (def-var-with-meta! "jolt.backend-scheme" "emit-quoted" (letrec ((emit-quoted (lambda (form) (let fnrec7689 ((form form)) (if (jolt-truthy? (jolt-invoke (var-deref "jolt.host" "form-char?") form)) (jolt-invoke (var-deref "jolt.backend-scheme" "emit-const") form) (if (jolt-truthy? (jolt-invoke (var-deref "jolt.host" "form-literal?") form)) (jolt-invoke (var-deref "jolt.backend-scheme" "emit-const") form) (if (jolt-truthy? (jolt-invoke (var-deref "jolt.host" "form-sym?") form)) (let* ((m (jolt-invoke (var-deref "jolt.host" "form-sym-meta") form)) (sns (jolt-invoke (var-deref "jolt.host" "form-sym-ns") form)) (nm (jolt-invoke (var-deref "jolt.host" "form-sym-name") form))) (if (jolt-truthy? (let* ((and__25__auto m)) (if (jolt-truthy? and__25__auto) (jolt-pos? (jolt-count m)) and__25__auto))) (let* ((_a$7690 (var-deref "clojure.core" "str")) (_a$7691 "(jolt-symbol/meta ") (_a$7692 (if (jolt-truthy? sns) (jolt-invoke (var-deref "jolt.backend-scheme" "chez-str-lit") sns) "#f")) (_a$7693 " ") (_a$7694 (jolt-invoke (var-deref "jolt.backend-scheme" "chez-str-lit") nm)) (_a$7695 " ") (_a$7696 (emit-quoted m)) (_a$7697 ")")) (jolt-invoke _a$7690 _a$7691 _a$7692 _a$7693 _a$7694 _a$7695 _a$7696 _a$7697)) (let* ((_a$7698 (var-deref "clojure.core" "str")) (_a$7699 "(jolt-symbol ") (_a$7700 (if (jolt-truthy? sns) (jolt-invoke (var-deref "jolt.backend-scheme" "chez-str-lit") sns) "#f")) (_a$7701 " ") (_a$7702 (jolt-invoke (var-deref "jolt.backend-scheme" "chez-str-lit") nm)) (_a$7703 ")")) (jolt-invoke _a$7698 _a$7699 _a$7700 _a$7701 _a$7702 _a$7703)))) (if (jolt-truthy? (jolt-invoke (var-deref "jolt.host" "form-set?") form)) (jolt-invoke (var-deref "clojure.core" "str") "(jolt-hash-set " (jolt-invoke (var-deref "clojure.string" "join") " " (jolt-invoke (var-deref "clojure.core" "sort") (jolt-map emit-quoted (jolt-invoke (var-deref "jolt.host" "form-set-items") form)))) ")") (if (jolt-truthy? (jolt-invoke (var-deref "jolt.host" "form-list?") form)) (jolt-invoke (var-deref "clojure.core" "str") "(jolt-list " (jolt-invoke (var-deref "clojure.string" "join") " " (jolt-map emit-quoted (jolt-invoke (var-deref "jolt.host" "form-elements") form))) ")") (if (jolt-truthy? (jolt-invoke (var-deref "jolt.host" "form-vec?") form)) (jolt-invoke (var-deref "clojure.core" "str") "(jolt-vector " (jolt-invoke (var-deref "clojure.string" "join") " " (jolt-map emit-quoted (jolt-invoke (var-deref "jolt.host" "form-vec-items") form))) ")") (if (jolt-truthy? (jolt-invoke (var-deref "jolt.host" "form-map?") form)) (jolt-invoke (var-deref "jolt.backend-scheme" "emit-quoted-map") (jolt-invoke (var-deref "jolt.host" "form-map-pairs") form)) (if (jolt-truthy? (jolt-invoke (var-deref "jolt.host" "form-regex?") form)) (jolt-invoke (var-deref "clojure.core" "str") "(jolt-regex " (jolt-invoke (var-deref "jolt.backend-scheme" "chez-str-lit") (jolt-invoke (var-deref "jolt.host" "form-regex-source") form)) ")") (if (jolt-truthy? (jolt-invoke (var-deref "clojure.core" "map?") form)) (jolt-invoke (var-deref "jolt.backend-scheme" "emit-quoted-map-value") form) (if (jolt-truthy? (jolt-invoke (var-deref "clojure.core" "vector?") form)) (jolt-invoke (var-deref "clojure.core" "str") "(jolt-vector " (jolt-invoke (var-deref "clojure.string" "join") " " (jolt-map emit-quoted form)) ")") (if (jolt-truthy? (jolt-invoke (var-deref "clojure.core" "set?") form)) (jolt-invoke (var-deref "clojure.core" "str") "(jolt-hash-set " (jolt-invoke (var-deref "clojure.string" "join") " " (jolt-invoke (var-deref "clojure.core" "sort") (jolt-map emit-quoted form))) ")") (if (jolt-truthy? (jolt-invoke (var-deref "clojure.core" "seq?") form)) (jolt-invoke (var-deref "clojure.core" "str") "(jolt-list " (jolt-invoke (var-deref "clojure.string" "join") " " (jolt-map emit-quoted form)) ")") (if (jolt-truthy? (keyword #f "else")) (jolt-throw (let* ((_a$7704 (jolt-invoke (var-deref "clojure.core" "str") "emit-quoted: unsupported quoted form " (jolt-invoke (var-deref "clojure.core" "pr-str") form))) (_a$7705 (jolt-hash-map))) (jolt-ex-info _a$7704 _a$7705))) jolt-nil))))))))))))))))) emit-quoted) (let* ((_o$7706 (keyword #f "private")) (_o$7707 #t)) (jolt-hash-map _o$7706 _o$7707)))) + (def-var-with-meta! "jolt.backend-scheme" "emit-quoted" (letrec ((emit-quoted (lambda (form) (let fnrec7689 ((form form)) (if (jolt-truthy? (jolt-invoke (var-deref "jolt.host" "form-char?") form)) (jolt-invoke (var-deref "jolt.backend-scheme" "emit-const") form) (if (jolt-truthy? (jolt-invoke (var-deref "jolt.host" "form-literal?") form)) (jolt-invoke (var-deref "jolt.backend-scheme" "emit-const") form) (if (jolt-truthy? (jolt-invoke (var-deref "jolt.host" "form-sym?") form)) (let* ((m (jolt-invoke (var-deref "jolt.host" "form-sym-meta") form)) (sns (jolt-invoke (var-deref "jolt.host" "form-sym-ns") form)) (nm (jolt-invoke (var-deref "jolt.host" "form-sym-name") form))) (if (jolt-truthy? (let* ((and__25__auto m)) (if (jolt-truthy? and__25__auto) (jolt-pos? (jolt-count m)) and__25__auto))) (let* ((_a$7690 (var-deref "clojure.core" "str")) (_a$7691 "(jolt-symbol/meta ") (_a$7692 (if (jolt-truthy? sns) (jolt-invoke (var-deref "jolt.backend-scheme" "chez-str-lit") sns) "#f")) (_a$7693 " ") (_a$7694 (jolt-invoke (var-deref "jolt.backend-scheme" "chez-str-lit") nm)) (_a$7695 " ") (_a$7696 (emit-quoted m)) (_a$7697 ")")) (jolt-invoke _a$7690 _a$7691 _a$7692 _a$7693 _a$7694 _a$7695 _a$7696 _a$7697)) (let* ((_a$7698 (var-deref "clojure.core" "str")) (_a$7699 "(jolt-symbol ") (_a$7700 (if (jolt-truthy? sns) (jolt-invoke (var-deref "jolt.backend-scheme" "chez-str-lit") sns) "#f")) (_a$7701 " ") (_a$7702 (jolt-invoke (var-deref "jolt.backend-scheme" "chez-str-lit") nm)) (_a$7703 ")")) (jolt-invoke _a$7698 _a$7699 _a$7700 _a$7701 _a$7702 _a$7703)))) (if (jolt-truthy? (jolt-invoke (var-deref "jolt.host" "form-set?") form)) (jolt-invoke (var-deref "clojure.core" "str") "(jolt-hash-set " (jolt-invoke (var-deref "clojure.string" "join") " " (jolt-invoke (var-deref "clojure.core" "sort") (jolt-map emit-quoted (jolt-invoke (var-deref "jolt.host" "form-set-items") form)))) ")") (if (jolt-truthy? (jolt-invoke (var-deref "jolt.host" "form-list?") form)) (jolt-invoke (var-deref "clojure.core" "str") "(jolt-list " (jolt-invoke (var-deref "clojure.string" "join") " " (jolt-map emit-quoted (jolt-invoke (var-deref "jolt.host" "form-elements") form))) ")") (if (jolt-truthy? (jolt-invoke (var-deref "jolt.host" "form-vec?") form)) (jolt-invoke (var-deref "clojure.core" "str") "(jolt-vector " (jolt-invoke (var-deref "clojure.string" "join") " " (jolt-map emit-quoted (jolt-invoke (var-deref "jolt.host" "form-vec-items") form))) ")") (if (jolt-truthy? (jolt-invoke (var-deref "jolt.host" "form-map?") form)) (jolt-invoke (var-deref "jolt.backend-scheme" "emit-quoted-map") (jolt-invoke (var-deref "jolt.host" "form-map-pairs") form)) (if (jolt-truthy? (jolt-invoke (var-deref "jolt.host" "form-regex?") form)) (jolt-invoke (var-deref "clojure.core" "str") "(jolt-regex " (jolt-invoke (var-deref "jolt.backend-scheme" "chez-str-lit") (jolt-invoke (var-deref "jolt.host" "form-regex-source") form)) ")") (if (jolt-truthy? (jolt-invoke (var-deref "jolt.host" "form-inst?") form)) (jolt-invoke (var-deref "clojure.core" "str") "(jolt-inst-from-string " (jolt-invoke (var-deref "jolt.backend-scheme" "chez-str-lit") (jolt-invoke (var-deref "jolt.host" "form-inst-source") form)) ")") (if (jolt-truthy? (jolt-invoke (var-deref "jolt.host" "form-uuid?") form)) (jolt-invoke (var-deref "clojure.core" "str") "(jolt-uuid-from-string " (jolt-invoke (var-deref "jolt.backend-scheme" "chez-str-lit") (jolt-invoke (var-deref "jolt.host" "form-uuid-source") form)) ")") (if (jolt-truthy? (jolt-invoke (var-deref "clojure.core" "map?") form)) (jolt-invoke (var-deref "jolt.backend-scheme" "emit-quoted-map-value") form) (if (jolt-truthy? (jolt-invoke (var-deref "clojure.core" "vector?") form)) (jolt-invoke (var-deref "clojure.core" "str") "(jolt-vector " (jolt-invoke (var-deref "clojure.string" "join") " " (jolt-map emit-quoted form)) ")") (if (jolt-truthy? (jolt-invoke (var-deref "clojure.core" "set?") form)) (jolt-invoke (var-deref "clojure.core" "str") "(jolt-hash-set " (jolt-invoke (var-deref "clojure.string" "join") " " (jolt-invoke (var-deref "clojure.core" "sort") (jolt-map emit-quoted form))) ")") (if (jolt-truthy? (jolt-invoke (var-deref "clojure.core" "seq?") form)) (jolt-invoke (var-deref "clojure.core" "str") "(jolt-list " (jolt-invoke (var-deref "clojure.string" "join") " " (jolt-map emit-quoted form)) ")") (if (jolt-truthy? (keyword #f "else")) (jolt-throw (let* ((_a$7704 (jolt-invoke (var-deref "clojure.core" "str") "emit-quoted: unsupported quoted form " (jolt-invoke (var-deref "clojure.core" "pr-str") form))) (_a$7705 (jolt-hash-map))) (jolt-ex-info _a$7704 _a$7705))) jolt-nil))))))))))))))))))) emit-quoted) (let* ((_o$7706 (keyword #f "private")) (_o$7707 #t)) (jolt-hash-map _o$7706 _o$7707)))) (guard (e (#t #f)) (def-var-with-meta! "jolt.backend-scheme" "jmeta-nonempty?" (letrec ((jmeta-nonempty? (lambda (m) (let fnrec7708 ((m m)) (let* ((and__25__auto (jolt-invoke (var-deref "clojure.core" "map?") m))) (if (jolt-truthy? and__25__auto) (jolt-pos? (jolt-count m)) and__25__auto)))))) jmeta-nonempty?) (let* ((_o$7709 (keyword #f "private")) (_o$7710 #t)) (jolt-hash-map _o$7709 _o$7710)))) (guard (e (#t #f)) diff --git a/host/chez/seed/prelude.ss b/host/chez/seed/prelude.ss index 8030cb3..e745fd8 100644 --- a/host/chez/seed/prelude.ss +++ b/host/chez/seed/prelude.ss @@ -51,7 +51,7 @@ (lambda (fnspecs . body) (let fnrec5095 ((fnspecs fnspecs) (body (list->cseq body))) (jolt-cons (jolt-symbol #f "letfn*") (jolt-cons (let* ((_a$5099 (lambda (acc s) (let fnrec5096 ((acc acc) (s s)) (let* ((_a$5097 (jolt-conj acc (jolt-first s))) (_a$5098 (jolt-cons (jolt-symbol #f "fn") s))) (jolt-conj _a$5097 _a$5098))))) (_a$5100 (jolt-vector)) (_a$5101 fnspecs)) (jolt-reduce _a$5099 _a$5100 _a$5101)) body))))) (mark-macro! "clojure.core" "letfn")) (guard (e (#t #f)) - (def-var! "clojure.core" "destructure" (letrec ((destructure (lambda (bindings) (let fnrec5102 ((bindings bindings)) (let* ((find-or (lambda (or-map nm) (let fnrec5103 ((or-map or-map) (nm nm)) (let* ((_a$5109 (lambda (acc k) (let fnrec5104 ((acc acc) (k k)) (if (jolt-truthy? (let* ((and__25__auto (jolt-invoke (var-deref "clojure.core" "symbol?") k))) (if (jolt-truthy? and__25__auto) (jolt= nm (jolt-invoke (var-deref "clojure.core" "name") k)) and__25__auto))) (let* ((_o$5105 #t) (_o$5106 (jolt-get or-map k))) (jolt-vector _o$5105 _o$5106)) acc)))) (_a$5110 (let* ((_o$5107 #f) (_o$5108 jolt-nil)) (jolt-vector _o$5107 _o$5108))) (_a$5111 (if (jolt-truthy? or-map) (jolt-keys or-map) (jolt-vector)))) (jolt-reduce _a$5109 _a$5110 _a$5111))))) (amp? (lambda (x) (let fnrec5112 ((x x)) (let* ((and__25__auto (jolt-invoke (var-deref "clojure.core" "symbol?") x))) (if (jolt-truthy? and__25__auto) (jolt= "&" (jolt-invoke (var-deref "clojure.core" "name") x)) and__25__auto))))) (proc (letrec ((proc (lambda (pat init acc) (let fnrec5113 ((pat pat) (init init) (acc acc)) (if (jolt-truthy? (jolt-invoke (var-deref "clojure.core" "symbol?") pat)) (jolt-conj (jolt-conj acc pat) init) (if (jolt-truthy? (jolt-invoke (var-deref "clojure.core" "vector?") pat)) (let* ((g (jolt-invoke (var-deref "clojure.core" "symbol") (jolt-invoke (var-deref "clojure.core" "str") (jolt-invoke (var-deref "clojure.core" "gensym"))))) (n (jolt-count pat)) (vloop (letrec ((vloop (lambda (i idx a) (let fnrec5114 ((i i) (idx idx) (a a)) (if (< i n) (let* ((elem (jolt-nth pat i))) (if (jolt-truthy? (jolt-invoke amp? elem)) (let* ((_a$5122 (+ i 2)) (_a$5123 idx) (_a$5124 (let* ((_a$5119 (jolt-nth pat (jolt-inc i))) (_a$5120 (let* ((_a$5115 (var-deref "clojure.core" "__sqcat")) (_a$5116 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "nthnext"))) (_a$5117 (jolt-invoke (var-deref "clojure.core" "__sq1") g)) (_a$5118 (jolt-invoke (var-deref "clojure.core" "__sq1") idx))) (jolt-invoke _a$5115 _a$5116 _a$5117 _a$5118))) (_a$5121 a)) (proc _a$5119 _a$5120 _a$5121)))) (vloop _a$5122 _a$5123 _a$5124)) (if (jolt= elem (keyword #f "as")) (let* ((_a$5125 (+ i 2)) (_a$5126 idx) (_a$5127 (proc (jolt-nth pat (jolt-inc i)) g a))) (vloop _a$5125 _a$5126 _a$5127)) (if (jolt-truthy? (keyword #f "else")) (let* ((_a$5133 (jolt-inc i)) (_a$5134 (jolt-inc idx)) (_a$5135 (proc elem (let* ((_a$5128 (var-deref "clojure.core" "__sqcat")) (_a$5129 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "nth"))) (_a$5130 (jolt-invoke (var-deref "clojure.core" "__sq1") g)) (_a$5131 (jolt-invoke (var-deref "clojure.core" "__sq1") idx)) (_a$5132 (jolt-invoke (var-deref "clojure.core" "__sq1") jolt-nil))) (jolt-invoke _a$5128 _a$5129 _a$5130 _a$5131 _a$5132)) a))) (vloop _a$5133 _a$5134 _a$5135)) jolt-nil)))) a))))) vloop))) (jolt-invoke vloop 0 0 (jolt-conj (jolt-conj acc g) init))) (if (jolt-truthy? (jolt-invoke (var-deref "clojure.core" "map?") pat)) (let* ((g (jolt-invoke (var-deref "clojure.core" "symbol") (jolt-invoke (var-deref "clojure.core" "str") (jolt-invoke (var-deref "clojure.core" "gensym"))))) (gm (jolt-invoke (var-deref "clojure.core" "symbol") (jolt-invoke (var-deref "clojure.core" "str") (jolt-invoke (var-deref "clojure.core" "gensym"))))) (coerce (let* ((_a$5168 (var-deref "clojure.core" "__sqcat")) (_a$5169 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol #f "if"))) (_a$5170 (jolt-invoke (var-deref "clojure.core" "__sq1") (let* ((_a$5136 (var-deref "clojure.core" "__sqcat")) (_a$5137 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "sequential?"))) (_a$5138 (jolt-invoke (var-deref "clojure.core" "__sq1") g))) (jolt-invoke _a$5136 _a$5137 _a$5138)))) (_a$5171 (jolt-invoke (var-deref "clojure.core" "__sq1") (let* ((_a$5163 (var-deref "clojure.core" "__sqcat")) (_a$5164 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol #f "if"))) (_a$5165 (jolt-invoke (var-deref "clojure.core" "__sq1") (let* ((_a$5152 (var-deref "clojure.core" "__sqcat")) (_a$5153 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "and"))) (_a$5154 (jolt-invoke (var-deref "clojure.core" "__sq1") (let* ((_a$5142 (var-deref "clojure.core" "__sqcat")) (_a$5143 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "="))) (_a$5144 (jolt-invoke (var-deref "clojure.core" "__sq1") 1)) (_a$5145 (jolt-invoke (var-deref "clojure.core" "__sq1") (let* ((_a$5139 (var-deref "clojure.core" "__sqcat")) (_a$5140 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "count"))) (_a$5141 (jolt-invoke (var-deref "clojure.core" "__sq1") g))) (jolt-invoke _a$5139 _a$5140 _a$5141))))) (jolt-invoke _a$5142 _a$5143 _a$5144 _a$5145)))) (_a$5155 (jolt-invoke (var-deref "clojure.core" "__sq1") (let* ((_a$5149 (var-deref "clojure.core" "__sqcat")) (_a$5150 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "map?"))) (_a$5151 (jolt-invoke (var-deref "clojure.core" "__sq1") (let* ((_a$5146 (var-deref "clojure.core" "__sqcat")) (_a$5147 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "first"))) (_a$5148 (jolt-invoke (var-deref "clojure.core" "__sq1") g))) (jolt-invoke _a$5146 _a$5147 _a$5148))))) (jolt-invoke _a$5149 _a$5150 _a$5151))))) (jolt-invoke _a$5152 _a$5153 _a$5154 _a$5155)))) (_a$5166 (jolt-invoke (var-deref "clojure.core" "__sq1") (let* ((_a$5156 (var-deref "clojure.core" "__sqcat")) (_a$5157 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "first"))) (_a$5158 (jolt-invoke (var-deref "clojure.core" "__sq1") g))) (jolt-invoke _a$5156 _a$5157 _a$5158)))) (_a$5167 (jolt-invoke (var-deref "clojure.core" "__sq1") (let* ((_a$5159 (var-deref "clojure.core" "__sqcat")) (_a$5160 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "apply"))) (_a$5161 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "hash-map"))) (_a$5162 (jolt-invoke (var-deref "clojure.core" "__sq1") g))) (jolt-invoke _a$5159 _a$5160 _a$5161 _a$5162))))) (jolt-invoke _a$5163 _a$5164 _a$5165 _a$5166 _a$5167)))) (_a$5172 (jolt-invoke (var-deref "clojure.core" "__sq1") g))) (jolt-invoke _a$5168 _a$5169 _a$5170 _a$5171 _a$5172))) (or-map (jolt-get pat (keyword #f "or"))) (as-sym (jolt-get pat (keyword #f "as"))) (bound (jolt-conj (jolt-conj (jolt-conj (jolt-conj acc g) init) gm) coerce)) (base (if (jolt-truthy? as-sym) (jolt-conj (jolt-conj bound as-sym) gm) bound)) (group (letrec ((group (lambda (a names kind dnsp) (let fnrec5173 ((a a) (names names) (kind kind) (dnsp dnsp)) (if (jolt-truthy? names) (jolt-reduce (lambda (aa s) (let fnrec5174 ((aa aa) (s s)) (let* ((local (jolt-invoke (var-deref "clojure.core" "name") s)) (nsp (let* ((or__26__auto (jolt-invoke (var-deref "clojure.core" "namespace") s))) (if (jolt-truthy? or__26__auto) or__26__auto dnsp))) (keyform (if (jolt= kind (keyword #f "kw")) (jolt-invoke (var-deref "clojure.core" "keyword") (if (jolt-truthy? nsp) (jolt-invoke (var-deref "clojure.core" "str") nsp "/" local) local)) (if (jolt= kind (keyword #f "str")) local (if (jolt-truthy? (keyword #f "else")) (let* ((_a$5175 (var-deref "clojure.core" "__sqcat")) (_a$5176 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol #f "quote"))) (_a$5177 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-invoke (var-deref "clojure.core" "symbol") nsp local)))) (jolt-invoke _a$5175 _a$5176 _a$5177)) jolt-nil)))) (fo (jolt-invoke find-or or-map local))) (let* ((_a$5187 (jolt-conj aa (jolt-invoke (var-deref "clojure.core" "symbol") local))) (_a$5188 (if (jolt-truthy? (jolt-nth fo 0)) (let* ((_a$5178 (var-deref "clojure.core" "__sqcat")) (_a$5179 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "get"))) (_a$5180 (jolt-invoke (var-deref "clojure.core" "__sq1") gm)) (_a$5181 (jolt-invoke (var-deref "clojure.core" "__sq1") keyform)) (_a$5182 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-nth fo 1)))) (jolt-invoke _a$5178 _a$5179 _a$5180 _a$5181 _a$5182)) (let* ((_a$5183 (var-deref "clojure.core" "__sqcat")) (_a$5184 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "get"))) (_a$5185 (jolt-invoke (var-deref "clojure.core" "__sq1") gm)) (_a$5186 (jolt-invoke (var-deref "clojure.core" "__sq1") keyform))) (jolt-invoke _a$5183 _a$5184 _a$5185 _a$5186))))) (jolt-conj _a$5187 _a$5188))))) a names) a))))) group)) (g1 (jolt-invoke group base (jolt-get pat (keyword #f "keys")) (keyword #f "kw") jolt-nil)) (g2 (jolt-invoke group g1 (jolt-get pat (keyword #f "strs")) (keyword #f "str") jolt-nil)) (g3 (jolt-invoke group g2 (jolt-get pat (keyword #f "syms")) (keyword #f "sym") jolt-nil))) (let* ((_a$5201 (lambda (a k) (let fnrec5189 ((a a) (k k)) (if (jolt-truthy? (jolt-invoke (var-deref "clojure.core" "keyword?") k)) (let* ((kn (jolt-invoke (var-deref "clojure.core" "name") k)) (kns (jolt-invoke (var-deref "clojure.core" "namespace") k))) (if (jolt-truthy? (let* ((and__25__auto kns)) (if (jolt-truthy? and__25__auto) (jolt= kn "keys") and__25__auto))) (jolt-invoke group a (jolt-get pat k) (keyword #f "kw") kns) (if (jolt-truthy? (let* ((and__25__auto kns)) (if (jolt-truthy? and__25__auto) (jolt= kn "strs") and__25__auto))) (jolt-invoke group a (jolt-get pat k) (keyword #f "str") kns) (if (jolt-truthy? (let* ((and__25__auto kns)) (if (jolt-truthy? and__25__auto) (jolt= kn "syms") and__25__auto))) (jolt-invoke group a (jolt-get pat k) (keyword #f "sym") kns) (if (jolt-truthy? (keyword #f "else")) a jolt-nil))))) (let* ((fo (if (jolt-truthy? (jolt-invoke (var-deref "clojure.core" "symbol?") k)) (jolt-invoke find-or or-map (jolt-invoke (var-deref "clojure.core" "name") k)) (let* ((_o$5190 #f) (_o$5191 jolt-nil)) (jolt-vector _o$5190 _o$5191))))) (proc k (if (jolt-truthy? (jolt-nth fo 0)) (let* ((_a$5192 (var-deref "clojure.core" "__sqcat")) (_a$5193 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "get"))) (_a$5194 (jolt-invoke (var-deref "clojure.core" "__sq1") gm)) (_a$5195 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-get pat k))) (_a$5196 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-nth fo 1)))) (jolt-invoke _a$5192 _a$5193 _a$5194 _a$5195 _a$5196)) (let* ((_a$5197 (var-deref "clojure.core" "__sqcat")) (_a$5198 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "get"))) (_a$5199 (jolt-invoke (var-deref "clojure.core" "__sq1") gm)) (_a$5200 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-get pat k)))) (jolt-invoke _a$5197 _a$5198 _a$5199 _a$5200))) a)))))) (_a$5202 g3) (_a$5203 (jolt-keys pat))) (jolt-reduce _a$5201 _a$5202 _a$5203))) (if (jolt-truthy? (keyword #f "else")) (jolt-throw (jolt-invoke (var-deref "clojure.core" "str") "unsupported destructuring pattern: " (jolt-invoke (var-deref "clojure.core" "pr-str") pat))) jolt-nil)))))))) proc)) (ploop (letrec ((ploop (lambda (i acc) (let fnrec5204 ((i i) (acc acc)) (if (< i (jolt-count bindings)) (let* ((_a$5209 (+ i 2)) (_a$5210 (let* ((_a$5205 proc) (_a$5206 (jolt-nth bindings i)) (_a$5207 (jolt-nth bindings (jolt-inc i))) (_a$5208 acc)) (jolt-invoke _a$5205 _a$5206 _a$5207 _a$5208)))) (ploop _a$5209 _a$5210)) acc))))) ploop))) (jolt-invoke ploop 0 (jolt-vector))))))) destructure))) + (def-var! "clojure.core" "destructure" (letrec ((destructure (lambda (bindings) (let fnrec5102 ((bindings bindings)) (let* ((find-or (lambda (or-map nm) (let fnrec5103 ((or-map or-map) (nm nm)) (let* ((_a$5109 (lambda (acc k) (let fnrec5104 ((acc acc) (k k)) (if (jolt-truthy? (let* ((and__25__auto (jolt-invoke (var-deref "clojure.core" "symbol?") k))) (if (jolt-truthy? and__25__auto) (jolt= nm (jolt-invoke (var-deref "clojure.core" "name") k)) and__25__auto))) (let* ((_o$5105 #t) (_o$5106 (jolt-get or-map k))) (jolt-vector _o$5105 _o$5106)) acc)))) (_a$5110 (let* ((_o$5107 #f) (_o$5108 jolt-nil)) (jolt-vector _o$5107 _o$5108))) (_a$5111 (if (jolt-truthy? or-map) (jolt-keys or-map) (jolt-vector)))) (jolt-reduce _a$5109 _a$5110 _a$5111))))) (amp? (lambda (x) (let fnrec5112 ((x x)) (let* ((and__25__auto (jolt-invoke (var-deref "clojure.core" "symbol?") x))) (if (jolt-truthy? and__25__auto) (jolt= "&" (jolt-invoke (var-deref "clojure.core" "name") x)) and__25__auto))))) (proc (letrec ((proc (lambda (pat init acc) (let fnrec5113 ((pat pat) (init init) (acc acc)) (if (jolt-truthy? (jolt-invoke (var-deref "clojure.core" "symbol?") pat)) (jolt-conj (jolt-conj acc pat) init) (if (jolt-truthy? (jolt-invoke (var-deref "clojure.core" "vector?") pat)) (let* ((g (jolt-invoke (var-deref "clojure.core" "symbol") (jolt-invoke (var-deref "clojure.core" "str") (jolt-invoke (var-deref "clojure.core" "gensym"))))) (n (jolt-count pat)) (vloop (letrec ((vloop (lambda (i idx a) (let fnrec5114 ((i i) (idx idx) (a a)) (if (< i n) (let* ((elem (jolt-nth pat i))) (if (jolt-truthy? (jolt-invoke amp? elem)) (let* ((_a$5122 (+ i 2)) (_a$5123 idx) (_a$5124 (let* ((_a$5119 (jolt-nth pat (jolt-inc i))) (_a$5120 (let* ((_a$5115 (var-deref "clojure.core" "__sqcat")) (_a$5116 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "nthnext"))) (_a$5117 (jolt-invoke (var-deref "clojure.core" "__sq1") g)) (_a$5118 (jolt-invoke (var-deref "clojure.core" "__sq1") idx))) (jolt-invoke _a$5115 _a$5116 _a$5117 _a$5118))) (_a$5121 a)) (proc _a$5119 _a$5120 _a$5121)))) (vloop _a$5122 _a$5123 _a$5124)) (if (jolt= elem (keyword #f "as")) (let* ((_a$5125 (+ i 2)) (_a$5126 idx) (_a$5127 (proc (jolt-nth pat (jolt-inc i)) g a))) (vloop _a$5125 _a$5126 _a$5127)) (if (jolt-truthy? (keyword #f "else")) (let* ((_a$5133 (jolt-inc i)) (_a$5134 (jolt-inc idx)) (_a$5135 (proc elem (let* ((_a$5128 (var-deref "clojure.core" "__sqcat")) (_a$5129 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "nth"))) (_a$5130 (jolt-invoke (var-deref "clojure.core" "__sq1") g)) (_a$5131 (jolt-invoke (var-deref "clojure.core" "__sq1") idx)) (_a$5132 (jolt-invoke (var-deref "clojure.core" "__sq1") jolt-nil))) (jolt-invoke _a$5128 _a$5129 _a$5130 _a$5131 _a$5132)) a))) (vloop _a$5133 _a$5134 _a$5135)) jolt-nil)))) a))))) vloop))) (jolt-invoke vloop 0 0 (jolt-conj (jolt-conj acc g) init))) (if (jolt-truthy? (jolt-invoke (var-deref "clojure.core" "map?") pat)) (let* ((g (jolt-invoke (var-deref "clojure.core" "symbol") (jolt-invoke (var-deref "clojure.core" "str") (jolt-invoke (var-deref "clojure.core" "gensym"))))) (gm (jolt-invoke (var-deref "clojure.core" "symbol") (jolt-invoke (var-deref "clojure.core" "str") (jolt-invoke (var-deref "clojure.core" "gensym"))))) (coerce (let* ((_a$5168 (var-deref "clojure.core" "__sqcat")) (_a$5169 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol #f "if"))) (_a$5170 (jolt-invoke (var-deref "clojure.core" "__sq1") (let* ((_a$5136 (var-deref "clojure.core" "__sqcat")) (_a$5137 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "sequential?"))) (_a$5138 (jolt-invoke (var-deref "clojure.core" "__sq1") g))) (jolt-invoke _a$5136 _a$5137 _a$5138)))) (_a$5171 (jolt-invoke (var-deref "clojure.core" "__sq1") (let* ((_a$5163 (var-deref "clojure.core" "__sqcat")) (_a$5164 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol #f "if"))) (_a$5165 (jolt-invoke (var-deref "clojure.core" "__sq1") (let* ((_a$5142 (var-deref "clojure.core" "__sqcat")) (_a$5143 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "odd?"))) (_a$5144 (jolt-invoke (var-deref "clojure.core" "__sq1") (let* ((_a$5139 (var-deref "clojure.core" "__sqcat")) (_a$5140 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "count"))) (_a$5141 (jolt-invoke (var-deref "clojure.core" "__sq1") g))) (jolt-invoke _a$5139 _a$5140 _a$5141))))) (jolt-invoke _a$5142 _a$5143 _a$5144)))) (_a$5166 (jolt-invoke (var-deref "clojure.core" "__sq1") (let* ((_a$5155 (var-deref "clojure.core" "__sqcat")) (_a$5156 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "merge"))) (_a$5157 (jolt-invoke (var-deref "clojure.core" "__sq1") (let* ((_a$5148 (var-deref "clojure.core" "__sqcat")) (_a$5149 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "apply"))) (_a$5150 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "hash-map"))) (_a$5151 (jolt-invoke (var-deref "clojure.core" "__sq1") (let* ((_a$5145 (var-deref "clojure.core" "__sqcat")) (_a$5146 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "butlast"))) (_a$5147 (jolt-invoke (var-deref "clojure.core" "__sq1") g))) (jolt-invoke _a$5145 _a$5146 _a$5147))))) (jolt-invoke _a$5148 _a$5149 _a$5150 _a$5151)))) (_a$5158 (jolt-invoke (var-deref "clojure.core" "__sq1") (let* ((_a$5152 (var-deref "clojure.core" "__sqcat")) (_a$5153 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "last"))) (_a$5154 (jolt-invoke (var-deref "clojure.core" "__sq1") g))) (jolt-invoke _a$5152 _a$5153 _a$5154))))) (jolt-invoke _a$5155 _a$5156 _a$5157 _a$5158)))) (_a$5167 (jolt-invoke (var-deref "clojure.core" "__sq1") (let* ((_a$5159 (var-deref "clojure.core" "__sqcat")) (_a$5160 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "apply"))) (_a$5161 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "hash-map"))) (_a$5162 (jolt-invoke (var-deref "clojure.core" "__sq1") g))) (jolt-invoke _a$5159 _a$5160 _a$5161 _a$5162))))) (jolt-invoke _a$5163 _a$5164 _a$5165 _a$5166 _a$5167)))) (_a$5172 (jolt-invoke (var-deref "clojure.core" "__sq1") g))) (jolt-invoke _a$5168 _a$5169 _a$5170 _a$5171 _a$5172))) (or-map (jolt-get pat (keyword #f "or"))) (as-sym (jolt-get pat (keyword #f "as"))) (bound (jolt-conj (jolt-conj (jolt-conj (jolt-conj acc g) init) gm) coerce)) (base (if (jolt-truthy? as-sym) (jolt-conj (jolt-conj bound as-sym) gm) bound)) (group (letrec ((group (lambda (a names kind dnsp) (let fnrec5173 ((a a) (names names) (kind kind) (dnsp dnsp)) (if (jolt-truthy? names) (jolt-reduce (lambda (aa s) (let fnrec5174 ((aa aa) (s s)) (let* ((local (jolt-invoke (var-deref "clojure.core" "name") s)) (nsp (let* ((or__26__auto (jolt-invoke (var-deref "clojure.core" "namespace") s))) (if (jolt-truthy? or__26__auto) or__26__auto dnsp))) (keyform (if (jolt= kind (keyword #f "kw")) (jolt-invoke (var-deref "clojure.core" "keyword") (if (jolt-truthy? nsp) (jolt-invoke (var-deref "clojure.core" "str") nsp "/" local) local)) (if (jolt= kind (keyword #f "str")) local (if (jolt-truthy? (keyword #f "else")) (let* ((_a$5175 (var-deref "clojure.core" "__sqcat")) (_a$5176 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol #f "quote"))) (_a$5177 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-invoke (var-deref "clojure.core" "symbol") nsp local)))) (jolt-invoke _a$5175 _a$5176 _a$5177)) jolt-nil)))) (fo (jolt-invoke find-or or-map local))) (let* ((_a$5187 (jolt-conj aa (jolt-invoke (var-deref "clojure.core" "symbol") local))) (_a$5188 (if (jolt-truthy? (jolt-nth fo 0)) (let* ((_a$5178 (var-deref "clojure.core" "__sqcat")) (_a$5179 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "get"))) (_a$5180 (jolt-invoke (var-deref "clojure.core" "__sq1") gm)) (_a$5181 (jolt-invoke (var-deref "clojure.core" "__sq1") keyform)) (_a$5182 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-nth fo 1)))) (jolt-invoke _a$5178 _a$5179 _a$5180 _a$5181 _a$5182)) (let* ((_a$5183 (var-deref "clojure.core" "__sqcat")) (_a$5184 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "get"))) (_a$5185 (jolt-invoke (var-deref "clojure.core" "__sq1") gm)) (_a$5186 (jolt-invoke (var-deref "clojure.core" "__sq1") keyform))) (jolt-invoke _a$5183 _a$5184 _a$5185 _a$5186))))) (jolt-conj _a$5187 _a$5188))))) a names) a))))) group)) (g1 (jolt-invoke group base (jolt-get pat (keyword #f "keys")) (keyword #f "kw") jolt-nil)) (g2 (jolt-invoke group g1 (jolt-get pat (keyword #f "strs")) (keyword #f "str") jolt-nil)) (g3 (jolt-invoke group g2 (jolt-get pat (keyword #f "syms")) (keyword #f "sym") jolt-nil))) (let* ((_a$5201 (lambda (a k) (let fnrec5189 ((a a) (k k)) (if (jolt-truthy? (jolt-invoke (var-deref "clojure.core" "keyword?") k)) (let* ((kn (jolt-invoke (var-deref "clojure.core" "name") k)) (kns (jolt-invoke (var-deref "clojure.core" "namespace") k))) (if (jolt-truthy? (let* ((and__25__auto kns)) (if (jolt-truthy? and__25__auto) (jolt= kn "keys") and__25__auto))) (jolt-invoke group a (jolt-get pat k) (keyword #f "kw") kns) (if (jolt-truthy? (let* ((and__25__auto kns)) (if (jolt-truthy? and__25__auto) (jolt= kn "strs") and__25__auto))) (jolt-invoke group a (jolt-get pat k) (keyword #f "str") kns) (if (jolt-truthy? (let* ((and__25__auto kns)) (if (jolt-truthy? and__25__auto) (jolt= kn "syms") and__25__auto))) (jolt-invoke group a (jolt-get pat k) (keyword #f "sym") kns) (if (jolt-truthy? (keyword #f "else")) a jolt-nil))))) (let* ((fo (if (jolt-truthy? (jolt-invoke (var-deref "clojure.core" "symbol?") k)) (jolt-invoke find-or or-map (jolt-invoke (var-deref "clojure.core" "name") k)) (let* ((_o$5190 #f) (_o$5191 jolt-nil)) (jolt-vector _o$5190 _o$5191))))) (proc k (if (jolt-truthy? (jolt-nth fo 0)) (let* ((_a$5192 (var-deref "clojure.core" "__sqcat")) (_a$5193 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "get"))) (_a$5194 (jolt-invoke (var-deref "clojure.core" "__sq1") gm)) (_a$5195 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-get pat k))) (_a$5196 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-nth fo 1)))) (jolt-invoke _a$5192 _a$5193 _a$5194 _a$5195 _a$5196)) (let* ((_a$5197 (var-deref "clojure.core" "__sqcat")) (_a$5198 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol "clojure.core" "get"))) (_a$5199 (jolt-invoke (var-deref "clojure.core" "__sq1") gm)) (_a$5200 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-get pat k)))) (jolt-invoke _a$5197 _a$5198 _a$5199 _a$5200))) a)))))) (_a$5202 g3) (_a$5203 (jolt-keys pat))) (jolt-reduce _a$5201 _a$5202 _a$5203))) (if (jolt-truthy? (keyword #f "else")) (jolt-throw (jolt-invoke (var-deref "clojure.core" "str") "unsupported destructuring pattern: " (jolt-invoke (var-deref "clojure.core" "pr-str") pat))) jolt-nil)))))))) proc)) (ploop (letrec ((ploop (lambda (i acc) (let fnrec5204 ((i i) (acc acc)) (if (< i (jolt-count bindings)) (let* ((_a$5209 (+ i 2)) (_a$5210 (let* ((_a$5205 proc) (_a$5206 (jolt-nth bindings i)) (_a$5207 (jolt-nth bindings (jolt-inc i))) (_a$5208 acc)) (jolt-invoke _a$5205 _a$5206 _a$5207 _a$5208)))) (ploop _a$5209 _a$5210)) acc))))) ploop))) (jolt-invoke ploop 0 (jolt-vector))))))) destructure))) (guard (e (#t #f)) (def-var! "clojure.core" "let" (lambda (bindings . body) (let fnrec5211 ((bindings bindings) (body (list->cseq body))) (let* ((_a$5212 (var-deref "clojure.core" "__sqcat")) (_a$5213 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-symbol #f "let*"))) (_a$5214 (jolt-invoke (var-deref "clojure.core" "__sq1") (jolt-invoke (var-deref "clojure.core" "__sqvec") (jolt-invoke (var-deref "clojure.core" "destructure") bindings)))) (_a$5215 body)) (jolt-invoke _a$5212 _a$5213 _a$5214 _a$5215))))) diff --git a/jolt-core/clojure/core/00-syntax.clj b/jolt-core/clojure/core/00-syntax.clj index 6f14559..8f9f8a1 100644 --- a/jolt-core/clojure/core/00-syntax.clj +++ b/jolt-core/clojure/core/00-syntax.clj @@ -212,16 +212,16 @@ (let* [g (symbol (str (gensym))) gm (symbol (str (gensym))) ;; kwargs: a map pattern may bind against the sequential rest - ;; of a fn — (& {:keys [...]}) — which is a seq of alternating - ;; k/v args, or a single trailing map. Coerce like Clojure (and - ;; like the interpreter's destructure-bind, so interpret/compile - ;; agree): a sequential value with one map element is that map, - ;; otherwise (apply hash-map). A real map value is used as-is, so - ;; ordinary map destructuring is unaffected. g holds init once; - ;; gm is the coerced map every lookup (and :as) reads from. + ;; of a fn — (& {:keys [...]}) — a seq of alternating k/v args, + ;; optionally with a trailing map (Clojure 1.11: (f :a 1 {:b 2}) + ;; merges the map over the pairs; (f {:a 1}) is just the map). + ;; An odd count means the last arg is that trailing map. A real + ;; map value is used as-is, so ordinary map destructuring is + ;; unaffected. g holds init once; gm is the coerced map every + ;; lookup (and :as) reads from. coerce `(if (sequential? ~g) - (if (and (= 1 (count ~g)) (map? (first ~g))) - (first ~g) + (if (odd? (count ~g)) + (merge (apply hash-map (butlast ~g)) (last ~g)) (apply hash-map ~g)) ~g) or-map (get pat :or) diff --git a/jolt-core/jolt/backend_scheme.clj b/jolt-core/jolt/backend_scheme.clj index b3d6fc8..4a86238 100644 --- a/jolt-core/jolt/backend_scheme.clj +++ b/jolt-core/jolt/backend_scheme.clj @@ -12,7 +12,8 @@ form-list? form-vec? form-map? form-set? form-char? form-literal? form-elements form-vec-items form-map-pairs form-set-items form-char-code - form-regex? form-regex-source]])) + form-regex? form-regex-source + form-inst? form-inst-source form-uuid? form-uuid-source]])) ;; Hot clojure.core primitives lowered to native Scheme. ;; `=` is the exactness-aware jolt= from values.ss; inc/dec/ @@ -335,6 +336,11 @@ (form-map? form) (emit-quoted-map (form-map-pairs form)) ;; a quoted #"…" regex value -> reconstruct it (same as the :regex IR leaf). (form-regex? form) (str "(jolt-regex " (chez-str-lit (form-regex-source form)) ")") + ;; quoted #inst / #uuid literals construct their value, like the JVM reader + ;; (which builds the Date/UUID at read time, so a quoted/macro form carries the + ;; value, not the raw tagged form). Same emit as the :inst / :uuid IR leaves. + (form-inst? form) (str "(jolt-inst-from-string " (chez-str-lit (form-inst-source form)) ")") + (form-uuid? form) (str "(jolt-uuid-from-string " (chez-str-lit (form-uuid-source form)) ")") ;; plain jolt VALUES (metadata maps and anything nested in them) (map? form) (emit-quoted-map-value form) (vector? form) (str "(jolt-vector " (str/join " " (map emit-quoted form)) ")") diff --git a/test/chez/corpus.edn b/test/chez/corpus.edn index 190a9be..c1524b6 100644 --- a/test/chez/corpus.edn +++ b/test/chez/corpus.edn @@ -1,4 +1,8 @@ [ + {:suite "host-interop / reify ILookup" :label "(get reify k) / (:k reify) / (get reify k d) route to valAt" :expected "[1 1 :dflt]" :actual "(let [r (reify clojure.lang.ILookup (valAt [_ k] (get {:a 1} k)) (valAt [_ k d] (get {:a 1} k d)))] [(:a r) (get r :a) (get r :z :dflt)])"} + {:suite "numbers / comparison error class" :label "nil operand is NPE, non-number is CCE" :expected "[\"java.lang.NullPointerException\" \"java.lang.ClassCastException\"]" :actual "[(try (> nil 5) (catch Throwable e (.getName (class e)))) (try (> :k 5) (catch Throwable e (.getName (class e))))]"} + {:suite "reader / quoted #inst constructs a value" :label "a quoted #inst literal is the constructed Date, not a tagged form" :expected "\"(f #inst \\\"1939-01-01T00:00:00.000-00:00\\\")\"" :actual "(pr-str (quote (f #inst \"1939\")))"} + {:suite "fn / kwargs trailing map" :label "(f :k v {map}) and (f {map}) both bind & {:as m}" :expected "[{:x 1 :y 2} {:x 1 :y 2}]" :actual "[((fn [a & {:as m}] m) 1 :x 1 {:y 2}) ((fn [a & {:as m}] m) 1 {:x 1 :y 2})]"} {:suite "destructure / :or" :label "map default when key absent" :expected "9" :actual "(let [{x :x :or {x 9}} {}] x)"} {:suite "destructure / :or" :label "kwargs default when key absent" :expected "9" :actual "((fn [& {x :x :or {x 9}}] x))"} {:suite "destructure / :or" :label "default not used when key present" :expected "5" :actual "(let [{x :x :or {x 9}} {:x 5}] x)"}