Mindustry Compiler
Angular • Typescript • GCP • TDD
Developed an app to parse a higher level language and convert it into assembly-like instructions.
Uses Antlr4TS to generate an AST and visitor pattern to convert to instruction lines.
Uses the Monaco Editor (backbone of VSCode) for syntax highlighting, parsing errors, and diffing.
Auth and save files with Google Firestore. Document updates trigger a cloud function which maintains the document's history.
Mindustry is a factory-building game with tower defense and RTS elements. An advanced part of the late game is the ability to fully control units with an assembly-like programming language.
I was familiar with programming languages, grammars, and implementing interpreters from college classes, and thought it would be fun to create a program that would convert higher level code into the mindustry-assembly.
I defined an ANTLR grammar file for my language MinLang, which Antlr4Ts uses to generate code that parses text into tokens. Then passing those to a Visitor Pattern I implemented which generates an Abstract Syntax Tree out of nodes I defined that have a compile() function, which turns it into the corresponding Mindustry-Assembly command. Branching and Looping nodes have additional logic to inject JUMP commands.
Try it out: https://mindustry-compiler.web.app/code
⚠ New files seem like they might work but don’t actually work correctly if you don’t log in. Some other small bugs and unintuitive UI. No ability to delete files. The fancy UI, Monaco Editor, and Google Cloud integrations were all afterthoughts once the compiler was finished, and I didn’t know the scope and time commitment of what I was getting into. Almost everything in this project was brand new to me, even type/javascript was pretty unfamiliar to me.
Source: https://gitlab.com/ciph3rzer0/mindustry-compiler
Grammar def: https://gitlab.com/ciph3rzer0/mindustry-compiler/-/blob/master/src/antlr/min/MinLang.g4
Visitor Pattern: https://gitlab.com/ciph3rzer0/mindustry-compiler/-/blob/master/src/antlr/min/MinLangVisitor.ts
AST Nodes: https://gitlab.com/ciph3rzer0/mindustry-compiler/-/blob/master/src/antlr/min/MinLogic.ts
Skills Developed
Learned Javascript/Typescript, Node, NPM, and Angular.
Test-Driven Development - Full test coverage of all expressions.
Reading documentation and integrating external code. For Monaco, Angular, and Firebase.
Redux state management using NGRX for auth and open files.
Technology
Angular for reactive Single Page Application.
NGRX to maintain user auth and open file state. (Angular's version of Redux)
Tailwind CSS for quick, inline styles.
Google Cloud for User authentication, NoSQL document store, and Cloud functions (to create old versions when files are saved)
Antlr4TS to define the grammar and turn it into an Abstract Syntax Tree.
Integrated Monaco Editor (The open source engine behind VS Code).
Showcase:
The starting page shows all files you've saved. You can click on any of them to open it in a new tab, or create a new file.
We get nice syntax highlighting by passing symbol definitions to Monaco. Clicking "Compile" on the left will show a textfield on the right with the compiled instructions that should be pasted into Mindustry.
The Monaco Editor does not handle tabs, so I created tabs in Angular and sync’d them with monaco editor or monaco diff-editor references. Tabs can be closed by clicking the X or dragged to rearrange.
Files are saved in Google Firestore. A cloud function triggers on record update which maintains a file history. You can click on the versions listed on the left to see past versions.
When you're done editing, click "Diff and Save" to see this confirmation page, utilizing Monaco Diff Editor and a fancy custom widget across the top of the screen for semantic versioning.
This is a neat little widget I developed.
It Automatically handles Semantic Versioning for you. Just click on the bubble of the major/minor/patch digits to increment them.