mirror of
https://github.com/leafo/moonscript.git
synced 2024-11-22 02:44:23 +00:00
1553 lines
136 KiB
HTML
1553 lines
136 KiB
HTML
|
<!DOCTYPE HTML>
|
|||
|
<html lang="en">
|
|||
|
<head>
|
|||
|
<meta charset="UTF-8">
|
|||
|
<title>MoonScript v0.1.0</title>
|
|||
|
|
|||
|
<style type="text/css">body {
|
|||
|
background: #F2F6FA;
|
|||
|
font-family: sans-serif;
|
|||
|
margin: 0px;
|
|||
|
}
|
|||
|
|
|||
|
.header h1 {
|
|||
|
background: #404142;
|
|||
|
margin: 0px;
|
|||
|
color: #F2F6FA;
|
|||
|
padding-left: 10px;
|
|||
|
text-shadow: -1px -1px 0px #2D2D2E;
|
|||
|
}
|
|||
|
|
|||
|
a:link, a:visited {
|
|||
|
color: #007BFF;
|
|||
|
}
|
|||
|
|
|||
|
a:hover {
|
|||
|
color: #409CFF;
|
|||
|
}
|
|||
|
|
|||
|
p {
|
|||
|
line-height: 140%;
|
|||
|
font-size: 16px;
|
|||
|
}
|
|||
|
|
|||
|
.main {
|
|||
|
width: 960px;
|
|||
|
padding-left: 1em;
|
|||
|
}
|
|||
|
|
|||
|
h1, .main h2, .main h3 {
|
|||
|
color: #4B4B4B;
|
|||
|
text-shadow: 1px 1px 0px white;
|
|||
|
padding-bottom: 2px;
|
|||
|
|
|||
|
margin: 0px;
|
|||
|
margin-top: 1.5em;
|
|||
|
}
|
|||
|
|
|||
|
.main h2 {
|
|||
|
border-bottom: 1px solid #7E7979;
|
|||
|
}
|
|||
|
|
|||
|
h1 {
|
|||
|
margin: 0px;
|
|||
|
margin-top: 1em;
|
|||
|
padding: 10px 20px;
|
|||
|
font-size: 40px;
|
|||
|
background: #E1E4E8;
|
|||
|
}
|
|||
|
|
|||
|
table, .bare-code {
|
|||
|
background: white;
|
|||
|
border: 1px solid #999;
|
|||
|
margin: 10px 0px;
|
|||
|
-webkit-box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.22);
|
|||
|
-moz-box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.22);
|
|||
|
box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.22);
|
|||
|
}
|
|||
|
|
|||
|
.bare-code {
|
|||
|
padding: 8px;
|
|||
|
}
|
|||
|
|
|||
|
td > pre {
|
|||
|
padding: 0px 8px;
|
|||
|
line-height: 18px;
|
|||
|
}
|
|||
|
|
|||
|
.code-border {
|
|||
|
border-right: 1px dashed #ddd;
|
|||
|
}
|
|||
|
|
|||
|
td {
|
|||
|
vertical-align: top;
|
|||
|
}
|
|||
|
|
|||
|
.code-header {
|
|||
|
background: #ABA9AB;
|
|||
|
background-image: -webkit-gradient(
|
|||
|
linear,
|
|||
|
left bottom,
|
|||
|
left top,
|
|||
|
color-stop(0, rgb(148,146,148)),
|
|||
|
color-stop(1, rgb(214,214,214))
|
|||
|
);
|
|||
|
background-image: -moz-linear-gradient(
|
|||
|
center bottom,
|
|||
|
rgb(148,146,148) 0%,
|
|||
|
rgb(214,214,214) 100%
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
.code-header td {
|
|||
|
color: white;
|
|||
|
text-shadow: 0px -1px 0px #555;
|
|||
|
font-size: 12px;
|
|||
|
font-weight: bold;
|
|||
|
|
|||
|
padding: 2px 6px;
|
|||
|
border-top: 1px solid #eee;
|
|||
|
border-bottom: 1px solid #666;
|
|||
|
}
|
|||
|
|
|||
|
p > code , li > code {
|
|||
|
background: #E1E4E8;
|
|||
|
border-radius: 4px;
|
|||
|
padding: 0px 4px;
|
|||
|
}
|
|||
|
|
|||
|
.l_string {
|
|||
|
color: #A16D43;
|
|||
|
/*
|
|||
|
background: #F9D7BB;
|
|||
|
background: #FFE9D6;
|
|||
|
*/
|
|||
|
}
|
|||
|
.l_symbol, .l_bold_symbol {
|
|||
|
color: #B50C0C;
|
|||
|
}
|
|||
|
.l_bold_symbol {
|
|||
|
/* font-weight: bold; */
|
|||
|
}
|
|||
|
.l_keyword {
|
|||
|
color: #0CB56C;
|
|||
|
}
|
|||
|
.l_comment {
|
|||
|
color: #D74DBF;
|
|||
|
}
|
|||
|
.l_fn_symbol {
|
|||
|
color: #8E4681;
|
|||
|
}
|
|||
|
.l_proper, .l_self_var, .l_special {
|
|||
|
color: #30A0BD;
|
|||
|
}
|
|||
|
.l_proper {
|
|||
|
font-weight: bold;
|
|||
|
}
|
|||
|
.l_builtins {
|
|||
|
color: #707A34;
|
|||
|
}
|
|||
|
.l_number {
|
|||
|
color: #4958C3;
|
|||
|
}
|
|||
|
|
|||
|
.footer {
|
|||
|
color: #747678;
|
|||
|
font-size: 80%;
|
|||
|
padding: 8px;
|
|||
|
}
|
|||
|
|
|||
|
</style>
|
|||
|
|
|||
|
</head><body>
|
|||
|
<div class="header">
|
|||
|
<h1>MoonScript v0.1.0</h1>
|
|||
|
</div>
|
|||
|
<ul>
|
|||
|
|
|||
|
<li><a href="#the_language">The Language</a></li>
|
|||
|
<ul>
|
|||
|
<li><a href="#assignment">Assignment</a></li>
|
|||
|
|
|||
|
<li><a href="#update_assignment">Update Assignment</a></li>
|
|||
|
|
|||
|
<li><a href="#comments_">Comments </a></li>
|
|||
|
|
|||
|
<li><a href="#literals_and_operators">Literals & Operators</a></li>
|
|||
|
|
|||
|
<li><a href="#function_literals">Function Literals</a></li>
|
|||
|
<ul>
|
|||
|
<li><a href="#fat_arrows">Fat Arrows</a></li>
|
|||
|
|
|||
|
<li><a href="#argument_defaults">Argument Defaults</a></li>
|
|||
|
|
|||
|
<li><a href="#considerations">Considerations</a></li>
|
|||
|
</ul>
|
|||
|
<li><a href="#table_literals">Table Literals</a></li>
|
|||
|
|
|||
|
<li><a href="#table_comprehensions">Table Comprehensions</a></li>
|
|||
|
<ul>
|
|||
|
<li><a href="#slicing">Slicing</a></li>
|
|||
|
</ul>
|
|||
|
<li><a href="#for_loop">For Loop</a></li>
|
|||
|
|
|||
|
<li><a href="#while_loop">While Loop</a></li>
|
|||
|
|
|||
|
<li><a href="#conditionals">Conditionals</a></li>
|
|||
|
|
|||
|
<li><a href="#line_decorators">Line Decorators</a></li>
|
|||
|
|
|||
|
<li><a href="#object_oriented_programming">Object Oriented Programming</a></li>
|
|||
|
<ul>
|
|||
|
<li><a href="#inheritance">Inheritance</a></li>
|
|||
|
|
|||
|
<li><a href="#types">Types</a></li>
|
|||
|
</ul>
|
|||
|
<li><a href="#export_statement">Export Statement</a></li>
|
|||
|
|
|||
|
<li><a href="#import_statement">Import Statement</a></li>
|
|||
|
|
|||
|
<li><a href="#with_statement">With Statement</a></li>
|
|||
|
|
|||
|
<li><a href="#the_using_clause_controlling_destructive_assignment">The Using Clause; Controlling Destructive Assignment</a></li>
|
|||
|
</ul>
|
|||
|
<li><a href="#moonscript_api">MoonScript API</a></li>
|
|||
|
<ul>
|
|||
|
<li><a href="#moonscript_module"><code>moonscript</code> Module</a></li>
|
|||
|
|
|||
|
<li><a href="#error_rewriting">Error Rewriting</a></li>
|
|||
|
|
|||
|
<li><a href="#programmatically_compiling">Programmatically Compiling</a></li>
|
|||
|
</ul>
|
|||
|
<li><a href="#command_line_use">Command Line Use</a></li>
|
|||
|
<ul>
|
|||
|
<li><a href="#moon"><code>moon</code></a></li>
|
|||
|
|
|||
|
<li><a href="#moonc"><code>moonc</code></a></li>
|
|||
|
</ul>
|
|||
|
<li><a href="#license_mit">License (MIT)</a></li>
|
|||
|
|
|||
|
</ul>
|
|||
|
<div class="main">
|
|||
|
<p>MoonScript is a programming language that compiles to
|
|||
|
<a href="http://www.lua.org">Lua</a>. This guide expects the reader to have basic
|
|||
|
familiarity with Lua. For each code snippet below, the MoonScript is on the
|
|||
|
left and the compiled Lua is on right right.</p>
|
|||
|
|
|||
|
</div><h1><a name="the_language"></a>The Language</h1><div class="main">
|
|||
|
|
|||
|
<h2><a name="assignment"></a>Assignment</h2>
|
|||
|
|
|||
|
<p>Unlike Lua, there is no <code>local</code> keyword. All assignments to names that are not
|
|||
|
already defined will be declared as local to the scope of that declaration. If
|
|||
|
you wish to create a global variable it must be done using the <code>export</code>
|
|||
|
keyword.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">hello</span> <span class="l_symbol">=</span> <span class="l_string">"world"</span>
|
|||
|
<span class="l_atom">a</span>,<span class="l_atom">b</span>,<span class="l_atom">c</span> <span class="l_symbol">=</span> <span class="l_number">1</span>, <span class="l_number">2</span>, <span class="l_number">3</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">hello</span> <span class="l_symbol">=</span> <span class="l_string">"world"</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">a</span>, <span class="l_atom">b</span>, <span class="l_atom">c</span> <span class="l_symbol">=</span> <span class="l_number">1</span>, <span class="l_number">2</span>, <span class="l_number">3</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<h2><a name="update_assignment"></a>Update Assignment</h2>
|
|||
|
|
|||
|
<p><code>+=</code>, <code>-=</code>, <code>/=</code>, <code>*=</code>, <code>%=</code> operators have been added for updating a value by
|
|||
|
a certain amount. They are aliases for their expanded equivalents.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">x</span> <span class="l_symbol">=</span> <span class="l_number">0</span>
|
|||
|
<span class="l_atom">x</span> <span class="l_symbol">+=</span> <span class="l_number">10</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">x</span> <span class="l_symbol">=</span> <span class="l_number">0</span>
|
|||
|
<span class="l_atom">x</span> <span class="l_symbol">=</span> <span class="l_atom">x</span> + <span class="l_number">10</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<h2><a name="comments_"></a>Comments </h2>
|
|||
|
|
|||
|
<p>Like Lua, comments start with <code>--</code> and continue to the end of the line.
|
|||
|
Comments are not written to the output.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_comment">-- I am a comment
|
|||
|
</span></code></pre></td><td><pre><code class="lua-code"></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<h2><a name="literals_and_operators"></a>Literals & Operators</h2>
|
|||
|
|
|||
|
<p>MoonScript supports all the same primitive literals as Lua and uses the same
|
|||
|
syntax. This applies to numbers, strings, booleans, and <code>nil</code>.</p>
|
|||
|
|
|||
|
<p>MoonScript also supports all the same binary and unary operators. Additionally
|
|||
|
<code>!=</code> is as an alias for <code>~=</code>.</p>
|
|||
|
|
|||
|
<h2><a name="function_literals"></a>Function Literals</h2>
|
|||
|
|
|||
|
<p>All functions are created using a function expression. A simple function is
|
|||
|
denoted using the arrow: <code>-></code></p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">my_function</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">-></span>
|
|||
|
<span class="l_atom">my_function</span>() <span class="l_comment">-- call the empty function
|
|||
|
</span></code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">my_function</span>
|
|||
|
<span class="l_atom">my_function</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>() <span class="l_keyword">end</span>
|
|||
|
<span class="l_atom">my_function</span>()</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>The 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:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">func_a</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">-></span> <span class="l_builtins">print</span> <span class="l_string">"hello world"</span>
|
|||
|
|
|||
|
<span class="l_atom">func_b</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">-></span>
|
|||
|
<span class="l_atom">value</span> <span class="l_symbol">=</span> <span class="l_number">100</span>
|
|||
|
<span class="l_builtins">print</span> <span class="l_string">"The value:"</span>, <span class="l_atom">value</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">func_a</span>
|
|||
|
<span class="l_atom">func_a</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>()
|
|||
|
<span class="l_keyword">return</span> <span class="l_builtins">print</span>(<span class="l_string">"hello world"</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">func_b</span>
|
|||
|
<span class="l_atom">func_b</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>()
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">value</span> <span class="l_symbol">=</span> <span class="l_number">100</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_builtins">print</span>(<span class="l_string">"The value:"</span>, <span class="l_atom">value</span>)
|
|||
|
<span class="l_keyword">end</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>If a function has no arguments, it can be called using the <code>!</code> operator,
|
|||
|
instead of empty parentheses. The <code>!</code> invocation is the prefered way to call
|
|||
|
functions with no arguments.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">func_a</span><span class="l_symbol">!</span>
|
|||
|
<span class="l_atom">func_b</span>()
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_atom">func_a</span>()
|
|||
|
<span class="l_atom">func_b</span>()</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>Functions with arguments can be created by preceding the arrow with a list of
|
|||
|
argument names in parentheses:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">sum</span> <span class="l_symbol">=</span> (<span class="l_atom">x</span>, <span class="l_atom">y</span>) <span class="l_fn_symbol">-></span> <span class="l_builtins">print</span> <span class="l_string">"sum"</span>, <span class="l_atom">x</span> + <span class="l_atom">y</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">sum</span>
|
|||
|
<span class="l_atom">sum</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">x</span>, <span class="l_atom">y</span>)
|
|||
|
<span class="l_keyword">return</span> <span class="l_builtins">print</span>(<span class="l_string">"sum"</span>, <span class="l_atom">x</span> + <span class="l_atom">y</span>)
|
|||
|
<span class="l_keyword">end</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>Functions can be called by listing the values of the arguments after the name
|
|||
|
of the variable where the function is stored. When chaining together function
|
|||
|
calls, the arguments are applied to the closest function to the left.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">sum</span> <span class="l_number">10</span>, <span class="l_number">20</span>
|
|||
|
<span class="l_builtins">print</span> <span class="l_atom">sum</span> <span class="l_number">10</span>, <span class="l_number">20</span>
|
|||
|
|
|||
|
<span class="l_atom">a</span> <span class="l_atom">b</span> <span class="l_atom">c</span> <span class="l_string">"a"</span>, <span class="l_string">"b"</span>, <span class="l_string">"c"</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_atom">sum</span>(<span class="l_number">10</span>, <span class="l_number">20</span>)
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">sum</span>(<span class="l_number">10</span>, <span class="l_number">20</span>))
|
|||
|
<span class="l_atom">a</span>(<span class="l_atom">b</span>(<span class="l_atom">c</span>(<span class="l_string">"a"</span>, <span class="l_string">"b"</span>, <span class="l_string">"c"</span>)))</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>In 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.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_builtins">print</span> <span class="l_string">"x:"</span>, <span class="l_atom">sum</span>(<span class="l_number">10</span>, <span class="l_number">20</span>), <span class="l_string">"y:"</span>, <span class="l_atom">sum</span>(<span class="l_number">30</span>, <span class="l_number">40</span>)
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_builtins">print</span>(<span class="l_string">"x:"</span>, <span class="l_atom">sum</span>(<span class="l_number">10</span>, <span class="l_number">20</span>), <span class="l_string">"y:"</span>, <span class="l_atom">sum</span>(<span class="l_number">30</span>, <span class="l_number">40</span>))</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>Functions will coerce the last statement in their body into a return statement,
|
|||
|
this is called implicit return:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">sum</span> <span class="l_symbol">=</span> (<span class="l_atom">x</span>, <span class="l_atom">y</span>) <span class="l_fn_symbol">-></span> <span class="l_atom">x</span> + <span class="l_atom">y</span>
|
|||
|
<span class="l_builtins">print</span> <span class="l_string">"The sum is "</span>, <span class="l_atom">sum</span> <span class="l_number">10</span>, <span class="l_number">20</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">sum</span>
|
|||
|
<span class="l_atom">sum</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">x</span>, <span class="l_atom">y</span>)
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">x</span> + <span class="l_atom">y</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_builtins">print</span>(<span class="l_string">"The sum is "</span>, <span class="l_atom">sum</span>(<span class="l_number">10</span>, <span class="l_number">20</span>))</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>And if you need to explicitly return, you can use the <code>return</code> keyword:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">sum</span> <span class="l_symbol">=</span> (<span class="l_atom">x</span>, <span class="l_atom">y</span>) <span class="l_fn_symbol">-></span> <span class="l_keyword">return</span> <span class="l_atom">x</span> + <span class="l_atom">y</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">sum</span>
|
|||
|
<span class="l_atom">sum</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">x</span>, <span class="l_atom">y</span>)
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">x</span> + <span class="l_atom">y</span>
|
|||
|
<span class="l_keyword">end</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>Just like in Lua, functions can return multiple values. The last statement must
|
|||
|
be a list of values separated by commas:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">mystery</span> <span class="l_symbol">=</span> (<span class="l_atom">x</span>, <span class="l_atom">y</span>) <span class="l_fn_symbol">-></span> <span class="l_atom">x</span> + <span class="l_atom">y</span>, <span class="l_atom">x</span> - <span class="l_atom">y</span>
|
|||
|
<span class="l_atom">a</span>,<span class="l_atom">b</span> <span class="l_symbol">=</span> <span class="l_atom">mystery</span> <span class="l_number">10</span>, <span class="l_number">20</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">mystery</span>
|
|||
|
<span class="l_atom">mystery</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">x</span>, <span class="l_atom">y</span>)
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">x</span> + <span class="l_atom">y</span>, <span class="l_atom">x</span> - <span class="l_atom">y</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">a</span>, <span class="l_atom">b</span> <span class="l_symbol">=</span> <span class="l_atom">mystery</span>(<span class="l_number">10</span>, <span class="l_number">20</span>)</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<h3><a name="fat_arrows"></a>Fat Arrows</h3>
|
|||
|
|
|||
|
<p>Because 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 <code>self</code> argument.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">func</span> <span class="l_symbol">=</span> (<span class="l_atom">num</span>) <span class="l_fn_symbol">=></span> <span class="l_self">self</span><span class="l_bold_symbol">.</span><span class="l_atom">value</span> + <span class="l_atom">num</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">func</span>
|
|||
|
<span class="l_atom">func</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">self</span>, <span class="l_atom">num</span>)
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">self</span><span class="l_symbol">.</span><span class="l_atom">value</span> + <span class="l_atom">num</span>
|
|||
|
<span class="l_keyword">end</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<h3><a name="argument_defaults"></a>Argument Defaults</h3>
|
|||
|
|
|||
|
<p>It is possible to provide deafult values for the arguments of a function. An
|
|||
|
argument is determined to be empty if it’s value is <code>nil</code>. Any <code>nil</code> arguments
|
|||
|
that have a default value will be replace before the body of the function is run.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">my_function</span> <span class="l_symbol">=</span> (<span class="l_atom">name</span><span class="l_symbol">=</span><span class="l_string">"something"</span>, <span class="l_atom">height</span><span class="l_symbol">=</span><span class="l_number">100</span>) <span class="l_fn_symbol">-></span>
|
|||
|
<span class="l_builtins">print</span> <span class="l_string">"Hello I am"</span>, <span class="l_atom">name</span>
|
|||
|
<span class="l_builtins">print</span> <span class="l_string">"My height is"</span>, <span class="l_atom">height</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">my_function</span>
|
|||
|
<span class="l_atom">my_function</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">name</span>, <span class="l_atom">height</span>)
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">name</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_special">nil</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_atom">name</span> <span class="l_symbol">=</span> <span class="l_string">"something"</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">height</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_special">nil</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_atom">height</span> <span class="l_symbol">=</span> <span class="l_number">100</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_builtins">print</span>(<span class="l_string">"Hello I am"</span>, <span class="l_atom">name</span>)
|
|||
|
<span class="l_keyword">return</span> <span class="l_builtins">print</span>(<span class="l_string">"My height is"</span>, <span class="l_atom">height</span>)
|
|||
|
<span class="l_keyword">end</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>An 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.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">some_args</span> <span class="l_symbol">=</span> (<span class="l_atom">x</span><span class="l_symbol">=</span><span class="l_number">100</span>, <span class="l_atom">y</span><span class="l_symbol">=</span><span class="l_atom">x</span>+<span class="l_number">1000</span>) <span class="l_fn_symbol">-></span>
|
|||
|
<span class="l_builtins">print</span> <span class="l_atom">x</span> + <span class="l_atom">y</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">some_args</span>
|
|||
|
<span class="l_atom">some_args</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">x</span>, <span class="l_atom">y</span>)
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">x</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_special">nil</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_atom">x</span> <span class="l_symbol">=</span> <span class="l_number">100</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">y</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_special">nil</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_atom">y</span> <span class="l_symbol">=</span> <span class="l_atom">x</span> + <span class="l_number">1000</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_builtins">print</span>(<span class="l_atom">x</span> + <span class="l_atom">y</span>)
|
|||
|
<span class="l_keyword">end</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<h3><a name="considerations"></a>Considerations</h3>
|
|||
|
|
|||
|
<p>Because of the expressive parentheses-less way of calling functions, some
|
|||
|
restrictions must be put in place to avoid parsing ambiguity involving
|
|||
|
whitespace.</p>
|
|||
|
|
|||
|
<p>The minus sign plays two roles, a unary negation operator and a binary
|
|||
|
subtraction operator. In order to force subtraction a space must be placed
|
|||
|
after the <code>-</code> operator. In order to force a negation, no space must follow
|
|||
|
the <code>-</code>. Consider the examples below.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">a</span> <span class="l_symbol">=</span> <span class="l_atom">x</span> - <span class="l_number">10</span>
|
|||
|
<span class="l_atom">b</span> <span class="l_symbol">=</span> <span class="l_atom">x</span><span class="l_number">-10</span>
|
|||
|
<span class="l_atom">c</span> <span class="l_symbol">=</span> <span class="l_atom">x</span> -<span class="l_atom">y</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">a</span> <span class="l_symbol">=</span> <span class="l_atom">x</span> - <span class="l_number">10</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">b</span> <span class="l_symbol">=</span> <span class="l_atom">x</span>(<span class="l_number">-10</span>)
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">c</span> <span class="l_symbol">=</span> <span class="l_atom">x</span>(-<span class="l_atom">y</span>)</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>The precedence of the first argument of a function call can also 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 literal.</p>
|
|||
|
|
|||
|
<p>When there is no space between a variable and a string literal, the
|
|||
|
function call takes precedence over any following expressions. No other
|
|||
|
arguments can be passed to the function when it is called this way.</p>
|
|||
|
|
|||
|
<p>Where 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.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">x</span> <span class="l_symbol">=</span> <span class="l_atom">func</span><span class="l_string">"hello"</span> + <span class="l_number">100</span>
|
|||
|
<span class="l_atom">y</span> <span class="l_symbol">=</span> <span class="l_atom">func</span> <span class="l_string">"hello"</span> + <span class="l_number">100</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">x</span> <span class="l_symbol">=</span> <span class="l_atom">func</span>(<span class="l_string">"hello"</span>) + <span class="l_number">100</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">y</span> <span class="l_symbol">=</span> <span class="l_atom">func</span>(<span class="l_string">"hello"</span> + <span class="l_number">100</span>)</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<h2><a name="table_literals"></a>Table Literals</h2>
|
|||
|
|
|||
|
<p>Like in Lua, tables are delimited in curly braces.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">some_values</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">{</span> <span class="l_number">1</span>, <span class="l_number">2</span>, <span class="l_number">3</span>, <span class="l_number">4</span> <span class="l_fn_symbol">}</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">some_values</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span>
|
|||
|
<span class="l_number">1</span>,
|
|||
|
<span class="l_number">2</span>,
|
|||
|
<span class="l_number">3</span>,
|
|||
|
<span class="l_number">4</span>
|
|||
|
<span class="l_symbol">}</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>Unlike Lua, assigning a value to a key in a table is done with <code>:</code> (instead of
|
|||
|
<code>=</code>).</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">some_values</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">{</span>
|
|||
|
<span class="l_table_key">name</span><span class="l_bold_symbol">:</span> <span class="l_string">"Bill"</span>,
|
|||
|
<span class="l_table_key">age</span><span class="l_bold_symbol">:</span> <span class="l_number">200</span>,
|
|||
|
<span class="l_fn_symbol">[</span><span class="l_string">"favorite food"</span><span class="l_fn_symbol">]</span><span class="l_bold_symbol">:</span> <span class="l_string">"rice"</span>
|
|||
|
<span class="l_fn_symbol">}</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">some_values</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span>
|
|||
|
<span class="l_atom">name</span> <span class="l_symbol">=</span> <span class="l_string">"Bill"</span>,
|
|||
|
<span class="l_atom">age</span> <span class="l_symbol">=</span> <span class="l_number">200</span>,
|
|||
|
[<span class="l_string">"favorite food"</span>] <span class="l_symbol">=</span> <span class="l_string">"rice"</span>
|
|||
|
<span class="l_symbol">}</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>The curly braces can be left off if a single table of key value pairs is being
|
|||
|
assigned.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">profile</span> <span class="l_symbol">=</span>
|
|||
|
<span class="l_table_key">height</span><span class="l_bold_symbol">:</span> <span class="l_string">"4 feet"</span>,
|
|||
|
<span class="l_table_key">shoe_size</span><span class="l_bold_symbol">:</span> <span class="l_number">13</span>,
|
|||
|
<span class="l_table_key">favorite_foods</span><span class="l_bold_symbol">:</span> <span class="l_fn_symbol">{</span><span class="l_string">"ice cream"</span>, <span class="l_string">"donuts"</span><span class="l_fn_symbol">}</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">profile</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span>
|
|||
|
<span class="l_atom">height</span> <span class="l_symbol">=</span> <span class="l_string">"4 feet"</span>,
|
|||
|
<span class="l_atom">shoe_size</span> <span class="l_symbol">=</span> <span class="l_number">13</span>,
|
|||
|
<span class="l_atom">favorite_foods</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span>
|
|||
|
<span class="l_string">"ice cream"</span>,
|
|||
|
<span class="l_string">"donuts"</span>
|
|||
|
<span class="l_symbol">}</span>
|
|||
|
<span class="l_symbol">}</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>Newlines can be used to delimit values instead of a comma (or both):</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">values</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">{</span>
|
|||
|
<span class="l_number">1</span>,<span class="l_number">2</span>,<span class="l_number">3</span>,<span class="l_number">4</span>
|
|||
|
<span class="l_number">5</span>,<span class="l_number">6</span>,<span class="l_number">7</span>,<span class="l_number">8</span>
|
|||
|
<span class="l_table_key">name</span><span class="l_bold_symbol">:</span> <span class="l_string">"superman"</span>
|
|||
|
<span class="l_table_key">occupation</span><span class="l_bold_symbol">:</span> <span class="l_string">"crime fighting"</span>
|
|||
|
<span class="l_fn_symbol">}</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">values</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span>
|
|||
|
<span class="l_number">1</span>,
|
|||
|
<span class="l_number">2</span>,
|
|||
|
<span class="l_number">3</span>,
|
|||
|
<span class="l_number">4</span>,
|
|||
|
<span class="l_number">5</span>,
|
|||
|
<span class="l_number">6</span>,
|
|||
|
<span class="l_number">7</span>,
|
|||
|
<span class="l_number">8</span>,
|
|||
|
<span class="l_atom">name</span> <span class="l_symbol">=</span> <span class="l_string">"superman"</span>,
|
|||
|
<span class="l_atom">occupation</span> <span class="l_symbol">=</span> <span class="l_string">"crime fighting"</span>
|
|||
|
<span class="l_symbol">}</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>When creating a single line table literal, the curly braces can also be left
|
|||
|
off:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">my_function</span> <span class="l_table_key">dance</span><span class="l_bold_symbol">:</span> <span class="l_string">"Tango"</span>, <span class="l_table_key">partner</span><span class="l_bold_symbol">:</span> <span class="l_string">"none"</span>
|
|||
|
|
|||
|
<span class="l_atom">y</span> <span class="l_symbol">=</span> <span class="l_table_key">type</span><span class="l_bold_symbol">:</span> <span class="l_string">"dog"</span>, <span class="l_table_key">legs</span><span class="l_bold_symbol">:</span> <span class="l_number">4</span>, <span class="l_table_key">tails</span><span class="l_bold_symbol">:</span> <span class="l_number">1</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_atom">my_function</span>(<span class="l_symbol">{</span>
|
|||
|
<span class="l_atom">dance</span> <span class="l_symbol">=</span> <span class="l_string">"Tango"</span>,
|
|||
|
<span class="l_atom">partner</span> <span class="l_symbol">=</span> <span class="l_string">"none"</span>
|
|||
|
<span class="l_symbol">}</span>)
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">y</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span>
|
|||
|
<span class="l_atom">type</span> <span class="l_symbol">=</span> <span class="l_string">"dog"</span>,
|
|||
|
<span class="l_atom">legs</span> <span class="l_symbol">=</span> <span class="l_number">4</span>,
|
|||
|
<span class="l_atom">tails</span> <span class="l_symbol">=</span> <span class="l_number">1</span>
|
|||
|
<span class="l_symbol">}</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<h2><a name="table_comprehensions"></a>Table Comprehensions</h2>
|
|||
|
|
|||
|
<p>Table comprehensions provide a quick way to iterate over a table’s values while
|
|||
|
applying a statement and accumulating the result.</p>
|
|||
|
|
|||
|
<p>The following creates a copy of the <code>items</code> table but with all the values
|
|||
|
doubled.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">items</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">{</span> <span class="l_number">1</span>, <span class="l_number">2</span>, <span class="l_number">3</span>, <span class="l_number">4</span> <span class="l_fn_symbol">}</span>
|
|||
|
<span class="l_atom">doubled</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">[</span><span class="l_atom">item</span> <span class="l_symbol">*</span> <span class="l_number">2</span> <span class="l_keyword">for</span> <span class="l_atom">i</span>, <span class="l_atom">item</span> <span class="l_keyword">in</span> <span class="l_builtins">ipairs</span> <span class="l_atom">items</span><span class="l_fn_symbol">]</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">items</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span>
|
|||
|
<span class="l_number">1</span>,
|
|||
|
<span class="l_number">2</span>,
|
|||
|
<span class="l_number">3</span>,
|
|||
|
<span class="l_number">4</span>
|
|||
|
<span class="l_symbol">}</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">doubled</span> <span class="l_symbol">=</span> (<span class="l_fn_symbol">function</span>()
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_accum_0</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span> <span class="l_symbol">}</span>
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">i</span>, <span class="l_atom">item</span> <span class="l_atom">in</span> <span class="l_builtins">ipairs</span>(<span class="l_atom">items</span>) <span class="l_keyword">do</span>
|
|||
|
<span class="l_builtins">table.insert</span>(<span class="l_atom">_accum_0</span>, <span class="l_atom">item</span> * <span class="l_number">2</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">_accum_0</span>
|
|||
|
<span class="l_keyword">end</span>)()</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>The items included in the new table can be restricted with a <code>when</code> clause:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">iter</span> <span class="l_symbol">=</span> <span class="l_builtins">ipairs</span> <span class="l_atom">items</span>
|
|||
|
<span class="l_atom">slice</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">[</span><span class="l_atom">item</span> <span class="l_keyword">for</span> <span class="l_atom">i</span>, <span class="l_atom">item</span> <span class="l_keyword">in</span> <span class="l_atom">iter</span> <span class="l_keyword">when</span> <span class="l_atom">i</span> <span class="l_symbol">></span> <span class="l_number">1</span> <span class="l_keyword">and</span> <span class="l_atom">i</span> <span class="l_symbol"><</span> <span class="l_number">3</span><span class="l_fn_symbol">]</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">iter</span> <span class="l_symbol">=</span> <span class="l_builtins">ipairs</span>(<span class="l_atom">items</span>)
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">slice</span> <span class="l_symbol">=</span> (<span class="l_fn_symbol">function</span>()
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_accum_0</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span> <span class="l_symbol">}</span>
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">i</span>, <span class="l_atom">item</span> <span class="l_atom">in</span> <span class="l_atom">iter</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">i</span> > <span class="l_number">1</span> <span class="l_keyword">and</span> <span class="l_atom">i</span> < <span class="l_number">3</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_builtins">table.insert</span>(<span class="l_atom">_accum_0</span>, <span class="l_atom">item</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">_accum_0</span>
|
|||
|
<span class="l_keyword">end</span>)()</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>Because it is common to iterate over the values of a numerically indexed table,
|
|||
|
an <code>*</code> operator is introduced. The doubled example can be rewritten as:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">doubled</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">[</span><span class="l_atom">item</span> <span class="l_symbol">*</span> <span class="l_number">2</span> <span class="l_keyword">for</span> <span class="l_atom">item</span> <span class="l_keyword">in</span> <span class="l_symbol">*</span><span class="l_atom">items</span><span class="l_fn_symbol">]</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">doubled</span> <span class="l_symbol">=</span> (<span class="l_fn_symbol">function</span>()
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_accum_0</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span> <span class="l_symbol">}</span>
|
|||
|
<span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_item_0</span> <span class="l_symbol">=</span> <span class="l_atom">items</span>
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">_index_0</span> <span class="l_symbol">=</span> <span class="l_number">1</span>, #<span class="l_atom">_item_0</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">item</span> <span class="l_symbol">=</span> <span class="l_atom">_item_0</span>[<span class="l_atom">_index_0</span>]
|
|||
|
<span class="l_builtins">table.insert</span>(<span class="l_atom">_accum_0</span>, <span class="l_atom">item</span> * <span class="l_number">2</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">_accum_0</span>
|
|||
|
<span class="l_keyword">end</span>)()</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>The <code>for</code> and <code>when</code> clauses can be chained as much as desired. The only
|
|||
|
requirement is that a comprehension has at least one <code>for</code> clause.</p>
|
|||
|
|
|||
|
<p>Using multiple <code>for</code> clauses is the same as using nested loops:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">x_coords</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">{</span><span class="l_number">4</span>, <span class="l_number">5</span>, <span class="l_number">6</span>, <span class="l_number">7</span><span class="l_fn_symbol">}</span>
|
|||
|
<span class="l_atom">y_coords</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">{</span><span class="l_number">9</span>, <span class="l_number">2</span>, <span class="l_number">3</span><span class="l_fn_symbol">}</span>
|
|||
|
|
|||
|
<span class="l_atom">points</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">[</span><span class="l_fn_symbol">{</span><span class="l_atom">x</span>,<span class="l_atom">y</span><span class="l_fn_symbol">}</span> <span class="l_keyword">for</span> <span class="l_atom">x</span> <span class="l_keyword">in</span> <span class="l_symbol">*</span><span class="l_atom">x_coords</span> <span class="l_keyword">for</span> <span class="l_atom">y</span> <span class="l_keyword">in</span> <span class="l_symbol">*</span><span class="l_atom">y_coords</span><span class="l_fn_symbol">]</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">x_coords</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span>
|
|||
|
<span class="l_number">4</span>,
|
|||
|
<span class="l_number">5</span>,
|
|||
|
<span class="l_number">6</span>,
|
|||
|
<span class="l_number">7</span>
|
|||
|
<span class="l_symbol">}</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">y_coords</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span>
|
|||
|
<span class="l_number">9</span>,
|
|||
|
<span class="l_number">2</span>,
|
|||
|
<span class="l_number">3</span>
|
|||
|
<span class="l_symbol">}</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">points</span> <span class="l_symbol">=</span> (<span class="l_fn_symbol">function</span>()
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_accum_0</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span> <span class="l_symbol">}</span>
|
|||
|
<span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_item_0</span> <span class="l_symbol">=</span> <span class="l_atom">x_coords</span>
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">_index_0</span> <span class="l_symbol">=</span> <span class="l_number">1</span>, #<span class="l_atom">_item_0</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">x</span> <span class="l_symbol">=</span> <span class="l_atom">_item_0</span>[<span class="l_atom">_index_0</span>]
|
|||
|
<span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_item_1</span> <span class="l_symbol">=</span> <span class="l_atom">y_coords</span>
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">_index_1</span> <span class="l_symbol">=</span> <span class="l_number">1</span>, #<span class="l_atom">_item_1</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">y</span> <span class="l_symbol">=</span> <span class="l_atom">_item_1</span>[<span class="l_atom">_index_1</span>]
|
|||
|
<span class="l_builtins">table.insert</span>(<span class="l_atom">_accum_0</span>, <span class="l_symbol">{</span>
|
|||
|
<span class="l_atom">x</span>,
|
|||
|
<span class="l_atom">y</span>
|
|||
|
<span class="l_symbol">}</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">_accum_0</span>
|
|||
|
<span class="l_keyword">end</span>)()</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<h3><a name="slicing"></a>Slicing</h3>
|
|||
|
|
|||
|
<p>A special syntax is provided to restrict the items that are iterated over when
|
|||
|
using the <code>*</code> operator. This is equivalent to setting the iteration bounds and
|
|||
|
a step size in a <code>for</code> loop.</p>
|
|||
|
|
|||
|
<p>Here we can set the minimum and maximum bounds, taking all items with indexes
|
|||
|
between 1 and 5 inclusive:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">slice</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">[</span><span class="l_atom">item</span> <span class="l_keyword">for</span> <span class="l_atom">item</span> <span class="l_keyword">in</span> <span class="l_symbol">*</span><span class="l_atom">items</span><span class="l_fn_symbol">[</span><span class="l_number">1</span><span class="l_bold_symbol">:</span><span class="l_number">5</span><span class="l_fn_symbol">]</span><span class="l_fn_symbol">]</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">slice</span> <span class="l_symbol">=</span> (<span class="l_fn_symbol">function</span>()
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_accum_0</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span> <span class="l_symbol">}</span>
|
|||
|
<span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_max_0</span> <span class="l_symbol">=</span> <span class="l_number">5</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_item_0</span> <span class="l_symbol">=</span> <span class="l_atom">items</span>
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">_index_0</span> <span class="l_symbol">=</span> <span class="l_number">1</span>, <span class="l_atom">_max_0</span> < <span class="l_number">0</span> <span class="l_keyword">and</span> #<span class="l_atom">_item_0</span> + <span class="l_atom">_max_0</span> <span class="l_keyword">or</span> <span class="l_atom">_max_0</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">item</span> <span class="l_symbol">=</span> <span class="l_atom">_item_0</span>[<span class="l_atom">_index_0</span>]
|
|||
|
<span class="l_builtins">table.insert</span>(<span class="l_atom">_accum_0</span>, <span class="l_atom">item</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">_accum_0</span>
|
|||
|
<span class="l_keyword">end</span>)()</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>Any 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:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">slice</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">[</span><span class="l_atom">item</span> <span class="l_keyword">for</span> <span class="l_atom">item</span> <span class="l_keyword">in</span> <span class="l_symbol">*</span><span class="l_atom">items</span><span class="l_fn_symbol">[</span><span class="l_number">1</span><span class="l_bold_symbol">:</span><span class="l_fn_symbol">]</span><span class="l_fn_symbol">]</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">slice</span> <span class="l_symbol">=</span> (<span class="l_fn_symbol">function</span>()
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_accum_0</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span> <span class="l_symbol">}</span>
|
|||
|
<span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_item_0</span> <span class="l_symbol">=</span> <span class="l_atom">items</span>
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">_index_0</span> <span class="l_symbol">=</span> <span class="l_number">1</span>, #<span class="l_atom">_item_0</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">item</span> <span class="l_symbol">=</span> <span class="l_atom">_item_0</span>[<span class="l_atom">_index_0</span>]
|
|||
|
<span class="l_builtins">table.insert</span>(<span class="l_atom">_accum_0</span>, <span class="l_atom">item</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">_accum_0</span>
|
|||
|
<span class="l_keyword">end</span>)()</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>If 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, …)</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">slice</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">[</span><span class="l_atom">item</span> <span class="l_keyword">for</span> <span class="l_atom">items</span> <span class="l_keyword">in</span> <span class="l_symbol">*</span><span class="l_atom">items</span><span class="l_fn_symbol">[</span><span class="l_bold_symbol">:</span><span class="l_bold_symbol">:</span><span class="l_number">2</span><span class="l_fn_symbol">]</span><span class="l_fn_symbol">]</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">slice</span> <span class="l_symbol">=</span> (<span class="l_fn_symbol">function</span>()
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_accum_0</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span> <span class="l_symbol">}</span>
|
|||
|
<span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_item_0</span> <span class="l_symbol">=</span> <span class="l_atom">items</span>
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">_index_0</span> <span class="l_symbol">=</span> <span class="l_number">1</span>, #<span class="l_atom">_item_0</span>, <span class="l_number">2</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">items</span> <span class="l_symbol">=</span> <span class="l_atom">_item_0</span>[<span class="l_atom">_index_0</span>]
|
|||
|
<span class="l_builtins">table.insert</span>(<span class="l_atom">_accum_0</span>, <span class="l_atom">item</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">_accum_0</span>
|
|||
|
<span class="l_keyword">end</span>)()</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<h2><a name="for_loop"></a>For Loop</h2>
|
|||
|
|
|||
|
<p>There are two for loop forms, just like in Lua. A numeric one and a generic one:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_keyword">for</span> <span class="l_atom">i</span> <span class="l_symbol">=</span> <span class="l_number">10</span>, <span class="l_number">20</span>
|
|||
|
<span class="l_builtins">print</span> <span class="l_atom">i</span>
|
|||
|
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">k</span> <span class="l_symbol">=</span> <span class="l_number">1</span>,<span class="l_number">15</span>,<span class="l_number">2</span> <span class="l_comment">-- an optional step provided
|
|||
|
</span> <span class="l_builtins">print</span> <span class="l_atom">k</span>
|
|||
|
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">key</span>, <span class="l_atom">value</span> <span class="l_keyword">in</span> <span class="l_builtins">pairs</span> <span class="l_atom">object</span>
|
|||
|
<span class="l_builtins">print</span> <span class="l_atom">key</span>, <span class="l_atom">value</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">for</span> <span class="l_atom">i</span> <span class="l_symbol">=</span> <span class="l_number">10</span>, <span class="l_number">20</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">i</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">k</span> <span class="l_symbol">=</span> <span class="l_number">1</span>, <span class="l_number">15</span>, <span class="l_number">2</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">k</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">key</span>, <span class="l_atom">value</span> <span class="l_atom">in</span> <span class="l_builtins">pairs</span>(<span class="l_atom">object</span>) <span class="l_keyword">do</span>
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">key</span>, <span class="l_atom">value</span>)
|
|||
|
<span class="l_keyword">end</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>The slicing and <code>*</code> operators can be used, just like with table comprehensions:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_keyword">for</span> <span class="l_atom">item</span> <span class="l_keyword">in</span> <span class="l_symbol">*</span><span class="l_atom">items</span><span class="l_fn_symbol">[</span><span class="l_number">2</span><span class="l_bold_symbol">:</span><span class="l_number">4</span><span class="l_fn_symbol">]</span>
|
|||
|
<span class="l_builtins">print</span> <span class="l_atom">item</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_max_0</span> <span class="l_symbol">=</span> <span class="l_number">4</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_item_0</span> <span class="l_symbol">=</span> <span class="l_atom">items</span>
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">_index_0</span> <span class="l_symbol">=</span> <span class="l_number">2</span>, <span class="l_atom">_max_0</span> < <span class="l_number">0</span> <span class="l_keyword">and</span> #<span class="l_atom">_item_0</span> + <span class="l_atom">_max_0</span> <span class="l_keyword">or</span> <span class="l_atom">_max_0</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">item</span> <span class="l_symbol">=</span> <span class="l_atom">_item_0</span>[<span class="l_atom">_index_0</span>]
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">item</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>A shorter syntax is also available for all variations when the body is only a
|
|||
|
single line:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_keyword">for</span> <span class="l_atom">item</span> <span class="l_keyword">in</span> <span class="l_symbol">*</span><span class="l_atom">items</span> <span class="l_keyword">do</span> <span class="l_builtins">print</span> <span class="l_atom">item</span>
|
|||
|
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">j</span> <span class="l_symbol">=</span> <span class="l_number">1</span>,<span class="l_number">10</span>,<span class="l_number">3</span> <span class="l_keyword">do</span> <span class="l_builtins">print</span> <span class="l_atom">j</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_item_0</span> <span class="l_symbol">=</span> <span class="l_atom">items</span>
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">_index_0</span> <span class="l_symbol">=</span> <span class="l_number">1</span>, #<span class="l_atom">_item_0</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">item</span> <span class="l_symbol">=</span> <span class="l_atom">_item_0</span>[<span class="l_atom">_index_0</span>]
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">item</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">j</span> <span class="l_symbol">=</span> <span class="l_number">1</span>, <span class="l_number">10</span>, <span class="l_number">3</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">j</span>)
|
|||
|
<span class="l_keyword">end</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>A for loop can also be used an expression. The last statement in the body of
|
|||
|
the for loop is coerced into an expression and appended to an accumulating
|
|||
|
table if the value of that expression is not nil.</p>
|
|||
|
|
|||
|
<p>Doubling every even number:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">doubled_evens</span> <span class="l_symbol">=</span> <span class="l_keyword">for</span> <span class="l_atom">i</span><span class="l_symbol">=</span><span class="l_number">1</span>,<span class="l_number">20</span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">i</span> % <span class="l_number">2</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_number">0</span>
|
|||
|
<span class="l_atom">i</span> <span class="l_symbol">*</span> <span class="l_number">2</span>
|
|||
|
<span class="l_keyword">else</span>
|
|||
|
<span class="l_atom">i</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">doubled_evens</span> <span class="l_symbol">=</span> (<span class="l_fn_symbol">function</span>()
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_accum_0</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span> <span class="l_symbol">}</span>
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">i</span> <span class="l_symbol">=</span> <span class="l_number">1</span>, <span class="l_number">20</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_value_0</span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">i</span> % <span class="l_number">2</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_number">0</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_atom">_value_0</span> <span class="l_symbol">=</span> <span class="l_atom">i</span> * <span class="l_number">2</span>
|
|||
|
<span class="l_keyword">else</span>
|
|||
|
<span class="l_atom">_value_0</span> <span class="l_symbol">=</span> <span class="l_atom">i</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">_value_0</span> ~<span class="l_symbol">=</span> <span class="l_special">nil</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_builtins">table.insert</span>(<span class="l_atom">_accum_0</span>, <span class="l_atom">_value_0</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">_accum_0</span>
|
|||
|
<span class="l_keyword">end</span>)()</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>Filtering out odd numbers:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">my_numbers</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">{</span><span class="l_number">1</span>,<span class="l_number">2</span>,<span class="l_number">3</span>,<span class="l_number">4</span>,<span class="l_number">5</span>,<span class="l_number">6</span><span class="l_fn_symbol">}</span>
|
|||
|
<span class="l_atom">odds</span> <span class="l_symbol">=</span> <span class="l_keyword">for</span> <span class="l_atom">x</span> <span class="l_keyword">in</span> <span class="l_symbol">*</span><span class="l_atom">my_numbers</span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">x</span> % <span class="l_number">2</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_number">1</span> <span class="l_keyword">then</span> <span class="l_atom">x</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">my_numbers</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span>
|
|||
|
<span class="l_number">1</span>,
|
|||
|
<span class="l_number">2</span>,
|
|||
|
<span class="l_number">3</span>,
|
|||
|
<span class="l_number">4</span>,
|
|||
|
<span class="l_number">5</span>,
|
|||
|
<span class="l_number">6</span>
|
|||
|
<span class="l_symbol">}</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">odds</span> <span class="l_symbol">=</span> (<span class="l_fn_symbol">function</span>()
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_accum_0</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span> <span class="l_symbol">}</span>
|
|||
|
<span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_item_0</span> <span class="l_symbol">=</span> <span class="l_atom">my_numbers</span>
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">_index_0</span> <span class="l_symbol">=</span> <span class="l_number">1</span>, #<span class="l_atom">_item_0</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">x</span> <span class="l_symbol">=</span> <span class="l_atom">_item_0</span>[<span class="l_atom">_index_0</span>]
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_value_0</span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">x</span> % <span class="l_number">2</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_number">1</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_atom">_value_0</span> <span class="l_symbol">=</span> <span class="l_atom">x</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">_value_0</span> ~<span class="l_symbol">=</span> <span class="l_special">nil</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_builtins">table.insert</span>(<span class="l_atom">_accum_0</span>, <span class="l_atom">_value_0</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">_accum_0</span>
|
|||
|
<span class="l_keyword">end</span>)()</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>For loops at the end of a function body are not accumulated into a table for a
|
|||
|
return value (Instead the function will return <code>nil</code>). Either an explicit
|
|||
|
<code>return</code> statement can be used, or the loop can be converted into a list
|
|||
|
comprehension.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">func_a</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">-></span> <span class="l_keyword">for</span> <span class="l_atom">i</span><span class="l_symbol">=</span><span class="l_number">1</span>,<span class="l_number">10</span> <span class="l_keyword">do</span> <span class="l_atom">i</span>
|
|||
|
<span class="l_atom">func_b</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">-></span> <span class="l_keyword">return</span> <span class="l_keyword">for</span> <span class="l_atom">i</span><span class="l_symbol">=</span><span class="l_number">1</span>,<span class="l_number">10</span> <span class="l_keyword">do</span> <span class="l_atom">i</span>
|
|||
|
|
|||
|
<span class="l_builtins">print</span> <span class="l_atom">func_a</span><span class="l_symbol">!</span> <span class="l_comment">-- prints nil
|
|||
|
</span><span class="l_builtins">print</span> <span class="l_atom">func_b</span><span class="l_symbol">!</span> <span class="l_comment">-- prints table object
|
|||
|
</span></code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">func_a</span>
|
|||
|
<span class="l_atom">func_a</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>()
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">i</span> <span class="l_symbol">=</span> <span class="l_number">1</span>, <span class="l_number">10</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_</span> <span class="l_symbol">=</span> <span class="l_atom">i</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">func_b</span>
|
|||
|
<span class="l_atom">func_b</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>()
|
|||
|
<span class="l_keyword">return</span> (<span class="l_fn_symbol">function</span>()
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_accum_0</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span> <span class="l_symbol">}</span>
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">i</span> <span class="l_symbol">=</span> <span class="l_number">1</span>, <span class="l_number">10</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_value_0</span> <span class="l_symbol">=</span> <span class="l_atom">i</span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">_value_0</span> ~<span class="l_symbol">=</span> <span class="l_special">nil</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_builtins">table.insert</span>(<span class="l_atom">_accum_0</span>, <span class="l_atom">_value_0</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">_accum_0</span>
|
|||
|
<span class="l_keyword">end</span>)()
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">func_a</span>())
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">func_b</span>())</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>This is done to avoid the needless creation of tables for functions that don’t
|
|||
|
need to return the results of the loop.</p>
|
|||
|
|
|||
|
<h2><a name="while_loop"></a>While Loop</h2>
|
|||
|
|
|||
|
<p>The while loop also comes in two variations:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">i</span> <span class="l_symbol">=</span> <span class="l_number">10</span>
|
|||
|
<span class="l_keyword">while</span> <span class="l_atom">i</span> <span class="l_symbol">></span> <span class="l_number">0</span>
|
|||
|
<span class="l_builtins">print</span> <span class="l_atom">i</span>
|
|||
|
<span class="l_atom">i</span> <span class="l_symbol">-=</span> <span class="l_number">1</span>
|
|||
|
|
|||
|
<span class="l_keyword">while</span> <span class="l_atom">running</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_special">true</span> <span class="l_keyword">do</span> <span class="l_atom">my_function</span><span class="l_symbol">!</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">i</span> <span class="l_symbol">=</span> <span class="l_number">10</span>
|
|||
|
<span class="l_atom">while</span> <span class="l_atom">i</span> > <span class="l_number">0</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">i</span>)
|
|||
|
<span class="l_atom">i</span> <span class="l_symbol">=</span> <span class="l_atom">i</span> - <span class="l_number">1</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_atom">while</span> <span class="l_atom">running</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_special">true</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_atom">my_function</span>()
|
|||
|
<span class="l_keyword">end</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>Like for loops, the while loop can also be used an expression. Additionally,
|
|||
|
for a function to return the accumlated value of a while loop, the statement
|
|||
|
must be explicitly returned.</p>
|
|||
|
|
|||
|
<h2><a name="conditionals"></a>Conditionals</h2>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">have_coins</span> <span class="l_symbol">=</span> <span class="l_special">false</span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">have_coins</span>
|
|||
|
<span class="l_builtins">print</span> <span class="l_string">"Got coins"</span>
|
|||
|
<span class="l_keyword">else</span>
|
|||
|
<span class="l_builtins">print</span> <span class="l_string">"No coins"</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">have_coins</span> <span class="l_symbol">=</span> <span class="l_special">false</span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">have_coins</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_builtins">print</span>(<span class="l_string">"Got coins"</span>)
|
|||
|
<span class="l_keyword">else</span>
|
|||
|
<span class="l_builtins">print</span>(<span class="l_string">"No coins"</span>)
|
|||
|
<span class="l_keyword">end</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>A short syntax for single statements can also be used:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">have_coins</span> <span class="l_symbol">=</span> <span class="l_special">false</span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">have_coins</span> <span class="l_keyword">then</span> <span class="l_builtins">print</span> <span class="l_string">"Got coins"</span> <span class="l_keyword">else</span> <span class="l_builtins">print</span> <span class="l_string">"No coins"</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">have_coins</span> <span class="l_symbol">=</span> <span class="l_special">false</span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">have_coins</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_builtins">print</span>(<span class="l_string">"Got coins"</span>)
|
|||
|
<span class="l_keyword">else</span>
|
|||
|
<span class="l_builtins">print</span>(<span class="l_string">"No coins"</span>)
|
|||
|
<span class="l_keyword">end</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>Because if statements can be used as expressions, this can able be written as:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">have_coins</span> <span class="l_symbol">=</span> <span class="l_special">false</span>
|
|||
|
<span class="l_builtins">print</span> <span class="l_keyword">if</span> <span class="l_atom">have_coins</span> <span class="l_keyword">then</span> <span class="l_string">"Got coins"</span> <span class="l_keyword">else</span> <span class="l_string">"No coins"</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">have_coins</span> <span class="l_symbol">=</span> <span class="l_special">false</span>
|
|||
|
<span class="l_builtins">print</span>((<span class="l_fn_symbol">function</span>()
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">have_coins</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_string">"Got coins"</span>
|
|||
|
<span class="l_keyword">else</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_string">"No coins"</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>)())</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>Conditionals can also be used in return statements and assignments:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">is_tall</span> <span class="l_symbol">=</span> (<span class="l_atom">name</span>) <span class="l_fn_symbol">-></span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">name</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_string">"Rob"</span>
|
|||
|
<span class="l_special">true</span>
|
|||
|
<span class="l_keyword">else</span>
|
|||
|
<span class="l_special">false</span>
|
|||
|
|
|||
|
<span class="l_atom">message</span> <span class="l_symbol">=</span> <span class="l_keyword">if</span> <span class="l_atom">is_tall</span> <span class="l_string">"Rob"</span>
|
|||
|
<span class="l_string">"I am very tall"</span>
|
|||
|
<span class="l_keyword">else</span>
|
|||
|
<span class="l_string">"I am not so tall"</span>
|
|||
|
|
|||
|
<span class="l_builtins">print</span> <span class="l_atom">message</span> <span class="l_comment">-- prints: I am very tall
|
|||
|
</span></code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">is_tall</span>
|
|||
|
<span class="l_atom">is_tall</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">name</span>)
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">name</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_string">"Rob"</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_special">true</span>
|
|||
|
<span class="l_keyword">else</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_special">false</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">message</span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">is_tall</span>(<span class="l_string">"Rob"</span>) <span class="l_keyword">then</span>
|
|||
|
<span class="l_atom">message</span> <span class="l_symbol">=</span> <span class="l_string">"I am very tall"</span>
|
|||
|
<span class="l_keyword">else</span>
|
|||
|
<span class="l_atom">message</span> <span class="l_symbol">=</span> <span class="l_string">"I am not so tall"</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">message</span>)</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<h2><a name="line_decorators"></a>Line Decorators</h2>
|
|||
|
|
|||
|
<p>For convenience, the for loop and if statement can be applied to single
|
|||
|
statements at the end of the line:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_builtins">print</span> <span class="l_string">"hello world"</span> <span class="l_keyword">if</span> <span class="l_atom">name</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_string">"Rob"</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">if</span> <span class="l_atom">name</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_string">"Rob"</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_builtins">print</span>(<span class="l_string">"hello world"</span>)
|
|||
|
<span class="l_keyword">end</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>And with basic loops:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_builtins">print</span> <span class="l_string">"item: "</span>, <span class="l_atom">item</span> <span class="l_keyword">for</span> <span class="l_atom">item</span> <span class="l_keyword">in</span> <span class="l_symbol">*</span><span class="l_atom">items</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_item_0</span> <span class="l_symbol">=</span> <span class="l_atom">items</span>
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">_index_0</span> <span class="l_symbol">=</span> <span class="l_number">1</span>, #<span class="l_atom">_item_0</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">item</span> <span class="l_symbol">=</span> <span class="l_atom">_item_0</span>[<span class="l_atom">_index_0</span>]
|
|||
|
<span class="l_builtins">print</span>(<span class="l_string">"item: "</span>, <span class="l_atom">item</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<h2><a name="object_oriented_programming"></a>Object Oriented Programming</h2>
|
|||
|
|
|||
|
<p>In these examples, the generated Lua code may appear overwhelming. It is best
|
|||
|
to focus on the meaning of the MoonScript code at first, then look into the Lua
|
|||
|
code if you wish to know the implementation details.</p>
|
|||
|
|
|||
|
<p>A simple class:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_keyword">class</span> <span class="l_proper">Inventory</span>
|
|||
|
<span class="l_table_key">new</span><span class="l_bold_symbol">:</span> <span class="l_fn_symbol">=></span>
|
|||
|
<span class="l_self_var">@items</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">{</span><span class="l_fn_symbol">}</span>
|
|||
|
|
|||
|
<span class="l_table_key">add_item</span><span class="l_bold_symbol">:</span> (<span class="l_atom">name</span>) <span class="l_fn_symbol">=></span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_self_var">@items</span><span class="l_fn_symbol">[</span><span class="l_atom">name</span><span class="l_fn_symbol">]</span>
|
|||
|
<span class="l_self_var">@items</span><span class="l_fn_symbol">[</span><span class="l_atom">name</span><span class="l_fn_symbol">]</span> <span class="l_symbol">+=</span> <span class="l_number">1</span>
|
|||
|
<span class="l_keyword">else</span>
|
|||
|
<span class="l_self_var">@items</span><span class="l_fn_symbol">[</span><span class="l_atom">name</span><span class="l_fn_symbol">]</span> <span class="l_symbol">=</span> <span class="l_number">1</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">Inventory</span>
|
|||
|
<span class="l_atom">Inventory</span> <span class="l_symbol">=</span> (<span class="l_fn_symbol">function</span>(<span class="l_atom">_parent_0</span>)
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_base_0</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span>
|
|||
|
<span class="l_atom">add_item</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">self</span>, <span class="l_atom">name</span>)
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">self</span><span class="l_symbol">.</span><span class="l_atom">items</span>[<span class="l_atom">name</span>] <span class="l_keyword">then</span>
|
|||
|
<span class="l_atom">self</span><span class="l_symbol">.</span><span class="l_atom">items</span>[<span class="l_atom">name</span>] <span class="l_symbol">=</span> <span class="l_atom">self</span><span class="l_symbol">.</span><span class="l_atom">items</span>[<span class="l_atom">name</span>] + <span class="l_number">1</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">self</span><span class="l_symbol">.</span><span class="l_atom">items</span>[<span class="l_atom">name</span>]
|
|||
|
<span class="l_keyword">else</span>
|
|||
|
<span class="l_atom">self</span><span class="l_symbol">.</span><span class="l_atom">items</span>[<span class="l_atom">name</span>] <span class="l_symbol">=</span> <span class="l_number">1</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_symbol">}</span>
|
|||
|
<span class="l_atom">_base_0</span><span class="l_symbol">.</span><span class="l_atom">__index</span> <span class="l_symbol">=</span> <span class="l_atom">_base_0</span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">_parent_0</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_atom">setmetatable</span>(<span class="l_atom">_base_0</span>, <span class="l_atom">getmetatable</span>(<span class="l_atom">_parent_0</span>)<span class="l_symbol">.</span><span class="l_atom">__index</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_class_0</span> <span class="l_symbol">=</span> <span class="l_atom">setmetatable</span>(<span class="l_symbol">{</span>
|
|||
|
<span class="l_atom">__init</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">self</span>)
|
|||
|
<span class="l_atom">self</span><span class="l_symbol">.</span><span class="l_atom">items</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span> <span class="l_symbol">}</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_symbol">}</span>, <span class="l_symbol">{</span>
|
|||
|
<span class="l_atom">__index</span> <span class="l_symbol">=</span> <span class="l_atom">_base_0</span>,
|
|||
|
<span class="l_atom">__call</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">mt</span>, <span class="l_symbol">.</span><span class="l_symbol">.</span><span class="l_symbol">.</span>)
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">self</span> <span class="l_symbol">=</span> <span class="l_atom">setmetatable</span>(<span class="l_symbol">{</span><span class="l_symbol">}</span>, <span class="l_atom">_base_0</span>)
|
|||
|
<span class="l_atom">mt</span><span class="l_symbol">.</span><span class="l_atom">__init</span>(<span class="l_atom">self</span>, <span class="l_symbol">.</span><span class="l_symbol">.</span><span class="l_symbol">.</span>)
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">self</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_symbol">}</span>)
|
|||
|
<span class="l_atom">_base_0</span><span class="l_symbol">.</span><span class="l_atom">__class</span> <span class="l_symbol">=</span> <span class="l_atom">_class_0</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">_class_0</span>
|
|||
|
<span class="l_keyword">end</span>)()</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>A class is declared with a <code>class</code> statement followed by a table-like
|
|||
|
declaration where all of the methods and properties are listed.</p>
|
|||
|
|
|||
|
<p>The <code>new</code> property is special in that it will become the constructor.</p>
|
|||
|
|
|||
|
<p>Notice how all the methods in the class use the fat arrow function syntax. When
|
|||
|
calling methods on a instance, the instance itself is sent in as the first
|
|||
|
argument. The fat arrow handles the creation of a <code>self</code> argument.</p>
|
|||
|
|
|||
|
<p>The <code>@</code> prefix on a variable name is shorthand for <code>self.</code>. <code>@items</code> becomes
|
|||
|
<code>self.items</code>.</p>
|
|||
|
|
|||
|
<p>Creating an instance of the class is done by calling the name of the class as a
|
|||
|
function.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">inv</span> <span class="l_symbol">=</span> <span class="l_proper">Inventory</span><span class="l_symbol">!</span>
|
|||
|
<span class="l_atom">inv</span><span class="l_symbol">\</span><span class="l_atom">add_item</span> <span class="l_string">"t-shirt"</span>
|
|||
|
<span class="l_atom">inv</span><span class="l_symbol">\</span><span class="l_atom">add_item</span> <span class="l_string">"pants"</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">inv</span> <span class="l_symbol">=</span> <span class="l_atom">Inventory</span>()
|
|||
|
<span class="l_atom">inv</span><span class="l_symbol">:</span><span class="l_atom">add_item</span>(<span class="l_string">"t-shirt"</span>)
|
|||
|
<span class="l_atom">inv</span><span class="l_symbol">:</span><span class="l_atom">add_item</span>(<span class="l_string">"pants"</span>)</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>Because the instance of the class needs to be sent to the methods when they are
|
|||
|
called, the ‘' operator is used.</p>
|
|||
|
|
|||
|
<p>All properties of a class are shared among the instances. This is fine for
|
|||
|
functions, but for other types of objects, undesired results may occur.</p>
|
|||
|
|
|||
|
<p>Consider the example below, the <code>clothes</code> property is shared amongst all
|
|||
|
instances, so modifications to it in one instance will show up in another:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_keyword">class</span> <span class="l_proper">Person</span>
|
|||
|
<span class="l_table_key">clothes</span><span class="l_bold_symbol">:</span> <span class="l_fn_symbol">{</span><span class="l_fn_symbol">}</span>
|
|||
|
<span class="l_table_key">give_item</span><span class="l_bold_symbol">:</span> (<span class="l_atom">name</span>) <span class="l_fn_symbol">=></span>
|
|||
|
<span class="l_builtins">table.insert</span> <span class="l_self_var">@clothes</span>, <span class="l_atom">name</span>
|
|||
|
|
|||
|
<span class="l_atom">a</span> <span class="l_symbol">=</span> <span class="l_proper">Person</span><span class="l_symbol">!</span>
|
|||
|
<span class="l_atom">b</span> <span class="l_symbol">=</span> <span class="l_proper">Person</span><span class="l_symbol">!</span>
|
|||
|
|
|||
|
<span class="l_atom">a</span><span class="l_symbol">\</span><span class="l_atom">give_item</span> <span class="l_string">"pants"</span>
|
|||
|
<span class="l_atom">b</span><span class="l_symbol">\</span><span class="l_atom">give_item</span> <span class="l_string">"shirt"</span>
|
|||
|
|
|||
|
<span class="l_comment">-- will print both pants and shirt
|
|||
|
</span><span class="l_builtins">print</span> <span class="l_atom">item</span> <span class="l_keyword">for</span> <span class="l_atom">item</span> <span class="l_keyword">in</span> <span class="l_symbol">*</span><span class="l_atom">a</span><span class="l_bold_symbol">.</span><span class="l_atom">clothes</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">Person</span>
|
|||
|
<span class="l_atom">Person</span> <span class="l_symbol">=</span> (<span class="l_fn_symbol">function</span>(<span class="l_atom">_parent_0</span>)
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_base_0</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span>
|
|||
|
<span class="l_atom">clothes</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span> <span class="l_symbol">}</span>,
|
|||
|
<span class="l_atom">give_item</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">self</span>, <span class="l_atom">name</span>)
|
|||
|
<span class="l_keyword">return</span> <span class="l_builtins">table.insert</span>(<span class="l_atom">self</span><span class="l_symbol">.</span><span class="l_atom">clothes</span>, <span class="l_atom">name</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_symbol">}</span>
|
|||
|
<span class="l_atom">_base_0</span><span class="l_symbol">.</span><span class="l_atom">__index</span> <span class="l_symbol">=</span> <span class="l_atom">_base_0</span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">_parent_0</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_atom">setmetatable</span>(<span class="l_atom">_base_0</span>, <span class="l_atom">getmetatable</span>(<span class="l_atom">_parent_0</span>)<span class="l_symbol">.</span><span class="l_atom">__index</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_class_0</span> <span class="l_symbol">=</span> <span class="l_atom">setmetatable</span>(<span class="l_symbol">{</span>
|
|||
|
<span class="l_atom">__init</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">self</span>, <span class="l_symbol">.</span><span class="l_symbol">.</span><span class="l_symbol">.</span>)
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">_parent_0</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">_parent_0</span><span class="l_symbol">.</span><span class="l_atom">__init</span>(<span class="l_atom">self</span>, <span class="l_symbol">.</span><span class="l_symbol">.</span><span class="l_symbol">.</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_symbol">}</span>, <span class="l_symbol">{</span>
|
|||
|
<span class="l_atom">__index</span> <span class="l_symbol">=</span> <span class="l_atom">_base_0</span>,
|
|||
|
<span class="l_atom">__call</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">mt</span>, <span class="l_symbol">.</span><span class="l_symbol">.</span><span class="l_symbol">.</span>)
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">self</span> <span class="l_symbol">=</span> <span class="l_atom">setmetatable</span>(<span class="l_symbol">{</span><span class="l_symbol">}</span>, <span class="l_atom">_base_0</span>)
|
|||
|
<span class="l_atom">mt</span><span class="l_symbol">.</span><span class="l_atom">__init</span>(<span class="l_atom">self</span>, <span class="l_symbol">.</span><span class="l_symbol">.</span><span class="l_symbol">.</span>)
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">self</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_symbol">}</span>)
|
|||
|
<span class="l_atom">_base_0</span><span class="l_symbol">.</span><span class="l_atom">__class</span> <span class="l_symbol">=</span> <span class="l_atom">_class_0</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">_class_0</span>
|
|||
|
<span class="l_keyword">end</span>)()
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">a</span> <span class="l_symbol">=</span> <span class="l_atom">Person</span>()
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">b</span> <span class="l_symbol">=</span> <span class="l_atom">Person</span>()
|
|||
|
<span class="l_atom">a</span><span class="l_symbol">:</span><span class="l_atom">give_item</span>(<span class="l_string">"pants"</span>)
|
|||
|
<span class="l_atom">b</span><span class="l_symbol">:</span><span class="l_atom">give_item</span>(<span class="l_string">"shirt"</span>)
|
|||
|
<span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_item_0</span> <span class="l_symbol">=</span> <span class="l_atom">a</span><span class="l_symbol">.</span><span class="l_atom">clothes</span>
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">_index_0</span> <span class="l_symbol">=</span> <span class="l_number">1</span>, #<span class="l_atom">_item_0</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">item</span> <span class="l_symbol">=</span> <span class="l_atom">_item_0</span>[<span class="l_atom">_index_0</span>]
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">item</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<h3><a name="inheritance"></a>Inheritance</h3>
|
|||
|
|
|||
|
<p>The <code>extends</code> keyword can be used in a class declaration to inherit the
|
|||
|
properties and methods from another class.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_keyword">class</span> <span class="l_proper">BackPack</span> <span class="l_keyword">extends</span> <span class="l_proper">Inventory</span>
|
|||
|
<span class="l_table_key">size</span><span class="l_bold_symbol">:</span> <span class="l_number">10</span>
|
|||
|
<span class="l_table_key">add_item</span><span class="l_bold_symbol">:</span> (<span class="l_atom">name</span>) <span class="l_fn_symbol">=></span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_symbol">#</span><span class="l_self_var">@items</span> <span class="l_symbol">></span> <span class="l_atom">size</span> <span class="l_keyword">then</span> <span class="l_atom">error</span> <span class="l_string">"backpack is full"</span>
|
|||
|
<span class="l_atom">super</span> <span class="l_atom">name</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">BackPack</span>
|
|||
|
<span class="l_atom">BackPack</span> <span class="l_symbol">=</span> (<span class="l_fn_symbol">function</span>(<span class="l_atom">_parent_0</span>)
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_base_0</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span>
|
|||
|
<span class="l_atom">size</span> <span class="l_symbol">=</span> <span class="l_number">10</span>,
|
|||
|
<span class="l_atom">add_item</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">self</span>, <span class="l_atom">name</span>)
|
|||
|
<span class="l_keyword">if</span> #<span class="l_atom">self</span><span class="l_symbol">.</span><span class="l_atom">items</span> > <span class="l_atom">size</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_atom">error</span>(<span class="l_string">"backpack is full"</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">_parent_0</span><span class="l_symbol">.</span><span class="l_atom">add_item</span>(<span class="l_atom">self</span>, <span class="l_atom">name</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_symbol">}</span>
|
|||
|
<span class="l_atom">_base_0</span><span class="l_symbol">.</span><span class="l_atom">__index</span> <span class="l_symbol">=</span> <span class="l_atom">_base_0</span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">_parent_0</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_atom">setmetatable</span>(<span class="l_atom">_base_0</span>, <span class="l_atom">getmetatable</span>(<span class="l_atom">_parent_0</span>)<span class="l_symbol">.</span><span class="l_atom">__index</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_class_0</span> <span class="l_symbol">=</span> <span class="l_atom">setmetatable</span>(<span class="l_symbol">{</span>
|
|||
|
<span class="l_atom">__init</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">self</span>, <span class="l_symbol">.</span><span class="l_symbol">.</span><span class="l_symbol">.</span>)
|
|||
|
<span class="l_keyword">if</span> <span class="l_atom">_parent_0</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">_parent_0</span><span class="l_symbol">.</span><span class="l_atom">__init</span>(<span class="l_atom">self</span>, <span class="l_symbol">.</span><span class="l_symbol">.</span><span class="l_symbol">.</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_symbol">}</span>, <span class="l_symbol">{</span>
|
|||
|
<span class="l_atom">__index</span> <span class="l_symbol">=</span> <span class="l_atom">_base_0</span>,
|
|||
|
<span class="l_atom">__call</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">mt</span>, <span class="l_symbol">.</span><span class="l_symbol">.</span><span class="l_symbol">.</span>)
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">self</span> <span class="l_symbol">=</span> <span class="l_atom">setmetatable</span>(<span class="l_symbol">{</span><span class="l_symbol">}</span>, <span class="l_atom">_base_0</span>)
|
|||
|
<span class="l_atom">mt</span><span class="l_symbol">.</span><span class="l_atom">__init</span>(<span class="l_atom">self</span>, <span class="l_symbol">.</span><span class="l_symbol">.</span><span class="l_symbol">.</span>)
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">self</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_symbol">}</span>)
|
|||
|
<span class="l_atom">_base_0</span><span class="l_symbol">.</span><span class="l_atom">__class</span> <span class="l_symbol">=</span> <span class="l_atom">_class_0</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">_class_0</span>
|
|||
|
<span class="l_keyword">end</span>)(<span class="l_atom">Inventory</span>)</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>Here we extend our Inventory class, and limit the amount of items it can carry.
|
|||
|
The <code>super</code> keyword can be called as a function to call the function of the
|
|||
|
same name in the super class. It can also be accessed like an object in order
|
|||
|
to retrieve values in the parent class that might have been shadowed by the
|
|||
|
child class.</p>
|
|||
|
|
|||
|
<h3><a name="types"></a>Types</h3>
|
|||
|
|
|||
|
<p>Every instance of a class carries its type with it. This is stored in the
|
|||
|
special <code>__class</code> 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.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">b</span> <span class="l_symbol">=</span> <span class="l_proper">BackPack</span><span class="l_symbol">!</span>
|
|||
|
<span class="l_builtins">assert</span> <span class="l_atom">b</span><span class="l_bold_symbol">.</span><span class="l_atom">__class</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_proper">BackPack</span>
|
|||
|
|
|||
|
<span class="l_builtins">print</span> <span class="l_proper">BackPack</span><span class="l_bold_symbol">.</span><span class="l_atom">size</span> <span class="l_comment">-- prints 10
|
|||
|
</span></code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">b</span> <span class="l_symbol">=</span> <span class="l_atom">BackPack</span>()
|
|||
|
<span class="l_builtins">assert</span>(<span class="l_atom">b</span><span class="l_symbol">.</span><span class="l_atom">__class</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_atom">BackPack</span>)
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">BackPack</span><span class="l_symbol">.</span><span class="l_atom">size</span>)</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<h2><a name="export_statement"></a>Export Statement</h2>
|
|||
|
|
|||
|
<p>Because, by default, all assignments to variables that are not lexically visible will
|
|||
|
be declared as local, special syntax is required to declare a variable globally.</p>
|
|||
|
|
|||
|
<p>The export keyword makes it so any following assignments to the specified names
|
|||
|
will not be assigned locally.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_keyword">export</span> <span class="l_atom">var_name</span>, <span class="l_atom">var_name2</span>
|
|||
|
<span class="l_atom">var_name</span>, <span class="l_atom">var_name3</span> <span class="l_symbol">=</span> <span class="l_string">"hello"</span>, <span class="l_string">"world"</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">var_name3</span>
|
|||
|
<span class="l_atom">var_name</span>, <span class="l_atom">var_name3</span> <span class="l_symbol">=</span> <span class="l_string">"hello"</span>, <span class="l_string">"world"</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>This is especially useful when declaring what will be externally visible in a
|
|||
|
module:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_comment">-- my_module.moon
|
|||
|
</span><span class="l_atom">module</span> <span class="l_string">"my_module"</span>, <span class="l_atom">package</span><span class="l_bold_symbol">.</span><span class="l_atom">seeall</span>
|
|||
|
<span class="l_keyword">export</span> <span class="l_atom">print_result</span>
|
|||
|
|
|||
|
<span class="l_atom">length</span> <span class="l_symbol">=</span> (<span class="l_atom">x</span>, <span class="l_atom">y</span>) <span class="l_fn_symbol">-></span> <span class="l_atom">math</span><span class="l_bold_symbol">.</span><span class="l_atom">sqrt</span> <span class="l_atom">x</span><span class="l_symbol">*</span><span class="l_atom">x</span> + <span class="l_atom">y</span><span class="l_symbol">*</span><span class="l_atom">y</span>
|
|||
|
|
|||
|
<span class="l_atom">print_result</span> <span class="l_symbol">=</span> (<span class="l_atom">x</span>, <span class="l_atom">y</span>) <span class="l_fn_symbol">-></span>
|
|||
|
<span class="l_builtins">print</span> <span class="l_string">"Length is "</span>, <span class="l_atom">length</span> <span class="l_atom">x</span>, <span class="l_atom">y</span>
|
|||
|
|
|||
|
<span class="l_comment">-- main.moon
|
|||
|
</span><span class="l_atom">require</span> <span class="l_string">"my_module"</span>
|
|||
|
|
|||
|
<span class="l_atom">my_module</span><span class="l_bold_symbol">.</span><span class="l_atom">print_result</span> <span class="l_number">4</span>, <span class="l_number">5</span> <span class="l_comment">-- prints the result
|
|||
|
</span>
|
|||
|
<span class="l_builtins">print</span> <span class="l_atom">my_module</span><span class="l_bold_symbol">.</span><span class="l_atom">length</span> <span class="l_number">6</span>, <span class="l_number">7</span> <span class="l_comment">-- errors, `length` not visible
|
|||
|
</span></code></pre></td><td><pre><code class="lua-code"><span class="l_atom">module</span>(<span class="l_string">"my_module"</span>, <span class="l_atom">package</span><span class="l_symbol">.</span><span class="l_atom">seeall</span>)
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">length</span>
|
|||
|
<span class="l_atom">length</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">x</span>, <span class="l_atom">y</span>)
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">math</span><span class="l_symbol">.</span><span class="l_atom">sqrt</span>(<span class="l_atom">x</span> * <span class="l_atom">x</span> + <span class="l_atom">y</span> * <span class="l_atom">y</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_atom">print_result</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">x</span>, <span class="l_atom">y</span>)
|
|||
|
<span class="l_keyword">return</span> <span class="l_builtins">print</span>(<span class="l_string">"Length is "</span>, <span class="l_atom">length</span>(<span class="l_atom">x</span>, <span class="l_atom">y</span>))
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_atom">require</span>(<span class="l_string">"my_module"</span>)
|
|||
|
<span class="l_atom">my_module</span><span class="l_symbol">.</span><span class="l_atom">print_result</span>(<span class="l_number">4</span>, <span class="l_number">5</span>)
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">my_module</span><span class="l_symbol">.</span><span class="l_atom">length</span>(<span class="l_number">6</span>, <span class="l_number">7</span>))</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<h2><a name="import_statement"></a>Import Statement</h2>
|
|||
|
|
|||
|
<p>Often you want to bring some values from a table into the current scope as
|
|||
|
local variables by their name. The import statement lets us accomplish this:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_keyword">import</span> <span class="l_atom">insert</span> <span class="l_keyword">from</span> <span class="l_atom">table</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">insert</span> <span class="l_symbol">=</span> <span class="l_builtins">table.insert</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>The multiple names can be given, each separated by a comma:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_keyword">import</span> <span class="l_proper">C</span>, <span class="l_proper">Ct</span>, <span class="l_proper">Cmt</span> <span class="l_keyword">from</span> <span class="l_atom">lpeg</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">C</span>, <span class="l_atom">Ct</span>, <span class="l_atom">Cmt</span> <span class="l_symbol">=</span> <span class="l_atom">lpeg</span><span class="l_symbol">.</span><span class="l_atom">C</span>, <span class="l_atom">lpeg</span><span class="l_symbol">.</span><span class="l_atom">Ct</span>, <span class="l_atom">lpeg</span><span class="l_symbol">.</span><span class="l_atom">Cmt</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>Sometimes a function requires that the table be sent in as the first argument
|
|||
|
(when using the <code>\` syntax). As a shortcut, we can prefix the name with a</code>`
|
|||
|
to bind it to that table:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_comment">-- some object
|
|||
|
</span><span class="l_atom">my_module</span> <span class="l_symbol">=</span>
|
|||
|
<span class="l_table_key">state</span><span class="l_bold_symbol">:</span> <span class="l_number">100</span>
|
|||
|
<span class="l_table_key">add</span><span class="l_bold_symbol">:</span> (<span class="l_atom">value</span>) <span class="l_fn_symbol">=></span>
|
|||
|
<span class="l_self">self</span><span class="l_bold_symbol">.</span><span class="l_atom">state</span> + <span class="l_atom">value</span>
|
|||
|
|
|||
|
<span class="l_keyword">import</span> <span class="l_symbol">\</span><span class="l_atom">add</span> <span class="l_keyword">from</span> <span class="l_atom">my_module</span>
|
|||
|
|
|||
|
<span class="l_builtins">print</span> <span class="l_atom">add</span>(<span class="l_number">22</span>) <span class="l_comment">-- equivalent to calling my_module:get(22)
|
|||
|
</span></code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">my_module</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span>
|
|||
|
<span class="l_atom">state</span> <span class="l_symbol">=</span> <span class="l_number">100</span>,
|
|||
|
<span class="l_atom">add</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">self</span>, <span class="l_atom">value</span>)
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">self</span><span class="l_symbol">.</span><span class="l_atom">state</span> + <span class="l_atom">value</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_symbol">}</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">add</span> <span class="l_symbol">=</span> <span class="l_atom">moon</span><span class="l_symbol">.</span><span class="l_atom">bind</span>(<span class="l_atom">my_module</span><span class="l_symbol">.</span><span class="l_atom">add</span>, <span class="l_atom">my_module</span>)
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">add</span>(<span class="l_number">22</span>))</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<h2><a name="with_statement"></a>With Statement</h2>
|
|||
|
|
|||
|
<p>A common pattern involving the creation of an object is calling a series of
|
|||
|
functions and setting a series of properties immediately after creating it.</p>
|
|||
|
|
|||
|
<p>This results in repeating the name of the object multiple times in code, adding
|
|||
|
unnecessary noise. A common solution to this is to pass a table in as an
|
|||
|
argument which contains a collection of keys and values to overwrite. The
|
|||
|
downside to this is that the constructor of this object must support this form.</p>
|
|||
|
|
|||
|
<p>The <code>with</code> block helps to alleviate this. It lets us use a bare function and
|
|||
|
index syntax in order to work with the object:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_keyword">with</span> <span class="l_proper">Person</span><span class="l_symbol">!</span>
|
|||
|
<span class="l_bold_symbol">.</span><span class="l_atom">name</span> <span class="l_symbol">=</span> <span class="l_string">"Oswald"</span>
|
|||
|
<span class="l_symbol">\</span><span class="l_atom">add_relative</span> <span class="l_atom">my_dad</span>
|
|||
|
<span class="l_symbol">\</span><span class="l_atom">save</span><span class="l_symbol">!</span>
|
|||
|
<span class="l_builtins">print</span> <span class="l_bold_symbol">.</span><span class="l_atom">name</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_with_0</span> <span class="l_symbol">=</span> <span class="l_atom">Person</span>()
|
|||
|
<span class="l_atom">_with_0</span><span class="l_symbol">.</span><span class="l_atom">name</span> <span class="l_symbol">=</span> <span class="l_string">"Oswald"</span>
|
|||
|
<span class="l_atom">_with_0</span><span class="l_symbol">:</span><span class="l_atom">add_relative</span>(<span class="l_atom">my_dad</span>)
|
|||
|
<span class="l_atom">_with_0</span><span class="l_symbol">:</span><span class="l_atom">save</span>()
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">_with_0</span><span class="l_symbol">.</span><span class="l_atom">name</span>)
|
|||
|
<span class="l_keyword">end</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>The <code>with</code> statement can also be used as an expression which returns the value
|
|||
|
it has been giving access to.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">file</span> <span class="l_symbol">=</span> <span class="l_keyword">with</span> <span class="l_proper">File</span> <span class="l_string">"favorite_foods.txt"</span>
|
|||
|
<span class="l_symbol">\</span><span class="l_atom">set_encoding</span> <span class="l_string">"utf8"</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">file</span>
|
|||
|
<span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_with_0</span> <span class="l_symbol">=</span> <span class="l_atom">File</span>(<span class="l_string">"favorite_foods.txt"</span>)
|
|||
|
<span class="l_atom">_with_0</span><span class="l_symbol">:</span><span class="l_atom">set_encoding</span>(<span class="l_string">"utf8"</span>)
|
|||
|
<span class="l_atom">file</span> <span class="l_symbol">=</span> <span class="l_atom">_with_0</span>
|
|||
|
<span class="l_keyword">end</span></code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>Or…</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">create_person</span> <span class="l_symbol">=</span> (<span class="l_atom">name</span>, <span class="l_atom">relatives</span>) <span class="l_fn_symbol">-></span>
|
|||
|
<span class="l_keyword">with</span> <span class="l_proper">Person</span><span class="l_symbol">!</span>
|
|||
|
<span class="l_bold_symbol">.</span><span class="l_atom">name</span> <span class="l_symbol">=</span> <span class="l_atom">name</span>
|
|||
|
<span class="l_symbol">\</span><span class="l_atom">add_relative</span> <span class="l_atom">relative</span> <span class="l_keyword">for</span> <span class="l_atom">relative</span> <span class="l_keyword">in</span> <span class="l_symbol">*</span><span class="l_atom">relatives</span>
|
|||
|
|
|||
|
<span class="l_atom">me</span> <span class="l_symbol">=</span> <span class="l_atom">create_person</span> <span class="l_string">"Leaf"</span>, <span class="l_fn_symbol">{</span><span class="l_atom">dad</span>, <span class="l_atom">mother</span>, <span class="l_atom">sister</span><span class="l_fn_symbol">}</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">create_person</span>
|
|||
|
<span class="l_atom">create_person</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">name</span>, <span class="l_atom">relatives</span>)
|
|||
|
<span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_with_0</span> <span class="l_symbol">=</span> <span class="l_atom">Person</span>()
|
|||
|
<span class="l_atom">_with_0</span><span class="l_symbol">.</span><span class="l_atom">name</span> <span class="l_symbol">=</span> <span class="l_atom">name</span>
|
|||
|
<span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">_item_0</span> <span class="l_symbol">=</span> <span class="l_atom">relatives</span>
|
|||
|
<span class="l_keyword">for</span> <span class="l_atom">_index_0</span> <span class="l_symbol">=</span> <span class="l_number">1</span>, #<span class="l_atom">_item_0</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">relative</span> <span class="l_symbol">=</span> <span class="l_atom">_item_0</span>[<span class="l_atom">_index_0</span>]
|
|||
|
<span class="l_atom">_with_0</span><span class="l_symbol">:</span><span class="l_atom">add_relative</span>(<span class="l_atom">relative</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">_with_0</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">me</span> <span class="l_symbol">=</span> <span class="l_atom">create_person</span>(<span class="l_string">"Leaf"</span>, <span class="l_symbol">{</span>
|
|||
|
<span class="l_atom">dad</span>,
|
|||
|
<span class="l_atom">mother</span>,
|
|||
|
<span class="l_atom">sister</span>
|
|||
|
<span class="l_symbol">}</span>)</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<h2><a name="the_using_clause_controlling_destructive_assignment"></a>The Using Clause; Controlling Destructive Assignment</h2>
|
|||
|
|
|||
|
<p>While 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:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">i</span> <span class="l_symbol">=</span> <span class="l_number">100</span>
|
|||
|
|
|||
|
<span class="l_comment">-- many lines of code...
|
|||
|
</span>
|
|||
|
<span class="l_atom">my_func</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">-></span>
|
|||
|
<span class="l_atom">i</span> <span class="l_symbol">=</span> <span class="l_number">10</span>
|
|||
|
<span class="l_keyword">while</span> <span class="l_atom">i</span> <span class="l_symbol">></span> <span class="l_number">0</span>
|
|||
|
<span class="l_builtins">print</span> <span class="l_atom">i</span>
|
|||
|
<span class="l_atom">i</span> <span class="l_symbol">-=</span> <span class="l_number">1</span>
|
|||
|
|
|||
|
<span class="l_atom">my_func</span>()
|
|||
|
|
|||
|
<span class="l_builtins">print</span> <span class="l_atom">i</span> <span class="l_comment">-- will print 0
|
|||
|
</span></code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">i</span> <span class="l_symbol">=</span> <span class="l_number">100</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">my_func</span>
|
|||
|
<span class="l_atom">my_func</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>()
|
|||
|
<span class="l_atom">i</span> <span class="l_symbol">=</span> <span class="l_number">10</span>
|
|||
|
<span class="l_atom">while</span> <span class="l_atom">i</span> > <span class="l_number">0</span> <span class="l_keyword">do</span>
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">i</span>)
|
|||
|
<span class="l_atom">i</span> <span class="l_symbol">=</span> <span class="l_atom">i</span> - <span class="l_number">1</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_atom">my_func</span>()
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">i</span>)</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>In <code>my_func</code>, we've overwritten the value of <code>i</code> 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.</p>
|
|||
|
|
|||
|
<p>It would be helpful to say which variables from the enclosing scope we intend
|
|||
|
on change, in order to prevent us from changing others by accident.</p>
|
|||
|
|
|||
|
<p>The <code>using</code> keyword lets us do that. <code>using nil</code> makes sure that no closed
|
|||
|
variables are overwritten in assignment. The <code>using</code> clause is placed after the
|
|||
|
argument list in a function, or in place of it if there are no arguments.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">i</span> <span class="l_symbol">=</span> <span class="l_number">100</span>
|
|||
|
|
|||
|
<span class="l_atom">my_func</span> <span class="l_symbol">=</span> (<span class="l_keyword">using</span> <span class="l_special">nil</span>) <span class="l_fn_symbol">-></span>
|
|||
|
<span class="l_atom">i</span> <span class="l_symbol">=</span> <span class="l_string">"hello"</span> <span class="l_comment">-- a new local variable is created here
|
|||
|
</span>
|
|||
|
<span class="l_atom">my_func</span>()
|
|||
|
<span class="l_builtins">print</span> <span class="l_atom">i</span> <span class="l_comment">-- prints 100, i is unaffected
|
|||
|
</span></code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">i</span> <span class="l_symbol">=</span> <span class="l_number">100</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">my_func</span>
|
|||
|
<span class="l_atom">my_func</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>()
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">i</span> <span class="l_symbol">=</span> <span class="l_string">"hello"</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_atom">my_func</span>()
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">i</span>)</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>Multiple names can be separated by commas. Closure values can still be
|
|||
|
accessed, they just cant be modified:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">tmp</span> <span class="l_symbol">=</span> <span class="l_number">1213</span>
|
|||
|
<span class="l_atom">i</span>, <span class="l_atom">k</span> <span class="l_symbol">=</span> <span class="l_number">100</span>, <span class="l_number">50</span>
|
|||
|
|
|||
|
<span class="l_atom">my_func</span> <span class="l_symbol">=</span> (<span class="l_atom">add</span> <span class="l_keyword">using</span> <span class="l_atom">k</span>,<span class="l_atom">i</span>) <span class="l_fn_symbol">-></span>
|
|||
|
<span class="l_atom">tmp</span> <span class="l_symbol">=</span> <span class="l_atom">tmp</span> + <span class="l_atom">add</span> <span class="l_comment">-- a new local tmp is created
|
|||
|
</span> <span class="l_atom">i</span> <span class="l_symbol">+=</span> <span class="l_atom">tmp</span>
|
|||
|
<span class="l_atom">k</span> <span class="l_symbol">+=</span> <span class="l_atom">tmp</span>
|
|||
|
|
|||
|
<span class="l_atom">my_func</span>(<span class="l_number">22</span>)
|
|||
|
<span class="l_builtins">print</span> <span class="l_atom">i</span>,<span class="l_atom">k</span> <span class="l_comment">-- these have been updated
|
|||
|
</span></code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">tmp</span> <span class="l_symbol">=</span> <span class="l_number">1213</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">i</span>, <span class="l_atom">k</span> <span class="l_symbol">=</span> <span class="l_number">100</span>, <span class="l_number">50</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">my_func</span>
|
|||
|
<span class="l_atom">my_func</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">add</span>)
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">tmp</span> <span class="l_symbol">=</span> <span class="l_atom">tmp</span> + <span class="l_atom">add</span>
|
|||
|
<span class="l_atom">i</span> <span class="l_symbol">=</span> <span class="l_atom">i</span> + <span class="l_atom">tmp</span>
|
|||
|
<span class="l_atom">k</span> <span class="l_symbol">=</span> <span class="l_atom">k</span> + <span class="l_atom">tmp</span>
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">k</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_atom">my_func</span>(<span class="l_number">22</span>)
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">i</span>, <span class="l_atom">k</span>)</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
</div><h1><a name="moonscript_api"></a>MoonScript API</h1><div class="main">
|
|||
|
|
|||
|
<h2><a name="moonscript_module"></a><code>moonscript</code> Module</h2>
|
|||
|
|
|||
|
<p>Upon installing MoonScript, a <code>moonscript</code> module is made available. The best
|
|||
|
use of this module is making your Lua’s require function MoonScript aware.</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">require</span> <span class="l_string">"moonscript"</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_atom">require</span>(<span class="l_string">"moonscript"</span>)</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>After <code>moonscript</code> is required, Lua’s package loader is updated to search for
|
|||
|
<code>.moon</code> files on any subsequent calls to <code>require</code>. The search path for <code>.moon</code>
|
|||
|
files is based on the current <code>package.path</code> value in Lua when <code>moonscript</code> is
|
|||
|
required. Any search paths in <code>package.path</code> ending in <code>.lua</code> are copied,
|
|||
|
rewritten to end in <code>.moon</code>, and then inserted in <code>package.moonpath</code>.</p>
|
|||
|
|
|||
|
<p>The <code>moonloader</code> is the function that is responsible for searching
|
|||
|
<code>package.moonpath</code> for a file available to be included. It is inserted in the
|
|||
|
second position of the <code>package.loaders</code> table. This means that a matching <code>.moon</code> file
|
|||
|
will be loaded over a matching <code>.lua</code> file that has the same base name.</p>
|
|||
|
|
|||
|
<p>For more information on Lua’s <code>package.loaders</code> see <a href="http://www.lua.org/manual/5.1/manual.html#pdf-package.loaders">Lua Reference Manual
|
|||
|
—
|
|||
|
package.loaders</a></p>
|
|||
|
|
|||
|
<p>The <code>moonloader</code>, when finding a valid path to a <code>.moon</code> file, will parse and
|
|||
|
compile the file in memory. The code is then turned into a function using the
|
|||
|
built in <code>load</code> function, which is run as the module.</p>
|
|||
|
|
|||
|
<h2><a name="error_rewriting"></a>Error Rewriting</h2>
|
|||
|
|
|||
|
<p>Runtime errors are given special attention when using the <code>moonloader</code>.
|
|||
|
Because we start off as MoonScript, but run code as Lua, errors that happen
|
|||
|
during runtime report their line numbers as they are in the compiled file. This
|
|||
|
can make debugging particularly difficult.</p>
|
|||
|
|
|||
|
<p>Consider the following file with a bug:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">add_numbers</span> <span class="l_symbol">=</span> (<span class="l_atom">x</span>,<span class="l_atom">y</span>) <span class="l_fn_symbol">-></span> <span class="l_atom">x</span> + <span class="l_atom">z</span>
|
|||
|
<span class="l_builtins">print</span> <span class="l_atom">add_numbers</span> <span class="l_number">10</span>,<span class="l_number">0</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">add_numbers</span>
|
|||
|
<span class="l_atom">add_numbers</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">x</span>, <span class="l_atom">y</span>)
|
|||
|
<span class="l_keyword">return</span> <span class="l_atom">x</span> + <span class="l_atom">z</span>
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">add_numbers</span>(<span class="l_number">10</span>, <span class="l_number">0</span>))</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
<p>The following error is generated:</p>
|
|||
|
|
|||
|
<pre class="bare-code"><code>moon:err.moon:1: attempt to perform arithmetic on global 'z' (a nil value)
|
|||
|
stack traceback:
|
|||
|
err.moon:1: in function 'add_numbers'
|
|||
|
err.moon:2: in main chunk
|
|||
|
</code></pre>
|
|||
|
|
|||
|
<p>Instead of the error being reported on line number 3, where it appears in the
|
|||
|
Lua file, it is reported on line 1, where the faulty line originated. The
|
|||
|
entire stack trace is rewritten in addition to the error.</p>
|
|||
|
|
|||
|
<h2><a name="programmatically_compiling"></a>Programmatically Compiling</h2>
|
|||
|
|
|||
|
<p>The MoonScript module also contains methods for parsing MoonScript text into an
|
|||
|
abstract syntax tree, and compiling an instance of a tree into Lua source code.</p>
|
|||
|
|
|||
|
<p>Knowledge of this API may be useful for creating tools to aid the generation of
|
|||
|
Lua code from MoonScript code.</p>
|
|||
|
|
|||
|
<p>Here is a quick example of how you would compile a MoonScript string to a Lua
|
|||
|
String:</p>
|
|||
|
|
|||
|
<table style="width: 100%;" cellspacing="0" cellpadding="1"><tbody><tr class="code-header"><td>moonscript</td><td>lua</td></tr><tr><td style="width: 50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">require</span> <span class="l_string">"moonscript.parse"</span>
|
|||
|
<span class="l_atom">require</span> <span class="l_string">"moonscript.compile"</span>
|
|||
|
|
|||
|
<span class="l_keyword">import</span> <span class="l_atom">parse</span>, <span class="l_atom">compile</span> <span class="l_keyword">from</span> <span class="l_atom">moonscript</span>
|
|||
|
|
|||
|
<span class="l_atom">moon_code</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">[</span><span class="l_fn_symbol">[</span>(<span class="l_fn_symbol">-></span> <span class="l_builtins">print</span> <span class="l_string">"hello world"</span>)<span class="l_symbol">!</span><span class="l_fn_symbol">]</span><span class="l_fn_symbol">]</span>
|
|||
|
|
|||
|
<span class="l_atom">tree</span>, <span class="l_atom">err</span> <span class="l_symbol">=</span> <span class="l_atom">parse</span><span class="l_bold_symbol">.</span><span class="l_atom">string</span> <span class="l_atom">moon_code</span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_keyword">not</span> <span class="l_atom">tree</span>
|
|||
|
<span class="l_atom">error</span> <span class="l_string">"Parse error: "</span> <span class="l_bold_symbol">.</span><span class="l_bold_symbol">.</span> <span class="l_atom">err</span>
|
|||
|
|
|||
|
<span class="l_atom">lua_code</span>, <span class="l_atom">err</span>, <span class="l_atom">pos</span> <span class="l_symbol">=</span> <span class="l_atom">compile</span><span class="l_bold_symbol">.</span><span class="l_atom">tree</span> <span class="l_atom">tree</span>
|
|||
|
<span class="l_keyword">if</span> <span class="l_keyword">not</span> <span class="l_atom">lua_code</span>
|
|||
|
<span class="l_atom">error</span> <span class="l_atom">compile</span><span class="l_bold_symbol">.</span><span class="l_atom">format_error</span> <span class="l_atom">err</span>, <span class="l_atom">pos</span>, <span class="l_atom">moon_code</span>
|
|||
|
|
|||
|
<span class="l_comment">-- our code is ready
|
|||
|
</span><span class="l_builtins">print</span> <span class="l_atom">lua_code</span>
|
|||
|
</code></pre></td><td><pre><code class="lua-code"><span class="l_atom">require</span>(<span class="l_string">"moonscript.parse"</span>)
|
|||
|
<span class="l_atom">require</span>(<span class="l_string">"moonscript.compile"</span>)
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">parse</span>, <span class="l_atom">compile</span> <span class="l_symbol">=</span> <span class="l_atom">moonscript</span><span class="l_symbol">.</span><span class="l_atom">parse</span>, <span class="l_atom">moonscript</span><span class="l_symbol">.</span><span class="l_atom">compile</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">moon_code</span> <span class="l_symbol">=</span> <span class="l_string">[[(-> print "hello world")!]]</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">tree</span>, <span class="l_atom">err</span> <span class="l_symbol">=</span> <span class="l_atom">parse</span><span class="l_symbol">.</span><span class="l_atom">string</span>(<span class="l_atom">moon_code</span>)
|
|||
|
<span class="l_keyword">if</span> <span class="l_keyword">not</span> <span class="l_atom">tree</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_atom">error</span>(<span class="l_string">"Parse error: "</span> <span class="l_symbol">.</span><span class="l_symbol">.</span> <span class="l_atom">err</span>)
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_keyword">local</span> <span class="l_atom">lua_code</span>, <span class="l_atom">pos</span>
|
|||
|
<span class="l_atom">lua_code</span>, <span class="l_atom">err</span>, <span class="l_atom">pos</span> <span class="l_symbol">=</span> <span class="l_atom">compile</span><span class="l_symbol">.</span><span class="l_atom">tree</span>(<span class="l_atom">tree</span>)
|
|||
|
<span class="l_keyword">if</span> <span class="l_keyword">not</span> <span class="l_atom">lua_code</span> <span class="l_keyword">then</span>
|
|||
|
<span class="l_atom">error</span>(<span class="l_atom">compile</span><span class="l_symbol">.</span><span class="l_atom">format_error</span>(<span class="l_atom">err</span>, <span class="l_atom">pos</span>, <span class="l_atom">moon_code</span>))
|
|||
|
<span class="l_keyword">end</span>
|
|||
|
<span class="l_builtins">print</span>(<span class="l_atom">lua_code</span>)</code></pre></td></tr></tbody></table>
|
|||
|
|
|||
|
</div><h1><a name="command_line_use"></a>Command Line Use</h1><div class="main">
|
|||
|
|
|||
|
<p>Two tools are installed with MoonScript, <code>moon</code> and <code>moonc</code>.</p>
|
|||
|
|
|||
|
<p><code>moonc</code> is for compiling MoonScript code to Lua.<br>
|
|||
|
<code>moon</code> is for running MoonsScript code directly.</p>
|
|||
|
|
|||
|
<h2><a name="moon"></a><code>moon</code></h2>
|
|||
|
|
|||
|
<p><code>moon</code> can be used to run MoonsScript files directly from the command line,
|
|||
|
without needing a separate compile step. All MoonsScript files are compiled in
|
|||
|
memory as they are run.</p>
|
|||
|
|
|||
|
<pre class="bare-code"><code>~> moon my_script.moon
|
|||
|
</code></pre>
|
|||
|
|
|||
|
<p>Any MoonScript files that are required will also be compiled and run
|
|||
|
automatically.</p>
|
|||
|
|
|||
|
<p>When an error occurs during runtime, the stack trace is rewritten to give line
|
|||
|
numbers from the original <code>.moon</code> file.</p>
|
|||
|
|
|||
|
<p>If you want to disable <a href="#error_rewriting">error rewriting</a>, you can pass the
|
|||
|
<code>-d</code> flag. A full list of flags can be seen by passing the <code>-h</code> or <code>--help</code>
|
|||
|
flag.</p>
|
|||
|
|
|||
|
<h2><a name="moonc"></a><code>moonc</code></h2>
|
|||
|
|
|||
|
<p><code>moonc</code> is used for transforming MoonsScript files into Lua files.
|
|||
|
It takes a list of files, compiles them all, and creates the associated <code>.lua</code>
|
|||
|
files in the same directories.</p>
|
|||
|
|
|||
|
<pre class="bare-code"><code>~> moonc my_script1.moon my_script2.moon ...
|
|||
|
</code></pre>
|
|||
|
|
|||
|
<p>You can control where the compiled files are put using the <code>-t</code> flag, followed
|
|||
|
by a directory.</p>
|
|||
|
|
|||
|
<p><code>moonc</code> can also take a directory as an argument, and it will recursively scan
|
|||
|
for all MoonScript files and compile them.</p>
|
|||
|
|
|||
|
<p><code>moonc</code> can write to standard out by passing the <code>-p</code> flag.</p>
|
|||
|
|
|||
|
<p>Combined with <code>linotify</code> on linux, the <code>-w</code> flag can be used to watch all files
|
|||
|
that match the given search path for changes, and then compile them only when
|
|||
|
required.</p>
|
|||
|
|
|||
|
<p>A full list of flags can be seen by passing the <code>-h</code> or <code>--help</code> flag.</p>
|
|||
|
|
|||
|
</div><h1><a name="license_mit"></a>License (MIT)</h1><div class="main">
|
|||
|
|
|||
|
<p>Copyright © 2011 by Leaf Corcoran</p>
|
|||
|
|
|||
|
<p>Permission is hereby granted, free of charge, to any person obtaining a copy
|
|||
|
of this software and associated documentation files (the “Software”), to deal
|
|||
|
in the Software without restriction, including without limitation the rights
|
|||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
|
copies of the Software, and to permit persons to whom the Software is
|
|||
|
furnished to do so, subject to the following conditions:</p>
|
|||
|
|
|||
|
<p>The above copyright notice and this permission notice shall be included in
|
|||
|
all copies or substantial portions of the Software.</p>
|
|||
|
|
|||
|
<p>THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||
|
THE SOFTWARE.</p>
|
|||
|
|
|||
|
</div>
|
|||
|
|
|||
|
<div class="footer">Generated on Sun Aug 14 16:19:23 2011; MoonScript v0.1.0</div>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
</body>
|
|||
|
</html>
|