bug fixes and performance improvements
This commit is contained in:
@@ -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))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user