cisco / ChezScheme

Chez Scheme
Apache License 2.0
6.97k stars 986 forks source link

Vanilla JavaScript backend #397

Closed amirouche closed 4 years ago

amirouche commented 5 years ago

I am perusing the idea of making a vanilla JavaScript backend something in the spirit of https://gitlab.com/ijp/guile/tree/compile-to-js-2017.

In the best of the worlds one should support both WASM and Vanilla JavaScript and compare.

For the time being I will look into a Vanilla JavaScript backend (at some point in the future).

Any help or input appreciated.

amirouche commented 5 years ago

Some similar experiences:

tx to @soegaard

soegaard commented 5 years ago

I forgot to point to:

https://github.com/soegaard/urlang/tree/master/compiler-rjs

which contains a compiler from Racket top-level-forms (i.e. without modules) to JavaScript.

The compiler uses Racket's expand to turn top-level-forms into fully expanded (FE) syntax. Then a series of passes written using Nanopass turns the program into ANF form and finally an Urlang program (represented as nanopass structures) is produced. The translation from ANF to Urlang is inspired by "Destination-driven Code Generation". At last the Urlang program is converted to JavaScript.

The main idea of introducing the last layer "Urlang to JavaScript" instead of emitting JavaScript directly was done to catch errors early. Consider the case where a faulty compiler pass inserts a reference to an unbound variable. Normally this identifier will be emitted to the final JavaScript program, and the problem will not be caught until the JavaScript program is run.

Having the entire JavaScript output as an Urlang program makes it possible to report these errors at compile time. Furthermore all identifiers carry source location information so in DrRacket I can usually jump directly to the place in the compiler where the mistake was made.

PS: Isn't the mailing list better for this sort of thread?

/Jens Axel

amirouche commented 5 years ago

Then a series of passes written using Nanopass turns the program into ANF form

Why did you choose to turn the program in ANF?

PS: Isn't the mailing list better for this sort of thread?

Not sure the mailing list is not very active.

soegaard commented 5 years ago

Why did you choose to turn the program in ANF? Familiarity and ease of code generation.

My thinking is that the JavaScript JIT is tuned for programs written in a direct style, so using ANF makes sense (as opposed to CPS).

Note that the disadvantage of this "Racket to JavaScript" compiler is that the primitives needs to implemented in JavaScript. And there are quite a few primitives in Racket.

/Jens Axel

amirouche commented 4 years ago

Personal backlog clean-up.

NalaGinrut commented 4 years ago

My thinking is that the JavaScript JIT is tuned for programs written in a direct style, so using ANF makes sense (as opposed to CPS).

The last time I've asked @akeep about the IR in Chez, he said the nanopass is enough to be the IR for high efficient optimizing. My understanding is that maybe it means there's no need to add yet another IR tier when we are using Chez as a backend.