A mostly AI coded js-maker, supervised by me.

This commit is contained in:
2026-05-26 09:42:35 +02:00
parent 8e8afc321b
commit 2cf831c180
23 changed files with 4143 additions and 1 deletions
+118
View File
@@ -0,0 +1,118 @@
#lang racket/base
(require "../main.rkt"
"jsmaker-executors.rkt"
"jsmaker-test-framework.rkt")
(define dom-preamble
(string-append
"const window = {};\n"
"const logs = [];\n"
"const attrs = {};\n"
"const console = { log: (...xs) => logs.push(xs.length === 1 ? xs[0] : xs) };\n"
"const document = {\n"
" getElementById: (id) => id === 'hi'\n"
" ? { setAttribute: (k, v) => { attrs[k] = v; }, getAttribute: (k) => attrs[k] || '' }\n"
" : false\n"
"};"))
(define t1-program
(js (set! window.myfunc (λ (x)
(let* ((el (send document getElementById 'hi))
(old (send el getAttribute "x"))
(y (+ old (* x x))))
(send el setAttribute "x" (+ y "")))
(send console log "dit set attribute x on element hi")))))
(define t2-program
(js (define (f x)
(if (and (> x 10) (< x 15))
(begin (console.log x)
(return x))
(return (* x x))))))
(define t3-program
(js (define (f x y z)
(send console log (cons x (cons y (list z))))
(let* ((l (cons x (cons y (list z)))))
(return (send l map (λ (a) (return (+ a 10)))))))))
(define tail-loop-expression
(js/expression (let loop ([i 0] [s 0])
(if (< i 5)
(loop (+ i 1) (+ s i))
s))))
(unless (regexp-match? #rx"while \\(true\\)" tail-loop-expression)
(error 'jsmaker-program-regression
"tail-recursive named let was not lowered to while(true): ~a"
tail-loop-expression))
(unless (regexp-match? #rx"\n " t1-program)
(error 'jsmaker-program-regression
"generated statement code does not appear to contain indentation: ~a"
t1-program))
(unless (regexp-match? #rx"if \\(\\(x > 10\\) && \\(x < 15\\)\\)" t2-program)
(error 'jsmaker-program-regression
"boolean and should compile directly in if test: ~a"
t2-program))
(define program-tests
(list
(js-program-test
'dom-style-set-attribute
t1-program
"(() => { attrs.x = 'old:'; window.myfunc(4); return [attrs.x, logs]; })()"
"[\"old:16\",[\"dit set attribute x on element hi\"]]"
#:preamble dom-preamble)
(js-program-test
'define-if-return-console
t2-program
"(() => { const a = f(12); const b = f(5); return [a, b, logs]; })()"
"[12,25,[12]]"
#:preamble "const logs = []; const console = { log: (...xs) => logs.push(xs.length === 1 ? xs[0] : xs) };" )
(js-program-test
'define-send-map-return
t3-program
"(() => { const r = f(1, 2, 3); return [r, logs]; })()"
"[[11,12,13],[[1,2,3]]]"
#:preamble "const logs = []; const console = { log: (...xs) => logs.push(xs.length === 1 ? xs[0] : xs) };" )
(js-expression-test 'named-let-tail-big
(js/expression (let loop ([i 0] [s 0])
(if (< i 100000)
(loop (+ i 1) (+ s 1))
s)))
"100000")
(js-expression-test 'named-let-tail-accumulator tail-loop-expression "10")
(js-expression-test 'explicit-while-form
(js/expression (let ([i 0] [s 0])
(while (< i 4)
(set! s (+ s i))
(set! i (+ i 1)))
s))
"6")
(js-expression-test 'bare-return
(js/expression ((lambda (x) (if x (return) (return 7))) #t))
"undefined")
(js-expression-test 'implicit-last-expression-return
(js/expression ((lambda (x) (+ x 10)) 5))
"15")
(js-program-test
'with-handlers-rest-lambda-statement
(js (with-handlers ([exn? (λ args (displayln (length args)))])
(/ 10 0)))
"logs"
"[1]"
#:preamble "const logs = []; const console = { log: (...xs) => logs.push(xs.length === 1 ? xs[0] : xs) };")))
(define engine (find-js-engine))
(run-jsmaker-regression 'jsmaker-program-regression program-tests "/tmp/jsmaker-program-regression.js" #:engine engine)