haskell: getLine/getContents/readFile/writeFile + 0-arity builtin force (+12 tests, 587/587)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 21s

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-06 13:43:13 +00:00
parent 578e54f06d
commit 041cb9f3ef
3 changed files with 189 additions and 5 deletions

View File

@@ -56,6 +56,8 @@
(dict-set! v "forced" true)
(dict-set! v "value" res)
res))))
((and (dict? v) (= (get v "type") "builtin") (= (get v "arity") 0))
((get v "fn")))
(:else v))))
;; Recursive force — used at the test/output boundary so test
@@ -474,6 +476,16 @@
((= op "div") (floor (/ lv rv)))
((= op "rem") (mod lv rv))
((= op "quot") (truncate (/ lv rv)))
((= op ">>=")
(if
(and (list? lv) (= (first lv) "IO"))
(hk-apply rv (nth lv 1))
(raise "(>>=): left side is not an IO action")))
((= op ">>")
(if
(and (list? lv) (= (first lv) "IO"))
rv
(raise "(>>): left side is not an IO action")))
(:else (raise (str "unknown operator: " op))))))
(define
@@ -683,7 +695,7 @@
(dict-set! env "quot" (hk-make-binop-builtin "quot" "quot"))
(dict-set! env "show" (hk-mk-lazy-builtin "show" hk-show-val 1))
(hk-load-into! env hk-prelude-src)
(do
(begin
(dict-set!
env
"putStrLn"
@@ -691,7 +703,7 @@
"putStrLn"
(fn
(s)
(do
(begin
(append! hk-io-lines (hk-force s))
(list "IO" (list "Tuple"))))
1))
@@ -702,7 +714,7 @@
"putStr"
(fn
(s)
(do
(begin
(append! hk-io-lines (hk-force s))
(list "IO" (list "Tuple"))))
1))
@@ -713,10 +725,72 @@
"print"
(fn
(x)
(do
(begin
(append! hk-io-lines (hk-show-val x))
(list "IO" (list "Tuple"))))
1))
(dict-set!
env
"getLine"
(hk-mk-lazy-builtin
"getLine"
(fn
()
(if
(empty? hk-stdin-lines)
(error "getLine: no more input")
(let
((line (first hk-stdin-lines)))
(begin
(set! hk-stdin-lines (rest hk-stdin-lines))
(list "IO" line)))))
0))
(dict-set!
env
"getContents"
(hk-mk-lazy-builtin
"getContents"
(fn
()
(let
((lines hk-stdin-lines))
(begin
(set! hk-stdin-lines (list))
(list
"IO"
(if
(empty? lines)
""
(reduce
(fn (acc s) (str acc "\n" s))
(first lines)
(rest lines)))))))
0))
(dict-set!
env
"readFile"
(hk-mk-lazy-builtin
"readFile"
(fn
(path)
(let
((p (hk-force path)))
(if
(has-key? hk-vfs p)
(list "IO" (get hk-vfs p))
(error (str "readFile: " p ": file not found")))))
1))
(dict-set!
env
"writeFile"
(hk-mk-lazy-builtin
"writeFile"
(fn
(path contents)
(begin
(dict-set! hk-vfs (hk-force path) (hk-force contents))
(list "IO" (list "Tuple"))))
2))
env))))
;; Eagerly build the Prelude env once at load time; each call to
@@ -945,6 +1019,20 @@
hk-run-io
(fn (src) (do (set! hk-io-lines (list)) (hk-run src) hk-io-lines)))
(define hk-stdin-lines (list))
(define hk-vfs (dict))
(define
hk-run-io-with-input
(fn
(src stdin-lines)
(begin
(set! hk-io-lines (list))
(set! hk-stdin-lines stdin-lines)
(hk-run src)
hk-io-lines)))
(define hk-env0 (hk-init-env))
(define