Files
gemigreerd-js-maker/scrbl/js-maker.scrbl
T
2026-06-08 12:15:04 +02:00

54 lines
1.8 KiB
Racket

#lang scribble/manual
@(require (for-label racket/base
js-maker))
@title{js-maker}
@author{Hans Dijkema}
@defmodule[js-maker]
@racketmodname[js-maker] provides a deliberately small syntax-driven macro for
making JavaScript strings from a limited Racket-like surface syntax. This is a
clean js-maker 3 restart based on the compact @filepath{js-transform.rkt}
implementation.
@defform[(js form ...)]{
Generates JavaScript statements for each @racket[form] and concatenates them.
The generated JavaScript is returned as a string.
@racketblock[
(js
(define (sum-to n)
(let loop ([i 0] [acc 0])
(if (> i n)
(return acc)
(loop (+ i 1) (+ acc i))))))]
}
@defform[(js1 form)]{
Generates JavaScript for a single expression or syntactic form and returns it as
a string. Use this when you want the expression-level generator directly.
@racketblock[
(js1 (+ 1 2))]
}
@section{Supported core forms}
The compact branch supports identifiers, quoted data, primitive literals,
function calls, infix arithmetic and comparison operators, @racket[if],
@racket[begin], @racket[return], @racket[set!], @racket[lambda],
@racket[define], ordinary @racket[let], @racket[let*], and named
@racket[let].
Ordinary @racket[let] keeps Racket's parallel binding semantics. All right-hand
sides are generated before the bound names are introduced, and the actual
JavaScript bindings are placed in an inner block so JavaScript temporal dead zone
rules cannot accidentally shadow the initializers.
Named @racket[let] is compiled to a JavaScript @tt{while (true)} loop. A tail
call to the loop name is rewritten to parallel assignment of the loop variables
followed by @tt{continue}. This keeps the important loop semantics without
reintroducing the large js-maker 2 implementation.