working on getting hashtables in

This commit is contained in:
Danny Yoo 2011-11-03 15:38:47 -04:00
parent f8145c933f
commit 8117943aaf
2 changed files with 103 additions and 79 deletions

View File

@ -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;

View File

@ -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;