Compiles again after command subsystem
Some checks failed
Rust / build (push) Failing after 3m52s

terrified to start testing
This commit is contained in:
2026-03-27 23:50:58 +01:00
parent 09cfcb1839
commit 0909524dee
75 changed files with 1165 additions and 609 deletions

View File

@@ -7,16 +7,15 @@ use orchid_base::{
FmtCtx, FmtUnit, Format, OrcErr, OrcErrv, Pos, Sym, Variants, match_mapping, tl_cache,
};
use crate::api;
use crate::atom::{AtomFactory, AtomicFeatures};
use crate::conv::{ToExpr, ToExprFuture};
use crate::entrypoint::request;
use crate::expr::Expr;
use crate::system::sys_id;
use crate::{AtomFactory, AtomicFeatures, Expr, ToExpr, ToExprFuture, api, request, sys_id};
/// Newly generated AST. Values of this type should not typically be constructed
/// manually but through the helpers in this module
#[derive(Clone, Debug)]
pub struct GExpr {
/// AST node type
pub kind: GExprKind,
/// Code location associated with the expression for debugging purposes
pub pos: Pos,
}
impl GExpr {
@@ -38,7 +37,10 @@ impl GExpr {
}
}
}
/// Reassign location information. The typical default is [Pos::Inherit]
pub fn at(self, pos: Pos) -> Self { GExpr { pos, kind: self.kind } }
/// Send the expression to the interpreter to be compiled and to become
/// shareable across extensions
pub async fn create(self) -> Expr {
Expr::deserialize(request(api::Create(sys_id(), self.serialize().await)).await).await
}
@@ -49,20 +51,36 @@ impl Format for GExpr {
}
}
/// AST nodes recognized by the interpreter
#[derive(Clone, Debug)]
pub enum GExprKind {
/// Function call
Call(Box<GExpr>, Box<GExpr>),
/// Lambda expression. Argument numbers are matched when equal
Lambda(u64, Box<GExpr>),
/// Slot for a lambda argument
Arg(u64),
/// The second expression is only valid after the first one had already been
/// fully normalized. The main use case is the pattern `Lambda(0, Seq(0,
/// Call(foo, 0)))` where foo is an atom that attempts to downcast its
/// argument.
Seq(Box<GExpr>, Box<GExpr>),
/// A reference to a constant from the shared constant tree. It is best to
/// mark the system that provides named constants as a dependency, but this is
/// not required
Const(Sym),
/// A newly created atom. Since at this point the atom needs to be registered
/// inside the extension but doesn't yet have an [api::ExprTicket], atoms need
/// their own [api::Atom::drop] if they have an identity
#[allow(private_interfaces)]
NewAtom(AtomFactory),
/// An expression previously registered or coming from outside the extension
Slot(Expr),
/// A runtime error
Bottom(OrcErrv),
}
impl GExprKind {
pub async fn serialize(self) -> api::ExpressionKind {
async fn serialize(self) -> api::ExpressionKind {
match_mapping!(self, Self => api::ExpressionKind {
Call(
f => Box::new(f.serialize().await),
@@ -117,6 +135,8 @@ impl ToExpr for Sym {
/// Creates an expression from a new atom that we own.
pub fn new_atom<A: AtomicFeatures>(atom: A) -> GExpr { inherit(GExprKind::NewAtom(atom.factory())) }
/// An expression which is only valid if a number of dependencies had already
/// been normalized
pub fn seq(
deps: impl IntoGExprStream,
val: impl ToExpr,
@@ -135,17 +155,24 @@ pub fn seq(
})
}
/// Argument bound by an enclosing [lam] or [dyn_lambda]
pub fn arg(n: u64) -> GExpr { inherit(GExprKind::Arg(n)) }
/// A lambda expression. The difference from [dyn_lambda] is purely aesthetic
pub fn lam<const N: u64>(b: impl ToExpr) -> ToExprFuture<impl Future<Output = GExpr>> {
dyn_lambda(N, b)
}
/// A lambda expression. The difference from [lam] is purely aesthetic
pub fn dyn_lambda(n: u64, b: impl ToExpr) -> ToExprFuture<impl Future<Output = GExpr>> {
ToExprFuture(async move { inherit(GExprKind::Lambda(n, Box::new(b.to_gen().await))) })
}
/// one or more items that are convertible to expressions. In practice, a
/// [ToExpr], [Vec<GExpr>], or a tuple of types that all implement [ToExpr]. For
/// compilation performance, the tuple's arity may not be more than 6
pub trait IntoGExprStream {
/// Convert each item to an expression and return them
fn into_gexpr_stream(self) -> impl Stream<Item = GExpr>;
}
impl<T: ToExpr> IntoGExprStream for T {
@@ -184,6 +211,7 @@ mod tuple_impls {
tuple_impl!(A B C D E F);
}
/// Call a (curried) function
pub fn call(
f: impl ToExpr,
argv: impl IntoGExprStream,
@@ -195,6 +223,7 @@ pub fn call(
})
}
/// Call a function on a dynamic number of arguments
pub fn call_v(
f: impl ToExpr,
argv: impl IntoIterator<Item: ToExpr>,
@@ -208,6 +237,7 @@ pub fn call_v(
})
}
/// A runtime error
pub fn bot(ev: impl IntoIterator<Item = OrcErr>) -> GExpr {
inherit(GExprKind::Bottom(OrcErrv::new(ev).unwrap()))
}