guile-commits
[Top][All Lists]
Advanced

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

[Guile-commits] 54/99: Implement structs in runtime.js


From: Christopher Allan Webber
Subject: [Guile-commits] 54/99: Implement structs in runtime.js
Date: Sun, 10 Oct 2021 21:50:59 -0400 (EDT)

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

commit cf1ddd466bb58922fbf843fd7413e85eabb2f500
Author: Ian Price <ianprice90@googlemail.com>
AuthorDate: Wed Jun 28 17:15:57 2017 +0100

    Implement structs in runtime.js
    
    * module/language/js-il/runtime.js:
      (scheme.Struct): new type.
      (allocate-struct/immediate, struct-vtable, struct-set!, struct-ref,
      struct-set!/immediate, struct-ref/immediate): Implement primitives.
      (def_guile_val): New helper.
      (string=?, string-append): Implement string functions.
      (standard-vtable-fields, <standard-vtable>, vtable-index-layout,
      vtable-index-printer, vtable-offset-user, make-struct/no-tail,
      make-vtable, struct-vtable?): Implement struct functions.
---
 module/language/js-il/runtime.js | 138 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 131 insertions(+), 7 deletions(-)

diff --git a/module/language/js-il/runtime.js b/module/language/js-il/runtime.js
index 5fc10c2..6b33f5c 100644
--- a/module/language/js-il/runtime.js
+++ b/module/language/js-il/runtime.js
@@ -418,13 +418,37 @@ scheme.builtins[3] = new scheme.Closure(call_with_values, 
0);
 scheme.builtins[4] = new scheme.Closure(callcc, 0);
 
 // Structs
-scheme.primitives["struct?"] = not_implemented_yet;
-scheme.primitives["struct-set!/immediate"] = not_implemented_yet;
-scheme.primitives["struct-vtable"] = not_implemented_yet;
-scheme.primitives["struct-ref/immediate"] = not_implemented_yet;
-scheme.primitives["struct-ref"] = not_implemented_yet;
-scheme.primitives["struct-set!"] = not_implemented_yet;
-scheme.primitives["allocate-struct/immediate"] = not_implemented_yet;
+scheme.Struct = function (vtable, nfields) {
+    this.is_vtable = false;
+    this.vtable = vtable;
+    this.fields = [];
+
+    // FIXME: worth doing?
+    for(var i = 0; i < nfields; i++){
+        this.fields[i]=scheme.UNDEFINED;
+    }
+
+    return this;
+};
+
+scheme.primitives["allocate-struct/immediate"] = function (vtable, nfields) {
+    return new scheme.Struct(vtable, nfields);
+};
+
+scheme.primitives["struct-vtable"] = function(struct) {
+    return struct.vtable;
+};
+
+scheme.primitives["struct-set!"] = function (struct, idx, obj) {
+    return struct.fields[idx] = obj;
+};
+
+scheme.primitives["struct-ref"] = function (struct, idx) {
+    return struct.fields[idx];
+};
+
+scheme.primitives["struct-set!/immediate"] = scheme.primitives["struct-set!"];
+scheme.primitives["struct-ref/immediate"] = scheme.primitives["struct-ref"];
 
 // Equality
 scheme.primitives["eq?"] = function(x, y) {
@@ -578,6 +602,12 @@ function def_guile0 (name, fn) {
     scheme.module_cache["guile"][name] = box;
 };
 
+function def_guile_val (name, val) {
+    var sym = new scheme.Symbol(name); // put in obarray
+    var box = new scheme.Box(val);
+    scheme.module_cache["guile"][name] = box;
+};
+
 function scm_list (self, cont) {
     var l = scheme.EMPTY;
     for (var i = arguments.length - 1; i >= 2; i--){
@@ -621,3 +651,97 @@ scheme.Macro = function (name, type, binding) {
 def_guile0("make-syntax-transformer", function (self, cont, name, type, 
binding) {
     return cont(new scheme.Macro(name, type, binding));
 });
+
+// Strings
+def_guile0("string=?", function (self, cont, s1, s2) {
+    return cont(coerce_bool(s1.s === s2.s));
+});
+
+def_guile0("string-append", function (self, cont, s1, s2) {
+    var s = new scheme.String(s1.s + s2.s);
+    return cont(s);
+});
+
+// Structs
+var vtable_base_layout = new scheme.String("pruhsruhpwphuhuh");
+def_guile_val("standard-vtable-fields", vtable_base_layout);
+
+var scm_vtable_index_layout = 0;
+var scm_vtable_index_flags = 1;
+var scm_vtable_index_self = 2;
+var scm_vtable_index_instance_finalize = 3;
+var scm_vtable_index_instance_printer = 4;
+var scm_vtable_index_name = 5;
+var scm_vtable_index_size = 6;
+var scm_vtable_index_reserved_7 = 7;
+var scm_vtable_offset_user = 8;
+
+function scm_struct_init(struct, layout, args) {
+    // FIXME: assumes there are no tail arrays
+    var nfields = layout.length / 2; // assumes even
+    var arg = 0;
+
+    for (var i = 0; i < nfields; i++) {
+        if (layout[2*i+1] == 'o') {
+            continue;
+        }
+        switch (layout[2*i]) {
+        case 'p' :
+            struct.fields[i] = (arg < args.length) ? args[arg] : scheme.FALSE;
+            arg += 1;
+            break;
+        case 'u' :
+            struct.fields[i] = (arg < args.length) ? args[arg] : 0;
+            arg += 1;
+            break;
+        case 's' :
+            struct.fields[i] = struct;
+        }
+    }
+};
+
+// Set up <standard-vtable>
+var scm_standard_vtable = new scheme.Struct(undefined, 0);
+scm_standard_vtable.vtable = scm_standard_vtable;
+scm_standard_vtable.is_vtable = true; // ?
+scm_struct_init(scm_standard_vtable,
+                vtable_base_layout.s,
+                [new scheme.Symbol(vtable_base_layout.s)]);
+//   scm_set_struct_vtable_name_x (scm_standard_vtable_vtable, name);
+
+def_guile_val("<standard-vtable>", scm_standard_vtable);
+def_guile_val("vtable-index-layout", scm_vtable_index_layout);
+def_guile_val("vtable-index-printer", scm_vtable_index_instance_printer);
+def_guile_val("vtable-offset-user", scm_vtable_offset_user);
+
+
+function scm_make_struct (vtable, args) {
+    var layout = vtable.fields[scm_vtable_index_layout].name;
+    var s = new scheme.Struct(vtable, layout.length / 2);
+    scm_struct_init(s, layout, args);
+    return s;
+}
+
+def_guile0("make-struct/no-tail", function (self, cont, vtable) {
+    var args = Array.prototype.slice.call(arguments, 3);
+    return cont(scm_make_struct(vtable, args));
+});
+
+def_guile0("make-vtable", function(self, cont, fields, printer) {
+    var layout = new scheme.Symbol(fields.s); // make-struct-layout
+    var str = scm_make_struct(scm_standard_vtable, [layout, printer]);
+    str.is_vtable = true;
+    return cont(str);
+});
+
+def_guile0("make-struct-layout", function (self, cont, str) {
+    var layout = new scheme.Symbol(str.s);
+    return cont(layout);
+});
+
+def_guile0("struct-vtable?", function (self, cont, obj) {
+    // We don't inherit flags, so =struct-vtable?= may give the wrong
+    // answer where SCM_VTABLE_FLAG_VTABLE would have been set
+    var bool = coerce_bool(obj instanceof scheme.Struct && obj.is_vtable);
+    return cont(bool);
+});



reply via email to

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