idk
This commit is contained in:
parent
206e92ef64
commit
aa890ea209
53
language.zig
53
language.zig
@ -7,13 +7,13 @@ const StringPool = @import("strings.zig");
|
|||||||
const StringIndex = StringPool.StringIndex;
|
const StringIndex = StringPool.StringIndex;
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
|
|
||||||
// data structures
|
|
||||||
const Object = std.StringArrayHashMapUnmanaged(JsonInput);
|
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
pub const Error = enum {
|
pub const Error = enum {
|
||||||
TrailingComma,
|
TrailingComma,
|
||||||
|
MissingKey,
|
||||||
|
MissingValue,
|
||||||
|
UnexpectedToken,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const JsonType = enum {
|
pub const JsonType = enum {
|
||||||
@ -35,12 +35,16 @@ pub const JsonValue = union(JsonType) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const JsonInput = union(JsonType) {
|
pub const JsonInput = union(JsonType) {
|
||||||
|
|
||||||
|
// data structures
|
||||||
|
const Object = std.StringArrayHashMapUnmanaged(JsonInput);
|
||||||
|
|
||||||
null: void,
|
null: void,
|
||||||
bool: bool,
|
bool: bool,
|
||||||
number: f64,
|
number: f64,
|
||||||
string: []const u8,
|
string: []const u8,
|
||||||
array: []JsonInput,
|
array: []JsonInput,
|
||||||
object: std.StringArrayHashMapUnmanaged(JsonInput),
|
object: Object,
|
||||||
|
|
||||||
pub fn deinit(self: JsonInput, allocator: mem.Allocator) void {
|
pub fn deinit(self: JsonInput, allocator: mem.Allocator) void {
|
||||||
switch (self) {
|
switch (self) {
|
||||||
@ -218,12 +222,31 @@ fn getObject(self: *Self, allocator: mem.Allocator, index: usize) !struct {
|
|||||||
const keys = try allocator.alloc(StringIndex, entry.object.len);
|
const keys = try allocator.alloc(StringIndex, entry.object.len);
|
||||||
const values = try allocator.alloc(usize, entry.object.len);
|
const values = try allocator.alloc(usize, entry.object.len);
|
||||||
|
|
||||||
for (0..entry.object.len) |i| {
|
var i: usize = 0;
|
||||||
const slice = StringIndex.slice(@enumFromInt(pidx), &self.property_index);
|
|
||||||
keys[i] = @enumFromInt(pidx);
|
flag: switch (self.index.get(vidx)) {
|
||||||
values[i] = vidx;
|
.array => {
|
||||||
pidx += slice.len + 1;
|
vidx += 1;
|
||||||
vidx += 1;
|
continue :flag self.index.get(vidx);
|
||||||
|
},
|
||||||
|
.object => |obj| {
|
||||||
|
var iter = StringIndex.iterator(
|
||||||
|
@enumFromInt(obj.property_idx),
|
||||||
|
self.property_index.string_bytes.items,
|
||||||
|
);
|
||||||
|
const slice = iter.next();
|
||||||
|
keys[i] = @enumFromInt(obj.property_idx);
|
||||||
|
values[i] = vidx;
|
||||||
|
i += 1;
|
||||||
|
pidx += slice.len + 1;
|
||||||
|
vidx += 1;
|
||||||
|
continue :flag self.index.get(vidx);
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
// pidx += slice.len + 1;
|
||||||
|
vidx += 1;
|
||||||
|
continue :flag self.index.get(vidx);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return .{ keys, values };
|
return .{ keys, values };
|
||||||
@ -341,7 +364,7 @@ fn getValue(
|
|||||||
return .{ .array = out[0..arr.len] };
|
return .{ .array = out[0..arr.len] };
|
||||||
},
|
},
|
||||||
.object => |obj| {
|
.object => |obj| {
|
||||||
var map: std.StringArrayHashMapUnmanaged(JsonInput) = .empty;
|
var map: JsonInput.Object = .empty;
|
||||||
var p = obj.property_idx;
|
var p = obj.property_idx;
|
||||||
var v = obj.value_idx;
|
var v = obj.value_idx;
|
||||||
for (0..obj.len) |_| {
|
for (0..obj.len) |_| {
|
||||||
@ -369,8 +392,12 @@ test getValue {
|
|||||||
|
|
||||||
const json =
|
const json =
|
||||||
\\ {
|
\\ {
|
||||||
\\ "array":[{"cute":true},
|
\\ "cute": true,
|
||||||
\\ {"funny":false}]
|
\\ "metadata": {
|
||||||
|
\\ "post": [1,2,3],
|
||||||
|
\\ "a": 2
|
||||||
|
\\ },
|
||||||
|
\\ "b": 3
|
||||||
\\ }
|
\\ }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
35
strings.zig
35
strings.zig
@ -1,6 +1,5 @@
|
|||||||
/// credits to Andrew Kelley
|
/// credits to Andrew Kelley
|
||||||
/// strings.zig
|
/// strings.zig
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
@ -26,9 +25,9 @@ pub fn deinit(self: *Self, allocator: Allocator) void {
|
|||||||
pub const StringIndex = enum(u32) {
|
pub const StringIndex = enum(u32) {
|
||||||
_,
|
_,
|
||||||
|
|
||||||
const Table = std.HashMapUnmanaged(StringIndex, void, TableContext, max_load_percent);
|
pub const Table = std.HashMapUnmanaged(StringIndex, void, TableContext, max_load_percent);
|
||||||
|
|
||||||
const TableContext = struct {
|
pub const TableContext = struct {
|
||||||
bytes: []const u8,
|
bytes: []const u8,
|
||||||
|
|
||||||
pub fn eql(_: @This(), a: StringIndex, b: StringIndex) bool {
|
pub fn eql(_: @This(), a: StringIndex, b: StringIndex) bool {
|
||||||
@ -40,7 +39,7 @@ pub const StringIndex = enum(u32) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const TableIndexAdapter = struct {
|
pub const TableIndexAdapter = struct {
|
||||||
bytes: []const u8,
|
bytes: []const u8,
|
||||||
|
|
||||||
pub fn eql(ctx: @This(), a: []const u8, b: StringIndex) bool {
|
pub fn eql(ctx: @This(), a: []const u8, b: StringIndex) bool {
|
||||||
@ -57,6 +56,34 @@ pub const StringIndex = enum(u32) {
|
|||||||
const start_slice = state.string_bytes.items[@intFromEnum(index)..];
|
const start_slice = state.string_bytes.items[@intFromEnum(index)..];
|
||||||
return start_slice[0..mem.indexOfScalar(u8, start_slice, 0).? :0];
|
return start_slice[0..mem.indexOfScalar(u8, start_slice, 0).? :0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn iterator(start: StringIndex, bytes: []const u8) Iterator {
|
||||||
|
return .{
|
||||||
|
.bytes = bytes,
|
||||||
|
.pos = @intFromEnum(start),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const Iterator = struct {
|
||||||
|
bytes: []const u8,
|
||||||
|
pos: usize = 0,
|
||||||
|
|
||||||
|
pub fn next(self: *Iterator) ?[:0]const u8 {
|
||||||
|
if (self.pos >= self.bytes.len) return null;
|
||||||
|
|
||||||
|
// Find the next null terminator starting from current position
|
||||||
|
const end_pos = mem.indexOfScalarPos(u8, self.bytes, self.pos, 0) orelse {
|
||||||
|
// No null found: return remaining bytes (invalid, but handle gracefully)
|
||||||
|
const s = self.bytes[self.pos..];
|
||||||
|
self.pos = self.bytes.len;
|
||||||
|
return s;
|
||||||
|
};
|
||||||
|
|
||||||
|
const s = self.bytes[self.pos..end_pos :0];
|
||||||
|
self.pos = end_pos + 1; // Skip the null terminator
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn add(state: *Self, allocator: Allocator, bytes: []const u8) !StringIndex {
|
pub fn add(state: *Self, allocator: Allocator, bytes: []const u8) !StringIndex {
|
||||||
|
@ -8,22 +8,10 @@ pub const Error = error{
|
|||||||
OutOfMemory,
|
OutOfMemory,
|
||||||
/// eg: bad escaping
|
/// eg: bad escaping
|
||||||
UnexpectedCharacter,
|
UnexpectedCharacter,
|
||||||
/// eg: got the wrong token type, check TokenType
|
|
||||||
UnexpectedToken,
|
|
||||||
/// eg: std.fmt.parseFloat failed
|
/// eg: std.fmt.parseFloat failed
|
||||||
BadNumber,
|
BadNumber,
|
||||||
/// fba error
|
/// fba error
|
||||||
BufferTooSmall,
|
BufferTooSmall,
|
||||||
/// eg: missing comma
|
|
||||||
CommaExpected,
|
|
||||||
/// eg: missing colon
|
|
||||||
ColonExpected,
|
|
||||||
/// eg: missing object key
|
|
||||||
KeyExpected,
|
|
||||||
/// eg: error while writing
|
|
||||||
PrintError,
|
|
||||||
/// eg: trailing comma in object
|
|
||||||
TrailingComma,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const TokenType = enum(u8) {
|
pub const TokenType = enum(u8) {
|
||||||
@ -269,9 +257,8 @@ pub fn nextIdentifier(self: *Self) Error!Token {
|
|||||||
var buffer = try self.allocator.alloc(u8, 0x100);
|
var buffer = try self.allocator.alloc(u8, 0x100);
|
||||||
defer self.allocator.free(buffer);
|
defer self.allocator.free(buffer);
|
||||||
|
|
||||||
self.matchCharPredicate(std.ascii.isAlphabetic) orelse {
|
self.matchCharPredicate(std.ascii.isAlphabetic) orelse
|
||||||
return error.UnexpectedToken;
|
return error.InvalidSyntax;
|
||||||
};
|
|
||||||
|
|
||||||
buffer[0] = self.lastChar();
|
buffer[0] = self.lastChar();
|
||||||
|
|
||||||
@ -380,9 +367,7 @@ pub fn nextString(self: *Self) Error!Token {
|
|||||||
|
|
||||||
self.skipWhitespace();
|
self.skipWhitespace();
|
||||||
|
|
||||||
self.matchChar('"') orelse {
|
self.matchChar('"') orelse unreachable;
|
||||||
return error.UnexpectedToken;
|
|
||||||
};
|
|
||||||
|
|
||||||
var buffer: std.ArrayList(u8) = .init(self.allocator);
|
var buffer: std.ArrayList(u8) = .init(self.allocator);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user