mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
841 lines
No EOL
205 KiB
HTML
841 lines
No EOL
205 KiB
HTML
<!DOCTYPE html> <html> <head> <title>nodes.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To … <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="cake.html"> cake.coffee </a> <a class="source" href="coffee-script.html"> coffee-script.coffee </a> <a class="source" href="command.html"> command.coffee </a> <a class="source" href="grammar.html"> grammar.coffee </a> <a class="source" href="lexer.html"> lexer.coffee </a> <a class="source" href="nodes.html"> nodes.coffee </a> <a class="source" href="optparse.html"> optparse.coffee </a> <a class="source" href="repl.html"> repl.coffee </a> <a class="source" href="rewriter.html"> rewriter.coffee </a> <a class="source" href="scope.html"> scope.coffee </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> nodes.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-1">#</a> </div> <p><code>nodes.coffee</code> contains all of the node classes for the syntax tree. Most
|
|
nodes are created as the result of actions in the <a href="grammar.html">grammar</a>,
|
|
but some are created by other nodes as a method of code generation. To convert
|
|
the syntax tree into a string of JavaScript code, call <code>compile()</code> on the root.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>Set up for both <strong>Node.js</strong> and the browser, by
|
|
including the <a href="scope.html">Scope</a> class.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">if</span> <span class="nx">process</span><span class="o">?</span>
|
|
<span class="nx">process</span><span class="p">.</span><span class="nx">mixin</span> <span class="nx">require</span> <span class="s1">'scope'</span>
|
|
<span class="k">else</span>
|
|
<span class="k">this</span><span class="p">.</span><span class="nv">exports: </span><span class="k">this</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <p>Helper function that marks a node as a JavaScript <em>statement</em>, or as a
|
|
<em>pure_statement</em>. Statements must be wrapped in a closure when used as an
|
|
expression, and nodes tagged as <em>pure_statement</em> cannot be closure-wrapped
|
|
without losing their meaning.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">statement: </span><span class="p">(</span><span class="nx">klass</span><span class="p">,</span> <span class="nx">only</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">klass::is_statement: </span><span class="o">-></span> <span class="kc">true</span>
|
|
<span class="p">(</span><span class="nv">klass::is_pure_statement: </span><span class="o">-></span> <span class="kc">true</span><span class="p">)</span> <span class="k">if</span> <span class="nx">only</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <h3>BaseNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>The <strong>BaseNode</strong> is the abstract base class for all nodes in the syntax tree.
|
|
Each subclass implements the <code>compile_node</code> method, which performs the
|
|
code generation for that node. To compile a node to JavaScript,
|
|
call <code>compile</code> on it, which wraps <code>compile_node</code> in some generic extra smarts,
|
|
to know when the generated code needs to be wrapped up in a closure.
|
|
An options hash is passed and cloned throughout, containing information about
|
|
the environment from higher in the tree (such as if a returned value is
|
|
being requested by the surrounding function), information about the current
|
|
scope, and indentation level.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.BaseNode: </span><span class="nx">class</span> <span class="nx">BaseNode</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>Common logic for determining whether to wrap this node in a closure before
|
|
compiling it, or to compile directly. We need to wrap if this node is a
|
|
<em>statement</em>, and it's not a <em>pure_statement</em>, and we're not at
|
|
the top level of a block (which would be unnecessary), and we haven't
|
|
already been asked to return the result (because statements know how to
|
|
return results).</p>
|
|
|
|
<p>If a Node is <em>top_sensitive</em>, that means that it needs to compile differently
|
|
depending on whether it's being used as part of a larger expression, or is a
|
|
top-level statement within the function body.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">options: </span><span class="nx">merge</span> <span class="nx">o</span> <span class="o">or</span> <span class="p">{}</span>
|
|
<span class="err">@</span><span class="nv">tab: </span> <span class="nx">o</span><span class="p">.</span><span class="nx">indent</span>
|
|
<span class="nx">del</span> <span class="err">@</span><span class="nx">options</span><span class="p">,</span> <span class="s1">'operation'</span> <span class="nx">unless</span> <span class="err">@</span><span class="nx">operation_sensitive</span><span class="p">()</span>
|
|
<span class="nv">top: </span> <span class="k">if</span> <span class="err">@</span><span class="nx">top_sensitive</span><span class="p">()</span> <span class="k">then</span> <span class="err">@</span><span class="nx">options</span><span class="p">.</span><span class="nx">top</span> <span class="k">else</span> <span class="nx">del</span> <span class="err">@</span><span class="nx">options</span><span class="p">,</span> <span class="s1">'top'</span>
|
|
<span class="nv">closure: </span> <span class="err">@</span><span class="nx">is_statement</span><span class="p">()</span> <span class="o">and</span> <span class="o">not</span> <span class="err">@</span><span class="nx">is_pure_statement</span><span class="p">()</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">top</span> <span class="o">and</span>
|
|
<span class="o">not</span> <span class="err">@</span><span class="nx">options</span><span class="p">.</span><span class="nx">returns</span> <span class="o">and</span> <span class="o">not</span> <span class="p">(</span><span class="k">this</span> <span class="k">instanceof</span> <span class="nx">CommentNode</span><span class="p">)</span> <span class="o">and</span>
|
|
<span class="o">not</span> <span class="err">@</span><span class="nx">contains</span> <span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="o">-></span> <span class="nx">node</span><span class="p">.</span><span class="nx">is_pure_statement</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="nx">closure</span> <span class="k">then</span> <span class="err">@</span><span class="nx">compile_closure</span><span class="p">(</span><span class="err">@</span><span class="nx">options</span><span class="p">)</span> <span class="k">else</span> <span class="err">@</span><span class="nx">compile_node</span><span class="p">(</span><span class="err">@</span><span class="nx">options</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>Statements converted into expressions via closure-wrapping share a scope
|
|
object with their parent closure, to preserve the expected lexical scope.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_closure: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">tab: </span><span class="nx">o</span><span class="p">.</span><span class="nx">indent</span>
|
|
<span class="nv">o.shared_scope: </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span>
|
|
<span class="nx">ClosureNode</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">compile</span> <span class="nx">o</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</a> </div> <p>If the code generation wishes to use the result of a complex expression
|
|
in multiple places, ensure that the expression is only ever evaluated once,
|
|
by assigning it to a temporary variable.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_reference: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">reference: </span><span class="nx">literal</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">()</span>
|
|
<span class="nv">compiled: </span> <span class="k">new</span> <span class="nx">AssignNode</span> <span class="nx">reference</span><span class="p">,</span> <span class="k">this</span>
|
|
<span class="p">[</span><span class="nx">compiled</span><span class="p">,</span> <span class="nx">reference</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>Convenience method to grab the current indentation level, plus tabbing in.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">idt: </span><span class="p">(</span><span class="nx">tabs</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">idt: </span><span class="err">@</span><span class="nx">tab</span> <span class="o">or</span> <span class="s1">''</span>
|
|
<span class="nv">num: </span><span class="p">(</span><span class="nx">tabs</span> <span class="o">or</span> <span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>
|
|
<span class="nx">idt</span> <span class="o">+=</span> <span class="nx">TAB</span> <span class="k">while</span> <span class="nx">num</span> <span class="o">-=</span> <span class="mi">1</span>
|
|
<span class="nx">idt</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</a> </div> <p>Does this node, or any of its children, contain a node of a certain kind?
|
|
Recursively traverses down the <em>children</em> of the nodes, yielding to a block
|
|
and returning true when the block finds a match. <code>contains</code> does not cross
|
|
scope boundaries.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">contains: </span><span class="p">(</span><span class="nx">block</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="k">for</span> <span class="nx">node</span> <span class="k">in</span> <span class="err">@</span><span class="nx">children</span>
|
|
<span class="k">return</span> <span class="kc">true</span> <span class="k">if</span> <span class="nx">block</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="kc">true</span> <span class="k">if</span> <span class="nx">node</span><span class="p">.</span><span class="nx">contains</span> <span class="o">and</span> <span class="nx">node</span><span class="p">.</span><span class="nx">contains</span> <span class="nx">block</span>
|
|
<span class="kc">false</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-11">#</a> </div> <p>Perform an in-order traversal of the AST. Crosses scope boundaries.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">traverse: </span><span class="p">(</span><span class="nx">block</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="k">for</span> <span class="nx">node</span> <span class="k">in</span> <span class="err">@</span><span class="nx">children</span>
|
|
<span class="nx">block</span> <span class="nx">node</span>
|
|
<span class="nx">node</span><span class="p">.</span><span class="nx">traverse</span> <span class="nx">block</span> <span class="k">if</span> <span class="nx">node</span><span class="p">.</span><span class="nx">traverse</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-12">#</a> </div> <p><code>toString</code> representation of the node, for inspecting the parse tree.
|
|
This is what <code>coffee --nodes</code> prints out.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">toString: </span><span class="p">(</span><span class="nx">idt</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nx">idt</span> <span class="o">||=</span> <span class="s1">''</span>
|
|
<span class="s1">'\n'</span> <span class="o">+</span> <span class="nx">idt</span> <span class="o">+</span> <span class="err">@</span><span class="nx">type</span> <span class="o">+</span> <span class="p">(</span><span class="nx">child</span><span class="p">.</span><span class="nx">toString</span><span class="p">(</span><span class="nx">idt</span> <span class="o">+</span> <span class="nx">TAB</span><span class="p">)</span> <span class="k">for</span> <span class="nx">child</span> <span class="k">in</span> <span class="err">@</span><span class="nx">children</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s1">''</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-13">#</a> </div> <p>Default implementations of the common node identification methods. Nodes
|
|
will override these with custom logic, if needed.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">unwrap: </span> <span class="o">-></span> <span class="k">this</span>
|
|
<span class="nv">children: </span> <span class="p">[]</span>
|
|
<span class="nv">is_statement: </span> <span class="o">-></span> <span class="kc">false</span>
|
|
<span class="nv">is_pure_statement: </span> <span class="o">-></span> <span class="kc">false</span>
|
|
<span class="nv">top_sensitive: </span> <span class="o">-></span> <span class="kc">false</span>
|
|
<span class="nv">operation_sensitive: </span> <span class="o">-></span> <span class="kc">false</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-14">#</a> </div> <h3>Expressions</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-15">#</a> </div> <p>The expressions body is the list of expressions that forms the body of an
|
|
indented block of code -- the implementation of a function, a clause in an
|
|
<code>if</code>, <code>switch</code>, or <code>try</code>, and so on...</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Expressions: </span><span class="nx">class</span> <span class="nx">Expressions</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Expressions'</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">nodes</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">children: </span><span class="err">@</span><span class="nv">expressions: </span><span class="nx">compact</span> <span class="nx">flatten</span> <span class="nx">nodes</span> <span class="o">or</span> <span class="p">[]</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-16">#</a> </div> <p>Tack an expression on to the end of this expression list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">push: </span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span>
|
|
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-17">#</a> </div> <p>Add an expression at the beginning of this expression list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">unshift: </span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">unshift</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span>
|
|
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-18">#</a> </div> <p>If this Expressions consists of just a single node, unwrap it by pulling
|
|
it back out.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">unwrap: </span><span class="o">-></span>
|
|
<span class="k">if</span> <span class="err">@</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">length</span> <span class="o">is</span> <span class="mi">1</span> <span class="k">then</span> <span class="err">@</span><span class="nx">expressions</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">else</span> <span class="k">this</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-19">#</a> </div> <p>Is this an empty block of code?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">empty: </span><span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">length</span> <span class="o">is</span> <span class="mi">0</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-20">#</a> </div> <p>Is the given node the last one in this block of expressions?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">is_last: </span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">l: </span><span class="err">@</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">length</span>
|
|
<span class="nv">last_index: </span><span class="k">if</span> <span class="err">@</span><span class="nx">expressions</span><span class="p">[</span><span class="nx">l</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="k">instanceof</span> <span class="nx">CommentNode</span> <span class="k">then</span> <span class="mi">2</span> <span class="k">else</span> <span class="mi">1</span>
|
|
<span class="nx">node</span> <span class="o">is</span> <span class="err">@</span><span class="nx">expressions</span><span class="p">[</span><span class="nx">l</span> <span class="o">-</span> <span class="nx">last_index</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-21">#</a> </div> <p>An <strong>Expressions</strong> is the only node that can serve as the root.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nx">o</span> <span class="o">||=</span> <span class="p">{}</span>
|
|
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span> <span class="k">then</span> <span class="k">super</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">else</span> <span class="err">@</span><span class="nx">compile_root</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
|
|
|
|
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="p">(</span><span class="err">@</span><span class="nx">compile_expression</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">))</span> <span class="k">for</span> <span class="nx">node</span> <span class="k">in</span> <span class="err">@</span><span class="nx">expressions</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s2">"\n"</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-22">#</a> </div> <p>If we happen to be the top-level <strong>Expressions</strong>, wrap everything in
|
|
a safety closure, unless requested not to.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_root: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">o.indent: </span><span class="err">@</span><span class="nv">tab: </span><span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">no_wrap</span> <span class="k">then</span> <span class="s1">''</span> <span class="k">else</span> <span class="nx">TAB</span>
|
|
<span class="nv">o.scope: </span><span class="k">new</span> <span class="nx">Scope</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="k">this</span><span class="p">,</span> <span class="kc">null</span><span class="p">)</span>
|
|
<span class="nv">code: </span><span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">globals</span> <span class="k">then</span> <span class="err">@</span><span class="nx">compile_node</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">else</span> <span class="err">@</span><span class="nx">compile_with_declarations</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
|
|
<span class="nv">code: </span><span class="nx">code</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="nx">TRAILING_WHITESPACE</span><span class="p">,</span> <span class="s1">''</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">no_wrap</span> <span class="k">then</span> <span class="nx">code</span> <span class="k">else</span> <span class="s2">"(function(){\n$code\n})();\n"</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-23">#</a> </div> <p>Compile the expressions body for the contents of a function, with
|
|
declarations of all inner variables pushed up to the top.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_with_declarations: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">code: </span><span class="err">@</span><span class="nx">compile_node</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
|
|
<span class="nv">args: </span><span class="err">@</span><span class="nx">contains</span> <span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="o">-></span> <span class="nx">node</span> <span class="k">instanceof</span> <span class="nx">ValueNode</span> <span class="o">and</span> <span class="nx">node</span><span class="p">.</span><span class="nx">is_arguments</span><span class="p">()</span>
|
|
<span class="nv">code: </span><span class="s2">"${@tab}arguments = Array.prototype.slice.call(arguments, 0);\n$code"</span> <span class="k">if</span> <span class="nx">args</span>
|
|
<span class="nv">code: </span><span class="s2">"${@tab}var ${o.scope.compiled_assignments()};\n$code"</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">has_assignments</span><span class="p">(</span><span class="k">this</span><span class="p">)</span>
|
|
<span class="nv">code: </span><span class="s2">"${@tab}var ${o.scope.compiled_declarations()};\n$code"</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">has_declarations</span><span class="p">(</span><span class="k">this</span><span class="p">)</span>
|
|
<span class="nx">code</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-24">#</a> </div> <p>Compiles a single expression within the expressions body. If we need to
|
|
return the result, and it's an expression, simply return it. If it's a
|
|
statement, ask the statement to do so.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_expression: </span><span class="p">(</span><span class="nx">node</span><span class="p">,</span> <span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">tab: </span><span class="nx">o</span><span class="p">.</span><span class="nx">indent</span>
|
|
<span class="nv">stmt: </span> <span class="nx">node</span><span class="p">.</span><span class="nx">is_statement</span><span class="p">()</span>
|
|
<span class="nv">returns: </span><span class="nx">del</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="s1">'returns'</span><span class="p">)</span> <span class="o">and</span> <span class="err">@</span><span class="nx">is_last</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">node</span><span class="p">.</span><span class="nx">is_pure_statement</span><span class="p">()</span>
|
|
<span class="k">return</span> <span class="p">(</span><span class="k">if</span> <span class="nx">stmt</span> <span class="k">then</span> <span class="s1">''</span> <span class="k">else</span> <span class="err">@</span><span class="nx">idt</span><span class="p">())</span> <span class="o">+</span> <span class="nx">node</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="p">{</span><span class="nv">top: </span><span class="kc">true</span><span class="p">}))</span> <span class="o">+</span> <span class="p">(</span><span class="k">if</span> <span class="nx">stmt</span> <span class="k">then</span> <span class="s1">''</span> <span class="k">else</span> <span class="s1">';'</span><span class="p">)</span> <span class="nx">unless</span> <span class="nx">returns</span>
|
|
<span class="k">return</span> <span class="nx">node</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="p">{</span><span class="nv">returns: </span><span class="kc">true</span><span class="p">}))</span> <span class="k">if</span> <span class="nx">node</span><span class="p">.</span><span class="nx">is_statement</span><span class="p">()</span>
|
|
<span class="s2">"${@tab}return ${node.compile(o)};"</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-25">#</a> </div> <p>Wrap up the given nodes as an <strong>Expressions</strong>, unless it already happens
|
|
to be one.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">Expressions.wrap: </span><span class="p">(</span><span class="nx">nodes</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="k">return</span> <span class="nx">nodes</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="nx">nodes</span><span class="p">.</span><span class="nx">length</span> <span class="o">is</span> <span class="mi">1</span> <span class="o">and</span> <span class="nx">nodes</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">instanceof</span> <span class="nx">Expressions</span>
|
|
<span class="k">new</span> <span class="nx">Expressions</span><span class="p">(</span><span class="nx">nodes</span><span class="p">)</span>
|
|
|
|
<span class="nx">statement</span> <span class="nx">Expressions</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-26">#</a> </div> <h3>LiteralNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-27">#</a> </div> <p>Literals are static values that can be passed through directly into
|
|
JavaScript without translation, such as: strings, numbers,
|
|
<code>true</code>, <code>false</code>, <code>null</code>...</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.LiteralNode: </span><span class="nx">class</span> <span class="nx">LiteralNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Literal'</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">value: </span><span class="nx">value</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-28">#</a> </div> <p>Break and continue must be treated as pure statements -- they lose their
|
|
meaning when wrapped in a closure.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">is_statement: </span><span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">value</span> <span class="o">is</span> <span class="s1">'break'</span> <span class="o">or</span> <span class="err">@</span><span class="nx">value</span> <span class="o">is</span> <span class="s1">'continue'</span>
|
|
<span class="nv">is_pure_statement: </span><span class="nx">LiteralNode</span><span class="o">::</span><span class="nx">is_statement</span>
|
|
|
|
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">idt: </span><span class="k">if</span> <span class="err">@</span><span class="nx">is_statement</span><span class="p">()</span> <span class="k">then</span> <span class="err">@</span><span class="nx">idt</span><span class="p">()</span> <span class="k">else</span> <span class="s1">''</span>
|
|
<span class="nv">end: </span><span class="k">if</span> <span class="err">@</span><span class="nx">is_statement</span><span class="p">()</span> <span class="k">then</span> <span class="s1">';'</span> <span class="k">else</span> <span class="s1">''</span>
|
|
<span class="s2">"$idt$@value$end"</span>
|
|
|
|
<span class="nv">toString: </span><span class="p">(</span><span class="nx">idt</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="s2">" \"$@value\""</span></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-29">#</a> </div> <h3>ReturnNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-30">#</a> </div> <p>A <code>return</code> is a <em>pure_statement</em> -- wrapping it in a closure wouldn't
|
|
make sense.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ReturnNode: </span><span class="nx">class</span> <span class="nx">ReturnNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Return'</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">expression</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">children: </span><span class="p">[</span><span class="err">@</span><span class="nv">expression: </span><span class="nx">expression</span><span class="p">]</span>
|
|
|
|
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="k">return</span> <span class="err">@</span><span class="nx">expression</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="p">{</span><span class="nv">returns: </span><span class="kc">true</span><span class="p">}))</span> <span class="k">if</span> <span class="err">@</span><span class="nx">expression</span><span class="p">.</span><span class="nx">is_statement</span><span class="p">()</span>
|
|
<span class="s2">"${@tab}return ${@expression.compile(o)};"</span>
|
|
|
|
<span class="nx">statement</span> <span class="nx">ReturnNode</span><span class="p">,</span> <span class="kc">true</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-31">#</a> </div> <h3>ValueNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-32">#</a> </div> <p>A value, variable or literal or parenthesized, indexed or dotted into,
|
|
or vanilla.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ValueNode: </span><span class="nx">class</span> <span class="nx">ValueNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Value'</span>
|
|
|
|
<span class="nv">SOAK: </span><span class="s2">" == undefined ? undefined : "</span></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-33">#</a> </div> <p>A <strong>ValueNode</strong> has a base and a list of property accesses.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">constructor: </span><span class="p">(</span><span class="nx">base</span><span class="p">,</span> <span class="nx">properties</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">children: </span> <span class="nx">flatten</span> <span class="p">[</span><span class="err">@</span><span class="nv">base: </span><span class="nx">base</span><span class="p">,</span> <span class="err">@</span><span class="nv">properties: </span><span class="p">(</span><span class="nx">properties</span> <span class="o">or</span> <span class="p">[])]</span></pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-34">#</a> </div> <p>Add a property access to the list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">push: </span><span class="p">(</span><span class="nx">prop</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">properties</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">prop</span><span class="p">)</span>
|
|
<span class="err">@</span><span class="nx">children</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">prop</span><span class="p">)</span>
|
|
<span class="k">this</span>
|
|
|
|
<span class="nv">operation_sensitive: </span><span class="o">-></span>
|
|
<span class="kc">true</span>
|
|
|
|
<span class="nv">has_properties: </span><span class="o">-></span>
|
|
<span class="o">!!</span><span class="err">@</span><span class="nx">properties</span><span class="p">.</span><span class="nx">length</span></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-35">#</a> </div> <p>Some boolean checks for the benefit of other nodes.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">is_array: </span><span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">base</span> <span class="k">instanceof</span> <span class="nx">ArrayNode</span> <span class="o">and</span> <span class="o">not</span> <span class="err">@</span><span class="nx">has_properties</span><span class="p">()</span>
|
|
|
|
<span class="nv">is_object: </span><span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">base</span> <span class="k">instanceof</span> <span class="nx">ObjectNode</span> <span class="o">and</span> <span class="o">not</span> <span class="err">@</span><span class="nx">has_properties</span><span class="p">()</span>
|
|
|
|
<span class="nv">is_splice: </span><span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">has_properties</span><span class="p">()</span> <span class="o">and</span> <span class="err">@</span><span class="nx">properties</span><span class="p">[</span><span class="err">@</span><span class="nx">properties</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="k">instanceof</span> <span class="nx">SliceNode</span>
|
|
|
|
<span class="nv">is_arguments: </span><span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">base</span><span class="p">.</span><span class="nx">value</span> <span class="o">is</span> <span class="s1">'arguments'</span></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-36">#</a> </div> <p>The value can be unwrapped as its inner node, if there are no attached
|
|
properties.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">unwrap: </span><span class="o">-></span>
|
|
<span class="k">if</span> <span class="err">@</span><span class="nx">properties</span><span class="p">.</span><span class="nx">length</span> <span class="k">then</span> <span class="k">this</span> <span class="k">else</span> <span class="err">@</span><span class="nx">base</span></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-37">#</a> </div> <p>Values are considered to be statements if their base is a statement.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">is_statement: </span><span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">base</span><span class="p">.</span><span class="nx">is_statement</span> <span class="o">and</span> <span class="err">@</span><span class="nx">base</span><span class="p">.</span><span class="nx">is_statement</span><span class="p">()</span> <span class="o">and</span> <span class="o">not</span> <span class="err">@</span><span class="nx">has_properties</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-38"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-38">#</a> </div> <p>We compile a value to JavaScript by compiling and joining each property.
|
|
Things get much more insteresting if the chain of properties has <em>soak</em>
|
|
operators <code>?.</code> interspersed. Then we have to take care not to accidentally
|
|
evaluate a anything twice when building the soak chain.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">soaked: </span> <span class="kc">false</span>
|
|
<span class="nv">only: </span> <span class="nx">del</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="s1">'only_first'</span><span class="p">)</span>
|
|
<span class="nv">op: </span> <span class="nx">del</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="s1">'operation'</span><span class="p">)</span>
|
|
<span class="nv">props: </span> <span class="k">if</span> <span class="nx">only</span> <span class="k">then</span> <span class="err">@</span><span class="nx">properties</span><span class="p">[</span><span class="mi">0</span><span class="p">...</span><span class="err">@</span><span class="nx">properties</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="k">else</span> <span class="err">@</span><span class="nx">properties</span>
|
|
<span class="nv">baseline: </span><span class="err">@</span><span class="nx">base</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
|
|
<span class="nv">baseline: </span><span class="s2">"($baseline)"</span> <span class="k">if</span> <span class="err">@</span><span class="nx">base</span> <span class="k">instanceof</span> <span class="nx">ObjectNode</span> <span class="o">and</span> <span class="err">@</span><span class="nx">has_properties</span><span class="p">()</span>
|
|
<span class="nv">complete: </span><span class="err">@</span><span class="nv">last: </span><span class="nx">baseline</span>
|
|
|
|
<span class="k">for</span> <span class="nx">prop</span> <span class="k">in</span> <span class="nx">props</span>
|
|
<span class="err">@</span><span class="nv">source: </span><span class="nx">baseline</span>
|
|
<span class="k">if</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">soak_node</span>
|
|
<span class="nv">soaked: </span><span class="kc">true</span>
|
|
<span class="k">if</span> <span class="err">@</span><span class="nx">base</span> <span class="k">instanceof</span> <span class="nx">CallNode</span> <span class="o">and</span> <span class="nx">prop</span> <span class="o">is</span> <span class="nx">props</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="nv">temp: </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">()</span>
|
|
<span class="nv">complete: </span><span class="s2">"($temp = $complete)$@SOAK"</span> <span class="o">+</span> <span class="p">(</span><span class="nv">baseline: </span><span class="nx">temp</span> <span class="o">+</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">))</span>
|
|
<span class="k">else</span>
|
|
<span class="nv">complete: </span><span class="nx">complete</span> <span class="o">+</span> <span class="err">@</span><span class="nx">SOAK</span> <span class="o">+</span> <span class="p">(</span><span class="nx">baseline</span> <span class="o">+=</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">))</span>
|
|
<span class="k">else</span>
|
|
<span class="nv">part: </span><span class="nx">prop</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
|
|
<span class="nx">baseline</span> <span class="o">+=</span> <span class="nx">part</span>
|
|
<span class="nx">complete</span> <span class="o">+=</span> <span class="nx">part</span>
|
|
<span class="err">@</span><span class="nv">last: </span><span class="nx">part</span>
|
|
|
|
<span class="k">if</span> <span class="nx">op</span> <span class="o">and</span> <span class="nx">soaked</span> <span class="k">then</span> <span class="s2">"($complete)"</span> <span class="k">else</span> <span class="nx">complete</span></pre></div> </td> </tr> <tr id="section-39"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-39">#</a> </div> <h3>CommentNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-40"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-40">#</a> </div> <p>CoffeeScript passes through comments as JavaScript comments at the
|
|
same position.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.CommentNode: </span><span class="nx">class</span> <span class="nx">CommentNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Comment'</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">lines</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">lines: </span><span class="nx">lines</span>
|
|
<span class="k">this</span>
|
|
|
|
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="s2">"$@tab//"</span> <span class="o">+</span> <span class="err">@</span><span class="nx">lines</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s2">"\n$@tab//"</span><span class="p">)</span>
|
|
|
|
<span class="nx">statement</span> <span class="nx">CommentNode</span></pre></div> </td> </tr> <tr id="section-41"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-41">#</a> </div> <h3>CallNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-42"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-42">#</a> </div> <p>Node for a function invocation. Takes care of converting <code>super()</code> calls into
|
|
calls against the prototype's function of the same name.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.CallNode: </span><span class="nx">class</span> <span class="nx">CallNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Call'</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">variable</span><span class="p">,</span> <span class="nx">args</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">children: </span> <span class="nx">flatten</span> <span class="p">[</span><span class="err">@</span><span class="nv">variable: </span><span class="nx">variable</span><span class="p">,</span> <span class="err">@</span><span class="nv">args: </span><span class="p">(</span><span class="nx">args</span> <span class="o">or</span> <span class="p">[])]</span>
|
|
<span class="err">@</span><span class="nv">prefix: </span> <span class="s1">''</span></pre></div> </td> </tr> <tr id="section-43"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-43">#</a> </div> <p>Tag this invocation as creating a new instance.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">new_instance: </span><span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">prefix: </span><span class="s1">'new '</span>
|
|
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-44">#</a> </div> <p>Add an argument to the call's arugment list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">push: </span><span class="p">(</span><span class="nx">arg</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">args</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">arg</span><span class="p">)</span>
|
|
<span class="err">@</span><span class="nx">children</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">arg</span><span class="p">)</span>
|
|
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-45">#</a> </div> <p>Compile a vanilla function call.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="k">return</span> <span class="err">@</span><span class="nx">compile_splat</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="err">@</span><span class="nx">args</span><span class="p">[</span><span class="err">@</span><span class="nx">args</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="k">instanceof</span> <span class="nx">SplatNode</span>
|
|
<span class="nv">args: </span><span class="p">(</span><span class="nx">arg</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">for</span> <span class="nx">arg</span> <span class="k">in</span> <span class="err">@</span><span class="nx">args</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s1">', '</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="err">@</span><span class="nx">compile_super</span><span class="p">(</span><span class="nx">args</span><span class="p">,</span> <span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="err">@</span><span class="nx">variable</span> <span class="o">is</span> <span class="s1">'super'</span>
|
|
<span class="s2">"$@prefix${@variable.compile(o)}($args)"</span></pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-46">#</a> </div> <p><code>super()</code> is converted into a call against the superclass's implementation
|
|
of the current function.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_super: </span><span class="p">(</span><span class="nx">args</span><span class="p">,</span> <span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">methname: </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">method</span><span class="p">.</span><span class="nx">name</span>
|
|
<span class="nv">meth: </span><span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">method</span><span class="p">.</span><span class="nx">proto</span>
|
|
<span class="s2">"${o.scope.method.proto}.__superClass__.$methname"</span>
|
|
<span class="k">else</span>
|
|
<span class="s2">"${methname}.__superClass__.constructor"</span>
|
|
<span class="s2">"${meth}.call(this${ if args.length then ', ' else '' }$args)"</span></pre></div> </td> </tr> <tr id="section-47"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-47">#</a> </div> <p>If you call a function with a splat, it's converted into a JavaScript
|
|
<code>.apply()</code> call to allow the variable-length arguments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_splat: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">meth: </span><span class="err">@</span><span class="nx">variable</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
|
|
<span class="nv">obj: </span> <span class="err">@</span><span class="nx">variable</span><span class="p">.</span><span class="nx">source</span> <span class="o">or</span> <span class="s1">'this'</span>
|
|
<span class="k">if</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/\(/</span><span class="p">)</span>
|
|
<span class="nv">temp: </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">()</span>
|
|
<span class="nv">obj: </span> <span class="nx">temp</span>
|
|
<span class="nv">meth: </span><span class="s2">"($temp = ${ @variable.source })${ @variable.last }"</span>
|
|
<span class="nv">args: </span><span class="k">for</span> <span class="nx">arg</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="err">@</span><span class="nx">args</span>
|
|
<span class="nv">code: </span><span class="nx">arg</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
|
|
<span class="nv">code: </span><span class="k">if</span> <span class="nx">arg</span> <span class="k">instanceof</span> <span class="nx">SplatNode</span> <span class="k">then</span> <span class="nx">code</span> <span class="k">else</span> <span class="s2">"[$code]"</span>
|
|
<span class="k">if</span> <span class="nx">i</span> <span class="o">is</span> <span class="mi">0</span> <span class="k">then</span> <span class="nx">code</span> <span class="k">else</span> <span class="s2">".concat($code)"</span>
|
|
<span class="s2">"$@prefix${meth}.apply($obj, ${ args.join('') })"</span></pre></div> </td> </tr> <tr id="section-48"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-48">#</a> </div> <h3>ExtendsNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-49">#</a> </div> <p>Node to extend an object's prototype with an ancestor object.
|
|
After <code>goog.inherits</code> from the
|
|
<a href="http://closure-library.googlecode.com/svn/docs/closure_goog_base.js.html">Closure Library</a>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ExtendsNode: </span><span class="nx">class</span> <span class="nx">ExtendsNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Extends'</span>
|
|
|
|
<span class="nv">code: </span><span class="s1">'''</span>
|
|
<span class="s1"> function(child, parent) {</span>
|
|
<span class="s1"> var ctor = function(){ };</span>
|
|
<span class="s1"> ctor.prototype = parent.prototype;</span>
|
|
<span class="s1"> child.__superClass__ = parent.prototype;</span>
|
|
<span class="s1"> child.prototype = new ctor();</span>
|
|
<span class="s1"> child.prototype.constructor = child;</span>
|
|
<span class="s1"> }</span>
|
|
<span class="s1"> '''</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">child</span><span class="p">,</span> <span class="nx">parent</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">children: </span> <span class="p">[</span><span class="err">@</span><span class="nv">child: </span><span class="nx">child</span><span class="p">,</span> <span class="err">@</span><span class="nv">parent: </span><span class="nx">parent</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-50">#</a> </div> <p>Hooks one constructor into another's prototype chain.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">assign</span><span class="p">(</span><span class="s1">'__extends'</span><span class="p">,</span> <span class="err">@</span><span class="nx">code</span><span class="p">,</span> <span class="kc">true</span><span class="p">)</span>
|
|
<span class="nv">ref: </span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">literal</span><span class="p">(</span><span class="s1">'__extends'</span><span class="p">)</span>
|
|
<span class="nv">call: </span><span class="k">new</span> <span class="nx">CallNode</span> <span class="nx">ref</span><span class="p">,</span> <span class="p">[</span><span class="err">@</span><span class="nx">child</span><span class="p">,</span> <span class="err">@</span><span class="nx">parent</span><span class="p">]</span>
|
|
<span class="nx">call</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-51">#</a> </div> <h3>AccessorNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-52"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-52">#</a> </div> <p>A <code>.</code> accessor into a property of a value, or the <code>::</code> shorthand for
|
|
an accessor into the object's prototype.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.AccessorNode: </span><span class="nx">class</span> <span class="nx">AccessorNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Accessor'</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">tag</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">children: </span> <span class="p">[</span><span class="err">@</span><span class="nv">name: </span><span class="nx">name</span><span class="p">]</span>
|
|
<span class="err">@</span><span class="nv">prototype: </span><span class="nx">tag</span> <span class="o">is</span> <span class="s1">'prototype'</span>
|
|
<span class="err">@</span><span class="nv">soak_node: </span><span class="nx">tag</span> <span class="o">is</span> <span class="s1">'soak'</span>
|
|
<span class="k">this</span>
|
|
|
|
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="s1">'.'</span> <span class="o">+</span> <span class="p">(</span><span class="k">if</span> <span class="err">@</span><span class="nx">prototype</span> <span class="k">then</span> <span class="s1">'prototype.'</span> <span class="k">else</span> <span class="s1">''</span><span class="p">)</span> <span class="o">+</span> <span class="err">@</span><span class="nx">name</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-53"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-53">#</a> </div> <h3>IndexNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-54"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-54">#</a> </div> <p>An indexed accessor into an array or object.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.IndexNode: </span><span class="nx">class</span> <span class="nx">IndexNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Index'</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">index</span><span class="p">,</span> <span class="nx">tag</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">children: </span> <span class="p">[</span><span class="err">@</span><span class="nv">index: </span><span class="nx">index</span><span class="p">]</span>
|
|
<span class="err">@</span><span class="nv">soak_node: </span><span class="nx">tag</span> <span class="o">is</span> <span class="s1">'soak'</span>
|
|
|
|
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">idx: </span><span class="err">@</span><span class="nx">index</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
|
|
<span class="s2">"[$idx]"</span></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-55">#</a> </div> <h3>RangeNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-56"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-56">#</a> </div> <p>A range literal. Ranges can be used to extract portions (slices) of arrays,
|
|
to specify a range for comprehensions, or as a value, to be expanded into the
|
|
corresponding array of integers at runtime.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.RangeNode: </span><span class="nx">class</span> <span class="nx">RangeNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Range'</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">from</span><span class="p">,</span> <span class="nx">to</span><span class="p">,</span> <span class="nx">exclusive</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">children: </span> <span class="p">[</span><span class="err">@</span><span class="nv">from: </span><span class="nx">from</span><span class="p">,</span> <span class="err">@</span><span class="nv">to: </span><span class="nx">to</span><span class="p">]</span>
|
|
<span class="err">@</span><span class="nv">exclusive: </span><span class="o">!!</span><span class="nx">exclusive</span></pre></div> </td> </tr> <tr id="section-57"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-57">#</a> </div> <p>Compiles the range's source variables -- where it starts and where it ends.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_variables: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">tab: </span><span class="nx">o</span><span class="p">.</span><span class="nx">indent</span>
|
|
<span class="p">[</span><span class="err">@</span><span class="nx">from_var</span><span class="p">,</span> <span class="err">@</span><span class="nx">to_var</span><span class="p">]</span><span class="o">:</span> <span class="p">[</span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">(),</span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">()]</span>
|
|
<span class="p">[</span><span class="nx">from</span><span class="p">,</span> <span class="nx">to</span><span class="p">]</span><span class="o">:</span> <span class="p">[</span><span class="err">@</span><span class="nx">from</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">),</span> <span class="err">@</span><span class="nx">to</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)]</span>
|
|
<span class="s2">"$@from_var = $from; $@to_var = $to;\n$@tab"</span></pre></div> </td> </tr> <tr id="section-58"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-58">#</a> </div> <p>When compiled normally, the range returns the contents of the <em>for loop</em>
|
|
needed to iterate over the values in the range. Used by comprehensions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="k">return</span> <span class="err">@</span><span class="nx">compile_array</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="nx">unless</span> <span class="nx">o</span><span class="p">.</span><span class="nx">index</span>
|
|
<span class="nv">idx: </span> <span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">'index'</span>
|
|
<span class="nv">step: </span> <span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">'step'</span>
|
|
<span class="nv">vars: </span> <span class="s2">"$idx = $@from_var"</span>
|
|
<span class="nv">step: </span> <span class="k">if</span> <span class="nx">step</span> <span class="k">then</span> <span class="nx">step</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">else</span> <span class="s1">'1'</span>
|
|
<span class="nv">equals: </span> <span class="k">if</span> <span class="err">@</span><span class="nx">exclusive</span> <span class="k">then</span> <span class="s1">''</span> <span class="k">else</span> <span class="s1">'='</span>
|
|
<span class="nv">intro: </span> <span class="s2">"($@from_var <= $@to_var ? $idx"</span>
|
|
<span class="nv">compare: </span> <span class="s2">"$intro <$equals $@to_var : $idx >$equals $@to_var)"</span>
|
|
<span class="nv">incr: </span> <span class="s2">"$intro += $step : $idx -= $step)"</span>
|
|
<span class="s2">"$vars; $compare; $incr"</span></pre></div> </td> </tr> <tr id="section-59"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-59">#</a> </div> <p>When used as a value, expand the range into the equivalent array. In the
|
|
future, the code this generates should probably be cleaned up by handwriting
|
|
it instead of wrapping nodes.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_array: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">name: </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">()</span>
|
|
<span class="nv">body: </span><span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="nx">literal</span><span class="p">(</span><span class="nx">name</span><span class="p">)])</span>
|
|
<span class="nv">arr: </span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="k">new</span> <span class="nx">ForNode</span><span class="p">(</span><span class="nx">body</span><span class="p">,</span> <span class="p">{</span><span class="nv">source: </span><span class="p">(</span><span class="k">new</span> <span class="nx">ValueNode</span><span class="p">(</span><span class="k">this</span><span class="p">))},</span> <span class="nx">literal</span><span class="p">(</span><span class="nx">name</span><span class="p">))])</span>
|
|
<span class="p">(</span><span class="k">new</span> <span class="nx">ParentheticalNode</span><span class="p">(</span><span class="k">new</span> <span class="nx">CallNode</span><span class="p">(</span><span class="k">new</span> <span class="nx">CodeNode</span><span class="p">([],</span> <span class="nx">arr</span><span class="p">)))).</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-60"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-60">#</a> </div> <h3>SliceNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-61"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-61">#</a> </div> <p>An array slice literal. Unlike JavaScript's <code>Array#slice</code>, the second parameter
|
|
specifies the index of the end of the slice, just as the first parameter
|
|
is the index of the beginning.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.SliceNode: </span><span class="nx">class</span> <span class="nx">SliceNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Slice'</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">range</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">children: </span><span class="p">[</span><span class="err">@</span><span class="nv">range: </span><span class="nx">range</span><span class="p">]</span>
|
|
<span class="k">this</span>
|
|
|
|
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">from: </span> <span class="err">@</span><span class="nx">range</span><span class="p">.</span><span class="nx">from</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
|
|
<span class="nv">to: </span> <span class="err">@</span><span class="nx">range</span><span class="p">.</span><span class="nx">to</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
|
|
<span class="nv">plus_part: </span> <span class="k">if</span> <span class="err">@</span><span class="nx">range</span><span class="p">.</span><span class="nx">exclusive</span> <span class="k">then</span> <span class="s1">''</span> <span class="k">else</span> <span class="s1">' + 1'</span>
|
|
<span class="s2">".slice($from, $to$plus_part)"</span></pre></div> </td> </tr> <tr id="section-62"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-62">#</a> </div> <h3>ObjectNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-63"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-63">#</a> </div> <p>An object literal, nothing fancy.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ObjectNode: </span><span class="nx">class</span> <span class="nx">ObjectNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Object'</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">props</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">children: </span><span class="err">@</span><span class="nv">objects: </span><span class="err">@</span><span class="nv">properties: </span><span class="nx">props</span> <span class="o">or</span> <span class="p">[]</span></pre></div> </td> </tr> <tr id="section-64"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-64">#</a> </div> <p>All the mucking about with commas is to make sure that CommentNodes and
|
|
AssignNodes get interleaved correctly, with no trailing commas or
|
|
commas affixed to comments.</p>
|
|
|
|
<p><em>TODO: Extract this and add it to ArrayNode</em>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">o.indent: </span><span class="err">@</span><span class="nx">idt</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
|
<span class="nv">non_comments: </span><span class="nx">prop</span> <span class="k">for</span> <span class="nx">prop</span> <span class="k">in</span> <span class="err">@</span><span class="nx">properties</span> <span class="k">when</span> <span class="o">not</span> <span class="p">(</span><span class="nx">prop</span> <span class="k">instanceof</span> <span class="nx">CommentNode</span><span class="p">)</span>
|
|
<span class="nv">last_noncom: </span> <span class="nx">non_comments</span><span class="p">[</span><span class="nx">non_comments</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span>
|
|
<span class="nv">props: </span><span class="k">for</span> <span class="nx">prop</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="err">@</span><span class="nx">properties</span>
|
|
<span class="nv">join: </span> <span class="s2">",\n"</span>
|
|
<span class="nv">join: </span> <span class="s2">"\n"</span> <span class="k">if</span> <span class="p">(</span><span class="nx">prop</span> <span class="o">is</span> <span class="nx">last_noncom</span><span class="p">)</span> <span class="o">or</span> <span class="p">(</span><span class="nx">prop</span> <span class="k">instanceof</span> <span class="nx">CommentNode</span><span class="p">)</span>
|
|
<span class="nv">join: </span> <span class="s1">''</span> <span class="k">if</span> <span class="nx">i</span> <span class="o">is</span> <span class="err">@</span><span class="nx">properties</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span>
|
|
<span class="nv">indent: </span><span class="k">if</span> <span class="nx">prop</span> <span class="k">instanceof</span> <span class="nx">CommentNode</span> <span class="k">then</span> <span class="s1">''</span> <span class="k">else</span> <span class="err">@</span><span class="nx">idt</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
|
<span class="nx">indent</span> <span class="o">+</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">+</span> <span class="nx">join</span>
|
|
<span class="nv">props: </span><span class="nx">props</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">''</span><span class="p">)</span>
|
|
<span class="nv">inner: </span><span class="k">if</span> <span class="nx">props</span> <span class="k">then</span> <span class="s1">'\n'</span> <span class="o">+</span> <span class="nx">props</span> <span class="o">+</span> <span class="s1">'\n'</span> <span class="o">+</span> <span class="err">@</span><span class="nx">idt</span><span class="p">()</span> <span class="k">else</span> <span class="s1">''</span>
|
|
<span class="s2">"{$inner}"</span></pre></div> </td> </tr> <tr id="section-65"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-65">#</a> </div> <h3>ArrayNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-66"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-66">#</a> </div> <p>An array literal.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ArrayNode: </span><span class="nx">class</span> <span class="nx">ArrayNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Array'</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">objects</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">children: </span><span class="err">@</span><span class="nv">objects: </span><span class="nx">objects</span> <span class="o">or</span> <span class="p">[]</span>
|
|
|
|
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">o.indent: </span><span class="err">@</span><span class="nx">idt</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
|
<span class="nv">objects: </span><span class="k">for</span> <span class="nx">obj</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="err">@</span><span class="nx">objects</span>
|
|
<span class="nv">code: </span><span class="nx">obj</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">CommentNode</span>
|
|
<span class="s2">"\n$code\n$o.indent"</span>
|
|
<span class="k">else</span> <span class="k">if</span> <span class="nx">i</span> <span class="o">is</span> <span class="err">@</span><span class="nx">objects</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span>
|
|
<span class="nx">code</span>
|
|
<span class="k">else</span>
|
|
<span class="s2">"$code, "</span>
|
|
<span class="nv">objects: </span><span class="nx">objects</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">''</span><span class="p">)</span>
|
|
<span class="nv">ending: </span><span class="k">if</span> <span class="nx">objects</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">'\n'</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">0</span> <span class="k">then</span> <span class="s2">"\n$@tab]"</span> <span class="k">else</span> <span class="s1">']'</span>
|
|
<span class="s2">"[$objects$ending"</span></pre></div> </td> </tr> <tr id="section-67"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-67">#</a> </div> <h3>ClassNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-68"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-68">#</a> </div> <p>The CoffeeScript class definition.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ClassNode: </span><span class="nx">class</span> <span class="nx">ClassNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Class'</span></pre></div> </td> </tr> <tr id="section-69"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-69">#</a> </div> <p>Initialize a <strong>ClassNode</strong> with its name, an optional superclass, and a
|
|
list of prototype property assignments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">constructor: </span><span class="p">(</span><span class="nx">variable</span><span class="p">,</span> <span class="nx">parent</span><span class="p">,</span> <span class="nx">props</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">children: </span><span class="nx">compact</span> <span class="nx">flatten</span> <span class="p">[</span><span class="err">@</span><span class="nv">variable: </span><span class="nx">variable</span><span class="p">,</span> <span class="err">@</span><span class="nv">parent: </span><span class="nx">parent</span><span class="p">,</span> <span class="err">@</span><span class="nv">properties: </span><span class="nx">props</span> <span class="o">or</span> <span class="p">[]]</span></pre></div> </td> </tr> <tr id="section-70"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-70">#</a> </div> <p>Instead of generating the JavaScript string directly, we build up the
|
|
equivalent syntax tree and compile that, in pieces. You can see the
|
|
constructor, property assignments, and inheritance getting built out below.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">extension: </span> <span class="err">@</span><span class="nx">parent</span> <span class="o">and</span> <span class="k">new</span> <span class="nx">ExtendsNode</span><span class="p">(</span><span class="err">@</span><span class="nx">variable</span><span class="p">,</span> <span class="err">@</span><span class="nx">parent</span><span class="p">)</span>
|
|
<span class="nv">constructor: </span><span class="kc">null</span>
|
|
<span class="nv">props: </span> <span class="k">new</span> <span class="nx">Expressions</span><span class="p">()</span>
|
|
<span class="nv">o.top: </span> <span class="kc">true</span>
|
|
<span class="nv">ret: </span> <span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">'returns'</span>
|
|
|
|
<span class="k">for</span> <span class="nx">prop</span> <span class="k">in</span> <span class="err">@</span><span class="nx">properties</span>
|
|
<span class="k">if</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">variable</span> <span class="o">and</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">variable</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">value</span> <span class="o">is</span> <span class="s1">'constructor'</span>
|
|
<span class="nv">func: </span><span class="nx">prop</span><span class="p">.</span><span class="nx">value</span>
|
|
<span class="nx">func</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="k">new</span> <span class="nx">ReturnNode</span><span class="p">(</span><span class="nx">literal</span><span class="p">(</span><span class="s1">'this'</span><span class="p">)))</span>
|
|
<span class="nv">constructor: </span><span class="k">new</span> <span class="nx">AssignNode</span><span class="p">(</span><span class="err">@</span><span class="nx">variable</span><span class="p">,</span> <span class="nx">func</span><span class="p">)</span>
|
|
<span class="k">else</span>
|
|
<span class="k">if</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">variable</span>
|
|
<span class="nv">val: </span><span class="k">new</span> <span class="nx">ValueNode</span><span class="p">(</span><span class="err">@</span><span class="nx">variable</span><span class="p">,</span> <span class="p">[</span><span class="k">new</span> <span class="nx">AccessorNode</span><span class="p">(</span><span class="nx">prop</span><span class="p">.</span><span class="nx">variable</span><span class="p">,</span> <span class="s1">'prototype'</span><span class="p">)])</span>
|
|
<span class="nv">prop: </span><span class="k">new</span> <span class="nx">AssignNode</span><span class="p">(</span><span class="nx">val</span><span class="p">,</span> <span class="nx">prop</span><span class="p">.</span><span class="nx">value</span><span class="p">)</span>
|
|
<span class="nx">props</span><span class="p">.</span><span class="nx">push</span> <span class="nx">prop</span>
|
|
|
|
<span class="k">if</span> <span class="o">not</span> <span class="nx">constructor</span>
|
|
<span class="k">if</span> <span class="err">@</span><span class="nx">parent</span>
|
|
<span class="nv">applied: </span><span class="k">new</span> <span class="nx">ValueNode</span><span class="p">(</span><span class="err">@</span><span class="nx">parent</span><span class="p">,</span> <span class="p">[</span><span class="k">new</span> <span class="nx">AccessorNode</span><span class="p">(</span><span class="nx">literal</span><span class="p">(</span><span class="s1">'apply'</span><span class="p">))])</span>
|
|
<span class="nv">constructor: </span><span class="k">new</span> <span class="nx">AssignNode</span><span class="p">(</span><span class="err">@</span><span class="nx">variable</span><span class="p">,</span> <span class="k">new</span> <span class="nx">CodeNode</span><span class="p">([],</span> <span class="k">new</span> <span class="nx">Expressions</span><span class="p">([</span>
|
|
<span class="k">new</span> <span class="nx">CallNode</span><span class="p">(</span><span class="nx">applied</span><span class="p">,</span> <span class="p">[</span><span class="nx">literal</span><span class="p">(</span><span class="s1">'this'</span><span class="p">),</span> <span class="nx">literal</span><span class="p">(</span><span class="s1">'arguments'</span><span class="p">)])</span>
|
|
<span class="p">])))</span>
|
|
<span class="k">else</span>
|
|
<span class="nv">constructor: </span><span class="k">new</span> <span class="nx">AssignNode</span><span class="p">(</span><span class="err">@</span><span class="nx">variable</span><span class="p">,</span> <span class="k">new</span> <span class="nx">CodeNode</span><span class="p">())</span>
|
|
|
|
<span class="nv">construct: </span> <span class="err">@</span><span class="nx">idt</span><span class="p">()</span> <span class="o">+</span> <span class="nx">constructor</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">+</span> <span class="s1">';\n'</span>
|
|
<span class="nv">props: </span> <span class="k">if</span> <span class="nx">props</span><span class="p">.</span><span class="nx">empty</span><span class="p">()</span> <span class="k">then</span> <span class="s1">''</span> <span class="k">else</span> <span class="nx">props</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">+</span> <span class="s1">'\n'</span>
|
|
<span class="nv">extension: </span><span class="k">if</span> <span class="nx">extension</span> <span class="k">then</span> <span class="err">@</span><span class="nx">idt</span><span class="p">()</span> <span class="o">+</span> <span class="nx">extension</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">+</span> <span class="s1">';\n'</span> <span class="k">else</span> <span class="s1">''</span>
|
|
<span class="nv">returns: </span> <span class="k">if</span> <span class="nx">ret</span> <span class="k">then</span> <span class="s1">'\n'</span> <span class="o">+</span> <span class="err">@</span><span class="nx">idt</span><span class="p">()</span> <span class="o">+</span> <span class="s1">'return '</span> <span class="o">+</span> <span class="err">@</span><span class="nx">variable</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">+</span> <span class="s1">';'</span> <span class="k">else</span> <span class="s1">''</span>
|
|
<span class="s2">"$construct$extension$props$returns"</span>
|
|
|
|
<span class="nx">statement</span> <span class="nx">ClassNode</span></pre></div> </td> </tr> <tr id="section-71"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-71">#</a> </div> <h3>PushNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-72"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-72">#</a> </div> <p>A faux-node that is never created by the grammar, but is used during
|
|
code generation to generate a quick <code>array.push(value)</code> tree of nodes.
|
|
Helpful for recording the result arrays from comprehensions.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">PushNode: exports.PushNode: </span><span class="p">{</span>
|
|
|
|
<span class="nv">wrap: </span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="nx">expressions</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">expr: </span><span class="nx">expressions</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span>
|
|
<span class="k">return</span> <span class="nx">expressions</span> <span class="k">if</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">is_pure_statement</span><span class="p">()</span> <span class="o">or</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">contains</span> <span class="p">(</span><span class="nx">n</span><span class="p">)</span> <span class="o">-></span> <span class="nx">n</span><span class="p">.</span><span class="nx">is_pure_statement</span><span class="p">()</span>
|
|
<span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="k">new</span> <span class="nx">CallNode</span><span class="p">(</span>
|
|
<span class="k">new</span> <span class="nx">ValueNode</span><span class="p">(</span><span class="nx">literal</span><span class="p">(</span><span class="nx">array</span><span class="p">),</span> <span class="p">[</span><span class="k">new</span> <span class="nx">AccessorNode</span><span class="p">(</span><span class="nx">literal</span><span class="p">(</span><span class="s1">'push'</span><span class="p">))]),</span> <span class="p">[</span><span class="nx">expr</span><span class="p">]</span>
|
|
<span class="p">)])</span>
|
|
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-73"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-73">#</a> </div> <h3>ClosureNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-74"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-74">#</a> </div> <p>A faux-node used to wrap an expressions body in a closure.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">ClosureNode: exports.ClosureNode: </span><span class="p">{</span>
|
|
|
|
<span class="nv">wrap: </span><span class="p">(</span><span class="nx">expressions</span><span class="p">,</span> <span class="nx">statement</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">func: </span><span class="k">new</span> <span class="nx">ParentheticalNode</span><span class="p">(</span><span class="k">new</span> <span class="nx">CodeNode</span><span class="p">([],</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="nx">expressions</span><span class="p">])))</span>
|
|
<span class="nv">call: </span><span class="k">new</span> <span class="nx">CallNode</span><span class="p">(</span><span class="k">new</span> <span class="nx">ValueNode</span><span class="p">(</span><span class="nx">func</span><span class="p">,</span> <span class="p">[</span><span class="k">new</span> <span class="nx">AccessorNode</span><span class="p">(</span><span class="nx">literal</span><span class="p">(</span><span class="s1">'call'</span><span class="p">))]),</span> <span class="p">[</span><span class="nx">literal</span><span class="p">(</span><span class="s1">'this'</span><span class="p">)])</span>
|
|
<span class="k">if</span> <span class="nx">statement</span> <span class="k">then</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="nx">call</span><span class="p">])</span> <span class="k">else</span> <span class="nx">call</span>
|
|
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-75"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-75">#</a> </div> <h3>AssignNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-76"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-76">#</a> </div> <p>The <strong>AssignNode</strong> is used to assign a local variable to value, or to set the
|
|
property of an object -- including within object literals.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.AssignNode: </span><span class="nx">class</span> <span class="nx">AssignNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Assign'</span></pre></div> </td> </tr> <tr id="section-77"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-77">#</a> </div> <p>Matchers for detecting prototype assignments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">PROTO_ASSIGN: </span><span class="sr">/^(\S+)\.prototype/</span>
|
|
<span class="nv">LEADING_DOT: </span> <span class="sr">/^\.(prototype\.)?/</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">variable</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">children: </span><span class="p">[</span><span class="err">@</span><span class="nv">variable: </span><span class="nx">variable</span><span class="p">,</span> <span class="err">@</span><span class="nv">value: </span><span class="nx">value</span><span class="p">]</span>
|
|
<span class="err">@</span><span class="nv">context: </span><span class="nx">context</span>
|
|
|
|
<span class="nv">top_sensitive: </span><span class="o">-></span>
|
|
<span class="kc">true</span>
|
|
|
|
<span class="nv">is_value: </span><span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">variable</span> <span class="k">instanceof</span> <span class="nx">ValueNode</span>
|
|
|
|
<span class="nv">is_statement: </span><span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">is_value</span><span class="p">()</span> <span class="o">and</span> <span class="p">(</span><span class="err">@</span><span class="nx">variable</span><span class="p">.</span><span class="nx">is_array</span><span class="p">()</span> <span class="o">or</span> <span class="err">@</span><span class="nx">variable</span><span class="p">.</span><span class="nx">is_object</span><span class="p">())</span></pre></div> </td> </tr> <tr id="section-78"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-78">#</a> </div> <p>Compile an assignment, delegating to <code>compile_pattern_match</code> or
|
|
<code>compile_splice</code> if appropriate. Keep track of the name of the base object
|
|
we've been assigned to, for correct internal references. If the variable
|
|
has not been seen yet within the current scope, declare it.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">top: </span> <span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">'top'</span>
|
|
<span class="k">return</span> <span class="err">@</span><span class="nx">compile_pattern_match</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="err">@</span><span class="nx">is_statement</span><span class="p">()</span>
|
|
<span class="k">return</span> <span class="err">@</span><span class="nx">compile_splice</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="err">@</span><span class="nx">is_value</span><span class="p">()</span> <span class="o">and</span> <span class="err">@</span><span class="nx">variable</span><span class="p">.</span><span class="nx">is_splice</span><span class="p">()</span>
|
|
<span class="nv">stmt: </span> <span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">'as_statement'</span>
|
|
<span class="nv">name: </span> <span class="err">@</span><span class="nx">variable</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
|
|
<span class="nv">last: </span> <span class="k">if</span> <span class="err">@</span><span class="nx">is_value</span><span class="p">()</span> <span class="k">then</span> <span class="err">@</span><span class="nx">variable</span><span class="p">.</span><span class="nx">last</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="err">@</span><span class="nx">LEADING_DOT</span><span class="p">,</span> <span class="s1">''</span><span class="p">)</span> <span class="k">else</span> <span class="nx">name</span>
|
|
<span class="nv">match: </span> <span class="nx">name</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="err">@</span><span class="nx">PROTO_ASSIGN</span><span class="p">)</span>
|
|
<span class="nv">proto: </span> <span class="nx">match</span> <span class="o">and</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="err">@</span><span class="nx">value</span> <span class="k">instanceof</span> <span class="nx">CodeNode</span>
|
|
<span class="err">@</span><span class="nv">value.name: </span> <span class="nx">last</span> <span class="k">if</span> <span class="nx">last</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">IDENTIFIER</span><span class="p">)</span>
|
|
<span class="err">@</span><span class="nv">value.proto: </span><span class="nx">proto</span> <span class="k">if</span> <span class="nx">proto</span>
|
|
<span class="nv">val: </span><span class="err">@</span><span class="nx">value</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
|
|
<span class="k">return</span> <span class="s2">"$name: $val"</span> <span class="k">if</span> <span class="err">@</span><span class="nx">context</span> <span class="o">is</span> <span class="s1">'object'</span>
|
|
<span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">find</span> <span class="nx">name</span> <span class="nx">unless</span> <span class="err">@</span><span class="nx">is_value</span><span class="p">()</span> <span class="o">and</span> <span class="err">@</span><span class="nx">variable</span><span class="p">.</span><span class="nx">has_properties</span><span class="p">()</span>
|
|
<span class="nv">val: </span><span class="s2">"$name = $val"</span>
|
|
<span class="k">return</span> <span class="s2">"$@tab$val;"</span> <span class="k">if</span> <span class="nx">stmt</span>
|
|
<span class="nv">val: </span><span class="s2">"($val)"</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">top</span> <span class="o">or</span> <span class="nx">o</span><span class="p">.</span><span class="nx">returns</span>
|
|
<span class="nv">val: </span><span class="s2">"${@tab}return $val"</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">returns</span>
|
|
<span class="nx">val</span></pre></div> </td> </tr> <tr id="section-79"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-79">#</a> </div> <p>Brief implementation of recursive pattern matching, when assigning array or
|
|
object literals to a value. Peeks at their properties to assign inner names.
|
|
See the <a href="http://wiki.ecmascript.org/doku.php?id=harmony:destructuring">ECMAScript Harmony Wiki</a>
|
|
for details.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_pattern_match: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">val_var: </span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">()</span>
|
|
<span class="nv">value: </span><span class="k">if</span> <span class="err">@</span><span class="nx">value</span><span class="p">.</span><span class="nx">is_statement</span><span class="p">()</span> <span class="k">then</span> <span class="nx">ClosureNode</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="err">@</span><span class="nx">value</span><span class="p">)</span> <span class="k">else</span> <span class="err">@</span><span class="nx">value</span>
|
|
<span class="nv">assigns: </span><span class="p">[</span><span class="s2">"$@tab$val_var = ${ value.compile(o) };"</span><span class="p">]</span>
|
|
<span class="nv">o.top: </span><span class="kc">true</span>
|
|
<span class="nv">o.as_statement: </span><span class="kc">true</span>
|
|
<span class="k">for</span> <span class="nx">obj</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="err">@</span><span class="nx">variable</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">objects</span>
|
|
<span class="nv">idx: </span><span class="nx">i</span>
|
|
<span class="p">[</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">idx</span><span class="p">]</span><span class="o">:</span> <span class="p">[</span><span class="nx">obj</span><span class="p">.</span><span class="nx">value</span><span class="p">,</span> <span class="nx">obj</span><span class="p">.</span><span class="nx">variable</span><span class="p">.</span><span class="nx">base</span><span class="p">]</span> <span class="k">if</span> <span class="err">@</span><span class="nx">variable</span><span class="p">.</span><span class="nx">is_object</span><span class="p">()</span>
|
|
<span class="nv">access_class: </span><span class="k">if</span> <span class="err">@</span><span class="nx">variable</span><span class="p">.</span><span class="nx">is_array</span><span class="p">()</span> <span class="k">then</span> <span class="nx">IndexNode</span> <span class="k">else</span> <span class="nx">AccessorNode</span>
|
|
<span class="k">if</span> <span class="nx">obj</span> <span class="k">instanceof</span> <span class="nx">SplatNode</span>
|
|
<span class="nv">val: </span><span class="nx">literal</span><span class="p">(</span><span class="nx">obj</span><span class="p">.</span><span class="nx">compile_value</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">val_var</span><span class="p">,</span> <span class="err">@</span><span class="nx">variable</span><span class="p">.</span><span class="nx">base</span><span class="p">.</span><span class="nx">objects</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">obj</span><span class="p">)))</span>
|
|
<span class="k">else</span>
|
|
<span class="nv">idx: </span><span class="nx">literal</span><span class="p">(</span><span class="nx">idx</span><span class="p">)</span> <span class="nx">unless</span> <span class="k">typeof</span> <span class="nx">idx</span> <span class="o">is</span> <span class="s1">'object'</span>
|
|
<span class="nv">val: </span><span class="k">new</span> <span class="nx">ValueNode</span><span class="p">(</span><span class="nx">literal</span><span class="p">(</span><span class="nx">val_var</span><span class="p">),</span> <span class="p">[</span><span class="k">new</span> <span class="nx">access_class</span><span class="p">(</span><span class="nx">idx</span><span class="p">)])</span>
|
|
<span class="nx">assigns</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="k">new</span> <span class="nx">AssignNode</span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">val</span><span class="p">).</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">))</span>
|
|
<span class="nv">code: </span><span class="nx">assigns</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s2">"\n"</span><span class="p">)</span>
|
|
<span class="nx">code</span> <span class="o">+=</span> <span class="s2">"\n${@tab}return ${ @variable.compile(o) };"</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">returns</span>
|
|
<span class="nx">code</span></pre></div> </td> </tr> <tr id="section-80"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-80">#</a> </div> <p>Compile the assignment from an array splice literal, using JavaScript's
|
|
<code>Array#splice</code> method.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_splice: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">name: </span> <span class="err">@</span><span class="nx">variable</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="p">{</span><span class="nv">only_first: </span><span class="kc">true</span><span class="p">}))</span>
|
|
<span class="nv">l: </span> <span class="err">@</span><span class="nx">variable</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">length</span>
|
|
<span class="nv">range: </span> <span class="err">@</span><span class="nx">variable</span><span class="p">.</span><span class="nx">properties</span><span class="p">[</span><span class="nx">l</span> <span class="o">-</span> <span class="mi">1</span><span class="p">].</span><span class="nx">range</span>
|
|
<span class="nv">plus: </span> <span class="k">if</span> <span class="nx">range</span><span class="p">.</span><span class="nx">exclusive</span> <span class="k">then</span> <span class="s1">''</span> <span class="k">else</span> <span class="s1">' + 1'</span>
|
|
<span class="nv">from: </span> <span class="nx">range</span><span class="p">.</span><span class="nx">from</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
|
|
<span class="nv">to: </span> <span class="nx">range</span><span class="p">.</span><span class="nx">to</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">+</span> <span class="s1">' - '</span> <span class="o">+</span> <span class="nx">from</span> <span class="o">+</span> <span class="nx">plus</span>
|
|
<span class="nv">val: </span> <span class="err">@</span><span class="nx">value</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
|
|
<span class="s2">"${name}.splice.apply($name, [$from, $to].concat($val))"</span></pre></div> </td> </tr> <tr id="section-81"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-81">#</a> </div> <h3>CodeNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-82"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-82">#</a> </div> <p>A function definition. This is the only node that creates a new Scope.
|
|
When for the purposes of walking the contents of a function body, the CodeNode
|
|
has no <em>children</em> -- they're within the inner scope.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.CodeNode: </span><span class="nx">class</span> <span class="nx">CodeNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Code'</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">params</span><span class="p">,</span> <span class="nx">body</span><span class="p">,</span> <span class="nx">tag</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">params: </span> <span class="nx">params</span> <span class="o">or</span> <span class="p">[]</span>
|
|
<span class="err">@</span><span class="nv">body: </span> <span class="nx">body</span> <span class="o">or</span> <span class="k">new</span> <span class="nx">Expressions</span><span class="p">()</span>
|
|
<span class="err">@</span><span class="nv">bound: </span> <span class="nx">tag</span> <span class="o">is</span> <span class="s1">'boundfunc'</span></pre></div> </td> </tr> <tr id="section-83"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-83">#</a> </div> <p>Compilation creates a new scope unless explicitly asked to share with the
|
|
outer scope. Handles splat parameters in the parameter list by peeking at
|
|
the JavaScript <code>arguments</code> objects. If the function is bound with the <code>=></code>
|
|
arrow, generates a wrapper that saves the current value of <code>this</code> through
|
|
a closure.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">shared_scope: </span><span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">'shared_scope'</span>
|
|
<span class="nv">top: </span> <span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">'top'</span>
|
|
<span class="nv">o.scope: </span> <span class="nx">shared_scope</span> <span class="o">or</span> <span class="k">new</span> <span class="nx">Scope</span><span class="p">(</span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">,</span> <span class="err">@</span><span class="nx">body</span><span class="p">,</span> <span class="k">this</span><span class="p">)</span>
|
|
<span class="nv">o.returns: </span> <span class="kc">true</span>
|
|
<span class="nv">o.top: </span> <span class="kc">true</span>
|
|
<span class="nv">o.indent: </span> <span class="err">@</span><span class="nx">idt</span><span class="p">(</span><span class="k">if</span> <span class="err">@</span><span class="nx">bound</span> <span class="k">then</span> <span class="mi">2</span> <span class="k">else</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">'no_wrap'</span>
|
|
<span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">'globals'</span>
|
|
<span class="k">if</span> <span class="err">@</span><span class="nx">params</span><span class="p">[</span><span class="err">@</span><span class="nx">params</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="k">instanceof</span> <span class="nx">SplatNode</span>
|
|
<span class="nv">splat: </span><span class="err">@</span><span class="nx">params</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span>
|
|
<span class="nv">splat.index: </span><span class="err">@</span><span class="nx">params</span><span class="p">.</span><span class="nx">length</span>
|
|
<span class="err">@</span><span class="nx">body</span><span class="p">.</span><span class="nx">unshift</span><span class="p">(</span><span class="nx">splat</span><span class="p">)</span>
|
|
<span class="nv">params: </span><span class="p">(</span><span class="nx">param</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">for</span> <span class="nx">param</span> <span class="k">in</span> <span class="err">@</span><span class="nx">params</span><span class="p">)</span>
|
|
<span class="p">(</span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">parameter</span><span class="p">(</span><span class="nx">param</span><span class="p">))</span> <span class="k">for</span> <span class="nx">param</span> <span class="k">in</span> <span class="nx">params</span>
|
|
<span class="nv">code: </span><span class="k">if</span> <span class="err">@</span><span class="nx">body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">.</span><span class="nx">length</span> <span class="k">then</span> <span class="s2">"\n${ @body.compile_with_declarations(o) }\n"</span> <span class="k">else</span> <span class="s1">''</span>
|
|
<span class="nv">name_part: </span><span class="k">if</span> <span class="err">@</span><span class="nx">name</span> <span class="k">then</span> <span class="s1">' '</span> <span class="o">+</span> <span class="err">@</span><span class="nx">name</span> <span class="k">else</span> <span class="s1">''</span>
|
|
<span class="nv">func: </span><span class="s2">"function${ if @bound then '' else name_part }(${ params.join(', ') }) {$code${@idt(if @bound then 1 else 0)}}"</span>
|
|
<span class="nv">func: </span><span class="s2">"($func)"</span> <span class="k">if</span> <span class="nx">top</span> <span class="o">and</span> <span class="o">not</span> <span class="err">@</span><span class="nx">bound</span>
|
|
<span class="k">return</span> <span class="nx">func</span> <span class="nx">unless</span> <span class="err">@</span><span class="nx">bound</span>
|
|
<span class="nv">inner: </span><span class="s2">"(function$name_part() {\n${@idt(2)}return __func.apply(__this, arguments);\n${@idt(1)}});"</span>
|
|
<span class="s2">"(function(__this) {\n${@idt(1)}var __func = $func;\n${@idt(1)}return $inner\n$@tab})(this)"</span>
|
|
|
|
<span class="nv">top_sensitive: </span><span class="o">-></span>
|
|
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-84"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-84">#</a> </div> <p>When traversing (for printing or inspecting), return the real children of
|
|
the function -- the parameters and body of expressions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">real_children: </span><span class="o">-></span>
|
|
<span class="nx">flatten</span> <span class="p">[</span><span class="err">@</span><span class="nx">params</span><span class="p">,</span> <span class="err">@</span><span class="nx">body</span><span class="p">.</span><span class="nx">expressions</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-85"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-85">#</a> </div> <p>Custom <code>traverse</code> implementation that uses the <code>real_children</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">traverse: </span><span class="p">(</span><span class="nx">block</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nx">block</span> <span class="k">this</span>
|
|
<span class="nx">block</span><span class="p">(</span><span class="nx">child</span><span class="p">)</span> <span class="k">for</span> <span class="nx">child</span> <span class="k">in</span> <span class="err">@</span><span class="nx">real_children</span><span class="p">()</span>
|
|
|
|
<span class="nv">toString: </span><span class="p">(</span><span class="nx">idt</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nx">idt</span> <span class="o">||=</span> <span class="s1">''</span>
|
|
<span class="nv">children: </span><span class="p">(</span><span class="nx">child</span><span class="p">.</span><span class="nx">toString</span><span class="p">(</span><span class="nx">idt</span> <span class="o">+</span> <span class="nx">TAB</span><span class="p">)</span> <span class="k">for</span> <span class="nx">child</span> <span class="k">in</span> <span class="err">@</span><span class="nx">real_children</span><span class="p">()).</span><span class="nx">join</span><span class="p">(</span><span class="s1">''</span><span class="p">)</span>
|
|
<span class="s2">"\n$idt$children"</span></pre></div> </td> </tr> <tr id="section-86"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-86">#</a> </div> <h3>SplatNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-87"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-87">#</a> </div> <p>A splat, either as a parameter to a function, an argument to a call,
|
|
or as part of a destructuring assignment.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.SplatNode: </span><span class="nx">class</span> <span class="nx">SplatNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Splat'</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">name: </span><span class="nx">literal</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="nx">unless</span> <span class="nx">name</span><span class="p">.</span><span class="nx">compile</span>
|
|
<span class="err">@</span><span class="nv">children: </span><span class="p">[</span><span class="err">@</span><span class="nv">name: </span><span class="nx">name</span><span class="p">]</span>
|
|
|
|
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="k">if</span> <span class="err">@</span><span class="nx">index</span><span class="o">?</span> <span class="k">then</span> <span class="err">@</span><span class="nx">compile_param</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">else</span> <span class="err">@</span><span class="nx">name</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-88"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-88">#</a> </div> <p>Compiling a parameter splat means recovering the parameters that succeed
|
|
the splat in the parameter list, by slicing the arguments object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_param: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">name: </span><span class="err">@</span><span class="nx">name</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
|
|
<span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">find</span> <span class="nx">name</span>
|
|
<span class="s2">"$name = Array.prototype.slice.call(arguments, $@index)"</span></pre></div> </td> </tr> <tr id="section-89"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-89">#</a> </div> <p>A compiling a splat as a destructuring assignment means slicing arguments
|
|
from the right-hand-side's corresponding array.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_value: </span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="s2">"Array.prototype.slice.call($name, $index)"</span></pre></div> </td> </tr> <tr id="section-90"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-90">#</a> </div> <h3>WhileNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-91"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-91">#</a> </div> <p>A while loop, the only sort of low-level loop exposed by CoffeeScript. From
|
|
it, all other loops can be manufactured. Useful in cases where you need more
|
|
flexibility or more speed than a comprehension can provide.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.WhileNode: </span><span class="nx">class</span> <span class="nx">WhileNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'While'</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">condition</span><span class="p">,</span> <span class="nx">opts</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">children</span><span class="o">:</span><span class="p">[</span><span class="err">@</span><span class="nv">condition: </span><span class="nx">condition</span><span class="p">]</span>
|
|
<span class="err">@</span><span class="nv">filter: </span><span class="nx">opts</span> <span class="o">and</span> <span class="nx">opts</span><span class="p">.</span><span class="nx">filter</span>
|
|
|
|
<span class="nv">add_body: </span><span class="p">(</span><span class="nx">body</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">children</span><span class="p">.</span><span class="nx">push</span> <span class="err">@</span><span class="nv">body: </span><span class="nx">body</span>
|
|
<span class="k">this</span>
|
|
|
|
<span class="nv">top_sensitive: </span><span class="o">-></span>
|
|
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-92"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-92">#</a> </div> <p>The main difference from a JavaScript <em>while</em> is that the CoffeeScript
|
|
<em>while</em> can be used as a part of a larger expression -- while loops may
|
|
return an array containing the computed result of each iteration.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">returns: </span> <span class="nx">del</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="s1">'returns'</span><span class="p">)</span>
|
|
<span class="nv">top: </span> <span class="nx">del</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="s1">'top'</span><span class="p">)</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">returns</span>
|
|
<span class="nv">o.indent: </span> <span class="err">@</span><span class="nx">idt</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
|
<span class="nv">o.top: </span> <span class="kc">true</span>
|
|
<span class="nv">cond: </span> <span class="err">@</span><span class="nx">condition</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
|
|
<span class="nv">set: </span> <span class="s1">''</span>
|
|
<span class="k">if</span> <span class="o">not</span> <span class="nx">top</span>
|
|
<span class="nv">rvar: </span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">()</span>
|
|
<span class="nv">set: </span> <span class="s2">"$@tab$rvar = [];\n"</span>
|
|
<span class="err">@</span><span class="nv">body: </span> <span class="nx">PushNode</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="nx">rvar</span><span class="p">,</span> <span class="err">@</span><span class="nx">body</span><span class="p">)</span> <span class="k">if</span> <span class="err">@</span><span class="nx">body</span>
|
|
<span class="nv">post: </span> <span class="k">if</span> <span class="nx">returns</span> <span class="k">then</span> <span class="s2">"\n${@tab}return $rvar;"</span> <span class="k">else</span> <span class="s1">''</span>
|
|
<span class="nv">pre: </span> <span class="s2">"$set${@tab}while ($cond)"</span>
|
|
<span class="k">return</span> <span class="s2">"$pre null;$post"</span> <span class="k">if</span> <span class="o">not</span> <span class="err">@</span><span class="nx">body</span>
|
|
<span class="err">@</span><span class="nv">body: </span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="k">new</span> <span class="nx">IfNode</span><span class="p">(</span><span class="err">@</span><span class="nx">filter</span><span class="p">,</span> <span class="err">@</span><span class="nx">body</span><span class="p">)])</span> <span class="k">if</span> <span class="err">@</span><span class="nx">filter</span>
|
|
<span class="s2">"$pre {\n${ @body.compile(o) }\n$@tab}$post"</span>
|
|
|
|
<span class="nx">statement</span> <span class="nx">WhileNode</span></pre></div> </td> </tr> <tr id="section-93"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-93">#</a> </div> <h3>OpNode</h3> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-94"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-94">#</a> </div> <p>Simple Arithmetic and logical operations. Performs some conversion from
|
|
CoffeeScript operations into their JavaScript equivalents.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.OpNode: </span><span class="nx">class</span> <span class="nx">OpNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Op'</span></pre></div> </td> </tr> <tr id="section-95"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-95">#</a> </div> <p>The map of conversions from CoffeeScript to JavaScript symbols.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">CONVERSIONS: </span><span class="p">{</span>
|
|
<span class="s1">'=='</span><span class="o">:</span> <span class="s1">'==='</span>
|
|
<span class="s1">'!='</span><span class="o">:</span> <span class="s1">'!=='</span>
|
|
<span class="s1">'and'</span><span class="o">:</span> <span class="s1">'&&'</span>
|
|
<span class="s1">'or'</span><span class="o">:</span> <span class="s1">'||'</span>
|
|
<span class="s1">'is'</span><span class="o">:</span> <span class="s1">'==='</span>
|
|
<span class="s1">'isnt'</span><span class="o">:</span> <span class="s1">'!=='</span>
|
|
<span class="s1">'not'</span><span class="o">:</span> <span class="s1">'!'</span>
|
|
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-96"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-96">#</a> </div> <p>The list of operators for which we perform
|
|
<a href="http://docs.python.org/reference/expressions.html#notin">Python-style comparison chaining</a>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">CHAINABLE: </span> <span class="p">[</span><span class="s1">'<'</span><span class="p">,</span> <span class="s1">'>'</span><span class="p">,</span> <span class="s1">'>='</span><span class="p">,</span> <span class="s1">'<='</span><span class="p">,</span> <span class="s1">'==='</span><span class="p">,</span> <span class="s1">'!=='</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-97"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-97">#</a> </div> <p>Our assignment operators that have no JavaScript equivalent.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ASSIGNMENT: </span> <span class="p">[</span><span class="s1">'||='</span><span class="p">,</span> <span class="s1">'&&='</span><span class="p">,</span> <span class="s1">'?='</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-98"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-98">#</a> </div> <p>Operators must come before their operands with a space.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">PREFIX_OPERATORS: </span><span class="p">[</span><span class="s1">'typeof'</span><span class="p">,</span> <span class="s1">'delete'</span><span class="p">]</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">operator</span><span class="p">,</span> <span class="nx">first</span><span class="p">,</span> <span class="nx">second</span><span class="p">,</span> <span class="nx">flip</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">type</span> <span class="o">+=</span> <span class="s1">' '</span> <span class="o">+</span> <span class="nx">operator</span>
|
|
<span class="err">@</span><span class="nv">children: </span><span class="nx">compact</span> <span class="p">[</span><span class="err">@</span><span class="nv">first: </span><span class="nx">first</span><span class="p">,</span> <span class="err">@</span><span class="nv">second: </span><span class="nx">second</span><span class="p">]</span>
|
|
<span class="err">@</span><span class="nv">operator: </span><span class="err">@</span><span class="nx">CONVERSIONS</span><span class="p">[</span><span class="nx">operator</span><span class="p">]</span> <span class="o">or</span> <span class="nx">operator</span>
|
|
<span class="err">@</span><span class="nv">flip: </span><span class="o">!!</span><span class="nx">flip</span>
|
|
|
|
<span class="nv">is_unary: </span><span class="o">-></span>
|
|
<span class="o">not</span> <span class="err">@</span><span class="nx">second</span>
|
|
|
|
<span class="nv">is_chainable: </span><span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">CHAINABLE</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="err">@</span><span class="nx">operator</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">0</span>
|
|
|
|
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">o.operation: </span><span class="kc">true</span>
|
|
<span class="k">return</span> <span class="err">@</span><span class="nx">compile_chain</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="err">@</span><span class="nx">is_chainable</span><span class="p">()</span> <span class="o">and</span> <span class="err">@</span><span class="nx">first</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span> <span class="k">instanceof</span> <span class="nx">OpNode</span> <span class="o">and</span> <span class="err">@</span><span class="nx">first</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">().</span><span class="nx">is_chainable</span><span class="p">()</span>
|
|
<span class="k">return</span> <span class="err">@</span><span class="nx">compile_assignment</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="err">@</span><span class="nx">ASSIGNMENT</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="err">@</span><span class="nx">operator</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">0</span>
|
|
<span class="k">return</span> <span class="err">@</span><span class="nx">compile_unary</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="err">@</span><span class="nx">is_unary</span><span class="p">()</span>
|
|
<span class="k">return</span> <span class="err">@</span><span class="nx">compile_existence</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="err">@</span><span class="nx">operator</span> <span class="o">is</span> <span class="s1">'?'</span>
|
|
<span class="p">[</span><span class="err">@</span><span class="nx">first</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">),</span> <span class="err">@</span><span class="nx">operator</span><span class="p">,</span> <span class="err">@</span><span class="nx">second</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)].</span><span class="nx">join</span> <span class="s1">' '</span></pre></div> </td> </tr> <tr id="section-99"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-99">#</a> </div> <p>Mimic Python's chained comparisons when multiple comparison operators are
|
|
used sequentially. For example: <code>50 < 65 > 10</code></p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_chain: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">shared: </span><span class="err">@</span><span class="nx">first</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">().</span><span class="nx">second</span>
|
|
<span class="p">[</span><span class="err">@</span><span class="nx">first</span><span class="p">.</span><span class="nx">second</span><span class="p">,</span> <span class="nx">shared</span><span class="p">]</span><span class="o">:</span> <span class="nx">shared</span><span class="p">.</span><span class="nx">compile_reference</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="nx">shared</span> <span class="k">instanceof</span> <span class="nx">CallNode</span>
|
|
<span class="p">[</span><span class="nx">first</span><span class="p">,</span> <span class="nx">second</span><span class="p">,</span> <span class="nx">shared</span><span class="p">]</span><span class="o">:</span> <span class="p">[</span><span class="err">@</span><span class="nx">first</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">),</span> <span class="err">@</span><span class="nx">second</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">),</span> <span class="nx">shared</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)]</span>
|
|
<span class="s2">"($first) && ($shared $@operator $second)"</span></pre></div> </td> </tr> <tr id="section-100"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-100">#</a> </div> <p>When compiling a conditional assignment, take care to ensure that the
|
|
operands are only evaluated once, even though we have to reference them
|
|
more than once.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_assignment: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="p">[</span><span class="nx">first</span><span class="p">,</span> <span class="nx">second</span><span class="p">]</span><span class="o">:</span> <span class="p">[</span><span class="err">@</span><span class="nx">first</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">),</span> <span class="err">@</span><span class="nx">second</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)]</span>
|
|
<span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="nx">first</span><span class="p">)</span> <span class="k">if</span> <span class="nx">first</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">IDENTIFIER</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="s2">"$first = ${ ExistenceNode.compile_test(o, @first) } ? $first : $second"</span> <span class="k">if</span> <span class="err">@</span><span class="nx">operator</span> <span class="o">is</span> <span class="s1">'?='</span>
|
|
<span class="s2">"$first = $first ${ @operator.substr(0, 2) } $second"</span>
|
|
|
|
<span class="nv">compile_existence: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="p">[</span><span class="nx">first</span><span class="p">,</span> <span class="nx">second</span><span class="p">]</span><span class="o">:</span> <span class="p">[</span><span class="err">@</span><span class="nx">first</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">),</span> <span class="err">@</span><span class="nx">second</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)]</span>
|
|
<span class="nv">test: </span><span class="nx">ExistenceNode</span><span class="p">.</span><span class="nx">compile_test</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="err">@</span><span class="nx">first</span><span class="p">)</span>
|
|
<span class="s2">"$test ? $first : $second"</span>
|
|
|
|
<span class="nv">compile_unary: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">space: </span><span class="k">if</span> <span class="err">@</span><span class="nx">PREFIX_OPERATORS</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="err">@</span><span class="nx">operator</span><span class="p">)</span> <span class="o">>=</span> <span class="mi">0</span> <span class="k">then</span> <span class="s1">' '</span> <span class="k">else</span> <span class="s1">''</span>
|
|
<span class="nv">parts: </span><span class="p">[</span><span class="err">@</span><span class="nx">operator</span><span class="p">,</span> <span class="nx">space</span><span class="p">,</span> <span class="err">@</span><span class="nx">first</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)]</span>
|
|
<span class="nv">parts: </span><span class="nx">parts</span><span class="p">.</span><span class="nx">reverse</span><span class="p">()</span> <span class="k">if</span> <span class="err">@</span><span class="nx">flip</span>
|
|
<span class="nx">parts</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">''</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-101"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-101">#</a> </div> <p>A try/catch/finally block.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.TryNode: </span><span class="nx">class</span> <span class="nx">TryNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Try'</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">attempt</span><span class="p">,</span> <span class="nx">error</span><span class="p">,</span> <span class="nx">recovery</span><span class="p">,</span> <span class="nx">ensure</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">children: </span><span class="nx">compact</span> <span class="p">[</span><span class="err">@</span><span class="nv">attempt: </span><span class="nx">attempt</span><span class="p">,</span> <span class="err">@</span><span class="nv">recovery: </span><span class="nx">recovery</span><span class="p">,</span> <span class="err">@</span><span class="nv">ensure: </span><span class="nx">ensure</span><span class="p">]</span>
|
|
<span class="err">@</span><span class="nv">error: </span><span class="nx">error</span>
|
|
<span class="k">this</span>
|
|
|
|
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">o.indent: </span> <span class="err">@</span><span class="nx">idt</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
|
<span class="nv">o.top: </span> <span class="kc">true</span>
|
|
<span class="nv">attempt_part: </span><span class="err">@</span><span class="nx">attempt</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
|
|
<span class="nv">error_part: </span> <span class="k">if</span> <span class="err">@</span><span class="nx">error</span> <span class="k">then</span> <span class="s2">" (${ @error.compile(o) }) "</span> <span class="k">else</span> <span class="s1">' '</span>
|
|
<span class="nv">catch_part: </span> <span class="s2">"${ (@recovery or '') and ' catch' }$error_part{\n${ @recovery.compile(o) }\n$@tab}"</span>
|
|
<span class="nv">finally_part: </span><span class="p">(</span><span class="err">@</span><span class="nx">ensure</span> <span class="o">or</span> <span class="s1">''</span><span class="p">)</span> <span class="o">and</span> <span class="s1">' finally {\n'</span> <span class="o">+</span> <span class="err">@</span><span class="nx">ensure</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="p">{</span><span class="nv">returns: </span><span class="kc">null</span><span class="p">}))</span> <span class="o">+</span> <span class="s2">"\n$@tab}"</span>
|
|
<span class="s2">"${@tab}try {\n$attempt_part\n$@tab}$catch_part$finally_part"</span>
|
|
|
|
<span class="nx">statement</span> <span class="nx">TryNode</span></pre></div> </td> </tr> <tr id="section-102"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-102">#</a> </div> <p>Throw an exception.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ThrowNode: </span><span class="nx">class</span> <span class="nx">ThrowNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Throw'</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">expression</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">children: </span><span class="p">[</span><span class="err">@</span><span class="nv">expression: </span><span class="nx">expression</span><span class="p">]</span>
|
|
|
|
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="s2">"${@tab}throw ${@expression.compile(o)};"</span>
|
|
|
|
<span class="nx">statement</span> <span class="nx">ThrowNode</span><span class="p">,</span> <span class="kc">true</span></pre></div> </td> </tr> <tr id="section-103"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-103">#</a> </div> <p>Check an expression for existence (meaning not null or undefined).</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ExistenceNode: </span><span class="nx">class</span> <span class="nx">ExistenceNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Existence'</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">expression</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">children: </span><span class="p">[</span><span class="err">@</span><span class="nv">expression: </span><span class="nx">expression</span><span class="p">]</span>
|
|
|
|
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nx">ExistenceNode</span><span class="p">.</span><span class="nx">compile_test</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="err">@</span><span class="nx">expression</span><span class="p">)</span>
|
|
|
|
<span class="nv">ExistenceNode.compile_test: </span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">variable</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="p">[</span><span class="nx">first</span><span class="p">,</span> <span class="nx">second</span><span class="p">]</span><span class="o">:</span> <span class="p">[</span><span class="nx">variable</span><span class="p">,</span> <span class="nx">variable</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="nx">variable</span> <span class="k">instanceof</span> <span class="nx">CallNode</span> <span class="o">or</span> <span class="p">(</span><span class="nx">variable</span> <span class="k">instanceof</span> <span class="nx">ValueNode</span> <span class="o">and</span> <span class="nx">variable</span><span class="p">.</span><span class="nx">has_properties</span><span class="p">())</span>
|
|
<span class="p">[</span><span class="nx">first</span><span class="p">,</span> <span class="nx">second</span><span class="p">]</span><span class="o">:</span> <span class="nx">variable</span><span class="p">.</span><span class="nx">compile_reference</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
|
|
<span class="p">[</span><span class="nx">first</span><span class="p">,</span> <span class="nx">second</span><span class="p">]</span><span class="o">:</span> <span class="p">[</span><span class="nx">first</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">),</span> <span class="nx">second</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)]</span>
|
|
<span class="s2">"(typeof $first !== \"undefined\" && $second !== null)"</span></pre></div> </td> </tr> <tr id="section-104"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-104">#</a> </div> <p>An extra set of parentheses, specified explicitly in the source.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ParentheticalNode: </span><span class="nx">class</span> <span class="nx">ParentheticalNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'Paren'</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">expression</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">children: </span><span class="p">[</span><span class="err">@</span><span class="nv">expression: </span><span class="nx">expression</span><span class="p">]</span>
|
|
|
|
<span class="nv">is_statement: </span><span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">expression</span><span class="p">.</span><span class="nx">is_statement</span><span class="p">()</span>
|
|
|
|
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">code: </span><span class="err">@</span><span class="nx">expression</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="nx">code</span> <span class="k">if</span> <span class="err">@</span><span class="nx">is_statement</span><span class="p">()</span>
|
|
<span class="nv">l: </span> <span class="nx">code</span><span class="p">.</span><span class="nx">length</span>
|
|
<span class="nv">code: </span><span class="nx">code</span><span class="p">.</span><span class="nx">substr</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="nx">l</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="k">if</span> <span class="nx">code</span><span class="p">.</span><span class="nx">substr</span><span class="p">(</span><span class="nx">l</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> <span class="o">is</span> <span class="s1">';'</span>
|
|
<span class="s2">"($code)"</span></pre></div> </td> </tr> <tr id="section-105"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-105">#</a> </div> <p>The replacement for the for loop is an array comprehension (that compiles)
|
|
into a for loop. Also acts as an expression, able to return the result
|
|
of the comprehenion. Unlike Python array comprehensions, it's able to pass
|
|
the current index of the loop as a second parameter.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.ForNode: </span><span class="nx">class</span> <span class="nx">ForNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'For'</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">body</span><span class="p">,</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">body: </span> <span class="nx">body</span>
|
|
<span class="err">@</span><span class="nv">name: </span> <span class="nx">name</span>
|
|
<span class="err">@</span><span class="nv">index: </span> <span class="nx">index</span> <span class="o">or</span> <span class="kc">null</span>
|
|
<span class="err">@</span><span class="nv">source: </span> <span class="nx">source</span><span class="p">.</span><span class="nx">source</span>
|
|
<span class="err">@</span><span class="nv">filter: </span> <span class="nx">source</span><span class="p">.</span><span class="nx">filter</span>
|
|
<span class="err">@</span><span class="nv">step: </span> <span class="nx">source</span><span class="p">.</span><span class="nx">step</span>
|
|
<span class="err">@</span><span class="nv">object: </span> <span class="o">!!</span><span class="nx">source</span><span class="p">.</span><span class="nx">object</span>
|
|
<span class="p">[</span><span class="err">@</span><span class="nx">name</span><span class="p">,</span> <span class="err">@</span><span class="nx">index</span><span class="p">]</span><span class="o">:</span> <span class="p">[</span><span class="err">@</span><span class="nx">index</span><span class="p">,</span> <span class="err">@</span><span class="nx">name</span><span class="p">]</span> <span class="k">if</span> <span class="err">@</span><span class="nx">object</span>
|
|
<span class="err">@</span><span class="nv">children: </span><span class="nx">compact</span> <span class="p">[</span><span class="err">@</span><span class="nx">body</span><span class="p">,</span> <span class="err">@</span><span class="nx">source</span><span class="p">,</span> <span class="err">@</span><span class="nx">filter</span><span class="p">]</span>
|
|
|
|
<span class="nv">top_sensitive: </span><span class="o">-></span>
|
|
<span class="kc">true</span>
|
|
|
|
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">top_level: </span> <span class="nx">del</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="s1">'top'</span><span class="p">)</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">o</span><span class="p">.</span><span class="nx">returns</span>
|
|
<span class="nv">range: </span> <span class="err">@</span><span class="nx">source</span> <span class="k">instanceof</span> <span class="nx">ValueNode</span> <span class="o">and</span> <span class="err">@</span><span class="nx">source</span><span class="p">.</span><span class="nx">base</span> <span class="k">instanceof</span> <span class="nx">RangeNode</span> <span class="o">and</span> <span class="o">not</span> <span class="err">@</span><span class="nx">source</span><span class="p">.</span><span class="nx">properties</span><span class="p">.</span><span class="nx">length</span>
|
|
<span class="nv">source: </span> <span class="k">if</span> <span class="nx">range</span> <span class="k">then</span> <span class="err">@</span><span class="nx">source</span><span class="p">.</span><span class="nx">base</span> <span class="k">else</span> <span class="err">@</span><span class="nx">source</span>
|
|
<span class="nv">scope: </span> <span class="nx">o</span><span class="p">.</span><span class="nx">scope</span>
|
|
<span class="nv">name: </span> <span class="err">@</span><span class="nx">name</span> <span class="o">and</span> <span class="err">@</span><span class="nx">name</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
|
|
<span class="nv">index: </span> <span class="err">@</span><span class="nx">index</span> <span class="o">and</span> <span class="err">@</span><span class="nx">index</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">o</span>
|
|
<span class="nv">name_found: </span> <span class="nx">name</span> <span class="o">and</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">find</span> <span class="nx">name</span>
|
|
<span class="nv">index_found: </span> <span class="nx">index</span> <span class="o">and</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">find</span> <span class="nx">index</span>
|
|
<span class="nv">body_dent: </span> <span class="err">@</span><span class="nx">idt</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
|
<span class="nv">rvar: </span> <span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">()</span> <span class="nx">unless</span> <span class="nx">top_level</span>
|
|
<span class="nv">svar: </span> <span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">()</span>
|
|
<span class="nv">ivar: </span> <span class="k">if</span> <span class="nx">range</span> <span class="k">then</span> <span class="nx">name</span> <span class="k">else</span> <span class="nx">index</span> <span class="o">or</span> <span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">()</span>
|
|
<span class="nv">var_part: </span> <span class="s1">''</span>
|
|
<span class="nv">body: </span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="err">@</span><span class="nx">body</span><span class="p">])</span>
|
|
<span class="k">if</span> <span class="nx">range</span>
|
|
<span class="nv">index_var: </span> <span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">()</span>
|
|
<span class="nv">source_part: </span> <span class="nx">source</span><span class="p">.</span><span class="nx">compile_variables</span> <span class="nx">o</span>
|
|
<span class="nv">for_part: </span> <span class="nx">source</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">merge</span> <span class="nx">o</span><span class="p">,</span> <span class="p">{</span><span class="nv">index: </span><span class="nx">ivar</span><span class="p">,</span> <span class="nv">step: </span><span class="err">@</span><span class="nx">step</span><span class="p">}</span>
|
|
<span class="nv">for_part: </span> <span class="s2">"$index_var = 0, $for_part, $index_var++"</span>
|
|
<span class="k">else</span>
|
|
<span class="nv">index_var: </span> <span class="kc">null</span>
|
|
<span class="nv">source_part: </span> <span class="s2">"$svar = ${ @source.compile(o) };\n$@tab"</span>
|
|
<span class="nv">var_part: </span> <span class="s2">"$body_dent$name = $svar[$ivar];\n"</span> <span class="k">if</span> <span class="nx">name</span>
|
|
<span class="k">if</span> <span class="o">not</span> <span class="err">@</span><span class="nx">object</span>
|
|
<span class="nv">lvar: </span> <span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">()</span>
|
|
<span class="nv">step_part: </span> <span class="k">if</span> <span class="err">@</span><span class="nx">step</span> <span class="k">then</span> <span class="s2">"$ivar += ${ @step.compile(o) }"</span> <span class="k">else</span> <span class="s2">"$ivar++"</span>
|
|
<span class="nv">for_part: </span> <span class="s2">"$ivar = 0, $lvar = ${svar}.length; $ivar < $lvar; $step_part"</span>
|
|
<span class="nv">set_result: </span> <span class="k">if</span> <span class="nx">rvar</span> <span class="k">then</span> <span class="err">@</span><span class="nx">idt</span><span class="p">()</span> <span class="o">+</span> <span class="nx">rvar</span> <span class="o">+</span> <span class="s1">' = []; '</span> <span class="k">else</span> <span class="err">@</span><span class="nx">idt</span><span class="p">()</span>
|
|
<span class="nv">return_result: </span> <span class="nx">rvar</span> <span class="o">or</span> <span class="s1">''</span>
|
|
<span class="nv">body: </span> <span class="nx">ClosureNode</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="nx">body</span><span class="p">,</span> <span class="kc">true</span><span class="p">)</span> <span class="k">if</span> <span class="nx">top_level</span> <span class="o">and</span> <span class="err">@</span><span class="nx">contains</span> <span class="p">(</span><span class="nx">n</span><span class="p">)</span> <span class="o">-></span> <span class="nx">n</span> <span class="k">instanceof</span> <span class="nx">CodeNode</span>
|
|
<span class="nv">body: </span> <span class="nx">PushNode</span><span class="p">.</span><span class="nx">wrap</span><span class="p">(</span><span class="nx">rvar</span><span class="p">,</span> <span class="nx">body</span><span class="p">)</span> <span class="nx">unless</span> <span class="nx">top_level</span>
|
|
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">returns</span>
|
|
<span class="nv">return_result: </span><span class="s1">'return '</span> <span class="o">+</span> <span class="nx">return_result</span>
|
|
<span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">'returns'</span>
|
|
<span class="nv">body: </span> <span class="k">new</span> <span class="nx">IfNode</span><span class="p">(</span><span class="err">@</span><span class="nx">filter</span><span class="p">,</span> <span class="nx">body</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="p">{</span><span class="nv">statement: </span><span class="kc">true</span><span class="p">})</span> <span class="k">if</span> <span class="err">@</span><span class="nx">filter</span>
|
|
<span class="k">else</span> <span class="k">if</span> <span class="err">@</span><span class="nx">filter</span>
|
|
<span class="nv">body: </span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="k">new</span> <span class="nx">IfNode</span><span class="p">(</span><span class="err">@</span><span class="nx">filter</span><span class="p">,</span> <span class="nx">body</span><span class="p">)])</span>
|
|
<span class="k">if</span> <span class="err">@</span><span class="nx">object</span>
|
|
<span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">assign</span><span class="p">(</span><span class="s1">'__hasProp'</span><span class="p">,</span> <span class="s1">'Object.prototype.hasOwnProperty'</span><span class="p">,</span> <span class="kc">true</span><span class="p">)</span>
|
|
<span class="nv">for_part: </span><span class="s2">"$ivar in $svar) { if (__hasProp.call($svar, $ivar)"</span>
|
|
<span class="nv">return_result: </span> <span class="s2">"\n$@tab$return_result;"</span> <span class="nx">unless</span> <span class="nx">top_level</span>
|
|
<span class="nv">body: </span> <span class="nx">body</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="p">{</span><span class="nv">indent: </span><span class="nx">body_dent</span><span class="p">,</span> <span class="nv">top: </span><span class="kc">true</span><span class="p">}))</span>
|
|
<span class="nv">vars: </span> <span class="k">if</span> <span class="nx">range</span> <span class="k">then</span> <span class="nx">name</span> <span class="k">else</span> <span class="s2">"$name, $ivar"</span>
|
|
<span class="nv">close: </span> <span class="k">if</span> <span class="err">@</span><span class="nx">object</span> <span class="k">then</span> <span class="s1">'}}\n'</span> <span class="k">else</span> <span class="s1">'}\n'</span>
|
|
<span class="s2">"$set_result${source_part}for ($for_part) {\n$var_part$body\n$@tab$close$@tab$return_result"</span>
|
|
|
|
<span class="nx">statement</span> <span class="nx">ForNode</span></pre></div> </td> </tr> <tr id="section-106"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-106">#</a> </div> <p>If/else statements. Switch/whens get compiled into these. Acts as an
|
|
expression by pushing down requested returns to the expression bodies.
|
|
Single-expression IfNodes are compiled into ternary operators if possible,
|
|
because ternaries are first-class returnable assignable expressions.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.IfNode: </span><span class="nx">class</span> <span class="nx">IfNode</span> <span class="k">extends</span> <span class="nx">BaseNode</span>
|
|
<span class="nv">type: </span><span class="s1">'If'</span>
|
|
|
|
<span class="nv">constructor: </span><span class="p">(</span><span class="nx">condition</span><span class="p">,</span> <span class="nx">body</span><span class="p">,</span> <span class="nx">else_body</span><span class="p">,</span> <span class="nx">tags</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">condition: </span><span class="nx">condition</span>
|
|
<span class="err">@</span><span class="nv">body: </span> <span class="nx">body</span> <span class="o">and</span> <span class="nx">body</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span>
|
|
<span class="err">@</span><span class="nv">else_body: </span><span class="nx">else_body</span> <span class="o">and</span> <span class="nx">else_body</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span>
|
|
<span class="err">@</span><span class="nv">children: </span> <span class="nx">compact</span> <span class="p">[</span><span class="err">@</span><span class="nx">condition</span><span class="p">,</span> <span class="err">@</span><span class="nx">body</span><span class="p">,</span> <span class="err">@</span><span class="nx">else_body</span><span class="p">]</span>
|
|
<span class="err">@</span><span class="nv">tags: </span> <span class="nx">tags</span> <span class="o">or</span> <span class="p">{}</span>
|
|
<span class="err">@</span><span class="nv">multiple: </span> <span class="kc">true</span> <span class="k">if</span> <span class="err">@</span><span class="nx">condition</span> <span class="k">instanceof</span> <span class="nb">Array</span>
|
|
<span class="err">@</span><span class="nv">condition: </span><span class="k">new</span> <span class="nx">OpNode</span><span class="p">(</span><span class="s1">'!'</span><span class="p">,</span> <span class="k">new</span> <span class="nx">ParentheticalNode</span><span class="p">(</span><span class="err">@</span><span class="nx">condition</span><span class="p">))</span> <span class="k">if</span> <span class="err">@</span><span class="nx">tags</span><span class="p">.</span><span class="nx">invert</span>
|
|
|
|
<span class="nv">push: </span><span class="p">(</span><span class="nx">else_body</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">eb: </span><span class="nx">else_body</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="err">@</span><span class="nx">else_body</span> <span class="k">then</span> <span class="err">@</span><span class="nx">else_body</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">eb</span><span class="p">)</span> <span class="k">else</span> <span class="err">@</span><span class="nv">else_body: </span><span class="nx">eb</span>
|
|
<span class="k">this</span>
|
|
|
|
<span class="nv">force_statement: </span><span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">tags.statement: </span><span class="kc">true</span>
|
|
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-107"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-107">#</a> </div> <p>Tag a chain of IfNodes with their switch condition for equality.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">rewrite_condition: </span><span class="p">(</span><span class="nx">expression</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nv">switcher: </span><span class="nx">expression</span>
|
|
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-108"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-108">#</a> </div> <p>Rewrite a chain of IfNodes with their switch condition for equality.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">rewrite_switch: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">assigner: </span><span class="err">@</span><span class="nx">switcher</span>
|
|
<span class="k">if</span> <span class="o">not</span> <span class="p">(</span><span class="err">@</span><span class="nx">switcher</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span> <span class="k">instanceof</span> <span class="nx">LiteralNode</span><span class="p">)</span>
|
|
<span class="nv">variable: </span><span class="nx">literal</span><span class="p">(</span><span class="nx">o</span><span class="p">.</span><span class="nx">scope</span><span class="p">.</span><span class="nx">free_variable</span><span class="p">())</span>
|
|
<span class="nv">assigner: </span><span class="k">new</span> <span class="nx">AssignNode</span><span class="p">(</span><span class="nx">variable</span><span class="p">,</span> <span class="err">@</span><span class="nx">switcher</span><span class="p">)</span>
|
|
<span class="err">@</span><span class="nv">switcher: </span><span class="nx">variable</span>
|
|
<span class="err">@</span><span class="nv">condition: </span><span class="k">if</span> <span class="err">@</span><span class="nx">multiple</span>
|
|
<span class="k">for</span> <span class="nx">cond</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="err">@</span><span class="nx">condition</span>
|
|
<span class="k">new</span> <span class="nx">OpNode</span><span class="p">(</span><span class="s1">'is'</span><span class="p">,</span> <span class="p">(</span><span class="k">if</span> <span class="nx">i</span> <span class="o">is</span> <span class="mi">0</span> <span class="k">then</span> <span class="nx">assigner</span> <span class="k">else</span> <span class="err">@</span><span class="nx">switcher</span><span class="p">),</span> <span class="nx">cond</span><span class="p">)</span>
|
|
<span class="k">else</span>
|
|
<span class="k">new</span> <span class="nx">OpNode</span><span class="p">(</span><span class="s1">'is'</span><span class="p">,</span> <span class="nx">assigner</span><span class="p">,</span> <span class="err">@</span><span class="nx">condition</span><span class="p">)</span>
|
|
<span class="err">@</span><span class="nx">else_body</span><span class="p">.</span><span class="nx">rewrite_condition</span><span class="p">(</span><span class="err">@</span><span class="nx">switcher</span><span class="p">)</span> <span class="k">if</span> <span class="err">@</span><span class="nx">is_chain</span><span class="p">()</span>
|
|
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-109"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-109">#</a> </div> <p>Rewrite a chain of IfNodes to add a default case as the final else.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">add_else: </span><span class="p">(</span><span class="nx">exprs</span><span class="p">,</span> <span class="nx">statement</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="k">if</span> <span class="err">@</span><span class="nx">is_chain</span><span class="p">()</span>
|
|
<span class="err">@</span><span class="nx">else_body</span><span class="p">.</span><span class="nx">add_else</span> <span class="nx">exprs</span><span class="p">,</span> <span class="nx">statement</span>
|
|
<span class="k">else</span>
|
|
<span class="nv">exprs: </span><span class="nx">exprs</span><span class="p">.</span><span class="nx">unwrap</span><span class="p">()</span> <span class="nx">unless</span> <span class="nx">statement</span>
|
|
<span class="err">@</span><span class="nx">children</span><span class="p">.</span><span class="nx">push</span> <span class="err">@</span><span class="nv">else_body: </span><span class="nx">exprs</span>
|
|
<span class="k">this</span></pre></div> </td> </tr> <tr id="section-110"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-110">#</a> </div> <p>If the else_body is an IfNode itself, then we've got an if-else chain.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">is_chain: </span><span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">chain</span> <span class="o">||=</span> <span class="err">@</span><span class="nx">else_body</span> <span class="o">and</span> <span class="err">@</span><span class="nx">else_body</span> <span class="k">instanceof</span> <span class="nx">IfNode</span></pre></div> </td> </tr> <tr id="section-111"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-111">#</a> </div> <p>The IfNode only compiles into a statement if either of the bodies needs
|
|
to be a statement.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">is_statement: </span><span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">statement</span> <span class="o">||=</span> <span class="o">!!</span><span class="p">(</span><span class="err">@</span><span class="nx">comment</span> <span class="o">or</span> <span class="err">@</span><span class="nx">tags</span><span class="p">.</span><span class="nx">statement</span> <span class="o">or</span> <span class="err">@</span><span class="nx">body</span><span class="p">.</span><span class="nx">is_statement</span><span class="p">()</span> <span class="o">or</span> <span class="p">(</span><span class="err">@</span><span class="nx">else_body</span> <span class="o">and</span> <span class="err">@</span><span class="nx">else_body</span><span class="p">.</span><span class="nx">is_statement</span><span class="p">()))</span>
|
|
|
|
<span class="nv">compile_condition: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="p">(</span><span class="nx">cond</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">for</span> <span class="nx">cond</span> <span class="k">in</span> <span class="nx">flatten</span><span class="p">([</span><span class="err">@</span><span class="nx">condition</span><span class="p">])).</span><span class="nx">join</span><span class="p">(</span><span class="s1">' || '</span><span class="p">)</span>
|
|
|
|
<span class="nv">compile_node: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="k">if</span> <span class="err">@</span><span class="nx">is_statement</span><span class="p">()</span> <span class="k">then</span> <span class="err">@</span><span class="nx">compile_statement</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">else</span> <span class="err">@</span><span class="nx">compile_ternary</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-112"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-112">#</a> </div> <p>Compile the IfNode as a regular if-else statement. Flattened chains
|
|
force sub-else bodies into statement form.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_statement: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="err">@</span><span class="nx">rewrite_switch</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">if</span> <span class="err">@</span><span class="nx">switcher</span>
|
|
<span class="nv">child: </span> <span class="nx">del</span> <span class="nx">o</span><span class="p">,</span> <span class="s1">'chain_child'</span>
|
|
<span class="nv">cond_o: </span> <span class="nx">merge</span> <span class="nx">o</span>
|
|
<span class="nx">del</span> <span class="nx">cond_o</span><span class="p">,</span> <span class="s1">'returns'</span>
|
|
<span class="nv">o.indent: </span> <span class="err">@</span><span class="nx">idt</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
|
<span class="nv">o.top: </span> <span class="kc">true</span>
|
|
<span class="nv">if_dent: </span> <span class="k">if</span> <span class="nx">child</span> <span class="k">then</span> <span class="s1">''</span> <span class="k">else</span> <span class="err">@</span><span class="nx">idt</span><span class="p">()</span>
|
|
<span class="nv">com_dent: </span> <span class="k">if</span> <span class="nx">child</span> <span class="k">then</span> <span class="err">@</span><span class="nx">idt</span><span class="p">()</span> <span class="k">else</span> <span class="s1">''</span>
|
|
<span class="nv">prefix: </span> <span class="k">if</span> <span class="err">@</span><span class="nx">comment</span> <span class="k">then</span> <span class="s2">"${ @comment.compile(cond_o) }\n$com_dent"</span> <span class="k">else</span> <span class="s1">''</span>
|
|
<span class="nv">body: </span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="err">@</span><span class="nx">body</span><span class="p">]).</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
|
|
<span class="nv">if_part: </span> <span class="s2">"$prefix${if_dent}if (${ @compile_condition(cond_o) }) {\n$body\n$@tab}"</span>
|
|
<span class="k">return</span> <span class="nx">if_part</span> <span class="nx">unless</span> <span class="err">@</span><span class="nx">else_body</span>
|
|
<span class="nv">else_part: </span><span class="k">if</span> <span class="err">@</span><span class="nx">is_chain</span><span class="p">()</span>
|
|
<span class="s1">' else '</span> <span class="o">+</span> <span class="err">@</span><span class="nx">else_body</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">merge</span><span class="p">(</span><span class="nx">o</span><span class="p">,</span> <span class="p">{</span><span class="nv">indent: </span><span class="err">@</span><span class="nx">idt</span><span class="p">(),</span> <span class="nv">chain_child: </span><span class="kc">true</span><span class="p">}))</span>
|
|
<span class="k">else</span>
|
|
<span class="s2">" else {\n${ Expressions.wrap([@else_body]).compile(o) }\n$@tab}"</span>
|
|
<span class="s2">"$if_part$else_part"</span></pre></div> </td> </tr> <tr id="section-113"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-113">#</a> </div> <p>Compile the IfNode into a ternary operator.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compile_ternary: </span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">if_part: </span> <span class="err">@</span><span class="nx">condition</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="o">+</span> <span class="s1">' ? '</span> <span class="o">+</span> <span class="err">@</span><span class="nx">body</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span>
|
|
<span class="nv">else_part: </span> <span class="k">if</span> <span class="err">@</span><span class="nx">else_body</span> <span class="k">then</span> <span class="err">@</span><span class="nx">else_body</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">o</span><span class="p">)</span> <span class="k">else</span> <span class="s1">'null'</span>
|
|
<span class="s2">"$if_part : $else_part"</span></pre></div> </td> </tr> <tr id="section-114"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-114">#</a> </div> <h2>Constants</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-115"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-115">#</a> </div> <p>Tabs are two spaces for pretty printing.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">TAB: </span><span class="s1">' '</span>
|
|
<span class="nv">TRAILING_WHITESPACE: </span><span class="sr">/\s+$/gm</span></pre></div> </td> </tr> <tr id="section-116"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-116">#</a> </div> <p>Keep the identifier regex in sync with the Lexer.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IDENTIFIER: </span> <span class="sr">/^[a-zA-Z$_](\w|\$)*$/</span></pre></div> </td> </tr> <tr id="section-117"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-117">#</a> </div> <h2>Utility Functions</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-118"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-118">#</a> </div> <p>Merge objects.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">merge: </span><span class="p">(</span><span class="nx">options</span><span class="p">,</span> <span class="nx">overrides</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">fresh: </span><span class="p">{}</span>
|
|
<span class="p">(</span><span class="nx">fresh</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span><span class="o">:</span> <span class="nx">val</span><span class="p">)</span> <span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="k">of</span> <span class="nx">options</span>
|
|
<span class="p">(</span><span class="nx">fresh</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span><span class="o">:</span> <span class="nx">val</span><span class="p">)</span> <span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="k">of</span> <span class="nx">overrides</span> <span class="k">if</span> <span class="nx">overrides</span>
|
|
<span class="nx">fresh</span></pre></div> </td> </tr> <tr id="section-119"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-119">#</a> </div> <p>Trim out all falsy values from an array.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">compact: </span><span class="p">(</span><span class="nx">array</span><span class="p">)</span> <span class="o">-></span> <span class="nx">item</span> <span class="k">for</span> <span class="nx">item</span> <span class="k">in</span> <span class="nx">array</span> <span class="k">when</span> <span class="nx">item</span></pre></div> </td> </tr> <tr id="section-120"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-120">#</a> </div> <p>Return a completely flattened version of an array.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">flatten: </span><span class="p">(</span><span class="nx">array</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">memo: </span><span class="p">[]</span>
|
|
<span class="k">for</span> <span class="nx">item</span> <span class="k">in</span> <span class="nx">array</span>
|
|
<span class="k">if</span> <span class="nx">item</span> <span class="k">instanceof</span> <span class="nb">Array</span> <span class="k">then</span> <span class="nv">memo: </span><span class="nx">memo</span><span class="p">.</span><span class="nx">concat</span><span class="p">(</span><span class="nx">item</span><span class="p">)</span> <span class="k">else</span> <span class="nx">memo</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">item</span><span class="p">)</span>
|
|
<span class="nx">memo</span></pre></div> </td> </tr> <tr id="section-121"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-121">#</a> </div> <p>Delete a key from an object, returning the value.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">del: </span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">key</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="nv">val: </span><span class="nx">obj</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span>
|
|
<span class="k">delete</span> <span class="nx">obj</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span>
|
|
<span class="nx">val</span></pre></div> </td> </tr> <tr id="section-122"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-122">#</a> </div> <p>Quickie helper for a generated LiteralNode.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">literal: </span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">-></span>
|
|
<span class="k">new</span> <span class="nx">LiteralNode</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span>
|
|
|
|
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html> |