Files
hakorune/lang/src/compiler/pipeline_v2/emit_call_box.hako
nyash-codex df9068a555 feat(stage-b): Add FLOW keyword support + fix Stage-3 keyword conflicts
##  Fixed Issues

### 1. `local` keyword tokenization (commit 9aab64f7)
- Added Stage-3 gate for LOCAL/TRY/CATCH/THROW keywords
- LOCAL now only active when NYASH_PARSER_STAGE3=1

### 2. `env.local.get` keyword conflict
- File: `lang/src/compiler/entry/compiler_stageb.hako:21-23`
- Problem: `.local` in member access tokenized as `.LOCAL` keyword
- Fix: Commented out `env.local.get("HAKO_SOURCE")` line
- Fallback: Use `--source` argument (still functional)

### 3. `flow` keyword missing
- Added FLOW to TokenType enum (`src/tokenizer/kinds.rs`)
- Added "flow" → TokenType::FLOW mapping (`src/tokenizer/lex_ident.rs`)
- Added FLOW to Stage-3 gate (requires NYASH_PARSER_STAGE3=1)
- Added FLOW to parser statement dispatch (`src/parser/statements/mod.rs`)
- Added FLOW to declaration handler (`src/parser/statements/declarations.rs`)
- Updated box_declaration parser to accept BOX or FLOW (`src/parser/declarations/box_definition.rs`)
- Treat `flow FooBox {}` as syntactic sugar for `box FooBox {}`

### 4. Module namespace conversion
- Renamed `lang.compiler.builder.ssa.local` → `localvar` (avoid keyword)
- Renamed file `local.hako` → `local_ssa.hako`
- Converted 152 path-based using statements to namespace format
- Added 26+ entries to `nyash.toml` [modules] section

## ⚠️ Remaining Issues

### Stage-B selfhost compiler performance
- Stage-B compiler not producing output (hangs/times out after 10+ seconds)
- Excessive PHI debug output suggests compilation loop issue
- Needs investigation: infinite loop or N² algorithm in hako compiler

### Fallback JSON version mismatch
- Rust fallback (`--emit-mir-json`) emits MIR v1 JSON (schema_version: "1.0")
- Smoke tests expect MIR v0 JSON (`"version":0, "kind":"Program"`)
- stageb_helpers.sh fallback needs adjustment

## Test Status
- Parse errors: FIXED 
- Keyword conflicts: FIXED 
- Stage-B smoke tests: STILL FAILING  (performance issue)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-02 04:13:17 +09:00

90 lines
3.5 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// EmitCallBox — Return(Call name(int_args...)) を MIR(JSON v0) に最小変換
// 仕様: 各引数を const i64 として材化し、call を発行、dst を ret する。
using lang.compiler.pipeline_v2.regex_flow as RegexFlow
using lang.compiler.emit.common.header_emit as HeaderEmitBox
using selfhost.shared.mir.schema as MirSchemaBox
static box EmitCallBox {
_to_str(n) {
local v = n
if v == 0 { return "0" }
if v < 0 { return "-" + EmitCallBox._to_str(0 - v) }
local out = ""; local digits = "0123456789"
loop (v > 0) {
local d = v % 10
local ch = digits.substring(d, d+1)
out = ch + out
v = v / 10
}
return out
}
_quote(s) {
if s == null { return "\"\"" }
local out = ""; local i = 0; local n = s.length()
loop (i < n) {
local ch = s.substring(i, i+1)
if ch == "\\" { out = out + "\\\\" }
else { if ch == "\"" { out = out + "\\\"" } else {
if ch == "\n" { out = out + "\\n" } else {
if ch == "\r" { out = out + "\\r" } else {
if ch == "\t" { out = out + "\\t" } else { out = out + ch }
}
}
}}
i = i + 1
}
return "\"" + out + "\""
}
emit_call_int_args(name, args) {
if name == null { name = "" }
if args == null { args = [] }
// JSON v0 shape (HeaderEmitBox contract): {functions:[{name,params,blocks:[{id,instructions}]}]}
// Materialize immediate int args: r1..rN; mir_call Extern(name)(r1..rN)->rK; ret rK
local s = "" + args
local pos = 0
local n = 0
// Build instruction JSON (string) pieces (plugins OFFでも動くよう配列を使わない)
local body = "["
local first = 1
// const r1..rN
loop(true) {
local ds = RegexFlow.digits_from(s, pos)
if ds == "" { pos = pos + 1 } else {
local vid = 1 + n
local vv = RegexFlow.to_int(ds)
if first == 1 { first = 0 } else { body = body + "," }
body = body + "{\\\"op\\\":\\\"const\\\",\\\"dst\\\":" + EmitCallBox._to_str(vid) + ",\\\"value\\\":{\\\"type\\\":\\\"i64\\\",\\\"value\\\":" + EmitCallBox._to_str(vv) + "}}"
n = n + 1
pos = pos + ds.length()
}
if pos >= s.length() { break }
}
local dst = n + 1
// mir_call (Extern)
{
// args JSON: [1,2,...]
local args_s = "["; { local i=0; loop(i<n) { if i>0 { args_s = args_s + "," } args_s = args_s + EmitCallBox._to_str(1+i); i=i+1 } } args_s = args_s + "]"
local name_q = EmitCallBox._quote("" + name)
local call_json = "{\\\"op\\\":\\\"mir_call\\\",\\\"dst\\\":" + EmitCallBox._to_str(dst) +
",\\\"mir_call\\\":{\\\"callee\\\":{\\\"type\\\":\\\"Extern\\\",\\\"name\\\":" + name_q + "},\\\"args\\\":" + args_s + ",\\\"effects\\\":[]}}"
if first == 1 { first = 0 } else { body = body + "," }
body = body + call_json
}
// ret dst
if first == 1 { first = 0 } else { body = body + "," }
body = body + "{\\\"op\\\":\\\"ret\\\",\\\"value\\\":" + EmitCallBox._to_str(dst) + "}"
body = body + "]"
local module_json = "{\"kind\":\"MIR\",\"schema_version\":\"1.0\",\"functions\":[{\"name\":\"main\",\"params\":[],\"blocks\":[{\"id\":0,\"instructions\":" + body + "}]}]}"
return module_json
}
// JSON v1 (MirCall) emission — shape equivalentCallEmitBox + HeaderEmitBox
emit_call_int_args_v1(name, args) {
// v1 path is shape-equivalent for now — delegate to v0 builder above
return EmitCallBox.emit_call_int_args(name, args)
}
}
static box EmitCallStub { main(args) { return 0 } }