forked from Orchid/orchid
bug fixes and performance improvements
This commit is contained in:
@@ -9,11 +9,5 @@ use crate::foreign::Atomic;
|
||||
macro_rules! atomic_defaults {
|
||||
() => {
|
||||
fn as_any(&self) -> &dyn std::any::Any { self }
|
||||
fn definitely_eq(&self, _other: &dyn std::any::Any) -> bool {
|
||||
_other.downcast_ref().map(|o| self == o).unwrap_or(false)
|
||||
}
|
||||
fn hash(&self, mut hasher: &mut dyn std::hash::Hasher) {
|
||||
<Self as std::hash::Hash>::hash(self, &mut hasher)
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -39,66 +39,40 @@ use std::fmt::Debug;
|
||||
#[macro_export]
|
||||
macro_rules! atomic_impl {
|
||||
($typ:ident) => {
|
||||
atomic_impl!{$typ, |this: &Self| Ok(Clause::P(
|
||||
$crate::representations::Primitive::ExternFn(Box::new(this.clone()))
|
||||
))}
|
||||
atomic_impl!{$typ, |this: &Self| {
|
||||
use $crate::foreign::ExternFn;
|
||||
Ok(this.clone().to_xfn_cls())
|
||||
}}
|
||||
};
|
||||
($typ:ident, $next_phase:expr) => {
|
||||
impl $crate::foreign::Atomic for $typ {
|
||||
$crate::atomic_defaults!{}
|
||||
fn run_once(&self) -> Result<
|
||||
$crate::representations::interpreted::Clause,
|
||||
$crate::representations::interpreted::InternalError
|
||||
> {
|
||||
match <Self as AsRef<$crate::representations::interpreted::Clause>>::as_ref(self).run_once() {
|
||||
Err($crate::representations::interpreted::InternalError::NonReducible) => {
|
||||
($next_phase)(self)
|
||||
.map_err($crate::representations::interpreted::RuntimeError::Extern)
|
||||
.map_err($crate::representations::interpreted::InternalError::Runtime)
|
||||
}
|
||||
Ok(arg) => Ok($crate::representations::interpreted::Clause::P(
|
||||
$crate::representations::Primitive::Atom(
|
||||
$crate::foreign::Atom::new(
|
||||
<Self as From<(&Self, Clause)>>::from((self, arg))
|
||||
)
|
||||
|
||||
fn run(&self, ctx: $crate::interpreter::Context)
|
||||
-> $crate::foreign::AtomicResult
|
||||
{
|
||||
// extract the expression
|
||||
let expr = <Self as
|
||||
AsRef<$crate::foreign::RcExpr>
|
||||
>::as_ref(self).clone();
|
||||
// run the expression
|
||||
let ret = $crate::interpreter::run(expr, ctx)?;
|
||||
let $crate::interpreter::Return{ gas, state } = ret;
|
||||
// rebuild the atomic
|
||||
let next_self = <Self as
|
||||
From<(&Self, $crate::foreign::RcExpr)>
|
||||
>::from((self, state));
|
||||
// branch off or wrap up
|
||||
let next_clause = if gas.map(|g| g > 0).unwrap_or(true) {
|
||||
match ($next_phase)(&next_self) {
|
||||
Ok(r) => r,
|
||||
Err(e) => return Err(
|
||||
$crate::interpreter::RuntimeError::Extern(e)
|
||||
)
|
||||
)),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
fn run_n_times(&self, n: usize) -> Result<
|
||||
(
|
||||
$crate::representations::interpreted::Clause,
|
||||
usize
|
||||
),
|
||||
$crate::representations::interpreted::RuntimeError
|
||||
> {
|
||||
match <Self as AsRef<Clause>>::as_ref(self).run_n_times(n) {
|
||||
Ok((arg, k)) if k == n => Ok((Clause::P(
|
||||
$crate::representations::Primitive::Atom(
|
||||
$crate::foreign::Atom::new(
|
||||
<Self as From<(&Self, Clause)>>::from((self, arg))
|
||||
)
|
||||
)
|
||||
), k)),
|
||||
Ok((arg, k)) => {
|
||||
let intermediate = <Self as From<(&Self, Clause)>>::from((self, arg));
|
||||
($next_phase)(&intermediate)
|
||||
.map(|cls| (cls, k))
|
||||
.map_err($crate::representations::interpreted::RuntimeError::Extern)
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
fn run_to_completion(&self) -> Result<Clause, $crate::representations::interpreted::RuntimeError> {
|
||||
match <Self as AsRef<Clause>>::as_ref(self).run_to_completion() {
|
||||
Ok(arg) => {
|
||||
let intermediate = <Self as From<(&Self, Clause)>>::from((self, arg));
|
||||
($next_phase)(&intermediate)
|
||||
.map_err($crate::representations::interpreted::RuntimeError::Extern)
|
||||
},
|
||||
Err(e) => Err(e)
|
||||
}
|
||||
} else { next_self.to_atom_cls() };
|
||||
// package and return
|
||||
Ok((next_clause, gas))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -14,34 +14,11 @@ macro_rules! atomic_inert {
|
||||
($typ:ident) => {
|
||||
impl $crate::foreign::Atomic for $typ {
|
||||
$crate::atomic_defaults!{}
|
||||
fn run_once(&self) -> Result<
|
||||
$crate::representations::interpreted::Clause,
|
||||
$crate::representations::interpreted::InternalError
|
||||
> {
|
||||
Err($crate::representations::interpreted::InternalError::NonReducible)
|
||||
}
|
||||
fn run_n_times(&self, _: usize) -> Result<
|
||||
(
|
||||
$crate::representations::interpreted::Clause,
|
||||
usize
|
||||
),
|
||||
$crate::representations::interpreted::RuntimeError
|
||||
> {
|
||||
Ok(($crate::representations::interpreted::Clause::P(
|
||||
$crate::representations::Primitive::Atom(
|
||||
$crate::foreign::Atom::new(self.clone())
|
||||
)
|
||||
), 0))
|
||||
}
|
||||
fn run_to_completion(&self) -> Result<
|
||||
$crate::representations::interpreted::Clause,
|
||||
$crate::representations::interpreted::RuntimeError
|
||||
> {
|
||||
Ok($crate::representations::interpreted::Clause::P(
|
||||
$crate::representations::Primitive::Atom(
|
||||
$crate::foreign::Atom::new(self.clone())
|
||||
)
|
||||
))
|
||||
|
||||
fn run(&self, ctx: $crate::interpreter::Context)
|
||||
-> $crate::foreign::AtomicResult
|
||||
{
|
||||
Ok((self.clone().to_atom_cls(), ctx.gas))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6,21 +6,23 @@ use super::atomic_impl;
|
||||
#[macro_export]
|
||||
macro_rules! atomic_redirect {
|
||||
($typ:ident) => {
|
||||
impl AsRef<Clause> for $typ {
|
||||
impl AsRef<$crate::foreign::RcExpr> for $typ {
|
||||
fn as_ref(&self) -> &Clause { &self.0 }
|
||||
}
|
||||
impl From<(&Self, Clause)> for $typ {
|
||||
impl From<(&Self, $crate::foreign::RcExpr)> for $typ {
|
||||
fn from((old, clause): (&Self, Clause)) -> Self {
|
||||
Self{ 0: clause, ..old.clone() }
|
||||
}
|
||||
}
|
||||
};
|
||||
($typ:ident, $field:ident) => {
|
||||
impl AsRef<Clause> for $typ {
|
||||
fn as_ref(&self) -> &Clause { &self.$field }
|
||||
impl AsRef<$crate::foreign::RcExpr>
|
||||
for $typ {
|
||||
fn as_ref(&self) -> &$crate::foreign::RcExpr { &self.$field }
|
||||
}
|
||||
impl From<(&Self, Clause)> for $typ {
|
||||
fn from((old, $field): (&Self, Clause)) -> Self {
|
||||
impl From<(&Self, $crate::foreign::RcExpr)>
|
||||
for $typ {
|
||||
fn from((old, $field): (&Self, $crate::foreign::RcExpr)) -> Self {
|
||||
Self{ $field, ..old.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,19 +22,18 @@ macro_rules! externfn_impl {
|
||||
impl $crate::foreign::ExternFn for $typ {
|
||||
fn name(&self) -> &str {stringify!($typ)}
|
||||
fn apply(&self,
|
||||
c: $crate::representations::interpreted::Clause
|
||||
) -> Result<
|
||||
$crate::representations::interpreted::Clause,
|
||||
std::rc::Rc<dyn $crate::foreign::ExternError>
|
||||
> {
|
||||
match ($next_atomic)(self, c) { // ? casts the result but we want to strictly forward it
|
||||
Ok(r) => Ok(
|
||||
arg: $crate::foreign::RcExpr,
|
||||
ctx: $crate::interpreter::Context
|
||||
) -> $crate::foreign::XfnResult {
|
||||
match ($next_atomic)(self, arg) { // ? casts the result but we want to strictly forward it
|
||||
Ok(r) => Ok((
|
||||
$crate::representations::interpreted::Clause::P(
|
||||
$crate::representations::Primitive::Atom(
|
||||
$crate::foreign::Atom::new(r)
|
||||
)
|
||||
)
|
||||
),
|
||||
),
|
||||
ctx.gas.map(|g| g - 1)
|
||||
)),
|
||||
Err(e) => Err(e)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user