Alles aangepast.

This commit is contained in:
2026-06-08 12:55:08 +02:00
parent a9610e6e0c
commit 823130e3ac
24 changed files with 418 additions and 2621 deletions
+41 -108
View File
@@ -1,118 +1,51 @@
#lang racket/base
(require "../main.rkt"
"jsmaker-executors.rkt"
(require rackunit
"../main.rkt"
"jsmaker-test-framework.rkt")
(define dom-preamble
(provide program-tests)
(define ordinary-let-program
(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"
"};"))
(js (define (ordinary-let x)
(let ([x 1] [y x])
(return y))))
"console.log(ordinary_let(99));\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 sequential-let-program
(string-append
(js (define (sequential-let x)
(let* ([x 1] [y x])
(return y))))
"console.log(sequential_let(99));\n"))
(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 named-let-program
(string-append
(js (define (sum-to n)
(let loop ([i 0] [acc 0])
(if (> i n)
(return acc)
(loop (+ i 1) (+ acc i))))))
"console.log(sum_to(10));\n"))
(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)
(test-suite
"generated JavaScript program behavior"
(test-case "ordinary let uses parallel Racket binding semantics"
(check-js-contains? ordinary-let-program "const")
(check-js-contains? ordinary-let-program "let x")
(when (node-available?)
(check-equal? (run-js/trimmed ordinary-let-program) "99")))
(test-case "let* uses sequential binding semantics"
(when (node-available?)
(check-equal? (run-js/trimmed sequential-let-program) "1")))
(test-case "named let compiles to a while loop with parallel updates"
(check-js-contains? named-let-program "while (true)")
(check-js-contains? named-let-program "continue;")
(when (node-available?)
(check-equal? (run-js/trimmed named-let-program) "55")))))
(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)
(module+ test
(require rackunit/text-ui)
(run-tests program-tests))