gorillascript
Version:
GorillaScript is a compile-to-JavaScript language designed to empower the user while attempting to prevent some common errors.
1,345 lines (1,344 loc) • 198 kB
JavaScript
(function (GLOBAL) {
"use strict";
var __async, __create, __in, __is, __isArray, __keys, __name, __once, __owns,
__slice, __toArray, __typeof, _ref, Cache, Call, isPrimordial,
MacroAccess, Node, nodeToType, Symbol, toJSSource, Type, Value;
__async = function (limit, length, hasResult, onValue, onComplete) {
var broken, completed, index, result, slotsUsed, sync;
if (typeof limit !== "number") {
throw new TypeError("Expected limit to be a Number, got " + __typeof(limit));
}
if (typeof length !== "number") {
throw new TypeError("Expected length to be a Number, got " + __typeof(length));
}
if (hasResult == null) {
hasResult = false;
} else if (typeof hasResult !== "boolean") {
throw new TypeError("Expected hasResult to be a Boolean, got " + __typeof(hasResult));
}
if (typeof onValue !== "function") {
throw new TypeError("Expected onValue to be a Function, got " + __typeof(onValue));
}
if (typeof onComplete !== "function") {
throw new TypeError("Expected onComplete to be a Function, got " + __typeof(onComplete));
}
if (hasResult) {
result = [];
} else {
result = null;
}
if (length <= 0) {
return onComplete(null, result);
}
if (limit < 1 || limit !== limit) {
limit = 1/0;
}
broken = null;
slotsUsed = 0;
sync = false;
completed = false;
function onValueCallback(err, value) {
if (completed) {
return;
}
--slotsUsed;
if (err != null && broken == null) {
broken = err;
}
if (hasResult && broken == null && arguments.length > 1) {
result.push(value);
}
if (!sync) {
next();
}
}
index = -1;
function next() {
while (!completed && broken == null && slotsUsed < limit && ++index < length) {
++slotsUsed;
sync = true;
onValue(index, __once(onValueCallback));
sync = false;
}
if (!completed && (broken != null || slotsUsed === 0)) {
completed = true;
if (broken != null) {
onComplete(broken);
} else {
onComplete(null, result);
}
}
}
next();
};
__create = typeof Object.create === "function" ? Object.create
: function (x) {
function F() {}
F.prototype = x;
return new F();
};
__in = typeof Array.prototype.indexOf === "function"
? (function (indexOf) {
return function (child, parent) {
return indexOf.call(parent, child) !== -1;
};
}(Array.prototype.indexOf))
: function (child, parent) {
var i, len;
len = +parent.length;
i = -1;
while (++i < len) {
if (child === parent[i] && i in parent) {
return true;
}
}
return false;
};
__is = typeof Object.is === "function" ? Object.is
: function (x, y) {
if (x === y) {
return x !== 0 || 1 / x === 1 / y;
} else {
return x !== x && y !== y;
}
};
__isArray = typeof Array.isArray === "function" ? Array.isArray
: (function (_toString) {
return function (x) {
return _toString.call(x) === "[object Array]";
};
}(Object.prototype.toString));
__keys = typeof Object.keys === "function" ? Object.keys
: function (x) {
var key, keys;
keys = [];
for (key in x) {
if (__owns.call(x, key)) {
keys.push(key);
}
}
return keys;
};
__name = function (func) {
if (typeof func !== "function") {
throw new TypeError("Expected func to be a Function, got " + __typeof(func));
}
return func.displayName || func.name || "";
};
__once = (function () {
function replacement() {
throw new Error("Attempted to call function more than once");
}
function doNothing() {}
return function (func, silentFail) {
if (typeof func !== "function") {
throw new TypeError("Expected func to be a Function, got " + __typeof(func));
}
if (silentFail == null) {
silentFail = false;
} else if (typeof silentFail !== "boolean") {
throw new TypeError("Expected silentFail to be a Boolean, got " + __typeof(silentFail));
}
return function () {
var f;
f = func;
if (silentFail) {
func = doNothing;
} else {
func = replacement;
}
return f.apply(this, arguments);
};
};
}());
__owns = Object.prototype.hasOwnProperty;
__slice = Array.prototype.slice;
__toArray = function (x) {
if (x == null) {
throw new TypeError("Expected an object, got " + __typeof(x));
} else if (__isArray(x)) {
return x;
} else if (typeof x === "string") {
return x.split("");
} else if (typeof x.length === "number") {
return __slice.call(x);
} else {
throw new TypeError("Expected an object with a length property, got " + __typeof(x));
}
};
__typeof = (function () {
var _toString;
_toString = Object.prototype.toString;
return function (o) {
if (o === void 0) {
return "Undefined";
} else if (o === null) {
return "Null";
} else {
return o.constructor && o.constructor.name || _toString.call(o).slice(8, -1);
}
};
}());
toJSSource = require("./jsutils").toJSSource;
Type = require("./types");
_ref = require("./utils");
Cache = _ref.Cache;
isPrimordial = _ref.isPrimordial;
_ref = null;
nodeToType = require("./parser-utils").nodeToType;
function capitalize(value) {
return value.charAt(0).toUpperCase() + value.substring(1);
}
function isPrimitive(value) {
var _ref;
return value === null || (_ref = typeof value) === "number" || _ref === "string" || _ref === "boolean" || _ref === "undefined";
}
Node = (function () {
var _Node_prototype;
function Node() {
var _this;
_this = this instanceof Node ? this : __create(_Node_prototype);
throw new Error("Node is not intended to be initialized directly");
}
_Node_prototype = Node.prototype;
Node.displayName = "Node";
_Node_prototype.isValue = false;
_Node_prototype.isSymbol = false;
_Node_prototype.isCall = false;
_Node_prototype.isMacroAccess = false;
_Node_prototype.isNoop = function () {
throw new Error("Not implemented: " + __name(this.constructor) + ".isNoop()");
};
_Node_prototype.isConst = function () {
return false;
};
_Node_prototype.constValue = function () {
throw new Error("Not a const: " + (typeof this === "undefined" ? "Undefined" : __typeof(this)));
};
_Node_prototype.isConstValue = function () {
return false;
};
_Node_prototype.isConstType = function () {
return false;
};
_Node_prototype.isConstTruthy = function () {
return false;
};
_Node_prototype.isConstFalsy = function () {
return false;
};
_Node_prototype.isLiteral = function () {
return this.isConst();
};
_Node_prototype.literalValue = function () {
return this.constValue();
};
_Node_prototype.isStatement = function () {
return false;
};
_Node_prototype.doWrap = function () {
return this;
};
_Node_prototype.type = function () {
return Type.any;
};
_Node_prototype.walk = function () {
return this;
};
_Node_prototype.walkAsync = function (f, context, callback) {
callback(null, this);
};
_Node_prototype.walkWithThis = function (f, context) {
var _ref;
if ((_ref = f.call(context, this)) != null) {
return _ref;
} else {
return this.walk(f, context);
}
};
_Node_prototype.walkWithThisAsync = function (f, context, callback) {
var _this;
_this = this;
f.call(context, function (err, value) {
if (err) {
callback(err);
} else if (value != null) {
callback(null, value);
} else {
_this.walkAsync(f, context, callback);
}
});
};
_Node_prototype.isInternalCall = function () {
return false;
};
_Node_prototype.isUnaryCall = function () {
return false;
};
_Node_prototype.isBinaryCall = function () {
return false;
};
_Node_prototype.isAssignCall = function () {
return false;
};
_Node_prototype.isNormalCall = function () {
return false;
};
_Node_prototype.doWrapArgs = true;
_Node_prototype.convertNothing = function () {
return this;
};
_Node_prototype.returnType = function (parser, isLast) {
if (isLast) {
return Type["undefined"];
} else {
return Type.none;
}
};
_Node_prototype.mutateLast = function (o, func, context, includeNoop) {
var _ref;
if ((_ref = func.call(context, this)) != null) {
return _ref;
} else {
return this;
}
};
_Node_prototype.withLabel = function (label) {
if (!label) {
return this;
} else {
return InternalCall(
"label",
this.index,
this.scope,
label,
this
);
}
};
_Node_prototype._reduce = function (parser) {
return this.walk(function (node) {
return node.reduce(parser);
});
};
_Node_prototype.reduce = function (parser) {
var reduced;
if (this._reduced != null) {
return this._reduced;
} else {
reduced = this._reduce(parser);
if (reduced === this) {
return this._reduced = this;
} else {
return this._reduced = reduced.reduce(parser);
}
}
};
_Node_prototype.rescope = function (newScope) {
var oldScope;
if (!this.scope || this.scope === newScope) {
return this;
}
oldScope = this.scope;
this.scope = newScope;
function walker(node) {
var nodeScope, parent;
nodeScope = node.scope;
if (!nodeScope || nodeScope === newScope) {
return node;
} else if (nodeScope === oldScope) {
return node.rescope(newScope);
} else {
parent = nodeScope.parent;
if (parent === oldScope) {
nodeScope.reparent(newScope);
}
return node.walk(walker);
}
}
return this.walk(walker);
};
return Node;
}());
Value = (function (Node) {
var _Node_prototype, _Value_prototype;
function Value(index, value) {
var _this;
_this = this instanceof Value ? this : __create(_Value_prototype);
_this.index = index;
_this.value = value;
return _this;
}
_Node_prototype = Node.prototype;
_Value_prototype = Value.prototype = __create(_Node_prototype);
_Value_prototype.constructor = Value;
Value.displayName = "Value";
if (typeof Node.extended === "function") {
Node.extended(Value);
}
_Value_prototype.isValue = true;
_Value_prototype.nodeType = "value";
_Value_prototype.nodeTypeId = 0;
_Value_prototype.cacheable = false;
_Value_prototype.reduce = function () {
return this;
};
_Value_prototype.isNoop = function () {
return true;
};
_Value_prototype.constValue = function () {
return this.value;
};
_Value_prototype.isConst = function () {
return true;
};
_Value_prototype.isConstValue = function (value) {
return value === this.value;
};
_Value_prototype.isConstType = function (type) {
return type === typeof this.value;
};
_Value_prototype.isConstTruthy = function () {
return !!this.value;
};
_Value_prototype.isConstFalsy = function () {
return !this.value;
};
_Value_prototype.equals = function (other) {
return other === this || other instanceof Value && __is(this.value, other.value);
};
_Value_prototype.type = function () {
var value;
value = this.value;
if (value === null) {
return Type["null"];
} else {
switch (typeof value) {
case "number": return Type.number;
case "string": return Type.string;
case "boolean": return Type.boolean;
case "undefined": return Type["undefined"];
default: throw new Error("Unhandled value in switch");
}
}
};
_Value_prototype.inspect = function () {
return "Value(" + toJSSource(this.value) + ")";
};
_Value_prototype.toString = function () {
var value;
value = this.value;
if (value !== value) {
return "NaN";
} else {
switch (value) {
case void 0: return "void";
case null: return "null";
case 1/0: return "Infinity";
case -1/0: return "-Infinity";
default: return toJSSource(value);
}
}
};
return Value;
}(Node));
Symbol = (function (Node) {
var _Node_prototype, _Symbol_prototype, Ident, Internal, Operator, Tmp;
function Symbol() {
var _this;
_this = this instanceof Symbol ? this : __create(_Symbol_prototype);
throw new Error("Symbol is not intended to be instantiated directly");
}
_Node_prototype = Node.prototype;
_Symbol_prototype = Symbol.prototype = __create(_Node_prototype);
_Symbol_prototype.constructor = Symbol;
Symbol.displayName = "Symbol";
if (typeof Node.extended === "function") {
Node.extended(Symbol);
}
_Symbol_prototype.isSymbol = true;
_Symbol_prototype.nodeType = "symbol";
_Symbol_prototype.nodeTypeId = 1;
_Symbol_prototype.isNoop = function () {
return true;
};
_Symbol_prototype.isIdent = false;
_Symbol_prototype.isTmp = false;
_Symbol_prototype.isIdentOrTmp = false;
_Symbol_prototype.isInternal = false;
_Symbol_prototype.isOperator = false;
_Symbol_prototype.reduce = function () {
return this;
};
_Symbol_prototype.cacheable = false;
Internal = (function (Symbol) {
var _Internal_prototype, _Symbol_prototype2, internalSymbols, name;
function Internal() {
var _this;
_this = this instanceof Internal ? this : __create(_Internal_prototype);
throw new Error("Internal is not intended to be instantiated directly");
}
_Symbol_prototype2 = Symbol.prototype;
_Internal_prototype = Internal.prototype = __create(_Symbol_prototype2);
_Internal_prototype.constructor = Internal;
Internal.displayName = "Internal";
if (typeof Symbol.extended === "function") {
Symbol.extended(Internal);
}
_Internal_prototype.inspect = function () {
return "Symbol." + this.name;
};
_Internal_prototype.toString = function () {
return this.name + "!";
};
_Internal_prototype.isInternal = true;
_Internal_prototype.symbolType = "internal";
_Internal_prototype.symbolTypeId = 0;
_Internal_prototype.isGoto = false;
_Internal_prototype.usedAsStatement = false;
internalSymbols = {
access: {
internalId: 0,
validateArgs: function (parent, child) {
var rest;
rest = __slice.call(arguments, 2);
},
_toString: function (call) {
var key, sb;
sb = [];
sb.push(call.args[0]);
key = call.args[1];
if (key.isConstType("string") && /^[\w\$_][\w\d\$_]*$/.test(key.constValue())) {
sb.push(".");
sb.push(key.constValue());
} else {
sb.push("[");
sb.push(key);
sb.push("]");
}
return sb.join("");
},
_type: (function () {
var cache, PRIMORDIAL_INSTANCE_PROPERTIES,
PRIMORDIAL_STATIC_PROPERTIES;
PRIMORDIAL_STATIC_PROPERTIES = {
Object: {
getPrototypeOf: Type.object["function"]().union(Type["undefined"]),
getOwnPropertyDescriptor: Type.object["function"]().union(Type["undefined"]),
getOwnPropertyNames: Type.string.array()["function"]().union(Type["undefined"]),
create: Type.object["function"]().union(Type["undefined"]),
defineProperty: Type.object["function"]().union(Type["undefined"]),
defineProperties: Type.object["function"]().union(Type["undefined"]),
seal: Type.object["function"]().union(Type["undefined"]),
freeze: Type.object["function"]().union(Type["undefined"]),
preventExtensions: Type.object["function"]().union(Type["undefined"]),
isSealed: Type.boolean["function"]().union(Type["undefined"]),
isFrozen: Type.boolean["function"]().union(Type["undefined"]),
isExtensible: Type.boolean["function"]().union(Type["undefined"]),
keys: Type.string.array()["function"]().union(Type["undefined"])
},
String: { fromCharCode: Type.string["function"]() },
Number: { isFinite: Type.boolean["function"]().union(Type["undefined"]), isNaN: Type.boolean["function"]().union(Type["undefined"]) },
Array: { isArray: Type.boolean["function"]().union(Type["undefined"]) },
Math: {
abs: Type.number["function"](),
acos: Type.number["function"](),
asin: Type.number["function"](),
atan: Type.number["function"](),
atan2: Type.number["function"](),
ceil: Type.number["function"](),
cos: Type.number["function"](),
exp: Type.number["function"](),
floor: Type.number["function"](),
imul: Type.number["function"]().union(Type["undefined"]),
log: Type.number["function"](),
max: Type.number["function"](),
min: Type.number["function"](),
pow: Type.number["function"](),
random: Type.number["function"](),
round: Type.number["function"](),
sin: Type.number["function"](),
sqrt: Type.number["function"](),
tan: Type.number["function"]()
},
JSON: { stringify: Type.string.union(Type["undefined"])["function"]().union(Type["undefined"]), parse: Type.string.union(Type.number).union(Type.boolean).union(Type["null"]).union(Type.array).union(Type.object)["function"]().union(Type["undefined"]) },
Date: { UTC: Type.number["function"]().union(Type["undefined"]), now: Type.number["function"]().union(Type["undefined"]) }
};
PRIMORDIAL_INSTANCE_PROPERTIES = {
Object: { toString: Type.string["function"](), toLocaleString: Type.string["function"]() },
String: {
valueOf: Type.string["function"](),
charAt: Type.string["function"](),
charCodeAt: Type.number["function"](),
concat: Type.string["function"](),
indexOf: Type.number["function"](),
lastIndexOf: Type.number["function"](),
localeCompare: Type.number["function"](),
match: Type.array.union(Type["null"])["function"](),
replace: Type.string["function"](),
search: Type.number["function"](),
slice: Type.string["function"](),
split: Type.string.array()["function"](),
substring: Type.string["function"](),
toLowerCase: Type.string["function"](),
toLocaleLowerCase: Type.string["function"](),
toUpperCase: Type.string["function"](),
toLocaleUpperCase: Type.string["function"](),
trim: Type.string["function"](),
length: Type.number
},
Boolean: { valueOf: Type.boolean["function"]() },
Number: { valueOf: Type.number["function"](), toFixed: Type.string["function"](), toExponential: Type.string["function"](), toPrecision: Type.string["function"]() },
Array: {
length: Type.number,
join: Type.string["function"](),
pop: Type.any["function"](),
push: Type.number["function"](),
concat: Type.array["function"](),
reverse: Type.array["function"](),
shift: Type.any["function"](),
unshift: Type.number["function"](),
slice: Type.array["function"](),
splice: Type.array["function"](),
sort: Type.array["function"](),
filter: Type.array["function"]().union(Type["undefined"]),
forEach: Type["undefined"]["function"]().union(Type["undefined"]),
some: Type.boolean["function"]().union(Type["undefined"]),
every: Type.boolean["function"]().union(Type["undefined"]),
map: Type.array["function"]().union(Type["undefined"]),
indexOf: Type.number["function"](),
lastIndexOf: Type.number["function"](),
reduce: Type.any["function"]().union(Type["undefined"]),
reduceRight: Type.any["function"]().union(Type["undefined"])
},
Arguments: { length: Type.number, callee: Type.none, caller: Type.none },
Date: {
toDateString: Type.string["function"](),
toTimeString: Type.string["function"](),
toLocaleDateString: Type.string["function"](),
toLocaleTimeString: Type.string["function"](),
valueOf: Type.number["function"](),
getTime: Type.number["function"](),
getFullYear: Type.number["function"](),
getUTCFullYear: Type.number["function"](),
getMonth: Type.number["function"](),
getUTCMonth: Type.number["function"](),
getDate: Type.number["function"](),
getUTCDate: Type.number["function"](),
getDay: Type.number["function"](),
getUTCDay: Type.number["function"](),
getHours: Type.number["function"](),
getUTCHours: Type.number["function"](),
getMinutes: Type.number["function"](),
getUTCMinutes: Type.number["function"](),
getSeconds: Type.number["function"](),
getUTCSeconds: Type.number["function"](),
getMilliseconds: Type.number["function"](),
getUTCMilliseconds: Type.number["function"](),
getTimezoneOffset: Type.number["function"](),
setTime: Type.number["function"](),
setMilliseconds: Type.number["function"](),
setUTCMilliseconds: Type.number["function"](),
setSeconds: Type.number["function"](),
setUTCSeconds: Type.number["function"](),
setMinutes: Type.number["function"](),
setUTCMinutes: Type.number["function"](),
setHours: Type.number["function"](),
setUTCHours: Type.number["function"](),
setDate: Type.number["function"](),
setUTCDate: Type.number["function"](),
setMonth: Type.number["function"](),
setUTCMonth: Type.number["function"](),
setFullYear: Type.number["function"](),
setUTCFullYear: Type.number["function"](),
toUTCString: Type.string["function"](),
toISOString: Type.string["function"](),
toJSON: Type.string["function"]()
},
RegExp: {
exec: Type.array.union(Type["null"])["function"](),
test: Type.boolean["function"](),
global: Type.boolean,
ignoreCase: Type.boolean,
multiline: Type.boolean,
sticky: Type.boolean.union(Type["undefined"])
},
Error: { name: Type.string, message: Type.string, stack: Type.any }
};
cache = Cache();
return function (call, parser) {
var _value;
_value = cache.get(call);
if (_value === void 0) {
_value = (function () {
var _ref, child, childValue, methodGroup, parent, parentType,
propertyTypes, type;
_ref = call.args;
parent = _ref[0];
child = _ref[1];
_ref = null;
if (parser) {
child = parser.macroExpand1(child).reduce(parser);
}
parentType = parent.type(parser);
if (child.isConst()) {
childValue = child.constValue();
if (parent instanceof Ident && __owns.call(PRIMORDIAL_STATIC_PROPERTIES, parent.name)) {
propertyTypes = PRIMORDIAL_STATIC_PROPERTIES[parent.name];
if (__owns.call(propertyTypes, childValue)) {
return propertyTypes[childValue];
}
}
if (parentType.isSubsetOf(Type.string)) {
methodGroup = PRIMORDIAL_INSTANCE_PROPERTIES.String;
} else if (parentType.isSubsetOf(Type.boolean)) {
methodGroup = PRIMORDIAL_INSTANCE_PROPERTIES.Boolean;
} else if (parentType.isSubsetOf(Type.number)) {
methodGroup = PRIMORDIAL_INSTANCE_PROPERTIES.Number;
} else if (parentType.isSubsetOf(Type.array)) {
methodGroup = PRIMORDIAL_INSTANCE_PROPERTIES.Array;
} else if (parentType.isSubsetOf(Type.date)) {
methodGroup = PRIMORDIAL_INSTANCE_PROPERTIES.Date;
} else if (parentType.isSubsetOf(Type.regexp)) {
methodGroup = PRIMORDIAL_INSTANCE_PROPERTIES.RegExp;
} else if (parentType.isSubsetOf(Type.error)) {
methodGroup = PRIMORDIAL_INSTANCE_PROPERTIES.Error;
}
if (methodGroup && __owns.call(methodGroup, childValue)) {
return methodGroup[childValue];
}
if (__owns.call(PRIMORDIAL_INSTANCE_PROPERTIES.Object, childValue)) {
return PRIMORDIAL_INSTANCE_PROPERTIES.Object[childValue];
}
if (parentType.isSubsetOf(Type.object) && typeof parentType.value === "function") {
type = parentType.value(String(child.constValue()));
if (type !== Type.any) {
return type;
}
}
}
if (child.type(parser).isSubsetOf(Type.number)) {
if (parentType.isSubsetOf(Type.string)) {
return Type.string.union(Type["undefined"]);
}
if (parentType.subtype && parentType.isSubsetOf(Type.array)) {
return parentType.subtype;
}
}
return Type.any;
}());
cache.set(call, _value);
}
return _value;
};
}()),
__reduce: function (call, parser) {
var _arr, _i, _len, _ref, args, cachedParent, child, cValue, end,
hasEnd, hasStep, inclusive, pair, parent, pValue, start, step,
value;
parent = call.args[0];
cachedParent = null;
function replaceLengthIdent(node) {
if (node instanceof Ident && node.name === "__currentArrayLength") {
if (parent.cacheable && cachedParent == null) {
cachedParent = parser.makeTmp(node.index, "ref", parent.type(parser));
cachedParent.scope = node.scope;
}
return Call(
node.index,
node.scope,
Symbol.access(node.index),
cachedParent != null ? cachedParent : parent,
Value(node.index, "length")
);
} else if (node instanceof Node && node.isInternalCall("access")) {
return node;
} else {
return node.walk(replaceLengthIdent);
}
}
child = replaceLengthIdent(call.args[1].reduce(parser));
if (cachedParent != null) {
return Call(
call.index,
call.scope,
Symbol.tmpWrapper(call.index),
Call(
call.index,
call.scope,
Symbol.access(call.index),
Call(
call.index,
call.scope,
Symbol.assign["="](call.index),
cachedParent,
parent
),
child
),
Value(call.index, cachedParent.id)
);
}
if (parent.isLiteral() && child.isConst()) {
cValue = child.constValue();
if (parent.isConst()) {
pValue = parent.constValue();
if (cValue in Object(pValue)) {
value = pValue[cValue];
if (value === null || (_ref = typeof value) === "string" || _ref === "number" || _ref === "boolean" || _ref === "undefined") {
return Value(call.index, value);
}
}
} else if (parent instanceof Node && parent.isInternalCall()) {
if (parent.func.isArray) {
if (cValue === "length") {
return Value(this.index, parent.args.length);
} else if (typeof cValue === "number") {
return parent.args[cValue] || Value(this.index, void 0);
}
} else if (parent.func.isObject) {
for (_arr = __toArray(parent.args), _i = 1, _len = _arr.length; _i < _len; ++_i) {
pair = _arr[_i];
if (pair.args[0].isConstValue(cValue) && !pair.args[2]) {
return pair.args[1];
}
}
}
}
}
if (child instanceof Call && child.func instanceof Ident && child.func.name === "__range") {
_ref = child.args;
start = _ref[0];
end = _ref[1];
step = _ref[2];
inclusive = _ref[3];
_ref = null;
hasStep = !step.isConst() || step.constValue() !== 1;
if (!hasStep) {
if (inclusive.isConst()) {
if (inclusive.constValue()) {
if (end.isConst() && typeof end.constValue() === "number") {
end = Value(end.index, +end.constValue() + 1 || 1/0);
} else {
end = Call(
end.index,
end.scope,
Symbol.binary["||"](end.index),
Call(
end.index,
end.scope,
Symbol.binary["+"](end.index),
end,
Value(inclusive.index, 1)
),
Value(end.index, 1/0)
);
}
}
} else {
end = Call(
end.index,
end.scope,
Symbol["if"](end.index),
inclusive,
Call(
end.index,
end.scope,
Symbol.binary["||"](end.index),
Call(
end.index,
end.scope,
Symbol.binary["+"](end.index),
end,
Value(inclusive.index, 1)
),
Value(end.index, 1/0)
),
end
);
}
}
args = [parent];
hasEnd = !end.isConst() || (_ref = end.constValue()) !== void 0 && _ref !== 1/0;
if (!start.isConst() || start.constValue() !== 0 || hasEnd || hasStep) {
args.push(start);
}
if (hasEnd || hasStep) {
args.push(end);
}
if (hasStep) {
args.push(step);
if (!inclusive.isConst() || inclusive.constValue()) {
args.push(inclusive);
}
}
if (hasStep) {
return Call.apply(void 0, [
call.index,
call.scope,
Ident(call.index, call.scope, "__sliceStep")
].concat(args)).reduce(parser);
} else {
return Call.apply(void 0, [
call.index,
call.scope,
Symbol.contextCall(call.index),
Ident(call.index, call.scope, "__slice")
].concat(args)).reduce(parser);
}
} else if (child !== call.args[1]) {
return Call(
call.index,
call.scope,
call.func,
parent,
child
);
}
},
___reduce: (function () {
var PURE_PRIMORDIAL_SUBFUNCTIONS;
PURE_PRIMORDIAL_SUBFUNCTIONS = {
String: { fromCharCode: true },
Number: { isFinite: true, isNaN: true },
Math: {
abs: true,
acos: true,
asin: true,
atan: true,
atan2: true,
ceil: true,
cos: true,
exp: true,
floor: true,
log: true,
max: true,
min: true,
pow: true,
round: true,
sin: true,
sqrt: true,
tan: true
},
JSON: { parse: true, stringify: true }
};
return function (access, call, parser) {
var _arr, _i, _len, _ref, arg, child, childValue, constArgs,
parent, parentValue, value;
_ref = access.args;
parent = _ref[0];
child = _ref[1];
_ref = null;
if (child.isConst()) {
constArgs = [];
for (_arr = __toArray(call.args), _i = 0, _len = _arr.length; _i < _len; ++_i) {
arg = _arr[_i];
if (arg.isConst()) {
constArgs.push(arg.constValue());
} else {
return;
}
}
childValue = child.constValue();
if (parent.isConst()) {
parentValue = parent.constValue();
if (typeof parentValue[childValue] === "function") {
try {
value = parentValue[childValue].apply(parentValue, constArgs);
} catch (_err) {
return;
}
if (isPrimitive(value)) {
return Value(call.index, value);
}
}
} else if (parent instanceof Ident && __owns.call(PURE_PRIMORDIAL_SUBFUNCTIONS, parent.name) && __owns.call(PURE_PRIMORDIAL_SUBFUNCTIONS[parent.name], childValue)) {
try {
value = (_ref = GLOBAL[parent.name])[childValue].apply(_ref, constArgs);
} catch (_err) {
return;
}
if (isPrimitive(value)) {
return Value(call.index, value);
}
}
}
};
}()),
_isNoop: (function () {
var cache;
cache = Cache();
return function (call, parser) {
var _value;
_value = cache.get(call);
if (_value === void 0) {
_value = call.args[0].isNoop(parser) && call.args[1].isNoop(parser);
cache.set(call, _value);
}
return _value;
};
}())
},
array: {
internalId: 1,
validateArgs: function () {
var args;
args = __slice.call(arguments);
},
_toString: function (call) {
var sb;
sb = [];
sb.push("[");
sb.push(call.args.join(", "));
sb.push("]");
return sb.join("");
},
_type: function () {
return Type.array;
},
_isLiteral: (function () {
var cache;
cache = Cache();
return function (call) {
var _arr, _every, _i, _len, _value, element;
_value = cache.get(call);
if (_value === void 0) {
_every = true;
for (_arr = __toArray(call.args), _i = 0, _len = _arr.length; _i < _len; ++_i) {
element = _arr[_i];
if (!element.isLiteral()) {
_every = false;
break;
}
}
_value = _every;
cache.set(call, _value);
}
return _value;
};
}()),
_literalValue: function (call) {
var _arr, _arr2, _i, _len, element;
_arr = [];
for (_arr2 = __toArray(call.args), _i = 0, _len = _arr2.length; _i < _len; ++_i) {
element = _arr2[_i];
_arr.push(element.literalValue());
}
return _arr;
},
_isNoop: (function () {
var cache;
cache = Cache();
return function (call, parser) {
var _arr, _every, _i, _len, _value, element;
_value = cache.get(call);
if (_value === void 0) {
_every = true;
for (_arr = __toArray(call.args), _i = 0, _len = _arr.length; _i < _len; ++_i) {
element = _arr[_i];
if (!element.isNoop(parser)) {
_every = false;
break;
}
}
_value = _every;
cache.set(call, _value);
}
return _value;
};
}())
},
autoReturn: {
internalId: 2,
doWrapArgs: false,
validateArgs: function (node) {
var rest;
rest = __slice.call(arguments, 1);
},
isGoto: true,
usedAsStatement: true,
_returnType: function (call, parser, isLast) {
return call.args[0].returnType(parser, false).union(call.args[0].type(parser));
}
},
block: {
internalId: 3,
doWrapArgs: false,
_type: (function () {
var cache;
cache = Cache();
return function (call, parser) {
var _value;
_value = cache.get(call);
if (_value === void 0) {
_value = (function () {
var _arr, _end, _i, _len, args, node;
args = call.args;
if (args.length === 0) {
return Type["undefined"];
} else {
for (_arr = __toArray(args), _i = 0, _len = _arr.length, _end = -1, _end += _len, _end > _len && (_end = _len); _i < _end; ++_i) {
node = _arr[_i];
node.type(parser);
}
return args[args.length - 1].type(parser);
}
}());
cache.set(call, _value);
}
return _value;
};
}()),
_returnType: function (call, parser, isLast) {
var _arr, arg, current, i, len;
current = Type.none;
for (_arr = __toArray(call.args), i = 0, len = _arr.length; i < len; ++i) {
arg = _arr[i];
current = current.union(arg.returnType(parser, isLast && i === len - 1));
}
return current;
},
_withLabel: function (call, label, parser) {
var args, last, len;
args = call.args;
len = args.length;
if (len === 1) {
return args[0].withLabel(label(parser));
} else if (len > 1) {
last = args[len - 1];
if (last instanceof Node && last.isInternalCall("forIn") && (function () {
var _arr, _end, _every, _i, _len, node;
_every = true;
for (_arr = __toArray(args), _i = 0, _len = _arr.length, _end = -1, _end += _len, _end > _len && (_end = _len); _i < _end; ++_i) {
node = _arr[_i];
if (!(node instanceof Node) || !node.isInternalCall("var") && !node.isAssignCall()) {
_every = false;
break;
}
}
return _every;
}())) {
return Call.apply(void 0, [call.index, call.scope, call.func].concat(
__toArray(__slice.call(args, 0, -1)),
[last.withLabel(label, parser)]
));
}
}
return Call(
call.index,
call.scope,
Symbol.label(call.index),
label,
call
);
},
__reduce: (function () {
function squishBody(body) {
var changed, current, i, previous;
changed = false;
for (i = body.length - 1; i > 0; --i) {
current = body[i];
previous = body[i - 1];
if (previous.isAssignCall("=") && (!previous.args[0].isIdentOrTmp || !!previous.scope.isMutable(previous.args[0]) || !previous.args[1].isInternalCall("function"))) {
if (previous.args[0].equals(current)) {
if (!changed) {
body = body.slice();
changed = true;
}
body.splice(i, 1);
} else if (current.isAssignCall() && previous.args[0].equals(current.args[1]) && (!current.args[0].isInternalCall("access") || !current.args[0].args[0].equals(previous.args[0]))) {
if (!changed) {
body = body.slice();
changed = true;
}
body.splice(i - 1, 2, Call(
current.index,
current.scope,
current.func,
current.args[0],
previous
));
}
}
}
return body;
}
return function (call, parser) {
var _arr, args, body, changed, i, len, newBody, node;
changed = false;
body = [];
args = call.args;
for (_arr = __toArray(args), i = 0, len = _arr.length; i < len; ++i) {
node = _arr[i];
if (node instanceof Symbol.nothing || i < len - 1 && node.isConst()) {
changed = true;
} else if (node instanceof Node && node.isInternalCall()) {
if (node.func.isBlock) {
body.push.apply(body, __toArray(node.args));
changed = true;
} else if (node.func.isGoto) {
body.push(node);
if (i < len - 1) {
changed = true;
}
break;
} else {
body.push(node);
}
} else {
body.push(node);
}
}
newBody = squishBody(body);
if (newBody !== body) {
changed = true;
body = newBody;
}
switch (body.length) {
case 0: return Symbol.nothing(this.index);
case 1: return body[0];
default:
if (changed) {
return Call.apply(void 0, [this.index, this.scope, call.func].concat(body));
} else {
return;
}
}
};
}()),
_isStatement: (function () {
var cache;
cache = Cache();
return function (call) {
var _arr, _i, _len, _some, _value, node;
_value = cache.get(call);
if (_value === void 0) {
_some = false;
for (_arr = __toArray(call.args), _i = 0, _len = _arr.length; _i < _len; ++_i) {
node = _arr[_i];
if (node.isStatement()) {
_some = true;
break;
}
}
_value = _some;
cache.set(call, _value);
}
return _value;
};
}()),
_mutateLast: function (call, parser, func, context, includeNoop) {
var args, lastNode, len;
args = call.args;
len = args.length;
if (len === 0) {
return Symbol.nothing(this.index).mutateLast(parser, func, context, includeNoop);
} else {
lastNode = args[len - 1].mutateLast(parser, func, context, includeNoop);
if (lastNode !== args[len - 1]) {
return Call.apply(void 0, [this.index, this.scope, call.func].concat(
__toArray(__slice.call(args, 0, -1)),
[lastNode]
));
} else {
return call;
}
}
},
_isNoop: (function () {
var cache;
cache = Cache();
return function (call, parser) {
var _arr, _every, _i, _len, _value, node;
_value = cache.get(call);
if (_value === void 0) {
_every = true;
for (_arr = __toArray(call.args), _i = 0, _len = _arr.length; _i < _len; ++_i) {
node = _arr[_i];
if (!node.isNoop(parser)) {
_every = false;
break;
}
}
_value = _every;
cache.set(call, _value);
}
return _value;
};
}())
},
"break": {
internalId: 4,
doWrapArgs: false,
validateArgs: function (label) {
var rest;
if (label == null) {
label = null;
}
rest = __slice.call(arguments, 1);
},
isGoto: true,
usedAsStatement: true
},
comment: {
internalId: 5,
doWrapArgs: false,
validateArgs: function (text) {
var rest;
rest = __slice.call(arguments, 1);
}
},
contextCall: {
internalId: 6,
validateArgs: function (func, context) {},
_type: function (call, parser) {
var fakeCall, func;
func = call.args[0];
if (typeof func._type === "function") {
fakeCall = Call.apply(void 0, [call.index, call.scope].concat(__toArray(call.args)));
return func._type(fakeCall, parser);
} else {
return Type.any;
}
}
},
"continue": {
internalId: 7,
doWrapArgs: false,
validateArgs: function (label) {
var rest;
if (label == null) {
label = null;
}
rest = __slice.call(arguments, 1);
},
isGoto: true,
usedAsStatement: true
},
custom: {
internalId: 8,
doWrapArgs: false,
validateArgs: function (name) {
var rest;
rest = __slice.call(arguments, 1);
}
},
"debugger": {
internalId: 9,
doWrapArgs: false,
validateArgs: function () {
var rest;
rest = __slice.call(arguments);
},
usedAsStatement: true
},
embedWrite: {
internalId: 10,
doWrapArgs: false,
validateArgs: function (text, escape) {
var rest;
rest = __slice.call(arguments, 2);
}
},
"for": {
internalId: 11,