feat: nyash.toml SSOT + using AST統合完了(12時間の戦い)
- nyash.tomlを唯一の真実(SSOT)として依存管理確立 - dev/ci/prodプロファイルによる段階的厳格化実装 - AST結合で宣言/式の曖昧性を根本解決 - Fail-Fast原則をCLAUDE.md/AGENTS.mdに明文化 - VM fallbackでもASTベース using有効化(NYASH_USING_AST=1) - 静的メソッドの is_static=true 修正で解決安定化 - STATICブレークハック既定OFF化で堅牢性向上 🎉 usingシステム完全体への道筋確立!JSONライブラリ・Nyash VM開発が可能に Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -12,23 +12,79 @@ impl NyashRunner {
|
||||
Ok(s) => s,
|
||||
Err(e) => { eprintln!("❌ Error reading file {}: {}", filename, e); process::exit(1); }
|
||||
};
|
||||
// Using preprocessing (strip + autoload)
|
||||
// Using preprocessing (legacy inline or AST-prelude merge when NYASH_USING_AST=1)
|
||||
let mut code2 = code;
|
||||
let use_ast_prelude = crate::config::env::enable_using()
|
||||
&& std::env::var("NYASH_USING_AST").ok().as_deref() == Some("1");
|
||||
let mut prelude_asts: Vec<nyash_rust::ast::ASTNode> = Vec::new();
|
||||
if crate::config::env::enable_using() {
|
||||
match crate::runner::modes::common_util::resolve::strip_using_and_register(self, &code2, filename) {
|
||||
Ok(s) => { code2 = s; }
|
||||
Err(e) => { eprintln!("❌ {}", e); process::exit(1); }
|
||||
if use_ast_prelude {
|
||||
match crate::runner::modes::common_util::resolve::resolve_prelude_paths_profiled(self, &code2, filename) {
|
||||
Ok((clean, paths)) => {
|
||||
code2 = clean;
|
||||
for p in paths {
|
||||
match std::fs::read_to_string(&p) {
|
||||
Ok(src) => match NyashParser::parse_from_string(&src) {
|
||||
Ok(ast) => prelude_asts.push(ast),
|
||||
Err(e) => { eprintln!("❌ Parse error in using prelude {}: {}", p, e); process::exit(1); }
|
||||
},
|
||||
Err(e) => { eprintln!("❌ Error reading using prelude {}: {}", p, e); process::exit(1); }
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => { eprintln!("❌ {}", e); process::exit(1); }
|
||||
}
|
||||
} else {
|
||||
match crate::runner::modes::common_util::resolve::strip_using_and_register(self, &code2, filename) {
|
||||
Ok(s) => { code2 = s; }
|
||||
Err(e) => { eprintln!("❌ {}", e); process::exit(1); }
|
||||
}
|
||||
}
|
||||
}
|
||||
// Dev sugar pre-expand: @name = expr → local name = expr
|
||||
code2 = crate::runner::modes::common_util::resolve::preexpand_at_local(&code2);
|
||||
|
||||
// Parse -> expand macros -> compile MIR
|
||||
let ast = match NyashParser::parse_from_string(&code2) {
|
||||
// Parse main code
|
||||
let main_ast = match NyashParser::parse_from_string(&code2) {
|
||||
Ok(ast) => ast,
|
||||
Err(e) => { eprintln!("❌ Parse error: {}", e); process::exit(1); }
|
||||
};
|
||||
let ast = crate::r#macro::maybe_expand_and_dump(&ast, false);
|
||||
// When using AST prelude mode, combine prelude ASTs + main AST into one Program before macro expansion
|
||||
let ast_combined = if use_ast_prelude && !prelude_asts.is_empty() {
|
||||
use nyash_rust::ast::ASTNode;
|
||||
let mut combined: Vec<ASTNode> = Vec::new();
|
||||
for a in prelude_asts {
|
||||
if let ASTNode::Program { statements, .. } = a { combined.extend(statements); }
|
||||
}
|
||||
if let ASTNode::Program { statements, .. } = main_ast.clone() {
|
||||
combined.extend(statements);
|
||||
}
|
||||
ASTNode::Program { statements: combined, span: nyash_rust::ast::Span::unknown() }
|
||||
} else { main_ast };
|
||||
// Optional: dump AST statement kinds for quick diagnostics
|
||||
if std::env::var("NYASH_AST_DUMP").ok().as_deref() == Some("1") {
|
||||
use nyash_rust::ast::ASTNode;
|
||||
eprintln!("[ast] dump start (vm-fallback)");
|
||||
if let ASTNode::Program { statements, .. } = &ast_combined {
|
||||
for (i, st) in statements.iter().enumerate().take(50) {
|
||||
let kind = match st {
|
||||
ASTNode::BoxDeclaration { is_static, name, .. } => {
|
||||
if *is_static { format!("StaticBox({})", name) } else { format!("Box({})", name) }
|
||||
}
|
||||
ASTNode::FunctionDeclaration { name, .. } => format!("FuncDecl({})", name),
|
||||
ASTNode::FunctionCall { name, .. } => format!("FuncCall({})", name),
|
||||
ASTNode::MethodCall { method, .. } => format!("MethodCall({})", method),
|
||||
ASTNode::ScopeBox { .. } => "ScopeBox".to_string(),
|
||||
ASTNode::ImportStatement { path, .. } => format!("Import({})", path),
|
||||
ASTNode::UsingStatement { namespace_name, .. } => format!("Using({})", namespace_name),
|
||||
_ => format!("{:?}", st),
|
||||
};
|
||||
eprintln!("[ast] {}: {}", i, kind);
|
||||
}
|
||||
}
|
||||
eprintln!("[ast] dump end");
|
||||
}
|
||||
let ast = crate::r#macro::maybe_expand_and_dump(&ast_combined, false);
|
||||
let mut compiler = MirCompiler::with_options(!self.config.no_optimize);
|
||||
let compile = match compiler.compile(ast) {
|
||||
Ok(c) => c,
|
||||
@ -44,6 +100,12 @@ impl NyashRunner {
|
||||
|
||||
// Execute via MIR interpreter
|
||||
let mut vm = MirInterpreter::new();
|
||||
if std::env::var("NYASH_DUMP_FUNCS").ok().as_deref() == Some("1") {
|
||||
eprintln!("[vm] functions available:");
|
||||
for k in module_vm.functions.keys() {
|
||||
eprintln!(" - {}", k);
|
||||
}
|
||||
}
|
||||
match vm.execute_module(&module_vm) {
|
||||
Ok(_ret) => { /* interpreter already prints via println/console in program */ }
|
||||
Err(e) => {
|
||||
|
||||
Reference in New Issue
Block a user