aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rwxr-xr-xdoc/.gitignore4
-rw-r--r--doc/docs/.vitepress/config.mts53
-rw-r--r--doc/docs/.vitepress/env.d.ts19
-rw-r--r--doc/docs/.vitepress/grammars/moonscript.tmLanguage263
-rw-r--r--doc/docs/.vitepress/grammars/moonscript.tmLanguage.json149
-rw-r--r--doc/docs/.vitepress/public/favicon.icobin0 -> 15406 bytes
-rw-r--r--doc/docs/.vitepress/public/image/yuescript.svg54
-rwxr-xr-xdoc/docs/.vitepress/theme/components/CompilerModal.vue20
-rwxr-xr-xdoc/docs/.vitepress/theme/components/YueCompiler.vue342
-rwxr-xr-xdoc/docs/.vitepress/theme/components/YueDisplay.vue4
-rw-r--r--doc/docs/.vitepress/theme/custom.css92
-rw-r--r--doc/docs/.vitepress/theme/index.ts10
-rwxr-xr-xdoc/docs/README.md14
-rwxr-xr-xdoc/docs/doc/index.md (renamed from doc/docs/doc/README.md)1514
-rw-r--r--doc/docs/index.md25
-rwxr-xr-xdoc/docs/try/index.md (renamed from doc/docs/try/README.md)0
-rwxr-xr-xdoc/docs/zh/README.md14
-rwxr-xr-xdoc/docs/zh/doc/index.md (renamed from doc/docs/zh/doc/README.md)1514
-rw-r--r--doc/docs/zh/index.md25
-rwxr-xr-xdoc/docs/zh/try/index.md (renamed from doc/docs/zh/try/README.md)0
-rwxr-xr-xdoc/package.json6
-rw-r--r--doc/tsconfig.json18
22 files changed, 2850 insertions, 1290 deletions
diff --git a/doc/.gitignore b/doc/.gitignore
index 0cef669..dea1a07 100755
--- a/doc/.gitignore
+++ b/doc/.gitignore
@@ -11,5 +11,5 @@ dist
11config.local.js 11config.local.js
12basement_dist 12basement_dist
13yarn.lock 13yarn.lock
14docs/.vuepress/public/js/yuescript.js 14docs/.vitepress/public/js/yuescript.js
15docs/.vuepress/public/js/yuescript.wasm 15docs/.vitepress/public/js/yuescript.wasm
diff --git a/doc/docs/.vitepress/config.mts b/doc/docs/.vitepress/config.mts
index 7f7416d..da3876d 100644
--- a/doc/docs/.vitepress/config.mts
+++ b/doc/docs/.vitepress/config.mts
@@ -1,10 +1,26 @@
1import { defineConfig } from 'vitepress' 1import { defineConfig } from 'vitepress'
2import { resolve, dirname } from 'path'
3import { readFileSync } from 'fs'
4import { fileURLToPath } from 'url'
5import lightPlus from '@shikijs/themes/light-plus'
6import darkPlus from '@shikijs/themes/dark-plus'
7
8const __dirname = dirname(fileURLToPath(import.meta.url))
9const moonscriptGrammarPath = resolve(__dirname, 'grammars/moonscript.tmLanguage.json')
10const moonscriptGrammar = JSON.parse(readFileSync(moonscriptGrammarPath, 'utf-8'))
11const moonscriptLanguage = {
12 ...moonscriptGrammar,
13 name: 'moonscript',
14 scopeName: 'source.moonscript',
15 aliases: ['yue', 'yuescript', 'moon'],
16}
2 17
3export default defineConfig({ 18export default defineConfig({
4 title: 'YueScript', 19 title: 'YueScript',
5 description: 'A language that compiles to Lua', 20 description: 'A language that compiles to Lua',
21 base: '/',
6 head: [ 22 head: [
7 ['meta', { name: 'theme-color', content: '#3eaf7c' }], 23 ['meta', { name: 'theme-color', content: '#b4ac8f' }],
8 ['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }], 24 ['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }],
9 ['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'black' }], 25 ['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'black' }],
10 ['meta', { property: 'og:title', content: 'YueScript' }], 26 ['meta', { property: 'og:title', content: 'YueScript' }],
@@ -29,10 +45,35 @@ export default defineConfig({
29 window.yue = Module; 45 window.yue = Module;
30 window.dispatchEvent(new Event('yue:ready')); 46 window.dispatchEvent(new Event('yue:ready'));
31 } 47 }
32};` 48};
33 ], 49(function() {
34 ['script', { src: '/js/yuescript.js' }] 50 function loadStub() {
51 window.yue = {
52 version: function() { return '(build with: make wasm)'; },
53 tolua: function() { return ['', 'Build yuescript wasm with: make wasm']; },
54 exec: function() { return ''; }
55 };
56 window.dispatchEvent(new Event('yue:ready'));
57 }
58 var s = document.createElement('script');
59 s.src = '/js/yuescript.js';
60 s.async = true;
61 document.head.appendChild(s);
62})();`
63 ]
35 ], 64 ],
65 vite: {
66 publicDir: resolve(__dirname, 'public'),
67 },
68 markdown: {
69 languages: [
70 moonscriptLanguage,
71 ],
72 theme: {
73 light: lightPlus,
74 dark: darkPlus,
75 },
76 },
36 locales: { 77 locales: {
37 root: { 78 root: {
38 label: 'English', 79 label: 'English',
@@ -42,7 +83,7 @@ export default defineConfig({
42 nav: [ 83 nav: [
43 { text: 'Document', link: '/doc/' }, 84 { text: 'Document', link: '/doc/' },
44 { text: 'Try yue!', link: '/try/' }, 85 { text: 'Try yue!', link: '/try/' },
45 { text: 'Github', link: 'https://github.com/pigpigyyy/Yuescript' } 86 { text: 'Github', link: 'https://github.com/IppClub/Yuescript' }
46 ] 87 ]
47 } 88 }
48 }, 89 },
@@ -54,7 +95,7 @@ export default defineConfig({
54 nav: [ 95 nav: [
55 { text: '文档', link: '/zh/doc/' }, 96 { text: '文档', link: '/zh/doc/' },
56 { text: '试一试!', link: '/zh/try/' }, 97 { text: '试一试!', link: '/zh/try/' },
57 { text: 'Github', link: 'https://github.com/pigpigyyy/Yuescript' } 98 { text: 'Github', link: 'https://github.com/IppClub/Yuescript' }
58 ] 99 ]
59 } 100 }
60 } 101 }
diff --git a/doc/docs/.vitepress/env.d.ts b/doc/docs/.vitepress/env.d.ts
new file mode 100644
index 0000000..0f28852
--- /dev/null
+++ b/doc/docs/.vitepress/env.d.ts
@@ -0,0 +1,19 @@
1/// <reference types="vitepress/client" />
2
3declare module '*.vue' {
4 import type { DefineComponent } from 'vue'
5 const component: DefineComponent<{}, {}, any>
6 export default component
7}
8
9declare global {
10 interface Window {
11 yue?: {
12 version: () => string
13 tolua: (code: string, ...args: unknown[]) => [string, string]
14 exec: (code: string) => string
15 }
16 }
17}
18
19export {}
diff --git a/doc/docs/.vitepress/grammars/moonscript.tmLanguage b/doc/docs/.vitepress/grammars/moonscript.tmLanguage
new file mode 100644
index 0000000..2c041ba
--- /dev/null
+++ b/doc/docs/.vitepress/grammars/moonscript.tmLanguage
@@ -0,0 +1,263 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3<plist version="1.0">
4<dict>
5 <!--
6 Some parts extratec from Lua.tmLanguage
7 -->
8 <key>comment</key>
9 <string>MoonScript Syntax: 0.0.1</string>
10 <key>fileTypes</key>
11 <array>
12 <string>moon</string>
13 </array>
14
15 <key>name</key>
16 <string>MoonScript</string>
17
18 <key>patterns</key>
19 <array>
20 <dict>
21 <key>captures</key>
22 <dict>
23 <key>1</key>
24 <dict>
25 <key>name</key>
26 <string>punctuation.definition.comment.lua</string>
27 </dict>
28 </dict>
29 <key>match</key>
30 <string>(--)(?!\[\[).*$\n?</string>
31 <key>name</key>
32 <string>comment.line.double-dash.lua</string>
33 </dict>
34
35
36 <dict>
37 <key>begin</key>
38 <string>'</string>
39 <key>beginCaptures</key>
40 <dict>
41 <key>0</key>
42 <dict>
43 <key>name</key>
44 <string>punctuation.definition.string.begin.lua</string>
45 </dict>
46 </dict>
47 <key>end</key>
48 <string>'</string>
49 <key>endCaptures</key>
50 <dict>
51 <key>0</key>
52 <dict>
53 <key>name</key>
54 <string>punctuation.definition.string.end.lua</string>
55 </dict>
56 </dict>
57 <key>name</key>
58 <string>string.quoted.single.lua</string>
59 <key>patterns</key>
60 <array>
61 <dict>
62 <key>match</key>
63 <string>\\(\d{1,3}|.)</string>
64 <key>name</key>
65 <string>constant.character.escape.lua</string>
66 </dict>
67 </array>
68 </dict>
69
70 <dict>
71 <key>begin</key>
72 <string>"</string>
73 <key>beginCaptures</key>
74 <dict>
75 <key>0</key>
76 <dict>
77 <key>name</key>
78 <string>punctuation.definition.string.begin.lua</string>
79 </dict>
80 </dict>
81 <key>end</key>
82 <string>"</string>
83 <key>endCaptures</key>
84 <dict>
85 <key>0</key>
86 <dict>
87 <key>name</key>
88 <string>punctuation.definition.string.end.lua</string>
89 </dict>
90 </dict>
91 <key>name</key>
92 <string>string.quoted.double.lua</string>
93 <key>patterns</key>
94 <array>
95 <dict>
96 <key>match</key>
97 <string>\\(\d{1,3}|.)</string>
98 <key>name</key>
99 <string>constant.character.escape.lua</string>
100 </dict>
101 </array>
102 </dict>
103
104 <dict>
105 <key>begin</key>
106 <string>(?&lt;!--)\[(=*)\[</string>
107 <key>beginCaptures</key>
108 <dict>
109 <key>0</key>
110 <dict>
111 <key>name</key>
112 <string>punctuation.definition.string.begin.lua</string>
113 </dict>
114 </dict>
115 <key>end</key>
116 <string>\]\1\]</string>
117 <key>endCaptures</key>
118 <dict>
119 <key>0</key>
120 <dict>
121 <key>name</key>
122 <string>punctuation.definition.string.end.lua</string>
123 </dict>
124 </dict>
125 <key>name</key>
126 <string>string.quoted.other.multiline.lua</string>
127 </dict>
128
129 <dict>
130 <key>match</key>
131 <string>(?&lt;![\d.])\s0x[a-fA-F\d]+|\b\d+(\.\d+)?([eE]-?\d+)?|\.\d+([eE]-?\d+)?</string>
132 <key>name</key>
133 <string>constant.numeric.lua</string>
134 </dict>
135
136 <dict>
137 <key>name</key>
138 <string>support.constant</string>
139 <key>match</key>
140 <string>\b[A-Z]\w*\b(?!:)</string>
141 </dict>
142
143 <dict>
144 <key>name</key>
145 <string>keyword.operator</string>
146 <key>match</key>
147 <string>=&gt;|-&gt;</string>
148 </dict>
149
150 <dict>
151 <key>match</key>
152 <string>\b(and|or|not)\b</string>
153 <key>name</key>
154 <string>keyword.operator.lua</string>
155 </dict>
156
157 <dict>
158 <key>match</key>
159 <string>[a-zA-Z_]\w*\s*(?=:)</string>
160 <key>name</key>
161 <string>entity.name.function</string>
162 </dict>
163
164 <dict>
165 <key>match</key>
166 <string>\(|\)</string>
167 <key>name</key>
168 <string>entity.name.function</string>
169 </dict>
170
171 <dict>
172 <key>match</key>
173 <string>\+|-|%|#|\*|\/|\^|==?|~=|!=|\\|:|,|;|\.|&lt;=?|&gt;=?|(?&lt;!\.)\.{2}(?!\.)</string>
174 <key>name</key>
175 <string>keyword.operator.lua</string>
176 </dict>
177
178 <dict>
179 <key>match</key>
180 <string>{|}|\[|\]</string>
181 <key>name</key>
182 <string>storage.modifier</string>
183 </dict>
184
185 <dict>
186 <key>name</key>
187 <string>storage.type.class</string>
188 <key>match</key>
189 <string>\b(class|extends|super)\b</string>
190 </dict>
191
192 <dict>
193 <key>name</key>
194 <string>keyword.control</string>
195 <key>match</key>
196 <string>\b(if|then|else|elseif|export|import|from|switch|when|with|using|do|for|in|while|return|local|unless|continue|break)\b</string>
197 </dict>
198
199 <dict>
200 <key>name</key>
201 <string>variable.language</string>
202 <key>match</key>
203 <string>\b(self)\b</string>
204 </dict>
205
206 <dict>
207 <key>name</key>
208 <string>variable.parameter</string>
209 <key>match</key>
210 <string>@@?[a-zA-Z_]\w*\b</string>
211 </dict>
212
213 <dict>
214 <key>name</key>
215 <string>constant.language.nil</string>
216 <key>match</key>
217 <string>\b(nil)\b</string>
218 </dict>
219
220
221 <dict>
222 <key>match</key>
223 <string>\b(true|false)\b</string>
224 <key>name</key>
225 <string>constant.language.boolean</string>
226 </dict>
227
228 <dict>
229 <key>match</key>
230 <string>(?&lt;!\.|\\)\b(function|repeat|end)\b(?!\s*:)</string>
231 <key>name</key>
232 <string>invalid.illegal</string>
233 </dict>
234
235 <dict>
236 <key>match</key>
237 <string>(?&lt;![^.]\.|\\)\b(assert|collectgarbage|dofile|error|getfenv|getmetatable|ipairs|loadfile|loadstring|module|next|pairs|pcall|print|rawequal|rawget|rawset|require|select|setfenv|setmetatable|tonumber|tostring|type|unpack|xpcall)\b</string>
238 <key>name</key>
239 <string>support.function.lua</string>
240 </dict>
241
242 <dict>
243 <key>match</key>
244 <string>(?&lt;![^.]\.|\\)\b(_G)\b</string>
245 <key>name</key>
246 <string>support.constant</string>
247 </dict>
248
249 <dict>
250 <key>match</key>
251 <string>(?&lt;![^.]\.|\\)\b(coroutine\.(create|resume|running|status|wrap|yield)|string\.(byte|char|dump|find|format|gmatch|gsub|len|lower|match|rep|reverse|sub|upper)|table\.(concat|insert|maxn|remove|sort)|math\.(abs|acos|asin|atan2?|ceil|cosh?|deg|exp|floor|fmod|frexp|ldexp|log|log10|max|min|modf|pow|rad|random|randomseed|sinh?|sqrt|tanh?)|io\.(close|flush|input|lines|open|output|popen|read|tmpfile|type|write)|os\.(clock|date|difftime|execute|exit|getenv|remove|rename|setlocale|time|tmpname)|package\.(cpath|loaded|loadlib|path|preload|seeall)|debug\.(debug|[gs]etfenv|[gs]ethook|getinfo|[gs]etlocal|[gs]etmetatable|getregistry|[gs]etupvalue|traceback))\b</string>
252 <key>name</key>
253 <string>support.function.library.lua</string>
254 </dict>
255
256 </array>
257
258 <key>scopeName</key>
259 <string>source.moonscript</string>
260 <key>uuid</key>
261 <string>D363822C-639B-4450-A21A-F45643A6940F</string>
262</dict>
263</plist>
diff --git a/doc/docs/.vitepress/grammars/moonscript.tmLanguage.json b/doc/docs/.vitepress/grammars/moonscript.tmLanguage.json
new file mode 100644
index 0000000..98a3dc9
--- /dev/null
+++ b/doc/docs/.vitepress/grammars/moonscript.tmLanguage.json
@@ -0,0 +1,149 @@
1{
2 "comment": "MoonScript Syntax: 0.0.1",
3 "fileTypes": [
4 "moon"
5 ],
6 "name": "MoonScript",
7 "patterns": [
8 {
9 "captures": {
10 "1": {
11 "name": "punctuation.definition.comment.lua"
12 }
13 },
14 "match": "(--)(?!\\[\\[).*$\\n?",
15 "name": "comment.line.double-dash.lua"
16 },
17 {
18 "begin": "'",
19 "beginCaptures": {
20 "0": {
21 "name": "punctuation.definition.string.begin.lua"
22 }
23 },
24 "end": "'",
25 "endCaptures": {
26 "0": {
27 "name": "punctuation.definition.string.end.lua"
28 }
29 },
30 "name": "string.quoted.single.lua",
31 "patterns": [
32 {
33 "match": "\\\\(\\d{1,3}|.)",
34 "name": "constant.character.escape.lua"
35 }
36 ]
37 },
38 {
39 "begin": "\"",
40 "beginCaptures": {
41 "0": {
42 "name": "punctuation.definition.string.begin.lua"
43 }
44 },
45 "end": "\"",
46 "endCaptures": {
47 "0": {
48 "name": "punctuation.definition.string.end.lua"
49 }
50 },
51 "name": "string.quoted.double.lua",
52 "patterns": [
53 {
54 "match": "\\\\(\\d{1,3}|.)",
55 "name": "constant.character.escape.lua"
56 }
57 ]
58 },
59 {
60 "begin": "(?<!--)\\[(=*)\\[",
61 "beginCaptures": {
62 "0": {
63 "name": "punctuation.definition.string.begin.lua"
64 }
65 },
66 "end": "\\]\\1\\]",
67 "endCaptures": {
68 "0": {
69 "name": "punctuation.definition.string.end.lua"
70 }
71 },
72 "name": "string.quoted.other.multiline.lua"
73 },
74 {
75 "match": "(?<![\\d.])\\s0x[a-fA-F\\d]+|\\b\\d+(\\.\\d+)?([eE]-?\\d+)?|\\.\\d+([eE]-?\\d+)?",
76 "name": "constant.numeric.lua"
77 },
78 {
79 "name": "support.constant",
80 "match": "\\b[A-Z]\\w*\\b(?!:)"
81 },
82 {
83 "name": "keyword.operator",
84 "match": "=>|->"
85 },
86 {
87 "match": "\\b(and|or|not)\\b",
88 "name": "keyword.operator.lua"
89 },
90 {
91 "match": "[a-zA-Z_]\\w*\\s*(?=:)",
92 "name": "entity.name.function"
93 },
94 {
95 "match": "\\(|\\)",
96 "name": "entity.name.function"
97 },
98 {
99 "match": "\\+|-|%|#|\\*|\\/|\\^|==?|~=|!=|\\\\|:|,|;|\\.|<=?|>=?|(?<!\\.)\\.{2}(?!\\.)",
100 "name": "keyword.operator.lua"
101 },
102 {
103 "match": "{|}|\\[|\\]",
104 "name": "storage.modifier"
105 },
106 {
107 "name": "storage.type.class",
108 "match": "\\b(class|extends|super)\\b"
109 },
110 {
111 "name": "keyword.control",
112 "match": "\\b(if|then|else|elseif|export|import|from|switch|when|with|using|do|for|in|while|return|local|unless|continue|break)\\b"
113 },
114 {
115 "name": "variable.language",
116 "match": "\\b(self)\\b"
117 },
118 {
119 "name": "variable.parameter",
120 "match": "@@?[a-zA-Z_]\\w*\\b"
121 },
122 {
123 "name": "constant.language.nil",
124 "match": "\\b(nil)\\b"
125 },
126 {
127 "match": "\\b(true|false)\\b",
128 "name": "constant.language.boolean"
129 },
130 {
131 "match": "(?<!\\.|\\\\)\\b(function|repeat|end)\\b(?!\\s*:)",
132 "name": "invalid.illegal"
133 },
134 {
135 "match": "(?<![^.]\\.|\\\\)\\b(assert|collectgarbage|dofile|error|getfenv|getmetatable|ipairs|loadfile|loadstring|module|next|pairs|pcall|print|rawequal|rawget|rawset|require|select|setfenv|setmetatable|tonumber|tostring|type|unpack|xpcall)\\b",
136 "name": "support.function.lua"
137 },
138 {
139 "match": "(?<![^.]\\.|\\\\)\\b(_G)\\b",
140 "name": "support.constant"
141 },
142 {
143 "match": "(?<![^.]\\.|\\\\)\\b(coroutine\\.(create|resume|running|status|wrap|yield)|string\\.(byte|char|dump|find|format|gmatch|gsub|len|lower|match|rep|reverse|sub|upper)|table\\.(concat|insert|maxn|remove|sort)|math\\.(abs|acos|asin|atan2?|ceil|cosh?|deg|exp|floor|fmod|frexp|ldexp|log|log10|max|min|modf|pow|rad|random|randomseed|sinh?|sqrt|tanh?)|io\\.(close|flush|input|lines|open|output|popen|read|tmpfile|type|write)|os\\.(clock|date|difftime|execute|exit|getenv|remove|rename|setlocale|time|tmpname)|package\\.(cpath|loaded|loadlib|path|preload|seeall)|debug\\.(debug|[gs]etfenv|[gs]ethook|getinfo|[gs]etlocal|[gs]etmetatable|getregistry|[gs]etupvalue|traceback))\\b",
144 "name": "support.function.library.lua"
145 }
146 ],
147 "scopeName": "source.moonscript",
148 "uuid": "D363822C-639B-4450-A21A-F45643A6940F"
149} \ No newline at end of file
diff --git a/doc/docs/.vitepress/public/favicon.ico b/doc/docs/.vitepress/public/favicon.ico
new file mode 100644
index 0000000..2c1360d
--- /dev/null
+++ b/doc/docs/.vitepress/public/favicon.ico
Binary files differ
diff --git a/doc/docs/.vitepress/public/image/yuescript.svg b/doc/docs/.vitepress/public/image/yuescript.svg
index 87fdb45..71214fe 100644
--- a/doc/docs/.vitepress/public/image/yuescript.svg
+++ b/doc/docs/.vitepress/public/image/yuescript.svg
@@ -1,53 +1 @@
1<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 284 244" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><g><path d="M88.8,198.15c-2.775,0.6 -6.075,1.2 -8.775,1.725c0.375,-1.5 1.425,-5.85 2.175,-8.625l-2.1,-2.175l-2.475,10.875c-0,0.15 -0.075,0.3 -0.225,0.45l-4.5,4.275l1.8,1.95l4.575,-4.35c0.15,-0.15 0.225,-0.225 0.375,-0.225l11.025,-1.875l-1.875,-2.025Z" style="fill:#b4ac8f;fill-rule:nonzero;"/><path d="M100.5,220.05c-1.425,2.025 -3.15,2.925 -5.85,1.125c-2.7,-1.875 -2.55,-3.9 -1.2,-5.85l5.775,-8.4l-2.175,-1.5l-5.85,8.55c-2.1,3 -1.725,5.925 2.4,8.775c4.425,3 7.275,1.8 9.15,-0.975l5.775,-8.475l-2.25,-1.5l-5.775,8.25Z" style="fill:#b4ac8f;fill-rule:nonzero;"/><path d="M112.275,233.1l10.8,4.275l1.05,-1.575l-8.7,-3.525l2.025,-5.1l7.95,3.15l0.675,-1.8l-7.875,-3.15l1.8,-4.425l8.25,3.3l0.675,-1.725l-10.65,-4.275l-6,14.85Z" style="fill:#b4ac8f;fill-rule:nonzero;"/><path d="M144.15,225.975c-3.525,-0.6 -6.15,0.6 -6.6,3.15c-0.375,2.25 0.9,3.675 4.725,5.4c3,1.35 3.9,2.25 3.6,3.975c-0.3,1.65 -1.8,2.325 -4.05,1.95c-2.175,-0.375 -3.525,-1.65 -3.6,-3.6l-2.625,-0.45c-0.225,2.925 1.8,5.1 5.7,5.85c4.275,0.75 6.75,-0.825 7.2,-3.45c0.375,-2.175 -0.525,-3.9 -4.95,-5.925c-2.775,-1.275 -3.675,-1.95 -3.45,-3.375c0.225,-1.35 1.425,-2.025 3.525,-1.65c2.25,0.375 3.075,1.575 3.075,3.15l2.55,0.45c0.45,-2.475 -0.975,-4.725 -5.1,-5.475Z" style="fill:#b4ac8f;fill-rule:nonzero;"/><path d="M167.925,242.1c-3.9,0.15 -5.25,-3 -5.325,-6.3c-0.15,-3.3 1.2,-6.3 4.8,-6.45c2.775,-0.075 3.9,1.2 4.425,2.925l2.625,-0.075c-0.45,-2.625 -2.55,-4.875 -7.05,-4.725c-5.4,0.225 -7.725,4.125 -7.575,8.4c0.15,4.725 2.4,8.25 8.1,8.025c4.575,-0.15 6.45,-2.625 6.9,-5.25l-2.625,0.075c-0.45,1.8 -1.5,3.3 -4.275,3.375Z" style="fill:#b4ac8f;fill-rule:nonzero;"/><path d="M198.975,234.3c-0.525,-2.1 -1.65,-3.15 -3.675,-3.15c1.35,-0.825 2.625,-2.175 2.025,-4.425c-0.675,-2.625 -3.375,-3.45 -6.675,-2.55l-6.675,1.725l3.975,15.45l2.55,-0.675l-1.8,-6.9l3.075,-0.825c2.925,-0.75 4.05,-0.15 4.575,1.95l0.075,0.3c0.45,1.65 0.825,3 1.275,3.6l2.55,-0.675c-0.45,-0.825 -0.825,-2.175 -1.2,-3.6l-0.075,-0.225Zm-7.425,-3.15l-3.3,0.825l-1.275,-5.025l3.825,-0.975c2.1,-0.525 3.6,-0.075 3.975,1.5c0.525,2.175 -0.975,3.15 -3.225,3.675Z" style="fill:#b4ac8f;fill-rule:nonzero;"/><path d="M208.708,217.966l-2.391,1.086l6.608,14.545l2.39,-1.086l-6.607,-14.545Z" style="fill:#b4ac8f;"/><path d="M223.95,208.725l-5.4,3.675l9,13.2l2.175,-1.5l-3.825,-5.55l2.925,-2.025c3.225,-2.175 4.575,-5.025 2.775,-7.65c-1.575,-2.4 -4.725,-2.175 -7.65,-0.15Zm3.825,6.375l-2.775,1.95l-3.15,-4.65l2.85,-1.95c1.95,-1.35 3.75,-1.5 4.8,-0c1.2,1.8 0.225,3.3 -1.725,4.65Z" style="fill:#b4ac8f;fill-rule:nonzero;"/><path d="M246.15,191.325l-1.425,-1.35l-9.45,9.9l1.425,1.275l3.75,-3.975l10.2,9.75l1.875,-1.95l-10.2,-9.675l3.825,-3.975Z" style="fill:#b4ac8f;fill-rule:nonzero;"/><path d="M182.1,1.425c-1.575,-0.225 -3.15,-0.45 -4.725,-0.675l-0,11.175c16.8,18.15 27.675,41.925 29.25,68.175l-103.65,-0c0,-0 -10.5,0.525 -10.5,9.225c0,9.075 8.325,10.575 10.425,10.575l52.05,0c0,0 6.525,-0.375 6.525,4.575c0,4.725 -4.8,4.5 -6.45,4.5l-106.125,0c8.25,-55.725 51.9,-99.9 107.325,-108.975c-59.775,3.15 -108.15,49.875 -113.925,108.975l-30.825,0c-0,0 -11.475,-1.35 -11.475,8.625c-0,9.975 8.625,9.6 11.025,9.6l30.825,0c1.125,21.225 7.8,41.1 18.525,58.05l0.075,-0.075c-6.6,-13.425 -10.875,-28.2 -12.45,-43.8l56.475,0c2.7,0 10.275,-0.375 10.275,-9.15c-0,-8.7 -9.3,-8.925 -9.3,-8.925l-76.35,0c-0,0 -6.675,0.525 -6.675,-4.8c-0,-5.325 4.35,-5.55 6.3,-5.55l142.875,0c0,0 10.95,1.2 10.95,-8.925c-0,-9 -9.6,-8.625 -13.125,-8.625l-48.825,0c0,0 -7.275,0.3 -7.275,-5.175c0,-5.475 6.15,-5.175 7.2,-5.175l86.025,0l-0,1.65c-0,28.875 -11.175,55.2 -29.475,74.85c-16.2,17.475 -38.025,29.7 -62.625,33.825c4.725,2.925 9.675,5.475 14.85,7.65c17.925,-5.1 34.2,-14.25 47.7,-26.4c11.025,-9.9 20.25,-21.9 27.075,-35.25l53.325,0l0,-5.025l-50.925,0c6.825,-15.15 10.65,-31.95 10.65,-49.65l0,-1.65l49.425,0c3.825,11.175 5.925,23.1 5.925,35.55c0,20.625 -5.7,39.975 -15.675,56.55l8.4,6.825c11.4,-18.45 18,-40.125 18,-63.375c0.3,-59.925 -43.65,-109.875 -101.1,-119.175Zm-87.975,131.325c0,4.875 -4.725,5.175 -4.725,5.175l-41.55,-0c-0.225,-3.225 -0.375,-6.45 -0.375,-9.675l0,-1.05l42.375,-0c0.75,0.075 4.275,0.675 4.275,5.55Zm123.225,-52.65c-1.35,-24.3 -9.825,-46.65 -23.475,-65.025c32.475,9.6 58.8,33.825 71.25,65.025l-47.775,-0Z" style="fill:#b4ac8f;fill-rule:nonzero;"/></g></svg> \ No newline at end of file
2<!-- Generator: Adobe Illustrator 22.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
4 <!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
5 <!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
6 <!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
7 <!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
8 <!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
9 <!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
10 <!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
11 <!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
12]>
13<svg version="1.1" id="图层_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
14 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="" viewBox="105 200 400 441.9" xml:space="preserve">
15 <g>
16 <g>
17 <path fill="#B4AC8F" d="M209.8,522.5c-3.7,0.8-8.1,1.6-11.7,2.3c0.5-2,1.9-7.8,2.9-11.5l-2.8-2.9l-3.3,14.5c0,0.2-0.1,0.4-0.3,0.6
18 l-6,5.7l2.4,2.6l6.1-5.8c0.2-0.2,0.3-0.3,0.5-0.3l14.7-2.5L209.8,522.5z"/>
19 <path fill="#B4AC8F" d="M225.4,551.7c-1.9,2.7-4.2,3.9-7.8,1.5c-3.6-2.5-3.4-5.2-1.6-7.8l7.7-11.2l-2.9-2l-7.8,11.4
20 c-2.8,4-2.3,7.9,3.2,11.7c5.9,4,9.7,2.4,12.2-1.3l7.7-11.3l-3-2L225.4,551.7z"/>
21 <polygon fill="#B4AC8F" points="241.1,569.1 255.5,574.8 256.9,572.7 245.3,568 248,561.2 258.6,565.4 259.5,563 249,558.8
22 251.4,552.9 262.4,557.3 263.3,555 249.1,549.3 "/>
23 <path fill="#B4AC8F" d="M283.6,559.6c-4.7-0.8-8.2,0.8-8.8,4.2c-0.5,3,1.2,4.9,6.3,7.2c4,1.8,5.2,3,4.8,5.3
24 c-0.4,2.2-2.4,3.1-5.4,2.6c-2.9-0.5-4.7-2.2-4.8-4.8l-3.5-0.6c-0.3,3.9,2.4,6.8,7.6,7.8c5.7,1,9-1.1,9.6-4.6
25 c0.5-2.9-0.7-5.2-6.6-7.9c-3.7-1.7-4.9-2.6-4.6-4.5c0.3-1.8,1.9-2.7,4.7-2.2c3,0.5,4.1,2.1,4.1,4.2l3.4,0.6
26 C291,563.6,289.1,560.6,283.6,559.6z"/>
27 <path fill="#B4AC8F" d="M315.3,581.1c-5.2,0.2-7-4-7.1-8.4c-0.2-4.4,1.6-8.4,6.4-8.6c3.7-0.1,5.2,1.6,5.9,3.9l3.5-0.1
28 c-0.6-3.5-3.4-6.5-9.4-6.3c-7.2,0.3-10.3,5.5-10.1,11.2c0.2,6.3,3.2,11,10.8,10.7c6.1-0.2,8.6-3.5,9.2-7l-3.5,0.1
29 C320.4,579,319,581,315.3,581.1z"/>
30 <path fill="#B4AC8F" d="M356.7,570.7c-0.7-2.8-2.2-4.2-4.9-4.2c1.8-1.1,3.5-2.9,2.7-5.9c-0.9-3.5-4.5-4.6-8.9-3.4l-8.9,2.3l5.3,20.6
31 l3.4-0.9L343,570l4.1-1.1c3.9-1,5.4-0.2,6.1,2.6l0.1,0.4c0.6,2.2,1.1,4,1.7,4.8l3.4-0.9c-0.6-1.1-1.1-2.9-1.6-4.8L356.7,570.7z
32 M346.8,566.5l-4.4,1.1l-1.7-6.7l5.1-1.3c2.8-0.7,4.8-0.1,5.3,2C351.8,564.5,349.8,565.8,346.8,566.5z"/>
33
34 <rect x="370.4" y="548.3" transform="matrix(0.9105 -0.4136 0.4136 0.9105 -197.8473 203.9409)" fill="#B4AC8F" width="3.5" height="21.3"/>
35 <path fill="#B4AC8F" d="M390,536.6l-7.2,4.9l12,17.6l2.9-2l-5.1-7.4l3.9-2.7c4.3-2.9,6.1-6.7,3.7-10.2
36 C398.1,533.6,393.9,533.9,390,536.6z M395.1,545.1l-3.7,2.6l-4.2-6.2l3.8-2.6c2.6-1.8,5-2,6.4,0
37 C399,541.3,397.7,543.3,395.1,545.1z"/>
38 <polygon fill="#B4AC8F" points="419.6,513.4 417.7,511.6 405.1,524.8 407,526.5 412,521.2 425.6,534.2 428.1,531.6 414.5,518.7
39 "/>
40 <path fill="#B4AC8F" d="M334.2,260.2c-2.1-0.3-4.2-0.6-6.3-0.9v14.4v0.5c22.4,24.2,36.9,55.9,39,90.9H228.7c0,0-14,0.7-14,12.3
41 c0,12.1,11.1,14.1,13.9,14.1s69.4,0,69.4,0s8.7-0.5,8.7,6.1c0,6.3-6.4,6-8.6,6H156.6c11-74.3,69.2-133.2,143.1-145.3
42 c-79.7,4.2-144.2,66.5-151.9,145.3h-41.1c0,0-15.3-1.8-15.3,11.5c0,13.3,11.5,12.8,14.7,12.8c0.6,0,19.5,0,41.1,0
43 c1.5,28.3,10.4,54.8,24.7,77.4l0.1-0.1c-8.8-17.9-14.5-37.6-16.6-58.4c31.5,0,73,0,75.3,0c3.6,0,13.7-0.5,13.7-12.2
44 c0-11.6-12.4-11.9-12.4-11.9l-101.8,0c0,0-8.9,0.7-8.9-6.4s5.8-7.4,8.4-7.4c0.6,0,190.5,0,190.5,0s14.6,1.6,14.6-11.9
45 c0-12-12.8-11.5-17.5-11.5c-4.7,0-65.1,0-65.1,0s-9.7,0.4-9.7-6.9c0-7.3,8.2-6.9,9.6-6.9c0.7,0,59.7,0,114.7,0c0,0.7,0,1.5,0,2.2
46 c0,38.5-14.9,73.6-39.3,99.8v0c-21.6,23.3-50.7,39.6-83.5,45.1c6.3,3.9,12.9,7.3,19.8,10.2c23.9-6.8,45.6-19,63.6-35.2v0
47 c14.7-13.2,27-29.2,36.1-47h71.1v-6.7h-67.9c9.1-20.2,14.2-42.6,14.2-66.2c0-0.7,0-1.5,0-2.2c26.9,0,51.4,0,65.9,0
48 c5.1,14.9,7.9,30.8,7.9,47.4c0,27.5-7.6,53.3-20.9,75.4l11.2,9.1c15.2-24.6,24-53.5,24-84.5C469.4,339.2,410.8,272.6,334.2,260.2
49 z M216.9,435.3c0,6.5-6.3,6.9-6.3,6.9s-27,0-55.4,0c-0.3-4.3-0.5-8.6-0.5-12.9c0-0.5,0-0.9,0-1.4c27.4,0,56.2,0,56.5,0
50 C212.2,428,216.9,428.8,216.9,435.3z M381.2,365.1c-1.8-32.4-13.1-62.2-31.3-86.7c43.3,12.8,78.4,45.1,95,86.7H381.2z"/>
51 </g>
52 </g>
53</svg>
diff --git a/doc/docs/.vitepress/theme/components/CompilerModal.vue b/doc/docs/.vitepress/theme/components/CompilerModal.vue
index 8620536..c00443e 100755
--- a/doc/docs/.vitepress/theme/components/CompilerModal.vue
+++ b/doc/docs/.vitepress/theme/components/CompilerModal.vue
@@ -1,7 +1,6 @@
1<template> 1<template>
2 <div v-if="isOpen" class="modal-backdrop" @click.self="close"> 2 <div v-if="isOpen" class="modal-backdrop" @click.self="close">
3 <div class="modal-body"> 3 <div class="modal-body">
4 <button class="modal-close" type="button" @click="close">×</button>
5 <YueCompiler :text="content" compileronly displayonly /> 4 <YueCompiler :text="content" compileronly displayonly />
6 </div> 5 </div>
7 </div> 6 </div>
@@ -25,10 +24,17 @@ export default {
25 this.content = event?.detail || '' 24 this.content = event?.detail || ''
26 this.isOpen = true 25 this.isOpen = true
27 } 26 }
27 this.handleKeydown = (event) => {
28 if (event.key === 'Escape' && this.isOpen) {
29 this.close()
30 }
31 }
28 window.addEventListener('yue:open-compiler', this.handleOpen) 32 window.addEventListener('yue:open-compiler', this.handleOpen)
33 window.addEventListener('keydown', this.handleKeydown)
29 }, 34 },
30 beforeUnmount() { 35 beforeUnmount() {
31 window.removeEventListener('yue:open-compiler', this.handleOpen) 36 window.removeEventListener('yue:open-compiler', this.handleOpen)
37 window.removeEventListener('keydown', this.handleKeydown)
32 }, 38 },
33 methods: { 39 methods: {
34 close() { 40 close() {
@@ -55,19 +61,7 @@ export default {
55 max-height: 90vh; 61 max-height: 90vh;
56 overflow: auto; 62 overflow: auto;
57 background: #ffffff; 63 background: #ffffff;
58 border-radius: 8px;
59 padding: 16px;
60 box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2); 64 box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);
61} 65}
62 66
63.modal-close {
64 position: sticky;
65 top: 0;
66 margin-left: auto;
67 border: none;
68 background: transparent;
69 font-size: 24px;
70 cursor: pointer;
71 color: #444;
72}
73</style> 67</style>
diff --git a/doc/docs/.vitepress/theme/components/YueCompiler.vue b/doc/docs/.vitepress/theme/components/YueCompiler.vue
index fc83486..28a6a9f 100755
--- a/doc/docs/.vitepress/theme/components/YueCompiler.vue
+++ b/doc/docs/.vitepress/theme/components/YueCompiler.vue
@@ -1,15 +1,10 @@
1<template> 1<template>
2 <div style="width: 100%; height: auto;"> 2 <div style="width: 100%; height: auto;">
3 <div class="parent" style="background-color: #f5f7ff;"> 3 <div class="parent">
4 <div class="editor-section"> 4 <div class="editor-section">
5 <div class="childTitle">YueScript {{ info }}</div> 5 <div class="childTitle">YueScript {{ info }}</div>
6 <div class="editor-container"> 6 <div class="editor-container">
7 <textarea 7 <div ref="codeEditor" class="code-editor"></div>
8 class="code-input"
9 v-model="code"
10 @input="codeChanged($event.target.value)"
11 :readonly="readonly"
12 ></textarea>
13 </div> 8 </div>
14 </div> 9 </div>
15 <div class="editor-section"> 10 <div class="editor-section">
@@ -27,10 +22,142 @@
27</template> 22</template>
28 23
29<script> 24<script>
30import 'prismjs/themes/prism.css' 25import pkg from 'prismjs/components/prism-core.js'
31import { highlight, languages } from 'prismjs/components/prism-core' 26const { highlight, languages } = pkg
32import 'prismjs/components/prism-moonscript' 27import 'prismjs/components/prism-moonscript'
33import 'prismjs/components/prism-lua' 28import 'prismjs/components/prism-lua'
29import { EditorState, Compartment } from '@codemirror/state'
30import { EditorView, keymap, lineNumbers } from '@codemirror/view'
31import {
32 indentUnit,
33 StreamLanguage,
34 syntaxHighlighting,
35 HighlightStyle
36} from '@codemirror/language'
37import { tags } from '@lezer/highlight'
38import { history, indentWithTab } from '@codemirror/commands'
39import { defaultKeymap, historyKeymap } from '@codemirror/commands'
40import { simpleMode } from '@codemirror/legacy-modes/mode/simple-mode'
41
42const vscodeLightTheme = EditorView.theme(
43 {
44 '&': {
45 height: '100%',
46 backgroundColor: '#ffffff',
47 color: '#000000',
48 fontSize: '15px'
49 },
50 '&.cm-focused': {
51 outline: 'none'
52 },
53 '.cm-content': {
54 fontFamily:
55 "Consolas, Menlo, Monaco, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', 'Lucida Sans Typewriter', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Liberation Mono', 'Nimbus Mono L', 'Courier New', Courier, monospace",
56 lineHeight: '1.375'
57 },
58 '.cm-gutters': {
59 backgroundColor: '#ffffff',
60 color: '#6e6e6e',
61 borderRight: 'none'
62 },
63 '.cm-activeLine': {
64 backgroundColor: 'transparent'
65 },
66 '.cm-activeLineGutter': {
67 backgroundColor: 'transparent'
68 },
69 '.cm-selectionBackground': {
70 backgroundColor: '#add6ff'
71 },
72 '&.cm-focused .cm-selectionBackground': {
73 backgroundColor: '#add6ff'
74 },
75 '.cm-cursor': {
76 borderLeftColor: '#000000'
77 },
78 '.cm-matchingBracket': {
79 backgroundColor: '#c9def5'
80 }
81 },
82 { dark: false }
83)
84
85const vscodeDarkTheme = EditorView.theme(
86 {
87 '&': {
88 height: '100%',
89 backgroundColor: '#1e1e1e',
90 color: '#d4d4d4',
91 fontSize: '15px'
92 },
93 '&.cm-focused': {
94 outline: 'none'
95 },
96 '.cm-content': {
97 fontFamily:
98 "Consolas, Menlo, Monaco, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', 'Lucida Sans Typewriter', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Liberation Mono', 'Nimbus Mono L', 'Courier New', Courier, monospace",
99 lineHeight: '1.375'
100 },
101 '.cm-gutters': {
102 backgroundColor: '#1e1e1e',
103 color: '#858585',
104 borderRight: 'none'
105 },
106 '.cm-activeLine': {
107 backgroundColor: 'transparent'
108 },
109 '.cm-activeLineGutter': {
110 backgroundColor: 'transparent'
111 },
112 '.cm-selectionBackground': {
113 backgroundColor: '#264f78'
114 },
115 '&.cm-focused .cm-selectionBackground': {
116 backgroundColor: '#264f78'
117 },
118 '.cm-cursor': {
119 borderLeftColor: '#aeafad'
120 },
121 '.cm-matchingBracket': {
122 backgroundColor: '#3a3d41'
123 }
124 },
125 { dark: true }
126)
127
128const vscodeLightHighlightStyle = HighlightStyle.define([
129 { tag: tags.comment, color: '#008000' },
130 { tag: tags.keyword, color: '#0000ff' },
131 { tag: [tags.operator, tags.punctuation], color: '#000000' },
132 { tag: [tags.string, tags.special(tags.string)], color: '#a31515' },
133 { tag: [tags.number, tags.bool, tags.null], color: '#098658' },
134 { tag: tags.function(tags.variableName), color: '#795e26' },
135 { tag: tags.typeName, color: '#267f99' },
136 { tag: tags.className, color: '#267f99' },
137 { tag: tags.variableName, color: '#001080' },
138 { tag: tags.propertyName, color: '#001080' },
139 { tag: tags.tagName, color: '#800000' },
140 { tag: tags.attributeName, color: '#e50000' },
141 { tag: tags.meta, color: '#666666' },
142 { tag: tags.invalid, color: '#cd3131' }
143])
144
145const vscodeDarkHighlightStyle = HighlightStyle.define([
146 { tag: tags.comment, color: '#6a9955' },
147 { tag: tags.keyword, color: '#569cd6' },
148 { tag: [tags.operator, tags.punctuation], color: '#d4d4d4' },
149 { tag: [tags.string, tags.special(tags.string)], color: '#ce9178' },
150 { tag: [tags.number, tags.bool, tags.null], color: '#b5cea8' },
151 { tag: tags.function(tags.variableName), color: '#dcdcaa' },
152 { tag: tags.typeName, color: '#4ec9b0' },
153 { tag: tags.className, color: '#4ec9b0' },
154 { tag: tags.variableName, color: '#9cdcfe' },
155 { tag: tags.propertyName, color: '#9cdcfe' },
156 { tag: tags.tagName, color: '#569cd6' },
157 { tag: tags.attributeName, color: '#9cdcfe' },
158 { tag: tags.meta, color: '#d4d4d4' },
159 { tag: tags.invalid, color: '#f44747' }
160])
34 161
35export default { 162export default {
36 props: { 163 props: {
@@ -54,7 +181,12 @@ export default {
54 code: '', 181 code: '',
55 compiled: '', 182 compiled: '',
56 result: '', 183 result: '',
57 windowWidth: 0 184 windowWidth: 0,
185 editorView: null,
186 readOnlyCompartment: null,
187 themeCompartment: null,
188 highlightCompartment: null,
189 themeObserver: null
58 } 190 }
59 }, 191 },
60 computed: { 192 computed: {
@@ -68,20 +200,22 @@ export default {
68 mounted() { 200 mounted() {
69 this.windowWidth = window.innerWidth 201 this.windowWidth = window.innerWidth
70 window.addEventListener('resize', this.handleResize) 202 window.addEventListener('resize', this.handleResize)
203 this.observeTheme()
71 204
72 if (this.text !== '') { 205 const initialCode = this.text !== '' ? this.text : ''
73 this.code = this.text 206 this.code = initialCode
74 this.codeChanged(this.text) 207 this.codeChanged(initialCode)
75 } 208 this.initEditor(initialCode)
209 this.$nextTick(() => {
210 this.focusEditorToEnd()
211 })
76 212
77 const check = ((self) => { 213 const check = ((self) => {
78 return () => { 214 return () => {
79 if (window.yue) { 215 if (window.yue) {
80 self.info = window.yue.version() 216 self.info = window.yue.version()
81 self.readonly = false 217 self.readonly = false
82 if (this.code !== '') { 218 this.refreshEditorReadOnly()
83 this.codeChanged(this.code)
84 }
85 } else { 219 } else {
86 setTimeout(check, 100) 220 setTimeout(check, 100)
87 } 221 }
@@ -91,11 +225,152 @@ export default {
91 }, 225 },
92 beforeUnmount() { 226 beforeUnmount() {
93 window.removeEventListener('resize', this.handleResize) 227 window.removeEventListener('resize', this.handleResize)
228 if (this.editorView) {
229 this.editorView.destroy()
230 this.editorView = null
231 }
232 if (this.themeObserver) {
233 this.themeObserver.disconnect()
234 this.themeObserver = null
235 }
94 }, 236 },
95 methods: { 237 methods: {
238 focusEditorToEnd() {
239 if (!this.editorView) {
240 return
241 }
242 const docLength = this.editorView.state.doc.length
243 this.editorView.dispatch({
244 selection: { anchor: docLength },
245 scrollIntoView: true
246 })
247 this.editorView.focus()
248 },
96 handleResize() { 249 handleResize() {
97 this.windowWidth = window.innerWidth 250 this.windowWidth = window.innerWidth
98 }, 251 },
252 isDarkTheme() {
253 return document.documentElement.classList.contains('dark')
254 },
255 observeTheme() {
256 if (this.themeObserver) {
257 return
258 }
259 this.themeObserver = new MutationObserver(() => {
260 this.refreshEditorTheme()
261 })
262 this.themeObserver.observe(document.documentElement, {
263 attributes: true,
264 attributeFilter: ['class']
265 })
266 },
267 initEditor(initialCode) {
268 if (!this.$refs.codeEditor) {
269 return
270 }
271
272 const moonscriptMode = simpleMode({
273 start: [
274 { regex: /--\[\[/, token: 'comment', push: 'commentBlock' },
275 { regex: /\[\[/, token: 'string', push: 'stringBlock' },
276 { regex: /--.*/, token: 'comment' },
277 { regex: /"(?:[^\\"]|\\.)*"?/, token: 'string' },
278 { regex: /'(?:[^\\']|\\.)*'?/, token: 'string' },
279 {
280 regex: /\b(?:class|extends|if|else|elseif|then|for|in|while|until|do|return|break|continue|switch|when|case|default|try|catch|finally|with|import|export|from|as|super|self|true|false|nil|and|or|not)\b/,
281 token: 'keyword'
282 },
283 { regex: /@[a-zA-Z_]\w*/, token: 'variable-2' },
284 { regex: /\b[A-Z][\w]*\b/, token: 'typeName' },
285 {
286 regex: /(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?/i,
287 token: 'number'
288 },
289 { regex: /[+\-/*=<>!]=?|[~^|&%]/, token: 'operator' },
290 { regex: /[()\[\]{}]/, token: 'bracket' },
291 { regex: /[a-zA-Z_]\w*/, token: 'variable' }
292 ],
293 commentBlock: [
294 { regex: /.*?\]\]/, token: 'comment', pop: true },
295 { regex: /.*/, token: 'comment' }
296 ],
297 stringBlock: [
298 { regex: /.*?\]\]/, token: 'string', pop: true },
299 { regex: /.*/, token: 'string' }
300 ],
301 languageData: {
302 name: 'moonscript'
303 }
304 })
305
306 this.readOnlyCompartment = new Compartment()
307 this.themeCompartment = new Compartment()
308 this.highlightCompartment = new Compartment()
309 const updateListener = EditorView.updateListener.of((update) => {
310 if (!update.docChanged) {
311 return
312 }
313 const nextCode = update.state.doc.toString()
314 this.code = nextCode
315 this.codeChanged(nextCode)
316 })
317
318 const isDark = this.isDarkTheme()
319
320 const state = EditorState.create({
321 doc: initialCode,
322 extensions: [
323 lineNumbers(),
324 history(),
325 keymap.of([...defaultKeymap, ...historyKeymap, indentWithTab]),
326 StreamLanguage.define(moonscriptMode),
327 indentUnit.of(' '),
328 this.readOnlyCompartment.of(EditorState.readOnly.of(this.readonly)),
329 this.highlightCompartment.of(
330 syntaxHighlighting(
331 isDark ? vscodeDarkHighlightStyle : vscodeLightHighlightStyle,
332 { fallback: true }
333 )
334 ),
335 updateListener,
336 this.themeCompartment.of(isDark ? vscodeDarkTheme : vscodeLightTheme)
337 ]
338 })
339
340 this.editorView = new EditorView({
341 state,
342 parent: this.$refs.codeEditor
343 })
344 },
345 refreshEditorTheme() {
346 if (!this.editorView || !this.themeCompartment || !this.highlightCompartment) {
347 return
348 }
349 const isDark = this.isDarkTheme()
350 this.editorView.dispatch({
351 effects: [
352 this.themeCompartment.reconfigure(
353 isDark ? vscodeDarkTheme : vscodeLightTheme
354 ),
355 this.highlightCompartment.reconfigure(
356 syntaxHighlighting(
357 isDark ? vscodeDarkHighlightStyle : vscodeLightHighlightStyle,
358 { fallback: true }
359 )
360 )
361 ]
362 })
363 },
364 refreshEditorReadOnly() {
365 if (!this.editorView || !this.readOnlyCompartment) {
366 return
367 }
368 this.editorView.dispatch({
369 effects: this.readOnlyCompartment.reconfigure(
370 EditorState.readOnly.of(this.readonly)
371 )
372 })
373 },
99 runCode() { 374 runCode() {
100 if (window.yue && this.compiled !== '') { 375 if (window.yue && this.compiled !== '') {
101 let res = '' 376 let res = ''
@@ -138,6 +413,10 @@ export default {
138 width: calc(100% - 120px); 413 width: calc(100% - 120px);
139 height: 55px; 414 height: 55px;
140 border-color: #b7ae8f; 415 border-color: #b7ae8f;
416 border-radius: 4px;
417 border-width: 1px;
418 border-style: solid;
419 padding: 10px;
141 outline: none; 420 outline: none;
142 resize: none; 421 resize: none;
143 margin-top: 5px; 422 margin-top: 5px;
@@ -147,12 +426,13 @@ export default {
147 display: flex; 426 display: flex;
148 flex-wrap: wrap; 427 flex-wrap: wrap;
149 width: 100%; 428 width: 100%;
429 background: var(--vp-c-bg-alt);
150} 430}
151 431
152.editor-section { 432.editor-section {
153 width: 50%; 433 width: 50%;
154 box-sizing: border-box; 434 box-sizing: border-box;
155 background: #f5f7ff; 435 background: var(--vp-c-bg-alt);
156} 436}
157 437
158.editor-container { 438.editor-container {
@@ -200,21 +480,17 @@ export default {
200 outline: none; 480 outline: none;
201} 481}
202 482
203.code-input { 483.code-editor {
204 width: 100%;
205 height: 100%; 484 height: 100%;
206 border: none; 485}
207 resize: none; 486
208 padding: 12px; 487.code-editor :deep(.cm-scroller) {
209 font-family: Consolas, Menlo, Monaco, 'Andale Mono WT', 'Andale Mono', 488 overscroll-behavior: contain;
210 'Lucida Console', 'Lucida Sans Typewriter', 'DejaVu Sans Mono', 489}
211 'Bitstream Vera Sans Mono', 'Liberation Mono', 'Nimbus Mono L', 'Courier New', 490
212 Courier, monospace; 491.code-editor :deep(.cm-content) {
213 line-height: 1.375; 492 padding-top: 15px;
214 background: #f5f7ff; 493 padding-left: 10px;
215 color: #5e6687;
216 font-size: 15px;
217 outline: none;
218} 494}
219 495
220.code-output { 496.code-output {
@@ -222,8 +498,6 @@ export default {
222 height: 100%; 498 height: 100%;
223 overflow: auto; 499 overflow: auto;
224 padding: 12px; 500 padding: 12px;
225 background: #f5f7ff;
226 color: #5e6687;
227 font-size: 15px; 501 font-size: 15px;
228} 502}
229 503
diff --git a/doc/docs/.vitepress/theme/components/YueDisplay.vue b/doc/docs/.vitepress/theme/components/YueDisplay.vue
index c633b43..507ace0 100755
--- a/doc/docs/.vitepress/theme/components/YueDisplay.vue
+++ b/doc/docs/.vitepress/theme/components/YueDisplay.vue
@@ -12,7 +12,9 @@ export default {
12 methods: { 12 methods: {
13 compile() { 13 compile() {
14 const node = this.$el.children[1] 14 const node = this.$el.children[1]
15 const code = node.innerText 15 const pre = node.querySelector('pre')
16 const codeNode = pre?.querySelector('code') || pre || node
17 const code = (codeNode?.textContent || '').replace(/\r\n?/g, '\n')
16 window.dispatchEvent(new CustomEvent('yue:open-compiler', { detail: code })) 18 window.dispatchEvent(new CustomEvent('yue:open-compiler', { detail: code }))
17 } 19 }
18 } 20 }
diff --git a/doc/docs/.vitepress/theme/custom.css b/doc/docs/.vitepress/theme/custom.css
index 67131ae..9085b4b 100644
--- a/doc/docs/.vitepress/theme/custom.css
+++ b/doc/docs/.vitepress/theme/custom.css
@@ -1,8 +1,98 @@
1:root { 1:root {
2 --vp-c-brand-1: #3eaf7c; 2 --vp-c-brand-1: #b4ac8f;
3 --vp-button-brand-bg: #b4ac8f;
4 --vp-button-brand-hover-bg: #b4ac8f;
5 --vp-button-brand-active-bg: #b4ac8f;
6 --vp-button-brand-border: #b4ac8f;
7 --vp-button-brand-hover-border: #b4ac8f;
8 --vp-button-brand-active-border: #b4ac8f;
9 --vp-button-brand-text: #fff;
3} 10}
4 11
5.VPHomeHero .image img { 12.VPHomeHero .image img {
6 width: 450px; 13 width: 450px;
7 max-width: 450px !important; 14 max-width: 450px !important;
8} 15}
16
17/* Prism theme for YueCompiler output (VS Code Light/Dark) */
18.code-output,
19.code-output code {
20 background: #ffffff;
21 color: #000000;
22}
23
24.dark .code-output,
25.dark .code-output code {
26 background: #1e1e1e;
27 color: #d4d4d4;
28}
29
30.code-output .token.comment {
31 color: #008000;
32}
33
34.code-output .token.keyword {
35 color: #0000ff;
36}
37
38.code-output .token.operator,
39.code-output .token.punctuation {
40 color: #000000;
41}
42
43.code-output .token.string,
44.code-output .token.char,
45.code-output .token.regex,
46.code-output .token.variable {
47 color: #a31515;
48}
49
50.code-output .token.number,
51.code-output .token.boolean,
52.code-output .token.constant {
53 color: #098658;
54}
55
56.code-output .token.function {
57 color: #795e26;
58}
59
60.code-output .token.class-name,
61.code-output .token.builtin {
62 color: #267f99;
63}
64
65.dark .code-output .token.comment {
66 color: #6a9955;
67}
68
69.dark .code-output .token.keyword {
70 color: #569cd6;
71}
72
73.dark .code-output .token.operator,
74.dark .code-output .token.punctuation {
75 color: #d4d4d4;
76}
77
78.dark .code-output .token.string,
79.dark .code-output .token.char,
80.dark .code-output .token.regex,
81.dark .code-output .token.variable {
82 color: #ce9178;
83}
84
85.dark .code-output .token.number,
86.dark .code-output .token.boolean,
87.dark .code-output .token.constant {
88 color: #b5cea8;
89}
90
91.dark .code-output .token.function {
92 color: #dcdcaa;
93}
94
95.dark .code-output .token.class-name,
96.dark .code-output .token.builtin {
97 color: #4ec9b0;
98}
diff --git a/doc/docs/.vitepress/theme/index.ts b/doc/docs/.vitepress/theme/index.ts
index 7234afe..e2a44c6 100644
--- a/doc/docs/.vitepress/theme/index.ts
+++ b/doc/docs/.vitepress/theme/index.ts
@@ -1,20 +1,18 @@
1import DefaultTheme from 'vitepress/theme' 1import DefaultTheme from 'vitepress/theme'
2import { h } from 'vue' 2import type { Theme } from 'vitepress'
3import './custom.css' 3import './custom.css'
4 4
5import CompilerModal from './components/CompilerModal.vue' 5import CompilerModal from './components/CompilerModal.vue'
6import YueCompiler from './components/YueCompiler.vue' 6import YueCompiler from './components/YueCompiler.vue'
7import YueDisplay from './components/YueDisplay.vue' 7import YueDisplay from './components/YueDisplay.vue'
8 8
9export default { 9const theme: Theme = {
10 extends: DefaultTheme, 10 extends: DefaultTheme,
11 Layout: () =>
12 h(DefaultTheme.Layout, null, {
13 'layout-bottom': () => h(CompilerModal)
14 }),
15 enhanceApp({ app }) { 11 enhanceApp({ app }) {
16 app.component('CompilerModal', CompilerModal) 12 app.component('CompilerModal', CompilerModal)
17 app.component('YueCompiler', YueCompiler) 13 app.component('YueCompiler', YueCompiler)
18 app.component('YueDisplay', YueDisplay) 14 app.component('YueDisplay', YueDisplay)
19 } 15 }
20} 16}
17
18export default theme
diff --git a/doc/docs/README.md b/doc/docs/README.md
deleted file mode 100755
index b7255a2..0000000
--- a/doc/docs/README.md
+++ /dev/null
@@ -1,14 +0,0 @@
1---
2layout: home
3hero:
4 name: YueScript
5 text: A language that compiles to Lua
6 image:
7 src: /image/yuescript.svg
8 alt: YueScript
9 actions:
10 - theme: brand
11 text: Quick Start →
12 link: /doc/
13footer: MIT Licensed | Copyright © 2017-2026 Li Jin
14---
diff --git a/doc/docs/doc/README.md b/doc/docs/doc/index.md
index 8569a10..6998747 100755
--- a/doc/docs/doc/README.md
+++ b/doc/docs/doc/index.md
@@ -5,7 +5,7 @@ title: Reference
5 5
6# YueScript 6# YueScript
7 7
8<img src="/image/yuescript.svg" width="300px" height="300px" alt="logo"/> 8<img src="/image/yuescript.svg" width="250px" height="250px" alt="logo" style="padding-top: 3em;"/>
9 9
10## Introduction 10## Introduction
11 11
@@ -14,7 +14,7 @@ YueScript is a dynamic language that compiles to Lua. And it's a [MoonScript](ht
14Yue (月) is the name of moon in Chinese and it's pronounced as [jyɛ]. 14Yue (月) is the name of moon in Chinese and it's pronounced as [jyɛ].
15 15
16### An Overview of YueScript 16### An Overview of YueScript
17```moonscript 17```yuescript
18-- import syntax 18-- import syntax
19import p, to_lua from "yue" 19import p, to_lua from "yue"
20 20
@@ -58,8 +58,10 @@ with apple
58-- js-like export syntax 58-- js-like export syntax
59export 🌛 = "月之脚本" 59export 🌛 = "月之脚本"
60``` 60```
61
61<YueDisplay> 62<YueDisplay>
62<pre> 63
64```yue
63-- import syntax 65-- import syntax
64import p, to_lua from "yue" 66import p, to_lua from "yue"
65 67
@@ -94,15 +96,16 @@ reduce = (arr, init, action): init ->
94-- metatable manipulation 96-- metatable manipulation
95apple = 97apple =
96 size: 15 98 size: 15
97 &lt;index&gt;: 99 <index>:
98 color: 0x00ffff 100 color: 0x00ffff
99 101
100with apple 102with apple
101 p .size, .color, .&lt;index&gt; if .&lt;&gt;? 103 p .size, .color, .<index> if .<>?
102 104
103-- js-like export syntax 105-- js-like export syntax
104export 🌛 = "月之脚本" 106export 🌛 = "月之脚本"
105</pre> 107```
108
106</YueDisplay> 109</YueDisplay>
107 110
108## Installation 111## Installation
@@ -194,7 +197,7 @@ f!
194### YueScript Tool 197### YueScript Tool
195 198
196&emsp;Use YueScript tool with: 199&emsp;Use YueScript tool with:
197``` 200```sh
198> yue -h 201> yue -h
199Usage: yue 202Usage: yue
200 [options] [<file/directory>] ... 203 [options] [<file/directory>] ...
@@ -239,11 +242,17 @@ Options:
239 in a single line to start/stop multi-line mode 242 in a single line to start/stop multi-line mode
240``` 243```
241&emsp;&emsp;Use cases: 244&emsp;&emsp;Use cases:
245
242&emsp;&emsp;Recursively compile every YueScript file with extension **.yue** under current path: **yue .** 246&emsp;&emsp;Recursively compile every YueScript file with extension **.yue** under current path: **yue .**
247
243&emsp;&emsp;Compile and save results to a target path: **yue -t /target/path/ .** 248&emsp;&emsp;Compile and save results to a target path: **yue -t /target/path/ .**
249
244&emsp;&emsp;Compile and reserve debug info: **yue -l .** 250&emsp;&emsp;Compile and reserve debug info: **yue -l .**
251
245&emsp;&emsp;Compile and generate minified codes: **yue -m .** 252&emsp;&emsp;Compile and generate minified codes: **yue -m .**
253
246&emsp;&emsp;Execute raw codes: **yue -e 'print 123'** 254&emsp;&emsp;Execute raw codes: **yue -e 'print 123'**
255
247&emsp;&emsp;Execute a YueScript file: **yue -e main.yue** 256&emsp;&emsp;Execute a YueScript file: **yue -e main.yue**
248 257
249## Macro 258## Macro
@@ -252,7 +261,7 @@ Options:
252 261
253Macro function is used for evaluating a string in the compile time and insert the generated codes into final compilation. 262Macro function is used for evaluating a string in the compile time and insert the generated codes into final compilation.
254 263
255```moonscript 264```yuescript
256macro PI2 = -> math.pi * 2 265macro PI2 = -> math.pi * 2
257area = $PI2 * 5 266area = $PI2 * 5
258 267
@@ -281,7 +290,8 @@ if $and f1!, f2!, f3!
281 print "OK" 290 print "OK"
282``` 291```
283<YueDisplay> 292<YueDisplay>
284<pre> 293
294```yue
285macro PI2 = -> math.pi * 2 295macro PI2 = -> math.pi * 2
286area = $PI2 * 5 296area = $PI2 * 5
287 297
@@ -308,13 +318,14 @@ value = $assert item
308macro and = (...) -> "#{ table.concat {...}, ' and ' }" 318macro and = (...) -> "#{ table.concat {...}, ' and ' }"
309if $and f1!, f2!, f3! 319if $and f1!, f2!, f3!
310 print "OK" 320 print "OK"
311</pre> 321```
322
312</YueDisplay> 323</YueDisplay>
313 324
314### Insert Raw Codes 325### Insert Raw Codes
315 326
316A macro function can either return a YueScript string or a config table containing Lua codes. 327A macro function can either return a YueScript string or a config table containing Lua codes.
317```moonscript 328```yuescript
318macro yueFunc = (var) -> "local #{var} = ->" 329macro yueFunc = (var) -> "local #{var} = ->"
319$yueFunc funcA 330$yueFunc funcA
320funcA = -> "fail to assign to the Yue macro defined variable" 331funcA = -> "fail to assign to the Yue macro defined variable"
@@ -340,7 +351,8 @@ end
340]==] 351]==]
341``` 352```
342<YueDisplay> 353<YueDisplay>
343<pre> 354
355```yue
344macro yueFunc = (var) -> "local #{var} = ->" 356macro yueFunc = (var) -> "local #{var} = ->"
345$yueFunc funcA 357$yueFunc funcA
346funcA = -> "fail to assign to the Yue macro defined variable" 358funcA = -> "fail to assign to the Yue macro defined variable"
@@ -364,13 +376,14 @@ if cond then
364 print("output") 376 print("output")
365end 377end
366]==] 378]==]
367</pre> 379```
380
368</YueDisplay> 381</YueDisplay>
369 382
370### Export Macro 383### Export Macro
371 384
372Macro functions can be exported from a module and get imported in another module. You have to put export macro functions in a single file to be used, and only macro definition, macro importing and macro expansion in place can be put into the macro exporting module. 385Macro functions can be exported from a module and get imported in another module. You have to put export macro functions in a single file to be used, and only macro definition, macro importing and macro expansion in place can be put into the macro exporting module.
373```moonscript 386```yuescript
374-- file: utils.yue 387-- file: utils.yue
375export macro map = (items, action) -> "[#{action} for _ in *#{items}]" 388export macro map = (items, action) -> "[#{action} for _ in *#{items}]"
376export macro filter = (items, action) -> "[_ for _ in *#{items} when #{action}]" 389export macro filter = (items, action) -> "[_ for _ in *#{items} when #{action}]"
@@ -385,7 +398,8 @@ import "utils" as {
385[1, 2, 3] |> $map(_ * 2) |> $filter(_ > 4) |> $each print _ 398[1, 2, 3] |> $map(_ * 2) |> $filter(_ > 4) |> $each print _
386``` 399```
387<YueDisplay> 400<YueDisplay>
388<pre> 401
402```yue
389-- file: utils.yue 403-- file: utils.yue
390export macro map = (items, action) -> "[#{action} for _ in *#{items}]" 404export macro map = (items, action) -> "[#{action} for _ in *#{items}]"
391export macro filter = (items, action) -> "[_ for _ in *#{items} when #{action}]" 405export macro filter = (items, action) -> "[_ for _ in *#{items} when #{action}]"
@@ -400,28 +414,31 @@ import "utils" as {
400} 414}
401[1, 2, 3] |> $map(_ * 2) |> $filter(_ > 4) |> $each print _ 415[1, 2, 3] |> $map(_ * 2) |> $filter(_ > 4) |> $each print _
402]] 416]]
403</pre> 417```
418
404</YueDisplay> 419</YueDisplay>
405 420
406### Builtin Macro 421### Builtin Macro
407 422
408There are some builtin macros but you can override them by declaring macros with the same names. 423There are some builtin macros but you can override them by declaring macros with the same names.
409```moonscript 424```yuescript
410print $FILE -- get string of current module name 425print $FILE -- get string of current module name
411print $LINE -- get number 2 426print $LINE -- get number 2
412``` 427```
413<YueDisplay> 428<YueDisplay>
414<pre> 429
430```yue
415print $FILE -- get string of current module name 431print $FILE -- get string of current module name
416print $LINE -- get number 2 432print $LINE -- get number 2
417</pre> 433```
434
418</YueDisplay> 435</YueDisplay>
419 436
420### Generating Macros with Macros 437### Generating Macros with Macros
421 438
422In YueScript, macro functions allow you to generate code at compile time. By nesting macro functions, you can create more complex generation patterns. This feature enables you to define a macro function that generates another macro function, allowing for more dynamic code generation. 439In YueScript, macro functions allow you to generate code at compile time. By nesting macro functions, you can create more complex generation patterns. This feature enables you to define a macro function that generates another macro function, allowing for more dynamic code generation.
423 440
424```moonscript 441```yuescript
425macro Enum = (...) -> 442macro Enum = (...) ->
426 items = {...} 443 items = {...}
427 itemSet = {item, true for item in *items} 444 itemSet = {item, true for item in *items}
@@ -440,7 +457,8 @@ print "Valid enum type:", $BodyType Static
440``` 457```
441 458
442<YueDisplay> 459<YueDisplay>
443<pre> 460
461```yue
444macro Enum = (...) -> 462macro Enum = (...) ->
445 items = {...} 463 items = {...}
446 itemSet = {item, true for item in *items} 464 itemSet = {item, true for item in *items}
@@ -456,14 +474,15 @@ macro BodyType = $Enum(
456 474
457print "Valid enum type:", $BodyType Static 475print "Valid enum type:", $BodyType Static
458-- print "Compilation error with enum type:", $BodyType Unknown 476-- print "Compilation error with enum type:", $BodyType Unknown
459</pre> 477```
478
460</YueDisplay> 479</YueDisplay>
461 480
462### Argument Validation 481### Argument Validation
463 482
464You can declare the expected AST node types in the argument list, and check whether the incoming macro arguments meet the expectations at compile time. 483You can declare the expected AST node types in the argument list, and check whether the incoming macro arguments meet the expectations at compile time.
465 484
466```moonscript 485```yuescript
467macro printNumAndStr = (num `Num, str `String) -> | 486macro printNumAndStr = (num `Num, str `String) -> |
468 print( 487 print(
469 #{num} 488 #{num}
@@ -473,7 +492,8 @@ macro printNumAndStr = (num `Num, str `String) -> |
473$printNumAndStr 123, "hello" 492$printNumAndStr 123, "hello"
474``` 493```
475<YueDisplay> 494<YueDisplay>
476<pre> 495
496```yue
477macro printNumAndStr = (num `Num, str `String) -> | 497macro printNumAndStr = (num `Num, str `String) -> |
478 print( 498 print(
479 #{num} 499 #{num}
@@ -481,12 +501,13 @@ macro printNumAndStr = (num `Num, str `String) -> |
481 ) 501 )
482 502
483$printNumAndStr 123, "hello" 503$printNumAndStr 123, "hello"
484</pre> 504```
505
485</YueDisplay> 506</YueDisplay>
486 507
487If you need more flexible argument checking, you can use the built-in `$is_ast` macro function to manually check at the appropriate place. 508If you need more flexible argument checking, you can use the built-in `$is_ast` macro function to manually check at the appropriate place.
488 509
489```moonscript 510```yuescript
490macro printNumAndStr = (num, str) -> 511macro printNumAndStr = (num, str) ->
491 error "expected Num as first argument" unless $is_ast Num, num 512 error "expected Num as first argument" unless $is_ast Num, num
492 error "expected String as second argument" unless $is_ast String, str 513 error "expected String as second argument" unless $is_ast String, str
@@ -495,14 +516,16 @@ macro printNumAndStr = (num, str) ->
495$printNumAndStr 123, "hello" 516$printNumAndStr 123, "hello"
496``` 517```
497<YueDisplay> 518<YueDisplay>
498<pre> 519
520```yue
499macro printNumAndStr = (num, str) -> 521macro printNumAndStr = (num, str) ->
500 error "expected Num as first argument" unless $is_ast Num, num 522 error "expected Num as first argument" unless $is_ast Num, num
501 error "expected String as second argument" unless $is_ast String, str 523 error "expected String as second argument" unless $is_ast String, str
502 "print(#{num}, #{str})" 524 "print(#{num}, #{str})"
503 525
504$printNumAndStr 123, "hello" 526$printNumAndStr 123, "hello"
505</pre> 527```
528
506</YueDisplay> 529</YueDisplay>
507 530
508For 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). 531For 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).
@@ -511,22 +534,24 @@ For more details about available AST nodes, please refer to the uppercased defin
511 534
512All 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. 535All 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.
513 536
514```moonscript 537```yuescript
515tb\func! if tb ~= nil 538tb\func! if tb ~= nil
516tb::func! if tb != nil 539tb::func! if tb != nil
517``` 540```
518<YueDisplay> 541<YueDisplay>
519<pre> 542
543```yue
520tb\func! if tb ~= nil 544tb\func! if tb ~= nil
521tb::func! if tb != nil 545tb::func! if tb != nil
522</pre> 546```
547
523</YueDisplay> 548</YueDisplay>
524 549
525### Chaining Comparisons 550### Chaining Comparisons
526 551
527Comparisons can be arbitrarily chained: 552Comparisons can be arbitrarily chained:
528 553
529```moonscript 554```yuescript
530print 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5 555print 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5
531-- output: true 556-- output: true
532 557
@@ -535,19 +560,21 @@ print 1 <= a <= 10
535-- output: true 560-- output: true
536``` 561```
537<YueDisplay> 562<YueDisplay>
538<pre> 563
564```yue
539print 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5 565print 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5
540-- output: true 566-- output: true
541 567
542a = 5 568a = 5
543print 1 <= a <= 10 569print 1 <= a <= 10
544-- output: true 570-- output: true
545</pre> 571```
572
546</YueDisplay> 573</YueDisplay>
547 574
548Note the evaluation behavior of chained comparisons: 575Note the evaluation behavior of chained comparisons:
549 576
550```moonscript 577```yuescript
551v = (x) -> 578v = (x) ->
552 print x 579 print x
553 x 580 x
@@ -570,7 +597,8 @@ print v(1) > v(2) <= v(3)
570]] 597]]
571``` 598```
572<YueDisplay> 599<YueDisplay>
573<pre> 600
601```yue
574v = (x) -> 602v = (x) ->
575 print x 603 print x
576 x 604 x
@@ -591,7 +619,8 @@ print v(1) > v(2) <= v(3)
591 1 619 1
592 false 620 false
593]] 621]]
594</pre> 622```
623
595</YueDisplay> 624</YueDisplay>
596 625
597The middle expression is only evaluated once, rather than twice as it would be if the expression were written as `v(1) < v(2) and v(2) <= v(3)`. However, the order of evaluations in a chained comparison is undefined. It is strongly recommended not to use expressions with side effects (such as printing) in chained comparisons. If side effects are required, the short-circuit `and` operator should be used explicitly. 626The middle expression is only evaluated once, rather than twice as it would be if the expression were written as `v(1) < v(2) and v(2) <= v(3)`. However, the order of evaluations in a chained comparison is undefined. It is strongly recommended not to use expressions with side effects (such as printing) in chained comparisons. If side effects are required, the short-circuit `and` operator should be used explicitly.
@@ -599,39 +628,43 @@ The middle expression is only evaluated once, rather than twice as it would be i
599### Table Appending 628### Table Appending
600The **[] =** operator is used to append values to tables. 629The **[] =** operator is used to append values to tables.
601 630
602```moonscript 631```yuescript
603tab = [] 632tab = []
604tab[] = "Value" 633tab[] = "Value"
605``` 634```
606<YueDisplay> 635<YueDisplay>
607<pre> 636
637```yue
608tab = [] 638tab = []
609tab[] = "Value" 639tab[] = "Value"
610</pre> 640```
641
611</YueDisplay> 642</YueDisplay>
612 643
613You can also use the spread operator `...` to append all elements from one list to another: 644You can also use the spread operator `...` to append all elements from one list to another:
614 645
615```moonscript 646```yuescript
616tbA = [1, 2, 3] 647tbA = [1, 2, 3]
617tbB = [4, 5, 6] 648tbB = [4, 5, 6]
618tbA[] = ...tbB 649tbA[] = ...tbB
619-- tbA is now [1, 2, 3, 4, 5, 6] 650-- tbA is now [1, 2, 3, 4, 5, 6]
620``` 651```
621<YueDisplay> 652<YueDisplay>
622<pre> 653
654```yue
623tbA = [1, 2, 3] 655tbA = [1, 2, 3]
624tbB = [4, 5, 6] 656tbB = [4, 5, 6]
625tbA[] = ...tbB 657tbA[] = ...tbB
626-- tbA is now [1, 2, 3, 4, 5, 6] 658-- tbA is now [1, 2, 3, 4, 5, 6]
627</pre> 659```
660
628</YueDisplay> 661</YueDisplay>
629 662
630### Table Spreading 663### Table Spreading
631 664
632You can concatenate array tables or hash tables using spread operator `...` before expressions in table literals. 665You can concatenate array tables or hash tables using spread operator `...` before expressions in table literals.
633 666
634```moonscript 667```yuescript
635parts = 668parts =
636 * "shoulders" 669 * "shoulders"
637 * "knees" 670 * "knees"
@@ -648,7 +681,8 @@ b = {4, 5, y: 1}
648merge = {...a, ...b} 681merge = {...a, ...b}
649``` 682```
650<YueDisplay> 683<YueDisplay>
651<pre> 684
685```yue
652parts = 686parts =
653 * "shoulders" 687 * "shoulders"
654 * "knees" 688 * "knees"
@@ -663,24 +697,27 @@ copy = {...other}
663a = {1, 2, 3, x: 1} 697a = {1, 2, 3, x: 1}
664b = {4, 5, y: 1} 698b = {4, 5, y: 1}
665merge = {...a, ...b} 699merge = {...a, ...b}
666</pre> 700```
701
667</YueDisplay> 702</YueDisplay>
668 703
669### Table Reversed Indexing 704### Table Reversed Indexing
670 705
671You can use the **#** operator to get the last elements of a table. 706You can use the **#** operator to get the last elements of a table.
672 707
673```moonscript 708```yuescript
674last = data.items[#] 709last = data.items[#]
675second_last = data.items[#-1] 710second_last = data.items[#-1]
676data.items[#] = 1 711data.items[#] = 1
677``` 712```
678<YueDisplay> 713<YueDisplay>
679<pre> 714
715```yue
680last = data.items[#] 716last = data.items[#]
681second_last = data.items[#-1] 717second_last = data.items[#-1]
682data.items[#] = 1 718data.items[#] = 1
683</pre> 719```
720
684</YueDisplay> 721</YueDisplay>
685 722
686### Metatable 723### Metatable
@@ -690,7 +727,7 @@ The **<>** operator can be used as a shortcut for metatable manipulation.
690* **Metatable Creation** 727* **Metatable Creation**
691Create normal table with empty bracekets **<>** or metamethod key which is surrounded by **<>**. 728Create normal table with empty bracekets **<>** or metamethod key which is surrounded by **<>**.
692 729
693```moonscript 730```yuescript
694mt = {} 731mt = {}
695add = (right) => <>: mt, value: @value + right.value 732add = (right) => <>: mt, value: @value + right.value
696mt.__add = add 733mt.__add = add
@@ -706,27 +743,29 @@ print d.value
706close _ = <close>: -> print "out of scope" 743close _ = <close>: -> print "out of scope"
707``` 744```
708<YueDisplay> 745<YueDisplay>
709<pre> 746
747```yue
710mt = {} 748mt = {}
711add = (right) => &lt;&gt;: mt, value: @value + right.value 749add = (right) => <>: mt, value: @value + right.value
712mt.__add = add 750mt.__add = add
713 751
714a = &lt;&gt;: mt, value: 1 752a = <>: mt, value: 1
715 -- set field with variable of the same name 753 -- set field with variable of the same name
716b = :&lt;add&gt;, value: 2 754b = :<add>, value: 2
717c = &lt;add&gt;: mt.__add, value: 3 755c = <add>: mt.__add, value: 3
718 756
719d = a + b + c 757d = a + b + c
720print d.value 758print d.value
721 759
722close _ = &lt;close&gt;: -> print "out of scope" 760close _ = <close>: -> print "out of scope"
723</pre> 761```
762
724</YueDisplay> 763</YueDisplay>
725 764
726* **Metatable Accessing** 765* **Metatable Accessing**
727Accessing metatable with **<>** or metamethod name surrounded by **<>** or writing some expression in **<>**. 766Accessing metatable with **<>** or metamethod name surrounded by **<>** or writing some expression in **<>**.
728 767
729```moonscript 768```yuescript
730-- create with metatable containing field "value" 769-- create with metatable containing field "value"
731tb = <"value">: 123 770tb = <"value">: 123
732tb.<index> = tb.<> 771tb.<index> = tb.<>
@@ -737,35 +776,38 @@ print tb.item
737``` 776```
738<YueDisplay> 777<YueDisplay>
739 778
740<pre> 779```yue
741-- create with metatable containing field "value" 780-- create with metatable containing field "value"
742tb = &lt;"value"&gt;: 123 781tb = <"value">: 123
743tb.&lt;index&gt; = tb.&lt;&gt; 782tb.<index> = tb.<>
744print tb.value 783print tb.value
745tb.&lt;&gt; = __index: {item: "hello"} 784tb.<> = __index: {item: "hello"}
746print tb.item 785print tb.item
747</pre> 786```
787
748</YueDisplay> 788</YueDisplay>
749 789
750* **Metatable Destructure** 790* **Metatable Destructure**
751Destruct metatable with metamethod key surrounded by **<>**. 791Destruct metatable with metamethod key surrounded by **<>**.
752 792
753```moonscript 793```yuescript
754{item, :new, :<close>, <index>: getter} = tb 794{item, :new, :<close>, <index>: getter} = tb
755print item, new, close, getter 795print item, new, close, getter
756``` 796```
757<YueDisplay> 797<YueDisplay>
758<pre> 798
759{item, :new, :&lt;close&gt;, &lt;index&gt;: getter} = tb 799```yue
800{item, :new, :<close>, <index>: getter} = tb
760print item, new, close, getter 801print item, new, close, getter
761</pre> 802```
803
762</YueDisplay> 804</YueDisplay>
763 805
764### Existence 806### Existence
765 807
766The **?** operator can be used in a variety of contexts to check for existence. 808The **?** operator can be used in a variety of contexts to check for existence.
767 809
768```moonscript 810```yuescript
769func?! 811func?!
770print abc?["hello world"]?.xyz 812print abc?["hello world"]?.xyz
771 813
@@ -780,7 +822,8 @@ with? io.open "test.txt", "w"
780 \close! 822 \close!
781``` 823```
782<YueDisplay> 824<YueDisplay>
783<pre> 825
826```yue
784func?! 827func?!
785print abc?["hello world"]?.xyz 828print abc?["hello world"]?.xyz
786 829
@@ -793,14 +836,15 @@ if print and x?
793with? io.open "test.txt", "w" 836with? io.open "test.txt", "w"
794 \write "hello" 837 \write "hello"
795 \close! 838 \close!
796</pre> 839```
840
797</YueDisplay> 841</YueDisplay>
798 842
799### Piping 843### Piping
800 844
801Instead of a series of nested function calls, you can pipe values with operator **|>**. 845Instead of a series of nested function calls, you can pipe values with operator **|>**.
802 846
803```moonscript 847```yuescript
804"hello" |> print 848"hello" |> print
8051 |> print 2 -- insert pipe item as the first argument 8491 |> print 2 -- insert pipe item as the first argument
8062 |> print 1, _, 3 -- pipe with a placeholder 8502 |> print 1, _, 3 -- pipe with a placeholder
@@ -814,7 +858,8 @@ readFile "example.txt"
814 |> print 858 |> print
815``` 859```
816<YueDisplay> 860<YueDisplay>
817<pre> 861
862```yue
818"hello" |> print 863"hello" |> print
8191 |> print 2 -- insert pipe item as the first argument 8641 |> print 2 -- insert pipe item as the first argument
8202 |> print 1, _, 3 -- pipe with a placeholder 8652 |> print 1, _, 3 -- pipe with a placeholder
@@ -825,13 +870,14 @@ readFile "example.txt"
825 |> emit 870 |> emit
826 |> render 871 |> render
827 |> print 872 |> print
828</pre> 873```
874
829</YueDisplay> 875</YueDisplay>
830 876
831### Nil Coalescing 877### Nil Coalescing
832 878
833The nil-coalescing operator **??** returns the value of its left-hand operand if it isn't **nil**; otherwise, it evaluates the right-hand operand and returns its result. The **??** operator doesn't evaluate its right-hand operand if the left-hand operand evaluates to non-nil. 879The nil-coalescing operator **??** returns the value of its left-hand operand if it isn't **nil**; otherwise, it evaluates the right-hand operand and returns its result. The **??** operator doesn't evaluate its right-hand operand if the left-hand operand evaluates to non-nil.
834```moonscript 880```yuescript
835local a, b, c, d 881local a, b, c, d
836a = b ?? c ?? d 882a = b ?? c ?? d
837func a ?? {} 883func a ?? {}
@@ -839,19 +885,21 @@ func a ?? {}
839a ??= false 885a ??= false
840``` 886```
841<YueDisplay> 887<YueDisplay>
842<pre> 888
889```yue
843local a, b, c, d 890local a, b, c, d
844a = b ?? c ?? d 891a = b ?? c ?? d
845func a ?? {} 892func a ?? {}
846a ??= false 893a ??= false
847</pre> 894```
895
848</YueDisplay> 896</YueDisplay>
849 897
850### Implicit Object 898### Implicit Object
851 899
852You 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. 900You 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.
853 901
854```moonscript 902```yuescript
855-- assignment with implicit object 903-- assignment with implicit object
856list = 904list =
857 * 1 905 * 1
@@ -894,7 +942,8 @@ tb =
894 942
895``` 943```
896<YueDisplay> 944<YueDisplay>
897<pre> 945
946```yue
898-- assignment with implicit object 947-- assignment with implicit object
899list = 948list =
900 * 1 949 * 1
@@ -934,7 +983,8 @@ tb =
934 value: 2 983 value: 2
935 func: => @value + 2 984 func: => @value + 2
936 tb: { } 985 tb: { }
937</pre> 986```
987
938</YueDisplay> 988</YueDisplay>
939 989
940## Module 990## Module
@@ -943,7 +993,7 @@ tb =
943 993
944The import statement is a syntax sugar for requiring a module or help extracting items from an imported module. The imported items are const by default. 994The import statement is a syntax sugar for requiring a module or help extracting items from an imported module. The imported items are const by default.
945 995
946```moonscript 996```yuescript
947-- used as table destructuring 997-- used as table destructuring
948do 998do
949 import insert, concat from table 999 import insert, concat from table
@@ -968,7 +1018,8 @@ do
968 import "export" as {one, two, Something:{umm:{ch}}} 1018 import "export" as {one, two, Something:{umm:{ch}}}
969``` 1019```
970<YueDisplay> 1020<YueDisplay>
971<pre> 1021
1022```yue
972-- used as table destructuring 1023-- used as table destructuring
973do 1024do
974 import insert, concat from table 1025 import insert, concat from table
@@ -991,26 +1042,29 @@ do
991 import "player" as PlayerModule 1042 import "player" as PlayerModule
992 import "lpeg" as :C, :Ct, :Cmt 1043 import "lpeg" as :C, :Ct, :Cmt
993 import "export" as {one, two, Something:{umm:{ch}}} 1044 import "export" as {one, two, Something:{umm:{ch}}}
994</pre> 1045```
1046
995</YueDisplay> 1047</YueDisplay>
996 1048
997### Import Global 1049### Import Global
998 1050
999You can import specific globals into local variables with `import`. When importing a chain of global variable accessings, the last field will be assigned to the local variable. 1051You can import specific globals into local variables with `import`. When importing a chain of global variable accessings, the last field will be assigned to the local variable.
1000 1052
1001```moonscript 1053```yuescript
1002do 1054do
1003 import tostring 1055 import tostring
1004 import table.concat 1056 import table.concat
1005 print concat ["a", tostring 1] 1057 print concat ["a", tostring 1]
1006``` 1058```
1007<YueDisplay> 1059<YueDisplay>
1008<pre> 1060
1061```yue
1009do 1062do
1010 import tostring 1063 import tostring
1011 import table.concat 1064 import table.concat
1012 print concat ["a", tostring 1] 1065 print concat ["a", tostring 1]
1013</pre> 1066```
1067
1014</YueDisplay> 1068</YueDisplay>
1015 1069
1016#### Automatic Import 1070#### Automatic Import
@@ -1019,7 +1073,7 @@ You can place `import global` at the top of a block to automatically import all
1019 1073
1020Names that are explicitly declared as globals in the same scope will not be imported, so you can still assign to them. 1074Names that are explicitly declared as globals in the same scope will not be imported, so you can still assign to them.
1021 1075
1022```moonscript 1076```yuescript
1023do 1077do
1024 import global 1078 import global
1025 print "hello" 1079 print "hello"
@@ -1034,7 +1088,8 @@ do
1034 FLAG = 123 1088 FLAG = 123
1035``` 1089```
1036<YueDisplay> 1090<YueDisplay>
1037<pre> 1091
1092```yue
1038do 1093do
1039 import global 1094 import global
1040 print "hello" 1095 print "hello"
@@ -1047,7 +1102,8 @@ do
1047 global FLAG 1102 global FLAG
1048 print FLAG 1103 print FLAG
1049 FLAG = 123 1104 FLAG = 123
1050</pre> 1105```
1106
1051</YueDisplay> 1107</YueDisplay>
1052 1108
1053### Export 1109### Export
@@ -1057,7 +1113,7 @@ The export statement offers a concise way to define modules.
1057* **Named Export** 1113* **Named Export**
1058Named export will define a local variable as well as adding a field in the exported table. 1114Named export will define a local variable as well as adding a field in the exported table.
1059 1115
1060```moonscript 1116```yuescript
1061export a, b, c = 1, 2, 3 1117export a, b, c = 1, 2, 3
1062export cool = "cat" 1118export cool = "cat"
1063 1119
@@ -1073,7 +1129,8 @@ export class Something
1073 umm: "cool" 1129 umm: "cool"
1074``` 1130```
1075<YueDisplay> 1131<YueDisplay>
1076<pre> 1132
1133```yue
1077export a, b, c = 1, 2, 3 1134export a, b, c = 1, 2, 3
1078export cool = "cat" 1135export cool = "cat"
1079 1136
@@ -1087,41 +1144,46 @@ export y = ->
1087 1144
1088export class Something 1145export class Something
1089 umm: "cool" 1146 umm: "cool"
1090</pre> 1147```
1148
1091</YueDisplay> 1149</YueDisplay>
1092 1150
1093Doing named export with destructuring. 1151Doing named export with destructuring.
1094 1152
1095```moonscript 1153```yuescript
1096export :loadstring, to_lua: tolua = yue 1154export :loadstring, to_lua: tolua = yue
1097export {itemA: {:fieldA = 'default'}} = tb 1155export {itemA: {:fieldA = 'default'}} = tb
1098``` 1156```
1099<YueDisplay> 1157<YueDisplay>
1100<pre> 1158
1159```yue
1101export :loadstring, to_lua: tolua = yue 1160export :loadstring, to_lua: tolua = yue
1102export {itemA: {:fieldA = 'default'}} = tb 1161export {itemA: {:fieldA = 'default'}} = tb
1103</pre> 1162```
1163
1104</YueDisplay> 1164</YueDisplay>
1105 1165
1106Export named items from module without creating local variables. 1166Export named items from module without creating local variables.
1107 1167
1108```moonscript 1168```yuescript
1109export.itemA = tb 1169export.itemA = tb
1110export.<index> = items 1170export.<index> = items
1111export["a-b-c"] = 123 1171export["a-b-c"] = 123
1112``` 1172```
1113<YueDisplay> 1173<YueDisplay>
1114<pre> 1174
1175```yue
1115export.itemA = tb 1176export.itemA = tb
1116export.&lt;index&gt; = items 1177export.<index> = items
1117export["a-b-c"] = 123 1178export["a-b-c"] = 123
1118</pre> 1179```
1180
1119</YueDisplay> 1181</YueDisplay>
1120 1182
1121* **Unnamed Export** 1183* **Unnamed Export**
1122Unnamed export will add the target item into the array part of the exported table. 1184Unnamed export will add the target item into the array part of the exported table.
1123 1185
1124```moonscript 1186```yuescript
1125d, e, f = 3, 2, 1 1187d, e, f = 3, 2, 1
1126export d, e, f 1188export d, e, f
1127 1189
@@ -1134,7 +1196,8 @@ export with tmp
1134 j = 2000 1196 j = 2000
1135``` 1197```
1136<YueDisplay> 1198<YueDisplay>
1137<pre> 1199
1200```yue
1138d, e, f = 3, 2, 1 1201d, e, f = 3, 2, 1
1139export d, e, f 1202export d, e, f
1140 1203
@@ -1145,46 +1208,51 @@ else
1145 1208
1146export with tmp 1209export with tmp
1147 j = 2000 1210 j = 2000
1148</pre> 1211```
1212
1149</YueDisplay> 1213</YueDisplay>
1150 1214
1151* **Default Export** 1215* **Default Export**
1152Using the **default** keyword in export statement to replace the exported table with any thing. 1216Using the **default** keyword in export statement to replace the exported table with any thing.
1153 1217
1154```moonscript 1218```yuescript
1155export default -> 1219export default ->
1156 print "hello" 1220 print "hello"
1157 123 1221 123
1158``` 1222```
1159<YueDisplay> 1223<YueDisplay>
1160<pre> 1224
1225```yue
1161export default -> 1226export default ->
1162 print "hello" 1227 print "hello"
1163 123 1228 123
1164</pre> 1229```
1230
1165</YueDisplay> 1231</YueDisplay>
1166 1232
1167## Assignment 1233## Assignment
1168 1234
1169The variable is dynamic typed and is defined as local by default. But you can change the scope of declaration by **local** and **global** statement. 1235The variable is dynamic typed and is defined as local by default. But you can change the scope of declaration by **local** and **global** statement.
1170 1236
1171```moonscript 1237```yuescript
1172hello = "world" 1238hello = "world"
1173a, b, c = 1, 2, 3 1239a, b, c = 1, 2, 3
1174hello = 123 -- uses the existing variable 1240hello = 123 -- uses the existing variable
1175``` 1241```
1176<YueDisplay> 1242<YueDisplay>
1177<pre> 1243
1244```yue
1178hello = "world" 1245hello = "world"
1179a, b, c = 1, 2, 3 1246a, b, c = 1, 2, 3
1180hello = 123 -- uses the existing variable 1247hello = 123 -- uses the existing variable
1181</pre> 1248```
1249
1182</YueDisplay> 1250</YueDisplay>
1183 1251
1184### Perform Update 1252### Perform Update
1185 1253
1186You can perform update assignment with many binary operators. 1254You can perform update assignment with many binary operators.
1187```moonscript 1255```yuescript
1188x = 1 1256x = 1
1189x += 1 1257x += 1
1190x -= 1 1258x -= 1
@@ -1195,7 +1263,8 @@ s ..= "world" -- will add a new local if local variable is not exist
1195arg or= "default value" 1263arg or= "default value"
1196``` 1264```
1197<YueDisplay> 1265<YueDisplay>
1198<pre> 1266
1267```yue
1199x = 1 1268x = 1
1200x += 1 1269x += 1
1201x -= 1 1270x -= 1
@@ -1204,25 +1273,28 @@ x /= 10
1204x %= 10 1273x %= 10
1205s ..= "world" -- will add a new local if local variable is not exist 1274s ..= "world" -- will add a new local if local variable is not exist
1206arg or= "default value" 1275arg or= "default value"
1207</pre> 1276```
1277
1208</YueDisplay> 1278</YueDisplay>
1209 1279
1210### Chaining Assignment 1280### Chaining Assignment
1211 1281
1212You can do chaining assignment to assign multiple items to hold the same value. 1282You can do chaining assignment to assign multiple items to hold the same value.
1213```moonscript 1283```yuescript
1214a = b = c = d = e = 0 1284a = b = c = d = e = 0
1215x = y = z = f! 1285x = y = z = f!
1216``` 1286```
1217<YueDisplay> 1287<YueDisplay>
1218<pre> 1288
1289```yue
1219a = b = c = d = e = 0 1290a = b = c = d = e = 0
1220x = y = z = f! 1291x = y = z = f!
1221</pre> 1292```
1293
1222</YueDisplay> 1294</YueDisplay>
1223 1295
1224### Explicit Locals 1296### Explicit Locals
1225```moonscript 1297```yuescript
1226do 1298do
1227 local a = 1 1299 local a = 1
1228 local * 1300 local *
@@ -1239,7 +1311,8 @@ do
1239 B = 2 1311 B = 2
1240``` 1312```
1241<YueDisplay> 1313<YueDisplay>
1242<pre> 1314
1315```yue
1243do 1316do
1244 local a = 1 1317 local a = 1
1245 local * 1318 local *
@@ -1254,11 +1327,12 @@ do
1254 print "only forward declare upper case variables" 1327 print "only forward declare upper case variables"
1255 a = 1 1328 a = 1
1256 B = 2 1329 B = 2
1257</pre> 1330```
1331
1258</YueDisplay> 1332</YueDisplay>
1259 1333
1260### Explicit Globals 1334### Explicit Globals
1261```moonscript 1335```yuescript
1262do 1336do
1263 global a = 1 1337 global a = 1
1264 global * 1338 global *
@@ -1275,7 +1349,8 @@ do
1275 local Temp = "a local value" 1349 local Temp = "a local value"
1276``` 1350```
1277<YueDisplay> 1351<YueDisplay>
1278<pre> 1352
1353```yue
1279do 1354do
1280 global a = 1 1355 global a = 1
1281 global * 1356 global *
@@ -1290,7 +1365,8 @@ do
1290 a = 1 1365 a = 1
1291 B = 2 1366 B = 2
1292 local Temp = "a local value" 1367 local Temp = "a local value"
1293</pre> 1368```
1369
1294</YueDisplay> 1370</YueDisplay>
1295 1371
1296## Destructuring Assignment 1372## Destructuring Assignment
@@ -1301,7 +1377,7 @@ Typically when you see a table literal, {1,2,3}, it is on the right hand side of
1301 1377
1302This is best explained with examples. Here is how you would unpack the first two values from a table: 1378This is best explained with examples. Here is how you would unpack the first two values from a table:
1303 1379
1304```moonscript 1380```yuescript
1305thing = [1, 2] 1381thing = [1, 2]
1306 1382
1307[a, b] = thing 1383[a, b] = thing
@@ -1309,17 +1385,18 @@ print a, b
1309``` 1385```
1310<YueDisplay> 1386<YueDisplay>
1311 1387
1312<pre> 1388```yue
1313thing = [1, 2] 1389thing = [1, 2]
1314 1390
1315[a, b] = thing 1391[a, b] = thing
1316print a, b 1392print a, b
1317</pre> 1393```
1394
1318</YueDisplay> 1395</YueDisplay>
1319 1396
1320In the destructuring table literal, the key represents the key to read from the right hand side, and the value represents the name the read value will be assigned to. 1397In the destructuring table literal, the key represents the key to read from the right hand side, and the value represents the name the read value will be assigned to.
1321 1398
1322```moonscript 1399```yuescript
1323obj = { 1400obj = {
1324 hello: "world" 1401 hello: "world"
1325 day: "tuesday" 1402 day: "tuesday"
@@ -1332,7 +1409,8 @@ print hello, the_day
1332:day = obj -- OK to do simple destructuring without braces 1409:day = obj -- OK to do simple destructuring without braces
1333``` 1410```
1334<YueDisplay> 1411<YueDisplay>
1335<pre> 1412
1413```yue
1336obj = { 1414obj = {
1337 hello: "world" 1415 hello: "world"
1338 day: "tuesday" 1416 day: "tuesday"
@@ -1343,12 +1421,13 @@ obj = {
1343print hello, the_day 1421print hello, the_day
1344 1422
1345:day = obj -- OK to do simple destructuring without braces 1423:day = obj -- OK to do simple destructuring without braces
1346</pre> 1424```
1425
1347</YueDisplay> 1426</YueDisplay>
1348 1427
1349This also works with nested data structures as well: 1428This also works with nested data structures as well:
1350 1429
1351```moonscript 1430```yuescript
1352obj2 = { 1431obj2 = {
1353 numbers: [1, 2, 3, 4] 1432 numbers: [1, 2, 3, 4]
1354 properties: { 1433 properties: {
@@ -1361,7 +1440,8 @@ obj2 = {
1361print first, second, color 1440print first, second, color
1362``` 1441```
1363<YueDisplay> 1442<YueDisplay>
1364<pre> 1443
1444```yue
1365obj2 = { 1445obj2 = {
1366 numbers: [1, 2, 3, 4] 1446 numbers: [1, 2, 3, 4]
1367 properties: { 1447 properties: {
@@ -1372,12 +1452,13 @@ obj2 = {
1372 1452
1373{numbers: [first, second]} = obj2 1453{numbers: [first, second]} = obj2
1374print first, second, color 1454print first, second, color
1375</pre> 1455```
1456
1376</YueDisplay> 1457</YueDisplay>
1377 1458
1378If the destructuring statement is complicated, feel free to spread it out over a few lines. A slightly more complicated example: 1459If the destructuring statement is complicated, feel free to spread it out over a few lines. A slightly more complicated example:
1379 1460
1380```moonscript 1461```yuescript
1381{ 1462{
1382 numbers: [first, second] 1463 numbers: [first, second]
1383 properties: { 1464 properties: {
@@ -1386,65 +1467,75 @@ If the destructuring statement is complicated, feel free to spread it out over a
1386} = obj2 1467} = obj2
1387``` 1468```
1388<YueDisplay> 1469<YueDisplay>
1389<pre> 1470
1471```yue
1390{ 1472{
1391 numbers: [first, second] 1473 numbers: [first, second]
1392 properties: { 1474 properties: {
1393 color: color 1475 color: color
1394 } 1476 }
1395} = obj2 1477} = obj2
1396</pre> 1478```
1479
1397</YueDisplay> 1480</YueDisplay>
1398 1481
1399It'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: 1482It'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:
1400 1483
1401```moonscript 1484```yuescript
1402{:concat, :insert} = table 1485{:concat, :insert} = table
1403``` 1486```
1404<YueDisplay> 1487<YueDisplay>
1405<pre> 1488
1489```yue
1406{:concat, :insert} = table 1490{:concat, :insert} = table
1407</pre> 1491```
1492
1408</YueDisplay> 1493</YueDisplay>
1409 1494
1410This is effectively the same as import, but we can rename fields we want to extract by mixing the syntax: 1495This is effectively the same as import, but we can rename fields we want to extract by mixing the syntax:
1411 1496
1412```moonscript 1497```yuescript
1413{:mix, :max, random: rand} = math 1498{:mix, :max, random: rand} = math
1414``` 1499```
1415<YueDisplay> 1500<YueDisplay>
1416<pre> 1501
1502```yue
1417{:mix, :max, random: rand} = math 1503{:mix, :max, random: rand} = math
1418</pre> 1504```
1505
1419</YueDisplay> 1506</YueDisplay>
1420 1507
1421You can write default values while doing destructuring like: 1508You can write default values while doing destructuring like:
1422 1509
1423```moonscript 1510```yuescript
1424{:name = "nameless", :job = "jobless"} = person 1511{:name = "nameless", :job = "jobless"} = person
1425``` 1512```
1426<YueDisplay> 1513<YueDisplay>
1427<pre> 1514
1515```yue
1428{:name = "nameless", :job = "jobless"} = person 1516{:name = "nameless", :job = "jobless"} = person
1429</pre> 1517```
1518
1430</YueDisplay> 1519</YueDisplay>
1431 1520
1432You can use `_` as placeholder when doing a list destructuring: 1521You can use `_` as placeholder when doing a list destructuring:
1433 1522
1434```moonscript 1523```yuescript
1435[_, two, _, four] = items 1524[_, two, _, four] = items
1436``` 1525```
1437<YueDisplay> 1526<YueDisplay>
1438<pre> 1527
1528```yue
1439[_, two, _, four] = items 1529[_, two, _, four] = items
1440</pre> 1530```
1531
1441</YueDisplay> 1532</YueDisplay>
1442 1533
1443### Range Destructuring 1534### Range Destructuring
1444 1535
1445You 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. 1536You 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.
1446 1537
1447```moonscript 1538```yuescript
1448orders = ["first", "second", "third", "fourth", "last"] 1539orders = ["first", "second", "third", "fourth", "last"]
1449[first, ...bulk, last] = orders 1540[first, ...bulk, last] = orders
1450print first -- prints: first 1541print first -- prints: first
@@ -1452,18 +1543,20 @@ print bulk -- prints: {"second", "third", "fourth"}
1452print last -- prints: last 1543print last -- prints: last
1453``` 1544```
1454<YueDisplay> 1545<YueDisplay>
1455<pre> 1546
1547```yue
1456orders = ["first", "second", "third", "fourth", "last"] 1548orders = ["first", "second", "third", "fourth", "last"]
1457[first, ...bulk, last] = orders 1549[first, ...bulk, last] = orders
1458print first -- prints: first 1550print first -- prints: first
1459print bulk -- prints: {"second", "third", "fourth"} 1551print bulk -- prints: {"second", "third", "fourth"}
1460print last -- prints: last 1552print last -- prints: last
1461</pre> 1553```
1554
1462</YueDisplay> 1555</YueDisplay>
1463 1556
1464The 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: 1557The 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:
1465 1558
1466```moonscript 1559```yuescript
1467-- Capture everything after first element 1560-- Capture everything after first element
1468[first, ...rest] = orders 1561[first, ...rest] = orders
1469 1562
@@ -1474,7 +1567,8 @@ The spread operator can be used in different positions to capture different rang
1474[first, ..._, last] = orders 1567[first, ..._, last] = orders
1475``` 1568```
1476<YueDisplay> 1569<YueDisplay>
1477<pre> 1570
1571```yue
1478-- Capture everything after first element 1572-- Capture everything after first element
1479[first, ...rest] = orders 1573[first, ...rest] = orders
1480 1574
@@ -1483,14 +1577,15 @@ The spread operator can be used in different positions to capture different rang
1483 1577
1484-- Capture things except the middle elements 1578-- Capture things except the middle elements
1485[first, ..._, last] = orders 1579[first, ..._, last] = orders
1486</pre> 1580```
1581
1487</YueDisplay> 1582</YueDisplay>
1488 1583
1489### Destructuring In Other Places 1584### Destructuring In Other Places
1490 1585
1491Destructuring can also show up in places where an assignment implicitly takes place. An example of this is a for loop: 1586Destructuring can also show up in places where an assignment implicitly takes place. An example of this is a for loop:
1492 1587
1493```moonscript 1588```yuescript
1494tuples = [ 1589tuples = [
1495 ["hello", "world"] 1590 ["hello", "world"]
1496 ["egg", "head"] 1591 ["egg", "head"]
@@ -1500,7 +1595,8 @@ for [left, right] in *tuples
1500 print left, right 1595 print left, right
1501``` 1596```
1502<YueDisplay> 1597<YueDisplay>
1503<pre> 1598
1599```yue
1504tuples = [ 1600tuples = [
1505 ["hello", "world"] 1601 ["hello", "world"]
1506 ["egg", "head"] 1602 ["egg", "head"]
@@ -1508,7 +1604,8 @@ tuples = [
1508 1604
1509for [left, right] in *tuples 1605for [left, right] in *tuples
1510 print left, right 1606 print left, right
1511</pre> 1607```
1608
1512</YueDisplay> 1609</YueDisplay>
1513 1610
1514We know each element in the array table is a two item tuple, so we can unpack it directly in the names clause of the for statement using a destructure. 1611We know each element in the array table is a two item tuple, so we can unpack it directly in the names clause of the for statement using a destructure.
@@ -1517,18 +1614,20 @@ We know each element in the array table is a two item tuple, so we can unpack it
1517 1614
1518`if` and `elseif` blocks can take an assignment in place of a conditional expression. Upon evaluating the conditional, the assignment will take place and the value that was assigned to will be used as the conditional expression. The assigned variable is only in scope for the body of the conditional, meaning it is never available if the value is not truthy. And you have to use "the walrus operator" `:=` instead of `=` to do assignment. 1615`if` and `elseif` blocks can take an assignment in place of a conditional expression. Upon evaluating the conditional, the assignment will take place and the value that was assigned to will be used as the conditional expression. The assigned variable is only in scope for the body of the conditional, meaning it is never available if the value is not truthy. And you have to use "the walrus operator" `:=` instead of `=` to do assignment.
1519 1616
1520```moonscript 1617```yuescript
1521if user := database.find_user "moon" 1618if user := database.find_user "moon"
1522 print user.name 1619 print user.name
1523``` 1620```
1524<YueDisplay> 1621<YueDisplay>
1525<pre> 1622
1623```yue
1526if user := database.find_user "moon" 1624if user := database.find_user "moon"
1527 print user.name 1625 print user.name
1528</pre> 1626```
1627
1529</YueDisplay> 1628</YueDisplay>
1530 1629
1531```moonscript 1630```yuescript
1532if hello := os.getenv "hello" 1631if hello := os.getenv "hello"
1533 print "You have hello", hello 1632 print "You have hello", hello
1534elseif world := os.getenv "world" 1633elseif world := os.getenv "world"
@@ -1537,50 +1636,56 @@ else
1537 print "nothing :(" 1636 print "nothing :("
1538``` 1637```
1539<YueDisplay> 1638<YueDisplay>
1540<pre> 1639
1640```yue
1541if hello := os.getenv "hello" 1641if hello := os.getenv "hello"
1542 print "You have hello", hello 1642 print "You have hello", hello
1543elseif world := os.getenv "world" 1643elseif world := os.getenv "world"
1544 print "you have world", world 1644 print "you have world", world
1545else 1645else
1546 print "nothing :(" 1646 print "nothing :("
1547</pre> 1647```
1648
1548</YueDisplay> 1649</YueDisplay>
1549 1650
1550If assignment with multiple return values. Only the first value is getting checked, other values are scoped. 1651If assignment with multiple return values. Only the first value is getting checked, other values are scoped.
1551```moonscript 1652```yuescript
1552if success, result := pcall -> "get result without problems" 1653if success, result := pcall -> "get result without problems"
1553 print result -- variable result is scoped 1654 print result -- variable result is scoped
1554print "OK" 1655print "OK"
1555``` 1656```
1556<YueDisplay> 1657<YueDisplay>
1557<pre> 1658
1659```yue
1558if success, result := pcall -> "get result without problems" 1660if success, result := pcall -> "get result without problems"
1559 print result -- variable result is scoped 1661 print result -- variable result is scoped
1560print "OK" 1662print "OK"
1561</pre> 1663```
1664
1562</YueDisplay> 1665</YueDisplay>
1563 1666
1564### While Assignment 1667### While Assignment
1565 1668
1566You can also use if assignment in a while loop to get the value as the loop condition. 1669You can also use if assignment in a while loop to get the value as the loop condition.
1567```moonscript 1670```yuescript
1568while byte := stream\read_one! 1671while byte := stream\read_one!
1569 -- do something with the byte 1672 -- do something with the byte
1570 print byte 1673 print byte
1571``` 1674```
1572<YueDisplay> 1675<YueDisplay>
1573<pre> 1676
1677```yue
1574while byte := stream\read_one! 1678while byte := stream\read_one!
1575 -- do something with the byte 1679 -- do something with the byte
1576 print byte 1680 print byte
1577</pre> 1681```
1682
1578</YueDisplay> 1683</YueDisplay>
1579 1684
1580## Varargs Assignment 1685## Varargs Assignment
1581 1686
1582You can assign the results returned from a function to a varargs symbol `...`. And then access its content using the Lua way. 1687You can assign the results returned from a function to a varargs symbol `...`. And then access its content using the Lua way.
1583```moonscript 1688```yuescript
1584list = [1, 2, 3, 4, 5] 1689list = [1, 2, 3, 4, 5]
1585fn = (ok) -> ok, table.unpack list 1690fn = (ok) -> ok, table.unpack list
1586ok, ... = fn true 1691ok, ... = fn true
@@ -1589,14 +1694,16 @@ first = select 1, ...
1589print ok, count, first 1694print ok, count, first
1590``` 1695```
1591<YueDisplay> 1696<YueDisplay>
1592<pre> 1697
1698```yue
1593list = [1, 2, 3, 4, 5] 1699list = [1, 2, 3, 4, 5]
1594fn = (ok) -> ok, table.unpack list 1700fn = (ok) -> ok, table.unpack list
1595ok, ... = fn true 1701ok, ... = fn true
1596count = select '#', ... 1702count = select '#', ...
1597first = select 1, ... 1703first = select 1, ...
1598print ok, count, first 1704print ok, count, first
1599</pre> 1705```
1706
1600</YueDisplay> 1707</YueDisplay>
1601 1708
1602## Whitespace 1709## Whitespace
@@ -1607,19 +1714,21 @@ YueScript is a whitespace significant language. You have to write some code bloc
1607 1714
1608A statement normally ends at a line break. You can also use a semicolon `;` to explicitly terminate a statement, which allows writing multiple statements on the same line: 1715A statement normally ends at a line break. You can also use a semicolon `;` to explicitly terminate a statement, which allows writing multiple statements on the same line:
1609 1716
1610```moonscript 1717```yuescript
1611a = 1; b = 2; print a + b 1718a = 1; b = 2; print a + b
1612``` 1719```
1613<YueDisplay> 1720<YueDisplay>
1614<pre> 1721
1722```yue
1615a = 1; b = 2; print a + b 1723a = 1; b = 2; print a + b
1616</pre> 1724```
1725
1617</YueDisplay> 1726</YueDisplay>
1618 1727
1619### Multiline Chaining 1728### Multiline Chaining
1620 1729
1621You can write multi-line chaining function calls with a same indent. 1730You can write multi-line chaining function calls with a same indent.
1622```moonscript 1731```yuescript
1623Rx.Observable 1732Rx.Observable
1624 .fromRange 1, 8 1733 .fromRange 1, 8
1625 \filter (x) -> x % 2 == 0 1734 \filter (x) -> x % 2 == 0
@@ -1628,19 +1737,21 @@ Rx.Observable
1628 \subscribe print 1737 \subscribe print
1629``` 1738```
1630<YueDisplay> 1739<YueDisplay>
1631<pre> 1740
1741```yue
1632Rx.Observable 1742Rx.Observable
1633 .fromRange 1, 8 1743 .fromRange 1, 8
1634 \filter (x) -> x % 2 == 0 1744 \filter (x) -> x % 2 == 0
1635 \concat Rx.Observable.of 'who do we appreciate' 1745 \concat Rx.Observable.of 'who do we appreciate'
1636 \map (value) -> value .. '!' 1746 \map (value) -> value .. '!'
1637 \subscribe print 1747 \subscribe print
1638</pre> 1748```
1749
1639</YueDisplay> 1750</YueDisplay>
1640 1751
1641## Comment 1752## Comment
1642 1753
1643```moonscript 1754```yuescript
1644-- I am a comment 1755-- I am a comment
1645 1756
1646str = --[[ 1757str = --[[
@@ -1653,7 +1764,8 @@ It's OK.
1653func --[[port]] 3000, --[[ip]] "192.168.1.1" 1764func --[[port]] 3000, --[[ip]] "192.168.1.1"
1654``` 1765```
1655<YueDisplay> 1766<YueDisplay>
1656<pre> 1767
1768```yue
1657-- I am a comment 1769-- I am a comment
1658 1770
1659str = --[[ 1771str = --[[
@@ -1664,14 +1776,15 @@ It's OK.
1664 .. strC 1776 .. strC
1665 1777
1666func --[[port]] 3000, --[[ip]] "192.168.1.1" 1778func --[[port]] 3000, --[[ip]] "192.168.1.1"
1667</pre> 1779```
1780
1668</YueDisplay> 1781</YueDisplay>
1669 1782
1670## Try 1783## Try
1671 1784
1672The syntax for Lua error handling in a common form. 1785The syntax for Lua error handling in a common form.
1673 1786
1674```moonscript 1787```yuescript
1675try 1788try
1676 func 1, 2, 3 1789 func 1, 2, 3
1677catch err 1790catch err
@@ -1699,7 +1812,8 @@ catch err
1699 print result 1812 print result
1700``` 1813```
1701<YueDisplay> 1814<YueDisplay>
1702<pre> 1815
1816```yue
1703try 1817try
1704 func 1, 2, 3 1818 func 1, 2, 3
1705catch err 1819catch err
@@ -1725,14 +1839,15 @@ if success, result := try func 1, 2, 3
1725catch err 1839catch err
1726 print yue.traceback err 1840 print yue.traceback err
1727 print result 1841 print result
1728</pre> 1842```
1843
1729</YueDisplay> 1844</YueDisplay>
1730 1845
1731### Try? 1846### Try?
1732 1847
1733`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. 1848`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.
1734 1849
1735```moonscript 1850```yuescript
1736a, b, c = try? func! 1851a, b, c = try? func!
1737 1852
1738-- with nil coalescing operator 1853-- with nil coalescing operator
@@ -1750,7 +1865,8 @@ catch e
1750 e 1865 e
1751``` 1866```
1752<YueDisplay> 1867<YueDisplay>
1753<pre> 1868
1869```yue
1754a, b, c = try? func! 1870a, b, c = try? func!
1755 1871
1756-- with nil coalescing operator 1872-- with nil coalescing operator
@@ -1766,48 +1882,55 @@ f try?
1766catch e 1882catch e
1767 print e 1883 print e
1768 e 1884 e
1769</pre> 1885```
1886
1770</YueDisplay> 1887</YueDisplay>
1771 1888
1772## Attributes 1889## Attributes
1773 1890
1774Syntax 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. 1891Syntax 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.
1775 1892
1776```moonscript 1893```yuescript
1777const a = 123 1894const a = 123
1778close _ = <close>: -> print "Out of scope." 1895close _ = <close>: -> print "Out of scope."
1779``` 1896```
1780<YueDisplay> 1897<YueDisplay>
1781<pre> 1898
1899```yue
1782const a = 123 1900const a = 123
1783close _ = &lt;close&gt;: -> print "Out of scope." 1901close _ = <close>: -> print "Out of scope."
1784</pre> 1902```
1903
1785</YueDisplay> 1904</YueDisplay>
1786 1905
1787You can do desctructuring with variables attributed as constant. 1906You can do desctructuring with variables attributed as constant.
1788 1907
1789```moonscript 1908```yuescript
1790const {:a, :b, c, d} = tb 1909const {:a, :b, c, d} = tb
1791-- a = 1 1910-- a = 1
1792``` 1911```
1793<YueDisplay> 1912<YueDisplay>
1794<pre> 1913
1914```yue
1795const {:a, :b, c, d} = tb 1915const {:a, :b, c, d} = tb
1796-- a = 1 1916-- a = 1
1797</pre> 1917```
1918
1798</YueDisplay> 1919</YueDisplay>
1799 1920
1800You can also declare a global variable to be `const`. 1921You can also declare a global variable to be `const`.
1801 1922
1802```moonscript 1923```yuescript
1803global const Constant = 123 1924global const Constant = 123
1804-- Constant = 1 1925-- Constant = 1
1805``` 1926```
1806<YueDisplay> 1927<YueDisplay>
1807<pre> 1928
1929```yue
1808global const Constant = 123 1930global const Constant = 123
1809-- Constant = 1 1931-- Constant = 1
1810</pre> 1932```
1933
1811</YueDisplay> 1934</YueDisplay>
1812 1935
1813## Literals 1936## Literals
@@ -1816,7 +1939,7 @@ All of the primitive literals in Lua can be used. This applies to numbers, strin
1816 1939
1817Unlike Lua, Line breaks are allowed inside of single and double quote strings without an escape sequence: 1940Unlike Lua, Line breaks are allowed inside of single and double quote strings without an escape sequence:
1818 1941
1819```moonscript 1942```yuescript
1820some_string = "Here is a string 1943some_string = "Here is a string
1821 that has a line break in it." 1944 that has a line break in it."
1822 1945
@@ -1825,39 +1948,42 @@ some_string = "Here is a string
1825print "I am #{math.random! * 100}% sure." 1948print "I am #{math.random! * 100}% sure."
1826``` 1949```
1827<YueDisplay> 1950<YueDisplay>
1828<pre> 1951
1952```yue
1829some_string = "Here is a string 1953some_string = "Here is a string
1830 that has a line break in it." 1954 that has a line break in it."
1831 1955
1832-- You can mix expressions into string literals using #{} syntax. 1956-- You can mix expressions into string literals using #{} syntax.
1833-- String interpolation is only available in double quoted strings. 1957-- String interpolation is only available in double quoted strings.
1834print "I am #{math.random! * 100}% sure." 1958print "I am #{math.random! * 100}% sure."
1835</pre> 1959```
1960
1836</YueDisplay> 1961</YueDisplay>
1837 1962
1838### Number Literals 1963### Number Literals
1839 1964
1840You can use underscores in a number literal to increase readability. 1965You can use underscores in a number literal to increase readability.
1841 1966
1842```moonscript 1967```yuescript
1843integer = 1_000_000 1968integer = 1_000_000
1844hex = 0xEF_BB_BF 1969hex = 0xEF_BB_BF
1845binary = 0B10011 1970binary = 0B10011
1846``` 1971```
1847<YueDisplay> 1972<YueDisplay>
1848 1973
1849<pre> 1974```yue
1850integer = 1_000_000 1975integer = 1_000_000
1851hex = 0xEF_BB_BF 1976hex = 0xEF_BB_BF
1852binary = 0B10011 1977binary = 0B10011
1853</pre> 1978```
1979
1854</YueDisplay> 1980</YueDisplay>
1855 1981
1856### YAML Multiline String 1982### YAML Multiline String
1857 1983
1858The `|` prefix introduces a YAML-style multiline string literal: 1984The `|` prefix introduces a YAML-style multiline string literal:
1859 1985
1860```moonscript 1986```yuescript
1861str = | 1987str = |
1862 key: value 1988 key: value
1863 list: 1989 list:
@@ -1865,20 +1991,22 @@ str = |
1865 - #{expr} 1991 - #{expr}
1866``` 1992```
1867<YueDisplay> 1993<YueDisplay>
1868<pre> 1994
1995```yue
1869str = | 1996str = |
1870 key: value 1997 key: value
1871 list: 1998 list:
1872 - item1 1999 - item1
1873 - #{expr} 2000 - #{expr}
1874</pre> 2001```
2002
1875</YueDisplay> 2003</YueDisplay>
1876 2004
1877This 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)`. 2005This 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)`.
1878 2006
1879YAML 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. 2007YAML 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.
1880 2008
1881```moonscript 2009```yuescript
1882fn = -> 2010fn = ->
1883 str = | 2011 str = |
1884 foo: 2012 foo:
@@ -1886,50 +2014,56 @@ fn = ->
1886 return str 2014 return str
1887``` 2015```
1888<YueDisplay> 2016<YueDisplay>
1889<pre> 2017
2018```yue
1890fn = -> 2019fn = ->
1891 str = | 2020 str = |
1892 foo: 2021 foo:
1893 bar: baz 2022 bar: baz
1894 return str 2023 return str
1895</pre> 2024```
2025
1896</YueDisplay> 2026</YueDisplay>
1897 2027
1898Internal indentation is preserved relative to the removed common prefix, allowing clean nested structures. 2028Internal indentation is preserved relative to the removed common prefix, allowing clean nested structures.
1899 2029
1900All 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. 2030All 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.
1901 2031
1902```moonscript 2032```yuescript
1903str = | 2033str = |
1904 path: "C:\Program Files\App" 2034 path: "C:\Program Files\App"
1905 note: 'He said: "#{Hello}!"' 2035 note: 'He said: "#{Hello}!"'
1906``` 2036```
1907<YueDisplay> 2037<YueDisplay>
1908<pre> 2038
2039```yue
1909str = | 2040str = |
1910 path: "C:\Program Files\App" 2041 path: "C:\Program Files\App"
1911 note: 'He said: "#{Hello}!"' 2042 note: 'He said: "#{Hello}!"'
1912</pre> 2043```
2044
1913</YueDisplay> 2045</YueDisplay>
1914 2046
1915## Function Literals 2047## Function Literals
1916 2048
1917All functions are created using a function expression. A simple function is denoted using the arrow: **->**. 2049All functions are created using a function expression. A simple function is denoted using the arrow: **->**.
1918 2050
1919```moonscript 2051```yuescript
1920my_function = -> 2052my_function = ->
1921my_function() -- call the empty function 2053my_function() -- call the empty function
1922``` 2054```
1923<YueDisplay> 2055<YueDisplay>
1924<pre> 2056
2057```yue
1925my_function = -> 2058my_function = ->
1926my_function() -- call the empty function 2059my_function() -- call the empty function
1927</pre> 2060```
2061
1928</YueDisplay> 2062</YueDisplay>
1929 2063
1930The body of the function can either be one statement placed directly after the arrow, or it can be a series of statements indented on the following lines: 2064The body of the function can either be one statement placed directly after the arrow, or it can be a series of statements indented on the following lines:
1931 2065
1932```moonscript 2066```yuescript
1933func_a = -> print "hello world" 2067func_a = -> print "hello world"
1934 2068
1935func_b = -> 2069func_b = ->
@@ -1937,147 +2071,169 @@ func_b = ->
1937 print "The value:", value 2071 print "The value:", value
1938``` 2072```
1939<YueDisplay> 2073<YueDisplay>
1940<pre> 2074
2075```yue
1941func_a = -> print "hello world" 2076func_a = -> print "hello world"
1942 2077
1943func_b = -> 2078func_b = ->
1944 value = 100 2079 value = 100
1945 print "The value:", value 2080 print "The value:", value
1946</pre> 2081```
2082
1947</YueDisplay> 2083</YueDisplay>
1948 2084
1949If a function has no arguments, it can be called using the ! operator, instead of empty parentheses. The ! invocation is the preferred way to call functions with no arguments. 2085If a function has no arguments, it can be called using the ! operator, instead of empty parentheses. The ! invocation is the preferred way to call functions with no arguments.
1950 2086
1951```moonscript 2087```yuescript
1952func_a! 2088func_a!
1953func_b() 2089func_b()
1954``` 2090```
1955<YueDisplay> 2091<YueDisplay>
1956<pre> 2092
2093```yue
1957func_a! 2094func_a!
1958func_b() 2095func_b()
1959</pre> 2096```
2097
1960</YueDisplay> 2098</YueDisplay>
1961 2099
1962Functions with arguments can be created by preceding the arrow with a list of argument names in parentheses: 2100Functions with arguments can be created by preceding the arrow with a list of argument names in parentheses:
1963 2101
1964```moonscript 2102```yuescript
1965sum = (x, y) -> print "sum", x + y 2103sum = (x, y) -> print "sum", x + y
1966``` 2104```
1967<YueDisplay> 2105<YueDisplay>
1968<pre> 2106
2107```yue
1969sum = (x, y) -> print "sum", x + y 2108sum = (x, y) -> print "sum", x + y
1970</pre> 2109```
2110
1971</YueDisplay> 2111</YueDisplay>
1972 2112
1973Functions can be called by listing the arguments after the name of an expression that evaluates to a function. When chaining together function calls, the arguments are applied to the closest function to the left. 2113Functions can be called by listing the arguments after the name of an expression that evaluates to a function. When chaining together function calls, the arguments are applied to the closest function to the left.
1974 2114
1975```moonscript 2115```yuescript
1976sum 10, 20 2116sum 10, 20
1977print sum 10, 20 2117print sum 10, 20
1978 2118
1979a b c "a", "b", "c" 2119a b c "a", "b", "c"
1980``` 2120```
1981<YueDisplay> 2121<YueDisplay>
1982<pre> 2122
2123```yue
1983sum 10, 20 2124sum 10, 20
1984print sum 10, 20 2125print sum 10, 20
1985 2126
1986a b c "a", "b", "c" 2127a b c "a", "b", "c"
1987</pre> 2128```
2129
1988</YueDisplay> 2130</YueDisplay>
1989 2131
1990In order to avoid ambiguity in when calling functions, parentheses can also be used to surround the arguments. This is required here in order to make sure the right arguments get sent to the right functions. 2132In order to avoid ambiguity in when calling functions, parentheses can also be used to surround the arguments. This is required here in order to make sure the right arguments get sent to the right functions.
1991 2133
1992```moonscript 2134```yuescript
1993print "x:", sum(10, 20), "y:", sum(30, 40) 2135print "x:", sum(10, 20), "y:", sum(30, 40)
1994``` 2136```
1995<YueDisplay> 2137<YueDisplay>
1996<pre> 2138
2139```yue
1997print "x:", sum(10, 20), "y:", sum(30, 40) 2140print "x:", sum(10, 20), "y:", sum(30, 40)
1998</pre> 2141```
2142
1999</YueDisplay> 2143</YueDisplay>
2000 2144
2001There must not be any space between the opening parenthesis and the function. 2145There must not be any space between the opening parenthesis and the function.
2002 2146
2003Functions will coerce the last statement in their body into a return statement, this is called implicit return: 2147Functions will coerce the last statement in their body into a return statement, this is called implicit return:
2004 2148
2005```moonscript 2149```yuescript
2006sum = (x, y) -> x + y 2150sum = (x, y) -> x + y
2007print "The sum is ", sum 10, 20 2151print "The sum is ", sum 10, 20
2008``` 2152```
2009<YueDisplay> 2153<YueDisplay>
2010<pre> 2154
2155```yue
2011sum = (x, y) -> x + y 2156sum = (x, y) -> x + y
2012print "The sum is ", sum 10, 20 2157print "The sum is ", sum 10, 20
2013</pre> 2158```
2159
2014</YueDisplay> 2160</YueDisplay>
2015 2161
2016And if you need to explicitly return, you can use the return keyword: 2162And if you need to explicitly return, you can use the return keyword:
2017 2163
2018```moonscript 2164```yuescript
2019sum = (x, y) -> return x + y 2165sum = (x, y) -> return x + y
2020``` 2166```
2021<YueDisplay> 2167<YueDisplay>
2022<pre> 2168
2169```yue
2023sum = (x, y) -> return x + y 2170sum = (x, y) -> return x + y
2024</pre> 2171```
2172
2025</YueDisplay> 2173</YueDisplay>
2026 2174
2027Just like in Lua, functions can return multiple values. The last statement must be a list of values separated by commas: 2175Just like in Lua, functions can return multiple values. The last statement must be a list of values separated by commas:
2028 2176
2029```moonscript 2177```yuescript
2030mystery = (x, y) -> x + y, x - y 2178mystery = (x, y) -> x + y, x - y
2031a, b = mystery 10, 20 2179a, b = mystery 10, 20
2032``` 2180```
2033<YueDisplay> 2181<YueDisplay>
2034<pre> 2182
2183```yue
2035mystery = (x, y) -> x + y, x - y 2184mystery = (x, y) -> x + y, x - y
2036a, b = mystery 10, 20 2185a, b = mystery 10, 20
2037</pre> 2186```
2187
2038</YueDisplay> 2188</YueDisplay>
2039 2189
2040### Fat Arrows 2190### Fat Arrows
2041 2191
2042Because it is an idiom in Lua to send an object as the first argument when calling a method, a special syntax is provided for creating functions which automatically includes a self argument. 2192Because it is an idiom in Lua to send an object as the first argument when calling a method, a special syntax is provided for creating functions which automatically includes a self argument.
2043 2193
2044```moonscript 2194```yuescript
2045func = (num) => @value + num 2195func = (num) => @value + num
2046``` 2196```
2047<YueDisplay> 2197<YueDisplay>
2048<pre> 2198
2199```yue
2049func = (num) => @value + num 2200func = (num) => @value + num
2050</pre> 2201```
2202
2051</YueDisplay> 2203</YueDisplay>
2052 2204
2053### Argument Defaults 2205### Argument Defaults
2054 2206
2055It is possible to provide default values for the arguments of a function. An argument is determined to be empty if its value is nil. Any nil arguments that have a default value will be replace before the body of the function is run. 2207It is possible to provide default values for the arguments of a function. An argument is determined to be empty if its value is nil. Any nil arguments that have a default value will be replace before the body of the function is run.
2056 2208
2057```moonscript 2209```yuescript
2058my_function = (name = "something", height = 100) -> 2210my_function = (name = "something", height = 100) ->
2059 print "Hello I am", name 2211 print "Hello I am", name
2060 print "My height is", height 2212 print "My height is", height
2061``` 2213```
2062<YueDisplay> 2214<YueDisplay>
2063<pre> 2215
2216```yue
2064my_function = (name = "something", height = 100) -> 2217my_function = (name = "something", height = 100) ->
2065 print "Hello I am", name 2218 print "Hello I am", name
2066 print "My height is", height 2219 print "My height is", height
2067</pre> 2220```
2221
2068</YueDisplay> 2222</YueDisplay>
2069 2223
2070An argument default value expression is evaluated in the body of the function in the order of the argument declarations. For this reason default values have access to previously declared arguments. 2224An argument default value expression is evaluated in the body of the function in the order of the argument declarations. For this reason default values have access to previously declared arguments.
2071 2225
2072```moonscript 2226```yuescript
2073some_args = (x = 100, y = x + 1000) -> 2227some_args = (x = 100, y = x + 1000) ->
2074 print x + y 2228 print x + y
2075``` 2229```
2076<YueDisplay> 2230<YueDisplay>
2077<pre> 2231
2232```yue
2078some_args = (x = 100, y = x + 1000) -> 2233some_args = (x = 100, y = x + 1000) ->
2079 print x + y 2234 print x + y
2080</pre> 2235```
2236
2081</YueDisplay> 2237</YueDisplay>
2082 2238
2083### Considerations 2239### Considerations
@@ -2086,19 +2242,21 @@ Because of the expressive parentheses-less way of calling functions, some restri
2086 2242
2087The minus sign plays two roles, a unary negation operator and a binary subtraction operator. Consider how the following examples compile: 2243The minus sign plays two roles, a unary negation operator and a binary subtraction operator. Consider how the following examples compile:
2088 2244
2089```moonscript 2245```yuescript
2090a = x - 10 2246a = x - 10
2091b = x-10 2247b = x-10
2092c = x -y 2248c = x -y
2093d = x- z 2249d = x- z
2094``` 2250```
2095<YueDisplay> 2251<YueDisplay>
2096<pre> 2252
2253```yue
2097a = x - 10 2254a = x - 10
2098b = x-10 2255b = x-10
2099c = x -y 2256c = x -y
2100d = x- z 2257d = x- z
2101</pre> 2258```
2259
2102</YueDisplay> 2260</YueDisplay>
2103 2261
2104The precedence of the first argument of a function call can be controlled using whitespace if the argument is a literal string. In Lua, it is common to leave off parentheses when calling a function with a single string or table literal. 2262The precedence of the first argument of a function call can be controlled using whitespace if the argument is a literal string. In Lua, it is common to leave off parentheses when calling a function with a single string or table literal.
@@ -2107,15 +2265,17 @@ When there is no space between a variable and a string literal, the function cal
2107 2265
2108Where there is a space following a variable and a string literal, the function call acts as show above. The string literal belongs to any following expressions (if they exist), which serves as the argument list. 2266Where there is a space following a variable and a string literal, the function call acts as show above. The string literal belongs to any following expressions (if they exist), which serves as the argument list.
2109 2267
2110```moonscript 2268```yuescript
2111x = func"hello" + 100 2269x = func"hello" + 100
2112y = func "hello" + 100 2270y = func "hello" + 100
2113``` 2271```
2114<YueDisplay> 2272<YueDisplay>
2115<pre> 2273
2274```yue
2116x = func"hello" + 100 2275x = func"hello" + 100
2117y = func "hello" + 100 2276y = func "hello" + 100
2118</pre> 2277```
2278
2119</YueDisplay> 2279</YueDisplay>
2120 2280
2121### Multi-line arguments 2281### Multi-line arguments
@@ -2124,7 +2284,7 @@ When calling functions that take a large number of arguments, it is convenient t
2124 2284
2125If an argument list is to be continued onto the next line, the current line must end in a comma. And the following line must be indented more than the current indentation. Once indented, all other argument lines must be at the same level of indentation to be part of the argument list 2285If an argument list is to be continued onto the next line, the current line must end in a comma. And the following line must be indented more than the current indentation. Once indented, all other argument lines must be at the same level of indentation to be part of the argument list
2126 2286
2127```moonscript 2287```yuescript
2128my_func 5, 4, 3, 2288my_func 5, 4, 3,
2129 8, 9, 10 2289 8, 9, 10
2130 2290
@@ -2134,7 +2294,8 @@ cool_func 1, 2,
2134 7, 8 2294 7, 8
2135``` 2295```
2136<YueDisplay> 2296<YueDisplay>
2137<pre> 2297
2298```yue
2138my_func 5, 4, 3, 2299my_func 5, 4, 3,
2139 8, 9, 10 2300 8, 9, 10
2140 2301
@@ -2142,29 +2303,32 @@ cool_func 1, 2,
2142 3, 4, 2303 3, 4,
2143 5, 6, 2304 5, 6,
2144 7, 8 2305 7, 8
2145</pre> 2306```
2307
2146</YueDisplay> 2308</YueDisplay>
2147 2309
2148This type of invocation can be nested. The level of indentation is used to determine to which function the arguments belong to. 2310This type of invocation can be nested. The level of indentation is used to determine to which function the arguments belong to.
2149 2311
2150```moonscript 2312```yuescript
2151my_func 5, 6, 7, 2313my_func 5, 6, 7,
2152 6, another_func 6, 7, 8, 2314 6, another_func 6, 7, 8,
2153 9, 1, 2, 2315 9, 1, 2,
2154 5, 4 2316 5, 4
2155``` 2317```
2156<YueDisplay> 2318<YueDisplay>
2157<pre> 2319
2320```yue
2158my_func 5, 6, 7, 2321my_func 5, 6, 7,
2159 6, another_func 6, 7, 8, 2322 6, another_func 6, 7, 8,
2160 9, 1, 2, 2323 9, 1, 2,
2161 5, 4 2324 5, 4
2162</pre> 2325```
2326
2163</YueDisplay> 2327</YueDisplay>
2164 2328
2165Because tables also use the comma as a delimiter, this indentation syntax is helpful for letting values be part of the argument list instead of being part of the table. 2329Because tables also use the comma as a delimiter, this indentation syntax is helpful for letting values be part of the argument list instead of being part of the table.
2166 2330
2167```moonscript 2331```yuescript
2168x = [ 2332x = [
2169 1, 2, 3, 4, a_func 4, 5, 2333 1, 2, 3, 4, a_func 4, 5,
2170 5, 6, 2334 5, 6,
@@ -2172,35 +2336,39 @@ x = [
2172] 2336]
2173``` 2337```
2174<YueDisplay> 2338<YueDisplay>
2175<pre> 2339
2340```yue
2176x = [ 2341x = [
2177 1, 2, 3, 4, a_func 4, 5, 2342 1, 2, 3, 4, a_func 4, 5,
2178 5, 6, 2343 5, 6,
2179 8, 9, 10 2344 8, 9, 10
2180] 2345]
2181</pre> 2346```
2347
2182</YueDisplay> 2348</YueDisplay>
2183 2349
2184Although uncommon, notice how we can give a deeper indentation for function arguments if we know we will be using a lower indentation further on. 2350Although uncommon, notice how we can give a deeper indentation for function arguments if we know we will be using a lower indentation further on.
2185 2351
2186```moonscript 2352```yuescript
2187y = [ my_func 1, 2, 3, 2353y = [ my_func 1, 2, 3,
2188 4, 5, 2354 4, 5,
2189 5, 6, 7 2355 5, 6, 7
2190] 2356]
2191``` 2357```
2192<YueDisplay> 2358<YueDisplay>
2193<pre> 2359
2360```yue
2194y = [ my_func 1, 2, 3, 2361y = [ my_func 1, 2, 3,
2195 4, 5, 2362 4, 5,
2196 5, 6, 7 2363 5, 6, 7
2197] 2364]
2198</pre> 2365```
2366
2199</YueDisplay> 2367</YueDisplay>
2200 2368
2201The same thing can be done with other block level statements like conditionals. We can use indentation level to determine what statement a value belongs to: 2369The same thing can be done with other block level statements like conditionals. We can use indentation level to determine what statement a value belongs to:
2202 2370
2203```moonscript 2371```yuescript
2204if func 1, 2, 3, 2372if func 1, 2, 3,
2205 "hello", 2373 "hello",
2206 "world" 2374 "world"
@@ -2214,7 +2382,8 @@ if func 1, 2, 3,
2214 print "I am inside if" 2382 print "I am inside if"
2215``` 2383```
2216<YueDisplay> 2384<YueDisplay>
2217<pre> 2385
2386```yue
2218if func 1, 2, 3, 2387if func 1, 2, 3,
2219 "hello", 2388 "hello",
2220 "world" 2389 "world"
@@ -2226,7 +2395,8 @@ if func 1, 2, 3,
2226 "world" 2395 "world"
2227 print "hello" 2396 print "hello"
2228 print "I am inside if" 2397 print "I am inside if"
2229</pre> 2398```
2399
2230</YueDisplay> 2400</YueDisplay>
2231 2401
2232### Parameter Destructuring 2402### Parameter Destructuring
@@ -2237,7 +2407,7 @@ YueScript now supports destructuring function parameters when the argument is an
2237 2407
2238* **Unwrapped simple table syntax**, starting with a sequence of key-value or shorthand bindings and continuing until another expression terminates it (e.g., `:a, b: b1, :c`). This form extracts multiple fields from the same object. 2408* **Unwrapped simple table syntax**, starting with a sequence of key-value or shorthand bindings and continuing until another expression terminates it (e.g., `:a, b: b1, :c`). This form extracts multiple fields from the same object.
2239 2409
2240```moonscript 2410```yuescript
2241f1 = (:a, :b, :c) -> 2411f1 = (:a, :b, :c) ->
2242 print a, b, c 2412 print a, b, c
2243 2413
@@ -2250,7 +2420,8 @@ arg1 = {a: 0}
2250f2 arg1, arg2 2420f2 arg1, arg2
2251``` 2421```
2252<YueDisplay> 2422<YueDisplay>
2253<pre> 2423
2424```yue
2254f1 = (:a, :b, :c) -> 2425f1 = (:a, :b, :c) ->
2255 print a, b, c 2426 print a, b, c
2256 2427
@@ -2261,14 +2432,15 @@ print a1, b, c
2261 2432
2262arg1 = {a: 0} 2433arg1 = {a: 0}
2263f2 arg1, arg2 2434f2 arg1, arg2
2264</pre> 2435```
2436
2265</YueDisplay> 2437</YueDisplay>
2266 2438
2267### Prefixed Return Expression 2439### Prefixed Return Expression
2268 2440
2269When working with deeply nested function bodies, it can be tedious to maintain readability and consistency of the return value. To address this, YueScript introduces the **Prefixed Return Expression** syntax. Its form is as follows: 2441When working with deeply nested function bodies, it can be tedious to maintain readability and consistency of the return value. To address this, YueScript introduces the **Prefixed Return Expression** syntax. Its form is as follows:
2270 2442
2271```moon 2443```yuescript
2272findFirstEven = (list): nil -> 2444findFirstEven = (list): nil ->
2273 for item in *list 2445 for item in *list
2274 if type(item) == "table" 2446 if type(item) == "table"
@@ -2277,19 +2449,21 @@ findFirstEven = (list): nil ->
2277 return sub 2449 return sub
2278``` 2450```
2279<YueDisplay> 2451<YueDisplay>
2280<pre> 2452
2453```yue
2281findFirstEven = (list): nil -> 2454findFirstEven = (list): nil ->
2282 for item in *list 2455 for item in *list
2283 if type(item) == "table" 2456 if type(item) == "table"
2284 for sub in *item 2457 for sub in *item
2285 if sub % 2 == 0 2458 if sub % 2 == 0
2286 return sub 2459 return sub
2287</pre> 2460```
2461
2288</YueDisplay> 2462</YueDisplay>
2289 2463
2290This is equivalent to: 2464This is equivalent to:
2291 2465
2292```moon 2466```yuescript
2293findFirstEven = (list) -> 2467findFirstEven = (list) ->
2294 for item in *list 2468 for item in *list
2295 if type(item) == "table" 2469 if type(item) == "table"
@@ -2299,7 +2473,8 @@ findFirstEven = (list) ->
2299 nil 2473 nil
2300``` 2474```
2301<YueDisplay> 2475<YueDisplay>
2302<pre> 2476
2477```yue
2303findFirstEven = (list) -> 2478findFirstEven = (list) ->
2304 for item in *list 2479 for item in *list
2305 if type(item) == "table" 2480 if type(item) == "table"
@@ -2307,7 +2482,8 @@ findFirstEven = (list) ->
2307 if sub % 2 == 0 2482 if sub % 2 == 0
2308 return sub 2483 return sub
2309 nil 2484 nil
2310</pre> 2485```
2486
2311</YueDisplay> 2487</YueDisplay>
2312 2488
2313The only difference is that you can move the final return expression before the `->` or `=>` token to indicate the function’s implicit return value as the last statement. This way, even in functions with multiple nested loops or conditional branches, you no longer need to write a trailing return expression at the end of the function body, making the logic structure more straightforward and easier to follow. 2489The only difference is that you can move the final return expression before the `->` or `=>` token to indicate the function’s implicit return value as the last statement. This way, even in functions with multiple nested loops or conditional branches, you no longer need to write a trailing return expression at the end of the function body, making the logic structure more straightforward and easier to follow.
@@ -2316,7 +2492,7 @@ The only difference is that you can move the final return expression before the
2316 2492
2317You can use the `(...t) ->` syntax to automatically store varargs into a named table. This table will contain all passed arguments (including `nil` values), and the `n` field of the table will store the actual number of arguments passed (including `nil` values). 2493You can use the `(...t) ->` syntax to automatically store varargs into a named table. This table will contain all passed arguments (including `nil` values), and the `n` field of the table will store the actual number of arguments passed (including `nil` values).
2318 2494
2319```moonscript 2495```yuescript
2320f = (...t) -> 2496f = (...t) ->
2321 print "argument count:", t.n 2497 print "argument count:", t.n
2322 print "table length:", #t 2498 print "table length:", #t
@@ -2338,7 +2514,8 @@ process = (...args) ->
2338process 1, nil, 3, nil, 5 2514process 1, nil, 3, nil, 5
2339``` 2515```
2340<YueDisplay> 2516<YueDisplay>
2341<pre> 2517
2518```yue
2342f = (...t) -> 2519f = (...t) ->
2343 print "argument count:", t.n 2520 print "argument count:", t.n
2344 print "table length:", #t 2521 print "table length:", #t
@@ -2358,53 +2535,60 @@ process = (...args) ->
2358 sum 2535 sum
2359 2536
2360process 1, nil, 3, nil, 5 2537process 1, nil, 3, nil, 5
2361</pre> 2538```
2539
2362</YueDisplay> 2540</YueDisplay>
2363 2541
2364## Backcalls 2542## Backcalls
2365 2543
2366Backcalls are used for unnesting callbacks. They are defined using arrows pointed to the left as the last parameter by default filling in a function call. All the syntax is mostly the same as regular arrow functions except that it is just pointing the other way and the function body does not require indent. 2544Backcalls are used for unnesting callbacks. They are defined using arrows pointed to the left as the last parameter by default filling in a function call. All the syntax is mostly the same as regular arrow functions except that it is just pointing the other way and the function body does not require indent.
2367 2545
2368```moonscript 2546```yuescript
2369<- f 2547<- f
2370print "hello" 2548print "hello"
2371``` 2549```
2372<YueDisplay> 2550<YueDisplay>
2373<pre> 2551
2552```yue
2374<- f 2553<- f
2375print "hello" 2554print "hello"
2376</pre> 2555```
2556
2377</YueDisplay> 2557</YueDisplay>
2378 2558
2379Fat arrow functions are also available. 2559Fat arrow functions are also available.
2380 2560
2381```moonscript 2561```yuescript
2382<= f 2562<= f
2383print @value 2563print @value
2384``` 2564```
2385<YueDisplay> 2565<YueDisplay>
2386<pre> 2566
2567```yue
2387<= f 2568<= f
2388print @value 2569print @value
2389</pre> 2570```
2571
2390</YueDisplay> 2572</YueDisplay>
2391 2573
2392You can specify a placeholder for where you want the backcall function to go as a parameter. 2574You can specify a placeholder for where you want the backcall function to go as a parameter.
2393 2575
2394```moonscript 2576```yuescript
2395(x) <- map _, [1, 2, 3] 2577(x) <- map _, [1, 2, 3]
2396x * 2 2578x * 2
2397``` 2579```
2398<YueDisplay> 2580<YueDisplay>
2399<pre> 2581
2582```yue
2400(x) <- map _, [1, 2, 3] 2583(x) <- map _, [1, 2, 3]
2401x * 2 2584x * 2
2402</pre> 2585```
2586
2403</YueDisplay> 2587</YueDisplay>
2404 2588
2405If 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. 2589If 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.
2406 2590
2407```moonscript 2591```yuescript
2408result, msg = do 2592result, msg = do
2409 data <- readAsync "filename.txt" 2593 data <- readAsync "filename.txt"
2410 print data 2594 print data
@@ -2413,32 +2597,36 @@ result, msg = do
2413print result, msg 2597print result, msg
2414``` 2598```
2415<YueDisplay> 2599<YueDisplay>
2416<pre> 2600
2601```yue
2417result, msg = do 2602result, msg = do
2418 data <- readAsync "filename.txt" 2603 data <- readAsync "filename.txt"
2419 print data 2604 print data
2420 info <- processAsync data 2605 info <- processAsync data
2421 check info 2606 check info
2422print result, msg 2607print result, msg
2423</pre> 2608```
2609
2424</YueDisplay> 2610</YueDisplay>
2425 2611
2426## Table Literals 2612## Table Literals
2427 2613
2428Like in Lua, tables are delimited in curly braces. 2614Like in Lua, tables are delimited in curly braces.
2429 2615
2430```moonscript 2616```yuescript
2431some_values = [1, 2, 3, 4] 2617some_values = [1, 2, 3, 4]
2432``` 2618```
2433<YueDisplay> 2619<YueDisplay>
2434<pre> 2620
2621```yue
2435some_values = [1, 2, 3, 4] 2622some_values = [1, 2, 3, 4]
2436</pre> 2623```
2624
2437</YueDisplay> 2625</YueDisplay>
2438 2626
2439Unlike Lua, assigning a value to a key in a table is done with **:** (instead of **=**). 2627Unlike Lua, assigning a value to a key in a table is done with **:** (instead of **=**).
2440 2628
2441```moonscript 2629```yuescript
2442some_values = { 2630some_values = {
2443 name: "Bill", 2631 name: "Bill",
2444 age: 200, 2632 age: 200,
@@ -2446,35 +2634,39 @@ some_values = {
2446} 2634}
2447``` 2635```
2448<YueDisplay> 2636<YueDisplay>
2449<pre> 2637
2638```yue
2450some_values = { 2639some_values = {
2451 name: "Bill", 2640 name: "Bill",
2452 age: 200, 2641 age: 200,
2453 ["favorite food"]: "rice" 2642 ["favorite food"]: "rice"
2454} 2643}
2455</pre> 2644```
2645
2456</YueDisplay> 2646</YueDisplay>
2457 2647
2458The curly braces can be left off if a single table of key value pairs is being assigned. 2648The curly braces can be left off if a single table of key value pairs is being assigned.
2459 2649
2460```moonscript 2650```yuescript
2461profile = 2651profile =
2462 height: "4 feet", 2652 height: "4 feet",
2463 shoe_size: 13, 2653 shoe_size: 13,
2464 favorite_foods: ["ice cream", "donuts"] 2654 favorite_foods: ["ice cream", "donuts"]
2465``` 2655```
2466<YueDisplay> 2656<YueDisplay>
2467<pre> 2657
2658```yue
2468profile = 2659profile =
2469 height: "4 feet", 2660 height: "4 feet",
2470 shoe_size: 13, 2661 shoe_size: 13,
2471 favorite_foods: ["ice cream", "donuts"] 2662 favorite_foods: ["ice cream", "donuts"]
2472</pre> 2663```
2664
2473</YueDisplay> 2665</YueDisplay>
2474 2666
2475Newlines can be used to delimit values instead of a comma (or both): 2667Newlines can be used to delimit values instead of a comma (or both):
2476 2668
2477```moonscript 2669```yuescript
2478values = { 2670values = {
2479 1, 2, 3, 4 2671 1, 2, 3, 4
2480 5, 6, 7, 8 2672 5, 6, 7, 8
@@ -2483,51 +2675,57 @@ values = {
2483} 2675}
2484``` 2676```
2485<YueDisplay> 2677<YueDisplay>
2486<pre> 2678
2679```yue
2487values = { 2680values = {
2488 1, 2, 3, 4 2681 1, 2, 3, 4
2489 5, 6, 7, 8 2682 5, 6, 7, 8
2490 name: "superman" 2683 name: "superman"
2491 occupation: "crime fighting" 2684 occupation: "crime fighting"
2492} 2685}
2493</pre> 2686```
2687
2494</YueDisplay> 2688</YueDisplay>
2495 2689
2496When creating a single line table literal, the curly braces can also be left off: 2690When creating a single line table literal, the curly braces can also be left off:
2497 2691
2498```moonscript 2692```yuescript
2499my_function dance: "Tango", partner: "none" 2693my_function dance: "Tango", partner: "none"
2500 2694
2501y = type: "dog", legs: 4, tails: 1 2695y = type: "dog", legs: 4, tails: 1
2502``` 2696```
2503<YueDisplay> 2697<YueDisplay>
2504<pre> 2698
2699```yue
2505my_function dance: "Tango", partner: "none" 2700my_function dance: "Tango", partner: "none"
2506 2701
2507y = type: "dog", legs: 4, tails: 1 2702y = type: "dog", legs: 4, tails: 1
2508</pre> 2703```
2704
2509</YueDisplay> 2705</YueDisplay>
2510 2706
2511The keys of a table literal can be language keywords without being escaped: 2707The keys of a table literal can be language keywords without being escaped:
2512 2708
2513```moonscript 2709```yuescript
2514tbl = { 2710tbl = {
2515 do: "something" 2711 do: "something"
2516 end: "hunger" 2712 end: "hunger"
2517} 2713}
2518``` 2714```
2519<YueDisplay> 2715<YueDisplay>
2520<pre> 2716
2717```yue
2521tbl = { 2718tbl = {
2522 do: "something" 2719 do: "something"
2523 end: "hunger" 2720 end: "hunger"
2524} 2721}
2525</pre> 2722```
2723
2526</YueDisplay> 2724</YueDisplay>
2527 2725
2528If you are constructing a table out of variables and wish the keys to be the same as the variable names, then the **:** prefix operator can be used: 2726If you are constructing a table out of variables and wish the keys to be the same as the variable names, then the **:** prefix operator can be used:
2529 2727
2530```moonscript 2728```yuescript
2531hair = "golden" 2729hair = "golden"
2532height = 200 2730height = 200
2533person = { :hair, :height, shoe_size: 40 } 2731person = { :hair, :height, shoe_size: 40 }
@@ -2535,43 +2733,49 @@ person = { :hair, :height, shoe_size: 40 }
2535print_table :hair, :height 2733print_table :hair, :height
2536``` 2734```
2537<YueDisplay> 2735<YueDisplay>
2538<pre> 2736
2737```yue
2539hair = "golden" 2738hair = "golden"
2540height = 200 2739height = 200
2541person = { :hair, :height, shoe_size: 40 } 2740person = { :hair, :height, shoe_size: 40 }
2542 2741
2543print_table :hair, :height 2742print_table :hair, :height
2544</pre> 2743```
2744
2545</YueDisplay> 2745</YueDisplay>
2546 2746
2547If you want the key of a field in the table to to be result of an expression, then you can wrap it in **[ ]**, just like in Lua. You can also use a string literal directly as a key, leaving out the square brackets. This is useful if your key has any special characters. 2747If you want the key of a field in the table to to be result of an expression, then you can wrap it in **[ ]**, just like in Lua. You can also use a string literal directly as a key, leaving out the square brackets. This is useful if your key has any special characters.
2548 2748
2549```moonscript 2749```yuescript
2550t = { 2750t = {
2551 [1 + 2]: "hello" 2751 [1 + 2]: "hello"
2552 "hello world": true 2752 "hello world": true
2553} 2753}
2554``` 2754```
2555<YueDisplay> 2755<YueDisplay>
2556<pre> 2756
2757```yue
2557t = { 2758t = {
2558 [1 + 2]: "hello" 2759 [1 + 2]: "hello"
2559 "hello world": true 2760 "hello world": true
2560} 2761}
2561</pre> 2762```
2763
2562</YueDisplay> 2764</YueDisplay>
2563 2765
2564Lua tables have both an array part and a hash part, but sometimes you want to make a semantic distinction between array and hash usage when writing Lua tables. Then you can write Lua table with **[ ]** instead of **{ }** to represent an array table and writing any key value pair in a list table won't be allowed. 2766Lua tables have both an array part and a hash part, but sometimes you want to make a semantic distinction between array and hash usage when writing Lua tables. Then you can write Lua table with **[ ]** instead of **{ }** to represent an array table and writing any key value pair in a list table won't be allowed.
2565 2767
2566```moonscript 2768```yuescript
2567some_values = [1, 2, 3, 4] 2769some_values = [1, 2, 3, 4]
2568list_with_one_element = [1, ] 2770list_with_one_element = [1, ]
2569``` 2771```
2570<YueDisplay> 2772<YueDisplay>
2571<pre> 2773
2774```yue
2572some_values = [1, 2, 3, 4] 2775some_values = [1, 2, 3, 4]
2573list_with_one_element = [1, ] 2776list_with_one_element = [1, ]
2574</pre> 2777```
2778
2575</YueDisplay> 2779</YueDisplay>
2576 2780
2577## Comprehensions 2781## Comprehensions
@@ -2582,42 +2786,48 @@ Comprehensions provide a convenient syntax for constructing a new table by itera
2582 2786
2583The following creates a copy of the items table but with all the values doubled. 2787The following creates a copy of the items table but with all the values doubled.
2584 2788
2585```moonscript 2789```yuescript
2586items = [ 1, 2, 3, 4 ] 2790items = [ 1, 2, 3, 4 ]
2587doubled = [item * 2 for i, item in ipairs items] 2791doubled = [item * 2 for i, item in ipairs items]
2588``` 2792```
2589<YueDisplay> 2793<YueDisplay>
2590<pre> 2794
2795```yue
2591items = [ 1, 2, 3, 4 ] 2796items = [ 1, 2, 3, 4 ]
2592doubled = [item * 2 for i, item in ipairs items] 2797doubled = [item * 2 for i, item in ipairs items]
2593</pre> 2798```
2799
2594</YueDisplay> 2800</YueDisplay>
2595 2801
2596The items included in the new table can be restricted with a when clause: 2802The items included in the new table can be restricted with a when clause:
2597 2803
2598```moonscript 2804```yuescript
2599slice = [item for i, item in ipairs items when i > 1 and i < 3] 2805slice = [item for i, item in ipairs items when i > 1 and i < 3]
2600``` 2806```
2601<YueDisplay> 2807<YueDisplay>
2602<pre> 2808
2809```yue
2603slice = [item for i, item in ipairs items when i > 1 and i < 3] 2810slice = [item for i, item in ipairs items when i > 1 and i < 3]
2604</pre> 2811```
2812
2605</YueDisplay> 2813</YueDisplay>
2606 2814
2607Because it is common to iterate over the values of a numerically indexed table, an **\*** operator is introduced. The doubled example can be rewritten as: 2815Because it is common to iterate over the values of a numerically indexed table, an **\*** operator is introduced. The doubled example can be rewritten as:
2608 2816
2609```moonscript 2817```yuescript
2610doubled = [item * 2 for item in *items] 2818doubled = [item * 2 for item in *items]
2611``` 2819```
2612<YueDisplay> 2820<YueDisplay>
2613<pre> 2821
2822```yue
2614doubled = [item * 2 for item in *items] 2823doubled = [item * 2 for item in *items]
2615</pre> 2824```
2825
2616</YueDisplay> 2826</YueDisplay>
2617 2827
2618In list comprehensions, you can also use the spread operator `...` to flatten nested lists, achieving a flat map effect: 2828In list comprehensions, you can also use the spread operator `...` to flatten nested lists, achieving a flat map effect:
2619 2829
2620```moonscript 2830```yuescript
2621data = 2831data =
2622 a: [1, 2, 3] 2832 a: [1, 2, 3]
2623 b: [4, 5, 6] 2833 b: [4, 5, 6]
@@ -2626,21 +2836,23 @@ flat = [...v for k,v in pairs data]
2626-- flat is now [1, 2, 3, 4, 5, 6] 2836-- flat is now [1, 2, 3, 4, 5, 6]
2627``` 2837```
2628<YueDisplay> 2838<YueDisplay>
2629<pre> 2839
2840```yue
2630data = 2841data =
2631 a: [1, 2, 3] 2842 a: [1, 2, 3]
2632 b: [4, 5, 6] 2843 b: [4, 5, 6]
2633 2844
2634flat = [...v for k,v in pairs data] 2845flat = [...v for k,v in pairs data]
2635-- flat is now [1, 2, 3, 4, 5, 6] 2846-- flat is now [1, 2, 3, 4, 5, 6]
2636</pre> 2847```
2848
2637</YueDisplay> 2849</YueDisplay>
2638 2850
2639The for and when clauses can be chained as much as desired. The only requirement is that a comprehension has at least one for clause. 2851The for and when clauses can be chained as much as desired. The only requirement is that a comprehension has at least one for clause.
2640 2852
2641Using multiple for clauses is the same as using nested loops: 2853Using multiple for clauses is the same as using nested loops:
2642 2854
2643```moonscript 2855```yuescript
2644x_coords = [4, 5, 6, 7] 2856x_coords = [4, 5, 6, 7]
2645y_coords = [9, 2, 3] 2857y_coords = [9, 2, 3]
2646 2858
@@ -2648,24 +2860,28 @@ points = [ [x, y] for x in *x_coords \
2648for y in *y_coords] 2860for y in *y_coords]
2649``` 2861```
2650<YueDisplay> 2862<YueDisplay>
2651<pre> 2863
2864```yue
2652x_coords = [4, 5, 6, 7] 2865x_coords = [4, 5, 6, 7]
2653y_coords = [9, 2, 3] 2866y_coords = [9, 2, 3]
2654 2867
2655points = [ [x, y] for x in *x_coords \ 2868points = [ [x, y] for x in *x_coords \
2656for y in *y_coords] 2869for y in *y_coords]
2657</pre> 2870```
2871
2658</YueDisplay> 2872</YueDisplay>
2659 2873
2660Numeric for loops can also be used in comprehensions: 2874Numeric for loops can also be used in comprehensions:
2661 2875
2662```moonscript 2876```yuescript
2663evens = [i for i = 1, 100 when i % 2 == 0] 2877evens = [i for i = 1, 100 when i % 2 == 0]
2664``` 2878```
2665<YueDisplay> 2879<YueDisplay>
2666<pre> 2880
2881```yue
2667evens = [i for i = 1, 100 when i % 2 == 0] 2882evens = [i for i = 1, 100 when i % 2 == 0]
2668</pre> 2883```
2884
2669</YueDisplay> 2885</YueDisplay>
2670 2886
2671### Table Comprehensions 2887### Table Comprehensions
@@ -2674,7 +2890,7 @@ The syntax for table comprehensions is very similar, only differing by using **{
2674 2890
2675This example makes a copy of the tablething: 2891This example makes a copy of the tablething:
2676 2892
2677```moonscript 2893```yuescript
2678thing = { 2894thing = {
2679 color: "red" 2895 color: "red"
2680 name: "fast" 2896 name: "fast"
@@ -2684,52 +2900,60 @@ thing = {
2684thing_copy = {k, v for k, v in pairs thing} 2900thing_copy = {k, v for k, v in pairs thing}
2685``` 2901```
2686<YueDisplay> 2902<YueDisplay>
2687<pre> 2903
2904```yue
2688thing = { 2905thing = {
2689 color: "red" 2906 color: "red"
2690 name: "fast" 2907 name: "fast"
2691 width: 123 2908 width: 123
2692} 2909}
2693 2910
2694thing_copy = {k, v for k, v in pairs thing} 2911thing_copy = \{k, v for k, v in pairs thing}
2695</pre> 2912```
2913
2696</YueDisplay> 2914</YueDisplay>
2697 2915
2698```moonscript 2916```yuescript
2699no_color = {k, v for k, v in pairs thing when k != "color"} 2917no_color = {k, v for k, v in pairs thing when k != "color"}
2700``` 2918```
2701<YueDisplay> 2919<YueDisplay>
2702<pre> 2920
2703no_color = {k, v for k, v in pairs thing when k != "color"} 2921```yue
2704</pre> 2922no_color = \{k, v for k, v in pairs thing when k != "color"}
2923```
2924
2705</YueDisplay> 2925</YueDisplay>
2706 2926
2707The **\*** operator is also supported. Here we create a square root look up table for a few numbers. 2927The **\*** operator is also supported. Here we create a square root look up table for a few numbers.
2708 2928
2709```moonscript 2929```yuescript
2710numbers = [1, 2, 3, 4] 2930numbers = [1, 2, 3, 4]
2711sqrts = {i, math.sqrt i for i in *numbers} 2931sqrts = {i, math.sqrt i for i in *numbers}
2712``` 2932```
2713<YueDisplay> 2933<YueDisplay>
2714<pre> 2934
2935```yue
2715numbers = [1, 2, 3, 4] 2936numbers = [1, 2, 3, 4]
2716sqrts = {i, math.sqrt i for i in *numbers} 2937sqrts = \{i, math.sqrt i for i in *numbers}
2717</pre> 2938```
2939
2718</YueDisplay> 2940</YueDisplay>
2719 2941
2720The key-value tuple in a table comprehension can also come from a single expression, in which case the expression should return two values. The first is used as the key and the second is used as the value: 2942The key-value tuple in a table comprehension can also come from a single expression, in which case the expression should return two values. The first is used as the key and the second is used as the value:
2721 2943
2722In this example we convert an array of pairs to a table where the first item in the pair is the key and the second is the value. 2944In this example we convert an array of pairs to a table where the first item in the pair is the key and the second is the value.
2723 2945
2724```moonscript 2946```yuescript
2725tuples = [ ["hello", "world"], ["foo", "bar"]] 2947tuples = [ ["hello", "world"], ["foo", "bar"]]
2726tbl = {unpack tuple for tuple in *tuples} 2948tbl = {unpack tuple for tuple in *tuples}
2727``` 2949```
2728<YueDisplay> 2950<YueDisplay>
2729<pre> 2951
2952```yue
2730tuples = [ ["hello", "world"], ["foo", "bar"]] 2953tuples = [ ["hello", "world"], ["foo", "bar"]]
2731tbl = {unpack tuple for tuple in *tuples} 2954tbl = \{unpack tuple for tuple in *tuples}
2732</pre> 2955```
2956
2733</YueDisplay> 2957</YueDisplay>
2734 2958
2735### Slicing 2959### Slicing
@@ -2738,81 +2962,93 @@ A special syntax is provided to restrict the items that are iterated over when u
2738 2962
2739Here we can set the minimum and maximum bounds, taking all items with indexes between 1 and 5 inclusive: 2963Here we can set the minimum and maximum bounds, taking all items with indexes between 1 and 5 inclusive:
2740 2964
2741```moonscript 2965```yuescript
2742slice = [item for item in *items[1, 5]] 2966slice = [item for item in *items[1, 5]]
2743``` 2967```
2744<YueDisplay> 2968<YueDisplay>
2745<pre> 2969
2970```yue
2746slice = [item for item in *items[1, 5]] 2971slice = [item for item in *items[1, 5]]
2747</pre> 2972```
2973
2748</YueDisplay> 2974</YueDisplay>
2749 2975
2750Any of the slice arguments can be left off to use a sensible default. In this example, if the max index is left off it defaults to the length of the table. This will take everything but the first element: 2976Any of the slice arguments can be left off to use a sensible default. In this example, if the max index is left off it defaults to the length of the table. This will take everything but the first element:
2751 2977
2752```moonscript 2978```yuescript
2753slice = [item for item in *items[2,]] 2979slice = [item for item in *items[2,]]
2754``` 2980```
2755<YueDisplay> 2981<YueDisplay>
2756<pre> 2982
2983```yue
2757slice = [item for item in *items[2,]] 2984slice = [item for item in *items[2,]]
2758</pre> 2985```
2986
2759</YueDisplay> 2987</YueDisplay>
2760 2988
2761If the minimum bound is left out, it defaults to 1. Here we only provide a step size and leave the other bounds blank. This takes all odd indexed items: (1, 3, 5, …) 2989If the minimum bound is left out, it defaults to 1. Here we only provide a step size and leave the other bounds blank. This takes all odd indexed items: (1, 3, 5, …)
2762 2990
2763```moonscript 2991```yuescript
2764slice = [item for item in *items[,,2]] 2992slice = [item for item in *items[,,2]]
2765``` 2993```
2766<YueDisplay> 2994<YueDisplay>
2767<pre> 2995
2996```yue
2768slice = [item for item in *items[,,2]] 2997slice = [item for item in *items[,,2]]
2769</pre> 2998```
2999
2770</YueDisplay> 3000</YueDisplay>
2771 3001
2772Both the minimum and maximum bounds can be negative, which means that the bounds are counted from the end of the table. 3002Both the minimum and maximum bounds can be negative, which means that the bounds are counted from the end of the table.
2773 3003
2774```moonscript 3004```yuescript
2775-- take the last 4 items 3005-- take the last 4 items
2776slice = [item for item in *items[-4,-1]] 3006slice = [item for item in *items[-4,-1]]
2777``` 3007```
2778<YueDisplay> 3008<YueDisplay>
2779<pre> 3009
3010```yue
2780-- take the last 4 items 3011-- take the last 4 items
2781slice = [item for item in *items[-4,-1]] 3012slice = [item for item in *items[-4,-1]]
2782</pre> 3013```
3014
2783</YueDisplay> 3015</YueDisplay>
2784 3016
2785The step size can also be negative, which means that the items are taken in reverse order. 3017The step size can also be negative, which means that the items are taken in reverse order.
2786 3018
2787```moonscript 3019```yuescript
2788reverse_slice = [item for item in *items[-1,1,-1]] 3020reverse_slice = [item for item in *items[-1,1,-1]]
2789``` 3021```
2790<YueDisplay> 3022<YueDisplay>
2791<pre> 3023
3024```yue
2792reverse_slice = [item for item in *items[-1,1,-1]] 3025reverse_slice = [item for item in *items[-1,1,-1]]
2793</pre> 3026```
3027
2794</YueDisplay> 3028</YueDisplay>
2795 3029
2796#### Slicing Expression 3030#### Slicing Expression
2797 3031
2798Slicing can also be used as an expression. This is useful for getting a sub-list of a table. 3032Slicing can also be used as an expression. This is useful for getting a sub-list of a table.
2799 3033
2800```moonscript 3034```yuescript
2801-- take the 2nd and 4th items as a new list 3035-- take the 2nd and 4th items as a new list
2802sub_list = items[2, 4] 3036sub_list = items[2, 4]
2803``` 3037```
2804<YueDisplay> 3038<YueDisplay>
2805<pre> 3039
3040```yue
2806-- take the 2nd and 4th items as a new list 3041-- take the 2nd and 4th items as a new list
2807sub_list = items[2, 4] 3042sub_list = items[2, 4]
2808</pre> 3043```
3044
2809</YueDisplay> 3045</YueDisplay>
2810 3046
2811## For Loop 3047## For Loop
2812 3048
2813There are two for loop forms, just like in Lua. A numeric one and a generic one: 3049There are two for loop forms, just like in Lua. A numeric one and a generic one:
2814 3050
2815```moonscript 3051```yuescript
2816for i = 10, 20 3052for i = 10, 20
2817 print i 3053 print i
2818 3054
@@ -2823,7 +3059,8 @@ for key, value in pairs object
2823 print key, value 3059 print key, value
2824``` 3060```
2825<YueDisplay> 3061<YueDisplay>
2826<pre> 3062
3063```yue
2827for i = 10, 20 3064for i = 10, 20
2828 print i 3065 print i
2829 3066
@@ -2832,42 +3069,47 @@ for k = 1, 15, 2 -- an optional step provided
2832 3069
2833for key, value in pairs object 3070for key, value in pairs object
2834 print key, value 3071 print key, value
2835</pre> 3072```
3073
2836</YueDisplay> 3074</YueDisplay>
2837 3075
2838The slicing and **\*** operators can be used, just like with comprehensions: 3076The slicing and **\*** operators can be used, just like with comprehensions:
2839 3077
2840```moonscript 3078```yuescript
2841for item in *items[2, 4] 3079for item in *items[2, 4]
2842 print item 3080 print item
2843``` 3081```
2844<YueDisplay> 3082<YueDisplay>
2845<pre> 3083
3084```yue
2846for item in *items[2, 4] 3085for item in *items[2, 4]
2847 print item 3086 print item
2848</pre> 3087```
3088
2849</YueDisplay> 3089</YueDisplay>
2850 3090
2851A shorter syntax is also available for all variations when the body is only a single line: 3091A shorter syntax is also available for all variations when the body is only a single line:
2852 3092
2853```moonscript 3093```yuescript
2854for item in *items do print item 3094for item in *items do print item
2855 3095
2856for j = 1, 10, 3 do print j 3096for j = 1, 10, 3 do print j
2857``` 3097```
2858<YueDisplay> 3098<YueDisplay>
2859<pre> 3099
3100```yue
2860for item in *items do print item 3101for item in *items do print item
2861 3102
2862for j = 1, 10, 3 do print j 3103for j = 1, 10, 3 do print j
2863</pre> 3104```
3105
2864</YueDisplay> 3106</YueDisplay>
2865 3107
2866A for loop can also be used as an expression. The last statement in the body of the for loop is coerced into an expression and appended to an accumulating array table. 3108A for loop can also be used as an expression. The last statement in the body of the for loop is coerced into an expression and appended to an accumulating array table.
2867 3109
2868Doubling every even number: 3110Doubling every even number:
2869 3111
2870```moonscript 3112```yuescript
2871doubled_evens = for i = 1, 20 3113doubled_evens = for i = 1, 20
2872 if i % 2 == 0 3114 if i % 2 == 0
2873 i * 2 3115 i * 2
@@ -2875,28 +3117,32 @@ doubled_evens = for i = 1, 20
2875 i 3117 i
2876``` 3118```
2877<YueDisplay> 3119<YueDisplay>
2878<pre> 3120
3121```yue
2879doubled_evens = for i = 1, 20 3122doubled_evens = for i = 1, 20
2880 if i % 2 == 0 3123 if i % 2 == 0
2881 i * 2 3124 i * 2
2882 else 3125 else
2883 i 3126 i
2884</pre> 3127```
3128
2885</YueDisplay> 3129</YueDisplay>
2886 3130
2887In 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. 3131In 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.
2888 3132
2889For example, to find the first number greater than 10: 3133For example, to find the first number greater than 10:
2890 3134
2891```moonscript 3135```yuescript
2892first_large = for n in *numbers 3136first_large = for n in *numbers
2893 break n if n > 10 3137 break n if n > 10
2894``` 3138```
2895<YueDisplay> 3139<YueDisplay>
2896<pre> 3140
3141```yue
2897first_large = for n in *numbers 3142first_large = for n in *numbers
2898 break n if n > 10 3143 break n if n > 10
2899</pre> 3144```
3145
2900</YueDisplay> 3146</YueDisplay>
2901 3147
2902This break-with-value syntax enables concise and expressive search or early-exit patterns directly within loop expressions. 3148This break-with-value syntax enables concise and expressive search or early-exit patterns directly within loop expressions.
@@ -2905,7 +3151,7 @@ You can also filter values by combining the for loop expression with the continu
2905 3151
2906For 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. 3152For 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.
2907 3153
2908```moonscript 3154```yuescript
2909func_a = -> for i = 1, 10 do print i 3155func_a = -> for i = 1, 10 do print i
2910func_b = -> return for i = 1, 10 do i 3156func_b = -> return for i = 1, 10 do i
2911 3157
@@ -2913,13 +3159,15 @@ print func_a! -- prints nil
2913print func_b! -- prints table object 3159print func_b! -- prints table object
2914``` 3160```
2915<YueDisplay> 3161<YueDisplay>
2916<pre> 3162
3163```yue
2917func_a = -> for i = 1, 10 do print i 3164func_a = -> for i = 1, 10 do print i
2918func_b = -> return for i = 1, 10 do i 3165func_b = -> return for i = 1, 10 do i
2919 3166
2920print func_a! -- prints nil 3167print func_a! -- prints nil
2921print func_b! -- prints table object 3168print func_b! -- prints table object
2922</pre> 3169```
3170
2923</YueDisplay> 3171</YueDisplay>
2924 3172
2925This is done to avoid the needless creation of tables for functions that don't need to return the results of the loop. 3173This is done to avoid the needless creation of tables for functions that don't need to return the results of the loop.
@@ -2928,7 +3176,7 @@ This is done to avoid the needless creation of tables for functions that don't n
2928 3176
2929The repeat loop comes from Lua: 3177The repeat loop comes from Lua:
2930 3178
2931```moonscript 3179```yuescript
2932i = 10 3180i = 10
2933repeat 3181repeat
2934 print i 3182 print i
@@ -2936,20 +3184,22 @@ repeat
2936until i == 0 3184until i == 0
2937``` 3185```
2938<YueDisplay> 3186<YueDisplay>
2939<pre> 3187
3188```yue
2940i = 10 3189i = 10
2941repeat 3190repeat
2942 print i 3191 print i
2943 i -= 1 3192 i -= 1
2944until i == 0 3193until i == 0
2945</pre> 3194```
3195
2946</YueDisplay> 3196</YueDisplay>
2947 3197
2948## While Loop 3198## While Loop
2949 3199
2950The while loop also comes in four variations: 3200The while loop also comes in four variations:
2951 3201
2952```moonscript 3202```yuescript
2953i = 10 3203i = 10
2954while i > 0 3204while i > 0
2955 print i 3205 print i
@@ -2958,17 +3208,19 @@ while i > 0
2958while running == true do my_function! 3208while running == true do my_function!
2959``` 3209```
2960<YueDisplay> 3210<YueDisplay>
2961<pre> 3211
3212```yue
2962i = 10 3213i = 10
2963while i > 0 3214while i > 0
2964 print i 3215 print i
2965 i -= 1 3216 i -= 1
2966 3217
2967while running == true do my_function! 3218while running == true do my_function!
2968</pre> 3219```
3220
2969</YueDisplay> 3221</YueDisplay>
2970 3222
2971```moonscript 3223```yuescript
2972i = 10 3224i = 10
2973until i == 0 3225until i == 0
2974 print i 3226 print i
@@ -2977,13 +3229,15 @@ until i == 0
2977until running == false do my_function! 3229until running == false do my_function!
2978``` 3230```
2979<YueDisplay> 3231<YueDisplay>
2980<pre> 3232
3233```yue
2981i = 10 3234i = 10
2982until i == 0 3235until i == 0
2983 print i 3236 print i
2984 i -= 1 3237 i -= 1
2985until running == false do my_function! 3238until running == false do my_function!
2986</pre> 3239```
3240
2987</YueDisplay> 3241</YueDisplay>
2988 3242
2989Like for loops, the while loop can also be used an expression. Additionally, for a function to return the accumulated value of a while loop, the statement must be explicitly returned. 3243Like for loops, the while loop can also be used an expression. Additionally, for a function to return the accumulated value of a while loop, the statement must be explicitly returned.
@@ -2992,7 +3246,7 @@ Like for loops, the while loop can also be used an expression. Additionally, for
2992 3246
2993A continue statement can be used to skip the current iteration in a loop. 3247A continue statement can be used to skip the current iteration in a loop.
2994 3248
2995```moonscript 3249```yuescript
2996i = 0 3250i = 0
2997while i < 10 3251while i < 10
2998 i += 1 3252 i += 1
@@ -3000,35 +3254,39 @@ while i < 10
3000 print i 3254 print i
3001``` 3255```
3002<YueDisplay> 3256<YueDisplay>
3003<pre> 3257
3258```yue
3004i = 0 3259i = 0
3005while i < 10 3260while i < 10
3006 i += 1 3261 i += 1
3007 continue if i % 2 == 0 3262 continue if i % 2 == 0
3008 print i 3263 print i
3009</pre> 3264```
3265
3010</YueDisplay> 3266</YueDisplay>
3011 3267
3012continue can also be used with loop expressions to prevent that iteration from accumulating into the result. This examples filters the array table into just even numbers: 3268continue can also be used with loop expressions to prevent that iteration from accumulating into the result. This examples filters the array table into just even numbers:
3013 3269
3014```moonscript 3270```yuescript
3015my_numbers = [1, 2, 3, 4, 5, 6] 3271my_numbers = [1, 2, 3, 4, 5, 6]
3016odds = for x in *my_numbers 3272odds = for x in *my_numbers
3017 continue if x % 2 == 1 3273 continue if x % 2 == 1
3018 x 3274 x
3019``` 3275```
3020<YueDisplay> 3276<YueDisplay>
3021<pre> 3277
3278```yue
3022my_numbers = [1, 2, 3, 4, 5, 6] 3279my_numbers = [1, 2, 3, 4, 5, 6]
3023odds = for x in *my_numbers 3280odds = for x in *my_numbers
3024 continue if x % 2 == 1 3281 continue if x % 2 == 1
3025 x 3282 x
3026</pre> 3283```
3284
3027</YueDisplay> 3285</YueDisplay>
3028 3286
3029## Conditionals 3287## Conditionals
3030 3288
3031```moonscript 3289```yuescript
3032have_coins = false 3290have_coins = false
3033if have_coins 3291if have_coins
3034 print "Got coins" 3292 print "Got coins"
@@ -3036,44 +3294,50 @@ else
3036 print "No coins" 3294 print "No coins"
3037``` 3295```
3038<YueDisplay> 3296<YueDisplay>
3039<pre> 3297
3298```yue
3040have_coins = false 3299have_coins = false
3041if have_coins 3300if have_coins
3042 print "Got coins" 3301 print "Got coins"
3043else 3302else
3044 print "No coins" 3303 print "No coins"
3045</pre> 3304```
3305
3046</YueDisplay> 3306</YueDisplay>
3047 3307
3048A short syntax for single statements can also be used: 3308A short syntax for single statements can also be used:
3049 3309
3050```moonscript 3310```yuescript
3051have_coins = false 3311have_coins = false
3052if have_coins then print "Got coins" else print "No coins" 3312if have_coins then print "Got coins" else print "No coins"
3053``` 3313```
3054<YueDisplay> 3314<YueDisplay>
3055<pre> 3315
3316```yue
3056have_coins = false 3317have_coins = false
3057if have_coins then print "Got coins" else print "No coins" 3318if have_coins then print "Got coins" else print "No coins"
3058</pre> 3319```
3320
3059</YueDisplay> 3321</YueDisplay>
3060 3322
3061Because if statements can be used as expressions, this can also be written as: 3323Because if statements can be used as expressions, this can also be written as:
3062 3324
3063```moonscript 3325```yuescript
3064have_coins = false 3326have_coins = false
3065print if have_coins then "Got coins" else "No coins" 3327print if have_coins then "Got coins" else "No coins"
3066``` 3328```
3067<YueDisplay> 3329<YueDisplay>
3068<pre> 3330
3331```yue
3069have_coins = false 3332have_coins = false
3070print if have_coins then "Got coins" else "No coins" 3333print if have_coins then "Got coins" else "No coins"
3071</pre> 3334```
3335
3072</YueDisplay> 3336</YueDisplay>
3073 3337
3074Conditionals can also be used in return statements and assignments: 3338Conditionals can also be used in return statements and assignments:
3075 3339
3076```moonscript 3340```yuescript
3077is_tall = (name) -> 3341is_tall = (name) ->
3078 if name == "Rob" 3342 if name == "Rob"
3079 true 3343 true
@@ -3088,7 +3352,8 @@ else
3088print message -- prints: I am very tall 3352print message -- prints: I am very tall
3089``` 3353```
3090<YueDisplay> 3354<YueDisplay>
3091<pre> 3355
3356```yue
3092is_tall = (name) -> 3357is_tall = (name) ->
3093 if name == "Rob" 3358 if name == "Rob"
3094 true 3359 true
@@ -3101,36 +3366,41 @@ else
3101 "I am not so tall" 3366 "I am not so tall"
3102 3367
3103print message -- prints: I am very tall 3368print message -- prints: I am very tall
3104</pre> 3369```
3370
3105</YueDisplay> 3371</YueDisplay>
3106 3372
3107The opposite of if is unless: 3373The opposite of if is unless:
3108 3374
3109```moonscript 3375```yuescript
3110unless os.date("%A") == "Monday" 3376unless os.date("%A") == "Monday"
3111 print "it is not Monday!" 3377 print "it is not Monday!"
3112``` 3378```
3113<YueDisplay> 3379<YueDisplay>
3114<pre> 3380
3381```yue
3115unless os.date("%A") == "Monday" 3382unless os.date("%A") == "Monday"
3116 print "it is not Monday!" 3383 print "it is not Monday!"
3117</pre> 3384```
3385
3118</YueDisplay> 3386</YueDisplay>
3119 3387
3120```moonscript 3388```yuescript
3121print "You're lucky!" unless math.random! > 0.1 3389print "You're lucky!" unless math.random! > 0.1
3122``` 3390```
3123<YueDisplay> 3391<YueDisplay>
3124<pre> 3392
3393```yue
3125print "You're lucky!" unless math.random! > 0.1 3394print "You're lucky!" unless math.random! > 0.1
3126</pre> 3395```
3396
3127</YueDisplay> 3397</YueDisplay>
3128 3398
3129### In Expression 3399### In Expression
3130 3400
3131You can write range checking code with an `in-expression`. 3401You can write range checking code with an `in-expression`.
3132 3402
3133```moonscript 3403```yuescript
3134a = 5 3404a = 5
3135 3405
3136if a in [1, 3, 5, 7] 3406if a in [1, 3, 5, 7]
@@ -3140,7 +3410,8 @@ if a in list
3140 print "checking if `a` is in a list" 3410 print "checking if `a` is in a list"
3141``` 3411```
3142<YueDisplay> 3412<YueDisplay>
3143<pre> 3413
3414```yue
3144a = 5 3415a = 5
3145 3416
3146if a in [1, 3, 5, 7] 3417if a in [1, 3, 5, 7]
@@ -3148,62 +3419,71 @@ if a in [1, 3, 5, 7]
3148 3419
3149if a in list 3420if a in list
3150 print "checking if `a` is in a list" 3421 print "checking if `a` is in a list"
3151</pre> 3422```
3423
3152</YueDisplay> 3424</YueDisplay>
3153 3425
3154```moonscript 3426```yuescript
3155print "You're lucky!" unless math.random! > 0.1 3427print "You're lucky!" unless math.random! > 0.1
3156``` 3428```
3157<YueDisplay> 3429<YueDisplay>
3158<pre> 3430
3431```yue
3159print "You're lucky!" unless math.random! > 0.1 3432print "You're lucky!" unless math.random! > 0.1
3160</pre> 3433```
3434
3161</YueDisplay> 3435</YueDisplay>
3162 3436
3163## Line Decorators 3437## Line Decorators
3164 3438
3165For convenience, the for loop and if statement can be applied to single statements at the end of the line: 3439For convenience, the for loop and if statement can be applied to single statements at the end of the line:
3166 3440
3167```moonscript 3441```yuescript
3168print "hello world" if name == "Rob" 3442print "hello world" if name == "Rob"
3169``` 3443```
3170<YueDisplay> 3444<YueDisplay>
3171<pre> 3445
3446```yue
3172print "hello world" if name == "Rob" 3447print "hello world" if name == "Rob"
3173</pre> 3448```
3449
3174</YueDisplay> 3450</YueDisplay>
3175 3451
3176And with basic loops: 3452And with basic loops:
3177 3453
3178```moonscript 3454```yuescript
3179print "item: ", item for item in *items 3455print "item: ", item for item in *items
3180``` 3456```
3181<YueDisplay> 3457<YueDisplay>
3182<pre> 3458
3459```yue
3183print "item: ", item for item in *items 3460print "item: ", item for item in *items
3184</pre> 3461```
3462
3185</YueDisplay> 3463</YueDisplay>
3186 3464
3187And with while loops: 3465And with while loops:
3188 3466
3189```moonscript 3467```yuescript
3190game\update! while game\isRunning! 3468game\update! while game\isRunning!
3191 3469
3192reader\parse_line! until reader\eof! 3470reader\parse_line! until reader\eof!
3193``` 3471```
3194<YueDisplay> 3472<YueDisplay>
3195<pre> 3473
3474```yue
3196game\update! while game\isRunning! 3475game\update! while game\isRunning!
3197 3476
3198reader\parse_line! until reader\eof! 3477reader\parse_line! until reader\eof!
3199</pre> 3478```
3479
3200</YueDisplay> 3480</YueDisplay>
3201 3481
3202## Switch 3482## Switch
3203 3483
3204The 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. 3484The 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.
3205 3485
3206```moonscript 3486```yuescript
3207switch name := "Dan" 3487switch name := "Dan"
3208 when "Robert" 3488 when "Robert"
3209 print "You are Robert" 3489 print "You are Robert"
@@ -3213,7 +3493,8 @@ switch name := "Dan"
3213 print "I don't know about you with name #{name}" 3493 print "I don't know about you with name #{name}"
3214``` 3494```
3215<YueDisplay> 3495<YueDisplay>
3216<pre> 3496
3497```yue
3217switch name := "Dan" 3498switch name := "Dan"
3218 when "Robert" 3499 when "Robert"
3219 print "You are Robert" 3500 print "You are Robert"
@@ -3221,14 +3502,15 @@ switch name := "Dan"
3221 print "Your name, it's Dan" 3502 print "Your name, it's Dan"
3222 else 3503 else
3223 print "I don't know about you with name #{name}" 3504 print "I don't know about you with name #{name}"
3224</pre> 3505```
3506
3225</YueDisplay> 3507</YueDisplay>
3226 3508
3227A switch when clause can match against multiple values by listing them out comma separated. 3509A switch when clause can match against multiple values by listing them out comma separated.
3228 3510
3229Switches can be used as expressions as well, here we can assign the result of the switch to a variable: 3511Switches can be used as expressions as well, here we can assign the result of the switch to a variable:
3230 3512
3231```moonscript 3513```yuescript
3232b = 1 3514b = 1
3233next_number = switch b 3515next_number = switch b
3234 when 1 3516 when 1
@@ -3239,7 +3521,8 @@ next_number = switch b
3239 error "can't count that high!" 3521 error "can't count that high!"
3240``` 3522```
3241<YueDisplay> 3523<YueDisplay>
3242<pre> 3524
3525```yue
3243b = 1 3526b = 1
3244next_number = switch b 3527next_number = switch b
3245 when 1 3528 when 1
@@ -3248,29 +3531,32 @@ next_number = switch b
3248 3 3531 3
3249 else 3532 else
3250 error "can't count that high!" 3533 error "can't count that high!"
3251</pre> 3534```
3535
3252</YueDisplay> 3536</YueDisplay>
3253 3537
3254We 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. 3538We 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.
3255 3539
3256```moonscript 3540```yuescript
3257msg = switch math.random(1, 5) 3541msg = switch math.random(1, 5)
3258 when 1 then "you are lucky" 3542 when 1 then "you are lucky"
3259 when 2 then "you are almost lucky" 3543 when 2 then "you are almost lucky"
3260 else "not so lucky" 3544 else "not so lucky"
3261``` 3545```
3262<YueDisplay> 3546<YueDisplay>
3263<pre> 3547
3548```yue
3264msg = switch math.random(1, 5) 3549msg = switch math.random(1, 5)
3265 when 1 then "you are lucky" 3550 when 1 then "you are lucky"
3266 when 2 then "you are almost lucky" 3551 when 2 then "you are almost lucky"
3267 else "not so lucky" 3552 else "not so lucky"
3268</pre> 3553```
3554
3269</YueDisplay> 3555</YueDisplay>
3270 3556
3271If you want to write code with one less indent when writing a switch statement, you can put the first when clause on the statement start line, and then all other clauses can be written with one less indent. 3557If you want to write code with one less indent when writing a switch statement, you can put the first when clause on the statement start line, and then all other clauses can be written with one less indent.
3272 3558
3273```moonscript 3559```yuescript
3274switch math.random(1, 5) 3560switch math.random(1, 5)
3275 when 1 3561 when 1
3276 print "you are lucky" -- two indents 3562 print "you are lucky" -- two indents
@@ -3283,7 +3569,8 @@ else
3283 print "not so lucky" 3569 print "not so lucky"
3284``` 3570```
3285<YueDisplay> 3571<YueDisplay>
3286<pre> 3572
3573```yue
3287switch math.random(1, 5) 3574switch math.random(1, 5)
3288 when 1 3575 when 1
3289 print "you are lucky" -- two indents 3576 print "you are lucky" -- two indents
@@ -3294,7 +3581,8 @@ switch math.random(1, 5) when 1
3294 print "you are lucky" -- one indent 3581 print "you are lucky" -- one indent
3295else 3582else
3296 print "not so lucky" 3583 print "not so lucky"
3297</pre> 3584```
3585
3298</YueDisplay> 3586</YueDisplay>
3299 3587
3300It 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. 3588It 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.
@@ -3303,7 +3591,7 @@ It is worth noting the order of the case comparison expression. The case's expre
3303 3591
3304You can do table matching in a switch when clause, if the table can be destructured by a specific structure and get non-nil values. 3592You can do table matching in a switch when clause, if the table can be destructured by a specific structure and get non-nil values.
3305 3593
3306```moonscript 3594```yuescript
3307items = 3595items =
3308 * x: 100 3596 * x: 100
3309 y: 200 3597 y: 200
@@ -3318,7 +3606,8 @@ for item in *items
3318 print "size #{width}, #{height}" 3606 print "size #{width}, #{height}"
3319``` 3607```
3320<YueDisplay> 3608<YueDisplay>
3321<pre> 3609
3610```yue
3322items = 3611items =
3323 * x: 100 3612 * x: 100
3324 y: 200 3613 y: 200
@@ -3331,12 +3620,13 @@ for item in *items
3331 print "Vec2 #{x}, #{y}" 3620 print "Vec2 #{x}, #{y}"
3332 when :width, :height 3621 when :width, :height
3333 print "size #{width}, #{height}" 3622 print "size #{width}, #{height}"
3334</pre> 3623```
3624
3335</YueDisplay> 3625</YueDisplay>
3336 3626
3337You can use default values to optionally destructure the table for some fields. 3627You can use default values to optionally destructure the table for some fields.
3338 3628
3339```moonscript 3629```yuescript
3340item = {} 3630item = {}
3341 3631
3342{pos: {:x = 50, :y = 200}} = item -- get error: attempt to index a nil value (field 'pos') 3632{pos: {:x = 50, :y = 200}} = item -- get error: attempt to index a nil value (field 'pos')
@@ -3346,7 +3636,8 @@ switch item
3346 print "Vec2 #{x}, #{y}" -- table destructuring will still pass 3636 print "Vec2 #{x}, #{y}" -- table destructuring will still pass
3347``` 3637```
3348<YueDisplay> 3638<YueDisplay>
3349<pre> 3639
3640```yue
3350item = {} 3641item = {}
3351 3642
3352{pos: {:x = 50, :y = 200}} = item -- get error: attempt to index a nil value (field 'pos') 3643{pos: {:x = 50, :y = 200}} = item -- get error: attempt to index a nil value (field 'pos')
@@ -3354,14 +3645,15 @@ item = {}
3354switch item 3645switch item
3355 when {pos: {:x = 50, :y = 200}} 3646 when {pos: {:x = 50, :y = 200}}
3356 print "Vec2 #{x}, #{y}" -- table destructuring will still pass 3647 print "Vec2 #{x}, #{y}" -- table destructuring will still pass
3357</pre> 3648```
3649
3358</YueDisplay> 3650</YueDisplay>
3359 3651
3360You can also match against array elements, table fields, and even nested structures with array or table literals. 3652You can also match against array elements, table fields, and even nested structures with array or table literals.
3361 3653
3362Match against array elements. 3654Match against array elements.
3363 3655
3364```moonscript 3656```yuescript
3365switch tb 3657switch tb
3366 when [1, 2, 3] 3658 when [1, 2, 3]
3367 print "1, 2, 3" 3659 print "1, 2, 3"
@@ -3371,7 +3663,8 @@ switch tb
3371 print "1, 2, #{b}" 3663 print "1, 2, #{b}"
3372``` 3664```
3373<YueDisplay> 3665<YueDisplay>
3374<pre> 3666
3667```yue
3375switch tb 3668switch tb
3376 when [1, 2, 3] 3669 when [1, 2, 3]
3377 print "1, 2, 3" 3670 print "1, 2, 3"
@@ -3379,12 +3672,13 @@ switch tb
3379 print "1, #{b}, 3" 3672 print "1, #{b}, 3"
3380 when [1, 2, b = 3] -- b has a default value 3673 when [1, 2, b = 3] -- b has a default value
3381 print "1, 2, #{b}" 3674 print "1, 2, #{b}"
3382</pre> 3675```
3676
3383</YueDisplay> 3677</YueDisplay>
3384 3678
3385Match against table fields with destructuring. 3679Match against table fields with destructuring.
3386 3680
3387```moonscript 3681```yuescript
3388switch tb 3682switch tb
3389 when success: true, :result 3683 when success: true, :result
3390 print "success", result 3684 print "success", result
@@ -3394,7 +3688,8 @@ switch tb
3394 print "invalid" 3688 print "invalid"
3395``` 3689```
3396<YueDisplay> 3690<YueDisplay>
3397<pre> 3691
3692```yue
3398switch tb 3693switch tb
3399 when success: true, :result 3694 when success: true, :result
3400 print "success", result 3695 print "success", result
@@ -3402,12 +3697,13 @@ switch tb
3402 print "failed", result 3697 print "failed", result
3403 else 3698 else
3404 print "invalid" 3699 print "invalid"
3405</pre> 3700```
3701
3406</YueDisplay> 3702</YueDisplay>
3407 3703
3408Match against nested table structures. 3704Match against nested table structures.
3409 3705
3410```moonscript 3706```yuescript
3411switch tb 3707switch tb
3412 when data: {type: "success", :content} 3708 when data: {type: "success", :content}
3413 print "success", content 3709 print "success", content
@@ -3417,7 +3713,8 @@ switch tb
3417 print "invalid" 3713 print "invalid"
3418``` 3714```
3419<YueDisplay> 3715<YueDisplay>
3420<pre> 3716
3717```yue
3421switch tb 3718switch tb
3422 when data: {type: "success", :content} 3719 when data: {type: "success", :content}
3423 print "success", content 3720 print "success", content
@@ -3425,12 +3722,13 @@ switch tb
3425 print "failed", content 3722 print "failed", content
3426 else 3723 else
3427 print "invalid" 3724 print "invalid"
3428</pre> 3725```
3726
3429</YueDisplay> 3727</YueDisplay>
3430 3728
3431Match against array of tables. 3729Match against array of tables.
3432 3730
3433```moonscript 3731```yuescript
3434switch tb 3732switch tb
3435 when [ 3733 when [
3436 {a: 1, b: 2} 3734 {a: 1, b: 2}
@@ -3441,7 +3739,8 @@ switch tb
3441 print "matched", fourth 3739 print "matched", fourth
3442``` 3740```
3443<YueDisplay> 3741<YueDisplay>
3444<pre> 3742
3743```yue
3445switch tb 3744switch tb
3446 when [ 3745 when [
3447 {a: 1, b: 2} 3746 {a: 1, b: 2}
@@ -3450,12 +3749,13 @@ switch tb
3450 fourth 3749 fourth
3451 ] 3750 ]
3452 print "matched", fourth 3751 print "matched", fourth
3453</pre> 3752```
3753
3454</YueDisplay> 3754</YueDisplay>
3455 3755
3456Match against a list and capture a range of elements. 3756Match against a list and capture a range of elements.
3457 3757
3458```moonscript 3758```yuescript
3459segments = ["admin", "users", "logs", "view"] 3759segments = ["admin", "users", "logs", "view"]
3460switch segments 3760switch segments
3461 when [...groups, resource, action] 3761 when [...groups, resource, action]
@@ -3464,14 +3764,16 @@ switch segments
3464 print "Action:", action -- prints: "view" 3764 print "Action:", action -- prints: "view"
3465``` 3765```
3466<YueDisplay> 3766<YueDisplay>
3467<pre> 3767
3768```yue
3468segments = ["admin", "users", "logs", "view"] 3769segments = ["admin", "users", "logs", "view"]
3469switch segments 3770switch segments
3470 when [...groups, resource, action] 3771 when [...groups, resource, action]
3471 print "Group:", groups -- prints: {"admin", "users"} 3772 print "Group:", groups -- prints: {"admin", "users"}
3472 print "Resource:", resource -- prints: "logs" 3773 print "Resource:", resource -- prints: "logs"
3473 print "Action:", action -- prints: "view" 3774 print "Action:", action -- prints: "view"
3474</pre> 3775```
3776
3475</YueDisplay> 3777</YueDisplay>
3476 3778
3477## Object Oriented Programming 3779## Object Oriented Programming
@@ -3480,7 +3782,7 @@ In these examples, the generated Lua code may appear overwhelming. It is best to
3480 3782
3481A simple class: 3783A simple class:
3482 3784
3483```moonscript 3785```yuescript
3484class Inventory 3786class Inventory
3485 new: => 3787 new: =>
3486 @items = {} 3788 @items = {}
@@ -3492,7 +3794,8 @@ class Inventory
3492 @items[name] = 1 3794 @items[name] = 1
3493``` 3795```
3494<YueDisplay> 3796<YueDisplay>
3495<pre> 3797
3798```yue
3496class Inventory 3799class Inventory
3497 new: => 3800 new: =>
3498 @items = {} 3801 @items = {}
@@ -3502,7 +3805,8 @@ class Inventory
3502 @items[name] += 1 3805 @items[name] += 1
3503 else 3806 else
3504 @items[name] = 1 3807 @items[name] = 1
3505</pre> 3808```
3809
3506</YueDisplay> 3810</YueDisplay>
3507 3811
3508A class is declared with a class statement followed by a table-like declaration where all of the methods and properties are listed. 3812A class is declared with a class statement followed by a table-like declaration where all of the methods and properties are listed.
@@ -3515,17 +3819,19 @@ The @ prefix on a variable name is shorthand for self.. @items becomes self.item
3515 3819
3516Creating an instance of the class is done by calling the name of the class as a function. 3820Creating an instance of the class is done by calling the name of the class as a function.
3517 3821
3518```moonscript 3822```yuescript
3519inv = Inventory! 3823inv = Inventory!
3520inv\add_item "t-shirt" 3824inv\add_item "t-shirt"
3521inv\add_item "pants" 3825inv\add_item "pants"
3522``` 3826```
3523<YueDisplay> 3827<YueDisplay>
3524<pre> 3828
3829```yue
3525inv = Inventory! 3830inv = Inventory!
3526inv\add_item "t-shirt" 3831inv\add_item "t-shirt"
3527inv\add_item "pants" 3832inv\add_item "pants"
3528</pre> 3833```
3834
3529</YueDisplay> 3835</YueDisplay>
3530 3836
3531Because the instance of the class needs to be sent to the methods when they are called, the \ operator is used. 3837Because the instance of the class needs to be sent to the methods when they are called, the \ operator is used.
@@ -3534,7 +3840,7 @@ All properties of a class are shared among the instances. This is fine for funct
3534 3840
3535Consider the example below, the clothes property is shared amongst all instances, so modifications to it in one instance will show up in another: 3841Consider the example below, the clothes property is shared amongst all instances, so modifications to it in one instance will show up in another:
3536 3842
3537```moonscript 3843```yuescript
3538class Person 3844class Person
3539 clothes: [] 3845 clothes: []
3540 give_item: (name) => 3846 give_item: (name) =>
@@ -3550,7 +3856,8 @@ b\give_item "shirt"
3550print item for item in *a.clothes 3856print item for item in *a.clothes
3551``` 3857```
3552<YueDisplay> 3858<YueDisplay>
3553<pre> 3859
3860```yue
3554class Person 3861class Person
3555 clothes: [] 3862 clothes: []
3556 give_item: (name) => 3863 give_item: (name) =>
@@ -3564,29 +3871,32 @@ b\give_item "shirt"
3564 3871
3565-- will print both pants and shirt 3872-- will print both pants and shirt
3566print item for item in *a.clothes 3873print item for item in *a.clothes
3567</pre> 3874```
3875
3568</YueDisplay> 3876</YueDisplay>
3569 3877
3570The proper way to avoid this problem is to create the mutable state of the object in the constructor: 3878The proper way to avoid this problem is to create the mutable state of the object in the constructor:
3571 3879
3572```moonscript 3880```yuescript
3573class Person 3881class Person
3574 new: => 3882 new: =>
3575 @clothes = [] 3883 @clothes = []
3576``` 3884```
3577<YueDisplay> 3885<YueDisplay>
3578<pre> 3886
3887```yue
3579class Person 3888class Person
3580 new: => 3889 new: =>
3581 @clothes = [] 3890 @clothes = []
3582</pre> 3891```
3892
3583</YueDisplay> 3893</YueDisplay>
3584 3894
3585### Inheritance 3895### Inheritance
3586 3896
3587The extends keyword can be used in a class declaration to inherit the properties and methods from another class. 3897The extends keyword can be used in a class declaration to inherit the properties and methods from another class.
3588 3898
3589```moonscript 3899```yuescript
3590class BackPack extends Inventory 3900class BackPack extends Inventory
3591 size: 10 3901 size: 10
3592 add_item: (name) => 3902 add_item: (name) =>
@@ -3594,13 +3904,15 @@ class BackPack extends Inventory
3594 super name 3904 super name
3595``` 3905```
3596<YueDisplay> 3906<YueDisplay>
3597<pre> 3907
3908```yue
3598class BackPack extends Inventory 3909class BackPack extends Inventory
3599 size: 10 3910 size: 10
3600 add_item: (name) => 3911 add_item: (name) =>
3601 if #@items > size then error "backpack is full" 3912 if #@items > size then error "backpack is full"
3602 super name 3913 super name
3603</pre> 3914```
3915
3604</YueDisplay> 3916</YueDisplay>
3605 3917
3606Here we extend our Inventory class, and limit the amount of items it can carry. 3918Here we extend our Inventory class, and limit the amount of items it can carry.
@@ -3609,7 +3921,7 @@ In this example, we don't define a constructor on the subclass, so the parent cl
3609 3921
3610Whenever 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. 3922Whenever 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.
3611 3923
3612```moonscript 3924```yuescript
3613class Shelf 3925class Shelf
3614 @__inherited: (child) => 3926 @__inherited: (child) =>
3615 print @__name, "was inherited by", child.__name 3927 print @__name, "was inherited by", child.__name
@@ -3618,14 +3930,16 @@ class Shelf
3618class Cupboard extends Shelf 3930class Cupboard extends Shelf
3619``` 3931```
3620<YueDisplay> 3932<YueDisplay>
3621<pre> 3933
3934```yue
3622class Shelf 3935class Shelf
3623 @__inherited: (child) => 3936 @__inherited: (child) =>
3624 print @__name, "was inherited by", child.__name 3937 print @__name, "was inherited by", child.__name
3625 3938
3626-- will print: Shelf was inherited by Cupboard 3939-- will print: Shelf was inherited by Cupboard
3627class Cupboard extends Shelf 3940class Cupboard extends Shelf
3628</pre> 3941```
3942
3629</YueDisplay> 3943</YueDisplay>
3630 3944
3631### Super 3945### Super
@@ -3642,7 +3956,7 @@ When the \ calling operator is used with super, self is inserted as the first ar
3642 3956
3643A few examples of using super in different ways: 3957A few examples of using super in different ways:
3644 3958
3645```moonscript 3959```yuescript
3646class MyClass extends ParentClass 3960class MyClass extends ParentClass
3647 a_method: => 3961 a_method: =>
3648 -- the following have the same effect: 3962 -- the following have the same effect:
@@ -3654,7 +3968,8 @@ class MyClass extends ParentClass
3654 assert super == ParentClass 3968 assert super == ParentClass
3655``` 3969```
3656<YueDisplay> 3970<YueDisplay>
3657<pre> 3971
3972```yue
3658class MyClass extends ParentClass 3973class MyClass extends ParentClass
3659 a_method: => 3974 a_method: =>
3660 -- the following have the same effect: 3975 -- the following have the same effect:
@@ -3664,7 +3979,8 @@ class MyClass extends ParentClass
3664 3979
3665 -- super as a value is equal to the parent class: 3980 -- super as a value is equal to the parent class:
3666 assert super == ParentClass 3981 assert super == ParentClass
3667</pre> 3982```
3983
3668</YueDisplay> 3984</YueDisplay>
3669 3985
3670**super** can also be used on left side of a Function Stub. The only major difference is that instead of the resulting function being bound to the value of super, it is bound to self. 3986**super** can also be used on left side of a Function Stub. The only major difference is that instead of the resulting function being bound to the value of super, it is bound to self.
@@ -3673,19 +3989,21 @@ class MyClass extends ParentClass
3673 3989
3674Every instance of a class carries its type with it. This is stored in the special __class property. This property holds the class object. The class object is what we call to build a new instance. We can also index the class object to retrieve class methods and properties. 3990Every instance of a class carries its type with it. This is stored in the special __class property. This property holds the class object. The class object is what we call to build a new instance. We can also index the class object to retrieve class methods and properties.
3675 3991
3676```moonscript 3992```yuescript
3677b = BackPack! 3993b = BackPack!
3678assert b.__class == BackPack 3994assert b.__class == BackPack
3679 3995
3680print BackPack.size -- prints 10 3996print BackPack.size -- prints 10
3681``` 3997```
3682<YueDisplay> 3998<YueDisplay>
3683<pre> 3999
4000```yue
3684b = BackPack! 4001b = BackPack!
3685assert b.__class == BackPack 4002assert b.__class == BackPack
3686 4003
3687print BackPack.size -- prints 10 4004print BackPack.size -- prints 10
3688</pre> 4005```
4006
3689</YueDisplay> 4007</YueDisplay>
3690 4008
3691### Class Objects 4009### Class Objects
@@ -3704,13 +4022,15 @@ The class object has a couple special properties:
3704 4022
3705The name of the class as when it was declared is stored as a string in the __name field of the class object. 4023The name of the class as when it was declared is stored as a string in the __name field of the class object.
3706 4024
3707```moonscript 4025```yuescript
3708print BackPack.__name -- prints Backpack 4026print BackPack.__name -- prints Backpack
3709``` 4027```
3710<YueDisplay> 4028<YueDisplay>
3711<pre> 4029
4030```yue
3712print BackPack.__name -- prints Backpack 4031print BackPack.__name -- prints Backpack
3713</pre> 4032```
4033
3714</YueDisplay> 4034</YueDisplay>
3715 4035
3716The base object is stored in __base. We can modify this table to add functionality to instances that have already been created and ones that are yet to be created. 4036The base object is stored in __base. We can modify this table to add functionality to instances that have already been created and ones that are yet to be created.
@@ -3721,7 +4041,7 @@ If the class extends from anything, the parent class object is stored in __paren
3721 4041
3722We can create variables directly in the class object instead of in the base by using @ in the front of the property name in a class declaration. 4042We can create variables directly in the class object instead of in the base by using @ in the front of the property name in a class declaration.
3723 4043
3724```moonscript 4044```yuescript
3725class Things 4045class Things
3726 @some_func: => print "Hello from", @__name 4046 @some_func: => print "Hello from", @__name
3727 4047
@@ -3731,7 +4051,8 @@ Things\some_func!
3731assert Things().some_func == nil 4051assert Things().some_func == nil
3732``` 4052```
3733<YueDisplay> 4053<YueDisplay>
3734<pre> 4054
4055```yue
3735class Things 4056class Things
3736 @some_func: => print "Hello from", @__name 4057 @some_func: => print "Hello from", @__name
3737 4058
@@ -3739,12 +4060,13 @@ Things\some_func!
3739 4060
3740-- class variables not visible in instances 4061-- class variables not visible in instances
3741assert Things().some_func == nil 4062assert Things().some_func == nil
3742</pre> 4063```
4064
3743</YueDisplay> 4065</YueDisplay>
3744 4066
3745In expressions, we can use @@ to access a value that is stored in the __class of self. Thus, @@hello is shorthand for self.__class.hello. 4067In expressions, we can use @@ to access a value that is stored in the __class of self. Thus, @@hello is shorthand for self.__class.hello.
3746 4068
3747```moonscript 4069```yuescript
3748class Counter 4070class Counter
3749 @count: 0 4071 @count: 0
3750 4072
@@ -3757,7 +4079,8 @@ Counter!
3757print Counter.count -- prints 2 4079print Counter.count -- prints 2
3758``` 4080```
3759<YueDisplay> 4081<YueDisplay>
3760<pre> 4082
4083```yue
3761class Counter 4084class Counter
3762 @count: 0 4085 @count: 0
3763 4086
@@ -3768,18 +4091,21 @@ Counter!
3768Counter! 4091Counter!
3769 4092
3770print Counter.count -- prints 2 4093print Counter.count -- prints 2
3771</pre> 4094```
4095
3772</YueDisplay> 4096</YueDisplay>
3773 4097
3774The calling semantics of @@ are similar to @. Calling a @@ name will pass the class in as the first argument using Lua's colon syntax. 4098The calling semantics of @@ are similar to @. Calling a @@ name will pass the class in as the first argument using Lua's colon syntax.
3775 4099
3776```moonscript 4100```yuescript
3777@@hello 1,2,3,4 4101@@hello 1,2,3,4
3778``` 4102```
3779<YueDisplay> 4103<YueDisplay>
3780<pre> 4104
4105```yue
3781@@hello 1,2,3,4 4106@@hello 1,2,3,4
3782</pre> 4107```
4108
3783</YueDisplay> 4109</YueDisplay>
3784 4110
3785### Class Declaration Statements 4111### Class Declaration Statements
@@ -3788,22 +4114,24 @@ In the body of a class declaration, we can have normal expressions in addition t
3788 4114
3789Here is an alternative way to create a class variable compared to what's described above: 4115Here is an alternative way to create a class variable compared to what's described above:
3790 4116
3791```moonscript 4117```yuescript
3792class Things 4118class Things
3793 @class_var = "hello world" 4119 @class_var = "hello world"
3794``` 4120```
3795<YueDisplay> 4121<YueDisplay>
3796<pre> 4122
4123```yue
3797class Things 4124class Things
3798 @class_var = "hello world" 4125 @class_var = "hello world"
3799</pre> 4126```
4127
3800</YueDisplay> 4128</YueDisplay>
3801 4129
3802These expressions are executed after all the properties have been added to the base. 4130These expressions are executed after all the properties have been added to the base.
3803 4131
3804All variables declared in the body of the class are local to the classes properties. This is convenient for placing private values or helper functions that only the class methods can access: 4132All variables declared in the body of the class are local to the classes properties. This is convenient for placing private values or helper functions that only the class methods can access:
3805 4133
3806```moonscript 4134```yuescript
3807class MoreThings 4135class MoreThings
3808 secret = 123 4136 secret = 123
3809 log = (msg) -> print "LOG:", msg 4137 log = (msg) -> print "LOG:", msg
@@ -3812,14 +4140,16 @@ class MoreThings
3812 log "hello world: " .. secret 4140 log "hello world: " .. secret
3813``` 4141```
3814<YueDisplay> 4142<YueDisplay>
3815<pre> 4143
4144```yue
3816class MoreThings 4145class MoreThings
3817 secret = 123 4146 secret = 123
3818 log = (msg) -> print "LOG:", msg 4147 log = (msg) -> print "LOG:", msg
3819 4148
3820 some_method: => 4149 some_method: =>
3821 log "hello world: " .. secret 4150 log "hello world: " .. secret
3822</pre> 4151```
4152
3823</YueDisplay> 4153</YueDisplay>
3824 4154
3825### @ and @@ Values 4155### @ and @@ Values
@@ -3828,33 +4158,37 @@ When @ and @@ are prefixed in front of a name they represent, respectively, that
3828 4158
3829If they are used all by themselves, they are aliases for self and self.__class. 4159If they are used all by themselves, they are aliases for self and self.__class.
3830 4160
3831```moonscript 4161```yuescript
3832assert @ == self 4162assert @ == self
3833assert @@ == self.__class 4163assert @@ == self.__class
3834``` 4164```
3835<YueDisplay> 4165<YueDisplay>
3836<pre> 4166
4167```yue
3837assert @ == self 4168assert @ == self
3838assert @@ == self.__class 4169assert @@ == self.__class
3839</pre> 4170```
4171
3840</YueDisplay> 4172</YueDisplay>
3841 4173
3842For example, a quick way to create a new instance of the same class from an instance method using @@: 4174For example, a quick way to create a new instance of the same class from an instance method using @@:
3843 4175
3844```moonscript 4176```yuescript
3845some_instance_method = (...) => @@ ... 4177some_instance_method = (...) => @@ ...
3846``` 4178```
3847<YueDisplay> 4179<YueDisplay>
3848<pre> 4180
4181```yue
3849some_instance_method = (...) => @@ ... 4182some_instance_method = (...) => @@ ...
3850</pre> 4183```
4184
3851</YueDisplay> 4185</YueDisplay>
3852 4186
3853### Constructor Property Promotion 4187### Constructor Property Promotion
3854 4188
3855To reduce the boilerplate code for definition of simple value objects. You can write a simple class like: 4189To reduce the boilerplate code for definition of simple value objects. You can write a simple class like:
3856 4190
3857```moonscript 4191```yuescript
3858class Something 4192class Something
3859 new: (@foo, @bar, @@biz, @@baz) => 4193 new: (@foo, @bar, @@biz, @@baz) =>
3860 4194
@@ -3868,7 +4202,8 @@ class Something
3868 @@baz = baz 4202 @@baz = baz
3869``` 4203```
3870<YueDisplay> 4204<YueDisplay>
3871<pre> 4205
4206```yue
3872class Something 4207class Something
3873 new: (@foo, @bar, @@biz, @@baz) => 4208 new: (@foo, @bar, @@biz, @@baz) =>
3874 4209
@@ -3880,76 +4215,85 @@ class Something
3880 @bar = bar 4215 @bar = bar
3881 @@biz = biz 4216 @@biz = biz
3882 @@baz = baz 4217 @@baz = baz
3883</pre> 4218```
4219
3884</YueDisplay> 4220</YueDisplay>
3885 4221
3886You can also use this syntax for a common function to initialize a object's fields. 4222You can also use this syntax for a common function to initialize a object's fields.
3887 4223
3888```moonscript 4224```yuescript
3889new = (@fieldA, @fieldB) => @ 4225new = (@fieldA, @fieldB) => @
3890obj = new {}, 123, "abc" 4226obj = new {}, 123, "abc"
3891print obj 4227print obj
3892``` 4228```
3893<YueDisplay> 4229<YueDisplay>
3894<pre> 4230
4231```yue
3895new = (@fieldA, @fieldB) => @ 4232new = (@fieldA, @fieldB) => @
3896obj = new {}, 123, "abc" 4233obj = new {}, 123, "abc"
3897print obj 4234print obj
3898</pre> 4235```
4236
3899</YueDisplay> 4237</YueDisplay>
3900 4238
3901### Class Expressions 4239### Class Expressions
3902 4240
3903The class syntax can also be used as an expression which can be assigned to a variable or explicitly returned. 4241The class syntax can also be used as an expression which can be assigned to a variable or explicitly returned.
3904 4242
3905```moonscript 4243```yuescript
3906x = class Bucket 4244x = class Bucket
3907 drops: 0 4245 drops: 0
3908 add_drop: => @drops += 1 4246 add_drop: => @drops += 1
3909``` 4247```
3910<YueDisplay> 4248<YueDisplay>
3911<pre> 4249
4250```yue
3912x = class Bucket 4251x = class Bucket
3913 drops: 0 4252 drops: 0
3914 add_drop: => @drops += 1 4253 add_drop: => @drops += 1
3915</pre> 4254```
4255
3916</YueDisplay> 4256</YueDisplay>
3917 4257
3918### Anonymous classes 4258### Anonymous classes
3919 4259
3920The name can be left out when declaring a class. The __name attribute will be nil, unless the class expression is in an assignment. The name on the left hand side of the assignment is used instead of nil. 4260The name can be left out when declaring a class. The __name attribute will be nil, unless the class expression is in an assignment. The name on the left hand side of the assignment is used instead of nil.
3921 4261
3922```moonscript 4262```yuescript
3923BigBucket = class extends Bucket 4263BigBucket = class extends Bucket
3924 add_drop: => @drops += 10 4264 add_drop: => @drops += 10
3925 4265
3926assert Bucket.__name == "BigBucket" 4266assert Bucket.__name == "BigBucket"
3927``` 4267```
3928<YueDisplay> 4268<YueDisplay>
3929<pre> 4269
4270```yue
3930BigBucket = class extends Bucket 4271BigBucket = class extends Bucket
3931 add_drop: => @drops += 10 4272 add_drop: => @drops += 10
3932 4273
3933assert Bucket.__name == "BigBucket" 4274assert Bucket.__name == "BigBucket"
3934</pre> 4275```
4276
3935</YueDisplay> 4277</YueDisplay>
3936 4278
3937You can even leave off the body, meaning you can write a blank anonymous class like this: 4279You can even leave off the body, meaning you can write a blank anonymous class like this:
3938 4280
3939```moonscript 4281```yuescript
3940x = class 4282x = class
3941``` 4283```
3942<YueDisplay> 4284<YueDisplay>
3943<pre> 4285
4286```yue
3944x = class 4287x = class
3945</pre> 4288```
4289
3946</YueDisplay> 4290</YueDisplay>
3947 4291
3948### Class Mixing 4292### Class Mixing
3949 4293
3950You can do mixing with keyword `using` to copy functions from either a plain table or a predefined class object into your new class. When doing mixing with a plain table, you can override the class indexing function (metamethod `__index`) to your customized implementation. When doing mixing with an existing class object, the class object's metamethods won't be copied. 4294You can do mixing with keyword `using` to copy functions from either a plain table or a predefined class object into your new class. When doing mixing with a plain table, you can override the class indexing function (metamethod `__index`) to your customized implementation. When doing mixing with an existing class object, the class object's metamethods won't be copied.
3951 4295
3952```moonscript 4296```yuescript
3953MyIndex = __index: var: 1 4297MyIndex = __index: var: 1
3954 4298
3955class X using MyIndex 4299class X using MyIndex
@@ -3967,7 +4311,8 @@ y\func!
3967assert y.__class.__parent ~= X -- X is not parent of Y 4311assert y.__class.__parent ~= X -- X is not parent of Y
3968``` 4312```
3969<YueDisplay> 4313<YueDisplay>
3970<pre> 4314
4315```yue
3971MyIndex = __index: var: 1 4316MyIndex = __index: var: 1
3972 4317
3973class X using MyIndex 4318class X using MyIndex
@@ -3983,7 +4328,8 @@ y = Y!
3983y\func! 4328y\func!
3984 4329
3985assert y.__class.__parent ~= X -- X is not parent of Y 4330assert y.__class.__parent ~= X -- X is not parent of Y
3986</pre> 4331```
4332
3987</YueDisplay> 4333</YueDisplay>
3988 4334
3989## With Statement 4335## With Statement
@@ -3996,7 +4342,7 @@ The with block helps to alleviate this. Within a with block we can use a special
3996 4342
3997For example, we work with a newly created object: 4343For example, we work with a newly created object:
3998 4344
3999```moonscript 4345```yuescript
4000with Person! 4346with Person!
4001 .name = "Oswald" 4347 .name = "Oswald"
4002 \add_relative my_dad 4348 \add_relative my_dad
@@ -4004,31 +4350,35 @@ with Person!
4004 print .name 4350 print .name
4005``` 4351```
4006<YueDisplay> 4352<YueDisplay>
4007<pre> 4353
4354```yue
4008with Person! 4355with Person!
4009 .name = "Oswald" 4356 .name = "Oswald"
4010 \add_relative my_dad 4357 \add_relative my_dad
4011 \save! 4358 \save!
4012 print .name 4359 print .name
4013</pre> 4360```
4361
4014</YueDisplay> 4362</YueDisplay>
4015 4363
4016The with statement can also be used as an expression which returns the value it has been giving access to. 4364The with statement can also be used as an expression which returns the value it has been giving access to.
4017 4365
4018```moonscript 4366```yuescript
4019file = with File "favorite_foods.txt" 4367file = with File "favorite_foods.txt"
4020 \set_encoding "utf8" 4368 \set_encoding "utf8"
4021``` 4369```
4022<YueDisplay> 4370<YueDisplay>
4023<pre> 4371
4372```yue
4024file = with File "favorite_foods.txt" 4373file = with File "favorite_foods.txt"
4025 \set_encoding "utf8" 4374 \set_encoding "utf8"
4026</pre> 4375```
4376
4027</YueDisplay> 4377</YueDisplay>
4028 4378
4029Or… 4379Or…
4030 4380
4031```moonscript 4381```yuescript
4032create_person = (name, relatives) -> 4382create_person = (name, relatives) ->
4033 with Person! 4383 with Person!
4034 .name = name 4384 .name = name
@@ -4037,36 +4387,40 @@ create_person = (name, relatives) ->
4037me = create_person "Leaf", [dad, mother, sister] 4387me = create_person "Leaf", [dad, mother, sister]
4038``` 4388```
4039<YueDisplay> 4389<YueDisplay>
4040<pre> 4390
4391```yue
4041create_person = (name, relatives) -> 4392create_person = (name, relatives) ->
4042 with Person! 4393 with Person!
4043 .name = name 4394 .name = name
4044 \add_relative relative for relative in *relatives 4395 \add_relative relative for relative in *relatives
4045 4396
4046me = create_person "Leaf", [dad, mother, sister] 4397me = create_person "Leaf", [dad, mother, sister]
4047</pre> 4398```
4399
4048</YueDisplay> 4400</YueDisplay>
4049 4401
4050In this usage, with can be seen as a special form of the K combinator. 4402In this usage, with can be seen as a special form of the K combinator.
4051 4403
4052The expression in the with statement can also be an assignment, if you want to give a name to the expression. 4404The expression in the with statement can also be an assignment, if you want to give a name to the expression.
4053 4405
4054```moonscript 4406```yuescript
4055with str := "Hello" 4407with str := "Hello"
4056 print "original:", str 4408 print "original:", str
4057 print "upper:", \upper! 4409 print "upper:", \upper!
4058``` 4410```
4059<YueDisplay> 4411<YueDisplay>
4060<pre> 4412
4413```yue
4061with str := "Hello" 4414with str := "Hello"
4062 print "original:", str 4415 print "original:", str
4063 print "upper:", \upper! 4416 print "upper:", \upper!
4064</pre> 4417```
4418
4065</YueDisplay> 4419</YueDisplay>
4066 4420
4067You can access special keys with `[]` in a `with` statement. 4421You can access special keys with `[]` in a `with` statement.
4068 4422
4069```moonscript 4423```yuescript
4070with tb 4424with tb
4071 [1] = 1 4425 [1] = 1
4072 print [2] 4426 print [2]
@@ -4076,7 +4430,8 @@ with tb
4076 [] = "abc" -- appending to "tb" 4430 [] = "abc" -- appending to "tb"
4077``` 4431```
4078<YueDisplay> 4432<YueDisplay>
4079<pre> 4433
4434```yue
4080with tb 4435with tb
4081 [1] = 1 4436 [1] = 1
4082 print [2] 4437 print [2]
@@ -4084,44 +4439,49 @@ with tb
4084 [3] = [2]\func! 4439 [3] = [2]\func!
4085 ["key-name"] = value 4440 ["key-name"] = value
4086 [] = "abc" -- appending to "tb" 4441 [] = "abc" -- appending to "tb"
4087</pre> 4442```
4443
4088</YueDisplay> 4444</YueDisplay>
4089 4445
4090`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. 4446`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.
4091 4447
4092```moonscript 4448```yuescript
4093with? obj 4449with? obj
4094 print obj.name 4450 print obj.name
4095``` 4451```
4096<YueDisplay> 4452<YueDisplay>
4097<pre> 4453
4454```yue
4098with? obj 4455with? obj
4099 print obj.name 4456 print obj.name
4100</pre> 4457```
4458
4101</YueDisplay> 4459</YueDisplay>
4102 4460
4103## Do 4461## Do
4104 4462
4105When used as a statement, do works just like it does in Lua. 4463When used as a statement, do works just like it does in Lua.
4106 4464
4107```moonscript 4465```yuescript
4108do 4466do
4109 var = "hello" 4467 var = "hello"
4110 print var 4468 print var
4111print var -- nil here 4469print var -- nil here
4112``` 4470```
4113<YueDisplay> 4471<YueDisplay>
4114<pre> 4472
4473```yue
4115do 4474do
4116 var = "hello" 4475 var = "hello"
4117 print var 4476 print var
4118print var -- nil here 4477print var -- nil here
4119</pre> 4478```
4479
4120</YueDisplay> 4480</YueDisplay>
4121 4481
4122YueScript'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. 4482YueScript'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.
4123 4483
4124```moonscript 4484```yuescript
4125counter = do 4485counter = do
4126 i = 0 4486 i = 0
4127 -> 4487 ->
@@ -4132,7 +4492,8 @@ print counter!
4132print counter! 4492print counter!
4133``` 4493```
4134<YueDisplay> 4494<YueDisplay>
4135<pre> 4495
4496```yue
4136counter = do 4497counter = do
4137 i = 0 4498 i = 0
4138 -> 4499 ->
@@ -4141,10 +4502,11 @@ counter = do
4141 4502
4142print counter! 4503print counter!
4143print counter! 4504print counter!
4144</pre> 4505```
4506
4145</YueDisplay> 4507</YueDisplay>
4146 4508
4147```moonscript 4509```yuescript
4148tbl = { 4510tbl = {
4149 key: do 4511 key: do
4150 print "assigning key!" 4512 print "assigning key!"
@@ -4152,13 +4514,15 @@ tbl = {
4152} 4514}
4153``` 4515```
4154<YueDisplay> 4516<YueDisplay>
4155<pre> 4517
4518```yue
4156tbl = { 4519tbl = {
4157 key: do 4520 key: do
4158 print "assigning key!" 4521 print "assigning key!"
4159 1234 4522 1234
4160} 4523}
4161</pre> 4524```
4525
4162</YueDisplay> 4526</YueDisplay>
4163 4527
4164## Function Stubs 4528## Function Stubs
@@ -4169,7 +4533,7 @@ The function stub syntax is a shorthand for creating a new closure function that
4169 4533
4170Its syntax is the same as calling an instance method with the \ operator but with no argument list provided. 4534Its syntax is the same as calling an instance method with the \ operator but with no argument list provided.
4171 4535
4172```moonscript 4536```yuescript
4173my_object = { 4537my_object = {
4174 value: 1000 4538 value: 1000
4175 write: => print "the value:", @value 4539 write: => print "the value:", @value
@@ -4188,7 +4552,8 @@ run_callback my_object.write
4188run_callback my_object\write 4552run_callback my_object\write
4189``` 4553```
4190<YueDisplay> 4554<YueDisplay>
4191<pre> 4555
4556```yue
4192my_object = { 4557my_object = {
4193 value: 1000 4558 value: 1000
4194 write: => print "the value:", @value 4559 write: => print "the value:", @value
@@ -4205,14 +4570,15 @@ run_callback my_object.write
4205-- function stub syntax 4570-- function stub syntax
4206-- lets us bundle the object into a new function 4571-- lets us bundle the object into a new function
4207run_callback my_object\write 4572run_callback my_object\write
4208</pre> 4573```
4574
4209</YueDisplay> 4575</YueDisplay>
4210 4576
4211## The Using Clause; Controlling Destructive Assignment 4577## The Using Clause; Controlling Destructive Assignment
4212 4578
4213While lexical scoping can be a great help in reducing the complexity of the code we write, things can get unwieldy as the code size increases. Consider the following snippet: 4579While lexical scoping can be a great help in reducing the complexity of the code we write, things can get unwieldy as the code size increases. Consider the following snippet:
4214 4580
4215```moonscript 4581```yuescript
4216i = 100 4582i = 100
4217 4583
4218-- many lines of code... 4584-- many lines of code...
@@ -4228,7 +4594,8 @@ my_func!
4228print i -- will print 0 4594print i -- will print 0
4229``` 4595```
4230<YueDisplay> 4596<YueDisplay>
4231<pre> 4597
4598```yue
4232i = 100 4599i = 100
4233 4600
4234-- many lines of code... 4601-- many lines of code...
@@ -4242,7 +4609,8 @@ my_func = ->
4242my_func! 4609my_func!
4243 4610
4244print i -- will print 0 4611print i -- will print 0
4245</pre> 4612```
4613
4246</YueDisplay> 4614</YueDisplay>
4247 4615
4248In 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. 4616In 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.
@@ -4251,7 +4619,7 @@ It would be helpful to say which variables from the enclosing scope we intend on
4251 4619
4252The using keyword lets us do that. using nil makes sure that no closed variables are overwritten in assignment. The using clause is placed after the argument list in a function, or in place of it if there are no arguments. 4620The using keyword lets us do that. using nil makes sure that no closed variables are overwritten in assignment. The using clause is placed after the argument list in a function, or in place of it if there are no arguments.
4253 4621
4254```moonscript 4622```yuescript
4255i = 100 4623i = 100
4256 4624
4257my_func = (using nil) -> 4625my_func = (using nil) ->
@@ -4261,7 +4629,8 @@ my_func!
4261print i -- prints 100, i is unaffected 4629print i -- prints 100, i is unaffected
4262``` 4630```
4263<YueDisplay> 4631<YueDisplay>
4264<pre> 4632
4633```yue
4265i = 100 4634i = 100
4266 4635
4267my_func = (using nil) -> 4636my_func = (using nil) ->
@@ -4269,12 +4638,13 @@ my_func = (using nil) ->
4269 4638
4270my_func! 4639my_func!
4271print i -- prints 100, i is unaffected 4640print i -- prints 100, i is unaffected
4272</pre> 4641```
4642
4273</YueDisplay> 4643</YueDisplay>
4274 4644
4275Multiple names can be separated by commas. Closure values can still be accessed, they just cant be modified: 4645Multiple names can be separated by commas. Closure values can still be accessed, they just cant be modified:
4276 4646
4277```moonscript 4647```yuescript
4278tmp = 1213 4648tmp = 1213
4279i, k = 100, 50 4649i, k = 100, 50
4280 4650
@@ -4287,7 +4657,8 @@ my_func(22)
4287print i, k -- these have been updated 4657print i, k -- these have been updated
4288``` 4658```
4289<YueDisplay> 4659<YueDisplay>
4290<pre> 4660
4661```yue
4291tmp = 1213 4662tmp = 1213
4292i, k = 100, 50 4663i, k = 100, 50
4293 4664
@@ -4298,7 +4669,8 @@ my_func = (add using k, i) ->
4298 4669
4299my_func(22) 4670my_func(22)
4300print i, k -- these have been updated 4671print i, k -- these have been updated
4301</pre> 4672```
4673
4302</YueDisplay> 4674</YueDisplay>
4303 4675
4304## The YueScript Library 4676## The YueScript Library
diff --git a/doc/docs/index.md b/doc/docs/index.md
new file mode 100644
index 0000000..a8c43d2
--- /dev/null
+++ b/doc/docs/index.md
@@ -0,0 +1,25 @@
1---
2layout: home
3hero:
4 name: YueScript
5 text: A language that compiles to Lua
6 image:
7 src: /image/yuescript.svg
8 alt: YueScript
9 actions:
10 - theme: brand
11 text: Quick Start →
12 link: /doc/
13features:
14 - title: Familiar Lua workflows
15 details: Write concise syntax that compiles to readable Lua, with predictable output.
16 - title: Modern language features
17 details: Pipe, pattern matching, slicing, and destructuring without giving up Lua interop.
18 - title: Tooling built in
19 details: Browser-based playground, syntax highlighting, and docs that stay in sync.
20footer: MIT Licensed | Copyright © 2017-2026 Li Jin
21---
22
23## License & Copyright
24
25MIT License. Copyright © 2017-2026 Li Jin. All rights reserved.
diff --git a/doc/docs/try/README.md b/doc/docs/try/index.md
index e931f96..e931f96 100755
--- a/doc/docs/try/README.md
+++ b/doc/docs/try/index.md
diff --git a/doc/docs/zh/README.md b/doc/docs/zh/README.md
deleted file mode 100755
index e76a477..0000000
--- a/doc/docs/zh/README.md
+++ /dev/null
@@ -1,14 +0,0 @@
1---
2layout: home
3hero:
4 name: 月之脚本
5 text: 一门编译到 Lua 的语言
6 image:
7 src: /image/yuescript.svg
8 alt: 月之脚本
9 actions:
10 - theme: brand
11 text: 快速上手 →
12 link: /zh/doc/
13footer: MIT Licensed | Copyright © 2017-2026 Li Jin
14---
diff --git a/doc/docs/zh/doc/README.md b/doc/docs/zh/doc/index.md
index a3ff7cb..dff51a9 100755
--- a/doc/docs/zh/doc/README.md
+++ b/doc/docs/zh/doc/index.md
@@ -5,7 +5,7 @@ title: 参考手册
5 5
6# 月之脚本 6# 月之脚本
7 7
8<img src="/image/yuescript.svg" width="300px" height="300px" alt="logo"/> 8<img src="/image/yuescript.svg" width="250px" height="250px" alt="logo" style="padding-top: 3em;"/>
9 9
10## 介绍 10## 介绍
11 11
@@ -14,7 +14,7 @@ title: 参考手册
14Yue(月)是中文中“月亮”的名称。 14Yue(月)是中文中“月亮”的名称。
15 15
16### 月之脚本概览 16### 月之脚本概览
17```moonscript 17```yuescript
18-- 导入语法 18-- 导入语法
19import p, to_lua from "yue" 19import p, to_lua from "yue"
20 20
@@ -59,7 +59,8 @@ with apple
59export 🌛 = "月之脚本" 59export 🌛 = "月之脚本"
60``` 60```
61<YueDisplay> 61<YueDisplay>
62<pre> 62
63```yue
63-- 导入语法 64-- 导入语法
64import p, to_lua from "yue" 65import p, to_lua from "yue"
65 66
@@ -94,15 +95,16 @@ reduce = (arr, init, action): init ->
94-- 元表操作 95-- 元表操作
95apple = 96apple =
96 size: 15 97 size: 15
97 &lt;index&gt;: 98 <index>:
98 color: 0x00ffff 99 color: 0x00ffff
99 100
100with apple 101with apple
101 p .size, .color, .&lt;index&gt; if .&lt;&gt;? 102 p .size, .color, .<index> if .<>?
102 103
103-- 类似js的导出语法 104-- 类似js的导出语法
104export 🌛 = "月之脚本" 105export 🌛 = "月之脚本"
105</pre> 106```
107
106</YueDisplay> 108</YueDisplay>
107 109
108## 安装 110## 安装
@@ -194,7 +196,7 @@ f!
194### 月之脚本编译工具 196### 月之脚本编译工具
195 197
196使用月之脚本编译工具: 198使用月之脚本编译工具:
197``` 199```sh
198命令行用法: yue 200命令行用法: yue
199 [选项] [<文件/目录>] ... 201 [选项] [<文件/目录>] ...
200 yue -e <代码或文件> [参数...] 202 yue -e <代码或文件> [参数...]
@@ -235,12 +237,12 @@ f!
235 不带选项直接运行可进入交互模式(REPL),在交互模式里输入单独的符号 '$' 237 不带选项直接运行可进入交互模式(REPL),在交互模式里输入单独的符号 '$'
236 可用于开始或结束多行模式。 238 可用于开始或结束多行模式。
237``` 239```
238&emsp;&emsp;使用案例: 240&emsp;&emsp;使用案例:
239&emsp;&emsp;递归编译当前路径下扩展名为 **.yue** 的每个月之脚本文件: **yue .** 241&emsp;&emsp;递归编译当前路径下扩展名为 **.yue** 的每个月之脚本文件: **yue .**
240&emsp;&emsp;编译并将结果保存到目标路径: **yue -t /target/path/ .** 242&emsp;&emsp;编译并将结果保存到目标路径: **yue -t /target/path/ .**
241&emsp;&emsp;编译并保留调试信息: **yue -l .** 243&emsp;&emsp;编译并保留调试信息: **yue -l .**
242&emsp;&emsp;编译并生成压缩代码: **yue -m .** 244&emsp;&emsp;编译并生成压缩代码: **yue -m .**
243&emsp;&emsp;直接执行代码: **yue -e 'print 123'** 245&emsp;&emsp;直接执行代码: **yue -e 'print 123'**
244&emsp;&emsp;执行一个月之脚本文件: **yue -e main.yue** 246&emsp;&emsp;执行一个月之脚本文件: **yue -e main.yue**
245 247
246## 宏 248## 宏
@@ -249,7 +251,7 @@ f!
249 251
250宏函数用于在编译时执行一段代码来生成新的代码,并将生成的代码插入到最终编译结果中。 252宏函数用于在编译时执行一段代码来生成新的代码,并将生成的代码插入到最终编译结果中。
251 253
252```moonscript 254```yuescript
253macro PI2 = -> math.pi * 2 255macro PI2 = -> math.pi * 2
254area = $PI2 * 5 256area = $PI2 * 5
255 257
@@ -278,7 +280,8 @@ if $and f1!, f2!, f3!
278 print "OK" 280 print "OK"
279``` 281```
280<YueDisplay> 282<YueDisplay>
281<pre> 283
284```yue
282macro PI2 = -> math.pi * 2 285macro PI2 = -> math.pi * 2
283area = $PI2 * 5 286area = $PI2 * 5
284 287
@@ -305,13 +308,14 @@ value = $assert item
305macro and = (...) -> "#{ table.concat {...}, ' and ' }" 308macro and = (...) -> "#{ table.concat {...}, ' and ' }"
306if $and f1!, f2!, f3! 309if $and f1!, f2!, f3!
307 print "OK" 310 print "OK"
308</pre> 311```
312
309</YueDisplay> 313</YueDisplay>
310 314
311### 直接插入代码 315### 直接插入代码
312 316
313宏函数可以返回一个包含月之脚本代码的字符串,或是一个包含 Lua 代码字符串的配置表。 317宏函数可以返回一个包含月之脚本代码的字符串,或是一个包含 Lua 代码字符串的配置表。
314```moonscript 318```yuescript
315macro yueFunc = (var) -> "local #{var} = ->" 319macro yueFunc = (var) -> "local #{var} = ->"
316$yueFunc funcA 320$yueFunc funcA
317funcA = -> "无法访问宏生成月之脚本里定义的变量" 321funcA = -> "无法访问宏生成月之脚本里定义的变量"
@@ -337,7 +341,8 @@ end
337]==] 341]==]
338``` 342```
339<YueDisplay> 343<YueDisplay>
340<pre> 344
345```yue
341macro yueFunc = (var) -> "local #{var} = ->" 346macro yueFunc = (var) -> "local #{var} = ->"
342$yueFunc funcA 347$yueFunc funcA
343funcA = -> "无法访问宏生成月之脚本里定义的变量" 348funcA = -> "无法访问宏生成月之脚本里定义的变量"
@@ -361,13 +366,14 @@ if cond then
361 print("输出") 366 print("输出")
362end 367end
363]==] 368]==]
364</pre> 369```
370
365</YueDisplay> 371</YueDisplay>
366 372
367### 导出宏 373### 导出宏
368 374
369宏函数可以从一个模块中导出,并在另一个模块中导入。你必须将导出的宏函数放在一个单独的文件中使用,而且只有宏定义、宏导入和宏展开可以放入这个宏导出模块中。 375宏函数可以从一个模块中导出,并在另一个模块中导入。你必须将导出的宏函数放在一个单独的文件中使用,而且只有宏定义、宏导入和宏展开可以放入这个宏导出模块中。
370```moonscript 376```yuescript
371-- 文件: utils.yue 377-- 文件: utils.yue
372export macro map = (items, action) -> "[#{action} for _ in *#{items}]" 378export macro map = (items, action) -> "[#{action} for _ in *#{items}]"
373export macro filter = (items, action) -> "[_ for _ in *#{items} when #{action}]" 379export macro filter = (items, action) -> "[_ for _ in *#{items} when #{action}]"
@@ -382,7 +388,8 @@ import "utils" as {
382[1, 2, 3] |> $map(_ * 2) |> $filter(_ > 4) |> $each print _ 388[1, 2, 3] |> $map(_ * 2) |> $filter(_ > 4) |> $each print _
383``` 389```
384<YueDisplay> 390<YueDisplay>
385<pre> 391
392```yue
386-- 文件: utils.yue 393-- 文件: utils.yue
387export macro map = (items, action) -> "[#{action} for _ in *#{items}]" 394export macro map = (items, action) -> "[#{action} for _ in *#{items}]"
388export macro filter = (items, action) -> "[_ for _ in *#{items} when #{action}]" 395export macro filter = (items, action) -> "[_ for _ in *#{items} when #{action}]"
@@ -397,28 +404,31 @@ import "utils" as {
397} 404}
398[1, 2, 3] |> $map(_ * 2) |> $filter(_ > 4) |> $each print _ 405[1, 2, 3] |> $map(_ * 2) |> $filter(_ > 4) |> $each print _
399]] 406]]
400</pre> 407```
408
401</YueDisplay> 409</YueDisplay>
402 410
403### 内置宏 411### 内置宏
404 412
405月之脚本中有一些内置可以直接使用的宏,但你可以通过声明相同名称的宏来覆盖它们。 413月之脚本中有一些内置可以直接使用的宏,但你可以通过声明相同名称的宏来覆盖它们。
406```moonscript 414```yuescript
407print $FILE -- 获取当前模块名称的字符串 415print $FILE -- 获取当前模块名称的字符串
408print $LINE -- 获取当前代码行数:2 416print $LINE -- 获取当前代码行数:2
409``` 417```
410<YueDisplay> 418<YueDisplay>
411<pre> 419
420```yue
412print $FILE -- 获取当前模块名称的字符串 421print $FILE -- 获取当前模块名称的字符串
413print $LINE -- 获取当前代码行数:2 422print $LINE -- 获取当前代码行数:2
414</pre> 423```
424
415</YueDisplay> 425</YueDisplay>
416 426
417### 用宏生成宏 427### 用宏生成宏
418 428
419在月之脚本中,宏函数允许你在编译时生成代码。通过嵌套的宏函数,你可以创建更复杂的生成模式。这个特性允许你定义一个宏函数,用它来生成另一个宏函数,从而实现更加动态的代码生成。 429在月之脚本中,宏函数允许你在编译时生成代码。通过嵌套的宏函数,你可以创建更复杂的生成模式。这个特性允许你定义一个宏函数,用它来生成另一个宏函数,从而实现更加动态的代码生成。
420 430
421```moonscript 431```yuescript
422macro Enum = (...) -> 432macro Enum = (...) ->
423 items = {...} 433 items = {...}
424 itemSet = {item, true for item in *items} 434 itemSet = {item, true for item in *items}
@@ -436,7 +446,8 @@ print "有效的枚举类型:", $BodyType Static
436-- print "编译报错的枚举类型:", $BodyType Unknown 446-- print "编译报错的枚举类型:", $BodyType Unknown
437``` 447```
438<YueDisplay> 448<YueDisplay>
439<pre> 449
450```yue
440macro Enum = (...) -> 451macro Enum = (...) ->
441 items = {...} 452 items = {...}
442 itemSet = {item, true for item in *items} 453 itemSet = {item, true for item in *items}
@@ -452,14 +463,15 @@ macro BodyType = $Enum(
452 463
453print "有效的枚举类型:", $BodyType Static 464print "有效的枚举类型:", $BodyType Static
454-- print "编译报错的枚举类型:", $BodyType Unknown 465-- print "编译报错的枚举类型:", $BodyType Unknown
455</pre> 466```
467
456</YueDisplay> 468</YueDisplay>
457 469
458### 宏参数检查 470### 宏参数检查
459 471
460可以直接在参数列表中声明期望的 AST 节点类型,并在编译时检查传入的宏参数是否符合预期。 472可以直接在参数列表中声明期望的 AST 节点类型,并在编译时检查传入的宏参数是否符合预期。
461 473
462```moonscript 474```yuescript
463macro printNumAndStr = (num `Num, str `String) -> | 475macro printNumAndStr = (num `Num, str `String) -> |
464 print( 476 print(
465 #{num} 477 #{num}
@@ -469,7 +481,8 @@ macro printNumAndStr = (num `Num, str `String) -> |
469$printNumAndStr 123, "hello" 481$printNumAndStr 123, "hello"
470``` 482```
471<YueDisplay> 483<YueDisplay>
472<pre> 484
485```yue
473macro printNumAndStr = (num `Num, str `String) -> | 486macro printNumAndStr = (num `Num, str `String) -> |
474 print( 487 print(
475 #{num} 488 #{num}
@@ -477,12 +490,13 @@ macro printNumAndStr = (num `Num, str `String) -> |
477 ) 490 )
478 491
479$printNumAndStr 123, "hello" 492$printNumAndStr 123, "hello"
480</pre> 493```
494
481</YueDisplay> 495</YueDisplay>
482 496
483如果需要做更加灵活的参数检查操作,可以使用内置的 `$is_ast` 宏函数在合适的位置进行手动检查。 497如果需要做更加灵活的参数检查操作,可以使用内置的 `$is_ast` 宏函数在合适的位置进行手动检查。
484 498
485```moonscript 499```yuescript
486macro printNumAndStr = (num, str) -> 500macro printNumAndStr = (num, str) ->
487 error "expected Num as first argument" unless $is_ast Num, num 501 error "expected Num as first argument" unless $is_ast Num, num
488 error "expected String as second argument" unless $is_ast String, str 502 error "expected String as second argument" unless $is_ast String, str
@@ -491,14 +505,16 @@ macro printNumAndStr = (num, str) ->
491$printNumAndStr 123, "hello" 505$printNumAndStr 123, "hello"
492``` 506```
493<YueDisplay> 507<YueDisplay>
494<pre> 508
509```yue
495macro printNumAndStr = (num, str) -> 510macro printNumAndStr = (num, str) ->
496 error "expected Num as first argument" unless $is_ast Num, num 511 error "expected Num as first argument" unless $is_ast Num, num
497 error "expected String as second argument" unless $is_ast String, str 512 error "expected String as second argument" unless $is_ast String, str
498 "print(#{num}, #{str})" 513 "print(#{num}, #{str})"
499 514
500$printNumAndStr 123, "hello" 515$printNumAndStr 123, "hello"
501</pre> 516```
517
502</YueDisplay> 518</YueDisplay>
503 519
504更多关于可用 AST 节点的详细信息,请参考 [yue_parser.cpp](https://github.com/IppClub/YueScript/blob/main/src/yuescript/yue_parser.cpp) 中大写的规则定义。 520更多关于可用 AST 节点的详细信息,请参考 [yue_parser.cpp](https://github.com/IppClub/YueScript/blob/main/src/yuescript/yue_parser.cpp) 中大写的规则定义。
@@ -507,22 +523,24 @@ $printNumAndStr 123, "hello"
507 523
508Lua 的所有二元和一元操作符在月之脚本中都是可用的。此外,**!=** 符号是 **~=** 的别名,而 **\\** 或 **::** 均可用于编写链式函数调用,如写作 `tb\func!` 或 `tb::func!`。此外月之脚本还提供了一些其他特殊的操作符,以编写更具表达力的代码。 524Lua 的所有二元和一元操作符在月之脚本中都是可用的。此外,**!=** 符号是 **~=** 的别名,而 **\\** 或 **::** 均可用于编写链式函数调用,如写作 `tb\func!` 或 `tb::func!`。此外月之脚本还提供了一些其他特殊的操作符,以编写更具表达力的代码。
509 525
510```moonscript 526```yuescript
511tb\func! if tb ~= nil 527tb\func! if tb ~= nil
512tb::func! if tb != nil 528tb::func! if tb != nil
513``` 529```
514<YueDisplay> 530<YueDisplay>
515<pre> 531
532```yue
516tb\func! if tb ~= nil 533tb\func! if tb ~= nil
517tb::func! if tb != nil 534tb::func! if tb != nil
518</pre> 535```
536
519</YueDisplay> 537</YueDisplay>
520 538
521### 链式比较 539### 链式比较
522 540
523你可以在月之脚本中进行比较表达式的链式书写: 541你可以在月之脚本中进行比较表达式的链式书写:
524 542
525```moonscript 543```yuescript
526print 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5 544print 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5
527-- 输出:true 545-- 输出:true
528 546
@@ -531,19 +549,21 @@ print 1 <= a <= 10
531-- 输出:true 549-- 输出:true
532``` 550```
533<YueDisplay> 551<YueDisplay>
534<pre> 552
553```yue
535print 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5 554print 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5
536-- 输出:true 555-- 输出:true
537 556
538a = 5 557a = 5
539print 1 <= a <= 10 558print 1 <= a <= 10
540-- 输出:true 559-- 输出:true
541</pre> 560```
561
542</YueDisplay> 562</YueDisplay>
543 563
544可以注意一下链式比较表达式的求值行为: 564可以注意一下链式比较表达式的求值行为:
545 565
546```moonscript 566```yuescript
547v = (x) -> 567v = (x) ->
548 print x 568 print x
549 x 569 x
@@ -566,7 +586,8 @@ print v(1) > v(2) <= v(3)
566]] 586]]
567``` 587```
568<YueDisplay> 588<YueDisplay>
569<pre> 589
590```yue
570v = (x) -> 591v = (x) ->
571 print x 592 print x
572 x 593 x
@@ -587,7 +608,8 @@ print v(1) > v(2) <= v(3)
587 1 608 1
588 false 609 false
589]] 610]]
590</pre> 611```
612
591</YueDisplay> 613</YueDisplay>
592 614
593在上面的例子里,中间的表达式 `v(2)` 仅被计算一次,如果把表达式写成 `v(1) < v(2) and v(2) <= v(3)` 的方式,中间的 `v(2)` 才会被计算两次。在链式比较中,求值的顺序往往是未定义的。所以强烈建议不要在链式比较中使用具有副作用(比如做打印操作)的表达式。如果需要使用有副作用的函数,应明确使用短路 `and` 运算符来做连接。 615在上面的例子里,中间的表达式 `v(2)` 仅被计算一次,如果把表达式写成 `v(1) < v(2) and v(2) <= v(3)` 的方式,中间的 `v(2)` 才会被计算两次。在链式比较中,求值的顺序往往是未定义的。所以强烈建议不要在链式比较中使用具有副作用(比如做打印操作)的表达式。如果需要使用有副作用的函数,应明确使用短路 `and` 运算符来做连接。
@@ -596,39 +618,43 @@ print v(1) > v(2) <= v(3)
596 618
597**[] =** 操作符用于向 Lua 表的最后插入值。 619**[] =** 操作符用于向 Lua 表的最后插入值。
598 620
599```moonscript 621```yuescript
600tab = [] 622tab = []
601tab[] = "Value" 623tab[] = "Value"
602``` 624```
603<YueDisplay> 625<YueDisplay>
604<pre> 626
627```yue
605tab = [] 628tab = []
606tab[] = "Value" 629tab[] = "Value"
607</pre> 630```
631
608</YueDisplay> 632</YueDisplay>
609 633
610你还可以使用展开操作符 `...` 来将一个列表中的所有元素追加到另一个列表中: 634你还可以使用展开操作符 `...` 来将一个列表中的所有元素追加到另一个列表中:
611 635
612```moonscript 636```yuescript
613tbA = [1, 2, 3] 637tbA = [1, 2, 3]
614tbB = [4, 5, 6] 638tbB = [4, 5, 6]
615tbA[] = ...tbB 639tbA[] = ...tbB
616-- tbA 现在为 [1, 2, 3, 4, 5, 6] 640-- tbA 现在为 [1, 2, 3, 4, 5, 6]
617``` 641```
618<YueDisplay> 642<YueDisplay>
619<pre> 643
644```yue
620tbA = [1, 2, 3] 645tbA = [1, 2, 3]
621tbB = [4, 5, 6] 646tbB = [4, 5, 6]
622tbA[] = ...tbB 647tbA[] = ...tbB
623-- tbA 现在为 [1, 2, 3, 4, 5, 6] 648-- tbA 现在为 [1, 2, 3, 4, 5, 6]
624</pre> 649```
650
625</YueDisplay> 651</YueDisplay>
626 652
627### 表扩展 653### 表扩展
628 654
629你可以使用前置 `...` 操作符在 Lua 表中插入数组表或哈希表。 655你可以使用前置 `...` 操作符在 Lua 表中插入数组表或哈希表。
630 656
631```moonscript 657```yuescript
632parts = 658parts =
633 * "shoulders" 659 * "shoulders"
634 * "knees" 660 * "knees"
@@ -645,7 +671,8 @@ b = {4, 5, y: 1}
645merge = {...a, ...b} 671merge = {...a, ...b}
646``` 672```
647<YueDisplay> 673<YueDisplay>
648<pre> 674
675```yue
649parts = 676parts =
650 * "shoulders" 677 * "shoulders"
651 * "knees" 678 * "knees"
@@ -660,24 +687,27 @@ copy = {...other}
660a = {1, 2, 3, x: 1} 687a = {1, 2, 3, x: 1}
661b = {4, 5, y: 1} 688b = {4, 5, y: 1}
662merge = {...a, ...b} 689merge = {...a, ...b}
663</pre> 690```
691
664</YueDisplay> 692</YueDisplay>
665 693
666### 表反向索引 694### 表反向索引
667 695
668你可以使用 **#** 操作符来反向索引表中的元素。 696你可以使用 **#** 操作符来反向索引表中的元素。
669 697
670```moonscript 698```yuescript
671last = data.items[#] 699last = data.items[#]
672second_last = data.items[#-1] 700second_last = data.items[#-1]
673data.items[#] = 1 701data.items[#] = 1
674``` 702```
675<YueDisplay> 703<YueDisplay>
676<pre> 704
705```yue
677last = data.items[#] 706last = data.items[#]
678second_last = data.items[#-1] 707second_last = data.items[#-1]
679data.items[#] = 1 708data.items[#] = 1
680</pre> 709```
710
681</YueDisplay> 711</YueDisplay>
682 712
683### 元表 713### 元表
@@ -687,7 +717,7 @@ data.items[#] = 1
687* **元表创建** 717* **元表创建**
688使用空括号 **<>** 或被 **<>** 包围的元方法键创建普通的 Lua 表。 718使用空括号 **<>** 或被 **<>** 包围的元方法键创建普通的 Lua 表。
689 719
690```moonscript 720```yuescript
691mt = {} 721mt = {}
692add = (right) => <>: mt, value: @value + right.value 722add = (right) => <>: mt, value: @value + right.value
693mt.__add = add 723mt.__add = add
@@ -703,27 +733,29 @@ print d.value
703close _ = <close>: -> print "超出范围" 733close _ = <close>: -> print "超出范围"
704``` 734```
705<YueDisplay> 735<YueDisplay>
706<pre> 736
737```yue
707mt = {} 738mt = {}
708add = (right) => &lt;&gt;: mt, value: @value + right.value 739add = (right) => <>: mt, value: @value + right.value
709mt.__add = add 740mt.__add = add
710 741
711a = &lt;&gt;: mt, value: 1 742a = <>: mt, value: 1
712-- 使用与临时变量名相同的字段名,将临时变量赋值给元表 743-- 使用与临时变量名相同的字段名,将临时变量赋值给元表
713b = :&lt;add&gt;, value: 2 744b = :<add>, value: 2
714c = &lt;add&gt;: mt.__add, value: 3 745c = <add>: mt.__add, value: 3
715 746
716d = a + b + c 747d = a + b + c
717print d.value 748print d.value
718 749
719close _ = &lt;close&gt;: -> print "超出范围" 750close _ = <close>: -> print "超出范围"
720</pre> 751```
752
721</YueDisplay> 753</YueDisplay>
722 754
723* **元表访问** 755* **元表访问**
724使用 **<>** 或被 **<>** 包围的元方法名或在 **<>** 中编写某些表达式来访问元表。 756使用 **<>** 或被 **<>** 包围的元方法名或在 **<>** 中编写某些表达式来访问元表。
725 757
726```moonscript 758```yuescript
727-- 使用包含字段 "value" 的元表创建 759-- 使用包含字段 "value" 的元表创建
728tb = <"value">: 123 760tb = <"value">: 123
729tb.<index> = tb.<> 761tb.<index> = tb.<>
@@ -734,35 +766,39 @@ print tb.item
734``` 766```
735<YueDisplay> 767<YueDisplay>
736 768
737<pre> 769
770```yue
738-- 使用包含字段 "value" 的元表创建 771-- 使用包含字段 "value" 的元表创建
739tb = &lt;"value"&gt;: 123 772tb = <"value">: 123
740tb.&lt;index&gt; = tb.&lt;&gt; 773tb.<index> = tb.<>
741print tb.value 774print tb.value
742tb.&lt;&gt; = __index: {item: "hello"} 775tb.<> = __index: {item: "hello"}
743print tb.item 776print tb.item
744</pre> 777```
778
745</YueDisplay> 779</YueDisplay>
746 780
747* **元表解构** 781* **元表解构**
748使用被 **<>** 包围的元方法键解构元表。 782使用被 **<>** 包围的元方法键解构元表。
749 783
750```moonscript 784```yuescript
751{item, :new, :<close>, <index>: getter} = tb 785{item, :new, :<close>, <index>: getter} = tb
752print item, new, close, getter 786print item, new, close, getter
753``` 787```
754<YueDisplay> 788<YueDisplay>
755<pre> 789
756{item, :new, :&lt;close&gt;, &lt;index&gt;: getter} = tb 790```yue
791{item, :new, :<close>, <index>: getter} = tb
757print item, new, close, getter 792print item, new, close, getter
758</pre> 793```
794
759</YueDisplay> 795</YueDisplay>
760 796
761### 存在性 797### 存在性
762 798
763**?** 运算符可以在多种上下文中用来检查存在性。 799**?** 运算符可以在多种上下文中用来检查存在性。
764 800
765```moonscript 801```yuescript
766func?! 802func?!
767print abc?["你好 世界"]?.xyz 803print abc?["你好 世界"]?.xyz
768 804
@@ -777,7 +813,8 @@ with? io.open "test.txt", "w"
777 \close! 813 \close!
778``` 814```
779<YueDisplay> 815<YueDisplay>
780<pre> 816
817```yue
781func?! 818func?!
782print abc?["你好 世界"]?.xyz 819print abc?["你好 世界"]?.xyz
783 820
@@ -790,14 +827,15 @@ if print and x?
790with? io.open "test.txt", "w" 827with? io.open "test.txt", "w"
791 \write "你好" 828 \write "你好"
792 \close! 829 \close!
793</pre> 830```
831
794</YueDisplay> 832</YueDisplay>
795 833
796### 管道 834### 管道
797 835
798与其使用一系列嵌套的函数调用,你还可以考虑使用运算符 **|>** 来传递值。 836与其使用一系列嵌套的函数调用,你还可以考虑使用运算符 **|>** 来传递值。
799 837
800```moonscript 838```yuescript
801"你好" |> print 839"你好" |> print
8021 |> print 2 -- 将管道项作为第一个参数插入 8401 |> print 2 -- 将管道项作为第一个参数插入
8032 |> print 1, _, 3 -- 带有占位符的管道 8412 |> print 1, _, 3 -- 带有占位符的管道
@@ -811,7 +849,8 @@ readFile "example.txt"
811 |> print 849 |> print
812``` 850```
813<YueDisplay> 851<YueDisplay>
814<pre> 852
853```yue
815"你好" |> print 854"你好" |> print
8161 |> print 2 -- 将管道项作为第一个参数插入 8551 |> print 2 -- 将管道项作为第一个参数插入
8172 |> print 1, _, 3 -- 带有占位符的管道 8562 |> print 1, _, 3 -- 带有占位符的管道
@@ -822,13 +861,14 @@ readFile "example.txt"
822 |> emit 861 |> emit
823 |> render 862 |> render
824 |> print 863 |> print
825</pre> 864```
865
826</YueDisplay> 866</YueDisplay>
827 867
828### 空值合并 868### 空值合并
829 869
830如果其左操作数不是 **nil**,则nil合并运算符 **??** 返回其左操作数的值;否则,它将计算右操作数并返回其结果。如果左操作数计算结果为非 nil 的值,**??** 运算符将不再计算其右操作数。 870如果其左操作数不是 **nil**,则nil合并运算符 **??** 返回其左操作数的值;否则,它将计算右操作数并返回其结果。如果左操作数计算结果为非 nil 的值,**??** 运算符将不再计算其右操作数。
831```moonscript 871```yuescript
832local a, b, c, d 872local a, b, c, d
833a = b ?? c ?? d 873a = b ?? c ?? d
834func a ?? {} 874func a ?? {}
@@ -836,19 +876,21 @@ func a ?? {}
836a ??= false 876a ??= false
837``` 877```
838<YueDisplay> 878<YueDisplay>
839<pre> 879
880```yue
840local a, b, c, d 881local a, b, c, d
841a = b ?? c ?? d 882a = b ?? c ?? d
842func a ?? {} 883func a ?? {}
843a ??= false 884a ??= false
844</pre> 885```
886
845</YueDisplay> 887</YueDisplay>
846 888
847### 隐式对象 889### 隐式对象
848 890
849你可以在表格块内使用符号 **\*** 或是 **-** 开始编写一系列隐式结构。如果你正在创建隐式对象,对象的字段必须具有相同的缩进。 891你可以在表格块内使用符号 **\*** 或是 **-** 开始编写一系列隐式结构。如果你正在创建隐式对象,对象的字段必须具有相同的缩进。
850 892
851```moonscript 893```yuescript
852-- 赋值时使用隐式对象 894-- 赋值时使用隐式对象
853list = 895list =
854 * 1 896 * 1
@@ -890,7 +932,8 @@ tb =
890 tb: { } 932 tb: { }
891``` 933```
892<YueDisplay> 934<YueDisplay>
893<pre> 935
936```yue
894-- 赋值时使用隐式对象 937-- 赋值时使用隐式对象
895list = 938list =
896 * 1 939 * 1
@@ -930,7 +973,8 @@ tb =
930 value: 2 973 value: 2
931 func: => @value + 2 974 func: => @value + 2
932 tb: { } 975 tb: { }
933</pre> 976```
977
934</YueDisplay> 978</YueDisplay>
935 979
936## 模块 980## 模块
@@ -939,7 +983,7 @@ tb =
939 983
940导入语句是一个语法糖,用于需要引入一个模块或者从已导入的模块中提取子项目。从模块导入的变量默认为不可修改的常量。 984导入语句是一个语法糖,用于需要引入一个模块或者从已导入的模块中提取子项目。从模块导入的变量默认为不可修改的常量。
941 985
942```moonscript 986```yuescript
943-- 用作表解构 987-- 用作表解构
944do 988do
945 import insert, concat from table 989 import insert, concat from table
@@ -964,7 +1008,8 @@ do
964 import "export" as {one, two, Something:{umm:{ch}}} 1008 import "export" as {one, two, Something:{umm:{ch}}}
965``` 1009```
966<YueDisplay> 1010<YueDisplay>
967<pre> 1011
1012```yue
968-- 用作表解构 1013-- 用作表解构
969do 1014do
970 import insert, concat from table 1015 import insert, concat from table
@@ -987,26 +1032,29 @@ do
987 import "player" as PlayerModule 1032 import "player" as PlayerModule
988 import "lpeg" as :C, :Ct, :Cmt 1033 import "lpeg" as :C, :Ct, :Cmt
989 import "export" as {one, two, Something:{umm:{ch}}} 1034 import "export" as {one, two, Something:{umm:{ch}}}
990</pre> 1035```
1036
991</YueDisplay> 1037</YueDisplay>
992 1038
993### 导入全局变量 1039### 导入全局变量
994 1040
995你可以使用 `import` 将指定的全局变量导入到本地变量中。当导入一系列对全局变量的链式访问时,最后一个访问的字段将被赋值给本地变量。 1041你可以使用 `import` 将指定的全局变量导入到本地变量中。当导入一系列对全局变量的链式访问时,最后一个访问的字段将被赋值给本地变量。
996 1042
997```moonscript 1043```yuescript
998do 1044do
999 import tostring 1045 import tostring
1000 import table.concat 1046 import table.concat
1001 print concat ["a", tostring 1] 1047 print concat ["a", tostring 1]
1002``` 1048```
1003<YueDisplay> 1049<YueDisplay>
1004<pre> 1050
1051```yue
1005do 1052do
1006 import tostring 1053 import tostring
1007 import table.concat 1054 import table.concat
1008 print concat ["a", tostring 1] 1055 print concat ["a", tostring 1]
1009</pre> 1056```
1057
1010</YueDisplay> 1058</YueDisplay>
1011 1059
1012#### 自动导入 1060#### 自动导入
@@ -1015,7 +1063,7 @@ do
1015 1063
1016但是在同一作用域中被显式声明为全局的变量不会被自动导入,因此可以继续进行赋值操作。 1064但是在同一作用域中被显式声明为全局的变量不会被自动导入,因此可以继续进行赋值操作。
1017 1065
1018```moonscript 1066```yuescript
1019do 1067do
1020 import global 1068 import global
1021 print "hello" 1069 print "hello"
@@ -1030,7 +1078,8 @@ do
1030 FLAG = 123 1078 FLAG = 123
1031``` 1079```
1032<YueDisplay> 1080<YueDisplay>
1033<pre> 1081
1082```yue
1034do 1083do
1035 import global 1084 import global
1036 print "hello" 1085 print "hello"
@@ -1043,7 +1092,8 @@ do
1043 global FLAG 1092 global FLAG
1044 print FLAG 1093 print FLAG
1045 FLAG = 123 1094 FLAG = 123
1046</pre> 1095```
1096
1047</YueDisplay> 1097</YueDisplay>
1048 1098
1049### 导出 1099### 导出
@@ -1053,7 +1103,7 @@ do
1053* **命名导出** 1103* **命名导出**
1054带命名的导出将定义一个局部变量,并在导出的表中添加一个同名的字段。 1104带命名的导出将定义一个局部变量,并在导出的表中添加一个同名的字段。
1055 1105
1056```moonscript 1106```yuescript
1057export a, b, c = 1, 2, 3 1107export a, b, c = 1, 2, 3
1058export cool = "cat" 1108export cool = "cat"
1059 1109
@@ -1069,7 +1119,8 @@ export class Something
1069 umm: "cool" 1119 umm: "cool"
1070``` 1120```
1071<YueDisplay> 1121<YueDisplay>
1072<pre> 1122
1123```yue
1073export a, b, c = 1, 2, 3 1124export a, b, c = 1, 2, 3
1074export cool = "cat" 1125export cool = "cat"
1075 1126
@@ -1083,41 +1134,46 @@ export y = ->
1083 1134
1084export class Something 1135export class Something
1085 umm: "cool" 1136 umm: "cool"
1086</pre> 1137```
1138
1087</YueDisplay> 1139</YueDisplay>
1088 1140
1089使用解构进行命名导出。 1141使用解构进行命名导出。
1090 1142
1091```moonscript 1143```yuescript
1092export :loadstring, to_lua: tolua = yue 1144export :loadstring, to_lua: tolua = yue
1093export {itemA: {:fieldA = '默认值'}} = tb 1145export {itemA: {:fieldA = '默认值'}} = tb
1094``` 1146```
1095<YueDisplay> 1147<YueDisplay>
1096<pre> 1148
1149```yue
1097export :loadstring, to_lua: tolua = yue 1150export :loadstring, to_lua: tolua = yue
1098export {itemA: {:fieldA = '默认值'}} = tb 1151export {itemA: {:fieldA = '默认值'}} = tb
1099</pre> 1152```
1153
1100</YueDisplay> 1154</YueDisplay>
1101 1155
1102从模块导出命名项目时,可以不用创建局部变量。 1156从模块导出命名项目时,可以不用创建局部变量。
1103 1157
1104```moonscript 1158```yuescript
1105export.itemA = tb 1159export.itemA = tb
1106export.<index> = items 1160export.<index> = items
1107export["a-b-c"] = 123 1161export["a-b-c"] = 123
1108``` 1162```
1109<YueDisplay> 1163<YueDisplay>
1110<pre> 1164
1165```yue
1111export.itemA = tb 1166export.itemA = tb
1112export.&lt;index&gt; = items 1167export.<index> = items
1113export["a-b-c"] = 123 1168export["a-b-c"] = 123
1114</pre> 1169```
1170
1115</YueDisplay> 1171</YueDisplay>
1116 1172
1117* **未命名导出** 1173* **未命名导出**
1118未命名导出会将要导出的目标项目添加到导出表的数组部分。 1174未命名导出会将要导出的目标项目添加到导出表的数组部分。
1119 1175
1120```moonscript 1176```yuescript
1121d, e, f = 3, 2, 1 1177d, e, f = 3, 2, 1
1122export d, e, f 1178export d, e, f
1123 1179
@@ -1130,7 +1186,8 @@ export with tmp
1130 j = 2000 1186 j = 2000
1131``` 1187```
1132<YueDisplay> 1188<YueDisplay>
1133<pre> 1189
1190```yue
1134d, e, f = 3, 2, 1 1191d, e, f = 3, 2, 1
1135export d, e, f 1192export d, e, f
1136 1193
@@ -1141,46 +1198,51 @@ else
1141 1198
1142export with tmp 1199export with tmp
1143 j = 2000 1200 j = 2000
1144</pre> 1201```
1202
1145</YueDisplay> 1203</YueDisplay>
1146 1204
1147* **默认导出** 1205* **默认导出**
1148在导出语句中使用 **default** 关键字,来替换导出的表为一个目标的对象。 1206在导出语句中使用 **default** 关键字,来替换导出的表为一个目标的对象。
1149 1207
1150```moonscript 1208```yuescript
1151export default -> 1209export default ->
1152 print "你好" 1210 print "你好"
1153 123 1211 123
1154``` 1212```
1155<YueDisplay> 1213<YueDisplay>
1156<pre> 1214
1215```yue
1157export default -> 1216export default ->
1158 print "你好" 1217 print "你好"
1159 123 1218 123
1160</pre> 1219```
1220
1161</YueDisplay> 1221</YueDisplay>
1162 1222
1163## 赋值 1223## 赋值
1164 1224
1165月之脚本中定义的变量是动态类型的,并默认为局部变量。但你可以通过 **local** 和 **global** 声明来改变声明变量的作用范围。 1225月之脚本中定义的变量是动态类型的,并默认为局部变量。但你可以通过 **local** 和 **global** 声明来改变声明变量的作用范围。
1166 1226
1167```moonscript 1227```yuescript
1168hello = "world" 1228hello = "world"
1169a, b, c = 1, 2, 3 1229a, b, c = 1, 2, 3
1170hello = 123 -- 访问现有的变量 1230hello = 123 -- 访问现有的变量
1171``` 1231```
1172<YueDisplay> 1232<YueDisplay>
1173<pre> 1233
1234```yue
1174hello = "world" 1235hello = "world"
1175a, b, c = 1, 2, 3 1236a, b, c = 1, 2, 3
1176hello = 123 -- 访问现有的变量 1237hello = 123 -- 访问现有的变量
1177</pre> 1238```
1239
1178</YueDisplay> 1240</YueDisplay>
1179 1241
1180### 执行更新 1242### 执行更新
1181 1243
1182你可以使用各式二进制运算符执行更新赋值。 1244你可以使用各式二进制运算符执行更新赋值。
1183```moonscript 1245```yuescript
1184x = 1 1246x = 1
1185x += 1 1247x += 1
1186x -= 1 1248x -= 1
@@ -1191,7 +1253,8 @@ s ..= "world" -- 如果执行更新的局部变量不存在,将新建一个局
1191arg or= "默认值" 1253arg or= "默认值"
1192``` 1254```
1193<YueDisplay> 1255<YueDisplay>
1194<pre> 1256
1257```yue
1195x = 1 1258x = 1
1196x += 1 1259x += 1
1197x -= 1 1260x -= 1
@@ -1200,25 +1263,28 @@ x /= 10
1200x %= 10 1263x %= 10
1201s ..= "world" -- 如果执行更新的局部变量不存在,将新建一个局部变量 1264s ..= "world" -- 如果执行更新的局部变量不存在,将新建一个局部变量
1202arg or= "默认值" 1265arg or= "默认值"
1203</pre> 1266```
1267
1204</YueDisplay> 1268</YueDisplay>
1205 1269
1206### 链式赋值 1270### 链式赋值
1207 1271
1208你可以进行链式赋值,将多个项目赋予相同的值。 1272你可以进行链式赋值,将多个项目赋予相同的值。
1209```moonscript 1273```yuescript
1210a = b = c = d = e = 0 1274a = b = c = d = e = 0
1211x = y = z = f! 1275x = y = z = f!
1212``` 1276```
1213<YueDisplay> 1277<YueDisplay>
1214<pre> 1278
1279```yue
1215a = b = c = d = e = 0 1280a = b = c = d = e = 0
1216x = y = z = f! 1281x = y = z = f!
1217</pre> 1282```
1283
1218</YueDisplay> 1284</YueDisplay>
1219 1285
1220### 显式声明局部变量 1286### 显式声明局部变量
1221```moonscript 1287```yuescript
1222do 1288do
1223 local a = 1 1289 local a = 1
1224 local * 1290 local *
@@ -1235,7 +1301,8 @@ do
1235 B = 2 1301 B = 2
1236``` 1302```
1237<YueDisplay> 1303<YueDisplay>
1238<pre> 1304
1305```yue
1239do 1306do
1240 local a = 1 1307 local a = 1
1241 local * 1308 local *
@@ -1250,11 +1317,12 @@ do
1250 print "只预先声明后续大写的变量为局部变量" 1317 print "只预先声明后续大写的变量为局部变量"
1251 a = 1 1318 a = 1
1252 B = 2 1319 B = 2
1253</pre> 1320```
1321
1254</YueDisplay> 1322</YueDisplay>
1255 1323
1256### 显式声明全局变量 1324### 显式声明全局变量
1257```moonscript 1325```yuescript
1258do 1326do
1259 global a = 1 1327 global a = 1
1260 global * 1328 global *
@@ -1271,7 +1339,8 @@ do
1271 local Temp = "一个局部值" 1339 local Temp = "一个局部值"
1272``` 1340```
1273<YueDisplay> 1341<YueDisplay>
1274<pre> 1342
1343```yue
1275do 1344do
1276 global a = 1 1345 global a = 1
1277 global * 1346 global *
@@ -1286,7 +1355,8 @@ do
1286 a = 1 1355 a = 1
1287 B = 2 1356 B = 2
1288 local Temp = "一个局部值" 1357 local Temp = "一个局部值"
1289</pre> 1358```
1359
1290</YueDisplay> 1360</YueDisplay>
1291 1361
1292## 解构赋值 1362## 解构赋值
@@ -1297,7 +1367,7 @@ do
1297 1367
1298最好是通过示例来解释。以下是如何从表格中解包前两个值的方法: 1368最好是通过示例来解释。以下是如何从表格中解包前两个值的方法:
1299 1369
1300```moonscript 1370```yuescript
1301thing = [1, 2] 1371thing = [1, 2]
1302 1372
1303[a, b] = thing 1373[a, b] = thing
@@ -1305,17 +1375,19 @@ print a, b
1305``` 1375```
1306<YueDisplay> 1376<YueDisplay>
1307 1377
1308<pre> 1378
1379```yue
1309thing = [1, 2] 1380thing = [1, 2]
1310 1381
1311[a, b] = thing 1382[a, b] = thing
1312print a, b 1383print a, b
1313</pre> 1384```
1385
1314</YueDisplay> 1386</YueDisplay>
1315 1387
1316在解构表格字面量中,键代表从右侧读取的键,值代表读取的值将被赋予的名称。 1388在解构表格字面量中,键代表从右侧读取的键,值代表读取的值将被赋予的名称。
1317 1389
1318```moonscript 1390```yuescript
1319obj = { 1391obj = {
1320 hello: "world" 1392 hello: "world"
1321 day: "tuesday" 1393 day: "tuesday"
@@ -1328,7 +1400,8 @@ print hello, the_day
1328:day = obj -- 可以不带大括号进行简单的解构 1400:day = obj -- 可以不带大括号进行简单的解构
1329``` 1401```
1330<YueDisplay> 1402<YueDisplay>
1331<pre> 1403
1404```yue
1332obj = { 1405obj = {
1333 hello: "world" 1406 hello: "world"
1334 day: "tuesday" 1407 day: "tuesday"
@@ -1339,12 +1412,13 @@ obj = {
1339print hello, the_day 1412print hello, the_day
1340 1413
1341:day = obj -- 可以不带大括号进行简单的解构 1414:day = obj -- 可以不带大括号进行简单的解构
1342</pre> 1415```
1416
1343</YueDisplay> 1417</YueDisplay>
1344 1418
1345这也适用于嵌套的数据结构: 1419这也适用于嵌套的数据结构:
1346 1420
1347```moonscript 1421```yuescript
1348obj2 = { 1422obj2 = {
1349 numbers: [1,2,3,4] 1423 numbers: [1,2,3,4]
1350 properties: { 1424 properties: {
@@ -1357,7 +1431,8 @@ obj2 = {
1357print first, second, color 1431print first, second, color
1358``` 1432```
1359<YueDisplay> 1433<YueDisplay>
1360<pre> 1434
1435```yue
1361obj2 = { 1436obj2 = {
1362 numbers: [1,2,3,4] 1437 numbers: [1,2,3,4]
1363 properties: { 1438 properties: {
@@ -1368,12 +1443,13 @@ obj2 = {
1368 1443
1369{numbers: [first, second]} = obj2 1444{numbers: [first, second]} = obj2
1370print first, second, color 1445print first, second, color
1371</pre> 1446```
1447
1372</YueDisplay> 1448</YueDisplay>
1373 1449
1374如果解构语句很复杂,也可以任意将其分散在几行中。稍微复杂一些的示例: 1450如果解构语句很复杂,也可以任意将其分散在几行中。稍微复杂一些的示例:
1375 1451
1376```moonscript 1452```yuescript
1377{ 1453{
1378 numbers: [first, second] 1454 numbers: [first, second]
1379 properties: { 1455 properties: {
@@ -1382,65 +1458,75 @@ print first, second, color
1382} = obj2 1458} = obj2
1383``` 1459```
1384<YueDisplay> 1460<YueDisplay>
1385<pre> 1461
1462```yue
1386{ 1463{
1387 numbers: [first, second] 1464 numbers: [first, second]
1388 properties: { 1465 properties: {
1389 color: color 1466 color: color
1390 } 1467 }
1391} = obj2 1468} = obj2
1392</pre> 1469```
1470
1393</YueDisplay> 1471</YueDisplay>
1394 1472
1395有时候我们会需要从 Lua 表中提取值并将它们赋给与键同名的局部变量。为了避免编写重复代码,我们可以使用 **:** 前缀操作符: 1473有时候我们会需要从 Lua 表中提取值并将它们赋给与键同名的局部变量。为了避免编写重复代码,我们可以使用 **:** 前缀操作符:
1396 1474
1397```moonscript 1475```yuescript
1398{:concat, :insert} = table 1476{:concat, :insert} = table
1399``` 1477```
1400<YueDisplay> 1478<YueDisplay>
1401<pre> 1479
1480```yue
1402{:concat, :insert} = table 1481{:concat, :insert} = table
1403</pre> 1482```
1483
1404</YueDisplay> 1484</YueDisplay>
1405 1485
1406这样的用法与导入语法有些相似。但我们可以通过混合语法重命名我们想要提取的字段: 1486这样的用法与导入语法有些相似。但我们可以通过混合语法重命名我们想要提取的字段:
1407 1487
1408```moonscript 1488```yuescript
1409{:mix, :max, random: rand} = math 1489{:mix, :max, random: rand} = math
1410``` 1490```
1411<YueDisplay> 1491<YueDisplay>
1412<pre> 1492
1493```yue
1413{:mix, :max, random: rand} = math 1494{:mix, :max, random: rand} = math
1414</pre> 1495```
1496
1415</YueDisplay> 1497</YueDisplay>
1416 1498
1417在进行解构时,你可以指定默认值,如: 1499在进行解构时,你可以指定默认值,如:
1418 1500
1419```moonscript 1501```yuescript
1420{:name = "nameless", :job = "jobless"} = person 1502{:name = "nameless", :job = "jobless"} = person
1421``` 1503```
1422<YueDisplay> 1504<YueDisplay>
1423<pre> 1505
1506```yue
1424{:name = "nameless", :job = "jobless"} = person 1507{:name = "nameless", :job = "jobless"} = person
1425</pre> 1508```
1509
1426</YueDisplay> 1510</YueDisplay>
1427 1511
1428在进行列表解构时,你可以使用`_`作为占位符: 1512在进行列表解构时,你可以使用`_`作为占位符:
1429 1513
1430```moonscript 1514```yuescript
1431[_, two, _, four] = items 1515[_, two, _, four] = items
1432``` 1516```
1433<YueDisplay> 1517<YueDisplay>
1434<pre> 1518
1519```yue
1435[_, two, _, four] = items 1520[_, two, _, four] = items
1436</pre> 1521```
1522
1437</YueDisplay> 1523</YueDisplay>
1438 1524
1439### 范围解构 1525### 范围解构
1440 1526
1441你可以使用展开运算符 `...` 在列表解构中来捕获一个范围的值到子列表中。这在当你想要从列表的开头和结尾提取特定元素,同时收集中间的元素时非常有用。 1527你可以使用展开运算符 `...` 在列表解构中来捕获一个范围的值到子列表中。这在当你想要从列表的开头和结尾提取特定元素,同时收集中间的元素时非常有用。
1442 1528
1443```moonscript 1529```yuescript
1444orders = ["first", "second", "third", "fourth", "last"] 1530orders = ["first", "second", "third", "fourth", "last"]
1445[first, ...bulk, last] = orders 1531[first, ...bulk, last] = orders
1446print first -- 打印: first 1532print first -- 打印: first
@@ -1448,18 +1534,20 @@ print bulk -- 打印: {"second", "third", "fourth"}
1448print last -- 打印: last 1534print last -- 打印: last
1449``` 1535```
1450<YueDisplay> 1536<YueDisplay>
1451<pre> 1537
1538```yue
1452orders = ["first", "second", "third", "fourth", "last"] 1539orders = ["first", "second", "third", "fourth", "last"]
1453[first, ...bulk, last] = orders 1540[first, ...bulk, last] = orders
1454print first -- 打印: first 1541print first -- 打印: first
1455print bulk -- 打印: {"second", "third", "fourth"} 1542print bulk -- 打印: {"second", "third", "fourth"}
1456print last -- 打印: last 1543print last -- 打印: last
1457</pre> 1544```
1545
1458</YueDisplay> 1546</YueDisplay>
1459 1547
1460展开运算符可以用在不同的位置来捕获不同的范围,并且你可以使用 `_` 作为占位符来表示你想跳过对应范围的捕获: 1548展开运算符可以用在不同的位置来捕获不同的范围,并且你可以使用 `_` 作为占位符来表示你想跳过对应范围的捕获:
1461 1549
1462```moonscript 1550```yuescript
1463-- 捕获第一个元素之后的所有元素 1551-- 捕获第一个元素之后的所有元素
1464[first, ...rest] = orders 1552[first, ...rest] = orders
1465 1553
@@ -1470,7 +1558,8 @@ print last -- 打印: last
1470[first, ..._, last] = orders 1558[first, ..._, last] = orders
1471``` 1559```
1472<YueDisplay> 1560<YueDisplay>
1473<pre> 1561
1562```yue
1474-- 捕获第一个元素之后的所有元素 1563-- 捕获第一个元素之后的所有元素
1475[first, ...rest] = orders 1564[first, ...rest] = orders
1476 1565
@@ -1479,14 +1568,15 @@ print last -- 打印: last
1479 1568
1480-- 跳过中间的元素,只捕获第一个和最后一个元素 1569-- 跳过中间的元素,只捕获第一个和最后一个元素
1481[first, ..._, last] = orders 1570[first, ..._, last] = orders
1482</pre> 1571```
1572
1483</YueDisplay> 1573</YueDisplay>
1484 1574
1485### 在其它地方的解构赋值 1575### 在其它地方的解构赋值
1486 1576
1487解构赋值也可以出现在其它隐式进行赋值的地方。一个例子是用在 for 循环中: 1577解构赋值也可以出现在其它隐式进行赋值的地方。一个例子是用在 for 循环中:
1488 1578
1489```moonscript 1579```yuescript
1490tuples = [ 1580tuples = [
1491 ["hello", "world"] 1581 ["hello", "world"]
1492 ["egg", "head"] 1582 ["egg", "head"]
@@ -1496,7 +1586,8 @@ for [left, right] in *tuples
1496 print left, right 1586 print left, right
1497``` 1587```
1498<YueDisplay> 1588<YueDisplay>
1499<pre> 1589
1590```yue
1500tuples = [ 1591tuples = [
1501 ["hello", "world"] 1592 ["hello", "world"]
1502 ["egg", "head"] 1593 ["egg", "head"]
@@ -1504,7 +1595,8 @@ tuples = [
1504 1595
1505for [left, right] in *tuples 1596for [left, right] in *tuples
1506 print left, right 1597 print left, right
1507</pre> 1598```
1599
1508</YueDisplay> 1600</YueDisplay>
1509 1601
1510我们知道数组表中的每个元素都是一个两项的元组,所以我们可以直接在 for 语句的名称子句中使用解构来解包它。 1602我们知道数组表中的每个元素都是一个两项的元组,所以我们可以直接在 for 语句的名称子句中使用解构来解包它。
@@ -1513,18 +1605,20 @@ for [left, right] in *tuples
1513 1605
1514`if` 和 `elseif` 代码块可以在条件表达式的位置进行赋值。在代码执行到要计算条件时,会首先进行赋值计算,并使用赋与的值作为分支判断的条件。赋值的变量仅在条件分支的代码块内有效,这意味着如果值不是真值,那么它就不会被用到。注意,你必须使用“海象运算符” `:=` 而不是 `=` 来做赋值。 1606`if` 和 `elseif` 代码块可以在条件表达式的位置进行赋值。在代码执行到要计算条件时,会首先进行赋值计算,并使用赋与的值作为分支判断的条件。赋值的变量仅在条件分支的代码块内有效,这意味着如果值不是真值,那么它就不会被用到。注意,你必须使用“海象运算符” `:=` 而不是 `=` 来做赋值。
1515 1607
1516```moonscript 1608```yuescript
1517if user := database.find_user "moon" 1609if user := database.find_user "moon"
1518 print user.name 1610 print user.name
1519``` 1611```
1520<YueDisplay> 1612<YueDisplay>
1521<pre> 1613
1614```yue
1522if user := database.find_user "moon" 1615if user := database.find_user "moon"
1523 print user.name 1616 print user.name
1524</pre> 1617```
1618
1525</YueDisplay> 1619</YueDisplay>
1526 1620
1527```moonscript 1621```yuescript
1528if hello := os.getenv "hello" 1622if hello := os.getenv "hello"
1529 print "你有 hello", hello 1623 print "你有 hello", hello
1530elseif world := os.getenv "world" 1624elseif world := os.getenv "world"
@@ -1533,50 +1627,56 @@ else
1533 print "什么都没有 :(" 1627 print "什么都没有 :("
1534``` 1628```
1535<YueDisplay> 1629<YueDisplay>
1536<pre> 1630
1631```yue
1537if hello := os.getenv "hello" 1632if hello := os.getenv "hello"
1538 print "你有 hello", hello 1633 print "你有 hello", hello
1539elseif world := os.getenv "world" 1634elseif world := os.getenv "world"
1540 print "你有 world", world 1635 print "你有 world", world
1541else 1636else
1542 print "什么都没有 :(" 1637 print "什么都没有 :("
1543</pre> 1638```
1639
1544</YueDisplay> 1640</YueDisplay>
1545 1641
1546使用多个返回值的 If 赋值。只有第一个值会被检查,其他值都有同样的作用域。 1642使用多个返回值的 If 赋值。只有第一个值会被检查,其他值都有同样的作用域。
1547```moonscript 1643```yuescript
1548if success, result := pcall -> "无报错地获取结果" 1644if success, result := pcall -> "无报错地获取结果"
1549 print result -- 变量 result 是有作用域的 1645 print result -- 变量 result 是有作用域的
1550print "好的" 1646print "好的"
1551``` 1647```
1552<YueDisplay> 1648<YueDisplay>
1553<pre> 1649
1650```yue
1554if success, result := pcall -> "无报错地获取结果" 1651if success, result := pcall -> "无报错地获取结果"
1555 print result -- 变量 result 是有作用域的 1652 print result -- 变量 result 是有作用域的
1556print "好的" 1653print "好的"
1557</pre> 1654```
1655
1558</YueDisplay> 1656</YueDisplay>
1559 1657
1560### While 赋值 1658### While 赋值
1561 1659
1562你可以在 while 循环中同样使用赋值来获取循环条件的值。 1660你可以在 while 循环中同样使用赋值来获取循环条件的值。
1563```moonscript 1661```yuescript
1564while byte := stream\read_one! 1662while byte := stream\read_one!
1565 -- 对 byte 做一些操作 1663 -- 对 byte 做一些操作
1566 print byte 1664 print byte
1567``` 1665```
1568<YueDisplay> 1666<YueDisplay>
1569<pre> 1667
1668```yue
1570while byte := stream\read_one! 1669while byte := stream\read_one!
1571 -- 对 byte 做一些操作 1670 -- 对 byte 做一些操作
1572 print byte 1671 print byte
1573</pre> 1672```
1673
1574</YueDisplay> 1674</YueDisplay>
1575 1675
1576## 可变参数赋值 1676## 可变参数赋值
1577 1677
1578你可以将函数返回的结果赋值给一个可变参数符号 `...`。然后使用 Lua 的方式访问其内容。 1678你可以将函数返回的结果赋值给一个可变参数符号 `...`。然后使用 Lua 的方式访问其内容。
1579```moonscript 1679```yuescript
1580list = [1, 2, 3, 4, 5] 1680list = [1, 2, 3, 4, 5]
1581fn = (ok) -> ok, table.unpack list 1681fn = (ok) -> ok, table.unpack list
1582ok, ... = fn true 1682ok, ... = fn true
@@ -1585,14 +1685,16 @@ first = select 1, ...
1585print ok, count, first 1685print ok, count, first
1586``` 1686```
1587<YueDisplay> 1687<YueDisplay>
1588<pre> 1688
1689```yue
1589list = [1, 2, 3, 4, 5] 1690list = [1, 2, 3, 4, 5]
1590fn = (ok) -> ok, table.unpack list 1691fn = (ok) -> ok, table.unpack list
1591ok, ... = fn true 1692ok, ... = fn true
1592count = select '#', ... 1693count = select '#', ...
1593first = select 1, ... 1694first = select 1, ...
1594print ok, count, first 1695print ok, count, first
1595</pre> 1696```
1697
1596</YueDisplay> 1698</YueDisplay>
1597 1699
1598## 空白 1700## 空白
@@ -1603,19 +1705,21 @@ print ok, count, first
1603 1705
1604一条语句通常以换行结束。你也可以使用分号 `;` 显式结束一条语句,从而在同一行中编写多条语句: 1706一条语句通常以换行结束。你也可以使用分号 `;` 显式结束一条语句,从而在同一行中编写多条语句:
1605 1707
1606```moonscript 1708```yuescript
1607a = 1; b = 2; print a + b 1709a = 1; b = 2; print a + b
1608``` 1710```
1609<YueDisplay> 1711<YueDisplay>
1610<pre> 1712
1713```yue
1611a = 1; b = 2; print a + b 1714a = 1; b = 2; print a + b
1612</pre> 1715```
1716
1613</YueDisplay> 1717</YueDisplay>
1614 1718
1615### 多行链式调用 1719### 多行链式调用
1616 1720
1617你可以使用相同的缩进来编写多行链式函数调用。 1721你可以使用相同的缩进来编写多行链式函数调用。
1618```moonscript 1722```yuescript
1619Rx.Observable 1723Rx.Observable
1620 .fromRange 1, 8 1724 .fromRange 1, 8
1621 \filter (x) -> x % 2 == 0 1725 \filter (x) -> x % 2 == 0
@@ -1624,19 +1728,21 @@ Rx.Observable
1624 \subscribe print 1728 \subscribe print
1625``` 1729```
1626<YueDisplay> 1730<YueDisplay>
1627<pre> 1731
1732```yue
1628Rx.Observable 1733Rx.Observable
1629 .fromRange 1, 8 1734 .fromRange 1, 8
1630 \filter (x) -> x % 2 == 0 1735 \filter (x) -> x % 2 == 0
1631 \concat Rx.Observable.of 'who do we appreciate' 1736 \concat Rx.Observable.of 'who do we appreciate'
1632 \map (value) -> value .. '!' 1737 \map (value) -> value .. '!'
1633 \subscribe print 1738 \subscribe print
1634</pre> 1739```
1740
1635</YueDisplay> 1741</YueDisplay>
1636 1742
1637## 注释 1743## 注释
1638 1744
1639```moonscript 1745```yuescript
1640-- 我是一个注释 1746-- 我是一个注释
1641 1747
1642str = --[[ 1748str = --[[
@@ -1649,7 +1755,8 @@ str = --[[
1649func --[[端口]] 3000, --[[ip]] "192.168.1.1" 1755func --[[端口]] 3000, --[[ip]] "192.168.1.1"
1650``` 1756```
1651<YueDisplay> 1757<YueDisplay>
1652<pre> 1758
1759```yue
1653-- 我是一个注释 1760-- 我是一个注释
1654 1761
1655str = --[[ 1762str = --[[
@@ -1660,14 +1767,15 @@ str = --[[
1660 .. strC 1767 .. strC
1661 1768
1662func --[[端口]] 3000, --[[ip]] "192.168.1.1" 1769func --[[端口]] 3000, --[[ip]] "192.168.1.1"
1663</pre> 1770```
1771
1664</YueDisplay> 1772</YueDisplay>
1665 1773
1666## 错误处理 1774## 错误处理
1667 1775
1668用于统一进行 Lua 错误处理的便捷语法。 1776用于统一进行 Lua 错误处理的便捷语法。
1669 1777
1670```moonscript 1778```yuescript
1671try 1779try
1672 func 1, 2, 3 1780 func 1, 2, 3
1673catch err 1781catch err
@@ -1695,7 +1803,8 @@ catch err
1695 print result 1803 print result
1696``` 1804```
1697<YueDisplay> 1805<YueDisplay>
1698<pre> 1806
1807```yue
1699try 1808try
1700 func 1, 2, 3 1809 func 1, 2, 3
1701catch err 1810catch err
@@ -1721,14 +1830,15 @@ if success, result := try func 1, 2, 3
1721catch err 1830catch err
1722 print yue.traceback err 1831 print yue.traceback err
1723 print result 1832 print result
1724</pre> 1833```
1834
1725</YueDisplay> 1835</YueDisplay>
1726 1836
1727### 错误处理简化 1837### 错误处理简化
1728 1838
1729`try?` 是 `try` 的功能简化语法,它不再返回 `try` 语句的布尔状态,并在成功时直接返回 `try` 代码块的结果,失败时返回 `nil` 值而非错误对象。 1839`try?` 是 `try` 的功能简化语法,它不再返回 `try` 语句的布尔状态,并在成功时直接返回 `try` 代码块的结果,失败时返回 `nil` 值而非错误对象。
1730 1840
1731```moonscript 1841```yuescript
1732a, b, c = try? func! 1842a, b, c = try? func!
1733 1843
1734-- 与空值合并运算符一起使用 1844-- 与空值合并运算符一起使用
@@ -1746,7 +1856,8 @@ catch e
1746 e 1856 e
1747``` 1857```
1748<YueDisplay> 1858<YueDisplay>
1749<pre> 1859
1860```yue
1750a, b, c = try? func! 1861a, b, c = try? func!
1751 1862
1752-- 与空值合并运算符一起使用 1863-- 与空值合并运算符一起使用
@@ -1762,48 +1873,55 @@ f try?
1762catch e 1873catch e
1763 print e 1874 print e
1764 e 1875 e
1765</pre> 1876```
1877
1766</YueDisplay> 1878</YueDisplay>
1767 1879
1768## 属性 1880## 属性
1769 1881
1770月之脚本现在提供了 Lua 5.4 新增的叫做属性的语法支持。在月之脚本编译到的 Lua 目标版本低于 5.4 时,你仍然可以同时使用`const` 和 `close` 的属性声明语法,并获得常量检查和作用域回调的功能。 1882月之脚本现在提供了 Lua 5.4 新增的叫做属性的语法支持。在月之脚本编译到的 Lua 目标版本低于 5.4 时,你仍然可以同时使用`const` 和 `close` 的属性声明语法,并获得常量检查和作用域回调的功能。
1771 1883
1772```moonscript 1884```yuescript
1773const a = 123 1885const a = 123
1774close _ = <close>: -> print "超出范围。" 1886close _ = <close>: -> print "超出范围。"
1775``` 1887```
1776<YueDisplay> 1888<YueDisplay>
1777<pre> 1889
1890```yue
1778const a = 123 1891const a = 123
1779close _ = &lt;close&gt;: -> print "超出范围。" 1892close _ = <close>: -> print "超出范围。"
1780</pre> 1893```
1894
1781</YueDisplay> 1895</YueDisplay>
1782 1896
1783你可以对进行解构得到的变量标记为常量。 1897你可以对进行解构得到的变量标记为常量。
1784 1898
1785```moonscript 1899```yuescript
1786const {:a, :b, c, d} = tb 1900const {:a, :b, c, d} = tb
1787-- a = 1 1901-- a = 1
1788``` 1902```
1789<YueDisplay> 1903<YueDisplay>
1790<pre> 1904
1905```yue
1791const {:a, :b, c, d} = tb 1906const {:a, :b, c, d} = tb
1792-- a = 1 1907-- a = 1
1793</pre> 1908```
1909
1794</YueDisplay> 1910</YueDisplay>
1795 1911
1796你也可以声明全局变量为常量。 1912你也可以声明全局变量为常量。
1797 1913
1798```moonscript 1914```yuescript
1799global const Constant = 123 1915global const Constant = 123
1800-- Constant = 1 1916-- Constant = 1
1801``` 1917```
1802<YueDisplay> 1918<YueDisplay>
1803<pre> 1919
1920```yue
1804global const Constant = 123 1921global const Constant = 123
1805-- Constant = 1 1922-- Constant = 1
1806</pre> 1923```
1924
1807</YueDisplay> 1925</YueDisplay>
1808 1926
1809## 字面量 1927## 字面量
@@ -1812,7 +1930,7 @@ Lua 中的所有基本字面量都可以在月之脚本中使用。包括数字
1812 1930
1813但与 Lua 不同的是,单引号和双引号字符串内部允许有换行: 1931但与 Lua 不同的是,单引号和双引号字符串内部允许有换行:
1814 1932
1815```moonscript 1933```yuescript
1816some_string = "这是一个字符串 1934some_string = "这是一个字符串
1817 并包括一个换行。" 1935 并包括一个换行。"
1818 1936
@@ -1821,39 +1939,43 @@ some_string = "这是一个字符串
1821print "我有#{math.random! * 100}%的把握。" 1939print "我有#{math.random! * 100}%的把握。"
1822``` 1940```
1823<YueDisplay> 1941<YueDisplay>
1824<pre> 1942
1943```yue
1825some_string = "这是一个字符串 1944some_string = "这是一个字符串
1826 并包括一个换行。" 1945 并包括一个换行。"
1827 1946
1828-- 使用#{}语法可以将表达式插入到字符串字面量中。 1947-- 使用#{}语法可以将表达式插入到字符串字面量中。
1829-- 字符串插值只在双引号字符串中可用。 1948-- 字符串插值只在双引号字符串中可用。
1830print "我有#{math.random! * 100}%的把握。" 1949print "我有#{math.random! * 100}%的把握。"
1831</pre> 1950```
1951
1832</YueDisplay> 1952</YueDisplay>
1833 1953
1834### 数字字面量 1954### 数字字面量
1835 1955
1836你可以在数字字面量中使用下划线来增加可读性。 1956你可以在数字字面量中使用下划线来增加可读性。
1837 1957
1838```moonscript 1958```yuescript
1839integer = 1_000_000 1959integer = 1_000_000
1840hex = 0xEF_BB_BF 1960hex = 0xEF_BB_BF
1841binary = 0B10011 1961binary = 0B10011
1842``` 1962```
1843<YueDisplay> 1963<YueDisplay>
1844 1964
1845<pre> 1965
1966```yue
1846integer = 1_000_000 1967integer = 1_000_000
1847hex = 0xEF_BB_BF 1968hex = 0xEF_BB_BF
1848binary = 0B10011 1969binary = 0B10011
1849</pre> 1970```
1971
1850</YueDisplay> 1972</YueDisplay>
1851 1973
1852### YAML 风格字符串 1974### YAML 风格字符串
1853 1975
1854使用 `|` 前缀标记一个多行 YAML 风格字符串: 1976使用 `|` 前缀标记一个多行 YAML 风格字符串:
1855 1977
1856```moonscript 1978```yuescript
1857str = | 1979str = |
1858 key: value 1980 key: value
1859 list: 1981 list:
@@ -1861,20 +1983,22 @@ str = |
1861 - #{expr} 1983 - #{expr}
1862``` 1984```
1863<YueDisplay> 1985<YueDisplay>
1864<pre> 1986
1987```yue
1865str = | 1988str = |
1866 key: value 1989 key: value
1867 list: 1990 list:
1868 - item1 1991 - item1
1869 - #{expr} 1992 - #{expr}
1870</pre> 1993```
1994
1871</YueDisplay> 1995</YueDisplay>
1872 1996
1873其效果类似于原生 Lua 的多行拼接,所有文本(含换行)将被保留下来,并支持 `#{...}` 语法,通过 `tostring(expr)` 插入表达式结果。 1997其效果类似于原生 Lua 的多行拼接,所有文本(含换行)将被保留下来,并支持 `#{...}` 语法,通过 `tostring(expr)` 插入表达式结果。
1874 1998
1875YAML 风格的多行字符串会自动检测首行后最小的公共缩进,并从所有行中删除该前缀空白字符。这让你可以在代码中对齐文本,但输出字符串不会带多余缩进。 1999YAML 风格的多行字符串会自动检测首行后最小的公共缩进,并从所有行中删除该前缀空白字符。这让你可以在代码中对齐文本,但输出字符串不会带多余缩进。
1876 2000
1877```moonscript 2001```yuescript
1878fn = -> 2002fn = ->
1879 str = | 2003 str = |
1880 foo: 2004 foo:
@@ -1882,50 +2006,56 @@ fn = ->
1882 return str 2006 return str
1883``` 2007```
1884<YueDisplay> 2008<YueDisplay>
1885<pre> 2009
2010```yue
1886fn = -> 2011fn = ->
1887 str = | 2012 str = |
1888 foo: 2013 foo:
1889 bar: baz 2014 bar: baz
1890 return str 2015 return str
1891</pre> 2016```
2017
1892</YueDisplay> 2018</YueDisplay>
1893 2019
1894输出字符串中的 foo: 对齐到行首,不会带有函数缩进空格。保留内部缩进的相对结构,适合书写结构化嵌套样式的内容。 2020输出字符串中的 foo: 对齐到行首,不会带有函数缩进空格。保留内部缩进的相对结构,适合书写结构化嵌套样式的内容。
1895 2021
1896支持自动处理字符中的引号、反斜杠等特殊符号,无需手动转义: 2022支持自动处理字符中的引号、反斜杠等特殊符号,无需手动转义:
1897 2023
1898```moonscript 2024```yuescript
1899str = | 2025str = |
1900 path: "C:\Program Files\App" 2026 path: "C:\Program Files\App"
1901 note: 'He said: "#{Hello}!"' 2027 note: 'He said: "#{Hello}!"'
1902``` 2028```
1903<YueDisplay> 2029<YueDisplay>
1904<pre> 2030
2031```yue
1905str = | 2032str = |
1906 path: "C:\Program Files\App" 2033 path: "C:\Program Files\App"
1907 note: 'He said: "#{Hello}!"' 2034 note: 'He said: "#{Hello}!"'
1908</pre> 2035```
2036
1909</YueDisplay> 2037</YueDisplay>
1910 2038
1911## 函数字面量 2039## 函数字面量
1912 2040
1913所有函数都是使用月之脚本的函数表达式创建的。一个简单的函数可以用箭头表示为:**->**。 2041所有函数都是使用月之脚本的函数表达式创建的。一个简单的函数可以用箭头表示为:**->**。
1914 2042
1915```moonscript 2043```yuescript
1916my_function = -> 2044my_function = ->
1917my_function() -- 调用空函数 2045my_function() -- 调用空函数
1918``` 2046```
1919<YueDisplay> 2047<YueDisplay>
1920<pre> 2048
2049```yue
1921my_function = -> 2050my_function = ->
1922my_function() -- 调用空函数 2051my_function() -- 调用空函数
1923</pre> 2052```
2053
1924</YueDisplay> 2054</YueDisplay>
1925 2055
1926函数体可以是紧跟在箭头后的一个语句,或者是在后面的行上使用同样缩进的一系列语句: 2056函数体可以是紧跟在箭头后的一个语句,或者是在后面的行上使用同样缩进的一系列语句:
1927 2057
1928```moonscript 2058```yuescript
1929func_a = -> print "你好,世界" 2059func_a = -> print "你好,世界"
1930 2060
1931func_b = -> 2061func_b = ->
@@ -1933,147 +2063,169 @@ func_b = ->
1933 print "这个值是:", value 2063 print "这个值是:", value
1934``` 2064```
1935<YueDisplay> 2065<YueDisplay>
1936<pre> 2066
2067```yue
1937func_a = -> print "你好,世界" 2068func_a = -> print "你好,世界"
1938 2069
1939func_b = -> 2070func_b = ->
1940 value = 100 2071 value = 100
1941 print "这个值是:", value 2072 print "这个值是:", value
1942</pre> 2073```
2074
1943</YueDisplay> 2075</YueDisplay>
1944 2076
1945如果一个函数没有参数,可以使用 **\!** 操作符调用它,而不是空括号。使用 **\!** 调用没有参数的函数是推荐的写法。 2077如果一个函数没有参数,可以使用 **\!** 操作符调用它,而不是空括号。使用 **\!** 调用没有参数的函数是推荐的写法。
1946 2078
1947```moonscript 2079```yuescript
1948func_a! 2080func_a!
1949func_b() 2081func_b()
1950``` 2082```
1951<YueDisplay> 2083<YueDisplay>
1952<pre> 2084
2085```yue
1953func_a! 2086func_a!
1954func_b() 2087func_b()
1955</pre> 2088```
2089
1956</YueDisplay> 2090</YueDisplay>
1957 2091
1958带有参数的函数可以通过在箭头前加上括号中的参数名列表来进行创建: 2092带有参数的函数可以通过在箭头前加上括号中的参数名列表来进行创建:
1959 2093
1960```moonscript 2094```yuescript
1961sum = (x, y) -> print "数字的和", x + y 2095sum = (x, y) -> print "数字的和", x + y
1962``` 2096```
1963<YueDisplay> 2097<YueDisplay>
1964<pre> 2098
2099```yue
1965sum = (x, y) -> print "数字的和", x + y 2100sum = (x, y) -> print "数字的和", x + y
1966</pre> 2101```
2102
1967</YueDisplay> 2103</YueDisplay>
1968 2104
1969函数可以通过在函数名后列出参数来调用。当对函数做嵌套的调用时,后面列出的参数会应用于左侧最近的函数。 2105函数可以通过在函数名后列出参数来调用。当对函数做嵌套的调用时,后面列出的参数会应用于左侧最近的函数。
1970 2106
1971```moonscript 2107```yuescript
1972sum 10, 20 2108sum 10, 20
1973print sum 10, 20 2109print sum 10, 20
1974 2110
1975a b c "a", "b", "c" 2111a b c "a", "b", "c"
1976``` 2112```
1977<YueDisplay> 2113<YueDisplay>
1978<pre> 2114
2115```yue
1979sum 10, 20 2116sum 10, 20
1980print sum 10, 20 2117print sum 10, 20
1981 2118
1982a b c "a", "b", "c" 2119a b c "a", "b", "c"
1983</pre> 2120```
2121
1984</YueDisplay> 2122</YueDisplay>
1985 2123
1986为了避免在调用函数时产生歧义,也可以使用括号将参数括起来。比如在以下的例子中是必需的,这样才能确保参数被传入到正确的函数。 2124为了避免在调用函数时产生歧义,也可以使用括号将参数括起来。比如在以下的例子中是必需的,这样才能确保参数被传入到正确的函数。
1987 2125
1988```moonscript 2126```yuescript
1989print "x:", sum(10, 20), "y:", sum(30, 40) 2127print "x:", sum(10, 20), "y:", sum(30, 40)
1990``` 2128```
1991<YueDisplay> 2129<YueDisplay>
1992<pre> 2130
2131```yue
1993print "x:", sum(10, 20), "y:", sum(30, 40) 2132print "x:", sum(10, 20), "y:", sum(30, 40)
1994</pre> 2133```
2134
1995</YueDisplay> 2135</YueDisplay>
1996 2136
1997注意:函数名与开始括号之间不能有任何空格。 2137注意:函数名与开始括号之间不能有任何空格。
1998 2138
1999函数会将函数体中的最后一个语句强制转换为返回语句,这被称作隐式返回: 2139函数会将函数体中的最后一个语句强制转换为返回语句,这被称作隐式返回:
2000 2140
2001```moonscript 2141```yuescript
2002sum = (x, y) -> x + y 2142sum = (x, y) -> x + y
2003print "数字的和是", sum 10, 20 2143print "数字的和是", sum 10, 20
2004``` 2144```
2005<YueDisplay> 2145<YueDisplay>
2006<pre> 2146
2147```yue
2007sum = (x, y) -> x + y 2148sum = (x, y) -> x + y
2008print "数字的和是", sum 10, 20 2149print "数字的和是", sum 10, 20
2009</pre> 2150```
2151
2010</YueDisplay> 2152</YueDisplay>
2011 2153
2012如果你需要做显式返回,可以使用 return 关键字: 2154如果你需要做显式返回,可以使用 return 关键字:
2013 2155
2014```moonscript 2156```yuescript
2015sum = (x, y) -> return x + y 2157sum = (x, y) -> return x + y
2016``` 2158```
2017<YueDisplay> 2159<YueDisplay>
2018<pre> 2160
2161```yue
2019sum = (x, y) -> return x + y 2162sum = (x, y) -> return x + y
2020</pre> 2163```
2164
2021</YueDisplay> 2165</YueDisplay>
2022 2166
2023就像在Lua中一样,函数可以返回多个值。最后一个语句必须是由逗号分隔的值列表: 2167就像在Lua中一样,函数可以返回多个值。最后一个语句必须是由逗号分隔的值列表:
2024 2168
2025```moonscript 2169```yuescript
2026mystery = (x, y) -> x + y, x - y 2170mystery = (x, y) -> x + y, x - y
2027a, b = mystery 10, 20 2171a, b = mystery 10, 20
2028``` 2172```
2029<YueDisplay> 2173<YueDisplay>
2030<pre> 2174
2175```yue
2031mystery = (x, y) -> x + y, x - y 2176mystery = (x, y) -> x + y, x - y
2032a, b = mystery 10, 20 2177a, b = mystery 10, 20
2033</pre> 2178```
2179
2034</YueDisplay> 2180</YueDisplay>
2035 2181
2036### 粗箭头 2182### 粗箭头
2037 2183
2038因为在 Lua 中调用方法时,经常习惯将对象作为第一个参数传入,所以月之脚本提供了一种特殊的语法来创建自动包含 self 参数的函数。 2184因为在 Lua 中调用方法时,经常习惯将对象作为第一个参数传入,所以月之脚本提供了一种特殊的语法来创建自动包含 self 参数的函数。
2039 2185
2040```moonscript 2186```yuescript
2041func = (num) => @value + num 2187func = (num) => @value + num
2042``` 2188```
2043<YueDisplay> 2189<YueDisplay>
2044<pre> 2190
2191```yue
2045func = (num) => @value + num 2192func = (num) => @value + num
2046</pre> 2193```
2194
2047</YueDisplay> 2195</YueDisplay>
2048 2196
2049### 参数默认值 2197### 参数默认值
2050 2198
2051可以为函数的参数提供默认值。如果参数的值为 nil,则确定该参数为空。任何具有默认值的 nil 参数在函数体运行之前都会被替换。 2199可以为函数的参数提供默认值。如果参数的值为 nil,则确定该参数为空。任何具有默认值的 nil 参数在函数体运行之前都会被替换。
2052 2200
2053```moonscript 2201```yuescript
2054my_function = (name = "某物", height = 100) -> 2202my_function = (name = "某物", height = 100) ->
2055 print "你好,我是", name 2203 print "你好,我是", name
2056 print "我的高度是", height 2204 print "我的高度是", height
2057``` 2205```
2058<YueDisplay> 2206<YueDisplay>
2059<pre> 2207
2208```yue
2060my_function = (name = "某物", height = 100) -> 2209my_function = (name = "某物", height = 100) ->
2061 print "你好,我是", name 2210 print "你好,我是", name
2062 print "我的高度是", height 2211 print "我的高度是", height
2063</pre> 2212```
2213
2064</YueDisplay> 2214</YueDisplay>
2065 2215
2066函数参数的默认值表达式在函数体中会按参数声明的顺序进行计算。因此,在默认值的表达式中可以访问先前声明的参数。 2216函数参数的默认值表达式在函数体中会按参数声明的顺序进行计算。因此,在默认值的表达式中可以访问先前声明的参数。
2067 2217
2068```moonscript 2218```yuescript
2069some_args = (x = 100, y = x + 1000) -> 2219some_args = (x = 100, y = x + 1000) ->
2070 print x + y 2220 print x + y
2071``` 2221```
2072<YueDisplay> 2222<YueDisplay>
2073<pre> 2223
2224```yue
2074some_args = (x = 100, y = x + 1000) -> 2225some_args = (x = 100, y = x + 1000) ->
2075 print x + y 2226 print x + y
2076</pre> 2227```
2228
2077</YueDisplay> 2229</YueDisplay>
2078 2230
2079### 多行参数 2231### 多行参数
@@ -2082,7 +2234,7 @@ some_args = (x = 100, y = x + 1000) ->
2082 2234
2083如果要将参数列表写到下一行,那么当前行必须以逗号结束。并且下一行的缩进必须比当前的缩进多。一旦做了参数的缩进,所有其他参数列表的行必须保持相同的缩进级别,以成为参数列表的一部分。 2235如果要将参数列表写到下一行,那么当前行必须以逗号结束。并且下一行的缩进必须比当前的缩进多。一旦做了参数的缩进,所有其他参数列表的行必须保持相同的缩进级别,以成为参数列表的一部分。
2084 2236
2085```moonscript 2237```yuescript
2086my_func 5, 4, 3, 2238my_func 5, 4, 3,
2087 8, 9, 10 2239 8, 9, 10
2088 2240
@@ -2092,7 +2244,8 @@ cool_func 1, 2,
2092 7, 8 2244 7, 8
2093``` 2245```
2094<YueDisplay> 2246<YueDisplay>
2095<pre> 2247
2248```yue
2096my_func 5, 4, 3, 2249my_func 5, 4, 3,
2097 8, 9, 10 2250 8, 9, 10
2098 2251
@@ -2100,29 +2253,32 @@ cool_func 1, 2,
2100 3, 4, 2253 3, 4,
2101 5, 6, 2254 5, 6,
2102 7, 8 2255 7, 8
2103</pre> 2256```
2257
2104</YueDisplay> 2258</YueDisplay>
2105 2259
2106这种调用方式可以做嵌套。并通过缩进级别来确定参数属于哪一个函数。 2260这种调用方式可以做嵌套。并通过缩进级别来确定参数属于哪一个函数。
2107 2261
2108```moonscript 2262```yuescript
2109my_func 5, 6, 7, 2263my_func 5, 6, 7,
2110 6, another_func 6, 7, 8, 2264 6, another_func 6, 7, 8,
2111 9, 1, 2, 2265 9, 1, 2,
2112 5, 4 2266 5, 4
2113``` 2267```
2114<YueDisplay> 2268<YueDisplay>
2115<pre> 2269
2270```yue
2116my_func 5, 6, 7, 2271my_func 5, 6, 7,
2117 6, another_func 6, 7, 8, 2272 6, another_func 6, 7, 8,
2118 9, 1, 2, 2273 9, 1, 2,
2119 5, 4 2274 5, 4
2120</pre> 2275```
2276
2121</YueDisplay> 2277</YueDisplay>
2122 2278
2123因为 Lua 表也使用逗号作为分隔符,这种缩进语法有助于让值成为参数列表的一部分,而不是 Lua 表的一部分。 2279因为 Lua 表也使用逗号作为分隔符,这种缩进语法有助于让值成为参数列表的一部分,而不是 Lua 表的一部分。
2124 2280
2125```moonscript 2281```yuescript
2126x = [ 2282x = [
2127 1, 2, 3, 4, a_func 4, 5, 2283 1, 2, 3, 4, a_func 4, 5,
2128 5, 6, 2284 5, 6,
@@ -2130,35 +2286,39 @@ x = [
2130] 2286]
2131``` 2287```
2132<YueDisplay> 2288<YueDisplay>
2133<pre> 2289
2290```yue
2134x = [ 2291x = [
2135 1, 2, 3, 4, a_func 4, 5, 2292 1, 2, 3, 4, a_func 4, 5,
2136 5, 6, 2293 5, 6,
2137 8, 9, 10 2294 8, 9, 10
2138] 2295]
2139</pre> 2296```
2297
2140</YueDisplay> 2298</YueDisplay>
2141 2299
2142有个不常见的写法可以注意一下,如果我们将在后面使用较低的缩进,我们可以为函数参数提供更深的缩进来区分列表的归属。 2300有个不常见的写法可以注意一下,如果我们将在后面使用较低的缩进,我们可以为函数参数提供更深的缩进来区分列表的归属。
2143 2301
2144```moonscript 2302```yuescript
2145y = [ my_func 1, 2, 3, 2303y = [ my_func 1, 2, 3,
2146 4, 5, 2304 4, 5,
2147 5, 6, 7 2305 5, 6, 7
2148] 2306]
2149``` 2307```
2150<YueDisplay> 2308<YueDisplay>
2151<pre> 2309
2310```yue
2152y = [ my_func 1, 2, 3, 2311y = [ my_func 1, 2, 3,
2153 4, 5, 2312 4, 5,
2154 5, 6, 7 2313 5, 6, 7
2155] 2314]
2156</pre> 2315```
2316
2157</YueDisplay> 2317</YueDisplay>
2158 2318
2159对于其它有代码块跟随的语句,比如条件语句,也可以通过小心安排缩进来做类似的事。比如我们可以通过调整缩进级别来控制一些值归属于哪个语句: 2319对于其它有代码块跟随的语句,比如条件语句,也可以通过小心安排缩进来做类似的事。比如我们可以通过调整缩进级别来控制一些值归属于哪个语句:
2160 2320
2161```moonscript 2321```yuescript
2162if func 1, 2, 3, 2322if func 1, 2, 3,
2163 "你好", 2323 "你好",
2164 "世界" 2324 "世界"
@@ -2172,7 +2332,8 @@ if func 1, 2, 3,
2172 print "我在if内部" 2332 print "我在if内部"
2173``` 2333```
2174<YueDisplay> 2334<YueDisplay>
2175<pre> 2335
2336```yue
2176if func 1, 2, 3, 2337if func 1, 2, 3,
2177 "你好", 2338 "你好",
2178 "世界" 2339 "世界"
@@ -2184,7 +2345,8 @@ if func 1, 2, 3,
2184 "世界" 2345 "世界"
2185 print "你好" 2346 print "你好"
2186 print "我在if内部" 2347 print "我在if内部"
2187</pre> 2348```
2349
2188</YueDisplay> 2350</YueDisplay>
2189 2351
2190### 参数解构 2352### 参数解构
@@ -2195,7 +2357,7 @@ if func 1, 2, 3,
2195 2357
2196- 无 {} 包裹、以键值/简写键序列开头,直至遇到其它表达式终止(例如 :a, b: b1, :c),表示从同一个对象中解构多个字段。 2358- 无 {} 包裹、以键值/简写键序列开头,直至遇到其它表达式终止(例如 :a, b: b1, :c),表示从同一个对象中解构多个字段。
2197 2359
2198```moonscript 2360```yuescript
2199f1 = (:a, :b, :c) -> 2361f1 = (:a, :b, :c) ->
2200 print a, b, c 2362 print a, b, c
2201 2363
@@ -2208,7 +2370,8 @@ arg1 = {a: 0}
2208f2 arg1, arg2 2370f2 arg1, arg2
2209``` 2371```
2210<YueDisplay> 2372<YueDisplay>
2211<pre> 2373
2374```yue
2212f1 = (:a, :b, :c) -> 2375f1 = (:a, :b, :c) ->
2213 print a, b, c 2376 print a, b, c
2214 2377
@@ -2219,14 +2382,15 @@ f2 = ({a: a1 = 123, :b = 'abc'}, c = {}) ->
2219 2382
2220arg1 = {a: 0} 2383arg1 = {a: 0}
2221f2 arg1, arg2 2384f2 arg1, arg2
2222</pre> 2385```
2386
2223</YueDisplay> 2387</YueDisplay>
2224 2388
2225### 前置返回表达式 2389### 前置返回表达式
2226 2390
2227在深度嵌套的函数体中,为了提升返回值的可读性及编写便利性,我们新增了 “前置返回表达式” 语法。其形式如下: 2391在深度嵌套的函数体中,为了提升返回值的可读性及编写便利性,我们新增了 “前置返回表达式” 语法。其形式如下:
2228 2392
2229```moon 2393```yuescript
2230findFirstEven = (list): nil -> 2394findFirstEven = (list): nil ->
2231 for item in *list 2395 for item in *list
2232 if type(item) == "table" 2396 if type(item) == "table"
@@ -2235,19 +2399,21 @@ findFirstEven = (list): nil ->
2235 return sub 2399 return sub
2236``` 2400```
2237<YueDisplay> 2401<YueDisplay>
2238<pre> 2402
2403```yue
2239findFirstEven = (list): nil -> 2404findFirstEven = (list): nil ->
2240 for item in *list 2405 for item in *list
2241 if type(item) == "table" 2406 if type(item) == "table"
2242 for sub in *item 2407 for sub in *item
2243 if sub % 2 == 0 2408 if sub % 2 == 0
2244 return sub 2409 return sub
2245</pre> 2410```
2411
2246</YueDisplay> 2412</YueDisplay>
2247 2413
2248这个写法等价于: 2414这个写法等价于:
2249 2415
2250```moon 2416```yuescript
2251findFirstEven = (list) -> 2417findFirstEven = (list) ->
2252 for item in *list 2418 for item in *list
2253 if type(item) == "table" 2419 if type(item) == "table"
@@ -2257,7 +2423,8 @@ findFirstEven = (list) ->
2257 nil 2423 nil
2258``` 2424```
2259<YueDisplay> 2425<YueDisplay>
2260<pre> 2426
2427```yue
2261findFirstEven = (list) -> 2428findFirstEven = (list) ->
2262 for item in *list 2429 for item in *list
2263 if type(item) == "table" 2430 if type(item) == "table"
@@ -2265,7 +2432,8 @@ findFirstEven = (list) ->
2265 if sub % 2 == 0 2432 if sub % 2 == 0
2266 return sub 2433 return sub
2267 nil 2434 nil
2268</pre> 2435```
2436
2269</YueDisplay> 2437</YueDisplay>
2270 2438
2271唯一的区别在于:你可以将函数的返回值表达式提前写在 `->` 或 `=>` 前,用以指示该函数应隐式返回该表达式的值。这样即使在多层循环或条件判断的场景下,也无需编写尾行悬挂的返回表达式,逻辑结构会更加直观清晰。 2439唯一的区别在于:你可以将函数的返回值表达式提前写在 `->` 或 `=>` 前,用以指示该函数应隐式返回该表达式的值。这样即使在多层循环或条件判断的场景下,也无需编写尾行悬挂的返回表达式,逻辑结构会更加直观清晰。
@@ -2274,7 +2442,7 @@ findFirstEven = (list) ->
2274 2442
2275你可以使用 `(...t) ->` 语法来将变长参数自动存储到一个命名表中。这个表会包含所有传入的参数(包括 `nil` 值),并且会在表的 `n` 字段中存储实际传入的参数个数(包括 `nil` 值在内的个数)。 2443你可以使用 `(...t) ->` 语法来将变长参数自动存储到一个命名表中。这个表会包含所有传入的参数(包括 `nil` 值),并且会在表的 `n` 字段中存储实际传入的参数个数(包括 `nil` 值在内的个数)。
2276 2444
2277```moonscript 2445```yuescript
2278f = (...t) -> 2446f = (...t) ->
2279 print "参数个数:", t.n 2447 print "参数个数:", t.n
2280 print "表长度:", #t 2448 print "表长度:", #t
@@ -2296,7 +2464,8 @@ process = (...args) ->
2296process 1, nil, 3, nil, 5 2464process 1, nil, 3, nil, 5
2297``` 2465```
2298<YueDisplay> 2466<YueDisplay>
2299<pre> 2467
2468```yue
2300f = (...t) -> 2469f = (...t) ->
2301 print "参数个数:", t.n 2470 print "参数个数:", t.n
2302 print "表长度:", #t 2471 print "表长度:", #t
@@ -2316,53 +2485,60 @@ process = (...args) ->
2316 sum 2485 sum
2317 2486
2318process 1, nil, 3, nil, 5 2487process 1, nil, 3, nil, 5
2319</pre> 2488```
2489
2320</YueDisplay> 2490</YueDisplay>
2321 2491
2322## 反向回调 2492## 反向回调
2323 2493
2324反向回调用于减少函数回调的嵌套。它们使用指向左侧的箭头,并且默认会被定义为传入后续函数调用的最后一个参数。它的语法大部分与常规箭头函数相同,只是它指向另一方向,并且后续的函数体不需要进行缩进。 2494反向回调用于减少函数回调的嵌套。它们使用指向左侧的箭头,并且默认会被定义为传入后续函数调用的最后一个参数。它的语法大部分与常规箭头函数相同,只是它指向另一方向,并且后续的函数体不需要进行缩进。
2325 2495
2326```moonscript 2496```yuescript
2327<- f 2497<- f
2328print "hello" 2498print "hello"
2329``` 2499```
2330<YueDisplay> 2500<YueDisplay>
2331<pre> 2501
2502```yue
2332<- f 2503<- f
2333print "hello" 2504print "hello"
2334</pre> 2505```
2506
2335</YueDisplay> 2507</YueDisplay>
2336 2508
2337月之脚本也提供了粗箭头反向回调函数。 2509月之脚本也提供了粗箭头反向回调函数。
2338 2510
2339```moonscript 2511```yuescript
2340<= f 2512<= f
2341print @value 2513print @value
2342``` 2514```
2343<YueDisplay> 2515<YueDisplay>
2344<pre> 2516
2517```yue
2345<= f 2518<= f
2346print @value 2519print @value
2347</pre> 2520```
2521
2348</YueDisplay> 2522</YueDisplay>
2349 2523
2350你可以通过一个占位符指定回调函数的传参位置。 2524你可以通过一个占位符指定回调函数的传参位置。
2351 2525
2352```moonscript 2526```yuescript
2353(x) <- map _, [1, 2, 3] 2527(x) <- map _, [1, 2, 3]
2354x * 2 2528x * 2
2355``` 2529```
2356<YueDisplay> 2530<YueDisplay>
2357<pre> 2531
2532```yue
2358(x) <- map _, [1, 2, 3] 2533(x) <- map _, [1, 2, 3]
2359x * 2 2534x * 2
2360</pre> 2535```
2536
2361</YueDisplay> 2537</YueDisplay>
2362 2538
2363如果你希望在反向回调处理后继续编写更多其它的代码,可以使用 do 语句将不属于反向回调的代码分隔开。对于非粗箭头函数的反向回调,回调返回值的括号也是可以省略的。 2539如果你希望在反向回调处理后继续编写更多其它的代码,可以使用 do 语句将不属于反向回调的代码分隔开。对于非粗箭头函数的反向回调,回调返回值的括号也是可以省略的。
2364 2540
2365```moonscript 2541```yuescript
2366result, msg = do 2542result, msg = do
2367 data <- readAsync "文件名.txt" 2543 data <- readAsync "文件名.txt"
2368 print data 2544 print data
@@ -2371,32 +2547,36 @@ result, msg = do
2371print result, msg 2547print result, msg
2372``` 2548```
2373<YueDisplay> 2549<YueDisplay>
2374<pre> 2550
2551```yue
2375result, msg = do 2552result, msg = do
2376 data <- readAsync "文件名.txt" 2553 data <- readAsync "文件名.txt"
2377 print data 2554 print data
2378 info <- processAsync data 2555 info <- processAsync data
2379 check info 2556 check info
2380print result, msg 2557print result, msg
2381</pre> 2558```
2559
2382</YueDisplay> 2560</YueDisplay>
2383 2561
2384## 表格字面量 2562## 表格字面量
2385 2563
2386和 Lua 一样,表格可以通过花括号进行定义。 2564和 Lua 一样,表格可以通过花括号进行定义。
2387 2565
2388```moonscript 2566```yuescript
2389some_values = [1, 2, 3, 4] 2567some_values = [1, 2, 3, 4]
2390``` 2568```
2391<YueDisplay> 2569<YueDisplay>
2392<pre> 2570
2571```yue
2393some_values = [1, 2, 3, 4] 2572some_values = [1, 2, 3, 4]
2394</pre> 2573```
2574
2395</YueDisplay> 2575</YueDisplay>
2396 2576
2397但与Lua不同的是,给表格中的键赋值是用 **:**(而不是 **=**)。 2577但与Lua不同的是,给表格中的键赋值是用 **:**(而不是 **=**)。
2398 2578
2399```moonscript 2579```yuescript
2400some_values = { 2580some_values = {
2401 name: "Bill", 2581 name: "Bill",
2402 age: 200, 2582 age: 200,
@@ -2404,35 +2584,39 @@ some_values = {
2404} 2584}
2405``` 2585```
2406<YueDisplay> 2586<YueDisplay>
2407<pre> 2587
2588```yue
2408some_values = { 2589some_values = {
2409 name: "Bill", 2590 name: "Bill",
2410 age: 200, 2591 age: 200,
2411 ["favorite food"]: "rice" 2592 ["favorite food"]: "rice"
2412} 2593}
2413</pre> 2594```
2595
2414</YueDisplay> 2596</YueDisplay>
2415 2597
2416如果只分配一个键值对的表格,可以省略花括号。 2598如果只分配一个键值对的表格,可以省略花括号。
2417 2599
2418```moonscript 2600```yuescript
2419profile = 2601profile =
2420 height: "4英尺", 2602 height: "4英尺",
2421 shoe_size: 13, 2603 shoe_size: 13,
2422 favorite_foods: ["冰淇淋", "甜甜圈"] 2604 favorite_foods: ["冰淇淋", "甜甜圈"]
2423``` 2605```
2424<YueDisplay> 2606<YueDisplay>
2425<pre> 2607
2608```yue
2426profile = 2609profile =
2427 height: "4英尺", 2610 height: "4英尺",
2428 shoe_size: 13, 2611 shoe_size: 13,
2429 favorite_foods: ["冰淇淋", "甜甜圈"] 2612 favorite_foods: ["冰淇淋", "甜甜圈"]
2430</pre> 2613```
2614
2431</YueDisplay> 2615</YueDisplay>
2432 2616
2433可以使用换行符而不使用逗号(或两者都用)来分隔表格中的值: 2617可以使用换行符而不使用逗号(或两者都用)来分隔表格中的值:
2434 2618
2435```moonscript 2619```yuescript
2436values = { 2620values = {
2437 1, 2, 3, 4 2621 1, 2, 3, 4
2438 5, 6, 7, 8 2622 5, 6, 7, 8
@@ -2441,51 +2625,57 @@ values = {
2441} 2625}
2442``` 2626```
2443<YueDisplay> 2627<YueDisplay>
2444<pre> 2628
2629```yue
2445values = { 2630values = {
2446 1, 2, 3, 4 2631 1, 2, 3, 4
2447 5, 6, 7, 8 2632 5, 6, 7, 8
2448 name: "超人" 2633 name: "超人"
2449 occupation: "打击犯罪" 2634 occupation: "打击犯罪"
2450} 2635}
2451</pre> 2636```
2637
2452</YueDisplay> 2638</YueDisplay>
2453 2639
2454创建单行表格字面量时,也可以省略花括号: 2640创建单行表格字面量时,也可以省略花括号:
2455 2641
2456```moonscript 2642```yuescript
2457my_function dance: "探戈", partner: "无" 2643my_function dance: "探戈", partner: "无"
2458 2644
2459y = type: "狗", legs: 4, tails: 1 2645y = type: "狗", legs: 4, tails: 1
2460``` 2646```
2461<YueDisplay> 2647<YueDisplay>
2462<pre> 2648
2649```yue
2463my_function dance: "探戈", partner: "无" 2650my_function dance: "探戈", partner: "无"
2464 2651
2465y = type: "狗", legs: 4, tails: 1 2652y = type: "狗", legs: 4, tails: 1
2466</pre> 2653```
2654
2467</YueDisplay> 2655</YueDisplay>
2468 2656
2469表格字面量的键可以使用 Lua 语言的关键字,而无需转义: 2657表格字面量的键可以使用 Lua 语言的关键字,而无需转义:
2470 2658
2471```moonscript 2659```yuescript
2472tbl = { 2660tbl = {
2473 do: "某事" 2661 do: "某事"
2474 end: "饥饿" 2662 end: "饥饿"
2475} 2663}
2476``` 2664```
2477<YueDisplay> 2665<YueDisplay>
2478<pre> 2666
2667```yue
2479tbl = { 2668tbl = {
2480 do: "某事" 2669 do: "某事"
2481 end: "饥饿" 2670 end: "饥饿"
2482} 2671}
2483</pre> 2672```
2673
2484</YueDisplay> 2674</YueDisplay>
2485 2675
2486如果你要构造一个由变量组成的表,并希望键与变量名相同,那么可以使用 **:** 前缀操作符: 2676如果你要构造一个由变量组成的表,并希望键与变量名相同,那么可以使用 **:** 前缀操作符:
2487 2677
2488```moonscript 2678```yuescript
2489hair = "金色" 2679hair = "金色"
2490height = 200 2680height = 200
2491person = { :hair, :height, shoe_size: 40 } 2681person = { :hair, :height, shoe_size: 40 }
@@ -2493,43 +2683,49 @@ person = { :hair, :height, shoe_size: 40 }
2493print_table :hair, :height 2683print_table :hair, :height
2494``` 2684```
2495<YueDisplay> 2685<YueDisplay>
2496<pre> 2686
2687```yue
2497hair = "金色" 2688hair = "金色"
2498height = 200 2689height = 200
2499person = { :hair, :height, shoe_size: 40 } 2690person = { :hair, :height, shoe_size: 40 }
2500 2691
2501print_table :hair, :height 2692print_table :hair, :height
2502</pre> 2693```
2694
2503</YueDisplay> 2695</YueDisplay>
2504 2696
2505如果你希望表中字段的键是某个表达式的结果,那么可以用 **[ ]** 包裹它,就像在 Lua 中一样。如果键中有任何特殊字符,也可以直接使用字符串字面量作为键,省略方括号。 2697如果你希望表中字段的键是某个表达式的结果,那么可以用 **[ ]** 包裹它,就像在 Lua 中一样。如果键中有任何特殊字符,也可以直接使用字符串字面量作为键,省略方括号。
2506 2698
2507```moonscript 2699```yuescript
2508t = { 2700t = {
2509 [1 + 2]: "你好" 2701 [1 + 2]: "你好"
2510 "你好 世界": true 2702 "你好 世界": true
2511} 2703}
2512``` 2704```
2513<YueDisplay> 2705<YueDisplay>
2514<pre> 2706
2707```yue
2515t = { 2708t = {
2516 [1 + 2]: "你好" 2709 [1 + 2]: "你好"
2517 "你好 世界": true 2710 "你好 世界": true
2518} 2711}
2519</pre> 2712```
2713
2520</YueDisplay> 2714</YueDisplay>
2521 2715
2522Lua 的表同时具有数组部分和哈希部分,但有时候你会希望在书写 Lua 表时,对 Lua 表做数组和哈希不同用法的语义区分。然后你可以用 **[ ]** 而不是 **{ }** 来编写表示数组的 Lua 表,并且不允许在数组 Lua 表中写入任何键值对。 2716Lua 的表同时具有数组部分和哈希部分,但有时候你会希望在书写 Lua 表时,对 Lua 表做数组和哈希不同用法的语义区分。然后你可以用 **[ ]** 而不是 **{ }** 来编写表示数组的 Lua 表,并且不允许在数组 Lua 表中写入任何键值对。
2523 2717
2524```moonscript 2718```yuescript
2525some_values = [ 1, 2, 3, 4 ] 2719some_values = [ 1, 2, 3, 4 ]
2526list_with_one_element = [ 1, ] 2720list_with_one_element = [ 1, ]
2527``` 2721```
2528<YueDisplay> 2722<YueDisplay>
2529<pre> 2723
2724```yue
2530some_values = [ 1, 2, 3, 4 ] 2725some_values = [ 1, 2, 3, 4 ]
2531list_with_one_element = [ 1, ] 2726list_with_one_element = [ 1, ]
2532</pre> 2727```
2728
2533</YueDisplay> 2729</YueDisplay>
2534 2730
2535## 推导式 2731## 推导式
@@ -2540,42 +2736,48 @@ list_with_one_element = [ 1, ]
2540 2736
2541以下操作创建了一个 items 表的副本,但所有包含的值都翻倍了。 2737以下操作创建了一个 items 表的副本,但所有包含的值都翻倍了。
2542 2738
2543```moonscript 2739```yuescript
2544items = [1, 2, 3, 4] 2740items = [1, 2, 3, 4]
2545doubled = [item * 2 for i, item in ipairs items] 2741doubled = [item * 2 for i, item in ipairs items]
2546``` 2742```
2547<YueDisplay> 2743<YueDisplay>
2548<pre> 2744
2745```yue
2549items = [1, 2, 3, 4] 2746items = [1, 2, 3, 4]
2550doubled = [item * 2 for i, item in ipairs items] 2747doubled = [item * 2 for i, item in ipairs items]
2551</pre> 2748```
2749
2552</YueDisplay> 2750</YueDisplay>
2553 2751
2554可以使用 `when` 子句筛选新表中包含的项目: 2752可以使用 `when` 子句筛选新表中包含的项目:
2555 2753
2556```moonscript 2754```yuescript
2557slice = [item for i, item in ipairs items when i > 1 and i < 3] 2755slice = [item for i, item in ipairs items when i > 1 and i < 3]
2558``` 2756```
2559<YueDisplay> 2757<YueDisplay>
2560<pre> 2758
2759```yue
2561slice = [item for i, item in ipairs items when i > 1 and i < 3] 2760slice = [item for i, item in ipairs items when i > 1 and i < 3]
2562</pre> 2761```
2762
2563</YueDisplay> 2763</YueDisplay>
2564 2764
2565因为我们常常需要迭代数值索引表的值,所以引入了 **\*** 操作符来做语法简化。doubled 示例可以重写为: 2765因为我们常常需要迭代数值索引表的值,所以引入了 **\*** 操作符来做语法简化。doubled 示例可以重写为:
2566 2766
2567```moonscript 2767```yuescript
2568doubled = [item * 2 for item in *items] 2768doubled = [item * 2 for item in *items]
2569``` 2769```
2570<YueDisplay> 2770<YueDisplay>
2571<pre> 2771
2772```yue
2572doubled = [item * 2 for item in *items] 2773doubled = [item * 2 for item in *items]
2573</pre> 2774```
2775
2574</YueDisplay> 2776</YueDisplay>
2575 2777
2576在列表推导式中,你还可以使用展开操作符 `...` 来实现对列表嵌套层级进行扁平化的处理: 2778在列表推导式中,你还可以使用展开操作符 `...` 来实现对列表嵌套层级进行扁平化的处理:
2577 2779
2578```moonscript 2780```yuescript
2579data = 2781data =
2580 a: [1, 2, 3] 2782 a: [1, 2, 3]
2581 b: [4, 5, 6] 2783 b: [4, 5, 6]
@@ -2584,21 +2786,23 @@ flat = [...v for k,v in pairs data]
2584-- flat 现在为 [1, 2, 3, 4, 5, 6] 2786-- flat 现在为 [1, 2, 3, 4, 5, 6]
2585``` 2787```
2586<YueDisplay> 2788<YueDisplay>
2587<pre> 2789
2790```yue
2588data = 2791data =
2589 a: [1, 2, 3] 2792 a: [1, 2, 3]
2590 b: [4, 5, 6] 2793 b: [4, 5, 6]
2591 2794
2592flat = [...v for k,v in pairs data] 2795flat = [...v for k,v in pairs data]
2593-- flat 现在为 [1, 2, 3, 4, 5, 6] 2796-- flat 现在为 [1, 2, 3, 4, 5, 6]
2594</pre> 2797```
2798
2595</YueDisplay> 2799</YueDisplay>
2596 2800
2597for 和 when 子句可以根据需要进行链式操作。唯一的要求是推导式中至少要有一个 for 子句。 2801for 和 when 子句可以根据需要进行链式操作。唯一的要求是推导式中至少要有一个 for 子句。
2598 2802
2599使用多个 for 子句与使用多重循环的效果相同: 2803使用多个 for 子句与使用多重循环的效果相同:
2600 2804
2601```moonscript 2805```yuescript
2602x_coords = [4, 5, 6, 7] 2806x_coords = [4, 5, 6, 7]
2603y_coords = [9, 2, 3] 2807y_coords = [9, 2, 3]
2604 2808
@@ -2606,24 +2810,28 @@ points = [ [x, y] for x in *x_coords \
2606for y in *y_coords] 2810for y in *y_coords]
2607``` 2811```
2608<YueDisplay> 2812<YueDisplay>
2609<pre> 2813
2814```yue
2610x_coords = [4, 5, 6, 7] 2815x_coords = [4, 5, 6, 7]
2611y_coords = [9, 2, 3] 2816y_coords = [9, 2, 3]
2612 2817
2613points = [ [x, y] for x in *x_coords \ 2818points = [ [x, y] for x in *x_coords \
2614for y in *y_coords] 2819for y in *y_coords]
2615</pre> 2820```
2821
2616</YueDisplay> 2822</YueDisplay>
2617 2823
2618在推导式中也可以使用简单的数值 for 循环: 2824在推导式中也可以使用简单的数值 for 循环:
2619 2825
2620```moonscript 2826```yuescript
2621evens = [i for i = 1, 100 when i % 2 == 0] 2827evens = [i for i = 1, 100 when i % 2 == 0]
2622``` 2828```
2623<YueDisplay> 2829<YueDisplay>
2624<pre> 2830
2831```yue
2625evens = [i for i = 1, 100 when i % 2 == 0] 2832evens = [i for i = 1, 100 when i % 2 == 0]
2626</pre> 2833```
2834
2627</YueDisplay> 2835</YueDisplay>
2628 2836
2629### 表格推导式 2837### 表格推导式
@@ -2632,7 +2840,7 @@ evens = [i for i = 1, 100 when i % 2 == 0]
2632 2840
2633以下示例生成了表格 thing 的副本: 2841以下示例生成了表格 thing 的副本:
2634 2842
2635```moonscript 2843```yuescript
2636thing = { 2844thing = {
2637 color: "red" 2845 color: "red"
2638 name: "fast" 2846 name: "fast"
@@ -2642,52 +2850,60 @@ thing = {
2642thing_copy = {k, v for k, v in pairs thing} 2850thing_copy = {k, v for k, v in pairs thing}
2643``` 2851```
2644<YueDisplay> 2852<YueDisplay>
2645<pre> 2853
2854```yue
2646thing = { 2855thing = {
2647 color: "red" 2856 color: "red"
2648 name: "fast" 2857 name: "fast"
2649 width: 123 2858 width: 123
2650} 2859}
2651 2860
2652thing_copy = {k, v for k, v in pairs thing} 2861thing_copy = \{k, v for k, v in pairs thing}
2653</pre> 2862```
2863
2654</YueDisplay> 2864</YueDisplay>
2655 2865
2656```moonscript 2866```yuescript
2657no_color = {k, v for k, v in pairs thing when k != "color"} 2867no_color = {k, v for k, v in pairs thing when k != "color"}
2658``` 2868```
2659<YueDisplay> 2869<YueDisplay>
2660<pre> 2870
2661no_color = {k, v for k, v in pairs thing when k != "color"} 2871```yue
2662</pre> 2872no_color = \{k, v for k, v in pairs thing when k != "color"}
2873```
2874
2663</YueDisplay> 2875</YueDisplay>
2664 2876
2665**\*** 操作符在表格推导式中能使用。在下面的例子里,我们为几个数字创建了一个平方根查找表。 2877**\*** 操作符在表格推导式中能使用。在下面的例子里,我们为几个数字创建了一个平方根查找表。
2666 2878
2667```moonscript 2879```yuescript
2668numbers = [1, 2, 3, 4] 2880numbers = [1, 2, 3, 4]
2669sqrts = {i, math.sqrt i for i in *numbers} 2881sqrts = {i, math.sqrt i for i in *numbers}
2670``` 2882```
2671<YueDisplay> 2883<YueDisplay>
2672<pre> 2884
2885```yue
2673numbers = [1, 2, 3, 4] 2886numbers = [1, 2, 3, 4]
2674sqrts = {i, math.sqrt i for i in *numbers} 2887sqrts = \{i, math.sqrt i for i in *numbers}
2675</pre> 2888```
2889
2676</YueDisplay> 2890</YueDisplay>
2677 2891
2678表格推导式中的键值元组也可以来自单个表达式,在这种情况下,表达式在计算后应返回两个值。第一个用作键,第二个用作值: 2892表格推导式中的键值元组也可以来自单个表达式,在这种情况下,表达式在计算后应返回两个值。第一个用作键,第二个用作值:
2679 2893
2680在下面的示例中,我们将一些数组转换为一个表,其中每个数组里的第一项是键,第二项是值。 2894在下面的示例中,我们将一些数组转换为一个表,其中每个数组里的第一项是键,第二项是值。
2681 2895
2682```moonscript 2896```yuescript
2683tuples = [ ["hello", "world"], ["foo", "bar"]] 2897tuples = [ ["hello", "world"], ["foo", "bar"]]
2684tbl = {unpack tuple for tuple in *tuples} 2898tbl = {unpack tuple for tuple in *tuples}
2685``` 2899```
2686<YueDisplay> 2900<YueDisplay>
2687<pre> 2901
2902```yue
2688tuples = [ ["hello", "world"], ["foo", "bar"]] 2903tuples = [ ["hello", "world"], ["foo", "bar"]]
2689tbl = {unpack tuple for tuple in *tuples} 2904tbl = \{unpack tuple for tuple in *tuples}
2690</pre> 2905```
2906
2691</YueDisplay> 2907</YueDisplay>
2692 2908
2693### 切片 2909### 切片
@@ -2696,82 +2912,94 @@ tbl = {unpack tuple for tuple in *tuples}
2696 2912
2697下面的案例中,我们在切片中设置最小和最大边界,取索引在 1 到 5 之间(包括 1 和 5)的所有项目: 2913下面的案例中,我们在切片中设置最小和最大边界,取索引在 1 到 5 之间(包括 1 和 5)的所有项目:
2698 2914
2699```moonscript 2915```yuescript
2700slice = [item for item in *items[1, 5]] 2916slice = [item for item in *items[1, 5]]
2701``` 2917```
2702<YueDisplay> 2918<YueDisplay>
2703<pre> 2919
2920```yue
2704slice = [item for item in *items[1, 5]] 2921slice = [item for item in *items[1, 5]]
2705</pre> 2922```
2923
2706</YueDisplay> 2924</YueDisplay>
2707 2925
2708切片的任意参数都可以省略,并会使用默认值。在如下示例中,如果省略了最大索引边界,它默认为表的长度。使下面的代码取除第一个元素之外的所有元素: 2926切片的任意参数都可以省略,并会使用默认值。在如下示例中,如果省略了最大索引边界,它默认为表的长度。使下面的代码取除第一个元素之外的所有元素:
2709 2927
2710```moonscript 2928```yuescript
2711slice = [item for item in *items[2,]] 2929slice = [item for item in *items[2,]]
2712``` 2930```
2713<YueDisplay> 2931<YueDisplay>
2714<pre> 2932
2933```yue
2715slice = [item for item in *items[2,]] 2934slice = [item for item in *items[2,]]
2716</pre> 2935```
2936
2717</YueDisplay> 2937</YueDisplay>
2718 2938
2719如果省略了最小边界,便默认会设置为 1。这里我们只提供一个步长,并留下其他边界为空。这样会使得代码取出所有奇数索引的项目:(1, 3, 5, …) 2939如果省略了最小边界,便默认会设置为 1。这里我们只提供一个步长,并留下其他边界为空。这样会使得代码取出所有奇数索引的项目:(1, 3, 5, …)
2720 2940
2721```moonscript 2941```yuescript
2722slice = [item for item in *items[,,2]] 2942slice = [item for item in *items[,,2]]
2723``` 2943```
2724<YueDisplay> 2944<YueDisplay>
2725 2945
2726<pre> 2946
2947```yue
2727slice = [item for item in *items[,,2]] 2948slice = [item for item in *items[,,2]]
2728</pre> 2949```
2950
2729</YueDisplay> 2951</YueDisplay>
2730 2952
2731最小和最大边界都可以是负数,使用负数意味着边界是从表的末尾开始计算的。 2953最小和最大边界都可以是负数,使用负数意味着边界是从表的末尾开始计算的。
2732 2954
2733```moonscript 2955```yuescript
2734-- 取最后4个元素 2956-- 取最后4个元素
2735slice = [item for item in *items[-4,-1]] 2957slice = [item for item in *items[-4,-1]]
2736``` 2958```
2737<YueDisplay> 2959<YueDisplay>
2738<pre> 2960
2961```yue
2739-- 取最后4个元素 2962-- 取最后4个元素
2740slice = [item for item in *items[-4,-1]] 2963slice = [item for item in *items[-4,-1]]
2741</pre> 2964```
2965
2742</YueDisplay> 2966</YueDisplay>
2743 2967
2744切片的步长也可以是负数,这意味着元素会以相反的顺序被取出。 2968切片的步长也可以是负数,这意味着元素会以相反的顺序被取出。
2745 2969
2746```moonscript 2970```yuescript
2747reverse_slice = [item for item in *items[-1,1,-1]] 2971reverse_slice = [item for item in *items[-1,1,-1]]
2748``` 2972```
2749<YueDisplay> 2973<YueDisplay>
2750<pre> 2974
2975```yue
2751reverse_slice = [item for item in *items[-1,1,-1]] 2976reverse_slice = [item for item in *items[-1,1,-1]]
2752</pre> 2977```
2978
2753</YueDisplay> 2979</YueDisplay>
2754 2980
2755#### 切片表达式 2981#### 切片表达式
2756 2982
2757切片也可以作为表达式来使用。可以用于获取一个表包含的子列表。 2983切片也可以作为表达式来使用。可以用于获取一个表包含的子列表。
2758 2984
2759```moonscript 2985```yuescript
2760-- 取第2和第4个元素作为新的列表 2986-- 取第2和第4个元素作为新的列表
2761sub_list = items[2, 4] 2987sub_list = items[2, 4]
2762``` 2988```
2763<YueDisplay> 2989<YueDisplay>
2764<pre> 2990
2991```yue
2765-- 取第2和第4个元素作为新的列表 2992-- 取第2和第4个元素作为新的列表
2766sub_list = items[2, 4] 2993sub_list = items[2, 4]
2767</pre> 2994```
2995
2768</YueDisplay> 2996</YueDisplay>
2769 2997
2770## for 循环 2998## for 循环
2771 2999
2772Lua 中有两种 for 循环形式,数字型和通用型: 3000Lua 中有两种 for 循环形式,数字型和通用型:
2773 3001
2774```moonscript 3002```yuescript
2775for i = 10, 20 3003for i = 10, 20
2776 print i 3004 print i
2777 3005
@@ -2782,7 +3010,8 @@ for key, value in pairs object
2782 print key, value 3010 print key, value
2783``` 3011```
2784<YueDisplay> 3012<YueDisplay>
2785<pre> 3013
3014```yue
2786for i = 10, 20 3015for i = 10, 20
2787 print i 3016 print i
2788 3017
@@ -2791,42 +3020,47 @@ for k = 1, 15, 2 -- 提供了一个遍历的步长
2791 3020
2792for key, value in pairs object 3021for key, value in pairs object
2793 print key, value 3022 print key, value
2794</pre> 3023```
3024
2795</YueDisplay> 3025</YueDisplay>
2796 3026
2797可以使用切片和 **\*** 操作符,就像在列表推导中一样: 3027可以使用切片和 **\*** 操作符,就像在列表推导中一样:
2798 3028
2799```moonscript 3029```yuescript
2800for item in *items[2, 4] 3030for item in *items[2, 4]
2801 print item 3031 print item
2802``` 3032```
2803<YueDisplay> 3033<YueDisplay>
2804<pre> 3034
3035```yue
2805for item in *items[2, 4] 3036for item in *items[2, 4]
2806 print item 3037 print item
2807</pre> 3038```
3039
2808</YueDisplay> 3040</YueDisplay>
2809 3041
2810当代码语句只有一行时,循环语句也都可以写作更短的语法: 3042当代码语句只有一行时,循环语句也都可以写作更短的语法:
2811 3043
2812```moonscript 3044```yuescript
2813for item in *items do print item 3045for item in *items do print item
2814 3046
2815for j = 1, 10, 3 do print j 3047for j = 1, 10, 3 do print j
2816``` 3048```
2817<YueDisplay> 3049<YueDisplay>
2818<pre> 3050
3051```yue
2819for item in *items do print item 3052for item in *items do print item
2820 3053
2821for j = 1, 10, 3 do print j 3054for j = 1, 10, 3 do print j
2822</pre> 3055```
3056
2823</YueDisplay> 3057</YueDisplay>
2824 3058
2825for 循环也可以用作表达式。for 循环主体中的最后一条语句会被强制转换为一个返回值的表达式,并会将表达式计算结果的值追加到一个作为结果的数组表中。 3059for 循环也可以用作表达式。for 循环主体中的最后一条语句会被强制转换为一个返回值的表达式,并会将表达式计算结果的值追加到一个作为结果的数组表中。
2826 3060
2827将每个偶数加倍: 3061将每个偶数加倍:
2828 3062
2829```moonscript 3063```yuescript
2830doubled_evens = for i = 1, 20 3064doubled_evens = for i = 1, 20
2831 if i % 2 == 0 3065 if i % 2 == 0
2832 i * 2 3066 i * 2
@@ -2834,35 +3068,39 @@ doubled_evens = for i = 1, 20
2834 i 3068 i
2835``` 3069```
2836<YueDisplay> 3070<YueDisplay>
2837<pre> 3071
3072```yue
2838doubled_evens = for i = 1, 20 3073doubled_evens = for i = 1, 20
2839 if i % 2 == 0 3074 if i % 2 == 0
2840 i * 2 3075 i * 2
2841 else 3076 else
2842 i 3077 i
2843</pre> 3078```
3079
2844</YueDisplay> 3080</YueDisplay>
2845 3081
2846此外,for 循环还支持带返回值的 break 语句,这样循环本身就可以作为一个表达式,在满足条件时提前退出并返回有意义的结果。 3082此外,for 循环还支持带返回值的 break 语句,这样循环本身就可以作为一个表达式,在满足条件时提前退出并返回有意义的结果。
2847 3083
2848例如,查找第一个大于 10 的数字: 3084例如,查找第一个大于 10 的数字:
2849 3085
2850```moonscript 3086```yuescript
2851first_large = for n in *numbers 3087first_large = for n in *numbers
2852 break n if n > 10 3088 break n if n > 10
2853``` 3089```
2854<YueDisplay> 3090<YueDisplay>
2855<pre> 3091
3092```yue
2856first_large = for n in *numbers 3093first_large = for n in *numbers
2857 break n if n > 10 3094 break n if n > 10
2858</pre> 3095```
3096
2859</YueDisplay> 3097</YueDisplay>
2860 3098
2861你还可以结合 for 循环表达式与 continue 语句来过滤值。 3099你还可以结合 for 循环表达式与 continue 语句来过滤值。
2862 3100
2863注意出现在函数体末尾的 for 循环,不会被当作是一个表达式并将循环结果累积到一个列表中作为返回值(相反,函数将返回 nil)。如果要函数末尾的循环转换为列表表达式,可以显式地使用返回语句加 for 循环表达式。 3101注意出现在函数体末尾的 for 循环,不会被当作是一个表达式并将循环结果累积到一个列表中作为返回值(相反,函数将返回 nil)。如果要函数末尾的循环转换为列表表达式,可以显式地使用返回语句加 for 循环表达式。
2864 3102
2865```moonscript 3103```yuescript
2866func_a = -> for i = 1, 10 do print i 3104func_a = -> for i = 1, 10 do print i
2867func_b = -> return for i = 1, 10 do i 3105func_b = -> return for i = 1, 10 do i
2868 3106
@@ -2870,13 +3108,15 @@ print func_a! -- 打印 nil
2870print func_b! -- 打印 table 对象 3108print func_b! -- 打印 table 对象
2871``` 3109```
2872<YueDisplay> 3110<YueDisplay>
2873<pre> 3111
3112```yue
2874func_a = -> for i = 1, 10 do print i 3113func_a = -> for i = 1, 10 do print i
2875func_b = -> return for i = 1, 10 do i 3114func_b = -> return for i = 1, 10 do i
2876 3115
2877print func_a! -- 打印 nil 3116print func_a! -- 打印 nil
2878print func_b! -- 打印 table 对象 3117print func_b! -- 打印 table 对象
2879</pre> 3118```
3119
2880</YueDisplay> 3120</YueDisplay>
2881 3121
2882这样做是为了避免在不需要返回循环结果的函数,创建无效的返回值表格。 3122这样做是为了避免在不需要返回循环结果的函数,创建无效的返回值表格。
@@ -2885,7 +3125,7 @@ print func_b! -- 打印 table 对象
2885 3125
2886repeat 循环是从 Lua 语言中搬过来的相似语法: 3126repeat 循环是从 Lua 语言中搬过来的相似语法:
2887 3127
2888```moonscript 3128```yuescript
2889i = 10 3129i = 10
2890repeat 3130repeat
2891 print i 3131 print i
@@ -2893,20 +3133,22 @@ repeat
2893until i == 0 3133until i == 0
2894``` 3134```
2895<YueDisplay> 3135<YueDisplay>
2896<pre> 3136
3137```yue
2897i = 10 3138i = 10
2898repeat 3139repeat
2899 print i 3140 print i
2900 i -= 1 3141 i -= 1
2901until i == 0 3142until i == 0
2902</pre> 3143```
3144
2903</YueDisplay> 3145</YueDisplay>
2904 3146
2905## while 循环 3147## while 循环
2906 3148
2907在月之脚本中的 while 循环有四种写法: 3149在月之脚本中的 while 循环有四种写法:
2908 3150
2909```moonscript 3151```yuescript
2910i = 10 3152i = 10
2911while i > 0 3153while i > 0
2912 print i 3154 print i
@@ -2915,17 +3157,19 @@ while i > 0
2915while running == true do my_function! 3157while running == true do my_function!
2916``` 3158```
2917<YueDisplay> 3159<YueDisplay>
2918<pre> 3160
3161```yue
2919i = 10 3162i = 10
2920while i > 0 3163while i > 0
2921 print i 3164 print i
2922 i -= 1 3165 i -= 1
2923 3166
2924while running == true do my_function! 3167while running == true do my_function!
2925</pre> 3168```
3169
2926</YueDisplay> 3170</YueDisplay>
2927 3171
2928```moonscript 3172```yuescript
2929i = 10 3173i = 10
2930until i == 0 3174until i == 0
2931 print i 3175 print i
@@ -2934,13 +3178,15 @@ until i == 0
2934until running == false do my_function! 3178until running == false do my_function!
2935``` 3179```
2936<YueDisplay> 3180<YueDisplay>
2937<pre> 3181
3182```yue
2938i = 10 3183i = 10
2939until i == 0 3184until i == 0
2940 print i 3185 print i
2941 i -= 1 3186 i -= 1
2942until running == false do my_function! 3187until running == false do my_function!
2943</pre> 3188```
3189
2944</YueDisplay> 3190</YueDisplay>
2945 3191
2946像 for 循环的语法一样,while 循环也可以作为一个表达式使用。为了使函数返回 while 循环的累积列表值,必须明确使用返回语句返回 while 循环表达式。 3192像 for 循环的语法一样,while 循环也可以作为一个表达式使用。为了使函数返回 while 循环的累积列表值,必须明确使用返回语句返回 while 循环表达式。
@@ -2949,7 +3195,7 @@ until running == false do my_function!
2949 3195
2950继续语句可以用来跳出当前的循环迭代。 3196继续语句可以用来跳出当前的循环迭代。
2951 3197
2952```moonscript 3198```yuescript
2953i = 0 3199i = 0
2954while i < 10 3200while i < 10
2955 i += 1 3201 i += 1
@@ -2957,35 +3203,39 @@ while i < 10
2957 print i 3203 print i
2958``` 3204```
2959<YueDisplay> 3205<YueDisplay>
2960<pre> 3206
3207```yue
2961i = 0 3208i = 0
2962while i < 10 3209while i < 10
2963 i += 1 3210 i += 1
2964 continue if i % 2 == 0 3211 continue if i % 2 == 0
2965 print i 3212 print i
2966</pre> 3213```
3214
2967</YueDisplay> 3215</YueDisplay>
2968 3216
2969继续语句也可以与各种循环表达式一起使用,以防止当前的循环迭代结果累积到结果列表中。以下示例将数组表过滤为仅包含偶数的数组: 3217继续语句也可以与各种循环表达式一起使用,以防止当前的循环迭代结果累积到结果列表中。以下示例将数组表过滤为仅包含偶数的数组:
2970 3218
2971```moonscript 3219```yuescript
2972my_numbers = [1, 2, 3, 4, 5, 6] 3220my_numbers = [1, 2, 3, 4, 5, 6]
2973odds = for x in *my_numbers 3221odds = for x in *my_numbers
2974 continue if x % 2 == 1 3222 continue if x % 2 == 1
2975 x 3223 x
2976``` 3224```
2977<YueDisplay> 3225<YueDisplay>
2978<pre> 3226
3227```yue
2979my_numbers = [1, 2, 3, 4, 5, 6] 3228my_numbers = [1, 2, 3, 4, 5, 6]
2980odds = for x in *my_numbers 3229odds = for x in *my_numbers
2981 continue if x % 2 == 1 3230 continue if x % 2 == 1
2982 x 3231 x
2983</pre> 3232```
3233
2984</YueDisplay> 3234</YueDisplay>
2985 3235
2986## 条件语句 3236## 条件语句
2987 3237
2988```moonscript 3238```yuescript
2989have_coins = false 3239have_coins = false
2990if have_coins 3240if have_coins
2991 print "有硬币" 3241 print "有硬币"
@@ -2993,44 +3243,50 @@ else
2993 print "没有硬币" 3243 print "没有硬币"
2994``` 3244```
2995<YueDisplay> 3245<YueDisplay>
2996<pre> 3246
3247```yue
2997have_coins = false 3248have_coins = false
2998if have_coins 3249if have_coins
2999 print "有硬币" 3250 print "有硬币"
3000else 3251else
3001 print "没有硬币" 3252 print "没有硬币"
3002</pre> 3253```
3254
3003</YueDisplay> 3255</YueDisplay>
3004 3256
3005对于简单的语句,也可以使用简短的语法: 3257对于简单的语句,也可以使用简短的语法:
3006 3258
3007```moonscript 3259```yuescript
3008have_coins = false 3260have_coins = false
3009if have_coins then print "有硬币" else print "没有硬币" 3261if have_coins then print "有硬币" else print "没有硬币"
3010``` 3262```
3011<YueDisplay> 3263<YueDisplay>
3012<pre> 3264
3265```yue
3013have_coins = false 3266have_coins = false
3014if have_coins then print "有硬币" else print "没有硬币" 3267if have_coins then print "有硬币" else print "没有硬币"
3015</pre> 3268```
3269
3016</YueDisplay> 3270</YueDisplay>
3017 3271
3018因为if语句可以用作表达式,所以也可以这样写: 3272因为if语句可以用作表达式,所以也可以这样写:
3019 3273
3020```moonscript 3274```yuescript
3021have_coins = false 3275have_coins = false
3022print if have_coins then "有硬币" else "没有硬币" 3276print if have_coins then "有硬币" else "没有硬币"
3023``` 3277```
3024<YueDisplay> 3278<YueDisplay>
3025<pre> 3279
3280```yue
3026have_coins = false 3281have_coins = false
3027print if have_coins then "有硬币" else "没有硬币" 3282print if have_coins then "有硬币" else "没有硬币"
3028</pre> 3283```
3284
3029</YueDisplay> 3285</YueDisplay>
3030 3286
3031条件语句也可以作为表达式用在返回语句和赋值语句中: 3287条件语句也可以作为表达式用在返回语句和赋值语句中:
3032 3288
3033```moonscript 3289```yuescript
3034is_tall = (name) -> 3290is_tall = (name) ->
3035 if name == "Rob" 3291 if name == "Rob"
3036 true 3292 true
@@ -3045,7 +3301,8 @@ else
3045print message -- 打印: 我很高 3301print message -- 打印: 我很高
3046``` 3302```
3047<YueDisplay> 3303<YueDisplay>
3048<pre> 3304
3305```yue
3049is_tall = (name) -> 3306is_tall = (name) ->
3050 if name == "Rob" 3307 if name == "Rob"
3051 true 3308 true
@@ -3058,37 +3315,42 @@ else
3058 "我不是很高" 3315 "我不是很高"
3059 3316
3060print message -- 打印: 我很高 3317print message -- 打印: 我很高
3061</pre> 3318```
3319
3062</YueDisplay> 3320</YueDisplay>
3063 3321
3064if 的反义词是 unless(相当于 if not,正如“如果”对应“除非”): 3322if 的反义词是 unless(相当于 if not,正如“如果”对应“除非”):
3065 3323
3066```moonscript 3324```yuescript
3067unless os.date("%A") == "Monday" 3325unless os.date("%A") == "Monday"
3068 print "今天不是星期一!" 3326 print "今天不是星期一!"
3069``` 3327```
3070<YueDisplay> 3328<YueDisplay>
3071 3329
3072<pre> 3330
3331```yue
3073unless os.date("%A") == "Monday" 3332unless os.date("%A") == "Monday"
3074 print "今天不是星期一!" 3333 print "今天不是星期一!"
3075</pre> 3334```
3335
3076</YueDisplay> 3336</YueDisplay>
3077 3337
3078```moonscript 3338```yuescript
3079print "你真幸运!" unless math.random! > 0.1 3339print "你真幸运!" unless math.random! > 0.1
3080``` 3340```
3081<YueDisplay> 3341<YueDisplay>
3082<pre> 3342
3343```yue
3083print "你真幸运!" unless math.random! > 0.1 3344print "你真幸运!" unless math.random! > 0.1
3084</pre> 3345```
3346
3085</YueDisplay> 3347</YueDisplay>
3086 3348
3087### 范围表达式 3349### 范围表达式
3088 3350
3089你可以使用范围表达式来编写进行范围检查的代码。 3351你可以使用范围表达式来编写进行范围检查的代码。
3090 3352
3091```moonscript 3353```yuescript
3092a = 5 3354a = 5
3093 3355
3094if a in [1, 3, 5, 7] 3356if a in [1, 3, 5, 7]
@@ -3098,7 +3360,8 @@ if a in list
3098 print "检查`a`是否在列表中" 3360 print "检查`a`是否在列表中"
3099``` 3361```
3100<YueDisplay> 3362<YueDisplay>
3101<pre> 3363
3364```yue
3102a = 5 3365a = 5
3103 3366
3104if a in [1, 3, 5, 7] 3367if a in [1, 3, 5, 7]
@@ -3106,62 +3369,71 @@ if a in [1, 3, 5, 7]
3106 3369
3107if a in list 3370if a in list
3108 print "检查`a`是否在列表中" 3371 print "检查`a`是否在列表中"
3109</pre> 3372```
3373
3110</YueDisplay> 3374</YueDisplay>
3111 3375
3112```moonscript 3376```yuescript
3113print "你很幸运!" unless math.random! > 0.1 3377print "你很幸运!" unless math.random! > 0.1
3114``` 3378```
3115<YueDisplay> 3379<YueDisplay>
3116<pre> 3380
3381```yue
3117print "你很幸运!" unless math.random! > 0.1 3382print "你很幸运!" unless math.random! > 0.1
3118</pre> 3383```
3384
3119</YueDisplay> 3385</YueDisplay>
3120 3386
3121## 代码行修饰符 3387## 代码行修饰符
3122 3388
3123为了方便编写代码,循环语句和 if 语句可以应用于单行代码语句的末尾: 3389为了方便编写代码,循环语句和 if 语句可以应用于单行代码语句的末尾:
3124 3390
3125```moonscript 3391```yuescript
3126print "你好,世界" if name == "Rob" 3392print "你好,世界" if name == "Rob"
3127``` 3393```
3128<YueDisplay> 3394<YueDisplay>
3129<pre> 3395
3396```yue
3130print "你好,世界" if name == "Rob" 3397print "你好,世界" if name == "Rob"
3131</pre> 3398```
3399
3132</YueDisplay> 3400</YueDisplay>
3133 3401
3134修饰 for 循环的示例: 3402修饰 for 循环的示例:
3135 3403
3136```moonscript 3404```yuescript
3137print "项目: ", item for item in *items 3405print "项目: ", item for item in *items
3138``` 3406```
3139<YueDisplay> 3407<YueDisplay>
3140<pre> 3408
3409```yue
3141print "项目: ", item for item in *items 3410print "项目: ", item for item in *items
3142</pre> 3411```
3412
3143</YueDisplay> 3413</YueDisplay>
3144 3414
3145修饰 while 循环的示例: 3415修饰 while 循环的示例:
3146 3416
3147```moonscript 3417```yuescript
3148game\update! while game\isRunning! 3418game\update! while game\isRunning!
3149 3419
3150reader\parse_line! until reader\eof! 3420reader\parse_line! until reader\eof!
3151``` 3421```
3152<YueDisplay> 3422<YueDisplay>
3153<pre> 3423
3424```yue
3154game\update! while game\isRunning! 3425game\update! while game\isRunning!
3155 3426
3156reader\parse_line! until reader\eof! 3427reader\parse_line! until reader\eof!
3157</pre> 3428```
3429
3158</YueDisplay> 3430</YueDisplay>
3159 3431
3160## switch 语句 3432## switch 语句
3161 3433
3162switch 语句是为了简化检查一系列相同值的if语句而提供的简写语法。要注意用于比较检查的目标值只会计算一次。和 if 语句一样,switch 语句在最后可以接一个 else 代码块来处理没有匹配的情况。在生成的 Lua 代码中,进行比较是使用 == 操作符完成的。switch 语句中也可以使用赋值表达式来储存临时变量值。 3434switch 语句是为了简化检查一系列相同值的if语句而提供的简写语法。要注意用于比较检查的目标值只会计算一次。和 if 语句一样,switch 语句在最后可以接一个 else 代码块来处理没有匹配的情况。在生成的 Lua 代码中,进行比较是使用 == 操作符完成的。switch 语句中也可以使用赋值表达式来储存临时变量值。
3163 3435
3164```moonscript 3436```yuescript
3165switch name := "Dan" 3437switch name := "Dan"
3166 when "Robert" 3438 when "Robert"
3167 print "你是Robert" 3439 print "你是Robert"
@@ -3171,7 +3443,8 @@ switch name := "Dan"
3171 print "我不认识你,你的名字是#{name}" 3443 print "我不认识你,你的名字是#{name}"
3172``` 3444```
3173<YueDisplay> 3445<YueDisplay>
3174<pre> 3446
3447```yue
3175switch name := "Dan" 3448switch name := "Dan"
3176 when "Robert" 3449 when "Robert"
3177 print "你是Robert" 3450 print "你是Robert"
@@ -3179,14 +3452,15 @@ switch name := "Dan"
3179 print "你的名字是Dan" 3452 print "你的名字是Dan"
3180 else 3453 else
3181 print "我不认识你,你的名字是#{name}" 3454 print "我不认识你,你的名字是#{name}"
3182</pre> 3455```
3456
3183</YueDisplay> 3457</YueDisplay>
3184 3458
3185switch 语句的 when 子句中可以通过使用逗号分隔的列表来匹配多个值。 3459switch 语句的 when 子句中可以通过使用逗号分隔的列表来匹配多个值。
3186 3460
3187switch 语句也可以作为表达式使用,下面我们可以将 switch 语句返回的结果分配给一个变量: 3461switch 语句也可以作为表达式使用,下面我们可以将 switch 语句返回的结果分配给一个变量:
3188 3462
3189```moonscript 3463```yuescript
3190b = 1 3464b = 1
3191next_number = switch b 3465next_number = switch b
3192 when 1 3466 when 1
@@ -3197,7 +3471,8 @@ next_number = switch b
3197 error "数字数得太大了!" 3471 error "数字数得太大了!"
3198``` 3472```
3199<YueDisplay> 3473<YueDisplay>
3200<pre> 3474
3475```yue
3201b = 1 3476b = 1
3202next_number = switch b 3477next_number = switch b
3203 when 1 3478 when 1
@@ -3206,29 +3481,32 @@ next_number = switch b
3206 3 3481 3
3207 else 3482 else
3208 error "数字数得太大了!" 3483 error "数字数得太大了!"
3209</pre> 3484```
3485
3210</YueDisplay> 3486</YueDisplay>
3211 3487
3212我们可以使用 then 关键字在 when 子句的同一行上编写处理代码。else 代码块的后续代码中要写在同一行上不需要额外的关键字。 3488我们可以使用 then 关键字在 when 子句的同一行上编写处理代码。else 代码块的后续代码中要写在同一行上不需要额外的关键字。
3213 3489
3214```moonscript 3490```yuescript
3215msg = switch math.random(1, 5) 3491msg = switch math.random(1, 5)
3216 when 1 then "你很幸运" 3492 when 1 then "你很幸运"
3217 when 2 then "你差点很幸运" 3493 when 2 then "你差点很幸运"
3218 else "不太幸运" 3494 else "不太幸运"
3219``` 3495```
3220<YueDisplay> 3496<YueDisplay>
3221<pre> 3497
3498```yue
3222msg = switch math.random(1, 5) 3499msg = switch math.random(1, 5)
3223 when 1 then "你很幸运" 3500 when 1 then "你很幸运"
3224 when 2 then "你差点很幸运" 3501 when 2 then "你差点很幸运"
3225 else "不太幸运" 3502 else "不太幸运"
3226</pre> 3503```
3504
3227</YueDisplay> 3505</YueDisplay>
3228 3506
3229如果在编写 switch 语句时希望少写一个缩进,那么你可以把第一个 when 子句放在 switch 开始语句的第一行,然后后续的子语句就都可以都少写一个缩进。 3507如果在编写 switch 语句时希望少写一个缩进,那么你可以把第一个 when 子句放在 switch 开始语句的第一行,然后后续的子语句就都可以都少写一个缩进。
3230 3508
3231```moonscript 3509```yuescript
3232switch math.random(1, 5) 3510switch math.random(1, 5)
3233 when 1 3511 when 1
3234 print "你很幸运" -- 两个缩进级别 3512 print "你很幸运" -- 两个缩进级别
@@ -3241,7 +3519,8 @@ else
3241 print "不太幸运" 3519 print "不太幸运"
3242``` 3520```
3243<YueDisplay> 3521<YueDisplay>
3244<pre> 3522
3523```yue
3245switch math.random(1, 5) 3524switch math.random(1, 5)
3246 when 1 3525 when 1
3247 print "你很幸运" -- 两个缩进级别 3526 print "你很幸运" -- 两个缩进级别
@@ -3252,7 +3531,8 @@ switch math.random(1, 5) when 1
3252 print "你很幸运" -- 一个缩进级别 3531 print "你很幸运" -- 一个缩进级别
3253else 3532else
3254 print "不太幸运" 3533 print "不太幸运"
3255</pre> 3534```
3535
3256</YueDisplay> 3536</YueDisplay>
3257 3537
3258值得注意的是,在生成 Lua 代码时,我们要做检查的目标变量会放在 == 表达式的右侧。当你希望给 when 子句的比较对象定义一个 \_\_eq 元方法来重载判断逻辑时,可能会有用。 3538值得注意的是,在生成 Lua 代码时,我们要做检查的目标变量会放在 == 表达式的右侧。当你希望给 when 子句的比较对象定义一个 \_\_eq 元方法来重载判断逻辑时,可能会有用。
@@ -3261,7 +3541,7 @@ else
3261 3541
3262在 switch 的 when 子句中,如果期待检查目标是一个表格,且可以通过特定的结构进行解构并获得非 nil 值,那么你可以尝试使用表格匹配的语法。 3542在 switch 的 when 子句中,如果期待检查目标是一个表格,且可以通过特定的结构进行解构并获得非 nil 值,那么你可以尝试使用表格匹配的语法。
3263 3543
3264```moonscript 3544```yuescript
3265items = 3545items =
3266 * x: 100 3546 * x: 100
3267 y: 200 3547 y: 200
@@ -3276,7 +3556,8 @@ for item in *items
3276 print "尺寸 #{width}, #{height}" 3556 print "尺寸 #{width}, #{height}"
3277``` 3557```
3278<YueDisplay> 3558<YueDisplay>
3279<pre> 3559
3560```yue
3280items = 3561items =
3281 * x: 100 3562 * x: 100
3282 y: 200 3563 y: 200
@@ -3289,12 +3570,13 @@ for item in *items
3289 print "Vec2 #{x}, #{y}" 3570 print "Vec2 #{x}, #{y}"
3290 when :width, :height 3571 when :width, :height
3291 print "尺寸 #{width}, #{height}" 3572 print "尺寸 #{width}, #{height}"
3292</pre> 3573```
3574
3293</YueDisplay> 3575</YueDisplay>
3294 3576
3295你可以使用默认值来选择性地解构表格的某些字段。 3577你可以使用默认值来选择性地解构表格的某些字段。
3296 3578
3297```moonscript 3579```yuescript
3298item = {} 3580item = {}
3299 3581
3300{pos: {:x = 50, :y = 200}} = item -- 获取错误:尝试索引nil值(字段'pos') 3582{pos: {:x = 50, :y = 200}} = item -- 获取错误:尝试索引nil值(字段'pos')
@@ -3304,22 +3586,24 @@ switch item
3304 print "Vec2 #{x}, #{y}" -- 表格解构仍然会通过 3586 print "Vec2 #{x}, #{y}" -- 表格解构仍然会通过
3305``` 3587```
3306<YueDisplay> 3588<YueDisplay>
3307<pre> 3589
3308item = {} 3590```yue
3591item = \{}
3309 3592
3310{pos: {:x = 50, :y = 200}} = item -- 获取错误:尝试索引nil值(字段'pos') 3593{pos: {:x = 50, :y = 200}} = item -- 获取错误:尝试索引nil值(字段'pos')
3311 3594
3312switch item 3595switch item
3313 when {pos: {:x = 50, :y = 200}} 3596 when {pos: {:x = 50, :y = 200}}
3314 print "Vec2 #{x}, #{y}" -- 表格解构仍然会通过 3597 print "Vec2 #{x}, #{y}" -- 表格解构仍然会通过
3315</pre> 3598```
3599
3316</YueDisplay> 3600</YueDisplay>
3317 3601
3318你也可以匹配数组元素、表格字段,甚至使用数组或表格字面量来匹配嵌套的结构。 3602你也可以匹配数组元素、表格字段,甚至使用数组或表格字面量来匹配嵌套的结构。
3319 3603
3320匹配数组元素。 3604匹配数组元素。
3321 3605
3322```moonscript 3606```yuescript
3323switch tb 3607switch tb
3324 when [1, 2, 3] 3608 when [1, 2, 3]
3325 print "1, 2, 3" 3609 print "1, 2, 3"
@@ -3329,7 +3613,8 @@ switch tb
3329 print "1, 2, #{b}" 3613 print "1, 2, #{b}"
3330``` 3614```
3331<YueDisplay> 3615<YueDisplay>
3332<pre> 3616
3617```yue
3333switch tb 3618switch tb
3334 when [1, 2, 3] 3619 when [1, 2, 3]
3335 print "1, 2, 3" 3620 print "1, 2, 3"
@@ -3337,12 +3622,13 @@ switch tb
3337 print "1, #{b}, 3" 3622 print "1, #{b}, 3"
3338 when [1, 2, b = 3] -- 变量b有默认值 3623 when [1, 2, b = 3] -- 变量b有默认值
3339 print "1, 2, #{b}" 3624 print "1, 2, #{b}"
3340</pre> 3625```
3626
3341</YueDisplay> 3627</YueDisplay>
3342 3628
3343匹配表格字段。 3629匹配表格字段。
3344 3630
3345```moonscript 3631```yuescript
3346switch tb 3632switch tb
3347 when success: true, :result 3633 when success: true, :result
3348 print "成功", result 3634 print "成功", result
@@ -3352,7 +3638,8 @@ switch tb
3352 print "无效值" 3638 print "无效值"
3353``` 3639```
3354<YueDisplay> 3640<YueDisplay>
3355<pre> 3641
3642```yue
3356switch tb 3643switch tb
3357 when success: true, :result 3644 when success: true, :result
3358 print "成功", result 3645 print "成功", result
@@ -3360,12 +3647,13 @@ switch tb
3360 print "失败", result 3647 print "失败", result
3361 else 3648 else
3362 print "无效值" 3649 print "无效值"
3363</pre> 3650```
3651
3364</YueDisplay> 3652</YueDisplay>
3365 3653
3366匹配嵌套的表格结构。 3654匹配嵌套的表格结构。
3367 3655
3368```moonscript 3656```yuescript
3369switch tb 3657switch tb
3370 when data: {type: "success", :content} 3658 when data: {type: "success", :content}
3371 print "成功", content 3659 print "成功", content
@@ -3375,7 +3663,8 @@ switch tb
3375 print "无效值" 3663 print "无效值"
3376``` 3664```
3377<YueDisplay> 3665<YueDisplay>
3378<pre> 3666
3667```yue
3379switch tb 3668switch tb
3380 when data: {type: "success", :content} 3669 when data: {type: "success", :content}
3381 print "成功", content 3670 print "成功", content
@@ -3383,12 +3672,13 @@ switch tb
3383 print "失败", content 3672 print "失败", content
3384 else 3673 else
3385 print "无效值" 3674 print "无效值"
3386</pre> 3675```
3676
3387</YueDisplay> 3677</YueDisplay>
3388 3678
3389匹配表格数组。 3679匹配表格数组。
3390 3680
3391```moonscript 3681```yuescript
3392switch tb 3682switch tb
3393 when [ 3683 when [
3394 {a: 1, b: 2} 3684 {a: 1, b: 2}
@@ -3399,7 +3689,8 @@ switch tb
3399 print "匹配成功", fourth 3689 print "匹配成功", fourth
3400``` 3690```
3401<YueDisplay> 3691<YueDisplay>
3402<pre> 3692
3693```yue
3403switch tb 3694switch tb
3404 when [ 3695 when [
3405 {a: 1, b: 2} 3696 {a: 1, b: 2}
@@ -3408,12 +3699,13 @@ switch tb
3408 fourth 3699 fourth
3409 ] 3700 ]
3410 print "匹配成功", fourth 3701 print "匹配成功", fourth
3411</pre> 3702```
3703
3412</YueDisplay> 3704</YueDisplay>
3413 3705
3414匹配一个列表并捕获特定范围内的元素。 3706匹配一个列表并捕获特定范围内的元素。
3415 3707
3416```moonscript 3708```yuescript
3417segments = ["admin", "users", "logs", "view"] 3709segments = ["admin", "users", "logs", "view"]
3418switch segments 3710switch segments
3419 when [...groups, resource, action] 3711 when [...groups, resource, action]
@@ -3422,14 +3714,16 @@ switch segments
3422 print "Action:", action -- 打印: "view" 3714 print "Action:", action -- 打印: "view"
3423``` 3715```
3424<YueDisplay> 3716<YueDisplay>
3425<pre> 3717
3718```yue
3426segments = ["admin", "users", "logs", "view"] 3719segments = ["admin", "users", "logs", "view"]
3427switch segments 3720switch segments
3428 when [...groups, resource, action] 3721 when [...groups, resource, action]
3429 print "Group:", groups -- 打印: {"admin", "users"} 3722 print "Group:", groups -- 打印: {"admin", "users"}
3430 print "Resource:", resource -- 打印: "logs" 3723 print "Resource:", resource -- 打印: "logs"
3431 print "Action:", action -- 打印: "view" 3724 print "Action:", action -- 打印: "view"
3432</pre> 3725```
3726
3433</YueDisplay> 3727</YueDisplay>
3434 3728
3435## 面向对象编程 3729## 面向对象编程
@@ -3438,7 +3732,7 @@ switch segments
3438 3732
3439一个简单的类: 3733一个简单的类:
3440 3734
3441```moonscript 3735```yuescript
3442class Inventory 3736class Inventory
3443 new: => 3737 new: =>
3444 @items = {} 3738 @items = {}
@@ -3450,17 +3744,19 @@ class Inventory
3450 @items[name] = 1 3744 @items[name] = 1
3451``` 3745```
3452<YueDisplay> 3746<YueDisplay>
3453<pre> 3747
3748```yue
3454class Inventory 3749class Inventory
3455 new: => 3750 new: =>
3456 @items = {} 3751 @items = \{}
3457 3752
3458 add_item: (name) => 3753 add_item: (name) =>
3459 if @items[name] 3754 if @items[name]
3460 @items[name] += 1 3755 @items[name] += 1
3461 else 3756 else
3462 @items[name] = 1 3757 @items[name] = 1
3463</pre> 3758```
3759
3464</YueDisplay> 3760</YueDisplay>
3465 3761
3466在月之脚本中采用面向对象的编程方式时,通常会使用类声明语句结合 Lua 表格字面量来做类定义。这个类的定义包含了它的所有方法和属性。在这种结构中,键名为 “new” 的成员扮演了一个重要的角色,是作为构造函数来使用。 3762在月之脚本中采用面向对象的编程方式时,通常会使用类声明语句结合 Lua 表格字面量来做类定义。这个类的定义包含了它的所有方法和属性。在这种结构中,键名为 “new” 的成员扮演了一个重要的角色,是作为构造函数来使用。
@@ -3471,18 +3767,20 @@ class Inventory
3471 3767
3472为了创建类的一个新实例,可以将类名当作一个函数来调用,这样就可以生成并返回一个新的实例。 3768为了创建类的一个新实例,可以将类名当作一个函数来调用,这样就可以生成并返回一个新的实例。
3473 3769
3474```moonscript 3770```yuescript
3475inv = Inventory! 3771inv = Inventory!
3476inv\add_item "t-shirt" 3772inv\add_item "t-shirt"
3477inv\add_item "pants" 3773inv\add_item "pants"
3478``` 3774```
3479<YueDisplay> 3775<YueDisplay>
3480 3776
3481<pre> 3777
3778```yue
3482inv = Inventory! 3779inv = Inventory!
3483inv\add_item "t-shirt" 3780inv\add_item "t-shirt"
3484inv\add_item "pants" 3781inv\add_item "pants"
3485</pre> 3782```
3783
3486</YueDisplay> 3784</YueDisplay>
3487 3785
3488在月之脚本的类中,由于需要将类的实例作为参数传入到调用的方法中,因此使用了 **\\** 操作符做类的成员函数调用。 3786在月之脚本的类中,由于需要将类的实例作为参数传入到调用的方法中,因此使用了 **\\** 操作符做类的成员函数调用。
@@ -3491,7 +3789,7 @@ inv\add_item "pants"
3491 3789
3492例如,在下面的示例中,clothes 属性在所有实例之间共享。因此,对这个属性在一个实例中的修改,将会影响到其他所有实例。 3790例如,在下面的示例中,clothes 属性在所有实例之间共享。因此,对这个属性在一个实例中的修改,将会影响到其他所有实例。
3493 3791
3494```moonscript 3792```yuescript
3495class Person 3793class Person
3496 clothes: [] 3794 clothes: []
3497 give_item: (name) => 3795 give_item: (name) =>
@@ -3507,7 +3805,8 @@ b\give_item "shirt"
3507print item for item in *a.clothes 3805print item for item in *a.clothes
3508``` 3806```
3509<YueDisplay> 3807<YueDisplay>
3510<pre> 3808
3809```yue
3511class Person 3810class Person
3512 clothes: [] 3811 clothes: []
3513 give_item: (name) => 3812 give_item: (name) =>
@@ -3521,29 +3820,32 @@ b\give_item "shirt"
3521 3820
3522-- 会同时打印出裤子和衬衫 3821-- 会同时打印出裤子和衬衫
3523print item for item in *a.clothes 3822print item for item in *a.clothes
3524</pre> 3823```
3824
3525</YueDisplay> 3825</YueDisplay>
3526 3826
3527避免这个问题的正确方法是在构造函数中创建对象的可变状态: 3827避免这个问题的正确方法是在构造函数中创建对象的可变状态:
3528 3828
3529```moonscript 3829```yuescript
3530class Person 3830class Person
3531 new: => 3831 new: =>
3532 @clothes = [] 3832 @clothes = []
3533``` 3833```
3534<YueDisplay> 3834<YueDisplay>
3535<pre> 3835
3836```yue
3536class Person 3837class Person
3537 new: => 3838 new: =>
3538 @clothes = [] 3839 @clothes = []
3539</pre> 3840```
3841
3540</YueDisplay> 3842</YueDisplay>
3541 3843
3542### 继承 3844### 继承
3543 3845
3544`extends` 关键字可以在类声明中使用,以继承另一个类的属性和方法。 3846`extends` 关键字可以在类声明中使用,以继承另一个类的属性和方法。
3545 3847
3546```moonscript 3848```yuescript
3547class BackPack extends Inventory 3849class BackPack extends Inventory
3548 size: 10 3850 size: 10
3549 add_item: (name) => 3851 add_item: (name) =>
@@ -3551,13 +3853,15 @@ class BackPack extends Inventory
3551 super name 3853 super name
3552``` 3854```
3553<YueDisplay> 3855<YueDisplay>
3554<pre> 3856
3857```yue
3555class BackPack extends Inventory 3858class BackPack extends Inventory
3556 size: 10 3859 size: 10
3557 add_item: (name) => 3860 add_item: (name) =>
3558 if #@items > size then error "背包已满" 3861 if #@items > size then error "背包已满"
3559 super name 3862 super name
3560</pre> 3863```
3864
3561</YueDisplay> 3865</YueDisplay>
3562 3866
3563 3867
@@ -3567,7 +3871,7 @@ class BackPack extends Inventory
3567 3871
3568此外,当一个类继承自另一个类时,它会尝试调用父类上的 `__inherited` 方法(如果这个方法存在的话),以此来向父类发送通知。这个 `__inherited` 函数接受两个参数:被继承的父类和继承的子类。 3872此外,当一个类继承自另一个类时,它会尝试调用父类上的 `__inherited` 方法(如果这个方法存在的话),以此来向父类发送通知。这个 `__inherited` 函数接受两个参数:被继承的父类和继承的子类。
3569 3873
3570```moonscript 3874```yuescript
3571class Shelf 3875class Shelf
3572 @__inherited: (child) => 3876 @__inherited: (child) =>
3573 print @__name, "被", child.__name, "继承" 3877 print @__name, "被", child.__name, "继承"
@@ -3576,14 +3880,16 @@ class Shelf
3576class Cupboard extends Shelf 3880class Cupboard extends Shelf
3577``` 3881```
3578<YueDisplay> 3882<YueDisplay>
3579<pre> 3883
3884```yue
3580class Shelf 3885class Shelf
3581 @__inherited: (child) => 3886 @__inherited: (child) =>
3582 print @__name, "被", child.__name, "继承" 3887 print @__name, "被", child.__name, "继承"
3583 3888
3584-- 将打印: Shelf 被 Cupboard 继承 3889-- 将打印: Shelf 被 Cupboard 继承
3585class Cupboard extends Shelf 3890class Cupboard extends Shelf
3586</pre> 3891```
3892
3587</YueDisplay> 3893</YueDisplay>
3588 3894
3589### super 关键字 3895### super 关键字
@@ -3598,7 +3904,7 @@ class Cupboard extends Shelf
3598 3904
3599下面是一些使用 `super` 的不同方法的示例: 3905下面是一些使用 `super` 的不同方法的示例:
3600 3906
3601```moonscript 3907```yuescript
3602class MyClass extends ParentClass 3908class MyClass extends ParentClass
3603 a_method: => 3909 a_method: =>
3604 -- 以下效果相同: 3910 -- 以下效果相同:
@@ -3610,7 +3916,8 @@ class MyClass extends ParentClass
3610 assert super == ParentClass 3916 assert super == ParentClass
3611``` 3917```
3612<YueDisplay> 3918<YueDisplay>
3613<pre> 3919
3920```yue
3614class MyClass extends ParentClass 3921class MyClass extends ParentClass
3615 a_method: => 3922 a_method: =>
3616 -- 以下效果相同: 3923 -- 以下效果相同:
@@ -3620,7 +3927,8 @@ class MyClass extends ParentClass
3620 3927
3621 -- super 作为值等于父类: 3928 -- super 作为值等于父类:
3622 assert super == ParentClass 3929 assert super == ParentClass
3623</pre> 3930```
3931
3624</YueDisplay> 3932</YueDisplay>
3625 3933
3626**super** 也可以用在函数存根的左侧。唯一的主要区别是,生成的函数不是绑定到 super 的值,而是绑定到 self。 3934**super** 也可以用在函数存根的左侧。唯一的主要区别是,生成的函数不是绑定到 super 的值,而是绑定到 self。
@@ -3629,19 +3937,21 @@ class MyClass extends ParentClass
3629 3937
3630每个类的实例都带有它的类型。这存储在特殊的 \_\_class 属性中。此属性会保存类对象。类对象是我们用来构建新实例的对象。我们还可以索引类对象以检索类方法和属性。 3938每个类的实例都带有它的类型。这存储在特殊的 \_\_class 属性中。此属性会保存类对象。类对象是我们用来构建新实例的对象。我们还可以索引类对象以检索类方法和属性。
3631 3939
3632```moonscript 3940```yuescript
3633b = BackPack! 3941b = BackPack!
3634assert b.__class == BackPack 3942assert b.__class == BackPack
3635 3943
3636print BackPack.size -- 打印 10 3944print BackPack.size -- 打印 10
3637``` 3945```
3638<YueDisplay> 3946<YueDisplay>
3639<pre> 3947
3948```yue
3640b = BackPack! 3949b = BackPack!
3641assert b.__class == BackPack 3950assert b.__class == BackPack
3642 3951
3643print BackPack.size -- 打印 10 3952print BackPack.size -- 打印 10
3644</pre> 3953```
3954
3645</YueDisplay> 3955</YueDisplay>
3646 3956
3647### 类对象 3957### 类对象
@@ -3659,13 +3969,15 @@ print BackPack.size -- 打印 10
3659 3969
3660此外,类对象包含几个特殊的属性:当类被声明时,类的名称会作为一个字符串存储在类对象的 “__name” 字段中。 3970此外,类对象包含几个特殊的属性:当类被声明时,类的名称会作为一个字符串存储在类对象的 “__name” 字段中。
3661 3971
3662```moonscript 3972```yuescript
3663print BackPack.__name -- 打印 Backpack 3973print BackPack.__name -- 打印 Backpack
3664``` 3974```
3665<YueDisplay> 3975<YueDisplay>
3666<pre> 3976
3977```yue
3667print BackPack.__name -- 打印 Backpack 3978print BackPack.__name -- 打印 Backpack
3668</pre> 3979```
3980
3669</YueDisplay> 3981</YueDisplay>
3670 3982
3671基础对象被保存在一个名为 `__base` 的特殊表中。我们可以编辑这个表,以便为那些已经创建出来的实例和还未创建的实例增加新的功能。 3983基础对象被保存在一个名为 `__base` 的特殊表中。我们可以编辑这个表,以便为那些已经创建出来的实例和还未创建的实例增加新的功能。
@@ -3676,7 +3988,7 @@ print BackPack.__name -- 打印 Backpack
3676 3988
3677我们可以直接在类对象中创建变量,而不是在类的基对象中,通过在类声明中的属性名前使用 @。 3989我们可以直接在类对象中创建变量,而不是在类的基对象中,通过在类声明中的属性名前使用 @。
3678 3990
3679```moonscript 3991```yuescript
3680class Things 3992class Things
3681 @some_func: => print "Hello from", @__name 3993 @some_func: => print "Hello from", @__name
3682 3994
@@ -3686,7 +3998,8 @@ Things\some_func!
3686assert Things().some_func == nil 3998assert Things().some_func == nil
3687``` 3999```
3688<YueDisplay> 4000<YueDisplay>
3689<pre> 4001
4002```yue
3690class Things 4003class Things
3691 @some_func: => print "Hello from", @__name 4004 @some_func: => print "Hello from", @__name
3692 4005
@@ -3694,12 +4007,13 @@ Things\some_func!
3694 4007
3695-- 类变量在实例中不可见 4008-- 类变量在实例中不可见
3696assert Things().some_func == nil 4009assert Things().some_func == nil
3697</pre> 4010```
4011
3698</YueDisplay> 4012</YueDisplay>
3699 4013
3700在表达式中,我们可以使用 @@ 来访问存储在 `self.__class` 中的值。因此,`@@hello` 是 `self.__class.hello` 的简写。 4014在表达式中,我们可以使用 @@ 来访问存储在 `self.__class` 中的值。因此,`@@hello` 是 `self.__class.hello` 的简写。
3701 4015
3702```moonscript 4016```yuescript
3703class Counter 4017class Counter
3704 @count: 0 4018 @count: 0
3705 4019
@@ -3712,7 +4026,8 @@ Counter!
3712print Counter.count -- 输出 2 4026print Counter.count -- 输出 2
3713``` 4027```
3714<YueDisplay> 4028<YueDisplay>
3715<pre> 4029
4030```yue
3716class Counter 4031class Counter
3717 @count: 0 4032 @count: 0
3718 4033
@@ -3723,18 +4038,21 @@ Counter!
3723Counter! 4038Counter!
3724 4039
3725print Counter.count -- 输出 2 4040print Counter.count -- 输出 2
3726</pre> 4041```
4042
3727</YueDisplay> 4043</YueDisplay>
3728 4044
3729@@ 的调用语义与 @ 类似。调用 @@ 时,会使用 Lua 的冒号语法将类作为第一个参数传入。 4045@@ 的调用语义与 @ 类似。调用 @@ 时,会使用 Lua 的冒号语法将类作为第一个参数传入。
3730 4046
3731```moonscript 4047```yuescript
3732@@hello 1,2,3,4 4048@@hello 1,2,3,4
3733``` 4049```
3734<YueDisplay> 4050<YueDisplay>
3735<pre> 4051
4052```yue
3736@@hello 1,2,3,4 4053@@hello 1,2,3,4
3737</pre> 4054```
4055
3738</YueDisplay> 4056</YueDisplay>
3739 4057
3740### 类声明语句 4058### 类声明语句
@@ -3743,22 +4061,24 @@ print Counter.count -- 输出 2
3743 4061
3744以下是创建类变量的另一种方法: 4062以下是创建类变量的另一种方法:
3745 4063
3746```moonscript 4064```yuescript
3747class Things 4065class Things
3748 @class_var = "hello world" 4066 @class_var = "hello world"
3749``` 4067```
3750<YueDisplay> 4068<YueDisplay>
3751<pre> 4069
4070```yue
3752class Things 4071class Things
3753 @class_var = "hello world" 4072 @class_var = "hello world"
3754</pre> 4073```
4074
3755</YueDisplay> 4075</YueDisplay>
3756 4076
3757这些表达式会在所有属性被添加到类的基对象后执行。 4077这些表达式会在所有属性被添加到类的基对象后执行。
3758 4078
3759在类的主体中声明的所有变量都会限制作用域只在类声明的范围。这对于放置只有类方法可以访问的私有值或辅助函数很方便: 4079在类的主体中声明的所有变量都会限制作用域只在类声明的范围。这对于放置只有类方法可以访问的私有值或辅助函数很方便:
3760 4080
3761```moonscript 4081```yuescript
3762class MoreThings 4082class MoreThings
3763 secret = 123 4083 secret = 123
3764 log = (msg) -> print "LOG:", msg 4084 log = (msg) -> print "LOG:", msg
@@ -3767,14 +4087,16 @@ class MoreThings
3767 log "hello world: " .. secret 4087 log "hello world: " .. secret
3768``` 4088```
3769<YueDisplay> 4089<YueDisplay>
3770<pre> 4090
4091```yue
3771class MoreThings 4092class MoreThings
3772 secret = 123 4093 secret = 123
3773 log = (msg) -> print "LOG:", msg 4094 log = (msg) -> print "LOG:", msg
3774 4095
3775 some_method: => 4096 some_method: =>
3776 log "hello world: " .. secret 4097 log "hello world: " .. secret
3777</pre> 4098```
4099
3778</YueDisplay> 4100</YueDisplay>
3779 4101
3780### @ 和 @@ 值 4102### @ 和 @@ 值
@@ -3783,33 +4105,37 @@ class MoreThings
3783 4105
3784如果它们单独使用,它们是 self 和 self.\_\_class 的别名。 4106如果它们单独使用,它们是 self 和 self.\_\_class 的别名。
3785 4107
3786```moonscript 4108```yuescript
3787assert @ == self 4109assert @ == self
3788assert @@ == self.__class 4110assert @@ == self.__class
3789``` 4111```
3790<YueDisplay> 4112<YueDisplay>
3791<pre> 4113
4114```yue
3792assert @ == self 4115assert @ == self
3793assert @@ == self.__class 4116assert @@ == self.__class
3794</pre> 4117```
4118
3795</YueDisplay> 4119</YueDisplay>
3796 4120
3797例如,使用 @@ 从实例方法快速创建同一类的新实例的方法: 4121例如,使用 @@ 从实例方法快速创建同一类的新实例的方法:
3798 4122
3799```moonscript 4123```yuescript
3800some_instance_method = (...) => @@ ... 4124some_instance_method = (...) => @@ ...
3801``` 4125```
3802<YueDisplay> 4126<YueDisplay>
3803<pre> 4127
4128```yue
3804some_instance_method = (...) => @@ ... 4129some_instance_method = (...) => @@ ...
3805</pre> 4130```
4131
3806</YueDisplay> 4132</YueDisplay>
3807 4133
3808### 构造属性提升 4134### 构造属性提升
3809 4135
3810为了减少编写简单值对象定义的代码。你可以这样简单写一个类: 4136为了减少编写简单值对象定义的代码。你可以这样简单写一个类:
3811 4137
3812```moonscript 4138```yuescript
3813class Something 4139class Something
3814 new: (@foo, @bar, @@biz, @@baz) => 4140 new: (@foo, @bar, @@biz, @@baz) =>
3815 4141
@@ -3823,7 +4149,8 @@ class Something
3823 @@baz = baz 4149 @@baz = baz
3824``` 4150```
3825<YueDisplay> 4151<YueDisplay>
3826<pre> 4152
4153```yue
3827class Something 4154class Something
3828 new: (@foo, @bar, @@biz, @@baz) => 4155 new: (@foo, @bar, @@biz, @@baz) =>
3829 4156
@@ -3835,76 +4162,85 @@ class Something
3835 @bar = bar 4162 @bar = bar
3836 @@biz = biz 4163 @@biz = biz
3837 @@baz = baz 4164 @@baz = baz
3838</pre> 4165```
4166
3839</YueDisplay> 4167</YueDisplay>
3840 4168
3841你也可以使用这种语法为一个函数初始化传入对象的字段。 4169你也可以使用这种语法为一个函数初始化传入对象的字段。
3842 4170
3843```moonscript 4171```yuescript
3844new = (@fieldA, @fieldB) => @ 4172new = (@fieldA, @fieldB) => @
3845obj = new {}, 123, "abc" 4173obj = new {}, 123, "abc"
3846print obj 4174print obj
3847``` 4175```
3848<YueDisplay> 4176<YueDisplay>
3849<pre> 4177
4178```yue
3850new = (@fieldA, @fieldB) => @ 4179new = (@fieldA, @fieldB) => @
3851obj = new {}, 123, "abc" 4180obj = new {}, 123, "abc"
3852print obj 4181print obj
3853</pre> 4182```
4183
3854</YueDisplay> 4184</YueDisplay>
3855 4185
3856### 类表达式 4186### 类表达式
3857 4187
3858类声明的语法也可以作为一个表达式使用,可以赋值给一个变量或者被返回语句返回。 4188类声明的语法也可以作为一个表达式使用,可以赋值给一个变量或者被返回语句返回。
3859 4189
3860```moonscript 4190```yuescript
3861x = class Bucket 4191x = class Bucket
3862 drops: 0 4192 drops: 0
3863 add_drop: => @drops += 1 4193 add_drop: => @drops += 1
3864``` 4194```
3865<YueDisplay> 4195<YueDisplay>
3866<pre> 4196
4197```yue
3867x = class Bucket 4198x = class Bucket
3868 drops: 0 4199 drops: 0
3869 add_drop: => @drops += 1 4200 add_drop: => @drops += 1
3870</pre> 4201```
4202
3871</YueDisplay> 4203</YueDisplay>
3872 4204
3873### 匿名类 4205### 匿名类
3874 4206
3875声明类时可以省略名称。如果类的表达式不在赋值语句中,\_\_name 属性将为 nil。如果出现在赋值语句中,赋值操作左侧的名称将代替 nil。 4207声明类时可以省略名称。如果类的表达式不在赋值语句中,\_\_name 属性将为 nil。如果出现在赋值语句中,赋值操作左侧的名称将代替 nil。
3876 4208
3877```moonscript 4209```yuescript
3878BigBucket = class extends Bucket 4210BigBucket = class extends Bucket
3879 add_drop: => @drops += 10 4211 add_drop: => @drops += 10
3880 4212
3881assert Bucket.__name == "BigBucket" 4213assert Bucket.__name == "BigBucket"
3882``` 4214```
3883<YueDisplay> 4215<YueDisplay>
3884<pre> 4216
4217```yue
3885BigBucket = class extends Bucket 4218BigBucket = class extends Bucket
3886 add_drop: => @drops += 10 4219 add_drop: => @drops += 10
3887 4220
3888assert Bucket.__name == "BigBucket" 4221assert Bucket.__name == "BigBucket"
3889</pre> 4222```
4223
3890</YueDisplay> 4224</YueDisplay>
3891 4225
3892你甚至可以省略掉主体,这意味着你可以这样写一个空白的匿名类: 4226你甚至可以省略掉主体,这意味着你可以这样写一个空白的匿名类:
3893 4227
3894```moonscript 4228```yuescript
3895x = class 4229x = class
3896``` 4230```
3897<YueDisplay> 4231<YueDisplay>
3898<pre> 4232
4233```yue
3899x = class 4234x = class
3900</pre> 4235```
4236
3901</YueDisplay> 4237</YueDisplay>
3902 4238
3903### 类混合 4239### 类混合
3904 4240
3905你可以通过使用 `using` 关键字来实现类混合。这意味着你可以从一个普通 Lua 表格或已定义的类对象中,复制函数到你创建的新类中。当你使用普通 Lua 表格进行类混合时,你有机会用自己的实现来重写类的索引方法(例如元方法 `__index`)。然而,当你从一个类对象做混合时,需要注意的是该类对象的元方法将不会被复制到新类。 4241你可以通过使用 `using` 关键字来实现类混合。这意味着你可以从一个普通 Lua 表格或已定义的类对象中,复制函数到你创建的新类中。当你使用普通 Lua 表格进行类混合时,你有机会用自己的实现来重写类的索引方法(例如元方法 `__index`)。然而,当你从一个类对象做混合时,需要注意的是该类对象的元方法将不会被复制到新类。
3906 4242
3907```moonscript 4243```yuescript
3908MyIndex = __index: var: 1 4244MyIndex = __index: var: 1
3909 4245
3910class X using MyIndex 4246class X using MyIndex
@@ -3922,7 +4258,8 @@ y\func!
3922assert y.__class.__parent ~= X -- X 不是 Y 的父类 4258assert y.__class.__parent ~= X -- X 不是 Y 的父类
3923``` 4259```
3924<YueDisplay> 4260<YueDisplay>
3925<pre> 4261
4262```yue
3926MyIndex = __index: var: 1 4263MyIndex = __index: var: 1
3927 4264
3928class X using MyIndex 4265class X using MyIndex
@@ -3938,7 +4275,8 @@ y = Y!
3938y\func! 4275y\func!
3939 4276
3940assert y.__class.__parent ~= X -- X 不是 Y 的父类 4277assert y.__class.__parent ~= X -- X 不是 Y 的父类
3941</pre> 4278```
4279
3942</YueDisplay> 4280</YueDisplay>
3943 4281
3944## with 语句 4282## with 语句
@@ -3951,7 +4289,7 @@ with 块有助于简化编写这样的代码。在 with 块内,我们可以使
3951 4289
3952例如,我们可以这样处理一个新创建的对象: 4290例如,我们可以这样处理一个新创建的对象:
3953 4291
3954```moonscript 4292```yuescript
3955with Person! 4293with Person!
3956 .name = "Oswald" 4294 .name = "Oswald"
3957 \add_relative my_dad 4295 \add_relative my_dad
@@ -3959,31 +4297,35 @@ with Person!
3959 print .name 4297 print .name
3960``` 4298```
3961<YueDisplay> 4299<YueDisplay>
3962<pre> 4300
4301```yue
3963with Person! 4302with Person!
3964 .name = "Oswald" 4303 .name = "Oswald"
3965 \add_relative my_dad 4304 \add_relative my_dad
3966 \save! 4305 \save!
3967 print .name 4306 print .name
3968</pre> 4307```
4308
3969</YueDisplay> 4309</YueDisplay>
3970 4310
3971with 语句也可以用作一个表达式,并返回它的代码块正在处理的对象。 4311with 语句也可以用作一个表达式,并返回它的代码块正在处理的对象。
3972 4312
3973```moonscript 4313```yuescript
3974file = with File "favorite_foods.txt" 4314file = with File "favorite_foods.txt"
3975 \set_encoding "utf8" 4315 \set_encoding "utf8"
3976``` 4316```
3977<YueDisplay> 4317<YueDisplay>
3978<pre> 4318
4319```yue
3979file = with File "favorite_foods.txt" 4320file = with File "favorite_foods.txt"
3980 \set_encoding "utf8" 4321 \set_encoding "utf8"
3981</pre> 4322```
4323
3982</YueDisplay> 4324</YueDisplay>
3983 4325
3984或者… 4326或者…
3985 4327
3986```moonscript 4328```yuescript
3987create_person = (name, relatives) -> 4329create_person = (name, relatives) ->
3988 with Person! 4330 with Person!
3989 .name = name 4331 .name = name
@@ -3992,36 +4334,40 @@ create_person = (name, relatives) ->
3992me = create_person "Leaf", [dad, mother, sister] 4334me = create_person "Leaf", [dad, mother, sister]
3993``` 4335```
3994<YueDisplay> 4336<YueDisplay>
3995<pre> 4337
4338```yue
3996create_person = (name, relatives) -> 4339create_person = (name, relatives) ->
3997 with Person! 4340 with Person!
3998 .name = name 4341 .name = name
3999 \add_relative relative for relative in *relatives 4342 \add_relative relative for relative in *relatives
4000 4343
4001me = create_person "Leaf", [dad, mother, sister] 4344me = create_person "Leaf", [dad, mother, sister]
4002</pre> 4345```
4346
4003</YueDisplay> 4347</YueDisplay>
4004 4348
4005在此用法中,with 可以被视为K组合子(k-combinator)的一种特殊形式。 4349在此用法中,with 可以被视为K组合子(k-combinator)的一种特殊形式。
4006 4350
4007如果你想给表达式另外起一个名称的话,with 语句中的表达式也可以是一个赋值语句。 4351如果你想给表达式另外起一个名称的话,with 语句中的表达式也可以是一个赋值语句。
4008 4352
4009```moonscript 4353```yuescript
4010with str := "你好" 4354with str := "你好"
4011 print "原始:", str 4355 print "原始:", str
4012 print "大写:", \upper! 4356 print "大写:", \upper!
4013``` 4357```
4014<YueDisplay> 4358<YueDisplay>
4015<pre> 4359
4360```yue
4016with str := "你好" 4361with str := "你好"
4017 print "原始:", str 4362 print "原始:", str
4018 print "大写:", \upper! 4363 print "大写:", \upper!
4019</pre> 4364```
4365
4020</YueDisplay> 4366</YueDisplay>
4021 4367
4022你可以在 `with` 语句中使用 `[]` 访问特殊键。 4368你可以在 `with` 语句中使用 `[]` 访问特殊键。
4023 4369
4024```moonscript 4370```yuescript
4025with tb 4371with tb
4026 [1] = 1 4372 [1] = 1
4027 print [2] 4373 print [2]
@@ -4031,7 +4377,8 @@ with tb
4031 [] = "abc" -- 追加到 "tb" 4377 [] = "abc" -- 追加到 "tb"
4032``` 4378```
4033<YueDisplay> 4379<YueDisplay>
4034<pre> 4380
4381```yue
4035with tb 4382with tb
4036 [1] = 1 4383 [1] = 1
4037 print [2] 4384 print [2]
@@ -4039,44 +4386,49 @@ with tb
4039 [3] = [2]\func! 4386 [3] = [2]\func!
4040 ["key-name"] = value 4387 ["key-name"] = value
4041 [] = "abc" -- 追加到 "tb" 4388 [] = "abc" -- 追加到 "tb"
4042</pre> 4389```
4390
4043</YueDisplay> 4391</YueDisplay>
4044 4392
4045`with?` 是 `with` 语法的一个增强版本,引入了存在性检查,用于在不显式判空的情况下安全访问可能为 nil 的对象。 4393`with?` 是 `with` 语法的一个增强版本,引入了存在性检查,用于在不显式判空的情况下安全访问可能为 nil 的对象。
4046 4394
4047```moonscript 4395```yuescript
4048with? obj 4396with? obj
4049 print obj.name 4397 print obj.name
4050``` 4398```
4051<YueDisplay> 4399<YueDisplay>
4052<pre> 4400
4401```yue
4053with? obj 4402with? obj
4054 print obj.name 4403 print obj.name
4055</pre> 4404```
4405
4056</YueDisplay> 4406</YueDisplay>
4057 4407
4058## do 语句 4408## do 语句
4059 4409
4060当用作语句时,do 语句的作用就像在 Lua 中差不多。 4410当用作语句时,do 语句的作用就像在 Lua 中差不多。
4061 4411
4062```moonscript 4412```yuescript
4063do 4413do
4064 var = "hello" 4414 var = "hello"
4065 print var 4415 print var
4066print var -- 这里是nil 4416print var -- 这里是nil
4067``` 4417```
4068<YueDisplay> 4418<YueDisplay>
4069<pre> 4419
4420```yue
4070do 4421do
4071 var = "hello" 4422 var = "hello"
4072 print var 4423 print var
4073print var -- 这里是nil 4424print var -- 这里是nil
4074</pre> 4425```
4426
4075</YueDisplay> 4427</YueDisplay>
4076 4428
4077月之脚本的 **do** 也可以用作表达式。允许你将多行代码的处理合并为一个表达式,并将 do 语句代码块的最后一个语句作为表达式返回的结果。 4429月之脚本的 **do** 也可以用作表达式。允许你将多行代码的处理合并为一个表达式,并将 do 语句代码块的最后一个语句作为表达式返回的结果。
4078 4430
4079```moonscript 4431```yuescript
4080counter = do 4432counter = do
4081 i = 0 4433 i = 0
4082 -> 4434 ->
@@ -4087,7 +4439,8 @@ print counter!
4087print counter! 4439print counter!
4088``` 4440```
4089<YueDisplay> 4441<YueDisplay>
4090<pre> 4442
4443```yue
4091counter = do 4444counter = do
4092 i = 0 4445 i = 0
4093 -> 4446 ->
@@ -4096,10 +4449,11 @@ counter = do
4096 4449
4097print counter! 4450print counter!
4098print counter! 4451print counter!
4099</pre> 4452```
4453
4100</YueDisplay> 4454</YueDisplay>
4101 4455
4102```moonscript 4456```yuescript
4103tbl = { 4457tbl = {
4104 key: do 4458 key: do
4105 print "分配键值!" 4459 print "分配键值!"
@@ -4107,13 +4461,15 @@ tbl = {
4107} 4461}
4108``` 4462```
4109<YueDisplay> 4463<YueDisplay>
4110<pre> 4464
4111tbl = { 4465```yue
4466tbl = \{
4112 key: do 4467 key: do
4113 print "分配键值!" 4468 print "分配键值!"
4114 1234 4469 1234
4115} 4470}
4116</pre> 4471```
4472
4117</YueDisplay> 4473</YueDisplay>
4118 4474
4119## 函数存根 4475## 函数存根
@@ -4124,7 +4480,7 @@ tbl = {
4124 4480
4125这种语法类似于使用 \ 操作符调用实例方法的方式,区别在于,这里不需要在 \ 操作符后面附加参数列表。 4481这种语法类似于使用 \ 操作符调用实例方法的方式,区别在于,这里不需要在 \ 操作符后面附加参数列表。
4126 4482
4127```moonscript 4483```yuescript
4128my_object = { 4484my_object = {
4129 value: 1000 4485 value: 1000
4130 write: => print "值为:", @value 4486 write: => print "值为:", @value
@@ -4143,8 +4499,9 @@ run_callback my_object.write
4143run_callback my_object\write 4499run_callback my_object\write
4144``` 4500```
4145<YueDisplay> 4501<YueDisplay>
4146<pre> 4502
4147my_object = { 4503```yue
4504my_object = \{
4148 value: 1000 4505 value: 1000
4149 write: => print "值为:", @value 4506 write: => print "值为:", @value
4150} 4507}
@@ -4160,14 +4517,15 @@ run_callback my_object.write
4160-- 函数存根语法 4517-- 函数存根语法
4161-- 让我们把对象捆绑到一个新函数中 4518-- 让我们把对象捆绑到一个新函数中
4162run_callback my_object\write 4519run_callback my_object\write
4163</pre> 4520```
4521
4164</YueDisplay> 4522</YueDisplay>
4165 4523
4166## 使用 using 语句:防止破坏性赋值 4524## 使用 using 语句:防止破坏性赋值
4167 4525
4168Lua 的变量作用域是降低代码复杂度的重要工具。然而,随着代码量的增加,维护这些变量可能变得更加困难。比如,看看下面的代码片段: 4526Lua 的变量作用域是降低代码复杂度的重要工具。然而,随着代码量的增加,维护这些变量可能变得更加困难。比如,看看下面的代码片段:
4169 4527
4170```moonscript 4528```yuescript
4171i = 100 4529i = 100
4172 4530
4173-- 许多代码行... 4531-- 许多代码行...
@@ -4183,7 +4541,8 @@ my_func!
4183print i -- 将打印 0 4541print i -- 将打印 0
4184``` 4542```
4185<YueDisplay> 4543<YueDisplay>
4186<pre> 4544
4545```yue
4187i = 100 4546i = 100
4188 4547
4189-- 许多代码行... 4548-- 许多代码行...
@@ -4197,7 +4556,8 @@ my_func = ->
4197my_func! 4556my_func!
4198 4557
4199print i -- 将打印 0 4558print i -- 将打印 0
4200</pre> 4559```
4560
4201</YueDisplay> 4561</YueDisplay>
4202 4562
4203在 `my_func` 中,我们不小心覆盖了变量 `i` 的值。虽然在这个例子中这个问题很明显,但在一个庞大的或者是由多人共同维护的代码库中,很难追踪每个变量的声明情况。 4563在 `my_func` 中,我们不小心覆盖了变量 `i` 的值。虽然在这个例子中这个问题很明显,但在一个庞大的或者是由多人共同维护的代码库中,很难追踪每个变量的声明情况。
@@ -4206,7 +4566,7 @@ print i -- 将打印 0
4206 4566
4207`using` 语句就是为此而生。`using nil` 确保函数内部的赋值不会意外地影响到外部作用域的变量。我们只需将 `using` 子句放在函数的参数列表之后;若函数没有参数,则直接放在括号内即可。 4567`using` 语句就是为此而生。`using nil` 确保函数内部的赋值不会意外地影响到外部作用域的变量。我们只需将 `using` 子句放在函数的参数列表之后;若函数没有参数,则直接放在括号内即可。
4208 4568
4209```moonscript 4569```yuescript
4210i = 100 4570i = 100
4211 4571
4212my_func = (using nil) -> 4572my_func = (using nil) ->
@@ -4216,7 +4576,8 @@ my_func!
4216print i -- 打印 100,i 没有受到影响 4576print i -- 打印 100,i 没有受到影响
4217``` 4577```
4218<YueDisplay> 4578<YueDisplay>
4219<pre> 4579
4580```yue
4220i = 100 4581i = 100
4221 4582
4222my_func = (using nil) -> 4583my_func = (using nil) ->
@@ -4224,12 +4585,13 @@ my_func = (using nil) ->
4224 4585
4225my_func! 4586my_func!
4226print i -- 打印 100,i 没有受到影响 4587print i -- 打印 100,i 没有受到影响
4227</pre> 4588```
4589
4228</YueDisplay> 4590</YueDisplay>
4229 4591
4230using子句中可以填写多个用逗号分隔名称。指定可以访问和修改的外部变量的名称: 4592using子句中可以填写多个用逗号分隔名称。指定可以访问和修改的外部变量的名称:
4231 4593
4232```moonscript 4594```yuescript
4233tmp = 1213 4595tmp = 1213
4234i, k = 100, 50 4596i, k = 100, 50
4235 4597
@@ -4242,7 +4604,8 @@ my_func(22)
4242print i, k -- 这些已经被更新 4604print i, k -- 这些已经被更新
4243``` 4605```
4244<YueDisplay> 4606<YueDisplay>
4245<pre> 4607
4608```yue
4246tmp = 1213 4609tmp = 1213
4247i, k = 100, 50 4610i, k = 100, 50
4248 4611
@@ -4253,7 +4616,8 @@ my_func = (add using k, i) ->
4253 4616
4254my_func(22) 4617my_func(22)
4255print i, k -- 这些已经被更新 4618print i, k -- 这些已经被更新
4256</pre> 4619```
4620
4257</YueDisplay> 4621</YueDisplay>
4258 4622
4259## 月之脚本语言库 4623## 月之脚本语言库
diff --git a/doc/docs/zh/index.md b/doc/docs/zh/index.md
new file mode 100644
index 0000000..6d677e9
--- /dev/null
+++ b/doc/docs/zh/index.md
@@ -0,0 +1,25 @@
1---
2layout: home
3hero:
4 name: 月之脚本
5 text: 一门编译到 Lua 的语言
6 image:
7 src: /image/yuescript.svg
8 alt: 月之脚本
9 actions:
10 - theme: brand
11 text: 快速上手 →
12 link: /zh/doc/
13features:
14 - title: 熟悉的 Lua 工作流
15 details: 更精简的语法,编译为可读 Lua,输出可预测、易集成。
16 - title: 现代语言特性
17 details: 管道、模式匹配、切片与解构,同时保留 Lua 互操作性。
18 - title: 内置工具链
19 details: 在线 Playground、语法高亮与同步更新的文档。
20footer: MIT Licensed | Copyright © 2017-2026 Li Jin
21---
22
23### 版权和协议
24
25MIT 许可。Copyright © 2017-2026 Li Jin. 保留所有权利。
diff --git a/doc/docs/zh/try/README.md b/doc/docs/zh/try/index.md
index 46667a8..46667a8 100755
--- a/doc/docs/zh/try/README.md
+++ b/doc/docs/zh/try/index.md
diff --git a/doc/package.json b/doc/package.json
index 421df11..3e1bd17 100755
--- a/doc/package.json
+++ b/doc/package.json
@@ -15,10 +15,16 @@
15 }, 15 },
16 "license": "MIT", 16 "license": "MIT",
17 "devDependencies": { 17 "devDependencies": {
18 "@types/node": "^25.2.0",
18 "vitepress": "^1.6.4", 19 "vitepress": "^1.6.4",
19 "vue": "^3.4.38" 20 "vue": "^3.4.38"
20 }, 21 },
21 "dependencies": { 22 "dependencies": {
23 "@codemirror/commands": "^6.10.1",
24 "@codemirror/language": "^6.12.1",
25 "@codemirror/legacy-modes": "^6.5.2",
26 "@codemirror/state": "^6.5.4",
27 "@codemirror/view": "^6.39.12",
22 "prismjs": "^1.29.0" 28 "prismjs": "^1.29.0"
23 } 29 }
24} 30}
diff --git a/doc/tsconfig.json b/doc/tsconfig.json
new file mode 100644
index 0000000..e8b48d8
--- /dev/null
+++ b/doc/tsconfig.json
@@ -0,0 +1,18 @@
1{
2 "compilerOptions": {
3 "target": "ES2020",
4 "module": "ESNext",
5 "moduleResolution": "Bundler",
6 "lib": ["ES2020", "DOM", "DOM.Iterable"],
7 "jsx": "preserve",
8 "types": ["vitepress/client"],
9 "skipLibCheck": true,
10 "noEmit": true
11 },
12 "include": [
13 "docs/.vitepress/**/*.ts",
14 "docs/.vitepress/**/*.mts",
15 "docs/.vitepress/**/*.vue",
16 "docs/.vitepress/env.d.ts"
17 ]
18}