diff options
Diffstat (limited to 'doc/docs/zh')
| -rw-r--r-- | doc/docs/zh/doc/advanced/macro.md | 142 |
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 |   更多关于可用 AST 节点的详细信息,请参考 [yue_parser.cpp](https://github.com/IppClub/YueScript/blob/main/src/yuescript/yue_parser.cpp) 中大写的规则定义。 | 340 |   更多关于可用 AST 节点的详细信息,请参考 [yue_parser.cpp](https://github.com/IppClub/YueScript/blob/main/src/yuescript/yue_parser.cpp) 中大写的规则定义。 |
| 341 | |||
| 342 | ## 注解语句 | ||
| 343 | |||
| 344 |   注解语句会把一个宏应用到它后面的那条语句上。 | ||
| 345 | |||
| 346 |   这等价于调用该宏,并把后面那条语句的源码作为最后一个参数附加进去。 | ||
| 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 |   如果注解宏返回的是配置表,可选字段 `before` 可以控制生成结果插入到被注解语句之前还是之后。 | ||
| 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 |   由于后面的语句会作为额外的宏参数传入,注解也可以从类声明生成注册代码。它同样可以使用普通宏支持的 AST 参数检查。 | ||
| 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 |   注解也可以用来给函数注入包装代码。 | ||
| 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 |   注解后面必须紧跟一条语句,而且不能作用在 `return` 语句上。如果被注解的语句正好位于代码块末尾,而你又需要拿到原始的语句 AST 形态,就需要额外补一个显式的 `return`,避免它被隐式返回表达式包起来。 | ||
