1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00

changing switch/case to switch/when -- it's a better word

This commit is contained in:
Jeremy Ashkenas 2009-12-24 01:33:59 -08:00
parent 849f0e4192
commit 8d76f4bd3f
13 changed files with 85 additions and 38 deletions

View file

@ -3,3 +3,5 @@ launch() if ignition is on
volume: 10 if band aint spinal_tap volume: 10 if band aint spinal_tap
let_the_wild_rumpus_begin() unless answer is no let_the_wild_rumpus_begin() unless answer is no
if car.speed < speed_limit then accelerate().

View file

@ -1,9 +1,9 @@
switch day switch day
case "Tuesday" then eat_breakfast() when "Tuesday" then eat_breakfast()
case "Wednesday" then go_to_the_park() when "Wednesday" then go_to_the_park()
case "Saturday" when "Saturday"
if day is bingo_day if day is bingo_day
go_to_bingo() go_to_bingo()
go_dancing(). go_dancing().
case "Sunday" then go_to_church() when "Sunday" then go_to_church()
else go_to_work(). else go_to_work().

View file

@ -69,7 +69,7 @@
<a href="#slice">Array Slice Literals</a><br /> <a href="#slice">Array Slice Literals</a><br />
<a href="#super">Calling Super from a Subclass</a><br /> <a href="#super">Calling Super from a Subclass</a><br />
<a href="#embedded">Embedded JavaScript</a><br /> <a href="#embedded">Embedded JavaScript</a><br />
<a href="#switch">Switch/Case/Else</a><br /> <a href="#switch">Switch/When/Else</a><br />
<a href="#try">Try/Catch/Finally</a><br /> <a href="#try">Try/Catch/Finally</a><br />
<a href="#strings">Multiline Strings</a><br /> <a href="#strings">Multiline Strings</a><br />
<a href="#change_log">Change Log</a><br /> <a href="#change_log">Change Log</a><br />
@ -278,6 +278,11 @@ coffee-script --print app/scripts/*.cs > concatenation.js</pre>
<p> <p>
You can use <tt>not</tt> as an alias for <tt>!</tt>. You can use <tt>not</tt> as an alias for <tt>!</tt>.
</p> </p>
<p>
Instead of a newline or semicolon, <tt>then</tt> can be used to separate
conditions from expressions, in <b>while</b>,
<b>if</b>/<b>else</b>, and <b>switch</b>/<b>when</b> statements.
</p>
<p> <p>
As in <a href="http://yaml.org/">YAML</a>, <tt>on</tt> and <tt>yes</tt> As in <a href="http://yaml.org/">YAML</a>, <tt>on</tt> and <tt>yes</tt>
are the same as boolean <tt>true</tt>, while <tt>off</tt> and <tt>no</tt> are boolean <tt>false</tt>. are the same as boolean <tt>true</tt>, while <tt>off</tt> and <tt>no</tt> are boolean <tt>false</tt>.
@ -343,15 +348,14 @@ coffee-script --print app/scripts/*.cs > concatenation.js</pre>
<%= code_for('embedded', 'hi()') %> <%= code_for('embedded', 'hi()') %>
<p id="switch"> <p id="switch">
<b class="header">Switch/Case/Else</b> <b class="header">Switch/When/Else</b>
<b>Switch</b> statements in JavaScript are rather broken. You can only <b>Switch</b> statements in JavaScript are rather broken. You can only
do comparisons based on string equality, and need to remember to <b>break</b> at the end of do comparisons based on string equality, and need to remember to <b>break</b> at the end of
every <b>case</b> statement to avoid accidentally falling through to every <b>case</b> statement to avoid accidentally falling through to
the default case. CoffeeScript the default case. CoffeeScript compiles <b>switch</b> statements into JavaScript if-else chains, allowing you to
compiles <b>switch</b> statements into JavaScript if-else chains, allowing you to
compare any object (via <b>===</b>), preventing fall-through, and resulting compare any object (via <b>===</b>), preventing fall-through, and resulting
in a returnable, assignable expression. To specify the default case, just in a returnable, assignable expression. The format is: <tt>switch</tt> condition,
use <tt>else</tt>. <tt>when</tt> clauses, <tt>else</tt> the default case.
</p> </p>
<%= code_for('switch') %> <%= code_for('switch') %>

View file

@ -9,4 +9,5 @@
if (!(answer === false)) { if (!(answer === false)) {
let_the_wild_rumpus_begin(); let_the_wild_rumpus_begin();
} }
car.speed < speed_limit ? accelerate() : null;
})(); })();

View file

@ -6,6 +6,7 @@
}; };
var Snake = function(name) { var Snake = function(name) {
this.name = name; this.name = name;
return this.name;
}; };
Snake.prototype = new Animal(); Snake.prototype = new Animal();
Snake.prototype.move = function() { Snake.prototype.move = function() {
@ -14,6 +15,7 @@
}; };
var Horse = function(name) { var Horse = function(name) {
this.name = name; this.name = name;
return this.name;
}; };
Horse.prototype = new Animal(); Horse.prototype = new Animal();
Horse.prototype.move = function() { Horse.prototype.move = function() {

View file

@ -115,10 +115,10 @@ drink(bottle) for bottle, i in ['soda', 'wine', 'lemonade'] if even(i).
# Switch statements ("else" serves as a default). # Switch statements ("else" serves as a default).
activity: switch day activity: switch day
case "Tuesday" then eat_breakfast() when "Tuesday" then eat_breakfast()
case "Sunday" then go_to_church() when "Sunday" then go_to_church()
case "Saturday" then go_to_the_park() when "Saturday" then go_to_the_park()
case "Wednesday" when "Wednesday"
if day is bingo_day if day is bingo_day
go_to_bingo() go_to_bingo()
else else

View file

@ -55,7 +55,7 @@
<a href="#slice">Array Slice Literals</a><br /> <a href="#slice">Array Slice Literals</a><br />
<a href="#super">Calling Super from a Subclass</a><br /> <a href="#super">Calling Super from a Subclass</a><br />
<a href="#embedded">Embedded JavaScript</a><br /> <a href="#embedded">Embedded JavaScript</a><br />
<a href="#switch">Switch/Case/Else</a><br /> <a href="#switch">Switch/When/Else</a><br />
<a href="#try">Try/Catch/Finally</a><br /> <a href="#try">Try/Catch/Finally</a><br />
<a href="#strings">Multiline Strings</a><br /> <a href="#strings">Multiline Strings</a><br />
<a href="#change_log">Change Log</a><br /> <a href="#change_log">Change Log</a><br />
@ -453,6 +453,11 @@ var eldest = 24 > 21 ? "Liz" : "Ike";
<p> <p>
You can use <tt>not</tt> as an alias for <tt>!</tt>. You can use <tt>not</tt> as an alias for <tt>!</tt>.
</p> </p>
<p>
Instead of a newline or semicolon, <tt>then</tt> can be used to separate
conditions from expressions, in <b>while</b>,
<b>if</b>/<b>else</b>, and <b>switch</b>/<b>when</b> statements.
</p>
<p> <p>
As in <a href="http://yaml.org/">YAML</a>, <tt>on</tt> and <tt>yes</tt> As in <a href="http://yaml.org/">YAML</a>, <tt>on</tt> and <tt>yes</tt>
are the same as boolean <tt>true</tt>, while <tt>off</tt> and <tt>no</tt> are boolean <tt>false</tt>. are the same as boolean <tt>true</tt>, while <tt>off</tt> and <tt>no</tt> are boolean <tt>false</tt>.
@ -465,6 +470,8 @@ var eldest = 24 > 21 ? "Liz" : "Ike";
volume<span class="Keyword">:</span> <span class="Number">10</span> <span class="Keyword">if</span> band <span class="Keyword">aint</span> spinal_tap volume<span class="Keyword">:</span> <span class="Number">10</span> <span class="Keyword">if</span> band <span class="Keyword">aint</span> spinal_tap
let_the_wild_rumpus_begin() <span class="Keyword">unless</span> answer <span class="Keyword">is</span> <span class="BuiltInConstant">no</span> let_the_wild_rumpus_begin() <span class="Keyword">unless</span> answer <span class="Keyword">is</span> <span class="BuiltInConstant">no</span>
<span class="Keyword">if</span> car.speed <span class="Keyword">&lt;</span> speed_limit <span class="Keyword">then</span> accelerate().
</pre><pre class="idle"><span class="Keyword">if</span> (ignition <span class="Keyword">===</span> <span class="BuiltInConstant">true</span>) { </pre><pre class="idle"><span class="Keyword">if</span> (ignition <span class="Keyword">===</span> <span class="BuiltInConstant">true</span>) {
launch(); launch();
} }
@ -475,6 +482,7 @@ let_the_wild_rumpus_begin() <span class="Keyword">unless</span> answer <span cla
<span class="Keyword">if</span> (<span class="Keyword">!</span>(answer <span class="Keyword">===</span> <span class="BuiltInConstant">false</span>)) { <span class="Keyword">if</span> (<span class="Keyword">!</span>(answer <span class="Keyword">===</span> <span class="BuiltInConstant">false</span>)) {
let_the_wild_rumpus_begin(); let_the_wild_rumpus_begin();
} }
car.speed <span class="Keyword">&lt;</span> speed_limit ? accelerate() : <span class="BuiltInConstant">null</span>;
</pre><br class='clear' /></div> </pre><br class='clear' /></div>
<p id="while"> <p id="while">
@ -595,6 +603,7 @@ tom.move()
}; };
<span class="Storage">var</span> <span class="FunctionName">Snake</span> = <span class="Storage">function</span>(<span class="FunctionArgument">name</span>) { <span class="Storage">var</span> <span class="FunctionName">Snake</span> = <span class="Storage">function</span>(<span class="FunctionArgument">name</span>) {
<span class="Variable">this</span>.<span class="LibraryConstant">name</span> <span class="Keyword">=</span> name; <span class="Variable">this</span>.<span class="LibraryConstant">name</span> <span class="Keyword">=</span> name;
<span class="Keyword">return</span> <span class="Variable">this</span>.<span class="LibraryConstant">name</span>;
}; };
<span class="LibraryClassType">Snake</span>.<span class="LibraryConstant">prototype</span> = <span class="Keyword">new</span> <span class="TypeName">Animal</span>(); <span class="LibraryClassType">Snake</span>.<span class="LibraryConstant">prototype</span> = <span class="Keyword">new</span> <span class="TypeName">Animal</span>();
<span class="LibraryClassType">Snake</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">move</span> = <span class="Storage">function</span>() { <span class="LibraryClassType">Snake</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">move</span> = <span class="Storage">function</span>() {
@ -603,6 +612,7 @@ tom.move()
}; };
<span class="Storage">var</span> <span class="FunctionName">Horse</span> = <span class="Storage">function</span>(<span class="FunctionArgument">name</span>) { <span class="Storage">var</span> <span class="FunctionName">Horse</span> = <span class="Storage">function</span>(<span class="FunctionArgument">name</span>) {
<span class="Variable">this</span>.<span class="LibraryConstant">name</span> <span class="Keyword">=</span> name; <span class="Variable">this</span>.<span class="LibraryConstant">name</span> <span class="Keyword">=</span> name;
<span class="Keyword">return</span> <span class="Variable">this</span>.<span class="LibraryConstant">name</span>;
}; };
<span class="LibraryClassType">Horse</span>.<span class="LibraryConstant">prototype</span> = <span class="Keyword">new</span> <span class="TypeName">Animal</span>(); <span class="LibraryClassType">Horse</span>.<span class="LibraryConstant">prototype</span> = <span class="Keyword">new</span> <span class="TypeName">Animal</span>();
<span class="LibraryClassType">Horse</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">move</span> = <span class="Storage">function</span>() { <span class="LibraryClassType">Horse</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">move</span> = <span class="Storage">function</span>() {
@ -620,6 +630,7 @@ Animal.prototype.move = function(meters) {
}; };
var Snake = function(name) { var Snake = function(name) {
this.name = name; this.name = name;
return this.name;
}; };
Snake.prototype = new Animal(); Snake.prototype = new Animal();
Snake.prototype.move = function() { Snake.prototype.move = function() {
@ -628,6 +639,7 @@ Snake.prototype.move = function() {
}; };
var Horse = function(name) { var Horse = function(name) {
this.name = name; this.name = name;
return this.name;
}; };
Horse.prototype = new Animal(); Horse.prototype = new Animal();
Horse.prototype.move = function() { Horse.prototype.move = function() {
@ -658,24 +670,23 @@ return [document.title, "Hello JavaScript"].join(": ");
;alert(hi());'>run: hi()</button><br class='clear' /></div> ;alert(hi());'>run: hi()</button><br class='clear' /></div>
<p id="switch"> <p id="switch">
<b class="header">Switch/Case/Else</b> <b class="header">Switch/When/Else</b>
<b>Switch</b> statements in JavaScript are rather broken. You can only <b>Switch</b> statements in JavaScript are rather broken. You can only
do comparisons based on string equality, and need to remember to <b>break</b> at the end of do comparisons based on string equality, and need to remember to <b>break</b> at the end of
every <b>case</b> statement to avoid accidentally falling through to every <b>case</b> statement to avoid accidentally falling through to
the default case. CoffeeScript the default case. CoffeeScript compiles <b>switch</b> statements into JavaScript if-else chains, allowing you to
compiles <b>switch</b> statements into JavaScript if-else chains, allowing you to
compare any object (via <b>===</b>), preventing fall-through, and resulting compare any object (via <b>===</b>), preventing fall-through, and resulting
in a returnable, assignable expression. To specify the default case, just in a returnable, assignable expression. The format is: <tt>switch</tt> condition,
use <tt>else</tt>. <tt>when</tt> clauses, <tt>else</tt> the default case.
</p> </p>
<div class='code'><pre class="idle"><span class="Keyword">switch</span> day <div class='code'><pre class="idle"><span class="Keyword">switch</span> day
<span class="Keyword">case</span> <span class="String"><span class="String">&quot;</span>Tuesday<span class="String">&quot;</span></span> <span class="Keyword">then</span> eat_breakfast() when <span class="String"><span class="String">&quot;</span>Tuesday<span class="String">&quot;</span></span> <span class="Keyword">then</span> eat_breakfast()
<span class="Keyword">case</span> <span class="String"><span class="String">&quot;</span>Wednesday<span class="String">&quot;</span></span> <span class="Keyword">then</span> go_to_the_park() when <span class="String"><span class="String">&quot;</span>Wednesday<span class="String">&quot;</span></span> <span class="Keyword">then</span> go_to_the_park()
<span class="Keyword">case</span> <span class="String"><span class="String">&quot;</span>Saturday<span class="String">&quot;</span></span> when <span class="String"><span class="String">&quot;</span>Saturday<span class="String">&quot;</span></span>
<span class="Keyword">if</span> day <span class="Keyword">is</span> bingo_day <span class="Keyword">if</span> day <span class="Keyword">is</span> bingo_day
go_to_bingo() go_to_bingo()
go_dancing(). go_dancing().
<span class="Keyword">case</span> <span class="String"><span class="String">&quot;</span>Sunday<span class="String">&quot;</span></span> <span class="Keyword">then</span> go_to_church() when <span class="String"><span class="String">&quot;</span>Sunday<span class="String">&quot;</span></span> <span class="Keyword">then</span> go_to_church()
<span class="Keyword">else</span> go_to_work(). <span class="Keyword">else</span> go_to_work().
</pre><pre class="idle"><span class="Keyword">if</span> (day <span class="Keyword">===</span> <span class="String"><span class="String">&quot;</span>Tuesday<span class="String">&quot;</span></span>) { </pre><pre class="idle"><span class="Keyword">if</span> (day <span class="Keyword">===</span> <span class="String"><span class="String">&quot;</span>Tuesday<span class="String">&quot;</span></span>) {
eat_breakfast(); eat_breakfast();

View file

@ -205,7 +205,7 @@
</dict> </dict>
<dict> <dict>
<key>match</key> <key>match</key>
<string>\b(break|case|catch|continue|else|finally|for|if|return|switch|then|throw|try|unless|while)\b</string> <string>\b(break|when|catch|continue|else|finally|for|if|return|switch|then|throw|try|unless|while)\b</string>
<key>name</key> <key>name</key>
<string>keyword.control.cs</string> <string>keyword.control.cs</string>
</dict> </dict>

View file

@ -9,7 +9,7 @@ token CODE PARAM NEW RETURN
token TRY CATCH FINALLY THROW token TRY CATCH FINALLY THROW
token BREAK CONTINUE token BREAK CONTINUE
token FOR IN WHILE token FOR IN WHILE
token SWITCH CASE token SWITCH WHEN
token SUPER token SUPER
token DELETE token DELETE
token NEWLINE token NEWLINE
@ -320,23 +320,23 @@ rule
IF Expression "." { result = ForNode.new(val[0], val[6], val[2], val[8], val[4]) } IF Expression "." { result = ForNode.new(val[0], val[6], val[2], val[8], val[4]) }
; ;
# Switch/Case blocks. # Switch/When blocks.
Switch: Switch:
SWITCH Expression Then SWITCH Expression Then
Cases "." { result = val[3].rewrite_condition(val[1]) } Whens "." { result = val[3].rewrite_condition(val[1]) }
| SWITCH Expression Then | SWITCH Expression Then
Cases ELSE Expressions "." { result = val[3].rewrite_condition(val[1]).add_else(val[5]) } Whens ELSE Expressions "." { result = val[3].rewrite_condition(val[1]).add_else(val[5]) }
; ;
# The inner list of cases. # The inner list of whens.
Cases: Whens:
Case { result = val[0] } When { result = val[0] }
| Cases Case { result = val[0] << val[1] } | Whens When { result = val[0] << val[1] }
; ;
# An individual case. # An individual when.
Case: When:
CASE Expression Then Expressions { result = IfNode.new(val[1], val[3]) } WHEN Expression Then Expressions { result = IfNode.new(val[1], val[3]) }
; ;
# All of the following nutso if-else destructuring is to make the # All of the following nutso if-else destructuring is to make the

View file

@ -13,7 +13,7 @@ module CoffeeScript
"try", "catch", "finally", "throw", "try", "catch", "finally", "throw",
"break", "continue", "break", "continue",
"for", "in", "while", "for", "in", "while",
"switch", "case", "switch", "when",
"super", "super",
"delete"] "delete"]

View file

@ -594,7 +594,7 @@ module CoffeeScript
end end
end end
# If/else statements. Switch/cases get compiled into these. Acts as an # If/else statements. Switch/whens get compiled into these. Acts as an
# expression by pushing down requested returns to the expression bodies. # expression by pushing down requested returns to the expression bodies.
# Single-expression IfNodes are compiled into ternary operators if possible, # Single-expression IfNodes are compiled into ternary operators if possible,
# because ternaries are first-class returnable assignable expressions. # because ternaries are first-class returnable assignable expressions.

11
test/fixtures/execution/test_switch.cs vendored Normal file
View file

@ -0,0 +1,11 @@
num: 10
result: switch num
when 5 then false
when 'a'
false
when 10 then true
when 11 then false
else false.
print(result)

16
test/fixtures/execution/test_switch.js vendored Normal file
View file

@ -0,0 +1,16 @@
(function(){
var num = 10;
var result;
if (num === 5) {
result = false;
} else if (num === 'a') {
result = false;
} else if (num === 10) {
result = true;
} else if (num === 11) {
result = false;
} else {
result = false;
}
print(result);
})();