Compare commits

..

100 Commits
1.8.0 ... 1.9.0

Author SHA1 Message Date
Jeremy Ashkenas
f7692c92ce more text tweaks 2015-01-29 12:25:25 -05:00
Jeremy Ashkenas
cdf69eb5bc Merge branch 'gh-pages' 2015-01-29 12:22:26 -05:00
Jeremy Ashkenas
9aeecf582b text tweak 2015-01-29 12:22:16 -05:00
Jeremy Ashkenas
e0ec8a51e4 CoffeeScript 1.9.0 2015-01-29 12:20:46 -05:00
Jeremy Ashkenas
a62e49311e removing the mkdirp test 2015-01-29 11:39:18 -05:00
Jeremy Ashkenas
9a38486d08 Merge pull request #3800 from ysmood/decouple_mkdirp
Decouple "mkdirp".
2015-01-29 11:38:27 -05:00
Jeremy Ashkenas
06e8be5d94 rebuilt browser just for testing 2015-01-29 11:16:01 -05:00
Yad Smood
90a1cbac49 Optimize the mkdirp test 2015-01-29 03:49:40 +08:00
Yad Smood
3d58b4cda1 Add test for mkdirp 2015-01-29 00:44:28 +08:00
Michael Ficarra
2f0724f0ad Merge pull request #3812 from xfq/patch-1
Update index.html.js
2015-01-27 20:39:47 -08:00
Xue Fuqiao
f288d20409 Update index.html.js
Node comes with npm installed and "npm" is not an abbreviation for "Node Package Manager".
2015-01-28 08:52:08 +08:00
Michael Ficarra
dca915af60 Merge pull request #3808 from lydell/api-break-fix
Fix broken CoffeeScript APIs
2015-01-26 09:43:04 -08:00
Simon Lydell
54a4560340 Fix broken CoffeeScript APIs
As evidenced in #3804, commit 8ab15d7 broke the CoffeeScript API. The REPL uses
those APIs, but wasn't updated in that commit. Still, that shouldn't have
_broken_ the REPL. The reason it broke is because the added _option_
'referencedVars' wasn't actually _optional;_ if it was omitted code that relies
on it being set broke. This commit defaults that option to an empty array, which
makes things behave exactly like before when the 'referencedVars' option is
omitted.
2015-01-26 18:21:02 +01:00
Michael Ficarra
518d7c16b7 Merge pull request #3807 from lydell/repl-fix
Fix #3804: Provide list of referenced vars to REPL
2015-01-26 08:35:38 -08:00
Simon Lydell
8ed691e266 Fix #3804: Provide list of referenced vars to REPL
Supersedes #3805. Here is a comparison of master, #3805 and this commit:

    # master
    $ bin/coffee
    coffee> 1 %% 2
    TypeError: Array.prototype.indexOf called on null or undefined

    # #3805
    $ bin/coffee
    coffee> 1 %% 2
    1
    coffee> (_results = null; i) for i in [1, 2, 3]
    TypeError: Cannot call method 'push' of null

    # this commit
    $ bin/coffee
    coffee> 1 %% 2
    1
    coffee> (_results = null; i) for i in [1, 2, 3]
    [ 1, 2, 3 ]
2015-01-26 17:18:35 +01:00
Yad Smood
74fc7128ab Decouple "mkdirp"
Make coffee completely independent.
2015-01-22 04:20:34 +08:00
Michael Ficarra
68c0e2dc0f Merge pull request #3798 from ogennadi/patch-1
Fixed broken link
2015-01-20 18:21:55 -08:00
Oge Nnadi
42dde38842 Fixed broken link 2015-01-20 12:45:27 -08:00
Michael Ficarra
7d6f6174d5 Merge pull request #3787 from lydell/single-token-interpolation
Fix #1316: Interpolate interpolations safely
2015-01-16 08:43:05 -08:00
Simon Lydell
05b3707506 Fix #1316: Interpolate interpolations safely
Instead of compiling to `"" + + (+"-");`, `"#{+}-"'` now gives an appropriate
error message:

    [stdin]:1:5: error: unexpected end of interpolation
    "#{+}-"
        ^

This is done by _always_ (instead of just sometimes) wrapping the interpolations
in parentheses in the lexer. Unnecessary parentheses won't be output anyway.

I got tired of updating the tests in test/location.coffee (which I had enough of
in #3770), which relies on implementation details (the exact amount of tokens
generated for a given string of code) to do their testing, so I refactored them
to be less fragile.
2015-01-16 17:19:42 +01:00
Michael Ficarra
5d1d1b7999 Merge pull request #3792 from lydell/issue-3194
Fix #3194: Make strings always uncallable
2015-01-15 22:34:57 -08:00
Simon Lydell
3db029f2c1 Make regexes always uncallable
No matter if they have interpolations or not.
2015-01-15 19:44:14 +01:00
Michael Ficarra
67aaa8b57f Merge pull request #3794 from lydell/jison-update
Make CoffeeScript work with jison 0.4.14+
2015-01-15 09:03:27 -08:00
Simon Lydell
28c07d30cb Make CoffeeScript work with jison 0.4.14+
Since zaach/jison commit 3548861b, `parser.lexer` is never modified anymore (a
copy of it is made, and that copy is modified instead). CoffeeScript itself
modifies `parser.lexer` and then accesses those modifications in the custom
`parser.yy.parseError` function, but that of course does not work anymore. This
commit puts the data that `parser.yy.parseError` needs directly on the `parser`
so that it is not lost.

Supersedes #3603. Fixes #3608 and zaach/jison#243.
2015-01-15 17:47:07 +01:00
Simon Lydell
fce502ac98 Fix #3194: Make strings always uncallable
No matter if they have interpolations or not.
2015-01-14 21:27:24 +01:00
Michael Ficarra
669e7fed10 Merge pull request #3791 from lydell/issue-3502
Fix #3502: Define param variables when expansion
2015-01-13 20:00:32 -08:00
Michael Ficarra
4bf45ff894 Merge pull request #3790 from lydell/scope-root
Get rid of `Scope.root` hack
2015-01-13 12:53:03 -08:00
Simon Lydell
4c2c472e07 Fix #3502: Define param variables when expansion 2015-01-13 21:26:11 +01:00
Simon Lydell
22f19522ff Get rid of Scope.root hack
Using the static property `Scope.root` for the top-level scope of a file is a
hack, which makes it impossible to have several independent `Scope` instances
at the same time (should we ever need that).

This commit makes every instance have a reference to its root instead.
2015-01-13 20:21:45 +01:00
Michael Ficarra
9fa77af576 Merge pull request #3784 from lydell/unique-generated-vars
Unique generated vars
2015-01-12 21:14:44 -08:00
Michael Ficarra
efd7ebb066 Merge pull request #3788 from lydell/unexpected-call-end
Better error message for unexpected CALL_END
2015-01-12 20:55:25 -08:00
Simon Lydell
62712060c0 Better error message for unexpected CALL_END 2015-01-12 20:40:59 +01:00
Simon Lydell
a46978640b Allow variables named like helper functions 2015-01-11 12:12:40 +01:00
Simon Lydell
8ab15d7372 Fix #1500, #1574, #3318: Name generated vars uniquely
Any variables generated by CoffeeScript are now made sure to be named to
something not present in the source code being compiled. This way you can no
longer interfere with them, either on purpose or by mistake. (#1500, #1574)

For example, `({a}, _arg) ->` now compiles correctly. (#1574)

As opposed to the somewhat complex implementations discussed in #1500, this
commit takes a very simple approach by saving all used variables names using a
single pass over the token stream. Any generated variables are then made sure
not to exist in that list.

`(@a) -> a` used to be equivalent to `(@a) -> @a`, but now throws a runtime
`ReferenceError` instead (unless `a` exists in an upper scope of course). (#3318)

`(@a) ->` used to compile to `(function(a) { this.a = a; })`. Now it compiles to
`(function(_at_a) { this.a = _at_a; })`. (But you cannot access `_at_a` either,
of course.)

Because of the above, `(@a, a) ->` is now valid; `@a` and `a` are not duplicate
parameters.

Duplicate this-parameters with a reserved word, such as `(@case, @case) ->`,
used to compile but now throws, just like regular duplicate parameters.
2015-01-10 23:25:01 +01:00
Joshua Peek
23a691ae87 Add test for reserved keywords as parameters 2015-01-10 23:23:26 +01:00
Michael Ficarra
bec8f27e8a Merge pull request #3782 from lydell/regex
Fix #3410, #3182: Allow regex to start with space or =
2015-01-10 07:52:02 -08:00
Michael Ficarra
ac2e540e1b Merge pull request #3777 from lydell/unary-plus-minus-refs
Fix #3598: Make unary + and - generate _refs
2015-01-09 18:12:52 -08:00
Michael Ficarra
e0ad0d795d Merge pull request #3783 from lydell/issue-3671
Fix #3671: Allow step in optimized range comprehensions
2015-01-09 17:54:55 -08:00
Simon Lydell
a63009fccb Fix #3671: Allow step in optimized range comprehensions
Allow the `by c` part in `for [a..b] by c then`.

Continue disallowing a `when d` part, since it makes no sense having a guard
that isn't given access to anything that changes on every iteration.
2015-01-10 02:31:56 +01:00
Simon Lydell
8fd6258a46 Fix #3410, #3182: Allow regex to start with space or =
A regex may not follow a specific set of tokens. These were already known before
in the `NOT_REGEX` and `NOT_SPACED_REGEX` arrays. (However, I've refactored them
to be more correct and to add a few missing tokens). In all other cases (except
after a spaced callable) a slash is the start of a regex, and may now start with
a space or an equals sign. It’s really that simple!

A slash after a spaced callable is the only ambigous case. We cannot know if
that's division or function application with a regex as the argument. The
spacing determines which is which:

Space on both sides:
- `a / b/i`  -> `a / b / i`
- `a /= b/i` -> `a /= b / i`

No spaces:
- `a/b/i`    -> `a / b / i`
- `a/=b/i`   -> `a /= b / i`

Space on the right side:
- `a/ b/i`   -> `a / b / i`
- `a/= b/i`  -> `a /= b / i`

Space on the left side:
- `a /b/i`   -> `a(/b/i)`
- `a /=b/i`  -> `a(/=b/i)`

The last case used to compile to `a /= b / i`, but that has been changed to be
consistent with the `/` operator. The last case really looks like a regex, so it
should be parsed as one.

Moreover, you may now also space the `/` and `/=` operators with other
whitespace characters than a space (such as tabs and non-breaking spaces) for
consistency.

Lastly, unclosed regexes are now reported as such, instead of generating some
other confusing error message.

It should perhaps also be noted that apart from escaping (such as `a /\ b/`) you
may now also use parentheses to disambiguate division and regex: `a (/ b/)`. See
https://github.com/jashkenas/coffeescript/issues/3182#issuecomment-26688427.
2015-01-10 01:48:00 +01:00
Simon Lydell
24398774fc Fix #3598: Make unary + and - generate _refs
Before commit c056c93e `Op::isComplex()` used to return true always. As far as I
understand, that commit attempts to exclude code such as `+1` and `-2` from
being marked as complex (and thus getting cached into `_ref` variables
sometimes). CoffeeScript is supposed to generate readable output so that choice
is understandable. However, it also excludes code such as `+a` (by mistake I
believe), which can cause `a` to be coerced multiple times. This commit fixes
this by only excluding unary + and - ops followed by a number.
2015-01-09 18:12:10 +01:00
Jeremy Ashkenas
e769423d52 Merge pull request #3774 from lydell/unicode-spaces
Fix #2516, #3560: Unicode space handling
2015-01-06 16:10:59 -05:00
Simon Lydell
9ec427ba80 Fix #2516, #3560: Unicode space handling
It is possible to match only valid JavaScript identifiers with a really long
regex (like coco and CoffeeScriptRedux does), but CoffeeScript uses a much
simpler one, which allows a bit too much.

Quoting jashkenas/coffeescript#1718 #issuecomment-2152464 @jashkenas:

> But it still seems very much across the "worth it" line. You'll get the
> SyntaxError as soon as it hits JS, and performance aside -- even the increase
> in filesize for our browser coffee-script.js lib seems too much, considering
> this is something no one ever does, apart from experimentation.

In short, CoffeeScript treats any non-ASCII character as part of an identifier.
However, unicode spaces should be excluded since having blank characters as part
of a _word_ is very confusing. This commit does so, while still keeping the
regex really simple.
2015-01-06 21:32:14 +01:00
Jeremy Ashkenas
c478f283f4 Merge pull request #3771 from mbrio/master
Fix issue #3498
2015-01-05 15:51:26 -05:00
Michael Diolosa
8e299b09cc Fix issue #3498 2015-01-05 15:40:04 -05:00
Michael Ficarra
b70f6571bd Merge pull request #3770 from lydell/interpolations
Refactor interpolation (and string and regex) handling in lexer
2015-01-04 12:12:56 -08:00
Simon Lydell
ae6df88c5c Point "missing )/}/]" errors to the unclosed (/{/[
Previously such errors pointed at the end of the input, which wasn't very
helpful. This is also consistent with unclosed strings, where the errors point
at the opening quote.

Note that this includes unclosed #{ (interpolations).
2015-01-04 07:51:53 +01:00
Simon Lydell
0dcff507fb Refactor interpolation (and string and regex) handling in lexer
- Fix #3394: Unclosed single-quoted strings (both regular ones and heredocs)
  used to pass through the lexer, causing a parsing error later, while
  double-quoted strings caused an error already in the lexing phase. Now both
  single and double-quoted unclosed strings error out in the lexer (which is the
  more logical option) with consistent error messages. This also fixes the last
  comment by @satyr in #3301.

- Similar to the above, unclosed heregexes also used to pass through the lexer
  and not error until in the parsing phase, which resulted in confusing error
  messages. This has been fixed, too.

- Fix #3348, by adding passing tests.

- Fix #3529: If a string starts with an interpolation, an empty string is no
  longer emitted before the interpolation (unless it is needed to coerce the
  interpolation into a string).

- Block comments cannot contain `*/`. Now the error message also shows exactly
  where the offending `*/`. This improvement might seem unrelated, but I had to
  touch that code anyway to refactor string and regex related code, and the
  change was very trivial. Moreover, it's consistent with the next two points.

- Regexes cannot start with `*`. Now the error message also shows exactly where
  the offending `*` is. (It might actually not be exatly at the start in
  heregexes.) It is a very minor improvement, but it was trivial to add.

- Octal escapes in strings are forbidden in CoffeeScript (just like in
  JavaScript strict mode). However, this used to be the case only for regular
  strings. Now they are also forbidden in heredocs. Moreover, the errors now
  point at the offending octal escape.

- Invalid regex flags are no longer allowed. This includes repeated modifiers
  and unknown ones. Moreover, invalid modifiers do not stop a heregex from
  being matched, which results in better error messages.

- Fix #3621: `///a#{1}///` compiles to `RegExp("a" + 1)`. So does
  `RegExp("a#{1}")`. Still, those two code snippets used to generate different
  tokens, which is a bit weird, but more importantly causes problems for
  coffeelint (see clutchski/coffeelint#340). This required lots of tests in
  test/location.coffee to be updated. Note that some updates to those tests are
  unrelated to this point; some have been updated to be more consistent (I
  discovered this because the refactored code happened to be seemingly more
  correct).

- Regular regex literals used to erraneously allow newlines to be escaped,
  causing invalid JavaScript output. This has been fixed.

- Heregexes may now be completely empty (`//////`), instead of erroring out with
  a confusing message.

- Fix #2388: Heredocs and heregexes used to be lexed simply, which meant that
  you couldn't nest a heredoc within a heredoc (double-quoted, that is) or a
  heregex inside a heregex.

- Fix #2321: If you used division inside interpolation and then a slash later in
  the string containing that interpolation, the division slash and the latter
  slash was erraneously matched as a regex. This has been fixed.

- Indentation inside interpolations in heredocs no longer affect how much
  indentation is removed from each line of the heredoc (which is more
  intuitive).

- Whitespace is now correctly trimmed from the start and end of strings in a few
  edge cases.

- Last but not least, the lexing of interpolated strings now seems to be more
  efficient. For a regular double-quoted string, we used to use a custom
  function to find the end of it (taking interpolations and interpolations
  within interpolations etc. into account). Then we used to re-find the
  interpolations and recursively lex their contents. In effect, the same string
  was processed twice, or even more in the case of deeper nesting of
  interpolations. Now the same string is processed just once.

- Code duplication between regular strings, heredocs, regular regexes and
  heregexes has been reduced.

- The above two points should result in more easily read code, too.
2015-01-04 07:47:09 +01:00
Jeremy Ashkenas
8e4fb1b937 Merge pull request #3748 from sscotth/master
Include logo .svg files
2014-12-03 10:20:32 -05:00
Scott
931b74e449 include logo .svg files 2014-12-02 18:33:07 -06:00
Jeremy Ashkenas
4199f4f325 Merge pull request #3734 from alubbe/master
fixed yield keyword not working in switch & for loop expressions
2014-11-21 18:38:11 -05:00
alubbe
5950d6328d added tests for yield in switch & for loop expressions 2014-11-21 23:14:53 +01:00
alubbe
a9fbf14adf fixed yield keyword not working in switch & for loop expressions 2014-11-21 22:52:09 +01:00
Jeremy Ashkenas
485aa8efcf add Die Alternative to books section 2014-11-17 13:43:41 -05:00
Jeremy Ashkenas
a563e8f8fe Merge pull request #3703 from bigtunacan/master
Add bower.json configuration
2014-10-29 17:05:25 -04:00
Joiey Seeley
4035e7caab Removed "mkdirp": "~0.3.5" from bower.json 2014-10-29 15:10:57 -05:00
Joiey Seeley
2c6e6ca870 Added an initial bower.json configuration file 2014-10-29 14:23:31 -05:00
Jeremy Ashkenas
f2a3f7507e Merge pull request #3521 from gscottolson/master
Retina favicon.ico
2014-10-27 17:18:33 -04:00
Jeremy Ashkenas
4f82e5912e Merge pull request #3677 from alubbe/master
implemented proper precedence for 'yield'
2014-10-13 11:41:36 -04:00
alubbe
dd5da7f5f2 implemented proper precedence for 'yield' 2014-10-13 03:32:02 +02:00
Anatoly Ressin
ec44aba71a Improved test readability + fixed integer divison 2014-10-12 22:32:02 +03:00
Anatoly Ressin
e8a4e93a72 Added failing test case for the yield precedence 2014-10-12 20:08:28 +03:00
Jeremy Ashkenas
158ca0d869 Merge pull request #3638 from lbeschastny/issue3638
Invalid block comments compilation
2014-09-23 14:52:03 -04:00
Jeremy Ashkenas
a78cbe78a1 Merge pull request #3240 from alubbe/master
using 'yield' automatically turns functions into generators
2014-09-19 16:38:41 -04:00
Leonid Beschastny
77d5b95260 Added test for jashkenas/coffee-script#3638 2014-09-17 15:02:18 +04:00
Leonid Beschastny
55e3b6b3c3 Fixed jashkenas/coffeescript#3638 - invalid block comments compilation 2014-09-17 15:02:10 +04:00
Andreas Lubbe
efca2861a6 added tests for yield, yield from, yield return and yield in if statements 2014-09-06 17:25:44 +02:00
Andreas Lubbe
781ea22d57 always wrap 'yield' in () to allow composability with all other operators 2014-09-06 17:12:25 +02:00
Andreas Lubbe
437b9ed65c added 'yield return' 2014-09-06 15:40:53 +02:00
Andreas Lubbe
c72556619f added 'yield from' 2014-09-06 13:53:21 +02:00
Andreas Lubbe
565d78f00b removed support for '->*" and '=>*' 2014-09-06 13:38:04 +02:00
Andreas Lubbe
75900660fd Merge remote-tracking branch 'A/master' 2014-09-06 11:32:25 +02:00
Michael Ficarra
b407a59baf Merge pull request #3618 from josh/update-site-example-projects
Refresh site Examples section
2014-08-28 00:40:35 -04:00
Joshua Peek
9dfd71b0e4 Add Atom to Examples 2014-08-27 21:24:42 -07:00
Joshua Peek
872092f6de Remove josh/nack from Examples 2014-08-27 21:21:25 -07:00
Michael Ficarra
8b066f125d Merge pull request #3616 from epmatsw/spelling
Quick spelling fixes
2014-08-26 19:46:34 -07:00
Will Stamper
94c467b520 Quick spelling fixes 2014-08-26 20:41:32 -05:00
Jeremy Ashkenas
53aa50f785 merged 2014-08-26 12:28:39 -04:00
Nami-Doc
e8c96de269 Fix the "Examples" link on coffeescript.org
It now points to the "Trending repositories" of the month.
2014-07-23 22:21:14 +02:00
Nami-Doc
1157b32413 Update link to "CoffeeScript Ristretto", fixes #3489 2014-06-26 17:08:31 +02:00
G. Scott Olson
ba4157b5e2 Retina favicon.ico 2014-06-23 11:11:54 -04:00
Jeremy Ashkenas
6ae21ae461 merged 2014-05-08 15:09:40 -04:00
Andreas Lubbe
f375394381 Merge https://github.com/jashkenas/coffee-script
Conflicts:
	lib/coffee-script/lexer.js
	lib/coffee-script/parser.js
	lib/coffee-script/rewriter.js
	src/lexer.coffee
	src/rewriter.coffee
2014-01-25 19:37:35 -08:00
Andreas Lubbe
1e377ed59b 'yield*' now works as expected 2013-12-27 22:12:04 -08:00
Andreas Lubbe
64e78a2bec updated lexer to allow 'yield*' 2013-12-26 01:16:02 -08:00
Andreas Lubbe
25b1eee293 first attempt at including 'yield*' 2013-12-23 19:32:25 -08:00
Andreas Lubbe
dab4ae9416 '->*' and '=>*' now produce generators 2013-12-19 18:08:25 -08:00
Andreas Lubbe
56b04a58dc first attempt at using '->*" and '=>*' for generators 2013-12-19 14:21:14 -08:00
Andreas Lubbe
e1000205fd Merge github.com:jashkenas/coffee-script 2013-12-05 11:56:34 -08:00
Andreas Lubbe
c02a403f2e fixed misspelling in Cakefile 2013-12-04 21:49:17 -08:00
Andreas Lubbe
f4b850d59c further improved readability of cakefile generator check 2013-12-02 23:33:16 -08:00
Andreas Lubbe
85c7fffd1a improved readability of cakefile generator check 2013-11-30 20:51:53 -08:00
Andreas Lubbe
9d29a830df entire generator test file is now ignored if generators are not available 2013-11-30 12:26:32 -08:00
Andreas Lubbe
74a92db173 improved readability of generator test 2013-11-30 11:45:19 -08:00
Andreas Lubbe
d712a6c0f4 npm run-script test-harmony executes generator tests 2013-11-29 20:59:22 -08:00
Andreas Lubbe
7906a2b6c1 removed yield from the reserved words 2013-11-29 20:58:43 -08:00
Andreas Lubbe
f11ca9888f added a test for generators 2013-11-29 20:58:26 -08:00
Andreas Lubbe
9941050120 using 'yield' automatically turns functions into generators 2013-11-15 22:19:31 +01:00
Andreas Lubbe
dafc7bdea5 added 'yield' to the unary keywords 2013-11-15 22:16:28 +01:00
Andreas Lubbe
f51cbd7117 removed 'yield' from the reserved keywords 2013-11-15 22:15:31 +01:00
111 changed files with 3870 additions and 2497 deletions

View File

@@ -276,6 +276,12 @@ runTests = (CoffeeScript) ->
# Run every test in the `test` folder, recording failures.
files = fs.readdirSync 'test'
# Ignore generators test file if generators are not available
generatorsAreAvailable = '--harmony' in process.execArgv or
'--harmony-generators' in process.execArgv
files.splice files.indexOf('generators.coffee'), 1 if not generatorsAreAvailable
for file in files when helpers.isCoffee file
literate = helpers.isLiterate file
currentFile = filename = path.join 'test', file

27
bower.json Normal file
View File

@@ -0,0 +1,27 @@
{
"name": "coffee-script",
"version": "1.9.0",
"main": [
"lib/coffee-script/coffee-script.js"
],
"description": "Unfancy JavaScript",
"keywords": [
"javascript",
"language",
"coffeescript",
"compiler"
],
"devDependencies": {
"uglify-js": "~2.2",
"jison": ">=0.2.0",
"highlight.js": "~8.0.0",
"underscore": "~1.5.2",
"docco": "~0.6.2"
},
"author": {
"name": "Jeremy Ashkenas"
},
"ignore": [
"test"
]
}

View File

@@ -0,0 +1,8 @@
perfectSquares = ->
num = 0
loop
num += 1
yield num * num
return
window.ps or= perfectSquares()

View File

@@ -140,7 +140,7 @@ compile = CoffeeScript.compile</pre></div></div>
</div>
<div class="content"><div class='highlight'><pre>CoffeeScript.<span class="hljs-function"><span class="hljs-title">eval</span> = <span class="hljs-params">(code, options = {})</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>CoffeeScript.e<span class="hljs-function"><span class="hljs-title">val</span> = <span class="hljs-params">(code, options = {})</span> -&gt;</span>
options.bare ?= <span class="hljs-literal">on</span>
eval compile code, options</pre></div></div>
@@ -157,7 +157,7 @@ compile = CoffeeScript.compile</pre></div></div>
</div>
<div class="content"><div class='highlight'><pre>CoffeeScript.<span class="hljs-function"><span class="hljs-title">run</span> = <span class="hljs-params">(code, options = {})</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>CoffeeScript.r<span class="hljs-function"><span class="hljs-title">un</span> = <span class="hljs-params">(code, options = {})</span> -&gt;</span>
options.bare = <span class="hljs-literal">on</span>
options.shiftLine = <span class="hljs-literal">on</span>
Function(compile code, options)()</pre></div></div>
@@ -193,7 +193,7 @@ Ported from <a href="https://developer.mozilla.org/en-US/docs/DOM/window.btoa">h
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">if</span> btoa? <span class="hljs-keyword">and</span> JSON? <span class="hljs-keyword">and</span> unescape? <span class="hljs-keyword">and</span> encodeURIComponent?
<span class="hljs-function"><span class="hljs-title">compile</span> = <span class="hljs-params">(code, options = {})</span> -&gt;</span>
<span class="hljs-function"> <span class="hljs-title">compile</span> = <span class="hljs-params">(code, options = {})</span> -&gt;</span>
options.sourceMap = <span class="hljs-literal">true</span>
options.inline = <span class="hljs-literal">true</span>
{js, v3SourceMap} = CoffeeScript.compile code, options
@@ -212,7 +212,7 @@ Ported from <a href="https://developer.mozilla.org/en-US/docs/DOM/window.btoa">h
</div>
<div class="content"><div class='highlight'><pre>CoffeeScript.<span class="hljs-function"><span class="hljs-title">load</span> = <span class="hljs-params">(url, callback, options = {}, hold = <span class="hljs-literal">false</span>)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>CoffeeScript.l<span class="hljs-function"><span class="hljs-title">oad</span> = <span class="hljs-params">(url, callback, options = {}, hold = <span class="hljs-literal">false</span>)</span> -&gt;</span>
options.sourceFiles = [url]
xhr = <span class="hljs-keyword">if</span> <span class="hljs-built_in">window</span>.ActiveXObject
<span class="hljs-keyword">new</span> <span class="hljs-built_in">window</span>.ActiveXObject(<span class="hljs-string">'Microsoft.XMLHTTP'</span>)
@@ -220,7 +220,7 @@ Ported from <a href="https://developer.mozilla.org/en-US/docs/DOM/window.btoa">h
<span class="hljs-keyword">new</span> <span class="hljs-built_in">window</span>.XMLHttpRequest()
xhr.open <span class="hljs-string">'GET'</span>, url, <span class="hljs-literal">true</span>
xhr.overrideMimeType <span class="hljs-string">'text/plain'</span> <span class="hljs-keyword">if</span> <span class="hljs-string">'overrideMimeType'</span> <span class="hljs-keyword">of</span> xhr
xhr.<span class="hljs-function"><span class="hljs-title">onreadystatechange</span> = -&gt;</span>
xhr.o<span class="hljs-function"><span class="hljs-title">nreadystatechange</span> = -&gt;</span>
<span class="hljs-keyword">if</span> xhr.readyState <span class="hljs-keyword">is</span> <span class="hljs-number">4</span>
<span class="hljs-keyword">if</span> xhr.status <span class="hljs-keyword">in</span> [<span class="hljs-number">0</span>, <span class="hljs-number">200</span>]
param = [xhr.responseText, options]
@@ -250,8 +250,8 @@ This happens on page load.</p>
coffeetypes = [<span class="hljs-string">'text/coffeescript'</span>, <span class="hljs-string">'text/literate-coffeescript'</span>]
coffees = (s <span class="hljs-keyword">for</span> s <span class="hljs-keyword">in</span> scripts <span class="hljs-keyword">when</span> s.type <span class="hljs-keyword">in</span> coffeetypes)
index = <span class="hljs-number">0</span>
<span class="hljs-function"><span class="hljs-title">execute</span> = -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">execute</span> = -&gt;</span>
param = coffees[index]
<span class="hljs-keyword">if</span> param <span class="hljs-keyword">instanceof</span> Array
CoffeeScript.run param...
@@ -263,7 +263,7 @@ This happens on page load.</p>
options = <span class="hljs-attribute">literate</span>: script.type <span class="hljs-keyword">is</span> coffeetypes[<span class="hljs-number">1</span>]
<span class="hljs-keyword">if</span> script.src
CoffeeScript.load script.src,
<span class="hljs-function"><span class="hljs-params">(param)</span> -&gt;</span>
<span class="hljs-function"> <span class="hljs-params">(param)</span> -&gt;</span>
coffees[i] = param
execute()
options

View File

@@ -260,7 +260,7 @@ original directory name, when running Cake tasks from subdirectories.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">run</span> = -&gt;</span>
<div class="content"><div class='highlight'><pre>exports.r<span class="hljs-function"><span class="hljs-title">un</span> = -&gt;</span>
<span class="hljs-built_in">global</span>.__originalDirname = fs.realpathSync <span class="hljs-string">'.'</span>
process.chdir cakefileDirectory __originalDirname
args = process.argv[<span class="hljs-number">2.</span>.]
@@ -314,8 +314,8 @@ original directory name, when running Cake tasks from subdirectories.</p>
<span class="hljs-built_in">console</span>.error message + <span class="hljs-string">'\n'</span>
<span class="hljs-built_in">console</span>.log <span class="hljs-string">'To see a list of all tasks/options, run "cake"'</span>
process.exit <span class="hljs-number">1</span>
<span class="hljs-function"><span class="hljs-title">missingTask</span> = <span class="hljs-params">(task)</span> -&gt;</span> fatalError <span class="hljs-string">"No such task: <span class="hljs-subst">#{task}</span>"</span></pre></div></div>
<span class="hljs-function">
<span class="hljs-title">missingTask</span> = <span class="hljs-params">(task)</span> -&gt;</span> fatalError <span class="hljs-string">"No such task: <span class="hljs-subst">#{task}</span>"</span></pre></div></div>
</li>

View File

@@ -144,9 +144,9 @@ SourceMap = <span class="hljs-built_in">require</span> <span class="hljs-str
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.VERSION = <span class="hljs-string">'1.8.0'</span>
<div class="content"><div class='highlight'><pre>exports.VERSION = <span class="hljs-string">'1.9.0'</span>
<span class="hljs-built_in">exports</span>.FILE_EXTENSIONS = [<span class="hljs-string">'.coffee'</span>, <span class="hljs-string">'.litcoffee'</span>, <span class="hljs-string">'.coffee.md'</span>]</pre></div></div>
exports.FILE_EXTENSIONS = [<span class="hljs-string">'.coffee'</span>, <span class="hljs-string">'.litcoffee'</span>, <span class="hljs-string">'.coffee.md'</span>]</pre></div></div>
</li>
@@ -161,7 +161,7 @@ SourceMap = <span class="hljs-built_in">require</span> <span class="hljs-str
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.helpers = helpers</pre></div></div>
<div class="content"><div class='highlight'><pre>exports.helpers = helpers</pre></div></div>
</li>
@@ -178,7 +178,7 @@ lexer/parser/compiler.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">withPrettyErrors</span> = <span class="hljs-params">(fn)</span> -&gt;</span>
<span class="hljs-function"><span class="hljs-params">(code, options = {})</span> -&gt;</span>
<span class="hljs-function"> <span class="hljs-params">(code, options = {})</span> -&gt;</span>
<span class="hljs-keyword">try</span>
fn.call @, code, options
<span class="hljs-keyword">catch</span> err
@@ -203,14 +203,36 @@ lookups.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.compile = compile = withPrettyErrors <span class="hljs-function"><span class="hljs-params">(code, options)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>exports.compile = compile = withPrettyErrors <span class="hljs-function"><span class="hljs-params">(code, options)</span> -&gt;</span>
{merge, extend} = helpers
options = extend {}, options
<span class="hljs-keyword">if</span> options.sourceMap
map = <span class="hljs-keyword">new</span> SourceMap
fragments = parser.parse(lexer.tokenize code, options).compileToFragments options
tokens = lexer.tokenize code, options</pre></div></div>
</li>
<li id="section-6">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<p>Pass a list of referenced variables, so that generated variables wont get
the same name. Since all generated variables start with an underscore only
referenced variables also starting with an underscore are passed, as an
optimization.</p>
</div>
<div class="content"><div class='highlight'><pre> options.referencedVars = (
token[<span class="hljs-number">1</span>] <span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> tokens <span class="hljs-keyword">when</span> token.variable <span class="hljs-keyword">and</span> token[<span class="hljs-number">1</span>].charAt(<span class="hljs-number">0</span>) <span class="hljs-keyword">is</span> <span class="hljs-string">'_'</span>
)
fragments = parser.parse(tokens).compileToFragments options
currentLine = <span class="hljs-number">0</span>
currentLine += <span class="hljs-number">1</span> <span class="hljs-keyword">if</span> options.header
@@ -222,11 +244,11 @@ lookups.</p>
</li>
<li id="section-6">
<li id="section-7">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</a>
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<p>Update the sourcemap with data from each fragment</p>
@@ -248,11 +270,11 @@ lookups.</p>
</li>
<li id="section-7">
<li id="section-8">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">&#182;</a>
<a class="pilcrow" href="#section-8">&#182;</a>
</div>
<p>Copy the code from each fragment into the final JavaScript.</p>
@@ -275,39 +297,18 @@ lookups.</p>
</li>
<li id="section-8">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">&#182;</a>
</div>
<p>Tokenize a string of CoffeeScript code, and return the array of tokens.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.tokens = withPrettyErrors <span class="hljs-function"><span class="hljs-params">(code, options)</span> -&gt;</span>
lexer.tokenize code, options</pre></div></div>
</li>
<li id="section-9">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</a>
</div>
<p>Parse a string of CoffeeScript code or an array of lexed tokens, and
return the AST. You can then compile it by calling <code>.compile()</code> on the root,
or traverse it by using <code>.traverseChildren()</code> with a callback.</p>
<p>Tokenize a string of CoffeeScript code, and return the array of tokens.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.nodes = withPrettyErrors <span class="hljs-function"><span class="hljs-params">(source, options)</span> -&gt;</span>
<span class="hljs-keyword">if</span> <span class="hljs-keyword">typeof</span> source <span class="hljs-keyword">is</span> <span class="hljs-string">'string'</span>
parser.parse lexer.tokenize source, options
<span class="hljs-keyword">else</span>
parser.parse source</pre></div></div>
<div class="content"><div class='highlight'><pre>exports.tokens = withPrettyErrors <span class="hljs-function"><span class="hljs-params">(code, options)</span> -&gt;</span>
lexer.tokenize code, options</pre></div></div>
</li>
@@ -318,13 +319,17 @@ or traverse it by using <code>.traverseChildren()</code> with a callback.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a>
</div>
<p>Compile and execute a string of CoffeeScript (on the server), correctly
setting <code>__filename</code>, <code>__dirname</code>, and relative <code>require()</code>.</p>
<p>Parse a string of CoffeeScript code or an array of lexed tokens, and
return the AST. You can then compile it by calling <code>.compile()</code> on the root,
or traverse it by using <code>.traverseChildren()</code> with a callback.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">run</span> = <span class="hljs-params">(code, options = {})</span> -&gt;</span>
mainModule = <span class="hljs-built_in">require</span>.main</pre></div></div>
<div class="content"><div class='highlight'><pre>exports.nodes = withPrettyErrors <span class="hljs-function"><span class="hljs-params">(source, options)</span> -&gt;</span>
<span class="hljs-keyword">if</span> <span class="hljs-keyword">typeof</span> source <span class="hljs-keyword">is</span> <span class="hljs-string">'string'</span>
parser.parse lexer.tokenize source, options
<span class="hljs-keyword">else</span>
parser.parse source</pre></div></div>
</li>
@@ -335,6 +340,23 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">&#182;</a>
</div>
<p>Compile and execute a string of CoffeeScript (on the server), correctly
setting <code>__filename</code>, <code>__dirname</code>, and relative <code>require()</code>.</p>
</div>
<div class="content"><div class='highlight'><pre>exports.r<span class="hljs-function"><span class="hljs-title">un</span> = <span class="hljs-params">(code, options = {})</span> -&gt;</span>
mainModule = <span class="hljs-built_in">require</span>.main</pre></div></div>
</li>
<li id="section-12">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">&#182;</a>
</div>
<p>Set the filename.</p>
</div>
@@ -345,11 +367,11 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
</li>
<li id="section-12">
<li id="section-13">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">&#182;</a>
<a class="pilcrow" href="#section-13">&#182;</a>
</div>
<p>Clear the module cache.</p>
@@ -360,11 +382,11 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
</li>
<li id="section-13">
<li id="section-14">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-13">&#182;</a>
<a class="pilcrow" href="#section-14">&#182;</a>
</div>
<p>Assign paths for node_modules loading</p>
@@ -379,11 +401,11 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
</li>
<li id="section-14">
<li id="section-15">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-14">&#182;</a>
<a class="pilcrow" href="#section-15">&#182;</a>
</div>
<p>Compile.</p>
@@ -398,26 +420,30 @@ setting <code>__filename</code>, <code>__dirname</code>, and relative <code>requ
</li>
<li id="section-15">
<li id="section-16">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-15">&#182;</a>
<a class="pilcrow" href="#section-16">&#182;</a>
</div>
<p>Compile and evaluate a string of CoffeeScript (in a Node.js-like environment).
The CoffeeScript REPL uses this to run the input.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">eval</span> = <span class="hljs-params">(code, options = {})</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>exports.e<span class="hljs-function"><span class="hljs-title">val</span> = <span class="hljs-params">(code, options = {})</span> -&gt;</span>
<span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> code = code.trim()
Script = vm.Script
<span class="hljs-keyword">if</span> Script
createContext = vm.Script.createContext ? vm.createContext
isContext = vm.isContext ? <span class="hljs-function"><span class="hljs-params">(ctx)</span> -&gt;</span>
options.sandbox <span class="hljs-keyword">instanceof</span> createContext().constructor
<span class="hljs-keyword">if</span> createContext
<span class="hljs-keyword">if</span> options.sandbox?
<span class="hljs-keyword">if</span> options.sandbox <span class="hljs-keyword">instanceof</span> Script.createContext().constructor
<span class="hljs-keyword">if</span> isContext options.sandbox
sandbox = options.sandbox
<span class="hljs-keyword">else</span>
sandbox = Script.createContext()
sandbox = createContext()
sandbox[k] = v <span class="hljs-keyword">for</span> own k, v <span class="hljs-keyword">of</span> options.sandbox
sandbox.<span class="hljs-built_in">global</span> = sandbox.root = sandbox.GLOBAL = sandbox
<span class="hljs-keyword">else</span>
@@ -428,11 +454,11 @@ The CoffeeScript REPL uses this to run the input.</p>
</li>
<li id="section-16">
<li id="section-17">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-16">&#182;</a>
<a class="pilcrow" href="#section-17">&#182;</a>
</div>
<p>define module/require only if they chose not to specify their own</p>
@@ -441,45 +467,45 @@ The CoffeeScript REPL uses this to run the input.</p>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">unless</span> sandbox <span class="hljs-keyword">isnt</span> <span class="hljs-built_in">global</span> <span class="hljs-keyword">or</span> sandbox.<span class="hljs-built_in">module</span> <span class="hljs-keyword">or</span> sandbox.<span class="hljs-built_in">require</span>
Module = <span class="hljs-built_in">require</span> <span class="hljs-string">'module'</span>
sandbox.<span class="hljs-built_in">module</span> = _module = <span class="hljs-keyword">new</span> Module(options.modulename || <span class="hljs-string">'eval'</span>)
sandbox.<span class="hljs-built_in">require</span> = <span class="hljs-function"><span class="hljs-title">_require</span> = <span class="hljs-params">(path)</span> -&gt;</span> Module._load path, _module, <span class="hljs-literal">true</span>
sandbox.<span class="hljs-built_in">require</span> = _<span class="hljs-function"><span class="hljs-title">require</span> = <span class="hljs-params">(path)</span> -&gt;</span> Module._load path, _module, <span class="hljs-literal">true</span>
_module.filename = sandbox.__filename
_require[r] = <span class="hljs-built_in">require</span>[r] <span class="hljs-keyword">for</span> r <span class="hljs-keyword">in</span> Object.getOwnPropertyNames <span class="hljs-built_in">require</span> <span class="hljs-keyword">when</span> r <span class="hljs-keyword">isnt</span> <span class="hljs-string">'paths'</span></pre></div></div>
</li>
<li id="section-17">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">&#182;</a>
</div>
<p>use the same hack node currently uses for their own REPL</p>
</div>
<div class="content"><div class='highlight'><pre> _require.paths = _module.paths = Module._nodeModulePaths process.cwd()
_require.<span class="hljs-function"><span class="hljs-title">resolve</span> = <span class="hljs-params">(request)</span> -&gt;</span> Module._resolveFilename request, _module
o = {}
o[k] = v <span class="hljs-keyword">for</span> own k, v <span class="hljs-keyword">of</span> options
o.bare = <span class="hljs-literal">on</span> <span class="hljs-comment"># ensure return value</span>
js = compile code, o
<span class="hljs-keyword">if</span> sandbox <span class="hljs-keyword">is</span> <span class="hljs-built_in">global</span>
vm.runInThisContext js
<span class="hljs-keyword">else</span>
vm.runInContext js, sandbox
<span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">register</span> = -&gt;</span> <span class="hljs-built_in">require</span> <span class="hljs-string">'./register'</span></pre></div></div>
</li>
<li id="section-18">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-18">&#182;</a>
</div>
<p>use the same hack node currently uses for their own REPL</p>
</div>
<div class="content"><div class='highlight'><pre> _require.paths = _module.paths = Module._nodeModulePaths process.cwd()
_require.r<span class="hljs-function"><span class="hljs-title">esolve</span> = <span class="hljs-params">(request)</span> -&gt;</span> Module._resolveFilename request, _module
o = {}
o[k] = v <span class="hljs-keyword">for</span> own k, v <span class="hljs-keyword">of</span> options
o.bare = <span class="hljs-literal">on</span> <span class="hljs-comment"># ensure return value</span>
js = compile code, o
<span class="hljs-keyword">if</span> sandbox <span class="hljs-keyword">is</span> <span class="hljs-built_in">global</span>
vm.runInThisContext js
<span class="hljs-keyword">else</span>
vm.runInContext js, sandbox
exports.r<span class="hljs-function"><span class="hljs-title">egister</span> = -&gt;</span> <span class="hljs-built_in">require</span> <span class="hljs-string">'./register'</span></pre></div></div>
</li>
<li id="section-19">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-19">&#182;</a>
</div>
<p>Throw error with deprecation warning when depending upon implicit <code>require.extensions</code> registration</p>
</div>
@@ -491,7 +517,7 @@ The CoffeeScript REPL uses this to run the input.</p>
Use CoffeeScript.register() or require the coffee-script/register module to require <span class="hljs-subst">#{ext}</span> files.
"""</span>
<span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">_compileFile</span> = <span class="hljs-params">(filename, sourceMap = <span class="hljs-literal">no</span>)</span> -&gt;</span>
exports._<span class="hljs-function"><span class="hljs-title">compileFile</span> = <span class="hljs-params">(filename, sourceMap = <span class="hljs-literal">no</span>)</span> -&gt;</span>
raw = fs.readFileSync filename, <span class="hljs-string">'utf8'</span>
stripped = <span class="hljs-keyword">if</span> raw.charCodeAt(<span class="hljs-number">0</span>) <span class="hljs-keyword">is</span> <span class="hljs-number">0xFEFF</span> <span class="hljs-keyword">then</span> raw.substring <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> raw
@@ -502,11 +528,11 @@ The CoffeeScript REPL uses this to run the input.</p>
</li>
<li id="section-19">
<li id="section-20">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-19">&#182;</a>
<a class="pilcrow" href="#section-20">&#182;</a>
</div>
<p>As the filename and code of a dynamically loaded file will be different
from the original file compiled with CoffeeScript.run, add that
@@ -521,11 +547,11 @@ information to error so it can be pretty-printed later.</p>
</li>
<li id="section-20">
<li id="section-21">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-20">&#182;</a>
<a class="pilcrow" href="#section-21">&#182;</a>
</div>
<p>Instantiate a Lexer for our use here.</p>
@@ -536,11 +562,11 @@ information to error so it can be pretty-printed later.</p>
</li>
<li id="section-21">
<li id="section-22">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-21">&#182;</a>
<a class="pilcrow" href="#section-22">&#182;</a>
</div>
<p>The real Lexer produces a generic stream of tokens. This object provides a
thin wrapper around it, compatible with the Jison API. We can then pass it
@@ -550,16 +576,17 @@ directly as a “Jison lexer”.</p>
<div class="content"><div class='highlight'><pre>parser.lexer =
<span class="hljs-attribute">lex</span>:<span class="hljs-function"> -&gt;</span>
token = <span class="hljs-property">@tokens</span>[<span class="hljs-property">@pos</span>++]
token = parser.tokens[<span class="hljs-property">@pos</span>++]
<span class="hljs-keyword">if</span> token
[tag, <span class="hljs-property">@yytext</span>, <span class="hljs-property">@yylloc</span>] = token
<span class="hljs-property">@errorToken</span> = token.origin <span class="hljs-keyword">or</span> token
parser.errorToken = token.origin <span class="hljs-keyword">or</span> token
<span class="hljs-property">@yylineno</span> = <span class="hljs-property">@yylloc</span>.first_line
<span class="hljs-keyword">else</span>
tag = <span class="hljs-string">''</span>
tag
<span class="hljs-attribute">setInput</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@tokens</span>)</span> -&gt;</span>
<span class="hljs-attribute">setInput</span>: <span class="hljs-function"><span class="hljs-params">(tokens)</span> -&gt;</span>
parser.tokens = tokens
<span class="hljs-property">@pos</span> = <span class="hljs-number">0</span>
<span class="hljs-attribute">upcomingInput</span>:<span class="hljs-function"> -&gt;</span>
<span class="hljs-string">""</span></pre></div></div>
@@ -567,32 +594,17 @@ directly as a “Jison lexer”.</p>
</li>
<li id="section-22">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-22">&#182;</a>
</div>
<p>Make all the AST nodes visible to the parser.</p>
</div>
<div class="content"><div class='highlight'><pre>parser.yy = <span class="hljs-built_in">require</span> <span class="hljs-string">'./nodes'</span></pre></div></div>
</li>
<li id="section-23">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-23">&#182;</a>
</div>
<p>Override Jisons default error handling function.</p>
<p>Make all the AST nodes visible to the parser.</p>
</div>
<div class="content"><div class='highlight'><pre>parser.yy.<span class="hljs-function"><span class="hljs-title">parseError</span> = <span class="hljs-params">(message, {token})</span> -&gt;</span></pre></div></div>
<div class="content"><div class='highlight'><pre>parser.yy = <span class="hljs-built_in">require</span> <span class="hljs-string">'./nodes'</span></pre></div></div>
</li>
@@ -603,13 +615,28 @@ directly as a “Jison lexer”.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-24">&#182;</a>
</div>
<p>Override Jisons default error handling function.</p>
</div>
<div class="content"><div class='highlight'><pre>parser.yy.p<span class="hljs-function"><span class="hljs-title">arseError</span> = <span class="hljs-params">(message, {token})</span> -&gt;</span></pre></div></div>
</li>
<li id="section-25">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-25">&#182;</a>
</div>
<p>Disregard Jisons message, it contains redundant line numer information.
Disregard the token, we take its value directly from the lexer in case
the error is caused by a generated token which might refer to its origin.</p>
</div>
<div class="content"><div class='highlight'><pre> {errorToken, tokens} = parser.lexer
<div class="content"><div class='highlight'><pre> {errorToken, tokens} = parser
[errorTag, errorText, errorLoc] = errorToken
errorText = <span class="hljs-keyword">if</span> errorToken <span class="hljs-keyword">is</span> tokens[tokens.length - <span class="hljs-number">1</span>]
@@ -622,11 +649,11 @@ the error is caused by a generated token which might refer to its origin.</p>
</li>
<li id="section-25">
<li id="section-26">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-25">&#182;</a>
<a class="pilcrow" href="#section-26">&#182;</a>
</div>
<p>The second argument has a <code>loc</code> property, which should have the location
data for this token. Unfortunately, Jison seems to send an outdated <code>loc</code>
@@ -640,11 +667,11 @@ from the lexer.</p>
</li>
<li id="section-26">
<li id="section-27">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-26">&#182;</a>
<a class="pilcrow" href="#section-27">&#182;</a>
</div>
<p>Based on <a href="http://v8.googlecode.com/svn/branches/bleeding_edge/src/messages.js">http://v8.googlecode.com/svn/branches/bleeding_edge/src/messages.js</a>
Modified to handle sourceMap</p>
@@ -672,11 +699,11 @@ Modified to handle sourceMap</p>
</li>
<li id="section-27">
<li id="section-28">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-27">&#182;</a>
<a class="pilcrow" href="#section-28">&#182;</a>
</div>
<p>Check for a sourceMap position</p>
@@ -717,11 +744,11 @@ Modified to handle sourceMap</p>
</li>
<li id="section-28">
<li id="section-29">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-28">&#182;</a>
<a class="pilcrow" href="#section-29">&#182;</a>
</div>
<p>Map of filenames -&gt; sourceMap object.</p>
@@ -732,11 +759,11 @@ Modified to handle sourceMap</p>
</li>
<li id="section-29">
<li id="section-30">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-29">&#182;</a>
<a class="pilcrow" href="#section-30">&#182;</a>
</div>
<p>Generates the source map for a coffee file and stores it in the local cache variable.</p>
@@ -744,18 +771,18 @@ Modified to handle sourceMap</p>
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">getSourceMap</span> = <span class="hljs-params">(filename)</span> -&gt;</span>
<span class="hljs-keyword">return</span> sourceMaps[filename] <span class="hljs-keyword">if</span> sourceMaps[filename]
<span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> path?.extname(filename) <span class="hljs-keyword">in</span> <span class="hljs-built_in">exports</span>.FILE_EXTENSIONS
answer = <span class="hljs-built_in">exports</span>._compileFile filename, <span class="hljs-literal">true</span>
<span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> path?.extname(filename) <span class="hljs-keyword">in</span> exports.FILE_EXTENSIONS
answer = exports._compileFile filename, <span class="hljs-literal">true</span>
sourceMaps[filename] = answer.sourceMap</pre></div></div>
</li>
<li id="section-30">
<li id="section-31">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-30">&#182;</a>
<a class="pilcrow" href="#section-31">&#182;</a>
</div>
<p>Based on <a href="http://goo.gl/ZTx1p">michaelficarra/CoffeeScriptRedux</a>
NodeJS / V8 have no support for transforming positions in stack traces using
@@ -764,14 +791,14 @@ positions.</p>
</div>
<div class="content"><div class='highlight'><pre>Error.<span class="hljs-function"><span class="hljs-title">prepareStackTrace</span> = <span class="hljs-params">(err, stack)</span> -&gt;</span>
<span class="hljs-function"><span class="hljs-title">getSourceMapping</span> = <span class="hljs-params">(filename, line, column)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>Error.p<span class="hljs-function"><span class="hljs-title">repareStackTrace</span> = <span class="hljs-params">(err, stack)</span> -&gt;</span>
<span class="hljs-function"> <span class="hljs-title">getSourceMapping</span> = <span class="hljs-params">(filename, line, column)</span> -&gt;</span>
sourceMap = getSourceMap filename
answer = sourceMap.sourceLocation [line - <span class="hljs-number">1</span>, column - <span class="hljs-number">1</span>] <span class="hljs-keyword">if</span> sourceMap
<span class="hljs-keyword">if</span> answer <span class="hljs-keyword">then</span> [answer[<span class="hljs-number">0</span>] + <span class="hljs-number">1</span>, answer[<span class="hljs-number">1</span>] + <span class="hljs-number">1</span>] <span class="hljs-keyword">else</span> <span class="hljs-literal">null</span>
frames = <span class="hljs-keyword">for</span> frame <span class="hljs-keyword">in</span> stack
<span class="hljs-keyword">break</span> <span class="hljs-keyword">if</span> frame.getFunction() <span class="hljs-keyword">is</span> <span class="hljs-built_in">exports</span>.run
<span class="hljs-keyword">break</span> <span class="hljs-keyword">if</span> frame.getFunction() <span class="hljs-keyword">is</span> exports.run
<span class="hljs-string">" at <span class="hljs-subst">#{formatSourcePosition frame, getSourceMapping}</span>"</span>
<span class="hljs-string">"<span class="hljs-subst">#{err.toString()}</span>\n<span class="hljs-subst">#{frames.join <span class="hljs-string">'\n'</span>}</span>\n"</span></pre></div></div>

View File

@@ -141,7 +141,6 @@ path = <span class="hljs-built_in">require</span> <span class="hljs-st
helpers = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span>
optparse = <span class="hljs-built_in">require</span> <span class="hljs-string">'./optparse'</span>
CoffeeScript = <span class="hljs-built_in">require</span> <span class="hljs-string">'./coffee-script'</span>
mkdirp = <span class="hljs-built_in">require</span> <span class="hljs-string">'mkdirp'</span>
{spawn, exec} = <span class="hljs-built_in">require</span> <span class="hljs-string">'child_process'</span>
{EventEmitter} = <span class="hljs-built_in">require</span> <span class="hljs-string">'events'</span>
@@ -161,11 +160,11 @@ useWinPathSep = path.sep <span class="hljs-keyword">is</span> <span class="hljs
</div>
<div class="content"><div class='highlight'><pre>helpers.extend CoffeeScript, <span class="hljs-keyword">new</span> EventEmitter
<span class="hljs-function"><span class="hljs-title">printLine</span> = <span class="hljs-params">(line)</span> -&gt;</span> process.stdout.write line + <span class="hljs-string">'\n'</span>
<span class="hljs-function">
<span class="hljs-title">printLine</span> = <span class="hljs-params">(line)</span> -&gt;</span> process.stdout.write line + <span class="hljs-string">'\n'</span>
<span class="hljs-function"><span class="hljs-title">printWarn</span> = <span class="hljs-params">(line)</span> -&gt;</span> process.stderr.write line + <span class="hljs-string">'\n'</span>
<span class="hljs-function"><span class="hljs-title">hidden</span> = <span class="hljs-params">(file)</span> -&gt;</span> <span class="hljs-regexp">/^\.|~$/</span>.test file</pre></div></div>
<span class="hljs-function">
<span class="hljs-title">hidden</span> = <span class="hljs-params">(file)</span> -&gt;</span> <span class="hljs-regexp">/^\.|~$/</span>.test file</pre></div></div>
</li>
@@ -254,7 +253,7 @@ Many flags cause us to divert before compiling anything. Flags passed after
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">run</span> = -&gt;</span>
<div class="content"><div class='highlight'><pre>exports.r<span class="hljs-function"><span class="hljs-title">un</span> = -&gt;</span>
parseOptions()</pre></div></div>
</li>
@@ -357,8 +356,8 @@ extension source files in it and all subdirectories.</p>
compileScript(source, code.toString(), base)
<span class="hljs-keyword">else</span>
notSources[source] = <span class="hljs-literal">yes</span>
<span class="hljs-function"><span class="hljs-title">findDirectoryIndex</span> = <span class="hljs-params">(source)</span> -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">findDirectoryIndex</span> = <span class="hljs-params">(source)</span> -&gt;</span>
<span class="hljs-keyword">for</span> ext <span class="hljs-keyword">in</span> CoffeeScript.FILE_EXTENSIONS
index = path.join source, <span class="hljs-string">"index<span class="hljs-subst">#{ext}</span>"</span>
<span class="hljs-keyword">try</span>
@@ -461,9 +460,9 @@ them together.</p>
<div class="content"><div class='highlight'><pre>joinTimeout = <span class="hljs-literal">null</span>
<span class="hljs-function"><span class="hljs-title">compileJoin</span> = -&gt;</span>
<span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> opts.join
<span class="hljs-keyword">unless</span> sourceCode.some<span class="hljs-function"><span class="hljs-params">((code) -&gt; code <span class="hljs-keyword">is</span> <span class="hljs-literal">null</span>)</span>
<span class="hljs-title">clearTimeout</span> <span class="hljs-title">joinTimeout</span>
<span class="hljs-title">joinTimeout</span> = <span class="hljs-title">wait</span> 100, -&gt;</span>
<span class="hljs-keyword">unless</span> sourceCode.some(<span class="hljs-function"><span class="hljs-params">(code)</span> -&gt;</span> code <span class="hljs-keyword">is</span> <span class="hljs-literal">null</span>)
clearTimeout joinTimeout
joinTimeout = wait <span class="hljs-number">100</span>,<span class="hljs-function"> -&gt;</span>
compileScript opts.join, sourceCode.join(<span class="hljs-string">'\n'</span>), opts.join</pre></div></div>
</li>
@@ -485,8 +484,8 @@ such as <code>--print</code>.</p>
watcher = <span class="hljs-literal">null</span>
prevStats = <span class="hljs-literal">null</span>
compileTimeout = <span class="hljs-literal">null</span>
<span class="hljs-function"><span class="hljs-title">watchErr</span> = <span class="hljs-params">(err)</span> -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">watchErr</span> = <span class="hljs-params">(err)</span> -&gt;</span>
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span>
<span class="hljs-keyword">return</span> <span class="hljs-keyword">unless</span> source <span class="hljs-keyword">in</span> sources
<span class="hljs-keyword">try</span>
@@ -495,8 +494,8 @@ such as <code>--print</code>.</p>
<span class="hljs-keyword">catch</span>
removeSource source, base
compileJoin()
<span class="hljs-function"><span class="hljs-title">compile</span> = -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">compile</span> = -&gt;</span>
clearTimeout compileTimeout
compileTimeout = wait <span class="hljs-number">25</span>,<span class="hljs-function"> -&gt;</span>
fs.stat source, <span class="hljs-function"><span class="hljs-params">(err, stats)</span> -&gt;</span>
@@ -509,15 +508,15 @@ such as <code>--print</code>.</p>
<span class="hljs-keyword">return</span> watchErr err <span class="hljs-keyword">if</span> err
compileScript(source, code.toString(), base)
rewatch()
<span class="hljs-function"><span class="hljs-title">startWatcher</span> = -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">startWatcher</span> = -&gt;</span>
watcher = fs.watch source
.<span class="hljs-literal">on</span> <span class="hljs-string">'change'</span>, compile
.<span class="hljs-literal">on</span> <span class="hljs-string">'error'</span>, <span class="hljs-function"><span class="hljs-params">(err)</span> -&gt;</span>
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'EPERM'</span>
removeSource source, base
<span class="hljs-function"><span class="hljs-title">rewatch</span> = -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">rewatch</span> = -&gt;</span>
watcher?.close()
startWatcher()
@@ -542,8 +541,8 @@ such as <code>--print</code>.</p>
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">watchDir</span> = <span class="hljs-params">(source, base)</span> -&gt;</span>
watcher = <span class="hljs-literal">null</span>
readdirTimeout = <span class="hljs-literal">null</span>
<span class="hljs-function"><span class="hljs-title">startWatcher</span> = -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">startWatcher</span> = -&gt;</span>
watcher = fs.watch source
.<span class="hljs-literal">on</span> <span class="hljs-string">'error'</span>, <span class="hljs-function"><span class="hljs-params">(err)</span> -&gt;</span>
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'EPERM'</span>
@@ -558,8 +557,8 @@ such as <code>--print</code>.</p>
<span class="hljs-keyword">return</span> stopWatcher()
<span class="hljs-keyword">for</span> file <span class="hljs-keyword">in</span> files
compilePath (path.join source, file), <span class="hljs-literal">no</span>, base
<span class="hljs-function"><span class="hljs-title">stopWatcher</span> = -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">stopWatcher</span> = -&gt;</span>
watcher.close()
removeSourceDir source, base
@@ -568,8 +567,8 @@ such as <code>--print</code>.</p>
startWatcher()
<span class="hljs-keyword">catch</span> err
<span class="hljs-keyword">throw</span> err <span class="hljs-keyword">unless</span> err.code <span class="hljs-keyword">is</span> <span class="hljs-string">'ENOENT'</span>
<span class="hljs-function"><span class="hljs-title">removeSourceDir</span> = <span class="hljs-params">(source, base)</span> -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">removeSourceDir</span> = <span class="hljs-params">(source, base)</span> -&gt;</span>
<span class="hljs-keyword">delete</span> watchedDirs[source]
sourcesChanged = <span class="hljs-literal">no</span>
<span class="hljs-keyword">for</span> file <span class="hljs-keyword">in</span> sources <span class="hljs-keyword">when</span> source <span class="hljs-keyword">is</span> path.dirname file
@@ -599,8 +598,8 @@ the compiled JS version as well.</p>
silentUnlink outputPath source, base
silentUnlink outputPath source, base, <span class="hljs-string">'.js.map'</span>
timeLog <span class="hljs-string">"removed <span class="hljs-subst">#{source}</span>"</span>
<span class="hljs-function"><span class="hljs-title">silentUnlink</span> = <span class="hljs-params">(path)</span> -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">silentUnlink</span> = <span class="hljs-params">(path)</span> -&gt;</span>
<span class="hljs-keyword">try</span>
fs.unlinkSync path
<span class="hljs-keyword">catch</span> err
@@ -639,6 +638,32 @@ the compiled JS version as well.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">&#182;</a>
</div>
<p>Recursively mkdir, like <code>mkdir -p</code>.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">mkdirp</span> = <span class="hljs-params">(dir, fn)</span> -&gt;</span>
mode = <span class="hljs-number">0</span>o777 &amp; ~process.umask()
<span class="hljs-keyword">do</span> m<span class="hljs-function"><span class="hljs-title">kdirs</span> = <span class="hljs-params">(p = dir, fn)</span> -&gt;</span>
fs.exists p, <span class="hljs-function"><span class="hljs-params">(exists)</span> -&gt;</span>
<span class="hljs-keyword">if</span> exists
fn()
<span class="hljs-keyword">else</span>
mkdirs path.dirname(p),<span class="hljs-function"> -&gt;</span>
fs.mkdir p, mode, <span class="hljs-function"><span class="hljs-params">(err)</span> -&gt;</span>
<span class="hljs-keyword">return</span> fn err <span class="hljs-keyword">if</span> err
fn()</pre></div></div>
</li>
<li id="section-18">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-18">&#182;</a>
</div>
<p>Write out a JavaScript source file with the compiled code. By default, files
are written out in <code>cwd</code> as <code>.js</code> files with the same name, but the output
directory can be customized with <code>--output</code>.</p>
@@ -650,7 +675,7 @@ same directory as the <code>.js</code> file.</p>
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">writeJs</span> = <span class="hljs-params">(base, sourcePath, js, jsPath, generatedSourceMap = <span class="hljs-literal">null</span>)</span> -&gt;</span>
sourceMapPath = outputPath sourcePath, base, <span class="hljs-string">".js.map"</span>
jsDir = path.dirname jsPath
<span class="hljs-function"><span class="hljs-title">compile</span> = -&gt;</span>
<span class="hljs-function"> <span class="hljs-title">compile</span> = -&gt;</span>
<span class="hljs-keyword">if</span> opts.compile
js = <span class="hljs-string">' '</span> <span class="hljs-keyword">if</span> js.length &lt;= <span class="hljs-number">0</span>
<span class="hljs-keyword">if</span> generatedSourceMap <span class="hljs-keyword">then</span> js = <span class="hljs-string">"<span class="hljs-subst">#{js}</span>\n//# sourceMappingURL=<span class="hljs-subst">#{helpers.baseFileName sourceMapPath, <span class="hljs-literal">no</span>, useWinPathSep}</span>\n"</span>
@@ -671,11 +696,11 @@ same directory as the <code>.js</code> file.</p>
</li>
<li id="section-18">
<li id="section-19">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-18">&#182;</a>
<a class="pilcrow" href="#section-19">&#182;</a>
</div>
<p>Convenience for cleaner setTimeouts.</p>
@@ -686,11 +711,11 @@ same directory as the <code>.js</code> file.</p>
</li>
<li id="section-19">
<li id="section-20">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-19">&#182;</a>
<a class="pilcrow" href="#section-20">&#182;</a>
</div>
<p>When watching scripts, its useful to log changes with the timestamp.</p>
@@ -702,11 +727,11 @@ same directory as the <code>.js</code> file.</p>
</li>
<li id="section-20">
<li id="section-21">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-20">&#182;</a>
<a class="pilcrow" href="#section-21">&#182;</a>
</div>
<p>Pretty-print a stream of tokens, sans location data.</p>
@@ -722,11 +747,11 @@ same directory as the <code>.js</code> file.</p>
</li>
<li id="section-21">
<li id="section-22">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-21">&#182;</a>
<a class="pilcrow" href="#section-22">&#182;</a>
</div>
<p>Use the <a href="optparse.html">OptionParser module</a> to extract all options from
<code>process.argv</code> that are specified in <code>SWITCHES</code>.</p>
@@ -743,11 +768,11 @@ same directory as the <code>.js</code> file.</p>
</li>
<li id="section-22">
<li id="section-23">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-22">&#182;</a>
<a class="pilcrow" href="#section-23">&#182;</a>
</div>
<p>The compile-time options to pass to the CoffeeScript compiler.</p>
@@ -782,11 +807,11 @@ same directory as the <code>.js</code> file.</p>
</li>
<li id="section-23">
<li id="section-24">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-23">&#182;</a>
<a class="pilcrow" href="#section-24">&#182;</a>
</div>
<p>Start up a new Node.js instance with the arguments in <code>--nodejs</code> passed to
the <code>node</code> binary, preserving the other options.</p>
@@ -806,11 +831,11 @@ the <code>node</code> binary, preserving the other options.</p>
</li>
<li id="section-24">
<li id="section-25">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-24">&#182;</a>
<a class="pilcrow" href="#section-25">&#182;</a>
</div>
<p>Print the <code>--help</code> usage message and exit. Deprecated switches are not
shown.</p>
@@ -823,11 +848,11 @@ shown.</p>
</li>
<li id="section-25">
<li id="section-26">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-25">&#182;</a>
<a class="pilcrow" href="#section-26">&#182;</a>
</div>
<p>Print the <code>--version</code> message and exit.</p>

View File

@@ -243,7 +243,7 @@ just be passed through unaffected.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-title">addLocationDataFn</span> = <span class="hljs-params">(first, last)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre><span class="hljs-function"> <span class="hljs-title">addLocationDataFn</span> = <span class="hljs-params">(first, last)</span> -&gt;</span>
<span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> last
<span class="hljs-string">"yy.addLocationDataFn(@<span class="hljs-subst">#{first}</span>)"</span>
<span class="hljs-keyword">else</span>
@@ -1247,7 +1247,8 @@ or postfix, with a single expression.</p>
]
<span class="hljs-attribute">ForBody</span>: [
o <span class="hljs-string">'FOR Range'</span>,<span class="hljs-function"> -&gt;</span> <span class="hljs-attribute">source</span>: LOC(<span class="hljs-number">2</span>) <span class="hljs-keyword">new</span> Value($<span class="hljs-number">2</span>)
o <span class="hljs-string">'FOR Range'</span>,<span class="hljs-function"> -&gt;</span> <span class="hljs-attribute">source</span>: (LOC(<span class="hljs-number">2</span>) <span class="hljs-keyword">new</span> Value($<span class="hljs-number">2</span>))
o <span class="hljs-string">'FOR Range BY Expression'</span>,<span class="hljs-function"> -&gt;</span> <span class="hljs-attribute">source</span>: (LOC(<span class="hljs-number">2</span>) <span class="hljs-keyword">new</span> Value($<span class="hljs-number">2</span>)), <span class="hljs-attribute">step</span>: $<span class="hljs-number">4</span>
o <span class="hljs-string">'ForStart ForSource'</span>,<span class="hljs-function"> -&gt;</span> $<span class="hljs-number">2.</span>own = $<span class="hljs-number">1.</span>own; $<span class="hljs-number">2.</span>name = $<span class="hljs-number">1</span>[<span class="hljs-number">0</span>]; $<span class="hljs-number">2.</span>index = $<span class="hljs-number">1</span>[<span class="hljs-number">1</span>]; $<span class="hljs-number">2</span>
]
@@ -1416,6 +1417,9 @@ rules are necessary.</p>
o <span class="hljs-string">'UNARY_MATH Expression'</span>,<span class="hljs-function"> -&gt;</span> <span class="hljs-keyword">new</span> Op $<span class="hljs-number">1</span> , $<span class="hljs-number">2</span>
o <span class="hljs-string">'- Expression'</span>, (<span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Op <span class="hljs-string">'-'</span>, $<span class="hljs-number">2</span>), <span class="hljs-attribute">prec</span>: <span class="hljs-string">'UNARY_MATH'</span>
o <span class="hljs-string">'+ Expression'</span>, (<span class="hljs-function">-&gt;</span> <span class="hljs-keyword">new</span> Op <span class="hljs-string">'+'</span>, $<span class="hljs-number">2</span>), <span class="hljs-attribute">prec</span>: <span class="hljs-string">'UNARY_MATH'</span>
o <span class="hljs-string">'YIELD Statement'</span>,<span class="hljs-function"> -&gt;</span> <span class="hljs-keyword">new</span> Op $<span class="hljs-number">1</span> , $<span class="hljs-number">2</span>
o <span class="hljs-string">'YIELD Expression'</span>,<span class="hljs-function"> -&gt;</span> <span class="hljs-keyword">new</span> Op $<span class="hljs-number">1</span> , $<span class="hljs-number">2</span>
o <span class="hljs-string">'YIELD FROM Expression'</span>,<span class="hljs-function"> -&gt;</span> <span class="hljs-keyword">new</span> Op $<span class="hljs-number">1.</span>concat($<span class="hljs-number">2</span>) , $<span class="hljs-number">3</span>
o <span class="hljs-string">'-- SimpleAssignable'</span>,<span class="hljs-function"> -&gt;</span> <span class="hljs-keyword">new</span> Op <span class="hljs-string">'--'</span>, $<span class="hljs-number">2</span>
o <span class="hljs-string">'++ SimpleAssignable'</span>,<span class="hljs-function"> -&gt;</span> <span class="hljs-keyword">new</span> Op <span class="hljs-string">'++'</span>, $<span class="hljs-number">2</span>
@@ -1517,6 +1521,7 @@ down. Following these rules is what makes <code>2 + 3 * 4</code> parse as:</p>
[<span class="hljs-string">'left'</span>, <span class="hljs-string">'COMPARE'</span>]
[<span class="hljs-string">'left'</span>, <span class="hljs-string">'LOGIC'</span>]
[<span class="hljs-string">'nonassoc'</span>, <span class="hljs-string">'INDENT'</span>, <span class="hljs-string">'OUTDENT'</span>]
[<span class="hljs-string">'right'</span>, <span class="hljs-string">'YIELD'</span>]
[<span class="hljs-string">'right'</span>, <span class="hljs-string">'='</span>, <span class="hljs-string">':'</span>, <span class="hljs-string">'COMPOUND_ASSIGN'</span>, <span class="hljs-string">'RETURN'</span>, <span class="hljs-string">'THROW'</span>, <span class="hljs-string">'EXTENDS'</span>]
[<span class="hljs-string">'right'</span>, <span class="hljs-string">'FORIN'</span>, <span class="hljs-string">'FOROF'</span>, <span class="hljs-string">'BY'</span>, <span class="hljs-string">'WHEN'</span>]
[<span class="hljs-string">'right'</span>, <span class="hljs-string">'IF'</span>, <span class="hljs-string">'ELSE'</span>, <span class="hljs-string">'FOR'</span>, <span class="hljs-string">'WHILE'</span>, <span class="hljs-string">'UNTIL'</span>, <span class="hljs-string">'LOOP'</span>, <span class="hljs-string">'SUPER'</span>, <span class="hljs-string">'CLASS'</span>]
@@ -1588,7 +1593,7 @@ precedence from low to high, and we have it high to low
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.parser = <span class="hljs-keyword">new</span> Parser
<div class="content"><div class='highlight'><pre>exports.parser = <span class="hljs-keyword">new</span> Parser
tokens : tokens.join <span class="hljs-string">' '</span>
bnf : grammar
operators : operators.reverse()

View File

@@ -134,7 +134,7 @@ arrays, count characters, that sort of thing.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">starts</span> = <span class="hljs-params">(string, literal, start)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>exports.s<span class="hljs-function"><span class="hljs-title">tarts</span> = <span class="hljs-params">(string, literal, start)</span> -&gt;</span>
literal <span class="hljs-keyword">is</span> string.substr start, literal.length</pre></div></div>
</li>
@@ -150,7 +150,7 @@ arrays, count characters, that sort of thing.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">ends</span> = <span class="hljs-params">(string, literal, back)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>exports.e<span class="hljs-function"><span class="hljs-title">nds</span> = <span class="hljs-params">(string, literal, back)</span> -&gt;</span>
len = literal.length
literal <span class="hljs-keyword">is</span> string.substr string.length - len - (back <span class="hljs-keyword">or</span> <span class="hljs-number">0</span>), len</pre></div></div>
@@ -167,7 +167,7 @@ arrays, count characters, that sort of thing.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.repeat = <span class="hljs-function"><span class="hljs-title">repeat</span> = <span class="hljs-params">(str, n)</span> -&gt;</span></pre></div></div>
<div class="content"><div class='highlight'><pre>exports.repeat = r<span class="hljs-function"><span class="hljs-title">epeat</span> = <span class="hljs-params">(str, n)</span> -&gt;</span></pre></div></div>
</li>
@@ -202,7 +202,7 @@ arrays, count characters, that sort of thing.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">compact</span> = <span class="hljs-params">(array)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>exports.c<span class="hljs-function"><span class="hljs-title">ompact</span> = <span class="hljs-params">(array)</span> -&gt;</span>
item <span class="hljs-keyword">for</span> item <span class="hljs-keyword">in</span> array <span class="hljs-keyword">when</span> item</pre></div></div>
</li>
@@ -218,7 +218,7 @@ arrays, count characters, that sort of thing.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">count</span> = <span class="hljs-params">(string, substr)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>exports.c<span class="hljs-function"><span class="hljs-title">ount</span> = <span class="hljs-params">(string, substr)</span> -&gt;</span>
num = pos = <span class="hljs-number">0</span>
<span class="hljs-keyword">return</span> <span class="hljs-number">1</span>/<span class="hljs-number">0</span> <span class="hljs-keyword">unless</span> substr.length
num++ <span class="hljs-keyword">while</span> pos = <span class="hljs-number">1</span> + string.indexOf substr, pos
@@ -239,7 +239,7 @@ options hash to propagate down the tree without polluting other branches.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">merge</span> = <span class="hljs-params">(options, overrides)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>exports.m<span class="hljs-function"><span class="hljs-title">erge</span> = <span class="hljs-params">(options, overrides)</span> -&gt;</span>
extend (extend {}, options), overrides</pre></div></div>
</li>
@@ -255,7 +255,7 @@ options hash to propagate down the tree without polluting other branches.</p>
</div>
<div class="content"><div class='highlight'><pre>extend = <span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">extend</span> = <span class="hljs-params">(object, properties)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>extend = exports.e<span class="hljs-function"><span class="hljs-title">xtend</span> = <span class="hljs-params">(object, properties)</span> -&gt;</span>
<span class="hljs-keyword">for</span> key, val <span class="hljs-keyword">of</span> properties
object[key] = val
object</pre></div></div>
@@ -274,7 +274,7 @@ Handy for getting a list of <code>children</code> from the nodes.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.flatten = <span class="hljs-function"><span class="hljs-title">flatten</span> = <span class="hljs-params">(array)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>exports.flatten = f<span class="hljs-function"><span class="hljs-title">latten</span> = <span class="hljs-params">(array)</span> -&gt;</span>
flattened = []
<span class="hljs-keyword">for</span> element <span class="hljs-keyword">in</span> array
<span class="hljs-keyword">if</span> element <span class="hljs-keyword">instanceof</span> Array
@@ -297,7 +297,7 @@ looking for a particular method in an options hash.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">del</span> = <span class="hljs-params">(obj, key)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>exports.d<span class="hljs-function"><span class="hljs-title">el</span> = <span class="hljs-params">(obj, key)</span> -&gt;</span>
val = obj[key]
<span class="hljs-keyword">delete</span> obj[key]
val</pre></div></div>
@@ -315,7 +315,7 @@ looking for a particular method in an options hash.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.last = <span class="hljs-function"><span class="hljs-title">last</span> = <span class="hljs-params">(array, back)</span> -&gt;</span> array[array.length - (back <span class="hljs-keyword">or</span> <span class="hljs-number">0</span>) - <span class="hljs-number">1</span>]</pre></div></div>
<div class="content"><div class='highlight'><pre>exports.last = l<span class="hljs-function"><span class="hljs-title">ast</span> = <span class="hljs-params">(array, back)</span> -&gt;</span> array[array.length - (back <span class="hljs-keyword">or</span> <span class="hljs-number">0</span>) - <span class="hljs-number">1</span>]</pre></div></div>
</li>
@@ -330,7 +330,7 @@ looking for a particular method in an options hash.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.some = <span class="hljs-attribute">Array</span>::some ? <span class="hljs-function"><span class="hljs-params">(fn)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>exports.some = <span class="hljs-attribute">Array</span>::some ? <span class="hljs-function"><span class="hljs-params">(fn)</span> -&gt;</span>
<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span> <span class="hljs-keyword">for</span> e <span class="hljs-keyword">in</span> <span class="hljs-keyword">this</span> <span class="hljs-keyword">when</span> fn e
<span class="hljs-literal">false</span></pre></div></div>
@@ -349,7 +349,7 @@ can be compiled “normally”.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">invertLiterate</span> = <span class="hljs-params">(code)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>exports.i<span class="hljs-function"><span class="hljs-title">nvertLiterate</span> = <span class="hljs-params">(code)</span> -&gt;</span>
maybe_code = <span class="hljs-literal">true</span>
lines = <span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> code.split(<span class="hljs-string">'\n'</span>)
<span class="hljs-keyword">if</span> maybe_code <span class="hljs-keyword">and</span> <span class="hljs-regexp">/^([ ]{4}|[ ]{0,3}\t)/</span>.test line
@@ -398,8 +398,8 @@ The object is returned either way.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">addLocationDataFn</span> = <span class="hljs-params">(first, last)</span> -&gt;</span>
<span class="hljs-function"><span class="hljs-params">(obj)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>exports.a<span class="hljs-function"><span class="hljs-title">ddLocationDataFn</span> = <span class="hljs-params">(first, last)</span> -&gt;</span>
<span class="hljs-function"> <span class="hljs-params">(obj)</span> -&gt;</span>
<span class="hljs-keyword">if</span> ((<span class="hljs-keyword">typeof</span> obj) <span class="hljs-keyword">is</span> <span class="hljs-string">'object'</span>) <span class="hljs-keyword">and</span> (!!obj[<span class="hljs-string">'updateLocationDataIfMissing'</span>])
obj.updateLocationDataIfMissing buildLocationData(first, last)
@@ -419,7 +419,7 @@ The object is returned either way.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">locationDataToString</span> = <span class="hljs-params">(obj)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>exports.l<span class="hljs-function"><span class="hljs-title">ocationDataToString</span> = <span class="hljs-params">(obj)</span> -&gt;</span>
<span class="hljs-keyword">if</span> (<span class="hljs-string">"2"</span> <span class="hljs-keyword">of</span> obj) <span class="hljs-keyword">and</span> (<span class="hljs-string">"first_line"</span> <span class="hljs-keyword">of</span> obj[<span class="hljs-number">2</span>]) <span class="hljs-keyword">then</span> locationData = obj[<span class="hljs-number">2</span>]
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> <span class="hljs-string">"first_line"</span> <span class="hljs-keyword">of</span> obj <span class="hljs-keyword">then</span> locationData = obj
@@ -442,8 +442,8 @@ The object is returned either way.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">baseFileName</span> = <span class="hljs-params">(file, stripExt = <span class="hljs-literal">no</span>, useWinPathSep = <span class="hljs-literal">no</span>)</span> -&gt;</span>
pathSep = <span class="hljs-keyword">if</span> useWinPathSep <span class="hljs-keyword">then</span> <span class="hljs-regexp">/\\|\//</span> <span class="hljs-keyword">else</span> <span class="hljs-regexp">/\/</span>/
<div class="content"><div class='highlight'><pre>exports.b<span class="hljs-function"><span class="hljs-title">aseFileName</span> = <span class="hljs-params">(file, stripExt = <span class="hljs-literal">no</span>, useWinPathSep = <span class="hljs-literal">no</span>)</span> -&gt;</span>
pathSep = <span class="hljs-keyword">if</span> useWinPathSep <span class="hljs-keyword">then</span> <span class="hljs-regexp">/\\|\//</span> <span class="hljs-keyword">else</span> <span class="hljs-regexp">/\//</span>
parts = file.split(pathSep)
file = parts[parts.length - <span class="hljs-number">1</span>]
<span class="hljs-keyword">return</span> file <span class="hljs-keyword">unless</span> stripExt <span class="hljs-keyword">and</span> file.indexOf(<span class="hljs-string">'.'</span>) &gt;= <span class="hljs-number">0</span>
@@ -465,7 +465,7 @@ The object is returned either way.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">isCoffee</span> = <span class="hljs-params">(file)</span> -&gt;</span> <span class="hljs-regexp">/\.((lit)?coffee|coffee\.md)$/</span>.test file</pre></div></div>
<div class="content"><div class='highlight'><pre>exports.i<span class="hljs-function"><span class="hljs-title">sCoffee</span> = <span class="hljs-params">(file)</span> -&gt;</span> <span class="hljs-regexp">/\.((lit)?coffee|coffee\.md)$/</span>.test file</pre></div></div>
</li>
@@ -480,7 +480,7 @@ The object is returned either way.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">isLiterate</span> = <span class="hljs-params">(file)</span> -&gt;</span> <span class="hljs-regexp">/\.(litcoffee|coffee\.md)$/</span>.test file</pre></div></div>
<div class="content"><div class='highlight'><pre>exports.i<span class="hljs-function"><span class="hljs-title">sLiterate</span> = <span class="hljs-params">(file)</span> -&gt;</span> <span class="hljs-regexp">/\.(litcoffee|coffee\.md)$/</span>.test file</pre></div></div>
</li>
@@ -498,7 +498,7 @@ marker showing where the error is.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">throwSyntaxError</span> = <span class="hljs-params">(message, location)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>exports.t<span class="hljs-function"><span class="hljs-title">hrowSyntaxError</span> = <span class="hljs-params">(message, location)</span> -&gt;</span>
error = <span class="hljs-keyword">new</span> SyntaxError message
error.location = location
error.toString = syntaxErrorToString</pre></div></div>
@@ -536,7 +536,7 @@ it already.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">updateSyntaxError</span> = <span class="hljs-params">(error, code, filename)</span> -&gt;</span></pre></div></div>
<div class="content"><div class='highlight'><pre>exports.u<span class="hljs-function"><span class="hljs-title">pdateSyntaxError</span> = <span class="hljs-params">(error, code, filename)</span> -&gt;</span></pre></div></div>
</li>
@@ -556,8 +556,8 @@ it already.</p>
error.filename <span class="hljs-keyword">or</span>= filename
error.stack = error.toString()
error
<span class="hljs-function"><span class="hljs-title">syntaxErrorToString</span> = -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">syntaxErrorToString</span> = -&gt;</span>
<span class="hljs-keyword">return</span> <span class="hljs-attribute">Error</span>::toString.call @ <span class="hljs-keyword">unless</span> <span class="hljs-property">@code</span> <span class="hljs-keyword">and</span> <span class="hljs-property">@location</span>
{first_line, first_column, last_line, last_column} = <span class="hljs-property">@location</span>
@@ -601,7 +601,7 @@ it already.</p>
colorsEnabled = process.stdout.isTTY <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> process.env.NODE_DISABLE_COLORS
<span class="hljs-keyword">if</span> <span class="hljs-property">@colorful</span> ? colorsEnabled
<span class="hljs-function"><span class="hljs-title">colorize</span> = <span class="hljs-params">(str)</span> -&gt;</span> <span class="hljs-string">"\x1B[1;31m<span class="hljs-subst">#{str}</span>\x1B[0m"</span>
<span class="hljs-function"> <span class="hljs-title">colorize</span> = <span class="hljs-params">(str)</span> -&gt;</span> <span class="hljs-string">"\x1B[1;31m<span class="hljs-subst">#{str}</span>\x1B[0m"</span>
codeLine = codeLine[...start] + colorize(codeLine[start...end]) + codeLine[end..]
marker = colorize marker
@@ -611,7 +611,7 @@ it already.</p>
<span class="hljs-subst">#{marker}</span>
"""</span>
<span class="hljs-built_in">exports</span>.<span class="hljs-function"><span class="hljs-title">nameWhitespaceCharacter</span> = <span class="hljs-params">(string)</span> -&gt;</span>
exports.n<span class="hljs-function"><span class="hljs-title">ameWhitespaceCharacter</span> = <span class="hljs-params">(string)</span> -&gt;</span>
<span class="hljs-keyword">switch</span> string
<span class="hljs-keyword">when</span> <span class="hljs-string">' '</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'space'</span>
<span class="hljs-keyword">when</span> <span class="hljs-string">'\n'</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'newline'</span>

View File

@@ -119,7 +119,7 @@
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>[key] = val <span class="hljs-keyword">for</span> key, val <span class="hljs-keyword">of</span> <span class="hljs-built_in">require</span> <span class="hljs-string">'./coffee-script'</span></pre></div></div>
<div class="content"><div class='highlight'><pre>exports[key] = val <span class="hljs-keyword">for</span> key, val <span class="hljs-keyword">of</span> <span class="hljs-built_in">require</span> <span class="hljs-string">'./coffee-script'</span></pre></div></div>
</li>

File diff suppressed because it is too large Load Diff

View File

@@ -157,8 +157,8 @@ addLocationDataFn, locationDataToString, throwSyntaxError} = <span class="hljs-b
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.extend = extend
<span class="hljs-built_in">exports</span>.addLocationDataFn = addLocationDataFn</pre></div></div>
<div class="content"><div class='highlight'><pre>exports.extend = extend
exports.addLocationDataFn = addLocationDataFn</pre></div></div>
</li>
@@ -207,7 +207,7 @@ all the CodeFragments <code>code</code> snippets, in order.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.CodeFragment = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CodeFragment</span></span>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(parent, code)</span> -&gt;</span>
<span class="hljs-property">@code</span> = <span class="hljs-string">"<span class="hljs-subst">#{code}</span>"</span>
<span class="hljs-property">@locationData</span> = parent?.locationData
@@ -266,7 +266,7 @@ scope, and indentation level.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Base = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Base</span></span>
<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>
<span class="hljs-attribute">compile</span>: <span class="hljs-function"><span class="hljs-params">(o, lvl)</span> -&gt;</span>
fragmentsToText <span class="hljs-property">@compileToFragments</span> o, lvl</pre></div></div>
@@ -327,7 +327,11 @@ object with their parent closure, to preserve the expected lexical scope.</p>
<span class="hljs-keyword">else</span>
meth = <span class="hljs-string">'call'</span>
func = <span class="hljs-keyword">new</span> Value func, [<span class="hljs-keyword">new</span> Access <span class="hljs-keyword">new</span> Literal meth]
(<span class="hljs-keyword">new</span> Call func, args).compileNode o</pre></div></div>
parts = (<span class="hljs-keyword">new</span> Call func, args).compileNode o
<span class="hljs-keyword">if</span> func.isGenerator
parts.unshift <span class="hljs-property">@makeCode</span> <span class="hljs-string">"(yield* "</span>
parts.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">")"</span>
parts</pre></div></div>
</li>
@@ -609,7 +613,7 @@ indented block of code — the implementation of a function, a clause in an
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(nodes)</span> -&gt;</span>
<span class="hljs-property">@expressions</span> = compact flatten nodes <span class="hljs-keyword">or</span> []
@@ -829,7 +833,7 @@ clean up obvious double-parentheses.</p>
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
o.level = LEVEL_TOP
<span class="hljs-property">@spaced</span> = <span class="hljs-literal">yes</span>
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></pre></div></div>
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>
</li>
@@ -951,7 +955,7 @@ JavaScript without translation, such as: strings, numbers,
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@value</span>)</span> -&gt;</span>
<span class="hljs-attribute">makeReturn</span>:<span class="hljs-function"> -&gt;</span>
@@ -1029,7 +1033,7 @@ make sense.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@expression</span>)</span> -&gt;</span>
<span class="hljs-attribute">children</span>: [<span class="hljs-string">'expression'</span>]
@@ -1091,7 +1095,7 @@ or vanilla.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(base, props, tag)</span> -&gt;</span>
<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
<span class="hljs-property">@base</span> = base
@@ -1254,7 +1258,7 @@ evaluate anything twice when building the soak chain.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">unfoldSoak</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
<span class="hljs-property">@unfoldedSoak</span> ?= <span class="hljs-keyword">do</span><span class="hljs-function"> =&gt;</span>
<span class="hljs-property">@unfoldedSoak</span> ?= <span class="hljs-keyword">do</span> <span class="hljs-function">=&gt;</span>
<span class="hljs-keyword">if</span> ifn = <span class="hljs-property">@base</span>.unfoldSoak o
ifn.body.properties.push <span class="hljs-property">@properties</span>...
<span class="hljs-keyword">return</span> ifn
@@ -1296,14 +1300,14 @@ at the same position.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@comment</span>)</span> -&gt;</span>
<span class="hljs-attribute">isStatement</span>: YES
<span class="hljs-attribute">makeReturn</span>: THIS
<span class="hljs-attribute">compileNode</span>: <span class="hljs-function"><span class="hljs-params">(o, level)</span> -&gt;</span>
comment = <span class="hljs-property">@comment</span>.replace <span class="hljs-regexp">/^(\s*)#/gm</span>, <span class="hljs-string">"$1 *"</span>
comment = <span class="hljs-property">@comment</span>.replace <span class="hljs-regexp">/^(\s*)# /gm</span>, <span class="hljs-string">"$1 * "</span>
code = <span class="hljs-string">"/*<span class="hljs-subst">#{multident comment, <span class="hljs-property">@tab</span>}</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">#{<span class="hljs-property">@tab</span>}</span>"</span> <span class="hljs-keyword">else</span> <span class="hljs-string">''</span>}</span> */"</span>
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
[<span class="hljs-property">@makeCode</span>(<span class="hljs-string">"\n"</span>), <span class="hljs-property">@makeCode</span>(code)]</pre></div></div>
@@ -1335,7 +1339,7 @@ calls against the prototypes function of the same name.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(variable, <span class="hljs-property">@args</span> = [], <span class="hljs-property">@soak</span>)</span> -&gt;</span>
<span class="hljs-property">@isNew</span> = <span class="hljs-literal">false</span>
<span class="hljs-property">@isSuper</span> = variable <span class="hljs-keyword">is</span> <span class="hljs-string">'super'</span>
@@ -1569,7 +1573,7 @@ After <code>goog.inherits</code> from the
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@child</span>, <span class="hljs-property">@parent</span>)</span> -&gt;</span>
<span class="hljs-attribute">children</span>: [<span class="hljs-string">'child'</span>, <span class="hljs-string">'parent'</span>]</pre></div></div>
@@ -1588,7 +1592,7 @@ After <code>goog.inherits</code> from the
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">compileToFragments</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</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">'extends'</span>), [<span class="hljs-property">@child</span>, <span class="hljs-property">@parent</span>]).compileToFragments o</pre></div></div>
<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">'extends'</span>, o), [<span class="hljs-property">@child</span>, <span class="hljs-property">@parent</span>]).compileToFragments o</pre></div></div>
</li>
@@ -1617,7 +1621,7 @@ an access into the objects prototype.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@name</span>, tag)</span> -&gt;</span>
<span class="hljs-property">@name</span>.asKey = <span class="hljs-literal">yes</span>
<span class="hljs-property">@soak</span> = tag <span class="hljs-keyword">is</span> <span class="hljs-string">'soak'</span>
@@ -1661,7 +1665,7 @@ an access into the objects prototype.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@index</span>)</span> -&gt;</span>
<span class="hljs-attribute">children</span>: [<span class="hljs-string">'index'</span>]
@@ -1700,7 +1704,7 @@ corresponding array of integers at runtime.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">children</span>: [<span class="hljs-string">'from'</span>, <span class="hljs-string">'to'</span>]
@@ -1866,7 +1870,7 @@ needed to iterate over the values in the range. Used by comprehensions.</p>
cond = <span class="hljs-string">"<span class="hljs-subst">#{<span class="hljs-property">@fromVar</span>}</span> &lt;= <span class="hljs-subst">#{<span class="hljs-property">@toVar</span>}</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> &lt;<span class="hljs-subst">#{<span class="hljs-property">@equals</span>}</span> <span class="hljs-subst">#{<span class="hljs-property">@toVar</span>}</span> : <span class="hljs-subst">#{i}</span> &gt;<span class="hljs-subst">#{<span class="hljs-property">@equals</span>}</span> <span class="hljs-subst">#{<span class="hljs-property">@toVar</span>}</span>; <span class="hljs-subst">#{cond}</span> ? <span class="hljs-subst">#{i}</span>++ : <span class="hljs-subst">#{i}</span>--"</span>
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>
<span class="hljs-function"><span class="hljs-title">hasArgs</span> = <span class="hljs-params">(node)</span> -&gt;</span> node?.contains isLiteralArguments
<span class="hljs-function"> <span class="hljs-title">hasArgs</span> = <span class="hljs-params">(node)</span> -&gt;</span> node?.contains isLiteralArguments
args = <span class="hljs-string">', arguments'</span> <span class="hljs-keyword">if</span> hasArgs(<span class="hljs-property">@from</span>) <span class="hljs-keyword">or</span> hasArgs(<span class="hljs-property">@to</span>)
[<span class="hljs-property">@makeCode</span> <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>
@@ -1898,7 +1902,7 @@ is the index of the beginning.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">children</span>: [<span class="hljs-string">'range'</span>]
@@ -1976,7 +1980,7 @@ is the index of the beginning.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(props, <span class="hljs-property">@generated</span> = <span class="hljs-literal">false</span>)</span> -&gt;</span>
<span class="hljs-property">@objects</span> = <span class="hljs-property">@properties</span> = props <span class="hljs-keyword">or</span> []
@@ -2044,7 +2048,7 @@ is the index of the beginning.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(objs)</span> -&gt;</span>
<span class="hljs-property">@objects</span> = objs <span class="hljs-keyword">or</span> []
@@ -2102,7 +2106,7 @@ list of prototype property assignments.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@variable</span>, <span class="hljs-property">@parent</span>, <span class="hljs-property">@body</span> = <span class="hljs-keyword">new</span> Block)</span> -&gt;</span>
<span class="hljs-property">@boundFuncs</span> = []
<span class="hljs-property">@body</span>.classBody = <span class="hljs-literal">yes</span>
@@ -2172,7 +2176,7 @@ constructor.</p>
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">addBoundFunctions</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
<span class="hljs-keyword">for</span> bvar <span class="hljs-keyword">in</span> <span class="hljs-property">@boundFuncs</span>
lhs = (<span class="hljs-keyword">new</span> Value (<span class="hljs-keyword">new</span> Literal <span class="hljs-string">"this"</span>), [<span class="hljs-keyword">new</span> Access bvar]).compile o
<span class="hljs-property">@ctor</span>.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>}</span>(<span class="hljs-subst">#{lhs}</span>, this)"</span>
<span class="hljs-property">@ctor</span>.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>
<span class="hljs-keyword">return</span></pre></div></div>
</li>
@@ -2369,7 +2373,7 @@ property of an object — including within object literals.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@variable</span>, <span class="hljs-property">@value</span>, <span class="hljs-property">@context</span>, options)</span> -&gt;</span>
<span class="hljs-property">@param</span> = options <span class="hljs-keyword">and</span> options.param
<span class="hljs-property">@subpattern</span> = options <span class="hljs-keyword">and</span> options.subpattern
@@ -2558,7 +2562,7 @@ for details.</p>
<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
name = obj.name.unwrap().value
obj = obj.unwrap()
val = <span class="hljs-string">"<span class="hljs-subst">#{olen}</span> &lt;= <span class="hljs-subst">#{vvarText}</span>.length ? <span class="hljs-subst">#{ utility <span class="hljs-string">'slice'</span> }</span>.call(<span class="hljs-subst">#{vvarText}</span>, <span class="hljs-subst">#{i}</span>"</span>
val = <span class="hljs-string">"<span class="hljs-subst">#{olen}</span> &lt;= <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>
<span class="hljs-keyword">if</span> rest = olen - i - <span class="hljs-number">1</span>
ivar = o.scope.freeVariable <span class="hljs-string">'i'</span>
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>
@@ -2715,11 +2719,13 @@ has no <em>children</em> — theyre within the inner scope.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(params, body, tag)</span> -&gt;</span>
<span class="hljs-property">@params</span> = params <span class="hljs-keyword">or</span> []
<span class="hljs-property">@body</span> = body <span class="hljs-keyword">or</span> <span class="hljs-keyword">new</span> Block
<span class="hljs-property">@bound</span> = tag <span class="hljs-keyword">is</span> <span class="hljs-string">'boundfunc'</span>
<span class="hljs-property">@params</span> = params <span class="hljs-keyword">or</span> []
<span class="hljs-property">@body</span> = body <span class="hljs-keyword">or</span> <span class="hljs-keyword">new</span> Block
<span class="hljs-property">@bound</span> = tag <span class="hljs-keyword">is</span> <span class="hljs-string">'boundfunc'</span>
<span class="hljs-property">@isGenerator</span> = !!<span class="hljs-property">@body</span>.contains <span class="hljs-function"><span class="hljs-params">(node)</span> -&gt;</span>
node <span class="hljs-keyword">instanceof</span> Op <span class="hljs-keyword">and</span> node.operator <span class="hljs-keyword">in</span> [<span class="hljs-string">'yield'</span>, <span class="hljs-string">'yield*'</span>]
<span class="hljs-attribute">children</span>: [<span class="hljs-string">'params'</span>, <span class="hljs-string">'body'</span>]
@@ -2781,9 +2787,8 @@ a closure.</p>
<span class="hljs-keyword">for</span> param <span class="hljs-keyword">in</span> <span class="hljs-property">@params</span> <span class="hljs-keyword">when</span> param <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Expansion
o.scope.parameter param.asReference o
<span class="hljs-keyword">for</span> param <span class="hljs-keyword">in</span> <span class="hljs-property">@params</span> <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> {<span class="hljs-attribute">name</span>: p} <span class="hljs-keyword">in</span> <span class="hljs-property">@params</span> <span class="hljs-keyword">when</span> param <span class="hljs-keyword">not</span> <span class="hljs-keyword">instanceof</span> Expansion
<span class="hljs-keyword">if</span> p.<span class="hljs-keyword">this</span> <span class="hljs-keyword">then</span> p = p.properties[<span class="hljs-number">0</span>].name
<span class="hljs-keyword">if</span> p.value <span class="hljs-keyword">then</span> o.scope.add p.value, <span class="hljs-string">'var'</span>, <span class="hljs-literal">yes</span>
<span class="hljs-keyword">for</span> p <span class="hljs-keyword">in</span> <span class="hljs-property">@params</span> <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
o.scope.add p.name.value, <span class="hljs-string">'var'</span>, <span class="hljs-literal">yes</span>
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> <span class="hljs-property">@params</span>)),
<span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'arguments'</span>
<span class="hljs-keyword">break</span>
@@ -2807,12 +2812,13 @@ a closure.</p>
o.scope.parameter fragmentsToText params[i]
uniqs = []
<span class="hljs-property">@eachParamName</span> <span class="hljs-function"><span class="hljs-params">(name, node)</span> -&gt;</span>
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
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
uniqs.push name
<span class="hljs-property">@body</span>.makeReturn() <span class="hljs-keyword">unless</span> wasEmpty <span class="hljs-keyword">or</span> <span class="hljs-property">@noReturn</span>
code = <span class="hljs-string">'function'</span>
code += <span class="hljs-string">' '</span> + <span class="hljs-property">@name</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@ctor</span>
code += <span class="hljs-string">'('</span>
code = <span class="hljs-string">'function'</span>
code += <span class="hljs-string">'*'</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@isGenerator</span>
code += <span class="hljs-string">' '</span> + <span class="hljs-property">@name</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@ctor</span>
code += <span class="hljs-string">'('</span>
answer = [<span class="hljs-property">@makeCode</span>(code)]
<span class="hljs-keyword">for</span> p, i <span class="hljs-keyword">in</span> params
<span class="hljs-keyword">if</span> i <span class="hljs-keyword">then</span> answer.push <span class="hljs-property">@makeCode</span> <span class="hljs-string">", "</span>
@@ -2872,7 +2878,7 @@ as well as be a splat, gathering up a group of parameters into an array.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@name</span>, <span class="hljs-property">@value</span>, <span class="hljs-property">@splat</span>)</span> -&gt;</span>
<span class="hljs-keyword">if</span> (name = <span class="hljs-property">@name</span>.unwrapAll().value) <span class="hljs-keyword">in</span> STRICT_PROSCRIBED
<span class="hljs-property">@name</span>.error <span class="hljs-string">"parameter name \"<span class="hljs-subst">#{name}</span>\" is not allowed"</span>
@@ -2886,9 +2892,8 @@ as well as be a splat, gathering up a group of parameters into an array.</p>
<span class="hljs-keyword">return</span> <span class="hljs-property">@reference</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@reference</span>
node = <span class="hljs-property">@name</span>
<span class="hljs-keyword">if</span> node.<span class="hljs-keyword">this</span>
node = node.properties[<span class="hljs-number">0</span>].name
<span class="hljs-keyword">if</span> node.value.reserved
node = <span class="hljs-keyword">new</span> Literal o.scope.freeVariable node.value
name = <span class="hljs-string">"at_<span class="hljs-subst">#{node.properties[<span class="hljs-number">0</span>].name.value}</span>"</span>
node = <span class="hljs-keyword">new</span> Literal o.scope.freeVariable name
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> node.isComplex()
node = <span class="hljs-keyword">new</span> Literal o.scope.freeVariable <span class="hljs-string">'arg'</span>
node = <span class="hljs-keyword">new</span> Value node
@@ -2918,9 +2923,7 @@ to that name.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">eachName</span>: <span class="hljs-function"><span class="hljs-params">(iterator, name = <span class="hljs-property">@name</span>)</span>-&gt;</span>
<span class="hljs-function"><span class="hljs-title">atParam</span> = <span class="hljs-params">(obj)</span> -&gt;</span>
node = obj.properties[<span class="hljs-number">0</span>].name
iterator node.value, node <span class="hljs-keyword">unless</span> node.value.reserved</pre></div></div>
<span class="hljs-function"> <span class="hljs-title">atParam</span> = <span class="hljs-params">(obj)</span> -&gt;</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>
</li>
@@ -3078,7 +3081,7 @@ or as part of a destructuring assignment.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">children</span>: [<span class="hljs-string">'name'</span>]
@@ -3117,12 +3120,12 @@ splats, to a proper array.</p>
node = list[<span class="hljs-number">0</span>]
fragments = node.compileToFragments o, LEVEL_LIST
<span class="hljs-keyword">return</span> fragments <span class="hljs-keyword">if</span> apply
<span class="hljs-keyword">return</span> [].concat node.makeCode(<span class="hljs-string">"<span class="hljs-subst">#{ utility <span class="hljs-string">'slice'</span> }</span>.call("</span>), fragments, node.makeCode(<span class="hljs-string">")"</span>)
<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>)
args = list[index..]
<span class="hljs-keyword">for</span> node, i <span class="hljs-keyword">in</span> args
compiledNode = node.compileToFragments o, LEVEL_LIST
args[i] = <span class="hljs-keyword">if</span> node <span class="hljs-keyword">instanceof</span> Splat
<span class="hljs-keyword">then</span> [].concat node.makeCode(<span class="hljs-string">"<span class="hljs-subst">#{ utility <span class="hljs-string">'slice'</span> }</span>.call("</span>), compiledNode, node.makeCode(<span class="hljs-string">")"</span>)
<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>)
<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>]
@@ -3160,7 +3163,7 @@ parameter list.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">isComplex</span>: NO
@@ -3200,7 +3203,7 @@ flexibility or more speed than a comprehension can provide.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(condition, options)</span> -&gt;</span>
<span class="hljs-property">@condition</span> = <span class="hljs-keyword">if</span> options?.invert <span class="hljs-keyword">then</span> condition.invert() <span class="hljs-keyword">else</span> condition
<span class="hljs-property">@guard</span> = options?.guard
@@ -3290,7 +3293,7 @@ CoffeeScript operations into their JavaScript equivalents.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(op, first, second, flip )</span> -&gt;</span>
<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>
@@ -3318,9 +3321,10 @@ CoffeeScript operations into their JavaScript equivalents.</p>
</div>
<div class="content"><div class='highlight'><pre> CONVERSIONS =
<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></pre></div></div>
<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>
</li>
@@ -3343,11 +3347,15 @@ CoffeeScript operations into their JavaScript equivalents.</p>
<span class="hljs-attribute">isSimpleNumber</span>: NO
<span class="hljs-attribute">isYield</span>:<span class="hljs-function"> -&gt;</span>
<span class="hljs-property">@operator</span> <span class="hljs-keyword">in</span> [<span class="hljs-string">'yield'</span>, <span class="hljs-string">'yield*'</span>]
<span class="hljs-attribute">isUnary</span>:<span class="hljs-function"> -&gt;</span>
<span class="hljs-keyword">not</span> <span class="hljs-property">@second</span>
<span class="hljs-attribute">isComplex</span>:<span class="hljs-function"> -&gt;</span>
<span class="hljs-keyword">not</span> (<span class="hljs-property">@isUnary</span>() <span class="hljs-keyword">and</span> <span class="hljs-property">@operator</span> <span class="hljs-keyword">in</span> [<span class="hljs-string">'+'</span>, <span class="hljs-string">'-'</span>]) <span class="hljs-keyword">or</span> <span class="hljs-property">@first</span>.isComplex()</pre></div></div>
<span class="hljs-keyword">not</span> (<span class="hljs-property">@isUnary</span>() <span class="hljs-keyword">and</span> <span class="hljs-property">@operator</span> <span class="hljs-keyword">in</span> [<span class="hljs-string">'+'</span>, <span class="hljs-string">'-'</span>] <span class="hljs-keyword">and</span>
<span class="hljs-property">@first</span> <span class="hljs-keyword">instanceof</span> Value <span class="hljs-keyword">and</span> <span class="hljs-property">@first</span>.isSimpleNumber())</pre></div></div>
</li>
@@ -3434,6 +3442,7 @@ as the chained expression is wrapped.</p>
<span class="hljs-property">@error</span> <span class="hljs-string">'delete operand may not be argument or var'</span>
<span class="hljs-keyword">if</span> <span class="hljs-property">@operator</span> <span class="hljs-keyword">in</span> [<span class="hljs-string">'--'</span>, <span class="hljs-string">'++'</span>] <span class="hljs-keyword">and</span> <span class="hljs-property">@first</span>.unwrapAll().value <span class="hljs-keyword">in</span> STRICT_PROSCRIBED
<span class="hljs-property">@error</span> <span class="hljs-string">"cannot increment/decrement \"<span class="hljs-subst">#{<span class="hljs-property">@first</span>.unwrapAll().value}</span>\""</span>
<span class="hljs-keyword">return</span> <span class="hljs-property">@compileYield</span> o <span class="hljs-keyword">if</span> <span class="hljs-property">@isYield</span>()
<span class="hljs-keyword">return</span> <span class="hljs-property">@compileUnary</span> o <span class="hljs-keyword">if</span> <span class="hljs-property">@isUnary</span>()
<span class="hljs-keyword">return</span> <span class="hljs-property">@compileChain</span> o <span class="hljs-keyword">if</span> isChain
<span class="hljs-keyword">switch</span> <span class="hljs-property">@operator</span>
@@ -3523,6 +3532,19 @@ used sequentially. For example:</p>
parts.reverse() <span class="hljs-keyword">if</span> <span class="hljs-property">@flip</span>
<span class="hljs-property">@joinFragmentArrays</span> parts, <span class="hljs-string">''</span>
<span class="hljs-attribute">compileYield</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
parts = []
op = <span class="hljs-property">@operator</span>
<span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> o.scope.parent?
<span class="hljs-property">@error</span> <span class="hljs-string">'yield statements must occur within a function generator.'</span>
<span class="hljs-keyword">if</span> <span class="hljs-string">'expression'</span> <span class="hljs-keyword">in</span> Object.keys <span class="hljs-property">@first</span>
parts.push <span class="hljs-property">@first</span>.expression.compileToFragments o, LEVEL_OP <span class="hljs-keyword">if</span> <span class="hljs-property">@first</span>.expression?
<span class="hljs-keyword">else</span>
parts.push [<span class="hljs-property">@makeCode</span> <span class="hljs-string">"(<span class="hljs-subst">#{op}</span> "</span>]
parts.push <span class="hljs-property">@first</span>.compileToFragments o, LEVEL_OP
parts.push [<span class="hljs-property">@makeCode</span> <span class="hljs-string">")"</span>]
<span class="hljs-property">@joinFragmentArrays</span> parts, <span class="hljs-string">''</span>
<span class="hljs-attribute">compilePower</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span></pre></div></div>
</li>
@@ -3547,7 +3569,7 @@ used sequentially. For example:</p>
<span class="hljs-keyword">new</span> Call(floor, [div]).compileToFragments o
<span class="hljs-attribute">compileModulo</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
mod = <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal utility <span class="hljs-string">'modulo'</span>
mod = <span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal utility <span class="hljs-string">'modulo'</span>, o
<span class="hljs-keyword">new</span> Call(mod, [<span class="hljs-property">@first</span>, <span class="hljs-property">@second</span>]).compileToFragments o
<span class="hljs-attribute">toString</span>: <span class="hljs-function"><span class="hljs-params">(idt)</span> -&gt;</span>
@@ -3566,7 +3588,7 @@ used sequentially. For example:</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@object</span>, <span class="hljs-property">@array</span>)</span> -&gt;</span>
<span class="hljs-attribute">children</span>: [<span class="hljs-string">'object'</span>, <span class="hljs-string">'array'</span>]
@@ -3606,7 +3628,7 @@ used sequentially. For example:</p>
<span class="hljs-attribute">compileLoopTest</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span>
[sub, ref] = <span class="hljs-property">@object</span>.cache o, LEVEL_LIST
fragments = [].concat <span class="hljs-property">@makeCode</span>(utility(<span class="hljs-string">'indexOf'</span>) + <span class="hljs-string">".call("</span>), <span class="hljs-property">@array</span>.compileToFragments(o, LEVEL_LIST),
fragments = [].concat <span class="hljs-property">@makeCode</span>(utility(<span class="hljs-string">'indexOf'</span>, o) + <span class="hljs-string">".call("</span>), <span class="hljs-property">@array</span>.compileToFragments(o, LEVEL_LIST),
<span class="hljs-property">@makeCode</span>(<span class="hljs-string">", "</span>), ref, <span class="hljs-property">@makeCode</span>(<span class="hljs-string">") "</span> + <span class="hljs-keyword">if</span> <span class="hljs-property">@negated</span> <span class="hljs-keyword">then</span> <span class="hljs-string">'&lt; 0'</span> <span class="hljs-keyword">else</span> <span class="hljs-string">'&gt;= 0'</span>)
<span class="hljs-keyword">return</span> fragments <span class="hljs-keyword">if</span> fragmentsToText(sub) <span class="hljs-keyword">is</span> fragmentsToText(ref)
fragments = sub.concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">', '</span>), fragments
@@ -3641,7 +3663,7 @@ used sequentially. For example:</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@attempt</span>, <span class="hljs-property">@errorVariable</span>, <span class="hljs-property">@recovery</span>, <span class="hljs-property">@ensure</span>)</span> -&gt;</span>
<span class="hljs-attribute">children</span>: [<span class="hljs-string">'attempt'</span>, <span class="hljs-string">'recovery'</span>, <span class="hljs-string">'ensure'</span>]
@@ -3716,7 +3738,7 @@ is optional, the <em>catch</em> is not.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@expression</span>)</span> -&gt;</span>
<span class="hljs-attribute">children</span>: [<span class="hljs-string">'expression'</span>]
@@ -3770,7 +3792,7 @@ table.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@expression</span>)</span> -&gt;</span>
<span class="hljs-attribute">children</span>: [<span class="hljs-string">'expression'</span>]
@@ -3830,7 +3852,7 @@ parentheses, but no longer — you can put in as many as you please.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@body</span>)</span> -&gt;</span>
<span class="hljs-attribute">children</span>: [<span class="hljs-string">'body'</span>]
@@ -3879,7 +3901,7 @@ you can map and filter in a single pass.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(body, source)</span> -&gt;</span>
{<span class="hljs-property">@source</span>, <span class="hljs-property">@guard</span>, <span class="hljs-property">@step</span>, <span class="hljs-property">@name</span>, <span class="hljs-property">@index</span>} = source
<span class="hljs-property">@body</span> = Block.wrap [body]
@@ -3977,7 +3999,7 @@ some cannot.</p>
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
<span class="hljs-keyword">if</span> <span class="hljs-property">@object</span>
forPartFragments = [<span class="hljs-property">@makeCode</span>(<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>}</span>.call(<span class="hljs-subst">#{svar}</span>, <span class="hljs-subst">#{kvar}</span>)) continue;"</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@own</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> <span class="hljs-property">@own</span>
bodyFragments = body.compileToFragments merge(o, <span class="hljs-attribute">indent</span>: idt1), LEVEL_TOP
<span class="hljs-keyword">if</span> bodyFragments <span class="hljs-keyword">and</span> (bodyFragments.length &gt; <span class="hljs-number">0</span>)
bodyFragments = [].concat <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"\n"</span>), bodyFragments, <span class="hljs-property">@makeCode</span>(<span class="hljs-string">"\n"</span>)
@@ -4031,7 +4053,7 @@ some cannot.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@subject</span>, <span class="hljs-property">@cases</span>, <span class="hljs-property">@otherwise</span>)</span> -&gt;</span>
<span class="hljs-attribute">children</span>: [<span class="hljs-string">'subject'</span>, <span class="hljs-string">'cases'</span>, <span class="hljs-string">'otherwise'</span>]
@@ -4098,7 +4120,7 @@ because ternaries are already proper expressions, and dont need conversion.</
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.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>
<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>
<span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(condition, <span class="hljs-property">@body</span>, options = {})</span> -&gt;</span>
<span class="hljs-property">@condition</span> = <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
<span class="hljs-property">@elseBody</span> = <span class="hljs-literal">null</span>
@@ -4264,10 +4286,10 @@ to the superclass for <code>super()</code> calls, and copies of any static prope
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">extends</span>:<span class="hljs-function"> -&gt;</span> <span class="hljs-string">"
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">extends</span>: <span class="hljs-function"><span class="hljs-params">(o)</span> -&gt;</span> <span class="hljs-string">"
function(child, parent) {
for (var key in parent) {
if (<span class="hljs-subst">#{utility <span class="hljs-string">'hasProp'</span>}</span>.call(parent, key)) child[key] = parent[key];
if (<span class="hljs-subst">#{utility <span class="hljs-string">'hasProp'</span>, o}</span>.call(parent, key)) child[key] = parent[key];
}
function ctor() {
this.constructor = child;
@@ -4450,12 +4472,16 @@ IS_REGEX = <span class="hljs-regexp">/^\//</span></pre></div></div>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">utility</span> = <span class="hljs-params">(name)</span> -&gt;</span>
ref = <span class="hljs-string">"__<span class="hljs-subst">#{name}</span>"</span>
Scope.root.assign ref, UTILITIES[name]()
ref
<span class="hljs-function"><span class="hljs-title">multident</span> = <span class="hljs-params">(code, tab)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre><span class="hljs-function"><span class="hljs-title">utility</span> = <span class="hljs-params">(name, o)</span> -&gt;</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>
ref = root.freeVariable <span class="hljs-string">"_<span class="hljs-subst">#{name}</span>"</span>
root.assign ref, UTILITIES[name] o
root.utilities[name] = ref
<span class="hljs-function">
<span class="hljs-title">multident</span> = <span class="hljs-params">(code, tab)</span> -&gt;</span>
code = code.replace <span class="hljs-regexp">/\n/g</span>, <span class="hljs-string">'$&amp;'</span> + tab
code.replace <span class="hljs-regexp">/\s+$/</span>, <span class="hljs-string">''</span></pre></div></div>
@@ -4480,11 +4506,11 @@ Examples: 0, -1, 1, 2e3, 2e-3, -0xfe, 0xfe</p>
parseInt x, <span class="hljs-number">16</span>
<span class="hljs-keyword">else</span>
parseFloat x
<span class="hljs-function"><span class="hljs-title">isLiteralArguments</span> = <span class="hljs-params">(node)</span> -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">isLiteralArguments</span> = <span class="hljs-params">(node)</span> -&gt;</span>
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
<span class="hljs-function"><span class="hljs-title">isLiteralThis</span> = <span class="hljs-params">(node)</span> -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">isLiteralThis</span> = <span class="hljs-params">(node)</span> -&gt;</span>
(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">'this'</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> node.asKey) <span class="hljs-keyword">or</span>
(node <span class="hljs-keyword">instanceof</span> Code <span class="hljs-keyword">and</span> node.bound) <span class="hljs-keyword">or</span>
(node <span class="hljs-keyword">instanceof</span> Call <span class="hljs-keyword">and</span> node.isSuper)</pre></div></div>

View File

@@ -138,7 +138,7 @@ option) list, and all subsequent arguments are left unparsed.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.OptionParser = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">OptionParser</span></span></pre></div></div>
<div class="content"><div class='highlight'><pre>exports.OptionParser = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">OptionParser</span></span></pre></div></div>
</li>

View File

@@ -173,8 +173,8 @@ This is a horrible thing that should not be required.</p>
</div>
<div class="content"><div class='highlight'><pre> Module = <span class="hljs-built_in">require</span> <span class="hljs-string">'module'</span>
<span class="hljs-function"><span class="hljs-title">findExtension</span> = <span class="hljs-params">(filename)</span> -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">findExtension</span> = <span class="hljs-params">(filename)</span> -&gt;</span>
extensions = path.basename(filename).split <span class="hljs-string">'.'</span></pre></div></div>
</li>
@@ -210,7 +210,7 @@ This is a horrible thing that should not be required.</p>
<span class="hljs-keyword">return</span> curExtension <span class="hljs-keyword">if</span> Module._extensions[curExtension]
<span class="hljs-string">'.js'</span>
<span class="hljs-attribute">Module</span>::<span class="hljs-function"><span class="hljs-title">load</span> = <span class="hljs-params">(filename)</span> -&gt;</span>
<span class="hljs-attribute">Module</span>::l<span class="hljs-function"><span class="hljs-title">oad</span> = <span class="hljs-params">(filename)</span> -&gt;</span>
<span class="hljs-property">@filename</span> = filename
<span class="hljs-property">@paths</span> = Module._nodeModulePaths path.dirname filename
extension = findExtension filename
@@ -234,7 +234,7 @@ to fork both CoffeeScript files, and JavaScript files, directly.</p>
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">if</span> child_process
{fork} = child_process
binary = <span class="hljs-built_in">require</span>.resolve <span class="hljs-string">'../../bin/coffee'</span>
child_process.<span class="hljs-function"><span class="hljs-title">fork</span> = <span class="hljs-params">(path, args, options)</span> -&gt;</span>
child_process.f<span class="hljs-function"><span class="hljs-title">ork</span> = <span class="hljs-params">(path, args, options)</span> -&gt;</span>
<span class="hljs-keyword">if</span> helpers.isCoffee path
<span class="hljs-keyword">unless</span> Array.isArray args
options = args <span class="hljs-keyword">or</span> {}

View File

@@ -188,11 +188,11 @@ parens. Unwrap all that.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">&#182;</a>
</div>
<p>Generate the AST of the clean input.</p>
<p>Tokenize the clean input.</p>
</div>
<div class="content"><div class='highlight'><pre> ast = CoffeeScript.nodes input</pre></div></div>
<div class="content"><div class='highlight'><pre> tokens = CoffeeScript.tokens input</pre></div></div>
</li>
@@ -203,20 +203,13 @@ parens. Unwrap all that.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">&#182;</a>
</div>
<p>Add assignment to <code>_</code> variable to force the input to be an expression.</p>
<p>Collect referenced variable names just like in <code>CoffeeScript.compile</code>.</p>
</div>
<div class="content"><div class='highlight'><pre> ast = <span class="hljs-keyword">new</span> Block [
<span class="hljs-keyword">new</span> Assign (<span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'_'</span>), ast, <span class="hljs-string">'='</span>
]
js = ast.compile <span class="hljs-attribute">bare</span>: <span class="hljs-literal">yes</span>, <span class="hljs-attribute">locals</span>: Object.keys(context)
result = <span class="hljs-keyword">if</span> context <span class="hljs-keyword">is</span> <span class="hljs-built_in">global</span>
vm.runInThisContext js, filename
<span class="hljs-keyword">else</span>
vm.runInContext js, context, filename
cb <span class="hljs-literal">null</span>, result
<span class="hljs-keyword">catch</span> err</pre></div></div>
<div class="content"><div class='highlight'><pre> referencedVars = (
token[<span class="hljs-number">1</span>] <span class="hljs-keyword">for</span> token <span class="hljs-keyword">in</span> tokens <span class="hljs-keyword">when</span> token.variable <span class="hljs-keyword">and</span> token[<span class="hljs-number">1</span>].charAt(<span class="hljs-number">0</span>) <span class="hljs-keyword">is</span> <span class="hljs-string">'_'</span>
)</pre></div></div>
</li>
@@ -227,15 +220,11 @@ parens. Unwrap all that.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">&#182;</a>
</div>
<p>ASTs <code>compile</code> does not add source code information to syntax errors.</p>
<p>Generate the AST of the tokens.</p>
</div>
<div class="content"><div class='highlight'><pre> updateSyntaxError err, input
cb err
<span class="hljs-function"><span class="hljs-title">addMultilineHandler</span> = <span class="hljs-params">(repl)</span> -&gt;</span>
{rli, inputStream, outputStream} = repl</pre></div></div>
<div class="content"><div class='highlight'><pre> ast = CoffeeScript.nodes tokens</pre></div></div>
</li>
@@ -246,6 +235,49 @@ parens. Unwrap all that.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">&#182;</a>
</div>
<p>Add assignment to <code>_</code> variable to force the input to be an expression.</p>
</div>
<div class="content"><div class='highlight'><pre> ast = <span class="hljs-keyword">new</span> Block [
<span class="hljs-keyword">new</span> Assign (<span class="hljs-keyword">new</span> Value <span class="hljs-keyword">new</span> Literal <span class="hljs-string">'_'</span>), ast, <span class="hljs-string">'='</span>
]
js = ast.compile {<span class="hljs-attribute">bare</span>: <span class="hljs-literal">yes</span>, <span class="hljs-attribute">locals</span>: Object.keys(context), referencedVars}
result = <span class="hljs-keyword">if</span> context <span class="hljs-keyword">is</span> <span class="hljs-built_in">global</span>
vm.runInThisContext js, filename
<span class="hljs-keyword">else</span>
vm.runInContext js, context, filename
cb <span class="hljs-literal">null</span>, result
<span class="hljs-keyword">catch</span> err</pre></div></div>
</li>
<li id="section-9">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</a>
</div>
<p>ASTs <code>compile</code> does not add source code information to syntax errors.</p>
</div>
<div class="content"><div class='highlight'><pre> updateSyntaxError err, input
cb err
<span class="hljs-function">
<span class="hljs-title">addMultilineHandler</span> = <span class="hljs-params">(repl)</span> -&gt;</span>
{rli, inputStream, outputStream} = repl</pre></div></div>
</li>
<li id="section-10">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a>
</div>
<p>Node 0.11.12 changed API, prompt is now _prompt.</p>
</div>
@@ -261,11 +293,11 @@ parens. Unwrap all that.</p>
</li>
<li id="section-9">
<li id="section-11">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">&#182;</a>
<a class="pilcrow" href="#section-11">&#182;</a>
</div>
<p>Proxy nodes line listener</p>
@@ -286,11 +318,11 @@ parens. Unwrap all that.</p>
</li>
<li id="section-10">
<li id="section-12">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">&#182;</a>
<a class="pilcrow" href="#section-12">&#182;</a>
</div>
<p>Handle Ctrl-v</p>
@@ -303,11 +335,11 @@ parens. Unwrap all that.</p>
</li>
<li id="section-11">
<li id="section-13">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">&#182;</a>
<a class="pilcrow" href="#section-13">&#182;</a>
</div>
<p>allow arbitrarily switching between modes any time before multiple lines are entered</p>
@@ -322,11 +354,11 @@ parens. Unwrap all that.</p>
</li>
<li id="section-12">
<li id="section-14">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">&#182;</a>
<a class="pilcrow" href="#section-14">&#182;</a>
</div>
<p>no-op unless the current line is empty</p>
@@ -337,11 +369,11 @@ parens. Unwrap all that.</p>
</li>
<li id="section-13">
<li id="section-15">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-13">&#182;</a>
<a class="pilcrow" href="#section-15">&#182;</a>
</div>
<p>eval, print, loop</p>
@@ -356,11 +388,11 @@ parens. Unwrap all that.</p>
</li>
<li id="section-14">
<li id="section-16">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-14">&#182;</a>
<a class="pilcrow" href="#section-16">&#182;</a>
</div>
<p>XXX: multiline hack</p>
@@ -378,11 +410,11 @@ parens. Unwrap all that.</p>
</li>
<li id="section-15">
<li id="section-17">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-15">&#182;</a>
<a class="pilcrow" href="#section-17">&#182;</a>
</div>
<p>Store and load command history from a file</p>
@@ -395,11 +427,11 @@ parens. Unwrap all that.</p>
</li>
<li id="section-16">
<li id="section-18">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-16">&#182;</a>
<a class="pilcrow" href="#section-18">&#182;</a>
</div>
<p>Get file info and at most maxSize of command history</p>
@@ -411,11 +443,11 @@ parens. Unwrap all that.</p>
</li>
<li id="section-17">
<li id="section-19">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">&#182;</a>
<a class="pilcrow" href="#section-19">&#182;</a>
</div>
<p>Read last <code>size</code> bytes from the file</p>
@@ -428,11 +460,11 @@ parens. Unwrap all that.</p>
</li>
<li id="section-18">
<li id="section-20">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-18">&#182;</a>
<a class="pilcrow" href="#section-20">&#182;</a>
</div>
<p>Set the history on the interpreter</p>
@@ -443,11 +475,11 @@ parens. Unwrap all that.</p>
</li>
<li id="section-19">
<li id="section-21">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-19">&#182;</a>
<a class="pilcrow" href="#section-21">&#182;</a>
</div>
<p>If the history file was truncated we should pop off a potential partial line</p>
@@ -458,11 +490,11 @@ parens. Unwrap all that.</p>
</li>
<li id="section-20">
<li id="section-22">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-20">&#182;</a>
<a class="pilcrow" href="#section-22">&#182;</a>
</div>
<p>Shift off the final blank newline</p>
@@ -480,11 +512,11 @@ parens. Unwrap all that.</p>
</li>
<li id="section-21">
<li id="section-23">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-21">&#182;</a>
<a class="pilcrow" href="#section-23">&#182;</a>
</div>
<p>Save the latest command in the file</p>
@@ -498,11 +530,11 @@ parens. Unwrap all that.</p>
</li>
<li id="section-22">
<li id="section-24">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-22">&#182;</a>
<a class="pilcrow" href="#section-24">&#182;</a>
</div>
<p>Add a command to show the history stack</p>
@@ -513,17 +545,17 @@ parens. Unwrap all that.</p>
<span class="hljs-attribute">action</span>:<span class="hljs-function"> -&gt;</span>
repl.outputStream.write <span class="hljs-string">"<span class="hljs-subst">#{repl.rli.history[..].reverse().join <span class="hljs-string">'\n'</span>}</span>\n"</span>
repl.displayPrompt()
<span class="hljs-function"><span class="hljs-title">getCommandId</span> = <span class="hljs-params">(repl, commandName)</span> -&gt;</span></pre></div></div>
<span class="hljs-function">
<span class="hljs-title">getCommandId</span> = <span class="hljs-params">(repl, commandName)</span> -&gt;</span></pre></div></div>
</li>
<li id="section-23">
<li id="section-25">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-23">&#182;</a>
<a class="pilcrow" href="#section-25">&#182;</a>
</div>
<p>Node 0.11 changed API, a command such as .help is now stored as help</p>
@@ -532,9 +564,9 @@ parens. Unwrap all that.</p>
<div class="content"><div class='highlight'><pre> commandsHaveLeadingDot = repl.commands[<span class="hljs-string">'.help'</span>]?
<span class="hljs-keyword">if</span> commandsHaveLeadingDot <span class="hljs-keyword">then</span> <span class="hljs-string">".<span class="hljs-subst">#{commandName}</span>"</span> <span class="hljs-keyword">else</span> commandName
<span class="hljs-built_in">module</span>.<span class="hljs-built_in">exports</span> =
<span class="hljs-built_in">module</span>.exports =
<span class="hljs-attribute">start</span>: <span class="hljs-function"><span class="hljs-params">(opts = {})</span> -&gt;</span>
[major, minor, build] = process.versions.node.split<span class="hljs-function"><span class="hljs-params">(<span class="hljs-string">'.'</span>)</span>.<span class="hljs-title">map</span> <span class="hljs-params">(n)</span> -&gt;</span> parseInt(n)
[major, minor, build] = process.versions.node.split(<span class="hljs-string">'.'</span>).map <span class="hljs-function"><span class="hljs-params">(n)</span> -&gt;</span> parseInt(n)
<span class="hljs-keyword">if</span> major <span class="hljs-keyword">is</span> <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> minor &lt; <span class="hljs-number">8</span>
<span class="hljs-built_in">console</span>.warn <span class="hljs-string">"Node 0.8.0+ required for CoffeeScript REPL"</span>
@@ -551,11 +583,11 @@ parens. Unwrap all that.</p>
</li>
<li id="section-24">
<li id="section-26">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-24">&#182;</a>
<a class="pilcrow" href="#section-26">&#182;</a>
</div>
<p>Adapt help inherited from the node REPL</p>

View File

@@ -270,11 +270,11 @@ calls that close on the same line, just before their outdent.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">closeOpenCalls</span>:<span class="hljs-function"> -&gt;</span>
<span class="hljs-function"><span class="hljs-title">condition</span> = <span class="hljs-params">(token, i)</span> -&gt;</span>
<span class="hljs-function"> <span class="hljs-title">condition</span> = <span class="hljs-params">(token, i)</span> -&gt;</span>
token[<span class="hljs-number">0</span>] <span class="hljs-keyword">in</span> [<span class="hljs-string">')'</span>, <span class="hljs-string">'CALL_END'</span>] <span class="hljs-keyword">or</span>
token[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'OUTDENT'</span> <span class="hljs-keyword">and</span> <span class="hljs-property">@tag</span>(i - <span class="hljs-number">1</span>) <span class="hljs-keyword">is</span> <span class="hljs-string">')'</span>
<span class="hljs-function"><span class="hljs-title">action</span> = <span class="hljs-params">(token, i)</span> -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">action</span> = <span class="hljs-params">(token, i)</span> -&gt;</span>
<span class="hljs-property">@tokens</span>[<span class="hljs-keyword">if</span> token[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'OUTDENT'</span> <span class="hljs-keyword">then</span> i - <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> i][<span class="hljs-number">0</span>] = <span class="hljs-string">'CALL_END'</span>
<span class="hljs-property">@scanTokens</span> <span class="hljs-function"><span class="hljs-params">(token, i)</span> -&gt;</span>
@@ -296,10 +296,10 @@ Match it with its paired close.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">closeOpenIndexes</span>:<span class="hljs-function"> -&gt;</span>
<span class="hljs-function"><span class="hljs-title">condition</span> = <span class="hljs-params">(token, i)</span> -&gt;</span>
<span class="hljs-function"> <span class="hljs-title">condition</span> = <span class="hljs-params">(token, i)</span> -&gt;</span>
token[<span class="hljs-number">0</span>] <span class="hljs-keyword">in</span> [<span class="hljs-string">']'</span>, <span class="hljs-string">'INDEX_END'</span>]
<span class="hljs-function"><span class="hljs-title">action</span> = <span class="hljs-params">(token, i)</span> -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">action</span> = <span class="hljs-params">(token, i)</span> -&gt;</span>
token[<span class="hljs-number">0</span>] = <span class="hljs-string">'INDEX_END'</span>
<span class="hljs-property">@scanTokens</span> <span class="hljs-function"><span class="hljs-params">(token, i)</span> -&gt;</span>
@@ -408,7 +408,7 @@ add them.</p>
[tag] = token
[prevTag] = prevToken = <span class="hljs-keyword">if</span> i &gt; <span class="hljs-number">0</span> <span class="hljs-keyword">then</span> tokens[i - <span class="hljs-number">1</span>] <span class="hljs-keyword">else</span> []
[nextTag] = <span class="hljs-keyword">if</span> i &lt; tokens.length - <span class="hljs-number">1</span> <span class="hljs-keyword">then</span> tokens[i + <span class="hljs-number">1</span>] <span class="hljs-keyword">else</span> []
<span class="hljs-function"><span class="hljs-title">stackTop</span> = -&gt;</span> stack[stack.length - <span class="hljs-number">1</span>]
<span class="hljs-function"> <span class="hljs-title">stackTop</span> = -&gt;</span> stack[stack.length - <span class="hljs-number">1</span>]
startIdx = i</pre></div></div>
</li>
@@ -425,7 +425,7 @@ and spliced, when returning for getting a new token.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-title">forward</span> = <span class="hljs-params">(n)</span> -&gt;</span> i - startIdx + n</pre></div></div>
<div class="content"><div class='highlight'><pre><span class="hljs-function"> <span class="hljs-title">forward</span> = <span class="hljs-params">(n)</span> -&gt;</span> i - startIdx + n</pre></div></div>
</li>
@@ -440,9 +440,9 @@ and spliced, when returning for getting a new token.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-title">inImplicit</span> = -&gt;</span> stackTop()?[<span class="hljs-number">2</span>]?.ours
<span class="hljs-function"><span class="hljs-title">inImplicitCall</span> = -&gt;</span> inImplicit() <span class="hljs-keyword">and</span> stackTop()?[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'('</span>
<span class="hljs-function"><span class="hljs-title">inImplicitObject</span> = -&gt;</span> inImplicit() <span class="hljs-keyword">and</span> stackTop()?[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'{'</span></pre></div></div>
<div class="content"><div class='highlight'><pre><span class="hljs-function"> <span class="hljs-title">inImplicit</span> = -&gt;</span> stackTop()?[<span class="hljs-number">2</span>]?.ours
<span class="hljs-function"> <span class="hljs-title">inImplicitCall</span> = -&gt;</span> inImplicit() <span class="hljs-keyword">and</span> stackTop()?[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'('</span>
<span class="hljs-function"> <span class="hljs-title">inImplicitObject</span> = -&gt;</span> inImplicit() <span class="hljs-keyword">and</span> stackTop()?[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'{'</span></pre></div></div>
</li>
@@ -458,26 +458,26 @@ class declaration or if-conditionals)</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-function"><span class="hljs-title">inImplicitControl</span> = -&gt;</span> inImplicit <span class="hljs-keyword">and</span> stackTop()?[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'CONTROL'</span>
<span class="hljs-function"><span class="hljs-title">startImplicitCall</span> = <span class="hljs-params">(j)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre><span class="hljs-function"> <span class="hljs-title">inImplicitControl</span> = -&gt;</span> inImplicit <span class="hljs-keyword">and</span> stackTop()?[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'CONTROL'</span>
<span class="hljs-function">
<span class="hljs-title">startImplicitCall</span> = <span class="hljs-params">(j)</span> -&gt;</span>
idx = j ? i
stack.push [<span class="hljs-string">'('</span>, idx, <span class="hljs-attribute">ours</span>: <span class="hljs-literal">yes</span>]
tokens.splice idx, <span class="hljs-number">0</span>, generate <span class="hljs-string">'CALL_START'</span>, <span class="hljs-string">'('</span>
i += <span class="hljs-number">1</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> j?
<span class="hljs-function"><span class="hljs-title">endImplicitCall</span> = -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">endImplicitCall</span> = -&gt;</span>
stack.pop()
tokens.splice i, <span class="hljs-number">0</span>, generate <span class="hljs-string">'CALL_END'</span>, <span class="hljs-string">')'</span>
tokens.splice i, <span class="hljs-number">0</span>, generate <span class="hljs-string">'CALL_END'</span>, <span class="hljs-string">')'</span>, [<span class="hljs-string">''</span>, <span class="hljs-string">'end of input'</span>, token[<span class="hljs-number">2</span>]]
i += <span class="hljs-number">1</span>
<span class="hljs-function"><span class="hljs-title">startImplicitObject</span> = <span class="hljs-params">(j, startsLine = <span class="hljs-literal">yes</span>)</span> -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">startImplicitObject</span> = <span class="hljs-params">(j, startsLine = <span class="hljs-literal">yes</span>)</span> -&gt;</span>
idx = j ? i
stack.push [<span class="hljs-string">'{'</span>, idx, <span class="hljs-attribute">sameLine</span>: <span class="hljs-literal">yes</span>, <span class="hljs-attribute">startsLine</span>: startsLine, <span class="hljs-attribute">ours</span>: <span class="hljs-literal">yes</span>]
tokens.splice idx, <span class="hljs-number">0</span>, generate <span class="hljs-string">'{'</span>, generate(<span class="hljs-keyword">new</span> String(<span class="hljs-string">'{'</span>)), token
i += <span class="hljs-number">1</span> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> j?
<span class="hljs-function"><span class="hljs-title">endImplicitObject</span> = <span class="hljs-params">(j)</span> -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">endImplicitObject</span> = <span class="hljs-params">(j)</span> -&gt;</span>
j = j ? i
stack.pop()
tokens.splice j, <span class="hljs-number">0</span>, generate <span class="hljs-string">'}'</span>, <span class="hljs-string">'}'</span>, token
@@ -580,7 +580,7 @@ f a, f() b, f? c, h[0] d etc.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (tag <span class="hljs-keyword">in</span> IMPLICIT_FUNC <span class="hljs-keyword">and</span> token.spaced <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> token.stringEnd <span class="hljs-keyword">or</span>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (tag <span class="hljs-keyword">in</span> IMPLICIT_FUNC <span class="hljs-keyword">and</span> token.spaced <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> token.stringEnd <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> token.regexEnd <span class="hljs-keyword">or</span>
tag <span class="hljs-keyword">is</span> <span class="hljs-string">'?'</span> <span class="hljs-keyword">and</span> i &gt; <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> tokens[i - <span class="hljs-number">1</span>].spaced) <span class="hljs-keyword">and</span>
(nextTag <span class="hljs-keyword">in</span> IMPLICIT_CALL <span class="hljs-keyword">or</span>
nextTag <span class="hljs-keyword">in</span> IMPLICIT_UNSPACED_CALL <span class="hljs-keyword">and</span>
@@ -619,7 +619,8 @@ that creates grammatical ambiguities.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> tag <span class="hljs-keyword">in</span> IMPLICIT_FUNC <span class="hljs-keyword">and</span> <span class="hljs-property">@matchTags</span>(i + <span class="hljs-number">1</span>, <span class="hljs-string">'INDENT'</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">':'</span>) <span class="hljs-keyword">and</span>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> tag <span class="hljs-keyword">in</span> IMPLICIT_FUNC <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> token.stringEnd <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> token.regexEnd <span class="hljs-keyword">and</span>
<span class="hljs-property">@matchTags</span>(i + <span class="hljs-number">1</span>, <span class="hljs-string">'INDENT'</span>, <span class="hljs-literal">null</span>, <span class="hljs-string">':'</span>) <span class="hljs-keyword">and</span>
<span class="hljs-keyword">not</span> <span class="hljs-property">@findTagsBackwards</span>(i, [<span class="hljs-string">'CLASS'</span>, <span class="hljs-string">'EXTENDS'</span>, <span class="hljs-string">'IF'</span>, <span class="hljs-string">'CATCH'</span>,
<span class="hljs-string">'SWITCH'</span>, <span class="hljs-string">'LEADING_WHEN'</span>, <span class="hljs-string">'FOR'</span>, <span class="hljs-string">'WHILE'</span>, <span class="hljs-string">'UNTIL'</span>])
startImplicitCall i + <span class="hljs-number">1</span>
@@ -707,7 +708,7 @@ that creates grammatical ambiguities.</p>
</div>
<p>End implicit calls when chaining method calls
like e.g.:</p>
<pre><code>f<span class="hljs-function"> -&gt;</span>
<pre><code>f <span class="hljs-function">-&gt;</span>
a
.g b,<span class="hljs-function"> -&gt;</span>
c
@@ -878,15 +879,15 @@ blocks are added.</p>
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">normalizeLines</span>:<span class="hljs-function"> -&gt;</span>
starter = indent = outdent = <span class="hljs-literal">null</span>
<span class="hljs-function"><span class="hljs-title">condition</span> = <span class="hljs-params">(token, i)</span> -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">condition</span> = <span class="hljs-params">(token, i)</span> -&gt;</span>
token[<span class="hljs-number">1</span>] <span class="hljs-keyword">isnt</span> <span class="hljs-string">';'</span> <span class="hljs-keyword">and</span> token[<span class="hljs-number">0</span>] <span class="hljs-keyword">in</span> SINGLE_CLOSERS <span class="hljs-keyword">and</span>
<span class="hljs-keyword">not</span> (token[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'TERMINATOR'</span> <span class="hljs-keyword">and</span> <span class="hljs-property">@tag</span>(i + <span class="hljs-number">1</span>) <span class="hljs-keyword">in</span> EXPRESSION_CLOSE) <span class="hljs-keyword">and</span>
<span class="hljs-keyword">not</span> (token[<span class="hljs-number">0</span>] <span class="hljs-keyword">is</span> <span class="hljs-string">'ELSE'</span> <span class="hljs-keyword">and</span> starter <span class="hljs-keyword">isnt</span> <span class="hljs-string">'THEN'</span>) <span class="hljs-keyword">and</span>
<span class="hljs-keyword">not</span> (token[<span class="hljs-number">0</span>] <span class="hljs-keyword">in</span> [<span class="hljs-string">'CATCH'</span>, <span class="hljs-string">'FINALLY'</span>] <span class="hljs-keyword">and</span> starter <span class="hljs-keyword">in</span> [<span class="hljs-string">'-&gt;'</span>, <span class="hljs-string">'=&gt;'</span>]) <span class="hljs-keyword">or</span>
token[<span class="hljs-number">0</span>] <span class="hljs-keyword">in</span> CALL_CLOSERS <span class="hljs-keyword">and</span> <span class="hljs-property">@tokens</span>[i - <span class="hljs-number">1</span>].newLine
<span class="hljs-function"><span class="hljs-title">action</span> = <span class="hljs-params">(token, i)</span> -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">action</span> = <span class="hljs-params">(token, i)</span> -&gt;</span>
<span class="hljs-property">@tokens</span>.splice (<span class="hljs-keyword">if</span> <span class="hljs-property">@tag</span>(i - <span class="hljs-number">1</span>) <span class="hljs-keyword">is</span> <span class="hljs-string">','</span> <span class="hljs-keyword">then</span> i - <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> i), <span class="hljs-number">0</span>, outdent
<span class="hljs-property">@scanTokens</span> <span class="hljs-function"><span class="hljs-params">(token, i, tokens)</span> -&gt;</span>
@@ -930,13 +931,13 @@ different precedence.</p>
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">tagPostfixConditionals</span>:<span class="hljs-function"> -&gt;</span>
original = <span class="hljs-literal">null</span>
<span class="hljs-function"><span class="hljs-title">condition</span> = <span class="hljs-params">(token, i)</span> -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">condition</span> = <span class="hljs-params">(token, i)</span> -&gt;</span>
[tag] = token
[prevTag] = <span class="hljs-property">@tokens</span>[i - <span class="hljs-number">1</span>]
tag <span class="hljs-keyword">is</span> <span class="hljs-string">'TERMINATOR'</span> <span class="hljs-keyword">or</span> (tag <span class="hljs-keyword">is</span> <span class="hljs-string">'INDENT'</span> <span class="hljs-keyword">and</span> prevTag <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> SINGLE_LINERS)
<span class="hljs-function"><span class="hljs-title">action</span> = <span class="hljs-params">(token, i)</span> -&gt;</span>
<span class="hljs-function">
<span class="hljs-title">action</span> = <span class="hljs-params">(token, i)</span> -&gt;</span>
<span class="hljs-keyword">if</span> token[<span class="hljs-number">0</span>] <span class="hljs-keyword">isnt</span> <span class="hljs-string">'INDENT'</span> <span class="hljs-keyword">or</span> (token.generated <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> token.fromThen)
original[<span class="hljs-number">0</span>] = <span class="hljs-string">'POST_'</span> + original[<span class="hljs-number">0</span>]
@@ -1048,7 +1049,7 @@ look things up from either end.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.INVERSES = INVERSES = {}</pre></div></div>
<div class="content"><div class='highlight'><pre>exports.INVERSES = INVERSES = {}</pre></div></div>
</li>
@@ -1115,7 +1116,7 @@ EXPRESSION_END = []
<div class="content"><div class='highlight'><pre>IMPLICIT_CALL = [
<span class="hljs-string">'IDENTIFIER'</span>, <span class="hljs-string">'NUMBER'</span>, <span class="hljs-string">'STRING'</span>, <span class="hljs-string">'JS'</span>, <span class="hljs-string">'REGEX'</span>, <span class="hljs-string">'NEW'</span>, <span class="hljs-string">'PARAM_START'</span>, <span class="hljs-string">'CLASS'</span>
<span class="hljs-string">'IF'</span>, <span class="hljs-string">'TRY'</span>, <span class="hljs-string">'SWITCH'</span>, <span class="hljs-string">'THIS'</span>, <span class="hljs-string">'BOOL'</span>, <span class="hljs-string">'NULL'</span>, <span class="hljs-string">'UNDEFINED'</span>, <span class="hljs-string">'UNARY'</span>,
<span class="hljs-string">'IF'</span>, <span class="hljs-string">'TRY'</span>, <span class="hljs-string">'SWITCH'</span>, <span class="hljs-string">'THIS'</span>, <span class="hljs-string">'BOOL'</span>, <span class="hljs-string">'NULL'</span>, <span class="hljs-string">'UNDEFINED'</span>, <span class="hljs-string">'UNARY'</span>, <span class="hljs-string">'YIELD'</span>
<span class="hljs-string">'UNARY_MATH'</span>, <span class="hljs-string">'SUPER'</span>, <span class="hljs-string">'THROW'</span>, <span class="hljs-string">'@'</span>, <span class="hljs-string">'-&gt;'</span>, <span class="hljs-string">'=&gt;'</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>
]

View File

@@ -127,7 +127,7 @@ with external scopes.</p>
<div class="content"><div class='highlight'><pre>{extend, last} = <span class="hljs-built_in">require</span> <span class="hljs-string">'./helpers'</span>
<span class="hljs-built_in">exports</span>.Scope = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Scope</span></span></pre></div></div>
exports.Scope = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Scope</span></span></pre></div></div>
</li>
@@ -138,11 +138,18 @@ with external scopes.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">&#182;</a>
</div>
<p>The <code>root</code> is the top-level <strong>Scope</strong> object for a given file.</p>
<p>Initialize a scope with its parent, for lookups up the chain,
as well as a reference to the <strong>Block</strong> node it belongs to, which is
where it should declare its variables, a reference to the function that
it belongs to, and a list of variables referenced in the source code
and therefore should be avoided when generating variables.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-property">@root</span>: <span class="hljs-literal">null</span></pre></div></div>
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@parent</span>, <span class="hljs-property">@expressions</span>, <span class="hljs-property">@method</span>, <span class="hljs-property">@referencedVars</span>)</span> -&gt;</span>
<span class="hljs-property">@variables</span> = [{<span class="hljs-attribute">name</span>: <span class="hljs-string">'arguments'</span>, <span class="hljs-attribute">type</span>: <span class="hljs-string">'arguments'</span>}]
<span class="hljs-property">@positions</span> = {}
<span class="hljs-property">@utilities</span> = {} <span class="hljs-keyword">unless</span> <span class="hljs-property">@parent</span></pre></div></div>
</li>
@@ -153,17 +160,11 @@ with external scopes.</p>
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">&#182;</a>
</div>
<p>Initialize a scope with its parent, for lookups up the chain,
as well as a reference to the <strong>Block</strong> node it belongs to, which is
where it should declare its variables, and a reference to the function that
it belongs to.</p>
<p>The <code>@root</code> is the top-level <strong>Scope</strong> object for a given file.</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@parent</span>, <span class="hljs-property">@expressions</span>, <span class="hljs-property">@method</span>)</span> -&gt;</span>
<span class="hljs-property">@variables</span> = [{<span class="hljs-attribute">name</span>: <span class="hljs-string">'arguments'</span>, <span class="hljs-attribute">type</span>: <span class="hljs-string">'arguments'</span>}]
<span class="hljs-property">@positions</span> = {}
Scope.root = <span class="hljs-keyword">this</span> <span class="hljs-keyword">unless</span> <span class="hljs-property">@parent</span></pre></div></div>
<div class="content"><div class='highlight'><pre> <span class="hljs-property">@root</span> = <span class="hljs-property">@parent</span>?.root ? <span class="hljs-keyword">this</span></pre></div></div>
</li>
@@ -312,7 +313,10 @@ compiler-generated variable. <code>_var</code>, <code>_var2</code>, and so on…
<div class="content"><div class='highlight'><pre> <span class="hljs-attribute">freeVariable</span>: <span class="hljs-function"><span class="hljs-params">(name, reserve=<span class="hljs-literal">true</span>)</span> -&gt;</span>
index = <span class="hljs-number">0</span>
index++ <span class="hljs-keyword">while</span> <span class="hljs-property">@check</span>((temp = <span class="hljs-property">@temporary</span> name, index))
<span class="hljs-keyword">loop</span>
temp = <span class="hljs-property">@temporary</span> name, index
<span class="hljs-keyword">break</span> <span class="hljs-keyword">unless</span> <span class="hljs-property">@check</span>(temp) <span class="hljs-keyword">or</span> temp <span class="hljs-keyword">in</span> <span class="hljs-property">@root</span>.referencedVars
index++
<span class="hljs-property">@add</span> temp, <span class="hljs-string">'var'</span>, <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> reserve
temp</pre></div></div>

View File

@@ -513,7 +513,7 @@ bits of the original value encoded into the first byte of the VLQ encoded value.
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">module</span>.<span class="hljs-built_in">exports</span> = SourceMap</pre></div></div>
<div class="content"><div class='highlight'><pre><span class="hljs-built_in">module</span>.exports = SourceMap</pre></div></div>
</li>

View File

@@ -214,7 +214,7 @@ nativeKeys = Object.keys</pre></div></div>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">if</span> <span class="hljs-keyword">typeof</span>(<span class="hljs-built_in">exports</span>) != <span class="hljs-string">'undefined'</span> <span class="hljs-keyword">then</span> <span class="hljs-built_in">exports</span>._ = _</pre></div></div>
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">if</span> <span class="hljs-keyword">typeof</span>(exports) != <span class="hljs-string">'undefined'</span> <span class="hljs-keyword">then</span> exports._ = _</pre></div></div>
</li>
@@ -285,7 +285,7 @@ Handles objects implementing <strong>forEach</strong>, arrays, and raw objects.<
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">each</span> = <span class="hljs-params">(obj, iterator, context)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.e<span class="hljs-function"><span class="hljs-title">ach</span> = <span class="hljs-params">(obj, iterator, context)</span> -&gt;</span>
<span class="hljs-keyword">try</span>
<span class="hljs-keyword">if</span> nativeForEach <span class="hljs-keyword">and</span> obj.forEach <span class="hljs-keyword">is</span> nativeForEach
obj.forEach iterator, context
@@ -311,7 +311,7 @@ Handles objects implementing <strong>forEach</strong>, arrays, and raw objects.<
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">map</span> = <span class="hljs-params">(obj, iterator, context)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.m<span class="hljs-function"><span class="hljs-title">ap</span> = <span class="hljs-params">(obj, iterator, context)</span> -&gt;</span>
<span class="hljs-keyword">return</span> obj.map(iterator, context) <span class="hljs-keyword">if</span> nativeMap <span class="hljs-keyword">and</span> obj.map <span class="hljs-keyword">is</span> nativeMap
results = []
_.each obj, <span class="hljs-function"><span class="hljs-params">(value, index, list)</span> -&gt;</span>
@@ -332,7 +332,7 @@ Handles objects implementing <strong>forEach</strong>, arrays, and raw objects.<
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">reduce</span> = <span class="hljs-params">(obj, iterator, memo, context)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.r<span class="hljs-function"><span class="hljs-title">educe</span> = <span class="hljs-params">(obj, iterator, memo, context)</span> -&gt;</span>
<span class="hljs-keyword">if</span> nativeReduce <span class="hljs-keyword">and</span> obj.reduce <span class="hljs-keyword">is</span> nativeReduce
iterator = _.bind iterator, context <span class="hljs-keyword">if</span> context
<span class="hljs-keyword">return</span> obj.reduce iterator, memo
@@ -354,7 +354,7 @@ JavaScript 1.8s version of <strong>reduceRight</strong>, if available.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">reduceRight</span> = <span class="hljs-params">(obj, iterator, memo, context)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.r<span class="hljs-function"><span class="hljs-title">educeRight</span> = <span class="hljs-params">(obj, iterator, memo, context)</span> -&gt;</span>
<span class="hljs-keyword">if</span> nativeReduceRight <span class="hljs-keyword">and</span> obj.reduceRight <span class="hljs-keyword">is</span> nativeReduceRight
iterator = _.bind iterator, context <span class="hljs-keyword">if</span> context
<span class="hljs-keyword">return</span> obj.reduceRight iterator, memo
@@ -374,7 +374,7 @@ JavaScript 1.8s version of <strong>reduceRight</strong>, if available.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">detect</span> = <span class="hljs-params">(obj, iterator, context)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.d<span class="hljs-function"><span class="hljs-title">etect</span> = <span class="hljs-params">(obj, iterator, context)</span> -&gt;</span>
result = <span class="hljs-literal">null</span>
_.each obj, <span class="hljs-function"><span class="hljs-params">(value, index, list)</span> -&gt;</span>
<span class="hljs-keyword">if</span> iterator.call context, value, index, list
@@ -396,7 +396,7 @@ JavaScript 1.8s version of <strong>reduceRight</strong>, if available.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">filter</span> = <span class="hljs-params">(obj, iterator, context)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.f<span class="hljs-function"><span class="hljs-title">ilter</span> = <span class="hljs-params">(obj, iterator, context)</span> -&gt;</span>
<span class="hljs-keyword">return</span> obj.filter iterator, context <span class="hljs-keyword">if</span> nativeFilter <span class="hljs-keyword">and</span> obj.filter <span class="hljs-keyword">is</span> nativeFilter
results = []
_.each obj, <span class="hljs-function"><span class="hljs-params">(value, index, list)</span> -&gt;</span>
@@ -416,7 +416,7 @@ JavaScript 1.8s version of <strong>reduceRight</strong>, if available.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">reject</span> = <span class="hljs-params">(obj, iterator, context)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.r<span class="hljs-function"><span class="hljs-title">eject</span> = <span class="hljs-params">(obj, iterator, context)</span> -&gt;</span>
results = []
_.each obj, <span class="hljs-function"><span class="hljs-params">(value, index, list)</span> -&gt;</span>
results.push value <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> iterator.call context, value, index, list
@@ -436,7 +436,7 @@ JavaScript 1.6s <strong>every</strong>, if it is present.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">every</span> = <span class="hljs-params">(obj, iterator, context)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.e<span class="hljs-function"><span class="hljs-title">very</span> = <span class="hljs-params">(obj, iterator, context)</span> -&gt;</span>
iterator ||= _.identity
<span class="hljs-keyword">return</span> obj.every iterator, context <span class="hljs-keyword">if</span> nativeEvery <span class="hljs-keyword">and</span> obj.every <span class="hljs-keyword">is</span> nativeEvery
result = <span class="hljs-literal">true</span>
@@ -458,7 +458,7 @@ JavaScript 1.6s <strong>some</strong>, if it exists.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">some</span> = <span class="hljs-params">(obj, iterator, context)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.s<span class="hljs-function"><span class="hljs-title">ome</span> = <span class="hljs-params">(obj, iterator, context)</span> -&gt;</span>
iterator ||= _.identity
<span class="hljs-keyword">return</span> obj.some iterator, context <span class="hljs-keyword">if</span> nativeSome <span class="hljs-keyword">and</span> obj.some <span class="hljs-keyword">is</span> nativeSome
result = <span class="hljs-literal">false</span>
@@ -480,7 +480,7 @@ based on <code>===</code>.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">include</span> = <span class="hljs-params">(obj, target)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.i<span class="hljs-function"><span class="hljs-title">nclude</span> = <span class="hljs-params">(obj, target)</span> -&gt;</span>
<span class="hljs-keyword">return</span> _.indexOf(obj, target) <span class="hljs-keyword">isnt</span> -<span class="hljs-number">1</span> <span class="hljs-keyword">if</span> nativeIndexOf <span class="hljs-keyword">and</span> obj.indexOf <span class="hljs-keyword">is</span> nativeIndexOf
<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span> <span class="hljs-keyword">for</span> own key, val <span class="hljs-keyword">of</span> obj <span class="hljs-keyword">when</span> val <span class="hljs-keyword">is</span> target
<span class="hljs-literal">false</span></pre></div></div>
@@ -498,7 +498,7 @@ based on <code>===</code>.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">invoke</span> = <span class="hljs-params">(obj, method)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.i<span class="hljs-function"><span class="hljs-title">nvoke</span> = <span class="hljs-params">(obj, method)</span> -&gt;</span>
args = _.rest arguments, <span class="hljs-number">2</span>
(<span class="hljs-keyword">if</span> method <span class="hljs-keyword">then</span> val[method] <span class="hljs-keyword">else</span> val).apply(val, args) <span class="hljs-keyword">for</span> val <span class="hljs-keyword">in</span> obj</pre></div></div>
@@ -515,11 +515,8 @@ based on <code>===</code>.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">pluck</span> = <span class="hljs-params">(obj, key)</span> -&gt;</span>
_.map<span class="hljs-function"><span class="hljs-params">(obj, (val) -&gt; val[key])</span>
</span></pre></div></div>
<div class="content"><div class='highlight'><pre>_.p<span class="hljs-function"><span class="hljs-title">luck</span> = <span class="hljs-params">(obj, key)</span> -&gt;</span>
_.map(obj, <span class="hljs-function"><span class="hljs-params">(val)</span> -&gt;</span> val[key])</pre></div></div>
</li>
@@ -534,7 +531,7 @@ based on <code>===</code>.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">max</span> = <span class="hljs-params">(obj, iterator, context)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.m<span class="hljs-function"><span class="hljs-title">ax</span> = <span class="hljs-params">(obj, iterator, context)</span> -&gt;</span>
<span class="hljs-keyword">return</span> Math.max.apply(Math, obj) <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> iterator <span class="hljs-keyword">and</span> _.isArray(obj)
result = <span class="hljs-attribute">computed</span>: -Infinity
_.each obj, <span class="hljs-function"><span class="hljs-params">(value, index, list)</span> -&gt;</span>
@@ -555,7 +552,7 @@ based on <code>===</code>.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">min</span> = <span class="hljs-params">(obj, iterator, context)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.m<span class="hljs-function"><span class="hljs-title">in</span> = <span class="hljs-params">(obj, iterator, context)</span> -&gt;</span>
<span class="hljs-keyword">return</span> Math.min.apply(Math, obj) <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> iterator <span class="hljs-keyword">and</span> _.isArray(obj)
result = <span class="hljs-attribute">computed</span>: Infinity
_.each obj, <span class="hljs-function"><span class="hljs-params">(value, index, list)</span> -&gt;</span>
@@ -576,16 +573,13 @@ based on <code>===</code>.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">sortBy</span> = <span class="hljs-params">(obj, iterator, context)</span> -&gt;</span>
_.pluck<span class="hljs-function"><span class="hljs-params">(((_.map obj, (value, index, list) -&gt;
<div class="content"><div class='highlight'><pre>_.s<span class="hljs-function"><span class="hljs-title">ortBy</span> = <span class="hljs-params">(obj, iterator, context)</span> -&gt;</span>
_.pluck(<span class="hljs-function">(<span class="hljs-params">(_.map obj, (value, index, list) -&gt;
{value: value, criteria: iterator.call(context, value, index, list)}
).sort((left, right) -&gt;
)</span>.<span class="hljs-title">sort</span>(<span class="hljs-params">(left, right)</span> -&gt;</span>
a = left.criteria; b = right.criteria
<span class="hljs-keyword">if</span> a &lt; b <span class="hljs-keyword">then</span> -<span class="hljs-number">1</span> <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> a &gt; b <span class="hljs-keyword">then</span> <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> <span class="hljs-number">0</span>
)), <span class="hljs-string">'value'</span>)</span>
</span></pre></div></div>
)), <span class="hljs-string">'value'</span>)</pre></div></div>
</li>
@@ -601,7 +595,7 @@ be inserted so as to maintain order. Uses binary search.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">sortedIndex</span> = <span class="hljs-params">(array, obj, iterator)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.s<span class="hljs-function"><span class="hljs-title">ortedIndex</span> = <span class="hljs-params">(array, obj, iterator)</span> -&gt;</span>
iterator ||= _.identity
low = <span class="hljs-number">0</span>
high = array.length
@@ -623,7 +617,7 @@ be inserted so as to maintain order. Uses binary search.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">toArray</span> = <span class="hljs-params">(iterable)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.t<span class="hljs-function"><span class="hljs-title">oArray</span> = <span class="hljs-params">(iterable)</span> -&gt;</span>
<span class="hljs-keyword">return</span> [] <span class="hljs-keyword">if</span> (!iterable)
<span class="hljs-keyword">return</span> iterable.toArray() <span class="hljs-keyword">if</span> (iterable.toArray)
<span class="hljs-keyword">return</span> iterable <span class="hljs-keyword">if</span> (_.isArray(iterable))
@@ -643,7 +637,7 @@ be inserted so as to maintain order. Uses binary search.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">size</span> = <span class="hljs-params">(obj)</span> -&gt;</span> _.toArray(obj).length</pre></div></div>
<div class="content"><div class='highlight'><pre>_.s<span class="hljs-function"><span class="hljs-title">ize</span> = <span class="hljs-params">(obj)</span> -&gt;</span> _.toArray(obj).length</pre></div></div>
</li>
@@ -685,7 +679,7 @@ with <strong>map</strong>.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">first</span> = <span class="hljs-params">(array, n, guard)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.f<span class="hljs-function"><span class="hljs-title">irst</span> = <span class="hljs-params">(array, n, guard)</span> -&gt;</span>
<span class="hljs-keyword">if</span> n <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> guard <span class="hljs-keyword">then</span> slice.call(array, <span class="hljs-number">0</span>, n) <span class="hljs-keyword">else</span> array[<span class="hljs-number">0</span>]</pre></div></div>
</li>
@@ -704,7 +698,7 @@ check allows it to work with <strong>map</strong>.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">rest</span> = <span class="hljs-params">(array, index, guard)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.r<span class="hljs-function"><span class="hljs-title">est</span> = <span class="hljs-params">(array, index, guard)</span> -&gt;</span>
slice.call(array, <span class="hljs-keyword">if</span> _.isUndefined(index) <span class="hljs-keyword">or</span> guard <span class="hljs-keyword">then</span> <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> index)</pre></div></div>
</li>
@@ -720,7 +714,7 @@ check allows it to work with <strong>map</strong>.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">last</span> = <span class="hljs-params">(array)</span> -&gt;</span> array[array.length - <span class="hljs-number">1</span>]</pre></div></div>
<div class="content"><div class='highlight'><pre>_.l<span class="hljs-function"><span class="hljs-title">ast</span> = <span class="hljs-params">(array)</span> -&gt;</span> array[array.length - <span class="hljs-number">1</span>]</pre></div></div>
</li>
@@ -735,7 +729,7 @@ check allows it to work with <strong>map</strong>.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">compact</span> = <span class="hljs-params">(array)</span> -&gt;</span> item <span class="hljs-keyword">for</span> item <span class="hljs-keyword">in</span> array <span class="hljs-keyword">when</span> item</pre></div></div>
<div class="content"><div class='highlight'><pre>_.c<span class="hljs-function"><span class="hljs-title">ompact</span> = <span class="hljs-params">(array)</span> -&gt;</span> item <span class="hljs-keyword">for</span> item <span class="hljs-keyword">in</span> array <span class="hljs-keyword">when</span> item</pre></div></div>
</li>
@@ -750,7 +744,7 @@ check allows it to work with <strong>map</strong>.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">flatten</span> = <span class="hljs-params">(array)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.f<span class="hljs-function"><span class="hljs-title">latten</span> = <span class="hljs-params">(array)</span> -&gt;</span>
_.reduce array, <span class="hljs-function"><span class="hljs-params">(memo, value)</span> -&gt;</span>
<span class="hljs-keyword">return</span> memo.concat(_.flatten(value)) <span class="hljs-keyword">if</span> _.isArray value
memo.push value
@@ -770,7 +764,7 @@ check allows it to work with <strong>map</strong>.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">without</span> = <span class="hljs-params">(array)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.w<span class="hljs-function"><span class="hljs-title">ithout</span> = <span class="hljs-params">(array)</span> -&gt;</span>
values = _.rest arguments
val <span class="hljs-keyword">for</span> val <span class="hljs-keyword">in</span> _.toArray(array) <span class="hljs-keyword">when</span> <span class="hljs-keyword">not</span> _.include values, val</pre></div></div>
@@ -788,7 +782,7 @@ been sorted, you have the option of using a faster algorithm.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">uniq</span> = <span class="hljs-params">(array, isSorted)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.u<span class="hljs-function"><span class="hljs-title">niq</span> = <span class="hljs-params">(array, isSorted)</span> -&gt;</span>
memo = []
<span class="hljs-keyword">for</span> el, i <span class="hljs-keyword">in</span> _.toArray array
memo.push el <span class="hljs-keyword">if</span> i <span class="hljs-keyword">is</span> <span class="hljs-number">0</span> || (<span class="hljs-keyword">if</span> isSorted <span class="hljs-keyword">is</span> <span class="hljs-literal">true</span> <span class="hljs-keyword">then</span> _.last(memo) <span class="hljs-keyword">isnt</span> el <span class="hljs-keyword">else</span> <span class="hljs-keyword">not</span> _.include(memo, el))
@@ -808,9 +802,9 @@ passed-in arrays.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">intersect</span> = <span class="hljs-params">(array)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.i<span class="hljs-function"><span class="hljs-title">ntersect</span> = <span class="hljs-params">(array)</span> -&gt;</span>
rest = _.rest arguments
_.select _.uniq<span class="hljs-function"><span class="hljs-params">(array)</span>, <span class="hljs-params">(item)</span> -&gt;</span>
_.select _.uniq(array), <span class="hljs-function"><span class="hljs-params">(item)</span> -&gt;</span>
_.all rest, <span class="hljs-function"><span class="hljs-params">(other)</span> -&gt;</span>
_.indexOf(other, item) &gt;= <span class="hljs-number">0</span></pre></div></div>
@@ -828,7 +822,7 @@ an index go together.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">zip</span> = -&gt;</span>
<div class="content"><div class='highlight'><pre>_.z<span class="hljs-function"><span class="hljs-title">ip</span> = -&gt;</span>
length = _.max _.pluck arguments, <span class="hljs-string">'length'</span>
results = <span class="hljs-keyword">new</span> Array length
<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> [<span class="hljs-number">0.</span>..length]
@@ -850,7 +844,7 @@ item in an array, or -1 if the item is not included in the array.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">indexOf</span> = <span class="hljs-params">(array, item)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.i<span class="hljs-function"><span class="hljs-title">ndexOf</span> = <span class="hljs-params">(array, item)</span> -&gt;</span>
<span class="hljs-keyword">return</span> array.indexOf item <span class="hljs-keyword">if</span> nativeIndexOf <span class="hljs-keyword">and</span> array.indexOf <span class="hljs-keyword">is</span> nativeIndexOf
i = <span class="hljs-number">0</span>; l = array.length
<span class="hljs-keyword">while</span> l - i
@@ -871,7 +865,7 @@ if possible.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">lastIndexOf</span> = <span class="hljs-params">(array, item)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.l<span class="hljs-function"><span class="hljs-title">astIndexOf</span> = <span class="hljs-params">(array, item)</span> -&gt;</span>
<span class="hljs-keyword">return</span> array.lastIndexOf(item) <span class="hljs-keyword">if</span> nativeLastIndexOf <span class="hljs-keyword">and</span> array.lastIndexOf <span class="hljs-keyword">is</span> nativeLastIndexOf
i = array.length
<span class="hljs-keyword">while</span> i
@@ -892,7 +886,7 @@ if possible.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">range</span> = <span class="hljs-params">(start, stop, step)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.r<span class="hljs-function"><span class="hljs-title">ange</span> = <span class="hljs-params">(start, stop, step)</span> -&gt;</span>
a = arguments
solo = a.length &lt;= <span class="hljs-number">1</span>
i = start = <span class="hljs-keyword">if</span> solo <span class="hljs-keyword">then</span> <span class="hljs-number">0</span> <span class="hljs-keyword">else</span> a[<span class="hljs-number">0</span>]
@@ -947,9 +941,9 @@ optionally). Binding with arguments is also known as <strong>curry</strong>.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">bind</span> = <span class="hljs-params">(func, obj)</span> -&gt;</span>
args = _.rest arguments, <span class="hljs-number">2</span><span class="hljs-function">
-&gt;</span> func.apply obj <span class="hljs-keyword">or</span> root, args.concat arguments</pre></div></div>
<div class="content"><div class='highlight'><pre>_.b<span class="hljs-function"><span class="hljs-title">ind</span> = <span class="hljs-params">(func, obj)</span> -&gt;</span>
args = _.rest arguments, <span class="hljs-number">2</span>
<span class="hljs-function"> -&gt;</span> func.apply obj <span class="hljs-keyword">or</span> root, args.concat arguments</pre></div></div>
</li>
@@ -965,7 +959,7 @@ all callbacks defined on an object belong to it.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">bindAll</span> = <span class="hljs-params">(obj)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.b<span class="hljs-function"><span class="hljs-title">indAll</span> = <span class="hljs-params">(obj)</span> -&gt;</span>
funcs = <span class="hljs-keyword">if</span> arguments.length &gt; <span class="hljs-number">1</span> <span class="hljs-keyword">then</span> _.rest(arguments) <span class="hljs-keyword">else</span> _.functions(obj)
_.each funcs, <span class="hljs-function"><span class="hljs-params">(f)</span> -&gt;</span> obj[f] = _.bind obj[f], obj
obj</pre></div></div>
@@ -984,7 +978,7 @@ it with the arguments supplied.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">delay</span> = <span class="hljs-params">(func, wait)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.d<span class="hljs-function"><span class="hljs-title">elay</span> = <span class="hljs-params">(func, wait)</span> -&gt;</span>
args = _.rest arguments, <span class="hljs-number">2</span>
setTimeout((<span class="hljs-function">-&gt;</span> func.apply(func, args)), wait)</pre></div></div>
@@ -1001,10 +995,10 @@ it with the arguments supplied.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">memoize</span> = <span class="hljs-params">(func, hasher)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.m<span class="hljs-function"><span class="hljs-title">emoize</span> = <span class="hljs-params">(func, hasher)</span> -&gt;</span>
memo = {}
hasher <span class="hljs-keyword">or</span>= _.identity<span class="hljs-function">
-&gt;</span>
hasher <span class="hljs-keyword">or</span>= _.identity
<span class="hljs-function"> -&gt;</span>
key = hasher.apply <span class="hljs-keyword">this</span>, arguments
<span class="hljs-keyword">return</span> memo[key] <span class="hljs-keyword">if</span> key <span class="hljs-keyword">of</span> memo
memo[key] = func.apply <span class="hljs-keyword">this</span>, arguments</pre></div></div>
@@ -1023,7 +1017,7 @@ cleared.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">defer</span> = <span class="hljs-params">(func)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.d<span class="hljs-function"><span class="hljs-title">efer</span> = <span class="hljs-params">(func)</span> -&gt;</span>
_.delay.apply _, [func, <span class="hljs-number">1</span>].concat _.rest arguments</pre></div></div>
</li>
@@ -1041,7 +1035,7 @@ conditionally execute the original function.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">wrap</span> = <span class="hljs-params">(func, wrapper)</span> -&gt;</span><span class="hljs-function">
<div class="content"><div class='highlight'><pre>_.w<span class="hljs-function"><span class="hljs-title">rap</span> = <span class="hljs-params">(func, wrapper)</span> -&gt;</span><span class="hljs-function">
-&gt;</span> wrapper.apply wrapper, [func].concat arguments</pre></div></div>
</li>
@@ -1058,9 +1052,9 @@ consuming the return value of the function that follows.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">compose</span> = -&gt;</span>
funcs = arguments<span class="hljs-function">
-&gt;</span>
<div class="content"><div class='highlight'><pre>_.c<span class="hljs-function"><span class="hljs-title">ompose</span> = -&gt;</span>
funcs = arguments
<span class="hljs-function"> -&gt;</span>
args = arguments
<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> [funcs.length - <span class="hljs-number">1.</span><span class="hljs-number">.0</span>] <span class="hljs-keyword">by</span> -<span class="hljs-number">1</span>
args = [funcs[i].apply(<span class="hljs-keyword">this</span>, args)]
@@ -1121,7 +1115,7 @@ consuming the return value of the function that follows.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">values</span> = <span class="hljs-params">(obj)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.v<span class="hljs-function"><span class="hljs-title">alues</span> = <span class="hljs-params">(obj)</span> -&gt;</span>
_.map obj, _.identity</pre></div></div>
</li>
@@ -1137,11 +1131,8 @@ consuming the return value of the function that follows.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">functions</span> = <span class="hljs-params">(obj)</span> -&gt;</span>
_.filter<span class="hljs-function"><span class="hljs-params">(_.keys(obj), (key) -&gt; _.isFunction(obj[key]))</span>.<span class="hljs-title">sort</span><span class="hljs-params">()</span>
</span></pre></div></div>
<div class="content"><div class='highlight'><pre>_.f<span class="hljs-function"><span class="hljs-title">unctions</span> = <span class="hljs-params">(obj)</span> -&gt;</span>
_.filter(_.keys(obj), <span class="hljs-function"><span class="hljs-params">(key)</span> -&gt;</span> _.isFunction(obj[key])).sort()</pre></div></div>
</li>
@@ -1156,7 +1147,7 @@ consuming the return value of the function that follows.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">extend</span> = <span class="hljs-params">(obj)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.e<span class="hljs-function"><span class="hljs-title">xtend</span> = <span class="hljs-params">(obj)</span> -&gt;</span>
<span class="hljs-keyword">for</span> source <span class="hljs-keyword">in</span> _.rest(arguments)
obj[key] = val <span class="hljs-keyword">for</span> key, val <span class="hljs-keyword">of</span> source
obj</pre></div></div>
@@ -1174,7 +1165,7 @@ consuming the return value of the function that follows.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">clone</span> = <span class="hljs-params">(obj)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.c<span class="hljs-function"><span class="hljs-title">lone</span> = <span class="hljs-params">(obj)</span> -&gt;</span>
<span class="hljs-keyword">return</span> obj.slice <span class="hljs-number">0</span> <span class="hljs-keyword">if</span> _.isArray obj
_.extend {}, obj</pre></div></div>
@@ -1192,7 +1183,7 @@ The primary purpose of this method is to “tap into” a method chain, in order
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">tap</span> = <span class="hljs-params">(obj, interceptor)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.t<span class="hljs-function"><span class="hljs-title">ap</span> = <span class="hljs-params">(obj, interceptor)</span> -&gt;</span>
interceptor obj
obj</pre></div></div>
@@ -1209,7 +1200,7 @@ The primary purpose of this method is to “tap into” a method chain, in order
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">isEqual</span> = <span class="hljs-params">(a, b)</span> -&gt;</span></pre></div></div>
<div class="content"><div class='highlight'><pre>_.i<span class="hljs-function"><span class="hljs-title">sEqual</span> = <span class="hljs-params">(a, b)</span> -&gt;</span></pre></div></div>
</li>
@@ -1425,7 +1416,7 @@ The primary purpose of this method is to “tap into” a method chain, in order
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">isEmpty</span> = <span class="hljs-params">(obj)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.i<span class="hljs-function"><span class="hljs-title">sEmpty</span> = <span class="hljs-params">(obj)</span> -&gt;</span>
<span class="hljs-keyword">return</span> obj.length <span class="hljs-keyword">is</span> <span class="hljs-number">0</span> <span class="hljs-keyword">if</span> _.isArray(obj) <span class="hljs-keyword">or</span> _.isString(obj)
<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span> <span class="hljs-keyword">for</span> own key <span class="hljs-keyword">of</span> obj
<span class="hljs-literal">true</span></pre></div></div>
@@ -1443,7 +1434,7 @@ The primary purpose of this method is to “tap into” a method chain, in order
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">isElement</span> = <span class="hljs-params">(obj)</span> -&gt;</span> obj <span class="hljs-keyword">and</span> obj.nodeType <span class="hljs-keyword">is</span> <span class="hljs-number">1</span></pre></div></div>
<div class="content"><div class='highlight'><pre>_.i<span class="hljs-function"><span class="hljs-title">sElement</span> = <span class="hljs-params">(obj)</span> -&gt;</span> obj <span class="hljs-keyword">and</span> obj.nodeType <span class="hljs-keyword">is</span> <span class="hljs-number">1</span></pre></div></div>
</li>
@@ -1473,7 +1464,7 @@ The primary purpose of this method is to “tap into” a method chain, in order
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">isArguments</span> = <span class="hljs-params">(obj)</span> -&gt;</span> obj <span class="hljs-keyword">and</span> obj.callee</pre></div></div>
<div class="content"><div class='highlight'><pre>_.i<span class="hljs-function"><span class="hljs-title">sArguments</span> = <span class="hljs-params">(obj)</span> -&gt;</span> obj <span class="hljs-keyword">and</span> obj.callee</pre></div></div>
</li>
@@ -1488,7 +1479,7 @@ The primary purpose of this method is to “tap into” a method chain, in order
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">isFunction</span> = <span class="hljs-params">(obj)</span> -&gt;</span> !!(obj <span class="hljs-keyword">and</span> obj.constructor <span class="hljs-keyword">and</span> obj.call <span class="hljs-keyword">and</span> obj.apply)</pre></div></div>
<div class="content"><div class='highlight'><pre>_.i<span class="hljs-function"><span class="hljs-title">sFunction</span> = <span class="hljs-params">(obj)</span> -&gt;</span> !!(obj <span class="hljs-keyword">and</span> obj.constructor <span class="hljs-keyword">and</span> obj.call <span class="hljs-keyword">and</span> obj.apply)</pre></div></div>
</li>
@@ -1503,7 +1494,7 @@ The primary purpose of this method is to “tap into” a method chain, in order
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">isString</span> = <span class="hljs-params">(obj)</span> -&gt;</span> !!(obj <span class="hljs-keyword">is</span> <span class="hljs-string">''</span> <span class="hljs-keyword">or</span> (obj <span class="hljs-keyword">and</span> obj.charCodeAt <span class="hljs-keyword">and</span> obj.substr))</pre></div></div>
<div class="content"><div class='highlight'><pre>_.i<span class="hljs-function"><span class="hljs-title">sString</span> = <span class="hljs-params">(obj)</span> -&gt;</span> !!(obj <span class="hljs-keyword">is</span> <span class="hljs-string">''</span> <span class="hljs-keyword">or</span> (obj <span class="hljs-keyword">and</span> obj.charCodeAt <span class="hljs-keyword">and</span> obj.substr))</pre></div></div>
</li>
@@ -1518,7 +1509,7 @@ The primary purpose of this method is to “tap into” a method chain, in order
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">isNumber</span> = <span class="hljs-params">(obj)</span> -&gt;</span> (obj <span class="hljs-keyword">is</span> +obj) <span class="hljs-keyword">or</span> toString.call(obj) <span class="hljs-keyword">is</span> <span class="hljs-string">'[object Number]'</span></pre></div></div>
<div class="content"><div class='highlight'><pre>_.i<span class="hljs-function"><span class="hljs-title">sNumber</span> = <span class="hljs-params">(obj)</span> -&gt;</span> (obj <span class="hljs-keyword">is</span> +obj) <span class="hljs-keyword">or</span> toString.call(obj) <span class="hljs-keyword">is</span> <span class="hljs-string">'[object Number]'</span></pre></div></div>
</li>
@@ -1533,7 +1524,7 @@ The primary purpose of this method is to “tap into” a method chain, in order
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">isBoolean</span> = <span class="hljs-params">(obj)</span> -&gt;</span> obj <span class="hljs-keyword">is</span> <span class="hljs-literal">true</span> <span class="hljs-keyword">or</span> obj <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span></pre></div></div>
<div class="content"><div class='highlight'><pre>_.i<span class="hljs-function"><span class="hljs-title">sBoolean</span> = <span class="hljs-params">(obj)</span> -&gt;</span> obj <span class="hljs-keyword">is</span> <span class="hljs-literal">true</span> <span class="hljs-keyword">or</span> obj <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span></pre></div></div>
</li>
@@ -1548,7 +1539,7 @@ The primary purpose of this method is to “tap into” a method chain, in order
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">isDate</span> = <span class="hljs-params">(obj)</span> -&gt;</span> !!(obj <span class="hljs-keyword">and</span> obj.getTimezoneOffset <span class="hljs-keyword">and</span> obj.setUTCFullYear)</pre></div></div>
<div class="content"><div class='highlight'><pre>_.i<span class="hljs-function"><span class="hljs-title">sDate</span> = <span class="hljs-params">(obj)</span> -&gt;</span> !!(obj <span class="hljs-keyword">and</span> obj.getTimezoneOffset <span class="hljs-keyword">and</span> obj.setUTCFullYear)</pre></div></div>
</li>
@@ -1563,7 +1554,7 @@ The primary purpose of this method is to “tap into” a method chain, in order
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">isRegExp</span> = <span class="hljs-params">(obj)</span> -&gt;</span> !!(obj <span class="hljs-keyword">and</span> obj.exec <span class="hljs-keyword">and</span> (obj.ignoreCase <span class="hljs-keyword">or</span> obj.ignoreCase <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>))</pre></div></div>
<div class="content"><div class='highlight'><pre>_.i<span class="hljs-function"><span class="hljs-title">sRegExp</span> = <span class="hljs-params">(obj)</span> -&gt;</span> !!(obj <span class="hljs-keyword">and</span> obj.exec <span class="hljs-keyword">and</span> (obj.ignoreCase <span class="hljs-keyword">or</span> obj.ignoreCase <span class="hljs-keyword">is</span> <span class="hljs-literal">false</span>))</pre></div></div>
</li>
@@ -1579,7 +1570,7 @@ The primary purpose of this method is to “tap into” a method chain, in order
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">isNaN</span> = <span class="hljs-params">(obj)</span> -&gt;</span> _.isNumber(obj) <span class="hljs-keyword">and</span> <span class="hljs-built_in">window</span>.isNaN(obj)</pre></div></div>
<div class="content"><div class='highlight'><pre>_.i<span class="hljs-function"><span class="hljs-title">sNaN</span> = <span class="hljs-params">(obj)</span> -&gt;</span> _.isNumber(obj) <span class="hljs-keyword">and</span> <span class="hljs-built_in">window</span>.isNaN(obj)</pre></div></div>
</li>
@@ -1594,7 +1585,7 @@ The primary purpose of this method is to “tap into” a method chain, in order
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">isNull</span> = <span class="hljs-params">(obj)</span> -&gt;</span> obj <span class="hljs-keyword">is</span> <span class="hljs-literal">null</span></pre></div></div>
<div class="content"><div class='highlight'><pre>_.i<span class="hljs-function"><span class="hljs-title">sNull</span> = <span class="hljs-params">(obj)</span> -&gt;</span> obj <span class="hljs-keyword">is</span> <span class="hljs-literal">null</span></pre></div></div>
</li>
@@ -1609,7 +1600,7 @@ The primary purpose of this method is to “tap into” a method chain, in order
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">isUndefined</span> = <span class="hljs-params">(obj)</span> -&gt;</span> <span class="hljs-keyword">typeof</span> obj <span class="hljs-keyword">is</span> <span class="hljs-string">'undefined'</span></pre></div></div>
<div class="content"><div class='highlight'><pre>_.i<span class="hljs-function"><span class="hljs-title">sUndefined</span> = <span class="hljs-params">(obj)</span> -&gt;</span> <span class="hljs-keyword">typeof</span> obj <span class="hljs-keyword">is</span> <span class="hljs-string">'undefined'</span></pre></div></div>
</li>
@@ -1650,7 +1641,7 @@ previous owner. Returns a reference to the Underscore object.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">noConflict</span> = -&gt;</span>
<div class="content"><div class='highlight'><pre>_.n<span class="hljs-function"><span class="hljs-title">oConflict</span> = -&gt;</span>
root._ = previousUnderscore
<span class="hljs-keyword">this</span></pre></div></div>
@@ -1667,7 +1658,7 @@ previous owner. Returns a reference to the Underscore object.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">identity</span> = <span class="hljs-params">(value)</span> -&gt;</span> value</pre></div></div>
<div class="content"><div class='highlight'><pre>_.i<span class="hljs-function"><span class="hljs-title">dentity</span> = <span class="hljs-params">(value)</span> -&gt;</span> value</pre></div></div>
</li>
@@ -1682,7 +1673,7 @@ previous owner. Returns a reference to the Underscore object.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">times</span> = <span class="hljs-params">(n, iterator, context)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.t<span class="hljs-function"><span class="hljs-title">imes</span> = <span class="hljs-params">(n, iterator, context)</span> -&gt;</span>
iterator.call context, i <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> [<span class="hljs-number">0.</span>..n]</pre></div></div>
</li>
@@ -1698,7 +1689,7 @@ previous owner. Returns a reference to the Underscore object.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">breakLoop</span> = -&gt;</span> <span class="hljs-keyword">throw</span> breaker</pre></div></div>
<div class="content"><div class='highlight'><pre>_.b<span class="hljs-function"><span class="hljs-title">reakLoop</span> = -&gt;</span> <span class="hljs-keyword">throw</span> breaker</pre></div></div>
</li>
@@ -1714,7 +1705,7 @@ theyre correctly added to the OOP wrapper as well.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">mixin</span> = <span class="hljs-params">(obj)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.m<span class="hljs-function"><span class="hljs-title">ixin</span> = <span class="hljs-params">(obj)</span> -&gt;</span>
<span class="hljs-keyword">for</span> name <span class="hljs-keyword">in</span> _.functions(obj)
addToWrapper name, _[name] = obj[name]</pre></div></div>
@@ -1733,7 +1724,7 @@ Useful for temporary DOM ids.</p>
</div>
<div class="content"><div class='highlight'><pre>idCounter = <span class="hljs-number">0</span>
_.<span class="hljs-function"><span class="hljs-title">uniqueId</span> = <span class="hljs-params">(prefix)</span> -&gt;</span>
_.u<span class="hljs-function"><span class="hljs-title">niqueId</span> = <span class="hljs-params">(prefix)</span> -&gt;</span>
(prefix <span class="hljs-keyword">or</span> <span class="hljs-string">''</span>) + idCounter++</pre></div></div>
</li>
@@ -1772,7 +1763,7 @@ With alterations for arbitrary delimiters, and to preserve whitespace.</p>
</div>
<div class="content"><div class='highlight'><pre>_.<span class="hljs-function"><span class="hljs-title">template</span> = <span class="hljs-params">(str, data)</span> -&gt;</span>
<div class="content"><div class='highlight'><pre>_.t<span class="hljs-function"><span class="hljs-title">emplate</span> = <span class="hljs-params">(str, data)</span> -&gt;</span>
c = _.templateSettings
endMatch = <span class="hljs-keyword">new</span> RegExp(<span class="hljs-string">"'(?=[^"</span>+c.end.substr(<span class="hljs-number">0</span>, <span class="hljs-number">1</span>)+<span class="hljs-string">"]*"</span>+escapeRegExp(c.end)+<span class="hljs-string">")"</span>,<span class="hljs-string">"g"</span>)
fn = <span class="hljs-keyword">new</span> Function <span class="hljs-string">'obj'</span>,
@@ -1971,7 +1962,7 @@ underscore functions. Wrapped objects may be chained.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-attribute">wrapper</span>::<span class="hljs-function"><span class="hljs-title">chain</span> = -&gt;</span>
<div class="content"><div class='highlight'><pre><span class="hljs-attribute">wrapper</span>::c<span class="hljs-function"><span class="hljs-title">hain</span> = -&gt;</span>
<span class="hljs-keyword">this</span>._chain = <span class="hljs-literal">true</span>
<span class="hljs-keyword">this</span></pre></div></div>
@@ -1988,7 +1979,7 @@ underscore functions. Wrapped objects may be chained.</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-attribute">wrapper</span>::<span class="hljs-function"><span class="hljs-title">value</span> = -&gt;</span> <span class="hljs-keyword">this</span>._wrapped</pre></div></div>
<div class="content"><div class='highlight'><pre><span class="hljs-attribute">wrapper</span>::v<span class="hljs-function"><span class="hljs-title">alue</span> = -&gt;</span> <span class="hljs-keyword">this</span>._wrapped</pre></div></div>
</li>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="-76 212 458 369" enable-background="new -76 212 458 369" xml:space="preserve">
<title>CoffeeScript Logo</title>
<g>
<g>
<path fill="#28334C" d="M106,228.6c0.5,2.3-0.9,4.4-5,6.5c-5.5-3.1-16.9-4.4-26.7-3.5c-10.4,0.9-19.4,4.2-17.9,11.3
c1.5,7.1,11.7,11,29.5,9.5c43.6-3.8,43.4-33.3,107.4-39c49.8-4.4,77.8,11,81.8,29.7c3.1,14.7-9.1,28.6-45.2,31.8
c-32,2.8-50.7-5.6-52.6-14.6c-1-4.5,1.8-11.3,17.2-13.1c1.5,7,10.6,14.4,31.1,12.6c14.8-1.3,27.6-6.6,25.9-14.9
c-1.8-8.6-17.7-13.7-42.6-11.5c-50.7,4.5-63.2,32.5-106.8,36.3c-30.8,2.7-55.9-8.5-59.4-25.1c-1.3-6.1-1.4-21,31.2-23.9
C91,219.2,104.6,222.2,106,228.6L106,228.6z M-56.4,402.5c-14.3,18-20.4,38.8-19.2,59.2c1.2,20.4,11.4,37.1,26.9,50.2
C-32,525-14,528.6,6.4,525c7.8-1.2,16.7-5.3,24.5-7.8c-16.7,0-31-5.3-44.9-16.7c-15.5-11.4-25.7-26.9-28.2-46.1
c-3.7-18,0-34.7,10.2-49c11.4-14.3,25.7-22,44.9-24.5c19.2-1.2,35.9,3.7,52.6,15.5c-3.7-5.3-9-9-14.3-14.3
c-16.7-11.4-34.7-16.7-56.7-11.4C-25.4,374.3-42.2,384.5-56.4,402.5z M167.2,306.2c-53.9,0-101.6-5.3-136.3-13.1
c-37.1-9-56.7-19.2-56.7-32.2c0-5.3,2.4-10.2,10.2-15.5c-23.3,9-35.9,16.7-35.9,28.2c1.2,13.1,22,25.7,64.5,35.9
c40,10.2,91.4,15.5,153,15.5c62.8,0,113-5.3,153-15.5c42.4-10.2,62.8-23.3,62.8-35.9c0-9-9-18-25.7-24.5c3.7,2.4,6.5,6.5,6.5,11.4
c0,13.1-19.2,23.3-57.9,32.2C268.7,300.9,222.6,306.2,167.2,306.2L167.2,306.2z M320.2,342.1c-40,9-91.4,15.5-153,15.5
c-62.8,0-114.2-6.5-154.2-15.5c-35.9-9-55.1-19.2-61.6-29.4c6.5,44.9,22,87.3,42.4,124.8c15.5,23.3,31,43.7,46.1,65.7
c6.5,13.1,11.4,25.7,14.3,38.8c10.2,14.3,24.5,23.3,42.4,28.2c22,7.8,44.9,11.4,68.1,10.2h2.4c23.3,1.2,47.7-2.4,70.6-10.2
c16.7-5.3,31-14.3,41.2-28.2h1.2c2.4-13.1,6.5-25.7,13.1-38.8c15.5-22,31-42.4,46.1-65.7c20.4-37.1,34.7-79.6,42.4-124.8
C374,324.1,354.8,334.3,320.2,342.1L320.2,342.1z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="-22 347 566 100" enable-background="new -22 347 566 100" xml:space="preserve">
<title>CoffeeScript Logo</title>
<g>
<g>
<path id="Shape" fill="#28334C" d="M21.7,351.1c0.1,0.6-0.2,1.1-1.2,1.6c-1.3-0.7-4.1-1.1-6.4-0.9c-2.5,0.2-4.6,1-4.3,2.7
c0.4,1.7,2.8,2.7,7.1,2.3c10.5-0.9,10.4-8,25.8-9.4c12-1.1,18.7,2.6,19.6,7.1c0.7,3.5-2.2,6.9-10.9,7.6
c-7.7,0.7-12.2-1.4-12.6-3.5c-0.2-1.1,0.4-2.7,4.1-3.1c0.4,1.7,2.5,3.5,7.5,3c3.6-0.3,6.6-1.6,6.2-3.6c-0.4-2.1-4.2-3.3-10.2-2.8
c-12.2,1.1-15.2,7.8-25.6,8.7c-7.4,0.7-13.4-2-14.2-6c-0.3-1.5-0.3-5,7.5-5.7C18.1,348.8,21.3,349.5,21.7,351.1z M-17.3,392.9
c-3.4,4.3-4.9,9.3-4.6,14.2c0.3,4.9,2.7,8.9,6.5,12c4,3.1,8.3,4,13.2,3.1c1.9-0.3,4-1.3,5.9-1.9c-4,0-7.4-1.3-10.8-4
c-3.7-2.7-6.2-6.5-6.8-11.1c-0.9-4.3,0-8.3,2.4-11.8c2.7-3.4,6.2-5.3,10.8-5.9c4.6-0.3,8.6,0.9,12.6,3.7c-0.9-1.3-2.2-2.2-3.4-3.4
c-4-2.7-8.3-4-13.6-2.7C-9.9,386.1-13.9,388.6-17.3,392.9z M36.3,369.8c-12.9,0-24.4-1.3-32.7-3.1c-8.9-2.2-13.6-4.6-13.6-7.7
c0-1.3,0.6-2.4,2.4-3.7c-5.6,2.2-8.6,4-8.6,6.8c0.3,3.1,5.3,6.2,15.5,8.6c9.6,2.4,21.9,3.7,36.7,3.7c15.1,0,27.1-1.3,36.7-3.7
c10.2-2.4,15.1-5.6,15.1-8.6c0-2.2-2.2-4.3-6.2-5.9c0.9,0.6,1.6,1.6,1.6,2.7c0,3.1-4.6,5.6-13.9,7.7
C60.7,368.5,49.7,369.8,36.3,369.8z M73.1,378.4c-9.6,2.2-21.9,3.7-36.7,3.7c-15.1,0-27.4-1.6-37-3.7c-8.6-2.2-13.2-4.6-14.8-7.1
c1.6,10.8,5.3,21,10.2,30c3.7,5.6,7.4,10.5,11.1,15.8c1.6,3.1,2.7,6.2,3.4,9.3c2.4,3.4,5.9,5.6,10.2,6.8
c5.3,1.9,10.8,2.7,16.4,2.4h0.6c5.6,0.3,11.5-0.6,16.9-2.4c4-1.3,7.4-3.4,9.9-6.8h0.3c0.6-3.1,1.6-6.2,3.1-9.3
c3.7-5.3,7.4-10.2,11.1-15.8c4.9-8.9,8.3-19.1,10.2-30C86,374.1,81.4,376.5,73.1,378.4z"/>
<g>
<path fill="#28334C" d="M179.3,408.5c-4.8,12.1-17.6,16.9-25.9,16.9c-13.4,0-19.9-6-19.9-22.3c0-16.5,7.9-47.3,31.7-47.3
c8.5,0,15.2,3.3,15.2,12.1c0,4.8-1.8,8.3-6.4,8.3c-1.5,0-3.4-0.4-5.2-2.4c2.2-1.1,4.2-4.9,4.2-8.3c0-2.9-1.5-5.6-5.6-5.6
c-10,0-18.9,23.9-18.9,42.4c0,8.3,2.2,14.2,10.9,14.2c7.1,0,13.5-3.4,17.7-9.1L179.3,408.5z M212.2,392.2c0.4,0.2,0.7,0.2,1,0.2
c4.2,0,10.1-2.7,14-5.5l0.8,2.4c-3.4,3.7-9.5,6.5-16.1,7.5c-1.5,16.8-10.6,27.3-21.7,27.3c-8.4,0-14.5-4-14.5-14.4
c0-10.5,6.2-32.2,24.9-32.2C208.4,377.8,212.2,382.8,212.2,392.2z M204.5,397.2c-1.9-0.5-2.4-2-2.4-3.8c0-2.5,1.2-4.2,2.8-4.9
c-0.2-3.8-1.1-5.3-3.4-5.3c-6.5,0-12,16.6-12,25.6c0,6,1.2,7.3,4.6,7.3C198.3,416.2,203,408.1,204.5,397.2L204.5,397.2z
M197.9,436.9c0-8.3,7.1-11,15.8-13.6l10.9-51.9c2.7-13,10.6-15.5,16.5-15.5c4.1,0,8,2.2,9.7,5.7c3.6-4.6,8.4-5.7,12.4-5.7
c5.6,0,10.8,3.9,10.8,9.8c0,1.5-0.1,2.6-0.3,3.7h-4.3c0.1-0.9,0.2-1.7,0.2-2.4c0-2.1-1.7-3.1-3.4-3.1c-2,0-4.8,1.1-6.2,7.1
l-1.7,7.4h9.1l-0.8,3.6h-9l-10.3,49.1c-2.7,13-10.6,15.5-16.5,15.5c-5.2,0-8.3-2.3-9.8-5.7c-3.5,4.6-8.3,5.7-12.3,5.7
C203.1,446.7,197.9,442.8,197.9,436.9L197.9,436.9z M207,438.7c1.9,0,4.2-1.8,5.4-7.1l1.1-5.3c-5.7,2-10.1,4.4-10.1,9.4
C203.4,436.9,205.1,438.7,207,438.7z M228.7,438.7c1.9,0,4.2-1.8,5.4-7.1l2.2-10.4l-9.4,1.8l-1.8,8.3c-0.5,2.1-1.1,4-1.8,5.6
C224.2,438.2,226.3,438.7,228.7,438.7L228.7,438.7z M227.3,420.7l9.4-1.7l7.7-36.8h-9L227.3,420.7L227.3,420.7z M243.9,364
c-2,0-4.8,1.1-6.2,7.1l-1.7,7.4h9l2.1-9.5c0.2-0.7,0.2-1.3,0.2-2C247.4,365,245.8,364,243.9,364z M281.8,417
c7.1,0,11.6-4,16.1-9.2h3.1c-5.2,8.3-12.9,16.8-25,16.8c-8.5,0-14.2-4.2-14.2-14.5c0-10.5,5.9-32.3,24.6-32.3
c8.1,0,10,4.2,10,8.7c0,10.5-10,18.5-20.9,19.2c-0.1,1.3-0.2,2.5-0.2,3.6C275.3,415.5,277.5,417,281.8,417z M287.1,382.6
c-4.6,0-9.1,9.7-10.9,18.7c7-0.5,13.2-7.4,13.2-15C289.4,384.1,288.9,382.6,287.1,382.6L287.1,382.6z M315.7,416
c3.4,0,7.8-2.3,10.8-4.8c-2,10.4-8.4,13.4-15.8,13.4c-8.4,0-14.1-4.2-14.1-14.5c0-10.5,5.9-32.3,24.6-32.3c8.1,0,10,4.2,10,8.7
c0,10.6-10,18.5-20.9,19.2c-0.1,0.9-0.2,2-0.2,2.7C310.1,414.1,312.6,416,315.7,416z M321.9,382.6c-4.5,0-9.1,10.1-11,18.7
c7.1-0.4,13.3-7.3,13.3-15C324.2,384.1,323.6,382.6,321.9,382.6z M373.2,375.9c-1.7,0-3-0.6-4.2-1.9c2.4-1.5,4.1-4.8,4.1-7.8
c0-3.1-1.8-6.1-6.8-6.1s-8.3,2.8-8.3,8.2c0,13.3,20.5,15.2,20.5,34.8c0,15.3-12.3,22.7-25.6,22.7c-10.4,0-19.3-4.5-19.3-15.7
c0-9.8,7-14.9,13.3-14.9c3.1,0,7.7,1.3,8,6c-4.9,0-10.7,2.3-10.7,8.5c0,4.5,2.9,8.7,8.7,8.7c6.1,0,10.6-4.4,10.6-12
c0-15.6-18.6-21.1-18.6-34.5c0-9.5,9.3-16.3,21-16.3c4.3,0,14.6,0.9,14.6,10.9C380.6,372,377.7,375.9,373.2,375.9L373.2,375.9z
M409.4,386.2c0-2.3-0.8-3.7-2.5-3.7c-5.7,0-11.7,16.6-11.7,26.7c0,6.2,2.2,7.6,6.6,7.6c7.1,0,11.6-4,16.1-9.2h3.1
c-5.2,8.3-12.9,16.8-25,16.8c-8.5,0-14.2-4.2-14.2-14.5c0-10.6,6-32.3,24.5-32.3c8.1,0,10.1,4.2,10.1,8.3c0,4.4-2.2,6.7-4.8,6.7
c-1,0-2.1-0.4-3.1-1.1C409,389.6,409.4,387.9,409.4,386.2z M437.1,378.6l-1.2,5.7c3.1-2.7,6.7-5.7,11-5.7c4.1,0,6.3,3.3,6.3,6.9
c0,3.1-2.1,6.7-6.6,6.7c-5.1,0-2.5-6-5.3-6c-2.7,0-4.4,1.4-6.7,3.4l-7.2,34.6h-13.1l9.6-45.4L437.1,378.6L437.1,378.6z
M471.3,378.6l-6.6,30.9c-0.3,1.2-0.4,2.1-0.4,2.9c0,2.5,1.2,3.3,3.7,3.3c3.5,0,6.9-3.4,8.1-8h3.8c-5.2,14.8-14.2,16.8-19.1,16.8
c-5.5,0-9.7-3.2-9.7-10.9c0-1.8,0.3-3.7,0.7-5.9l6.2-29.2C458,378.5,471.3,378.6,471.3,378.6z M467.2,359.2c4,0,7.2,3.2,7.2,7.2
s-3.2,7.1-7.2,7.1s-7.1-3.1-7.1-7.1C460,362.4,463.3,359.2,467.2,359.2z M496.3,375.2l-1.5,6.9c2.6-2.3,6.1-3.9,10.7-3.9
c6.2,0,11.1,3.5,11.1,14.4c0,12.2-4.7,32.1-22.3,32.1c-4.5,0-6.8-1.6-7.7-3.2l-4.7,22.1l-13.7,3.2l15.2-71.5
C483.4,375.3,496.3,375.2,496.3,375.2z M504.1,392.2c0-7-2.9-7.5-4.5-7.5c-2,0-4.5,1.6-6.3,4.4l-5.4,25.5c0.4,1,1.4,2.1,3.4,2.1
C501,416.7,504.1,400.8,504.1,392.2z M531.9,409.5c-0.3,1.1-0.5,2.2-0.5,3.1c0,1.9,0.7,3.2,3.1,3.2c0.7,0,1.7,0,2.4-0.3
c-2.5,7.8-6.6,8.9-9.6,8.9c-6.4,0-9.1-4.4-9.1-10.3c0-1.6,0.2-3.1,0.6-4.8l5.8-27.2h-3l0.7-3.6h3L528,366l13.4-1.9
c0,0-1.4,6.2-3.1,14.4h5.5l-0.7,3.6h-5.5L531.9,409.5z"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@@ -34,7 +34,7 @@
<a href="#operators">Operators and Aliases</a>
<a href="#classes">Classes, Inheritance, and Super</a>
<a href="#destructuring">Destructuring Assignment</a>
<a href="#fat-arrow">Function Binding</a>
<a href="#fat-arrow">Bound and Generator Functions</a>
<a href="#embedded">Embedded JavaScript</a>
<a href="#switch">Switch and Try/Catch</a>
<a href="#comparisons">Chained Comparisons</a>
@@ -110,7 +110,7 @@
<p>
<b>Latest Version:</b>
<a href="http://github.com/jashkenas/coffeescript/tarball/1.8.0">1.8.0</a>
<a href="http://github.com/jashkenas/coffeescript/tarball/1.9.0">1.9.0</a>
</p>
<pre>npm install -g coffee-script</pre>
@@ -142,8 +142,8 @@
<p>
To install, first make sure you have a working copy of the latest stable version of
<a href="http://nodejs.org/">Node.js</a>, and <a href="http://npmjs.org">npm</a>
(the Node Package Manager). You can then install CoffeeScript globally with npm:
<a href="http://nodejs.org/">Node.js</a>. You can then install CoffeeScript globally
with <a href="http://npmjs.org">npm</a>:
</p>
<pre>
@@ -707,7 +707,7 @@ Expressions
<%= codeFor('soaks') %>
<p>
Soaking up nulls is similar to Ruby's
<a href="http://andand.rubyforge.org/">andand gem</a>, and to the
<a href="https://rubygems.org/gems/andand">andand gem</a>, and to the
<a href="http://groovy.codehaus.org/Operators#Operators-SafeNavigationOperator%28%3F.%29">safe navigation operator</a>
in Groovy.
</p>
@@ -793,7 +793,7 @@ Expressions
<p>
<span id="fat-arrow" class="bookmark"></span>
<b class="header">Function binding</b>
<b class="header">Bound Functions, Generator Functions</b>
In JavaScript, the <tt>this</tt> keyword is dynamically scoped to mean the
object that the current function is attached to. If you pass a function as
a callback or attach it to a different object, the original value of <tt>this</tt>
@@ -820,6 +820,13 @@ Expressions
be automatically bound to each instance of the class when the instance is
constructed.
</p>
<p>
CoffeeScript functions also support
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*">ES6 generator functions</a>
through the <tt>yield</tt> keyword. There's no <tt>function*(){}</tt>
nonsense &mdash; a generator in CoffeeScript is simply a function that yields.
</p>
<%= codeFor('generators', 'ps.next().value') %>
<p>
<span id="embedded" class="bookmark"></span>
@@ -1045,14 +1052,18 @@ Expressions
</li>
<li>
<a href="http://www.packtpub.com/coffeescript-application-development/book">CoffeeScript Application Development</a>
is a new book from Packt Publishing that introduces CoffeeScript while
from Packt, introduces CoffeeScript while
walking through the process of building a demonstration web application.
</li>
<li>
<a href="http://www.manning.com/lee/">CoffeeScript in Action</a>
is a new book from Manning Publications that covers CoffeeScript syntax, composition techniques
from Manning Publications, covers CoffeeScript syntax, composition techniques
and application development.
</li>
<li>
<a href="http://www.dpunkt.de/buecher/4021/coffeescript.html">CoffeeScript: Die Alternative zu JavaScript</a>
from dpunkt.verlag, is the first CoffeeScript book in Deutsch.
</li>
</ul>
<h2>
@@ -1115,8 +1126,8 @@ Expressions
the Bolo tank game for modern browsers.
</li>
<li>
<b>josh</b>'s <a href="http://josh.github.com/nack/">nack</a>, a Node.js-powered
<a href="http://rack.rubyforge.org/">Rack</a> server.
<b>github</b>'s <a href="https://atom.io/">Atom</a>,
a hackable text editor built on web technologies.
</li>
</ul>
@@ -1192,6 +1203,25 @@ Expressions
Change Log
</h2>
<p>
<%= releaseHeader('2015-01-29', '1.9.0', '1.8.0') %>
<ul>
<li>
CoffeeScript now supports ES6 generators. A generator is simply a function
that <tt>yield</tt>s.
</li>
<li>
Improved error reporting for string interpolation.
</li>
<li>
Changed strategy for the generation of internal compiler variable names.
</li>
<li>
Fixed REPL compatibility with latest versions of Node and IO.js.
</li>
</ul>
</p>
<p>
<%= releaseHeader('2014-08-26', '1.8.0', '1.7.1') %>
<ul>
@@ -1463,7 +1493,7 @@ Expressions
effectively creating a shallow copy of the list.
</li>
<li>
Additional tweaks and improvments to <tt>coffee --watch</tt> under
Additional tweaks and improvements to <tt>coffee --watch</tt> under
Node's "new" file watching API. Watch will now beep by default
if you introduce a syntax error into a watched script. We also now
ignore hidden directories by default when watching recursively.

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var volume, winner;
if (ignition === true) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var courses, dish, food, foods, i, _i, _j, _k, _len, _len1, _len2, _ref;
_ref = ['toast', 'cheese', 'wine'];

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
/*
SkinnyMochaHalfCaffScript Compiler v1.0

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var fs;
fs = require('fs');
@@ -10,5 +10,5 @@ task('build:parser', 'rebuild the Jison parser', function(options) {
require('jison');
code = require('./lib/grammar').parser.generate();
dir = options.output || 'lib';
return fs.writeFile("" + dir + "/parser.js", code);
return fs.writeFile(dir + "/parser.js", code);
});

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
$('body').click(function(e) {
return $('.box').fadeIn('fast').addClass('.active');
}).css('background', 'white');

View File

@@ -1,11 +1,11 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var Animal, Horse, Snake, sam, tom,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
__hasProp = {}.hasOwnProperty;
Animal = (function() {
function Animal(name) {
this.name = name;
function Animal(_at_name) {
this.name = _at_name;
}
Animal.prototype.move = function(meters) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var cholesterol, healthy;
cholesterol = 127;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var date, mood;
if (singing) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var Person, tim;
Person = (function() {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var fill;
fill = function(container, liquid) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var filename, _fn, _i, _len;
_fn = function(filename) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var hi;
hi = function() {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var footprints, solipsism, speed;
if ((typeof mind !== "undefined" && mind !== null) && (typeof world === "undefined" || world === null)) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var first, last, text, _ref;
text = "Every literary critic believes he will outwit history and have the last word";

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var eldest, grade;
grade = function(student) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var one, six, three, two;
six = (one = 1) + (two = 2) + (three = 3);

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var globals, name;
globals = ((function() {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var error;
alert((function() {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var Account;
Account = function(customer, cart) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var cube, square;
square = function(x) {

View File

@@ -0,0 +1,13 @@
// Generated by CoffeeScript 1.9.0
var perfectSquares;
perfectSquares = function*() {
var num;
num = 0;
while (true) {
num += 1;
(yield num * num);
}
};
window.ps || (window.ps = perfectSquares());

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var html;
html = "<strong>\n cup of coffeescript\n</strong>";

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var OPERATOR;
OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})/;

View File

@@ -1,8 +1,8 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var author, quote, sentence;
author = "Wittgenstein";
quote = "A picture is a fact. -- " + author;
sentence = "" + (22 / 7) + " is a decent approximation of π";
sentence = (22 / 7) + " is a decent approximation of π";

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var city, forecast, temp, weatherReport, _ref;
weatherReport = function(location) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var age, ages, child, yearsOld;
yearsOld = {
@@ -12,7 +12,7 @@ ages = (function() {
_results = [];
for (child in yearsOld) {
age = yearsOld[child];
_results.push("" + child + " is " + age);
_results.push(child + " is " + age);
}
return _results;
})();

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var city, futurists, name, street, _ref, _ref1;
futurists = {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var bitlist, kids, singers, song;
song = ["do", "re", "mi", "fa", "so"];

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
$('.account').attr({
"class": 'active'
});

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var cubes, list, math, num, number, opposite, race, square,
__slice = [].slice;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var theBait, theSwitch, _ref;
theBait = 1000;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var close, contents, open, tag, _i, _ref,
__slice = [].slice;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
String.prototype.dasherize = function() {
return this.replace(/_/g, "-");
};

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var countdown, num;
countdown = (function() {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var changeNumbers, inner, outer;
outer = 1;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var copy, end, middle, numbers, start;
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var zip, _ref;
zip = typeof lottery.drawWinner === "function" ? (_ref = lottery.drawWinner().address) != null ? _ref.zipcode : void 0 : void 0;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var awardMedals, contenders, gold, rest, silver,
__slice = [].slice;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var numbers, _ref;
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var mobyDick;
mobyDick = "Call me Ishmael. Some years ago -- never mind how long precisely -- having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world...";

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
switch (day) {
case "Mon":
go(work);

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var grade, score;
score = 76;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var error;
try {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
var lyrics, num;
if (this.studyingEconomics) {
@@ -16,7 +16,7 @@ lyrics = (function() {
var _results;
_results = [];
while (num -= 1) {
_results.push("" + num + " little monkeys, jumping on the bed. One fell out and bumped his head.");
_results.push(num + " little monkeys, jumping on the bed. One fell out and bumped his head.");
}
return _results;
})();

File diff suppressed because one or more lines are too long

View File

@@ -34,7 +34,7 @@
<a href="#operators">Operators and Aliases</a>
<a href="#classes">Classes, Inheritance, and Super</a>
<a href="#destructuring">Destructuring Assignment</a>
<a href="#fat-arrow">Function Binding</a>
<a href="#fat-arrow">Bound and Generator Functions</a>
<a href="#embedded">Embedded JavaScript</a>
<a href="#switch">Switch and Try/Catch</a>
<a href="#comparisons">Chained Comparisons</a>
@@ -110,7 +110,7 @@
<p>
<b>Latest Version:</b>
<a href="http://github.com/jashkenas/coffeescript/tarball/1.8.0">1.8.0</a>
<a href="http://github.com/jashkenas/coffeescript/tarball/1.9.0">1.9.0</a>
</p>
<pre>npm install -g coffee-script</pre>
@@ -258,8 +258,8 @@ cubes = (function() {
<p>
To install, first make sure you have a working copy of the latest stable version of
<a href="http://nodejs.org/">Node.js</a>, and <a href="http://npmjs.org">npm</a>
(the Node Package Manager). You can then install CoffeeScript globally with npm:
<a href="http://nodejs.org/">Node.js</a>. You can then install CoffeeScript globally
with <a href="http://npmjs.org">npm</a>:
</p>
<pre>
@@ -962,7 +962,7 @@ ages = (<span class="function"><span class="keyword">function</span><span class=
_results = [];
<span class="keyword">for</span> (child <span class="keyword">in</span> yearsOld) {
age = yearsOld[child];
_results.push(<span class="string">""</span> + child + <span class="string">" is "</span> + age);
_results.push(child + <span class="string">" is "</span> + age);
}
<span class="keyword">return</span> _results;
})();
@@ -979,7 +979,7 @@ ages = (function() {
_results = [];
for (child in yearsOld) {
age = yearsOld[child];
_results.push("" + child + " is " + age);
_results.push(child + " is " + age);
}
return _results;
})();
@@ -1023,7 +1023,7 @@ lyrics = (<span class="function"><span class="keyword">function</span><span clas
<span class="keyword">var</span> _results;
_results = [];
<span class="keyword">while</span> (num -= <span class="number">1</span>) {
_results.push(<span class="string">""</span> + num + <span class="string">" little monkeys, jumping on the bed. One fell out and bumped his head."</span>);
_results.push(num + <span class="string">" little monkeys, jumping on the bed. One fell out and bumped his head."</span>);
}
<span class="keyword">return</span> _results;
})();
@@ -1044,7 +1044,7 @@ lyrics = (function() {
var _results;
_results = [];
while (num -= 1) {
_results.push("" + num + " little monkeys, jumping on the bed. One fell out and bumped his head.");
_results.push(num + " little monkeys, jumping on the bed. One fell out and bumped his head.");
}
return _results;
})();
@@ -1445,7 +1445,7 @@ zip = <span class="keyword">typeof</span> lottery.drawWinner === <span class="st
</code></pre><script>window.example22 = "zip = lottery.drawWinner?().address?.zipcode\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example22);'>load</div><br class='clear' /></div>
<p>
Soaking up nulls is similar to Ruby's
<a href="http://andand.rubyforge.org/">andand gem</a>, and to the
<a href="https://rubygems.org/gems/andand">andand gem</a>, and to the
<a href="http://groovy.codehaus.org/Operators#Operators-SafeNavigationOperator%28%3F.%29">safe navigation operator</a>
in Groovy.
</p>
@@ -1501,12 +1501,12 @@ tom.move()
</code></pre><pre><code><span class="keyword">var</span> Animal, Horse, Snake, sam, tom,
__hasProp = {}.hasOwnProperty,
__extends = <span class="function"><span class="keyword">function</span><span class="params">(child, parent)</span> {</span> <span class="keyword">for</span> (<span class="keyword">var</span> key <span class="keyword">in</span> parent) { <span class="keyword">if</span> (__hasProp.call(parent, key)) child[key] = parent[key]; } <span class="function"><span class="keyword">function</span> <span class="title">ctor</span><span class="params">()</span> {</span> <span class="keyword">this</span>.constructor = child; } ctor.prototype = parent.prototype; child.prototype = <span class="keyword">new</span> ctor(); child.__super__ = parent.prototype; <span class="keyword">return</span> child; };
__extends = <span class="function"><span class="keyword">function</span><span class="params">(child, parent)</span> {</span> <span class="keyword">for</span> (<span class="keyword">var</span> key <span class="keyword">in</span> parent) { <span class="keyword">if</span> (__hasProp.call(parent, key)) child[key] = parent[key]; } <span class="function"><span class="keyword">function</span> <span class="title">ctor</span><span class="params">()</span> {</span> <span class="keyword">this</span>.constructor = child; } ctor.prototype = parent.prototype; child.prototype = <span class="keyword">new</span> ctor(); child.__super__ = parent.prototype; <span class="keyword">return</span> child; },
__hasProp = {}.hasOwnProperty;
Animal = (<span class="function"><span class="keyword">function</span><span class="params">()</span> {</span>
<span class="function"><span class="keyword">function</span> <span class="title">Animal</span><span class="params">(name)</span> {</span>
<span class="keyword">this</span>.name = name;
<span class="function"><span class="keyword">function</span> <span class="title">Animal</span><span class="params">(_at_name)</span> {</span>
<span class="keyword">this</span>.name = _at_name;
}
Animal.prototype.move = <span class="function"><span class="keyword">function</span><span class="params">(meters)</span> {</span>
@@ -1557,12 +1557,12 @@ sam.move();
tom.move();
</code></pre><script>window.example23 = "class Animal\n constructor: (@name) ->\n\n move: (meters) ->\n alert @name + \" moved #{meters}m.\"\n\nclass Snake extends Animal\n move: ->\n alert \"Slithering...\"\n super 5\n\nclass Horse extends Animal\n move: ->\n alert \"Galloping...\"\n super 45\n\nsam = new Snake \"Sammy the Python\"\ntom = new Horse \"Tommy the Palomino\"\n\nsam.move()\ntom.move()\n\n\n\n\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example23);'>load</div><div class='minibutton ok' onclick='javascript: var Animal, Horse, Snake, sam, tom,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
__hasProp = {}.hasOwnProperty;
Animal = (function() {
function Animal(name) {
this.name = name;
function Animal(_at_name) {
this.name = _at_name;
}
Animal.prototype.move = function(meters) {
@@ -1832,7 +1832,7 @@ tim = new Person({
<p>
<span id="fat-arrow" class="bookmark"></span>
<b class="header">Function binding</b>
<b class="header">Bound Functions, Generator Functions</b>
In JavaScript, the <tt>this</tt> keyword is dynamically scoped to mean the
object that the current function is attached to. If you pass a function as
a callback or attach it to a different object, the original value of <tt>this</tt>
@@ -1875,6 +1875,44 @@ Account = <span class="function"><span class="keyword">function</span><span clas
be automatically bound to each instance of the class when the instance is
constructed.
</p>
<p>
CoffeeScript functions also support
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*">ES6 generator functions</a>
through the <tt>yield</tt> keyword. There's no <tt>function*(){}</tt>
nonsense &mdash; a generator in CoffeeScript is simply a function that yields.
</p>
<div class='code'><pre><code><span class="function"><span class="title">perfectSquares</span> = -&gt;</span>
num = <span class="number">0</span>
<span class="keyword">loop</span>
num += <span class="number">1</span>
yield num * num
<span class="keyword">return</span>
<span class="built_in">window</span>.ps <span class="keyword">or</span>= perfectSquares()</code></pre><pre><code><span class="keyword">var</span> perfectSquares;
perfectSquares = <span class="function"><span class="keyword">function</span>*<span class="params">()</span> {</span>
<span class="keyword">var</span> num;
num = <span class="number">0</span>;
<span class="keyword">while</span> (<span class="literal">true</span>) {
num += <span class="number">1</span>;
(<span class="keyword">yield</span> num * num);
}
};
window.ps || (window.ps = perfectSquares());
</code></pre><script>window.example32 = "perfectSquares = ->\n num = 0\n loop\n num += 1\n yield num * num\n return\n\nwindow.ps or= perfectSquares()"</script><div class='minibutton load' onclick='javascript: loadConsole(example32);'>load</div><div class='minibutton ok' onclick='javascript: var perfectSquares;
perfectSquares = function*() {
var num;
num = 0;
while (true) {
num += 1;
(yield num * num);
}
};
window.ps || (window.ps = perfectSquares());
;alert(ps.next().value);'>run: ps.next().value</div><br class='clear' /></div>
<p>
<span id="embedded" class="bookmark"></span>
@@ -1894,7 +1932,7 @@ Account = <span class="function"><span class="keyword">function</span><span clas
hi = <span class="function"><span class="keyword">function</span><span class="params">()</span> {</span>
<span class="keyword">return</span> [document.title, <span class="string">"Hello JavaScript"</span>].join(<span class="string">": "</span>);
};
</code></pre><script>window.example32 = "hi = `function() {\n return [document.title, \"Hello JavaScript\"].join(\": \");\n}`\n\n\n\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example32);'>load</div><div class='minibutton ok' onclick='javascript: var hi;
</code></pre><script>window.example33 = "hi = `function() {\n return [document.title, \"Hello JavaScript\"].join(\": \");\n}`\n\n\n\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example33);'>load</div><div class='minibutton ok' onclick='javascript: var hi;
hi = function() {
return [document.title, "Hello JavaScript"].join(": ");
@@ -1948,7 +1986,7 @@ hi = function() {
<span class="keyword">default</span>:
go(work);
}
</code></pre><script>window.example33 = "switch day\n when \"Mon\" then go work\n when \"Tue\" then go relax\n when \"Thu\" then go iceFishing\n when \"Fri\", \"Sat\"\n if day is bingoDay\n go bingo\n go dancing\n when \"Sun\" then go church\n else go work"</script><div class='minibutton load' onclick='javascript: loadConsole(example33);'>load</div><br class='clear' /></div>
</code></pre><script>window.example34 = "switch day\n when \"Mon\" then go work\n when \"Tue\" then go relax\n when \"Thu\" then go iceFishing\n when \"Fri\", \"Sat\"\n if day is bingoDay\n go bingo\n go dancing\n when \"Sun\" then go church\n else go work"</script><div class='minibutton load' onclick='javascript: loadConsole(example34);'>load</div><br class='clear' /></div>
<p>
Switch statements can also be used without a control expression, turning them in to a cleaner alternative to if/else chains.
@@ -1979,7 +2017,7 @@ grade = (<span class="function"><span class="keyword">function</span><span class
<span class="keyword">return</span> <span class="string">'A'</span>;
}
})();
</code></pre><script>window.example34 = "score = 76\ngrade = switch\n when score < 60 then 'F'\n when score < 70 then 'D'\n when score < 80 then 'C'\n when score < 90 then 'B'\n else 'A'\n# grade == 'C'\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example34);'>load</div><br class='clear' /></div>
</code></pre><script>window.example35 = "score = 76\ngrade = switch\n when score < 60 then 'F'\n when score < 70 then 'D'\n when score < 80 then 'C'\n when score < 90 then 'B'\n else 'A'\n# grade == 'C'\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example35);'>load</div><br class='clear' /></div>
<p>
<span id="try" class="bookmark"></span>
@@ -2006,7 +2044,7 @@ grade = (<span class="function"><span class="keyword">function</span><span class
} <span class="keyword">finally</span> {
cleanUp();
}
</code></pre><script>window.example35 = "try\n allHellBreaksLoose()\n catsAndDogsLivingTogether()\ncatch error\n print error\nfinally\n cleanUp()\n\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example35);'>load</div><br class='clear' /></div>
</code></pre><script>window.example36 = "try\n allHellBreaksLoose()\n catsAndDogsLivingTogether()\ncatch error\n print error\nfinally\n cleanUp()\n\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example36);'>load</div><br class='clear' /></div>
<p>
<span id="comparisons" class="bookmark"></span>
@@ -2026,7 +2064,7 @@ healthy = <span class="number">200</span> &gt; cholesterol &gt; <span class="num
cholesterol = <span class="number">127</span>;
healthy = (<span class="number">200</span> &gt; cholesterol &amp;&amp; cholesterol &gt; <span class="number">60</span>);
</code></pre><script>window.example36 = "cholesterol = 127\n\nhealthy = 200 > cholesterol > 60\n\n\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example36);'>load</div><div class='minibutton ok' onclick='javascript: var cholesterol, healthy;
</code></pre><script>window.example37 = "cholesterol = 127\n\nhealthy = 200 > cholesterol > 60\n\n\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example37);'>load</div><div class='minibutton ok' onclick='javascript: var cholesterol, healthy;
cholesterol = 127;
@@ -2055,14 +2093,14 @@ author = <span class="string">"Wittgenstein"</span>;
quote = <span class="string">"A picture is a fact. -- "</span> + author;
sentence = <span class="string">""</span> + (<span class="number">22</span> / <span class="number">7</span>) + <span class="string">" is a decent approximation of π"</span>;
</code></pre><script>window.example37 = "author = \"Wittgenstein\"\nquote = \"A picture is a fact. -- #{ author }\"\n\nsentence = \"#{ 22 / 7 } is a decent approximation of π\"\n\n\n\n\n\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example37);'>load</div><div class='minibutton ok' onclick='javascript: var author, quote, sentence;
sentence = (<span class="number">22</span> / <span class="number">7</span>) + <span class="string">" is a decent approximation of π"</span>;
</code></pre><script>window.example38 = "author = \"Wittgenstein\"\nquote = \"A picture is a fact. -- #{ author }\"\n\nsentence = \"#{ 22 / 7 } is a decent approximation of π\"\n\n\n\n\n\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example38);'>load</div><div class='minibutton ok' onclick='javascript: var author, quote, sentence;
author = "Wittgenstein";
quote = "A picture is a fact. -- " + author;
sentence = "" + (22 / 7) + " is a decent approximation of π";
sentence = (22 / 7) + " is a decent approximation of π";
;alert(sentence);'>run: sentence</div><br class='clear' /></div>
<p>
Multiline strings are allowed in CoffeeScript. Lines are joined by a single space unless they end with a backslash. Indentation is ignored.
@@ -2076,7 +2114,7 @@ sentence = "" + (22 / 7) + " is a decent approximation of π";
</code></pre><pre><code><span class="keyword">var</span> mobyDick;
mobyDick = <span class="string">"Call me Ishmael. Some years ago -- never mind how long precisely -- having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world..."</span>;
</code></pre><script>window.example38 = "mobyDick = \"Call me Ishmael. Some years ago --\n never mind how long precisely -- having little\n or no money in my purse, and nothing particular\n to interest me on shore, I thought I would sail\n about a little and see the watery part of the\n world...\"\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example38);'>load</div><div class='minibutton ok' onclick='javascript: var mobyDick;
</code></pre><script>window.example39 = "mobyDick = \"Call me Ishmael. Some years ago --\n never mind how long precisely -- having little\n or no money in my purse, and nothing particular\n to interest me on shore, I thought I would sail\n about a little and see the watery part of the\n world...\"\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example39);'>load</div><div class='minibutton ok' onclick='javascript: var mobyDick;
mobyDick = "Call me Ishmael. Some years ago -- never mind how long precisely -- having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world...";
;alert(mobyDick);'>run: mobyDick</div><br class='clear' /></div>
@@ -2095,7 +2133,7 @@ mobyDick = "Call me Ishmael. Some years ago -- never mind how long precisely --
</code></pre><pre><code><span class="keyword">var</span> html;
html = <span class="string">"&lt;strong&gt;\n cup of coffeescript\n&lt;/strong&gt;"</span>;
</code></pre><script>window.example39 = "html = \"\"\"\n <strong>\n cup of coffeescript\n </strong>\n \"\"\"\n \n"</script><div class='minibutton load' onclick='javascript: loadConsole(example39);'>load</div><div class='minibutton ok' onclick='javascript: var html;
</code></pre><script>window.example40 = "html = \"\"\"\n <strong>\n cup of coffeescript\n </strong>\n \"\"\"\n \n"</script><div class='minibutton load' onclick='javascript: loadConsole(example40);'>load</div><div class='minibutton ok' onclick='javascript: var html;
html = "<strong>\n cup of coffeescript\n</strong>";
;alert(html);'>run: html</div><br class='clear' /></div>
@@ -2120,7 +2158,7 @@ SkinnyMochaHalfCaffScript Compiler v1.0
Released under the MIT License
*/</span>
</code></pre><script>window.example40 = "###\nSkinnyMochaHalfCaffScript Compiler v1.0\nReleased under the MIT License\n###\n\n\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example40);'>load</div><br class='clear' /></div>
</code></pre><script>window.example41 = "###\nSkinnyMochaHalfCaffScript Compiler v1.0\nReleased under the MIT License\n###\n\n\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example41);'>load</div><br class='clear' /></div>
<p>
<span id="regexes" class="bookmark"></span>
@@ -2145,7 +2183,7 @@ Released under the MIT License
</code></pre><pre><code><span class="keyword">var</span> OPERATOR;
OPERATOR = <span class="regexp">/^(?:[-=]&gt;|[-+*\/%&lt;&gt;&amp;|^!?=]=|&gt;&gt;&gt;=?|([-+:])\1|([&amp;|&lt;&gt;])\2=?|\?\.|\.{2,3})/</span>;
</code></pre><script>window.example41 = "OPERATOR = /// ^ (\n ?: [-=]> # function\n | [-+*/%<>&|^!?=]= # compound assign / compare\n | >>>=? # zero-fill right shift\n | ([-+:])\\1 # doubles\n | ([&|<>])\\2=? # logic / shift\n | \\?\\. # soak access\n | \\.{2,3} # range or splat\n) ///\n\n\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example41);'>load</div><br class='clear' /></div>
</code></pre><script>window.example42 = "OPERATOR = /// ^ (\n ?: [-=]> # function\n | [-+*/%<>&|^!?=]= # compound assign / compare\n | >>>=? # zero-fill right shift\n | ([-+:])\\1 # doubles\n | ([&|<>])\\2=? # logic / shift\n | \\?\\. # soak access\n | \\.{2,3} # range or splat\n) ///\n\n\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example42);'>load</div><br class='clear' /></div>
<h2>
@@ -2190,9 +2228,9 @@ task(<span class="string">'build:parser'</span>, <span class="string">'rebuild t
<span class="built_in">require</span>(<span class="string">'jison'</span>);
code = <span class="built_in">require</span>(<span class="string">'./lib/grammar'</span>).parser.generate();
dir = options.output || <span class="string">'lib'</span>;
<span class="keyword">return</span> fs.writeFile(<span class="string">""</span> + dir + <span class="string">"/parser.js"</span>, code);
<span class="keyword">return</span> fs.writeFile(dir + <span class="string">"/parser.js"</span>, code);
});
</code></pre><script>window.example42 = "fs = require 'fs'\n\noption '-o', '--output [DIR]', 'directory for compiled code'\n\ntask 'build:parser', 'rebuild the Jison parser', (options) ->\n require 'jison'\n code = require('./lib/grammar').parser.generate()\n dir = options.output or 'lib'\n fs.writeFile \"#{dir}/parser.js\", code"</script><div class='minibutton load' onclick='javascript: loadConsole(example42);'>load</div><br class='clear' /></div>
</code></pre><script>window.example43 = "fs = require 'fs'\n\noption '-o', '--output [DIR]', 'directory for compiled code'\n\ntask 'build:parser', 'rebuild the Jison parser', (options) ->\n require 'jison'\n code = require('./lib/grammar').parser.generate()\n dir = options.output or 'lib'\n fs.writeFile \"#{dir}/parser.js\", code"</script><div class='minibutton load' onclick='javascript: loadConsole(example43);'>load</div><br class='clear' /></div>
<p>
If you need to invoke one task before another &mdash; for example, running
<tt>build</tt> before <tt>test</tt>, you can use the <tt>invoke</tt> function:
@@ -2302,14 +2340,18 @@ task(<span class="string">'build:parser'</span>, <span class="string">'rebuild t
</li>
<li>
<a href="http://www.packtpub.com/coffeescript-application-development/book">CoffeeScript Application Development</a>
is a new book from Packt Publishing that introduces CoffeeScript while
from Packt, introduces CoffeeScript while
walking through the process of building a demonstration web application.
</li>
<li>
<a href="http://www.manning.com/lee/">CoffeeScript in Action</a>
is a new book from Manning Publications that covers CoffeeScript syntax, composition techniques
from Manning Publications, covers CoffeeScript syntax, composition techniques
and application development.
</li>
<li>
<a href="http://www.dpunkt.de/buecher/4021/coffeescript.html">CoffeeScript: Die Alternative zu JavaScript</a>
from dpunkt.verlag, is the first CoffeeScript book in Deutsch.
</li>
</ul>
<h2>
@@ -2372,8 +2414,8 @@ task(<span class="string">'build:parser'</span>, <span class="string">'rebuild t
the Bolo tank game for modern browsers.
</li>
<li>
<b>josh</b>'s <a href="http://josh.github.com/nack/">nack</a>, a Node.js-powered
<a href="http://rack.rubyforge.org/">Rack</a> server.
<b>github</b>'s <a href="https://atom.io/">Atom</a>,
a hackable text editor built on web technologies.
</li>
</ul>
@@ -2449,6 +2491,29 @@ task(<span class="string">'build:parser'</span>, <span class="string">'rebuild t
Change Log
</h2>
<p>
<div class="anchor" id="1.9.0"></div>
<b class="header">
<a href="https://github.com/jashkenas/coffeescript/compare/1.8.0...1.9.0">1.9.0</a>
<span class="timestamp"> &mdash; <time datetime="2015-01-29">January 29, 2015</time></span>
</b>
<ul>
<li>
CoffeeScript now supports ES6 generators. A generator is simply a function
that <tt>yield</tt>s.
</li>
<li>
Improved error reporting for string interpolation.
</li>
<li>
Changed strategy for the generation of internal compiler variable names.
</li>
<li>
Fixed REPL compatibility with latest versions of Node and IO.js.
</li>
</ul>
</p>
<p>
<div class="anchor" id="1.8.0"></div>
<b class="header">
@@ -2532,7 +2597,7 @@ task(<span class="string">'build:parser'</span>, <span class="string">'rebuild t
</code></pre><pre><code>$(<span class="string">'body'</span>).click(<span class="function"><span class="keyword">function</span><span class="params">(e)</span> {</span>
<span class="keyword">return</span> $(<span class="string">'.box'</span>).fadeIn(<span class="string">'fast'</span>).addClass(<span class="string">'.active'</span>);
}).css(<span class="string">'background'</span>, <span class="string">'white'</span>);
</code></pre><script>window.example43 = "$ 'body'\n.click (e) ->\n $ '.box'\n .fadeIn 'fast'\n .addClass '.active'\n.css 'background', 'white'\n\n\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example43);'>load</div><br class='clear' /></div>
</code></pre><script>window.example44 = "$ 'body'\n.click (e) ->\n $ '.box'\n .fadeIn 'fast'\n .addClass '.active'\n.css 'background', 'white'\n\n\n"</script><div class='minibutton load' onclick='javascript: loadConsole(example44);'>load</div><br class='clear' /></div>
<ul>
<li>
Added <tt>**</tt>, <tt>//</tt> and <tt>%%</tt> operators and <tt>...</tt> expansion in parameter lists and destructuring expressions.
@@ -2771,7 +2836,7 @@ task(<span class="string">'build:parser'</span>, <span class="string">'rebuild t
effectively creating a shallow copy of the list.
</li>
<li>
Additional tweaks and improvments to <tt>coffee --watch</tt> under
Additional tweaks and improvements to <tt>coffee --watch</tt> under
Node's "new" file watching API. Watch will now beep by default
if you introduce a syntax error into a watched script. We also now
ignore hidden directories by default when watching recursively.

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
(function() {
var CoffeeScript, compile, runScripts,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
@@ -41,7 +41,7 @@
options.sourceMap = true;
options.inline = true;
_ref = CoffeeScript.compile(code, options), js = _ref.js, v3SourceMap = _ref.v3SourceMap;
return "" + js + "\n//# sourceMappingURL=data:application/json;base64," + (btoa(unescape(encodeURIComponent(v3SourceMap)))) + "\n//# sourceURL=coffeescript";
return js + "\n//# sourceMappingURL=data:application/json;base64," + (btoa(unescape(encodeURIComponent(v3SourceMap)))) + "\n//# sourceURL=coffeescript";
};
}

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
(function() {
var CoffeeScript, cakefileDirectory, fatalError, fs, helpers, missingTask, oparse, options, optparse, path, printTasks, switches, tasks;
@@ -76,7 +76,7 @@
var cakefilePath, desc, name, relative, spaces, task;
relative = path.relative || path.resolve;
cakefilePath = path.join(relative(__originalDirname, process.cwd()), 'Cakefile');
console.log("" + cakefilePath + " defines the following tasks:\n");
console.log(cakefilePath + " defines the following tasks:\n");
for (name in tasks) {
task = tasks[name];
spaces = 20 - name.length;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
(function() {
var Lexer, SourceMap, compile, ext, formatSourcePosition, fs, getSourceMap, helpers, lexer, parser, path, sourceMaps, vm, withPrettyErrors, _base, _i, _len, _ref,
__hasProp = {}.hasOwnProperty,
@@ -18,7 +18,7 @@
SourceMap = require('./sourcemap');
exports.VERSION = '1.8.0';
exports.VERSION = '1.9.0';
exports.FILE_EXTENSIONS = ['.coffee', '.litcoffee', '.coffee.md'];
@@ -40,13 +40,25 @@
};
exports.compile = compile = withPrettyErrors(function(code, options) {
var answer, currentColumn, currentLine, extend, fragment, fragments, header, js, map, merge, newLines, _i, _len;
var answer, currentColumn, currentLine, extend, fragment, fragments, header, js, map, merge, newLines, token, tokens, _i, _len;
merge = helpers.merge, extend = helpers.extend;
options = extend({}, options);
if (options.sourceMap) {
map = new SourceMap;
}
fragments = parser.parse(lexer.tokenize(code, options)).compileToFragments(options);
tokens = lexer.tokenize(code, options);
options.referencedVars = (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = tokens.length; _i < _len; _i++) {
token = tokens[_i];
if (token.variable && token[1].charAt(0) === '_') {
_results.push(token[1]);
}
}
return _results;
})();
fragments = parser.parse(tokens).compileToFragments(options);
currentLine = 0;
if (options.header) {
currentLine += 1;
@@ -120,24 +132,27 @@
};
exports["eval"] = function(code, options) {
var Module, Script, js, k, o, r, sandbox, v, _i, _len, _module, _ref, _ref1, _require;
var Module, createContext, isContext, js, k, o, r, sandbox, v, _i, _len, _module, _ref, _ref1, _ref2, _ref3, _require;
if (options == null) {
options = {};
}
if (!(code = code.trim())) {
return;
}
Script = vm.Script;
if (Script) {
createContext = (_ref = vm.Script.createContext) != null ? _ref : vm.createContext;
isContext = (_ref1 = vm.isContext) != null ? _ref1 : function(ctx) {
return options.sandbox instanceof createContext().constructor;
};
if (createContext) {
if (options.sandbox != null) {
if (options.sandbox instanceof Script.createContext().constructor) {
if (isContext(options.sandbox)) {
sandbox = options.sandbox;
} else {
sandbox = Script.createContext();
_ref = options.sandbox;
for (k in _ref) {
if (!__hasProp.call(_ref, k)) continue;
v = _ref[k];
sandbox = createContext();
_ref2 = options.sandbox;
for (k in _ref2) {
if (!__hasProp.call(_ref2, k)) continue;
v = _ref2[k];
sandbox[k] = v;
}
}
@@ -154,9 +169,9 @@
return Module._load(path, _module, true);
};
_module.filename = sandbox.__filename;
_ref1 = Object.getOwnPropertyNames(require);
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
r = _ref1[_i];
_ref3 = Object.getOwnPropertyNames(require);
for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
r = _ref3[_i];
if (r !== 'paths') {
_require[r] = require[r];
}
@@ -223,10 +238,10 @@
parser.lexer = {
lex: function() {
var tag, token;
token = this.tokens[this.pos++];
token = parser.tokens[this.pos++];
if (token) {
tag = token[0], this.yytext = token[1], this.yylloc = token[2];
this.errorToken = token.origin || token;
parser.errorToken = token.origin || token;
this.yylineno = this.yylloc.first_line;
} else {
tag = '';
@@ -234,7 +249,7 @@
return tag;
},
setInput: function(tokens) {
this.tokens = tokens;
parser.tokens = tokens;
return this.pos = 0;
},
upcomingInput: function() {
@@ -245,9 +260,9 @@
parser.yy = require('./nodes');
parser.yy.parseError = function(message, _arg) {
var errorLoc, errorTag, errorText, errorToken, token, tokens, _ref1;
var errorLoc, errorTag, errorText, errorToken, token, tokens;
token = _arg.token;
_ref1 = parser.lexer, errorToken = _ref1.errorToken, tokens = _ref1.tokens;
errorToken = parser.errorToken, tokens = parser.tokens;
errorTag = errorToken[0], errorText = errorToken[1], errorLoc = errorToken[2];
errorText = errorToken === tokens[tokens.length - 1] ? 'end of input' : errorTag === 'INDENT' || errorTag === 'OUTDENT' ? 'indentation' : helpers.nameWhitespaceCharacter(errorText);
return helpers.throwSyntaxError("unexpected " + errorText, errorLoc);
@@ -263,7 +278,7 @@
if (frame.isEval()) {
fileName = frame.getScriptNameOrSourceURL();
if (!fileName) {
fileLocation = "" + (frame.getEvalOrigin()) + ", ";
fileLocation = (frame.getEvalOrigin()) + ", ";
}
} else {
fileName = frame.getFileName();
@@ -272,7 +287,7 @@
line = frame.getLineNumber();
column = frame.getColumnNumber();
source = getSourceMapping(fileName, line, column);
fileLocation = source ? "" + fileName + ":" + source[0] + ":" + source[1] : "" + fileName + ":" + line + ":" + column;
fileLocation = source ? fileName + ":" + source[0] + ":" + source[1] : fileName + ":" + line + ":" + column;
}
functionName = frame.getFunctionName();
isConstructor = frame.isConstructor();
@@ -283,19 +298,19 @@
if (functionName) {
tp = as = '';
if (typeName && functionName.indexOf(typeName)) {
tp = "" + typeName + ".";
tp = typeName + ".";
}
if (methodName && functionName.indexOf("." + methodName) !== functionName.length - methodName.length - 1) {
as = " [as " + methodName + "]";
}
return "" + tp + functionName + as + " (" + fileLocation + ")";
} else {
return "" + typeName + "." + (methodName || '<anonymous>') + " (" + fileLocation + ")";
return typeName + "." + (methodName || '<anonymous>') + " (" + fileLocation + ")";
}
} else if (isConstructor) {
return "new " + (functionName || '<anonymous>') + " (" + fileLocation + ")";
} else if (functionName) {
return "" + functionName + " (" + fileLocation + ")";
return functionName + " (" + fileLocation + ")";
} else {
return fileLocation;
}
@@ -341,7 +356,7 @@
}
return _results;
})();
return "" + (err.toString()) + "\n" + (frames.join('\n')) + "\n";
return (err.toString()) + "\n" + (frames.join('\n')) + "\n";
};
}).call(this);

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
(function() {
var BANNER, CoffeeScript, EventEmitter, SWITCHES, compileJoin, compileOptions, compilePath, compileScript, compileStdio, exec, findDirectoryIndex, forkNode, fs, helpers, hidden, joinTimeout, mkdirp, notSources, optionParser, optparse, opts, outputPath, parseOptions, path, printLine, printTokens, printWarn, removeSource, removeSourceDir, silentUnlink, sourceCode, sources, spawn, timeLog, usage, useWinPathSep, version, wait, watch, watchDir, watchedDirs, writeJs, _ref,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
@@ -13,8 +13,6 @@
CoffeeScript = require('./coffee-script');
mkdirp = require('mkdirp');
_ref = require('child_process'), spawn = _ref.spawn, exec = _ref.exec;
EventEmitter = require('events').EventEmitter;
@@ -440,6 +438,27 @@
return path.join(dir, basename + extension);
};
mkdirp = function(dir, fn) {
var mkdirs, mode;
mode = 0x1ff & ~process.umask();
return (mkdirs = function(p, fn) {
return fs.exists(p, function(exists) {
if (exists) {
return fn();
} else {
return mkdirs(path.dirname(p), function() {
return fs.mkdir(p, mode, function(err) {
if (err) {
return fn(err);
}
return fn();
});
});
}
});
})(dir, fn);
};
writeJs = function(base, sourcePath, js, jsPath, generatedSourceMap) {
var compile, jsDir, sourceMapPath;
if (generatedSourceMap == null) {
@@ -453,7 +472,7 @@
js = ' ';
}
if (generatedSourceMap) {
js = "" + js + "\n//# sourceMappingURL=" + (helpers.baseFileName(sourceMapPath, false, useWinPathSep)) + "\n";
js = js + "\n//# sourceMappingURL=" + (helpers.baseFileName(sourceMapPath, false, useWinPathSep)) + "\n";
}
fs.writeFile(jsPath, js, function(err) {
if (err) {
@@ -487,7 +506,7 @@
};
timeLog = function(message) {
return console.log("" + ((new Date).toLocaleTimeString()) + " - " + message);
return console.log(((new Date).toLocaleTimeString()) + " - " + message);
};
printTokens = function(tokens) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
(function() {
var Parser, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap;
@@ -421,6 +421,11 @@
return {
source: LOC(2)(new Value($2))
};
}), o('FOR Range BY Expression', function() {
return {
source: LOC(2)(new Value($2)),
step: $4
};
}), o('ForStart ForSource', function() {
$2.own = $1.own;
$2.name = $1[0];
@@ -552,6 +557,12 @@
return new Op('+', $2);
}), {
prec: 'UNARY_MATH'
}), o('YIELD Statement', function() {
return new Op($1, $2);
}), o('YIELD Expression', function() {
return new Op($1, $2);
}), o('YIELD FROM Expression', function() {
return new Op($1.concat($2), $3);
}), o('-- SimpleAssignable', function() {
return new Op('--', $2);
}), o('++ SimpleAssignable', function() {
@@ -594,7 +605,7 @@
]
};
operators = [['left', '.', '?.', '::', '?::'], ['left', 'CALL_START', 'CALL_END'], ['nonassoc', '++', '--'], ['left', '?'], ['right', 'UNARY'], ['right', '**'], ['right', 'UNARY_MATH'], ['left', 'MATH'], ['left', '+', '-'], ['left', 'SHIFT'], ['left', 'RELATION'], ['left', 'COMPARE'], ['left', 'LOGIC'], ['nonassoc', 'INDENT', 'OUTDENT'], ['right', '=', ':', 'COMPOUND_ASSIGN', 'RETURN', 'THROW', 'EXTENDS'], ['right', 'FORIN', 'FOROF', 'BY', 'WHEN'], ['right', 'IF', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS'], ['left', 'POST_IF']];
operators = [['left', '.', '?.', '::', '?::'], ['left', 'CALL_START', 'CALL_END'], ['nonassoc', '++', '--'], ['left', '?'], ['right', 'UNARY'], ['right', '**'], ['right', 'UNARY_MATH'], ['left', 'MATH'], ['left', '+', '-'], ['left', 'SHIFT'], ['left', 'RELATION'], ['left', 'COMPARE'], ['left', 'LOGIC'], ['nonassoc', 'INDENT', 'OUTDENT'], ['right', 'YIELD'], ['right', '=', ':', 'COMPOUND_ASSIGN', 'RETURN', 'THROW', 'EXTENDS'], ['right', 'FORIN', 'FOROF', 'BY', 'WHEN'], ['right', 'IF', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS'], ['left', 'POST_IF']];
tokens = [];

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
(function() {
var buildLocationData, extend, flatten, last, repeat, syntaxErrorToString, _ref;
@@ -150,7 +150,7 @@
locationData = obj;
}
if (locationData) {
return ("" + (locationData.first_line + 1) + ":" + (locationData.first_column + 1) + "-") + ("" + (locationData.last_line + 1) + ":" + (locationData.last_column + 1));
return ((locationData.first_line + 1) + ":" + (locationData.first_column + 1) + "-") + ((locationData.last_line + 1) + ":" + (locationData.last_column + 1));
} else {
return "No location data";
}
@@ -231,7 +231,7 @@
codeLine = codeLine.slice(0, start) + colorize(codeLine.slice(start, end)) + codeLine.slice(end);
marker = colorize(marker);
}
return "" + filename + ":" + (first_line + 1) + ":" + (first_column + 1) + ": error: " + this.message + "\n" + codeLine + "\n" + marker;
return filename + ":" + (first_line + 1) + ":" + (first_column + 1) + ": error: " + this.message + "\n" + codeLine + "\n" + marker;
};
exports.nameWhitespaceCharacter = function(string) {

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
(function() {
var key, val, _ref;

View File

@@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
(function() {
var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDENTABLE_CLOSERS, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, STRICT_PROSCRIBED, TRAILING_SPACES, UNARY, UNARY_MATH, WHITESPACE, compact, count, invertLiterate, key, last, locationDataToString, repeat, starts, throwSyntaxError, _ref, _ref1,
var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HERECOMMENT_ILLEGAL, HEREDOC_DOUBLE, HEREDOC_INDENT, HEREDOC_SINGLE, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDENTABLE_CLOSERS, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LEADING_BLANK_LINE, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NUMBER, OCTAL_ESCAPE, OPERATOR, POSSIBLY_DIVISION, REGEX, REGEX_FLAGS, REGEX_ILLEGAL, RELATION, RESERVED, Rewriter, SHIFT, STRICT_PROSCRIBED, STRING_DOUBLE, STRING_OMIT, STRING_SINGLE, STRING_START, TRAILING_BLANK_LINE, TRAILING_SPACES, UNARY, UNARY_MATH, VALID_FLAGS, WHITESPACE, compact, count, invertLiterate, key, last, locationDataToString, repeat, starts, throwSyntaxError, _ref, _ref1,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
_ref = require('./rewriter'), Rewriter = _ref.Rewriter, INVERSES = _ref.INVERSES;
@@ -11,7 +11,7 @@
function Lexer() {}
Lexer.prototype.tokenize = function(code, opts) {
var consumed, i, tag, _ref2;
var consumed, end, i, _ref2;
if (opts == null) {
opts = {};
}
@@ -28,13 +28,19 @@
code = this.clean(code);
i = 0;
while (this.chunk = code.slice(i)) {
consumed = this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.heredocToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken();
consumed = this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken();
_ref2 = this.getLineAndColumnFromChunk(consumed), this.chunkLine = _ref2[0], this.chunkColumn = _ref2[1];
i += consumed;
if (opts.untilBalanced && this.ends.length === 0) {
return {
tokens: this.tokens,
index: i
};
}
}
this.closeIndentation();
if (tag = this.ends.pop()) {
this.error("missing " + tag);
if (end = this.ends.pop()) {
throwSyntaxError("missing " + end.tag, end.origin[2]);
}
if (opts.rewrite === false) {
return this.tokens;
@@ -69,6 +75,10 @@
this.token('OWN', id);
return id.length;
}
if (id === 'from' && this.tag() === 'YIELD') {
this.token('FROM', id);
return id.length;
}
forcedIdentifier = colon || (prev = last(this.tokens)) && (((_ref2 = prev[0]) === '.' || _ref2 === '?.' || _ref2 === '::' || _ref2 === '?::') || !prev.spaced && prev[0] === '@');
tag = 'IDENTIFIER';
if (!forcedIdentifier && (__indexOf.call(JS_KEYWORDS, id) >= 0 || __indexOf.call(COFFEE_KEYWORDS, id) >= 0)) {
@@ -129,6 +139,7 @@
})();
}
tagToken = this.token(tag, id, 0, idLength);
tagToken.variable = !forcedIdentifier;
if (poppedToken) {
_ref4 = [poppedToken[2].first_line, poppedToken[2].first_column], tagToken[2].first_line = _ref4[0], tagToken[2].first_column = _ref4[1];
}
@@ -166,60 +177,87 @@
};
Lexer.prototype.stringToken = function() {
var inner, innerLen, numBreak, octalEsc, pos, quote, string, trimmed;
switch (quote = this.chunk.charAt(0)) {
case "'":
string = (SIMPLESTR.exec(this.chunk) || [])[0];
break;
case '"':
string = this.balancedString(this.chunk, '"');
}
if (!string) {
var $, attempt, doc, end, heredoc, i, indent, indentRegex, match, quote, regex, start, token, tokens, _ref2, _ref3;
quote = (STRING_START.exec(this.chunk) || [])[0];
if (!quote) {
return 0;
}
inner = string.slice(1, -1);
trimmed = this.removeNewlines(inner);
if (quote === '"' && 0 < string.indexOf('#{', 1)) {
numBreak = pos = 0;
innerLen = inner.length;
while (inner.charAt(pos++) === '\n' && pos < innerLen) {
numBreak++;
regex = (function() {
switch (quote) {
case "'":
return STRING_SINGLE;
case '"':
return STRING_DOUBLE;
case "'''":
return HEREDOC_SINGLE;
case '"""':
return HEREDOC_DOUBLE;
}
this.interpolateString(trimmed, {
strOffset: 1 + numBreak,
lexedLength: string.length
});
})();
heredoc = quote.length === 3;
start = quote.length;
_ref2 = this.matchWithInterpolations(this.chunk.slice(start), regex, quote, start), tokens = _ref2.tokens, end = _ref2.index;
$ = tokens.length - 1;
if (heredoc) {
indent = null;
doc = ((function() {
var _i, _len, _results;
_results = [];
for (i = _i = 0, _len = tokens.length; _i < _len; i = ++_i) {
token = tokens[i];
if (token[0] === 'NEOSTRING') {
_results.push(token[1]);
}
}
return _results;
})()).join('#{}');
while (match = HEREDOC_INDENT.exec(doc)) {
attempt = match[1];
if (indent === null || (0 < (_ref3 = attempt.length) && _ref3 < indent.length)) {
indent = attempt;
}
}
if (indent) {
indentRegex = RegExp("^" + indent, "gm");
}
this.mergeInterpolationTokens(tokens, {
quote: quote[0],
start: start,
end: end
}, (function(_this) {
return function(value, i) {
value = _this.formatString(value);
if (i === 0) {
value = value.replace(LEADING_BLANK_LINE, '');
}
if (i === $) {
value = value.replace(TRAILING_BLANK_LINE, '');
}
value = value.replace(indentRegex, '');
value = value.replace(MULTILINER, '\\n');
return value;
};
})(this));
} else {
this.token('STRING', quote + this.escapeLines(trimmed) + quote, 0, string.length);
this.mergeInterpolationTokens(tokens, {
quote: quote,
start: start,
end: end
}, (function(_this) {
return function(value, i) {
value = _this.formatString(value);
value = value.replace(STRING_OMIT, function(match, offset) {
if ((i === 0 && offset === 0) || (i === $ && offset + match.length === value.length)) {
return '';
} else {
return ' ';
}
});
return value;
};
})(this));
}
if (octalEsc = /^(?:\\.|[^\\])*\\(?:0[0-7]|[1-7])/.test(string)) {
this.error("octal escape sequences " + string + " are not allowed");
}
return string.length;
};
Lexer.prototype.heredocToken = function() {
var doc, heredoc, match, quote, strOffset;
if (!(match = HEREDOC.exec(this.chunk))) {
return 0;
}
heredoc = match[0];
quote = heredoc.charAt(0);
doc = this.sanitizeHeredoc(match[2], {
quote: quote,
indent: null
});
if (quote === '"' && 0 <= doc.indexOf('#{')) {
strOffset = match[2].charAt(0) === '\n' ? 4 : 3;
this.interpolateString(doc, {
heredoc: true,
strOffset: strOffset,
lexedLength: heredoc.length
});
} else {
this.token('STRING', this.makeString(doc, quote, true), 0, heredoc.length);
}
return heredoc.length;
return end;
};
Lexer.prototype.commentToken = function() {
@@ -229,10 +267,13 @@
}
comment = match[0], here = match[1];
if (here) {
this.token('HERECOMMENT', this.sanitizeHeredoc(here, {
herecomment: true,
indent: repeat(' ', this.indent)
}), 0, comment.length);
if (match = HERECOMMENT_ILLEGAL.exec(comment)) {
this.error("block comments cannot contain " + match[0], match.index);
}
if (here.indexOf('\n') >= 0) {
here = here.replace(RegExp("\\n" + (repeat(' ', this.indent)), "g"), '\n');
}
this.token('HERECOMMENT', here, 0, comment.length);
}
return comment.length;
};
@@ -247,86 +288,67 @@
};
Lexer.prototype.regexToken = function() {
var flags, length, match, prev, regex, _ref2, _ref3;
if (this.chunk.charAt(0) !== '/') {
return 0;
}
if (length = this.heregexToken()) {
return length;
}
prev = last(this.tokens);
if (prev && (_ref2 = prev[0], __indexOf.call((prev.spaced ? NOT_REGEX : NOT_SPACED_REGEX), _ref2) >= 0)) {
return 0;
}
if (!(match = REGEX.exec(this.chunk))) {
return 0;
}
_ref3 = match, match = _ref3[0], regex = _ref3[1], flags = _ref3[2];
if (regex === '//') {
return 0;
}
if (regex.slice(0, 2) === '/*') {
this.error('regular expressions cannot begin with `*`');
}
this.token('REGEX', "" + regex + flags, 0, match.length);
return match.length;
};
Lexer.prototype.heregexToken = function() {
var body, flags, flagsOffset, heregex, match, plusToken, prev, re, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4;
if (!(match = HEREGEX.exec(this.chunk))) {
return 0;
}
heregex = match[0], body = match[1], flags = match[2];
if (0 > body.indexOf('#{')) {
re = this.escapeLines(body.replace(HEREGEX_OMIT, '$1$2').replace(/\//g, '\\/'), true);
if (re.match(/^\*/)) {
this.error('regular expressions cannot begin with `*`');
}
this.token('REGEX', "/" + (re || '(?:)') + "/" + flags, 0, heregex.length);
return heregex.length;
}
this.token('IDENTIFIER', 'RegExp', 0, 0);
this.token('CALL_START', '(', 0, 0);
tokens = [];
_ref2 = this.interpolateString(body, {
regex: true,
strOffset: 3
});
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
token = _ref2[_i];
tag = token[0], value = token[1];
if (tag === 'TOKENS') {
tokens.push.apply(tokens, value);
} else if (tag === 'NEOSTRING') {
if (!(value = value.replace(HEREGEX_OMIT, '$1$2'))) {
continue;
var closed, end, flags, index, match, prev, re, regex, rparen, tokens, _ref2, _ref3, _ref4;
switch (false) {
case !(match = REGEX_ILLEGAL.exec(this.chunk)):
this.error("regular expressions cannot begin with " + match[2], match.index + match[1].length);
break;
case this.chunk.slice(0, 3) !== '///':
_ref2 = this.matchWithInterpolations(this.chunk.slice(3), HEREGEX, '///', 3), tokens = _ref2.tokens, index = _ref2.index;
break;
case !(match = REGEX.exec(this.chunk)):
regex = match[0], closed = match[1];
index = regex.length;
prev = last(this.tokens);
if (prev) {
if (prev.spaced && (_ref3 = prev[0], __indexOf.call(CALLABLE, _ref3) >= 0) && !prev.stringEnd && !prev.regexEnd) {
if (!closed || POSSIBLY_DIVISION.test(regex)) {
return 0;
}
} else if (_ref4 = prev[0], __indexOf.call(NOT_REGEX, _ref4) >= 0) {
return 0;
}
}
value = value.replace(/\\/g, '\\\\');
token[0] = 'STRING';
token[1] = this.makeString(value, '"', true);
tokens.push(token);
} else {
this.error("Unexpected " + tag);
}
prev = last(this.tokens);
plusToken = ['+', '+'];
plusToken[2] = prev[2];
tokens.push(plusToken);
if (!closed) {
this.error('missing / (unclosed regex)');
}
break;
default:
return 0;
}
tokens.pop();
if (((_ref3 = tokens[0]) != null ? _ref3[0] : void 0) !== 'STRING') {
this.token('STRING', '""', 0, 0);
this.token('+', '+', 0, 0);
flags = REGEX_FLAGS.exec(this.chunk.slice(index))[0];
end = index + flags.length;
switch (false) {
case !!VALID_FLAGS.test(flags):
this.error("invalid regular expression flags " + flags, index);
break;
case !regex:
this.token('REGEX', "" + regex + flags);
break;
case tokens.length !== 1:
re = this.formatHeregex(tokens[0][1]).replace(/\//g, '\\/');
this.token('REGEX', "/" + (re || '(?:)') + "/" + flags);
break;
default:
this.token('IDENTIFIER', 'RegExp', 0, 0);
this.token('CALL_START', '(', 0, 0);
this.mergeInterpolationTokens(tokens, {
quote: '"',
start: 3,
end: end
}, (function(_this) {
return function(value) {
return _this.formatHeregex(value).replace(/\\/g, '\\\\');
};
})(this));
if (flags) {
this.token(',', ',', index, 0);
this.token('STRING', '"' + flags + '"', index, flags.length);
}
rparen = this.token(')', ')', end, 0);
rparen.regexEnd = true;
}
(_ref4 = this.tokens).push.apply(_ref4, tokens);
if (flags) {
flagsOffset = heregex.lastIndexOf(flags);
this.token(',', ',', flagsOffset, 0);
this.token('STRING', '"' + flags + '"', flagsOffset, flags.length);
}
this.token(')', ')', heregex.length - 1, 0);
return heregex.length;
return end;
};
Lexer.prototype.lineToken = function() {
@@ -359,7 +381,9 @@
diff = size - this.indent + this.outdebt;
this.token('INDENT', diff, indent.length - size, size);
this.indents.push(diff);
this.ends.push('OUTDENT');
this.ends.push({
tag: 'OUTDENT'
});
this.outdebt = this.indebt = 0;
this.indent = size;
} else if (size < this.baseIndent) {
@@ -443,7 +467,7 @@
};
Lexer.prototype.literalToken = function() {
var match, prev, tag, value, _ref2, _ref3, _ref4, _ref5;
var match, prev, tag, token, value, _ref2, _ref3, _ref4, _ref5;
if (match = OPERATOR.exec(this.chunk)) {
value = match[0];
if (CODE.test(value)) {
@@ -482,7 +506,7 @@
} else if (__indexOf.call(LOGIC, value) >= 0 || value === '?' && (prev != null ? prev.spaced : void 0)) {
tag = 'LOGIC';
} else if (prev && !prev.spaced) {
if (value === '(' && (_ref4 = prev[0], __indexOf.call(CALLABLE, _ref4) >= 0)) {
if (value === '(' && (_ref4 = prev[0], __indexOf.call(CALLABLE, _ref4) >= 0) && !prev.stringEnd && !prev.regexEnd) {
if (prev[0] === '?') {
prev[0] = 'FUNC_EXIST';
}
@@ -495,48 +519,25 @@
}
}
}
token = this.makeToken(tag, value);
switch (value) {
case '(':
case '{':
case '[':
this.ends.push(INVERSES[value]);
this.ends.push({
tag: INVERSES[value],
origin: token
});
break;
case ')':
case '}':
case ']':
this.pair(value);
}
this.token(tag, value);
this.tokens.push(token);
return value.length;
};
Lexer.prototype.sanitizeHeredoc = function(doc, options) {
var attempt, herecomment, indent, match, _ref2;
indent = options.indent, herecomment = options.herecomment;
if (herecomment) {
if (HEREDOC_ILLEGAL.test(doc)) {
this.error("block comment cannot contain \"*/\", starting");
}
if (doc.indexOf('\n') < 0) {
return doc;
}
} else {
while (match = HEREDOC_INDENT.exec(doc)) {
attempt = match[1];
if (indent === null || (0 < (_ref2 = attempt.length) && _ref2 < indent.length)) {
indent = attempt;
}
}
}
if (indent) {
doc = doc.replace(RegExp("\\n" + indent, "g"), '\n');
}
if (!herecomment) {
doc = doc.replace(/^\n/, '');
}
return doc;
};
Lexer.prototype.tagParameters = function() {
var i, stack, tok, tokens;
if (this.tag() !== ')') {
@@ -570,113 +571,82 @@
return this.outdentToken(this.indent);
};
Lexer.prototype.balancedString = function(str, end) {
var continueCount, i, letter, match, prev, stack, _i, _ref2;
continueCount = 0;
stack = [end];
for (i = _i = 1, _ref2 = str.length; 1 <= _ref2 ? _i < _ref2 : _i > _ref2; i = 1 <= _ref2 ? ++_i : --_i) {
if (continueCount) {
--continueCount;
continue;
Lexer.prototype.matchWithInterpolations = function(str, regex, end, offsetInChunk) {
var close, column, index, line, nested, open, strPart, tokens, _ref2, _ref3, _ref4;
tokens = [];
while (true) {
strPart = regex.exec(str)[0];
tokens.push(this.makeToken('NEOSTRING', strPart, offsetInChunk));
str = str.slice(strPart.length);
offsetInChunk += strPart.length;
if (str.slice(0, 2) !== '#{') {
break;
}
switch (letter = str.charAt(i)) {
case '\\':
++continueCount;
continue;
case end:
stack.pop();
if (!stack.length) {
return str.slice(0, +i + 1 || 9e9);
}
end = stack[stack.length - 1];
continue;
_ref2 = this.getLineAndColumnFromChunk(offsetInChunk + 1), line = _ref2[0], column = _ref2[1];
_ref3 = new Lexer().tokenize(str.slice(1), {
line: line,
column: column,
untilBalanced: true
}), nested = _ref3.tokens, index = _ref3.index;
index += 1;
open = nested[0], close = nested[nested.length - 1];
open[0] = open[1] = '(';
close[0] = close[1] = ')';
close.origin = ['', 'end of interpolation', close[2]];
if (((_ref4 = nested[1]) != null ? _ref4[0] : void 0) === 'TERMINATOR') {
nested.splice(1, 1);
}
if (end === '}' && (letter === '"' || letter === "'")) {
stack.push(end = letter);
} else if (end === '}' && letter === '/' && (match = HEREGEX.exec(str.slice(i)) || REGEX.exec(str.slice(i)))) {
continueCount += match[0].length - 1;
} else if (end === '}' && letter === '{') {
stack.push(end = '}');
} else if (end === '"' && prev === '#' && letter === '{') {
stack.push(end = '}');
}
prev = letter;
tokens.push(['TOKENS', nested]);
str = str.slice(index);
offsetInChunk += index;
}
return this.error("missing " + (stack.pop()) + ", starting");
if (str.slice(0, end.length) !== end) {
this.error("missing " + end);
}
return {
tokens: tokens,
index: offsetInChunk + end.length
};
};
Lexer.prototype.interpolateString = function(str, options) {
var column, errorToken, expr, heredoc, i, inner, interpolated, len, letter, lexedLength, line, locationToken, nested, offsetInChunk, pi, plusToken, popped, regex, rparen, strOffset, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4;
if (options == null) {
options = {};
}
heredoc = options.heredoc, regex = options.regex, offsetInChunk = options.offsetInChunk, strOffset = options.strOffset, lexedLength = options.lexedLength;
offsetInChunk || (offsetInChunk = 0);
strOffset || (strOffset = 0);
lexedLength || (lexedLength = str.length);
tokens = [];
pi = 0;
i = -1;
while (letter = str.charAt(i += 1)) {
if (letter === '\\') {
i += 1;
continue;
}
if (!(letter === '#' && str.charAt(i + 1) === '{' && (expr = this.balancedString(str.slice(i + 1), '}')))) {
continue;
}
if (pi < i) {
tokens.push(this.makeToken('NEOSTRING', str.slice(pi, i), strOffset + pi));
}
if (!errorToken) {
errorToken = this.makeToken('', 'string interpolation', offsetInChunk + i + 1, 2);
}
inner = expr.slice(1, -1);
if (inner.length) {
_ref2 = this.getLineAndColumnFromChunk(strOffset + i + 2), line = _ref2[0], column = _ref2[1];
nested = new Lexer().tokenize(inner, {
line: line,
column: column,
rewrite: false
});
popped = nested.pop();
if (((_ref3 = nested[0]) != null ? _ref3[0] : void 0) === 'TERMINATOR') {
popped = nested.shift();
}
if (len = nested.length) {
if (len > 1) {
nested.unshift(this.makeToken('(', '(', strOffset + i + 1, 0));
nested.push(this.makeToken(')', ')', strOffset + i + 1 + inner.length, 0));
}
tokens.push(['TOKENS', nested]);
}
}
i += expr.length;
pi = i + 1;
}
if ((i > pi && pi < str.length)) {
tokens.push(this.makeToken('NEOSTRING', str.slice(pi), strOffset + pi));
}
if (regex) {
return tokens;
}
if (!tokens.length) {
return this.token('STRING', '""', offsetInChunk, lexedLength);
}
if (tokens[0][0] !== 'NEOSTRING') {
tokens.unshift(this.makeToken('NEOSTRING', '', offsetInChunk));
}
Lexer.prototype.mergeInterpolationTokens = function(tokens, _arg, fn) {
var converted, end, errorToken, firstEmptyStringIndex, firstIndex, i, interpolated, locationToken, plusToken, quote, rparen, start, tag, token, tokensToPush, value, _i, _len, _ref2;
quote = _arg.quote, start = _arg.start, end = _arg.end;
if (interpolated = tokens.length > 1) {
this.token('(', '(', offsetInChunk, 0, errorToken);
errorToken = this.makeToken('', 'interpolation', start + tokens[0][1].length, 2);
this.token('(', '(', 0, 0, errorToken);
}
firstIndex = this.tokens.length;
for (i = _i = 0, _len = tokens.length; _i < _len; i = ++_i) {
token = tokens[i];
tag = token[0], value = token[1];
if (i) {
if (i) {
plusToken = this.token('+', '+');
}
locationToken = tag === 'TOKENS' ? value[0] : token;
switch (tag) {
case 'TOKENS':
if (value.length === 2) {
continue;
}
locationToken = value[0];
tokensToPush = value;
break;
case 'NEOSTRING':
converted = fn(token[1], i);
if (converted.length === 0) {
if (i === 0) {
firstEmptyStringIndex = this.tokens.length;
} else {
continue;
}
}
if (i === 2 && (firstEmptyStringIndex != null)) {
this.tokens.splice(firstEmptyStringIndex, 2);
}
token[0] = 'STRING';
token[1] = this.makeString(converted, quote);
locationToken = token;
tokensToPush = [token];
}
if (this.tokens.length > firstIndex) {
plusToken = this.token('+', '+');
plusToken[2] = {
first_line: locationToken[2].first_line,
first_column: locationToken[2].first_column,
@@ -684,27 +654,17 @@
last_column: locationToken[2].first_column
};
}
if (tag === 'TOKENS') {
(_ref4 = this.tokens).push.apply(_ref4, value);
} else if (tag === 'NEOSTRING') {
token[0] = 'STRING';
token[1] = this.makeString(value, '"', heredoc);
this.tokens.push(token);
} else {
this.error("Unexpected " + tag);
}
(_ref2 = this.tokens).push.apply(_ref2, tokensToPush);
}
if (interpolated) {
rparen = this.makeToken(')', ')', offsetInChunk + lexedLength, 0);
rparen.stringEnd = true;
this.tokens.push(rparen);
rparen = this.token(')', ')', end, 0);
return rparen.stringEnd = true;
}
return tokens;
};
Lexer.prototype.pair = function(tag) {
var wanted;
if (tag !== (wanted = last(this.ends))) {
var wanted, _ref2;
if (tag !== (wanted = (_ref2 = last(this.ends)) != null ? _ref2.tag : void 0)) {
if ('OUTDENT' !== wanted) {
this.error("unmatched " + tag);
}
@@ -773,29 +733,25 @@
Lexer.prototype.unfinished = function() {
var _ref2;
return LINE_CONTINUER.test(this.chunk) || ((_ref2 = this.tag()) === '\\' || _ref2 === '.' || _ref2 === '?.' || _ref2 === '?::' || _ref2 === 'UNARY' || _ref2 === 'MATH' || _ref2 === 'UNARY_MATH' || _ref2 === '+' || _ref2 === '-' || _ref2 === '**' || _ref2 === 'SHIFT' || _ref2 === 'RELATION' || _ref2 === 'COMPARE' || _ref2 === 'LOGIC' || _ref2 === 'THROW' || _ref2 === 'EXTENDS');
return LINE_CONTINUER.test(this.chunk) || ((_ref2 = this.tag()) === '\\' || _ref2 === '.' || _ref2 === '?.' || _ref2 === '?::' || _ref2 === 'UNARY' || _ref2 === 'MATH' || _ref2 === 'UNARY_MATH' || _ref2 === '+' || _ref2 === '-' || _ref2 === 'YIELD' || _ref2 === '**' || _ref2 === 'SHIFT' || _ref2 === 'RELATION' || _ref2 === 'COMPARE' || _ref2 === 'LOGIC' || _ref2 === 'THROW' || _ref2 === 'EXTENDS');
};
Lexer.prototype.removeNewlines = function(str) {
return str.replace(/^\s*\n\s*/, '').replace(/([^\\]|\\\\)\s*\n\s*$/, '$1');
};
Lexer.prototype.escapeLines = function(str, heredoc) {
str = str.replace(/\\[^\S\n]*(\n|\\)\s*/g, function(escaped, character) {
Lexer.prototype.formatString = function(str) {
return str.replace(/\\[^\S\n]*(\n|\\)\s*/g, function(escaped, character) {
if (character === '\n') {
return '';
} else {
return escaped;
}
});
if (heredoc) {
return str.replace(MULTILINER, '\\n');
} else {
return str.replace(/\s*\n\s*/g, ' ');
}
};
Lexer.prototype.makeString = function(body, quote, heredoc) {
Lexer.prototype.formatHeregex = function(str) {
return str.replace(HEREGEX_OMIT, '$1$2').replace(MULTILINER, '\\n');
};
Lexer.prototype.makeString = function(body, quote) {
var match;
if (!body) {
return quote + quote;
}
@@ -807,7 +763,10 @@
}
});
body = body.replace(RegExp("" + quote, "g"), '\\$&');
return quote + this.escapeLines(body, heredoc) + quote;
if (match = OCTAL_ESCAPE.exec(body)) {
this.error("octal escape sequences are not allowed " + match[2], match.index + match[1].length + 1);
}
return quote + body + quote;
};
Lexer.prototype.error = function(message, offset) {
@@ -826,7 +785,7 @@
})();
JS_KEYWORDS = ['true', 'false', 'null', 'this', 'new', 'delete', 'typeof', 'in', 'instanceof', 'return', 'throw', 'break', 'continue', 'debugger', 'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally', 'class', 'extends', 'super'];
JS_KEYWORDS = ['true', 'false', 'null', 'this', 'new', 'delete', 'typeof', 'in', 'instanceof', 'return', 'throw', 'break', 'continue', 'debugger', 'yield', 'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally', 'class', 'extends', 'super'];
COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when'];
@@ -853,9 +812,9 @@
COFFEE_KEYWORDS = COFFEE_KEYWORDS.concat(COFFEE_ALIASES);
RESERVED = ['case', 'default', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', '__hasProp', '__extends', '__slice', '__bind', '__indexOf', 'implements', 'interface', 'package', 'private', 'protected', 'public', 'static', 'yield'];
RESERVED = ['case', 'default', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', 'implements', 'interface', 'package', 'private', 'protected', 'public', 'static'];
STRICT_PROSCRIBED = ['arguments', 'eval'];
STRICT_PROSCRIBED = ['arguments', 'eval', 'yield*'];
JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED).concat(STRICT_PROSCRIBED);
@@ -865,12 +824,10 @@
BOM = 65279;
IDENTIFIER = /^([$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)([^\n\S]*:(?!:))?/;
IDENTIFIER = /^(?!\d)((?:(?!\s)[$\w\x7f-\uffff])+)([^\n\S]*:(?!:))?/;
NUMBER = /^0b[01]+|^0o[0-7]+|^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i;
HEREDOC = /^("""|''')((?:\\[\s\S]|[^\\])*?)(?:\n[^\n\S]*)?\1/;
OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>*\/%])\2=?|\?(\.|::)|\.{2,3})/;
WHITESPACE = /^[^\n\S]+/;
@@ -881,24 +838,48 @@
MULTI_DENT = /^(?:\n[^\n\S]*)+/;
SIMPLESTR = /^'[^\\']*(?:\\[\s\S][^\\']*)*'/;
JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/;
REGEX = /^(\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)([imgy]{0,4})(?!\w)/;
STRING_START = /^(?:'''|"""|'|")/;
HEREGEX = /^\/{3}((?:\\?[\s\S])+?)\/{3}([imgy]{0,4})(?!\w)/;
STRING_SINGLE = /^(?:[^\\']|\\[\s\S])*/;
STRING_DOUBLE = /^(?:[^\\"#]|\\[\s\S]|\#(?!\{))*/;
HEREDOC_SINGLE = /^(?:[^\\']|\\[\s\S]|'(?!''))*/;
HEREDOC_DOUBLE = /^(?:[^\\"#]|\\[\s\S]|"(?!"")|\#(?!\{))*/;
STRING_OMIT = /\s*\n\s*/g;
HEREDOC_INDENT = /\n+([^\n\S]*)(?=\S)/g;
REGEX = /^\/(?!\/)(?:[^[\/\n\\]|\\.|\[(?:\\.|[^\]\n\\])*])*(\/)?/;
REGEX_FLAGS = /^\w*/;
VALID_FLAGS = /^(?!.*(.).*\1)[imgy]*$/;
HEREGEX = /^(?:[^\\\/#]|\\[\s\S]|\/(?!\/\/)|\#(?!\{))*/;
HEREGEX_OMIT = /((?:\\\\)+)|\\(\s|\/)|\s+(?:#.*)?/g;
REGEX_ILLEGAL = /^(\/|\/{3}\s*)(\*)/;
POSSIBLY_DIVISION = /^\/=?\s/;
MULTILINER = /\n/g;
HEREDOC_INDENT = /\n+([^\n\S]*)/g;
HEREDOC_ILLEGAL = /\*\//;
HERECOMMENT_ILLEGAL = /\*\//;
LINE_CONTINUER = /^\s*(?:,|\??\.(?![.\d])|::)/;
OCTAL_ESCAPE = /^((?:\\.|[^\\])*)(\\(?:0[0-7]|[1-7]))/;
LEADING_BLANK_LINE = /^[^\n\S]*\n/;
TRAILING_BLANK_LINE = /\n[^\n\S]*$/;
TRAILING_SPACES = /\s+$/;
COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|=', '**=', '//=', '%%='];
@@ -919,13 +900,11 @@
BOOL = ['TRUE', 'FALSE'];
NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', 'NULL', 'UNDEFINED', '++', '--'];
CALLABLE = ['IDENTIFIER', ')', ']', '?', '@', 'THIS', 'SUPER'];
NOT_SPACED_REGEX = NOT_REGEX.concat(')', '}', 'THIS', 'IDENTIFIER', 'STRING', ']');
INDEXABLE = CALLABLE.concat(['NUMBER', 'STRING', 'REGEX', 'BOOL', 'NULL', 'UNDEFINED', '}', '::']);
CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER'];
INDEXABLE = CALLABLE.concat('NUMBER', 'BOOL', 'NULL', 'UNDEFINED');
NOT_REGEX = INDEXABLE.concat(['++', '--']);
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'];

View File

@@ -1,8 +1,8 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
(function() {
var Access, Arr, Assign, Base, Block, Call, Class, Code, CodeFragment, Comment, Existence, Expansion, Extends, For, HEXNUM, IDENTIFIER, IDENTIFIER_STR, IS_REGEX, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, NUMBER, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, STRICT_PROSCRIBED, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, addLocationDataFn, compact, del, ends, extend, flatten, fragmentsToText, isLiteralArguments, isLiteralThis, last, locationDataToString, merge, multident, parseNum, some, starts, throwSyntaxError, unfoldSoak, utility, _ref, _ref1,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
__hasProp = {}.hasOwnProperty,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
__slice = [].slice;
@@ -87,7 +87,7 @@
};
Base.prototype.compileClosure = function(o) {
var args, argumentsNode, func, jumpNode, meth;
var args, argumentsNode, func, jumpNode, meth, parts;
if (jumpNode = this.jumps()) {
jumpNode.error('cannot use a pure statement in an expression');
}
@@ -104,7 +104,12 @@
}
func = new Value(func, [new Access(new Literal(meth))]);
}
return (new Call(func, args)).compileNode(o);
parts = (new Call(func, args)).compileNode(o);
if (func.isGenerator) {
parts.unshift(this.makeCode("(yield* "));
parts.push(this.makeCode(")"));
}
return parts;
};
Base.prototype.cache = function(o, level, reused) {
@@ -131,7 +136,7 @@
var me;
me = this.unwrapAll();
if (res) {
return new Call(new Literal("" + res + ".push"), [me]);
return new Call(new Literal(res + ".push"), [me]);
} else {
return new Return(me);
}
@@ -408,24 +413,24 @@
};
Block.prototype.compileRoot = function(o) {
var exp, fragments, i, name, prelude, preludeExps, rest, _i, _len, _ref2;
var exp, fragments, i, name, prelude, preludeExps, rest, _i, _len, _ref2, _ref3;
o.indent = o.bare ? '' : TAB;
o.level = LEVEL_TOP;
this.spaced = true;
o.scope = new Scope(null, this, null);
_ref2 = o.locals || [];
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
name = _ref2[_i];
o.scope = new Scope(null, this, null, (_ref2 = o.referencedVars) != null ? _ref2 : []);
_ref3 = o.locals || [];
for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
name = _ref3[_i];
o.scope.parameter(name);
}
prelude = [];
if (!o.bare) {
preludeExps = (function() {
var _j, _len1, _ref3, _results;
_ref3 = this.expressions;
var _j, _len1, _ref4, _results;
_ref4 = this.expressions;
_results = [];
for (i = _j = 0, _len1 = _ref3.length; _j < _len1; i = ++_j) {
exp = _ref3[i];
for (i = _j = 0, _len1 = _ref4.length; _j < _len1; i = ++_j) {
exp = _ref4[i];
if (!(exp.unwrap() instanceof Comment)) {
break;
}
@@ -480,7 +485,7 @@
if (i) {
fragments.push(this.makeCode('\n'));
}
fragments.push(this.makeCode("" + this.tab + "var "));
fragments.push(this.makeCode(this.tab + "var "));
if (declars) {
fragments.push(this.makeCode(scope.declaredVariables().join(', ')));
}
@@ -512,8 +517,8 @@
exports.Literal = Literal = (function(_super) {
__extends(Literal, _super);
function Literal(value) {
this.value = value;
function Literal(_at_value) {
this.value = _at_value;
}
Literal.prototype.makeReturn = function() {
@@ -612,8 +617,8 @@
return [this.makeCode(this.val)];
};
function Bool(val) {
this.val = val;
function Bool(_at_val) {
this.val = _at_val;
}
return Bool;
@@ -623,8 +628,8 @@
exports.Return = Return = (function(_super) {
__extends(Return, _super);
function Return(expression) {
this.expression = expression;
function Return(_at_expression) {
this.expression = _at_expression;
}
Return.prototype.children = ['expression'];
@@ -845,8 +850,8 @@
exports.Comment = Comment = (function(_super) {
__extends(Comment, _super);
function Comment(comment) {
this.comment = comment;
function Comment(_at_comment) {
this.comment = _at_comment;
}
Comment.prototype.isStatement = YES;
@@ -855,7 +860,7 @@
Comment.prototype.compileNode = function(o, level) {
var code, comment;
comment = this.comment.replace(/^(\s*)#/gm, "$1 *");
comment = this.comment.replace(/^(\s*)# /gm, "$1 * ");
code = "/*" + (multident(comment, this.tab)) + (__indexOf.call(comment, '\n') >= 0 ? "\n" + this.tab : '') + " */";
if ((level || o.level) === LEVEL_TOP) {
code = o.indent + code;
@@ -870,9 +875,9 @@
exports.Call = Call = (function(_super) {
__extends(Call, _super);
function Call(variable, args, soak) {
this.args = args != null ? args : [];
this.soak = soak;
function Call(variable, _at_args, _at_soak) {
this.args = _at_args != null ? _at_args : [];
this.soak = _at_soak;
this.isNew = false;
this.isSuper = variable === 'super';
this.variable = this.isSuper ? null : variable;
@@ -905,7 +910,7 @@
accesses.push(new Access(new Literal(method.name)));
return (new Value(new Literal(method.klass), accesses)).compile(o);
} else if (method != null ? method.ctor : void 0) {
return "" + method.name + ".__super__.constructor";
return method.name + ".__super__.constructor";
} else {
return this.error('cannot call super outside of an instance method.');
}
@@ -1007,7 +1012,7 @@
Call.prototype.compileSplat = function(o, splatArgs) {
var answer, base, fun, idt, name, ref;
if (this.isSuper) {
return [].concat(this.makeCode("" + (this.superReference(o)) + ".apply(" + (this.superThis(o)) + ", "), splatArgs, this.makeCode(")"));
return [].concat(this.makeCode((this.superReference(o)) + ".apply(" + (this.superThis(o)) + ", "), splatArgs, this.makeCode(")"));
}
if (this.isNew) {
idt = this.tab + TAB;
@@ -1041,15 +1046,15 @@
exports.Extends = Extends = (function(_super) {
__extends(Extends, _super);
function Extends(child, parent) {
this.child = child;
this.parent = parent;
function Extends(_at_child, _at_parent) {
this.child = _at_child;
this.parent = _at_parent;
}
Extends.prototype.children = ['child', 'parent'];
Extends.prototype.compileToFragments = function(o) {
return new Call(new Value(new Literal(utility('extends'))), [this.child, this.parent]).compileToFragments(o);
return new Call(new Value(new Literal(utility('extends', o))), [this.child, this.parent]).compileToFragments(o);
};
return Extends;
@@ -1059,8 +1064,8 @@
exports.Access = Access = (function(_super) {
__extends(Access, _super);
function Access(name, tag) {
this.name = name;
function Access(_at_name, tag) {
this.name = _at_name;
this.name.asKey = true;
this.soak = tag === 'soak';
}
@@ -1088,8 +1093,8 @@
exports.Index = Index = (function(_super) {
__extends(Index, _super);
function Index(index) {
this.index = index;
function Index(_at_index) {
this.index = _at_index;
}
Index.prototype.children = ['index'];
@@ -1111,9 +1116,9 @@
Range.prototype.children = ['from', 'to'];
function Range(from, to, tag) {
this.from = from;
this.to = to;
function Range(_at_from, _at_to, tag) {
this.from = _at_from;
this.to = _at_to;
this.exclusive = tag === 'exclusive';
this.equals = this.exclusive ? '' : '=';
}
@@ -1146,23 +1151,23 @@
idx = del(o, 'index');
idxName = del(o, 'name');
namedIndex = idxName && idxName !== idx;
varPart = "" + idx + " = " + this.fromC;
varPart = idx + " = " + this.fromC;
if (this.toC !== this.toVar) {
varPart += ", " + this.toC;
}
if (this.step !== this.stepVar) {
varPart += ", " + this.step;
}
_ref2 = ["" + idx + " <" + this.equals, "" + idx + " >" + this.equals], lt = _ref2[0], gt = _ref2[1];
condPart = this.stepNum ? parseNum(this.stepNum[0]) > 0 ? "" + lt + " " + this.toVar : "" + gt + " " + this.toVar : known ? ((_ref3 = [parseNum(this.fromNum[0]), parseNum(this.toNum[0])], from = _ref3[0], to = _ref3[1], _ref3), from <= to ? "" + lt + " " + to : "" + gt + " " + to) : (cond = this.stepVar ? "" + this.stepVar + " > 0" : "" + this.fromVar + " <= " + this.toVar, "" + cond + " ? " + lt + " " + this.toVar + " : " + gt + " " + this.toVar);
stepPart = this.stepVar ? "" + idx + " += " + this.stepVar : known ? namedIndex ? from <= to ? "++" + idx : "--" + idx : from <= to ? "" + idx + "++" : "" + idx + "--" : namedIndex ? "" + cond + " ? ++" + idx + " : --" + idx : "" + cond + " ? " + idx + "++ : " + idx + "--";
_ref2 = [idx + " <" + this.equals, idx + " >" + this.equals], lt = _ref2[0], gt = _ref2[1];
condPart = this.stepNum ? parseNum(this.stepNum[0]) > 0 ? lt + " " + this.toVar : gt + " " + this.toVar : known ? ((_ref3 = [parseNum(this.fromNum[0]), parseNum(this.toNum[0])], from = _ref3[0], to = _ref3[1], _ref3), from <= to ? lt + " " + to : gt + " " + to) : (cond = this.stepVar ? this.stepVar + " > 0" : this.fromVar + " <= " + this.toVar, cond + " ? " + lt + " " + this.toVar + " : " + gt + " " + this.toVar);
stepPart = this.stepVar ? idx + " += " + this.stepVar : known ? namedIndex ? from <= to ? "++" + idx : "--" + idx : from <= to ? idx + "++" : idx + "--" : namedIndex ? cond + " ? ++" + idx + " : --" + idx : cond + " ? " + idx + "++ : " + idx + "--";
if (namedIndex) {
varPart = "" + idxName + " = " + varPart;
varPart = idxName + " = " + varPart;
}
if (namedIndex) {
stepPart = "" + idxName + " = " + stepPart;
stepPart = idxName + " = " + stepPart;
}
return [this.makeCode("" + varPart + "; " + condPart + "; " + stepPart)];
return [this.makeCode(varPart + "; " + condPart + "; " + stepPart)];
};
Range.prototype.compileArray = function(o) {
@@ -1186,8 +1191,8 @@
o.index = i;
body = fragmentsToText(this.compileNode(o));
} else {
vars = ("" + i + " = " + this.fromC) + (this.toC !== this.toVar ? ", " + this.toC : '');
cond = "" + this.fromVar + " <= " + this.toVar;
vars = (i + " = " + this.fromC) + (this.toC !== this.toVar ? ", " + this.toC : '');
cond = this.fromVar + " <= " + this.toVar;
body = "var " + vars + "; " + cond + " ? " + i + " <" + this.equals + " " + this.toVar + " : " + i + " >" + this.equals + " " + this.toVar + "; " + cond + " ? " + i + "++ : " + i + "--";
}
post = "{ " + result + ".push(" + i + "); }\n" + idt + "return " + result + ";\n" + o.indent;
@@ -1209,8 +1214,8 @@
Slice.prototype.children = ['range'];
function Slice(range) {
this.range = range;
function Slice(_at_range) {
this.range = _at_range;
Slice.__super__.constructor.call(this);
}
@@ -1235,8 +1240,8 @@
exports.Obj = Obj = (function(_super) {
__extends(Obj, _super);
function Obj(props, generated) {
this.generated = generated != null ? generated : false;
function Obj(props, _at_generated) {
this.generated = _at_generated != null ? _at_generated : false;
this.objects = this.properties = props || [];
}
@@ -1284,7 +1289,7 @@
}
}
answer.unshift(this.makeCode("{" + (props.length && '\n')));
answer.push(this.makeCode("" + (props.length && '\n' + this.tab) + "}"));
answer.push(this.makeCode((props.length && '\n' + this.tab) + "}"));
if (this.front) {
return this.wrapInBraces(answer);
} else {
@@ -1374,10 +1379,10 @@
exports.Class = Class = (function(_super) {
__extends(Class, _super);
function Class(variable, parent, body) {
this.variable = variable;
this.parent = parent;
this.body = body != null ? body : new Block;
function Class(_at_variable, _at_parent, _at_body) {
this.variable = _at_variable;
this.parent = _at_parent;
this.body = _at_body != null ? _at_body : new Block;
this.boundFuncs = [];
this.body.classBody = true;
}
@@ -1418,7 +1423,7 @@
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
bvar = _ref2[_i];
lhs = (new Value(new Literal("this"), [new Access(bvar)])).compile(o);
this.ctor.body.unshift(new Literal("" + lhs + " = " + (utility('bind')) + "(" + lhs + ", this)"));
this.ctor.body.unshift(new Literal(lhs + " = " + (utility('bind', o)) + "(" + lhs + ", this)"));
}
};
@@ -1505,9 +1510,9 @@
if (!this.ctor) {
this.ctor = new Code;
if (this.externalCtor) {
this.ctor.body.push(new Literal("" + this.externalCtor + ".apply(this, arguments)"));
this.ctor.body.push(new Literal(this.externalCtor + ".apply(this, arguments)"));
} else if (this.parent) {
this.ctor.body.push(new Literal("" + name + ".__super__.constructor.apply(this, arguments)"));
this.ctor.body.push(new Literal(name + ".__super__.constructor.apply(this, arguments)"));
}
this.ctor.body.makeReturn();
this.body.expressions.unshift(this.ctor);
@@ -1561,11 +1566,11 @@
exports.Assign = Assign = (function(_super) {
__extends(Assign, _super);
function Assign(variable, value, context, options) {
function Assign(_at_variable, _at_value, _at_context, options) {
var forbidden, name, _ref2;
this.variable = variable;
this.value = value;
this.context = context;
this.variable = _at_variable;
this.value = _at_value;
this.context = _at_context;
this.param = options && options.param;
this.subpattern = options && options.subpattern;
forbidden = (_ref2 = (name = this.variable.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0);
@@ -1672,7 +1677,7 @@
assigns = [];
expandedIdx = false;
if (!IDENTIFIER.test(vvarText) || this.variable.assigns(vvarText)) {
assigns.push([this.makeCode("" + (ref = o.scope.freeVariable('ref')) + " = ")].concat(__slice.call(vvar)));
assigns.push([this.makeCode((ref = o.scope.freeVariable('ref')) + " = ")].concat(__slice.call(vvar)));
vvar = [this.makeCode(ref)];
vvarText = ref;
}
@@ -1693,7 +1698,7 @@
if (!expandedIdx && obj instanceof Splat) {
name = obj.name.unwrap().value;
obj = obj.unwrap();
val = "" + olen + " <= " + vvarText + ".length ? " + (utility('slice')) + ".call(" + vvarText + ", " + i;
val = olen + " <= " + vvarText + ".length ? " + (utility('slice', o)) + ".call(" + vvarText + ", " + i;
if (rest = olen - i - 1) {
ivar = o.scope.freeVariable('i');
val += ", " + ivar + " = " + vvarText + ".length - " + rest + ") : (" + ivar + " = " + i + ", [])";
@@ -1701,15 +1706,15 @@
val += ") : []";
}
val = new Literal(val);
expandedIdx = "" + ivar + "++";
expandedIdx = ivar + "++";
} else if (!expandedIdx && obj instanceof Expansion) {
if (rest = olen - i - 1) {
if (rest === 1) {
expandedIdx = "" + vvarText + ".length - 1";
expandedIdx = vvarText + ".length - 1";
} else {
ivar = o.scope.freeVariable('i');
val = new Literal("" + ivar + " = " + vvarText + ".length - " + rest);
expandedIdx = "" + ivar + "++";
val = new Literal(ivar + " = " + vvarText + ".length - " + rest);
expandedIdx = ivar + "++";
assigns.push(val.compileToFragments(o, LEVEL_LIST));
}
}
@@ -1817,6 +1822,10 @@
this.params = params || [];
this.body = body || new Block;
this.bound = tag === 'boundfunc';
this.isGenerator = !!this.body.contains(function(node) {
var _ref2;
return node instanceof Op && ((_ref2 = node.operator) === 'yield' || _ref2 === 'yield*');
});
}
Code.prototype.children = ['params', 'body'];
@@ -1865,15 +1874,9 @@
}
_ref5 = this.params;
for (_k = 0, _len2 = _ref5.length; _k < _len2; _k++) {
p = _ref5[_k].name;
if (!(!(param instanceof Expansion))) {
continue;
}
if (p["this"]) {
p = p.properties[0].name;
}
if (p.value) {
o.scope.add(p.value, 'var', true);
p = _ref5[_k];
if (!(p instanceof Expansion) && p.name.value) {
o.scope.add(p.name.value, 'var', true);
}
}
splats = new Assign(new Value(new Arr((function() {
@@ -1926,7 +1929,7 @@
uniqs = [];
this.eachParamName(function(name, node) {
if (__indexOf.call(uniqs, name) >= 0) {
node.error("multiple parameters named '" + name + "'");
node.error("multiple parameters named " + name);
}
return uniqs.push(name);
});
@@ -1934,6 +1937,9 @@
this.body.makeReturn();
}
code = 'function';
if (this.isGenerator) {
code += '*';
}
if (this.ctor) {
code += ' ' + this.name;
}
@@ -1985,11 +1991,11 @@
exports.Param = Param = (function(_super) {
__extends(Param, _super);
function Param(name, value, splat) {
var _ref2;
this.name = name;
this.value = value;
this.splat = splat;
function Param(_at_name, _at_value, _at_splat) {
var name, _ref2;
this.name = _at_name;
this.value = _at_value;
this.splat = _at_splat;
if (_ref2 = (name = this.name.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0) {
this.name.error("parameter name \"" + name + "\" is not allowed");
}
@@ -2002,16 +2008,14 @@
};
Param.prototype.asReference = function(o) {
var node;
var name, node;
if (this.reference) {
return this.reference;
}
node = this.name;
if (node["this"]) {
node = node.properties[0].name;
if (node.value.reserved) {
node = new Literal(o.scope.freeVariable(node.value));
}
name = "at_" + node.properties[0].name.value;
node = new Literal(o.scope.freeVariable(name));
} else if (node.isComplex()) {
node = new Literal(o.scope.freeVariable('arg'));
}
@@ -2033,11 +2037,7 @@
name = this.name;
}
atParam = function(obj) {
var node;
node = obj.properties[0].name;
if (!node.value.reserved) {
return iterator(node.value, node);
}
return iterator("@" + obj.properties[0].name.value, obj);
};
if (name instanceof Literal) {
return iterator(name.value, name);
@@ -2109,13 +2109,13 @@
if (apply) {
return fragments;
}
return [].concat(node.makeCode("" + (utility('slice')) + ".call("), fragments, node.makeCode(")"));
return [].concat(node.makeCode((utility('slice', o)) + ".call("), fragments, node.makeCode(")"));
}
args = list.slice(index);
for (i = _i = 0, _len = args.length; _i < _len; i = ++_i) {
node = args[i];
compiledNode = node.compileToFragments(o, LEVEL_LIST);
args[i] = node instanceof Splat ? [].concat(node.makeCode("" + (utility('slice')) + ".call("), compiledNode, node.makeCode(")")) : [].concat(node.makeCode("["), compiledNode, node.makeCode("]"));
args[i] = node instanceof Splat ? [].concat(node.makeCode((utility('slice', o)) + ".call("), compiledNode, node.makeCode(")")) : [].concat(node.makeCode("["), compiledNode, node.makeCode("]"));
}
if (index === 0) {
node = list[0];
@@ -2187,8 +2187,8 @@
}
};
While.prototype.addBody = function(body) {
this.body = body;
While.prototype.addBody = function(_at_body) {
this.body = _at_body;
return this;
};
@@ -2273,7 +2273,8 @@
CONVERSIONS = {
'==': '===',
'!=': '!==',
'of': 'in'
'of': 'in',
'yieldfrom': 'yield*'
};
INVERSIONS = {
@@ -2285,13 +2286,18 @@
Op.prototype.isSimpleNumber = NO;
Op.prototype.isYield = function() {
var _ref2;
return (_ref2 = this.operator) === 'yield' || _ref2 === 'yield*';
};
Op.prototype.isUnary = function() {
return !this.second;
};
Op.prototype.isComplex = function() {
var _ref2;
return !(this.isUnary() && ((_ref2 = this.operator) === '+' || _ref2 === '-')) || this.first.isComplex();
return !(this.isUnary() && ((_ref2 = this.operator) === '+' || _ref2 === '-') && this.first instanceof Value && this.first.isSimpleNumber());
};
Op.prototype.isChainable = function() {
@@ -2369,6 +2375,9 @@
if (((_ref2 = this.operator) === '--' || _ref2 === '++') && (_ref3 = this.first.unwrapAll().value, __indexOf.call(STRICT_PROSCRIBED, _ref3) >= 0)) {
this.error("cannot increment/decrement \"" + (this.first.unwrapAll().value) + "\"");
}
if (this.isYield()) {
return this.compileYield(o);
}
if (this.isUnary()) {
return this.compileUnary(o);
}
@@ -2444,6 +2453,25 @@
return this.joinFragmentArrays(parts, '');
};
Op.prototype.compileYield = function(o) {
var op, parts;
parts = [];
op = this.operator;
if (o.scope.parent == null) {
this.error('yield statements must occur within a function generator.');
}
if (__indexOf.call(Object.keys(this.first), 'expression') >= 0) {
if (this.first.expression != null) {
parts.push(this.first.expression.compileToFragments(o, LEVEL_OP));
}
} else {
parts.push([this.makeCode("(" + op + " ")]);
parts.push(this.first.compileToFragments(o, LEVEL_OP));
parts.push([this.makeCode(")")]);
}
return this.joinFragmentArrays(parts, '');
};
Op.prototype.compilePower = function(o) {
var pow;
pow = new Value(new Literal('Math'), [new Access(new Literal('pow'))]);
@@ -2459,7 +2487,7 @@
Op.prototype.compileModulo = function(o) {
var mod;
mod = new Value(new Literal(utility('modulo')));
mod = new Value(new Literal(utility('modulo', o)));
return new Call(mod, [this.first, this.second]).compileToFragments(o);
};
@@ -2474,9 +2502,9 @@
exports.In = In = (function(_super) {
__extends(In, _super);
function In(object, array) {
this.object = object;
this.array = array;
function In(_at_object, _at_array) {
this.object = _at_object;
this.array = _at_array;
}
In.prototype.children = ['object', 'array'];
@@ -2525,7 +2553,7 @@
In.prototype.compileLoopTest = function(o) {
var fragments, ref, sub, _ref2;
_ref2 = this.object.cache(o, LEVEL_LIST), sub = _ref2[0], ref = _ref2[1];
fragments = [].concat(this.makeCode(utility('indexOf') + ".call("), this.array.compileToFragments(o, LEVEL_LIST), this.makeCode(", "), ref, this.makeCode(") " + (this.negated ? '< 0' : '>= 0')));
fragments = [].concat(this.makeCode(utility('indexOf', o) + ".call("), this.array.compileToFragments(o, LEVEL_LIST), this.makeCode(", "), ref, this.makeCode(") " + (this.negated ? '< 0' : '>= 0')));
if (fragmentsToText(sub) === fragmentsToText(ref)) {
return fragments;
}
@@ -2548,11 +2576,11 @@
exports.Try = Try = (function(_super) {
__extends(Try, _super);
function Try(attempt, errorVariable, recovery, ensure) {
this.attempt = attempt;
this.errorVariable = errorVariable;
this.recovery = recovery;
this.ensure = ensure;
function Try(_at_attempt, _at_errorVariable, _at_recovery, _at_ensure) {
this.attempt = _at_attempt;
this.errorVariable = _at_errorVariable;
this.recovery = _at_recovery;
this.ensure = _at_ensure;
}
Try.prototype.children = ['attempt', 'recovery', 'ensure'];
@@ -2580,7 +2608,7 @@
tryPart = this.attempt.compileToFragments(o, LEVEL_TOP);
catchPart = this.recovery ? (placeholder = new Literal('_error'), this.errorVariable ? this.recovery.unshift(new Assign(this.errorVariable, placeholder)) : void 0, [].concat(this.makeCode(" catch ("), placeholder.compileToFragments(o), this.makeCode(") {\n"), this.recovery.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab + "}"))) : !(this.ensure || this.recovery) ? [this.makeCode(' catch (_error) {}')] : [];
ensurePart = this.ensure ? [].concat(this.makeCode(" finally {\n"), this.ensure.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab + "}")) : [];
return [].concat(this.makeCode("" + this.tab + "try {\n"), tryPart, this.makeCode("\n" + this.tab + "}"), catchPart, ensurePart);
return [].concat(this.makeCode(this.tab + "try {\n"), tryPart, this.makeCode("\n" + this.tab + "}"), catchPart, ensurePart);
};
return Try;
@@ -2590,8 +2618,8 @@
exports.Throw = Throw = (function(_super) {
__extends(Throw, _super);
function Throw(expression) {
this.expression = expression;
function Throw(_at_expression) {
this.expression = _at_expression;
}
Throw.prototype.children = ['expression'];
@@ -2613,8 +2641,8 @@
exports.Existence = Existence = (function(_super) {
__extends(Existence, _super);
function Existence(expression) {
this.expression = expression;
function Existence(_at_expression) {
this.expression = _at_expression;
}
Existence.prototype.children = ['expression'];
@@ -2629,7 +2657,7 @@
_ref2 = this.negated ? ['===', '||'] : ['!==', '&&'], cmp = _ref2[0], cnj = _ref2[1];
code = "typeof " + code + " " + cmp + " \"undefined\" " + cnj + " " + code + " " + cmp + " null";
} else {
code = "" + code + " " + (this.negated ? '==' : '!=') + " null";
code = code + " " + (this.negated ? '==' : '!=') + " null";
}
return [this.makeCode(o.level <= LEVEL_COND ? code : "(" + code + ")")];
};
@@ -2641,8 +2669,8 @@
exports.Parens = Parens = (function(_super) {
__extends(Parens, _super);
function Parens(body) {
this.body = body;
function Parens(_at_body) {
this.body = _at_body;
}
Parens.prototype.children = ['body'];
@@ -2730,7 +2758,7 @@
}
ivar = (this.object && index) || scope.freeVariable('i');
kvar = (this.range && name) || index || ivar;
kvarAssign = kvar !== ivar ? "" + kvar + " = " : "";
kvarAssign = kvar !== ivar ? kvar + " = " : "";
if (this.step && !this.range) {
_ref3 = this.cacheToCodeFragments(this.step.cache(o, LEVEL_LIST)), step = _ref3[0], stepVar = _ref3[1];
stepNum = stepVar.match(NUMBER);
@@ -2755,7 +2783,7 @@
svar = ref;
}
if (name && !this.pattern) {
namePart = "" + name + " = " + svar + "[" + kvar + "]";
namePart = name + " = " + svar + "[" + kvar + "]";
}
if (!this.object) {
if (step !== stepVar) {
@@ -2766,8 +2794,8 @@
}
declare = "" + kvarAssign + ivar + " = 0, " + lvar + " = " + svar + ".length";
declareDown = "" + kvarAssign + ivar + " = " + svar + ".length - 1";
compare = "" + ivar + " < " + lvar;
compareDown = "" + ivar + " >= 0";
compare = ivar + " < " + lvar;
compareDown = ivar + " >= 0";
if (this.step) {
if (stepNum) {
if (down) {
@@ -2775,14 +2803,14 @@
declare = declareDown;
}
} else {
compare = "" + stepVar + " > 0 ? " + compare + " : " + compareDown;
compare = stepVar + " > 0 ? " + compare + " : " + compareDown;
declare = "(" + stepVar + " > 0 ? (" + declare + ") : " + declareDown + ")";
}
increment = "" + ivar + " += " + stepVar;
increment = ivar + " += " + stepVar;
} else {
increment = "" + (kvar !== ivar ? "++" + ivar : "" + ivar + "++");
increment = "" + (kvar !== ivar ? "++" + ivar : ivar + "++");
}
forPartFragments = [this.makeCode("" + declare + "; " + compare + "; " + kvarAssign + increment)];
forPartFragments = [this.makeCode(declare + "; " + compare + "; " + kvarAssign + increment)];
}
}
if (this.returns) {
@@ -2800,16 +2828,16 @@
}
}
if (this.pattern) {
body.expressions.unshift(new Assign(this.name, new Literal("" + svar + "[" + kvar + "]")));
body.expressions.unshift(new Assign(this.name, new Literal(svar + "[" + kvar + "]")));
}
defPartFragments = [].concat(this.makeCode(defPart), this.pluckDirectCall(o, body));
if (namePart) {
varPart = "\n" + idt1 + namePart + ";";
}
if (this.object) {
forPartFragments = [this.makeCode("" + kvar + " in " + svar)];
forPartFragments = [this.makeCode(kvar + " in " + svar)];
if (this.own) {
guardPart = "\n" + idt1 + "if (!" + (utility('hasProp')) + ".call(" + svar + ", " + kvar + ")) continue;";
guardPart = "\n" + idt1 + "if (!" + (utility('hasProp', o)) + ".call(" + svar + ", " + kvar + ")) continue;";
}
}
bodyFragments = body.compileToFragments(merge(o, {
@@ -2818,7 +2846,7 @@
if (bodyFragments && (bodyFragments.length > 0)) {
bodyFragments = [].concat(this.makeCode("\n"), bodyFragments, this.makeCode("\n"));
}
return [].concat(defPartFragments, this.makeCode("" + (resultPart || '') + this.tab + "for ("), forPartFragments, this.makeCode(") {" + guardPart + varPart), bodyFragments, this.makeCode("" + this.tab + "}" + (returnResult || '')));
return [].concat(defPartFragments, this.makeCode("" + (resultPart || '') + this.tab + "for ("), forPartFragments, this.makeCode(") {" + guardPart + varPart), bodyFragments, this.makeCode(this.tab + "}" + (returnResult || '')));
};
For.prototype.pluckDirectCall = function(o, body) {
@@ -2854,10 +2882,10 @@
exports.Switch = Switch = (function(_super) {
__extends(Switch, _super);
function Switch(subject, cases, otherwise) {
this.subject = subject;
this.cases = cases;
this.otherwise = otherwise;
function Switch(_at_subject, _at_cases, _at_otherwise) {
this.subject = _at_subject;
this.cases = _at_cases;
this.otherwise = _at_otherwise;
}
Switch.prototype.children = ['subject', 'cases', 'otherwise'];
@@ -2939,8 +2967,8 @@
exports.If = If = (function(_super) {
__extends(If, _super);
function If(condition, body, options) {
this.body = body;
function If(condition, _at_body, options) {
this.body = _at_body;
if (options == null) {
options = {};
}
@@ -3063,8 +3091,8 @@
})(Base);
UTILITIES = {
"extends": function() {
return "function(child, parent) { for (var key in parent) { if (" + (utility('hasProp')) + ".call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }";
"extends": function(o) {
return "function(child, parent) { for (var key in parent) { if (" + (utility('hasProp', o)) + ".call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }";
},
bind: function() {
return 'function(fn, me){ return function(){ return fn.apply(me, arguments); }; }';
@@ -3113,11 +3141,16 @@
IS_REGEX = /^\//;
utility = function(name) {
var ref;
ref = "__" + name;
Scope.root.assign(ref, UTILITIES[name]());
return ref;
utility = function(name, o) {
var ref, root;
root = o.scope.root;
if (name in root.utilities) {
return root.utilities[name];
} else {
ref = root.freeVariable("_" + name);
root.assign(ref, UTILITIES[name](o));
return root.utilities[name] = ref;
}
};
multident = function(code, tab) {

View File

@@ -1,12 +1,12 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
(function() {
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments, repeat;
repeat = require('./helpers').repeat;
exports.OptionParser = OptionParser = (function() {
function OptionParser(rules, banner) {
this.banner = banner;
function OptionParser(rules, _at_banner) {
this.banner = _at_banner;
this.rules = buildRules(rules);
}
@@ -62,7 +62,7 @@
var letPart, lines, rule, spaces, _i, _len, _ref;
lines = [];
if (this.banner) {
lines.unshift("" + this.banner + "\n");
lines.unshift(this.banner + "\n");
}
_ref = this.rules;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
(function() {
var CoffeeScript, Module, binary, child_process, ext, findExtension, fork, helpers, loadFile, path, _i, _len, _ref;

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
(function() {
var CoffeeScript, addHistory, addMultilineHandler, fs, getCommandId, merge, nodeREPL, path, replDefaults, updateSyntaxError, vm, _ref;
@@ -19,16 +19,29 @@
historyFile: process.env.HOME ? path.join(process.env.HOME, '.coffee_history') : void 0,
historyMaxInputSize: 10240,
"eval": function(input, context, filename, cb) {
var Assign, Block, Literal, Value, ast, err, js, result, _ref1;
var Assign, Block, Literal, Value, ast, err, js, referencedVars, result, token, tokens, _ref1;
input = input.replace(/\uFF00/g, '\n');
input = input.replace(/^\(([\s\S]*)\n\)$/m, '$1');
_ref1 = require('./nodes'), Block = _ref1.Block, Assign = _ref1.Assign, Value = _ref1.Value, Literal = _ref1.Literal;
try {
ast = CoffeeScript.nodes(input);
tokens = CoffeeScript.tokens(input);
referencedVars = (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = tokens.length; _i < _len; _i++) {
token = tokens[_i];
if (token.variable && token[1].charAt(0) === '_') {
_results.push(token[1]);
}
}
return _results;
})();
ast = CoffeeScript.nodes(tokens);
ast = new Block([new Assign(new Value(new Literal('_')), ast, '=')]);
js = ast.compile({
bare: true,
locals: Object.keys(context)
locals: Object.keys(context),
referencedVars: referencedVars
});
result = context === global ? vm.runInThisContext(js, filename) : vm.runInContext(js, context, filename);
return cb(null, result);
@@ -58,7 +71,7 @@
rli.removeListener('line', nodeLineListener);
rli.on('line', function(cmd) {
if (multiline.enabled) {
multiline.buffer += "" + cmd + "\n";
multiline.buffer += cmd + "\n";
rli.setPrompt(multiline.prompt);
rli.prompt(true);
} else {
@@ -118,7 +131,7 @@
fd = fs.openSync(filename, 'a');
repl.rli.addListener('line', function(code) {
if (code && code.length && code !== '.history' && lastLine !== code) {
fs.write(fd, "" + code + "\n");
fs.write(fd, code + "\n");
return lastLine = code;
}
});
@@ -128,7 +141,7 @@
return repl.commands[getCommandId(repl, 'history')] = {
help: 'Show command history',
action: function() {
repl.outputStream.write("" + (repl.rli.history.slice(0).reverse().join('\n')) + "\n");
repl.outputStream.write((repl.rli.history.slice(0).reverse().join('\n')) + "\n");
return repl.displayPrompt();
}
};

View File

@@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
(function() {
var BALANCED_PAIRS, CALL_CLOSERS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, generate, left, rite, _i, _len, _ref,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
@@ -17,8 +17,8 @@
exports.Rewriter = (function() {
function Rewriter() {}
Rewriter.prototype.rewrite = function(tokens) {
this.tokens = tokens;
Rewriter.prototype.rewrite = function(_at_tokens) {
this.tokens = _at_tokens;
this.removeLeadingNewlines();
this.closeOpenCalls();
this.closeOpenIndexes();
@@ -194,7 +194,7 @@
};
endImplicitCall = function() {
stack.pop();
tokens.splice(i, 0, generate('CALL_END', ')'));
tokens.splice(i, 0, generate('CALL_END', ')', ['', 'end of input', token[2]]));
return i += 1;
};
startImplicitObject = function(j, startsLine) {
@@ -257,14 +257,14 @@
}
stack.pop();
}
if ((__indexOf.call(IMPLICIT_FUNC, tag) >= 0 && token.spaced && !token.stringEnd || tag === '?' && i > 0 && !tokens[i - 1].spaced) && (__indexOf.call(IMPLICIT_CALL, nextTag) >= 0 || __indexOf.call(IMPLICIT_UNSPACED_CALL, nextTag) >= 0 && !((_ref = tokens[i + 1]) != null ? _ref.spaced : void 0) && !((_ref1 = tokens[i + 1]) != null ? _ref1.newLine : void 0))) {
if ((__indexOf.call(IMPLICIT_FUNC, tag) >= 0 && token.spaced && !token.stringEnd && !token.regexEnd || tag === '?' && i > 0 && !tokens[i - 1].spaced) && (__indexOf.call(IMPLICIT_CALL, nextTag) >= 0 || __indexOf.call(IMPLICIT_UNSPACED_CALL, nextTag) >= 0 && !((_ref = tokens[i + 1]) != null ? _ref.spaced : void 0) && !((_ref1 = tokens[i + 1]) != null ? _ref1.newLine : void 0))) {
if (tag === '?') {
tag = token[0] = 'FUNC_EXIST';
}
startImplicitCall(i + 1);
return forward(2);
}
if (__indexOf.call(IMPLICIT_FUNC, tag) >= 0 && this.matchTags(i + 1, 'INDENT', null, ':') && !this.findTagsBackwards(i, ['CLASS', 'EXTENDS', 'IF', 'CATCH', 'SWITCH', 'LEADING_WHEN', 'FOR', 'WHILE', 'UNTIL'])) {
if (__indexOf.call(IMPLICIT_FUNC, tag) >= 0 && !token.stringEnd && !token.regexEnd && this.matchTags(i + 1, 'INDENT', null, ':') && !this.findTagsBackwards(i, ['CLASS', 'EXTENDS', 'IF', 'CATCH', 'SWITCH', 'LEADING_WHEN', 'FOR', 'WHILE', 'UNTIL'])) {
startImplicitCall(i + 1);
stack.push(['INDENT', i + 2]);
return forward(3);
@@ -458,7 +458,7 @@
IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS'];
IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL', 'UNDEFINED', 'UNARY', 'UNARY_MATH', 'SUPER', 'THROW', '@', '->', '=>', '[', '(', '{', '--', '++'];
IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL', 'UNDEFINED', 'UNARY', 'YIELD', 'UNARY_MATH', 'SUPER', 'THROW', '@', '->', '=>', '[', '(', '{', '--', '++'];
IMPLICIT_UNSPACED_CALL = ['+', '-'];

View File

@@ -1,16 +1,17 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
(function() {
var Scope, extend, last, _ref;
var Scope, extend, last, _ref,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
_ref = require('./helpers'), extend = _ref.extend, last = _ref.last;
exports.Scope = Scope = (function() {
Scope.root = null;
function Scope(parent, expressions, method) {
this.parent = parent;
this.expressions = expressions;
this.method = method;
function Scope(_at_parent, _at_expressions, _at_method, _at_referencedVars) {
var _ref1, _ref2;
this.parent = _at_parent;
this.expressions = _at_expressions;
this.method = _at_method;
this.referencedVars = _at_referencedVars;
this.variables = [
{
name: 'arguments',
@@ -19,8 +20,9 @@
];
this.positions = {};
if (!this.parent) {
Scope.root = this;
this.utilities = {};
}
this.root = (_ref1 = (_ref2 = this.parent) != null ? _ref2.root : void 0) != null ? _ref1 : this;
}
Scope.prototype.add = function(name, type, immediate) {
@@ -91,7 +93,11 @@
reserve = true;
}
index = 0;
while (this.check((temp = this.temporary(name, index)))) {
while (true) {
temp = this.temporary(name, index);
if (!(this.check(temp) || __indexOf.call(this.root.referencedVars, temp) >= 0)) {
break;
}
index++;
}
if (reserve) {
@@ -133,7 +139,7 @@
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
v = _ref1[_i];
if (v.type.assigned) {
_results.push("" + v.name + " = " + v.type.value);
_results.push(v.name + " = " + v.type.value);
}
}
return _results;

View File

@@ -1,10 +1,10 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 1.9.0
(function() {
var LineMap, SourceMap;
LineMap = (function() {
function LineMap(line) {
this.line = line;
function LineMap(_at_line) {
this.line = _at_line;
this.columns = [];
}

View File

@@ -8,7 +8,7 @@
"compiler"
],
"author": "Jeremy Ashkenas",
"version": "1.8.0",
"version": "1.9.0",
"license": "MIT",
"engines": {
"node": ">=0.8.0"
@@ -23,7 +23,8 @@
},
"preferGlobal": true,
"scripts": {
"test": "node ./bin/cake test"
"test": "node ./bin/cake test",
"test-harmony": "node --harmony ./bin/cake test"
},
"homepage": "http://coffeescript.org",
"bugs": "https://github.com/jashkenas/coffeescript/issues",
@@ -37,8 +38,5 @@
"highlight.js": "~8.0.0",
"underscore": "~1.5.2",
"docco": "~0.6.2"
},
"dependencies": {
"mkdirp": "~0.3.5"
}
}

View File

@@ -12,7 +12,7 @@ helpers = require './helpers'
SourceMap = require './sourcemap'
# The current CoffeeScript version number.
exports.VERSION = '1.8.0'
exports.VERSION = '1.9.0'
exports.FILE_EXTENSIONS = ['.coffee', '.litcoffee', '.coffee.md']
@@ -44,7 +44,17 @@ exports.compile = compile = withPrettyErrors (code, options) ->
if options.sourceMap
map = new SourceMap
fragments = parser.parse(lexer.tokenize code, options).compileToFragments options
tokens = lexer.tokenize code, options
# Pass a list of referenced variables, so that generated variables won't get
# the same name. Since all generated variables start with an underscore only
# referenced variables also starting with an underscore are passed, as an
# optimization.
options.referencedVars = (
token[1] for token in tokens when token.variable and token[1].charAt(0) is '_'
)
fragments = parser.parse(tokens).compileToFragments options
currentLine = 0
currentLine += 1 if options.header
@@ -124,13 +134,17 @@ exports.run = (code, options = {}) ->
# The CoffeeScript REPL uses this to run the input.
exports.eval = (code, options = {}) ->
return unless code = code.trim()
Script = vm.Script
if Script
createContext = vm.Script.createContext ? vm.createContext
isContext = vm.isContext ? (ctx) ->
options.sandbox instanceof createContext().constructor
if createContext
if options.sandbox?
if options.sandbox instanceof Script.createContext().constructor
if isContext options.sandbox
sandbox = options.sandbox
else
sandbox = Script.createContext()
sandbox = createContext()
sandbox[k] = v for own k, v of options.sandbox
sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox
else
@@ -188,16 +202,17 @@ lexer = new Lexer
# directly as a "Jison lexer".
parser.lexer =
lex: ->
token = @tokens[@pos++]
token = parser.tokens[@pos++]
if token
[tag, @yytext, @yylloc] = token
@errorToken = token.origin or token
parser.errorToken = token.origin or token
@yylineno = @yylloc.first_line
else
tag = ''
tag
setInput: (@tokens) ->
setInput: (tokens) ->
parser.tokens = tokens
@pos = 0
upcomingInput: ->
""
@@ -209,7 +224,7 @@ parser.yy.parseError = (message, {token}) ->
# Disregard Jison's message, it contains redundant line numer information.
# Disregard the token, we take its value directly from the lexer in case
# the error is caused by a generated token which might refer to its origin.
{errorToken, tokens} = parser.lexer
{errorToken, tokens} = parser
[errorTag, errorText, errorLoc] = errorToken
errorText = if errorToken is tokens[tokens.length - 1]
@@ -303,4 +318,3 @@ Error.prepareStackTrace = (err, stack) ->
" at #{formatSourcePosition frame, getSourceMapping}"
"#{err.toString()}\n#{frames.join '\n'}\n"

View File

@@ -10,7 +10,6 @@ path = require 'path'
helpers = require './helpers'
optparse = require './optparse'
CoffeeScript = require './coffee-script'
mkdirp = require 'mkdirp'
{spawn, exec} = require 'child_process'
{EventEmitter} = require 'events'
@@ -330,6 +329,20 @@ outputPath = (source, base, extension=".js") ->
dir = path.join opts.output, path.relative base, srcDir
path.join dir, basename + extension
# Recursively mkdir, like `mkdir -p`.
mkdirp = (dir, fn) ->
mode = 0o777 & ~process.umask()
do mkdirs = (p = dir, fn) ->
fs.exists p, (exists) ->
if exists
fn()
else
mkdirs path.dirname(p), ->
fs.mkdir p, mode, (err) ->
return fn err if err
fn()
# Write out a JavaScript source file with the compiled code. By default, files
# are written out in `cwd` as `.js` files with the same name, but the output
# directory can be customized with `--output`.

View File

@@ -451,7 +451,8 @@ grammar =
]
ForBody: [
o 'FOR Range', -> source: LOC(2) new Value($2)
o 'FOR Range', -> source: (LOC(2) new Value($2))
o 'FOR Range BY Expression', -> source: (LOC(2) new Value($2)), step: $4
o 'ForStart ForSource', -> $2.own = $1.own; $2.name = $1[0]; $2.index = $1[1]; $2
]
@@ -536,6 +537,9 @@ grammar =
o 'UNARY_MATH Expression', -> new Op $1 , $2
o '- Expression', (-> new Op '-', $2), prec: 'UNARY_MATH'
o '+ Expression', (-> new Op '+', $2), prec: 'UNARY_MATH'
o 'YIELD Statement', -> new Op $1 , $2
o 'YIELD Expression', -> new Op $1 , $2
o 'YIELD FROM Expression', -> new Op $1.concat($2) , $3
o '-- SimpleAssignable', -> new Op '--', $2
o '++ SimpleAssignable', -> new Op '++', $2
@@ -595,6 +599,7 @@ operators = [
['left', 'COMPARE']
['left', 'LOGIC']
['nonassoc', 'INDENT', 'OUTDENT']
['right', 'YIELD']
['right', '=', ':', 'COMPOUND_ASSIGN', 'RETURN', 'THROW', 'EXTENDS']
['right', 'FORIN', 'FOROF', 'BY', 'WHEN']
['right', 'IF', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS']

View File

@@ -32,8 +32,7 @@ exports.Lexer = class Lexer
# Each tokenizing method is responsible for returning the number of characters
# it has consumed.
#
# Before returning the token stream, run it through the [Rewriter](rewriter.html)
# unless explicitly asked not to.
# Before returning the token stream, run it through the [Rewriter](rewriter.html).
tokenize: (code, opts = {}) ->
@literate = opts.literate # Are we lexing literate CoffeeScript?
@indent = 0 # The current indentation level.
@@ -60,7 +59,6 @@ exports.Lexer = class Lexer
@commentToken() or
@whitespaceToken() or
@lineToken() or
@heredocToken() or
@stringToken() or
@numberToken() or
@regexToken() or
@@ -72,8 +70,10 @@ exports.Lexer = class Lexer
i += consumed
return {@tokens, index: i} if opts.untilBalanced and @ends.length is 0
@closeIndentation()
@error "missing #{tag}" if tag = @ends.pop()
throwSyntaxError "missing #{end.tag}", end.origin[2] if end = @ends.pop()
return @tokens if opts.rewrite is off
(new Rewriter).rewrite @tokens
@@ -109,6 +109,9 @@ exports.Lexer = class Lexer
if id is 'own' and @tag() is 'FOR'
@token 'OWN', id
return id.length
if id is 'from' and @tag() is 'YIELD'
@token 'FROM', id
return id.length
forcedIdentifier = colon or
(prev = last @tokens) and (prev[0] in ['.', '?.', '::', '?::'] or
not prev.spaced and prev[0] is '@')
@@ -153,6 +156,7 @@ exports.Lexer = class Lexer
else tag
tagToken = @token tag, id, 0, idLength
tagToken.variable = not forcedIdentifier
if poppedToken
[tagToken[2].first_line, tagToken[2].first_column] =
[poppedToken[2].first_line, poppedToken[2].first_column]
@@ -183,49 +187,60 @@ exports.Lexer = class Lexer
@token 'NUMBER', number, 0, lexedLength
lexedLength
# Matches strings, including multi-line strings. Ensures that quotation marks
# are balanced within the string's contents, and within nested interpolations.
# Matches strings, including multi-line strings, as well as heredocs, with or without
# interpolation.
stringToken: ->
switch quote = @chunk.charAt 0
when "'" then [string] = SIMPLESTR.exec(@chunk) || []
when '"' then string = @balancedString @chunk, '"'
return 0 unless string
inner = string[1...-1]
trimmed = @removeNewlines inner
if quote is '"' and 0 < string.indexOf '#{', 1
numBreak = pos = 0
innerLen = inner.length
numBreak++ while inner.charAt(pos++) is '\n' and pos < innerLen
@interpolateString trimmed, strOffset: 1 + numBreak, lexedLength: string.length
else
@token 'STRING', quote + @escapeLines(trimmed) + quote, 0, string.length
if octalEsc = /^(?:\\.|[^\\])*\\(?:0[0-7]|[1-7])/.test string
@error "octal escape sequences #{string} are not allowed"
string.length
[quote] = STRING_START.exec(@chunk) || []
return 0 unless quote
regex = switch quote
when "'" then STRING_SINGLE
when '"' then STRING_DOUBLE
when "'''" then HEREDOC_SINGLE
when '"""' then HEREDOC_DOUBLE
heredoc = quote.length is 3
# Matches heredocs, adjusting indentation to the correct level, as heredocs
# preserve whitespace, but ignore indentation to the left.
heredocToken: ->
return 0 unless match = HEREDOC.exec @chunk
heredoc = match[0]
quote = heredoc.charAt 0
doc = @sanitizeHeredoc match[2], quote: quote, indent: null
if quote is '"' and 0 <= doc.indexOf '#{'
strOffset = if match[2].charAt(0) is '\n' then 4 else 3
@interpolateString doc, heredoc: yes, strOffset: strOffset, lexedLength: heredoc.length
start = quote.length
{tokens, index: end} = @matchWithInterpolations @chunk[start..], regex, quote, start
$ = tokens.length - 1
if heredoc
# Find the smallest indentation. It will be removed from all lines later.
indent = null
doc = (token[1] for token, i in tokens when token[0] is 'NEOSTRING').join '#{}'
while match = HEREDOC_INDENT.exec doc
attempt = match[1]
indent = attempt if indent is null or 0 < attempt.length < indent.length
indentRegex = /// ^#{indent} ///gm if indent
@mergeInterpolationTokens tokens, {quote: quote[0], start, end}, (value, i) =>
value = @formatString value
value = value.replace LEADING_BLANK_LINE, '' if i is 0
value = value.replace TRAILING_BLANK_LINE, '' if i is $
value = value.replace indentRegex, ''
value = value.replace MULTILINER, '\\n'
value
else
@token 'STRING', @makeString(doc, quote, yes), 0, heredoc.length
heredoc.length
@mergeInterpolationTokens tokens, {quote, start, end}, (value, i) =>
value = @formatString value
value = value.replace STRING_OMIT, (match, offset) ->
if (i is 0 and offset is 0) or
(i is $ and offset + match.length is value.length)
''
else
' '
value
end
# Matches and consumes comments.
commentToken: ->
return 0 unless match = @chunk.match COMMENT
[comment, here] = match
if here
@token 'HERECOMMENT',
(@sanitizeHeredoc here,
herecomment: true, indent: repeat ' ', @indent),
0, comment.length
if match = HERECOMMENT_ILLEGAL.exec comment
@error "block comments cannot contain #{match[0]}", match.index
if here.indexOf('\n') >= 0
here = here.replace /// \n #{repeat ' ', @indent} ///g, '\n'
@token 'HERECOMMENT', here, 0, comment.length
comment.length
# Matches JavaScript interpolated directly into the source via backticks.
@@ -234,70 +249,50 @@ exports.Lexer = class Lexer
@token 'JS', (script = match[0])[1...-1], 0, script.length
script.length
# Matches regular expression literals. Lexing regular expressions is difficult
# to distinguish from division, so we borrow some basic heuristics from
# JavaScript and Ruby.
# Matches regular expression literals, as well as multiline extended ones.
# Lexing regular expressions is difficult to distinguish from division, so we
# borrow some basic heuristics from JavaScript and Ruby.
regexToken: ->
return 0 if @chunk.charAt(0) isnt '/'
return length if length = @heregexToken()
prev = last @tokens
return 0 if prev and (prev[0] in (if prev.spaced then NOT_REGEX else NOT_SPACED_REGEX))
return 0 unless match = REGEX.exec @chunk
[match, regex, flags] = match
# Avoid conflicts with floor division operator.
return 0 if regex is '//'
if regex[..1] is '/*' then @error 'regular expressions cannot begin with `*`'
@token 'REGEX', "#{regex}#{flags}", 0, match.length
match.length
# Matches multiline extended regular expressions.
heregexToken: ->
return 0 unless match = HEREGEX.exec @chunk
[heregex, body, flags] = match
if 0 > body.indexOf '#{'
re = @escapeLines body.replace(HEREGEX_OMIT, '$1$2').replace(/\//g, '\\/'), yes
if re.match /^\*/ then @error 'regular expressions cannot begin with `*`'
@token 'REGEX', "/#{ re or '(?:)' }/#{flags}", 0, heregex.length
return heregex.length
@token 'IDENTIFIER', 'RegExp', 0, 0
@token 'CALL_START', '(', 0, 0
tokens = []
for token in @interpolateString(body, regex: yes, strOffset: 3)
[tag, value] = token
if tag is 'TOKENS'
tokens.push value...
else if tag is 'NEOSTRING'
continue unless value = value.replace HEREGEX_OMIT, '$1$2'
# Convert NEOSTRING into STRING
value = value.replace /\\/g, '\\\\'
token[0] = 'STRING'
token[1] = @makeString(value, '"', yes)
tokens.push token
switch
when match = REGEX_ILLEGAL.exec @chunk
@error "regular expressions cannot begin with #{match[2]}", match.index + match[1].length
when @chunk[...3] is '///'
{tokens, index} = @matchWithInterpolations @chunk[3..], HEREGEX, '///', 3
when match = REGEX.exec @chunk
[regex, closed] = match
index = regex.length
prev = last @tokens
if prev
if prev.spaced and prev[0] in CALLABLE and not prev.stringEnd and not prev.regexEnd
return 0 if not closed or POSSIBLY_DIVISION.test regex
else if prev[0] in NOT_REGEX
return 0
@error 'missing / (unclosed regex)' unless closed
else
@error "Unexpected #{tag}"
return 0
prev = last @tokens
plusToken = ['+', '+']
plusToken[2] = prev[2] # Copy location data
tokens.push plusToken
[flags] = REGEX_FLAGS.exec @chunk[index..]
end = index + flags.length
switch
when not VALID_FLAGS.test flags
@error "invalid regular expression flags #{flags}", index
when regex
@token 'REGEX', "#{regex}#{flags}"
when tokens.length is 1
re = @formatHeregex(tokens[0][1]).replace(/\//g, '\\/')
@token 'REGEX', "/#{ re or '(?:)' }/#{flags}"
else
@token 'IDENTIFIER', 'RegExp', 0, 0
@token 'CALL_START', '(', 0, 0
@mergeInterpolationTokens tokens, {quote: '"', start: 3, end}, (value) =>
@formatHeregex(value).replace(/\\/g, '\\\\')
if flags
@token ',', ',', index, 0
@token 'STRING', '"' + flags + '"', index, flags.length
rparen = @token ')', ')', end, 0
rparen.regexEnd = true
# Remove the extra "+"
tokens.pop()
unless tokens[0]?[0] is 'STRING'
@token 'STRING', '""', 0, 0
@token '+', '+', 0, 0
@tokens.push tokens...
if flags
# Find the flags in the heregex
flagsOffset = heregex.lastIndexOf flags
@token ',', ',', flagsOffset, 0
@token 'STRING', '"' + flags + '"', flagsOffset, flags.length
@token ')', ')', heregex.length-1, 0
heregex.length
end
# Matches newlines, indents, and outdents, and determines which is which.
# If we can detect that the current line is continued onto the the next line,
@@ -330,7 +325,7 @@ exports.Lexer = class Lexer
diff = size - @indent + @outdebt
@token 'INDENT', diff, indent.length - size, size
@indents.push diff
@ends.push 'OUTDENT'
@ends.push {tag: 'OUTDENT'}
@outdebt = @indebt = 0
@indent = size
else if size < @baseIndent
@@ -423,38 +418,23 @@ exports.Lexer = class Lexer
else if value in SHIFT then tag = 'SHIFT'
else if value in LOGIC or value is '?' and prev?.spaced then tag = 'LOGIC'
else if prev and not prev.spaced
if value is '(' and prev[0] in CALLABLE
if value is '(' and prev[0] in CALLABLE and not prev.stringEnd and not prev.regexEnd
prev[0] = 'FUNC_EXIST' if prev[0] is '?'
tag = 'CALL_START'
else if value is '[' and prev[0] in INDEXABLE
tag = 'INDEX_START'
switch prev[0]
when '?' then prev[0] = 'INDEX_SOAK'
token = @makeToken tag, value
switch value
when '(', '{', '[' then @ends.push INVERSES[value]
when '(', '{', '[' then @ends.push {tag: INVERSES[value], origin: token}
when ')', '}', ']' then @pair value
@token tag, value
@tokens.push token
value.length
# Token Manipulators
# ------------------
# Sanitize a heredoc or herecomment by
# erasing all external indentation on the left-hand side.
sanitizeHeredoc: (doc, options) ->
{indent, herecomment} = options
if herecomment
if HEREDOC_ILLEGAL.test doc
@error "block comment cannot contain \"*/\", starting"
return doc if doc.indexOf('\n') < 0
else
while match = HEREDOC_INDENT.exec doc
attempt = match[1]
indent = attempt if indent is null or 0 < attempt.length < indent.length
doc = doc.replace /// \n #{indent} ///g, '\n' if indent
doc = doc.replace /^\n/, '' unless herecomment
doc
# A source of ambiguity in our grammar used to be parameter lists in function
# definitions versus argument lists in function calls. Walk backwards, tagging
# parameters specially in order to make things easier for the parser.
@@ -480,138 +460,126 @@ exports.Lexer = class Lexer
closeIndentation: ->
@outdentToken @indent
# Matches a balanced group such as a single or double-quoted string. Pass in
# a series of delimiters, all of which must be nested correctly within the
# contents of the string. This method allows us to have strings within
# interpolations within strings, ad infinitum.
balancedString: (str, end) ->
continueCount = 0
stack = [end]
for i in [1...str.length]
if continueCount
--continueCount
continue
switch letter = str.charAt i
when '\\'
++continueCount
continue
when end
stack.pop()
unless stack.length
return str[0..i]
end = stack[stack.length - 1]
continue
if end is '}' and letter in ['"', "'"]
stack.push end = letter
else if end is '}' and letter is '/' and match = (HEREGEX.exec(str[i..]) or REGEX.exec(str[i..]))
continueCount += match[0].length - 1
else if end is '}' and letter is '{'
stack.push end = '}'
else if end is '"' and prev is '#' and letter is '{'
stack.push end = '}'
prev = letter
@error "missing #{ stack.pop() }, starting"
# Expand variables and expressions inside double-quoted strings using
# Ruby-like notation for substitution of arbitrary expressions.
# Match the contents of a delimited token and expand variables and expressions
# inside it using Ruby-like notation for substitution of arbitrary
# expressions.
#
# "Hello #{name.capitalize()}."
#
# If it encounters an interpolation, this method will recursively create a
# new Lexer, tokenize the interpolated contents, and merge them into the
# token stream.
# If it encounters an interpolation, this method will recursively create a new
# Lexer and tokenize until the `{` of `#{` is balanced with a `}`.
#
# - `str` is the start of the string contents (IE with the " or """ stripped
# off.)
# - `options.offsetInChunk` is the start of the interpolated string in the
# current chunk, including the " or """, etc... If not provided, this is
# assumed to be 0. `options.lexedLength` is the length of the
# interpolated string, including both the start and end quotes. Both of these
# values are ignored if `options.regex` is true.
# - `options.strOffset` is the offset of str, relative to the start of the
# current chunk.
interpolateString: (str, options = {}) ->
{heredoc, regex, offsetInChunk, strOffset, lexedLength} = options
offsetInChunk ||= 0
strOffset ||= 0
lexedLength ||= str.length
# Parse the string.
# - `str` is the start of the token contents (with the starting delimiter
# stripped off.)
# - `regex` matches the contents of a token (but not `end`, and not `#{` if
# interpolations are desired).
# - `end` is the terminator of the token.
# - `offsetInChunk` is the start of the interpolated string in the current
# chunk, including the starting delimiter.
#
# Examples of delimiters are `'`, `"`, `'''`, `"""` and `///`.
#
# This method allows us to have strings within interpolations within strings,
# ad infinitum.
matchWithInterpolations: (str, regex, end, offsetInChunk) ->
tokens = []
pi = 0
i = -1
while letter = str.charAt i += 1
if letter is '\\'
i += 1
continue
unless letter is '#' and str.charAt(i+1) is '{' and
(expr = @balancedString str[i + 1..], '}')
continue
# NEOSTRING is a fake token. This will be converted to a string below.
tokens.push @makeToken('NEOSTRING', str[pi...i], strOffset + pi) if pi < i
unless errorToken
errorToken = @makeToken '', 'string interpolation', offsetInChunk + i + 1, 2
inner = expr[1...-1]
if inner.length
[line, column] = @getLineAndColumnFromChunk(strOffset + i + 2)
nested = new Lexer().tokenize inner, line: line, column: column, rewrite: off
popped = nested.pop()
popped = nested.shift() if nested[0]?[0] is 'TERMINATOR'
if len = nested.length
if len > 1
nested.unshift @makeToken '(', '(', strOffset + i + 1, 0
nested.push @makeToken ')', ')', strOffset + i + 1 + inner.length, 0
# Push a fake 'TOKENS' token, which will get turned into real tokens below.
tokens.push ['TOKENS', nested]
i += expr.length
pi = i + 1
tokens.push @makeToken('NEOSTRING', str[pi..], strOffset + pi) if i > pi < str.length
loop
[strPart] = regex.exec str
# If regex, then return now and let the regex code deal with all these fake tokens
return tokens if regex
# Push a fake 'NEOSTRING' token, which will get turned into a real string later.
tokens.push @makeToken 'NEOSTRING', strPart, offsetInChunk
# If we didn't find any tokens, then just return an empty string.
return @token 'STRING', '""', offsetInChunk, lexedLength unless tokens.length
str = str[strPart.length..]
offsetInChunk += strPart.length
# If the first token is not a string, add a fake empty string to the beginning.
tokens.unshift @makeToken('NEOSTRING', '', offsetInChunk) unless tokens[0][0] is 'NEOSTRING'
break unless str[...2] is '#{'
# The `1`s are to remove the `#` in `#{`.
[line, column] = @getLineAndColumnFromChunk offsetInChunk + 1
{tokens: nested, index} =
new Lexer().tokenize str[1..], line: line, column: column, untilBalanced: on
# Skip the trailing `}`.
index += 1
# Turn the leading and trailing `{` and `}` into parentheses. Unnecessary
# parentheses will be removed later.
[open, ..., close] = nested
open[0] = open[1] = '('
close[0] = close[1] = ')'
close.origin = ['', 'end of interpolation', close[2]]
# Remove leading 'TERMINATOR' (if any).
nested.splice 1, 1 if nested[1]?[0] is 'TERMINATOR'
# Push a fake 'TOKENS' token, which will get turned into real tokens later.
tokens.push ['TOKENS', nested]
str = str[index..]
offsetInChunk += index
unless str[...end.length] is end
@error "missing #{end}"
{tokens, index: offsetInChunk + end.length}
# Merge the array `tokens` of the fake token types 'TOKENS' and 'NEOSTRING'
# (as returned by `matchWithInterpolations`) into the token stream. The value
# of 'NEOSTRING's are converted using `fn` and turned into strings using
# `quote` first. The tokens are wrapped in parentheses if needed, using
# `start` and `end` for their location data.
mergeInterpolationTokens: (tokens, {quote, start, end}, fn) ->
if interpolated = tokens.length > 1
@token '(', '(', offsetInChunk, 0, errorToken
errorToken = @makeToken '', 'interpolation', start + tokens[0][1].length, 2
@token '(', '(', 0, 0, errorToken
# Push all the tokens
firstIndex = @tokens.length
for token, i in tokens
[tag, value] = token
if i
switch tag
when 'TOKENS'
# Optimize out empty interpolations (an empty pair of parentheses).
continue if value.length is 2
# Push all the tokens in the fake 'TOKENS' token. These already have
# sane location data.
locationToken = value[0]
tokensToPush = value
when 'NEOSTRING'
# Convert 'NEOSTRING' into 'STRING'.
converted = fn token[1], i
# Optimize out empty strings. We ensure that the tokens stream always
# starts with a string token, though, to make sure that the result
# really is a string.
if converted.length is 0
if i is 0
firstEmptyStringIndex = @tokens.length
else
continue
# However, there is one case where we can optimize away a starting
# empty string.
if i is 2 and firstEmptyStringIndex?
@tokens.splice firstEmptyStringIndex, 2 # Remove empty string and the plus.
token[0] = 'STRING'
token[1] = @makeString converted, quote
locationToken = token
tokensToPush = [token]
if @tokens.length > firstIndex
# Create a 0-length "+" token.
plusToken = @token '+', '+' if i
locationToken = if tag == 'TOKENS' then value[0] else token
plusToken = @token '+', '+'
plusToken[2] =
first_line: locationToken[2].first_line
first_line: locationToken[2].first_line
first_column: locationToken[2].first_column
last_line: locationToken[2].first_line
last_column: locationToken[2].first_column
if tag is 'TOKENS'
# Push all the tokens in the fake 'TOKENS' token. These already have
# sane location data.
@tokens.push value...
else if tag is 'NEOSTRING'
# Convert NEOSTRING into STRING
token[0] = 'STRING'
token[1] = @makeString value, '"', heredoc
@tokens.push token
else
@error "Unexpected #{tag}"
last_line: locationToken[2].first_line
last_column: locationToken[2].first_column
@tokens.push tokensToPush...
if interpolated
rparen = @makeToken ')', ')', offsetInChunk + lexedLength, 0
rparen = @token ')', ')', end, 0
rparen.stringEnd = true
@tokens.push rparen
tokens
# Pairs up a closing token, ensuring that all listed pairs of tokens are
# correctly balanced throughout the course of the token stream.
pair: (tag) ->
unless tag is wanted = last @ends
unless tag is wanted = last(@ends)?.tag
@error "unmatched #{tag}" unless 'OUTDENT' is wanted
# Auto-close INDENT to support syntax like this:
#
@@ -688,32 +656,27 @@ exports.Lexer = class Lexer
# Are we in the midst of an unfinished expression?
unfinished: ->
LINE_CONTINUER.test(@chunk) or
@tag() in ['\\', '.', '?.', '?::', 'UNARY', 'MATH', 'UNARY_MATH', '+', '-',
@tag() in ['\\', '.', '?.', '?::', 'UNARY', 'MATH', 'UNARY_MATH', '+', '-', 'YIELD',
'**', 'SHIFT', 'RELATION', 'COMPARE', 'LOGIC', 'THROW', 'EXTENDS']
# Remove newlines from beginning and (non escaped) from end of string literals.
removeNewlines: (str) ->
str.replace(/^\s*\n\s*/, '')
.replace(/([^\\]|\\\\)\s*\n\s*$/, '$1')
# Converts newlines for string literals.
escapeLines: (str, heredoc) ->
# Ignore escaped backslashes and remove escaped newlines
str = str.replace /\\[^\S\n]*(\n|\\)\s*/g, (escaped, character) ->
formatString: (str) ->
# Ignore escaped backslashes and remove escaped newlines.
str.replace /\\[^\S\n]*(\n|\\)\s*/g, (escaped, character) ->
if character is '\n' then '' else escaped
if heredoc
str.replace MULTILINER, '\\n'
else
str.replace /\s*\n\s*/g, ' '
# Constructs a string token by escaping quotes and newlines.
makeString: (body, quote, heredoc) ->
formatHeregex: (str) ->
str.replace(HEREGEX_OMIT, '$1$2').replace(MULTILINER, '\\n')
# Constructs a string token by escaping quotes.
makeString: (body, quote) ->
return quote + quote unless body
# Ignore escaped backslashes and unescape quotes
# Ignore escaped backslashes and unescape quotes.
body = body.replace /// \\( #{quote} | \\ ) ///g, (match, contents) ->
if contents is quote then contents else match
body = body.replace /// #{quote} ///g, '\\$&'
quote + @escapeLines(body, heredoc) + quote
if match = OCTAL_ESCAPE.exec body
@error "octal escape sequences are not allowed #{match[2]}", match.index + match[1].length + 1
quote + body + quote
# Throws a compiler error on the current position.
error: (message, offset = 0) ->
@@ -729,7 +692,7 @@ exports.Lexer = class Lexer
JS_KEYWORDS = [
'true', 'false', 'null', 'this'
'new', 'delete', 'typeof', 'in', 'instanceof'
'return', 'throw', 'break', 'continue', 'debugger'
'return', 'throw', 'break', 'continue', 'debugger', 'yield'
'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally'
'class', 'extends', 'super'
]
@@ -756,12 +719,11 @@ COFFEE_KEYWORDS = COFFEE_KEYWORDS.concat COFFEE_ALIASES
# to avoid having a JavaScript error at runtime.
RESERVED = [
'case', 'default', 'function', 'var', 'void', 'with', 'const', 'let', 'enum'
'export', 'import', 'native', '__hasProp', '__extends', '__slice', '__bind'
'__indexOf', 'implements', 'interface', 'package', 'private', 'protected'
'public', 'static', 'yield'
'export', 'import', 'native', 'implements', 'interface', 'package', 'private'
'protected', 'public', 'static'
]
STRICT_PROSCRIBED = ['arguments', 'eval']
STRICT_PROSCRIBED = ['arguments', 'eval', 'yield*']
# The superset of both JavaScript keywords and reserved words, none of which may
# be used as identifiers or properties.
@@ -775,7 +737,8 @@ BOM = 65279
# Token matching regexes.
IDENTIFIER = /// ^
( [$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]* )
(?!\d)
( (?: (?!\s)[$\w\x7f-\uffff] )+ )
( [^\n\S]* : (?!:) )? # Is this a property name?
///
@@ -786,8 +749,6 @@ NUMBER = ///
^ \d*\.?\d+ (?:e[+-]?\d+)? # decimal
///i
HEREDOC = /// ^ ("""|''') ((?: \\[\s\S] | [^\\] )*?) (?:\n[^\n\S]*)? \1 ///
OPERATOR = /// ^ (
?: [-=]> # function
| [-+*/%<>&|^!?=]= # compound assign / compare
@@ -806,26 +767,34 @@ CODE = /^[-=]>/
MULTI_DENT = /^(?:\n[^\n\S]*)+/
SIMPLESTR = /^'[^\\']*(?:\\[\s\S][^\\']*)*'/
JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/
# String-matching-regexes.
STRING_START = /^(?:'''|"""|'|")/
STRING_SINGLE = /// ^(?: [^\\'] | \\[\s\S] )* ///
STRING_DOUBLE = /// ^(?: [^\\"#] | \\[\s\S] | \#(?!\{) )* ///
HEREDOC_SINGLE = /// ^(?: [^\\'] | \\[\s\S] | '(?!'') )* ///
HEREDOC_DOUBLE = /// ^(?: [^\\"#] | \\[\s\S] | "(?!"") | \#(?!\{) )* ///
STRING_OMIT = /\s*\n\s*/g
HEREDOC_INDENT = /\n+([^\n\S]*)(?=\S)/g
# Regex-matching-regexes.
REGEX = /// ^
(/ (?! [\s=] ) # disallow leading whitespace or equals signs
[^ [ / \n \\ ]* # every other thing
(?:
(?: \\[\s\S] # anything escaped
| \[ # character class
[^ \] \n \\ ]*
(?: \\[\s\S] [^ \] \n \\ ]* )*
]
) [^ [ / \n \\ ]*
)*
/) ([imgy]{0,4}) (?!\w)
/ (?!/) (
?: [^ [ / \n \\ ] # every other thing
| \\. # anything (but newlines) escaped
| \[ # character class
(?: \\. | [^ \] \n \\ ] )*
]
)* (/)?
///
HEREGEX = /// ^ /{3} ((?:\\?[\s\S])+?) /{3} ([imgy]{0,4}) (?!\w) ///
REGEX_FLAGS = /^\w*/
VALID_FLAGS = /^(?!.*(.).*\1)[imgy]*$/
HEREGEX = /// ^(?: [^\\/#] | \\[\s\S] | /(?!//) | \#(?!\{) )* ///
HEREGEX_OMIT = ///
((?:\\\\)+) # consume (and preserve) an even number of backslashes
@@ -833,16 +802,23 @@ HEREGEX_OMIT = ///
| \s+(?:#.*)? # remove whitespace and comments
///g
# Token cleaning regexes.
MULTILINER = /\n/g
REGEX_ILLEGAL = /// ^ ( / | /{3}\s*) (\*) ///
HEREDOC_INDENT = /\n+([^\n\S]*)/g
POSSIBLY_DIVISION = /// ^ /=?\s ///
HEREDOC_ILLEGAL = /\*\//
# Other regexes.
MULTILINER = /\n/g
LINE_CONTINUER = /// ^ \s* (?: , | \??\.(?![.\d]) | :: ) ///
HERECOMMENT_ILLEGAL = /\*\//
TRAILING_SPACES = /\s+$/
LINE_CONTINUER = /// ^ \s* (?: , | \??\.(?![.\d]) | :: ) ///
OCTAL_ESCAPE = /// ^ ((?: \\. | [^\\] )*) (\\ (?: 0[0-7] | [1-7] )) ///
LEADING_BLANK_LINE = /^[^\n\S]*\n/
TRAILING_BLANK_LINE = /\n[^\n\S]*$/
TRAILING_SPACES = /\s+$/
# Compound assignment tokens.
COMPOUND_ASSIGN = [
@@ -873,23 +849,17 @@ RELATION = ['IN', 'OF', 'INSTANCEOF']
# Boolean tokens.
BOOL = ['TRUE', 'FALSE']
# Tokens which a regular expression will never immediately follow, but which
# a division operator might.
#
# See: http://www.mozilla.org/js/language/js20-2002-04/rationale/syntax.html#regular-expressions
#
# Our list is shorter, due to sans-parentheses method calls.
NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', 'NULL', 'UNDEFINED', '++', '--']
# If the previous token is not spaced, there are more preceding tokens that
# force a division parse:
NOT_SPACED_REGEX = NOT_REGEX.concat ')', '}', 'THIS', 'IDENTIFIER', 'STRING', ']'
# Tokens which could legitimately be invoked or indexed. An opening
# parentheses or bracket following these tokens will be recorded as the start
# of a function invocation or indexing operation.
CALLABLE = ['IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER']
INDEXABLE = CALLABLE.concat 'NUMBER', 'BOOL', 'NULL', 'UNDEFINED'
CALLABLE = ['IDENTIFIER', ')', ']', '?', '@', 'THIS', 'SUPER']
INDEXABLE = CALLABLE.concat ['NUMBER', 'STRING', 'REGEX', 'BOOL', 'NULL', 'UNDEFINED', '}', '::']
# Tokens which a regular expression will never immediately follow (except spaced
# CALLABLEs in some cases), but which a division operator can.
#
# See: http://www-archive.mozilla.org/js/language/js20-2002-04/rationale/syntax.html#regular-expressions
NOT_REGEX = INDEXABLE.concat ['++', '--']
# Tokens that, when immediately preceding a `WHEN`, indicate that the `WHEN`
# occurs at the start of a line. We disambiguate these from trailing whens to

View File

@@ -89,7 +89,11 @@ exports.Base = class Base
else
meth = 'call'
func = new Value func, [new Access new Literal meth]
(new Call func, args).compileNode o
parts = (new Call func, args).compileNode o
if func.isGenerator
parts.unshift @makeCode "(yield* "
parts.push @makeCode ")"
parts
# If the code generation wishes to use the result of a complex expression
# in multiple places, ensure that the expression is only ever evaluated once,
@@ -316,7 +320,7 @@ exports.Block = class Block extends Base
o.indent = if o.bare then '' else TAB
o.level = LEVEL_TOP
@spaced = yes
o.scope = new Scope null, this, null
o.scope = new Scope null, this, null, o.referencedVars ? []
# Mark given local variables in the root scope as parameters so they don't
# end up being declared on this block.
o.scope.parameter name for name in o.locals or []
@@ -455,7 +459,6 @@ exports.Return = class Return extends Base
answer.push @makeCode ";"
return answer
#### Value
# A value, variable or literal or parenthesized, indexed or dotted into,
@@ -577,7 +580,7 @@ exports.Comment = class Comment extends Base
makeReturn: THIS
compileNode: (o, level) ->
comment = @comment.replace /^(\s*)#/gm, "$1 *"
comment = @comment.replace /^(\s*)# /gm, "$1 * "
code = "/*#{multident comment, @tab}#{if '\n' in comment then "\n#{@tab}" else ''} */"
code = o.indent + code if (level or o.level) is LEVEL_TOP
[@makeCode("\n"), @makeCode(code)]
@@ -733,7 +736,7 @@ exports.Extends = class Extends extends Base
# Hooks one constructor into another's prototype chain.
compileToFragments: (o) ->
new Call(new Value(new Literal utility 'extends'), [@child, @parent]).compileToFragments o
new Call(new Value(new Literal utility 'extends', o), [@child, @parent]).compileToFragments o
#### Access
@@ -1014,7 +1017,7 @@ exports.Class = class Class extends Base
addBoundFunctions: (o) ->
for bvar in @boundFuncs
lhs = (new Value (new Literal "this"), [new Access bvar]).compile o
@ctor.body.unshift new Literal "#{lhs} = #{utility 'bind'}(#{lhs}, this)"
@ctor.body.unshift new Literal "#{lhs} = #{utility 'bind', o}(#{lhs}, this)"
return
# Merge the properties from a top-level object as prototypal properties
@@ -1228,7 +1231,7 @@ exports.Assign = class Assign extends Base
if not expandedIdx and obj instanceof Splat
name = obj.name.unwrap().value
obj = obj.unwrap()
val = "#{olen} <= #{vvarText}.length ? #{ utility 'slice' }.call(#{vvarText}, #{i}"
val = "#{olen} <= #{vvarText}.length ? #{ utility 'slice', o }.call(#{vvarText}, #{i}"
if rest = olen - i - 1
ivar = o.scope.freeVariable 'i'
val += ", #{ivar} = #{vvarText}.length - #{rest}) : (#{ivar} = #{i}, [])"
@@ -1315,9 +1318,11 @@ exports.Assign = class Assign extends Base
# has no *children* -- they're within the inner scope.
exports.Code = class Code extends Base
constructor: (params, body, tag) ->
@params = params or []
@body = body or new Block
@bound = tag is 'boundfunc'
@params = params or []
@body = body or new Block
@bound = tag is 'boundfunc'
@isGenerator = !!@body.contains (node) ->
node instanceof Op and node.operator in ['yield', 'yield*']
children: ['params', 'body']
@@ -1355,9 +1360,8 @@ exports.Code = class Code extends Base
for param in @params when param not instanceof Expansion
o.scope.parameter param.asReference o
for param in @params when param.splat or param instanceof Expansion
for {name: p} in @params when param not instanceof Expansion
if p.this then p = p.properties[0].name
if p.value then o.scope.add p.value, 'var', yes
for p in @params when p not instanceof Expansion and p.name.value
o.scope.add p.name.value, 'var', yes
splats = new Assign new Value(new Arr(p.asReference o for p in @params)),
new Value new Literal 'arguments'
break
@@ -1381,12 +1385,13 @@ exports.Code = class Code extends Base
o.scope.parameter fragmentsToText params[i]
uniqs = []
@eachParamName (name, node) ->
node.error "multiple parameters named '#{name}'" if name in uniqs
node.error "multiple parameters named #{name}" if name in uniqs
uniqs.push name
@body.makeReturn() unless wasEmpty or @noReturn
code = 'function'
code += ' ' + @name if @ctor
code += '('
code = 'function'
code += '*' if @isGenerator
code += ' ' + @name if @ctor
code += '('
answer = [@makeCode(code)]
for p, i in params
if i then answer.push @makeCode ", "
@@ -1425,9 +1430,8 @@ exports.Param = class Param extends Base
return @reference if @reference
node = @name
if node.this
node = node.properties[0].name
if node.value.reserved
node = new Literal o.scope.freeVariable node.value
name = "at_#{node.properties[0].name.value}"
node = new Literal o.scope.freeVariable name
else if node.isComplex()
node = new Literal o.scope.freeVariable 'arg'
node = new Value node
@@ -1445,9 +1449,7 @@ exports.Param = class Param extends Base
# `name` is the name of the parameter and `node` is the AST node corresponding
# to that name.
eachName: (iterator, name = @name)->
atParam = (obj) ->
node = obj.properties[0].name
iterator node.value, node unless node.value.reserved
atParam = (obj) -> iterator "@#{obj.properties[0].name.value}", obj
# * simple literals `foo`
return iterator name.value, name if name instanceof Literal
# * at-params `@foo`
@@ -1504,12 +1506,12 @@ exports.Splat = class Splat extends Base
node = list[0]
fragments = node.compileToFragments o, LEVEL_LIST
return fragments if apply
return [].concat node.makeCode("#{ utility 'slice' }.call("), fragments, node.makeCode(")")
return [].concat node.makeCode("#{ utility 'slice', o }.call("), fragments, node.makeCode(")")
args = list[index..]
for node, i in args
compiledNode = node.compileToFragments o, LEVEL_LIST
args[i] = if node instanceof Splat
then [].concat node.makeCode("#{ utility 'slice' }.call("), compiledNode, node.makeCode(")")
then [].concat node.makeCode("#{ utility 'slice', o }.call("), compiledNode, node.makeCode(")")
else [].concat node.makeCode("["), compiledNode, node.makeCode("]")
if index is 0
node = list[0]
@@ -1612,9 +1614,10 @@ exports.Op = class Op extends Base
# The map of conversions from CoffeeScript to JavaScript symbols.
CONVERSIONS =
'==': '==='
'!=': '!=='
'of': 'in'
'==': '==='
'!=': '!=='
'of': 'in'
'yieldfrom': 'yield*'
# The map of invertible operators.
INVERSIONS =
@@ -1625,11 +1628,15 @@ exports.Op = class Op extends Base
isSimpleNumber: NO
isYield: ->
@operator in ['yield', 'yield*']
isUnary: ->
not @second
isComplex: ->
not (@isUnary() and @operator in ['+', '-']) or @first.isComplex()
not (@isUnary() and @operator in ['+', '-'] and
@first instanceof Value and @first.isSimpleNumber())
# Am I capable of
# [Python-style comparison chaining](http://docs.python.org/reference/expressions.html#notin)?
@@ -1691,6 +1698,7 @@ exports.Op = class Op extends Base
@error 'delete operand may not be argument or var'
if @operator in ['--', '++'] and @first.unwrapAll().value in STRICT_PROSCRIBED
@error "cannot increment/decrement \"#{@first.unwrapAll().value}\""
return @compileYield o if @isYield()
return @compileUnary o if @isUnary()
return @compileChain o if isChain
switch @operator
@@ -1745,6 +1753,19 @@ exports.Op = class Op extends Base
parts.reverse() if @flip
@joinFragmentArrays parts, ''
compileYield: (o) ->
parts = []
op = @operator
if not o.scope.parent?
@error 'yield statements must occur within a function generator.'
if 'expression' in Object.keys @first
parts.push @first.expression.compileToFragments o, LEVEL_OP if @first.expression?
else
parts.push [@makeCode "(#{op} "]
parts.push @first.compileToFragments o, LEVEL_OP
parts.push [@makeCode ")"]
@joinFragmentArrays parts, ''
compilePower: (o) ->
# Make a Math.pow call
pow = new Value new Literal('Math'), [new Access new Literal 'pow']
@@ -1756,7 +1777,7 @@ exports.Op = class Op extends Base
new Call(floor, [div]).compileToFragments o
compileModulo: (o) ->
mod = new Value new Literal utility 'modulo'
mod = new Value new Literal utility 'modulo', o
new Call(mod, [@first, @second]).compileToFragments o
toString: (idt) ->
@@ -1790,7 +1811,7 @@ exports.In = class In extends Base
compileLoopTest: (o) ->
[sub, ref] = @object.cache o, LEVEL_LIST
fragments = [].concat @makeCode(utility('indexOf') + ".call("), @array.compileToFragments(o, LEVEL_LIST),
fragments = [].concat @makeCode(utility('indexOf', o) + ".call("), @array.compileToFragments(o, LEVEL_LIST),
@makeCode(", "), ref, @makeCode(") " + if @negated then '< 0' else '>= 0')
return fragments if fragmentsToText(sub) is fragmentsToText(ref)
fragments = sub.concat @makeCode(', '), fragments
@@ -1999,7 +2020,7 @@ exports.For = class For extends While
varPart = "\n#{idt1}#{namePart};" if namePart
if @object
forPartFragments = [@makeCode("#{kvar} in #{svar}")]
guardPart = "\n#{idt1}if (!#{utility 'hasProp'}.call(#{svar}, #{kvar})) continue;" if @own
guardPart = "\n#{idt1}if (!#{utility 'hasProp', o}.call(#{svar}, #{kvar})) continue;" if @own
bodyFragments = body.compileToFragments merge(o, indent: idt1), LEVEL_TOP
if bodyFragments and (bodyFragments.length > 0)
bodyFragments = [].concat @makeCode("\n"), bodyFragments, @makeCode("\n")
@@ -2158,10 +2179,10 @@ UTILITIES =
# Correctly set up a prototype chain for inheritance, including a reference
# to the superclass for `super()` calls, and copies of any static properties.
extends: -> "
extends: (o) -> "
function(child, parent) {
for (var key in parent) {
if (#{utility 'hasProp'}.call(parent, key)) child[key] = parent[key];
if (#{utility 'hasProp', o}.call(parent, key)) child[key] = parent[key];
}
function ctor() {
this.constructor = child;
@@ -2238,10 +2259,14 @@ IS_REGEX = /^\//
# ----------------
# Helper for ensuring that utility functions are assigned at the top level.
utility = (name) ->
ref = "__#{name}"
Scope.root.assign ref, UTILITIES[name]()
ref
utility = (name, o) ->
{root} = o.scope
if name of root.utilities
root.utilities[name]
else
ref = root.freeVariable "_#{name}"
root.assign ref, UTILITIES[name] o
root.utilities[name] = ref
multident = (code, tab) ->
code = code.replace /\n/g, '$&' + tab

View File

@@ -20,13 +20,19 @@ replDefaults =
{Block, Assign, Value, Literal} = require './nodes'
try
# Generate the AST of the clean input.
ast = CoffeeScript.nodes input
# Tokenize the clean input.
tokens = CoffeeScript.tokens input
# Collect referenced variable names just like in `CoffeeScript.compile`.
referencedVars = (
token[1] for token in tokens when token.variable and token[1].charAt(0) is '_'
)
# Generate the AST of the tokens.
ast = CoffeeScript.nodes tokens
# Add assignment to `_` variable to force the input to be an expression.
ast = new Block [
new Assign (new Value new Literal '_'), ast, '='
]
js = ast.compile bare: yes, locals: Object.keys(context)
js = ast.compile {bare: yes, locals: Object.keys(context), referencedVars}
result = if context is global
vm.runInThisContext js, filename
else

View File

@@ -157,7 +157,7 @@ class exports.Rewriter
endImplicitCall = ->
stack.pop()
tokens.splice i, 0, generate 'CALL_END', ')'
tokens.splice i, 0, generate 'CALL_END', ')', ['', 'end of input', token[2]]
i += 1
startImplicitObject = (j, startsLine = yes) ->
@@ -209,7 +209,7 @@ class exports.Rewriter
# Recognize standard implicit calls like
# f a, f() b, f? c, h[0] d etc.
if (tag in IMPLICIT_FUNC and token.spaced and not token.stringEnd or
if (tag in IMPLICIT_FUNC and token.spaced and not token.stringEnd and not token.regexEnd or
tag is '?' and i > 0 and not tokens[i - 1].spaced) and
(nextTag in IMPLICIT_CALL or
nextTag in IMPLICIT_UNSPACED_CALL and
@@ -243,7 +243,8 @@ class exports.Rewriter
# which is probably always unintended.
# Furthermore don't allow this in literal arrays, as
# that creates grammatical ambiguities.
if tag in IMPLICIT_FUNC and @matchTags(i + 1, 'INDENT', null, ':') and
if tag in IMPLICIT_FUNC and not token.stringEnd and not token.regexEnd and
@matchTags(i + 1, 'INDENT', null, ':') and
not @findTagsBackwards(i, ['CLASS', 'EXTENDS', 'IF', 'CATCH',
'SWITCH', 'LEADING_WHEN', 'FOR', 'WHILE', 'UNTIL'])
startImplicitCall i + 1
@@ -467,7 +468,7 @@ IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@
# If preceded by an `IMPLICIT_FUNC`, indicates a function invocation.
IMPLICIT_CALL = [
'IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS'
'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL', 'UNDEFINED', 'UNARY',
'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL', 'UNDEFINED', 'UNARY', 'YIELD'
'UNARY_MATH', 'SUPER', 'THROW', '@', '->', '=>', '[', '(', '{', '--', '++'
]

View File

@@ -11,19 +11,20 @@ Import the helpers we plan to use.
exports.Scope = class Scope
The `root` is the top-level **Scope** object for a given file.
@root: null
Initialize a scope with its parent, for lookups up the chain,
as well as a reference to the **Block** node it belongs to, which is
where it should declare its variables, and a reference to the function that
it belongs to.
where it should declare its variables, a reference to the function that
it belongs to, and a list of variables referenced in the source code
and therefore should be avoided when generating variables.
constructor: (@parent, @expressions, @method) ->
constructor: (@parent, @expressions, @method, @referencedVars) ->
@variables = [{name: 'arguments', type: 'arguments'}]
@positions = {}
Scope.root = this unless @parent
@utilities = {} unless @parent
The `@root` is the top-level **Scope** object for a given file.
@root = @parent?.root ? this
Adds a new variable or overrides an existing one.
@@ -84,7 +85,10 @@ compiler-generated variable. `_var`, `_var2`, and so on...
freeVariable: (name, reserve=true) ->
index = 0
index++ while @check((temp = @temporary name, index))
loop
temp = @temporary name, index
break unless @check(temp) or temp in @root.referencedVars
index++
@add temp, 'var', yes if reserve
temp

View File

@@ -75,3 +75,35 @@ test "#1274: `[] = a()` compiles to `false` instead of `a()`", ->
fn = -> a = true
[] = fn()
ok a
test "#3194: string interpolation in array", ->
arr = [ "a"
key: 'value'
]
eq 2, arr.length
eq 'a', arr[0]
eq 'value', arr[1].key
b = 'b'
arr = [ "a#{b}"
key: 'value'
]
eq 2, arr.length
eq 'ab', arr[0]
eq 'value', arr[1].key
test "regex interpolation in array", ->
arr = [ /a/
key: 'value'
]
eq 2, arr.length
eq 'a', arr[0].source
eq 'value', arr[1].key
b = 'b'
arr = [ ///a#{b}///
key: 'value'
]
eq 2, arr.length
eq 'ab', arr[0].source
eq 'value', arr[1].key

View File

@@ -6,6 +6,7 @@
# * Destructuring Assignment
# * Context Property (@) Assignment
# * Existential Assignment (?=)
# * Assignment to variables similar to generated variables
test "context property assignment (using @)", ->
nonce = {}
@@ -405,3 +406,54 @@ test "#2181: conditional assignment as a subexpression", ->
false && a or= true
eq false, a
eq false, not a or= true
test "#1500: Assignment to variables similar to generated variables", ->
_len = 0
x = ((_results = null; i) for i in [1, 2, 3])
arrayEq [1, 2, 3], x
eq 0, _len
for x in [1, 2, 3]
f = ->
_i = 0
f()
eq 'undefined', typeof _i
_ref = 2
x = _ref * 2 ? 1
eq x, 4
eq 'undefined', typeof _ref1
x = {}
_base = -> x
_name = -1
_base()[-_name] ?= 2
eq x[1], 2
eq _base(), x
eq _name, -1
f = (@a, _at_a, a) -> [@a, _at_a, a]
arrayEq [1, 2, 3], f.call scope = {}, 1, 2, 3
eq 1, scope.a
doesNotThrow -> CoffeeScript.compile '(@_slice...) ->'
test "Assignment to variables similar to helper functions", ->
f = (__slice...) -> __slice
arrayEq [1, 2, 3], f 1, 2, 3
eq 'undefined', typeof __slice1
class A
class B extends A
__extends = 3
__hasProp = 4
value: 5
method: (__bind, __bind1) => [__bind, __bind1, __extends, __hasProp, @value]
{method} = new B
arrayEq [1, 2, 3, 4, 5], method 1, 2
__modulo = -1 %% 3
eq 2, __modulo
__indexOf = [1, 2, 3]
ok 2 in __indexOf

View File

@@ -399,3 +399,22 @@ test "#3132: Place block-comments nicely", ->
"""
eq CoffeeScript.compile(input, bare: on), result
test "#3638: Demand a whitespace after # symbol", ->
input = """
###
#No
#whitespace
###"""
result = """
/*
#No
#whitespace
*/
"""
eq CoffeeScript.compile(input, bare: on), result

View File

@@ -52,6 +52,32 @@ test "Issue #986: Unicode identifiers", ->
λ = 5
eq λ, 5
test "#2516: Unicode spaces should not be part of identifiers", ->
a = (x) -> x * 2
b = 3
eq 6, a b # U+00A0 NO-BREAK SPACE
eq 6, ab # U+1680 OGHAM SPACE MARK
eq 6, a b # U+2000 EN QUAD
eq 6, ab # U+2001 EM QUAD
eq 6, ab # U+2002 EN SPACE
eq 6, ab # U+2003 EM SPACE
eq 6, ab # U+2004 THREE-PER-EM SPACE
eq 6, ab # U+2005 FOUR-PER-EM SPACE
eq 6, ab # U+2006 SIX-PER-EM SPACE
eq 6, ab # U+2007 FIGURE SPACE
eq 6, ab # U+2008 PUNCTUATION SPACE
eq 6, ab # U+2009 THIN SPACE
eq 6, ab # U+200A HAIR SPACE
eq 6, ab # U+202F NARROW NO-BREAK SPACE
eq 6, ab # U+205F MEDIUM MATHEMATICAL SPACE
eq 6, a b # U+3000 IDEOGRAPHIC SPACE
# #3560: Non-breaking space (U+00A0) (before `'c'`)
eq 5, {c: 5}[ 'c' ]
# A line where every space in non-breaking
  eq 1 + 1, 2  
test "don't accidentally stringify keywords", ->
ok (-> this == 'this')() is false

View File

@@ -246,6 +246,17 @@ test "Optimized range comprehensions.", ->
ok exxes.join(' ') is 'x x x x x x x x x x'
test "#3671: Allow step in optimized range comprehensions.", ->
exxes = ('x' for [0...10] by 2)
eq exxes.join(' ') , 'x x x x x'
test "#3671: Disallow guard in optimized range comprehensions.", ->
throws -> CoffeeScript.compile "exxes = ('x' for [0...10] when a)"
test "Loop variables should be able to reference outer variables", ->
outer = 1
do ->

View File

@@ -89,7 +89,7 @@ if require?
test "#1096: unexpected generated tokens", ->
# Unexpected interpolation
assertErrorFormat '{"#{key}": val}', '''
[stdin]:1:3: error: unexpected string interpolation
[stdin]:1:3: error: unexpected interpolation
{"#{key}": val}
^^
'''
@@ -111,6 +111,11 @@ test "#1096: unexpected generated tokens", ->
a:
^
'''
assertErrorFormat 'a +', '''
[stdin]:1:4: error: unexpected end of input
a +
^
'''
# Unexpected implicit object
assertErrorFormat '''
for i in [1]:
@@ -121,6 +126,72 @@ test "#1096: unexpected generated tokens", ->
^
'''
test "#1316: unexpected end of interpolation", ->
assertErrorFormat '''
"#{+}"
''', '''
[stdin]:1:5: error: unexpected end of interpolation
"#{+}"
^
'''
assertErrorFormat '''
"#{++}"
''', '''
[stdin]:1:6: error: unexpected end of interpolation
"#{++}"
^
'''
assertErrorFormat '''
"#{-}"
''', '''
[stdin]:1:5: error: unexpected end of interpolation
"#{-}"
^
'''
assertErrorFormat '''
"#{--}"
''', '''
[stdin]:1:6: error: unexpected end of interpolation
"#{--}"
^
'''
assertErrorFormat '''
"#{~}"
''', '''
[stdin]:1:5: error: unexpected end of interpolation
"#{~}"
^
'''
assertErrorFormat '''
"#{!}"
''', '''
[stdin]:1:5: error: unexpected end of interpolation
"#{!}"
^
'''
assertErrorFormat '''
"#{not}"
''', '''
[stdin]:1:7: error: unexpected end of interpolation
"#{not}"
^
'''
assertErrorFormat '''
"#{5) + (4}_"
''', '''
[stdin]:1:5: error: unmatched )
"#{5) + (4}_"
^
'''
# #2918
assertErrorFormat '''
"#{foo.}"
''', '''
[stdin]:1:8: error: unexpected end of interpolation
"#{foo.}"
^
'''
test "#3325: implicit indentation errors", ->
assertErrorFormat '''
i for i in a then i
@@ -139,3 +210,311 @@ test "explicit indentation errors", ->
c
^^
'''
test "unclosed strings", ->
assertErrorFormat '''
'
''', '''
[stdin]:1:1: error: missing '
'
^
'''
assertErrorFormat '''
"
''', '''
[stdin]:1:1: error: missing "
"
^
'''
assertErrorFormat """
'''
""", """
[stdin]:1:1: error: missing '''
'''
^
"""
assertErrorFormat '''
"""
''', '''
[stdin]:1:1: error: missing """
"""
^
'''
assertErrorFormat '''
"#{"
''', '''
[stdin]:1:4: error: missing "
"#{"
^
'''
assertErrorFormat '''
"""#{"
''', '''
[stdin]:1:6: error: missing "
"""#{"
^
'''
assertErrorFormat '''
"#{"""
''', '''
[stdin]:1:4: error: missing """
"#{"""
^
'''
assertErrorFormat '''
"""#{"""
''', '''
[stdin]:1:6: error: missing """
"""#{"""
^
'''
assertErrorFormat '''
///#{"""
''', '''
[stdin]:1:6: error: missing """
///#{"""
^
'''
assertErrorFormat '''
"a
#{foo """
bar
#{ +'12 }
baz
"""} b"
''', '''
[stdin]:4:11: error: missing '
#{ +'12 }
^
'''
# https://github.com/jashkenas/coffeescript/issues/3301#issuecomment-31735168
assertErrorFormat '''
# Note the double escaping; this would be `"""a\"""` real code.
"""a\\"""
''', '''
[stdin]:2:1: error: missing """
"""a\\"""
^
'''
test "unclosed heregexes", ->
assertErrorFormat '''
///
''', '''
[stdin]:1:1: error: missing ///
///
^
'''
# https://github.com/jashkenas/coffeescript/issues/3301#issuecomment-31735168
assertErrorFormat '''
# Note the double escaping; this would be `///a\///` real code.
///a\\///
''', '''
[stdin]:2:1: error: missing ///
///a\\///
^
'''
test "unexpected token after string", ->
# Parsing error.
assertErrorFormat '''
'foo'bar
''', '''
[stdin]:1:6: error: unexpected bar
'foo'bar
^^^
'''
assertErrorFormat '''
"foo"bar
''', '''
[stdin]:1:6: error: unexpected bar
"foo"bar
^^^
'''
# Lexing error.
assertErrorFormat '''
'foo'bar'
''', '''
[stdin]:1:9: error: missing '
'foo'bar'
^
'''
assertErrorFormat '''
"foo"bar"
''', '''
[stdin]:1:9: error: missing "
"foo"bar"
^
'''
test "#3348: Location data is wrong in interpolations with leading whitespace", ->
assertErrorFormat '''
"#{ {"#{key}": val} }"
''', '''
[stdin]:1:7: error: unexpected interpolation
"#{ {"#{key}": val} }"
^^
'''
test "octal escapes", ->
assertErrorFormat '''
"a\\0\\tb\\\\\\07c"
''', '''
[stdin]:1:10: error: octal escape sequences are not allowed \\07
"a\\0\\tb\\\\\\07c"
\ \ \ \ ^
'''
test "illegal herecomment", ->
assertErrorFormat '''
###
Regex: /a*/g
###
''', '''
[stdin]:2:12: error: block comments cannot contain */
Regex: /a*/g
^
'''
test "#1724: regular expressions beginning with *", ->
assertErrorFormat '''
/* foo/
''', '''
[stdin]:1:2: error: regular expressions cannot begin with *
/* foo/
^
'''
assertErrorFormat '''
///
* foo
///
''', '''
[stdin]:2:3: error: regular expressions cannot begin with *
* foo
^
'''
test "invalid regex flags", ->
assertErrorFormat '''
/a/ii
''', '''
[stdin]:1:4: error: invalid regular expression flags ii
/a/ii
^
'''
assertErrorFormat '''
/a/G
''', '''
[stdin]:1:4: error: invalid regular expression flags G
/a/G
^
'''
assertErrorFormat '''
/a/gimi
''', '''
[stdin]:1:4: error: invalid regular expression flags gimi
/a/gimi
^
'''
assertErrorFormat '''
/a/g_
''', '''
[stdin]:1:4: error: invalid regular expression flags g_
/a/g_
^
'''
assertErrorFormat '''
///a///ii
''', '''
[stdin]:1:8: error: invalid regular expression flags ii
///a///ii
^
'''
doesNotThrow -> CoffeeScript.compile '/a/ymgi'
test "missing `)`, `}`, `]`", ->
assertErrorFormat '''
(
''', '''
[stdin]:1:1: error: missing )
(
^
'''
assertErrorFormat '''
{
''', '''
[stdin]:1:1: error: missing }
{
^
'''
assertErrorFormat '''
[
''', '''
[stdin]:1:1: error: missing ]
[
^
'''
assertErrorFormat '''
obj = {a: [1, (2+
''', '''
[stdin]:1:15: error: missing )
obj = {a: [1, (2+
^
'''
assertErrorFormat '''
"#{
''', '''
[stdin]:1:3: error: missing }
"#{
^
'''
assertErrorFormat '''
"""
foo#{ bar "#{1}"
''', '''
[stdin]:2:7: error: missing }
foo#{ bar "#{1}"
^
'''
test "unclosed regexes", ->
assertErrorFormat '''
/
''', '''
[stdin]:1:1: error: missing / (unclosed regex)
/
^
'''
assertErrorFormat '''
# Note the double escaping; this would be `/a\/` real code.
/a\\/
''', '''
[stdin]:2:1: error: missing / (unclosed regex)
/a\\/
^
'''
assertErrorFormat '''
/// ^
a #{""" ""#{if /[/].test "|" then 1 else 0}"" """}
///
''', '''
[stdin]:2:18: error: missing / (unclosed regex)
a #{""" ""#{if /[/].test "|" then 1 else 0}"" """}
^
'''
test "duplicate function arguments", ->
assertErrorFormat '''
(foo, bar, foo) ->
''', '''
[stdin]:1:12: error: multiple parameters named foo
(foo, bar, foo) ->
^^^
'''
assertErrorFormat '''
(@foo, bar, @foo) ->
''', '''
[stdin]:1:13: error: multiple parameters named @foo
(@foo, bar, @foo) ->
^^^^
'''

Some files were not shown because too many files have changed in this diff Show More