feat: Add transformation to Python and a menu item to call it
This commit is contained in:
parent
9985fe1dde
commit
cd5f02603b
1
.gitignore
vendored
1
.gitignore
vendored
@ -11,3 +11,4 @@
|
||||
/.polyglot.metaborg.yaml
|
||||
|
||||
*.aterm
|
||||
*.pp.*
|
||||
|
@ -15,3 +15,11 @@ In the meantime, in case it's of use to me later or to anyone else, I will docum
|
||||
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. ...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...
|
@ -4,6 +4,7 @@ imports
|
||||
|
||||
Syntax
|
||||
Analysis
|
||||
Transformation
|
||||
|
||||
language
|
||||
|
||||
|
7
editor/Transformation.esv
Normal file
7
editor/Transformation.esv
Normal file
@ -0,0 +1,7 @@
|
||||
module Transformation
|
||||
|
||||
menus
|
||||
|
||||
menu: "Transform" (openeditor)
|
||||
|
||||
action: "Generate Python" = generate-python
|
25
trans/python.str
Normal file
25
trans/python.str
Normal file
@ -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
|
@ -6,6 +6,7 @@ imports
|
||||
pp
|
||||
outline
|
||||
analysis
|
||||
python
|
||||
|
||||
rules // Debugging
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user