Phase 2: load internal SCI namespaces - Add SCI as git submodule at vendor/sci - gensym: symbol generation with prefix+counter - doto macro: (doto obj (method args)...) - defrecord macro: emits positional constructor ->TypeName - name: Clojure core function for keyword/symbol name - Fix multi-arity defn: indexed? check for vector patterns (tuples) - Edamame stubs for parser.cljc deps Internal namespace loading results: interop: 14 bindings (all OK) opts: 16 bindings (all OK — defrecord fixed) parser: 2 bindings (6 failures: utils/new-var, edamame/normalize-opts) analyzer/interpreter: pending (15+ deps each)
141 lines
4.9 KiB
Text
141 lines
4.9 KiB
Text
(use ../src/jolt/evaluator)
|
|
(use ../src/jolt/types)
|
|
(use ../src/jolt/reader)
|
|
(use ../src/jolt/api)
|
|
|
|
(def ctx (init))
|
|
|
|
(defn load-file [ctx path &opt quiet]
|
|
(var s (slurp path))
|
|
(var count 0)
|
|
(var ok 0)
|
|
(var fail 0)
|
|
(var failures @[])
|
|
(while (> (length (string/trim s)) 0)
|
|
(def [form rest] (parse-next s))
|
|
(set s rest)
|
|
(++ count)
|
|
(if (not (nil? form))
|
|
(do
|
|
(when (not quiet) (printf "eval form %d..." count) (flush))
|
|
(if (try
|
|
(do (eval-form ctx @{} form) true)
|
|
([err]
|
|
(when (not quiet) (printf " FAIL: %q\n" err))
|
|
(array/push failures {:form-number count :error (string err)})
|
|
false))
|
|
(do (when (not quiet) (printf " OK\n")) (++ ok))
|
|
(++ fail)))))
|
|
{:ok ok :fail fail :total count :failures failures})
|
|
|
|
(def sci-base "vendor/sci/src/sci")
|
|
|
|
# ============================================================
|
|
# Phase 1: Core SCI files (known-good)
|
|
# ============================================================
|
|
(def core-order @[
|
|
"impl/macros.cljc"
|
|
"impl/protocols.cljc"
|
|
"impl/types.cljc"
|
|
"impl/unrestrict.cljc"
|
|
"impl/vars.cljc"
|
|
"lang.cljc"
|
|
"impl/utils.cljc"
|
|
"impl/namespaces.cljc"
|
|
"core.cljc"
|
|
])
|
|
|
|
# ============================================================
|
|
# Phase 2: Internal namespaces — interop, parser, opts, analyzer, interpreter
|
|
# These need edamame stubs first
|
|
# ============================================================
|
|
|
|
# Create minimal edamame.core namespace for parser/interpreter
|
|
(def edn-ns (ctx-find-ns ctx "edamame.core"))
|
|
(defn edn-eof [] :edamame/eof)
|
|
(defn edn-reader [x] @{:s x :pos 0 :line 1 :col 1})
|
|
(defn edn-parse-string [s & opts] (parse-string s))
|
|
|
|
(def edn-parse-next (fn [& args]
|
|
(def reader (args 0))
|
|
(def s (reader :s))
|
|
(def pos (reader :pos))
|
|
(if (>= pos (length s)) (edn-eof)
|
|
(let [[form new-pos] (read-form 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))))
|
|
|
|
(ns-intern edn-ns "eof" edn-eof)
|
|
(ns-intern edn-ns "normalize-opts" (fn [opts] (if (= true opts) {:all true} (or opts {}))))
|
|
(ns-intern edn-ns "reader" edn-reader)
|
|
(ns-intern edn-ns "parse-string" edn-parse-string)
|
|
(ns-intern edn-ns "parse-string-all" (fn [s & opts] @[(edn-parse-string s)]))
|
|
(ns-intern edn-ns "parse-next" edn-parse-next)
|
|
(ns-intern edn-ns "continue" :edamame/continue)
|
|
|
|
# Create minimal tools.reader namespace
|
|
(def rt-ns (ctx-find-ns ctx "clojure.tools.reader.reader-types"))
|
|
(ns-intern rt-ns "indexing-push-back-reader" (fn [rdr] rdr))
|
|
(ns-intern rt-ns "string-push-back-reader" edn-reader)
|
|
(ns-intern rt-ns "source-logging-reader?" (fn [rdr] false))
|
|
(ns-intern rt-ns "get-line-number" (fn [rdr] (rdr :line)))
|
|
(ns-intern rt-ns "get-column-number" (fn [rdr] (rdr :col)))
|
|
|
|
# ============================================================
|
|
# Phase 3: Load internal SCI namespaces in dependency order
|
|
# ============================================================
|
|
(def internal-order @[
|
|
# interop needs: types, utils, reflector(clj)
|
|
"impl/interop.cljc"
|
|
# opts needs: namespaces, types
|
|
"impl/opts.cljc"
|
|
# parser needs: edamame, tools.reader, interop, types, utils
|
|
"impl/parser.cljc"
|
|
])
|
|
|
|
(var total-ok 0)
|
|
(var total-fail 0)
|
|
(var all-failures @[])
|
|
|
|
# Phase 1: core
|
|
(each file core-order
|
|
(def path (string sci-base "/" file))
|
|
(printf "\n=== Loading %s ===\n" file)
|
|
(def result (load-file ctx path))
|
|
(printf " Result: %d ok, %d fail, %d total\n" (result :ok) (result :fail) (result :total))
|
|
(+= total-ok (result :ok))
|
|
(+= total-fail (result :fail))
|
|
(each f (result :failures)
|
|
(array/push all-failures {:file file :form-number (f :form-number) :error (f :error)})))
|
|
|
|
# Phase 2: internal
|
|
(each file internal-order
|
|
(def path (string sci-base "/" file))
|
|
(printf "\n=== Loading %s (internal) ===\n" file)
|
|
(def result (load-file ctx path))
|
|
(printf " Result: %d ok, %d fail, %d total\n" (result :ok) (result :fail) (result :total))
|
|
(+= total-ok (result :ok))
|
|
(+= total-fail (result :fail))
|
|
(each f (result :failures)
|
|
(array/push all-failures {:file file :form-number (f :form-number) :error (f :error)})))
|
|
|
|
(printf "\n==============================\n")
|
|
(printf "TOTAL: %d ok, %d fail, %d total\n" total-ok total-fail (+ total-ok total-fail))
|
|
(printf "==============================\n")
|
|
|
|
# Check namespace binding counts
|
|
(printf "\n--- Namespace bindings ---\n")
|
|
(each nsn ["sci.impl.interop" "sci.impl.opts" "sci.impl.parser" "sci.impl.analyzer" "sci.impl.interpreter"]
|
|
(def ns (ctx-find-ns ctx nsn))
|
|
(printf "%s: %d bindings\n" nsn (if ns (length (keys (ns-map ns))) 0)))
|
|
|
|
(when (> (length all-failures) 0)
|
|
(printf "\n=== FAILURES ===\n")
|
|
(each f all-failures
|
|
(printf "[%s:%d] %s\n" (f :file) (f :form-number) (f :error))))
|