Files
hakorune/tools/hako_parser/ast_emit.hako
nyash-codex 772149c86d Analyzer安定化完了: NYASH_DISABLE_PLUGINS=1復元 + plugin無効化根治
## 修正内容
1. **hako_check.sh/run_tests.sh**: NYASH_DISABLE_PLUGINS=1 + NYASH_BOX_FACTORY_POLICY=builtin_first追加
2. **src/box_factory/plugin.rs**: NYASH_DISABLE_PLUGINS=1チェック追加
3. **src/box_factory/mod.rs**: plugin shortcut pathでNYASH_DISABLE_PLUGINS尊重
4. **tools/hako_check/render/graphviz.hako**: smart quotes修正(parse error解消)

## 根本原因
- NYASH_USE_PLUGIN_BUILTINS=1が自動設定され、ArrayBox/MapBoxがplugin経由で生成を試行
- bid/registry.rsで"Plugin loading temporarily disabled"の状態でも試行されエラー
- mod.rs:272のshortcut pathがNYASH_DISABLE_PLUGINSを無視していた

## テスト結果
- 10/11 PASS(HC011,13-18,21-22,31)
- HC012: 既存issue(JSON安定化未完)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 15:49:25 +09:00

81 lines
3.2 KiB
Plaintext

// tools/hako_parser/ast_emit.hako - HakoAstEmitBox (MVP)
using selfhost.shared.common.string_helpers as Str
static box HakoAstEmitBox {
// Emit minimal AST JSON v0 from MapBox (stable order)
to_json(ast) {
if ast == null { return "{\"boxes\":[],\"uses\":[]}" }
local uses = me._sort_strings(ast.get("uses"))
local boxes = me._sort_boxes(ast.get("boxes"))
local out = "{\"uses\":" + me._emit_array(uses) + ",\"boxes\":" + me._emit_boxes(boxes) + "}"
return out
}
_emit_array(arr) {
if arr == null { return "[]" }
local s = "["
local n = arr.size()
local i = 0
while i < n {
local v = arr.get(i)
s = s + Str.json_quote(v)
if i != n-1 { s = s + "," }
i = i + 1
}
return s + "]"
}
_emit_boxes(boxes) {
if boxes == null { return "[]" }
local s = "["
local n = boxes.size()
local i = 0
while i < n {
local b = boxes.get(i)
local name = Str.json_quote(b.get("name"))
local is_static = b.get("is_static")
local methods = me._emit_methods(me._sort_methods(b.get("methods")))
s = s + "{\"name\":" + name + ",\"is_static\":" + Str.int_to_str(is_static) + ",\"methods\":" + methods + "}"
if i != n-1 { s = s + "," }
i = i + 1
}
return s + "]"
}
_emit_methods(methods) {
if methods == null { return "[]" }
local s = "["
local n = methods.size()
local i = 0
while i < n {
local m = methods.get(i)
local name = Str.json_quote(m.get("name"))
local arity = Str.int_to_str(m.get("arity"))
// span is integer line number
local spanv = m.get("span"); if spanv == null { spanv = 0 }
s = s + "{\"name\":" + name + ",\"arity\":" + arity + ",\"span\":" + Str.int_to_str(spanv) + "}"
if i != n-1 { s = s + "," }
i = i + 1
}
return s + "]"
}
// Helpers: sorting (naive O(n^2))
_sort_strings(arr) { if arr == null { return new ArrayBox() }
local out = new ArrayBox(); local i=0; while i<arr.size() { out.push(arr.get(i)); i=i+1 }
// selection sort
local n = out.size(); local a=0; while a<n { local b=a+1; while b<n { if out.get(b) < out.get(a) { local tmp=out.get(a); out.set(a,out.get(b)); out.set(b,tmp) } b=b+1 } a=a+1 }
return out }
_sort_boxes(boxes) { if boxes == null { return new ArrayBox() }
local out = new ArrayBox(); local i=0; while i<boxes.size() { out.push(boxes.get(i)); i=i+1 }
local n=out.size(); local a=0; while a<n { local b=a+1; while b<n { if out.get(b).get("name") < out.get(a).get("name") { local tmp=out.get(a); out.set(a,out.get(b)); out.set(b,tmp) } b=b+1 } a=a+1 }
return out }
_sort_methods(methods) { if methods == null { return new ArrayBox() }
local out = new ArrayBox(); local i=0; while i<methods.size() { out.push(methods.get(i)); i=i+1 }
local n=out.size(); local a=0; while a<n { local b=a+1; while b<n {
local ma=out.get(a); local mb=out.get(b)
local ka = ma.get("name") + "/" + Str.int_to_str(ma.get("arity"))
local kb = mb.get("name") + "/" + Str.int_to_str(mb.get("arity"))
if kb < ka { local tmp=out.get(a); out.set(a,out.get(b)); out.set(b,tmp) }
b=b+1 } a=a+1 }
return out }
}
static box HakoAstEmitMain { method main(args) { return 0 } }