chore: fmt
This commit is contained in:
@@ -45,7 +45,18 @@ impl<'vm> AttrSet<'vm> {
|
|||||||
self.data = self
|
self.data = self
|
||||||
.data
|
.data
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(k, v)| (k.clone(), match v.clone() { x @ Value::ThunkRef(thunk) => { thunk.capture(env.clone()); x }, x => x }))
|
.map(|(k, v)| {
|
||||||
|
(
|
||||||
|
k.clone(),
|
||||||
|
match v.clone() {
|
||||||
|
x @ Value::ThunkRef(thunk) => {
|
||||||
|
thunk.capture(env.clone());
|
||||||
|
x
|
||||||
|
}
|
||||||
|
x => x,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +110,7 @@ impl ToPublic for AttrSet<'_> {
|
|||||||
|
|
||||||
#[derive(Debug, Constructor, Clone, PartialEq)]
|
#[derive(Debug, Constructor, Clone, PartialEq)]
|
||||||
pub struct RecAttrSet<'vm> {
|
pub struct RecAttrSet<'vm> {
|
||||||
data: Rc<Env<'vm>>
|
data: Rc<Env<'vm>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'vm> RecAttrSet<'vm> {
|
impl<'vm> RecAttrSet<'vm> {
|
||||||
@@ -178,7 +189,8 @@ impl<'vm> RecAttrSet<'vm> {
|
|||||||
impl ToPublic for RecAttrSet<'_> {
|
impl ToPublic for RecAttrSet<'_> {
|
||||||
fn to_public(self, vm: &VM) -> p::Value {
|
fn to_public(self, vm: &VM) -> p::Value {
|
||||||
p::Value::AttrSet(p::AttrSet::new(
|
p::Value::AttrSet(p::AttrSet::new(
|
||||||
self.data.map
|
self.data
|
||||||
|
.map
|
||||||
.borrow()
|
.borrow()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(sym, value)| (sym.clone(), value.clone().to_public(vm)))
|
.map(|(sym, value)| (sym.clone(), value.clone().to_public(vm)))
|
||||||
|
|||||||
@@ -25,77 +25,6 @@ pub use func::*;
|
|||||||
pub use list::List;
|
pub use list::List;
|
||||||
pub use primop::*;
|
pub use primop::*;
|
||||||
|
|
||||||
pub trait ToPublic {
|
|
||||||
fn to_public(self, vm: &VM) -> p::Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Thunk<'vm> {
|
|
||||||
pub thunk: RefCell<_Thunk<'vm>>,
|
|
||||||
pub env: RefCell<Option<Rc<Env<'vm>>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, IsVariant, Unwrap, Clone)]
|
|
||||||
pub enum _Thunk<'vm> {
|
|
||||||
Code(OpCodes),
|
|
||||||
SuspendedFrom(*const Thunk<'vm>),
|
|
||||||
Value(Box<Value<'vm>>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'vm> Thunk<'vm> {
|
|
||||||
pub fn new(opcodes: OpCodes) -> Self {
|
|
||||||
Thunk {
|
|
||||||
thunk: RefCell::new(_Thunk::Code(opcodes)),
|
|
||||||
env: RefCell::new(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unwrap_code(&self) -> OpCodes {
|
|
||||||
self.thunk.borrow().clone().unwrap_code()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn capture(&self, env: Rc<Env<'vm>>) {
|
|
||||||
*self.env.borrow_mut() = Some(env);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn force(&self, vm: &VM<'vm>) -> Result<Value<'vm>> {
|
|
||||||
match &*self.thunk.borrow() {
|
|
||||||
_Thunk::Value(value) => return Ok(value.as_ref().clone()),
|
|
||||||
_Thunk::SuspendedFrom(from) => {
|
|
||||||
return Err(Error::EvalError(format!(
|
|
||||||
"thunk {:p} already suspended from {from:p} (infinite recursion encountered)",
|
|
||||||
self as *const Thunk
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
_Thunk::Code(_) => (),
|
|
||||||
}
|
|
||||||
let opcodes = std::mem::replace(
|
|
||||||
&mut *self.thunk.borrow_mut(),
|
|
||||||
_Thunk::SuspendedFrom(self as *const Thunk),
|
|
||||||
)
|
|
||||||
.unwrap_code();
|
|
||||||
let value = vm.eval(opcodes, self.env.borrow().clone().unwrap())?;
|
|
||||||
let _ = std::mem::replace(
|
|
||||||
&mut *self.thunk.borrow_mut(),
|
|
||||||
_Thunk::Value(value.clone().into()),
|
|
||||||
);
|
|
||||||
Ok(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn value(&'vm self) -> Option<Value<'vm>> {
|
|
||||||
match &*self.thunk.borrow() {
|
|
||||||
_Thunk::Value(value) => Some(value.as_ref().clone()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq for Thunk<'_> {
|
|
||||||
fn eq(&self, _: &Self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, IsVariant, Unwrap, Clone, PartialEq)]
|
#[derive(Debug, IsVariant, Unwrap, Clone, PartialEq)]
|
||||||
pub enum Value<'vm> {
|
pub enum Value<'vm> {
|
||||||
Const(Const),
|
Const(Const),
|
||||||
@@ -484,3 +413,74 @@ impl ToPublic for Value<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait ToPublic {
|
||||||
|
fn to_public(self, vm: &VM) -> p::Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Thunk<'vm> {
|
||||||
|
pub thunk: RefCell<_Thunk<'vm>>,
|
||||||
|
pub env: RefCell<Option<Rc<Env<'vm>>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, IsVariant, Unwrap, Clone)]
|
||||||
|
pub enum _Thunk<'vm> {
|
||||||
|
Code(OpCodes),
|
||||||
|
SuspendedFrom(*const Thunk<'vm>),
|
||||||
|
Value(Box<Value<'vm>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'vm> Thunk<'vm> {
|
||||||
|
pub fn new(opcodes: OpCodes) -> Self {
|
||||||
|
Thunk {
|
||||||
|
thunk: RefCell::new(_Thunk::Code(opcodes)),
|
||||||
|
env: RefCell::new(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unwrap_code(&self) -> OpCodes {
|
||||||
|
self.thunk.borrow().clone().unwrap_code()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn capture(&self, env: Rc<Env<'vm>>) {
|
||||||
|
*self.env.borrow_mut() = Some(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn force(&self, vm: &VM<'vm>) -> Result<Value<'vm>> {
|
||||||
|
match &*self.thunk.borrow() {
|
||||||
|
_Thunk::Value(value) => return Ok(value.as_ref().clone()),
|
||||||
|
_Thunk::SuspendedFrom(from) => {
|
||||||
|
return Err(Error::EvalError(format!(
|
||||||
|
"thunk {:p} already suspended from {from:p} (infinite recursion encountered)",
|
||||||
|
self as *const Thunk
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
_Thunk::Code(_) => (),
|
||||||
|
}
|
||||||
|
let opcodes = std::mem::replace(
|
||||||
|
&mut *self.thunk.borrow_mut(),
|
||||||
|
_Thunk::SuspendedFrom(self as *const Thunk),
|
||||||
|
)
|
||||||
|
.unwrap_code();
|
||||||
|
let value = vm.eval(opcodes, self.env.borrow().clone().unwrap())?;
|
||||||
|
let _ = std::mem::replace(
|
||||||
|
&mut *self.thunk.borrow_mut(),
|
||||||
|
_Thunk::Value(value.clone().into()),
|
||||||
|
);
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn value(&'vm self) -> Option<Value<'vm>> {
|
||||||
|
match &*self.thunk.borrow() {
|
||||||
|
_Thunk::Value(value) => Some(value.as_ref().clone()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for Thunk<'_> {
|
||||||
|
fn eq(&self, _: &Self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -86,8 +86,7 @@ impl<'vm> VM<'vm> {
|
|||||||
opcode: OpCode,
|
opcode: OpCode,
|
||||||
stack: &'s mut Stack<'vm, CAP>,
|
stack: &'s mut Stack<'vm, CAP>,
|
||||||
env: &Rc<Env<'vm>>,
|
env: &Rc<Env<'vm>>,
|
||||||
) -> Result<usize>
|
) -> Result<usize> {
|
||||||
{
|
|
||||||
match opcode {
|
match opcode {
|
||||||
OpCode::Illegal => panic!("illegal opcode"),
|
OpCode::Illegal => panic!("illegal opcode"),
|
||||||
OpCode::Const { value } => stack.push(Value::Const(value))?,
|
OpCode::Const { value } => stack.push(Value::Const(value))?,
|
||||||
@@ -170,8 +169,12 @@ impl<'vm> VM<'vm> {
|
|||||||
}
|
}
|
||||||
OpCode::FinalizeRec => {
|
OpCode::FinalizeRec => {
|
||||||
env.enter(stack.tos()?.clone().unwrap_attr_set().into_inner());
|
env.enter(stack.tos()?.clone().unwrap_attr_set().into_inner());
|
||||||
stack.tos_mut()?.as_mut().unwrap_attr_set().capture(env.clone());
|
stack
|
||||||
},
|
.tos_mut()?
|
||||||
|
.as_mut()
|
||||||
|
.unwrap_attr_set()
|
||||||
|
.capture(env.clone());
|
||||||
|
}
|
||||||
OpCode::PushStaticAttr { name } => {
|
OpCode::PushStaticAttr { name } => {
|
||||||
let val = stack.pop();
|
let val = stack.pop();
|
||||||
stack.tos_mut()?.push_attr(Symbol::new(name.clone()), val);
|
stack.tos_mut()?.push_attr(Symbol::new(name.clone()), val);
|
||||||
|
|||||||
Reference in New Issue
Block a user