From 472f3e89a61ec51218cefe65305ec6f0a0d95fbf Mon Sep 17 00:00:00 2001 From: Taylan Kammer Date: Fri, 28 Feb 2025 14:38:57 +0100 Subject: update --- src/libzisp/io/unparser.zig | 101 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 91 insertions(+), 10 deletions(-) (limited to 'src/libzisp/io/unparser.zig') diff --git a/src/libzisp/io/unparser.zig b/src/libzisp/io/unparser.zig index d835924..c25e918 100644 --- a/src/libzisp/io/unparser.zig +++ b/src/libzisp/io/unparser.zig @@ -3,19 +3,100 @@ const std = @import("std"); const value = @import("../value.zig"); const ShortString = value.ShortString; +const OtherTag = value.OtherTag; const Value = value.Value; +const Hval = value.Hval; -// const State = struct { +pub fn unparse(w: anytype, v: Value) anyerror!void { + try if (value.double.check(v)) + unparseDouble(w, v) + else if (value.fixnum.check(v)) + unparseFixnum(w, v) + else if (value.ptr.checkZisp(v)) + unparseHeap(w, v) + else + unparseOther(w, v); +} + +fn unparseDouble(w: anytype, v: Value) !void { + _ = w; + _ = v; + @panic("not implemented"); +} + +fn unparseFixnum(w: anytype, v: Value) !void { + _ = w; + _ = v; + @panic("not implemented"); +} -// } +fn unparseHeap(w: anytype, v: Value) !void { + const p, const t = value.ptr.unpack(v); + try switch (t) { + .pair => unparsePair(w, p), + .istr => @panic("not implemented"), + .proc => @panic("not implemented"), + }; +} + +fn unparseOther(w: anytype, v: Value) !void { + try switch (v.other.tag) { + .rune => unparseRune(w, v), + .sstr => unparseSstr(w, v), + .qstr => unparseQstr(w, v), + .char => unparseChar(w, v), + .misc => unparseMisc(w, v), + }; +} + +fn unparseRune(w: anytype, v: Value) !void { + const name = value.rune.unpack(v); + try w.writeByte('#'); + try w.writeAll(name.constSlice()); +} -pub fn unparse(v: Value) []u8 { - var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init; - var out: std.ArrayList(u8) = .init(gpa.allocator()); - if (value.rune.check(v)) { - const name = value.rune.unpack(v); - out.append('#') catch @panic(""); - out.appendSlice(name.slice()) catch @panic(""); +fn unparseSstr(w: anytype, v: Value) !void { + const str = value.sstr.unpack(v); + try w.writeAll(str.constSlice()); +} + +fn unparseQstr(w: anytype, v: Value) !void { + const str = value.sstr.unpack(v); + try w.writeByte('"'); + try w.writeAll(str.constSlice()); + try w.writeByte('"'); +} + +fn unparseChar(w: anytype, v: Value) !void { + var buf: [4]u8 = undefined; + const len = try std.unicode.utf8Encode(v.char.value, &buf); + try w.writeAll(buf[0..len]); +} + +fn unparseMisc(w: anytype, v: Value) !void { + try switch (v.misc.value) { + .f => w.writeAll("#f"), + .t => w.writeAll("#t"), + .nil => w.writeAll("()"), + .eof => w.writeAll("#eof"), + .undef => w.writeAll("#undef"), + }; +} + +fn unparsePair(w: anytype, p: [*]Hval) !void { + const vs: *[2]Value = @ptrCast(p); + try w.writeByte('('); + try unparse(w, vs[0]); + var cdr = vs[1]; + while (value.pair.check(cdr)) : (cdr = value.pair.cdr(cdr)) { + try w.writeByte(' '); + try unparse(w, value.pair.car(cdr)); + } + if (!value.nil.check(cdr)) { + try w.writeByte(' '); + try w.writeByte('.'); + try w.writeByte(' '); + try unparse(w, cdr); } - return out.toOwnedSlice() catch @panic(""); + try w.writeByte(')'); } -- cgit v1.2.3