https://github.com/n0bra1n3r/mast
A simple DSL for defining abstract syntax trees in Nim
https://github.com/n0bra1n3r/mast
abstract-syntax-tree ast domain-specific-language dsl macros nim nim-lang
Last synced: 12 months ago
JSON representation
A simple DSL for defining abstract syntax trees in Nim
- Host: GitHub
- URL: https://github.com/n0bra1n3r/mast
- Owner: n0bra1n3r
- Created: 2021-11-13T11:40:09.000Z (over 4 years ago)
- Default Branch: staging
- Last Pushed: 2024-09-07T03:37:28.000Z (almost 2 years ago)
- Last Synced: 2025-07-13T15:42:42.745Z (12 months ago)
- Topics: abstract-syntax-tree, ast, domain-specific-language, dsl, macros, nim, nim-lang
- Language: Nim
- Homepage:
- Size: 26.4 KB
- Stars: 6
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# mast

A simple DSL for defining abstract syntax trees in [Nim](https://nim-lang.org/).
This project was directly inspired by the [breeze](https://github.com/alehander92/breeze)
library.
## Overview
This library provides another way to write Nim [macros](https://nim-lang.org/docs/macros.html)
more closely following the output of [`treeRepr`](https://nim-lang.org/docs/macros.html#treeRepr%2CNimNode).
## Showcase
Please **see [tests](tests/)** for examples of most features. This section
provides an incomplete summary of the core functionality.
### Basic example
The following is an example usage:
```nim
import mast
macro makeMain(say: static string) =
ast:
ProcDef:
`main`
Empty
Empty
FormalParams:
Empty
Empty
Empty
StmtList:
Command:
`echo`
"Hello macro!"
Command:
`echo`
(lit say)
makeMain "Hello world!"
```
```nim
# `makeMain` expands to:
proc main() =
echo "Hello macro!"
echo "Hello world!"
```
Notice that most elements in the AST definition correspond to their `nnk*`
[NimNode](https://nim-lang.org/docs/macros.html#NimNodeKind) counterparts.
Exceptions to this pattern are the following:
* Identifiers which are enclosed in backticks ("`")
* Literals which are simply specified in the AST definition as-is
* External expressions which are embedded in the AST by enclosing them in
parentheses
### Identifiers
Under the hood mast uses the [`fmt`](https://nim-lang.org/docs/strformat.html#fmt.m%2Cstaticstring%2Cstaticchar%2Cstaticchar)
macro to parse identifier names. This means that identifier names can be
composed using the following syntax:
```nim
let i = 1
let newIdent = ast`ident{i}` # generates `Ident "ident1"`
```
Bound symbols can be specified by using the `sym` macro:
```nim
let boundSym = ast (sym someDeclaredSymbol)
```
Lastly, new symbols can be generated using the following syntax:
```nim
let genSymed = ast (sym Proc`someProcSymbol`)
```
The `Proc` symbol here corresponds to [`nskProc`](https://nim-lang.org/docs/macros.html#NimSymKind),
and the symbol inside the backticks can be interpolated in the same way as
identifiers.
## Installing
The package can be installed by following the nimble instructions
[here](https://github.com/nim-lang/nimble#nimble-install).
## Usage
Simply import mast into your module to start using it.
## Contributing
This project is maintained during my free time, and serves as a tool for a game
engine I am writing after work hours. Contributions are welcome, and I will
merge them immediately if they serve to keep the project robust, simple, and
maintainable.
**Cheers and happy coding!** 🍺