diff options
| author | Taylan Kammer <taylan.kammer@gmail.com> | 2025-03-30 18:34:00 +0200 |
|---|---|---|
| committer | Taylan Kammer <taylan.kammer@gmail.com> | 2025-03-30 18:34:00 +0200 |
| commit | 3d05c94b9d8aa964e4ff848c95d5999cec170e04 (patch) | |
| tree | 2864753404e8c9cb9fa8bce537772a29b90d1cbd | |
| parent | 9340f3c44ca0d9d4fdee905fc6e8b428824b9185 (diff) | |
Big cleanup.
| -rw-r--r-- | build.zig | 6 | ||||
| -rw-r--r-- | src/libzisp/io/parser.zig | 80 | ||||
| -rw-r--r-- | src/main.zig | 2 | ||||
| -rw-r--r-- | src/zisp.zig (renamed from src/libzisp.zig) | 15 | ||||
| -rw-r--r-- | src/zisp/gc.zig (renamed from src/libzisp/gc.zig) | 9 | ||||
| -rw-r--r-- | src/zisp/io.zig (renamed from src/libzisp/io.zig) | 0 | ||||
| -rw-r--r-- | src/zisp/io/Parser.zig (renamed from src/libzisp/io/Parser.zig) | 71 | ||||
| -rw-r--r-- | src/zisp/io/decoder.zig (renamed from src/libzisp/io/decoder.zig) | 0 | ||||
| -rw-r--r-- | src/zisp/io/encoder.zig (renamed from src/libzisp/io/encoder.zig) | 0 | ||||
| -rw-r--r-- | src/zisp/io/parser.zig | 75 | ||||
| -rw-r--r-- | src/zisp/io/reader.zig (renamed from src/libzisp/io/reader.zig) | 0 | ||||
| -rw-r--r-- | src/zisp/io/unparser.zig (renamed from src/libzisp/io/unparser.zig) | 0 | ||||
| -rw-r--r-- | src/zisp/io/writer.zig (renamed from src/libzisp/io/writer.zig) | 0 | ||||
| -rw-r--r-- | src/zisp/lib.zig (renamed from src/libzisp/lib.zig) | 0 | ||||
| -rw-r--r-- | src/zisp/lib/list.zig (renamed from src/libzisp/lib/list.zig) | 0 | ||||
| -rw-r--r-- | src/zisp/value.zig (renamed from src/libzisp/value.zig) | 15 | ||||
| -rw-r--r-- | src/zisp/value/boole.zig (renamed from src/libzisp/value/boole.zig) | 0 | ||||
| -rw-r--r-- | src/zisp/value/char.zig (renamed from src/libzisp/value/char.zig) | 0 | ||||
| -rw-r--r-- | src/zisp/value/double.zig (renamed from src/libzisp/value/double.zig) | 0 | ||||
| -rw-r--r-- | src/zisp/value/eof.zig (renamed from src/libzisp/value/eof.zig) | 0 | ||||
| -rw-r--r-- | src/zisp/value/fixnum.zig (renamed from src/libzisp/value/fixnum.zig) | 0 | ||||
| -rw-r--r-- | src/zisp/value/istr.zig (renamed from src/libzisp/value/istr.zig) | 0 | ||||
| -rw-r--r-- | src/zisp/value/nil.zig (renamed from src/libzisp/value/nil.zig) | 0 | ||||
| -rw-r--r-- | src/zisp/value/pair.zig (renamed from src/libzisp/value/pair.zig) | 0 | ||||
| -rw-r--r-- | src/zisp/value/ptr.zig (renamed from src/libzisp/value/ptr.zig) | 0 | ||||
| -rw-r--r-- | src/zisp/value/rune.zig (renamed from src/libzisp/value/rune.zig) | 0 | ||||
| -rw-r--r-- | src/zisp/value/seq.zig (renamed from src/libzisp/value/seq.zig) | 0 | ||||
| -rw-r--r-- | src/zisp/value/sstr.zig (renamed from src/libzisp/value/sstr.zig) | 0 |
28 files changed, 118 insertions, 155 deletions
@@ -23,7 +23,7 @@ pub fn build(b: *std.Build) void { // only contains e.g. external object files, you can make this `null`. // In this case the main source file is merely a path, however, in more // complicated build scripts, this could be a generated file. - .root_source_file = b.path("src/libzisp.zig"), + .root_source_file = b.path("src/zisp.zig"), .target = target, .optimize = optimize, }); @@ -42,14 +42,14 @@ pub fn build(b: *std.Build) void { // Modules can depend on one another using the `std.Build.Module.addImport` function. // This is what allows Zig source code to use `@import("foo")` where 'foo' is not a // file path. In this case, we set up `exe_mod` to import `lib_mod`. - exe_mod.addImport("libzisp", lib_mod); + exe_mod.addImport("zisp", lib_mod); // Now, we will create a static library based on the module we created above. // This creates a `std.Build.Step.Compile`, which is the build step responsible // for actually invoking the compiler. const lib = b.addLibrary(.{ .linkage = .static, - .name = "libzisp", + .name = "zisp", .root_module = lib_mod, }); diff --git a/src/libzisp/io/parser.zig b/src/libzisp/io/parser.zig deleted file mode 100644 index d004c91..0000000 --- a/src/libzisp/io/parser.zig +++ /dev/null @@ -1,80 +0,0 @@ -const builtin = @import("builtin"); -const std = @import("std"); - -const value = @import("../value.zig"); - -const Parser = @import("Parser.zig"); - -const Value = value.Value; - -const is_test = builtin.is_test; -const is_debug = builtin.mode == .Debug; - -// In debug, we want to see if we leak, so very small numbers. -const def_init_stack_mem = (if (is_debug) 2 else 32) * @sizeOf(Parser.Context); -const def_init_chars_mem = (if (is_debug) 2 else 2048); - -pub const DefaultStackSfa = std.heap.StackFallbackAllocator(def_init_stack_mem); -pub const DefaultCharsSfa = std.heap.StackFallbackAllocator(def_init_chars_mem); - -pub fn default( - fb_alloc: *std.mem.Allocator, - stack_sfa: *DefaultStackSfa, - chars_sfa: *DefaultCharsSfa, -) !Parser { - if (!is_test and is_debug) { - fb_alloc.* = std.heap.DebugAllocator(.{}).init; - } - - const alloc = if (is_test) - std.testing.allocator - else if (is_debug) - fb_alloc.allocator() - else - std.heap.smp_allocator; - - stack_sfa.* = std.heap.stackFallback(def_init_stack_mem, alloc); - chars_sfa.* = std.heap.stackFallback(def_init_chars_mem, alloc); - - return Parser.init( - stack_sfa.get(), - chars_sfa.get(), - def_init_stack_mem, - def_init_chars_mem, - ); -} - -pub fn deinit(fb_alloc: *std.mem.Allocator) void { - if (!is_test and is_debug) { - if (fb_alloc.?.deinit() == .leak) { - @panic("parser leaked"); - } - } -} - -pub fn parse(input: std.io.AnyReader) Value { - var fb_alloc: std.mem.Allocator = undefined; - var stack_sfa: DefaultStackSfa = undefined; - var chars_sfa: DefaultCharsSfa = undefined; - var p = default(&fb_alloc, &stack_sfa, &chars_sfa) catch @panic("OOM"); - defer p.deinit(); - return p.run(input) catch { - if (p.unread_char) |c| { - std.debug.panic( - "Parse error: {s}, unread_char: 0x{x}\n", - .{ p.err_msg, c }, - ); - } else { - std.debug.panic("Parse error: {s}\n", .{p.err_msg}); - } - }; -} - -pub fn _parse(input: std.io.AnyReader) !Value { - var fb_alloc: std.mem.Allocator = undefined; - var stack_sfa: DefaultStackSfa = undefined; - var chars_sfa: DefaultCharsSfa = undefined; - var p = try default(&fb_alloc, &stack_sfa, &chars_sfa); - defer p.deinit(); - return p.run(input); -} diff --git a/src/main.zig b/src/main.zig index c52d7e5..769a906 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,6 +1,6 @@ const std = @import("std"); -const zisp = @import("libzisp"); +const zisp = @import("zisp"); pub fn main() !void { const reader = std.io.getStdIn().reader().any(); diff --git a/src/libzisp.zig b/src/zisp.zig index ced15f0..6472daf 100644 --- a/src/libzisp.zig +++ b/src/zisp.zig @@ -3,10 +3,10 @@ const std = @import("std"); const testing = std.testing; -pub const gc = @import("libzisp/gc.zig"); -pub const io = @import("libzisp/io.zig"); -pub const lib = @import("libzisp/lib.zig"); -pub const value = @import("libzisp/value.zig"); +pub const gc = @import("zisp/gc.zig"); +pub const io = @import("zisp/io.zig"); +pub const lib = @import("zisp/lib.zig"); +pub const value = @import("zisp/value.zig"); pub const Hval = gc.Hval; @@ -399,12 +399,9 @@ fn parseBench(path: []const u8, iters: usize) !void { const file = try std.fs.cwd().openFile(path, .{}); defer file.close(); - var fb_alloc: std.mem.Allocator = undefined; - var stack_sfa: io.parser.DefaultStackSfa = undefined; - var chars_sfa: io.parser.DefaultCharsSfa = undefined; - var parser = try io.parser.default(&fb_alloc, &stack_sfa, &chars_sfa); + var sfa = io.parser.DefaultSfa.init(std.heap.smp_allocator); + var parser = try io.parser.initSfa(&sfa); defer parser.deinit(); - defer io.parser.deinit(&fb_alloc); var timer = try std.time.Timer.start(); for (0..iters) |i| { diff --git a/src/libzisp/gc.zig b/src/zisp/gc.zig index 815e203..d778b77 100644 --- a/src/libzisp/gc.zig +++ b/src/zisp/gc.zig @@ -13,14 +13,7 @@ pub const Hval = union { seq_header: seq.Header, }; -var _debugAlloc = switch (builtin.mode) { - .Debug => std.heap.DebugAllocator(.{}).init, - else => undefined, -}; -const alloc = switch (builtin.mode) { - .Debug => _debugAlloc.allocator(), - else => std.heap.smp_allocator, -}; +pub const alloc = std.heap.smp_allocator; // Cons cells diff --git a/src/libzisp/io.zig b/src/zisp/io.zig index 8adf495..8adf495 100644 --- a/src/libzisp/io.zig +++ b/src/zisp/io.zig diff --git a/src/libzisp/io/Parser.zig b/src/zisp/io/Parser.zig index 6684104..08bf8ba 100644 --- a/src/libzisp/io/Parser.zig +++ b/src/zisp/io/Parser.zig @@ -97,13 +97,11 @@ fn dummyCons(v1: Value, v2: Value) Value { const real_cons = &value.pair.cons; const fake_cons = &dummyCons; -pub const ParseError = enum { +pub const Error = enum { InvalidCharacter, UnclosedString, UnexpectedEof, UnicodeError, - RuneTooLong, - OutOfMemory, OutOfRange, ReadError, }; @@ -117,11 +115,12 @@ pub const Context = struct { char: u8 = undefined, }; -// parameters -stack_alloc: std.mem.Allocator, -chars_alloc: std.mem.Allocator, +pub const Alloc = struct { + stack: std.mem.Allocator, + chars: std.mem.Allocator, +}; -// state +alloc: Alloc, input: std.io.AnyReader = undefined, context: Context = .{}, stack: List(Context) = undefined, @@ -132,24 +131,19 @@ unread_char: ?u8 = null, err_msg: []const u8 = undefined, pub fn init( - stack_alloc: std.mem.Allocator, - chars_alloc: std.mem.Allocator, - init_stack_mem: usize, - init_chars_mem: usize, + alloc: Alloc, + init_stack_capacity: usize, + init_chars_capacity: usize, ) !Parser { - var p: Parser = .{ - .stack_alloc = stack_alloc, - .chars_alloc = chars_alloc, - }; - const csize = @sizeOf(Context); - p.stack = try .initCapacity(stack_alloc, init_stack_mem / csize); - p.chars = try .initCapacity(chars_alloc, init_chars_mem); + var p: Parser = .{ .alloc = alloc }; + p.stack = try .initCapacity(alloc.stack, init_stack_capacity); + p.chars = try .initCapacity(alloc.chars, init_chars_capacity); return p; } pub fn deinit(p: *Parser) void { - p.stack.deinit(p.stack_alloc); - p.chars.deinit(p.chars_alloc); + p.stack.deinit(p.alloc.stack); + p.chars.deinit(p.alloc.chars); } // @@ -158,7 +152,10 @@ pub fn deinit(p: *Parser) void { fn read(p: *Parser) !?u8 { if (is_debug and p.unread_char != null) { - @panic("Called read() while there was an unused character!"); + std.debug.panic( + "Called read() while there was an unused character! '{c}'", + .{p.unread_char.?}, + ); } const c = p.input.readByte() catch |e| switch (e) { error.EndOfStream => return null, @@ -189,7 +186,7 @@ fn getUnread(p: *Parser) ?u8 { // fn addChar(p: *Parser, c: u8) !void { - try p.chars.append(p.chars_alloc, c); + try p.chars.append(p.alloc.chars, c); } fn getBareString(p: *Parser) Value { @@ -293,7 +290,7 @@ fn printStack(p: *Parser) void { fn err( p: *Parser, - comptime e: ParseError, + comptime e: Error, comptime msg: []const u8, ) error{ParseError} { p.err_msg = @tagName(e) ++ " at: " ++ msg; @@ -301,11 +298,11 @@ fn err( } fn push(p: *Parser, next: Fn) !void { - try p.stack.append(p.stack_alloc, .{ .next = next }); + try p.stack.append(p.alloc.stack, .{ .next = next }); } fn pushContext(p: *Parser, next: Fn) !void { - try p.stack.append(p.stack_alloc, .{ + try p.stack.append(p.alloc.stack, .{ .next = next, .val = p.context.val, .char = p.context.char, @@ -550,7 +547,7 @@ fn parseUniHex(p: *Parser) !void { } const n = try std.unicode.utf8CodepointSequenceLength(uc); - const buf = try p.chars.addManyAsSlice(p.chars_alloc, n); + const buf = try p.chars.addManyAsSlice(p.alloc.chars, n); _ = try std.unicode.utf8Encode(uc, buf); } @@ -567,20 +564,6 @@ fn parseHashExpression(p: *Parser, next: Fn) !void { const l = try parseLabel(p); return parseLabelEnd(p, l, next); } - if (isBareChar(c)) { - // Reserved for future extensions to syntax sugar. - return p.err(.InvalidCharacter, "hash expression"); - } - // fast-path to avoid subr - if (c == '\\') { - return p.jump(next, p.cons(HASH, try parseBareEscString(p))); - } - if (c == '"') { - return p.jump(next, p.cons(HASH, try parseQuotedString(p, '"'))); - } - if (c == '|') { - return p.jump(next, p.cons(HASH, try parseQuotedString(p, '|'))); - } p.unread(c); return p.subr(.parseHashDatum, next); } @@ -782,15 +765,9 @@ fn parseQuoteExpr(p: *Parser, c1: u8, next: Fn) !void { else => unreachable, }; - // fast-path to avoid subr - const c = try p.readNoEof("quote expression"); - if (isBareChar(c) or c == '\\') { - return p.jump(next, p.cons(q, try parseBareString(p, c))); - } - try p.push(next); p.context.val = q; - p.unread(c); + p.unread(try p.readNoEof("quote expression")); return p.subr(.parseDatum, .endQuoteExpr); } diff --git a/src/libzisp/io/decoder.zig b/src/zisp/io/decoder.zig index eb27e20..eb27e20 100644 --- a/src/libzisp/io/decoder.zig +++ b/src/zisp/io/decoder.zig diff --git a/src/libzisp/io/encoder.zig b/src/zisp/io/encoder.zig index eb27e20..eb27e20 100644 --- a/src/libzisp/io/encoder.zig +++ b/src/zisp/io/encoder.zig diff --git a/src/zisp/io/parser.zig b/src/zisp/io/parser.zig new file mode 100644 index 0000000..cb96e44 --- /dev/null +++ b/src/zisp/io/parser.zig @@ -0,0 +1,75 @@ +const builtin = @import("builtin"); +const std = @import("std"); + +const value = @import("../value.zig"); + +const Parser = @import("Parser.zig"); + +const Value = value.Value; + +const is_test = builtin.is_test; +const is_debug = builtin.mode == .Debug; + +const ctx_size = @sizeOf(Parser.Context); + +pub fn Sfa(init_stack: usize, init_chars: usize) type { + return struct { + const Self = @This(); + + pub const init_stack_capacity: usize = init_stack; + pub const init_chars_capacity: usize = init_chars; + + pub const init_stack_mem: usize = init_stack * ctx_size; + pub const init_chars_mem: usize = init_chars; + + stack: std.heap.StackFallbackAllocator(init_stack_mem), + chars: std.heap.StackFallbackAllocator(init_chars_mem), + + pub fn init(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) Parser.Alloc { + return .{ .stack = s.stack.get(), .chars = s.chars.get() }; + } + }; +} + +pub const DefaultSfa = Sfa(32, 2048); + +pub fn initSfa(alloc: anytype) !Parser { + const SfaType = @typeInfo(@TypeOf(alloc)).pointer.child; + return Parser.init( + alloc.allocator(), + SfaType.init_stack_capacity, + SfaType.init_chars_capacity, + ); +} + +pub fn parse(input: std.io.AnyReader) Value { + return _parse(input, true); +} + +pub fn _parse( + input: std.io.AnyReader, + comptime panic: bool, +) if (panic) Value else error{ParseError}!Value { + const alloc = std.heap.smp_allocator; + var sfa = DefaultSfa.init(alloc); + var p = initSfa(&sfa) 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; + }; +} diff --git a/src/libzisp/io/reader.zig b/src/zisp/io/reader.zig index 3465cb3..3465cb3 100644 --- a/src/libzisp/io/reader.zig +++ b/src/zisp/io/reader.zig diff --git a/src/libzisp/io/unparser.zig b/src/zisp/io/unparser.zig index d703182..d703182 100644 --- a/src/libzisp/io/unparser.zig +++ b/src/zisp/io/unparser.zig diff --git a/src/libzisp/io/writer.zig b/src/zisp/io/writer.zig index eb27e20..eb27e20 100644 --- a/src/libzisp/io/writer.zig +++ b/src/zisp/io/writer.zig diff --git a/src/libzisp/lib.zig b/src/zisp/lib.zig index 7752110..7752110 100644 --- a/src/libzisp/lib.zig +++ b/src/zisp/lib.zig diff --git a/src/libzisp/lib/list.zig b/src/zisp/lib/list.zig index 9d6a6bc..9d6a6bc 100644 --- a/src/libzisp/lib/list.zig +++ b/src/zisp/lib/list.zig diff --git a/src/libzisp/value.zig b/src/zisp/value.zig index fbe907a..e5b78ec 100644 --- a/src/libzisp/value.zig +++ b/src/zisp/value.zig @@ -281,10 +281,11 @@ pub const Value = packed union { }, /// Hexdumps the value. - pub inline fn dump(v: Value) void { + pub fn dump(v: Value) void { std.debug.dumpHex(std.mem.asBytes(&v)); } + /// Checks for bit-equality i.e. == comprison. pub fn eq(v1: Value, v2: Value) bool { return v1.bits == v2.bits; } @@ -294,32 +295,32 @@ pub const Value = packed union { // since those aren't sub-categorized into further types. /// Checks for a Zisp double, including: +nan.0, -nan.0, +inf.0, -inf.0 - pub inline fn isDouble(v: Value) bool { + pub fn isDouble(v: Value) bool { return v.ieee.exp != FILL or v.ieee.rest == 0; } /// Checks for a non-double Zisp value packed into a NaN. - pub inline fn isPacked(v: Value) bool { + pub fn isPacked(v: Value) bool { return !v.isDouble(); } /// Checks for a fixnum. - pub inline fn isFixnum(v: Value) bool { + pub fn isFixnum(v: Value) bool { return v.isPacked() and v.ieee.sign; } /// Checks for any kind of pointer. - pub inline fn isPtr(v: Value) bool { + pub fn isPtr(v: Value) bool { return v.isPacked() and !v.ieee.sign and v.ieee.quiet; } /// Checks for a non-double, non-fixnum, non-pointer Zisp value. - pub inline fn isOther(v: Value) bool { + pub fn isOther(v: Value) bool { return v.isPacked() and !v.ieee.sign and !v.ieee.quiet; } /// Checks for an other type of value based on tag. - pub inline fn isOtherTag(v: Value, tag: OtherTag) bool { + pub fn isOtherTag(v: Value, tag: OtherTag) bool { return v.isOther() and v.other.tag == tag; } }; diff --git a/src/libzisp/value/boole.zig b/src/zisp/value/boole.zig index 2e94e4d..2e94e4d 100644 --- a/src/libzisp/value/boole.zig +++ b/src/zisp/value/boole.zig diff --git a/src/libzisp/value/char.zig b/src/zisp/value/char.zig index 09a3034..09a3034 100644 --- a/src/libzisp/value/char.zig +++ b/src/zisp/value/char.zig diff --git a/src/libzisp/value/double.zig b/src/zisp/value/double.zig index 5cfe6ee..5cfe6ee 100644 --- a/src/libzisp/value/double.zig +++ b/src/zisp/value/double.zig diff --git a/src/libzisp/value/eof.zig b/src/zisp/value/eof.zig index 4b16669..4b16669 100644 --- a/src/libzisp/value/eof.zig +++ b/src/zisp/value/eof.zig diff --git a/src/libzisp/value/fixnum.zig b/src/zisp/value/fixnum.zig index 80fb4ae..80fb4ae 100644 --- a/src/libzisp/value/fixnum.zig +++ b/src/zisp/value/fixnum.zig diff --git a/src/libzisp/value/istr.zig b/src/zisp/value/istr.zig index abd0447..abd0447 100644 --- a/src/libzisp/value/istr.zig +++ b/src/zisp/value/istr.zig diff --git a/src/libzisp/value/nil.zig b/src/zisp/value/nil.zig index f95ecad..f95ecad 100644 --- a/src/libzisp/value/nil.zig +++ b/src/zisp/value/nil.zig diff --git a/src/libzisp/value/pair.zig b/src/zisp/value/pair.zig index 6ea1edf..6ea1edf 100644 --- a/src/libzisp/value/pair.zig +++ b/src/zisp/value/pair.zig diff --git a/src/libzisp/value/ptr.zig b/src/zisp/value/ptr.zig index 2ed3765..2ed3765 100644 --- a/src/libzisp/value/ptr.zig +++ b/src/zisp/value/ptr.zig diff --git a/src/libzisp/value/rune.zig b/src/zisp/value/rune.zig index 195210e..195210e 100644 --- a/src/libzisp/value/rune.zig +++ b/src/zisp/value/rune.zig diff --git a/src/libzisp/value/seq.zig b/src/zisp/value/seq.zig index 3418a5a..3418a5a 100644 --- a/src/libzisp/value/seq.zig +++ b/src/zisp/value/seq.zig diff --git a/src/libzisp/value/sstr.zig b/src/zisp/value/sstr.zig index b02fd3d..b02fd3d 100644 --- a/src/libzisp/value/sstr.zig +++ b/src/zisp/value/sstr.zig |
