summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.zig13
-rw-r--r--src/zisp.zig5
-rw-r--r--src/zisp/gc.zig20
-rw-r--r--src/zisp/io.zig58
-rw-r--r--src/zisp/io/Decoder.zig22
-rw-r--r--src/zisp/io/Encoder.zig24
-rw-r--r--src/zisp/io/Parser.zig64
7 files changed, 137 insertions, 69 deletions
diff --git a/src/main.zig b/src/main.zig
index d08f9a1..6559046 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -1,25 +1,24 @@
const std = @import("std");
const zisp = @import("zisp");
+const File = std.Io.File;
+
const gc = zisp.gc;
const io = zisp.io;
const value = zisp.value;
pub fn main() !u8 {
- const alloc = std.heap.smp_allocator;
- const gst_io = std.Io.Threaded.global_single_threaded.io();
+ try zisp.init();
var stdin_buffer: [4096]u8 = undefined;
- var stdin_reader = std.Io.File.stdin().reader(gst_io, &stdin_buffer);
+ var stdin_reader = File.stdin().reader(io.mainIo(), &stdin_buffer);
const reader = &stdin_reader.interface;
var stdout_buffer: [4096]u8 = undefined;
- var stdout_writer = std.Io.File.stdout().writer(gst_io, &stdout_buffer);
+ var stdout_writer = File.stdout().writer(io.mainIo(), &stdout_buffer);
const writer = &stdout_writer.interface;
- try gc.init();
-
- var p = try io.Parser.init(alloc);
+ var p = try io.Parser.init();
defer p.deinit();
while (true) {
const datum = p.run(reader) catch {
diff --git a/src/zisp.zig b/src/zisp.zig
index dff410f..88edc88 100644
--- a/src/zisp.zig
+++ b/src/zisp.zig
@@ -7,6 +7,11 @@ pub const value = @import("zisp/value.zig");
pub const _test = @import("test/all.zig");
+pub fn init() !void {
+ try gc.init();
+ try io.init();
+}
+
test {
std.testing.refAllDecls(@This());
}
diff --git a/src/zisp/gc.zig b/src/zisp/gc.zig
index b2fcc46..0e47682 100644
--- a/src/zisp/gc.zig
+++ b/src/zisp/gc.zig
@@ -17,22 +17,14 @@ var init_done = false;
pub fn init() !void {
if (init_done) return;
defer init_done = true;
- const alloc = std.heap.smp_allocator;
- initCustom(
- alloc,
- try ListPool.init(alloc),
- try IstrSet.init(alloc),
- );
+ main_alloc = std.heap.smp_allocator;
+ main_list_pool = try ListPool.init(main_alloc);
+ main_istr_set = try IstrSet.init(main_alloc);
}
-pub fn initCustom(
- alloc: Alloc,
- list_pool: ListPool,
- istr_set: IstrSet,
-) void {
- main_alloc = alloc;
- main_list_pool = list_pool;
- main_istr_set = istr_set;
+pub fn mainAlloc() Alloc {
+ init() catch @panic("OOM"); // TODO this is only here for the test suite
+ return main_alloc;
}
pub fn mainListPool() *ListPool {
diff --git a/src/zisp/io.zig b/src/zisp/io.zig
index 0a7e5dd..f0d0a8f 100644
--- a/src/zisp/io.zig
+++ b/src/zisp/io.zig
@@ -1,5 +1,6 @@
const std = @import("std");
+const gc = @import("gc.zig");
const value = @import("value.zig");
const Alloc = std.mem.Allocator;
@@ -14,6 +15,34 @@ pub const Printer = @import("io/Printer.zig");
pub const Decoder = @import("io/Decoder.zig");
pub const Encoder = @import("io/Encoder.zig");
+var main_io: std.Io = undefined;
+var main_decoder: Decoder = undefined;
+var main_encoder: Encoder = undefined;
+
+var init_done = false;
+
+pub fn init() !void {
+ if (init_done) return;
+ defer init_done = true;
+ main_io = std.Io.Threaded.global_single_threaded.io();
+ main_decoder = try .init(gc.mainAlloc());
+ main_encoder = try .init(gc.mainAlloc());
+}
+
+pub fn mainIo() std.Io {
+ return main_io;
+}
+
+pub fn mainDecoder() *Decoder {
+ init() catch @panic("OOM"); // TODO this is only here for the test suite
+ return &main_decoder;
+}
+
+pub fn mainEncoder() *Encoder {
+ init() catch @panic("OOM"); // TODO this is only here for the test suite
+ return &main_encoder;
+}
+
// Parse
const ParserErrors = error{
@@ -51,26 +80,11 @@ pub fn print(writer: *Writer, v: Value) !void {
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));
+pub fn printStdout(v: Value) !void {
+ var stdout_buffer: [4096]u8 = undefined;
+ var stdout_writer = std.Io.File.stdout().writer(main_io, &stdout_buffer);
+ const writer = &stdout_writer.interface;
+ try print(writer, v);
+ try writer.writeByte('\n');
+ try writer.flush();
}
diff --git a/src/zisp/io/Decoder.zig b/src/zisp/io/Decoder.zig
index 95a0b68..ac39a02 100644
--- a/src/zisp/io/Decoder.zig
+++ b/src/zisp/io/Decoder.zig
@@ -1 +1,23 @@
const std = @import("std");
+
+const Alloc = std.mem.Allocator;
+
+const io = @import("../io.zig");
+const value = @import("../value.zig");
+
+const Value = value.Value;
+
+const Decoder = @This();
+
+alloc: Alloc,
+
+pub fn init(alloc: Alloc) !Decoder {
+ return .{ .alloc = alloc };
+}
+
+pub fn decodeInPlace(d: *Decoder, v: Value) !Value {
+ std.debug.print("decode: ", .{});
+ try io.printStdout(v);
+ _ = d;
+ return v;
+}
diff --git a/src/zisp/io/Encoder.zig b/src/zisp/io/Encoder.zig
index eb27e20..fb05e22 100644
--- a/src/zisp/io/Encoder.zig
+++ b/src/zisp/io/Encoder.zig
@@ -1 +1,23 @@
-// wip
+const std = @import("std");
+
+const Alloc = std.mem.Allocator;
+
+const io = @import("../io.zig");
+const value = @import("../value.zig");
+
+const Value = value.Value;
+
+const Encoder = @This();
+
+alloc: Alloc,
+
+pub fn init(alloc: Alloc) !Encoder {
+ return .{ .alloc = alloc };
+}
+
+pub fn encode(e: *Encoder, v: Value) !Value {
+ std.debug.print("encode: ", .{});
+ try io.printStdout(v);
+ _ = e;
+ return v;
+}
diff --git a/src/zisp/io/Parser.zig b/src/zisp/io/Parser.zig
index f768468..6e9f87e 100644
--- a/src/zisp/io/Parser.zig
+++ b/src/zisp/io/Parser.zig
@@ -40,11 +40,13 @@ const List = std.ArrayListUnmanaged;
const Reader = std.Io.Reader;
const gc = @import("../gc.zig");
+const io = @import("../io.zig");
const lib = @import("../lib.zig");
const value = @import("../value.zig");
const ListPool = gc.ListPool;
const IstrSet = gc.IstrSet;
+const Decoder = io.Decoder;
const Value = value.Value;
const Parser = @This();
@@ -95,22 +97,23 @@ pub const Context = struct {
list_pool: ?*ListPool,
istr_set: ?*IstrSet,
alloc: Alloc,
+ctx_stack: List(Context),
+str_chars: List(u8),
+list_elts: List(Value),
+decoder: ?*Decoder,
reader: *Reader = undefined,
-
context: Context = .{},
-ctx_stack: List(Context) = undefined,
-str_chars: List(u8) = undefined,
-list_elts: List(Value) = undefined,
-
result: Value = undefined,
unread_char: ?u8 = null,
err_msg: []const u8 = undefined,
-pub fn init(alloc: Alloc) !Parser {
+pub fn init() !Parser {
const list_pool = gc.mainListPool();
const istr_set = gc.mainIstrSet();
- return initCustom(list_pool, istr_set, alloc, 32, 2048, 32);
+ const alloc = gc.mainAlloc();
+ const decoder = io.mainDecoder();
+ return initCustom(list_pool, istr_set, alloc, 32, 2048, 32, decoder);
}
pub fn initCustom(
@@ -120,16 +123,17 @@ pub fn initCustom(
init_ctx_stack_cap: usize,
init_str_chars_cap: usize,
init_list_elts_cap: usize,
+ decoder: ?*Decoder,
) !Parser {
- var p: Parser = .{
+ return .{
.list_pool = list_pool,
.istr_set = istr_set,
.alloc = alloc,
+ .ctx_stack = try .initCapacity(alloc, init_ctx_stack_cap),
+ .str_chars = try .initCapacity(alloc, init_str_chars_cap),
+ .list_elts = try .initCapacity(alloc, init_list_elts_cap),
+ .decoder = decoder,
};
- p.ctx_stack = try .initCapacity(alloc, init_ctx_stack_cap);
- p.str_chars = try .initCapacity(alloc, init_str_chars_cap);
- p.list_elts = try .initCapacity(alloc, init_list_elts_cap);
- return p;
}
pub fn deinit(p: *Parser) void {
@@ -254,10 +258,10 @@ fn makeList(p: *Parser, vals: []const Value) !Value {
const Fn = enum {
parseUnit,
- parseDatum,
endUnit,
returnContext,
- parseJoin,
+ parseDatum,
+ endDatum,
endJoinDatum,
parseHashDatum,
endHashDatum,
@@ -270,10 +274,10 @@ const Fn = enum {
inline fn call(p: *Parser, f: Fn) !void {
try switch (f) {
.parseUnit => p.parseUnit(),
- .parseDatum => p.parseDatum(),
.endUnit => p.endUnit(),
.returnContext => p.returnContext(),
- .parseJoin => p.parseJoin(),
+ .parseDatum => p.parseDatum(),
+ .endDatum => p.endDatum(),
.endJoinDatum => p.endJoinDatum(),
.parseHashDatum => p.parseHashDatum(),
.endHashDatum => p.endHashDatum(),
@@ -354,8 +358,8 @@ fn subr(p: *Parser, start: Fn, next: Fn) !void {
p.context.next = start;
}
-fn jump(p: *Parser, next: Fn, val: ?Value) void {
- if (val) |v| p.result = v;
+fn jump(p: *Parser, next: Fn, val: ?Value) !void {
+ if (val) |v| p.result = try p.decode(v);
p.context.next = next;
}
@@ -365,11 +369,21 @@ fn abort(p: *Parser, next: Fn, unread_c: u8) void {
p.context.next = next;
}
-fn retval(p: *Parser, val: Value) void {
+fn retval(p: *Parser, val: Value) !void {
+ p.result = try p.decode(val);
+ p.ret();
+}
+
+fn retNoDecode(p: *Parser, val: Value) void {
p.result = val;
p.ret();
}
+fn decode(p: *Parser, val: Value) !Value {
+ if (p.decoder) |dec| return dec.decodeInPlace(val);
+ return val;
+}
+
//
// Start parser functions
//
@@ -408,20 +422,20 @@ fn endUnit(p: *Parser) !void {
}
fn returnContext(p: *Parser) !void {
- return p.retval(p.context.val);
+ return p.retNoDecode(p.context.val);
}
fn parseDatum(p: *Parser) !void {
const c = p.getUnread() orelse try p.readNoEof("datum");
if (isBareChar(c) or isSpecialBareChar(c)) {
- return p.jump(.parseJoin, try p.getBareString(c));
+ return p.jump(.endDatum, try p.getBareString(c));
} else {
- return p.parseCladDatum(c, .parseJoin);
+ return p.parseCladDatum(c, .endDatum);
}
}
-fn parseJoin(p: *Parser) !void {
+fn endDatum(p: *Parser) !void {
if (p.result.eq(value.none)) {
return p.ret();
}
@@ -445,7 +459,7 @@ fn endJoinDatum(p: *Parser) !void {
const join = p.context.char;
if (p.result.eq(value.none)) {
if (join == 0) {
- return p.retval(prev);
+ return p.retNoDecode(prev);
} else {
return p.err(.InvalidCharacter, "join datum");
}
@@ -457,7 +471,7 @@ fn endJoinDatum(p: *Parser) !void {
else => unreachable,
};
const joined = try p.makeList(&.{ rune, prev, p.result });
- return p.jump(.parseJoin, joined);
+ return p.jump(.endDatum, joined);
}
fn getBareString(p: *Parser, c1: u8) !Value {