aboutsummaryrefslogtreecommitdiff
path: root/doc/docs/doc/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/docs/doc/README.md')
-rwxr-xr-xdoc/docs/doc/README.md594
1 files changed, 594 insertions, 0 deletions
diff --git a/doc/docs/doc/README.md b/doc/docs/doc/README.md
new file mode 100755
index 0000000..0d43d04
--- /dev/null
+++ b/doc/docs/doc/README.md
@@ -0,0 +1,594 @@
1---
2sidebar: auto
3---
4
5<CompilerModal />
6
7# Yuescript
8<img src="/image/yuescript.svg" width="300" height="300" alt="logo"/>
9
10## Introduction
11
12Yuescript is a dynamic language that compiles to Lua. The codes written in Yuescript are expressive and extremely concise. And it is suitable for writing some changing application logic with more maintainable codes and runs in a Lua embeded environment such as games or website servers.
13
14Yue (月) is the name of moon in Chinese and it's pronounced as [jyɛ].
15
16### An Overview of Yuescript
17```moonscript
18-- import syntax
19import "yue" as :p, :to_lua
20
21-- implicit objects
22inventory =
23 equipment:
24 * "sword"
25 * "shield"
26 items:
27 * name: "potion"
28 count: 10
29 * name: "bread"
30 count: 3
31
32-- backcall
33{1, 2, 3}
34 |> map (x)-> x * 2
35 |> filter (x)-> x > 4
36 |> reduce 0, (a, b)-> a + b
37 |> print
38
39-- metatable manipulation
40apple =
41 size: 15
42 index#: {color: 0x00ffff}
43p apple.color, apple.#?, apple.index#
44
45-- js-like export syntax
46export yuescript = "月之脚本"
47```
48<YueDisplay>
49<pre>
50-- import syntax
51import "yue" as :p, :to_lua
52
53-- implicit objects
54inventory =
55 equipment:
56 * "sword"
57 * "shield"
58 items:
59 * name: "potion"
60 count: 10
61 * name: "bread"
62 count: 3
63
64-- backcall
65{1, 2, 3}
66 |> map (x)-> x * 2
67 |> filter (x)-> x > 4
68 |> reduce 0, (a, b)-> a + b
69 |> print
70
71-- metatable manipulation
72apple =
73 size: 15
74 index#: {color: 0x00ffff}
75p apple.color, apple.#?, apple.index#
76
77-- js-like export syntax
78export yuescript = "月之脚本"
79</pre>
80</YueDisplay>
81
82## Installation
83
84* **Lua Module**
85
86&emsp;&emsp;Install [luarocks](https://luarocks.org), a package manager for Lua modules. Then install it as a Lua module and executable with:
87
88```
89> luarocks install yuescript
90```
91
92&emsp;&emsp;Or you can build `yue.so` file with:
93
94```
95> make shared LUAI=/usr/local/include/lua LUAL=/usr/local/lib/lua
96```
97
98&emsp;&emsp;Then get the binary file from path **bin/shared/yue.so**.
99
100* **Binary Tool**
101
102&emsp;&emsp;Clone this repo, then build and install executable with:
103```
104> make install
105```
106
107&emsp;&emsp;Build Yuescript tool without macro feature:
108```
109> make install NO_MACRO=true
110```
111
112&emsp;&emsp;Build Yuescript tool without built-in Lua binary:
113```
114> make install NO_LUA=true
115```
116
117## Usage
118
119&emsp;&emsp;Require the Yuescript module in Lua:
120```Lua
121-- require `main.yue` in Lua
122require("yue")("main")
123
124-- use the Yuescript compiler in Lua
125local yue = require("yue")
126local codes, err, globals = yue.to_lua([[
127f = ->
128 print "hello world"
129f!
130]],{
131 implicit_return_root = true,
132 reserve_line_number = true,
133 lint_global = true
134})
135```
136&emsp;&emsp;Use Yuescript tool with:
137```
138> yue -h
139Usage: yue [options|files|directories] ...
140
141 -h Print this message
142 -e str Execute a file or raw codes
143 -t path Specify where to place compiled files
144 -o file Write output to file
145 -s Use spaces in generated codes instead of tabs
146 -m Generate minified codes
147 -p Write output to standard out
148 -b Dump compile time (doesn't write output)
149 -l Write line numbers from source codes
150 -v Print version
151 -- Read from standard in, print to standard out
152 (Must be first and only argument)
153
154 Execute without options to enter REPL, type symbol '$'
155 in a single line to start/stop multi-line mode
156```
157&emsp;&emsp;Use cases:
158&emsp;&emsp;Recursively compile every Yuescript file with extension **.yue** under current path: **yue .**
159&emsp;&emsp;Compile and save results to a target path: **yue -t /target/path/ .**
160&emsp;&emsp;Compile and reserve debug info: **yue -l .**
161&emsp;&emsp;Compile and generate minified codes: **yue -m .**
162&emsp;&emsp;Execute raw codes: **yue -e 'print 123'**
163&emsp;&emsp;Execute a Yuescript file: **yue -e main.yue**
164
165## Macro
166
167### Common Usage
168Macro function is used for evaluating a string in the compile time and insert the generated codes into final compilation.
169
170```moonscript
171macro config = (debugging)->
172 global debugMode = debugging == "true"
173 ""
174
175macro asserts = (cond)->
176 debugMode and "assert #{cond}" or ""
177
178macro assert = (cond)->
179 debugMode and "assert #{cond}" or "#{cond}"
180
181$config true
182$asserts item ~= nil
183
184$config false
185value = $assert item
186
187-- the passed expressions are treated as strings
188macro and = (...)-> "#{ table.concat {...}, ' and ' }"
189if $and f1!, f2!, f3!
190 print "OK"
191```
192<YueDisplay>
193<pre>
194macro config = (debugging)->
195 global debugMode = debugging == "true"
196 ""
197
198macro asserts = (cond)->
199 debugMode and "assert #{cond}" or ""
200
201macro assert = (cond)->
202 debugMode and "assert #{cond}" or "#{cond}"
203
204$config true
205$asserts item ~= nil
206
207$config false
208value = $assert item
209
210-- the passed expressions are treated as strings
211macro and = (...)-> "#{ table.concat {...}, ' and ' }"
212if $and f1!, f2!, f3!
213 print "OK"
214</pre>
215</YueDisplay>
216
217### Insert Raw Codes
218
219A macro function can either return a Yuescript string or a config table containing Lua codes.
220```moonscript
221macro yueFunc = (var)-> "local #{var} = ->"
222$yueFunc funcA
223funcA = -> "assign the Yue defined variable"
224
225-- take care and let Yuescript know the
226-- local variables you declared in Lua code
227macro luaFunc = (var)-> {
228 codes: "local function #{var}() end"
229 type: "lua"
230 locals: {var}
231}
232$luaFunc funcB
233funcB = -> "assign the Lua defined variable"
234
235macro lua = (code)-> {
236 :code
237 type: "lua"
238}
239
240-- the raw string leading and ending symbols are auto trimed
241$lua[==[
242-- raw Lua codes insertion
243if cond then
244 print("output")
245end
246]==]
247```
248<YueDisplay>
249<pre>
250macro yueFunc = (var)-> "local #{var} = ->"
251$yueFunc funcA
252funcA = -> "assign the Yue defined variable"
253
254-- take care and let Yuescript know the
255-- local variables you declared in Lua codes
256macro luaFunc = (var)-> {
257 codes: "local function #{var}() end"
258 type: "lua"
259 locals: {var}
260}
261$luaFunc funcB
262funcB = -> "assign the Lua defined variable"
263
264macro lua = (code)-> {
265 :code
266 type: "lua"
267}
268
269-- the raw string leading and ending symbols are auto trimed
270$lua[==[
271-- raw Lua codes insertion
272if cond then
273 print("output")
274end
275]==]
276</pre>
277</YueDisplay>
278
279### Export Macro
280
281Macro functions can be exported from a module and get imported in another module. It is recommanded to export macro functions in a single file to speed up compilation.
282```moonscript
283-- file: utils.yue
284export macro map = (items, action)-> "[#{action} for _ in *#{items}]"
285export macro filter = (items, action)-> "[_ for _ in *#{items} when #{action}]"
286export macro foreach = (items, action)-> "for _ in *#{items}
287 #{action}"
288
289-- file main.yue
290import "utils" as {
291 $, -- symbol to import all macros
292 $foreach: $each -- rename macro $foreach to $each
293}
294{1, 2, 3} |> $map(_ * 2) |> $filter(_ > 4) |> $each print _
295```
296<YueDisplay>
297<pre>
298-- file: utils.yue
299export macro map = (items, action)-> "[#{action} for _ in *#{items}]"
300export macro filter = (items, action)-> "[_ for _ in *#{items} when #{action}]"
301export macro foreach = (items, action)-> "for _ in *#{items}
302 #{action}"
303
304-- file main.yue
305-- import function is not available in browser, try it in a real environment
306--[[
307import "utils" as {
308 $, -- symbol to import all macros
309 $foreach: $each -- rename macro $foreach to $each
310}
311{1, 2, 3} |> $map(_ * 2) |> $filter(_ > 4) |> $each print _
312]]
313</pre>
314</YueDisplay>
315
316## Special Operator
317
318### Metatable
319
320The **#** operator can be used as a shortcut for metatable manipulation.
321
322* **Metatable Creation**
323Create normal table with key **#** or metamethod key that ends with **#**.
324
325```moonscript
326mt = {}
327add = (right)=> #: mt, value: @value + right.value
328mt.__add = add
329
330a = #: mt, value: 1
331 -- set field with variable of the same name
332b = :add#, value: 2
333c = add#: mt.__add, value: 3
334
335d = a + b + c
336print d.value
337
338close _ = close#: -> print "out of scope"
339```
340<YueDisplay>
341<pre>
342mt = {}
343add = (right)=> #: mt, value: @value + right.value
344mt.__add = add
345
346a = #: mt, value: 1
347 -- set field with variable of the same name
348b = :add#, value: 2
349c = add#: mt.__add, value: 3
350
351d = a + b + c
352print d.value
353
354close _ = close#: -> print "out of scope"
355</pre>
356</YueDisplay>
357
358* **Metatable Accessing**
359Accessing metatable with key **#** or metamethod key that ends with **#**.
360
361```moonscript
362-- create with metatable containing field "value"
363tb = ["value"]#: 123
364tb.index# = tb.#
365print tb.value
366
367tb.# = __index: {item: "hello"}
368print tb.item
369```
370<YueDisplay>
371<pre>
372-- create with metatable containing field "value"
373tb = ["value"]#: 123
374tb.index# = tb.#
375print tb.value
376
377tb.# = __index: {item: "hello"}
378print tb.item
379</pre>
380</YueDisplay>
381
382* **Metatable Destructure**
383Destruct metatable with metamethod key that ends with **#**.
384
385```moonscript
386{item, :new, :close#, index#: getter} = tb
387print item, new, close, getter
388```
389<YueDisplay>
390<pre>
391{item, :new, :close#, index#: getter} = tb
392print item, new, close, getter
393</pre>
394</YueDisplay>
395
396### Existence
397
398The **?** operator can be used in a variety of contexts to check for existence.
399
400```moonscript
401func?!
402print abc?["hello world"]?.xyz
403
404x = tab?.value
405len = utf8?.len or string?.len or (o)-> #o
406
407if print and x?
408 print x
409
410with? io.open "test.txt", "w"
411 \write "hello"
412 \close!
413```
414<YueDisplay>
415<pre>
416func?!
417print abc?["hello world"]?.xyz
418
419x = tab?.value
420len = utf8?.len or string?.len or (o)-> #o
421
422if print and x?
423 print x
424
425with? io.open "test.txt", "w"
426 \write "hello"
427 \close!
428</pre>
429</YueDisplay>
430
431### Piping
432
433Instead of a series of nested function calls, you can pipe values with operator **|>**.
434```moonscript
435"hello" |> print
4361 |> print 2 -- insert pipe item as the first argument
4372 |> print 1, _, 3 -- pipe with a placeholder
438
439-- pipe expression in multiline
440readFile "example.txt"
441 |> extract language, {}
442 |> parse language
443 |> emit
444 |> render
445 |> print
446```
447<YueDisplay>
448<pre>
449"hello" |> print
4501 |> print 2 -- insert pipe item as the first argument
4512 |> print 1, _, 3 -- pipe with a placeholder
452
453-- pipe expression in multiline
454readFile "example.txt"
455 |> extract language, {}
456 |> parse language
457 |> emit
458 |> render
459 |> print
460</pre>
461</YueDisplay>
462
463## Module
464
465### Import
466
467The import statement is a syntax sugar for requiring a module or help extracting items from an imported module.
468
469```moonscript
470-- used as table destructure
471do
472 import C, Ct, Cmt from require "lpeg"
473 import insert, concat from table
474
475-- shortcut for requring a module
476do
477 import 'module'
478 import 'module_x'
479 import "d-a-s-h-e-s"
480 import "module.part"
481
482-- requring module with aliasing or table destruction
483do
484 import "player" as PlayerModule
485 import "lpeg" as :C, :Ct, :Cmt
486 import "export" as {one, two, Something:{umm:{ch}}}
487```
488<YueDisplay>
489<pre>
490-- used as table destruction
491do
492 import C, Ct, Cmt from require "lpeg"
493 import insert, concat from table
494
495-- shortcut for requring a module
496do
497 import 'module'
498 import 'module_x'
499 import "d-a-s-h-e-s"
500 import "module.part"
501
502-- requring module with aliasing or table destruction
503do
504 import "player" as PlayerModule
505 import "lpeg" as :C, :Ct, :Cmt
506 import "export" as {one, two, Something:{umm:{ch}}}
507</pre>
508</YueDisplay>
509
510### Export
511
512The export statement offers a concise way to define modules.
513
514* **Named Export**
515Named export will define a local variable as well as adding a field in the exported table.
516
517```moonscript
518export a, b, c = 1, 2, 3
519export cool = "cat"
520
521export What = if this
522 "abc"
523else
524 "def"
525
526export y = ->
527 hallo = 3434
528
529export class Something
530 umm: "cool"
531```
532<YueDisplay>
533<pre>
534export a, b, c = 1, 2, 3
535export cool = "cat"
536
537export What = if this
538 "abc"
539else
540 "def"
541
542export y = ->
543 hallo = 3434
544
545export class Something
546 umm: "cool"
547</pre>
548</YueDisplay>
549
550* **Unnamed Export**
551Unnamed export will add the target item into the array part of the exported table.
552
553```moonscript
554d, e, f = 3, 2, 1
555export d, e, f
556
557export if this
558 123
559else
560 456
561
562export with tmp
563 j = 2000
564```
565<YueDisplay>
566<pre>
567d, e, f = 3, 2, 1
568export d, e, f
569
570export if this
571 123
572else
573 456
574
575export with tmp
576 j = 2000
577</pre>
578</YueDisplay>
579
580* **Default Export**
581Using the **default** keyword in export statement to replace the exported table with any thing.
582
583```moonscript
584export default ->
585 print "hello"
586 123
587```
588<YueDisplay>
589<pre>
590export default ->
591 print "hello"
592 123
593</pre>
594</YueDisplay> \ No newline at end of file