moonscript/docs/reference_manual.html

2417 lines
188 KiB
HTML
Raw Normal View History

2011-08-14 23:21:03 +00:00
<!DOCTYPE HTML>
<html lang="en">
<head>
2011-12-12 08:49:06 +00:00
<!-- Autogenerated from on Mon Dec 12 00:44:42 2011 -->
2011-08-14 23:21:03 +00:00
<meta charset="UTF-8">
2011-12-12 08:49:06 +00:00
<title>MoonScript v0.2.0 - Language Guide</title>
2011-08-14 23:21:03 +00:00
<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;
}
2011-12-12 08:49:06 +00:00
a.current {
color: black;
font-weight: bold;
text-decoration: none;
}
2011-08-14 23:21:03 +00:00
p {
line-height: 140%;
font-size: 16px;
}
.main {
width: 960px;
padding-left: 1em;
}
2011-12-12 08:49:06 +00:00
h1, h2, h3 {
2011-08-14 23:21:03 +00:00
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;
}
2011-12-12 08:49:06 +00:00
table, .bare-code, div > pre {
2011-08-14 23:21:03 +00:00
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);
}
2011-12-12 08:49:06 +00:00
div > pre {
padding: 8px;
}
2011-08-14 23:21:03 +00:00
.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;
}
2011-12-12 08:49:06 +00:00
.l_builtins, .nv {
2011-08-14 23:21:03 +00:00
color: #707A34;
}
.l_number {
color: #4958C3;
}
.footer {
color: #747678;
font-size: 80%;
padding: 8px;
}
2011-12-12 08:49:06 +00:00
.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;
}
2011-08-14 23:21:03 +00:00
</style>
</head><body>
<div class="header">
2011-12-12 08:49:06 +00:00
<h1>MoonScript v0.2.0 - Language Guide</h1>
2011-08-14 23:21:03 +00:00
</div>
2011-12-12 08:49:06 +00:00
<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 &amp; 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 &amp; 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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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
2011-08-14 23:21:03 +00:00
a certain amount. They are aliases for their expanded equivalents.</p>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<h2><a name="literals_and_operators"></a>Literals &amp; 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>-&gt;</code></p>
2011-12-12 08:49:06 +00:00
<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">-&gt;</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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<span class="l_atom">my_function</span>()</code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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">-&gt;</span> <span class="l_builtins">print</span> <span class="l_string">"hello world"</span>
2011-08-14 23:21:03 +00:00
<span class="l_atom">func_b</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">-&gt;</span>
<span class="l_atom">value</span> <span class="l_symbol">=</span> <span class="l_number">100</span>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>)
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span></code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<p>If a function has no arguments, it can be called using the <code>!</code> operator,
2011-08-22 15:02:50 +00:00
instead of empty parentheses. The <code>!</code> invocation is the preferred way to call
2011-08-14 23:21:03 +00:00
functions with no arguments.</p>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<p>Functions with arguments can be created by preceding the arrow with a list of
argument names in parentheses:</p>
2011-12-12 08:49:06 +00:00
<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">-&gt;</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>
2011-08-14 23:21:03 +00:00
<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>)
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span></code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<span class="l_builtins">print</span> <span class="l_atom">sum</span> <span class="l_number">10</span>, <span class="l_number">20</span>
2011-12-12 08:49:06 +00:00
<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>)
2011-08-14 23:21:03 +00:00
<span class="l_builtins">print</span>(<span class="l_atom">sum</span>(<span class="l_number">10</span>, <span class="l_number">20</span>))
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<p>Functions will coerce the last statement in their body into a return statement,
this is called implicit return:</p>
2011-12-12 08:49:06 +00:00
<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">-&gt;</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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<p>And if you need to explicitly return, you can use the <code>return</code> keyword:</p>
2011-12-12 08:49:06 +00:00
<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">-&gt;</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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span></code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<p>Just like in Lua, functions can return multiple values. The last statement must
be a list of values separated by commas:</p>
2011-12-12 08:49:06 +00:00
<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">-&gt;</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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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">=&gt;</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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span></code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<h3><a name="argument_defaults"></a>Argument Defaults</h3>
2011-08-22 15:02:50 +00:00
<p>It is possible to provide default values for the arguments of a function. An
2011-08-14 23:21:03 +00:00
argument is determined to be empty if its 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>
2011-12-12 08:49:06 +00:00
<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">-&gt;</span>
2011-08-14 23:21:03 +00:00
<span class="l_builtins">print</span> <span class="l_string">"Hello I am"</span>, <span class="l_atom">name</span>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>)
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span></code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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">-&gt;</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>
2011-08-14 23:21:03 +00:00
<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>)
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span></code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<span class="l_atom">b</span> <span class="l_symbol">=</span> <span class="l_atom">x</span><span class="l_number">-10</span>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>)
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>,
2011-12-12 08:49:06 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>,
2011-12-12 08:49:06 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-12-12 08:49:06 +00:00
<span class="l_symbol">}</span></code></pre></td></tr>
</tbody></table>
<p>The same thing can be done with other block level statements like
2011-10-01 20:05:57 +00:00
<a href="#conditionals">conditionals</a>. We can use indentation level to determine what
statement a value belongs to:</p>
2011-12-12 08:49:06 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>)
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span></code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<h2><a name="table_literals"></a>Table Literals</h2>
<p>Like in Lua, tables are delimited in curly braces.</p>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<span class="l_number">1</span>,
<span class="l_number">2</span>,
<span class="l_number">3</span>,
<span class="l_number">4</span>
2011-12-12 08:49:06 +00:00
<span class="l_symbol">}</span></code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<p>Unlike Lua, assigning a value to a key in a table is done with <code>:</code> (instead of
<code>=</code>).</p>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<span class="l_symbol">}</span></code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<p>The curly braces can be left off if a single table of key value pairs is being
assigned.</p>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>,
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<span class="l_symbol">}</span></code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<p>Newlines can be used to delimit values instead of a comma (or both):</p>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<span class="l_symbol">}</span></code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<p>When creating a single line table literal, the curly braces can also be left
off:</p>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<span class="l_symbol">}</span></code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<p>The keys of a table literal can be language keywords without being escaped:</p>
2011-12-12 08:49:06 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-12-12 08:49:06 +00:00
<span class="l_symbol">}</span>)</code></pre></td></tr>
</tbody></table>
2011-12-12 08:49:06 +00:00
<h2><a name="comprehensions"></a>Comprehensions</h2>
2011-08-14 23:21:03 +00:00
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<p>The following creates a copy of the <code>items</code> table but with all the values
doubled.</p>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-08-22 15:02:50 +00:00
<span class="l_keyword">local</span> <span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_number">0</span>
2011-08-14 23:21:03 +00:00
<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>
2011-08-22 15:02:50 +00:00
<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>
2011-08-14 23:21:03 +00:00
<span class="l_keyword">end</span>
<span class="l_keyword">return</span> <span class="l_atom">_accum_0</span>
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span>)()</code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<p>The items included in the new table can be restricted with a <code>when</code> clause:</p>
2011-12-12 08:49:06 +00:00
<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">&gt;</span> <span class="l_number">1</span> <span class="l_keyword">and</span> <span class="l_atom">i</span> <span class="l_symbol">&lt;</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>)
2011-08-14 23:21:03 +00:00
<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>
2011-08-22 15:02:50 +00:00
<span class="l_keyword">local</span> <span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_number">0</span>
2011-08-14 23:21:03 +00:00
<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> &gt; <span class="l_number">1</span> <span class="l_keyword">and</span> <span class="l_atom">i</span> &lt; <span class="l_number">3</span> <span class="l_keyword">then</span>
2011-08-22 15:02:50 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span>)()</code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>()
2011-08-14 23:21:03 +00:00
<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>
2011-08-22 15:02:50 +00:00
<span class="l_keyword">local</span> <span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_number">0</span>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<span class="l_keyword">end</span>
<span class="l_keyword">return</span> <span class="l_atom">_accum_0</span>
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span>)()</code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-08-22 15:02:50 +00:00
<span class="l_keyword">local</span> <span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_number">0</span>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>()
2011-08-14 23:21:03 +00:00
<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>
2011-08-22 15:02:50 +00:00
<span class="l_keyword">local</span> <span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_number">0</span>
2011-12-12 08:49:06 +00:00
<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> &lt; <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>
2011-08-14 23:21:03 +00:00
<span class="l_keyword">end</span>
<span class="l_keyword">return</span> <span class="l_atom">_accum_0</span>
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span>)()</code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>()
2011-08-14 23:21:03 +00:00
<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>
2011-08-22 15:02:50 +00:00
<span class="l_keyword">local</span> <span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_number">0</span>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<span class="l_keyword">end</span>
<span class="l_keyword">return</span> <span class="l_atom">_accum_0</span>
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span>)()</code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>()
2011-08-14 23:21:03 +00:00
<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>
2011-08-22 15:02:50 +00:00
<span class="l_keyword">local</span> <span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_number">0</span>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<span class="l_keyword">end</span>
<span class="l_keyword">return</span> <span class="l_atom">_accum_0</span>
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span>)()</code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>)
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span></code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<p>The slicing and <code>*</code> operators can be used, just like with table comprehensions:</p>
2011-12-12 08:49:06 +00:00
<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> &lt; <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>
2011-08-14 23:21:03 +00:00
<p>A shorter syntax is also available for all variations when the body is only a
single line:</p>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
2011-12-12 08:49:06 +00:00
<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>)
2011-08-14 23:21:03 +00:00
<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>)
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span></code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>()
2011-08-14 23:21:03 +00:00
<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>
2011-08-22 15:02:50 +00:00
<span class="l_keyword">local</span> <span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_number">0</span>
2011-08-14 23:21:03 +00:00
<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>
2011-08-22 15:02:50 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span>)()</code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<p>Filtering out odd numbers:</p>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-08-22 15:02:50 +00:00
<span class="l_keyword">local</span> <span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_number">0</span>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span>)()</code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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">-&gt;</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>
2011-08-14 23:21:03 +00:00
<span class="l_atom">func_b</span> <span class="l_symbol">=</span> <span class="l_fn_symbol">-&gt;</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
2011-12-12 08:49:06 +00:00
</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>
2011-08-14 23:21:03 +00:00
<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>
2011-08-22 15:02:50 +00:00
<span class="l_keyword">local</span> <span class="l_atom">_len_0</span> <span class="l_symbol">=</span> <span class="l_number">0</span>
2011-08-14 23:21:03 +00:00
<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>
2011-08-22 15:02:50 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>())
2011-12-12 08:49:06 +00:00
<span class="l_builtins">print</span>(<span class="l_atom">func_b</span>())</code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<p>This is done to avoid the needless creation of tables for functions that dont
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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<span class="l_keyword">while</span> <span class="l_atom">i</span> <span class="l_symbol">&gt;</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>
2011-12-12 08:49:06 +00:00
<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>
2011-10-01 20:05:57 +00:00
<span class="l_keyword">while</span> <span class="l_atom">i</span> &gt; <span class="l_number">0</span> <span class="l_keyword">do</span>
2011-08-14 23:21:03 +00:00
<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>
2011-10-01 20:05:57 +00:00
<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>
2011-08-14 23:21:03 +00:00
<span class="l_atom">my_function</span>()
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span></code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<p>Like for loops, the while loop can also be used an expression. Additionally,
2011-08-22 15:02:50 +00:00
for a function to return the accumulated value of a while loop, the statement
2011-08-14 23:21:03 +00:00
must be explicitly returned.</p>
<h2><a name="conditionals"></a>Conditionals</h2>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>)
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span></code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<p>A short syntax for single statements can also be used:</p>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>)
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span></code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<p>Because if statements can be used as expressions, this can able be written as:</p>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span>)())</code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<p>Conditionals can also be used in return statements and assignments:</p>
2011-12-12 08:49:06 +00:00
<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">-&gt;</span>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<span class="l_builtins">print</span>(<span class="l_atom">message</span>)</code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<span class="l_builtins">print</span>(<span class="l_string">"hello world"</span>)
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span></code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<p>And with basic loops:</p>
2011-12-12 08:49:06 +00:00
<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 switchs <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 cases
expression is on the left hand side. This can be useful if the cases
expression wants to overwrite how the comparison is done by defining an <code>eq</code>
metamethod.</p>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<span class="l_table_key">new</span><span class="l_bold_symbol">:</span> <span class="l_fn_symbol">=&gt;</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">=&gt;</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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>)
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<span class="l_symbol">}</span>, <span class="l_symbol">{</span>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span>)()</code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>()
2011-08-14 23:21:03 +00:00
<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>)
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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">=&gt;</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
2011-12-12 08:49:06 +00:00
</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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>)
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<span class="l_symbol">}</span>, <span class="l_symbol">{</span>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>)
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
2011-08-22 15:02:50 +00:00
<p>The proper way to avoid this problem is to create the mutable state of the
object in the constructor:</p>
2011-12-12 08:49:06 +00:00
<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>
2011-08-22 15:02:50 +00:00
<span class="l_table_key">new</span><span class="l_bold_symbol">:</span> <span class="l_fn_symbol">=&gt;</span>
2011-12-12 08:49:06 +00:00
<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>
2011-08-22 15:02:50 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>)
2011-08-22 15:02:50 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-22 15:02:50 +00:00
<span class="l_symbol">}</span>, <span class="l_symbol">{</span>
2011-12-12 08:49:06 +00:00
<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>
2011-08-22 15:02:50 +00:00
<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>
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span>)()</code></pre></td></tr>
</tbody></table>
2011-08-22 15:02:50 +00:00
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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">=&gt;</span>
<span class="l_keyword">if</span> <span class="l_symbol">#</span><span class="l_self_var">@items</span> <span class="l_symbol">&gt;</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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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> &gt; <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>
2011-12-12 08:49:06 +00:00
<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>)
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<span class="l_keyword">end</span>
2011-12-12 08:49:06 +00:00
<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">=&gt;</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>
2011-08-14 23:21:03 +00:00
<span class="l_symbol">}</span>, <span class="l_symbol">{</span>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span>)()</code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>()
2011-08-14 23:21:03 +00:00
<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>)
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<p>This is especially useful when declaring what will be externally visible in a
module:</p>
2011-12-12 08:49:06 +00:00
<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
2011-10-01 20:05:57 +00:00
</span><span class="l_builtins">module</span> <span class="l_string">"my_module"</span>, <span class="l_builtins">package.seeall</span>
2011-08-14 23:21:03 +00:00
<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">-&gt;</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">-&gt;</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
2011-10-01 20:05:57 +00:00
</span><span class="l_builtins">require</span> <span class="l_string">"my_module"</span>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>)
2011-08-14 23:21:03 +00:00
<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>
2011-10-01 20:05:57 +00:00
<span class="l_builtins">require</span>(<span class="l_string">"my_module"</span>)
2011-08-14 23:21:03 +00:00
<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>)
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
2011-10-31 05:17:53 +00:00
<h3><a name="export_all_and_export_proper"></a>Export All &amp; 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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<p>The multiple names can be given, each separated by a comma:</p>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<p>Sometimes a function requires that the table be sent in as the first argument
2011-10-31 05:17:53 +00:00
(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>
2011-08-14 23:21:03 +00:00
2011-12-12 08:49:06 +00:00
<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
2011-08-14 23:21:03 +00:00
</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">=&gt;</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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-10-01 20:05:57 +00:00
<p>The <code>with</code> block helps to alleviate this. Within a <code>with</code> block we can use a
2011-10-31 05:17:53 +00:00
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>
2011-10-01 20:05:57 +00:00
<p>For example, we work with a newly created object:</p>
2011-08-14 23:21:03 +00:00
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>)
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span></code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<p>The <code>with</code> statement can also be used as an expression which returns the value
it has been giving access to.</p>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span></code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<p>Or…</p>
2011-12-12 08:49:06 +00:00
<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">-&gt;</span>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>)
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<span class="l_symbol">}</span>)</code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
2011-10-01 20:05:57 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-10-01 20:05:57 +00:00
<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">=&gt;</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">-&gt;</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
2011-12-12 08:49:06 +00:00
</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>
2011-10-01 20:05:57 +00:00
<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>
2011-12-12 08:49:06 +00:00
<span class="l_keyword">end</span>)())</code></pre></td></tr>
</tbody></table>
2011-10-01 20:05:57 +00:00
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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">-&gt;</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">&gt;</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>()
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>
2011-10-01 20:05:57 +00:00
<span class="l_keyword">while</span> <span class="l_atom">i</span> &gt; <span class="l_number">0</span> <span class="l_keyword">do</span>
2011-08-14 23:21:03 +00:00
<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>()
2011-12-12 08:49:06 +00:00
<span class="l_builtins">print</span>(<span class="l_atom">i</span>)</code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<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 isnt
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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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">-&gt;</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>()
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>()
2011-12-12 08:49:06 +00:00
<span class="l_builtins">print</span>(<span class="l_atom">i</span>)</code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
<p>Multiple names can be separated by commas. Closure values can still be
accessed, they just cant be modified:</p>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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">-&gt;</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>)
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<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>)
2011-12-12 08:49:06 +00:00
<span class="l_builtins">print</span>(<span class="l_atom">i</span>, <span class="l_atom">k</span>)</code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
</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 Luas require function MoonScript aware.</p>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<p>After <code>moonscript</code> is required, Luas 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 Luas <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>
2011-12-12 08:49:06 +00:00
<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">-&gt;</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>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<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>
2011-08-14 23:21:03 +00:00
<p>The following error is generated:</p>
2011-12-12 08:49:06 +00:00
<pre><code>moon:err.moon:1: attempt to perform arithmetic on global 'z' (a nil value)
2011-08-14 23:21:03 +00:00
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>
2011-12-12 08:49:06 +00:00
<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>
2011-10-01 20:05:57 +00:00
<span class="l_builtins">require</span> <span class="l_string">"moonscript.compile"</span>
2011-08-14 23:21:03 +00:00
<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">-&gt;</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
2011-12-12 08:49:06 +00:00
</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>)
2011-10-01 20:05:57 +00:00
<span class="l_builtins">require</span>(<span class="l_string">"moonscript.compile"</span>)
2011-08-14 23:21:03 +00:00
<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">[[(-&gt; 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>
2011-12-12 08:49:06 +00:00
<span class="l_builtins">print</span>(<span class="l_atom">lua_code</span>)</code></pre></td></tr>
</tbody></table>
2011-08-14 23:21:03 +00:00
</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>
2011-12-12 08:49:06 +00:00
<pre class="highlight lang_bash"><code><span class="nv">$ </span>moon my_script.moon</code>
</pre>
2011-08-14 23:21:03 +00:00
<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>
2011-12-12 08:49:06 +00:00
<pre class="highlight lang_bash"><code><span class="nv">$ </span>moonc my_script1.moon my_script2.moon ...</code>
</pre>
2011-08-14 23:21:03 +00:00
<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">
2011-12-12 08:49:06 +00:00
<pre><code>Copyright (C) 2011 by Leaf Corcoran
2011-08-14 23:21:03 +00:00
2011-12-12 08:49:06 +00:00
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
2011-08-14 23:21:03 +00:00
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
2011-12-12 08:49:06 +00:00
furnished to do so, subject to the following conditions:
2011-08-14 23:21:03 +00:00
2011-12-12 08:49:06 +00:00
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
2011-08-14 23:21:03 +00:00
2011-12-12 08:49:06 +00:00
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2011-08-14 23:21:03 +00:00
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
2011-12-12 08:49:06 +00:00
THE SOFTWARE.
</code></pre>
2011-08-14 23:21:03 +00:00
</div>
2011-12-12 08:49:06 +00:00
<div class="footer">Generated on Mon Dec 12 00:44:42 2011; MoonScript v0.2.0</div>
2011-08-14 23:21:03 +00:00
</body>
</html>