stage2 更多的工具库

This commit is contained in:
zzy committed 2026-09-17 22:32:36 +08:00
1 parent 4141e7d574
commit 16a1f030d4
15 files changed
+1914 -109

No files matched your search

+43 -38
View File
@@ -95,17 +95,24 @@ fn peek(p: *Parser): i32 {
ret p.src.ptr[p.pos] as i32;
}
// 当前字符是否等于 ch(EOF 时 false)。
fn at_char(p: *Parser, ch: u8): bool {
var c = peek(p);
if c < 0 { ret false; }
ret (c as u8) == ch;
}
fn parse_string_raw(p: *Parser): ViewResult {
if peek(p) != 34 { ret .Err(at(.InvalidFormat, p.pos)); }
if !at_char(p, '"') { ret .Err(at(.InvalidFormat, p.pos)); }
p.pos = p.pos + 1;
var start = p.pos;
while p.pos < p.src.len {
var c = p.src.ptr[p.pos];
if c == 34 { break; }
if c == 92 { // '\\'
if c == '"' { break; }
if c == '\\' { // '\\'
p.pos = p.pos + 1;
if p.pos >= p.src.len { ret .Err(at(.UnexpectedEnd, p.pos)); }
if p.src.ptr[p.pos] == 117 { // 'u'
if p.src.ptr[p.pos] == 'u' { // 'u'
var k: usize = 0;
while k < 4 {
p.pos = p.pos + 1;
@@ -141,18 +148,18 @@ fn parse_literal(p: *Parser, word: []u8, kind: JsonKind): NodeResult {
fn parse_number(p: *Parser): NodeResult {
var start = p.pos;
if peek(p) == 45 { p.pos = p.pos + 1; } // '-'
if at_char(p, '-') { p.pos = p.pos + 1; } // '-'
if p.pos >= p.src.len || !is_digit(p.src.ptr[p.pos]) {
ret .Err(at(.InvalidDigit, p.pos));
}
if p.src.ptr[p.pos] == 48 { // 前导 0 后面不能接数字
if p.src.ptr[p.pos] == '0' { // 前导 0 后面不能接数字
p.pos = p.pos + 1;
} else {
while p.pos < p.src.len && is_digit(p.src.ptr[p.pos]) {
p.pos = p.pos + 1;
}
}
if p.pos < p.src.len && p.src.ptr[p.pos] == 46 { // '.'
if p.pos < p.src.len && p.src.ptr[p.pos] == '.' { // '.'
p.pos = p.pos + 1;
if p.pos >= p.src.len || !is_digit(p.src.ptr[p.pos]) {
ret .Err(at(.InvalidDigit, p.pos));
@@ -161,9 +168,9 @@ fn parse_number(p: *Parser): NodeResult {
p.pos = p.pos + 1;
}
}
if p.pos < p.src.len && (p.src.ptr[p.pos] == 101 || p.src.ptr[p.pos] == 69) { // e/E
if p.pos < p.src.len && (p.src.ptr[p.pos] == 'e' || p.src.ptr[p.pos] == 'E') { // e/E
p.pos = p.pos + 1;
if p.pos < p.src.len && (p.src.ptr[p.pos] == 43 || p.src.ptr[p.pos] == 45) {
if p.pos < p.src.len && (p.src.ptr[p.pos] == '+' || p.src.ptr[p.pos] == '-') {
p.pos = p.pos + 1;
}
if p.pos >= p.src.len || !is_digit(p.src.ptr[p.pos]) {
@@ -190,7 +197,7 @@ fn parse_array(p: *Parser): NodeResult {
var kids = Vec.blank(@sizeof(JsonChild), 8);
skip_ws(p);
if peek(p) == 93 { // ']'
if at_char(p, ']') { // ']'
p.pos = p.pos + 1;
var empty = blank_node(.Array);
empty.children = kids;
@@ -211,12 +218,11 @@ fn parse_array(p: *Parser): NodeResult {
}
skip_ws(p);
var c = peek(p);
if c == 44 { // ','
if at_char(p, ',') { // ','
p.pos = p.pos + 1;
continue;
}
if c == 93 { // ']'
if at_char(p, ']') { // ']'
p.pos = p.pos + 1;
break;
}
@@ -234,7 +240,7 @@ fn parse_object(p: *Parser): NodeResult {
var kids = Vec.blank(@sizeof(JsonChild), 8);
skip_ws(p);
if peek(p) == 125 { // '}'
if at_char(p, '}') { // '}'
p.pos = p.pos + 1;
var empty = blank_node(.Object);
empty.children = kids;
@@ -250,7 +256,7 @@ fn parse_object(p: *Parser): NodeResult {
}
skip_ws(p);
if peek(p) != 58 { // ':'
if !at_char(p, ':') { // ':'
Vec.drop(&kids);
ret .Err(at(.InvalidFormat, p.pos));
}
@@ -270,12 +276,11 @@ fn parse_object(p: *Parser): NodeResult {
}
skip_ws(p);
var c = peek(p);
if c == 44 { // ','
if at_char(p, ',') { // ','
p.pos = p.pos + 1;
continue;
}
if c == 125 { // '}'
if at_char(p, '}') { // '}'
p.pos = p.pos + 1;
break;
}
@@ -294,7 +299,7 @@ fn parse_value(p: *Parser): NodeResult {
if c < 0 { ret .Err(at(.UnexpectedEnd, p.pos)); }
var ch = c as u8;
if ch == 34 { // '"'
if ch == '"' { // '"'
var view = ByteView.empty();
match parse_string_raw(p) {
.Ok(v) => { view = v; },
@@ -304,11 +309,11 @@ fn parse_value(p: *Parser): NodeResult {
node.text = view;
ret intern_node(p, node);
}
if ch == 123 { ret parse_object(p); } // '{'
if ch == 91 { ret parse_array(p); } // '['
if ch == 116 { ret parse_literal(p, "true", .True); }
if ch == 102 { ret parse_literal(p, "false", .False); }
if ch == 110 { ret parse_literal(p, "null", .Null); }
if ch == '{' { ret parse_object(p); } // '{'
if ch == '[' { ret parse_array(p); } // '['
if ch == 't' { ret parse_literal(p, "true", .True); }
if ch == 'f' { ret parse_literal(p, "false", .False); }
if ch == 'n' { ret parse_literal(p, "null", .Null); }
ret parse_number(p);
}
@@ -431,7 +436,7 @@ fn object_find(doc: *Json, index: usize, key: ByteView): FindResult {
}
fn emit_quoted(out: *ByteBuffer, text: ByteView): Status {
match ByteBuffer.append_byte(out, 34) { // '"'
match ByteBuffer.append_byte(out, '"') { // '"'
.Ok => {},
.Err(error) => { ret .Err(error); },
}
@@ -439,11 +444,11 @@ fn emit_quoted(out: *ByteBuffer, text: ByteView): Status {
.Ok => {},
.Err(error) => { ret .Err(error); },
}
ret ByteBuffer.append_byte(out, 34);
ret ByteBuffer.append_byte(out, '"');
}
fn emit_indent(out: *ByteBuffer, indent: usize, depth: usize): Status {
match ByteBuffer.append_byte(out, 10) { // '\n'
match ByteBuffer.append_byte(out, '\n') { // '\n'
.Ok => {},
.Err(error) => { ret .Err(error); },
}
@@ -468,11 +473,11 @@ fn emit(out: *ByteBuffer, doc: *Json, index: usize, indent: usize, depth: usize)
fn emit_children(out: *ByteBuffer, doc: *Json, n: *JsonNode, is_object: bool, indent: usize,
depth: usize): Status {
var open_byte: u8 = 91; // '['
var close_byte: u8 = 93; // ']'
var open_byte: u8 = '['; // '['
var close_byte: u8 = ']'; // ']'
if is_object {
open_byte = 123; // '{'
close_byte = 125; // '}'
open_byte = '{'; // '{'
close_byte = '}'; // '}'
}
match ByteBuffer.append_byte(out, open_byte) {
@@ -488,7 +493,7 @@ fn emit_children(out: *ByteBuffer, doc: *Json, n: *JsonNode, is_object: bool, in
var i: usize = 0;
while i < count {
if i != 0 {
match ByteBuffer.append_byte(out, 44) { // ','
match ByteBuffer.append_byte(out, ',') { // ','
.Ok => {},
.Err(error) => { ret .Err(error); },
}
@@ -508,12 +513,12 @@ fn emit_children(out: *ByteBuffer, doc: *Json, n: *JsonNode, is_object: bool, in
.Ok => {},
.Err(error) => { ret .Err(error); },
}
match ByteBuffer.append_byte(out, 58) { // ':'
match ByteBuffer.append_byte(out, ':') { // ':'
.Ok => {},
.Err(error) => { ret .Err(error); },
}
if indent != 0 {
match ByteBuffer.append_byte(out, 32) { // ' '
match ByteBuffer.append_byte(out, ' ') { // ' '
.Ok => {},
.Err(error) => { ret .Err(error); },
}
@@ -746,14 +751,14 @@ fn test_construction_helpers() {
fn test_large_array() {
var out = ByteBuffer.new();
expect_ok(ByteBuffer.append_byte(&out, 91)); // '['
expect_ok(ByteBuffer.append_byte(&out, '[')); // '['
var i: usize = 0;
while i < 1000 {
if i != 0 { expect_ok(ByteBuffer.append_byte(&out, 44)); }
expect_ok(ByteBuffer.append_byte(&out, 49)); // '1'
if i != 0 { expect_ok(ByteBuffer.append_byte(&out, ',')); }
expect_ok(ByteBuffer.append_byte(&out, '1')); // '1'
i = i + 1;
}
expect_ok(ByteBuffer.append_byte(&out, 93)); // ']'
expect_ok(ByteBuffer.append_byte(&out, ']')); // ']'
var text = ByteBuffer.as_slice(out);
var r = parse(ByteView.from_slice(text));