mirror of
https://github.com/leafo/moonscript.git
synced 2024-12-24 01:04:21 +00:00
2417 lines
188 KiB
HTML
2417 lines
188 KiB
HTML
<!DOCTYPE HTML>
|
||
<html lang="en">
|
||
<head>
|
||
<!-- Autogenerated from on Mon Dec 12 00:44:42 2011 -->
|
||
<meta charset="UTF-8">
|
||
<title>MoonScript v0.2.0 - Language Guide</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;
|
||
}
|
||
|
||
a.current {
|
||
color: black;
|
||
font-weight: bold;
|
||
text-decoration: none;
|
||
}
|
||
|
||
p {
|
||
line-height: 140%;
|
||
font-size: 16px;
|
||
}
|
||
|
||
.main {
|
||
width: 960px;
|
||
padding-left: 1em;
|
||
}
|
||
|
||
h1, h2, 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, div > pre {
|
||
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);
|
||
}
|
||
|
||
div > pre {
|
||
padding: 8px;
|
||
}
|
||
|
||
.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, .nv {
|
||
color: #707A34;
|
||
}
|
||
.l_number {
|
||
color: #4958C3;
|
||
}
|
||
|
||
.footer {
|
||
color: #747678;
|
||
font-size: 80%;
|
||
padding: 8px;
|
||
}
|
||
|
||
.clearfix:after {
|
||
content: ".";
|
||
display: block;
|
||
clear: both;
|
||
visibility: hidden;
|
||
line-height: 0;
|
||
height: 0;
|
||
}
|
||
|
||
.column {
|
||
float: left;
|
||
}
|
||
|
||
.index {
|
||
margin-left: 20px;
|
||
}
|
||
|
||
h3 > code {
|
||
display: block;
|
||
background: #C3DFFA;
|
||
padding: 1em;
|
||
color: #0075ea;
|
||
text-shadow: 1px 1px 0px #e8f1fa;
|
||
border-bottom: 1px solid #b1cae3;
|
||
}
|
||
|
||
|
||
</style>
|
||
|
||
</head><body>
|
||
<div class="header">
|
||
<h1>MoonScript v0.2.0 - Language Guide</h1>
|
||
</div>
|
||
|
||
<div class="clearfix index">
|
||
<div class="column">
|
||
<h3>On This Page</h3>
|
||
<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>
|
||
|
||
<li><a href="#multiline_arguments">Multi-line arguments</a></li>
|
||
</ul>
|
||
<li><a href="#table_literals">Table Literals</a></li>
|
||
|
||
<li><a href="#comprehensions">Comprehensions</a></li>
|
||
<ul>
|
||
<li><a href="#list_comprehensions">List Comprehensions</a></li>
|
||
|
||
<li><a href="#table_comprehensions">Table Comprehensions</a></li>
|
||
|
||
<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="#switch">Switch</a></li>
|
||
|
||
<li><a href="#object_oriented_programming">Object Oriented Programming</a></li>
|
||
<ul>
|
||
<li><a href="#inheritance">Inheritance</a></li>
|
||
|
||
<li><a href="#super">Super</a></li>
|
||
|
||
<li><a href="#types">Types</a></li>
|
||
</ul>
|
||
<li><a href="#export_statement">Export Statement</a></li>
|
||
<ul>
|
||
<li><a href="#export_all_and_export_proper">Export All & Export Proper</a></li>
|
||
</ul>
|
||
<li><a href="#import_statement">Import Statement</a></li>
|
||
|
||
<li><a href="#with_statement">With Statement</a></li>
|
||
|
||
<li><a href="#function_stubs">Function Stubs</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>
|
||
|
||
<div class="column">
|
||
<h3>All Pages</h3>
|
||
<ul>
|
||
<li><a href="./reference_manual.html" class="current">Language Guide</a></li>
|
||
<li><a href="./standard_lib.html">Standard Library</a></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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>, <code>..=</code> operators have been added for updating a value by
|
||
a certain amount. They are aliases for their expanded equivalents.</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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>
|
||
|
||
<span class="l_atom">s</span> <span class="l_symbol">=</span> <span class="l_string">"hello "</span>
|
||
<span class="l_atom">s</span> <span class="l_bold_symbol">.</span><span class="l_bold_symbol">.</span><span class="l_symbol">=</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">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>
|
||
<span class="l_keyword">local</span> <span class="l_atom">s</span> <span class="l_symbol">=</span> <span class="l_string">"hello "</span>
|
||
<span class="l_atom">s</span> <span class="l_symbol">=</span> <span class="l_atom">s</span> <span class="l_symbol">.</span><span class="l_symbol">.</span> <span class="l_string">"world"</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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 preferred way to call
|
||
functions with no arguments.</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 default 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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>
|
||
|
||
|
||
<h3><a name="multiline_arguments"></a>Multi-line arguments</h3>
|
||
|
||
<p>When calling functions that take a large number of arguments, it is convenient
|
||
to split the argument list over multiple lines. Because of the white-space
|
||
sensitive nature of the language, care must be taken when splitting up the
|
||
argument list.</p>
|
||
|
||
<p>If an argument list is to be continued onto the next line, the current line
|
||
must end in a comma. And the following line must be indented more than the
|
||
current indentation. Once indented, all other argument lines must be at the
|
||
same level of indentation to be part of the argument list</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td width="50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">my_func</span> <span class="l_number">5</span>,<span class="l_number">4</span>,<span class="l_number">3</span>,
|
||
<span class="l_number">8</span>,<span class="l_number">9</span>,<span class="l_number">10</span>
|
||
|
||
<span class="l_atom">cool_func</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></code></pre></td>
|
||
<td><pre><code class="lua-code"><span class="l_atom">my_func</span>(<span class="l_number">5</span>, <span class="l_number">4</span>, <span class="l_number">3</span>, <span class="l_number">8</span>, <span class="l_number">9</span>, <span class="l_number">10</span>)
|
||
<span class="l_atom">cool_func</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>)</code></pre></td></tr>
|
||
</tbody></table>
|
||
|
||
|
||
<p>This type of invocation can be nested. The level of indentation is used to
|
||
determine to which function the arguments belong to.</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td width="50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">my_func</span> <span class="l_number">5</span>,<span class="l_number">6</span>,<span class="l_number">7</span>,
|
||
<span class="l_number">6</span>, <span class="l_atom">another_func</span> <span class="l_number">6</span>,<span class="l_number">7</span>,<span class="l_number">8</span>,
|
||
<span class="l_number">9</span>,<span class="l_number">1</span>,<span class="l_number">2</span>,
|
||
<span class="l_number">5</span>,<span class="l_number">4</span></code></pre></td>
|
||
<td><pre><code class="lua-code"><span class="l_atom">my_func</span>(<span class="l_number">5</span>, <span class="l_number">6</span>, <span class="l_number">7</span>, <span class="l_number">6</span>, <span class="l_atom">another_func</span>(<span class="l_number">6</span>, <span class="l_number">7</span>, <span class="l_number">8</span>, <span class="l_number">9</span>, <span class="l_number">1</span>, <span class="l_number">2</span>), <span class="l_number">5</span>, <span class="l_number">4</span>)</code></pre></td></tr>
|
||
</tbody></table>
|
||
|
||
|
||
<p>Because <a href="#table_literals">tables</a> also use the comma as a delimiter, this
|
||
indentation syntax is helpful for letting values be part of the argument list
|
||
instead of being part of the table.</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td width="50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">x</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_atom">a_func</span> <span class="l_number">4</span>,<span class="l_number">5</span>,
|
||
<span class="l_number">5</span>,<span class="l_number">6</span>,
|
||
<span class="l_number">8</span>,<span class="l_number">9</span>,<span class="l_number">10</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</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_atom">a_func</span>(<span class="l_number">4</span>, <span class="l_number">5</span>, <span class="l_number">5</span>, <span class="l_number">6</span>),
|
||
<span class="l_number">8</span>,
|
||
<span class="l_number">9</span>,
|
||
<span class="l_number">10</span>
|
||
<span class="l_symbol">}</span></code></pre></td></tr>
|
||
</tbody></table>
|
||
|
||
|
||
<p>Although uncommon, notice how we can give a deeper indentation for function
|
||
arguments if we know we will be using a lower indentation futher on.</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td width="50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">y</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">{</span> <span class="l_atom">my_func</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">5</span>,<span class="l_number">6</span>,<span class="l_number">7</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">y</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span>
|
||
<span class="l_atom">my_func</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">5</span>,
|
||
<span class="l_number">6</span>,
|
||
<span class="l_number">7</span>
|
||
<span class="l_symbol">}</span></code></pre></td></tr>
|
||
</tbody></table>
|
||
|
||
|
||
<p>The same thing can be done with other block level statements like
|
||
<a href="#conditionals">conditionals</a>. We can use indentation level to determine what
|
||
statement a value belongs to:</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td width="50%" class="code-border"><pre><code class="moon-code"><span class="l_keyword">if</span> <span class="l_atom">func</span> <span class="l_number">1</span>,<span class="l_number">2</span>,<span class="l_number">3</span>,
|
||
<span class="l_string">"hello"</span>,
|
||
<span class="l_string">"world"</span>
|
||
<span class="l_builtins">print</span> <span class="l_string">"hello"</span>
|
||
<span class="l_builtins">print</span> <span class="l_string">"I am inside if"</span>
|
||
|
||
<span class="l_keyword">if</span> <span class="l_atom">func</span> <span class="l_number">1</span>,<span class="l_number">2</span>,<span class="l_number">3</span>,
|
||
<span class="l_string">"hello"</span>,
|
||
<span class="l_string">"world"</span>
|
||
<span class="l_builtins">print</span> <span class="l_string">"hello"</span>
|
||
<span class="l_builtins">print</span> <span class="l_string">"I am inside if"</span></code></pre></td>
|
||
<td><pre><code class="lua-code"><span class="l_keyword">if</span> <span class="l_atom">func</span>(<span class="l_number">1</span>, <span class="l_number">2</span>, <span class="l_number">3</span>, <span class="l_string">"hello"</span>, <span class="l_string">"world"</span>) <span class="l_keyword">then</span>
|
||
<span class="l_builtins">print</span>(<span class="l_string">"hello"</span>)
|
||
<span class="l_builtins">print</span>(<span class="l_string">"I am inside if"</span>)
|
||
<span class="l_keyword">end</span>
|
||
<span class="l_keyword">if</span> <span class="l_atom">func</span>(<span class="l_number">1</span>, <span class="l_number">2</span>, <span class="l_number">3</span>, <span class="l_string">"hello"</span>, <span class="l_string">"world"</span>) <span class="l_keyword">then</span>
|
||
<span class="l_builtins">print</span>(<span class="l_string">"hello"</span>)
|
||
<span class="l_builtins">print</span>(<span class="l_string">"I am inside if"</span>)
|
||
<span class="l_keyword">end</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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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>
|
||
|
||
|
||
<p>The keys of a table literal can be language keywords without being escaped:</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td width="50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">tbl</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">{</span>
|
||
<span class="l_keyword">do</span><span class="l_bold_symbol">:</span> <span class="l_string">"something"</span>
|
||
<span class="l_table_key">end</span><span class="l_bold_symbol">:</span> <span class="l_string">"hunger"</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">tbl</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span>
|
||
[<span class="l_string">"do"</span>] <span class="l_symbol">=</span> <span class="l_string">"something"</span>,
|
||
[<span class="l_string">"end"</span>] <span class="l_symbol">=</span> <span class="l_string">"hunger"</span>
|
||
<span class="l_symbol">}</span></code></pre></td></tr>
|
||
</tbody></table>
|
||
|
||
|
||
<p>If you are constructing a table out of variables and wish the keys to be the
|
||
same as the variable names, then the <code>:</code> prefix operator can be used:</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td width="50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">hair</span> <span class="l_symbol">=</span> <span class="l_string">"golden"</span>
|
||
<span class="l_atom">height</span> <span class="l_symbol">=</span> <span class="l_number">200</span>
|
||
<span class="l_atom">person</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">{</span> <span class="l_bold_symbol">:</span><span class="l_atom">hair</span>, <span class="l_bold_symbol">:</span><span class="l_atom">height</span>, <span class="l_table_key">shoe_size</span><span class="l_bold_symbol">:</span> <span class="l_number">40</span> <span class="l_fn_symbol">}</span>
|
||
|
||
<span class="l_atom">print_table</span> <span class="l_bold_symbol">:</span><span class="l_atom">hair</span>, <span class="l_bold_symbol">:</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">hair</span> <span class="l_symbol">=</span> <span class="l_string">"golden"</span>
|
||
<span class="l_keyword">local</span> <span class="l_atom">height</span> <span class="l_symbol">=</span> <span class="l_number">200</span>
|
||
<span class="l_keyword">local</span> <span class="l_atom">person</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span>
|
||
<span class="l_atom">hair</span> <span class="l_symbol">=</span> <span class="l_atom">hair</span>,
|
||
<span class="l_atom">height</span> <span class="l_symbol">=</span> <span class="l_atom">height</span>,
|
||
<span class="l_atom">shoe_size</span> <span class="l_symbol">=</span> <span class="l_number">40</span>
|
||
<span class="l_symbol">}</span>
|
||
<span class="l_atom">print_table</span>(<span class="l_symbol">{</span>
|
||
<span class="l_atom">hair</span> <span class="l_symbol">=</span> <span class="l_atom">hair</span>,
|
||
<span class="l_atom">height</span> <span class="l_symbol">=</span> <span class="l_atom">height</span>
|
||
<span class="l_symbol">}</span>)</code></pre></td></tr>
|
||
</tbody></table>
|
||
|
||
|
||
<h2><a name="comprehensions"></a>Comprehensions</h2>
|
||
|
||
<p>Compiling provide a convenient syntax for constructing a new table by iterating
|
||
over some existing object and applying an expression to its values. There are
|
||
two kinds of comprehensions: list comprehensions and table comprehensions. They
|
||
both produce Lua tables; <em>list comprehensions</em> accumulate values into an
|
||
array-like table, and <em>table comprehensions</em> let you set both the key and the
|
||
value on each iteration.</p>
|
||
|
||
<h3><a name="list_comprehensions"></a>List Comprehensions</h3>
|
||
|
||
<p>The following creates a copy of the <code>items</code> table but with all the values
|
||
doubled.</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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">local</span> <span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_number">0</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_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_atom">_len_0</span> + <span class="l_number">1</span>
|
||
<span class="l_atom">_accum_0</span>[<span class="l_atom">_len_0</span>] <span class="l_symbol">=</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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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">local</span> <span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_number">0</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_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_atom">_len_0</span> + <span class="l_number">1</span>
|
||
<span class="l_atom">_accum_0</span>[<span class="l_atom">_len_0</span>] <span class="l_symbol">=</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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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">local</span> <span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_number">0</span>
|
||
<span class="l_keyword">local</span> <span class="l_atom">_list_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">_list_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">_list_0</span>[<span class="l_atom">_index_0</span>]
|
||
<span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_atom">_len_0</span> + <span class="l_number">1</span>
|
||
<span class="l_atom">_accum_0</span>[<span class="l_atom">_len_0</span>] <span class="l_symbol">=</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 <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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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">local</span> <span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_number">0</span>
|
||
<span class="l_keyword">local</span> <span class="l_atom">_list_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">_list_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">_list_0</span>[<span class="l_atom">_index_0</span>]
|
||
<span class="l_keyword">local</span> <span class="l_atom">_list_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_0</span> <span class="l_symbol">=</span> <span class="l_number">1</span>, #<span class="l_atom">_list_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">_list_1</span>[<span class="l_atom">_index_0</span>]
|
||
<span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_atom">_len_0</span> + <span class="l_number">1</span>
|
||
<span class="l_atom">_accum_0</span>[<span class="l_atom">_len_0</span>] <span class="l_symbol">=</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">return</span> <span class="l_atom">_accum_0</span>
|
||
<span class="l_keyword">end</span>)()</code></pre></td></tr>
|
||
</tbody></table>
|
||
|
||
|
||
<h3><a name="table_comprehensions"></a>Table Comprehensions</h3>
|
||
|
||
<p>The syntax for table comprehensions is very similar, differing by using <code>{</code> and
|
||
<code>}</code> and taking two values from each iteration.</p>
|
||
|
||
<p>This example copies the key-value table <code>thing</code>:</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td width="50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">thing</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">{</span>
|
||
<span class="l_table_key">color</span><span class="l_bold_symbol">:</span> <span class="l_string">"red"</span>
|
||
<span class="l_table_key">name</span><span class="l_bold_symbol">:</span> <span class="l_string">"fast"</span>
|
||
<span class="l_table_key">width</span><span class="l_bold_symbol">:</span> <span class="l_number">123</span>
|
||
<span class="l_fn_symbol">}</span>
|
||
|
||
<span class="l_atom">thing_copy</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">{</span><span class="l_atom">k</span>,<span class="l_atom">v</span> <span class="l_keyword">for</span> <span class="l_atom">k</span>,<span class="l_atom">v</span> <span class="l_keyword">in</span> <span class="l_builtins">pairs</span> <span class="l_atom">thing</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">thing</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span>
|
||
<span class="l_atom">color</span> <span class="l_symbol">=</span> <span class="l_string">"red"</span>,
|
||
<span class="l_atom">name</span> <span class="l_symbol">=</span> <span class="l_string">"fast"</span>,
|
||
<span class="l_atom">width</span> <span class="l_symbol">=</span> <span class="l_number">123</span>
|
||
<span class="l_symbol">}</span>
|
||
<span class="l_keyword">local</span> <span class="l_atom">thing_copy</span> <span class="l_symbol">=</span> (<span class="l_fn_symbol">function</span>()
|
||
<span class="l_keyword">local</span> <span class="l_atom">_tbl_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">k</span>, <span class="l_atom">v</span> <span class="l_atom">in</span> <span class="l_builtins">pairs</span>(<span class="l_atom">thing</span>) <span class="l_keyword">do</span>
|
||
<span class="l_atom">_tbl_0</span>[<span class="l_atom">k</span>] <span class="l_symbol">=</span> <span class="l_atom">v</span>
|
||
<span class="l_keyword">end</span>
|
||
<span class="l_keyword">return</span> <span class="l_atom">_tbl_0</span>
|
||
<span class="l_keyword">end</span>)()</code></pre></td></tr>
|
||
</tbody></table>
|
||
|
||
|
||
<p>Table comprehensions, like list comprehensions, also support multiple <code>for</code> and
|
||
<code>when</code> clauses. In this example we use a <code>where</code> clause to prevent the value
|
||
associated with the <code>color</code> key from being copied.</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td width="50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">no_color</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">{</span><span class="l_atom">k</span>,<span class="l_atom">v</span> <span class="l_keyword">for</span> <span class="l_atom">k</span>,<span class="l_atom">v</span> <span class="l_keyword">in</span> <span class="l_builtins">pairs</span> <span class="l_atom">thing</span> <span class="l_keyword">when</span> <span class="l_atom">k</span> <span class="l_symbol">!</span><span class="l_symbol">=</span> <span class="l_string">"color"</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">no_color</span> <span class="l_symbol">=</span> (<span class="l_fn_symbol">function</span>()
|
||
<span class="l_keyword">local</span> <span class="l_atom">_tbl_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">k</span>, <span class="l_atom">v</span> <span class="l_atom">in</span> <span class="l_builtins">pairs</span>(<span class="l_atom">thing</span>) <span class="l_keyword">do</span>
|
||
<span class="l_keyword">if</span> <span class="l_atom">k</span> ~<span class="l_symbol">=</span> <span class="l_string">"color"</span> <span class="l_keyword">then</span>
|
||
<span class="l_atom">_tbl_0</span>[<span class="l_atom">k</span>] <span class="l_symbol">=</span> <span class="l_atom">v</span>
|
||
<span class="l_keyword">end</span>
|
||
<span class="l_keyword">end</span>
|
||
<span class="l_keyword">return</span> <span class="l_atom">_tbl_0</span>
|
||
<span class="l_keyword">end</span>)()</code></pre></td></tr>
|
||
</tbody></table>
|
||
|
||
|
||
<p>The <code>*</code> operator is also supported. Here we create a square root look up table
|
||
for a few numbers.</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td width="50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">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_fn_symbol">}</span>
|
||
<span class="l_atom">sqrts</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">{</span><span class="l_atom">i</span>, <span class="l_atom">math</span><span class="l_bold_symbol">.</span><span class="l_atom">sqrt</span> <span class="l_atom">i</span> <span class="l_keyword">for</span> <span class="l_atom">i</span> <span class="l_keyword">in</span> <span class="l_symbol">*</span><span class="l_atom">numbers</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">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_symbol">}</span>
|
||
<span class="l_keyword">local</span> <span class="l_atom">sqrts</span> <span class="l_symbol">=</span> (<span class="l_fn_symbol">function</span>()
|
||
<span class="l_keyword">local</span> <span class="l_atom">_tbl_0</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">_list_0</span> <span class="l_symbol">=</span> <span class="l_atom">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">_list_0</span> <span class="l_keyword">do</span>
|
||
<span class="l_keyword">local</span> <span class="l_atom">i</span> <span class="l_symbol">=</span> <span class="l_atom">_list_0</span>[<span class="l_atom">_index_0</span>]
|
||
<span class="l_atom">_tbl_0</span>[<span class="l_atom">i</span>] <span class="l_symbol">=</span> <span class="l_atom">math</span><span class="l_symbol">.</span><span class="l_atom">sqrt</span>(<span class="l_atom">i</span>)
|
||
<span class="l_keyword">end</span>
|
||
<span class="l_keyword">return</span> <span class="l_atom">_tbl_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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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_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">local</span> <span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_number">0</span>
|
||
<span class="l_keyword">local</span> <span class="l_atom">_list_0</span> <span class="l_symbol">=</span> <span class="l_atom">items</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">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">_list_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">_list_0</span>[<span class="l_atom">_index_0</span>]
|
||
<span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_atom">_len_0</span> + <span class="l_number">1</span>
|
||
<span class="l_atom">_accum_0</span>[<span class="l_atom">_len_0</span>] <span class="l_symbol">=</span> <span class="l_atom">item</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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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">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">local</span> <span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_number">0</span>
|
||
<span class="l_keyword">local</span> <span class="l_atom">_list_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">_list_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">_list_0</span>[<span class="l_atom">_index_0</span>]
|
||
<span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_atom">_len_0</span> + <span class="l_number">1</span>
|
||
<span class="l_atom">_accum_0</span>[<span class="l_atom">_len_0</span>] <span class="l_symbol">=</span> <span class="l_atom">item</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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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_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">local</span> <span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_number">0</span>
|
||
<span class="l_keyword">local</span> <span class="l_atom">_list_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">_list_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">_list_0</span>[<span class="l_atom">_index_0</span>]
|
||
<span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_atom">_len_0</span> + <span class="l_number">1</span>
|
||
<span class="l_atom">_accum_0</span>[<span class="l_atom">_len_0</span>] <span class="l_symbol">=</span> <span class="l_atom">item</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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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_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">local</span> <span class="l_atom">_list_0</span> <span class="l_symbol">=</span> <span class="l_atom">items</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">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">_list_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">_list_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></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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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">local</span> <span class="l_atom">_list_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">_list_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">_list_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">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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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">local</span> <span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_number">0</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_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_atom">_len_0</span> + <span class="l_number">1</span>
|
||
<span class="l_atom">_accum_0</span>[<span class="l_atom">_len_0</span>] <span class="l_symbol">=</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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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">local</span> <span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_number">0</span>
|
||
<span class="l_keyword">local</span> <span class="l_atom">_list_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">_list_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">_list_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_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_atom">_len_0</span> + <span class="l_number">1</span>
|
||
<span class="l_atom">_accum_0</span>[<span class="l_atom">_len_0</span>] <span class="l_symbol">=</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>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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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">local</span> <span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_number">0</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_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_atom">_len_0</span> + <span class="l_number">1</span>
|
||
<span class="l_atom">_accum_0</span>[<span class="l_atom">_len_0</span>] <span class="l_symbol">=</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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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_keyword">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">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 accumulated value of a while loop, the statement
|
||
must be explicitly returned.</p>
|
||
|
||
<h2><a name="conditionals"></a>Conditionals</h2>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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">local</span> <span class="l_atom">_list_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">_list_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">_list_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></code></pre></td></tr>
|
||
</tbody></table>
|
||
|
||
|
||
<h2><a name="switch"></a>Switch</h2>
|
||
|
||
<p>The switch statement is shorthand for writing a series of if statements that
|
||
check against the same value. Note that the value is only evaluated once. Like
|
||
if statements, switches can have an else block to handle no matches. Comparison
|
||
is done with the <code>==</code> operator.</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td width="50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">name</span> <span class="l_symbol">=</span> <span class="l_string">"Dan"</span>
|
||
<span class="l_keyword">switch</span> <span class="l_atom">name</span>
|
||
<span class="l_keyword">when</span> <span class="l_string">"Robert"</span>
|
||
<span class="l_builtins">print</span> <span class="l_string">"You are robert"</span>
|
||
<span class="l_keyword">when</span> <span class="l_string">"Dan"</span>
|
||
<span class="l_builtins">print</span> <span class="l_string">"Your name, it's Dan"</span>
|
||
<span class="l_keyword">else</span>
|
||
<span class="l_builtins">print</span> <span class="l_string">"I don't know about your name"</span></code></pre></td>
|
||
<td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">name</span> <span class="l_symbol">=</span> <span class="l_string">"Dan"</span>
|
||
<span class="l_keyword">local</span> <span class="l_atom">_exp_0</span> <span class="l_symbol">=</span> <span class="l_atom">name</span>
|
||
<span class="l_keyword">if</span> <span class="l_string">"Robert"</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_atom">_exp_0</span> <span class="l_keyword">then</span>
|
||
<span class="l_builtins">print</span>(<span class="l_string">"You are robert"</span>)
|
||
<span class="l_keyword">elseif</span> <span class="l_string">"Dan"</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_atom">_exp_0</span> <span class="l_keyword">then</span>
|
||
<span class="l_builtins">print</span>(<span class="l_string">"Your name, it's Dan"</span>)
|
||
<span class="l_keyword">else</span>
|
||
<span class="l_builtins">print</span>(<span class="l_string">"I don't know about your name"</span>)
|
||
<span class="l_keyword">end</span></code></pre></td></tr>
|
||
</tbody></table>
|
||
|
||
|
||
<p>Switches can be used as expressions as well, here we can assign the result of
|
||
the switch to a variable:</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td width="50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">b</span> <span class="l_symbol">=</span> <span class="l_number">1</span>
|
||
<span class="l_atom">next_number</span> <span class="l_symbol">=</span> <span class="l_keyword">switch</span> <span class="l_atom">b</span>
|
||
<span class="l_keyword">when</span> <span class="l_number">1</span>
|
||
<span class="l_number">2</span>
|
||
<span class="l_keyword">when</span> <span class="l_number">2</span>
|
||
<span class="l_number">3</span>
|
||
<span class="l_keyword">else</span>
|
||
<span class="l_atom">error</span> <span class="l_string">"can't count that high!"</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_number">1</span>
|
||
<span class="l_keyword">local</span> <span class="l_atom">next_number</span>
|
||
<span class="l_keyword">local</span> <span class="l_atom">_exp_0</span> <span class="l_symbol">=</span> <span class="l_atom">b</span>
|
||
<span class="l_keyword">if</span> <span class="l_number">1</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_atom">_exp_0</span> <span class="l_keyword">then</span>
|
||
<span class="l_atom">next_number</span> <span class="l_symbol">=</span> <span class="l_number">2</span>
|
||
<span class="l_keyword">elseif</span> <span class="l_number">2</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_atom">_exp_0</span> <span class="l_keyword">then</span>
|
||
<span class="l_atom">next_number</span> <span class="l_symbol">=</span> <span class="l_number">3</span>
|
||
<span class="l_keyword">else</span>
|
||
<span class="l_atom">next_number</span> <span class="l_symbol">=</span> <span class="l_atom">error</span>(<span class="l_string">"can't count that high!"</span>)
|
||
<span class="l_keyword">end</span></code></pre></td></tr>
|
||
</tbody></table>
|
||
|
||
|
||
<p>We can use the <code>then</code> keyword to write a switch’s <code>when</code> block on a single line.
|
||
No extra keyword is needed to write the else block on a single line.</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td width="50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">msg</span> <span class="l_symbol">=</span> <span class="l_keyword">switch</span> <span class="l_atom">math</span><span class="l_bold_symbol">.</span><span class="l_atom">random</span>(<span class="l_number">1</span>, <span class="l_number">5</span>)
|
||
<span class="l_keyword">when</span> <span class="l_number">1</span> <span class="l_keyword">then</span> <span class="l_string">"you are lucky"</span>
|
||
<span class="l_keyword">when</span> <span class="l_number">2</span> <span class="l_keyword">then</span> <span class="l_string">"you are almost lucky"</span>
|
||
<span class="l_keyword">else</span> <span class="l_string">"not so lucky"</span></code></pre></td>
|
||
<td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">msg</span>
|
||
<span class="l_keyword">local</span> <span class="l_atom">_exp_0</span> <span class="l_symbol">=</span> <span class="l_atom">math</span><span class="l_symbol">.</span><span class="l_atom">random</span>(<span class="l_number">1</span>, <span class="l_number">5</span>)
|
||
<span class="l_keyword">if</span> <span class="l_number">1</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_atom">_exp_0</span> <span class="l_keyword">then</span>
|
||
<span class="l_atom">msg</span> <span class="l_symbol">=</span> <span class="l_string">"you are lucky"</span>
|
||
<span class="l_keyword">elseif</span> <span class="l_number">2</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_atom">_exp_0</span> <span class="l_keyword">then</span>
|
||
<span class="l_atom">msg</span> <span class="l_symbol">=</span> <span class="l_string">"you are almost lucky"</span>
|
||
<span class="l_keyword">else</span>
|
||
<span class="l_atom">msg</span> <span class="l_symbol">=</span> <span class="l_string">"not so lucky"</span>
|
||
<span class="l_keyword">end</span></code></pre></td></tr>
|
||
</tbody></table>
|
||
|
||
|
||
<p>It is worth noting the order of the case comparison expression. The case’s
|
||
expression is on the left hand side. This can be useful if the case’s
|
||
expression wants to overwrite how the comparison is done by defining an <code>eq</code>
|
||
metamethod.</p>
|
||
|
||
<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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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_keyword">local</span> <span class="l_atom">_parent_0</span> <span class="l_symbol">=</span> <span class="l_special">nil</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">_parent_0</span><span class="l_symbol">.</span><span class="l_atom">__base</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_atom">__base</span> <span class="l_symbol">=</span> <span class="l_atom">_base_0</span>,
|
||
<span class="l_atom">__name</span> <span class="l_symbol">=</span> <span class="l_string">"Inventory"</span>,
|
||
<span class="l_atom">__parent</span> <span class="l_symbol">=</span> <span class="l_atom">_parent_0</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_fn_symbol">function</span>(<span class="l_atom">cls</span>, <span class="l_atom">name</span>)
|
||
<span class="l_keyword">local</span> <span class="l_atom">val</span> <span class="l_symbol">=</span> <span class="l_atom">rawget</span>(<span class="l_atom">_base_0</span>, <span class="l_atom">name</span>)
|
||
<span class="l_keyword">if</span> <span class="l_atom">val</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_special">nil</span> <span class="l_keyword">and</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_atom">name</span>]
|
||
<span class="l_keyword">else</span>
|
||
<span class="l_keyword">return</span> <span class="l_atom">val</span>
|
||
<span class="l_keyword">end</span>
|
||
<span class="l_keyword">end</span>,
|
||
<span class="l_atom">__call</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">cls</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_0</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">cls</span><span class="l_symbol">.</span><span class="l_atom">__init</span>(<span class="l_atom">_self_0</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_0</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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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_keyword">local</span> <span class="l_atom">_parent_0</span> <span class="l_symbol">=</span> <span class="l_special">nil</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">_parent_0</span><span class="l_symbol">.</span><span class="l_atom">__base</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_atom">__base</span> <span class="l_symbol">=</span> <span class="l_atom">_base_0</span>,
|
||
<span class="l_atom">__name</span> <span class="l_symbol">=</span> <span class="l_string">"Person"</span>,
|
||
<span class="l_atom">__parent</span> <span class="l_symbol">=</span> <span class="l_atom">_parent_0</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_fn_symbol">function</span>(<span class="l_atom">cls</span>, <span class="l_atom">name</span>)
|
||
<span class="l_keyword">local</span> <span class="l_atom">val</span> <span class="l_symbol">=</span> <span class="l_atom">rawget</span>(<span class="l_atom">_base_0</span>, <span class="l_atom">name</span>)
|
||
<span class="l_keyword">if</span> <span class="l_atom">val</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_special">nil</span> <span class="l_keyword">and</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_atom">name</span>]
|
||
<span class="l_keyword">else</span>
|
||
<span class="l_keyword">return</span> <span class="l_atom">val</span>
|
||
<span class="l_keyword">end</span>
|
||
<span class="l_keyword">end</span>,
|
||
<span class="l_atom">__call</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">cls</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_0</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">cls</span><span class="l_symbol">.</span><span class="l_atom">__init</span>(<span class="l_atom">_self_0</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_0</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">local</span> <span class="l_atom">_list_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">_list_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">_list_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></code></pre></td></tr>
|
||
</tbody></table>
|
||
|
||
|
||
<p>The proper way to avoid this problem is to create the mutable state of the
|
||
object in the constructor:</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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">new</span><span class="l_bold_symbol">:</span> <span class="l_fn_symbol">=></span>
|
||
<span class="l_self_var">@clothes</span> <span class="l_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">Person</span>
|
||
<span class="l_atom">Person</span> <span class="l_symbol">=</span> (<span class="l_fn_symbol">function</span>()
|
||
<span class="l_keyword">local</span> <span class="l_atom">_parent_0</span> <span class="l_symbol">=</span> <span class="l_special">nil</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_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">_parent_0</span><span class="l_symbol">.</span><span class="l_atom">__base</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">clothes</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_atom">__base</span> <span class="l_symbol">=</span> <span class="l_atom">_base_0</span>,
|
||
<span class="l_atom">__name</span> <span class="l_symbol">=</span> <span class="l_string">"Person"</span>,
|
||
<span class="l_atom">__parent</span> <span class="l_symbol">=</span> <span class="l_atom">_parent_0</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_fn_symbol">function</span>(<span class="l_atom">cls</span>, <span class="l_atom">name</span>)
|
||
<span class="l_keyword">local</span> <span class="l_atom">val</span> <span class="l_symbol">=</span> <span class="l_atom">rawget</span>(<span class="l_atom">_base_0</span>, <span class="l_atom">name</span>)
|
||
<span class="l_keyword">if</span> <span class="l_atom">val</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_special">nil</span> <span class="l_keyword">and</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_atom">name</span>]
|
||
<span class="l_keyword">else</span>
|
||
<span class="l_keyword">return</span> <span class="l_atom">val</span>
|
||
<span class="l_keyword">end</span>
|
||
<span class="l_keyword">end</span>,
|
||
<span class="l_atom">__call</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">cls</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_0</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">cls</span><span class="l_symbol">.</span><span class="l_atom">__init</span>(<span class="l_atom">_self_0</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_0</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>
|
||
|
||
|
||
<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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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_keyword">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_keyword">local</span> <span class="l_atom">_parent_0</span> <span class="l_symbol">=</span> <span class="l_atom">Inventory</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">_parent_0</span><span class="l_symbol">.</span><span class="l_atom">__base</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_atom">__base</span> <span class="l_symbol">=</span> <span class="l_atom">_base_0</span>,
|
||
<span class="l_atom">__name</span> <span class="l_symbol">=</span> <span class="l_string">"BackPack"</span>,
|
||
<span class="l_atom">__parent</span> <span class="l_symbol">=</span> <span class="l_atom">_parent_0</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_fn_symbol">function</span>(<span class="l_atom">cls</span>, <span class="l_atom">name</span>)
|
||
<span class="l_keyword">local</span> <span class="l_atom">val</span> <span class="l_symbol">=</span> <span class="l_atom">rawget</span>(<span class="l_atom">_base_0</span>, <span class="l_atom">name</span>)
|
||
<span class="l_keyword">if</span> <span class="l_atom">val</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_special">nil</span> <span class="l_keyword">and</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_atom">name</span>]
|
||
<span class="l_keyword">else</span>
|
||
<span class="l_keyword">return</span> <span class="l_atom">val</span>
|
||
<span class="l_keyword">end</span>
|
||
<span class="l_keyword">end</span>,
|
||
<span class="l_atom">__call</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">cls</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_0</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">cls</span><span class="l_symbol">.</span><span class="l_atom">__init</span>(<span class="l_atom">_self_0</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_0</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>Here we extend our Inventory class, and limit the amount of items it can carry.</p>
|
||
|
||
<h3><a name="super"></a>Super</h3>
|
||
|
||
<p><code>super</code> is a special keyword that can be used in two different ways: It can be
|
||
treated as an object, or it can be called like a function. It only has special
|
||
functionality when inside a class.</p>
|
||
|
||
<p>When called as a function, it will call the function of the same name in the
|
||
parent class. The current <code>self</code> will automatically be passed as the first
|
||
argument. (As seen in the <a href="#inheritance">inheritance</a> example above)</p>
|
||
|
||
<p>When <code>super</code> is used as a normal value, it is a reference to the parent class
|
||
object.</p>
|
||
|
||
<p>It can be accessed like any of object in order to retrieve values in the
|
||
parent class that might have been shadowed by the child class.</p>
|
||
|
||
<p>When the <code>\</code> calling operator is used with <code>super</code>, <code>self</code> is inserted as the
|
||
first argument instead of the value of <code>super</code> itself. When using <code>.</code> to
|
||
retrieve a function, the raw function is returned.</p>
|
||
|
||
<p>A few examples of using <code>super</code> in different ways:</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td width="50%" class="code-border"><pre><code class="moon-code"><span class="l_keyword">class</span> <span class="l_proper">MyClass</span> <span class="l_keyword">extends</span> <span class="l_proper">ParentClass</span>
|
||
<span class="l_table_key">a_method</span><span class="l_bold_symbol">:</span> <span class="l_fn_symbol">=></span>
|
||
<span class="l_comment">-- the following have the same effect:
|
||
</span> <span class="l_keyword">super</span> <span class="l_string">"hello"</span>, <span class="l_string">"world"</span>
|
||
<span class="l_keyword">super</span><span class="l_symbol">\</span><span class="l_atom">a_method</span> <span class="l_string">"hello"</span>, <span class="l_string">"world"</span>
|
||
<span class="l_keyword">super</span><span class="l_bold_symbol">.</span><span class="l_atom">a_method</span> <span class="l_self">self</span>, <span class="l_string">"hello"</span>, <span class="l_string">"world"</span>
|
||
|
||
<span class="l_comment">-- super as a value is equal to the parent class:
|
||
</span> <span class="l_builtins">assert</span> <span class="l_keyword">super</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_proper">ParentClass</span></code></pre></td>
|
||
<td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">MyClass</span>
|
||
<span class="l_atom">MyClass</span> <span class="l_symbol">=</span> (<span class="l_fn_symbol">function</span>()
|
||
<span class="l_keyword">local</span> <span class="l_atom">_parent_0</span> <span class="l_symbol">=</span> <span class="l_atom">ParentClass</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">a_method</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">self</span>)
|
||
<span class="l_atom">_parent_0</span><span class="l_symbol">.</span><span class="l_atom">a_method</span>(<span class="l_atom">self</span>, <span class="l_string">"hello"</span>, <span class="l_string">"world"</span>)
|
||
<span class="l_atom">_parent_0</span><span class="l_symbol">.</span><span class="l_atom">a_method</span>(<span class="l_atom">self</span>, <span class="l_string">"hello"</span>, <span class="l_string">"world"</span>)
|
||
<span class="l_atom">_parent_0</span><span class="l_symbol">.</span><span class="l_atom">a_method</span>(<span class="l_atom">self</span>, <span class="l_string">"hello"</span>, <span class="l_string">"world"</span>)
|
||
<span class="l_keyword">return</span> <span class="l_builtins">assert</span>(<span class="l_atom">_parent_0</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_atom">ParentClass</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">_parent_0</span><span class="l_symbol">.</span><span class="l_atom">__base</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_atom">__base</span> <span class="l_symbol">=</span> <span class="l_atom">_base_0</span>,
|
||
<span class="l_atom">__name</span> <span class="l_symbol">=</span> <span class="l_string">"MyClass"</span>,
|
||
<span class="l_atom">__parent</span> <span class="l_symbol">=</span> <span class="l_atom">_parent_0</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_fn_symbol">function</span>(<span class="l_atom">cls</span>, <span class="l_atom">name</span>)
|
||
<span class="l_keyword">local</span> <span class="l_atom">val</span> <span class="l_symbol">=</span> <span class="l_atom">rawget</span>(<span class="l_atom">_base_0</span>, <span class="l_atom">name</span>)
|
||
<span class="l_keyword">if</span> <span class="l_atom">val</span> <span class="l_symbol">=</span><span class="l_symbol">=</span> <span class="l_special">nil</span> <span class="l_keyword">and</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_atom">name</span>]
|
||
<span class="l_keyword">else</span>
|
||
<span class="l_keyword">return</span> <span class="l_atom">val</span>
|
||
<span class="l_keyword">end</span>
|
||
<span class="l_keyword">end</span>,
|
||
<span class="l_atom">__call</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">cls</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_0</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">cls</span><span class="l_symbol">.</span><span class="l_atom">__init</span>(<span class="l_atom">_self_0</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_0</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><code>super</code> can also be used on left side of a <a href="#function_stubs">Function Stub</a>.
|
||
The only major difference is that instead of the resulting function being bound
|
||
to the value of <code>super</code>, it is bound to <code>self</code>.</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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td width="50%" class="code-border"><pre><code class="moon-code"><span class="l_comment">-- my_module.moon
|
||
</span><span class="l_builtins">module</span> <span class="l_string">"my_module"</span>, <span class="l_builtins">package.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_builtins">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_builtins">module</span>(<span class="l_string">"my_module"</span>, <span class="l_builtins">package.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_builtins">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>
|
||
|
||
|
||
<p>Assignment can be combined with the export keyword to assign to global
|
||
variables directly:</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td width="50%" class="code-border"><pre><code class="moon-code"><span class="l_keyword">export</span> <span class="l_atom">some_number</span>, <span class="l_atom">message_str</span> <span class="l_symbol">=</span> <span class="l_number">100</span>, <span class="l_string">"hello world"</span></code></pre></td>
|
||
<td><pre><code class="lua-code"><span class="l_atom">some_number</span>, <span class="l_atom">message_str</span> <span class="l_symbol">=</span> <span class="l_number">100</span>, <span class="l_string">"hello world"</span></code></pre></td></tr>
|
||
</tbody></table>
|
||
|
||
|
||
<p>Additionally, a class declaration can be prefixed with the export keyword in
|
||
order to export it.</p>
|
||
|
||
<h3><a name="export_all_and_export_proper"></a>Export All & Export Proper</h3>
|
||
|
||
<p>The <code>export</code> statement can also take special symbols <code>*</code> and <code>^</code>.</p>
|
||
|
||
<p><code>export *</code> will cause any name declared after the statement to be exported in the
|
||
current scope. <code>export ^</code> will export all proper names, names that begin with a
|
||
capital letter.</p>
|
||
|
||
<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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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>\</code> syntax). As a shortcut, we can prefix the name
|
||
with a <code>\</code> to bind it to that table:</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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_fn_symbol">function</span>()
|
||
<span class="l_keyword">local</span> <span class="l_atom">_base_0</span> <span class="l_symbol">=</span> <span class="l_atom">my_module</span>
|
||
<span class="l_keyword">local</span> <span class="l_atom">_fn_0</span> <span class="l_symbol">=</span> <span class="l_atom">_base_0</span><span class="l_symbol">.</span><span class="l_atom">add</span>
|
||
<span class="l_keyword">return</span> <span class="l_fn_symbol">function</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">_fn_0</span>(<span class="l_atom">_base_0</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_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. Within a <code>with</code> block we can use a
|
||
special statements that begin with either <code>.</code> or <code>\</code> which represent
|
||
those operations applied to the object we are using <code>with</code> on.</p>
|
||
|
||
<p>For example, we work with a newly created object:</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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">local</span> <span class="l_atom">_list_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">_list_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">_list_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">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="function_stubs"></a>Function Stubs</h2>
|
||
|
||
<p>It is common to pass a function from an object around as a value, for example,
|
||
passing an instance method into a function as a callback. If the function
|
||
expects the object it is operating on as the first argument then you must
|
||
somehow bundle that object with the function so it can be called properly.</p>
|
||
|
||
<p>The function stub syntax is a shorthand for creating a new closure function
|
||
that bundles both the object and function. This new function calls the wrapped
|
||
function in the correct context of the object.</p>
|
||
|
||
<p>Its syntax is the same as calling an instance method with the <code>\</code> operator but
|
||
with no argument list provided.</p>
|
||
|
||
<table width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td width="50%" class="code-border"><pre><code class="moon-code"><span class="l_atom">my_object</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">{</span>
|
||
<span class="l_table_key">value</span><span class="l_bold_symbol">:</span> <span class="l_number">1000</span>
|
||
<span class="l_table_key">write</span><span class="l_bold_symbol">:</span> <span class="l_fn_symbol">=></span> <span class="l_builtins">print</span> <span class="l_string">"the value:"</span>, <span class="l_self_var">@value</span>
|
||
<span class="l_fn_symbol">}</span>
|
||
|
||
<span class="l_atom">run_callback</span> (<span class="l_atom">func</span>) <span class="l_fn_symbol">-></span>
|
||
<span class="l_builtins">print</span> <span class="l_string">"running callback..."</span>
|
||
<span class="l_atom">func</span><span class="l_symbol">!</span>
|
||
|
||
<span class="l_comment">-- this will not work:
|
||
</span><span class="l_comment">-- the function has to no reference to my_object
|
||
</span><span class="l_atom">run_callback</span> <span class="l_atom">my_object</span><span class="l_bold_symbol">.</span><span class="l_atom">write</span>
|
||
|
||
<span class="l_comment">-- function stub syntax
|
||
</span><span class="l_comment">-- lets us bundle the object into a new function
|
||
</span><span class="l_atom">run_callback</span> <span class="l_atom">my_object</span><span class="l_symbol">\</span><span class="l_atom">write</span></code></pre></td>
|
||
<td><pre><code class="lua-code"><span class="l_keyword">local</span> <span class="l_atom">my_object</span> <span class="l_symbol">=</span> <span class="l_symbol">{</span>
|
||
<span class="l_atom">value</span> <span class="l_symbol">=</span> <span class="l_number">1000</span>,
|
||
<span class="l_atom">write</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">function</span>(<span class="l_atom">self</span>)
|
||
<span class="l_keyword">return</span> <span class="l_builtins">print</span>(<span class="l_string">"the value:"</span>, <span class="l_atom">self</span><span class="l_symbol">.</span><span class="l_atom">value</span>)
|
||
<span class="l_keyword">end</span>
|
||
<span class="l_symbol">}</span>
|
||
<span class="l_atom">run_callback</span>(<span class="l_fn_symbol">function</span>(<span class="l_atom">func</span>)
|
||
<span class="l_builtins">print</span>(<span class="l_string">"running callback..."</span>)
|
||
<span class="l_keyword">return</span> <span class="l_atom">func</span>()
|
||
<span class="l_keyword">end</span>)
|
||
<span class="l_atom">run_callback</span>(<span class="l_atom">my_object</span><span class="l_symbol">.</span><span class="l_atom">write</span>)
|
||
<span class="l_atom">run_callback</span>((<span class="l_fn_symbol">function</span>()
|
||
<span class="l_keyword">local</span> <span class="l_atom">_base_0</span> <span class="l_symbol">=</span> <span class="l_atom">my_object</span>
|
||
<span class="l_keyword">local</span> <span class="l_atom">_fn_0</span> <span class="l_symbol">=</span> <span class="l_atom">_base_0</span><span class="l_symbol">.</span><span class="l_atom">write</span>
|
||
<span class="l_keyword">return</span> <span class="l_fn_symbol">function</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">_fn_0</span>(<span class="l_atom">_base_0</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>)())</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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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_keyword">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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td width="50%" class="code-border"><pre><code class="moon-code"><span class="l_builtins">require</span> <span class="l_string">"moonscript"</span></code></pre></td>
|
||
<td><pre><code class="lua-code"><span class="l_builtins">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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td 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><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 width="100%" cellpadding="1" cellspacing="0"><tbody><tr class="code-header"><td>moonscript</td>
|
||
<td>lua</td></tr>
|
||
<tr><td width="50%" class="code-border"><pre><code class="moon-code"><span class="l_builtins">require</span> <span class="l_string">"moonscript.parse"</span>
|
||
<span class="l_builtins">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_builtins">require</span>(<span class="l_string">"moonscript.parse"</span>)
|
||
<span class="l_builtins">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="highlight lang_bash"><code><span class="nv">$ </span>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="highlight lang_bash"><code><span class="nv">$ </span>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">
|
||
|
||
<pre><code>Copyright (C) 2011 by Leaf Corcoran
|
||
|
||
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:
|
||
|
||
The above copyright notice and this permission notice shall be included in
|
||
all copies or substantial portions of the Software.
|
||
|
||
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.
|
||
</code></pre>
|
||
|
||
</div>
|
||
|
||
<div class="footer">Generated on Mon Dec 12 00:44:42 2011; MoonScript v0.2.0</div>
|
||
|
||
|
||
|
||
|
||
</body>
|
||
</html>
|