Compare commits

...

12 Commits
0.1.1 ... 0.1.2

Author SHA1 Message Date
Jeremy Ashkenas
9dc932e380 bumping to 0.1.2 to get the super()/extends fix out there 2009-12-24 17:05:55 -08:00
Jeremy Ashkenas
a71de4b5b6 got extends back in the language -- use it together with super 2009-12-24 16:49:23 -08:00
Jeremy Ashkenas
ada8dfc6d4 fixing super() calls, thanks to tolmasky 2009-12-24 16:23:23 -08:00
Jeremy Ashkenas
4112595368 removing the special-case std-reading in favor of '--eval' 2009-12-24 15:49:42 -08:00
Jeremy Ashkenas
c281db7730 document that -e can read from stdin 2009-12-24 15:35:58 -08:00
Jeremy Ashkenas
5e6b49ad1e with a working -n --no-wrap option to disable the top-level function safety wrapper 2009-12-24 15:31:00 -08:00
Jeremy Ashkenas
ec1a527575 Merge branch 'master' of git://github.com/tlrobinson/coffee-script 2009-12-24 15:05:56 -08:00
tlrobinson
dc0ab1afca Command line CoffeeScript 2009-12-24 14:42:57 -08:00
tlrobinson
ae72fbfd0d Narwhal support for CoffeeScript 2009-12-24 14:41:35 -08:00
tlrobinson
ad0735f765 Read from stdin if source is "-" 2009-12-24 14:40:39 -08:00
Jeremy Ashkenas
d49c178f1d added and -> &&, or -> || to the docs (they were missing) 2009-12-24 14:37:30 -08:00
Jeremy Ashkenas
8f8ba255b3 docs for 0.1.1 2009-12-24 12:02:28 -08:00
22 changed files with 1353 additions and 1032 deletions

3
bin/cs Executable file
View File

@@ -0,0 +1,3 @@
#!/usr/bin/env narwhal
require("coffee-script").run(system.args);

View File

@@ -1,6 +1,6 @@
Gem::Specification.new do |s|
s.name = 'coffee-script'
s.version = '0.1.1' # Keep version in sync with coffee-script.rb
s.version = '0.1.2' # Keep version in sync with coffee-script.rb
s.date = '2009-12-24'
s.homepage = "http://jashkenas.github.com/coffee-script/"

View File

@@ -3,13 +3,13 @@ Animal.prototype.move: meters =>
alert(this.name + " moved " + meters + "m.").
Snake: name => this.name: name.
Snake.prototype: new Animal()
Snake extends new Animal()
Snake.prototype.move: =>
alert("Slithering...")
super(5).
Horse: name => this.name: name.
Horse.prototype: new Animal()
Horse extends new Animal()
Horse.prototype.move: =>
alert("Galloping...")
super(45).

View File

@@ -67,7 +67,7 @@
<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="#super">Calling Super from a Subclass</a><br />
<a href="#inheritance">Inheritance, and Calling Super from a Subclass</a><br />
<a href="#embedded">Embedded JavaScript</a><br />
<a href="#switch">Switch/When/Else</a><br />
<a href="#try">Try/Catch/Finally</a><br />
@@ -283,6 +283,10 @@ coffee-script --print app/scripts/*.cs > concatenation.js</pre>
<p>
You can use <tt>not</tt> as an alias for <tt>!</tt>.
</p>
<p>
For logic, <tt>and</tt> compiles to <tt>&amp;&amp;</tt>, and <tt>or</tt>
into <tt>||</tt>.
</p>
<p>
Instead of a newline or semicolon, <tt>then</tt> can be used to separate
conditions from expressions, in <b>while</b>,
@@ -328,8 +332,8 @@ coffee-script --print app/scripts/*.cs > concatenation.js</pre>
</p>
<%= code_for('slices', 'three_to_six') %>
<p id="super">
<b class="header">Calling Super from a Subclass</b>
<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 that provide a cleaner
syntax for classical inheritance on top of JavaScript's prototypes:
@@ -337,9 +341,11 @@ coffee-script --print app/scripts/*.cs > concatenation.js</pre>
<a href="http://prototypejs.org/">Prototype.js</a>,
<a href="http://jsclass.jcoglan.com/">JS.Class</a>, etc.
The libraries provide syntactic sugar, but the built-in inheritance would
be completely usable if it weren't for one small exception:
it's very awkward to call <b>super</b>, the prototype object's
implementation of the current function. CoffeeScript converts
be completely usable if it weren't for a couple of small exceptions:
it's awkward to call <b>super</b> (the prototype object's
implementation of the current function), and it's awkward to correctly
set the prototype chain. CoffeeScript provides <tt>extends</tt>
to help with prototype setup, and converts
<tt>super()</tt> calls into calls against the immediate ancestor's
method of the same name.
</p>
@@ -415,7 +421,24 @@ coffee-script --print app/scripts/*.cs > concatenation.js</pre>
<h2 id="change_log">Change Log</h2>
<p>
<b class="header" style="margin-top: 25px;">0.1.0</b>
<b class="header" style="margin-top: 20px;">0.1.2</b>
Fixed a bug with calling <tt>super()</tt> through more than one level of
inheritance, with the re-addition of the <tt>extends</tt> keyword.
Added experimental <a href="http://narwhaljs.org/">Narwhal</a>
support (as a Tusk package), contributed by
<a href="http://tlrobinson.net/">Tom Robinson</a>, including
<b>bin/cs</b> as a CoffeeScript REPL and interpreter.
New <tt>--no-wrap</tt> option to suppress the safety function
wrapper.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.1.1</b>
Added <tt>instanceof</tt> and <tt>typeof</tt> as operators.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.1.0</b>
Initial CoffeeScript release.
</p>

View File

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

View File

@@ -145,13 +145,13 @@ Animal.prototype.move: meters =>
alert(this.name + " moved " + meters + "m.").
Snake: name => this.name: name.
Snake.prototype: Animal
Snake extends new Animal()
Snake.prototype.move: =>
alert('Slithering...')
super(5).
Horse: name => this.name: name.
Horse.prototype: Animal
Horse extends new Animal()
Horse.prototype.move: =>
alert('Galloping...')
super(45).

View File

@@ -53,7 +53,7 @@
<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="#super">Calling Super from a Subclass</a><br />
<a href="#inheritance">Inheritance, and Calling Super from a Subclass</a><br />
<a href="#embedded">Embedded JavaScript</a><br />
<a href="#switch">Switch/When/Else</a><br />
<a href="#try">Try/Catch/Finally</a><br />
@@ -458,6 +458,10 @@ var eldest = 24 > 21 ? "Liz" : "Ike";
<p>
You can use <tt>not</tt> as an alias for <tt>!</tt>.
</p>
<p>
For logic, <tt>and</tt> compiles to <tt>&amp;&amp;</tt>, and <tt>or</tt>
into <tt>||</tt>.
</p>
<p>
Instead of a newline or semicolon, <tt>then</tt> can be used to separate
conditions from expressions, in <b>while</b>,
@@ -561,8 +565,8 @@ three_to_six<span class="Keyword">:</span> nums[<span class="Number">3</span>, <
var three_to_six = nums.slice(3, 6 + 1);
;alert(three_to_six);'>run: three_to_six</button><br class='clear' /></div>
<p id="super">
<b class="header">Calling Super from a Subclass</b>
<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 that provide a cleaner
syntax for classical inheritance on top of JavaScript's prototypes:
@@ -570,9 +574,11 @@ var three_to_six = nums.slice(3, 6 + 1);
<a href="http://prototypejs.org/">Prototype.js</a>,
<a href="http://jsclass.jcoglan.com/">JS.Class</a>, etc.
The libraries provide syntactic sugar, but the built-in inheritance would
be completely usable if it weren't for one small exception:
it's very awkward to call <b>super</b>, the prototype object's
implementation of the current function. CoffeeScript converts
be completely usable if it weren't for a couple of small exceptions:
it's awkward to call <b>super</b> (the prototype object's
implementation of the current function), and it's awkward to correctly
set the prototype chain. CoffeeScript provides <tt>extends</tt>
to help with prototype setup, and converts
<tt>super()</tt> calls into calls against the immediate ancestor's
method of the same name.
</p>
@@ -581,13 +587,13 @@ var three_to_six = nums.slice(3, 6 + 1);
alert(<span class="Variable">this</span>.name <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span> moved <span class="String">&quot;</span></span> <span class="Keyword">+</span> meters <span class="Keyword">+</span> <span class="String"><span class="String">&quot;</span>m.<span class="String">&quot;</span></span>).
<span class="FunctionName">Snake</span><span class="Keyword">:</span> <span class="FunctionArgument">name</span> <span class="Storage">=&gt;</span> <span class="Variable">this</span>.name<span class="Keyword">:</span> name.
Snake.prototype<span class="Keyword">:</span> <span class="Keyword">new</span> <span class="TypeName">Animal</span>()
Snake <span class="Variable">extends</span> <span class="Keyword">new</span> <span class="TypeName">Animal</span>()
<span class="FunctionName">Snake.prototype.move</span><span class="Keyword">:</span> <span class="Storage">=&gt;</span>
alert(<span class="String"><span class="String">&quot;</span>Slithering...<span class="String">&quot;</span></span>)
<span class="Variable">super</span>(<span class="Number">5</span>).
<span class="FunctionName">Horse</span><span class="Keyword">:</span> <span class="FunctionArgument">name</span> <span class="Storage">=&gt;</span> <span class="Variable">this</span>.name<span class="Keyword">:</span> name.
Horse.prototype<span class="Keyword">:</span> <span class="Keyword">new</span> <span class="TypeName">Animal</span>()
Horse <span class="Variable">extends</span> <span class="Keyword">new</span> <span class="TypeName">Animal</span>()
<span class="FunctionName">Horse.prototype.move</span><span class="Keyword">:</span> <span class="Storage">=&gt;</span>
alert(<span class="String"><span class="String">&quot;</span>Galloping...<span class="String">&quot;</span></span>)
<span class="Variable">super</span>(<span class="Number">45</span>).
@@ -610,19 +616,19 @@ tom.move()
<span class="Variable">this</span>.<span class="LibraryConstant">name</span> <span class="Keyword">=</span> name;
<span class="Keyword">return</span> <span class="Variable">this</span>.<span class="LibraryConstant">name</span>;
};
<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">__proto__</span> = <span class="Keyword">new</span> <span class="TypeName">Animal</span>();
<span class="LibraryClassType">Snake</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">move</span> = <span class="Storage">function</span>() {
<span class="LibraryFunction">alert</span>(<span class="String"><span class="String">&quot;</span>Slithering...<span class="String">&quot;</span></span>);
<span class="Keyword">return</span> <span class="Variable">this</span>.<span class="LibraryConstant">constructor</span>.<span class="LibraryConstant">prototype</span>.move.<span class="LibraryFunction">call</span>(<span class="Variable">this</span>, <span class="Number">5</span>);
<span class="Keyword">return</span> Snake.<span class="LibraryConstant">prototype</span>.__proto__.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="Keyword">return</span> <span class="Variable">this</span>.<span class="LibraryConstant">name</span>;
};
<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">__proto__</span> = <span class="Keyword">new</span> <span class="TypeName">Animal</span>();
<span class="LibraryClassType">Horse</span>.<span class="LibraryConstant">prototype</span>.<span class="FunctionName">move</span> = <span class="Storage">function</span>() {
<span class="LibraryFunction">alert</span>(<span class="String"><span class="String">&quot;</span>Galloping...<span class="String">&quot;</span></span>);
<span class="Keyword">return</span> <span class="Variable">this</span>.<span class="LibraryConstant">constructor</span>.<span class="LibraryConstant">prototype</span>.move.<span class="LibraryFunction">call</span>(<span class="Variable">this</span>, <span class="Number">45</span>);
<span class="Keyword">return</span> Horse.<span class="LibraryConstant">prototype</span>.__proto__.move.<span class="LibraryFunction">call</span>(<span class="Variable">this</span>, <span class="Number">45</span>);
};
<span class="Storage">var</span> sam <span class="Keyword">=</span> <span class="Keyword">new</span> <span class="TypeName">Snake</span>(<span class="String"><span class="String">&quot;</span>Sammy the Python<span class="String">&quot;</span></span>);
<span class="Storage">var</span> tom <span class="Keyword">=</span> <span class="Keyword">new</span> <span class="TypeName">Horse</span>(<span class="String"><span class="String">&quot;</span>Tommy the Palomino<span class="String">&quot;</span></span>);
@@ -637,19 +643,19 @@ var Snake = function(name) {
this.name = name;
return this.name;
};
Snake.prototype = new Animal();
Snake.prototype.__proto__ = new Animal();
Snake.prototype.move = function() {
alert("Slithering...");
return this.constructor.prototype.move.call(this, 5);
return Snake.prototype.__proto__.move.call(this, 5);
};
var Horse = function(name) {
this.name = name;
return this.name;
};
Horse.prototype = new Animal();
Horse.prototype.__proto__ = new Animal();
Horse.prototype.move = function() {
alert("Galloping...");
return this.constructor.prototype.move.call(this, 45);
return Horse.prototype.__proto__.move.call(this, 45);
};
var sam = new Snake("Sammy the Python");
var tom = new Horse("Tommy the Palomino");
@@ -794,7 +800,24 @@ world...";
<h2 id="change_log">Change Log</h2>
<p>
<b class="header" style="margin-top: 25px;">0.1.0</b>
<b class="header" style="margin-top: 20px;">0.1.2</b>
Fixed a bug with calling <tt>super()</tt> through more than one level of
inheritance, with the re-addition of the <tt>extends</tt> keyword.
Added experimental <a href="http://narwhaljs.org/">Narwhal</a>
support (as a Tusk package), contributed by
<a href="http://tlrobinson.net/">Tom Robinson</a>, including
<b>bin/cs</b> as a CoffeeScript REPL and interpreter.
New <tt>--no-wrap</tt> option to suppress the safety function
wrapper.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.1.1</b>
Added <tt>instanceof</tt> and <tt>typeof</tt> as operators.
</p>
<p>
<b class="header" style="margin-top: 20px;">0.1.0</b>
Initial CoffeeScript release.
</p>

91
lib-js/coffee-script.js Normal file
View File

@@ -0,0 +1,91 @@
var FILE = require("file");
var OS = require("os");
exports.run = function(args) {
// TODO: non-REPL
args.shift();
if (args.length) {
require(FILE.absolute(args[0]));
return;
}
while (true)
{
try {
system.stdout.write("cs> ").flush();
var result = exports.cs_eval(require("readline").readline());
if (result !== undefined)
print(result);
} catch (e) {
print(e);
}
}
}
// executes the coffee-script Ruby program to convert from CoffeeScript to Objective-J.
// eventually this will hopefully be replaced by a JavaScript program.
var coffeePath = FILE.path(module.path).dirname().dirname().join("bin", "coffee-script");
exports.compileFile = function(path) {
var coffee = OS.popen([coffeePath, "--print", path]);
if (coffee.wait() !== 0)
throw new Error("coffee compiler error");
return coffee.stdout.read();
}
exports.compile = function(source) {
var coffee = OS.popen([coffeePath, "-e"]);
coffee.stdin.write(source).flush().close();
if (coffee.wait() !== 0)
throw new Error("coffee compiler error");
return coffee.stdout.read();
}
// these two functions are equivalent to objective-j's objj_eval/make_narwhal_factory.
// implemented as a call to coffee and objj_eval/make_narwhal_factory
exports.cs_eval = function(source) {
init();
var code = exports.compile(source);
// strip the function wrapper, we add our own.
// TODO: this is very fragile
code = code.split("\n").slice(1,-2).join("\n");
return eval(code);
}
exports.make_narwhal_factory = function(path) {
init();
var code = exports.compileFile(path);
// strip the function wrapper, we add our own.
// TODO: this is very fragile
code = code.split("\n").slice(1,-2).join("\n");
var 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);
// eval requires parenthesis, but parenthesis break compileFunction.
else
return eval("(" + factoryText + ")");
}
var init = function() {
// make sure it's only done once
init = function(){}
}

View File

@@ -0,0 +1,23 @@
var coffeescript = null;
function CoffeeScriptLoader() {
var loader = {};
var factories = {};
loader.reload = function(topId, path) {
if (!coffeescript) coffeescript = require("coffee-script");
//print("loading objective-j: " + topId + " (" + path + ")");
factories[topId] = coffeescript.make_narwhal_factory(path);
}
loader.load = function(topId, path) {
if (!factories.hasOwnProperty(topId))
loader.reload(topId, path);
return factories[topId];
}
return loader;
};
require.loader.loaders.unshift([".cs", CoffeeScriptLoader()]);

View File

@@ -9,12 +9,12 @@ require "coffee_script/parse_error"
# Namespace for all CoffeeScript internal classes.
module CoffeeScript
VERSION = '0.1.1' # Keep in sync with the gemspec.
VERSION = '0.1.2' # Keep in sync with the gemspec.
# Compile a script (String or IO) to JavaScript.
def self.compile(script)
def self.compile(script, options={})
script = script.read if script.respond_to?(:read)
Parser.new.parse(script).compile
Parser.new.parse(script).compile(options)
end
end

View File

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

View File

@@ -108,7 +108,7 @@ Usage:
# Compile a single source file to JavaScript.
def compile(script, source='')
begin
CoffeeScript.compile(script)
CoffeeScript.compile(script, :no_wrap => @options[:no_wrap])
rescue CoffeeScript::ParseError => e
STDERR.puts e.message(source)
exit(1) unless @options[:watch]
@@ -147,7 +147,7 @@ Usage:
opts.on('-l', '--lint', 'pipe the compiled JavaScript through JSLint') do |l|
@options[:lint] = true
end
opts.on('-e', '--eval', 'eval a little scriptlet directly from the cli') do |e|
opts.on('-e', '--eval', 'eval a little scriptlet or read from stdin') do |e|
@options[:eval] = true
end
opts.on('-t', '--tokens', 'print the tokens that the lexer produces') do |t|
@@ -156,6 +156,9 @@ Usage:
opts.on('-v', '--verbose', 'print at every step of code generation') do |v|
ENV['VERBOSE'] = 'true'
end
opts.on('-n', '--no-wrap', 'suppress the top-level safety function wrapper') do |n|
@options[:no_wrap] = true
end
opts.on_tail('--install-bundle', 'install the CoffeeScript TextMate bundle') do |i|
install_bundle
exit

View File

@@ -11,7 +11,7 @@ token BREAK CONTINUE
token FOR IN WHILE
token SWITCH WHEN
token DELETE INSTANCEOF TYPEOF
token SUPER
token SUPER EXTENDS
token NEWLINE
token COMMENT
token JS
@@ -29,8 +29,8 @@ prechigh
right '-=' '+=' '/=' '*='
right DELETE INSTANCEOF TYPEOF
left "."
right THROW FOR IN WHILE NEW
left UNLESS IF ELSE
right THROW FOR IN WHILE NEW SUPER
left UNLESS IF ELSE EXTENDS
left ":" '||:' '&&:'
right RETURN
preclow
@@ -81,6 +81,7 @@ rule
| While
| For
| Switch
| Extends
| Comment
;
@@ -254,6 +255,11 @@ rule
| Super { result = val[0] }
;
# Extending an object's prototype.
Extends:
Value EXTENDS Expression { result = ExtendsNode.new(val[0], val[2]) }
;
# A generic function invocation.
Invocation:
Value "(" ArgList ")" { result = CallNode.new(val[0], val[2]) }

View File

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

View File

@@ -75,16 +75,17 @@ module CoffeeScript
end
# If this is the top-level Expressions, wrap everything in a safety closure.
def root_compile
code = compile(:indent => TAB, :scope => Scope.new)
def root_compile(o={})
indent = o[:no_wrap] ? '' : TAB
code = compile(:indent => indent, :scope => Scope.new)
code.gsub!(STRIP_TRAILING_WHITESPACE, '')
"(function(){\n#{code}\n})();"
o[:no_wrap] ? code : "(function(){\n#{code}\n})();"
end
# The extra fancy is to handle pushing down returns and assignments
# recursively to the final lines of inner statements.
def compile(options={})
return root_compile unless options[:scope]
return root_compile(options) unless options[:scope]
code = @expressions.map { |node|
o = super(options)
if last?(node) && (o[:return] || o[:assign])
@@ -209,10 +210,25 @@ module CoffeeScript
def compile_super(args, o)
methname = o[:last_assign].sub(LEADING_DOT, '')
"this.constructor.prototype.#{methname}.call(this, #{args})"
arg_part = args.empty? ? '' : ", #{args}"
"#{o[:proto_assign]}.prototype.__proto__.#{methname}.call(this#{arg_part})"
end
end
# Node to extend an object's prototype with an ancestor object.
class ExtendsNode < Node
attr_reader :sub_object, :super_object
def initialize(sub_object, super_object)
@sub_object, @super_object = sub_object, super_object
end
def compile(o={})
"#{@sub_object.compile(o)}.prototype.__proto__ = #{@super_object.compile(o)}"
end
end
# A value, indexed or dotted into, or vanilla.
class ValueNode < Node
attr_reader :literal, :properties, :last
@@ -298,7 +314,8 @@ module CoffeeScript
# Setting the value of a local variable, or the value of an object property.
class AssignNode < Node
LEADING_VAR = /\Avar\s+/
LEADING_VAR = /\Avar\s+/
PROTO_ASSIGN = /\A(\S+)\.prototype/
statement
custom_return
@@ -315,9 +332,10 @@ module CoffeeScript
def compile(o={})
o = super(o)
name = @variable.respond_to?(:compile) ? @variable.compile(o) : @variable
name = @variable.respond_to?(:compile) ? @variable.compile(o) : @variable.to_s
last = @variable.respond_to?(:last) ? @variable.last.to_s : name.to_s
o = o.merge(:assign => name, :last_assign => last)
proto = name[PROTO_ASSIGN, 1]
o = o.merge(:assign => name, :last_assign => last, :proto_assign => proto)
postfix = o[:return] ? ";\n#{o[:indent]}return #{name}" : ''
return write("#{@variable}: #{@value.compile(o)}") if @context == :object
return write("#{name} = #{@value.compile(o)}#{postfix}") if @variable.properties? && !@value.custom_assign?

File diff suppressed because it is too large Load Diff

9
package.json Normal file
View File

@@ -0,0 +1,9 @@
{
"name": "coffee-script",
"lib": "lib-js",
"preload": ["coffee-script/loader"],
"description": "Unfancy JavaScript",
"keywords": ["javascript", "language"],
"author": "Jeremy Ashkenas",
"version": "0.1.2"
}

29
test/fixtures/each_no_wrap.js vendored Normal file
View File

@@ -0,0 +1,29 @@
// The cornerstone, an each implementation.
// Handles objects implementing forEach, arrays, and raw objects.
_.each = function(obj, iterator, context) {
var index = 0;
try {
if (obj.forEach) {
obj.forEach(iterator, context);
} else if (_.isArray(obj) || _.isArguments(obj)) {
var a = obj;
for (var b=0, c=a.length; b<c; b++) {
var item = a[b];
var i = b;
iterator.call(context, item, i, obj);
}
} else {
var d = _.keys(obj);
for (var e=0, f=d.length; e<f; e++) {
var key = d[e];
iterator.call(context, obj[key], key, obj);
}
}
} catch (e) {
if (e !== breaker) {
throw e;
}
}
return obj;
};

View File

@@ -0,0 +1,23 @@
Base: => .
Base.prototype.func: string =>
'zero/' + string.
FirstChild: => .
FirstChild extends new Base()
FirstChild.prototype.func: string =>
super('one/') + string.
SecondChild: => .
SecondChild extends new FirstChild()
SecondChild.prototype.func: string =>
super('two/') + string.
ThirdChild: => .
ThirdChild extends new SecondChild()
ThirdChild.prototype.func: string =>
super('three/') + string.
result: (new ThirdChild()).func('four')
print(result is 'zero/one/two/three/four')

View File

@@ -0,0 +1,27 @@
(function(){
var Base = function() {
};
Base.prototype.func = function(string) {
return 'zero/' + string;
};
var FirstChild = function() {
};
FirstChild.prototype.__proto__ = new Base();
FirstChild.prototype.func = function(string) {
return FirstChild.prototype.__proto__.func.call(this, 'one/') + string;
};
var SecondChild = function() {
};
SecondChild.prototype.__proto__ = new FirstChild();
SecondChild.prototype.func = function(string) {
return SecondChild.prototype.__proto__.func.call(this, 'two/') + string;
};
var ThirdChild = function() {
};
ThirdChild.prototype.__proto__ = new SecondChild();
ThirdChild.prototype.func = function(string) {
return ThirdChild.prototype.__proto__.func.call(this, 'three/') + string;
};
var result = (new ThirdChild()).func('four');
print(result === 'zero/one/two/three/four');
})();

View File

@@ -10,8 +10,9 @@ class ExecutionTest < Test::Unit::TestCase
starting_place = File.expand_path(Dir.pwd)
Dir.chdir('/Users/jashkenas/Desktop/Beauty/Code/v8')
sources.each do |source|
# puts `./shell #{source}`
assert `./shell #{source}`.chomp.to_sym == :true
suceeded = `./shell #{source}`.chomp.to_sym == :true
puts "failed: #{source}" unless suceeded
assert suceeded
end
ensure
Dir.chdir(starting_place)

View File

@@ -72,4 +72,9 @@ class ParserTest < Test::Unit::TestCase
assert nodes.compile == File.read('test/fixtures/each.js')
end
def test_no_wrap
nodes = @par.parse(File.read('test/fixtures/each.cs'))
assert nodes.compile(:no_wrap => true) == File.read('test/fixtures/each_no_wrap.js')
end
end