Browse Source

feat: Add transformation to Python and a menu item to call it

main
Glen Whitney 1 year ago
parent
commit
cd5f02603b
  1. 1
      .gitignore
  2. 10
      README.md
  3. 1
      editor/Main.esv
  4. 7
      editor/Transformation.esv
  5. 25
      trans/python.str
  6. 1
      trans/spoofax_helloworld.str

1
.gitignore

@ -11,3 +11,4 @@
/.polyglot.metaborg.yaml
*.aterm
*.pp.*

10
README.md

@ -14,4 +14,12 @@ In the meantime, in case it's of use to me later or to anyone else, I will docum
1. At this point I followed the tutorial linked at the top of this readme...
1. ... 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 https://yellowgrass.org/issue/Spoofax/236 for the workarounds I used for this and the subsequent JRE version issues I encountered.
1. 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.
1. The guide ends there, but we want to be able to "compile" helloworld language programs into Python Hello World programs, so...
1. The guide ends there, but we want to be able to "compile" helloworld language programs into Python Hello World programs, so...
1. ...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.
1. 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.
1. Then the Transformation module has to be imported into editor/Main.esv.
1. 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.)
1. 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.
1. Now at this point (after building the project) we can visit a test.hel file, select Transform > Generate Python from the menu, and voila, test.py is written alongside test.hel.
1. Executing `python3 test.py` 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.
1. But now we'd actually like to be able to "compile" helloworld programs into python without firing up Eclipse, so...

1
editor/Main.esv

@ -4,6 +4,7 @@ imports
Syntax
Analysis
Transformation
language

7
editor/Transformation.esv

@ -0,0 +1,7 @@
module Transformation
menus
menu: "Transform" (openeditor)
action: "Generate Python" = generate-python

25
trans/python.str

@ -0,0 +1,25 @@
module python
imports
signatures/-
rules
// Generate python code from AST:
to-python:
Program(x, y) -> $[ print( [x'] + ',', [y'] ) ]
where
x' := <to-python> x
; y' := <to-python> y
to-python:
Hello() -> $[ "Greetings" ]
to-python:
World() -> $[ "Earth" ]
// Interface python code generation with editor services and file system
generate-python: (selected, _, _, path, project-path) -> (filename, result)
with filename := <guarantee-extension(|"py")> path
; result := <to-python> selected

1
trans/spoofax_helloworld.str

@ -6,6 +6,7 @@ imports
pp
outline
analysis
python
rules // Debugging

Loading…
Cancel
Save