Getting started with adding a backend for Rehp for a new language.
Let me know where you hit friction with these instructions and I'll clarify.
- Clone rehp
grep -r php .
to see various references to PHP. That shows you what was done to extend the compiler to add a new backend. You will be doing something very similar. In general, the best way to get started is to copy/paste everything that was done for PHP, to add your new backend.- Check out the file
compiler/lib/rehp.re
This is the new intermediate representation that was added to the jsoo compiler. Rehp uses the bytecode disassembler from jsoo, and instead of turning it into js, it turns it into this other intermediate representation called "Rehp"- which is defined by
compiler/lib/rehp.re`. - Add your backend to
compiler/lib/backend.ml/i
including info about the file extension. - Add a new file
compiler/lib/YourLang.re
, which can start out as a copy of thecompiler/lib/php.re
file. This represents the AST for your new language. - Add a new file
compiller/lib/YourLangOutput.re
which can start out as a copy ofcompiler/lib/php_out.re
. This is the file that prints your final AST in your backend language. - The main meat of the conversion from
Rehp
intermediate representation should be in a new filecompiler/lib/your_lang_from_rehp.re
. You can start with a copy of eithercompiler/lib/js_from_rehp.re
orcompiler/lib/php_from_rehp.re
depending on if your target language is more similar to JS or more similar to PHP. Ask me which I think is a better starting point, or just try one to get started. - Add new switch cases for your new backend in
compiler/lib/RehpDriver.re
so that it actually uses all your langauge backend conversion and printer.
Most of the work will be in the your_language_from_rehp.re
module, but you want to make sure you get everything plumbed through before getting started.
The overall flow for the compiler is:
js_of_ocaml.ml
`parse_bytecode.ml`(generates bytecode AST) ->
RehpDriver.f
a-bunch-of-bytecode-optimizations (taken right from jsoo).
`generate.ml` (which turns the optimized bytecode into `Rehp` IR)
some-optimizations-on-Rehp itself (which were taken right from jsoo).
Backend (either `javascript_from_rehp.re` or `php_from_rehp.re`, or `your_lang_from_rehp.re`)
Then print according to backend (`js_output.ml` / `rehp_output.re` / `your_lang_output.re`)
- Add a new test case to
buildTest.sh
specifying your--backend
flag. - Run
esy test
to see the output generated.
Sharing some of my notes here too: https://gist.github.com/prometheansacrifice/bde5374f4b0de97b705ae0d5431b488d