Fixing some showstoppers

- inertness now tracked separately from gas
- atomic_impl now correctly rolls over when the argument is inert
- syntax fixes
- tree shaking
This commit is contained in:
2023-05-08 20:27:52 +01:00
parent a604e40bad
commit 6a381c5b57
28 changed files with 112 additions and 445 deletions

View File

@@ -1,4 +1,4 @@
use crate::foreign::Atom;
use crate::foreign::AtomicReturn;
use crate::representations::Primitive;
use crate::representations::interpreted::{Clause, ExprInst};
@@ -9,19 +9,20 @@ use super::context::{Context, Return};
pub fn run(expr: ExprInst, mut ctx: Context)
-> Result<Return, RuntimeError>
{
let state = expr.try_normalize(|cls| -> Result<Clause, 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) {
match &i {
Clause::Apply { f, x } => {
let res = apply(f.clone(), x.clone(), ctx.clone())?;
if ctx.is_stuck(res.gas) {return Ok(i)}
if res.inert {return Ok((i, (res.gas, true)))}
ctx.gas = res.gas;
i = res.state.expr().clause.clone();
}
Clause::P(Primitive::Atom(Atom(data))) => {
let (clause, gas) = data.run(ctx.clone())?;
if ctx.is_stuck(gas) {return Ok(i)}
Clause::P(Primitive::Atom(data)) => {
let ret = data.run(ctx.clone())?;
let AtomicReturn { clause, gas, inert } = ret;
if inert {return Ok((i, (gas, true)))}
ctx.gas = gas;
i = clause.clone();
}
@@ -30,10 +31,12 @@ pub fn run(expr: ExprInst, mut ctx: Context)
ctx.gas = ctx.gas.map(|g| g - 1); // cost of lookup
i = symval.expr().clause.clone();
}
_ => return Ok(i)
// non-reducible
_ => return Ok((i, (ctx.gas, true)))
}
}
Ok(i)
// out of gas
Ok((i, (ctx.gas, false)))
})?;
Ok(Return { state, gas: ctx.gas })
Ok(Return { state, gas, inert })
}