🚀 Start Phase 15.3: Nyash compiler MVP implementation
Major milestone: - Set up apps/selfhost-compiler/ directory structure - Implement basic Nyash compiler in Nyash (CompilerBox) - Stage-1: Basic arithmetic parser (int/string/+/-/*/括弧/return) - JSON v0 output compatible with --ny-parser-pipe - Runner integration with NYASH_USE_NY_COMPILER=1 flag - Comprehensive smoke tests for PHI/Bridge/Stage-2 Technical updates: - Updated CLAUDE.md with Phase 15.3 status and MIR14 details - Statement separation policy: newline-based with minimal ASI - Fixed runaway ny-parser-pipe processes (CPU 94.9%) - Clarified MIR14 as canonical instruction set (not 13/18) - LoopForm strategy: PHI auto-generation during reverse lowering Collaborative development: - ChatGPT5 implementing compiler skeleton - Codex provided LoopForm PHI generation guidance - Claude maintaining documentation and coordination 🎉 セルフホスティングの歴史的一歩!自分自身をコンパイルする日が近いにゃ! Co-Authored-By: ChatGPT <noreply@openai.com>
This commit is contained in:
@ -242,10 +242,23 @@ fn lower_expr_with_vars(
|
||||
match e {
|
||||
ExprV0::Var { name } => {
|
||||
if let Some(&vid) = vars.get(name) {
|
||||
Ok((vid, cur_bb))
|
||||
} else {
|
||||
Err(format!("undefined variable: {}", name))
|
||||
return Ok((vid, cur_bb));
|
||||
}
|
||||
if name == "me" {
|
||||
// Optional gate: allow a dummy 'me' instance for Stage-2 JSON smoke
|
||||
if std::env::var("NYASH_BRIDGE_ME_DUMMY").ok().as_deref() == Some("1") {
|
||||
let class = std::env::var("NYASH_BRIDGE_ME_CLASS").unwrap_or_else(|_| "Main".to_string());
|
||||
let dst = f.next_value_id();
|
||||
if let Some(bb) = f.get_block_mut(cur_bb) {
|
||||
bb.add_instruction(MirInstruction::NewBox { dst, box_type: class, args: vec![] });
|
||||
}
|
||||
vars.insert("me".to_string(), dst);
|
||||
return Ok((dst, cur_bb));
|
||||
} else {
|
||||
return Err("undefined 'me' outside box context (set NYASH_BRIDGE_ME_DUMMY=1 to inject placeholder)".into());
|
||||
}
|
||||
}
|
||||
Err(format!("undefined variable: {}", name))
|
||||
}
|
||||
ExprV0::Call { name, args } => {
|
||||
// Lower args
|
||||
|
||||
@ -36,6 +36,14 @@ fn suggest_in_base(base: &str, leaf: &str, out: &mut Vec<String>) {
|
||||
impl NyashRunner {
|
||||
/// File-mode dispatcher (thin wrapper around backend/mode selection)
|
||||
pub(crate) fn run_file(&self, filename: &str) {
|
||||
// Phase-15.3: Ny compiler MVP (Ny -> JSON v0) behind env gate
|
||||
if std::env::var("NYASH_USE_NY_COMPILER").ok().as_deref() == Some("1") {
|
||||
if self.try_run_ny_compiler_pipeline(filename) {
|
||||
return;
|
||||
} else if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
|
||||
eprintln!("[ny-compiler] fallback to default path (MVP unavailable for this input)");
|
||||
}
|
||||
}
|
||||
// Direct v0 bridge when requested via CLI/env
|
||||
let use_ny_parser = self.config.parser_ny || std::env::var("NYASH_USE_NY_PARSER").ok().as_deref() == Some("1");
|
||||
if use_ny_parser {
|
||||
@ -141,6 +149,84 @@ impl NyashRunner {
|
||||
}
|
||||
}
|
||||
|
||||
/// Phase-15.3: Attempt Ny compiler pipeline (Ny -> JSON v0 via Ny program), then execute MIR
|
||||
fn try_run_ny_compiler_pipeline(&self, filename: &str) -> bool {
|
||||
use std::io::Write;
|
||||
// Read input source
|
||||
let code = match fs::read_to_string(filename) {
|
||||
Ok(c) => c,
|
||||
Err(e) => { eprintln!("[ny-compiler] read error: {}", e); return false; }
|
||||
};
|
||||
// Write to tmp/ny_parser_input.ny (as expected by Ny parser v0)
|
||||
let tmp_dir = std::path::Path::new("tmp");
|
||||
if let Err(e) = std::fs::create_dir_all(tmp_dir) {
|
||||
eprintln!("[ny-compiler] mkdir tmp failed: {}", e);
|
||||
return false;
|
||||
}
|
||||
let tmp_path = tmp_dir.join("ny_parser_input.ny");
|
||||
match std::fs::File::create(&tmp_path) {
|
||||
Ok(mut f) => {
|
||||
if let Err(e) = f.write_all(code.as_bytes()) {
|
||||
eprintln!("[ny-compiler] write tmp failed: {}", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Err(e) => { eprintln!("[ny-compiler] open tmp failed: {}", e); return false; }
|
||||
}
|
||||
// Locate current exe to invoke Ny VM for the Ny parser program
|
||||
let exe = match std::env::current_exe() {
|
||||
Ok(p) => p,
|
||||
Err(e) => { eprintln!("[ny-compiler] current_exe failed: {}", e); return false; }
|
||||
};
|
||||
// Prefer new selfhost-compiler entry; fallback to legacy ny_parser_v0
|
||||
let cand_new = std::path::Path::new("apps/selfhost-compiler/compiler.nyash");
|
||||
let cand_old = std::path::Path::new("apps/selfhost/parser/ny_parser_v0/main.nyash");
|
||||
let parser_prog = if cand_new.exists() { cand_new } else { cand_old };
|
||||
if !parser_prog.exists() { eprintln!("[ny-compiler] compiler program not found: {}", parser_prog.display()); return false; }
|
||||
let mut cmd = std::process::Command::new(exe);
|
||||
cmd.arg("--backend").arg("vm").arg(parser_prog);
|
||||
// Propagate minimal env; disable plugins to reduce noise
|
||||
cmd.env_remove("NYASH_USE_NY_COMPILER");
|
||||
// Suppress parent runner's result printing in child
|
||||
cmd.env("NYASH_JSON_ONLY", "1");
|
||||
let out = match cmd.output() {
|
||||
Ok(o) => o,
|
||||
Err(e) => { eprintln!("[ny-compiler] spawn failed: {}", e); return false; }
|
||||
};
|
||||
if !out.status.success() {
|
||||
if let Ok(s) = String::from_utf8(out.stderr) { eprintln!("[ny-compiler] parser stderr:\n{}", s); }
|
||||
return false;
|
||||
}
|
||||
let stdout = match String::from_utf8(out.stdout) { Ok(s) => s, Err(_) => String::new() };
|
||||
let mut json_line = String::new();
|
||||
for line in stdout.lines() {
|
||||
let t = line.trim();
|
||||
if t.starts_with('{') && t.contains("\"version\":0") { json_line = t.to_string(); break; }
|
||||
}
|
||||
if json_line.is_empty() {
|
||||
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
|
||||
let head: String = stdout.chars().take(200).collect();
|
||||
eprintln!("[ny-compiler] JSON not found in child stdout (head): {}", head.replace('\n', "\\n"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Parse JSON v0 → MIR module
|
||||
match json_v0_bridge::parse_json_v0_to_module(&json_line) {
|
||||
Ok(module) => {
|
||||
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
|
||||
println!("🚀 Ny compiler MVP (ny→json_v0) path ON");
|
||||
}
|
||||
json_v0_bridge::maybe_dump_mir(&module);
|
||||
self.execute_mir_module(&module);
|
||||
true
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("[ny-compiler] JSON parse failed: {}", e);
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Execute Nyash file with interpreter (common helper)
|
||||
pub(crate) fn execute_nyash_file(&self, filename: &str) {
|
||||
let quiet_pipe = std::env::var("NYASH_JSON_ONLY").ok().as_deref() == Some("1");
|
||||
|
||||
Reference in New Issue
Block a user