CoffeeScript-in-CoffeeScript is now able to compile subClass extends superClass

This commit is contained in:
Jeremy Ashkenas 2010-02-08 23:16:29 -05:00
parent 210d673ef0
commit 32098e5a13
4 changed files with 58 additions and 16 deletions

View File

@ -1,5 +1,5 @@
(function(){
var CallNode, CommentNode, Expressions, LiteralNode, Node, ReturnNode, TAB, TRAILING_WHITESPACE, ValueNode, any, compact, del, dup, flatten, inherit, merge, statement;
var CallNode, CommentNode, Expressions, ExtendsNode, LiteralNode, Node, ReturnNode, TAB, TRAILING_WHITESPACE, ValueNode, any, compact, del, dup, flatten, inherit, merge, statement;
var __hasProp = Object.prototype.hasOwnProperty;
process.mixin(require('./scope'));
// The abstract base class for all CoffeeScript nodes.
@ -257,17 +257,14 @@
};
// Merge objects.
merge = function merge(src, dest) {
var __a, __b, key, val;
dest[key] = (function() {
__a = []; __b = src;
for (key in __b) {
val = __b[key];
if (__hasProp.call(__b, key)) {
__a.push(val);
}
var __a, key, val;
__a = src;
for (key in __a) {
val = __a[key];
if (__hasProp.call(__a, key)) {
((dest[key] = val));
}
return __a;
}).call(this);
}
return dest;
};
// Do any of the elements in the list pass a truth test?
@ -361,7 +358,7 @@
var __a, __b, __c, __d, i, idt;
idt = (this.indent || '');
__c = 0; __d = (tabs || 0);
for (__b=0, i=__c; (__c <= __d ? i <= __d : i >= __d); (__c <= __d ? i += 1 : i -= 1), __b++) {
for (__b=0, i=__c; (__c <= __d ? i < __d : i > __d); (__c <= __d ? i += 1 : i -= 1), __b++) {
idt += TAB;
}
return idt;
@ -702,4 +699,23 @@
return [call, reference];
}
}));
// Node to extend an object's prototype with an ancestor object.
// After goog.inherits from the Closure Library.
ExtendsNode = (exports.ExtendsNode = inherit(Node, {
constructor: function constructor(child, parent) {
this.child = child;
this.parent = parent;
this.children = [child, parent];
return this;
},
// Hooking one constructor into another's prototype chain.
compile_node: function compile_node(o) {
var child, constructor, parent;
constructor = o.scope.free_variable();
child = this.child.compile(o);
parent = this.parent.compile(o);
return this.idt() + constructor + ' = function(){};\n' + this.idt() + constructor + '.prototype = ' + parent + ".prototype;\n" + this.idt() + child + '.__superClass__ = ' + parent + ".prototype;\n" + this.idt() + child + '.prototype = new ' + constructor + "();\n" + this.idt() + child + '.prototype.constructor = ' + child + ';';
}
}));
statement(ExtendsNode);
})();

View File

@ -47,7 +47,7 @@
};
// Find an available, short, name for a compiler-generated variable.
Scope.prototype.free_variable = function free_variable() {
while (check(this.temp_variable)) {
while (this.check(this.temp_variable)) {
((this.temp_variable = succ(this.temp_variable)));
}
this.variables[this.temp_variable] = 'var';

View File

@ -69,7 +69,7 @@ dup: (input) ->
# Merge objects.
merge: (src, dest) ->
dest[key]: val for key, val of src
(dest[key]: val) for key, val of src
dest
# Do any of the elements in the list pass a truth test?
@ -134,7 +134,7 @@ Node::compile_closure: (o) ->
# Quick short method for the current indentation level, plus tabbing in.
Node::idt: (tabs) ->
idt: (@indent || '')
idt += TAB for i in [0..(tabs or 0)]
idt += TAB for i in [0...(tabs or 0)]
idt
# Does this node, or any of its children, contain a node of a certain kind?
@ -415,6 +415,32 @@ CallNode: exports.CallNode: inherit Node, {
}
# Node to extend an object's prototype with an ancestor object.
# After goog.inherits from the Closure Library.
ExtendsNode: exports.ExtendsNode: inherit Node, {
constructor: (child, parent) ->
@child: child
@parent: parent
@children: [child, parent]
this
# Hooking one constructor into another's prototype chain.
compile_node: (o) ->
constructor: o.scope.free_variable()
child: @child.compile(o)
parent: @parent.compile(o)
@idt() + constructor + ' = function(){};\n' + @idt() +
constructor + '.prototype = ' + parent + ".prototype;\n" + @idt() +
child + '.__superClass__ = ' + parent + ".prototype;\n" + @idt() +
child + '.prototype = new ' + constructor + "();\n" + @idt() +
child + '.prototype.constructor = ' + child + ';'
}
statement ExtendsNode

View File

@ -36,7 +36,7 @@ Scope::reset: (name) ->
# Find an available, short, name for a compiler-generated variable.
Scope::free_variable: ->
(@temp_variable: succ(@temp_variable)) while check @temp_variable
(@temp_variable: succ(@temp_variable)) while @check @temp_variable
@variables[@temp_variable]: 'var'
@temp_variable