guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 75/99: scheme.HashTable uses ES6 Map objects


From: Christopher Allan Webber
Subject: [Guile-commits] 75/99: scheme.HashTable uses ES6 Map objects
Date: Sun, 10 Oct 2021 21:51:07 -0400 (EDT)

cwebber pushed a commit to branch compile-to-js-merge
in repository guile.

commit 17e48e86419927e076c7b42c4e2f0e8ab866536e
Author: Ian Price <ianprice90@googlemail.com>
AuthorDate: Wed Aug 16 20:34:51 2017 +0100

    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.
---
 module/language/js-il/runtime.js | 124 +++++++++++++++++++++++----------------
 1 file changed, 72 insertions(+), 52 deletions(-)

diff --git a/module/language/js-il/runtime.js b/module/language/js-il/runtime.js
index 6ce8a7f..aa38b0a 100644
--- a/module/language/js-il/runtime.js
+++ b/module/language/js-il/runtime.js
@@ -325,27 +325,43 @@ scheme.Syntax = function (expr, wrap, module) {
 };
 
 // Hashtables
-var scm_hash = function (obj) {
-    if (obj instanceof scheme.Symbol) {
-        return obj.name;
-    }
+scheme.HashTable = function (is_weak) {
+    // HashTable definition needs to come before scm_pre_modules_obarray
 
-    console.log("Can't hash object", obj);
-    throw "BadHash";
-};
+    // ignore the is_weak argument, since we can't iterate over js WeakMaps
+    this.table = new Map(); // WeakMap();
 
-scheme.HashTable = function ( ) {
-    // HashTable definition needs to come before scm_pre_modules_obarray
-    this.table = {};
     this.lookup = function (obj, dflt) {
-        var hash = scm_hash(obj);
-        if (this.table.hasOwnProperty(hash)) {
-            return this.table[hash];
+        if (this.table.has(obj)) {
+            return this.table.get(obj);
         } else {
             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;
 };
 
@@ -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.
         // This leads to an infinite loop in the temporary definition of
         // 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)) {
         v = scm_public_lookup (module_name, sym);
     } else {
@@ -486,7 +502,7 @@ function scm_module_ensure_local_variable(module, sym) {
             return box;
         } else {
             var v = new scheme.Box(scheme.UNDEFINED);
-            scm_pre_modules_obarray.table[sym.name] = v;
+            scm_pre_modules_obarray.set(sym, v);
             return v;
         }
     }
@@ -819,7 +835,7 @@ function def_guile0 (name, fn) {
 function def_guile_val (name, val) {
     var sym = new scheme.Symbol(name); // put in obarray
     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) {
@@ -1184,58 +1200,62 @@ def_guile0("make-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());
+    return cont(new scheme.HashTable(true));
+});
+
+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) {
-    if (hashtable instanceof scheme.HashTable) {
-        hashtable.table = {};
-        return cont(scheme.FALSE);
-    } else {
-        console.log("hash-clear!", arguments);
-        not_implemented_yet();
-    }
+    return cont(hashtable.clear());
 });
 
 def_guile0("hashq-remove!", function (self, cont, htable, key) {
-    if (htable instanceof scheme.HashTable) {
-        delete htable.table[scm_hash(key)];
-        return cont(scheme.FALSE);
-    } else {
-        console.log("hashq-ref", arguments);
-        not_implemented_yet();
-    }
+    return cont(htable.delete(key));
 });
 
+def_guile0("hashq-ref", function(self, cont, obarray, sym, dflt) {
+    return cont(obarray.lookup(sym, dflt ? dflt : scheme.FALSE));
+});
 
+def_guile0("hashq-set!", function (self, cont, hashtable, key, obj) {
+    return cont(hashtable.set(key,obj));
+});
 
+def_guile0("hash-for-each", function (self, cont, proc, htable) {
+    var keys = htable.keys(); // don't know if I can use js iterators
 
+    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]));
+        }
+    };
 
-def_guile0("hashq-ref", function(self, cont, obarray, sym, dflt) {
-
-    if (obarray instanceof scheme.HashTable) {
-        return cont(obarray.lookup(sym, dflt ? dflt : scheme.FALSE));
-    } else {
-        console.log("hashq-ref", arguments);
-        not_implemented_yet();
-    }
+    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
 
-def_guile0("hashq-set!", function (self, cont, hashtable, key, obj) {
-    if (hashtable instanceof scheme.HashTable) {
-        hashtable.table[scm_hash(key)] = obj;
-        return cont(scheme.FALSE);
-    } else {
-        console.log("hashq-set!", arguments);
-        not_implemented_yet();
-    }
-});
+    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]));
+        }
+    };
 
-def_guile0("hash-for-each", function (self, cont, module, symbol) {
-    // FIXME:
-    return cont(scheme.FALSE);
+    return loop(0, scheme.EMPTY, cont);
 });
 
 // Modules



reply via email to

[Prev in Thread] Current Thread [Next in Thread]