node conversion finished, narwhal removed.

This commit is contained in:
Jeremy Ashkenas
2010-01-29 23:30:54 -05:00
parent e08e99a403
commit f5a37035cf
48 changed files with 208 additions and 357 deletions

View File

@@ -17,10 +17,9 @@ namespace :build do
sh "racc #{args[:racc_args]} -o lib/coffee_script/parser.rb lib/coffee_script/grammar.y" sh "racc #{args[:racc_args]} -o lib/coffee_script/parser.rb lib/coffee_script/grammar.y"
end end
desc "Compile the Narwhal interface for --interactive and --run" desc "Continually compile the CoffeeScript/Node.js components with --watch"
task :narwhal do task :node do
sh "bin/coffee lib/coffee_script/narwhal/*.coffee -o lib/coffee_script/narwhal/lib/coffee-script" sh "bin/coffee -w src/*.coffee -o lib/coffee_script/"
sh "mv lib/coffee_script/narwhal/lib/coffee-script/coffee-script.js lib/coffee_script/narwhal/lib/coffee-script.js"
end end
desc "Compile and install the Ultraviolet syntax highlighter" desc "Compile and install the Ultraviolet syntax highlighter"

View File

@@ -118,7 +118,7 @@ gem install coffee-script</pre>
Installing the gem provides the <tt>coffee</tt> command, which can Installing the gem provides the <tt>coffee</tt> command, which can
be used to compile CoffeeScript <tt>.coffee</tt> files into JavaScript, as be used to compile CoffeeScript <tt>.coffee</tt> files into JavaScript, as
well as debug them. In conjunction with well as debug them. In conjunction with
<a href="http://narwhaljs.org/">Narwhal</a>, the <tt>coffee</tt> <a href="http://nodejs.org/">Node.js</a>, the <tt>coffee</tt>
command also provides direct evaluation and an interactive REPL. command also provides direct evaluation and an interactive REPL.
When compiling to JavaScript, <tt>coffee</tt> writes the output When compiling to JavaScript, <tt>coffee</tt> writes the output
as <tt>.js</tt> files in the same directory by default, but output as <tt>.js</tt> files in the same directory by default, but output
@@ -130,14 +130,14 @@ gem install coffee-script</pre>
<td width="25%"><code>-i, --interactive</code></td> <td width="25%"><code>-i, --interactive</code></td>
<td> <td>
Launch an interactive CoffeeScript session. Launch an interactive CoffeeScript session.
Requires <a href="http://narwhaljs.org/">Narwhal</a>. Requires <a href="http://nodejs.org/">Node.js</a>.
</td> </td>
</tr> </tr>
<tr> <tr>
<td><code>-r, --run</code></td> <td><code>-r, --run</code></td>
<td> <td>
Compile and execute scripts without saving the intermediate Compile and execute scripts without saving the intermediate
JavaScript. Requires <a href="http://narwhaljs.org/">Narwhal</a>. JavaScript. Requires <a href="http://nodejs.org/">Node.js</a>.
</td> </td>
</tr> </tr>
<tr> <tr>
@@ -194,7 +194,7 @@ gem install coffee-script</pre>
<td><code>-n, --no-wrap</code></td> <td><code>-n, --no-wrap</code></td>
<td> <td>
Compile the JavaScript without the top-level function safety wrapper. Compile the JavaScript without the top-level function safety wrapper.
(Used for CoffeeScript as a Narwhal module.) (Used for CoffeeScript as a Node.js module.)
</td> </td>
</tr> </tr>
<tr> <tr>

View File

@@ -11,6 +11,6 @@ index: (list, target) ->
if val < target then low: mid + 1 else high: mid if val < target then low: mid + 1 else high: mid
return -1 return -1
print(2 is index([10, 20, 30, 40, 50], 30)) puts 2 is index([10, 20, 30, 40, 50], 30)
print(4 is index([-97, 35, 67, 88, 1200], 1200)) puts 4 is index([-97, 35, 67, 88, 1200], 1200)
print(0 is index([0, 45, 70], 0)) puts 0 is index([0, 45, 70], 0)

View File

@@ -8,6 +8,6 @@ runtime: (N) ->
t: n - 1 + sum / n t: n - 1 + sum / n
t t
print(runtime(3) is 2.6666666666666665) puts runtime(3) is 2.6666666666666665
print(runtime(5) is 7.4) puts runtime(5) is 7.4
print(runtime(8) is 16.92142857142857) puts runtime(8) is 16.92142857142857

View File

@@ -26,9 +26,9 @@ match_star: (c, regexp, text) ->
return false unless text and (text[0] is c or c is '.') return false unless text and (text[0] is c or c is '.')
text: text.slice(1) text: text.slice(1)
print(match("ex", "some text")) puts match("ex", "some text")
print(match("s..t", "spit")) puts match("s..t", "spit")
print(match("^..t", "buttercup")) puts match("^..t", "buttercup")
print(match("i..$", "cherries")) puts match("i..$", "cherries")
print(match("o*m", "vrooooommm!")) puts match("o*m", "vrooooommm!")
print(match("^hel*o$", "hellllllo")) puts match("^hel*o$", "hellllllo")

View File

@@ -19,7 +19,7 @@ binary_search: (items, value) ->
# Test the function. # Test the function.
print(2 is binary_search([10, 20, 30, 40, 50], 30)) puts(2 is binary_search([10, 20, 30, 40, 50], 30))
print(4 is binary_search([-97, 35, 67, 88, 1200], 1200)) puts(4 is binary_search([-97, 35, 67, 88, 1200], 1200))
print(0 is binary_search([0, 45, 70], 0)) puts(0 is binary_search([0, 45, 70], 0))
print(-1 is binary_search([0, 45, 70], 10)) puts(-1 is binary_search([0, 45, 70], 10))

View File

@@ -7,5 +7,5 @@ bubble_sort: (list) ->
# Test the function. # Test the function.
print(bubble_sort([3, 2, 1]).join(' ') is '1 2 3') puts(bubble_sort([3, 2, 1]).join(' ') is '1 2 3')
print(bubble_sort([9, 2, 7, 0, 1]).join(' ') is '0 1 2 7 9') puts(bubble_sort([9, 2, 7, 0, 1]).join(' ') is '0 1 2 7 9')

View File

@@ -91,16 +91,16 @@ LinkedList::toString: -> this.toArray().toString()
list: new LinkedList() list: new LinkedList()
list.add("Hi") list.add("Hi")
print(list.size() is 1) puts(list.size() is 1)
print(list.item(0) is "Hi") puts(list.item(0) is "Hi")
print(list.item(1) is null) puts(list.item(1) is null)
list: new LinkedList() list: new LinkedList()
list.add("zero").add("one").add("two") list.add("zero").add("one").add("two")
print(list.size() is 3) puts(list.size() is 3)
print(list.item(2) is "two") puts(list.item(2) is "two")
print(list.remove(1) is "one") puts(list.remove(1) is "one")
print(list.item(0) is "zero") puts(list.item(0) is "zero")
print(list.item(1) is "two") puts(list.item(1) is "two")
print(list.size() is 2) puts(list.size() is 2)
print(list.item(-10) is null) puts(list.item(-10) is null)

View File

@@ -31,6 +31,6 @@ is_valid_identifier: (identifier) ->
# Tests. # Tests.
print(is_valid_identifier("49927398716") is true) puts(is_valid_identifier("49927398716") is true)
print(is_valid_identifier("4408041234567893") is true) puts(is_valid_identifier("4408041234567893") is true)
print(is_valid_identifier("4408041234567890") is false) puts(is_valid_identifier("4408041234567890") is false)

View File

@@ -15,5 +15,5 @@ merge_sort: (list) ->
# Test the function. # Test the function.
print(merge_sort([3, 2, 1]).join(' ') is '1 2 3') puts(merge_sort([3, 2, 1]).join(' ') is '1 2 3')
print(merge_sort([9, 2, 7, 0, 1]).join(' ') is '0 1 2 7 9') puts(merge_sort([9, 2, 7, 0, 1]).join(' ') is '0 1 2 7 9')

View File

@@ -19,5 +19,5 @@ selection_sort: (list) ->
# Test the function. # Test the function.
print(selection_sort([3, 2, 1]).join(' ') is '1 2 3') puts(selection_sort([3, 2, 1]).join(' ') is '1 2 3')
print(selection_sort([9, 2, 7, 0, 1]).join(' ') is '0 1 2 7 9') puts(selection_sort([9, 2, 7, 0, 1]).join(' ') is '0 1 2 7 9')

View File

@@ -215,7 +215,7 @@ gem install coffee-script</pre>
Installing the gem provides the <tt>coffee</tt> command, which can Installing the gem provides the <tt>coffee</tt> command, which can
be used to compile CoffeeScript <tt>.coffee</tt> files into JavaScript, as be used to compile CoffeeScript <tt>.coffee</tt> files into JavaScript, as
well as debug them. In conjunction with well as debug them. In conjunction with
<a href="http://narwhaljs.org/">Narwhal</a>, the <tt>coffee</tt> <a href="http://nodejs.org/">Node.js</a>, the <tt>coffee</tt>
command also provides direct evaluation and an interactive REPL. command also provides direct evaluation and an interactive REPL.
When compiling to JavaScript, <tt>coffee</tt> writes the output When compiling to JavaScript, <tt>coffee</tt> writes the output
as <tt>.js</tt> files in the same directory by default, but output as <tt>.js</tt> files in the same directory by default, but output
@@ -227,14 +227,14 @@ gem install coffee-script</pre>
<td width="25%"><code>-i, --interactive</code></td> <td width="25%"><code>-i, --interactive</code></td>
<td> <td>
Launch an interactive CoffeeScript session. Launch an interactive CoffeeScript session.
Requires <a href="http://narwhaljs.org/">Narwhal</a>. Requires <a href="http://nodejs.org/">Node.js</a>.
</td> </td>
</tr> </tr>
<tr> <tr>
<td><code>-r, --run</code></td> <td><code>-r, --run</code></td>
<td> <td>
Compile and execute scripts without saving the intermediate Compile and execute scripts without saving the intermediate
JavaScript. Requires <a href="http://narwhaljs.org/">Narwhal</a>. JavaScript. Requires <a href="http://nodejs.org/">Node.js</a>.
</td> </td>
</tr> </tr>
<tr> <tr>
@@ -291,7 +291,7 @@ gem install coffee-script</pre>
<td><code>-n, --no-wrap</code></td> <td><code>-n, --no-wrap</code></td>
<td> <td>
Compile the JavaScript without the top-level function safety wrapper. Compile the JavaScript without the top-level function safety wrapper.
(Used for CoffeeScript as a Narwhal module.) (Used for CoffeeScript as a Node.js module.)
</td> </td>
</tr> </tr>
<tr> <tr>

View File

@@ -17,4 +17,17 @@
coffee.write(code); coffee.write(code);
return coffee.close(); return coffee.close();
}; };
exports.compile_files = function compile_files(paths, callback) {
var coffee, js;
js = '';
coffee = process.createChildProcess('coffee', ['--print'].concat(paths));
coffee.addListener('output', function(results) {
if ((typeof results !== "undefined" && results !== null)) {
return js += results;
}
});
return coffee.addListener('exit', function() {
return callback(js);
});
};
})(); })();

View File

@@ -28,9 +28,6 @@ Usage:
# Path to the root of the CoffeeScript install. # Path to the root of the CoffeeScript install.
ROOT = File.expand_path(File.dirname(__FILE__) + '/../..') ROOT = File.expand_path(File.dirname(__FILE__) + '/../..')
# Command to execute in Narwhal
LAUNCHER = "narwhal -p #{ROOT} -e 'require(\"coffee-script\").run(system.args);'"
# Run the CommandLine off the contents of ARGV. # Run the CommandLine off the contents of ARGV.
def initialize def initialize
@mtimes = {} @mtimes = {}
@@ -114,7 +111,7 @@ Usage:
puts js puts js
end end
# Use Narwhal to run an interactive CoffeeScript session. # Use Node.js to run an interactive CoffeeScript session.
def launch_repl def launch_repl
exec "node #{ROOT}/lib/coffee_script/repl.js" exec "node #{ROOT}/lib/coffee_script/repl.js"
rescue Errno::ENOENT rescue Errno::ENOENT
@@ -122,12 +119,12 @@ Usage:
exit(1) exit(1)
end end
# Use Narwhal to compile and execute CoffeeScripts. # Use Node.js to compile and execute CoffeeScripts.
def run_scripts def run_scripts
sources = @sources.join(' ') sources = @sources.join(' ')
exec "#{LAUNCHER} #{sources}" exec "node #{ROOT}/lib/coffee_script/runner.js #{sources}"
rescue Errno::ENOENT rescue Errno::ENOENT
puts "Error: Narwhal must be installed in order to execute CoffeeScripts." puts "Error: Node.js must be installed in order to execute scripts."
exit(1) exit(1)
end end
@@ -168,10 +165,10 @@ Usage:
def parse_options def parse_options
@options = {} @options = {}
@option_parser = OptionParser.new do |opts| @option_parser = OptionParser.new do |opts|
opts.on('-i', '--interactive', 'run a CoffeeScript REPL (requires Narwhal)') do |i| opts.on('-i', '--interactive', 'run a CoffeeScript REPL (requires Node.js)') do |i|
@options[:interactive] = true @options[:interactive] = true
end end
opts.on('-r', '--run', 'compile and run a script (requires Narwhal)') do |r| opts.on('-r', '--run', 'compile and run a script (requires Node.js)') do |r|
@options[:run] = true @options[:run] = true
end end
opts.on('-o', '--output [DIR]', 'set the directory for compiled JavaScript') do |d| opts.on('-o', '--output [DIR]', 'set the directory for compiled JavaScript') do |d|

View File

@@ -1,62 +0,0 @@
# This (javascript) file is generated from lib/coffee_script/narwhal/coffee-script.coffee
# Executes the `coffee` Ruby program to convert from CoffeeScript
# to Javascript. Eventually this will hopefully happen entirely within JS.
# Require external dependencies.
OS: require('os')
File: require('file')
Readline: require('readline')
# The path to the CoffeeScript Compiler.
coffeePath: File.path(module.path).dirname().dirname().dirname().dirname().dirname().join('bin', 'coffee')
# Our general-purpose error handler.
checkForErrors: (coffeeProcess) ->
return true if coffeeProcess.wait() is 0
system.stderr.print(coffeeProcess.stderr.read())
throw new Error("CoffeeScript compile error")
# Run a simple REPL, round-tripping to the CoffeeScript compiler for every
# command.
exports.run: (args) ->
if args.length
for path, i in args
exports.evalCS(File.read(path))
delete args[i]
return true
while true
try
system.stdout.write('coffee> ').flush()
result: exports.evalCS(Readline.readline(), ['--globals'])
print(result) if result isnt undefined
catch e
print(e)
# Compile a given CoffeeScript file into JavaScript.
exports.compileFile: (path) ->
coffee: OS.popen([coffeePath, "--print", "--no-wrap", path])
checkForErrors(coffee)
coffee.stdout.read()
# Compile a string of CoffeeScript into JavaScript.
exports.compile: (source, flags) ->
coffee: OS.popen([coffeePath, "--eval", "--no-wrap"].concat(flags or []))
coffee.stdin.write(source).flush().close()
checkForErrors(coffee)
coffee.stdout.read()
# Evaluating a string of CoffeeScript first compiles it externally.
exports.evalCS: (source, flags) ->
eval(exports.compile(source, flags))
# Make a factory for the CoffeeScript environment.
exports.makeNarwhalFactory: (path) ->
code: exports.compileFile(path)
factoryText: "function(require,exports,module,system,print){" + code + "/**/\n}"
if system.engine is "rhino"
Packages.org.mozilla.javascript.Context.getCurrentContext().compileFunction(global, factoryText, path, 0, null)
else
# eval requires parentheses, but parentheses break compileFunction.
eval("(" + factoryText + ")")

View File

@@ -1,80 +0,0 @@
(function(){
var File, OS, Readline, checkForErrors, coffeePath;
// This (javascript) file is generated from lib/coffee_script/narwhal/coffee-script.coffee
// Executes the `coffee` Ruby program to convert from CoffeeScript
// to Javascript. Eventually this will hopefully happen entirely within JS.
// Require external dependencies.
OS = require('os');
File = require('file');
Readline = require('readline');
// The path to the CoffeeScript Compiler.
coffeePath = File.path(module.path).dirname().dirname().dirname().dirname().dirname().join('bin', 'coffee');
// Our general-purpose error handler.
checkForErrors = function checkForErrors(coffeeProcess) {
if (coffeeProcess.wait() === 0) {
return true;
}
system.stderr.print(coffeeProcess.stderr.read());
throw new Error("CoffeeScript compile error");
};
// Run a simple REPL, round-tripping to the CoffeeScript compiler for every
// command.
exports.run = function run(args) {
var __a, __b, i, path, result;
if (args.length) {
__a = args;
for (i = 0; i < __a.length; i++) {
path = __a[i];
exports.evalCS(File.read(path));
delete args[i];
}
return true;
}
__b = [];
while (true) {
__b.push((function() {
try {
system.stdout.write('coffee> ').flush();
result = exports.evalCS(Readline.readline(), ['--globals']);
if (result !== undefined) {
return print(result);
}
} catch (e) {
return print(e);
}
}).call(this));
}
return __b;
};
// Compile a given CoffeeScript file into JavaScript.
exports.compileFile = function compileFile(path) {
var coffee;
coffee = OS.popen([coffeePath, "--print", "--no-wrap", path]);
checkForErrors(coffee);
return coffee.stdout.read();
};
// Compile a string of CoffeeScript into JavaScript.
exports.compile = function compile(source, flags) {
var coffee;
coffee = OS.popen([coffeePath, "--eval", "--no-wrap"].concat(flags || []));
coffee.stdin.write(source).flush().close();
checkForErrors(coffee);
return coffee.stdout.read();
};
// Evaluating a string of CoffeeScript first compiles it externally.
exports.evalCS = function evalCS(source, flags) {
return eval(exports.compile(source, flags));
};
// Make a factory for the CoffeeScript environment.
exports.makeNarwhalFactory = function makeNarwhalFactory(path) {
var code, factoryText;
code = exports.compileFile(path);
factoryText = "function(require,exports,module,system,print){" + code + "/**/\n}";
if (system.engine === "rhino") {
return Packages.org.mozilla.javascript.Context.getCurrentContext().compileFunction(global, factoryText, path, 0, null);
} else {
// eval requires parentheses, but parentheses break compileFunction.
return eval("(" + factoryText + ")");
}
};
})();

View File

@@ -1,21 +0,0 @@
(function(){
var coffeescript, factories, loader;
// This (javascript) file is generated from lib/coffee_script/narwhal/loader.coffee
coffeescript = null;
factories = {
};
loader = {
// Reload the coffee-script environment from source.
reload: function reload(topId, path) {
coffeescript = coffeescript || require('coffee-script');
return factories[topId] = function() {
return coffeescript.makeNarwhalFactory(path);
};
},
// Ensure that the coffee-script environment is loaded.
load: function load(topId, path) {
return factories[topId] = factories[topId] || this.reload(topId, path);
}
};
require.loader.loaders.unshift([".coffee", loader]);
})();

View File

@@ -1,19 +0,0 @@
# This (javascript) file is generated from lib/coffee_script/narwhal/loader.coffee
coffeescript: null
factories: {}
loader: {
# Reload the coffee-script environment from source.
reload: (topId, path) ->
coffeescript ||= require('coffee-script')
factories[topId]: -> coffeescript.makeNarwhalFactory(path)
# Ensure that the coffee-script environment is loaded.
load: (topId, path) ->
factories[topId] ||= this.reload(topId, path)
}
require.loader.loaders.unshift([".coffee", loader])

View File

@@ -0,0 +1,10 @@
(function(){
var coffee, paths;
coffee = require('./coffee-script');
process.mixin(require('sys'));
paths = process.ARGV;
paths = paths.slice(2, paths.length);
coffee.compile_files(paths, function(js) {
return eval(js);
});
})();

View File

@@ -1,7 +1,7 @@
{ {
"name": "coffee-script", "name": "coffee-script",
"lib": "lib/coffee_script/narwhal/lib", "lib": "lib/coffee_script",
"preload": ["coffee-script/loader"], "preload": ["loader"],
"description": "Unfancy JavaScript", "description": "Unfancy JavaScript",
"keywords": ["javascript", "language"], "keywords": ["javascript", "language"],
"author": "Jeremy Ashkenas", "author": "Jeremy Ashkenas",

View File

@@ -12,4 +12,12 @@ exports.compile: (code, callback) ->
coffee.write(code) coffee.write(code)
coffee.close() coffee.close()
exports.compile_files: (paths, callback) ->
js: ''
coffee: process.createChildProcess 'coffee', ['--print'].concat(paths)
coffee.addListener 'output', (results) ->
js += results if results?
coffee.addListener 'exit', ->
callback(js)

6
src/runner.coffee Normal file
View File

@@ -0,0 +1,6 @@
coffee: require './coffee-script'
process.mixin require 'sys'
paths: process.ARGV
paths: paths[2...paths.length]
coffee.compile_files paths, (js) -> eval(js)

View File

@@ -4,12 +4,12 @@ area: (x, y, x1, y1) ->
x: y: 10 x: y: 10
x1: y1: 20 x1: y1: 20
print area(x, y, x1, y1) is 100 puts area(x, y, x1, y1) is 100
print(area(x, y, puts(area(x, y,
x1, y1) is 100) x1, y1) is 100)
print(area( puts(area(
x x
y y
x1 x1
@@ -19,7 +19,7 @@ print(area(
# Arguments are turned into arrays. # Arguments are turned into arrays.
curried: -> curried: ->
print area.apply(this, arguments.concat(20, 20)) is 100 puts area.apply(this, arguments.concat(20, 20)) is 100
curried 10, 10 curried 10, 10
@@ -29,4 +29,4 @@ func: ->
arguments: 25 arguments: 25
arguments arguments
print func(100) is 25 puts func(100) is 25

View File

@@ -1,15 +1,15 @@
nums: n * n for n in [1, 2, 3] when n % 2 isnt 0 nums: n * n for n in [1, 2, 3] when n % 2 isnt 0
results: n * 2 for n in nums results: n * 2 for n in nums
print results.join(',') is '2,18' puts results.join(',') is '2,18'
obj: {one: 1, two: 2, three: 3} obj: {one: 1, two: 2, three: 3}
names: prop + '!' for prop of obj names: prop + '!' for prop of obj
odds: prop + '!' for prop, value of obj when value % 2 isnt 0 odds: prop + '!' for prop, value of obj when value % 2 isnt 0
print names.join(' ') is "one! two! three!" puts names.join(' ') is "one! two! three!"
print odds.join(' ') is "one! three!" puts odds.join(' ') is "one! three!"
evens: for num in [1, 2, 3, 4, 5, 6] when num % 2 is 0 evens: for num in [1, 2, 3, 4, 5, 6] when num % 2 is 0
@@ -17,12 +17,12 @@ evens: for num in [1, 2, 3, 4, 5, 6] when num % 2 is 0
num -= 2 num -= 2
num * -1 num * -1
print evens.join(', ') is '4, 6, 8' puts evens.join(', ') is '4, 6, 8'
# Make sure that the "in" operator still works. # Make sure that the "in" operator still works.
print 2 in evens puts 2 in evens
# When functions are being defined within the body of a comprehension, make # When functions are being defined within the body of a comprehension, make
@@ -37,6 +37,6 @@ for method in methods
obj[name]: -> obj[name]: ->
"I'm " + name "I'm " + name
print obj.one() is "I'm one" puts obj.one() is "I'm one"
print obj.two() is "I'm two" puts obj.two() is "I'm two"
print obj.three() is "I'm three" puts obj.three() is "I'm three"

View File

@@ -7,7 +7,7 @@ catch error
result2: try nonexistent * missing catch error then true result2: try nonexistent * missing catch error then true
print result is true and result2 is true puts result is true and result2 is true
# Assign to conditional. # Assign to conditional.
@@ -16,8 +16,8 @@ get_x: -> 10
if x: get_x() then 100 if x: get_x() then 100
print x is 10 puts x is 10
x: if get_x() then 100 x: if get_x() then 100
print x is 100 puts x is 100

View File

@@ -1,4 +1,4 @@
results: [1, 2, 3].map (x) -> results: [1, 2, 3].map (x) ->
x * x x * x
print results.join(' ') is '1 4 9' puts results.join(' ') is '1 4 9'

View File

@@ -20,7 +20,7 @@ ThirdChild::func: (string) ->
result: (new ThirdChild()).func 'four' result: (new ThirdChild()).func 'four'
print result is 'zero/one/two/three/four' puts result is 'zero/one/two/three/four'
TopClass: (arg) -> TopClass: (arg) ->
@@ -35,4 +35,4 @@ SubClass: ->
SuperClass extends TopClass SuperClass extends TopClass
SubClass extends SuperClass SubClass extends SuperClass
print((new SubClass()).prop is 'top-super-sub') puts((new SubClass()).prop is 'top-super-sub')

View File

@@ -3,7 +3,7 @@ identity_wrap: (x) ->
result: identity_wrap(identity_wrap(true))()() result: identity_wrap(identity_wrap(true))()()
print result puts result
str: 'god' str: 'god'
@@ -14,7 +14,7 @@ result: str.
reverse(). reverse().
reverse() reverse()
print result.join('') is 'dog' puts result.join('') is 'dog'
result: str result: str
.split('') .split('')
@@ -22,4 +22,4 @@ result: str
.reverse() .reverse()
.reverse() .reverse()
print result.join('') is 'dog' puts result.join('') is 'dog'

View File

@@ -3,26 +3,26 @@ b: -2
[a, b]: [b, a] [a, b]: [b, a]
print a is -2 puts a is -2
print b is -1 puts b is -1
arr: [1, 2, 3] arr: [1, 2, 3]
[a, b, c]: arr [a, b, c]: arr
print a is 1 puts a is 1
print b is 2 puts b is 2
print c is 3 puts c is 3
obj: {x: 10, y: 20, z: 30} obj: {x: 10, y: 20, z: 30}
{x: a, y: b, z: c}: obj {x: a, y: b, z: c}: obj
print a is 10 puts a is 10
print b is 20 puts b is 20
print c is 30 puts c is 30
person: { person: {
@@ -42,8 +42,8 @@ person: {
{name: a, family: {brother: {addresses: [one, {city: b}]}}}: person {name: a, family: {brother: {addresses: [one, {city: b}]}}}: person
print a is "Bob" puts a is "Bob"
print b is "Moquasset NY, 10021" puts b is "Moquasset NY, 10021"
test: { test: {
@@ -59,4 +59,4 @@ test: {
{person: {address: [ignore, addr...]}}: test {person: {address: [ignore, addr...]}}: test
print addr.join(', ') is "Street 101, Apt 101, City 101" puts addr.join(', ') is "Street 101, Apt 101, City 101"

View File

@@ -26,4 +26,4 @@ func: ->
c.single: c.list[1..1][0] c.single: c.list[1..1][0]
print func() is '-' puts func() is '-'

View File

@@ -1,8 +1,8 @@
print(if my_special_variable? then false else true) puts(if my_special_variable? then false else true)
my_special_variable: false my_special_variable: false
print(if my_special_variable? then true else false) puts(if my_special_variable? then true else false)
# Existential assignment. # Existential assignment.
@@ -12,7 +12,7 @@ a: null
a ?= 10 a ?= 10
b ?= 10 b ?= 10
print a is 10 and b is 10 puts a is 10 and b is 10
# The existential operator. # The existential operator.
@@ -20,7 +20,7 @@ print a is 10 and b is 10
z: null z: null
x: z ? "EX" x: z ? "EX"
print z is null and x is "EX" puts z is null and x is "EX"
# Only evaluate once. # Only evaluate once.
@@ -30,7 +30,7 @@ get_next_node: ->
throw "up" if counter throw "up" if counter
counter++ counter++
print(if get_next_node()? then true else false) puts(if get_next_node()? then true else false)
# Existence chains, soaking up undefined properties: # Existence chains, soaking up undefined properties:
@@ -39,17 +39,17 @@ obj: {
prop: "hello" prop: "hello"
} }
print obj?.prop is "hello" puts obj?.prop is "hello"
print obj?.prop?.non?.existent?.property is undefined puts obj?.prop?.non?.existent?.property is undefined
# Soaks and caches method calls as well. # Soaks and caches method calls as well.
arr: ["--", "----"] arr: ["--", "----"]
print arr.pop()?.length is 4 puts arr.pop()?.length is 4
print arr.pop()?.length is 2 puts arr.pop()?.length is 2
print arr.pop()?.length is undefined puts arr.pop()?.length is undefined
print arr[0]?.length is undefined puts arr[0]?.length is undefined
print arr.pop()?.length?.non?.existent()?.property is undefined puts arr.pop()?.length?.non?.existent()?.property is undefined

View File

@@ -9,7 +9,7 @@ findit: (items) ->
for item in items for item in items
return item if item is "bacon" return item if item is "bacon"
print findit(items) is "bacon" puts findit(items) is "bacon"
# When when a closure wrapper is generated for expression conversion, make sure # When when a closure wrapper is generated for expression conversion, make sure
@@ -26,5 +26,5 @@ obj: {
this.num this.num
} }
print obj.num is obj.func() puts obj.num is obj.func()
print obj.num is obj.result puts obj.num is obj.result

View File

@@ -7,10 +7,10 @@ result: if a
if d if d
true true
print result puts result
first: if false then false else second: if false then false else true first: if false then false else second: if false then false else true
print first puts first
print second puts second

View File

@@ -2,11 +2,11 @@ x: 1
y: {} y: {}
y.x: -> 3 y.x: -> 3
print x is 1 puts x is 1
print typeof(y.x) is 'function' puts typeof(y.x) is 'function'
print y.x instanceof Function puts y.x instanceof Function
print y.x() is 3 puts y.x() is 3
print y.x.name is 'x' puts y.x.name is 'x'
# The empty function should not cause a syntax error. # The empty function should not cause a syntax error.
@@ -17,10 +17,10 @@ obj: {
name: "Fred" name: "Fred"
bound: -> bound: ->
(=> print(this.name is "Fred"))() (=> puts(this.name is "Fred"))()
unbound: -> unbound: ->
(-> print(!this.name?))() (-> puts(!this.name?))()
} }
obj.unbound() obj.unbound()
@@ -44,18 +44,18 @@ Math: {
FastAdd: memoize (a, b) -> a + b FastAdd: memoize (a, b) -> a + b
} }
print Math.Add(5, 5) is 10 puts Math.Add(5, 5) is 10
print Math.AnonymousAdd(10, 10) is 20 puts Math.AnonymousAdd(10, 10) is 20
print Math.FastAdd(20, 20) is 40 puts Math.FastAdd(20, 20) is 40
# Parens are optional on simple function calls. # Parens are optional on simple function calls.
print 100 > 1 if 1 > 0 puts 100 > 1 if 1 > 0
print true unless false puts true unless false
print true for i in [1..3] puts true for i in [1..3]
print_func: (f) -> print(f()) puts_func: (f) -> puts(f())
print_func -> true puts_func -> true
# Optional parens can be used in a nested fashion. # Optional parens can be used in a nested fashion.
call: (func) -> func() call: (func) -> func()
@@ -64,7 +64,7 @@ result: call ->
inner: call -> inner: call ->
Math.Add(5, 5) Math.Add(5, 5)
print result is 10 puts result is 10
# And even with strange things like this: # And even with strange things like this:
@@ -72,8 +72,8 @@ print result is 10
funcs: [(x) -> x, (x) -> x * x] funcs: [(x) -> x, (x) -> x * x]
result: funcs[1] 5 result: funcs[1] 5
print result is 25 puts result is 25
result: ("hello".slice) 3 result: ("hello".slice) 3
print result is 'lo' puts result is 'lo'

View File

@@ -18,4 +18,4 @@ switch 'string'
code() code()
# comment # comment
print func() puts func()

View File

@@ -3,7 +3,7 @@ a: """
on two lines on two lines
""" """
print a is "basic heredoc\non two lines" puts a is "basic heredoc\non two lines"
a: ''' a: '''
@@ -12,12 +12,12 @@ a: '''
c c
''' '''
print a is "a\n \"b\nc" puts a is "a\n \"b\nc"
a: '''one-liner''' a: '''one-liner'''
print a is 'one-liner' puts a is 'one-liner'
a: """ a: """
@@ -25,7 +25,7 @@ a: """
here here
""" """
print a is "out\nhere" puts a is "out\nhere"
a: ''' a: '''
@@ -34,7 +34,7 @@ a: '''
c c
''' '''
print a is " a\n b\nc" puts a is " a\n b\nc"
a: ''' a: '''
a a
@@ -43,4 +43,4 @@ a
b c b c
''' '''
print a is "a\n\n\nb c" puts a is "a\n\n\nb c"

View File

@@ -1,10 +1,10 @@
num: 1 + 2 + (a: 3) num: 1 + 2 + (a: 3)
print num is 6 puts num is 6
result: if true result: if true
false false
other: "result" other: "result"
print result is "result" and other is "result" puts result is "result" and other is "result"

View File

@@ -1,37 +1,37 @@
a: [(x) -> x, (x) -> x * x] a: [(x) -> x, (x) -> x * x]
print a.length is 2 puts a.length is 2
regex: /match/i regex: /match/i
words: "I think there is a match in here." words: "I think there is a match in here."
print !!words.match(regex) puts !!words.match(regex)
neg: (3 -4) neg: (3 -4)
print neg is -1 puts neg is -1
func: -> func: ->
return if true return if true
print func() is null puts func() is null
str: "\\" str: "\\"
reg: /\\/ reg: /\\/
print reg(str) and str is '\\' puts reg(str) and str is '\\'
i: 10 i: 10
while i -= 1 while i -= 1
print i is 0 puts i is 0
money$: 'dollars' money$: 'dollars'
print money$ is 'dollars' puts money$ is 'dollars'

View File

@@ -6,6 +6,6 @@ multi_liner:
single_liner: single_liner:
[x, y] for y in [3..5] for x in [3..5] [x, y] for y in [3..5] for x in [3..5]
print multi_liner.length is single_liner.length puts multi_liner.length is single_liner.length
print 5 is multi_liner[2][2][1] puts 5 is multi_liner[2][2][1]
print 5 is single_liner[2][2][1] puts 5 is single_liner[2][2][1]

View File

@@ -3,4 +3,4 @@ six:
2 + 2 +
3 3
print six is 6 puts six is 6

View File

@@ -1,12 +1,12 @@
# CoffeeScript's operations should be chainable, like Python's. # CoffeeScript's operations should be chainable, like Python's.
print 500 > 50 > 5 > -5 puts 500 > 50 > 5 > -5
print true is not false is true is not false puts true is not false is true is not false
print 10 < 20 > 10 puts 10 < 20 > 10
print 50 > 10 > 5 is parseInt('5', 10) puts 50 > 10 > 5 is parseInt('5', 10)
# Make sure that each argument is only evaluated once, even if used # Make sure that each argument is only evaluated once, even if used
@@ -15,4 +15,4 @@ print 50 > 10 > 5 is parseInt('5', 10)
i: 0 i: 0
func: -> i++ func: -> i++
print 1 > func() < 1 puts 1 > func() < 1

View File

@@ -5,16 +5,16 @@ negs: negs[0..2]
result: nums.concat(negs).join(', ') result: nums.concat(negs).join(', ')
print result is '3, 6, 9, -20, -19, -18' puts result is '3, 6, 9, -20, -19, -18'
# Ensure that ranges are safe. This used to infinite loop: # Ensure that ranges are safe. This used to infinite loop:
j = 5 j = 5
result: for j in [j..(j+3)] result: for j in [j..(j+3)]
j j
print result.join(' ') is '5 6 7 8' puts result.join(' ') is '5 6 7 8'
# With range comprehensions, you can loop in steps. # With range comprehensions, you can loop in steps.
results: x for x in [0..25] by 5 results: x for x in [0..25] by 5
print results.join(' ') is '0 5 10 15 20 25' puts results.join(' ') is '0 5 10 15 20 25'

View File

@@ -5,7 +5,7 @@ b: array[2...4]
result: a.concat(b).join(' ') result: a.concat(b).join(' ')
print result is "7 8 9 2 3" puts result is "7 8 9 2 3"
countdown: [10..1].join(' ') countdown: [10..1].join(' ')
print countdown is "10 9 8 7 6 5 4 3 2 1" puts countdown is "10 9 8 7 6 5 4 3 2 1"

View File

@@ -3,7 +3,7 @@ func: (first, second, rest...) ->
result: func 1, 2, 3, 4, 5 result: func 1, 2, 3, 4, 5
print result is "3 4 5" puts result is "3 4 5"
gold: silver: bronze: the_field: null gold: silver: bronze: the_field: null
@@ -29,7 +29,7 @@ contenders: [
medalists "Mighty Mouse", contenders... medalists "Mighty Mouse", contenders...
print gold is "Mighty Mouse" puts gold is "Mighty Mouse"
print silver is "Michael Phelps" puts silver is "Michael Phelps"
print bronze is "Liu Xiang" puts bronze is "Liu Xiang"
print the_field.length is 8 puts the_field.length is 8

View File

@@ -2,4 +2,4 @@ array: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
array[5..10]: [0, 0, 0] array[5..10]: [0, 0, 0]
print array.join(' ') is '0 1 2 3 4 0 0 0' puts array.join(' ') is '0 1 2 3 4 0 0 0'

View File

@@ -14,7 +14,7 @@ result: switch num
when 11 then false when 11 then false
else false else false
print result puts result
func: (num) -> func: (num) ->
switch num switch num
@@ -24,7 +24,7 @@ func: (num) ->
false false
else false else false
print func(2) puts func(2)
print func(6) puts func(6)
print !func(3) puts !func(3)
print !func(8) puts !func(8)

View File

@@ -1,17 +1,17 @@
i: 100 i: 100
while i -= 1 while i -= 1
print i is 0 puts i is 0
i: 5 i: 5
list: while i -= 1 list: while i -= 1
i * 2 i * 2
print list.join(' ') is "8 6 4 2" puts list.join(' ') is "8 6 4 2"
i: 5 i: 5
list: (i * 3 while i -= 1) list: (i * 3 while i -= 1)
print list.join(' ') is "12 9 6 3" puts list.join(' ') is "12 9 6 3"

View File

@@ -3,14 +3,14 @@
result: while sunny? result: while sunny?
go_outside() go_outside()
print(3 + try puts(3 + try
nonexistent.no_way nonexistent.no_way
catch error catch error
print(error) puts(error)
3 3
) )
func: (x) -> func: (x) ->
return throw x return throw x
print(x * x for x in [1..100]) puts(x * x for x in [1..100])