diff options
Diffstat (limited to 'doc/docs')
-rwxr-xr-x | doc/docs/doc/README.md | 580 | ||||
-rwxr-xr-x | doc/docs/zh/doc/README.md | 608 |
2 files changed, 1039 insertions, 149 deletions
diff --git a/doc/docs/doc/README.md b/doc/docs/doc/README.md index 89bd643..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 |
19 | import "yue" as :p, :to_lua | 19 | import p, to_lua from "yue" |
20 | 20 | ||
21 | -- object literals | 21 | -- object literals |
22 | inventory = | 22 | inventory = |
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 | ||
33 | map = (arr, action) -> | ||
34 | [action item for item in *arr] | ||
35 | |||
36 | filter = (arr, cond) -> | ||
37 | [item for item in *arr when cond item] | ||
38 | |||
39 | reduce = (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 |
54 | import "yue" as :p, :to_lua | 64 | import p, to_lua from "yue" |
55 | 65 | ||
56 | -- object literals | 66 | -- object literals |
57 | inventory = | 67 | inventory = |
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 | ||
78 | map = (arr, action) -> | ||
79 | [action item for item in *arr] | ||
80 | |||
81 | filter = (arr, cond) -> | ||
82 | [item for item in *arr when cond item] | ||
83 | |||
84 | reduce = (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 |  Use YueScript module in Lua: | 153 |  Use YueScript module in Lua: |
134 | 154 | ||
135 | * **Case 1** | 155 | * **Case 1** |
136 | Require "your_yuescript_entry.yue" in Lua. | 156 | Require "your_yuescript_entry.yue" in Lua. |
137 | ```Lua | 157 | ```Lua |
138 | require("yue")("your_yuescript_entry") | 158 | require("yue")("your_yuescript_entry") |
139 | ``` | 159 | ``` |
140 |  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 |  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** |
143 | Require YueScript module and rewite message by hand. | 163 | Require YueScript module and rewite message by hand. |
144 | ```lua | 164 | ```lua |
145 | local yue = require("yue") | 165 | local yue = require("yue") |
@@ -151,7 +171,7 @@ end, function(err) | |||
151 | end) | 171 | end) |
152 | ``` | 172 | ``` |
153 | 173 | ||
154 | * **Case 3** | 174 | * **Case 3** |
155 | Use the YueScript compiler function in Lua. | 175 | Use the YueScript compiler function in Lua. |
156 | ```lua | 176 | ```lua |
157 | local yue = require("yue") | 177 | local 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 |   Use cases: | 226 |   Use cases: |
207 |   Recursively compile every YueScript file with extension **.yue** under current path: **yue .** | 227 |   Recursively compile every YueScript file with extension **.yue** under current path: **yue .** |
208 |   Compile and save results to a target path: **yue -t /target/path/ .** | 228 |   Compile and save results to a target path: **yue -t /target/path/ .** |
209 |   Compile and reserve debug info: **yue -l .** | 229 |   Compile and reserve debug info: **yue -l .** |
210 |   Compile and generate minified codes: **yue -m .** | 230 |   Compile and generate minified codes: **yue -m .** |
211 |   Execute raw codes: **yue -e 'print 123'** | 231 |   Execute raw codes: **yue -e 'print 123'** |
212 |   Execute a YueScript file: **yue -e main.yue** | 232 |   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 | |||
449 | You 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 | ||
452 | macro printNumAndStr = (num `Num, str `String) -> | | ||
453 | print( | ||
454 | #{num} | ||
455 | #{str} | ||
456 | ) | ||
457 | |||
458 | $printNumAndStr 123, "hello" | ||
459 | ``` | ||
460 | <YueDisplay> | ||
461 | <pre> | ||
462 | macro printNumAndStr = (num `Num, str `String) -> | | ||
463 | print( | ||
464 | #{num} | ||
465 | #{str} | ||
466 | ) | ||
467 | |||
468 | $printNumAndStr 123, "hello" | ||
469 | </pre> | ||
470 | </YueDisplay> | ||
471 | |||
472 | If 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 | ||
475 | macro 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> | ||
484 | macro 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 | |||
493 | For more details about available AST nodes, please refer to the uppercased definitions in [yue_parser.cpp](https://github.com/IppClub/YueScript/blob/main/src/yuescript/yue_parser.cpp). | ||
494 | |||
427 | ## Operator | 495 | ## Operator |
428 | 496 | ||
429 | All 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. | 497 | All 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 | |||
639 | You can use the **#** operator to get the last elements of a table. | ||
640 | |||
641 | ```moonscript | ||
642 | last = data.items[#] | ||
643 | second_last = data.items[#-1] | ||
644 | ``` | ||
645 | <YueDisplay> | ||
646 | <pre> | ||
647 | last = data.items[#] | ||
648 | second_last = data.items[#-1] | ||
649 | </pre> | ||
650 | </YueDisplay> | ||
651 | |||
569 | ### Metatable | 652 | ### Metatable |
570 | 653 | ||
571 | The **<>** operator can be used as a shortcut for metatable manipulation. | 654 | The **<>** operator can be used as a shortcut for metatable manipulation. |
572 | 655 | ||
573 | * **Metatable Creation** | 656 | * **Metatable Creation** |
574 | Create normal table with empty bracekets **<>** or metamethod key which is surrounded by **<>**. | 657 | Create normal table with empty bracekets **<>** or metamethod key which is surrounded by **<>**. |
575 | 658 | ||
576 | ```moonscript | 659 | ```moonscript |
@@ -606,7 +689,7 @@ close _ = <close>: -> print "out of scope" | |||
606 | </pre> | 689 | </pre> |
607 | </YueDisplay> | 690 | </YueDisplay> |
608 | 691 | ||
609 | * **Metatable Accessing** | 692 | * **Metatable Accessing** |
610 | Accessing metatable with **<>** or metamethod name surrounded by **<>** or writing some expression in **<>**. | 693 | Accessing 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** |
634 | Destruct metatable with metamethod key surrounded by **<>**. | 717 | Destruct 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 | ||
735 | You 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. | 818 | You 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 | ||
737 | list = | 822 | list = |
738 | * 1 | 823 | * 1 |
739 | * 2 | 824 | * 2 |
740 | * 3 | 825 | * 3 |
741 | 826 | ||
827 | -- function call with implicit object | ||
742 | func | 828 | func |
743 | * 1 | 829 | * 1 |
744 | * 2 | 830 | * 2 |
745 | * 3 | 831 | * 3 |
746 | 832 | ||
833 | -- return with implicit object | ||
834 | f = -> | ||
835 | return | ||
836 | * 1 | ||
837 | * 2 | ||
838 | * 3 | ||
839 | |||
840 | -- table with implicit object | ||
747 | tb = | 841 | tb = |
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 | ||
770 | list = | 865 | list = |
771 | * 1 | 866 | * 1 |
772 | * 2 | 867 | * 2 |
773 | * 3 | 868 | * 3 |
774 | 869 | ||
870 | -- function call with implicit object | ||
775 | func | 871 | func |
776 | * 1 | 872 | * 1 |
777 | * 2 | 873 | * 2 |
778 | * 3 | 874 | * 3 |
779 | 875 | ||
876 | -- return with implicit object | ||
877 | f = -> | ||
878 | return | ||
879 | * 1 | ||
880 | * 2 | ||
881 | * 3 | ||
882 | |||
883 | -- table with implicit object | ||
780 | tb = | 884 | tb = |
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 | ||
861 | The export statement offers a concise way to define modules. | 965 | The export statement offers a concise way to define modules. |
862 | 966 | ||
863 | * **Named Export** | 967 | * **Named Export** |
864 | Named export will define a local variable as well as adding a field in the exported table. | 968 | Named 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** |
928 | Unnamed export will add the target item into the array part of the exported table. | 1032 | Unnamed 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** |
958 | Using the **default** keyword in export statement to replace the exported table with any thing. | 1062 | Using 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 | ||
1205 | It’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: | 1309 | It'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 | |||
1355 | You 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 | ||
1358 | orders = ["first", "second", "third", "fourth", "last"] | ||
1359 | [first, ...bulk, last] = orders | ||
1360 | print first -- prints: first | ||
1361 | print bulk -- prints: {"second", "third", "fourth"} | ||
1362 | print last -- prints: last | ||
1363 | ``` | ||
1364 | <YueDisplay> | ||
1365 | <pre> | ||
1366 | orders = ["first", "second", "third", "fourth", "last"] | ||
1367 | [first, ...bulk, last] = orders | ||
1368 | print first -- prints: first | ||
1369 | print bulk -- prints: {"second", "third", "fourth"} | ||
1370 | print last -- prints: last | ||
1371 | </pre> | ||
1372 | </YueDisplay> | ||
1373 | |||
1374 | The 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 | ||
1251 | Destructuring can also show up in places where an assignment implicitly takes place. An example of this is a for loop: | 1401 | Destructuring 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 | ||
1633 | a, b, c = try? func! | ||
1634 | |||
1635 | -- with nil coalescing operator | ||
1636 | a = (try? func!) ?? "default" | ||
1637 | |||
1638 | -- as function argument | ||
1639 | f try? func! | ||
1640 | |||
1641 | -- with catch block | ||
1642 | f try? | ||
1643 | print 123 | ||
1644 | func! | ||
1645 | catch e | ||
1646 | print e | ||
1647 | e | ||
1648 | ``` | ||
1649 | <YueDisplay> | ||
1650 | <pre> | ||
1651 | a, b, c = try? func! | ||
1652 | |||
1653 | -- with nil coalescing operator | ||
1654 | a = (try? func!) ?? "default" | ||
1655 | |||
1656 | -- as function argument | ||
1657 | f try? func! | ||
1658 | |||
1659 | -- with catch block | ||
1660 | f try? | ||
1661 | print 123 | ||
1662 | func! | ||
1663 | catch e | ||
1664 | print e | ||
1665 | e | ||
1666 | </pre> | ||
1667 | </YueDisplay> | ||
1668 | |||
1478 | ## Attributes | 1669 | ## Attributes |
1479 | 1670 | ||
1480 | Syntax 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. | 1671 | Syntax 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 | ||
1697 | You can also declare a global variable to be `const`. | ||
1698 | |||
1699 | ```moonscript | ||
1700 | global const Constant = 123 | ||
1701 | -- Constant = 1 | ||
1702 | ``` | ||
1703 | <YueDisplay> | ||
1704 | <pre> | ||
1705 | global const Constant = 123 | ||
1706 | -- Constant = 1 | ||
1707 | </pre> | ||
1708 | </YueDisplay> | ||
1709 | |||
1506 | ## Literals | 1710 | ## Literals |
1507 | 1711 | ||
1508 | All of the primitive literals in Lua can be used. This applies to numbers, strings, booleans, and **nil**. | 1712 | All 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 |
1536 | integer = 1_000_000 | 1740 | integer = 1_000_000 |
1537 | hex = 0xEF_BB_BF | 1741 | hex = 0xEF_BB_BF |
1742 | binary = 0B10011 | ||
1538 | ``` | 1743 | ``` |
1539 | <YueDisplay> | 1744 | <YueDisplay> |
1540 | 1745 | ||
1541 | <pre> | 1746 | <pre> |
1542 | integer = 1_000_000 | 1747 | integer = 1_000_000 |
1543 | hex = 0xEF_BB_BF | 1748 | hex = 0xEF_BB_BF |
1749 | binary = 0B10011 | ||
1750 | </pre> | ||
1751 | </YueDisplay> | ||
1752 | |||
1753 | ### YAML Multiline String | ||
1754 | |||
1755 | The `|` prefix introduces a YAML-style multiline string literal: | ||
1756 | |||
1757 | ```moonscript | ||
1758 | str = | | ||
1759 | key: value | ||
1760 | list: | ||
1761 | - item1 | ||
1762 | - #{expr} | ||
1763 | ``` | ||
1764 | <YueDisplay> | ||
1765 | <pre> | ||
1766 | str = | | ||
1767 | key: value | ||
1768 | list: | ||
1769 | - item1 | ||
1770 | - #{expr} | ||
1771 | </pre> | ||
1772 | </YueDisplay> | ||
1773 | |||
1774 | This 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 | |||
1776 | YAML 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 | ||
1779 | fn = -> | ||
1780 | str = | | ||
1781 | foo: | ||
1782 | bar: baz | ||
1783 | return str | ||
1784 | ``` | ||
1785 | <YueDisplay> | ||
1786 | <pre> | ||
1787 | fn = -> | ||
1788 | str = | | ||
1789 | foo: | ||
1790 | bar: baz | ||
1791 | return str | ||
1792 | </pre> | ||
1793 | </YueDisplay> | ||
1794 | |||
1795 | Internal indentation is preserved relative to the removed common prefix, allowing clean nested structures. | ||
1796 | |||
1797 | All 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 | ||
1800 | str = | | ||
1801 | path: "C:\Program Files\App" | ||
1802 | note: 'He said: "#{Hello}!"' | ||
1803 | ``` | ||
1804 | <YueDisplay> | ||
1805 | <pre> | ||
1806 | str = | | ||
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 | ||
1905 | If you wish to have further code after your backcalls, you can set them aside with a do statement. | 2170 | If 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 |
1908 | result, msg = do | 2173 | result, 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 |
1913 | print result, msg | 2178 | print result, msg |
1914 | ``` | 2179 | ``` |
1915 | <YueDisplay> | 2180 | <YueDisplay> |
1916 | <pre> | 2181 | <pre> |
1917 | result, msg = do | 2182 | result, 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 |
1922 | print result, msg | 2187 | print result, msg |
1923 | </pre> | 2188 | </pre> |
@@ -2096,13 +2361,11 @@ doubled = [item * 2 for i, item in ipairs items] | |||
2096 | The items included in the new table can be restricted with a when clause: | 2361 | The items included in the new table can be restricted with a when clause: |
2097 | 2362 | ||
2098 | ```moonscript | 2363 | ```moonscript |
2099 | iter = ipairs items | 2364 | slice = [item for i, item in ipairs items when i > 1 and i < 3] |
2100 | slice = [item for i, item in iter when i > 1 and i < 3] | ||
2101 | ``` | 2365 | ``` |
2102 | <YueDisplay> | 2366 | <YueDisplay> |
2103 | <pre> | 2367 | <pre> |
2104 | iter = ipairs items | 2368 | slice = [item for i, item in ipairs items when i > 1 and i < 3] |
2105 | slice = [item for i, item in iter when i > 1 and i < 3] | ||
2106 | </pre> | 2369 | </pre> |
2107 | </YueDisplay> | 2370 | </YueDisplay> |
2108 | 2371 | ||
@@ -2250,6 +2513,45 @@ slice = [item for item in *items[,,2]] | |||
2250 | </pre> | 2513 | </pre> |
2251 | </YueDisplay> | 2514 | </YueDisplay> |
2252 | 2515 | ||
2516 | Both 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 | ||
2520 | slice = [item for item in *items[-4,-1]] | ||
2521 | ``` | ||
2522 | <YueDisplay> | ||
2523 | <pre> | ||
2524 | -- take the last 4 items | ||
2525 | slice = [item for item in *items[-4,-1]] | ||
2526 | </pre> | ||
2527 | </YueDisplay> | ||
2528 | |||
2529 | The step size can also be negative, which means that the items are taken in reverse order. | ||
2530 | |||
2531 | ```moonscript | ||
2532 | reverse_slice = [item for item in *items[-1,1,-1]] | ||
2533 | ``` | ||
2534 | <YueDisplay> | ||
2535 | <pre> | ||
2536 | reverse_slice = [item for item in *items[-1,1,-1]] | ||
2537 | </pre> | ||
2538 | </YueDisplay> | ||
2539 | |||
2540 | #### Slicing Expression | ||
2541 | |||
2542 | Slicing 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 | ||
2546 | sub_list = items[2, 4] | ||
2547 | ``` | ||
2548 | <YueDisplay> | ||
2549 | <pre> | ||
2550 | -- take the 2nd and 4th items as a new list | ||
2551 | sub_list = items[2, 4] | ||
2552 | </pre> | ||
2553 | </YueDisplay> | ||
2554 | |||
2253 | ## For Loop | 2555 | ## For Loop |
2254 | 2556 | ||
2255 | There are two for loop forms, just like in Lua. A numeric one and a generic one: | 2557 | There are two for loop forms, just like in Lua. A numeric one and a generic one: |
@@ -2326,6 +2628,23 @@ doubled_evens = for i = 1, 20 | |||
2326 | </pre> | 2628 | </pre> |
2327 | </YueDisplay> | 2629 | </YueDisplay> |
2328 | 2630 | ||
2631 | In 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 | |||
2633 | For example, to find the first number greater than 10: | ||
2634 | |||
2635 | ```moonscript | ||
2636 | first_large = for n in *numbers | ||
2637 | break n if n > 10 | ||
2638 | ``` | ||
2639 | <YueDisplay> | ||
2640 | <pre> | ||
2641 | first_large = for n in *numbers | ||
2642 | break n if n > 10 | ||
2643 | </pre> | ||
2644 | </YueDisplay> | ||
2645 | |||
2646 | This break-with-value syntax enables concise and expressive search or early-exit patterns directly within loop expressions. | ||
2647 | |||
2329 | You can also filter values by combining the for loop expression with the continue statement. | 2648 | You can also filter values by combining the for loop expression with the continue statement. |
2330 | 2649 | ||
2331 | For 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. | 2650 | For 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. |
@@ -2347,7 +2666,7 @@ print func_b! -- prints table object | |||
2347 | </pre> | 2666 | </pre> |
2348 | </YueDisplay> | 2667 | </YueDisplay> |
2349 | 2668 | ||
2350 | This is done to avoid the needless creation of tables for functions that don’t need to return the results of the loop. | 2669 | This is done to avoid the needless creation of tables for functions that don't need to return the results of the loop. |
2351 | 2670 | ||
2352 | ## Repeat Loop | 2671 | ## Repeat Loop |
2353 | 2672 | ||
@@ -2626,28 +2945,26 @@ reader\parse_line! until reader\eof! | |||
2626 | 2945 | ||
2627 | ## Switch | 2946 | ## Switch |
2628 | 2947 | ||
2629 | The 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. | 2948 | The 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. |
2630 | 2949 | ||
2631 | ```moonscript | 2950 | ```moonscript |
2632 | name = "Dan" | 2951 | switch name := "Dan" |
2633 | switch name | ||
2634 | when "Robert" | 2952 | when "Robert" |
2635 | print "You are Robert" | 2953 | print "You are Robert" |
2636 | when "Dan", "Daniel" | 2954 | when "Dan", "Daniel" |
2637 | print "Your name, it's Dan" | 2955 | print "Your name, it's Dan" |
2638 | else | 2956 | else |
2639 | print "I don't know about your name" | 2957 | print "I don't know about you with name #{name}" |
2640 | ``` | 2958 | ``` |
2641 | <YueDisplay> | 2959 | <YueDisplay> |
2642 | <pre> | 2960 | <pre> |
2643 | name = "Dan" | 2961 | switch name := "Dan" |
2644 | switch name | ||
2645 | when "Robert" | 2962 | when "Robert" |
2646 | print "You are Robert" | 2963 | print "You are Robert" |
2647 | when "Dan", "Daniel" | 2964 | when "Dan", "Daniel" |
2648 | print "Your name, it's Dan" | 2965 | print "Your name, it's Dan" |
2649 | else | 2966 | else |
2650 | print "I don't know about your name" | 2967 | print "I don't know about you with name #{name}" |
2651 | </pre> | 2968 | </pre> |
2652 | </YueDisplay> | 2969 | </YueDisplay> |
2653 | 2970 | ||
@@ -2678,7 +2995,7 @@ next_number = switch b | |||
2678 | </pre> | 2995 | </pre> |
2679 | </YueDisplay> | 2996 | </YueDisplay> |
2680 | 2997 | ||
2681 | We 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. | 2998 | We 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. |
2682 | 2999 | ||
2683 | ```moonscript | 3000 | ```moonscript |
2684 | msg = switch math.random(1, 5) | 3001 | msg = switch math.random(1, 5) |
@@ -2724,7 +3041,7 @@ else | |||
2724 | </pre> | 3041 | </pre> |
2725 | </YueDisplay> | 3042 | </YueDisplay> |
2726 | 3043 | ||
2727 | It 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. | 3044 | It 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. |
2728 | 3045 | ||
2729 | ### Table Matching | 3046 | ### Table Matching |
2730 | 3047 | ||
@@ -2784,6 +3101,123 @@ switch item | |||
2784 | </pre> | 3101 | </pre> |
2785 | </YueDisplay> | 3102 | </YueDisplay> |
2786 | 3103 | ||
3104 | You can also match against array elements, table fields, and even nested structures with array or table literals. | ||
3105 | |||
3106 | Match against array elements. | ||
3107 | |||
3108 | ```moonscript | ||
3109 | switch 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> | ||
3119 | switch 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 | |||
3129 | Match against table fields with destructuring. | ||
3130 | |||
3131 | ```moonscript | ||
3132 | switch 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> | ||
3142 | switch 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 | |||
3152 | Match against nested table structures. | ||
3153 | |||
3154 | ```moonscript | ||
3155 | switch 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> | ||
3165 | switch 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 | |||
3175 | Match against array of tables. | ||
3176 | |||
3177 | ```moonscript | ||
3178 | switch 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> | ||
3189 | switch 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 | |||
3200 | Match against a list and capture a range of elements. | ||
3201 | |||
3202 | ```moonscript | ||
3203 | segments = ["admin", "users", "logs", "view"] | ||
3204 | switch 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> | ||
3212 | segments = ["admin", "users", "logs", "view"] | ||
3213 | switch 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 | |||
2787 | ## Object Oriented Programming | 3221 | ## Object Oriented Programming |
2788 | 3222 | ||
2789 | In 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. | 3223 | In 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. |
@@ -2915,7 +3349,7 @@ class BackPack extends Inventory | |||
2915 | 3349 | ||
2916 | Here we extend our Inventory class, and limit the amount of items it can carry. | 3350 | Here we extend our Inventory class, and limit the amount of items it can carry. |
2917 | 3351 | ||
2918 | In 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. | 3352 | In 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. |
2919 | 3353 | ||
2920 | Whenever 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. | 3354 | Whenever 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. |
2921 | 3355 | ||
@@ -3002,13 +3436,13 @@ print BackPack.size -- prints 10 | |||
3002 | 3436 | ||
3003 | The 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. | 3437 | The 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. |
3004 | 3438 | ||
3005 | The 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. | 3439 | The 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. |
3006 | 3440 | ||
3007 | A 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. | 3441 | A 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. |
3008 | 3442 | ||
3009 | The 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. | 3443 | The 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. |
3010 | 3444 | ||
3011 | It 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. | 3445 | It 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. |
3012 | 3446 | ||
3013 | The class object has a couple special properties: | 3447 | The class object has a couple special properties: |
3014 | 3448 | ||
@@ -3081,7 +3515,7 @@ print Counter.count -- prints 2 | |||
3081 | </pre> | 3515 | </pre> |
3082 | </YueDisplay> | 3516 | </YueDisplay> |
3083 | 3517 | ||
3084 | The calling semantics of @@ are similar to @. Calling a @@ name will pass the class in as the first argument using Lua’s colon syntax. | 3518 | The calling semantics of @@ are similar to @. Calling a @@ name will pass the class in as the first argument using Lua's colon syntax. |
3085 | 3519 | ||
3086 | ```moonscript | 3520 | ```moonscript |
3087 | @@hello 1,2,3,4 | 3521 | @@hello 1,2,3,4 |
@@ -3096,7 +3530,7 @@ The calling semantics of @@ are similar to @. Calling a @@ name will pass the cl | |||
3096 | 3530 | ||
3097 | In 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. | 3531 | In 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. |
3098 | 3532 | ||
3099 | Here is an alternative way to create a class variable compared to what’s described above: | 3533 | Here is an alternative way to create a class variable compared to what's described above: |
3100 | 3534 | ||
3101 | ```moonscript | 3535 | ```moonscript |
3102 | class Things | 3536 | class Things |
@@ -3362,19 +3796,19 @@ In this usage, with can be seen as a special form of the K combinator. | |||
3362 | The expression in the with statement can also be an assignment, if you want to give a name to the expression. | 3796 | The expression in the with statement can also be an assignment, if you want to give a name to the expression. |
3363 | 3797 | ||
3364 | ```moonscript | 3798 | ```moonscript |
3365 | with str = "Hello" | 3799 | with str := "Hello" |
3366 | print "original:", str | 3800 | print "original:", str |
3367 | print "upper:", \upper! | 3801 | print "upper:", \upper! |
3368 | ``` | 3802 | ``` |
3369 | <YueDisplay> | 3803 | <YueDisplay> |
3370 | <pre> | 3804 | <pre> |
3371 | with str = "Hello" | 3805 | with str := "Hello" |
3372 | print "original:", str | 3806 | print "original:", str |
3373 | print "upper:", \upper! | 3807 | print "upper:", \upper! |
3374 | </pre> | 3808 | </pre> |
3375 | </YueDisplay> | 3809 | </YueDisplay> |
3376 | 3810 | ||
3377 | Accessing special keys with `[]` in a `with` statement. | 3811 | You can access special keys with `[]` in a `with` statement. |
3378 | 3812 | ||
3379 | ```moonscript | 3813 | ```moonscript |
3380 | with tb | 3814 | with tb |
@@ -3397,6 +3831,18 @@ with tb | |||
3397 | </pre> | 3831 | </pre> |
3398 | </YueDisplay> | 3832 | </YueDisplay> |
3399 | 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 | ||
3837 | with? obj | ||
3838 | print obj.name | ||
3839 | ``` | ||
3840 | <YueDisplay> | ||
3841 | <pre> | ||
3842 | with? obj | ||
3843 | print obj.name | ||
3844 | </pre> | ||
3845 | </YueDisplay> | ||
3400 | 3846 | ||
3401 | ## Do | 3847 | ## Do |
3402 | 3848 | ||
@@ -3417,7 +3863,7 @@ print var -- nil here | |||
3417 | </pre> | 3863 | </pre> |
3418 | </YueDisplay> | 3864 | </YueDisplay> |
3419 | 3865 | ||
3420 | YueScript’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. | 3866 | YueScript'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. |
3421 | 3867 | ||
3422 | ```moonscript | 3868 | ```moonscript |
3423 | counter = do | 3869 | counter = do |
@@ -3543,7 +3989,7 @@ print i -- will print 0 | |||
3543 | </pre> | 3989 | </pre> |
3544 | </YueDisplay> | 3990 | </YueDisplay> |
3545 | 3991 | ||
3546 | In 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. | 3992 | In 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. |
3547 | 3993 | ||
3548 | It 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. | 3994 | It 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. |
3549 | 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 | -- 导入语法 |
19 | import "yue" as :p, :to_lua | 19 | import p, to_lua from "yue" |
20 | 20 | ||
21 | -- 隐式对象 | 21 | -- 隐式对象 |
22 | inventory = | 22 | inventory = |
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 | -- 列表推导 | ||
33 | map = (arr, action) -> | ||
34 | [action item for item in *arr] | ||
35 | |||
36 | filter = (arr, cond) -> | ||
37 | [item for item in *arr when cond item] | ||
38 | |||
39 | reduce = (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 | -- 导入语法 |
54 | import "yue" as :p, :to_lua | 64 | import p, to_lua from "yue" |
55 | 65 | ||
56 | -- 隐式对象 | 66 | -- 隐式对象 |
57 | inventory = | 67 | inventory = |
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 | -- 列表推导 | ||
78 | map = (arr, action) -> | ||
79 | [action item for item in *arr] | ||
80 | |||
81 | filter = (arr, cond) -> | ||
82 | [item for item in *arr when cond item] | ||
83 | |||
84 | reduce = (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 |  您可以下载预编译的二进制程序,包括兼容不同 Lua 版本的二进制可执行文件和库文件。 | 145 |  你可以下载预编译的二进制程序,包括兼容不同 Lua 版本的二进制可执行文件和库文件。 |
126 | 146 | ||
127 |  在[这里](https://github.com/IppClub/YueScript/releases)下载预编译的二进制程序。 | 147 |  在[这里](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 |
138 | require("yue")("你的脚本入口文件") | 158 | require("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 |
145 | local yue = require("yue") | 165 | local yue = require("yue") |
@@ -151,7 +171,7 @@ end, function(err) | |||
151 | end) | 171 | end) |
152 | ``` | 172 | ``` |
153 | 173 | ||
154 | * **用法 3** | 174 | * **用法 3** |
155 | 在Lua中使用月之脚本编译器功能。 | 175 | 在Lua中使用月之脚本编译器功能。 |
156 | ```lua | 176 | ```lua |
157 | local yue = require("yue") | 177 | local yue = require("yue") |
@@ -202,12 +222,12 @@ f! | |||
202 | 不添加任何选项执行命令可以进入REPL模式, | 222 | 不添加任何选项执行命令可以进入REPL模式, |
203 | 在单行输入符号 '$' 并换行后,可以开始或是停止多行输入模式 | 223 | 在单行输入符号 '$' 并换行后,可以开始或是停止多行输入模式 |
204 | ``` | 224 | ``` |
205 |   使用案例: | 225 |   使用案例: |
206 |   递归编译当前路径下扩展名为 **.yue** 的每个月之脚本文件: **yue .** | 226 |   递归编译当前路径下扩展名为 **.yue** 的每个月之脚本文件: **yue .** |
207 |   编译并将结果保存到目标路径: **yue -t /target/path/ .** | 227 |   编译并将结果保存到目标路径: **yue -t /target/path/ .** |
208 |   编译并保留调试信息: **yue -l .** | 228 |   编译并保留调试信息: **yue -l .** |
209 |   编译并生成压缩代码: **yue -m .** | 229 |   编译并生成压缩代码: **yue -m .** |
210 |   直接执行代码: **yue -e 'print 123'** | 230 |   直接执行代码: **yue -e 'print 123'** |
211 |   执行一个月之脚本文件: **yue -e main.yue** | 231 |   执行一个月之脚本文件: **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 |
339 | export macro map = (items, action) -> "[#{action} for _ in *#{items}]" | 359 | export 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 | ||
450 | macro printNumAndStr = (num `Num, str `String) -> | | ||
451 | print( | ||
452 | #{num} | ||
453 | #{str} | ||
454 | ) | ||
455 | |||
456 | $printNumAndStr 123, "hello" | ||
457 | ``` | ||
458 | <YueDisplay> | ||
459 | <pre> | ||
460 | macro 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 | ||
473 | macro 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> | ||
482 | macro 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 | ||
427 | Lua的所有二元和一元操作符在月之脚本中都是可用的。此外,**!=** 符号是 **~=** 的别名,而 **\\** 或 **::** 均可用于编写链式函数调用,如写作 `tb\func!` 或 `tb::func!`。此外月之脚本还提供了一些其他特殊的操作符,以编写更具表达力的代码。 | 495 | Lua的所有二元和一元操作符在月之脚本中都是可用的。此外,**!=** 符号是 **~=** 的别名,而 **\\** 或 **::** 均可用于编写链式函数调用,如写作 `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 |
445 | print 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5 | 513 | print 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 |
534 | parts = | 602 | parts = |
@@ -565,11 +633,26 @@ merge = {...a, ...b} | |||
565 | </pre> | 633 | </pre> |
566 | </YueDisplay> | 634 | </YueDisplay> |
567 | 635 | ||
636 | ### 表反向索引 | ||
637 | |||
638 | 你可以使用 **#** 操作符来反向索引表中的元素。 | ||
639 | |||
640 | ```moonscript | ||
641 | last = data.items[#] | ||
642 | second_last = data.items[#-1] | ||
643 | ``` | ||
644 | <YueDisplay> | ||
645 | <pre> | ||
646 | last = data.items[#] | ||
647 | second_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 _ = <close>: -> 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 | -- 赋值时使用隐式对象 | ||
736 | list = | 821 | list = |
737 | * 1 | 822 | * 1 |
738 | * 2 | 823 | * 2 |
739 | * 3 | 824 | * 3 |
740 | 825 | ||
826 | -- 函数调用时使用隐式对象 | ||
741 | func | 827 | func |
742 | * 1 | 828 | * 1 |
743 | * 2 | 829 | * 2 |
744 | * 3 | 830 | * 3 |
745 | 831 | ||
832 | -- 返回时使用隐式对象 | ||
833 | f = -> | ||
834 | return | ||
835 | * 1 | ||
836 | * 2 | ||
837 | * 3 | ||
838 | |||
839 | -- 表格时使用隐式对象 | ||
746 | tb = | 840 | tb = |
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 | -- 赋值时使用隐式对象 | ||
769 | list = | 863 | list = |
770 | * 1 | 864 | * 1 |
771 | * 2 | 865 | * 2 |
772 | * 3 | 866 | * 3 |
773 | 867 | ||
868 | -- 函数调用时使用隐式对象 | ||
774 | func | 869 | func |
775 | * 1 | 870 | * 1 |
776 | * 2 | 871 | * 2 |
777 | * 3 | 872 | * 3 |
778 | 873 | ||
874 | -- 返回时使用隐式对象 | ||
875 | f = -> | ||
876 | return | ||
877 | * 1 | ||
878 | * 2 | ||
879 | * 3 | ||
880 | |||
881 | -- 表格时使用隐式对象 | ||
779 | tb = | 882 | tb = |
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 | ||
1356 | orders = ["first", "second", "third", "fourth", "last"] | ||
1357 | [first, ...bulk, last] = orders | ||
1358 | print first -- 打印: first | ||
1359 | print bulk -- 打印: {"second", "third", "fourth"} | ||
1360 | print last -- 打印: last | ||
1361 | ``` | ||
1362 | <YueDisplay> | ||
1363 | <pre> | ||
1364 | orders = ["first", "second", "third", "fourth", "last"] | ||
1365 | [first, ...bulk, last] = orders | ||
1366 | print first -- 打印: first | ||
1367 | print bulk -- 打印: {"second", "third", "fourth"} | ||
1368 | print 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 |
1253 | tuples = [ | 1402 | tuples = [ |
@@ -1322,7 +1471,7 @@ print "好的" | |||
1322 | 1471 | ||
1323 | ### While 赋值 | 1472 | ### While 赋值 |
1324 | 1473 | ||
1325 | 您可以在 while 循环中同样使用赋值来获取循环条件的值。 | 1474 | 你可以在 while 循环中同样使用赋值来获取循环条件的值。 |
1326 | ```moonscript | 1475 | ```moonscript |
1327 | while byte := stream\read_one! | 1476 | while 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 |
1343 | list = [1, 2, 3, 4, 5] | 1492 | list = [1, 2, 3, 4, 5] |
1344 | fn = (ok) -> ok, table.unpack list | 1493 | fn = (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 | ||
1631 | a, b, c = try? func! | ||
1632 | |||
1633 | -- 与空值合并运算符一起使用 | ||
1634 | a = (try? func!) ?? "default" | ||
1635 | |||
1636 | -- 作为函数参数 | ||
1637 | f try? func! | ||
1638 | |||
1639 | -- 带 catch 块的 try! | ||
1640 | f try? | ||
1641 | print 123 | ||
1642 | func! | ||
1643 | catch e | ||
1644 | print e | ||
1645 | e | ||
1646 | ``` | ||
1647 | <YueDisplay> | ||
1648 | <pre> | ||
1649 | a, b, c = try? func! | ||
1650 | |||
1651 | -- 与空值合并运算符一起使用 | ||
1652 | a = (try? func!) ?? "default" | ||
1653 | |||
1654 | -- 作为函数参数 | ||
1655 | f try? func! | ||
1656 | |||
1657 | -- 带 catch 块的 try! | ||
1658 | f try? | ||
1659 | print 123 | ||
1660 | func! | ||
1661 | catch 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 | ||
1698 | global const Constant = 123 | ||
1699 | -- Constant = 1 | ||
1700 | ``` | ||
1701 | <YueDisplay> | ||
1702 | <pre> | ||
1703 | global const Constant = 123 | ||
1704 | -- Constant = 1 | ||
1705 | </pre> | ||
1706 | </YueDisplay> | ||
1707 | |||
1505 | ## 字面量 | 1708 | ## 字面量 |
1506 | 1709 | ||
1507 | Lua中的所有基本字面量都可以在月之脚本中使用。包括数字、字符串、布尔值和**nil**。 | 1710 | Lua中的所有基本字面量都可以在月之脚本中使用。包括数字、字符串、布尔值和**nil**。 |
@@ -1529,17 +1732,78 @@ print "我有#{math.random! * 100}%的把握。" | |||
1529 | 1732 | ||
1530 | ### 数字字面量 | 1733 | ### 数字字面量 |
1531 | 1734 | ||
1532 | 您可以在数字字面量中使用下划线来增加可读性。 | 1735 | 你可以在数字字面量中使用下划线来增加可读性。 |
1533 | 1736 | ||
1534 | ```moonscript | 1737 | ```moonscript |
1535 | integer = 1_000_000 | 1738 | integer = 1_000_000 |
1536 | hex = 0xEF_BB_BF | 1739 | hex = 0xEF_BB_BF |
1740 | binary = 0B10011 | ||
1537 | ``` | 1741 | ``` |
1538 | <YueDisplay> | 1742 | <YueDisplay> |
1539 | 1743 | ||
1540 | <pre> | 1744 | <pre> |
1541 | integer = 1_000_000 | 1745 | integer = 1_000_000 |
1542 | hex = 0xEF_BB_BF | 1746 | hex = 0xEF_BB_BF |
1747 | binary = 0B10011 | ||
1748 | </pre> | ||
1749 | </YueDisplay> | ||
1750 | |||
1751 | ### YAML 风格字符串 | ||
1752 | |||
1753 | 使用 `|` 前缀标记一个多行 YAML 风格字符串: | ||
1754 | |||
1755 | ```moonscript | ||
1756 | str = | | ||
1757 | key: value | ||
1758 | list: | ||
1759 | - item1 | ||
1760 | - #{expr} | ||
1761 | ``` | ||
1762 | <YueDisplay> | ||
1763 | <pre> | ||
1764 | str = | | ||
1765 | key: value | ||
1766 | list: | ||
1767 | - item1 | ||
1768 | - #{expr} | ||
1769 | </pre> | ||
1770 | </YueDisplay> | ||
1771 | |||
1772 | 其效果类似于原生 Lua 的多行拼接,所有文本(含换行)将被保留下来,并支持 `#{...}` 语法,通过 `tostring(expr)` 插入表达式结果。 | ||
1773 | |||
1774 | YAML 风格的多行字符串会自动检测首行后最小的公共缩进,并从所有行中删除该前缀空白字符。这让你可以在代码中对齐文本,但输出字符串不会带多余缩进。 | ||
1775 | |||
1776 | ```moonscript | ||
1777 | fn = -> | ||
1778 | str = | | ||
1779 | foo: | ||
1780 | bar: baz | ||
1781 | return str | ||
1782 | ``` | ||
1783 | <YueDisplay> | ||
1784 | <pre> | ||
1785 | fn = -> | ||
1786 | str = | | ||
1787 | foo: | ||
1788 | bar: baz | ||
1789 | return str | ||
1790 | </pre> | ||
1791 | </YueDisplay> | ||
1792 | |||
1793 | 输出字符串中的 foo: 对齐到行首,不会带有函数缩进空格。保留内部缩进的相对结构,适合书写结构化嵌套样式的内容。 | ||
1794 | |||
1795 | 支持自动处理字符中的引号、反斜杠等特殊符号,无需手动转义: | ||
1796 | |||
1797 | ```moonscript | ||
1798 | str = | | ||
1799 | path: "C:\Program Files\App" | ||
1800 | note: 'He said: "#{Hello}!"' | ||
1801 | ``` | ||
1802 | <YueDisplay> | ||
1803 | <pre> | ||
1804 | str = | | ||
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 |
1650 | sum = (x, y) -> return x + y | 1914 | sum = (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 |
1869 | result, msg = do | 2133 | result, 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 |
1874 | print result, msg | 2138 | print result, msg |
1875 | ``` | 2139 | ``` |
1876 | <YueDisplay> | 2140 | <YueDisplay> |
1877 | <pre> | 2141 | <pre> |
1878 | result, msg = do | 2142 | result, 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 |
1883 | print result, msg | 2147 | print 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 |
2060 | iter = ipairs items | 2324 | slice = [item for i, item in ipairs items when i > 1 and i < 3] |
2061 | slice = [item for i, item in iter when i > 1 and i < 3] | ||
2062 | ``` | 2325 | ``` |
2063 | <YueDisplay> | 2326 | <YueDisplay> |
2064 | <pre> | 2327 | <pre> |
2065 | iter = ipairs items | 2328 | slice = [item for i, item in ipairs items when i > 1 and i < 3] |
2066 | slice = [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个元素 | ||
2481 | slice = [item for item in *items[-4,-1]] | ||
2482 | ``` | ||
2483 | <YueDisplay> | ||
2484 | <pre> | ||
2485 | -- 取最后4个元素 | ||
2486 | slice = [item for item in *items[-4,-1]] | ||
2487 | </pre> | ||
2488 | </YueDisplay> | ||
2489 | |||
2490 | 切片的步长也可以是负数,这意味着元素会以相反的顺序被取出。 | ||
2491 | |||
2492 | ```moonscript | ||
2493 | reverse_slice = [item for item in *items[-1,1,-1]] | ||
2494 | ``` | ||
2495 | <YueDisplay> | ||
2496 | <pre> | ||
2497 | reverse_slice = [item for item in *items[-1,1,-1]] | ||
2498 | </pre> | ||
2499 | </YueDisplay> | ||
2500 | |||
2501 | #### 切片表达式 | ||
2502 | |||
2503 | 切片也可以作为表达式来使用。可以用于获取一个表包含的子列表。 | ||
2504 | |||
2505 | ```moonscript | ||
2506 | -- 取第2和第4个元素作为新的列表 | ||
2507 | sub_list = items[2, 4] | ||
2508 | ``` | ||
2509 | <YueDisplay> | ||
2510 | <pre> | ||
2511 | -- 取第2和第4个元素作为新的列表 | ||
2512 | sub_list = items[2, 4] | ||
2513 | </pre> | ||
2514 | </YueDisplay> | ||
2515 | |||
2215 | ## for 循环 | 2516 | ## for 循环 |
2216 | 2517 | ||
2217 | Lua中有两种for循环形式,数字型和通用型: | 2518 | Lua中有两种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 | ||
2597 | first_large = for n in *numbers | ||
2598 | break n if n > 10 | ||
2599 | ``` | ||
2600 | <YueDisplay> | ||
2601 | <pre> | ||
2602 | first_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 |
2296 | func_a = -> for i = 1, 10 do print i | 2612 | func_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 |
2521 | a = 5 | 2837 | a = 5 |
@@ -2588,28 +2904,26 @@ reader\parse_line! until reader\eof! | |||
2588 | 2904 | ||
2589 | ## switch 语句 | 2905 | ## switch 语句 |
2590 | 2906 | ||
2591 | switch语句是为了简化检查一系列相同值的if语句而提供的简写语法。要注意用于比较检查的目标值只会计算一次。和if语句一样,switch语句在最后可以接一个else代码块来处理没有匹配的情况。在生成的Lua代码中,进行比较是使用==操作符完成的。 | 2907 | switch语句是为了简化检查一系列相同值的if语句而提供的简写语法。要注意用于比较检查的目标值只会计算一次。和if语句一样,switch语句在最后可以接一个else代码块来处理没有匹配的情况。在生成的Lua代码中,进行比较是使用==操作符完成的。switch语句中也可以使用赋值表达式来储存临时变量值。 |
2592 | 2908 | ||
2593 | ```moonscript | 2909 | ```moonscript |
2594 | name = "Dan" | 2910 | switch name := "Dan" |
2595 | switch 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> |
2605 | name = "Dan" | 2920 | switch name := "Dan" |
2606 | switch 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 | ||
3068 | switch 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> | ||
3078 | switch 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 | ||
3091 | switch 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> | ||
3101 | switch 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 | ||
3114 | switch 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> | ||
3124 | switch 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 | ||
3137 | switch 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> | ||
3148 | switch 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 | ||
3162 | segments = ["admin", "users", "logs", "view"] | ||
3163 | switch 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> | ||
3171 | segments = ["admin", "users", "logs", "view"] | ||
3172 | switch 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 |
3222 | MyIndex = __index: var: 1 | 3653 | MyIndex = __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 |
3324 | with str = "你好" | 3755 | with str := "你好" |
3325 | print "原始:", str | 3756 | print "原始:", str |
3326 | print "大写:", \upper! | 3757 | print "大写:", \upper! |
3327 | ``` | 3758 | ``` |
3328 | <YueDisplay> | 3759 | <YueDisplay> |
3329 | <pre> | 3760 | <pre> |
3330 | with str = "你好" | 3761 | with 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 |
3339 | with tb | 3770 | with tb |
@@ -3356,6 +3787,19 @@ with tb | |||
3356 | </pre> | 3787 | </pre> |
3357 | </YueDisplay> | 3788 | </YueDisplay> |
3358 | 3789 | ||
3790 | `with?` 是 `with` 语法的一个增强版本,引入了存在性检查,用于在不显式判空的情况下安全访问可能为 nil 的对象。 | ||
3791 | |||
3792 | ```moonscript | ||
3793 | with? obj | ||
3794 | print obj.name | ||
3795 | ``` | ||
3796 | <YueDisplay> | ||
3797 | <pre> | ||
3798 | with? 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 |
3381 | counter = do | 3825 | counter = 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 /> |