fix(stage-b): Add sh_core using + Stage-1 JSON support
## Fixed Issues
1. compiler_stageb.hako: Added 'using sh_core as StringHelpers'
- Resolved: call unresolved ParserStringUtilsBox.skip_ws/2
- Root cause: using chain resolution not implemented
- Workaround: explicit using in parent file
2. stageb_helpers.sh: Accept Stage-1 JSON format
- Modified awk pattern to accept both formats:
- MIR JSON v0: "version":0, "kind":"Program"
- Stage-1 JSON: "type":"Program"
## Remaining Issues
ParserBox VM crash: Invalid value: use of undefined value ValueId(5839)
- Cause: Complex nested loops in parse_program2()
- Workaround: Minimal Stage-B (without ParserBox) works
- Fallback: Rust compiler path available
## Verification
✅ Minimal Stage-B outputs JSON correctly
❌ ParserBox execution crashes VM (SSA bug)
Co-Authored-By: Task先生 (AI Agent)
This commit is contained in:
@ -1,8 +1,11 @@
|
||||
// Stage-B compiler entry — ParserBox → FlowEntry emit-only
|
||||
|
||||
using sh_core as StringHelpers // Required: ParserStringUtilsBox depends on this (using chain unresolved)
|
||||
using lang.compiler.parser.box as ParserBox
|
||||
|
||||
static box StageBMain {
|
||||
// Note: Runner resolves entry as Main.main by default.
|
||||
// Provide static box Main with method main(args) as the entry point.
|
||||
static box Main {
|
||||
// Minimal Stage‑B driver: parse args/env, extract main body if wrapped in `box Main { static method main(){...} }`,
|
||||
// then run ParserBox → FlowEntry emit. Keep implementation single‑method to avoid parser drift issues.
|
||||
main(args) {
|
||||
@ -25,25 +28,54 @@ static box StageBMain {
|
||||
local p = new ParserBox()
|
||||
p.stage3_enable(1)
|
||||
|
||||
// 3) Extract using/externs from the original text
|
||||
p.extract_usings(src)
|
||||
local usings_json = p.get_usings_json()
|
||||
p.extract_externs(src)
|
||||
local externs_json = p.get_externs_json()
|
||||
// 3) (Temporarily disabled) Extract using/externs — keep minimal path for emit stability
|
||||
// p.extract_usings(src)
|
||||
// local usings_json = p.get_usings_json()
|
||||
// p.extract_externs(src)
|
||||
// local externs_json = p.get_externs_json()
|
||||
|
||||
// 4) If wrapped in `box Main { static method main() { ... } }`, extract the method body text
|
||||
// 4) If wrapped in `box Main { method main() { ... } }` or `static box Main { method main() { ... } }`,
|
||||
// extract the method body text
|
||||
local body_src = null
|
||||
{
|
||||
// naive search for "static method main" → '(' → ')' → '{' ... balanced '}'
|
||||
// naive search for "method main" → '(' → ')' → '{' ... balanced '}'
|
||||
local s = src
|
||||
local k0 = s.indexOf("static method main")
|
||||
// naive substring search for "method main"
|
||||
local k0 = -1
|
||||
{
|
||||
local pat = "method main"
|
||||
local m = pat.length()
|
||||
local i = 0
|
||||
local n = s.length()
|
||||
loop(i + m <= n) {
|
||||
if s.substring(i, i + m) == pat { k0 = i break }
|
||||
i = i + 1
|
||||
}
|
||||
}
|
||||
if k0 >= 0 {
|
||||
local k1 = s.indexOf("(", k0)
|
||||
// find '(' after k0
|
||||
local k1 = -1
|
||||
{
|
||||
local j = k0
|
||||
local n = s.length()
|
||||
loop(j < n) { if s.substring(j, j + 1) == "(" { k1 = j break } j = j + 1 }
|
||||
}
|
||||
if k1 >= 0 {
|
||||
local k2 = s.indexOf(")", k1)
|
||||
// find ')' after k1
|
||||
local k2 = -1
|
||||
{
|
||||
local j = k1
|
||||
local n = s.length()
|
||||
loop(j < n) { if s.substring(j, j + 1) == ")" { k2 = j break } j = j + 1 }
|
||||
}
|
||||
if k2 >= 0 {
|
||||
// Find opening '{' following ')'
|
||||
local k3 = s.indexOf("{", k2)
|
||||
local k3 = -1
|
||||
{
|
||||
local j = k2
|
||||
local n = s.length()
|
||||
loop(j < n) { if s.substring(j, j + 1) == "{" { k3 = j break } j = j + 1 }
|
||||
}
|
||||
if k3 >= 0 {
|
||||
// Balanced scan for matching '}'
|
||||
local depth = 0
|
||||
|
||||
@ -58,7 +58,8 @@ Quick profile opt‑in switches (smokes)
|
||||
- `SMOKES_ENABLE_STAGEB_OOB=1` — Stage‑B OOB observation (array/map)
|
||||
- `SMOKES_ENABLE_OOB_STRICT=1` — Gate‑C(Core) strict OOB fail‑fast canary (`gate_c_oob_strict_fail_vm.sh`)
|
||||
- `SMOKES_ENABLE_LLVM_SELF_PARAM=1` — LLVM instruction boxes self‑param builder tests (const/binop/compare/branch/jump/ret)
|
||||
- `SMOKES_ENABLE_STAGEB=1` — Stage‑B positive canaries (emit→Gate‑C). Default OFF while v1 downconvert matures.
|
||||
- `SMOKES_ENABLE_STAGEB=1` — Stage‑B positive canaries(emit→Gate‑C)。既定OFF(安定化後に昇格予定)。
|
||||
必要に応じて各テスト内で `HAKO_STAGEB_ALLOW_FALLBACK=1` を付与(TTL; 既定OFF)。
|
||||
|
||||
Default quick canaries (regression)
|
||||
- apps/json_lint_vm.sh — JSON Lint expected outputs (OK×10 / ERROR×6)
|
||||
@ -70,11 +71,11 @@ Dispatch policy: length()
|
||||
- これにより、配列に対して誤って文字列長を返す回帰を防止する(2025‑11 修正)。
|
||||
|
||||
Deprecations
|
||||
- `NYASH_GATE_C_DIRECT` は移行中の互換トグル(TTL)だよ。将来は Gate‑C(Core)
|
||||
- `NYASH_GATE_C_DIRECT` は移行中の互換トグル(TTL)だよ。将来は Gate‑C(Core)
|
||||
直行(`HAKO_GATE_C_CORE=1`)に統一予定。新しい導線では Core の実行仕様(数値=rc,
|
||||
安定化した診断タグ)が適用されるよ。
|
||||
- 互換トグルを使うと起動時に警告が出るよ(`HAKO_GATE_C_DIRECT_SILENCE=1` で抑止可)。
|
||||
- Stage‑B fallback TTL: global既定はOFF。テスト内でのみ `HAKO_STAGEB_ALLOW_FALLBACK=1` を設定して使用する(TTL)。
|
||||
- Stage‑B fallback TTL: 既定OFF(撤退方針)。必要な場合はテスト内限定で `HAKO_STAGEB_ALLOW_FALLBACK=1` を付与する。
|
||||
|
||||
Diagnostics (stable tags)
|
||||
- 本フェーズでは、Gate‑C(Core) の境界で安定タグを整形して出力する:
|
||||
@ -109,7 +110,8 @@ Minimal mir_call semantics (Core)
|
||||
- Methods (Map): `size()/len()/iterator()/set()/get()`(エントリ数メタを返す/更新する/メタから取得する)
|
||||
- ModuleFunction: `ArrayBox.len/0` / `MapBox.len/0`(メタのサイズを返す)— 他はタグ付き Fail‑Fast
|
||||
- Global/Extern: `env.console.{log|warn|error}`(数値引数のみ印字)
|
||||
- Others are Fail‑Fast(安定文言を出力)
|
||||
- Others are Fail‑Fast(安定文言を出力)。Closure 生成は v1 bridge で受理(NewClosure 発行)するが、
|
||||
実行時の呼出は未実装(VM 側は Fail‑Fast)。
|
||||
|
||||
See also: docs/development/architecture/collection_semantics.md(Array/Map のSSOT集約)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user