aboutsummaryrefslogtreecommitdiff
path: root/doc/docs/zh
diff options
context:
space:
mode:
Diffstat (limited to 'doc/docs/zh')
-rw-r--r--doc/docs/zh/doc/advanced/macro.md142
1 files changed, 142 insertions, 0 deletions
diff --git a/doc/docs/zh/doc/advanced/macro.md b/doc/docs/zh/doc/advanced/macro.md
index 5110571..0d7ee6d 100644
--- a/doc/docs/zh/doc/advanced/macro.md
+++ b/doc/docs/zh/doc/advanced/macro.md
@@ -338,3 +338,145 @@ $printNumAndStr 123, "hello"
338</YueDisplay> 338</YueDisplay>
339 339
340&emsp;&emsp;更多关于可用 AST 节点的详细信息,请参考 [yue_parser.cpp](https://github.com/IppClub/YueScript/blob/main/src/yuescript/yue_parser.cpp) 中大写的规则定义。 340&emsp;&emsp;更多关于可用 AST 节点的详细信息,请参考 [yue_parser.cpp](https://github.com/IppClub/YueScript/blob/main/src/yuescript/yue_parser.cpp) 中大写的规则定义。
341
342## 注解语句
343
344&emsp;&emsp;注解语句会把一个宏应用到它后面的那条语句上。
345
346&emsp;&emsp;这等价于调用该宏,并把后面那条语句的源码作为最后一个参数附加进去。
347
348```yuescript
349macro ShowName = (code) -> |
350 print "#{code\match '^[%w_]*'}"
351
352$[ShowName]
353myFunc = ->
354
355return
356```
357
358<YueDisplay>
359
360```yue
361macro ShowName = (code) -> |
362 print "#{code\match '^[%w_]*'}"
363
364$[ShowName]
365myFunc = ->
366
367return
368```
369
370</YueDisplay>
371
372&emsp;&emsp;如果注解宏返回的是配置表,可选字段 `before` 可以控制生成结果插入到被注解语句之前还是之后。
373
374```yuescript
375macro 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]
383tableA = {}
384
385$[Tag after]
386tableB = {}
387
388return
389```
390
391<YueDisplay>
392
393```yue
394macro 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]
402tableA = {}
403
404$[Tag after]
405tableB = {}
406
407return
408```
409
410</YueDisplay>
411
412&emsp;&emsp;由于后面的语句会作为额外的宏参数传入,注解也可以从类声明生成注册代码。它同样可以使用普通宏支持的 AST 参数检查。
413
414```yuescript
415macro Register = (registry, code`ClassDecl) ->
416 className = code\match "^class%s+(%w+)"
417 return |
418 #{registry}["#{className}"] = #{className}
419
420registry = {}
421
422$[Register(registry)]
423class Worker
424 run: => "ok"
425
426return
427```
428
429<YueDisplay>
430
431```yue
432macro Register = (registry, code`ClassDecl) ->
433 className = code\match "^class%s+(%w+)"
434 return |
435 #{registry}["#{className}"] = #{className}
436
437registry = {}
438
439$[Register(registry)]
440class Worker
441 run: => "ok"
442
443return
444```
445
446</YueDisplay>
447
448&emsp;&emsp;注解也可以用来给函数注入包装代码。
449
450```yuescript
451macro 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]
461add = (a, b) -> a + b
462```
463
464<YueDisplay>
465
466```yue
467macro 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]
477add = (a, b) -> a + b
478```
479
480</YueDisplay>
481
482&emsp;&emsp;注解后面必须紧跟一条语句,而且不能作用在 `return` 语句上。如果被注解的语句正好位于代码块末尾,而你又需要拿到原始的语句 AST 形态,就需要额外补一个显式的 `return`,避免它被隐式返回表达式包起来。