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

documentation waypoint

This commit is contained in:
Jeremy Ashkenas 2009-12-21 11:41:45 -05:00
parent dcc70e5ab0
commit c7fa9c320a
42 changed files with 1026 additions and 53 deletions

View file

@ -18,6 +18,7 @@ end
desc "Build the documentation page"
task :doc do
source = 'documentation/index.html.erb'
Thread.new { `bin/coffee-script documentation/cs/*.cs -o documentation/js -w` }
loop do
mtime = File.stat(source).mtime
if !@mtime || mtime > @mtime

View file

@ -0,0 +1,5 @@
# Eat lunch.
lunch: food.eat() for food in ['toast', 'cheese', 'wine'].
# Zebra-stripe a table.
highlight(row) for row, i in table if i % 2 is 0.

View file

@ -0,0 +1,2 @@
greeting: "Hello CoffeeScript"
difficulty: 0.5

View file

@ -0,0 +1,9 @@
mood: greatly_improved if singing
if happy and knows_it
claps_hands()
cha_cha_cha().
date: if friday then sue else jill.
expensive ||= do_the_math()

View file

@ -0,0 +1,3 @@
js: => `alert("Hello JavaScript");`.
js() if 10 > 9

View file

@ -0,0 +1,9 @@
grade: student =>
if student.excellent_work
"A+"
else if student.okay_stuff
"B"
else
"C"..
eldest: if 24 > 21 then "Liz" else "Ike".

View file

@ -0,0 +1,2 @@
square: x => x * x.
cube: x => square(x) * x.

View file

@ -0,0 +1,3 @@
# CoffeeScript on the left, JS on the right.
square: x => x * x.

View file

@ -0,0 +1,6 @@
song: ["do", "re", "mi", "fa", "so"]
ages: {
max: 10
ida: 9
tim: 11
}

View file

@ -0,0 +1,11 @@
# Comments start with hash marks.
# Periods mark the end of a block.
left_hand: if raining then umbrella else parasol.
# To signal the beginning of the next expression,
# use "then", or a newline.
left_hand: if raining
umbrella
else
parasol.

View file

@ -0,0 +1,5 @@
num: 1
change_numbers: =>
num: 2
new_num: 3.
new_num: change_numbers()

View file

@ -0,0 +1,2 @@
nums: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
three_to_six: nums[3, 6]

View file

@ -0,0 +1,6 @@
moby_dick: "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..."

21
documentation/cs/super.cs Normal file
View file

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

View file

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

7
documentation/cs/try.cs Normal file
View file

@ -0,0 +1,7 @@
try
all_hell_breaks_loose()
cats_and_dogs_living_together()
catch error
print( error )
finally
clean_up().

View file

@ -0,0 +1,5 @@
while demand > supply
sell()
restock().
while supply > demand then buy().

View file

@ -1,40 +1,34 @@
body {
font-size: 16px;
line-height: 24px;
background: #f0f0e5;
color: #252519;
font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
font-size: 14px;
line-height: 20px;
background: #efefef;
color: #191933;
font-family: Arial, Helvetica, sans-serif;
}
div.container {
width: 720px;
width: 850px;
margin: 50px 0 50px 50px;
}
p {
width: 550px;
padding-left: 13px;
width: 625px;
}
#documentation p {
margin-bottom: 4px;
}
a, a:visited {
padding: 0 2px;
text-decoration: none;
background: #dadaba;
color: #252519;
}
a:active, a:hover {
color: #000;
background: #f0c095;
a {
color: #000055;
}
h1, h2, h3, h4, h5, h6 {
padding-left: 13px;
margin-top: 40px;
}
b.header {
font-size: 18px;
br.clear {
height: 0;
clear: both;
}
span.alias {
font-size: 14px;
font-style: italic;
margin-left: 20px;
b.header {
color: #000055;
display: block;
margin: 40px 0 5px 0;
font-size: 16px;
}
table, tr, td {
margin: 0; padding: 0;
@ -53,7 +47,24 @@ code, pre, tt {
}
pre {
font-size: 12px;
padding: 2px 0 2px 12px;
border-left: 6px solid #aaaa99;
margin: 0px 0 30px;
padding: 0 0 0 12px;
margin: 0;
width: 410px;
float: left;
border-left: 1px dotted #559;
}
pre:first-child {
border-left: 0;
}
div.code {
position: relative;
border: 1px solid #cacaca;
background: #fff;
padding: 7px 0 10px 0;
-moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px;
-webkit-box-shadow: 0px 0px 7px #cacaca;
}
div.code button {
position: absolute;
right: 8px; bottom: 8px;
}

View file

@ -1,26 +1,222 @@
<%
require 'uv'
def code_for(file, executable=false)
@stripper ||= /(\A\(function\(\)\{\n|\}\)\(\);\Z|^ )/
cs = File.read("documentation/cs/#{file}.cs")
js = File.read("documentation/js/#{file}.js").gsub(@stripper, '')
cshtml = Uv.parse(cs, 'xhtml', 'coffeescript', false, 'idle', false)
jshtml = Uv.parse(js, 'xhtml', 'javascript', false, 'idle', false)
append = executable == true ? '' : "alert(#{executable});"
run = executable == true ? 'run' : "run: #{executable}"
button = executable ? "<button onclick='javascript: #{js};#{append}'>#{run}</button>" : ''
"<div class='code'>#{cshtml}#{jshtml}#{button}<br class='clear' /></div>"
end
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>CoffeeScript</title>
<link rel="stylesheet" type="text/css" href="documentation/css/docs.css" />
<title>CoffeeScript, briefly...</title>
<link rel="stylesheet" type="text/css" href="documentation/css/docs.css" />
<link rel="stylesheet" type="text/css" href="documentation/css/idle.css" />
</head>
<body>
<div class="container">
<h1>CoffeeScript</h1>
<h1><sub style="font-size: 100px;">&#9749;</sub> CoffeeScript</h1>
<p>
CoffeeScript is a little language that compiles into JavaScript. Think
of it as JavaScript's simpleminded kid brother &mdash; the same genes,
the same accent, but another kind of way of doing things.
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
JavaScript equivalent, it's just another way of saying it.
</p>
<!-- <%# code_for('intro') %>-->
<p>
<b>Disclaimer:</b><br />
CoffeeScript is just for fun and seriously alpha. <i>There is no guarantee,
explicit or implied, of its suitability for any purpose.</i> That said, it
compiles into pretty-printed JavaScript (the good parts) that can pass through
<a href="http://www.jslint.com/">JSLint</a> warning-free.
</p>
<h2>Table of Contents</h2>
<p>
<i>
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.
</i>
</p>
<p>
<a href="#punctuation">Punctuation Primer</a><br />
<a href="#functions">Functions and Invocation</a><br />
<a href="#objects_and_arrays">Objects and Arrays</a><br />
<a href="#assignment">Assignment</a><br />
<a href="#lexical_scope">Lexical Scoping and Variable Safety</a><br />
<a href="#conditionals">Conditionals, Ternaries, and Conditional Assignment</a><br />
<a href="#expressions">Everything is an Expression</a><br />
<a href="#while">While Loops</a><br />
<a href="#array_comprehensions">Array Comprehensions</a><br />
<a href="#slice">Array Slice Literals</a><br />
<a href="#inheritance">Inheritance, and Calling Super from a Subclass</a>
<a href="#embedded">Embedded JavaScript</a><br />
<a href="#switch">Switch/Case/Else</a><br />
<a href="#try">Try/Catch/Finally</a><br />
<a href="#strings">Multiline Strings</a><br />
</p>
<p>
In all of the following examples, the source CoffeeScript is provided on
the left, and the direct compilation into JavaScript is on the right.
</p>
<div id="documentation">
<p id="punctuation">
<b class="header">Punctuation Primer</b>
You don't need to use semicolons to (<b>;</b>) terminate expressions, ending
the line will do just as well. So newlines can matter, but whitespace is
not otherwise significant. Instead of using curly braces (<b>{ }</b>)
to delimit blocks of code, a period (<b>.</b>) marks the end of a
function, if statement, or try/catch.
</p>
<!-- <%# code_for('punctuation') %> -->
<p id="functions">
<b class="header">Functions and Invocation</b>
Let's start with the best part, shall we? Function literals are my
absolute favorite thing about CoffeeScript.
</p>
<%= code_for('functions', 'cube(5)') %>
<p id="objects_arrays">
<b class="header">Objects and Arrays</b>
Object and Array literals look very similar. When you spread out
each assignment on a separate line, the commas are optional.
</p>
<%= code_for('objects_and_arrays', 'song.join(",")') %>
<p>
</p>
<p id="assignment">
<b class="header">Assignment</b>
All assignment in CoffeeScript, whether to a variable or to an object
property, uses a colon. Equal signs are only needed for mathy things.
</p>
<%= code_for('assignment', 'greeting') %>
<p>
</p>
<p id="lexical_scope">
<b class="header">Lexical Scoping and Variable Safety</b>
The CoffeeScript compiler takes care to make sure that all of your variables
are properly defined within lexical scope &mdash; you never need to declare
<i>var</i> yourself.
</p>
<%= code_for('scope', 'new_num') %>
<p>
Notice how the variables are declared with <i>var</i> the first time
they appear. The second reference of <b>num</b>, within the function,
is not redeclared because <b>num</b> is still in scope. As opposed
to the second <b>new_num</b>, in the last line.
</p>
<p id="conditionals">
<b class="header">Conditionals, Ternaries, and Conditional Assignment</b>
</p>
<%= code_for('conditionals') %>
<p>
</p>
<p id="expressions">
<b class="header">Everything is an Expression</b>
You might have noticed how even though we don't add return statements
to CoffeScript functions, they nonetheless return their final value.
The CoffeeScript compiler tries to make sure that every little language
construct can be used as an expression.
</p>
<%= code_for('expressions', 'eldest') %>
<p>
When compiling a function definition, CoffeeScript tries to push down
the return statement to each of the potential final lines of the function.
It uses the same mechanism to push down assignment statements. If statement
are compiled into ternary operators when possible, so that they can be used
as expressions.
</p>
<p id="while">
<b class="header">While Loops</b>
The only low-level loop that CoffeeScript provides is the while loop.
</p>
<%= code_for('while') %>
<p id="array_comprehensions">
<b class="header">Array Comprehensions</b>
Most of your looping needs should be handled by array comprehensions.
They replace (and compile into) for loops, handling
<b>each</b>/<b>forEach</b> style loops, as well as <b>select</b>/<b>filter</b>.
Unlike for loops, array comprehensions are expressions, and can be returned
and assigned.
</p>
<%= code_for('array_comprehensions') %>
<p id="slice">
<b class="header">Array Slice Literals</b>
CoffeeScript includes a literal syntax for extracting slices of arrays.
The first argument is the index of the first element in the slice, and
the second is the index of the last one.
</p>
<%= code_for('slices', 'three_to_six') %>
<p id="inheritance">
<b class="header">Inheritance, and Calling Super from a Subclass</b>
JavaScript's prototypal inheritance has always been a bit of a
brain-bender, with a whole family tree of libraries (Base2, Prototype
).
</p>
<%= code_for('super', true) %>
<p id="embedded">
<b class="header">Embedded JavaScript</b>
If you ever need to interpolate literal JavaScript snippets, you can
use backticks to pass JavaScript straight through.
</p>
<%= code_for('embedded', true) %>
<p id="switch">
<b class="header">Switch/Case/Else</b>
Switch statements in JavaScript are fundamentally broken. You can only
do string comparisons, and need to break at the end of each case
statment to prevent falling through to the default case. CoffeeScript
compiles switch statements into if-else chains, allowing you to
compare any object (via <b>===</b>), preventing fall-through, and resulting
in a returnable expression.
</p>
<%= code_for('switch') %>
<p id="try">
<b class="header">Try/Catch/Finally</b>
Try/catch statements just about the same as JavaScript (although
they work as expressions). No braces required.
</p>
<%= code_for('try') %>
<p id="try">
<b class="header">Multiline Strings</b>
Multiline strings are allowed in CoffeeScript.
</p>
<%= code_for('strings') %>
</div>
</div>
</body>

View file

@ -0,0 +1,16 @@
(function(){
var lunch;
var a = ['toast', 'cheese', 'wine'];
var d = [];
for (var b=0, c=a.length; b<c; b++) {
var food = a[b];
d[b] = food.eat();
}
lunch = d;
var e = table;
for (var f=0, g=e.length; f<g; f++) {
var row = e[f];
var i = f;
i % 2 === 0 ? highlight(row) : null;
}
})();

View file

@ -0,0 +1,4 @@
(function(){
var greeting = "Hello CoffeeScript";
var difficulty = 0.5;
})();

View file

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

View file

@ -0,0 +1,8 @@
(function(){
var js = function() {
return alert("Hello JavaScript");
};
if (10 > 9) {
js();
}
})();

View file

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

View file

@ -0,0 +1,3 @@
(function(){
})();

View file

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

View file

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

View file

@ -0,0 +1,8 @@
(function(){
var song = ["do", "re", "mi", "fa", "so"];
var ages = {
max: 10,
ida: 9,
tim: 11
};
})();

View file

@ -0,0 +1,4 @@
(function(){
var left_hand = raining ? umbrella : parasol;
left_hand = raining ? umbrella : parasol;
})();

View file

@ -0,0 +1,9 @@
(function(){
var num = 1;
var change_numbers = function() {
num = 2;
var new_num = 3;
return new_num;
};
var new_num = change_numbers();
})();

View file

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

View file

@ -0,0 +1,8 @@
(function(){
var moby_dick = "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...";
})();

28
documentation/js/super.js Normal file
View file

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

View file

@ -0,0 +1,13 @@
(function(){
if (day === "Tuesday") {
eat_breakfast();
} else if (day === "Wednesday") {
go_to_the_park();
} else if (day === "Saturday") {
day === bingo_day ? go_to_bingo() : null;
} else if (day === "Sunday") {
go_to_church();
} else {
go_to_work();
}
})();

10
documentation/js/try.js Normal file
View file

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

View file

@ -0,0 +1,9 @@
(function(){
while (demand > supply) {
sell();
restock();
}
while (supply > demand) {
buy();
}
})();

View file

@ -136,13 +136,28 @@ story: "Lorem ipsum dolor \"sit\" amet, consectetuer adipiscing elit,
sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna
aliquam erat volutpat. Ut wisi enim ad."
# Calling super from an overridden method.
Greeter: => . # Create the parent object.
Greeter.prototype.hello: name => alert('Hello ' + name). # Define a "hello" method.
Exclaimer: name => this.name: name. # Create the child object.
Exclaimer.prototype: new Greeter() # Set the child to inherit from the parent.
Exclaimer.prototype.hello: => super(this.name + "!"). # The child's "hello" calls the parent's via "super".
(new Exclaimer('Bob')).hello() # Run it.
# Inheritance and calling super.
Animal: => .
Animal.prototype.move: meters =>
alert(this.name + " moved " + meters + "m.").
Snake: name => this.name: name.
Snake extends Animal
Snake.prototype.move: =>
alert('Slithering...')
super(5).
Horse: name => this.name: name.
Horse extends Animal
Horse.prototype.move: =>
alert('Galloping...')
super(45).
sam: new Snake("Sammy the Snake")
tom: new Horse("Tommy the Horse")
sam.move()
tom.move()
# Numbers.
a_googol: 1e100

View file

@ -1,22 +1,484 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>CoffeeScript</title>
<link rel="stylesheet" type="text/css" href="documentation/css/docs.css" />
<title>CoffeeScript, briefly...</title>
<link rel="stylesheet" type="text/css" href="documentation/css/docs.css" />
<link rel="stylesheet" type="text/css" href="documentation/css/idle.css" />
</head>
<body>
<div class="container">
<h1>CoffeeScript</h1>
<h1><sub style="font-size: 100px;">&#9749;</sub> CoffeeScript</h1>
<p>
CoffeeScript is a little language that compiles into JavaScript. Think
of it as JavaScript's simpleminded kid brother &mdash; the same genes,
the same accent, but another kind of way of doing things.
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
JavaScript equivalent, it's just another way of saying it.
</p>
<!-- -->
<p>
<b>Disclaimer:</b><br />
CoffeeScript is just for fun and seriously alpha. <i>There is no guarantee,
explicit or implied, of its suitability for any purpose.</i> That said, it
compiles into pretty-printed JavaScript (the good parts) that can pass through
<a href="http://www.jslint.com/">JSLint</a> warning-free.
</p>
<h2>Table of Contents</h2>
<p>
<i>
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.
</i>
</p>
<p>
<a href="#punctuation">Punctuation Primer</a><br />
<a href="#functions">Functions and Invocation</a><br />
<a href="#objects_and_arrays">Objects and Arrays</a><br />
<a href="#assignment">Assignment</a><br />
<a href="#lexical_scope">Lexical Scoping and Variable Safety</a><br />
<a href="#conditionals">Conditionals, Ternaries, and Conditional Assignment</a><br />
<a href="#expressions">Everything is an Expression</a><br />
<a href="#while">While Loops</a><br />
<a href="#array_comprehensions">Array Comprehensions</a><br />
<a href="#slice">Array Slice Literals</a><br />
<a href="#inheritance">Inheritance, and Calling Super from a Subclass</a>
<a href="#embedded">Embedded JavaScript</a><br />
<a href="#switch">Switch/Case/Else</a><br />
<a href="#try">Try/Catch/Finally</a><br />
<a href="#strings">Multiline Strings</a><br />
</p>
<p>
In all of the following examples, the source CoffeeScript is provided on
the left, and the direct compilation into JavaScript is on the right.
</p>
<div id="documentation">
<p id="punctuation">
<b class="header">Punctuation Primer</b>
You don't need to use semicolons to (<b>;</b>) terminate expressions, ending
the line will do just as well. So newlines can matter, but whitespace is
not otherwise significant. Instead of using curly braces (<b>{ }</b>)
to delimit blocks of code, a period (<b>.</b>) marks the end of a
function, if statement, or try/catch.
</p>
<!-- -->
<p id="functions">
<b class="header">Functions and Invocation</b>
Let's start with the best part, shall we? Function literals are my
absolute favorite thing about CoffeeScript.
</p>
<div class='code'><pre class="idle"><span class="FunctionName">square</span><span class="Keyword">:</span> <span class="FunctionArgument">x</span> <span class="Storage">=&gt;</span> x <span class="Keyword">*</span> x.
<span class="FunctionName">cube</span><span class="Keyword">:</span> <span class="FunctionArgument">x</span> <span class="Storage">=&gt;</span> square(x) <span class="Keyword">*</span> x.
</pre><pre class="idle"><span class="Storage">var</span> <span class="FunctionName">square</span> = <span class="Storage">function</span>(<span class="FunctionArgument">x</span>) {
<span class="Keyword">return</span> x <span class="Keyword">*</span> x;
};
<span class="Storage">var</span> <span class="FunctionName">cube</span> = <span class="Storage">function</span>(<span class="FunctionArgument">x</span>) {
<span class="Keyword">return</span> square(x) <span class="Keyword">*</span> x;
};
</pre><button onclick='javascript: var square = function(x) {
return x * x;
};
var cube = function(x) {
return square(x) * x;
};
;alert(cube(5));'>run: cube(5)</button><br class='clear' /></div>
<p id="objects_arrays">
<b class="header">Objects and Arrays</b>
Object and Array literals look very similar. When you spread out
each assignment on a separate line, the commas are optional.
</p>
<div class='code'><pre class="idle">song<span class="Keyword">:</span> [<span class="String"><span class="String">&quot;</span>do<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>re<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>mi<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>fa<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>so<span class="String">&quot;</span></span>]
ages<span class="Keyword">:</span> {
max<span class="Keyword">:</span> <span class="Number">10</span>
ida<span class="Keyword">:</span> <span class="Number">9</span>
tim<span class="Keyword">:</span> <span class="Number">11</span>
}
</pre><pre class="idle"><span class="Storage">var</span> song <span class="Keyword">=</span> [<span class="String"><span class="String">&quot;</span>do<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>re<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>mi<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>fa<span class="String">&quot;</span></span>, <span class="String"><span class="String">&quot;</span>so<span class="String">&quot;</span></span>];
<span class="Storage">var</span> ages <span class="Keyword">=</span> {
max: <span class="Number">10</span>,
ida: <span class="Number">9</span>,
tim: <span class="Number">11</span>
};
</pre><button onclick='javascript: var song = ["do", "re", "mi", "fa", "so"];
var ages = {
max: 10,
ida: 9,
tim: 11
};
;alert(song.join(","));'>run: song.join(",")</button><br class='clear' /></div>
<p>
</p>
<p id="assignment">
<b class="header">Assignment</b>
All assignment in CoffeeScript, whether to a variable or to an object
property, uses a colon. Equal signs are only needed for mathy things.
</p>
<div class='code'><pre class="idle">greeting<span class="Keyword">:</span> <span class="String"><span class="String">&quot;</span>Hello CoffeeScript<span class="String">&quot;</span></span>
difficulty<span class="Keyword">:</span> <span class="Number">0.5</span>
</pre><pre class="idle"><span class="Storage">var</span> greeting <span class="Keyword">=</span> <span class="String"><span class="String">&quot;</span>Hello CoffeeScript<span class="String">&quot;</span></span>;
<span class="Storage">var</span> difficulty <span class="Keyword">=</span> <span class="Number">0.5</span>;
</pre><button onclick='javascript: var greeting = "Hello CoffeeScript";
var difficulty = 0.5;
;alert(greeting);'>run: greeting</button><br class='clear' /></div>
<p>
</p>
<p id="lexical_scope">
<b class="header">Lexical Scoping and Variable Safety</b>
The CoffeeScript compiler takes care to make sure that all of your variables
are properly defined within lexical scope &mdash; you never need to declare
<i>var</i> yourself.
</p>
<div class='code'><pre class="idle">num<span class="Keyword">:</span> <span class="Number">1</span>
<span class="FunctionName">change_numbers</span><span class="Keyword">:</span> <span class="Storage">=&gt;</span>
num<span class="Keyword">:</span> <span class="Number">2</span>
new_num<span class="Keyword">:</span> <span class="Number">3</span>.
new_num<span class="Keyword">:</span> change_numbers()
</pre><pre class="idle"><span class="Storage">var</span> num <span class="Keyword">=</span> <span class="Number">1</span>;
<span class="Storage">var</span> <span class="FunctionName">change_numbers</span> = <span class="Storage">function</span>() {
num <span class="Keyword">=</span> <span class="Number">2</span>;
<span class="Storage">var</span> new_num <span class="Keyword">=</span> <span class="Number">3</span>;
<span class="Keyword">return</span> new_num;
};
<span class="Storage">var</span> new_num <span class="Keyword">=</span> change_numbers();
</pre><button onclick='javascript: var num = 1;
var change_numbers = function() {
num = 2;
var new_num = 3;
return new_num;
};
var new_num = change_numbers();
;alert(new_num);'>run: new_num</button><br class='clear' /></div>
<p>
Notice how the variables are declared with <i>var</i> the first time
they appear. The second reference of <b>num</b>, within the function,
is not redeclared because <b>num</b> is still in scope. As opposed
to the second <b>new_num</b>, in the last line.
</p>
<p id="conditionals">
<b class="header">Conditionals, Ternaries, and Conditional Assignment</b>
</p>
<div class='code'><pre class="idle">mood<span class="Keyword">:</span> greatly_improved <span class="Keyword">if</span> singing
<span class="Keyword">if</span> happy <span class="Keyword">and</span> knows_it
claps_hands()
cha_cha_cha().
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()
</pre><pre class="idle"><span class="Storage">var</span> mood;
<span class="Keyword">if</span> (singing) {
mood <span class="Keyword">=</span> greatly_improved;
}
<span class="Keyword">if</span> (happy <span class="Keyword">&amp;</span><span class="Keyword">&amp;</span> knows_it) {
claps_hands();
cha_cha_cha();
}
<span class="Storage">var</span> date <span class="Keyword">=</span> friday ? sue : jill;
expensive <span class="Keyword">=</span> expensive <span class="Keyword">||</span> do_the_math();
</pre><br class='clear' /></div>
<p>
</p>
<p id="expressions">
<b class="header">Everything is an Expression</b>
You might have noticed how even though we don't add return statements
to CoffeScript functions, they nonetheless return their final value.
The CoffeeScript compiler tries to make sure that every little language
construct can be used as an expression.
</p>
<div class='code'><pre class="idle"><span class="FunctionName">grade</span><span class="Keyword">:</span> <span class="FunctionArgument">student</span> <span class="Storage">=&gt;</span>
<span class="Keyword">if</span> student.excellent_work
<span class="String"><span class="String">&quot;</span>A+<span class="String">&quot;</span></span>
<span class="Keyword">else</span> <span class="Keyword">if</span> student.okay_stuff
<span class="String"><span class="String">&quot;</span>B<span class="String">&quot;</span></span>
<span class="Keyword">else</span>
<span class="String"><span class="String">&quot;</span>C<span class="String">&quot;</span></span>..
eldest<span class="Keyword">:</span> <span class="Keyword">if</span> <span class="Number">24</span> <span class="Keyword">&gt;</span> <span class="Number">21</span> <span class="Keyword">then</span> <span class="String"><span class="String">&quot;</span>Liz<span class="String">&quot;</span></span> <span class="Keyword">else</span> <span class="String"><span class="String">&quot;</span>Ike<span class="String">&quot;</span></span>.
</pre><pre class="idle"><span class="Storage">var</span> <span class="FunctionName">grade</span> = <span class="Storage">function</span>(<span class="FunctionArgument">student</span>) {
<span class="Keyword">if</span> (student.excellent_work) {
<span class="Keyword">return</span> <span class="String"><span class="String">&quot;</span>A+<span class="String">&quot;</span></span>;
} <span class="Keyword">else</span> <span class="Keyword">if</span> (student.okay_stuff) {
<span class="Keyword">return</span> <span class="String"><span class="String">&quot;</span>B<span class="String">&quot;</span></span>;
} <span class="Keyword">else</span> {
<span class="Keyword">return</span> <span class="String"><span class="String">&quot;</span>C<span class="String">&quot;</span></span>;
}
};
<span class="Storage">var</span> eldest <span class="Keyword">=</span> <span class="Number">24</span> <span class="Keyword">&gt;</span> <span class="Number">21</span> ? <span class="String"><span class="String">&quot;</span>Liz<span class="String">&quot;</span></span> : <span class="String"><span class="String">&quot;</span>Ike<span class="String">&quot;</span></span>;
</pre><button onclick='javascript: var grade = function(student) {
if (student.excellent_work) {
return "A+";
} else if (student.okay_stuff) {
return "B";
} else {
return "C";
}
};
var eldest = 24 > 21 ? "Liz" : "Ike";
;alert(eldest);'>run: eldest</button><br class='clear' /></div>
<p>
When compiling a function definition, CoffeeScript tries to push down
the return statement to each of the potential final lines of the function.
It uses the same mechanism to push down assignment statements. If statement
are compiled into ternary operators when possible, so that they can be used
as expressions.
</p>
<p id="while">
<b class="header">While Loops</b>
The only low-level loop that CoffeeScript provides is the while loop.
</p>
<div class='code'><pre class="idle"><span class="Keyword">while</span> demand <span class="Keyword">&gt;</span> supply
sell()
restock().
<span class="Keyword">while</span> supply <span class="Keyword">&gt;</span> demand <span class="Keyword">then</span> buy().
</pre><pre class="idle"><span class="Keyword">while</span> (demand <span class="Keyword">&gt;</span> supply) {
sell();
restock();
}
<span class="Keyword">while</span> (supply <span class="Keyword">&gt;</span> demand) {
buy();
}
</pre><br class='clear' /></div>
<p id="array_comprehensions">
<b class="header">Array Comprehensions</b>
Most of your looping needs should be handled by array comprehensions.
They replace (and compile into) for loops, handling
<b>each</b>/<b>forEach</b> style loops, as well as <b>select</b>/<b>filter</b>.
Unlike for loops, array comprehensions are expressions, and can be returned
and assigned.
</p>
<div class='code'><pre class="idle"><span class="Comment"><span class="Comment">#</span> Eat lunch.</span>
lunch<span class="Keyword">:</span> food.eat() <span class="Keyword">for</span> food <span class="Keyword">in</span> [<span class="String"><span class="String">'</span>toast<span class="String">'</span></span>, <span class="String"><span class="String">'</span>cheese<span class="String">'</span></span>, <span class="String"><span class="String">'</span>wine<span class="String">'</span></span>].
<span class="Comment"><span class="Comment">#</span> Zebra-stripe a table.</span>
highlight(row) <span class="Keyword">for</span> row, i <span class="Keyword">in</span> table <span class="Keyword">if</span> i <span class="Keyword">%</span> <span class="Number">2</span> <span class="Keyword">is</span> <span class="Number">0</span>.
</pre><pre class="idle"><span class="Storage">var</span> lunch;
<span class="Storage">var</span> a <span class="Keyword">=</span> [<span class="String"><span class="String">'</span>toast<span class="String">'</span></span>, <span class="String"><span class="String">'</span>cheese<span class="String">'</span></span>, <span class="String"><span class="String">'</span>wine<span class="String">'</span></span>];
<span class="Storage">var</span> d <span class="Keyword">=</span> [];
<span class="Keyword">for</span> (<span class="Storage">var</span> b<span class="Keyword">=</span><span class="Number">0</span>, c<span class="Keyword">=</span>a.<span class="LibraryConstant">length</span>; b<span class="Keyword">&lt;</span>c; b<span class="Keyword">++</span>) {
<span class="Storage">var</span> food <span class="Keyword">=</span> a[b];
d[b] <span class="Keyword">=</span> food.eat();
}
lunch <span class="Keyword">=</span> d;
<span class="Storage">var</span> e <span class="Keyword">=</span> table;
<span class="Keyword">for</span> (<span class="Storage">var</span> f<span class="Keyword">=</span><span class="Number">0</span>, g<span class="Keyword">=</span>e.<span class="LibraryConstant">length</span>; f<span class="Keyword">&lt;</span>g; f<span class="Keyword">++</span>) {
<span class="Storage">var</span> row <span class="Keyword">=</span> e[f];
<span class="Storage">var</span> i <span class="Keyword">=</span> f;
i <span class="Keyword">%</span> <span class="Number">2</span> <span class="Keyword">===</span> <span class="Number">0</span> ? highlight(row) : <span class="BuiltInConstant">null</span>;
}
</pre><br class='clear' /></div>
<p id="slice">
<b class="header">Array Slice Literals</b>
CoffeeScript includes a literal syntax for extracting slices of arrays.
The first argument is the index of the first element in the slice, and
the second is the index of the last one.
</p>
<div class='code'><pre class="idle">nums<span class="Keyword">:</span> [<span class="Number">0</span>, <span class="Number">1</span>, <span class="Number">2</span>, <span class="Number">3</span>, <span class="Number">4</span>, <span class="Number">5</span>, <span class="Number">6</span>, <span class="Number">7</span>, <span class="Number">8</span>, <span class="Number">9</span>]
three_to_six<span class="Keyword">:</span> nums[<span class="Number">3</span>, <span class="Number">6</span>]
</pre><pre class="idle"><span class="Storage">var</span> nums <span class="Keyword">=</span> [<span class="Number">0</span>, <span class="Number">1</span>, <span class="Number">2</span>, <span class="Number">3</span>, <span class="Number">4</span>, <span class="Number">5</span>, <span class="Number">6</span>, <span class="Number">7</span>, <span class="Number">8</span>, <span class="Number">9</span>];
<span class="Storage">var</span> three_to_six <span class="Keyword">=</span> nums.<span class="LibraryFunction">slice</span>(<span class="Number">3</span>, <span class="Number">6</span> <span class="Keyword">+</span> <span class="Number">1</span>);
</pre><button onclick='javascript: var nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
var three_to_six = nums.slice(3, 6 + 1);
;alert(three_to_six);'>run: three_to_six</button><br class='clear' /></div>
<p id="inheritance">
<b class="header">Inheritance, and Calling Super from a Subclass</b>
JavaScript's prototypal inheritance has always been a bit of a
brain-bender, with a whole family tree of libraries (Base2, Prototype
).
</p>
<div class='code'><pre class="idle"><span class="FunctionName">Animal</span><span class="Keyword">:</span> <span class="Storage">=&gt;</span> .
<span class="FunctionName">Animal.prototype.move</span><span class="Keyword">:</span> <span class="FunctionArgument">meters</span> <span class="Storage">=&gt;</span>
alert(<span class="Variable">this</span>.name <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span> moved <span class="String">&quot;</span></span> <span class="Keyword">+</span> meters <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span>m.<span class="String">&quot;</span></span>).
<span class="FunctionName">Snake</span><span class="Keyword">:</span> <span class="FunctionArgument">name</span> <span class="Storage">=&gt;</span> <span class="Variable">this</span>.name<span class="Keyword">:</span> name.
Snake <span class="Variable">extends</span> <span class="Keyword">new</span> <span class="TypeName">Animal</span>()
<span class="FunctionName">Snake.prototype.move</span><span class="Keyword">:</span> <span class="Storage">=&gt;</span>
alert(<span class="String"><span class="String">&quot;</span>Slithering...<span class="String">&quot;</span></span>)
<span class="Variable">super</span>(<span class="Number">5</span>).
<span class="FunctionName">Horse</span><span class="Keyword">:</span> <span class="FunctionArgument">name</span> <span class="Storage">=&gt;</span> <span class="Variable">this</span>.name<span class="Keyword">:</span> name.
Horse <span class="Variable">extends</span> <span class="Keyword">new</span> <span class="TypeName">Animal</span>()
<span class="FunctionName">Horse.prototype.move</span><span class="Keyword">:</span> <span class="Storage">=&gt;</span>
alert(<span class="String"><span class="String">&quot;</span>Galloping...<span class="String">&quot;</span></span>)
<span class="Variable">super</span>(<span class="Number">45</span>).
sam<span class="Keyword">:</span> <span class="Keyword">new</span> <span class="TypeName">Snake</span>(<span class="String"><span class="String">&quot;</span>Sammy the Python<span class="String">&quot;</span></span>)
tom<span class="Keyword">:</span> <span class="Keyword">new</span> <span class="TypeName">Horse</span>(<span class="String"><span class="String">&quot;</span>Tommy the Palomino<span class="String">&quot;</span></span>)
sam.move()
tom.move()
</pre><pre class="idle"><span class="Storage">var</span> <span class="FunctionName">Animal</span> = <span class="Storage">function</span>() {
};
<span class="LibraryClassType">Animal</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">move</span> = <span class="Storage">function</span>(<span class="FunctionArgument">meters</span>) {
<span class="Keyword">return</span> <span class="LibraryFunction">alert</span>(<span class="Variable">this</span>.<span class="LibraryConstant">name</span> <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span> moved <span class="String">&quot;</span></span> <span class="Keyword">+</span> meters <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span>m.<span class="String">&quot;</span></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="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="LibraryFunction">alert</span>(<span class="String"><span class="String">&quot;</span>Slithering...<span class="String">&quot;</span></span>);
<span class="Keyword">return</span> <span class="Variable">this</span>.<span class="LibraryConstant">constructor</span>.<span class="LibraryConstant">prototype</span>.move.<span class="LibraryFunction">call</span>(<span class="Variable">this</span>, <span class="Number">5</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="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="LibraryFunction">alert</span>(<span class="String"><span class="String">&quot;</span>Galloping...<span class="String">&quot;</span></span>);
<span class="Keyword">return</span> <span class="Variable">this</span>.<span class="LibraryConstant">constructor</span>.<span class="LibraryConstant">prototype</span>.move.<span class="LibraryFunction">call</span>(<span class="Variable">this</span>, <span class="Number">45</span>);
};
<span class="Storage">var</span> sam <span class="Keyword">=</span> <span class="Keyword">new</span> <span class="TypeName">Snake</span>(<span class="String"><span class="String">&quot;</span>Sammy the Python<span class="String">&quot;</span></span>);
<span class="Storage">var</span> tom <span class="Keyword">=</span> <span class="Keyword">new</span> <span class="TypeName">Horse</span>(<span class="String"><span class="String">&quot;</span>Tommy the Palomino<span class="String">&quot;</span></span>);
sam.move();
tom.move();
</pre><button onclick='javascript: var Animal = function() {
};
Animal.prototype.move = function(meters) {
return alert(this.name + " moved " + meters + "m.");
};
var Snake = function(name) {
this.name = name;
};
Snake.prototype = new Animal();
Snake.prototype.move = function() {
alert("Slithering...");
return this.constructor.prototype.move.call(this, 5);
};
var Horse = function(name) {
this.name = name;
};
Horse.prototype = new Animal();
Horse.prototype.move = function() {
alert("Galloping...");
return this.constructor.prototype.move.call(this, 45);
};
var sam = new Snake("Sammy the Python");
var tom = new Horse("Tommy the Palomino");
sam.move();
tom.move();
;'>run</button><br class='clear' /></div>
<p id="embedded">
<b class="header">Embedded JavaScript</b>
If you ever need to interpolate literal JavaScript snippets, you can
use backticks to pass JavaScript straight through.
</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>.
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">js</span> = <span class="Storage">function</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>) {
js();
}
</pre><button onclick='javascript: var js = function() {
return alert("Hello JavaScript");
};
if (10 > 9) {
js();
}
;'>run</button><br class='clear' /></div>
<p id="switch">
<b class="header">Switch/Case/Else</b>
Switch statements in JavaScript are fundamentally broken. You can only
do string comparisons, and need to break at the end of each case
statment to prevent falling through to the default case. CoffeeScript
compiles switch statements into if-else chains, allowing you to
compare any object (via <b>===</b>), preventing fall-through, and resulting
in a returnable expression.
</p>
<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()
<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()
<span class="Keyword">case</span> <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">then</span> go_to_bingo().
<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()
<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>) {
eat_breakfast();
} <span class="Keyword">else</span> <span class="Keyword">if</span> (day <span class="Keyword">===</span> <span class="String"><span class="String">&quot;</span>Wednesday<span class="String">&quot;</span></span>) {
go_to_the_park();
} <span class="Keyword">else</span> <span class="Keyword">if</span> (day <span class="Keyword">===</span> <span class="String"><span class="String">&quot;</span>Saturday<span class="String">&quot;</span></span>) {
day <span class="Keyword">===</span> bingo_day ? go_to_bingo() : <span class="BuiltInConstant">null</span>;
} <span class="Keyword">else</span> <span class="Keyword">if</span> (day <span class="Keyword">===</span> <span class="String"><span class="String">&quot;</span>Sunday<span class="String">&quot;</span></span>) {
go_to_church();
} <span class="Keyword">else</span> {
go_to_work();
}
</pre><br class='clear' /></div>
<p id="try">
<b class="header">Try/Catch/Finally</b>
Try/catch statements just about the same as JavaScript (although
they work as expressions). No braces required.
</p>
<div class='code'><pre class="idle"><span class="Keyword">try</span>
all_hell_breaks_loose()
cats_and_dogs_living_together()
<span class="Keyword">catch</span> error
print( error )
<span class="Keyword">finally</span>
clean_up().
</pre><pre class="idle"><span class="Keyword">try</span> {
all_hell_breaks_loose();
cats_and_dogs_living_together();
} <span class="Keyword">catch</span> (error) {
<span class="LibraryFunction">print</span>(error);
} <span class="Keyword">finally</span> {
clean_up();
}
</pre><br class='clear' /></div>
<p id="try">
<b class="header">Multiline Strings</b>
Multiline strings are allowed in CoffeeScript.
</p>
<div class='code'><pre class="idle">moby_dick<span class="Keyword">:</span> <span class="String"><span class="String">&quot;</span>Call me Ishmael. Some years ago --</span>
<span class="String">never mind how long precisely -- having little</span>
<span class="String">or no money in my purse, and nothing particular</span>
<span class="String">to interest me on shore, I thought I would sail</span>
<span class="String">about a little and see the watery part of the</span>
<span class="String">world...<span class="String">&quot;</span></span>
</pre><pre class="idle"><span class="Storage">var</span> moby_dick <span class="Keyword">=</span> <span class="String"><span class="String">&quot;</span>Call me Ishmael. Some years ago --\</span>
<span class="String">never mind how long precisely -- having little\</span>
<span class="String">or no money in my purse, and nothing particular\</span>
<span class="String">to interest me on shore, I thought I would sail\</span>
<span class="String">about a little and see the watery part of the\</span>
<span class="String">world...<span class="String">&quot;</span></span>;
</pre><br class='clear' /></div>
</div>
</div>
</body>

View file

@ -229,7 +229,7 @@
</dict>
<dict>
<key>match</key>
<string>\b(super|this)\b</string>
<string>\b(super|this|extends)\b</string>
<key>name</key>
<string>variable.language.cs</string>
</dict>

View file

@ -10,7 +10,7 @@ token TRY CATCH FINALLY THROW
token BREAK CONTINUE
token FOR IN WHILE
token SWITCH CASE
token SUPER
token EXTENDS SUPER
token DELETE
token NEWLINE
token JS
@ -28,8 +28,8 @@ prechigh
right '-=' '+=' '/=' '*=' '||=' '&&='
right DELETE
left "."
right THROW FOR IN WHILE
left UNLESS IF ELSE
right THROW FOR IN WHILE NEW
left UNLESS IF ELSE EXTENDS
left ":"
right RETURN
preclow
@ -68,6 +68,7 @@ rule
| Call
| Code
| Operation
| Extend
;
# We have to take extra care to convert these statements into expressions.
@ -246,6 +247,11 @@ rule
SUPER "(" ArgList ")" { result = CallNode.new(:super, val[2]) }
;
# Extending a class.
Extend:
IDENTIFIER EXTENDS Expression { result = ExtendNode.new(val[0], val[2]) }
;
# The array literal.
Array:
"[" ArgList "]" { result = ArrayNode.new(val[1]) }

View file

@ -14,7 +14,7 @@ module CoffeeScript
"break", "continue",
"for", "in", "while",
"switch", "case",
"super",
"extends", "super",
"delete"]
# Token matching regexes.

View file

@ -110,6 +110,10 @@ module CoffeeScript
STATEMENTS.include?(@value.to_s)
end
def line_ending
@value.to_s[-1..-1] == ';' ? '' : ';'
end
def compile(indent, scope, opts={})
code = @value.to_s
write(code)
@ -171,6 +175,20 @@ module CoffeeScript
end
end
class ExtendNode < Node
attr_reader :subclass, :superclass
def initialize(subclass, superclass)
@subclass, @superclass = subclass, superclass
end
def compile(indent, scope, opts={})
"#{@subclass}.prototype = #{@superclass.compile(indent, scope, opts)}"
end
end
# A value, indexed or dotted into, or vanilla.
class ValueNode < Node
attr_reader :literal, :properties, :last
@ -269,7 +287,7 @@ module CoffeeScript
def compile(indent, scope, opts={})
name = @variable.respond_to?(:compile) ? @variable.compile(indent, scope) : @variable
last = @variable.respond_to?(:last) ? @variable.last : name
last = @variable.respond_to?(:last) ? @variable.last.to_s : name.to_s
opts = opts.merge({:assign => name, :last_assign => last})
return write("#{@variable}: #{@value.compile(indent, scope, opts)}") if @context == :object
return write("#{name} = #{@value.compile(indent, scope, opts)}") if @variable.properties?