The Spoofax helloworld language project, extended to the point of "compiling" the language to python
Go to file
Glen Whitney 7bbc968b31 docs: Add note about Spoofax version 2021-01-13 16:30:42 -08:00
.mvn init: The Spoofax "helloworld" example as generated 2020-12-08 19:18:30 -08:00
editor feat: Add transformation to Python and a menu item to call it 2020-12-09 20:46:06 -08:00
src/main/strategies/spoofax_helloworld/strategies init: The Spoofax "helloworld" example as generated 2020-12-08 19:18:30 -08:00
syntax feat: define the helloworld language, per tutorial 2020-12-08 19:58:33 -08:00
trans feat: Add transformation to Python and a menu item to call it 2020-12-09 20:46:06 -08:00
.gitignore feat: Add transformation to Python and a menu item to call it 2020-12-09 20:46:06 -08:00 docs: Add note about Spoofax version 2021-01-13 16:30:42 -08:00
hel2py feat: Add command-line compilation 2020-12-10 22:14:40 -08:00
metaborg.yaml init: The Spoofax "helloworld" example as generated 2020-12-08 19:18:30 -08:00
pom.xml init: The Spoofax "helloworld" example as generated 2020-12-08 19:18:30 -08:00
test.hel test: Add a test helloworld file, per tutorial 2020-12-08 20:03:44 -08:00

spoofax_helloworld Language Specification

This repository begins with exactly the helloworld language example from the Spoofax user guide, except under the name "spoofax_helloworld."

The plan is to develop this example just to the point of defining a translation of this language into python, and setting things up so that it is possible to (independently from Eclipse) "compile" a helloworld "program" into a python program.

Then I will freeze this project and start again with the calc language, grafting into that the syntax changes I'm actually interested in.

In the meantime, in case it's of use to me later or to anyone else, I will document here in this readme the full set of steps I go through in order to get the helloworld program into the goal state.

  1. In my previously existing working installation of Eclipse IDE for Java (2020-09, i.e. v. 4.17, for completeness sake), I went to Help > Install new software, clicked on the button to add a new site, put in the site name of Spoofax and got the the URL for the site from - it's the very long url labeled as "Eclipse update site:" that spans several lines. NOTE: The latest release as of this writing, Spoofax 2.5.13, produced the "lifecycle" error in item 5 below. However, the "development snapshot" available using the update site did not generate the error, so I recommend using a Spoofax newer than release 2.5.13.
  2. Then I checked the box next to "Spoofax Eclipse" and then followed the prompts (I think I had to click on "Next>" or maybe "Finished"). Eventually Eclipse asked me if I wanted it to restart, which I agreed to.
  3. And indeed, once it restarted, the "Spoofax" and "Spoofax (meta)" menus showed up.
  4. At this point I followed the tutorial linked at the top of this readme...
  5. ... until I got to the point of building the project. Then I encountered a "Plugin execution not covered by lifecycle configuration error." See the YellowGrass issue for the workarounds I used for this and the subsequent JRE version issues I encountered.
  6. With those workarounds, I was able to enter the test.hel program and get into parse or produce syntax errors when incorrect, as described in the getting started guide.
  7. The guide ends there, but we want to be able to "compile" helloworld language programs into Python Hello World programs, so...
  8. ...I first created a Stratego transformation which would generate Python source code from the AST of a helloworld language program. The basic transformation is captured in the rule "to-python". Note this is implemented in a very direct, explicit way, not taking advantage of the visitor patterns factoring into separate local rules and strategies for applying them to the parse tree. This is probably OK though for such a trivial "language". This rule is placed in the file trans/python.str.
  9. However, now you want to be able to run this transformation from the IDE. For that, you need to create a menu item on the Spoofax menu. We follow the process documented in the Editor SerVice (ESV) section of the Spoofax documentation. The basic menu definition is simple, it just basically associates a label with a Stratego strategy. We put this in the file editor/Transformation.esv.
  10. Then the Transformation module has to be imported into editor/Main.esv.
  11. And we need to add a "glue" strategy generate-python to python.str which accepts the conventional parameters for an ESV menu item, deals with the file system, and finally calls the basic to-python rule on the proper AST. (Note the Spoofax documentation and the calc example repository differed on which parameter of the call to generate-python should be transformed; I followed the calc example and it seemed to work.)
  12. Finally, we need the Editor SerVice to be able to see the generate-python strategy, so we have to include the python module in spoofax_helloworld.str, which seems to serve more or less as the Stratego main program for this language.
  13. Now at this point (after building the project) we can visit a test.hel file, select Transform > Generate Python from the menu, and voila, is written alongside test.hel.
  14. Executing python3 from a shell shows that we are now actually able to produce valid greetings as specified by (any one of the four legal) helloworld language programs.
  15. But now we'd actually like to be able to "compile" helloworld programs into python without firing up Eclipse, so...
  16. ...we create the hel2py script. To use this, you need to download the Spoofax sunshine executable jar, from Then there are a few environment variables that need to be set; these are explained in the output of hel2py -h. Once all is set up, you can use the command to translate a helloworld language file to Python, and execute it by piping the result to python3 -.
  17. The end result isn't really very satisfactory for deploying a helloworld language "transpiler" to Python, as it requires an Eclipse installation which shouldn't really be necessary. But as it does minimally meet the stated goal of this repository, we'll wrap up efforts on the helloworld language here and move on to work on a more interesting language. It will be more worthwhile to investigate a streamlined packaging of a compiler when there's a language it might be worth compiling.