broken refactor

This commit is contained in:
minish 2025-10-08 17:47:05 -04:00
parent cb15876d9d
commit eaf547c3d2
Signed by: min
SSH Key Fingerprint: SHA256:mf+pUTmK92Y57BuCjlkBdd82LqztTfDCQIUp0fCKABc
1 changed files with 72 additions and 46 deletions

View File

@ -332,31 +332,60 @@ impl<'a> FuncBuild<'a> {
(self.check_drop(v1), self.check_drop(v2)) (self.check_drop(v1), self.check_drop(v2))
} }
fn gen_unop(&mut self, r: Expr, f: impl Fn(bool, Val) -> Inst) -> Val { fn gen_unop(&mut self, r: Expr, f: impl Fn(bool, Val) -> Inst, is_captured: bool) -> Val {
let v1 = self.translate(r); let v1 = self.translate(r, is_captured);
// If nothing will use this,
// don't generate anything
if !is_captured {
return Val::Nil;
}
let a1 = self.check_drop(&v1); let a1 = self.check_drop(&v1);
self.insts.push(f(a1, v1)); self.insts.push(f(a1, v1));
Val::Stack(self.push_any(), true) Val::Stack(self.push_any(), true)
} }
fn gen_binop(&mut self, l: Expr, r: Expr, f: impl Fn(bool, bool, Val, Val) -> Inst) -> Val { fn gen_binop(
let (v1, v2) = (self.translate(l), self.translate(r)); &mut self,
l: Expr,
r: Expr,
f: impl Fn(bool, bool, Val, Val) -> Inst,
is_captured: bool,
) -> Val {
let (v1, v2) = (
self.translate(l, is_captured),
self.translate(r, is_captured),
);
// If this is unused, do not generate code
if !is_captured {
return Val::Nil;
}
let (a1, a2) = self.check_drop2(&v1, &v2); let (a1, a2) = self.check_drop2(&v1, &v2);
self.insts.push(f(a1, a2, v1, v2)); self.insts.push(f(a1, a2, v1, v2));
Val::Stack(self.push_any(), true) Val::Stack(self.push_any(), true)
} }
fn translate(&mut self, e: Expr) -> Val { fn translate(&mut self, e: Expr, is_captured: bool) -> Val {
match e { match e {
/* organisational */ /* organisational */
Expr::Block(mut b) => { Expr::Block(mut b) => {
let last = b.exprs.pop(); let last = b.exprs.pop();
for e in b.exprs { for e in b.exprs {
self.translate(e); self.translate(e, false);
} }
// yield last expr // yield last expr
last.map_or(Val::Nil, |e| self.translate(e)) last.map_or(Val::Nil, |e| self.translate(e, is_captured))
}
/* captured literal */
Expr::Literal(lit) if is_captured => {
let v1 = self.translate(Expr::Literal(lit), false);
self.insts.push(Inst::Copy(v1));
Val::Stack(self.push_any(), false)
} }
/* 1 to 1 literals */ /* 1 to 1 literals */
@ -375,42 +404,37 @@ impl<'a> FuncBuild<'a> {
unreachable!() unreachable!()
}; };
// will the var ever get used? // will the var ever get referenced?
let gets_used = ref_stat.now != ref_stat.meta.total.get(); let gets_referenced = ref_stat.now != ref_stat.meta.total.get();
match *r { // if this isn't getting captured OR referenced,
// the var's value is a literal, and it gets used; add to stack // just continue translation without adding to stack
Expr::Literal(lit) if gets_used => { if !(is_captured || gets_referenced) {
let v1 = self.translate(Expr::Literal(lit)); self.translate(*r, false)
self.insts.push(Inst::Copy(v1)); } else {
Val::Stack(self.push_any(), false) // get val
} let val = match *r {
// it doesn't get used; just treat it like a literal // the var's value is a literal
Expr::Literal(lit) => self.translate(Expr::Literal(lit)), Expr::Literal(lit) => self.translate(Expr::Literal(lit), gets_referenced),
// value is an expr // value is an expr
e => { e => self.translate(e, true),
// translate the value };
let val = self.translate(e); // if the var got used, it will be on stack
// we know the top of the stack is the result // so keep track of it
// so lets keep track of that if gets_referenced {
self.local.swap_top(FSValue::Var(id)); self.local.swap_top(FSValue::Var(id));
// also if this val is never used again, just pop it now
if !gets_used {
let v1 = self.pop_top();
self.insts.push(Inst::Pop(v1));
} }
val val
} }
} }
}
/* math */ /* math */
Expr::Add(l, r) => self.gen_binop(*l, *r, Inst::Add), Expr::Add(l, r) => self.gen_binop(*l, *r, Inst::Add, is_captured),
Expr::Multiply(l, r) => self.gen_binop(*l, *r, Inst::Mul), Expr::Multiply(l, r) => self.gen_binop(*l, *r, Inst::Mul, is_captured),
Expr::Divide(l, r) => self.gen_binop(*l, *r, Inst::Div), Expr::Divide(l, r) => self.gen_binop(*l, *r, Inst::Div, is_captured),
Expr::Modulo(l, r) => self.gen_binop(*l, *r, Inst::Mod), Expr::Modulo(l, r) => self.gen_binop(*l, *r, Inst::Mod, is_captured),
Expr::Exponent(l, r) => self.gen_binop(*l, *r, Inst::Pow), Expr::Exponent(l, r) => self.gen_binop(*l, *r, Inst::Pow, is_captured),
Expr::Subtract(l, r) => { Expr::Subtract(l, r) => {
// negate // negate
@ -420,7 +444,7 @@ impl<'a> FuncBuild<'a> {
Expr::Literal(Literal::Float(f)) => Val::Float64(-f), Expr::Literal(Literal::Float(f)) => Val::Float64(-f),
// at runtime // at runtime
e => { e => {
let v2 = self.translate(e); let v2 = self.translate(e, is_captured);
let a2 = self.check_drop(&v2); let a2 = self.check_drop(&v2);
self.insts.push(Inst::Mul(a2, false, v2, Val::Int64(-1))); self.insts.push(Inst::Mul(a2, false, v2, Val::Int64(-1)));
Val::Stack(self.pop_top(), true) Val::Stack(self.pop_top(), true)
@ -428,7 +452,7 @@ impl<'a> FuncBuild<'a> {
}; };
// add // add
let v1 = self.translate(*l); let v1 = self.translate(*l, is_captured);
let a1 = self.check_drop(&v1); let a1 = self.check_drop(&v1);
self.insts.push(Inst::Add(a1, true, v1, nv2)); self.insts.push(Inst::Add(a1, true, v1, nv2));
@ -436,15 +460,17 @@ impl<'a> FuncBuild<'a> {
} }
/* logic */ /* logic */
Expr::And(l, r) => self.gen_binop(*l, *r, Inst::And), Expr::And(l, r) => self.gen_binop(*l, *r, Inst::And, is_captured),
Expr::Or(l, r) => self.gen_binop(*l, *r, Inst::Or), Expr::Or(l, r) => self.gen_binop(*l, *r, Inst::Or, is_captured),
Expr::EqualTo(l, r) => self.gen_binop(*l, *r, Inst::Eq), Expr::EqualTo(l, r) => self.gen_binop(*l, *r, Inst::Eq, is_captured),
Expr::GreaterThan(l, r) => self.gen_binop(*l, *r, Inst::Gt), Expr::GreaterThan(l, r) => self.gen_binop(*l, *r, Inst::Gt, is_captured),
Expr::GreaterThanOrEqualTo(l, r) => self.gen_binop(*l, *r, Inst::GtEq), Expr::GreaterThanOrEqualTo(l, r) => self.gen_binop(*l, *r, Inst::GtEq, is_captured),
Expr::Not(r) => self.gen_unop(*r, Inst::Not), Expr::Not(r) => self.gen_unop(*r, Inst::Not, is_captured),
Expr::NotEqualTo(l, r) => self.translate(Expr::Not(Box::new(Expr::EqualTo(l, r)))), Expr::NotEqualTo(l, r) => {
Expr::LessThan(l, r) => self.translate(Expr::GreaterThan(r, l)), self.translate(Expr::Not(Box::new(Expr::EqualTo(l, r))), is_captured)
}
Expr::LessThan(l, r) => self.translate(Expr::GreaterThan(r, l), is_captured),
e => unimplemented!("{e:?}"), e => unimplemented!("{e:?}"),
} }
@ -460,6 +486,6 @@ pub fn analysis_demo(e: &mut Expr) {
pub fn translation_demo(e: Expr) -> Vec<Inst> { pub fn translation_demo(e: Expr) -> Vec<Inst> {
// translation pass // translation pass
let mut fb = FuncBuild::new_root(); let mut fb = FuncBuild::new_root();
fb.translate(e); fb.translate(e, false);
fb.insts fb.insts
} }