This commit is contained in:
Demian Ferreiro 2013-02-28 10:37:30 -03:00
parent c0e07013e8
commit bf70b4660e
6 changed files with 196 additions and 244 deletions

View File

@ -16,7 +16,6 @@
action = (match = unwrap.exec(action)) ? match[1] : "(" + action + "())";
action = action.replace(/\bnew /g, '$&yy.');
action = action.replace(/\b(?:Block\.wrap|extend)\b/g, 'yy.$&');
action = action.replace(/\b(Op|Value\.(create|wrap))\b/g, 'yy.$&');
addLocationDataFn = function(first, last) {
if (!last) {
return "yy.addLocationDataFn(@" + first + ")";
@ -94,12 +93,12 @@
],
AssignObj: [
o('ObjAssignable', function() {
return Value.wrap($1);
return new Value($1);
}), o('ObjAssignable : Expression', function() {
return new Assign(LOC(1)(Value.wrap($1)), $3, 'object');
return new Assign(LOC(1)(new Value($1)), $3, 'object');
}), o('ObjAssignable :\
INDENT Expression OUTDENT', function() {
return new Assign(LOC(1)(Value.wrap($1)), $4, 'object');
return new Assign(LOC(1)(new Value($1)), $4, 'object');
}), o('Comment')
],
ObjAssignable: [o('Identifier'), o('AlphaNumeric'), o('ThisProperty')],
@ -160,27 +159,27 @@
],
SimpleAssignable: [
o('Identifier', function() {
return Value.wrap($1);
return new Value($1);
}), o('Value Accessor', function() {
return $1.add($2);
}), o('Invocation Accessor', function() {
return Value.wrap($1, [].concat($2));
return new Value($1, [].concat($2));
}), o('ThisProperty')
],
Assignable: [
o('SimpleAssignable'), o('Array', function() {
return Value.wrap($1);
return new Value($1);
}), o('Object', function() {
return Value.wrap($1);
return new Value($1);
})
],
Value: [
o('Assignable'), o('Literal', function() {
return Value.wrap($1);
return new Value($1);
}), o('Parenthetical', function() {
return Value.wrap($1);
return new Value($1);
}), o('Range', function() {
return Value.wrap($1);
return new Value($1);
}), o('This')
],
Accessor: [
@ -274,14 +273,14 @@
],
This: [
o('THIS', function() {
return Value.wrap(new Literal('this'));
return new Value(new Literal('this'));
}), o('@', function() {
return Value.wrap(new Literal('this'));
return new Value(new Literal('this'));
})
],
ThisProperty: [
o('@ Identifier', function() {
return Value.wrap(LOC(1)(new Literal('this')), [LOC(2)(new Access($2))], 'this');
return new Value(LOC(1)(new Literal('this')), [LOC(2)(new Access($2))], 'this');
})
],
Array: [
@ -348,7 +347,7 @@
o('CATCH Identifier Block', function() {
return [$2, $3];
}), o('CATCH Object Block', function() {
return [LOC(2)(Value.wrap($2)), $3];
return [LOC(2)(new Value($2)), $3];
})
],
Throw: [
@ -411,7 +410,7 @@
ForBody: [
o('FOR Range', function() {
return {
source: LOC(2)(Value.wrap($2))
source: LOC(2)(new Value($2))
};
}), o('ForStart ForSource', function() {
$2.own = $1.own;
@ -430,9 +429,9 @@
],
ForValue: [
o('Identifier'), o('ThisProperty'), o('Array', function() {
return Value.wrap($1);
return new Value($1);
}), o('Object', function() {
return Value.wrap($1);
return new Value($1);
})
],
ForVariables: [
@ -533,42 +532,42 @@
],
Operation: [
o('UNARY Expression', function() {
return Op.create($1, $2);
return new Op($1, $2);
}), o('- Expression', (function() {
return Op.create('-', $2);
return new Op('-', $2);
}), {
prec: 'UNARY'
}), o('+ Expression', (function() {
return Op.create('+', $2);
return new Op('+', $2);
}), {
prec: 'UNARY'
}), o('-- SimpleAssignable', function() {
return Op.create('--', $2);
return new Op('--', $2);
}), o('++ SimpleAssignable', function() {
return Op.create('++', $2);
return new Op('++', $2);
}), o('SimpleAssignable --', function() {
return Op.create('--', $1, null, true);
return new Op('--', $1, null, true);
}), o('SimpleAssignable ++', function() {
return Op.create('++', $1, null, true);
return new Op('++', $1, null, true);
}), o('Expression ?', function() {
return new Existence($1);
}), o('Expression + Expression', function() {
return Op.create('+', $1, $3);
return new Op('+', $1, $3);
}), o('Expression - Expression', function() {
return Op.create('-', $1, $3);
return new Op('-', $1, $3);
}), o('Expression MATH Expression', function() {
return Op.create($2, $1, $3);
return new Op($2, $1, $3);
}), o('Expression SHIFT Expression', function() {
return Op.create($2, $1, $3);
return new Op($2, $1, $3);
}), o('Expression COMPARE Expression', function() {
return Op.create($2, $1, $3);
return new Op($2, $1, $3);
}), o('Expression LOGIC Expression', function() {
return Op.create($2, $1, $3);
return new Op($2, $1, $3);
}), o('Expression RELATION Expression', function() {
if ($2.charAt(0) === '!') {
return Op.create($2.slice(1), $1, $3).invert();
return new Op($2.slice(1), $1, $3).invert();
} else {
return Op.create($2, $1, $3);
return new Op($2, $1, $3);
}
}), o('SimpleAssignable COMPOUND_ASSIGN\
Expression', function() {

View File

@ -164,7 +164,7 @@
};
Base.prototype.invert = function() {
return Op.create('!', this);
return new Op('!', this);
};
Base.prototype.unwrapAll = function() {
@ -488,7 +488,7 @@
__extends(Undefined, _super);
function Undefined() {
Undefined.__super__.constructor.apply(this, arguments);
return Undefined.__super__.constructor.apply(this, arguments);
}
Undefined.prototype.isAssignable = NO;
@ -512,7 +512,7 @@
__extends(Null, _super);
function Null() {
Null.__super__.constructor.apply(this, arguments);
return Null.__super__.constructor.apply(this, arguments);
}
Null.prototype.isAssignable = NO;
@ -587,21 +587,16 @@
__extends(Value, _super);
Value.wrap = function(base, props, tag) {
function Value(base, props, tag) {
if (!props && base instanceof Value) {
return base;
} else {
return new Value(base, props, tag);
}
};
function Value(base, properties, tag) {
this.base = base;
this.properties = properties;
this.properties || (this.properties = []);
if (tag === 'this') {
this["this"] = true;
this.properties = props || [];
if (tag) {
this[tag] = true;
}
return this;
}
Value.prototype.children = ['base', 'properties'];
@ -684,10 +679,10 @@
if (this.properties.length < 2 && !this.base.isComplex() && !(name != null ? name.isComplex() : void 0)) {
return [this, this];
}
base = Value.wrap(this.base, this.properties.slice(0, -1));
base = new Value(this.base, this.properties.slice(0, -1));
if (base.isComplex()) {
bref = new Literal(o.scope.freeVariable('base'));
base = Value.wrap(new Parens(new Assign(bref, base)));
base = new Value(new Parens(new Assign(bref, base)));
}
if (!name) {
return [base, bref];
@ -697,7 +692,7 @@
name = new Index(new Assign(nref, name.index));
nref = new Index(nref);
}
return [base.add(name), Value.wrap(bref || base.base, [nref || name])];
return [base.add(name), new Value(bref || base.base, [nref || name])];
};
Value.prototype.compileNode = function(o) {
@ -731,8 +726,8 @@
continue;
}
prop.soak = false;
fst = Value.wrap(_this.base, _this.properties.slice(0, i));
snd = Value.wrap(_this.base, _this.properties.slice(i));
fst = new Value(_this.base, _this.properties.slice(0, i));
snd = new Value(_this.base, _this.properties.slice(i));
if (fst.isComplex()) {
ref = new Literal(o.scope.freeVariable('ref'));
fst = new Parens(new Assign(ref, fst));
@ -816,7 +811,7 @@
accesses.push(new Access(new Literal('constructor')));
}
accesses.push(new Access(new Literal(name)));
return (Value.wrap(new Literal(method.klass), accesses)).compile(o);
return (new Value(new Literal(method.klass), accesses)).compile(o);
} else {
return "" + name + ".__super__.constructor";
}
@ -835,15 +830,15 @@
if (ifn = unfoldSoak(o, this, 'variable')) {
return ifn;
}
_ref2 = Value.wrap(this.variable).cacheReference(o), left = _ref2[0], rite = _ref2[1];
_ref2 = new Value(this.variable).cacheReference(o), left = _ref2[0], rite = _ref2[1];
} else {
left = new Literal(this.superReference(o));
rite = Value.wrap(left);
rite = new Value(left);
}
rite = new Call(rite, this.args);
rite.isNew = this.isNew;
left = new Literal("typeof " + (left.compile(o)) + " === \"function\"");
return new If(left, Value.wrap(rite), {
return new If(left, new Value(rite), {
soak: true
});
}
@ -912,7 +907,7 @@
idt = this.tab + TAB;
return "(function(func, args, ctor) {\n" + idt + "ctor.prototype = func.prototype;\n" + idt + "var child = new ctor, result = func.apply(child, args);\n" + idt + "return Object(result) === result ? result : child;\n" + this.tab + "})(" + (this.variable.compile(o, LEVEL_LIST)) + ", " + splatArgs + ", function(){})";
}
base = Value.wrap(this.variable);
base = new Value(this.variable);
if ((name = base.properties.pop()) && base.isComplex()) {
ref = o.scope.freeVariable('ref');
fun = "(" + ref + " = " + (base.compile(o, LEVEL_LIST)) + ")" + (name.compile(o));
@ -947,7 +942,7 @@
Extends.prototype.children = ['child', 'parent'];
Extends.prototype.compile = function(o) {
return new Call(Value.wrap(new Literal(utility('extends'))), [this.child, this.parent]).compile(o);
return new Call(new Value(new Literal(utility('extends'))), [this.child, this.parent]).compile(o);
};
return Extends;
@ -1302,7 +1297,7 @@
_ref2 = this.boundFuncs;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
bvar = _ref2[_i];
lhs = (Value.wrap(new Literal("this"), [new Access(bvar)])).compile(o);
lhs = (new Value(new Literal("this"), [new Access(bvar)])).compile(o);
this.ctor.body.unshift(new Literal("" + lhs + " = " + (utility('bind')) + "(" + lhs + ", this)"));
}
};
@ -1338,7 +1333,7 @@
func.context = name;
}
} else {
assign.variable = Value.wrap(new Literal(name), [new Access(new Literal('prototype')), new Access(base)]);
assign.variable = new Value(new Literal(name), [new Access(new Literal('prototype')), new Access(base)]);
if (func instanceof Code && func.bound) {
this.boundFuncs.push(base);
func.bound = false;
@ -1383,8 +1378,7 @@
return this.directives = expressions.splice(0, index);
};
Class.prototype.ensureConstructor = function(name, o) {
var returnExpr;
Class.prototype.ensureConstructor = function(name) {
if (!this.ctor) {
this.ctor = new Code;
if (this.parent) {
@ -1393,20 +1387,12 @@
if (this.externalCtor) {
this.ctor.body.push(new Literal("" + this.externalCtor + ".apply(this, arguments)"));
}
this.ctor.body.makeReturn();
this.body.expressions.unshift(this.ctor);
}
this.ctor.ctor = this.ctor.name = name;
this.ctor.klass = null;
this.ctor.noReturn = true;
returnExpr = null;
this.ctor.body.traverseChildren(false, function(node) {
if (node instanceof Return && (returnExpr = node.expression)) {
return false;
}
});
if (returnExpr) {
throw SyntaxError("cannot return a value from a constructor: \"" + (returnExpr.compileNode(o)) + "\" in class " + name);
}
return this.ctor.noReturn = true;
};
Class.prototype.compileNode = function(o) {
@ -1420,7 +1406,7 @@
this.hoistDirectivePrologue();
this.setContext(name);
this.walkBody(name, o);
this.ensureConstructor(name, o);
this.ensureConstructor(name);
this.body.spaced = true;
if (!(this.ctor instanceof Code)) {
this.body.expressions.unshift(this.ctor);
@ -1543,7 +1529,7 @@
idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(0);
}
acc = IDENTIFIER.test(idx.unwrap().value || 0);
value = Value.wrap(value);
value = new Value(value);
value.properties.push(new (acc ? Access : Index)(idx));
if (_ref4 = obj.unwrap().value, __indexOf.call(RESERVED, _ref4) >= 0) {
throw new SyntaxError("assignment to a reserved word: " + (obj.compile(o)) + " = " + (value.compile(o)));
@ -1567,7 +1553,7 @@
_ref5 = obj, (_ref6 = _ref5.variable, idx = _ref6.base), obj = _ref5.value;
} else {
if (obj.base instanceof Parens) {
_ref7 = Value.wrap(obj.unwrapAll()).cacheReference(o), obj = _ref7[0], idx = _ref7[1];
_ref7 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref7[0], idx = _ref7[1];
} else {
idx = obj["this"] ? obj.properties[0].name : obj;
}
@ -1597,7 +1583,7 @@
} else {
acc = isObject && IDENTIFIER.test(idx.unwrap().value || 0);
}
val = Value.wrap(new Literal(vvar), [new (acc ? Access : Index)(idx)]);
val = new Value(new Literal(vvar), [new (acc ? Access : Index)(idx)]);
}
if ((name != null) && __indexOf.call(RESERVED, name) >= 0) {
throw new SyntaxError("assignment to a reserved word: " + (obj.compile(o)) + " = " + (val.compile(o)));
@ -1627,7 +1613,7 @@
if (__indexOf.call(this.context, "?") >= 0) {
o.isExistentialEquals = true;
}
return Op.create(this.context.slice(0, -1), left, new Assign(right, this.value, '=')).compile(o);
return new Op(this.context.slice(0, -1), left, new Assign(right, this.value, '=')).compile(o);
};
Assign.prototype.compileSplice = function(o) {
@ -1716,7 +1702,7 @@
o.scope.add(p.value, 'var', true);
}
}
splats = new Assign(Value.wrap(new Arr((function() {
splats = new Assign(new Value(new Arr((function() {
var _l, _len3, _ref5, _results;
_ref5 = this.params;
_results = [];
@ -1725,7 +1711,7 @@
_results.push(p.asReference(o));
}
return _results;
}).call(this))), Value.wrap(new Literal('arguments')));
}).call(this))), new Value(new Literal('arguments')));
break;
}
_ref5 = this.params;
@ -1734,16 +1720,16 @@
if (param.isComplex()) {
val = ref = param.asReference(o);
if (param.value) {
val = Op.create('?', ref, param.value);
val = new Op('?', ref, param.value);
}
exprs.push(new Assign(Value.wrap(param.name), val, '=', {
exprs.push(new Assign(new Value(param.name), val, '=', {
param: true
}));
} else {
ref = param;
if (param.value) {
lit = new Literal(ref.name.value + ' == null');
val = new Assign(Value.wrap(param.name), param.value, '=');
val = new Assign(new Value(param.name), param.value, '=');
exprs.push(new If(lit, val));
}
}
@ -1856,7 +1842,7 @@
} else if (node.isComplex()) {
node = new Literal(o.scope.freeVariable('arg'));
}
node = Value.wrap(node);
node = new Value(node);
if (this.splat) {
node = new Splat(node);
}
@ -2065,7 +2051,7 @@
__extends(Op, _super);
Op.create = function(op, first, second, flip) {
function Op(op, first, second, flip) {
if (op === 'in') {
return new In(first, second);
}
@ -2080,14 +2066,11 @@
first = new Parens(first);
}
}
return new Op(op, first, second, flip);
};
function Op(op, first, second, flip) {
this.operator = CONVERSIONS[op] || op;
this.first = first;
this.second = second;
this.operator = CONVERSIONS[op] || op;
this.flip = !!flip;
return this;
}
CONVERSIONS = {
@ -2149,7 +2132,7 @@
} else if (this.operator === '!' && (fst = this.first.unwrap()) instanceof Op && ((_ref2 = fst.operator) === '!' || _ref2 === 'in' || _ref2 === 'instanceof')) {
return fst;
} else {
return Op.create('!', this);
return new Op('!', this);
}
};
@ -2158,7 +2141,7 @@
return ((_ref2 = this.operator) === '++' || _ref2 === '--' || _ref2 === 'delete') && unfoldSoak(o, this, 'first');
};
Op.generateDo = function(exp) {
Op.prototype.generateDo = function(exp) {
var call, func, param, passedParams, ref, _i, _len, _ref2;
passedParams = [];
func = exp instanceof Assign && (ref = exp.value.unwrap()) instanceof Code ? ref : exp;
@ -2654,7 +2637,7 @@
}
fn = ((_ref6 = val.base) != null ? _ref6.unwrapAll() : void 0) || val;
ref = new Literal(o.scope.freeVariable('fn'));
base = Value.wrap(ref);
base = new Value(ref);
if (val.base) {
_ref7 = [base, val], val.base = _ref7[0], base = _ref7[1];
}
@ -2885,7 +2868,7 @@
if (mentionsArgs) {
args.push(new Literal('arguments'));
}
func = Value.wrap(func, [new Access(meth)]);
func = new Value(func, [new Access(meth)]);
}
func.noReturn = noReturn;
call = new Call(func, args);
@ -2909,7 +2892,7 @@
return;
}
parent[name] = ifn.body;
ifn.body = Value.wrap(parent);
ifn.body = new Value(parent);
return ifn;
};

View File

@ -1,4 +1,4 @@
/* Jison generated parser */
/* parser generated by jison 0.4.2 */
var parser = (function(){
var parser = {trace: function trace() { },
yy: {},
@ -85,11 +85,11 @@ case 37:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Assign($$[$0-3],
break;
case 38:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Assign($$[$0-4], $$[$0-1]));
break;
case 39:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap($$[$0]));
case 39:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
break;
case 40:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Assign(yy.addLocationDataFn(_$[$0-2])(yy.Value.wrap($$[$0-2])), $$[$0], 'object'));
case 40:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Assign(yy.addLocationDataFn(_$[$0-2])(new yy.Value($$[$0-2])), $$[$0], 'object'));
break;
case 41:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Assign(yy.addLocationDataFn(_$[$0-4])(yy.Value.wrap($$[$0-4])), $$[$0-1], 'object'));
case 41:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Assign(yy.addLocationDataFn(_$[$0-4])(new yy.Value($$[$0-4])), $$[$0-1], 'object'));
break;
case 42:this.$ = $$[$0];
break;
@ -143,27 +143,27 @@ case 66:this.$ = $$[$0];
break;
case 67:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Splat($$[$0-1]));
break;
case 68:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap($$[$0]));
case 68:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
break;
case 69:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0-1].add($$[$0]));
break;
case 70:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.Value.wrap($$[$0-1], [].concat($$[$0])));
case 70:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Value($$[$0-1], [].concat($$[$0])));
break;
case 71:this.$ = $$[$0];
break;
case 72:this.$ = $$[$0];
break;
case 73:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap($$[$0]));
case 73:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
break;
case 74:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap($$[$0]));
case 74:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
break;
case 75:this.$ = $$[$0];
break;
case 76:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap($$[$0]));
case 76:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
break;
case 77:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap($$[$0]));
case 77:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
break;
case 78:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap($$[$0]));
case 78:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
break;
case 79:this.$ = $$[$0];
break;
@ -231,11 +231,11 @@ case 109:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])([]);
break;
case 110:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-2]);
break;
case 111:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap(new yy.Literal('this')));
case 111:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value(new yy.Literal('this')));
break;
case 112:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap(new yy.Literal('this')));
case 112:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value(new yy.Literal('this')));
break;
case 113:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.Value.wrap(yy.addLocationDataFn(_$[$0-1])(new yy.Literal('this')), [yy.addLocationDataFn(_$[$0])(new yy.Access($$[$0]))], 'this'));
case 113:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Value(yy.addLocationDataFn(_$[$0-1])(new yy.Literal('this')), [yy.addLocationDataFn(_$[$0])(new yy.Access($$[$0]))], 'this'));
break;
case 114:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Arr([]));
break;
@ -283,7 +283,7 @@ case 135:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Try($$[$0-3], $$
break;
case 136:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([$$[$0-1], $$[$0]]);
break;
case 137:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([yy.addLocationDataFn(_$[$0-1])(yy.Value.wrap($$[$0-1])), $$[$0]]);
case 137:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([new yy.Value($$[$0-1]), $$[$0]]);
break;
case 138:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Throw($$[$0]));
break;
@ -325,7 +325,7 @@ break;
case 153:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.For($$[$0], $$[$0-1]));
break;
case 154:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])({
source: yy.addLocationDataFn(_$[$0])(yy.Value.wrap($$[$0]))
source: new yy.Value($$[$0])
});
break;
case 155:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])((function () {
@ -346,9 +346,9 @@ case 158:this.$ = $$[$0];
break;
case 159:this.$ = $$[$0];
break;
case 160:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap($$[$0]));
case 160:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
break;
case 161:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Value.wrap($$[$0]));
case 161:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
break;
case 162:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([$$[$0]]);
break;
@ -429,39 +429,39 @@ case 184:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.If($$[$0], yy.ad
statement: true
}));
break;
case 185:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.Op.create($$[$0-1], $$[$0]));
case 185:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op($$[$0-1], $$[$0]));
break;
case 186:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.Op.create('-', $$[$0]));
case 186:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('-', $$[$0]));
break;
case 187:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.Op.create('+', $$[$0]));
case 187:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('+', $$[$0]));
break;
case 188:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.Op.create('--', $$[$0]));
case 188:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('--', $$[$0]));
break;
case 189:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.Op.create('++', $$[$0]));
case 189:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('++', $$[$0]));
break;
case 190:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.Op.create('--', $$[$0-1], null, true));
case 190:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('--', $$[$0-1], null, true));
break;
case 191:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.Op.create('++', $$[$0-1], null, true));
case 191:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('++', $$[$0-1], null, true));
break;
case 192:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Existence($$[$0-1]));
break;
case 193:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(yy.Op.create('+', $$[$0-2], $$[$0]));
case 193:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op('+', $$[$0-2], $$[$0]));
break;
case 194:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(yy.Op.create('-', $$[$0-2], $$[$0]));
case 194:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op('-', $$[$0-2], $$[$0]));
break;
case 195:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(yy.Op.create($$[$0-1], $$[$0-2], $$[$0]));
case 195:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op($$[$0-1], $$[$0-2], $$[$0]));
break;
case 196:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(yy.Op.create($$[$0-1], $$[$0-2], $$[$0]));
case 196:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op($$[$0-1], $$[$0-2], $$[$0]));
break;
case 197:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(yy.Op.create($$[$0-1], $$[$0-2], $$[$0]));
case 197:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op($$[$0-1], $$[$0-2], $$[$0]));
break;
case 198:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(yy.Op.create($$[$0-1], $$[$0-2], $$[$0]));
case 198:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op($$[$0-1], $$[$0-2], $$[$0]));
break;
case 199:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])((function () {
if ($$[$0-1].charAt(0) === '!') {
return yy.Op.create($$[$0-1].slice(1), $$[$0-2], $$[$0]).invert();
return new yy.Op($$[$0-1].slice(1), $$[$0-2], $$[$0]).invert();
} else {
return yy.Op.create($$[$0-1], $$[$0-2], $$[$0]);
return new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
}
}()));
break;
@ -591,19 +591,16 @@ return new Parser;
if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
exports.parser = parser;
exports.Parser = parser.Parser;
exports.parse = function () { return parser.parse.apply(parser, arguments); }
exports.parse = function () { return parser.parse.apply(parser, arguments); };
exports.main = function commonjsMain(args) {
if (!args[1])
throw new Error('Usage: '+args[0]+' FILE');
var source, cwd;
if (typeof process !== 'undefined') {
source = require('fs').readFileSync(require('path').resolve(args[1]), "utf8");
} else {
source = require("file").path(require("file").cwd()).join(args[1]).read({charset: "utf-8"});
if (!args[1]) {
console.log('Usage: '+args[0]+' FILE');
process.exit(1);
}
var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8");
return exports.parser.parse(source);
}
};
if (typeof module !== 'undefined' && require.main === module) {
exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args);
exports.main(process.argv.slice(1));
}
}

View File

@ -39,7 +39,6 @@ o = (patternString, action, options) ->
# All runtime functions we need are defined on "yy"
action = action.replace /\bnew /g, '$&yy.'
action = action.replace /\b(?:Block\.wrap|extend)\b/g, 'yy.$&'
action = action.replace /\b(Op|Value\.(create|wrap))\b/g, 'yy.$&'
# Returns a function which adds location data to the first parameter passed
# in, and returns the parameter. If the parameter is not a node, it will
@ -159,10 +158,10 @@ grammar =
# Assignment when it happens within an object literal. The difference from
# the ordinary **Assign** is that these allow numbers and strings as keys.
AssignObj: [
o 'ObjAssignable', -> Value.wrap $1
o 'ObjAssignable : Expression', -> new Assign LOC(1)(Value.wrap($1)), $3, 'object'
o 'ObjAssignable', -> new Value $1
o 'ObjAssignable : Expression', -> new Assign LOC(1)(new Value($1)), $3, 'object'
o 'ObjAssignable :
INDENT Expression OUTDENT', -> new Assign LOC(1)(Value.wrap($1)), $4, 'object'
INDENT Expression OUTDENT', -> new Assign LOC(1)(new Value($1)), $4, 'object'
o 'Comment'
]
@ -236,26 +235,26 @@ grammar =
# Variables and properties that can be assigned to.
SimpleAssignable: [
o 'Identifier', -> Value.wrap $1
o 'Identifier', -> new Value $1
o 'Value Accessor', -> $1.add $2
o 'Invocation Accessor', -> Value.wrap $1, [].concat $2
o 'Invocation Accessor', -> new Value $1, [].concat $2
o 'ThisProperty'
]
# Everything that can be assigned to.
Assignable: [
o 'SimpleAssignable'
o 'Array', -> Value.wrap $1
o 'Object', -> Value.wrap $1
o 'Array', -> new Value $1
o 'Object', -> new Value $1
]
# The types of things that can be treated as values -- assigned to, invoked
# as functions, indexed into, named as a class, etc.
Value: [
o 'Assignable'
o 'Literal', -> Value.wrap $1
o 'Parenthetical', -> Value.wrap $1
o 'Range', -> Value.wrap $1
o 'Literal', -> new Value $1
o 'Parenthetical', -> new Value $1
o 'Range', -> new Value $1
o 'This'
]
@ -330,13 +329,13 @@ grammar =
# A reference to the *this* current object.
This: [
o 'THIS', -> Value.wrap new Literal 'this'
o '@', -> Value.wrap new Literal 'this'
o 'THIS', -> new Value new Literal 'this'
o '@', -> new Value new Literal 'this'
]
# A reference to a property on *this*.
ThisProperty: [
o '@ Identifier', -> Value.wrap LOC(1)(new Literal('this')), [LOC(2)(new Access($2))], 'this'
o '@ Identifier', -> new Value LOC(1)(new Literal('this')), [LOC(2)(new Access($2))], 'this'
]
# The array literal.
@ -400,7 +399,7 @@ grammar =
# A catch clause names its error and runs a block of code.
Catch: [
o 'CATCH Identifier Block', -> [$2, $3]
o 'CATCH Object Block', -> [LOC(2)(Value.wrap($2)), $3]
o 'CATCH Object Block', -> [LOC(2)(new Value($2)), $3]
]
# Throw an exception object.
@ -449,7 +448,7 @@ grammar =
]
ForBody: [
o 'FOR Range', -> source: LOC(2) Value.wrap($2)
o 'FOR Range', -> source: LOC(2) new Value($2)
o 'ForStart ForSource', -> $2.own = $1.own; $2.name = $1[0]; $2.index = $1[1]; $2
]
@ -463,8 +462,8 @@ grammar =
ForValue: [
o 'Identifier'
o 'ThisProperty'
o 'Array', -> Value.wrap $1
o 'Object', -> Value.wrap $1
o 'Array', -> new Value $1
o 'Object', -> new Value $1
]
# An array or range comprehension has variables for the current element
@ -530,30 +529,30 @@ grammar =
# -type rule, but in order to make the precedence binding possible, separate
# rules are necessary.
Operation: [
o 'UNARY Expression', -> Op.create $1 , $2
o '- Expression', (-> Op.create '-', $2), prec: 'UNARY'
o '+ Expression', (-> Op.create '+', $2), prec: 'UNARY'
o 'UNARY Expression', -> new Op $1 , $2
o '- Expression', (-> new Op '-', $2), prec: 'UNARY'
o '+ Expression', (-> new Op '+', $2), prec: 'UNARY'
o '-- SimpleAssignable', -> Op.create '--', $2
o '++ SimpleAssignable', -> Op.create '++', $2
o 'SimpleAssignable --', -> Op.create '--', $1, null, true
o 'SimpleAssignable ++', -> Op.create '++', $1, null, true
o '-- SimpleAssignable', -> new Op '--', $2
o '++ SimpleAssignable', -> new Op '++', $2
o 'SimpleAssignable --', -> new Op '--', $1, null, true
o 'SimpleAssignable ++', -> new Op '++', $1, null, true
# [The existential operator](http://jashkenas.github.com/coffee-script/#existence).
o 'Expression ?', -> new Existence $1
o 'Expression + Expression', -> Op.create '+' , $1, $3
o 'Expression - Expression', -> Op.create '-' , $1, $3
o 'Expression + Expression', -> new Op '+' , $1, $3
o 'Expression - Expression', -> new Op '-' , $1, $3
o 'Expression MATH Expression', -> Op.create $2, $1, $3
o 'Expression SHIFT Expression', -> Op.create $2, $1, $3
o 'Expression COMPARE Expression', -> Op.create $2, $1, $3
o 'Expression LOGIC Expression', -> Op.create $2, $1, $3
o 'Expression MATH Expression', -> new Op $2, $1, $3
o 'Expression SHIFT Expression', -> new Op $2, $1, $3
o 'Expression COMPARE Expression', -> new Op $2, $1, $3
o 'Expression LOGIC Expression', -> new Op $2, $1, $3
o 'Expression RELATION Expression', ->
if $2.charAt(0) is '!'
Op.create($2[1..], $1, $3).invert()
new Op($2[1..], $1, $3).invert()
else
Op.create $2, $1, $3
new Op $2, $1, $3
o 'SimpleAssignable COMPOUND_ASSIGN
Expression', -> new Assign $1, $3, $2

View File

@ -123,7 +123,7 @@ exports.Base = class Base
child.traverseChildren crossScope, func
invert: ->
Op.create '!', this
new Op '!', this
unwrapAll: ->
node = this
@ -384,15 +384,12 @@ exports.Return = class Return extends Base
# A value, variable or literal or parenthesized, indexed or dotted into,
# or vanilla.
exports.Value = class Value extends Base
@wrap: (base, props, tag) ->
if not props and base instanceof Value
base
else
new Value base, props, tag
constructor: (@base, @properties, tag) ->
@properties or= []
@this = true if tag is 'this'
constructor: (base, props, tag) ->
return base if not props and base instanceof Value
@base = base
@properties = props or []
@[tag] = true if tag
return this
children: ['base', 'properties']
@ -438,16 +435,16 @@ exports.Value = class Value extends Base
name = last @properties
if @properties.length < 2 and not @base.isComplex() and not name?.isComplex()
return [this, this] # `a` `a.b`
base = Value.wrap @base, @properties[...-1]
base = new Value @base, @properties[...-1]
if base.isComplex() # `a().b`
bref = new Literal o.scope.freeVariable 'base'
base = Value.wrap new Parens new Assign bref, base
base = new Value new Parens new Assign bref, base
return [base, bref] unless name # `a()`
if name.isComplex() # `a[b()]`
nref = new Literal o.scope.freeVariable 'name'
name = new Index new Assign nref, name.index
nref = new Index nref
[base.add(name), Value.wrap(bref or base.base, [nref or name])]
[base.add(name), new Value(bref or base.base, [nref or name])]
# We compile a value to JavaScript by compiling and joining each property.
# Things get much more interesting if the chain of properties has *soak*
@ -469,8 +466,8 @@ exports.Value = class Value extends Base
return ifn
for prop, i in @properties when prop.soak
prop.soak = off
fst = Value.wrap @base, @properties[...i]
snd = Value.wrap @base, @properties[i..]
fst = new Value @base, @properties[...i]
snd = new Value @base, @properties[i..]
if fst.isComplex()
ref = new Literal o.scope.freeVariable 'ref'
fst = new Parens new Assign ref, fst
@ -525,7 +522,7 @@ exports.Call = class Call extends Base
accesses = [new Access(new Literal '__super__')]
accesses.push new Access new Literal 'constructor' if method.static
accesses.push new Access new Literal name
(Value.wrap (new Literal method.klass), accesses).compile o
(new Value (new Literal method.klass), accesses).compile o
else
"#{name}.__super__.constructor"
@ -539,14 +536,14 @@ exports.Call = class Call extends Base
if @soak
if @variable
return ifn if ifn = unfoldSoak o, this, 'variable'
[left, rite] = Value.wrap(@variable).cacheReference o
[left, rite] = new Value(@variable).cacheReference o
else
left = new Literal @superReference o
rite = Value.wrap left
rite = new Value left
rite = new Call rite, @args
rite.isNew = @isNew
left = new Literal "typeof #{ left.compile o } === \"function\""
return new If left, Value.wrap(rite), soak: yes
return new If left, new Value(rite), soak: yes
call = this
list = []
loop
@ -592,7 +589,7 @@ exports.Call = class Call extends Base
#{idt}return Object(result) === result ? result : child;
#{@tab}})(#{ @variable.compile o, LEVEL_LIST }, #{splatArgs}, function(){})
"""
base = Value.wrap @variable
base = new Value @variable
if (name = base.properties.pop()) and base.isComplex()
ref = o.scope.freeVariable 'ref'
fun = "(#{ref} = #{ base.compile o, LEVEL_LIST })#{ name.compile o }"
@ -618,7 +615,7 @@ exports.Extends = class Extends extends Base
# Hooks one constructor into another's prototype chain.
compile: (o) ->
new Call(Value.wrap(new Literal utility 'extends'), [@child, @parent]).compile o
new Call(new Value(new Literal utility 'extends'), [@child, @parent]).compile o
#### Access
@ -873,7 +870,7 @@ exports.Class = class Class extends Base
# constructor.
addBoundFunctions: (o) ->
for bvar in @boundFuncs
lhs = (Value.wrap (new Literal "this"), [new Access bvar]).compile o
lhs = (new Value (new Literal "this"), [new Access bvar]).compile o
@ctor.body.unshift new Literal "#{lhs} = #{utility 'bind'}(#{lhs}, this)"
return
@ -902,7 +899,7 @@ exports.Class = class Class extends Base
if func.bound
func.context = name
else
assign.variable = Value.wrap(new Literal(name), [(new Access new Literal 'prototype'), new Access base ])
assign.variable = new Value(new Literal(name), [(new Access new Literal 'prototype'), new Access base ])
if func instanceof Code and func.bound
@boundFuncs.push base
func.bound = no
@ -931,23 +928,17 @@ exports.Class = class Class extends Base
# Make sure that a constructor is defined for the class, and properly
# configured.
ensureConstructor: (name, o) ->
ensureConstructor: (name) ->
if not @ctor
@ctor = new Code
@ctor.body.push new Literal "#{name}.__super__.constructor.apply(this, arguments)" if @parent
@ctor.body.push new Literal "#{@externalCtor}.apply(this, arguments)" if @externalCtor
@ctor.body.makeReturn()
@body.expressions.unshift @ctor
@ctor.ctor = @ctor.name = name
@ctor.klass = null
@ctor.noReturn = yes
# Prevent constructor from returning a value.
returnExpr = null
@ctor.body.traverseChildren no, (node) ->
return no if node instanceof Return and (returnExpr = node.expression)
if returnExpr
throw SyntaxError "cannot return a value from a constructor: \"#{returnExpr.compileNode o}\" in class #{name}"
# Instead of generating the JavaScript string directly, we build up the
# equivalent syntax tree and compile that, in pieces. You can see the
# constructor, property assignments, and inheritance getting built out below.
@ -960,7 +951,7 @@ exports.Class = class Class extends Base
@hoistDirectivePrologue()
@setContext name
@walkBody name, o
@ensureConstructor name, o
@ensureConstructor name
@body.spaced = yes
@body.expressions.unshift @ctor unless @ctor instanceof Code
@body.expressions.push lname
@ -1051,7 +1042,7 @@ exports.Assign = class Assign extends Base
else
new Literal 0
acc = IDENTIFIER.test idx.unwrap().value or 0
value = Value.wrap value
value = new Value value
value.properties.push new (if acc then Access else Index) idx
if obj.unwrap().value in RESERVED
throw new SyntaxError "assignment to a reserved word: #{obj.compile o} = #{value.compile o}"
@ -1072,7 +1063,7 @@ exports.Assign = class Assign extends Base
else
# A shorthand `{a, b, @c} = val` pattern-match.
if obj.base instanceof Parens
[obj, idx] = Value.wrap(obj.unwrapAll()).cacheReference o
[obj, idx] = new Value(obj.unwrapAll()).cacheReference o
else
idx = if obj.this then obj.properties[0].name else obj
if not splat and obj instanceof Splat
@ -1097,7 +1088,7 @@ exports.Assign = class Assign extends Base
acc = no
else
acc = isObject and IDENTIFIER.test idx.unwrap().value or 0
val = Value.wrap new Literal(vvar), [new (if acc then Access else Index) idx]
val = new Value new Literal(vvar), [new (if acc then Access else Index) idx]
if name? and name in RESERVED
throw new SyntaxError "assignment to a reserved word: #{obj.compile o} = #{val.compile o}"
assigns.push new Assign(obj, val, null, param: @param, subpattern: yes).compile o, LEVEL_LIST
@ -1115,7 +1106,7 @@ exports.Assign = class Assign extends Base
left.base.value != "this" and not o.scope.check left.base.value
throw new Error "the variable \"#{left.base.value}\" can't be assigned with #{@context} because it has not been defined."
if "?" in @context then o.isExistentialEquals = true
Op.create(@context[...-1], left, new Assign(right, @value, '=') ).compile o
new Op(@context[...-1], left, new Assign(right, @value, '=') ).compile o
# Compile the assignment from an array splice literal, using JavaScript's
# `Array#splice` method.
@ -1173,19 +1164,19 @@ exports.Code = class Code extends Base
for {name: p} in @params
if p.this then p = p.properties[0].name
if p.value then o.scope.add p.value, 'var', yes
splats = new Assign Value.wrap(new Arr(p.asReference o for p in @params)),
Value.wrap new Literal 'arguments'
splats = new Assign new Value(new Arr(p.asReference o for p in @params)),
new Value new Literal 'arguments'
break
for param in @params
if param.isComplex()
val = ref = param.asReference o
val = Op.create '?', ref, param.value if param.value
exprs.push new Assign Value.wrap(param.name), val, '=', param: yes
val = new Op '?', ref, param.value if param.value
exprs.push new Assign new Value(param.name), val, '=', param: yes
else
ref = param
if param.value
lit = new Literal ref.name.value + ' == null'
val = new Assign Value.wrap(param.name), param.value, '='
val = new Assign new Value(param.name), param.value, '='
exprs.push new If lit, val
params.push ref unless splats
wasEmpty = @body.isEmpty()
@ -1246,7 +1237,7 @@ exports.Param = class Param extends Base
node = new Literal o.scope.freeVariable node.value
else if node.isComplex()
node = new Literal o.scope.freeVariable 'arg'
node = Value.wrap node
node = new Value node
node = new Splat node if @splat
@reference = node
@ -1390,19 +1381,18 @@ exports.While = class While extends Base
# Simple Arithmetic and logical operations. Performs some conversion from
# CoffeeScript operations into their JavaScript equivalents.
exports.Op = class Op extends Base
@create: (op, first, second, flip) ->
if op is 'in'
return new In first, second
constructor: (op, first, second, flip ) ->
return new In first, second if op is 'in'
if op is 'do'
return @generateDo first
if op is 'new'
return first.newInstance() if first instanceof Call and not first.do and not first.isNew
first = new Parens first if first instanceof Code and first.bound or first.do
return new Op op, first, second, flip
constructor: (op, @first, @second, flip ) ->
@operator = CONVERSIONS[op] or op
@first = first
@second = second
@flip = !!flip
return this
# The map of conversions from CoffeeScript to JavaScript symbols.
CONVERSIONS =
@ -1455,12 +1445,12 @@ exports.Op = class Op extends Base
fst.operator in ['!', 'in', 'instanceof']
fst
else
Op.create '!', this
new Op '!', this
unfoldSoak: (o) ->
@operator in ['++', '--', 'delete'] and unfoldSoak o, this, 'first'
@generateDo: (exp) ->
generateDo: (exp) ->
passedParams = []
func = if exp instanceof Assign and (ref = exp.value.unwrap()) instanceof Code
ref
@ -1789,7 +1779,7 @@ exports.For = class For extends While
val.properties[0].name?.value in ['call', 'apply'])
fn = val.base?.unwrapAll() or val
ref = new Literal o.scope.freeVariable 'fn'
base = Value.wrap ref
base = new Value ref
if val.base
[val.base, base] = [base, val]
body.expressions[idx] = new Call base, expr.args
@ -1937,7 +1927,7 @@ Closure =
meth = new Literal if mentionsArgs then 'apply' else 'call'
args = [new Literal 'this']
args.push new Literal 'arguments' if mentionsArgs
func = Value.wrap func, [new Access meth]
func = new Value func, [new Access meth]
func.noReturn = noReturn
call = new Call func, args
if statement then Block.wrap [call] else call
@ -1954,7 +1944,7 @@ Closure =
unfoldSoak = (o, parent, name) ->
return unless ifn = parent[name].unfoldSoak o
parent[name] = ifn.body
ifn.body = Value.wrap parent
ifn.body = new Value parent
ifn
# Constants

View File

@ -595,6 +595,11 @@ test "#1813: Passing class definitions as expressions", ->
eq result, B
test "#1966: external constructors should produce their return value", ->
ctor = -> {}
class A then constructor: ctor
ok (new A) not instanceof A
test "#1980: regression with an inherited class with static function members", ->
class A
@ -676,27 +681,6 @@ test "#2630: class bodies can't reference arguments", ->
throws ->
CoffeeScript.compile('class Test then arguments')
test "#2359: instanceof should work when extending native objects", ->
class MyError extends Error
ok new MyError instanceof MyError
test '#2359: external constructors returning "other typed" objets', ->
ctor = -> {}
class A then constructor: ctor
ok new A instanceof A
ok new ctor not instanceof A
ok new ctor not instanceof ctor
test "#2359: constructors should not return an explicit value", ->
throws -> CoffeeScript.run "class then constructor: -> return 5"
throws -> CoffeeScript.run """
class
constructor: ->
if foo
return bar: 7
baz()
"""
test "#2319: fn class n extends o.p [INDENT] x = 123", ->
first = ->
@ -706,4 +690,4 @@ test "#2319: fn class n extends o.p [INDENT] x = 123", ->
one = 1
one: -> one
eq new OneKeeper().one(), 1
eq new OneKeeper().one(), 1