Phase 11-12: LLVM backend initial, semantics layer, plugin unification

Major changes:
- LLVM backend initial implementation (compiler.rs, llvm mode)
- Semantics layer integration in interpreter (operators.rs)
- Phase 12 plugin architecture revision (3-layer system)
- Builtin box removal preparation
- MIR instruction set documentation (26→Core-15 migration)
- Cross-backend testing infrastructure
- Await/nowait syntax support

New features:
- LLVM AOT compilation support (--backend llvm)
- Semantics layer for interpreter→VM flow
- Tri-backend smoke tests
- Plugin-only registry mode

Bug fixes:
- Interpreter plugin box arithmetic operations
- Branch test returns incorrect values

Documentation:
- Phase 12 README.md updated with new plugin architecture
- Removed obsolete NYIR proposals
- Added LLVM test programs documentation

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Moe Charm
2025-09-01 23:44:34 +09:00
parent fff9749f47
commit 11506cee3b
196 changed files with 10955 additions and 380 deletions

View File

@ -55,6 +55,29 @@ fn builder_debug_log(msg: &str) {
}
}
/// PHIの入力型から戻り値型を推定するヘルパー
fn infer_type_from_phi(
function: &super::MirFunction,
ret_val: super::ValueId,
types: &std::collections::HashMap<super::ValueId, super::MirType>,
) -> Option<super::MirType> {
for (_bid, bb) in function.blocks.iter() {
for inst in bb.instructions.iter() {
if let super::MirInstruction::Phi { dst, inputs } = inst {
if *dst == ret_val {
let mut it = inputs.iter().filter_map(|(_, v)| types.get(v));
if let Some(first) = it.next() {
if it.all(|mt| mt == first) {
return Some(first.clone());
}
}
}
}
}
}
None
}
/// MIR builder for converting AST to SSA form
pub struct MirBuilder {
/// Current module being built
@ -326,7 +349,27 @@ impl MirBuilder {
let mut function = self.current_function.take().unwrap();
// Flush value_types (TyEnv) into function metadata
function.metadata.value_types = self.value_types.clone();
// 補助: 本文中に明示的な return <expr> が存在する場合、
// 末尾returnを挿入しなかった関数でも戻り型を推定する。
if matches!(function.signature.return_type, super::MirType::Void | super::MirType::Unknown) {
let mut inferred: Option<super::MirType> = None;
'outer: for (_bid, bb) in function.blocks.iter() {
for inst in bb.instructions.iter() {
if let super::MirInstruction::Return { value: Some(v) } = inst {
if let Some(mt) = self.value_types.get(v).cloned() { inferred = Some(mt); break 'outer; }
// 追加: v が PHI の場合は入力側の型から推定
if let Some(mt) = infer_type_from_phi(&function, *v, &self.value_types) { inferred = Some(mt); break 'outer; }
}
}
if let Some(super::MirInstruction::Return { value: Some(v) }) = &bb.terminator {
if let Some(mt) = self.value_types.get(v).cloned() { inferred = Some(mt); break; }
if let Some(mt) = infer_type_from_phi(&function, *v, &self.value_types) { inferred = Some(mt); break; }
}
}
if let Some(mt) = inferred { function.signature.return_type = mt; }
}
module.add_function(function);
Ok(module)
}
@ -1486,6 +1529,18 @@ impl MirBuilder {
self.emit_instruction(MirInstruction::Const { dst: void_id, value: ConstValue::Void })?;
return Ok(void_id);
},
("console", "readLine") => {
// env.console.readLine() → ExternCall returning string
let result_id = self.value_gen.next();
self.emit_instruction(MirInstruction::ExternCall {
dst: Some(result_id),
iface_name: "env.console".to_string(),
method_name: "readLine".to_string(),
args: arg_values,
effects: EffectMask::IO,
})?;
return Ok(result_id);
},
("canvas", "fillRect") | ("canvas", "fillText") => {
self.emit_instruction(MirInstruction::ExternCall {
dst: None,