From 8117943aaf1b6154d446ce1b46357f3035b2e4e0 Mon Sep 17 00:00:00 2001 From: Danny Yoo Date: Thu, 3 Nov 2011 15:38:47 -0400 Subject: [PATCH] working on getting hashtables in --- js-assembler/runtime-src/baselib-hashes.js | 132 ++++++++---------- .../runtime-src/baselib-primitives.js | 50 ++++++- 2 files changed, 103 insertions(+), 79 deletions(-) diff --git a/js-assembler/runtime-src/baselib-hashes.js b/js-assembler/runtime-src/baselib-hashes.js index 44ce6e5..3d408c2 100644 --- a/js-assembler/runtime-src/baselib-hashes.js +++ b/js-assembler/runtime-src/baselib-hashes.js @@ -2,6 +2,8 @@ /*global Hashtable*/ +// Mutable hashtables. + (function (baselib, Hashtable) { 'use strict'; @@ -14,11 +16,11 @@ var _eqHashCodeCounter = 0; var makeEqHashCode = function () { _eqHashCodeCounter++; - return _eqHashCodeCounter; + return String(_eqHashCodeCounter); }; - // getHashCode: any -> (or fixnum string) + // getHashCode: any -> string // Given a value, produces a hashcode appropriate for eq. var getEqHashCode = function (x) { if (typeof (x) === 'string') { @@ -33,7 +35,7 @@ if (x && x._eqHashCode) { return x._eqHashCode; } - return 0; + return ''; }; @@ -48,22 +50,46 @@ + var makeEqHashtable = function() { + return new WhalesongHashtable( + "hasheq", + function (x) { return getEqHashCode(x); }, + function (x, y) { return x === y; }); + }; - - - + var makeEqualHashtable = function() { + return new WhalesongHashtable( + "hash", + function (x) { + return baselib.format.toWrittenString(x); + }, + function (x, y) { + return baselib.equality.equals(x, y, new baselib.UnionFind()); + }) + }; + + var makeEqvHashtable = function() { + return new WhalesongHashtable( + "hasheqv", + function (x) { + return baselib.format.toWrittenString(x); + }, + baselib.equality.eqv); + }; ////////////////////////////////////////////////////////////////////// - // Eq Hashtables - var EqHashTable = function (inputHash) { - this.hash = makeLowLevelEqHash(); - this.mutable = true; - + // Whalesong's Hashtables are a thin wrapper around the Hashtable + // class to make it printable and equatable. + var WhalesongHashtable = function (type, hash_function, equality_function) { + this.type = type; + this.hash_function = hash_function; + this.equality_function = equality_function; + this.hash = new Hashtable(hash_function, equality_function); }; - EqHashTable.prototype.toWrittenString = function (cache) { + WhalesongHashtable.prototype.toWrittenString = function (cache) { var keys = this.hash.keys(); var ret = [], i; for (i = 0; i < keys.length; i++) { @@ -71,10 +97,10 @@ var valStr = baselib.format.toWrittenString(this.hash.get(keys[i]), cache); ret.push('(' + keyStr + ' . ' + valStr + ')'); } - return ('#hasheq(' + ret.join(' ') + ')'); + return ('#' + this.type + '(' + ret.join(' ') + ')'); }; - EqHashTable.prototype.toDisplayedString = function (cache) { + WhalesongHashtable.prototype.toDisplayedString = function (cache) { var keys = this.hash.keys(); var ret = [], i; for (i = 0; i < keys.length; i++) { @@ -82,14 +108,16 @@ var valStr = baselib.format.toDisplayedString(this.hash.get(keys[i]), cache); ret.push('(' + keyStr + ' . ' + valStr + ')'); } - return ('#hasheq(' + ret.join(' ') + ')'); + return ('#' + this.type + '(' + ret.join(' ') + ')'); }; - EqHashTable.prototype.equals = function (other, aUnionFind) { - if (!(other instanceof EqHashTable)) { + WhalesongHashtable.prototype.equals = function (other, aUnionFind) { + if (!(other instanceof WhalesongHashtable)) { return false; } - + if (other.type !== this.type) { + return false; + } if (this.hash.keys().length !== other.hash.keys().length) { return false; } @@ -106,69 +134,20 @@ return true; }; - - - ////////////////////////////////////////////////////////////////////// - // Equal hash tables - var EqualHashTable = function (inputHash) { - this.hash = new Hashtable( - function (x) { - return baselib.format.toWrittenString(x); - }, - function (x, y) { - return baselib.equality.equals(x, y, new baselib.UnionFind()); - }); - this.mutable = true; + WhalesongHashtable.prototype.ref = function(key) { + return this.hash.get(key); }; - EqualHashTable.prototype.toWrittenString = function (cache) { - var keys = this.hash.keys(); - var ret = [], i; - for (i = 0; i < keys.length; i++) { - var keyStr = baselib.format.toWrittenString(keys[i], cache); - var valStr = 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 = [], i; - for (i = 0; i < keys.length; i++) { - var keyStr = baselib.format.toDisplayedString(keys[i], cache); - var valStr = baselib.format.toDisplayedString(this.hash.get(keys[i]), cache); - ret.push('(' + keyStr + ' . ' + valStr + ')'); - } - return ('#hash(' + ret.join(' ') + ')'); + WhalesongHashtable.prototype.set = function(key, value) { + return this.hash.put(key, value); }; - 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(), i; - for (i = 0; i < keys.length; i++){ - if (! (other.hash.containsKey(keys[i]) && - baselib.equality.equals(this.hash.get(keys[i]), - other.hash.get(keys[i]), - aUnionFind))) { - return false; - } - } - return true; + WhalesongHashtable.prototype.remove = function(key) { + this.hash.remove(key); }; - - - var isHash = function (x) { - return (x instanceof EqHashTable || - x instanceof EqualHashTable); + return (x instanceof WhalesongHashtable); }; @@ -178,9 +157,10 @@ exports.makeEqHashCode = makeEqHashCode; exports.makeLowLevelEqHash = makeLowLevelEqHash; + exports.makeEqHashtable = makeEqHashtable; + exports.makeEqvHashtable = makeEqvHashtable; + exports.makeEqualHashtable = makeEqualHashtable; - exports.EqualHashTable = EqualHashTable; - exports.EqHashTable = EqHashTable; exports.isHash = isHash; diff --git a/js-assembler/runtime-src/baselib-primitives.js b/js-assembler/runtime-src/baselib-primitives.js index 62ff9f1..f7f5996 100644 --- a/js-assembler/runtime-src/baselib-primitives.js +++ b/js-assembler/runtime-src/baselib-primitives.js @@ -24,6 +24,7 @@ var isNatural = baselib.numbers.isNatural; var isPair = baselib.lists.isPair; var isList = baselib.lists.isList; + var isChar = baselib.chars.isChar; var isVector = baselib.vectors.isVector; var isString = baselib.strings.isString; var isSymbol = baselib.symbols.isSymbol; @@ -104,8 +105,8 @@ }, 'cadrable value'); var checkList = baselib.check.checkList; - var checkListofChars = baselib.check.makeCheckListofArgumentType(baselib.chars.isChar, - 'character'); + var checkListofChars = baselib.check.makeCheckListofArgumentType(isChar, 'character'); + var checkListofPairs = baselib.check.makeCheckListofArgumentType(isPair, 'pair'); var checkVector = baselib.check.checkVector; var checkBox = baselib.check.checkBox; var checkMutableBox = baselib.check.checkMutableBox; @@ -1090,7 +1091,7 @@ 'char?', 1, function(M) { - return baselib.chars.isChar(M.e[M.e.length -1 ]); + return isChar(M.e[M.e.length -1 ]); }); @@ -2491,6 +2492,49 @@ return Math.floor( (new Date()).getTime() / 1000 ); }); + + // initializeHash: (listof pair) WhalesongHashtable -> WhalesongHashtable + var initializeHash = function(lst, hash) { + while (lst !== NULL) { + hash.put(lst.first.first, lst.first.rest); + lst = lst.rest; + } + return hash; + }; + + installPrimitiveProcedure( + 'make-hasheq', + makeList(0, 1), + function(M) { + var lst = NULL; + if (M.a === 1) { + lst = checkListofPairs(M, 'make-hasheq', 0); + } + return initializeHash(lst, plt.baselib.hashes.makeEqHashtable()); + }); + + installPrimitiveProcedure( + 'make-hasheqv', + makeList(0, 1), + function(M) { + var lst = NULL; + if (M.a === 1) { + lst = checkListofPairs(M, 'make-hasheqv', 0); + } + return initializeHash(lst, plt.baselib.hashes.makeEqvHashtable()); + }); + + installPrimitiveProcedure( + 'make-hash', + makeList(0, 1), + function(M) { + var lst = NULL; + if (M.a === 1) { + lst = checkListofPairs(M, 'make-hash', 0); + } + return initializeHash(lst, plt.baselib.hashes.makeEqualHashtable()); + }); + exports['Primitives'] = Primitives; exports['installPrimitiveProcedure'] = installPrimitiveProcedure; exports['installPrimitiveClosure'] = installPrimitiveClosure;