using: safer seam defaults (fix_braces OFF by default) + path-alias handling; json_native: robust integer parse + EscapeUtils unquote; add JsonCompat layer; builder: preindex static methods + fallback for bare calls; diagnostics: seam dump + function-call trace

This commit is contained in:
Selfhosting Dev
2025-09-25 10:23:14 +09:00
parent 2f306dd6a5
commit 9384c80623
30 changed files with 1786 additions and 527 deletions

View File

@ -141,11 +141,21 @@ box JsonScanner {
is_digit_char(ch) {
return ch == "0" or ch == "1" or ch == "2" or ch == "3" or ch == "4" or ch == "5" or ch == "6" or ch == "7" or ch == "8" or ch == "9"
}
// 16進数字判定内蔵
is_hex_digit_char(ch) {
return me.is_digit_char(ch) or ch == "a" or ch == "b" or ch == "c" or ch == "d" or ch == "e" or ch == "f" or ch == "A" or ch == "B" or ch == "C" or ch == "D" or ch == "E" or ch == "F"
}
// 英字判定(内蔵)
is_alpha_char(ch) {
return (ch >= "a" and ch <= "z") or (ch >= "A" and ch <= "Z")
}
// 英数字 + 下線(識別子向け)
is_alphanumeric_or_underscore(ch) {
return me.is_alpha_char(ch) or me.is_digit_char(ch) or ch == "_"
}
// ===== 高レベル読み取りメソッド =====
@ -198,6 +208,18 @@ box JsonScanner {
return me.text.substring(start_pos, me.position)
}
// 識別子を読み取り(英数字+アンダースコア)
read_identifier() {
local start_pos = me.position
if not me.is_alpha_char(me.current()) and me.current() != "_" {
return ""
}
loop(not me.is_eof() and me.is_alphanumeric_or_underscore(me.current())) {
me.advance()
}
return me.text.substring(start_pos, me.position)
}
// 数値文字列を読み取り
read_number() {
@ -344,4 +366,4 @@ box JsonScanner {
to_debug_string() {
return "Scanner{pos:" + me.position + "/" + me.length + ", line:" + me.line + ", col:" + me.column + ", context:'" + me.get_context(5) + "'}"
}
}
}

View File

@ -3,6 +3,7 @@
using "apps/lib/json_native/lexer/scanner.nyash" as JsonScanner
using "apps/lib/json_native/lexer/token.nyash" as JsonToken
using "apps/lib/json_native/utils/escape.nyash" as EscapeUtils
// Removed other dependencies - using self-contained methods
// 🎯 高精度JSONトークナイザーEverything is Box
@ -109,8 +110,8 @@ box JsonTokenizer {
return new JsonToken("ERROR", "Unterminated string literal", start_pos, me.scanner.get_position())
}
// エスケープ解除して値を取得
local unescaped = me.unquote_string(literal)
// エスケープ解除して値を取得(厳密版)
local unescaped = EscapeUtils.unquote_string(literal)
// 文字列妥当性検証
if not me.validate_string(unescaped) {
@ -141,8 +142,8 @@ box JsonTokenizer {
tokenize_keyword() {
local start_pos = me.scanner.get_position()
// アルファベット文字を読み取り
local keyword = me.scanner.read_while(this.is_identifier_char)
// アルファベット/数字/下線を読み取り(関数参照を避ける安全版)
local keyword = me.scanner.read_identifier()
// キーワード判定
local token_type = me.keyword_to_token_type(keyword)
@ -190,10 +191,7 @@ box JsonTokenizer {
}
}
// 識別子文字かどうか判定
is_identifier_char(ch) {
return me.is_alphanumeric_char(ch) or ch == "_"
}
// 数値形式の妥当性検証
validate_number_format(num_str) {