feat: stash

This commit is contained in:
2025-05-10 16:29:55 +08:00
parent 14045f7924
commit f86c088e97
21 changed files with 222 additions and 219 deletions

View File

@@ -1,7 +1,6 @@
use std::cell::RefCell;
use std::sync::Arc;
use anyhow::{Result, anyhow};
use derive_more::{IsVariant, Unwrap};
use super::common as c;
@@ -11,6 +10,7 @@ use super::public as p;
use c::Symbol;
use crate::bytecode::OpCodes;
use crate::error::*;
use crate::vm::{Env, VM};
mod attrset;
@@ -65,9 +65,10 @@ impl Thunk {
match &*self.thunk.borrow() {
_Thunk::Value(value) => return Ok(value.as_ref().clone()),
_Thunk::SuspendedFrom(from) => {
return Err(anyhow!(
"already suspended from {from:p} (infinite recursion encountered)"
));
return Err(Error::EvalError(format!(
"thunk {:p} already suspended from {from:p} (infinite recursion encountered)",
self as *const Thunk
)));
}
_Thunk::Code(_) => (),
}
@@ -77,9 +78,7 @@ impl Thunk {
_Thunk::SuspendedFrom(self as *const Thunk),
)
.unwrap_code();
let value = vm
.eval(opcodes, self.env.borrow().clone().unwrap())
.unwrap();
let value = vm.eval(opcodes, self.env.borrow().clone().unwrap())?;
let _ = std::mem::replace(
&mut *self.thunk.borrow_mut(),
_Thunk::Value(value.clone().into()),
@@ -199,9 +198,9 @@ impl Value {
}
}
pub fn call(self, vm: &VM, args: Vec<Value>) -> Value {
pub fn call(self, vm: &VM, args: Vec<Value>) -> Result<Value> {
use Value::*;
match self {
Ok(match self {
PrimOp(func) => func.call(vm, args),
PartialPrimOp(func) => func.call(vm, args),
mut func @ Value::Func(_) => {
@@ -209,12 +208,12 @@ impl Value {
while let Some(arg) = iter.next() {
func = match func {
PrimOp(func) => {
return func.call(vm, [arg].into_iter().chain(iter).collect());
return Ok(func.call(vm, [arg].into_iter().chain(iter).collect()));
}
PartialPrimOp(func) => {
return func.call(vm, [arg].into_iter().chain(iter).collect());
return Ok(func.call(vm, [arg].into_iter().chain(iter).collect()));
}
Func(func) => func.call(vm, arg),
Func(func) => func.call(vm, arg)?,
_ => todo!(),
}
}
@@ -222,7 +221,7 @@ impl Value {
}
x @ Catchable(_) => x,
_ => todo!(),
}
})
}
pub fn not(self) -> Value {