refactor: reduce coupling
This commit is contained in:
75
evaluator/nixjit_eval/src/value/primop.rs
Normal file
75
evaluator/nixjit_eval/src/value/primop.rs
Normal file
@@ -0,0 +1,75 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use derive_more::Constructor;
|
||||
|
||||
use nixjit_error::Result;
|
||||
|
||||
use super::Value;
|
||||
use crate::EvalContext;
|
||||
|
||||
#[derive(Debug, Clone, Constructor)]
|
||||
pub struct PrimOp<Ctx: EvalContext> {
|
||||
pub name: &'static str,
|
||||
arity: usize,
|
||||
func: fn(Vec<Value<Ctx>>, &Ctx) -> Result<Value<Ctx>>,
|
||||
}
|
||||
|
||||
impl<Ctx: EvalContext> PrimOp<Ctx> {
|
||||
pub fn call(&self, args: Vec<Value<Ctx>>, ctx: &Ctx) -> Result<Value<Ctx>> {
|
||||
if args.len() > self.arity {
|
||||
todo!()
|
||||
}
|
||||
if self.arity > args.len() {
|
||||
Value::PrimOpApp(Rc::new(PrimOpApp {
|
||||
name: self.name,
|
||||
arity: self.arity - args.len(),
|
||||
args,
|
||||
func: self.func,
|
||||
}))
|
||||
.ok()
|
||||
} else {
|
||||
(self.func)(args, ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PrimOpApp<Ctx: EvalContext> {
|
||||
pub name: &'static str,
|
||||
arity: usize,
|
||||
args: Vec<Value<Ctx>>,
|
||||
func: fn(Vec<Value<Ctx>>, &Ctx) -> Result<Value<Ctx>>,
|
||||
}
|
||||
|
||||
impl<Ctx: EvalContext> Clone for PrimOpApp<Ctx> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
name: self.name,
|
||||
arity: self.arity,
|
||||
args: self.args.clone(),
|
||||
func: self.func,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Ctx: EvalContext> PrimOpApp<Ctx> {
|
||||
pub fn call(self: &mut Rc<Self>, args: Vec<Value<Ctx>>, ctx: &Ctx) -> Result<Value<Ctx>> {
|
||||
if self.arity < args.len() {
|
||||
todo!()
|
||||
}
|
||||
let func = self.func;
|
||||
let Some(ret) = ({
|
||||
let self_mut = Rc::make_mut(self);
|
||||
self_mut.arity -= args.len();
|
||||
self_mut.args.extend(args);
|
||||
if self_mut.arity == 0 {
|
||||
Some(func(std::mem::take(&mut self_mut.args), ctx))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}) else {
|
||||
return Value::PrimOpApp(self.clone()).ok();
|
||||
};
|
||||
ret
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user