HS: js-block return values + worker stub test
Parser: parse-js-block extracts raw JS source by character positions. Compiler: js-block AST → hs-js-exec call, stores result in it. Runtime: hs-js-exec creates JS Function, handles promise rejection. Test runner: host-new-function/host-promise-state natives + promise monkey-patch. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2268,6 +2268,25 @@
|
||||
(list (quote hs-halt!) (quote event) (nth ast 1)))
|
||||
((= head (quote focus!))
|
||||
(list (quote dom-focus) (hs-to-sx (nth ast 1))))
|
||||
((= head (quote js-block))
|
||||
(let
|
||||
((params (nth ast 1)) (js-src (nth ast 2)))
|
||||
(let
|
||||
((bound-syms (map (fn (p) (make-symbol p)) params)))
|
||||
(list
|
||||
(quote let)
|
||||
(list
|
||||
(list
|
||||
(quote __hs-js)
|
||||
(list
|
||||
(quote hs-js-exec)
|
||||
(cons (quote list) params)
|
||||
js-src
|
||||
(cons (quote list) bound-syms))))
|
||||
(list
|
||||
(quote begin)
|
||||
(list (quote set!) (quote it) (quote __hs-js))
|
||||
(quote __hs-js))))))
|
||||
(true ast)))))))))
|
||||
|
||||
;; ── Convenience: source → SX ─────────────────────────────────
|
||||
|
||||
@@ -2506,6 +2506,33 @@
|
||||
(let
|
||||
((target (cond ((at-end?) (list (quote beingTold))) ((and (= (tp-type) "keyword") (or (= (tp-val) "then") (= (tp-val) "end"))) (list (quote beingTold))) (true (parse-expr)))))
|
||||
(list (quote close-element) target))))
|
||||
(define
|
||||
parse-js-block
|
||||
(fn
|
||||
()
|
||||
(let
|
||||
((params (if (= (tp-type) "paren-open") (do (adv!) (define collect-params! (fn (acc) (cond ((or (at-end?) (= (tp-type) "paren-close")) (do (when (= (tp-type) "paren-close") (adv!)) acc)) ((= (tp-type) "comma") (do (adv!) (collect-params! acc))) (true (let ((pname (tp-val))) (do (adv!) (collect-params! (append acc pname)))))))) (collect-params! (list))) (list))))
|
||||
(let
|
||||
((js-start (cur-start)))
|
||||
(define
|
||||
skip-to-end!
|
||||
(fn
|
||||
()
|
||||
(if
|
||||
(or
|
||||
(at-end?)
|
||||
(and (= (tp-type) "keyword") (= (tp-val) "end")))
|
||||
nil
|
||||
(do (adv!) (skip-to-end!)))))
|
||||
(skip-to-end!)
|
||||
(let
|
||||
((js-end (cur-start)))
|
||||
(let
|
||||
((js-src (substring src js-start js-end)))
|
||||
(when
|
||||
(and (= (tp-type) "keyword") (= (tp-val) "end"))
|
||||
(adv!))
|
||||
(list (quote js-block) params js-src)))))))
|
||||
(define
|
||||
parse-cmd
|
||||
(fn
|
||||
@@ -2655,6 +2682,8 @@
|
||||
(do (adv!) (list (quote continue))))
|
||||
((and (= typ "keyword") (or (= val "exit") (= val "halt")))
|
||||
(do (adv!) (list (quote exit))))
|
||||
((and (= typ "keyword") (= val "js"))
|
||||
(do (adv!) (parse-js-block)))
|
||||
(true (parse-expr))))))
|
||||
(define
|
||||
parse-cmd-list
|
||||
@@ -2710,7 +2739,8 @@
|
||||
(= v "close")
|
||||
(= v "pick")
|
||||
(= v "ask")
|
||||
(= v "answer"))))
|
||||
(= v "answer")
|
||||
(= v "js"))))
|
||||
(define
|
||||
cl-collect
|
||||
(fn
|
||||
|
||||
@@ -2588,3 +2588,21 @@
|
||||
node
|
||||
(walk (hs-node-get node (first keys)) (rest keys)))))
|
||||
(hs-line-for (walk (hs-parse-ast src-str) path))))
|
||||
|
||||
(define
|
||||
hs-js-exec
|
||||
(fn
|
||||
(param-names js-src bound-args)
|
||||
(let
|
||||
((js-fn (host-new-function param-names js-src)))
|
||||
(let
|
||||
((result (host-call-fn js-fn bound-args)))
|
||||
(if
|
||||
(= (host-typeof result) "promise")
|
||||
(let
|
||||
((state (host-promise-state result)))
|
||||
(if
|
||||
(and state (= (host-get state "ok") false))
|
||||
(raise (host-get state "value"))
|
||||
(if state (host-get state "value") result)))
|
||||
result)))))
|
||||
|
||||
Reference in New Issue
Block a user