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
|
const std = @import("std");
const gc = @import("../gc.zig");
const value = @import("../value.zig");
const Value = value.Value;
pub fn toWriter(w: *std.Io.Writer, v: Value) anyerror!void {
// zig fmt: off
try if (v.isDouble()) double(w, v)
else if (v.isFixnum()) fixnum(w, v)
else if (v.getPtr(.pair)) |p| pair(w, @ptrCast(p))
else if (v.getPtr(.seq)) |p| seq(w, @ptrCast(p))
else if (v.isRune()) rune(w, v)
else if (v.isChar()) char(w, v)
else if (v.isMisc()) misc(w, v)
else if (v.isSrat()) srat(w, v)
else if (v.isSstr()) sstr(w, v)
;
// zig fmt: on
}
pub fn double(w: *std.Io.Writer, v: Value) !void {
_ = w;
_ = v;
@panic("not implemented");
}
pub fn fixnum(w: *std.Io.Writer, v: Value) !void {
_ = w;
_ = v;
@panic("not implemented");
}
pub fn rune(w: *std.Io.Writer, v: Value) !void {
const name = value.rune.unpack(v);
try w.writeByte('#');
try w.writeAll(name.slice());
}
pub fn sstr(w: *std.Io.Writer, v: Value) !void {
// TODO: Check if pipes/escapes necessary.
const str = value.sstr.unpack(v);
try w.writeAll(str.slice());
}
pub fn char(w: *std.Io.Writer, v: Value) !void {
const uc: u21 = value.char.unpack(v);
var buf: [4]u8 = undefined;
const len = try std.unicode.utf8Encode(uc, &buf);
try w.writeAll(buf[0..len]);
}
pub fn misc(w: *std.Io.Writer, v: Value) !void {
try switch (v.bits) {
value.f.bits => w.writeAll("#f"),
value.t.bits => w.writeAll("#t"),
value.nil.bits => w.writeAll("()"),
value.eof.bits => w.writeAll("#EOF"),
value.none.bits => w.writeAll("#NONE"),
value.undef.bits => w.writeAll("#UNDEF"),
else => @panic("not implemented"),
};
}
pub fn srat(w: *std.Io.Writer, v: Value) !void {
_ = w;
_ = v;
@panic("not implemented");
}
pub fn pair(w: *std.Io.Writer, p: *[2]Value) !void {
try w.writeByte('(');
try toWriter(w, p[0]);
var cdr = p[1];
while (value.pair.check(cdr)) |p2| : (cdr = value.pair.cdr(cdr)) {
try w.writeByte(' ');
try toWriter(w, p2[0]);
}
if (!value.nil.eq(cdr)) {
try w.writeByte(' ');
try w.writeByte('&');
try w.writeByte(' ');
try toWriter(w, cdr);
}
try w.writeByte(')');
}
pub fn seq(w: *std.Io.Writer, s: *value.seq.Header) !void {
switch (s.type) {
.string => try string(w, s),
else => @panic("not implemented"),
}
}
pub fn string(w: *std.Io.Writer, s: *value.seq.Header) !void {
// TODO: Check if pipes/escapes necessary.
try w.writeByte('|');
try w.writeAll(s.bytes());
try w.writeByte('|');
}
|