diff options
| author | Taylan Kammer <taylan.kammer@gmail.com> | 2026-06-09 10:45:24 +0200 |
|---|---|---|
| committer | Taylan Kammer <taylan.kammer@gmail.com> | 2026-06-09 10:45:24 +0200 |
| commit | 79469e08b9920fa0b10d5e6dcc3dffc30e96928b (patch) | |
| tree | 1d7f2d998626429790aa5037ad1d03e7efa6ab6d | |
| parent | 9c4dae501a64af864c3ceef3d185cd15f7757dcf (diff) | |
cleanup
| -rw-r--r-- | src/main.zig | 2 | ||||
| -rw-r--r-- | src/test/parse.zig | 10 | ||||
| -rw-r--r-- | src/zisp/io.zig | 78 | ||||
| -rw-r--r-- | src/zisp/io/Parser.zig | 5 | ||||
| -rw-r--r-- | src/zisp/io/Printer.zig | 147 | ||||
| -rw-r--r-- | src/zisp/io/decode.zig | 1 | ||||
| -rw-r--r-- | src/zisp/io/encode.zig | 1 | ||||
| -rw-r--r-- | src/zisp/io/parse.zig | 42 | ||||
| -rw-r--r-- | src/zisp/io/print.zig | 137 | ||||
| -rw-r--r-- | src/zisp/io/read.zig | 14 | ||||
| -rw-r--r-- | src/zisp/io/write.zig | 1 |
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 |
