@@ -60,7 +60,7 @@ Traditional DSL approaches have trade-offs:
6060
6161Leverage ` zrtl_paint ` and ` zrtl_window ` to create a Processing/p5.js-style creative coding language:
6262
63- ```
63+ ``` text
6464// sketch.art - Creative coding DSL
6565
6666canvas 800 600
@@ -89,26 +89,50 @@ line 0 550 800 550
8989 entry_point: "sketch_main"
9090}
9191
92+ // Map DSL builtins to ZRTL symbols
93+ @builtin {
94+ canvas_create: "$Paint$canvas_create",
95+ fill_circle: "$Paint$fill_circle",
96+ fill_rect: "$Paint$fill_rect",
97+ set_color: "$Paint$rgb",
98+ }
99+
92100canvas_stmt = { "canvas" ~ integer ~ integer }
93101 -> TypedStatement {
94- "call_runtime": "$Paint$canvas_create",
95- "args": ["$1", "$2"],
96- "store_result": "canvas"
102+ "commands": [
103+ { "define": "var_decl", "args": {
104+ "name": "canvas",
105+ "value": { "define": "call", "args": {
106+ "callee": "canvas_create",
107+ "args": ["$1", "$2"]
108+ }}
109+ }}
110+ ]
97111 }
98112
99113fill_stmt = { "fill" ~ color }
100114 -> TypedStatement {
101- "call_runtime": "$Paint$set_fill_color",
102- "args": ["canvas", "$color"]
115+ "commands": [
116+ { "define": "var_decl", "args": {
117+ "name": "fill_color",
118+ "value": "$1"
119+ }}
120+ ]
103121 }
104122
105123circle_stmt = { "circle" ~ expr ~ expr ~ expr }
106124 -> TypedStatement {
107- "call_runtime": "$Paint$fill_circle",
108- "args": ["canvas", "$1", "$2", "$3", "fill_color"]
125+ "commands": [
126+ { "define": "call", "args": {
127+ "callee": "fill_circle",
128+ "args": ["canvas", "$1", "$2", "$3", "fill_color"]
129+ }}
130+ ]
109131 }
110132```
111133
134+ The grammar builds TypedAST nodes (` var_decl ` , ` call ` ) that reference ` @builtin ` symbols. During compilation, these resolve to ZRTL plugin functions like ` $Paint$fill_circle ` .
135+
112136** Running the DSL:**
113137
114138``` rust
@@ -138,7 +162,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
138162
139163Create a language for ETL and data transformation:
140164
141- ```
165+ ``` text
142166// pipeline.flow - Data transformation DSL
143167
144168source "data/sales.csv" as sales
@@ -164,6 +188,7 @@ output "reports/summary.json"
164188```
165189
166190** Leveraging ZRTL plugins:**
191+
167192- ` zrtl_fs ` for file I/O
168193- ` zrtl_json ` for JSON parsing/generation
169194- ` zrtl_string ` for text manipulation
@@ -173,7 +198,7 @@ output "reports/summary.json"
173198
174199A simplified HDL for education or prototyping:
175200
176- ```
201+ ``` text
177202// counter.hdl - Hardware description
178203
179204module counter(clk: clock, reset: bit, out: bits[8]) {
@@ -195,7 +220,7 @@ module counter(clk: clock, reset: bit, out: bits[8]) {
195220
196221A language for game logic with built-in entity/component concepts:
197222
198- ```
223+ ``` text
199224// player.game - Game entity script
200225
201226entity Player {
@@ -217,6 +242,7 @@ entity Player {
217242```
218243
219244** Runtime using ZRTL:**
245+
220246- ` zrtl_window ` for windowing/input
221247- ` zrtl_paint ` for 2D rendering
222248- ` zrtl_image ` for sprite loading
@@ -226,7 +252,7 @@ entity Player {
226252
227253A type-safe configuration language:
228254
229- ```
255+ ``` text
230256// app.config - Typed configuration
231257
232258database {
@@ -268,59 +294,89 @@ Let's build a simple **charting DSL** that generates visualizations:
268294 entry_point: "render_chart"
269295}
270296
297+ // Map builtins to chart plugin symbols
298+ @builtin {
299+ chart_set_type: "$Chart$set_type",
300+ chart_set_title: "$Chart$set_title",
301+ chart_add_data: "$Chart$add_data",
302+ chart_set_style: "$Chart$set_style",
303+ chart_render: "$Chart$render",
304+ }
305+
271306// Entry point
272307program = { SOI ~ chart_definition ~ EOI }
273- -> TypedModule {
274- "create_main": "render_chart",
275- "body": "$chart_definition"
308+ -> TypedProgram {
309+ "get_child": { "index": 0 }
276310 }
277311
278312chart_definition = { chart_type ~ title? ~ data_section ~ style_section? }
279- -> TypedFunction {
280- "name": "render_chart",
281- "body": ["$chart_type", "$title", "$data_section", "$style_section"]
313+ -> TypedDeclaration {
314+ "commands": [
315+ { "define": "function", "args": {
316+ "name": "render_chart",
317+ "params": [],
318+ "return_type": "void",
319+ "body": { "get_all_children": true }
320+ }}
321+ ]
282322 }
283323
284324chart_type = { ("bar" | "line" | "pie") ~ "chart" }
285325 -> TypedStatement {
286- "call_runtime": "$Chart$set_type",
287- "args": ["$1"]
326+ "commands": [
327+ { "define": "call", "args": {
328+ "callee": "chart_set_type",
329+ "args": [{ "get_text": true }]
330+ }}
331+ ]
288332 }
289333
290334title = { "title" ~ string_literal }
291335 -> TypedStatement {
292- "call_runtime": "$Chart$set_title",
293- "args": ["$string_literal"]
336+ "commands": [
337+ { "define": "call", "args": {
338+ "callee": "chart_set_title",
339+ "args": ["$1"]
340+ }}
341+ ]
294342 }
295343
296344data_section = { "data" ~ "{" ~ data_point* ~ "}" }
297345 -> TypedBlock {
298- "statements ": "$data_point"
346+ "get_all_children ": true
299347 }
300348
301349data_point = { string_literal ~ ":" ~ number }
302350 -> TypedStatement {
303- "call_runtime": "$Chart$add_data",
304- "args": ["$string_literal", "$number"]
351+ "commands": [
352+ { "define": "call", "args": {
353+ "callee": "chart_add_data",
354+ "args": ["$1", "$2"]
355+ }}
356+ ]
305357 }
306358
307359style_section = { "style" ~ "{" ~ style_prop* ~ "}" }
308360 -> TypedBlock {
309- "statements ": "$style_prop"
361+ "get_all_children ": true
310362 }
311363
312364style_prop = { identifier ~ ":" ~ (color | number | string_literal) }
313365 -> TypedStatement {
314- "call_runtime": "$Chart$set_style",
315- "args": ["$identifier", "$2"]
366+ "commands": [
367+ { "define": "call", "args": {
368+ "callee": "chart_set_style",
369+ "args": ["$1", "$2"]
370+ }}
371+ ]
316372 }
317373
318374// Terminals
319375string_literal = @{ "\"" ~ (!"\"" ~ ANY)* ~ "\"" }
320- -> String { "get_text": true, "trim_quotes": true }
376+ -> String { "get_text": true }
321377
322378number = @{ "-"? ~ ASCII_DIGIT+ ~ ("." ~ ASCII_DIGIT+)? }
323- -> Number { "get_text": true, " parse_float": true }
379+ -> Number { "parse_float": true }
324380
325381color = @{ "#" ~ ASCII_HEX_DIGIT{6} }
326382 -> Color { "get_text": true }
@@ -425,7 +481,7 @@ zrtl_plugin! {
425481
426482### Step 3: Write DSL Programs
427483
428- ```
484+ ``` text
429485// sales_report.chart
430486
431487bar chart
@@ -536,7 +592,7 @@ zrtl_plugin! {
536592}
537593```
538594
539- ```
595+ ``` text
540596// In your DSL
541597user = App.get_user()
542598if user.is_admin {
@@ -574,7 +630,7 @@ Don't reinvent the wheel. ZRTL provides:
574630
575631Your DSL syntax should be intuitive for domain experts:
576632
577- ```
633+ ``` text
578634// Good: Reads like natural language
579635send email to "[email protected] " with subject "Hello" 580636
0 commit comments