---
title: "Blog - How to setup Mbeddr with MPS"
url: https://ad301.org
---
Introduction
JetBrains’ Meta Programming System (MPS) is a tool that allows users to define Domain Specific Languages (DSLs). DSLs are typically small languages that - in contrast to General Purpose Languages (GPLs) - focus on a specific problem domain. A DSL in MPS is converted into a target language using a generator. By default MPS only supports Java as a generation target language. The Mbeddr project aims to provide C as a further target language, however, the setup is quite mystical.
As such, this tutorial serves as a quick reference and step-by-step instruction set to setup a minimal working example of Mbeddr in MPS.
You can open the final working project here!
Disclaimer
If, during this tutorial, you ever think “Wow, this is confusing! Does the author even know how this all really works?”, the answer is most certainly “No!”
I was only able to achieve anything using MPS and Mbeddr thanks to Sergej Koščejev!
This was quickly put together so others may have a minimal starting chance, if you have any feedback please feel free to message me at pilkiad+mps@proton.me.
Step 1 - Download and install MPS
Mbeddr is officially supported for MPS
2018.2. You can download it on the list
of previous versions. The good news is that if you
choose to download the linux application
(tar.gz) the installs are self-contained and
you can download many different MPS versions without fear of
conflicts. Just unpack the tar.gz file and
place it somewhere you will remember.
Step 2 - Download and install Mbeddr
Head on over to the download page of Mbeddr. Once there, you want to click on the link titled “all-plugins”. At the time of writing this tutorial this is the direct link to the file.
You then want to unpack the file
com.mbeddr.allInOne_2018_2_0.zip, the resulting
folder will simply be called plugins. Go ahead
an copy all files and subfolders withing
plugins into the folder of the same name inside
the MPS installation.
Your MPS folder should look somewhat like this:
MPS 2018.2
|- about.txt
|- bin
|- build.number
|- build.properties
|- build.txt
|- jre
|- languages
|- lib
|- license
|- plugins <-- This is where the 'plugins' content should go
|- readme.txt
|- releaseNotes.txt
|- samples.zipNOTE: For me, copying the file
build.properties resulted in IDE errors down
the line, so I left that one out.
Step 3 - Create a hello world
Setup the project
Once Mbeddr has been installed by pasting the files into
the plugins folder, open up MPS 2018.2.
- Click on Create New Project
- Give the project a name, I chose “HelloC”
- Also give the language of your project a name, I chose “HelloCLang”
- Make sure to tick Create Sandbox Solution
- Click OK
Create a basic DSL
We need to create a very basic DSL in order to be able to generate anything. What exactly happens inside the DSL is not to important, we just want a rootable concept so the generator has something to reference.
- Under HelloCLang (the language module) right click structure, click New and then Concept
- Give the concept a name, I chose “HelloC_File”
- Make it implement
INamedConcept, this is just so we can name the file. We later want to use the name as a reference property inside the generated outputs. - Set instance can be root to
true - Give it a property “personToGreet” of type
string
For now, we don’t need to worry about anything more complex (like defining an editor).
Define a basic generator
- Under HelloCLang (the language module) open generator/HelloCLang/main, then main@generator and finally main (or, you know.. I could have said “open the generator”)
- Set top-priority group to
true. This has to be done since Mbeddr apparently has some of their own top-priority mappings that would overwrite the one we are currently creating - Create a mapping label where the name is
“ProgramToModule”, the input concept is “HelloC_File” and
the output concept is “ImplementationModule”. This tells MPS
to apply all rules concerned with converting concepts to C
code (what we are trying to do) to all concepts of type
“HelloC_File”
- NOTE: Your generator will need to import
com.mbeddr.core.modules.structurefor this to work. Select main@generator, press Alt+Enter (to open model properties), go to Dependencies tab, click on + and addcom.mbeddr.core.modules.structure
- NOTE: Your generator will need to import
- We will create a root mapping rule, but we need some
setup
- Go to the model properties of main@generator
again (select, Alt+Enter) and go to Used Languages.
Once there, click on + and add:
com.mbeddr.core.modules(allows us to create modules)com.mbeddr.core.buildconfig(tells Mbeddr how to setup the created binaries)jetbrains.mps.lang.generator(I’m 90% sure this also does.. something)
- Go back to main, under root mapping
rules create a new rule where concept is
“HelloC_File”
- As the output, place your curser on the
and press Alt+Enter to bring up the intentions, select New Root Template and then module (with an “I” as an icon). This is the C module that will be generated from every “HelloC_File” our users create. The text was replaced by the automatically created name “map_HelloC_file”, place the cursor on that. - Open the “Inspector” window (bottom right in the GUI) on “map_HelloC_File”
- Under mapping label in the inspector put “ProgramToModule”. This ensures that the root mapping uses the previously defined rules to conver every “HelloC_File” concept to an “ImplementationModule” that will then be mapped onto “map_HelloC_File”
- As the output, place your curser on the
- You should now have: a root mapping taking “HelloC_File” as input an creating a module “map_HelloC_file”
- Go to the model properties of main@generator
again (select, Alt+Enter) and go to Used Languages.
Once there, click on + and add:
- We can now define the basic C module that will be
generated from every “HelloC_File”
- Open map_HelloC_File (under main@generator)
- Put your cursor on the name
map_HelloC_File, press ALt+Enter and select Add Property Macro- The inspector opens, under value enter
node.name;where the code should go - This ensures the name of the generated
.cand.hfiles is replaced by whatever we called the “HelloC_File”, this is also why we made the “HelloC_File” concept extendINamedConcept
- The inspector opens, under value enter
- Under imports write
<stdio.h> - Further down, create a function. Put your cursor on the
empty line, press Ctrl+Space and type function (and
auto-complete)
- Name the function “main”
- In the “main” function create an
ArbitraryFunctionCall(Ctrl+Space)- As the
calledFunctionNamewrite “puts” - Inside the paranthesis write “Hello, world!” (with the quotation marks) TBD
- As the
- End the “main” function with
return 0;- You will also need to change its signature from
exported void main()toexported int64 main()
- You will also need to change its signature from
- We can now define a build configuration
- Right click main@generator, New, c.m.core.buildconfig and finally BuildConfiguration
- Under Platform press Ctrl+Space and select gnu
- Under Binaries press Ctrl+Space and select
executable
- Select the entire generated block statement, press
Alt+Enter and Add Node Macro
- The macro needs to be
$LOOP$ - Under iteration sequence put
genContext.inputModel.roots(HelloC_File)
- The macro needs to be
- Put the name “Program”, select that name and replace
with property macro
node.name; - Under modules, select “map_HelloC_File”
(Ctrl+Space)
- Select the reference, press Alt+Enter and hit Add Reference Macro
- Under referent put
genContext.get output ProgramToModule for (node);
- Select the entire generated block statement, press
Alt+Enter and Add Node Macro
- To actually use the build configuration head back to
main and create a new conditional root rule
- Just select “BuildConfiguration (main)”
- Great! Final step: we need to specify the generator
priority
- Alt+Enter on the generator/HelloCLang/main
- Go to Dependencies and add
com.mbeddr.core.modules.gen#1758019824472882132(the numbers may be different, I do not know what they mean)- Make sure its Scope is set to
Design
- Make sure its Scope is set to
- Go to Generators priorities
- Click on +
- Double click the left side and select main. This needs to be the one down at the bottom, the deepest one in the hierarchy. None of the above appear to work. So DON’T select HelloCLang/main, or the main that is directly under there but the main that has the symbol of the generator main (I know - very straight forward!)
- Double click the right side and select copyInImportedModules for some reason
- Make sure the Rule is set to
<and NOT to=
Step 4 - Try it out!
Assuming that by some miracle all the steps worked so far and you were able to follow, right click on your language HelloCLang and select Rebuild Language ‘HelloCLang’.
- Right click your sandbox (within
HelloCLang.sandbox, HelloCLang) and click
New and HelloCFile
- Insert a name, I chose “greatName”
- Insert a person to greet, I chose “Lara”
- Right click anywhere in the editor and select Preview Generated Text
If all has gone to plan you should now see:
greatName.cgreatName.hTypeSizeConfiguration (H.sandbox)- and
Makefile
Comments