partway towards commands
I got very confused and started mucking about with "spawn" when in fact all I needed was the "inline" extension type in orcx that allows the interpreter to expose custom constants.
This commit is contained in:
@@ -7,12 +7,10 @@ use std::{fmt, mem};
|
||||
use futures::FutureExt;
|
||||
use futures_locks::RwLock;
|
||||
use itertools::Itertools;
|
||||
use orchid_base::error::OrcErrv;
|
||||
use orchid_base::format::{FmtCtx, FmtUnit, Format, Variants};
|
||||
use orchid_base::location::{Pos, SrcRange};
|
||||
use orchid_base::name::Sym;
|
||||
use orchid_base::tl_cache;
|
||||
use orchid_base::tree::{AtomRepr, TokenVariant, indent};
|
||||
use orchid_base::{
|
||||
AtomRepr, FmtCtx, FmtUnit, Format, OrcErrv, Pos, SrcRange, Sym, TokenVariant, Variants, indent,
|
||||
tl_cache,
|
||||
};
|
||||
use substack::Substack;
|
||||
|
||||
use crate::api;
|
||||
@@ -26,6 +24,12 @@ pub struct ExprData {
|
||||
kind: RwLock<ExprKind>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ExprFromApiCtx {
|
||||
pub sys: api::SysId,
|
||||
pub ctx: Ctx,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Expr(Rc<ExprData>);
|
||||
impl Expr {
|
||||
@@ -54,35 +58,40 @@ impl Expr {
|
||||
)
|
||||
}
|
||||
#[must_use]
|
||||
pub async fn from_api(api: &api::Expression, psb: PathSetBuilder<'_, u64>, ctx: Ctx) -> Self {
|
||||
pub async fn from_api(
|
||||
api: api::Expression,
|
||||
psb: PathSetBuilder<'_, u64>,
|
||||
ctx: ExprFromApiCtx,
|
||||
) -> Self {
|
||||
let pos = Pos::from_api(&api.location).await;
|
||||
let kind = match &api.kind {
|
||||
let kind = match api.kind {
|
||||
api::ExpressionKind::Arg(n) => {
|
||||
assert!(psb.register_arg(n), "Arguments must be enclosed in a matching lambda");
|
||||
assert!(psb.register_arg(&n), "Arguments must be enclosed in a matching lambda");
|
||||
ExprKind::Arg
|
||||
},
|
||||
api::ExpressionKind::Bottom(bot) => ExprKind::Bottom(OrcErrv::from_api(bot).await),
|
||||
api::ExpressionKind::Call(f, x) => {
|
||||
let (lpsb, rpsb) = psb.split();
|
||||
ExprKind::Call(
|
||||
Expr::from_api(f, lpsb, ctx.clone()).boxed_local().await,
|
||||
Expr::from_api(x, rpsb, ctx).boxed_local().await,
|
||||
Expr::from_api(*f, lpsb, ctx.clone()).boxed_local().await,
|
||||
Expr::from_api(*x, rpsb, ctx).boxed_local().await,
|
||||
)
|
||||
},
|
||||
api::ExpressionKind::Const(name) => ExprKind::Const(Sym::from_api(*name).await),
|
||||
api::ExpressionKind::Const(name) => ExprKind::Const(Sym::from_api(name).await),
|
||||
api::ExpressionKind::Lambda(x, body) => {
|
||||
let lbuilder = psb.lambda(x);
|
||||
let body = Expr::from_api(body, lbuilder.stack(), ctx).boxed_local().await;
|
||||
let lbuilder = psb.lambda(&x);
|
||||
let body = Expr::from_api(*body, lbuilder.stack(), ctx).boxed_local().await;
|
||||
ExprKind::Lambda(lbuilder.collect(), body)
|
||||
},
|
||||
api::ExpressionKind::NewAtom(a) =>
|
||||
ExprKind::Atom(AtomHand::from_api(a, pos.clone(), &mut ctx.clone()).await),
|
||||
api::ExpressionKind::Slot(tk) => return ctx.exprs.take_expr(*tk).expect("Invalid slot"),
|
||||
api::ExpressionKind::NewAtom(a) => ExprKind::Atom(
|
||||
AtomHand::from_api(&a.associate(ctx.sys), pos.clone(), &mut ctx.ctx.clone()).await,
|
||||
),
|
||||
api::ExpressionKind::Slot(tk) => return ctx.ctx.exprs.take_expr(tk).expect("Invalid slot"),
|
||||
api::ExpressionKind::Seq(a, b) => {
|
||||
let (apsb, bpsb) = psb.split();
|
||||
ExprKind::Seq(
|
||||
Expr::from_api(a, apsb, ctx.clone()).boxed_local().await,
|
||||
Expr::from_api(b, bpsb, ctx).boxed_local().await,
|
||||
Expr::from_api(*a, apsb, ctx.clone()).boxed_local().await,
|
||||
Expr::from_api(*b, bpsb, ctx).boxed_local().await,
|
||||
)
|
||||
},
|
||||
};
|
||||
@@ -159,8 +168,10 @@ async fn print_exprkind<'a>(
|
||||
panic!("This variant is swapped into write guards, so a read can never see it")
|
||||
},
|
||||
ExprKind::Atom(a) => a.print(c).await,
|
||||
ExprKind::Bottom(e) if e.len() == 1 => format!("Bottom({e})").into(),
|
||||
ExprKind::Bottom(e) => format!("Bottom(\n\t{}\n)", indent(&e.to_string())).into(),
|
||||
ExprKind::Bottom(e) => match e.one() {
|
||||
Some(e) => format!("Bottom({e})").into(),
|
||||
None => format!("Bottom(\n\t{}\n)", indent(&e.to_string())).into(),
|
||||
},
|
||||
ExprKind::Call(f, x) => tl_cache!(Rc<Variants>: Rc::new(Variants::default()
|
||||
.unbounded("{0b} {1l}")
|
||||
.bounded("({0b} {1})")))
|
||||
@@ -333,8 +344,8 @@ impl WeakExpr {
|
||||
|
||||
impl TokenVariant<api::ExprTicket> for Expr {
|
||||
type FromApiCtx<'a> = ExprStore;
|
||||
async fn from_api(api: &api::ExprTicket, ctx: &mut Self::FromApiCtx<'_>, _: SrcRange) -> Self {
|
||||
ctx.get_expr(*api).expect("Invalid ticket")
|
||||
async fn from_api(api: api::ExprTicket, ctx: &mut Self::FromApiCtx<'_>, _: SrcRange) -> Self {
|
||||
ctx.get_expr(api).expect("Invalid ticket")
|
||||
}
|
||||
type ToApiCtx<'a> = ExprStore;
|
||||
async fn into_api(self, ctx: &mut Self::ToApiCtx<'_>) -> api::ExprTicket {
|
||||
@@ -349,8 +360,8 @@ impl TokenVariant<api::ExprTicket> for Expr {
|
||||
pub struct ExprWillPanic;
|
||||
|
||||
impl TokenVariant<api::Expression> for Expr {
|
||||
type FromApiCtx<'a> = Ctx;
|
||||
async fn from_api(api: &api::Expression, ctx: &mut Self::FromApiCtx<'_>, _: SrcRange) -> Self {
|
||||
type FromApiCtx<'a> = ExprFromApiCtx;
|
||||
async fn from_api(api: api::Expression, ctx: &mut Self::FromApiCtx<'_>, _: SrcRange) -> Self {
|
||||
Self::from_api(api, PathSetBuilder::new(), ctx.clone()).await
|
||||
}
|
||||
type ToApiCtx<'a> = ExprWillPanic;
|
||||
|
||||
Reference in New Issue
Block a user