added yes, no, on and off as boolean aliases and a nice aliases section to the docs

This commit is contained in:
Jeremy Ashkenas 2009-12-23 20:24:55 -05:00
parent a4d014549b
commit 64879cdc66
10 changed files with 95 additions and 63 deletions

View File

@ -0,0 +1,5 @@
launch() if ignition is on
volume: 10 if band aint spinal_tap
let_the_wild_rumpus_begin() unless answer is no

View File

@ -1,3 +1,4 @@
js: => `alert("Hello JavaScript");`. hi: `function() {
return [document.title, "Hello JavaScript"].join(": ");
}`
js() if 10 > 9

View File

@ -19,7 +19,7 @@
<html> <html>
<head> <head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" /> <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>CoffeeScript, briefly...</title> <title>CoffeeScript</title>
<link rel="stylesheet" type="text/css" href="documentation/css/docs.css" /> <link rel="stylesheet" type="text/css" href="documentation/css/docs.css" />
<link rel="stylesheet" type="text/css" href="documentation/css/idle.css" /> <link rel="stylesheet" type="text/css" href="documentation/css/idle.css" />
</head> </head>
@ -33,7 +33,7 @@
CoffeeScript is a little language that compiles into JavaScript. Think CoffeeScript is a little language that compiles into JavaScript. Think
of it as JavaScript's less ostentatious kid brother &mdash; the same genes, of it as JavaScript's less ostentatious kid brother &mdash; the same genes,
the same accent, but a different sense of style. Apart from a handful of the same accent, but a different sense of style. Apart from a handful of
bonus goodies, statements in CoffeeScript correspond one-to-one with their bonus goodies, statements in CoffeeScript correspond one-to-one with their
equivalent in JavaScript, it's just another way of saying it. equivalent in JavaScript, it's just another way of saying it.
</p> </p>
@ -232,7 +232,7 @@ coffee-script --print app/scripts/*.cs > concatenation.js</pre>
<p> <p>
CoffeeScript includes the conditional assignment operators: <tt>||:</tt>, CoffeeScript includes the conditional assignment operators: <tt>||:</tt>,
which only assigns a value to a variable if the variable's current value which only assigns a value to a variable if the variable's current value
is falsy, and <tt>&amp;&amp;:</tt>, which will only replace the value of is falsy, and <tt>&amp;&amp;:</tt>, which only replaces the value of
truthy variables. truthy variables.
</p> </p>
@ -257,15 +257,15 @@ coffee-script --print app/scripts/*.cs > concatenation.js</pre>
</p> </p>
<%= code_for('while') %> <%= code_for('while') %>
<p> <p>
Other JavaScript loops, such as <b>for</b> loops and <b>do-while</b> loops 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>while</b>, but the hope is that you
won't need to do that with CoffeeScript, either because you're using won't need to do that with CoffeeScript, either because you're using
<b>each</b> (<b>forEach</b>) style iterators, or... <b>each</b> (<b>forEach</b>) style iterators, or...
</p> </p>
<p id="array_comprehensions"> <p id="array_comprehensions">
<b class="header">Array Comprehensions</b> <b class="header">Array Comprehensions</b>
For your looping needs, CoffeeScript provides array comprehensions For your looping needs, CoffeeScript provides array comprehensions
similar to Python's. They replace (and compile into) <b>for</b> loops, with similar to Python's. They replace (and compile into) <b>for</b> loops, with
optional guard clauses and the value of the current array index. optional guard clauses and the value of the current array index.
Unlike for loops, array comprehensions are expressions, and can be returned Unlike for loops, array comprehensions are expressions, and can be returned
@ -287,7 +287,7 @@ coffee-script --print app/scripts/*.cs > concatenation.js</pre>
JavaScript's prototypal inheritance has always been a bit of a JavaScript's prototypal inheritance has always been a bit of a
brain-bender, with a whole family tree of libraries that provide a cleaner brain-bender, with a whole family tree of libraries that provide a cleaner
syntax for classical inheritance on top of JavaScript's prototypes: syntax for classical inheritance on top of JavaScript's prototypes:
<a href="http://code.google.com/p/base2/">Base2</a>, <a href="http://code.google.com/p/base2/">Base2</a>,
<a href="http://prototypejs.org/">Prototype.js</a>, <a href="http://prototypejs.org/">Prototype.js</a>,
<a href="http://jsclass.jcoglan.com/">JS.Class</a>, etc. <a href="http://jsclass.jcoglan.com/">JS.Class</a>, etc.
</p> </p>
@ -298,24 +298,26 @@ coffee-script --print app/scripts/*.cs > concatenation.js</pre>
If you ever need to interpolate literal JavaScript snippets, you can If you ever need to interpolate literal JavaScript snippets, you can
use backticks to pass JavaScript straight through. use backticks to pass JavaScript straight through.
</p> </p>
<%= code_for('embedded', true) %> <%= code_for('embedded', 'hi()') %>
<p id="aliases"> <p id="aliases">
<b class="header">Aliases</b> <b class="header">Aliases</b>
Because the <tt>==</tt> operator frequently causes undesirable coercion, Because the <tt>==</tt> operator frequently causes undesirable coercion,
is intransitive, and has a different meaning than in other languages, is intransitive, and has a different meaning than in other languages,
CoffeeScript compiles <tt>==</tt> into <tt>===</tt>, and <tt>!=</tt> into CoffeeScript compiles <tt>==</tt> into <tt>===</tt>, and <tt>!=</tt> into
<tt>!==</tt>. <tt>!==</tt>.
</p> In addition, <tt>is</tt> compiles into <tt>===</tt>,
<p>
<tt>is</tt> also compiles into <tt>===</tt>,
and <tt>aint</tt> into <tt>!==</tt>. and <tt>aint</tt> into <tt>!==</tt>.
</p> </p>
<p> <p>
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>.
</p> </p>
<!-- <%# code_for('punctuation') %> --> <p>
For single-line statements, <tt>unless</tt> can be used as the inverse of <tt>if</tt>.
</p>
<%= code_for('aliases') %>
<p id="switch"> <p id="switch">
<b class="header">Switch/Case/Else</b> <b class="header">Switch/Case/Else</b>
Switch statements in JavaScript are fundamentally broken. You can only Switch statements in JavaScript are fundamentally broken. You can only

View File

@ -0,0 +1,12 @@
(function(){
if (ignition === true) {
launch();
}
var volume;
if (band !== spinal_tap) {
volume = 10;
}
if (!(answer === false)) {
let_the_wild_rumpus_begin();
}
})();

View File

@ -1,8 +1,5 @@
(function(){ (function(){
var js = function() { var hi = function() {
return alert("Hello JavaScript"); return [document.title, "Hello JavaScript"].join(": ");
}; };
if (10 > 9) {
js();
}
})(); })();

View File

@ -5,7 +5,7 @@
<html> <html>
<head> <head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" /> <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>CoffeeScript, briefly...</title> <title>CoffeeScript</title>
<link rel="stylesheet" type="text/css" href="documentation/css/docs.css" /> <link rel="stylesheet" type="text/css" href="documentation/css/docs.css" />
<link rel="stylesheet" type="text/css" href="documentation/css/idle.css" /> <link rel="stylesheet" type="text/css" href="documentation/css/idle.css" />
</head> </head>
@ -19,7 +19,7 @@
CoffeeScript is a little language that compiles into JavaScript. Think CoffeeScript is a little language that compiles into JavaScript. Think
of it as JavaScript's less ostentatious kid brother &mdash; the same genes, of it as JavaScript's less ostentatious kid brother &mdash; the same genes,
the same accent, but a different sense of style. Apart from a handful of the same accent, but a different sense of style. Apart from a handful of
bonus goodies, statements in CoffeeScript correspond one-to-one with their bonus goodies, statements in CoffeeScript correspond one-to-one with their
equivalent in JavaScript, it's just another way of saying it. equivalent in JavaScript, it's just another way of saying it.
</p> </p>
@ -363,7 +363,7 @@ var new_num = change_numbers();
date<span class="Keyword">:</span> <span class="Keyword">if</span> friday <span class="Keyword">then</span> sue <span class="Keyword">else</span> jill. date<span class="Keyword">:</span> <span class="Keyword">if</span> friday <span class="Keyword">then</span> sue <span class="Keyword">else</span> jill.
expensive <span class="Keyword">||</span><span class="Keyword">=</span> do_the_math() expensive <span class="Keyword">||</span><span class="Keyword">:</span> do_the_math()
</pre><pre class="idle"><span class="Storage">var</span> mood; </pre><pre class="idle"><span class="Storage">var</span> mood;
<span class="Keyword">if</span> (singing) { <span class="Keyword">if</span> (singing) {
mood <span class="Keyword">=</span> greatly_improved; mood <span class="Keyword">=</span> greatly_improved;
@ -378,7 +378,7 @@ expensive <span class="Keyword">=</span> expensive <span class="Keyword">||</spa
<p> <p>
CoffeeScript includes the conditional assignment operators: <tt>||:</tt>, CoffeeScript includes the conditional assignment operators: <tt>||:</tt>,
which only assigns a value to a variable if the variable's current value which only assigns a value to a variable if the variable's current value
is falsy, and <tt>&amp;&amp;:</tt>, which will only replace the value of is falsy, and <tt>&amp;&amp;:</tt>, which only replaces the value of
truthy variables. truthy variables.
</p> </p>
@ -444,15 +444,15 @@ var eldest = 24 > 21 ? "Liz" : "Ike";
} }
</pre><br class='clear' /></div> </pre><br class='clear' /></div>
<p> <p>
Other JavaScript loops, such as <b>for</b> loops and <b>do-while</b> loops 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>while</b>, but the hope is that you
won't need to do that with CoffeeScript, either because you're using won't need to do that with CoffeeScript, either because you're using
<b>each</b> (<b>forEach</b>) style iterators, or... <b>each</b> (<b>forEach</b>) style iterators, or...
</p> </p>
<p id="array_comprehensions"> <p id="array_comprehensions">
<b class="header">Array Comprehensions</b> <b class="header">Array Comprehensions</b>
For your looping needs, CoffeeScript provides array comprehensions For your looping needs, CoffeeScript provides array comprehensions
similar to Python's. They replace (and compile into) <b>for</b> loops, with similar to Python's. They replace (and compile into) <b>for</b> loops, with
optional guard clauses and the value of the current array index. optional guard clauses and the value of the current array index.
Unlike for loops, array comprehensions are expressions, and can be returned Unlike for loops, array comprehensions are expressions, and can be returned
@ -502,7 +502,7 @@ var three_to_six = nums.slice(3, 6 + 1);
JavaScript's prototypal inheritance has always been a bit of a JavaScript's prototypal inheritance has always been a bit of a
brain-bender, with a whole family tree of libraries that provide a cleaner brain-bender, with a whole family tree of libraries that provide a cleaner
syntax for classical inheritance on top of JavaScript's prototypes: syntax for classical inheritance on top of JavaScript's prototypes:
<a href="http://code.google.com/p/base2/">Base2</a>, <a href="http://code.google.com/p/base2/">Base2</a>,
<a href="http://prototypejs.org/">Prototype.js</a>, <a href="http://prototypejs.org/">Prototype.js</a>,
<a href="http://jsclass.jcoglan.com/">JS.Class</a>, etc. <a href="http://jsclass.jcoglan.com/">JS.Class</a>, etc.
</p> </p>
@ -584,39 +584,51 @@ tom.move();
If you ever need to interpolate literal JavaScript snippets, you can If you ever need to interpolate literal JavaScript snippets, you can
use backticks to pass JavaScript straight through. use backticks to pass JavaScript straight through.
</p> </p>
<div class='code'><pre class="idle"><span class="FunctionName">js</span><span class="Keyword">:</span> <span class="Storage">=&gt;</span> <span class="String"><span class="String">`</span>alert(&quot;Hello JavaScript&quot;);<span class="String">`</span></span>. <div class='code'><pre class="idle">hi<span class="Keyword">:</span> <span class="String"><span class="String">`</span>function() {</span>
<span class="String"> return [document.title, &quot;Hello JavaScript&quot;].join(&quot;: &quot;);</span>
<span class="String">}<span class="String">`</span></span>
js() <span class="Keyword">if</span> <span class="Number">10</span> <span class="Keyword">&gt;</span> <span class="Number">9</span> </pre><pre class="idle"><span class="Storage">var</span> <span class="FunctionName">hi</span> = <span class="Storage">function</span>() {
</pre><pre class="idle"><span class="Storage">var</span> <span class="FunctionName">js</span> = <span class="Storage">function</span>() { <span class="Keyword">return</span> [<span class="LibraryClassType">document</span>.<span class="LibraryConstant">title</span>, <span class="String"><span class="String">&quot;</span>Hello JavaScript<span class="String">&quot;</span></span>].<span class="LibraryFunction">join</span>(<span class="String"><span class="String">&quot;</span>: <span class="String">&quot;</span></span>);
<span class="Keyword">return</span> <span class="LibraryFunction">alert</span>(<span class="String"><span class="String">&quot;</span>Hello JavaScript<span class="String">&quot;</span></span>);
}; };
<span class="Keyword">if</span> (<span class="Number">10</span> <span class="Keyword">&gt;</span> <span class="Number">9</span>) { </pre><button onclick='javascript: var hi = function() {
js(); return [document.title, "Hello JavaScript"].join(": ");
}
</pre><button onclick='javascript: var js = function() {
return alert("Hello JavaScript");
}; };
if (10 > 9) { ;alert(hi());'>run: hi()</button><br class='clear' /></div>
js();
}
;'>run</button><br class='clear' /></div>
<p id="aliases"> <p id="aliases">
<b class="header">Aliases</b> <b class="header">Aliases</b>
Because the <tt>==</tt> operator frequently causes undesirable coercion, Because the <tt>==</tt> operator frequently causes undesirable coercion,
is intransitive, and has a different meaning than in other languages, is intransitive, and has a different meaning than in other languages,
CoffeeScript compiles <tt>==</tt> into <tt>===</tt>, and <tt>!=</tt> into CoffeeScript compiles <tt>==</tt> into <tt>===</tt>, and <tt>!=</tt> into
<tt>!==</tt>. <tt>!==</tt>.
</p> In addition, <tt>is</tt> compiles into <tt>===</tt>,
<p>
<tt>is</tt> also compiles into <tt>===</tt>,
and <tt>aint</tt> into <tt>!==</tt>. and <tt>aint</tt> into <tt>!==</tt>.
</p> </p>
<p> <p>
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>.
</p> </p>
<!-- --> <p>
For single-line statements, <tt>unless</tt> can be used as the inverse of <tt>if</tt>.
</p>
<div class='code'><pre class="idle">launch() <span class="Keyword">if</span> ignition <span class="Keyword">is</span> <span class="BuiltInConstant">on</span>
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>
</pre><pre class="idle"><span class="Keyword">if</span> (ignition <span class="Keyword">===</span> <span class="BuiltInConstant">true</span>) {
launch();
}
<span class="Storage">var</span> volume;
<span class="Keyword">if</span> (band <span class="Keyword">!</span><span class="Keyword">==</span> spinal_tap) {
volume <span class="Keyword">=</span> <span class="Number">10</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();
}
</pre><br class='clear' /></div>
<p id="switch"> <p id="switch">
<b class="header">Switch/Case/Else</b> <b class="header">Switch/Case/Else</b>
Switch statements in JavaScript are fundamentally broken. You can only Switch statements in JavaScript are fundamentally broken. You can only

View File

@ -211,13 +211,13 @@
</dict> </dict>
<dict> <dict>
<key>match</key> <key>match</key>
<string>\btrue\b</string> <string>\b(true|on|yes)\b</string>
<key>name</key> <key>name</key>
<string>constant.language.boolean.true.cs</string> <string>constant.language.boolean.true.cs</string>
</dict> </dict>
<dict> <dict>
<key>match</key> <key>match</key>
<string>\bfalse\b</string> <string>\b(false|off|no)\b</string>
<key>name</key> <key>name</key>
<string>constant.language.boolean.false.cs</string> <string>constant.language.boolean.false.cs</string>
</dict> </dict>

View File

@ -3,7 +3,7 @@ class Parser
# Declare tokens produced by the lexer # Declare tokens produced by the lexer
token IF ELSE THEN UNLESS token IF ELSE THEN UNLESS
token NUMBER STRING REGEX token NUMBER STRING REGEX
token TRUE FALSE NULL token TRUE FALSE YES NO ON OFF
token IDENTIFIER PROPERTY_ACCESS token IDENTIFIER PROPERTY_ACCESS
token CODE PARAM NEW RETURN token CODE PARAM NEW RETURN
token TRY CATCH FINALLY THROW token TRY CATCH FINALLY THROW
@ -102,11 +102,14 @@ rule
| STRING { result = LiteralNode.new(val[0]) } | STRING { result = LiteralNode.new(val[0]) }
| JS { result = LiteralNode.new(val[0]) } | JS { result = LiteralNode.new(val[0]) }
| REGEX { result = LiteralNode.new(val[0]) } | REGEX { result = LiteralNode.new(val[0]) }
| TRUE { result = LiteralNode.new(true) }
| FALSE { result = LiteralNode.new(false) }
| NULL { result = LiteralNode.new(nil) }
| BREAK { result = LiteralNode.new(val[0]) } | BREAK { result = LiteralNode.new(val[0]) }
| CONTINUE { result = LiteralNode.new(val[0]) } | CONTINUE { result = LiteralNode.new(val[0]) }
| TRUE { result = LiteralNode.new(true) }
| FALSE { result = LiteralNode.new(false) }
| YES { result = LiteralNode.new(true) }
| NO { result = LiteralNode.new(false) }
| ON { result = LiteralNode.new(true) }
| OFF { result = LiteralNode.new(false) }
; ;
# Assignment to a variable. # Assignment to a variable.

View File

@ -7,7 +7,7 @@ module CoffeeScript
# The list of keywords passed verbatim to the parser. # The list of keywords passed verbatim to the parser.
KEYWORDS = ["if", "else", "then", "unless", KEYWORDS = ["if", "else", "then", "unless",
"true", "false", "null", "true", "false", "yes", "no", "on", "off",
"and", "or", "is", "aint", "not", "and", "or", "is", "aint", "not",
"new", "return", "new", "return",
"try", "catch", "finally", "throw", "try", "catch", "finally", "throw",
@ -21,7 +21,7 @@ module CoffeeScript
IDENTIFIER = /\A([a-zA-Z$_]\w*)/ IDENTIFIER = /\A([a-zA-Z$_]\w*)/
NUMBER = /\A\b((0(x|X)[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?(e[+\-]?[0-9]+)?))\b/i NUMBER = /\A\b((0(x|X)[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?(e[+\-]?[0-9]+)?))\b/i
STRING = /\A(""|''|"(.*?)[^\\]"|'(.*?)[^\\]')/m STRING = /\A(""|''|"(.*?)[^\\]"|'(.*?)[^\\]')/m
JS = /\A(`(.*?)`)/ JS = /\A(``|`(.*?)[^\\]`)/m
OPERATOR = /\A([+\*&|\/\-%=<>:]+)/ OPERATOR = /\A([+\*&|\/\-%=<>:]+)/
WHITESPACE = /\A([ \t\r]+)/ WHITESPACE = /\A([ \t\r]+)/
NEWLINE = /\A(\n+)/ NEWLINE = /\A(\n+)/

View File

@ -601,7 +601,7 @@ module CoffeeScript
@body = body && body.unwrap @body = body && body.unwrap
@else_body = else_body && else_body.unwrap @else_body = else_body && else_body.unwrap
@tags = tags @tags = tags
@condition = OpNode.new("!", @condition) if @tags[:invert] @condition = OpNode.new("!", ParentheticalNode.new(@condition)) if @tags[:invert]
end end
def <<(else_body) def <<(else_body)
@ -656,7 +656,7 @@ module CoffeeScript
def compile_statement(o) def compile_statement(o)
indent = o[:indent] indent = o[:indent]
o[:indent] += TAB o[:indent] += TAB
if_part = "if (#{@condition.compile(o.merge(:no_paren => true))}) {\n#{Expressions.wrap(@body).compile(o)}\n#{indent}}" if_part = "if (#{@condition.compile(o)}) {\n#{Expressions.wrap(@body).compile(o)}\n#{indent}}"
return if_part unless @else_body return if_part unless @else_body
else_part = chain? ? else_part = chain? ?
" else #{@else_body.compile(o.merge(:indent => indent))}" : " else #{@else_body.compile(o.merge(:indent => indent))}" :