HS: ask/answer + prompt/confirm mock (+4 tests)

Wire up the `ask` and `answer` commands end-to-end:

- tokenizer.sx: register `ask` and `answer` as hs-keywords.

- parser.sx: cmd-kw? gains both; parse-cmd dispatches to new
  parse-ask-cmd (emits `(ask MSG)`) and parse-answer-cmd, which
  reads `answer MSG [with YES or NO]`. The with/or pair reads
  yes/no via parse-atom — parse-expr would collapse
  `"Yes" or "No"` into `(or "Yes" "No")` before match-kw "or"
  could fire. The no-`with` form emits `(answer-alert MSG)`.

- compiler.sx: three new cond branches (ask, answer, answer-alert)
  compile to a let that binds __hs-a, sets `the-result` and `it`,
  and returns the value — so `then put it into ...` works.

- runtime.sx: hs-ask / hs-answer / hs-answer-alert call
  window.prompt / confirm / alert via host-call + host-global.

- tests/hs-run-filtered.js: test-name-keyed globalThis.{alert,
  confirm,prompt}; __currentHsTestName is updated before each
  test. Host-set! for innerHTML/textContent now coerces JS
  null → "null" (browser behaviour) so `prompt → null` →
  `put it into #out` renders literal text "null", which the
  fourth test depends on.

Suite hs-upstream-askAnswer: 1/5 -> 5/5.
Smoke 0-195: 166/195 -> 170/195.
This commit is contained in:
2026-04-24 14:08:25 +00:00
parent 30fca2dd19
commit 6c1da9212a
11 changed files with 244 additions and 60 deletions

View File

@@ -1717,6 +1717,23 @@
(ca-collect (append acc (list arg)))))))
(ca-collect (list))))
(define parse-call-cmd (fn () (parse-expr)))
(define parse-ask-cmd (fn () (list (quote ask) (parse-expr))))
(define
parse-answer-cmd
(fn
()
(let
((msg (parse-atom)))
(if
(match-kw "with")
(let
((yes (parse-atom)))
(begin
(match-kw "or")
(let
((no-val (parse-atom)))
(list (quote answer) msg yes no-val))))
(list (quote answer-alert) msg)))))
(define parse-get-cmd (fn () (list (quote __get-cmd) (parse-expr))))
(define
parse-take-cmd
@@ -2399,6 +2416,10 @@
(do (adv!) (parse-take-cmd)))
((and (= typ "keyword") (= val "pick"))
(do (adv!) (parse-pick-cmd)))
((and (= typ "keyword") (= val "ask"))
(do (adv!) (parse-ask-cmd)))
((and (= typ "keyword") (= val "answer"))
(do (adv!) (parse-answer-cmd)))
((and (= typ "keyword") (= val "settle"))
(do (adv!) (list (quote settle))))
((and (= typ "keyword") (= val "go"))
@@ -2504,7 +2525,9 @@
(= v "morph")
(= v "open")
(= v "close")
(= v "pick"))))
(= v "pick")
(= v "ask")
(= v "answer"))))
(define
cl-collect
(fn