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:
nyash-codex
2025-11-02 08:23:43 +09:00
parent 91f3d82deb
commit 3aa0c3c875
15 changed files with 326 additions and 119 deletions

View File

@ -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 StageB driver: parse args/env, extract main body if wrapped in `box Main { static method main(){...} }`,
// then run ParserBox → FlowEntry emit. Keep implementation singlemethod 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