mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
documentation waypoint
This commit is contained in:
parent
dcc70e5ab0
commit
c7fa9c320a
42 changed files with 1026 additions and 53 deletions
1
Rakefile
1
Rakefile
|
@ -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
|
||||
|
|
5
documentation/cs/array_comprehensions.cs
Normal file
5
documentation/cs/array_comprehensions.cs
Normal 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.
|
2
documentation/cs/assignment.cs
Normal file
2
documentation/cs/assignment.cs
Normal file
|
@ -0,0 +1,2 @@
|
|||
greeting: "Hello CoffeeScript"
|
||||
difficulty: 0.5
|
9
documentation/cs/conditionals.cs
Normal file
9
documentation/cs/conditionals.cs
Normal 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()
|
3
documentation/cs/embedded.cs
Normal file
3
documentation/cs/embedded.cs
Normal file
|
@ -0,0 +1,3 @@
|
|||
js: => `alert("Hello JavaScript");`.
|
||||
|
||||
js() if 10 > 9
|
9
documentation/cs/expressions.cs
Normal file
9
documentation/cs/expressions.cs
Normal 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".
|
2
documentation/cs/functions.cs
Normal file
2
documentation/cs/functions.cs
Normal file
|
@ -0,0 +1,2 @@
|
|||
square: x => x * x.
|
||||
cube: x => square(x) * x.
|
3
documentation/cs/intro.cs
Normal file
3
documentation/cs/intro.cs
Normal file
|
@ -0,0 +1,3 @@
|
|||
# CoffeeScript on the left, JS on the right.
|
||||
|
||||
square: x => x * x.
|
6
documentation/cs/objects_and_arrays.cs
Normal file
6
documentation/cs/objects_and_arrays.cs
Normal file
|
@ -0,0 +1,6 @@
|
|||
song: ["do", "re", "mi", "fa", "so"]
|
||||
ages: {
|
||||
max: 10
|
||||
ida: 9
|
||||
tim: 11
|
||||
}
|
11
documentation/cs/punctuation.cs
Normal file
11
documentation/cs/punctuation.cs
Normal 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.
|
5
documentation/cs/scope.cs
Normal file
5
documentation/cs/scope.cs
Normal file
|
@ -0,0 +1,5 @@
|
|||
num: 1
|
||||
change_numbers: =>
|
||||
num: 2
|
||||
new_num: 3.
|
||||
new_num: change_numbers()
|
2
documentation/cs/slices.cs
Normal file
2
documentation/cs/slices.cs
Normal file
|
@ -0,0 +1,2 @@
|
|||
nums: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
three_to_six: nums[3, 6]
|
6
documentation/cs/strings.cs
Normal file
6
documentation/cs/strings.cs
Normal 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
21
documentation/cs/super.cs
Normal 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()
|
7
documentation/cs/switch.cs
Normal file
7
documentation/cs/switch.cs
Normal 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
7
documentation/cs/try.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
try
|
||||
all_hell_breaks_loose()
|
||||
cats_and_dogs_living_together()
|
||||
catch error
|
||||
print( error )
|
||||
finally
|
||||
clean_up().
|
5
documentation/cs/while.cs
Normal file
5
documentation/cs/while.cs
Normal file
|
@ -0,0 +1,5 @@
|
|||
while demand > supply
|
||||
sell()
|
||||
restock().
|
||||
|
||||
while supply > demand then buy().
|
|
@ -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;
|
||||
}
|
|
@ -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;">☕</sub> CoffeeScript</h1>
|
||||
|
||||
<p>
|
||||
CoffeeScript is a little language that compiles into JavaScript. Think
|
||||
of it as JavaScript's simpleminded kid brother — 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 — 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>
|
||||
|
|
16
documentation/js/array_comprehensions.js
Normal file
16
documentation/js/array_comprehensions.js
Normal 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;
|
||||
}
|
||||
})();
|
4
documentation/js/assignment.js
Normal file
4
documentation/js/assignment.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
(function(){
|
||||
var greeting = "Hello CoffeeScript";
|
||||
var difficulty = 0.5;
|
||||
})();
|
12
documentation/js/conditionals.js
Normal file
12
documentation/js/conditionals.js
Normal 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();
|
||||
})();
|
8
documentation/js/embedded.js
Normal file
8
documentation/js/embedded.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
(function(){
|
||||
var js = function() {
|
||||
return alert("Hello JavaScript");
|
||||
};
|
||||
if (10 > 9) {
|
||||
js();
|
||||
}
|
||||
})();
|
12
documentation/js/expressions.js
Normal file
12
documentation/js/expressions.js
Normal 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";
|
||||
})();
|
3
documentation/js/expressions_assignment.js
Normal file
3
documentation/js/expressions_assignment.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
(function(){
|
||||
|
||||
})();
|
8
documentation/js/functions.js
Normal file
8
documentation/js/functions.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
(function(){
|
||||
var square = function(x) {
|
||||
return x * x;
|
||||
};
|
||||
var cube = function(x) {
|
||||
return square(x) * x;
|
||||
};
|
||||
})();
|
5
documentation/js/intro.js
Normal file
5
documentation/js/intro.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
(function(){
|
||||
var square = function(x) {
|
||||
return x * x;
|
||||
};
|
||||
})();
|
8
documentation/js/objects_and_arrays.js
Normal file
8
documentation/js/objects_and_arrays.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
(function(){
|
||||
var song = ["do", "re", "mi", "fa", "so"];
|
||||
var ages = {
|
||||
max: 10,
|
||||
ida: 9,
|
||||
tim: 11
|
||||
};
|
||||
})();
|
4
documentation/js/punctuation.js
Normal file
4
documentation/js/punctuation.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
(function(){
|
||||
var left_hand = raining ? umbrella : parasol;
|
||||
left_hand = raining ? umbrella : parasol;
|
||||
})();
|
9
documentation/js/scope.js
Normal file
9
documentation/js/scope.js
Normal 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();
|
||||
})();
|
4
documentation/js/slices.js
Normal file
4
documentation/js/slices.js
Normal 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);
|
||||
})();
|
8
documentation/js/strings.js
Normal file
8
documentation/js/strings.js
Normal 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
28
documentation/js/super.js
Normal 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();
|
||||
})();
|
13
documentation/js/switch.js
Normal file
13
documentation/js/switch.js
Normal 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
10
documentation/js/try.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
(function(){
|
||||
try {
|
||||
all_hell_breaks_loose();
|
||||
cats_and_dogs_living_together();
|
||||
} catch (error) {
|
||||
print(error);
|
||||
} finally {
|
||||
clean_up();
|
||||
}
|
||||
})();
|
9
documentation/js/while.js
Normal file
9
documentation/js/while.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
(function(){
|
||||
while (demand > supply) {
|
||||
sell();
|
||||
restock();
|
||||
}
|
||||
while (supply > demand) {
|
||||
buy();
|
||||
}
|
||||
})();
|
|
@ -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
|
||||
|
|
472
index.html
472
index.html
|
@ -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;">☕</sub> CoffeeScript</h1>
|
||||
|
||||
<p>
|
||||
CoffeeScript is a little language that compiles into JavaScript. Think
|
||||
of it as JavaScript's simpleminded kid brother — 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">=></span> x <span class="Keyword">*</span> x.
|
||||
<span class="FunctionName">cube</span><span class="Keyword">:</span> <span class="FunctionArgument">x</span> <span class="Storage">=></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">"</span>do<span class="String">"</span></span>, <span class="String"><span class="String">"</span>re<span class="String">"</span></span>, <span class="String"><span class="String">"</span>mi<span class="String">"</span></span>, <span class="String"><span class="String">"</span>fa<span class="String">"</span></span>, <span class="String"><span class="String">"</span>so<span class="String">"</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">"</span>do<span class="String">"</span></span>, <span class="String"><span class="String">"</span>re<span class="String">"</span></span>, <span class="String"><span class="String">"</span>mi<span class="String">"</span></span>, <span class="String"><span class="String">"</span>fa<span class="String">"</span></span>, <span class="String"><span class="String">"</span>so<span class="String">"</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">"</span>Hello CoffeeScript<span class="String">"</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">"</span>Hello CoffeeScript<span class="String">"</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 — 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">=></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">&</span><span class="Keyword">&</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">=></span>
|
||||
<span class="Keyword">if</span> student.excellent_work
|
||||
<span class="String"><span class="String">"</span>A+<span class="String">"</span></span>
|
||||
<span class="Keyword">else</span> <span class="Keyword">if</span> student.okay_stuff
|
||||
<span class="String"><span class="String">"</span>B<span class="String">"</span></span>
|
||||
<span class="Keyword">else</span>
|
||||
<span class="String"><span class="String">"</span>C<span class="String">"</span></span>..
|
||||
|
||||
eldest<span class="Keyword">:</span> <span class="Keyword">if</span> <span class="Number">24</span> <span class="Keyword">></span> <span class="Number">21</span> <span class="Keyword">then</span> <span class="String"><span class="String">"</span>Liz<span class="String">"</span></span> <span class="Keyword">else</span> <span class="String"><span class="String">"</span>Ike<span class="String">"</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">"</span>A+<span class="String">"</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">"</span>B<span class="String">"</span></span>;
|
||||
} <span class="Keyword">else</span> {
|
||||
<span class="Keyword">return</span> <span class="String"><span class="String">"</span>C<span class="String">"</span></span>;
|
||||
}
|
||||
};
|
||||
<span class="Storage">var</span> eldest <span class="Keyword">=</span> <span class="Number">24</span> <span class="Keyword">></span> <span class="Number">21</span> ? <span class="String"><span class="String">"</span>Liz<span class="String">"</span></span> : <span class="String"><span class="String">"</span>Ike<span class="String">"</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">></span> supply
|
||||
sell()
|
||||
restock().
|
||||
|
||||
<span class="Keyword">while</span> supply <span class="Keyword">></span> demand <span class="Keyword">then</span> buy().
|
||||
</pre><pre class="idle"><span class="Keyword">while</span> (demand <span class="Keyword">></span> supply) {
|
||||
sell();
|
||||
restock();
|
||||
}
|
||||
<span class="Keyword">while</span> (supply <span class="Keyword">></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"><</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"><</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">=></span> .
|
||||
<span class="FunctionName">Animal.prototype.move</span><span class="Keyword">:</span> <span class="FunctionArgument">meters</span> <span class="Storage">=></span>
|
||||
alert(<span class="Variable">this</span>.name <span class="Keyword">+</span> <span class="String"><span class="String">"</span> moved <span class="String">"</span></span> <span class="Keyword">+</span> meters <span class="Keyword">+</span> <span class="String"><span class="String">"</span>m.<span class="String">"</span></span>).
|
||||
|
||||
<span class="FunctionName">Snake</span><span class="Keyword">:</span> <span class="FunctionArgument">name</span> <span class="Storage">=></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">=></span>
|
||||
alert(<span class="String"><span class="String">"</span>Slithering...<span class="String">"</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">=></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">=></span>
|
||||
alert(<span class="String"><span class="String">"</span>Galloping...<span class="String">"</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">"</span>Sammy the Python<span class="String">"</span></span>)
|
||||
tom<span class="Keyword">:</span> <span class="Keyword">new</span> <span class="TypeName">Horse</span>(<span class="String"><span class="String">"</span>Tommy the Palomino<span class="String">"</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">"</span> moved <span class="String">"</span></span> <span class="Keyword">+</span> meters <span class="Keyword">+</span> <span class="String"><span class="String">"</span>m.<span class="String">"</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">"</span>Slithering...<span class="String">"</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">"</span>Galloping...<span class="String">"</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">"</span>Sammy the Python<span class="String">"</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">"</span>Tommy the Palomino<span class="String">"</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">=></span> <span class="String"><span class="String">`</span>alert("Hello JavaScript");<span class="String">`</span></span>.
|
||||
|
||||
js() <span class="Keyword">if</span> <span class="Number">10</span> <span class="Keyword">></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">"</span>Hello JavaScript<span class="String">"</span></span>);
|
||||
};
|
||||
<span class="Keyword">if</span> (<span class="Number">10</span> <span class="Keyword">></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">"</span>Tuesday<span class="String">"</span></span> <span class="Keyword">then</span> eat_breakfast()
|
||||
<span class="Keyword">case</span> <span class="String"><span class="String">"</span>Wednesday<span class="String">"</span></span> <span class="Keyword">then</span> go_to_the_park()
|
||||
<span class="Keyword">case</span> <span class="String"><span class="String">"</span>Saturday<span class="String">"</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">"</span>Sunday<span class="String">"</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">"</span>Tuesday<span class="String">"</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">"</span>Wednesday<span class="String">"</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">"</span>Saturday<span class="String">"</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">"</span>Sunday<span class="String">"</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">"</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">"</span></span>
|
||||
</pre><pre class="idle"><span class="Storage">var</span> moby_dick <span class="Keyword">=</span> <span class="String"><span class="String">"</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">"</span></span>;
|
||||
</pre><br class='clear' /></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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]) }
|
||||
|
|
|
@ -14,7 +14,7 @@ module CoffeeScript
|
|||
"break", "continue",
|
||||
"for", "in", "while",
|
||||
"switch", "case",
|
||||
"super",
|
||||
"extends", "super",
|
||||
"delete"]
|
||||
|
||||
# Token matching regexes.
|
||||
|
|
|
@ -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?
|
||||
|
|
Loading…
Add table
Reference in a new issue