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:
2026-03-13 16:48:42 +01:00
parent cdcca694c5
commit 09cfcb1839
146 changed files with 3582 additions and 2822 deletions

View File

@@ -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;