2013-03-10 23:37:22 -04:00
<!DOCTYPE html>
< html >
< head >
< title > nodes.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" >
2014-08-26 12:24:29 -04:00
< div id = "jump_page_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 = "register.html" >
register.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.litcoffee
< / a >
< / div >
2013-03-10 23:37:22 -04:00
< / div >
< / li >
< / ul >
2013-03-18 01:06:33 -04:00
< ul class = "sections" >
< li id = "title" >
< div class = "annotation" >
< h1 > nodes.coffee< / h1 >
< / div >
< / li >
2013-03-10 23:37:22 -04:00
< li id = "section-1" >
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2013-03-10 23:37:22 -04:00
< a class = "pilcrow" href = "#section-1" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2013-03-10 23:37:22 -04:00
< p > < code > nodes.coffee< / code > contains all of the node classes for the syntax tree. Most
2010-03-07 16:41:06 -05:00
nodes are created as the result of actions in the < a href = "grammar.html" > grammar< / a > ,
but some are created by other nodes as a method of code generation. To convert
2014-01-29 23:54:00 -05:00
the syntax tree into a string of JavaScript code, call < code > compile()< / code > on the root.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2014-08-23 10:08:39 -04:00
< div class = "content" > < div class = 'highlight' > < pre >
Error.stackTraceLimit = Infinity
2013-03-04 14:19:08 -05:00
2014-01-29 23:54:00 -05:00
{Scope} = < span class = "hljs-built_in" > require< / span > < span class = "hljs-string" > './scope'< / span >
2016-09-22 16:19:43 -04:00
{isUnassignable, JS_FORBIDDEN} = < span class = "hljs-built_in" > require< / span > < span class = "hljs-string" > './lexer'< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2013-03-10 23:37:22 -04:00
< li id = "section-2" >
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-2" > ¶ < / a >
< / div >
2014-01-29 23:54:00 -05:00
< p > Import the helpers we plan to use.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2015-02-18 15:43:33 -05:00
< div class = "content" > < div class = 'highlight' > < pre > {compact, flatten, extend, merge, del, starts, ends, some,
2014-01-29 23:54:00 -05:00
addLocationDataFn, locationDataToString, throwSyntaxError} = < span class = "hljs-built_in" > require< / span > < span class = "hljs-string" > './helpers'< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2013-03-10 23:37:22 -04:00
< li id = "section-3" >
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-3" > ¶ < / a >
< / div >
2014-01-29 23:54:00 -05:00
< p > Functions required by parser< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.extend = extend
exports.addLocationDataFn = addLocationDataFn< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2013-03-10 23:37:22 -04:00
< li id = "section-4" >
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-4" > ¶ < / a >
< / div >
2014-08-23 10:08:39 -04:00
< p > Constant functions for nodes that don’ t need customization.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-function" > < span class = "hljs-title" > YES< / span > = -> < / span > < span class = "hljs-literal" > yes< / span >
< span class = "hljs-function" > < span class = "hljs-title" > NO< / span > = -> < / span > < span class = "hljs-literal" > no< / span >
< span class = "hljs-function" > < span class = "hljs-title" > THIS< / span > = -> < / span > < span class = "hljs-keyword" > this< / span >
2016-09-22 16:19:43 -04:00
< span class = "hljs-function" > < span class = "hljs-title" > NEGATE< / span > = -> < / span > @negated = < span class = "hljs-keyword" > not< / span > @negated; < span class = "hljs-keyword" > this< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2013-03-10 23:37:22 -04:00
< li id = "section-5" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2014-01-29 23:54:00 -05:00
< a class = "pilcrow" href = "#section-5" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "codefragment" > CodeFragment< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
< li id = "section-6" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-6" > ¶ < / a >
< / div >
< p > The various nodes defined below all compile to a collection of < strong > CodeFragment< / strong > objects.
2013-03-04 14:19:08 -05:00
A CodeFragments is a block of generated code, and the location in the source file where the code
came from. CodeFragments can be assembled together into working code just by catting together
2014-08-23 10:08:39 -04:00
all the CodeFragments’ < code > code< / code > snippets, in order.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.CodeFragment = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > CodeFragment< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (parent, code)< / span > -> < / span >
@code = < span class = "hljs-string" > "< span class = "hljs-subst" > #{code}< / span > "< / span >
@locationData = parent?.locationData
@type = parent?.constructor?.name < span class = "hljs-keyword" > or< / span > < span class = "hljs-string" > 'unknown'< / span >
2013-03-04 14:19:08 -05:00
2016-09-22 16:19:43 -04:00
toString: < span class = "hljs-function" > -> < / span >
< span class = "hljs-string" > "< span class = "hljs-subst" > #{@code}< / span > < span class = "hljs-subst" > #{< span class = "hljs-keyword" > if< / span > @locationData < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > ": "< / span > + locationDataToString(@locationData) < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > ''< / span > }< / span > "< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-7" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-7" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Convert an array of CodeFragments into a string.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-function" > < span class = "hljs-title" > fragmentsToText< / span > = < span class = "hljs-params" > (fragments)< / span > -> < / span >
(fragment.code < span class = "hljs-keyword" > for< / span > fragment < span class = "hljs-keyword" > in< / span > fragments).join(< span class = "hljs-string" > ''< / span > )< / pre > < / div > < / div >
2013-06-02 01:37:45 -04:00
< / li >
2014-08-23 10:08:39 -04:00
< li id = "section-8" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-8" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "base" > Base< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
< li id = "section-9" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-9" > ¶ < / a >
< / div >
< p > The < strong > Base< / strong > is the abstract base class for all nodes in the syntax tree.
2010-06-28 00:19:58 -04:00
Each subclass implements the < code > compileNode< / code > method, which performs the
2010-03-07 16:41:06 -05:00
code generation for that node. To compile a node to JavaScript,
2010-06-28 00:19:58 -04:00
call < code > compile< / code > on it, which wraps < code > compileNode< / code > in some generic extra smarts,
2010-03-07 16:41:06 -05:00
to know when the generated code needs to be wrapped up in a closure.
An options hash is passed and cloned throughout, containing information about
the environment from higher in the tree (such as if a returned value is
being requested by the surrounding function), information about the current
2014-01-29 23:54:00 -05:00
scope, and indentation level.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Base = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Base< / span > < / span >
2013-03-04 14:19:08 -05:00
2016-09-22 16:19:43 -04:00
compile: < span class = "hljs-function" > < span class = "hljs-params" > (o, lvl)< / span > -> < / span >
fragmentsToText @compileToFragments o, lvl< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-10" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-10" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > Common logic for determining whether to wrap this node in a closure before
2010-03-07 16:41:06 -05:00
compiling it, or to compile directly. We need to wrap if this node is a
2014-08-23 10:08:39 -04:00
< em > statement< / em > , and it’ s not a < em > pureStatement< / em > , and we’ re not at
the top level of a block (which would be unnecessary), and we haven’ t
2010-03-07 16:41:06 -05:00
already been asked to return the result (because statements know how to
2014-01-29 23:54:00 -05:00
return results).< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileToFragments: < span class = "hljs-function" > < span class = "hljs-params" > (o, lvl)< / span > -> < / span >
2013-03-18 01:06:33 -04:00
o = extend {}, o
2014-01-29 23:54:00 -05:00
o.level = lvl < span class = "hljs-keyword" > if< / span > lvl
2016-09-22 16:19:43 -04:00
node = @unfoldSoak(o) < span class = "hljs-keyword" > or< / span > < span class = "hljs-keyword" > this< / span >
2013-03-18 01:06:33 -04:00
node.tab = o.indent
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > o.level < span class = "hljs-keyword" > is< / span > LEVEL_TOP < span class = "hljs-keyword" > or< / span > < span class = "hljs-keyword" > not< / span > node.isStatement(o)
2013-03-18 01:06:33 -04:00
node.compileNode o
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2013-03-18 01:06:33 -04:00
node.compileClosure o< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-11" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-11" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > Statements converted into expressions via closure-wrapping share a scope
2014-01-29 23:54:00 -05:00
object with their parent closure, to preserve the expected lexical scope.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileClosure: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
< span class = "hljs-keyword" > if< / span > jumpNode = @jumps()
2014-01-29 23:54:00 -05:00
jumpNode.error < span class = "hljs-string" > 'cannot use a pure statement in an expression'< / span >
o.sharedScope = < span class = "hljs-literal" > yes< / span >
func = < span class = "hljs-keyword" > new< / span > Code [], Block.wrap [< span class = "hljs-keyword" > this< / span > ]
args = []
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > (argumentsNode = @contains isLiteralArguments) < span class = "hljs-keyword" > or< / span > @contains isLiteralThis
args = [< span class = "hljs-keyword" > new< / span > ThisLiteral]
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > argumentsNode
meth = < span class = "hljs-string" > 'apply'< / span >
2016-09-22 16:19:43 -04:00
args.push < span class = "hljs-keyword" > new< / span > IdentifierLiteral < span class = "hljs-string" > 'arguments'< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
meth = < span class = "hljs-string" > 'call'< / span >
2016-09-22 16:19:43 -04:00
func = < span class = "hljs-keyword" > new< / span > Value func, [< span class = "hljs-keyword" > new< / span > Access < span class = "hljs-keyword" > new< / span > PropertyName meth]
2015-01-29 12:20:46 -05:00
parts = (< span class = "hljs-keyword" > new< / span > Call func, args).compileNode o
2015-04-15 11:26:30 -04:00
< span class = "hljs-keyword" > if< / span > func.isGenerator < span class = "hljs-keyword" > or< / span > func.base?.isGenerator
2016-09-22 16:19:43 -04:00
parts.unshift @makeCode < span class = "hljs-string" > "(yield* "< / span >
parts.push @makeCode < span class = "hljs-string" > ")"< / span >
2015-01-29 12:20:46 -05:00
parts< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-12" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-12" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > If the code generation wishes to use the result of a complex expression
2010-03-07 16:41:06 -05:00
in multiple places, ensure that the expression is only ever evaluated once,
2014-01-29 23:54:00 -05:00
by assigning it to a temporary variable. Pass a level to precompile.< / p >
2013-03-04 14:19:08 -05:00
< p > If < code > level< / code > is passed, then returns < code > [val, ref]< / code > , where < code > val< / code > is the compiled value, and < code > ref< / code >
is the compiled reference. If < code > level< / code > is not passed, this returns < code > [val, ref]< / code > where
2014-01-29 23:54:00 -05:00
the two values are raw nodes which have not been compiled.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > cache: < span class = "hljs-function" > < span class = "hljs-params" > (o, level, isComplex)< / span > -> < / span >
complex = < span class = "hljs-keyword" > if< / span > isComplex? < span class = "hljs-keyword" > then< / span > isComplex < span class = "hljs-keyword" > this< / span > < span class = "hljs-keyword" > else< / span > @isComplex()
2015-02-18 15:43:33 -05:00
< span class = "hljs-keyword" > if< / span > complex
2016-09-22 16:19:43 -04:00
ref = < span class = "hljs-keyword" > new< / span > IdentifierLiteral o.scope.freeVariable < span class = "hljs-string" > 'ref'< / span >
2014-01-29 23:54:00 -05:00
sub = < span class = "hljs-keyword" > new< / span > Assign ref, < span class = "hljs-keyword" > this< / span >
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > level < span class = "hljs-keyword" > then< / span > [sub.compileToFragments(o, level), [@makeCode(ref.value)]] < span class = "hljs-keyword" > else< / span > [sub, ref]
2015-02-18 15:43:33 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
ref = < span class = "hljs-keyword" > if< / span > level < span class = "hljs-keyword" > then< / span > @compileToFragments o, level < span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > this< / span >
2015-02-18 15:43:33 -05:00
[ref, ref]
2013-03-04 14:19:08 -05:00
2016-09-22 16:19:43 -04:00
cacheToCodeFragments: < span class = "hljs-function" > < span class = "hljs-params" > (cacheValues)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
[fragmentsToText(cacheValues[< span class = "hljs-number" > 0< / span > ]), fragmentsToText(cacheValues[< span class = "hljs-number" > 1< / span > ])]< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-13" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-13" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-08-23 10:08:39 -04:00
< p > Construct a node that returns the current node’ s result.
2010-03-23 00:18:50 -04:00
Note that this is overridden for smarter behavior for
2014-08-23 10:08:39 -04:00
many statement nodes (e.g. If, For)…< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > makeReturn: < span class = "hljs-function" > < span class = "hljs-params" > (res)< / span > -> < / span >
me = @unwrapAll()
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > res
< span class = "hljs-keyword" > new< / span > Call < span class = "hljs-keyword" > new< / span > Literal(< span class = "hljs-string" > "< span class = "hljs-subst" > #{res}< / span > .push"< / span > ), [me]
< span class = "hljs-keyword" > else< / span >
< span class = "hljs-keyword" > new< / span > Return me< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-14" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-14" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > Does this node, or any of its children, contain a node of a certain kind?
2013-03-10 23:37:22 -04:00
Recursively traverses down the < em > children< / em > nodes and returns the first one
that verifies < code > pred< / code > . Otherwise return undefined. < code > contains< / code > does not cross
2014-01-29 23:54:00 -05:00
scope boundaries.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > contains: < span class = "hljs-function" > < span class = "hljs-params" > (pred)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
node = < span class = "hljs-literal" > undefined< / span >
2016-09-22 16:19:43 -04:00
@traverseChildren < span class = "hljs-literal" > no< / span > , < span class = "hljs-function" > < span class = "hljs-params" > (n)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > pred n
2013-03-18 01:06:33 -04:00
node = n
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > < span class = "hljs-literal" > no< / span >
2013-03-18 01:06:33 -04:00
node< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-15" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-15" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Pull out the last non-comment node of a node list.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > lastNonComment: < span class = "hljs-function" > < span class = "hljs-params" > (list)< / span > -> < / span >
2013-03-18 01:06:33 -04:00
i = list.length
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > list[i] < span class = "hljs-keyword" > while< / span > i-- < span class = "hljs-keyword" > when< / span > list[i] < span class = "hljs-keyword" > not< / span > < span class = "hljs-keyword" > instanceof< / span > Comment
< span class = "hljs-literal" > null< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-16" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-16" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > < code > toString< / code > representation of the node, for inspecting the parse tree.
2014-01-29 23:54:00 -05:00
This is what < code > coffee --nodes< / code > prints out.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > toString: < span class = "hljs-function" > < span class = "hljs-params" > (idt = < span class = "hljs-string" > ''< / span > , name = @constructor.name)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
tree = < span class = "hljs-string" > '\n'< / span > + idt + name
2016-09-22 16:19:43 -04:00
tree += < span class = "hljs-string" > '?'< / span > < span class = "hljs-keyword" > if< / span > @soak
@eachChild (node) -> tree += node.toString idt + TAB
2013-03-18 01:06:33 -04:00
tree< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-17" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-17" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Passes each child to a function, breaking when the function returns < code > false< / code > .< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > eachChild: < span class = "hljs-function" > < span class = "hljs-params" > (func)< / span > -> < / span >
< span class = "hljs-keyword" > return< / span > < span class = "hljs-keyword" > this< / span > < span class = "hljs-keyword" > unless< / span > @children
< span class = "hljs-keyword" > for< / span > attr < span class = "hljs-keyword" > in< / span > @children < span class = "hljs-keyword" > when< / span > @[attr]
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > for< / span > child < span class = "hljs-keyword" > in< / span > flatten [@[attr]]
< span class = "hljs-keyword" > return< / span > < span class = "hljs-keyword" > this< / span > < span class = "hljs-keyword" > if< / span > func(child) < span class = "hljs-keyword" > is< / span > < span class = "hljs-literal" > false< / span >
< span class = "hljs-keyword" > this< / span >
2010-06-28 00:19:58 -04:00
2016-09-22 16:19:43 -04:00
traverseChildren: < span class = "hljs-function" > < span class = "hljs-params" > (crossScope, func)< / span > -> < / span >
@eachChild (child) ->
2013-06-02 01:37:45 -04:00
recur = func(child)
2014-01-29 23:54:00 -05:00
child.traverseChildren(crossScope, func) < span class = "hljs-keyword" > unless< / span > recur < span class = "hljs-keyword" > is< / span > < span class = "hljs-literal" > no< / span >
2010-06-28 00:19:58 -04:00
2016-09-22 16:19:43 -04:00
invert: < span class = "hljs-function" > -> < / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > new< / span > Op < span class = "hljs-string" > '!'< / span > , < span class = "hljs-keyword" > this< / span >
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
unwrapAll: < span class = "hljs-function" > -> < / span >
2014-01-29 23:54:00 -05:00
node = < span class = "hljs-keyword" > this< / span >
< span class = "hljs-keyword" > continue< / span > < span class = "hljs-keyword" > until< / span > node < span class = "hljs-keyword" > is< / span > node = node.unwrap()
2013-03-18 01:06:33 -04:00
node< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-18" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-18" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > Default implementations of the common node properties and methods. Nodes
2014-01-29 23:54:00 -05:00
will override these with custom logic, if needed.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > children: []
2010-11-20 14:22:28 -05:00
2013-03-18 01:06:33 -04:00
isStatement : NO
jumps : NO
isComplex : YES
isChainable : NO
isAssignable : NO
2016-09-22 16:19:43 -04:00
isNumber : NO
2010-11-20 14:22:28 -05:00
2013-03-18 01:06:33 -04:00
unwrap : THIS
unfoldSoak : NO< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-19" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-19" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Is this node used to assign a certain variable?< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > assigns: NO< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-20" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-20" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > For this node and all descendents, set the location data to < code > locationData< / code >
2014-01-29 23:54:00 -05:00
if the location data is not already set.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > updateLocationDataIfMissing: < span class = "hljs-function" > < span class = "hljs-params" > (locationData)< / span > -> < / span >
< span class = "hljs-keyword" > return< / span > < span class = "hljs-keyword" > this< / span > < span class = "hljs-keyword" > if< / span > @locationData
@locationData = locationData
2013-02-25 03:12:22 -05:00
2016-09-22 16:19:43 -04:00
@eachChild (child) ->
2013-03-18 01:06:33 -04:00
child.updateLocationDataIfMissing locationData< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-21" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-21" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-08-23 10:08:39 -04:00
< p > Throw a SyntaxError associated with this node’ s location.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > error: < span class = "hljs-function" > < span class = "hljs-params" > (message)< / span > -> < / span >
throwSyntaxError message, @locationData
2013-03-04 14:19:08 -05:00
2016-09-22 16:19:43 -04:00
makeCode: < span class = "hljs-function" > < span class = "hljs-params" > (code)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > new< / span > CodeFragment < span class = "hljs-keyword" > this< / span > , code
2013-03-04 14:19:08 -05:00
2016-09-22 16:19:43 -04:00
wrapInBraces: < span class = "hljs-function" > < span class = "hljs-params" > (fragments)< / span > -> < / span >
[].concat @makeCode(< span class = "hljs-string" > '('< / span > ), fragments, @makeCode(< span class = "hljs-string" > ')'< / span > )< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-22" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-22" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > < code > fragmentsList< / code > is an array of arrays of fragments. Each array in fragmentsList will be
2013-03-04 14:19:08 -05:00
concatonated together, with < code > joinStr< / code > added in between each, to produce a final flat array
2014-01-29 23:54:00 -05:00
of fragments.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > joinFragmentArrays: < span class = "hljs-function" > < span class = "hljs-params" > (fragmentsList, joinStr)< / span > -> < / span >
2013-03-18 01:06:33 -04:00
answer = []
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > for< / span > fragments,i < span class = "hljs-keyword" > in< / span > fragmentsList
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > i < span class = "hljs-keyword" > then< / span > answer.push @makeCode joinStr
2013-03-18 01:06:33 -04:00
answer = answer.concat fragments
answer< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-23" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-23" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "block" > Block< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
< li id = "section-24" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-24" > ¶ < / a >
< / div >
< p > The block is the list of expressions that forms the body of an
2016-09-22 16:19:43 -04:00
indented block of code – the implementation of a function, a clause in an
2014-08-23 10:08:39 -04:00
< code > if< / code > , < code > switch< / code > , or < code > try< / code > , and so on…< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Block = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Block< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (nodes)< / span > -> < / span >
@expressions = compact flatten nodes < span class = "hljs-keyword" > or< / span > []
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'expressions'< / span > ]< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-25" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-25" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Tack an expression on to the end of this expression list.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > push: < span class = "hljs-function" > < span class = "hljs-params" > (node)< / span > -> < / span >
@expressions.push node
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > this< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-26" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-26" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Remove and return the last expression of this expression list.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > pop: < span class = "hljs-function" > -> < / span >
@expressions.pop()< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-27" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-27" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Add an expression at the beginning of this expression list.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > unshift: < span class = "hljs-function" > < span class = "hljs-params" > (node)< / span > -> < / span >
@expressions.unshift node
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > this< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-28" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-28" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > If this Block consists of just a single node, unwrap it by pulling
2014-01-29 23:54:00 -05:00
it back out.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > unwrap: < span class = "hljs-function" > -> < / span >
< span class = "hljs-keyword" > if< / span > @expressions.length < span class = "hljs-keyword" > is< / span > < span class = "hljs-number" > 1< / span > < span class = "hljs-keyword" > then< / span > @expressions[< span class = "hljs-number" > 0< / span > ] < span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > this< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-29" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-29" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Is this an empty block of code?< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > isEmpty: < span class = "hljs-function" > -> < / span >
< span class = "hljs-keyword" > not< / span > @expressions.length
2010-06-28 00:19:58 -04:00
2016-09-22 16:19:43 -04:00
isStatement: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
< span class = "hljs-keyword" > for< / span > exp < span class = "hljs-keyword" > in< / span > @expressions < span class = "hljs-keyword" > when< / span > exp.isStatement o
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > < span class = "hljs-literal" > yes< / span >
< span class = "hljs-literal" > no< / span >
2010-12-24 14:02:10 -05:00
2016-09-22 16:19:43 -04:00
jumps: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
< span class = "hljs-keyword" > for< / span > exp < span class = "hljs-keyword" > in< / span > @expressions
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > jumpNode < span class = "hljs-keyword" > if< / span > jumpNode = exp.jumps o< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-30" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-30" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > A Block node does not return its entire body, rather it
2014-01-29 23:54:00 -05:00
ensures that the final expression is returned.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > makeReturn: < span class = "hljs-function" > < span class = "hljs-params" > (res)< / span > -> < / span >
len = @expressions.length
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > while< / span > len--
2016-09-22 16:19:43 -04:00
expr = @expressions[len]
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > expr < span class = "hljs-keyword" > not< / span > < span class = "hljs-keyword" > instanceof< / span > Comment
2016-09-22 16:19:43 -04:00
@expressions[len] = expr.makeReturn res
@expressions.splice(len, < span class = "hljs-number" > 1< / span > ) < span class = "hljs-keyword" > if< / span > expr < span class = "hljs-keyword" > instanceof< / span > Return < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > expr.expression
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > break< / span >
< span class = "hljs-keyword" > this< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-31" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-31" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > A < strong > Block< / strong > is the only node that can serve as the root.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileToFragments: < span class = "hljs-function" > < span class = "hljs-params" > (o = {}, level)< / span > -> < / span >
< span class = "hljs-keyword" > if< / span > o.scope < span class = "hljs-keyword" > then< / span > < span class = "hljs-keyword" > super< / span > o, level < span class = "hljs-keyword" > else< / span > @compileRoot o< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-32" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-32" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > Compile all expressions within the < strong > Block< / strong > body. If we need to
2014-08-23 10:08:39 -04:00
return the result, and it’ s an expression, simply return it. If it’ s a
2014-01-29 23:54:00 -05:00
statement, ask the statement to do so.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
@tab = o.indent
2014-01-29 23:54:00 -05:00
top = o.level < span class = "hljs-keyword" > is< / span > LEVEL_TOP
2013-03-18 01:06:33 -04:00
compiledNodes = []
2013-03-04 14:19:08 -05:00
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > for< / span > node, index < span class = "hljs-keyword" > in< / span > @expressions
2013-03-04 14:19:08 -05:00
2013-03-18 01:06:33 -04:00
node = node.unwrapAll()
2014-01-29 23:54:00 -05:00
node = (node.unfoldSoak(o) < span class = "hljs-keyword" > or< / span > node)
< span class = "hljs-keyword" > if< / span > node < span class = "hljs-keyword" > instanceof< / span > Block< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-33" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-33" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-08-23 10:08:39 -04:00
< p > This is a nested block. We don’ t do anything special here like enclose
2011-08-04 23:17:23 -04:00
it in a new scope; we just compile the statements in this block along with
2014-01-29 23:54:00 -05:00
our own< / p >
2013-03-10 23:37:22 -04:00
< / div >
2013-03-18 01:06:33 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compiledNodes.push node.compileNode o
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > top
node.front = < span class = "hljs-literal" > true< / span >
2013-03-18 01:06:33 -04:00
fragments = node.compileToFragments o
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > unless< / span > node.isStatement o
2016-09-22 16:19:43 -04:00
fragments.unshift @makeCode < span class = "hljs-string" > "< span class = "hljs-subst" > #{@tab}< / span > "< / span >
fragments.push @makeCode < span class = "hljs-string" > ";"< / span >
2013-03-18 01:06:33 -04:00
compiledNodes.push fragments
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2013-03-18 01:06:33 -04:00
compiledNodes.push node.compileToFragments o, LEVEL_LIST
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > top
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > @spaced
< span class = "hljs-keyword" > return< / span > [].concat @joinFragmentArrays(compiledNodes, < span class = "hljs-string" > '\n\n'< / span > ), @makeCode(< span class = "hljs-string" > "\n"< / span > )
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > return< / span > @joinFragmentArrays(compiledNodes, < span class = "hljs-string" > '\n'< / span > )
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > compiledNodes.length
2016-09-22 16:19:43 -04:00
answer = @joinFragmentArrays(compiledNodes, < span class = "hljs-string" > ', '< / span > )
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
answer = [@makeCode < span class = "hljs-string" > "void 0"< / span > ]
< span class = "hljs-keyword" > if< / span > compiledNodes.length > < span class = "hljs-number" > 1< / span > < span class = "hljs-keyword" > and< / span > o.level > = LEVEL_LIST < span class = "hljs-keyword" > then< / span > @wrapInBraces answer < span class = "hljs-keyword" > else< / span > answer< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-34" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-34" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > If we happen to be the top-level < strong > Block< / strong > , wrap everything in
2010-06-28 00:19:58 -04:00
a safety closure, unless requested not to.
It would be better not to generate them in the first place, but for now,
2014-01-29 23:54:00 -05:00
clean up obvious double-parentheses.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileRoot: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
o.indent = < span class = "hljs-keyword" > if< / span > o.bare < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > ''< / span > < span class = "hljs-keyword" > else< / span > TAB
2013-03-18 01:06:33 -04:00
o.level = LEVEL_TOP
2016-09-22 16:19:43 -04:00
@spaced = < span class = "hljs-literal" > yes< / span >
2015-01-29 12:20:46 -05:00
o.scope = < span class = "hljs-keyword" > new< / span > Scope < span class = "hljs-literal" > null< / span > , < span class = "hljs-keyword" > this< / span > , < span class = "hljs-literal" > null< / span > , o.referencedVars ? []< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-35" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-35" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-08-23 10:08:39 -04:00
< p > Mark given local variables in the root scope as parameters so they don’ t
2014-01-29 23:54:00 -05:00
end up being declared on this block.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< div class = "content" > < div class = 'highlight' > < pre > o.scope.parameter name < span class = "hljs-keyword" > for< / span > name < span class = "hljs-keyword" > in< / span > o.locals < span class = "hljs-keyword" > or< / span > []
2013-03-18 01:06:33 -04:00
prelude = []
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > unless< / span > o.bare
2016-09-22 16:19:43 -04:00
preludeExps = < span class = "hljs-keyword" > for< / span > exp, i < span class = "hljs-keyword" > in< / span > @expressions
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > break< / span > < span class = "hljs-keyword" > unless< / span > exp.unwrap() < span class = "hljs-keyword" > instanceof< / span > Comment
2013-03-18 01:06:33 -04:00
exp
2016-09-22 16:19:43 -04:00
rest = @expressions[preludeExps.length...]
@expressions = preludeExps
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > preludeExps.length
2016-09-22 16:19:43 -04:00
prelude = @compileNode merge(o, indent: < span class = "hljs-string" > ''< / span > )
prelude.push @makeCode < span class = "hljs-string" > "\n"< / span >
@expressions = rest
fragments = @compileWithDeclarations o
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > fragments < span class = "hljs-keyword" > if< / span > o.bare
2016-09-22 16:19:43 -04:00
[].concat prelude, @makeCode(< span class = "hljs-string" > "(function() {\n"< / span > ), fragments, @makeCode(< span class = "hljs-string" > "\n}).call(this);\n"< / span > )< / pre > < / div > < / div >
2013-03-18 01:06:33 -04:00
< / li >
2014-08-23 10:08:39 -04:00
< li id = "section-36" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-36" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > Compile the expressions body for the contents of a function, with
2014-01-29 23:54:00 -05:00
declarations of all inner variables pushed up to the top.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileWithDeclarations: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
2013-03-18 01:06:33 -04:00
fragments = []
post = []
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > for< / span > exp, i < span class = "hljs-keyword" > in< / span > @expressions
2013-03-18 01:06:33 -04:00
exp = exp.unwrap()
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > break< / span > < span class = "hljs-keyword" > unless< / span > exp < span class = "hljs-keyword" > instanceof< / span > Comment < span class = "hljs-keyword" > or< / span > exp < span class = "hljs-keyword" > instanceof< / span > Literal
2016-09-22 16:19:43 -04:00
o = merge(o, level: LEVEL_TOP)
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > i
2016-09-22 16:19:43 -04:00
rest = @expressions.splice i, < span class = "hljs-number" > 9e9< / span >
[spaced, @spaced] = [@spaced, < span class = "hljs-literal" > no< / span > ]
[fragments, @spaced] = [@compileNode(o), spaced]
@expressions = rest
post = @compileNode o
2013-03-18 01:06:33 -04:00
{scope} = o
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > scope.expressions < span class = "hljs-keyword" > is< / span > < span class = "hljs-keyword" > this< / span >
2013-03-18 01:06:33 -04:00
declars = o.scope.hasDeclarations()
assigns = scope.hasAssignments
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > declars < span class = "hljs-keyword" > or< / span > assigns
2016-09-22 16:19:43 -04:00
fragments.push @makeCode < span class = "hljs-string" > '\n'< / span > < span class = "hljs-keyword" > if< / span > i
fragments.push @makeCode < span class = "hljs-string" > "< span class = "hljs-subst" > #{@tab}< / span > var "< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > declars
2016-09-22 16:19:43 -04:00
fragments.push @makeCode scope.declaredVariables().join(< span class = "hljs-string" > ', '< / span > )
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > assigns
2016-09-22 16:19:43 -04:00
fragments.push @makeCode < span class = "hljs-string" > ",\n< span class = "hljs-subst" > #{@tab + TAB}< / span > "< / span > < span class = "hljs-keyword" > if< / span > declars
fragments.push @makeCode scope.assignedVariables().join(< span class = "hljs-string" > ",\n< span class = "hljs-subst" > #{@tab + TAB}< / span > "< / span > )
fragments.push @makeCode < span class = "hljs-string" > ";\n< span class = "hljs-subst" > #{< span class = "hljs-keyword" > if< / span > @spaced < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > '\n'< / span > < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > ''< / span > }< / span > "< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > fragments.length < span class = "hljs-keyword" > and< / span > post.length
2016-09-22 16:19:43 -04:00
fragments.push @makeCode < span class = "hljs-string" > "\n"< / span >
2013-03-18 01:06:33 -04:00
fragments.concat post< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-37" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-37" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > Wrap up the given nodes as a < strong > Block< / strong > , unless it already happens
2014-01-29 23:54:00 -05:00
to be one.< / p >
2013-03-18 01:06:33 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > @wrap: < span class = "hljs-function" > < span class = "hljs-params" > (nodes)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > nodes[< span class = "hljs-number" > 0< / span > ] < span class = "hljs-keyword" > if< / span > nodes.length < span class = "hljs-keyword" > is< / span > < span class = "hljs-number" > 1< / span > < span class = "hljs-keyword" > and< / span > nodes[< span class = "hljs-number" > 0< / span > ] < span class = "hljs-keyword" > instanceof< / span > Block
< span class = "hljs-keyword" > new< / span > Block nodes< / pre > < / div > < / div >
2013-06-02 01:37:45 -04:00
< / li >
2014-08-23 10:08:39 -04:00
< li id = "section-38" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-38" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "literal" > Literal< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
< li id = "section-39" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-39" > ¶ < / a >
< / div >
2016-09-22 16:19:43 -04:00
< p > < code > Literal< / code > is a base class for static values that can be passed through
directly into JavaScript without translation, such as: strings, numbers,
2014-08-23 10:08:39 -04:00
< code > true< / code > , < code > false< / code > , < code > null< / code > …< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Literal = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Literal< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@value)< / span > -> < / span >
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
isComplex: NO
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
assigns: < span class = "hljs-function" > < span class = "hljs-params" > (name)< / span > -> < / span >
name < span class = "hljs-keyword" > is< / span > @value
2010-12-24 14:02:10 -05:00
2016-09-22 16:19:43 -04:00
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
[@makeCode @value]
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
toString: < span class = "hljs-function" > -> < / span >
< span class = "hljs-string" > " < span class = "hljs-subst" > #{< span class = "hljs-keyword" > if< / span > @isStatement() < span class = "hljs-keyword" > then< / span > < span class = "hljs-keyword" > super< / span > < span class = "hljs-keyword" > else< / span > @constructor.name}< / span > : < span class = "hljs-subst" > #{@value}< / span > "< / span >
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
exports.NumberLiteral = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > NumberLiteral< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Literal< / span > < / span >
2010-12-24 14:02:10 -05:00
2016-09-22 16:19:43 -04:00
exports.InfinityLiteral = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > InfinityLiteral< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > NumberLiteral< / span > < / span >
compileNode: < span class = "hljs-function" > -> < / span >
[@makeCode < span class = "hljs-string" > '2e308'< / span > ]
2010-06-28 00:19:58 -04:00
2016-09-22 16:19:43 -04:00
exports.NaNLiteral = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > NaNLiteral< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > NumberLiteral< / span > < / span >
constructor: < span class = "hljs-function" > -> < / span >
< span class = "hljs-keyword" > super< / span > < span class = "hljs-string" > 'NaN'< / span >
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
code = [@makeCode < span class = "hljs-string" > '0/0'< / span > ]
< span class = "hljs-keyword" > if< / span > o.level > = LEVEL_OP < span class = "hljs-keyword" > then< / span > @wrapInBraces code < span class = "hljs-keyword" > else< / span > code
exports.StringLiteral = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > StringLiteral< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Literal< / span > < / span >
exports.RegexLiteral = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > RegexLiteral< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Literal< / span > < / span >
exports.PassthroughLiteral = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > PassthroughLiteral< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Literal< / span > < / span >
exports.IdentifierLiteral = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > IdentifierLiteral< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Literal< / span > < / span >
isAssignable: YES
exports.PropertyName = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > PropertyName< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Literal< / span > < / span >
isAssignable: YES
exports.StatementLiteral = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > StatementLiteral< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Literal< / span > < / span >
isStatement: YES
makeReturn: THIS
jumps: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
< span class = "hljs-keyword" > return< / span > < span class = "hljs-keyword" > this< / span > < span class = "hljs-keyword" > if< / span > @value < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > 'break'< / span > < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > (o?.< span class = "hljs-keyword" > loop< / span > < span class = "hljs-keyword" > or< / span > o?.block)
< span class = "hljs-keyword" > return< / span > < span class = "hljs-keyword" > this< / span > < span class = "hljs-keyword" > if< / span > @value < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > 'continue'< / span > < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > o?.< span class = "hljs-keyword" > loop< / span >
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
[@makeCode < span class = "hljs-string" > "< span class = "hljs-subst" > #{@tab}< / span > < span class = "hljs-subst" > #{@value}< / span > ;"< / span > ]
exports.ThisLiteral = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > ThisLiteral< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Literal< / span > < / span >
constructor: < span class = "hljs-function" > -> < / span >
< span class = "hljs-keyword" > super< / span > < span class = "hljs-string" > 'this'< / span >
2012-05-14 14:45:20 -04:00
2016-09-22 16:19:43 -04:00
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
code = < span class = "hljs-keyword" > if< / span > o.scope.method?.bound < span class = "hljs-keyword" > then< / span > o.scope.method.context < span class = "hljs-keyword" > else< / span > @value
[@makeCode code]
2012-05-14 14:45:20 -04:00
2016-09-22 16:19:43 -04:00
exports.UndefinedLiteral = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > UndefinedLiteral< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Literal< / span > < / span >
constructor: < span class = "hljs-function" > -> < / span >
< span class = "hljs-keyword" > super< / span > < span class = "hljs-string" > 'undefined'< / span >
2012-05-14 14:45:20 -04:00
2016-09-22 16:19:43 -04:00
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
[@makeCode < span class = "hljs-keyword" > if< / span > o.level > = LEVEL_ACCESS < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > '(void 0)'< / span > < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > 'void 0'< / span > ]
2013-06-02 01:37:45 -04:00
2016-09-22 16:19:43 -04:00
exports.NullLiteral = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > NullLiteral< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Literal< / span > < / span >
constructor: < span class = "hljs-function" > -> < / span >
< span class = "hljs-keyword" > super< / span > < span class = "hljs-string" > 'null'< / span >
exports.BooleanLiteral = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > BooleanLiteral< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Literal< / span > < / span > < / pre > < / div > < / div >
2013-06-02 01:37:45 -04:00
< / li >
2014-08-23 10:08:39 -04:00
< li id = "section-40" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-40" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "return" > Return< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
< li id = "section-41" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-41" > ¶ < / a >
< / div >
2016-09-22 16:19:43 -04:00
< p > A < code > return< / code > is a < em > pureStatement< / em > – wrapping it in a closure wouldn’ t
2014-01-29 23:54:00 -05:00
make sense.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Return = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Return< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@expression)< / span > -> < / span >
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'expression'< / span > ]
2010-06-28 00:19:58 -04:00
2016-09-22 16:19:43 -04:00
isStatement: YES
makeReturn: THIS
jumps: THIS
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
compileToFragments: < span class = "hljs-function" > < span class = "hljs-params" > (o, level)< / span > -> < / span >
expr = @expression?.makeReturn()
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > expr < span class = "hljs-keyword" > and< / span > expr < span class = "hljs-keyword" > not< / span > < span class = "hljs-keyword" > instanceof< / span > Return < span class = "hljs-keyword" > then< / span > expr.compileToFragments o, level < span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > super< / span > o, level
2010-07-11 10:40:44 -04:00
2016-09-22 16:19:43 -04:00
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
answer = []< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-42" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-42" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-08-23 10:08:39 -04:00
< p > TODO: If we call expression.compile() here twice, we’ ll sometimes get back different results!< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > answer.push @makeCode @tab + < span class = "hljs-string" > "return< span class = "hljs-subst" > #{< span class = "hljs-keyword" > if< / span > @expression < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > " "< / span > < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > ""< / span > }< / span > "< / span >
< span class = "hljs-keyword" > if< / span > @expression
answer = answer.concat @expression.compileToFragments o, LEVEL_PAREN
answer.push @makeCode < span class = "hljs-string" > ";"< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > answer< / pre > < / div > < / div >
2013-06-02 01:37:45 -04:00
< / li >
2014-08-23 10:08:39 -04:00
< li id = "section-43" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-43" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< p > < code > yield return< / code > works exactly like < code > return< / code > , except that it turns the function
into a generator.< / p >
2014-08-23 10:08:39 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.YieldReturn = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > YieldReturn< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Return< / span > < / span >
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
< span class = "hljs-keyword" > unless< / span > o.scope.parent?
@error < span class = "hljs-string" > 'yield can only occur inside functions'< / span >
< span class = "hljs-keyword" > super< / span > < / pre > < / div > < / div >
2014-08-23 10:08:39 -04:00
< / li >
< li id = "section-44" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-44" > ¶ < / a >
< / div >
2016-09-22 16:19:43 -04:00
< h3 id = "value" > Value< / h3 >
< / div >
< / li >
< li id = "section-45" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-45" > ¶ < / a >
< / div >
2014-08-23 10:08:39 -04:00
< p > A value, variable or literal or parenthesized, indexed or dotted into,
2014-01-29 23:54:00 -05:00
or vanilla.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Value = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Value< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (base, props, tag)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > base < span class = "hljs-keyword" > if< / span > < span class = "hljs-keyword" > not< / span > props < span class = "hljs-keyword" > and< / span > base < span class = "hljs-keyword" > instanceof< / span > Value
2016-09-22 16:19:43 -04:00
@base = base
@properties = props < span class = "hljs-keyword" > or< / span > []
2014-01-29 23:54:00 -05:00
@[tag] = < span class = "hljs-literal" > true< / span > < span class = "hljs-keyword" > if< / span > tag
< span class = "hljs-keyword" > return< / span > < span class = "hljs-keyword" > this< / span >
2013-03-04 14:19:08 -05:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'base'< / span > , < span class = "hljs-string" > 'properties'< / span > ]< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-46" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-46" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Add a property (or < em > properties< / em > ) < code > Access< / code > to the list.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > add: < span class = "hljs-function" > < span class = "hljs-params" > (props)< / span > -> < / span >
@properties = @properties.concat props
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > this< / span >
2016-09-22 16:19:43 -04:00
hasProperties: < span class = "hljs-function" > -> < / span >
!!@properties.length
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
bareLiteral: < span class = "hljs-function" > < span class = "hljs-params" > (type)< / span > -> < / span >
< span class = "hljs-keyword" > not< / span > @properties.length < span class = "hljs-keyword" > and< / span > @base < span class = "hljs-keyword" > instanceof< / span > type< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-47" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-47" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Some boolean checks for the benefit of other nodes.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > isArray : < span class = "hljs-function" > -> < / span > @bareLiteral(Arr)
isRange : < span class = "hljs-function" > -> < / span > @bareLiteral(Range)
isComplex : < span class = "hljs-function" > -> < / span > @hasProperties() < span class = "hljs-keyword" > or< / span > @base.isComplex()
isAssignable : < span class = "hljs-function" > -> < / span > @hasProperties() < span class = "hljs-keyword" > or< / span > @base.isAssignable()
isNumber : < span class = "hljs-function" > -> < / span > @bareLiteral(NumberLiteral)
isString : < span class = "hljs-function" > -> < / span > @bareLiteral(StringLiteral)
isRegex : < span class = "hljs-function" > -> < / span > @bareLiteral(RegexLiteral)
isUndefined : < span class = "hljs-function" > -> < / span > @bareLiteral(UndefinedLiteral)
isNull : < span class = "hljs-function" > -> < / span > @bareLiteral(NullLiteral)
isBoolean : < span class = "hljs-function" > -> < / span > @bareLiteral(BooleanLiteral)
isAtomic : < span class = "hljs-function" > -> < / span >
< span class = "hljs-keyword" > for< / span > node < span class = "hljs-keyword" > in< / span > @properties.concat @base
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > < span class = "hljs-literal" > no< / span > < span class = "hljs-keyword" > if< / span > node.soak < span class = "hljs-keyword" > or< / span > node < span class = "hljs-keyword" > instanceof< / span > Call
< span class = "hljs-literal" > yes< / span >
2016-09-22 16:19:43 -04:00
isNotCallable : < span class = "hljs-function" > -> < / span > @isNumber() < span class = "hljs-keyword" > or< / span > @isString() < span class = "hljs-keyword" > or< / span > @isRegex() < span class = "hljs-keyword" > or< / span >
@isArray() < span class = "hljs-keyword" > or< / span > @isRange() < span class = "hljs-keyword" > or< / span > @isSplice() < span class = "hljs-keyword" > or< / span > @isObject() < span class = "hljs-keyword" > or< / span >
@isUndefined() < span class = "hljs-keyword" > or< / span > @isNull() < span class = "hljs-keyword" > or< / span > @isBoolean()
2014-01-29 23:54:00 -05:00
2016-09-22 16:19:43 -04:00
isStatement : < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span > < span class = "hljs-keyword" > not< / span > @properties.length < span class = "hljs-keyword" > and< / span > @base.isStatement o
assigns : < span class = "hljs-function" > < span class = "hljs-params" > (name)< / span > -> < / span > < span class = "hljs-keyword" > not< / span > @properties.length < span class = "hljs-keyword" > and< / span > @base.assigns name
jumps : < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span > < span class = "hljs-keyword" > not< / span > @properties.length < span class = "hljs-keyword" > and< / span > @base.jumps o
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
isObject: < span class = "hljs-function" > < span class = "hljs-params" > (onlyGenerated)< / span > -> < / span >
< span class = "hljs-keyword" > return< / span > < span class = "hljs-literal" > no< / span > < span class = "hljs-keyword" > if< / span > @properties.length
(@base < span class = "hljs-keyword" > instanceof< / span > Obj) < span class = "hljs-keyword" > and< / span > (< span class = "hljs-keyword" > not< / span > onlyGenerated < span class = "hljs-keyword" > or< / span > @base.generated)
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
isSplice: < span class = "hljs-function" > -> < / span >
[..., lastProp] = @properties
2015-02-18 15:43:33 -05:00
lastProp < span class = "hljs-keyword" > instanceof< / span > Slice
2010-03-23 00:18:50 -04:00
2016-09-22 16:19:43 -04:00
looksStatic: < span class = "hljs-function" > < span class = "hljs-params" > (className)< / span > -> < / span >
@base.value < span class = "hljs-keyword" > is< / span > className < span class = "hljs-keyword" > and< / span > @properties.length < span class = "hljs-keyword" > is< / span > < span class = "hljs-number" > 1< / span > < span class = "hljs-keyword" > and< / span >
@properties[< span class = "hljs-number" > 0< / span > ].name?.value < span class = "hljs-keyword" > isnt< / span > < span class = "hljs-string" > 'prototype'< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-48" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-48" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > The value can be unwrapped as its inner node, if there are no attached
2014-01-29 23:54:00 -05:00
properties.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > unwrap: < span class = "hljs-function" > -> < / span >
< span class = "hljs-keyword" > if< / span > @properties.length < span class = "hljs-keyword" > then< / span > < span class = "hljs-keyword" > this< / span > < span class = "hljs-keyword" > else< / span > @base< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-49" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-49" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > A reference has base part (< code > this< / code > value) and name part.
2010-11-20 14:22:28 -05:00
We cache them separately for compiling complex expressions.
2014-01-29 23:54:00 -05:00
< code > a()[b()] ?= c< / code > -> < code > (_base = a())[_name = b()] ? _base[_name] = c< / code > < / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > cacheReference: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
[..., name] = @properties
< span class = "hljs-keyword" > if< / span > @properties.length < < span class = "hljs-number" > 2< / span > < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > @base.isComplex() < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > name?.isComplex()
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > [< span class = "hljs-keyword" > this< / span > , < span class = "hljs-keyword" > this< / span > ] < span class = "hljs-comment" > # `a` `a.b`< / span >
2016-09-22 16:19:43 -04:00
base = < span class = "hljs-keyword" > new< / span > Value @base, @properties[...< span class = "hljs-number" > -1< / span > ]
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > base.isComplex() < span class = "hljs-comment" > # `a().b`< / span >
2016-09-22 16:19:43 -04:00
bref = < span class = "hljs-keyword" > new< / span > IdentifierLiteral o.scope.freeVariable < span class = "hljs-string" > 'base'< / span >
2014-01-29 23:54:00 -05:00
base = < span class = "hljs-keyword" > new< / span > Value < span class = "hljs-keyword" > new< / span > Parens < span class = "hljs-keyword" > new< / span > Assign bref, base
< span class = "hljs-keyword" > return< / span > [base, bref] < span class = "hljs-keyword" > unless< / span > name < span class = "hljs-comment" > # `a()`< / span >
< span class = "hljs-keyword" > if< / span > name.isComplex() < span class = "hljs-comment" > # `a[b()]`< / span >
2016-09-22 16:19:43 -04:00
nref = < span class = "hljs-keyword" > new< / span > IdentifierLiteral o.scope.freeVariable < span class = "hljs-string" > 'name'< / span >
2014-01-29 23:54:00 -05:00
name = < span class = "hljs-keyword" > new< / span > Index < span class = "hljs-keyword" > new< / span > Assign nref, name.index
nref = < span class = "hljs-keyword" > new< / span > Index nref
[base.add(name), < span class = "hljs-keyword" > new< / span > Value(bref < span class = "hljs-keyword" > or< / span > base.base, [nref < span class = "hljs-keyword" > or< / span > name])]< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-50" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-50" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > We compile a value to JavaScript by compiling and joining each property.
2010-11-20 14:22:28 -05:00
Things get much more interesting if the chain of properties has < em > soak< / em >
2010-03-07 17:31:39 -05:00
operators < code > ?.< / code > interspersed. Then we have to take care not to accidentally
2014-01-29 23:54:00 -05:00
evaluate anything twice when building the soak chain.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
@base.front = @front
props = @properties
fragments = @base.compileToFragments o, (< span class = "hljs-keyword" > if< / span > props.length < span class = "hljs-keyword" > then< / span > LEVEL_ACCESS < span class = "hljs-keyword" > else< / span > < span class = "hljs-literal" > null< / span > )
< span class = "hljs-keyword" > if< / span > props.length < span class = "hljs-keyword" > and< / span > SIMPLENUM.test fragmentsToText fragments
fragments.push @makeCode < span class = "hljs-string" > '.'< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > for< / span > prop < span class = "hljs-keyword" > in< / span > props
2013-03-18 01:06:33 -04:00
fragments.push (prop.compileToFragments o)...
fragments< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-51" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-51" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Unfold a soak into an < code > If< / code > : < code > a?.b< / code > -> < code > a.b if a?< / code > < / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > unfoldSoak: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
@unfoldedSoak ?= < span class = "hljs-keyword" > do< / span > =>
< span class = "hljs-keyword" > if< / span > ifn = @base.unfoldSoak o
ifn.body.properties.push @properties...
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > ifn
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > for< / span > prop, i < span class = "hljs-keyword" > in< / span > @properties < span class = "hljs-keyword" > when< / span > prop.soak
2014-01-29 23:54:00 -05:00
prop.soak = < span class = "hljs-literal" > off< / span >
2016-09-22 16:19:43 -04:00
fst = < span class = "hljs-keyword" > new< / span > Value @base, @properties[...i]
snd = < span class = "hljs-keyword" > new< / span > Value @base, @properties[i..]
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > fst.isComplex()
2016-09-22 16:19:43 -04:00
ref = < span class = "hljs-keyword" > new< / span > IdentifierLiteral o.scope.freeVariable < span class = "hljs-string" > 'ref'< / span >
2014-01-29 23:54:00 -05:00
fst = < span class = "hljs-keyword" > new< / span > Parens < span class = "hljs-keyword" > new< / span > Assign ref, fst
2013-03-18 01:06:33 -04:00
snd.base = ref
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > return< / span > < span class = "hljs-keyword" > new< / span > If < span class = "hljs-keyword" > new< / span > Existence(fst), snd, soak: < span class = "hljs-literal" > on< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-literal" > no< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-52" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2014-01-29 23:54:00 -05:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-52" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "comment" > Comment< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-53" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-53" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
< p > CoffeeScript passes through block comments as JavaScript block comments
2014-01-29 23:54:00 -05:00
at the same position.< / p >
2013-06-02 01:37:45 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Comment = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Comment< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@comment)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
2016-09-22 16:19:43 -04:00
isStatement: YES
makeReturn: THIS
2014-01-29 23:54:00 -05:00
2016-09-22 16:19:43 -04:00
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o, level)< / span > -> < / span >
comment = @comment.replace < span class = "hljs-regexp" > /^(\s*)#(?=\s)/gm< / span > , < span class = "hljs-string" > "$1 *"< / span >
code = < span class = "hljs-string" > "/*< span class = "hljs-subst" > #{multident comment, @tab}< / span > < span class = "hljs-subst" > #{< span class = "hljs-keyword" > if< / span > < span class = "hljs-string" > '\n'< / span > < span class = "hljs-keyword" > in< / span > comment < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > "\n< span class = "hljs-subst" > #{@tab}< / span > "< / span > < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > ''< / span > }< / span > */"< / span >
2014-01-29 23:54:00 -05:00
code = o.indent + code < span class = "hljs-keyword" > if< / span > (level < span class = "hljs-keyword" > or< / span > o.level) < span class = "hljs-keyword" > is< / span > LEVEL_TOP
2016-09-22 16:19:43 -04:00
[@makeCode(< span class = "hljs-string" > "\n"< / span > ), @makeCode(code)]< / pre > < / div > < / div >
2014-08-23 10:08:39 -04:00
< / li >
< li id = "section-54" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-54" > ¶ < / a >
< / div >
2016-09-22 16:19:43 -04:00
< h3 id = "call" > Call< / h3 >
2013-03-10 23:37:22 -04:00
< / div >
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-55" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2014-01-29 23:54:00 -05:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-55" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< p > Node for a function invocation.< / p >
2013-06-02 01:37:45 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Call = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Call< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@variable, @args = [], @soak)< / span > -> < / span >
@isNew = < span class = "hljs-literal" > false< / span >
< span class = "hljs-keyword" > if< / span > @variable < span class = "hljs-keyword" > instanceof< / span > Value < span class = "hljs-keyword" > and< / span > @variable.isNotCallable()
@variable.error < span class = "hljs-string" > "literal is not a function"< / span >
children: [< span class = "hljs-string" > 'variable'< / span > , < span class = "hljs-string" > 'args'< / span > ]< / pre > < / div > < / div >
2014-01-29 23:54:00 -05:00
2013-06-02 01:37:45 -04:00
< / li >
2014-08-23 10:08:39 -04:00
< li id = "section-56" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-56" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< p > Tag this invocation as creating a new instance.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > newInstance: < span class = "hljs-function" > -> < / span >
base = @variable?.base < span class = "hljs-keyword" > or< / span > @variable
< span class = "hljs-keyword" > if< / span > base < span class = "hljs-keyword" > instanceof< / span > Call < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > base.isNew
base.newInstance()
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
@isNew = < span class = "hljs-literal" > true< / span >
< span class = "hljs-keyword" > this< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-57" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-57" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Soaked chained invocations unfold into if/else ternary structures.< / p >
2013-03-18 01:06:33 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > unfoldSoak: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
< span class = "hljs-keyword" > if< / span > @soak
< span class = "hljs-keyword" > if< / span > < span class = "hljs-keyword" > this< / span > < span class = "hljs-keyword" > instanceof< / span > SuperCall
left = < span class = "hljs-keyword" > new< / span > Literal @superReference o
2014-01-29 23:54:00 -05:00
rite = < span class = "hljs-keyword" > new< / span > Value left
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > else< / span >
< span class = "hljs-keyword" > return< / span > ifn < span class = "hljs-keyword" > if< / span > ifn = unfoldSoak o, < span class = "hljs-keyword" > this< / span > , < span class = "hljs-string" > 'variable'< / span >
[left, rite] = < span class = "hljs-keyword" > new< / span > Value(@variable).cacheReference o
rite = < span class = "hljs-keyword" > new< / span > Call rite, @args
rite.isNew = @isNew
2014-01-29 23:54:00 -05:00
left = < span class = "hljs-keyword" > new< / span > Literal < span class = "hljs-string" > "typeof < span class = "hljs-subst" > #{ left.compile o }< / span > === \"function\""< / span >
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > return< / span > < span class = "hljs-keyword" > new< / span > If left, < span class = "hljs-keyword" > new< / span > Value(rite), soak: < span class = "hljs-literal" > yes< / span >
2014-01-29 23:54:00 -05:00
call = < span class = "hljs-keyword" > this< / span >
2013-03-18 01:06:33 -04:00
list = []
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > loop< / span >
< span class = "hljs-keyword" > if< / span > call.variable < span class = "hljs-keyword" > instanceof< / span > Call
2013-03-18 01:06:33 -04:00
list.push call
call = call.variable
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > continue< / span >
< span class = "hljs-keyword" > break< / span > < span class = "hljs-keyword" > unless< / span > call.variable < span class = "hljs-keyword" > instanceof< / span > Value
2013-03-18 01:06:33 -04:00
list.push call
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > break< / span > < span class = "hljs-keyword" > unless< / span > (call = call.variable.base) < span class = "hljs-keyword" > instanceof< / span > Call
< span class = "hljs-keyword" > for< / span > call < span class = "hljs-keyword" > in< / span > list.reverse()
< span class = "hljs-keyword" > if< / span > ifn
< span class = "hljs-keyword" > if< / span > call.variable < span class = "hljs-keyword" > instanceof< / span > Call
2013-03-18 01:06:33 -04:00
call.variable = ifn
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2013-03-18 01:06:33 -04:00
call.variable.base = ifn
2014-01-29 23:54:00 -05:00
ifn = unfoldSoak o, call, < span class = "hljs-string" > 'variable'< / span >
2013-03-18 01:06:33 -04:00
ifn< / pre > < / div > < / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-58" >
2013-03-18 01:06:33 -04:00
< div class = "annotation" >
2013-03-10 23:37:22 -04:00
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-58" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Compile a vanilla function call.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
@variable?.front = @front
compiledArray = Splat.compileSplattedArray o, @args, < span class = "hljs-literal" > true< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > compiledArray.length
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > return< / span > @compileSplat o, compiledArray
2013-03-18 01:06:33 -04:00
compiledArgs = []
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > for< / span > arg, argIndex < span class = "hljs-keyword" > in< / span > @args
< span class = "hljs-keyword" > if< / span > argIndex < span class = "hljs-keyword" > then< / span > compiledArgs.push @makeCode < span class = "hljs-string" > ", "< / span >
2013-03-18 01:06:33 -04:00
compiledArgs.push (arg.compileToFragments o, LEVEL_LIST)...
2013-03-04 14:19:08 -05:00
2013-03-18 01:06:33 -04:00
fragments = []
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > < span class = "hljs-keyword" > this< / span > < span class = "hljs-keyword" > instanceof< / span > SuperCall
preface = @superReference(o) + < span class = "hljs-string" > ".call(< span class = "hljs-subst" > #{@superThis(o)}< / span > "< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > compiledArgs.length < span class = "hljs-keyword" > then< / span > preface += < span class = "hljs-string" > ", "< / span >
2016-09-22 16:19:43 -04:00
fragments.push @makeCode preface
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > @isNew < span class = "hljs-keyword" > then< / span > fragments.push @makeCode < span class = "hljs-string" > 'new '< / span >
fragments.push @variable.compileToFragments(o, LEVEL_ACCESS)...
fragments.push @makeCode < span class = "hljs-string" > "("< / span >
2013-03-18 01:06:33 -04:00
fragments.push compiledArgs...
2016-09-22 16:19:43 -04:00
fragments.push @makeCode < span class = "hljs-string" > ")"< / span >
2013-03-18 01:06:33 -04:00
fragments< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-59" >
2013-03-18 01:06:33 -04:00
< div class = "annotation" >
2013-03-10 23:37:22 -04:00
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-59" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-08-23 10:08:39 -04:00
< p > If you call a function with a splat, it’ s converted into a JavaScript
2010-08-03 00:06:34 -04:00
< code > .apply()< / code > call to allow an array of arguments to be passed.
2014-08-23 10:08:39 -04:00
If it’ s a constructor, then things get real tricky. We have to inject an
2014-01-29 23:54:00 -05:00
inner constructor in order to be able to pass the varargs.< / p >
2014-08-23 10:08:39 -04:00
< p > splatArgs is an array of CodeFragments to put into the ‘ apply’ .< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileSplat: < span class = "hljs-function" > < span class = "hljs-params" > (o, splatArgs)< / span > -> < / span >
< span class = "hljs-keyword" > if< / span > < span class = "hljs-keyword" > this< / span > < span class = "hljs-keyword" > instanceof< / span > SuperCall
< span class = "hljs-keyword" > return< / span > [].concat @makeCode(< span class = "hljs-string" > "< span class = "hljs-subst" > #{ @superReference o }< / span > .apply(< span class = "hljs-subst" > #{@superThis(o)}< / span > , "< / span > ),
splatArgs, @makeCode(< span class = "hljs-string" > ")"< / span > )
2013-03-04 14:19:08 -05:00
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > @isNew
idt = @tab + TAB
< span class = "hljs-keyword" > return< / span > [].concat @makeCode(< span class = "hljs-string" > """
2013-03-18 01:06:33 -04:00
(function(func, args, ctor) {
2014-01-29 23:54:00 -05:00
< span class = "hljs-subst" > #{idt}< / span > ctor.prototype = func.prototype;
< span class = "hljs-subst" > #{idt}< / span > var child = new ctor, result = func.apply(child, args);
< span class = "hljs-subst" > #{idt}< / span > return Object(result) === result ? result : child;
2016-09-22 16:19:43 -04:00
< span class = "hljs-subst" > #{@tab}< / span > })("""< / span > ),
(@variable.compileToFragments o, LEVEL_LIST),
@makeCode(< span class = "hljs-string" > ", "< / span > ), splatArgs, @makeCode(< span class = "hljs-string" > ", function(){})"< / span > )
2013-03-04 14:19:08 -05:00
2013-03-18 01:06:33 -04:00
answer = []
2016-09-22 16:19:43 -04:00
base = < span class = "hljs-keyword" > new< / span > Value @variable
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > (name = base.properties.pop()) < span class = "hljs-keyword" > and< / span > base.isComplex()
ref = o.scope.freeVariable < span class = "hljs-string" > 'ref'< / span >
2016-09-22 16:19:43 -04:00
answer = answer.concat @makeCode(< span class = "hljs-string" > "(< span class = "hljs-subst" > #{ref}< / span > = "< / span > ),
2013-03-18 01:06:33 -04:00
(base.compileToFragments o, LEVEL_LIST),
2016-09-22 16:19:43 -04:00
@makeCode(< span class = "hljs-string" > ")"< / span > ),
2013-03-18 01:06:33 -04:00
name.compileToFragments(o)
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2013-03-18 01:06:33 -04:00
fun = base.compileToFragments o, LEVEL_ACCESS
2016-09-22 16:19:43 -04:00
fun = @wrapInBraces fun < span class = "hljs-keyword" > if< / span > SIMPLENUM.test fragmentsToText fun
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > name
2013-03-18 01:06:33 -04:00
ref = fragmentsToText fun
fun.push (name.compileToFragments o)...
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
ref = < span class = "hljs-string" > 'null'< / span >
2013-03-18 01:06:33 -04:00
answer = answer.concat fun
2016-09-22 16:19:43 -04:00
answer = answer.concat @makeCode(< span class = "hljs-string" > ".apply(< span class = "hljs-subst" > #{ref}< / span > , "< / span > ), splatArgs, @makeCode(< span class = "hljs-string" > ")"< / span > )< / pre > < / div > < / div >
< / li >
< li id = "section-60" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-60" > ¶ < / a >
< / div >
< h3 id = "super" > Super< / h3 >
< / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-61" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-61" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< p > Takes care of converting < code > super()< / code > calls into calls against the prototype’ s
function of the same name.< / p >
2014-08-23 10:08:39 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.SuperCall = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > SuperCall< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Call< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (args)< / span > -> < / span >
< span class = "hljs-keyword" > super< / span > < span class = "hljs-literal" > null< / span > , args ? [< span class = "hljs-keyword" > new< / span > Splat < span class = "hljs-keyword" > new< / span > IdentifierLiteral < span class = "hljs-string" > 'arguments'< / span > ]< / pre > < / div > < / div >
2014-08-23 10:08:39 -04:00
< / li >
< li id = "section-62" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-62" > ¶ < / a >
< / div >
2016-09-22 16:19:43 -04:00
< p > Allow to recognize a bare < code > super< / code > call without parentheses and arguments.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > @isBare = args?< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-63" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-63" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< p > Grab the reference to the superclass’ s implementation of the current
method.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > superReference: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
method = o.scope.namedMethod()
< span class = "hljs-keyword" > if< / span > method?.klass
{klass, name, variable} = method
< span class = "hljs-keyword" > if< / span > klass.isComplex()
bref = < span class = "hljs-keyword" > new< / span > IdentifierLiteral o.scope.parent.freeVariable < span class = "hljs-string" > 'base'< / span >
base = < span class = "hljs-keyword" > new< / span > Value < span class = "hljs-keyword" > new< / span > Parens < span class = "hljs-keyword" > new< / span > Assign bref, klass
variable.base = base
variable.properties.splice < span class = "hljs-number" > 0< / span > , klass.properties.length
< span class = "hljs-keyword" > if< / span > name.isComplex() < span class = "hljs-keyword" > or< / span > (name < span class = "hljs-keyword" > instanceof< / span > Index < span class = "hljs-keyword" > and< / span > name.index.isAssignable())
nref = < span class = "hljs-keyword" > new< / span > IdentifierLiteral o.scope.parent.freeVariable < span class = "hljs-string" > 'name'< / span >
name = < span class = "hljs-keyword" > new< / span > Index < span class = "hljs-keyword" > new< / span > Assign nref, name.index
variable.properties.pop()
variable.properties.push name
accesses = [< span class = "hljs-keyword" > new< / span > Access < span class = "hljs-keyword" > new< / span > PropertyName < span class = "hljs-string" > '__super__'< / span > ]
accesses.push < span class = "hljs-keyword" > new< / span > Access < span class = "hljs-keyword" > new< / span > PropertyName < span class = "hljs-string" > 'constructor'< / span > < span class = "hljs-keyword" > if< / span > method.static
accesses.push < span class = "hljs-keyword" > if< / span > nref? < span class = "hljs-keyword" > then< / span > < span class = "hljs-keyword" > new< / span > Index nref < span class = "hljs-keyword" > else< / span > name
(< span class = "hljs-keyword" > new< / span > Value bref ? klass, accesses).compile o
< span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > method?.ctor
< span class = "hljs-string" > "< span class = "hljs-subst" > #{method.name}< / span > .__super__.constructor"< / span >
< span class = "hljs-keyword" > else< / span >
@error < span class = "hljs-string" > 'cannot call super outside of an instance method.'< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2014-08-23 10:08:39 -04:00
< li id = "section-64" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2014-08-23 10:08:39 -04:00
< a class = "pilcrow" href = "#section-64" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< p > The appropriate < code > this< / code > value for a < code > super< / code > call.< / p >
2014-08-23 10:08:39 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > superThis : < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
method = o.scope.method
(method < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > method.klass < span class = "hljs-keyword" > and< / span > method.context) < span class = "hljs-keyword" > or< / span > < span class = "hljs-string" > "this"< / span > < / pre > < / div > < / div >
2014-08-23 10:08:39 -04:00
< / li >
< li id = "section-65" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-65" > ¶ < / a >
< / div >
2016-09-22 16:19:43 -04:00
< h3 id = "regexwithinterpolations" > RegexWithInterpolations< / h3 >
< / div >
< / li >
< li id = "section-66" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-66" > ¶ < / a >
< / div >
< p > Regexes with interpolations are in fact just a variation of a < code > Call< / code > (a
< code > RegExp()< / code > call to be precise) with a < code > StringWithInterpolations< / code > inside.< / p >
< / div >
< div class = "content" > < div class = 'highlight' > < pre > exports.RegexWithInterpolations = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > RegexWithInterpolations< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Call< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (args = [])< / span > -> < / span >
< span class = "hljs-keyword" > super< / span > (< span class = "hljs-keyword" > new< / span > Value < span class = "hljs-keyword" > new< / span > IdentifierLiteral < span class = "hljs-string" > 'RegExp'< / span > ), args, < span class = "hljs-literal" > false< / span > < / pre > < / div > < / div >
< / li >
< li id = "section-67" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-67" > ¶ < / a >
< / div >
< h3 id = "extends" > Extends< / h3 >
< / div >
< / li >
< li id = "section-68" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-68" > ¶ < / a >
< / div >
< p > Node to extend an object’ s prototype with an ancestor object.
After < code > goog.inherits< / code > from the
< a href = "http://closure-library.googlecode.com/svn/docs/closureGoogBase.js.html" > Closure Library< / a > .< / p >
< / div >
< div class = "content" > < div class = 'highlight' > < pre > exports.Extends = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Extends< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@child, @parent)< / span > -> < / span >
children: [< span class = "hljs-string" > 'child'< / span > , < span class = "hljs-string" > 'parent'< / span > ]< / pre > < / div > < / div >
< / li >
< li id = "section-69" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-69" > ¶ < / a >
< / div >
< p > Hooks one constructor into another’ s prototype chain.< / p >
< / div >
< div class = "content" > < div class = 'highlight' > < pre > compileToFragments: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
< span class = "hljs-keyword" > new< / span > Call(< span class = "hljs-keyword" > new< / span > Value(< span class = "hljs-keyword" > new< / span > Literal utility < span class = "hljs-string" > 'extend'< / span > , o), [@child, @parent]).compileToFragments o< / pre > < / div > < / div >
< / li >
< li id = "section-70" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-70" > ¶ < / a >
< / div >
< h3 id = "access" > Access< / h3 >
< / div >
< / li >
< li id = "section-71" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-71" > ¶ < / a >
< / div >
2014-08-23 10:08:39 -04:00
< p > A < code > .< / code > access into a property of a value, or the < code > ::< / code > shorthand for
an access into the object’ s prototype.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Access = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Access< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@name, tag)< / span > -> < / span >
@name.asKey = < span class = "hljs-literal" > yes< / span >
@soak = tag < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > 'soak'< / span >
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'name'< / span > ]
2010-06-28 00:19:58 -04:00
2016-09-22 16:19:43 -04:00
compileToFragments: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
name = @name.compileToFragments o
node = @name.unwrap()
< span class = "hljs-keyword" > if< / span > node < span class = "hljs-keyword" > instanceof< / span > PropertyName
< span class = "hljs-keyword" > if< / span > node.value < span class = "hljs-keyword" > in< / span > JS_FORBIDDEN
[@makeCode(< span class = "hljs-string" > '["'< / span > ), name..., @makeCode(< span class = "hljs-string" > '"]'< / span > )]
< span class = "hljs-keyword" > else< / span >
[@makeCode(< span class = "hljs-string" > '.'< / span > ), name...]
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
[@makeCode(< span class = "hljs-string" > '['< / span > ), name..., @makeCode(< span class = "hljs-string" > ']'< / span > )]
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
isComplex: NO< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-72" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-72" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "index" > Index< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-73" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-73" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
< p > A < code > [ ... ]< / code > indexed access into an array or object.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Index = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Index< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@index)< / span > -> < / span >
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'index'< / span > ]
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
compileToFragments: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
[].concat @makeCode(< span class = "hljs-string" > "["< / span > ), @index.compileToFragments(o, LEVEL_PAREN), @makeCode(< span class = "hljs-string" > "]"< / span > )
2010-06-28 00:19:58 -04:00
2016-09-22 16:19:43 -04:00
isComplex: < span class = "hljs-function" > -> < / span >
@index.isComplex()< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-74" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-74" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "range" > Range< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-75" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-75" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
< p > A range literal. Ranges can be used to extract portions (slices) of arrays,
2010-12-24 14:02:10 -05:00
to specify a range for comprehensions, or as a value, to be expanded into the
2014-01-29 23:54:00 -05:00
corresponding array of integers at runtime.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Range = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Range< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
2010-11-21 12:38:27 -05:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'from'< / span > , < span class = "hljs-string" > 'to'< / span > ]
2010-11-21 12:38:27 -05:00
2016-09-22 16:19:43 -04:00
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@from, @to, tag)< / span > -> < / span >
@exclusive = tag < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > 'exclusive'< / span >
@equals = < span class = "hljs-keyword" > if< / span > @exclusive < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > ''< / span > < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > '='< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-76" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-76" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< p > Compiles the range’ s source variables – where it starts and where it ends.
2014-01-29 23:54:00 -05:00
But only if they need to be cached to avoid double evaluation.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileVariables: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
o = merge o, top: < span class = "hljs-literal" > true< / span >
2015-02-18 15:43:33 -05:00
isComplex = del o, < span class = "hljs-string" > 'isComplex'< / span >
2016-09-22 16:19:43 -04:00
[@fromC, @fromVar] = @cacheToCodeFragments @from.cache o, LEVEL_LIST, isComplex
[@toC, @toVar] = @cacheToCodeFragments @to.cache o, LEVEL_LIST, isComplex
[@step, @stepVar] = @cacheToCodeFragments step.cache o, LEVEL_LIST, isComplex < span class = "hljs-keyword" > if< / span > step = del o, < span class = "hljs-string" > 'step'< / span >
@fromNum = < span class = "hljs-keyword" > if< / span > @from.isNumber() < span class = "hljs-keyword" > then< / span > Number @fromVar < span class = "hljs-keyword" > else< / span > < span class = "hljs-literal" > null< / span >
@toNum = < span class = "hljs-keyword" > if< / span > @to.isNumber() < span class = "hljs-keyword" > then< / span > Number @toVar < span class = "hljs-keyword" > else< / span > < span class = "hljs-literal" > null< / span >
@stepNum = < span class = "hljs-keyword" > if< / span > step?.isNumber() < span class = "hljs-keyword" > then< / span > Number @stepVar < span class = "hljs-keyword" > else< / span > < span class = "hljs-literal" > null< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-77" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-77" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > When compiled normally, the range returns the contents of the < em > for loop< / em >
2014-01-29 23:54:00 -05:00
needed to iterate over the values in the range. Used by comprehensions.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
@compileVariables o < span class = "hljs-keyword" > unless< / span > @fromVar
< span class = "hljs-keyword" > return< / span > @compileArray(o) < span class = "hljs-keyword" > unless< / span > o.index< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-78" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-78" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Set up endpoints.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > known = @fromNum? < span class = "hljs-keyword" > and< / span > @toNum?
2014-01-29 23:54:00 -05:00
idx = del o, < span class = "hljs-string" > 'index'< / span >
idxName = del o, < span class = "hljs-string" > 'name'< / span >
namedIndex = idxName < span class = "hljs-keyword" > and< / span > idxName < span class = "hljs-keyword" > isnt< / span > idx
2016-09-22 16:19:43 -04:00
varPart = < span class = "hljs-string" > "< span class = "hljs-subst" > #{idx}< / span > = < span class = "hljs-subst" > #{@fromC}< / span > "< / span >
varPart += < span class = "hljs-string" > ", < span class = "hljs-subst" > #{@toC}< / span > "< / span > < span class = "hljs-keyword" > if< / span > @toC < span class = "hljs-keyword" > isnt< / span > @toVar
varPart += < span class = "hljs-string" > ", < span class = "hljs-subst" > #{@step}< / span > "< / span > < span class = "hljs-keyword" > if< / span > @step < span class = "hljs-keyword" > isnt< / span > @stepVar
[lt, gt] = [< span class = "hljs-string" > "< span class = "hljs-subst" > #{idx}< / span > < < span class = "hljs-subst" > #{@equals}< / span > "< / span > , < span class = "hljs-string" > "< span class = "hljs-subst" > #{idx}< / span > > < span class = "hljs-subst" > #{@equals}< / span > "< / span > ]< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-79" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-79" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Generate the condition.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > condPart = < span class = "hljs-keyword" > if< / span > @stepNum?
< span class = "hljs-keyword" > if< / span > @stepNum > < span class = "hljs-number" > 0< / span > < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > "< span class = "hljs-subst" > #{lt}< / span > < span class = "hljs-subst" > #{@toVar}< / span > "< / span > < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > "< span class = "hljs-subst" > #{gt}< / span > < span class = "hljs-subst" > #{@toVar}< / span > "< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > known
2016-09-22 16:19:43 -04:00
[from, to] = [@fromNum, @toNum]
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > from < = to < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > "< span class = "hljs-subst" > #{lt}< / span > < span class = "hljs-subst" > #{to}< / span > "< / span > < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > "< span class = "hljs-subst" > #{gt}< / span > < span class = "hljs-subst" > #{to}< / span > "< / span >
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
cond = < span class = "hljs-keyword" > if< / span > @stepVar < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > "< span class = "hljs-subst" > #{@stepVar}< / span > > 0"< / span > < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > "< span class = "hljs-subst" > #{@fromVar}< / span > < = < span class = "hljs-subst" > #{@toVar}< / span > "< / span >
< span class = "hljs-string" > "< span class = "hljs-subst" > #{cond}< / span > ? < span class = "hljs-subst" > #{lt}< / span > < span class = "hljs-subst" > #{@toVar}< / span > : < span class = "hljs-subst" > #{gt}< / span > < span class = "hljs-subst" > #{@toVar}< / span > "< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-80" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-80" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Generate the step.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > stepPart = < span class = "hljs-keyword" > if< / span > @stepVar
< span class = "hljs-string" > "< span class = "hljs-subst" > #{idx}< / span > += < span class = "hljs-subst" > #{@stepVar}< / span > "< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > known
< span class = "hljs-keyword" > if< / span > namedIndex
< span class = "hljs-keyword" > if< / span > from < = to < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > "++< span class = "hljs-subst" > #{idx}< / span > "< / span > < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > "--< span class = "hljs-subst" > #{idx}< / span > "< / span >
< span class = "hljs-keyword" > else< / span >
< span class = "hljs-keyword" > if< / span > from < = to < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > "< span class = "hljs-subst" > #{idx}< / span > ++"< / span > < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > "< span class = "hljs-subst" > #{idx}< / span > --"< / span >
< span class = "hljs-keyword" > else< / span >
< span class = "hljs-keyword" > if< / span > namedIndex
< span class = "hljs-string" > "< span class = "hljs-subst" > #{cond}< / span > ? ++< span class = "hljs-subst" > #{idx}< / span > : --< span class = "hljs-subst" > #{idx}< / span > "< / span >
< span class = "hljs-keyword" > else< / span >
< span class = "hljs-string" > "< span class = "hljs-subst" > #{cond}< / span > ? < span class = "hljs-subst" > #{idx}< / span > ++ : < span class = "hljs-subst" > #{idx}< / span > --"< / span >
2012-04-10 14:57:45 -04:00
2014-01-29 23:54:00 -05:00
varPart = < span class = "hljs-string" > "< span class = "hljs-subst" > #{idxName}< / span > = < span class = "hljs-subst" > #{varPart}< / span > "< / span > < span class = "hljs-keyword" > if< / span > namedIndex
stepPart = < span class = "hljs-string" > "< span class = "hljs-subst" > #{idxName}< / span > = < span class = "hljs-subst" > #{stepPart}< / span > "< / span > < span class = "hljs-keyword" > if< / span > namedIndex< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-81" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-81" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > The final loop body.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > [@makeCode < span class = "hljs-string" > "< span class = "hljs-subst" > #{varPart}< / span > ; < span class = "hljs-subst" > #{condPart}< / span > ; < span class = "hljs-subst" > #{stepPart}< / span > "< / span > ]< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-82" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-82" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > When used as a value, expand the range into the equivalent array.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileArray: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
known = @fromNum? < span class = "hljs-keyword" > and< / span > @toNum?
< span class = "hljs-keyword" > if< / span > known < span class = "hljs-keyword" > and< / span > Math.abs(@fromNum - @toNum) < = < span class = "hljs-number" > 20< / span >
range = [@fromNum..@toNum]
range.pop() < span class = "hljs-keyword" > if< / span > @exclusive
< span class = "hljs-keyword" > return< / span > [@makeCode < span class = "hljs-string" > "[< span class = "hljs-subst" > #{ range.join(< span class = "hljs-string" > ', '< / span > ) }< / span > ]"< / span > ]
idt = @tab + TAB
i = o.scope.freeVariable < span class = "hljs-string" > 'i'< / span > , single: < span class = "hljs-literal" > true< / span >
2014-01-29 23:54:00 -05:00
result = o.scope.freeVariable < span class = "hljs-string" > 'results'< / span >
pre = < span class = "hljs-string" > "\n< span class = "hljs-subst" > #{idt}< / span > < span class = "hljs-subst" > #{result}< / span > = [];"< / span >
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > known
2013-03-18 01:06:33 -04:00
o.index = i
2016-09-22 16:19:43 -04:00
body = fragmentsToText @compileNode o
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
vars = < span class = "hljs-string" > "< span class = "hljs-subst" > #{i}< / span > = < span class = "hljs-subst" > #{@fromC}< / span > "< / span > + < span class = "hljs-keyword" > if< / span > @toC < span class = "hljs-keyword" > isnt< / span > @toVar < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > ", < span class = "hljs-subst" > #{@toC}< / span > "< / span > < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > ''< / span >
cond = < span class = "hljs-string" > "< span class = "hljs-subst" > #{@fromVar}< / span > < = < span class = "hljs-subst" > #{@toVar}< / span > "< / span >
body = < span class = "hljs-string" > "var < span class = "hljs-subst" > #{vars}< / span > ; < span class = "hljs-subst" > #{cond}< / span > ? < span class = "hljs-subst" > #{i}< / span > < < span class = "hljs-subst" > #{@equals}< / span > < span class = "hljs-subst" > #{@toVar}< / span > : < span class = "hljs-subst" > #{i}< / span > > < span class = "hljs-subst" > #{@equals}< / span > < span class = "hljs-subst" > #{@toVar}< / span > ; < span class = "hljs-subst" > #{cond}< / span > ? < span class = "hljs-subst" > #{i}< / span > ++ : < span class = "hljs-subst" > #{i}< / span > --"< / span >
2014-01-29 23:54:00 -05:00
post = < span class = "hljs-string" > "{ < span class = "hljs-subst" > #{result}< / span > .push(< span class = "hljs-subst" > #{i}< / span > ); }\n< span class = "hljs-subst" > #{idt}< / span > return < span class = "hljs-subst" > #{result}< / span > ;\n< span class = "hljs-subst" > #{o.indent}< / span > "< / span >
2016-09-22 16:19:43 -04:00
< span class = "hljs-function" > < span class = "hljs-title" > hasArgs< / span > = < span class = "hljs-params" > (node)< / span > -> < / span > node?.contains isLiteralArguments
args = < span class = "hljs-string" > ', arguments'< / span > < span class = "hljs-keyword" > if< / span > hasArgs(@from) < span class = "hljs-keyword" > or< / span > hasArgs(@to)
[@makeCode < span class = "hljs-string" > "(function() {< span class = "hljs-subst" > #{pre}< / span > \n< span class = "hljs-subst" > #{idt}< / span > for (< span class = "hljs-subst" > #{body}< / span > )< span class = "hljs-subst" > #{post}< / span > }).apply(this< span class = "hljs-subst" > #{args ? < span class = "hljs-string" > ''< / span > }< / span > )"< / span > ]< / pre > < / div > < / div >
2013-06-02 01:37:45 -04:00
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-83" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-83" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
< h3 id = "slice" > Slice< / h3 >
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-84" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-84" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-08-23 10:08:39 -04:00
< p > An array slice literal. Unlike JavaScript’ s < code > Array#slice< / code > , the second parameter
2010-12-24 14:02:10 -05:00
specifies the index of the end of the slice, just as the first parameter
2014-01-29 23:54:00 -05:00
is the index of the beginning.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Slice = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Slice< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
2010-11-21 12:38:27 -05:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'range'< / span > ]
2010-11-21 12:38:27 -05:00
2016-09-22 16:19:43 -04:00
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@range)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > super< / span > ()< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-85" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-85" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > We have to be careful when trying to slice through the end of the array,
2010-12-24 14:02:10 -05:00
< code > 9e9< / code > is used because not all implementations respect < code > undefined< / code > or < code > 1/0< / code > .
2014-01-29 23:54:00 -05:00
< code > 9e9< / code > should be safe because < code > 9e9< / code > > < code > 2**32< / code > , the max array length.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
{to, from} = @range
fromCompiled = from < span class = "hljs-keyword" > and< / span > from.compileToFragments(o, LEVEL_PAREN) < span class = "hljs-keyword" > or< / span > [@makeCode < span class = "hljs-string" > '0'< / span > ]< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-86" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-86" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-08-23 10:08:39 -04:00
< p > TODO: jwalton - move this into the ‘ if’ ?< / p >
2013-03-10 23:37:22 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-keyword" > if< / span > to
2013-03-18 01:06:33 -04:00
compiled = to.compileToFragments o, LEVEL_PAREN
compiledText = fragmentsToText compiled
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > < span class = "hljs-keyword" > not< / span > (< span class = "hljs-keyword" > not< / span > @range.exclusive < span class = "hljs-keyword" > and< / span > +compiledText < span class = "hljs-keyword" > is< / span > < span class = "hljs-number" > -1< / span > )
toStr = < span class = "hljs-string" > ', '< / span > + < span class = "hljs-keyword" > if< / span > @range.exclusive
2013-03-18 01:06:33 -04:00
compiledText
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > to.isNumber()
2014-01-29 23:54:00 -05:00
< span class = "hljs-string" > "< span class = "hljs-subst" > #{+compiledText + < span class = "hljs-number" > 1< / span > }< / span > "< / span >
< span class = "hljs-keyword" > else< / span >
2013-03-18 01:06:33 -04:00
compiled = to.compileToFragments o, LEVEL_ACCESS
2014-01-29 23:54:00 -05:00
< span class = "hljs-string" > "+< span class = "hljs-subst" > #{fragmentsToText compiled}< / span > + 1 || 9e9"< / span >
2016-09-22 16:19:43 -04:00
[@makeCode < span class = "hljs-string" > ".slice(< span class = "hljs-subst" > #{ fragmentsToText fromCompiled }< / span > < span class = "hljs-subst" > #{ toStr < span class = "hljs-keyword" > or< / span > < span class = "hljs-string" > ''< / span > }< / span > )"< / span > ]< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-87" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-87" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "obj" > Obj< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-88" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-88" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
< p > An object literal, nothing fancy.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Obj = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Obj< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (props, @generated = < span class = "hljs-literal" > false< / span > )< / span > -> < / span >
@objects = @properties = props < span class = "hljs-keyword" > or< / span > []
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'properties'< / span > ]
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
props = @properties
< span class = "hljs-keyword" > if< / span > @generated
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > for< / span > node < span class = "hljs-keyword" > in< / span > props < span class = "hljs-keyword" > when< / span > node < span class = "hljs-keyword" > instanceof< / span > Value
node.error < span class = "hljs-string" > 'cannot have an implicit value in an implicit object'< / span >
2015-02-18 15:43:33 -05:00
< span class = "hljs-keyword" > break< / span > < span class = "hljs-keyword" > for< / span > prop, dynamicIndex < span class = "hljs-keyword" > in< / span > props < span class = "hljs-keyword" > when< / span > (prop.variable < span class = "hljs-keyword" > or< / span > prop).base < span class = "hljs-keyword" > instanceof< / span > Parens
hasDynamic = dynamicIndex < props.length
2013-03-18 01:06:33 -04:00
idt = o.indent += TAB
2016-09-22 16:19:43 -04:00
lastNoncom = @lastNonComment @properties
2013-03-18 01:06:33 -04:00
answer = []
2015-02-18 15:43:33 -05:00
< span class = "hljs-keyword" > if< / span > hasDynamic
oref = o.scope.freeVariable < span class = "hljs-string" > 'obj'< / span >
2016-09-22 16:19:43 -04:00
answer.push @makeCode < span class = "hljs-string" > "(\n< span class = "hljs-subst" > #{idt}< / span > < span class = "hljs-subst" > #{oref}< / span > = "< / span >
answer.push @makeCode < span class = "hljs-string" > "{< span class = "hljs-subst" > #{< span class = "hljs-keyword" > if< / span > props.length < span class = "hljs-keyword" > is< / span > < span class = "hljs-number" > 0< / span > < span class = "hljs-keyword" > or< / span > dynamicIndex < span class = "hljs-keyword" > is< / span > < span class = "hljs-number" > 0< / span > < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > '}'< / span > < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > '\n'< / span > }< / span > "< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > for< / span > prop, i < span class = "hljs-keyword" > in< / span > props
2015-02-18 15:43:33 -05:00
< span class = "hljs-keyword" > if< / span > i < span class = "hljs-keyword" > is< / span > dynamicIndex
2016-09-22 16:19:43 -04:00
answer.push @makeCode < span class = "hljs-string" > "\n< span class = "hljs-subst" > #{idt}< / span > }"< / span > < span class = "hljs-keyword" > unless< / span > i < span class = "hljs-keyword" > is< / span > < span class = "hljs-number" > 0< / span >
answer.push @makeCode < span class = "hljs-string" > ',\n'< / span >
2015-02-18 15:43:33 -05:00
join = < span class = "hljs-keyword" > if< / span > i < span class = "hljs-keyword" > is< / span > props.length - < span class = "hljs-number" > 1< / span > < span class = "hljs-keyword" > or< / span > i < span class = "hljs-keyword" > is< / span > dynamicIndex - < span class = "hljs-number" > 1< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-string" > ''< / span >
< span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > prop < span class = "hljs-keyword" > is< / span > lastNoncom < span class = "hljs-keyword" > or< / span > prop < span class = "hljs-keyword" > instanceof< / span > Comment
< span class = "hljs-string" > '\n'< / span >
< span class = "hljs-keyword" > else< / span >
< span class = "hljs-string" > ',\n'< / span >
indent = < span class = "hljs-keyword" > if< / span > prop < span class = "hljs-keyword" > instanceof< / span > Comment < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > ''< / span > < span class = "hljs-keyword" > else< / span > idt
2015-02-18 15:43:33 -05:00
indent += TAB < span class = "hljs-keyword" > if< / span > hasDynamic < span class = "hljs-keyword" > and< / span > i < dynamicIndex
2015-09-03 12:37:36 -04:00
< span class = "hljs-keyword" > if< / span > prop < span class = "hljs-keyword" > instanceof< / span > Assign
< span class = "hljs-keyword" > if< / span > prop.context < span class = "hljs-keyword" > isnt< / span > < span class = "hljs-string" > 'object'< / span >
prop.operatorToken.error < span class = "hljs-string" > "unexpected < span class = "hljs-subst" > #{prop.operatorToken.value}< / span > "< / span >
< span class = "hljs-keyword" > if< / span > prop.variable < span class = "hljs-keyword" > instanceof< / span > Value < span class = "hljs-keyword" > and< / span > prop.variable.hasProperties()
prop.variable.error < span class = "hljs-string" > 'invalid object key'< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > prop < span class = "hljs-keyword" > instanceof< / span > Value < span class = "hljs-keyword" > and< / span > prop.< span class = "hljs-keyword" > this< / span >
prop = < span class = "hljs-keyword" > new< / span > Assign prop.properties[< span class = "hljs-number" > 0< / span > ].name, prop, < span class = "hljs-string" > 'object'< / span >
< span class = "hljs-keyword" > if< / span > prop < span class = "hljs-keyword" > not< / span > < span class = "hljs-keyword" > instanceof< / span > Comment
2015-02-18 15:43:33 -05:00
< span class = "hljs-keyword" > if< / span > i < dynamicIndex
< span class = "hljs-keyword" > if< / span > prop < span class = "hljs-keyword" > not< / span > < span class = "hljs-keyword" > instanceof< / span > Assign
prop = < span class = "hljs-keyword" > new< / span > Assign prop, prop, < span class = "hljs-string" > 'object'< / span >
(prop.variable.base < span class = "hljs-keyword" > or< / span > prop.variable).asKey = < span class = "hljs-literal" > yes< / span >
< span class = "hljs-keyword" > else< / span >
< span class = "hljs-keyword" > if< / span > prop < span class = "hljs-keyword" > instanceof< / span > Assign
key = prop.variable
value = prop.value
< span class = "hljs-keyword" > else< / span >
[key, value] = prop.base.cache o
2016-09-22 16:19:43 -04:00
prop = < span class = "hljs-keyword" > new< / span > Assign (< span class = "hljs-keyword" > new< / span > Value (< span class = "hljs-keyword" > new< / span > IdentifierLiteral oref), [< span class = "hljs-keyword" > new< / span > Access key]), value
< span class = "hljs-keyword" > if< / span > indent < span class = "hljs-keyword" > then< / span > answer.push @makeCode indent
2013-03-18 01:06:33 -04:00
answer.push prop.compileToFragments(o, LEVEL_TOP)...
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > join < span class = "hljs-keyword" > then< / span > answer.push @makeCode join
2015-02-18 15:43:33 -05:00
< span class = "hljs-keyword" > if< / span > hasDynamic
2016-09-22 16:19:43 -04:00
answer.push @makeCode < span class = "hljs-string" > ",\n< span class = "hljs-subst" > #{idt}< / span > < span class = "hljs-subst" > #{oref}< / span > \n< span class = "hljs-subst" > #{@tab}< / span > )"< / span >
2015-02-18 15:43:33 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
answer.push @makeCode < span class = "hljs-string" > "\n< span class = "hljs-subst" > #{@tab}< / span > }"< / span > < span class = "hljs-keyword" > unless< / span > props.length < span class = "hljs-keyword" > is< / span > < span class = "hljs-number" > 0< / span >
< span class = "hljs-keyword" > if< / span > @front < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > hasDynamic < span class = "hljs-keyword" > then< / span > @wrapInBraces answer < span class = "hljs-keyword" > else< / span > answer
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
assigns: < span class = "hljs-function" > < span class = "hljs-params" > (name)< / span > -> < / span >
< span class = "hljs-keyword" > for< / span > prop < span class = "hljs-keyword" > in< / span > @properties < span class = "hljs-keyword" > when< / span > prop.assigns name < span class = "hljs-keyword" > then< / span > < span class = "hljs-keyword" > return< / span > < span class = "hljs-literal" > yes< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-literal" > no< / span > < / pre > < / div > < / div >
2013-03-18 01:06:33 -04:00
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-89" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-89" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "arr" > Arr< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-90" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-90" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
< p > An array literal.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Arr = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Arr< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (objs)< / span > -> < / span >
@objects = objs < span class = "hljs-keyword" > or< / span > []
2010-08-04 23:14:34 -04:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'objects'< / span > ]
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
< span class = "hljs-keyword" > return< / span > [@makeCode < span class = "hljs-string" > '[]'< / span > ] < span class = "hljs-keyword" > unless< / span > @objects.length
2013-03-18 01:06:33 -04:00
o.indent += TAB
2016-09-22 16:19:43 -04:00
answer = Splat.compileSplattedArray o, @objects
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > answer < span class = "hljs-keyword" > if< / span > answer.length
2013-03-04 14:19:08 -05:00
2013-03-18 01:06:33 -04:00
answer = []
2016-09-22 16:19:43 -04:00
compiledObjs = (obj.compileToFragments o, LEVEL_LIST < span class = "hljs-keyword" > for< / span > obj < span class = "hljs-keyword" > in< / span > @objects)
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > for< / span > fragments, index < span class = "hljs-keyword" > in< / span > compiledObjs
< span class = "hljs-keyword" > if< / span > index
2016-09-22 16:19:43 -04:00
answer.push @makeCode < span class = "hljs-string" > ", "< / span >
2013-03-18 01:06:33 -04:00
answer.push fragments...
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > fragmentsToText(answer).indexOf(< span class = "hljs-string" > '\n'< / span > ) > = < span class = "hljs-number" > 0< / span >
2016-09-22 16:19:43 -04:00
answer.unshift @makeCode < span class = "hljs-string" > "[\n< span class = "hljs-subst" > #{o.indent}< / span > "< / span >
answer.push @makeCode < span class = "hljs-string" > "\n< span class = "hljs-subst" > #{@tab}< / span > ]"< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
answer.unshift @makeCode < span class = "hljs-string" > "["< / span >
answer.push @makeCode < span class = "hljs-string" > "]"< / span >
2013-03-18 01:06:33 -04:00
answer
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
assigns: < span class = "hljs-function" > < span class = "hljs-params" > (name)< / span > -> < / span >
< span class = "hljs-keyword" > for< / span > obj < span class = "hljs-keyword" > in< / span > @objects < span class = "hljs-keyword" > when< / span > obj.assigns name < span class = "hljs-keyword" > then< / span > < span class = "hljs-keyword" > return< / span > < span class = "hljs-literal" > yes< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-literal" > no< / span > < / pre > < / div > < / div >
2013-06-02 01:37:45 -04:00
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-91" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-91" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "class" > Class< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-92" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-92" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
< p > The CoffeeScript class definition.
2010-12-24 14:02:10 -05:00
Initialize a < strong > Class< / strong > with its name, an optional superclass, and a
2014-01-29 23:54:00 -05:00
list of prototype property assignments.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Class = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Class< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@variable, @parent, @body = < span class = "hljs-keyword" > new< / span > Block)< / span > -> < / span >
@boundFuncs = []
@body.classBody = < span class = "hljs-literal" > yes< / span >
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'variable'< / span > , < span class = "hljs-string" > 'parent'< / span > , < span class = "hljs-string" > 'body'< / span > ]
defaultClassVariableName: < span class = "hljs-string" > '_Class'< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-93" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-93" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Figure out the appropriate name for the constructor function of this class.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > determineName: < span class = "hljs-function" > -> < / span >
< span class = "hljs-keyword" > return< / span > @defaultClassVariableName < span class = "hljs-keyword" > unless< / span > @variable
[..., tail] = @variable.properties
node = < span class = "hljs-keyword" > if< / span > tail
tail < span class = "hljs-keyword" > instanceof< / span > Access < span class = "hljs-keyword" > and< / span > tail.name
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
@variable.base
< span class = "hljs-keyword" > unless< / span > node < span class = "hljs-keyword" > instanceof< / span > IdentifierLiteral < span class = "hljs-keyword" > or< / span > node < span class = "hljs-keyword" > instanceof< / span > PropertyName
< span class = "hljs-keyword" > return< / span > @defaultClassVariableName
name = node.value
< span class = "hljs-keyword" > unless< / span > tail
message = isUnassignable name
@variable.error message < span class = "hljs-keyword" > if< / span > message
< span class = "hljs-keyword" > if< / span > name < span class = "hljs-keyword" > in< / span > JS_FORBIDDEN < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > "_< span class = "hljs-subst" > #{name}< / span > "< / span > < span class = "hljs-keyword" > else< / span > name< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-94" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-94" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > For all < code > this< / code > -references and bound functions in the class definition,
2014-01-29 23:54:00 -05:00
< code > this< / code > is the Class being constructed.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > setContext: < span class = "hljs-function" > < span class = "hljs-params" > (name)< / span > -> < / span >
@body.traverseChildren < span class = "hljs-literal" > false< / span > , < span class = "hljs-function" > < span class = "hljs-params" > (node)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > < span class = "hljs-literal" > false< / span > < span class = "hljs-keyword" > if< / span > node.classBody
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > node < span class = "hljs-keyword" > instanceof< / span > ThisLiteral
2013-03-18 01:06:33 -04:00
node.value = name
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > node < span class = "hljs-keyword" > instanceof< / span > Code
node.context = name < span class = "hljs-keyword" > if< / span > node.bound< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-95" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-95" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > Ensure that all functions bound to the instance are proxied in the
2014-01-29 23:54:00 -05:00
constructor.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > addBoundFunctions: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
< span class = "hljs-keyword" > for< / span > bvar < span class = "hljs-keyword" > in< / span > @boundFuncs
lhs = (< span class = "hljs-keyword" > new< / span > Value (< span class = "hljs-keyword" > new< / span > ThisLiteral), [< span class = "hljs-keyword" > new< / span > Access bvar]).compile o
@ctor.body.unshift < span class = "hljs-keyword" > new< / span > Literal < span class = "hljs-string" > "< span class = "hljs-subst" > #{lhs}< / span > = < span class = "hljs-subst" > #{utility < span class = "hljs-string" > 'bind'< / span > , o}< / span > (< span class = "hljs-subst" > #{lhs}< / span > , this)"< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-96" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-96" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > Merge the properties from a top-level object as prototypal properties
2014-01-29 23:54:00 -05:00
on the class.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > addProperties: < span class = "hljs-function" > < span class = "hljs-params" > (node, name, o)< / span > -> < / span >
2013-03-18 01:06:33 -04:00
props = node.base.properties[..]
2014-01-29 23:54:00 -05:00
exprs = < span class = "hljs-keyword" > while< / span > assign = props.shift()
< span class = "hljs-keyword" > if< / span > assign < span class = "hljs-keyword" > instanceof< / span > Assign
2013-03-18 01:06:33 -04:00
base = assign.variable.base
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > delete< / span > assign.context
2013-03-18 01:06:33 -04:00
func = assign.value
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > base.value < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > 'constructor'< / span >
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > @ctor
2014-01-29 23:54:00 -05:00
assign.error < span class = "hljs-string" > 'cannot define more than one constructor in a class'< / span >
< span class = "hljs-keyword" > if< / span > func.bound
assign.error < span class = "hljs-string" > 'cannot define a constructor as a bound function'< / span >
< span class = "hljs-keyword" > if< / span > func < span class = "hljs-keyword" > instanceof< / span > Code
2016-09-22 16:19:43 -04:00
assign = @ctor = func
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
@externalCtor = o.classScope.freeVariable < span class = "hljs-string" > 'ctor'< / span >
assign = < span class = "hljs-keyword" > new< / span > Assign < span class = "hljs-keyword" > new< / span > IdentifierLiteral(@externalCtor), func
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
< span class = "hljs-keyword" > if< / span > assign.variable.< span class = "hljs-keyword" > this< / span >
func.static = < span class = "hljs-literal" > yes< / span >
< span class = "hljs-keyword" > else< / span >
2015-02-18 15:43:33 -05:00
acc = < span class = "hljs-keyword" > if< / span > base.isComplex() < span class = "hljs-keyword" > then< / span > < span class = "hljs-keyword" > new< / span > Index base < span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > new< / span > Access base
2016-09-22 16:19:43 -04:00
assign.variable = < span class = "hljs-keyword" > new< / span > Value(< span class = "hljs-keyword" > new< / span > IdentifierLiteral(name), [(< span class = "hljs-keyword" > new< / span > Access < span class = "hljs-keyword" > new< / span > PropertyName < span class = "hljs-string" > 'prototype'< / span > ), acc])
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > func < span class = "hljs-keyword" > instanceof< / span > Code < span class = "hljs-keyword" > and< / span > func.bound
2016-09-22 16:19:43 -04:00
@boundFuncs.push base
2014-01-29 23:54:00 -05:00
func.bound = < span class = "hljs-literal" > no< / span >
2013-03-18 01:06:33 -04:00
assign
compact exprs< / pre > < / div > < / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-97" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-97" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Walk the body of the class, looking for prototype properties to be converted
and tagging static assignments.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > walkBody: < span class = "hljs-function" > < span class = "hljs-params" > (name, o)< / span > -> < / span >
@traverseChildren < span class = "hljs-literal" > false< / span > , < span class = "hljs-function" > < span class = "hljs-params" > (child)< / span > => < / span >
2014-01-29 23:54:00 -05:00
cont = < span class = "hljs-literal" > true< / span >
< span class = "hljs-keyword" > return< / span > < span class = "hljs-literal" > false< / span > < span class = "hljs-keyword" > if< / span > child < span class = "hljs-keyword" > instanceof< / span > Class
< span class = "hljs-keyword" > if< / span > child < span class = "hljs-keyword" > instanceof< / span > Block
< span class = "hljs-keyword" > for< / span > node, i < span class = "hljs-keyword" > in< / span > exps = child.expressions
< span class = "hljs-keyword" > if< / span > node < span class = "hljs-keyword" > instanceof< / span > Assign < span class = "hljs-keyword" > and< / span > node.variable.looksStatic name
node.value.static = < span class = "hljs-literal" > yes< / span >
< span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > node < span class = "hljs-keyword" > instanceof< / span > Value < span class = "hljs-keyword" > and< / span > node.isObject(< span class = "hljs-literal" > true< / span > )
cont = < span class = "hljs-literal" > false< / span >
2016-09-22 16:19:43 -04:00
exps[i] = @addProperties node, name, o
2013-03-18 01:06:33 -04:00
child.expressions = exps = flatten exps
2014-01-29 23:54:00 -05:00
cont < span class = "hljs-keyword" > and< / span > child < span class = "hljs-keyword" > not< / span > < span class = "hljs-keyword" > instanceof< / span > Class< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-98" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-98" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > < code > use strict< / code > (and other directives) must be the first expression statement(s)
2012-04-10 14:57:45 -04:00
of a function body. This method ensures the prologue is correctly positioned
2014-01-29 23:54:00 -05:00
above the < code > constructor< / code > .< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > hoistDirectivePrologue: < span class = "hljs-function" > -> < / span >
2014-01-29 23:54:00 -05:00
index = < span class = "hljs-number" > 0< / span >
2016-09-22 16:19:43 -04:00
{expressions} = @body
2014-01-29 23:54:00 -05:00
++index < span class = "hljs-keyword" > while< / span > (node = expressions[index]) < span class = "hljs-keyword" > and< / span > node < span class = "hljs-keyword" > instanceof< / span > Comment < span class = "hljs-keyword" > or< / span >
node < span class = "hljs-keyword" > instanceof< / span > Value < span class = "hljs-keyword" > and< / span > node.isString()
2016-09-22 16:19:43 -04:00
@directives = expressions.splice < span class = "hljs-number" > 0< / span > , index< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-99" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-99" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > Make sure that a constructor is defined for the class, and properly
2014-01-29 23:54:00 -05:00
configured.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > ensureConstructor: < span class = "hljs-function" > < span class = "hljs-params" > (name)< / span > -> < / span >
< span class = "hljs-keyword" > if< / span > < span class = "hljs-keyword" > not< / span > @ctor
@ctor = < span class = "hljs-keyword" > new< / span > Code
< span class = "hljs-keyword" > if< / span > @externalCtor
@ctor.body.push < span class = "hljs-keyword" > new< / span > Literal < span class = "hljs-string" > "< span class = "hljs-subst" > #{@externalCtor}< / span > .apply(this, arguments)"< / span >
< span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > @parent
@ctor.body.push < span class = "hljs-keyword" > new< / span > Literal < span class = "hljs-string" > "< span class = "hljs-subst" > #{name}< / span > .__super__.constructor.apply(this, arguments)"< / span >
@ctor.body.makeReturn()
@body.expressions.unshift @ctor
@ctor.ctor = @ctor.name = name
@ctor.klass = < span class = "hljs-literal" > null< / span >
@ctor.noReturn = < span class = "hljs-literal" > yes< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-100" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-100" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > Instead of generating the JavaScript string directly, we build up the
2010-12-24 14:02:10 -05:00
equivalent syntax tree and compile that, in pieces. You can see the
2014-01-29 23:54:00 -05:00
constructor, property assignments, and inheritance getting built out below.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
< span class = "hljs-keyword" > if< / span > jumpNode = @body.jumps()
2014-01-29 23:54:00 -05:00
jumpNode.error < span class = "hljs-string" > 'Class bodies cannot contain pure statements'< / span >
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > argumentsNode = @body.contains isLiteralArguments
2014-01-29 23:54:00 -05:00
argumentsNode.error < span class = "hljs-string" > "Class bodies shouldn't reference arguments"< / span >
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
name = @determineName()
lname = < span class = "hljs-keyword" > new< / span > IdentifierLiteral name
func = < span class = "hljs-keyword" > new< / span > Code [], Block.wrap [@body]
2014-01-29 23:54:00 -05:00
args = []
o.classScope = func.makeScope o.scope
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
@hoistDirectivePrologue()
@setContext name
@walkBody name, o
@ensureConstructor name
@addBoundFunctions o
@body.spaced = < span class = "hljs-literal" > yes< / span >
@body.expressions.push lname
< span class = "hljs-keyword" > if< / span > @parent
superClass = < span class = "hljs-keyword" > new< / span > IdentifierLiteral o.classScope.freeVariable < span class = "hljs-string" > 'superClass'< / span > , reserve: < span class = "hljs-literal" > no< / span >
@body.expressions.unshift < span class = "hljs-keyword" > new< / span > Extends lname, superClass
2014-01-29 23:54:00 -05:00
func.params.push < span class = "hljs-keyword" > new< / span > Param superClass
2016-09-22 16:19:43 -04:00
args.push @parent
2012-04-10 14:57:45 -04:00
2016-09-22 16:19:43 -04:00
@body.expressions.unshift @directives...
2013-06-02 01:37:45 -04:00
2014-01-29 23:54:00 -05:00
klass = < span class = "hljs-keyword" > new< / span > Parens < span class = "hljs-keyword" > new< / span > Call func, args
2016-09-22 16:19:43 -04:00
klass = < span class = "hljs-keyword" > new< / span > Assign @variable, klass, < span class = "hljs-literal" > null< / span > , { @moduleDeclaration } < span class = "hljs-keyword" > if< / span > @variable
2014-01-29 23:54:00 -05:00
klass.compileToFragments o< / pre > < / div > < / div >
2013-06-02 01:37:45 -04:00
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-101" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-101" > ¶ < / a >
< / div >
< h3 id = "import-and-export" > Import and Export< / h3 >
< / div >
< div class = "content" > < div class = 'highlight' > < pre >
exports.ModuleDeclaration = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > ModuleDeclaration< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@clause, @source)< / span > -> < / span >
@checkSource()
children: [< span class = "hljs-string" > 'clause'< / span > , < span class = "hljs-string" > 'source'< / span > ]
isStatement: YES
jumps: THIS
makeReturn: THIS
checkSource: < span class = "hljs-function" > -> < / span >
< span class = "hljs-keyword" > if< / span > @source? < span class = "hljs-keyword" > and< / span > @source < span class = "hljs-keyword" > instanceof< / span > StringWithInterpolations
@source.error < span class = "hljs-string" > 'the name of the module to be imported from must be an uninterpolated string'< / span >
checkScope: < span class = "hljs-function" > < span class = "hljs-params" > (o, moduleDeclarationType)< / span > -> < / span >
< span class = "hljs-keyword" > if< / span > o.indent.length < span class = "hljs-keyword" > isnt< / span > < span class = "hljs-number" > 0< / span >
@error < span class = "hljs-string" > "< span class = "hljs-subst" > #{moduleDeclarationType}< / span > statements must be at top-level scope"< / span >
exports.ImportDeclaration = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > ImportDeclaration< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > ModuleDeclaration< / span > < / span >
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
@checkScope o, < span class = "hljs-string" > 'import'< / span >
o.importedSymbols = []
code = []
code.push @makeCode < span class = "hljs-string" > "< span class = "hljs-subst" > #{@tab}< / span > import "< / span >
code.push @clause.compileNode(o)... < span class = "hljs-keyword" > if< / span > @clause?
< span class = "hljs-keyword" > if< / span > @source?.value?
code.push @makeCode < span class = "hljs-string" > ' from '< / span > < span class = "hljs-keyword" > unless< / span > @clause < span class = "hljs-keyword" > is< / span > < span class = "hljs-literal" > null< / span >
code.push @makeCode @source.value
code.push @makeCode < span class = "hljs-string" > ';'< / span >
code
exports.ImportClause = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > ImportClause< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@defaultBinding, @namedImports)< / span > -> < / span >
children: [< span class = "hljs-string" > 'defaultBinding'< / span > , < span class = "hljs-string" > 'namedImports'< / span > ]
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
code = []
< span class = "hljs-keyword" > if< / span > @defaultBinding?
code.push @defaultBinding.compileNode(o)...
code.push @makeCode < span class = "hljs-string" > ', '< / span > < span class = "hljs-keyword" > if< / span > @namedImports?
< span class = "hljs-keyword" > if< / span > @namedImports?
code.push @namedImports.compileNode(o)...
code
exports.ExportDeclaration = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > ExportDeclaration< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > ModuleDeclaration< / span > < / span >
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
@checkScope o, < span class = "hljs-string" > 'export'< / span >
code = []
code.push @makeCode < span class = "hljs-string" > "< span class = "hljs-subst" > #{@tab}< / span > export "< / span >
code.push @makeCode < span class = "hljs-string" > 'default '< / span > < span class = "hljs-keyword" > if< / span > @ < span class = "hljs-keyword" > instanceof< / span > ExportDefaultDeclaration
< span class = "hljs-keyword" > if< / span > @ < span class = "hljs-keyword" > not< / span > < span class = "hljs-keyword" > instanceof< / span > ExportDefaultDeclaration < span class = "hljs-keyword" > and< / span >
(@clause < span class = "hljs-keyword" > instanceof< / span > Assign < span class = "hljs-keyword" > or< / span > @clause < span class = "hljs-keyword" > instanceof< / span > Class)< / pre > < / div > < / div >
< / li >
< li id = "section-102" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-102" > ¶ < / a >
< / div >
< p > When the ES2015 < code > class< / code > keyword is supported, don’ t add a < code > var< / code > here< / p >
< / div >
< div class = "content" > < div class = 'highlight' > < pre > code.push @makeCode < span class = "hljs-string" > 'var '< / span >
@clause.moduleDeclaration = < span class = "hljs-string" > 'export'< / span >
< span class = "hljs-keyword" > if< / span > @clause.body? < span class = "hljs-keyword" > and< / span > @clause.body < span class = "hljs-keyword" > instanceof< / span > Block
code = code.concat @clause.compileToFragments o, LEVEL_TOP
< span class = "hljs-keyword" > else< / span >
code = code.concat @clause.compileNode o
code.push @makeCode < span class = "hljs-string" > " from < span class = "hljs-subst" > #{@source.value}< / span > "< / span > < span class = "hljs-keyword" > if< / span > @source?.value?
code.push @makeCode < span class = "hljs-string" > ';'< / span >
code
exports.ExportNamedDeclaration = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > ExportNamedDeclaration< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > ExportDeclaration< / span > < / span >
exports.ExportDefaultDeclaration = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > ExportDefaultDeclaration< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > ExportDeclaration< / span > < / span >
exports.ExportAllDeclaration = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > ExportAllDeclaration< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > ExportDeclaration< / span > < / span >
exports.ModuleSpecifierList = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > ModuleSpecifierList< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@specifiers)< / span > -> < / span >
children: [< span class = "hljs-string" > 'specifiers'< / span > ]
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
code = []
o.indent += TAB
compiledList = (specifier.compileToFragments o, LEVEL_LIST < span class = "hljs-keyword" > for< / span > specifier < span class = "hljs-keyword" > in< / span > @specifiers)
< span class = "hljs-keyword" > if< / span > @specifiers.length < span class = "hljs-keyword" > isnt< / span > < span class = "hljs-number" > 0< / span >
code.push @makeCode < span class = "hljs-string" > "{\n< span class = "hljs-subst" > #{o.indent}< / span > "< / span >
< span class = "hljs-keyword" > for< / span > fragments, index < span class = "hljs-keyword" > in< / span > compiledList
code.push @makeCode(< span class = "hljs-string" > ",\n< span class = "hljs-subst" > #{o.indent}< / span > "< / span > ) < span class = "hljs-keyword" > if< / span > index
code.push fragments...
code.push @makeCode < span class = "hljs-string" > "\n}"< / span >
< span class = "hljs-keyword" > else< / span >
code.push @makeCode < span class = "hljs-string" > '{}'< / span >
code
exports.ImportSpecifierList = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > ImportSpecifierList< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > ModuleSpecifierList< / span > < / span >
exports.ExportSpecifierList = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > ExportSpecifierList< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > ModuleSpecifierList< / span > < / span >
exports.ModuleSpecifier = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > ModuleSpecifier< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@original, @alias, @moduleDeclarationType)< / span > -> < / span > < / pre > < / div > < / div >
< / li >
< li id = "section-103" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-103" > ¶ < / a >
< / div >
< p > The name of the variable entering the local scope< / p >
< / div >
< div class = "content" > < div class = 'highlight' > < pre > @identifier = < span class = "hljs-keyword" > if< / span > @alias? < span class = "hljs-keyword" > then< / span > @alias.value < span class = "hljs-keyword" > else< / span > @original.value
children: [< span class = "hljs-string" > 'original'< / span > , < span class = "hljs-string" > 'alias'< / span > ]
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
o.scope.add @identifier, @moduleDeclarationType
code = []
code.push @makeCode @original.value
code.push @makeCode < span class = "hljs-string" > " as < span class = "hljs-subst" > #{@alias.value}< / span > "< / span > < span class = "hljs-keyword" > if< / span > @alias?
code
exports.ImportSpecifier = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > ImportSpecifier< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > ModuleSpecifier< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (imported, local)< / span > -> < / span >
< span class = "hljs-keyword" > super< / span > imported, local, < span class = "hljs-string" > 'import'< / span >
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span > < / pre > < / div > < / div >
< / li >
< li id = "section-104" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-104" > ¶ < / a >
< / div >
< p > Per the spec, symbols can’ t be imported multiple times
(e.g. < code > import { foo, foo } from ' lib' < / code > is invalid)< / p >
< / div >
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-keyword" > if< / span > @identifier < span class = "hljs-keyword" > in< / span > o.importedSymbols < span class = "hljs-keyword" > or< / span > o.scope.check(@identifier)
@error < span class = "hljs-string" > "'< span class = "hljs-subst" > #{@identifier}< / span > ' has already been declared"< / span >
< span class = "hljs-keyword" > else< / span >
o.importedSymbols.push @identifier
< span class = "hljs-keyword" > super< / span > o
exports.ImportDefaultSpecifier = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > ImportDefaultSpecifier< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > ImportSpecifier< / span > < / span >
exports.ImportNamespaceSpecifier = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > ImportNamespaceSpecifier< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > ImportSpecifier< / span > < / span >
exports.ExportSpecifier = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > ExportSpecifier< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > ModuleSpecifier< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (local, exported)< / span > -> < / span >
< span class = "hljs-keyword" > super< / span > local, exported, < span class = "hljs-string" > 'export'< / span > < / pre > < / div > < / div >
< / li >
< li id = "section-105" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-105" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "assign" > Assign< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-106" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-106" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
< p > The < strong > Assign< / strong > is used to assign a local variable to value, or to set the
2016-09-22 16:19:43 -04:00
property of an object – including within object literals.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Assign = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Assign< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@variable, @value, @context, options = {})< / span > -> < / span >
{@param, @subpattern, @operatorToken, @moduleDeclaration} = options
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'variable'< / span > , < span class = "hljs-string" > 'value'< / span > ]
2010-06-28 00:19:58 -04:00
2016-09-22 16:19:43 -04:00
isStatement: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
o?.level < span class = "hljs-keyword" > is< / span > LEVEL_TOP < span class = "hljs-keyword" > and< / span > @context? < span class = "hljs-keyword" > and< / span > (@moduleDeclaration < span class = "hljs-keyword" > or< / span > < span class = "hljs-string" > "?"< / span > < span class = "hljs-keyword" > in< / span > @context)
2011-08-04 23:17:23 -04:00
2016-09-22 16:19:43 -04:00
checkAssignability: < span class = "hljs-function" > < span class = "hljs-params" > (o, varBase)< / span > -> < / span >
< span class = "hljs-keyword" > if< / span > Object::hasOwnProperty.call(o.scope.positions, varBase.value) < span class = "hljs-keyword" > and< / span >
o.scope.variables[o.scope.positions[varBase.value]].type < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > 'import'< / span >
varBase.error < span class = "hljs-string" > "'< span class = "hljs-subst" > #{varBase.value}< / span > ' is read-only"< / span >
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
assigns: < span class = "hljs-function" > < span class = "hljs-params" > (name)< / span > -> < / span >
@[< span class = "hljs-keyword" > if< / span > @context < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > 'object'< / span > < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > 'value'< / span > < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > 'variable'< / span > ].assigns name
unfoldSoak: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
unfoldSoak o, < span class = "hljs-keyword" > this< / span > , < span class = "hljs-string" > 'variable'< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-107" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-107" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > Compile an assignment, delegating to < code > compilePatternMatch< / code > or
2010-12-24 14:02:10 -05:00
< code > compileSplice< / code > if appropriate. Keep track of the name of the base object
2014-08-23 10:08:39 -04:00
we’ ve been assigned to, for correct internal references. If the variable
2014-01-29 23:54:00 -05:00
has not been seen yet within the current scope, declare it.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
< span class = "hljs-keyword" > if< / span > isValue = @variable < span class = "hljs-keyword" > instanceof< / span > Value
< span class = "hljs-keyword" > return< / span > @compilePatternMatch o < span class = "hljs-keyword" > if< / span > @variable.isArray() < span class = "hljs-keyword" > or< / span > @variable.isObject()
< span class = "hljs-keyword" > return< / span > @compileSplice o < span class = "hljs-keyword" > if< / span > @variable.isSplice()
< span class = "hljs-keyword" > return< / span > @compileConditional o < span class = "hljs-keyword" > if< / span > @context < span class = "hljs-keyword" > in< / span > [< span class = "hljs-string" > '||='< / span > , < span class = "hljs-string" > '& & ='< / span > , < span class = "hljs-string" > '?='< / span > ]
< span class = "hljs-keyword" > return< / span > @compileSpecialMath o < span class = "hljs-keyword" > if< / span > @context < span class = "hljs-keyword" > in< / span > [< span class = "hljs-string" > '**='< / span > , < span class = "hljs-string" > '//='< / span > , < span class = "hljs-string" > '%%='< / span > ]
< span class = "hljs-keyword" > if< / span > @value < span class = "hljs-keyword" > instanceof< / span > Code
< span class = "hljs-keyword" > if< / span > @value.static
@value.klass = @variable.base
@value.name = @variable.properties[< span class = "hljs-number" > 0< / span > ]
@value.variable = @variable
< span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > @variable.properties?.length > = < span class = "hljs-number" > 2< / span >
[properties..., prototype, name] = @variable.properties
2015-02-18 15:43:33 -05:00
< span class = "hljs-keyword" > if< / span > prototype.name?.value < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > 'prototype'< / span >
2016-09-22 16:19:43 -04:00
@value.klass = < span class = "hljs-keyword" > new< / span > Value @variable.base, properties
@value.name = name
@value.variable = @variable
< span class = "hljs-keyword" > unless< / span > @context
varBase = @variable.unwrapAll()
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > unless< / span > varBase.isAssignable()
2016-09-22 16:19:43 -04:00
@variable.error < span class = "hljs-string" > "'< span class = "hljs-subst" > #{@variable.compile o}< / span > ' can't be assigned"< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > unless< / span > varBase.hasProperties?()
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > @moduleDeclaration < span class = "hljs-comment" > # `moduleDeclaration` can be `'import'` or `'export'`< / span >
@checkAssignability o, varBase
o.scope.add varBase.value, @moduleDeclaration
< span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > @param
2015-02-18 15:43:33 -05:00
o.scope.add varBase.value, < span class = "hljs-string" > 'var'< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
@checkAssignability o, varBase
2015-02-18 15:43:33 -05:00
o.scope.find varBase.value
2016-09-22 16:19:43 -04:00
val = @value.compileToFragments o, LEVEL_LIST
@variable.front = < span class = "hljs-literal" > true< / span > < span class = "hljs-keyword" > if< / span > isValue < span class = "hljs-keyword" > and< / span > @variable.base < span class = "hljs-keyword" > instanceof< / span > Obj
compiledName = @variable.compileToFragments o, LEVEL_LIST
< span class = "hljs-keyword" > if< / span > @context < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > 'object'< / span >
< span class = "hljs-keyword" > if< / span > fragmentsToText(compiledName) < span class = "hljs-keyword" > in< / span > JS_FORBIDDEN
compiledName.unshift @makeCode < span class = "hljs-string" > '"'< / span >
compiledName.push @makeCode < span class = "hljs-string" > '"'< / span >
< span class = "hljs-keyword" > return< / span > compiledName.concat @makeCode(< span class = "hljs-string" > ": "< / span > ), val
answer = compiledName.concat @makeCode(< span class = "hljs-string" > " < span class = "hljs-subst" > #{ @context < span class = "hljs-keyword" > or< / span > < span class = "hljs-string" > '='< / span > }< / span > "< / span > ), val
< span class = "hljs-keyword" > if< / span > o.level < = LEVEL_LIST < span class = "hljs-keyword" > then< / span > answer < span class = "hljs-keyword" > else< / span > @wrapInBraces answer< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-108" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-108" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > Brief implementation of recursive pattern matching, when assigning array or
2015-09-03 12:37:36 -04:00
object literals to a value. Peeks at their properties to assign inner names.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compilePatternMatch: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
top = o.level < span class = "hljs-keyword" > is< / span > LEVEL_TOP
{value} = < span class = "hljs-keyword" > this< / span >
2016-09-22 16:19:43 -04:00
{objects} = @variable.base
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > unless< / span > olen = objects.length
2013-03-18 01:06:33 -04:00
code = value.compileToFragments o
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > return< / span > < span class = "hljs-keyword" > if< / span > o.level > = LEVEL_OP < span class = "hljs-keyword" > then< / span > @wrapInBraces code < span class = "hljs-keyword" > else< / span > code
2015-09-03 12:37:36 -04:00
[obj] = objects
< span class = "hljs-keyword" > if< / span > olen < span class = "hljs-keyword" > is< / span > < span class = "hljs-number" > 1< / span > < span class = "hljs-keyword" > and< / span > obj < span class = "hljs-keyword" > instanceof< / span > Expansion
obj.error < span class = "hljs-string" > 'Destructuring assignment has no target'< / span >
2016-09-22 16:19:43 -04:00
isObject = @variable.isObject()
2015-09-03 12:37:36 -04:00
< span class = "hljs-keyword" > if< / span > top < span class = "hljs-keyword" > and< / span > olen < span class = "hljs-keyword" > is< / span > < span class = "hljs-number" > 1< / span > < span class = "hljs-keyword" > and< / span > obj < span class = "hljs-keyword" > not< / span > < span class = "hljs-keyword" > instanceof< / span > Splat< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-109" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-109" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2015-09-03 12:37:36 -04:00
< p > Pick the property straight off the value when there’ s just one to pick
(no need to cache the value into a variable).< / p >
2014-01-29 23:54:00 -05:00
< / div >
2015-09-03 12:37:36 -04:00
< div class = "content" > < div class = 'highlight' > < pre > defaultValue = < span class = "hljs-literal" > null< / span >
< span class = "hljs-keyword" > if< / span > obj < span class = "hljs-keyword" > instanceof< / span > Assign < span class = "hljs-keyword" > and< / span > obj.context < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > 'object'< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-110" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-110" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2015-09-03 12:37:36 -04:00
< p > A regular object pattern-match.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > {variable: {base: idx}, value: obj} = obj
2015-09-03 12:37:36 -04:00
< span class = "hljs-keyword" > if< / span > obj < span class = "hljs-keyword" > instanceof< / span > Assign
defaultValue = obj.value
obj = obj.variable
< span class = "hljs-keyword" > else< / span >
< span class = "hljs-keyword" > if< / span > obj < span class = "hljs-keyword" > instanceof< / span > Assign
defaultValue = obj.value
obj = obj.variable
idx = < span class = "hljs-keyword" > if< / span > isObject< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-111" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-111" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2015-09-03 12:37:36 -04:00
< p > A shorthand < code > {a, b, @c} = val< / code > pattern-match.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-keyword" > if< / span > obj.< span class = "hljs-keyword" > this< / span >
obj.properties[< span class = "hljs-number" > 0< / span > ].name
< span class = "hljs-keyword" > else< / span >
< span class = "hljs-keyword" > new< / span > PropertyName obj.unwrap().value
2015-09-03 12:37:36 -04:00
< span class = "hljs-keyword" > else< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-112" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-112" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2015-09-03 12:37:36 -04:00
< p > A regular array pattern-match.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-keyword" > new< / span > NumberLiteral < span class = "hljs-number" > 0< / span >
acc = idx.unwrap() < span class = "hljs-keyword" > instanceof< / span > PropertyName
2015-09-03 12:37:36 -04:00
value = < span class = "hljs-keyword" > new< / span > Value value
value.properties.push < span class = "hljs-keyword" > new< / span > (< span class = "hljs-keyword" > if< / span > acc < span class = "hljs-keyword" > then< / span > Access < span class = "hljs-keyword" > else< / span > Index) idx
2016-09-22 16:19:43 -04:00
message = isUnassignable obj.unwrap().value
obj.error message < span class = "hljs-keyword" > if< / span > message
2015-09-03 12:37:36 -04:00
value = < span class = "hljs-keyword" > new< / span > Op < span class = "hljs-string" > '?'< / span > , value, defaultValue < span class = "hljs-keyword" > if< / span > defaultValue
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > return< / span > < span class = "hljs-keyword" > new< / span > Assign(obj, value, < span class = "hljs-literal" > null< / span > , param: @param).compileToFragments o, LEVEL_TOP
2015-09-03 12:37:36 -04:00
vvar = value.compileToFragments o, LEVEL_LIST
vvarText = fragmentsToText vvar
assigns = []
expandedIdx = < span class = "hljs-literal" > false< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-113" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-113" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2015-09-03 12:37:36 -04:00
< p > Make vvar into a simple variable if it isn’ t already.< / p >
2013-03-18 01:06:33 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-keyword" > if< / span > value.unwrap() < span class = "hljs-keyword" > not< / span > < span class = "hljs-keyword" > instanceof< / span > IdentifierLiteral < span class = "hljs-keyword" > or< / span > @variable.assigns(vvarText)
assigns.push [@makeCode(< span class = "hljs-string" > "< span class = "hljs-subst" > #{ ref = o.scope.freeVariable < span class = "hljs-string" > 'ref'< / span > }< / span > = "< / span > ), vvar...]
vvar = [@makeCode ref]
2015-09-03 12:37:36 -04:00
vvarText = ref
< span class = "hljs-keyword" > for< / span > obj, i < span class = "hljs-keyword" > in< / span > objects
idx = i
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > < span class = "hljs-keyword" > not< / span > expandedIdx < span class = "hljs-keyword" > and< / span > obj < span class = "hljs-keyword" > instanceof< / span > Splat
2013-03-18 01:06:33 -04:00
name = obj.name.unwrap().value
obj = obj.unwrap()
2015-01-29 12:20:46 -05:00
val = < span class = "hljs-string" > "< span class = "hljs-subst" > #{olen}< / span > < = < span class = "hljs-subst" > #{vvarText}< / span > .length ? < span class = "hljs-subst" > #{ utility < span class = "hljs-string" > 'slice'< / span > , o }< / span > .call(< span class = "hljs-subst" > #{vvarText}< / span > , < span class = "hljs-subst" > #{i}< / span > "< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > rest = olen - i - < span class = "hljs-number" > 1< / span >
2016-09-22 16:19:43 -04:00
ivar = o.scope.freeVariable < span class = "hljs-string" > 'i'< / span > , single: < span class = "hljs-literal" > true< / span >
2014-01-29 23:54:00 -05:00
val += < span class = "hljs-string" > ", < span class = "hljs-subst" > #{ivar}< / span > = < span class = "hljs-subst" > #{vvarText}< / span > .length - < span class = "hljs-subst" > #{rest}< / span > ) : (< span class = "hljs-subst" > #{ivar}< / span > = < span class = "hljs-subst" > #{i}< / span > , [])"< / span >
< span class = "hljs-keyword" > else< / span >
val += < span class = "hljs-string" > ") : []"< / span >
val = < span class = "hljs-keyword" > new< / span > Literal val
expandedIdx = < span class = "hljs-string" > "< span class = "hljs-subst" > #{ivar}< / span > ++"< / span >
< span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > < span class = "hljs-keyword" > not< / span > expandedIdx < span class = "hljs-keyword" > and< / span > obj < span class = "hljs-keyword" > instanceof< / span > Expansion
< span class = "hljs-keyword" > if< / span > rest = olen - i - < span class = "hljs-number" > 1< / span >
< span class = "hljs-keyword" > if< / span > rest < span class = "hljs-keyword" > is< / span > < span class = "hljs-number" > 1< / span >
expandedIdx = < span class = "hljs-string" > "< span class = "hljs-subst" > #{vvarText}< / span > .length - 1"< / span >
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
ivar = o.scope.freeVariable < span class = "hljs-string" > 'i'< / span > , single: < span class = "hljs-literal" > true< / span >
2014-01-29 23:54:00 -05:00
val = < span class = "hljs-keyword" > new< / span > Literal < span class = "hljs-string" > "< span class = "hljs-subst" > #{ivar}< / span > = < span class = "hljs-subst" > #{vvarText}< / span > .length - < span class = "hljs-subst" > #{rest}< / span > "< / span >
expandedIdx = < span class = "hljs-string" > "< span class = "hljs-subst" > #{ivar}< / span > ++"< / span >
assigns.push val.compileToFragments o, LEVEL_LIST
< span class = "hljs-keyword" > continue< / span >
< span class = "hljs-keyword" > else< / span >
< span class = "hljs-keyword" > if< / span > obj < span class = "hljs-keyword" > instanceof< / span > Splat < span class = "hljs-keyword" > or< / span > obj < span class = "hljs-keyword" > instanceof< / span > Expansion
obj.error < span class = "hljs-string" > "multiple splats/expansions are disallowed in an assignment"< / span >
2015-09-03 12:37:36 -04:00
defaultValue = < span class = "hljs-literal" > null< / span >
< span class = "hljs-keyword" > if< / span > obj < span class = "hljs-keyword" > instanceof< / span > Assign < span class = "hljs-keyword" > and< / span > obj.context < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > 'object'< / span > < / pre > < / div > < / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-114" >
2015-09-03 12:37:36 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-114" > ¶ < / a >
2015-09-03 12:37:36 -04:00
< / div >
< p > A regular object pattern-match.< / p >
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > {variable: {base: idx}, value: obj} = obj
2015-09-03 12:37:36 -04:00
< span class = "hljs-keyword" > if< / span > obj < span class = "hljs-keyword" > instanceof< / span > Assign
defaultValue = obj.value
obj = obj.variable
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2015-09-03 12:37:36 -04:00
< span class = "hljs-keyword" > if< / span > obj < span class = "hljs-keyword" > instanceof< / span > Assign
defaultValue = obj.value
obj = obj.variable
idx = < span class = "hljs-keyword" > if< / span > isObject< / pre > < / div > < / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-115" >
2015-09-03 12:37:36 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-115" > ¶ < / a >
2015-09-03 12:37:36 -04:00
< / div >
< p > A shorthand < code > {a, b, @c} = val< / code > pattern-match.< / p >
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-keyword" > if< / span > obj.< span class = "hljs-keyword" > this< / span >
obj.properties[< span class = "hljs-number" > 0< / span > ].name
< span class = "hljs-keyword" > else< / span >
< span class = "hljs-keyword" > new< / span > PropertyName obj.unwrap().value
2015-09-03 12:37:36 -04:00
< span class = "hljs-keyword" > else< / span > < / pre > < / div > < / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-116" >
2015-09-03 12:37:36 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-116" > ¶ < / a >
2015-09-03 12:37:36 -04:00
< / div >
< p > A regular array pattern-match.< / p >
< / div >
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-keyword" > new< / span > Literal expandedIdx < span class = "hljs-keyword" > or< / span > idx
name = obj.unwrap().value
2016-09-22 16:19:43 -04:00
acc = idx.unwrap() < span class = "hljs-keyword" > instanceof< / span > PropertyName
2014-01-29 23:54:00 -05:00
val = < span class = "hljs-keyword" > new< / span > Value < span class = "hljs-keyword" > new< / span > Literal(vvarText), [< span class = "hljs-keyword" > new< / span > (< span class = "hljs-keyword" > if< / span > acc < span class = "hljs-keyword" > then< / span > Access < span class = "hljs-keyword" > else< / span > Index) idx]
2015-09-03 12:37:36 -04:00
val = < span class = "hljs-keyword" > new< / span > Op < span class = "hljs-string" > '?'< / span > , val, defaultValue < span class = "hljs-keyword" > if< / span > defaultValue
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > name?
message = isUnassignable name
obj.error message < span class = "hljs-keyword" > if< / span > message
assigns.push < span class = "hljs-keyword" > new< / span > Assign(obj, val, < span class = "hljs-literal" > null< / span > , param: @param, subpattern: < span class = "hljs-literal" > yes< / span > ).compileToFragments o, LEVEL_LIST
assigns.push vvar < span class = "hljs-keyword" > unless< / span > top < span class = "hljs-keyword" > or< / span > @subpattern
fragments = @joinFragmentArrays assigns, < span class = "hljs-string" > ', '< / span >
< span class = "hljs-keyword" > if< / span > o.level < LEVEL_LIST < span class = "hljs-keyword" > then< / span > fragments < span class = "hljs-keyword" > else< / span > @wrapInBraces fragments< / pre > < / div > < / div >
2013-03-18 01:06:33 -04:00
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-117" >
2013-03-18 01:06:33 -04:00
< div class = "annotation" >
2013-03-10 23:37:22 -04:00
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-117" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > When compiling a conditional assignment, take care to ensure that the
2010-11-20 14:22:28 -05:00
operands are only evaluated once, even though we have to reference them
2014-01-29 23:54:00 -05:00
more than once.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileConditional: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
[left, right] = @variable.cacheReference o< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-118" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-118" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Disallow conditional assignment of undefined variables.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-keyword" > if< / span > < span class = "hljs-keyword" > not< / span > left.properties.length < span class = "hljs-keyword" > and< / span > left.base < span class = "hljs-keyword" > instanceof< / span > Literal < span class = "hljs-keyword" > and< / span >
2016-09-22 16:19:43 -04:00
left.base < span class = "hljs-keyword" > not< / span > < span class = "hljs-keyword" > instanceof< / span > ThisLiteral < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > o.scope.check left.base.value
@variable.error < span class = "hljs-string" > "the variable \"< span class = "hljs-subst" > #{left.base.value}< / span > \" can't be assigned with < span class = "hljs-subst" > #{@context}< / span > because it has not been declared before"< / span >
< span class = "hljs-keyword" > if< / span > < span class = "hljs-string" > "?"< / span > < span class = "hljs-keyword" > in< / span > @context
2014-01-29 23:54:00 -05:00
o.isExistentialEquals = < span class = "hljs-literal" > true< / span >
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > new< / span > If(< span class = "hljs-keyword" > new< / span > Existence(left), right, type: < span class = "hljs-string" > 'if'< / span > ).addElse(< span class = "hljs-keyword" > new< / span > Assign(right, @value, < span class = "hljs-string" > '='< / span > )).compileToFragments o
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
fragments = < span class = "hljs-keyword" > new< / span > Op(@context[...< span class = "hljs-number" > -1< / span > ], left, < span class = "hljs-keyword" > new< / span > Assign(right, @value, < span class = "hljs-string" > '='< / span > )).compileToFragments o
< span class = "hljs-keyword" > if< / span > o.level < = LEVEL_LIST < span class = "hljs-keyword" > then< / span > fragments < span class = "hljs-keyword" > else< / span > @wrapInBraces fragments< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-119" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-119" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Convert special math assignment operators like < code > a **= b< / code > to the equivalent
extended form < code > a = a ** b< / code > and then compiles that.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileSpecialMath: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
[left, right] = @variable.cacheReference o
< span class = "hljs-keyword" > new< / span > Assign(left, < span class = "hljs-keyword" > new< / span > Op(@context[...< span class = "hljs-number" > -1< / span > ], right, @value)).compileToFragments o< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-120" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2014-01-29 23:54:00 -05:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-120" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-08-23 10:08:39 -04:00
< p > Compile the assignment from an array splice literal, using JavaScript’ s
2014-01-29 23:54:00 -05:00
< code > Array#splice< / code > method.< / p >
2013-06-02 01:37:45 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileSplice: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
{range: {from, to, exclusive}} = @variable.properties.pop()
name = @variable.compile o
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > from
2016-09-22 16:19:43 -04:00
[fromDecl, fromRef] = @cacheToCodeFragments from.cache o, LEVEL_OP
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
fromDecl = fromRef = < span class = "hljs-string" > '0'< / span >
< span class = "hljs-keyword" > if< / span > to
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > from?.isNumber() < span class = "hljs-keyword" > and< / span > to.isNumber()
2014-01-29 23:54:00 -05:00
to = to.compile(o) - fromRef
to += < span class = "hljs-number" > 1< / span > < span class = "hljs-keyword" > unless< / span > exclusive
< span class = "hljs-keyword" > else< / span >
to = to.compile(o, LEVEL_ACCESS) + < span class = "hljs-string" > ' - '< / span > + fromRef
to += < span class = "hljs-string" > ' + 1'< / span > < span class = "hljs-keyword" > unless< / span > exclusive
< span class = "hljs-keyword" > else< / span >
to = < span class = "hljs-string" > "9e9"< / span >
2016-09-22 16:19:43 -04:00
[valDef, valRef] = @value.cache o, LEVEL_LIST
answer = [].concat @makeCode(< span class = "hljs-string" > "[].splice.apply(< span class = "hljs-subst" > #{name}< / span > , [< span class = "hljs-subst" > #{fromDecl}< / span > , < span class = "hljs-subst" > #{to}< / span > ].concat("< / span > ), valDef, @makeCode(< span class = "hljs-string" > ")), "< / span > ), valRef
< span class = "hljs-keyword" > if< / span > o.level > LEVEL_TOP < span class = "hljs-keyword" > then< / span > @wrapInBraces answer < span class = "hljs-keyword" > else< / span > answer< / pre > < / div > < / div >
2014-01-29 23:54:00 -05:00
2013-06-02 01:37:45 -04:00
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-121" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-121" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "code" > Code< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-122" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-122" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
< p > A function definition. This is the only node that creates a new Scope.
2010-12-24 14:02:10 -05:00
When for the purposes of walking the contents of a function body, the Code
2016-09-22 16:19:43 -04:00
has no < em > children< / em > – they’ re within the inner scope.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Code = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Code< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (params, body, tag)< / span > -> < / span >
@params = params < span class = "hljs-keyword" > or< / span > []
@body = body < span class = "hljs-keyword" > or< / span > < span class = "hljs-keyword" > new< / span > Block
@bound = tag < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > 'boundfunc'< / span >
@isGenerator = !!@body.contains (node) ->
(node < span class = "hljs-keyword" > instanceof< / span > Op < span class = "hljs-keyword" > and< / span > node.isYield()) < span class = "hljs-keyword" > or< / span > node < span class = "hljs-keyword" > instanceof< / span > YieldReturn
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'params'< / span > , < span class = "hljs-string" > 'body'< / span > ]
2010-06-28 00:19:58 -04:00
2016-09-22 16:19:43 -04:00
isStatement: < span class = "hljs-function" > -> < / span > !!@ctor
2010-12-24 14:02:10 -05:00
2016-09-22 16:19:43 -04:00
jumps: NO
2014-01-29 23:54:00 -05:00
2016-09-22 16:19:43 -04:00
makeScope: < span class = "hljs-function" > < span class = "hljs-params" > (parentScope)< / span > -> < / span > < span class = "hljs-keyword" > new< / span > Scope parentScope, @body, < span class = "hljs-keyword" > this< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-123" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-123" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > Compilation creates a new scope unless explicitly asked to share with the
2010-12-24 14:02:10 -05:00
outer scope. Handles splat parameters in the parameter list by peeking at
2011-08-04 23:17:23 -04:00
the JavaScript < code > arguments< / code > object. If the function is bound with the < code > => < / code >
2010-12-24 14:02:10 -05:00
arrow, generates a wrapper that saves the current value of < code > this< / code > through
2014-01-29 23:54:00 -05:00
a closure.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > @bound < span class = "hljs-keyword" > and< / span > o.scope.method?.bound
@context = o.scope.method.context< / pre > < / div > < / div >
2014-01-29 23:54:00 -05:00
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-124" >
2014-01-29 23:54:00 -05:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-124" > ¶ < / a >
2014-01-29 23:54:00 -05:00
< / div >
< p > Handle bound functions early.< / p >
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-keyword" > if< / span > @bound < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > @context
@context = < span class = "hljs-string" > '_this'< / span >
wrapper = < span class = "hljs-keyword" > new< / span > Code [< span class = "hljs-keyword" > new< / span > Param < span class = "hljs-keyword" > new< / span > IdentifierLiteral @context], < span class = "hljs-keyword" > new< / span > Block [< span class = "hljs-keyword" > this< / span > ]
boundfunc = < span class = "hljs-keyword" > new< / span > Call(wrapper, [< span class = "hljs-keyword" > new< / span > ThisLiteral])
boundfunc.updateLocationDataIfMissing @locationData
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > boundfunc.compileNode(o)
2016-09-22 16:19:43 -04:00
o.scope = del(o, < span class = "hljs-string" > 'classScope'< / span > ) < span class = "hljs-keyword" > or< / span > @makeScope o.scope
2014-01-29 23:54:00 -05:00
o.scope.shared = del(o, < span class = "hljs-string" > 'sharedScope'< / span > )
2013-03-18 01:06:33 -04:00
o.indent += TAB
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > delete< / span > o.bare
< span class = "hljs-keyword" > delete< / span > o.isExistentialEquals
2013-03-18 01:06:33 -04:00
params = []
exprs = []
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > for< / span > param < span class = "hljs-keyword" > in< / span > @params < span class = "hljs-keyword" > when< / span > param < span class = "hljs-keyword" > not< / span > < span class = "hljs-keyword" > instanceof< / span > Expansion
2014-01-29 23:54:00 -05:00
o.scope.parameter param.asReference o
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > for< / span > param < span class = "hljs-keyword" > in< / span > @params < span class = "hljs-keyword" > when< / span > param.splat < span class = "hljs-keyword" > or< / span > param < span class = "hljs-keyword" > instanceof< / span > Expansion
< span class = "hljs-keyword" > for< / span > p < span class = "hljs-keyword" > in< / span > @params < span class = "hljs-keyword" > when< / span > p < span class = "hljs-keyword" > not< / span > < span class = "hljs-keyword" > instanceof< / span > Expansion < span class = "hljs-keyword" > and< / span > p.name.value
2015-01-29 12:20:46 -05:00
o.scope.add p.name.value, < span class = "hljs-string" > 'var'< / span > , < span class = "hljs-literal" > yes< / span >
2016-09-22 16:19:43 -04:00
splats = < span class = "hljs-keyword" > new< / span > Assign < span class = "hljs-keyword" > new< / span > Value(< span class = "hljs-keyword" > new< / span > Arr(p.asReference o < span class = "hljs-keyword" > for< / span > p < span class = "hljs-keyword" > in< / span > @params)),
< span class = "hljs-keyword" > new< / span > Value < span class = "hljs-keyword" > new< / span > IdentifierLiteral < span class = "hljs-string" > 'arguments'< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > break< / span >
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > for< / span > param < span class = "hljs-keyword" > in< / span > @params
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > param.isComplex()
2013-03-18 01:06:33 -04:00
val = ref = param.asReference o
2014-01-29 23:54:00 -05:00
val = < span class = "hljs-keyword" > new< / span > Op < span class = "hljs-string" > '?'< / span > , ref, param.value < span class = "hljs-keyword" > if< / span > param.value
2016-09-22 16:19:43 -04:00
exprs.push < span class = "hljs-keyword" > new< / span > Assign < span class = "hljs-keyword" > new< / span > Value(param.name), val, < span class = "hljs-string" > '='< / span > , param: < span class = "hljs-literal" > yes< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2013-03-18 01:06:33 -04:00
ref = param
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > param.value
lit = < span class = "hljs-keyword" > new< / span > Literal ref.name.value + < span class = "hljs-string" > ' == null'< / span >
val = < span class = "hljs-keyword" > new< / span > Assign < span class = "hljs-keyword" > new< / span > Value(param.name), param.value, < span class = "hljs-string" > '='< / span >
exprs.push < span class = "hljs-keyword" > new< / span > If lit, val
params.push ref < span class = "hljs-keyword" > unless< / span > splats
2016-09-22 16:19:43 -04:00
wasEmpty = @body.isEmpty()
2014-01-29 23:54:00 -05:00
exprs.unshift splats < span class = "hljs-keyword" > if< / span > splats
2016-09-22 16:19:43 -04:00
@body.expressions.unshift exprs... < span class = "hljs-keyword" > if< / span > exprs.length
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > for< / span > p, i < span class = "hljs-keyword" > in< / span > params
2013-03-18 01:06:33 -04:00
params[i] = p.compileToFragments o
o.scope.parameter fragmentsToText params[i]
uniqs = []
2016-09-22 16:19:43 -04:00
@eachParamName (name, node) ->
2015-01-29 12:20:46 -05:00
node.error < span class = "hljs-string" > "multiple parameters named < span class = "hljs-subst" > #{name}< / span > "< / span > < span class = "hljs-keyword" > if< / span > name < span class = "hljs-keyword" > in< / span > uniqs
2013-03-18 01:06:33 -04:00
uniqs.push name
2016-09-22 16:19:43 -04:00
@body.makeReturn() < span class = "hljs-keyword" > unless< / span > wasEmpty < span class = "hljs-keyword" > or< / span > @noReturn
2015-01-29 12:20:46 -05:00
code = < span class = "hljs-string" > 'function'< / span >
2016-09-22 16:19:43 -04:00
code += < span class = "hljs-string" > '*'< / span > < span class = "hljs-keyword" > if< / span > @isGenerator
code += < span class = "hljs-string" > ' '< / span > + @name < span class = "hljs-keyword" > if< / span > @ctor
2015-01-29 12:20:46 -05:00
code += < span class = "hljs-string" > '('< / span >
2016-09-22 16:19:43 -04:00
answer = [@makeCode(code)]
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > for< / span > p, i < span class = "hljs-keyword" > in< / span > params
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > i < span class = "hljs-keyword" > then< / span > answer.push @makeCode < span class = "hljs-string" > ", "< / span >
2013-03-18 01:06:33 -04:00
answer.push p...
2016-09-22 16:19:43 -04:00
answer.push @makeCode < span class = "hljs-string" > ') {'< / span >
answer = answer.concat(@makeCode(< span class = "hljs-string" > "\n"< / span > ), @body.compileWithDeclarations(o), @makeCode(< span class = "hljs-string" > "\n< span class = "hljs-subst" > #{@tab}< / span > "< / span > )) < span class = "hljs-keyword" > unless< / span > @body.isEmpty()
answer.push @makeCode < span class = "hljs-string" > '}'< / span >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > return< / span > [@makeCode(@tab), answer...] < span class = "hljs-keyword" > if< / span > @ctor
< span class = "hljs-keyword" > if< / span > @front < span class = "hljs-keyword" > or< / span > (o.level > = LEVEL_ACCESS) < span class = "hljs-keyword" > then< / span > @wrapInBraces answer < span class = "hljs-keyword" > else< / span > answer
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
eachParamName: < span class = "hljs-function" > < span class = "hljs-params" > (iterator)< / span > -> < / span >
param.eachName iterator < span class = "hljs-keyword" > for< / span > param < span class = "hljs-keyword" > in< / span > @params< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-125" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-125" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > Short-circuit < code > traverseChildren< / code > method to prevent it from crossing scope boundaries
2014-01-29 23:54:00 -05:00
unless < code > crossScope< / code > is < code > true< / code > .< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > traverseChildren: < span class = "hljs-function" > < span class = "hljs-params" > (crossScope, func)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > super< / span > (crossScope, func) < span class = "hljs-keyword" > if< / span > crossScope< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-126" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-126" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "param" > Param< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-127" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-127" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< p > A parameter in a function definition. Beyond a typical JavaScript parameter,
2010-12-24 14:02:10 -05:00
these parameters can also attach themselves to the context of the function,
2014-01-29 23:54:00 -05:00
as well as be a splat, gathering up a group of parameters into an array.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Param = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Param< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@name, @value, @splat)< / span > -> < / span >
message = isUnassignable @name.unwrapAll().value
@name.error message < span class = "hljs-keyword" > if< / span > message
< span class = "hljs-keyword" > if< / span > @name < span class = "hljs-keyword" > instanceof< / span > Obj < span class = "hljs-keyword" > and< / span > @name.generated
token = @name.objects[< span class = "hljs-number" > 0< / span > ].operatorToken
2015-09-03 12:37:36 -04:00
token.error < span class = "hljs-string" > "unexpected < span class = "hljs-subst" > #{token.value}< / span > "< / span >
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'name'< / span > , < span class = "hljs-string" > 'value'< / span > ]
2010-08-03 00:06:34 -04:00
2016-09-22 16:19:43 -04:00
compileToFragments: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
@name.compileToFragments o, LEVEL_LIST
2010-08-03 00:06:34 -04:00
2016-09-22 16:19:43 -04:00
asReference: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
< span class = "hljs-keyword" > return< / span > @reference < span class = "hljs-keyword" > if< / span > @reference
node = @name
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > node.< span class = "hljs-keyword" > this< / span >
2015-02-03 11:31:43 -05:00
name = node.properties[< span class = "hljs-number" > 0< / span > ].name.value
2016-09-22 16:19:43 -04:00
name = < span class = "hljs-string" > "_< span class = "hljs-subst" > #{name}< / span > "< / span > < span class = "hljs-keyword" > if< / span > name < span class = "hljs-keyword" > in< / span > JS_FORBIDDEN
node = < span class = "hljs-keyword" > new< / span > IdentifierLiteral o.scope.freeVariable name
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > node.isComplex()
2016-09-22 16:19:43 -04:00
node = < span class = "hljs-keyword" > new< / span > IdentifierLiteral o.scope.freeVariable < span class = "hljs-string" > 'arg'< / span >
2014-01-29 23:54:00 -05:00
node = < span class = "hljs-keyword" > new< / span > Value node
2016-09-22 16:19:43 -04:00
node = < span class = "hljs-keyword" > new< / span > Splat node < span class = "hljs-keyword" > if< / span > @splat
node.updateLocationDataIfMissing @locationData
@reference = node
2010-08-03 00:06:34 -04:00
2016-09-22 16:19:43 -04:00
isComplex: < span class = "hljs-function" > -> < / span >
@name.isComplex()< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-128" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-128" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > Iterates the name or names of a < code > Param< / code > .
2013-03-10 23:37:22 -04:00
In a sense, a destructured parameter represents multiple JS parameters. This
method allows to iterate them all.
The < code > iterator< / code > function will be called as < code > iterator(name, node)< / code > where
< code > name< / code > is the name of the parameter and < code > node< / code > is the AST node corresponding
2014-01-29 23:54:00 -05:00
to that name.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > eachName: < span class = "hljs-function" > < span class = "hljs-params" > (iterator, name = @name)< / span > -> < / span >
< span class = "hljs-function" > < span class = "hljs-title" > atParam< / span > = < span class = "hljs-params" > (obj)< / span > -> < / span > iterator < span class = "hljs-string" > "@< span class = "hljs-subst" > #{obj.properties[< span class = "hljs-number" > 0< / span > ].name.value}< / span > "< / span > , obj< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-129" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-129" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< ul >
2012-04-10 14:57:45 -04:00
< li > simple literals < code > foo< / code > < / li >
2013-03-10 23:37:22 -04:00
< / ul >
< / div >
2014-01-29 23:54:00 -05:00
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-keyword" > return< / span > iterator name.value, name < span class = "hljs-keyword" > if< / span > name < span class = "hljs-keyword" > instanceof< / span > Literal< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-130" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-130" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< ul >
2012-04-10 14:57:45 -04:00
< li > at-params < code > @foo< / code > < / li >
2013-03-10 23:37:22 -04:00
< / ul >
< / div >
2014-01-29 23:54:00 -05:00
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-keyword" > return< / span > atParam name < span class = "hljs-keyword" > if< / span > name < span class = "hljs-keyword" > instanceof< / span > Value
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > for< / span > obj < span class = "hljs-keyword" > in< / span > name.objects ? []< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-131" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-131" > ¶ < / a >
2015-09-03 12:37:36 -04:00
< / div >
< ul >
< li > destructured parameter with default value< / li >
< / ul >
< / div >
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-keyword" > if< / span > obj < span class = "hljs-keyword" > instanceof< / span > Assign < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > obj.context?
obj = obj.variable< / pre > < / div > < / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-132" >
2015-09-03 12:37:36 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-132" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< ul >
2012-04-10 14:57:45 -04:00
< li > assignments within destructured parameters < code > {foo:bar}< / code > < / li >
2013-03-10 23:37:22 -04:00
< / ul >
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-keyword" > if< / span > obj < span class = "hljs-keyword" > instanceof< / span > Assign< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-133" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-133" > ¶ < / a >
< / div >
< p > … possibly with a default value< / p >
< / div >
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-keyword" > if< / span > obj.value < span class = "hljs-keyword" > instanceof< / span > Assign
obj = obj.value
@eachName iterator, obj.value.unwrap()< / pre > < / div > < / div >
< / li >
< li id = "section-134" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-134" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< ul >
2012-05-14 14:45:20 -04:00
< li > splats within destructured parameters < code > [xs...]< / code > < / li >
2013-03-10 23:37:22 -04:00
< / ul >
< / div >
2014-01-29 23:54:00 -05:00
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > obj < span class = "hljs-keyword" > instanceof< / span > Splat
2013-03-18 01:06:33 -04:00
node = obj.name.unwrap()
iterator node.value, node
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > obj < span class = "hljs-keyword" > instanceof< / span > Value< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-135" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-135" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< ul >
2012-04-10 14:57:45 -04:00
< li > destructured parameters within destructured parameters < code > [{a}]< / code > < / li >
2013-03-10 23:37:22 -04:00
< / ul >
< / div >
2014-01-29 23:54:00 -05:00
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-keyword" > if< / span > obj.isArray() < span class = "hljs-keyword" > or< / span > obj.isObject()
2016-09-22 16:19:43 -04:00
@eachName iterator, obj.base< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-136" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-136" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< ul >
2012-04-10 14:57:45 -04:00
< li > at-params within destructured parameters < code > {@foo}< / code > < / li >
2013-03-10 23:37:22 -04:00
< / ul >
< / div >
2014-01-29 23:54:00 -05:00
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > obj.< span class = "hljs-keyword" > this< / span >
2013-03-18 01:06:33 -04:00
atParam obj< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-137" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-137" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
< ul >
< li > simple destructured parameters {foo}< / li >
< / ul >
< / div >
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-keyword" > else< / span > iterator obj.base.value, obj.base
< span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > obj < span class = "hljs-keyword" > not< / span > < span class = "hljs-keyword" > instanceof< / span > Expansion
obj.error < span class = "hljs-string" > "illegal parameter < span class = "hljs-subst" > #{obj.compile()}< / span > "< / span >
< span class = "hljs-keyword" > return< / span > < / pre > < / div > < / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-138" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-138" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-08-23 10:08:39 -04:00
< h3 id = "splat" > Splat< / h3 >
2013-03-10 23:37:22 -04:00
< / div >
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-139" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-139" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-08-23 10:08:39 -04:00
< p > A splat, either as a parameter to a function, an argument to a call,
2014-01-29 23:54:00 -05:00
or as part of a destructuring assignment.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Splat = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Splat< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'name'< / span > ]
2010-06-28 00:19:58 -04:00
2016-09-22 16:19:43 -04:00
isAssignable: YES
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (name)< / span > -> < / span >
@name = < span class = "hljs-keyword" > if< / span > name.compile < span class = "hljs-keyword" > then< / span > name < span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > new< / span > Literal name
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
assigns: < span class = "hljs-function" > < span class = "hljs-params" > (name)< / span > -> < / span >
@name.assigns name
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
compileToFragments: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
@name.compileToFragments o
2012-04-10 14:57:45 -04:00
2016-09-22 16:19:43 -04:00
unwrap: < span class = "hljs-function" > -> < / span > @name< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-140" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-140" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > Utility function that converts an arbitrary number of elements, mixed with
2014-01-29 23:54:00 -05:00
splats, to a proper array.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > @compileSplattedArray: < span class = "hljs-function" > < span class = "hljs-params" > (o, list, apply)< / span > -> < / span >
index = < span class = "hljs-number" > -1< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > continue< / span > < span class = "hljs-keyword" > while< / span > (node = list[++index]) < span class = "hljs-keyword" > and< / span > node < span class = "hljs-keyword" > not< / span > < span class = "hljs-keyword" > instanceof< / span > Splat
< span class = "hljs-keyword" > return< / span > [] < span class = "hljs-keyword" > if< / span > index > = list.length
< span class = "hljs-keyword" > if< / span > list.length < span class = "hljs-keyword" > is< / span > < span class = "hljs-number" > 1< / span >
node = list[< span class = "hljs-number" > 0< / span > ]
2013-03-18 01:06:33 -04:00
fragments = node.compileToFragments o, LEVEL_LIST
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > fragments < span class = "hljs-keyword" > if< / span > apply
2015-01-29 12:20:46 -05:00
< span class = "hljs-keyword" > return< / span > [].concat node.makeCode(< span class = "hljs-string" > "< span class = "hljs-subst" > #{ utility < span class = "hljs-string" > 'slice'< / span > , o }< / span > .call("< / span > ), fragments, node.makeCode(< span class = "hljs-string" > ")"< / span > )
2013-03-18 01:06:33 -04:00
args = list[index..]
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > for< / span > node, i < span class = "hljs-keyword" > in< / span > args
2013-03-18 01:06:33 -04:00
compiledNode = node.compileToFragments o, LEVEL_LIST
2014-01-29 23:54:00 -05:00
args[i] = < span class = "hljs-keyword" > if< / span > node < span class = "hljs-keyword" > instanceof< / span > Splat
2015-01-29 12:20:46 -05:00
< span class = "hljs-keyword" > then< / span > [].concat node.makeCode(< span class = "hljs-string" > "< span class = "hljs-subst" > #{ utility < span class = "hljs-string" > 'slice'< / span > , o }< / span > .call("< / span > ), compiledNode, node.makeCode(< span class = "hljs-string" > ")"< / span > )
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span > [].concat node.makeCode(< span class = "hljs-string" > "["< / span > ), compiledNode, node.makeCode(< span class = "hljs-string" > "]"< / span > )
< span class = "hljs-keyword" > if< / span > index < span class = "hljs-keyword" > is< / span > < span class = "hljs-number" > 0< / span >
node = list[< span class = "hljs-number" > 0< / span > ]
concatPart = (node.joinFragmentArrays args[< span class = "hljs-number" > 1.< / span > .], < span class = "hljs-string" > ', '< / span > )
< span class = "hljs-keyword" > return< / span > args[< span class = "hljs-number" > 0< / span > ].concat node.makeCode(< span class = "hljs-string" > ".concat("< / span > ), concatPart, node.makeCode(< span class = "hljs-string" > ")"< / span > )
base = (node.compileToFragments o, LEVEL_LIST < span class = "hljs-keyword" > for< / span > node < span class = "hljs-keyword" > in< / span > list[...index])
base = list[< span class = "hljs-number" > 0< / span > ].joinFragmentArrays base, < span class = "hljs-string" > ', '< / span >
concatPart = list[index].joinFragmentArrays args, < span class = "hljs-string" > ', '< / span >
2015-02-18 15:43:33 -05:00
[..., last] = list
[].concat list[< span class = "hljs-number" > 0< / span > ].makeCode(< span class = "hljs-string" > "["< / span > ), base, list[index].makeCode(< span class = "hljs-string" > "].concat("< / span > ), concatPart, last.makeCode(< span class = "hljs-string" > ")"< / span > )< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-141" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2014-01-29 23:54:00 -05:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-141" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "expansion" > Expansion< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-142" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-142" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
< p > Used to skip values inside an array destructuring (pattern matching) or
2014-01-29 23:54:00 -05:00
parameter list.< / p >
2013-06-02 01:37:45 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Expansion = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Expansion< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
2014-01-29 23:54:00 -05:00
2016-09-22 16:19:43 -04:00
isComplex: NO
2014-01-29 23:54:00 -05:00
2016-09-22 16:19:43 -04:00
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
@error < span class = "hljs-string" > 'Expansion must be used inside a destructuring assignment or parameter list'< / span >
2014-01-29 23:54:00 -05:00
2016-09-22 16:19:43 -04:00
asReference: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > this< / span >
2016-09-22 16:19:43 -04:00
eachName: < span class = "hljs-function" > < span class = "hljs-params" > (iterator)< / span > -> < / span > < / pre > < / div > < / div >
2014-01-29 23:54:00 -05:00
2013-06-02 01:37:45 -04:00
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-143" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-143" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "while" > While< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-144" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-144" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
< p > A while loop, the only sort of low-level loop exposed by CoffeeScript. From
2010-12-24 14:02:10 -05:00
it, all other loops can be manufactured. Useful in cases where you need more
2014-01-29 23:54:00 -05:00
flexibility or more speed than a comprehension can provide.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.While = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > While< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (condition, options)< / span > -> < / span >
@condition = < span class = "hljs-keyword" > if< / span > options?.invert < span class = "hljs-keyword" > then< / span > condition.invert() < span class = "hljs-keyword" > else< / span > condition
@guard = options?.guard
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'condition'< / span > , < span class = "hljs-string" > 'guard'< / span > , < span class = "hljs-string" > 'body'< / span > ]
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
isStatement: YES
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
makeReturn: < span class = "hljs-function" > < span class = "hljs-params" > (res)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > res
< span class = "hljs-keyword" > super< / span >
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
@returns = < span class = "hljs-keyword" > not< / span > @jumps loop: < span class = "hljs-literal" > yes< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > this< / span >
2010-03-23 00:18:50 -04:00
2016-09-22 16:19:43 -04:00
addBody: < span class = "hljs-function" > < span class = "hljs-params" > (@body)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > this< / span >
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
jumps: < span class = "hljs-function" > -> < / span >
{expressions} = @body
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > < span class = "hljs-literal" > no< / span > < span class = "hljs-keyword" > unless< / span > expressions.length
< span class = "hljs-keyword" > for< / span > node < span class = "hljs-keyword" > in< / span > expressions
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > return< / span > jumpNode < span class = "hljs-keyword" > if< / span > jumpNode = node.jumps loop: < span class = "hljs-literal" > yes< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-literal" > no< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-145" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-145" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > The main difference from a JavaScript < em > while< / em > is that the CoffeeScript
2016-09-22 16:19:43 -04:00
< em > while< / em > can be used as a part of a larger expression – while loops may
2014-01-29 23:54:00 -05:00
return an array containing the computed result of each iteration.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
2013-03-18 01:06:33 -04:00
o.indent += TAB
2014-01-29 23:54:00 -05:00
set = < span class = "hljs-string" > ''< / span >
{body} = < span class = "hljs-keyword" > this< / span >
< span class = "hljs-keyword" > if< / span > body.isEmpty()
2016-09-22 16:19:43 -04:00
body = @makeCode < span class = "hljs-string" > ''< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > @returns
2014-01-29 23:54:00 -05:00
body.makeReturn rvar = o.scope.freeVariable < span class = "hljs-string" > 'results'< / span >
2016-09-22 16:19:43 -04:00
set = < span class = "hljs-string" > "< span class = "hljs-subst" > #{@tab}< / span > < span class = "hljs-subst" > #{rvar}< / span > = [];\n"< / span >
< span class = "hljs-keyword" > if< / span > @guard
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > body.expressions.length > < span class = "hljs-number" > 1< / span >
2016-09-22 16:19:43 -04:00
body.expressions.unshift < span class = "hljs-keyword" > new< / span > If (< span class = "hljs-keyword" > new< / span > Parens @guard).invert(), < span class = "hljs-keyword" > new< / span > StatementLiteral < span class = "hljs-string" > "continue"< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
body = Block.wrap [< span class = "hljs-keyword" > new< / span > If @guard, body] < span class = "hljs-keyword" > if< / span > @guard
body = [].concat @makeCode(< span class = "hljs-string" > "\n"< / span > ), (body.compileToFragments o, LEVEL_TOP), @makeCode(< span class = "hljs-string" > "\n< span class = "hljs-subst" > #{@tab}< / span > "< / span > )
answer = [].concat @makeCode(set + @tab + < span class = "hljs-string" > "while ("< / span > ), @condition.compileToFragments(o, LEVEL_PAREN),
@makeCode(< span class = "hljs-string" > ") {"< / span > ), body, @makeCode(< span class = "hljs-string" > "}"< / span > )
< span class = "hljs-keyword" > if< / span > @returns
answer.push @makeCode < span class = "hljs-string" > "\n< span class = "hljs-subst" > #{@tab}< / span > return < span class = "hljs-subst" > #{rvar}< / span > ;"< / span >
2013-03-18 01:06:33 -04:00
answer< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-146" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-146" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "op" > Op< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-147" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-147" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
< p > Simple Arithmetic and logical operations. Performs some conversion from
2014-01-29 23:54:00 -05:00
CoffeeScript operations into their JavaScript equivalents.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Op = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Op< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (op, first, second, flip )< / span > -> < / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > < span class = "hljs-keyword" > new< / span > In first, second < span class = "hljs-keyword" > if< / span > op < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > 'in'< / span >
< span class = "hljs-keyword" > if< / span > op < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > 'do'< / span >
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > return< / span > @generateDo first
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > op < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > 'new'< / span >
< span class = "hljs-keyword" > return< / span > first.newInstance() < span class = "hljs-keyword" > if< / span > first < span class = "hljs-keyword" > instanceof< / span > Call < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > first.< span class = "hljs-keyword" > do< / span > < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > first.isNew
first = < span class = "hljs-keyword" > new< / span > Parens first < span class = "hljs-keyword" > if< / span > first < span class = "hljs-keyword" > instanceof< / span > Code < span class = "hljs-keyword" > and< / span > first.bound < span class = "hljs-keyword" > or< / span > first.< span class = "hljs-keyword" > do< / span >
2016-09-22 16:19:43 -04:00
@operator = CONVERSIONS[op] < span class = "hljs-keyword" > or< / span > op
@first = first
@second = second
@flip = !!flip
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > < span class = "hljs-keyword" > this< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-148" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-148" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > The map of conversions from CoffeeScript to JavaScript symbols.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2013-03-18 01:06:33 -04:00
< div class = "content" > < div class = 'highlight' > < pre > CONVERSIONS =
2015-01-29 12:20:46 -05:00
< span class = "hljs-string" > '=='< / span > : < span class = "hljs-string" > '==='< / span >
< span class = "hljs-string" > '!='< / span > : < span class = "hljs-string" > '!=='< / span >
< span class = "hljs-string" > 'of'< / span > : < span class = "hljs-string" > 'in'< / span >
< span class = "hljs-string" > 'yieldfrom'< / span > : < span class = "hljs-string" > 'yield*'< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-149" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-149" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > The map of invertible operators.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2013-03-18 01:06:33 -04:00
< div class = "content" > < div class = 'highlight' > < pre > INVERSIONS =
2014-01-29 23:54:00 -05:00
< span class = "hljs-string" > '!=='< / span > : < span class = "hljs-string" > '==='< / span >
< span class = "hljs-string" > '==='< / span > : < span class = "hljs-string" > '!=='< / span >
2010-06-28 00:19:58 -04:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'first'< / span > , < span class = "hljs-string" > 'second'< / span > ]
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
isNumber: < span class = "hljs-function" > -> < / span >
@isUnary() < span class = "hljs-keyword" > and< / span > @operator < span class = "hljs-keyword" > in< / span > [< span class = "hljs-string" > '+'< / span > , < span class = "hljs-string" > '-'< / span > ] < span class = "hljs-keyword" > and< / span >
@first < span class = "hljs-keyword" > instanceof< / span > Value < span class = "hljs-keyword" > and< / span > @first.isNumber()
2010-12-24 14:02:10 -05:00
2016-09-22 16:19:43 -04:00
isYield: < span class = "hljs-function" > -> < / span >
@operator < span class = "hljs-keyword" > in< / span > [< span class = "hljs-string" > 'yield'< / span > , < span class = "hljs-string" > 'yield*'< / span > ]
2015-01-29 12:20:46 -05:00
2016-09-22 16:19:43 -04:00
isUnary: < span class = "hljs-function" > -> < / span >
< span class = "hljs-keyword" > not< / span > @second
2015-02-18 15:43:33 -05:00
2016-09-22 16:19:43 -04:00
isComplex: < span class = "hljs-function" > -> < / span >
< span class = "hljs-keyword" > not< / span > @isNumber()< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-150" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-150" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > Am I capable of
2014-01-29 23:54:00 -05:00
< a href = "http://docs.python.org/reference/expressions.html#notin" > Python-style comparison chaining< / a > ?< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > isChainable: < span class = "hljs-function" > -> < / span >
@operator < span class = "hljs-keyword" > in< / span > [< span class = "hljs-string" > '< '< / span > , < span class = "hljs-string" > '> '< / span > , < span class = "hljs-string" > '> ='< / span > , < span class = "hljs-string" > '< ='< / span > , < span class = "hljs-string" > '==='< / span > , < span class = "hljs-string" > '!=='< / span > ]
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
invert: < span class = "hljs-function" > -> < / span >
< span class = "hljs-keyword" > if< / span > @isChainable() < span class = "hljs-keyword" > and< / span > @first.isChainable()
2014-01-29 23:54:00 -05:00
allInvertable = < span class = "hljs-literal" > yes< / span >
curr = < span class = "hljs-keyword" > this< / span >
< span class = "hljs-keyword" > while< / span > curr < span class = "hljs-keyword" > and< / span > curr.operator
allInvertable < span class = "hljs-keyword" > and< / span > = (curr.operator < span class = "hljs-keyword" > of< / span > INVERSIONS)
2013-03-18 01:06:33 -04:00
curr = curr.first
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > < span class = "hljs-keyword" > new< / span > Parens(< span class = "hljs-keyword" > this< / span > ).invert() < span class = "hljs-keyword" > unless< / span > allInvertable
curr = < span class = "hljs-keyword" > this< / span >
< span class = "hljs-keyword" > while< / span > curr < span class = "hljs-keyword" > and< / span > curr.operator
2013-03-18 01:06:33 -04:00
curr.invert = !curr.invert
curr.operator = INVERSIONS[curr.operator]
curr = curr.first
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > this< / span >
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > op = INVERSIONS[@operator]
@operator = op
< span class = "hljs-keyword" > if< / span > @first.unwrap() < span class = "hljs-keyword" > instanceof< / span > Op
@first.invert()
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > this< / span >
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > @second
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > new< / span > Parens(< span class = "hljs-keyword" > this< / span > ).invert()
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > if< / span > @operator < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > '!'< / span > < span class = "hljs-keyword" > and< / span > (fst = @first.unwrap()) < span class = "hljs-keyword" > instanceof< / span > Op < span class = "hljs-keyword" > and< / span >
2014-01-29 23:54:00 -05:00
fst.operator < span class = "hljs-keyword" > in< / span > [< span class = "hljs-string" > '!'< / span > , < span class = "hljs-string" > 'in'< / span > , < span class = "hljs-string" > 'instanceof'< / span > ]
2013-03-18 01:06:33 -04:00
fst
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
< span class = "hljs-keyword" > new< / span > Op < span class = "hljs-string" > '!'< / span > , < span class = "hljs-keyword" > this< / span >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
unfoldSoak: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
@operator < span class = "hljs-keyword" > in< / span > [< span class = "hljs-string" > '++'< / span > , < span class = "hljs-string" > '--'< / span > , < span class = "hljs-string" > 'delete'< / span > ] < span class = "hljs-keyword" > and< / span > unfoldSoak o, < span class = "hljs-keyword" > this< / span > , < span class = "hljs-string" > 'first'< / span >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
generateDo: < span class = "hljs-function" > < span class = "hljs-params" > (exp)< / span > -> < / span >
2013-03-18 01:06:33 -04:00
passedParams = []
2014-01-29 23:54:00 -05:00
func = < span class = "hljs-keyword" > if< / span > exp < span class = "hljs-keyword" > instanceof< / span > Assign < span class = "hljs-keyword" > and< / span > (ref = exp.value.unwrap()) < span class = "hljs-keyword" > instanceof< / span > Code
2013-03-18 01:06:33 -04:00
ref
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2013-03-18 01:06:33 -04:00
exp
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > for< / span > param < span class = "hljs-keyword" > in< / span > func.params < span class = "hljs-keyword" > or< / span > []
< span class = "hljs-keyword" > if< / span > param.value
2013-03-18 01:06:33 -04:00
passedParams.push param.value
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > delete< / span > param.value
< span class = "hljs-keyword" > else< / span >
2013-03-18 01:06:33 -04:00
passedParams.push param
2014-01-29 23:54:00 -05:00
call = < span class = "hljs-keyword" > new< / span > Call exp, passedParams
call.< span class = "hljs-keyword" > do< / span > = < span class = "hljs-literal" > yes< / span >
2013-03-18 01:06:33 -04:00
call
2016-09-22 16:19:43 -04:00
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
isChain = @isChainable() < span class = "hljs-keyword" > and< / span > @first.isChainable()< / pre > < / div > < / div >
2013-03-18 01:06:33 -04:00
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-151" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-151" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-08-23 10:08:39 -04:00
< p > In chains, there’ s no need to wrap bare obj literals in parens,
2014-01-29 23:54:00 -05:00
as the chained expression is wrapped.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > @first.front = @front < span class = "hljs-keyword" > unless< / span > isChain
< span class = "hljs-keyword" > if< / span > @operator < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > 'delete'< / span > < span class = "hljs-keyword" > and< / span > o.scope.check(@first.unwrapAll().value)
@error < span class = "hljs-string" > 'delete operand may not be argument or var'< / span >
< span class = "hljs-keyword" > if< / span > @operator < span class = "hljs-keyword" > in< / span > [< span class = "hljs-string" > '--'< / span > , < span class = "hljs-string" > '++'< / span > ]
message = isUnassignable @first.unwrapAll().value
@first.error message < span class = "hljs-keyword" > if< / span > message
< span class = "hljs-keyword" > return< / span > @compileYield o < span class = "hljs-keyword" > if< / span > @isYield()
< span class = "hljs-keyword" > return< / span > @compileUnary o < span class = "hljs-keyword" > if< / span > @isUnary()
< span class = "hljs-keyword" > return< / span > @compileChain o < span class = "hljs-keyword" > if< / span > isChain
< span class = "hljs-keyword" > switch< / span > @operator
< span class = "hljs-keyword" > when< / span > < span class = "hljs-string" > '?'< / span > < span class = "hljs-keyword" > then< / span > @compileExistence o
< span class = "hljs-keyword" > when< / span > < span class = "hljs-string" > '**'< / span > < span class = "hljs-keyword" > then< / span > @compilePower o
< span class = "hljs-keyword" > when< / span > < span class = "hljs-string" > '//'< / span > < span class = "hljs-keyword" > then< / span > @compileFloorDivision o
< span class = "hljs-keyword" > when< / span > < span class = "hljs-string" > '%%'< / span > < span class = "hljs-keyword" > then< / span > @compileModulo o
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
lhs = @first.compileToFragments o, LEVEL_OP
rhs = @second.compileToFragments o, LEVEL_OP
answer = [].concat lhs, @makeCode(< span class = "hljs-string" > " < span class = "hljs-subst" > #{@operator}< / span > "< / span > ), rhs
< span class = "hljs-keyword" > if< / span > o.level < = LEVEL_OP < span class = "hljs-keyword" > then< / span > answer < span class = "hljs-keyword" > else< / span > @wrapInBraces answer< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-152" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-152" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-08-23 10:08:39 -04:00
< p > Mimic Python’ s chained comparisons when multiple comparison operators are
2014-01-29 23:54:00 -05:00
used sequentially. For example:< / p >
2014-08-23 10:08:39 -04:00
< pre > < code > bin/coffee -e < span class = "hljs-string" > 'console.log 50 < 65 > 10'< / span >
< span class = "hljs-literal" > true< / span >
2014-01-29 23:54:00 -05:00
< / code > < / pre >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileChain: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
[@first.second, shared] = @first.second.cache o
fst = @first.compileToFragments o, LEVEL_OP
fragments = fst.concat @makeCode(< span class = "hljs-string" > " < span class = "hljs-subst" > #{< span class = "hljs-keyword" > if< / span > @invert < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > '& & '< / span > < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > '||'< / span > }< / span > "< / span > ),
(shared.compileToFragments o), @makeCode(< span class = "hljs-string" > " < span class = "hljs-subst" > #{@operator}< / span > "< / span > ), (@second.compileToFragments o, LEVEL_OP)
@wrapInBraces fragments< / pre > < / div > < / div >
2013-06-02 01:37:45 -04:00
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-153" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-153" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Keep reference to the left expression, unless this an existential assignment< / p >
2010-11-20 14:22:28 -05:00
2013-06-02 01:37:45 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileExistence: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
< span class = "hljs-keyword" > if< / span > @first.isComplex()
ref = < span class = "hljs-keyword" > new< / span > IdentifierLiteral o.scope.freeVariable < span class = "hljs-string" > 'ref'< / span >
fst = < span class = "hljs-keyword" > new< / span > Parens < span class = "hljs-keyword" > new< / span > Assign ref, @first
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
fst = @first
2013-03-18 01:06:33 -04:00
ref = fst
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > new< / span > If(< span class = "hljs-keyword" > new< / span > Existence(fst), ref, type: < span class = "hljs-string" > 'if'< / span > ).addElse(@second).compileToFragments o< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-154" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-154" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Compile a unary < strong > Op< / strong > .< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileUnary: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
2013-03-18 01:06:33 -04:00
parts = []
2016-09-22 16:19:43 -04:00
op = @operator
parts.push [@makeCode op]
< span class = "hljs-keyword" > if< / span > op < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > '!'< / span > < span class = "hljs-keyword" > and< / span > @first < span class = "hljs-keyword" > instanceof< / span > Existence
@first.negated = < span class = "hljs-keyword" > not< / span > @first.negated
< span class = "hljs-keyword" > return< / span > @first.compileToFragments o
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > o.level > = LEVEL_ACCESS
< span class = "hljs-keyword" > return< / span > (< span class = "hljs-keyword" > new< / span > Parens < span class = "hljs-keyword" > this< / span > ).compileToFragments o
plusMinus = op < span class = "hljs-keyword" > in< / span > [< span class = "hljs-string" > '+'< / span > , < span class = "hljs-string" > '-'< / span > ]
2016-09-22 16:19:43 -04:00
parts.push [@makeCode(< span class = "hljs-string" > ' '< / span > )] < span class = "hljs-keyword" > if< / span > op < span class = "hljs-keyword" > in< / span > [< span class = "hljs-string" > 'new'< / span > , < span class = "hljs-string" > 'typeof'< / span > , < span class = "hljs-string" > 'delete'< / span > ] < span class = "hljs-keyword" > or< / span >
plusMinus < span class = "hljs-keyword" > and< / span > @first < span class = "hljs-keyword" > instanceof< / span > Op < span class = "hljs-keyword" > and< / span > @first.operator < span class = "hljs-keyword" > is< / span > op
< span class = "hljs-keyword" > if< / span > (plusMinus < span class = "hljs-keyword" > and< / span > @first < span class = "hljs-keyword" > instanceof< / span > Op) < span class = "hljs-keyword" > or< / span > (op < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > 'new'< / span > < span class = "hljs-keyword" > and< / span > @first.isStatement o)
@first = < span class = "hljs-keyword" > new< / span > Parens @first
parts.push @first.compileToFragments o, LEVEL_OP
parts.reverse() < span class = "hljs-keyword" > if< / span > @flip
@joinFragmentArrays parts, < span class = "hljs-string" > ''< / span >
compileYield: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
2015-01-29 12:20:46 -05:00
parts = []
2016-09-22 16:19:43 -04:00
op = @operator
< span class = "hljs-keyword" > unless< / span > o.scope.parent?
@error < span class = "hljs-string" > 'yield can only occur inside functions'< / span >
< span class = "hljs-keyword" > if< / span > < span class = "hljs-string" > 'expression'< / span > < span class = "hljs-keyword" > in< / span > Object.keys(@first) < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > (@first < span class = "hljs-keyword" > instanceof< / span > Throw)
parts.push @first.expression.compileToFragments o, LEVEL_OP < span class = "hljs-keyword" > if< / span > @first.expression?
2015-01-29 12:20:46 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
parts.push [@makeCode < span class = "hljs-string" > "("< / span > ] < span class = "hljs-keyword" > if< / span > o.level > = LEVEL_PAREN
parts.push [@makeCode op]
parts.push [@makeCode < span class = "hljs-string" > " "< / span > ] < span class = "hljs-keyword" > if< / span > @first.base?.value < span class = "hljs-keyword" > isnt< / span > < span class = "hljs-string" > ''< / span >
parts.push @first.compileToFragments o, LEVEL_OP
parts.push [@makeCode < span class = "hljs-string" > ")"< / span > ] < span class = "hljs-keyword" > if< / span > o.level > = LEVEL_PAREN
@joinFragmentArrays parts, < span class = "hljs-string" > ''< / span >
2015-01-29 12:20:46 -05:00
2016-09-22 16:19:43 -04:00
compilePower: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-155" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2014-01-29 23:54:00 -05:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-155" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Make a Math.pow call< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > pow = < span class = "hljs-keyword" > new< / span > Value < span class = "hljs-keyword" > new< / span > IdentifierLiteral(< span class = "hljs-string" > 'Math'< / span > ), [< span class = "hljs-keyword" > new< / span > Access < span class = "hljs-keyword" > new< / span > PropertyName < span class = "hljs-string" > 'pow'< / span > ]
< span class = "hljs-keyword" > new< / span > Call(pow, [@first, @second]).compileToFragments o
2010-06-28 00:19:58 -04:00
2016-09-22 16:19:43 -04:00
compileFloorDivision: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
floor = < span class = "hljs-keyword" > new< / span > Value < span class = "hljs-keyword" > new< / span > IdentifierLiteral(< span class = "hljs-string" > 'Math'< / span > ), [< span class = "hljs-keyword" > new< / span > Access < span class = "hljs-keyword" > new< / span > PropertyName < span class = "hljs-string" > 'floor'< / span > ]
div = < span class = "hljs-keyword" > new< / span > Op < span class = "hljs-string" > '/'< / span > , @first, @second
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > new< / span > Call(floor, [div]).compileToFragments o
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
compileModulo: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
2015-01-29 12:20:46 -05:00
mod = < span class = "hljs-keyword" > new< / span > Value < span class = "hljs-keyword" > new< / span > Literal utility < span class = "hljs-string" > 'modulo'< / span > , o
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > new< / span > Call(mod, [@first, @second]).compileToFragments o
2010-06-28 00:19:58 -04:00
2016-09-22 16:19:43 -04:00
toString: < span class = "hljs-function" > < span class = "hljs-params" > (idt)< / span > -> < / span >
< span class = "hljs-keyword" > super< / span > idt, @constructor.name + < span class = "hljs-string" > ' '< / span > + @operator< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-156" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-156" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "in" > In< / h3 >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.In = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > In< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@object, @array)< / span > -> < / span >
2010-06-28 00:19:58 -04:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'object'< / span > , < span class = "hljs-string" > 'array'< / span > ]
2010-06-28 00:19:58 -04:00
2016-09-22 16:19:43 -04:00
invert: NEGATE
2010-08-04 23:14:34 -04:00
2016-09-22 16:19:43 -04:00
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
< span class = "hljs-keyword" > if< / span > @array < span class = "hljs-keyword" > instanceof< / span > Value < span class = "hljs-keyword" > and< / span > @array.isArray() < span class = "hljs-keyword" > and< / span > @array.base.objects.length
< span class = "hljs-keyword" > for< / span > obj < span class = "hljs-keyword" > in< / span > @array.base.objects < span class = "hljs-keyword" > when< / span > obj < span class = "hljs-keyword" > instanceof< / span > Splat
2014-01-29 23:54:00 -05:00
hasSplat = < span class = "hljs-literal" > yes< / span >
< span class = "hljs-keyword" > break< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-157" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2014-01-29 23:54:00 -05:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-157" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > < code > compileOrTest< / code > only if we have an array literal with no splats< / p >
2013-06-02 01:37:45 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-keyword" > return< / span > @compileOrTest o < span class = "hljs-keyword" > unless< / span > hasSplat
@compileLoopTest o
2014-01-29 23:54:00 -05:00
2016-09-22 16:19:43 -04:00
compileOrTest: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
[sub, ref] = @object.cache o, LEVEL_OP
[cmp, cnj] = < span class = "hljs-keyword" > if< / span > @negated < span class = "hljs-keyword" > then< / span > [< span class = "hljs-string" > ' !== '< / span > , < span class = "hljs-string" > ' & & '< / span > ] < span class = "hljs-keyword" > else< / span > [< span class = "hljs-string" > ' === '< / span > , < span class = "hljs-string" > ' || '< / span > ]
2014-01-29 23:54:00 -05:00
tests = []
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > for< / span > item, i < span class = "hljs-keyword" > in< / span > @array.base.objects
< span class = "hljs-keyword" > if< / span > i < span class = "hljs-keyword" > then< / span > tests.push @makeCode cnj
tests = tests.concat (< span class = "hljs-keyword" > if< / span > i < span class = "hljs-keyword" > then< / span > ref < span class = "hljs-keyword" > else< / span > sub), @makeCode(cmp), item.compileToFragments(o, LEVEL_ACCESS)
< span class = "hljs-keyword" > if< / span > o.level < LEVEL_OP < span class = "hljs-keyword" > then< / span > tests < span class = "hljs-keyword" > else< / span > @wrapInBraces tests
compileLoopTest: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
[sub, ref] = @object.cache o, LEVEL_LIST
fragments = [].concat @makeCode(utility(< span class = "hljs-string" > 'indexOf'< / span > , o) + < span class = "hljs-string" > ".call("< / span > ), @array.compileToFragments(o, LEVEL_LIST),
@makeCode(< span class = "hljs-string" > ", "< / span > ), ref, @makeCode(< span class = "hljs-string" > ") "< / span > + < span class = "hljs-keyword" > if< / span > @negated < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > '< 0'< / span > < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > '> = 0'< / span > )
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > fragments < span class = "hljs-keyword" > if< / span > fragmentsToText(sub) < span class = "hljs-keyword" > is< / span > fragmentsToText(ref)
2016-09-22 16:19:43 -04:00
fragments = sub.concat @makeCode(< span class = "hljs-string" > ', '< / span > ), fragments
< span class = "hljs-keyword" > if< / span > o.level < LEVEL_LIST < span class = "hljs-keyword" > then< / span > fragments < span class = "hljs-keyword" > else< / span > @wrapInBraces fragments
2014-01-29 23:54:00 -05:00
2016-09-22 16:19:43 -04:00
toString: < span class = "hljs-function" > < span class = "hljs-params" > (idt)< / span > -> < / span >
< span class = "hljs-keyword" > super< / span > idt, @constructor.name + < span class = "hljs-keyword" > if< / span > @negated < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > '!'< / span > < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > ''< / span > < / pre > < / div > < / div >
2014-01-29 23:54:00 -05:00
2013-06-02 01:37:45 -04:00
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-158" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-158" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "try" > Try< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-159" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-159" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
< p > A classic < em > try/catch/finally< / em > block.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Try = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Try< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@attempt, @errorVariable, @recovery, @ensure)< / span > -> < / span >
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'attempt'< / span > , < span class = "hljs-string" > 'recovery'< / span > , < span class = "hljs-string" > 'ensure'< / span > ]
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
isStatement: YES
2010-08-04 23:14:34 -04:00
2016-09-22 16:19:43 -04:00
jumps: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span > @attempt.jumps(o) < span class = "hljs-keyword" > or< / span > @recovery?.jumps(o)
2010-12-24 14:02:10 -05:00
2016-09-22 16:19:43 -04:00
makeReturn: < span class = "hljs-function" > < span class = "hljs-params" > (res)< / span > -> < / span >
@attempt = @attempt .makeReturn res < span class = "hljs-keyword" > if< / span > @attempt
@recovery = @recovery.makeReturn res < span class = "hljs-keyword" > if< / span > @recovery
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > this< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-160" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-160" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< p > Compilation is more or less as you would expect – the < em > finally< / em > clause
2014-01-29 23:54:00 -05:00
is optional, the < em > catch< / em > is not.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
2013-03-18 01:06:33 -04:00
o.indent += TAB
2016-09-22 16:19:43 -04:00
tryPart = @attempt.compileToFragments o, LEVEL_TOP
catchPart = < span class = "hljs-keyword" > if< / span > @recovery
generatedErrorVariableName = o.scope.freeVariable < span class = "hljs-string" > 'error'< / span > , reserve: < span class = "hljs-literal" > no< / span >
placeholder = < span class = "hljs-keyword" > new< / span > IdentifierLiteral generatedErrorVariableName
< span class = "hljs-keyword" > if< / span > @errorVariable
message = isUnassignable @errorVariable.unwrapAll().value
@errorVariable.error message < span class = "hljs-keyword" > if< / span > message
@recovery.unshift < span class = "hljs-keyword" > new< / span > Assign @errorVariable, placeholder
[].concat @makeCode(< span class = "hljs-string" > " catch ("< / span > ), placeholder.compileToFragments(o), @makeCode(< span class = "hljs-string" > ") {\n"< / span > ),
@recovery.compileToFragments(o, LEVEL_TOP), @makeCode(< span class = "hljs-string" > "\n< span class = "hljs-subst" > #{@tab}< / span > }"< / span > )
< span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > unless< / span > @ensure < span class = "hljs-keyword" > or< / span > @recovery
generatedErrorVariableName = o.scope.freeVariable < span class = "hljs-string" > 'error'< / span > , reserve: < span class = "hljs-literal" > no< / span >
[@makeCode(< span class = "hljs-string" > " catch (< span class = "hljs-subst" > #{generatedErrorVariableName}< / span > ) {}"< / span > )]
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2013-03-18 01:06:33 -04:00
[]
2012-04-10 14:57:45 -04:00
2016-09-22 16:19:43 -04:00
ensurePart = < span class = "hljs-keyword" > if< / span > @ensure < span class = "hljs-keyword" > then< / span > ([].concat @makeCode(< span class = "hljs-string" > " finally {\n"< / span > ), @ensure.compileToFragments(o, LEVEL_TOP),
@makeCode(< span class = "hljs-string" > "\n< span class = "hljs-subst" > #{@tab}< / span > }"< / span > )) < span class = "hljs-keyword" > else< / span > []
2012-04-10 14:57:45 -04:00
2016-09-22 16:19:43 -04:00
[].concat @makeCode(< span class = "hljs-string" > "< span class = "hljs-subst" > #{@tab}< / span > try {\n"< / span > ),
2013-03-18 01:06:33 -04:00
tryPart,
2016-09-22 16:19:43 -04:00
@makeCode(< span class = "hljs-string" > "\n< span class = "hljs-subst" > #{@tab}< / span > }"< / span > ), catchPart, ensurePart< / pre > < / div > < / div >
2013-06-02 01:37:45 -04:00
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-161" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-161" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "throw" > Throw< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-162" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-162" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
< p > Simple node to throw an exception.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Throw = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Throw< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@expression)< / span > -> < / span >
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'expression'< / span > ]
2010-06-28 00:19:58 -04:00
2016-09-22 16:19:43 -04:00
isStatement: YES
jumps: NO< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-163" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-163" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-08-23 10:08:39 -04:00
< p > A < strong > Throw< / strong > is already a return, of sorts…< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > makeReturn: THIS
2013-06-02 01:37:45 -04:00
2016-09-22 16:19:43 -04:00
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
[].concat @makeCode(@tab + < span class = "hljs-string" > "throw "< / span > ), @expression.compileToFragments(o), @makeCode(< span class = "hljs-string" > ";"< / span > )< / pre > < / div > < / div >
2013-06-02 01:37:45 -04:00
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-164" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-164" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "existence" > Existence< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-165" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-165" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< p > Checks a variable for existence – not < em > null< / em > and not < em > undefined< / em > . This is
2010-12-24 14:02:10 -05:00
similar to < code > .nil?< / code > in Ruby, and avoids having to consult a JavaScript truth
2014-01-29 23:54:00 -05:00
table.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Existence = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Existence< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@expression)< / span > -> < / span >
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'expression'< / span > ]
2010-06-28 00:19:58 -04:00
2016-09-22 16:19:43 -04:00
invert: NEGATE
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
@expression.front = @front
code = @expression.compile o, LEVEL_OP
< span class = "hljs-keyword" > if< / span > @expression.unwrap() < span class = "hljs-keyword" > instanceof< / span > IdentifierLiteral < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > o.scope.check code
[cmp, cnj] = < span class = "hljs-keyword" > if< / span > @negated < span class = "hljs-keyword" > then< / span > [< span class = "hljs-string" > '==='< / span > , < span class = "hljs-string" > '||'< / span > ] < span class = "hljs-keyword" > else< / span > [< span class = "hljs-string" > '!=='< / span > , < span class = "hljs-string" > '& & '< / span > ]
2014-01-29 23:54:00 -05:00
code = < span class = "hljs-string" > "typeof < span class = "hljs-subst" > #{code}< / span > < span class = "hljs-subst" > #{cmp}< / span > \"undefined\" < span class = "hljs-subst" > #{cnj}< / span > < span class = "hljs-subst" > #{code}< / span > < span class = "hljs-subst" > #{cmp}< / span > null"< / span >
< span class = "hljs-keyword" > else< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-166" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-166" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > do not use strict equality here; it will break existing code< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > code = < span class = "hljs-string" > "< span class = "hljs-subst" > #{code}< / span > < span class = "hljs-subst" > #{< span class = "hljs-keyword" > if< / span > @negated < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > '=='< / span > < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > '!='< / span > }< / span > null"< / span >
[@makeCode(< span class = "hljs-keyword" > if< / span > o.level < = LEVEL_COND < span class = "hljs-keyword" > then< / span > code < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > "(< span class = "hljs-subst" > #{code}< / span > )"< / span > )]< / pre > < / div > < / div >
2013-06-02 01:37:45 -04:00
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-167" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-167" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "parens" > Parens< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-168" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-168" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
< p > An extra set of parentheses, specified explicitly in the source. At one time
2010-12-24 14:02:10 -05:00
we tried to clean up the results by detecting and removing redundant
2016-09-22 16:19:43 -04:00
parentheses, but no longer – you can put in as many as you please.< / p >
2014-01-29 23:54:00 -05:00
< p > Parentheses are a good way to force any statement to become an expression.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Parens = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Parens< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@body)< / span > -> < / span >
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'body'< / span > ]
2010-03-23 00:18:50 -04:00
2016-09-22 16:19:43 -04:00
unwrap : < span class = "hljs-function" > -> < / span > @body
isComplex : < span class = "hljs-function" > -> < / span > @body.isComplex()
2010-07-11 10:40:44 -04:00
2016-09-22 16:19:43 -04:00
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
expr = @body.unwrap()
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > expr < span class = "hljs-keyword" > instanceof< / span > Value < span class = "hljs-keyword" > and< / span > expr.isAtomic()
2016-09-22 16:19:43 -04:00
expr.front = @front
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > expr.compileToFragments o
2013-03-18 01:06:33 -04:00
fragments = expr.compileToFragments o, LEVEL_PAREN
2014-01-29 23:54:00 -05:00
bare = o.level < LEVEL_OP < span class = "hljs-keyword" > and< / span > (expr < span class = "hljs-keyword" > instanceof< / span > Op < span class = "hljs-keyword" > or< / span > expr < span class = "hljs-keyword" > instanceof< / span > Call < span class = "hljs-keyword" > or< / span >
(expr < span class = "hljs-keyword" > instanceof< / span > For < span class = "hljs-keyword" > and< / span > expr.returns))
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > bare < span class = "hljs-keyword" > then< / span > fragments < span class = "hljs-keyword" > else< / span > @wrapInBraces fragments< / pre > < / div > < / div >
2013-06-02 01:37:45 -04:00
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-169" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-169" > ¶ < / a >
< / div >
< h3 id = "stringwithinterpolations" > StringWithInterpolations< / h3 >
< / div >
< / li >
< li id = "section-170" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-170" > ¶ < / a >
< / div >
< p > Strings with interpolations are in fact just a variation of < code > Parens< / code > with
string concatenation inside.< / p >
< / div >
< div class = "content" > < div class = 'highlight' > < pre >
exports.StringWithInterpolations = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > StringWithInterpolations< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Parens< / span > < / span > < / pre > < / div > < / div >
< / li >
< li id = "section-171" >
< div class = "annotation" >
< div class = "pilwrap " >
< a class = "pilcrow" href = "#section-171" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "for" > For< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-172" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-172" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
< p > CoffeeScript’ s replacement for the < em > for< / em > loop is our array and object
2010-12-24 14:02:10 -05:00
comprehensions, that compile into < em > for< / em > loops here. They also act as an
2014-01-29 23:54:00 -05:00
expression, able to return the result of each filtered iteration.< / p >
2010-12-24 14:02:10 -05:00
< p > Unlike Python array comprehensions, they can be multi-line, and you can pass
the current index of the loop as a second parameter. Unlike Ruby blocks,
2014-01-29 23:54:00 -05:00
you can map and filter in a single pass.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.For = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > For< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > While< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (body, source)< / span > -> < / span >
{@source, @guard, @step, @name, @index} = source
@body = Block.wrap [body]
@own = !!source.own
@object = !!source.object
[@name, @index] = [@index, @name] < span class = "hljs-keyword" > if< / span > @object
@index.error < span class = "hljs-string" > 'index cannot be a pattern matching expression'< / span > < span class = "hljs-keyword" > if< / span > @index < span class = "hljs-keyword" > instanceof< / span > Value
@range = @source < span class = "hljs-keyword" > instanceof< / span > Value < span class = "hljs-keyword" > and< / span > @source.base < span class = "hljs-keyword" > instanceof< / span > Range < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > @source.properties.length
@pattern = @name < span class = "hljs-keyword" > instanceof< / span > Value
@index.error < span class = "hljs-string" > 'indexes do not apply to range loops'< / span > < span class = "hljs-keyword" > if< / span > @range < span class = "hljs-keyword" > and< / span > @index
@name.error < span class = "hljs-string" > 'cannot pattern match over range loops'< / span > < span class = "hljs-keyword" > if< / span > @range < span class = "hljs-keyword" > and< / span > @pattern
@name.error < span class = "hljs-string" > 'cannot use own with for-in'< / span > < span class = "hljs-keyword" > if< / span > @own < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > @object
@returns = < span class = "hljs-literal" > false< / span >
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'body'< / span > , < span class = "hljs-string" > 'source'< / span > , < span class = "hljs-string" > 'guard'< / span > , < span class = "hljs-string" > 'step'< / span > ]< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-173" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-173" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > Welcome to the hairiest method in all of CoffeeScript. Handles the inner
2010-12-24 14:02:10 -05:00
loop, filtering, stepping, and result saving for array, object, and range
comprehensions. Some of the generated code can be shared in common, and
2014-01-29 23:54:00 -05:00
some cannot.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
body = Block.wrap [@body]
2015-02-18 15:43:33 -05:00
[..., last] = body.expressions
2016-09-22 16:19:43 -04:00
@returns = < span class = "hljs-literal" > no< / span > < span class = "hljs-keyword" > if< / span > last?.jumps() < span class = "hljs-keyword" > instanceof< / span > Return
source = < span class = "hljs-keyword" > if< / span > @range < span class = "hljs-keyword" > then< / span > @source.base < span class = "hljs-keyword" > else< / span > @source
2015-02-18 15:43:33 -05:00
scope = o.scope
2016-09-22 16:19:43 -04:00
name = @name < span class = "hljs-keyword" > and< / span > (@name.compile o, LEVEL_LIST) < span class = "hljs-keyword" > if< / span > < span class = "hljs-keyword" > not< / span > @pattern
index = @index < span class = "hljs-keyword" > and< / span > (@index.compile o, LEVEL_LIST)
scope.find(name) < span class = "hljs-keyword" > if< / span > name < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > @pattern
2014-01-29 23:54:00 -05:00
scope.find(index) < span class = "hljs-keyword" > if< / span > index
2016-09-22 16:19:43 -04:00
rvar = scope.freeVariable < span class = "hljs-string" > 'results'< / span > < span class = "hljs-keyword" > if< / span > @returns
ivar = (@object < span class = "hljs-keyword" > and< / span > index) < span class = "hljs-keyword" > or< / span > scope.freeVariable < span class = "hljs-string" > 'i'< / span > , single: < span class = "hljs-literal" > true< / span >
kvar = (@range < span class = "hljs-keyword" > and< / span > name) < span class = "hljs-keyword" > or< / span > index < span class = "hljs-keyword" > or< / span > ivar
2015-02-18 15:43:33 -05:00
kvarAssign = < span class = "hljs-keyword" > if< / span > kvar < span class = "hljs-keyword" > isnt< / span > ivar < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > "< span class = "hljs-subst" > #{kvar}< / span > = "< / span > < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > ""< / span >
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > @step < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > @range
[step, stepVar] = @cacheToCodeFragments @step.cache o, LEVEL_LIST, isComplexOrAssignable
stepNum = Number stepVar < span class = "hljs-keyword" > if< / span > @step.isNumber()
name = ivar < span class = "hljs-keyword" > if< / span > @pattern
2015-02-18 15:43:33 -05:00
varPart = < span class = "hljs-string" > ''< / span >
guardPart = < span class = "hljs-string" > ''< / span >
defPart = < span class = "hljs-string" > ''< / span >
2016-09-22 16:19:43 -04:00
idt1 = @tab + TAB
< span class = "hljs-keyword" > if< / span > @range
2015-02-18 15:43:33 -05:00
forPartFragments = source.compileToFragments merge o,
2016-09-22 16:19:43 -04:00
{index: ivar, name, @step, isComplex: isComplexOrAssignable}
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
svar = @source.compile o, LEVEL_LIST
< span class = "hljs-keyword" > if< / span > (name < span class = "hljs-keyword" > or< / span > @own) < span class = "hljs-keyword" > and< / span > @source.unwrap() < span class = "hljs-keyword" > not< / span > < span class = "hljs-keyword" > instanceof< / span > IdentifierLiteral
defPart += < span class = "hljs-string" > "< span class = "hljs-subst" > #{@tab}< / span > < span class = "hljs-subst" > #{ref = scope.freeVariable < span class = "hljs-string" > 'ref'< / span > }< / span > = < span class = "hljs-subst" > #{svar}< / span > ;\n"< / span >
2013-03-18 01:06:33 -04:00
svar = ref
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > name < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > @pattern
2014-01-29 23:54:00 -05:00
namePart = < span class = "hljs-string" > "< span class = "hljs-subst" > #{name}< / span > = < span class = "hljs-subst" > #{svar}< / span > [< span class = "hljs-subst" > #{kvar}< / span > ]"< / span >
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > < span class = "hljs-keyword" > not< / span > @object
defPart += < span class = "hljs-string" > "< span class = "hljs-subst" > #{@tab}< / span > < span class = "hljs-subst" > #{step}< / span > ;\n"< / span > < span class = "hljs-keyword" > if< / span > step < span class = "hljs-keyword" > isnt< / span > stepVar
down = stepNum < < span class = "hljs-number" > 0< / span >
lvar = scope.freeVariable < span class = "hljs-string" > 'len'< / span > < span class = "hljs-keyword" > unless< / span > @step < span class = "hljs-keyword" > and< / span > stepNum? < span class = "hljs-keyword" > and< / span > down
2014-01-29 23:54:00 -05:00
declare = < span class = "hljs-string" > "< span class = "hljs-subst" > #{kvarAssign}< / span > < span class = "hljs-subst" > #{ivar}< / span > = 0, < span class = "hljs-subst" > #{lvar}< / span > = < span class = "hljs-subst" > #{svar}< / span > .length"< / span >
declareDown = < span class = "hljs-string" > "< span class = "hljs-subst" > #{kvarAssign}< / span > < span class = "hljs-subst" > #{ivar}< / span > = < span class = "hljs-subst" > #{svar}< / span > .length - 1"< / span >
compare = < span class = "hljs-string" > "< span class = "hljs-subst" > #{ivar}< / span > < < span class = "hljs-subst" > #{lvar}< / span > "< / span >
compareDown = < span class = "hljs-string" > "< span class = "hljs-subst" > #{ivar}< / span > > = 0"< / span >
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > @step
< span class = "hljs-keyword" > if< / span > stepNum?
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > down
2013-03-18 01:06:33 -04:00
compare = compareDown
declare = declareDown
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
compare = < span class = "hljs-string" > "< span class = "hljs-subst" > #{stepVar}< / span > > 0 ? < span class = "hljs-subst" > #{compare}< / span > : < span class = "hljs-subst" > #{compareDown}< / span > "< / span >
declare = < span class = "hljs-string" > "(< span class = "hljs-subst" > #{stepVar}< / span > > 0 ? (< span class = "hljs-subst" > #{declare}< / span > ) : < span class = "hljs-subst" > #{declareDown}< / span > )"< / span >
increment = < span class = "hljs-string" > "< span class = "hljs-subst" > #{ivar}< / span > += < span class = "hljs-subst" > #{stepVar}< / span > "< / span >
< span class = "hljs-keyword" > else< / span >
increment = < span class = "hljs-string" > "< span class = "hljs-subst" > #{< span class = "hljs-keyword" > if< / span > kvar < span class = "hljs-keyword" > isnt< / span > ivar < span class = "hljs-keyword" > then< / span > < span class = "hljs-string" > "++< span class = "hljs-subst" > #{ivar}< / span > "< / span > < span class = "hljs-keyword" > else< / span > < span class = "hljs-string" > "< span class = "hljs-subst" > #{ivar}< / span > ++"< / span > }< / span > "< / span >
2016-09-22 16:19:43 -04:00
forPartFragments = [@makeCode(< span class = "hljs-string" > "< span class = "hljs-subst" > #{declare}< / span > ; < span class = "hljs-subst" > #{compare}< / span > ; < span class = "hljs-subst" > #{kvarAssign}< / span > < span class = "hljs-subst" > #{increment}< / span > "< / span > )]
< span class = "hljs-keyword" > if< / span > @returns
resultPart = < span class = "hljs-string" > "< span class = "hljs-subst" > #{@tab}< / span > < span class = "hljs-subst" > #{rvar}< / span > = [];\n"< / span >
returnResult = < span class = "hljs-string" > "\n< span class = "hljs-subst" > #{@tab}< / span > return < span class = "hljs-subst" > #{rvar}< / span > ;"< / span >
2013-03-18 01:06:33 -04:00
body.makeReturn rvar
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > @guard
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > body.expressions.length > < span class = "hljs-number" > 1< / span >
2016-09-22 16:19:43 -04:00
body.expressions.unshift < span class = "hljs-keyword" > new< / span > If (< span class = "hljs-keyword" > new< / span > Parens @guard).invert(), < span class = "hljs-keyword" > new< / span > StatementLiteral < span class = "hljs-string" > "continue"< / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
body = Block.wrap [< span class = "hljs-keyword" > new< / span > If @guard, body] < span class = "hljs-keyword" > if< / span > @guard
< span class = "hljs-keyword" > if< / span > @pattern
body.expressions.unshift < span class = "hljs-keyword" > new< / span > Assign @name, < span class = "hljs-keyword" > new< / span > Literal < span class = "hljs-string" > "< span class = "hljs-subst" > #{svar}< / span > [< span class = "hljs-subst" > #{kvar}< / span > ]"< / span >
defPartFragments = [].concat @makeCode(defPart), @pluckDirectCall(o, body)
2014-01-29 23:54:00 -05:00
varPart = < span class = "hljs-string" > "\n< span class = "hljs-subst" > #{idt1}< / span > < span class = "hljs-subst" > #{namePart}< / span > ;"< / span > < span class = "hljs-keyword" > if< / span > namePart
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > @object
forPartFragments = [@makeCode(< span class = "hljs-string" > "< span class = "hljs-subst" > #{kvar}< / span > in < span class = "hljs-subst" > #{svar}< / span > "< / span > )]
guardPart = < span class = "hljs-string" > "\n< span class = "hljs-subst" > #{idt1}< / span > if (!< span class = "hljs-subst" > #{utility < span class = "hljs-string" > 'hasProp'< / span > , o}< / span > .call(< span class = "hljs-subst" > #{svar}< / span > , < span class = "hljs-subst" > #{kvar}< / span > )) continue;"< / span > < span class = "hljs-keyword" > if< / span > @own
bodyFragments = body.compileToFragments merge(o, indent: idt1), LEVEL_TOP
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > bodyFragments < span class = "hljs-keyword" > and< / span > (bodyFragments.length > < span class = "hljs-number" > 0< / span > )
2016-09-22 16:19:43 -04:00
bodyFragments = [].concat @makeCode(< span class = "hljs-string" > "\n"< / span > ), bodyFragments, @makeCode(< span class = "hljs-string" > "\n"< / span > )
[].concat defPartFragments, @makeCode(< span class = "hljs-string" > "< span class = "hljs-subst" > #{resultPart < span class = "hljs-keyword" > or< / span > < span class = "hljs-string" > ''< / span > }< / span > < span class = "hljs-subst" > #{@tab}< / span > for ("< / span > ),
forPartFragments, @makeCode(< span class = "hljs-string" > ") {< span class = "hljs-subst" > #{guardPart}< / span > < span class = "hljs-subst" > #{varPart}< / span > "< / span > ), bodyFragments,
@makeCode(< span class = "hljs-string" > "< span class = "hljs-subst" > #{@tab}< / span > }< span class = "hljs-subst" > #{returnResult < span class = "hljs-keyword" > or< / span > < span class = "hljs-string" > ''< / span > }< / span > "< / span > )
2014-01-29 23:54:00 -05:00
2016-09-22 16:19:43 -04:00
pluckDirectCall: < span class = "hljs-function" > < span class = "hljs-params" > (o, body)< / span > -> < / span >
2013-03-18 01:06:33 -04:00
defs = []
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > for< / span > expr, idx < span class = "hljs-keyword" > in< / span > body.expressions
2013-03-18 01:06:33 -04:00
expr = expr.unwrapAll()
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > continue< / span > < span class = "hljs-keyword" > unless< / span > expr < span class = "hljs-keyword" > instanceof< / span > Call
val = expr.variable?.unwrapAll()
< span class = "hljs-keyword" > continue< / span > < span class = "hljs-keyword" > unless< / span > (val < span class = "hljs-keyword" > instanceof< / span > Code) < span class = "hljs-keyword" > or< / span >
(val < span class = "hljs-keyword" > instanceof< / span > Value < span class = "hljs-keyword" > and< / span >
val.base?.unwrapAll() < span class = "hljs-keyword" > instanceof< / span > Code < span class = "hljs-keyword" > and< / span >
val.properties.length < span class = "hljs-keyword" > is< / span > < span class = "hljs-number" > 1< / span > < span class = "hljs-keyword" > and< / span >
val.properties[< span class = "hljs-number" > 0< / span > ].name?.value < span class = "hljs-keyword" > in< / span > [< span class = "hljs-string" > 'call'< / span > , < span class = "hljs-string" > 'apply'< / span > ])
fn = val.base?.unwrapAll() < span class = "hljs-keyword" > or< / span > val
2016-09-22 16:19:43 -04:00
ref = < span class = "hljs-keyword" > new< / span > IdentifierLiteral o.scope.freeVariable < span class = "hljs-string" > 'fn'< / span >
2014-01-29 23:54:00 -05:00
base = < span class = "hljs-keyword" > new< / span > Value ref
< span class = "hljs-keyword" > if< / span > val.base
2013-03-18 01:06:33 -04:00
[val.base, base] = [base, val]
2014-01-29 23:54:00 -05:00
body.expressions[idx] = < span class = "hljs-keyword" > new< / span > Call base, expr.args
2016-09-22 16:19:43 -04:00
defs = defs.concat @makeCode(@tab), (< span class = "hljs-keyword" > new< / span > Assign(ref, fn).compileToFragments(o, LEVEL_TOP)), @makeCode(< span class = "hljs-string" > ';\n'< / span > )
2013-03-18 01:06:33 -04:00
defs< / pre > < / div > < / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-174" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-174" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "switch" > Switch< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-175" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-175" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
< p > A JavaScript < em > switch< / em > statement. Converts into a returnable expression on-demand.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.Switch = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > Switch< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (@subject, @cases, @otherwise)< / span > -> < / span >
2010-09-16 00:32:57 -04:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'subject'< / span > , < span class = "hljs-string" > 'cases'< / span > , < span class = "hljs-string" > 'otherwise'< / span > ]
2010-09-16 00:32:57 -04:00
2016-09-22 16:19:43 -04:00
isStatement: YES
2010-09-16 00:32:57 -04:00
2016-09-22 16:19:43 -04:00
jumps: < span class = "hljs-function" > < span class = "hljs-params" > (o = {block: < span class = "hljs-literal" > yes< / span > })< / span > -> < / span >
< span class = "hljs-keyword" > for< / span > [conds, block] < span class = "hljs-keyword" > in< / span > @cases
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > return< / span > jumpNode < span class = "hljs-keyword" > if< / span > jumpNode = block.jumps o
2016-09-22 16:19:43 -04:00
@otherwise?.jumps o
2010-12-24 14:02:10 -05:00
2016-09-22 16:19:43 -04:00
makeReturn: < span class = "hljs-function" > < span class = "hljs-params" > (res)< / span > -> < / span >
pair[< span class = "hljs-number" > 1< / span > ].makeReturn res < span class = "hljs-keyword" > for< / span > pair < span class = "hljs-keyword" > in< / span > @cases
@otherwise < span class = "hljs-keyword" > or< / span > = < span class = "hljs-keyword" > new< / span > Block [< span class = "hljs-keyword" > new< / span > Literal < span class = "hljs-string" > 'void 0'< / span > ] < span class = "hljs-keyword" > if< / span > res
@otherwise?.makeReturn res
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > this< / span >
2010-09-16 00:32:57 -04:00
2016-09-22 16:19:43 -04:00
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
2013-03-18 01:06:33 -04:00
idt1 = o.indent + TAB
idt2 = o.indent = idt1 + TAB
2016-09-22 16:19:43 -04:00
fragments = [].concat @makeCode(@tab + < span class = "hljs-string" > "switch ("< / span > ),
(< span class = "hljs-keyword" > if< / span > @subject < span class = "hljs-keyword" > then< / span > @subject.compileToFragments(o, LEVEL_PAREN) < span class = "hljs-keyword" > else< / span > @makeCode < span class = "hljs-string" > "false"< / span > ),
@makeCode(< span class = "hljs-string" > ") {\n"< / span > )
< span class = "hljs-keyword" > for< / span > [conditions, block], i < span class = "hljs-keyword" > in< / span > @cases
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > for< / span > cond < span class = "hljs-keyword" > in< / span > flatten [conditions]
2016-09-22 16:19:43 -04:00
cond = cond.invert() < span class = "hljs-keyword" > unless< / span > @subject
fragments = fragments.concat @makeCode(idt1 + < span class = "hljs-string" > "case "< / span > ), cond.compileToFragments(o, LEVEL_PAREN), @makeCode(< span class = "hljs-string" > ":\n"< / span > )
fragments = fragments.concat body, @makeCode(< span class = "hljs-string" > '\n'< / span > ) < span class = "hljs-keyword" > if< / span > (body = block.compileToFragments o, LEVEL_TOP).length > < span class = "hljs-number" > 0< / span >
< span class = "hljs-keyword" > break< / span > < span class = "hljs-keyword" > if< / span > i < span class = "hljs-keyword" > is< / span > @cases.length - < span class = "hljs-number" > 1< / span > < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > @otherwise
expr = @lastNonComment block.expressions
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > continue< / span > < span class = "hljs-keyword" > if< / span > expr < span class = "hljs-keyword" > instanceof< / span > Return < span class = "hljs-keyword" > or< / span > (expr < span class = "hljs-keyword" > instanceof< / span > Literal < span class = "hljs-keyword" > and< / span > expr.jumps() < span class = "hljs-keyword" > and< / span > expr.value < span class = "hljs-keyword" > isnt< / span > < span class = "hljs-string" > 'debugger'< / span > )
fragments.push cond.makeCode(idt2 + < span class = "hljs-string" > 'break;\n'< / span > )
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > if< / span > @otherwise < span class = "hljs-keyword" > and< / span > @otherwise.expressions.length
fragments.push @makeCode(idt1 + < span class = "hljs-string" > "default:\n"< / span > ), (@otherwise.compileToFragments o, LEVEL_TOP)..., @makeCode(< span class = "hljs-string" > "\n"< / span > )
fragments.push @makeCode @tab + < span class = "hljs-string" > '}'< / span >
2013-03-18 01:06:33 -04:00
fragments< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-176" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-176" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h3 id = "if" > If< / h3 >
2014-08-23 10:08:39 -04:00
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-177" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-177" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
< p > < em > If/else< / em > statements. Acts as an expression by pushing down requested returns
2014-01-29 23:54:00 -05:00
to the last line of each clause.< / p >
2010-12-24 14:02:10 -05:00
< p > Single-expression < strong > Ifs< / strong > are compiled into conditional operators if possible,
2014-08-23 10:08:39 -04:00
because ternaries are already proper expressions, and don’ t need conversion.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > exports.If = < span class = "hljs-class" > < span class = "hljs-keyword" > class< / span > < span class = "hljs-title" > If< / span > < span class = "hljs-keyword" > extends< / span > < span class = "hljs-title" > Base< / span > < / span >
constructor: < span class = "hljs-function" > < span class = "hljs-params" > (condition, @body, options = {})< / span > -> < / span >
@condition = < span class = "hljs-keyword" > if< / span > options.type < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > 'unless'< / span > < span class = "hljs-keyword" > then< / span > condition.invert() < span class = "hljs-keyword" > else< / span > condition
@elseBody = < span class = "hljs-literal" > null< / span >
@isChain = < span class = "hljs-literal" > false< / span >
{@soak} = options
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
children: [< span class = "hljs-string" > 'condition'< / span > , < span class = "hljs-string" > 'body'< / span > , < span class = "hljs-string" > 'elseBody'< / span > ]
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
bodyNode: < span class = "hljs-function" > -> < / span > @body?.unwrap()
elseBodyNode: < span class = "hljs-function" > -> < / span > @elseBody?.unwrap()< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-178" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-178" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Rewrite a chain of < strong > Ifs< / strong > to add a default case as the final < em > else< / em > .< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > addElse: < span class = "hljs-function" > < span class = "hljs-params" > (elseBody)< / span > -> < / span >
< span class = "hljs-keyword" > if< / span > @isChain
@elseBodyNode().addElse elseBody
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
@isChain = elseBody < span class = "hljs-keyword" > instanceof< / span > If
@elseBody = @ensureBlock elseBody
@elseBody.updateLocationDataIfMissing elseBody.locationData
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > this< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-179" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-179" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > The < strong > If< / strong > only compiles into a statement if either of its bodies needs
2014-01-29 23:54:00 -05:00
to be a statement. Otherwise a conditional operator is safe.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > isStatement: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
o?.level < span class = "hljs-keyword" > is< / span > LEVEL_TOP < span class = "hljs-keyword" > or< / span >
2016-09-22 16:19:43 -04:00
@bodyNode().isStatement(o) < span class = "hljs-keyword" > or< / span > @elseBodyNode()?.isStatement(o)
2010-03-06 23:48:06 -05:00
2016-09-22 16:19:43 -04:00
jumps: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span > @body.jumps(o) < span class = "hljs-keyword" > or< / span > @elseBody?.jumps(o)
2010-12-24 14:02:10 -05:00
2016-09-22 16:19:43 -04:00
compileNode: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
< span class = "hljs-keyword" > if< / span > @isStatement o < span class = "hljs-keyword" > then< / span > @compileStatement o < span class = "hljs-keyword" > else< / span > @compileExpression o
2010-03-23 00:18:50 -04:00
2016-09-22 16:19:43 -04:00
makeReturn: < span class = "hljs-function" > < span class = "hljs-params" > (res)< / span > -> < / span >
@elseBody < span class = "hljs-keyword" > or< / span > = < span class = "hljs-keyword" > new< / span > Block [< span class = "hljs-keyword" > new< / span > Literal < span class = "hljs-string" > 'void 0'< / span > ] < span class = "hljs-keyword" > if< / span > res
@body < span class = "hljs-keyword" > and< / span > = < span class = "hljs-keyword" > new< / span > Block [@body.makeReturn res]
@elseBody < span class = "hljs-keyword" > and< / span > = < span class = "hljs-keyword" > new< / span > Block [@elseBody.makeReturn res]
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > this< / span >
2010-05-04 23:31:28 -04:00
2016-09-22 16:19:43 -04:00
ensureBlock: < span class = "hljs-function" > < span class = "hljs-params" > (node)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > node < span class = "hljs-keyword" > instanceof< / span > Block < span class = "hljs-keyword" > then< / span > node < span class = "hljs-keyword" > else< / span > < span class = "hljs-keyword" > new< / span > Block [node]< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-180" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-180" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
< p > Compile the < code > If< / code > as a regular < em > if-else< / em > statement. Flattened chains
2014-01-29 23:54:00 -05:00
force inner < em > else< / em > bodies into statement form.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileStatement: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
child = del o, < span class = "hljs-string" > 'chainChild'< / span >
exeq = del o, < span class = "hljs-string" > 'isExistentialEquals'< / span >
2011-08-04 23:17:23 -04:00
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > if< / span > exeq
2016-09-22 16:19:43 -04:00
< span class = "hljs-keyword" > return< / span > < span class = "hljs-keyword" > new< / span > If(@condition.invert(), @elseBodyNode(), type: < span class = "hljs-string" > 'if'< / span > ).compileToFragments o
2011-08-04 23:17:23 -04:00
2013-03-18 01:06:33 -04:00
indent = o.indent + TAB
2016-09-22 16:19:43 -04:00
cond = @condition.compileToFragments o, LEVEL_PAREN
body = @ensureBlock(@body).compileToFragments merge o, {indent}
ifPart = [].concat @makeCode(< span class = "hljs-string" > "if ("< / span > ), cond, @makeCode(< span class = "hljs-string" > ") {\n"< / span > ), body, @makeCode(< span class = "hljs-string" > "\n< span class = "hljs-subst" > #{@tab}< / span > }"< / span > )
ifPart.unshift @makeCode @tab < span class = "hljs-keyword" > unless< / span > child
< span class = "hljs-keyword" > return< / span > ifPart < span class = "hljs-keyword" > unless< / span > @elseBody
answer = ifPart.concat @makeCode(< span class = "hljs-string" > ' else '< / span > )
< span class = "hljs-keyword" > if< / span > @isChain
2014-01-29 23:54:00 -05:00
o.chainChild = < span class = "hljs-literal" > yes< / span >
2016-09-22 16:19:43 -04:00
answer = answer.concat @elseBody.unwrap().compileToFragments o, LEVEL_TOP
2014-01-29 23:54:00 -05:00
< span class = "hljs-keyword" > else< / span >
2016-09-22 16:19:43 -04:00
answer = answer.concat @makeCode(< span class = "hljs-string" > "{\n"< / span > ), @elseBody.compileToFragments(merge(o, {indent}), LEVEL_TOP), @makeCode(< span class = "hljs-string" > "\n< span class = "hljs-subst" > #{@tab}< / span > }"< / span > )
2013-03-18 01:06:33 -04:00
answer< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-181" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-181" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Compile the < code > If< / code > as a conditional operator.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > compileExpression: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span >
cond = @condition.compileToFragments o, LEVEL_COND
body = @bodyNode().compileToFragments o, LEVEL_LIST
alt = < span class = "hljs-keyword" > if< / span > @elseBodyNode() < span class = "hljs-keyword" > then< / span > @elseBodyNode().compileToFragments(o, LEVEL_LIST) < span class = "hljs-keyword" > else< / span > [@makeCode(< span class = "hljs-string" > 'void 0'< / span > )]
fragments = cond.concat @makeCode(< span class = "hljs-string" > " ? "< / span > ), body, @makeCode(< span class = "hljs-string" > " : "< / span > ), alt
< span class = "hljs-keyword" > if< / span > o.level > = LEVEL_COND < span class = "hljs-keyword" > then< / span > @wrapInBraces fragments < span class = "hljs-keyword" > else< / span > fragments
2010-11-20 14:22:28 -05:00
2016-09-22 16:19:43 -04:00
unfoldSoak: < span class = "hljs-function" > -> < / span >
@soak < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > this< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-182" >
2013-03-18 01:06:33 -04:00
< div class = "annotation" >
2014-01-29 23:54:00 -05:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-182" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h2 id = "constants" > Constants< / h2 >
2013-03-18 01:06:33 -04:00
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-183" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-183" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2013-06-02 01:37:45 -04:00
< / div >
2014-08-23 10:08:39 -04:00
< div class = "content" > < div class = 'highlight' > < pre >
UTILITIES =< / pre > < / div > < / div >
2014-01-29 23:54:00 -05:00
2013-06-02 01:37:45 -04:00
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-184" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-184" > ¶ < / a >
2013-06-02 01:37:45 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Correctly set up a prototype chain for inheritance, including a reference
to the superclass for < code > super()< / code > calls, and copies of any static properties.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > extend: < span class = "hljs-function" > < span class = "hljs-params" > (o)< / span > -> < / span > < span class = "hljs-string" > "
2014-01-29 23:54:00 -05:00
function(child, parent) {
for (var key in parent) {
2015-01-29 12:20:46 -05:00
if (< span class = "hljs-subst" > #{utility < span class = "hljs-string" > 'hasProp'< / span > , o}< / span > .call(parent, key)) child[key] = parent[key];
2014-01-29 23:54:00 -05:00
}
function ctor() {
this.constructor = child;
}
ctor.prototype = parent.prototype;
child.prototype = new ctor();
child.__super__ = parent.prototype;
return child;
}
"< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-185" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-185" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-08-23 10:08:39 -04:00
< p > Create a function bound to the current value of “this”.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > bind: < span class = "hljs-function" > -> < / span > < span class = "hljs-string" > '
2014-01-29 23:54:00 -05:00
function(fn, me){
return function(){
return fn.apply(me, arguments);
};
}
'< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-186" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-186" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Discover if an item is in an array.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > indexOf: < span class = "hljs-function" > -> < / span > < span class = "hljs-string" > "
2014-01-29 23:54:00 -05:00
[].indexOf || function(item) {
for (var i = 0, l = this.length; i < l; i++) {
if (i in this & & this[i] === item) return i;
}
return -1;
}
"< / span >
2013-03-10 23:37:22 -04:00
2016-09-22 16:19:43 -04:00
modulo: < span class = "hljs-function" > -> < / span > < span class = "hljs-string" > """
2014-08-23 10:08:39 -04:00
function(a, b) { return (+a % (b = +b) + b) % b; }
2014-01-29 23:54:00 -05:00
"""< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-187" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-187" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Shortcuts to speed up the lookup time for native functions.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2016-09-22 16:19:43 -04:00
< div class = "content" > < div class = 'highlight' > < pre > hasProp: < span class = "hljs-function" > -> < / span > < span class = "hljs-string" > '{}.hasOwnProperty'< / span >
slice : < span class = "hljs-function" > -> < / span > < span class = "hljs-string" > '[].slice'< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-188" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-188" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-08-23 10:08:39 -04:00
< p > Levels indicate a node’ s position in the AST. Useful for knowing if
2014-01-29 23:54:00 -05:00
parens are necessary or superfluous.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< div class = "content" > < div class = 'highlight' > < pre > LEVEL_TOP = < span class = "hljs-number" > 1< / span > < span class = "hljs-comment" > # ...;< / span >
LEVEL_PAREN = < span class = "hljs-number" > 2< / span > < span class = "hljs-comment" > # (...)< / span >
LEVEL_LIST = < span class = "hljs-number" > 3< / span > < span class = "hljs-comment" > # [...]< / span >
LEVEL_COND = < span class = "hljs-number" > 4< / span > < span class = "hljs-comment" > # ... ? x : y< / span >
LEVEL_OP = < span class = "hljs-number" > 5< / span > < span class = "hljs-comment" > # !...< / span >
LEVEL_ACCESS = < span class = "hljs-number" > 6< / span > < span class = "hljs-comment" > # ...[0]< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-189" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-189" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Tabs are two spaces for pretty printing.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< div class = "content" > < div class = 'highlight' > < pre > TAB = < span class = "hljs-string" > ' '< / span >
2016-09-22 16:19:43 -04:00
SIMPLENUM = < span class = "hljs-regexp" > /^[+-]?\d+$/< / span > < / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-190" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-190" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< h2 id = "helper-functions" > Helper Functions< / h2 >
2013-03-10 23:37:22 -04:00
< / div >
< / li >
2013-03-18 01:06:33 -04:00
2016-09-22 16:19:43 -04:00
< li id = "section-191" >
2013-03-10 23:37:22 -04:00
< div class = "annotation" >
2013-03-18 01:06:33 -04:00
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-191" > ¶ < / a >
2014-08-23 10:08:39 -04:00
< / div >
< / div >
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-192" >
2014-08-23 10:08:39 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-192" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< p > Helper for ensuring that utility functions are assigned at the top level.< / p >
2013-03-10 23:37:22 -04:00
< / div >
2015-01-29 12:20:46 -05:00
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-function" > < span class = "hljs-title" > utility< / span > = < span class = "hljs-params" > (name, o)< / span > -> < / span >
{root} = o.scope
< span class = "hljs-keyword" > if< / span > name < span class = "hljs-keyword" > of< / span > root.utilities
root.utilities[name]
< span class = "hljs-keyword" > else< / span >
2015-02-18 15:43:33 -05:00
ref = root.freeVariable name
2015-01-29 12:20:46 -05:00
root.assign ref, UTILITIES[name] o
root.utilities[name] = ref
2016-09-22 16:19:43 -04:00
< span class = "hljs-function" >
< span class = "hljs-title" > multident< / span > = < span class = "hljs-params" > (code, tab)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
code = code.replace < span class = "hljs-regexp" > /\n/g< / span > , < span class = "hljs-string" > '$& '< / span > + tab
2016-09-22 16:19:43 -04:00
code.replace < span class = "hljs-regexp" > /\s+$/< / span > , < span class = "hljs-string" > ''< / span >
< span class = "hljs-function" >
< span class = "hljs-title" > isLiteralArguments< / span > = < span class = "hljs-params" > (node)< / span > -> < / span >
2014-01-29 23:54:00 -05:00
node < span class = "hljs-keyword" > instanceof< / span > Literal < span class = "hljs-keyword" > and< / span > node.value < span class = "hljs-keyword" > is< / span > < span class = "hljs-string" > 'arguments'< / span > < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > node.asKey
2016-09-22 16:19:43 -04:00
< span class = "hljs-function" >
< span class = "hljs-title" > isLiteralThis< / span > = < span class = "hljs-params" > (node)< / span > -> < / span >
(node < span class = "hljs-keyword" > instanceof< / span > ThisLiteral < span class = "hljs-keyword" > and< / span > < span class = "hljs-keyword" > not< / span > node.asKey) < span class = "hljs-keyword" > or< / span >
2014-01-29 23:54:00 -05:00
(node < span class = "hljs-keyword" > instanceof< / span > Code < span class = "hljs-keyword" > and< / span > node.bound) < span class = "hljs-keyword" > or< / span >
2016-09-22 16:19:43 -04:00
node < span class = "hljs-keyword" > instanceof< / span > SuperCall
< span class = "hljs-function" >
< span class = "hljs-title" > isComplexOrAssignable< / span > = < span class = "hljs-params" > (node)< / span > -> < / span > node.isComplex() < span class = "hljs-keyword" > or< / span > node.isAssignable?()< / pre > < / div > < / div >
2013-06-02 01:37:45 -04:00
< / li >
2016-09-22 16:19:43 -04:00
< li id = "section-193" >
2013-06-02 01:37:45 -04:00
< div class = "annotation" >
< div class = "pilwrap " >
2016-09-22 16:19:43 -04:00
< a class = "pilcrow" href = "#section-193" > ¶ < / a >
2013-03-18 01:06:33 -04:00
< / div >
2014-08-23 10:08:39 -04:00
< p > Unfold a node’ s child if soak, then tuck the node under created < code > If< / code > < / p >
2010-03-06 23:48:06 -05:00
2013-03-18 01:06:33 -04:00
< / div >
2014-01-29 23:54:00 -05:00
< div class = "content" > < div class = 'highlight' > < pre > < span class = "hljs-function" > < span class = "hljs-title" > unfoldSoak< / span > = < span class = "hljs-params" > (o, parent, name)< / span > -> < / span >
< span class = "hljs-keyword" > return< / span > < span class = "hljs-keyword" > unless< / span > ifn = parent[name].unfoldSoak o
parent[name] = ifn.body
ifn.body = < span class = "hljs-keyword" > new< / span > Value parent
ifn< / pre > < / div > < / div >
2013-03-10 23:37:22 -04:00
< / li >
2013-03-18 01:06:33 -04:00
< / ul >
2013-03-10 23:37:22 -04:00
< / div >
< / body >
< / html >