summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTaylan Kammer <taylan.kammer@gmail.com>2026-06-09 10:45:24 +0200
committerTaylan Kammer <taylan.kammer@gmail.com>2026-06-09 10:45:24 +0200
commit79469e08b9920fa0b10d5e6dcc3dffc30e96928b (patch)
tree1d7f2d998626429790aa5037ad1d03e7efa6ab6d
parent9c4dae501a64af864c3ceef3d185cd15f7757dcf (diff)
cleanup
-rw-r--r--src/main.zig2
-rw-r--r--src/test/parse.zig10
-rw-r--r--src/zisp/io.zig78
-rw-r--r--src/zisp/io/Parser.zig5
-rw-r--r--src/zisp/io/Printer.zig147
-rw-r--r--src/zisp/io/decode.zig1
-rw-r--r--src/zisp/io/encode.zig1
-rw-r--r--src/zisp/io/parse.zig42
-rw-r--r--src/zisp/io/print.zig137
-rw-r--r--src/zisp/io/read.zig14
-rw-r--r--src/zisp/io/write.zig1
11 files changed, 228 insertions, 210 deletions
diff --git a/src/main.zig b/src/main.zig
index fcf3284..592d317 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -36,7 +36,7 @@ pub fn main() !u8 {
try writer.writeAll("0x");
try writer.printInt(datum.bits, 16, .lower, .{});
try writer.writeAll(": ");
- try zisp.io.print.toWriter(writer, datum);
+ try zisp.io.print(writer, datum);
try writer.writeAll("\n");
try writer.flush();
}
diff --git a/src/test/parse.zig b/src/test/parse.zig
index bc665e9..ba29333 100644
--- a/src/test/parse.zig
+++ b/src/test/parse.zig
@@ -13,7 +13,7 @@ pub const Value = zisp.value.Value;
fn parse(str: []const u8) Value {
var fbs = std.Io.Reader.fixed(str);
- return zisp.io.parse.fromReaderNoError(alloc, &fbs);
+ return zisp.io.parseNoError(alloc, &fbs);
}
test "parse empty" {
@@ -117,7 +117,7 @@ test "print" {
var buf: [32]u8 = undefined;
var w = std.Io.Writer.fixed(&buf);
const v = parse("#foo");
- try zisp.io.print.toWriter(&w, v);
+ try zisp.io.print(&w, v);
try testing.expectEqualStrings("#foo", buf[0..w.end]);
}
@@ -125,7 +125,7 @@ test "print2" {
var buf: [128]u8 = undefined;
var w = std.Io.Writer.fixed(&buf);
const v = parse("#{foo bar['x]}");
- try zisp.io.print.toWriter(&w, v);
+ try zisp.io.print(&w, v);
try testing.expectEqualStrings(
"(#HASH #BRACE foo (#JOIN bar #SQUARE (#QUOTE & x)))",
buf[0..w.end],
@@ -138,7 +138,7 @@ fn parseAndPrint(str: []const u8) !void {
const w = &fw.interface;
const v = parse(str);
- try zisp.io.print.toWriter(w, v);
+ try zisp.io.print(w, v);
try w.writeByte('\n');
try w.flush();
}
@@ -174,7 +174,7 @@ fn parseBench(path: []const u8, iters: usize) !void {
var file_reader = file.reader(io, &buf);
const reader = &file_reader.interface;
while (true) {
- const v = zisp.io.parse.fromReaderNoError(alloc, reader);
+ const v = zisp.io.parseNoError(alloc, reader);
if (value.eof.eq(v)) break;
}
}
diff --git a/src/zisp/io.zig b/src/zisp/io.zig
index e6f7c78..0a7e5dd 100644
--- a/src/zisp/io.zig
+++ b/src/zisp/io.zig
@@ -1,10 +1,76 @@
-pub const parse = @import("io/parse.zig");
-pub const print = @import("io/print.zig");
+const std = @import("std");
-pub const decode = @import("io/decode.zig");
-pub const encode = @import("io/encode.zig");
+const value = @import("value.zig");
-pub const read = @import("io/read.zig");
-pub const write = @import("io/write.zig");
+const Alloc = std.mem.Allocator;
+const Reader = std.Io.Reader;
+const Writer = std.Io.Writer;
+
+const Value = value.Value;
pub const Parser = @import("io/Parser.zig");
+pub const Printer = @import("io/Printer.zig");
+
+pub const Decoder = @import("io/Decoder.zig");
+pub const Encoder = @import("io/Encoder.zig");
+
+// Parse
+
+const ParserErrors = error{
+ ParseError,
+ OutOfMemory,
+};
+
+pub fn parse(alloc: Alloc, reader: *Reader) ParserErrors!Value {
+ var p = try Parser.init(alloc);
+ defer p.deinit();
+ return p.run(reader);
+}
+
+pub fn parseNoError(alloc: Alloc, reader: *Reader) Value {
+ var p = Parser.init(alloc) catch @panic("OOM");
+ defer p.deinit();
+ return p.run(reader) catch |e| switch (e) {
+ error.OutOfMemory => @panic("OOM"),
+ error.ParseError => {
+ const format = "Parse error: {s}, unread_char: {s}\n";
+ const unread: [4]u8 =
+ if (p.unread_char) |c|
+ "0x".* ++ std.fmt.hex(c)
+ else
+ "none".*;
+ std.debug.panic(format, .{ p.err_msg, unread });
+ },
+ };
+}
+
+// Print
+
+pub fn print(writer: *Writer, v: Value) !void {
+ var p = Printer.init(writer);
+ try p.print(v);
+}
+
+// Decode
+
+pub fn decode(v: Value) !Value {
+ _ = v;
+ @panic("not implemented");
+}
+
+// Encode
+
+pub fn encode(v: Value) !Value {
+ _ = v;
+ @panic("not implemented");
+}
+
+// Read & Write
+
+pub fn read(alloc: Alloc, reader: *Reader) !Value {
+ return decode(try parse(alloc, reader));
+}
+
+pub fn write(v: Value) !void {
+ return print(try encode(v));
+}
diff --git a/src/zisp/io/Parser.zig b/src/zisp/io/Parser.zig
index 3b5aa2a..9d36a57 100644
--- a/src/zisp/io/Parser.zig
+++ b/src/zisp/io/Parser.zig
@@ -37,6 +37,7 @@ const std = @import("std");
const Alloc = std.mem.Allocator;
const List = std.ArrayListUnmanaged;
+const Reader = std.Io.Reader;
const gc = @import("../gc.zig");
const lib = @import("../lib.zig");
@@ -92,7 +93,7 @@ alloc: Alloc,
istr_set: ?*IstrSet,
pair_pool: *PairPool,
-input: *std.Io.Reader = undefined,
+input: *Reader = undefined,
context: Context = .{},
stack: List(Context) = undefined,
@@ -262,7 +263,7 @@ inline fn call(p: *Parser, f: Fn) !void {
};
}
-pub fn run(p: *Parser, input: *std.Io.Reader) !Value {
+pub fn run(p: *Parser, input: *Reader) !Value {
p.input = input;
p.context.next = .parseUnit;
while (p.context.next) |next| {
diff --git a/src/zisp/io/Printer.zig b/src/zisp/io/Printer.zig
new file mode 100644
index 0000000..e6b3d5b
--- /dev/null
+++ b/src/zisp/io/Printer.zig
@@ -0,0 +1,147 @@
+const std = @import("std");
+
+const Writer = std.Io.Writer;
+
+const io = @import("../io.zig");
+const value = @import("../value.zig");
+
+const Parser = io.Parser;
+const Value = value.Value;
+const PairPtr = value.pair.PairPtr;
+const IstrPtr = value.istr.IstrPtr;
+const ArrayPtr = value.array.ArrayPtr;
+
+const Printer = @This();
+
+writer: *Writer,
+
+pub fn init(writer: *Writer) Printer {
+ return .{ .writer = writer };
+}
+
+fn write(p: *Printer, str: []const u8) !void {
+ _ = try p.writer.write(str);
+}
+
+pub fn print(p: *Printer, v: Value) anyerror!void {
+ if (v.isSstr()) return p.printBareStr(value.sstr.unpack(&v));
+ if (v.isRune()) return p.printRune(v);
+ if (v.isMisc()) return p.printMisc(v);
+ if (value.istr.check(v)) |str| return p.printBareStr(str.str());
+ if (value.array.check(.str, v)) |str| return p.printBareStr(str.str());
+ if (value.pair.check(v)) |pair| return p.printPair(pair);
+ @panic("Unsupported type to print.");
+}
+
+pub fn printBareStr(p: *Printer, s: []const u8) !void {
+ if (s.len == 0) @panic("Empty string must be quoted.");
+ const no_joins = Parser.isSpecialBareChar(s[0]);
+ for (s) |c| {
+ if (Parser.isBareChar(c)) {
+ try p.writer.writeByte(c);
+ } else if (no_joins and (c == '.' or c == ':')) {
+ try p.writer.writeByte(c);
+ } else {
+ @panic("String needs quoting.");
+ }
+ }
+}
+
+pub fn printRune(p: *Printer, v: Value) !void {
+ try p.write("#");
+ try p.write(value.rune.unpack(&v));
+}
+
+pub fn printMisc(p: *Printer, v: Value) !void {
+ try switch (v.bits) {
+ value.f.bits => p.write("#f"),
+ value.t.bits => p.write("#t"),
+ value.nil.bits => p.write("()"),
+ value.eof.bits => p.write("#EOF"),
+ value.none.bits => p.write("#NONE"),
+ value.undef.bits => p.write("#UNDEF"),
+ else => @panic("Unsupported misc value to print."),
+ };
+}
+
+pub fn printPair(p: *Printer, pair: PairPtr) !void {
+ try switch (pair.car.bits) {
+ Parser.PQSTR.bits => p.printQuotString(pair.cdr, '|'),
+ Parser.DQSTR.bits => p.printQuotString(pair.cdr, '"'),
+ Parser.ATSTR.bits => p.printAtString(pair.cdr),
+ Parser.LABEL.bits => p.printLabel(pair.cdr),
+ else => p.printList(pair),
+ };
+}
+
+fn printQuotString(p: *Printer, s: Value, comptime qchar: u8) !void {
+ try p.writer.writeByte(qchar);
+ const str = try value.string.getString(&s);
+ for (str) |c| switch (c) {
+ qchar => {
+ try p.writer.writeByte('\\');
+ try p.writer.writeByte(qchar);
+ },
+ '\\' => {
+ try p.writer.writeByte('\\');
+ try p.writer.writeByte('\\');
+ },
+ else => {
+ try p.writer.writeByte(c);
+ },
+ };
+ try p.writer.writeByte(qchar);
+}
+
+pub fn printAtString(p: *Printer, at_str_pair: Value) !void {
+ const pair = value.pair.assert(at_str_pair);
+ const byte = value.fixnum.unpack(pair.car);
+ std.debug.assert(byte <= 255);
+ const str = try value.string.getString(&pair.cdr);
+ try p.write("@");
+ try p.writer.writeByte(@intCast(byte));
+ try p.write(str);
+ try p.writer.writeByte(@intCast(byte));
+}
+
+pub fn printLabel(p: *Printer, v: Value) !void {
+ var num: Value = undefined;
+ var dat: ?Value = undefined;
+ if (value.pair.check(v)) |pair| {
+ num = pair.car;
+ dat = pair.cdr;
+ } else {
+ num = v;
+ dat = null;
+ }
+
+ const x = value.fixnum.unpack(num);
+ std.debug.assert(x >= 0);
+ std.debug.assert(x <= std.math.maxInt(u48));
+ var buf: [12]u8 = undefined;
+ const end = std.fmt.printInt(&buf, x, 16, .lower, .{});
+
+ try p.write("#%");
+ try p.write(buf[0..end]);
+ if (dat) |d| {
+ try p.write("=");
+ try p.print(d);
+ } else {
+ try p.write("%");
+ }
+}
+
+pub fn printList(p: *Printer, pair: PairPtr) !void {
+ try p.write("(");
+ try p.print(pair.car);
+ var cdr = pair.cdr;
+ while (value.pair.check(cdr)) |next| : (cdr = next.cdr) {
+ try p.write(" ");
+ try p.print(next.car);
+ }
+ if (!value.nil.eq(cdr)) {
+ try p.write(" & ");
+ try p.print(cdr);
+ }
+ try p.write(")");
+}
diff --git a/src/zisp/io/decode.zig b/src/zisp/io/decode.zig
deleted file mode 100644
index eb27e20..0000000
--- a/src/zisp/io/decode.zig
+++ /dev/null
@@ -1 +0,0 @@
-// wip
diff --git a/src/zisp/io/encode.zig b/src/zisp/io/encode.zig
deleted file mode 100644
index eb27e20..0000000
--- a/src/zisp/io/encode.zig
+++ /dev/null
@@ -1 +0,0 @@
-// wip
diff --git a/src/zisp/io/parse.zig b/src/zisp/io/parse.zig
deleted file mode 100644
index 9b6d32c..0000000
--- a/src/zisp/io/parse.zig
+++ /dev/null
@@ -1,42 +0,0 @@
-const builtin = @import("builtin");
-const std = @import("std");
-
-const Alloc = std.mem.Allocator;
-const Reader = *std.Io.Reader;
-
-const io = @import("../io.zig");
-const value = @import("../value.zig");
-
-const Parser = io.Parser;
-const Value = value.Value;
-
-const is_test = builtin.is_test;
-const is_debug = builtin.mode == .Debug;
-
-const ParserErrors = error{
- ParseError,
- OutOfMemory,
-};
-
-pub fn fromReader(alloc: Alloc, input: Reader) ParserErrors!Value {
- var p = try Parser.init(alloc);
- defer p.deinit();
- return p.run(input);
-}
-
-pub fn fromReaderNoError(alloc: Alloc, input: Reader) Value {
- var p = Parser.init(alloc) catch @panic("OOM");
- defer p.deinit();
- return p.run(input) catch |e| switch (e) {
- error.OutOfMemory => @panic("OOM"),
- error.ParseError => {
- const format = "Parse error: {s}, unread_char: {s}\n";
- const unread: [4]u8 =
- if (p.unread_char) |c|
- "0x".* ++ std.fmt.hex(c)
- else
- "none".*;
- std.debug.panic(format, .{ p.err_msg, unread });
- },
- };
-}
diff --git a/src/zisp/io/print.zig b/src/zisp/io/print.zig
deleted file mode 100644
index e5caab7..0000000
--- a/src/zisp/io/print.zig
+++ /dev/null
@@ -1,137 +0,0 @@
-const std = @import("std");
-
-const Writer = *std.Io.Writer;
-
-const io = @import("../io.zig");
-const value = @import("../value.zig");
-
-const Parser = io.Parser;
-const Value = value.Value;
-const PairPtr = value.pair.PairPtr;
-const IstrPtr = value.istr.IstrPtr;
-const ArrayPtr = value.array.ArrayPtr;
-
-pub fn toWriter(w: Writer, v: Value) anyerror!void {
- if (v.isSstr()) return printBareStr(w, value.sstr.unpack(&v));
- if (v.isRune()) return printRune(w, v);
- if (v.isMisc()) return printMisc(w, v);
- if (value.istr.check(v)) |p| return printBareStr(w, p.str());
- if (value.array.check(.str, v)) |p| return printBareStr(w, p.str());
- if (value.pair.check(v)) |p| return printPair(w, p);
- @panic("Unsupported type to print.");
-}
-
-pub fn printBareStr(w: Writer, s: []const u8) !void {
- if (s.len == 0) @panic("Empty string must be quoted.");
- const no_joins = Parser.isSpecialBareChar(s[0]);
- for (s) |c| {
- if (Parser.isBareChar(c)) {
- try w.writeByte(c);
- } else if (no_joins and (c == '.' or c == ':')) {
- try w.writeByte(c);
- } else {
- @panic("String needs quoting.");
- }
- }
-}
-
-pub fn printRune(w: Writer, v: Value) !void {
- try w.writeByte('#');
- try w.writeAll(value.rune.unpack(&v));
-}
-
-pub fn printMisc(w: 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("Unsupported misc value to print."),
- };
-}
-
-pub fn printPair(w: Writer, p: PairPtr) !void {
- try switch (p.car.bits) {
- Parser.PQSTR.bits => printQuotString(w, p.cdr, '|'),
- Parser.DQSTR.bits => printQuotString(w, p.cdr, '"'),
- Parser.ATSTR.bits => printAtString(w, p.cdr),
- Parser.LABEL.bits => printLabel(w, p.cdr),
- else => printList(w, p),
- };
-}
-
-fn printQuotString(w: Writer, s: Value, comptime qchar: u8) !void {
- try w.writeByte(qchar);
- const str = try value.string.getString(&s);
- for (str) |c| switch (c) {
- qchar => {
- try w.writeByte('\\');
- try w.writeByte(qchar);
- },
- '\\' => {
- try w.writeByte('\\');
- try w.writeByte('\\');
- },
- else => {
- try w.writeByte(c);
- },
- };
- try w.writeByte(qchar);
-}
-
-pub fn printAtString(w: Writer, at_str_pair: Value) !void {
- const p = value.pair.assert(at_str_pair);
- const b = value.fixnum.unpack(p.car);
- std.debug.assert(b <= 255);
- const str = try value.string.getString(&p.cdr);
- try w.writeByte('@');
- try w.writeByte(@intCast(b));
- try w.writeAll(str);
- try w.writeByte(@intCast(b));
-}
-
-pub fn printLabel(w: Writer, v: Value) !void {
- var num: Value = undefined;
- var dat: ?Value = undefined;
- if (value.pair.check(v)) |p| {
- num = p.car;
- dat = p.cdr;
- } else {
- num = v;
- dat = null;
- }
-
- const x = value.fixnum.unpack(num);
- std.debug.assert(x >= 0);
- std.debug.assert(x <= std.math.maxInt(u48));
- var buf: [12]u8 = undefined;
- const end = std.fmt.printInt(&buf, x, 16, .lower, .{});
-
- try w.writeAll("#%");
- try w.writeAll(buf[0..end]);
- if (dat) |d| {
- try w.writeByte('=');
- try toWriter(w, d);
- } else {
- try w.writeByte('%');
- }
-}
-
-pub fn printList(w: Writer, p: PairPtr) !void {
- try w.writeByte('(');
- try toWriter(w, p.car);
- var cdr = p.cdr;
- while (value.pair.check(cdr)) |p2| : (cdr = p2.cdr) {
- try w.writeByte(' ');
- try toWriter(w, p2.car);
- }
- if (!value.nil.eq(cdr)) {
- try w.writeByte(' ');
- try w.writeByte('&');
- try w.writeByte(' ');
- try toWriter(w, cdr);
- }
- try w.writeByte(')');
-}
diff --git a/src/zisp/io/read.zig b/src/zisp/io/read.zig
deleted file mode 100644
index 23f0ea8..0000000
--- a/src/zisp/io/read.zig
+++ /dev/null
@@ -1,14 +0,0 @@
-const std = @import("std");
-
-const parse = @import("parse.zig");
-const decode = @import("decode.zig");
-
-const Value = @import("../value.zig").Value;
-
-pub fn fromReader(
- alloc: std.mem.Allocator,
- io: std.Io,
- reader: *std.Io.Reader,
-) Value {
- return decode.decode(parse.fromReader(alloc, io, reader));
-}
diff --git a/src/zisp/io/write.zig b/src/zisp/io/write.zig
deleted file mode 100644
index eb27e20..0000000
--- a/src/zisp/io/write.zig
+++ /dev/null
@@ -1 +0,0 @@
-// wip