mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-19 02:00:26 +02:00
scheme.HashTable uses ES6 Map objects
* module/language/js-il/runtime.js: (scheme.HashTable): Change object interface. (cached-module-box): Update primitive. (scm_module_ensure_local_variable, def_guile_val): Update helpers (scm_hash): Remove helper. (make-weak-key-hash-table, hash-clear!, hashq-remove! hashq-ref, hashq-set!, hash-for-each): Update builtins. (make-weak-value-hash-table, hash-map->list): New builtins.
This commit is contained in:
parent
e57f9bc06a
commit
17e48e8641
1 changed files with 75 additions and 55 deletions
|
@ -325,27 +325,43 @@ scheme.Syntax = function (expr, wrap, module) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Hashtables
|
// Hashtables
|
||||||
var scm_hash = function (obj) {
|
scheme.HashTable = function (is_weak) {
|
||||||
if (obj instanceof scheme.Symbol) {
|
|
||||||
return obj.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("Can't hash object", obj);
|
|
||||||
throw "BadHash";
|
|
||||||
};
|
|
||||||
|
|
||||||
scheme.HashTable = function ( ) {
|
|
||||||
// HashTable definition needs to come before scm_pre_modules_obarray
|
// HashTable definition needs to come before scm_pre_modules_obarray
|
||||||
this.table = {};
|
|
||||||
|
// ignore the is_weak argument, since we can't iterate over js WeakMaps
|
||||||
|
this.table = new Map(); // WeakMap();
|
||||||
|
|
||||||
this.lookup = function (obj, dflt) {
|
this.lookup = function (obj, dflt) {
|
||||||
var hash = scm_hash(obj);
|
if (this.table.has(obj)) {
|
||||||
if (this.table.hasOwnProperty(hash)) {
|
return this.table.get(obj);
|
||||||
return this.table[hash];
|
|
||||||
} else {
|
} else {
|
||||||
return dflt;
|
return dflt;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.get = function(key) {
|
||||||
|
return this.table.get(key);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.set = function (key, obj) {
|
||||||
|
this.table.set(key, obj);
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.delete = function (key) {
|
||||||
|
this.table.delete(key);
|
||||||
|
return scheme.FALSE; // or handle
|
||||||
|
};
|
||||||
|
|
||||||
|
this.clear = function () {
|
||||||
|
this.table.clear();
|
||||||
|
return scheme.UNSPECIFIED;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.keys = function () {
|
||||||
|
return [...this.table.keys()];
|
||||||
|
};
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -402,7 +418,7 @@ scheme.primitives["cached-module-box"] = function (module_name, sym, is_public,
|
||||||
// equal? which is not being handled as a toplevel reference.
|
// equal? which is not being handled as a toplevel reference.
|
||||||
// This leads to an infinite loop in the temporary definition of
|
// This leads to an infinite loop in the temporary definition of
|
||||||
// resolve-module, which is called by cache-module-box.
|
// resolve-module, which is called by cache-module-box.
|
||||||
v = scm_pre_modules_obarray.table["equal?"];
|
v = scm_pre_modules_obarray.get(sym);
|
||||||
} else if (scheme.is_true(is_public)) {
|
} else if (scheme.is_true(is_public)) {
|
||||||
v = scm_public_lookup (module_name, sym);
|
v = scm_public_lookup (module_name, sym);
|
||||||
} else {
|
} else {
|
||||||
|
@ -486,7 +502,7 @@ function scm_module_ensure_local_variable(module, sym) {
|
||||||
return box;
|
return box;
|
||||||
} else {
|
} else {
|
||||||
var v = new scheme.Box(scheme.UNDEFINED);
|
var v = new scheme.Box(scheme.UNDEFINED);
|
||||||
scm_pre_modules_obarray.table[sym.name] = v;
|
scm_pre_modules_obarray.set(sym, v);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -819,7 +835,7 @@ function def_guile0 (name, fn) {
|
||||||
function def_guile_val (name, val) {
|
function def_guile_val (name, val) {
|
||||||
var sym = new scheme.Symbol(name); // put in obarray
|
var sym = new scheme.Symbol(name); // put in obarray
|
||||||
var box = new scheme.Box(val);
|
var box = new scheme.Box(val);
|
||||||
scm_pre_modules_obarray.table[name] = box;
|
scm_pre_modules_obarray.set(sym,box);
|
||||||
};
|
};
|
||||||
|
|
||||||
function scm_list (self, cont) {
|
function scm_list (self, cont) {
|
||||||
|
@ -1184,58 +1200,62 @@ def_guile0("make-hash-table", function (self, cont, size) {
|
||||||
});
|
});
|
||||||
|
|
||||||
def_guile0("make-weak-key-hash-table", function (self, cont, size) {
|
def_guile0("make-weak-key-hash-table", function (self, cont, size) {
|
||||||
// FIXME: not weak
|
return cont(new scheme.HashTable(true));
|
||||||
return cont(new scheme.HashTable());
|
});
|
||||||
|
|
||||||
|
def_guile0("make-weak-value-hash-table", function (self, cont, size) {
|
||||||
|
// FIXME:
|
||||||
|
return cont(new scheme.HashTable(true));
|
||||||
});
|
});
|
||||||
|
|
||||||
def_guile0("hash-clear!", function (self, cont, hashtable) {
|
def_guile0("hash-clear!", function (self, cont, hashtable) {
|
||||||
if (hashtable instanceof scheme.HashTable) {
|
return cont(hashtable.clear());
|
||||||
hashtable.table = {};
|
|
||||||
return cont(scheme.FALSE);
|
|
||||||
} else {
|
|
||||||
console.log("hash-clear!", arguments);
|
|
||||||
not_implemented_yet();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
def_guile0("hashq-remove!", function (self, cont, htable, key) {
|
def_guile0("hashq-remove!", function (self, cont, htable, key) {
|
||||||
if (htable instanceof scheme.HashTable) {
|
return cont(htable.delete(key));
|
||||||
delete htable.table[scm_hash(key)];
|
|
||||||
return cont(scheme.FALSE);
|
|
||||||
} else {
|
|
||||||
console.log("hashq-ref", arguments);
|
|
||||||
not_implemented_yet();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def_guile0("hashq-ref", function(self, cont, obarray, sym, dflt) {
|
def_guile0("hashq-ref", function(self, cont, obarray, sym, dflt) {
|
||||||
|
|
||||||
if (obarray instanceof scheme.HashTable) {
|
|
||||||
return cont(obarray.lookup(sym, dflt ? dflt : scheme.FALSE));
|
return cont(obarray.lookup(sym, dflt ? dflt : scheme.FALSE));
|
||||||
} else {
|
|
||||||
console.log("hashq-ref", arguments);
|
|
||||||
not_implemented_yet();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
def_guile0("hashq-set!", function (self, cont, hashtable, key, obj) {
|
def_guile0("hashq-set!", function (self, cont, hashtable, key, obj) {
|
||||||
if (hashtable instanceof scheme.HashTable) {
|
return cont(hashtable.set(key,obj));
|
||||||
hashtable.table[scm_hash(key)] = obj;
|
|
||||||
return cont(scheme.FALSE);
|
|
||||||
} else {
|
|
||||||
console.log("hashq-set!", arguments);
|
|
||||||
not_implemented_yet();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
def_guile0("hash-for-each", function (self, cont, module, symbol) {
|
def_guile0("hash-for-each", function (self, cont, proc, htable) {
|
||||||
// FIXME:
|
var keys = htable.keys(); // don't know if I can use js iterators
|
||||||
return cont(scheme.FALSE);
|
|
||||||
|
var loop = function (i) {
|
||||||
|
if (i === keys.length) {
|
||||||
|
return cont(scheme.UNSPECIFIED);
|
||||||
|
} else {
|
||||||
|
var newk = function() {
|
||||||
|
return loop(i+1);
|
||||||
|
};
|
||||||
|
return proc.fun(proc, newk, keys[i], htable.get(keys[i]));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return loop(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
def_guile0("hash-map->list", function (self, cont, proc, htable) {
|
||||||
|
var keys = htable.keys(); // don't know if I can use js iterators
|
||||||
|
|
||||||
|
var loop = function (i, retval, k) {
|
||||||
|
if (i === keys.length) {
|
||||||
|
return k(retval);
|
||||||
|
} else {
|
||||||
|
var newk = function(result) {
|
||||||
|
return loop(i+1, scheme.primitives.cons(result, retval), k);
|
||||||
|
};
|
||||||
|
return proc.fun(proc, newk, keys[i], htable.get(keys[i]));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return loop(0, scheme.EMPTY, cont);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Modules
|
// Modules
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue