refactor codegen a little
This commit is contained in:
parent
03620fa56a
commit
e960a12e96
146
src/compiler.rs
146
src/compiler.rs
|
@ -300,10 +300,23 @@ impl<'a> FuncBuild<'a> {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns stackval for top item of stack.
|
||||||
|
/// (Panics if empty)
|
||||||
|
fn top(&self) -> Stkval {
|
||||||
|
Stkval::Local(self.local.top_index() as u8)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pushes a value to stack and returns its stackval.
|
||||||
fn push_any(&mut self) -> Stkval {
|
fn push_any(&mut self) -> Stkval {
|
||||||
let i = self.local.height();
|
|
||||||
self.local.push(FSValue::Any);
|
self.local.push(FSValue::Any);
|
||||||
Stkval::Local(i as u8)
|
self.top()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Pops top stack value and returns its stackval.
|
||||||
|
fn pop_top(&mut self) -> Stkval {
|
||||||
|
let to_pop = self.top();
|
||||||
|
self.local.values_mut().pop();
|
||||||
|
to_pop
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_drop(&mut self, v: &Val) -> bool {
|
fn check_drop(&mut self, v: &Val) -> bool {
|
||||||
|
@ -318,6 +331,21 @@ 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 {
|
||||||
|
let v1 = self.translate(r);
|
||||||
|
let a1 = self.check_drop(&v1);
|
||||||
|
|
||||||
|
self.insts.push(f(a1, v1));
|
||||||
|
Val::Stack(self.push_any(), true)
|
||||||
|
}
|
||||||
|
fn gen_binop(&mut self, l: Expr, r: Expr, f: impl Fn(bool, bool, Val, Val) -> Inst) -> Val {
|
||||||
|
let (v1, v2) = (self.translate(l), self.translate(r));
|
||||||
|
let (a1, a2) = self.check_drop2(&v1, &v2);
|
||||||
|
|
||||||
|
self.insts.push(f(a1, a2, v1, v2));
|
||||||
|
Val::Stack(self.push_any(), true)
|
||||||
|
}
|
||||||
|
|
||||||
fn translate(&mut self, e: Expr) -> Val {
|
fn translate(&mut self, e: Expr) -> Val {
|
||||||
// println!("{e:?}");
|
// println!("{e:?}");
|
||||||
let outp = match e {
|
let outp = match e {
|
||||||
|
@ -367,71 +395,51 @@ impl<'a> FuncBuild<'a> {
|
||||||
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
|
// also if this val is never used again, just pop it now
|
||||||
if !gets_used {
|
if !gets_used {
|
||||||
self.local.pop_top();
|
let v1 = self.pop_top();
|
||||||
self.insts
|
self.insts.push(Inst::Pop(v1));
|
||||||
.push(Inst::Pop(Stkval::Local(self.local.height() as u8)));
|
|
||||||
}
|
}
|
||||||
val
|
val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* math */
|
/* math */
|
||||||
Expr::Add(l, r) => {
|
Expr::Add(l, r) => self.gen_binop(*l, *r, Inst::Add),
|
||||||
let (v1, v2) = (self.translate(*l), self.translate(*r));
|
Expr::Multiply(l, r) => self.gen_binop(*l, *r, Inst::Mul),
|
||||||
let (a1, a2) = self.check_drop2(&v1, &v2);
|
Expr::Divide(l, r) => self.gen_binop(*l, *r, Inst::Div),
|
||||||
|
Expr::Modulo(l, r) => self.gen_binop(*l, *r, Inst::Mod),
|
||||||
|
Expr::Exponent(l, r) => self.gen_binop(*l, *r, Inst::Pow),
|
||||||
|
|
||||||
self.insts.push(Inst::Add(a1, a2, v1, v2));
|
Expr::Subtract(l, r) => {
|
||||||
|
// negate
|
||||||
|
let nv2 = match *r {
|
||||||
|
// statically
|
||||||
|
Expr::Literal(Literal::Integer(i)) => Val::Int64(-i),
|
||||||
|
Expr::Literal(Literal::Float(f)) => Val::Float64(-f),
|
||||||
|
// at runtime
|
||||||
|
e => {
|
||||||
|
let v2 = self.translate(e);
|
||||||
|
let a2 = self.check_drop(&v2);
|
||||||
|
self.insts.push(Inst::Mul(a2, false, v2, Val::Int64(-1)));
|
||||||
|
Val::Stack(self.pop_top(), true)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// add
|
||||||
|
let v1 = self.translate(*l);
|
||||||
|
let a1 = self.check_drop(&v1);
|
||||||
|
|
||||||
|
self.insts.push(Inst::Add(a1, true, v1, nv2));
|
||||||
Val::Stack(self.push_any(), true)
|
Val::Stack(self.push_any(), true)
|
||||||
}
|
}
|
||||||
Expr::Multiply(l, r) => {
|
|
||||||
let (v1, v2) = (self.translate(*l), self.translate(*r));
|
|
||||||
let (a1, a2) = self.check_drop2(&v1, &v2);
|
|
||||||
|
|
||||||
self.insts.push(Inst::Mul(a1, a2, v1, v2));
|
/* logic */
|
||||||
Val::Stack(self.push_any(), true)
|
Expr::And(l, r) => self.gen_binop(*l, *r, Inst::And),
|
||||||
}
|
Expr::Or(l, r) => self.gen_binop(*l, *r, Inst::Or),
|
||||||
Expr::Divide(l, r) => {
|
Expr::EqualTo(l, r) => self.gen_binop(*l, *r, Inst::Eq),
|
||||||
let (v1, v2) = (self.translate(*l), self.translate(*r));
|
Expr::GreaterThan(l, r) => self.gen_binop(*l, *r, Inst::Gt),
|
||||||
let (a1, a2) = self.check_drop2(&v1, &v2);
|
Expr::Not(r) => self.gen_unop(*r, Inst::Not),
|
||||||
|
|
||||||
self.insts.push(Inst::Div(a1, a2, v1, v2));
|
|
||||||
Val::Stack(self.push_any(), true)
|
|
||||||
}
|
|
||||||
Expr::Modulo(l, r) => {
|
|
||||||
let (v1, v2) = (self.translate(*l), self.translate(*r));
|
|
||||||
let (a1, a2) = self.check_drop2(&v1, &v2);
|
|
||||||
|
|
||||||
self.insts.push(Inst::Mod(a1, a2, v1, v2));
|
|
||||||
Val::Stack(self.push_any(), true)
|
|
||||||
}
|
|
||||||
Expr::Exponent(l, r) => {
|
|
||||||
let (v1, v2) = (self.translate(*l), self.translate(*r));
|
|
||||||
let (a1, a2) = self.check_drop2(&v1, &v2);
|
|
||||||
|
|
||||||
self.insts.push(Inst::Pow(a1, a2, v1, v2));
|
|
||||||
Val::Stack(self.push_any(), true)
|
|
||||||
}
|
|
||||||
Expr::And(l, r) => {
|
|
||||||
let (v1, v2) = (self.translate(*l), self.translate(*r));
|
|
||||||
let (a1, a2) = self.check_drop2(&v1, &v2);
|
|
||||||
|
|
||||||
self.insts.push(Inst::And(a1, a2, v1, v2));
|
|
||||||
Val::Stack(self.push_any(), true)
|
|
||||||
}
|
|
||||||
Expr::Or(l, r) => {
|
|
||||||
let (v1, v2) = (self.translate(*l), self.translate(*r));
|
|
||||||
let (a1, a2) = self.check_drop2(&v1, &v2);
|
|
||||||
|
|
||||||
self.insts.push(Inst::Or(a1, a2, v1, v2));
|
|
||||||
Val::Stack(self.push_any(), true)
|
|
||||||
}
|
|
||||||
Expr::EqualTo(l, r) => {
|
|
||||||
let (v1, v2) = (self.translate(*l), self.translate(*r));
|
|
||||||
let (a1, a2) = self.check_drop2(&v1, &v2);
|
|
||||||
|
|
||||||
self.insts.push(Inst::Eq(a1, a2, v1, v2));
|
|
||||||
Val::Stack(self.push_any(), true)
|
|
||||||
}
|
|
||||||
Expr::NotEqualTo(l, r) => {
|
Expr::NotEqualTo(l, r) => {
|
||||||
let (v1, v2) = (self.translate(*l), self.translate(Expr::Not(r)));
|
let (v1, v2) = (self.translate(*l), self.translate(Expr::Not(r)));
|
||||||
let (a1, a2) = self.check_drop2(&v1, &v2);
|
let (a1, a2) = self.check_drop2(&v1, &v2);
|
||||||
|
@ -439,13 +447,6 @@ impl<'a> FuncBuild<'a> {
|
||||||
self.insts.push(Inst::Eq(a1, a2, v1, v2));
|
self.insts.push(Inst::Eq(a1, a2, v1, v2));
|
||||||
Val::Stack(self.push_any(), true)
|
Val::Stack(self.push_any(), true)
|
||||||
}
|
}
|
||||||
Expr::GreaterThan(l, r) => {
|
|
||||||
let (v1, v2) = (self.translate(*l), self.translate(*r));
|
|
||||||
let (a1, a2) = self.check_drop2(&v1, &v2);
|
|
||||||
|
|
||||||
self.insts.push(Inst::Gt(a1, a2, v1, v2));
|
|
||||||
Val::Stack(self.push_any(), true)
|
|
||||||
}
|
|
||||||
Expr::LessThan(l, r) => {
|
Expr::LessThan(l, r) => {
|
||||||
let (v1, v2) = (self.translate(*l), self.translate(*r));
|
let (v1, v2) = (self.translate(*l), self.translate(*r));
|
||||||
let (a1, a2) = self.check_drop2(&v1, &v2);
|
let (a1, a2) = self.check_drop2(&v1, &v2);
|
||||||
|
@ -453,26 +454,7 @@ impl<'a> FuncBuild<'a> {
|
||||||
self.insts.push(Inst::Gt(a2, a1, v2, v1));
|
self.insts.push(Inst::Gt(a2, a1, v2, v1));
|
||||||
Val::Stack(self.push_any(), true)
|
Val::Stack(self.push_any(), true)
|
||||||
}
|
}
|
||||||
Expr::Subtract(l, r) => {
|
|
||||||
let (v1, v2) = (
|
|
||||||
self.translate(*l),
|
|
||||||
self.translate(Expr::Multiply(
|
|
||||||
r,
|
|
||||||
Box::new(Expr::Literal(Literal::Integer(-1))),
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
let (a1, a2) = self.check_drop2(&v1, &v2);
|
|
||||||
|
|
||||||
self.insts.push(Inst::Add(a1, a2, v1, v2));
|
|
||||||
Val::Stack(self.push_any(), true)
|
|
||||||
}
|
|
||||||
Expr::Not(r) => {
|
|
||||||
let v1 = self.translate(*r);
|
|
||||||
let a1 = self.check_drop(&v1);
|
|
||||||
|
|
||||||
self.insts.push(Inst::Not(a1, v1));
|
|
||||||
Val::Stack(self.push_any(), true)
|
|
||||||
}
|
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
};
|
};
|
||||||
// println!("CHECK {:?} {:?}", self.insts.last(), self.local.values());
|
// println!("CHECK {:?} {:?}", self.insts.last(), self.local.values());
|
||||||
|
|
|
@ -20,15 +20,12 @@ where
|
||||||
fn pop(&mut self, index: usize) {
|
fn pop(&mut self, index: usize) {
|
||||||
self.values_mut().remove(index);
|
self.values_mut().remove(index);
|
||||||
}
|
}
|
||||||
fn height(&self) -> usize {
|
fn top_index(&self) -> usize {
|
||||||
self.values().len()
|
self.values().len() - 1
|
||||||
}
|
}
|
||||||
fn swap_top(&mut self, new: Self::Value) {
|
fn swap_top(&mut self, new: Self::Value) {
|
||||||
*self.values_mut().last_mut().unwrap() = new;
|
*self.values_mut().last_mut().unwrap() = new;
|
||||||
}
|
}
|
||||||
fn pop_top(&mut self) {
|
|
||||||
self.values_mut().pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find(&self, input: &Self::Input) -> Option<(Self::Output, u16)> {
|
fn find(&self, input: &Self::Input) -> Option<(Self::Output, u16)> {
|
||||||
let mut cur = Some(self);
|
let mut cur = Some(self);
|
||||||
|
|
Loading…
Reference in New Issue