Child pages
  • Shapes - an introductory MPS tutorial

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...



Now, to place the collection below the name of the Canvas, you should use the Alt + Enter shortcut (or the light-bulb symbol) the bring up the intention pop up menu and pick "Add On New Line".

If you accidentally press "Add New Line", undo that action with Control/Cmd + Z.
You'll get the final editor definition:

...

First we need to set the dependencies of the generator module and the generator model as specified below:

Image Removed

 

Image Removed

Remember,  to depend on the JDK module. Without this dependency you would not be able to compile your sandbox eventually.

Note: Remember, Alt + Enter will bring up the properties of the node selected in the left-hand hand Project View.

Image Added

Second, the generator model must depend on java.swing and java.awt, as specified below. Without these dependencies you would not be able to type the Java Swing code needed to implement the generator templates:

 

Image Added

With the dependencies you can start typing the Java code that will be part of the generated Java class. We will then parametrize the code with values from the Canvas, to make it reflect the user's intent.

...

If the LOOP macro is underlined in red, most likely you did not select the whole line before applying the intention. Undo, select the whole line including the semicolon and apply the Add LOOP macro intention again.
The LOOP macro will repeat the "System.out.println("Draw here");" statement for each shape listed in node.shapes.

We, however, need to have the "System.out.println("Draw here");" statements replaced with code that draws each of these shapes. The COPY_SRC macro will do just that. Please, select the whole statement within the LOOP macro again, including the semicolon, hit Alt + Enter and choose Node macro.

...

Type in COPY_SRC (Control + Space) and you get a macro that will replace "System.out.println("Draw here");" with the current shape for all shapes that the LOOP macro provides.


Make sure your COPY_SRC macro wraps the whole statement, including the semicolon, like it is displayed in the picture. If not, undo, select the whole statement and insert the COPY_SRC macro again.

Generating circles

Now we get Canvas to be translated into a Java class and we also made a place for Shapes to add the code that will draw them. The time is up for us to define the actual translation rules for Shapes themselves, so that we get a "graphics.drawCircle()" method inserted in the generated code as a replacement for the Circle shape. You need to open the main mapping configuration and add a new entry to the "reduction rules" section:

...

We'll start mimicking how generator is done for Circles. Identically provide the following code for the reduce_Square template.

Hint: Start by inserting a BlockStatement


The values passed into "drawRect" should be replaced with property macros with the upperLeftX, upperLeftY and size properties of the Square.

...

Info

The drawRect() method's third and fourth parameters specify the rectangle's width and height, respectively. Since we want to draw a square, we need to provide the same values for both arguments. This is why the property macros for the third and fourth parameters both specify size.

Generating code

Now we're done defining the generator. If you rebuild the language, open MyDrawing, right-click it and choose "Preview Generated Text",

  Image Added
you'll get a nicely structured Java code that properly initializes a JFrame and draws all the shapes:

Image Added

If your code is different, look into one of your generator templates, they are probably different from the ones presented in the tutorial. Maybe your macros are not attached to the correct pieces of code or the values specified in the Inspector window for the macros differ from the ones in the screen-shots.

If the code does not compile, make sure your generator module depends on the JDK module, as we defined earlier.

A more robust generation for Squares

The way we handled the graphics local variable in the templates was not quite right. We relied, perhaps too optimistically, on the name of the variable to be the same in map_Canvasreduce_Circle and reduce_Square. What if the names of the variable in these three templates were not the same? A more robust solution is needed

As indicated earlier in the section for the Circle generator, we'll use the reduce_Square template to properly tie the graphics local variable with the graphics parameter that the map_Canvas template generates. Relying on name match is not very robust.

...

We could now replicate the retrieval of the graphics parameter for the reduce_Circle template, as well.

Generating code

Now we're done defining the generator. If you rebuild the language, open MyDrawing, right-click it and choose "Preview Generated Text",

  Image Removed
you'll get a nicely structured Java code that properly initializes a JFrame and draws all the shapes:

Image Removed

Running the code

It is nice to see generated code, but you might actually prefer seeing it running. MPS can compile and run generated Java code easily. We only need to indicate that Canvas is generated into a runnable Java class and thus Canvas itself should be treated as runnable, or as a "main" class. We only need to make Canvas implement the IMainClass interface and MPS will take care of the rest. The IMainClass interface comes from the jet brains.mps.execution.util language and so we need to add it to the list of dependencies of our language and set the scope to Extends:

...


You will get a running Java application with your drawing on it as a reward for your efforts.

An alternative generator - generating XML

Just to give you an idea how the generator could be utilized to generate code in a declarative language, such as xml, here's a simple generator for the Shapes language generating xml. We start from an empty generator. The Java templates and rules have all been deleted:

Image Added

First, the jetbrains.mps.core.xml language must be imported (Control + L). It is the projectional equivalent to xml, as we know it, just like BaseLanguage is a projectional equivalent to Java.

A root mapping rule must be created to convert Canvases into xml files.

Image Added

Image Added

The template named map_Canvas gets created.

Image Added

Xml code must be typed into the template in order to create the required code:

Image Added

Image Added

In order to insert the name attribute, type "space" followed by "name=":

Image Added

A property macro must be set on the contents of the name attribute value:

Image Added

Image Added

Some more xml needs to be inserted:

Image Added

We create a placeholder for all the shapes:

Image Added

With Control/Cmd + Up select the placeholder xml element:

Image Added

Then insert a COPY_SRCL macro to loop through all the shapes of a Canvas and trigger their reduction rules:

Image Added

Image Added

The name of the generated xml file can also be customized using a property macro.

Image Added

Image Added

Reduction rules for Square and Circle now need to be created:

Image Added

Image Added

The templates for Circle and Square must hold an XmlElement as their root:

Image Added

Then the xml template must be fully constructed:

Image Added

template fragment must be created around the whole xml code:

Image Added

Image Added

The TF symbols indicate the template fragment:

Image Added

Property macros should be used to parametrize the template:

Image Added

The property macro must be further specified in the Inspector so that the correct value is used and converted from integer to string:

Image Added

The same must be repeated for the y xml attribute.

For radius, we will use a dedicated xml element:

Image Added

Image Added

And quire similarly for the color reference:

Image Added

The template for Square will be very similar:

Image Added

The generator should be holding four root nodes now:

Image Added

When you rebuild your language and preview the generated code for your sandbox, you should be getting an xml file similar to this:

Image Added

What to do next

Congratulations! You've just completed your introductory tutorial into MPS.

...