aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rwxr-xr-xdoc/docs/doc/README.md574
-rwxr-xr-xdoc/docs/zh/doc/README.md608
2 files changed, 1037 insertions, 145 deletions
diff --git a/doc/docs/doc/README.md b/doc/docs/doc/README.md
index c4518bf..f0d67a5 100755
--- a/doc/docs/doc/README.md
+++ b/doc/docs/doc/README.md
@@ -16,19 +16,29 @@ 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
33map = (arr, action) ->
34 [action item for item in *arr]
35
36filter = (arr, cond) ->
37 [item for item in *arr when cond item]
38
39reduce = (arr, init, action): init ->
40 init = action init, item for item in *arr
41
32-- pipe operator 42-- pipe operator
33[1, 2, 3] 43[1, 2, 3]
34 |> map (x) -> x * 2 44 |> map (x) -> x * 2
@@ -51,19 +61,29 @@ export 🌛 = "月之脚本"
51<YueDisplay> 61<YueDisplay>
52<pre> 62<pre>
53-- import syntax 63-- import syntax
54import "yue" as :p, :to_lua 64import p, to_lua from "yue"
55 65
56-- object literals 66-- object literals
57inventory = 67inventory =
58 equipment: 68 equipment:
59 * "sword" 69 - "sword"
60 * "shield" 70 - "shield"
61 items: 71 items:
62 * name: "potion" 72 - name: "potion"
63 count: 10 73 count: 10
64 * name: "bread" 74 - name: "bread"
65 count: 3 75 count: 3
66 76
77-- list comprehension
78map = (arr, action) ->
79 [action item for item in *arr]
80
81filter = (arr, cond) ->
82 [item for item in *arr when cond item]
83
84reduce = (arr, init, action): init ->
85 init = action init, item for item in *arr
86
67-- pipe operator 87-- pipe operator
68[1, 2, 3] 88[1, 2, 3]
69 |> map (x) -> x * 2 89 |> map (x) -> x * 2
@@ -132,14 +152,14 @@ export 🌛 = "月之脚本"
132 152
133&emsp;Use YueScript module in Lua: 153&emsp;Use YueScript module in Lua:
134 154
135* **Case 1** 155* **Case 1**
136Require "your_yuescript_entry.yue" in Lua. 156Require "your_yuescript_entry.yue" in Lua.
137```Lua 157```Lua
138require("yue")("your_yuescript_entry") 158require("yue")("your_yuescript_entry")
139``` 159```
140&emsp;And this code still works when you compile "your_yuescript_entry.yue" to "your_yuescript_entry.lua" in the same path. In the rest YueScript files just use the normal **require** or **import**. The code line numbers in error messages will also be handled correctly. 160&emsp;And this code still works when you compile "your_yuescript_entry.yue" to "your_yuescript_entry.lua" in the same path. In the rest YueScript files just use the normal **require** or **import**. The code line numbers in error messages will also be handled correctly.
141 161
142* **Case 2** 162* **Case 2**
143Require YueScript module and rewite message by hand. 163Require YueScript module and rewite message by hand.
144```lua 164```lua
145local yue = require("yue") 165local yue = require("yue")
@@ -151,7 +171,7 @@ end, function(err)
151end) 171end)
152``` 172```
153 173
154* **Case 3** 174* **Case 3**
155Use the YueScript compiler function in Lua. 175Use the YueScript compiler function in Lua.
156```lua 176```lua
157local yue = require("yue") 177local yue = require("yue")
@@ -203,12 +223,12 @@ Usage: yue [options|files|directories] ...
203 Execute without options to enter REPL, type symbol '$' 223 Execute without options to enter REPL, type symbol '$'
204 in a single line to start/stop multi-line mode 224 in a single line to start/stop multi-line mode
205``` 225```
206&emsp;&emsp;Use cases: 226&emsp;&emsp;Use cases:
207&emsp;&emsp;Recursively compile every YueScript file with extension **.yue** under current path: **yue .** 227&emsp;&emsp;Recursively compile every YueScript file with extension **.yue** under current path: **yue .**
208&emsp;&emsp;Compile and save results to a target path: **yue -t /target/path/ .** 228&emsp;&emsp;Compile and save results to a target path: **yue -t /target/path/ .**
209&emsp;&emsp;Compile and reserve debug info: **yue -l .** 229&emsp;&emsp;Compile and reserve debug info: **yue -l .**
210&emsp;&emsp;Compile and generate minified codes: **yue -m .** 230&emsp;&emsp;Compile and generate minified codes: **yue -m .**
211&emsp;&emsp;Execute raw codes: **yue -e 'print 123'** 231&emsp;&emsp;Execute raw codes: **yue -e 'print 123'**
212&emsp;&emsp;Execute a YueScript file: **yue -e main.yue** 232&emsp;&emsp;Execute a YueScript file: **yue -e main.yue**
213 233
214## Macro 234## Macro
@@ -424,6 +444,54 @@ print "Valid enum type:", $BodyType Static
424</pre> 444</pre>
425</YueDisplay> 445</YueDisplay>
426 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
427## Operator 495## Operator
428 496
429All 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.
@@ -566,11 +634,26 @@ merge = {...a, ...b}
566</pre> 634</pre>
567</YueDisplay> 635</YueDisplay>
568 636
637### Table Reversed Indexing
638
639You can use the **#** operator to get the last elements of a table.
640
641```moonscript
642last = data.items[#]
643second_last = data.items[#-1]
644```
645<YueDisplay>
646<pre>
647last = data.items[#]
648second_last = data.items[#-1]
649</pre>
650</YueDisplay>
651
569### Metatable 652### Metatable
570 653
571The **<>** operator can be used as a shortcut for metatable manipulation. 654The **<>** operator can be used as a shortcut for metatable manipulation.
572 655
573* **Metatable Creation** 656* **Metatable Creation**
574Create normal table with empty bracekets **<>** or metamethod key which is surrounded by **<>**. 657Create normal table with empty bracekets **<>** or metamethod key which is surrounded by **<>**.
575 658
576```moonscript 659```moonscript
@@ -606,7 +689,7 @@ close _ = &lt;close&gt;: -> print "out of scope"
606</pre> 689</pre>
607</YueDisplay> 690</YueDisplay>
608 691
609* **Metatable Accessing** 692* **Metatable Accessing**
610Accessing metatable with **<>** or metamethod name surrounded by **<>** or writing some expression in **<>**. 693Accessing metatable with **<>** or metamethod name surrounded by **<>** or writing some expression in **<>**.
611 694
612```moonscript 695```moonscript
@@ -630,7 +713,7 @@ print tb.item
630</pre> 713</pre>
631</YueDisplay> 714</YueDisplay>
632 715
633* **Metatable Destructure** 716* **Metatable Destructure**
634Destruct metatable with metamethod key surrounded by **<>**. 717Destruct metatable with metamethod key surrounded by **<>**.
635 718
636```moonscript 719```moonscript
@@ -732,34 +815,45 @@ a ??= false
732 815
733### Implicit Object 816### Implicit Object
734 817
735You 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. 818You 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.
819
736```moonscript 820```moonscript
821-- assignment with implicit object
737list = 822list =
738 * 1 823 * 1
739 * 2 824 * 2
740 * 3 825 * 3
741 826
827-- function call with implicit object
742func 828func
743 * 1 829 * 1
744 * 2 830 * 2
745 * 3 831 * 3
746 832
833-- return with implicit object
834f = ->
835 return
836 * 1
837 * 2
838 * 3
839
840-- table with implicit object
747tb = 841tb =
748 name: "abc" 842 name: "abc"
749 843
750 values: 844 values:
751 * "a" 845 - "a"
752 * "b" 846 - "b"
753 * "c" 847 - "c"
754 848
755 objects: 849 objects:
756 * name: "a" 850 - name: "a"
757 value: 1 851 value: 1
758 func: => @value + 1 852 func: => @value + 1
759 tb: 853 tb:
760 fieldA: 1 854 fieldA: 1
761 855
762 * name: "b" 856 - name: "b"
763 value: 2 857 value: 2
764 func: => @value + 2 858 func: => @value + 2
765 tb: { } 859 tb: { }
@@ -767,32 +861,42 @@ tb =
767``` 861```
768<YueDisplay> 862<YueDisplay>
769<pre> 863<pre>
864-- assignment with implicit object
770list = 865list =
771 * 1 866 * 1
772 * 2 867 * 2
773 * 3 868 * 3
774 869
870-- function call with implicit object
775func 871func
776 * 1 872 * 1
777 * 2 873 * 2
778 * 3 874 * 3
779 875
876-- return with implicit object
877f = ->
878 return
879 * 1
880 * 2
881 * 3
882
883-- table with implicit object
780tb = 884tb =
781 name: "abc" 885 name: "abc"
782 886
783 values: 887 values:
784 * "a" 888 - "a"
785 * "b" 889 - "b"
786 * "c" 890 - "c"
787 891
788 objects: 892 objects:
789 * name: "a" 893 - name: "a"
790 value: 1 894 value: 1
791 func: => @value + 1 895 func: => @value + 1
792 tb: 896 tb:
793 fieldA: 1 897 fieldA: 1
794 898
795 * name: "b" 899 - name: "b"
796 value: 2 900 value: 2
797 func: => @value + 2 901 func: => @value + 2
798 tb: { } 902 tb: { }
@@ -860,7 +964,7 @@ do
860 964
861The export statement offers a concise way to define modules. 965The export statement offers a concise way to define modules.
862 966
863* **Named Export** 967* **Named Export**
864Named export will define a local variable as well as adding a field in the exported table. 968Named export will define a local variable as well as adding a field in the exported table.
865 969
866```moonscript 970```moonscript
@@ -924,7 +1028,7 @@ export["a-b-c"] = 123
924</pre> 1028</pre>
925</YueDisplay> 1029</YueDisplay>
926 1030
927* **Unnamed Export** 1031* **Unnamed Export**
928Unnamed export will add the target item into the array part of the exported table. 1032Unnamed export will add the target item into the array part of the exported table.
929 1033
930```moonscript 1034```moonscript
@@ -954,7 +1058,7 @@ export with tmp
954</pre> 1058</pre>
955</YueDisplay> 1059</YueDisplay>
956 1060
957* **Default Export** 1061* **Default Export**
958Using the **default** keyword in export statement to replace the exported table with any thing. 1062Using the **default** keyword in export statement to replace the exported table with any thing.
959 1063
960```moonscript 1064```moonscript
@@ -1202,7 +1306,7 @@ If the destructuring statement is complicated, feel free to spread it out over a
1202</pre> 1306</pre>
1203</YueDisplay> 1307</YueDisplay>
1204 1308
1205It’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: 1309It'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:
1206 1310
1207```moonscript 1311```moonscript
1208{:concat, :insert} = table 1312{:concat, :insert} = table
@@ -1246,6 +1350,52 @@ You can use `_` as placeholder when doing a list destructuring:
1246</pre> 1350</pre>
1247</YueDisplay> 1351</YueDisplay>
1248 1352
1353### Range Destructuring
1354
1355You 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.
1356
1357```moonscript
1358orders = ["first", "second", "third", "fourth", "last"]
1359[first, ...bulk, last] = orders
1360print first -- prints: first
1361print bulk -- prints: {"second", "third", "fourth"}
1362print last -- prints: last
1363```
1364<YueDisplay>
1365<pre>
1366orders = ["first", "second", "third", "fourth", "last"]
1367[first, ...bulk, last] = orders
1368print first -- prints: first
1369print bulk -- prints: {"second", "third", "fourth"}
1370print last -- prints: last
1371</pre>
1372</YueDisplay>
1373
1374The 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:
1375
1376```moonscript
1377-- Capture everything after first element
1378[first, ...rest] = orders
1379
1380-- Capture everything before last element
1381[...start, last] = orders
1382
1383-- Capture things except the middle elements
1384[first, ..._, last] = orders
1385```
1386<YueDisplay>
1387<pre>
1388-- Capture everything after first element
1389[first, ...rest] = orders
1390
1391-- Capture everything before last element
1392[...start, last] = orders
1393
1394-- Capture things except the middle elements
1395[first, ..._, last] = orders
1396</pre>
1397</YueDisplay>
1398
1249### Destructuring In Other Places 1399### Destructuring In Other Places
1250 1400
1251Destructuring can also show up in places where an assignment implicitly takes place. An example of this is a for loop: 1401Destructuring can also show up in places where an assignment implicitly takes place. An example of this is a for loop:
@@ -1475,6 +1625,47 @@ catch err
1475</pre> 1625</pre>
1476</YueDisplay> 1626</YueDisplay>
1477 1627
1628### Try?
1629
1630`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.
1631
1632```moonscript
1633a, b, c = try? func!
1634
1635-- with nil coalescing operator
1636a = (try? func!) ?? "default"
1637
1638-- as function argument
1639f try? func!
1640
1641-- with catch block
1642f try?
1643 print 123
1644 func!
1645catch e
1646 print e
1647 e
1648```
1649<YueDisplay>
1650<pre>
1651a, b, c = try? func!
1652
1653-- with nil coalescing operator
1654a = (try? func!) ?? "default"
1655
1656-- as function argument
1657f try? func!
1658
1659-- with catch block
1660f try?
1661 print 123
1662 func!
1663catch e
1664 print e
1665 e
1666</pre>
1667</YueDisplay>
1668
1478## Attributes 1669## Attributes
1479 1670
1480Syntax 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. 1671Syntax 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.
@@ -1503,6 +1694,19 @@ const {:a, :b, c, d} = tb
1503</pre> 1694</pre>
1504</YueDisplay> 1695</YueDisplay>
1505 1696
1697You can also declare a global variable to be `const`.
1698
1699```moonscript
1700global const Constant = 123
1701-- Constant = 1
1702```
1703<YueDisplay>
1704<pre>
1705global const Constant = 123
1706-- Constant = 1
1707</pre>
1708</YueDisplay>
1709
1506## Literals 1710## Literals
1507 1711
1508All of the primitive literals in Lua can be used. This applies to numbers, strings, booleans, and **nil**. 1712All of the primitive literals in Lua can be used. This applies to numbers, strings, booleans, and **nil**.
@@ -1535,12 +1739,73 @@ You can use underscores in a number literal to increase readability.
1535```moonscript 1739```moonscript
1536integer = 1_000_000 1740integer = 1_000_000
1537hex = 0xEF_BB_BF 1741hex = 0xEF_BB_BF
1742binary = 0B10011
1538``` 1743```
1539<YueDisplay> 1744<YueDisplay>
1540 1745
1541<pre> 1746<pre>
1542integer = 1_000_000 1747integer = 1_000_000
1543hex = 0xEF_BB_BF 1748hex = 0xEF_BB_BF
1749binary = 0B10011
1750</pre>
1751</YueDisplay>
1752
1753### YAML Multiline String
1754
1755The `|` prefix introduces a YAML-style multiline string literal:
1756
1757```moonscript
1758str = |
1759 key: value
1760 list:
1761 - item1
1762 - #{expr}
1763```
1764<YueDisplay>
1765<pre>
1766str = |
1767 key: value
1768 list:
1769 - item1
1770 - #{expr}
1771</pre>
1772</YueDisplay>
1773
1774This 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)`.
1775
1776YAML 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.
1777
1778```moonscript
1779fn = ->
1780 str = |
1781 foo:
1782 bar: baz
1783 return str
1784```
1785<YueDisplay>
1786<pre>
1787fn = ->
1788 str = |
1789 foo:
1790 bar: baz
1791 return str
1792</pre>
1793</YueDisplay>
1794
1795Internal indentation is preserved relative to the removed common prefix, allowing clean nested structures.
1796
1797All 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.
1798
1799```moonscript
1800str = |
1801 path: "C:\Program Files\App"
1802 note: 'He said: "#{Hello}!"'
1803```
1804<YueDisplay>
1805<pre>
1806str = |
1807 path: "C:\Program Files\App"
1808 note: 'He said: "#{Hello}!"'
1544</pre> 1809</pre>
1545</YueDisplay> 1810</YueDisplay>
1546 1811
@@ -1902,22 +2167,22 @@ x * 2
1902</pre> 2167</pre>
1903</YueDisplay> 2168</YueDisplay>
1904 2169
1905If you wish to have further code after your backcalls, you can set them aside with a do statement. 2170If you wish to have further code after your backcalls, you can set them aside with a do statement. And the parentheses can be omitted with non-fat arrow functions.
1906 2171
1907```moonscript 2172```moonscript
1908result, msg = do 2173result, msg = do
1909 (data) <- readAsync "filename.txt" 2174 data <- readAsync "filename.txt"
1910 print data 2175 print data
1911 (info) <- processAsync data 2176 info <- processAsync data
1912 check info 2177 check info
1913print result, msg 2178print result, msg
1914``` 2179```
1915<YueDisplay> 2180<YueDisplay>
1916<pre> 2181<pre>
1917result, msg = do 2182result, msg = do
1918 (data) <- readAsync "filename.txt" 2183 data <- readAsync "filename.txt"
1919 print data 2184 print data
1920 (info) <- processAsync data 2185 info <- processAsync data
1921 check info 2186 check info
1922print result, msg 2187print result, msg
1923</pre> 2188</pre>
@@ -2248,6 +2513,45 @@ slice = [item for item in *items[,,2]]
2248</pre> 2513</pre>
2249</YueDisplay> 2514</YueDisplay>
2250 2515
2516Both the minimum and maximum bounds can be negative, which means that the bounds are counted from the end of the table.
2517
2518```moonscript
2519-- take the last 4 items
2520slice = [item for item in *items[-4,-1]]
2521```
2522<YueDisplay>
2523<pre>
2524-- take the last 4 items
2525slice = [item for item in *items[-4,-1]]
2526</pre>
2527</YueDisplay>
2528
2529The step size can also be negative, which means that the items are taken in reverse order.
2530
2531```moonscript
2532reverse_slice = [item for item in *items[-1,1,-1]]
2533```
2534<YueDisplay>
2535<pre>
2536reverse_slice = [item for item in *items[-1,1,-1]]
2537</pre>
2538</YueDisplay>
2539
2540#### Slicing Expression
2541
2542Slicing can also be used as an expression. This is useful for getting a sub-list of a table.
2543
2544```moonscript
2545-- take the 2nd and 4th items as a new list
2546sub_list = items[2, 4]
2547```
2548<YueDisplay>
2549<pre>
2550-- take the 2nd and 4th items as a new list
2551sub_list = items[2, 4]
2552</pre>
2553</YueDisplay>
2554
2251## For Loop 2555## For Loop
2252 2556
2253There are two for loop forms, just like in Lua. A numeric one and a generic one: 2557There are two for loop forms, just like in Lua. A numeric one and a generic one:
@@ -2324,6 +2628,23 @@ doubled_evens = for i = 1, 20
2324</pre> 2628</pre>
2325</YueDisplay> 2629</YueDisplay>
2326 2630
2631In addition, for loops support break with a return value, allowing the loop itself to be used as an expression that exits early with a meaningful result.
2632
2633For example, to find the first number greater than 10:
2634
2635```moonscript
2636first_large = for n in *numbers
2637 break n if n > 10
2638```
2639<YueDisplay>
2640<pre>
2641first_large = for n in *numbers
2642 break n if n > 10
2643</pre>
2644</YueDisplay>
2645
2646This break-with-value syntax enables concise and expressive search or early-exit patterns directly within loop expressions.
2647
2327You can also filter values by combining the for loop expression with the continue statement. 2648You can also filter values by combining the for loop expression with the continue statement.
2328 2649
2329For loops at the end of a function body are not accumulated into a table for a return value (Instead the function will return nil). Either an explicit return statement can be used, or the loop can be converted into a list comprehension. 2650For loops at the end of a function body are not accumulated into a table for a return value (Instead the function will return nil). Either an explicit return statement can be used, or the loop can be converted into a list comprehension.
@@ -2345,7 +2666,7 @@ print func_b! -- prints table object
2345</pre> 2666</pre>
2346</YueDisplay> 2667</YueDisplay>
2347 2668
2348This is done to avoid the needless creation of tables for functions that dont need to return the results of the loop. 2669This is done to avoid the needless creation of tables for functions that don't need to return the results of the loop.
2349 2670
2350## Repeat Loop 2671## Repeat Loop
2351 2672
@@ -2624,28 +2945,26 @@ reader\parse_line! until reader\eof!
2624 2945
2625## Switch 2946## Switch
2626 2947
2627The 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. 2948The 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.
2628 2949
2629```moonscript 2950```moonscript
2630name = "Dan" 2951switch name := "Dan"
2631switch name
2632 when "Robert" 2952 when "Robert"
2633 print "You are Robert" 2953 print "You are Robert"
2634 when "Dan", "Daniel" 2954 when "Dan", "Daniel"
2635 print "Your name, it's Dan" 2955 print "Your name, it's Dan"
2636 else 2956 else
2637 print "I don't know about your name" 2957 print "I don't know about you with name #{name}"
2638``` 2958```
2639<YueDisplay> 2959<YueDisplay>
2640<pre> 2960<pre>
2641name = "Dan" 2961switch name := "Dan"
2642switch name
2643 when "Robert" 2962 when "Robert"
2644 print "You are Robert" 2963 print "You are Robert"
2645 when "Dan", "Daniel" 2964 when "Dan", "Daniel"
2646 print "Your name, it's Dan" 2965 print "Your name, it's Dan"
2647 else 2966 else
2648 print "I don't know about your name" 2967 print "I don't know about you with name #{name}"
2649</pre> 2968</pre>
2650</YueDisplay> 2969</YueDisplay>
2651 2970
@@ -2676,7 +2995,7 @@ next_number = switch b
2676</pre> 2995</pre>
2677</YueDisplay> 2996</YueDisplay>
2678 2997
2679We 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. 2998We 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.
2680 2999
2681```moonscript 3000```moonscript
2682msg = switch math.random(1, 5) 3001msg = switch math.random(1, 5)
@@ -2722,7 +3041,7 @@ else
2722</pre> 3041</pre>
2723</YueDisplay> 3042</YueDisplay>
2724 3043
2725It 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. 3044It 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.
2726 3045
2727### Table Matching 3046### Table Matching
2728 3047
@@ -2782,6 +3101,123 @@ switch item
2782</pre> 3101</pre>
2783</YueDisplay> 3102</YueDisplay>
2784 3103
3104You can also match against array elements, table fields, and even nested structures with array or table literals.
3105
3106Match against array elements.
3107
3108```moonscript
3109switch tb
3110 when [1, 2, 3]
3111 print "1, 2, 3"
3112 when [1, b, 3]
3113 print "1, #{b}, 3"
3114 when [1, 2, b = 3] -- b has a default value
3115 print "1, 2, #{b}"
3116```
3117<YueDisplay>
3118<pre>
3119switch tb
3120 when [1, 2, 3]
3121 print "1, 2, 3"
3122 when [1, b, 3]
3123 print "1, #{b}, 3"
3124 when [1, 2, b = 3] -- b has a default value
3125 print "1, 2, #{b}"
3126</pre>
3127</YueDisplay>
3128
3129Match against table fields with destructuring.
3130
3131```moonscript
3132switch tb
3133 when success: true, :result
3134 print "success", result
3135 when success: false
3136 print "failed", result
3137 else
3138 print "invalid"
3139```
3140<YueDisplay>
3141<pre>
3142switch tb
3143 when success: true, :result
3144 print "success", result
3145 when success: false
3146 print "failed", result
3147 else
3148 print "invalid"
3149</pre>
3150</YueDisplay>
3151
3152Match against nested table structures.
3153
3154```moonscript
3155switch tb
3156 when data: {type: "success", :content}
3157 print "success", content
3158 when data: {type: "error", :content}
3159 print "failed", content
3160 else
3161 print "invalid"
3162```
3163<YueDisplay>
3164<pre>
3165switch tb
3166 when data: {type: "success", :content}
3167 print "success", content
3168 when data: {type: "error", :content}
3169 print "failed", content
3170 else
3171 print "invalid"
3172</pre>
3173</YueDisplay>
3174
3175Match against array of tables.
3176
3177```moonscript
3178switch tb
3179 when [
3180 {a: 1, b: 2}
3181 {a: 3, b: 4}
3182 {a: 5, b: 6}
3183 fourth
3184 ]
3185 print "matched", fourth
3186```
3187<YueDisplay>
3188<pre>
3189switch tb
3190 when [
3191 {a: 1, b: 2}
3192 {a: 3, b: 4}
3193 {a: 5, b: 6}
3194 fourth
3195 ]
3196 print "matched", fourth
3197</pre>
3198</YueDisplay>
3199
3200Match against a list and capture a range of elements.
3201
3202```moonscript
3203segments = ["admin", "users", "logs", "view"]
3204switch segments
3205 when [...groups, resource, action]
3206 print "Group:", groups -- prints: {"admin", "users"}
3207 print "Resource:", resource -- prints: "logs"
3208 print "Action:", action -- prints: "view"
3209```
3210<YueDisplay>
3211<pre>
3212segments = ["admin", "users", "logs", "view"]
3213switch segments
3214 when [...groups, resource, action]
3215 print "Group:", groups -- prints: {"admin", "users"}
3216 print "Resource:", resource -- prints: "logs"
3217 print "Action:", action -- prints: "view"
3218</pre>
3219</YueDisplay>
3220
2785## Object Oriented Programming 3221## Object Oriented Programming
2786 3222
2787In 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. 3223In 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.
@@ -2913,7 +3349,7 @@ class BackPack extends Inventory
2913 3349
2914Here we extend our Inventory class, and limit the amount of items it can carry. 3350Here we extend our Inventory class, and limit the amount of items it can carry.
2915 3351
2916In 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. 3352In 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.
2917 3353
2918Whenever 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. 3354Whenever 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.
2919 3355
@@ -3000,13 +3436,13 @@ print BackPack.size -- prints 10
3000 3436
3001The 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. 3437The 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.
3002 3438
3003The 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. 3439The 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.
3004 3440
3005A 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. 3441A 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.
3006 3442
3007The 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. 3443The 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.
3008 3444
3009It 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. 3445It 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.
3010 3446
3011The class object has a couple special properties: 3447The class object has a couple special properties:
3012 3448
@@ -3079,7 +3515,7 @@ print Counter.count -- prints 2
3079</pre> 3515</pre>
3080</YueDisplay> 3516</YueDisplay>
3081 3517
3082The calling semantics of @@ are similar to @. Calling a @@ name will pass the class in as the first argument using Lua’s colon syntax. 3518The calling semantics of @@ are similar to @. Calling a @@ name will pass the class in as the first argument using Lua's colon syntax.
3083 3519
3084```moonscript 3520```moonscript
3085@@hello 1,2,3,4 3521@@hello 1,2,3,4
@@ -3094,7 +3530,7 @@ The calling semantics of @@ are similar to @. Calling a @@ name will pass the cl
3094 3530
3095In 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. 3531In 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.
3096 3532
3097Here is an alternative way to create a class variable compared to whats described above: 3533Here is an alternative way to create a class variable compared to what's described above:
3098 3534
3099```moonscript 3535```moonscript
3100class Things 3536class Things
@@ -3360,19 +3796,19 @@ In this usage, with can be seen as a special form of the K combinator.
3360The expression in the with statement can also be an assignment, if you want to give a name to the expression. 3796The expression in the with statement can also be an assignment, if you want to give a name to the expression.
3361 3797
3362```moonscript 3798```moonscript
3363with str = "Hello" 3799with str := "Hello"
3364 print "original:", str 3800 print "original:", str
3365 print "upper:", \upper! 3801 print "upper:", \upper!
3366``` 3802```
3367<YueDisplay> 3803<YueDisplay>
3368<pre> 3804<pre>
3369with str = "Hello" 3805with str := "Hello"
3370 print "original:", str 3806 print "original:", str
3371 print "upper:", \upper! 3807 print "upper:", \upper!
3372</pre> 3808</pre>
3373</YueDisplay> 3809</YueDisplay>
3374 3810
3375Accessing special keys with `[]` in a `with` statement. 3811You can access special keys with `[]` in a `with` statement.
3376 3812
3377```moonscript 3813```moonscript
3378with tb 3814with tb
@@ -3395,6 +3831,18 @@ with tb
3395</pre> 3831</pre>
3396</YueDisplay> 3832</YueDisplay>
3397 3833
3834`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.
3835
3836```moonscript
3837with? obj
3838 print obj.name
3839```
3840<YueDisplay>
3841<pre>
3842with? obj
3843 print obj.name
3844</pre>
3845</YueDisplay>
3398 3846
3399## Do 3847## Do
3400 3848
@@ -3415,7 +3863,7 @@ print var -- nil here
3415</pre> 3863</pre>
3416</YueDisplay> 3864</YueDisplay>
3417 3865
3418YueScript’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. 3866YueScript'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.
3419 3867
3420```moonscript 3868```moonscript
3421counter = do 3869counter = do
@@ -3541,7 +3989,7 @@ print i -- will print 0
3541</pre> 3989</pre>
3542</YueDisplay> 3990</YueDisplay>
3543 3991
3544In 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. 3992In 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.
3545 3993
3546It 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. 3994It 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.
3547 3995
diff --git a/doc/docs/zh/doc/README.md b/doc/docs/zh/doc/README.md
index 1a2da96..15f4768 100755
--- a/doc/docs/zh/doc/README.md
+++ b/doc/docs/zh/doc/README.md
@@ -16,19 +16,29 @@ Yue(月)是中文中“月亮”的名称。
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-- 列表推导
33map = (arr, action) ->
34 [action item for item in *arr]
35
36filter = (arr, cond) ->
37 [item for item in *arr when cond item]
38
39reduce = (arr, init, action): init ->
40 init = action init, item for item in *arr
41
32-- 管道操作符 42-- 管道操作符
33[1, 2, 3] 43[1, 2, 3]
34 |> map (x) -> x * 2 44 |> map (x) -> x * 2
@@ -51,19 +61,29 @@ export 🌛 = "月之脚本"
51<YueDisplay> 61<YueDisplay>
52<pre> 62<pre>
53-- 导入语法 63-- 导入语法
54import "yue" as :p, :to_lua 64import p, to_lua from "yue"
55 65
56-- 隐式对象 66-- 隐式对象
57inventory = 67inventory =
58 equipment: 68 equipment:
59 * "sword" 69 - "sword"
60 * "shield" 70 - "shield"
61 items: 71 items:
62 * name: "potion" 72 - name: "potion"
63 count: 10 73 count: 10
64 * name: "bread" 74 - name: "bread"
65 count: 3 75 count: 3
66 76
77-- 列表推导
78map = (arr, action) ->
79 [action item for item in *arr]
80
81filter = (arr, cond) ->
82 [item for item in *arr when cond item]
83
84reduce = (arr, init, action): init ->
85 init = action init, item for item in *arr
86
67-- 管道操作符 87-- 管道操作符
68[1, 2, 3] 88[1, 2, 3]
69 |> map (x) -> x * 2 89 |> map (x) -> x * 2
@@ -122,7 +142,7 @@ export 🌛 = "月之脚本"
122 142
123* **下载预编译的二进制程序** 143* **下载预编译的二进制程序**
124 144
125&emsp;可以下载预编译的二进制程序,包括兼容不同 Lua 版本的二进制可执行文件和库文件。 145&emsp;可以下载预编译的二进制程序,包括兼容不同 Lua 版本的二进制可执行文件和库文件。
126 146
127&emsp;在[这里](https://github.com/IppClub/YueScript/releases)下载预编译的二进制程序。 147&emsp;在[这里](https://github.com/IppClub/YueScript/releases)下载预编译的二进制程序。
128 148
@@ -132,14 +152,14 @@ export 🌛 = "月之脚本"
132 152
133在Lua中使用月之脚本模块: 153在Lua中使用月之脚本模块:
134 154
135* **用法 1** 155* **用法 1**
136在Lua中引入 "你的脚本入口文件.yue"。 156在Lua中引入 "你的脚本入口文件.yue"。
137```Lua 157```Lua
138require("yue")("你的脚本入口文件") 158require("yue")("你的脚本入口文件")
139``` 159```
140当你在同一路径下把 "你的脚本入口文件.yue" 编译成了 "你的脚本入口文件.lua" 时,仍然可以使用这个代码加载 .lua 代码文件。在其余的月之脚本文件中,只需正常使用 **require** 或 **import**进行脚本引用即可。错误消息中的代码行号也会被正确处理。 160当你在同一路径下把 "你的脚本入口文件.yue" 编译成了 "你的脚本入口文件.lua" 时,仍然可以使用这个代码加载 .lua 代码文件。在其余的月之脚本文件中,只需正常使用 **require** 或 **import**进行脚本引用即可。错误消息中的代码行号也会被正确处理。
141 161
142* **用法 2** 162* **用法 2**
143手动引入月之脚本模块并重写错误消息来帮助调试。 163手动引入月之脚本模块并重写错误消息来帮助调试。
144```lua 164```lua
145local yue = require("yue") 165local yue = require("yue")
@@ -151,7 +171,7 @@ end, function(err)
151end) 171end)
152``` 172```
153 173
154* **用法 3** 174* **用法 3**
155在Lua中使用月之脚本编译器功能。 175在Lua中使用月之脚本编译器功能。
156```lua 176```lua
157local yue = require("yue") 177local yue = require("yue")
@@ -202,12 +222,12 @@ f!
202 不添加任何选项执行命令可以进入REPL模式, 222 不添加任何选项执行命令可以进入REPL模式,
203 在单行输入符号 '$' 并换行后,可以开始或是停止多行输入模式 223 在单行输入符号 '$' 并换行后,可以开始或是停止多行输入模式
204``` 224```
205&emsp;&emsp;使用案例: 225&emsp;&emsp;使用案例:
206&emsp;&emsp;递归编译当前路径下扩展名为 **.yue** 的每个月之脚本文件: **yue .** 226&emsp;&emsp;递归编译当前路径下扩展名为 **.yue** 的每个月之脚本文件: **yue .**
207&emsp;&emsp;编译并将结果保存到目标路径: **yue -t /target/path/ .** 227&emsp;&emsp;编译并将结果保存到目标路径: **yue -t /target/path/ .**
208&emsp;&emsp;编译并保留调试信息: **yue -l .** 228&emsp;&emsp;编译并保留调试信息: **yue -l .**
209&emsp;&emsp;编译并生成压缩代码: **yue -m .** 229&emsp;&emsp;编译并生成压缩代码: **yue -m .**
210&emsp;&emsp;直接执行代码: **yue -e 'print 123'** 230&emsp;&emsp;直接执行代码: **yue -e 'print 123'**
211&emsp;&emsp;执行一个月之脚本文件: **yue -e main.yue** 231&emsp;&emsp;执行一个月之脚本文件: **yue -e main.yue**
212 232
213## 宏 233## 宏
@@ -333,7 +353,7 @@ end
333 353
334### 导出宏 354### 导出宏
335 355
336宏函数可以从一个模块中导出,并在另一个模块中导入。您必须将导出的宏函数放在一个单独的文件中使用,而且只有宏定义、宏导入和宏展开可以放入这个宏导出模块中。 356宏函数可以从一个模块中导出,并在另一个模块中导入。你必须将导出的宏函数放在一个单独的文件中使用,而且只有宏定义、宏导入和宏展开可以放入这个宏导出模块中。
337```moonscript 357```moonscript
338-- 文件: utils.yue 358-- 文件: utils.yue
339export macro map = (items, action) -> "[#{action} for _ in *#{items}]" 359export macro map = (items, action) -> "[#{action} for _ in *#{items}]"
@@ -422,6 +442,54 @@ print "有效的枚举类型:", $BodyType Static
422</pre> 442</pre>
423</YueDisplay> 443</YueDisplay>
424 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
425## 操作符 493## 操作符
426 494
427Lua的所有二元和一元操作符在月之脚本中都是可用的。此外,**!=** 符号是 **~=** 的别名,而 **\\** 或 **::** 均可用于编写链式函数调用,如写作 `tb\func!` 或 `tb::func!`。此外月之脚本还提供了一些其他特殊的操作符,以编写更具表达力的代码。 495Lua的所有二元和一元操作符在月之脚本中都是可用的。此外,**!=** 符号是 **~=** 的别名,而 **\\** 或 **::** 均可用于编写链式函数调用,如写作 `tb\func!` 或 `tb::func!`。此外月之脚本还提供了一些其他特殊的操作符,以编写更具表达力的代码。
@@ -439,7 +507,7 @@ tb::func! if tb != nil
439 507
440### 链式比较 508### 链式比较
441 509
442可以在月之脚本中进行比较表达式的链式书写: 510可以在月之脚本中进行比较表达式的链式书写:
443 511
444```moonscript 512```moonscript
445print 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5 513print 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5
@@ -528,7 +596,7 @@ tab[] = "Value"
528 596
529### 表扩展 597### 表扩展
530 598
531可以使用前置 `...` 操作符在Lua表中插入数组表或哈希表。 599可以使用前置 `...` 操作符在Lua表中插入数组表或哈希表。
532 600
533```moonscript 601```moonscript
534parts = 602parts =
@@ -565,11 +633,26 @@ merge = {...a, ...b}
565</pre> 633</pre>
566</YueDisplay> 634</YueDisplay>
567 635
636### 表反向索引
637
638你可以使用 **#** 操作符来反向索引表中的元素。
639
640```moonscript
641last = data.items[#]
642second_last = data.items[#-1]
643```
644<YueDisplay>
645<pre>
646last = data.items[#]
647second_last = data.items[#-1]
648</pre>
649</YueDisplay>
650
568### 元表 651### 元表
569 652
570**<>** 操作符可提供元表操作的快捷方式。 653**<>** 操作符可提供元表操作的快捷方式。
571 654
572* **元表创建** 655* **元表创建**
573使用空括号 **<>** 或被 **<>** 包围的元方法键创建普通的Lua表。 656使用空括号 **<>** 或被 **<>** 包围的元方法键创建普通的Lua表。
574 657
575```moonscript 658```moonscript
@@ -605,7 +688,7 @@ close _ = &lt;close&gt;: -> print "超出范围"
605</pre> 688</pre>
606</YueDisplay> 689</YueDisplay>
607 690
608* **元表访问** 691* **元表访问**
609使用 **<>** 或被 **<>** 包围的元方法名或在 **<>** 中编写某些表达式来访问元表。 692使用 **<>** 或被 **<>** 包围的元方法名或在 **<>** 中编写某些表达式来访问元表。
610 693
611```moonscript 694```moonscript
@@ -629,7 +712,7 @@ print tb.item
629</pre> 712</pre>
630</YueDisplay> 713</YueDisplay>
631 714
632* **元表解构** 715* **元表解构**
633使用被 **<>** 包围的元方法键解构元表。 716使用被 **<>** 包围的元方法键解构元表。
634 717
635```moonscript 718```moonscript
@@ -680,7 +763,7 @@ with? io.open "test.txt", "w"
680 763
681### 管道 764### 管道
682 765
683与其使用一系列嵌套的函数调用,还可以考虑使用运算符 **|>** 来传递值。 766与其使用一系列嵌套的函数调用,还可以考虑使用运算符 **|>** 来传递值。
684 767
685```moonscript 768```moonscript
686"你好" |> print 769"你好" |> print
@@ -731,67 +814,87 @@ a ??= false
731 814
732### 隐式对象 815### 隐式对象
733 816
734您可以在表格块内使用符号 **\*** 开始编写一系列隐式结构。如果您正在创建隐式对象,对象的字段必须具有相同的缩进。 817你可以在表格块内使用符号 **\*** 或是 **-** 开始编写一系列隐式结构。如果你正在创建隐式对象,对象的字段必须具有相同的缩进。
818
735```moonscript 819```moonscript
820-- 赋值时使用隐式对象
736list = 821list =
737 * 1 822 * 1
738 * 2 823 * 2
739 * 3 824 * 3
740 825
826-- 函数调用时使用隐式对象
741func 827func
742 * 1 828 * 1
743 * 2 829 * 2
744 * 3 830 * 3
745 831
832-- 返回时使用隐式对象
833f = ->
834 return
835 * 1
836 * 2
837 * 3
838
839-- 表格时使用隐式对象
746tb = 840tb =
747 name: "abc" 841 name: "abc"
748 842
749 values: 843 values:
750 * "a" 844 - "a"
751 * "b" 845 - "b"
752 * "c" 846 - "c"
753 847
754 objects: 848 objects:
755 * name: "a" 849 - name: "a"
756 value: 1 850 value: 1
757 func: => @value + 1 851 func: => @value + 1
758 tb: 852 tb:
759 fieldA: 1 853 fieldA: 1
760 854
761 * name: "b" 855 - name: "b"
762 value: 2 856 value: 2
763 func: => @value + 2 857 func: => @value + 2
764 tb: { } 858 tb: { }
765
766``` 859```
767<YueDisplay> 860<YueDisplay>
768<pre> 861<pre>
862-- 赋值时使用隐式对象
769list = 863list =
770 * 1 864 * 1
771 * 2 865 * 2
772 * 3 866 * 3
773 867
868-- 函数调用时使用隐式对象
774func 869func
775 * 1 870 * 1
776 * 2 871 * 2
777 * 3 872 * 3
778 873
874-- 返回时使用隐式对象
875f = ->
876 return
877 * 1
878 * 2
879 * 3
880
881-- 表格时使用隐式对象
779tb = 882tb =
780 name: "abc" 883 name: "abc"
781 884
782 values: 885 values:
783 * "a" 886 - "a"
784 * "b" 887 - "b"
785 * "c" 888 - "c"
786 889
787 objects: 890 objects:
788 * name: "a" 891 - name: "a"
789 value: 1 892 value: 1
790 func: => @value + 1 893 func: => @value + 1
791 tb: 894 tb:
792 fieldA: 1 895 fieldA: 1
793 896
794 * name: "b" 897 - name: "b"
795 value: 2 898 value: 2
796 func: => @value + 2 899 func: => @value + 2
797 tb: { } 900 tb: { }
@@ -859,7 +962,7 @@ do
859 962
860导出语句提供了一种简洁的方式来定义当前的模块。 963导出语句提供了一种简洁的方式来定义当前的模块。
861 964
862* **命名导出** 965* **命名导出**
863带命名的导出将定义一个局部变量,并在导出的表中添加一个同名的字段。 966带命名的导出将定义一个局部变量,并在导出的表中添加一个同名的字段。
864 967
865```moonscript 968```moonscript
@@ -923,7 +1026,7 @@ export["a-b-c"] = 123
923</pre> 1026</pre>
924</YueDisplay> 1027</YueDisplay>
925 1028
926* **未命名导出** 1029* **未命名导出**
927未命名导出会将要导出的目标项目添加到导出表的数组部分。 1030未命名导出会将要导出的目标项目添加到导出表的数组部分。
928 1031
929```moonscript 1032```moonscript
@@ -953,7 +1056,7 @@ export with tmp
953</pre> 1056</pre>
954</YueDisplay> 1057</YueDisplay>
955 1058
956* **默认导出** 1059* **默认导出**
957在导出语句中使用 **default** 关键字,来替换导出的表为一个目标的对象。 1060在导出语句中使用 **default** 关键字,来替换导出的表为一个目标的对象。
958 1061
959```moonscript 1062```moonscript
@@ -1223,7 +1326,7 @@ print first, second, color
1223</pre> 1326</pre>
1224</YueDisplay> 1327</YueDisplay>
1225 1328
1226在进行解构时,可以指定默认值,如: 1329在进行解构时,可以指定默认值,如:
1227 1330
1228```moonscript 1331```moonscript
1229{:name = "nameless", :job = "jobless"} = person 1332{:name = "nameless", :job = "jobless"} = person
@@ -1234,7 +1337,7 @@ print first, second, color
1234</pre> 1337</pre>
1235</YueDisplay> 1338</YueDisplay>
1236 1339
1237在进行列表解构时,可以使用`_`作为占位符: 1340在进行列表解构时,可以使用`_`作为占位符:
1238 1341
1239```moonscript 1342```moonscript
1240[_, two, _, four] = items 1343[_, two, _, four] = items
@@ -1245,9 +1348,55 @@ print first, second, color
1245</pre> 1348</pre>
1246</YueDisplay> 1349</YueDisplay>
1247 1350
1248### 在其它地方的解构 1351### 范围解构
1352
1353你可以使用展开运算符 `...` 在列表解构中来捕获一个范围的值到子列表中。这在当你想要从列表的开头和结尾提取特定元素,同时收集中间的元素时非常有用。
1354
1355```moonscript
1356orders = ["first", "second", "third", "fourth", "last"]
1357[first, ...bulk, last] = orders
1358print first -- 打印: first
1359print bulk -- 打印: {"second", "third", "fourth"}
1360print last -- 打印: last
1361```
1362<YueDisplay>
1363<pre>
1364orders = ["first", "second", "third", "fourth", "last"]
1365[first, ...bulk, last] = orders
1366print first -- 打印: first
1367print bulk -- 打印: {"second", "third", "fourth"}
1368print last -- 打印: last
1369</pre>
1370</YueDisplay>
1371
1372展开运算符可以用在不同的位置来捕获不同的范围,并且你可以使用 `_` 作为占位符来表示你想跳过对应范围的捕获:
1373
1374```moonscript
1375-- 捕获第一个元素之后的所有元素
1376[first, ...rest] = orders
1377
1378-- 捕获最后一个元素之前的所有元素
1379[...start, last] = orders
1380
1381-- 跳过中间的元素,只捕获第一个和最后一个元素
1382[first, ..._, last] = orders
1383```
1384<YueDisplay>
1385<pre>
1386-- 捕获第一个元素之后的所有元素
1387[first, ...rest] = orders
1388
1389-- 捕获最后一个元素之前的所有元素
1390[...start, last] = orders
1391
1392-- 跳过中间的元素,只捕获第一个和最后一个元素
1393[first, ..._, last] = orders
1394</pre>
1395</YueDisplay>
1396
1397### 在其它地方的解构赋值
1249 1398
1250解构也可以出现在其它隐式进行赋值的地方。一个例子是用在for循环: 1399解构赋值也可以出现在其它隐式进行赋值的地方。一个例子是用在for循环
1251 1400
1252```moonscript 1401```moonscript
1253tuples = [ 1402tuples = [
@@ -1322,7 +1471,7 @@ print "好的"
1322 1471
1323### While 赋值 1472### While 赋值
1324 1473
1325可以在 while 循环中同样使用赋值来获取循环条件的值。 1474可以在 while 循环中同样使用赋值来获取循环条件的值。
1326```moonscript 1475```moonscript
1327while byte := stream\read_one! 1476while byte := stream\read_one!
1328 -- 对 byte 做一些操作 1477 -- 对 byte 做一些操作
@@ -1338,7 +1487,7 @@ while byte := stream\read_one!
1338 1487
1339## 可变参数赋值 1488## 可变参数赋值
1340 1489
1341可以将函数返回的结果赋值给一个可变参数符号 `...`。然后使用Lua的方式访问其内容。 1490可以将函数返回的结果赋值给一个可变参数符号 `...`。然后使用Lua的方式访问其内容。
1342```moonscript 1491```moonscript
1343list = [1, 2, 3, 4, 5] 1492list = [1, 2, 3, 4, 5]
1344fn = (ok) -> ok, table.unpack list 1493fn = (ok) -> ok, table.unpack list
@@ -1360,7 +1509,7 @@ print ok, count, first
1360 1509
1361## 空白 1510## 空白
1362 1511
1363月之脚本是一个对空白敏感的语言。您必须在相同的缩进中使用空格 **' '** 或制表符 **'\t'** 来编写一些代码块,如函数体、值列表和一些控制块。包含不同空白的表达式可能意味着不同的事情。制表符被视为4个空格,但最好不要混合使用空格和制表符。 1512月之脚本是一个对空白敏感的语言。你必须在相同的缩进中使用空格 **' '** 或制表符 **'\t'** 来编写一些代码块,如函数体、值列表和一些控制块。包含不同空白的表达式可能意味着不同的事情。制表符被视为4个空格,但最好不要混合使用空格和制表符。
1364 1513
1365### 多行链式调用 1514### 多行链式调用
1366 1515
@@ -1474,6 +1623,47 @@ catch err
1474</pre> 1623</pre>
1475</YueDisplay> 1624</YueDisplay>
1476 1625
1626### 错误处理简化
1627
1628`try?` 是 `try` 的功能简化语法,它不再返回 `try` 语句的布尔状态,并在成功时直接返回 `try` 代码块的结果,失败时返回 `nil` 值而非错误对象。
1629
1630```moonscript
1631a, b, c = try? func!
1632
1633-- 与空值合并运算符一起使用
1634a = (try? func!) ?? "default"
1635
1636-- 作为函数参数
1637f try? func!
1638
1639-- 带 catch 块的 try!
1640f try?
1641 print 123
1642 func!
1643catch e
1644 print e
1645 e
1646```
1647<YueDisplay>
1648<pre>
1649a, b, c = try? func!
1650
1651-- 与空值合并运算符一起使用
1652a = (try? func!) ?? "default"
1653
1654-- 作为函数参数
1655f try? func!
1656
1657-- 带 catch 块的 try!
1658f try?
1659 print 123
1660 func!
1661catch e
1662 print e
1663 e
1664</pre>
1665</YueDisplay>
1666
1477## 属性 1667## 属性
1478 1668
1479月之脚本现在提供了Lua 5.4新增的叫做属性的语法支持。在月之脚本编译到的Lua目标版本低于5.4时,你仍然可以同时使用`const`和`close`的属性声明语法,并获得常量检查和作用域回调的功能。 1669月之脚本现在提供了Lua 5.4新增的叫做属性的语法支持。在月之脚本编译到的Lua目标版本低于5.4时,你仍然可以同时使用`const`和`close`的属性声明语法,并获得常量检查和作用域回调的功能。
@@ -1502,6 +1692,19 @@ const {:a, :b, c, d} = tb
1502</pre> 1692</pre>
1503</YueDisplay> 1693</YueDisplay>
1504 1694
1695你也可以声明全局变量为常量。
1696
1697```moonscript
1698global const Constant = 123
1699-- Constant = 1
1700```
1701<YueDisplay>
1702<pre>
1703global const Constant = 123
1704-- Constant = 1
1705</pre>
1706</YueDisplay>
1707
1505## 字面量 1708## 字面量
1506 1709
1507Lua中的所有基本字面量都可以在月之脚本中使用。包括数字、字符串、布尔值和**nil**。 1710Lua中的所有基本字面量都可以在月之脚本中使用。包括数字、字符串、布尔值和**nil**。
@@ -1529,17 +1732,78 @@ print "我有#{math.random! * 100}%的把握。"
1529 1732
1530### 数字字面量 1733### 数字字面量
1531 1734
1532可以在数字字面量中使用下划线来增加可读性。 1735可以在数字字面量中使用下划线来增加可读性。
1533 1736
1534```moonscript 1737```moonscript
1535integer = 1_000_000 1738integer = 1_000_000
1536hex = 0xEF_BB_BF 1739hex = 0xEF_BB_BF
1740binary = 0B10011
1537``` 1741```
1538<YueDisplay> 1742<YueDisplay>
1539 1743
1540<pre> 1744<pre>
1541integer = 1_000_000 1745integer = 1_000_000
1542hex = 0xEF_BB_BF 1746hex = 0xEF_BB_BF
1747binary = 0B10011
1748</pre>
1749</YueDisplay>
1750
1751### YAML 风格字符串
1752
1753使用 `|` 前缀标记一个多行 YAML 风格字符串:
1754
1755```moonscript
1756str = |
1757 key: value
1758 list:
1759 - item1
1760 - #{expr}
1761```
1762<YueDisplay>
1763<pre>
1764str = |
1765 key: value
1766 list:
1767 - item1
1768 - #{expr}
1769</pre>
1770</YueDisplay>
1771
1772其效果类似于原生 Lua 的多行拼接,所有文本(含换行)将被保留下来,并支持 `#{...}` 语法,通过 `tostring(expr)` 插入表达式结果。
1773
1774YAML 风格的多行字符串会自动检测首行后最小的公共缩进,并从所有行中删除该前缀空白字符。这让你可以在代码中对齐文本,但输出字符串不会带多余缩进。
1775
1776```moonscript
1777fn = ->
1778 str = |
1779 foo:
1780 bar: baz
1781 return str
1782```
1783<YueDisplay>
1784<pre>
1785fn = ->
1786 str = |
1787 foo:
1788 bar: baz
1789 return str
1790</pre>
1791</YueDisplay>
1792
1793输出字符串中的 foo: 对齐到行首,不会带有函数缩进空格。保留内部缩进的相对结构,适合书写结构化嵌套样式的内容。
1794
1795支持自动处理字符中的引号、反斜杠等特殊符号,无需手动转义:
1796
1797```moonscript
1798str = |
1799 path: "C:\Program Files\App"
1800 note: 'He said: "#{Hello}!"'
1801```
1802<YueDisplay>
1803<pre>
1804str = |
1805 path: "C:\Program Files\App"
1806 note: 'He said: "#{Hello}!"'
1543</pre> 1807</pre>
1544</YueDisplay> 1808</YueDisplay>
1545 1809
@@ -1644,7 +1908,7 @@ print "数字的和是", sum 10, 20
1644</pre> 1908</pre>
1645</YueDisplay> 1909</YueDisplay>
1646 1910
1647如果需要做显式返回,可以使用return关键字: 1911如果需要做显式返回,可以使用return关键字:
1648 1912
1649```moonscript 1913```moonscript
1650sum = (x, y) -> return x + y 1914sum = (x, y) -> return x + y
@@ -1850,7 +2114,7 @@ print @value
1850</pre> 2114</pre>
1851</YueDisplay> 2115</YueDisplay>
1852 2116
1853可以通过一个占位符指定回调函数的传参位置。 2117可以通过一个占位符指定回调函数的传参位置。
1854 2118
1855```moonscript 2119```moonscript
1856(x) <- map _, [1, 2, 3] 2120(x) <- map _, [1, 2, 3]
@@ -1863,22 +2127,22 @@ x * 2
1863</pre> 2127</pre>
1864</YueDisplay> 2128</YueDisplay>
1865 2129
1866如果您希望在反向回调处理后继续编写更多其它的代码,您可以使用do语句将不归属反向回调的代码分开。 2130如果你希望在反向回调处理后继续编写更多其它的代码,可以使用 do 语句将不属于反向回调的代码分隔开。对于非粗箭头函数的反向回调,回调返回值的括号也是可以省略的。
1867 2131
1868```moonscript 2132```moonscript
1869result, msg = do 2133result, msg = do
1870 (data) <- readAsync "文件名.txt" 2134 data <- readAsync "文件名.txt"
1871 print data 2135 print data
1872 (info) <- processAsync data 2136 info <- processAsync data
1873 check info 2137 check info
1874print result, msg 2138print result, msg
1875``` 2139```
1876<YueDisplay> 2140<YueDisplay>
1877<pre> 2141<pre>
1878result, msg = do 2142result, msg = do
1879 (data) <- readAsync "文件名.txt" 2143 data <- readAsync "文件名.txt"
1880 print data 2144 print data
1881 (info) <- processAsync data 2145 info <- processAsync data
1882 check info 2146 check info
1883print result, msg 2147print result, msg
1884</pre> 2148</pre>
@@ -2037,7 +2301,7 @@ list_with_one_element = [ 1, ]
2037 2301
2038## 推导式 2302## 推导式
2039 2303
2040推导式为我们提供了一种便捷的语法,通过遍历现有对象并对其值应用表达式来构造出新的表格。月之脚本有两种推导式:列表推导式和表格推导式。它们最终都是产生Lua表格;列表推导式将值累积到类似数组的表格中,而表格推导式允许您在每次遍历时设置新表格的键和值。 2304推导式为我们提供了一种便捷的语法,通过遍历现有对象并对其值应用表达式来构造出新的表格。月之脚本有两种推导式:列表推导式和表格推导式。它们最终都是产生Lua表格;列表推导式将值累积到类似数组的表格中,而表格推导式允许你在每次遍历时设置新表格的键和值。
2041 2305
2042### 列表推导式 2306### 列表推导式
2043 2307
@@ -2057,13 +2321,11 @@ doubled = [item * 2 for i, item in ipairs items]
2057可以使用when子句筛选新表中包含的项目: 2321可以使用when子句筛选新表中包含的项目:
2058 2322
2059```moonscript 2323```moonscript
2060iter = ipairs items 2324slice = [item for i, item in ipairs items when i > 1 and i < 3]
2061slice = [item for i, item in iter when i > 1 and i < 3]
2062``` 2325```
2063<YueDisplay> 2326<YueDisplay>
2064<pre> 2327<pre>
2065iter = ipairs items 2328slice = [item for i, item in ipairs items when i > 1 and i < 3]
2066slice = [item for i, item in iter when i > 1 and i < 3]
2067</pre> 2329</pre>
2068</YueDisplay> 2330</YueDisplay>
2069 2331
@@ -2212,6 +2474,45 @@ slice = [item for item in *items[,,2]]
2212</pre> 2474</pre>
2213</YueDisplay> 2475</YueDisplay>
2214 2476
2477最小和最大边界都可以是负数,使用负数意味着边界是从表的末尾开始计算的。
2478
2479```moonscript
2480-- 取最后4个元素
2481slice = [item for item in *items[-4,-1]]
2482```
2483<YueDisplay>
2484<pre>
2485-- 取最后4个元素
2486slice = [item for item in *items[-4,-1]]
2487</pre>
2488</YueDisplay>
2489
2490切片的步长也可以是负数,这意味着元素会以相反的顺序被取出。
2491
2492```moonscript
2493reverse_slice = [item for item in *items[-1,1,-1]]
2494```
2495<YueDisplay>
2496<pre>
2497reverse_slice = [item for item in *items[-1,1,-1]]
2498</pre>
2499</YueDisplay>
2500
2501#### 切片表达式
2502
2503切片也可以作为表达式来使用。可以用于获取一个表包含的子列表。
2504
2505```moonscript
2506-- 取第2和第4个元素作为新的列表
2507sub_list = items[2, 4]
2508```
2509<YueDisplay>
2510<pre>
2511-- 取第2和第4个元素作为新的列表
2512sub_list = items[2, 4]
2513</pre>
2514</YueDisplay>
2515
2215## for 循环 2516## for 循环
2216 2517
2217Lua中有两种for循环形式,数字型和通用型: 2518Lua中有两种for循环形式,数字型和通用型:
@@ -2288,9 +2589,24 @@ doubled_evens = for i = 1, 20
2288</pre> 2589</pre>
2289</YueDisplay> 2590</YueDisplay>
2290 2591
2291您还可以结合for循环表达式与continue语句来过滤值。 2592此外,for循环还支持带返回值的break语句,这样循环本身就可以作为一个表达式,在满足条件时提前退出并返回有意义的结果。
2292 2593
2293注意出现在函数体末尾的for循环,不会被当作是一个表达式,并将循环结果累积到一个列表中作为返回值(相反,函数将返回nil)。如果要函数末尾的循环转换为列表表达式,可以使用返回语句加for循环表达式。 2594例如,查找第一个大于10的数字:
2595
2596```moonscript
2597first_large = for n in *numbers
2598 break n if n > 10
2599```
2600<YueDisplay>
2601<pre>
2602first_large = for n in *numbers
2603 break n if n > 10
2604</pre>
2605</YueDisplay>
2606
2607你还可以结合for循环表达式与continue语句来过滤值。
2608
2609注意出现在函数体末尾的for循环,不会被当作是一个表达式并将循环结果累积到一个列表中作为返回值(相反,函数将返回nil)。如果要函数末尾的循环转换为列表表达式,可以显式地使用返回语句加for循环表达式。
2294 2610
2295```moonscript 2611```moonscript
2296func_a = -> for i = 1, 10 do print i 2612func_a = -> for i = 1, 10 do print i
@@ -2515,7 +2831,7 @@ print "你真幸运!" unless math.random! > 0.1
2515 2831
2516### 范围表达式 2832### 范围表达式
2517 2833
2518可以使用范围表达式来编写进行范围检查的代码。 2834可以使用范围表达式来编写进行范围检查的代码。
2519 2835
2520```moonscript 2836```moonscript
2521a = 5 2837a = 5
@@ -2588,28 +2904,26 @@ reader\parse_line! until reader\eof!
2588 2904
2589## switch 语句 2905## switch 语句
2590 2906
2591switch语句是为了简化检查一系列相同值的if语句而提供的简写语法。要注意用于比较检查的目标值只会计算一次。和if语句一样,switch语句在最后可以接一个else代码块来处理没有匹配的情况。在生成的Lua代码中,进行比较是使用==操作符完成的。 2907switch语句是为了简化检查一系列相同值的if语句而提供的简写语法。要注意用于比较检查的目标值只会计算一次。和if语句一样,switch语句在最后可以接一个else代码块来处理没有匹配的情况。在生成的Lua代码中,进行比较是使用==操作符完成的。switch语句中也可以使用赋值表达式来储存临时变量值。
2592 2908
2593```moonscript 2909```moonscript
2594name = "Dan" 2910switch name := "Dan"
2595switch name
2596 when "Robert" 2911 when "Robert"
2597 print "你是Robert" 2912 print "你是Robert"
2598 when "Dan", "Daniel" 2913 when "Dan", "Daniel"
2599 print "你的名字是Dan" 2914 print "你的名字是Dan"
2600 else 2915 else
2601 print "我不知道你的名字" 2916 print "我不认识,你的名字是#{name}"
2602``` 2917```
2603<YueDisplay> 2918<YueDisplay>
2604<pre> 2919<pre>
2605name = "Dan" 2920switch name := "Dan"
2606switch name
2607 when "Robert" 2921 when "Robert"
2608 print "你是Robert" 2922 print "你是Robert"
2609 when "Dan", "Daniel" 2923 when "Dan", "Daniel"
2610 print "你的名字是Dan" 2924 print "你的名字是Dan"
2611 else 2925 else
2612 print "我不知道你的名字" 2926 print "我不认识,你的名字是#{name}"
2613</pre> 2927</pre>
2614</YueDisplay> 2928</YueDisplay>
2615 2929
@@ -2686,7 +3000,7 @@ else
2686</pre> 3000</pre>
2687</YueDisplay> 3001</YueDisplay>
2688 3002
2689值得注意的是,在生成Lua代码时,我们要做检查的目标变量会放在==表达式的右侧。当您希望给when子句的比较对象定义一个\_\_eq元方法来重载判断逻辑时,可能会有用。 3003值得注意的是,在生成Lua代码时,我们要做检查的目标变量会放在==表达式的右侧。当你希望给when子句的比较对象定义一个\_\_eq元方法来重载判断逻辑时,可能会有用。
2690 3004
2691### 表格匹配 3005### 表格匹配
2692 3006
@@ -2746,9 +3060,126 @@ switch item
2746</pre> 3060</pre>
2747</YueDisplay> 3061</YueDisplay>
2748 3062
3063你也可以匹配数组元素、表格字段,甚至使用数组或表格字面量来匹配嵌套的结构。
3064
3065匹配数组元素。
3066
3067```moonscript
3068switch tb
3069 when [1, 2, 3]
3070 print "1, 2, 3"
3071 when [1, b, 3]
3072 print "1, #{b}, 3"
3073 when [1, 2, b = 3] -- 变量b有默认值
3074 print "1, 2, #{b}"
3075```
3076<YueDisplay>
3077<pre>
3078switch tb
3079 when [1, 2, 3]
3080 print "1, 2, 3"
3081 when [1, b, 3]
3082 print "1, #{b}, 3"
3083 when [1, 2, b = 3] -- 变量b有默认值
3084 print "1, 2, #{b}"
3085</pre>
3086</YueDisplay>
3087
3088匹配表格字段。
3089
3090```moonscript
3091switch tb
3092 when success: true, :result
3093 print "成功", result
3094 when success: false
3095 print "失败", result
3096 else
3097 print "无效值"
3098```
3099<YueDisplay>
3100<pre>
3101switch tb
3102 when success: true, :result
3103 print "成功", result
3104 when success: false
3105 print "失败", result
3106 else
3107 print "无效值"
3108</pre>
3109</YueDisplay>
3110
3111匹配嵌套的表格结构。
3112
3113```moonscript
3114switch tb
3115 when data: {type: "success", :content}
3116 print "成功", content
3117 when data: {type: "error", :content}
3118 print "失败", content
3119 else
3120 print "无效值"
3121```
3122<YueDisplay>
3123<pre>
3124switch tb
3125 when data: {type: "success", :content}
3126 print "成功", content
3127 when data: {type: "error", :content}
3128 print "失败", content
3129 else
3130 print "无效值"
3131</pre>
3132</YueDisplay>
3133
3134匹配表格数组。
3135
3136```moonscript
3137switch tb
3138 when [
3139 {a: 1, b: 2}
3140 {a: 3, b: 4}
3141 {a: 5, b: 6}
3142 fourth
3143 ]
3144 print "匹配成功", fourth
3145```
3146<YueDisplay>
3147<pre>
3148switch tb
3149 when [
3150 {a: 1, b: 2}
3151 {a: 3, b: 4}
3152 {a: 5, b: 6}
3153 fourth
3154 ]
3155 print "匹配成功", fourth
3156</pre>
3157</YueDisplay>
3158
3159匹配一个列表并捕获特定范围内的元素。
3160
3161```moonscript
3162segments = ["admin", "users", "logs", "view"]
3163switch segments
3164 when [...groups, resource, action]
3165 print "Group:", groups -- 打印: {"admin", "users"}
3166 print "Resource:", resource -- 打印: "logs"
3167 print "Action:", action -- 打印: "view"
3168```
3169<YueDisplay>
3170<pre>
3171segments = ["admin", "users", "logs", "view"]
3172switch segments
3173 when [...groups, resource, action]
3174 print "Group:", groups -- 打印: {"admin", "users"}
3175 print "Resource:", resource -- 打印: "logs"
3176 print "Action:", action -- 打印: "view"
3177</pre>
3178</YueDisplay>
3179
2749## 面向对象编程 3180## 面向对象编程
2750 3181
2751在以下的示例中,月之脚本生成的Lua代码可能看起来会很复杂。所以最好主要关注月之脚本代码层面的意义,然后如果您想知道关于面向对象功能的实现细节,再查看Lua代码。 3182在以下的示例中,月之脚本生成的Lua代码可能看起来会很复杂。所以最好主要关注月之脚本代码层面的意义,然后如果你想知道关于面向对象功能的实现细节,再查看Lua代码。
2752 3183
2753一个简单的类: 3184一个简单的类:
2754 3185
@@ -3216,7 +3647,7 @@ x = class
3216 3647
3217### 类混合 3648### 类混合
3218 3649
3219您可以通过使用 `using` 关键字来实现类混合。这意味着您可以从一个普通 Lua 表格或已定义的类对象中,复制函数到您创建的新类中。当您使用普通 Lua 表格进行类混合时,您有机会用自己的实现来重写类的索引方法(例如元方法 `__index`)。然而,当您从一个类对象做混合时,需要注意的是该类对象的元方法将不会被复制到新类。 3650你可以通过使用 `using` 关键字来实现类混合。这意味着你可以从一个普通 Lua 表格或已定义的类对象中,复制函数到你创建的新类中。当你使用普通 Lua 表格进行类混合时,你有机会用自己的实现来重写类的索引方法(例如元方法 `__index`)。然而,当你从一个类对象做混合时,需要注意的是该类对象的元方法将不会被复制到新类。
3220 3651
3221```moonscript 3652```moonscript
3222MyIndex = __index: var: 1 3653MyIndex = __index: var: 1
@@ -3318,22 +3749,22 @@ me = create_person "Leaf", [dad, mother, sister]
3318 3749
3319在此用法中,with可以被视为K组合子(k-combinator)的一种特殊形式。 3750在此用法中,with可以被视为K组合子(k-combinator)的一种特殊形式。
3320 3751
3321如果给表达式另外起一个名称的话,with语句中的表达式也可以是一个赋值语句。 3752如果想给表达式另外起一个名称的话,with语句中的表达式也可以是一个赋值语句。
3322 3753
3323```moonscript 3754```moonscript
3324with str = "你好" 3755with str := "你好"
3325 print "原始:", str 3756 print "原始:", str
3326 print "大写:", \upper! 3757 print "大写:", \upper!
3327``` 3758```
3328<YueDisplay> 3759<YueDisplay>
3329<pre> 3760<pre>
3330with str = "你好" 3761with str := "你好"
3331 print "原始:", str 3762 print "原始:", str
3332 print "大写:", \upper! 3763 print "大写:", \upper!
3333</pre> 3764</pre>
3334</YueDisplay> 3765</YueDisplay>
3335 3766
3336在with语句中用`[]`访问特殊键。 3767 `with` 语句中使用 `[]` 访问特殊键。
3337 3768
3338```moonscript 3769```moonscript
3339with tb 3770with tb
@@ -3356,6 +3787,19 @@ with tb
3356</pre> 3787</pre>
3357</YueDisplay> 3788</YueDisplay>
3358 3789
3790`with?` 是 `with` 语法的一个增强版本,引入了存在性检查,用于在不显式判空的情况下安全访问可能为 nil 的对象。
3791
3792```moonscript
3793with? obj
3794 print obj.name
3795```
3796<YueDisplay>
3797<pre>
3798with? obj
3799 print obj.name
3800</pre>
3801</YueDisplay>
3802
3359## do 语句 3803## do 语句
3360 3804
3361当用作语句时,do语句的作用就像在Lua中差不多。 3805当用作语句时,do语句的作用就像在Lua中差不多。
@@ -3375,7 +3819,7 @@ print var -- 这里是nil
3375</pre> 3819</pre>
3376</YueDisplay> 3820</YueDisplay>
3377 3821
3378月之脚本的 **do** 也可以用作表达式。允许您将多行代码的处理合并为一个表达式,并将do语句代码块的最后一个语句作为表达式返回的结果。 3822月之脚本的 **do** 也可以用作表达式。允许你将多行代码的处理合并为一个表达式,并将do语句代码块的最后一个语句作为表达式返回的结果。
3379 3823
3380```moonscript 3824```moonscript
3381counter = do 3825counter = do
@@ -4334,8 +4778,8 @@ simplified: boolean
4334 4778
4335版权 (c) 2017-2025 李瑾 \<dragon-fly@qq.com\> 4779版权 (c) 2017-2025 李瑾 \<dragon-fly@qq.com\>
4336 4780
4337特此免费授予任何获得本软件副本和相关文档文件(下称“软件”)的人不受限制地处置该软件的权利,包括不受限制地使用、复制、修改、合并、发布、分发、转授许可和/或出售该软件副本,以及再授权被配发了本软件的人如上的权利,须在下列条件下: 4781特此免费授予任何获得本软件副本和相关文档文件(下称“软件”)的人不受限制地处置该软件的权利,包括不受限制地使用、复制、修改、合并、发布、分发、转授许可和/或出售该软件副本,以及再授权被配发了本软件的人如上的权利,须在下列条件下:
4338上述版权声明和本许可声明应包含在该软件的所有副本或实质成分中。 4782上述版权声明和本许可声明应包含在该软件的所有副本或实质成分中。
4339本软件是“如此”提供的,没有任何形式的明示或暗示的保证,包括但不限于对适销性、特定用途的适用性和不侵权的保证。在任何情况下,作者或版权持有人都不对任何索赔、损害或其他责任负责,无论这些追责来自合同、侵权或其它行为中,还是产生于、源于或有关于本软件以及本软件的使用或其它处置。 4783本软件是“如此”提供的,没有任何形式的明示或暗示的保证,包括但不限于对适销性、特定用途的适用性和不侵权的保证。在任何情况下,作者或版权持有人都不对任何索赔、损害或其他责任负责,无论这些追责来自合同、侵权或其它行为中,还是产生于、源于或有关于本软件以及本软件的使用或其它处置。
4340 4784
4341<CompilerModal /> 4785<CompilerModal />