Backup commit

My backspace key started ghosting. Nothing works atm.
This commit is contained in:
2024-01-27 14:50:33 +00:00
parent f77e4fd90a
commit a8887227e5
236 changed files with 10946 additions and 8977 deletions

View File

@@ -1,45 +1,101 @@
use std::collections::VecDeque;
use hashbrown::HashMap;
use super::apply::apply;
use super::context::{Context, Return};
use super::error::RuntimeError;
use crate::foreign::AtomicReturn;
use crate::representations::interpreted::{Clause, ExprInst};
use super::context::{Halt, RunContext};
use super::error::RunError;
use super::nort::{Clause, Expr};
use crate::foreign::atom::AtomicReturn;
use crate::foreign::error::ExternResult;
use crate::location::CodeLocation;
use crate::name::Sym;
use crate::utils::pure_seq::pushed;
/// Information about a normalization run presented to an atom
#[derive(Clone)]
pub struct RunData<'a> {
/// Location of the atom
pub location: CodeLocation,
/// Information about the execution
pub ctx: RunContext<'a>,
}
#[derive(Debug)]
pub struct Interrupted {
stack: Vec<Expr>,
}
impl Interrupted {
pub fn resume(self, ctx: RunContext) -> Result<Halt, RunError> {
run_stack(self.stack, ctx)
}
}
/// Normalize an expression using beta reduction with memoization
pub fn run(expr: ExprInst, mut ctx: Context) -> Result<Return, RuntimeError> {
let (state, (gas, inert)) = expr.try_normalize(
|mut cls, loc| -> Result<(Clause, _), RuntimeError> {
while ctx.gas.map(|g| g > 0).unwrap_or(true) {
pub fn run(mut expr: Expr, mut ctx: RunContext) -> Result<Halt, RunError> {
run_stack(vec![expr], ctx)
}
fn run_stack(
mut stack: Vec<Expr>,
mut ctx: RunContext,
) -> Result<Halt, RunError> {
let mut expr = stack.pop().expect("Empty stack");
loop {
if ctx.no_gas() {
return Err(RunError::Interrupted(Interrupted {
stack: pushed(stack, expr),
}));
}
let (next_clsi, inert) = expr.clause.try_normalize(|mut cls| {
loop {
if ctx.no_gas() {
return Ok((cls, false));
}
match cls {
cls @ Clause::Identity(_) => return Ok((cls, false)),
// TODO:
// - unfuck nested loop
// - inline most of [apply] to eliminate recursion step
Clause::Apply { f, x } => {
let res = apply(f, x, ctx.clone())?;
if res.inert {
return Ok((res.state.expr_val().clause, (res.gas, true)));
if x.is_empty() {
return Ok((f.clause.into_cls(), false));
}
ctx.gas = res.gas;
cls = res.state.expr().clause.clone();
let (gas, clause) = apply(f, x, ctx.clone())?;
if ctx.gas.is_some() {
ctx.gas = gas;
}
cls = clause;
},
Clause::Atom(data) => {
let AtomicReturn { clause, gas, inert } = data.run(ctx.clone())?;
if inert {
return Ok((clause, (gas, true)));
let run = RunData { ctx: ctx.clone(), location: expr.location() };
let atomic_ret = data.run(run)?;
if ctx.gas.is_some() {
ctx.gas = atomic_ret.gas;
}
ctx.gas = gas;
cls = clause;
if atomic_ret.inert {
return Ok((atomic_ret.clause, true));
}
cls = atomic_ret.clause;
},
Clause::Constant(c) => {
let symval = (ctx.symbols.get(&c)).ok_or_else(|| {
RuntimeError::MissingSymbol(c.clone(), loc.clone())
RunError::MissingSymbol(c.clone(), expr.location())
})?;
ctx.gas = ctx.gas.map(|g| g - 1); // cost of lookup
cls = symval.expr().clause.clone();
cls = Clause::Identity(symval.clause.clone());
},
// non-reducible
_ => return Ok((cls, (ctx.gas, true))),
}
c => return Ok((c, true)),
};
}
// out of gas
Ok((cls, (ctx.gas, false)))
},
)?;
Ok(Return { state, gas, inert })
})?;
expr.clause = next_clsi;
if inert {
match stack.pop() {
Some(e) => expr = e,
None => return Ok(Halt { state: expr, gas: ctx.gas, inert }),
}
}
}
}