Compare commits

...

588 Commits
0.5.0 ... 0.7.1

Author SHA1 Message Date
Jeremy Ashkenas
e40d25e4bd rebuilding docs and compressed version for CoffeeScript 0.7.1 2010-07-11 10:40:44 -04:00
Jeremy Ashkenas
2a7a26482a fixing optparse to behave nicely in the presence of hashbangs -- stop parsing after the first non-option argument, and pass the rest along -- and adding an OptionParser test. 2010-07-11 09:57:42 -04:00
Jeremy Ashkenas
3d6cdfa636 making it possible to pass in command-line arguments to a hash-banged coffee script. Ticket #473 2010-07-10 15:36:54 -04:00
Jeremy Ashkenas
15a2b7d69a Fixing issue number #486 (which is debatable). Allowing an unparenthesized if/else ternary as a trailing parameter to a call. 2010-07-10 14:52:54 -04:00
Jeremy Ashkenas
9ff8433f21 fixing previously-escaped-inner-quotes-in-double-quoted-heredoc-interpolations. Issue #479 2010-07-10 11:54:59 -04:00
Jeremy Ashkenas
1c7d51a2c4 fixing issue #485, unary minus following an existential operator. 2010-07-10 11:27:43 -04:00
Jeremy Ashkenas
49020208f9 better printing for OpNodes with running with --nodes 2010-07-10 11:17:44 -04:00
Jeremy Ashkenas
6f32fe27f8 better formatting for top-level closured-values. 2010-07-10 09:49:01 -04:00
Jeremy Ashkenas
7a16db9ad3 fixing inline-loop object-in-array tests for instance variables. Issue #481 2010-07-10 09:01:22 -04:00
Jeremy Ashkenas
2f8a29b5a0 fixing a comment/block-comment combination lexing regex issue. Ticket #478 2010-07-10 08:44:30 -04:00
Jeremy Ashkenas
64b5ccc524 Fixes issue #477, missing global helpers in REPL. 2010-07-09 01:01:31 -04:00
Jeremy Ashkenas
4fc4edc7a0 adding wavded's gedit-coffeescript to the resources section of the docs 2010-07-08 10:18:18 -04:00
Jeremy Ashkenas
358edfb21f fixing return node squashing the possiblity of a ternary, when there should be one. Issue #475 2010-07-06 23:04:35 -04:00
Jeremy Ashkenas
577daf5457 fixing herecomment/indentation bugaboo ... issue #474 2010-07-06 22:20:42 -04:00
Jeremy Ashkenas
afa3bb4191 added dsc's coffeecup to the resources section. 2010-07-05 08:51:45 -04:00
Jeremy Ashkenas
e81810d845 fixing issue #427 -- incorrect stringification of reserved word 2010-07-04 20:55:21 -04:00
Jeremy Ashkenas
c57ebffe6f fixing Lexer::OPERATOR regex for non-spaced + unary arithmetic. Issue #471 2010-07-04 13:29:22 -04:00
Jeremy Ashkenas
e281133f12 fixing empty catch clauses ... Issue #470 2010-07-04 12:50:04 -04:00
Jeremy Ashkenas
92878558c6 fixing improper formatting in range-to-array expansion. 2010-07-03 17:00:30 -04:00
Jeremy Ashkenas
ec449158c6 fixing improperly-formatted-output of pattern matching within comprehension arguments. 2010-07-03 15:09:21 -04:00
Jeremy Ashkenas
eefa004b8f fixing the block comment test to use defined variables. 2010-07-01 21:51:28 -04:00
Jeremy Ashkenas
77a75ed365 adding passed-through block comments back to the grammar/lexer/rewriter/nodes ... thanks, Trevor Burnham. 2010-07-01 21:26:33 -04:00
Jeremy Ashkenas
364ec2a694 better syntax errors for tokens-not-in-the-grammar. Coming soon to a Jison near you (hopefully) 2010-07-01 20:40:08 -04:00
Jeremy Ashkenas
9a8a707016 throw a syntax error if you try to use the fat arrow to define a class constructor. 2010-06-30 22:03:20 -04:00
Jeremy Ashkenas
7a5f014014 fixing closurenode wrapping of bodies with bound function declarations inside -- this doesn't have to be mentioned explicitly. 2010-06-30 21:54:16 -04:00
Jeremy Ashkenas
5ca5a504a4 allowing empty bodies in try blocks and in catch blocks 2010-06-30 20:53:09 -04:00
Jeremy Ashkenas
cb45c8feac fixing html entity in the changelog 2010-06-30 19:51:49 -04:00
Jeremy Ashkenas
7d79d73b58 allowing paren-less instance creation, a la 'new Class' 2010-06-29 21:03:50 -04:00
Jeremy Ashkenas
7c426db36a fixing range literals (which had gone untested) oops. 2010-06-28 20:26:31 -04:00
Jeremy Ashkenas
744638ed08 adding a one-line exception test. 2010-06-28 08:52:13 -04:00
Jeremy Ashkenas
9bc7cd7904 adding a one-line exception test. 2010-06-28 08:50:44 -04:00
Jeremy Ashkenas
d83bbfb1d5 updating readme with NPM install. 2010-06-28 01:19:04 -04:00
Jeremy Ashkenas
4ad9e82f50 docs for the NPM install 2010-06-28 01:06:53 -04:00
Jeremy Ashkenas
677c7edf3f CoffeeScript 0.7.0 is on the books. 2010-06-28 01:00:53 -04:00
Jeremy Ashkenas
e56af4967c removing our vendor'd copy of Jison ... you should install it from NPM now. 2010-06-28 00:26:45 -04:00
Jeremy Ashkenas
1f7af35368 getting ready for a 0.7.0. cleanups and doc revisions, not quite there yet. 2010-06-28 00:19:58 -04:00
Jeremy Ashkenas
08ab4abd43 removing obvious redundant parentheses. 2010-06-27 23:55:18 -04:00
Jeremy Ashkenas
a810eb29db slightly simpler comment regex. 2010-06-27 22:26:59 -04:00
Jeremy Ashkenas
3881324007 cleaning up the grammar rule for Super 2010-06-27 16:50:31 -04:00
Jeremy Ashkenas
af3b356d70 fixing an improper-js-output bug when using a loop-compiled inarray clause as part of a larger expression 2010-06-27 13:27:51 -04:00
Jeremy Ashkenas
24676eea71 Fixing commented-out if-clauses or empty if-clauses. 2010-06-27 13:19:23 -04:00
Jeremy Ashkenas
7e2eb997a8 adding a test for trailing-comments-preceding-outdents 2010-06-27 13:02:47 -04:00
Jeremy Ashkenas
ec570c46bf Big commit. First draft of stripping comments from generated JS output. Issue #41 2010-06-27 12:59:54 -04:00
Jeremy Ashkenas
8eedfe4bc6 slight simplification of the if-else grammar rules 2010-06-27 11:46:30 -04:00
Jeremy Ashkenas
800fb81d1b Re-ordering lexer rules for fewer regex matches / slightly faster lexing. 2010-06-27 10:58:08 -04:00
Jeremy Ashkenas
e020f5849c adding a test for #454 2010-06-26 17:21:30 -04:00
Jeremy Ashkenas
698784e103 fixing issue #454 single-line function with single-line if/else 2010-06-26 17:20:13 -04:00
Jeremy Ashkenas
f7345ffaac removing extensions from CoffeeScript 2010-06-26 13:36:31 -04:00
Jeremy Ashkenas
b7faa4a7f2 using the new in-tests for the Rewriter. 2010-06-21 23:54:43 -04:00
Jeremy Ashkenas
0fcfb80be4 switching 'a in b' to 'a of b', and adding an array presence check for 'a in b'. 2010-06-21 23:51:12 -04:00
Jeremy Ashkenas
38a9b7166b Adding TrevorBurnham's suggestion for 'a not in b' 2010-06-21 22:25:28 -04:00
Jeremy Ashkenas
3b28f52ff7 adding non-ASCII characters to test_literals.coffee for Node v0.1.99 2010-06-21 20:47:58 -04:00
Jeremy Ashkenas
7725fe338e Merge branch 'npm' of git://github.com/Tim-Smart/coffee-script 2010-06-21 18:57:17 -04:00
Tim-Smart
2ed66f6e8b Update package.json to allow for npm publishing and installation 2010-06-22 10:48:49 +12:00
Jeremy Ashkenas
9aaf789c21 changing a couple repetitions to DRY objects ... doesn't change the compiled output. 2010-06-20 11:19:50 -04:00
Jeremy Ashkenas
d5cf339b83 adding a test for holmsand's patch for Object.prototype-named variables. 2010-06-16 07:24:17 -04:00
Dan Holmsand
6bc7b56e6e Make sure variables named e.g. "constructor" are declared with var 2010-06-16 12:54:53 +02:00
Jeremy Ashkenas
e4db6d47c2 Updated Cakefile from Tim_Smart with colorized, explained 'cake install' 2010-06-15 21:33:53 -04:00
Jeremy Ashkenas
ce4e00e5ae mistaken camelCase 'nodeLibraries' from the great under_score purge ... now fixed. 2010-06-15 20:40:10 -04:00
Jeremy Ashkenas
06ca2ef726 more streamlined code generation for instance-bound methods ... keep the prototype method around, and just bind it in the constructor. 2010-06-15 02:21:01 -04:00
Jeremy Ashkenas
8d853a6d58 adding the ability to have classes with functions pre-bound to the instance, using the fat arrow, and the constructor-function-definition pattern, avoiding prototypes. 2010-06-15 01:28:30 -04:00
Jeremy Ashkenas
de768aefc3 a bit more work on keywords-in-object-literals... 2010-06-15 01:03:14 -04:00
Jeremy Ashkenas
4b284f6687 first draft at ticket #437 ... automatic quoting of reserved words and keywords. 2010-06-15 00:54:02 -04:00
Jeremy Ashkenas
d0948e5586 fixing comprehensions to also close over the index variable, if used in an inner function... 2010-06-13 21:43:04 -04:00
Jeremy Ashkenas
b0a45e5b93 Ticket #423. When functions are generated within comprehensions ... the comprehensions should close over the element instead of sharing it. 2010-06-13 21:21:30 -04:00
Jeremy Ashkenas
6f91331626 slight refactor to IfNode::ensureExpressions 2010-06-13 18:04:09 -04:00
Jeremy Ashkenas
4ecb1bb2ed switching to 'Compiled' messages after the code has finished compiling on --watch ... 2010-06-13 14:21:02 -04:00
Jeremy Ashkenas
3bcca99cba adding another statement/expression/return test. 2010-06-13 01:19:31 -04:00
Jeremy Ashkenas
5612a59b30 allowing implicit returns to be pushed down into each branch of computation, even when there's an explicit return nested more deeply. Issue #401 2010-06-13 01:13:52 -04:00
Jeremy Ashkenas
88ea66b4c9 allowing a regex literal to be the last token in a file ... Lexer bug. 2010-06-13 00:56:42 -04:00
Jeremy Ashkenas
b61399fbde fixing issue #396 ... issue with nested if/elses getting mis-nested. 2010-06-12 19:38:14 -04:00
Jeremy Ashkenas
a8db2bcf10 fixing a mistaken camelCase in the Cakefile 2010-06-12 19:10:10 -04:00
Jeremy Ashkenas
e14f4c5db1 First draft of switching the CoffeeScript Compiler over to camelCase. Pour one on the ground for underscores... 2010-06-12 19:05:13 -04:00
Jeremy Ashkenas
1948b0c7c7 linebreaks in the rewriter ... cosmetic. 2010-06-12 18:09:07 -04:00
Jeremy Ashkenas
4b4b0e630e yet another rewriter-based comment fix, this time for issue #403 2010-06-12 18:06:33 -04:00
Jeremy Ashkenas
d9071a80a0 Unsatisfactory patch that fixes Issue #394 ... comments that prefix spaced out if/else clauses. 2010-06-12 17:41:46 -04:00
Jeremy Ashkenas
969740a263 slight simplification to if/else in the grammar. 2010-06-12 13:53:11 -04:00
Jeremy Ashkenas
0222d90fa3 adding a 'loop' keyword to CoffeeScript. Takes an expression or a block. Runs it until you break or return out. 2010-06-12 12:15:53 -04:00
Jeremy Ashkenas
a133e018cc Making the REPL the default behaviour of 'coffee', when called with no arguments, a-la Node and Python. 2010-06-12 11:09:30 -04:00
Jeremy Ashkenas
c2d1ae06c5 removing the <- bind operator from CoffeeScript... 2010-06-12 11:00:56 -04:00
Jeremy Ashkenas
59e41f195b simpler 'cake loc' task. 2010-06-11 18:53:12 -04:00
Jeremy Ashkenas
7987d4e5ce adding a cake task to check loc 2010-06-11 18:47:48 -04:00
Jeremy Ashkenas
a8e331a778 new improved REPL, using Node's new 'readline' module... 2010-06-11 18:36:18 -04:00
Jeremy Ashkenas
eb97652537 adding a sentence about parentheses wrapping. 2010-06-11 17:28:18 -04:00
Jeremy Ashkenas
0a4fe7ed97 fixing the lexer so that leading commas surpress newlines 2010-06-11 08:29:16 -04:00
Jeremy Ashkenas
676e893c14 reworking parser for more permissive non-comma-separated array elements. 2010-06-09 00:37:23 -04:00
Jeremy Ashkenas
e37056192b Fix for issue #414 -- apostrophes in heredocs. 2010-06-02 19:53:03 -04:00
Jeremy Ashkenas
8321f6bfe3 making block comments require their own lines for delimiters. Issue 379. 2010-06-02 00:03:07 -04:00
Jeremy Ashkenas
b3d1c238eb fixing block comments at the top of function blocks, and in other locations ... Issue #379 2010-06-01 23:56:10 -04:00
Jeremy Ashkenas
61d9bd7e5e making the lexer more sophisticated about incorrect outdents ... a little safer for everyone. 2010-06-01 23:32:46 -04:00
Jeremy Ashkenas
1fbb6e8734 adding copying header to extras/coffee-script.js 2010-06-01 22:09:00 -04:00
Jeremy Ashkenas
59de6b505a ahh, finally. switched up our Jison configuration to provide better syntax errors. Now you get the unexpected token, instead of the expected one. 2010-06-01 20:21:12 -04:00
Jeremy Ashkenas
ea1411cd07 removing call to deprecated sys.p() in the REPL, now it's 'puts inspect value' 2010-06-01 19:24:48 -04:00
Jeremy Ashkenas
c5fd64c72a allowing direct calls against numbers. 2010-05-31 22:56:51 -04:00
Jeremy Ashkenas
45f442bd73 allowing Klass::['dynamic-property'] syntax. Issue #392 2010-05-31 22:32:43 -04:00
Jeremy Ashkenas
b8a4adbdc7 whitespace adjustments 2010-05-31 19:54:28 -04:00
Jeremy Ashkenas
47fdcebb01 one more range comprehension vs range literal test, for thoroughness. 2010-05-31 19:43:30 -04:00
Jeremy Ashkenas
8cdd8de360 adding a negative range comprehension test. 2010-05-31 19:41:02 -04:00
Jeremy Ashkenas
7402aea9f2 cleaner generated code for range comprehensions, but you have to use an explicit step to go downwards. Forked the code path for cleaner range literals as well. 2010-05-31 19:38:45 -04:00
Jeremy Ashkenas
300c711af1 enabling compilation of non-.coffee-extension files passed directly to the coffee command (Issue #391) 2010-05-31 15:36:41 -04:00
Jeremy Ashkenas
39b8bbc39b Moving all of the 'test_issues' tests from 'hiatus' to their proper locations... 2010-05-31 15:13:48 -04:00
Jeremy Ashkenas
90f96af720 Simpler stab at a fix for issue #397. Allow CoffeeScript-only keywords to be used as accessors, or in assignment. 2010-05-31 14:42:30 -04:00
Jeremy Ashkenas
710b2b5fdc moving issue #381 test to the proper spot. 2010-05-31 14:03:07 -04:00
Jeremy Ashkenas
a577b81eb3 reworking fix for Issue #383 with a more sensitive regex. (decimals without a leading zero) 2010-05-31 13:40:03 -04:00
Jeremy Ashkenas
a5478b0712 refactoring name_access_type into tag_accessor 2010-05-31 13:25:06 -04:00
Jeremy Ashkenas
12587d8295 reworking Stan's nodes.coffee type/children work a bit for issue 386 2010-05-31 10:36:50 -04:00
Stan Angeloff
e17bb4ff11 FIXES #397: Can't use @variable in switch in instance method 2010-05-26 21:58:11 +03:00
Stan Angeloff
aba19841ee FIXES #390: super() calls in constructor of classes that are defined as object properties 2010-05-25 09:15:46 +03:00
Stan Angeloff
0288dba46c Whoops, forgot the extra condition before we perform the rewrite 2010-05-23 12:52:49 +03:00
Stan Angeloff
5a306785ba Tests to ensure reserver words and operators can be used as object keys 2010-05-23 12:44:40 +03:00
Stan Angeloff
c200b95f6a Allowing operators as object keys 2010-05-23 12:42:15 +03:00
Stan Angeloff
2cccd621ea First steps in allowing reserved words as object keys 2010-05-23 12:21:31 +03:00
Stan Angeloff
385b18f588 FIXES #383: Numbers that start with . not recognized 2010-05-20 00:20:33 +03:00
Stan Angeloff
bf1f9f4b95 FIXES #380: problem with @ and instanceof 2010-05-19 23:51:53 +03:00
Stan Angeloff
4c3271728d OOP love for nodes.coffee 2010-05-19 23:24:55 +03:00
Stan Angeloff
57231ae75d Merging type, children and statement functions 2010-05-19 22:53:05 +03:00
Stan Angeloff
97c2a70593 Baby steps fixing #386 2010-05-19 22:37:42 +03:00
Jeremy Ashkenas
485346f0e5 CoffeeScript 0.6.2 2010-05-15 01:18:05 -04:00
Jeremy Ashkenas
a8d4c3a567 sprinkling toString() throughout, for Node.js 0.1.95 compatibility. 2010-05-15 00:34:14 -04:00
Jeremy Ashkenas
dfb3a13246 Fixed lingering CoffeeScript Compiler running live in Internet Explorer bugs. Implemented helpers.index_of and removed named functions. Ticket #366 2010-05-14 23:40:04 -04:00
Jeremy Ashkenas
f84eb9ed47 fixing heredoc indentation from herecomment tweaks 2010-05-14 21:50:17 -04:00
Jeremy Ashkenas
8136c5f3de making regexes stricter about their flags. 2010-05-14 09:14:41 -04:00
Jeremy Ashkenas
45669e08c6 better indentation handling for far-left heredocs and herecomments 2010-05-12 21:49:46 -04:00
Jeremy Ashkenas
a5db69e1af better indentation handling for far-left heredocs and herecomments 2010-05-12 21:47:31 -04:00
Jeremy Ashkenas
8aceef20e1 Adding initial implementation of here-comments (block comments) Issue #368 2010-05-12 20:56:44 -04:00
Jeremy Ashkenas
7e3c71ed19 Allowing more flexible linebreaks/indentation within object literals. 2010-05-12 18:28:40 -04:00
Jeremy Ashkenas
9d09bee6fb better test for sans-condition switch... 2010-05-11 09:32:16 -04:00
Jeremy Ashkenas
cd6ee373ff enabling condition-less switches. 2010-05-10 22:57:51 -04:00
Jeremy Ashkenas
4d0acc9b02 fixing andreyvit's issue with parentheses not being applied to multi-operators as the condition clause of a switch... 2010-05-10 22:50:11 -04:00
Jeremy Ashkenas
393fbf1b66 merging in gfxmonk's cleanup to how children of nodes are determined. Removing some (so far) unused portions. 2010-05-10 22:41:18 -04:00
gfxmonk
3324b03a5d Merge remote branch 'upstream/master'
Conflicts:
	src/nodes.coffee
2010-05-10 21:09:00 +10:00
gfxmonk
eb91f9922d determine @children dynamically based on attribute names, instead of manual bookkeeping 2010-05-10 20:58:01 +10:00
Jeremy Ashkenas
9a7420ccd0 adding support for calling variadic functions with less than the requested number of arguments. 2010-05-08 12:44:54 -04:00
Jeremy Ashkenas
be72120311 further minor cleanup to varargs 2010-05-08 12:20:14 -04:00
Jeremy Ashkenas
c452c3a101 minor cleanup to varargs 2010-05-08 12:15:47 -04:00
Tim Jones
0b3bb66708 Added safe soaking on non-existent variables. 2010-05-05 21:58:48 +12:00
Jeremy Ashkenas
d0d0fa4d10 disallowing regex literals as implicit calls immediatly after ']', a rare case, I hope. Ticket #358 2010-05-04 23:50:22 -04:00
Jeremy Ashkenas
6222ed622f forcing spaces for implicit calls ... making '@ name' a call instead of an access. Ticket #353 2010-05-04 23:44:54 -04:00
Jeremy Ashkenas
1a03e98057 making 'while' and 'until' have the same associativity and precedence as 'for', #356 2010-05-04 23:37:03 -04:00
Jeremy Ashkenas
46cea93fc3 recompiling annotated documentation 2010-05-04 23:31:28 -04:00
Jeremy Ashkenas
d64b8fd9d8 merged in Trevor Burnham's recursive coffee compilation, with some adjustments... 2010-05-04 23:22:28 -04:00
Jeremy Ashkenas
c051daee2f Merge commit 'TrevorBurnham/master' 2010-05-04 23:01:15 -04:00
Tim Jones
ae70d10996 Removing obsolete delete calls. 2010-05-03 21:17:30 -04:00
Tim Jones
52e6399e02 Added missing or to IndexNode. 2010-05-03 21:17:23 -04:00
Tim Jones
ac05f62f2f Wrapping all soaked chains that are involved in operations. 2010-05-03 21:17:16 -04:00
Tim Jones
4d935efd09 Stop anonymous supers. 2010-05-03 21:16:50 -04:00
Trevor Burnham
fa8cc7976a Added recursive compilation and monitoring option to coffee command 2010-05-03 17:38:59 -04:00
Jeremy Ashkenas
ee4e34bf6d relative requires... 2010-05-01 11:00:43 -04:00
gfxmonk
c8e0f8b149 Cleaned up IfNodes
- renamed rewrite_condition() to switches_over(),
   and @switcher to @switch_subject
 - removed unused else_body constructor parameter, as well
   as unnecessary push() method
 - ensure both @body and @else_body are always Expressions
   (previously they could be either Expressions or IfNode)
2010-05-02 00:39:34 +10:00
gfxmonk
b47188763c add require statements to tests that depend on coffee-script modules 2010-05-02 00:27:50 +10:00
Jeremy Ashkenas
5e5c9df5c4 removing holmsand's cleanup 2010-05-01 08:40:02 -04:00
Jeremy Ashkenas
1a97f599dd added a test for the multiple-functions-passed-sans-parens 2010-04-30 23:20:22 -04:00
Tim Jones
3b264c9572 Added a small part to the rewriter to allow a better two-function call. 2010-05-01 14:04:57 +12:00
Dan Holmsand
144c096ae6 Remove unused variable index_var from for loops 2010-04-30 09:48:30 +02:00
Jeremy Ashkenas
adbcd320b2 adding until loops as the inverse of while loops 2010-04-28 22:08:00 -04:00
Jeremy Ashkenas
17ba44056e changing 'filter' to 'guard' to get around Express' clobbering of Object.prototype. 2010-04-28 21:46:47 -04:00
Jeremy Ashkenas
502abade7c rewriting the compiler using 'unless' blocks where appropriate. 2010-04-27 19:38:24 -04:00
Jeremy Ashkenas
b746c9018e adding 'unless' blocks 2010-04-27 19:35:15 -04:00
Jeremy Ashkenas
92af641827 no newline on no_such_task for Cake 2010-04-27 07:59:19 -04:00
Jeremy Ashkenas
b5606a247d adding pattern matching for comprehensions. 2010-04-26 23:46:35 -04:00
Jeremy Ashkenas
d62baf5a5d Merge branch 'for_destructuring' of git://github.com/StanAngeloff/coffee-script 2010-04-26 23:34:07 -04:00
Jeremy Ashkenas
e17567866a Merge branch 'master' of git://github.com/Tesco/coffee-script 2010-04-26 23:31:18 -04:00
Stan Angeloff
76f9596f22 Cleaning up. 2010-04-26 21:54:31 +03:00
Stan Angeloff
2a3a713811 Allowing pattern matching within for..loops 2010-04-26 21:35:35 +03:00
gfxmonk
175ebb3cd8 fail with appropriate error status if child process fails 2010-04-26 16:08:19 +10:00
Tim Jones
95367a4a63 Fixing silly mistake with the comments. 2010-04-26 16:00:12 +12:00
Tim Jones
8950c3c4c8 Fixing invalid pattern matching and object creation. 2010-04-26 15:54:47 +12:00
Jeremy Ashkenas
2d1abd099d rewriting the Lexer, CommandLine, Nodes, and Rewriter to take advantage of the new DRY object pattern matching. 2010-04-25 22:29:43 -04:00
Jeremy Ashkenas
a894db35fd Got the DRY object pattern matching style working properly, from Harmony. {name, age}: person now works correctly. 2010-04-25 22:21:53 -04:00
Jeremy Ashkenas
328a14014c eliminating the IndentedAssignList nonterminal. 2010-04-25 21:22:29 -04:00
Jeremy Ashkenas
315a2c63fa simplifying the grammar by replacing all of our trailing comma rules with an OptComma nonterminal. 2010-04-25 21:17:46 -04:00
Jeremy Ashkenas
ca4ea7649d Throwing an error when pattern matching has a non-identifier on the left-hand side. 2010-04-25 11:22:15 -04:00
Jeremy Ashkenas
08c877ec7b Fixing string keys in pattern matching on objects (ticket 325) 2010-04-25 11:07:09 -04:00
Jeremy Ashkenas
212ad45be4 merging gfxmonk's removed error event fix. 2010-04-24 22:13:13 -04:00
gfxmonk
e9b37c7578 replaced nonexistant error event callback with a combination of stderr and exit events 2010-04-25 11:24:06 +10:00
Jeremy Ashkenas
1438cecfad Fixing splats-with-super()-in-classes, an oversight. 2010-04-24 15:57:15 -04:00
Jeremy Ashkenas
49824ce1a6 removing yytext mentions for real this time. 2010-04-21 23:21:48 -04:00
Jeremy Ashkenas
bc0ec9dc07 Revert "removing yytext mentions from the grammar"
This reverts commit 5957b9f155.
2010-04-21 23:10:45 -04:00
Jeremy Ashkenas
5957b9f155 removing yytext mentions from the grammar 2010-04-21 23:01:14 -04:00
Jeremy Ashkenas
72e6e828f1 new version of Jison vendored ... rebuild the grammar, tests pass. 2010-04-21 22:52:20 -04:00
Jeremy Ashkenas
01b4393fa7 fixing Issue #328, parse error with indents and comments (StanAngeloff) 2010-04-21 22:26:45 -04:00
Jeremy Ashkenas
bf2a5386f9 requiring helpers module in test_bind.coffee 2010-04-21 19:52:58 -04:00
Jeremy Ashkenas
fb4d4a609b making bin/cake install add CoffeeScript as a Node.js library, and creating an index.js file for the top-level inclusion. 2010-04-20 20:20:38 -04:00
Jeremy Ashkenas
1cddb2aa88 Redoing Rewriter#add_implicit_parentheses to be more robust. 2010-04-20 01:32:12 -04:00
Jeremy Ashkenas
aac9679282 merging in gfodor's excellent Rewriter patch. 2010-04-19 23:18:39 -04:00
Jeremy Ashkenas
90472685e8 Merge branch 'master' of git://github.com/gfodor/coffee-script 2010-04-19 23:12:24 -04:00
Jeremy Ashkenas
7bb764b3e4 ignoring raw 2010-04-18 18:14:17 -04:00
Greg Fodor
1aed9c545f Fix for bug with chaining 2010-04-18 00:41:47 -04:00
Jeremy Ashkenas
c937e49689 adding 'coffeescript-idea' to the resources section. 2010-04-13 23:41:18 -04:00
Jeremy Ashkenas
0d860516ac fixing non-spaced function application. 2010-04-13 09:05:55 -04:00
Jeremy Ashkenas
4ced1d65b4 allowing 'debugger' ... it should never have been a reserved word. 2010-04-12 21:23:01 -04:00
Jeremy Ashkenas
92540d5e85 CoffeeScript 0.6.1, for Node.js v0.1.90 2010-04-12 21:20:00 -04:00
Jeremy Ashkenas
ea982a627e adding coffee-haml-filter to the docs 2010-04-11 17:57:29 -04:00
Jeremy Ashkenas
835ecac8db simplifying some unecessary interpolated expressions into interpolated values. 2010-04-11 16:57:53 -04:00
Jeremy Ashkenas
c3bbb48041 adding a test case for issue 309, interpolations with implicit calls. 2010-04-11 09:37:48 -04:00
Jeremy Ashkenas
2e842f0146 merging Stan's recursive tokenizing fix for interpolations. 2010-04-11 09:26:21 -04:00
Jeremy Ashkenas
8de2fb9009 Merge commit 'StanAngeloff/issue_309' 2010-04-11 09:22:31 -04:00
Stan Angeloff
17e177405a FIXES #309: Optional parens and interpolation. 2010-04-11 12:22:54 +03:00
Dr Nic Williams
ef67561fb3 Using anonymous callback for 'exit' event when running tests 2010-04-11 19:05:49 +10:00
Jeremy Ashkenas
df97effb9c fixing implicit-call-in-function-in-parens bug. 2010-04-10 18:56:46 -04:00
Jeremy Ashkenas
8317960f81 Battery of patches for compatibility with Node v0.1.90 2010-04-10 18:05:35 -04:00
Jeremy Ashkenas
065bf54094 generated closures should only call() or apply() when necessary. 2010-04-10 14:40:05 -04:00
Jeremy Ashkenas
f36acc27e5 safely preserving the arguments object through generated closure wrappers. 2010-04-10 14:20:32 -04:00
Jeremy Ashkenas
491ad6de95 adding webchat to the doc page 2010-04-10 13:42:39 -04:00
Jeremy Ashkenas
3eedf8ed1b Adding noonat to the contributor list 2010-04-06 21:09:23 -04:00
Jeremy Ashkenas
75b260e495 Merge branch 'master' of git://github.com/noonat/coffee-script 2010-04-06 21:08:29 -04:00
noonat
2351948291 Renamed Lexer.tag() argument to new_tag, due to Rhino scope confusion 2010-04-05 22:58:56 -07:00
Tim Jones
538e518d76 Realigning function arrows. 2010-04-06 02:29:38 +12:00
Tim Jones
de955dacc4 Added Statement to the grammar. 2010-04-06 02:26:23 +12:00
Chris Lloyd
19ed63129e Interpolated strings are expressions. 2010-04-04 17:05:52 +10:00
Chris Lloyd
2e744a1c1b Failing test for string interpolation. Interpolated strings need to be expressions, not values. 2010-04-04 16:54:59 +10:00
Jeremy Ashkenas
89534b88b1 merging in Chris Lloyd's fix for optional descriptions on Cake tasks. 2010-04-04 00:20:17 -04:00
Jeremy Ashkenas
c067808b54 CoffeeScript 0.6.0 is on the books. 2010-04-03 20:43:50 -04:00
Jeremy Ashkenas
59ae79d8fb rebuilding the docs with the fixed highlighter for '@' and regexes. 2010-04-03 19:10:26 -04:00
Jeremy Ashkenas
ad1c5e1884 merging non-func-constructor-fix, but a little more forgiving. 2010-04-03 14:53:26 -04:00
Stan Angeloff
9958cedd89 Throwing proper error when "constructor" is not a function within a class body. 2010-04-03 21:43:42 +03:00
Jeremy Ashkenas
d1aaed4430 Merge branch 'master' of git://github.com/Tesco/coffee-script 2010-04-03 12:21:31 -04:00
Tim Jones
89debc87b2 Removing {@prop: value} from the grammar. 2010-04-04 04:18:29 +12:00
Jeremy Ashkenas
9d2c81ea54 rebuilding the docs with new pygments, no errors on '@' 2010-04-03 12:01:46 -04:00
Jeremy Ashkenas
44765907b3 tiny tweak 2010-04-03 11:16:49 -04:00
Jeremy Ashkenas
4a85f3d499 cleaning up tests ... consolidation, consistency... 2010-04-03 10:39:32 -04:00
Jeremy Ashkenas
f99b5ad463 Merging Tesco's invoking-this-fix 2010-04-03 09:58:45 -04:00
Tim Jones
8fc631269b Added a rule to prevent invoking THIS. 2010-04-03 14:14:16 +13:00
Tim Jones
a1975583a7 Added THIS to CALLABLE. 2010-04-03 13:58:21 +13:00
Jeremy Ashkenas
1c628e7883 fixing parens-around-implicit-function-with-multiline-chained-chaser bug 2010-04-01 23:38:20 -04:00
Jeremy Ashkenas
3605168e85 fixing single evaluation of functions used in chained comparisons wrapped in parentheses. 2010-03-31 22:48:47 -04:00
Jeremy Ashkenas
f86fca2739 merged tanob's fix for installing outside of /usr/local without a /bin 2010-03-31 21:30:14 -04:00
Adriano Bonat
0410748e2d Merge remote branch 'upstream/master' 2010-03-31 22:14:26 -03:00
Adriano Bonat
2172878f21 When installing in different prefixes, prefix + '/bin' may not exist. 2010-03-31 09:38:05 -03:00
Jeremy Ashkenas
d3a51fbfa1 stylistics: removing a bunch of unecessary parentheses 2010-03-31 00:17:49 -04:00
Jeremy Ashkenas
aae2405de4 removing all of the 'type' tags from the Nodes. Simply using constructor.name instead. 2010-03-31 00:04:14 -04:00
Jeremy Ashkenas
2b578367a9 rebuilding the source documentation with the new utility refactors 2010-03-30 23:53:02 -04:00
Jeremy Ashkenas
f9b028b78c __extend back to __extends, as is the correct name. 2010-03-30 20:15:51 -04:00
Jeremy Ashkenas
572aa4e98f reverting the grammar to the pre-slice notation. 2010-03-30 20:11:40 -04:00
Jeremy Ashkenas
864275f07e removing __range, and all the slice behavior it enabled. If you can't do array[-1], then you shouldn't be able to do array[0..-1] -- it's just too inconsistent. 2010-03-30 20:06:44 -04:00
Jeremy Ashkenas
998a7c8cb0 more cleanups, added a utility helper function to the codegen 2010-03-30 19:48:37 -04:00
Jeremy Ashkenas
6d7a04228f another reshuffle ... removed utilities.coffee entirely. 2010-03-30 19:42:09 -04:00
Jeremy Ashkenas
4a8c2e8a13 more refactors to utilities ... removing dependencies and the namespacing 2010-03-30 19:27:38 -04:00
Jeremy Ashkenas
f3a60edc5d simplifying the lookup of the top-level scope object 2010-03-30 19:21:14 -04:00
Jeremy Ashkenas
1e1146d61d more utility simplifications 2010-03-30 19:17:40 -04:00
Jeremy Ashkenas
832e1d8cb8 Utilities doesn't need to be a class, and removing __utilities.keys 2010-03-30 19:00:59 -04:00
Jeremy Ashkenas
4936211a9c modified shorter imlementation of bind 2010-03-30 18:49:55 -04:00
Jeremy Ashkenas
f0d731009f merged matehat's utility branch, arraySlice -> slice, removed dead dependency... 2010-03-30 18:27:53 -04:00
Jeremy Ashkenas
a6248d03e5 Merge branch 'slice' of git://github.com/matehat/coffee-script 2010-03-30 18:19:41 -04:00
Jeremy Ashkenas
a934cf4947 make JSLint happy about the while condition 2010-03-30 18:19:09 -04:00
matehat
c498b7090e Removed __splice in the same manner 2010-03-30 18:14:51 -04:00
matehat
ca9e45e8af Removed the __slice method, in favor of the native array slice method 2010-03-30 17:57:23 -04:00
matehat
97096696a2 Put back every utility functions on the global scope, automatically prefixed with __ and set them dynamically as reserved on the lexer. 2010-03-30 16:48:43 -04:00
matehat
27fb3763b4 A set of improvements on previous code 2010-03-30 16:14:07 -04:00
matehat
da43c70488 Merged in StanAngeloff excellent slice branch, applying recent factoring of utility functions 2010-03-30 15:43:30 -04:00
Stan Angeloff
76ade0cb4d Removing vendor specific files for measurement tests. 2010-03-30 14:33:57 -04:00
Stan Angeloff
09e1526bca Removing commented code in compile_splice -- this is working correctly now. 2010-03-30 14:33:57 -04:00
Stan Angeloff
7d1fbeb708 Re-compiling the core using the new __slice and __splice functions. 2010-03-30 14:32:37 -04:00
Stan Angeloff
15217c705e Allowing for negative indices in slice literals. 2010-03-30 14:30:15 -04:00
matehat
9f108e87eb Removed unused __hasProp assignment and declared Coffeescript a reserved name 2010-03-30 11:20:53 -04:00
matehat
1e786d6d8b Removed unnecessary check 2010-03-30 10:58:21 -04:00
matehat
0557eb9b93 Removed hard-coding of utility object name 2010-03-30 09:08:16 -04:00
matehat
241f6f3068 Applied the utility factoring into a "Coffeescript" object to the core. All tests pass fast. 2010-03-30 09:02:51 -04:00
Jeremy Ashkenas
326656245a using the new static properties of class definitions in the CoffeeScript compiler -- it's hardly used. 2010-03-29 21:49:20 -04:00
Jeremy Ashkenas
177ec92c39 adding class methods to class definition syntax, using '@' 2010-03-29 21:43:12 -04:00
Jeremy Ashkenas
711dacae5f more little documentation for the rewriter ... moving along 2010-03-29 21:22:12 -04:00
Jeremy Ashkenas
c19183118e removing a case from Rewriter#add_implicit_parentheses that apparently never happens... 2010-03-29 20:52:22 -04:00
Jeremy Ashkenas
0af132d0c6 update internal documentation ... it's been a while 2010-03-29 20:48:41 -04:00
Jeremy Ashkenas
83c0e77ca8 making the Rewriter's add_implicit_calls more sensitive of parenthetical arguments. 2010-03-28 17:12:30 -04:00
Jeremy Ashkenas
1e315b5a33 fixing single-line implicit call wrapped around function with trailing arguments 2010-03-28 16:44:41 -04:00
Tim Jones
6e0e0767f9 Removed unprocessed values on a for loop from the grammar. 2010-03-29 07:32:01 +13:00
Tim Jones
6df50399a9 Restricted class and extends values to simple assignments. 2010-03-29 06:14:35 +13:00
Tim Jones
7b9a8998cf Addressing some assignment issues. 2010-03-29 06:06:16 +13:00
Jeremy Ashkenas
7de5253318 removing unused reserved variable 'source var' from range comprehensions 2010-03-27 16:04:47 -04:00
Jeremy Ashkenas
eaf4a71d32 Revert "Added Unix-like piping. Allows chaining of function calls where every succeeding call receives as first argument the result of all preceding expressions."
This reverts commit 7ee10e06be.
2010-03-27 15:25:34 -04:00
Jeremy Ashkenas
4dd40034ed Revert "removing the special case for | or"
This reverts commit 9763839ed1.
2010-03-27 15:25:27 -04:00
Jeremy Ashkenas
030476d335 Revert "typo for @compile_bitwise_or"
This reverts commit 45aae5e322.
2010-03-27 15:25:19 -04:00
Jeremy Ashkenas
45aae5e322 typo for @compile_bitwise_or 2010-03-27 12:13:24 -04:00
Jeremy Ashkenas
9763839ed1 removing the special case for | or 2010-03-27 10:28:08 -04:00
Stan Angeloff
7ee10e06be Added Unix-like piping. Allows chaining of function calls where every succeeding call receives as first argument the result of all preceding expressions. 2010-03-27 15:49:33 +02:00
matehat
8f3ea1d0c5 Fixed a small bug that happened when having a trailing comma in multiline array and object literals 2010-03-26 14:11:34 -04:00
matehat
b9b87f7d8e Minor modifications to the grammar to allow a single trailing comma for function call arguments, array literal and object literals. Adjusted tests accordingly 2010-03-26 11:44:25 -04:00
Chris Lloyd
c9b6e82e2c Optional sentence descriptions for cake tasks. 2010-03-26 20:25:17 +11:00
Jeremy Ashkenas
c8f969b4a2 adding a test case for the explicit returns 2010-03-25 18:54:17 -04:00
Jeremy Ashkenas
ecd1c77f48 fixing explicit returns of comprehensions (and probably other things as well) 2010-03-25 18:51:24 -04:00
Jeremy Ashkenas
ad93d2fe4d added another language extension test for a << b into a.push(b) 2010-03-23 20:42:40 -04:00
Jeremy Ashkenas
5a4d401582 make sure that the source-hacking docs mention to 'git checkout lib' 2010-03-23 00:25:37 -04:00
Jeremy Ashkenas
590c069158 CoffeeScript 0.5.6 2010-03-23 00:18:50 -04:00
Jeremy Ashkenas
94185e3f70 Merge branch 'master' of git://github.com/matehat/coffee-script 2010-03-22 23:20:05 -04:00
Jeremy Ashkenas
9adcd16ec6 '=' -> ':' 2010-03-22 18:48:41 -04:00
matehat
74bcd898e7 improving readability a bit 2010-03-22 02:02:04 -04:00
matehat
296808d4d3 Added splats positional flexibility to pattern matching 2010-03-22 01:52:47 -04:00
Jeremy Ashkenas
b7519cb834 switching a couple of the half_assignment tests to ensure that : and = are still interchangeable 2010-03-21 23:46:58 -04:00
Jeremy Ashkenas
7d6c050048 more half-assignment tests 2010-03-21 23:39:05 -04:00
Jeremy Ashkenas
16f9a2e6b7 rewriting the compiler to use half-expression assignment 2010-03-21 23:33:24 -04:00
Jeremy Ashkenas
cbfe7f5822 fix and tests for half assignments... whew. 2010-03-21 23:24:24 -04:00
Jeremy Ashkenas
895cd88761 almost there with half-assignments 2010-03-21 23:06:04 -04:00
Jeremy Ashkenas
f2ea18b0ba removing AND OR NOT IS ISNT from the grammar 2010-03-21 22:07:46 -04:00
Jeremy Ashkenas
162f6b9d5c one step at a time 2010-03-21 22:05:49 -04:00
Jeremy Ashkenas
4f8ae3ccbe one more step 2010-03-21 21:46:53 -04:00
Jeremy Ashkenas
acd9be3863 one step further 2010-03-21 21:46:06 -04:00
Jeremy Ashkenas
ddf18ae34c nothing much 2010-03-21 21:26:12 -04:00
Jeremy Ashkenas
0da61ec47e adding a couple of interchangeable tests 2010-03-21 21:07:32 -04:00
Jeremy Ashkenas
80230414a2 merging in gfxmonk's major refactor to the way that returns are pushed down into the interior of expressions 2010-03-21 11:28:05 -04:00
Jeremy Ashkenas
ce7c0d176b briefer test runner output 2010-03-21 10:18:23 -04:00
Jeremy Ashkenas
4ec79732f1 merging gfxmonk's cleanups 2010-03-21 10:11:02 -04:00
gfxmonk
cc3c314988 Cleaned up return logic
- ReturnNodes are explicitly added during compilation
 - ReturnNode is used instead of scattering "return" throughout
   code compilation snippets
 - nodes gain a make_return method in order to do the most useful
   thing when a return is requested
2010-03-21 22:21:55 +11:00
gfxmonk
8553a89af2 improve feedback when running the test task
- run synchronously, to ensure ordering is consistent
 - big red error message (and exit status)
 - don't bail early
 - don't bother printing a stack trace (it's useless
   until we can get line numbers in eval'd code)
2010-03-21 22:21:47 +11:00
Jeremy Ashkenas
566321d67a fixing infinite recursion when compiling if statements containing pure_statements 2010-03-20 10:36:06 -04:00
Jeremy Ashkenas
a2778bf06d resolving issues with comments in the middle of unfinished single-line expressions. 2010-03-20 00:58:25 -04:00
Jeremy Ashkenas
29eff23490 renaming test_curry to test_bind 2010-03-19 23:32:00 -04:00
Jeremy Ashkenas
4ebaa82563 removing the CoffeeScript.run named function from eval'd script scope by making it anonymous 2010-03-19 23:15:42 -04:00
Jeremy Ashkenas
69911209ea adding a pattern-matching-on-expression test 2010-03-19 22:48:55 -04:00
Jeremy Ashkenas
92688c89ef merging in matehat's nice refactor to splats (in arrays and otherwise) 2010-03-19 22:41:23 -04:00
matehat
fe04f8ce6b Added function call's flexibility with splats to array literals, factoring out splat compiling, and adjusted tests 2010-03-18 09:31:40 -04:00
Jeremy Ashkenas
b72641693d fixing doubled semis 2010-03-18 08:45:26 -04:00
Jeremy Ashkenas
0c6ee52cfc merging in matehat's curry branch. cleaning some loose ends up. adding some tests. 2010-03-18 00:42:26 -04:00
matehat
1f87094628 Slightly altered syntax, similar to Underscore's Function#bind form, highly simplified lexing and parsing and no polluted scope. Passing tests included. 2010-03-18 00:19:32 -04:00
matehat
3b22018296 Applied the new splat flexibility to function currying operator 2010-03-18 00:08:34 -04:00
matehat
5be437deb9 Added some inline docs 2010-03-18 00:08:34 -04:00
matehat
8d098194dd Added the '<-' currying operator, as heavily discussed in #251, along with tests. 2010-03-18 00:08:34 -04:00
matehat
256525bfa2 Fixed a small bug about flexible splats that occured when the leading array was a literal 2010-03-18 00:08:05 -04:00
Jeremy Ashkenas
79e4f30f69 fixing a bug where the Lexer assumed that values would always be strings. 2010-03-17 22:16:18 -04:00
Jeremy Ashkenas
884637468e fixing off-by-one error in compile_splat_arguments 2010-03-17 22:07:11 -04:00
Jeremy Ashkenas
6fd7810d89 can't use indexing[] into strings cross-browser, use substr() instead. 2010-03-17 21:41:00 -04:00
Jeremy Ashkenas
2f97d0d9b1 merging matehat's flexible splats (at any position within argument lists) 2010-03-17 21:15:54 -04:00
Jeremy Ashkenas
1bb9c57767 Merge branch 'splats' of git://github.com/matehat/coffee-script 2010-03-17 21:07:31 -04:00
Jeremy Ashkenas
d880b8b8f2 adding interpolation to heredocs, using the same rules as for strings 2010-03-17 20:47:27 -04:00
matehat
7129f518a4 Added the ability for function declaration to have a splat at an arbitrary position, not just at the end. Still restrict their number to 1. Adjusted tests accordingly. 2010-03-17 15:00:19 -04:00
matehat
fa6f1c2fb1 Fixed a tiny slicing bug 2010-03-17 15:00:19 -04:00
matehat
2bd1c3acca Added the ability to put as many splats in a function call as one wants. Also optimized the assembly into static arrays. Adjusted tests accordingly. 2010-03-17 15:00:19 -04:00
Jeremy Ashkenas
70cfc9500e pushing docs to the site 2010-03-16 23:18:54 -04:00
Jeremy Ashkenas
61b011cc28 fixing trailing whitespace on the final line 2010-03-16 19:57:39 -04:00
Jeremy Ashkenas
391135b1a5 fixing the relative path to 'grammar' 2010-03-16 19:36:08 -04:00
Jeremy Ashkenas
12d8d70573 fixing incorrectly-rooted relative paths in bin/cake and bin/coffee 2010-03-16 19:27:11 -04:00
Jeremy Ashkenas
04c5aeda2d Merge branch 'master' of git://github.com/matehat/coffee-script 2010-03-16 19:15:21 -04:00
Jeremy Ashkenas
25438be207 new docs for underscore 2010-03-16 19:13:13 -04:00
matehat
33f51d76f4 Added the possibility to end an identifier with '::', refering directly to its prototype. 2010-03-16 17:39:36 -04:00
Jeremy Ashkenas
e3021909c2 comments and tests 2010-03-16 06:54:49 -04:00
Jeremy Ashkenas
61dee1beba tweakin' 2010-03-15 23:10:14 -07:00
Jeremy Ashkenas
21e954eec3 updating module loading test 2010-03-15 23:08:58 -07:00
Jeremy Ashkenas
0b3054a348 merging in matehat's registerExtension patch for direct-requires of CoffeeScript. 2010-03-15 23:03:30 -07:00
Jeremy Ashkenas
02f4cb75dd removing deprecated references to process.mixin in favor of helpers.extend for Node 0.1.32 2010-03-15 22:53:25 -07:00
Jeremy Ashkenas
3aeb8c6bdb moving the contains-a-pure-statement-means-no-closure logic into ClosureNode.wrap itself. 2010-03-15 22:27:31 -07:00
Jeremy Ashkenas
8c2b2c7f80 merging in the fixed branch for gfxmonk/break_issue 2010-03-15 22:22:41 -07:00
Jeremy Ashkenas
745c635a55 fixing issue with break statements and for loops and closures and the value of 'this' 2010-03-15 22:20:29 -07:00
Jeremy Ashkenas
c7dd31846d merging in gfxmonk's fix for reporting line numbers for unclosed { [ ( opening symbols 2010-03-15 22:09:16 -07:00
gfxmonk
e87fa4293d report line number of opening token if a pair (eg bracket) is left open 2010-03-15 22:07:40 -07:00
gfxmonk
b269884f8d fixed non-recursive traverse() for CodeNode 2010-03-15 22:03:54 -07:00
Jeremy Ashkenas
3fed9761a6 let's make that non-greedy 2010-03-15 21:50:33 -07:00
Jeremy Ashkenas
6ccf196b61 adding another language extension test, with %w{} style ruby word array literals 2010-03-15 21:47:40 -07:00
Jeremy Ashkenas
a4bd8dc623 removing outdated arguments tests 2010-03-15 21:45:37 -07:00
Jeremy Ashkenas
34f01408c9 removing arguments-to-arrays from the docs 2010-03-15 20:53:43 -07:00
Jeremy Ashkenas
73074daa07 removing arguments-to-array-conversion from coffee 2010-03-15 20:46:14 -07:00
Jeremy Ashkenas
119b80d449 removing fiddling with require.paths from CoffeeScript 2010-03-15 20:39:46 -07:00
Jeremy Ashkenas
60b3103314 using granular helper imports, for nicer within. 2010-03-14 14:58:32 -07:00
Jeremy Ashkenas
75ffb9dc84 stop mixing in helpers (t(ticket #250) -- with a test 2010-03-14 14:48:43 -07:00
Jeremy Ashkenas
b306d40bf1 we don't need relative requires for the language 2010-03-14 13:48:58 -07:00
Jeremy Ashkenas
a27f146338 fixing 'cake test' to print out the name of the file with the failing test. 2010-03-14 09:33:41 -07:00
Jeremy Ashkenas
74995358cd updating the Cakefile for the new tmbundle location. 2010-03-14 08:59:55 -07:00
Jeremy Ashkenas
35da6c32b7 removing the tmbundle from the main repository. See jashkenas/coffee-script-tmbundle for the new one 2010-03-14 08:05:33 -07:00
Jeremy Ashkenas
701a5c7cb9 Merge branch 'master' of git://github.com/drnic/coffee-script 2010-03-14 07:39:02 -07:00
gfxmonk
3c3e7f666b added another "invalid break" example, with code not on the top-level 2010-03-14 13:02:36 +11:00
gfxmonk
89dfa1fd7a added code to illustrate an issue with break statements 2010-03-14 13:02:35 +11:00
gfxmonk
1da00f0ee3 added a test case for broken "break" statement 2010-03-14 11:35:56 +11:00
gfxmonk
5809a1637f fixed non-recursive traverse() for CodeNode 2010-03-14 00:05:51 +11:00
gfxmonk
e47bea34d5 report line number of opening token if a pair (eg bracket) is left open 2010-03-14 00:03:17 +11:00
matehat
709f17c278 Added an extension on node's 'require' module so it can import .coffee module and added some tests to make sure it works. 2010-03-12 14:22:01 -05:00
Jeremy Ashkenas
3c597dde72 no need to save the lookups 2010-03-10 22:32:00 -05:00
Jeremy Ashkenas
0379431812 tweaks 2010-03-10 21:53:33 -05:00
Jeremy Ashkenas
3f9fd85afb removing the unused CallNode#push 2010-03-10 20:53:31 -05:00
Jeremy Ashkenas
7b0a235c71 removing the nearly-unused notion of 'operation sensitive' 2010-03-10 20:19:32 -05:00
Jeremy Ashkenas
55cac23976 fixing indentation for prefix while nodes 2010-03-10 20:15:12 -05:00
Dr Nic Williams
22a16a3e33 added two snippets for creating functions; matching tab/key triggers from JavaScript bundle 2010-03-11 10:27:25 +10:00
Dr Nic Williams
db555d12ea can set Grammar via Shift+Ctrl+Alt+C 2010-03-11 10:16:34 +10:00
Jeremy Ashkenas
b9f1390405 adding more comment tests -- this terminator/comment as-block business really seems to have opened them up a bit 2010-03-10 16:44:50 -05:00
Jeremy Ashkenas
f2d0aee656 added Stan's fix for try/finally without catch 2010-03-10 16:27:30 -05:00
Jeremy Ashkenas
2a47727641 allowing terminator/comment as a block, so that you can have comment-only blocks 2010-03-10 16:18:17 -05:00
Jeremy Ashkenas
ccb7f63b8a fixing exports for the browser 2010-03-10 09:47:02 -05:00
Jeremy Ashkenas
1f9bb6a1c4 fixing broken multi-line optional-paren blocks 2010-03-10 09:28:00 -05:00
Jeremy Ashkenas
21b5d2cac5 tweaks to the helper docs, if they're going to be published 2010-03-10 00:05:30 -05:00
Jeremy Ashkenas
56eeeebed1 updating the docco 2010-03-09 23:53:21 -05:00
Jeremy Ashkenas
54627f6807 CoffeeScript language extensions are now working. 2010-03-09 23:44:29 -05:00
Jeremy Ashkenas
5754d36fdd adding the broken test 2010-03-09 23:32:54 -05:00
Jeremy Ashkenas
3d14d362a8 first draft of CoffeeScript language extensions. 2010-03-09 23:04:16 -05:00
Jeremy Ashkenas
472e027463 fixing the nested-implicit-parens-on-a-single-line 2010-03-09 21:54:44 -05:00
Jeremy Ashkenas
b297510d2b big refactor -- pulled all helper functions into helpers.coffee to facilitate sharing. 2010-03-09 21:24:30 -05:00
Jeremy Ashkenas
4932d25540 making balanced_string accept an array of delimiters, in hope of using it in the Rewriter 2010-03-09 20:53:56 -05:00
Jeremy Ashkenas
b6c3b743f0 Merge branch 'tm_highlighting' of git://github.com/cehoffman/coffee-script 2010-03-09 19:45:52 -05:00
Jeremy Ashkenas
1b4edd0e37 scrubbing all carriage returns from CoffeeScript source before compiling for the benefit of Windows users. 2010-03-08 23:07:26 -05:00
Jeremy Ashkenas
dcb00b4fe8 minor refactors to balanced_string 2010-03-08 22:48:14 -05:00
Jeremy Ashkenas
b33b688373 fixing more bugs in balance/interpolate/regexp/string/etc 2010-03-08 22:25:06 -05:00
Jeremy Ashkenas
4b97b15c0c more refactors to interpolation 2010-03-08 21:55:06 -05:00
Chris Hoffman
93c0774036 Regex interpolation highlighting 2010-03-08 20:48:23 -06:00
Chris Hoffman
645885d72d Merge branch 'master' of git://github.com/jashkenas/coffee-script 2010-03-08 20:34:36 -06:00
Jeremy Ashkenas
b5af5f66fb more regexp and string interpolation tweaks 2010-03-08 21:34:10 -05:00
Chris Hoffman
fb04f8900a Merge branch 'master' of git://github.com/jashkenas/coffee-script 2010-03-08 20:12:40 -06:00
Jeremy Ashkenas
3396dce2bb waypoint -- going to try to clean up regex_token 2010-03-08 20:57:28 -05:00
Jeremy Ashkenas
3291bd2a4a removing the 'supress' option from the lexer, just look at the slash. 2010-03-08 20:07:19 -05:00
Jeremy Ashkenas
121f01c06f merged stan's interpolation_3, a couple of tweaks 2010-03-08 19:43:12 -05:00
Jeremy Ashkenas
6cac2d57ba Merge commit 'StanAngeloff/interpolation_3' 2010-03-08 19:36:09 -05:00
Jeremy Ashkenas
c04b43e047 adding documentation for var shadowing 2010-03-08 19:27:38 -05:00
Jeremy Ashkenas
ff20732dd7 Merge branch 'tm_highlighting' of git://github.com/cehoffman/coffee-script 2010-03-08 19:14:34 -05:00
Stan Angeloff
81af8f296e Regular expression interpolations; fixed bug in string interpolations when all tokens were identifiers. 2010-03-08 20:06:51 +02:00
Stan Angeloff
830d1fb42b Merge branch 'master' of git://github.com/jashkenas/coffee-script into interpolation_3 2010-03-08 16:43:41 +02:00
Jeremy Ashkenas
e19cb48d3d Merge branch 'master' of git://github.com/uiru/coffee-script 2010-03-08 09:30:25 -05:00
Chris Hoffman
f755580b11 Match regex highlighting to how coffee parses it 2010-03-08 08:18:37 -06:00
Jeremy Ashkenas
81955005b9 doc tweaks 2010-03-08 09:13:15 -05:00
Will
62a871773b Include an extra line process.mixin require 'sys' on the top to let the .js output run using node (v0.1.31) 2010-03-09 01:03:43 +11:00
Chris Hoffman
5e52e7f19e While loop can be a single line expressions so don't indent when it is 2010-03-08 08:02:23 -06:00
Chris Hoffman
4c66a6a642 Merge branch 'master' of git://github.com/jashkenas/coffee-script 2010-03-08 07:33:45 -06:00
Chris Hoffman
9e1deecf13 Merge branch 'tm_highlighting' 2010-03-08 07:33:02 -06:00
Chris Hoffman
1ce93ccceb Indent function in symbol list based on indention in source 2010-03-08 07:30:15 -06:00
Chris Hoffman
4b04f8bec1 Add auto indent settings for textmate 2010-03-08 07:28:56 -06:00
Jeremy Ashkenas
5528bc7b2d scratch 'as seen above' 2010-03-08 06:44:47 -05:00
Jeremy Ashkenas
912f3b19f7 little tweaks to the docs 2010-03-08 06:40:54 -05:00
Chris Hoffman
9e5e85780b Don't highlight fresh[key]: val situations 2010-03-08 05:37:51 -06:00
Chris Hoffman
10aa3b3ae3 Revert "Properly highlight fresh[key]: val situations" 2010-03-08 05:37:07 -06:00
Jeremy Ashkenas
bcf7b3f95b CoffeeScript 0.5.5, with string interpolation and internal documentation 2010-03-08 06:34:07 -05:00
Chris Hoffman
07f1c784a4 Properly highlight fresh[key]: val situations 2010-03-08 05:29:01 -06:00
Chris Hoffman
465994cff9 Clean up some misplaced files 2010-03-08 05:26:38 -06:00
Chris Hoffman
697ad6cbda Merge remote branch 'origin' 2010-03-08 05:15:17 -06:00
Jeremy Ashkenas
a840671015 Finishing off the docs for nodes.coffee -- almost ready to roll. 2010-03-08 05:13:05 -06:00
Jeremy Ashkenas
7f0ab8308d making ThrowNode not a pure_statement -- it can jump out of the closure just fine 2010-03-08 05:13:05 -06:00
Jeremy Ashkenas
270b9fde04 waypoint -- documented down to the ThrowNode 2010-03-08 05:13:04 -06:00
Jeremy Ashkenas
993c9899cb Fixing up command-line args for --stdio and --eval. Now makes more sense with --run by default. 2010-03-08 05:13:04 -06:00
Jeremy Ashkenas
c8246e95f1 broke the flag for --no-wrap, fixed. 2010-03-08 05:13:04 -06:00
Stan Angeloff
f08de1ed4c Empty expression interpolations evaluate as empty strings now. 2010-03-08 05:13:04 -06:00
Jeremy Ashkenas
90f2e0dbb9 Merge branch 'tm_highlighting' of git://github.com/cehoffman/coffee-script 2010-03-08 06:11:15 -05:00
Chris Hoffman
80a3bd8951 Add variable assignment highlighting for textmate 2010-03-08 05:10:08 -06:00
Jeremy Ashkenas
b0aec3cbe2 Finishing off the docs for nodes.coffee -- almost ready to roll. 2010-03-08 05:42:57 -05:00
Jeremy Ashkenas
5f5e0634dd making ThrowNode not a pure_statement -- it can jump out of the closure just fine 2010-03-08 05:19:48 -05:00
Jeremy Ashkenas
049e605016 changing from storage.type... to variable.assignment -- it was a little garish in most color schemes I tried. 2010-03-08 05:16:45 -05:00
Jeremy Ashkenas
4687c3e140 Merge branch 'tm_highlighting' of git://github.com/cehoffman/coffee-script 2010-03-08 04:59:10 -05:00
Jeremy Ashkenas
6d74e223be waypoint -- documented down to the ThrowNode 2010-03-08 04:58:39 -05:00
Chris Hoffman
221427a6b4 Make variable assignment highlighting work in more cases 2010-03-08 03:55:03 -06:00
Chris Hoffman
3bf892128d Make old style classes show up as a function and don't let $\d be highlighted as a number 2010-03-08 03:47:49 -06:00
Chris Hoffman
abd7f939f2 Don't show object creation instances in symbol list for textmate 2010-03-08 03:46:38 -06:00
Jeremy Ashkenas
299e9918b9 Fixing up command-line args for --stdio and --eval. Now makes more sense with --run by default. 2010-03-08 04:46:24 -05:00
Chris Hoffman
eea83ff613 Add comment starter preference for textmate 2010-03-08 03:46:05 -06:00
Jeremy Ashkenas
9eceab667c broke the flag for --no-wrap, fixed. 2010-03-08 04:28:26 -05:00
Stan Angeloff
026e7649d5 Empty expression interpolations evaluate as empty strings now. 2010-03-08 04:13:59 -05:00
Chris Hoffman
c807da7664 Identify functions for symbol lookup and correct lookbehind assertion 2010-03-08 02:39:38 -06:00
Chris Hoffman
dde5db621d Add some TextMate triggers for string interpolation 2010-03-08 02:06:57 -06:00
Chris Hoffman
6b95cb4ee0 Fix the naked .property highlighting in interpolation to match coffee parsing 2010-03-08 01:40:04 -06:00
Stan Angeloff
a5f69ef716 Empty expression interpolations evaluate as empty strings now. 2010-03-08 09:31:31 +02:00
Chris Hoffman
accccb5f39 Allow $ to be the first character in a variable name for highlighting in textmate 2010-03-08 01:20:43 -06:00
Chris Hoffman
f8ddccd7d0 Escape $ in regexes where it was meant as character and not end of line 2010-03-08 01:05:52 -06:00
Chris Hoffman
e06e882962 Update highlighting for class definitions in textmate 2010-03-08 00:59:21 -06:00
Chris Hoffman
c3f74ca4f1 Add string interpolation highlighting and Cakefile highlighting 2010-03-08 00:43:04 -06:00
Jeremy Ashkenas
532464f7ae waypoint -- docs halfway down through the OpNode 2010-03-07 22:47:34 -05:00
Jeremy Ashkenas
570fb013e2 test tweaks 2010-03-07 22:29:46 -05:00
Jeremy Ashkenas
71ace9d8d0 allowing naked interpolation of dotted properties. .property 2010-03-07 22:26:25 -05:00
Jeremy Ashkenas
1cf0326183 unifying the CoffeeScript.compile and CoffeeScript.run apis to be the same -- source code and options hash. 2010-03-07 22:17:45 -05:00
Jeremy Ashkenas
5b9ebd19d5 adding source file information to all coffeescript compiles 2010-03-07 22:08:24 -05:00
Jeremy Ashkenas
6ce869b3fb adding a note about the 'git co lib' - build twice shuffle to the docs -- there's been more than one question about it already. 2010-03-07 21:57:08 -05:00
Jeremy Ashkenas
06b50ecb98 unifying all of the server-side evaluation under CoffeeScript.run -- this means that __filename and __dirname and relative requires should work from all angles under Node.js 2010-03-07 21:49:08 -05:00
Jeremy Ashkenas
0bc7719572 merging in Zaach's Jison updates 2010-03-07 19:11:03 -05:00
Jeremy Ashkenas
9028f79a27 Merge branch 'master' of git://github.com/zaach/coffee-script 2010-03-07 19:09:20 -05:00
Jeremy Ashkenas
a3e1693a75 waypoint -- docc'd down to the SplatNode 2010-03-07 19:07:37 -05:00
Zachary Carter
060b3e23c1 Merge branch 'master' of git://github.com/jashkenas/coffee-script 2010-03-07 18:59:54 -05:00
Zachary Carter
612c238157 Rebuild parser, now with skinnier parse table. 2010-03-07 18:53:23 -05:00
Zachary Carter
8adbc75811 Update Jison for table optimizations. 2010-03-07 18:48:15 -05:00
Jeremy Ashkenas
7485e5482c mention rlwrap in the docs on --interactive 2010-03-07 18:19:41 -05:00
Jeremy Ashkenas
659a5436a5 adding coffee-mode and rack-coffee to the Resources section of the docs 2010-03-07 17:52:14 -05:00
Jeremy Ashkenas
c6d7a27848 waypoint on the documentation -- almost halfway through the nodes 2010-03-07 17:31:39 -05:00
Jeremy Ashkenas
094b198d5d first little bit of commenting the nodes.coffee -- with some slight refactors 2010-03-07 16:41:06 -05:00
Jeremy Ashkenas
22b97a3b54 documenting scope.coffee -- nodes.coffee is the next, and last up to bat. 2010-03-07 15:45:45 -05:00
Jeremy Ashkenas
a4f7a5e248 documenting and cleaning up the Rewriter 2010-03-07 14:41:52 -05:00
Jeremy Ashkenas
45d8cf163e updating to the latest docco 2010-03-07 13:49:34 -05:00
Jeremy Ashkenas
d46daa1d7c documenting optparse.coffee and repl.coffee 2010-03-07 13:41:15 -05:00
Jeremy Ashkenas
4906cf1aff cleaned and commented the lexer (again) interpolate_string() continues to shrink 2010-03-07 12:47:03 -05:00
Stan Angeloff
f74fae58e3 Rewritting lexer.coffee to accept nested string interpolations. 2010-03-07 11:42:52 -05:00
Jeremy Ashkenas
1602e0e823 adding complete documentation for the grammar 2010-03-07 11:41:56 -05:00
Jeremy Ashkenas
202ebf06ff documentation for command.coffee 2010-03-07 00:28:58 -05:00
Jeremy Ashkenas
3e3b71724d making equality left-associative so that our chaining works properly with it. 2010-03-06 23:48:06 -05:00
Jeremy Ashkenas
893fb98522 moving command_line.coffee -> command.coffee 2010-03-06 22:18:15 -05:00
Jeremy Ashkenas
e267226438 commenting coffee-script.coffee for documentation 2010-03-06 20:30:40 -05:00
Jeremy Ashkenas
62626b712b Commenting cake.coffee for Docco docs. 2010-03-06 20:18:50 -05:00
Jeremy Ashkenas
7bdf14b210 Override process.argv as well as process.ARGV for eval'd scripts 2010-03-06 20:09:08 -05:00
Jeremy Ashkenas
87420e6504 updating the Function Binding docs with an improved explanation. 2010-03-06 19:29:41 -05:00
Jeremy Ashkenas
c73a3ec356 updating webserver example for node API 2010-03-06 19:23:25 -05:00
Jeremy Ashkenas
2e23e6a2dc removing narwhal.coffee and narwhal.js, because I don't think that anyone was using them. 2010-03-06 19:05:21 -05:00
Jeremy Ashkenas
5b3ef78101 adding a doc:source Cake task to document CoffeeScript's internals 2010-03-06 19:02:31 -05:00
Jeremy Ashkenas
9b262d56a5 allowing relative requires of JavaScript from directly-eval'd CoffeeScript. 2010-03-06 17:40:13 -05:00
Jeremy Ashkenas
453b43992d fixing line numbers in errors printed prior to parsing 2010-03-06 16:42:40 -05:00
Jeremy Ashkenas
a5e3617015 Adding a starts() helper to avoid substring() calls for simple matches. 2010-03-06 16:24:06 -05:00
Jeremy Ashkenas
c4ad6d1ee6 minor cleanups to balanced_group -> balanced_token, removing optional escaper (unused), and using it to implement interpolated javascript. 2010-03-06 16:06:47 -05:00
Stan Angeloff
f9cde1b46d Improving performance by removing call to bound function for every character in a string. Added a third option to \delimited\ to allow custom escape sequences. 2010-03-06 15:53:37 -05:00
Jeremy Ashkenas
03bc897b39 updating CoffeeScript docs to require Node 0.1.31 + 2010-03-06 15:48:20 -05:00
Stan Angeloff
83fd84745d Rewriting string tokenizer; allowing nested double-quoted strings inside expression interpolations. 2010-03-06 15:21:30 -05:00
Jeremy Ashkenas
e977967eb5 implementing the CoffeeScript compiler using interpolation where appropriate. 2010-03-06 13:59:11 -05:00
Jeremy Ashkenas
15b00cb3ca implementing string interpolation using string interpolation 2010-03-06 13:32:43 -05:00
Jeremy Ashkenas
18e5f72a84 done converting nodes.coffee code generation to use string interpolation where appropriate 2010-03-06 00:23:54 -05:00
Jeremy Ashkenas
47682de0f0 adding a test for intermingled identifier/expression interpolations 2010-03-05 22:54:39 -05:00
Jeremy Ashkenas
b4ea43cbd0 waypoint -- starting to implement nodes.coffee with interpolations, and fixing/shortening/combining the lexer implementation to allow identifier interpolations to be interleaved with expression interps 2010-03-05 22:52:28 -05:00
Jeremy Ashkenas
08341286a3 adding back parentheses wrapper around interpolated expressions -- we need it 2010-03-05 21:12:13 -05:00
Jeremy Ashkenas
4c3b0b9a74 allowing @properties to be referenced in naked interpolations 2010-03-05 21:05:31 -05:00
Jeremy Ashkenas
d250e9e9cc some edits to the interpolation path 2010-03-05 20:42:36 -05:00
Stan Angeloff
75be5eed62 Test line commented by mistake, no functional changes 2010-03-05 19:50:28 -05:00
Stan Angeloff
e2f86678a4 Allowing expressions to be used inside strings; syntax is $\{...\} 2010-03-05 19:50:20 -05:00
Stan Angeloff
fe7d5dfd19 Added string interpolation for identifiers 2010-03-05 19:49:48 -05:00
Jeremy Ashkenas
965034e16e add proper spacing to optparse by default 2010-03-04 22:59:03 -05:00
Jeremy Ashkenas
44398d044f Updating docs for CoffeeScript 0.5.4. Tag it and bag it. 2010-03-03 23:01:53 -05:00
Jeremy Ashkenas
3feb874b1e Merge branch 'path_fix' of git://github.com/cehoffman/coffee-script 2010-03-03 20:17:58 -05:00
Chris Hoffman
f7183e6918 Use new node api for resolving a chain of symlinks 2010-03-03 16:34:17 -06:00
Samuel Reis
707cd2d734 updated command_line.js 2010-03-03 14:32:28 +01:00
Samuel Reis
c11c3ed2f2 fix: process.watchFile has moved to fs.watchFile 2010-03-03 14:31:30 +01:00
Jeremy Ashkenas
5fd0972b5d improvement to comment handling that should ensure that they have no effect on indentation 2010-03-02 19:23:21 -05:00
Jeremy Ashkenas
70cb195e6f rebuilding extras/coffee-script.js 2010-03-02 16:52:55 -05:00
Jeremy Ashkenas
c219adffd5 removing special rule from rewriter for naked functions in arrays 2010-03-02 00:43:01 -05:00
Jeremy Ashkenas
cd6dd5abfd couple more tweaks to lexer.coffee 2010-02-28 21:39:07 -05:00
Jeremy Ashkenas
29ece0e6ba better commenting the coffeescript lexer as the first trial for docco 2010-02-28 20:44:33 -05:00
Jeremy Ashkenas
45bad556ab defining __filename and __dirname correctly as local variables for eval'd scripts 2010-02-28 19:56:00 -05:00
Jeremy Ashkenas
30cf63ec92 updating Underscore.coffee to Underscore.js version 0.6.0 2010-02-28 15:12:18 -05:00
Jeremy Ashkenas
969c2e528d a number of refactors to the Lexer. It should be a good bit clearer to read now. 2010-02-28 13:34:52 -05:00
Jeremy Ashkenas
bb2bf7ce57 allowing chaining of property accesses by indentation level (really nice for Node and jQuery work) ticket #221 2010-02-28 12:49:37 -05:00
Jeremy Ashkenas
2969e156c7 fixing require paths in the Cakefile so that build:jison will work, even if you don't have it installed. 2010-02-28 10:37:12 -05:00
Jeremy Ashkenas
b08995cbcc fixing heredocs with multiple double quotes (broken regex from the Ruby translation), with tests. 2010-02-28 10:29:30 -05:00
Jeremy Ashkenas
47f71f9193 updating docs to say 'Node.js greater than 0.1.30' 2010-02-28 10:11:01 -05:00
Jeremy Ashkenas
fec2eaef7e removing the (now-unused) inherits helper, and adding a helper for creating LiteralNodes 2010-02-28 00:22:06 -05:00
Jeremy Ashkenas
56eb474bf3 If you don't specify a constructor, one will be provided for you by the state. 2010-02-28 00:13:17 -05:00
Jeremy Ashkenas
62b2ab29cd CoffeeScript 0.5.3, with classes 2010-02-27 20:21:46 -05:00
Jeremy Ashkenas
a35693554c updating documentation for classes 2010-02-27 20:12:47 -05:00
Jeremy Ashkenas
f7427259ee reserving __extends and __hasProp 2010-02-27 20:03:57 -05:00
Jeremy Ashkenas
e02ab76edf converting the remainder of the CoffeeScript compiler (Rewriter, Scope, Optparse) to use classes 2010-02-27 19:46:45 -05:00
Jeremy Ashkenas
9f46c306e5 super is now possible in nodes/Expressions, where it wasn't possible before. 2010-02-27 19:42:10 -05:00
Jeremy Ashkenas
b5c9d779bd updating the Lexer to use classes and some of the older documentation 2010-02-27 19:40:53 -05:00
Jeremy Ashkenas
d2cb1f321e making sure that the body of extends only gets defined once per file. 2010-02-27 19:29:34 -05:00
Jeremy Ashkenas
8f871a8218 converting the nodes.coffee AST to use the new class system 2010-02-27 19:19:53 -05:00
Jeremy Ashkenas
4ec7514d10 making inner comments work within class definitions 2010-02-27 19:03:23 -05:00
Jeremy Ashkenas
1c7e4c4203 first draft of adding classes to CoffeeScript 2010-02-27 18:57:45 -05:00
Jeremy Ashkenas
7d39fe1c56 fixing multiple evaluation of splat sources, when it's an invoked function 2010-02-27 15:15:26 -05:00
Jeremy Ashkenas
afa26c37f1 fixing regexp literals versus division, with tests 2010-02-27 14:30:14 -05:00
Jeremy Ashkenas
2f658ba925 fixing multiple single-line function forms on the same line 2010-02-27 11:03:43 -05:00
Jeremy Ashkenas
0ab810e4cb fancy new fullscreen version of 'Try CoffeeScript' 2010-02-27 02:21:26 -05:00
Jeremy Ashkenas
37d086b670 rebuilding the browser code in anticipation of a page push 2010-02-27 01:38:50 -05:00
Jeremy Ashkenas
5e7f5f390a adding a traverse method to the AST, so we can do fancy processing from external scripts. 2010-02-27 01:22:21 -05:00
Jeremy Ashkenas
f4cd0bdf29 making --run the default option for consistency. If you want to save the file, use -c or --compile. 2010-02-27 00:38:04 -05:00
Jeremy Ashkenas
723ea53585 adding the long-ago-needed documentation for constructors with 'return this' 2010-02-26 20:09:49 -05:00
Jeremy Ashkenas
93f644fae2 finishing the second half of prefix installs. Using readLink to refer to the CoffeeScript installation reliably. 2010-02-26 19:49:12 -05:00
Jeremy Ashkenas
82951a469b adding favicon to docs 2010-02-26 19:10:56 -05:00
Jeremy Ashkenas
d2d5f649d3 caching the length property lookup for vanilla array comprehensions and rebuilding docs 2010-02-25 23:39:14 -05:00
Jeremy Ashkenas
5c7526a741 moving some of the fs methods over to sync methods, where it's alright and where it makes things clearer 2010-02-25 21:53:42 -05:00
Jeremy Ashkenas
17ea48c543 first draft of options for Cakefiles, using optparse.coffee, as well as a cake install task that takes --prefix. Still need to fix the lib/bin scripts 2010-02-25 21:43:42 -05:00
Jeremy Ashkenas
55ed202957 no outline on the Try CoffeeScript input for safari 2010-02-25 21:10:32 -05:00
Jeremy Ashkenas
d5df5505f9 hide the error div on initial page load 2010-02-25 20:48:54 -05:00
Jeremy Ashkenas
dc7f4b4be0 new live 'Try CoffeeScript' 2010-02-25 20:39:34 -05:00
Jeremy Ashkenas
406a18067d allowing merged short flags in optparse.coffee, via normalize_arguments 2010-02-25 19:06:08 -05:00
Jeremy Ashkenas
3ae2ebe5ea Merge branch 'fix_example_webserver' of git://github.com/hugs/coffee-script 2010-02-25 18:56:11 -05:00
Jeremy Ashkenas
a23dc6b753 raising an error on unrecognized options 2010-02-25 18:54:08 -05:00
Jeremy Ashkenas
5f1d3fd775 updating docs with the new flags 2010-02-25 18:43:33 -05:00
Jeremy Ashkenas
9d4e06e8a8 moving -tr --tree to -n --nodes, and --no-wrap gives up its -n short flag. 2010-02-25 18:42:35 -05:00
Jason Huggins
6bc61ec1a1 Fixed web_server example to be compatible with Node v0.1.30 2010-02-25 17:42:05 -06:00
Jeremy Ashkenas
c62f93f930 improving errors for undefined options, and error messages for compile attempts on nonexistent files 2010-02-25 18:36:43 -05:00
Jeremy Ashkenas
213ae1430e using text instead of html to escape entities in the rendered JS for Try CoffeeScript 2010-02-25 18:20:15 -05:00
Jeremy Ashkenas
ee5d738827 doc update 2010-02-25 17:18:28 -05:00
Jeremy Ashkenas
eab9bbf04f adding a test for nested pattern matching 2010-02-25 07:31:33 -05:00
Jeremy Ashkenas
4ed51536bb fixing patternmatched assigns within assigns within calls 2010-02-25 07:28:48 -05:00
Jeremy Ashkenas
b32a60585b improving CoffeeScript in browser script activation, and updating docs 2010-02-25 06:26:27 -05:00
Jeremy Ashkenas
66a6568fe7 cleaning and shrinking the option parser 2010-02-25 06:15:58 -05:00
Jeremy Ashkenas
fe32146adc cleaning and commenting cake.coffee 2010-02-25 01:17:43 -05:00
Jeremy Ashkenas
69feac3a01 adding return values for destructuring assignment. 2010-02-25 00:43:02 -05:00
Jeremy Ashkenas
05d95acfc3 docs for CoffeeScript 0.5.2, which is now out. 2010-02-25 00:26:59 -05:00
Jeremy Ashkenas
22674bc536 removing CoffeeScript.activate() simply including the tag will do for text/coffeescript 2010-02-24 23:57:39 -05:00
Jeremy Ashkenas
23c5ebb00f call it 'CoffeeScript' in the command_line, so that --run scripts may access it as such 2010-02-24 22:30:22 -05:00
Jeremy Ashkenas
c14869f008 implementing the inline javascript in the documentation page in text/coffeescript, switching from the closure compiler to the yui compressor for building the browser version -- the closure compiler had a bug for our input -- fixable by hand but not worth the tiny savings 2010-02-24 20:41:56 -05:00
Jeremy Ashkenas
c1427d6558 adding a minified combined coffee-script.js. Include it on the page, after any text/coffeescript tags, and call CoffeeScript.activate(); to run it 2010-02-24 19:57:29 -05:00
Jeremy Ashkenas
2a46e13d33 moving print_tokens (the pretty printer) from coffee_script to command_line 2010-02-24 18:56:32 -05:00
Jeremy Ashkenas
b26e577244 adding documentation for --stdio 2010-02-24 18:27:10 -05:00
Jeremy Ashkenas
9f8710b631 adding compilation over stdin/stdout. Use --stdio or -s, and pipe away. 2010-02-24 18:18:29 -05:00
Jeremy Ashkenas
aba8cb1b08 upgrading the optparse library to avoid having to register callbacks for each argument. It just returns a simple options hash. 2010-02-24 17:57:58 -05:00
Jeremy Ashkenas
92cd80226c bumping to 0.5.1 2010-02-24 00:54:07 -05:00
Jeremy Ashkenas
10d335ccb1 adding existence soaks for indexed-lookup property accesses: obj?['property'] 2010-02-24 00:06:01 -05:00
Jeremy Ashkenas
4eeb8c4bd2 adding conditional while loops with while ... when 2010-02-23 22:53:43 -05:00
Jeremy Ashkenas
4d146bacb1 fixing throwing an error string in the Rewriter, when it should have been an Error object 2010-02-23 21:59:29 -05:00
Jeremy Ashkenas
7de4caffca removing a shift-reduce error from the grammar that worked its way in 2010-02-23 21:22:28 -05:00
Jeremy Ashkenas
8db0cb9fa5 rebuilding with new for spacing 2010-02-23 21:12:44 -05:00
Jeremy Ashkenas
c30b3d3c48 updating to the latest Jison 2010-02-23 21:03:05 -05:00
Jeremy Ashkenas
52db4fbf8c merging Tim-Smart's branch 2010-02-23 20:52:03 -05:00
Jeremy Ashkenas
5cd8f2c52c Merge branch 'master' of git://github.com/Tim-Smart/coffee-script 2010-02-23 20:51:29 -05:00
Jeremy Ashkenas
5a1aa44393 going back to == undefined instead of == null to appease the angry JSLint. 2010-02-22 22:19:17 -05:00
Tim
432696d6eb nodes.coffee: ForNode: Small whitespace change in for_part 2010-02-22 20:19:00 -07:00
Jeremy Ashkenas
3df7bd98f4 fixing issue 196, better handling of soak/existence chains 2010-02-22 22:11:47 -05:00
Jeremy Ashkenas
1f870911c9 Merge branch 'master' of git://github.com/cehoffman/coffee-script 2010-02-22 20:28:41 -05:00
Jeremy Ashkenas
4bb9392753 adding warning about Node.js/Windows to the docs. 2010-02-22 20:25:15 -05:00
Chris Hoffman
fdffacfb40 Make trailing else on switch fix pass on to multiple when switches 2010-02-22 19:17:54 -06:00
Jeremy Ashkenas
a64afe6162 fixing the trailing-else-in-switch-getting-sucked-in-bug, Issue 195. 2010-02-22 19:22:09 -05:00
Jeremy Ashkenas
15b86a5f7a doc updates 2010-02-22 17:14:51 -05:00
Jeremy Ashkenas
9b78fb67cf allowing checked out versions of the source to use bin/cake and bin/coffee from any directory. 2010-02-22 09:12:52 -05:00
Jeremy Ashkenas
4817b96bac fixing the build:ultraviolet task in the Cakefile 2010-02-22 09:09:35 -05:00
Jeremy Ashkenas
6985802eb3 making the docs a little less jumpy with more stable menus 2010-02-21 23:29:31 -05:00
Jeremy Ashkenas
aad0ce162d ensuring that we don't write --eval scriptlets out to disk -- they should print, if nothing else 2010-02-21 22:41:19 -05:00
246 changed files with 13624 additions and 15006 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
raw
presentation
test.coffee
parser.output

126
Cakefile
View File

@@ -1,57 +1,119 @@
fs: require 'fs'
coffee: require 'coffee-script'
fs: require 'fs'
{helpers}: require('./lib/helpers')
CoffeeScript: require './lib/coffee-script'
{spawn, exec}: require('child_process')
# ANSI Terminal Colors.
red: '\033[0;31m'
green: '\033[0;32m'
reset: '\033[0m'
# Run a CoffeeScript through our node/coffee interpreter.
run: (args) ->
proc: process.createChildProcess 'bin/coffee', args
proc.addListener 'error', (err) -> if err then puts err
proc: spawn 'bin/coffee', args
proc.stderr.addListener 'data', (buffer) -> puts buffer.toString()
proc.addListener 'exit', (status) -> process.exit(1) if status != 0
# Log a message with a color.
log: (message, color, explanation) ->
puts "$color$message$reset ${explanation or ''}"
task 'install', 'install CoffeeScript into /usr/local', ->
option '-p', '--prefix [DIR]', 'set the installation prefix for `cake install`'
task 'install', 'install CoffeeScript into /usr/local (or --prefix)', (options) ->
base: options.prefix or '/usr/local'
lib: "$base/lib/coffee-script"
bin: "$base/bin"
node: "~/.node_libraries/coffee-script"
puts "Installing CoffeeScript to $lib"
puts "Linking to $node"
puts "Linking 'coffee' to $bin/coffee"
exec([
'mkdir -p /usr/local/lib/coffee-script'
'cp -rf bin lib LICENSE README package.json src vendor /usr/local/lib/coffee-script'
'ln -sf /usr/local/lib/coffee-script/lib/bin/coffee /usr/local/bin/coffee'
'ln -sf /usr/local/lib/coffee-script/lib/bin/cake /usr/local/bin/cake'
].join(' && '))
"mkdir -p $lib $bin"
"cp -rf bin lib LICENSE README package.json src $lib"
"ln -sf $lib/bin/coffee $bin/coffee"
"ln -sf $lib/bin/cake $bin/cake"
"mkdir -p ~/.node_libraries"
"ln -sf $lib/lib $node"
].join(' && '), (err, stdout, stderr) ->
if err then print stderr else log 'done', green
)
task 'build', 'build the CoffeeScript language from source', ->
fs.readdir 'src', (err, files) ->
files: 'src/' + file for file in files when file.match(/\.coffee$/)
run ['-o', 'lib'].concat(files)
files: fs.readdirSync 'src'
files: 'src/' + file for file in files when file.match(/\.coffee$/)
run ['-c', '-o', 'lib'].concat(files)
task 'build:full', 'rebuild the source twice, and run the tests', ->
exec 'bin/cake build && bin/cake build && bin/cake test', (err, stdout, stderr) ->
print stdout if stdout
print stderr if stderr
throw err if err
task 'build:parser', 'rebuild the Jison parser (run build first)', ->
parser: require('grammar').parser
require 'jison'
parser: require('./lib/grammar').parser
js: parser.generate()
parser_path: 'lib/parser.js'
fs.writeFile parser_path, js
parserPath: 'lib/parser.js'
fs.writeFile parserPath, js
task 'build:ultraviolet', 'build and install the Ultraviolet syntax highlighter', ->
exec('plist2syntax extras/CoffeeScript.tmbundle/Syntaxes/CoffeeScript.tmLanguage').addCallback ->
exec 'plist2syntax ../coffee-script-tmbundle/Syntaxes/CoffeeScript.tmLanguage', (err) ->
throw err if err
exec 'sudo mv coffeescript.yaml /usr/local/lib/ruby/gems/1.8/gems/ultraviolet-0.10.2/syntax/coffeescript.syntax'
task 'build:underscore', 'rebuild the Underscore.coffee documentation page', ->
exec 'uv -s coffeescript -t idle -h examples/underscore.coffee > documentation/underscore.html'
task 'build:browser', 'rebuild the merged script for inclusion in the browser', ->
exec 'rake browser', (err) ->
throw err if err
task 'doc:site', 'watch and continually rebuild the documentation for the website', ->
exec 'rake doc'
task 'doc:source', 'rebuild the internal documentation', ->
exec 'docco src/*.coffee && cp -rf docs documentation && rm -r docs', (err) ->
throw err if err
task 'doc:underscore', 'rebuild the Underscore.coffee documentation page', ->
exec 'docco examples/underscore.coffee && cp -rf docs documentation && rm -r docs', (err) ->
throw err if err
task 'loc', 'count the lines of source code in CoffeeScript', ->
exec "cat src/*.coffee | grep -v '^\\( *#\\|\\s*$\\)' | wc -l | tr -s ' '", (err, stdout) ->
print stdout
task 'test', 'run the CoffeeScript language test suite', ->
process.mixin require 'assert'
test_count: 0
start_time: new Date()
[original_ok, original_throws]: [ok, throws]
process.mixin {
ok: (args...) -> test_count += 1; original_ok(args...)
throws: (args...) -> test_count += 1; original_throws(args...)
helpers.extend global, require 'assert'
passedTests: failedTests: 0
startTime: new Date
originalOk: ok
helpers.extend global, {
ok: (args...) -> passedTests += 1; originalOk(args...)
CoffeeScript: CoffeeScript
}
process.addListener 'exit', ->
time: ((new Date() - start_time) / 1000).toFixed(2)
puts '\033[0;32mpassed ' + test_count + ' tests in ' + time + ' seconds\033[0m'
time: ((new Date - startTime) / 1000).toFixed(2)
message: "passed $passedTests tests in $time seconds$reset"
if failedTests
log "failed $failedTests and $message", red
else
log message, green
fs.readdir 'test', (err, files) ->
for file in files
fs.readFile 'test/' + file, (err, source) ->
js: coffee.compile source
process.compile js, file
files.forEach (file) ->
return unless file.match(/\.coffee$/i)
source: path.join 'test', file
fs.readFile source, (err, code) ->
try
CoffeeScript.run code.toString(), {source: source}
catch err
failedTests += 1
log "failed $source", red, '\n' + err.stack.toString()

28
README
View File

@@ -25,6 +25,9 @@
Install Node.js, and then the CoffeeScript compiler:
sudo bin/cake install
Or, if you have the Node Package Manager installed:
sudo npm install coffee-script
Compile a script:
coffee /path/to/script.coffee
@@ -34,8 +37,29 @@
To suggest a feature, report a bug, or general discussion:
http://github.com/jashkenas/coffee-script/issues/
If you'd like to chat, drop by #coffeescript on Freenode.
If you'd like to chat, drop by #coffeescript on Freenode IRC,
or on webchat.freenode.net.
The source repository:
git://github.com/jashkenas/coffee-script.git
Contributors:
Stan Angeloff (StanAngeloff)
Jeremy Ashkenas (jashkenas)
Zach Carter (zaach)
Tim Cuthbertson (gfxmonk)
Mathieu D'Amours (matehat)
Chris Hoffman (cehoffman)
Jason Huggins (hugs)
Timothy Jones (Tesco)
Chris Lloyd (chrislloyd)
Matt Lyon (mattly)
Jeff Olson (olsonjeffery)
Nathan Ostgard (noonat)
Samuel Reis (grgh)
Tom Robinson (tlrobinson)
Tim Smart (Tim-Smart)
Dr. Nic Williams (drnic)

View File

@@ -1,11 +1,23 @@
require 'erb'
require 'fileutils'
require 'rake/testtask'
require 'rubygems'
require 'yui/compressor'
HEADER = <<-EOS
/**
* CoffeeScript Compiler v0.7.1
* http://coffeescript.org
*
* Copyright 2010, Jeremy Ashkenas
* Released under the MIT License
*/
EOS
desc "Build the documentation page"
task :doc do
source = 'documentation/index.html.erb'
child = fork { exec "bin/coffee documentation/coffee/*.coffee -o documentation/js -w" }
child = fork { exec "bin/coffee -c documentation/coffee/*.coffee -o documentation/js -w" }
at_exit { Process.kill("INT", child) }
Signal.trap("INT") { exit }
loop do
@@ -18,3 +30,12 @@ task :doc do
sleep 1
end
end
desc "Build the single concatenated and minified script for the browser"
task :browser do
sources = %w(helpers.js rewriter.js lexer.js parser.js scope.js nodes.js coffee-script.js)
code = sources.map {|s| File.read('lib/' + s) }.join('')
code = YUI::JavaScriptCompressor.new.compress(code)
File.open('extras/coffee-script.js', 'w+') {|f| f.write(HEADER + code) }
end

View File

@@ -1,7 +1,8 @@
#!/usr/bin/env node
process.mixin(require('sys'));
var path = require('path');
var fs = require('fs');
var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib');
require.paths.unshift('./lib');
require('cake').run();
require(lib + '/helpers').helpers.extend(global, require('sys'));
require(lib + '/cake').run();

View File

@@ -1,7 +1,8 @@
#!/usr/bin/env node
process.mixin(require('sys'));
var path = require('path');
var fs = require('fs');
var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib');
require.paths.unshift('./lib');
require('command_line').run();
require(lib + '/helpers').helpers.extend(global, require('sys'));
require(lib + '/command').run();

View File

@@ -1,9 +1,11 @@
launch() if ignition is on
volume: 10 if band isnt spinal_tap
volume: 10 if band isnt SpinalTap
let_the_wild_rumpus_begin() unless answer is no
letTheWildRumpusBegin() unless answer is no
if car.speed < speed_limit then accelerate()
if car.speed < limit then accelerate()
winner: yes if pick in [47, 92, 13]
print "My name is " + @name

View File

@@ -1,4 +0,0 @@
backwards: ->
alert arguments.reverse()
backwards "stairway", "to", "heaven"

View File

@@ -1,5 +1,5 @@
# Eat lunch.
lunch: eat(food) for food in ['toast', 'cheese', 'wine']
lunch: eat food for food in ['toast', 'cheese', 'wine']
# Naive collision detection.
for roid in asteroids

View File

@@ -1,5 +1,3 @@
process.mixin require 'assert'
task 'test', 'run each of the unit tests', ->
for test in test_files
for test in files
fs.readFile test, (err, code) -> eval coffee.compile code

View File

@@ -0,0 +1,29 @@
class Animal
move: (meters) ->
alert @name + " moved " + meters + "m."
class Snake extends Animal
constructor: (name) ->
@name: name
move: ->
alert "Slithering..."
super 5
class Horse extends Animal
constructor: (name) ->
@name: name
move: ->
alert "Galloping..."
super 45
sam: new Snake "Sammy the Python"
tom: new Horse "Tommy the Palomino"
sam.move()
tom.move()

View File

@@ -1,9 +1,9 @@
mood: greatly_improved if singing
mood: greatlyImproved if singing
if happy and knows_it
claps_hands()
cha_cha_cha()
if happy and knowsIt
clapsHands()
chaChaCha()
date: if friday then sue else jill
expensive ||= do_the_math()
options: or defaultOptions

View File

@@ -1,8 +1,8 @@
grade: (student) ->
if student.excellent_work
if student.excellentWork
"A+"
else if student.okay_stuff
if student.tried_hard then "B" else "B-"
else if student.okayStuff
if student.triedHard then "B" else "B-"
else
"C"

View File

@@ -0,0 +1,2 @@
author: "Wittgenstein"
quote: "A picture is a fact. -- $author"

View File

@@ -0,0 +1,6 @@
sentence: "${ 22 / 7 } is a decent approximation of π"
sep: "[.\\/\\- ]"
dates: /\d+$sep\d+$sep\d+/g

View File

@@ -1,5 +1,5 @@
weather_report: (location) ->
weatherReport: (location) ->
# Make an Ajax request to fetch the weather...
[location, 72, "Mostly Sunny"]
[city, temp, forecast]: weather_report "Berkeley, CA"
[city, temp, forecast]: weatherReport "Berkeley, CA"

View File

@@ -1,4 +1,4 @@
years_old: {max: 10, ida: 9, tim: 11}
yearsOld: {max: 10, ida: 9, tim: 11}
ages: for child, age of years_old
ages: for child, age of yearsOld
child + " is " + age

View File

@@ -10,4 +10,4 @@ futurists: {
}
}
{poet: {name: poet, address: [street, city]}}: futurists
{poet: {name, address: [street, city]}}: futurists

View File

@@ -0,0 +1 @@
$('.account').css {class: 'active'}

View File

@@ -1,9 +1,9 @@
# Assignment:
number: 42
opposite_day: true
opposite: true
# Conditions:
number: -42 if opposite_day
number: -42 if opposite
# Functions:
square: (x) -> x * x
@@ -26,4 +26,4 @@ race: (winner, runners...) ->
alert "I knew it!" if elvis?
# Array comprehensions:
cubed_list: math.cube num for num in list
cubes: math.cube num for num in list

View File

@@ -1,4 +1,4 @@
bait: 1000
and_switch: 0
theBait: 1000
theSwitch: 0
[bait, and_switch]: [and_switch, bait]
[theBait, theSwitch]: [theSwitch, theBait]

View File

@@ -0,0 +1,7 @@
tag: "<impossible>"
[open, contents..., close]: tag.split("")

View File

@@ -0,0 +1,2 @@
String::dasherize: ->
this.replace(/_/g, "-")

View File

@@ -1,6 +1,6 @@
countdown: num for num in [10..1]
countdown: num for num in [10..1] by -1
egg_delivery: ->
deliverEggs: ->
for i in [0...eggs.length] by 12
dozen_eggs: eggs[i...i+12]
deliver new egg_carton(dozen)
dozen: eggs[i...i+12]
deliver new eggCarton(dozen)

View File

@@ -1,5 +1,5 @@
num: 1
change_numbers: ->
new_num: -1
num: 10
new_num: change_numbers()
outer: 1
changeNumbers: ->
inner: -1
outer: 10
inner: changeNumbers()

View File

@@ -1,6 +1,6 @@
numbers: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
three_to_six: numbers[3..6]
threeToSix: numbers[3..6]
numbers_copy: numbers[0...numbers.length]
copy: numbers[0...numbers.length]

View File

@@ -1 +1 @@
lottery.draw_winner()?.address?.zipcode
lottery.drawWinner()?.address?.zipcode

View File

@@ -1,9 +1,9 @@
gold: silver: the_field: "unknown"
gold: silver: rest: "unknown"
award_medals: (first, second, rest...) ->
gold: first
silver: second
the_field: rest
awardMedals: (first, second, rest...) ->
gold: first
silver: second
rest: rest
contenders: [
"Michael Phelps"
@@ -18,8 +18,8 @@ contenders: [
"Usain Bolt"
]
award_medals contenders...
awardMedals contenders...
alert "Gold: " + gold
alert "Silver: " + silver
alert "The Field: " + the_field
alert "The Field: " + rest

View File

@@ -1,4 +1,4 @@
moby_dick: "Call me Ishmael. Some years ago --
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

View File

@@ -1,34 +0,0 @@
Animal: ->
Animal::move: (meters) ->
alert @name + " moved " + meters + "m."
Snake: (name) ->
@name: name
this
Snake extends Animal
Snake::move: ->
alert "Slithering..."
super 5
Horse: (name) ->
@name: name
this
Horse extends Animal
Horse::move: ->
alert "Galloping..."
super 45
sam: new Snake "Sammy the Python"
tom: new Horse "Tommy the Palomino"
sam.move()
tom.move()

View File

@@ -1,10 +1,10 @@
switch day
when "Mon" then go_to_work()
when "Tue" then go_to_the_park()
when "Thu" then go_ice_fishing()
when "Mon" then goToWork()
when "Tue" then goToThePark()
when "Thu" then goIceFishing()
when "Fri", "Sat"
if day is bingo_day
go_to_bingo()
go_dancing()
when "Sun" then go_to_church()
else go_to_work()
if day is bingoDay
goToBingo()
goDancing()
when "Sun" then goToChurch()
else goToWork()

View File

@@ -1,7 +1,7 @@
try
all_hell_breaks_loose()
cats_and_dogs_living_together()
allHellBreaksLoose()
catsAndDogsLivingTogether()
catch error
print error
finally
clean_up()
cleanUp()

View File

@@ -1,10 +1,10 @@
# Econ 101
if this.studying_economics
while supply > demand then buy()
while supply < demand then sell()
if this.studyingEconomics
buy() while supply > demand
sell() until supply > demand
# Nursery Rhyme
num: 6
lyrics: while num -= 1
lyrics: while num: - 1
num + " little monkeys, jumping on the bed.
One fell out and bumped his head."

View File

@@ -8,7 +8,7 @@ div.container {
width: 950px;
margin: 100px 0 50px 50px;
}
p {
p, li {
width: 625px;
}
a {
@@ -63,6 +63,11 @@ code, pre, tt, textarea {
padding: 3px 0 3px 12px;
font-size: 12px;
}
pre.no_bar {
border-left: 0;
margin-left: 0;
padding-left: 0;
}
div.code {
position: relative;
border: 1px solid #cacaca;
@@ -100,6 +105,7 @@ div.code {
position: fixed;
z-index: 100;
height: 50px;
min-width: 490px;
left: 40px; right: 40px; top: 25px;
background: #ddd;
padding-left: 235px;
@@ -112,10 +118,23 @@ div.code {
#logo {
display: block;
width: 215px; height: 50px;
background: url('logo.png');
background: url('../images/logo.png');
position: absolute;
top: 0px; left: 10px;
}
#error {
position: absolute;
-webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px;
right: 15px; top: 15px; left: 722px;
height: 15px;
padding: 2px 5px;
background: #fdcdcc;
color: #864544;
border: 1px solid #864544;
font: 10px/15px Arial;
overflow: hidden;
text-transform: uppercase;
}
.navigation {
height: 50px;
font: bold 11px/50px Arial;
@@ -124,13 +143,17 @@ div.code {
float: left;
padding: 0 20px;
border: 1px solid #bbb;
border-top: 0; border-bottom: 0;
border-top: 0; border-bottom: 0; border-left-width: 0;
cursor: pointer;
}
.navigation.try {
border-left: 0;
body.full_screen .navigation {
position: static;
}
.navigation:hover {
.navigation.toc {
border-left-width: 1px;
}
.navigation:hover,
.navigation.active {
background: #d0d0d0;
background: -webkit-gradient(linear, left top, left bottom, from(#f0f0f0), to(#c0c0c0));
background: -moz-linear-gradient(top, #f0f0f0, #c0c0c0);
@@ -147,7 +170,7 @@ div.code {
-webkit-border-top-right-radius: 0; -moz-border-radius-topright: 0;
-webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;
}
.navigation:hover .contents {
.navigation.active .contents {
display: block;
}
.navigation .contents.repl_wrapper {
@@ -155,20 +178,36 @@ div.code {
width: 700px;
padding: 0;
}
body.full_screen .navigation .contents.repl_wrapper {
position: fixed;
width: auto; height: auto;
left: 60px; top: 75px; right: 60px; bottom: 30px;
}
.navigation .contents.repl_wrapper .code {
-webkit-box-shadow: none; -moz-box-shadow: none;
background: transparent;
border: 0;
position: static;
}
body.full_screen .navigation .contents.repl_wrapper .code {
height: 100%;
padding: 0; margin: 0;
}
.navigation .code button {
bottom: 10px;
text-transform: none;
}
.navigation .compile {
left: 240px; right: auto;
.navigation .full_screen, .navigation .minimize {
right: auto;
left: 10px;
display: none;
}
body.minimized .full_screen, body.full_screen .minimize {
display: inline;
}
.navigation .contents a {
display: block;
width: 300px;
width: 290px;
text-transform: none;
text-decoration: none;
font-weight: normal;
@@ -189,19 +228,40 @@ div.code {
#repl_source, #repl_results {
background: transparent;
outline: none;
margin: 5px 0 20px;
}
#repl_source {
border: 0;
padding: 5px 7px;
#repl_source_wrap {
margin-left: 5px;
min-height: 250px;
resize: none;
width: 295px;
height: 250px;
width: 307px;
position: relative;
float: left;
}
#repl_source {
width: 96%;
height: 100%;
border: 0;
resize: none;
}
#repl_results {
font-family: Monaco, Consolas, "Lucida Console", monospace;
text-transform: none;
font-weight: normal;
min-height: 260px;
width: 355px;
}
height: 260px;
margin-bottom: 25px;
overflow-y: auto;
width: 370px;
}
body.full_screen #repl_results, body.full_screen #repl_source_wrap {
width: auto; height: auto;
position: absolute;
margin-bottom: 0;
top: 10px; left: 10px; right: 10px; bottom: 40px;
}
body.full_screen #repl_source_wrap {
right: 50%;
}
body.full_screen #repl_results {
left: 50%;
}

View File

@@ -57,6 +57,7 @@ pre.idle .FunctionName {
color: #21439C;
}
pre.idle .Variable {
color: #A535AE;
}
pre.idle .Comment {
color: #919191;

View File

@@ -0,0 +1,45 @@
<!DOCTYPE html> <html> <head> <title>cake.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="cake.html"> cake.coffee </a> <a class="source" href="coffee-script.html"> coffee-script.coffee </a> <a class="source" href="command.html"> command.coffee </a> <a class="source" href="grammar.html"> grammar.coffee </a> <a class="source" href="helpers.html"> helpers.coffee </a> <a class="source" href="index.html"> index.coffee </a> <a class="source" href="lexer.html"> lexer.coffee </a> <a class="source" href="nodes.html"> nodes.coffee </a> <a class="source" href="optparse.html"> optparse.coffee </a> <a class="source" href="repl.html"> repl.coffee </a> <a class="source" href="rewriter.html"> rewriter.coffee </a> <a class="source" href="scope.html"> scope.coffee </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> cake.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-1">#</a> </div> <p><code>cake</code> is a simplified version of <a href="http://www.gnu.org/software/make/">Make</a>
(<a href="http://rake.rubyforge.org/">Rake</a>, <a href="http://github.com/280north/jake">Jake</a>)
for CoffeeScript. You define tasks with names and descriptions in a Cakefile,
and can call them from the command line, or invoke them from other tasks.</p>
<p>Running <code>cake</code> with no arguments will print out a list of all the tasks in the
current directory's Cakefile.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>External dependencies.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">fs: </span> <span class="nx">require</span> <span class="s1">&#39;fs&#39;</span>
<span class="nv">path: </span> <span class="nx">require</span> <span class="s1">&#39;path&#39;</span>
<span class="nv">helpers: </span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./helpers&#39;</span><span class="p">).</span><span class="nx">helpers</span>
<span class="nv">optparse: </span> <span class="nx">require</span> <span class="s1">&#39;./optparse&#39;</span>
<span class="nv">CoffeeScript: </span><span class="nx">require</span> <span class="s1">&#39;./coffee-script&#39;</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <p>Keep track of the list of defined tasks, the accepted options, and so on.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">tasks: </span><span class="p">{}</span>
<span class="nv">options: </span><span class="p">{}</span>
<span class="nv">switches: </span><span class="p">[]</span>
<span class="nv">oparse: </span><span class="kc">null</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>Mixin the top-level Cake functions for Cakefiles to use directly.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">helpers</span><span class="p">.</span><span class="nx">extend</span> <span class="nx">global</span><span class="p">,</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>Define a Cake task with a short name, an optional sentence description,
and the function to run as the action itself.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">task: </span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">description</span><span class="p">,</span> <span class="nx">action</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="p">[</span><span class="nx">action</span><span class="p">,</span> <span class="nx">description</span><span class="p">]</span><span class="o">:</span> <span class="p">[</span><span class="nx">description</span><span class="p">,</span> <span class="nx">action</span><span class="p">]</span> <span class="nx">unless</span> <span class="nx">action</span>
<span class="nx">tasks</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span><span class="o">:</span> <span class="p">{</span><span class="nx">name</span><span class="p">,</span> <span class="nx">description</span><span class="p">,</span> <span class="nx">action</span><span class="p">}</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>Define an option that the Cakefile accepts. The parsed options hash,
containing all of the command-line options passed, will be made available
as the first argument to the action.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">option: </span><span class="p">(</span><span class="nx">letter</span><span class="p">,</span> <span class="nx">flag</span><span class="p">,</span> <span class="nx">description</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">switches</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="nx">letter</span><span class="p">,</span> <span class="nx">flag</span><span class="p">,</span> <span class="nx">description</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>Invoke another task in the current Cakefile.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">invoke: </span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">missingTask</span> <span class="nx">name</span> <span class="nx">unless</span> <span class="nx">tasks</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span>
<span class="nx">tasks</span><span class="p">[</span><span class="nx">name</span><span class="p">].</span><span class="nx">action</span> <span class="nx">options</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</a> </div> <p>Run <code>cake</code>. Executes all of the tasks you pass, in order. Note that Node's
asynchrony may cause tasks to execute in a different order than you'd expect.
If no tasks are passed, print the help screen.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.run: </span><span class="o">-&gt;</span>
<span class="nx">path</span><span class="p">.</span><span class="nx">exists</span> <span class="s1">&#39;Cakefile&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">exists</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s2">&quot;Cakefile not found in ${process.cwd()}&quot;</span><span class="p">)</span> <span class="nx">unless</span> <span class="nx">exists</span>
<span class="nv">args: </span><span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">...</span><span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">.</span><span class="nx">length</span><span class="p">]</span>
<span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">run</span> <span class="nx">fs</span><span class="p">.</span><span class="nx">readFileSync</span><span class="p">(</span><span class="s1">&#39;Cakefile&#39;</span><span class="p">).</span><span class="nx">toString</span><span class="p">(),</span> <span class="p">{</span><span class="nv">source: </span><span class="s1">&#39;Cakefile&#39;</span><span class="p">}</span>
<span class="nv">oparse: </span><span class="k">new</span> <span class="nx">optparse</span><span class="p">.</span><span class="nx">OptionParser</span> <span class="nx">switches</span>
<span class="k">return</span> <span class="nx">printTasks</span><span class="p">()</span> <span class="nx">unless</span> <span class="nx">args</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">options: </span><span class="nx">oparse</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">args</span><span class="p">)</span>
<span class="nx">invoke</span> <span class="nx">arg</span> <span class="k">for</span> <span class="nx">arg</span> <span class="k">in</span> <span class="nx">options</span><span class="p">.</span><span class="nx">arguments</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>Display the list of Cake tasks in a format similar to <code>rake -T</code></p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">printTasks: </span><span class="o">-&gt;</span>
<span class="nx">puts</span> <span class="s1">&#39;&#39;</span>
<span class="k">for</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">task</span> <span class="k">of</span> <span class="nx">tasks</span>
<span class="nv">spaces: </span><span class="mi">20</span> <span class="o">-</span> <span class="nx">name</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">spaces: </span><span class="k">if</span> <span class="nx">spaces</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="k">then</span> <span class="p">(</span><span class="s1">&#39; &#39;</span> <span class="k">for</span> <span class="nx">i</span> <span class="k">in</span> <span class="p">[</span><span class="mi">0</span><span class="p">..</span><span class="nx">spaces</span><span class="p">]).</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="nv">desc: </span> <span class="k">if</span> <span class="nx">task</span><span class="p">.</span><span class="nx">description</span> <span class="k">then</span> <span class="s2">&quot;# $task.description&quot;</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="nx">puts</span> <span class="s2">&quot;cake $name$spaces $desc&quot;</span>
<span class="nx">puts</span> <span class="nx">oparse</span><span class="p">.</span><span class="nx">help</span><span class="p">()</span> <span class="k">if</span> <span class="nx">switches</span><span class="p">.</span><span class="nx">length</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</a> </div> <p>Print an error and exit when attempting to all an undefined task.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">missingTask: </span><span class="p">(</span><span class="nx">task</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">puts</span> <span class="s2">&quot;No such task: \&quot;$task\&quot;&quot;</span>
<span class="nx">process</span><span class="p">.</span><span class="nx">exit</span> <span class="mi">1</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -0,0 +1,60 @@
<!DOCTYPE html> <html> <head> <title>coffee-script.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="cake.html"> cake.coffee </a> <a class="source" href="coffee-script.html"> coffee-script.coffee </a> <a class="source" href="command.html"> command.coffee </a> <a class="source" href="grammar.html"> grammar.coffee </a> <a class="source" href="helpers.html"> helpers.coffee </a> <a class="source" href="index.html"> index.coffee </a> <a class="source" href="lexer.html"> lexer.coffee </a> <a class="source" href="nodes.html"> nodes.coffee </a> <a class="source" href="optparse.html"> optparse.coffee </a> <a class="source" href="repl.html"> repl.coffee </a> <a class="source" href="rewriter.html"> rewriter.coffee </a> <a class="source" href="scope.html"> scope.coffee </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> coffee-script.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-1">#</a> </div> <p>CoffeeScript can be used both on the server, as a command-line compiler based
on Node.js/V8, or to run CoffeeScripts directly in the browser. This module
contains the main entry functions for tokenzing, parsing, and compiling source
CoffeeScript into JavaScript.</p>
<p>If included on a webpage, it will automatically sniff out, compile, and
execute all scripts present in <code>text/coffeescript</code> tags.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>Set up dependencies correctly for both the server and the browser.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">if</span> <span class="nx">process</span><span class="o">?</span>
<span class="nv">path: </span> <span class="nx">require</span> <span class="s1">&#39;path&#39;</span>
<span class="nv">Lexer: </span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./lexer&#39;</span><span class="p">).</span><span class="nx">Lexer</span>
<span class="nv">parser: </span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./parser&#39;</span><span class="p">).</span><span class="nx">parser</span>
<span class="nv">helpers: </span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./helpers&#39;</span><span class="p">).</span><span class="nx">helpers</span>
<span class="nx">helpers</span><span class="p">.</span><span class="nx">extend</span> <span class="nx">global</span><span class="p">,</span> <span class="nx">require</span> <span class="s1">&#39;./nodes&#39;</span>
<span class="k">if</span> <span class="nx">require</span><span class="p">.</span><span class="nx">registerExtension</span>
<span class="nx">require</span><span class="p">.</span><span class="nx">registerExtension</span> <span class="s1">&#39;.coffee&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">content</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">compile</span> <span class="nx">content</span>
<span class="k">else</span>
<span class="k">this</span><span class="p">.</span><span class="nv">exports: </span><span class="k">this</span><span class="p">.</span><span class="nv">CoffeeScript: </span><span class="p">{}</span>
<span class="nv">Lexer: </span> <span class="k">this</span><span class="p">.</span><span class="nx">Lexer</span>
<span class="nv">parser: </span> <span class="k">this</span><span class="p">.</span><span class="nx">parser</span>
<span class="nv">helpers: </span> <span class="k">this</span><span class="p">.</span><span class="nx">helpers</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <p>The current CoffeeScript version number.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.VERSION: </span><span class="s1">&#39;0.7.1&#39;</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>Instantiate a Lexer for our use here.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">lexer: </span><span class="k">new</span> <span class="nx">Lexer</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>Compile a string of CoffeeScript code to JavaScript, using the Coffee/Jison
compiler.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.compile: compile: </span><span class="p">(</span><span class="nx">code</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">options: </span><span class="o">or</span> <span class="p">{}</span>
<span class="k">try</span>
<span class="p">(</span><span class="nx">parser</span><span class="p">.</span><span class="nx">parse</span> <span class="nx">lexer</span><span class="p">.</span><span class="nx">tokenize</span> <span class="nx">code</span><span class="p">).</span><span class="nx">compile</span> <span class="nx">options</span>
<span class="k">catch</span> <span class="nx">err</span>
<span class="nv">err.message: </span><span class="s2">&quot;In $options.source, $err.message&quot;</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">source</span>
<span class="k">throw</span> <span class="nx">err</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>Tokenize a string of CoffeeScript code, and return the array of tokens.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.tokens: </span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">lexer</span><span class="p">.</span><span class="nx">tokenize</span> <span class="nx">code</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>Tokenize and parse a string of CoffeeScript code, and return the AST. You can
then compile it by calling <code>.compile()</code> on the root, or traverse it by using
<code>.traverse()</code> with a callback.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.nodes: </span><span class="p">(</span><span class="nx">code</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">parser</span><span class="p">.</span><span class="nx">parse</span> <span class="nx">lexer</span><span class="p">.</span><span class="nx">tokenize</span> <span class="nx">code</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</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> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.run: </span><span class="p">((</span><span class="nx">code</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">module.filename: __filename: </span><span class="nx">options</span><span class="p">.</span><span class="nx">source</span>
<span class="nv">__dirname: </span><span class="nx">path</span><span class="p">.</span><span class="nx">dirname</span><span class="p">(</span><span class="nx">__filename</span><span class="p">)</span>
<span class="nb">eval</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">code</span><span class="p">,</span> <span class="nx">options</span>
<span class="p">)</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>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
directly as a "Jison lexer".</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">parser.lexer: </span><span class="p">{</span>
<span class="nv">lex: </span><span class="o">-&gt;</span>
<span class="nv">token: </span><span class="nx">@tokens</span><span class="p">[</span><span class="nx">@pos</span><span class="p">]</span> <span class="o">or</span> <span class="p">[</span><span class="s2">&quot;&quot;</span><span class="p">]</span>
<span class="vi">@pos: </span><span class="o">+</span> <span class="mi">1</span>
<span class="k">this</span><span class="p">.</span><span class="nv">yylineno: </span><span class="nx">token</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
<span class="k">this</span><span class="p">.</span><span class="nv">yytext: </span> <span class="nx">token</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="nv">setInput: </span><span class="p">(</span><span class="nx">tokens</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@tokens: </span><span class="nx">tokens</span>
<span class="vi">@pos: </span><span class="mi">0</span>
<span class="nv">upcomingInput: </span><span class="o">-&gt;</span> <span class="s2">&quot;&quot;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</a> </div> <p>Activate CoffeeScript in the browser by having it compile and evaluate
all script tags with a content-type of <code>text/coffeescript</code>. This happens
on page load. Unfortunately, the text contents of remote scripts cannot be
accessed from the browser, so only inline script tags will work.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">if</span> <span class="nb">document</span><span class="o">?</span> <span class="o">and</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementsByTagName</span>
<span class="nv">processScripts: </span><span class="o">-&gt;</span>
<span class="k">for</span> <span class="nx">tag</span> <span class="k">in</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementsByTagName</span><span class="p">(</span><span class="s1">&#39;script&#39;</span><span class="p">)</span> <span class="k">when</span> <span class="nx">tag</span><span class="p">.</span><span class="nx">type</span> <span class="o">is</span> <span class="s1">&#39;text/coffeescript&#39;</span>
<span class="nb">eval</span> <span class="nx">exports</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">tag</span><span class="p">.</span><span class="nx">innerHTML</span>
<span class="k">if</span> <span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span> <span class="s1">&#39;load&#39;</span><span class="p">,</span> <span class="nx">processScripts</span><span class="p">,</span> <span class="kc">false</span>
<span class="k">else</span> <span class="k">if</span> <span class="nb">window</span><span class="p">.</span><span class="nx">attachEvent</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">attachEvent</span> <span class="s1">&#39;onload&#39;</span><span class="p">,</span> <span class="nx">processScripts</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -0,0 +1,131 @@
<!DOCTYPE html> <html> <head> <title>command.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="cake.html"> cake.coffee </a> <a class="source" href="coffee-script.html"> coffee-script.coffee </a> <a class="source" href="command.html"> command.coffee </a> <a class="source" href="grammar.html"> grammar.coffee </a> <a class="source" href="helpers.html"> helpers.coffee </a> <a class="source" href="index.html"> index.coffee </a> <a class="source" href="lexer.html"> lexer.coffee </a> <a class="source" href="nodes.html"> nodes.coffee </a> <a class="source" href="optparse.html"> optparse.coffee </a> <a class="source" href="repl.html"> repl.coffee </a> <a class="source" href="rewriter.html"> rewriter.coffee </a> <a class="source" href="scope.html"> scope.coffee </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> command.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-1">#</a> </div> <p>The <code>coffee</code> utility. Handles command-line compilation of CoffeeScript
into various forms: saved into <code>.js</code> files or printed to stdout, piped to
<a href="http://javascriptlint.com/">JSLint</a> or recompiled every time the source is
saved, printed as a token stream or as the syntax tree, or launch an
interactive REPL.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>External dependencies.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">fs: </span> <span class="nx">require</span> <span class="s1">&#39;fs&#39;</span>
<span class="nv">path: </span> <span class="nx">require</span> <span class="s1">&#39;path&#39;</span>
<span class="nv">optparse: </span> <span class="nx">require</span> <span class="s1">&#39;./optparse&#39;</span>
<span class="nv">CoffeeScript: </span> <span class="nx">require</span> <span class="s1">&#39;./coffee-script&#39;</span>
<span class="p">{</span><span class="nx">spawn</span><span class="p">,</span> <span class="nx">exec</span><span class="p">}</span><span class="o">:</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;child_process&#39;</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <p>The help banner that is printed when <code>coffee</code> is called without arguments.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">BANNER: </span><span class="s1">&#39;&#39;&#39;</span>
<span class="s1"> coffee compiles CoffeeScript source files into JavaScript.</span>
<span class="s1"> Usage:</span>
<span class="s1"> coffee path/to/script.coffee</span>
<span class="s1"> &#39;&#39;&#39;</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>The list of all the valid option flags that <code>coffee</code> knows how to handle.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">SWITCHES: </span><span class="p">[</span>
<span class="p">[</span><span class="s1">&#39;-c&#39;</span><span class="p">,</span> <span class="s1">&#39;--compile&#39;</span><span class="p">,</span> <span class="s1">&#39;compile to JavaScript and save as .js files&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s1">&#39;-i&#39;</span><span class="p">,</span> <span class="s1">&#39;--interactive&#39;</span><span class="p">,</span> <span class="s1">&#39;run an interactive CoffeeScript REPL&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s1">&#39;-o&#39;</span><span class="p">,</span> <span class="s1">&#39;--output [DIR]&#39;</span><span class="p">,</span> <span class="s1">&#39;set the directory for compiled JavaScript&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s1">&#39;-w&#39;</span><span class="p">,</span> <span class="s1">&#39;--watch&#39;</span><span class="p">,</span> <span class="s1">&#39;watch scripts for changes, and recompile&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s1">&#39;-p&#39;</span><span class="p">,</span> <span class="s1">&#39;--print&#39;</span><span class="p">,</span> <span class="s1">&#39;print the compiled JavaScript to stdout&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s1">&#39;-l&#39;</span><span class="p">,</span> <span class="s1">&#39;--lint&#39;</span><span class="p">,</span> <span class="s1">&#39;pipe the compiled JavaScript through JSLint&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s1">&#39;-s&#39;</span><span class="p">,</span> <span class="s1">&#39;--stdio&#39;</span><span class="p">,</span> <span class="s1">&#39;listen for and compile scripts over stdio&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s1">&#39;-e&#39;</span><span class="p">,</span> <span class="s1">&#39;--eval&#39;</span><span class="p">,</span> <span class="s1">&#39;compile a string from the command line&#39;</span><span class="p">]</span>
<span class="p">[</span> <span class="s1">&#39;--no-wrap&#39;</span><span class="p">,</span> <span class="s1">&#39;compile without the top-level function wrapper&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s1">&#39;-t&#39;</span><span class="p">,</span> <span class="s1">&#39;--tokens&#39;</span><span class="p">,</span> <span class="s1">&#39;print the tokens that the lexer produces&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s1">&#39;-n&#39;</span><span class="p">,</span> <span class="s1">&#39;--nodes&#39;</span><span class="p">,</span> <span class="s1">&#39;print the parse tree that Jison produces&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s1">&#39;-v&#39;</span><span class="p">,</span> <span class="s1">&#39;--version&#39;</span><span class="p">,</span> <span class="s1">&#39;display CoffeeScript version&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s1">&#39;-h&#39;</span><span class="p">,</span> <span class="s1">&#39;--help&#39;</span><span class="p">,</span> <span class="s1">&#39;display this help message&#39;</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>Top-level objects shared by all the functions.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">options: </span><span class="p">{}</span>
<span class="nv">sources: </span><span class="p">[]</span>
<span class="nv">optionParser: </span><span class="kc">null</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>Run <code>coffee</code> by parsing passed options and determining what action to take.
Many flags cause us to divert before compiling anything. Flags passed after
<code>--</code> will be passed verbatim to your script as arguments in <code>process.argv</code></p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.run: </span><span class="o">-&gt;</span>
<span class="nx">parseOptions</span><span class="p">()</span>
<span class="k">return</span> <span class="nx">usage</span><span class="p">()</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">help</span>
<span class="k">return</span> <span class="nx">version</span><span class="p">()</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">version</span>
<span class="k">return</span> <span class="nx">require</span> <span class="s1">&#39;./repl&#39;</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">interactive</span>
<span class="k">return</span> <span class="nx">compileStdio</span><span class="p">()</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">stdio</span>
<span class="k">return</span> <span class="nx">compileScript</span> <span class="s1">&#39;console&#39;</span><span class="p">,</span> <span class="nx">sources</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nb">eval</span>
<span class="k">return</span> <span class="nx">require</span> <span class="s1">&#39;./repl&#39;</span> <span class="nx">unless</span> <span class="nx">sources</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">separator: </span><span class="nx">sources</span><span class="p">.</span><span class="nx">indexOf</span> <span class="s1">&#39;--&#39;</span>
<span class="nv">flags: </span><span class="p">[]</span>
<span class="k">if</span> <span class="nx">separator</span> <span class="o">&gt;=</span> <span class="mi">0</span>
<span class="nv">flags: </span> <span class="nx">sources</span><span class="p">[(</span><span class="nx">separator</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)...</span><span class="nx">sources</span><span class="p">.</span><span class="nx">length</span><span class="p">]</span>
<span class="nv">sources: </span><span class="nx">sources</span><span class="p">[</span><span class="mi">0</span><span class="p">...</span><span class="nx">separator</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">run</span>
<span class="nv">flags: </span> <span class="nx">sources</span><span class="p">[</span><span class="mi">1</span><span class="p">..</span><span class="nx">sources</span><span class="p">.</span><span class="nx">length</span><span class="p">].</span><span class="nx">concat</span> <span class="nx">flags</span>
<span class="nv">sources: </span><span class="p">[</span><span class="nx">sources</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span>
<span class="nv">process.ARGV: process.argv: </span><span class="nx">flags</span>
<span class="nx">compileScripts</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>Asynchronously read in each CoffeeScript in a list of source files and
compile them. If a directory is passed, recursively compile all
'.coffee' extension source files in it and all subdirectories.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">compileScripts: </span><span class="o">-&gt;</span>
<span class="k">for</span> <span class="nx">source</span> <span class="k">in</span> <span class="nx">sources</span>
<span class="nv">base: </span><span class="nx">source</span>
<span class="nv">compile: </span><span class="p">(</span><span class="nx">source</span><span class="p">,</span> <span class="nx">topLevel</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">path</span><span class="p">.</span><span class="nx">exists</span> <span class="nx">source</span><span class="p">,</span> <span class="p">(</span><span class="nx">exists</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s2">&quot;File not found: $source&quot;</span> <span class="nx">unless</span> <span class="nx">exists</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">stat</span> <span class="nx">source</span><span class="p">,</span> <span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">stats</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">if</span> <span class="nx">stats</span><span class="p">.</span><span class="nx">isDirectory</span><span class="p">()</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">readdir</span> <span class="nx">source</span><span class="p">,</span> <span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">files</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">for</span> <span class="nx">file</span> <span class="k">in</span> <span class="nx">files</span>
<span class="nx">compile</span> <span class="nx">path</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="nx">source</span><span class="p">,</span> <span class="nx">file</span><span class="p">)</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">topLevel</span> <span class="o">or</span> <span class="nx">path</span><span class="p">.</span><span class="nx">extname</span><span class="p">(</span><span class="nx">source</span><span class="p">)</span> <span class="o">is</span> <span class="s1">&#39;.coffee&#39;</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">readFile</span> <span class="nx">source</span><span class="p">,</span> <span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">code</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">compileScript</span><span class="p">(</span><span class="nx">source</span><span class="p">,</span> <span class="nx">code</span><span class="p">.</span><span class="nx">toString</span><span class="p">(),</span> <span class="nx">base</span><span class="p">)</span>
<span class="nx">watch</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">base</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">watch</span>
<span class="nx">compile</span> <span class="nx">source</span><span class="p">,</span> <span class="kc">true</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</a> </div> <p>Compile a single source script, containing the given code, according to the
requested options. If evaluating the script directly sets <code>__filename</code>,
<code>__dirname</code> and <code>module.filename</code> to be correct relative to the script's path.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">compileScript: </span><span class="p">(</span><span class="nx">source</span><span class="p">,</span> <span class="nx">code</span><span class="p">,</span> <span class="nx">base</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">o: </span><span class="nx">options</span>
<span class="nv">codeOpts: </span><span class="nx">compileOptions</span> <span class="nx">source</span>
<span class="k">try</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">tokens</span> <span class="k">then</span> <span class="nx">printTokens</span> <span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">tokens</span> <span class="nx">code</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">nodes</span> <span class="k">then</span> <span class="nx">puts</span> <span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">nodes</span><span class="p">(</span><span class="nx">code</span><span class="p">).</span><span class="nx">toString</span><span class="p">()</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">run</span> <span class="k">then</span> <span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">run</span> <span class="nx">code</span><span class="p">,</span> <span class="nx">codeOpts</span>
<span class="k">else</span>
<span class="nv">js: </span><span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">compile</span> <span class="nx">code</span><span class="p">,</span> <span class="nx">codeOpts</span>
<span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">print</span> <span class="k">then</span> <span class="nx">print</span> <span class="nx">js</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">compile</span> <span class="k">then</span> <span class="nx">writeJs</span> <span class="nx">source</span><span class="p">,</span> <span class="nx">js</span><span class="p">,</span> <span class="nx">base</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">lint</span> <span class="k">then</span> <span class="nx">lint</span> <span class="nx">js</span>
<span class="k">catch</span> <span class="nx">err</span>
<span class="nx">error</span><span class="p">(</span><span class="nx">err</span><span class="p">.</span><span class="nx">stack</span><span class="p">)</span> <span class="o">and</span> <span class="nx">process</span><span class="p">.</span><span class="nx">exit</span> <span class="mi">1</span> <span class="nx">unless</span> <span class="nx">o</span><span class="p">.</span><span class="nx">watch</span>
<span class="nx">puts</span> <span class="nx">err</span><span class="p">.</span><span class="nx">message</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>Attach the appropriate listeners to compile scripts incoming over <strong>stdin</strong>,
and write them back to <strong>stdout</strong>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">compileStdio: </span><span class="o">-&gt;</span>
<span class="nv">code: </span><span class="s1">&#39;&#39;</span>
<span class="nv">stdin: </span><span class="nx">process</span><span class="p">.</span><span class="nx">openStdin</span><span class="p">()</span>
<span class="nx">stdin</span><span class="p">.</span><span class="nx">addListener</span> <span class="s1">&#39;data&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">buffer</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">code: </span><span class="o">+</span> <span class="nx">buffer</span><span class="p">.</span><span class="nx">toString</span><span class="p">()</span> <span class="k">if</span> <span class="nx">buffer</span>
<span class="nx">stdin</span><span class="p">.</span><span class="nx">addListener</span> <span class="s1">&#39;end&#39;</span><span class="p">,</span> <span class="o">-&gt;</span>
<span class="nx">compileScript</span> <span class="s1">&#39;stdio&#39;</span><span class="p">,</span> <span class="nx">code</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</a> </div> <p>Watch a source CoffeeScript file using <code>fs.watchFile</code>, recompiling it every
time the file is updated. May be used in combination with other options,
such as <code>--lint</code> or <code>--print</code>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">watch: </span><span class="p">(</span><span class="nx">source</span><span class="p">,</span> <span class="nx">base</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">watchFile</span> <span class="nx">source</span><span class="p">,</span> <span class="p">{</span><span class="nv">persistent: </span><span class="kc">true</span><span class="p">,</span> <span class="nv">interval: </span><span class="mi">500</span><span class="p">},</span> <span class="p">(</span><span class="nx">curr</span><span class="p">,</span> <span class="nx">prev</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">curr</span><span class="p">.</span><span class="nx">mtime</span><span class="p">.</span><span class="nx">getTime</span><span class="p">()</span> <span class="o">is</span> <span class="nx">prev</span><span class="p">.</span><span class="nx">mtime</span><span class="p">.</span><span class="nx">getTime</span><span class="p">()</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">readFile</span> <span class="nx">source</span><span class="p">,</span> <span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">code</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">compileScript</span><span class="p">(</span><span class="nx">source</span><span class="p">,</span> <span class="nx">code</span><span class="p">.</span><span class="nx">toString</span><span class="p">(),</span> <span class="nx">base</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-11">#</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> </td> <td class="code"> <div class="highlight"><pre><span class="nv">writeJs: </span><span class="p">(</span><span class="nx">source</span><span class="p">,</span> <span class="nx">js</span><span class="p">,</span> <span class="nx">base</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">filename: </span><span class="nx">path</span><span class="p">.</span><span class="nx">basename</span><span class="p">(</span><span class="nx">source</span><span class="p">,</span> <span class="nx">path</span><span class="p">.</span><span class="nx">extname</span><span class="p">(</span><span class="nx">source</span><span class="p">))</span> <span class="o">+</span> <span class="s1">&#39;.js&#39;</span>
<span class="nv">srcDir: </span> <span class="nx">path</span><span class="p">.</span><span class="nx">dirname</span> <span class="nx">source</span>
<span class="nv">baseDir: </span> <span class="nx">srcDir</span><span class="p">.</span><span class="nx">substring</span> <span class="nx">base</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">dir: </span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">output</span> <span class="k">then</span> <span class="nx">path</span><span class="p">.</span><span class="nx">join</span> <span class="nx">options</span><span class="p">.</span><span class="nx">output</span><span class="p">,</span> <span class="nx">baseDir</span> <span class="k">else</span> <span class="nx">srcDir</span>
<span class="nv">jsPath: </span> <span class="nx">path</span><span class="p">.</span><span class="nx">join</span> <span class="nx">dir</span><span class="p">,</span> <span class="nx">filename</span>
<span class="nv">compile: </span> <span class="o">-&gt;</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">writeFile</span> <span class="nx">jsPath</span><span class="p">,</span> <span class="nx">js</span><span class="p">,</span> <span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">puts</span> <span class="s2">&quot;Compiled $source&quot;</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">compile</span> <span class="o">and</span> <span class="nx">options</span><span class="p">.</span><span class="nx">watch</span>
<span class="nx">path</span><span class="p">.</span><span class="nx">exists</span> <span class="nx">dir</span><span class="p">,</span> <span class="p">(</span><span class="nx">exists</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">if</span> <span class="nx">exists</span> <span class="k">then</span> <span class="nx">compile</span><span class="p">()</span> <span class="k">else</span> <span class="nx">exec</span> <span class="s2">&quot;mkdir -p $dir&quot;</span><span class="p">,</span> <span class="nx">compile</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-12">#</a> </div> <p>Pipe compiled JS through JSLint (requires a working <code>jsl</code> command), printing
any errors or warnings that arise.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">lint: </span><span class="p">(</span><span class="nx">js</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">printIt: </span><span class="p">(</span><span class="nx">buffer</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">print</span> <span class="nx">buffer</span><span class="p">.</span><span class="nx">toString</span><span class="p">()</span>
<span class="nv">jsl: </span><span class="nx">spawn</span> <span class="s1">&#39;jsl&#39;</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;-nologo&#39;</span><span class="p">,</span> <span class="s1">&#39;-stdin&#39;</span><span class="p">]</span>
<span class="nx">jsl</span><span class="p">.</span><span class="nx">stdout</span><span class="p">.</span><span class="nx">addListener</span> <span class="s1">&#39;data&#39;</span><span class="p">,</span> <span class="nx">printIt</span>
<span class="nx">jsl</span><span class="p">.</span><span class="nx">stderr</span><span class="p">.</span><span class="nx">addListener</span> <span class="s1">&#39;data&#39;</span><span class="p">,</span> <span class="nx">printIt</span>
<span class="nx">jsl</span><span class="p">.</span><span class="nx">stdin</span><span class="p">.</span><span class="nx">write</span> <span class="nx">js</span>
<span class="nx">jsl</span><span class="p">.</span><span class="nx">stdin</span><span class="p">.</span><span class="nx">end</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-13">#</a> </div> <p>Pretty-print a stream of tokens.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">printTokens: </span><span class="p">(</span><span class="nx">tokens</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">strings: </span><span class="k">for</span> <span class="nx">token</span> <span class="k">in</span> <span class="nx">tokens</span>
<span class="p">[</span><span class="nx">tag</span><span class="p">,</span> <span class="nx">value</span><span class="p">]</span><span class="o">:</span> <span class="p">[</span><span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nx">token</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">toString</span><span class="p">().</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/\n/</span><span class="p">,</span> <span class="s1">&#39;\\n&#39;</span><span class="p">)]</span>
<span class="s2">&quot;[$tag $value]&quot;</span>
<span class="nx">puts</span> <span class="nx">strings</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-14">#</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> </td> <td class="code"> <div class="highlight"><pre><span class="nv">parseOptions: </span><span class="o">-&gt;</span>
<span class="nv">optionParser: </span> <span class="k">new</span> <span class="nx">optparse</span><span class="p">.</span><span class="nx">OptionParser</span> <span class="nx">SWITCHES</span><span class="p">,</span> <span class="nx">BANNER</span>
<span class="nv">o: options: </span> <span class="nx">optionParser</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">...</span><span class="nx">process</span><span class="p">.</span><span class="nx">argv</span><span class="p">.</span><span class="nx">length</span><span class="p">])</span>
<span class="nv">options.run: </span> <span class="o">not</span> <span class="p">(</span><span class="nx">o</span><span class="p">.</span><span class="nx">compile</span> <span class="o">or</span> <span class="nx">o</span><span class="p">.</span><span class="nx">print</span> <span class="o">or</span> <span class="nx">o</span><span class="p">.</span><span class="nx">lint</span><span class="p">)</span>
<span class="nv">options.print: </span><span class="o">!!</span> <span class="p">(</span><span class="nx">o</span><span class="p">.</span><span class="nx">print</span> <span class="o">or</span> <span class="p">(</span><span class="nx">o</span><span class="p">.</span><span class="nb">eval</span> <span class="o">or</span> <span class="nx">o</span><span class="p">.</span><span class="nx">stdio</span> <span class="o">and</span> <span class="nx">o</span><span class="p">.</span><span class="nx">compile</span><span class="p">))</span>
<span class="nv">sources: </span> <span class="nx">options</span><span class="p">.</span><span class="nx">arguments</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-15">#</a> </div> <p>The compile-time options to pass to the CoffeeScript compiler.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">compileOptions: </span><span class="p">(</span><span class="nx">source</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">o: </span><span class="p">{</span><span class="nx">source</span><span class="p">}</span>
<span class="nv">o.noWrap: </span><span class="nx">options</span><span class="p">[</span><span class="s1">&#39;no-wrap&#39;</span><span class="p">]</span>
<span class="nx">o</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-16">#</a> </div> <p>Print the <code>--help</code> usage message and exit.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">usage: </span><span class="o">-&gt;</span>
<span class="nx">puts</span> <span class="nx">optionParser</span><span class="p">.</span><span class="nx">help</span><span class="p">()</span>
<span class="nx">process</span><span class="p">.</span><span class="nx">exit</span> <span class="mi">0</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-17">#</a> </div> <p>Print the <code>--version</code> message and exit.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">version: </span><span class="o">-&gt;</span>
<span class="nx">puts</span> <span class="s2">&quot;CoffeeScript version $CoffeeScript.VERSION&quot;</span>
<span class="nx">process</span><span class="p">.</span><span class="nx">exit</span> <span class="mi">0</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -0,0 +1,185 @@
/*--------------------- Layout and Typography ----------------------------*/
body {
font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
font-size: 16px;
line-height: 24px;
color: #252519;
margin: 0; padding: 0;
}
a {
color: #261a3b;
}
a:visited {
color: #261a3b;
}
p {
margin: 0 0 15px 0;
}
h1, h2, h3, h4, h5, h6 {
margin: 40px 0 15px 0;
}
h3, h4, h5, h6 {
margin-top: 20px;
}
#container {
position: relative;
}
#background {
position: fixed;
top: 0; left: 580px; right: 0; bottom: 0;
background: #f5f5ff;
border-left: 1px solid #e5e5ee;
z-index: -1;
}
#jump_to, #jump_page {
background: white;
-webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;
-webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;
font: 10px Arial;
text-transform: uppercase;
cursor: pointer;
text-align: right;
}
#jump_to, #jump_wrapper {
position: fixed;
right: 0; top: 0;
padding: 5px 10px;
}
#jump_wrapper {
padding: 0;
display: none;
}
#jump_to:hover #jump_wrapper {
display: block;
}
#jump_page {
padding: 5px 0 3px;
margin: 0 0 25px 25px;
}
#jump_page .source {
display: block;
padding: 5px 10px;
text-decoration: none;
border-top: 1px solid #eee;
}
#jump_page .source:hover {
background: #f5f5ff;
}
#jump_page .source:first-child {
}
table td {
border: 0;
outline: 0;
}
td.docs, th.docs {
max-width: 500px;
min-width: 500px;
min-height: 5px;
padding: 10px 25px 1px 50px;
vertical-align: top;
text-align: left;
}
.docs pre {
margin: 15px 0 15px;
padding-left: 15px;
}
.docs p tt, .docs p code {
background: #f8f8ff;
border: 1px solid #dedede;
font-size: 12px;
padding: 0 0.2em;
}
.octowrap {
position: relative;
}
.octothorpe {
font: 12px Arial;
text-decoration: none;
color: #454545;
position: absolute;
top: 3px; left: -20px;
padding: 1px 2px;
opacity: 0;
-webkit-transition: opacity 0.2s linear;
}
td.docs:hover .octothorpe {
opacity: 1;
}
td.code, th.code {
padding: 14px 15px 16px 50px;
width: 100%;
vertical-align: top;
background: #f5f5ff;
border-left: 1px solid #e5e5ee;
}
pre, tt, code {
font-size: 12px; line-height: 18px;
font-family: Monaco, Consolas, "Lucida Console", monospace;
margin: 0; padding: 0;
}
/*---------------------- Syntax Highlighting -----------------------------*/
td.linenos { background-color: #f0f0f0; padding-right: 10px; }
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
body .hll { background-color: #ffffcc }
body .c { color: #408080; font-style: italic } /* Comment */
body .err { border: 1px solid #FF0000 } /* Error */
body .k { color: #954121 } /* Keyword */
body .o { color: #666666 } /* Operator */
body .cm { color: #408080; font-style: italic } /* Comment.Multiline */
body .cp { color: #BC7A00 } /* Comment.Preproc */
body .c1 { color: #408080; font-style: italic } /* Comment.Single */
body .cs { color: #408080; font-style: italic } /* Comment.Special */
body .gd { color: #A00000 } /* Generic.Deleted */
body .ge { font-style: italic } /* Generic.Emph */
body .gr { color: #FF0000 } /* Generic.Error */
body .gh { color: #000080; font-weight: bold } /* Generic.Heading */
body .gi { color: #00A000 } /* Generic.Inserted */
body .go { color: #808080 } /* Generic.Output */
body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
body .gs { font-weight: bold } /* Generic.Strong */
body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
body .gt { color: #0040D0 } /* Generic.Traceback */
body .kc { color: #954121 } /* Keyword.Constant */
body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */
body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */
body .kp { color: #954121 } /* Keyword.Pseudo */
body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */
body .kt { color: #B00040 } /* Keyword.Type */
body .m { color: #666666 } /* Literal.Number */
body .s { color: #219161 } /* Literal.String */
body .na { color: #7D9029 } /* Name.Attribute */
body .nb { color: #954121 } /* Name.Builtin */
body .nc { color: #0000FF; font-weight: bold } /* Name.Class */
body .no { color: #880000 } /* Name.Constant */
body .nd { color: #AA22FF } /* Name.Decorator */
body .ni { color: #999999; font-weight: bold } /* Name.Entity */
body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
body .nf { color: #0000FF } /* Name.Function */
body .nl { color: #A0A000 } /* Name.Label */
body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
body .nt { color: #954121; font-weight: bold } /* Name.Tag */
body .nv { color: #19469D } /* Name.Variable */
body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
body .w { color: #bbbbbb } /* Text.Whitespace */
body .mf { color: #666666 } /* Literal.Number.Float */
body .mh { color: #666666 } /* Literal.Number.Hex */
body .mi { color: #666666 } /* Literal.Number.Integer */
body .mo { color: #666666 } /* Literal.Number.Oct */
body .sb { color: #219161 } /* Literal.String.Backtick */
body .sc { color: #219161 } /* Literal.String.Char */
body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */
body .s2 { color: #219161 } /* Literal.String.Double */
body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
body .sh { color: #219161 } /* Literal.String.Heredoc */
body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
body .sx { color: #954121 } /* Literal.String.Other */
body .sr { color: #BB6688 } /* Literal.String.Regex */
body .s1 { color: #219161 } /* Literal.String.Single */
body .ss { color: #19469D } /* Literal.String.Symbol */
body .bp { color: #954121 } /* Name.Builtin.Pseudo */
body .vc { color: #19469D } /* Name.Variable.Class */
body .vg { color: #19469D } /* Name.Variable.Global */
body .vi { color: #19469D } /* Name.Variable.Instance */
body .il { color: #666666 } /* Literal.Number.Integer.Long */

View File

@@ -0,0 +1,416 @@
<!DOCTYPE html> <html> <head> <title>grammar.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="cake.html"> cake.coffee </a> <a class="source" href="coffee-script.html"> coffee-script.coffee </a> <a class="source" href="command.html"> command.coffee </a> <a class="source" href="grammar.html"> grammar.coffee </a> <a class="source" href="helpers.html"> helpers.coffee </a> <a class="source" href="index.html"> index.coffee </a> <a class="source" href="lexer.html"> lexer.coffee </a> <a class="source" href="nodes.html"> nodes.coffee </a> <a class="source" href="optparse.html"> optparse.coffee </a> <a class="source" href="repl.html"> repl.coffee </a> <a class="source" href="rewriter.html"> rewriter.coffee </a> <a class="source" href="scope.html"> scope.coffee </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> grammar.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-1">#</a> </div> <p>The CoffeeScript parser is generated by <a href="http://github.com/zaach/jison">Jison</a>
from this grammar file. Jison is a bottom-up parser generator, similar in
style to <a href="http://www.gnu.org/software/bison">Bison</a>, implemented in JavaScript.
It can recognize <a href="http://en.wikipedia.org/wiki/LR_grammar">LALR(1), LR(0), SLR(1), and LR(1)</a>
type grammars. To create the Jison parser, we list the pattern to match
on the left-hand side, and the action to take (usually the creation of syntax
tree nodes) on the right. As the parser runs, it
shifts tokens from our token stream, from left to right, and
<a href="http://en.wikipedia.org/wiki/Bottom-up_parsing">attempts to match</a>
the token sequence against the rules below. When a match can be made, it
reduces into the <a href="http://en.wikipedia.org/wiki/Terminal_and_nonterminal_symbols">nonterminal</a>
(the enclosing name at the top), and we proceed from there.</p>
<p>If you run the <code>cake build:parser</code> command, Jison constructs a parse table
from our rules and saves it into <code>lib/parser.js</code>.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>The only dependency is on the <strong>Jison.Parser</strong>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">Parser: </span><span class="nx">require</span><span class="p">(</span><span class="s1">&#39;jison&#39;</span><span class="p">).</span><span class="nx">Parser</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <h2>Jison DSL</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>Since we're going to be wrapped in a function by Jison in any case, if our
action immediately returns a value, we can optimize by removing the function
wrapper and just returning the value directly.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">unwrap: </span><span class="sr">/function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>Our handy DSL for Jison grammar generation, thanks to
<a href="http://github.com/creationix">Tim Caswell</a>. For every rule in the grammar,
we pass the pattern-defining string, the action to run, and extra options,
optionally. If no action is specified, we simply pass the value of the
previous nonterminal.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">o: </span><span class="p">(</span><span class="nx">patternString</span><span class="p">,</span> <span class="nx">action</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="p">[</span><span class="nx">patternString</span><span class="p">,</span> <span class="s1">&#39;$$ = $1;&#39;</span><span class="p">,</span> <span class="nx">options</span><span class="p">]</span> <span class="nx">unless</span> <span class="nx">action</span>
<span class="nv">action: </span><span class="k">if</span> <span class="nv">match: </span><span class="p">(</span><span class="nx">action</span> <span class="o">+</span> <span class="s1">&#39;&#39;</span><span class="p">).</span><span class="nx">match</span><span class="p">(</span><span class="nx">unwrap</span><span class="p">)</span> <span class="k">then</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">else</span> <span class="s2">&quot;($action())&quot;</span>
<span class="p">[</span><span class="nx">patternString</span><span class="p">,</span> <span class="s2">&quot;$$ = $action;&quot;</span><span class="p">,</span> <span class="nx">options</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <h2>Grammatical Rules</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>In all of the rules that follow, you'll see the name of the nonterminal as
the key to a list of alternative matches. With each match's action, the
dollar-sign variables are provided by Jison as references to the value of
their numeric position, so in this rule:</p>
<pre><code>"Expression UNLESS Expression"
</code></pre>
<p><code>$1</code> would be the value of the first <code>Expression</code>, <code>$2</code> would be the token
for the <code>UNLESS</code> terminal, and <code>$3</code> would be the value of the second
<code>Expression</code>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">grammar: </span><span class="p">{</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</a> </div> <p>The <strong>Root</strong> is the top-level node in the syntax tree. Since we parse bottom-up,
all parsing must end here.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Root: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">Expressions</span>
<span class="nx">o</span> <span class="s2">&quot;TERMINATOR&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">Expressions</span>
<span class="nx">o</span> <span class="s2">&quot;Body&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Block TERMINATOR&quot;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>Any list of statements and expressions, seperated by line breaks or semicolons.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Body: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Line&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">$1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;Body TERMINATOR Line&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">push</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Body TERMINATOR&quot;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</a> </div> <p>Expressions and statements, which make up a line in a body.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Line: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Expression&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Statement&quot;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-11">#</a> </div> <p>Pure statements which cannot be expressions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Statement: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Return&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Throw&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;BREAK&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s2">&quot;CONTINUE&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-12">#</a> </div> <p>All the different types of expressions in our language. The basic unit of
CoffeeScript is the <strong>Expression</strong> -- everything that can be an expression
is one. Expressions serve as the building blocks of many other rules, making
them somewhat circular.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Expression: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Value&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Call&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Code&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Operation&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Assign&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;If&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Try&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;While&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;For&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Switch&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Extends&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Class&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Splat&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Existence&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Comment&quot;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-13">#</a> </div> <p>A an indented block of expressions. Note that the <a href="rewriter.html">Rewriter</a>
will convert some postfix forms into blocks for us, by adjusting the
token stream.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Block: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;INDENT Body OUTDENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;INDENT OUTDENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">Expressions</span>
<span class="nx">o</span> <span class="s2">&quot;TERMINATOR Comment&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">$2</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-14">#</a> </div> <p>A literal identifier, a variable name or property.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Identifier: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;IDENTIFIER&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-15">#</a> </div> <p>Alphanumerics are separated from the other <strong>Literal</strong> matchers because
they can also serve as keys in object literals.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">AlphaNumeric: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;NUMBER&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s2">&quot;STRING&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-16">#</a> </div> <p>All of our immediate values. These can (in general), be passed straight
through and printed to JavaScript.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Literal: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;AlphaNumeric&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;JS&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s2">&quot;REGEX&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s2">&quot;TRUE&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="kc">true</span>
<span class="nx">o</span> <span class="s2">&quot;FALSE&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="kc">false</span>
<span class="nx">o</span> <span class="s2">&quot;YES&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="kc">true</span>
<span class="nx">o</span> <span class="s2">&quot;NO&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="kc">false</span>
<span class="nx">o</span> <span class="s2">&quot;ON&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="kc">true</span>
<span class="nx">o</span> <span class="s2">&quot;OFF&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="kc">false</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-17">#</a> </div> <p>Assignment of a variable, property, or index to a value.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Assign: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Assignable ASSIGN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">AssignNode</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-18">#</a> </div> <p>Assignment when it happens within an object literal. The difference from
the ordinary <strong>Assign</strong> is that these allow numbers and strings as keys.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">AssignObj: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Identifier&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s2">&quot;AlphaNumeric&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Identifier ASSIGN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">AssignNode</span> <span class="k">new</span> <span class="nx">ValueNode</span><span class="p">(</span><span class="nx">$1</span><span class="p">),</span> <span class="nx">$3</span><span class="p">,</span> <span class="s1">&#39;object&#39;</span>
<span class="nx">o</span> <span class="s2">&quot;AlphaNumeric ASSIGN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">AssignNode</span> <span class="k">new</span> <span class="nx">ValueNode</span><span class="p">(</span><span class="nx">$1</span><span class="p">),</span> <span class="nx">$3</span><span class="p">,</span> <span class="s1">&#39;object&#39;</span>
<span class="nx">o</span> <span class="s2">&quot;Comment&quot;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-19">#</a> </div> <p>A return statement from a function body.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Return: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;RETURN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ReturnNode</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;RETURN&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ReturnNode</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="s1">&#39;null&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-20">#</a> </div> <p>A block comment.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Comment: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;HERECOMMENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">CommentNode</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-21">#</a> </div> <p><a href="http://jashkenas.github.com/coffee-script/#existence">The existential operator</a>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Existence: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Expression ?&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ExistenceNode</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-22">#</a> </div> <p>The <strong>Code</strong> node is the function literal. It's defined by an indented block
of <strong>Expressions</strong> preceded by a function arrow, with an optional parameter
list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Code: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;PARAM_START ParamList PARAM_END FuncGlyph Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">CodeNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$5</span><span class="p">,</span> <span class="nx">$4</span>
<span class="nx">o</span> <span class="s2">&quot;FuncGlyph Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">CodeNode</span> <span class="p">[],</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-23">#</a> </div> <p>CoffeeScript has two different symbols for functions. <code>-&gt;</code> is for ordinary
functions, and <code>=&gt;</code> is for functions bound to the current value of <em>this</em>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">FuncGlyph: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;-&gt;&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="s1">&#39;func&#39;</span>
<span class="nx">o</span> <span class="s2">&quot;=&gt;&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="s1">&#39;boundfunc&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-24">#</a> </div> <p>An optional, trailing comma.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">OptComma: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s1">&#39;&#39;</span>
<span class="nx">o</span> <span class="s1">&#39;,&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-25">#</a> </div> <p>The list of parameters that a function accepts can be of any length.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ParamList: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">[]</span>
<span class="nx">o</span> <span class="s2">&quot;Param&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="nx">$1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;ParamList , Param&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="p">[</span><span class="nx">$3</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-26">#</a> </div> <p>A single parameter in a function definition can be ordinary, or a splat
that hoovers up the remaining arguments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Param: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;PARAM&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s2">&quot;Param . . .&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">SplatNode</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-27">#</a> </div> <p>A splat that occurs outside of a parameter list.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Splat: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Expression . . .&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">SplatNode</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-28">#</a> </div> <p>Variables and properties that can be assigned to.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">SimpleAssignable: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Identifier&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s2">&quot;Value Accessor&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">push</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;Invocation Accessor&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">$1</span><span class="p">,</span> <span class="p">[</span><span class="nx">$2</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;ThisProperty&quot;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-29">#</a> </div> <p>Everything that can be assigned to.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Assignable: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;SimpleAssignable&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Array&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s2">&quot;Object&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-30">#</a> </div> <p>The types of things that can be treated as values -- assigned to, invoked
as functions, indexed into, named as a class, etc.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Value: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Assignable&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Literal&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s2">&quot;Parenthetical&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s2">&quot;Range&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s2">&quot;This&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;NULL&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="s1">&#39;null&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-31">#</a> </div> <p>The general group of accessors into an object, by property, by prototype
or by array index or slice.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Accessor: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;PROPERTY_ACCESS Identifier&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">AccessorNode</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;PROTOTYPE_ACCESS Identifier&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">AccessorNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="s1">&#39;prototype&#39;</span>
<span class="nx">o</span> <span class="s2">&quot;::&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">AccessorNode</span><span class="p">(</span><span class="k">new</span> <span class="nx">LiteralNode</span><span class="p">(</span><span class="s1">&#39;prototype&#39;</span><span class="p">))</span>
<span class="nx">o</span> <span class="s2">&quot;SOAK_ACCESS Identifier&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">AccessorNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="s1">&#39;soak&#39;</span>
<span class="nx">o</span> <span class="s2">&quot;Index&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Slice&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">SliceNode</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-32">#</a> </div> <p>Indexing into an object or array using bracket notation.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Index: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;INDEX_START Expression INDEX_END&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">IndexNode</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;INDEX_SOAK Index&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nv">$2.soakNode: </span><span class="kc">yes</span><span class="p">;</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;INDEX_PROTO Index&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nv">$2.proto: </span><span class="kc">yes</span><span class="p">;</span> <span class="nx">$2</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-33">#</a> </div> <p>In CoffeeScript, an object literal is simply a list of assignments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nb">Object</span><span class="o">:</span> <span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;{ AssignList OptComma }&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ObjectNode</span> <span class="nx">$2</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-34">#</a> </div> <p>Assignment of properties within an object literal can be separated by
comma, as in JavaScript, or simply by newline.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">AssignList: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">[]</span>
<span class="nx">o</span> <span class="s2">&quot;AssignObj&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="nx">$1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;AssignList , AssignObj&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="p">[</span><span class="nx">$3</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;AssignList OptComma TERMINATOR AssignObj&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="p">[</span><span class="nx">$4</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;AssignList OptComma INDENT AssignList OptComma OUTDENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">$4</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-35">#</a> </div> <p>Class definitions have optional bodies of prototype property assignments,
and optional references to the superclass.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Class: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;CLASS SimpleAssignable&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ClassNode</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;CLASS SimpleAssignable EXTENDS Value&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ClassNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$4</span>
<span class="nx">o</span> <span class="s2">&quot;CLASS SimpleAssignable INDENT ClassBody OUTDENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ClassNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">$4</span>
<span class="nx">o</span> <span class="s2">&quot;CLASS SimpleAssignable EXTENDS Value INDENT ClassBody OUTDENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ClassNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$4</span><span class="p">,</span> <span class="nx">$6</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-36">#</a> </div> <p>Assignments that can happen directly inside a class declaration.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ClassAssign: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;AssignObj&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s2">&quot;ThisProperty ASSIGN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">AssignNode</span> <span class="k">new</span> <span class="nx">ValueNode</span><span class="p">(</span><span class="nx">$1</span><span class="p">),</span> <span class="nx">$3</span><span class="p">,</span> <span class="s1">&#39;this&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-37">#</a> </div> <p>A list of assignments to a class.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ClassBody: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">[]</span>
<span class="nx">o</span> <span class="s2">&quot;ClassAssign&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="nx">$1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;ClassBody TERMINATOR ClassAssign&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">$3</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-38"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-38">#</a> </div> <p>The three flavors of function call: normal, object instantiation with <code>new</code>,
and calling <code>super()</code></p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Call: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Invocation&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Super&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;NEW Invocation&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$2</span><span class="p">.</span><span class="nx">newInstance</span><span class="p">()</span>
<span class="nx">o</span> <span class="s2">&quot;NEW Value&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">(</span><span class="k">new</span> <span class="nx">CallNode</span><span class="p">(</span><span class="nx">$2</span><span class="p">,</span> <span class="p">[])).</span><span class="nx">newInstance</span><span class="p">()</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-39"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-39">#</a> </div> <p>Extending an object by setting its prototype chain to reference a parent
object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Extends: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;SimpleAssignable EXTENDS Value&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ExtendsNode</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-40"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-40">#</a> </div> <p>Ordinary function invocation, or a chained series of calls.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Invocation: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Value Arguments&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">CallNode</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;Invocation Arguments&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">CallNode</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$2</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-41"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-41">#</a> </div> <p>The list of arguments to a function call.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Arguments: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;CALL_START ArgList OptComma CALL_END&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$2</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-42"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-42">#</a> </div> <p>Calling super.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Super: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;SUPER Arguments&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">CallNode</span> <span class="s1">&#39;super&#39;</span><span class="p">,</span> <span class="nx">$2</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-43"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-43">#</a> </div> <p>A reference to the <em>this</em> current object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">This: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;THIS&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="s1">&#39;this&#39;</span>
<span class="nx">o</span> <span class="s2">&quot;@&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="k">new</span> <span class="nx">LiteralNode</span> <span class="s1">&#39;this&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-44">#</a> </div> <p>A reference to a property on <em>this</em>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ThisProperty: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;@ Identifier&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="k">new</span> <span class="nx">LiteralNode</span><span class="p">(</span><span class="s1">&#39;this&#39;</span><span class="p">),</span> <span class="p">[</span><span class="k">new</span> <span class="nx">AccessorNode</span><span class="p">(</span><span class="nx">$2</span><span class="p">)]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-45">#</a> </div> <p>The CoffeeScript range literal.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Range: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;[ Expression . . Expression ]&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">RangeNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$5</span>
<span class="nx">o</span> <span class="s2">&quot;[ Expression . . . Expression ]&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">RangeNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$6</span><span class="p">,</span> <span class="kc">true</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-46">#</a> </div> <p>The slice literal.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Slice: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;INDEX_START Expression . . Expression INDEX_END&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">RangeNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$5</span>
<span class="nx">o</span> <span class="s2">&quot;INDEX_START Expression . . . Expression INDEX_END&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">RangeNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$6</span><span class="p">,</span> <span class="kc">true</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-47"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-47">#</a> </div> <p>The array literal.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nb">Array</span><span class="o">:</span> <span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;[ ArgList OptComma ]&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ArrayNode</span> <span class="nx">$2</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-48"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-48">#</a> </div> <p>The <strong>ArgList</strong> is both the list of objects passed into a function call,
as well as the contents of an array literal
(i.e. comma-separated expressions). Newlines work as well.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ArgList: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">[]</span>
<span class="nx">o</span> <span class="s2">&quot;Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="nx">$1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;ArgList , Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="p">[</span><span class="nx">$3</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;ArgList OptComma TERMINATOR Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="p">[</span><span class="nx">$4</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;ArgList OptComma INDENT ArgList OptComma OUTDENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">$4</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-49">#</a> </div> <p>Just simple, comma-separated, required arguments (no fancy syntax). We need
this to be separate from the <strong>ArgList</strong> for use in <strong>Switch</strong> blocks, where
having the newlines wouldn't make sense.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">SimpleArgs: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Expression&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;SimpleArgs , Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span>
<span class="k">if</span> <span class="nx">$1</span> <span class="k">instanceof</span> <span class="nb">Array</span> <span class="k">then</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">concat</span><span class="p">([</span><span class="nx">$3</span><span class="p">])</span> <span class="k">else</span> <span class="p">[</span><span class="nx">$1</span><span class="p">].</span><span class="nx">concat</span><span class="p">([</span><span class="nx">$3</span><span class="p">])</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-50">#</a> </div> <p>The variants of <em>try/catch/finally</em> exception handling blocks.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Try: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;TRY Block Catch&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">TryNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$3</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nx">$3</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;TRY Block FINALLY Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">TryNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="nx">$4</span>
<span class="nx">o</span> <span class="s2">&quot;TRY Block Catch FINALLY Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">TryNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$3</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nx">$3</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="nx">$5</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-51">#</a> </div> <p>A catch clause names its error and runs a block of code.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Catch: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;CATCH Identifier Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="nx">$2</span><span class="p">,</span> <span class="nx">$3</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-52"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-52">#</a> </div> <p>Throw an exception object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Throw: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;THROW Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ThrowNode</span> <span class="nx">$2</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-53"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-53">#</a> </div> <p>Parenthetical expressions. Note that the <strong>Parenthetical</strong> is a <strong>Value</strong>,
not an <strong>Expression</strong>, so if you need to use an expression in a place
where only values are accepted, wrapping it in parentheses will always do
the trick.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Parenthetical: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;( Line )&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ParentheticalNode</span> <span class="nx">$2</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-54"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-54">#</a> </div> <p>The condition portion of a while loop.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">WhileSource: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;WHILE Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">WhileNode</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;WHILE Expression WHEN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">WhileNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="p">{</span><span class="nv">guard : </span><span class="nx">$4</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;UNTIL Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">WhileNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="p">{</span><span class="nv">invert: </span><span class="kc">true</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;UNTIL Expression WHEN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">WhileNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="p">{</span><span class="nv">invert: </span><span class="kc">true</span><span class="p">,</span> <span class="nv">guard: </span><span class="nx">$4</span><span class="p">}</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-55">#</a> </div> <p>The while loop can either be normal, with a block of expressions to execute,
or postfix, with a single expression. There is no do..while.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">While: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;WhileSource Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">addBody</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;Statement WhileSource&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$2</span><span class="p">.</span><span class="nx">addBody</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">$1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;Expression WhileSource&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$2</span><span class="p">.</span><span class="nx">addBody</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">$1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;Loop&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span>
<span class="p">]</span>
<span class="nv">Loop: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;LOOP Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">WhileNode</span><span class="p">(</span><span class="k">new</span> <span class="nx">LiteralNode</span> <span class="s1">&#39;true&#39;</span><span class="p">).</span><span class="nx">addBody</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;LOOP Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">WhileNode</span><span class="p">(</span><span class="k">new</span> <span class="nx">LiteralNode</span> <span class="s1">&#39;true&#39;</span><span class="p">).</span><span class="nx">addBody</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span> <span class="p">[</span><span class="nx">$2</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-56"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-56">#</a> </div> <p>Array, object, and range comprehensions, at the most generic level.
Comprehensions can either be normal, with a block of expressions to execute,
or postfix, with a single expression.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">For: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Statement FOR ForVariables ForSource&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ForNode</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$4</span><span class="p">,</span> <span class="nx">$3</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nx">$3</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;Expression FOR ForVariables ForSource&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ForNode</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$4</span><span class="p">,</span> <span class="nx">$3</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nx">$3</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;FOR ForVariables ForSource Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ForNode</span> <span class="nx">$4</span><span class="p">,</span> <span class="nx">$3</span><span class="p">,</span> <span class="nx">$2</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="nx">$2</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-57"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-57">#</a> </div> <p>An array of all accepted values for a variable inside the loop. This
enables support for pattern matching.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ForValue: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;Identifier&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Array&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">$1</span>
<span class="nx">o</span> <span class="s2">&quot;Object&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">ValueNode</span> <span class="nx">$1</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-58"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-58">#</a> </div> <p>An array or range comprehension has variables for the current element and
(optional) reference to the current index. Or, <em>key, value</em>, in the case
of object comprehensions.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ForVariables: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;ForValue&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="nx">$1</span><span class="p">]</span>
<span class="nx">o</span> <span class="s2">&quot;ForValue , ForValue&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-59"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-59">#</a> </div> <p>The source of a comprehension is an array or object with an optional guard
clause. If it's an array comprehension, you can also choose to step through
in fixed-size increments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ForSource: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;IN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">{</span><span class="nv">source: </span><span class="nx">$2</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;OF Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">{</span><span class="nv">source: </span><span class="nx">$2</span><span class="p">,</span> <span class="nv">object: </span><span class="kc">true</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;IN Expression WHEN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">{</span><span class="nv">source: </span><span class="nx">$2</span><span class="p">,</span> <span class="nv">guard: </span><span class="nx">$4</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;OF Expression WHEN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">{</span><span class="nv">source: </span><span class="nx">$2</span><span class="p">,</span> <span class="nv">guard: </span><span class="nx">$4</span><span class="p">,</span> <span class="nv">object: </span><span class="kc">true</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;IN Expression BY Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">{</span><span class="nv">source: </span><span class="nx">$2</span><span class="p">,</span> <span class="nv">step: </span> <span class="nx">$4</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;IN Expression WHEN Expression BY Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">{</span><span class="nv">source: </span><span class="nx">$2</span><span class="p">,</span> <span class="nv">guard: </span><span class="nx">$4</span><span class="p">,</span> <span class="nv">step: </span> <span class="nx">$6</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;IN Expression BY Expression WHEN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="p">{</span><span class="nv">source: </span><span class="nx">$2</span><span class="p">,</span> <span class="nv">step: </span> <span class="nx">$4</span><span class="p">,</span> <span class="nv">guard: </span><span class="nx">$6</span><span class="p">}</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-60"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-60">#</a> </div> <p>The CoffeeScript switch/when/else block replaces the JavaScript
switch/case/default by compiling into an if-else chain.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Switch: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;SWITCH Expression INDENT Whens OUTDENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$4</span><span class="p">.</span><span class="nx">switchesOver</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;SWITCH Expression INDENT Whens ELSE Block OUTDENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$4</span><span class="p">.</span><span class="nx">switchesOver</span><span class="p">(</span><span class="nx">$2</span><span class="p">).</span><span class="nx">addElse</span> <span class="nx">$6</span><span class="p">,</span> <span class="kc">true</span>
<span class="nx">o</span> <span class="s2">&quot;SWITCH INDENT Whens OUTDENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;SWITCH INDENT Whens ELSE Block OUTDENT&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$3</span><span class="p">.</span><span class="nx">addElse</span> <span class="nx">$5</span><span class="p">,</span> <span class="kc">true</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-61"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-61">#</a> </div> <p>The inner list of whens is left recursive. At code-generation time, the
IfNode will rewrite them into a proper chain.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Whens: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;When&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Whens When&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">addElse</span> <span class="nx">$2</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-62"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-62">#</a> </div> <p>An individual <strong>When</strong> clause, with action.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">When: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;LEADING_WHEN SimpleArgs Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">IfNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$3</span><span class="p">,</span> <span class="p">{</span><span class="nv">statement: </span><span class="kc">true</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;LEADING_WHEN SimpleArgs Block TERMINATOR&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">IfNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$3</span><span class="p">,</span> <span class="p">{</span><span class="nv">statement: </span><span class="kc">true</span><span class="p">}</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-63"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-63">#</a> </div> <p>The most basic form of <em>if</em> is a condition and an action. The following
if-related rules are broken up along these lines in order to avoid
ambiguity.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">IfBlock: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;IF Expression Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">IfNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;UNLESS Expression Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">IfNode</span> <span class="nx">$2</span><span class="p">,</span> <span class="nx">$3</span><span class="p">,</span> <span class="p">{</span><span class="nv">invert: </span><span class="kc">true</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;IfBlock ELSE IF Expression Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">addElse</span> <span class="p">(</span><span class="k">new</span> <span class="nx">IfNode</span><span class="p">(</span><span class="nx">$4</span><span class="p">,</span> <span class="nx">$5</span><span class="p">)).</span><span class="nx">forceStatement</span><span class="p">()</span>
<span class="nx">o</span> <span class="s2">&quot;IfBlock ELSE Block&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">$1</span><span class="p">.</span><span class="nx">addElse</span> <span class="nx">$3</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-64"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-64">#</a> </div> <p>The full complement of <em>if</em> expressions, including postfix one-liner
<em>if</em> and <em>unless</em>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">If: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;IfBlock&quot;</span>
<span class="nx">o</span> <span class="s2">&quot;Statement IF Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">IfNode</span> <span class="nx">$3</span><span class="p">,</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="nx">$1</span><span class="p">]),</span> <span class="p">{</span><span class="nv">statement: </span><span class="kc">true</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;Expression IF Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">IfNode</span> <span class="nx">$3</span><span class="p">,</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="nx">$1</span><span class="p">]),</span> <span class="p">{</span><span class="nv">statement: </span><span class="kc">true</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;Statement UNLESS Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">IfNode</span> <span class="nx">$3</span><span class="p">,</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="nx">$1</span><span class="p">]),</span> <span class="p">{</span><span class="nv">statement: </span><span class="kc">true</span><span class="p">,</span> <span class="nv">invert: </span><span class="kc">true</span><span class="p">}</span>
<span class="nx">o</span> <span class="s2">&quot;Expression UNLESS Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">IfNode</span> <span class="nx">$3</span><span class="p">,</span> <span class="nx">Expressions</span><span class="p">.</span><span class="nx">wrap</span><span class="p">([</span><span class="nx">$1</span><span class="p">]),</span> <span class="p">{</span><span class="nv">statement: </span><span class="kc">true</span><span class="p">,</span> <span class="nv">invert: </span><span class="kc">true</span><span class="p">}</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-65"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-65">#</a> </div> <p>Arithmetic and logical operators, working on one or more operands.
Here they are grouped by order of precedence. The actual precedence rules
are defined at the bottom of the page. It would be shorter if we could
combine most of these rules into a single generic <em>Operand OpSymbol Operand</em>
-type rule, but in order to make the precedence binding possible, separate
rules are necessary.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">Operation: </span><span class="p">[</span>
<span class="nx">o</span> <span class="s2">&quot;! Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;!&#39;</span><span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;!! Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;!!&#39;</span><span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span><span class="p">(</span><span class="s2">&quot;- Expression&quot;</span><span class="p">,</span> <span class="p">(</span><span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span><span class="p">(</span><span class="s1">&#39;-&#39;</span><span class="p">,</span> <span class="nx">$2</span><span class="p">)),</span> <span class="p">{</span><span class="nv">prec: </span><span class="s1">&#39;UMINUS&#39;</span><span class="p">})</span>
<span class="nx">o</span><span class="p">(</span><span class="s2">&quot;+ Expression&quot;</span><span class="p">,</span> <span class="p">(</span><span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span><span class="p">(</span><span class="s1">&#39;+&#39;</span><span class="p">,</span> <span class="nx">$2</span><span class="p">)),</span> <span class="p">{</span><span class="nv">prec: </span><span class="s1">&#39;UPLUS&#39;</span><span class="p">})</span>
<span class="nx">o</span> <span class="s2">&quot;~ Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;~&#39;</span><span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;-- Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;--&#39;</span><span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;++ Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;++&#39;</span><span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;DELETE Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;delete&#39;</span><span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;TYPEOF Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;typeof&#39;</span><span class="p">,</span> <span class="nx">$2</span>
<span class="nx">o</span> <span class="s2">&quot;Expression --&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;--&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="kc">true</span>
<span class="nx">o</span> <span class="s2">&quot;Expression ++&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;++&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="kc">true</span>
<span class="nx">o</span> <span class="s2">&quot;Expression * Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;*&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression / Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression % Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;%&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression + Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;+&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression - Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;-&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression &lt;&lt; Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;&lt;&lt;&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression &gt;&gt; Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;&gt;&gt;&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression &gt;&gt;&gt; Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;&gt;&gt;&gt;&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression &amp; Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;&amp;&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression | Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;|&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression ^ Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;^&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression &lt;= Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;&lt;=&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression &lt; Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;&lt;&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression &gt; Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;&gt;&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression &gt;= Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;&gt;=&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression == Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;==&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression != Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;!=&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression &amp;&amp; Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;&amp;&amp;&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression || Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;||&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression OP? Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;?&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression -= Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;-=&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression += Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;+=&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression /= Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;/=&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression *= Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;*=&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression %= Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;%=&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression ||= Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;||=&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression &amp;&amp;= Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;&amp;&amp;=&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression ?= Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;?=&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression INSTANCEOF Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;instanceof&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression IN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">InNode</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression OF Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;in&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$3</span>
<span class="nx">o</span> <span class="s2">&quot;Expression ! IN Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;!&#39;</span><span class="p">,</span> <span class="k">new</span> <span class="nx">InNode</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$4</span>
<span class="nx">o</span> <span class="s2">&quot;Expression ! OF Expression&quot;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;!&#39;</span><span class="p">,</span> <span class="k">new</span> <span class="nx">ParentheticalNode</span> <span class="k">new</span> <span class="nx">OpNode</span> <span class="s1">&#39;in&#39;</span><span class="p">,</span> <span class="nx">$1</span><span class="p">,</span> <span class="nx">$4</span>
<span class="p">]</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-66"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-66">#</a> </div> <h2>Precedence</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-67"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-67">#</a> </div> <p>Operators at the top of this list have higher precedence than the ones lower
down. Following these rules is what makes <code>2 + 3 * 4</code> parse as:</p>
<pre><code>2 + (3 * 4)
</code></pre>
<p>And not:</p>
<pre><code>(2 + 3) * 4
</code></pre> </td> <td class="code"> <div class="highlight"><pre><span class="nv">operators: </span><span class="p">[</span>
<span class="p">[</span><span class="s2">&quot;left&quot;</span><span class="p">,</span> <span class="s1">&#39;?&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;nonassoc&quot;</span><span class="p">,</span> <span class="s1">&#39;UMINUS&#39;</span><span class="p">,</span> <span class="s1">&#39;UPLUS&#39;</span><span class="p">,</span> <span class="s1">&#39;!&#39;</span><span class="p">,</span> <span class="s1">&#39;!!&#39;</span><span class="p">,</span> <span class="s1">&#39;~&#39;</span><span class="p">,</span> <span class="s1">&#39;++&#39;</span><span class="p">,</span> <span class="s1">&#39;--&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;left&quot;</span><span class="p">,</span> <span class="s1">&#39;*&#39;</span><span class="p">,</span> <span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="s1">&#39;%&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;left&quot;</span><span class="p">,</span> <span class="s1">&#39;+&#39;</span><span class="p">,</span> <span class="s1">&#39;-&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;left&quot;</span><span class="p">,</span> <span class="s1">&#39;&lt;&lt;&#39;</span><span class="p">,</span> <span class="s1">&#39;&gt;&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;&gt;&gt;&gt;&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;left&quot;</span><span class="p">,</span> <span class="s1">&#39;&amp;&#39;</span><span class="p">,</span> <span class="s1">&#39;|&#39;</span><span class="p">,</span> <span class="s1">&#39;^&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;left&quot;</span><span class="p">,</span> <span class="s1">&#39;&lt;=&#39;</span><span class="p">,</span> <span class="s1">&#39;&lt;&#39;</span><span class="p">,</span> <span class="s1">&#39;&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;&gt;=&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;right&quot;</span><span class="p">,</span> <span class="s1">&#39;DELETE&#39;</span><span class="p">,</span> <span class="s1">&#39;INSTANCEOF&#39;</span><span class="p">,</span> <span class="s1">&#39;TYPEOF&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;left&quot;</span><span class="p">,</span> <span class="s1">&#39;==&#39;</span><span class="p">,</span> <span class="s1">&#39;!=&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;left&quot;</span><span class="p">,</span> <span class="s1">&#39;&amp;&amp;&#39;</span><span class="p">,</span> <span class="s1">&#39;||&#39;</span><span class="p">,</span> <span class="s1">&#39;OP?&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;right&quot;</span><span class="p">,</span> <span class="s1">&#39;-=&#39;</span><span class="p">,</span> <span class="s1">&#39;+=&#39;</span><span class="p">,</span> <span class="s1">&#39;/=&#39;</span><span class="p">,</span> <span class="s1">&#39;*=&#39;</span><span class="p">,</span> <span class="s1">&#39;%=&#39;</span><span class="p">,</span> <span class="s1">&#39;||=&#39;</span><span class="p">,</span> <span class="s1">&#39;&amp;&amp;=&#39;</span><span class="p">,</span> <span class="s1">&#39;?=&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;left&quot;</span><span class="p">,</span> <span class="s1">&#39;.&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;right&quot;</span><span class="p">,</span> <span class="s1">&#39;INDENT&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;left&quot;</span><span class="p">,</span> <span class="s1">&#39;OUTDENT&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;right&quot;</span><span class="p">,</span> <span class="s1">&#39;WHEN&#39;</span><span class="p">,</span> <span class="s1">&#39;LEADING_WHEN&#39;</span><span class="p">,</span> <span class="s1">&#39;IN&#39;</span><span class="p">,</span> <span class="s1">&#39;OF&#39;</span><span class="p">,</span> <span class="s1">&#39;BY&#39;</span><span class="p">,</span> <span class="s1">&#39;THROW&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;right&quot;</span><span class="p">,</span> <span class="s1">&#39;FOR&#39;</span><span class="p">,</span> <span class="s1">&#39;WHILE&#39;</span><span class="p">,</span> <span class="s1">&#39;UNTIL&#39;</span><span class="p">,</span> <span class="s1">&#39;LOOP&#39;</span><span class="p">,</span> <span class="s1">&#39;NEW&#39;</span><span class="p">,</span> <span class="s1">&#39;SUPER&#39;</span><span class="p">,</span> <span class="s1">&#39;CLASS&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;left&quot;</span><span class="p">,</span> <span class="s1">&#39;EXTENDS&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;right&quot;</span><span class="p">,</span> <span class="s1">&#39;ASSIGN&#39;</span><span class="p">,</span> <span class="s1">&#39;RETURN&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s2">&quot;right&quot;</span><span class="p">,</span> <span class="s1">&#39;-&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;=&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;UNLESS&#39;</span><span class="p">,</span> <span class="s1">&#39;IF&#39;</span><span class="p">,</span> <span class="s1">&#39;ELSE&#39;</span><span class="p">]</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-68"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-68">#</a> </div> <h2>Wrapping Up</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-69"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-69">#</a> </div> <p>Finally, now what we have our <strong>grammar</strong> and our <strong>operators</strong>, we can create
our <strong>Jison.Parser</strong>. We do this by processing all of our rules, recording all
terminals (every symbol which does not appear as the name of a rule above)
as "tokens".</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">tokens: </span><span class="p">[]</span>
<span class="k">for</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">alternatives</span> <span class="k">of</span> <span class="nx">grammar</span>
<span class="nx">grammar</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span><span class="o">:</span> <span class="k">for</span> <span class="nx">alt</span> <span class="k">in</span> <span class="nx">alternatives</span>
<span class="k">for</span> <span class="nx">token</span> <span class="k">in</span> <span class="nx">alt</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">split</span> <span class="s1">&#39; &#39;</span>
<span class="nx">tokens</span><span class="p">.</span><span class="nx">push</span> <span class="nx">token</span> <span class="nx">unless</span> <span class="nx">grammar</span><span class="p">[</span><span class="nx">token</span><span class="p">]</span>
<span class="nx">alt</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;return ${alt[1]}&quot;</span> <span class="k">if</span> <span class="nx">name</span> <span class="o">is</span> <span class="s1">&#39;Root&#39;</span>
<span class="nx">alt</span></pre></div> </td> </tr> <tr id="section-70"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-70">#</a> </div> <p>Initialize the <strong>Parser</strong> with our list of terminal <strong>tokens</strong>, our <strong>grammar</strong>
rules, and the name of the root. Reverse the operators because Jison orders
precedence from low to high, and we have it high to low
(as in <a href="http://dinosaur.compilertools.net/yacc/index.html">Yacc</a>).</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.parser: </span><span class="k">new</span> <span class="nx">Parser</span> <span class="p">{</span>
<span class="nv">tokens: </span> <span class="nx">tokens</span><span class="p">.</span><span class="nx">join</span> <span class="s1">&#39; &#39;</span>
<span class="nv">bnf: </span> <span class="nx">grammar</span>
<span class="nv">operators: </span> <span class="nx">operators</span><span class="p">.</span><span class="nx">reverse</span><span class="p">()</span>
<span class="nv">startSymbol: </span> <span class="s1">&#39;Root&#39;</span>
<span class="p">}</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -0,0 +1,36 @@
<!DOCTYPE html> <html> <head> <title>helpers.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="cake.html"> cake.coffee </a> <a class="source" href="coffee-script.html"> coffee-script.coffee </a> <a class="source" href="command.html"> command.coffee </a> <a class="source" href="grammar.html"> grammar.coffee </a> <a class="source" href="helpers.html"> helpers.coffee </a> <a class="source" href="index.html"> index.coffee </a> <a class="source" href="lexer.html"> lexer.coffee </a> <a class="source" href="nodes.html"> nodes.coffee </a> <a class="source" href="optparse.html"> optparse.coffee </a> <a class="source" href="repl.html"> repl.coffee </a> <a class="source" href="rewriter.html"> rewriter.coffee </a> <a class="source" href="scope.html"> scope.coffee </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> helpers.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-1">#</a> </div> <p>This file contains the common helper functions that we'd like to share among
the <strong>Lexer</strong>, <strong>Rewriter</strong>, and the <strong>Nodes</strong>. Merge objects, flatten
arrays, count characters, that sort of thing.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>Set up exported variables for both <strong>Node.js</strong> and the browser.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">this</span><span class="p">.</span><span class="nv">exports: </span><span class="k">this</span> <span class="nx">unless</span> <span class="nx">process</span><span class="o">?</span>
<span class="nv">helpers: exports.helpers: </span><span class="p">{}</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <p>Cross-browser indexOf, so that IE can join the party.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.indexOf: indexOf: </span><span class="p">(</span><span class="nx">array</span><span class="p">,</span> <span class="nx">item</span><span class="p">,</span> <span class="nx">from</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="nx">array</span><span class="p">.</span><span class="nx">indexOf</span> <span class="nx">item</span><span class="p">,</span> <span class="nx">from</span> <span class="k">if</span> <span class="nx">array</span><span class="p">.</span><span class="nx">indexOf</span>
<span class="k">for</span> <span class="nx">other</span><span class="p">,</span> <span class="nx">index</span> <span class="k">in</span> <span class="nx">array</span>
<span class="k">if</span> <span class="nx">other</span> <span class="o">is</span> <span class="nx">item</span> <span class="o">and</span> <span class="p">(</span><span class="o">not</span> <span class="nx">from</span> <span class="o">or</span> <span class="p">(</span><span class="nx">from</span> <span class="o">&lt;=</span> <span class="nx">index</span><span class="p">))</span>
<span class="k">return</span> <span class="nx">index</span>
<span class="o">-</span><span class="mi">1</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>Does a list include a value?</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.include: include: </span><span class="p">(</span><span class="nx">list</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">indexOf</span><span class="p">(</span><span class="nx">list</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>Peek at the beginning of a given string to see if it matches a sequence.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.starts: starts: </span><span class="p">(</span><span class="nx">string</span><span class="p">,</span> <span class="nx">literal</span><span class="p">,</span> <span class="nx">start</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">string</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="nx">start</span><span class="p">,</span> <span class="p">(</span><span class="nx">start</span> <span class="o">or</span> <span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="nx">literal</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="o">is</span> <span class="nx">literal</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>Trim out all falsy values from an array.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.compact: compact: </span><span class="p">(</span><span class="nx">array</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">item</span> <span class="k">for</span> <span class="nx">item</span> <span class="k">in</span> <span class="nx">array</span> <span class="k">when</span> <span class="nx">item</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>Count the number of occurences of a character in a string.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.count: count: </span><span class="p">(</span><span class="nx">string</span><span class="p">,</span> <span class="nx">letter</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">num: </span><span class="mi">0</span>
<span class="nv">pos: </span><span class="nx">indexOf</span> <span class="nx">string</span><span class="p">,</span> <span class="nx">letter</span>
<span class="k">while</span> <span class="nx">pos</span> <span class="o">isnt</span> <span class="o">-</span><span class="mi">1</span>
<span class="nv">num: </span><span class="o">+</span> <span class="mi">1</span>
<span class="nv">pos: </span><span class="nx">indexOf</span> <span class="nx">string</span><span class="p">,</span> <span class="nx">letter</span><span class="p">,</span> <span class="nx">pos</span> <span class="o">+</span> <span class="mi">1</span>
<span class="nx">num</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</a> </div> <p>Merge objects, returning a fresh copy with attributes from both sides.
Used every time <code>BaseNode#compile</code> is called, to allow properties in the
options hash to propagate down the tree without polluting other branches.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.merge: merge: </span><span class="p">(</span><span class="nx">options</span><span class="p">,</span> <span class="nx">overrides</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">fresh: </span><span class="p">{}</span>
<span class="p">(</span><span class="nx">fresh</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span><span class="o">:</span> <span class="nx">val</span><span class="p">)</span> <span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="k">of</span> <span class="nx">options</span>
<span class="p">(</span><span class="nx">fresh</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span><span class="o">:</span> <span class="nx">val</span><span class="p">)</span> <span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="k">of</span> <span class="nx">overrides</span> <span class="k">if</span> <span class="nx">overrides</span>
<span class="nx">fresh</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>Extend a source object with the properties of another object (shallow copy).
We use this to simulate Node's deprecated <code>process.mixin</code></p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.extend: extend: </span><span class="p">(</span><span class="nx">object</span><span class="p">,</span> <span class="nx">properties</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="p">(</span><span class="nx">object</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span><span class="o">:</span> <span class="nx">val</span><span class="p">)</span> <span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="k">of</span> <span class="nx">properties</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</a> </div> <p>Return a completely flattened version of an array. Handy for getting a
list of <code>children</code> from the nodes.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.flatten: flatten: </span><span class="p">(</span><span class="nx">array</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">memo: </span><span class="p">[]</span>
<span class="k">for</span> <span class="nx">item</span> <span class="k">in</span> <span class="nx">array</span>
<span class="k">if</span> <span class="nx">item</span> <span class="k">instanceof</span> <span class="nb">Array</span> <span class="k">then</span> <span class="nv">memo: </span><span class="nx">memo</span><span class="p">.</span><span class="nx">concat</span><span class="p">(</span><span class="nx">item</span><span class="p">)</span> <span class="k">else</span> <span class="nx">memo</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">item</span><span class="p">)</span>
<span class="nx">memo</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-11">#</a> </div> <p>Delete a key from an object, returning the value. Useful when a node is
looking for a particular method in an options hash.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">helpers.del: del: </span><span class="p">(</span><span class="nx">obj</span><span class="p">,</span> <span class="nx">key</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">val: </span><span class="nx">obj</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span>
<span class="k">delete</span> <span class="nx">obj</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span>
<span class="nx">val</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -0,0 +1,3 @@
<!DOCTYPE html> <html> <head> <title>index.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="cake.html"> cake.coffee </a> <a class="source" href="coffee-script.html"> coffee-script.coffee </a> <a class="source" href="command.html"> command.coffee </a> <a class="source" href="grammar.html"> grammar.coffee </a> <a class="source" href="helpers.html"> helpers.coffee </a> <a class="source" href="index.html"> index.coffee </a> <a class="source" href="lexer.html"> lexer.coffee </a> <a class="source" href="nodes.html"> nodes.coffee </a> <a class="source" href="optparse.html"> optparse.coffee </a> <a class="source" href="repl.html"> repl.coffee </a> <a class="source" href="rewriter.html"> rewriter.coffee </a> <a class="source" href="scope.html"> scope.coffee </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> index.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-1">#</a> </div> <p>Loader for CoffeeScript as a Node.js library.</p> </td> <td class="code"> <div class="highlight"><pre><span class="p">(</span><span class="nx">exports</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span><span class="o">:</span> <span class="nx">val</span><span class="p">)</span> <span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="k">of</span> <span class="nx">require</span> <span class="s1">&#39;./coffee-script&#39;</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -0,0 +1,422 @@
<!DOCTYPE html> <html> <head> <title>lexer.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="cake.html"> cake.coffee </a> <a class="source" href="coffee-script.html"> coffee-script.coffee </a> <a class="source" href="command.html"> command.coffee </a> <a class="source" href="grammar.html"> grammar.coffee </a> <a class="source" href="helpers.html"> helpers.coffee </a> <a class="source" href="index.html"> index.coffee </a> <a class="source" href="lexer.html"> lexer.coffee </a> <a class="source" href="nodes.html"> nodes.coffee </a> <a class="source" href="optparse.html"> optparse.coffee </a> <a class="source" href="repl.html"> repl.coffee </a> <a class="source" href="rewriter.html"> rewriter.coffee </a> <a class="source" href="scope.html"> scope.coffee </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> lexer.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-1">#</a> </div> <p>The CoffeeScript Lexer. Uses a series of token-matching regexes to attempt
matches against the beginning of the source code. When a match is found,
a token is produced, we consume the match, and start again. Tokens are in the
form:</p>
<pre><code>[tag, value, lineNumber]
</code></pre>
<p>Which is a format that can be fed directly into <a href="http://github.com/zaach/jison">Jison</a>.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>Set up the Lexer for both Node.js and the browser, depending on where we are.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">if</span> <span class="nx">process</span><span class="o">?</span>
<span class="p">{</span><span class="nx">Rewriter</span><span class="p">}</span><span class="o">:</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./rewriter&#39;</span><span class="p">)</span>
<span class="p">{</span><span class="nx">helpers</span><span class="p">}</span><span class="o">:</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./helpers&#39;</span><span class="p">)</span>
<span class="k">else</span>
<span class="k">this</span><span class="p">.</span><span class="nv">exports: </span><span class="k">this</span>
<span class="nv">Rewriter: </span> <span class="k">this</span><span class="p">.</span><span class="nx">Rewriter</span>
<span class="nv">helpers: </span> <span class="k">this</span><span class="p">.</span><span class="nx">helpers</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <p>Import the helpers we need.</p> </td> <td class="code"> <div class="highlight"><pre><span class="p">{</span><span class="nx">include</span><span class="p">,</span> <span class="nx">count</span><span class="p">,</span> <span class="nx">starts</span><span class="p">,</span> <span class="nx">compact</span><span class="p">}</span><span class="o">:</span> <span class="nx">helpers</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <h2>The Lexer Class</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>The Lexer class reads a stream of CoffeeScript and divvys it up into tagged
tokens. Some potential ambiguity in the grammar has been avoided by
pushing some extra smarts into the Lexer.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Lexer: </span><span class="nx">class</span> <span class="nx">Lexer</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p><strong>tokenize</strong> is the Lexer's main method. Scan by attempting to match tokens
one at a time, using a regular expression anchored at the start of the
remaining code, or a custom recursive token-matching method
(for interpolations). When the next token has been recorded, we move forward
within the code past the token, and begin again.</p>
<p>Each tokenizing method is responsible for incrementing <code>@i</code> by the number of
characters it has consumed. <code>@i</code> can be thought of as our finger on the page
of source.</p>
<p>Before returning the token stream, run it through the <a href="rewriter.html">Rewriter</a>
unless explicitly asked not to.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">tokenize: </span><span class="p">(</span><span class="nx">code</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">code : </span><span class="nx">code</span><span class="p">.</span><span class="nx">replace</span> <span class="sr">/(\r|\s+$)/g</span><span class="p">,</span> <span class="s1">&#39;&#39;</span>
<span class="nv">o : </span><span class="nx">options</span> <span class="o">or</span> <span class="p">{}</span>
<span class="vi">@code : </span><span class="nx">code</span> <span class="c1"># The remainder of the source code.</span>
<span class="vi">@i : </span><span class="mi">0</span> <span class="c1"># Current character position we&#39;re parsing.</span>
<span class="vi">@line : </span><span class="nx">o</span><span class="p">.</span><span class="nx">line</span> <span class="o">or</span> <span class="mi">0</span> <span class="c1"># The current line.</span>
<span class="vi">@indent : </span><span class="mi">0</span> <span class="c1"># The current indentation level.</span>
<span class="vi">@outdebt : </span><span class="mi">0</span> <span class="c1"># The under-outdentation of the last outdent.</span>
<span class="vi">@indents : </span><span class="p">[]</span> <span class="c1"># The stack of all current indentation levels.</span>
<span class="vi">@tokens : </span><span class="p">[]</span> <span class="c1"># Stream of parsed tokens in the form [&#39;TYPE&#39;, value, line]</span>
<span class="k">while</span> <span class="nx">@i</span> <span class="o">&lt;</span> <span class="nx">@code</span><span class="p">.</span><span class="nx">length</span>
<span class="vi">@chunk: </span><span class="nx">@code</span><span class="p">.</span><span class="nx">slice</span> <span class="nx">@i</span>
<span class="nx">@extractNextToken</span><span class="p">()</span>
<span class="nx">@closeIndentation</span><span class="p">()</span>
<span class="k">return</span> <span class="nx">@tokens</span> <span class="k">if</span> <span class="nx">o</span><span class="p">.</span><span class="nx">rewrite</span> <span class="o">is</span> <span class="kc">off</span>
<span class="p">(</span><span class="k">new</span> <span class="nx">Rewriter</span><span class="p">).</span><span class="nx">rewrite</span> <span class="nx">@tokens</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>At every position, run through this list of attempted matches,
short-circuiting if any of them succeed. Their order determines precedence:
<code>@literalToken</code> is the fallback catch-all.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">extractNextToken: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">@identifierToken</span><span class="p">()</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">@commentToken</span><span class="p">()</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">@whitespaceToken</span><span class="p">()</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">@lineToken</span><span class="p">()</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">@heredocToken</span><span class="p">()</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">@stringToken</span><span class="p">()</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">@numberToken</span><span class="p">()</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">@regexToken</span><span class="p">()</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">@jsToken</span><span class="p">()</span>
<span class="k">return</span> <span class="nx">@literalToken</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</a> </div> <h2>Tokenizers</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>Matches identifying literals: variables, keywords, method names, etc.
Check to ensure that JavaScript reserved words aren't being used as
identifiers. Because CoffeeScript reserves a handful of keywords that are
allowed in JavaScript, we're careful not to tag them as keywords when
referenced as property names here, so you can still do <code>jQuery.is()</code> even
though <code>is</code> means <code>===</code> otherwise.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">identifierToken: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nv">id: </span><span class="nx">@match</span> <span class="nx">IDENTIFIER</span><span class="p">,</span> <span class="mi">1</span>
<span class="vi">@i: </span><span class="o">+</span> <span class="nx">id</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">forcedIdentifier: </span><span class="nx">@tagAccessor</span><span class="p">()</span> <span class="o">or</span> <span class="nx">@match</span> <span class="nx">ASSIGNED</span><span class="p">,</span> <span class="mi">1</span>
<span class="nv">tag: </span><span class="s1">&#39;IDENTIFIER&#39;</span>
<span class="nv">tag: </span><span class="nx">id</span><span class="p">.</span><span class="nx">toUpperCase</span><span class="p">()</span> <span class="k">if</span> <span class="nx">include</span><span class="p">(</span><span class="nx">JS_KEYWORDS</span><span class="p">,</span> <span class="nx">id</span><span class="p">)</span> <span class="o">or</span> <span class="p">(</span><span class="o">not</span> <span class="nx">forcedIdentifier</span> <span class="o">and</span> <span class="nx">include</span><span class="p">(</span><span class="nx">COFFEE_KEYWORDS</span><span class="p">,</span> <span class="nx">id</span><span class="p">))</span>
<span class="nv">tag: </span><span class="s1">&#39;LEADING_WHEN&#39;</span> <span class="k">if</span> <span class="nx">tag</span> <span class="o">is</span> <span class="s1">&#39;WHEN&#39;</span> <span class="o">and</span> <span class="nx">include</span> <span class="nx">LINE_BREAK</span><span class="p">,</span> <span class="nx">@tag</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">include</span><span class="p">(</span><span class="nx">JS_FORBIDDEN</span><span class="p">,</span> <span class="nx">id</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">forcedIdentifier</span>
<span class="nv">tag: </span><span class="s1">&#39;STRING&#39;</span>
<span class="nv">id: </span> <span class="s2">&quot;&#39;$id&#39;&quot;</span>
<span class="k">if</span> <span class="nx">forcedIdentifier</span> <span class="o">is</span> <span class="s1">&#39;accessor&#39;</span>
<span class="nv">close_index: </span><span class="kc">true</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span> <span class="k">if</span> <span class="nx">@tag</span><span class="p">()</span> <span class="o">isnt</span> <span class="s1">&#39;@&#39;</span>
<span class="nx">@token</span> <span class="s1">&#39;INDEX_START&#39;</span><span class="p">,</span> <span class="s1">&#39;[&#39;</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">include</span><span class="p">(</span><span class="nx">RESERVED</span><span class="p">,</span> <span class="nx">id</span><span class="p">)</span>
<span class="nx">@identifierError</span> <span class="nx">id</span>
<span class="nx">unless</span> <span class="nx">forcedIdentifier</span>
<span class="nv">tag: id: </span><span class="nx">CONVERSIONS</span><span class="p">[</span><span class="nx">id</span><span class="p">]</span> <span class="k">if</span> <span class="nx">include</span> <span class="nx">COFFEE_ALIASES</span><span class="p">,</span> <span class="nx">id</span>
<span class="k">return</span> <span class="nx">@tagHalfAssignment</span> <span class="nx">tag</span> <span class="k">if</span> <span class="nx">@prev</span><span class="p">()</span> <span class="o">and</span> <span class="nx">@prev</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;ASSIGN&#39;</span> <span class="o">and</span> <span class="nx">include</span> <span class="nx">HALF_ASSIGNMENTS</span><span class="p">,</span> <span class="nx">tag</span>
<span class="nx">@token</span> <span class="nx">tag</span><span class="p">,</span> <span class="nx">id</span>
<span class="nx">@token</span> <span class="s1">&#39;]&#39;</span><span class="p">,</span> <span class="s1">&#39;]&#39;</span> <span class="k">if</span> <span class="nx">close_index</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</a> </div> <p>Matches numbers, including decimals, hex, and exponential notation.
Be careful not to interfere with ranges-in-progress.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">numberToken: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nv">number: </span><span class="nx">@match</span> <span class="nx">NUMBER</span><span class="p">,</span> <span class="mi">1</span>
<span class="k">return</span> <span class="kc">false</span> <span class="k">if</span> <span class="nx">@tag</span><span class="p">()</span> <span class="o">is</span> <span class="s1">&#39;.&#39;</span> <span class="o">and</span> <span class="nx">starts</span> <span class="nx">number</span><span class="p">,</span> <span class="s1">&#39;.&#39;</span>
<span class="vi">@i: </span><span class="o">+</span> <span class="nx">number</span><span class="p">.</span><span class="nx">length</span>
<span class="nx">@token</span> <span class="s1">&#39;NUMBER&#39;</span><span class="p">,</span> <span class="nx">number</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-11">#</a> </div> <p>Matches strings, including multi-line strings. Ensures that quotation marks
are balanced within the string's contents, and within nested interpolations.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">stringToken: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nx">starts</span><span class="p">(</span><span class="nx">@chunk</span><span class="p">,</span> <span class="s1">&#39;&quot;&#39;</span><span class="p">)</span> <span class="o">or</span> <span class="nx">starts</span><span class="p">(</span><span class="nx">@chunk</span><span class="p">,</span> <span class="s2">&quot;&#39;&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nv">string:</span>
<span class="nx">@balancedToken</span><span class="p">([</span><span class="s1">&#39;&quot;&#39;</span><span class="p">,</span> <span class="s1">&#39;&quot;&#39;</span><span class="p">],</span> <span class="p">[</span><span class="s1">&#39;${&#39;</span><span class="p">,</span> <span class="s1">&#39;}&#39;</span><span class="p">])</span> <span class="o">or</span>
<span class="nx">@balancedToken</span> <span class="p">[</span><span class="s2">&quot;&#39;&quot;</span><span class="p">,</span> <span class="s2">&quot;&#39;&quot;</span><span class="p">]</span>
<span class="nx">@interpolateString</span> <span class="nx">string</span><span class="p">.</span><span class="nx">replace</span> <span class="nx">STRING_NEWLINES</span><span class="p">,</span> <span class="s2">&quot; \\\n&quot;</span>
<span class="vi">@line: </span><span class="o">+</span> <span class="nx">count</span> <span class="nx">string</span><span class="p">,</span> <span class="s2">&quot;\n&quot;</span>
<span class="vi">@i: </span><span class="o">+</span> <span class="nx">string</span><span class="p">.</span><span class="nx">length</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-12">#</a> </div> <p>Matches heredocs, adjusting indentation to the correct level, as heredocs
preserve whitespace, but ignore indentation to the left.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">heredocToken: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nv">match: </span><span class="nx">@chunk</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">HEREDOC</span><span class="p">)</span>
<span class="nv">quote: </span><span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">substr</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span>
<span class="nv">doc: </span><span class="nx">@sanitizeHeredoc</span> <span class="nx">match</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">or</span> <span class="nx">match</span><span class="p">[</span><span class="mi">4</span><span class="p">],</span> <span class="p">{</span><span class="nx">quote</span><span class="p">}</span>
<span class="nx">@interpolateString</span> <span class="s2">&quot;$quote$doc$quote&quot;</span>
<span class="vi">@line: </span><span class="o">+</span> <span class="nx">count</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="s2">&quot;\n&quot;</span>
<span class="vi">@i: </span><span class="o">+</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">length</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-13">#</a> </div> <p>Matches and conumes comments.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">commentToken: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nv">match: </span><span class="nx">@chunk</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">COMMENT</span><span class="p">)</span>
<span class="vi">@line: </span><span class="o">+</span> <span class="nx">count</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="s2">&quot;\n&quot;</span>
<span class="vi">@i: </span><span class="o">+</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">length</span>
<span class="k">if</span> <span class="nx">match</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
<span class="nv">comment: </span><span class="nx">@sanitizeHeredoc</span> <span class="nx">match</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">{</span><span class="nv">herecomment: </span><span class="kc">true</span><span class="p">}</span>
<span class="nx">@token</span> <span class="s1">&#39;HERECOMMENT&#39;</span><span class="p">,</span> <span class="nx">comment</span><span class="p">.</span><span class="nx">split</span> <span class="nx">MULTILINER</span>
<span class="nx">@token</span> <span class="s1">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s1">&#39;\n&#39;</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-14">#</a> </div> <p>Matches JavaScript interpolated directly into the source via backticks.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">jsToken: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nx">starts</span> <span class="nx">@chunk</span><span class="p">,</span> <span class="s1">&#39;`&#39;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nv">script: </span><span class="nx">@balancedToken</span> <span class="p">[</span><span class="s1">&#39;`&#39;</span><span class="p">,</span> <span class="s1">&#39;`&#39;</span><span class="p">]</span>
<span class="nx">@token</span> <span class="s1">&#39;JS&#39;</span><span class="p">,</span> <span class="nx">script</span><span class="p">.</span><span class="nx">replace</span> <span class="nx">JS_CLEANER</span><span class="p">,</span> <span class="s1">&#39;&#39;</span>
<span class="vi">@i: </span><span class="o">+</span> <span class="nx">script</span><span class="p">.</span><span class="nx">length</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-15">#</a> </div> <p>Matches regular expression literals. Lexing regular expressions is difficult
to distinguish from division, so we borrow some basic heuristics from
JavaScript and Ruby, borrow slash balancing from <code>@balancedToken</code>, and
borrow interpolation from <code>@interpolateString</code>.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">regexToken: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nx">@chunk</span><span class="p">.</span><span class="nx">match</span> <span class="nx">REGEX_START</span>
<span class="k">return</span> <span class="kc">false</span> <span class="k">if</span> <span class="nx">include</span> <span class="nx">NOT_REGEX</span><span class="p">,</span> <span class="nx">@tag</span><span class="p">()</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nv">regex: </span><span class="nx">@balancedToken</span> <span class="p">[</span><span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="s1">&#39;/&#39;</span><span class="p">]</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nv">end: </span><span class="nx">@chunk</span><span class="p">.</span><span class="nx">substr</span><span class="p">(</span><span class="nx">regex</span><span class="p">.</span><span class="nx">length</span><span class="p">).</span><span class="nx">match</span> <span class="nx">REGEX_END</span>
<span class="nv">regex: </span><span class="o">+</span> <span class="nv">flags: </span><span class="nx">end</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="k">if</span> <span class="nx">end</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">regex</span><span class="p">.</span><span class="nx">match</span> <span class="nx">REGEX_INTERPOLATION</span>
<span class="nv">str: </span><span class="nx">regex</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="mi">1</span><span class="p">).</span><span class="nx">split</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="nv">str: </span><span class="nx">str</span><span class="p">.</span><span class="nx">replace</span> <span class="nx">REGEX_ESCAPE</span><span class="p">,</span> <span class="p">(</span><span class="nx">escaped</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="s1">&#39;\\&#39;</span> <span class="o">+</span> <span class="nx">escaped</span>
<span class="vi">@tokens: </span><span class="nx">@tokens</span><span class="p">.</span><span class="nx">concat</span> <span class="p">[[</span><span class="s1">&#39;(&#39;</span><span class="p">,</span> <span class="s1">&#39;(&#39;</span><span class="p">],</span> <span class="p">[</span><span class="s1">&#39;NEW&#39;</span><span class="p">,</span> <span class="s1">&#39;new&#39;</span><span class="p">],</span> <span class="p">[</span><span class="s1">&#39;IDENTIFIER&#39;</span><span class="p">,</span> <span class="s1">&#39;RegExp&#39;</span><span class="p">],</span> <span class="p">[</span><span class="s1">&#39;CALL_START&#39;</span><span class="p">,</span> <span class="s1">&#39;(&#39;</span><span class="p">]]</span>
<span class="nx">@interpolateString</span> <span class="s2">&quot;\&quot;$str\&quot;&quot;</span><span class="p">,</span> <span class="kc">yes</span>
<span class="vi">@tokens: </span><span class="nx">@tokens</span><span class="p">.</span><span class="nx">concat</span> <span class="p">[[</span><span class="s1">&#39;,&#39;</span><span class="p">,</span> <span class="s1">&#39;,&#39;</span><span class="p">],</span> <span class="p">[</span><span class="s1">&#39;STRING&#39;</span><span class="p">,</span> <span class="s2">&quot;\&quot;$flags\&quot;&quot;</span><span class="p">],</span> <span class="p">[</span><span class="s1">&#39;)&#39;</span><span class="p">,</span> <span class="s1">&#39;)&#39;</span><span class="p">],</span> <span class="p">[</span><span class="s1">&#39;)&#39;</span><span class="p">,</span> <span class="s1">&#39;)&#39;</span><span class="p">]]</span>
<span class="k">else</span>
<span class="nx">@token</span> <span class="s1">&#39;REGEX&#39;</span><span class="p">,</span> <span class="nx">regex</span>
<span class="vi">@i: </span><span class="o">+</span> <span class="nx">regex</span><span class="p">.</span><span class="nx">length</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-16">#</a> </div> <p>Matches a token in which which the passed delimiter pairs must be correctly
balanced (ie. strings, JS literals).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">balancedToken: </span><span class="p">(</span><span class="nx">delimited</span><span class="p">...)</span> <span class="o">-&gt;</span>
<span class="nx">@balancedString</span> <span class="nx">@chunk</span><span class="p">,</span> <span class="nx">delimited</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-17">#</a> </div> <p>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,
then the newline is suppressed:</p>
<pre><code>elements
.each( ... )
.map( ... )
</code></pre>
<p>Keeps track of the level of indentation, because a single outdent token
can close multiple indents, so we need to know how far in we happen to be.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">lineToken: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nv">indent: </span><span class="nx">@match</span> <span class="nx">MULTI_DENT</span><span class="p">,</span> <span class="mi">1</span>
<span class="vi">@line: </span><span class="o">+</span> <span class="nx">count</span> <span class="nx">indent</span><span class="p">,</span> <span class="s2">&quot;\n&quot;</span>
<span class="vi">@i : </span><span class="o">+</span> <span class="nx">indent</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">prev: </span><span class="nx">@prev</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="nv">size: </span><span class="nx">indent</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">LAST_DENTS</span><span class="p">).</span><span class="nx">reverse</span><span class="p">()[</span><span class="mi">0</span><span class="p">].</span><span class="nx">match</span><span class="p">(</span><span class="nx">LAST_DENT</span><span class="p">)[</span><span class="mi">1</span><span class="p">].</span><span class="nx">length</span>
<span class="nv">nextCharacter: </span><span class="nx">@match</span> <span class="nx">NEXT_CHARACTER</span><span class="p">,</span> <span class="mi">1</span>
<span class="nv">noNewlines: </span><span class="nx">nextCharacter</span> <span class="o">is</span> <span class="s1">&#39;.&#39;</span> <span class="o">or</span> <span class="nx">nextCharacter</span> <span class="o">is</span> <span class="s1">&#39;,&#39;</span> <span class="o">or</span> <span class="nx">@unfinished</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">size</span> <span class="o">is</span> <span class="nx">@indent</span>
<span class="k">return</span> <span class="nx">@suppressNewlines</span><span class="p">()</span> <span class="k">if</span> <span class="nx">noNewlines</span>
<span class="k">return</span> <span class="nx">@newlineToken</span> <span class="nx">indent</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">size</span> <span class="o">&gt;</span> <span class="nx">@indent</span>
<span class="k">return</span> <span class="nx">@suppressNewlines</span><span class="p">()</span> <span class="k">if</span> <span class="nx">noNewlines</span>
<span class="nv">diff: </span><span class="nx">size</span> <span class="o">-</span> <span class="nx">@indent</span>
<span class="nx">@token</span> <span class="s1">&#39;INDENT&#39;</span><span class="p">,</span> <span class="nx">diff</span>
<span class="nx">@indents</span><span class="p">.</span><span class="nx">push</span> <span class="nx">diff</span>
<span class="k">else</span>
<span class="nx">@outdentToken</span> <span class="nx">@indent</span> <span class="o">-</span> <span class="nx">size</span><span class="p">,</span> <span class="nx">noNewlines</span>
<span class="vi">@indent: </span><span class="nx">size</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-18">#</a> </div> <p>Record an outdent token or multiple tokens, if we happen to be moving back
inwards past several recorded indents.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">outdentToken: </span><span class="p">(</span><span class="nx">moveOut</span><span class="p">,</span> <span class="nx">noNewlines</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">if</span> <span class="nx">moveOut</span> <span class="o">&gt;</span> <span class="o">-</span><span class="nx">@outdebt</span>
<span class="k">while</span> <span class="nx">moveOut</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">and</span> <span class="nx">@indents</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">lastIndent: </span><span class="nx">@indents</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span>
<span class="nx">@token</span> <span class="s1">&#39;OUTDENT&#39;</span><span class="p">,</span> <span class="nx">lastIndent</span>
<span class="nv">moveOut: </span><span class="o">-</span> <span class="nx">lastIndent</span>
<span class="k">else</span>
<span class="vi">@outdebt: </span><span class="o">+</span> <span class="nx">moveOut</span>
<span class="vi">@outdebt: </span><span class="nx">moveOut</span> <span class="nx">unless</span> <span class="nx">noNewlines</span>
<span class="nx">@token</span> <span class="s1">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s2">&quot;\n&quot;</span> <span class="nx">unless</span> <span class="nx">@tag</span><span class="p">()</span> <span class="o">is</span> <span class="s1">&#39;TERMINATOR&#39;</span> <span class="o">or</span> <span class="nx">noNewlines</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-19">#</a> </div> <p>Matches and consumes non-meaningful whitespace. Tag the previous token
as being "spaced", because there are some cases where it makes a difference.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">whitespaceToken: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nv">space: </span><span class="nx">@match</span> <span class="nx">WHITESPACE</span><span class="p">,</span> <span class="mi">1</span>
<span class="nv">prev: </span><span class="nx">@prev</span><span class="p">()</span>
<span class="nv">prev.spaced: </span><span class="kc">true</span> <span class="k">if</span> <span class="nx">prev</span>
<span class="vi">@i: </span><span class="o">+</span> <span class="nx">space</span><span class="p">.</span><span class="nx">length</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-20">#</a> </div> <p>Generate a newline token. Consecutive newlines get merged together.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">newlineToken: </span><span class="p">(</span><span class="nx">newlines</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@token</span> <span class="s1">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s2">&quot;\n&quot;</span> <span class="nx">unless</span> <span class="nx">@tag</span><span class="p">()</span> <span class="o">is</span> <span class="s1">&#39;TERMINATOR&#39;</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-21">#</a> </div> <p>Use a <code>\</code> at a line-ending to suppress the newline.
The slash is removed here once its job is done.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">suppressNewlines: </span><span class="o">-&gt;</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span> <span class="k">if</span> <span class="nx">@value</span><span class="p">()</span> <span class="o">is</span> <span class="s2">&quot;\\&quot;</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-22">#</a> </div> <p>We treat all other single characters as a token. Eg.: <code>( ) , . !</code>
Multi-character operators are also literal tokens, so that Jison can assign
the proper order of operations. There are some symbols that we tag specially
here. <code>;</code> and newlines are both treated as a <code>TERMINATOR</code>, we distinguish
parentheses that indicate a method call from regular parentheses, and so on.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">literalToken: </span><span class="o">-&gt;</span>
<span class="nv">match: </span><span class="nx">@chunk</span><span class="p">.</span><span class="nx">match</span> <span class="nx">OPERATOR</span>
<span class="nv">value: </span><span class="nx">match</span> <span class="o">and</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="nv">space: </span><span class="nx">match</span> <span class="o">and</span> <span class="nx">match</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
<span class="nx">@tagParameters</span><span class="p">()</span> <span class="k">if</span> <span class="nx">value</span> <span class="o">and</span> <span class="nx">value</span><span class="p">.</span><span class="nx">match</span> <span class="nx">CODE</span>
<span class="nv">value: </span><span class="o">or</span> <span class="nx">@chunk</span><span class="p">.</span><span class="nx">substr</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span>
<span class="nv">prevSpaced: </span><span class="nx">@prev</span><span class="p">()</span> <span class="o">and</span> <span class="nx">@prev</span><span class="p">().</span><span class="nx">spaced</span>
<span class="nv">tag: </span><span class="nx">value</span>
<span class="k">if</span> <span class="nx">value</span><span class="p">.</span><span class="nx">match</span> <span class="nx">ASSIGNMENT</span>
<span class="nv">tag: </span><span class="s1">&#39;ASSIGN&#39;</span>
<span class="nx">@assignmentError</span><span class="p">()</span> <span class="k">if</span> <span class="nx">include</span> <span class="nx">JS_FORBIDDEN</span><span class="p">,</span> <span class="nx">@value</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">value</span> <span class="o">is</span> <span class="s1">&#39;;&#39;</span>
<span class="nv">tag: </span><span class="s1">&#39;TERMINATOR&#39;</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">value</span> <span class="o">is</span> <span class="s1">&#39;?&#39;</span> <span class="o">and</span> <span class="nx">prevSpaced</span>
<span class="nv">tag: </span><span class="s1">&#39;OP?&#39;</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">include</span><span class="p">(</span><span class="nx">CALLABLE</span><span class="p">,</span> <span class="nx">@tag</span><span class="p">())</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">prevSpaced</span>
<span class="k">if</span> <span class="nx">value</span> <span class="o">is</span> <span class="s1">&#39;(&#39;</span>
<span class="nv">tag: </span><span class="s1">&#39;CALL_START&#39;</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">value</span> <span class="o">is</span> <span class="s1">&#39;[&#39;</span>
<span class="nv">tag: </span><span class="s1">&#39;INDEX_START&#39;</span>
<span class="nx">@tag</span> <span class="mi">1</span><span class="p">,</span> <span class="s1">&#39;INDEX_SOAK&#39;</span> <span class="k">if</span> <span class="nx">@tag</span><span class="p">()</span> <span class="o">is</span> <span class="s1">&#39;?&#39;</span>
<span class="nx">@tag</span> <span class="mi">1</span><span class="p">,</span> <span class="s1">&#39;INDEX_PROTO&#39;</span> <span class="k">if</span> <span class="nx">@tag</span><span class="p">()</span> <span class="o">is</span> <span class="s1">&#39;::&#39;</span>
<span class="vi">@i: </span><span class="o">+</span> <span class="nx">value</span><span class="p">.</span><span class="nx">length</span>
<span class="k">return</span> <span class="nx">@tagHalfAssignment</span> <span class="nx">tag</span> <span class="k">if</span> <span class="nx">space</span> <span class="o">and</span> <span class="nx">prevSpaced</span> <span class="o">and</span> <span class="nx">@prev</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;ASSIGN&#39;</span> <span class="o">and</span> <span class="nx">include</span> <span class="nx">HALF_ASSIGNMENTS</span><span class="p">,</span> <span class="nx">tag</span>
<span class="nx">@token</span> <span class="nx">tag</span><span class="p">,</span> <span class="nx">value</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-23">#</a> </div> <h2>Token Manipulators</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-24">#</a> </div> <p>As we consume a new <code>IDENTIFIER</code>, look at the previous token to determine
if it's a special kind of accessor. Return <code>true</code> if any type of accessor
is the previous token.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">tagAccessor: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="k">if</span> <span class="p">(</span><span class="o">not</span> <span class="nv">prev: </span><span class="nx">@prev</span><span class="p">())</span> <span class="o">or</span> <span class="p">(</span><span class="nx">prev</span> <span class="o">and</span> <span class="nx">prev</span><span class="p">.</span><span class="nx">spaced</span><span class="p">)</span>
<span class="nv">accessor: </span><span class="k">if</span> <span class="nx">prev</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;::&#39;</span>
<span class="nx">@tag</span> <span class="mi">1</span><span class="p">,</span> <span class="s1">&#39;PROTOTYPE_ACCESS&#39;</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">prev</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;.&#39;</span> <span class="o">and</span> <span class="o">not</span> <span class="p">(</span><span class="nx">@value</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="o">is</span> <span class="s1">&#39;.&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">@tag</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="o">is</span> <span class="s1">&#39;?&#39;</span>
<span class="nx">@tag</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="s1">&#39;SOAK_ACCESS&#39;</span><span class="p">)</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span><span class="p">(</span><span class="o">-</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">else</span>
<span class="nx">@tag</span> <span class="mi">1</span><span class="p">,</span> <span class="s1">&#39;PROPERTY_ACCESS&#39;</span>
<span class="k">else</span>
<span class="nx">prev</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;@&#39;</span>
<span class="k">if</span> <span class="nx">accessor</span> <span class="k">then</span> <span class="s1">&#39;accessor&#39;</span> <span class="k">else</span> <span class="kc">false</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-25">#</a> </div> <p>Sanitize a heredoc or herecomment by escaping internal double quotes and
erasing all external indentation on the left-hand side.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">sanitizeHeredoc: </span><span class="p">(</span><span class="nx">doc</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">while</span> <span class="nv">match: </span><span class="nx">HEREDOC_INDENT</span><span class="p">.</span><span class="nx">exec</span> <span class="nx">doc</span>
<span class="nv">attempt: </span><span class="k">if</span> <span class="nx">match</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="o">?</span> <span class="k">then</span> <span class="nx">match</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="k">else</span> <span class="nx">match</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>
<span class="nv">indent: </span><span class="nx">attempt</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">indent</span> <span class="o">or</span> <span class="nx">attempt</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="nx">indent</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">doc: </span><span class="nx">doc</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="s2">&quot;^&quot;</span> <span class="o">+</span><span class="nx">indent</span><span class="p">,</span> <span class="s1">&#39;gm&#39;</span><span class="p">),</span> <span class="s1">&#39;&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="nx">doc</span> <span class="k">if</span> <span class="nx">options</span><span class="p">.</span><span class="nx">herecomment</span>
<span class="nx">doc</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="nx">MULTILINER</span><span class="p">,</span> <span class="s2">&quot;\\n&quot;</span><span class="p">)</span>
<span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">quote</span><span class="p">,</span> <span class="s1">&#39;g&#39;</span><span class="p">),</span> <span class="s2">&quot;\\$options.quote&quot;</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-26">#</a> </div> <p>Tag a half assignment.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">tagHalfAssignment: </span><span class="p">(</span><span class="nx">tag</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">tag: </span> <span class="s1">&#39;?&#39;</span> <span class="k">if</span> <span class="nx">tag</span> <span class="o">is</span> <span class="s1">&#39;OP?&#39;</span>
<span class="nv">last: </span><span class="nx">@tokens</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="s2">&quot;$tag=&quot;</span><span class="p">,</span> <span class="s2">&quot;$tag=&quot;</span><span class="p">,</span> <span class="nx">last</span><span class="p">[</span><span class="mi">2</span><span class="p">]]</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-27">#</a> </div> <p>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.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">tagParameters: </span><span class="o">-&gt;</span>
<span class="k">return</span> <span class="k">if</span> <span class="nx">@tag</span><span class="p">()</span> <span class="o">isnt</span> <span class="s1">&#39;)&#39;</span>
<span class="nv">i: </span><span class="mi">0</span>
<span class="nx">loop</span>
<span class="nv">i: </span><span class="o">+</span> <span class="mi">1</span>
<span class="nv">tok: </span><span class="nx">@prev</span> <span class="nx">i</span>
<span class="k">return</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">tok</span>
<span class="k">switch</span> <span class="nx">tok</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">when</span> <span class="s1">&#39;IDENTIFIER&#39;</span> <span class="k">then</span> <span class="nx">tok</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">:</span> <span class="s1">&#39;PARAM&#39;</span>
<span class="k">when</span> <span class="s1">&#39;)&#39;</span> <span class="k">then</span> <span class="nx">tok</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">:</span> <span class="s1">&#39;PARAM_END&#39;</span>
<span class="k">when</span> <span class="s1">&#39;(&#39;</span><span class="p">,</span> <span class="s1">&#39;CALL_START&#39;</span> <span class="k">then</span> <span class="k">return</span> <span class="nx">tok</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">:</span> <span class="s1">&#39;PARAM_START&#39;</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-28">#</a> </div> <p>Close up all remaining open blocks at the end of the file.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">closeIndentation: </span><span class="o">-&gt;</span>
<span class="nx">@outdentToken</span> <span class="nx">@indent</span></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-29">#</a> </div> <p>The error for when you try to use a forbidden word in JavaScript as
an identifier.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">identifierError: </span><span class="p">(</span><span class="nx">word</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s2">&quot;SyntaxError: Reserved word \&quot;$word\&quot; on line ${@line + 1}&quot;</span></pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-30">#</a> </div> <p>The error for when you try to assign to a reserved word in JavaScript,
like "function" or "default".</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">assignmentError: </span><span class="o">-&gt;</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s2">&quot;SyntaxError: Reserved word \&quot;${@value()}\&quot; on line ${@line + 1} can&#39;t be assigned&quot;</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-31">#</a> </div> <p>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.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">balancedString: </span><span class="p">(</span><span class="nx">str</span><span class="p">,</span> <span class="nx">delimited</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">options: </span><span class="o">or</span> <span class="p">{}</span>
<span class="nv">slash: </span><span class="nx">delimited</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;/&#39;</span>
<span class="nv">levels: </span><span class="p">[]</span>
<span class="nv">i: </span><span class="mi">0</span>
<span class="k">while</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">str</span><span class="p">.</span><span class="nx">length</span>
<span class="k">if</span> <span class="nx">levels</span><span class="p">.</span><span class="nx">length</span> <span class="o">and</span> <span class="nx">starts</span> <span class="nx">str</span><span class="p">,</span> <span class="s1">&#39;\\&#39;</span><span class="p">,</span> <span class="nx">i</span>
<span class="nv">i: </span><span class="o">+</span> <span class="mi">1</span>
<span class="k">else</span>
<span class="k">for</span> <span class="nx">pair</span> <span class="k">in</span> <span class="nx">delimited</span>
<span class="p">[</span><span class="nx">open</span><span class="p">,</span> <span class="nx">close</span><span class="p">]</span><span class="o">:</span> <span class="nx">pair</span>
<span class="k">if</span> <span class="nx">levels</span><span class="p">.</span><span class="nx">length</span> <span class="o">and</span> <span class="nx">starts</span><span class="p">(</span><span class="nx">str</span><span class="p">,</span> <span class="nx">close</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="o">and</span> <span class="nx">levels</span><span class="p">[</span><span class="nx">levels</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">is</span> <span class="nx">pair</span>
<span class="nx">levels</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span>
<span class="nv">i: </span><span class="o">+</span> <span class="nx">close</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span>
<span class="nv">i: </span><span class="o">+</span> <span class="mi">1</span> <span class="nx">unless</span> <span class="nx">levels</span><span class="p">.</span><span class="nx">length</span>
<span class="k">break</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">starts</span> <span class="nx">str</span><span class="p">,</span> <span class="nx">open</span><span class="p">,</span> <span class="nx">i</span>
<span class="nx">levels</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">pair</span><span class="p">)</span>
<span class="nv">i: </span><span class="o">+</span> <span class="nx">open</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span>
<span class="k">break</span>
<span class="k">break</span> <span class="k">if</span> <span class="o">not</span> <span class="nx">levels</span><span class="p">.</span><span class="nx">length</span> <span class="o">or</span> <span class="nx">slash</span> <span class="o">and</span> <span class="nx">starts</span> <span class="nx">str</span><span class="p">,</span> <span class="s1">&#39;\n&#39;</span><span class="p">,</span> <span class="nx">i</span>
<span class="nv">i: </span><span class="o">+</span> <span class="mi">1</span>
<span class="k">if</span> <span class="nx">levels</span><span class="p">.</span><span class="nx">length</span>
<span class="k">return</span> <span class="kc">false</span> <span class="k">if</span> <span class="nx">slash</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s2">&quot;SyntaxError: Unterminated ${levels.pop()[0]} starting on line ${@line + 1}&quot;</span>
<span class="k">if</span> <span class="o">not</span> <span class="nx">i</span> <span class="k">then</span> <span class="kc">false</span> <span class="k">else</span> <span class="nx">str</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-32">#</a> </div> <p>Expand variables and expressions inside double-quoted strings using
<a href="http://wiki.ecmascript.org/doku.php?id=strawman:string_interpolation">ECMA Harmony's interpolation syntax</a>
for substitution of bare variables as well as arbitrary expressions.</p>
<pre><code>"Hello $name."
"Hello ${name.capitalize()}."
</code></pre>
<p>If it encounters an interpolation, this method will recursively create a
new Lexer, tokenize the interpolated contents, and merge them into the
token stream.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">interpolateString: </span><span class="p">(</span><span class="nx">str</span><span class="p">,</span> <span class="nx">escapeQuotes</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">if</span> <span class="nx">str</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="mi">3</span> <span class="o">or</span> <span class="o">not</span> <span class="nx">starts</span> <span class="nx">str</span><span class="p">,</span> <span class="s1">&#39;&quot;&#39;</span>
<span class="nx">@token</span> <span class="s1">&#39;STRING&#39;</span><span class="p">,</span> <span class="nx">str</span>
<span class="k">else</span>
<span class="nv">lexer: </span> <span class="k">new</span> <span class="nx">Lexer</span>
<span class="nv">tokens: </span> <span class="p">[]</span>
<span class="nv">quote: </span> <span class="nx">str</span><span class="p">.</span><span class="nx">substring</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span>
<span class="p">[</span><span class="nx">i</span><span class="p">,</span> <span class="nx">pi</span><span class="p">]</span><span class="o">:</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span>
<span class="k">while</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">str</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span>
<span class="k">if</span> <span class="nx">starts</span> <span class="nx">str</span><span class="p">,</span> <span class="s1">&#39;\\&#39;</span><span class="p">,</span> <span class="nx">i</span>
<span class="nv">i: </span><span class="o">+</span> <span class="mi">1</span>
<span class="k">else</span> <span class="k">if</span> <span class="nv">match: </span><span class="nx">str</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="nx">i</span><span class="p">).</span><span class="nx">match</span> <span class="nx">INTERPOLATION</span>
<span class="p">[</span><span class="nx">group</span><span class="p">,</span> <span class="nx">interp</span><span class="p">]</span><span class="o">:</span> <span class="nx">match</span>
<span class="nv">interp: </span><span class="s2">&quot;this.${ interp.substring(1) }&quot;</span> <span class="k">if</span> <span class="nx">starts</span> <span class="nx">interp</span><span class="p">,</span> <span class="s1">&#39;@&#39;</span>
<span class="nx">tokens</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="s1">&#39;STRING&#39;</span><span class="p">,</span> <span class="s2">&quot;$quote${ str.substring(pi, i) }$quote&quot;</span><span class="p">]</span> <span class="k">if</span> <span class="nx">pi</span> <span class="o">&lt;</span> <span class="nx">i</span>
<span class="nx">tokens</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="s1">&#39;IDENTIFIER&#39;</span><span class="p">,</span> <span class="nx">interp</span><span class="p">]</span>
<span class="nv">i: </span><span class="o">+</span> <span class="nx">group</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span>
<span class="nv">pi: </span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nv">expr: </span><span class="nx">@balancedString</span> <span class="nx">str</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="nx">i</span><span class="p">),</span> <span class="p">[[</span><span class="s1">&#39;${&#39;</span><span class="p">,</span> <span class="s1">&#39;}&#39;</span><span class="p">]])</span>
<span class="nx">tokens</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="s1">&#39;STRING&#39;</span><span class="p">,</span> <span class="s2">&quot;$quote${ str.substring(pi, i) }$quote&quot;</span><span class="p">]</span> <span class="k">if</span> <span class="nx">pi</span> <span class="o">&lt;</span> <span class="nx">i</span>
<span class="nv">inner: </span><span class="nx">expr</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">inner</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">inner: </span><span class="nx">inner</span><span class="p">.</span><span class="nx">replace</span> <span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="s1">&#39;\\\\&#39;</span> <span class="o">+</span> <span class="nx">quote</span><span class="p">,</span> <span class="s1">&#39;g&#39;</span><span class="p">),</span> <span class="nx">quote</span>
<span class="nv">nested: </span><span class="nx">lexer</span><span class="p">.</span><span class="nx">tokenize</span> <span class="s2">&quot;($inner)&quot;</span><span class="p">,</span> <span class="p">{</span><span class="nv">line: </span><span class="nx">@line</span><span class="p">}</span>
<span class="p">(</span><span class="nx">tok</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">:</span> <span class="s1">&#39;)&#39;</span><span class="p">)</span> <span class="k">for</span> <span class="nx">tok</span><span class="p">,</span> <span class="nx">idx</span> <span class="k">in</span> <span class="nx">nested</span> <span class="k">when</span> <span class="nx">tok</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;CALL_END&#39;</span>
<span class="nx">nested</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span>
<span class="nx">tokens</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="s1">&#39;TOKENS&#39;</span><span class="p">,</span> <span class="nx">nested</span><span class="p">]</span>
<span class="k">else</span>
<span class="nx">tokens</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="s1">&#39;STRING&#39;</span><span class="p">,</span> <span class="s2">&quot;$quote$quote&quot;</span><span class="p">]</span>
<span class="nv">i: </span><span class="o">+</span> <span class="nx">expr</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span>
<span class="nv">pi: </span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span>
<span class="nv">i: </span><span class="o">+</span> <span class="mi">1</span>
<span class="nx">tokens</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="s1">&#39;STRING&#39;</span><span class="p">,</span> <span class="s2">&quot;$quote${ str.substring(pi, i) }$quote&quot;</span><span class="p">]</span> <span class="k">if</span> <span class="nx">pi</span> <span class="o">&lt;</span> <span class="nx">i</span> <span class="o">and</span> <span class="nx">pi</span> <span class="o">&lt;</span> <span class="nx">str</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span>
<span class="nx">tokens</span><span class="p">.</span><span class="nx">unshift</span> <span class="p">[</span><span class="s1">&#39;STRING&#39;</span><span class="p">,</span> <span class="s1">&#39;&quot;&quot;&#39;</span><span class="p">]</span> <span class="nx">unless</span> <span class="nx">tokens</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;STRING&#39;</span>
<span class="nv">interpolated: </span><span class="nx">tokens</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">1</span>
<span class="nx">@token</span> <span class="s1">&#39;(&#39;</span><span class="p">,</span> <span class="s1">&#39;(&#39;</span> <span class="k">if</span> <span class="nx">interpolated</span>
<span class="k">for</span> <span class="nx">token</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">tokens</span>
<span class="p">[</span><span class="nx">tag</span><span class="p">,</span> <span class="nx">value</span><span class="p">]</span><span class="o">:</span> <span class="nx">token</span>
<span class="k">if</span> <span class="nx">tag</span> <span class="o">is</span> <span class="s1">&#39;TOKENS&#39;</span>
<span class="vi">@tokens: </span><span class="nx">@tokens</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">value</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">tag</span> <span class="o">is</span> <span class="s1">&#39;STRING&#39;</span> <span class="o">and</span> <span class="nx">escapeQuotes</span>
<span class="nv">escaped: </span><span class="nx">value</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nx">value</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">).</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/&quot;/g</span><span class="p">,</span> <span class="s1">&#39;\\&quot;&#39;</span><span class="p">)</span>
<span class="nx">@token</span> <span class="nx">tag</span><span class="p">,</span> <span class="s2">&quot;\&quot;$escaped\&quot;&quot;</span>
<span class="k">else</span>
<span class="nx">@token</span> <span class="nx">tag</span><span class="p">,</span> <span class="nx">value</span>
<span class="nx">@token</span> <span class="s1">&#39;+&#39;</span><span class="p">,</span> <span class="s1">&#39;+&#39;</span> <span class="k">if</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">tokens</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span>
<span class="nx">@token</span> <span class="s1">&#39;)&#39;</span><span class="p">,</span> <span class="s1">&#39;)&#39;</span> <span class="k">if</span> <span class="nx">interpolated</span>
<span class="nx">tokens</span></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-33">#</a> </div> <h2>Helpers</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-34">#</a> </div> <p>Add a token to the results, taking note of the line number.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">token: </span><span class="p">(</span><span class="nx">tag</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">push</span> <span class="p">[</span><span class="nx">tag</span><span class="p">,</span> <span class="nx">value</span><span class="p">,</span> <span class="nx">@line</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-35">#</a> </div> <p>Peek at a tag in the current token stream.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">tag: </span><span class="p">(</span><span class="nx">index</span><span class="p">,</span> <span class="nx">newTag</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="nx">unless</span> <span class="nv">tok: </span><span class="nx">@prev</span> <span class="nx">index</span>
<span class="k">return</span> <span class="nx">tok</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">:</span> <span class="nx">newTag</span> <span class="k">if</span> <span class="nx">newTag</span><span class="o">?</span>
<span class="nx">tok</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-36">#</a> </div> <p>Peek at a value in the current token stream.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">value: </span><span class="p">(</span><span class="nx">index</span><span class="p">,</span> <span class="nx">val</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="nx">unless</span> <span class="nv">tok: </span><span class="nx">@prev</span> <span class="nx">index</span>
<span class="k">return</span> <span class="nx">tok</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="o">:</span> <span class="nx">val</span> <span class="k">if</span> <span class="nx">val</span><span class="o">?</span>
<span class="nx">tok</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-37">#</a> </div> <p>Peek at a previous token, entire.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">prev: </span><span class="p">(</span><span class="nx">index</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@tokens</span><span class="p">[</span><span class="nx">@tokens</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="p">(</span><span class="nx">index</span> <span class="o">or</span> <span class="mi">1</span><span class="p">)]</span></pre></div> </td> </tr> <tr id="section-38"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-38">#</a> </div> <p>Attempt to match a string against the current chunk, returning the indexed
match if successful, and <code>false</code> otherwise.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">match: </span><span class="p">(</span><span class="nx">regex</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">false</span> <span class="nx">unless</span> <span class="nv">m: </span><span class="nx">@chunk</span><span class="p">.</span><span class="nx">match</span> <span class="nx">regex</span>
<span class="k">if</span> <span class="nx">m</span> <span class="k">then</span> <span class="nx">m</span><span class="p">[</span><span class="nx">index</span><span class="p">]</span> <span class="k">else</span> <span class="kc">false</span></pre></div> </td> </tr> <tr id="section-39"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-39">#</a> </div> <p>Are we in the midst of an unfinished expression?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">unfinished: </span><span class="o">-&gt;</span>
<span class="nv">prev: </span><span class="nx">@prev</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="nx">@value</span><span class="p">()</span> <span class="o">and</span> <span class="nx">@value</span><span class="p">().</span><span class="nx">match</span> <span class="o">and</span> <span class="nx">@value</span><span class="p">().</span><span class="nx">match</span><span class="p">(</span><span class="nx">NO_NEWLINE</span><span class="p">)</span> <span class="o">and</span>
<span class="nx">prev</span> <span class="o">and</span> <span class="p">(</span><span class="nx">prev</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">isnt</span> <span class="s1">&#39;.&#39;</span><span class="p">)</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">@value</span><span class="p">().</span><span class="nx">match</span><span class="p">(</span><span class="nx">CODE</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-40"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-40">#</a> </div> <h2>Constants</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-41"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-41">#</a> </div> <p>Keywords that CoffeeScript shares in common with JavaScript.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">JS_KEYWORDS: </span><span class="p">[</span>
<span class="s2">&quot;if&quot;</span><span class="p">,</span> <span class="s2">&quot;else&quot;</span><span class="p">,</span>
<span class="s2">&quot;true&quot;</span><span class="p">,</span> <span class="s2">&quot;false&quot;</span><span class="p">,</span>
<span class="s2">&quot;new&quot;</span><span class="p">,</span> <span class="s2">&quot;return&quot;</span><span class="p">,</span>
<span class="s2">&quot;try&quot;</span><span class="p">,</span> <span class="s2">&quot;catch&quot;</span><span class="p">,</span> <span class="s2">&quot;finally&quot;</span><span class="p">,</span> <span class="s2">&quot;throw&quot;</span><span class="p">,</span>
<span class="s2">&quot;break&quot;</span><span class="p">,</span> <span class="s2">&quot;continue&quot;</span><span class="p">,</span>
<span class="s2">&quot;for&quot;</span><span class="p">,</span> <span class="s2">&quot;in&quot;</span><span class="p">,</span> <span class="s2">&quot;while&quot;</span><span class="p">,</span>
<span class="s2">&quot;delete&quot;</span><span class="p">,</span> <span class="s2">&quot;instanceof&quot;</span><span class="p">,</span> <span class="s2">&quot;typeof&quot;</span><span class="p">,</span>
<span class="s2">&quot;switch&quot;</span><span class="p">,</span> <span class="s2">&quot;super&quot;</span><span class="p">,</span> <span class="s2">&quot;extends&quot;</span><span class="p">,</span> <span class="s2">&quot;class&quot;</span><span class="p">,</span>
<span class="s2">&quot;this&quot;</span><span class="p">,</span> <span class="s2">&quot;null&quot;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-42"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-42">#</a> </div> <p>CoffeeScript-only keywords, which we're more relaxed about allowing. They can't
be used standalone, but you can reference them as an attached property.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">COFFEE_ALIASES: </span> <span class="p">[</span><span class="s2">&quot;and&quot;</span><span class="p">,</span> <span class="s2">&quot;or&quot;</span><span class="p">,</span> <span class="s2">&quot;is&quot;</span><span class="p">,</span> <span class="s2">&quot;isnt&quot;</span><span class="p">,</span> <span class="s2">&quot;not&quot;</span><span class="p">]</span>
<span class="nv">COFFEE_KEYWORDS: </span><span class="nx">COFFEE_ALIASES</span><span class="p">.</span><span class="nx">concat</span> <span class="p">[</span>
<span class="s2">&quot;then&quot;</span><span class="p">,</span> <span class="s2">&quot;unless&quot;</span><span class="p">,</span> <span class="s2">&quot;until&quot;</span><span class="p">,</span> <span class="s2">&quot;loop&quot;</span><span class="p">,</span>
<span class="s2">&quot;yes&quot;</span><span class="p">,</span> <span class="s2">&quot;no&quot;</span><span class="p">,</span> <span class="s2">&quot;on&quot;</span><span class="p">,</span> <span class="s2">&quot;off&quot;</span><span class="p">,</span>
<span class="s2">&quot;of&quot;</span><span class="p">,</span> <span class="s2">&quot;by&quot;</span><span class="p">,</span> <span class="s2">&quot;where&quot;</span><span class="p">,</span> <span class="s2">&quot;when&quot;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-43"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-43">#</a> </div> <p>The list of keywords that are reserved by JavaScript, but not used, or are
used by CoffeeScript internally. We throw an error when these are encountered,
to avoid having a JavaScript error at runtime.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">RESERVED: </span><span class="p">[</span>
<span class="s2">&quot;case&quot;</span><span class="p">,</span> <span class="s2">&quot;default&quot;</span><span class="p">,</span> <span class="s2">&quot;do&quot;</span><span class="p">,</span> <span class="s2">&quot;function&quot;</span><span class="p">,</span> <span class="s2">&quot;var&quot;</span><span class="p">,</span> <span class="s2">&quot;void&quot;</span><span class="p">,</span> <span class="s2">&quot;with&quot;</span>
<span class="s2">&quot;const&quot;</span><span class="p">,</span> <span class="s2">&quot;let&quot;</span><span class="p">,</span> <span class="s2">&quot;enum&quot;</span><span class="p">,</span> <span class="s2">&quot;export&quot;</span><span class="p">,</span> <span class="s2">&quot;import&quot;</span><span class="p">,</span> <span class="s2">&quot;native&quot;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-44">#</a> </div> <p>The superset of both JavaScript keywords and reserved words, none of which may
be used as identifiers or properties.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">JS_FORBIDDEN: </span><span class="nx">JS_KEYWORDS</span><span class="p">.</span><span class="nx">concat</span> <span class="nx">RESERVED</span></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-45">#</a> </div> <p>Token matching regexes.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IDENTIFIER : </span><span class="sr">/^([a-zA-Z\$_](\w|\$)*)/</span>
<span class="nv">NUMBER : </span><span class="sr">/^(((\b0(x|X)[0-9a-fA-F]+)|((\b[0-9]+(\.[0-9]+)?|\.[0-9]+)(e[+\-]?[0-9]+)?)))\b/i</span>
<span class="nv">HEREDOC : </span><span class="sr">/^(&quot;{6}|&#39;{6}|&quot;{3}\n?([\s\S]*?)\n?([ \t]*)&quot;{3}|&#39;{3}\n?([\s\S]*?)\n?([ \t]*)&#39;{3})/</span>
<span class="nv">INTERPOLATION : </span><span class="sr">/^\$([a-zA-Z_@]\w*(\.\w+)*)/</span>
<span class="nv">OPERATOR : </span><span class="sr">/^(-[\-=&gt;]?|\+[+=]?|[*&amp;|\/%=&lt;&gt;:!?]+)([ \t]*)/</span>
<span class="nv">WHITESPACE : </span><span class="sr">/^([ \t]+)/</span>
<span class="nv">COMMENT : </span><span class="sr">/^(\s*#{3}(?!#)[ \t]*\n+([\s\S]*?)[ \t]*\n+[ \t]*#{3}|(\s*#(?!##[^#])[^\n]*)+)/</span>
<span class="nv">CODE : </span><span class="sr">/^((-|=)&gt;)/</span>
<span class="nv">MULTI_DENT : </span><span class="sr">/^((\n([ \t]*))+)(\.)?/</span>
<span class="nv">LAST_DENTS : </span><span class="sr">/\n([ \t]*)/g</span>
<span class="nv">LAST_DENT : </span><span class="sr">/\n([ \t]*)/</span>
<span class="nv">ASSIGNMENT : </span><span class="sr">/^[:=]$/</span></pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-46">#</a> </div> <p>Regex-matching-regexes.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">REGEX_START : </span><span class="sr">/^\/[^\/ ]/</span>
<span class="nv">REGEX_INTERPOLATION: </span><span class="sr">/([^\\]\$[a-zA-Z_@]|[^\\]\$\{.*[^\\]\})/</span>
<span class="nv">REGEX_END : </span><span class="sr">/^(([imgy]{1,4})\b|\W|$)/</span>
<span class="nv">REGEX_ESCAPE : </span><span class="sr">/\\[^\$]/g</span></pre></div> </td> </tr> <tr id="section-47"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-47">#</a> </div> <p>Token cleaning regexes.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">JS_CLEANER : </span><span class="sr">/(^`|`$)/g</span>
<span class="nv">MULTILINER : </span><span class="sr">/\n/g</span>
<span class="nv">STRING_NEWLINES : </span><span class="sr">/\n[ \t]*/g</span>
<span class="nv">NO_NEWLINE : </span><span class="sr">/^([+\*&amp;|\/\-%=&lt;&gt;:!.\\][&lt;&gt;=&amp;|]*|and|or|is|isnt|not|delete|typeof|instanceof)$/</span>
<span class="nv">HEREDOC_INDENT : </span><span class="sr">/(\n+([ \t]*)|^([ \t]+))/g</span>
<span class="nv">ASSIGNED : </span><span class="sr">/^([a-zA-Z\$_]\w*[ \t]*?[:=][^=])/</span>
<span class="nv">NEXT_CHARACTER : </span><span class="sr">/^\s*(\S)/</span></pre></div> </td> </tr> <tr id="section-48"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-48">#</a> </div> <p>Tokens which a regular expression will never immediately follow, but which
a division operator might.</p>
<p>See: http://www.mozilla.org/js/language/js20-2002-04/rationale/syntax.html#regular-expressions</p>
<p>Our list is shorter, due to sans-parentheses method calls.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">NOT_REGEX: </span><span class="p">[</span>
<span class="s1">&#39;NUMBER&#39;</span><span class="p">,</span> <span class="s1">&#39;REGEX&#39;</span><span class="p">,</span> <span class="s1">&#39;++&#39;</span><span class="p">,</span> <span class="s1">&#39;--&#39;</span><span class="p">,</span> <span class="s1">&#39;FALSE&#39;</span><span class="p">,</span> <span class="s1">&#39;NULL&#39;</span><span class="p">,</span> <span class="s1">&#39;TRUE&#39;</span><span class="p">,</span> <span class="s1">&#39;]&#39;</span>
<span class="p">]</span></pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-49">#</a> </div> <p>Tokens which could legitimately be invoked or indexed. A opening
parentheses or bracket following these tokens will be recorded as the start
of a function invocation or indexing operation.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">CALLABLE: </span><span class="p">[</span><span class="s1">&#39;IDENTIFIER&#39;</span><span class="p">,</span> <span class="s1">&#39;SUPER&#39;</span><span class="p">,</span> <span class="s1">&#39;)&#39;</span><span class="p">,</span> <span class="s1">&#39;]&#39;</span><span class="p">,</span> <span class="s1">&#39;}&#39;</span><span class="p">,</span> <span class="s1">&#39;STRING&#39;</span><span class="p">,</span> <span class="s1">&#39;@&#39;</span><span class="p">,</span> <span class="s1">&#39;THIS&#39;</span><span class="p">,</span> <span class="s1">&#39;?&#39;</span><span class="p">,</span> <span class="s1">&#39;::&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-50">#</a> </div> <p>Tokens that, when immediately preceding a <code>WHEN</code>, indicate that the <code>WHEN</code>
occurs at the start of a line. We disambiguate these from trailing whens to
avoid an ambiguity in the grammar.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">LINE_BREAK: </span><span class="p">[</span><span class="s1">&#39;INDENT&#39;</span><span class="p">,</span> <span class="s1">&#39;OUTDENT&#39;</span><span class="p">,</span> <span class="s1">&#39;TERMINATOR&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-51">#</a> </div> <p>Half-assignments...</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">HALF_ASSIGNMENTS: </span><span class="p">[</span><span class="s1">&#39;-&#39;</span><span class="p">,</span> <span class="s1">&#39;+&#39;</span><span class="p">,</span> <span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="s1">&#39;*&#39;</span><span class="p">,</span> <span class="s1">&#39;%&#39;</span><span class="p">,</span> <span class="s1">&#39;||&#39;</span><span class="p">,</span> <span class="s1">&#39;&amp;&amp;&#39;</span><span class="p">,</span> <span class="s1">&#39;?&#39;</span><span class="p">,</span> <span class="s1">&#39;OP?&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-52"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-52">#</a> </div> <p>Conversions from CoffeeScript operators into JavaScript ones.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">CONVERSIONS: </span><span class="p">{</span>
<span class="s1">&#39;and&#39;</span><span class="o">:</span> <span class="s1">&#39;&amp;&amp;&#39;</span>
<span class="s1">&#39;or&#39;</span><span class="o">:</span> <span class="s1">&#39;||&#39;</span>
<span class="s1">&#39;is&#39;</span><span class="o">:</span> <span class="s1">&#39;==&#39;</span>
<span class="s1">&#39;isnt&#39;</span><span class="o">:</span> <span class="s1">&#39;!=&#39;</span>
<span class="s1">&#39;not&#39;</span><span class="o">:</span> <span class="s1">&#39;!&#39;</span>
<span class="p">}</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,72 @@
<!DOCTYPE html> <html> <head> <title>optparse.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="cake.html"> cake.coffee </a> <a class="source" href="coffee-script.html"> coffee-script.coffee </a> <a class="source" href="command.html"> command.coffee </a> <a class="source" href="grammar.html"> grammar.coffee </a> <a class="source" href="helpers.html"> helpers.coffee </a> <a class="source" href="index.html"> index.coffee </a> <a class="source" href="lexer.html"> lexer.coffee </a> <a class="source" href="nodes.html"> nodes.coffee </a> <a class="source" href="optparse.html"> optparse.coffee </a> <a class="source" href="repl.html"> repl.coffee </a> <a class="source" href="rewriter.html"> rewriter.coffee </a> <a class="source" href="scope.html"> scope.coffee </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> optparse.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-1">#</a> </div> <p>A simple <strong>OptionParser</strong> class to parse option flags from the command-line.
Use it like so:</p>
<pre><code>parser: new OptionParser switches, helpBanner
options: parser.parse process.argv
</code></pre>
<p>The first non-option is considered to be the start of the file (and file
option) list, and all subsequent arguments are left unparsed.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.OptionParser: </span><span class="nx">class</span> <span class="nx">OptionParser</span></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>Initialize with a list of valid options, in the form:</p>
<pre><code>[short-flag, long-flag, description]
</code></pre>
<p>Along with an an optional banner for the usage help.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">constructor: </span><span class="p">(</span><span class="nx">rules</span><span class="p">,</span> <span class="nx">banner</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@banner: </span> <span class="nx">banner</span>
<span class="vi">@rules: </span> <span class="nx">buildRules</span><span class="p">(</span><span class="nx">rules</span><span class="p">)</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <p>Parse the list of arguments, populating an <code>options</code> object with all of the
specified options, and returning it. <code>options.arguments</code> will be an array
containing the remaning non-option arguments. This is a simpler API than
many option parsers that allow you to attach callback actions for every
flag. Instead, you're responsible for interpreting the options object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">parse: </span><span class="p">(</span><span class="nx">args</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">options: </span><span class="p">{</span><span class="nv">arguments: </span><span class="p">[]}</span>
<span class="nv">args: </span><span class="nx">normalizeArguments</span> <span class="nx">args</span>
<span class="k">for</span> <span class="nx">arg</span><span class="p">,</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">args</span>
<span class="nv">isOption: </span><span class="o">!!</span><span class="p">(</span><span class="nx">arg</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">LONG_FLAG</span><span class="p">)</span> <span class="o">or</span> <span class="nx">arg</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">SHORT_FLAG</span><span class="p">))</span>
<span class="nv">matchedRule: </span><span class="kc">no</span>
<span class="k">for</span> <span class="nx">rule</span> <span class="k">in</span> <span class="nx">@rules</span>
<span class="k">if</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">shortFlag</span> <span class="o">is</span> <span class="nx">arg</span> <span class="o">or</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">longFlag</span> <span class="o">is</span> <span class="nx">arg</span>
<span class="nx">options</span><span class="p">[</span><span class="nx">rule</span><span class="p">.</span><span class="nx">name</span><span class="p">]</span><span class="o">:</span> <span class="k">if</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">hasArgument</span> <span class="k">then</span> <span class="nx">args</span><span class="p">[</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="k">else</span> <span class="kc">true</span>
<span class="nv">matchedRule: </span><span class="kc">yes</span>
<span class="k">break</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s2">&quot;unrecognized option: $arg&quot;</span> <span class="k">if</span> <span class="nx">isOption</span> <span class="o">and</span> <span class="o">not</span> <span class="nx">matchedRule</span>
<span class="k">if</span> <span class="o">not</span> <span class="nx">isOption</span>
<span class="nv">options.arguments: </span><span class="nx">args</span><span class="p">[</span><span class="nx">i</span><span class="p">...</span><span class="nx">args</span><span class="p">.</span><span class="nx">length</span><span class="p">]</span>
<span class="k">break</span>
<span class="nx">options</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>Return the help text for this <strong>OptionParser</strong>, listing and describing all
of the valid options, for <code>--help</code> and such.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">help: </span><span class="o">-&gt;</span>
<span class="nv">lines: </span><span class="p">[</span><span class="s1">&#39;Available options:&#39;</span><span class="p">]</span>
<span class="nx">lines</span><span class="p">.</span><span class="nx">unshift</span> <span class="s2">&quot;$@banner\n&quot;</span> <span class="k">if</span> <span class="nx">@banner</span>
<span class="k">for</span> <span class="nx">rule</span> <span class="k">in</span> <span class="nx">@rules</span>
<span class="nv">spaces: </span> <span class="mi">15</span> <span class="o">-</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">longFlag</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">spaces: </span> <span class="k">if</span> <span class="nx">spaces</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="k">then</span> <span class="p">(</span><span class="s1">&#39; &#39;</span> <span class="k">for</span> <span class="nx">i</span> <span class="k">in</span> <span class="p">[</span><span class="mi">0</span><span class="p">..</span><span class="nx">spaces</span><span class="p">]).</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="k">else</span> <span class="s1">&#39;&#39;</span>
<span class="nv">letPart: </span><span class="k">if</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">shortFlag</span> <span class="k">then</span> <span class="nx">rule</span><span class="p">.</span><span class="nx">shortFlag</span> <span class="o">+</span> <span class="s1">&#39;, &#39;</span> <span class="k">else</span> <span class="s1">&#39; &#39;</span>
<span class="nx">lines</span><span class="p">.</span><span class="nx">push</span> <span class="s2">&quot; $letPart$rule.longFlag$spaces$rule.description&quot;</span>
<span class="s2">&quot;\n${ lines.join(&#39;\n&#39;) }\n&quot;</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <h2>Helpers</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>Regex matchers for option flags.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">LONG_FLAG: </span> <span class="sr">/^(--\w[\w\-]+)/</span>
<span class="nv">SHORT_FLAG: </span><span class="sr">/^(-\w)/</span>
<span class="nv">MULTI_FLAG: </span><span class="sr">/^-(\w{2,})/</span>
<span class="nv">OPTIONAL: </span> <span class="sr">/\[(.+)\]/</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>Build and return the list of option rules. If the optional <em>short-flag</em> is
unspecified, leave it out by padding with <code>null</code>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">buildRules: </span><span class="p">(</span><span class="nx">rules</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">for</span> <span class="nx">tuple</span> <span class="k">in</span> <span class="nx">rules</span>
<span class="nx">tuple</span><span class="p">.</span><span class="nx">unshift</span> <span class="kc">null</span> <span class="k">if</span> <span class="nx">tuple</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="mi">3</span>
<span class="nx">buildRule</span> <span class="nx">tuple</span><span class="p">...</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</a> </div> <p>Build a rule from a <code>-o</code> short flag, a <code>--output [DIR]</code> long flag, and the
description of what the option does.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">buildRule: </span><span class="p">(</span><span class="nx">shortFlag</span><span class="p">,</span> <span class="nx">longFlag</span><span class="p">,</span> <span class="nx">description</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">match: </span> <span class="nx">longFlag</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">OPTIONAL</span><span class="p">)</span>
<span class="nv">longFlag: </span> <span class="nx">longFlag</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">LONG_FLAG</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
<span class="p">{</span>
<span class="nv">name: </span> <span class="nx">longFlag</span><span class="p">.</span><span class="nx">substr</span> <span class="mi">2</span>
<span class="nv">shortFlag: </span> <span class="nx">shortFlag</span>
<span class="nv">longFlag: </span> <span class="nx">longFlag</span>
<span class="nv">description: </span> <span class="nx">description</span>
<span class="nv">hasArgument: </span><span class="o">!!</span><span class="p">(</span><span class="nx">match</span> <span class="o">and</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>Normalize arguments by expanding merged flags into multiple flags. This allows
you to have <code>-wl</code> be the same as <code>--watch --lint</code>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">normalizeArguments: </span><span class="p">(</span><span class="nx">args</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">args: </span><span class="nx">args</span><span class="p">.</span><span class="nx">slice</span> <span class="mi">0</span>
<span class="nv">result: </span><span class="p">[]</span>
<span class="k">for</span> <span class="nx">arg</span> <span class="k">in</span> <span class="nx">args</span>
<span class="k">if</span> <span class="nv">match: </span><span class="nx">arg</span><span class="p">.</span><span class="nx">match</span> <span class="nx">MULTI_FLAG</span>
<span class="nx">result</span><span class="p">.</span><span class="nx">push</span> <span class="s1">&#39;-&#39;</span> <span class="o">+</span> <span class="nx">l</span> <span class="k">for</span> <span class="nx">l</span> <span class="k">in</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="nx">split</span> <span class="s1">&#39;&#39;</span>
<span class="k">else</span>
<span class="nx">result</span><span class="p">.</span><span class="nx">push</span> <span class="nx">arg</span>
<span class="nx">result</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -0,0 +1,25 @@
<!DOCTYPE html> <html> <head> <title>repl.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="cake.html"> cake.coffee </a> <a class="source" href="coffee-script.html"> coffee-script.coffee </a> <a class="source" href="command.html"> command.coffee </a> <a class="source" href="grammar.html"> grammar.coffee </a> <a class="source" href="helpers.html"> helpers.coffee </a> <a class="source" href="index.html"> index.coffee </a> <a class="source" href="lexer.html"> lexer.coffee </a> <a class="source" href="nodes.html"> nodes.coffee </a> <a class="source" href="optparse.html"> optparse.coffee </a> <a class="source" href="repl.html"> repl.coffee </a> <a class="source" href="rewriter.html"> rewriter.coffee </a> <a class="source" href="scope.html"> scope.coffee </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> repl.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-1">#</a> </div> <p>A very simple Read-Eval-Print-Loop. Compiles one line at a time to JavaScript
and evaluates it. Good for simple tests, or poking around the <strong>Node.js</strong> API.
Using it looks like this:</p>
<pre><code>coffee&gt; puts "$num bottles of beer" for num in [99..1]
</code></pre> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>Require the <strong>coffee-script</strong> module to get access to the compiler.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">CoffeeScript: </span><span class="nx">require</span> <span class="s1">&#39;./coffee-script&#39;</span>
<span class="nv">helpers: </span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./helpers&#39;</span><span class="p">).</span><span class="nx">helpers</span>
<span class="nv">readline: </span> <span class="nx">require</span> <span class="s1">&#39;readline&#39;</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <p>Start by opening up <strong>stdio</strong>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">stdio: </span><span class="nx">process</span><span class="p">.</span><span class="nx">openStdin</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>Quick alias for quitting the REPL.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nx">helpers</span><span class="p">.</span><span class="nx">extend</span> <span class="nx">global</span><span class="p">,</span> <span class="p">{</span>
<span class="nv">quit: </span><span class="o">-&gt;</span> <span class="nx">process</span><span class="p">.</span><span class="nx">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>The main REPL function. <strong>run</strong> is called every time a line of code is entered.
Attempt to evaluate the command. If there's an exception, print it out instead
of exiting.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">run: </span><span class="p">(</span><span class="nx">buffer</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">try</span>
<span class="nv">val: </span><span class="nx">CoffeeScript</span><span class="p">.</span><span class="nx">run</span> <span class="nx">buffer</span><span class="p">.</span><span class="nx">toString</span><span class="p">(),</span> <span class="p">{</span><span class="nv">noWrap: </span><span class="kc">true</span><span class="p">,</span> <span class="nv">globals: </span><span class="kc">true</span><span class="p">,</span> <span class="nv">source: </span><span class="s1">&#39;repl&#39;</span><span class="p">}</span>
<span class="nx">puts</span> <span class="nx">inspect</span> <span class="nx">val</span> <span class="k">if</span> <span class="nx">val</span> <span class="o">isnt</span> <span class="kc">undefined</span>
<span class="k">catch</span> <span class="nx">err</span>
<span class="nx">puts</span> <span class="nx">err</span><span class="p">.</span><span class="nx">stack</span> <span class="o">or</span> <span class="nx">err</span><span class="p">.</span><span class="nx">toString</span><span class="p">()</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">prompt</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>Create the REPL by listening to <strong>stdin</strong>.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">repl: </span><span class="nx">readline</span><span class="p">.</span><span class="nx">createInterface</span> <span class="nx">stdio</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">setPrompt</span> <span class="s1">&#39;coffee&gt; &#39;</span>
<span class="nx">stdio</span><span class="p">.</span><span class="nx">addListener</span> <span class="s1">&#39;data&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">buffer</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">repl</span><span class="p">.</span><span class="nx">write</span> <span class="nx">buffer</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">addListener</span> <span class="s1">&#39;close&#39;</span><span class="p">,</span> <span class="o">-&gt;</span> <span class="nx">stdio</span><span class="p">.</span><span class="nx">destroy</span><span class="p">()</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">addListener</span> <span class="s1">&#39;line&#39;</span><span class="p">,</span> <span class="nx">run</span>
<span class="nx">repl</span><span class="p">.</span><span class="nx">prompt</span><span class="p">()</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -0,0 +1,235 @@
<!DOCTYPE html> <html> <head> <title>rewriter.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="cake.html"> cake.coffee </a> <a class="source" href="coffee-script.html"> coffee-script.coffee </a> <a class="source" href="command.html"> command.coffee </a> <a class="source" href="grammar.html"> grammar.coffee </a> <a class="source" href="helpers.html"> helpers.coffee </a> <a class="source" href="index.html"> index.coffee </a> <a class="source" href="lexer.html"> lexer.coffee </a> <a class="source" href="nodes.html"> nodes.coffee </a> <a class="source" href="optparse.html"> optparse.coffee </a> <a class="source" href="repl.html"> repl.coffee </a> <a class="source" href="rewriter.html"> rewriter.coffee </a> <a class="source" href="scope.html"> scope.coffee </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> rewriter.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-1">#</a> </div> <p>The CoffeeScript language has a good deal of optional syntax, implicit syntax,
and shorthand syntax. This can greatly complicate a grammar and bloat
the resulting parse table. Instead of making the parser handle it all, we take
a series of passes over the token stream, using this <strong>Rewriter</strong> to convert
shorthand into the unambiguous long form, add implicit indentation and
parentheses, balance incorrect nestings, and generally clean things up.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>Set up exported variables for both Node.js and the browser.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">if</span> <span class="nx">process</span><span class="o">?</span>
<span class="p">{</span><span class="nx">helpers</span><span class="p">}</span><span class="o">:</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;./helpers&#39;</span><span class="p">)</span>
<span class="k">else</span>
<span class="k">this</span><span class="p">.</span><span class="nv">exports: </span><span class="k">this</span>
<span class="nv">helpers: </span> <span class="k">this</span><span class="p">.</span><span class="nx">helpers</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <p>Import the helpers we need.</p> </td> <td class="code"> <div class="highlight"><pre><span class="p">{</span><span class="nx">include</span><span class="p">}</span><span class="o">:</span> <span class="nx">helpers</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>The <strong>Rewriter</strong> class is used by the <a href="lexer.html">Lexer</a>, directly against
its internal array of tokens.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">exports.Rewriter: </span><span class="nx">class</span> <span class="nx">Rewriter</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>Rewrite the token stream in multiple passes, one logical filter at
a time. This could certainly be changed into a single pass through the
stream, with a big ol' efficient switch, but it's much nicer to work with
like this. The order of these passes matters -- indentation must be
corrected before implicit parentheses can be wrapped around blocks of code.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">rewrite: </span><span class="p">(</span><span class="nx">tokens</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="vi">@tokens: </span><span class="nx">tokens</span>
<span class="nx">@adjustComments</span><span class="p">()</span>
<span class="nx">@removeLeadingNewlines</span><span class="p">()</span>
<span class="nx">@removeMidExpressionNewlines</span><span class="p">()</span>
<span class="nx">@closeOpenCallsAndIndexes</span><span class="p">()</span>
<span class="nx">@addImplicitIndentation</span><span class="p">()</span>
<span class="nx">@addImplicitParentheses</span><span class="p">()</span>
<span class="nx">@ensureBalance</span> <span class="nx">BALANCED_PAIRS</span>
<span class="nx">@rewriteClosingParens</span><span class="p">()</span>
<span class="nx">@tokens</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>Rewrite the token stream, looking one token ahead and behind.
Allow the return value of the block to tell us how many tokens to move
forwards (or backwards) in the stream, to make sure we don't miss anything
as tokens are inserted and removed, and the stream changes length under
our feet.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">scanTokens: </span><span class="p">(</span><span class="nx">block</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">i: </span><span class="mi">0</span>
<span class="nx">loop</span>
<span class="k">break</span> <span class="nx">unless</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span>
<span class="nv">move: </span><span class="nx">block</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">],</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span><span class="p">],</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">],</span> <span class="nx">i</span>
<span class="nv">i: </span><span class="o">+</span> <span class="nx">move</span>
<span class="kc">true</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>Massage newlines and indentations so that comments don't have to be
correctly indented, or appear on a line of their own.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">adjustComments: </span><span class="o">-&gt;</span>
<span class="nx">@scanTokens</span> <span class="p">(</span><span class="nx">prev</span><span class="p">,</span> <span class="nx">token</span><span class="p">,</span> <span class="nx">post</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="o">=&gt;</span>
<span class="k">return</span> <span class="mi">1</span> <span class="nx">unless</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;HERECOMMENT&#39;</span>
<span class="p">[</span><span class="nx">before</span><span class="p">,</span> <span class="nx">after</span><span class="p">]</span><span class="o">:</span> <span class="p">[</span><span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span> <span class="o">-</span> <span class="mi">2</span><span class="p">],</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">2</span><span class="p">]]</span>
<span class="k">if</span> <span class="nx">after</span> <span class="o">and</span> <span class="nx">after</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;INDENT&#39;</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span>
<span class="k">if</span> <span class="nx">before</span> <span class="o">and</span> <span class="nx">before</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;OUTDENT&#39;</span> <span class="o">and</span> <span class="nx">post</span> <span class="o">and</span> <span class="nx">prev</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="nx">post</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;TERMINATOR&#39;</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span> <span class="o">-</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span>
<span class="k">else</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">after</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">prev</span> <span class="o">and</span> <span class="nx">prev</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">not</span> <span class="k">in</span> <span class="p">[</span><span class="s1">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s1">&#39;INDENT&#39;</span><span class="p">,</span> <span class="s1">&#39;OUTDENT&#39;</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">post</span> <span class="o">and</span> <span class="nx">post</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;TERMINATOR&#39;</span> <span class="o">and</span> <span class="nx">after</span> <span class="o">and</span> <span class="nx">after</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;OUTDENT&#39;</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span> <span class="mi">2</span><span class="p">)...)</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span><span class="p">(</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s2">&quot;\n&quot;</span><span class="p">,</span> <span class="nx">prev</span><span class="p">[</span><span class="mi">2</span><span class="p">]])</span>
<span class="k">else</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s2">&quot;\n&quot;</span><span class="p">,</span> <span class="nx">prev</span><span class="p">[</span><span class="mi">2</span><span class="p">]]</span>
<span class="k">return</span> <span class="mi">2</span>
<span class="k">return</span> <span class="mi">1</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</a> </div> <p>Leading newlines would introduce an ambiguity in the grammar, so we
dispatch them here.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">removeLeadingNewlines: </span><span class="o">-&gt;</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">shift</span><span class="p">()</span> <span class="k">while</span> <span class="nx">@tokens</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">and</span> <span class="nx">@tokens</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;TERMINATOR&#39;</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>Some blocks occur in the middle of expressions -- when we're expecting
this, remove their trailing newlines.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">removeMidExpressionNewlines: </span><span class="o">-&gt;</span>
<span class="nx">@scanTokens</span> <span class="p">(</span><span class="nx">prev</span><span class="p">,</span> <span class="nx">token</span><span class="p">,</span> <span class="nx">post</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="o">=&gt;</span>
<span class="k">return</span> <span class="mi">1</span> <span class="nx">unless</span> <span class="nx">post</span> <span class="o">and</span> <span class="nx">include</span><span class="p">(</span><span class="nx">EXPRESSION_CLOSE</span><span class="p">,</span> <span class="nx">post</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">and</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;TERMINATOR&#39;</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span><span class="p">,</span> <span class="mi">1</span>
<span class="k">return</span> <span class="mi">0</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</a> </div> <p>The lexer has tagged the opening parenthesis of a method call, and the
opening bracket of an indexing operation. Match them with their paired
close.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">closeOpenCallsAndIndexes: </span><span class="o">-&gt;</span>
<span class="nv">parens: </span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="nv">brackets: </span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="nx">@scanTokens</span> <span class="p">(</span><span class="nx">prev</span><span class="p">,</span> <span class="nx">token</span><span class="p">,</span> <span class="nx">post</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="o">=&gt;</span>
<span class="k">switch</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">when</span> <span class="s1">&#39;CALL_START&#39;</span> <span class="k">then</span> <span class="nx">parens</span><span class="p">.</span><span class="nx">push</span> <span class="mi">0</span>
<span class="k">when</span> <span class="s1">&#39;INDEX_START&#39;</span> <span class="k">then</span> <span class="nx">brackets</span><span class="p">.</span><span class="nx">push</span> <span class="mi">0</span>
<span class="k">when</span> <span class="s1">&#39;(&#39;</span> <span class="k">then</span> <span class="nx">parens</span><span class="p">[</span><span class="nx">parens</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span><span class="o">:</span> <span class="o">+</span> <span class="mi">1</span>
<span class="k">when</span> <span class="s1">&#39;[&#39;</span> <span class="k">then</span> <span class="nx">brackets</span><span class="p">[</span><span class="nx">brackets</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span><span class="o">:</span> <span class="o">+</span> <span class="mi">1</span>
<span class="k">when</span> <span class="s1">&#39;)&#39;</span>
<span class="k">if</span> <span class="nx">parens</span><span class="p">[</span><span class="nx">parens</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">is</span> <span class="mi">0</span>
<span class="nx">parens</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span>
<span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">:</span> <span class="s1">&#39;CALL_END&#39;</span>
<span class="k">else</span>
<span class="nx">parens</span><span class="p">[</span><span class="nx">parens</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span><span class="o">:</span> <span class="o">-</span> <span class="mi">1</span>
<span class="k">when</span> <span class="s1">&#39;]&#39;</span>
<span class="k">if</span> <span class="nx">brackets</span><span class="p">[</span><span class="nx">brackets</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span>
<span class="nx">brackets</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span>
<span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">:</span> <span class="s1">&#39;INDEX_END&#39;</span>
<span class="k">else</span>
<span class="nx">brackets</span><span class="p">[</span><span class="nx">brackets</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span><span class="o">:</span> <span class="o">-</span> <span class="mi">1</span>
<span class="k">return</span> <span class="mi">1</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-11">#</a> </div> <p>Methods may be optionally called without parentheses, for simple cases.
Insert the implicit parentheses here, so that the parser doesn't have to
deal with them.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">addImplicitParentheses: </span><span class="o">-&gt;</span>
<span class="nv">stack: </span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="nv">closeCalls: </span><span class="p">(</span><span class="nx">i</span><span class="p">)</span> <span class="o">=&gt;</span>
<span class="k">for</span> <span class="nx">tmp</span> <span class="k">in</span> <span class="p">[</span><span class="mi">0</span><span class="p">...</span><span class="nx">stack</span><span class="p">[</span><span class="nx">stack</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]]</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;CALL_END&#39;</span><span class="p">,</span> <span class="s1">&#39;)&#39;</span><span class="p">,</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span><span class="p">][</span><span class="mi">2</span><span class="p">]])</span>
<span class="nv">size: </span><span class="nx">stack</span><span class="p">[</span><span class="nx">stack</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span>
<span class="nx">stack</span><span class="p">[</span><span class="nx">stack</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span><span class="o">:</span> <span class="mi">0</span>
<span class="nx">size</span>
<span class="nx">@scanTokens</span> <span class="p">(</span><span class="nx">prev</span><span class="p">,</span> <span class="nx">token</span><span class="p">,</span> <span class="nx">post</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="o">=&gt;</span>
<span class="nv">tag: </span><span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="nx">stack</span><span class="p">[</span><span class="nx">stack</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">2</span><span class="p">]</span><span class="o">:</span> <span class="o">+</span> <span class="nx">stack</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span> <span class="k">if</span> <span class="nx">tag</span> <span class="o">is</span> <span class="s1">&#39;OUTDENT&#39;</span>
<span class="nv">open: </span><span class="nx">stack</span><span class="p">[</span><span class="nx">stack</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">&gt;</span> <span class="mi">0</span>
<span class="k">if</span> <span class="nx">prev</span> <span class="o">and</span> <span class="nx">prev</span><span class="p">.</span><span class="nx">spaced</span> <span class="o">and</span> <span class="nx">include</span><span class="p">(</span><span class="nx">IMPLICIT_FUNC</span><span class="p">,</span> <span class="nx">prev</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">and</span> <span class="nx">include</span><span class="p">(</span><span class="nx">IMPLICIT_CALL</span><span class="p">,</span> <span class="nx">tag</span><span class="p">)</span> <span class="o">and</span>
<span class="o">not</span> <span class="p">(</span><span class="nx">tag</span> <span class="o">is</span> <span class="s1">&#39;!&#39;</span> <span class="o">and</span> <span class="p">(</span><span class="nx">post</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">in</span> <span class="p">[</span><span class="s1">&#39;IN&#39;</span><span class="p">,</span> <span class="s1">&#39;OF&#39;</span><span class="p">]))</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;CALL_START&#39;</span><span class="p">,</span> <span class="s1">&#39;(&#39;</span><span class="p">,</span> <span class="nx">token</span><span class="p">[</span><span class="mi">2</span><span class="p">]]</span>
<span class="nx">stack</span><span class="p">[</span><span class="nx">stack</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span><span class="o">:</span> <span class="o">+</span> <span class="mi">1</span>
<span class="nx">stack</span><span class="p">.</span><span class="nx">push</span> <span class="mi">0</span> <span class="k">if</span> <span class="nx">include</span><span class="p">(</span><span class="nx">EXPRESSION_START</span><span class="p">,</span> <span class="nx">tag</span><span class="p">)</span>
<span class="k">return</span> <span class="mi">2</span>
<span class="k">if</span> <span class="nx">include</span><span class="p">(</span><span class="nx">EXPRESSION_START</span><span class="p">,</span> <span class="nx">tag</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">tag</span> <span class="o">is</span> <span class="s1">&#39;INDENT&#39;</span> <span class="o">and</span> <span class="o">!</span><span class="nx">token</span><span class="p">.</span><span class="nx">generated</span> <span class="o">and</span> <span class="nx">open</span> <span class="o">and</span> <span class="o">not</span> <span class="p">(</span><span class="nx">prev</span> <span class="o">and</span> <span class="nx">include</span><span class="p">(</span><span class="nx">IMPLICIT_BLOCK</span><span class="p">,</span> <span class="nx">prev</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
<span class="nv">size: </span><span class="nx">closeCalls</span><span class="p">(</span><span class="nx">i</span><span class="p">)</span>
<span class="nx">stack</span><span class="p">.</span><span class="nx">push</span> <span class="mi">0</span>
<span class="k">return</span> <span class="nx">size</span>
<span class="nx">stack</span><span class="p">.</span><span class="nx">push</span> <span class="mi">0</span>
<span class="k">return</span> <span class="mi">1</span>
<span class="k">if</span> <span class="nx">open</span> <span class="o">and</span> <span class="o">!</span><span class="nx">token</span><span class="p">.</span><span class="nx">generated</span> <span class="o">and</span> <span class="nx">prev</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">isnt</span> <span class="s1">&#39;,&#39;</span> <span class="o">and</span> <span class="p">(</span><span class="o">!</span><span class="nx">post</span> <span class="o">or</span> <span class="nx">include</span><span class="p">(</span><span class="nx">IMPLICIT_END</span><span class="p">,</span> <span class="nx">tag</span><span class="p">))</span>
<span class="nv">j: </span><span class="mi">1</span><span class="p">;</span> <span class="nx">j</span><span class="o">++</span> <span class="k">while</span> <span class="p">(</span><span class="nv">nx: </span><span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span> <span class="o">+</span> <span class="nx">j</span><span class="p">])</span><span class="o">?</span> <span class="o">and</span> <span class="nx">include</span><span class="p">(</span><span class="nx">IMPLICIT_END</span><span class="p">,</span> <span class="nx">nx</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">if</span> <span class="nx">nx</span><span class="o">?</span> <span class="o">and</span> <span class="nx">nx</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;,&#39;</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> <span class="k">if</span> <span class="nx">tag</span> <span class="o">is</span> <span class="s1">&#39;TERMINATOR&#39;</span>
<span class="k">else</span>
<span class="nv">size: </span><span class="nx">closeCalls</span><span class="p">(</span><span class="nx">i</span><span class="p">)</span>
<span class="nx">stack</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span> <span class="k">if</span> <span class="nx">tag</span> <span class="o">isnt</span> <span class="s1">&#39;OUTDENT&#39;</span> <span class="o">and</span> <span class="nx">include</span> <span class="nx">EXPRESSION_END</span><span class="p">,</span> <span class="nx">tag</span>
<span class="k">return</span> <span class="nx">size</span>
<span class="k">if</span> <span class="nx">tag</span> <span class="o">isnt</span> <span class="s1">&#39;OUTDENT&#39;</span> <span class="o">and</span> <span class="nx">include</span> <span class="nx">EXPRESSION_END</span><span class="p">,</span> <span class="nx">tag</span>
<span class="nx">stack</span><span class="p">[</span><span class="nx">stack</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">2</span><span class="p">]</span><span class="o">:</span> <span class="o">+</span> <span class="nx">stack</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span>
<span class="k">return</span> <span class="mi">1</span>
<span class="k">return</span> <span class="mi">1</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-12">#</a> </div> <p>Because our grammar is LALR(1), it can't handle some single-line
expressions that lack ending delimiters. The <strong>Rewriter</strong> adds the implicit
blocks, so it doesn't need to. ')' can close a single-line block,
but we need to make sure it's balanced.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">addImplicitIndentation: </span><span class="o">-&gt;</span>
<span class="nx">@scanTokens</span> <span class="p">(</span><span class="nx">prev</span><span class="p">,</span> <span class="nx">token</span><span class="p">,</span> <span class="nx">post</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="o">=&gt;</span>
<span class="k">if</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;ELSE&#39;</span> <span class="o">and</span> <span class="nx">prev</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">isnt</span> <span class="s1">&#39;OUTDENT&#39;</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">@indentation</span><span class="p">(</span><span class="nx">token</span><span class="p">)...</span>
<span class="k">return</span> <span class="mi">2</span>
<span class="k">if</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;CATCH&#39;</span> <span class="o">and</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">2</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;TERMINATOR&#39;</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">@indentation</span><span class="p">(</span><span class="nx">token</span><span class="p">)...</span>
<span class="k">return</span> <span class="mi">4</span>
<span class="k">return</span> <span class="mi">1</span> <span class="nx">unless</span> <span class="nx">include</span><span class="p">(</span><span class="nx">SINGLE_LINERS</span><span class="p">,</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">and</span>
<span class="nx">post</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">isnt</span> <span class="s1">&#39;INDENT&#39;</span> <span class="o">and</span>
<span class="o">not</span> <span class="p">(</span><span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;ELSE&#39;</span> <span class="o">and</span> <span class="nx">post</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;IF&#39;</span><span class="p">)</span>
<span class="nv">starter: </span><span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="p">[</span><span class="nx">indent</span><span class="p">,</span> <span class="nx">outdent</span><span class="p">]</span><span class="o">:</span> <span class="nx">@indentation</span> <span class="nx">token</span>
<span class="nv">indent.generated: outdent.generated: </span><span class="kc">true</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">indent</span>
<span class="nv">idx: </span><span class="nx">i</span> <span class="o">+</span> <span class="mi">1</span>
<span class="nv">parens: </span><span class="mi">0</span>
<span class="nx">loop</span>
<span class="nv">idx: </span><span class="o">+</span> <span class="mi">1</span>
<span class="nv">tok: </span><span class="nx">@tokens</span><span class="p">[</span><span class="nx">idx</span><span class="p">]</span>
<span class="nv">pre: </span><span class="nx">@tokens</span><span class="p">[</span><span class="nx">idx</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span>
<span class="k">if</span> <span class="p">(</span><span class="o">not</span> <span class="nx">tok</span> <span class="o">or</span>
<span class="p">(</span><span class="nx">include</span><span class="p">(</span><span class="nx">SINGLE_CLOSERS</span><span class="p">,</span> <span class="nx">tok</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">and</span> <span class="nx">tok</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">isnt</span> <span class="s1">&#39;;&#39;</span> <span class="o">and</span> <span class="nx">parens</span> <span class="o">is</span> <span class="mi">0</span><span class="p">)</span> <span class="o">or</span>
<span class="p">(</span><span class="nx">tok</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;)&#39;</span> <span class="o">and</span> <span class="nx">parens</span> <span class="o">is</span> <span class="mi">0</span><span class="p">))</span> <span class="o">and</span>
<span class="o">not</span> <span class="p">(</span><span class="nx">tok</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;ELSE&#39;</span> <span class="o">and</span> <span class="nx">starter</span> <span class="o">not</span> <span class="k">in</span> <span class="p">[</span><span class="s1">&#39;IF&#39;</span><span class="p">,</span> <span class="s1">&#39;THEN&#39;</span><span class="p">])</span>
<span class="nv">insertion: </span><span class="k">if</span> <span class="nx">pre</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s2">&quot;,&quot;</span> <span class="k">then</span> <span class="nx">idx</span> <span class="o">-</span> <span class="mi">1</span> <span class="k">else</span> <span class="nx">idx</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">insertion</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">outdent</span>
<span class="k">break</span>
<span class="nv">parens: </span><span class="o">+</span> <span class="mi">1</span> <span class="k">if</span> <span class="nx">tok</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;(&#39;</span>
<span class="nv">parens: </span><span class="o">-</span> <span class="mi">1</span> <span class="k">if</span> <span class="nx">tok</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;)&#39;</span>
<span class="k">return</span> <span class="mi">1</span> <span class="nx">unless</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="s1">&#39;THEN&#39;</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span><span class="p">,</span> <span class="mi">1</span>
<span class="k">return</span> <span class="mi">0</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-13">#</a> </div> <p>Ensure that all listed pairs of tokens are correctly balanced throughout
the course of the token stream.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">ensureBalance: </span><span class="p">(</span><span class="nx">pairs</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nv">levels: </span><span class="p">{}</span>
<span class="nv">openLine: </span><span class="p">{}</span>
<span class="nx">@scanTokens</span> <span class="p">(</span><span class="nx">prev</span><span class="p">,</span> <span class="nx">token</span><span class="p">,</span> <span class="nx">post</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="o">=&gt;</span>
<span class="k">for</span> <span class="nx">pair</span> <span class="k">in</span> <span class="nx">pairs</span>
<span class="p">[</span><span class="nx">open</span><span class="p">,</span> <span class="nx">close</span><span class="p">]</span><span class="o">:</span> <span class="nx">pair</span>
<span class="nx">levels</span><span class="p">[</span><span class="nx">open</span><span class="p">]</span><span class="o">:</span> <span class="o">or</span> <span class="mi">0</span>
<span class="k">if</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="nx">open</span>
<span class="nx">openLine</span><span class="p">[</span><span class="nx">open</span><span class="p">]</span><span class="o">:</span> <span class="nx">token</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="k">if</span> <span class="nx">levels</span><span class="p">[</span><span class="nx">open</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span>
<span class="nx">levels</span><span class="p">[</span><span class="nx">open</span><span class="p">]</span><span class="o">:</span> <span class="o">+</span> <span class="mi">1</span>
<span class="nx">levels</span><span class="p">[</span><span class="nx">open</span><span class="p">]</span><span class="o">:</span> <span class="o">-</span> <span class="mi">1</span> <span class="k">if</span> <span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="nx">close</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s2">&quot;too many ${token[1]} on line ${token[2] + 1}&quot;</span><span class="p">)</span> <span class="k">if</span> <span class="nx">levels</span><span class="p">[</span><span class="nx">open</span><span class="p">]</span> <span class="o">&lt;</span> <span class="mi">0</span>
<span class="k">return</span> <span class="mi">1</span>
<span class="nv">unclosed: </span><span class="nx">key</span> <span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">value</span> <span class="k">of</span> <span class="nx">levels</span> <span class="k">when</span> <span class="nx">value</span> <span class="o">&gt;</span> <span class="mi">0</span>
<span class="k">if</span> <span class="nx">unclosed</span><span class="p">.</span><span class="nx">length</span>
<span class="nv">open: </span><span class="nx">unclosed</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="nv">line: </span><span class="nx">openLine</span><span class="p">[</span><span class="nx">open</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span> <span class="s2">&quot;unclosed $open on line $line&quot;</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-14">#</a> </div> <p>We'd like to support syntax like this:</p>
<pre><code>el.click((event) -&gt;
el.hide())
</code></pre>
<p>In order to accomplish this, move outdents that follow closing parens
inwards, safely. The steps to accomplish this are:</p>
<ol>
<li>Check that all paired tokens are balanced and in order.</li>
<li>Rewrite the stream with a stack: if you see an <code>EXPRESSION_START</code>, add it
to the stack. If you see an <code>EXPRESSION_END</code>, pop the stack and replace
it with the inverse of what we've just popped.</li>
<li>Keep track of "debt" for tokens that we manufacture, to make sure we end
up balanced in the end.</li>
<li>Be careful not to alter array or parentheses delimiters with overzealous
rewriting.</li>
</ol> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">rewriteClosingParens: </span><span class="o">-&gt;</span>
<span class="nv">stack: </span><span class="p">[]</span>
<span class="nv">debt: </span> <span class="p">{}</span>
<span class="p">(</span><span class="nx">debt</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span><span class="o">:</span> <span class="mi">0</span><span class="p">)</span> <span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="k">of</span> <span class="nx">INVERSES</span>
<span class="nx">@scanTokens</span> <span class="p">(</span><span class="nx">prev</span><span class="p">,</span> <span class="nx">token</span><span class="p">,</span> <span class="nx">post</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="o">=&gt;</span>
<span class="nv">tag: </span><span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="nv">inv: </span><span class="nx">INVERSES</span><span class="p">[</span><span class="nx">token</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span>
<span class="k">if</span> <span class="nx">include</span> <span class="nx">EXPRESSION_START</span><span class="p">,</span> <span class="nx">tag</span>
<span class="nx">stack</span><span class="p">.</span><span class="nx">push</span> <span class="nx">token</span>
<span class="k">return</span> <span class="mi">1</span>
<span class="k">else</span> <span class="k">if</span> <span class="nx">include</span> <span class="nx">EXPRESSION_END</span><span class="p">,</span> <span class="nx">tag</span>
<span class="k">if</span> <span class="nx">debt</span><span class="p">[</span><span class="nx">inv</span><span class="p">]</span> <span class="o">&gt;</span> <span class="mi">0</span>
<span class="nx">debt</span><span class="p">[</span><span class="nx">inv</span><span class="p">]</span><span class="o">:</span> <span class="o">-</span> <span class="mi">1</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span><span class="p">,</span> <span class="mi">1</span>
<span class="k">return</span> <span class="mi">0</span>
<span class="k">else</span>
<span class="nv">match: </span><span class="nx">stack</span><span class="p">.</span><span class="nx">pop</span><span class="p">()</span>
<span class="nv">mtag: </span> <span class="nx">match</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="nv">oppos: </span><span class="nx">INVERSES</span><span class="p">[</span><span class="nx">mtag</span><span class="p">]</span>
<span class="k">return</span> <span class="mi">1</span> <span class="k">if</span> <span class="nx">tag</span> <span class="o">is</span> <span class="nx">oppos</span>
<span class="nx">debt</span><span class="p">[</span><span class="nx">mtag</span><span class="p">]</span><span class="o">:</span> <span class="o">+</span> <span class="mi">1</span>
<span class="nv">val: </span><span class="p">[</span><span class="nx">oppos</span><span class="p">,</span> <span class="k">if</span> <span class="nx">mtag</span> <span class="o">is</span> <span class="s1">&#39;INDENT&#39;</span> <span class="k">then</span> <span class="nx">match</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">else</span> <span class="nx">oppos</span><span class="p">]</span>
<span class="k">if</span> <span class="nx">@tokens</span><span class="p">[</span><span class="nx">i</span> <span class="o">+</span> <span class="mi">2</span><span class="p">]</span><span class="o">?</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">is</span> <span class="nx">mtag</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span> <span class="o">+</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">val</span>
<span class="nx">stack</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">match</span><span class="p">)</span>
<span class="k">else</span>
<span class="nx">@tokens</span><span class="p">.</span><span class="nx">splice</span> <span class="nx">i</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">val</span>
<span class="k">return</span> <span class="mi">1</span>
<span class="k">else</span>
<span class="k">return</span> <span class="mi">1</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-15">#</a> </div> <p>Generate the indentation tokens, based on another token on the same line.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">indentation: </span><span class="p">(</span><span class="nx">token</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="p">[[</span><span class="s1">&#39;INDENT&#39;</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="nx">token</span><span class="p">[</span><span class="mi">2</span><span class="p">]],</span> <span class="p">[</span><span class="s1">&#39;OUTDENT&#39;</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="nx">token</span><span class="p">[</span><span class="mi">2</span><span class="p">]]]</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-16">#</a> </div> <h2>Constants</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-17">#</a> </div> <p>List of the token pairs that must be balanced.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">BALANCED_PAIRS: </span><span class="p">[[</span><span class="s1">&#39;(&#39;</span><span class="p">,</span> <span class="s1">&#39;)&#39;</span><span class="p">],</span> <span class="p">[</span><span class="s1">&#39;[&#39;</span><span class="p">,</span> <span class="s1">&#39;]&#39;</span><span class="p">],</span> <span class="p">[</span><span class="s1">&#39;{&#39;</span><span class="p">,</span> <span class="s1">&#39;}&#39;</span><span class="p">],</span> <span class="p">[</span><span class="s1">&#39;INDENT&#39;</span><span class="p">,</span> <span class="s1">&#39;OUTDENT&#39;</span><span class="p">],</span>
<span class="p">[</span><span class="s1">&#39;PARAM_START&#39;</span><span class="p">,</span> <span class="s1">&#39;PARAM_END&#39;</span><span class="p">],</span> <span class="p">[</span><span class="s1">&#39;CALL_START&#39;</span><span class="p">,</span> <span class="s1">&#39;CALL_END&#39;</span><span class="p">],</span> <span class="p">[</span><span class="s1">&#39;INDEX_START&#39;</span><span class="p">,</span> <span class="s1">&#39;INDEX_END&#39;</span><span class="p">]]</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-18">#</a> </div> <p>The inverse mappings of <code>BALANCED_PAIRS</code> we're trying to fix up, so we can
look things up from either end.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">INVERSES: </span><span class="p">{}</span>
<span class="k">for</span> <span class="nx">pair</span> <span class="k">in</span> <span class="nx">BALANCED_PAIRS</span>
<span class="nx">INVERSES</span><span class="p">[</span><span class="nx">pair</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span><span class="o">:</span> <span class="nx">pair</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="nx">INVERSES</span><span class="p">[</span><span class="nx">pair</span><span class="p">[</span><span class="mi">1</span><span class="p">]]</span><span class="o">:</span> <span class="nx">pair</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-19">#</a> </div> <p>The tokens that signal the start of a balanced pair.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">EXPRESSION_START: </span><span class="nx">pair</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="nx">pair</span> <span class="k">in</span> <span class="nx">BALANCED_PAIRS</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-20">#</a> </div> <p>The tokens that signal the end of a balanced pair.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">EXPRESSION_END: </span> <span class="nx">pair</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="nx">pair</span> <span class="k">in</span> <span class="nx">BALANCED_PAIRS</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-21">#</a> </div> <p>Tokens that indicate the close of a clause of an expression.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">EXPRESSION_CLOSE: </span><span class="p">[</span><span class="s1">&#39;CATCH&#39;</span><span class="p">,</span> <span class="s1">&#39;WHEN&#39;</span><span class="p">,</span> <span class="s1">&#39;ELSE&#39;</span><span class="p">,</span> <span class="s1">&#39;FINALLY&#39;</span><span class="p">].</span><span class="nx">concat</span> <span class="nx">EXPRESSION_END</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-22">#</a> </div> <p>Tokens that, if followed by an <code>IMPLICIT_CALL</code>, indicate a function invocation.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IMPLICIT_FUNC: </span> <span class="p">[</span><span class="s1">&#39;IDENTIFIER&#39;</span><span class="p">,</span> <span class="s1">&#39;SUPER&#39;</span><span class="p">,</span> <span class="s1">&#39;)&#39;</span><span class="p">,</span> <span class="s1">&#39;CALL_END&#39;</span><span class="p">,</span> <span class="s1">&#39;]&#39;</span><span class="p">,</span> <span class="s1">&#39;INDEX_END&#39;</span><span class="p">,</span> <span class="s1">&#39;@&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-23">#</a> </div> <p>If preceded by an <code>IMPLICIT_FUNC</code>, indicates a function invocation.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IMPLICIT_CALL: </span> <span class="p">[</span><span class="s1">&#39;IDENTIFIER&#39;</span><span class="p">,</span> <span class="s1">&#39;NUMBER&#39;</span><span class="p">,</span> <span class="s1">&#39;STRING&#39;</span><span class="p">,</span> <span class="s1">&#39;JS&#39;</span><span class="p">,</span> <span class="s1">&#39;REGEX&#39;</span><span class="p">,</span> <span class="s1">&#39;NEW&#39;</span><span class="p">,</span> <span class="s1">&#39;PARAM_START&#39;</span><span class="p">,</span>
<span class="s1">&#39;TRY&#39;</span><span class="p">,</span> <span class="s1">&#39;DELETE&#39;</span><span class="p">,</span> <span class="s1">&#39;TYPEOF&#39;</span><span class="p">,</span> <span class="s1">&#39;SWITCH&#39;</span><span class="p">,</span>
<span class="s1">&#39;TRUE&#39;</span><span class="p">,</span> <span class="s1">&#39;FALSE&#39;</span><span class="p">,</span> <span class="s1">&#39;YES&#39;</span><span class="p">,</span> <span class="s1">&#39;NO&#39;</span><span class="p">,</span> <span class="s1">&#39;ON&#39;</span><span class="p">,</span> <span class="s1">&#39;OFF&#39;</span><span class="p">,</span> <span class="s1">&#39;!&#39;</span><span class="p">,</span> <span class="s1">&#39;!!&#39;</span><span class="p">,</span>
<span class="s1">&#39;THIS&#39;</span><span class="p">,</span> <span class="s1">&#39;NULL&#39;</span><span class="p">,</span>
<span class="s1">&#39;@&#39;</span><span class="p">,</span> <span class="s1">&#39;-&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;=&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;[&#39;</span><span class="p">,</span> <span class="s1">&#39;(&#39;</span><span class="p">,</span> <span class="s1">&#39;{&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-24">#</a> </div> <p>Tokens indicating that the implicit call must enclose a block of expressions.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IMPLICIT_BLOCK: </span><span class="p">[</span><span class="s1">&#39;-&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;=&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;{&#39;</span><span class="p">,</span> <span class="s1">&#39;[&#39;</span><span class="p">,</span> <span class="s1">&#39;,&#39;</span><span class="p">]</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-25">#</a> </div> <p>Tokens that always mark the end of an implicit call for single-liners.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">IMPLICIT_END: </span> <span class="p">[</span><span class="s1">&#39;IF&#39;</span><span class="p">,</span> <span class="s1">&#39;UNLESS&#39;</span><span class="p">,</span> <span class="s1">&#39;FOR&#39;</span><span class="p">,</span> <span class="s1">&#39;WHILE&#39;</span><span class="p">,</span> <span class="s1">&#39;UNTIL&#39;</span><span class="p">,</span> <span class="s1">&#39;LOOP&#39;</span><span class="p">,</span> <span class="s1">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s1">&#39;INDENT&#39;</span><span class="p">].</span><span class="nx">concat</span> <span class="nx">EXPRESSION_END</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-26">#</a> </div> <p>Single-line flavors of block expressions that have unclosed endings.
The grammar can't disambiguate them, so we insert the implicit indentation.</p> </td> <td class="code"> <div class="highlight"><pre><span class="nv">SINGLE_LINERS: </span><span class="p">[</span><span class="s1">&#39;ELSE&#39;</span><span class="p">,</span> <span class="s2">&quot;-&gt;&quot;</span><span class="p">,</span> <span class="s2">&quot;=&gt;&quot;</span><span class="p">,</span> <span class="s1">&#39;TRY&#39;</span><span class="p">,</span> <span class="s1">&#39;FINALLY&#39;</span><span class="p">,</span> <span class="s1">&#39;THEN&#39;</span><span class="p">]</span>
<span class="nv">SINGLE_CLOSERS: </span><span class="p">[</span><span class="s1">&#39;TERMINATOR&#39;</span><span class="p">,</span> <span class="s1">&#39;CATCH&#39;</span><span class="p">,</span> <span class="s1">&#39;FINALLY&#39;</span><span class="p">,</span> <span class="s1">&#39;ELSE&#39;</span><span class="p">,</span> <span class="s1">&#39;OUTDENT&#39;</span><span class="p">,</span> <span class="s1">&#39;LEADING_WHEN&#39;</span><span class="p">]</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

View File

@@ -0,0 +1,48 @@
<!DOCTYPE html> <html> <head> <title>scope.coffee</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <div id="jump_to"> Jump To &hellip; <div id="jump_wrapper"> <div id="jump_page"> <a class="source" href="cake.html"> cake.coffee </a> <a class="source" href="coffee-script.html"> coffee-script.coffee </a> <a class="source" href="command.html"> command.coffee </a> <a class="source" href="grammar.html"> grammar.coffee </a> <a class="source" href="helpers.html"> helpers.coffee </a> <a class="source" href="index.html"> index.coffee </a> <a class="source" href="lexer.html"> lexer.coffee </a> <a class="source" href="nodes.html"> nodes.coffee </a> <a class="source" href="optparse.html"> optparse.coffee </a> <a class="source" href="repl.html"> repl.coffee </a> <a class="source" href="rewriter.html"> rewriter.coffee </a> <a class="source" href="scope.html"> scope.coffee </a> </div> </div> </div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> scope.coffee </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-1">#</a> </div> <p>The <strong>Scope</strong> class regulates lexical scoping within CoffeeScript. As you
generate code, you create a tree of scopes in the same shape as the nested
function bodies. Each scope knows about the variables declared within it,
and has a reference to its parent enclosing scope. In this way, we know which
variables are new and need to be declared with <code>var</code>, and which are shared
with the outside.</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-2">#</a> </div> <p>Set up exported variables for both <strong>Node.js</strong> and the browser.</p> </td> <td class="code"> <div class="highlight"><pre><span class="k">this</span><span class="p">.</span><span class="nv">exports: </span><span class="k">this</span> <span class="nx">unless</span> <span class="nx">process</span><span class="o">?</span>
<span class="nv">exports.Scope: </span><span class="nx">class</span> <span class="nx">Scope</span></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-3">#</a> </div> <p>The top-level <strong>Scope</strong> object.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="vi">@root: </span><span class="kc">null</span></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-4">#</a> </div> <p>Initialize a scope with its parent, for lookups up the chain,
as well as a reference to the <strong>Expressions</strong> node is belongs to, which is
where it should declare its variables, and a reference to the function that
it wraps.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">constructor: </span><span class="p">(</span><span class="nx">parent</span><span class="p">,</span> <span class="nx">expressions</span><span class="p">,</span> <span class="nx">method</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="p">[</span><span class="nx">@parent</span><span class="p">,</span> <span class="nx">@expressions</span><span class="p">,</span> <span class="nx">@method</span><span class="p">]</span><span class="o">:</span> <span class="p">[</span><span class="nx">parent</span><span class="p">,</span> <span class="nx">expressions</span><span class="p">,</span> <span class="nx">method</span><span class="p">]</span>
<span class="vi">@variables: </span><span class="p">{}</span>
<span class="k">if</span> <span class="nx">@parent</span>
<span class="vi">@tempVar: </span><span class="nx">@parent</span><span class="p">.</span><span class="nx">tempVar</span>
<span class="k">else</span>
<span class="nv">Scope.root: </span><span class="k">this</span>
<span class="vi">@tempVar: </span><span class="s1">&#39;_a&#39;</span></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-5">#</a> </div> <p>Look up a variable name in lexical scope, and declare it if it does not
already exist.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">find: </span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">true</span> <span class="k">if</span> <span class="nx">@check</span> <span class="nx">name</span>
<span class="nx">@variables</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span><span class="o">:</span> <span class="s1">&#39;var&#39;</span>
<span class="kc">false</span></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-6">#</a> </div> <p>Test variables and return true the first time fn(v, k) returns true</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">any: </span><span class="p">(</span><span class="nx">fn</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">for</span> <span class="nx">v</span><span class="p">,</span> <span class="nx">k</span> <span class="k">of</span> <span class="nx">@variables</span> <span class="k">when</span> <span class="nx">fn</span><span class="p">(</span><span class="nx">v</span><span class="p">,</span> <span class="nx">k</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">true</span>
<span class="k">return</span> <span class="kc">false</span></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-7">#</a> </div> <p>Reserve a variable name as originating from a function parameter for this
scope. No <code>var</code> required for internal references.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">parameter: </span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@variables</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span><span class="o">:</span> <span class="s1">&#39;param&#39;</span></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-8">#</a> </div> <p>Just check to see if a variable has already been declared, without reserving.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">check: </span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="k">return</span> <span class="kc">true</span> <span class="k">if</span> <span class="nx">@variables</span><span class="p">.</span><span class="nx">hasOwnProperty</span> <span class="nx">name</span>
<span class="o">!!</span><span class="p">(</span><span class="nx">@parent</span> <span class="o">and</span> <span class="nx">@parent</span><span class="p">.</span><span class="nx">check</span><span class="p">(</span><span class="nx">name</span><span class="p">))</span></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-9">#</a> </div> <p>If we need to store an intermediate result, find an available name for a
compiler-generated variable. <code>_a</code>, <code>_b</code>, and so on...</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">freeVariable: </span><span class="o">-&gt;</span>
<span class="k">while</span> <span class="nx">@check</span> <span class="nx">@tempVar</span>
<span class="nv">ordinal: </span><span class="mi">1</span> <span class="o">+</span> <span class="nb">parseInt</span> <span class="nx">@tempVar</span><span class="p">.</span><span class="nx">substr</span><span class="p">(</span><span class="mi">1</span><span class="p">),</span> <span class="mi">36</span>
<span class="vi">@tempVar: </span><span class="s1">&#39;_&#39;</span> <span class="o">+</span> <span class="nx">ordinal</span><span class="p">.</span><span class="nx">toString</span><span class="p">(</span><span class="mi">36</span><span class="p">).</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/\d/g</span><span class="p">,</span> <span class="s1">&#39;a&#39;</span><span class="p">)</span>
<span class="nx">@variables</span><span class="p">[</span><span class="nx">@tempVar</span><span class="p">]</span><span class="o">:</span> <span class="s1">&#39;var&#39;</span>
<span class="nx">@tempVar</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-10">#</a> </div> <p>Ensure that an assignment is made at the top of this scope
(or at the top-level scope, if requested).</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">assign: </span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">@variables</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span><span class="o">:</span> <span class="p">{</span><span class="nv">value: </span><span class="nx">value</span><span class="p">,</span> <span class="nv">assigned: </span><span class="kc">true</span><span class="p">}</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-11">#</a> </div> <p>Does this scope reference any variables that need to be declared in the
given function body?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">hasDeclarations: </span><span class="p">(</span><span class="nx">body</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">body</span> <span class="o">is</span> <span class="nx">@expressions</span> <span class="o">and</span> <span class="nx">@any</span> <span class="p">(</span><span class="nx">k</span><span class="p">,</span> <span class="nx">val</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">val</span> <span class="o">is</span> <span class="s1">&#39;var&#39;</span></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-12">#</a> </div> <p>Does this scope reference any assignments that need to be declared at the
top of the given function body?</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">hasAssignments: </span><span class="p">(</span><span class="nx">body</span><span class="p">)</span> <span class="o">-&gt;</span>
<span class="nx">body</span> <span class="o">is</span> <span class="nx">@expressions</span> <span class="o">and</span> <span class="nx">@any</span> <span class="p">(</span><span class="nx">k</span><span class="p">,</span> <span class="nx">val</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nx">val</span><span class="p">.</span><span class="nx">assigned</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-13">#</a> </div> <p>Return the list of variables first declared in this scope.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">declaredVariables: </span><span class="o">-&gt;</span>
<span class="p">(</span><span class="nx">key</span> <span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="k">of</span> <span class="nx">@variables</span> <span class="k">when</span> <span class="nx">val</span> <span class="o">is</span> <span class="s1">&#39;var&#39;</span><span class="p">).</span><span class="nx">sort</span><span class="p">()</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-14">#</a> </div> <p>Return the list of assignments that are supposed to be made at the top
of this scope.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">assignedVariables: </span><span class="o">-&gt;</span>
<span class="s2">&quot;$key = $val.value&quot;</span> <span class="k">for</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">val</span> <span class="k">of</span> <span class="nx">@variables</span> <span class="k">when</span> <span class="nx">val</span><span class="p">.</span><span class="nx">assigned</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-15">#</a> </div> <p>Compile the JavaScript for all of the variable declarations in this scope.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compiledDeclarations: </span><span class="o">-&gt;</span>
<span class="nx">@declaredVariables</span><span class="p">().</span><span class="nx">join</span> <span class="s1">&#39;, &#39;</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="octowrap"> <a class="octothorpe" href="#section-16">#</a> </div> <p>Compile the JavaScript for all of the variable assignments in this scope.</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nv">compiledAssignments: </span><span class="o">-&gt;</span>
<span class="nx">@assignedVariables</span><span class="p">().</span><span class="nx">join</span> <span class="s1">&#39;, &#39;</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@@ -1,7 +1,7 @@
<%
require 'uv'
def code_for(file, executable=false)
@stripper ||= /(\A\(function\(\)\{\n|\}\)\(\);\Z|^ )/
@stripper ||= /(\A\(function\(\)\{\n|\}\)\(\);\n*\Z|^ )/
return '' unless File.exists?("documentation/js/#{file}.js")
cs = File.read("documentation/coffee/#{file}.coffee")
js = File.read("documentation/js/#{file}.js").gsub(@stripper, '')
@@ -22,14 +22,15 @@
<title>CoffeeScript</title>
<link rel="stylesheet" type="text/css" href="documentation/css/docs.css" />
<link rel="stylesheet" type="text/css" href="documentation/css/idle.css" />
<link rel="shortcut icon" href="documentation/images/favicon.ico" />
</head>
<body>
<body class="minimized">
<div id="fadeout"></div>
<div id="flybar">
<a id="logo" href="#top"> </a>
<div class="navigation">
<div class="navigation toc">
<div class="button">
Table of Contents
</div>
@@ -45,22 +46,24 @@
<a href="#conditionals">Conditionals, Ternaries, and Conditional Assignment</a>
<a href="#aliases">Aliases</a>
<a href="#splats">Splats...</a>
<a href="#arguments">Arguments are Arrays</a>
<a href="#while">While Loops</a>
<a href="#while">While, Until, and Loop</a>
<a href="#comprehensions">Comprehensions (Arrays, Objects, and Ranges)</a>
<a href="#slice_splice">Array Slicing and Splicing with Ranges</a>
<a href="#expressions">Everything is an Expression</a>
<a href="#existence">The Existential Operator</a>
<a href="#inheritance">Inheritance, and Calling Super from a Subclass</a>
<a href="#classes">Classes, Inheritance, and Super</a>
<a href="#pattern_matching">Pattern Matching</a>
<a href="#fat_arrow">Function Binding</a>
<a href="#embedded">Embedded JavaScript</a>
<a href="#switch">Switch/When/Else</a>
<a href="#try">Try/Catch/Finally</a>
<a href="#comparisons">Chained Comparisons</a>
<a href="#interpolation">String and RegExp Interpolation</a>
<a href="#strings">Multiline Strings and Heredocs</a>
<a href="#cake">Cake, and Cakefiles</a>
<a href="#scripts">"text/coffeescript" Script Tags</a>
<a href="#resources">Resources</a>
<a href="#webchat">Web Chat (IRC)</a>
<a href="#change_log">Change Log</a>
</div>
</div>
@@ -70,17 +73,37 @@
</div>
<div class="contents repl_wrapper">
<div class="code">
<textarea id="repl_source">reverse: (string) ->
<div id="repl_source_wrap"><textarea id="repl_source">reverse: (string) ->
string.split('').reverse().join ''
alert reverse '!tpircseeffoC'</textarea>
alert reverse '.eeffoC yrT'</textarea></div>
<pre id="repl_results"></pre>
<button class="compile" onclick="javascript: repl_compile();">compile</button>
<button class="run" onclick="javascript: repl_run();">run</button>
<button class="full_screen">go full screen</button>
<button class="minimize">minimize</button>
<button class="run">run</button>
<br class="clear" />
</div>
</div>
</div>
<div class="navigation annotated">
<div class="button">
Annotated Source
</div>
<div class="contents">
<a href="documentation/docs/grammar.html">Grammar Rules &mdash; src/grammar</a>
<a href="documentation/docs/lexer.html">Lexing Tokens &mdash; src/lexer</a>
<a href="documentation/docs/rewriter.html">The Rewriter &mdash; src/rewriter</a>
<a href="documentation/docs/nodes.html">The Syntax Tree &mdash; src/nodes</a>
<a href="documentation/docs/scope.html">Lexical Scope &mdash; src/scope</a>
<a href="documentation/docs/helpers.html">Helpers &amp; Utility Functions &mdash; src/helpers</a>
<a href="documentation/docs/coffee-script.html">The CoffeeScript Module &mdash; src/coffee-script</a>
<a href="documentation/docs/cake.html">Cake &amp; Cakefiles &mdash; src/cake</a>
<a href="documentation/docs/command.html">"coffee" Command-Line Utility &mdash; src/command</a>
<a href="documentation/docs/optparse.html">Option Parsing &mdash; src/optparse</a>
<a href="documentation/docs/repl.html">Interactive REPL &mdash; src/repl</a>
</div>
</div>
<div id="error" style="display:none;"></div>
</div>
<div class="container">
@@ -101,13 +124,12 @@ alert reverse '!tpircseeffoC'</textarea>
it compiles into clean JavaScript (the good parts) that can use existing
JavaScript libraries seamlessly, and passes through
<a href="http://www.jslint.com/">JSLint</a> without warnings. The compiled
output is quite readable &mdash; pretty-printed, with comments
preserved intact.
output is pretty-printed and quite readable.
</p>
<p>
<b>Latest Version:</b>
<a href="http://github.com/jashkenas/coffee-script/tarball/0.5.0">0.5.0</a>
<a href="http://github.com/jashkenas/coffee-script/tarball/0.7.1">0.7.1</a>
</p>
<h2>
@@ -117,11 +139,11 @@ alert reverse '!tpircseeffoC'</textarea>
<p><i>CoffeeScript on the left, compiled JavaScript output on the right.</i></p>
<%= code_for('overview', 'cubed_list') %>
<%= code_for('overview', 'cubes') %>
<p>
For a longer CoffeeScript example, check out
<a href="documentation/underscore.html">Underscore.coffee</a>, a port
<a href="documentation/docs/underscore.html">Underscore.coffee</a>, a port
of the <a href="http://documentcloud.github.com/underscore/">Underscore.js</a>
library of helper functions. Underscore.coffee can pass the entire Underscore.js
test suite. The CoffeeScript version is faster than the original for a number
@@ -138,18 +160,22 @@ alert reverse '!tpircseeffoC'</textarea>
</h2>
<p>
The CoffeeScript compiler is written in pure CoffeeScript, and is available
The CoffeeScript compiler is written in pure CoffeeScript, using a
<a href="documentation/docs/grammar.html">small DSL</a>
on top of the <a href="http://github.com/zaach/jison">Jison parser generator</a>, and is available
as a <a href="http://nodejs.org/">Node.js</a> utility. The core compiler however,
does not depend on Node, and can be run in other server-side-JavaScript environments,
or in the browser (see "Try CoffeeScript", above).
or in the browser (see "Try CoffeeScript", above). This may be helpful,
as Node only run on flavors of nix, and not Windows, for the time being.
</p>
<p>
To install, first make sure you have a working version of
<a href="http://nodejs.org/">Node.js</a>, 0.1.30 or higher. Then clone the CoffeeScript
To install, first make sure you have a working copy of the latest tagged version of
<a href="http://nodejs.org/">Node.js</a>, currently <b>0.1.90</b> or higher.
Then clone the CoffeeScript
<a href="http://github.com/jashkenas/coffee-script">source repository</a>
from GitHub, or download the latest
release: <a href="http://github.com/jashkenas/coffee-script/tarball/0.5.0">0.5.0</a>.
release: <a href="http://github.com/jashkenas/coffee-script/tarball/0.7.1">0.7.1</a>.
To install the CoffeeScript compiler system-wide
under <tt>/usr/local</tt>, open the directory and run:
</p>
@@ -158,10 +184,18 @@ alert reverse '!tpircseeffoC'</textarea>
sudo bin/cake install</pre>
<p>
This provides the <tt>coffee</tt> command, which can
be used to compile CoffeeScript <tt>.coffee</tt> files into JavaScript, as
well as debug them. The <tt>coffee</tt>
command also provides direct evaluation and an interactive REPL.
Alternatively, if you already have the
<a href="http://npmjs.org/">Node Package Manager</a> installed,
you can use that to grab the latest CoffeeScript:
</p>
<pre>
sudo npm install coffee-script</pre>
<p>
Both of these provide the <tt>coffee</tt> command, which will execute CoffeeScripts
under Node.js by default, but is also used to compile CoffeeScript
<tt>.coffee</tt> files into JavaScript, or to run an an interactive REPL.
When compiling to JavaScript, <tt>coffee</tt> writes the output
as <tt>.js</tt> files in the same directory by default, but output
can be customized with the following options:
@@ -169,22 +203,25 @@ sudo bin/cake install</pre>
<table>
<tr>
<td width="25%"><code>-i, --interactive</code></td>
<td><code>-c, --compile</code></td>
<td>
Launch an interactive CoffeeScript session to try short snippets.
Compile a <tt>.coffee</tt> script into a <tt>.js</tt> JavaScript file
of the same name.
</td>
</tr>
<tr>
<td><code>-r, --run</code></td>
<td width="25%"><code>-i, --interactive</code></td>
<td>
Compile and execute a given CoffeeScript without saving the intermediate
JavaScript.
Launch an interactive CoffeeScript session to try short snippets.
More pleasant if wrapped with
<a href="http://utopia.knoware.nl/~hlub/uck/rlwrap/rlwrap.html">rlwrap</a>.
</td>
</tr>
<tr>
<td><code>-o, --output [DIR]</code></td>
<td>
Write out all compiled JavaScript files into the specified directory.
Use in conjunction with <tt>--compile</tt> or <tt>--watch</tt>.
</td>
</tr>
<tr>
@@ -212,14 +249,22 @@ sudo bin/cake install</pre>
</td>
</tr>
<tr>
<td><code>-e, --eval</code></td>
<td><code>-s, --stdio</code></td>
<td>
Compile and print a little snippet of CoffeeScript directly from the
command line. For example:<br /><tt>coffee -e "square: (x) -> x * x"</tt>
Pipe in CoffeeScript to STDIN and get back JavaScript over STDOUT.
Good for use with processes written in other languages. An example:<br />
<tt>cat src/cake.coffee | coffee -sc</tt>
</td>
</tr>
<tr>
<td><code>-n, --no-wrap</code></td>
<td><code>-e, --eval</code></td>
<td>
Compile and print a little snippet of CoffeeScript directly from the
command line. For example:<br /><tt>coffee -e "puts num for num in [10..1]"</tt>
</td>
</tr>
<tr>
<td><code>--no-wrap</code></td>
<td>
Compile the JavaScript without the top-level function safety wrapper.
(Used for CoffeeScript as a Node.js module.)
@@ -233,18 +278,18 @@ sudo bin/cake install</pre>
</td>
</tr>
<tr>
<td><code>-tr, --tree</code></td>
<td><code>-n, --nodes</code></td>
<td>
Instead of compiling the CoffeeScript, just lex and parse it, and print
out the parse tree:
<pre>
Expressions
Assign
Value "square"
Code "x"
Op *
Value "x"
Value "x"</pre>
<pre class="no_bar">
Expressions
Assign
Value "square"
Code "x"
Op *
Value "x"
Value "x"</pre>
</td>
</tr>
</table>
@@ -254,7 +299,7 @@ sudo bin/cake install</pre>
</p>
<pre>
coffee path/to/script.coffee
coffee -c path/to/script.coffee
coffee --interactive
coffee --watch --lint experimental.coffee
coffee --print app/scripts/*.coffee > concatenation.js</pre>
@@ -295,7 +340,8 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
<p>
You don't need to use parentheses to invoke a function if you're passing
arguments:<br /><tt>print "coffee"</tt>
arguments:<br /><tt>print "coffee"</tt>. Implicit parentheses wrap forwards
to the end of the line, or block expression.
</p>
<p>
@@ -342,6 +388,12 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
and match the two styles.
</p>
<%= code_for('objects_and_arrays', 'song.join(",")') %>
<p>
In JavaScript, you can't use reserved words, like <tt>class</tt>, as properties
of an object, without quoting them as strings. CoffeeScript notices and quotes
them for you, so you don't have to worry about it (say, when using jQuery).
</p>
<%= code_for('objects_reserved') %>
<p>
<span id="lexical_scope" class="bookmark"></span>
@@ -350,7 +402,7 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
are properly declared within lexical scope &mdash; you never need to write
<tt>var</tt> yourself.
</p>
<%= code_for('scope', 'new_num') %>
<%= code_for('scope', 'inner') %>
<p>
Notice how the all of the variable declarations have been pushed up to
the top of the closest scope, the first time they appear.
@@ -359,6 +411,13 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
should not be able to change the value of the external variable of the same name, and
therefore has a declaration of its own.
</p>
<p>
This behavior is effectively identical to Ruby's scope for local variables.
Because you don't have direct access to the <tt>var</tt> keyword,
it's impossible to shadow an outer variable on purpose, you may only refer
to it. So be careful that you're not reusing the name of an external
variable accidentally, if you're writing a deeply nested function.
</p>
<p>
Although suppressed within this documentation for clarity, all
CoffeeScript output is wrapped in an anonymous function:
@@ -388,10 +447,9 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
</p>
<%= code_for('conditionals') %>
<p>
The conditional assignment operators are included: <tt>||=</tt>,
which only assigns a value to a variable if the variable's current value
is falsy, and <tt>&amp;&amp;=</tt>, which only replaces the value of
truthy variables.
You can assign a variable to a half-expression to perform an operation
like Ruby's <tt>||=</tt>, which only assigns a value to a variable
if the variable's current value is falsy.
</p>
<p>
@@ -426,6 +484,10 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
<p>
As a shortcut for <tt>this.property</tt>, you can use <tt>@property</tt>.
</p>
<p>
You can use <tt>in</tt> to test for array presence, and <tt>of</tt> to
test for JavaScript object-key presence.
</p>
<%= code_for('aliases') %>
<p>
@@ -438,19 +500,9 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
</p>
<%= code_for('splats', true) %>
<p>
<span id="arguments" class="bookmark"></span>
<b class="header">Arguments are Arrays</b>
If you reference the <b>arguments object</b> directly, it will be converted
into a real Array, making all of the
<a href="https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Array">Array methods</a>
available.
</p>
<%= code_for('arguments', true) %>
<p>
<span id="while" class="bookmark"></span>
<b class="header">While Loops</b>
<b class="header">While, Until, and Loop</b>
The only low-level loop that CoffeeScript provides is the <b>while</b> loop. The
main difference from JavaScript is that the <b>while</b> loop can be used
as an expression, returning an array containing the result of each iteration
@@ -458,8 +510,10 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
</p>
<%= code_for('while', 'lyrics.join("\n")') %>
<p>
For readability, the <b>until</b> keyword is equivalent to <tt>while not</tt>,
and the <b>loop</b> keyword is equivalent to <tt>while true</tt>.
Other JavaScript loops, such as <b>for</b> loops and <b>do-while</b> loops
can be mimicked by variations on <b>while</b>, but the hope is that you
can be mimicked by variations on <b>loop</b>, but the hope is that you
won't need to do that with CoffeeScript, either because you're using
<b>each</b> (<b>forEach</b>) style iterators, or...
</p>
@@ -478,8 +532,7 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
<p>
If you know the start and end of your loop, or would like to step through
in fixed-size increments, you can use a range to specify the start and
end of your comprehension. (The long line-breaking "for" definitions in
the compiled JS below allow ranges to count downwards, as well as upwards).
end of your comprehension.
</p>
<%= code_for('range_comprehensions', 'countdown') %>
<p>
@@ -499,7 +552,7 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
the slice, and the second is the index of the last one. Three dots signify
a range that excludes the end.
</p>
<%= code_for('slices', 'numbers_copy') %>
<%= code_for('slices', 'copy') %>
<p>
The same syntax can be used with assignment to replace a segment of an
array with new values (to splice it).
@@ -577,8 +630,8 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
</p>
<p>
<span id="inheritance" class="bookmark"></span>
<b class="header">Inheritance, and Calling Super from a Subclass</b>
<span id="classes" class="bookmark"></span>
<b class="header">Classes, Inheritance, and Super</b>
JavaScript's prototypal inheritance has always been a bit of a
brain-bender, with a whole family tree of libraries that provide a cleaner
syntax for classical inheritance on top of JavaScript's prototypes:
@@ -592,12 +645,24 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
set the prototype chain.
</p>
<p>
CoffeeScript provides <tt>extends</tt>
to help with prototype setup, <tt>::</tt> for quick access to an
object's prototype, and converts <tt>super()</tt> into a call against
the immediate ancestor's method of the same name.
Instead of repetitively attaching functions to a prototype, CoffeeScript
provides a basic <tt>class</tt> structure that allows you to name your class,
set the superclass, assign prototypal properties, and define the constructor,
in a single assignable expression.
</p>
<%= code_for('classes', true) %>
<p>
If structuring your prototypes classically isn't your cup of tea, CoffeeScript
provides a couple of lower-level conveniences. The <tt>extends</tt> operator
helps with proper prototype setup, <tt>::</tt> gives you
quick access to an object's prototype, and <tt>super()</tt>
is converted into a call against the immediate ancestor's method of the same name.
</p>
<%= code_for('prototypes', '"one_two".dasherize()') %>
<p>
Finally, you may assign Class-level (static) properties within a class
definition by using<br /><tt>@property: value</tt>
</p>
<%= code_for('super', true) %>
<p>
<span id="pattern_matching" class="bookmark"></span>
@@ -610,7 +675,7 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
on the right to the variables on the left. In the simplest case, it can be
used for parallel assignment:
</p>
<%= code_for('parallel_assignment', 'bait') %>
<%= code_for('parallel_assignment', 'theBait') %>
<p>
But it's also helpful for dealing with functions that return multiple
values.
@@ -620,12 +685,24 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
Pattern matching can be used with any depth of array and object nesting,
to help pull out deeply nested properties.
</p>
<%= code_for('object_extraction', 'poet + " — " + street') %>
<%= code_for('object_extraction', 'name + " — " + street') %>
<p>
Pattern matching can even be combined with splats.
</p>
<%= code_for('patterns_and_splats', 'contents.join("")') %>
<p>
<span id="fat_arrow" class="bookmark"></span>
<b class="header">Function binding</b>
The fat arrow <tt>=></tt> can be used to both define a function, and to bind
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
as callback, or attach it to a different object, the original value of <tt>this</tt>
will be lost. If you're not familiar with this behavior,
<a href="http://www.digital-web.com/articles/scope_in_javascript/">this Digital Web article</a>
gives a good overview of the quirks.
</p>
<p>
The fat arrow <tt>=&gt;</tt> can be used to both define a function, and to bind
it to the current value of <tt>this</tt>, right on the spot. This is helpful
when using callback-based libraries like Prototype or jQuery, for creating
iterator functions to pass to <tt>each</tt>, or event-handler functions
@@ -633,6 +710,11 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
properties of the <tt>this</tt> where they're defined.
</p>
<%= code_for('fat_arrow') %>
<p>
If we had used <tt>-></tt> in the callback above, <tt>@customer</tt> would
have referred to the undefined "customer" property of the DOM element,
and trying to call <tt>purchase()</tt> on it would have raised an exception.
</p>
<p>
<span id="embedded" class="bookmark"></span>
@@ -679,12 +761,26 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
</p>
<%= code_for('comparisons', 'healthy') %>
<p>
<span id="interpolation" class="bookmark"></span>
<b class="header">String and RegExp Interpolation</b>
A version of <a href="http://wiki.ecmascript.org/doku.php?id=strawman:string_interpolation">ECMAScript Harmony's proposed string interpolation</a>
is included in CoffeeScript. Simple variables can be included by marking
them with a dollar sign.
</p>
<%= code_for('interpolation', 'quote') %>
<p>
And arbitrary expressions can be interpolated by using brackets <tt>${ ... }</tt><br />
Interpolation works the same way within regular expressions.
</p>
<%= code_for('interpolation_expression', 'sentence') %>
<p>
<span id="strings" class="bookmark"></span>
<b class="header">Multiline Strings and Heredocs</b>
Multiline strings are allowed in CoffeeScript.
</p>
<%= code_for('strings', 'moby_dick') %>
<%= code_for('strings', 'mobyDick') %>
<p>
Heredocs can be used to hold formatted or indentation-sensitive text
(or, if you just don't feel like escaping quotes and apostrophes). The
@@ -692,6 +788,9 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
you can keep it all aligned with the body of your code.
</p>
<%= code_for('heredocs') %>
<p>
Double-quoted heredocs, like double-quoted strings, allow interpolation.
</p>
<h2>
<span id="cake" class="bookmark"></span>
@@ -714,6 +813,34 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
</p>
<%= code_for('cake_tasks') %>
<h2>
<span id="scripts" class="bookmark"></span>
"text/coffeescript" Script Tags
</h2>
<p>
While it's not recommended for serious use, CoffeeScripts may be included
directly within the browser using <tt>&lt;script type="text/coffeescript"&gt;</tt>
tags. The source includes a compressed and minified version of the compiler
(<a href="extras/coffee-script.js">Download current version here, 43k when gzipped</a>)
as <tt>extras/coffee-script.js</tt>. Include this file on a page with
inline CoffeeScript tags, and it will compile and evaluate them in order.
</p>
<p>
In fact, the little bit of glue script that runs "Try CoffeeScript" above,
as well as jQuery for the menu, is implemented in just this way.
View source and look at the bottom of the page to see the example.
Including the script also gives you access to <tt>CoffeeScript.compile()</tt>
so you can pop open Firebug and try compiling some strings.
</p>
<p>
The usual caveats about CoffeeScript apply &mdash; your inline scripts will
run within a closure wrapper, so if you want to expose global variables or
functions, attach them to the <tt>window</tt> object.
</p>
<h2>
<span id="resources" class="bookmark"></span>
Resources
@@ -726,22 +853,208 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
<tt>bin/cake test</tt> to run the test suite,<br />
<tt>bin/cake build</tt> to rebuild the CoffeeScript compiler, and <br />
<tt>bin/cake build:parser</tt> to regenerate the Jison parser if you're
working on the grammar.
working on the grammar. <br /><br />
<tt>git checkout lib &amp;&amp; bin/cake build:full</tt> is a good command to run when you're working
on the core language. It'll refresh the lib directory
(in case you broke something), build your altered compiler, use that to
rebuild itself (a good sanity test) and then run all of the tests. If
they pass, there's a good chance you've made a successful change.
</li>
<li>
<a href="http://github.com/jashkenas/coffee-script/issues">CoffeeScript Issues</a><br />
Bugs reports, feature requests, and general discussion all belong here.
</li>
<li>
If you'd like to chat, stop by <tt>#coffeescript</tt> on Freenode.
If you'd like to chat, stop by <tt>#coffeescript</tt> on Freenode in the
IRC client of your choice, or on
<a href="http://webchat.freenode.net/">webchat.freenode.net</a>.
</li>
<li>
<b>yeungda</b>'s <a href="http://github.com/yeungda/jcoffeescript">JCoffeeScript</a>
&mdash; A Java Library that uses Rhino to compile CoffeeScript, allowing
compilation within Java projects or on systems that Node.js doesn't support.
</li>
<li>
<b>defunkt</b>'s <a href="http://github.com/defunkt/coffee-mode">CoffeeScript Major Mode</a>
&mdash; a Emacs major mode that provides syntax highlighting, indentation
support, and some bonus commands.
</li>
<li>
<b>jashkenas</b>'s <a href="http://github.com/jashkenas/coffee-script-tmbundle">CoffeeScript TextMate Bundle</a>
&mdash; which provides syntax highlighting, snippet expansion, and the
ability to run bits of CoffeeScript from within TextMate itself.
</li>
<li>
<b>kchmck</b>'s <a href="http://github.com/kchmck/vim-coffee-script">Vim CoffeeScript</a>
&mdash; which adds Vim syntax highlighting and indentation support.
</li>
<li>
<b>wavded</b>'s <a href="http://github.com/wavded/gedit-coffeescript">gedit-coffeescript</a>
&mdash; a CoffeeScript syntax highlighter for the gedit text editor.
</li>
<li>
<b>yeungda</b>'s <a href="http://yeungda.github.com/coffeescript-idea/">coffeescript-idea</a>
&mdash; a plugin for IntelliJ IDEA and RubyMine providing syntax highlighting.
</li>
<li>
<b>mattly</b>'s <a href="http://github.com/mattly/rack-coffee">rack-coffee</a>
&mdash; a small Rack middleware for serving CoffeeScript files as
compiled JavaScript on the fly.
</li>
<li>
<b>jnicklas</b>'s <a href="http://github.com/jnicklas/bistro_car">BistroCar</a>
&mdash; a plugin that serves and bundles CoffeeScript from within your
Rails application.
</li>
<li>
<b>dsc</b>'s <a href="http://github.com/dsc/coffeecup">CoffeeCup</a>
&mdash; A Python WSGI middleware that compiles CoffeeScript to JavaScript
on-demand during development.
</li>
<li>
<b>sutto</b>'s <a href="http://github.com/Sutto/barista">Barista</a>
&mdash; a BistroCar alternative that integrates well with
<a href="http://documentcloud.github.com/jammit">Jammit</a> and Rails 3.
</li>
<li>
<b>inem</b> and <b>gerad</b>'s <a href="http://github.com/gerad/coffee-haml-filter">coffee-haml-filter</a>
&mdash; a custom filter for rendering CoffeeScript inline within
<a href="http://haml-lang.com/">HAML</a> templates.
</li>
<li>
<b>jashkenas</b>'s <a href="http://jashkenas.github.com/docco/">Docco</a>
&mdash; A quick-and-dirty literate-programming-style documentation generator
for CoffeeScript. Used to produce the annotated source.
</li>
</ul>
<h2>
<span id="webchat" class="bookmark"></span>
Web Chat (IRC)
</h2>
<p>
Quick help and advice can usually be found in the CoffeeScript IRC room.
Join <tt>#coffeescript</tt> on <tt>irc.freenode.net</tt>, or click the
button below to open a webchat session on this page.
</p>
<p>
<button id="open_webchat">click to open #coffeescript</button>
</p>
<h2>
<span id="change_log" class="bookmark"></span>
Change Log
</h2>
<p>
<b class="header" style="margin-top: 20px;">0.7.1</b>
Block-style comments are now passed through and printed as JavaScript block
comments -- making them useful for licenses and copyright headers. Better
support for running coffee scripts standalone via hashbangs.
Improved syntax errors for tokens that are not in the grammar.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.7.0</b>
Official CoffeeScript variable style is now camelCase, as in JavaScript.
Reserved words are now allowed as object keys, and will be quoted for you.
Range comprehensions now generate cleaner code, but you have to specify <tt>by -1</tt>
if you'd like to iterate downward. Reporting of syntax errors is greatly
improved from the previous release. Running <tt>coffee</tt> with no arguments
now launches the REPL, with Readline support. The <tt>&lt;-</tt> bind operator
has been removed from CoffeeScript. The <tt>loop</tt> keyword was added,
which is equivalent to a <tt>while true</tt> loop. Comprehensions that contain
closures will now close over their variables, like the semantics of a <tt>forEach</tt>.
You can now use bound function in class definitions (bound to the instance).
For consistency, <tt>a in b</tt> is now an array presence check, and <tt>a of b</tt>
is an object-key check. Comments are no longer passed through to the generated
JavaScript.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.6.2</b>
The <tt>coffee</tt> command will now preserve directory structure when
compiling a directory full of scripts. Fixed two omissions that were preventing
the CoffeeScript compiler from running live within Internet Explorer.
There's now a syntax for block comments, similar in spirit to CoffeeScript's heredocs.
ECMA Harmony DRY-style pattern matching is now supported, where the name
of the property is the same as the name of the value: <tt>{name, length}: func</tt>.
Pattern matching is now allowed within comprehension variables. <tt>unless</tt>
is now allowed in block form. <tt>until</tt> loops were added, as the inverse
of <tt>while</tt> loops. <tt>switch</tt> statements are now allowed without
switch object clauses. Compatible
with Node.js <b>v0.1.95</b>.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.6.1</b>
Upgraded CoffeeScript for compatibility with the new Node.js <b>v0.1.90</b>
series.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.6.0</b>
Trailing commas are now allowed, a-la Python. Static
properties may be assigned directly within class definitions,
using <tt>@property</tt> notation.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.5.6</b>
Interpolation can now be used within regular expressions and heredocs, as well as
strings. Added the <tt>&lt;-</tt> bind operator.
Allowing assignment to half-expressions instead of special <tt>||=</tt>-style
operators. The arguments object is no longer automatically converted into
an array. After requiring <tt>coffee-script</tt>, Node.js can now directly
load <tt>.coffee</tt> files, thanks to <b>registerExtension</b>. Multiple
splats can now be used in function calls, arrays, and pattern matching.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.5.5</b>
String interpolation, contributed by
<a href="http://github.com/StanAngeloff">Stan Angeloff</a>.
Since <tt>--run</tt> has been the default since <b>0.5.3</b>, updating
<tt>--stdio</tt> and <tt>--eval</tt> to run by default, pass <tt>--compile</tt>
as well if you'd like to print the result.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.5.4</b>
Bugfix that corrects the Node.js global constants <tt>__filename</tt> and
<tt>__dirname</tt>. Tweaks for more flexible parsing of nested function
literals and improperly-indented comments. Updates for the latest Node.js API.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.5.3</b>
CoffeeScript now has a syntax for defining classes. Many of the core
components (Nodes, Lexer, Rewriter, Scope, Optparse) are using them.
Cakefiles can use <tt>optparse.coffee</tt> to define options for tasks.
<tt>--run</tt> is now the default flag for the <tt>coffee</tt> command,
use <tt>--compile</tt> to save JavaScripts. Bugfix for an ambiguity between
RegExp literals and chained divisions.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.5.2</b>
Added a compressed version of the compiler for inclusion in web pages as
<br /><tt>extras/coffee-script.js</tt>. It'll automatically run any script tags
with type <tt>text/coffeescript</tt> for you. Added a <tt>--stdio</tt> option
to the <tt>coffee</tt> command, for piped-in compiles.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.5.1</b>
Improvements to null soaking with the existential operator, including
soaks on indexed properties. Added conditions to <tt>while</tt> loops,
so you can use them as filters with <tt>when</tt>, in the same manner as
comprehensions.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.5.0</b>
CoffeeScript 0.5.0 is a major release, While there are no language changes,
@@ -904,32 +1217,63 @@ coffee --print app/scripts/*.coffee > concatenation.js</pre>
</div>
<script type="text/javascript" src="lib/rewriter.js"></script>
<script type="text/javascript" src="lib/lexer.js"></script>
<script type="text/javascript" src="lib/parser.js"></script>
<script type="text/javascript" src="lib/scope.js"></script>
<script type="text/javascript" src="lib/nodes.js"></script>
<script type="text/javascript" src="lib/coffee-script.js"></script>
<script type="text/coffeescript">
# Set up the compilation function, to run when you stop typing.
compile_source: ->
source: $('#repl_source').val()
window.compiled_js: ''
try
window.compiled_js: CoffeeScript.compile source, {noWrap: true}
$('#repl_results').text window.compiled_js
$('#error').hide();
catch error
$('#error').text(error.message).show();
# Listen for keypresses and recompile.
$('#repl_source').keyup -> compile_source()
# Eval the compiled js.
$('button.run').click ->
try
eval window.compiled_js
catch error then alert error
current_nav: null
# Helper to hide the menus.
close_menus: ->
if current_nav
current_nav.removeClass 'active'
document.body.className: 'minimized'
current_nav: null
# Bind navigation buttons to open the menus.
$('.navigation').click (e) ->
return if e.target.tagName.toLowerCase() is 'a'
if this isnt (current_nav and current_nav[0])
close_menus();
current_nav: $(this)
current_nav.addClass 'active'
false
$(document.body).click -> close_menus()
$('.navigation .full_screen').click ->
document.body.className: 'full_screen'
$('.navigation .minimize').click ->
document.body.className: 'minimized'
$('#open_webchat').click ->
$(this).replaceWith $('<iframe src="http://webchat.freenode.net/?channels=coffeescript" width="625" height="400"></iframe>')
compile_source()
<script type="text/javascript">
window.repl_compile = function() {
var source = document.getElementById('repl_source').value;
window.compiled_js = '';
try {
window.compiled_js = CoffeeScript.compile(source, {no_wrap: true});
} catch(error) {
alert(error);
}
document.getElementById('repl_results').innerHTML = window.compiled_js;
}
window.repl_run = function() {
try {
eval(window.compiled_js);
} catch(error) {
alert(error);
}
}
</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script src="extras/coffee-script.js"></script>
</body>
</html>

View File

@@ -1,14 +1,17 @@
(function(){
var volume;
var volume, winner;
if (ignition === true) {
launch();
}
if (band !== spinal_tap) {
if (band !== SpinalTap) {
volume = 10;
}
if (!(answer === false)) {
let_the_wild_rumpus_begin();
letTheWildRumpusBegin();
}
car.speed < limit ? accelerate() : null;
if (47 === pick || 92 === pick || 13 === pick) {
winner = true;
}
car.speed < speed_limit ? accelerate() : null;
print("My name is " + this.name);
})();
})();

View File

@@ -1,8 +0,0 @@
(function(){
var backwards;
backwards = function backwards() {
arguments = Array.prototype.slice.call(arguments, 0);
return alert(arguments.reverse());
};
backwards("stairway", "to", "heaven");
})();

View File

@@ -1,21 +1,19 @@
(function(){
var _a, _b, _c, _d, _e, _f, _g, food, lunch, roid, roid2;
// Eat lunch.
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, food, lunch, roid, roid2;
lunch = (function() {
_a = []; _b = ['toast', 'cheese', 'wine'];
for (_c = 0; _c < _b.length; _c++) {
food = _b[_c];
_a = []; _c = ['toast', 'cheese', 'wine'];
for (_b = 0, _d = _c.length; _b < _d; _b++) {
food = _c[_b];
_a.push(eat(food));
}
return _a;
}).call(this);
// Naive collision detection.
_d = asteroids;
for (_e = 0; _e < _d.length; _e++) {
roid = _d[_e];
_f = asteroids;
for (_g = 0; _g < _f.length; _g++) {
roid2 = _f[_g];
})();
_f = asteroids;
for (_e = 0, _g = _f.length; _e < _g; _e++) {
roid = _f[_e];
_i = asteroids;
for (_h = 0, _j = _i.length; _h < _j; _h++) {
roid2 = _i[_h];
if (roid !== roid2) {
if (roid.overlaps(roid2)) {
roid.explode();
@@ -23,4 +21,4 @@
}
}
}
})();
})();

View File

@@ -2,4 +2,4 @@
var difficulty, greeting;
greeting = "Hello CoffeeScript";
difficulty = 0.5;
})();
})();

View File

@@ -1,14 +1,15 @@
(function(){
process.mixin(require('assert'));
task('test', 'run each of the unit tests', function() {
var _a, _b, _c, test;
_a = []; _b = test_files;
for (_c = 0; _c < _b.length; _c++) {
test = _b[_c];
_a.push(fs.readFile(test, function(err, code) {
return eval(coffee.compile(code));
}));
var _a, _b, _c, _d;
_a = []; _c = files;
for (_b = 0, _d = _c.length; _b < _d; _b++) {
(function() {
var test = _c[_b];
return _a.push(fs.readFile(test, function(err, code) {
return eval(coffee.compile(code));
}));
})();
}
return _a;
});
})();
})();

View File

@@ -0,0 +1,39 @@
(function(){
var Animal, Horse, Snake, sam, tom;
var __extends = function(child, parent) {
var ctor = function(){ };
ctor.prototype = parent.prototype;
child.__superClass__ = parent.prototype;
child.prototype = new ctor();
child.prototype.constructor = child;
};
Animal = function() { };
Animal.prototype.move = function(meters) {
return alert(this.name + " moved " + meters + "m.");
};
Snake = function(name) {
this.name = name;
return this;
};
__extends(Snake, Animal);
Snake.prototype.move = function() {
alert("Slithering...");
return Snake.__superClass__.move.call(this, 5);
};
Horse = function(name) {
this.name = name;
return this;
};
__extends(Horse, Animal);
Horse.prototype.move = function() {
alert("Galloping...");
return Horse.__superClass__.move.call(this, 45);
};
sam = new Snake("Sammy the Python");
tom = new Horse("Tommy the Palomino");
sam.move();
tom.move();
})();

View File

@@ -2,4 +2,4 @@
var cholesterol, healthy;
cholesterol = 127;
healthy = (200 > cholesterol) && (cholesterol > 60);
})();
})();

View File

@@ -1,12 +1,12 @@
(function(){
var date, expensive, mood;
var date, mood, options;
if (singing) {
mood = greatly_improved;
mood = greatlyImproved;
}
if (happy && knows_it) {
claps_hands();
cha_cha_cha();
if (happy && knowsIt) {
clapsHands();
chaChaCha();
}
date = friday ? sue : jill;
expensive = expensive || do_the_math();
})();
options = options || defaultOptions;
})();

View File

@@ -3,4 +3,4 @@
hi = function() {
return [document.title, "Hello JavaScript"].join(": ");
};
})();
})();

View File

@@ -4,4 +4,4 @@
solipsism = true;
}
speed = (typeof speed !== "undefined" && speed !== null) ? speed : 140;
})();
})();

View File

@@ -1,13 +1,17 @@
(function(){
var eldest, grade;
grade = function grade(student) {
if (student.excellent_work) {
grade = function(student) {
if (student.excellentWork) {
return "A+";
} else if (student.okay_stuff) {
return student.tried_hard ? "B" : "B-";
} else if (student.okayStuff) {
if (student.triedHard) {
return "B";
} else {
return "B-";
}
} else {
return "C";
}
};
eldest = 24 > 21 ? "Liz" : "Ike";
})();
})();

View File

@@ -1,4 +1,4 @@
(function(){
var one, six, three, two;
six = ((one = 1)) + ((two = 2)) + ((three = 3));
})();
six = (one = 1) + (two = 2) + (three = 3);
})();

View File

@@ -1,12 +1,11 @@
(function(){
var _a, _b, globals, name;
var __hasProp = Object.prototype.hasOwnProperty;
// The first ten global properties.
globals = (function() {
_a = []; _b = window;
for (name in _b) { if (__hasProp.call(_b, name)) {
_a.push(name);
}}
return _a;
}).call(this).slice(0, 10);
})();
})().slice(0, 10);
})();

View File

@@ -5,5 +5,5 @@
} catch (error) {
return "And the error is ... " + error;
}
}).call(this));
})();
})());
})();

View File

@@ -1,6 +1,6 @@
(function(){
var Account;
Account = function Account(customer, cart) {
Account = function(customer, cart) {
this.customer = customer;
this.cart = cart;
return $('.shopping_cart').bind('click', (function(__this) {
@@ -12,4 +12,4 @@
});
})(this));
};
})();
})();

View File

@@ -1,9 +1,9 @@
(function(){
var cube, square;
square = function square(x) {
square = function(x) {
return x * x;
};
cube = function cube(x) {
cube = function(x) {
return square(x) * x;
};
})();
})();

View File

@@ -1,4 +1,4 @@
(function(){
var html;
html = "<strong>\n cup of coffeescript\n</strong>";
})();
html = '<strong>\n cup of coffeescript\n</strong>';
})();

View File

@@ -0,0 +1,5 @@
(function(){
var author, quote;
author = "Wittgenstein";
quote = ("A picture is a fact. -- " + author);
})();

View File

@@ -0,0 +1,6 @@
(function(){
var dates, sentence, sep;
sentence = ("" + (22 / 7) + " is a decent approximation of π");
sep = "[.\\/\\- ]";
dates = (new RegExp(("\\d+" + sep + "\\d+" + sep + "\\d+"), "g"));
})();

View File

@@ -1,11 +1,10 @@
(function(){
var _a, city, forecast, temp, weather_report;
weather_report = function weather_report(location) {
// Make an Ajax request to fetch the weather...
var _a, city, forecast, temp, weatherReport;
weatherReport = function(location) {
return [location, 72, "Mostly Sunny"];
};
_a = weather_report("Berkeley, CA");
_a = weatherReport("Berkeley, CA");
city = _a[0];
temp = _a[1];
forecast = _a[2];
})();
})();

View File

@@ -1,17 +1,17 @@
(function(){
var _a, _b, age, ages, child, years_old;
var _a, _b, age, ages, child, yearsOld;
var __hasProp = Object.prototype.hasOwnProperty;
years_old = {
yearsOld = {
max: 10,
ida: 9,
tim: 11
};
ages = (function() {
_a = []; _b = years_old;
_a = []; _b = yearsOld;
for (child in _b) { if (__hasProp.call(_b, child)) {
age = _b[child];
_a.push(child + " is " + age);
}}
return _a;
}).call(this);
})();
})();
})();

View File

@@ -1,5 +1,5 @@
(function(){
var _a, _b, _c, city, futurists, poet, street;
var _a, _b, _c, city, futurists, name, street;
futurists = {
sculptor: "Umberto Boccioni",
painter: "Vladimir Burliuk",
@@ -10,8 +10,8 @@
};
_a = futurists;
_b = _a.poet;
poet = _b.name;
name = _b.name;
_c = _b.address;
street = _c[0];
city = _c[1];
})();
})();

View File

@@ -7,4 +7,4 @@
tim: 11
};
matrix = [1, 0, 1, 0, 0, 1, 1, 1, 0];
})();
})();

View File

@@ -0,0 +1,5 @@
(function(){
$('.account').css({
'class': 'active'
});
})();

View File

@@ -1,43 +1,37 @@
(function(){
var _a, _b, _c, cubed_list, list, math, num, number, opposite_day, race, square;
// Assignment:
var _a, _b, _c, _d, cubes, list, math, num, number, opposite, race, square;
var __slice = Array.prototype.slice;
number = 42;
opposite_day = true;
// Conditions:
if (opposite_day) {
opposite = true;
if (opposite) {
number = -42;
}
// Functions:
square = function square(x) {
square = function(x) {
return x * x;
};
// Arrays:
list = [1, 2, 3, 4, 5];
// Objects:
math = {
root: Math.sqrt,
square: square,
cube: function cube(x) {
cube: function(x) {
return x * square(x);
}
};
// Splats:
race = function race(winner) {
race = function(winner) {
var runners;
runners = Array.prototype.slice.call(arguments, 1);
var _a = arguments.length, _b = _a >= 2;
runners = __slice.call(arguments, 1, _a - 0);
return print(winner, runners);
};
// Existence:
if ((typeof elvis !== "undefined" && elvis !== null)) {
if (typeof elvis !== "undefined" && elvis !== null) {
alert("I knew it!");
}
// Array comprehensions:
cubed_list = (function() {
_a = []; _b = list;
for (_c = 0; _c < _b.length; _c++) {
num = _b[_c];
cubes = (function() {
_a = []; _c = list;
for (_b = 0, _d = _c.length; _b < _d; _b++) {
num = _c[_b];
_a.push(math.cube(num));
}
return _a;
}).call(this);
})();
})();
})();

View File

@@ -1,8 +1,8 @@
(function(){
var _a, and_switch, bait;
bait = 1000;
and_switch = 0;
_a = [and_switch, bait];
bait = _a[0];
and_switch = _a[1];
})();
var _a, theBait, theSwitch;
theBait = 1000;
theSwitch = 0;
_a = [theSwitch, theBait];
theBait = _a[0];
theSwitch = _a[1];
})();

View File

@@ -0,0 +1,9 @@
(function(){
var _a, close, contents, open, tag;
var __slice = Array.prototype.slice;
tag = "<impossible>";
_a = tag.split("");
open = _a[0];
contents = __slice.call(_a, 1, _a.length - 1);
close = _a[_a.length - 1];
})();

5
documentation/js/prototypes.js vendored Normal file
View File

@@ -0,0 +1,5 @@
(function(){
String.prototype.dasherize = function() {
return this.replace(/_/g, "-");
};
})();

View File

@@ -1,21 +1,22 @@
(function(){
var _a, _b, _c, _d, _e, countdown, egg_delivery, num;
var _a, countdown, deliverEggs, num;
countdown = (function() {
_a = []; _d = 10; _e = 1;
for (_c=0, num=_d; (_d <= _e ? num <= _e : num >= _e); (_d <= _e ? num += 1 : num -= 1), _c++) {
_a = [];
for (num = 10; num >= 1; num += -1) {
_a.push(num);
}
return _a;
}).call(this);
egg_delivery = function egg_delivery() {
var _f, _g, _h, _i, _j, dozen_eggs, i;
_f = []; _i = 0; _j = eggs.length;
for (_h=0, i=_i; (_i <= _j ? i < _j : i > _j); (_i <= _j ? i += 12 : i -= 12), _h++) {
_f.push((function() {
dozen_eggs = eggs.slice(i, i + 12);
return deliver(new egg_carton(dozen));
}).call(this));
})();
deliverEggs = function() {
var _b, _c, dozen, i;
_b = []; (_c = eggs.length);
for (i = 0; i < _c; i += 12) {
_b.push((function() {
dozen = eggs.slice(i, i + 12);
return deliver(new eggCarton(dozen));
})());
}
return _f;
return _b;
};
})();
})();

View File

@@ -1,10 +1,11 @@
(function(){
var change_numbers, new_num, num;
num = 1;
change_numbers = function change_numbers() {
var new_num;
new_num = -1;
return num = 10;
var changeNumbers, inner, outer;
outer = 1;
changeNumbers = function() {
var inner;
inner = -1;
outer = 10;
return outer;
};
new_num = change_numbers();
})();
inner = changeNumbers();
})();

View File

@@ -1,6 +1,6 @@
(function(){
var numbers, numbers_copy, three_to_six;
var copy, numbers, threeToSix;
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
three_to_six = numbers.slice(3, 6 + 1);
numbers_copy = numbers.slice(0, numbers.length);
})();
threeToSix = numbers.slice(3, 6 + 1);
copy = numbers.slice(0, numbers.length);
})();

View File

@@ -1,4 +1,4 @@
(function(){
var _a;
(_a = lottery.draw_winner()) == null ? undefined : _a.address == null ? undefined : _a.address.zipcode;
})();
typeof (_a = (lottery.drawWinner())) === "undefined" || _a == undefined ? undefined : _a.address == undefined ? undefined : _a.address.zipcode;
})();

View File

@@ -1,16 +1,18 @@
(function(){
var award_medals, contenders, gold, silver, the_field;
gold = (silver = (the_field = "unknown"));
award_medals = function award_medals(first, second) {
var rest;
rest = Array.prototype.slice.call(arguments, 2);
var awardMedals, contenders, gold, rest, silver;
var __slice = Array.prototype.slice;
gold = (silver = (rest = "unknown"));
awardMedals = function(first, second) {
var _a = arguments.length, _b = _a >= 3;
rest = __slice.call(arguments, 2, _a - 0);
gold = first;
silver = second;
return the_field = rest;
rest = rest;
return rest;
};
contenders = ["Michael Phelps", "Liu Xiang", "Yao Ming", "Allyson Felix", "Shawn Johnson", "Roman Sebrle", "Guo Jingjing", "Tyson Gay", "Asafa Powell", "Usain Bolt"];
award_medals.apply(this, contenders);
awardMedals.apply(this, contenders);
alert("Gold: " + gold);
alert("Silver: " + silver);
alert("The Field: " + the_field);
})();
alert("The Field: " + rest);
})();

View File

@@ -2,4 +2,4 @@
var numbers;
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
numbers.splice.apply(numbers, [3, 6 - 3 + 1].concat([-3, -4, -5, -6]));
})();
})();

View File

@@ -1,9 +1,9 @@
(function(){
var moby_dick;
moby_dick = "Call me Ishmael. Some years ago -- \
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,37 +0,0 @@
(function(){
var Animal, Horse, Snake, _a, _b, sam, tom;
Animal = function Animal() { };
Animal.prototype.move = function move(meters) {
return alert(this.name + " moved " + meters + "m.");
};
Snake = function Snake(name) {
this.name = name;
return this;
};
_a = function(){};
_a.prototype = Animal.prototype;
Snake.__superClass__ = Animal.prototype;
Snake.prototype = new _a();
Snake.prototype.constructor = Snake;
Snake.prototype.move = function move() {
alert("Slithering...");
return Snake.__superClass__.move.call(this, 5);
};
Horse = function Horse(name) {
this.name = name;
return this;
};
_b = function(){};
_b.prototype = Animal.prototype;
Horse.__superClass__ = Animal.prototype;
Horse.prototype = new _b();
Horse.prototype.constructor = Horse;
Horse.prototype.move = function move() {
alert("Galloping...");
return Horse.__superClass__.move.call(this, 45);
};
sam = new Snake("Sammy the Python");
tom = new Horse("Tommy the Palomino");
sam.move();
tom.move();
})();

View File

@@ -1,18 +1,18 @@
(function(){
if (day === "Mon") {
go_to_work();
goToWork();
} else if (day === "Tue") {
go_to_the_park();
goToThePark();
} else if (day === "Thu") {
go_ice_fishing();
goIceFishing();
} else if (day === "Fri" || day === "Sat") {
if (day === bingo_day) {
go_to_bingo();
go_dancing();
if (day === bingoDay) {
goToBingo();
goDancing();
}
} else if (day === "Sun") {
go_to_church();
goToChurch();
} else {
go_to_work();
goToWork();
}
})();
})();

View File

@@ -1,10 +1,10 @@
(function(){
try {
all_hell_breaks_loose();
cats_and_dogs_living_together();
allHellBreaksLoose();
catsAndDogsLivingTogether();
} catch (error) {
print(error);
} finally {
clean_up();
cleanUp();
}
})();
})();

View File

@@ -1,15 +1,13 @@
(function(){
var _a, lyrics, num;
// Econ 101
if (this.studying_economics) {
if (this.studyingEconomics) {
while (supply > demand) {
buy();
}
while (supply < demand) {
while (!(supply > demand)) {
sell();
}
}
// Nursery Rhyme
num = 6;
lyrics = (function() {
_a = [];
@@ -18,5 +16,5 @@
One fell out and bumped his head.");
}
return _a;
}).call(this);
})();
})();
})();

View File

@@ -1,627 +0,0 @@
<!DOCTYPE html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" media="screen,projection,print" href="css/idle.css" />
<title>Underscore.coffee</title>
</head>
<body>
<pre class="idle"><span class="line-numbers"> 1 </span>
<span class="line-numbers"> 2 </span> <span class="Comment"><span class="Comment">#</span> Underscore.coffee</span>
<span class="line-numbers"> 3 </span> <span class="Comment"><span class="Comment">#</span> (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.</span>
<span class="line-numbers"> 4 </span> <span class="Comment"><span class="Comment">#</span> Underscore is freely distributable under the terms of the MIT license.</span>
<span class="line-numbers"> 5 </span> <span class="Comment"><span class="Comment">#</span> Portions of Underscore are inspired by or borrowed from Prototype.js,</span>
<span class="line-numbers"> 6 </span> <span class="Comment"><span class="Comment">#</span> Oliver Steele's Functional, and John Resig's Micro-Templating.</span>
<span class="line-numbers"> 7 </span> <span class="Comment"><span class="Comment">#</span> For all details and documentation:</span>
<span class="line-numbers"> 8 </span> <span class="Comment"><span class="Comment">#</span> http://documentcloud.github.com/underscore/</span>
<span class="line-numbers"> 9 </span>
<span class="line-numbers"> 10 </span>
<span class="line-numbers"> 11 </span> <span class="Comment"><span class="Comment">#</span> ------------------------- Baseline setup ---------------------------------</span>
<span class="line-numbers"> 12 </span>
<span class="line-numbers"> 13 </span> <span class="Comment"><span class="Comment">#</span> Establish the root object, &quot;window&quot; in the browser, or &quot;global&quot; on the server.</span>
<span class="line-numbers"> 14 </span> <span class="FunctionName">root</span><span class="Keyword">:</span> <span class="Variable">this</span>
<span class="line-numbers"> 15 </span>
<span class="line-numbers"> 16 </span>
<span class="line-numbers"> 17 </span> <span class="Comment"><span class="Comment">#</span> Save the previous value of the &quot;_&quot; variable.</span>
<span class="line-numbers"> 18 </span> <span class="FunctionName">previousUnderscore</span><span class="Keyword">:</span> root._
<span class="line-numbers"> 19 </span>
<span class="line-numbers"> 20 </span>
<span class="line-numbers"> 21 </span> <span class="Comment"><span class="Comment">#</span> If Underscore is called as a function, it returns a wrapped object that</span>
<span class="line-numbers"> 22 </span> <span class="Comment"><span class="Comment">#</span> can be used OO-style. This wrapper holds altered versions of all the</span>
<span class="line-numbers"> 23 </span> <span class="Comment"><span class="Comment">#</span> underscore functions. Wrapped objects may be chained.</span>
<span class="line-numbers"> 24 </span> <span class="FunctionName">wrapper</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 25 </span> <span class="FunctionName">this._wrapped</span><span class="Keyword">:</span> obj
<span class="line-numbers"> 26 </span> <span class="Variable">this</span>
<span class="line-numbers"> 27 </span>
<span class="line-numbers"> 28 </span>
<span class="line-numbers"> 29 </span> <span class="Comment"><span class="Comment">#</span> Establish the object that gets thrown to break out of a loop iteration.</span>
<span class="line-numbers"> 30 </span> <span class="FunctionName">breaker</span><span class="Keyword">:</span> <span class="Keyword">if</span> <span class="Keyword">typeof</span>(StopIteration) <span class="Keyword">is</span> <span class="String"><span class="String">'</span>undefined<span class="String">'</span></span> <span class="Keyword">then</span> <span class="String"><span class="String">'</span>__break__<span class="String">'</span></span> <span class="Keyword">else</span> StopIteration
<span class="line-numbers"> 31 </span>
<span class="line-numbers"> 32 </span>
<span class="line-numbers"> 33 </span> <span class="Comment"><span class="Comment">#</span> Create a safe reference to the Underscore object forreference below.</span>
<span class="line-numbers"> 34 </span> <span class="FunctionName">_</span><span class="Keyword">:</span> <span class="FunctionName">root._</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> <span class="Keyword">new</span> <span class="TypeName">wrapper</span>(obj)
<span class="line-numbers"> 35 </span>
<span class="line-numbers"> 36 </span>
<span class="line-numbers"> 37 </span> <span class="Comment"><span class="Comment">#</span> Export the Underscore object for CommonJS.</span>
<span class="line-numbers"> 38 </span> <span class="Keyword">if</span> <span class="Keyword">typeof</span>(exports) <span class="Keyword">!</span><span class="Keyword">=</span> <span class="String"><span class="String">'</span>undefined<span class="String">'</span></span> <span class="Keyword">then</span> <span class="FunctionName">exports._</span><span class="Keyword">:</span> _
<span class="line-numbers"> 39 </span>
<span class="line-numbers"> 40 </span>
<span class="line-numbers"> 41 </span> <span class="Comment"><span class="Comment">#</span> Create quick reference variables for speed access to core prototypes.</span>
<span class="line-numbers"> 42 </span> <span class="FunctionName">slice</span><span class="Keyword">:</span> <span class="FunctionName">Array:</span><span class="Keyword">:</span>slice
<span class="line-numbers"> 43 </span> <span class="FunctionName">unshift</span><span class="Keyword">:</span> <span class="FunctionName">Array:</span><span class="Keyword">:</span>unshift
<span class="line-numbers"> 44 </span> <span class="FunctionName">toString</span><span class="Keyword">:</span> <span class="FunctionName">Object:</span><span class="Keyword">:</span>toString
<span class="line-numbers"> 45 </span> <span class="FunctionName">hasOwnProperty</span><span class="Keyword">:</span> <span class="FunctionName">Object:</span><span class="Keyword">:</span>hasOwnProperty
<span class="line-numbers"> 46 </span> <span class="FunctionName">propertyIsEnumerable</span><span class="Keyword">:</span> <span class="FunctionName">Object:</span><span class="Keyword">:</span>propertyIsEnumerable
<span class="line-numbers"> 47 </span>
<span class="line-numbers"> 48 </span>
<span class="line-numbers"> 49 </span> <span class="Comment"><span class="Comment">#</span> Current version.</span>
<span class="line-numbers"> 50 </span> <span class="FunctionName">_.VERSION</span><span class="Keyword">:</span> <span class="String"><span class="String">'</span>0.5.8<span class="String">'</span></span>
<span class="line-numbers"> 51 </span>
<span class="line-numbers"> 52 </span>
<span class="line-numbers"> 53 </span> <span class="Comment"><span class="Comment">#</span> ------------------------ Collection Functions: ---------------------------</span>
<span class="line-numbers"> 54 </span>
<span class="line-numbers"> 55 </span> <span class="Comment"><span class="Comment">#</span> The cornerstone, an each implementation.</span>
<span class="line-numbers"> 56 </span> <span class="Comment"><span class="Comment">#</span> Handles objects implementing forEach, arrays, and raw objects.</span>
<span class="line-numbers"> 57 </span> <span class="FunctionName">_.each</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj, iterator, context</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 58 </span> <span class="FunctionName">index</span><span class="Keyword">:</span> <span class="Number">0</span>
<span class="line-numbers"> 59 </span> <span class="Keyword">try</span>
<span class="line-numbers"> 60 </span> <span class="Keyword">return</span> obj.forEach(iterator, context) <span class="Keyword">if</span> obj.forEach
<span class="line-numbers"> 61 </span> <span class="Keyword">if</span> _.isNumber(obj.length)
<span class="line-numbers"> 62 </span> <span class="Keyword">return</span> iterator.call(context, obj[i], i, obj) <span class="Keyword">for</span> i <span class="Keyword">in</span> [<span class="Number">0</span>...obj.length]
<span class="line-numbers"> 63 </span> iterator.call(context, val, key, obj) <span class="Keyword">for</span> key, val <span class="Keyword">of</span> obj
<span class="line-numbers"> 64 </span> <span class="Keyword">catch</span> e
<span class="line-numbers"> 65 </span> <span class="Keyword">throw</span> e <span class="Keyword">if</span> e <span class="Keyword">isnt</span> breaker
<span class="line-numbers"> 66 </span> obj
<span class="line-numbers"> 67 </span>
<span class="line-numbers"> 68 </span>
<span class="line-numbers"> 69 </span> <span class="Comment"><span class="Comment">#</span> Return the results of applying the iterator to each element. Use JavaScript</span>
<span class="line-numbers"> 70 </span> <span class="Comment"><span class="Comment">#</span> 1.6's version of map, if possible.</span>
<span class="line-numbers"> 71 </span> <span class="FunctionName">_.map</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj, iterator, context</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 72 </span> <span class="Keyword">return</span> obj.map(iterator, context) <span class="Keyword">if</span> (obj <span class="Keyword">and</span> _.isFunction(obj.map))
<span class="line-numbers"> 73 </span> <span class="FunctionName">results</span><span class="Keyword">:</span> []
<span class="line-numbers"> 74 </span> _.each obj, <span class="FunctionArgument">(</span><span class="FunctionArgument">value, index, list</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 75 </span> results.push(iterator.call(context, value, index, list))
<span class="line-numbers"> 76 </span> results
<span class="line-numbers"> 77 </span>
<span class="line-numbers"> 78 </span>
<span class="line-numbers"> 79 </span> <span class="Comment"><span class="Comment">#</span> Reduce builds up a single result from a list of values. Also known as</span>
<span class="line-numbers"> 80 </span> <span class="Comment"><span class="Comment">#</span> inject, or foldl. Uses JavaScript 1.8's version of reduce, if possible.</span>
<span class="line-numbers"> 81 </span> <span class="FunctionName">_.reduce</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj, memo, iterator, context</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 82 </span> <span class="Keyword">return</span> obj.reduce(_.bind(iterator, context), memo) <span class="Keyword">if</span> (obj <span class="Keyword">and</span> _.isFunction(obj.reduce))
<span class="line-numbers"> 83 </span> _.each obj, <span class="FunctionArgument">(</span><span class="FunctionArgument">value, index, list</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 84 </span> <span class="FunctionName">memo</span><span class="Keyword">:</span> iterator.call(context, memo, value, index, list)
<span class="line-numbers"> 85 </span> memo
<span class="line-numbers"> 86 </span>
<span class="line-numbers"> 87 </span>
<span class="line-numbers"> 88 </span> <span class="Comment"><span class="Comment">#</span> The right-associative version of reduce, also known as foldr. Uses</span>
<span class="line-numbers"> 89 </span> <span class="Comment"><span class="Comment">#</span> JavaScript 1.8's version of reduceRight, if available.</span>
<span class="line-numbers"> 90 </span> <span class="FunctionName">_.reduceRight</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj, memo, iterator, context</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 91 </span> <span class="Keyword">return</span> obj.reduceRight(_.bind(iterator, context), memo) <span class="Keyword">if</span> (obj <span class="Keyword">and</span> _.isFunction(obj.reduceRight))
<span class="line-numbers"> 92 </span> _.each _.clone(_.toArray(obj)).reverse(), <span class="FunctionArgument">(</span><span class="FunctionArgument">value, index</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 93 </span> <span class="FunctionName">memo</span><span class="Keyword">:</span> iterator.call(context, memo, value, index, obj)
<span class="line-numbers"> 94 </span> memo
<span class="line-numbers"> 95 </span>
<span class="line-numbers"> 96 </span>
<span class="line-numbers"> 97 </span> <span class="Comment"><span class="Comment">#</span> Return the first value which passes a truth test.</span>
<span class="line-numbers"> 98 </span> <span class="FunctionName">_.detect</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj, iterator, context</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 99 </span> <span class="FunctionName">result</span><span class="Keyword">:</span> <span class="BuiltInConstant">null</span>
<span class="line-numbers"> 100 </span> _.each obj, <span class="FunctionArgument">(</span><span class="FunctionArgument">value, index, list</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 101 </span> <span class="Keyword">if</span> iterator.call(context, value, index, list)
<span class="line-numbers"> 102 </span> <span class="FunctionName">result</span><span class="Keyword">:</span> value
<span class="line-numbers"> 103 </span> _.breakLoop()
<span class="line-numbers"> 104 </span> result
<span class="line-numbers"> 105 </span>
<span class="line-numbers"> 106 </span>
<span class="line-numbers"> 107 </span> <span class="Comment"><span class="Comment">#</span> Return all the elements that pass a truth test. Use JavaScript 1.6's</span>
<span class="line-numbers"> 108 </span> <span class="Comment"><span class="Comment">#</span> filter(), if it exists.</span>
<span class="line-numbers"> 109 </span> <span class="FunctionName">_.select</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj, iterator, context</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 110 </span> <span class="Keyword">if</span> obj <span class="Keyword">and</span> _.isFunction(obj.filter) <span class="Keyword">then</span> <span class="Keyword">return</span> obj.filter(iterator, context)
<span class="line-numbers"> 111 </span> <span class="FunctionName">results</span><span class="Keyword">:</span> []
<span class="line-numbers"> 112 </span> _.each obj, <span class="FunctionArgument">(</span><span class="FunctionArgument">value, index, list</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 113 </span> results.push(value) <span class="Keyword">if</span> iterator.call(context, value, index, list)
<span class="line-numbers"> 114 </span> results
<span class="line-numbers"> 115 </span>
<span class="line-numbers"> 116 </span>
<span class="line-numbers"> 117 </span> <span class="Comment"><span class="Comment">#</span> Return all the elements for which a truth test fails.</span>
<span class="line-numbers"> 118 </span> <span class="FunctionName">_.reject</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj, iterator, context</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 119 </span> <span class="FunctionName">results</span><span class="Keyword">:</span> []
<span class="line-numbers"> 120 </span> _.each obj, <span class="FunctionArgument">(</span><span class="FunctionArgument">value, index, list</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 121 </span> results.push(value) <span class="Keyword">if</span> <span class="Keyword">not</span> iterator.call(context, value, index, list)
<span class="line-numbers"> 122 </span> results
<span class="line-numbers"> 123 </span>
<span class="line-numbers"> 124 </span>
<span class="line-numbers"> 125 </span> <span class="Comment"><span class="Comment">#</span> Determine whether all of the elements match a truth test. Delegate to</span>
<span class="line-numbers"> 126 </span> <span class="Comment"><span class="Comment">#</span> JavaScript 1.6's every(), if it is present.</span>
<span class="line-numbers"> 127 </span> <span class="FunctionName">_.all</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj, iterator, context</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 128 </span> iterator <span class="Keyword">||</span><span class="Keyword">=</span> _.identity
<span class="line-numbers"> 129 </span> <span class="Keyword">return</span> obj.every(iterator, context) <span class="Keyword">if</span> obj <span class="Keyword">and</span> _.isFunction(obj.every)
<span class="line-numbers"> 130 </span> <span class="FunctionName">result</span><span class="Keyword">:</span> <span class="BuiltInConstant">true</span>
<span class="line-numbers"> 131 </span> _.each obj, <span class="FunctionArgument">(</span><span class="FunctionArgument">value, index, list</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 132 </span> _.breakLoop() <span class="Keyword">unless</span> (<span class="FunctionName">result</span><span class="Keyword">:</span> result <span class="Keyword">and</span> iterator.call(context, value, index, list))
<span class="line-numbers"> 133 </span> result
<span class="line-numbers"> 134 </span>
<span class="line-numbers"> 135 </span>
<span class="line-numbers"> 136 </span> <span class="Comment"><span class="Comment">#</span> Determine if at least one element in the object matches a truth test. Use</span>
<span class="line-numbers"> 137 </span> <span class="Comment"><span class="Comment">#</span> JavaScript 1.6's some(), if it exists.</span>
<span class="line-numbers"> 138 </span> <span class="FunctionName">_.any</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj, iterator, context</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 139 </span> iterator <span class="Keyword">||</span><span class="Keyword">=</span> _.identity
<span class="line-numbers"> 140 </span> <span class="Keyword">return</span> obj.some(iterator, context) <span class="Keyword">if</span> obj <span class="Keyword">and</span> _.isFunction(obj.some)
<span class="line-numbers"> 141 </span> <span class="FunctionName">result</span><span class="Keyword">:</span> <span class="BuiltInConstant">false</span>
<span class="line-numbers"> 142 </span> _.each obj, <span class="FunctionArgument">(</span><span class="FunctionArgument">value, index, list</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 143 </span> _.breakLoop() <span class="Keyword">if</span> (<span class="FunctionName">result</span><span class="Keyword">:</span> iterator.call(context, value, index, list))
<span class="line-numbers"> 144 </span> result
<span class="line-numbers"> 145 </span>
<span class="line-numbers"> 146 </span>
<span class="line-numbers"> 147 </span> <span class="Comment"><span class="Comment">#</span> Determine if a given value is included in the array or object,</span>
<span class="line-numbers"> 148 </span> <span class="Comment"><span class="Comment">#</span> based on '==='.</span>
<span class="line-numbers"> 149 </span> <span class="FunctionName">_.include</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj, target</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 150 </span> <span class="Keyword">return</span> _.indexOf(obj, target) <span class="Keyword">isnt</span> <span class="Keyword">-</span><span class="Number">1</span> <span class="Keyword">if</span> obj <span class="Keyword">and</span> _.isFunction(obj.indexOf)
<span class="line-numbers"> 151 </span> <span class="Keyword">for</span> key, val <span class="Keyword">of</span> obj
<span class="line-numbers"> 152 </span> <span class="Keyword">return</span> <span class="BuiltInConstant">true</span> <span class="Keyword">if</span> val <span class="Keyword">is</span> target
<span class="line-numbers"> 153 </span> <span class="BuiltInConstant">false</span>
<span class="line-numbers"> 154 </span>
<span class="line-numbers"> 155 </span>
<span class="line-numbers"> 156 </span> <span class="Comment"><span class="Comment">#</span> Invoke a method with arguments on every item in a collection.</span>
<span class="line-numbers"> 157 </span> <span class="FunctionName">_.invoke</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj, method</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 158 </span> <span class="FunctionName">args</span><span class="Keyword">:</span> _.rest(arguments, <span class="Number">2</span>)
<span class="line-numbers"> 159 </span> (<span class="Keyword">if</span> method <span class="Keyword">then</span> val[method] <span class="Keyword">else</span> val).apply(val, args) <span class="Keyword">for</span> val <span class="Keyword">in</span> obj
<span class="line-numbers"> 160 </span>
<span class="line-numbers"> 161 </span>
<span class="line-numbers"> 162 </span> <span class="Comment"><span class="Comment">#</span> Convenience version of a common use case of map: fetching a property.</span>
<span class="line-numbers"> 163 </span> <span class="FunctionName">_.pluck</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj, key</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 164 </span> _.map(obj, (<span class="FunctionArgument">(</span><span class="FunctionArgument">val</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> val[key]))
<span class="line-numbers"> 165 </span>
<span class="line-numbers"> 166 </span>
<span class="line-numbers"> 167 </span> <span class="Comment"><span class="Comment">#</span> Return the maximum item or (item-based computation).</span>
<span class="line-numbers"> 168 </span> <span class="FunctionName">_.max</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj, iterator, context</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 169 </span> <span class="Keyword">return</span> Math.max.apply(Math, obj) <span class="Keyword">if</span> <span class="Keyword">not</span> iterator <span class="Keyword">and</span> _.isArray(obj)
<span class="line-numbers"> 170 </span> <span class="FunctionName">result</span><span class="Keyword">:</span> {<span class="FunctionName">computed</span><span class="Keyword">:</span> <span class="Keyword">-</span><span class="BuiltInConstant">Infinity</span>}
<span class="line-numbers"> 171 </span> _.each obj, <span class="FunctionArgument">(</span><span class="FunctionArgument">value, index, list</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 172 </span> <span class="FunctionName">computed</span><span class="Keyword">:</span> <span class="Keyword">if</span> iterator <span class="Keyword">then</span> iterator.call(context, value, index, list) <span class="Keyword">else</span> value
<span class="line-numbers"> 173 </span> computed <span class="Keyword">&gt;=</span> result.computed <span class="Keyword">and</span> (<span class="FunctionName">result</span><span class="Keyword">:</span> {<span class="FunctionName">value</span><span class="Keyword">:</span> value, <span class="FunctionName">computed</span><span class="Keyword">:</span> computed})
<span class="line-numbers"> 174 </span> result.value
<span class="line-numbers"> 175 </span>
<span class="line-numbers"> 176 </span>
<span class="line-numbers"> 177 </span> <span class="Comment"><span class="Comment">#</span> Return the minimum element (or element-based computation).</span>
<span class="line-numbers"> 178 </span> <span class="FunctionName">_.min</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj, iterator, context</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 179 </span> <span class="Keyword">return</span> Math.min.apply(Math, obj) <span class="Keyword">if</span> <span class="Keyword">not</span> iterator <span class="Keyword">and</span> _.isArray(obj)
<span class="line-numbers"> 180 </span> <span class="FunctionName">result</span><span class="Keyword">:</span> {<span class="FunctionName">computed</span><span class="Keyword">:</span> <span class="BuiltInConstant">Infinity</span>}
<span class="line-numbers"> 181 </span> _.each obj, <span class="FunctionArgument">(</span><span class="FunctionArgument">value, index, list</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 182 </span> <span class="FunctionName">computed</span><span class="Keyword">:</span> <span class="Keyword">if</span> iterator <span class="Keyword">then</span> iterator.call(context, value, index, list) <span class="Keyword">else</span> value
<span class="line-numbers"> 183 </span> computed <span class="Keyword">&lt;</span> result.computed <span class="Keyword">and</span> (<span class="FunctionName">result</span><span class="Keyword">:</span> {<span class="FunctionName">value</span><span class="Keyword">:</span> value, <span class="FunctionName">computed</span><span class="Keyword">:</span> computed})
<span class="line-numbers"> 184 </span> result.value
<span class="line-numbers"> 185 </span>
<span class="line-numbers"> 186 </span>
<span class="line-numbers"> 187 </span> <span class="Comment"><span class="Comment">#</span> Sort the object's values by a criteria produced by an iterator.</span>
<span class="line-numbers"> 188 </span> <span class="FunctionName">_.sortBy</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj, iterator, context</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 189 </span> _.pluck(((_.map obj, <span class="FunctionArgument">(</span><span class="FunctionArgument">value, index, list</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 190 </span> {<span class="FunctionName">value</span><span class="Keyword">:</span> value, <span class="FunctionName">criteria</span><span class="Keyword">:</span> iterator.call(context, value, index, list)}
<span class="line-numbers"> 191 </span> ).sort(<span class="FunctionArgument">(</span><span class="FunctionArgument">left, right</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 192 </span> <span class="FunctionName">a</span><span class="Keyword">:</span> left.criteria; <span class="FunctionName">b</span><span class="Keyword">:</span> right.criteria
<span class="line-numbers"> 193 </span> <span class="Keyword">if</span> a <span class="Keyword">&lt;</span> b <span class="Keyword">then</span> <span class="Keyword">-</span><span class="Number">1</span> <span class="Keyword">else</span> <span class="Keyword">if</span> a <span class="Keyword">&gt;</span> b <span class="Keyword">then</span> <span class="Number">1</span> <span class="Keyword">else</span> <span class="Number">0</span>
<span class="line-numbers"> 194 </span> )), <span class="String"><span class="String">'</span>value<span class="String">'</span></span>)
<span class="line-numbers"> 195 </span>
<span class="line-numbers"> 196 </span>
<span class="line-numbers"> 197 </span> <span class="Comment"><span class="Comment">#</span> Use a comparator function to figure out at what index an object should</span>
<span class="line-numbers"> 198 </span> <span class="Comment"><span class="Comment">#</span> be inserted so as to maintain order. Uses binary search.</span>
<span class="line-numbers"> 199 </span> <span class="FunctionName">_.sortedIndex</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">array, obj, iterator</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 200 </span> iterator <span class="Keyword">||</span><span class="Keyword">=</span> _.identity
<span class="line-numbers"> 201 </span> <span class="FunctionName">low</span><span class="Keyword">:</span> <span class="Number">0</span>; <span class="FunctionName">high</span><span class="Keyword">:</span> array.length
<span class="line-numbers"> 202 </span> <span class="Keyword">while</span> low <span class="Keyword">&lt;</span> high
<span class="line-numbers"> 203 </span> <span class="FunctionName">mid</span><span class="Keyword">:</span> (low <span class="Keyword">+</span> high) <span class="Keyword">&gt;</span><span class="Keyword">&gt;</span> <span class="Number">1</span>
<span class="line-numbers"> 204 </span> <span class="Keyword">if</span> iterator(array[mid]) <span class="Keyword">&lt;</span> iterator(obj) <span class="Keyword">then</span> <span class="FunctionName">low</span><span class="Keyword">:</span> mid <span class="Keyword">+</span> <span class="Number">1</span> <span class="Keyword">else</span> <span class="FunctionName">high</span><span class="Keyword">:</span> mid
<span class="line-numbers"> 205 </span> low
<span class="line-numbers"> 206 </span>
<span class="line-numbers"> 207 </span>
<span class="line-numbers"> 208 </span> <span class="Comment"><span class="Comment">#</span> Convert anything iterable into a real, live array.</span>
<span class="line-numbers"> 209 </span> <span class="FunctionName">_.toArray</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">iterable</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 210 </span> <span class="Keyword">return</span> [] <span class="Keyword">if</span> (<span class="Keyword">!</span>iterable)
<span class="line-numbers"> 211 </span> <span class="Keyword">return</span> iterable.toArray() <span class="Keyword">if</span> (iterable.toArray)
<span class="line-numbers"> 212 </span> <span class="Keyword">return</span> iterable <span class="Keyword">if</span> (_.isArray(iterable))
<span class="line-numbers"> 213 </span> <span class="Keyword">return</span> slice.call(iterable) <span class="Keyword">if</span> (_.isArguments(iterable))
<span class="line-numbers"> 214 </span> _.values(iterable)
<span class="line-numbers"> 215 </span>
<span class="line-numbers"> 216 </span>
<span class="line-numbers"> 217 </span> <span class="Comment"><span class="Comment">#</span> Return the number of elements in an object.</span>
<span class="line-numbers"> 218 </span> <span class="FunctionName">_.size</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> _.toArray(obj).length
<span class="line-numbers"> 219 </span>
<span class="line-numbers"> 220 </span>
<span class="line-numbers"> 221 </span> <span class="Comment"><span class="Comment">#</span> -------------------------- Array Functions: ------------------------------</span>
<span class="line-numbers"> 222 </span>
<span class="line-numbers"> 223 </span> <span class="Comment"><span class="Comment">#</span> Get the first element of an array. Passing &quot;n&quot; will return the first N</span>
<span class="line-numbers"> 224 </span> <span class="Comment"><span class="Comment">#</span> values in the array. Aliased as &quot;head&quot;. The &quot;guard&quot; check allows it to work</span>
<span class="line-numbers"> 225 </span> <span class="Comment"><span class="Comment">#</span> with _.map.</span>
<span class="line-numbers"> 226 </span> <span class="FunctionName">_.first</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">array, n, guard</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 227 </span> <span class="Keyword">if</span> n <span class="Keyword">and</span> <span class="Keyword">not</span> guard <span class="Keyword">then</span> slice.call(array, <span class="Number">0</span>, n) <span class="Keyword">else</span> array[<span class="Number">0</span>]
<span class="line-numbers"> 228 </span>
<span class="line-numbers"> 229 </span>
<span class="line-numbers"> 230 </span> <span class="Comment"><span class="Comment">#</span> Returns everything but the first entry of the array. Aliased as &quot;tail&quot;.</span>
<span class="line-numbers"> 231 </span> <span class="Comment"><span class="Comment">#</span> Especially useful on the arguments object. Passing an &quot;index&quot; will return</span>
<span class="line-numbers"> 232 </span> <span class="Comment"><span class="Comment">#</span> the rest of the values in the array from that index onward. The &quot;guard&quot;</span>
<span class="line-numbers"> 233 </span> <span class="Comment"><span class="Comment">#</span> check allows it to work with _.map.</span>
<span class="line-numbers"> 234 </span> <span class="FunctionName">_.rest</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">array, index, guard</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 235 </span> slice.call(array, <span class="Keyword">if</span> _.isUndefined(index) <span class="Keyword">or</span> guard <span class="Keyword">then</span> <span class="Number">1</span> <span class="Keyword">else</span> index)
<span class="line-numbers"> 236 </span>
<span class="line-numbers"> 237 </span>
<span class="line-numbers"> 238 </span> <span class="Comment"><span class="Comment">#</span> Get the last element of an array.</span>
<span class="line-numbers"> 239 </span> <span class="FunctionName">_.last</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">array</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> array[array.length <span class="Keyword">-</span> <span class="Number">1</span>]
<span class="line-numbers"> 240 </span>
<span class="line-numbers"> 241 </span>
<span class="line-numbers"> 242 </span> <span class="Comment"><span class="Comment">#</span> Trim out all falsy values from an array.</span>
<span class="line-numbers"> 243 </span> <span class="FunctionName">_.compact</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">array</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> item <span class="Keyword">for</span> item <span class="Keyword">in</span> array <span class="Keyword">when</span> item
<span class="line-numbers"> 244 </span>
<span class="line-numbers"> 245 </span>
<span class="line-numbers"> 246 </span> <span class="Comment"><span class="Comment">#</span> Return a completely flattened version of an array.</span>
<span class="line-numbers"> 247 </span> <span class="FunctionName">_.flatten</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">array</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 248 </span> _.reduce array, [], <span class="FunctionArgument">(</span><span class="FunctionArgument">memo, value</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 249 </span> <span class="Keyword">return</span> memo.concat(_.flatten(value)) <span class="Keyword">if</span> _.isArray(value)
<span class="line-numbers"> 250 </span> memo.push(value)
<span class="line-numbers"> 251 </span> memo
<span class="line-numbers"> 252 </span>
<span class="line-numbers"> 253 </span>
<span class="line-numbers"> 254 </span> <span class="Comment"><span class="Comment">#</span> Return a version of the array that does not contain the specified value(s).</span>
<span class="line-numbers"> 255 </span> <span class="FunctionName">_.without</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">array</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 256 </span> <span class="FunctionName">values</span><span class="Keyword">:</span> _.rest(arguments)
<span class="line-numbers"> 257 </span> val <span class="Keyword">for</span> val <span class="Keyword">in</span> _.toArray(array) <span class="Keyword">when</span> <span class="Keyword">not</span> _.include(values, val)
<span class="line-numbers"> 258 </span>
<span class="line-numbers"> 259 </span>
<span class="line-numbers"> 260 </span> <span class="Comment"><span class="Comment">#</span> Produce a duplicate-free version of the array. If the array has already</span>
<span class="line-numbers"> 261 </span> <span class="Comment"><span class="Comment">#</span> been sorted, you have the option of using a faster algorithm.</span>
<span class="line-numbers"> 262 </span> <span class="FunctionName">_.uniq</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">array, isSorted</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 263 </span> <span class="FunctionName">memo</span><span class="Keyword">:</span> []
<span class="line-numbers"> 264 </span> <span class="Keyword">for</span> el, i <span class="Keyword">in</span> _.toArray(array)
<span class="line-numbers"> 265 </span> memo.push(el) <span class="Keyword">if</span> i <span class="Keyword">is</span> <span class="Number">0</span> <span class="Keyword">||</span> (<span class="Keyword">if</span> isSorted <span class="Keyword">is</span> <span class="BuiltInConstant">true</span> <span class="Keyword">then</span> _.last(memo) <span class="Keyword">isnt</span> el <span class="Keyword">else</span> <span class="Keyword">not</span> _.include(memo, el))
<span class="line-numbers"> 266 </span> memo
<span class="line-numbers"> 267 </span>
<span class="line-numbers"> 268 </span>
<span class="line-numbers"> 269 </span> <span class="Comment"><span class="Comment">#</span> Produce an array that contains every item shared between all the</span>
<span class="line-numbers"> 270 </span> <span class="Comment"><span class="Comment">#</span> passed-in arrays.</span>
<span class="line-numbers"> 271 </span> <span class="FunctionName">_.intersect</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">array</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 272 </span> <span class="FunctionName">rest</span><span class="Keyword">:</span> _.rest(arguments)
<span class="line-numbers"> 273 </span> _.select _.uniq(array), <span class="FunctionArgument">(</span><span class="FunctionArgument">item</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 274 </span> _.all rest, <span class="FunctionArgument">(</span><span class="FunctionArgument">other</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 275 </span> _.indexOf(other, item) <span class="Keyword">&gt;=</span> <span class="Number">0</span>
<span class="line-numbers"> 276 </span>
<span class="line-numbers"> 277 </span>
<span class="line-numbers"> 278 </span> <span class="Comment"><span class="Comment">#</span> Zip together multiple lists into a single array -- elements that share</span>
<span class="line-numbers"> 279 </span> <span class="Comment"><span class="Comment">#</span> an index go together.</span>
<span class="line-numbers"> 280 </span> <span class="FunctionName">_.zip</span><span class="Keyword">:</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 281 </span> <span class="FunctionName">length</span><span class="Keyword">:</span> _.max(_.pluck(arguments, <span class="String"><span class="String">'</span>length<span class="String">'</span></span>))
<span class="line-numbers"> 282 </span> <span class="FunctionName">results</span><span class="Keyword">:</span> <span class="Keyword">new</span> <span class="TypeName">Array</span>(length)
<span class="line-numbers"> 283 </span> <span class="Keyword">for</span> i <span class="Keyword">in</span> [<span class="Number">0</span>...length]
<span class="line-numbers"> 284 </span> results[i]<span class="Keyword">:</span> _.pluck(arguments, String(i))
<span class="line-numbers"> 285 </span> results
<span class="line-numbers"> 286 </span>
<span class="line-numbers"> 287 </span>
<span class="line-numbers"> 288 </span> <span class="Comment"><span class="Comment">#</span> If the browser doesn't supply us with indexOf (I'm looking at you, MSIE),</span>
<span class="line-numbers"> 289 </span> <span class="Comment"><span class="Comment">#</span> we need this function. Return the position of the first occurence of an</span>
<span class="line-numbers"> 290 </span> <span class="Comment"><span class="Comment">#</span> item in an array, or -1 if the item is not included in the array.</span>
<span class="line-numbers"> 291 </span> <span class="FunctionName">_.indexOf</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">array, item</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 292 </span> <span class="Keyword">return</span> array.indexOf(item) <span class="Keyword">if</span> array.indexOf
<span class="line-numbers"> 293 </span> <span class="FunctionName">i</span><span class="Keyword">:</span> <span class="Number">0</span>; <span class="FunctionName">l</span><span class="Keyword">:</span> array.length
<span class="line-numbers"> 294 </span> <span class="Keyword">while</span> l <span class="Keyword">-</span> i
<span class="line-numbers"> 295 </span> <span class="Keyword">if</span> array[i] <span class="Keyword">is</span> item <span class="Keyword">then</span> <span class="Keyword">return</span> i <span class="Keyword">else</span> i<span class="Keyword">++</span>
<span class="line-numbers"> 296 </span> <span class="Keyword">-</span><span class="Number">1</span>
<span class="line-numbers"> 297 </span>
<span class="line-numbers"> 298 </span>
<span class="line-numbers"> 299 </span> <span class="Comment"><span class="Comment">#</span> Provide JavaScript 1.6's lastIndexOf, delegating to the native function,</span>
<span class="line-numbers"> 300 </span> <span class="Comment"><span class="Comment">#</span> if possible.</span>
<span class="line-numbers"> 301 </span> <span class="FunctionName">_.lastIndexOf</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">array, item</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 302 </span> <span class="Keyword">return</span> array.lastIndexOf(item) <span class="Keyword">if</span> array.lastIndexOf
<span class="line-numbers"> 303 </span> <span class="FunctionName">i</span><span class="Keyword">:</span> array.length
<span class="line-numbers"> 304 </span> <span class="Keyword">while</span> i
<span class="line-numbers"> 305 </span> <span class="Keyword">if</span> array[i] <span class="Keyword">is</span> item <span class="Keyword">then</span> <span class="Keyword">return</span> i <span class="Keyword">else</span> i<span class="Keyword">--</span>
<span class="line-numbers"> 306 </span> <span class="Keyword">-</span><span class="Number">1</span>
<span class="line-numbers"> 307 </span>
<span class="line-numbers"> 308 </span>
<span class="line-numbers"> 309 </span> <span class="Comment"><span class="Comment">#</span> Generate an integer Array containing an arithmetic progression. A port of</span>
<span class="line-numbers"> 310 </span> <span class="Comment"><span class="Comment">#</span> the native Python range() function. See:</span>
<span class="line-numbers"> 311 </span> <span class="Comment"><span class="Comment">#</span> http://docs.python.org/library/functions.html#range</span>
<span class="line-numbers"> 312 </span> <span class="FunctionName">_.range</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">start, stop, step</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 313 </span> <span class="FunctionName">a</span><span class="Keyword">:</span> arguments
<span class="line-numbers"> 314 </span> <span class="FunctionName">solo</span><span class="Keyword">:</span> a.length <span class="Keyword">&lt;=</span> <span class="Number">1</span>
<span class="line-numbers"> 315 </span> <span class="FunctionName">i</span><span class="Keyword">:</span> <span class="FunctionName">start</span><span class="Keyword">:</span> <span class="Keyword">if</span> solo <span class="Keyword">then</span> <span class="Number">0</span> <span class="Keyword">else</span> a[<span class="Number">0</span>]
<span class="line-numbers"> 316 </span> <span class="FunctionName">stop</span><span class="Keyword">:</span> <span class="Keyword">if</span> solo <span class="Keyword">then</span> a[<span class="Number">0</span>] <span class="Keyword">else</span> a[<span class="Number">1</span>]
<span class="line-numbers"> 317 </span> <span class="FunctionName">step</span><span class="Keyword">:</span> a[<span class="Number">2</span>] <span class="Keyword">or</span> <span class="Number">1</span>
<span class="line-numbers"> 318 </span> <span class="FunctionName">len</span><span class="Keyword">:</span> Math.ceil((stop <span class="Keyword">-</span> start) <span class="Keyword">/</span> step)
<span class="line-numbers"> 319 </span> <span class="Keyword">return</span> [] <span class="Keyword">if</span> len <span class="Keyword">&lt;=</span> <span class="Number">0</span>
<span class="line-numbers"> 320 </span> <span class="FunctionName">range</span><span class="Keyword">:</span> <span class="Keyword">new</span> <span class="TypeName">Array</span>(len)
<span class="line-numbers"> 321 </span> <span class="FunctionName">idx</span><span class="Keyword">:</span> <span class="Number">0</span>
<span class="line-numbers"> 322 </span> <span class="Keyword">while</span> <span class="BuiltInConstant">true</span>
<span class="line-numbers"> 323 </span> <span class="Keyword">return</span> range <span class="Keyword">if</span> (<span class="Keyword">if</span> step <span class="Keyword">&gt;</span> <span class="Number">0</span> <span class="Keyword">then</span> i <span class="Keyword">-</span> stop <span class="Keyword">else</span> stop <span class="Keyword">-</span> i) <span class="Keyword">&gt;=</span> <span class="Number">0</span>
<span class="line-numbers"> 324 </span> range[idx]<span class="Keyword">:</span> i
<span class="line-numbers"> 325 </span> idx<span class="Keyword">++</span>
<span class="line-numbers"> 326 </span> i<span class="Keyword">+</span><span class="Keyword">=</span> step
<span class="line-numbers"> 327 </span>
<span class="line-numbers"> 328 </span>
<span class="line-numbers"> 329 </span> <span class="Comment"><span class="Comment">#</span> ----------------------- Function Functions: -----------------------------</span>
<span class="line-numbers"> 330 </span>
<span class="line-numbers"> 331 </span> <span class="Comment"><span class="Comment">#</span> Create a function bound to a given object (assigning 'this', and arguments,</span>
<span class="line-numbers"> 332 </span> <span class="Comment"><span class="Comment">#</span> optionally). Binding with arguments is also known as 'curry'.</span>
<span class="line-numbers"> 333 </span> <span class="FunctionName">_.bind</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">func, obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 334 </span> <span class="FunctionName">args</span><span class="Keyword">:</span> _.rest(arguments, <span class="Number">2</span>)
<span class="line-numbers"> 335 </span> <span class="Storage">-&gt;</span> func.apply(obj <span class="Keyword">or</span> root, args.concat(arguments))
<span class="line-numbers"> 336 </span>
<span class="line-numbers"> 337 </span>
<span class="line-numbers"> 338 </span> <span class="Comment"><span class="Comment">#</span> Bind all of an object's methods to that object. Useful for ensuring that</span>
<span class="line-numbers"> 339 </span> <span class="Comment"><span class="Comment">#</span> all callbacks defined on an object belong to it.</span>
<span class="line-numbers"> 340 </span> <span class="FunctionName">_.bindAll</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 341 </span> <span class="FunctionName">funcs</span><span class="Keyword">:</span> <span class="Keyword">if</span> arguments.length <span class="Keyword">&gt;</span> <span class="Number">1</span> <span class="Keyword">then</span> _.rest(arguments) <span class="Keyword">else</span> _.functions(obj)
<span class="line-numbers"> 342 </span> _.each(funcs, <span class="FunctionArgument">(</span><span class="FunctionArgument">f</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> obj[f]<span class="Keyword">:</span> _.bind(obj[f], obj))
<span class="line-numbers"> 343 </span> obj
<span class="line-numbers"> 344 </span>
<span class="line-numbers"> 345 </span>
<span class="line-numbers"> 346 </span> <span class="Comment"><span class="Comment">#</span> Delays a function for the given number of milliseconds, and then calls</span>
<span class="line-numbers"> 347 </span> <span class="Comment"><span class="Comment">#</span> it with the arguments supplied.</span>
<span class="line-numbers"> 348 </span> <span class="FunctionName">_.delay</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">func, wait</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 349 </span> <span class="FunctionName">args</span><span class="Keyword">:</span> _.rest(arguments, <span class="Number">2</span>)
<span class="line-numbers"> 350 </span> setTimeout((<span class="Storage">-&gt;</span> func.apply(func, args)), wait)
<span class="line-numbers"> 351 </span>
<span class="line-numbers"> 352 </span>
<span class="line-numbers"> 353 </span> <span class="Comment"><span class="Comment">#</span> Defers a function, scheduling it to run after the current call stack has</span>
<span class="line-numbers"> 354 </span> <span class="Comment"><span class="Comment">#</span> cleared.</span>
<span class="line-numbers"> 355 </span> <span class="FunctionName">_.defer</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">func</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 356 </span> _.delay.apply(_, [func, <span class="Number">1</span>].concat(_.rest(arguments)))
<span class="line-numbers"> 357 </span>
<span class="line-numbers"> 358 </span>
<span class="line-numbers"> 359 </span> <span class="Comment"><span class="Comment">#</span> Returns the first function passed as an argument to the second,</span>
<span class="line-numbers"> 360 </span> <span class="Comment"><span class="Comment">#</span> allowing you to adjust arguments, run code before and after, and</span>
<span class="line-numbers"> 361 </span> <span class="Comment"><span class="Comment">#</span> conditionally execute the original function.</span>
<span class="line-numbers"> 362 </span> <span class="FunctionName">_.wrap</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">func, wrapper</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 363 </span> <span class="Storage">-&gt;</span> wrapper.apply(wrapper, [func].concat(arguments))
<span class="line-numbers"> 364 </span>
<span class="line-numbers"> 365 </span>
<span class="line-numbers"> 366 </span> <span class="Comment"><span class="Comment">#</span> Returns a function that is the composition of a list of functions, each</span>
<span class="line-numbers"> 367 </span> <span class="Comment"><span class="Comment">#</span> consuming the return value of the function that follows.</span>
<span class="line-numbers"> 368 </span> <span class="FunctionName">_.compose</span><span class="Keyword">:</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 369 </span> <span class="FunctionName">funcs</span><span class="Keyword">:</span> arguments
<span class="line-numbers"> 370 </span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 371 </span> <span class="FunctionName">args</span><span class="Keyword">:</span> arguments
<span class="line-numbers"> 372 </span> <span class="Keyword">for</span> i <span class="Keyword">in</span> [(funcs.length <span class="Keyword">-</span> <span class="Number">1</span>)..<span class="Number">0</span>]
<span class="line-numbers"> 373 </span> <span class="FunctionName">args</span><span class="Keyword">:</span> [funcs[i].apply(<span class="Variable">this</span>, args)]
<span class="line-numbers"> 374 </span> args[<span class="Number">0</span>]
<span class="line-numbers"> 375 </span>
<span class="line-numbers"> 376 </span>
<span class="line-numbers"> 377 </span> <span class="Comment"><span class="Comment">#</span> ------------------------- Object Functions: ----------------------------</span>
<span class="line-numbers"> 378 </span>
<span class="line-numbers"> 379 </span> <span class="Comment"><span class="Comment">#</span> Retrieve the names of an object's properties.</span>
<span class="line-numbers"> 380 </span> <span class="FunctionName">_.keys</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 381 </span> <span class="Keyword">return</span> _.range(<span class="Number">0</span>, obj.length) <span class="Keyword">if</span> _.isArray(obj)
<span class="line-numbers"> 382 </span> key <span class="Keyword">for</span> key, val <span class="Keyword">of</span> obj
<span class="line-numbers"> 383 </span>
<span class="line-numbers"> 384 </span>
<span class="line-numbers"> 385 </span> <span class="Comment"><span class="Comment">#</span> Retrieve the values of an object's properties.</span>
<span class="line-numbers"> 386 </span> <span class="FunctionName">_.values</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 387 </span> _.map(obj, _.identity)
<span class="line-numbers"> 388 </span>
<span class="line-numbers"> 389 </span>
<span class="line-numbers"> 390 </span> <span class="Comment"><span class="Comment">#</span> Return a sorted list of the function names available in Underscore.</span>
<span class="line-numbers"> 391 </span> <span class="FunctionName">_.functions</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 392 </span> _.select(_.keys(obj), <span class="FunctionArgument">(</span><span class="FunctionArgument">key</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> _.isFunction(obj[key])).sort()
<span class="line-numbers"> 393 </span>
<span class="line-numbers"> 394 </span>
<span class="line-numbers"> 395 </span> <span class="Comment"><span class="Comment">#</span> Extend a given object with all of the properties in a source object.</span>
<span class="line-numbers"> 396 </span> <span class="FunctionName">_.extend</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">destination, source</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 397 </span> <span class="Keyword">for</span> key, val <span class="Keyword">of</span> source
<span class="line-numbers"> 398 </span> destination[key]<span class="Keyword">:</span> val
<span class="line-numbers"> 399 </span> destination
<span class="line-numbers"> 400 </span>
<span class="line-numbers"> 401 </span>
<span class="line-numbers"> 402 </span> <span class="Comment"><span class="Comment">#</span> Create a (shallow-cloned) duplicate of an object.</span>
<span class="line-numbers"> 403 </span> <span class="FunctionName">_.clone</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 404 </span> <span class="Keyword">return</span> obj.slice(<span class="Number">0</span>) <span class="Keyword">if</span> _.isArray(obj)
<span class="line-numbers"> 405 </span> _.extend({}, obj)
<span class="line-numbers"> 406 </span>
<span class="line-numbers"> 407 </span>
<span class="line-numbers"> 408 </span> <span class="Comment"><span class="Comment">#</span> Invokes interceptor with the obj, and then returns obj.</span>
<span class="line-numbers"> 409 </span> <span class="Comment"><span class="Comment">#</span> The primary purpose of this method is to &quot;tap into&quot; a method chain, in order to perform operations on intermediate results within the chain.</span>
<span class="line-numbers"> 410 </span> <span class="FunctionName">_.tap</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj, interceptor</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 411 </span> interceptor(obj)
<span class="line-numbers"> 412 </span> obj
<span class="line-numbers"> 413 </span>
<span class="line-numbers"> 414 </span>
<span class="line-numbers"> 415 </span> <span class="Comment"><span class="Comment">#</span> Perform a deep comparison to check if two objects are equal.</span>
<span class="line-numbers"> 416 </span> <span class="FunctionName">_.isEqual</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">a, b</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 417 </span> <span class="Comment"><span class="Comment">#</span> Check object identity.</span>
<span class="line-numbers"> 418 </span> <span class="Keyword">return</span> <span class="BuiltInConstant">true</span> <span class="Keyword">if</span> a <span class="Keyword">is</span> b
<span class="line-numbers"> 419 </span> <span class="Comment"><span class="Comment">#</span> Different types?</span>
<span class="line-numbers"> 420 </span> <span class="FunctionName">atype</span><span class="Keyword">:</span> <span class="Keyword">typeof</span>(a); <span class="FunctionName">btype</span><span class="Keyword">:</span> <span class="Keyword">typeof</span>(b)
<span class="line-numbers"> 421 </span> <span class="Keyword">return</span> <span class="BuiltInConstant">false</span> <span class="Keyword">if</span> atype <span class="Keyword">isnt</span> btype
<span class="line-numbers"> 422 </span> <span class="Comment"><span class="Comment">#</span> Basic equality test (watch out for coercions).</span>
<span class="line-numbers"> 423 </span> <span class="Keyword">return</span> <span class="BuiltInConstant">true</span> <span class="Keyword">if</span> <span class="String"><span class="String">`</span>a == b<span class="String">`</span></span>
<span class="line-numbers"> 424 </span> <span class="Comment"><span class="Comment">#</span> One is falsy and the other truthy.</span>
<span class="line-numbers"> 425 </span> <span class="Keyword">return</span> <span class="BuiltInConstant">false</span> <span class="Keyword">if</span> (<span class="Keyword">!</span>a <span class="Keyword">and</span> b) <span class="Keyword">or</span> (a <span class="Keyword">and</span> <span class="Keyword">!</span>b)
<span class="line-numbers"> 426 </span> <span class="Comment"><span class="Comment">#</span> One of them implements an isEqual()?</span>
<span class="line-numbers"> 427 </span> <span class="Keyword">return</span> a.isEqual(b) <span class="Keyword">if</span> a.isEqual
<span class="line-numbers"> 428 </span> <span class="Comment"><span class="Comment">#</span> Check dates' integer values.</span>
<span class="line-numbers"> 429 </span> <span class="Keyword">return</span> a.getTime() <span class="Keyword">is</span> b.getTime() <span class="Keyword">if</span> _.isDate(a) <span class="Keyword">and</span> _.isDate(b)
<span class="line-numbers"> 430 </span> <span class="Comment"><span class="Comment">#</span> Both are NaN?</span>
<span class="line-numbers"> 431 </span> <span class="Keyword">return</span> <span class="BuiltInConstant">true</span> <span class="Keyword">if</span> _.isNaN(a) <span class="Keyword">and</span> _.isNaN(b)
<span class="line-numbers"> 432 </span> <span class="Comment"><span class="Comment">#</span> Compare regular expressions.</span>
<span class="line-numbers"> 433 </span> <span class="Keyword">if</span> _.isRegExp(a) <span class="Keyword">and</span> _.isRegExp(b)
<span class="line-numbers"> 434 </span> <span class="Keyword">return</span> a.source <span class="Keyword">is</span> b.source <span class="Keyword">and</span>
<span class="line-numbers"> 435 </span> a.global <span class="Keyword">is</span> b.global <span class="Keyword">and</span>
<span class="line-numbers"> 436 </span> a.ignoreCase <span class="Keyword">is</span> b.ignoreCase <span class="Keyword">and</span>
<span class="line-numbers"> 437 </span> a.multiline <span class="Keyword">is</span> b.multiline
<span class="line-numbers"> 438 </span> <span class="Comment"><span class="Comment">#</span> If a is not an object by this point, we can't handle it.</span>
<span class="line-numbers"> 439 </span> <span class="Keyword">return</span> <span class="BuiltInConstant">false</span> <span class="Keyword">if</span> atype <span class="Keyword">isnt</span> <span class="String"><span class="String">'</span>object<span class="String">'</span></span>
<span class="line-numbers"> 440 </span> <span class="Comment"><span class="Comment">#</span> Check for different array lengths before comparing contents.</span>
<span class="line-numbers"> 441 </span> <span class="Keyword">return</span> <span class="BuiltInConstant">false</span> <span class="Keyword">if</span> a.length <span class="Keyword">and</span> (a.length <span class="Keyword">isnt</span> b.length)
<span class="line-numbers"> 442 </span> <span class="Comment"><span class="Comment">#</span> Nothing else worked, deep compare the contents.</span>
<span class="line-numbers"> 443 </span> <span class="FunctionName">aKeys</span><span class="Keyword">:</span> _.keys(a); <span class="FunctionName">bKeys</span><span class="Keyword">:</span> _.keys(b)
<span class="line-numbers"> 444 </span> <span class="Comment"><span class="Comment">#</span> Different object sizes?</span>
<span class="line-numbers"> 445 </span> <span class="Keyword">return</span> <span class="BuiltInConstant">false</span> <span class="Keyword">if</span> aKeys.length <span class="Keyword">isnt</span> bKeys.length
<span class="line-numbers"> 446 </span> <span class="Comment"><span class="Comment">#</span> Recursive comparison of contents.</span>
<span class="line-numbers"> 447 </span> <span class="Comment"><span class="Comment">#</span> for (var key in a) if (!_.isEqual(a[key], b[key])) return false;</span>
<span class="line-numbers"> 448 </span> <span class="Keyword">return</span> <span class="BuiltInConstant">true</span>
<span class="line-numbers"> 449 </span>
<span class="line-numbers"> 450 </span>
<span class="line-numbers"> 451 </span> <span class="Comment"><span class="Comment">#</span> Is a given array or object empty?</span>
<span class="line-numbers"> 452 </span> <span class="FunctionName">_.isEmpty</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> _.keys(obj).length <span class="Keyword">is</span> <span class="Number">0</span>
<span class="line-numbers"> 453 </span>
<span class="line-numbers"> 454 </span>
<span class="line-numbers"> 455 </span> <span class="Comment"><span class="Comment">#</span> Is a given value a DOM element?</span>
<span class="line-numbers"> 456 </span> <span class="FunctionName">_.isElement</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> obj <span class="Keyword">and</span> obj.nodeType <span class="Keyword">is</span> <span class="Number">1</span>
<span class="line-numbers"> 457 </span>
<span class="line-numbers"> 458 </span>
<span class="line-numbers"> 459 </span> <span class="Comment"><span class="Comment">#</span> Is a given value an array?</span>
<span class="line-numbers"> 460 </span> <span class="FunctionName">_.isArray</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> <span class="Keyword">!</span><span class="Keyword">!</span>(obj <span class="Keyword">and</span> obj.concat <span class="Keyword">and</span> obj.unshift)
<span class="line-numbers"> 461 </span>
<span class="line-numbers"> 462 </span>
<span class="line-numbers"> 463 </span> <span class="Comment"><span class="Comment">#</span> Is a given variable an arguments object?</span>
<span class="line-numbers"> 464 </span> <span class="FunctionName">_.isArguments</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> obj <span class="Keyword">and</span> _.isNumber(obj.length) <span class="Keyword">and</span> <span class="Keyword">not</span> obj.concat <span class="Keyword">and</span>
<span class="line-numbers"> 465 </span> <span class="Keyword">not</span> obj.substr <span class="Keyword">and</span> <span class="Keyword">not</span> obj.apply <span class="Keyword">and</span> <span class="Keyword">not</span> propertyIsEnumerable.call(obj, <span class="String"><span class="String">'</span>length<span class="String">'</span></span>)
<span class="line-numbers"> 466 </span>
<span class="line-numbers"> 467 </span>
<span class="line-numbers"> 468 </span> <span class="Comment"><span class="Comment">#</span> Is the given value a function?</span>
<span class="line-numbers"> 469 </span> <span class="FunctionName">_.isFunction</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> <span class="Keyword">!</span><span class="Keyword">!</span>(obj <span class="Keyword">and</span> obj.constructor <span class="Keyword">and</span> obj.call <span class="Keyword">and</span> obj.apply)
<span class="line-numbers"> 470 </span>
<span class="line-numbers"> 471 </span>
<span class="line-numbers"> 472 </span> <span class="Comment"><span class="Comment">#</span> Is the given value a string?</span>
<span class="line-numbers"> 473 </span> <span class="FunctionName">_.isString</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> <span class="Keyword">!</span><span class="Keyword">!</span>(obj <span class="Keyword">is</span> <span class="String"><span class="String">'</span><span class="String">'</span></span> <span class="Keyword">or</span> (obj <span class="Keyword">and</span> obj.charCodeAt <span class="Keyword">and</span> obj.substr))
<span class="line-numbers"> 474 </span>
<span class="line-numbers"> 475 </span>
<span class="line-numbers"> 476 </span> <span class="Comment"><span class="Comment">#</span> Is a given value a number?</span>
<span class="line-numbers"> 477 </span> <span class="FunctionName">_.isNumber</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> (obj <span class="Keyword">is</span> <span class="Keyword">+</span>obj) <span class="Keyword">or</span> toString.call(obj) <span class="Keyword">is</span> <span class="String"><span class="String">'</span>[object Number]<span class="String">'</span></span>
<span class="line-numbers"> 478 </span>
<span class="line-numbers"> 479 </span>
<span class="line-numbers"> 480 </span> <span class="Comment"><span class="Comment">#</span> Is a given value a Date?</span>
<span class="line-numbers"> 481 </span> <span class="FunctionName">_.isDate</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> <span class="Keyword">!</span><span class="Keyword">!</span>(obj <span class="Keyword">and</span> obj.getTimezoneOffset <span class="Keyword">and</span> obj.setUTCFullYear)
<span class="line-numbers"> 482 </span>
<span class="line-numbers"> 483 </span>
<span class="line-numbers"> 484 </span> <span class="Comment"><span class="Comment">#</span> Is the given value a regular expression?</span>
<span class="line-numbers"> 485 </span> <span class="FunctionName">_.isRegExp</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> <span class="Keyword">!</span><span class="Keyword">!</span>(obj <span class="Keyword">and</span> obj.exec <span class="Keyword">and</span> (obj.ignoreCase <span class="Keyword">or</span> obj.ignoreCase <span class="Keyword">is</span> <span class="BuiltInConstant">false</span>))
<span class="line-numbers"> 486 </span>
<span class="line-numbers"> 487 </span>
<span class="line-numbers"> 488 </span> <span class="Comment"><span class="Comment">#</span> Is the given value NaN -- this one is interesting. NaN != NaN, and</span>
<span class="line-numbers"> 489 </span> <span class="Comment"><span class="Comment">#</span> isNaN(undefined) == true, so we make sure it's a number first.</span>
<span class="line-numbers"> 490 </span> <span class="FunctionName">_.isNaN</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> _.isNumber(obj) <span class="Keyword">and</span> window.isNaN(obj)
<span class="line-numbers"> 491 </span>
<span class="line-numbers"> 492 </span>
<span class="line-numbers"> 493 </span> <span class="Comment"><span class="Comment">#</span> Is a given value equal to null?</span>
<span class="line-numbers"> 494 </span> <span class="FunctionName">_.isNull</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> obj <span class="Keyword">is</span> <span class="BuiltInConstant">null</span>
<span class="line-numbers"> 495 </span>
<span class="line-numbers"> 496 </span>
<span class="line-numbers"> 497 </span> <span class="Comment"><span class="Comment">#</span> Is a given variable undefined?</span>
<span class="line-numbers"> 498 </span> <span class="FunctionName">_.isUndefined</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> <span class="Keyword">typeof</span> obj <span class="Keyword">is</span> <span class="String"><span class="String">'</span>undefined<span class="String">'</span></span>
<span class="line-numbers"> 499 </span>
<span class="line-numbers"> 500 </span>
<span class="line-numbers"> 501 </span> <span class="Comment"><span class="Comment">#</span> -------------------------- Utility Functions: --------------------------</span>
<span class="line-numbers"> 502 </span>
<span class="line-numbers"> 503 </span> <span class="Comment"><span class="Comment">#</span> Run Underscore.js in noConflict mode, returning the '_' variable to its</span>
<span class="line-numbers"> 504 </span> <span class="Comment"><span class="Comment">#</span> previous owner. Returns a reference to the Underscore object.</span>
<span class="line-numbers"> 505 </span> <span class="FunctionName">_.noConflict</span><span class="Keyword">:</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 506 </span> <span class="FunctionName">root._</span><span class="Keyword">:</span> previousUnderscore
<span class="line-numbers"> 507 </span> <span class="Variable">this</span>
<span class="line-numbers"> 508 </span>
<span class="line-numbers"> 509 </span>
<span class="line-numbers"> 510 </span> <span class="Comment"><span class="Comment">#</span> Keep the identity function around for default iterators.</span>
<span class="line-numbers"> 511 </span> <span class="FunctionName">_.identity</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">value</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span> value
<span class="line-numbers"> 512 </span>
<span class="line-numbers"> 513 </span>
<span class="line-numbers"> 514 </span> <span class="Comment"><span class="Comment">#</span> Break out of the middle of an iteration.</span>
<span class="line-numbers"> 515 </span> <span class="FunctionName">_.breakLoop</span><span class="Keyword">:</span> <span class="Storage">-&gt;</span> <span class="Keyword">throw</span> breaker
<span class="line-numbers"> 516 </span>
<span class="line-numbers"> 517 </span>
<span class="line-numbers"> 518 </span> <span class="Comment"><span class="Comment">#</span> Generate a unique integer id (unique within the entire client session).</span>
<span class="line-numbers"> 519 </span> <span class="Comment"><span class="Comment">#</span> Useful for temporary DOM ids.</span>
<span class="line-numbers"> 520 </span> <span class="FunctionName">idCounter</span><span class="Keyword">:</span> <span class="Number">0</span>
<span class="line-numbers"> 521 </span> <span class="FunctionName">_.uniqueId</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">prefix</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 522 </span> (prefix <span class="Keyword">or</span> <span class="String"><span class="String">'</span><span class="String">'</span></span>) <span class="Keyword">+</span> idCounter<span class="Keyword">++</span>
<span class="line-numbers"> 523 </span>
<span class="line-numbers"> 524 </span>
<span class="line-numbers"> 525 </span> <span class="Comment"><span class="Comment">#</span> By default, Underscore uses ERB-style template delimiters, change the</span>
<span class="line-numbers"> 526 </span> <span class="Comment"><span class="Comment">#</span> following template settings to use alternative delimiters.</span>
<span class="line-numbers"> 527 </span> <span class="FunctionName">_.templateSettings</span><span class="Keyword">:</span> {
<span class="line-numbers"> 528 </span> <span class="FunctionName">start</span><span class="Keyword">:</span> <span class="String"><span class="String">'</span>&lt;%<span class="String">'</span></span>
<span class="line-numbers"> 529 </span> <span class="FunctionName">end</span><span class="Keyword">:</span> <span class="String"><span class="String">'</span>%&gt;<span class="String">'</span></span>
<span class="line-numbers"> 530 </span> <span class="FunctionName">interpolate</span><span class="Keyword">:</span><span class="String"> <span class="String">/</span>&lt;%=(.+?)%&gt;<span class="String">/</span>g</span>
<span class="line-numbers"> 531 </span> }
<span class="line-numbers"> 532 </span>
<span class="line-numbers"> 533 </span>
<span class="line-numbers"> 534 </span> <span class="Comment"><span class="Comment">#</span> JavaScript templating a-la ERB, pilfered from John Resig's</span>
<span class="line-numbers"> 535 </span> <span class="Comment"><span class="Comment">#</span> &quot;Secrets of the JavaScript Ninja&quot;, page 83.</span>
<span class="line-numbers"> 536 </span> <span class="Comment"><span class="Comment">#</span> Single-quote fix from Rick Strahl's version.</span>
<span class="line-numbers"> 537 </span> <span class="FunctionName">_.template</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">str, data</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 538 </span> <span class="FunctionName">c</span><span class="Keyword">:</span> _.templateSettings
<span class="line-numbers"> 539 </span> <span class="FunctionName">fn</span><span class="Keyword">:</span> <span class="Keyword">new</span> <span class="TypeName">Function</span> <span class="String"><span class="String">'</span>obj<span class="String">'</span></span>,
<span class="line-numbers"> 540 </span> <span class="String"><span class="String">'</span>var p=[],print=function(){p.push.apply(p,arguments);};<span class="String">'</span></span> <span class="Keyword">+</span>
<span class="line-numbers"> 541 </span> <span class="String"><span class="String">'</span>with(obj){p.push(<span class="UserDefinedConstant">\'</span><span class="String">'</span></span> <span class="Keyword">+</span>
<span class="line-numbers"> 542 </span> str.replace(<span class="String"><span class="String">/</span>[<span class="UserDefinedConstant">\r</span><span class="UserDefinedConstant">\t</span><span class="UserDefinedConstant">\n</span>]<span class="String">/</span>g</span>, <span class="String"><span class="String">&quot;</span> <span class="String">&quot;</span></span>)
<span class="line-numbers"> 543 </span> .replace(<span class="Keyword">new</span> <span class="TypeName">RegExp</span>(<span class="String"><span class="String">&quot;</span>'(?=[^<span class="String">&quot;</span></span><span class="Keyword">+</span>c.end[<span class="Number">0</span>]<span class="Keyword">+</span><span class="String"><span class="String">&quot;</span>]*<span class="String">&quot;</span></span><span class="Keyword">+</span>c.end<span class="Keyword">+</span><span class="String"><span class="String">&quot;</span>)<span class="String">&quot;</span></span>,<span class="String"><span class="String">&quot;</span>g<span class="String">&quot;</span></span>),<span class="String"><span class="String">&quot;</span><span class="UserDefinedConstant">\t</span><span class="String">&quot;</span></span>)
<span class="line-numbers"> 544 </span> .split(<span class="String"><span class="String">&quot;</span>'<span class="String">&quot;</span></span>).join(<span class="String"><span class="String">&quot;</span><span class="UserDefinedConstant">\\</span>'<span class="String">&quot;</span></span>)
<span class="line-numbers"> 545 </span> .split(<span class="String"><span class="String">&quot;</span><span class="UserDefinedConstant">\t</span><span class="String">&quot;</span></span>).join(<span class="String"><span class="String">&quot;</span>'<span class="String">&quot;</span></span>)
<span class="line-numbers"> 546 </span> .replace(c.interpolate, <span class="String"><span class="String">&quot;</span>',$1,'<span class="String">&quot;</span></span>)
<span class="line-numbers"> 547 </span> .split(c.start).join(<span class="String"><span class="String">&quot;</span>');<span class="String">&quot;</span></span>)
<span class="line-numbers"> 548 </span> .split(c.end).join(<span class="String"><span class="String">&quot;</span>p.push('<span class="String">&quot;</span></span>) <span class="Keyword">+</span>
<span class="line-numbers"> 549 </span> <span class="String"><span class="String">&quot;</span>');}return p.join('');<span class="String">&quot;</span></span>
<span class="line-numbers"> 550 </span> <span class="Keyword">if</span> data <span class="Keyword">then</span> fn(data) <span class="Keyword">else</span> fn
<span class="line-numbers"> 551 </span>
<span class="line-numbers"> 552 </span>
<span class="line-numbers"> 553 </span> <span class="Comment"><span class="Comment">#</span> ------------------------------- Aliases ----------------------------------</span>
<span class="line-numbers"> 554 </span>
<span class="line-numbers"> 555 </span> <span class="FunctionName">_.forEach</span><span class="Keyword">:</span> _.each
<span class="line-numbers"> 556 </span> <span class="FunctionName">_.foldl</span><span class="Keyword">:</span> <span class="FunctionName">_.inject</span><span class="Keyword">:</span> _.reduce
<span class="line-numbers"> 557 </span> <span class="FunctionName">_.foldr</span><span class="Keyword">:</span> _.reduceRight
<span class="line-numbers"> 558 </span> <span class="FunctionName">_.filter</span><span class="Keyword">:</span> _.select
<span class="line-numbers"> 559 </span> <span class="FunctionName">_.every</span><span class="Keyword">:</span> _.all
<span class="line-numbers"> 560 </span> <span class="FunctionName">_.some</span><span class="Keyword">:</span> _.any
<span class="line-numbers"> 561 </span> <span class="FunctionName">_.head</span><span class="Keyword">:</span> _.first
<span class="line-numbers"> 562 </span> <span class="FunctionName">_.tail</span><span class="Keyword">:</span> _.rest
<span class="line-numbers"> 563 </span> <span class="FunctionName">_.methods</span><span class="Keyword">:</span> _.functions
<span class="line-numbers"> 564 </span>
<span class="line-numbers"> 565 </span>
<span class="line-numbers"> 566 </span> <span class="Comment"><span class="Comment">#</span> ------------------------ Setup the OOP Wrapper: --------------------------</span>
<span class="line-numbers"> 567 </span>
<span class="line-numbers"> 568 </span> <span class="Comment"><span class="Comment">#</span> Helper function to continue chaining intermediate results.</span>
<span class="line-numbers"> 569 </span> <span class="FunctionName">result</span><span class="Keyword">:</span> <span class="FunctionArgument">(</span><span class="FunctionArgument">obj, chain</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 570 </span> <span class="Keyword">if</span> chain <span class="Keyword">then</span> _(obj).chain() <span class="Keyword">else</span> obj
<span class="line-numbers"> 571 </span>
<span class="line-numbers"> 572 </span>
<span class="line-numbers"> 573 </span> <span class="Comment"><span class="Comment">#</span> Add all of the Underscore functions to the wrapper object.</span>
<span class="line-numbers"> 574 </span> _.each _.functions(_), <span class="FunctionArgument">(</span><span class="FunctionArgument">name</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 575 </span> <span class="FunctionName">method</span><span class="Keyword">:</span> _[name]
<span class="line-numbers"> 576 </span> wrapper.prototype[name]<span class="Keyword">:</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 577 </span> unshift.call(arguments, <span class="Variable">this</span>._wrapped)
<span class="line-numbers"> 578 </span> result(method.apply(_, arguments), <span class="Variable">this</span>._chain)
<span class="line-numbers"> 579 </span>
<span class="line-numbers"> 580 </span>
<span class="line-numbers"> 581 </span> <span class="Comment"><span class="Comment">#</span> Add all mutator Array functions to the wrapper.</span>
<span class="line-numbers"> 582 </span> _.each [<span class="String"><span class="String">'</span>pop<span class="String">'</span></span>, <span class="String"><span class="String">'</span>push<span class="String">'</span></span>, <span class="String"><span class="String">'</span>reverse<span class="String">'</span></span>, <span class="String"><span class="String">'</span>shift<span class="String">'</span></span>, <span class="String"><span class="String">'</span>sort<span class="String">'</span></span>, <span class="String"><span class="String">'</span>splice<span class="String">'</span></span>, <span class="String"><span class="String">'</span>unshift<span class="String">'</span></span>], <span class="FunctionArgument">(</span><span class="FunctionArgument">name</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 583 </span> <span class="FunctionName">method</span><span class="Keyword">:</span> Array.prototype[name]
<span class="line-numbers"> 584 </span> wrapper.prototype[name]<span class="Keyword">:</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 585 </span> method.apply(<span class="Variable">this</span>._wrapped, arguments)
<span class="line-numbers"> 586 </span> result(<span class="Variable">this</span>._wrapped, <span class="Variable">this</span>._chain)
<span class="line-numbers"> 587 </span>
<span class="line-numbers"> 588 </span>
<span class="line-numbers"> 589 </span> <span class="Comment"><span class="Comment">#</span> Add all accessor Array functions to the wrapper.</span>
<span class="line-numbers"> 590 </span> _.each [<span class="String"><span class="String">'</span>concat<span class="String">'</span></span>, <span class="String"><span class="String">'</span>join<span class="String">'</span></span>, <span class="String"><span class="String">'</span>slice<span class="String">'</span></span>], <span class="FunctionArgument">(</span><span class="FunctionArgument">name</span><span class="FunctionArgument">)</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 591 </span> <span class="FunctionName">method</span><span class="Keyword">:</span> Array.prototype[name]
<span class="line-numbers"> 592 </span> wrapper.prototype[name]<span class="Keyword">:</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 593 </span> result(method.apply(<span class="Variable">this</span>._wrapped, arguments), <span class="Variable">this</span>._chain)
<span class="line-numbers"> 594 </span>
<span class="line-numbers"> 595 </span>
<span class="line-numbers"> 596 </span> <span class="Comment"><span class="Comment">#</span> Start chaining a wrapped Underscore object.</span>
<span class="line-numbers"> 597 </span> <span class="FunctionName">wrapper::chain</span><span class="Keyword">:</span> <span class="Storage">-&gt;</span>
<span class="line-numbers"> 598 </span> <span class="FunctionName">this._chain</span><span class="Keyword">:</span> <span class="BuiltInConstant">true</span>
<span class="line-numbers"> 599 </span> <span class="Variable">this</span>
<span class="line-numbers"> 600 </span>
<span class="line-numbers"> 601 </span>
<span class="line-numbers"> 602 </span> <span class="Comment"><span class="Comment">#</span> Extracts the result from a wrapped and chained object.</span>
<span class="line-numbers"> 603 </span> <span class="FunctionName">wrapper::value</span><span class="Keyword">:</span> <span class="Storage">-&gt;</span> <span class="Variable">this</span>._wrapped
</pre> <p>
<a href="http://validator.w3.org/check?uri=referer">
<img style="border:0"
src="http://www.w3.org/Icons/valid-xhtml10"
alt="Valid XHTML 1.0 Strict" height="31" width="88" />
</a>
<a href="http://jigsaw.w3.org/css-validator/check?uri=referer">
<img style="border:0;width:88px;height:31px"
src="http://jigsaw.w3.org/css-validator/images/vcss"
alt="Valid CSS!" />
</a>
</p>
</body>
</html>

View File

@@ -21,7 +21,7 @@ match_here: (regexp, text) ->
# Search for a kleene star match at the beginning of the text.
match_star: (c, regexp, text) ->
while true
loop
return true if match_here(regexp, text)
return false unless text and (text[0] is c or c is '.')
text: text.slice(1)

View File

@@ -8,7 +8,7 @@ get '/hello', ->
# Append.
append: (location, data) ->
path: new Pathname location
throw "Location does not exist" unless path.exists()
throw new Error("Location does not exist") unless path.exists()
File.open path, 'a', (file) ->
file.puts YAML.dump data
@@ -33,7 +33,7 @@ File.open: (path, mode, block) ->
# Write.
write: (location, data) ->
path = new Pathname location
path: new Pathname location
raise "Location does not exist" unless path.exists()
File.open path, 'w', (file) ->

View File

@@ -19,7 +19,7 @@ spaced_out_multiline_object: {
pi: 3.14159
list: [1, 2, 3, 4]
regex: /match[ing](every|thing|\/)/gi
three: new Idea()
three: new Idea
inner_obj: {
freedom: -> _.freedom()
@@ -94,7 +94,7 @@ while demand > supply
while supply > demand then buy()
while true
loop
break if broken
continue if continuing
@@ -140,24 +140,28 @@ sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna
aliquam erat volutpat. Ut wisi enim ad."
# Inheritance and calling super.
Animal: ->
Animal::move: (meters) ->
alert(this.name + " moved " + meters + "m.")
class Animal
move: (meters) ->
alert this.name + " moved " + meters + "m."
Snake: (name) -> this.name: name
Snake extends Animal
Snake::move: ->
alert('Slithering...')
super(5)
class Snake extends Animal
constructor: (name) ->
@name: name
Horse: (name) -> this.name: name
Horse extends Animal
Horse::move: ->
alert('Galloping...')
super(45)
move: ->
alert 'Slithering...'
super 5
sam: new Snake("Sammy the Snake")
tom: new Horse("Tommy the Horse")
class Horse extends Animal
constructor: (name) ->
@name: name
move: ->
alert 'Galloping...'
super 45
sam: new Snake "Sammy the Snake"
tom: new Horse "Tommy the Horse"
sam.move()
tom.move()

View File

@@ -1,101 +1,103 @@
# "Classic" linked list implementation that doesn't keep track of its size.
LinkedList: ->
this._head: null # Pointer to the first item in the list.
class LinkedList
constructor: ->
this._head: null # Pointer to the first item in the list.
# Appends some data to the end of the list. This method traverses the existing
# list and places the value at the end in a new node.
LinkedList::add: (data) ->
# Appends some data to the end of the list. This method traverses the existing
# list and places the value at the end in a new node.
add: (data) ->
# Create a new node object to wrap the data.
node: {data: data, next: null}
# Create a new node object to wrap the data.
node: {data: data, next: null}
current: this._head ||= node
current: this._head ||= node
if this._head isnt node
current: current.next while current.next
current.next: node
if this._head isnt node
current: current.next while current.next
current.next: node
this
this
# Retrieves the data at the given position in the list.
LinkedList::item: (index) ->
# Retrieves the data at the given position in the list.
item: (index) ->
# Check for out-of-bounds values.
return null if index < 0
# Check for out-of-bounds values.
return null if index < 0
current: this._head or null
i: -1
current: this._head or null
i: -1
# Advance through the list.
current: current.next while current and index > (i += 1)
# Advance through the list.
current: current.next while current and index > (i += 1)
# Return null if we've reached the end.
current and current.data
# Return null if we've reached the end.
current and current.data
# Remove the item from the given location in the list.
LinkedList::remove: (index) ->
# Remove the item from the given location in the list.
remove: (index) ->
# Check for out-of-bounds values.
return null if index < 0
# Check for out-of-bounds values.
return null if index < 0
current: this._head or null
i: -1
current: this._head or null
i: -1
# Special case: removing the first item.
if index is 0
this._head: current.next
else
# Special case: removing the first item.
if index is 0
this._head: current.next
else
# Find the right location.
[previous, current]: [current, current.next] while index > (i += 1)
# Find the right location.
[previous, current]: [current, current.next] while index > (i += 1)
# Skip over the item to remove.
previous.next: current.next
# Skip over the item to remove.
previous.next: current.next
# Return the value.
current and current.data
# Return the value.
current and current.data
# Calculate the number of items in the list.
LinkedList::size: ->
current: this._head
count: 0
# Calculate the number of items in the list.
size: ->
current: this._head
count: 0
while current
count += 1
current: current.next
while current
count += 1
current: current.next
count
count
# Convert the list into an array.
LinkedList::toArray: ->
result: []
current: this._head
# Convert the list into an array.
toArray: ->
result: []
current: this._head
while current
result.push(current.data)
current: current.next
while current
result.push(current.data)
current: current.next
result
result
# The string representation of the linked list.
LinkedList::toString: -> this.toArray().toString()
# The string representation of the linked list.
toString: -> this.toArray().toString()
# Tests.
list: new LinkedList()
list: new LinkedList
list.add("Hi")
puts(list.size() is 1)
puts(list.item(0) is "Hi")
puts(list.item(1) is null)
list: new LinkedList()
list: new LinkedList
list.add("zero").add("one").add("two")
puts(list.size() is 3)
puts(list.item(2) is "two")

View File

@@ -14,8 +14,7 @@ print(add(2, 4))
# loop: 'quaff' print.
while true
print('quaff')
loop print 'quaff'
# ('cheese', 'bread', 'mayo') at (1) print
@@ -53,16 +52,16 @@ for key, val of {dog: 'canine', cat: 'feline', fox: 'vulpine'}
# Person print = ():
# ('My name is ', /name, '.') join print.
Person: ->
Person::print: ->
print('My name is ' + this.name + '.')
class Person
print: ->
print 'My name is ' + this.name + '.'
# p = Person ()
# p /name string print
p: new Person()
print(p.name)
p: new Person
print p.name
# Policeman = Person class (rank): /rank = rank.
@@ -71,12 +70,13 @@ print(p.name)
#
# Policeman ('Constable') print
Policeman: (rank) -> this.rank: rank
Policeman extends Person
Policeman::print: ->
print('My name is ' + this.name + " and I'm a " + this.rank + '.')
class Policeman extends Person
constructor: (rank) ->
@rank: rank
print: ->
print 'My name is ' + this.name + " and I'm a " + this.rank + '.'
print(new Policeman('Constable'))
print new Policeman 'Constable'
# app = [window (width=200, height=400)
@@ -188,9 +188,9 @@ HomePage::get: (url) ->
# b /right = BTree ()
BTree: ->
b: new BTree()
b.left: new BTree()
b.right: new BTree()
b: new BTree
b.left: new BTree
b.right: new BTree
# BTree = class: /left, /right.
@@ -200,6 +200,6 @@ b.right: new BTree()
# 'left path found!' print.
BTree: ->
b: new BTree()
b: new BTree
print('left path found!') if b.left?

View File

@@ -1,96 +1,122 @@
# Underscore.coffee
# (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
# Underscore is freely distributable under the terms of the MIT license.
# Portions of Underscore are inspired by or borrowed from Prototype.js,
# Oliver Steele's Functional, and John Resig's Micro-Templating.
# **Underscore.coffee
# (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.**
# Underscore is freely distributable under the terms of the
# [MIT license](http://en.wikipedia.org/wiki/MIT_License).
# Portions of Underscore are inspired by or borrowed from
# [Prototype.js](http://prototypejs.org/api), Oliver Steele's
# [Functional](http://osteele.com), and John Resig's
# [Micro-Templating](http://ejohn.com).
# For all details and documentation:
# http://documentcloud.github.com/underscore/
# ------------------------- Baseline setup ---------------------------------
# Baseline setup
# --------------
# Establish the root object, "window" in the browser, or "global" on the server.
# Establish the root object, `window` in the browser, or `global` on the server.
root: this
# Save the previous value of the "_" variable.
# Save the previous value of the `_` variable.
previousUnderscore: root._
# If Underscore is called as a function, it returns a wrapped object that
# can be used OO-style. This wrapper holds altered versions of all the
# underscore functions. Wrapped objects may be chained.
wrapper: (obj) ->
this._wrapped: obj
this
# Establish the object that gets thrown to break out of a loop iteration.
# `StopIteration` is SOP on Mozilla.
breaker: if typeof(StopIteration) is 'undefined' then '__break__' else StopIteration
# Create a safe reference to the Underscore object forreference below.
_: root._: (obj) -> new wrapper(obj)
# Helper function to escape **RegExp** contents, because JS doesn't have one.
escapeRegExp: (string) -> string.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1')
# Export the Underscore object for CommonJS.
if typeof(exports) != 'undefined' then exports._: _
# Save bytes in the minified (but not gzipped) version:
ArrayProto: Array.prototype
ObjProto: Object.prototype
# Create quick reference variables for speed access to core prototypes.
slice: Array::slice
unshift: Array::unshift
toString: Object::toString
hasOwnProperty: Object::hasOwnProperty
propertyIsEnumerable: Object::propertyIsEnumerable
slice: ArrayProto.slice
unshift: ArrayProto.unshift
toString: ObjProto.toString
hasOwnProperty: ObjProto.hasOwnProperty
propertyIsEnumerable: ObjProto.propertyIsEnumerable
# All **ECMA5** native implementations we hope to use are declared here.
nativeForEach: ArrayProto.forEach
nativeMap: ArrayProto.map
nativeReduce: ArrayProto.reduce
nativeReduceRight: ArrayProto.reduceRight
nativeFilter: ArrayProto.filter
nativeEvery: ArrayProto.every
nativeSome: ArrayProto.some
nativeIndexOf: ArrayProto.indexOf
nativeLastIndexOf: ArrayProto.lastIndexOf
nativeIsArray: Array.isArray
nativeKeys: Object.keys
# Create a safe reference to the Underscore object for use below.
_: (obj) -> new wrapper(obj)
# Export the Underscore object for **CommonJS**.
if typeof(exports) != 'undefined' then exports._: _
# Export Underscore to global scope.
root._: _
# Current version.
_.VERSION: '0.5.8'
_.VERSION: '1.0.2'
# ------------------------ Collection Functions: ---------------------------
# Collection Functions
# --------------------
# The cornerstone, an each implementation.
# Handles objects implementing forEach, arrays, and raw objects.
# The cornerstone, an **each** implementation.
# Handles objects implementing **forEach**, arrays, and raw objects.
_.each: (obj, iterator, context) ->
index: 0
try
return obj.forEach(iterator, context) if obj.forEach
if _.isNumber(obj.length)
return iterator.call(context, obj[i], i, obj) for i in [0...obj.length]
iterator.call(context, val, key, obj) for key, val of obj
if nativeForEach and obj.forEach is nativeForEach
obj.forEach iterator, context
else if _.isNumber obj.length
iterator.call(context, obj[i], i, obj) for i in [0...obj.length]
else
iterator.call(context, val, key, obj) for key, val of obj
catch e
throw e if e isnt breaker
obj
# Return the results of applying the iterator to each element. Use JavaScript
# 1.6's version of map, if possible.
# 1.6's version of **map**, if possible.
_.map: (obj, iterator, context) ->
return obj.map(iterator, context) if (obj and _.isFunction(obj.map))
return obj.map(iterator, context) if nativeMap and obj.map is nativeMap
results: []
_.each obj, (value, index, list) ->
results.push(iterator.call(context, value, index, list))
results.push iterator.call context, value, index, list
results
# Reduce builds up a single result from a list of values. Also known as
# inject, or foldl. Uses JavaScript 1.8's version of reduce, if possible.
# **Reduce** builds up a single result from a list of values. Also known as
# **inject**, or **foldl**. Uses JavaScript 1.8's version of **reduce**, if possible.
_.reduce: (obj, memo, iterator, context) ->
return obj.reduce(_.bind(iterator, context), memo) if (obj and _.isFunction(obj.reduce))
return obj.reduce(_.bind(iterator, context), memo) if nativeReduce and obj.reduce is nativeReduce
_.each obj, (value, index, list) ->
memo: iterator.call(context, memo, value, index, list)
memo: iterator.call context, memo, value, index, list
memo
# The right-associative version of reduce, also known as foldr. Uses
# JavaScript 1.8's version of reduceRight, if available.
# The right-associative version of **reduce**, also known as **foldr**. Uses
# JavaScript 1.8's version of **reduceRight**, if available.
_.reduceRight: (obj, memo, iterator, context) ->
return obj.reduceRight(_.bind(iterator, context), memo) if (obj and _.isFunction(obj.reduceRight))
return obj.reduceRight(_.bind(iterator, context), memo) if nativeReduceRight and obj.reduceRight is nativeReduceRight
_.each _.clone(_.toArray(obj)).reverse(), (value, index) ->
memo: iterator.call(context, memo, value, index, obj)
memo: iterator.call context, memo, value, index, obj
memo
@@ -98,19 +124,19 @@
_.detect: (obj, iterator, context) ->
result: null
_.each obj, (value, index, list) ->
if iterator.call(context, value, index, list)
if iterator.call context, value, index, list
result: value
_.breakLoop()
result
# Return all the elements that pass a truth test. Use JavaScript 1.6's
# filter(), if it exists.
_.select: (obj, iterator, context) ->
if obj and _.isFunction(obj.filter) then return obj.filter(iterator, context)
# **filter**, if it exists.
_.filter: (obj, iterator, context) ->
return obj.filter iterator, context if nativeFilter and obj.filter is nativeFilter
results: []
_.each obj, (value, index, list) ->
results.push(value) if iterator.call(context, value, index, list)
results.push value if iterator.call context, value, index, list
results
@@ -118,15 +144,15 @@
_.reject: (obj, iterator, context) ->
results: []
_.each obj, (value, index, list) ->
results.push(value) if not iterator.call(context, value, index, list)
results.push value if not iterator.call context, value, index, list
results
# Determine whether all of the elements match a truth test. Delegate to
# JavaScript 1.6's every(), if it is present.
_.all: (obj, iterator, context) ->
# JavaScript 1.6's **every**, if it is present.
_.every: (obj, iterator, context) ->
iterator ||= _.identity
return obj.every(iterator, context) if obj and _.isFunction(obj.every)
return obj.every iterator, context if nativeEvery and obj.every is nativeEvery
result: true
_.each obj, (value, index, list) ->
_.breakLoop() unless (result: result and iterator.call(context, value, index, list))
@@ -134,10 +160,10 @@
# Determine if at least one element in the object matches a truth test. Use
# JavaScript 1.6's some(), if it exists.
_.any: (obj, iterator, context) ->
# JavaScript 1.6's **some**, if it exists.
_.some: (obj, iterator, context) ->
iterator ||= _.identity
return obj.some(iterator, context) if obj and _.isFunction(obj.some)
return obj.some iterator, context if nativeSome and obj.some is nativeSome
result: false
_.each obj, (value, index, list) ->
_.breakLoop() if (result: iterator.call(context, value, index, list))
@@ -145,9 +171,9 @@
# Determine if a given value is included in the array or object,
# based on '==='.
# based on `===`.
_.include: (obj, target) ->
return _.indexOf(obj, target) isnt -1 if obj and _.isFunction(obj.indexOf)
return _.indexOf(obj, target) isnt -1 if nativeIndexOf and obj.indexOf is nativeIndexOf
for key, val of obj
return true if val is target
false
@@ -155,13 +181,13 @@
# Invoke a method with arguments on every item in a collection.
_.invoke: (obj, method) ->
args: _.rest(arguments, 2)
args: _.rest arguments, 2
(if method then val[method] else val).apply(val, args) for val in obj
# Convenience version of a common use case of map: fetching a property.
# Convenience version of a common use case of **map**: fetching a property.
_.pluck: (obj, key) ->
_.map(obj, ((val) -> val[key]))
_.map(obj, (val) -> val[key])
# Return the maximum item or (item-based computation).
@@ -184,7 +210,7 @@
result.value
# Sort the object's values by a criteria produced by an iterator.
# Sort the object's values by a criterion produced by an iterator.
_.sortBy: (obj, iterator, context) ->
_.pluck(((_.map obj, (value, index, list) ->
{value: value, criteria: iterator.call(context, value, index, list)}
@@ -198,7 +224,8 @@
# be inserted so as to maintain order. Uses binary search.
_.sortedIndex: (array, obj, iterator) ->
iterator ||= _.identity
low: 0; high: array.length
low: 0
high: array.length
while low < high
mid: (low + high) >> 1
if iterator(array[mid]) < iterator(obj) then low: mid + 1 else high: mid
@@ -218,19 +245,20 @@
_.size: (obj) -> _.toArray(obj).length
# -------------------------- Array Functions: ------------------------------
# Array Functions
# ---------------
# Get the first element of an array. Passing "n" will return the first N
# values in the array. Aliased as "head". The "guard" check allows it to work
# with _.map.
# Get the first element of an array. Passing `n` will return the first N
# values in the array. Aliased as **head**. The `guard` check allows it to work
# with **map**.
_.first: (array, n, guard) ->
if n and not guard then slice.call(array, 0, n) else array[0]
# Returns everything but the first entry of the array. Aliased as "tail".
# Especially useful on the arguments object. Passing an "index" will return
# the rest of the values in the array from that index onward. The "guard"
# check allows it to work with _.map.
# Returns everything but the first entry of the array. Aliased as **tail**.
# Especially useful on the arguments object. Passing an `index` will return
# the rest of the values in the array from that index onward. The `guard`
# check allows it to work with **map**.
_.rest: (array, index, guard) ->
slice.call(array, if _.isUndefined(index) or guard then 1 else index)
@@ -246,30 +274,30 @@
# Return a completely flattened version of an array.
_.flatten: (array) ->
_.reduce array, [], (memo, value) ->
return memo.concat(_.flatten(value)) if _.isArray(value)
memo.push(value)
return memo.concat(_.flatten(value)) if _.isArray value
memo.push value
memo
# Return a version of the array that does not contain the specified value(s).
_.without: (array) ->
values: _.rest(arguments)
val for val in _.toArray(array) when not _.include(values, val)
values: _.rest arguments
val for val in _.toArray(array) when not _.include values, val
# Produce a duplicate-free version of the array. If the array has already
# been sorted, you have the option of using a faster algorithm.
_.uniq: (array, isSorted) ->
memo: []
for el, i in _.toArray(array)
memo.push(el) if i is 0 || (if isSorted is true then _.last(memo) isnt el else not _.include(memo, el))
for el, i in _.toArray array
memo.push el if i is 0 || (if isSorted is true then _.last(memo) isnt el else not _.include(memo, el))
memo
# Produce an array that contains every item shared between all the
# passed-in arrays.
_.intersect: (array) ->
rest: _.rest(arguments)
rest: _.rest arguments
_.select _.uniq(array), (item) ->
_.all rest, (other) ->
_.indexOf(other, item) >= 0
@@ -278,28 +306,28 @@
# Zip together multiple lists into a single array -- elements that share
# an index go together.
_.zip: ->
length: _.max(_.pluck(arguments, 'length'))
results: new Array(length)
length: _.max _.pluck arguments, 'length'
results: new Array length
for i in [0...length]
results[i]: _.pluck(arguments, String(i))
results[i]: _.pluck arguments, String i
results
# If the browser doesn't supply us with indexOf (I'm looking at you, MSIE),
# If the browser doesn't supply us with **indexOf** (I'm looking at you, MSIE),
# we need this function. Return the position of the first occurence of an
# item in an array, or -1 if the item is not included in the array.
_.indexOf: (array, item) ->
return array.indexOf(item) if array.indexOf
return array.indexOf item if nativeIndexOf and array.indexOf is nativeIndexOf
i: 0; l: array.length
while l - i
if array[i] is item then return i else i++
-1
# Provide JavaScript 1.6's lastIndexOf, delegating to the native function,
# Provide JavaScript 1.6's **lastIndexOf**, delegating to the native function,
# if possible.
_.lastIndexOf: (array, item) ->
return array.lastIndexOf(item) if array.lastIndexOf
return array.lastIndexOf(item) if nativeLastIndexOf and array.lastIndexOf is nativeLastIndexOf
i: array.length
while i
if array[i] is item then return i else i--
@@ -307,8 +335,7 @@
# Generate an integer Array containing an arithmetic progression. A port of
# the native Python range() function. See:
# http://docs.python.org/library/functions.html#range
# [the native Python **range** function](http://docs.python.org/library/functions.html#range).
_.range: (start, stop, step) ->
a: arguments
solo: a.length <= 1
@@ -317,50 +344,51 @@
step: a[2] or 1
len: Math.ceil((stop - start) / step)
return [] if len <= 0
range: new Array(len)
range: new Array len
idx: 0
while true
loop
return range if (if step > 0 then i - stop else stop - i) >= 0
range[idx]: i
idx++
i+= step
# ----------------------- Function Functions: -----------------------------
# Function Functions
# ------------------
# Create a function bound to a given object (assigning 'this', and arguments,
# optionally). Binding with arguments is also known as 'curry'.
# Create a function bound to a given object (assigning `this`, and arguments,
# optionally). Binding with arguments is also known as **curry**.
_.bind: (func, obj) ->
args: _.rest(arguments, 2)
-> func.apply(obj or root, args.concat(arguments))
args: _.rest arguments, 2
-> func.apply obj or root, args.concat arguments
# Bind all of an object's methods to that object. Useful for ensuring that
# all callbacks defined on an object belong to it.
_.bindAll: (obj) ->
funcs: if arguments.length > 1 then _.rest(arguments) else _.functions(obj)
_.each(funcs, (f) -> obj[f]: _.bind(obj[f], obj))
_.each funcs, (f) -> obj[f]: _.bind obj[f], obj
obj
# Delays a function for the given number of milliseconds, and then calls
# it with the arguments supplied.
_.delay: (func, wait) ->
args: _.rest(arguments, 2)
args: _.rest arguments, 2
setTimeout((-> func.apply(func, args)), wait)
# Defers a function, scheduling it to run after the current call stack has
# cleared.
_.defer: (func) ->
_.delay.apply(_, [func, 1].concat(_.rest(arguments)))
_.delay.apply _, [func, 1].concat _.rest arguments
# Returns the first function passed as an argument to the second,
# allowing you to adjust arguments, run code before and after, and
# conditionally execute the original function.
_.wrap: (func, wrapper) ->
-> wrapper.apply(wrapper, [func].concat(arguments))
-> wrapper.apply wrapper, [func].concat arguments
# Returns a function that is the composition of a list of functions, each
@@ -374,41 +402,42 @@
args[0]
# ------------------------- Object Functions: ----------------------------
# Object Functions
# ----------------
# Retrieve the names of an object's properties.
_.keys: (obj) ->
return _.range(0, obj.length) if _.isArray(obj)
_.keys: nativeKeys or (obj) ->
return _.range 0, obj.length if _.isArray(obj)
key for key, val of obj
# Retrieve the values of an object's properties.
_.values: (obj) ->
_.map(obj, _.identity)
_.map obj, _.identity
# Return a sorted list of the function names available in Underscore.
_.functions: (obj) ->
_.select(_.keys(obj), (key) -> _.isFunction(obj[key])).sort()
_.filter(_.keys(obj), (key) -> _.isFunction(obj[key])).sort()
# Extend a given object with all of the properties in a source object.
_.extend: (destination, source) ->
for key, val of source
destination[key]: val
destination
_.extend: (obj) ->
for source in _.rest(arguments)
(obj[key]: val) for key, val of source
obj
# Create a (shallow-cloned) duplicate of an object.
_.clone: (obj) ->
return obj.slice(0) if _.isArray(obj)
_.extend({}, obj)
return obj.slice 0 if _.isArray obj
_.extend {}, obj
# Invokes interceptor with the obj, and then returns obj.
# The primary purpose of this method is to "tap into" a method chain, in order to perform operations on intermediate results within the chain.
_.tap: (obj, interceptor) ->
interceptor(obj)
interceptor obj
obj
@@ -423,7 +452,7 @@
return true if `a == b`
# One is falsy and the other truthy.
return false if (!a and b) or (a and !b)
# One of them implements an isEqual()?
# One of them implements an `isEqual()`?
return a.isEqual(b) if a.isEqual
# Check dates' integer values.
return a.getTime() is b.getTime() if _.isDate(a) and _.isDate(b)
@@ -444,12 +473,15 @@
# Different object sizes?
return false if aKeys.length isnt bKeys.length
# Recursive comparison of contents.
# for (var key in a) if (!_.isEqual(a[key], b[key])) return false;
return true
(return false) for key, val of a when !(key in b) or !_.isEqual(val, b[key])
true
# Is a given array or object empty?
_.isEmpty: (obj) -> _.keys(obj).length is 0
_.isEmpty: (obj) ->
return obj.length is 0 if _.isArray obj
(return false) for key of obj when hasOwnProperty.call(obj, key)
true
# Is a given value a DOM element?
@@ -457,12 +489,11 @@
# Is a given value an array?
_.isArray: (obj) -> !!(obj and obj.concat and obj.unshift)
_.isArray: nativeIsArray or (obj) -> !!(obj and obj.concat and obj.unshift and not obj.callee)
# Is a given variable an arguments object?
_.isArguments: (obj) -> obj and _.isNumber(obj.length) and not obj.concat and
not obj.substr and not obj.apply and not propertyIsEnumerable.call(obj, 'length')
_.isArguments: (obj) -> obj and obj.callee
# Is the given value a function?
@@ -477,6 +508,10 @@
_.isNumber: (obj) -> (obj is +obj) or toString.call(obj) is '[object Number]'
# Is a given value a boolean?
_.isBoolean: (obj) -> obj is true or obj is false
# Is a given value a Date?
_.isDate: (obj) -> !!(obj and obj.getTimezoneOffset and obj.setUTCFullYear)
@@ -485,8 +520,8 @@
_.isRegExp: (obj) -> !!(obj and obj.exec and (obj.ignoreCase or obj.ignoreCase is false))
# Is the given value NaN -- this one is interesting. NaN != NaN, and
# isNaN(undefined) == true, so we make sure it's a number first.
# Is the given value NaN -- this one is interesting. `NaN != NaN`, and
# `isNaN(undefined) == true`, so we make sure it's a number first.
_.isNaN: (obj) -> _.isNumber(obj) and window.isNaN(obj)
@@ -498,9 +533,10 @@
_.isUndefined: (obj) -> typeof obj is 'undefined'
# -------------------------- Utility Functions: --------------------------
# Utility Functions
# -----------------
# Run Underscore.js in noConflict mode, returning the '_' variable to its
# Run Underscore.js in noConflict mode, returning the `_` variable to its
# previous owner. Returns a reference to the Underscore object.
_.noConflict: ->
root._: previousUnderscore
@@ -511,10 +547,22 @@
_.identity: (value) -> value
# Run a function `n` times.
_.times: (n, iterator, context) ->
iterator.call(context, i) for i in [0...n]
# Break out of the middle of an iteration.
_.breakLoop: -> throw breaker
# Add your own custom functions to the Underscore object, ensuring that
# they're correctly added to the OOP wrapper as well.
_.mixin: (obj) ->
for name in _.functions(obj)
addToWrapper name, _[name]: obj[name]
# Generate a unique integer id (unique within the entire client session).
# Useful for temporary DOM ids.
idCounter: 0
@@ -522,7 +570,7 @@
(prefix or '') + idCounter++
# By default, Underscore uses ERB-style template delimiters, change the
# By default, Underscore uses **ERB**-style template delimiters, change the
# following template settings to use alternative delimiters.
_.templateSettings: {
start: '<%'
@@ -531,16 +579,17 @@
}
# JavaScript templating a-la ERB, pilfered from John Resig's
# "Secrets of the JavaScript Ninja", page 83.
# Single-quote fix from Rick Strahl's version.
# JavaScript templating a-la **ERB**, pilfered from John Resig's
# *Secrets of the JavaScript Ninja*, page 83.
# Single-quote fix from Rick Strahl.
_.template: (str, data) ->
c: _.templateSettings
endMatch: new RegExp("'(?=[^"+c.end.substr(0, 1)+"]*"+escapeRegExp(c.end)+")","g")
fn: new Function 'obj',
'var p=[],print=function(){p.push.apply(p,arguments);};' +
'with(obj){p.push(\'' +
str.replace(/[\r\t\n]/g, " ")
.replace(new RegExp("'(?=[^"+c.end[0]+"]*"+c.end+")","g"),"\t")
.replace(endMatch,"\t")
.split("'").join("\\'")
.split("\t").join("'")
.replace(c.interpolate, "',$1,'")
@@ -550,32 +599,46 @@
if data then fn(data) else fn
# ------------------------------- Aliases ----------------------------------
# Aliases
# -------
_.forEach: _.each
_.foldl: _.inject: _.reduce
_.foldr: _.reduceRight
_.filter: _.select
_.every: _.all
_.some: _.any
_.select: _.filter
_.all: _.every
_.any: _.some
_.head: _.first
_.tail: _.rest
_.methods: _.functions
# ------------------------ Setup the OOP Wrapper: --------------------------
# Setup the OOP Wrapper
# ---------------------
# If Underscore is called as a function, it returns a wrapped object that
# can be used OO-style. This wrapper holds altered versions of all the
# underscore functions. Wrapped objects may be chained.
wrapper: (obj) ->
this._wrapped: obj
this
# Helper function to continue chaining intermediate results.
result: (obj, chain) ->
if chain then _(obj).chain() else obj
# Add all of the Underscore functions to the wrapper object.
_.each _.functions(_), (name) ->
method: _[name]
# A method to easily add functions to the OOP wrapper.
addToWrapper: (name, func) ->
wrapper.prototype[name]: ->
unshift.call(arguments, this._wrapped)
result(method.apply(_, arguments), this._chain)
args: _.toArray arguments
unshift.call args, this._wrapped
result func.apply(_, args), this._chain
# Add all of the Underscore functions to the wrapper object.
_.mixin _
# Add all mutator Array functions to the wrapper.

View File

@@ -1,12 +1,13 @@
# Contributed by Jason Huggins
sys: require 'sys'
http: require 'http'
server: http.createServer (req, res) ->
res.sendHeader 200, {'Content-Type': 'text/plain'}
res.sendBody 'Hello, World!'
res.finish()
res.writeHeader 200, {'Content-Type': 'text/plain'}
res.write 'Hello, World!'
res.end()
server.listen 3000
puts "Server running at http://localhost:3000/"
sys.puts "Server running at http://localhost:3000/"

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>name</key>
<string>comments</string>
<key>scope</key>
<string>source.coffee</string>
<key>settings</key>
<dict>
<key>shellVariables</key>
<array>
<dict>
<key>name</key>
<string>TM_COMMENT_START</string>
<key>value</key>
<string># </string>
</dict>
</array>
</dict>
<key>uuid</key>
<string>0A92C6F6-4D73-4859-B38C-4CC19CBC191F</string>
</dict>
</plist>

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