core: java.time + java.io shims — Selmer renders end to end (jolt-ea7)

Selmer now loads and renders templates on jolt: variables, filters
(upper, date with JVM patterns), if/for tags, nested lookups, HTML
escaping, and render-file with its last-modified template cache.

New src/jolt/javatime.janet provides the java.time surface Selmer's
date filters use (DateTimeFormatter/Instant/ZoneId/LocalDateTime/
FormatStyle/Locale, epoch-ms backed, host-local timezone) plus the
java.io/java.lang/java.net shims its template reader needs
(StringReader, StringBuilder, URL, File/separator, Class/forName).
Everything registers through three new evaluator registries
(class-statics, tagged-methods, class-ctors), so the module is data
plus an install call.

Fixes shaken out along the way, each load-bearing for Selmer and
correct on their own:
- :refer :all silently referred nothing (it iterated the :all keyword)
- ns :import ignored vector specs and didn't share deftype ctor vars
- dot calls on deftype/reify instances never consulted the protocol
  registry, so (.render-node node ctx) failed where (render-node ...)
  worked
- instance? rejected expression type args like (Class/forName "[C")
- char-array didn't accept a string
- io/resource now searches the loader's source roots (the classpath
  analog); io/reader handles char arrays, URLs, readers, and returns
  an in-memory reader with :read-line-fn for file paths
- String .split (regex, JVM trailing-empty semantics), file-path
  methods (.toURI/.toURL/.getPath/.lastModified/.exists)
- System/getProperty (os.name & co), the janet/* bridge now works
  inside env-less fibers, and qualified class names that syntax-quote
  mangles (selmer.util/StringBuilder) fall back to the ctor registry

Spec rows cover the shim surface; test/integration/selmer-test.janet
runs the real Selmer from ~/src/selmer (skips cleanly when absent).
This commit is contained in:
Yogthos 2026-06-10 22:29:53 -04:00
parent 123c58560a
commit d584369dda
9 changed files with 548 additions and 29 deletions

View file

@ -52,8 +52,12 @@
;; instance?: class names don't evaluate to values on jolt, so the type arg is
;; passed quoted to the ctx-capturing checker; the value evaluates normally.
;; A LIST in type position is a class-valued expression (e.g. Selmer's
;; (Class/forName "[C")) — evaluate it instead.
(defmacro instance? [t x]
`(instance-check (quote ~t) ~x))
(if (seq? t)
`(instance-check ~t ~x)
`(instance-check (quote ~t) ~x)))
;; Single-threaded host: evaluate the monitor expr (for its effects, matching
;; Clojure's evaluation order) and the body — no lock to take.