Added support for defining macros in Rust within the macro system

Also fixed a lot of bugs
This commit is contained in:
2025-09-30 21:23:16 +02:00
parent 7971a2b4eb
commit b77653f841
52 changed files with 849 additions and 502 deletions

View File

@@ -7,12 +7,12 @@ edition = "2024"
[dependencies]
async-fn-stream = { version = "0.1.0", path = "../async-fn-stream" }
async-lock = "3.4.1"
async-once-cell = "0.5.4"
async-process = "2.4.0"
bound = "0.6.0"
derive_destructure = "1.0.0"
futures = { version = "0.3.31", features = ["std"], default-features = false }
futures-locks = "0.7.1"
hashbrown = "0.16.0"
itertools = "0.14.0"
lazy_static = "1.5.0"

View File

@@ -1,7 +1,7 @@
use std::fmt;
use std::rc::{Rc, Weak};
use async_lock::OnceCell;
use async_once_cell::OnceCell;
use derive_destructure::destructure;
use orchid_base::format::{FmtCtx, FmtUnit, Format, take_first_fmt};
use orchid_base::location::Pos;
@@ -85,7 +85,7 @@ impl AtomHand {
}
impl Format for AtomHand {
async fn print<'a>(&'a self, _c: &'a (impl FmtCtx + ?Sized + 'a)) -> FmtUnit {
(self.0.display.get_or_init(|| async {
(self.0.display.get_or_init(async {
FmtUnit::from_api(&self.0.owner.reqnot().request(api::AtomPrint(self.0.api_ref())).await)
}))
.await

View File

@@ -3,7 +3,7 @@ use std::num::{NonZero, NonZeroU16};
use std::rc::{Rc, Weak};
use std::{fmt, ops};
use async_lock::RwLock;
use futures_locks::RwLock;
use hashbrown::HashMap;
use orchid_base::builtin::Spawner;
use orchid_base::interner::Interner;

View File

@@ -48,13 +48,15 @@ pub async fn absolute_path(
) -> Result<VName, AbsPathError> {
let i_self = i.i("self").await;
let i_super = i.i("super").await;
let relative = rel.first().is_some_and(|s| *s != i_self && *s != i_super);
if let Some((_, tail)) = rel.split_first().filter(|(h, _)| **h != i_self) {
let mut relative = false;
if let Some((_, tail)) = rel.split_first().filter(|(h, _)| **h == i_self) {
rel = tail;
relative = true;
} else {
while let Some((_, tail)) = rel.split_first().filter(|(h, _)| **h == i_super) {
cwd = cwd.split_last().ok_or(AbsPathError::TooManySupers)?.1;
rel = tail;
relative = true;
}
}
if relative { VName::new(cwd.iter().chain(rel).cloned()) } else { VName::new(rel.to_vec()) }

View File

@@ -1,8 +1,8 @@
use std::mem;
use async_lock::RwLockWriteGuard;
use bound::Bound;
use futures::FutureExt;
use futures_locks::{RwLockWriteGuard, TryLockError};
use orchid_base::error::OrcErrv;
use orchid_base::format::{FmtCtxImpl, Format, take_first};
use orchid_base::location::Pos;
@@ -12,7 +12,7 @@ use crate::ctx::Ctx;
use crate::expr::{Expr, ExprKind, PathSet, Step};
use crate::tree::Root;
type ExprGuard = Bound<RwLockWriteGuard<'static, ExprKind>, Expr>;
type ExprGuard = Bound<RwLockWriteGuard<ExprKind>, Expr>;
/// The stack operation associated with a transform
enum StackOp {
@@ -76,13 +76,13 @@ impl ExecCtx {
#[must_use]
pub async fn unpack_ident(&self, ex: &Expr) -> Expr {
match ex.kind().try_write().as_deref_mut() {
Some(ExprKind::Identity(ex)) => {
Ok(ExprKind::Identity(ex)) => {
let val = self.unpack_ident(ex).boxed_local().await;
*ex = val.clone();
val
},
Some(_) => ex.clone(),
None => panic!("Cycle encountered!"),
Ok(_) => ex.clone(),
Err(TryLockError) => panic!("Cycle encountered!"),
}
}
pub async fn execute(&mut self) {

View File

@@ -4,8 +4,8 @@ use std::num::NonZeroU64;
use std::rc::{Rc, Weak};
use std::{fmt, mem};
use async_lock::RwLock;
use futures::FutureExt;
use futures_locks::RwLock;
use itertools::Itertools;
use orchid_base::error::OrcErrv;
use orchid_base::format::{FmtCtx, FmtUnit, Format, Variants};
@@ -41,9 +41,9 @@ impl Expr {
pub async fn try_into_owned_atom(self) -> Result<AtomHand, Self> {
match Rc::try_unwrap(self.0) {
Err(e) => Err(Self(e)),
Ok(data) => match data.kind.into_inner() {
Ok(data) => match data.kind.try_unwrap().expect("This fields shouldn't be copied") {
ExprKind::Atom(a) => Ok(a),
inner => Err(Self(Rc::new(ExprData { kind: inner.into(), pos: data.pos }))),
inner => Err(Self(Rc::new(ExprData { kind: RwLock::new(inner), pos: data.pos }))),
},
}
}

View File

@@ -28,6 +28,7 @@ use crate::api;
use crate::atom::AtomHand;
use crate::ctx::Ctx;
use crate::dealias::{ChildError, ChildErrorKind, walk};
use crate::expr::ExprKind;
use crate::expr_store::ExprStore;
use crate::system::SystemCtor;
use crate::tree::MemberKind;
@@ -56,6 +57,7 @@ impl Drop for ExtensionData {
let mut exiting_snd = self.exiting_snd.clone();
(self.ctx.spawn)(Box::pin(async move {
reqnot.notify(api::HostExtNotif::Exit).await;
exiting_snd.send(()).await.unwrap()
}))
}
@@ -247,6 +249,13 @@ impl Extension {
let unit = atom.print(&FmtCtxImpl { i: &this.ctx().i }).await;
hand.handle(eap, &unit.to_api()).await
},
api::ExtHostReq::CreateAtom(ref create @ api::CreateAtom(ref atom, target)) => {
let atom = AtomHand::from_api(atom, Pos::None, &mut ctx.clone()).await;
let target = ctx.system_inst(target).await.expect("Invalid recipient for atom");
let expr = ExprKind::Atom(atom).at(Pos::None);
target.ext().exprs().give_expr(expr.clone());
hand.handle(create, &expr.id()).await
},
}
})
}

View File

@@ -1,4 +1,4 @@
use futures::future::join_all;
use futures::FutureExt;
use itertools::Itertools;
use orchid_base::error::{OrcRes, Reporter, mk_errv};
use orchid_base::format::fmt;
@@ -51,9 +51,14 @@ pub async fn parse_items(
items: ParsSnippet<'_>,
) -> OrcRes<Vec<Item>> {
let lines = line_items(ctx, items).await;
let line_res =
join_all(lines.into_iter().map(|p| parse_item(ctx, path.clone(), p.output, p.tail))).await;
Ok(line_res.into_iter().flat_map(|l| l.ok().into_iter().flatten()).collect())
let mut line_ok = Vec::new();
for Parsed { output: comments, tail } in lines {
match parse_item(ctx, path.clone(), comments, tail).boxed_local().await {
Err(e) => ctx.rep().report(e),
Ok(l) => line_ok.extend(l),
}
}
Ok(line_ok)
}
pub async fn parse_item(

View File

@@ -93,13 +93,14 @@ async fn conv(
},
};
let name = ctx.i.ex(name).await;
let mem_path = module.push(name.clone());
let mkind = match kind {
api::ParsedMemberKind::Module { lines, use_prelude } => {
let items = conv(lines, module.push(name.clone()), callback, ctx).boxed_local().await?;
let items = conv(lines, mem_path, callback, ctx).boxed_local().await?;
ParsedMemberKind::Mod(ParsedModule::new(use_prelude, items))
},
api::ParsedMemberKind::Constant(cid) => {
ctx.sys.0.const_paths.insert(cid, ctx.mod_path.suffix(module.unreverse(), ctx.i).await);
ctx.sys.0.const_paths.insert(cid, ctx.mod_path.suffix(mem_path.unreverse(), ctx.i).await);
ParsedMemberKind::Const(cid, ctx.sys.clone())
},
};

View File

@@ -3,9 +3,9 @@ use std::fmt;
use std::future::Future;
use std::rc::{Rc, Weak};
use async_lock::RwLock;
use derive_destructure::destructure;
use futures::future::join_all;
use futures_locks::RwLock;
use hashbrown::HashMap;
use itertools::Itertools;
use memo_map::MemoMap;
@@ -163,6 +163,9 @@ impl System {
)),
None => (),
}
if root_data.root.members.get(selector).is_some() {
return Ok(VName::new(rel.iter().cloned()).expect("split_first was called above"));
}
if tail.is_empty() {
return Ok(VPath::new(cwd.iter().cloned()).name_with_suffix(selector.clone()));
}

View File

@@ -4,10 +4,10 @@ use std::cell::RefCell;
use std::rc::{Rc, Weak};
use std::slice;
use async_lock::RwLock;
use async_once_cell::OnceCell;
use derive_destructure::destructure;
use futures::{FutureExt, StreamExt, stream};
use futures_locks::RwLock;
use hashbrown::HashMap;
use hashbrown::hash_map::Entry;
use itertools::Itertools;