public: publish selfhost snapshot to public repo (SSOT using + AST merge + JSON VM fixes)

- SSOT using profiles (aliases/packages via nyash.toml), AST prelude merge
- Parser/member guards; Builder pin/PHI and instance→function rewrite (dev on)
- VM refactors (handlers split) and JSON roundtrip/nested stabilization
- CURRENT_TASK.md updated with scope and acceptance criteria

Notes: dev-only guards remain togglable via env; no default behavior changes for prod.
This commit is contained in:
nyash-codex
2025-09-26 14:34:42 +09:00
parent ecd46161b3
commit cdf826cbe7
44 changed files with 6264 additions and 576 deletions

View File

@ -212,7 +212,7 @@ static box JsonNode {
}
} else {
if me.kind == "int" {
return "" + me.value
return me.value.toString()
} else {
if me.kind == "float" {
// 数値の文字列表現をそのまま出力(引用符なし)
@ -268,7 +268,14 @@ box JsonNodeInstance {
me.kind = "null"
me.value = null
}
// インスタンス用: オブジェクトに値を設定
object_set(key, node) {
if me.kind == "object" {
me.value.set(key, node)
}
}
// インスタンスメソッドとして静的メソッドを呼び出し
get_kind() { return me.kind }
as_bool() {
@ -289,27 +296,68 @@ box JsonNodeInstance {
}
return ""
}
stringify() {
stringify() {
if me.kind == "null" {
return "null"
} else {
if me.kind == "bool" {
if me.value {
return "true"
} else {
return "false"
}
} else {
if me.kind == "int" {
return "" + me.value
} else {
if me.kind == "string" {
return "\"" + me.value + "\""
} else {
return "null"
}
}
}
if me.kind == "bool" {
if me.value { return "true" } else { return "false" }
}
if me.kind == "int" {
return me.value.toString()
}
if me.kind == "float" {
return me.value
}
if me.kind == "string" {
return EscapeUtils.quote_string(me.value)
}
if me.kind == "array" {
local parts = new ArrayBox()
local i = 0
loop(i < me.value.length()) {
local elem = me.value.get(i)
parts.push(elem.stringify())
i = i + 1
}
return "[" + StringUtils.join(parts, ",") + "]"
}
if me.kind == "object" {
local parts = new ArrayBox()
local keys = me.value.keys()
local i = 0
loop(i < keys.length()) {
local key = keys.get(i)
local val = me.value.get(key)
local pair = EscapeUtils.quote_string(key) + ":" + val.stringify()
parts.push(pair)
i = i + 1
}
return "{" + StringUtils.join(parts, ",") + "}"
}
return "null"
}
// Instance helper: push element into array value
array_push(node) {
if me.kind == "array" {
me.value.push(node)
}
}
// Instance helper: array size
array_size() {
if me.kind == "array" {
return me.value.length()
}
return 0
}
// Instance helper: object get
object_get(key) {
if me.kind == "object" {
return me.value.get(key)
}
return null
}
}

View File

@ -13,7 +13,9 @@ box JsonTokenizer {
errors: ArrayBox // エラー情報配列
birth(input_text) {
me.scanner = JsonScannerModule.create_scanner(input_text)
// Avoid static module wrapper to ensure constructor args are preserved on VM path
// (create_scanner(...) lost the argument under VM fallback in some cases)
me.scanner = new JsonScanner(input_text)
me.tokens = new ArrayBox()
me.errors = new ArrayBox()
}

View File

@ -295,19 +295,15 @@ static box StringUtils {
}
local acc = 0
local digits = "0123456789"
loop(i < s.length()) {
// 各桁の数値を計算
local ch = s.substring(i, i + 1)
// '0'..'9' 前提is_integer で検証済み)
// 文字を数値へ: (ch - '0') 相当の分岐
local digit = 0
if ch == "0" { digit = 0 } else { if ch == "1" { digit = 1 } else { if ch == "2" { digit = 2 } else { if ch == "3" { digit = 3 } else {
if ch == "4" { digit = 4 } else { if ch == "5" { digit = 5 } else { if ch == "6" { digit = 6 } else { if ch == "7" { digit = 7 } else {
if ch == "8" { digit = 8 } else { if ch == "9" { digit = 9 } else { digit = 0 } } } } } } } } }
acc = acc * 10 + digit
// '0'..'9' → 位置で数値化
local d = this.index_of(digits, ch)
if d < 0 { break }
acc = acc * 10 + d
i = i + 1
}
if neg { return 0 - acc } else { return acc }
}