summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.zig14
-rw-r--r--src/test/data/parser-test-1.scm4
-rw-r--r--src/test/parse.zig61
-rw-r--r--src/test/strings.zig15
-rw-r--r--src/zisp/gc.zig10
-rw-r--r--src/zisp/io/Parser.zig10
-rw-r--r--src/zisp/io/parser.zig5
-rw-r--r--src/zisp/io/unparser.zig30
-rw-r--r--src/zisp/value.zig9
-rw-r--r--src/zisp/value/rune.zig2
-rw-r--r--src/zisp/value/sstr.zig2
11 files changed, 98 insertions, 64 deletions
diff --git a/src/main.zig b/src/main.zig
index 9e86d03..faeb534 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -2,11 +2,20 @@ const std = @import("std");
const zisp = @import("zisp");
+const gstIo = std.Io.Threaded.global_single_threaded.io();
+
pub fn main() !void {
- const reader = std.io.getStdIn().reader().any();
- const writer = std.io.getStdOut().writer().any();
+ var stdin_buffer: [4096]u8 = undefined;
+ var stdin_reader = std.Io.File.stdin().reader(gstIo, &stdin_buffer);
+ const reader = &stdin_reader.interface;
+
+ var stdout_buffer: [4096]u8 = undefined;
+ var stdout_writer = std.Io.File.stdout().writer(gstIo, &stdout_buffer);
+ const writer = &stdout_writer.interface;
+
while (true) {
try writer.writeAll("> ");
+ try writer.flush();
const datum = zisp.io.parser.parse(reader);
if (datum.eq(zisp.value.eof)) {
try writer.writeAll("\n");
@@ -15,5 +24,6 @@ pub fn main() !void {
try writer.writeAll("= ");
try zisp.io.unparser.unparse(writer, datum);
try writer.writeAll("\n");
+ try writer.flush();
}
}
diff --git a/src/test/data/parser-test-1.scm b/src/test/data/parser-test-1.scm
index 87c41b5..374b4c6 100644
--- a/src/test/data/parser-test-1.scm
+++ b/src/test/data/parser-test-1.scm
@@ -149,7 +149,7 @@
(error "cannot"
value dscr)))))
-(define (bsrf/d bstr . indxs)
+(define (bsrf/d bstr & indxs)
(letvls (((bvec offset dscr)
(bsunwp bstr)))
(let loop ((bvec bvec)
@@ -166,7 +166,7 @@
dscr*
(cdr indxs)))))))
-(define (bst!/d bstr . args)
+(define (bst!/d bstr & args)
(letvls (((bvec offset dscr)
(bsunwp bstr)))
(let loop ((bvec bvec)
diff --git a/src/test/parse.zig b/src/test/parse.zig
index dd26098..8c44454 100644
--- a/src/test/parse.zig
+++ b/src/test/parse.zig
@@ -3,14 +3,16 @@ const std = @import("std");
const testing = std.testing;
const expect = testing.expect;
+const gstIo = std.Io.Threaded.global_single_threaded.io();
+
pub const io = @import("../zisp/io.zig");
pub const value = @import("../zisp/value.zig");
pub const Value = value.Value;
fn parse(str: []const u8) Value {
- var fbs = std.io.fixedBufferStream(str);
- return io.parser.parse(fbs.reader().any());
+ var fbs = std.Io.Reader.fixed(str);
+ return io.parser.parse(&fbs);
}
test "parse empty" {
@@ -42,7 +44,7 @@ test "parse short bare string" {
try expect(parse("|x()|").eq(str("x()")));
try expect(parse("|{\\|}|").eq(str("{|}")));
try expect(parse("foobar").eq(str("foobar")));
- try expect(parse("!$%&*+").eq(str("!$%&*+")));
+ try expect(parse("!$%.*+").eq(str("!$%.*+")));
try expect(parse("-/<=>?").eq(str("-/<=>?")));
try expect(parse("@^_~00").eq(str("@^_~00")));
}
@@ -54,7 +56,7 @@ test "parse long bare string" {
try expect(parse("+foo.bar.baz").eq(str("+foo.bar.baz")));
try expect(parse("-foo.bar.baz").eq(str("-foo.bar.baz")));
try expect(parse("0foo.bar.baz").eq(str("0foo.bar.baz")));
- try expect(parse("!$%&*+-/<=>?@^_~").eq(str("!$%&*+-/<=>?@^_~")));
+ try expect(parse("!$%*+-./<=>?@^_~").eq(str("!$%*+-./<=>?@^_~")));
try expect(parse("|foo\\x20;bar\\x0a;baz|").eq(str("foo bar\nbaz")));
}
@@ -104,7 +106,7 @@ test "parse3" {
}
test "parse4" {
- const val = parse("(foo . ;~x bar ;~y)");
+ const val = parse("(foo & ;~x bar ;~y)");
const s = value.sstr.unpack(value.pair.car(val));
try testing.expectEqualStrings("foo", s.slice());
@@ -114,33 +116,33 @@ test "parse4" {
}
test "unparse" {
- var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init;
- var out: std.ArrayList(u8) = .init(gpa.allocator());
-
- const w = out.writer();
+ var buf: [32]u8 = undefined;
+ var w = std.Io.Writer.fixed(&buf);
const v = parse("#foo");
- try io.unparser.unparse(w, v);
- try testing.expectEqualStrings("#foo", try out.toOwnedSlice());
+ try io.unparser.unparse(&w, v);
+ try testing.expectEqualStrings("#foo", buf[0..w.end]);
}
test "unparse2" {
- var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init;
- var out: std.ArrayList(u8) = .init(gpa.allocator());
-
- const w = out.writer();
+ var buf: [128]u8 = undefined;
+ var w = std.Io.Writer.fixed(&buf);
const v = parse("#{foo bar['x]}");
- try io.unparser.unparse(w, v);
+ try io.unparser.unparse(&w, v);
try testing.expectEqualStrings(
- "(#HASH #BRACE foo (#JOIN bar #SQUARE (#QUOTE . x)))",
- try out.toOwnedSlice(),
+ "(#HASH #BRACE foo (#JOIN bar #SQUARE (#QUOTE & x)))",
+ buf[0..w.end],
);
}
fn writeParseResult(str: []const u8) !void {
- const w = std.io.getStdErr().writer();
+ var buf: [64]u8 = undefined;
+ var fw = std.Io.File.stderr().writer(gstIo, &buf);
+ const w = &fw.interface;
+
const v = parse(str);
try io.unparser.unparse(w, v);
try w.writeByte('\n');
+ try w.flush();
}
test "unparse3" {
@@ -152,7 +154,7 @@ test "unparse4" {
}
test "unparse5" {
- try writeParseResult("(;~foo foo ;~bar . ;~bar bar ;~bar)");
+ try writeParseResult("(;~foo foo ;~bar & ;~bar bar ;~bar)");
}
test "unparse6" {
@@ -160,12 +162,12 @@ test "unparse6" {
}
test "unparse7" {
- try writeParseResult("#`(#,(->keyword (syntax->datum #'sym)) . in)");
+ try writeParseResult("#`(#,(->keyword (syntax->datum #'sym)) & in)");
}
fn parseBench(path: []const u8, iters: usize) !void {
- const file = try std.fs.cwd().openFile(path, .{});
- defer file.close();
+ const file = try std.Io.Dir.cwd().openFile(gstIo, path, .{});
+ defer file.close(gstIo);
var sfa = io.parser.DefaultSfa.init(std.heap.smp_allocator);
var parser = try io.parser.initSfa(&sfa);
@@ -174,24 +176,21 @@ fn parseBench(path: []const u8, iters: usize) !void {
var timer = try std.time.Timer.start();
for (0..iters) |i| {
_ = i;
- var br = std.io.bufferedReader(file.reader());
- const reader = br.reader().any();
- // const reader = file.reader().any();
+ var buf: [4096]u8 = undefined;
+ var reader = file.reader(gstIo, &buf);
var v: Value = undefined;
while (true) {
- // std.debug.print("hihi {s}\n", .{path});
- v = parser.run(reader) catch |e| {
+ v = parser.run(&reader.interface) catch |e| {
std.debug.print("\nfile pos: {}\n", .{
- try file.getPos(),
+ reader.logicalPos(),
});
return e;
};
- // try io.unparser.unparse(std.io.getStdOut().writer().any(), v);
if (value.eof.eq(v)) {
break;
}
}
- try file.seekTo(0);
+ try reader.seekTo(0);
}
const ns: f64 = @floatFromInt(timer.lap());
const secs = ns / 1_000_000_000;
diff --git a/src/test/strings.zig b/src/test/strings.zig
index 8f640f4..3a0585e 100644
--- a/src/test/strings.zig
+++ b/src/test/strings.zig
@@ -2,6 +2,8 @@ const std = @import("std");
const testing = std.testing;
+const gstIo = std.Io.Threaded.global_single_threaded.io();
+
pub const value = @import("../zisp/value.zig");
const istr = value.istr;
@@ -11,20 +13,27 @@ test "istr" {
const s1 = "foo bar baz";
const v1 = istr.intern(s1);
const v1_len: usize = @intCast(fx.unpack(istr.len(v1)));
+
try testing.expectEqualStrings(s1, istr.assert(v1).bytes());
try testing.expectEqual(s1.len, v1_len);
- const file = try std.fs.cwd().openFile("src/test/data/string.txt", .{});
- defer file.close();
+ const path = "src/test/data/string.txt";
+ var file = try std.Io.Dir.cwd().openFile(gstIo, path, .{});
+ defer file.close(gstIo);
+
var s2_buf: [4096]u8 = undefined;
- const s2_len = try file.readAll(&s2_buf);
+ const s2_len = try file.readStreaming(gstIo, &.{&s2_buf});
var s2: []u8 = s2_buf[0..s2_len];
+
const v2 = istr.intern(s2);
const v2_len: usize = @intCast(fx.unpack(istr.len(v2)));
+
var s2_orig_buf: [4096]u8 = undefined;
@memcpy(&s2_orig_buf, &s2_buf);
const s2_orig = s2_orig_buf[0..s2_len];
+
s2[0] = s2[0] +% 1;
+
try testing.expectEqualStrings(s2_orig, istr.assert(v2).bytes());
try testing.expectEqual(s2_len, v2_len);
}
diff --git a/src/zisp/gc.zig b/src/zisp/gc.zig
index 2f51b9b..4fc2c90 100644
--- a/src/zisp/gc.zig
+++ b/src/zisp/gc.zig
@@ -13,10 +13,16 @@ pub const alloc = std.heap.smp_allocator;
// Cons cells
-var cons_pool = std.heap.MemoryPool([2]Value).init(alloc);
+const ConsPool = std.heap.MemoryPool([2]Value);
+var cons_pool: ConsPool = undefined;
+var need_init = true;
pub fn cons(v1: Value, v2: Value) *[2]Value {
- const mem = cons_pool.create() catch @panic("OOM");
+ if (need_init) {
+ cons_pool = ConsPool.initCapacity(alloc, 64) catch @panic("OOM");
+ need_init = false;
+ }
+ const mem = cons_pool.create(alloc) catch @panic("OOM");
mem[0] = v1;
mem[1] = v2;
return mem;
diff --git a/src/zisp/io/Parser.zig b/src/zisp/io/Parser.zig
index 57cdc14..2c381e1 100644
--- a/src/zisp/io/Parser.zig
+++ b/src/zisp/io/Parser.zig
@@ -119,7 +119,8 @@ pub const Alloc = struct {
};
alloc: Alloc,
-input: std.io.AnyReader = undefined,
+io: std.Io,
+input: *std.Io.Reader = undefined,
context: Context = .{},
stack: List(Context) = undefined,
chars: List(u8) = undefined,
@@ -130,10 +131,11 @@ err_msg: []const u8 = undefined,
pub fn init(
alloc: Alloc,
+ io: std.Io,
init_stack_capacity: usize,
init_chars_capacity: usize,
) !Parser {
- var p: Parser = .{ .alloc = alloc };
+ 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);
return p;
@@ -155,7 +157,7 @@ fn read(p: *Parser) !?u8 {
.{p.unread_char.?},
);
}
- const c = p.input.readByte() catch |e| switch (e) {
+ const c = p.input.takeByte() catch |e| switch (e) {
error.EndOfStream => return null,
else => return p.err(.ReadError, "???"),
};
@@ -242,7 +244,7 @@ fn call(p: *Parser, f: Fn) !void {
};
}
-pub fn run(p: *Parser, input: std.io.AnyReader) !Value {
+pub fn run(p: *Parser, input: *std.Io.Reader) !Value {
p.input = input;
p.context.next = .parseUnit;
while (p.context.next) |next| {
diff --git a/src/zisp/io/parser.zig b/src/zisp/io/parser.zig
index cfe2bf1..49d260c 100644
--- a/src/zisp/io/parser.zig
+++ b/src/zisp/io/parser.zig
@@ -44,17 +44,18 @@ pub fn initSfa(alloc: anytype) !Parser {
const SfaType = @typeInfo(@TypeOf(alloc)).pointer.child;
return Parser.init(
alloc.allocator(),
+ std.Io.Threaded.global_single_threaded.io(),
SfaType.init_stack_capacity,
SfaType.init_chars_capacity,
);
}
-pub fn parse(input: std.io.AnyReader) Value {
+pub fn parse(input: *std.Io.Reader) Value {
return _parse(input, true);
}
pub fn _parse(
- input: std.io.AnyReader,
+ input: *std.Io.Reader,
comptime panic: bool,
) if (panic) Value else error{ ParseError, OutOfMemory }!Value {
const alloc = std.heap.smp_allocator;
diff --git a/src/zisp/io/unparser.zig b/src/zisp/io/unparser.zig
index 64e18d0..04184fa 100644
--- a/src/zisp/io/unparser.zig
+++ b/src/zisp/io/unparser.zig
@@ -6,10 +6,9 @@ const value = @import("../value.zig");
const istr = value.istr;
const seq = value.seq;
-const ShortString = value.ShortString;
const Value = value.Value;
-pub fn unparse(w: anytype, v: Value) anyerror!void {
+pub fn unparse(w: *std.Io.Writer, v: Value) anyerror!void {
// zig fmt: off
try if (v.isDouble()) unparseDouble(w, v)
else if (v.isFixnum()) unparseFixnum(w, v)
@@ -22,40 +21,41 @@ pub fn unparse(w: anytype, v: Value) anyerror!void {
else if (v.isSstr()) unparseSstr(w, v)
;
// zig fmt: on
+ try w.flush();
}
-fn unparseDouble(w: anytype, v: Value) !void {
+fn unparseDouble(w: *std.Io.Writer, v: Value) !void {
_ = w;
_ = v;
@panic("not implemented");
}
-fn unparseFixnum(w: anytype, v: Value) !void {
+fn unparseFixnum(w: *std.Io.Writer, v: Value) !void {
_ = w;
_ = v;
@panic("not implemented");
}
-fn unparseRune(w: anytype, v: Value) !void {
+fn unparseRune(w: *std.Io.Writer, v: Value) !void {
const name = value.rune.unpack(v);
try w.writeByte('#');
- try w.writeAll(name.constSlice());
+ try w.writeAll(name.slice());
}
-fn unparseSstr(w: anytype, v: Value) !void {
+fn unparseSstr(w: *std.Io.Writer, v: Value) !void {
// TODO: Check if pipes/escapes necessary.
const str = value.sstr.unpack(v);
- try w.writeAll(str.constSlice());
+ try w.writeAll(str.slice());
}
-fn unparseChar(w: anytype, v: Value) !void {
+fn unparseChar(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]);
}
-fn unparseMisc(w: anytype, v: Value) !void {
+fn unparseMisc(w: *std.Io.Writer, v: Value) !void {
try switch (v.bits) {
value.f.bits => w.writeAll("#f"),
value.t.bits => w.writeAll("#t"),
@@ -67,13 +67,13 @@ fn unparseMisc(w: anytype, v: Value) !void {
};
}
-fn unparseSrat(w: anytype, v: Value) !void {
+fn unparseSrat(w: *std.Io.Writer, v: Value) !void {
_ = w;
_ = v;
@panic("not implemented");
}
-fn unparsePair(w: anytype, p: *[2]Value) !void {
+fn unparsePair(w: *std.Io.Writer, p: *[2]Value) !void {
try w.writeByte('(');
try unparse(w, p[0]);
var cdr = p[1];
@@ -83,21 +83,21 @@ fn unparsePair(w: anytype, p: *[2]Value) !void {
}
if (!value.nil.eq(cdr)) {
try w.writeByte(' ');
- try w.writeByte('.');
+ try w.writeByte('&');
try w.writeByte(' ');
try unparse(w, cdr);
}
try w.writeByte(')');
}
-fn unparseSeq(w: anytype, s: *seq.Header) !void {
+fn unparseSeq(w: *std.Io.Writer, s: *seq.Header) !void {
switch (s.type) {
.string => try unparseString(w, s),
else => @panic("not implemented"),
}
}
-fn unparseString(w: anytype, s: *seq.Header) !void {
+fn unparseString(w: *std.Io.Writer, s: *seq.Header) !void {
// TODO: Check if pipes/escapes necessary.
try w.writeByte('|');
try w.writeAll(s.bytes());
diff --git a/src/zisp/value.zig b/src/zisp/value.zig
index 449a577..2d148ed 100644
--- a/src/zisp/value.zig
+++ b/src/zisp/value.zig
@@ -170,7 +170,14 @@ const endian = builtin.target.cpu.arch.endian();
const max = std.math.maxInt;
/// Used when dealing with runes and short strings.
-pub const ShortString = std.BoundedArray(u8, 6);
+pub const ShortString = struct {
+ len: u8,
+ buf: [6]u8,
+
+ pub fn slice(this: @This()) []const u8 {
+ return this.buf[0..this.len];
+ }
+};
/// Used to find the length of a rune or short string.
pub fn sstrLen(x: u64) u8 {
diff --git a/src/zisp/value/rune.zig b/src/zisp/value/rune.zig
index e75c276..f49feb4 100644
--- a/src/zisp/value/rune.zig
+++ b/src/zisp/value/rune.zig
@@ -51,7 +51,7 @@ pub fn unpack(v: Value) ShortString {
assert(v);
const s: [6]u8 = @bitCast(v.rune.name);
const l = value.sstrLen(v.bits);
- return .{ .buffer = s, .len = l };
+ return .{ .buf = s, .len = l };
}
// Zisp API
diff --git a/src/zisp/value/sstr.zig b/src/zisp/value/sstr.zig
index 4f0336e..b4cabff 100644
--- a/src/zisp/value/sstr.zig
+++ b/src/zisp/value/sstr.zig
@@ -45,7 +45,7 @@ pub fn unpack(v: Value) ShortString {
assert(v);
const s: [6]u8 = @bitCast(v.sstr.string);
const l = value.sstrLen(v.bits);
- return .{ .buffer = s, .len = l };
+ return .{ .buf = s, .len = l };
}
// No Zisp API for sstr specifically, since it's a string. See string.zig.