mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
1225 lines
82 KiB
HTML
1225 lines
82 KiB
HTML
<!DOCTYPE html>
|
|
|
|
<html>
|
|
<head>
|
|
<title>rewriter.coffee</title>
|
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
|
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
|
|
<link rel="stylesheet" media="all" href="docco.css" />
|
|
</head>
|
|
<body>
|
|
<div id="container">
|
|
<div id="background"></div>
|
|
|
|
<ul id="jump_to">
|
|
<li>
|
|
<a class="large" href="javascript:void(0);">Jump To …</a>
|
|
<a class="small" href="javascript:void(0);">+</a>
|
|
<div id="jump_wrapper">
|
|
<div id="jump_page">
|
|
|
|
|
|
<a class="source" href="browser.html">
|
|
browser.coffee
|
|
</a>
|
|
|
|
|
|
<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="helpers.html">
|
|
helpers.coffee
|
|
</a>
|
|
|
|
|
|
<a class="source" href="index.html">
|
|
index.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.litcoffee
|
|
</a>
|
|
|
|
|
|
<a class="source" href="sourcemap.html">
|
|
sourcemap.coffee
|
|
</a>
|
|
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
|
|
<ul class="sections">
|
|
<li id="title">
|
|
<div class="annotation">
|
|
<h1>rewriter.coffee</h1>
|
|
</div>
|
|
</li>
|
|
|
|
|
|
<li id="section-1">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-1">¶</a>
|
|
</div>
|
|
<p>The CoffeeScript language has a good deal of optional syntax, implicit syntax,
|
|
and shorthand syntax. This can greatly complicate a grammar and bloat
|
|
the resulting parse table. Instead of making the parser handle it all, we take
|
|
a series of passes over the token stream, using this <strong>Rewriter</strong> to convert
|
|
shorthand into the unambiguous long form, add implicit indentation and
|
|
parentheses, and generally clean things up.
|
|
|
|
</p>
|
|
<p>Create a generated token: one that exists due to a use of implicit syntax.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre><span class="nv">generate = </span><span class="nf">(tag, value) -></span>
|
|
<span class="nv">tok = </span><span class="p">[</span><span class="nx">tag</span><span class="p">,</span> <span class="nx">value</span><span class="p">]</span>
|
|
<span class="nv">tok.generated = </span><span class="kc">yes</span>
|
|
<span class="nx">tok</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-2">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-2">¶</a>
|
|
</div>
|
|
|
|
<p>The <strong>Rewriter</strong> class is used by the <a href="lexer.html">Lexer</a>, directly against
|
|
its internal array of tokens.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre><span class="k">class</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">Rewriter</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-3">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-3">¶</a>
|
|
</div>
|
|
|
|
<p>Helpful snippet for debugging:
|
|
console.log (t[0] + '/' + t[1] for t in @tokens).join ' '
|
|
|
|
</p>
|
|
<p>Rewrite the token stream in multiple passes, one logical filter at
|
|
a time. This could certainly be changed into a single pass through the
|
|
stream, with a big ol' efficient switch, but it's much nicer to work with
|
|
like this. The order of these passes matters -- indentation must be
|
|
corrected before implicit parentheses can be wrapped around blocks of code.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="nv">rewrite: </span><span class="nf">(@tokens) -></span>
|
|
<span class="nx">@removeLeadingNewlines</span><span class="p">()</span>
|
|
<span class="nx">@removeMidExpressionNewlines</span><span class="p">()</span>
|
|
<span class="nx">@closeOpenCalls</span><span class="p">()</span>
|
|
<span class="nx">@closeOpenIndexes</span><span class="p">()</span>
|
|
<span class="nx">@addImplicitIndentation</span><span class="p">()</span>
|
|
<span class="nx">@tagPostfixConditionals</span><span class="p">()</span>
|
|
<span class="nx">@addImplicitBracesAndParens</span><span class="p">()</span>
|
|
<span class="nx">@addLocationDataToGeneratedTokens</span><span class="p">()</span>
|
|
<span class="nx">@tokens</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-4">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-4">¶</a>
|
|
</div>
|
|
|
|
<p>Rewrite the token stream, looking one token ahead and behind.
|
|
Allow the return value of the block to tell us how many tokens to move
|
|
forwards (or backwards) in the stream, to make sure we don't miss anything
|
|
as tokens are inserted and removed, and the stream changes length under
|
|
our feet.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="nv">scanTokens: </span><span class="nf">(block) -></span>
|
|
<span class="p">{</span><span class="nx">tokens</span><span class="p">}</span> <span class="o">=</span> <span class="k">this</span>
|
|
<span class="nv">i = </span><span class="mi">0</span>
|
|
<span class="nx">i</span> <span class="o">+=</span> <span class="nx">block</span><span class="p">.</span><span class="nx">call</span> <span class="k">this</span><span class="p">,</span> <span class="nx">token</span><span class="p">,</span> <span class="nx">i</span><span class="p">,</span> <span class="nx">tokens</span> <span class="k">while</span> <span class="nv">token = </span><span class="nx">tokens</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span>
|
|
<span class="kc">true</span>
|
|
|
|
<span class="nv">detectEnd: </span><span class="nf">(i, condition, action) -></span>
|
|
<span class="p">{</span><span class="nx">tokens</span><span class="p">}</span> <span class="o">=</span> <span class="k">this</span>
|
|
<span class="nv">levels = </span><span class="mi">0</span>
|
|
<span class="k">while</span> <span class="nv">token = </span><span class="nx">tokens</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span>
|
|
<span class="k">return</span> <span class="nx">action</span><span class="p">.</span><span class="nx">call</span> <span class="k">this</span><span class="p">,</span> <span class="nx">token</span><span class="p">,</span> <span class="nx">i</span> <span class="k">if</span> <span class="nx">levels</span> <span class="o">is</span> <span class="mi">0</span> <span class="o">and</span> <span class="nx">condition</span><span class="p">.</span><span class="nx">call</span> <span class="k">this</span><span class="p">,</span> <span class="nx">token</span><span class="p">,</span> <span class="nx">i</span>
|
|
<span class="k">return</span> <span class="nx">action</span><span class="p">.</span><span class="nx">call</span> <span class="k">this</span><span class="p">,</span> <span class="nx">token</span><span class="p">,</span> <span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">token</span> <span class="o">or</span> <span class="nx">levels</span> <span class="o"><</span> <span class="mi">0</span>
|
|
<span class="k">if</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">in</span> <span class="nx">EXPRESSION_START</span>
|
|
<span class="nx">levels</span> <span class="o">+=</span> <span class="mi">1</span>
|
|
<span class="k">else</span> <span class="k">if</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">in</span> <span class="nx">EXPRESSION_END</span>
|
|
<span class="nx">levels</span> <span class="o">-=</span> <span class="mi">1</span>
|
|
<span class="nx">i</span> <span class="o">+=</span> <span class="mi">1</span>
|
|
<span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-5">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-5">¶</a>
|
|
</div>
|
|
|
|
<p>Leading newlines would introduce an ambiguity in the grammar, so we
|
|
dispatch them here.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="nv">removeLeadingNewlines: </span><span class="nf">-></span>
|
|
<span class="k">break</span> <span class="k">for</span> <span class="p">[</span><span class="nx">tag</span><span class="p">],</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">@tokens</span> <span class="k">when</span> <span class="nx">tag</span> <span class="o">isnt</span> <span class="s">'TERMINATOR'</span>
|
|
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">i</span> <span class="k">if</span> <span class="nx">i</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-6">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-6">¶</a>
|
|
</div>
|
|
|
|
<p>Some blocks occur in the middle of expressions -- when we're expecting
|
|
this, remove their trailing newlines.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="nv">removeMidExpressionNewlines: </span><span class="nf">-></span>
|
|
<span class="nx">@scanTokens</span> <span class="nf">(token, i, tokens) -></span>
|
|
<span class="k">return</span> <span class="mi">1</span> <span class="k">unless</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s">'TERMINATOR'</span> <span class="o">and</span> <span class="nx">@tag</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="k">in</span> <span class="nx">EXPRESSION_CLOSE</span>
|
|
<span class="nx">tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span><span class="p">,</span> <span class="mi">1</span>
|
|
<span class="mi">0</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-7">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-7">¶</a>
|
|
</div>
|
|
|
|
<p>The lexer has tagged the opening parenthesis of a method call. Match it with
|
|
its paired close. We have the mis-nested outdent case included here for
|
|
calls that close on the same line, just before their outdent.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="nv">closeOpenCalls: </span><span class="nf">-></span>
|
|
<span class="nv">condition = </span><span class="nf">(token, i) -></span>
|
|
<span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">in</span> <span class="p">[</span><span class="s">')'</span><span class="p">,</span> <span class="s">'CALL_END'</span><span class="p">]</span> <span class="o">or</span>
|
|
<span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s">'OUTDENT'</span> <span class="o">and</span> <span class="nx">@tag</span><span class="p">(</span><span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">is</span> <span class="s">')'</span>
|
|
|
|
<span class="nv">action = </span><span class="nf">(token, i) -></span>
|
|
<span class="nx">@tokens</span><span class="p">[</span><span class="k">if</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s">'OUTDENT'</span> <span class="k">then</span> <span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span> <span class="k">else</span> <span class="nx">i</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s">'CALL_END'</span>
|
|
|
|
<span class="nx">@scanTokens</span> <span class="nf">(token, i) -></span>
|
|
<span class="nx">@detectEnd</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">condition</span><span class="p">,</span> <span class="nx">action</span> <span class="k">if</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s">'CALL_START'</span>
|
|
<span class="mi">1</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-8">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-8">¶</a>
|
|
</div>
|
|
|
|
<p>The lexer has tagged the opening parenthesis of an indexing operation call.
|
|
Match it with its paired close.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="nv">closeOpenIndexes: </span><span class="nf">-></span>
|
|
<span class="nv">condition = </span><span class="nf">(token, i) -></span>
|
|
<span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">in</span> <span class="p">[</span><span class="s">']'</span><span class="p">,</span> <span class="s">'INDEX_END'</span><span class="p">]</span>
|
|
|
|
<span class="nv">action = </span><span class="nf">(token, i) -></span>
|
|
<span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s">'INDEX_END'</span>
|
|
|
|
<span class="nx">@scanTokens</span> <span class="nf">(token, i) -></span>
|
|
<span class="nx">@detectEnd</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">condition</span><span class="p">,</span> <span class="nx">action</span> <span class="k">if</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s">'INDEX_START'</span>
|
|
<span class="mi">1</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-9">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-9">¶</a>
|
|
</div>
|
|
|
|
<p>Match tags in token stream starting at i with pattern, skipping HERECOMMENTs
|
|
Pattern may consist of strings (equality), an array of strings (one of)
|
|
or null (wildcard)
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="nv">matchTags: </span><span class="nf">(i, pattern...) -></span>
|
|
<span class="nv">fuzz = </span><span class="mi">0</span>
|
|
<span class="k">for</span> <span class="nx">j</span> <span class="k">in</span> <span class="p">[</span><span class="mi">0</span> <span class="p">...</span> <span class="nx">pattern</span><span class="p">.</span><span class="nx">length</span><span class="p">]</span>
|
|
<span class="nx">fuzz</span> <span class="o">+=</span> <span class="mi">2</span> <span class="k">while</span> <span class="nx">@tag</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="nx">j</span> <span class="o">+</span> <span class="nx">fuzz</span><span class="p">)</span> <span class="o">is</span> <span class="s">'HERECOMMENT'</span>
|
|
<span class="k">continue</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">pattern</span><span class="p">[</span><span class="nx">j</span><span class="p">]</span><span class="o">?</span>
|
|
<span class="nx">pattern</span><span class="p">[</span><span class="nx">j</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="nx">pattern</span><span class="p">[</span><span class="nx">j</span><span class="p">]]</span> <span class="k">if</span> <span class="k">typeof</span> <span class="nx">pattern</span><span class="p">[</span><span class="nx">j</span><span class="p">]</span> <span class="o">is</span> <span class="s">'string'</span>
|
|
<span class="k">return</span> <span class="kc">no</span> <span class="k">if</span> <span class="nx">@tag</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="nx">j</span> <span class="o">+</span> <span class="nx">fuzz</span><span class="p">)</span> <span class="o">not</span> <span class="k">in</span> <span class="nx">pattern</span><span class="p">[</span><span class="nx">j</span><span class="p">]</span>
|
|
<span class="kc">yes</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-10">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-10">¶</a>
|
|
</div>
|
|
|
|
<p>yes iff standing in front of something looking like
|
|
@<x>: or <x>:, skipping over 'HERECOMMENT's
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="nv">looksObjectish: </span><span class="nf">(j) -></span>
|
|
<span class="nx">@matchTags</span><span class="p">(</span><span class="nx">j</span><span class="p">,</span> <span class="s">'@'</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="s">':'</span><span class="p">)</span> <span class="o">or</span> <span class="nx">@matchTags</span><span class="p">(</span><span class="nx">j</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="s">':'</span><span class="p">)</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-11">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-11">¶</a>
|
|
</div>
|
|
|
|
<p>yes iff current line of tokens contain an element of tags on same
|
|
expression level. Stop searching at LINEBREAKS or explicit start of
|
|
containing balanced expression.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="nv">findTagsBackwards: </span><span class="nf">(i, tags) -></span>
|
|
<span class="nv">backStack = </span><span class="p">[]</span>
|
|
<span class="k">while</span> <span class="nx">i</span> <span class="o">>=</span> <span class="mi">0</span> <span class="o">and</span> <span class="p">(</span><span class="nx">backStack</span><span class="p">.</span><span class="nx">length</span> <span class="o">or</span>
|
|
<span class="nx">@tag</span><span class="p">(</span><span class="nx">i</span><span class="p">)</span> <span class="o">not</span> <span class="k">in</span> <span class="nx">tags</span> <span class="o">and</span>
|
|
<span class="p">(</span><span class="nx">@tag</span><span class="p">(</span><span class="nx">i</span><span class="p">)</span> <span class="o">not</span> <span class="k">in</span> <span class="nx">EXPRESSION_START</span> <span class="o">or</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span><span class="p">].</span><span class="nx">generated</span><span class="p">)</span> <span class="o">and</span>
|
|
<span class="nx">@tag</span><span class="p">(</span><span class="nx">i</span><span class="p">)</span> <span class="o">not</span> <span class="k">in</span> <span class="nx">LINEBREAKS</span><span class="p">)</span>
|
|
<span class="nx">backStack</span><span class="p">.</span><span class="nx">push</span> <span class="nx">@tag</span><span class="p">(</span><span class="nx">i</span><span class="p">)</span> <span class="k">if</span> <span class="nx">@tag</span><span class="p">(</span><span class="nx">i</span><span class="p">)</span> <span class="k">in</span> <span class="nx">EXPRESSION_END</span>
|
|
<span class="nx">backStack</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span> <span class="k">if</span> <span class="nx">@tag</span><span class="p">(</span><span class="nx">i</span><span class="p">)</span> <span class="k">in</span> <span class="nx">EXPRESSION_START</span> <span class="o">and</span> <span class="nx">backStack</span><span class="p">.</span><span class="nx">length</span>
|
|
<span class="nx">i</span> <span class="o">-=</span> <span class="mi">1</span>
|
|
<span class="nx">@tag</span><span class="p">(</span><span class="nx">i</span><span class="p">)</span> <span class="k">in</span> <span class="nx">tags</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-12">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-12">¶</a>
|
|
</div>
|
|
|
|
<p>Look for signs of implicit calls and objects in the token stream and
|
|
add them.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="nv">addImplicitBracesAndParens: </span><span class="nf">-></span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-13">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-13">¶</a>
|
|
</div>
|
|
|
|
<p>Track current balancing depth (both implicit and explicit) on stack.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="nv">stack = </span><span class="p">[]</span>
|
|
|
|
<span class="nx">@scanTokens</span> <span class="nf">(token, i, tokens) -></span>
|
|
<span class="p">[</span><span class="nx">tag</span><span class="p">]</span> <span class="o">=</span> <span class="nx">token</span>
|
|
<span class="p">[</span><span class="nx">prevTag</span><span class="p">]</span> <span class="o">=</span> <span class="k">if</span> <span class="nx">i</span> <span class="o">></span> <span class="mi">0</span> <span class="k">then</span> <span class="nx">tokens</span><span class="p">[</span><span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="k">else</span> <span class="p">[]</span>
|
|
<span class="p">[</span><span class="nx">nextTag</span><span class="p">]</span> <span class="o">=</span> <span class="k">if</span> <span class="nx">i</span> <span class="o"><</span> <span class="nx">tokens</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span> <span class="k">then</span> <span class="nx">tokens</span><span class="p">[</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="k">else</span> <span class="p">[]</span>
|
|
<span class="nv">stackTop = </span><span class="nf">-></span> <span class="nx">stack</span><span class="p">[</span><span class="nx">stack</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">startIdx = </span><span class="nx">i</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-14">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-14">¶</a>
|
|
</div>
|
|
|
|
<p>Helper function, used for keeping track of the number of tokens consumed
|
|
and spliced, when returning for getting a new token.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="nv">forward = </span><span class="nf">(n) -></span> <span class="nx">i</span> <span class="o">-</span> <span class="nx">startIdx</span> <span class="o">+</span> <span class="nx">n</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-15">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-15">¶</a>
|
|
</div>
|
|
|
|
<p>Helper functions
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="nv">inImplicit = </span><span class="nf">-></span> <span class="nx">stackTop</span><span class="p">()</span><span class="o">?</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="o">?</span><span class="p">.</span><span class="nx">ours</span>
|
|
<span class="nv">inImplicitCall = </span><span class="nf">-></span> <span class="nx">inImplicit</span><span class="p">()</span> <span class="o">and</span> <span class="nx">stackTop</span><span class="p">()</span><span class="o">?</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s">'('</span>
|
|
<span class="nv">inImplicitObject = </span><span class="nf">-></span> <span class="nx">inImplicit</span><span class="p">()</span> <span class="o">and</span> <span class="nx">stackTop</span><span class="p">()</span><span class="o">?</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s">'{'</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-16">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-16">¶</a>
|
|
</div>
|
|
|
|
<p>Unclosed control statement inside implicit parens (like
|
|
class declaration or if-conditionals)
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="nv">inImplicitControl = </span><span class="nf">-></span> <span class="nx">inImplicit</span> <span class="o">and</span> <span class="nx">stackTop</span><span class="p">()</span><span class="o">?</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s">'CONTROL'</span>
|
|
|
|
<span class="nv">startImplicitCall = </span><span class="nf">(j) -></span>
|
|
<span class="nv">idx = </span><span class="nx">j</span> <span class="o">?</span> <span class="nx">i</span>
|
|
<span class="nx">stack</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="s">'('</span><span class="p">,</span> <span class="nx">idx</span><span class="p">,</span> <span class="nv">ours: </span><span class="kc">yes</span><span class="p">]</span>
|
|
<span class="nx">tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">idx</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">generate</span> <span class="s">'CALL_START'</span><span class="p">,</span> <span class="s">'('</span>
|
|
<span class="nx">i</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">j</span><span class="o">?</span>
|
|
|
|
<span class="nv">endImplicitCall = </span><span class="nf">-></span>
|
|
<span class="nx">stack</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span>
|
|
<span class="nx">tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">generate</span> <span class="s">'CALL_END'</span><span class="p">,</span> <span class="s">')'</span>
|
|
<span class="nx">i</span> <span class="o">+=</span> <span class="mi">1</span>
|
|
|
|
<span class="nv">startImplicitObject = </span><span class="nf">(j, startsLine = yes) -></span>
|
|
<span class="nv">idx = </span><span class="nx">j</span> <span class="o">?</span> <span class="nx">i</span>
|
|
<span class="nx">stack</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="s">'{'</span><span class="p">,</span> <span class="nx">idx</span><span class="p">,</span> <span class="nv">sameLine: </span><span class="kc">yes</span><span class="p">,</span> <span class="nv">startsLine: </span><span class="nx">startsLine</span><span class="p">,</span> <span class="nv">ours: </span><span class="kc">yes</span><span class="p">]</span>
|
|
<span class="nx">tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">idx</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">generate</span> <span class="s">'{'</span><span class="p">,</span> <span class="nx">generate</span><span class="p">(</span><span class="k">new</span> <span class="nb">String</span><span class="p">(</span><span class="s">'{'</span><span class="p">))</span>
|
|
<span class="nx">i</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">j</span><span class="o">?</span>
|
|
|
|
<span class="nv">endImplicitObject = </span><span class="nf">(j) -></span>
|
|
<span class="nv">j = </span><span class="nx">j</span> <span class="o">?</span> <span class="nx">i</span>
|
|
<span class="nx">stack</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span>
|
|
<span class="nx">tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">j</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">generate</span> <span class="s">'}'</span><span class="p">,</span> <span class="s">'}'</span>
|
|
<span class="nx">i</span> <span class="o">+=</span> <span class="mi">1</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-17">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-17">¶</a>
|
|
</div>
|
|
|
|
<p>Don't end an implicit call on next indent if any of these are in an argument
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="k">if</span> <span class="nx">inImplicitCall</span><span class="p">()</span> <span class="o">and</span> <span class="nx">tag</span> <span class="k">in</span> <span class="p">[</span><span class="s">'IF'</span><span class="p">,</span> <span class="s">'TRY'</span><span class="p">,</span> <span class="s">'FINALLY'</span><span class="p">,</span> <span class="s">'CATCH'</span><span class="p">,</span>
|
|
<span class="s">'CLASS'</span><span class="p">,</span> <span class="s">'SWITCH'</span><span class="p">]</span>
|
|
<span class="nx">stack</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="s">'CONTROL'</span><span class="p">,</span> <span class="nx">i</span><span class="p">,</span> <span class="nv">ours: </span><span class="kc">true</span><span class="p">]</span>
|
|
<span class="k">return</span> <span class="nx">forward</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="nx">tag</span> <span class="o">is</span> <span class="s">'INDENT'</span> <span class="o">and</span> <span class="nx">inImplicit</span><span class="p">()</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-18">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-18">¶</a>
|
|
</div>
|
|
|
|
<p>An INDENT closes an implicit call unless
|
|
1. We have seen a CONTROL argument on the line.
|
|
2. The last token before the indent is part of the list below
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="k">if</span> <span class="nx">prevTag</span> <span class="o">not</span> <span class="k">in</span> <span class="p">[</span><span class="s">'=>'</span><span class="p">,</span> <span class="s">'->'</span><span class="p">,</span> <span class="s">'['</span><span class="p">,</span> <span class="s">'('</span><span class="p">,</span> <span class="s">','</span><span class="p">,</span> <span class="s">'{'</span><span class="p">,</span> <span class="s">'TRY'</span><span class="p">,</span> <span class="s">'ELSE'</span><span class="p">,</span> <span class="s">'='</span><span class="p">]</span>
|
|
<span class="nx">endImplicitCall</span><span class="p">()</span> <span class="k">while</span> <span class="nx">inImplicitCall</span><span class="p">()</span>
|
|
<span class="nx">stack</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span> <span class="k">if</span> <span class="nx">inImplicitControl</span><span class="p">()</span>
|
|
<span class="nx">stack</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="nx">tag</span><span class="p">,</span> <span class="nx">i</span><span class="p">]</span>
|
|
<span class="k">return</span> <span class="nx">forward</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-19">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-19">¶</a>
|
|
</div>
|
|
|
|
<p>Straightforward start of explicit expression
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="k">if</span> <span class="nx">tag</span> <span class="k">in</span> <span class="nx">EXPRESSION_START</span>
|
|
<span class="nx">stack</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="nx">tag</span><span class="p">,</span> <span class="nx">i</span><span class="p">]</span>
|
|
<span class="k">return</span> <span class="nx">forward</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-20">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-20">¶</a>
|
|
</div>
|
|
|
|
<p>Close all implicit expressions inside of explicitly closed expressions.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="k">if</span> <span class="nx">tag</span> <span class="k">in</span> <span class="nx">EXPRESSION_END</span>
|
|
<span class="k">while</span> <span class="nx">inImplicit</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="nx">inImplicitCall</span><span class="p">()</span>
|
|
<span class="nx">endImplicitCall</span><span class="p">()</span>
|
|
<span class="k">else</span> <span class="k">if</span> <span class="nx">inImplicitObject</span><span class="p">()</span>
|
|
<span class="nx">endImplicitObject</span><span class="p">()</span>
|
|
<span class="k">else</span>
|
|
<span class="nx">stack</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span>
|
|
<span class="nx">stack</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-21">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-21">¶</a>
|
|
</div>
|
|
|
|
<p>Recognize standard implicit calls like
|
|
f a, f() b, f? c, h[0] d etc.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="k">if</span> <span class="p">(</span><span class="nx">tag</span> <span class="k">in</span> <span class="nx">IMPLICIT_FUNC</span> <span class="o">and</span> <span class="nx">token</span><span class="p">.</span><span class="nx">spaced</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">token</span><span class="p">.</span><span class="nx">stringEnd</span> <span class="o">or</span>
|
|
<span class="nx">tag</span> <span class="o">is</span> <span class="s">'?'</span> <span class="o">and</span> <span class="nx">i</span> <span class="o">></span> <span class="mi">0</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">tokens</span><span class="p">[</span><span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">].</span><span class="nx">spaced</span><span class="p">)</span> <span class="o">and</span>
|
|
<span class="p">(</span><span class="nx">nextTag</span> <span class="k">in</span> <span class="nx">IMPLICIT_CALL</span> <span class="o">or</span>
|
|
<span class="nx">nextTag</span> <span class="k">in</span> <span class="nx">IMPLICIT_UNSPACED_CALL</span> <span class="o">and</span>
|
|
<span class="o">not</span> <span class="nx">tokens</span><span class="p">[</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span><span class="o">?</span><span class="p">.</span><span class="nx">spaced</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">tokens</span><span class="p">[</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span><span class="o">?</span><span class="p">.</span><span class="nx">newLine</span><span class="p">)</span>
|
|
<span class="nv">tag = </span><span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s">'FUNC_EXIST'</span> <span class="k">if</span> <span class="nx">tag</span> <span class="o">is</span> <span class="s">'?'</span>
|
|
<span class="nx">startImplicitCall</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span>
|
|
<span class="k">return</span> <span class="nx">forward</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-22">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-22">¶</a>
|
|
</div>
|
|
|
|
<p>Implicit call taking an implicit indented object as first argument.
|
|
f
|
|
a: b
|
|
c: d
|
|
and
|
|
f
|
|
1
|
|
a: b
|
|
b: c
|
|
Don't accept implicit calls of this type, when on the same line
|
|
as the control strucutures below as that may misinterpret constructs like:
|
|
if f
|
|
a: 1
|
|
as
|
|
if f(a: 1)
|
|
which is probably always unintended.
|
|
Furthermore don't allow this in literal arrays, as
|
|
that creates grammatical ambiguities.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="k">if</span> <span class="nx">@matchTags</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span> <span class="nx">IMPLICIT_FUNC</span><span class="p">,</span> <span class="s">'INDENT'</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="s">':'</span><span class="p">)</span> <span class="o">and</span>
|
|
<span class="o">not</span> <span class="nx">@findTagsBackwards</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span> <span class="p">[</span><span class="s">'CLASS'</span><span class="p">,</span> <span class="s">'EXTENDS'</span><span class="p">,</span> <span class="s">'IF'</span><span class="p">,</span> <span class="s">'CATCH'</span><span class="p">,</span>
|
|
<span class="s">'SWITCH'</span><span class="p">,</span> <span class="s">'LEADING_WHEN'</span><span class="p">,</span> <span class="s">'FOR'</span><span class="p">,</span> <span class="s">'WHILE'</span><span class="p">,</span> <span class="s">'UNTIL'</span><span class="p">])</span>
|
|
<span class="nx">startImplicitCall</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span>
|
|
<span class="nx">stack</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="s">'INDENT'</span><span class="p">,</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">2</span><span class="p">]</span>
|
|
<span class="k">return</span> <span class="nx">forward</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-23">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-23">¶</a>
|
|
</div>
|
|
|
|
<p>Implicit objects start here
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="k">if</span> <span class="nx">tag</span> <span class="o">is</span> <span class="s">':'</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-24">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-24">¶</a>
|
|
</div>
|
|
|
|
<p>Go back to the (implicit) start of the object
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="k">if</span> <span class="nx">@tag</span><span class="p">(</span><span class="nx">i</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span> <span class="o">is</span> <span class="s">'@'</span> <span class="k">then</span> <span class="nv">s = </span><span class="nx">i</span> <span class="o">-</span> <span class="mi">2</span> <span class="k">else</span> <span class="nv">s = </span><span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span>
|
|
<span class="nx">s</span> <span class="o">-=</span> <span class="mi">2</span> <span class="k">while</span> <span class="nx">@tag</span><span class="p">(</span><span class="nx">s</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span> <span class="o">is</span> <span class="s">'HERECOMMENT'</span>
|
|
|
|
<span class="nv">startsLine = </span><span class="nx">s</span> <span class="o">is</span> <span class="mi">0</span> <span class="o">or</span> <span class="nx">@tag</span><span class="p">(</span><span class="nx">s</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="k">in</span> <span class="nx">LINEBREAKS</span> <span class="o">or</span> <span class="nx">tokens</span><span class="p">[</span><span class="nx">s</span> <span class="o">-</span> <span class="mi">1</span><span class="p">].</span><span class="nx">newLine</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-25">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-25">¶</a>
|
|
</div>
|
|
|
|
<p>Are we just continuing an already declared object?
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="k">if</span> <span class="nx">stackTop</span><span class="p">()</span>
|
|
<span class="p">[</span><span class="nx">stackTag</span><span class="p">,</span> <span class="nx">stackIdx</span><span class="p">]</span> <span class="o">=</span> <span class="nx">stackTop</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="nx">stackTag</span> <span class="o">is</span> <span class="s">'{'</span> <span class="o">or</span> <span class="nx">stackTag</span> <span class="o">is</span> <span class="s">'INDENT'</span> <span class="o">and</span> <span class="nx">@tag</span><span class="p">(</span><span class="nx">stackIdx</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">is</span> <span class="s">'{'</span><span class="p">)</span> <span class="o">and</span>
|
|
<span class="p">(</span><span class="nx">startsLine</span> <span class="o">or</span> <span class="nx">@tag</span><span class="p">(</span><span class="nx">s</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">is</span> <span class="s">','</span> <span class="o">or</span> <span class="nx">@tag</span><span class="p">(</span><span class="nx">s</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">is</span> <span class="s">'{'</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="nx">forward</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
|
|
|
<span class="nx">startImplicitObject</span><span class="p">(</span><span class="nx">s</span><span class="p">,</span> <span class="o">!!</span><span class="nx">startsLine</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="nx">forward</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-26">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-26">¶</a>
|
|
</div>
|
|
|
|
<p>End implicit calls when chaining method calls
|
|
like e.g.:
|
|
f ->
|
|
a
|
|
.g b, ->
|
|
c
|
|
.h a
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="k">if</span> <span class="nx">prevTag</span> <span class="o">is</span> <span class="s">'OUTDENT'</span> <span class="o">and</span> <span class="nx">inImplicitCall</span><span class="p">()</span> <span class="o">and</span> <span class="nx">tag</span> <span class="k">in</span> <span class="p">[</span><span class="s">'.'</span><span class="p">,</span> <span class="s">'?.'</span><span class="p">,</span> <span class="s">'::'</span><span class="p">,</span> <span class="s">'?::'</span><span class="p">]</span>
|
|
<span class="nx">endImplicitCall</span><span class="p">()</span>
|
|
<span class="k">return</span> <span class="nx">forward</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
|
|
|
<span class="nx">stackTop</span><span class="p">()[</span><span class="mi">2</span><span class="p">].</span><span class="nv">sameLine = </span><span class="kc">no</span> <span class="k">if</span> <span class="nx">inImplicitObject</span><span class="p">()</span> <span class="o">and</span> <span class="nx">tag</span> <span class="k">in</span> <span class="nx">LINEBREAKS</span>
|
|
|
|
<span class="k">if</span> <span class="nx">tag</span> <span class="k">in</span> <span class="nx">IMPLICIT_END</span>
|
|
<span class="k">while</span> <span class="nx">inImplicit</span><span class="p">()</span>
|
|
<span class="p">[</span><span class="nx">stackTag</span><span class="p">,</span> <span class="nx">stackIdx</span><span class="p">,</span> <span class="p">{</span><span class="nx">sameLine</span><span class="p">,</span> <span class="nx">startsLine</span><span class="p">}]</span> <span class="o">=</span> <span class="nx">stackTop</span><span class="p">()</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-27">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-27">¶</a>
|
|
</div>
|
|
|
|
<p>Close implicit calls when reached end of argument list
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="k">if</span> <span class="nx">inImplicitCall</span><span class="p">()</span> <span class="o">and</span> <span class="nx">prevTag</span> <span class="o">isnt</span> <span class="s">','</span>
|
|
<span class="nx">endImplicitCall</span><span class="p">()</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-28">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-28">¶</a>
|
|
</div>
|
|
|
|
<p>Close implicit objects such as:
|
|
return a: 1, b: 2 unless true
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="k">else</span> <span class="k">if</span> <span class="nx">inImplicitObject</span><span class="p">()</span> <span class="o">and</span> <span class="nx">sameLine</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">startsLine</span>
|
|
<span class="nx">endImplicitObject</span><span class="p">()</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-29">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-29">¶</a>
|
|
</div>
|
|
|
|
<p>Close implicit objects when at end of line, line didn't end with a comma
|
|
and the implicit object didn't start the line or the next line doesn't look like
|
|
the continuation of an object.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="k">else</span> <span class="k">if</span> <span class="nx">inImplicitObject</span><span class="p">()</span> <span class="o">and</span> <span class="nx">tag</span> <span class="o">is</span> <span class="s">'TERMINATOR'</span> <span class="o">and</span> <span class="nx">prevTag</span> <span class="o">isnt</span> <span class="s">','</span> <span class="o">and</span>
|
|
<span class="o">not</span> <span class="p">(</span><span class="nx">startsLine</span> <span class="o">and</span> <span class="nx">@looksObjectish</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">))</span>
|
|
<span class="nx">endImplicitObject</span><span class="p">()</span>
|
|
<span class="k">else</span>
|
|
<span class="k">break</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-30">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-30">¶</a>
|
|
</div>
|
|
|
|
<p>Close implicit object if comma is the last character
|
|
and what comes after doesn't look like it belongs.
|
|
This is used for trailing commas and calls, like:
|
|
x =
|
|
a: b,
|
|
c: d,
|
|
e = 2
|
|
|
|
</p>
|
|
<p>and
|
|
|
|
</p>
|
|
<p>f a, b: c, d: e, f, g: h: i, j
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="k">if</span> <span class="nx">tag</span> <span class="o">is</span> <span class="s">','</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@looksObjectish</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">and</span> <span class="nx">inImplicitObject</span><span class="p">()</span> <span class="o">and</span>
|
|
<span class="p">(</span><span class="nx">nextTag</span> <span class="o">isnt</span> <span class="s">'TERMINATOR'</span> <span class="o">or</span> <span class="o">not</span> <span class="nx">@looksObjectish</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">2</span><span class="p">))</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-31">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-31">¶</a>
|
|
</div>
|
|
|
|
<p>When nextTag is OUTDENT the comma is insignificant and
|
|
should just be ignored so embed it in the implicit object.
|
|
|
|
</p>
|
|
<p>When it isn't the comma go on to play a role in a call or
|
|
array further up the stack, so give it a chance.
|
|
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="nv">offset = </span><span class="k">if</span> <span class="nx">nextTag</span> <span class="o">is</span> <span class="s">'OUTDENT'</span> <span class="k">then</span> <span class="mi">1</span> <span class="k">else</span> <span class="mi">0</span>
|
|
<span class="k">while</span> <span class="nx">inImplicitObject</span><span class="p">()</span>
|
|
<span class="nx">endImplicitObject</span> <span class="nx">i</span> <span class="o">+</span> <span class="nx">offset</span>
|
|
<span class="k">return</span> <span class="nx">forward</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-32">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-32">¶</a>
|
|
</div>
|
|
|
|
<p>Add location data to all tokens generated by the rewriter.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="nv">addLocationDataToGeneratedTokens: </span><span class="nf">-></span>
|
|
<span class="nx">@scanTokens</span> <span class="nf">(token, i, tokens) -></span>
|
|
<span class="k">return</span> <span class="mi">1</span> <span class="k">if</span> <span class="nx">token</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
|
|
<span class="k">return</span> <span class="mi">1</span> <span class="k">unless</span> <span class="nx">token</span><span class="p">.</span><span class="nx">generated</span> <span class="o">or</span> <span class="nx">token</span><span class="p">.</span><span class="nx">explicit</span>
|
|
<span class="k">if</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s">'{'</span> <span class="o">and</span> <span class="nx">nextLocation</span><span class="o">=</span><span class="nx">tokens</span><span class="p">[</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span><span class="o">?</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
|
|
<span class="p">{</span><span class="nv">first_line: </span><span class="nx">line</span><span class="p">,</span> <span class="nv">first_column: </span><span class="nx">column</span><span class="p">}</span> <span class="o">=</span> <span class="nx">nextLocation</span>
|
|
<span class="k">else</span> <span class="k">if</span> <span class="nv">prevLocation = </span><span class="nx">tokens</span><span class="p">[</span><span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span><span class="o">?</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
|
|
<span class="p">{</span><span class="nv">last_line: </span><span class="nx">line</span><span class="p">,</span> <span class="nv">last_column: </span><span class="nx">column</span><span class="p">}</span> <span class="o">=</span> <span class="nx">prevLocation</span>
|
|
<span class="k">else</span>
|
|
<span class="nv">line = column = </span><span class="mi">0</span>
|
|
<span class="nx">token</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span>
|
|
<span class="nv">first_line: </span> <span class="nx">line</span>
|
|
<span class="nv">first_column: </span><span class="nx">column</span>
|
|
<span class="nv">last_line: </span> <span class="nx">line</span>
|
|
<span class="nv">last_column: </span> <span class="nx">column</span>
|
|
<span class="mi">1</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-33">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-33">¶</a>
|
|
</div>
|
|
|
|
<p>Because our grammar is LALR(1), it can't handle some single-line
|
|
expressions that lack ending delimiters. The <strong>Rewriter</strong> adds the implicit
|
|
blocks, so it doesn't need to. ')' can close a single-line block,
|
|
but we need to make sure it's balanced.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="nv">addImplicitIndentation: </span><span class="nf">-></span>
|
|
<span class="nv">starter = indent = outdent = </span><span class="kc">null</span>
|
|
|
|
<span class="nv">condition = </span><span class="nf">(token, i) -></span>
|
|
<span class="nx">token</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">isnt</span> <span class="s">';'</span> <span class="o">and</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">in</span> <span class="nx">SINGLE_CLOSERS</span> <span class="o">and</span>
|
|
<span class="o">not</span> <span class="p">(</span><span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s">'ELSE'</span> <span class="o">and</span> <span class="nx">starter</span> <span class="o">not</span> <span class="k">in</span> <span class="p">[</span><span class="s">'IF'</span><span class="p">,</span> <span class="s">'THEN'</span><span class="p">])</span>
|
|
|
|
<span class="nv">action = </span><span class="nf">(token, i) -></span>
|
|
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="p">(</span><span class="k">if</span> <span class="nx">@tag</span><span class="p">(</span><span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">is</span> <span class="s">','</span> <span class="k">then</span> <span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span> <span class="k">else</span> <span class="nx">i</span><span class="p">),</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">outdent</span>
|
|
|
|
<span class="nx">@scanTokens</span> <span class="nf">(token, i, tokens) -></span>
|
|
<span class="p">[</span><span class="nx">tag</span><span class="p">]</span> <span class="o">=</span> <span class="nx">token</span>
|
|
<span class="k">if</span> <span class="nx">tag</span> <span class="o">is</span> <span class="s">'TERMINATOR'</span> <span class="o">and</span> <span class="nx">@tag</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">is</span> <span class="s">'THEN'</span>
|
|
<span class="nx">tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span><span class="p">,</span> <span class="mi">1</span>
|
|
<span class="k">return</span> <span class="mi">0</span>
|
|
<span class="k">if</span> <span class="nx">tag</span> <span class="o">is</span> <span class="s">'ELSE'</span> <span class="o">and</span> <span class="nx">@tag</span><span class="p">(</span><span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">isnt</span> <span class="s">'OUTDENT'</span>
|
|
<span class="nx">tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">@indentation</span><span class="p">()...</span>
|
|
<span class="k">return</span> <span class="mi">2</span>
|
|
<span class="k">if</span> <span class="nx">tag</span> <span class="o">is</span> <span class="s">'CATCH'</span> <span class="o">and</span> <span class="nx">@tag</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">2</span><span class="p">)</span> <span class="k">in</span> <span class="p">[</span><span class="s">'OUTDENT'</span><span class="p">,</span> <span class="s">'TERMINATOR'</span><span class="p">,</span> <span class="s">'FINALLY'</span><span class="p">]</span>
|
|
<span class="nx">tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">@indentation</span><span class="p">()...</span>
|
|
<span class="k">return</span> <span class="mi">4</span>
|
|
<span class="k">if</span> <span class="nx">tag</span> <span class="k">in</span> <span class="nx">SINGLE_LINERS</span> <span class="o">and</span> <span class="nx">@tag</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">isnt</span> <span class="s">'INDENT'</span> <span class="o">and</span>
|
|
<span class="o">not</span> <span class="p">(</span><span class="nx">tag</span> <span class="o">is</span> <span class="s">'ELSE'</span> <span class="o">and</span> <span class="nx">@tag</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">is</span> <span class="s">'IF'</span><span class="p">)</span>
|
|
<span class="nv">starter = </span><span class="nx">tag</span>
|
|
<span class="p">[</span><span class="nx">indent</span><span class="p">,</span> <span class="nx">outdent</span><span class="p">]</span> <span class="o">=</span> <span class="nx">@indentation</span> <span class="kc">yes</span>
|
|
<span class="nv">indent.fromThen = </span><span class="kc">true</span> <span class="k">if</span> <span class="nx">starter</span> <span class="o">is</span> <span class="s">'THEN'</span>
|
|
<span class="nx">tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">indent</span>
|
|
<span class="nx">@detectEnd</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">2</span><span class="p">,</span> <span class="nx">condition</span><span class="p">,</span> <span class="nx">action</span>
|
|
<span class="nx">tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span><span class="p">,</span> <span class="mi">1</span> <span class="k">if</span> <span class="nx">tag</span> <span class="o">is</span> <span class="s">'THEN'</span>
|
|
<span class="k">return</span> <span class="mi">1</span>
|
|
<span class="k">return</span> <span class="mi">1</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-34">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-34">¶</a>
|
|
</div>
|
|
|
|
<p>Tag postfix conditionals as such, so that we can parse them with a
|
|
different precedence.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="nv">tagPostfixConditionals: </span><span class="nf">-></span>
|
|
|
|
<span class="nv">original = </span><span class="kc">null</span>
|
|
|
|
<span class="nv">condition = </span><span class="nf">(token, i) -></span>
|
|
<span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">in</span> <span class="p">[</span><span class="s">'TERMINATOR'</span><span class="p">,</span> <span class="s">'INDENT'</span><span class="p">]</span>
|
|
|
|
<span class="nv">action = </span><span class="nf">(token, i) -></span>
|
|
<span class="k">if</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">isnt</span> <span class="s">'INDENT'</span> <span class="o">or</span> <span class="p">(</span><span class="nx">token</span><span class="p">.</span><span class="nx">generated</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">token</span><span class="p">.</span><span class="nx">fromThen</span><span class="p">)</span>
|
|
<span class="nx">original</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="s">'POST_'</span> <span class="o">+</span> <span class="nx">original</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
|
|
<span class="nx">@scanTokens</span> <span class="nf">(token, i) -></span>
|
|
<span class="k">return</span> <span class="mi">1</span> <span class="k">unless</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s">'IF'</span>
|
|
<span class="nv">original = </span><span class="nx">token</span>
|
|
<span class="nx">@detectEnd</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">condition</span><span class="p">,</span> <span class="nx">action</span>
|
|
<span class="mi">1</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-35">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-35">¶</a>
|
|
</div>
|
|
|
|
<p>Generate the indentation tokens, based on another token on the same line.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="nv">indentation: </span><span class="nf">(implicit = no) -></span>
|
|
<span class="nv">indent = </span><span class="p">[</span><span class="s">'INDENT'</span><span class="p">,</span> <span class="mi">2</span><span class="p">]</span>
|
|
<span class="nv">outdent = </span><span class="p">[</span><span class="s">'OUTDENT'</span><span class="p">,</span> <span class="mi">2</span><span class="p">]</span>
|
|
<span class="nv">indent.generated = outdent.generated = </span><span class="kc">yes</span> <span class="k">if</span> <span class="nx">implicit</span>
|
|
<span class="nv">indent.explicit = outdent.explicit = </span><span class="kc">yes</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">implicit</span>
|
|
<span class="p">[</span><span class="nx">indent</span><span class="p">,</span> <span class="nx">outdent</span><span class="p">]</span>
|
|
|
|
<span class="nv">generate: </span><span class="nx">generate</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-36">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-36">¶</a>
|
|
</div>
|
|
|
|
<p>Look up a tag by token index.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre> <span class="nv">tag: </span><span class="nf">(i) -></span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span><span class="o">?</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-37">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-37">¶</a>
|
|
</div>
|
|
|
|
<h2>Constants</h2>
|
|
<p>List of the token pairs that must be balanced.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre><span class="nv">BALANCED_PAIRS = </span><span class="p">[</span>
|
|
<span class="p">[</span><span class="s">'('</span><span class="p">,</span> <span class="s">')'</span><span class="p">]</span>
|
|
<span class="p">[</span><span class="s">'['</span><span class="p">,</span> <span class="s">']'</span><span class="p">]</span>
|
|
<span class="p">[</span><span class="s">'{'</span><span class="p">,</span> <span class="s">'}'</span><span class="p">]</span>
|
|
<span class="p">[</span><span class="s">'INDENT'</span><span class="p">,</span> <span class="s">'OUTDENT'</span><span class="p">],</span>
|
|
<span class="p">[</span><span class="s">'CALL_START'</span><span class="p">,</span> <span class="s">'CALL_END'</span><span class="p">]</span>
|
|
<span class="p">[</span><span class="s">'PARAM_START'</span><span class="p">,</span> <span class="s">'PARAM_END'</span><span class="p">]</span>
|
|
<span class="p">[</span><span class="s">'INDEX_START'</span><span class="p">,</span> <span class="s">'INDEX_END'</span><span class="p">]</span>
|
|
<span class="p">]</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-38">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-38">¶</a>
|
|
</div>
|
|
|
|
<p>The inverse mappings of <code>BALANCED_PAIRS</code> we're trying to fix up, so we can
|
|
look things up from either end.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre><span class="nv">exports.INVERSES = INVERSES = </span><span class="p">{}</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-39">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-39">¶</a>
|
|
</div>
|
|
|
|
<p>The tokens that signal the start/end of a balanced pair.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre><span class="nv">EXPRESSION_START = </span><span class="p">[]</span>
|
|
<span class="nv">EXPRESSION_END = </span><span class="p">[]</span>
|
|
|
|
<span class="k">for</span> <span class="p">[</span><span class="nx">left</span><span class="p">,</span> <span class="nx">rite</span><span class="p">]</span> <span class="k">in</span> <span class="nx">BALANCED_PAIRS</span>
|
|
<span class="nx">EXPRESSION_START</span><span class="p">.</span><span class="nx">push</span> <span class="nx">INVERSES</span><span class="p">[</span><span class="nx">rite</span><span class="p">]</span> <span class="o">=</span> <span class="nx">left</span>
|
|
<span class="nx">EXPRESSION_END</span> <span class="p">.</span><span class="nx">push</span> <span class="nx">INVERSES</span><span class="p">[</span><span class="nx">left</span><span class="p">]</span> <span class="o">=</span> <span class="nx">rite</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-40">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-40">¶</a>
|
|
</div>
|
|
|
|
<p>Tokens that indicate the close of a clause of an expression.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre><span class="nv">EXPRESSION_CLOSE = </span><span class="p">[</span><span class="s">'CATCH'</span><span class="p">,</span> <span class="s">'WHEN'</span><span class="p">,</span> <span class="s">'ELSE'</span><span class="p">,</span> <span class="s">'FINALLY'</span><span class="p">].</span><span class="nx">concat</span> <span class="nx">EXPRESSION_END</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-41">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-41">¶</a>
|
|
</div>
|
|
|
|
<p>Tokens that, if followed by an <code>IMPLICIT_CALL</code>, indicate a function invocation.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre><span class="nv">IMPLICIT_FUNC = </span><span class="p">[</span><span class="s">'IDENTIFIER'</span><span class="p">,</span> <span class="s">'SUPER'</span><span class="p">,</span> <span class="s">')'</span><span class="p">,</span> <span class="s">'CALL_END'</span><span class="p">,</span> <span class="s">']'</span><span class="p">,</span> <span class="s">'INDEX_END'</span><span class="p">,</span> <span class="s">'@'</span><span class="p">,</span> <span class="s">'THIS'</span><span class="p">]</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-42">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-42">¶</a>
|
|
</div>
|
|
|
|
<p>If preceded by an <code>IMPLICIT_FUNC</code>, indicates a function invocation.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre><span class="nv">IMPLICIT_CALL = </span><span class="p">[</span>
|
|
<span class="s">'IDENTIFIER'</span><span class="p">,</span> <span class="s">'NUMBER'</span><span class="p">,</span> <span class="s">'STRING'</span><span class="p">,</span> <span class="s">'JS'</span><span class="p">,</span> <span class="s">'REGEX'</span><span class="p">,</span> <span class="s">'NEW'</span><span class="p">,</span> <span class="s">'PARAM_START'</span><span class="p">,</span> <span class="s">'CLASS'</span>
|
|
<span class="s">'IF'</span><span class="p">,</span> <span class="s">'TRY'</span><span class="p">,</span> <span class="s">'SWITCH'</span><span class="p">,</span> <span class="s">'THIS'</span><span class="p">,</span> <span class="s">'BOOL'</span><span class="p">,</span> <span class="s">'NULL'</span><span class="p">,</span> <span class="s">'UNDEFINED'</span><span class="p">,</span> <span class="s">'UNARY'</span><span class="p">,</span> <span class="s">'SUPER'</span>
|
|
<span class="s">'@'</span><span class="p">,</span> <span class="s">'->'</span><span class="p">,</span> <span class="s">'=>'</span><span class="p">,</span> <span class="s">'['</span><span class="p">,</span> <span class="s">'('</span><span class="p">,</span> <span class="s">'{'</span><span class="p">,</span> <span class="s">'--'</span><span class="p">,</span> <span class="s">'++'</span>
|
|
<span class="p">]</span>
|
|
|
|
<span class="nv">IMPLICIT_UNSPACED_CALL = </span><span class="p">[</span><span class="s">'+'</span><span class="p">,</span> <span class="s">'-'</span><span class="p">]</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-43">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-43">¶</a>
|
|
</div>
|
|
|
|
<p>Tokens indicating that the implicit call must enclose a block of expressions.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre><span class="nv">IMPLICIT_BLOCK = </span><span class="p">[</span><span class="s">'->'</span><span class="p">,</span> <span class="s">'=>'</span><span class="p">,</span> <span class="s">'{'</span><span class="p">,</span> <span class="s">'['</span><span class="p">,</span> <span class="s">','</span><span class="p">]</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-44">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-44">¶</a>
|
|
</div>
|
|
|
|
<p>Tokens that always mark the end of an implicit call for single-liners.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre><span class="nv">IMPLICIT_END = </span><span class="p">[</span><span class="s">'POST_IF'</span><span class="p">,</span> <span class="s">'FOR'</span><span class="p">,</span> <span class="s">'WHILE'</span><span class="p">,</span> <span class="s">'UNTIL'</span><span class="p">,</span> <span class="s">'WHEN'</span><span class="p">,</span> <span class="s">'BY'</span><span class="p">,</span>
|
|
<span class="s">'LOOP'</span><span class="p">,</span> <span class="s">'TERMINATOR'</span><span class="p">]</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-45">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-45">¶</a>
|
|
</div>
|
|
|
|
<p>Single-line flavors of block expressions that have unclosed endings.
|
|
The grammar can't disambiguate them, so we insert the implicit indentation.
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre><span class="nv">SINGLE_LINERS = </span><span class="p">[</span><span class="s">'ELSE'</span><span class="p">,</span> <span class="s">'->'</span><span class="p">,</span> <span class="s">'=>'</span><span class="p">,</span> <span class="s">'TRY'</span><span class="p">,</span> <span class="s">'FINALLY'</span><span class="p">,</span> <span class="s">'THEN'</span><span class="p">]</span>
|
|
<span class="nv">SINGLE_CLOSERS = </span><span class="p">[</span><span class="s">'TERMINATOR'</span><span class="p">,</span> <span class="s">'CATCH'</span><span class="p">,</span> <span class="s">'FINALLY'</span><span class="p">,</span> <span class="s">'ELSE'</span><span class="p">,</span> <span class="s">'OUTDENT'</span><span class="p">,</span> <span class="s">'LEADING_WHEN'</span><span class="p">]</span></pre></div></div>
|
|
|
|
</li>
|
|
|
|
|
|
<li id="section-46">
|
|
<div class="annotation">
|
|
<div class="pilwrap">
|
|
<a class="pilcrow" href="#section-46">¶</a>
|
|
</div>
|
|
|
|
<p>Tokens that end a line.
|
|
</p>
|
|
|
|
</div>
|
|
|
|
<div class="content"><div class="highlight"><pre><span class="nv">LINEBREAKS = </span><span class="p">[</span><span class="s">'TERMINATOR'</span><span class="p">,</span> <span class="s">'INDENT'</span><span class="p">,</span> <span class="s">'OUTDENT'</span><span class="p">]</span>
|
|
|
|
</pre></div></div>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
</div>
|
|
</body>
|
|
</html>
|