2010-05-04 23:31:28 -04:00
<!DOCTYPE html> < html > < head > < title > rewriter.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 = "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.coffee < / a > < / div > < / div > < / div > < table cellpadding = "0" cellspacing = "0" > < thead > < tr > < th class = "docs" > < h1 > rewriter.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 > The CoffeeScript language has a good deal of optional syntax, implicit syntax,
2010-03-16 23:18:54 -04:00
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, balance incorrect nestings, and generally clean things up.< / 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 exported variables for both Node.js and the browser.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "k" > if< / span > < span class = "nx" > process< / span > < span class = "o" > ?< / span >
2010-08-03 00:06:34 -04:00
< span class = "p" > {< / span > < span class = "nx" > helpers< / span > < span class = "p" > }< / span > < span class = "o" > =< / span > < span class = "nx" > require< / span > < span class = "p" > (< / span > < span class = "s1" > ' ./helpers' < / span > < span class = "p" > )< / span >
2010-03-09 23:53:21 -05:00
< span class = "k" > else< / span >
2010-08-04 23:14:34 -04:00
< span class = "k" > this< / span > < span class = "p" > .< / span > < span class = "nv" > exports = < / span > < span class = "k" > this< / span >
< span class = "nv" > helpers = < / span > < span class = "k" > this< / span > < span class = "p" > .< / span > < span class = "nx" > helpers< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-3" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-3" > #< / a > < / div > < p > Import the helpers we need.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "p" > {< / span > < span class = "nx" > include< / span > < span class = "p" > }< / span > < span class = "o" > =< / span > < span class = "nx" > helpers< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-4" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-4" > #< / 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 > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nv" > exports.Rewriter = < / span > < span class = "nx" > class< / span > < span class = "nx" > Rewriter< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-5" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-5" > #< / a > < / div > < p > Helpful snippet for debugging:
2010-08-03 00:06:34 -04:00
puts (t[0] + '/' + t[1] for t in @tokens).join ' '< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < / pre > < / div > < / td > < / tr > < tr id = "section-6" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-6" > #< / a > < / div > < p > Rewrite the token stream in multiple passes, one logical filter at
2010-03-06 23:48:06 -05:00
a time. This could certainly be changed into a single pass through the
2010-03-07 14:41:52 -05:00
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
2010-08-04 23:14:34 -04:00
corrected before implicit parentheses can be wrapped around blocks of code.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nx" > rewrite< / span > < span class = "o" > :< / span > < span class = "p" > (< / span > < span class = "nx" > tokens< / span > < span class = "p" > )< / span > < span class = "o" > -> < / span >
< span class = "vi" > @tokens = < / span > < span class = "nx" > tokens< / span >
2010-07-11 10:40:44 -04:00
< span class = "nx" > @adjustComments< / span > < span class = "p" > ()< / span >
2010-06-28 00:19:58 -04:00
< span class = "nx" > @removeLeadingNewlines< / span > < span class = "p" > ()< / span >
< span class = "nx" > @removeMidExpressionNewlines< / span > < span class = "p" > ()< / span >
2010-08-11 00:40:15 -04:00
< span class = "nx" > @closeOpenCalls< / span > < span class = "p" > ()< / span >
< span class = "nx" > @closeOpenIndexes< / span > < span class = "p" > ()< / span >
2010-06-28 00:19:58 -04:00
< span class = "nx" > @addImplicitIndentation< / span > < span class = "p" > ()< / span >
2010-08-03 00:06:34 -04:00
< span class = "nx" > @addImplicitBraces< / span > < span class = "p" > ()< / span >
2010-08-23 22:08:33 -04:00
< span class = "nx" > @tagPostfixConditionals< / span > < span class = "p" > ()< / span >
2010-06-28 00:19:58 -04:00
< span class = "nx" > @addImplicitParentheses< / span > < span class = "p" > ()< / span >
< span class = "nx" > @ensureBalance< / span > < span class = "nx" > BALANCED_PAIRS< / span >
< span class = "nx" > @rewriteClosingParens< / span > < span class = "p" > ()< / span >
2010-08-03 00:06:34 -04:00
< span class = "nx" > @tokens< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-7" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-7" > #< / a > < / div > < p > Rewrite the token stream, looking one token ahead and behind.
2010-03-06 23:48:06 -05:00
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
2010-03-07 14:41:52 -05:00
as tokens are inserted and removed, and the stream changes length under
2010-08-04 23:14:34 -04:00
our feet.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nx" > scanTokens< / span > < span class = "o" > :< / span > < span class = "p" > (< / span > < span class = "nx" > block< / span > < span class = "p" > )< / span > < span class = "o" > -> < / span >
< span class = "nv" > i = < / span > < span class = "mi" > 0< / span >
2010-06-28 00:19:58 -04:00
< span class = "nx" > loop< / span >
2010-04-03 12:01:46 -04:00
< span class = "k" > break< / span > < span class = "nx" > unless< / span > < span class = "nx" > @tokens< / span > < span class = "p" > [< / span > < span class = "nx" > i< / span > < span class = "p" > ]< / span >
2010-08-23 22:08:33 -04:00
< span class = "nv" > move = < / 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" > @tokens< / span > < span class = "p" > [< / span > < span class = "nx" > i< / span > < span class = "p" > ],< / span > < span class = "nx" > i< / span >
2010-08-03 00:06:34 -04:00
< span class = "nx" > i< / span > < span class = "o" > +=< / span > < span class = "nx" > move< / span >
2010-08-11 00:40:15 -04:00
< span class = "kc" > true< / span >
< span class = "nx" > detectEnd< / span > < span class = "o" > :< / span > < span class = "p" > (< / span > < span class = "nx" > i< / span > < span class = "p" > ,< / span > < span class = "nx" > condition< / span > < span class = "p" > ,< / span > < span class = "nx" > action< / span > < span class = "p" > )< / span > < span class = "o" > -> < / span >
< span class = "nv" > levels = < / span > < span class = "mi" > 0< / span >
< span class = "nx" > loop< / 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 = "nx" > levels< / span > < span class = "o" > +=< / span > < span class = "mi" > 1< / span > < span class = "k" > if< / span > < span class = "nx" > include< / span > < span class = "nx" > EXPRESSION_START< / 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 = "nx" > levels< / span > < span class = "o" > -=< / span > < span class = "mi" > 1< / span > < span class = "k" > if< / span > < span class = "nx" > include< / span > < span class = "nx" > EXPRESSION_END< / 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 = "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 > < / td > < / tr > < tr id = "section-8" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-8" > #< / a > < / div > < p > Massage newlines and indentations so that comments don't have to be
2010-08-04 23:14:34 -04:00
correctly indented, or appear on a line of their own.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nx" > adjustComments< / span > < span class = "o" > :< / span > < span class = "o" > -> < / span >
2010-08-23 22:08:33 -04:00
< span class = "nx" > @scanTokens< / 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 = "o" > -> < / span >
2010-07-11 10:40:44 -04:00
< span class = "k" > return< / span > < span class = "mi" > 1< / span > < span class = "nx" > 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 = "s1" > ' HERECOMMENT' < / span >
2010-08-11 00:40:15 -04:00
< span class = "p" > [< / span > < span class = "nx" > before< / span > < span class = "p" > ,< / span > < span class = "nx" > prev< / span > < span class = "p" > ,< / span > < span class = "nx" > post< / span > < span class = "p" > ,< / span > < span class = "nx" > after< / span > < span class = "p" > ]< / span > < span class = "o" > =< / span > < span class = "p" > [< / span > < span class = "nx" > @tokens< / 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 = "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" > @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" > @tokens< / span > < span class = "p" > [< / span > < span class = "nx" > i< / span > < span class = "o" > +< / span > < span class = "mi" > 2< / span > < span class = "p" > ]]< / span >
2010-07-11 10:40:44 -04:00
< span class = "k" > if< / span > < span class = "nx" > after< / span > < span class = "o" > and< / span > < span class = "nx" > after< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "o" > is< / span > < span class = "s1" > ' INDENT' < / 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" > 1< / span >
< span class = "k" > if< / span > < span class = "nx" > before< / span > < span class = "o" > and< / span > < span class = "nx" > before< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "o" > is< / span > < span class = "s1" > ' OUTDENT' < / span > < span class = "o" > and< / span > < span class = "nx" > post< / span > < span class = "o" > and< / span > < span class = "nx" > prev< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "o" > is< / span > < span class = "nx" > post< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "o" > is< / span > < span class = "s1" > ' TERMINATOR' < / 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" > 1< / span >
< span class = "k" > else< / 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" > after< / span >
< span class = "k" > else< / span > < span class = "k" > if< / span > < span class = "nx" > prev< / span > < span class = "o" > and< / span > < span class = "nx" > prev< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "o" > not< / span > < span class = "k" > in< / span > < span class = "p" > [< / span > < span class = "s1" > ' TERMINATOR' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' INDENT' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' OUTDENT' < / span > < span class = "p" > ]< / span >
< span class = "k" > if< / span > < span class = "nx" > post< / span > < span class = "o" > and< / span > < span class = "nx" > post< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "o" > is< / span > < span class = "s1" > ' TERMINATOR' < / span > < span class = "o" > and< / span > < span class = "nx" > after< / span > < span class = "o" > and< / span > < span class = "nx" > after< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "o" > is< / span > < span class = "s1" > ' OUTDENT' < / span >
2010-08-03 00:06:34 -04:00
< span class = "nx" > @tokens< / span > < span class = "p" > .< / span > < span class = "nx" > splice< / 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 = "mi" > 0< / span > < span class = "p" > ,< / span > < span class = "nx" > @tokens< / span > < span class = "p" > .< / span > < span class = "nx" > splice< / span > < span class = "p" > (< / span > < span class = "nx" > i< / span > < span class = "p" > ,< / span > < span class = "mi" > 2< / span > < span class = "p" > )...)< / span >
< span class = "k" > if< / span > < span class = "nx" > @tokens< / 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 = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "o" > isnt< / span > < span class = "s1" > ' TERMINATOR' < / 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 = "p" > [< / span > < span class = "s1" > ' TERMINATOR' < / span > < span class = "p" > ,< / span > < span class = "s2" > " \n" < / span > < span class = "p" > ,< / span > < span class = "nx" > prev< / span > < span class = "p" > [< / span > < span class = "mi" > 2< / span > < span class = "p" > ]]< / span >
2010-07-11 10:40:44 -04:00
< span class = "k" > else< / 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 = "p" > [< / span > < span class = "s1" > ' TERMINATOR' < / span > < span class = "p" > ,< / span > < span class = "s2" > " \n" < / span > < span class = "p" > ,< / span > < span class = "nx" > prev< / span > < span class = "p" > [< / span > < span class = "mi" > 2< / span > < span class = "p" > ]]< / span >
< span class = "k" > return< / span > < span class = "mi" > 2< / span >
2010-08-03 00:06:34 -04:00
< span class = "k" > return< / span > < span class = "mi" > 1< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-9" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-9" > #< / a > < / div > < p > Leading newlines would introduce an ambiguity in the grammar, so we
2010-08-04 23:14:34 -04:00
dispatch them here.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nx" > removeLeadingNewlines< / span > < span class = "o" > :< / span > < span class = "o" > -> < / span >
2010-08-03 00:06:34 -04:00
< span class = "nx" > @tokens< / span > < span class = "p" > .< / span > < span class = "nx" > shift< / span > < span class = "p" > ()< / span > < span class = "k" > while< / span > < span class = "nx" > @tokens< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "o" > and< / span > < span class = "nx" > @tokens< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ][< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "o" > is< / span > < span class = "s1" > ' TERMINATOR' < / span > < / pre > < / div > < / td > < / tr > < tr id = "section-10" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-10" > #< / a > < / div > < p > Some blocks occur in the middle of expressions -- when we're expecting
2010-08-04 23:14:34 -04:00
this, remove their trailing newlines.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nx" > removeMidExpressionNewlines< / span > < span class = "o" > :< / span > < span class = "o" > -> < / span >
2010-08-23 22:08:33 -04:00
< span class = "nx" > @scanTokens< / 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 = "o" > -> < / span >
2010-08-11 00:40:15 -04:00
< span class = "k" > return< / span > < span class = "mi" > 1< / span > < span class = "nx" > unless< / span > < span class = "nx" > include< / span > < span class = "p" > (< / span > < span class = "nx" > EXPRESSION_CLOSE< / span > < span class = "p" > ,< / 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" > and< / 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 = "s1" > ' TERMINATOR' < / span >
2010-04-03 12:01:46 -04:00
< 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 >
2010-08-11 00:40:15 -04:00
< span class = "k" > return< / span > < span class = "mi" > 0< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-11" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-11" > #< / a > < / div > < p > The lexer has tagged the opening parenthesis of a method call. Match it with
its paired close.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nx" > closeOpenCalls< / span > < span class = "o" > :< / span > < span class = "o" > -> < / span >
2010-08-23 22:08:33 -04:00
< span class = "nx" > @scanTokens< / 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 = "o" > -> < / span >
2010-08-11 00:40:15 -04:00
< 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 = "s1" > ' CALL_START' < / span >
< span class = "nv" > condition = < / 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 = "o" > -> < / 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 = "s1" > ' )' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' CALL_END' < / span > < span class = "p" > ]< / span >
< span class = "nv" > action = < / 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 = "o" > -> < / 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 = "s1" > ' CALL_END' < / 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" > return< / span > < span class = "mi" > 1< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-12" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-12" > #< / a > < / div > < p > The lexer has tagged the opening parenthesis of an indexing operation call.
Match it with its paired close.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nx" > closeOpenIndexes< / span > < span class = "o" > :< / span > < span class = "o" > -> < / span >
2010-08-23 22:08:33 -04:00
< span class = "nx" > @scanTokens< / 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 = "o" > -> < / span >
2010-08-11 00:40:15 -04:00
< 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 = "s1" > ' INDEX_START' < / span >
< span class = "nv" > condition = < / 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 = "o" > -> < / 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 = "s1" > ' ]' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' INDEX_END' < / span > < span class = "p" > ]< / span >
< span class = "nv" > action = < / 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 = "o" > -> < / 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 = "s1" > ' INDEX_END' < / 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" > return< / span > < span class = "mi" > 1< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-13" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-13" > #< / a > < / div > < p > Object literals may be written with implicit braces, for simple cases.
2010-08-04 23:14:34 -04:00
Insert the missing braces here, so that the parser doesn't have to.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nx" > addImplicitBraces< / span > < span class = "o" > :< / span > < span class = "o" > -> < / span >
2010-08-11 00:40:15 -04:00
< span class = "nv" > stack = < / span > < span class = "p" > []< / span >
2010-08-23 22:08:33 -04:00
< span class = "nx" > @scanTokens< / 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 = "o" > -> < / span >
2010-08-11 00:40:15 -04:00
< span class = "k" > if< / span > < span class = "nx" > include< / span > < span class = "nx" > EXPRESSION_START< / 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 = "nx" > stack< / span > < span class = "p" > .< / span > < span class = "nx" > push< / span > < span class = "p" > (< / span > < span class = "k" > if< / 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 = "s1" > ' INDENT' < / 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 = "o" > -< / span > < span class = "mi" > 1< / span > < span class = "p" > )< / span > < span class = "o" > is< / span > < span class = "s1" > ' {' < / span > < span class = "p" > ))< / span > < span class = "k" > then< / span > < span class = "s1" > ' {' < / span > < span class = "k" > else< / span > < span class = "nx" > token< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ])< / span >
< span class = "k" > if< / span > < span class = "nx" > include< / span > < span class = "nx" > EXPRESSION_END< / 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 = "nx" > stack< / span > < span class = "p" > .< / span > < span class = "nx" > pop< / span > < span class = "p" > ()< / span >
< span class = "nv" > last = < / 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 = "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 = "s1" > ' :' < / span > < span class = "o" > and< / span > < span class = "p" > (< / span > < span class = "o" > not< / span > < span class = "nx" > last< / span > < span class = "o" > or< / span > < span class = "nx" > last< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "o" > isnt< / span > < span class = "s1" > ' {' < / span > < span class = "p" > )< / span >
< span class = "nx" > stack< / span > < span class = "p" > .< / span > < span class = "nx" > push< / span > < span class = "s1" > ' {' < / span >
< span class = "nv" > idx = < / 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" > 2< / span > < span class = "p" > )< / span > < span class = "o" > is< / span > < span class = "s1" > ' @' < / span > < span class = "k" > then< / span > < span class = "nx" > i< / span > < span class = "o" > -< / span > < span class = "mi" > 2< / span > < span class = "k" > else< / span > < span class = "nx" > i< / span > < span class = "o" > -< / span > < span class = "mi" > 1< / span >
2010-08-23 22:08:33 -04:00
< span class = "nv" > tok = < / span > < span class = "p" > [< / span > < span class = "s1" > ' {' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' {' < / span > < span class = "p" > ,< / span > < span class = "nx" > token< / span > < span class = "p" > [< / span > < span class = "mi" > 2< / span > < span class = "p" > ]]< / span >
< span class = "nv" > tok.generated = < / span > < span class = "kc" > yes< / 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" > tok< / span >
2010-08-11 00:40:15 -04:00
< span class = "nv" > condition = < / 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 = "o" > -> < / span >
< span class = "p" > [< / span > < span class = "nx" > one< / span > < span class = "p" > ,< / span > < span class = "nx" > two< / span > < span class = "p" > ,< / span > < span class = "nx" > three< / span > < span class = "p" > ]< / span > < span class = "o" > =< / span > < span class = "nx" > @tokens< / span > < span class = "p" > .< / span > < span class = "nx" > slice< / 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" > i< / span > < span class = "o" > +< / span > < span class = "mi" > 4< / span > < span class = "p" > )< / span >
< span class = "k" > return< / span > < span class = "kc" > false< / span > < span class = "k" > if< / span > < span class = "s1" > ' HERECOMMENT' < / span > < span class = "k" > in< / span > < span class = "p" > [< / 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 = "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 = "p" > ((< / 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 = "s1" > ' TERMINATOR' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' OUTDENT' < / span > < span class = "p" > ])< / span > < span class = "o" > and< / span > < span class = "o" > not< / span > < span class = "p" > ((< / span > < span class = "nx" > two< / span > < span class = "o" > and< / span > < span class = "nx" > two< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "o" > is< / span > < span class = "s1" > ' :' < / span > < span class = "p" > )< / span > < span class = "o" > or< / span > < span class = "p" > (< / span > < span class = "nx" > one< / span > < span class = "o" > and< / span > < span class = "nx" > one< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "o" > is< / span > < span class = "s1" > ' @' < / span > < span class = "o" > and< / span > < span class = "nx" > three< / span > < span class = "o" > and< / span > < span class = "nx" > three< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "o" > is< / span > < span class = "s1" > ' :' < / span > < span class = "p" > )))< / span > < span class = "o" > or< / 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 = "s1" > ' ,' < / span > < span class = "o" > and< / span > < span class = "nx" > one< / span > < span class = "o" > and< / span > < span class = "p" > (< / span > < span class = "nx" > one< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "o" > not< / span > < span class = "k" > in< / span > < span class = "p" > [< / span > < span class = "s1" > ' IDENTIFIER' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' STRING' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' @' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' TERMINATOR' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' OUTDENT' < / span > < span class = "p" > ]))< / span >
< span class = "nv" > action = < / 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 = "o" > -> < / 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 = "p" > [< / span > < span class = "s1" > ' }' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' }' < / span > < span class = "p" > ,< / span > < span class = "nx" > token< / span > < span class = "p" > [< / span > < span class = "mi" > 2< / span > < span class = "p" > ]]< / 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 >
2010-08-03 00:06:34 -04:00
< span class = "k" > return< / span > < span class = "mi" > 2< / span >
2010-08-11 00:40:15 -04:00
< span class = "k" > return< / span > < span class = "mi" > 1< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-14" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-14" > #< / a > < / div > < p > Methods may be optionally called without parentheses, for simple cases.
2010-03-06 23:48:06 -05:00
Insert the implicit parentheses here, so that the parser doesn't have to
2010-08-04 23:14:34 -04:00
deal with them.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nx" > addImplicitParentheses< / span > < span class = "o" > :< / span > < span class = "o" > -> < / span >
2010-08-23 22:08:33 -04:00
< span class = "nv" > classLine = < / span > < span class = "kc" > no< / span >
< span class = "nx" > @scanTokens< / 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 = "o" > -> < / span >
< span class = "nv" > classLine = < / span > < span class = "kc" > yes< / 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 = "s1" > ' CLASS' < / span >
< span class = "nv" > prev = < / 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 = "nv" > next = < / 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 = "nv" > idx = < / span > < span class = "mi" > 1< / span >
< span class = "nv" > callObject = < / span > < span class = "o" > not< / span > < span class = "nx" > classLine< / 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 = "o" > is< / span > < span class = "s1" > ' INDENT' < / span > < span class = "o" > and< / span > < span class = "nx" > next< / span > < span class = "o" > and< / span > < span class = "nx" > next< / span > < span class = "p" > .< / span > < span class = "nx" > generated< / span > < span class = "o" > and< / span > < span class = "nx" > next< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "o" > is< / span > < span class = "s1" > ' {' < / span > < span class = "o" > and< / span > < span class = "nx" > prev< / span > < span class = "o" > and< / span > < span class = "nx" > include< / span > < span class = "p" > (< / span > < span class = "nx" > IMPLICIT_FUNC< / span > < span class = "p" > ,< / span > < span class = "nx" > prev< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ])< / span >
< span class = "nv" > idx = < / span > < span class = "mi" > 2< / span > < span class = "k" > if< / span > < span class = "nx" > callObject< / span >
< span class = "nv" > classLine = < / span > < span class = "kc" > no< / span > < span class = "k" > if< / span > < span class = "nx" > include< / span > < span class = "p" > (< / span > < span class = "nx" > LINEBREAKS< / 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 = "k" > if< / span > < span class = "nx" > prev< / span > < span class = "o" > and< / span > < span class = "p" > (< / span > < span class = "nx" > prev< / span > < span class = "p" > .< / span > < span class = "nx" > spaced< / span > < span class = "o" > and< / span > < span class = "nx" > include< / span > < span class = "p" > (< / span > < span class = "nx" > IMPLICIT_FUNC< / span > < span class = "p" > ,< / span > < span class = "nx" > prev< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ])< / span > < span class = "o" > and< / span > < span class = "nx" > include< / span > < span class = "p" > (< / span > < span class = "nx" > IMPLICIT_CALL< / 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" > 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 = "s1" > ' UNARY' < / 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 = "o" > +< / span > < span class = "mi" > 1< / span > < span class = "p" > )< / span > < span class = "k" > in< / span > < span class = "p" > [< / span > < span class = "s1" > ' IN' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' OF' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' INSTANCEOF' < / span > < span class = "p" > ])))< / span > < span class = "o" > or< / span > < span class = "nx" > callObject< / span >
2010-05-04 23:31:28 -04:00
< 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 = "p" > [< / span > < span class = "s1" > ' CALL_START' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' (' < / span > < span class = "p" > ,< / span > < span class = "nx" > token< / span > < span class = "p" > [< / span > < span class = "mi" > 2< / span > < span class = "p" > ]]< / span >
2010-08-11 00:40:15 -04:00
< span class = "nv" > condition = < / 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 = "o" > -> < / span >
< span class = "p" > (< / span > < span class = "o" > not< / span > < span class = "nx" > token< / span > < span class = "p" > .< / span > < span class = "nx" > generated< / span > < span class = "o" > and< / 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 = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "o" > isnt< / span > < span class = "s1" > ' ,' < / span > < span class = "o" > and< / span > < span class = "nx" > include< / span > < span class = "p" > (< / span > < span class = "nx" > IMPLICIT_END< / 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" > 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 = "s1" > ' INDENT' < / span > < span class = "o" > and< / span > < span class = "p" > (< / span > < span class = "nx" > include< / span > < span class = "p" > (< / span > < span class = "nx" > IMPLICIT_BLOCK< / span > < span class = "p" > ,< / 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" > or< / 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 = "s1" > ' CLASS' < / 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 = "s1" > ' PROPERTY_ACCESS' < / 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 = "s1" > ' OUTDENT' < / span >
< span class = "nv" > action = < / 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 = "o" > -> < / span >
< span class = "nv" > idx = < / 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 = "s1" > ' 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 = "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 = "p" > [< / span > < span class = "s1" > ' CALL_END' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' )' < / span > < span class = "p" > ,< / span > < span class = "nx" > token< / span > < span class = "p" > [< / span > < span class = "mi" > 2< / span > < span class = "p" > ]]< / span >
2010-08-23 22:08:33 -04:00
< span class = "nx" > @detectEnd< / span > < span class = "nx" > i< / span > < span class = "o" > +< / span > < span class = "nx" > idx< / span > < span class = "p" > ,< / span > < span class = "nx" > condition< / span > < span class = "p" > ,< / span > < span class = "nx" > action< / span >
2010-05-04 23:31:28 -04:00
< span class = "k" > return< / span > < span class = "mi" > 2< / span >
2010-08-11 00:40:15 -04:00
< span class = "k" > return< / span > < span class = "mi" > 1< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-15" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-15" > #< / a > < / div > < p > Because our grammar is LALR(1), it can't handle some single-line
2010-03-07 14:41:52 -05:00
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,
2010-08-04 23:14:34 -04:00
but we need to make sure it's balanced.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nx" > addImplicitIndentation< / span > < span class = "o" > :< / span > < span class = "o" > -> < / span >
2010-08-23 22:08:33 -04:00
< span class = "nx" > @scanTokens< / 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 = "o" > -> < / span >
2010-08-11 00:40:15 -04:00
< 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 = "s1" > ' 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 = "s1" > ' OUTDENT' < / span >
2010-07-11 10:40:44 -04:00
< 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 = "nx" > token< / span > < span class = "p" > )...< / span >
2010-06-28 00:19:58 -04:00
< span class = "k" > return< / span > < span class = "mi" > 2< / span >
2010-08-03 00:06:34 -04:00
< 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 = "s1" > ' CATCH' < / span > < span class = "o" > and< / span >
2010-08-23 22:08:33 -04:00
< span class = "p" > (< / 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 = "s1" > ' TERMINATOR' < / span > < span class = "o" > or< / 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 = "s1" > ' FINALLY' < / span > < span class = "p" > )< / span >
2010-07-11 10:40:44 -04:00
< 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 = "nx" > token< / span > < span class = "p" > )...< / span >
< span class = "k" > return< / span > < span class = "mi" > 4< / span >
2010-08-11 00:40:15 -04:00
< span class = "k" > if< / span > < span class = "nx" > include< / span > < span class = "p" > (< / span > < span class = "nx" > SINGLE_LINERS< / 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" > 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 = "s1" > ' INDENT' < / 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 = "s1" > ' 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 = "s1" > ' IF' < / span > < span class = "p" > )< / span >
< span class = "nv" > starter = < / span > < span class = "nx" > token< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / 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 = "nx" > token< / span >
< span class = "nv" > indent.generated = outdent.generated = < / span > < span class = "kc" > true< / 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 = "nv" > condition = < / 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 = "o" > -> < / span >
< span class = "p" > (< / span > < span class = "nx" > include< / span > < span class = "p" > (< / span > < span class = "nx" > SINGLE_CLOSERS< / 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" > and< / 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 = "s1" > ' ;' < / span > < span class = "p" > )< / 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 = "s1" > ' 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 = "s1" > ' IF' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' THEN' < / span > < span class = "p" > ])< / span >
< span class = "nv" > action = < / 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 = "o" > -> < / span >
< span class = "nv" > idx = < / span > < span class = "k" > if< / 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 = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "o" > is< / span > < span class = "s1" > ' ,' < / 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 = "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" > outdent< / 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" > token< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "o" > is< / span > < span class = "s1" > ' THEN' < / span >
< span class = "k" > return< / span > < span class = "mi" > 2< / span >
2010-08-23 22:08:33 -04:00
< span class = "k" > return< / span > < span class = "mi" > 1< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-16" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-16" > #< / a > < / div > < p > Tag postfix conditionals as such, so that we can parse them with a
different precedence.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nx" > tagPostfixConditionals< / span > < span class = "o" > :< / span > < span class = "o" > -> < / span >
< span class = "nx" > @scanTokens< / 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 = "o" > -> < / 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 = "p" > [< / span > < span class = "s1" > ' IF' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' UNLESS' < / span > < span class = "p" > ]< / span >
< span class = "nv" > original = < / span > < span class = "nx" > token< / span >
< span class = "nv" > condition = < / 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 = "o" > -> < / 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 = "s1" > ' TERMINATOR' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' INDENT' < / span > < span class = "p" > ]< / span >
< span class = "nv" > action = < / 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 = "o" > -> < / 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 = "s1" > ' 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 = "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 = "s1" > ' INDENT' < / 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" > return< / span > < span class = "mi" > 1< / span >
< span class = "k" > return< / span > < span class = "mi" > 1< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-17" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-17" > #< / a > < / div > < p > Ensure that all listed pairs of tokens are correctly balanced throughout
2010-08-04 23:14:34 -04:00
the course of the token stream.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nx" > ensureBalance< / span > < span class = "o" > :< / span > < span class = "p" > (< / span > < span class = "nx" > pairs< / span > < span class = "p" > )< / span > < span class = "o" > -> < / span >
< span class = "nv" > levels = < / span > < span class = "p" > {}< / span >
< span class = "nv" > openLine = < / span > < span class = "p" > {}< / span >
2010-08-23 22:08:33 -04:00
< span class = "nx" > @scanTokens< / 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 = "o" > -> < / span >
2010-03-06 23:48:06 -05:00
< span class = "k" > for< / span > < span class = "nx" > pair< / span > < span class = "k" > in< / span > < span class = "nx" > pairs< / span >
2010-08-03 00:06:34 -04:00
< span class = "p" > [< / span > < span class = "nx" > open< / span > < span class = "p" > ,< / span > < span class = "nx" > close< / span > < span class = "p" > ]< / span > < span class = "o" > =< / span > < span class = "nx" > pair< / span >
< span class = "nx" > levels< / span > < span class = "p" > [< / span > < span class = "nx" > open< / span > < span class = "p" > ]< / span > < span class = "o" > or=< / span > < span class = "mi" > 0< / span >
2010-03-16 23:18:54 -04:00
< 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 = "nx" > open< / span >
2010-08-03 00:06:34 -04:00
< span class = "nx" > openLine< / span > < span class = "p" > [< / span > < span class = "nx" > open< / span > < span class = "p" > ]< / span > < span class = "o" > =< / span > < span class = "nx" > token< / span > < span class = "p" > [< / span > < span class = "mi" > 2< / span > < span class = "p" > ]< / span > < span class = "k" > if< / span > < span class = "nx" > levels< / span > < span class = "p" > [< / span > < span class = "nx" > open< / span > < span class = "p" > ]< / span > < span class = "o" > ==< / span > < span class = "mi" > 0< / span >
< span class = "nx" > levels< / span > < span class = "p" > [< / span > < span class = "nx" > open< / span > < span class = "p" > ]< / span > < span class = "o" > +=< / span > < span class = "mi" > 1< / span >
< span class = "nx" > levels< / span > < span class = "p" > [< / span > < span class = "nx" > open< / span > < span class = "p" > ]< / span > < span class = "o" > -=< / span > < span class = "mi" > 1< / 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 = "nx" > close< / span >
< span class = "k" > throw< / span > < span class = "k" > new< / span > < span class = "nb" > Error< / span > < span class = "p" > (< / span > < span class = "s2" > " too many #{token[1]} on line #{token[2] + 1}" < / span > < span class = "p" > )< / span > < span class = "k" > if< / span > < span class = "nx" > levels< / span > < span class = "p" > [< / span > < span class = "nx" > open< / span > < span class = "p" > ]< / span > < span class = "o" > < < / span > < span class = "mi" > 0< / span >
2010-03-06 23:48:06 -05:00
< span class = "k" > return< / span > < span class = "mi" > 1< / span >
2010-08-04 23:14:34 -04:00
< span class = "nv" > unclosed = < / span > < span class = "nx" > key< / span > < span class = "k" > for< / span > < span class = "nx" > key< / span > < span class = "p" > ,< / span > < span class = "nx" > value< / span > < span class = "k" > of< / span > < span class = "nx" > levels< / span > < span class = "k" > when< / span > < span class = "nx" > value< / span > < span class = "o" > > < / span > < span class = "mi" > 0< / span >
2010-03-16 23:18:54 -04:00
< span class = "k" > if< / span > < span class = "nx" > unclosed< / span > < span class = "p" > .< / span > < span class = "nx" > length< / span >
2010-08-04 23:14:34 -04:00
< span class = "nv" > open = < / span > < span class = "nx" > unclosed< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span >
< span class = "nv" > line = < / span > < span class = "nx" > openLine< / span > < span class = "p" > [< / span > < span class = "nx" > open< / span > < span class = "p" > ]< / span > < span class = "o" > +< / span > < span class = "mi" > 1< / span >
2010-08-23 22:08:33 -04:00
< span class = "k" > throw< / span > < span class = "k" > new< / span > < span class = "nb" > Error< / span > < span class = "s2" > " unclosed #{open} on line #{line}" < / span > < / pre > < / div > < / td > < / tr > < tr id = "section-18" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-18" > #< / a > < / div > < p > We'd like to support syntax like this:< / p >
2010-03-07 14:41:52 -05:00
< pre > < code > el.click((event) ->
el.hide())
< / code > < / pre >
< p > In order to accomplish this, move outdents that follow closing parens
2010-03-06 23:48:06 -05:00
inwards, safely. The steps to accomplish this are:< / p >
< ol >
< li > Check that all paired tokens are balanced and in order.< / li >
2010-03-29 21:22:12 -04:00
< li > Rewrite the stream with a stack: if you see an < code > EXPRESSION_START< / code > , add it
to the stack. If you see an < code > EXPRESSION_END< / code > , pop the stack and replace
2010-03-06 23:48:06 -05:00
it with the inverse of what we've just popped.< / li >
2010-03-29 21:22:12 -04:00
< li > Keep track of "debt" for tokens that we manufacture, to make sure we end
2010-03-06 23:48:06 -05:00
up balanced in the end.< / li >
2010-05-04 23:31:28 -04:00
< li > Be careful not to alter array or parentheses delimiters with overzealous
rewriting.< / li >
2010-08-04 23:14:34 -04:00
< / ol > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nx" > rewriteClosingParens< / span > < span class = "o" > :< / span > < span class = "o" > -> < / span >
< span class = "nv" > stack = < / span > < span class = "p" > []< / span >
< span class = "nv" > debt = < / span > < span class = "p" > {}< / span >
2010-08-03 00:06:34 -04:00
< span class = "p" > (< / span > < span class = "nx" > debt< / span > < span class = "p" > [< / span > < span class = "nx" > key< / span > < span class = "p" > ]< / span > < span class = "o" > =< / span > < span class = "mi" > 0< / 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" > INVERSES< / span >
2010-08-23 22:08:33 -04:00
< span class = "nx" > @scanTokens< / 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 = "o" > -> < / span >
2010-08-04 23:14:34 -04:00
< 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 = "nv" > inv = < / span > < span class = "nx" > INVERSES< / span > < span class = "p" > [< / span > < span class = "nx" > token< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]]< / span >
2010-03-07 14:41:52 -05:00
< span class = "k" > if< / span > < span class = "nx" > include< / span > < span class = "nx" > EXPRESSION_START< / span > < span class = "p" > ,< / span > < span class = "nx" > tag< / span >
< span class = "nx" > stack< / span > < span class = "p" > .< / span > < span class = "nx" > push< / span > < span class = "nx" > token< / span >
< span class = "k" > return< / span > < span class = "mi" > 1< / span >
< span class = "k" > else< / span > < span class = "k" > if< / span > < span class = "nx" > include< / span > < span class = "nx" > EXPRESSION_END< / span > < span class = "p" > ,< / span > < span class = "nx" > tag< / span >
< span class = "k" > if< / span > < span class = "nx" > debt< / span > < span class = "p" > [< / span > < span class = "nx" > inv< / span > < span class = "p" > ]< / span > < span class = "o" > > < / span > < span class = "mi" > 0< / span >
2010-08-03 00:06:34 -04:00
< span class = "nx" > debt< / span > < span class = "p" > [< / span > < span class = "nx" > inv< / span > < span class = "p" > ]< / span > < span class = "o" > -=< / span > < span class = "mi" > 1< / span >
2010-04-03 12:01:46 -04:00
< 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 >
2010-03-06 23:48:06 -05:00
< span class = "k" > return< / span > < span class = "mi" > 0< / span >
2010-03-07 14:41:52 -05:00
< span class = "k" > else< / span >
2010-08-04 23:14:34 -04:00
< span class = "nv" > match = < / span > < span class = "nx" > stack< / span > < span class = "p" > .< / span > < span class = "nx" > pop< / span > < span class = "p" > ()< / span >
< span class = "nv" > mtag = < / span > < span class = "nx" > match< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span >
< span class = "nv" > oppos = < / span > < span class = "nx" > INVERSES< / span > < span class = "p" > [< / span > < span class = "nx" > mtag< / span > < span class = "p" > ]< / span >
2010-05-04 23:31:28 -04:00
< span class = "k" > return< / span > < span class = "mi" > 1< / span > < span class = "k" > if< / span > < span class = "nx" > tag< / span > < span class = "o" > is< / span > < span class = "nx" > oppos< / span >
2010-08-03 00:06:34 -04:00
< span class = "nx" > debt< / span > < span class = "p" > [< / span > < span class = "nx" > mtag< / span > < span class = "p" > ]< / span > < span class = "o" > +=< / span > < span class = "mi" > 1< / span >
2010-08-04 23:14:34 -04:00
< span class = "nv" > val = < / span > < span class = "p" > [< / span > < span class = "nx" > oppos< / span > < span class = "p" > ,< / span > < span class = "k" > if< / span > < span class = "nx" > mtag< / span > < span class = "o" > is< / span > < span class = "s1" > ' INDENT' < / span > < span class = "k" > then< / span > < span class = "nx" > match< / span > < span class = "p" > [< / span > < span class = "mi" > 1< / span > < span class = "p" > ]< / span > < span class = "k" > else< / span > < span class = "nx" > oppos< / span > < span class = "p" > ]< / span >
2010-05-04 23:31:28 -04:00
< span class = "k" > if< / span > < span class = "nx" > @tokens< / 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" > ?< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "o" > is< / span > < span class = "nx" > mtag< / 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" > 3< / span > < span class = "p" > ,< / span > < span class = "mi" > 0< / span > < span class = "p" > ,< / span > < span class = "nx" > val< / span >
< span class = "nx" > stack< / span > < span class = "p" > .< / span > < span class = "nx" > push< / span > < span class = "p" > (< / span > < span class = "nx" > match< / span > < span class = "p" > )< / span >
< span class = "k" > else< / 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" > val< / span >
2010-03-07 14:41:52 -05:00
< span class = "k" > return< / span > < span class = "mi" > 1< / span >
2010-03-06 23:48:06 -05:00
< span class = "k" > else< / span >
2010-08-23 22:08:33 -04:00
< span class = "k" > return< / span > < span class = "mi" > 1< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-19" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-19" > #< / a > < / div > < p > Generate the indentation tokens, based on another token on the same line.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nx" > indentation< / span > < span class = "o" > :< / span > < span class = "p" > (< / span > < span class = "nx" > token< / span > < span class = "p" > )< / span > < span class = "o" > -> < / span >
< span class = "p" > [[< / span > < span class = "s1" > ' INDENT' < / span > < span class = "p" > ,< / span > < span class = "mi" > 2< / span > < span class = "p" > ,< / span > < span class = "nx" > token< / span > < span class = "p" > [< / span > < span class = "mi" > 2< / span > < span class = "p" > ]],< / span > < span class = "p" > [< / span > < span class = "s1" > ' OUTDENT' < / span > < span class = "p" > ,< / span > < span class = "mi" > 2< / span > < span class = "p" > ,< / span > < span class = "nx" > token< / span > < span class = "p" > [< / span > < span class = "mi" > 2< / span > < span class = "p" > ]]]< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-20" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-20" > #< / a > < / div > < p > Look up a tag by token index.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nx" > tag< / span > < span class = "o" > :< / span > < span class = "p" > (< / span > < span class = "nx" > i< / span > < span class = "p" > )< / span > < span class = "o" > -> < / span >
< span class = "nx" > @tokens< / span > < span class = "p" > [< / span > < span class = "nx" > i< / span > < span class = "p" > ]< / span > < span class = "o" > and< / span > < span class = "nx" > @tokens< / span > < span class = "p" > [< / span > < span class = "nx" > i< / span > < span class = "p" > ][< / span > < span class = "mi" > 0< / 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 > < h2 > Constants< / h2 > < / td > < td class = "code" > < div class = "highlight" > < pre > < / pre > < / div > < / td > < / tr > < tr id = "section-22" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-22" > #< / a > < / div > < p > List of the token pairs that must be balanced.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nv" > BALANCED_PAIRS = < / span > < span class = "p" > [[< / span > < span class = "s1" > ' (' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' )' < / span > < span class = "p" > ],< / span > < span class = "p" > [< / span > < span class = "s1" > ' [' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' ]' < / span > < span class = "p" > ],< / span > < span class = "p" > [< / span > < span class = "s1" > ' {' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' }' < / span > < span class = "p" > ],< / span > < span class = "p" > [< / span > < span class = "s1" > ' INDENT' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' OUTDENT' < / span > < span class = "p" > ],< / span >
< span class = "p" > [< / span > < span class = "s1" > ' PARAM_START' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' PARAM_END' < / span > < span class = "p" > ],< / span > < span class = "p" > [< / span > < span class = "s1" > ' CALL_START' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' CALL_END' < / span > < span class = "p" > ],< / span > < span class = "p" > [< / span > < span class = "s1" > ' INDEX_START' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' INDEX_END' < / span > < span class = "p" > ]]< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-23" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-23" > #< / a > < / div > < p > The inverse mappings of < code > BALANCED_PAIRS< / code > we're trying to fix up, so we can
2010-08-04 23:14:34 -04:00
look things up from either end.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nv" > INVERSES = < / span > < span class = "p" > {}< / span >
2010-03-07 14:41:52 -05:00
< span class = "k" > for< / span > < span class = "nx" > pair< / span > < span class = "k" > in< / span > < span class = "nx" > BALANCED_PAIRS< / span >
2010-08-03 00:06:34 -04:00
< span class = "nx" > INVERSES< / span > < span class = "p" > [< / span > < span class = "nx" > pair< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]]< / span > < span class = "o" > =< / span > < span class = "nx" > pair< / span > < span class = "p" > [< / span > < span class = "mi" > 1< / span > < span class = "p" > ]< / span >
2010-08-23 22:08:33 -04:00
< span class = "nx" > INVERSES< / span > < span class = "p" > [< / span > < span class = "nx" > pair< / span > < span class = "p" > [< / span > < span class = "mi" > 1< / span > < span class = "p" > ]]< / span > < span class = "o" > =< / span > < span class = "nx" > pair< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-24" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-24" > #< / a > < / div > < p > The tokens that signal the start of a balanced pair.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nv" > EXPRESSION_START = < / span > < span class = "nx" > pair< / span > < span class = "p" > [< / span > < span class = "mi" > 0< / span > < span class = "p" > ]< / span > < span class = "k" > for< / span > < span class = "nx" > pair< / span > < span class = "k" > in< / span > < span class = "nx" > BALANCED_PAIRS< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-25" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-25" > #< / a > < / div > < p > The tokens that signal the end of a balanced pair.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nv" > EXPRESSION_END = < / span > < span class = "nx" > pair< / span > < span class = "p" > [< / span > < span class = "mi" > 1< / span > < span class = "p" > ]< / span > < span class = "k" > for< / span > < span class = "nx" > pair< / span > < span class = "k" > in< / span > < span class = "nx" > BALANCED_PAIRS< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-26" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-26" > #< / a > < / div > < p > Tokens that indicate the close of a clause of an expression.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nv" > EXPRESSION_CLOSE = < / span > < span class = "p" > [< / span > < span class = "s1" > ' CATCH' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' WHEN' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' ELSE' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' FINALLY' < / span > < span class = "p" > ].< / span > < span class = "nx" > concat< / span > < span class = "nx" > EXPRESSION_END< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-27" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-27" > #< / a > < / div > < p > Tokens that, if followed by an < code > IMPLICIT_CALL< / code > , indicate a function invocation.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nv" > IMPLICIT_FUNC = < / span > < span class = "p" > [< / span > < span class = "s1" > ' IDENTIFIER' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' SUPER' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' )' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' CALL_END' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' ]' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' INDEX_END' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' @' < / span > < span class = "p" > ]< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-28" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-28" > #< / a > < / div > < p > If preceded by an < code > IMPLICIT_FUNC< / code > , indicates a function invocation.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nv" > IMPLICIT_CALL = < / span > < span class = "p" > [< / span >
2010-08-03 00:06:34 -04:00
< span class = "s1" > ' IDENTIFIER' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' NUMBER' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' STRING' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' JS' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' REGEX' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' NEW' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' PARAM_START' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' CLASS' < / span > < span class = "p" > ,< / span >
2010-08-23 22:08:33 -04:00
< span class = "s1" > ' IF' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' UNLESS' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' TRY' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' SWITCH' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' THIS' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' NULL' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' UNARY' < / span >
2010-08-03 00:06:34 -04:00
< span class = "s1" > ' TRUE' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' FALSE' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' YES' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' NO' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' ON' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' OFF' < / span > < span class = "p" > ,< / span >
2010-08-23 22:08:33 -04:00
< 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-29" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-29" > #< / a > < / div > < p > Tokens indicating that the implicit call must enclose a block of expressions.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nv" > IMPLICIT_BLOCK = < / 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-30" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-30" > #< / a > < / div > < p > Tokens that always mark the end of an implicit call for single-liners.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nv" > IMPLICIT_END = < / span > < span class = "p" > [< / span > < span class = "s1" > ' POST_IF' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' POST_UNLESS' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' FOR' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' WHILE' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' UNTIL' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' LOOP' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' TERMINATOR' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' INDENT' < / span > < span class = "p" > ]< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-31" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-31" > #< / a > < / div > < p > Single-line flavors of block expressions that have unclosed endings.
2010-08-04 23:14:34 -04:00
The grammar can't disambiguate them, so we insert the implicit indentation.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nv" > SINGLE_LINERS = < / span > < span class = "p" > [< / span > < span class = "s1" > ' ELSE' < / span > < span class = "p" > ,< / span > < span class = "s2" > " -> " < / span > < span class = "p" > ,< / span > < span class = "s2" > " => " < / span > < span class = "p" > ,< / span > < span class = "s1" > ' TRY' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' FINALLY' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' THEN' < / span > < span class = "p" > ]< / span >
2010-08-23 22:08:33 -04:00
< span class = "nv" > SINGLE_CLOSERS = < / span > < span class = "p" > [< / span > < span class = "s1" > ' TERMINATOR' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' CATCH' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' FINALLY' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' ELSE' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' OUTDENT' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' LEADING_WHEN' < / span > < span class = "p" > ]< / span > < / pre > < / div > < / td > < / tr > < tr id = "section-32" > < td class = "docs" > < div class = "octowrap" > < a class = "octothorpe" href = "#section-32" > #< / a > < / div > < p > Tokens that end a line.< / p > < / td > < td class = "code" > < div class = "highlight" > < pre > < span class = "nv" > LINEBREAKS = < / span > < span class = "p" > [< / span > < span class = "s1" > ' TERMINATOR' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' INDENT' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' OUTDENT' < / span > < span class = "p" > ]< / span >
2010-03-06 23:48:06 -05:00
< / pre > < / div > < / td > < / tr > < / tbody > < / table > < / div > < / body > < / html >