From cd5f02603bc317bbf20d5794c480c339e992ddfa Mon Sep 17 00:00:00 2001 From: Glen Whitney Date: Wed, 9 Dec 2020 20:46:06 -0800 Subject: [PATCH] feat: Add transformation to Python and a menu item to call it --- .gitignore | 1 + README.md | 10 +++++++++- editor/Main.esv | 1 + editor/Transformation.esv | 7 +++++++ trans/python.str | 25 +++++++++++++++++++++++++ trans/spoofax_helloworld.str | 1 + 6 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 editor/Transformation.esv create mode 100644 trans/python.str diff --git a/.gitignore b/.gitignore index 3520f23..d1c1972 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ /.polyglot.metaborg.yaml *.aterm +*.pp.* diff --git a/README.md b/README.md index 5233a48..57333a3 100644 --- a/README.md +++ b/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... \ No newline at end of file +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... \ No newline at end of file diff --git a/editor/Main.esv b/editor/Main.esv index 520f115..c546bc3 100644 --- a/editor/Main.esv +++ b/editor/Main.esv @@ -4,6 +4,7 @@ imports Syntax Analysis + Transformation language diff --git a/editor/Transformation.esv b/editor/Transformation.esv new file mode 100644 index 0000000..a282a0f --- /dev/null +++ b/editor/Transformation.esv @@ -0,0 +1,7 @@ +module Transformation + +menus + + menu: "Transform" (openeditor) + + action: "Generate Python" = generate-python diff --git a/trans/python.str b/trans/python.str new file mode 100644 index 0000000..6d594be --- /dev/null +++ b/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' := x + ; y' := 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 := path + ; result := selected diff --git a/trans/spoofax_helloworld.str b/trans/spoofax_helloworld.str index 93d7736..a286a03 100644 --- a/trans/spoofax_helloworld.str +++ b/trans/spoofax_helloworld.str @@ -6,6 +6,7 @@ imports pp outline analysis + python rules // Debugging