aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rwxr-xr-xdoc/docs/.vuepress/components/YueCompiler.vue83
-rwxr-xr-xdoc/docs/README.md2
-rwxr-xr-xdoc/docs/doc/README.md744
-rwxr-xr-xdoc/docs/zh/README.md2
-rwxr-xr-xdoc/docs/zh/doc/README.md923
5 files changed, 1415 insertions, 339 deletions
diff --git a/doc/docs/.vuepress/components/YueCompiler.vue b/doc/docs/.vuepress/components/YueCompiler.vue
index 6b6042c..3a22d1c 100755
--- a/doc/docs/.vuepress/components/YueCompiler.vue
+++ b/doc/docs/.vuepress/components/YueCompiler.vue
@@ -1,21 +1,21 @@
1<template> 1<template>
2 <div style="width: 100%; height: auto;"> 2 <div style="width: 100%; height: auto;">
3 <div class="parent" style="background-color: #f5f7ff;"> 3 <div class="parent" style="background-color: #f5f7ff;">
4 <div class="childL" style="height: 2.5em;"> 4 <div class="editor-section">
5 <div class="childTitle">YueScript {{ info }}</div> 5 <div class="childTitle">YueScript {{ info }}</div>
6 <div class="editor-container" ref='yueEditor'>
7 <ClientOnly>
8 <prism-editor class="my-editor" v-model="code" :highlight="highlighterYue" @input="codeChanged($event)" line-numbers :readonly="readonly"></prism-editor>
9 </ClientOnly>
10 </div>
6 </div> 11 </div>
7 <div class="childR" style="height: 2.5em;"> 12 <div class="editor-section">
8 <div class="childTitle">Lua</div> 13 <div class="childTitle">Lua</div>
9 </div> 14 <div class="editor-container">
10 <div class="childL" ref='yueEditor' style="height: 30em;"> 15 <ClientOnly>
11 <ClientOnly> 16 <prism-editor class="my-editor" v-model="compiled" :highlight="highlighterLua" @input="codeChanged($event)" :line-numbers="isMobileLayout" readonly></prism-editor>
12 <prism-editor class="my-editor" v-model="code" :highlight="highlighterYue" @input="codeChanged($event)" line-numbers :readonly="readonly"></prism-editor> 17 </ClientOnly>
13 </ClientOnly> 18 </div>
14 </div>
15 <div class="childR" style="height: 30em;">
16 <ClientOnly>
17 <prism-editor class="my-editor" v-model="compiled" :highlight="highlighterLua" @input="codeChanged($event)" readonly></prism-editor>
18 </ClientOnly>
19 </div> 19 </div>
20 </div> 20 </div>
21 <div v-if="!compileronly"> 21 <div v-if="!compileronly">
@@ -57,9 +57,18 @@
57 code: '', 57 code: '',
58 compiled: '', 58 compiled: '',
59 result: '', 59 result: '',
60 windowWidth: 0,
60 }; 61 };
61 }, 62 },
63 computed: {
64 isMobileLayout() {
65 return this.windowWidth <= 768;
66 },
67 },
62 mounted () { 68 mounted () {
69 this.windowWidth = window.innerWidth;
70 window.addEventListener('resize', this.handleResize);
71
63 if (this.text !== '') { 72 if (this.text !== '') {
64 this.$data.code = this.text; 73 this.$data.code = this.text;
65 this.codeChanged(this.text); 74 this.codeChanged(this.text);
@@ -86,7 +95,13 @@
86 })(this); 95 })(this);
87 check(); 96 check();
88 }, 97 },
98 beforeDestroy() {
99 window.removeEventListener('resize', this.handleResize);
100 },
89 methods: { 101 methods: {
102 handleResize() {
103 this.windowWidth = window.innerWidth;
104 },
90 runCode() { 105 runCode() {
91 if (window.yue && this.$data.compiled !== '') { 106 if (window.yue && this.$data.compiled !== '') {
92 let res = ''; 107 let res = '';
@@ -136,27 +151,35 @@
136 resize: none; 151 resize: none;
137 margin-top: 5px; 152 margin-top: 5px;
138 } 153 }
139 .childL { 154
140 float: left; 155 .parent {
141 width: 50%; 156 display: flex;
142 box-sizing: border-box; 157 flex-wrap: wrap;
143 background-clip: content-box; 158 width: 100%;
144 background: #f5f7ff;
145 } 159 }
146 .childR { 160
147 float: left; 161 .editor-section {
148 width: 50%; 162 width: 50%;
149 box-sizing: border-box; 163 box-sizing: border-box;
150 background-clip: content-box;
151 background: #f5f7ff; 164 background: #f5f7ff;
152 } 165 }
166
167 .editor-container {
168 height: 55vh;
169 }
170
153 .childTitle { 171 .childTitle {
154 width: 100%; 172 width: 100%;
155 font-size: 1.2em; 173 font-size: 1.2em;
156 color: #b7ae8f; 174 color: #b7ae8f;
157 text-align: center; 175 text-align: center;
158 padding: 0.2em; 176 padding: 0.2em;
177 height: 2.5em;
178 display: flex;
179 align-items: center;
180 justify-content: center;
159 } 181 }
182
160 .button { 183 .button {
161 float: right; 184 float: right;
162 border: none; 185 border: none;
@@ -173,9 +196,11 @@
173 margin-top: 10px; 196 margin-top: 10px;
174 margin-right: 5px; 197 margin-right: 5px;
175 } 198 }
199
176 .button:hover { 200 .button:hover {
177 background-color: #beb69a; 201 background-color: #beb69a;
178 } 202 }
203
179 .button:focus, 204 .button:focus,
180 .button:active:focus, 205 .button:active:focus,
181 .button.active:focus, 206 .button.active:focus,
@@ -207,5 +232,19 @@
207 .my-editor >>> .prism-editor__textarea:focus { 232 .my-editor >>> .prism-editor__textarea:focus {
208 outline: none; 233 outline: none;
209 } 234 }
210</style>
211 235
236 /* 移动端响应式布局 */
237 @media screen and (max-width: 768px) {
238 .parent {
239 flex-direction: column;
240 }
241
242 .editor-section {
243 width: 100%;
244 }
245
246 .editor-container {
247 height: 30vh;
248 }
249 }
250</style>
diff --git a/doc/docs/README.md b/doc/docs/README.md
index 21e47c4..098d7da 100755
--- a/doc/docs/README.md
+++ b/doc/docs/README.md
@@ -3,6 +3,6 @@ home: true
3heroImage: ./image/yuescript.svg 3heroImage: ./image/yuescript.svg
4actionText: Quick Start → 4actionText: Quick Start →
5actionLink: /doc/ 5actionLink: /doc/
6footer: MIT Licensed | Copyright © 2017-2025 Li Jin 6footer: MIT Licensed | Copyright © 2017-2026 Li Jin
7--- 7---
8 8
diff --git a/doc/docs/doc/README.md b/doc/docs/doc/README.md
index 0853391..5308ebc 100755
--- a/doc/docs/doc/README.md
+++ b/doc/docs/doc/README.md
@@ -16,17 +16,17 @@ Yue (月) is the name of moon in Chinese and it's pronounced as [jyɛ].
16### An Overview of YueScript 16### An Overview of YueScript
17```moonscript 17```moonscript
18-- import syntax 18-- import syntax
19import "yue" as :p, :to_lua 19import p, to_lua from "yue"
20 20
21-- object literals 21-- object literals
22inventory = 22inventory =
23 equipment: 23 equipment:
24 * "sword" 24 - "sword"
25 * "shield" 25 - "shield"
26 items: 26 items:
27 * name: "potion" 27 - name: "potion"
28 count: 10 28 count: 10
29 * name: "bread" 29 - name: "bread"
30 count: 3 30 count: 3
31 31
32-- list comprehension 32-- list comprehension
@@ -61,17 +61,17 @@ export 🌛 = "月之脚本"
61<YueDisplay> 61<YueDisplay>
62<pre> 62<pre>
63-- import syntax 63-- import syntax
64import "yue" as :p, :to_lua 64import p, to_lua from "yue"
65 65
66-- object literals 66-- object literals
67inventory = 67inventory =
68 equipment: 68 equipment:
69 * "sword" 69 - "sword"
70 * "shield" 70 - "shield"
71 items: 71 items:
72 * name: "potion" 72 - name: "potion"
73 count: 10 73 count: 10
74 * name: "bread" 74 - name: "bread"
75 count: 3 75 count: 3
76 76
77-- list comprehension 77-- list comprehension
@@ -408,16 +408,16 @@ In YueScript, macro functions allow you to generate code at compile time. By nes
408 408
409```moonscript 409```moonscript
410macro Enum = (...) -> 410macro Enum = (...) ->
411 items = {...} 411 items = {...}
412 itemSet = {item, true for item in *items} 412 itemSet = {item, true for item in *items}
413 (item) -> 413 (item) ->
414 error "got \"#{item}\", expecting one of #{table.concat items, ', '}" unless itemSet[item] 414 error "got \"#{item}\", expecting one of #{table.concat items, ', '}" unless itemSet[item]
415 "\"#{item}\"" 415 "\"#{item}\""
416 416
417macro BodyType = $Enum( 417macro BodyType = $Enum(
418 Static 418 Static
419 Dynamic 419 Dynamic
420 Kinematic 420 Kinematic
421) 421)
422 422
423print "Valid enum type:", $BodyType Static 423print "Valid enum type:", $BodyType Static
@@ -427,16 +427,16 @@ print "Valid enum type:", $BodyType Static
427<YueDisplay> 427<YueDisplay>
428<pre> 428<pre>
429macro Enum = (...) -> 429macro Enum = (...) ->
430 items = {...} 430 items = {...}
431 itemSet = {item, true for item in *items} 431 itemSet = {item, true for item in *items}
432 (item) -> 432 (item) ->
433 error "got \"#{item}\", expecting one of #{table.concat items, ', '}" unless itemSet[item] 433 error "got \"#{item}\", expecting one of #{table.concat items, ', '}" unless itemSet[item]
434 "\"#{item}\"" 434 "\"#{item}\""
435 435
436macro BodyType = $Enum( 436macro BodyType = $Enum(
437 Static 437 Static
438 Dynamic 438 Dynamic
439 Kinematic 439 Kinematic
440) 440)
441 441
442print "Valid enum type:", $BodyType Static 442print "Valid enum type:", $BodyType Static
@@ -444,6 +444,54 @@ print "Valid enum type:", $BodyType Static
444</pre> 444</pre>
445</YueDisplay> 445</YueDisplay>
446 446
447### Argument Validation
448
449You can declare the expected AST node types in the argument list, and check whether the incoming macro arguments meet the expectations at compile time.
450
451```moonscript
452macro printNumAndStr = (num `Num, str `String) -> |
453 print(
454 #{num}
455 #{str}
456 )
457
458$printNumAndStr 123, "hello"
459```
460<YueDisplay>
461<pre>
462macro printNumAndStr = (num `Num, str `String) -> |
463 print(
464 #{num}
465 #{str}
466 )
467
468$printNumAndStr 123, "hello"
469</pre>
470</YueDisplay>
471
472If you need more flexible argument checking, you can use the built-in `$is_ast` macro function to manually check at the appropriate place.
473
474```moonscript
475macro printNumAndStr = (num, str) ->
476 error "expected Num as first argument" unless $is_ast Num, num
477 error "expected String as second argument" unless $is_ast String, str
478 "print(#{num}, #{str})"
479
480$printNumAndStr 123, "hello"
481```
482<YueDisplay>
483<pre>
484macro printNumAndStr = (num, str) ->
485 error "expected Num as first argument" unless $is_ast Num, num
486 error "expected String as second argument" unless $is_ast String, str
487 "print(#{num}, #{str})"
488
489$printNumAndStr 123, "hello"
490</pre>
491</YueDisplay>
492
493For 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).
494
447## Operator 495## Operator
448 496
449All of Lua's binary and unary operators are available. Additionally **!=** is as an alias for **~=**, and either **\\** or **::** can be used to write a chaining function call like `tb\func!` or `tb::func!`. And Yuescipt offers some other special operators to write more expressive codes. 497All of Lua's binary and unary operators are available. Additionally **!=** is as an alias for **~=**, and either **\\** or **::** can be used to write a chaining function call like `tb\func!` or `tb::func!`. And Yuescipt offers some other special operators to write more expressive codes.
@@ -486,47 +534,47 @@ Note the evaluation behavior of chained comparisons:
486 534
487```moonscript 535```moonscript
488v = (x) -> 536v = (x) ->
489 print x 537 print x
490 x 538 x
491 539
492print v(1) < v(2) <= v(3) 540print v(1) < v(2) <= v(3)
493--[[ 541--[[
494 output: 542 output:
495 2 543 2
496 1 544 1
497 3 545 3
498 true 546 true
499]] 547]]
500 548
501print v(1) > v(2) <= v(3) 549print v(1) > v(2) <= v(3)
502--[[ 550--[[
503 output: 551 output:
504 2 552 2
505 1 553 1
506 false 554 false
507]] 555]]
508``` 556```
509<YueDisplay> 557<YueDisplay>
510<pre> 558<pre>
511v = (x) -> 559v = (x) ->
512 print x 560 print x
513 x 561 x
514 562
515print v(1) < v(2) <= v(3) 563print v(1) < v(2) <= v(3)
516--[[ 564--[[
517 output: 565 output:
518 2 566 2
519 1 567 1
520 3 568 3
521 true 569 true
522]] 570]]
523 571
524print v(1) > v(2) <= v(3) 572print v(1) > v(2) <= v(3)
525--[[ 573--[[
526 output: 574 output:
527 2 575 2
528 1 576 1
529 false 577 false
530]] 578]]
531</pre> 579</pre>
532</YueDisplay> 580</YueDisplay>
@@ -547,19 +595,36 @@ tab[] = "Value"
547</pre> 595</pre>
548</YueDisplay> 596</YueDisplay>
549 597
598You can also use the spread operator `...` to append all elements from one list to another:
599
600```moonscript
601tbA = [1, 2, 3]
602tbB = [4, 5, 6]
603tbA[] = ...tbB
604-- tbA is now [1, 2, 3, 4, 5, 6]
605```
606<YueDisplay>
607<pre>
608tbA = [1, 2, 3]
609tbB = [4, 5, 6]
610tbA[] = ...tbB
611-- tbA is now [1, 2, 3, 4, 5, 6]
612</pre>
613</YueDisplay>
614
550### Table Spreading 615### Table Spreading
551 616
552You can concatenate array tables or hash tables using spread operator `...` before expressions in table literals. 617You can concatenate array tables or hash tables using spread operator `...` before expressions in table literals.
553 618
554```moonscript 619```moonscript
555parts = 620parts =
556 * "shoulders" 621 * "shoulders"
557 * "knees" 622 * "knees"
558lyrics = 623lyrics =
559 * "head" 624 * "head"
560 * ...parts 625 * ...parts
561 * "and" 626 * "and"
562 * "toes" 627 * "toes"
563 628
564copy = {...other} 629copy = {...other}
565 630
@@ -570,13 +635,13 @@ merge = {...a, ...b}
570<YueDisplay> 635<YueDisplay>
571<pre> 636<pre>
572parts = 637parts =
573 * "shoulders" 638 * "shoulders"
574 * "knees" 639 * "knees"
575lyrics = 640lyrics =
576 * "head" 641 * "head"
577 * ...parts 642 * ...parts
578 * "and" 643 * "and"
579 * "toes" 644 * "toes"
580 645
581copy = {...other} 646copy = {...other}
582 647
@@ -586,6 +651,23 @@ merge = {...a, ...b}
586</pre> 651</pre>
587</YueDisplay> 652</YueDisplay>
588 653
654### Table Reversed Indexing
655
656You can use the **#** operator to get the last elements of a table.
657
658```moonscript
659last = data.items[#]
660second_last = data.items[#-1]
661data.items[#] = 1
662```
663<YueDisplay>
664<pre>
665last = data.items[#]
666second_last = data.items[#-1]
667data.items[#] = 1
668</pre>
669</YueDisplay>
670
589### Metatable 671### Metatable
590 672
591The **<>** operator can be used as a shortcut for metatable manipulation. 673The **<>** operator can be used as a shortcut for metatable manipulation.
@@ -752,34 +834,45 @@ a ??= false
752 834
753### Implicit Object 835### Implicit Object
754 836
755You can write a list of implicit structures that starts with the symbol **\*** inside a table block. If you are creating implicit object, the fields of the object must be with the same indent. 837You can write a list of implicit structures that starts with the symbol **\*** or **-** inside a table block. If you are creating implicit object, the fields of the object must be with the same indent.
838
756```moonscript 839```moonscript
840-- assignment with implicit object
757list = 841list =
758 * 1 842 * 1
759 * 2 843 * 2
760 * 3 844 * 3
761 845
846-- function call with implicit object
762func 847func
763 * 1 848 * 1
764 * 2 849 * 2
765 * 3 850 * 3
766 851
852-- return with implicit object
853f = ->
854 return
855 * 1
856 * 2
857 * 3
858
859-- table with implicit object
767tb = 860tb =
768 name: "abc" 861 name: "abc"
769 862
770 values: 863 values:
771 * "a" 864 - "a"
772 * "b" 865 - "b"
773 * "c" 866 - "c"
774 867
775 objects: 868 objects:
776 * name: "a" 869 - name: "a"
777 value: 1 870 value: 1
778 func: => @value + 1 871 func: => @value + 1
779 tb: 872 tb:
780 fieldA: 1 873 fieldA: 1
781 874
782 * name: "b" 875 - name: "b"
783 value: 2 876 value: 2
784 func: => @value + 2 877 func: => @value + 2
785 tb: { } 878 tb: { }
@@ -787,32 +880,42 @@ tb =
787``` 880```
788<YueDisplay> 881<YueDisplay>
789<pre> 882<pre>
883-- assignment with implicit object
790list = 884list =
791 * 1 885 * 1
792 * 2 886 * 2
793 * 3 887 * 3
794 888
889-- function call with implicit object
795func 890func
796 * 1 891 * 1
797 * 2 892 * 2
798 * 3 893 * 3
799 894
895-- return with implicit object
896f = ->
897 return
898 * 1
899 * 2
900 * 3
901
902-- table with implicit object
800tb = 903tb =
801 name: "abc" 904 name: "abc"
802 905
803 values: 906 values:
804 * "a" 907 - "a"
805 * "b" 908 - "b"
806 * "c" 909 - "c"
807 910
808 objects: 911 objects:
809 * name: "a" 912 - name: "a"
810 value: 1 913 value: 1
811 func: => @value + 1 914 func: => @value + 1
812 tb: 915 tb:
813 fieldA: 1 916 fieldA: 1
814 917
815 * name: "b" 918 - name: "b"
816 value: 2 919 value: 2
817 func: => @value + 2 920 func: => @value + 2
818 tb: { } 921 tb: { }
@@ -1222,7 +1325,7 @@ If the destructuring statement is complicated, feel free to spread it out over a
1222</pre> 1325</pre>
1223</YueDisplay> 1326</YueDisplay>
1224 1327
1225It’s common to extract values from at table and assign them the local variables that have the same name as the key. In order to avoid repetition we can use the **:** prefix operator: 1328It's common to extract values from at table and assign them the local variables that have the same name as the key. In order to avoid repetition we can use the **:** prefix operator:
1226 1329
1227```moonscript 1330```moonscript
1228{:concat, :insert} = table 1331{:concat, :insert} = table
@@ -1266,6 +1369,52 @@ You can use `_` as placeholder when doing a list destructuring:
1266</pre> 1369</pre>
1267</YueDisplay> 1370</YueDisplay>
1268 1371
1372### Range Destructuring
1373
1374You can use the spread operator `...` in list destructuring to capture a range of values. This is useful when you want to extract specific elements from the beginning and end of a list while collecting the rest in between.
1375
1376```moonscript
1377orders = ["first", "second", "third", "fourth", "last"]
1378[first, ...bulk, last] = orders
1379print first -- prints: first
1380print bulk -- prints: {"second", "third", "fourth"}
1381print last -- prints: last
1382```
1383<YueDisplay>
1384<pre>
1385orders = ["first", "second", "third", "fourth", "last"]
1386[first, ...bulk, last] = orders
1387print first -- prints: first
1388print bulk -- prints: {"second", "third", "fourth"}
1389print last -- prints: last
1390</pre>
1391</YueDisplay>
1392
1393The spread operator can be used in different positions to capture different ranges, and you can use `_` as a placeholder for the values you don't want to capture:
1394
1395```moonscript
1396-- Capture everything after first element
1397[first, ...rest] = orders
1398
1399-- Capture everything before last element
1400[...start, last] = orders
1401
1402-- Capture things except the middle elements
1403[first, ..._, last] = orders
1404```
1405<YueDisplay>
1406<pre>
1407-- Capture everything after first element
1408[first, ...rest] = orders
1409
1410-- Capture everything before last element
1411[...start, last] = orders
1412
1413-- Capture things except the middle elements
1414[first, ..._, last] = orders
1415</pre>
1416</YueDisplay>
1417
1269### Destructuring In Other Places 1418### Destructuring In Other Places
1270 1419
1271Destructuring can also show up in places where an assignment implicitly takes place. An example of this is a for loop: 1420Destructuring can also show up in places where an assignment implicitly takes place. An example of this is a for loop:
@@ -1495,6 +1644,47 @@ catch err
1495</pre> 1644</pre>
1496</YueDisplay> 1645</YueDisplay>
1497 1646
1647### Try?
1648
1649`try?` is a simplified use for error handling syntax that omit the boolean status from the `try` statement, and it will return the result from the try block when success, return nil instead of error object otherwise.
1650
1651```moonscript
1652a, b, c = try? func!
1653
1654-- with nil coalescing operator
1655a = (try? func!) ?? "default"
1656
1657-- as function argument
1658f try? func!
1659
1660-- with catch block
1661f try?
1662 print 123
1663 func!
1664catch e
1665 print e
1666 e
1667```
1668<YueDisplay>
1669<pre>
1670a, b, c = try? func!
1671
1672-- with nil coalescing operator
1673a = (try? func!) ?? "default"
1674
1675-- as function argument
1676f try? func!
1677
1678-- with catch block
1679f try?
1680 print 123
1681 func!
1682catch e
1683 print e
1684 e
1685</pre>
1686</YueDisplay>
1687
1498## Attributes 1688## Attributes
1499 1689
1500Syntax support for Lua 5.4 attributes. And you can still use both the `const` and `close` declaration and get constant check and scoped callback working when targeting Lua versions below 5.4. 1690Syntax support for Lua 5.4 attributes. And you can still use both the `const` and `close` declaration and get constant check and scoped callback working when targeting Lua versions below 5.4.
@@ -1575,6 +1765,66 @@ binary = 0B10011
1575<pre> 1765<pre>
1576integer = 1_000_000 1766integer = 1_000_000
1577hex = 0xEF_BB_BF 1767hex = 0xEF_BB_BF
1768binary = 0B10011
1769</pre>
1770</YueDisplay>
1771
1772### YAML Multiline String
1773
1774The `|` prefix introduces a YAML-style multiline string literal:
1775
1776```moonscript
1777str = |
1778 key: value
1779 list:
1780 - item1
1781 - #{expr}
1782```
1783<YueDisplay>
1784<pre>
1785str = |
1786 key: value
1787 list:
1788 - item1
1789 - #{expr}
1790</pre>
1791</YueDisplay>
1792
1793This allows writing structured multiline text conveniently. All line breaks and indentation are preserved relative to the first non-empty line, and expressions inside `#{...}` are interpolated automatically as `tostring(expr)`.
1794
1795YAML Multiline String automatically detects the common leading whitespace prefix (minimum indentation across all non-empty lines) and removes it from all lines. This makes it easy to indent your code visually without affecting the resulting string content.
1796
1797```moonscript
1798fn = ->
1799 str = |
1800 foo:
1801 bar: baz
1802 return str
1803```
1804<YueDisplay>
1805<pre>
1806fn = ->
1807 str = |
1808 foo:
1809 bar: baz
1810 return str
1811</pre>
1812</YueDisplay>
1813
1814Internal indentation is preserved relative to the removed common prefix, allowing clean nested structures.
1815
1816All special characters like quotes (`"`) and backslashes (`\`) in the YAMLMultiline block are automatically escaped so that the generated Lua string is syntactically valid and behaves as expected.
1817
1818```moonscript
1819str = |
1820 path: "C:\Program Files\App"
1821 note: 'He said: "#{Hello}!"'
1822```
1823<YueDisplay>
1824<pre>
1825str = |
1826 path: "C:\Program Files\App"
1827 note: 'He said: "#{Hello}!"'
1578</pre> 1828</pre>
1579</YueDisplay> 1829</YueDisplay>
1580 1830
@@ -1895,6 +2145,138 @@ if func 1, 2, 3,
1895</pre> 2145</pre>
1896</YueDisplay> 2146</YueDisplay>
1897 2147
2148### Parameter Destructuring
2149
2150YueScript now supports destructuring function parameters when the argument is an object. Two forms of destructuring table literals are available:
2151
2152* **Curly-brace wrapped literals/object parameters**, allowing optional default values when fields are missing (e.g., `{:a, :b}`, `{a: a1 = 123}`).
2153
2154* **Unwrapped simple table syntax**, starting with a sequence of key-value or shorthand bindings and continuing until another expression terminates it (e.g., `:a, b: b1, :c`). This form extracts multiple fields from the same object.
2155
2156```moonscript
2157f1 = (:a, :b, :c) ->
2158 print a, b, c
2159
2160f1 a: 1, b: "2", c: {}
2161
2162f2 = ({a: a1 = 123, :b = 'abc'}, c = {}) ->
2163 print a1, b, c
2164
2165arg1 = {a: 0}
2166f2 arg1, arg2
2167```
2168<YueDisplay>
2169<pre>
2170f1 = (:a, :b, :c) ->
2171 print a, b, c
2172
2173f1 a: 1, b: "2", c: {}
2174
2175f2 = ({a: a1 = 123, :b = 'abc'}, c = {}) ->
2176print a1, b, c
2177
2178arg1 = {a: 0}
2179f2 arg1, arg2
2180</pre>
2181</YueDisplay>
2182
2183### Prefixed Return Expression
2184
2185When working with deeply nested function bodies, it can be tedious to maintain readability and consistency of the return value. To address this, YueScript introduces the **Prefixed Return Expression** syntax. Its form is as follows:
2186
2187```moon
2188findFirstEven = (list): nil ->
2189 for item in *list
2190 if type(item) == "table"
2191 for sub in *item
2192 if sub % 2 == 0
2193 return sub
2194```
2195<YueDisplay>
2196<pre>
2197findFirstEven = (list): nil ->
2198 for item in *list
2199 if type(item) == "table"
2200 for sub in *item
2201 if sub % 2 == 0
2202 return sub
2203</pre>
2204</YueDisplay>
2205
2206This is equivalent to:
2207
2208```moon
2209findFirstEven = (list) ->
2210 for item in *list
2211 if type(item) == "table"
2212 for sub in *item
2213 if sub % 2 == 0
2214 return sub
2215 nil
2216```
2217<YueDisplay>
2218<pre>
2219findFirstEven = (list) ->
2220 for item in *list
2221 if type(item) == "table"
2222 for sub in *item
2223 if sub % 2 == 0
2224 return sub
2225 nil
2226</pre>
2227</YueDisplay>
2228
2229The only difference is that you can move the final return expression before the `->` or `=>` token to indicate the function’s implicit return value as the last statement. This way, even in functions with multiple nested loops or conditional branches, you no longer need to write a trailing return expression at the end of the function body, making the logic structure more straightforward and easier to follow.
2230
2231### Named Varargs
2232
2233You can use the `(...t) ->` syntax to automatically store varargs into a named table. This table will contain all passed arguments (including `nil` values), and the `n` field of the table will store the actual number of arguments passed (including `nil` values).
2234
2235```moonscript
2236f = (...t) ->
2237 print "argument count:", t.n
2238 print "table length:", #t
2239 for i = 1, t.n
2240 print t[i]
2241
2242f 1, 2, 3
2243f "a", "b", "c", "d"
2244f!
2245
2246-- Handling cases with nil values
2247process = (...args) ->
2248 sum = 0
2249 for i = 1, args.n
2250 if args[i] != nil and type(args[i]) == "number"
2251 sum += args[i]
2252 sum
2253
2254process 1, nil, 3, nil, 5
2255```
2256<YueDisplay>
2257<pre>
2258f = (...t) ->
2259 print "argument count:", t.n
2260 print "table length:", #t
2261 for i = 1, t.n
2262 print t[i]
2263
2264f 1, 2, 3
2265f "a", "b", "c", "d"
2266f!
2267
2268-- Handling cases with nil values
2269process = (...args) ->
2270 sum = 0
2271 for i = 1, args.n
2272 if args[i] != nil and type(args[i]) == "number"
2273 sum += args[i]
2274 sum
2275
2276process 1, nil, 3, nil, 5
2277</pre>
2278</YueDisplay>
2279
1898## Backcalls 2280## Backcalls
1899 2281
1900Backcalls are used for unnesting callbacks. They are defined using arrows pointed to the left as the last parameter by default filling in a function call. All the syntax is mostly the same as regular arrow functions except that it is just pointing the other way and the function body does not require indent. 2282Backcalls are used for unnesting callbacks. They are defined using arrows pointed to the left as the last parameter by default filling in a function call. All the syntax is mostly the same as regular arrow functions except that it is just pointing the other way and the function body does not require indent.
@@ -2149,6 +2531,27 @@ doubled = [item * 2 for item in *items]
2149</pre> 2531</pre>
2150</YueDisplay> 2532</YueDisplay>
2151 2533
2534In list comprehensions, you can also use the spread operator `...` to flatten nested lists, achieving a flat map effect:
2535
2536```moonscript
2537data =
2538 a: [1, 2, 3]
2539 b: [4, 5, 6]
2540
2541flat = [...v for k,v in pairs data]
2542-- flat is now [1, 2, 3, 4, 5, 6]
2543```
2544<YueDisplay>
2545<pre>
2546data =
2547 a: [1, 2, 3]
2548 b: [4, 5, 6]
2549
2550flat = [...v for k,v in pairs data]
2551-- flat is now [1, 2, 3, 4, 5, 6]
2552</pre>
2553</YueDisplay>
2554
2152The for and when clauses can be chained as much as desired. The only requirement is that a comprehension has at least one for clause. 2555The for and when clauses can be chained as much as desired. The only requirement is that a comprehension has at least one for clause.
2153 2556
2154Using multiple for clauses is the same as using nested loops: 2557Using multiple for clauses is the same as using nested loops:
@@ -2282,6 +2685,45 @@ slice = [item for item in *items[,,2]]
2282</pre> 2685</pre>
2283</YueDisplay> 2686</YueDisplay>
2284 2687
2688Both the minimum and maximum bounds can be negative, which means that the bounds are counted from the end of the table.
2689
2690```moonscript
2691-- take the last 4 items
2692slice = [item for item in *items[-4,-1]]
2693```
2694<YueDisplay>
2695<pre>
2696-- take the last 4 items
2697slice = [item for item in *items[-4,-1]]
2698</pre>
2699</YueDisplay>
2700
2701The step size can also be negative, which means that the items are taken in reverse order.
2702
2703```moonscript
2704reverse_slice = [item for item in *items[-1,1,-1]]
2705```
2706<YueDisplay>
2707<pre>
2708reverse_slice = [item for item in *items[-1,1,-1]]
2709</pre>
2710</YueDisplay>
2711
2712#### Slicing Expression
2713
2714Slicing can also be used as an expression. This is useful for getting a sub-list of a table.
2715
2716```moonscript
2717-- take the 2nd and 4th items as a new list
2718sub_list = items[2, 4]
2719```
2720<YueDisplay>
2721<pre>
2722-- take the 2nd and 4th items as a new list
2723sub_list = items[2, 4]
2724</pre>
2725</YueDisplay>
2726
2285## For Loop 2727## For Loop
2286 2728
2287There are two for loop forms, just like in Lua. A numeric one and a generic one: 2729There are two for loop forms, just like in Lua. A numeric one and a generic one:
@@ -2396,7 +2838,7 @@ print func_b! -- prints table object
2396</pre> 2838</pre>
2397</YueDisplay> 2839</YueDisplay>
2398 2840
2399This is done to avoid the needless creation of tables for functions that dont need to return the results of the loop. 2841This is done to avoid the needless creation of tables for functions that don't need to return the results of the loop.
2400 2842
2401## Repeat Loop 2843## Repeat Loop
2402 2844
@@ -2675,28 +3117,26 @@ reader\parse_line! until reader\eof!
2675 3117
2676## Switch 3118## Switch
2677 3119
2678The switch statement is shorthand for writing a series of if statements that check against the same value. Note that the value is only evaluated once. Like if statements, switches can have an else block to handle no matches. Comparison is done with the == operator. 3120The switch statement is shorthand for writing a series of if statements that check against the same value. Note that the value is only evaluated once. Like if statements, switches can have an else block to handle no matches. Comparison is done with the == operator. In switch statement, you can also use assignment expression to store temporary variable value.
2679 3121
2680```moonscript 3122```moonscript
2681name = "Dan" 3123switch name := "Dan"
2682switch name
2683 when "Robert" 3124 when "Robert"
2684 print "You are Robert" 3125 print "You are Robert"
2685 when "Dan", "Daniel" 3126 when "Dan", "Daniel"
2686 print "Your name, it's Dan" 3127 print "Your name, it's Dan"
2687 else 3128 else
2688 print "I don't know about your name" 3129 print "I don't know about you with name #{name}"
2689``` 3130```
2690<YueDisplay> 3131<YueDisplay>
2691<pre> 3132<pre>
2692name = "Dan" 3133switch name := "Dan"
2693switch name
2694 when "Robert" 3134 when "Robert"
2695 print "You are Robert" 3135 print "You are Robert"
2696 when "Dan", "Daniel" 3136 when "Dan", "Daniel"
2697 print "Your name, it's Dan" 3137 print "Your name, it's Dan"
2698 else 3138 else
2699 print "I don't know about your name" 3139 print "I don't know about you with name #{name}"
2700</pre> 3140</pre>
2701</YueDisplay> 3141</YueDisplay>
2702 3142
@@ -2727,7 +3167,7 @@ next_number = switch b
2727</pre> 3167</pre>
2728</YueDisplay> 3168</YueDisplay>
2729 3169
2730We can use the then keyword to write a switch’s when block on a single line. No extra keyword is needed to write the else block on a single line. 3170We can use the then keyword to write a switch's when block on a single line. No extra keyword is needed to write the else block on a single line.
2731 3171
2732```moonscript 3172```moonscript
2733msg = switch math.random(1, 5) 3173msg = switch math.random(1, 5)
@@ -2773,7 +3213,7 @@ else
2773</pre> 3213</pre>
2774</YueDisplay> 3214</YueDisplay>
2775 3215
2776It is worth noting the order of the case comparison expression. The case’s expression is on the left hand side. This can be useful if the case’s expression wants to overwrite how the comparison is done by defining an eq metamethod. 3216It is worth noting the order of the case comparison expression. The case's expression is on the left hand side. This can be useful if the case's expression wants to overwrite how the comparison is done by defining an eq metamethod.
2777 3217
2778### Table Matching 3218### Table Matching
2779 3219
@@ -2929,6 +3369,27 @@ switch tb
2929</pre> 3369</pre>
2930</YueDisplay> 3370</YueDisplay>
2931 3371
3372Match against a list and capture a range of elements.
3373
3374```moonscript
3375segments = ["admin", "users", "logs", "view"]
3376switch segments
3377 when [...groups, resource, action]
3378 print "Group:", groups -- prints: {"admin", "users"}
3379 print "Resource:", resource -- prints: "logs"
3380 print "Action:", action -- prints: "view"
3381```
3382<YueDisplay>
3383<pre>
3384segments = ["admin", "users", "logs", "view"]
3385switch segments
3386 when [...groups, resource, action]
3387 print "Group:", groups -- prints: {"admin", "users"}
3388 print "Resource:", resource -- prints: "logs"
3389 print "Action:", action -- prints: "view"
3390</pre>
3391</YueDisplay>
3392
2932## Object Oriented Programming 3393## Object Oriented Programming
2933 3394
2934In these examples, the generated Lua code may appear overwhelming. It is best to focus on the meaning of the YueScript code at first, then look into the Lua code if you wish to know the implementation details. 3395In these examples, the generated Lua code may appear overwhelming. It is best to focus on the meaning of the YueScript code at first, then look into the Lua code if you wish to know the implementation details.
@@ -3060,7 +3521,7 @@ class BackPack extends Inventory
3060 3521
3061Here we extend our Inventory class, and limit the amount of items it can carry. 3522Here we extend our Inventory class, and limit the amount of items it can carry.
3062 3523
3063In this example, we don’t define a constructor on the subclass, so the parent class' constructor is called when we make a new instance. If we did define a constructor then we can use the super method to call the parent constructor. 3524In this example, we don't define a constructor on the subclass, so the parent class' constructor is called when we make a new instance. If we did define a constructor then we can use the super method to call the parent constructor.
3064 3525
3065Whenever a class inherits from another, it sends a message to the parent class by calling the method __inherited on the parent class if it exists. The function receives two arguments, the class that is being inherited and the child class. 3526Whenever a class inherits from another, it sends a message to the parent class by calling the method __inherited on the parent class if it exists. The function receives two arguments, the class that is being inherited and the child class.
3066 3527
@@ -3147,13 +3608,13 @@ print BackPack.size -- prints 10
3147 3608
3148The class object is what we create when we use a class statement. The class object is stored in a variable of the same name of the class. 3609The class object is what we create when we use a class statement. The class object is stored in a variable of the same name of the class.
3149 3610
3150The class object can be called like a function in order to create new instances. That’s how we created instances of classes in the examples above. 3611The class object can be called like a function in order to create new instances. That's how we created instances of classes in the examples above.
3151 3612
3152A class is made up of two tables. The class table itself, and the base table. The base is used as the metatable for all the instances. All properties listed in the class declaration are placed in the base. 3613A class is made up of two tables. The class table itself, and the base table. The base is used as the metatable for all the instances. All properties listed in the class declaration are placed in the base.
3153 3614
3154The class object’s metatable reads properties from the base if they don’t exist in the class object. This means we can access functions and properties directly from the class. 3615The class object's metatable reads properties from the base if they don't exist in the class object. This means we can access functions and properties directly from the class.
3155 3616
3156It is important to note that assigning to the class object does not assign into the base, so it’s not a valid way to add new methods to instances. Instead the base must explicitly be changed. See the __base field below. 3617It is important to note that assigning to the class object does not assign into the base, so it's not a valid way to add new methods to instances. Instead the base must explicitly be changed. See the __base field below.
3157 3618
3158The class object has a couple special properties: 3619The class object has a couple special properties:
3159 3620
@@ -3226,7 +3687,7 @@ print Counter.count -- prints 2
3226</pre> 3687</pre>
3227</YueDisplay> 3688</YueDisplay>
3228 3689
3229The calling semantics of @@ are similar to @. Calling a @@ name will pass the class in as the first argument using Lua’s colon syntax. 3690The calling semantics of @@ are similar to @. Calling a @@ name will pass the class in as the first argument using Lua's colon syntax.
3230 3691
3231```moonscript 3692```moonscript
3232@@hello 1,2,3,4 3693@@hello 1,2,3,4
@@ -3241,7 +3702,7 @@ The calling semantics of @@ are similar to @. Calling a @@ name will pass the cl
3241 3702
3242In the body of a class declaration, we can have normal expressions in addition to key/value pairs. In this context, self is equal to the class object. 3703In the body of a class declaration, we can have normal expressions in addition to key/value pairs. In this context, self is equal to the class object.
3243 3704
3244Here is an alternative way to create a class variable compared to whats described above: 3705Here is an alternative way to create a class variable compared to what's described above:
3245 3706
3246```moonscript 3707```moonscript
3247class Things 3708class Things
@@ -3507,19 +3968,19 @@ In this usage, with can be seen as a special form of the K combinator.
3507The expression in the with statement can also be an assignment, if you want to give a name to the expression. 3968The expression in the with statement can also be an assignment, if you want to give a name to the expression.
3508 3969
3509```moonscript 3970```moonscript
3510with str = "Hello" 3971with str := "Hello"
3511 print "original:", str 3972 print "original:", str
3512 print "upper:", \upper! 3973 print "upper:", \upper!
3513``` 3974```
3514<YueDisplay> 3975<YueDisplay>
3515<pre> 3976<pre>
3516with str = "Hello" 3977with str := "Hello"
3517 print "original:", str 3978 print "original:", str
3518 print "upper:", \upper! 3979 print "upper:", \upper!
3519</pre> 3980</pre>
3520</YueDisplay> 3981</YueDisplay>
3521 3982
3522Accessing special keys with `[]` in a `with` statement. 3983You can access special keys with `[]` in a `with` statement.
3523 3984
3524```moonscript 3985```moonscript
3525with tb 3986with tb
@@ -3542,6 +4003,18 @@ with tb
3542</pre> 4003</pre>
3543</YueDisplay> 4004</YueDisplay>
3544 4005
4006`with?` is an enhanced version of `with` syntax, which introduces an existential check to safely access objects that may be nil without explicit null checks.
4007
4008```moonscript
4009with? obj
4010 print obj.name
4011```
4012<YueDisplay>
4013<pre>
4014with? obj
4015 print obj.name
4016</pre>
4017</YueDisplay>
3545 4018
3546## Do 4019## Do
3547 4020
@@ -3562,7 +4035,7 @@ print var -- nil here
3562</pre> 4035</pre>
3563</YueDisplay> 4036</YueDisplay>
3564 4037
3565YueScript’s **do** can also be used an expression . Allowing you to combine multiple lines into one. The result of the do expression is the last statement in its body. 4038YueScript's **do** can also be used an expression . Allowing you to combine multiple lines into one. The result of the do expression is the last statement in its body.
3566 4039
3567```moonscript 4040```moonscript
3568counter = do 4041counter = do
@@ -3688,7 +4161,7 @@ print i -- will print 0
3688</pre> 4161</pre>
3689</YueDisplay> 4162</YueDisplay>
3690 4163
3691In my_func, we've overwritten the value of i mistakenly. In this example it is quite obvious, but consider a large, or foreign code base where it isn’t clear what names have already been declared. 4164In my_func, we've overwritten the value of i mistakenly. In this example it is quite obvious, but consider a large, or foreign code base where it isn't clear what names have already been declared.
3692 4165
3693It would be helpful to say which variables from the enclosing scope we intend on change, in order to prevent us from changing others by accident. 4166It would be helpful to say which variables from the enclosing scope we intend on change, in order to prevent us from changing others by accident.
3694 4167
@@ -3804,9 +4277,9 @@ The YueScript compiling function. It compiles the YueScript code to Lua code.
3804**Signature:** 4277**Signature:**
3805```lua 4278```lua
3806to_lua: function(code: string, config?: Config): 4279to_lua: function(code: string, config?: Config):
3807 --[[codes]] string | nil, 4280 --[[codes]] string | nil,
3808 --[[error]] string | nil, 4281 --[[error]] string | nil,
3809 --[[globals]] {{string, integer, integer}} | nil 4282 --[[globals]] {{string, integer, integer}} | nil
3810``` 4283```
3811 4284
3812**Parameters:** 4285**Parameters:**
@@ -3929,8 +4402,8 @@ Loads YueScript code from a string into a function.
3929**Signature:** 4402**Signature:**
3930```lua 4403```lua
3931loadstring: function(input: string, chunkname: string, env: table, config?: Config): 4404loadstring: function(input: string, chunkname: string, env: table, config?: Config):
3932 --[[loaded function]] nil | function(...: any): (any...), 4405 --[[loaded function]] nil | function(...: any): (any...),
3933 --[[error]] string | nil 4406 --[[error]] string | nil
3934``` 4407```
3935 4408
3936**Parameters:** 4409**Parameters:**
@@ -3960,8 +4433,8 @@ Loads YueScript code from a string into a function.
3960**Signature:** 4433**Signature:**
3961```lua 4434```lua
3962loadstring: function(input: string, chunkname: string, config?: Config): 4435loadstring: function(input: string, chunkname: string, config?: Config):
3963 --[[loaded function]] nil | function(...: any): (any...), 4436 --[[loaded function]] nil | function(...: any): (any...),
3964 --[[error]] string | nil 4437 --[[error]] string | nil
3965``` 4438```
3966 4439
3967**Parameters:** 4440**Parameters:**
@@ -3990,8 +4463,8 @@ Loads YueScript code from a string into a function.
3990**Signature:** 4463**Signature:**
3991```lua 4464```lua
3992loadstring: function(input: string, config?: Config): 4465loadstring: function(input: string, config?: Config):
3993 --[[loaded function]] nil | function(...: any): (any...), 4466 --[[loaded function]] nil | function(...: any): (any...),
3994 --[[error]] string | nil 4467 --[[error]] string | nil
3995``` 4468```
3996 4469
3997**Parameters:** 4470**Parameters:**
@@ -4019,8 +4492,8 @@ Loads YueScript code from a file into a function.
4019**Signature:** 4492**Signature:**
4020```lua 4493```lua
4021loadfile: function(filename: string, env: table, config?: Config): 4494loadfile: function(filename: string, env: table, config?: Config):
4022 nil | function(...: any): (any...), 4495 nil | function(...: any): (any...),
4023 string | nil 4496 string | nil
4024``` 4497```
4025 4498
4026**Parameters:** 4499**Parameters:**
@@ -4049,8 +4522,8 @@ Loads YueScript code from a file into a function.
4049**Signature:** 4522**Signature:**
4050```lua 4523```lua
4051loadfile: function(filename: string, config?: Config): 4524loadfile: function(filename: string, config?: Config):
4052 nil | function(...: any): (any...), 4525 nil | function(...: any): (any...),
4053 string | nil 4526 string | nil
4054``` 4527```
4055 4528
4056**Parameters:** 4529**Parameters:**
@@ -4305,9 +4778,9 @@ Converts the code to the AST.
4305 4778
4306**Signature:** 4779**Signature:**
4307```lua 4780```lua
4308to_ast: function(code: string, flattenLevel?: number, astName?: string): 4781to_ast: function(code: string, flattenLevel?: number, astName?: string, reserveComment?: boolean):
4309 --[[AST]] AST | nil, 4782 --[[AST]] AST | nil,
4310 --[[error]] nil | string 4783 --[[error]] nil | string
4311``` 4784```
4312 4785
4313**Parameters:** 4786**Parameters:**
@@ -4317,6 +4790,7 @@ to_ast: function(code: string, flattenLevel?: number, astName?: string):
4317| code | string | The code. | 4790| code | string | The code. |
4318| flattenLevel | integer | [Optional] The flatten level. Higher level means more flattening. Default is 0. Maximum is 2. | 4791| flattenLevel | integer | [Optional] The flatten level. Higher level means more flattening. Default is 0. Maximum is 2. |
4319| astName | string | [Optional] The AST name. Default is "File". | 4792| astName | string | [Optional] The AST name. Default is "File". |
4793| reserveComment | boolean | [Optional] Whether to reserve the original comments. Default is false. |
4320 4794
4321**Returns:** 4795**Returns:**
4322 4796
@@ -4325,6 +4799,33 @@ to_ast: function(code: string, flattenLevel?: number, astName?: string):
4325| AST \| nil | The AST, or nil if the conversion failed. | 4799| AST \| nil | The AST, or nil if the conversion failed. |
4326| string \| nil | The error message, or nil if the conversion succeeded. | 4800| string \| nil | The error message, or nil if the conversion succeeded. |
4327 4801
4802#### format
4803
4804**Type:** Function.
4805
4806**Description:**
4807
4808Formats the YueScript code.
4809
4810**Signature:**
4811```lua
4812format: function(code: string, tabSize?: number, reserveComment?: boolean): string
4813```
4814
4815**Parameters:**
4816
4817| Parameter | Type | Description |
4818| --- | --- | --- |
4819| code | string | The code. |
4820| tabSize | integer | [Optional] The tab size. Default is 4. |
4821| reserveComment | boolean | [Optional] Whether to reserve the original comments. Default is true. |
4822
4823**Returns:**
4824
4825| Return Type | Description |
4826| --- | --- |
4827| string | The formatted code. |
4828
4328#### __call 4829#### __call
4329 4830
4330**Type:** Metamethod. 4831**Type:** Metamethod.
@@ -4396,6 +4897,19 @@ Whether the compiler should reserve the original line number in the compiled cod
4396reserve_line_number: boolean 4897reserve_line_number: boolean
4397``` 4898```
4398 4899
4900#### reserve_comment
4901
4902**Type:** Field.
4903
4904**Description:**
4905
4906Whether the compiler should reserve the original comments in the compiled code.
4907
4908**Signature:**
4909```lua
4910reserve_comment: boolean
4911```
4912
4399#### space_over_tab 4913#### space_over_tab
4400 4914
4401**Type:** Field. 4915**Type:** Field.
@@ -4446,11 +4960,11 @@ The target Lua version enumeration.
4446**Signature:** 4960**Signature:**
4447```lua 4961```lua
4448enum LuaTarget 4962enum LuaTarget
4449 "5.1" 4963 "5.1"
4450 "5.2" 4964 "5.2"
4451 "5.3" 4965 "5.3"
4452 "5.4" 4966 "5.4"
4453 "5.5" 4967 "5.5"
4454end 4968end
4455``` 4969```
4456 4970
@@ -4527,7 +5041,7 @@ simplified: boolean
4527 5041
4528## Licence: MIT 5042## Licence: MIT
4529 5043
4530Copyright (c) 2017-2025 Li Jin \<dragon-fly@qq.com\> 5044Copyright (c) 2017-2026 Li Jin \<dragon-fly@qq.com\>
4531 5045
4532Permission is hereby granted, free of charge, to any person obtaining a copy 5046Permission is hereby granted, free of charge, to any person obtaining a copy
4533of this software and associated documentation files (the "Software"), to deal 5047of this software and associated documentation files (the "Software"), to deal
diff --git a/doc/docs/zh/README.md b/doc/docs/zh/README.md
index f5c9811..05b2069 100755
--- a/doc/docs/zh/README.md
+++ b/doc/docs/zh/README.md
@@ -3,6 +3,6 @@ home: true
3heroImage: /image/yuescript.svg 3heroImage: /image/yuescript.svg
4actionText: 快速上手 → 4actionText: 快速上手 →
5actionLink: /zh/doc/ 5actionLink: /zh/doc/
6footer: MIT Licensed | Copyright © 2017-2025 Li Jin 6footer: MIT Licensed | Copyright © 2017-2026 Li Jin
7--- 7---
8 8
diff --git a/doc/docs/zh/doc/README.md b/doc/docs/zh/doc/README.md
index 2968f6e..de5dff1 100755
--- a/doc/docs/zh/doc/README.md
+++ b/doc/docs/zh/doc/README.md
@@ -9,24 +9,24 @@ title: 参考手册
9 9
10## 介绍 10## 介绍
11 11
12月之脚本(YueScript)是一种动态语言,可以编译为Lua。它是[MoonScript](https://github.com/leafo/moonscript)的方言。用月之脚本编写的代码既有表现力又非常简洁。它适合编写一些更易于维护的代码,并在嵌入 Lua 的环境中运行,如游戏或网站服务器。 12月之脚本(YueScript)是一种动态语言,可以编译为 Lua。它是 [MoonScript](https://github.com/leafo/moonscript) 的方言。用月之脚本编写的代码既有表现力又非常简洁。它适合编写一些更易于维护的代码,并在嵌入 Lua 的环境中运行,如游戏或网站服务器。
13 13
14Yue(月)是中文中“月亮”的名称。 14Yue(月)是中文中“月亮”的名称。
15 15
16### 月之脚本概览 16### 月之脚本概览
17```moonscript 17```moonscript
18-- 导入语法 18-- 导入语法
19import "yue" as :p, :to_lua 19import p, to_lua from "yue"
20 20
21-- 隐式对象 21-- 隐式对象
22inventory = 22inventory =
23 equipment: 23 equipment:
24 * "sword" 24 - "sword"
25 * "shield" 25 - "shield"
26 items: 26 items:
27 * name: "potion" 27 - name: "potion"
28 count: 10 28 count: 10
29 * name: "bread" 29 - name: "bread"
30 count: 3 30 count: 3
31 31
32-- 列表推导 32-- 列表推导
@@ -61,17 +61,17 @@ export 🌛 = "月之脚本"
61<YueDisplay> 61<YueDisplay>
62<pre> 62<pre>
63-- 导入语法 63-- 导入语法
64import "yue" as :p, :to_lua 64import p, to_lua from "yue"
65 65
66-- 隐式对象 66-- 隐式对象
67inventory = 67inventory =
68 equipment: 68 equipment:
69 * "sword" 69 - "sword"
70 * "shield" 70 - "shield"
71 items: 71 items:
72 * name: "potion" 72 - name: "potion"
73 count: 10 73 count: 10
74 * name: "bread" 74 - name: "bread"
75 count: 3 75 count: 3
76 76
77-- 列表推导 77-- 列表推导
@@ -109,7 +109,7 @@ export 🌛 = "月之脚本"
109 109
110* **Lua 模块** 110* **Lua 模块**
111 111
112&emsp;安装 [luarocks](https://luarocks.org),一个Lua模块的包管理器。然后作为Lua模块和可执行文件安装它: 112&emsp;安装 [luarocks](https://luarocks.org),一个 Lua 模块的包管理器。然后作为 Lua 模块和可执行文件安装它:
113 113
114``` 114```
115> luarocks install yuescript 115> luarocks install yuescript
@@ -150,14 +150,14 @@ export 🌛 = "月之脚本"
150 150
151### Lua 模块 151### Lua 模块
152 152
153在Lua中使用月之脚本模块: 153 Lua 中使用月之脚本模块:
154 154
155* **用法 1** 155* **用法 1**
156在Lua中引入 "你的脚本入口文件.yue"。 156 Lua 中引入 "你的脚本入口文件.yue"。
157```Lua 157```Lua
158require("yue")("你的脚本入口文件") 158require("yue")("你的脚本入口文件")
159``` 159```
160当你在同一路径下把 "你的脚本入口文件.yue" 编译成了 "你的脚本入口文件.lua" 时,仍然可以使用这个代码加载 .lua 代码文件。在其余的月之脚本文件中,只需正常使用 **require** 或 **import**进行脚本引用即可。错误消息中的代码行号也会被正确处理。 160当你在同一路径下把 "你的脚本入口文件.yue" 编译成了 "你的脚本入口文件.lua" 时,仍然可以使用这个代码加载 .lua 代码文件。在其余的月之脚本文件中,只需正常使用 **require** 或 **import** 进行脚本引用即可。错误消息中的代码行号也会被正确处理。
161 161
162* **用法 2** 162* **用法 2**
163手动引入月之脚本模块并重写错误消息来帮助调试。 163手动引入月之脚本模块并重写错误消息来帮助调试。
@@ -172,7 +172,7 @@ end)
172``` 172```
173 173
174* **用法 3** 174* **用法 3**
175在Lua中使用月之脚本编译器功能。 175 Lua 中使用月之脚本编译器功能。
176```lua 176```lua
177local yue = require("yue") 177local yue = require("yue")
178local codes, err, globals = yue.to_lua([[ 178local codes, err, globals = yue.to_lua([[
@@ -222,12 +222,12 @@ f!
222 不添加任何选项执行命令可以进入REPL模式, 222 不添加任何选项执行命令可以进入REPL模式,
223 在单行输入符号 '$' 并换行后,可以开始或是停止多行输入模式 223 在单行输入符号 '$' 并换行后,可以开始或是停止多行输入模式
224``` 224```
225&emsp;&emsp;使用案例: 225&emsp;&emsp;使用案例:
226&emsp;&emsp;递归编译当前路径下扩展名为 **.yue** 的每个月之脚本文件: **yue .** 226&emsp;&emsp;递归编译当前路径下扩展名为 **.yue** 的每个月之脚本文件: **yue .**
227&emsp;&emsp;编译并将结果保存到目标路径: **yue -t /target/path/ .** 227&emsp;&emsp;编译并将结果保存到目标路径: **yue -t /target/path/ .**
228&emsp;&emsp;编译并保留调试信息: **yue -l .** 228&emsp;&emsp;编译并保留调试信息: **yue -l .**
229&emsp;&emsp;编译并生成压缩代码: **yue -m .** 229&emsp;&emsp;编译并生成压缩代码: **yue -m .**
230&emsp;&emsp;直接执行代码: **yue -e 'print 123'** 230&emsp;&emsp;直接执行代码: **yue -e 'print 123'**
231&emsp;&emsp;执行一个月之脚本文件: **yue -e main.yue** 231&emsp;&emsp;执行一个月之脚本文件: **yue -e main.yue**
232 232
233## 宏 233## 宏
@@ -407,16 +407,16 @@ print $LINE -- 获取当前代码行数:2
407 407
408```moonscript 408```moonscript
409macro Enum = (...) -> 409macro Enum = (...) ->
410 items = {...} 410 items = {...}
411 itemSet = {item, true for item in *items} 411 itemSet = {item, true for item in *items}
412 (item) -> 412 (item) ->
413 error "got \"#{item}\", expecting one of #{table.concat items, ', '}" unless itemSet[item] 413 error "got \"#{item}\", expecting one of #{table.concat items, ', '}" unless itemSet[item]
414 "\"#{item}\"" 414 "\"#{item}\""
415 415
416macro BodyType = $Enum( 416macro BodyType = $Enum(
417 Static 417 Static
418 Dynamic 418 Dynamic
419 Kinematic 419 Kinematic
420) 420)
421 421
422print "有效的枚举类型:", $BodyType Static 422print "有效的枚举类型:", $BodyType Static
@@ -425,16 +425,16 @@ print "有效的枚举类型:", $BodyType Static
425<YueDisplay> 425<YueDisplay>
426<pre> 426<pre>
427macro Enum = (...) -> 427macro Enum = (...) ->
428 items = {...} 428 items = {...}
429 itemSet = {item, true for item in *items} 429 itemSet = {item, true for item in *items}
430 (item) -> 430 (item) ->
431 error "got \"#{item}\", expecting one of #{table.concat items, ', '}" unless itemSet[item] 431 error "got \"#{item}\", expecting one of #{table.concat items, ', '}" unless itemSet[item]
432 "\"#{item}\"" 432 "\"#{item}\""
433 433
434macro BodyType = $Enum( 434macro BodyType = $Enum(
435 Static 435 Static
436 Dynamic 436 Dynamic
437 Kinematic 437 Kinematic
438) 438)
439 439
440print "有效的枚举类型:", $BodyType Static 440print "有效的枚举类型:", $BodyType Static
@@ -442,9 +442,57 @@ print "有效的枚举类型:", $BodyType Static
442</pre> 442</pre>
443</YueDisplay> 443</YueDisplay>
444 444
445### 宏参数检查
446
447可以直接在参数列表中声明期望的 AST 节点类型,并在编译时检查传入的宏参数是否符合预期。
448
449```moonscript
450macro printNumAndStr = (num `Num, str `String) -> |
451 print(
452 #{num}
453 #{str}
454 )
455
456$printNumAndStr 123, "hello"
457```
458<YueDisplay>
459<pre>
460macro printNumAndStr = (num `Num, str `String) -> |
461 print(
462 #{num}
463 #{str}
464 )
465
466$printNumAndStr 123, "hello"
467</pre>
468</YueDisplay>
469
470如果需要做更加灵活的参数检查操作,可以使用内置的 `$is_ast` 宏函数在合适的位置进行手动检查。
471
472```moonscript
473macro printNumAndStr = (num, str) ->
474 error "expected Num as first argument" unless $is_ast Num, num
475 error "expected String as second argument" unless $is_ast String, str
476 "print(#{num}, #{str})"
477
478$printNumAndStr 123, "hello"
479```
480<YueDisplay>
481<pre>
482macro printNumAndStr = (num, str) ->
483 error "expected Num as first argument" unless $is_ast Num, num
484 error "expected String as second argument" unless $is_ast String, str
485 "print(#{num}, #{str})"
486
487$printNumAndStr 123, "hello"
488</pre>
489</YueDisplay>
490
491更多关于可用 AST 节点的详细信息,请参考 [yue_parser.cpp](https://github.com/IppClub/YueScript/blob/main/src/yuescript/yue_parser.cpp) 中大写的规则定义。
492
445## 操作符 493## 操作符
446 494
447Lua的所有二元和一元操作符在月之脚本中都是可用的。此外,**!=** 符号是 **~=** 的别名,而 **\\** 或 **::** 均可用于编写链式函数调用,如写作 `tb\func!` 或 `tb::func!`。此外月之脚本还提供了一些其他特殊的操作符,以编写更具表达力的代码。 495Lua 的所有二元和一元操作符在月之脚本中都是可用的。此外,**!=** 符号是 **~=** 的别名,而 **\\** 或 **::** 均可用于编写链式函数调用,如写作 `tb\func!` 或 `tb::func!`。此外月之脚本还提供了一些其他特殊的操作符,以编写更具表达力的代码。
448 496
449```moonscript 497```moonscript
450tb\func! if tb ~= nil 498tb\func! if tb ~= nil
@@ -484,56 +532,56 @@ print 1 <= a <= 10
484 532
485```moonscript 533```moonscript
486v = (x) -> 534v = (x) ->
487 print x 535 print x
488 x 536 x
489 537
490print v(1) < v(2) <= v(3) 538print v(1) < v(2) <= v(3)
491--[[ 539--[[
492 输出: 540 输出:
493 2 541 2
494 1 542 1
495 3 543 3
496 true 544 true
497]] 545]]
498 546
499print v(1) > v(2) <= v(3) 547print v(1) > v(2) <= v(3)
500--[[ 548--[[
501 输出: 549 输出:
502 2 550 2
503 1 551 1
504 false 552 false
505]] 553]]
506``` 554```
507<YueDisplay> 555<YueDisplay>
508<pre> 556<pre>
509v = (x) -> 557v = (x) ->
510 print x 558 print x
511 x 559 x
512 560
513print v(1) < v(2) <= v(3) 561print v(1) < v(2) <= v(3)
514--[[ 562--[[
515 输出: 563 输出:
516 2 564 2
517 1 565 1
518 3 566 3
519 true 567 true
520]] 568]]
521 569
522print v(1) > v(2) <= v(3) 570print v(1) > v(2) <= v(3)
523--[[ 571--[[
524 输出: 572 输出:
525 2 573 2
526 1 574 1
527 false 575 false
528]] 576]]
529</pre> 577</pre>
530</YueDisplay> 578</YueDisplay>
531 579
532在上面的例子里,中间的表达式`v(2)`仅被计算一次,如果把表达式写成`v(1) < v(2) and v(2) <= v(3)`的方式,中间的`v(2)`才会被计算两次。在链式比较中,求值的顺序往往是未定义的。所以强烈建议不要在链式比较中使用具有副作用(比如做打印操作)的表达式。如果需要使用有副作用的函数,应明确使用短路 `and` 运算符来做连接。 580在上面的例子里,中间的表达式 `v(2)` 仅被计算一次,如果把表达式写成 `v(1) < v(2) and v(2) <= v(3)` 的方式,中间的 `v(2)` 才会被计算两次。在链式比较中,求值的顺序往往是未定义的。所以强烈建议不要在链式比较中使用具有副作用(比如做打印操作)的表达式。如果需要使用有副作用的函数,应明确使用短路 `and` 运算符来做连接。
533 581
534### 表追加 582### 表追加
535 583
536**[] =** 操作符用于向Lua表的最后插入值。 584**[] =** 操作符用于向 Lua 表的最后插入值。
537 585
538```moonscript 586```moonscript
539tab = [] 587tab = []
@@ -546,19 +594,36 @@ tab[] = "Value"
546</pre> 594</pre>
547</YueDisplay> 595</YueDisplay>
548 596
597你还可以使用展开操作符 `...` 来将一个列表中的所有元素追加到另一个列表中:
598
599```moonscript
600tbA = [1, 2, 3]
601tbB = [4, 5, 6]
602tbA[] = ...tbB
603-- tbA 现在为 [1, 2, 3, 4, 5, 6]
604```
605<YueDisplay>
606<pre>
607tbA = [1, 2, 3]
608tbB = [4, 5, 6]
609tbA[] = ...tbB
610-- tbA 现在为 [1, 2, 3, 4, 5, 6]
611</pre>
612</YueDisplay>
613
549### 表扩展 614### 表扩展
550 615
551你可以使用前置 `...` 操作符在Lua表中插入数组表或哈希表。 616你可以使用前置 `...` 操作符在 Lua 表中插入数组表或哈希表。
552 617
553```moonscript 618```moonscript
554parts = 619parts =
555 * "shoulders" 620 * "shoulders"
556 * "knees" 621 * "knees"
557lyrics = 622lyrics =
558 * "head" 623 * "head"
559 * ...parts 624 * ...parts
560 * "and" 625 * "and"
561 * "toes" 626 * "toes"
562 627
563copy = {...other} 628copy = {...other}
564 629
@@ -569,13 +634,13 @@ merge = {...a, ...b}
569<YueDisplay> 634<YueDisplay>
570<pre> 635<pre>
571parts = 636parts =
572 * "shoulders" 637 * "shoulders"
573 * "knees" 638 * "knees"
574lyrics = 639lyrics =
575 * "head" 640 * "head"
576 * ...parts 641 * ...parts
577 * "and" 642 * "and"
578 * "toes" 643 * "toes"
579 644
580copy = {...other} 645copy = {...other}
581 646
@@ -585,12 +650,29 @@ merge = {...a, ...b}
585</pre> 650</pre>
586</YueDisplay> 651</YueDisplay>
587 652
653### 表反向索引
654
655你可以使用 **#** 操作符来反向索引表中的元素。
656
657```moonscript
658last = data.items[#]
659second_last = data.items[#-1]
660data.items[#] = 1
661```
662<YueDisplay>
663<pre>
664last = data.items[#]
665second_last = data.items[#-1]
666data.items[#] = 1
667</pre>
668</YueDisplay>
669
588### 元表 670### 元表
589 671
590**<>** 操作符可提供元表操作的快捷方式。 672**<>** 操作符可提供元表操作的快捷方式。
591 673
592* **元表创建** 674* **元表创建**
593使用空括号 **<>** 或被 **<>** 包围的元方法键创建普通的Lua表。 675使用空括号 **<>** 或被 **<>** 包围的元方法键创建普通的 Lua 表。
594 676
595```moonscript 677```moonscript
596mt = {} 678mt = {}
@@ -732,7 +814,7 @@ readFile "example.txt"
732 814
733### 空值合并 815### 空值合并
734 816
735如果其左操作数不是**nil**,则nil合并运算符 **??** 返回其左操作数的值;否则,它将计算右操作数并返回其结果。如果左操作数计算结果为非nil的值,**??** 运算符将不再计算其右操作数。 817如果其左操作数不是 **nil**,则nil合并运算符 **??** 返回其左操作数的值;否则,它将计算右操作数并返回其结果。如果左操作数计算结果为非 nil 的值,**??** 运算符将不再计算其右操作数。
736```moonscript 818```moonscript
737local a, b, c, d 819local a, b, c, d
738a = b ?? c ?? d 820a = b ?? c ?? d
@@ -751,67 +833,87 @@ a ??= false
751 833
752### 隐式对象 834### 隐式对象
753 835
754你可以在表格块内使用符号 **\*** 开始编写一系列隐式结构。如果你正在创建隐式对象,对象的字段必须具有相同的缩进。 836你可以在表格块内使用符号 **\*** 或是 **-** 开始编写一系列隐式结构。如果你正在创建隐式对象,对象的字段必须具有相同的缩进。
837
755```moonscript 838```moonscript
839-- 赋值时使用隐式对象
756list = 840list =
757 * 1 841 * 1
758 * 2 842 * 2
759 * 3 843 * 3
760 844
845-- 函数调用时使用隐式对象
761func 846func
762 * 1 847 * 1
763 * 2 848 * 2
764 * 3 849 * 3
765 850
851-- 返回时使用隐式对象
852f = ->
853 return
854 * 1
855 * 2
856 * 3
857
858-- 表格时使用隐式对象
766tb = 859tb =
767 name: "abc" 860 name: "abc"
768 861
769 values: 862 values:
770 * "a" 863 - "a"
771 * "b" 864 - "b"
772 * "c" 865 - "c"
773 866
774 objects: 867 objects:
775 * name: "a" 868 - name: "a"
776 value: 1 869 value: 1
777 func: => @value + 1 870 func: => @value + 1
778 tb: 871 tb:
779 fieldA: 1 872 fieldA: 1
780 873
781 * name: "b" 874 - name: "b"
782 value: 2 875 value: 2
783 func: => @value + 2 876 func: => @value + 2
784 tb: { } 877 tb: { }
785
786``` 878```
787<YueDisplay> 879<YueDisplay>
788<pre> 880<pre>
881-- 赋值时使用隐式对象
789list = 882list =
790 * 1 883 * 1
791 * 2 884 * 2
792 * 3 885 * 3
793 886
887-- 函数调用时使用隐式对象
794func 888func
795 * 1 889 * 1
796 * 2 890 * 2
797 * 3 891 * 3
798 892
893-- 返回时使用隐式对象
894f = ->
895 return
896 * 1
897 * 2
898 * 3
899
900-- 表格时使用隐式对象
799tb = 901tb =
800 name: "abc" 902 name: "abc"
801 903
802 values: 904 values:
803 * "a" 905 - "a"
804 * "b" 906 - "b"
805 * "c" 907 - "c"
806 908
807 objects: 909 objects:
808 * name: "a" 910 - name: "a"
809 value: 1 911 value: 1
810 func: => @value + 1 912 func: => @value + 1
811 tb: 913 tb:
812 fieldA: 1 914 fieldA: 1
813 915
814 * name: "b" 916 - name: "b"
815 value: 2 917 value: 2
816 func: => @value + 2 918 func: => @value + 2
817 tb: { } 919 tb: { }
@@ -991,7 +1093,7 @@ export default ->
991 1093
992## 赋值 1094## 赋值
993 1095
994月之脚本中定义的变量是动态类型的,并默认为局部变量。但你可以通过**local**和**global**声明来改变声明变量的作用范围。 1096月之脚本中定义的变量是动态类型的,并默认为局部变量。但你可以通过 **local** 和 **global** 声明来改变声明变量的作用范围。
995 1097
996```moonscript 1098```moonscript
997hello = "world" 1099hello = "world"
@@ -1120,9 +1222,9 @@ do
1120 1222
1121## 解构赋值 1223## 解构赋值
1122 1224
1123解构赋值是一种快速从Lua表中按名称或基于数组中的位置提取值的方法。 1225解构赋值是一种快速从 Lua 表中按名称或基于数组中的位置提取值的方法。
1124 1226
1125通常当你看到一个字面量的Lua表,比如{1,2,3},它位于赋值的右侧,因为它是一个值。解构赋值语句的写法就是交换了字面量Lua表的角色,并将其放在赋值语句的左侧。 1227通常当你看到一个字面量的 Lua 表,比如 `{1,2,3}`,它位于赋值的右侧,因为它是一个值。解构赋值语句的写法就是交换了字面量 Lua 表的角色,并将其放在赋值语句的左侧。
1126 1228
1127最好是通过示例来解释。以下是如何从表格中解包前两个值的方法: 1229最好是通过示例来解释。以下是如何从表格中解包前两个值的方法:
1128 1230
@@ -1221,7 +1323,7 @@ print first, second, color
1221</pre> 1323</pre>
1222</YueDisplay> 1324</YueDisplay>
1223 1325
1224有时候我们会需要从Lua表中提取值并将它们赋给与键同名的局部变量。为了避免编写重复代码,我们可以使用 **:** 前缀操作符: 1326有时候我们会需要从 Lua 表中提取值并将它们赋给与键同名的局部变量。为了避免编写重复代码,我们可以使用 **:** 前缀操作符:
1225 1327
1226```moonscript 1328```moonscript
1227{:concat, :insert} = table 1329{:concat, :insert} = table
@@ -1265,9 +1367,55 @@ print first, second, color
1265</pre> 1367</pre>
1266</YueDisplay> 1368</YueDisplay>
1267 1369
1268### 在其它地方的解构 1370### 范围解构
1371
1372你可以使用展开运算符 `...` 在列表解构中来捕获一个范围的值到子列表中。这在当你想要从列表的开头和结尾提取特定元素,同时收集中间的元素时非常有用。
1373
1374```moonscript
1375orders = ["first", "second", "third", "fourth", "last"]
1376[first, ...bulk, last] = orders
1377print first -- 打印: first
1378print bulk -- 打印: {"second", "third", "fourth"}
1379print last -- 打印: last
1380```
1381<YueDisplay>
1382<pre>
1383orders = ["first", "second", "third", "fourth", "last"]
1384[first, ...bulk, last] = orders
1385print first -- 打印: first
1386print bulk -- 打印: {"second", "third", "fourth"}
1387print last -- 打印: last
1388</pre>
1389</YueDisplay>
1269 1390
1270解构也可以出现在其它隐式进行赋值的地方。一个例子是用在for循环: 1391展开运算符可以用在不同的位置来捕获不同的范围,并且你可以使用 `_` 作为占位符来表示你想跳过对应范围的捕获:
1392
1393```moonscript
1394-- 捕获第一个元素之后的所有元素
1395[first, ...rest] = orders
1396
1397-- 捕获最后一个元素之前的所有元素
1398[...start, last] = orders
1399
1400-- 跳过中间的元素,只捕获第一个和最后一个元素
1401[first, ..._, last] = orders
1402```
1403<YueDisplay>
1404<pre>
1405-- 捕获第一个元素之后的所有元素
1406[first, ...rest] = orders
1407
1408-- 捕获最后一个元素之前的所有元素
1409[...start, last] = orders
1410
1411-- 跳过中间的元素,只捕获第一个和最后一个元素
1412[first, ..._, last] = orders
1413</pre>
1414</YueDisplay>
1415
1416### 在其它地方的解构赋值
1417
1418解构赋值也可以出现在其它隐式进行赋值的地方。一个例子是用在 for 循环中:
1271 1419
1272```moonscript 1420```moonscript
1273tuples = [ 1421tuples = [
@@ -1290,7 +1438,7 @@ for [left, right] in *tuples
1290</pre> 1438</pre>
1291</YueDisplay> 1439</YueDisplay>
1292 1440
1293我们知道数组表中的每个元素都是一个两项的元组,所以我们可以直接在for语句的名称子句中使用解构来解包它。 1441我们知道数组表中的每个元素都是一个两项的元组,所以我们可以直接在 for 语句的名称子句中使用解构来解包它。
1294 1442
1295## If 赋值 1443## If 赋值
1296 1444
@@ -1358,7 +1506,7 @@ while byte := stream\read_one!
1358 1506
1359## 可变参数赋值 1507## 可变参数赋值
1360 1508
1361你可以将函数返回的结果赋值给一个可变参数符号 `...`。然后使用Lua的方式访问其内容。 1509你可以将函数返回的结果赋值给一个可变参数符号 `...`。然后使用 Lua 的方式访问其内容。
1362```moonscript 1510```moonscript
1363list = [1, 2, 3, 4, 5] 1511list = [1, 2, 3, 4, 5]
1364fn = (ok) -> ok, table.unpack list 1512fn = (ok) -> ok, table.unpack list
@@ -1435,7 +1583,7 @@ func --[[端口]] 3000, --[[ip]] "192.168.1.1"
1435 1583
1436## 错误处理 1584## 错误处理
1437 1585
1438用于统一进行Lua错误处理的便捷语法。 1586用于统一进行 Lua 错误处理的便捷语法。
1439 1587
1440```moonscript 1588```moonscript
1441try 1589try
@@ -1494,9 +1642,50 @@ catch err
1494</pre> 1642</pre>
1495</YueDisplay> 1643</YueDisplay>
1496 1644
1645### 错误处理简化
1646
1647`try?` 是 `try` 的功能简化语法,它不再返回 `try` 语句的布尔状态,并在成功时直接返回 `try` 代码块的结果,失败时返回 `nil` 值而非错误对象。
1648
1649```moonscript
1650a, b, c = try? func!
1651
1652-- 与空值合并运算符一起使用
1653a = (try? func!) ?? "default"
1654
1655-- 作为函数参数
1656f try? func!
1657
1658-- 带 catch 块的 try!
1659f try?
1660 print 123
1661 func!
1662catch e
1663 print e
1664 e
1665```
1666<YueDisplay>
1667<pre>
1668a, b, c = try? func!
1669
1670-- 与空值合并运算符一起使用
1671a = (try? func!) ?? "default"
1672
1673-- 作为函数参数
1674f try? func!
1675
1676-- 带 catch 块的 try!
1677f try?
1678 print 123
1679 func!
1680catch e
1681 print e
1682 e
1683</pre>
1684</YueDisplay>
1685
1497## 属性 1686## 属性
1498 1687
1499月之脚本现在提供了Lua 5.4新增的叫做属性的语法支持。在月之脚本编译到的Lua目标版本低于5.4时,你仍然可以同时使用`const`和`close`的属性声明语法,并获得常量检查和作用域回调的功能。 1688月之脚本现在提供了 Lua 5.4 新增的叫做属性的语法支持。在月之脚本编译到的 Lua 目标版本低于 5.4 时,你仍然可以同时使用`const` 和 `close` 的属性声明语法,并获得常量检查和作用域回调的功能。
1500 1689
1501```moonscript 1690```moonscript
1502const a = 123 1691const a = 123
@@ -1537,9 +1726,9 @@ global const Constant = 123
1537 1726
1538## 字面量 1727## 字面量
1539 1728
1540Lua中的所有基本字面量都可以在月之脚本中使用。包括数字、字符串、布尔值和**nil**。 1729Lua 中的所有基本字面量都可以在月之脚本中使用。包括数字、字符串、布尔值和 **nil**。
1541 1730
1542但与Lua不同的是,单引号和双引号字符串内部允许有换行: 1731但与 Lua 不同的是,单引号和双引号字符串内部允许有换行:
1543 1732
1544```moonscript 1733```moonscript
1545some_string = "这是一个字符串 1734some_string = "这是一个字符串
@@ -1574,6 +1763,66 @@ binary = 0B10011
1574<pre> 1763<pre>
1575integer = 1_000_000 1764integer = 1_000_000
1576hex = 0xEF_BB_BF 1765hex = 0xEF_BB_BF
1766binary = 0B10011
1767</pre>
1768</YueDisplay>
1769
1770### YAML 风格字符串
1771
1772使用 `|` 前缀标记一个多行 YAML 风格字符串:
1773
1774```moonscript
1775str = |
1776 key: value
1777 list:
1778 - item1
1779 - #{expr}
1780```
1781<YueDisplay>
1782<pre>
1783str = |
1784 key: value
1785 list:
1786 - item1
1787 - #{expr}
1788</pre>
1789</YueDisplay>
1790
1791其效果类似于原生 Lua 的多行拼接,所有文本(含换行)将被保留下来,并支持 `#{...}` 语法,通过 `tostring(expr)` 插入表达式结果。
1792
1793YAML 风格的多行字符串会自动检测首行后最小的公共缩进,并从所有行中删除该前缀空白字符。这让你可以在代码中对齐文本,但输出字符串不会带多余缩进。
1794
1795```moonscript
1796fn = ->
1797 str = |
1798 foo:
1799 bar: baz
1800 return str
1801```
1802<YueDisplay>
1803<pre>
1804fn = ->
1805 str = |
1806 foo:
1807 bar: baz
1808 return str
1809</pre>
1810</YueDisplay>
1811
1812输出字符串中的 foo: 对齐到行首,不会带有函数缩进空格。保留内部缩进的相对结构,适合书写结构化嵌套样式的内容。
1813
1814支持自动处理字符中的引号、反斜杠等特殊符号,无需手动转义:
1815
1816```moonscript
1817str = |
1818 path: "C:\Program Files\App"
1819 note: 'He said: "#{Hello}!"'
1820```
1821<YueDisplay>
1822<pre>
1823str = |
1824 path: "C:\Program Files\App"
1825 note: 'He said: "#{Hello}!"'
1577</pre> 1826</pre>
1578</YueDisplay> 1827</YueDisplay>
1579 1828
@@ -1678,7 +1927,7 @@ print "数字的和是", sum 10, 20
1678</pre> 1927</pre>
1679</YueDisplay> 1928</YueDisplay>
1680 1929
1681如果你需要做显式返回,可以使用return关键字: 1930如果你需要做显式返回,可以使用 return 关键字:
1682 1931
1683```moonscript 1932```moonscript
1684sum = (x, y) -> return x + y 1933sum = (x, y) -> return x + y
@@ -1704,7 +1953,7 @@ a, b = mystery 10, 20
1704 1953
1705### 粗箭头 1954### 粗箭头
1706 1955
1707因为在Lua中调用方法时,经常习惯将对象作为第一个参数传入,所以月之脚本提供了一种特殊的语法来创建自动包含self参数的函数。 1956因为在 Lua 中调用方法时,经常习惯将对象作为第一个参数传入,所以月之脚本提供了一种特殊的语法来创建自动包含 self 参数的函数。
1708 1957
1709```moonscript 1958```moonscript
1710func = (num) => @value + num 1959func = (num) => @value + num
@@ -1717,7 +1966,7 @@ func = (num) => @value + num
1717 1966
1718### 参数默认值 1967### 参数默认值
1719 1968
1720可以为函数的参数提供默认值。如果参数的值为nil,则确定该参数为空。任何具有默认值的nil参数在函数体运行之前都会被替换。 1969可以为函数的参数提供默认值。如果参数的值为 nil,则确定该参数为空。任何具有默认值的 nil 参数在函数体运行之前都会被替换。
1721 1970
1722```moonscript 1971```moonscript
1723my_function = (name = "某物", height = 100) -> 1972my_function = (name = "某物", height = 100) ->
@@ -1789,7 +2038,7 @@ my_func 5, 6, 7,
1789</pre> 2038</pre>
1790</YueDisplay> 2039</YueDisplay>
1791 2040
1792因为Lua表也使用逗号作为分隔符,这种缩进语法有助于让值成为参数列表的一部分,而不是Lua表的一部分。 2041因为 Lua 表也使用逗号作为分隔符,这种缩进语法有助于让值成为参数列表的一部分,而不是 Lua 表的一部分。
1793 2042
1794```moonscript 2043```moonscript
1795x = [ 2044x = [
@@ -1856,6 +2105,138 @@ if func 1, 2, 3,
1856</pre> 2105</pre>
1857</YueDisplay> 2106</YueDisplay>
1858 2107
2108### 参数解构
2109
2110月之脚本支持在函数形参位置对传入对象进行解构。适用两类解构表子面量:
2111
2112- 使用 {} 包裹的字面量/对象形参,支持提供获得空字段时的默认值(例如 {:a, :b}、{a: a1 = 123})。
2113
2114- 无 {} 包裹、以键值/简写键序列开头,直至遇到其它表达式终止(例如 :a, b: b1, :c),表示从同一个对象中解构多个字段。
2115
2116```moonscript
2117f1 = (:a, :b, :c) ->
2118 print a, b, c
2119
2120f1 a: 1, b: "2", c: {}
2121
2122f2 = ({a: a1 = 123, :b = 'abc'}, c = {}) ->
2123 print a1, b, c
2124
2125arg1 = {a: 0}
2126f2 arg1, arg2
2127```
2128<YueDisplay>
2129<pre>
2130f1 = (:a, :b, :c) ->
2131 print a, b, c
2132
2133f1 a: 1, b: "2", c: {}
2134
2135f2 = ({a: a1 = 123, :b = 'abc'}, c = {}) ->
2136 print a1, b, c
2137
2138arg1 = {a: 0}
2139f2 arg1, arg2
2140</pre>
2141</YueDisplay>
2142
2143### 前置返回表达式
2144
2145在深度嵌套的函数体中,为了提升返回值的可读性及编写便利性,我们新增了 “前置返回表达式” 语法。其形式如下:
2146
2147```moon
2148findFirstEven = (list): nil ->
2149 for item in *list
2150 if type(item) == "table"
2151 for sub in *item
2152 if sub % 2 == 0
2153 return sub
2154```
2155<YueDisplay>
2156<pre>
2157findFirstEven = (list): nil ->
2158 for item in *list
2159 if type(item) == "table"
2160 for sub in *item
2161 if sub % 2 == 0
2162 return sub
2163</pre>
2164</YueDisplay>
2165
2166这个写法等价于:
2167
2168```moon
2169findFirstEven = (list) ->
2170 for item in *list
2171 if type(item) == "table"
2172 for sub in *item
2173 if sub % 2 == 0
2174 return sub
2175 nil
2176```
2177<YueDisplay>
2178<pre>
2179findFirstEven = (list) ->
2180 for item in *list
2181 if type(item) == "table"
2182 for sub in *item
2183 if sub % 2 == 0
2184 return sub
2185 nil
2186</pre>
2187</YueDisplay>
2188
2189唯一的区别在于:你可以将函数的返回值表达式提前写在 `->` 或 `=>` 前,用以指示该函数应隐式返回该表达式的值。这样即使在多层循环或条件判断的场景下,也无需编写尾行悬挂的返回表达式,逻辑结构会更加直观清晰。
2190
2191### 命名变长参数
2192
2193你可以使用 `(...t) ->` 语法来将变长参数自动存储到一个命名表中。这个表会包含所有传入的参数(包括 `nil` 值),并且会在表的 `n` 字段中存储实际传入的参数个数(包括 `nil` 值在内的个数)。
2194
2195```moonscript
2196f = (...t) ->
2197 print "参数个数:", t.n
2198 print "表长度:", #t
2199 for i = 1, t.n
2200 print t[i]
2201
2202f 1, 2, 3
2203f "a", "b", "c", "d"
2204f!
2205
2206-- 处理包含 nil 的情况
2207process = (...args) ->
2208 sum = 0
2209 for i = 1, args.n
2210 if args[i] != nil and type(args[i]) == "number"
2211 sum += args[i]
2212 sum
2213
2214process 1, nil, 3, nil, 5
2215```
2216<YueDisplay>
2217<pre>
2218f = (...t) ->
2219 print "参数个数:", t.n
2220 print "表长度:", #t
2221 for i = 1, t.n
2222 print t[i]
2223
2224f 1, 2, 3
2225f "a", "b", "c", "d"
2226f!
2227
2228-- 处理包含 nil 的情况
2229process = (...args) ->
2230 sum = 0
2231 for i = 1, args.n
2232 if args[i] != nil and type(args[i]) == "number"
2233 sum += args[i]
2234 sum
2235
2236process 1, nil, 3, nil, 5
2237</pre>
2238</YueDisplay>
2239
1859## 反向回调 2240## 反向回调
1860 2241
1861反向回调用于减少函数回调的嵌套。它们使用指向左侧的箭头,并且默认会被定义为传入后续函数调用的最后一个参数。它的语法大部分与常规箭头函数相同,只是它指向另一方向,并且后续的函数体不需要进行缩进。 2242反向回调用于减少函数回调的嵌套。它们使用指向左侧的箭头,并且默认会被定义为传入后续函数调用的最后一个参数。它的语法大部分与常规箭头函数相同,只是它指向另一方向,并且后续的函数体不需要进行缩进。
@@ -1920,7 +2301,7 @@ print result, msg
1920 2301
1921## 表格字面量 2302## 表格字面量
1922 2303
1923和Lua一样,表格可以通过花括号进行定义。 2304 Lua 一样,表格可以通过花括号进行定义。
1924 2305
1925```moonscript 2306```moonscript
1926some_values = [1, 2, 3, 4] 2307some_values = [1, 2, 3, 4]
@@ -2003,7 +2384,7 @@ y = type: "狗", legs: 4, tails: 1
2003</pre> 2384</pre>
2004</YueDisplay> 2385</YueDisplay>
2005 2386
2006表格字面量的键可以使用Lua语言的关键字,而无需转义: 2387表格字面量的键可以使用 Lua 语言的关键字,而无需转义:
2007 2388
2008```moonscript 2389```moonscript
2009tbl = { 2390tbl = {
@@ -2039,7 +2420,7 @@ print_table :hair, :height
2039</pre> 2420</pre>
2040</YueDisplay> 2421</YueDisplay>
2041 2422
2042如果你希望表中字段的键是某个表达式的结果,那么可以用 **[ ]** 包裹它,就像在Lua中一样。如果键中有任何特殊字符,也可以直接使用字符串字面量作为键,省略方括号。 2423如果你希望表中字段的键是某个表达式的结果,那么可以用 **[ ]** 包裹它,就像在 Lua 中一样。如果键中有任何特殊字符,也可以直接使用字符串字面量作为键,省略方括号。
2043 2424
2044```moonscript 2425```moonscript
2045t = { 2426t = {
@@ -2056,7 +2437,7 @@ t = {
2056</pre> 2437</pre>
2057</YueDisplay> 2438</YueDisplay>
2058 2439
2059Lua的表同时具有数组部分和哈希部分,但有时候你会希望在书写Lua表时,对Lua表做数组和哈希不同用法的语义区分。然后你可以用 **[ ]** 而不是 **{ }** 来编写表示数组的 Lua 表,并且不允许在数组 Lua 表中写入任何键值对。 2440Lua 的表同时具有数组部分和哈希部分,但有时候你会希望在书写 Lua 表时,对 Lua 表做数组和哈希不同用法的语义区分。然后你可以用 **[ ]** 而不是 **{ }** 来编写表示数组的 Lua 表,并且不允许在数组 Lua 表中写入任何键值对。
2060 2441
2061```moonscript 2442```moonscript
2062some_values = [ 1, 2, 3, 4 ] 2443some_values = [ 1, 2, 3, 4 ]
@@ -2071,11 +2452,11 @@ list_with_one_element = [ 1, ]
2071 2452
2072## 推导式 2453## 推导式
2073 2454
2074推导式为我们提供了一种便捷的语法,通过遍历现有对象并对其值应用表达式来构造出新的表格。月之脚本有两种推导式:列表推导式和表格推导式。它们最终都是产生Lua表格;列表推导式将值累积到类似数组的表格中,而表格推导式允许你在每次遍历时设置新表格的键和值。 2455推导式为我们提供了一种便捷的语法,通过遍历现有对象并对其值应用表达式来构造出新的表格。月之脚本有两种推导式:列表推导式和表格推导式。它们最终都是产生 Lua 表格;列表推导式将值累积到类似数组的表格中,而表格推导式允许你在每次遍历时设置新表格的键和值。
2075 2456
2076### 列表推导式 2457### 列表推导式
2077 2458
2078以下操作创建了一个items表的副本,但所有包含的值都翻倍了。 2459以下操作创建了一个 items 表的副本,但所有包含的值都翻倍了。
2079 2460
2080```moonscript 2461```moonscript
2081items = [1, 2, 3, 4] 2462items = [1, 2, 3, 4]
@@ -2088,7 +2469,7 @@ doubled = [item * 2 for i, item in ipairs items]
2088</pre> 2469</pre>
2089</YueDisplay> 2470</YueDisplay>
2090 2471
2091可以使用when子句筛选新表中包含的项目: 2472可以使用 `when` 子句筛选新表中包含的项目:
2092 2473
2093```moonscript 2474```moonscript
2094slice = [item for i, item in ipairs items when i > 1 and i < 3] 2475slice = [item for i, item in ipairs items when i > 1 and i < 3]
@@ -2099,7 +2480,7 @@ slice = [item for i, item in ipairs items when i > 1 and i < 3]
2099</pre> 2480</pre>
2100</YueDisplay> 2481</YueDisplay>
2101 2482
2102因为我们常常需要迭代数值索引表的值,所以引入了 **\*** 操作符来做语法简化。doubled示例可以重写为: 2483因为我们常常需要迭代数值索引表的值,所以引入了 **\*** 操作符来做语法简化。doubled 示例可以重写为:
2103 2484
2104```moonscript 2485```moonscript
2105doubled = [item * 2 for item in *items] 2486doubled = [item * 2 for item in *items]
@@ -2110,9 +2491,30 @@ doubled = [item * 2 for item in *items]
2110</pre> 2491</pre>
2111</YueDisplay> 2492</YueDisplay>
2112 2493
2113for和when子句可以根据需要进行链式操作。唯一的要求是推导式中至少要有一个for子句。 2494在列表推导式中,你还可以使用展开操作符 `...` 来实现对列表嵌套层级进行扁平化的处理:
2495
2496```moonscript
2497data =
2498 a: [1, 2, 3]
2499 b: [4, 5, 6]
2500
2501flat = [...v for k,v in pairs data]
2502-- flat 现在为 [1, 2, 3, 4, 5, 6]
2503```
2504<YueDisplay>
2505<pre>
2506data =
2507 a: [1, 2, 3]
2508 b: [4, 5, 6]
2509
2510flat = [...v for k,v in pairs data]
2511-- flat 现在为 [1, 2, 3, 4, 5, 6]
2512</pre>
2513</YueDisplay>
2514
2515for 和 when 子句可以根据需要进行链式操作。唯一的要求是推导式中至少要有一个 for 子句。
2114 2516
2115使用多个for子句与使用多重循环的效果相同: 2517使用多个 for 子句与使用多重循环的效果相同:
2116 2518
2117```moonscript 2519```moonscript
2118x_coords = [4, 5, 6, 7] 2520x_coords = [4, 5, 6, 7]
@@ -2131,7 +2533,7 @@ for y in *y_coords]
2131</pre> 2533</pre>
2132</YueDisplay> 2534</YueDisplay>
2133 2535
2134在推导式中也可以使用简单的数值for循环: 2536在推导式中也可以使用简单的数值 for 循环:
2135 2537
2136```moonscript 2538```moonscript
2137evens = [i for i = 1, 100 when i % 2 == 0] 2539evens = [i for i = 1, 100 when i % 2 == 0]
@@ -2146,7 +2548,7 @@ evens = [i for i = 1, 100 when i % 2 == 0]
2146 2548
2147表格推导式和列表推导式的语法非常相似,只是要使用 **{** 和 **}** 并从每次迭代中取两个值。 2549表格推导式和列表推导式的语法非常相似,只是要使用 **{** 和 **}** 并从每次迭代中取两个值。
2148 2550
2149以下示例生成了表格thing的副本: 2551以下示例生成了表格 thing 的副本:
2150 2552
2151```moonscript 2553```moonscript
2152thing = { 2554thing = {
@@ -2208,9 +2610,9 @@ tbl = {unpack tuple for tuple in *tuples}
2208 2610
2209### 切片 2611### 切片
2210 2612
2211当使用 **\*** 操作符时,月之脚本还提供了一种特殊的语法来限制要遍历的列表范围。这个语法也相当于在for循环中设置迭代边界和步长。 2613当使用 **\*** 操作符时,月之脚本还提供了一种特殊的语法来限制要遍历的列表范围。这个语法也相当于在 for 循环中设置迭代边界和步长。
2212 2614
2213下面的案例中,我们在切片中设置最小和最大边界,取索引在1到5之间(包括1和5)的所有项目: 2615下面的案例中,我们在切片中设置最小和最大边界,取索引在 1 到 5 之间(包括 1 和 5)的所有项目:
2214 2616
2215```moonscript 2617```moonscript
2216slice = [item for item in *items[1, 5]] 2618slice = [item for item in *items[1, 5]]
@@ -2232,7 +2634,7 @@ slice = [item for item in *items[2,]]
2232</pre> 2634</pre>
2233</YueDisplay> 2635</YueDisplay>
2234 2636
2235如果省略了最小边界,便默认会设置为1。这里我们只提供一个步长,并留下其他边界为空。这样会使得代码取出所有奇数索引的项目:(1, 3, 5, …) 2637如果省略了最小边界,便默认会设置为 1。这里我们只提供一个步长,并留下其他边界为空。这样会使得代码取出所有奇数索引的项目:(1, 3, 5, …)
2236 2638
2237```moonscript 2639```moonscript
2238slice = [item for item in *items[,,2]] 2640slice = [item for item in *items[,,2]]
@@ -2244,9 +2646,48 @@ slice = [item for item in *items[,,2]]
2244</pre> 2646</pre>
2245</YueDisplay> 2647</YueDisplay>
2246 2648
2649最小和最大边界都可以是负数,使用负数意味着边界是从表的末尾开始计算的。
2650
2651```moonscript
2652-- 取最后4个元素
2653slice = [item for item in *items[-4,-1]]
2654```
2655<YueDisplay>
2656<pre>
2657-- 取最后4个元素
2658slice = [item for item in *items[-4,-1]]
2659</pre>
2660</YueDisplay>
2661
2662切片的步长也可以是负数,这意味着元素会以相反的顺序被取出。
2663
2664```moonscript
2665reverse_slice = [item for item in *items[-1,1,-1]]
2666```
2667<YueDisplay>
2668<pre>
2669reverse_slice = [item for item in *items[-1,1,-1]]
2670</pre>
2671</YueDisplay>
2672
2673#### 切片表达式
2674
2675切片也可以作为表达式来使用。可以用于获取一个表包含的子列表。
2676
2677```moonscript
2678-- 取第2和第4个元素作为新的列表
2679sub_list = items[2, 4]
2680```
2681<YueDisplay>
2682<pre>
2683-- 取第2和第4个元素作为新的列表
2684sub_list = items[2, 4]
2685</pre>
2686</YueDisplay>
2687
2247## for 循环 2688## for 循环
2248 2689
2249Lua中有两种for循环形式,数字型和通用型: 2690Lua 中有两种 for 循环形式,数字型和通用型:
2250 2691
2251```moonscript 2692```moonscript
2252for i = 10, 20 2693for i = 10, 20
@@ -2299,7 +2740,7 @@ for j = 1, 10, 3 do print j
2299</pre> 2740</pre>
2300</YueDisplay> 2741</YueDisplay>
2301 2742
2302for循环也可以用作表达式。for循环主体中的最后一条语句会被强制转换为一个返回值的表达式,并会将表达式计算结果的值追加到一个作为结果的数组表中。 2743for 循环也可以用作表达式。for 循环主体中的最后一条语句会被强制转换为一个返回值的表达式,并会将表达式计算结果的值追加到一个作为结果的数组表中。
2303 2744
2304将每个偶数加倍: 2745将每个偶数加倍:
2305 2746
@@ -2320,9 +2761,9 @@ doubled_evens = for i = 1, 20
2320</pre> 2761</pre>
2321</YueDisplay> 2762</YueDisplay>
2322 2763
2323此外,for循环还支持带返回值的break语句,这样循环本身就可以作为一个表达式,在满足条件时提前退出并返回有意义的结果。 2764此外,for 循环还支持带返回值的 break 语句,这样循环本身就可以作为一个表达式,在满足条件时提前退出并返回有意义的结果。
2324 2765
2325例如,查找第一个大于10的数字: 2766例如,查找第一个大于 10 的数字:
2326 2767
2327```moonscript 2768```moonscript
2328first_large = for n in *numbers 2769first_large = for n in *numbers
@@ -2335,9 +2776,9 @@ first_large = for n in *numbers
2335</pre> 2776</pre>
2336</YueDisplay> 2777</YueDisplay>
2337 2778
2338你还可以结合for循环表达式与continue语句来过滤值。 2779你还可以结合 for 循环表达式与 continue 语句来过滤值。
2339 2780
2340注意出现在函数体末尾的for循环,不会被当作是一个表达式并将循环结果累积到一个列表中作为返回值(相反,函数将返回nil)。如果要函数末尾的循环转换为列表表达式,可以显式地使用返回语句加for循环表达式。 2781注意出现在函数体末尾的 for 循环,不会被当作是一个表达式并将循环结果累积到一个列表中作为返回值(相反,函数将返回 nil)。如果要函数末尾的循环转换为列表表达式,可以显式地使用返回语句加 for 循环表达式。
2341 2782
2342```moonscript 2783```moonscript
2343func_a = -> for i = 1, 10 do print i 2784func_a = -> for i = 1, 10 do print i
@@ -2360,7 +2801,7 @@ print func_b! -- 打印 table 对象
2360 2801
2361## repeat 循环 2802## repeat 循环
2362 2803
2363repeat循环是从Lua语言中搬过来的相似语法: 2804repeat 循环是从 Lua 语言中搬过来的相似语法:
2364 2805
2365```moonscript 2806```moonscript
2366i = 10 2807i = 10
@@ -2381,7 +2822,7 @@ until i == 0
2381 2822
2382## while 循环 2823## while 循环
2383 2824
2384在月之脚本中的while循环有四种写法: 2825在月之脚本中的 while 循环有四种写法:
2385 2826
2386```moonscript 2827```moonscript
2387i = 10 2828i = 10
@@ -2420,7 +2861,7 @@ until running == false do my_function!
2420</pre> 2861</pre>
2421</YueDisplay> 2862</YueDisplay>
2422 2863
2423像for循环的语法一样,while循环也可以作为一个表达式使用。为了使函数返回while循环的累积列表值,必须明确使用返回语句返回while循环表达式。 2864像 for 循环的语法一样,while 循环也可以作为一个表达式使用。为了使函数返回 while 循环的累积列表值,必须明确使用返回语句返回 while 循环表达式。
2424 2865
2425## 继续 2866## 继续
2426 2867
@@ -2538,13 +2979,14 @@ print message -- 打印: 我很高
2538</pre> 2979</pre>
2539</YueDisplay> 2980</YueDisplay>
2540 2981
2541if的反义词是unless(相当于if not,如果 vs 除非): 2982if 的反义词是 unless(相当于 if not,“如”对应“除非):
2542 2983
2543```moonscript 2984```moonscript
2544unless os.date("%A") == "Monday" 2985unless os.date("%A") == "Monday"
2545 print "今天不是星期一!" 2986 print "今天不是星期一!"
2546``` 2987```
2547<YueDisplay> 2988<YueDisplay>
2989
2548<pre> 2990<pre>
2549unless os.date("%A") == "Monday" 2991unless os.date("%A") == "Monday"
2550 print "今天不是星期一!" 2992 print "今天不是星期一!"
@@ -2596,7 +3038,7 @@ print "你很幸运!" unless math.random! > 0.1
2596 3038
2597## 代码行修饰符 3039## 代码行修饰符
2598 3040
2599为了方便编写代码,循环语句和if语句可以应用于单行代码语句的末尾: 3041为了方便编写代码,循环语句和 if 语句可以应用于单行代码语句的末尾:
2600 3042
2601```moonscript 3043```moonscript
2602print "你好,世界" if name == "Rob" 3044print "你好,世界" if name == "Rob"
@@ -2607,7 +3049,7 @@ print "你好,世界" if name == "Rob"
2607</pre> 3049</pre>
2608</YueDisplay> 3050</YueDisplay>
2609 3051
2610修饰for循环的示例: 3052修饰 for 循环的示例:
2611 3053
2612```moonscript 3054```moonscript
2613print "项目: ", item for item in *items 3055print "项目: ", item for item in *items
@@ -2618,7 +3060,7 @@ print "项目: ", item for item in *items
2618</pre> 3060</pre>
2619</YueDisplay> 3061</YueDisplay>
2620 3062
2621修饰while循环的示例: 3063修饰 while 循环的示例:
2622 3064
2623```moonscript 3065```moonscript
2624game\update! while game\isRunning! 3066game\update! while game\isRunning!
@@ -2635,34 +3077,32 @@ reader\parse_line! until reader\eof!
2635 3077
2636## switch 语句 3078## switch 语句
2637 3079
2638switch语句是为了简化检查一系列相同值的if语句而提供的简写语法。要注意用于比较检查的目标值只会计算一次。和if语句一样,switch语句在最后可以接一个else代码块来处理没有匹配的情况。在生成的Lua代码中,进行比较是使用==操作符完成的。 3080switch 语句是为了简化检查一系列相同值的if语句而提供的简写语法。要注意用于比较检查的目标值只会计算一次。和 if 语句一样,switch 语句在最后可以接一个 else 代码块来处理没有匹配的情况。在生成的 Lua 代码中,进行比较是使用 == 操作符完成的。switch 语句中也可以使用赋值表达式来储存临时变量值。
2639 3081
2640```moonscript 3082```moonscript
2641name = "Dan" 3083switch name := "Dan"
2642switch name
2643 when "Robert" 3084 when "Robert"
2644 print "你是Robert" 3085 print "你是Robert"
2645 when "Dan", "Daniel" 3086 when "Dan", "Daniel"
2646 print "你的名字是Dan" 3087 print "你的名字是Dan"
2647 else 3088 else
2648 print "我不知道你的名字" 3089 print "我不认识,你的名字是#{name}"
2649``` 3090```
2650<YueDisplay> 3091<YueDisplay>
2651<pre> 3092<pre>
2652name = "Dan" 3093switch name := "Dan"
2653switch name
2654 when "Robert" 3094 when "Robert"
2655 print "你是Robert" 3095 print "你是Robert"
2656 when "Dan", "Daniel" 3096 when "Dan", "Daniel"
2657 print "你的名字是Dan" 3097 print "你的名字是Dan"
2658 else 3098 else
2659 print "我不知道你的名字" 3099 print "我不认识,你的名字是#{name}"
2660</pre> 3100</pre>
2661</YueDisplay> 3101</YueDisplay>
2662 3102
2663switch语句的when子句中可以通过使用逗号分隔的列表来匹配多个值。 3103switch 语句的 when 子句中可以通过使用逗号分隔的列表来匹配多个值。
2664 3104
2665switch语句也可以作为表达式使用,下面我们可以将switch语句返回的结果分配给一个变量: 3105switch 语句也可以作为表达式使用,下面我们可以将 switch 语句返回的结果分配给一个变量:
2666 3106
2667```moonscript 3107```moonscript
2668b = 1 3108b = 1
@@ -2687,7 +3127,7 @@ next_number = switch b
2687</pre> 3127</pre>
2688</YueDisplay> 3128</YueDisplay>
2689 3129
2690我们可以使用then关键字在when子句的同一行上编写处理代码。else代码块的后续代码中要写在同一行上不需要额外的关键字。 3130我们可以使用 then 关键字在 when 子句的同一行上编写处理代码。else 代码块的后续代码中要写在同一行上不需要额外的关键字。
2691 3131
2692```moonscript 3132```moonscript
2693msg = switch math.random(1, 5) 3133msg = switch math.random(1, 5)
@@ -2704,7 +3144,7 @@ msg = switch math.random(1, 5)
2704</pre> 3144</pre>
2705</YueDisplay> 3145</YueDisplay>
2706 3146
2707如果在编写switch语句时希望少写一个缩进,那么你可以把第一个when子句放在switch开始语句的第一行,然后后续的子语句就都可以都少写一个缩进。 3147如果在编写 switch 语句时希望少写一个缩进,那么你可以把第一个 when 子句放在 switch 开始语句的第一行,然后后续的子语句就都可以都少写一个缩进。
2708 3148
2709```moonscript 3149```moonscript
2710switch math.random(1, 5) 3150switch math.random(1, 5)
@@ -2733,11 +3173,11 @@ else
2733</pre> 3173</pre>
2734</YueDisplay> 3174</YueDisplay>
2735 3175
2736值得注意的是,在生成Lua代码时,我们要做检查的目标变量会放在==表达式的右侧。当你希望给when子句的比较对象定义一个\_\_eq元方法来重载判断逻辑时,可能会有用。 3176值得注意的是,在生成 Lua 代码时,我们要做检查的目标变量会放在 == 表达式的右侧。当你希望给 when 子句的比较对象定义一个 \_\_eq 元方法来重载判断逻辑时,可能会有用。
2737 3177
2738### 表格匹配 3178### 表格匹配
2739 3179
2740在switch的when子句中,如果期待检查目标是一个表格,且可以通过特定的结构进行解构并获得非nil值,那么你可以尝试使用表格匹配的语法。 3180在 switch 的 when 子句中,如果期待检查目标是一个表格,且可以通过特定的结构进行解构并获得非 nil 值,那么你可以尝试使用表格匹配的语法。
2741 3181
2742```moonscript 3182```moonscript
2743items = 3183items =
@@ -2889,9 +3329,30 @@ switch tb
2889</pre> 3329</pre>
2890</YueDisplay> 3330</YueDisplay>
2891 3331
3332匹配一个列表并捕获特定范围内的元素。
3333
3334```moonscript
3335segments = ["admin", "users", "logs", "view"]
3336switch segments
3337 when [...groups, resource, action]
3338 print "Group:", groups -- 打印: {"admin", "users"}
3339 print "Resource:", resource -- 打印: "logs"
3340 print "Action:", action -- 打印: "view"
3341```
3342<YueDisplay>
3343<pre>
3344segments = ["admin", "users", "logs", "view"]
3345switch segments
3346 when [...groups, resource, action]
3347 print "Group:", groups -- 打印: {"admin", "users"}
3348 print "Resource:", resource -- 打印: "logs"
3349 print "Action:", action -- 打印: "view"
3350</pre>
3351</YueDisplay>
3352
2892## 面向对象编程 3353## 面向对象编程
2893 3354
2894在以下的示例中,月之脚本生成的Lua代码可能看起来会很复杂。所以最好主要关注月之脚本代码层面的意义,然后如果你想知道关于面向对象功能的实现细节,再查看Lua代码。 3355在以下的示例中,月之脚本生成的 Lua 代码可能看起来会很复杂。所以最好主要关注月之脚本代码层面的意义,然后如果你想知道关于面向对象功能的实现细节,再查看 Lua 代码。
2895 3356
2896一个简单的类: 3357一个简单的类:
2897 3358
@@ -2920,11 +3381,11 @@ class Inventory
2920</pre> 3381</pre>
2921</YueDisplay> 3382</YueDisplay>
2922 3383
2923在月之脚本中采用面向对象的编程方式时,通常会使用类声明语句结合Lua表格字面量来做类定义。这个类的定义包含了它的所有方法和属性。在这种结构中,键名为“new”的成员扮演了一个重要的角色,是作为构造函数来使用。 3384在月之脚本中采用面向对象的编程方式时,通常会使用类声明语句结合 Lua 表格字面量来做类定义。这个类的定义包含了它的所有方法和属性。在这种结构中,键名为 “new” 的成员扮演了一个重要的角色,是作为构造函数来使用。
2924 3385
2925值得注意的是,类中的方法都采用了粗箭头函数语法。当在类的实例上调用方法时,该实例会自动作为第一个参数被传入,因此粗箭头函数用于生成一个名为“self”的参数。 3386值得注意的是,类中的方法都采用了粗箭头函数语法。当在类的实例上调用方法时,该实例会自动作为第一个参数被传入,因此粗箭头函数用于生成一个名为 “self” 的参数。
2926 3387
2927此外,“@”前缀在变量名上起到了简化作用,代表“self”。例如,`@items` 就等同于 `self.items`。 3388此外,“@” 前缀在变量名上起到了简化作用,代表 “self”。例如,`@items` 就等同于 `self.items`。
2928 3389
2929为了创建类的一个新实例,可以将类名当作一个函数来调用,这样就可以生成并返回一个新的实例。 3390为了创建类的一个新实例,可以将类名当作一个函数来调用,这样就可以生成并返回一个新的实例。
2930 3391
@@ -2946,7 +3407,7 @@ inv\add_item "pants"
2946 3407
2947需要特别注意的是,类的所有属性在其实例之间是共享的。这对于函数类型的成员属性通常不会造成问题,但对于其他类型的属性,可能会导致意外的结果。 3408需要特别注意的是,类的所有属性在其实例之间是共享的。这对于函数类型的成员属性通常不会造成问题,但对于其他类型的属性,可能会导致意外的结果。
2948 3409
2949例如,在下面的示例中,clothes属性在所有实例之间共享。因此,对这个属性在一个实例中的修改,将会影响到其他所有实例。 3410例如,在下面的示例中,clothes 属性在所有实例之间共享。因此,对这个属性在一个实例中的修改,将会影响到其他所有实例。
2950 3411
2951```moonscript 3412```moonscript
2952class Person 3413class Person
@@ -2998,7 +3459,7 @@ class Person
2998 3459
2999### 继承 3460### 继承
3000 3461
3001`extends`关键字可以在类声明中使用,以继承另一个类的属性和方法。 3462`extends` 关键字可以在类声明中使用,以继承另一个类的属性和方法。
3002 3463
3003```moonscript 3464```moonscript
3004class BackPack extends Inventory 3465class BackPack extends Inventory
@@ -3018,11 +3479,11 @@ class BackPack extends Inventory
3018</YueDisplay> 3479</YueDisplay>
3019 3480
3020 3481
3021在这一部分,我们对月之脚本中的`Inventory`类进行了扩展,加入了对可以携带物品数量的限制。 3482在这一部分,我们对月之脚本中的 `Inventory` 类进行了扩展,加入了对可以携带物品数量的限制。
3022 3483
3023在这个特定的例子中,子类并没有定义自己的构造函数。因此,当创建一个新的实例时,系统会默认调用父类的构造函数。但如果我们在子类中定义了构造函数,我们可以利用`super`方法来调用并执行父类的构造函数。 3484在这个特定的例子中,子类并没有定义自己的构造函数。因此,当创建一个新的实例时,系统会默认调用父类的构造函数。但如果我们在子类中定义了构造函数,我们可以利用 `super` 方法来调用并执行父类的构造函数。
3024 3485
3025此外,当一个类继承自另一个类时,它会尝试调用父类上的`__inherited`方法(如果这个方法存在的话),以此来向父类发送通知。这个`__inherited`函数接受两个参数:被继承的父类和继承的子类。 3486此外,当一个类继承自另一个类时,它会尝试调用父类上的 `__inherited` 方法(如果这个方法存在的话),以此来向父类发送通知。这个 `__inherited` 函数接受两个参数:被继承的父类和继承的子类。
3026 3487
3027```moonscript 3488```moonscript
3028class Shelf 3489class Shelf
@@ -3045,15 +3506,15 @@ class Cupboard extends Shelf
3045 3506
3046### super 关键字 3507### super 关键字
3047 3508
3048`super`是一个特别的关键字,它有两种不同的使用方式:既可以当作一个对象来看待,也可以像调用函数那样使用。它仅在类的内部使用时具有特殊的功能。 3509`super` 是一个特别的关键字,它有两种不同的使用方式:既可以当作一个对象来看待,也可以像调用函数那样使用。它仅在类的内部使用时具有特殊的功能。
3049 3510
3050当`super`被作为一个函数调用时,它将调用父类中与之同名的函数。此时,当前的`self`会自动作为第一个参数传递,正如上面提到的继承示例所展示的那样。 3511当 `super` 被作为一个函数调用时,它将调用父类中与之同名的函数。此时,当前的 `self` 会自动作为第一个参数传递,正如上面提到的继承示例所展示的那样。
3051 3512
3052在将`super`当作普通值使用时,它实际上是对父类对象的引用。通过这种方式,我们可以访问父类中可能被子类覆盖的值,就像访问任何普通对象一样。 3513在将 `super` 当作普通值使用时,它实际上是对父类对象的引用。通过这种方式,我们可以访问父类中可能被子类覆盖的值,就像访问任何普通对象一样。
3053 3514
3054此外,当使用`\`操作符与`super`一起使用时,`self`将被插入为第一个参数,而不是使用`super`本身的值。而在使用`.`操作符来检索函数时,则会返回父类中的原始函数。 3515此外,当使用 `\` 操作符与 `super` 一起使用时,`self`将被插入为第一个参数,而不是使用 `super` 本身的值。而在使用`.`操作符来检索函数时,则会返回父类中的原始函数。
3055 3516
3056下面是一些使用`super`的不同方法的示例: 3517下面是一些使用 `super` 的不同方法的示例:
3057 3518
3058```moonscript 3519```moonscript
3059class MyClass extends ParentClass 3520class MyClass extends ParentClass
@@ -3112,9 +3573,9 @@ print BackPack.size -- 打印 10
3112 3573
3113如果在类对象的元表中找不到某个属性,系统会从基表中检索该属性。这就意味着我们可以直接从类本身访问到其方法和属性。 3574如果在类对象的元表中找不到某个属性,系统会从基表中检索该属性。这就意味着我们可以直接从类本身访问到其方法和属性。
3114 3575
3115需要特别注意的是,对类对象的赋值并不会影响到基表,因此这不是向实例添加新方法的正确方式。相反,需要直接修改基表。关于这点,可以参考下面的“__base”字段。 3576需要特别注意的是,对类对象的赋值并不会影响到基表,因此这不是向实例添加新方法的正确方式。相反,需要直接修改基表。关于这点,可以参考下面的 “__base” 字段。
3116 3577
3117此外,类对象包含几个特殊的属性:当类被声明时,类的名称会作为一个字符串存储在类对象的“__name”字段中。 3578此外,类对象包含几个特殊的属性:当类被声明时,类的名称会作为一个字符串存储在类对象的 “__name” 字段中。
3118 3579
3119```moonscript 3580```moonscript
3120print BackPack.__name -- 打印 Backpack 3581print BackPack.__name -- 打印 Backpack
@@ -3196,7 +3657,7 @@ print Counter.count -- 输出 2
3196 3657
3197### 类声明语句 3658### 类声明语句
3198 3659
3199在类声明的主体中,除了键/值对外,我们还可以编写普通的表达式。在这种类声明体中的普通代码的上下文中,self等于类对象,而不是实例对象。 3660在类声明的主体中,除了键/值对外,我们还可以编写普通的表达式。在这种类声明体中的普通代码的上下文中,self 等于类对象,而不是实例对象。
3200 3661
3201以下是创建类变量的另一种方法: 3662以下是创建类变量的另一种方法:
3202 3663
@@ -3236,9 +3697,9 @@ class MoreThings
3236 3697
3237### @ 和 @@ 值 3698### @ 和 @@ 值
3238 3699
3239当@和@@前缀在一个名字前时,它们分别代表在self和self.\_\_class中访问的那个名字。 3700 @ @@ 前缀在一个名字前时,它们分别代表在 self self.\_\_class 中访问的那个名字。
3240 3701
3241如果它们单独使用,它们是self和self.\_\_class的别名。 3702如果它们单独使用,它们是 self self.\_\_class 的别名。
3242 3703
3243```moonscript 3704```moonscript
3244assert @ == self 3705assert @ == self
@@ -3251,7 +3712,7 @@ assert @@ == self.__class
3251</pre> 3712</pre>
3252</YueDisplay> 3713</YueDisplay>
3253 3714
3254例如,使用@@从实例方法快速创建同一类的新实例的方法: 3715例如,使用 @@ 从实例方法快速创建同一类的新实例的方法:
3255 3716
3256```moonscript 3717```moonscript
3257some_instance_method = (...) => @@ ... 3718some_instance_method = (...) => @@ ...
@@ -3329,7 +3790,7 @@ x = class Bucket
3329 3790
3330### 匿名类 3791### 匿名类
3331 3792
3332声明类时可以省略名称。如果类的表达式不在赋值语句中,\_\_name属性将为nil。如果出现在赋值语句中,赋值操作左侧的名称将代替nil。 3793声明类时可以省略名称。如果类的表达式不在赋值语句中,\_\_name 属性将为 nil。如果出现在赋值语句中,赋值操作左侧的名称将代替 nil。
3333 3794
3334```moonscript 3795```moonscript
3335BigBucket = class extends Bucket 3796BigBucket = class extends Bucket
@@ -3400,11 +3861,11 @@ assert y.__class.__parent ~= X -- X 不是 Y 的父类
3400 3861
3401## with 语句 3862## with 语句
3402 3863
3403在编写Lua代码时,我们在创建对象后的常见操作是立即调用这个对象一系列操作函数并设置一系列属性。 3864在编写 Lua 代码时,我们在创建对象后的常见操作是立即调用这个对象一系列操作函数并设置一系列属性。
3404 3865
3405这导致在代码中多次重复引用对象的名称,增加了不必要的文本噪音。一个常见的解决方案是在创建对象时,在构造函数传入一个表,该表包含要覆盖设置的键和值的集合。这样做的缺点是该对象的构造函数必须支持这种初始化形式。 3866这导致在代码中多次重复引用对象的名称,增加了不必要的文本噪音。一个常见的解决方案是在创建对象时,在构造函数传入一个表,该表包含要覆盖设置的键和值的集合。这样做的缺点是该对象的构造函数必须支持这种初始化形式。
3406 3867
3407with块有助于简化编写这样的代码。在with块内,我们可以使用以.或\开头的特殊语句,这些语句代表我们正在使用的对象的操作。 3868with 块有助于简化编写这样的代码。在 with 块内,我们可以使用以 . 或 \ 开头的特殊语句,这些语句代表我们正在使用的对象的操作。
3408 3869
3409例如,我们可以这样处理一个新创建的对象: 3870例如,我们可以这样处理一个新创建的对象:
3410 3871
@@ -3425,7 +3886,7 @@ with Person!
3425</pre> 3886</pre>
3426</YueDisplay> 3887</YueDisplay>
3427 3888
3428with语句也可以用作一个表达式,并返回它的代码块正在处理的对象。 3889with 语句也可以用作一个表达式,并返回它的代码块正在处理的对象。
3429 3890
3430```moonscript 3891```moonscript
3431file = with File "favorite_foods.txt" 3892file = with File "favorite_foods.txt"
@@ -3459,24 +3920,24 @@ me = create_person "Leaf", [dad, mother, sister]
3459</pre> 3920</pre>
3460</YueDisplay> 3921</YueDisplay>
3461 3922
3462在此用法中,with可以被视为K组合子(k-combinator)的一种特殊形式。 3923在此用法中,with 可以被视为K组合子(k-combinator)的一种特殊形式。
3463 3924
3464如果你想给表达式另外起一个名称的话,with语句中的表达式也可以是一个赋值语句。 3925如果你想给表达式另外起一个名称的话,with 语句中的表达式也可以是一个赋值语句。
3465 3926
3466```moonscript 3927```moonscript
3467with str = "你好" 3928with str := "你好"
3468 print "原始:", str 3929 print "原始:", str
3469 print "大写:", \upper! 3930 print "大写:", \upper!
3470``` 3931```
3471<YueDisplay> 3932<YueDisplay>
3472<pre> 3933<pre>
3473with str = "你好" 3934with str := "你好"
3474 print "原始:", str 3935 print "原始:", str
3475 print "大写:", \upper! 3936 print "大写:", \upper!
3476</pre> 3937</pre>
3477</YueDisplay> 3938</YueDisplay>
3478 3939
3479在with语句中用`[]`访问特殊键。 3940 `with` 语句中使用 `[]` 访问特殊键。
3480 3941
3481```moonscript 3942```moonscript
3482with tb 3943with tb
@@ -3499,9 +3960,22 @@ with tb
3499</pre> 3960</pre>
3500</YueDisplay> 3961</YueDisplay>
3501 3962
3963`with?` 是 `with` 语法的一个增强版本,引入了存在性检查,用于在不显式判空的情况下安全访问可能为 nil 的对象。
3964
3965```moonscript
3966with? obj
3967 print obj.name
3968```
3969<YueDisplay>
3970<pre>
3971with? obj
3972 print obj.name
3973</pre>
3974</YueDisplay>
3975
3502## do 语句 3976## do 语句
3503 3977
3504当用作语句时,do语句的作用就像在Lua中差不多。 3978当用作语句时,do 语句的作用就像在 Lua 中差不多。
3505 3979
3506```moonscript 3980```moonscript
3507do 3981do
@@ -3518,7 +3992,7 @@ print var -- 这里是nil
3518</pre> 3992</pre>
3519</YueDisplay> 3993</YueDisplay>
3520 3994
3521月之脚本的 **do** 也可以用作表达式。允许你将多行代码的处理合并为一个表达式,并将do语句代码块的最后一个语句作为表达式返回的结果。 3995月之脚本的 **do** 也可以用作表达式。允许你将多行代码的处理合并为一个表达式,并将 do 语句代码块的最后一个语句作为表达式返回的结果。
3522 3996
3523```moonscript 3997```moonscript
3524counter = do 3998counter = do
@@ -3702,7 +4176,7 @@ print i, k -- 这些已经被更新
3702 4176
3703## 月之脚本语言库 4177## 月之脚本语言库
3704 4178
3705使用`require("yue")`来访问。 4179使用 `require("yue")` 来访问。
3706 4180
3707### yue 4181### yue
3708 4182
@@ -3760,9 +4234,9 @@ yue_compiled: {string: string}
3760**签名:** 4234**签名:**
3761```lua 4235```lua
3762to_lua: function(code: string, config?: Config): 4236to_lua: function(code: string, config?: Config):
3763 --[[codes]] string | nil, 4237 --[[codes]] string | nil,
3764 --[[error]] string | nil, 4238 --[[error]] string | nil,
3765 --[[globals]] {{string, integer, integer}} | nil 4239 --[[globals]] {{string, integer, integer}} | nil
3766``` 4240```
3767 4241
3768**参数:** 4242**参数:**
@@ -3885,8 +4359,8 @@ remove_loader: function(): boolean
3885**签名:** 4359**签名:**
3886```lua 4360```lua
3887loadstring: function(input: string, chunkname: string, env: table, config?: Config): 4361loadstring: function(input: string, chunkname: string, env: table, config?: Config):
3888 --[[loaded function]] nil | function(...: any): (any...), 4362 --[[loaded function]] nil | function(...: any): (any...),
3889 --[[error]] string | nil 4363 --[[error]] string | nil
3890``` 4364```
3891 4365
3892**参数:** 4366**参数:**
@@ -3916,8 +4390,8 @@ loadstring: function(input: string, chunkname: string, env: table, config?: Conf
3916**签名:** 4390**签名:**
3917```lua 4391```lua
3918loadstring: function(input: string, chunkname: string, config?: Config): 4392loadstring: function(input: string, chunkname: string, config?: Config):
3919 --[[loaded function]] nil | function(...: any): (any...), 4393 --[[loaded function]] nil | function(...: any): (any...),
3920 --[[error]] string | nil 4394 --[[error]] string | nil
3921``` 4395```
3922 4396
3923**参数:** 4397**参数:**
@@ -3946,8 +4420,8 @@ loadstring: function(input: string, chunkname: string, config?: Config):
3946**签名:** 4420**签名:**
3947```lua 4421```lua
3948loadstring: function(input: string, config?: Config): 4422loadstring: function(input: string, config?: Config):
3949 --[[loaded function]] nil | function(...: any): (any...), 4423 --[[loaded function]] nil | function(...: any): (any...),
3950 --[[error]] string | nil 4424 --[[error]] string | nil
3951``` 4425```
3952 4426
3953**参数:** 4427**参数:**
@@ -3975,8 +4449,8 @@ loadstring: function(input: string, config?: Config):
3975**签名:** 4449**签名:**
3976```lua 4450```lua
3977loadfile: function(filename: string, env: table, config?: Config): 4451loadfile: function(filename: string, env: table, config?: Config):
3978 nil | function(...: any): (any...), 4452 nil | function(...: any): (any...),
3979 string | nil 4453 string | nil
3980``` 4454```
3981 4455
3982**参数:** 4456**参数:**
@@ -4005,8 +4479,8 @@ loadfile: function(filename: string, env: table, config?: Config):
4005**签名:** 4479**签名:**
4006```lua 4480```lua
4007loadfile: function(filename: string, config?: Config): 4481loadfile: function(filename: string, config?: Config):
4008 nil | function(...: any): (any...), 4482 nil | function(...: any): (any...),
4009 string | nil 4483 string | nil
4010``` 4484```
4011 4485
4012**参数:** 4486**参数:**
@@ -4261,9 +4735,9 @@ type AST = {string, integer, integer, any}
4261 4735
4262**签名:** 4736**签名:**
4263```lua 4737```lua
4264to_ast: function(code: string, flattenLevel?: number, astName?: string): 4738to_ast: function(code: string, flattenLevel?: number, astName?: string, reserveComment?: boolean):
4265 --[[AST]] AST | nil, 4739 --[[AST]] AST | nil,
4266 --[[error]] nil | string 4740 --[[error]] nil | string
4267``` 4741```
4268 4742
4269**参数:** 4743**参数:**
@@ -4272,6 +4746,42 @@ to_ast: function(code: string, flattenLevel?: number, astName?: string):
4272| --- | --- | --- | 4746| --- | --- | --- |
4273| code | string | 代码。 | 4747| code | string | 代码。 |
4274| flattenLevel | integer | [可选] 扁平化级别。级别越高,会消除更多的 AST 结构的嵌套。默认为 0。最大为 2。 | 4748| flattenLevel | integer | [可选] 扁平化级别。级别越高,会消除更多的 AST 结构的嵌套。默认为 0。最大为 2。 |
4749| astName | string | [可选] AST 名称。默认为 "File"。 |
4750| reserveComment | boolean | [可选] 是否保留原始注释。默认为 false。 |
4751
4752**返回值:**
4753
4754| 返回类型 | 描述 |
4755| --- | --- |
4756| AST \| nil | AST,如果转换失败则为 nil。 |
4757| string \| nil | 错误消息,如果转换成功则为 nil。 |
4758
4759#### format
4760
4761**类型:** 函数。
4762
4763**描述:**
4764
4765格式化 YueScript 代码。
4766
4767**签名:**
4768```lua
4769format: function(code: string, tabSize?: number, reserveComment?: boolean): string
4770```
4771
4772**参数:**
4773
4774| 参数名 | 类型 | 描述 |
4775| --- | --- | --- |
4776| code | string | 代码。 |
4777| tabSize | integer | [可选] 制表符大小。默认为 4。 |
4778| reserveComment | boolean | [可选] 是否保留原始注释。默认为 true。 |
4779
4780**返回值:**
4781
4782| 返回类型 | 描述 |
4783| --- | --- |
4784| string | 格式化后的代码。 |
4275 4785
4276#### __call 4786#### __call
4277 4787
@@ -4344,6 +4854,19 @@ implicit_return_root: boolean
4344reserve_line_number: boolean 4854reserve_line_number: boolean
4345``` 4855```
4346 4856
4857#### reserve_comment
4858
4859**类型:** 成员变量。
4860
4861**描述:**
4862
4863编译器是否应该在编译后的代码中保留原始注释。
4864
4865**签名:**
4866```lua
4867reserve_comment: boolean
4868```
4869
4347#### space_over_tab 4870#### space_over_tab
4348 4871
4349**类型:** 成员变量。 4872**类型:** 成员变量。
@@ -4394,11 +4917,11 @@ line_offset: integer
4394**签名:** 4917**签名:**
4395```lua 4918```lua
4396enum LuaTarget 4919enum LuaTarget
4397 "5.1" 4920 "5.1"
4398 "5.2" 4921 "5.2"
4399 "5.3" 4922 "5.3"
4400 "5.4" 4923 "5.4"
4401 "5.5" 4924 "5.5"
4402end 4925end
4403``` 4926```
4404 4927