feat: stack var (WIP)
This commit is contained in:
@@ -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()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user