tail returns and complex stuff

This commit is contained in:
2026-05-27 17:00:11 +02:00
parent 92d4461203
commit 9026d2cbdf
4 changed files with 105 additions and 35 deletions
+39 -3
View File
@@ -16,7 +16,7 @@
(list (verbatim rkt) (verbatim js)))))
@title{js-maker: a Syntax-Driven Racket-to-JavaScript Generator}
@author+email["Hans Dijkema" "hans@dijkewijk.nl"]
@author+email["Hans Dijkema" ""]
@defmodule[jsmaker]
@@ -58,7 +58,32 @@ function square(x) {
Inside function bodies, the last expression is returned automatically unless it
is already a statement form such as @racket[return], @racket[define],
@racket[set!], @racket[while], or @racket[for].
@racket[set!], @racket[while], or @racket[for]. At the top level of a
@racket[js] form, js-maker also returns the value of a final value-producing
form, such as @racket[let], @racket[begin], @racket[if], or
@racket[with-handlers]. This makes @racket[js] output suitable as the body of a
WebView @tt{runJavaScript} wrapper function.
For example:
@racketblock[
(let ([html "<h1>Hi</h1>"])
(displayln
(js
(let ([el (send document getElementById 'test)])
(set! (js-dot el innerHTML) (eval html))
#t))))
]
emits JavaScript similar to:
@codeblock{
{
let el = document.getElementById("test");
el.innerHTML = "<h1>Hi</h1>";
return true;
}
}
}
@defform[(js/expression expr)]{
@@ -245,7 +270,13 @@ Interop forms provide direct access to JavaScript object and method syntax:
@item{@racket[(send obj method arg ...)] emits @tt{obj.method(arg, ...)}.}
@item{@racket[(new cls arg ...)] emits @tt{new cls(arg, ...)}.}
@item{@racket[(js-ref obj key)] emits @tt{obj[key]}.}
@item{@racket[(js-dot obj field)] emits @tt{obj.field}.}
@item{@racket[(js-dot obj field)] emits @tt{obj.field}. It is the
preferred explicit form for property access in generated code.}
@item{@racket[(set! (js-dot obj field) value)] emits @tt{obj.field = value}.}
@item{@racket[(set! expr.field value)] is also accepted by the reader as
@racket[(set! expr .field value)] and is emitted as a direct property
assignment. This is mainly a convenience for DOM code such as
@racket[(set! (send document getElementById 'test).innerHTML html)].}
@item{@racket[(set-prop! obj key value)] emits @tt{obj[key] = value}.}
@item{@racket[(delete-prop! obj key)] and @racket[(js-delete obj key)] emit
JavaScript @tt{delete}.}
@@ -719,6 +750,7 @@ The package uses this layout:
js-maker/
main.rkt
info.rkt
private/
testing/
demo/
scrbl/
@@ -727,6 +759,10 @@ js-maker/
@filepath{main.rkt} is the public module. @filepath{testing/} contains the
executor and regression framework. @filepath{demo/} contains generated-code
examples. @filepath{scrbl/} contains this reference and the use-case document.
The @filepath{private/} directory contains compatibility/helper material from
the source project. The current public module and tests do not depend on those
private files; they are kept for downstream compatibility and are omitted from
compilation and the package test entry point in @filepath{info.rkt}.
@section{Limitations and non-goals}