You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Weitere Details zu verfügbaren AST-Knoten findest du in den großgeschriebenen Definitionen in `yue_parser.cpp`.
341
+
342
+
## Annotation-Anweisungen
343
+
344
+
Annotation-Anweisungen wenden ein Makro auf die direkt folgende Anweisung an.
345
+
346
+
Das entspricht einem Makroaufruf, bei dem der Quelltext der folgenden Anweisung als letztes Argument zusätzlich übergeben wird.
347
+
348
+
```yuescript
349
+
macro ShowName = (code) -> |
350
+
print "#{code\match '^[%w_]*'}"
351
+
352
+
$[ShowName]
353
+
myFunc = ->
354
+
355
+
return
356
+
```
357
+
358
+
<YueDisplay>
359
+
360
+
```yue
361
+
macro ShowName = (code) -> |
362
+
print "#{code\match '^[%w_]*'}"
363
+
364
+
$[ShowName]
365
+
myFunc = ->
366
+
367
+
return
368
+
```
369
+
370
+
</YueDisplay>
371
+
372
+
Wenn das Annotationsmakro eine Konfigurationstabelle zurückgibt, steuert das optionale Feld `before`, ob das Ergebnis vor oder nach der annotierten Anweisung eingefügt wird.
373
+
374
+
```yuescript
375
+
macro Tag = (tag, code) ->
376
+
tableName = code\match "^[%w_]+"
377
+
return
378
+
type: "text"
379
+
before: tag == "before"
380
+
code: "-- #{tag}:#{tableName}"
381
+
382
+
$[Tag before]
383
+
tableA = {}
384
+
385
+
$[Tag after]
386
+
tableB = {}
387
+
388
+
return
389
+
```
390
+
391
+
<YueDisplay>
392
+
393
+
```yue
394
+
macro Tag = (tag, code) ->
395
+
tableName = code\match "^[%w_]+"
396
+
return
397
+
type: "text"
398
+
before: tag == "before"
399
+
code: "-- #{tag}:#{tableName}"
400
+
401
+
$[Tag before]
402
+
tableA = {}
403
+
404
+
$[Tag after]
405
+
tableB = {}
406
+
407
+
return
408
+
```
409
+
410
+
</YueDisplay>
411
+
412
+
Da die folgende Anweisung als zusätzliches Makroargument übergeben wird, lassen sich mit Annotationen auch direkt Registrierungszeilen aus Klassendeklarationen erzeugen. Du kannst dabei dieselben AST-Argumentprüfungen wie bei normalen Makros verwenden.
413
+
414
+
```yuescript
415
+
macro Register = (registry, code`ClassDecl) ->
416
+
className = code\match "^class%s+(%w+)"
417
+
return |
418
+
#{registry}["#{className}"] = #{className}
419
+
420
+
registry = {}
421
+
422
+
$[Register(registry)]
423
+
class Worker
424
+
run: => "ok"
425
+
426
+
return
427
+
```
428
+
429
+
<YueDisplay>
430
+
431
+
```yue
432
+
macro Register = (registry, code`ClassDecl) ->
433
+
className = code\match "^class%s+(%w+)"
434
+
return |
435
+
#{registry}["#{className}"] = #{className}
436
+
437
+
registry = {}
438
+
439
+
$[Register(registry)]
440
+
class Worker
441
+
run: => "ok"
442
+
443
+
return
444
+
```
445
+
446
+
</YueDisplay>
447
+
448
+
Annotationen können auch Wrapper-Code um Funktionen herum einfügen:
449
+
450
+
```yuescript
451
+
macro ValidateNumberArgs = (code) ->
452
+
funcName = code\match "^(%w+)%s*="
453
+
return |
454
+
local __orig_#{funcName} = #{funcName}
455
+
#{funcName} = (...) ->
456
+
for i = 1, select "#", ...
457
+
assert type(select i, ...) == "number", "expected number for arg \#{i}"
458
+
__orig_#{funcName} ...
459
+
460
+
$[ValidateNumberArgs]
461
+
add = (a, b) -> a + b
462
+
```
463
+
464
+
<YueDisplay>
465
+
466
+
```yue
467
+
macro ValidateNumberArgs = (code) ->
468
+
funcName = code\match "^(%w+)%s*="
469
+
return |
470
+
local __orig_#{funcName} = #{funcName}
471
+
#{funcName} = (...) ->
472
+
for i = 1, select "#", ...
473
+
assert type(select i, ...) == "number", "expected number for arg \#{i}"
474
+
__orig_#{funcName} ...
475
+
476
+
$[ValidateNumberArgs]
477
+
add = (a, b) -> a + b
478
+
```
479
+
480
+
</YueDisplay>
481
+
482
+
Auf eine Annotation muss immer eine Anweisung folgen, und sie kann nicht auf eine `return`-Anweisung angewendet werden. Wenn die annotierte Anweisung am Ende eines Blocks steht und du die rohe AST-Form der Anweisung brauchst, füge ein explizites `return` danach ein, damit sie nicht in einen implizit zurückgegebenen Ausdruck eingebettet wird.
Copy file name to clipboardExpand all lines: doc/docs/doc/advanced/macro.md
+152-1Lines changed: 152 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -68,7 +68,7 @@ if $and f1!, f2!, f3!
68
68
69
69
## Insert Raw Codes
70
70
71
-
A macro function can either return a YueScript string or a config table containing Lua codes.
71
+
A macro function can either return a YueScript string or a config table containing generated code.
72
72
73
73
```yuescript
74
74
macro yueFunc = (var) -> "local #{var} = ->"
@@ -126,6 +126,15 @@ end
126
126
127
127
</YueDisplay>
128
128
129
+
The returned table can be used to control how the generated code gets inserted.
130
+
131
+
-`code` is the generated text.
132
+
-`type` chooses how the text is handled. It can be `"yue"` (the default), `"lua"`, or `"text"`.
133
+
-`locals` declares local names introduced by inserted text.
134
+
-`before` puts the generated result before the annotated statement instead of after it.
135
+
136
+
In most cases you only need to choose a `type`. Use `"yue"` for generated YueScript, `"lua"` for raw Lua, and `"text"` for text that should be copied straight into the final output.
137
+
129
138
## Export Macro
130
139
131
140
Macro functions can be exported from a module and get imported in another module. You have to put export macro functions in a single file to be used, and only macro definition, macro importing and macro expansion in place can be put into the macro exporting module.
For more details about available AST nodes, please refer to the uppercased definitions in [yue_parser.cpp](https://github.com/IppClub/YueScript/blob/main/src/yuescript/yue_parser.cpp).
350
+
351
+
## Annotation Statements
352
+
353
+
Annotation statements apply a macro to the statement immediately following them.
354
+
355
+
This is equivalent to calling the macro with the following statement's source text appended as the last argument.
356
+
357
+
```yuescript
358
+
macro ShowName = (code) -> |
359
+
print "#{code\match '^[%w_]*'}"
360
+
361
+
$[ShowName]
362
+
myFunc = ->
363
+
364
+
return
365
+
```
366
+
367
+
<YueDisplay>
368
+
369
+
```yue
370
+
macro ShowName = (code) -> |
371
+
print "#{code\match '^[%w_]*'}"
372
+
373
+
$[ShowName]
374
+
myFunc = ->
375
+
376
+
return
377
+
```
378
+
379
+
</YueDisplay>
380
+
381
+
When the annotation macro returns a config table, the optional `before` field controls whether the generated result is emitted before or after the annotated statement.
382
+
383
+
```yuescript
384
+
macro Tag = (tag, code) ->
385
+
tableName = code\match "^[%w_]+"
386
+
return
387
+
type: "text"
388
+
before: tag == "before"
389
+
code: "-- #{tag}:#{tableName}"
390
+
391
+
$[Tag before]
392
+
tableA = {}
393
+
394
+
$[Tag after]
395
+
tableB = {}
396
+
397
+
return
398
+
```
399
+
400
+
<YueDisplay>
401
+
402
+
```yue
403
+
macro Tag = (tag, code) ->
404
+
tableName = code\match "^[%w_]+"
405
+
return
406
+
type: "text"
407
+
before: tag == "before"
408
+
code: "-- #{tag}:#{tableName}"
409
+
410
+
$[Tag before]
411
+
tableA = {}
412
+
413
+
$[Tag after]
414
+
tableB = {}
415
+
416
+
return
417
+
```
418
+
419
+
</YueDisplay>
420
+
421
+
Because the followed statement is passed in as an extra macro argument, annotations can also be used to generate registration code from class declarations. Because the followed statement is passed in as an extra macro argument, you can use the same AST argument checks as normal macros:
422
+
423
+
```yuescript
424
+
macro Register = (registry, code`ClassDecl) ->
425
+
className = code\match "^class%s+(%w+)"
426
+
return |
427
+
#{registry}["#{className}"] = #{className}
428
+
429
+
registry = {}
430
+
431
+
$[Register(registry)]
432
+
class Worker
433
+
run: => "ok"
434
+
435
+
return
436
+
```
437
+
438
+
<YueDisplay>
439
+
440
+
```yue
441
+
macro Register = (registry, code`ClassDecl) ->
442
+
className = code\match "^class%s+(%w+)"
443
+
return |
444
+
#{registry}["#{className}"] = #{className}
445
+
446
+
registry = {}
447
+
448
+
$[Register(registry)]
449
+
class Worker
450
+
run: => "ok"
451
+
452
+
return
453
+
```
454
+
455
+
</YueDisplay>
456
+
457
+
Annotations can also inject wrapper code around functions:
458
+
459
+
```yuescript
460
+
macro ValidateNumberArgs = (code) ->
461
+
funcName = code\match "^(%w+)%s*="
462
+
return |
463
+
local __orig_#{funcName} = #{funcName}
464
+
#{funcName} = (...) ->
465
+
for i = 1, select "#", ...
466
+
assert type(select i, ...) == "number", "expected number for arg \#{i}"
467
+
__orig_#{funcName} ...
468
+
469
+
$[ValidateNumberArgs]
470
+
add = (a, b) -> a + b
471
+
```
472
+
473
+
<YueDisplay>
474
+
475
+
```yue
476
+
macro ValidateNumberArgs = (code) ->
477
+
funcName = code\match "^(%w+)%s*="
478
+
return |
479
+
local __orig_#{funcName} = #{funcName}
480
+
#{funcName} = (...) ->
481
+
for i = 1, select "#", ...
482
+
assert type(select i, ...) == "number", "expected number for arg \#{i}"
483
+
__orig_#{funcName} ...
484
+
485
+
$[ValidateNumberArgs]
486
+
add = (a, b) -> a + b
487
+
```
488
+
489
+
</YueDisplay>
490
+
491
+
An annotation must always be followed by a statement, and it can not be applied to a `return` statement. If the annotated statement appears at the end of a block, add an explicit trailing `return` when you need the raw statement AST shape instead of an implicitly returned expression.
0 commit comments