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"
|
desc "Build the documentation page"
|
||||||
task :doc do
|
task :doc do
|
||||||
source = 'documentation/index.html.erb'
|
source = 'documentation/index.html.erb'
|
||||||
|
Thread.new { `bin/coffee-script documentation/cs/*.cs -o documentation/js -w` }
|
||||||
loop do
|
loop do
|
||||||
mtime = File.stat(source).mtime
|
mtime = File.stat(source).mtime
|
||||||
if !@mtime || mtime > @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 {
|
body {
|
||||||
font-size: 16px;
|
font-size: 14px;
|
||||||
line-height: 24px;
|
line-height: 20px;
|
||||||
background: #f0f0e5;
|
background: #efefef;
|
||||||
color: #252519;
|
color: #191933;
|
||||||
font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
}
|
}
|
||||||
div.container {
|
div.container {
|
||||||
width: 720px;
|
width: 850px;
|
||||||
margin: 50px 0 50px 50px;
|
margin: 50px 0 50px 50px;
|
||||||
}
|
}
|
||||||
p {
|
p {
|
||||||
width: 550px;
|
padding-left: 13px;
|
||||||
|
width: 625px;
|
||||||
}
|
}
|
||||||
#documentation p {
|
a {
|
||||||
margin-bottom: 4px;
|
color: #000055;
|
||||||
}
|
|
||||||
a, a:visited {
|
|
||||||
padding: 0 2px;
|
|
||||||
text-decoration: none;
|
|
||||||
background: #dadaba;
|
|
||||||
color: #252519;
|
|
||||||
}
|
|
||||||
a:active, a:hover {
|
|
||||||
color: #000;
|
|
||||||
background: #f0c095;
|
|
||||||
}
|
}
|
||||||
h1, h2, h3, h4, h5, h6 {
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
padding-left: 13px;
|
||||||
margin-top: 40px;
|
margin-top: 40px;
|
||||||
}
|
}
|
||||||
b.header {
|
br.clear {
|
||||||
font-size: 18px;
|
height: 0;
|
||||||
|
clear: both;
|
||||||
}
|
}
|
||||||
span.alias {
|
b.header {
|
||||||
font-size: 14px;
|
color: #000055;
|
||||||
font-style: italic;
|
display: block;
|
||||||
margin-left: 20px;
|
margin: 40px 0 5px 0;
|
||||||
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
table, tr, td {
|
table, tr, td {
|
||||||
margin: 0; padding: 0;
|
margin: 0; padding: 0;
|
||||||
|
@ -53,7 +47,24 @@ code, pre, tt {
|
||||||
}
|
}
|
||||||
pre {
|
pre {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
padding: 2px 0 2px 12px;
|
padding: 0 0 0 12px;
|
||||||
border-left: 6px solid #aaaa99;
|
margin: 0;
|
||||||
margin: 0px 0 30px;
|
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>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
|
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
|
||||||
<title>CoffeeScript</title>
|
<title>CoffeeScript, briefly...</title>
|
||||||
<link rel="stylesheet" type="text/css" href="documentation/css/docs.css" />
|
<link rel="stylesheet" type="text/css" href="documentation/css/docs.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="documentation/css/idle.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
<h1>CoffeeScript</h1>
|
<h1><sub style="font-size: 100px;">☕</sub> CoffeeScript</h1>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
CoffeeScript is a little language that compiles into JavaScript. Think
|
CoffeeScript is a little language that compiles into JavaScript. Think
|
||||||
of it as JavaScript's simpleminded kid brother — the same genes,
|
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>
|
||||||
|
|
||||||
<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>
|
||||||
|
|
||||||
|
<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>
|
</div>
|
||||||
|
|
||||||
</body>
|
</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
|
sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna
|
||||||
aliquam erat volutpat. Ut wisi enim ad."
|
aliquam erat volutpat. Ut wisi enim ad."
|
||||||
|
|
||||||
# Calling super from an overridden method.
|
# Inheritance and calling super.
|
||||||
Greeter: => . # Create the parent object.
|
Animal: => .
|
||||||
Greeter.prototype.hello: name => alert('Hello ' + name). # Define a "hello" method.
|
Animal.prototype.move: meters =>
|
||||||
Exclaimer: name => this.name: name. # Create the child object.
|
alert(this.name + " moved " + meters + "m.").
|
||||||
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".
|
Snake: name => this.name: name.
|
||||||
(new Exclaimer('Bob')).hello() # Run it.
|
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.
|
# Numbers.
|
||||||
a_googol: 1e100
|
a_googol: 1e100
|
||||||
|
|
468
index.html
468
index.html
|
@ -1,22 +1,484 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
|
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
|
||||||
<title>CoffeeScript</title>
|
<title>CoffeeScript, briefly...</title>
|
||||||
<link rel="stylesheet" type="text/css" href="documentation/css/docs.css" />
|
<link rel="stylesheet" type="text/css" href="documentation/css/docs.css" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="documentation/css/idle.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
<h1>CoffeeScript</h1>
|
<h1><sub style="font-size: 100px;">☕</sub> CoffeeScript</h1>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
CoffeeScript is a little language that compiles into JavaScript. Think
|
CoffeeScript is a little language that compiles into JavaScript. Think
|
||||||
of it as JavaScript's simpleminded kid brother — the same genes,
|
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>
|
||||||
|
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<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>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -229,7 +229,7 @@
|
||||||
</dict>
|
</dict>
|
||||||
<dict>
|
<dict>
|
||||||
<key>match</key>
|
<key>match</key>
|
||||||
<string>\b(super|this)\b</string>
|
<string>\b(super|this|extends)\b</string>
|
||||||
<key>name</key>
|
<key>name</key>
|
||||||
<string>variable.language.cs</string>
|
<string>variable.language.cs</string>
|
||||||
</dict>
|
</dict>
|
||||||
|
|
|
@ -10,7 +10,7 @@ token TRY CATCH FINALLY THROW
|
||||||
token BREAK CONTINUE
|
token BREAK CONTINUE
|
||||||
token FOR IN WHILE
|
token FOR IN WHILE
|
||||||
token SWITCH CASE
|
token SWITCH CASE
|
||||||
token SUPER
|
token EXTENDS SUPER
|
||||||
token DELETE
|
token DELETE
|
||||||
token NEWLINE
|
token NEWLINE
|
||||||
token JS
|
token JS
|
||||||
|
@ -28,8 +28,8 @@ prechigh
|
||||||
right '-=' '+=' '/=' '*=' '||=' '&&='
|
right '-=' '+=' '/=' '*=' '||=' '&&='
|
||||||
right DELETE
|
right DELETE
|
||||||
left "."
|
left "."
|
||||||
right THROW FOR IN WHILE
|
right THROW FOR IN WHILE NEW
|
||||||
left UNLESS IF ELSE
|
left UNLESS IF ELSE EXTENDS
|
||||||
left ":"
|
left ":"
|
||||||
right RETURN
|
right RETURN
|
||||||
preclow
|
preclow
|
||||||
|
@ -68,6 +68,7 @@ rule
|
||||||
| Call
|
| Call
|
||||||
| Code
|
| Code
|
||||||
| Operation
|
| Operation
|
||||||
|
| Extend
|
||||||
;
|
;
|
||||||
|
|
||||||
# We have to take extra care to convert these statements into expressions.
|
# 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]) }
|
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.
|
# The array literal.
|
||||||
Array:
|
Array:
|
||||||
"[" ArgList "]" { result = ArrayNode.new(val[1]) }
|
"[" ArgList "]" { result = ArrayNode.new(val[1]) }
|
||||||
|
|
|
@ -14,7 +14,7 @@ module CoffeeScript
|
||||||
"break", "continue",
|
"break", "continue",
|
||||||
"for", "in", "while",
|
"for", "in", "while",
|
||||||
"switch", "case",
|
"switch", "case",
|
||||||
"super",
|
"extends", "super",
|
||||||
"delete"]
|
"delete"]
|
||||||
|
|
||||||
# Token matching regexes.
|
# Token matching regexes.
|
||||||
|
|
|
@ -110,6 +110,10 @@ module CoffeeScript
|
||||||
STATEMENTS.include?(@value.to_s)
|
STATEMENTS.include?(@value.to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def line_ending
|
||||||
|
@value.to_s[-1..-1] == ';' ? '' : ';'
|
||||||
|
end
|
||||||
|
|
||||||
def compile(indent, scope, opts={})
|
def compile(indent, scope, opts={})
|
||||||
code = @value.to_s
|
code = @value.to_s
|
||||||
write(code)
|
write(code)
|
||||||
|
@ -171,6 +175,20 @@ module CoffeeScript
|
||||||
end
|
end
|
||||||
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.
|
# A value, indexed or dotted into, or vanilla.
|
||||||
class ValueNode < Node
|
class ValueNode < Node
|
||||||
attr_reader :literal, :properties, :last
|
attr_reader :literal, :properties, :last
|
||||||
|
@ -269,7 +287,7 @@ module CoffeeScript
|
||||||
|
|
||||||
def compile(indent, scope, opts={})
|
def compile(indent, scope, opts={})
|
||||||
name = @variable.respond_to?(:compile) ? @variable.compile(indent, scope) : @variable
|
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})
|
opts = opts.merge({:assign => name, :last_assign => last})
|
||||||
return write("#{@variable}: #{@value.compile(indent, scope, opts)}") if @context == :object
|
return write("#{@variable}: #{@value.compile(indent, scope, opts)}") if @context == :object
|
||||||
return write("#{name} = #{@value.compile(indent, scope, opts)}") if @variable.properties?
|
return write("#{name} = #{@value.compile(indent, scope, opts)}") if @variable.properties?
|
||||||
|
|
Loading…
Add table
Reference in a new issue