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>
This commit is contained in:
nyash-codex
2025-11-02 04:13:17 +09:00
parent 82cdfa7056
commit df9068a555
115 changed files with 478 additions and 232 deletions

View File

@ -1,8 +1,8 @@
// Moved from apps/selfhost-compiler/builder/mod.hako
// builder/mod.hako — Aggregator for compiler-track passes (scaffold)
using lang.compiler.builder.ssa.local as LocalSSA
using lang.compiler.builder.ssa.loop as LoopSSA
using lang.compiler.builder.ssa.localvar as LocalSSA
using lang.compiler.builder.ssa.loopssa as LoopSSA
using lang.compiler.builder.rewrite.special as RewriteSpecial
using lang.compiler.builder.rewrite.known as RewriteKnown

View File

@ -1,7 +1,7 @@
// cond_inserter.hako — minimal JSON-string helper to ensure branch(cond) has copy
// Scope: smoke/dev helper文字列JSON限定、構造的なLocalSSAとは別ライン
using "lang/src/shared/json/json_cursor.hako" as JsonCursorBox
using selfhost.shared.json.core.json_cursor as JsonCursorBox
static box CondInserter {
ensure_cond(mjson) {

View File

@ -4,7 +4,7 @@
// 「ブロック内にオペランドが材化されているLocalSSA」ことを軽く検証・整形する。
// - 既定では再配線Copy挿入等は行わず、将来の拡張に備えた安全な足場のみを提供する。
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using selfhost.shared.common.string_helpers as StringHelpers
static box LocalSSA {
// --- 内部ヘルパ ---
// trace fields are created on demand (dynamic properties)

View File

@ -4,7 +4,7 @@
// - Args are expected as an ArrayBox of integer register ids.
// - Callers may optionally attach (string like "[1,2]") for legacy rebuild paths.
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using selfhost.shared.common.string_helpers as StringHelpers
static box CallEmitBox {
make_call(name, arg_ids, dst) {

View File

@ -1,6 +1,6 @@
// newbox_emit_box.hako — NewBoxEmitBox: construct MIR(JSON v0) node for newbox
// Responsibility: return MapBox node for { op: newbox, box_type, args, dst }.
using "lang/src/shared/json/stringify.hako" as JSON
using selfhost.shared.json.stringify as JSON
static box NewBoxEmitBox {
make_new(box_type, arg_ids, dst) {

View File

@ -3,8 +3,8 @@
// Future: add Binary/Compare/ExternCall/BoxCall lowering incrementally.
using selfhost.common.json.mir_builder_min as MirJsonBuilderMin
using "lang/src/shared/json/stringify.hako" as JSON
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using selfhost.shared.json.stringify as JSON
using selfhost.shared.common.string_helpers as StringHelpers
static box MirEmitterBox {
_index_of(hay, needle) { return hay.indexOf(needle) }

View File

@ -2,7 +2,7 @@
// - When invoked with --min-json, emit minimal Program JSON v0 to stdout
// - Otherwise, act as a silent placeholder (return 0)
using "lang/src/compiler/entry/compiler_stageb.hako" as StageBMain
using lang.compiler.entry.compiler_stageb as StageBMain
static box Main {
_parse_signed_int(raw) {

View File

@ -18,7 +18,8 @@ static box StageBMain {
i = i + 1
}
}
if src == null { src = env.local.get("HAKO_SOURCE") }
// Skip env.local.get check - Stage-3 keyword conflict
// Original: if src == null { src = env.local.get("HAKO_SOURCE") }
if src == null { src = "return 0" }
// 2) Stage3 acceptance default ON for selfhost (env may turn off; keep tolerant here)
@ -72,7 +73,7 @@ static box StageBMain {
local prefer = 1
local out = FlowEntryBox.emit_v0_from_ast_with_context(ast_json, prefer, usings_json, null, externs_json)
if out == null || out == "" { out = FlowEntryBox.emit_v0_from_ast(ast_json, prefer) }
if out == null || out == "" { out = "{\"version\":0,\"kind\":\"Program\",\"body\":[{\"type\":\"Return\",\"expr\":{\"type\":\"Int\",\"value\":0}}]}" }
// TTL OFF: do not fallback to dummy JSON when emit fails. Empty output surfaces failure to caller.
print(out)
return 0
}

View File

@ -27,7 +27,7 @@ pipeline_v2.pipeline = "pipeline_v2/pipeline.hako"
pipeline_v2.using_resolver = "pipeline_v2/using_resolver_box.hako"
# Builder / SSA / Rewrite (scaffolds)
builder.ssa.local = "builder/ssa/local.hako"
builder.ssa.local = "builder/ssa/local_ssa.hako"
builder.ssa.loop = "builder/ssa/loopssa.hako"
builder.ssa.cond_inserter = "builder/ssa/cond_inserter.hako"
builder.rewrite.special = "builder/rewrite/special.hako"

View File

@ -4,8 +4,8 @@
// Behavior: If dotted, verify alias head is known; otherwise print a stable one-line error and return 0.
// NonResponsibility: Namespace normalization or emit.
using "lang/src/compiler/pipeline_v2/using_resolver_box.hako" as UsingResolverBox
using "lang/src/compiler/pipeline_v2/regex_flow.hako" as RegexFlow
using lang.compiler.pipeline_v2.using_resolver_box as UsingResolverBox
using lang.compiler.pipeline_v2.regex_flow as RegexFlow
static box AliasPreflightBox {
// Returns 1 if OK, 0 if alias head is unresolved (prints error).

View File

@ -1,6 +1,6 @@
// CallExtractBox — Stage1 JSON から Return(Call name(args...)) を抽出(整数引数のみ)
// Delegation to Stage1IntArgsExtractBox (unified implementation)
using "lang/src/compiler/pipeline_v2/stage1_int_args_extract_box.hako" as Unified
using lang.compiler.pipeline_v2.stage1_int_args_extract_box as Unified
static box CallExtractBox {
// Returns { name: String, args: [Int,...] } or null

View File

@ -1,6 +1,6 @@
// CompareExtractBox — Stage1 JSON から Compare(lhs,rhs,op) を堅牢に抽出(整数のみ)
using "lang/src/compiler/pipeline_v2/regex_flow.hako" as RegexFlow
using "lang/src/shared/common/box_helpers.hako" as BoxHelpers
using lang.compiler.pipeline_v2.regex_flow as RegexFlow
using selfhost.shared.common.box_helpers as BoxHelpers
static box CompareExtractBox {
// --- internal helpers (range & safe find) ---

View File

@ -1,5 +1,5 @@
// EmitBinopBox — binop の最小 MIR(JSON v0) 生成
using "lang/src/shared/json/mir_builder_min.hako" as MirJsonBuilderMin
using selfhost.shared.json.mir_builder_min as MirJsonBuilderMin
static box EmitBinopBox {
_map_binop(opk) {

View File

@ -1,9 +1,9 @@
// EmitCallBox — Return(Call name(int_args...)) を MIR(JSON v0) に最小変換
// 仕様: 各引数を const i64 として材化し、call を発行、dst を ret する。
using "lang/src/compiler/pipeline_v2/regex_flow.hako" as RegexFlow
using lang.compiler.pipeline_v2.regex_flow as RegexFlow
using lang.compiler.emit.common.header_emit as HeaderEmitBox
using "lang/src/shared/mir/mir_schema_box.hako" as MirSchemaBox
using selfhost.shared.mir.schema as MirSchemaBox
static box EmitCallBox {
_to_str(n) {

View File

@ -1,5 +1,5 @@
// EmitCompareBox — compare/branch/jump/ret の最小 MIR(JSON v0) 生成string直組み
using "lang/src/compiler/pipeline_v2/local_ssa_box.hako" as LocalSSABox
using lang.compiler.pipeline_v2.localvar_ssa_box as LocalSSABox
using lang.compiler.emit.common.mir_emit as MirEmitBox
using lang.compiler.emit.common.header_emit as HeaderEmitBox

View File

@ -1,9 +1,9 @@
// EmitMethodBox — Return(Method recv, method, args[int...]) → MIR(JSON v0)
// 最小形: const recv→r1; 各引数を r2..rN; boxcall(method, recv=r1, args=r2..) → rK; ret rK
using "lang/src/compiler/pipeline_v2/regex_flow.hako" as RegexFlow
using lang.compiler.pipeline_v2.regex_flow as RegexFlow
using lang.compiler.emit.common.header_emit as HeaderEmitBox
using "lang/src/shared/mir/mir_schema_box.hako" as MirSchemaBox
using selfhost.shared.mir.schema as MirSchemaBox
static box EmitMethodBox {
_to_str(n) {

View File

@ -1,9 +1,9 @@
using "lang/src/shared/mir/json_emit_box.hako" as JsonEmitBox
using selfhost.shared.mir.json_emit as JsonEmitBox
// Shared MIR helpers (P1/P2)
using "lang/src/shared/mir/mir_schema_box.hako" as MirSchema
using "lang/src/shared/mir/block_builder_box.hako" as BlockBuilder
using "lang/src/compiler/pipeline_v2/local_ssa_box.hako" as LocalSSABox
using "lang/src/shared/common/box_helpers.hako" as BoxHelpers
using selfhost.shared.mir.schema as MirSchema
using selfhost.shared.mir.builder as BlockBuilder
using lang.compiler.pipeline_v2.localvar_ssa_box as LocalSSABox
using selfhost.shared.common.box_helpers as BoxHelpers
flow EmitMirFlow {
_int(n) { return "" + n }

View File

@ -1,9 +1,9 @@
using "lang/src/shared/mir/json_emit_box.hako" as JsonEmitBox
using selfhost.shared.mir.json_emit as JsonEmitBox
// Shared MIR helpers (P1)
using "lang/src/shared/mir/mir_schema_box.hako" as MirSchema
using "lang/src/shared/mir/block_builder_box.hako" as BlockBuilder
using "lang/src/shared/common/box_helpers.hako" as BoxHelpers
using "lang/src/compiler/pipeline_v2/local_ssa_box.hako" as LocalSSABox
using selfhost.shared.mir.schema as MirSchema
using selfhost.shared.mir.builder as BlockBuilder
using selfhost.shared.common.box_helpers as BoxHelpers
using lang.compiler.pipeline_v2.localvar_ssa_box as LocalSSABox
flow EmitMirFlowMap {
_array_len(arr) { return BoxHelpers.array_len(arr) }

View File

@ -1,12 +1,12 @@
// EmitNewBoxBox — Return(New class, args[int...]) → MIR(JSON v0)
// 最小形: 各引数を r1..rN; newbox(class, args=r1..rN) → rK; ret rK
using "lang/src/shared/json/mir_builder_min.hako" as MirJsonBuilderMin
using "lang/src/compiler/pipeline_v2/regex_flow.hako" as RegexFlow
using "lang/src/compiler/pipeline_v2/stage1_args_parser_box.hako" as Stage1ArgsParserBox
using "lang/src/shared/mir/json_emit_box.hako" as JsonEmitBox
using "lang/src/shared/mir/block_builder_box.hako" as BlockBuilder
using "lang/src/compiler/pipeline_v2/local_ssa_box.hako" as LocalSSABox
using selfhost.shared.json.mir_builder_min as MirJsonBuilderMin
using lang.compiler.pipeline_v2.regex_flow as RegexFlow
using lang.compiler.pipeline_v2.stage1_args_parser_box as Stage1ArgsParserBox
using selfhost.shared.mir.json_emit as JsonEmitBox
using selfhost.shared.mir.builder as BlockBuilder
using lang.compiler.pipeline_v2.localvar_ssa_box as LocalSSABox
static box EmitNewBoxBox {
emit_newbox_int_args(class_name, args) {

View File

@ -14,7 +14,7 @@ using lang.compiler.parser.stmt.parser_control_box
using lang.compiler.parser.stmt.parser_exception_box
using lang.compiler.stage1.json_program_box
using lang.compiler.stage1.emitter_box as EmitterBoxMod
using "lang/src/compiler/pipeline_v2/backend_box.hako" as BackendBoxMod
using lang.compiler.pipeline_v2.backend_box as BackendBoxMod
box ExecutionPipelineBox {
backend_name

View File

@ -1,8 +1,8 @@
// flow_entry.hako — Pipeline v2 entry boxemit-only
// Guard: This box performs no execution. Returns MIR(JSON) as text.
using "lang/src/compiler/pipeline_v2/pipeline.hako" as PipelineV2
using "lang/src/shared/json/mir_v1_adapter.hako" as MirJsonV1Adapter
using lang.compiler.pipeline_v2.pipeline as PipelineV2
using selfhost.shared.json.mir_v1_adapter as MirJsonV1Adapter
static box FlowEntryBox {
// Emit legacy v0 JSONcall/boxcall/newbox。最小入力: Stage1 JSON 文字列

View File

@ -1,7 +1,7 @@
// LocalSSABox — 材化materialize/Copy 挿入の最小ポリシーを集約
// Phase 15.7: 最小実装。将来 PHI/Call 前の規約をここに集約して拡張する。
using "lang/src/shared/common/box_helpers.hako" as BoxHelpers
using selfhost.shared.common.box_helpers as BoxHelpers
static box LocalSSABox {
_maybe_unwrap_instructions(insts) {

View File

@ -1,7 +1,7 @@
// map_helpers_box.hako — Pipeline用の軽量ヘルパMapBoxの型付き取得
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/common/box_helpers.hako" as BoxHelpers
using selfhost.shared.common.string_helpers as StringHelpers
using selfhost.shared.common.box_helpers as BoxHelpers
static box MapHelpersBox {
_raw_get(m, key) {
return BoxHelpers.map_get(m, key)

View File

@ -1,6 +1,6 @@
// MethodExtractBox — Stage1 JSON から Return(Method recv, method, args) を抽出(整数引数のみ; recvは無視
// Delegation to Stage1IntArgsExtractBox (unified implementation)
using "lang/src/compiler/pipeline_v2/stage1_int_args_extract_box.hako" as Unified
using lang.compiler.pipeline_v2.stage1_int_args_extract_box as Unified
static box MethodExtractBox {
// Returns { method: String, args: [Int,...] } or null

View File

@ -1,10 +1,10 @@
// MirBuilderBox — minimal Ny→MIR(JSON v0) lowering entry (dev)
// Phase 15.7: kept optional; pipeline.v2 uses Emit flow directly.
using "lang/src/compiler/pipeline_v2/stage1_extract_flow.hako" as Stage1ExtractFlow
using "lang/src/compiler/pipeline_v2/emit_return_box.hako" as EmitReturnBox
using "lang/src/compiler/pipeline_v2/emit_binop_box.hako" as EmitBinopBox
using "lang/src/compiler/pipeline_v2/emit_compare_box.hako" as EmitCompareBox
using "lang/src/shared/common/box_helpers.hako" as BoxHelpers
using lang.compiler.pipeline_v2.stage1_extract_flow as Stage1ExtractFlow
using lang.compiler.pipeline_v2.emit_return_box as EmitReturnBox
using lang.compiler.pipeline_v2.emit_binop_box as EmitBinopBox
using lang.compiler.pipeline_v2.emit_compare_box as EmitCompareBox
using selfhost.shared.common.box_helpers as BoxHelpers
box MirBuilderBox {
// Placeholder for optimizer toggle

View File

@ -1,12 +1,12 @@
// MirCallBox — JSON v1 unified call emitters薄い箱
// 目的: v1mir_callを第一級に扱う最小APIを集中させる。実行は含まないemit-only
using "lang/src/shared/json/mir_builder_min.hako" as MirJsonBuilderMin
using "lang/src/compiler/pipeline_v2/regex_flow.hako" as RegexFlow
using selfhost.shared.json.mir_builder_min as MirJsonBuilderMin
using lang.compiler.pipeline_v2.regex_flow as RegexFlow
using lang.compiler.emit.common.mir_emit as MirEmitBox
using lang.compiler.emit.common.call_emit as CallEmitBox
using lang.compiler.emit.common.header_emit as HeaderEmitBox
using "lang/src/shared/mir/json_emit_box.hako" as JsonEmitBox
using selfhost.shared.mir.json_emit as JsonEmitBox
static box MirCallBox {
// Global(name, args:int[])

View File

@ -3,9 +3,9 @@
// - primary: NamespaceBox.normalize_global_name(raw, resolver)
// - fallback: unique tail match via UsingResolverBox.guess_namespace_from_tail
using "lang/src/compiler/pipeline_v2/using_resolver_box.hako" as UsingResolverBox
using "lang/src/compiler/pipeline_v2/namespace_box.hako" as NamespaceBox
using "lang/src/compiler/pipeline_v2/regex_flow.hako" as RegexFlow
using lang.compiler.pipeline_v2.using_resolver_box as UsingResolverBox
using lang.compiler.pipeline_v2.namespace_box as NamespaceBox
using lang.compiler.pipeline_v2.regex_flow as RegexFlow
static box PipelineNameResolveBox {
// Returns fully-qualified name or null

View File

@ -5,8 +5,8 @@
// NonResponsibility:
// - IO / TOML 読み込み、Runner 側の using 解決、実行
using "lang/src/compiler/pipeline_v2/using_resolver_box.hako" as UsingResolver
using "lang/src/compiler/pipeline_v2/regex_flow.hako" as RegexFlow
using lang.compiler.pipeline_v2.using_resolver_box as UsingResolver
using lang.compiler.pipeline_v2.regex_flow as RegexFlow
static box NamespaceBox {
// Normalize global function name using resolver context

View File

@ -1,6 +1,6 @@
// NewExtractBox — Stage1 JSON から Return(New class(args...)) を抽出(整数引数のみ)
// Delegation to Stage1IntArgsExtractBox (unified implementation)
using "lang/src/compiler/pipeline_v2/stage1_int_args_extract_box.hako" as Unified
using lang.compiler.pipeline_v2.stage1_int_args_extract_box as Unified
static box NewExtractBox {
// Returns { class: String, args: [Int,...] } or null

View File

@ -1,7 +1,7 @@
// normalizer_box.hako — Minimal normalizer for Compare maps (cmp/lhs/rhs)
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/common/box_helpers.hako" as BoxHelpers
using selfhost.shared.common.string_helpers as StringHelpers
using selfhost.shared.common.box_helpers as BoxHelpers
static box NormalizerBox {
// Normalize cmp/lhs/rhs into MapBox with String keys
normalize_cmp(raw) {

View File

@ -1,30 +1,30 @@
using "lang/src/compiler/pipeline_v2/stage1_extract_flow.hako" as Stage1ExtractFlow
using "lang/src/compiler/pipeline_v2/emit_return_box.hako" as EmitReturnBox
using "lang/src/compiler/pipeline_v2/emit_binop_box.hako" as EmitBinopBox
using "lang/src/compiler/pipeline_v2/emit_compare_box.hako" as EmitCompareBox
using "lang/src/compiler/pipeline_v2/regex_flow.hako" as RegexFlow
using lang.compiler.builder.ssa.local as LocalSSA
using "lang/src/compiler/pipeline_v2/emit_call_box.hako" as EmitCallBox
using "lang/src/compiler/pipeline_v2/emit_method_box.hako" as EmitMethodBox
using "lang/src/compiler/pipeline_v2/emit_newbox_box.hako" as EmitNewBoxBox
using "lang/src/compiler/pipeline_v2/mir_call_box.hako" as MirCallBox
using "lang/src/shared/json/mir_v1_adapter.hako" as MirJsonV1Adapter
using "lang/src/compiler/pipeline_v2/compare_extract_box.hako" as CompareExtractBox
using "lang/src/compiler/pipeline_v2/normalizer_box.hako" as NormalizerBox
using "lang/src/compiler/pipeline_v2/map_helpers_box.hako" as MapHelpersBox
using "lang/src/compiler/pipeline_v2/call_extract_box.hako" as CallExtractBox
using "lang/src/compiler/pipeline_v2/method_extract_box.hako" as MethodExtractBox
using "lang/src/compiler/pipeline_v2/new_extract_box.hako" as NewExtractBox
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/compiler/pipeline_v2/using_resolver_box.hako" as UsingResolverBox
using "lang/src/compiler/pipeline_v2/namespace_box.hako" as NamespaceBox
using "lang/src/compiler/pipeline_v2/signature_verifier_box.hako" as SignatureVerifierBox
using "lang/src/compiler/pipeline_v2/stage1_json_scanner_box.hako" as Stage1JsonScannerBox
using "lang/src/compiler/pipeline_v2/stage1_name_args_normalizer_box.hako" as NameArgsNormBox
using "lang/src/compiler/pipeline_v2/alias_preflight_box.hako" as AliasPreflightBox
using "lang/src/compiler/pipeline_v2/stage1_args_parser_box.hako" as Stage1ArgsParserBox
using "lang/src/compiler/pipeline_v2/pipeline_helpers_box.hako" as PipelineHelpersBox
using "lang/src/shared/json/mir_v1_meta_inject_box.hako" as MirV1MetaInjectBox
using lang.compiler.pipeline_v2.stage1_extract_flow as Stage1ExtractFlow
using lang.compiler.pipeline_v2.emit_return_box as EmitReturnBox
using lang.compiler.pipeline_v2.emit_binop_box as EmitBinopBox
using lang.compiler.pipeline_v2.emit_compare_box as EmitCompareBox
using lang.compiler.pipeline_v2.regex_flow as RegexFlow
using lang.compiler.builder.ssa.localvar as LocalSSA
using lang.compiler.pipeline_v2.emit_call_box as EmitCallBox
using lang.compiler.pipeline_v2.emit_method_box as EmitMethodBox
using lang.compiler.pipeline_v2.emit_newbox_box as EmitNewBoxBox
using lang.compiler.pipeline_v2.mir_call_box as MirCallBox
using selfhost.shared.json.mir_v1_adapter as MirJsonV1Adapter
using lang.compiler.pipeline_v2.compare_extract_box as CompareExtractBox
using lang.compiler.pipeline_v2.normalizer_box as NormalizerBox
using lang.compiler.pipeline_v2.map_helpers_box as MapHelpersBox
using lang.compiler.pipeline_v2.call_extract_box as CallExtractBox
using lang.compiler.pipeline_v2.method_extract_box as MethodExtractBox
using lang.compiler.pipeline_v2.new_extract_box as NewExtractBox
using sh_core as StringHelpers
using lang.compiler.pipeline_v2.using_resolver_box as UsingResolverBox
using lang.compiler.pipeline_v2.namespace_box as NamespaceBox
using lang.compiler.pipeline_v2.signature_verifier_box as SignatureVerifierBox
using lang.compiler.pipeline_v2.stage1_json_scanner_box as Stage1JsonScannerBox
using lang.compiler.pipeline_v2.stage1_name_args_normalizer_box as NameArgsNormBox
using lang.compiler.pipeline_v2.alias_preflight_box as AliasPreflightBox
using lang.compiler.pipeline_v2.stage1_args_parser_box as Stage1ArgsParserBox
using lang.compiler.pipeline_v2.pipeline_helpers_box as PipelineHelpersBox
using selfhost.shared.json.mir_v1_meta_inject_box as MirV1MetaInjectBox
flow PipelineV2 {
lower_stage1_to_mir(ast_json, prefer_cfg) {

View File

@ -1,9 +1,9 @@
// pipeline_emit_box.hako — PipelineEmitBox
// Responsibility: small wrappers that emit MIR(JSON v0) and apply LocalSSA ensures
using "lang/src/compiler/pipeline_v2/emit_call_box.hako" as EmitCallBox
using "lang/src/compiler/pipeline_v2/local_ssa_box.hako" as LocalSSABox
using "lang/src/shared/json/mir_v1_meta_inject_box.hako" as MirV1MetaInjectBox
using lang.compiler.pipeline_v2.emit_call_box as EmitCallBox
using lang.compiler.pipeline_v2.localvar_ssa_box as LocalSSABox
using selfhost.shared.json.mir_v1_meta_inject_box as MirV1MetaInjectBox
static box PipelineEmitBox {
// Emit Call(name, int-args) → JSON v0, wrapped with LocalSSA ensures

View File

@ -2,8 +2,8 @@
// 責務: JSON/数値解析の共通ユーティリティ
// Extracted from PipelineV2 flow (556行 → 506行、-50行削減)
using "lang/src/compiler/pipeline_v2/regex_flow.hako" as RegexFlow
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using lang.compiler.pipeline_v2.regex_flow as RegexFlow
using selfhost.shared.common.string_helpers as StringHelpers
static box PipelineHelpersBox {
// Parse integer at specific position (whitespace-aware, sign-aware)

View File

@ -1,6 +1,6 @@
// readonly_map_view.hako — 読み取り専用ビュー(誤更新防止用)
using "lang/src/shared/common/box_helpers.hako" as BoxHelpers
using selfhost.shared.common.box_helpers as BoxHelpers
static box ReadOnlyMapView {
_m

View File

@ -1,4 +1,4 @@
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using selfhost.shared.common.string_helpers as StringHelpers
flow RegexFlow {
// Minimal regex-like helpers focused on readability and determinism.

View File

@ -6,7 +6,7 @@
// (e.g., indexOf=1 on String/Array, push=1 on Array, etc.).
// - Unknown methods are allowed (return 1) to avoid over-blocking during bring-up.
using "lang/src/compiler/pipeline_v2/regex_flow.hako" as RegexFlow
using lang.compiler.pipeline_v2.regex_flow as RegexFlow
// Method registry is optional; allow unknowns by design in bring-up.
static box SignatureVerifierBox {

View File

@ -2,8 +2,8 @@
// Responsibility: Parse Stage1 args JSON text into integers (MVP: Int only).
// NonResponsibility: MIR emit or namespace.
using "lang/src/compiler/pipeline_v2/regex_flow.hako" as RegexFlow
using "lang/src/shared/json/json_cursor.hako" as JsonCursorBox
using lang.compiler.pipeline_v2.regex_flow as RegexFlow
using selfhost.shared.json.core.json_cursor as JsonCursorBox
static box Stage1ArgsParserBox {
// Count Int occurrences in Stage1 args JSON text.

View File

@ -1,4 +1,4 @@
using "lang/src/compiler/pipeline_v2/regex_flow.hako" as RegexFlow
using lang.compiler.pipeline_v2.regex_flow as RegexFlow
flow Stage1ExtractFlow {
// Extract minimal info from Stage1 JSON (Return Int / BinOp / Compare)

View File

@ -2,7 +2,7 @@
// Responsibility: 3つの類似ExtractBoxを統合call_extract/method_extract/new_extract
// Notes: 85%重複コードを共通化、args抽出ロジックを一元管理
using "lang/src/compiler/pipeline_v2/regex_flow.hako" as RegexFlow
using lang.compiler.pipeline_v2.regex_flow as RegexFlow
static box Stage1IntArgsExtractBox {
// ===== 汎用Extract内部実装 =====

View File

@ -6,8 +6,8 @@
// - name/args basic extraction
// NonResponsibility: MIR emit, namespace resolution, IO
using "lang/src/shared/json/json_cursor.hako" as JsonCursorBox
using "lang/src/shared/common/box_helpers.hako" as BoxHelpers
using selfhost.shared.json.core.json_cursor as JsonCursorBox
using selfhost.shared.common.box_helpers as BoxHelpers
static box Stage1JsonScannerBox {
// Find the start position of Program.body array key

View File

@ -5,10 +5,10 @@
// - New: class normalization via UsingResolverBox/NamespaceBox
// NonResponsibility: MIR emit or IO
using "lang/src/compiler/pipeline_v2/namespace_box.hako" as NamespaceBox
using "lang/src/compiler/pipeline_v2/signature_verifier_box.hako" as SignatureVerifierBox
using "lang/src/compiler/pipeline_v2/alias_preflight_box.hako" as AliasPreflightBox
using "lang/src/shared/common/box_helpers.hako" as BoxHelpers
using lang.compiler.pipeline_v2.namespace_box as NamespaceBox
using lang.compiler.pipeline_v2.signature_verifier_box as SignatureVerifierBox
using lang.compiler.pipeline_v2.alias_preflight_box as AliasPreflightBox
using selfhost.shared.common.box_helpers as BoxHelpers
static box Stage1NameArgsNormalizerBox {
_label_or_name(scan) {

View File

@ -2,7 +2,7 @@
// Responsibility: Provide a thin, unified guard to prevent emit after terminator.
// Notes: Operates on an instructions ArrayBox of Map nodes with key "op".
using "lang/src/shared/common/box_helpers.hako" as BoxHelpers
using selfhost.shared.common.box_helpers as BoxHelpers
static box TerminatorGuardBox {
// Return 1 if the given instructions array ends with ret/throw

View File

@ -4,9 +4,9 @@
// modules_map: Map, modules_keys: Array
// }
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/common/box_helpers.hako" as BoxHelpers
using "lang/src/compiler/pipeline_v2/regex_flow.hako" as RegexFlow
using selfhost.shared.common.string_helpers as StringHelpers
using selfhost.shared.common.box_helpers as BoxHelpers
using lang.compiler.pipeline_v2.regex_flow as RegexFlow
static box UsingResolverBox {
// Lightweight state as String: holds modules_json only

View File

@ -1,6 +1,6 @@
// Moved from apps/selfhost-compiler/boxes/emitter_box.hako
// EmitterBox — thin wrapper to emit JSON v0 (extracted)
using "lang/src/compiler/stage1/json_program_box.hako" as JsonProg
using lang.compiler.stage1.json_program_box as JsonProg
static box EmitterBox {
emit_program(json, usings_json, externs_json) {

View File

@ -1,8 +1,8 @@
// Moved from apps/selfhost-compiler/boxes/json_program_box.hako
// JsonProgramBox — JSON v0 正規化の最小箱
// 責務: Programヘッダの補正・meta.usings注入・主要Stmt/Exprのキー順安定化
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/json/json_utils.hako" as JsonUtilsBox
using selfhost.shared.common.string_helpers as StringHelpers
using selfhost.shared.json.utils.json_utils as JsonUtilsBox
static box JsonProgramBox {
normalize(json, usings_json, externs_json) {

View File

@ -2,7 +2,7 @@
// 目的: ArrayBox/MapBox の安全な操作を統一的に提供
// 削減: 7ファイル × 2パターン = 14重複 → 1箇所に集約
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using selfhost.shared.common.string_helpers as StringHelpers
static box BoxHelpers {
// ArrayBox.size/1 の結果unwrap (MapBox-wrapped integer対応)

View File

@ -1,7 +1,7 @@
// Mini-VM scanning and numeric helpers
// Delegation Policy: all scanning primitives route to JsonCursorBox to avoid divergence.
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/json/json_cursor.hako" as JsonCursorBox
using selfhost.shared.common.string_helpers as StringHelpers
using selfhost.shared.json.core.json_cursor as JsonCursorBox
static box MiniVmScan {
// helper: find needle from position pos (escape-aware where needed)

View File

@ -1,8 +1,8 @@
// json_scan.hako — JsonScanBox
// Escape-aware JSON structure scanning helpers.
using "lang/src/shared/json/core/string_scan.hako" as StringScanBox
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using selfhost.shared.json.core.string_scan as StringScanBox
using selfhost.shared.common.string_helpers as StringHelpers
static box JsonScanBox {
// minimal string→int (delegate to shared helper)

View File

@ -1,7 +1,7 @@
// string_scan.hako — StringScanBox
// Escape-aware string scanning helpers for JSON/text processing.
using "lang/src/shared/common/string_ops.hako" as StringOps
using selfhost.shared.common.string_ops as StringOps
static box StringScanBox {
// Return the single-character string at index i (empty if out of bounds)

View File

@ -2,9 +2,9 @@
// Responsibility: provide a minimal, escape-aware scanning facade used by JsonFragBox
// Delegates to StringOps, StringScanBox and JsonScanBox.
using "lang/src/shared/common/string_ops.hako" as StringOps
using "lang/src/shared/json/core/string_scan.hako" as StringScanBox
using "lang/src/shared/json/core/json_scan.hako" as JsonScanBox
using selfhost.shared.common.string_ops as StringOps
using selfhost.shared.json.core.string_scan as StringScanBox
using selfhost.shared.json.core.json_scan as JsonScanBox
static box JsonCursorBox {
index_of_from(hay, needle, pos) {

View File

@ -1,7 +1,7 @@
// JsonUtilsBox — JSON読み取りユーティリティの共通箱
// 責務: JSON値抽出・JSON構造パース・トップレベル配列分割
// Extracted from JsonProgramBox (480行 → 345行, 削減 ~135行)
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using selfhost.shared.common.string_helpers as StringHelpers
static box JsonUtilsBox {
// Extract JSON value by key (returns value with '@' + end position marker)

View File

@ -1,5 +1,5 @@
// mir_builder2.hako — Instance builder引数渡しバグ回避のため、非staticで内部状態を保持
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using selfhost.shared.common.string_helpers as StringHelpers
using lang.compiler.emit.common.json_emit as JsonEmitBox
using lang.compiler.emit.common.mir_emit as MirEmitBox
using lang.compiler.emit.common.header_emit as HeaderEmitBox

View File

@ -1,13 +1,13 @@
// mir_builder_min.nyash — Minimal MIR(JSON v0) builder for selfhost tests
// Scope: selfhost only (apps/selfhost/...); no core/runtime changes.
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/common/box_helpers.hako" as BoxHelpers
using selfhost.shared.common.string_helpers as StringHelpers
using selfhost.shared.common.box_helpers as BoxHelpers
using lang.compiler.emit.common.json_emit as JsonEmitBox
using lang.compiler.emit.common.mir_emit as MirEmitBox
using lang.compiler.emit.common.call_emit as CallEmitBox
using lang.compiler.emit.common.newbox_emit as NewBoxEmitBox
using "lang/src/shared/json/json_inst_encode_box.hako" as JsonInstEncodeBox
using selfhost.shared.json.json_inst_encode_box as JsonInstEncodeBox
box MirJsonBuilderMin {
buf: StringBox

View File

@ -1,7 +1,7 @@
// mir_v1_adapter.nyash — Minimal JSON v1 (mir_call) to v0 adapter for selfhost
// Scope: selfhost only. Transforms op:"mir_call" into legacy v0 ops (call/boxcall/newbox).
using "lang/src/shared/json/json_cursor.hako" as JsonCursorBox
using selfhost.shared.json.core.json_cursor as JsonCursorBox
static box MirJsonV1Adapter {
// Delegate to JsonCursorBox (escape-aware implementations, fixes 2 escape bugs)

View File

@ -2,8 +2,8 @@
// 責務: 文字列JSONから key:int / key:str を簡便に取り出す。
// 非責務: 実行・評価構造検査やVM実行は他箱に委譲
using "lang/src/shared/json/json_cursor.hako" as JsonCursorBox
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using selfhost.shared.json.core.json_cursor as JsonCursorBox
using selfhost.shared.common.string_helpers as StringHelpers
static box JsonFragBox {
// 基本ヘルパ

View File

@ -1,9 +1,9 @@
// selfhost/shared/mir/block_builder_box.hako
// BlockBuilderBox — small helpers to assemble P1 shapes
using "lang/src/shared/mir/mir_schema_box.hako" as MirSchemaBox
using "lang/src/shared/mir/loop_form_box.hako" as LoopFormBox
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using selfhost.shared.mir.schema as MirSchemaBox
using selfhost.shared.mir.loopform as LoopFormBox
using selfhost.shared.common.string_helpers as StringHelpers
static box BlockBuilderBox {

View File

@ -1,8 +1,8 @@
// selfhost/shared/mir/json_emit_box.hako
// JsonEmitBox — Gate C JSON emitter (schema_version 1.0, numbers unwrapped)
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/common/box_helpers.hako" as BoxHelpers
using selfhost.shared.common.string_helpers as StringHelpers
using selfhost.shared.common.box_helpers as BoxHelpers
static box JsonEmitBox {
_expect_map(val, context) {

View File

@ -1,7 +1,7 @@
// selfhost/shared/mir/loop_form_box.hako
// LoopFormBox — minimal loop structure builder (P2: continue/break snapshots + Exit PHI)
using "lang/src/shared/mir/mir_schema_box.hako" as MirSchemaBox
using selfhost.shared.mir.schema as MirSchemaBox
static box LoopFormBox {

View File

@ -9,15 +9,15 @@
using "lang/src/vm/boxes/result_box.hako" as Result
using "lang/src/vm/boxes/result_helpers.hako" as ResultHelpers
using "lang/src/shared/json/json_cursor.hako" as JsonCursorBox
using selfhost.shared.json.core.json_cursor as JsonCursorBox
using "lang/src/shared/json/json_canonical_box.hako" as JsonCanonicalBox
using "lang/src/vm/hakorune-vm/function_locator.hako" as FunctionLocatorBox
using "lang/src/vm/hakorune-vm/blocks_locator.hako" as BlocksLocatorBox
using "lang/src/vm/hakorune-vm/instrs_locator.hako" as InstrsLocatorBox
using "lang/src/vm/hakorune-vm/backward_object_scanner.hako" as BackwardObjectScannerBox
using "lang/src/vm/hakorune-vm/block_iterator.hako" as BlockIteratorBox
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/common/box_helpers.hako" as BoxHelpers
using selfhost.shared.common.string_helpers as StringHelpers
using selfhost.shared.common.box_helpers as BoxHelpers
static box MirIoBox {
// Internal: provider gate (yyjson)

View File

@ -1,7 +1,7 @@
// selfhost/shared/mir/mir_schema_box.hako
// MirSchemaBox — minimal MIR(JSON v0) constructors (P1 scope)
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using selfhost.shared.common.string_helpers as StringHelpers
static box MirSchemaBox {
_expect_map(val, context) {

View File

@ -1,6 +1,6 @@
// cfg_navigator.hako — CfgNavigatorBoxブロックの先頭/末尾シーク)
using "lang/src/shared/common/string_ops.hako" as StringOps
using selfhost.shared.common.string_ops as StringOps
using "lang/src/shared/json/json_cursor.hako" as JsonCursorBox
static box CfgNavigatorBox {

View File

@ -1,7 +1,7 @@
// mir_vm_m2.nyash — Ny製の最小MIR(JSON v0)実行器M2: const/binop/ret
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/common/string_ops.hako" as StringOps
using selfhost.shared.common.string_ops as StringOps
static box MirVmM2 {
_str_to_int(s) { return StringHelpers.to_i64(s) }

View File

@ -1,7 +1,7 @@
// mir_vm_min.hako — Ny製の最小MIR(JSON v0)実行器const/compare/copy/branch/jump/ret の最小)
using "lang/src/vm/boxes/op_handlers.hako" as OpHandlersBox
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/common/string_ops.hako" as StringOps
using selfhost.shared.common.string_ops as StringOps
using "lang/src/shared/json/utils/json_frag.hako" as JsonFragBox
using "lang/src/shared/json/json_cursor.hako" as JsonCursorBox
using "lang/src/vm/boxes/operator_box.hako" as OperatorBox

View File

@ -2,7 +2,7 @@
// Usage: import and call report(text) or analyze_dump_file(path)
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/common/string_ops.hako" as StringOps
using selfhost.shared.common.string_ops as StringOps
using "lang/src/shared/common/mini_vm_scan.hako" as MiniVmScan
static box SeamInspector {

View File

@ -1,5 +1,5 @@
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/common/string_ops.hako" as StringOps
using selfhost.shared.common.string_ops as StringOps
using "lang/src/shared/common/mini_vm_scan.hako" as MiniVmScan
static box Main {
// --- minimal helpers ---

View File

@ -2,7 +2,7 @@
using "lang/src/compiler/pipeline_v2/flow_entry.hako" as FlowEntryBox
using hakorune.vm.mir_min as MirVmMin
using "lang/src/shared/common/string_ops.hako" as StringOps
using selfhost.shared.common.string_ops as StringOps
static box FlowRunner {
_read_digits(text, pos) { local out = "" local i = pos loop(true) { local ch = text.substring(i, i+1) if ch == "" { break } if ch >= "0" && ch <= "9" { out = out + ch i = i + 1 } else { break } } return out }

View File

@ -1,7 +1,7 @@
// ArgsExtractorBox - Extract and load arguments from MirCall JSON
// Single Responsibility: Parse args array, load values from registers
using "lang/src/shared/common/string_ops.hako" as StringOps
using selfhost.shared.common.string_ops as StringOps
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/vm/hakorune-vm/value_manager.hako" as ValueManagerBox

View File

@ -2,7 +2,7 @@
// Handles: %dst = %lhs op_kind %rhs (Add/Sub/Mul/Div/Mod)
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/common/string_ops.hako" as StringOps
using selfhost.shared.common.string_ops as StringOps
using "lang/src/vm/boxes/result_box.hako" as Result
using "lang/src/vm/hakorune-vm/value_manager.hako" as ValueManagerBox
using "lang/src/vm/hakorune-vm/reg_guard.hako" as RegGuardBox

View File

@ -3,7 +3,7 @@
using "lang/src/shared/json/json_cursor.hako" as JsonCursorBox
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/common/string_ops.hako" as StringOps
using selfhost.shared.common.string_ops as StringOps
using "lang/src/vm/boxes/result_box.hako" as Result
using "lang/src/vm/hakorune-vm/function_locator.hako" as FunctionLocatorBox
using "lang/src/vm/hakorune-vm/blocks_locator.hako" as BlocksLocatorBox

View File

@ -1,7 +1,7 @@
// CalleeParserBox - Extract callee information from MirCall JSON
// Single Responsibility: Parse callee field and extract type/name
using "lang/src/shared/common/string_ops.hako" as StringOps
using selfhost.shared.common.string_ops as StringOps
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/vm/hakorune-vm/json_field_extractor.hako" as JsonFieldExtractor

View File

@ -3,7 +3,7 @@
// Note: Full closure calling via Callee::Value is Phase 4 Day 16
using "lang/src/vm/boxes/result_box.hako" as Result
using "lang/src/shared/common/string_ops.hako" as StringOps
using selfhost.shared.common.string_ops as StringOps
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/json/json_cursor.hako" as JsonCursorBox

View File

@ -2,7 +2,7 @@
// Handles: %dst = const value
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/common/string_ops.hako" as StringOps
using selfhost.shared.common.string_ops as StringOps
using "lang/src/vm/boxes/result_box.hako" as Result
using "lang/src/vm/hakorune-vm/value_manager.hako" as ValueManagerBox
using "lang/src/vm/hakorune-vm/json_field_extractor.hako" as JsonFieldExtractor

View File

@ -4,7 +4,7 @@
// Phase 1 Day 3: 制御フロー実装Branch/Jump/Phi- 箱化モジュール化
using "lang/src/shared/json/json_cursor.hako" as JsonCursorBox
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/common/string_ops.hako" as StringOps
using selfhost.shared.common.string_ops as StringOps
using "lang/src/vm/hakorune-vm/json_scan_guard.hako" as JsonScanGuardBox
using "lang/src/vm/boxes/result_box.hako" as Result
// Phase 1 Day 3: 箱化モジュール化

View File

@ -1,7 +1,7 @@
// InstructionDispatcherBox - Dispatch instructions to specific handlers
// Single Responsibility: Extract op field and route to correct handler
using "lang/src/shared/common/string_ops.hako" as StringOps
using selfhost.shared.common.string_ops as StringOps
using "lang/src/vm/boxes/result_box.hako" as Result
using "lang/src/vm/hakorune-vm/json_field_extractor.hako" as JsonFieldExtractor
using "lang/src/vm/hakorune-vm/value_manager.hako" as ValueManagerBox

View File

@ -2,7 +2,7 @@
// Centralizes JSON field parsing logic
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/common/string_ops.hako" as StringOps
using selfhost.shared.common.string_ops as StringOps
static box JsonFieldExtractor {
// Extract integer field from JSON

View File

@ -4,7 +4,7 @@
using "lang/src/vm/boxes/result_box.hako" as Result
using "lang/src/vm/hakorune-vm/value_manager.hako" as ValueManagerBox
using "lang/src/vm/hakorune-vm/json_field_extractor.hako" as JsonFieldExtractor
using "lang/src/shared/common/string_ops.hako" as StringOps
using selfhost.shared.common.string_ops as StringOps
using "lang/src/vm/gc/gc_runtime.hako" as GcRuntime
static box NewBoxHandlerBox {

View File

@ -3,7 +3,7 @@
using "lang/src/shared/json/json_cursor.hako" as JsonCursorBox
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/common/string_ops.hako" as StringOps
using selfhost.shared.common.string_ops as StringOps
using "lang/src/vm/boxes/result_box.hako" as Result
using "lang/src/vm/hakorune-vm/core_bridge_ops.hako" as CoreBridgeOps

View File

@ -2,7 +2,7 @@
// Strategy: 箱化モジュール化 - Ret/Jump/Branch を分離
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/common/string_ops.hako" as StringOps
using selfhost.shared.common.string_ops as StringOps
using "lang/src/vm/boxes/result_box.hako" as Result
using "lang/src/vm/hakorune-vm/instrs_locator.hako" as InstrsLocatorBox
using "lang/src/vm/hakorune-vm/backward_object_scanner.hako" as BackwardObjectScannerBox

View File

@ -2,7 +2,7 @@
// Handles: %dst = op_kind %operand (Neg/Not/BitNot)
using "lang/src/shared/common/string_helpers.hako" as StringHelpers
using "lang/src/shared/common/string_ops.hako" as StringOps
using selfhost.shared.common.string_ops as StringOps
using "lang/src/vm/boxes/result_box.hako" as Result
using "lang/src/vm/hakorune-vm/value_manager.hako" as ValueManagerBox
using "lang/src/vm/hakorune-vm/reg_guard.hako" as RegGuardBox

View File

@ -72,12 +72,52 @@ path = "lang/src/shared/common/string_helpers.hako"
"lang.compiler.stage1.emitter_box" = "lang/src/compiler/stage1/emitter_box.hako"
"lang.compiler.pipeline_v2.flow_entry" = "lang/src/compiler/pipeline_v2/flow_entry.hako"
"lang.compiler.pipeline_v2.pipeline" = "lang/src/compiler/pipeline_v2/pipeline.hako"
"lang.compiler.pipeline_v2.stage1_extract_flow" = "lang/src/compiler/pipeline_v2/stage1_extract_flow.hako"
"lang.compiler.pipeline_v2.emit_return_box" = "lang/src/compiler/pipeline_v2/emit_return_box.hako"
"lang.compiler.pipeline_v2.emit_binop_box" = "lang/src/compiler/pipeline_v2/emit_binop_box.hako"
"lang.compiler.pipeline_v2.emit_compare_box" = "lang/src/compiler/pipeline_v2/emit_compare_box.hako"
"lang.compiler.pipeline_v2.regex_flow" = "lang/src/compiler/pipeline_v2/regex_flow.hako"
"lang.compiler.pipeline_v2.emit_call_box" = "lang/src/compiler/pipeline_v2/emit_call_box.hako"
"lang.compiler.pipeline_v2.emit_method_box" = "lang/src/compiler/pipeline_v2/emit_method_box.hako"
"lang.compiler.pipeline_v2.emit_newbox_box" = "lang/src/compiler/pipeline_v2/emit_newbox_box.hako"
"lang.compiler.pipeline_v2.mir_call_box" = "lang/src/compiler/pipeline_v2/mir_call_box.hako"
"lang.compiler.pipeline_v2.compare_extract_box" = "lang/src/compiler/pipeline_v2/compare_extract_box.hako"
"lang.compiler.pipeline_v2.normalizer_box" = "lang/src/compiler/pipeline_v2/normalizer_box.hako"
"lang.compiler.pipeline_v2.map_helpers_box" = "lang/src/compiler/pipeline_v2/map_helpers_box.hako"
"lang.compiler.pipeline_v2.call_extract_box" = "lang/src/compiler/pipeline_v2/call_extract_box.hako"
"lang.compiler.pipeline_v2.method_extract_box" = "lang/src/compiler/pipeline_v2/method_extract_box.hako"
"lang.compiler.pipeline_v2.new_extract_box" = "lang/src/compiler/pipeline_v2/new_extract_box.hako"
"lang.compiler.pipeline_v2.using_resolver_box" = "lang/src/compiler/pipeline_v2/using_resolver_box.hako"
"lang.compiler.pipeline_v2.namespace_box" = "lang/src/compiler/pipeline_v2/namespace_box.hako"
"lang.compiler.pipeline_v2.signature_verifier_box" = "lang/src/compiler/pipeline_v2/signature_verifier_box.hako"
"lang.compiler.pipeline_v2.stage1_json_scanner_box" = "lang/src/compiler/pipeline_v2/stage1_json_scanner_box.hako"
"lang.compiler.pipeline_v2.stage1_name_args_normalizer_box" = "lang/src/compiler/pipeline_v2/stage1_name_args_normalizer_box.hako"
"lang.compiler.pipeline_v2.alias_preflight_box" = "lang/src/compiler/pipeline_v2/alias_preflight_box.hako"
"lang.compiler.pipeline_v2.stage1_args_parser_box" = "lang/src/compiler/pipeline_v2/stage1_args_parser_box.hako"
"lang.compiler.pipeline_v2.pipeline_helpers_box" = "lang/src/compiler/pipeline_v2/pipeline_helpers_box.hako"
"lang.compiler.pipeline_v2.backend_box" = "lang/src/compiler/pipeline_v2/backend_box.hako"
"lang.compiler.pipeline_v2.execution_pipeline_box" = "lang/src/compiler/pipeline_v2/execution_pipeline_box.hako"
"lang.compiler.pipeline_v2.mir_builder_box" = "lang/src/compiler/pipeline_v2/mir_builder_box.hako"
"lang.compiler.pipeline_v2.name_resolve_box" = "lang/src/compiler/pipeline_v2/name_resolve_box.hako"
"lang.compiler.pipeline_v2.pipeline_emit_box" = "lang/src/compiler/pipeline_v2/pipeline_emit_box.hako"
"lang.compiler.pipeline_v2.readonly_map_view" = "lang/src/compiler/pipeline_v2/readonly_map_view.hako"
"lang.compiler.pipeline_v2.stage1_int_args_extract_box" = "lang/src/compiler/pipeline_v2/stage1_int_args_extract_box.hako"
"lang.compiler.pipeline_v2.terminator_guard_box" = "lang/src/compiler/pipeline_v2/terminator_guard_box.hako"
"lang.compiler.pipeline_v2.emit_mir_flow" = "lang/src/compiler/pipeline_v2/emit_mir_flow.hako"
"lang.compiler.pipeline_v2.emit_mir_flow_map" = "lang/src/compiler/pipeline_v2/emit_mir_flow_map.hako"
"selfhost.shared.json.mir_v1_meta_inject_box" = "lang/src/shared/json/mir_v1_meta_inject_box.hako"
"selfhost.shared.json.json_inst_encode_box" = "lang/src/shared/json/json_inst_encode_box.hako"
"selfhost.shared.common.string_ops" = "lang/src/shared/common/string_ops.hako"
"lang.compiler.pipeline_v2.using_resolver" = "lang/src/compiler/pipeline_v2/using_resolver_box.hako"
"lang.compiler.builder.ssa.local" = "lang/src/compiler/builder/ssa/local.hako"
"lang.compiler.builder.ssa.localvar" = "lang/src/compiler/builder/ssa/local_ssa.hako"
"lang.compiler.builder.ssa.loop" = "lang/src/compiler/builder/ssa/loopssa.hako"
"lang.compiler.builder.ssa.cond_inserter" = "lang/src/compiler/builder/ssa/cond_inserter.hako"
"lang.compiler.builder.rewrite.special" = "lang/src/compiler/builder/rewrite/special.hako"
"lang.compiler.builder.rewrite.known" = "lang/src/compiler/builder/rewrite/known.hako"
"lang.compiler.pipeline_v2.localvar_ssa_box" = "lang/src/compiler/pipeline_v2/local_ssa_box.hako"
"lang.compiler.entry.compiler" = "lang/src/compiler/entry/compiler.hako"
"lang.compiler.entry.compiler_stageb" = "lang/src/compiler/entry/compiler_stageb.hako"
"lang.compiler.emit.mir_emitter_box" = "lang/src/compiler/emit/mir_emitter_box.hako"
"lang.compiler.emit.common.json_emit_box" = "lang/src/compiler/emit/common/json_emit_box.hako"
"lang.compiler.emit.common.mir_emit_box" = "lang/src/compiler/emit/common/mir_emit_box.hako"
"lang.compiler.emit.common.call_emit_box" = "lang/src/compiler/emit/common/call_emit_box.hako"
@ -95,13 +135,16 @@ path = "lang/src/shared/common/string_helpers.hako"
"selfhost.shared.common.mini_vm_binop" = "lang/src/shared/common/mini_vm_binop.hako"
"selfhost.shared.common.mini_vm_compare" = "lang/src/shared/common/mini_vm_compare.hako"
"selfhost.shared.common.string_helpers" = "lang/src/shared/common/string_helpers.hako"
"selfhost.shared.common.string_ops" = "lang/src/shared/common/string_ops.hako"
"selfhost.shared.common.box_helpers" = "lang/src/shared/common/box_helpers.hako"
"selfhost.shared.json.mir_builder_min" = "lang/src/shared/json/mir_builder_min.hako"
"selfhost.shared.json.mir_v1_adapter" = "lang/src/shared/json/mir_v1_adapter.hako"
"selfhost.shared.json.core.json_cursor" = "lang/src/shared/json/json_cursor.hako"
"selfhost.shared.json.core.string_scan" = "lang/src/shared/json/core/string_scan.hako"
"selfhost.shared.json.core.json_scan" = "lang/src/shared/json/core/json_scan.hako"
"selfhost.shared.json.utils.json_utils" = "lang/src/shared/json/json_utils.hako"
"selfhost.shared.json.stringify" = "lang/src/shared/json/stringify.hako"
"selfhost.shared.mir.schema" = "lang/src/shared/mir/mir_schema_box.hako"
"selfhost.shared.mir.loopform" = "lang/src/shared/mir/loop_form_box.hako"
"selfhost.shared.mir.builder" = "lang/src/shared/mir/block_builder_box.hako"
"selfhost.shared.mir.io" = "lang/src/shared/mir/mir_io_box.hako"
"selfhost.shared.mir.json_emit" = "lang/src/shared/mir/json_emit_box.hako"

View File

@ -111,7 +111,15 @@ impl NyashParser {
/// box宣言をパース: box Name { fields... methods... }
pub fn parse_box_declaration(&mut self) -> Result<ASTNode, ParseError> {
self.consume(TokenType::BOX)?;
// Accept either 'box' or 'flow' (flow is syntactic sugar for static box)
if !self.match_token(&TokenType::BOX) && !self.match_token(&TokenType::FLOW) {
return Err(ParseError::UnexpectedToken {
found: self.current_token().token_type.clone(),
expected: "'box' or 'flow'".to_string(),
line: self.current_token().line,
});
}
self.advance(); // consume BOX or FLOW
let (name, type_parameters, extends, implements) =
box_header::parse_header(self)?;

View File

@ -106,23 +106,12 @@ impl NyashParser {
self.current_token().token_type
);
}
if self.match_token(&TokenType::RBRACE) {
self.consume(TokenType::RBRACE)?;
} else if self.is_at_end() {
// Safety valve: if EOF is reached right after members (common at file end),
// accept as implicitly closed static box. This keeps behavior stable for
// well-formed sources and avoids false negatives on seam edges.
if std::env::var("NYASH_PARSER_TRACE_STATIC").ok().as_deref() == Some("1") {
eprintln!("[parser][static-box] accepting EOF as closing '}}' (at file end)");
}
} else {
// Still something else here; report a structured error
let line = self.current_token().line;
return Err(ParseError::UnexpectedToken {
expected: "RBRACE".to_string(),
found: self.current_token().token_type.clone(),
line,
});
// Consume the closing RBRACE of the static box
self.consume(TokenType::RBRACE)?;
if std::env::var("NYASH_PARSER_TRACE_STATIC").ok().as_deref() == Some("1") {
eprintln!("[parser][static-box] successfully closed static box '{}'", name);
}
// 🔥 Static初期化ブロックから依存関係を抽出

View File

@ -15,6 +15,7 @@ impl NyashParser {
pub(super) fn parse_declaration_statement(&mut self) -> Result<ASTNode, ParseError> {
match &self.current_token().token_type {
TokenType::BOX => self.parse_box_declaration(),
TokenType::FLOW => self.parse_box_declaration(), // flow is syntactic sugar for static box
TokenType::IMPORT => self.parse_import(),
TokenType::INTERFACE => self.parse_interface_box_declaration(),
TokenType::GLOBAL => self.parse_global_var(),

View File

@ -194,6 +194,7 @@ impl NyashParser {
// Declarations
TokenType::BOX
| TokenType::FLOW
| TokenType::IMPORT
| TokenType::INTERFACE
| TokenType::GLOBAL

View File

@ -19,3 +19,21 @@ pub fn post_run_exit_if_oob_strict_triggered() -> ! {
std::process::exit(0)
}
/// Apply a consistent child environment for selfhost/core wrapper executions.
/// - Forces JSON-only quiet pipe
/// - Disables plugins to avoid host-side side effects
/// - Disables file-based using resolution (namespace-first policy)
/// - Skips nyash.toml env injection to reduce drift
pub fn apply_core_wrapper_env(cmd: &mut std::process::Command) {
// Remove noisy or recursive toggles
cmd.env_remove("NYASH_USE_NY_COMPILER");
cmd.env_remove("NYASH_CLI_VERBOSE");
// Enforce quiet JSON capture
cmd.env("NYASH_JSON_ONLY", "1");
// Restrict environment to avoid plugin/using drift
cmd.env("NYASH_DISABLE_PLUGINS", "1");
cmd.env("NYASH_SKIP_TOML_ENV", "1");
cmd.env("NYASH_USING_AST", "0");
cmd.env("NYASH_ALLOW_USING_FILE", "0");
cmd.env("HAKO_ALLOW_USING_FILE", "0");
}

View File

@ -37,7 +37,7 @@ pub(crate) fn execute_file_with_backend(runner: &NyashRunner, filename: &str) {
return;
}
Err(e) => {
eprintln!("❌ Direct bridge parse error: {}", e);
eprintln!("❌ Direct bridge parse error in {}: {}", filename, e);
process::exit(1);
}
}
@ -56,7 +56,7 @@ pub(crate) fn execute_file_with_backend(runner: &NyashRunner, filename: &str) {
let ast = match NyashParser::parse_from_string(&code) {
Ok(ast) => ast,
Err(e) => {
eprintln!("❌ Parse error: {}", e);
eprintln!("❌ Parse error in {}: {}", filename, e);
process::exit(1);
}
};
@ -79,7 +79,7 @@ pub(crate) fn execute_file_with_backend(runner: &NyashRunner, filename: &str) {
};
let ast = match NyashParser::parse_from_string(&code) {
Ok(ast) => ast,
Err(e) => { eprintln!("❌ Parse error: {}", e); process::exit(1); }
Err(e) => { eprintln!("❌ Parse error in {}: {}", filename, e); process::exit(1); }
};
let expanded = if crate::r#macro::enabled() {
let a = crate::r#macro::maybe_expand_and_dump(&ast, false);

View File

@ -114,7 +114,7 @@ impl NyashRunner {
ast
}
Err(e) => {
eprintln!("❌ Parse error: {}", e);
eprintln!("❌ Parse error in {}: {}", filename, e);
process::exit(1);
}
};

View File

@ -72,7 +72,9 @@ pub fn collect_using_and_strip(
// can organize their modules via file paths.
if (prod || !crate::config::env::allow_using_file()) && !inside_pkg {
return Err(format!(
"using: file paths are disallowed in this profile. Add it to nyash.toml [using] (packages/aliases) and reference by name: {}",
"{}:{}: using: file paths are disallowed in this profile. Add it to nyash.toml [using] (packages/aliases) and reference by name: {}",
filename,
line_no,
target
));
}
@ -220,7 +222,9 @@ pub fn collect_using_and_strip(
}
} else {
return Err(format!(
"using: '{}' not found in nyash.toml [using]. Define a package or alias and use its name (prod profile)",
"{}:{}: using: '{}' not found in nyash.toml [using]. Define a package or alias and use its name (prod profile)",
filename,
line_no,
target
));
}
@ -311,7 +315,7 @@ pub fn collect_using_and_strip(
prelude_paths.push(path_str);
}
}
Err(e) => return Err(format!("using: {}", e)),
Err(e) => return Err(format!("{}:{}: using: {}", filename, line_no, e)),
}
}
continue;

View File

@ -17,6 +17,8 @@ pub fn run_ny_program_capture_json(
) -> Option<String> {
use std::process::Command;
let mut cmd = Command::new(exe);
// Apply consistent child env to avoid plugin/using drift
crate::runner::child_env::apply_core_wrapper_env(&mut cmd);
cmd.arg("--backend").arg("vm").arg(program);
for a in extra_args {
cmd.arg(a);

View File

@ -13,7 +13,7 @@ impl NyashRunner {
// Parse → AST
let ast = match NyashParser::parse_from_string(&code) {
Ok(ast) => ast,
Err(e) => { eprintln!("❌ Parse error: {}", e); process::exit(1); }
Err(e) => { eprintln!("❌ Parse error in {}: {}", filename, e); process::exit(1); }
};
let ast = crate::r#macro::maybe_expand_and_dump(&ast, false);
// AST → MIR

View File

@ -58,7 +58,7 @@ impl NyashRunner {
let main_ast = match NyashParser::parse_from_string(code_ref) {
Ok(ast) => ast,
Err(e) => {
eprintln!("❌ Parse error: {}", e);
eprintln!("❌ Parse error in {}: {}", filename, e);
process::exit(1);
}
};

View File

@ -21,7 +21,7 @@ impl NyashRunner {
let ast = match NyashParser::parse_from_string(&code) {
Ok(ast) => ast,
Err(e) => {
eprintln!("❌ Parse error: {}", e);
eprintln!("❌ Parse error in {}: {}", filename, e);
process::exit(1);
}
};

View File

@ -15,7 +15,7 @@ impl NyashRunner {
// Parse to AST
let ast = match NyashParser::parse_from_string(&code) {
Ok(ast) => ast,
Err(e) => { eprintln!("❌ Parse error: {}", e); process::exit(1); }
Err(e) => { eprintln!("❌ Parse error in {}: {}", filename, e); process::exit(1); }
};
let ast = crate::r#macro::maybe_expand_and_dump(&ast, false);

View File

@ -82,7 +82,7 @@ pub fn execute_pyvm_only(runner: &NyashRunner, filename: &str) {
let ast = match NyashParser::parse_from_string(&code) {
Ok(ast) => ast,
Err(e) => {
eprintln!("❌ Parse error: {}", e);
eprintln!("❌ Parse error in {}: {}", filename, e);
process::exit(1);
}
};

View File

@ -154,7 +154,8 @@ impl NyashRunner {
let main_ast = match NyashParser::parse_from_string(code_ref) {
Ok(ast) => ast,
Err(e) => {
eprintln!("❌ Parse error: {}", e);
eprintln!("❌ Parse error in main source ({}): {}",
cfg.file.as_ref().map(|s| s.as_str()).unwrap_or("<stdin>"), e);
if std::env::var("NYASH_STRIP_DEBUG").ok().as_deref() == Some("1") {
eprintln!("[vm-debug] Parse failed for main source");
eprintln!("[vm-debug] Line 15-25 of source:");

View File

@ -58,7 +58,7 @@ impl NyashRunner {
let main_ast = match NyashParser::parse_from_string(&code2) {
Ok(ast) => ast,
Err(e) => {
eprintln!("❌ Parse error: {}", e);
eprintln!("❌ Parse error in {}: {}", filename, e);
process::exit(1);
}
};

View File

@ -17,7 +17,7 @@ impl NyashRunner {
// Parse to AST
let ast = match NyashParser::parse_from_string(&code) {
Ok(ast) => ast,
Err(e) => { eprintln!("❌ Parse error: {}", e); process::exit(1); }
Err(e) => { eprintln!("❌ Parse error in {}: {}", filename, e); process::exit(1); }
};
let ast = crate::r#macro::maybe_expand_and_dump(&ast, false);

View File

@ -164,8 +164,18 @@ impl NyashRunner {
parser_prog,
timeout_ms,
&extra,
&["NYASH_USE_NY_COMPILER", "NYASH_CLI_VERBOSE"],
&[("NYASH_JSON_ONLY", "1")],
&[
"NYASH_USE_NY_COMPILER",
"NYASH_CLI_VERBOSE",
],
&[
("NYASH_JSON_ONLY", "1"),
("NYASH_DISABLE_PLUGINS", "1"),
("NYASH_SKIP_TOML_ENV", "1"),
("NYASH_USING_AST", "0"),
("NYASH_ALLOW_USING_FILE", "0"),
("HAKO_ALLOW_USING_FILE", "0"),
],
) {
match json::parse_json_v0_line(&line) {
Ok(module) => {
@ -360,9 +370,7 @@ impl NyashRunner {
.unwrap_or_else(|_| std::path::PathBuf::from("target/release/nyash"));
let mut cmd = std::process::Command::new(exe);
cmd.arg("--backend").arg("vm").arg(&inline_path);
cmd.env_remove("NYASH_USE_NY_COMPILER");
cmd.env_remove("NYASH_CLI_VERBOSE");
cmd.env("NYASH_JSON_ONLY", "1");
crate::runner::child_env::apply_core_wrapper_env(&mut cmd);
let timeout_ms: u64 = std::env::var("NYASH_NY_COMPILER_TIMEOUT_MS")
.ok()
.and_then(|s| s.parse().ok())

View File

@ -40,6 +40,7 @@ pub enum TokenType {
CLEANUP,
THROW,
LOCAL,
FLOW,
STATIC,
OUTBOX,
NOT,

View File

@ -46,6 +46,7 @@ impl NyashTokenizer {
"cleanup" => TokenType::CLEANUP,
"throw" => TokenType::THROW,
"local" => TokenType::LOCAL,
"flow" => TokenType::FLOW,
"static" => TokenType::STATIC,
"outbox" => TokenType::OUTBOX,
"not" => TokenType::NOT,
@ -61,12 +62,13 @@ impl NyashTokenizer {
_ => TokenType::IDENTIFIER(identifier.clone()),
};
// Stage-3 gate: LOCAL/TRY/CATCH/THROW require NYASH_PARSER_STAGE3=1
// Stage-3 gate: LOCAL/FLOW/TRY/CATCH/THROW require NYASH_PARSER_STAGE3=1
let stage3_enabled = crate::config::env::parser_stage3();
if !stage3_enabled {
let is_stage3 = matches!(
tok,
TokenType::LOCAL
| TokenType::FLOW
| TokenType::TRY
| TokenType::CATCH
| TokenType::THROW
@ -83,6 +85,7 @@ impl NyashTokenizer {
let is_stage3 = matches!(
tok,
TokenType::LOCAL
| TokenType::FLOW
| TokenType::TRY
| TokenType::CATCH
| TokenType::THROW

Some files were not shown because too many files have changed in this diff Show More