Phase 21.6 solidification: chain green (return/binop/loop/call); add Phase 21.7 normalization plan (methodize static boxes). Update CURRENT_TASK.md and docs.

This commit is contained in:
nyash-codex
2025-11-11 22:35:45 +09:00
parent 52b62c5772
commit 9e2fa1e36e
19 changed files with 1309 additions and 35 deletions

View File

@ -1,10 +1,21 @@
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize, Serialize)]
#[derive(Debug, Deserialize, Serialize, Clone)]
pub(super) struct ProgramV0 {
pub(super) version: i32,
pub(super) kind: String,
pub(super) body: Vec<StmtV0>,
#[serde(default)]
pub(super) defs: Vec<FuncDefV0>,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub(super) struct FuncDefV0 {
pub(super) name: String,
pub(super) params: Vec<String>,
pub(super) body: ProgramV0,
#[serde(rename = "box")]
pub(super) box_name: String,
}
#[derive(Debug, Deserialize, Serialize, Clone)]

View File

@ -185,6 +185,7 @@ pub(super) fn parse_source_v0_to_json(input: &str) -> Result<String, String> {
version: 0,
kind: "Program".into(),
body: vec![StmtV0::Return { expr }],
defs: vec![],
};
serde_json::to_string(&prog).map_err(|e| e.to_string())
}

View File

@ -293,6 +293,103 @@ pub(super) fn lower_program(prog: ProgramV0) -> Result<MirModule, String> {
f.signature.return_type = MirType::Unknown;
// フェーズM.2: PHI後処理削除 - MirBuilder/LoopBuilderでPHI統一済み
module.add_function(f);
// Phase 21.6: Process function definitions (defs)
// Toggle: HAKO_STAGEB_FUNC_SCAN=1 + HAKO_MIR_BUILDER_FUNCS=1
// Minimal support: Return(Int|Binary(+|-|*|/, Int|Var, Int|Var))
let mut func_map: HashMap<String, String> = HashMap::new();
if !prog.defs.is_empty() {
for func_def in prog.defs {
// Create function signature: Main.<name>
let func_name = format!("{}.{}", func_def.box_name, func_def.name);
// Register function in map for Call resolution
func_map.insert(func_def.name.clone(), func_name.clone());
let param_ids: Vec<ValueId> = (0..func_def.params.len())
.map(|i| ValueId::new(i as u32 + 1))
.collect();
let param_types: Vec<MirType> = (0..func_def.params.len())
.map(|_| MirType::Unknown)
.collect();
let sig = FunctionSignature {
name: func_name,
params: param_types,
return_type: MirType::Integer,
effects: EffectMask::PURE,
};
let entry = BasicBlockId::new(0);
let mut func = MirFunction::new(sig, entry);
// Map params to value IDs
let mut func_var_map: HashMap<String, ValueId> = HashMap::new();
for (i, param_name) in func_def.params.iter().enumerate() {
func_var_map.insert(param_name.clone(), param_ids[i]);
}
// Lower function body
let mut loop_stack: Vec<LoopContext> = Vec::new();
let start_bb = func.entry_block;
let _end_bb = lower_stmt_list_with_vars(
&mut func,
start_bb,
&func_def.body.body,
&mut func_var_map,
&mut loop_stack,
&env,
)?;
func.signature.return_type = MirType::Unknown;
module.add_function(func);
}
}
// Phase 21.6: Call resolution post-processing
// Toggle: HAKO_MIR_BUILDER_CALL_RESOLVE=1
// Resolve Call instructions to use qualified function names (e.g., "add" -> "Main.add")
if std::env::var("HAKO_MIR_BUILDER_CALL_RESOLVE").ok().as_deref() == Some("1") {
if !func_map.is_empty() {
for (_func_idx, func) in module.functions.iter_mut() {
for (_block_id, block) in func.blocks.iter_mut() {
let mut const_replacements: Vec<(ValueId, String)> = Vec::new();
// Find Call instructions and their associated Const values
for inst in &block.instructions {
if let MirInstruction::Call { func: func_reg, .. } = inst {
// Look for the Const instruction that defines func_reg
for const_inst in &block.instructions {
if let MirInstruction::Const { dst, value } = const_inst {
if dst == func_reg {
if let ConstValue::String(name) = value {
// Try to resolve the name
if let Some(resolved) = func_map.get(name) {
const_replacements.push((*dst, resolved.clone()));
if std::env::var("HAKO_MIR_BUILDER_DEBUG").ok().as_deref() == Some("1") {
eprintln!("[mirbuilder/call:resolve] {} => {}", name, resolved);
}
}
}
}
}
}
}
}
// Apply replacements
for (dst, new_name) in const_replacements {
for inst in &mut block.instructions {
if let MirInstruction::Const { dst: d, value } = inst {
if d == &dst {
*value = ConstValue::String(new_name.clone());
}
}
}
}
}
}
}
}
Ok(module)
}