HS: do→let/it chaining, single-IO fetch, fetch URL parser, IO mock

Compiler: do-blocks now compile to (let ((it cmd1)) (let ((it cmd2)) ...))
instead of (do cmd1 cmd2 ...). This chains the `it` variable through
command sequences, enabling `fetch X then put it into me` pattern.
Each command's result is bound to `it` for the next command.

Runtime: hs-fetch simplified to single perform (io-fetch url format)
instead of two-stage io-fetch + io-parse-text/json.

Parser: fetch URL /path handled by reading /+ident tokens.
Default fetch format changed to "text" (was "json").

Test runner: mock fetch routes with format-specific responses.
io-fetch handler returns content directly based on format param.

Fetch tests still need IO suspension to chain through let continuations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-17 22:54:31 +00:00
parent 25db89a96c
commit ac193e8839
7 changed files with 53 additions and 22 deletions

View File

@@ -999,7 +999,23 @@
(hs-to-sx (nth ast 1))
(hs-to-sx (nth ast 2)))))
((= head (quote do))
(cons (quote do) (map hs-to-sx (rest ast))))
(let
((compiled (map hs-to-sx (rest ast))))
(if
(= (len compiled) 1)
(first compiled)
(let
((last-cmd (nth compiled (- (len compiled) 1)))
(init-cmds (reverse (rest (reverse compiled)))))
(reduce
(fn
(body cmd)
(list
(quote let)
(list (list (quote it) cmd))
body))
last-cmd
(reverse init-cmds))))))
((= head (quote wait)) (list (quote hs-wait) (nth ast 1)))
((= head (quote wait-for)) (emit-wait-for ast))
((= head (quote log))

View File

@@ -1270,7 +1270,7 @@
(let
((url (if (nil? url-atom) url-atom (parse-arith (parse-poss url-atom)))))
(let
((fmt (if (match-kw "as") (let ((f (tp-val))) (adv!) f) "json")))
((fmt (if (match-kw "as") (let ((f (tp-val))) (adv!) f) "text")))
(list (quote fetch) url fmt)))))))
(define
parse-call-args

View File

@@ -285,13 +285,7 @@
hs-fetch
(fn
(url format)
(let
((response (perform (list (quote io-fetch) url))))
(cond
((= format "json") (perform (list (quote io-parse-json) response)))
((= format "text") (perform (list (quote io-parse-text) response)))
((= format "html") (perform (list (quote io-parse-html) response)))
(true response)))))
(perform (list "io-fetch" url (if format format "text")))))
(define
hs-coerce