feat: stack var (WIP)

This commit is contained in:
2025-08-09 08:12:53 +08:00
parent fd182b6233
commit d8ad7fe904
36 changed files with 1521 additions and 1058 deletions

View File

@@ -10,20 +10,20 @@ use nixjit_ir::PrimOpId;
use super::Value;
use crate::EvalContext;
pub type Args = smallvec::SmallVec<[Value; 2]>;
/// Represents a partially applied primitive operation (builtin function).
///
/// This struct holds the state of a primop that has received some, but not
/// all, of its required arguments.
#[derive(Debug, Clone, Constructor)]
pub struct PrimOpApp {
/// The name of the primitive operation.
pub name: &'static str,
/// The number of remaining arguments the primop expects.
arity: usize,
/// The unique ID of the primop.
id: PrimOpId,
/// The arguments that have already been applied.
args: Vec<Value>,
args: Args,
}
impl PrimOpApp {
@@ -32,27 +32,15 @@ impl PrimOpApp {
/// If enough arguments are provided to satisfy the primop's arity, it is
/// executed. Otherwise, it returns a new `PrimOpApp` with the combined
/// arguments.
pub fn call(
self: &mut Rc<Self>,
mut args: Vec<Value>,
ctx: &mut impl EvalContext,
) -> Result<Value> {
if self.arity < args.len() {
let leftover = args.split_off(self.arity);
for arg in self.args.iter().rev().cloned() {
args.insert(0, arg);
}
let mut ret = ctx.call_primop(self.id, args)?;
ret.call(leftover.into_iter().map(Ok), ctx)?;
return Ok(ret);
}
let self_mut = Rc::make_mut(self);
self_mut.arity -= args.len();
self_mut.args.extend(args);
if self_mut.arity == 0 {
ctx.call_primop(self_mut.id, std::mem::take(&mut self_mut.args))
pub fn call(self: Rc<Self>, arg: Value, ctx: &mut impl EvalContext) -> Result<Value> {
let mut primop = Rc::unwrap_or_clone(self);
if primop.arity == 1 {
primop.args.push(arg);
ctx.call_primop(primop.id, primop.args)
} else {
Ok(Value::PrimOpApp(self.clone()))
primop.args.push(arg);
primop.arity -= 1;
Ok(Value::PrimOpApp(primop.into()))
}
}
}