summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.zig14
-rw-r--r--src/test/parse.zig30
-rw-r--r--src/zisp/io/Parser.zig83
-rw-r--r--src/zisp/io/parse.zig52
-rw-r--r--src/zisp/io/read.zig8
5 files changed, 107 insertions, 80 deletions
diff --git a/src/main.zig b/src/main.zig
index 55fecdf..a01daa9 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -2,20 +2,20 @@ const std = @import("std");
const zisp = @import("zisp");
-const alloc = std.heap.smp_allocator;
-const gstio = std.Io.Threaded.global_single_threaded.io();
-
pub fn main() !u8 {
+ const alloc = std.heap.smp_allocator;
+ const io = std.Io.Threaded.global_single_threaded.io();
+
var stdin_buffer: [4096]u8 = undefined;
- var stdin_reader = std.Io.File.stdin().reader(gstio, &stdin_buffer);
+ var stdin_reader = std.Io.File.stdin().reader(io, &stdin_buffer);
const reader = &stdin_reader.interface;
var stdout_buffer: [4096]u8 = undefined;
- var stdout_writer = std.Io.File.stdout().writer(gstio, &stdout_buffer);
+ var stdout_writer = std.Io.File.stdout().writer(io, &stdout_buffer);
const writer = &stdout_writer.interface;
- var sfa = zisp.io.Parser.DefaultSfa.withFallback(alloc);
- var p = try zisp.io.Parser.initWithSfa(&sfa, gstio);
+ var p, const sfa = try zisp.io.Parser.init(alloc, io);
+ defer p.deinit(sfa);
while (true) {
const datum = p.run(reader) catch {
const format = "Parse error: {s}, pos: {d}, unread_char: {s}\n";
diff --git a/src/test/parse.zig b/src/test/parse.zig
index 272c92a..61f8fc3 100644
--- a/src/test/parse.zig
+++ b/src/test/parse.zig
@@ -3,16 +3,17 @@ const std = @import("std");
const testing = std.testing;
const expect = testing.expect;
-const gst_io = std.Io.Threaded.global_single_threaded.io();
+const alloc = std.heap.smp_allocator;
+const io = std.Io.Threaded.global_single_threaded.io();
-pub const io = @import("../zisp/io.zig");
-pub const value = @import("../zisp/value.zig");
+pub const zisp = @import("../zisp.zig");
-pub const Value = value.Value;
+pub const value = zisp.value;
+pub const Value = zisp.Value;
fn parse(str: []const u8) Value {
var fbs = std.Io.Reader.fixed(str);
- return io.parse.fromReader(&fbs);
+ return zisp.io.parse.fromReaderNoError(alloc, io, &fbs);
}
test "parse empty" {
@@ -119,7 +120,7 @@ test "print" {
var buf: [32]u8 = undefined;
var w = std.Io.Writer.fixed(&buf);
const v = parse("#foo");
- try io.print.toWriter(&w, v);
+ try zisp.io.print.toWriter(&w, v);
try testing.expectEqualStrings("#foo", buf[0..w.end]);
}
@@ -127,7 +128,7 @@ test "print2" {
var buf: [128]u8 = undefined;
var w = std.Io.Writer.fixed(&buf);
const v = parse("#{foo bar['x]}");
- try io.print.toWriter(&w, v);
+ try zisp.io.print.toWriter(&w, v);
try testing.expectEqualStrings(
"(#HASH #BRACE foo (#JOIN bar #SQUARE (#QUOTE & x)))",
buf[0..w.end],
@@ -136,11 +137,11 @@ test "print2" {
fn parseAndPrint(str: []const u8) !void {
var buf: [64]u8 = undefined;
- var fw = std.Io.File.stderr().writer(gst_io, &buf);
+ var fw = std.Io.File.stderr().writer(io, &buf);
const w = &fw.interface;
const v = parse(str);
- try io.print.toWriter(w, v);
+ try zisp.io.print.toWriter(w, v);
try w.writeByte('\n');
try w.flush();
}
@@ -166,18 +167,17 @@ test "print7" {
}
fn parseBench(path: []const u8, iters: usize) !void {
- const file = try std.Io.Dir.cwd().openFile(gst_io, path, .{});
- defer file.close(gst_io);
+ const file = try std.Io.Dir.cwd().openFile(io, path, .{});
+ defer file.close(io);
- var sfa = io.Parser.DefaultSfa.withFallback(std.heap.smp_allocator);
- var parser = try io.Parser.initWithSfa(&sfa, gst_io);
- defer parser.deinit();
+ var parser, const sfa = try zisp.io.Parser.init(alloc, io);
+ defer parser.deinit(sfa);
var timer = try std.time.Timer.start();
for (0..iters) |i| {
_ = i;
var buf: [4096]u8 = undefined;
- var reader = file.reader(gst_io, &buf);
+ var reader = file.reader(io, &buf);
var v: Value = undefined;
while (true) {
v = parser.run(&reader.interface) catch |e| {
diff --git a/src/zisp/io/Parser.zig b/src/zisp/io/Parser.zig
index d18150e..9833baa 100644
--- a/src/zisp/io/Parser.zig
+++ b/src/zisp/io/Parser.zig
@@ -120,33 +120,23 @@ pub const Alloc = struct {
chars: std.mem.Allocator,
};
-pub fn Sfa(init_stack: usize, init_chars: usize) type {
+pub fn StackFallbackAlloc(ctx_stack_cap: usize, str_chars_cap: usize) type {
return struct {
- const Self = @This();
+ pub const ctx_stack_bytes = ctx_stack_cap * @sizeOf(Context);
+ pub const str_chars_bytes = str_chars_cap;
- pub const init_stack_capacity: usize = init_stack;
- pub const init_chars_capacity: usize = init_chars;
+ stack: std.heap.StackFallbackAllocator(ctx_stack_bytes),
+ chars: std.heap.StackFallbackAllocator(str_chars_bytes),
- pub const init_stack_mem: usize = init_stack * @sizeOf(Context);
- pub const init_chars_mem: usize = init_chars;
-
- stack: std.heap.StackFallbackAllocator(init_stack_mem),
- chars: std.heap.StackFallbackAllocator(init_chars_mem),
-
- pub fn withFallback(fallback: std.mem.Allocator) Self {
- return .{
- .stack = std.heap.stackFallback(init_stack_mem, fallback),
- .chars = std.heap.stackFallback(init_chars_mem, fallback),
- };
- }
-
- pub fn allocator(s: *Self) Alloc {
- return .{ .stack = s.stack.get(), .chars = s.chars.get() };
+ pub fn alloc(self: *@This()) Alloc {
+ return .{ .stack = self.stack.get(), .chars = self.chars.get() };
}
};
}
-pub const DefaultSfa = Sfa(32, 2048);
+const def_ctx_stack_cap = 32;
+const def_str_chars_cap = 2048;
+const DefaultSfa = StackFallbackAlloc(def_ctx_stack_cap, def_str_chars_cap);
alloc: Alloc,
io: std.Io,
@@ -159,29 +149,54 @@ result: Value = undefined,
unread_char: ?u8 = null,
err_msg: []const u8 = undefined,
-pub fn init(
+pub fn init(alloc: std.mem.Allocator, io: std.Io) !struct {
+ Parser,
+ DefaultSfa,
+} {
+ return initWithSfa(def_ctx_stack_cap, def_str_chars_cap, alloc, io);
+}
+
+pub fn initWithSfa(
+ comptime init_ctx_stack_cap: usize,
+ comptime init_str_chars_cap: usize,
+ alloc: std.mem.Allocator,
+ io: std.Io,
+) !struct {
+ Parser,
+ StackFallbackAlloc(init_ctx_stack_cap, init_str_chars_cap),
+} {
+ const Sfa = StackFallbackAlloc(init_ctx_stack_cap, init_str_chars_cap);
+ var sfa: Sfa = .{
+ .stack = std.heap.stackFallback(Sfa.ctx_stack_bytes, alloc),
+ .chars = std.heap.stackFallback(Sfa.str_chars_bytes, alloc),
+ };
+ const parser: Parser = try initCustom(
+ sfa.alloc(),
+ io,
+ init_ctx_stack_cap,
+ init_str_chars_cap,
+ );
+ return .{ parser, sfa };
+}
+
+pub fn initCustom(
alloc: Alloc,
io: std.Io,
- init_stack_capacity: usize,
- init_chars_capacity: usize,
+ init_ctx_stack_cap: usize,
+ init_str_chars_cap: usize,
) !Parser {
var p: Parser = .{ .alloc = alloc, .io = io };
- p.stack = try .initCapacity(alloc.stack, init_stack_capacity);
- p.chars = try .initCapacity(alloc.chars, init_chars_capacity);
+ p.stack = try .initCapacity(alloc.stack, init_ctx_stack_cap);
+ p.chars = try .initCapacity(alloc.chars, init_str_chars_cap);
return p;
}
-pub fn initWithSfa(sfa: anytype, io: std.Io) !Parser {
- const SfaType = @typeInfo(@TypeOf(sfa)).pointer.child;
- return init(
- sfa.allocator(),
- io,
- SfaType.init_stack_capacity,
- SfaType.init_chars_capacity,
- );
+pub fn deinit(p: *Parser, sfa: anytype) void {
+ p.deinitCustom();
+ _ = sfa;
}
-pub fn deinit(p: *Parser) void {
+pub fn deinitCustom(p: *Parser) void {
p.stack.deinit(p.alloc.stack);
p.chars.deinit(p.alloc.chars);
}
diff --git a/src/zisp/io/parse.zig b/src/zisp/io/parse.zig
index 4d00ca9..6e84b55 100644
--- a/src/zisp/io/parse.zig
+++ b/src/zisp/io/parse.zig
@@ -10,30 +10,38 @@ const Value = value.Value;
const is_test = builtin.is_test;
const is_debug = builtin.mode == .Debug;
-pub fn fromReader(input: *std.Io.Reader) Value {
- return _fromReader(input, true);
+const ParserErrors = error{
+ ParseError,
+ OutOfMemory,
+};
+
+pub fn fromReader(
+ alloc: std.mem.Allocator,
+ io: std.Io,
+ input: *std.Io.Reader,
+) ParserErrors!Value {
+ var p, const sfa = try Parser.init(alloc, io);
+ defer p.deinit(sfa);
+ return p.run(input);
}
-pub fn _fromReader(
+pub fn fromReaderNoError(
+ alloc: std.mem.Allocator,
+ io: std.Io,
input: *std.Io.Reader,
- comptime panic: bool,
-) if (panic) Value else error{ ParseError, OutOfMemory }!Value {
- const alloc = std.heap.smp_allocator;
- const io = std.Io.Threaded.global_single_threaded.io();
- var sfa = Parser.DefaultSfa.withFallback(alloc);
- var p = Parser.initWithSfa(&sfa, io) catch |e| {
- if (panic) @panic("OOM") else return e;
- };
- defer p.deinit();
- return p.run(input) catch |e| if (panic) {
- 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 });
- } else {
- return e;
+) Value {
+ var p, const sfa = Parser.init(alloc, io) catch @panic("OOM");
+ defer p.deinit(sfa);
+ 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/read.zig b/src/zisp/io/read.zig
index 5fa647e..23f0ea8 100644
--- a/src/zisp/io/read.zig
+++ b/src/zisp/io/read.zig
@@ -5,6 +5,10 @@ const decode = @import("decode.zig");
const Value = @import("../value.zig").Value;
-pub fn fromReader(reader: *std.Io.Reader) Value {
- return decode.decode(parse.fromReader(reader));
+pub fn fromReader(
+ alloc: std.mem.Allocator,
+ io: std.Io,
+ reader: *std.Io.Reader,
+) Value {
+ return decode.decode(parse.fromReader(alloc, io, reader));
}