diff --git a/lib/hyperscript/compiler.sx b/lib/hyperscript/compiler.sx index ec9a784e..f3c227da 100644 --- a/lib/hyperscript/compiler.sx +++ b/lib/hyperscript/compiler.sx @@ -7,6 +7,22 @@ ;; (hs-to-sx (hs-compile "on click add .active to me")) ;; → (hs-on me "click" (fn (event) (dom-add-class me "active"))) +;; ── Compiler plugin registries ──────────────────────────────────── +;; Plugins call (hs-register-command! "head" compile-fn) and +;; (hs-register-converter! "TypeName" convert-fn) at load time. Both +;; compile-fn and convert-fn receive a ctx dict (built per call inside +;; hs-to-sx) exposing :hs-to-sx for recursion plus the AST node fields +;; the dispatch needs. Compile-fn returns an SX expression. +(begin + (define _hs-command-registry {}) + (define _hs-converter-registry {}) + (define + hs-register-command! + (fn (name compile-fn) (dict-set! _hs-command-registry name compile-fn))) + (define + hs-register-converter! + (fn (name convert-fn) (dict-set! _hs-converter-registry name convert-fn)))) + (define hs-to-sx (let @@ -952,6 +968,22 @@ (true (let ((head (first ast))) + (let + ((reg-cmd-fn (dict-get _hs-command-registry (str head))) + (reg-conv-fn + (and + (= head (quote as)) + (dict-get _hs-converter-registry (nth ast 2))))) + (cond + (reg-conv-fn + (reg-conv-fn + {:hs-to-sx hs-to-sx + :ast ast + :value-ast (nth ast 1) + :type-name (nth ast 2)})) + (reg-cmd-fn + (reg-cmd-fn {:hs-to-sx hs-to-sx :ast ast :head head})) + (true (cond ((= head (quote __bind-from-detail__)) (let @@ -2667,7 +2699,7 @@ (quote begin) (list (quote set!) (quote it) (quote __hs-js)) (quote __hs-js)))))) - (true ast))))))))) + (true ast)))))))))))) ;; ── Convenience: source → SX ───────────────────────────────── (define diff --git a/shared/static/wasm/sx/hs-compiler.sx b/shared/static/wasm/sx/hs-compiler.sx index 07c4d91c..f3c227da 100644 --- a/shared/static/wasm/sx/hs-compiler.sx +++ b/shared/static/wasm/sx/hs-compiler.sx @@ -7,6 +7,22 @@ ;; (hs-to-sx (hs-compile "on click add .active to me")) ;; → (hs-on me "click" (fn (event) (dom-add-class me "active"))) +;; ── Compiler plugin registries ──────────────────────────────────── +;; Plugins call (hs-register-command! "head" compile-fn) and +;; (hs-register-converter! "TypeName" convert-fn) at load time. Both +;; compile-fn and convert-fn receive a ctx dict (built per call inside +;; hs-to-sx) exposing :hs-to-sx for recursion plus the AST node fields +;; the dispatch needs. Compile-fn returns an SX expression. +(begin + (define _hs-command-registry {}) + (define _hs-converter-registry {}) + (define + hs-register-command! + (fn (name compile-fn) (dict-set! _hs-command-registry name compile-fn))) + (define + hs-register-converter! + (fn (name convert-fn) (dict-set! _hs-converter-registry name convert-fn)))) + (define hs-to-sx (let @@ -48,6 +64,15 @@ prop value)) (list (quote hs-query-all) (nth base-ast 1)))) + ((and (list? base-ast) (= (first base-ast) (quote query))) + (list + (quote dom-set-prop) + (list + (quote hs-named-target) + (nth base-ast 1) + (list (quote hs-query-first) (nth base-ast 1))) + prop + value)) ((and (list? base-ast) (= (first base-ast) dot-sym) (let ((inner (nth base-ast 1))) (and (list? inner) (= (first inner) (quote query)) (let ((s (nth inner 1))) (and (string? s) (> (len s) 0) (= (substring s 0 1) ".")))))) (let ((inner (nth base-ast 1)) @@ -221,7 +246,8 @@ having-info of-filter-info count-filter-info - elsewhere?) + elsewhere? + or-sources) (cond ((<= (len items) 1) (let @@ -279,7 +305,27 @@ having-info (get having-info "threshold") nil)))) - (true on-call)))))))))))) + (true + (if + or-sources + (cons + (quote do) + (cons + on-call + (map + (fn + (pair) + (list + (quote hs-on) + (if + (nth pair 1) + (hs-to-sx + (nth pair 1)) + (quote me)) + (first pair) + handler)) + or-sources))) + on-call))))))))))))) ((= (first items) :from) (scan-on (rest (rest items)) @@ -291,7 +337,8 @@ having-info of-filter-info count-filter-info - elsewhere?)) + elsewhere? + or-sources)) ((= (first items) :filter) (scan-on (rest (rest items)) @@ -303,7 +350,8 @@ having-info of-filter-info count-filter-info - elsewhere?)) + elsewhere? + or-sources)) ((= (first items) :every) (scan-on (rest (rest items)) @@ -315,7 +363,8 @@ having-info of-filter-info count-filter-info - elsewhere?)) + elsewhere? + or-sources)) ((= (first items) :catch) (scan-on (rest (rest items)) @@ -327,7 +376,8 @@ having-info of-filter-info count-filter-info - elsewhere?)) + elsewhere? + or-sources)) ((= (first items) :finally) (scan-on (rest (rest items)) @@ -339,7 +389,8 @@ having-info of-filter-info count-filter-info - elsewhere?)) + elsewhere? + or-sources)) ((= (first items) :having) (scan-on (rest (rest items)) @@ -351,7 +402,8 @@ (nth items 1) of-filter-info count-filter-info - elsewhere?)) + elsewhere? + or-sources)) ((= (first items) :of-filter) (scan-on (rest (rest items)) @@ -363,7 +415,8 @@ having-info (nth items 1) count-filter-info - elsewhere?)) + elsewhere? + or-sources)) ((= (first items) :count-filter) (scan-on (rest (rest items)) @@ -375,7 +428,8 @@ having-info of-filter-info (nth items 1) - elsewhere?)) + elsewhere? + or-sources)) ((= (first items) :elsewhere) (scan-on (rest (rest items)) @@ -387,6 +441,20 @@ having-info of-filter-info count-filter-info + (nth items 1) + or-sources)) + ((= (first items) :or-sources) + (scan-on + (rest (rest items)) + source + filter + every? + catch-info + finally-info + having-info + of-filter-info + count-filter-info + elsewhere? (nth items 1))) (true (scan-on @@ -399,8 +467,9 @@ having-info of-filter-info count-filter-info - elsewhere?))))) - (scan-on (rest parts) nil nil false nil nil nil nil nil false))))) + elsewhere? + or-sources))))) + (scan-on (rest parts) nil nil false nil nil nil nil nil false nil))))) (define emit-send (fn @@ -899,6 +968,22 @@ (true (let ((head (first ast))) + (let + ((reg-cmd-fn (dict-get _hs-command-registry (str head))) + (reg-conv-fn + (and + (= head (quote as)) + (dict-get _hs-converter-registry (nth ast 2))))) + (cond + (reg-conv-fn + (reg-conv-fn + {:hs-to-sx hs-to-sx + :ast ast + :value-ast (nth ast 1) + :type-name (nth ast 2)})) + (reg-cmd-fn + (reg-cmd-fn {:hs-to-sx hs-to-sx :ast ast :head head})) + (true (cond ((= head (quote __bind-from-detail__)) (let @@ -2614,7 +2699,7 @@ (quote begin) (list (quote set!) (quote it) (quote __hs-js)) (quote __hs-js)))))) - (true ast))))))))) + (true ast)))))))))))) ;; ── Convenience: source → SX ───────────────────────────────── (define