This commit is contained in:
minish 2025-10-09 21:39:11 -04:00
parent fe2cec5743
commit 5f9ddce9f2
Signed by: min
SSH Key Fingerprint: SHA256:mf+pUTmK92Y57BuCjlkBdd82LqztTfDCQIUp0fCKABc
1 changed files with 26 additions and 13 deletions

View File

@ -205,7 +205,7 @@ pub enum Val {
/* u16 len, LEN data */ /* u16 len, LEN data */
String(String), String(String),
/* 1b returnability, 4b arity, insts */ /* 1b returnability, 4b arity, insts */
Func(bool, Vec<Inst>), Func(bool, u8, Vec<Inst>),
/* 1b value */ /* 1b value */
Bool(bool), Bool(bool),
/* i64 data */ /* i64 data */
@ -329,13 +329,6 @@ impl<'a> FuncBuild<'a> {
self.top() 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 {
if let Val::Stack(Stkval::Local(i), true) = v { if let Val::Stack(Stkval::Local(i), true) = v {
self.local.pop(*i as usize); self.local.pop(*i as usize);
@ -383,6 +376,11 @@ impl<'a> FuncBuild<'a> {
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 gen_copy(&mut self, v1: Val) -> Val {
let a1 = self.check_drop(&v1);
self.insts.push(Inst::Copy(a1, v1));
Val::Stack(self.push_any(), false)
}
fn translate(&mut self, e: Expr, do_compute: bool, do_yield: bool) -> Val { fn translate(&mut self, e: Expr, do_compute: bool, do_yield: bool) -> Val {
match e { match e {
@ -395,9 +393,22 @@ impl<'a> FuncBuild<'a> {
// compute/yield last expr if requested // compute/yield last expr if requested
last.map_or(Val::Nil, |e| self.translate(e, do_compute, do_yield)) last.map_or(Val::Nil, |e| self.translate(e, do_compute, do_yield))
} }
Expr::Func(args, exprs, fs) => { Expr::Func(args, expr, fs) => {
// neww function!!!! // neww function!!!!
Val::Nil let mut fb = FuncBuild::with_parent(self);
// push args to stack
let arity = args.len() as u8;
for arg in args {
let Expr::Literal(Literal::Ident(id, _)) = arg else {
unreachable!()
};
fb.local.push(FSValue::Var(id));
}
// translate expr
fb.translate(*expr, true, false);
// pack
let returnability = fs.unwrap().is_unreturnable.get();
Val::Func(returnability, arity, fb.insts)
} }
/* control flow */ /* control flow */
@ -432,9 +443,7 @@ impl<'a> FuncBuild<'a> {
/* captured literal */ /* captured literal */
Expr::Literal(lit) if do_yield => { Expr::Literal(lit) if do_yield => {
let v1 = self.translate(Expr::Literal(lit), true, false); let v1 = self.translate(Expr::Literal(lit), true, false);
let a1 = self.check_drop(&v1); self.gen_copy(v1)
self.insts.push(Inst::Copy(a1, v1));
Val::Stack(self.push_any(), false)
} }
/* 1 to 1 literals */ /* 1 to 1 literals */
@ -481,10 +490,14 @@ impl<'a> FuncBuild<'a> {
let val = match val { let val = match val {
// apply appropriate drop rule // apply appropriate drop rule
Val::Stack(sv, _) => Val::Stack(sv, gets_referenced), Val::Stack(sv, _) => Val::Stack(sv, gets_referenced),
// non-literal type
val if matches!(val, Val::Func(_, _, _)) => self.gen_copy(val),
// okay as-is // okay as-is
val => val, val => val,
}; };
println!("{val:?}");
// check if var already exists // check if var already exists
if let Some(sv) = self.find(&id) { if let Some(sv) = self.find(&id) {
// yes, move it there // yes, move it there