diff --git a/documentation/css/docs.css b/documentation/css/docs.css index dd2a4f86..d3688f31 100644 --- a/documentation/css/docs.css +++ b/documentation/css/docs.css @@ -1,7 +1,7 @@ body { font-size: 14px; line-height: 20px; - background: #efeff9; + background: #f3f3f9; color: #191933; font-family: Arial, Helvetica, sans-serif; } diff --git a/documentation/index.html.erb b/documentation/index.html.erb index 3df8a296..3f039253 100644 --- a/documentation/index.html.erb +++ b/documentation/index.html.erb @@ -42,10 +42,10 @@

Disclaimer: CoffeeScript is just for fun and seriously alpha. I'm sure that there are still - plenty of holes in the walls and leaks in the syntax. There is no guarantee, + plenty of holes in the lexer and leaks in the syntax. There is no guarantee, explicit or implied, of its suitability for any purpose. That said, it compiles into clean JavaScript (the good parts) that can use existing - JavaScript libraries seamlessly, and can pass through + JavaScript libraries seamlessly, and passes through JSLint without warnings. The compiled output is quite readable — pretty-printed, with comments preserved intact. @@ -63,12 +63,12 @@ Lexical Scoping and Variable Safety
Conditionals, Ternaries, and Conditional Assignment
Everything is an Expression
+ Aliases
While Loops
Array Comprehensions
Array Slice Literals
Calling Super from a Subclass
Embedded JavaScript
- Aliases
Switch/Case/Else
Try/Catch/Finally
Multiline Strings
@@ -88,7 +88,7 @@ sudo gem install coffee-script

Installing the gem provides the coffee-script command, which can be used to compile CoffeeScript .cs files into JavaScript, as - well as debug. By default, coffee-script writes out the + well as debug them. By default, coffee-script writes out the JavaScript as .js files in the same directory, but output can be customized with the following options:

@@ -103,7 +103,7 @@ sudo gem install coffee-script -w, --watch - Watch the modification times of the named scripts, recompiling as + Watch the modification times of the coffee-scripts, recompiling as soon as a change occurs. @@ -118,14 +118,15 @@ sudo gem install coffee-script -l, --lint If the jsl (JavaScript Lint) command is installed, use it - to check the compilation of a CoffeeScript file. + to check the compilation of a CoffeeScript file. (Handy in + conjunction with --watch) -e, --eval Compile and print a little snippet of CoffeeScript directly from the - command line. For example:
coffee-script -e "square: x => x * x." + command line (or from stdin). For example:
coffee-script -e "square: x => x * x." @@ -143,6 +144,12 @@ sudo gem install coffee-script AST. + + --install-bundle + + Install the TextMate bundle for CoffeeScript syntax highlighting. + +

@@ -160,10 +167,9 @@ coffee-script --print app/scripts/*.cs > concatenation.js This document is structured so that it can be read from top to bottom, if you like. Later sections use ideas and syntax previously introduced. + Familiarity with JavaScript is assumed. In all of the following examples, the source CoffeeScript is provided on the left, and the direct compilation into JavaScript is on the right. - Familiarity with JavaScript is assumed, although it would certainly - be nice to have a tutorial that builds from the ground up in the future.

@@ -173,7 +179,7 @@ coffee-script --print app/scripts/*.cs > concatenation.js the line will do just as well. All other whitespace is not significant. Instead of using curly braces { } to delimit a block of code, use a period . to mark the end of a - block for + block, for functions, if-statements, switch, and try/catch. @@ -181,9 +187,8 @@ coffee-script --print app/scripts/*.cs > concatenation.js

Functions and Invocation - Let's start with the best part of CoffeeScript, shall we? Functions are defined - by a list of parameters, an arrow, and the function body. The empty - function looks like this: =>. + Functions are defined by a list of parameters, an arrow, and the + function body. The empty function looks like this: =>.

<%= code_for('functions', 'cube(5)') %> @@ -207,18 +212,18 @@ coffee-script --print app/scripts/*.cs > concatenation.js

Lexical Scoping and Variable Safety The CoffeeScript compiler takes care to make sure that all of your variables - are properly defined within lexical scope — you never need to declare - var yourself. + are properly declared within lexical scope — you never need to write + var yourself.

<%= code_for('scope', 'new_num') %>

Notice how the variables are declared with var the first time they appear. The second reference of num, within the function, is not redeclared because num is still in scope. As opposed - to the second new_num, in the last line. + to the second occurrence of new_num, in the last line.

- Although suppressed within this documentation, all + Although suppressed within this documentation for clarity, all CoffeeScript output is wrapped in an anonymous function: (function(){ ... })(); This safety wrapper, combined with the automatic generation of the var keyword, make it exceedingly difficult @@ -243,7 +248,7 @@ coffee-script --print app/scripts/*.cs > concatenation.js

Everything is an Expression (at least, as much as possible) You might have noticed how even though we don't add return statements - to CoffeScript functions, they nonetheless return their final value. + to CoffeeScript functions, they nonetheless return their final value. The CoffeeScript compiler tries to make sure that all statements in the language can be used as expressions. Watch how the return gets pushed down into each possible branch of execution, in the function @@ -251,9 +256,30 @@ coffee-script --print app/scripts/*.cs > concatenation.js

<%= code_for('expressions', 'eldest') %>

- The same mechanism is used to push down assignment statements, switch - statements, and if-elses (although the ternary operator is preferred). + The same mechanism is used to push down assignment through switch + statements, and if-elses (although the ternary operator is preferred).

+ +

+ Aliases + Because the == operator frequently causes undesirable coercion, + is intransitive, and has a different meaning than in other languages, + CoffeeScript compiles == into ===, and != into + !==. + In addition, is compiles into ===, + and aint into !==. +

+

+ You can use not as an alias for !. +

+

+ As in YAML, on and yes + are the same as boolean true, while off and no are boolean false. +

+

+ For single-line statements, unless can be used as the inverse of if. +

+ <%= code_for('aliases') %>

While Loops @@ -310,30 +336,9 @@ coffee-script --print app/scripts/*.cs > concatenation.js

<%= code_for('embedded', 'hi()') %> -

- Aliases - Because the == operator frequently causes undesirable coercion, - is intransitive, and has a different meaning than in other languages, - CoffeeScript compiles == into ===, and != into - !==. - In addition, is compiles into ===, - and aint into !==. -

-

- You can use not as an alias for !. -

-

- As in YAML, on and yes - are the same as boolean true, while off and no are boolean false. -

-

- For single-line statements, unless can be used as the inverse of if. -

- <%= code_for('aliases') %> -

Switch/Case/Else - Switch statements in JavaScript are rather broken. You can only + Switch statements in JavaScript are rather broken. You can only do string comparisons, and need to remember to break at the end of every case statement to avoid accidentally falling through to the default case. CoffeeScript @@ -346,7 +351,7 @@ coffee-script --print app/scripts/*.cs > concatenation.js

Try/Catch/Finally - Try/catch statements just about the same as JavaScript (although + Try/catch statements are just about the same as JavaScript (although they work as expressions). No braces required.

<%= code_for('try') %> diff --git a/index.html b/index.html index 1b6152f5..a34ac81d 100644 --- a/index.html +++ b/index.html @@ -28,10 +28,10 @@

Disclaimer: CoffeeScript is just for fun and seriously alpha. I'm sure that there are still - plenty of holes in the walls and leaks in the syntax. There is no guarantee, + plenty of holes in the lexer and leaks in the syntax. There is no guarantee, explicit or implied, of its suitability for any purpose. That said, it compiles into clean JavaScript (the good parts) that can use existing - JavaScript libraries seamlessly, and can pass through + JavaScript libraries seamlessly, and passes through JSLint without warnings. The compiled output is quite readable — pretty-printed, with comments preserved intact. @@ -49,12 +49,12 @@ Lexical Scoping and Variable Safety
Conditionals, Ternaries, and Conditional Assignment
Everything is an Expression
+ Aliases
While Loops
Array Comprehensions
Array Slice Literals
Calling Super from a Subclass
Embedded JavaScript
- Aliases
Switch/Case/Else
Try/Catch/Finally
Multiline Strings
@@ -158,7 +158,7 @@ sudo gem install coffee-script

Installing the gem provides the coffee-script command, which can be used to compile CoffeeScript .cs files into JavaScript, as - well as debug. By default, coffee-script writes out the + well as debug them. By default, coffee-script writes out the JavaScript as .js files in the same directory, but output can be customized with the following options:

@@ -173,7 +173,7 @@ sudo gem install coffee-script -w, --watch - Watch the modification times of the named scripts, recompiling as + Watch the modification times of the coffee-scripts, recompiling as soon as a change occurs. @@ -188,14 +188,15 @@ sudo gem install coffee-script -l, --lint If the jsl (JavaScript Lint) command is installed, use it - to check the compilation of a CoffeeScript file. + to check the compilation of a CoffeeScript file. (Handy in + conjunction with --watch) -e, --eval Compile and print a little snippet of CoffeeScript directly from the - command line. For example:
coffee-script -e "square: x => x * x." + command line (or from stdin). For example:
coffee-script -e "square: x => x * x." @@ -213,6 +214,12 @@ sudo gem install coffee-script AST. + + --install-bundle + + Install the TextMate bundle for CoffeeScript syntax highlighting. + +

@@ -230,10 +237,9 @@ coffee-script --print app/scripts/*.cs > concatenation.js This document is structured so that it can be read from top to bottom, if you like. Later sections use ideas and syntax previously introduced. + Familiarity with JavaScript is assumed. In all of the following examples, the source CoffeeScript is provided on the left, and the direct compilation into JavaScript is on the right. - Familiarity with JavaScript is assumed, although it would certainly - be nice to have a tutorial that builds from the ground up in the future.

@@ -243,7 +249,7 @@ coffee-script --print app/scripts/*.cs > concatenation.js the line will do just as well. All other whitespace is not significant. Instead of using curly braces { } to delimit a block of code, use a period . to mark the end of a - block for + block, for functions, if-statements, switch, and try/catch. @@ -251,9 +257,8 @@ coffee-script --print app/scripts/*.cs > concatenation.js

Functions and Invocation - Let's start with the best part of CoffeeScript, shall we? Functions are defined - by a list of parameters, an arrow, and the function body. The empty - function looks like this: =>. + Functions are defined by a list of parameters, an arrow, and the + function body. The empty function looks like this: =>.

square: x => x * x.
 cube:   x => square(x) * x.
@@ -315,8 +320,8 @@ var ages = {
     

Lexical Scoping and Variable Safety The CoffeeScript compiler takes care to make sure that all of your variables - are properly defined within lexical scope — you never need to declare - var yourself. + are properly declared within lexical scope — you never need to write + var yourself.

num: 1
 change_numbers: =>
@@ -342,10 +347,10 @@ var new_num = change_numbers();
       Notice how the variables are declared with var the first time
       they appear. The second reference of num, within the function,
       is not redeclared because num is still in scope. As opposed
-      to the second new_num, in the last line.
+      to the second occurrence of new_num, in the last line.
     

- Although suppressed within this documentation, all + Although suppressed within this documentation for clarity, all CoffeeScript output is wrapped in an anonymous function: (function(){ ... })(); This safety wrapper, combined with the automatic generation of the var keyword, make it exceedingly difficult @@ -389,7 +394,7 @@ expensive = expensive || Everything is an Expression (at least, as much as possible) You might have noticed how even though we don't add return statements - to CoffeScript functions, they nonetheless return their final value. + to CoffeeScript functions, they nonetheless return their final value. The CoffeeScript compiler tries to make sure that all statements in the language can be used as expressions. Watch how the return gets pushed down into each possible branch of execution, in the function @@ -426,9 +431,45 @@ eldest: if 21 ? "Liz" : "Ike"; ;alert(eldest);'>run: eldest

- The same mechanism is used to push down assignment statements, switch - statements, and if-elses (although the ternary operator is preferred). + The same mechanism is used to push down assignment through switch + statements, and if-elses (although the ternary operator is preferred).

+ +

+ Aliases + Because the == operator frequently causes undesirable coercion, + is intransitive, and has a different meaning than in other languages, + CoffeeScript compiles == into ===, and != into + !==. + In addition, is compiles into ===, + and aint into !==. +

+

+ You can use not as an alias for !. +

+

+ As in YAML, on and yes + are the same as boolean true, while off and no are boolean false. +

+

+ For single-line statements, unless can be used as the inverse of if. +

+
launch() if ignition is on
+
+volume: 10 if band aint spinal_tap
+
+let_the_wild_rumpus_begin() unless answer is no
+
if (ignition === true) {
+  launch();
+}
+var volume;
+if (band !== spinal_tap) {
+  volume = 10;
+}
+if (!(answer === false)) {
+  let_the_wild_rumpus_begin();
+}
+

While Loops @@ -537,6 +578,10 @@ tom: new var Animal = function() { }; Animal.prototype.move = function(meters) { @@ -606,45 +651,9 @@ return [document.title, "Hello JavaScript"].join(": "); }; ;alert(hi());'>run: hi()

-

- Aliases - Because the == operator frequently causes undesirable coercion, - is intransitive, and has a different meaning than in other languages, - CoffeeScript compiles == into ===, and != into - !==. - In addition, is compiles into ===, - and aint into !==. -

-

- You can use not as an alias for !. -

-

- As in YAML, on and yes - are the same as boolean true, while off and no are boolean false. -

-

- For single-line statements, unless can be used as the inverse of if. -

-
launch() if ignition is on
-
-volume: 10 if band aint spinal_tap
-
-let_the_wild_rumpus_begin() unless answer is no
-
if (ignition === true) {
-  launch();
-}
-var volume;
-if (band !== spinal_tap) {
-  volume = 10;
-}
-if (!(answer === false)) {
-  let_the_wild_rumpus_begin();
-}
-

-

Switch/Case/Else - Switch statements in JavaScript are rather broken. You can only + Switch statements in JavaScript are rather broken. You can only do string comparisons, and need to remember to break at the end of every case statement to avoid accidentally falling through to the default case. CoffeeScript @@ -680,7 +689,7 @@ let_the_wild_rumpus_begin() unless answer Try/Catch/Finally - Try/catch statements just about the same as JavaScript (although + Try/catch statements are just about the same as JavaScript (although they work as expressions). No braces required.

try
diff --git a/lib/coffee_script/command_line.rb b/lib/coffee_script/command_line.rb
index 19ed27d0..2ab75295 100644
--- a/lib/coffee_script/command_line.rb
+++ b/lib/coffee_script/command_line.rb
@@ -10,7 +10,7 @@ module CoffeeScript
   class CommandLine
 
     BANNER = <<-EOS
-coffee-script compiles CoffeeScript files into JavaScript.
+coffee-script compiles CoffeeScript source files into JavaScript.
 
 Usage:
   coffee-script path/to/script.cs
diff --git a/lib/coffee_script/grammar.y b/lib/coffee_script/grammar.y
index 65941b37..d9ea226c 100644
--- a/lib/coffee_script/grammar.y
+++ b/lib/coffee_script/grammar.y
@@ -273,13 +273,15 @@ rule
 
   # Try/catch/finally exception handling blocks.
   Try:
-    TRY Expressions CATCH IDENTIFIER
-      Expressions "."                 { result = TryNode.new(val[1], val[3], val[4]) }
-  | TRY Expressions FINALLY
-      Expressions "."                 { result = TryNode.new(val[1], nil, nil, val[3]) }
-  | TRY Expressions CATCH IDENTIFIER
-      Expressions
-      FINALLY Expressions "."         { result = TryNode.new(val[1], val[3], val[4], val[6]) }
+    TRY Expressions Catch "."         { result = TryNode.new(val[1], val[2][0], val[2][1]) }
+  | TRY Expressions Catch
+    FINALLY Then Expressions "."      { result = TryNode.new(val[1], val[2][0], val[2][1], val[5]) }
+  ;
+
+  # A catch clause.
+  Catch:
+    /* nothing */                     { result = [nil, nil] }
+  | CATCH IDENTIFIER Then Expressions { result = [val[1], val[3]] }
   ;
 
   # Throw an exception.
diff --git a/lib/coffee_script/nodes.rb b/lib/coffee_script/nodes.rb
index 2367a03a..38fac8bc 100644
--- a/lib/coffee_script/nodes.rb
+++ b/lib/coffee_script/nodes.rb
@@ -541,7 +541,8 @@ module CoffeeScript
       o = super(o)
       indent = o[:indent]
       o[:indent] += TAB
-      catch_part = @recovery &&  " catch (#{@error}) {\n#{@recovery.compile(o)}\n#{indent}}"
+      error_part = @error ? " (#{@error}) " : ' '
+      catch_part = @recovery &&  " catch#{error_part}{\n#{@recovery.compile(o)}\n#{indent}}"
       finally_part = @finally && " finally {\n#{@finally.compile(o.merge(:assign => nil, :return => nil))}\n#{indent}}"
       write("try {\n#{@try.compile(o)}\n#{indent}}#{catch_part}#{finally_part}")
     end