#reader"../lang/reader.ss" import file("../private/runtime/value.ss").{ 'object-class': objectClass, 'has-own-property?' : hasOwnProperty, 'object-proto' : objectProto, 'object?' : isObject, 'object-get-attributes' : objectGetAttributes, 'bit-flag-set?' : isBitFlagSet, 'DONT-ENUM?' : DONT_ENUM, 'proto:Function' : proto_Function, 'proto:Array' : proto_Array, 'new-Array' : newArray, 'object-get' : get, 'object-put!' : put, 'object-delete!' : del, 'any->uint32' : ToUint32, 'any->string' : ToString, 'any->integer' : ToInteger, 'any->property-name' : ToName, 'any->object' : ToObject, 'has-property?' : HasProperty }; import scheme/base.{ 'eq?' : schemeEq, 'display' : schemeDisplay, 'write' : schemeWrite, 'void' : schemeVoid, 'build-list' : schemeBuildList, 'values' : schemeValues, 'map' : schemeMap, 'floor' : schemeFloor, 'max' : schemeMax, 'min' : schemeMin }; import scheme/string.{ 'string-join' : stringJoin }; /* private */ var undefined = void(0); var Object = { toString : function() { return "[object " + objectClass(this) + "]"; }, toLocaleString : function() { return this.toString(); }, valueOf : function() { return this }, hasOwnProperty : function(x) { return hasOwnProperty(this, ToName(x)) }, isPrototypeOf : function(x) { if (!isObject(x)) return false; do { if (schemeEq(this, x)) return true; x = objectProto(x); } while (x); return false; }, propertyIsEnumerable : function(key) { var attributes = objectGetAttributes(this, key); return attributes && isBitFlagSet(attributes, DONT_ENUM); } }; /* private */ function ensureInstance(object, proto, expected) { if (!proto.isPrototypeOf(object)) throw ("expected " + expected + ", receieved object"); } var Function = { toString : function() { ensureInstance(this, proto_Function, "function"); return "[object Function]"; }, apply : function(obj, args) { throw "not yet implemented" }, call : function(obj) { throw "not yet implemented" } }; /* private */ function arrayLength(a) { return get(this, 'length', {|| => 0 }, ToUint32); } /* private */ function mapN(len, f) { schemeMap(f, schemeBuildList(len, schemeValues)); } var Array = { write : function(out) { var length = arrayLength(this); for (var i = 0; i < length; i++) { if (i > 0) schemeDisplay(',', out); get(this, ToName(i), schemeVoid, {|x| schemeWrite(x, out) }); } }, display : function(out) { var length = arrayLength(this); for (var i = 0; i < length; i++) { if (i > 0) schemeDisplay(',', out); get(this, ToName(i), schemeVoid, {|x| schemeDisplay(x, out) }); } }, // 15.4.4.2 toString : function() { var length = arrayLength(this); var result = ""; for (var i = 0; i < length; i++) { if (i > 0) result += ","; result += get(this, ToName(i), {|| => ""}, ToString); } return result; }, // 15.4.4.3 toLocaleString : function() { ensureInstance(this, proto_Array, "array"); var length = arrayLength(this); var result = ""; for (var i = 0; i < length; i++) { if (i > 0) result += ","; result += get(this, ToName(i), {|| => ""}, {|v| => ToObject(v).toLocaleString() }); } return result; }, // 15.4.4.4 concat : function(a1) { var A = newArray(); var k, n = 0; for (k = 0; k < this.length; k++, n++) { var Result8 = ToName(k); if (HasProperty(this, Result8)) put(A, ToName(n), this[Result8]); } for (var i = 0; i < arguments.length; i++) { var E = arguments[i]; for (var k = 0; k < E.length; k++, n++) { var Result8 = ToName(k); if (HasProperty(this, Result8)) put(A, ToName(n), E[Result8]); } } return A; }, // 15.4.4.5 join : function(separator) { if (separator === undefined || separator === null) separator = ','; var self = this; return stringJoin(mapN(this.length, {|i| get(self, ToName(i), {|| => ""}, {|v| => (v === undefined || v === null) ? "" : ToString(v) }) }), separator); }, // 15.4.4.6 pop : function() { var length = arrayLength(this); if (length === 0) { this.length = length; return undefined; } var key = ToName(length - 1); var val = get(this, key, schemeVoid); del(this, key); put(this, 'length', length - 1); return val; }, // 15.4.4.7 push : function(first) { var length = arrayLength(this); var newLength = length + arguments.length; for (var i = 0; i < arguments.length; i++) { put(this, ToName(i + length), arguments[i]); } put(this, 'length', newLength); return newLength; }, // 15.4.4.8 reverse : function() { var length = arrayLength(this); var half = schemeFloor(length / 2); for (var left = 0; left < half; left++) { var right = length - left - 1; var leftKey = ToName(left); var rightKey = ToName(right); get(this, leftKey, {|| get(this, rightKey, {|| del(this, leftKey); del(this, rightKey) }, {|rightVal| del(this, rightKey); put(this, leftKey, rightVal) })}, {|leftVal| get(this, rightKey, {|| put(this, rightKey, leftVal); del(this, rightKey) }, {|rightVal| put(this, leftKey, rightVal); put(this, rightKey, leftVal) }) }); } }, // 15.4.4.9 shift : function() { var length = arrayLength(this); if (length === 0) { put(this, 'length', length); return undefined; } var removed = get(this, '0'); for (var k = 0; k < length; k++) { var kKey = ToName(k); var kMinus1Key = ToName(k - 1); get(this, kKey, {|| del(this, kMinus1Key)}, {|val| put(this, kMinus1Key, val)}); } del(this, ToName(length - 1)); put(this, 'length', length - 1); return removed; }, // 15.4.4.10 slice : function(start, end) { var length = arrayLength(this); var A = newArray(); var ToIndex = {|x| let i = ToInteger(x); => (i < 0) ? schemeMax(i + length, 0) : schemeMin(i, length)}; start = ToIndex(start); end = ToIndex(end); var k, n; for (k = start, n = 0; k < end; k++, n++) { var kKey = ToName(k); if (HasProperty(this, kKey)) { put(A, ToName(n), get(this, kKey)); } } put(A, 'length', n); return A; }, // 15.4.4.11 sort : function(comparefn) { }, // 15.4.4.12 splice : function(start, deleteCount) { }, // 15.4.4.13 unshift : function(first) { } };