hv1: early-exit at main (no plugin init); tokenizer: Stage-3 single-quote + full escapes (\/ \b \f \' \r fix); builder: route BinOp via SSOT emit_binop_to_dst; hv1 verify canary route (builder→Core); docs: phase-20.39 updates

This commit is contained in:
nyash-codex
2025-11-04 20:46:43 +09:00
parent 31ce798341
commit 44a5158a14
53 changed files with 2237 additions and 179 deletions

View File

@ -94,12 +94,20 @@ impl super::MirBuilder {
self.value_types.insert(dst, MirType::Integer);
} else {
// guard中は従来のBinOp
self.emit_instruction(MirInstruction::BinOp { dst, op, lhs, rhs })?;
if let (Some(func), Some(cur_bb)) = (self.current_function.as_mut(), self.current_block) {
crate::mir::ssot::binop_lower::emit_binop_to_dst(func, cur_bb, dst, op, lhs, rhs);
} else {
self.emit_instruction(MirInstruction::BinOp { dst, op, lhs, rhs })?;
}
self.value_types.insert(dst, MirType::Integer);
}
} else {
// 既存の算術経路
self.emit_instruction(MirInstruction::BinOp { dst, op, lhs, rhs })?;
if let (Some(func), Some(cur_bb)) = (self.current_function.as_mut(), self.current_block) {
crate::mir::ssot::binop_lower::emit_binop_to_dst(func, cur_bb, dst, op, lhs, rhs);
} else {
self.emit_instruction(MirInstruction::BinOp { dst, op, lhs, rhs })?;
}
if matches!(op, crate::mir::BinaryOp::Add) {
let lhs_is_str = match self.value_types.get(&lhs) {
Some(MirType::String) => true,
@ -122,7 +130,11 @@ impl super::MirBuilder {
}
} else {
// 既存の算術経路
self.emit_instruction(MirInstruction::BinOp { dst, op, lhs, rhs })?;
if let (Some(func), Some(cur_bb)) = (self.current_function.as_mut(), self.current_block) {
crate::mir::ssot::binop_lower::emit_binop_to_dst(func, cur_bb, dst, op, lhs, rhs);
} else {
self.emit_instruction(MirInstruction::BinOp { dst, op, lhs, rhs })?;
}
if matches!(op, crate::mir::BinaryOp::Add) {
let lhs_is_str = match self.value_types.get(&lhs) {
Some(MirType::String) => true,

View File

@ -18,6 +18,7 @@ pub mod instruction_introspection; // Introspection helpers for tests (instructi
pub mod types; // core MIR enums (ConstValue, Ops, MirType)
pub mod loop_api; // Minimal LoopBuilder facade (adapter-ready)
pub mod loop_builder; // SSA loop construction with phi nodes
pub mod ssot; // Shared helpers (SSOT) for instruction lowering
pub mod optimizer;
pub mod utils; // Phase 15 control flow utilities for root treatment
pub mod phi_core; // Phase 1 scaffold: unified PHI entry (re-exports only)

View File

@ -0,0 +1,50 @@
use crate::mir::{BasicBlockId, BinaryOp, MirFunction, MirInstruction, ValueId};
/// Parse a binary operator string to BinaryOp
pub fn parse_binop_str(op: &str) -> Option<BinaryOp> {
match op {
"+" => Some(BinaryOp::Add),
"-" => Some(BinaryOp::Sub),
"*" => Some(BinaryOp::Mul),
"/" => Some(BinaryOp::Div),
"%" => Some(BinaryOp::Mod),
"&" => Some(BinaryOp::BitAnd),
"|" => Some(BinaryOp::BitOr),
"^" => Some(BinaryOp::BitXor),
"<<" => Some(BinaryOp::Shl),
">>" => Some(BinaryOp::Shr),
_ => None,
}
}
/// Emit a MIR BinOp into the current block and return the destination ValueId
pub fn emit_binop_func(
f: &mut MirFunction,
cur_bb: BasicBlockId,
op: BinaryOp,
lhs: ValueId,
rhs: ValueId,
) -> ValueId {
let dst = f.next_value_id();
if let Some(bb) = f.get_block_mut(cur_bb) {
bb.add_instruction(MirInstruction::BinOp { dst, op, lhs, rhs });
}
dst
}
/// Emit a MIR BinOp into the current block using the provided destination id.
/// This variant allows front-ends that pre-allocate `dst` (e.g., builders that
/// maintain their own value id generator) to route through the SSOT without
/// changing id allocation policy.
pub fn emit_binop_to_dst(
f: &mut MirFunction,
cur_bb: BasicBlockId,
dst: ValueId,
op: BinaryOp,
lhs: ValueId,
rhs: ValueId,
) {
if let Some(bb) = f.get_block_mut(cur_bb) {
bb.add_instruction(MirInstruction::BinOp { dst, op, lhs, rhs });
}
}

View File

@ -0,0 +1,26 @@
use crate::mir::{BasicBlockId, MirFunction, MirInstruction, ValueId, BinaryOp, ConstValue};
use std::collections::HashMap;
/// Apply `var += step` before continue so that header sees updated value.
/// Returns the new ValueId of the variable if updated, otherwise None.
pub fn apply_increment_before_continue(
f: &mut MirFunction,
cur_bb: BasicBlockId,
vars: &mut HashMap<String, ValueId>,
var_name: &str,
step: i64,
) -> Option<ValueId> {
let cur_val = match vars.get(var_name) { Some(v) => *v, None => return None };
// Emit const step
let step_v = f.next_value_id();
if let Some(bb) = f.get_block_mut(cur_bb) {
bb.add_instruction(MirInstruction::Const { dst: step_v, value: ConstValue::Integer(step) });
}
// Emit add
let new_v = f.next_value_id();
if let Some(bb) = f.get_block_mut(cur_bb) {
bb.add_instruction(MirInstruction::BinOp { dst: new_v, op: BinaryOp::Add, lhs: cur_val, rhs: step_v });
}
vars.insert(var_name.to_string(), new_v);
Some(new_v)
}

2
src/mir/ssot/mod.rs Normal file
View File

@ -0,0 +1,2 @@
pub mod binop_lower;
pub mod loop_common;