diff --git a/src/jolt/core.janet b/src/jolt/core.janet index 24fbab0..3584df3 100644 --- a/src/jolt/core.janet +++ b/src/jolt/core.janet @@ -959,4 +959,55 @@ (when (get (core-macro-names) name) (put v :macro true))) ns) - (error "Wrong number of args passed to: init-core!")))) + (error "Wrong number of args passed to: init-core!")))) + +# ============================================================ +# Edamame + tools.reader shim for SCI eval-string +# ============================================================ + +(defn make-string-reader [s] + @{:s s :pos 0 :line 1 :col 1}) + +(defn shim-edamame-eof [] :edamame/eof) + +(defn shim-normalize-opts [opts] + (if (= true opts) + {:all true :row-key :line :col-key :column :read-cond :allow :location? nil} + (if (nil? opts) {} opts))) + +(defn init-edamame-shim! + "Create edamame.core and clojure.tools.reader.reader-types namespaces. + Takes parse-str (string→form) and read-f (string pos→[form pos]) from the host reader." + [ctx parse-str read-f] + (defn edn-parse-string [& args] (parse-str (args 0))) + (defn edn-parse-string-all [& args] @[(parse-str (args 0))]) + (defn edn-parse-next [& args] + (def reader (args 0)) + (def s (reader :s)) + (def pos (reader :pos)) + (if (>= pos (length s)) + (shim-edamame-eof) + (let [[form new-pos] (read-f s pos)] + (put reader :pos new-pos) + (var lp pos) + (while (< lp new-pos) + (if (= (s lp) 10) + (do (put reader :line (+ 1 (reader :line))) + (put reader :col 1)) + (put reader :col (+ 1 (reader :col)))) + (++ lp)) + form))) + (let [edn (ctx-find-ns ctx "edamame.core")] + (ns-intern edn "eof" shim-edamame-eof) + (ns-intern edn "normalize-opts" shim-normalize-opts) + (ns-intern edn "reader" make-string-reader) + (ns-intern edn "parse-string" edn-parse-string) + (ns-intern edn "parse-string-all" edn-parse-string-all) + (ns-intern edn "parse-next" edn-parse-next) + (ns-intern edn "continue" :edamame/continue)) + (let [rt (ctx-find-ns ctx "clojure.tools.reader.reader-types")] + (ns-intern rt "indexing-push-back-reader" identity) + (ns-intern rt "string-push-back-reader" make-string-reader) + (ns-intern rt "source-logging-reader?" (fn [rdr] false)) + (ns-intern rt "get-line-number" (fn [rdr] (rdr :line))) + (ns-intern rt "get-column-number" (fn [rdr] (rdr :col))))) diff --git a/test/test-load-sci.janet b/test/test-load-sci.janet index 06e99e7..9c4b180 100644 --- a/test/test-load-sci.janet +++ b/test/test-load-sci.janet @@ -2,6 +2,7 @@ (use ../src/jolt/types) (use ../src/jolt/reader) (use ../src/jolt/api) +(use ../src/jolt/core) (def ctx (init)) @@ -63,6 +64,33 @@ (printf "TOTAL: %d ok, %d fail, %d total\n" total-ok total-fail (+ total-ok total-fail)) (printf "==============================\n") +# After loading, check what SCI namespaces exist +(printf "\ncurrent ns: %s\n" (ctx-current-ns ctx)) +(printf "sci.core exists: %q\n" (not (nil? (ctx-find-ns ctx "sci.core")))) +(printf "total namespaces: %d\n" (length (keys ((ctx :env) :namespaces)))) + +# Initialize edamame shim (in core.janet) and test eval-string +(init-edamame-shim! ctx parse-string read-form) + +# Check critical SCI namespaces +(printf "\n--- Critical SCI namespaces ---\n") +(def critical-ns ["sci.impl.interpreter" "sci.impl.parser" "sci.impl.analyzer" "sci.impl.opts"]) +(each nsn critical-ns + (def ns (ctx-find-ns ctx nsn)) + (printf "%s: %d bindings\n" nsn (if ns (length (keys (ns-map ns))) 0))) + +(printf "\n--- Testing sci.core/eval-string ---\n") +(def core-ns (ctx-find-ns ctx "sci.core")) +(def ev (ns-find core-ns "eval-string")) +(if ev + (do + (printf "eval-string found, calling...\n") + (flush) + (def f (var-get ev)) + (def result (try (f "(+ 1 2 3)") ([err] (string "ERROR: " err)))) + (printf "eval-string result: %q\n" result)) + (printf "eval-string NOT found\n")) + (when (> (length all-failures) 0) (printf "\n=== FAILURES ===\n") (each f all-failures