#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.