spec: bytevectors (make-bytevector/u8-ref/u8-set!/utf8->string/etc)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-01 19:16:02 +00:00
parent 24e1a862fb
commit a381154507
5 changed files with 486 additions and 3 deletions

View File

@@ -1817,6 +1817,73 @@ PRIMITIVES_JS_MODULES: dict[str, str] = {
});
return out;
};
''',
"stdlib.bytevectors": '''
// stdlib.bytevectors — R7RS bytevector type backed by Uint8Array
function SxBytevector(size_or_buf) {
if (size_or_buf instanceof Uint8Array) {
this.data = size_or_buf;
} else {
this.data = new Uint8Array(typeof size_or_buf === "number" ? size_or_buf : 0);
}
this._bytevector = true;
}
SxBytevector.prototype._type = "bytevector";
PRIMITIVES["make-bytevector"] = function(n, fill) {
var bv = new SxBytevector(n);
if (fill !== undefined) bv.data.fill(fill & 0xff);
return bv;
};
PRIMITIVES["bytevector?"] = function(v) { return v instanceof SxBytevector; };
PRIMITIVES["bytevector-length"] = function(bv) { return bv.data.length; };
PRIMITIVES["bytevector-u8-ref"] = function(bv, i) { return bv.data[i]; };
PRIMITIVES["bytevector-u8-set!"] = function(bv, i, byte) { bv.data[i] = byte & 0xff; return NIL; };
PRIMITIVES["bytevector-copy"] = function(bv, start, end_) {
var s = start === undefined ? 0 : start;
var e = end_ === undefined ? bv.data.length : end_;
return new SxBytevector(bv.data.slice(s, e));
};
PRIMITIVES["bytevector-copy!"] = function(dst, at, src, start, end_) {
var s = start === undefined ? 0 : start;
var e = end_ === undefined ? src.data.length : end_;
dst.data.set(src.data.subarray(s, e), at);
return NIL;
};
PRIMITIVES["bytevector-append"] = function() {
var total = 0;
for (var i = 0; i < arguments.length; i++) total += arguments[i].data.length;
var result = new Uint8Array(total);
var pos = 0;
for (var i = 0; i < arguments.length; i++) {
result.set(arguments[i].data, pos);
pos += arguments[i].data.length;
}
return new SxBytevector(result);
};
PRIMITIVES["utf8->string"] = function(bv, start, end_) {
var s = start === undefined ? 0 : start;
var e = end_ === undefined ? bv.data.length : end_;
var dec = new TextDecoder("utf-8");
return dec.decode(bv.data.subarray(s, e));
};
PRIMITIVES["string->utf8"] = function(str, start, end_) {
var enc = new TextEncoder();
var full = enc.encode(str);
var s = start === undefined ? 0 : start;
var e = end_ === undefined ? full.length : end_;
return new SxBytevector(full.slice(s, e));
};
PRIMITIVES["bytevector->list"] = function(bv) {
var out = [];
for (var i = 0; i < bv.data.length; i++) out.push(bv.data[i]);
return out;
};
PRIMITIVES["list->bytevector"] = function(lst) {
if (!Array.isArray(lst)) lst = [];
var b = new Uint8Array(lst.length);
for (var i = 0; i < lst.length; i++) b[i] = lst[i] & 0xff;
return new SxBytevector(b);
};
''',
}
# Modules to include by default (all)
@@ -1864,6 +1931,7 @@ PLATFORM_JS_PRE = '''
if (x._hash_table) return "hash-table";
if (x._sxset) return "set";
if (x._regexp) return "regexp";
if (x._bytevector) return "bytevector";
if (x._rational) return "rational";
if (typeof Node !== "undefined" && x instanceof Node) return "dom-node";
if (Array.isArray(x)) return "list";