tengri/dsl/README.md
2025-08-23 13:10:59 +03:00

68 lines
2.1 KiB
Markdown

[***dizzle***](https://codeberg.org/unspeaker/tengri/src/branch/main/dsl)
is a means of adding a tiny interpreted domain-specific language to your programs.
dizzle currently provides an s-expression based syntax.
dizzle parses source code by means of the `Dsl`, `DslExpr` and `DslWord` traits.
those are implemented for basic stringy types and their `Option` and `Result` wrapped analogs.
to customize parsing, define and use your own traits on top of the provided ones.
dizzle evaluates the parsed source code by means of the `DslNs` trait. the methods of
this trait match literals, words, and expressions, against pre-defined lists. the
`dsl_words` and `dsl_exprs` macros let you define those lists slightly less verbosely.
## goals
* [x] const parse
* [ ] live reload
* [ ] serialize modified code back to original indentation
## examples
### in [`tengri_output`](../output)
```edn
(bsp/s (fixed/y 2 :toolbar)
(fill/x (align/c (bsp/w :pool
(bsp/s :outputs (bsp/s :inputs (bsp/s :tracks :scenes)))))))
```
### in [`tengri_input`](../input)
```edn
(@u undo 1)
(@shift-u redo 1)
(@e editor show :pool-clip)
(@ctrl-a scene add)
(@ctrl-t track add)
(@tab pool toggle)
```
## implementation notes
### `DslExpr` trait behavior
this is the trait which differentiates "a thing" from
"a thing that is many things".
|source |key|exp |head |tail |
|---------------|---|-------|---------|---------------|
|`a` |`a`|e0 |`a` |None |
|`(a)` |e1 |`a` |`(a)` |None |
|`a b c` |e2 |e0 |`a` |`b c` |
|`(a b c)` |e1 |`a b c`|`(a b c)`| |
|`(a b c) d e` |e1 |e3 |`(a b c)`|`d e` |
|`a (b c d) e f`|e1 |e0 |`a` |`(b c d) e f` |
* e0: Unexpected 'a'
* e1: Unexpected '('
* e2: Unexpected 'b'
* e3: Unexpected 'd'
### possible design for operator-based syntax
* replace: `(:= :name :value1 :valueN)`
* append: `(:+ :name :value2 :valueN)`
* filter: `(:- :name :value2 :valueN)`
* map: `(:* :name op)`
* reduce: `(:/ :name op)`