From c2bb93b5f8df960131a68b919642ac5900828f31 Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Tue, 5 Jan 2010 21:40:36 -0500 Subject: [PATCH] ellipsis is the new splat --- documentation/coffee/overview.coffee | 2 +- documentation/coffee/splats.coffee | 4 +-- documentation/index.html.erb | 32 ++++++++-------------- index.html | 25 ++++++++++------- lib/coffee_script/grammar.y | 8 +++--- lib/coffee_script/lexer.rb | 3 +- test/fixtures/execution/test_splats.coffee | 6 ++-- 7 files changed, 38 insertions(+), 42 deletions(-) diff --git a/documentation/coffee/overview.coffee b/documentation/coffee/overview.coffee index 295f38a1..6c940d9f 100644 --- a/documentation/coffee/overview.coffee +++ b/documentation/coffee/overview.coffee @@ -19,7 +19,7 @@ math: { } # Splats: -race: winner, *runners => +race: winner, runners... => print(winner, runners) # Existence: diff --git a/documentation/coffee/splats.coffee b/documentation/coffee/splats.coffee index de02d242..035b902f 100644 --- a/documentation/coffee/splats.coffee +++ b/documentation/coffee/splats.coffee @@ -1,6 +1,6 @@ gold: silver: the_field: "unknown" -medalists: first, second, *rest => +medalists: first, second, rest... => gold: first silver: second the_field: rest @@ -18,7 +18,7 @@ contenders: [ "Usain Bolt" ] -medalists(*contenders) +medalists(contenders...) alert("Gold: " + gold) alert("Silver: " + silver) diff --git a/documentation/index.html.erb b/documentation/index.html.erb index ecf0ca55..9a927bf3 100644 --- a/documentation/index.html.erb +++ b/documentation/index.html.erb @@ -1,18 +1,3 @@ -<%# - TODO: - Multiline and nested array comprehensions (and filters with 'when'). - Range comprehension examples (expression endpoints), with steps. - Object comprehension examples. - Significant Whitespace Rules. - Newline-delimited Matrix. - Automatic newline escaping. - All functions are named functions. - Splats in function definitions. - (Multiple) splats as arguments to a function call. - Exists? - Array assignment splice literals. -%> - <% require 'uv' def code_for(file, executable=false) @@ -82,7 +67,7 @@ Conditionals, Ternaries, and Conditional Assignment
The Existence Operator
Aliases
- Splats
+ Splats...
Arguments are Arrays
While Loops
Comprehensions (Arrays, Objects, and Ranges)
@@ -250,6 +235,13 @@ coffee --print app/scripts/*.coffee > concatenation.js use indentation.

+

+ You can use newlines to break up your expression into smaller pieces, + as long as CoffeeScript can tell that the line hasn't finished + (similar to how Ruby handles it). For example, + if the line ends in an operator, dot, or keyword. +

+

Functions and Invocation Functions are defined by a list of parameters, an arrow, and the @@ -365,10 +357,10 @@ coffee --print app/scripts/*.coffee > concatenation.js <%= code_for('aliases') %>

- Splats + Splats... The JavaScript arguments object is a useful way to work with functions that accept variable numbers of arguments. CoffeeScript provides - splats *, both for function definition as well as invocation, + splats ..., both for function definition as well as invocation, making variable arguments a little bit more palatable.

<%= code_for('splats', true) %> @@ -376,8 +368,8 @@ coffee --print app/scripts/*.coffee > concatenation.js

Arguments are Arrays If you reference the arguments object directly, it will be converted - into a real Array, making all of the - Array methods + into a real Array, making all of the + Array methods available.

<%= code_for('arguments', true) %> diff --git a/index.html b/index.html index e80a0b4b..dcbabd77 100644 --- a/index.html +++ b/index.html @@ -1,8 +1,6 @@ - - @@ -55,7 +53,7 @@ Conditionals, Ternaries, and Conditional Assignment
The Existence Operator
Aliases
- Splats
+ Splats...
Arguments are Arrays
While Loops
Comprehensions (Arrays, Objects, and Ranges)
@@ -97,7 +95,7 @@ math: { } # Splats: -race: winner, *runners => +race: winner, runners... => print(winner, runners) # Existence: @@ -342,6 +340,13 @@ coffee --print app/scripts/*.coffee > concatenation.js use indentation.

+

+ You can use newlines to break up your expression into smaller pieces, + as long as CoffeeScript can tell that the line hasn't finished + (similar to how Ruby handles it). For example, + if the line ends in an operator, dot, or keyword. +

+

Functions and Invocation Functions are defined by a list of parameters, an arrow, and the @@ -573,15 +578,15 @@ car.speed < speed_limit ? accelerate() :

- Splats + Splats... The JavaScript arguments object is a useful way to work with functions that accept variable numbers of arguments. CoffeeScript provides - splats *, both for function definition as well as invocation, + splats ..., both for function definition as well as invocation, making variable arguments a little bit more palatable.

gold: silver: the_field: "unknown"
 
-medalists: first, second, *rest =>
+medalists: first, second, rest... =>
   gold:       first
   silver:     second
   the_field:  rest
@@ -599,7 +604,7 @@ contenders: [
   "Usain Bolt"
 ]
 
-medalists(*contenders)
+medalists(contenders...)
 
 alert("Gold: " + gold)
 alert("Silver: " + silver)
@@ -637,8 +642,8 @@ alert("The Field: " + the_field);
     

Arguments are Arrays If you reference the arguments object directly, it will be converted - into a real Array, making all of the - Array methods + into a real Array, making all of the + Array methods available.

backwards: =>
diff --git a/lib/coffee_script/grammar.y b/lib/coffee_script/grammar.y
index 5ba10e26..6979c317 100644
--- a/lib/coffee_script/grammar.y
+++ b/lib/coffee_script/grammar.y
@@ -5,7 +5,7 @@ token IF ELSE UNLESS
 token NUMBER STRING REGEX
 token TRUE FALSE YES NO ON OFF
 token IDENTIFIER PROPERTY_ACCESS
-token CODE PARAM PARAM_SPLAT NEW RETURN
+token CODE PARAM NEW RETURN
 token TRY CATCH FINALLY THROW
 token BREAK CONTINUE
 token FOR IN BY WHEN WHILE
@@ -21,7 +21,7 @@ token INDENT OUTDENT
 # Declare order of operations.
 prechigh
   left     '?'
-  nonassoc UMINUS PARAM_SPLAT SPLAT NOT '!' '!!' '~' '++' '--'
+  nonassoc UMINUS NOT '!' '!!' '~' '++' '--'
   left     '*' '/' '%'
   left     '+' '-'
   left     '<<' '>>' '>>>'
@@ -204,11 +204,11 @@ rule
 
   Param:
     PARAM
-  | PARAM_SPLAT PARAM                 { result = ParamSplatNode.new(val[1]) }
+  | PARAM "." "." "."                 { result = ParamSplatNode.new(val[0]) }
   ;
 
   Splat:
-    '*' Value = SPLAT                 { result = ArgSplatNode.new(val[1]) }
+    Expression "." "." "."            { result = ArgSplatNode.new(val[0])}
   ;
 
   # Expressions that can be treated as values.
diff --git a/lib/coffee_script/lexer.rb b/lib/coffee_script/lexer.rb
index 798156a6..742ef132 100644
--- a/lib/coffee_script/lexer.rb
+++ b/lib/coffee_script/lexer.rb
@@ -221,8 +221,7 @@ module CoffeeScript
         i -= 1
         tok = @tokens[i]
         return if !tok
-        next if tok[0] == ','
-        next tok[0] = :PARAM_SPLAT if tok[0] == '*'
+        next if ['.', ','].include?(tok[0])
         return if tok[0] != :IDENTIFIER
         tok[0] = :PARAM
       end
diff --git a/test/fixtures/execution/test_splats.coffee b/test/fixtures/execution/test_splats.coffee
index c5881bbe..683998d3 100644
--- a/test/fixtures/execution/test_splats.coffee
+++ b/test/fixtures/execution/test_splats.coffee
@@ -1,4 +1,4 @@
-func: first, second, *rest =>
+func: first, second, rest... =>
   rest.join(' ')
 
 result: func(1, 2, 3, 4, 5)
@@ -8,7 +8,7 @@ print(result is "3 4 5")
 
 gold: silver: bronze: the_field: null
 
-medalists: first, second, third, *rest =>
+medalists: first, second, third, rest... =>
   gold:       first
   silver:     second
   bronze:     third
@@ -27,7 +27,7 @@ contenders: [
   "Usain Bolt"
 ]
 
-medalists("Mighty Mouse", *contenders)
+medalists("Mighty Mouse", contenders...)
 
 print(gold is "Mighty Mouse")
 print(silver is "Michael Phelps")