forked from Orchid/orchid
pre-recording backup
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
use crate::foreign::AtomicReturn;
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::foreign::{AtomicReturn, Atomic, ExternError, Atom};
|
||||
use crate::representations::Primitive;
|
||||
use crate::representations::interpreted::{Clause, ExprInst};
|
||||
|
||||
@@ -6,9 +9,10 @@ use super::apply::apply;
|
||||
use super::error::RuntimeError;
|
||||
use super::context::{Context, Return};
|
||||
|
||||
pub fn run(expr: ExprInst, mut ctx: Context)
|
||||
-> Result<Return, RuntimeError>
|
||||
{
|
||||
pub fn run(
|
||||
expr: ExprInst,
|
||||
mut ctx: Context
|
||||
) -> Result<Return, RuntimeError> {
|
||||
let (state, (gas, inert)) = expr.try_normalize(|cls| -> Result<(Clause, _), RuntimeError> {
|
||||
let mut i = cls.clone();
|
||||
while ctx.gas.map(|g| g > 0).unwrap_or(true) {
|
||||
@@ -39,4 +43,67 @@ pub fn run(expr: ExprInst, mut ctx: Context)
|
||||
Ok((i, (ctx.gas, false)))
|
||||
})?;
|
||||
Ok(Return { state, gas, inert })
|
||||
}
|
||||
|
||||
pub type HandlerParm = Box<dyn Atomic>;
|
||||
pub type HandlerRes = Result<
|
||||
Result<ExprInst, Rc<dyn ExternError>>,
|
||||
HandlerParm
|
||||
>;
|
||||
|
||||
pub trait Handler {
|
||||
fn resolve(&mut self, data: HandlerParm) -> HandlerRes;
|
||||
|
||||
fn then<T: Handler>(self, t: T) -> impl Handler
|
||||
where Self: Sized {
|
||||
Pair(self, t)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F> Handler for F
|
||||
where F: FnMut(HandlerParm) -> HandlerRes
|
||||
{
|
||||
fn resolve(&mut self, data: HandlerParm) -> HandlerRes {
|
||||
self(data)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Pair<T, U>(T, U);
|
||||
|
||||
impl<T: Handler, U: Handler> Handler for Pair<T, U> {
|
||||
fn resolve(&mut self, data: HandlerParm) -> HandlerRes {
|
||||
match self.0.resolve(data) {
|
||||
Ok(out) => Ok(out),
|
||||
Err(data) => self.1.resolve(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_handler(
|
||||
mut expr: ExprInst,
|
||||
mut handler: impl Handler,
|
||||
mut ctx: Context
|
||||
) -> Result<Return, RuntimeError> {
|
||||
loop {
|
||||
let ret = run(expr.clone(), ctx.clone())?;
|
||||
if ret.gas == Some(0) {
|
||||
return Ok(ret)
|
||||
}
|
||||
let state_ex = ret.state.expr();
|
||||
let a = if let Clause::P(Primitive::Atom(a)) = &state_ex.clause {a}
|
||||
else {
|
||||
mem::drop(state_ex);
|
||||
return Ok(ret)
|
||||
};
|
||||
let boxed = a.clone().0;
|
||||
expr = match handler.resolve(boxed) {
|
||||
Ok(r) => r.map_err(RuntimeError::Extern)?,
|
||||
Err(e) => return Ok(Return{
|
||||
gas: ret.gas,
|
||||
inert: ret.inert,
|
||||
state: Clause::P(Primitive::Atom(Atom(e))).wrap()
|
||||
})
|
||||
};
|
||||
ctx.gas = ret.gas;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user