aboutsummaryrefslogtreecommitdiff
path: root/doc/docs/doc/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/docs/doc/README.md')
-rwxr-xr-xdoc/docs/doc/README.md574
1 files changed, 511 insertions, 63 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