119 lines
4.3 KiB
Racket
119 lines
4.3 KiB
Racket
#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)
|