1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
const std = @import("std");
const value = @import("../value.zig");
const istr = value.istr;
const seq = value.seq;
const ShortString = value.ShortString;
const OtherTag = value.OtherTag;
const Value = value.Value;
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, @ptrCast(p)),
.seq => unparseSeq(w, @ptrCast(p)),
else => @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());
}
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: *[2]Value) !void {
try w.writeByte('(');
try unparse(w, p[0]);
var cdr = p[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);
}
try w.writeByte(')');
}
fn unparseSeq(w: anytype, p: *seq.Header) !void {
const h = istr.getHeaderFromPtr(@ptrCast(p));
switch (h.type) {
.string => try unparseString(w, h),
else => @panic("not implemented"),
}
}
fn unparseString(w: anytype, h: *seq.Header) !void {
const info = h.info.string;
if (info.quoted) {
try w.writeByte('"');
}
try w.writeAll(h.bytes());
if (info.quoted) {
try w.writeByte('"');
}
}
|