bug fixes and performance improvements

This commit is contained in:
2023-05-07 22:35:38 +01:00
parent f3ce910f66
commit a604e40bad
167 changed files with 5965 additions and 4229 deletions

View File

@@ -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)
}
};
}

View File

@@ -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))
}
}
};

View File

@@ -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))
}
}
};

View File

@@ -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() }
}
}

View File

@@ -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)
}
}