commit
2970d59395
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,31 @@ 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
|
||||
|
||||
|
||||
test "#2599: other typed constructors should be inherited", ->
|
||||
class Base
|
||||
constructor: -> return {}
|
||||
|
||||
class Derived extends Base
|
||||
|
||||
ok (new Derived) not instanceof Derived
|
||||
ok (new Derived) not instanceof Base
|
||||
ok (new Base) not instanceof Base
|
||||
|
||||
test "#2359: extending native objects that use other typed constructors requires defining a constructor", ->
|
||||
class BrokenArray extends Array
|
||||
method: -> 'no one will call me'
|
||||
|
||||
brokenArray = new BrokenArray
|
||||
ok brokenArray not instanceof BrokenArray
|
||||
ok typeof brokenArray.method is 'undefined'
|
||||
|
||||
class WorkingArray extends Array
|
||||
constructor: -> super
|
||||
method: -> 'yes!'
|
||||
|
||||
workingArray = new WorkingArray
|
||||
ok workingArray instanceof WorkingArray
|
||||
eq 'yes!', workingArray.method()
|
Loading…
Reference in New Issue