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:
@ -1,7 +1,7 @@
|
||||
use super::ast::{ProgramV0, StmtV0};
|
||||
use super::ast::{ProgramV0, StmtV0, ExprV0};
|
||||
use crate::mir::{
|
||||
BasicBlockId, ConstValue, EffectMask, FunctionSignature, MirFunction, MirInstruction, MirModule,
|
||||
MirPrinter, MirType, ValueId,
|
||||
MirPrinter, MirType, ValueId, BinaryOp,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::cell::RefCell;
|
||||
@ -28,6 +28,8 @@ pub(super) struct LoopContext {
|
||||
thread_local! {
|
||||
static EXIT_SNAPSHOT_STACK: RefCell<Vec<Vec<(BasicBlockId, HashMap<String, ValueId>)>>> = RefCell::new(Vec::new());
|
||||
static CONT_SNAPSHOT_STACK: RefCell<Vec<Vec<(BasicBlockId, HashMap<String, ValueId>)>>> = RefCell::new(Vec::new());
|
||||
// Optional increment hint for current loop frame: (var_name, step)
|
||||
static INCR_HINT_STACK: RefCell<Vec<Option<(String, i64)>>> = RefCell::new(Vec::new());
|
||||
}
|
||||
|
||||
pub(super) fn push_loop_snapshot_frames() {
|
||||
@ -59,6 +61,35 @@ fn record_continue_snapshot(cur_bb: BasicBlockId, vars: &HashMap<String, ValueId
|
||||
});
|
||||
}
|
||||
|
||||
pub(super) fn detect_and_push_increment_hint(body: &[StmtV0]) {
|
||||
let mut hint: Option<(String, i64)> = None;
|
||||
for stmt in body.iter().rev() {
|
||||
if let StmtV0::Local { name, expr } = stmt.clone() {
|
||||
if let ExprV0::Binary { op, lhs, rhs } = expr {
|
||||
if let ExprV0::Var { name: vname } = *lhs {
|
||||
if vname == name {
|
||||
if let ExprV0::Int { value } = *rhs {
|
||||
if let Some(v) = value.as_i64() {
|
||||
let s = match op.as_str() { "+" => v, "-" => -v, _ => 0 };
|
||||
if s != 0 { hint = Some((name.clone(), s)); break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
INCR_HINT_STACK.with(|s| s.borrow_mut().push(hint));
|
||||
}
|
||||
|
||||
pub(super) fn pop_increment_hint() -> Option<(String, i64)> {
|
||||
INCR_HINT_STACK.with(|s| s.borrow_mut().pop().unwrap_or(None))
|
||||
}
|
||||
|
||||
fn peek_increment_hint() -> Option<(String, i64)> {
|
||||
INCR_HINT_STACK.with(|s| s.borrow().last().cloned().unwrap_or(None))
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(super) struct BridgeEnv {
|
||||
pub(super) throw_enabled: bool,
|
||||
@ -172,7 +203,13 @@ pub(super) fn lower_stmt_with_vars(
|
||||
}
|
||||
StmtV0::Continue => {
|
||||
if let Some(ctx) = loop_stack.last().copied() {
|
||||
// snapshot variables at continue
|
||||
// Optional: apply increment hint before continue (so header sees updated var)
|
||||
if let Some((ref var_name, step)) = peek_increment_hint() {
|
||||
let _ = crate::mir::ssot::loop_common::apply_increment_before_continue(
|
||||
f, cur_bb, vars, var_name, step,
|
||||
);
|
||||
}
|
||||
// snapshot variables at continue (after increment)
|
||||
record_continue_snapshot(cur_bb, vars);
|
||||
lower_continue_stmt(f, cur_bb, ctx.cond_bb);
|
||||
}
|
||||
|
||||
@ -152,22 +152,11 @@ pub(super) fn lower_expr_with_scope<S: VarScope>(
|
||||
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)?;
|
||||
let bop = match op.as_str() {
|
||||
"+" => BinaryOp::Add,
|
||||
"-" => BinaryOp::Sub,
|
||||
"*" => BinaryOp::Mul,
|
||||
"/" => BinaryOp::Div,
|
||||
_ => return Err("unsupported op".into()),
|
||||
let bop = match crate::mir::ssot::binop_lower::parse_binop_str(op) {
|
||||
Some(b) => b,
|
||||
None => return Err("unsupported op".into()),
|
||||
};
|
||||
let dst = f.next_value_id();
|
||||
if let Some(bb) = f.get_block_mut(cur_after_r) {
|
||||
bb.add_instruction(MirInstruction::BinOp {
|
||||
dst,
|
||||
op: bop,
|
||||
lhs: l,
|
||||
rhs: r,
|
||||
});
|
||||
}
|
||||
let dst = crate::mir::ssot::binop_lower::emit_binop_func(f, cur_after_r, bop, l, r);
|
||||
Ok((dst, cur_after_r))
|
||||
}
|
||||
ExprV0::Extern {
|
||||
|
||||
@ -126,8 +126,11 @@ pub(super) fn lower_loop_stmt(
|
||||
// open snapshot frames for nested break/continue
|
||||
super::push_loop_snapshot_frames();
|
||||
loop_stack.push(LoopContext { cond_bb, exit_bb });
|
||||
// Detect simple increment hint for this loop body
|
||||
super::detect_and_push_increment_hint(body);
|
||||
let bend_res = lower_stmt_list_with_vars(ops.f, body_bb, body, &mut body_vars, loop_stack, env);
|
||||
loop_stack.pop();
|
||||
let _ = super::pop_increment_hint();
|
||||
let bend = bend_res?;
|
||||
// collect snapshots for this loop level
|
||||
let continue_snaps = super::pop_continue_snapshots();
|
||||
|
||||
Reference in New Issue
Block a user