diff --git a/js-assembler/get-runtime.rkt b/js-assembler/get-runtime.rkt index 1a75ba2..a60412e 100644 --- a/js-assembler/get-runtime.rkt +++ b/js-assembler/get-runtime.rkt @@ -36,6 +36,7 @@ (define-runtime-path baselib.js "runtime-src/baselib.js") (define-runtime-path baselib_unionfind.js "runtime-src/baselib_unionfind.js") +(define-runtime-path baselib_equality.js "runtime-src/baselib_equality.js") (define-runtime-path baselib_hash.js "runtime-src/baselib_hash.js") (define-runtime-path baselib_symbol.js "runtime-src/baselib_symbol.js") (define-runtime-path baselib_structs.js "runtime-src/baselib_structs.js") @@ -43,8 +44,11 @@ (define-runtime-path baselib_inspectors.js "runtime-src/baselib_inspectors.js") (define-runtime-path baselib_exceptions.js "runtime-src/baselib_exceptions.js") (define-runtime-path baselib_format.js "runtime-src/baselib_format.js") +(define-runtime-path baselib_chars.js "runtime-src/baselib_chars.js") (define-runtime-path baselib_strings.js "runtime-src/baselib_strings.js") (define-runtime-path baselib_bytes.js "runtime-src/baselib_bytes.js") +(define-runtime-path baselib_readergraph.js "runtime-src/baselib_readergraph.js") + (define-runtime-path jshashtable.js "runtime-src/jshashtable-2.1_src.js") @@ -74,6 +78,7 @@ baselib.js baselib_unionfind.js + baselib_equality.js baselib_hash.js baselib_format.js baselib_symbol.js @@ -81,8 +86,10 @@ baselib_arity.js baselib_inspectors.js baselib_exceptions.js + baselib_chars.js baselib_strings.js baselib_bytes.js + baselib_readergraph.js link.js helpers.js diff --git a/js-assembler/runtime-src/baselib_chars.js b/js-assembler/runtime-src/baselib_chars.js new file mode 100644 index 0000000..9b42db8 --- /dev/null +++ b/js-assembler/runtime-src/baselib_chars.js @@ -0,0 +1,75 @@ +// Single characters +(function(baselib) { + var exports = {}; + baselib.chars = exports; + + + // Chars + // Char: string -> Char + Char = function(val){ + this.val = val; + }; + // The characters less than 256 must be eq?, according to the + // documentation: + // http://docs.racket-lang.org/reference/characters.html + var _CharCache = {}; + for (var i = 0; i < 256; i++) { + _CharCache[String.fromCharCode(i)] = new Char(String.fromCharCode(i)); + } + + // makeInstance: 1-character string -> Char + Char.makeInstance = function(val){ + if (_CharCache[val]) { + return _CharCache[val]; + } + return new Char(val); + }; + + Char.prototype.toString = function(cache) { + var code = this.val.charCodeAt(0); + var returnVal; + switch (code) { + case 0: returnVal = '#\\nul'; break; + case 8: returnVal = '#\\backspace'; break; + case 9: returnVal = '#\\tab'; break; + case 10: returnVal = '#\\newline'; break; + case 11: returnVal = '#\\vtab'; break; + case 12: returnVal = '#\\page'; break; + case 13: returnVal = '#\\return'; break; + case 20: returnVal = '#\\space'; break; + case 127: returnVal = '#\\rubout'; break; + default: if (code >= 32 && code <= 126) { + returnVal = ("#\\" + this.val); + } + else { + var numStr = code.toString(16).toUpperCase(); + while (numStr.length < 4) { + numStr = '0' + numStr; + } + returnVal = ('#\\u' + numStr); + } + break; + } + return returnVal; + }; + + Char.prototype.toWrittenString = Char.prototype.toString; + + Char.prototype.toDisplayedString = function (cache) { + return this.val; + }; + + Char.prototype.getValue = function() { + return this.val; + }; + + Char.prototype.equals = function(other, aUnionFind){ + return other instanceof Char && this.val == other.val; + }; + + + + + exports.Char = Char; + +})(this['plt'].baselib); \ No newline at end of file diff --git a/js-assembler/runtime-src/baselib_equality.js b/js-assembler/runtime-src/baselib_equality.js new file mode 100644 index 0000000..0713a52 --- /dev/null +++ b/js-assembler/runtime-src/baselib_equality.js @@ -0,0 +1,47 @@ +// Equality function +(function(baselib) { + var exports = {}; + baselib.equality = exports; + + + // equals: X Y -> boolean + // Returns true if the objects are equivalent; otherwise, returns false. + var equals = function(x, y, aUnionFind) { + if (x === y) { return true; } + + if (isNumber(x) && isNumber(y)) { + return jsnums.eqv(x, y); + } + + if (isString(x) && isString(y)) { + return x.toString() === y.toString(); + } + + if (x == undefined || x == null) { + return (y == undefined || y == null); + } + + if ( typeof(x) == 'object' && + typeof(y) == 'object' && + x.equals && + y.equals) { + + if (typeof (aUnionFind) === 'undefined') { + aUnionFind = new plt.baselib.UnionFind(); + } + + if (aUnionFind.find(x) === aUnionFind.find(y)) { + return true; + } + else { + aUnionFind.merge(x, y); + return x.equals(y, aUnionFind); + } + } + return false; + }; + + + exports.equals = equals; + +})(this['plt'].baselib); \ No newline at end of file diff --git a/js-assembler/runtime-src/baselib_hash.js b/js-assembler/runtime-src/baselib_hash.js index 3bc39e2..53cd4cc 100644 --- a/js-assembler/runtime-src/baselib_hash.js +++ b/js-assembler/runtime-src/baselib_hash.js @@ -1,8 +1,8 @@ (function(baselib) { - var hash = {}; + var exports = {}; - baselib.hash = hash; + baselib.hash = exports; @@ -43,9 +43,150 @@ - hash.getEqHashCode = getEqHashCode; - hash.makeEqHashCode = makeEqHashCode; - hash.makeLowLevelEqHash = makeLowLevelEqHash; + + + + + + + + ////////////////////////////////////////////////////////////////////// + // Eq Hashtables + var EqHashTable = function(inputHash) { + this.hash = makeLowLevelEqHash(); + this.mutable = true; + + }; + + EqHashTable.prototype.toWrittenString = function(cache) { + var keys = this.hash.keys(); + var ret = []; + for (var i = 0; i < keys.length; i++) { + var keyStr = toWrittenString(keys[i], cache); + var valStr = toWrittenString(this.hash.get(keys[i]), cache); + ret.push('(' + keyStr + ' . ' + valStr + ')'); + } + return ('#hasheq(' + ret.join(' ') + ')'); + }; + + EqHashTable.prototype.toDisplayedString = function(cache) { + var keys = this.hash.keys(); + var ret = []; + for (var i = 0; i < keys.length; i++) { + var keyStr = toDisplayedString(keys[i], cache); + var valStr = toDisplayedString(this.hash.get(keys[i]), cache); + ret.push('(' + keyStr + ' . ' + valStr + ')'); + } + return ('#hasheq(' + ret.join(' ') + ')'); + }; + + EqHashTable.prototype.equals = function(other, aUnionFind) { + if ( !(other instanceof EqHashTable) ) { + return false; + } + + if (this.hash.keys().length != other.hash.keys().length) { + return false; + } + + var keys = this.hash.keys(); + for (var i = 0; i < keys.length; i++){ + if ( !(other.hash.containsKey(keys[i]) && + plt.baselib.equality.equals(this.hash.get(keys[i]), + other.hash.get(keys[i]), + aUnionFind)) ) { + return false; + } + } + return true; + }; + + + + ////////////////////////////////////////////////////////////////////// + // Equal hash tables + var EqualHashTable = function(inputHash) { + this.hash = new _Hashtable( + function(x) { + return plt.baselib.format.toWrittenString(x); + }, + function(x, y) { + return plt.baselib.equality.equals(x, y, new plt.baselib.UnionFind()); + }); + this.mutable = true; + }; + + EqualHashTable.prototype.toWrittenString = function(cache) { + var keys = this.hash.keys(); + var ret = []; + for (var i = 0; i < keys.length; i++) { + var keyStr = plt.baselib.format.toWrittenString(keys[i], cache); + var valStr = plt.baselib.format.toWrittenString(this.hash.get(keys[i]), cache); + ret.push('(' + keyStr + ' . ' + valStr + ')'); + } + return ('#hash(' + ret.join(' ') + ')'); + }; + EqualHashTable.prototype.toDisplayedString = function(cache) { + var keys = this.hash.keys(); + var ret = []; + for (var i = 0; i < keys.length; i++) { + var keyStr = plt.baselib.format.toDisplayedString(keys[i], cache); + var valStr = plt.baselib.format.toDisplayedString(this.hash.get(keys[i]), cache); + ret.push('(' + keyStr + ' . ' + valStr + ')'); + } + return ('#hash(' + ret.join(' ') + ')'); + }; + + EqualHashTable.prototype.equals = function(other, aUnionFind) { + if ( !(other instanceof EqualHashTable) ) { + return false; + } + + if (this.hash.keys().length != other.hash.keys().length) { + return false; + } + + var keys = this.hash.keys(); + for (var i = 0; i < keys.length; i++){ + if (! (other.hash.containsKey(keys[i]) && + plt.baselib.equality.equals(this.hash.get(keys[i]), + other.hash.get(keys[i]), + aUnionFind))) { + return false; + } + } + return true; + }; + + + + + + + + + + + + + + + + + + + + + + + + exports.getEqHashCode = getEqHashCode; + exports.makeEqHashCode = makeEqHashCode; + exports.makeLowLevelEqHash = makeLowLevelEqHash; + + + exports.EqualHashTable = EqualHashTable; + exports.EqHashTable = EqHashTable; diff --git a/js-assembler/runtime-src/baselib_readergraph.js b/js-assembler/runtime-src/baselib_readergraph.js new file mode 100644 index 0000000..5d3f9ba --- /dev/null +++ b/js-assembler/runtime-src/baselib_readergraph.js @@ -0,0 +1,59 @@ +// Arity structure +(function(baselib) { + var exports = {}; + baselib.readergraph = exports; + + + var readerGraph = function(x, objectHash, n) { + if (typeof(x) === 'object' && objectHash.containsKey(x)) { + return objectHash.get(x); + } + + if (types.isPair(x)) { + var consPair = types.cons(x.first, x.rest); + objectHash.put(x, consPair); + consPair.f = readerGraph(x.first, objectHash, n+1); + consPair.r = readerGraph(x.rest, objectHash, n+1); + return consPair; + } + + if (types.isVector(x)) { + var len = x.length(); + var aVector = types.vector(len, x.elts); + objectHash.put(x, aVector); + for (var i = 0; i < len; i++) { + aVector.elts[i] = readerGraph(aVector.elts[i], objectHash, n+1); + } + return aVector; + } + + if (types.isBox(x)) { + var aBox = types.box(x.ref()); + objectHash.put(x, aBox); + aBox.val = readerGraph(x.ref(), objectHash, n+1); + return aBox; + } + + if (types.isHash(x)) { + throw new Error("make-reader-graph of hash not implemented yet"); + } + + if (types.isStruct(x)) { + var aStruct = helpers.clone(x); + objectHash.put(x, aStruct); + for(var i = 0 ;i < x._fields.length; i++) { + x._fields[i] = readerGraph(x._fields[i], objectHash, n+1); + } + return aStruct; + } + + if (types.isPlaceholder(x)) { + return readerGraph(x.ref(), objectHash, n+1); + } + + return x; + }; + + exports.readerGraph = readerGraph; + +})(this['plt'].baselib); \ No newline at end of file diff --git a/js-assembler/runtime-src/types.js b/js-assembler/runtime-src/types.js index f2d2dbc..607a183 100644 --- a/js-assembler/runtime-src/types.js +++ b/js-assembler/runtime-src/types.js @@ -25,7 +25,6 @@ if (! this['plt']) { this['plt'] = {}; } // makeLowLevelEqHash: -> hashtable // Constructs an eq hashtable that uses Moby's getEqHashCode function. var makeLowLevelEqHash = plt.baselib.hash.makeLowLevelEqHash; - var toWrittenString = plt.baselib.format.toWrittenString; var toDisplayedString = plt.baselib.format.toDisplayedString; var toDomNode = plt.baselib.format.toDomNode; @@ -195,69 +194,6 @@ if (! this['plt']) { this['plt'] = {}; } - // Chars - // Char: string -> Char - Char = function(val){ - this.val = val; - }; - // The characters less than 256 must be eq?, according to the - // documentation: - // http://docs.racket-lang.org/reference/characters.html - var _CharCache = {}; - for (var i = 0; i < 256; i++) { - _CharCache[String.fromCharCode(i)] = new Char(String.fromCharCode(i)); - } - - // makeInstance: 1-character string -> Char - Char.makeInstance = function(val){ - if (_CharCache[val]) { - return _CharCache[val]; - } - return new Char(val); - }; - - Char.prototype.toString = function(cache) { - var code = this.val.charCodeAt(0); - var returnVal; - switch (code) { - case 0: returnVal = '#\\nul'; break; - case 8: returnVal = '#\\backspace'; break; - case 9: returnVal = '#\\tab'; break; - case 10: returnVal = '#\\newline'; break; - case 11: returnVal = '#\\vtab'; break; - case 12: returnVal = '#\\page'; break; - case 13: returnVal = '#\\return'; break; - case 20: returnVal = '#\\space'; break; - case 127: returnVal = '#\\rubout'; break; - default: if (code >= 32 && code <= 126) { - returnVal = ("#\\" + this.val); - } - else { - var numStr = code.toString(16).toUpperCase(); - while (numStr.length < 4) { - numStr = '0' + numStr; - } - returnVal = ('#\\u' + numStr); - } - break; - } - return returnVal; - }; - - Char.prototype.toWrittenString = Char.prototype.toString; - - Char.prototype.toDisplayedString = function (cache) { - return this.val; - }; - - Char.prototype.getValue = function() { - return this.val; - }; - - Char.prototype.equals = function(other, aUnionFind){ - return other instanceof Char && this.val == other.val; - }; - ////////////////////////////////////////////////////////////////////// // Keywords @@ -560,114 +496,6 @@ if (! this['plt']) { this['plt'] = {}; } - ////////////////////////////////////////////////////////////////////// - // Hashtables - var EqHashTable = function(inputHash) { - this.hash = makeLowLevelEqHash(); - this.mutable = true; - - }; - EqHashTable = EqHashTable; - - EqHashTable.prototype.toWrittenString = function(cache) { - var keys = this.hash.keys(); - var ret = []; - for (var i = 0; i < keys.length; i++) { - var keyStr = toWrittenString(keys[i], cache); - var valStr = toWrittenString(this.hash.get(keys[i]), cache); - ret.push('(' + keyStr + ' . ' + valStr + ')'); - } - return ('#hasheq(' + ret.join(' ') + ')'); - }; - - EqHashTable.prototype.toDisplayedString = function(cache) { - var keys = this.hash.keys(); - var ret = []; - for (var i = 0; i < keys.length; i++) { - var keyStr = toDisplayedString(keys[i], cache); - var valStr = toDisplayedString(this.hash.get(keys[i]), cache); - ret.push('(' + keyStr + ' . ' + valStr + ')'); - } - return ('#hasheq(' + ret.join(' ') + ')'); - }; - - EqHashTable.prototype.equals = function(other, aUnionFind) { - if ( !(other instanceof EqHashTable) ) { - return false; - } - - if (this.hash.keys().length != other.hash.keys().length) { - return false; - } - - var keys = this.hash.keys(); - for (var i = 0; i < keys.length; i++){ - if ( !(other.hash.containsKey(keys[i]) && - equals(this.hash.get(keys[i]), - other.hash.get(keys[i]), - aUnionFind)) ) { - return false; - } - } - return true; - }; - - - - var EqualHashTable = function(inputHash) { - this.hash = new _Hashtable(function(x) { - return toWrittenString(x); - }, - function(x, y) { - return equals(x, y, new plt.baselib.UnionFind()); - }); - this.mutable = true; - }; - - EqualHashTable = EqualHashTable; - - EqualHashTable.prototype.toWrittenString = function(cache) { - var keys = this.hash.keys(); - var ret = []; - for (var i = 0; i < keys.length; i++) { - var keyStr = toWrittenString(keys[i], cache); - var valStr = toWrittenString(this.hash.get(keys[i]), cache); - ret.push('(' + keyStr + ' . ' + valStr + ')'); - } - return ('#hash(' + ret.join(' ') + ')'); - }; - EqualHashTable.prototype.toDisplayedString = function(cache) { - var keys = this.hash.keys(); - var ret = []; - for (var i = 0; i < keys.length; i++) { - var keyStr = toDisplayedString(keys[i], cache); - var valStr = toDisplayedString(this.hash.get(keys[i]), cache); - ret.push('(' + keyStr + ' . ' + valStr + ')'); - } - return ('#hash(' + ret.join(' ') + ')'); - }; - - EqualHashTable.prototype.equals = function(other, aUnionFind) { - if ( !(other instanceof EqualHashTable) ) { - return false; - } - - if (this.hash.keys().length != other.hash.keys().length) { - return false; - } - - var keys = this.hash.keys(); - for (var i = 0; i < keys.length; i++){ - if (! (other.hash.containsKey(keys[i]) && - equals(this.hash.get(keys[i]), - other.hash.get(keys[i]), - aUnionFind))) { - return false; - } - } - return true; - }; - ////////////////////////////////////////////////////////////////////// @@ -841,44 +669,8 @@ if (! this['plt']) { this['plt'] = {}; } } - // equals: X Y -> boolean - // Returns true if the objects are equivalent; otherwise, returns false. - var equals = function(x, y, aUnionFind) { - if (x === y) { return true; } - - if (isNumber(x) && isNumber(y)) { - return jsnums.eqv(x, y); - } - - if (isString(x) && isString(y)) { - return x.toString() === y.toString(); - } - - if (x == undefined || x == null) { - return (y == undefined || y == null); - } - - if ( typeof(x) == 'object' && - typeof(y) == 'object' && - x.equals && - y.equals) { - - if (typeof (aUnionFind) === 'undefined') { - aUnionFind = new plt.baselib.UnionFind(); - } - - if (aUnionFind.find(x) === aUnionFind.find(y)) { - return true; - } - else { - aUnionFind.merge(x, y); - return x.equals(y, aUnionFind); - } - } - return false; - }; - + var equals = plt.baselib.equality.equals; @@ -1152,7 +944,7 @@ if (! this['plt']) { this['plt'] = {}; } var makeHashEq = function(lst) { - var newHash = new EqHashTable(); + var newHash = new plt.baselib.hash.EqHashTable(); while ( !isEmpty(lst) ) { newHash.hash.put(lst.first.first, lst.first.rest); lst = lst.rest; @@ -1162,7 +954,7 @@ if (! this['plt']) { this['plt'] = {}; } var makeHashEqual = function(lst) { - var newHash = new EqualHashTable(); + var newHash = new plt.baselib.hash.EqualHashTable(); while ( !isEmpty(lst) ) { newHash.hash.put(lst.first.first, lst.first.rest); lst = lst.rest; @@ -1179,56 +971,6 @@ if (! this['plt']) { this['plt'] = {}; } - var readerGraph = function(x, objectHash, n) { - if (typeof(x) === 'object' && objectHash.containsKey(x)) { - return objectHash.get(x); - } - - if (types.isPair(x)) { - var consPair = types.cons(x.first, x.rest); - objectHash.put(x, consPair); - consPair.f = readerGraph(x.first, objectHash, n+1); - consPair.r = readerGraph(x.rest, objectHash, n+1); - return consPair; - } - - if (types.isVector(x)) { - var len = x.length(); - var aVector = types.vector(len, x.elts); - objectHash.put(x, aVector); - for (var i = 0; i < len; i++) { - aVector.elts[i] = readerGraph(aVector.elts[i], objectHash, n+1); - } - return aVector; - } - - if (types.isBox(x)) { - var aBox = types.box(x.ref()); - objectHash.put(x, aBox); - aBox.val = readerGraph(x.ref(), objectHash, n+1); - return aBox; - } - - if (types.isHash(x)) { - throw new Error("make-reader-graph of hash not implemented yet"); - } - - if (types.isStruct(x)) { - var aStruct = helpers.clone(x); - objectHash.put(x, aStruct); - for(var i = 0 ;i < x._fields.length; i++) { - x._fields[i] = readerGraph(x._fields[i], objectHash, n+1); - } - return aStruct; - } - - if (types.isPlaceholder(x)) { - return readerGraph(x.ref(), objectHash, n+1); - } - - return x; - }; - @@ -1253,7 +995,7 @@ if (! this['plt']) { this['plt'] = {}; } types.vectorImmutable = makeVectorImmutable; types.regexp = function(p) { return new RegularExpression(p) ; } types.byteRegexp = function(p) { return new ByteRegularExpression(p) ; } - types.character = Char.makeInstance; + types.character = plt.baselib.chars.Char.makeInstance; types['string'] = makeString; types.box = function(x) { return new Box(x, true); }; types.placeholder = function(x) { return new Placeholder(x); }; @@ -1292,7 +1034,7 @@ if (! this['plt']) { this['plt'] = {}; } types.isSymbol = function(x) { return x instanceof Symbol; }; - types.isChar = function(x) { return x instanceof Char; }; + types.isChar = function(x) { return x instanceof plt.baselib.chars.Char; }; types.isString = isString; types.isPair = function(x) { return x instanceof Cons; }; types.isList = isList; @@ -1300,8 +1042,8 @@ if (! this['plt']) { this['plt'] = {}; } types.isVector = function(x) { return x instanceof Vector; }; types.isBox = function(x) { return x instanceof Box; }; types.isPlaceholder = function(x) { return x instanceof Placeholder; }; - types.isHash = function(x) { return (x instanceof EqHashTable || - x instanceof EqualHashTable); }; + types.isHash = function(x) { return (x instanceof plt.baselib.hash.EqHashTable || + x instanceof plt.baselib.hash.EqualHashTable); }; types.isByteString = function(x) { return x instanceof plt.baselib.bytes.Bytes; }; types.isStruct = function(x) { return x instanceof Struct; }; types.isColor = Color.predicate; @@ -1399,8 +1141,6 @@ if (! this['plt']) { this['plt'] = {}; } - types.readerGraph = readerGraph; - scope.link.announceReady('types'); })(this['plt']);