forked from Orchid/orchid
temp commit
This commit is contained in:
@@ -10,6 +10,7 @@ use orchid_base::logging::Logger;
|
||||
|
||||
use crate::ctx::Ctx;
|
||||
use crate::expr::{Expr, ExprKind, ExprParseCtx, PathSet, PathSetBuilder, Step};
|
||||
use crate::tree::Root;
|
||||
|
||||
type ExprGuard = Bound<RwLockWriteGuard<'static, ExprKind>, Expr>;
|
||||
|
||||
@@ -36,16 +37,21 @@ pub struct ExecCtx {
|
||||
cur_pos: Pos,
|
||||
did_pop: bool,
|
||||
logger: Logger,
|
||||
root: Root,
|
||||
}
|
||||
impl ExecCtx {
|
||||
pub async fn new(ctx: Ctx, logger: Logger, init: Expr) -> Self {
|
||||
#[must_use]
|
||||
pub async fn new(ctx: Ctx, logger: Logger, root: Root, init: Expr) -> Self {
|
||||
let cur_pos = init.pos();
|
||||
let cur = Bound::async_new(init, |init| init.kind().write()).await;
|
||||
Self { ctx, gas: None, stack: vec![], cur, cur_pos, did_pop: false, logger }
|
||||
Self { ctx, gas: None, stack: vec![], cur, cur_pos, did_pop: false, logger, root }
|
||||
}
|
||||
#[must_use]
|
||||
pub fn remaining_gas(&self) -> u64 { self.gas.expect("queried remaining_gas but no gas was set") }
|
||||
pub fn set_gas(&mut self, gas: Option<u64>) { self.gas = gas }
|
||||
#[must_use]
|
||||
pub fn idle(&self) -> bool { self.did_pop }
|
||||
#[must_use]
|
||||
pub fn result(self) -> ExecResult {
|
||||
if self.idle() {
|
||||
match &*self.cur {
|
||||
@@ -56,15 +62,18 @@ impl ExecCtx {
|
||||
ExecResult::Gas(self)
|
||||
}
|
||||
}
|
||||
#[must_use]
|
||||
pub fn use_gas(&mut self, amount: u64) -> bool {
|
||||
if let Some(gas) = &mut self.gas {
|
||||
*gas -= amount;
|
||||
}
|
||||
self.gas != Some(0)
|
||||
}
|
||||
#[must_use]
|
||||
pub async fn try_lock(&self, ex: &Expr) -> ExprGuard {
|
||||
Bound::async_new(ex.clone(), |ex| ex.kind().write()).await
|
||||
}
|
||||
#[must_use]
|
||||
pub async fn unpack_ident(&self, ex: &Expr) -> Expr {
|
||||
match ex.kind().try_write().as_deref_mut() {
|
||||
Some(ExprKind::Identity(ex)) => {
|
||||
@@ -89,14 +98,11 @@ impl ExecCtx {
|
||||
},
|
||||
ExprKind::Seq(a, b) if !self.did_pop => (ExprKind::Seq(a.clone(), b), StackOp::Push(a)),
|
||||
ExprKind::Seq(_, b) => (ExprKind::Identity(b), StackOp::Nop),
|
||||
ExprKind::Const(name) => {
|
||||
let root = (self.ctx.root.get().and_then(|v| v.upgrade()))
|
||||
.expect("Root not assigned before execute call");
|
||||
match root.get_const_value(name, self.cur_pos.clone(), self.ctx.clone()).await {
|
||||
ExprKind::Const(name) =>
|
||||
match self.root.get_const_value(name, self.cur_pos.clone()).await {
|
||||
Err(e) => (ExprKind::Bottom(e), StackOp::Pop),
|
||||
Ok(v) => (ExprKind::Identity(v), StackOp::Nop),
|
||||
}
|
||||
},
|
||||
},
|
||||
ExprKind::Arg => panic!("This should not appear outside function bodies"),
|
||||
ek @ ExprKind::Atom(_) => (ek, StackOp::Pop),
|
||||
ExprKind::Bottom(bot) => (ExprKind::Bottom(bot.clone()), StackOp::Unwind(bot)),
|
||||
@@ -105,7 +111,7 @@ impl ExecCtx {
|
||||
Ok(atom) => {
|
||||
let ext = atom.sys().ext().clone();
|
||||
let x_norm = self.unpack_ident(&x).await;
|
||||
let mut parse_ctx = ExprParseCtx { ctx: self.ctx.clone(), exprs: ext.exprs().clone() };
|
||||
let mut parse_ctx = ExprParseCtx { ctx: &self.ctx, exprs: ext.exprs() };
|
||||
let val =
|
||||
Expr::from_api(&atom.call(x_norm).await, PathSetBuilder::new(), &mut parse_ctx).await;
|
||||
(ExprKind::Identity(val.clone()), StackOp::Swap(val))
|
||||
@@ -117,12 +123,10 @@ impl ExecCtx {
|
||||
ExprKind::Atom(a) => {
|
||||
let ext = a.sys().ext().clone();
|
||||
let x_norm = self.unpack_ident(&x).await;
|
||||
let mut parse_ctx =
|
||||
ExprParseCtx { ctx: ext.ctx().clone(), exprs: ext.exprs().clone() };
|
||||
let val = Expr::from_api(
|
||||
&a.clone().call(x_norm).await,
|
||||
PathSetBuilder::new(),
|
||||
&mut parse_ctx,
|
||||
&mut ExprParseCtx { ctx: ext.ctx(), exprs: ext.exprs() },
|
||||
)
|
||||
.await;
|
||||
(ExprKind::Identity(val.clone()), StackOp::Swap(val))
|
||||
@@ -168,6 +172,7 @@ impl ExecCtx {
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
async fn substitute(
|
||||
src: &Expr,
|
||||
path: &[Step],
|
||||
|
||||
Reference in New Issue
Block a user