support arrays finally done
This commit is contained in:
parent
31107aa9d4
commit
3128f9e768
159
language.zig
159
language.zig
@ -153,38 +153,6 @@ fn addString(self: *Self, allocator: std.mem.Allocator, bytes: []const u8) !usiz
|
||||
return idx;
|
||||
}
|
||||
|
||||
fn addObject(self: *Self, allocator: std.mem.Allocator, object: std.AutoArrayHashMapUnmanaged([]const u8, JsonInput)) !usize {
|
||||
var entry: ?ObjectEntry = null;
|
||||
|
||||
for (object.keys(), object.values(), 0..) |key, value, times| {
|
||||
const stridx = try self.property_index.add(allocator, key);
|
||||
try self.index.ensureUnusedCapacity(allocator, 1);
|
||||
const vidx = self.index.addOneAssumeCapacity();
|
||||
self.index.set(vidx, @unionInit(JsonValue, std.meta.activeTag(value), self.addValue(allocator, value)));
|
||||
if (times == 0) {
|
||||
entry = ObjectEntry{
|
||||
.len = object.entries.len,
|
||||
.property_idx = stridx,
|
||||
.value_idx = vidx,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
try self.index.ensureUnusedCapacity(allocator, 1);
|
||||
const idx = self.index.addOneAssumeCapacity();
|
||||
if (entry) |e| {
|
||||
self.index.set(idx, .{ .object = e });
|
||||
return idx;
|
||||
} else {
|
||||
self.index.set(idx, .{ .object = ObjectEntry{
|
||||
.len = 0,
|
||||
.property_idx = 0,
|
||||
.value_idx = 1,
|
||||
} });
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
fn addEmptyObject(self: *Self, allocator: std.mem.Allocator) !usize {
|
||||
try self.index.ensureUnusedCapacity(allocator, 1);
|
||||
const idx = self.index.addOneAssumeCapacity();
|
||||
@ -197,33 +165,6 @@ fn addEmptyObject(self: *Self, allocator: std.mem.Allocator) !usize {
|
||||
return idx;
|
||||
}
|
||||
|
||||
fn addArray(self: *Self, allocator: std.mem.Allocator, array: []JsonInput) !usize {
|
||||
var entry: ?ArraySlice = null;
|
||||
for (array, 0..) |value, times| {
|
||||
try self.index.ensureUnusedCapacity(allocator, 1);
|
||||
const idx = self.index.addOneAssumeCapacity();
|
||||
self.index.set(idx, @unionInit(JsonValue, std.meta.activeTag(value), self.addValue(allocator, value)));
|
||||
if (times == 0) {
|
||||
entry = ArraySlice{
|
||||
.start = idx,
|
||||
.len = array.len,
|
||||
};
|
||||
}
|
||||
}
|
||||
try self.index.ensureUnusedCapacity(allocator, 1);
|
||||
const idx = self.index.addOneAssumeCapacity();
|
||||
if (entry) |e| {
|
||||
self.index.set(idx, .{ .array = e });
|
||||
return idx;
|
||||
} else {
|
||||
self.index.set(idx, .{ .array = ArraySlice{
|
||||
.start = 0,
|
||||
.len = 0,
|
||||
} });
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
fn addEmptyArray(self: *Self, allocator: std.mem.Allocator) !usize {
|
||||
try self.index.ensureUnusedCapacity(allocator, 1);
|
||||
const idx = self.index.addOneAssumeCapacity();
|
||||
@ -248,17 +189,6 @@ fn addNull(self: *Self, allocator: std.mem.Allocator) !usize {
|
||||
return idx;
|
||||
}
|
||||
|
||||
fn addValue(self: *Self, allocator: std.mem.Allocator, value: JsonInput) !void {
|
||||
switch (value) {
|
||||
.null => try self.addNull(allocator),
|
||||
.bool => try self.addBool(allocator, value.bool),
|
||||
.number => try self.addNumber(allocator, value.number),
|
||||
.string => try self.addString(allocator, value.string),
|
||||
.array => try self.addArray(allocator, value.array),
|
||||
.object => try self.addObject(allocator, value.object),
|
||||
}
|
||||
}
|
||||
|
||||
fn getProperty(self: *Self, index: []const u8) ?StringIndex {
|
||||
return self.property_index.string_table.get(index);
|
||||
}
|
||||
@ -435,18 +365,7 @@ test getValue {
|
||||
|
||||
const json =
|
||||
\\ {
|
||||
\\ "name": "Yuzu",
|
||||
\\ "author": true,
|
||||
\\ "age": 15,
|
||||
\\ "address": {
|
||||
\\ "street": 1,
|
||||
\\ "deeply_nested": {
|
||||
\\ "k": 5,
|
||||
\\ "socialist": "expansion",
|
||||
\\ "idk": {"a":"b"}
|
||||
\\ }
|
||||
\\ },
|
||||
\\ "offset": "yes"
|
||||
\\ "array": [1,2,3,[4,5,6]]
|
||||
\\ }
|
||||
;
|
||||
|
||||
@ -543,7 +462,7 @@ pub fn parse(self: *Self, tokenizer: *Tokenizer) !usize {
|
||||
else => return error.InvalidSyntax,
|
||||
}
|
||||
},
|
||||
.object_end => {
|
||||
.object_end, .array_end => {
|
||||
defer tokenizer.skipWhitespace();
|
||||
assert(query.pop() != null);
|
||||
|
||||
@ -552,25 +471,66 @@ pub fn parse(self: *Self, tokenizer: *Tokenizer) !usize {
|
||||
token = next;
|
||||
switch (next.type) {
|
||||
.comma => continue :flag .comma,
|
||||
.object_end, .array_end => |t| continue :flag t,
|
||||
.object_end, .array_end => continue :flag next.type,
|
||||
else => return error.InvalidSyntax,
|
||||
}
|
||||
},
|
||||
.array_begin => {
|
||||
defer tokenizer.skipWhitespace();
|
||||
|
||||
// order matters
|
||||
const parent_idx = query.get(query.len - 1);
|
||||
|
||||
const idx_ptr = try query.addOne();
|
||||
|
||||
idx_ptr.* = try self.addEmptyArray(allocator);
|
||||
self.index.set(idx_ptr.*, .{ .array = ArraySlice{
|
||||
.len = 0,
|
||||
.start = idx_ptr.* + 1,
|
||||
} });
|
||||
|
||||
switch (self.index.get(parent_idx)) {
|
||||
.array => |slice| {
|
||||
self.index.set(parent_idx, .{ .array = ArraySlice{
|
||||
.len = slice.len + 1,
|
||||
.start = if (slice.len == 0) idx_ptr.* else slice.start,
|
||||
} });
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
const next = it.next() orelse return error.InvalidSyntax;
|
||||
token = next;
|
||||
switch (next.type) {
|
||||
.property => return error.InvalidSyntax,
|
||||
else => continue :flag next.type,
|
||||
}
|
||||
},
|
||||
.true, .false => {
|
||||
defer tokenizer.skipWhitespace();
|
||||
|
||||
_ = try self.addBool(allocator, if (token.type == .true) true else false);
|
||||
const idx = try self.addBool(allocator, if (token.type == .true) true else false);
|
||||
const parent_idx = query.get(query.len - 1);
|
||||
switch (self.index.get(parent_idx)) {
|
||||
.array => |slice| {
|
||||
self.index.set(parent_idx, .{ .array = ArraySlice{
|
||||
.len = slice.len + 1,
|
||||
.start = if (slice.len == 0) idx else slice.start,
|
||||
} });
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
const next = it.next() orelse return error.InvalidSyntax;
|
||||
token = next;
|
||||
switch (next.type) {
|
||||
.comma => continue :flag .comma,
|
||||
.object_end => continue :flag .object_end,
|
||||
.object_end, .array_end => continue :flag next.type,
|
||||
else => return error.InvalidSyntax,
|
||||
}
|
||||
},
|
||||
.string => {
|
||||
defer tokenizer.skipWhitespace();
|
||||
const parent_idx = query.get(query.len - 1);
|
||||
|
||||
const next = it.next() orelse return error.InvalidSyntax;
|
||||
switch (next.type) {
|
||||
@ -578,8 +538,17 @@ pub fn parse(self: *Self, tokenizer: *Tokenizer) !usize {
|
||||
continue :flag .property;
|
||||
},
|
||||
else => |t| {
|
||||
_ = try self.addString(allocator, token.value.?.string);
|
||||
const idx = try self.addString(allocator, token.value.?.string);
|
||||
allocator.free(token.value.?.string);
|
||||
switch (self.index.get(parent_idx)) {
|
||||
.array => |slice| {
|
||||
self.index.set(parent_idx, .{ .array = ArraySlice{
|
||||
.len = slice.len + 1,
|
||||
.start = if (slice.len == 0) idx else slice.start,
|
||||
} });
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
token = next;
|
||||
continue :flag t;
|
||||
@ -589,13 +558,23 @@ pub fn parse(self: *Self, tokenizer: *Tokenizer) !usize {
|
||||
.number => {
|
||||
defer tokenizer.skipWhitespace();
|
||||
|
||||
_ = try self.addNumber(allocator, token.value.?.number);
|
||||
const parent_idx = query.get(query.len - 1);
|
||||
const idx = try self.addNumber(allocator, token.value.?.number);
|
||||
switch (self.index.get(parent_idx)) {
|
||||
.array => |slice| {
|
||||
self.index.set(parent_idx, .{ .array = ArraySlice{
|
||||
.len = slice.len + 1,
|
||||
.start = if (slice.len == 0) idx else slice.start,
|
||||
} });
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
const next = it.next() orelse return error.InvalidSyntax;
|
||||
token = next;
|
||||
switch (next.type) {
|
||||
.comma => continue :flag .comma,
|
||||
.object_end => continue :flag .object_end,
|
||||
.object_end, .array_end => continue :flag next.type,
|
||||
else => return error.InvalidSyntax,
|
||||
}
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user