forked from Orchid/orchid
Added support for defining macros in Rust within the macro system
Also fixed a lot of bugs
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()) }
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 }))),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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())
|
||||
},
|
||||
};
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user