chore: Phase 25.1 完了 - LoopForm v2/Stage1 CLI/環境変数削減 + Phase 26-D からの変更
Phase 25.1 完了成果: - ✅ LoopForm v2 テスト・ドキュメント・コメント完備 - 4ケース(A/B/C/D)完全テストカバレッジ - 最小再現ケース作成(SSAバグ調査用) - SSOT文書作成(loopform_ssot.md) - 全ソースに [LoopForm] コメントタグ追加 - ✅ Stage-1 CLI デバッグ環境構築 - stage1_cli.hako 実装 - stage1_bridge.rs ブリッジ実装 - デバッグツール作成(stage1_debug.sh/stage1_minimal.sh) - アーキテクチャ改善提案文書 - ✅ 環境変数削減計画策定 - 25変数の完全調査・分類 - 6段階削減ロードマップ(25→5、80%削減) - 即時削除可能変数特定(NYASH_CONFIG/NYASH_DEBUG) Phase 26-D からの累積変更: - PHI実装改善(ExitPhiBuilder/HeaderPhiBuilder等) - MIRビルダーリファクタリング - 型伝播・最適化パス改善 - その他約300ファイルの累積変更 🎯 技術的成果: - SSAバグ根本原因特定(条件分岐内loop変数変更) - Region+next_iパターン適用完了(UsingCollectorBox等) - LoopFormパターン文書化・テスト化完了 - セルフホスティング基盤強化 Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: ChatGPT <noreply@openai.com> Co-Authored-By: Task Assistant <task@anthropic.com>
This commit is contained in:
@ -35,16 +35,12 @@ impl NyashRunner {
|
||||
// - merge_prelude_text で text-merge(.hako は AST parse しない)
|
||||
let mut code2 = if crate::config::env::enable_using() {
|
||||
match crate::runner::modes::common_util::resolve::resolve_prelude_paths_profiled(
|
||||
self,
|
||||
&code,
|
||||
filename,
|
||||
self, &code, filename,
|
||||
) {
|
||||
Ok((_, prelude_paths)) => {
|
||||
if !prelude_paths.is_empty() {
|
||||
match crate::runner::modes::common_util::resolve::merge_prelude_text(
|
||||
self,
|
||||
&code,
|
||||
filename,
|
||||
self, &code, filename,
|
||||
) {
|
||||
Ok(merged) => {
|
||||
if trace {
|
||||
@ -90,8 +86,9 @@ impl NyashRunner {
|
||||
code2 = crate::runner::modes::common_util::hako::strip_local_decl(&code2);
|
||||
}
|
||||
|
||||
if trace && (std::env::var("NYASH_PARSER_STAGE3").ok() == Some("1".into())
|
||||
|| std::env::var("HAKO_PARSER_STAGE3").ok() == Some("1".into()))
|
||||
if trace
|
||||
&& (std::env::var("NYASH_PARSER_STAGE3").ok() == Some("1".into())
|
||||
|| std::env::var("HAKO_PARSER_STAGE3").ok() == Some("1".into()))
|
||||
{
|
||||
eprintln!("[vm-fallback] Stage-3: enabled (env) for {}", filename);
|
||||
}
|
||||
@ -102,7 +99,9 @@ impl NyashRunner {
|
||||
let on = crate::runner::modes::common_util::hako::fail_fast_on_hako();
|
||||
if on {
|
||||
let s = code2.as_str();
|
||||
let hako_like = s.contains("static box ") || s.contains("using selfhost.") || s.contains("using hakorune.");
|
||||
let hako_like = s.contains("static box ")
|
||||
|| s.contains("using selfhost.")
|
||||
|| s.contains("using hakorune.");
|
||||
if hako_like {
|
||||
eprintln!(
|
||||
"❌ Hako-like source detected in Nyash VM path. Use Hakorune VM (v1 dispatcher) or Core/LLVM for MIR.\n hint: set HAKO_VERIFY_PRIMARY=hakovm in verify path"
|
||||
@ -116,7 +115,11 @@ impl NyashRunner {
|
||||
let main_ast = match NyashParser::parse_from_string(&code2) {
|
||||
Ok(ast) => ast,
|
||||
Err(e) => {
|
||||
eprintln!("❌ Parse error in {}: {}", filename, e);
|
||||
crate::runner::modes::common_util::diag::print_parse_error_with_context(
|
||||
filename,
|
||||
&code2,
|
||||
&e,
|
||||
);
|
||||
process::exit(1);
|
||||
}
|
||||
};
|
||||
@ -186,7 +189,8 @@ impl NyashRunner {
|
||||
type_parameters,
|
||||
is_static,
|
||||
..
|
||||
} = st {
|
||||
} = st
|
||||
{
|
||||
if *is_static {
|
||||
static_names.push(name.clone());
|
||||
continue; // modules/static boxes are not user-instantiable directly
|
||||
@ -308,7 +312,9 @@ impl NyashRunner {
|
||||
if let Err(errors) = verifier.verify_function(func) {
|
||||
if !errors.is_empty() {
|
||||
eprintln!("[vm-verify] function: {}", name);
|
||||
for er in errors { eprintln!(" • {}", er); }
|
||||
for er in errors {
|
||||
eprintln!(" • {}", er);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -321,13 +327,17 @@ impl NyashRunner {
|
||||
}
|
||||
match vm.execute_module(&module_vm) {
|
||||
Ok(ret) => {
|
||||
use crate::box_trait::{IntegerBox, BoolBox};
|
||||
use crate::box_trait::{BoolBox, IntegerBox};
|
||||
|
||||
// Extract exit code from return value
|
||||
let exit_code = if let Some(ib) = ret.as_any().downcast_ref::<IntegerBox>() {
|
||||
ib.value as i32
|
||||
} else if let Some(bb) = ret.as_any().downcast_ref::<BoolBox>() {
|
||||
if bb.value { 1 } else { 0 }
|
||||
if bb.value {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
} else {
|
||||
// For non-integer/bool returns, default to 0 (success)
|
||||
0
|
||||
@ -355,21 +365,54 @@ impl NyashRunner {
|
||||
instance_v2::InstanceBox,
|
||||
mir::MirCompiler,
|
||||
};
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::process;
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
// Macro expand (if enabled)
|
||||
let ast = crate::r#macro::maybe_expand_and_dump(&ast, false);
|
||||
// Minimal user-defined Box support (inline factory)
|
||||
{
|
||||
use nyash_rust::ast::ASTNode;
|
||||
let mut nonstatic_decls: std::collections::HashMap<String, CoreBoxDecl> = std::collections::HashMap::new();
|
||||
let mut nonstatic_decls: std::collections::HashMap<String, CoreBoxDecl> =
|
||||
std::collections::HashMap::new();
|
||||
let mut static_names: Vec<String> = Vec::new();
|
||||
if let ASTNode::Program { statements, .. } = &ast {
|
||||
for st in statements {
|
||||
if let ASTNode::BoxDeclaration { name, fields, public_fields, private_fields, methods, constructors, init_fields, weak_fields, is_interface, extends, implements, type_parameters, is_static, .. } = st {
|
||||
if *is_static { static_names.push(name.clone()); continue; }
|
||||
let decl = CoreBoxDecl { name: name.clone(), fields: fields.clone(), public_fields: public_fields.clone(), private_fields: private_fields.clone(), methods: methods.clone(), constructors: constructors.clone(), init_fields: init_fields.clone(), weak_fields: weak_fields.clone(), is_interface: *is_interface, extends: extends.clone(), implements: implements.clone(), type_parameters: type_parameters.clone() };
|
||||
if let ASTNode::BoxDeclaration {
|
||||
name,
|
||||
fields,
|
||||
public_fields,
|
||||
private_fields,
|
||||
methods,
|
||||
constructors,
|
||||
init_fields,
|
||||
weak_fields,
|
||||
is_interface,
|
||||
extends,
|
||||
implements,
|
||||
type_parameters,
|
||||
is_static,
|
||||
..
|
||||
} = st
|
||||
{
|
||||
if *is_static {
|
||||
static_names.push(name.clone());
|
||||
continue;
|
||||
}
|
||||
let decl = CoreBoxDecl {
|
||||
name: name.clone(),
|
||||
fields: fields.clone(),
|
||||
public_fields: public_fields.clone(),
|
||||
private_fields: private_fields.clone(),
|
||||
methods: methods.clone(),
|
||||
constructors: constructors.clone(),
|
||||
init_fields: init_fields.clone(),
|
||||
weak_fields: weak_fields.clone(),
|
||||
is_interface: *is_interface,
|
||||
extends: extends.clone(),
|
||||
implements: implements.clone(),
|
||||
type_parameters: type_parameters.clone(),
|
||||
};
|
||||
nonstatic_decls.insert(name.clone(), decl);
|
||||
}
|
||||
}
|
||||
@ -390,7 +433,8 @@ impl NyashRunner {
|
||||
&self,
|
||||
name: &str,
|
||||
args: &[Box<dyn crate::box_trait::NyashBox>],
|
||||
) -> Result<Box<dyn crate::box_trait::NyashBox>, RuntimeError> {
|
||||
) -> Result<Box<dyn crate::box_trait::NyashBox>, RuntimeError>
|
||||
{
|
||||
let opt = { self.decls.read().unwrap().get(name).cloned() };
|
||||
let decl = match opt {
|
||||
Some(d) => d,
|
||||
@ -409,8 +453,12 @@ impl NyashRunner {
|
||||
Ok(Box::new(inst))
|
||||
}
|
||||
|
||||
fn box_types(&self) -> Vec<&str> { vec![] }
|
||||
fn is_available(&self) -> bool { true }
|
||||
fn box_types(&self) -> Vec<&str> {
|
||||
vec![]
|
||||
}
|
||||
fn is_available(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn factory_type(&self) -> crate::box_factory::FactoryType {
|
||||
crate::box_factory::FactoryType::User
|
||||
}
|
||||
@ -425,7 +473,10 @@ impl NyashRunner {
|
||||
let mut compiler = MirCompiler::with_options(!self.config.no_optimize);
|
||||
let module = match compiler.compile(ast) {
|
||||
Ok(r) => r.module,
|
||||
Err(e) => { eprintln!("❌ MIR compilation error: {}", e); process::exit(1); }
|
||||
Err(e) => {
|
||||
eprintln!("❌ MIR compilation error: {}", e);
|
||||
process::exit(1);
|
||||
}
|
||||
};
|
||||
let mut interp = MirInterpreter::new();
|
||||
match interp.execute_module(&module) {
|
||||
@ -434,7 +485,11 @@ impl NyashRunner {
|
||||
let rc = if let Some(ib) = result.as_any().downcast_ref::<IntegerBox>() {
|
||||
ib.value as i32
|
||||
} else if let Some(bb) = result.as_any().downcast_ref::<BoolBox>() {
|
||||
if bb.value { 1 } else { 0 }
|
||||
if bb.value {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user