Phase 25.1b: Step2完了(FuncBodyBasicLowerBox導入)

Step2実装内容:
- FuncBodyBasicLowerBox導入(defs専用下請けモジュール)
- _try_lower_local_if_return実装(Local+単純if)
- _inline_local_ints実装(軽い正規化)
- minimal lowers統合(Return/BinOp/IfCompare/MethodArray系)

Fail-Fast体制確立:
- MirBuilderBox: defs_onlyでも必ずタグ出力
- [builder/selfhost-first:unsupported:defs_only]
- [builder/selfhost-first:unsupported:no_match]

Phase構造整備:
- Phase 25.1b README新設(Step0-3計画)
- Phase 25.2b README新設(次期計画)
- UsingResolverBox追加(using system対応準備)

スモークテスト:
- stage1_launcher_program_to_mir_canary_vm.sh追加

Next: Step3 LoopForm対応

🤖 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-15 22:32:13 +09:00
parent 6856922374
commit 7ca7f646de
31 changed files with 1670 additions and 323 deletions

View File

@ -106,6 +106,9 @@ pub enum ParseError {
#[error("Invalid statement at line {line}")]
InvalidStatement { line: usize },
#[error("Unsupported identifier '{name}' at line {line}")]
UnsupportedIdentifier { name: String, line: usize },
#[error("Circular dependency detected between static boxes: {cycle}")]
CircularDependency { cycle: String },
@ -215,6 +218,17 @@ impl NyashParser {
let mut tokenizer = crate::tokenizer::NyashTokenizer::new(pre);
let tokens = tokenizer.tokenize()?;
for tok in &tokens {
if let TokenType::IDENTIFIER(name) = &tok.token_type {
if name == "self" {
return Err(ParseError::UnsupportedIdentifier {
name: name.clone(),
line: tok.line,
});
}
}
}
let mut parser = Self::new(tokens);
parser.debug_fuel = fuel;
let result = parser.parse();

View File

@ -86,6 +86,7 @@ pub(super) enum ExprV0 {
Bool {
value: bool,
},
Null,
Binary {
op: String,
lhs: Box<ExprV0>,

View File

@ -65,6 +65,21 @@ impl<'a> VarScope for MapVars<'a> {
self.vars.insert(name.to_string(), dst);
return Ok(Some(dst));
}
// Phase 25.1a: Treat `hostbridge` as a well-known global for bridge lowering.
// The actual extern dispatch is handled at runtime; here we only need a stable
// placeholder value so that Program(JSON) containing hostbridge.extern_invoke(...)
// can be lowered without "undefined variable" errors.
if name == "hostbridge" {
let dst = f.next_value_id();
if let Some(bb) = f.get_block_mut(cur_bb) {
bb.add_instruction(MirInstruction::Const {
dst,
value: ConstValue::String("hostbridge".into()),
});
}
self.vars.insert(name.to_string(), dst);
return Ok(Some(dst));
}
if name == "me" {
if env.allow_me_dummy {
let dst = f.next_value_id();
@ -163,6 +178,16 @@ pub(super) fn lower_expr_with_scope<S: VarScope>(
}
Ok((dst, cur_bb))
}
ExprV0::Null => {
let dst = f.next_value_id();
if let Some(bb) = f.get_block_mut(cur_bb) {
bb.add_instruction(MirInstruction::Const {
dst,
value: ConstValue::Null,
});
}
Ok((dst, cur_bb))
}
ExprV0::Binary { op, lhs, rhs } => {
let (l, cur_after_l) = lower_expr_with_scope(env, f, cur_bb, lhs, vars)?;
let (r, cur_after_r) = lower_expr_with_scope(env, f, cur_after_l, rhs, vars)?;

View File

@ -155,6 +155,34 @@ impl NyashRunner {
crate::runner::modes::common_util::hako::strip_local_decl(&code_final);
}
// Optional: dump merged Hako source after using/prelude merge and Hako normalization.
// Guarded by env; defaultはOFFPhase 25.1a selfhost builder デバッグ用)。
if std::env::var("NYASH_VM_DUMP_MERGED_HAKO")
.ok()
.as_deref()
== Some("1")
{
let default_path = {
let mut tmp = std::env::temp_dir();
tmp.push("nyash_merged_vm.hako");
tmp
};
let path = std::env::var("NYASH_VM_DUMP_MERGED_HAKO_PATH")
.ok()
.filter(|p| !p.is_empty())
.unwrap_or_else(|| default_path.to_string_lossy().into_owned());
if let Err(e) = fs::write(&path, &code_final) {
if trace {
eprintln!("[vm/merged-hako] failed to write {}: {}", path, e);
}
} else if trace
|| crate::config::env::env_bool("NYASH_VM_DUMP_MERGED_HAKO_LOG")
{
eprintln!("[vm/merged-hako] dumped merged code to {}", path);
}
}
if trace && (std::env::var("NYASH_PARSER_STAGE3").ok() == Some("1".into())
|| std::env::var("HAKO_PARSER_STAGE3").ok() == Some("1".into()))
{