forked from Orchid/orchid
temp commit
This commit is contained in:
@@ -14,6 +14,7 @@ derive_destructure = "1.0.0"
|
||||
dyn-clone = "1.0.17"
|
||||
futures = "0.3.31"
|
||||
hashbrown = "0.15.2"
|
||||
include_dir = { version = "0.7.4", optional = true }
|
||||
itertools = "0.14.0"
|
||||
konst = "0.3.16"
|
||||
lazy_static = "1.5.0"
|
||||
@@ -25,8 +26,8 @@ orchid-api-derive = { version = "0.1.0", path = "../orchid-api-derive" }
|
||||
orchid-api-traits = { version = "0.1.0", path = "../orchid-api-traits" }
|
||||
orchid-base = { version = "0.1.0", path = "../orchid-base" }
|
||||
ordered-float = "5.0.0"
|
||||
paste = "1.0.15"
|
||||
some_executor = "0.4.0"
|
||||
pastey = "0.1.0"
|
||||
some_executor = "0.5.1"
|
||||
substack = "1.1.1"
|
||||
tokio = { version = "1.43.0", optional = true }
|
||||
tokio = { version = "1.46.1", optional = true }
|
||||
trait-set = "0.3.0"
|
||||
|
||||
@@ -59,7 +59,7 @@ impl<'a> AtomReadGuard<'a> {
|
||||
async fn new(id: api::AtomId, ctx: &'a SysCtx) -> Self {
|
||||
let guard = ctx.get_or_default::<ObjStore>().objects.read().await;
|
||||
let valid = guard.iter().map(|i| i.0).collect_vec();
|
||||
assert!(guard.get(&id).is_some(), "Received invalid atom ID: {:?} not in {:?}", id, valid);
|
||||
assert!(guard.get(&id).is_some(), "Received invalid atom ID: {id:?} not in {valid:?}");
|
||||
Self { id, guard }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::num::NonZero;
|
||||
use std::pin::Pin;
|
||||
use std::rc::Rc;
|
||||
|
||||
use async_std::channel::{self, Receiver, RecvError, Sender};
|
||||
use async_std::channel::{self, Receiver, Sender};
|
||||
use async_std::stream;
|
||||
use async_std::sync::Mutex;
|
||||
use futures::future::{LocalBoxFuture, join_all};
|
||||
@@ -22,7 +22,7 @@ use orchid_base::logging::Logger;
|
||||
use orchid_base::name::Sym;
|
||||
use orchid_base::parse::{Comment, Snippet};
|
||||
use orchid_base::reqnot::{ReqNot, RequestHandle, Requester};
|
||||
use orchid_base::tree::{TokenVariant, ttv_from_api, ttv_into_api};
|
||||
use orchid_base::tree::{TokenVariant, ttv_from_api};
|
||||
use substack::Substack;
|
||||
use trait_set::trait_set;
|
||||
|
||||
@@ -32,6 +32,7 @@ use crate::atom_owned::take_atom;
|
||||
use crate::expr::{Expr, ExprHandle};
|
||||
use crate::fs::VirtFS;
|
||||
use crate::lexer::{LexContext, err_cascade, err_not_applicable};
|
||||
use crate::parser::{ParsCtx, get_const, linev_into_api};
|
||||
use crate::system::{SysCtx, atom_by_idx};
|
||||
use crate::system_ctor::{CtedObj, DynSystemCtor};
|
||||
use crate::tree::{GenTok, GenTokTree, LazyMemberFactory, TreeIntoApiCtxImpl};
|
||||
@@ -47,7 +48,6 @@ impl ExtensionData {
|
||||
pub fn new(name: &'static str, systems: &'static [&'static dyn DynSystemCtor]) -> Self {
|
||||
Self { name, systems }
|
||||
}
|
||||
// pub fn main(self) { extension_main(self) }
|
||||
}
|
||||
|
||||
pub enum MemberRecord {
|
||||
@@ -57,7 +57,6 @@ pub enum MemberRecord {
|
||||
|
||||
pub struct SystemRecord {
|
||||
vfses: HashMap<api::VfsId, &'static dyn VirtFS>,
|
||||
declfs: api::EagerVfs,
|
||||
lazy_members: HashMap<api::TreeId, MemberRecord>,
|
||||
ctx: SysCtx,
|
||||
}
|
||||
@@ -84,19 +83,6 @@ pub async fn with_atom_record<'a, F: Future<Output = SysCtx>, T>(
|
||||
cb(atom_record, ctx, id, data).await
|
||||
}
|
||||
|
||||
// pub fn extension_main(data: ExtensionData) {
|
||||
|
||||
// if thread::Builder::new()
|
||||
// .name(format!("ext-main:{}", data.name))
|
||||
// .spawn(|| extension_main_logic(data))
|
||||
// .unwrap()
|
||||
// .join()
|
||||
// .is_err()
|
||||
// {
|
||||
// process::exit(-1)
|
||||
// }
|
||||
// }
|
||||
|
||||
pub struct ExtensionOwner {
|
||||
_interner_cell: Rc<RefCell<Option<Interner>>>,
|
||||
_systems_lock: Rc<Mutex<HashMap<api::SysId, SystemRecord>>>,
|
||||
@@ -109,12 +95,7 @@ impl ExtPort for ExtensionOwner {
|
||||
Box::pin(async { self.out_send.send(msg.to_vec()).boxed_local().await.unwrap() })
|
||||
}
|
||||
fn recv(&self) -> LocalBoxFuture<'_, Option<Vec<u8>>> {
|
||||
Box::pin(async {
|
||||
match self.out_recv.recv().await {
|
||||
Ok(v) => Some(v),
|
||||
Err(RecvError) => None,
|
||||
}
|
||||
})
|
||||
Box::pin(async { (self.out_recv.recv().await).ok() })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,8 +122,7 @@ pub fn extension_init(
|
||||
let get_ctx = clone!(systems_weak; move |id: api::SysId| clone!(systems_weak; async move {
|
||||
let systems =
|
||||
systems_weak.upgrade().expect("System table dropped before request processing done");
|
||||
let x = systems.lock().await.get(&id).expect("System not found").ctx.clone();
|
||||
x
|
||||
systems.lock().await.get(&id).expect("System not found").ctx.clone()
|
||||
}));
|
||||
let init_ctx = {
|
||||
clone!(interner_weak, spawner, logger);
|
||||
@@ -200,32 +180,25 @@ pub fn extension_init(
|
||||
.then(|mem| {
|
||||
let (req, lazy_mems) = (&hand, &lazy_mems);
|
||||
clone!(i, ctx; async move {
|
||||
let name = i.i(&mem.name).await.to_api();
|
||||
let value = mem.kind.into_api(&mut TreeIntoApiCtxImpl {
|
||||
let mut tia_ctx = TreeIntoApiCtxImpl {
|
||||
lazy_members: &mut *lazy_mems.lock().await,
|
||||
sys: ctx,
|
||||
basepath: &[],
|
||||
path: Substack::Bottom,
|
||||
req
|
||||
})
|
||||
.await;
|
||||
(name, value)
|
||||
};
|
||||
(i.i(&mem.name).await.to_api(), mem.kind.into_api(&mut tia_ctx).await)
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
.await;
|
||||
let declfs = cted.inst().dyn_vfs().to_api_rec(&mut vfses, &i).await;
|
||||
let record =
|
||||
SystemRecord { declfs, vfses, ctx, lazy_members: lazy_mems.into_inner() };
|
||||
let vfs = cted.inst().dyn_vfs().to_api_rec(&mut vfses, &i).await;
|
||||
let record = SystemRecord { vfses, ctx, lazy_members: lazy_mems.into_inner() };
|
||||
let systems = systems_weak.upgrade().expect("System constructed during shutdown");
|
||||
systems.lock().await.insert(new_sys.id, record);
|
||||
hand
|
||||
.handle(&new_sys, &api::NewSystemResponse {
|
||||
lex_filter,
|
||||
const_root,
|
||||
line_types: vec![],
|
||||
})
|
||||
.await
|
||||
let response =
|
||||
api::NewSystemResponse { lex_filter, const_root, line_types: vec![], vfs };
|
||||
hand.handle(&new_sys, &response).await
|
||||
},
|
||||
api::HostExtReq::GetMember(get_tree @ api::GetMember(sys_id, tree_id)) => {
|
||||
let sys_ctx = get_ctx(sys_id).await;
|
||||
@@ -248,18 +221,13 @@ pub fn extension_init(
|
||||
};
|
||||
hand.handle(&get_tree, &tree.into_api(&mut tia_ctx).await).await
|
||||
},
|
||||
api::HostExtReq::VfsReq(api::VfsReq::GetVfs(get_vfs @ api::GetVfs(sys_id))) => {
|
||||
let systems = systems_weak.upgrade().expect("VFS root requested during shutdown");
|
||||
let systems_g = systems.lock().await;
|
||||
hand.handle(&get_vfs, &systems_g[&sys_id].declfs).await
|
||||
},
|
||||
api::HostExtReq::SysReq(api::SysReq::SysFwded(fwd)) => {
|
||||
let api::SysFwded(sys_id, payload) = fwd;
|
||||
let ctx = get_ctx(sys_id).await;
|
||||
let sys = ctx.cted().inst();
|
||||
sys.dyn_request(hand, payload).await
|
||||
},
|
||||
api::HostExtReq::VfsReq(api::VfsReq::VfsRead(vfs_read)) => {
|
||||
api::HostExtReq::VfsRead(vfs_read) => {
|
||||
let api::VfsRead(sys_id, vfs_id, path) = &vfs_read;
|
||||
let ctx = get_ctx(*sys_id).await;
|
||||
let systems = systems_weak.upgrade().expect("VFS requested during shutdoown");
|
||||
@@ -308,13 +276,18 @@ pub fn extension_init(
|
||||
let parser =
|
||||
parsers.iter().find(|p| p.line_head() == **name).expect("No parser candidate");
|
||||
let module = Sym::from_api(*module, ctx.i()).await;
|
||||
let o_line = match parser.parse(ctx.clone(), module, *exported, comments, tail).await
|
||||
{
|
||||
let pctx = ParsCtx::new(ctx.clone(), module);
|
||||
let o_line = match parser.parse(pctx, *exported, comments, tail).await {
|
||||
Err(e) => Err(e.to_api()),
|
||||
Ok(t) => Ok(ttv_into_api(t, &mut (), &mut (ctx.clone(), &hand)).await),
|
||||
Ok(t) => Ok(linev_into_api(t, ctx.clone(), &hand).await),
|
||||
};
|
||||
hand.handle(&pline, &o_line).await
|
||||
},
|
||||
api::HostExtReq::FetchParsedConst(ref fpc @ api::FetchParsedConst { id, sys }) => {
|
||||
let ctx = get_ctx(sys).await;
|
||||
let cnst = get_const(id, ctx.clone()).await;
|
||||
hand.handle(fpc, &cnst.api_return(ctx, &hand).await).await
|
||||
},
|
||||
api::HostExtReq::AtomReq(atom_req) => {
|
||||
let atom = atom_req.get_atom();
|
||||
let atom_req = atom_req.clone();
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
use std::borrow::Cow;
|
||||
use std::num::NonZero;
|
||||
|
||||
use futures::FutureExt;
|
||||
use futures::future::LocalBoxFuture;
|
||||
use hashbrown::HashMap;
|
||||
use orchid_base::interner::{Interner, Tok};
|
||||
use orchid_base::pure_seq::pushed;
|
||||
|
||||
use crate::api;
|
||||
use crate::system::SysCtx;
|
||||
@@ -16,11 +18,58 @@ pub trait VirtFS: Send + Sync + 'static {
|
||||
) -> LocalBoxFuture<'a, api::OrcResult<api::Loaded>>;
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DeclVmod(Cow<'static, [(&'static str, DeclFs)]>);
|
||||
impl DeclVmod {
|
||||
pub fn new(items: &'static [(&'static str, DeclFs)]) -> DeclVmod {
|
||||
DeclVmod(Cow::Borrowed(items))
|
||||
}
|
||||
pub fn entry(
|
||||
key: &'static str,
|
||||
items: &'static [(&'static str, DeclFs)],
|
||||
) -> (&'static str, DeclVmod) {
|
||||
(key, DeclVmod(Cow::Borrowed(items)))
|
||||
}
|
||||
pub fn merge(&self, other: &Self) -> Result<Self, Vec<&'static str>> {
|
||||
let mut items = Vec::new();
|
||||
for (k, v1) in self.0.iter() {
|
||||
items.push((*k, match other.0.iter().find(|(k2, _)| k == k2) {
|
||||
Some((_, v2)) => v1.merge(v2).map_err(|e| pushed::<_, Vec<_>>(e, *k))?,
|
||||
None => v1.clone(),
|
||||
}));
|
||||
}
|
||||
for (k, v) in other.0.iter() {
|
||||
if !items.iter().any(|(k2, _)| k2 == k) {
|
||||
items.push((*k, v.clone()))
|
||||
}
|
||||
}
|
||||
Ok(Self(Cow::Owned(items)))
|
||||
}
|
||||
pub async fn to_api_rec(
|
||||
&self,
|
||||
vfses: &mut HashMap<api::VfsId, &'static dyn VirtFS>,
|
||||
i: &Interner,
|
||||
) -> std::collections::HashMap<api::TStr, api::EagerVfs> {
|
||||
let mut output = std::collections::HashMap::new();
|
||||
for (k, v) in self.0.iter() {
|
||||
output.insert(i.i::<String>(*k).await.to_api(), v.to_api_rec(vfses, i).boxed_local().await);
|
||||
}
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum DeclFs {
|
||||
Lazy(&'static dyn VirtFS),
|
||||
Mod(&'static [(&'static str, DeclFs)]),
|
||||
Mod(DeclVmod),
|
||||
}
|
||||
impl DeclFs {
|
||||
pub fn merge(&self, other: &Self) -> Result<Self, Vec<&'static str>> {
|
||||
match (self, other) {
|
||||
(Self::Mod(m1), Self::Mod(m2)) => Ok(Self::Mod(m1.merge(m2)?)),
|
||||
(..) => Err(Vec::new()),
|
||||
}
|
||||
}
|
||||
pub async fn to_api_rec(
|
||||
&self,
|
||||
vfses: &mut HashMap<api::VfsId, &'static dyn VirtFS>,
|
||||
@@ -33,14 +82,7 @@ impl DeclFs {
|
||||
vfses.insert(id, *fs);
|
||||
api::EagerVfs::Lazy(id)
|
||||
},
|
||||
DeclFs::Mod(children) => {
|
||||
let mut output = std::collections::HashMap::new();
|
||||
for (k, v) in children.iter() {
|
||||
output
|
||||
.insert(i.i::<String>(*k).await.to_api(), v.to_api_rec(vfses, i).boxed_local().await);
|
||||
}
|
||||
api::EagerVfs::Eager(output)
|
||||
},
|
||||
DeclFs::Mod(m) => api::EagerVfs::Eager(m.to_api_rec(vfses, i).await),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ mod expr_func_derives {
|
||||
|
||||
macro_rules! expr_func_derive {
|
||||
($arity: tt, $($t:ident),*) => {
|
||||
paste::paste!{
|
||||
pastey::paste!{
|
||||
impl<
|
||||
$($t: TryFromExpr, )*
|
||||
Out: ToExpr,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::fmt;
|
||||
use std::future::Future;
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
@@ -49,10 +50,15 @@ impl<'a> LexContext<'a> {
|
||||
}
|
||||
|
||||
pub fn pos(&self, tail: &'a str) -> u32 { (self.text.len() - tail.len()) as u32 }
|
||||
|
||||
pub fn tok_ran(&self, len: u32, tail: &'a str) -> SrcRange {
|
||||
SrcRange::new(self.pos(tail) - len..self.pos(tail), &self.src)
|
||||
pub fn pos_tt(&self, tail_with: &'a str, tail_without: &'a str) -> SrcRange {
|
||||
SrcRange::new(self.pos(tail_with)..self.pos(tail_without), &self.src)
|
||||
}
|
||||
|
||||
pub fn pos_lt(&self, len: impl TryInto<u32, Error: fmt::Debug>, tail: &'a str) -> SrcRange {
|
||||
SrcRange::new(self.pos(tail) - len.try_into().unwrap()..self.pos(tail), &self.src)
|
||||
}
|
||||
|
||||
pub fn i(&self) -> &Interner { self.ctx.i() }
|
||||
}
|
||||
|
||||
pub trait Lexer: Send + Sync + Sized + Default + 'static {
|
||||
|
||||
@@ -1,50 +1,179 @@
|
||||
use futures::future::LocalBoxFuture;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use futures::FutureExt;
|
||||
use futures::future::{LocalBoxFuture, join_all};
|
||||
use itertools::Itertools;
|
||||
use orchid_api::ResolveNames;
|
||||
use orchid_base::error::OrcRes;
|
||||
use orchid_base::id_store::IdStore;
|
||||
use orchid_base::interner::Tok;
|
||||
use orchid_base::location::SrcRange;
|
||||
use orchid_base::name::Sym;
|
||||
use orchid_base::parse::{Comment, Snippet};
|
||||
use orchid_base::reqnot::{ReqHandlish, Requester};
|
||||
use orchid_base::tree::ttv_into_api;
|
||||
|
||||
use crate::api;
|
||||
use crate::expr::Expr;
|
||||
use crate::gen_expr::GExpr;
|
||||
use crate::system::SysCtx;
|
||||
use crate::system::{SysCtx, SysCtxEntry};
|
||||
use crate::tree::GenTokTree;
|
||||
|
||||
pub type GenSnippet<'a> = Snippet<'a, Expr, GExpr>;
|
||||
|
||||
pub trait Parser: Send + Sync + Sized + Default + 'static {
|
||||
const LINE_HEAD: &'static str;
|
||||
fn parse(
|
||||
ctx: SysCtx,
|
||||
module: Sym,
|
||||
fn parse<'a>(
|
||||
ctx: ParsCtx<'a>,
|
||||
exported: bool,
|
||||
comments: Vec<Comment>,
|
||||
line: GenSnippet<'_>,
|
||||
) -> impl Future<Output = OrcRes<Vec<GenTokTree>>> + '_;
|
||||
line: GenSnippet<'a>,
|
||||
) -> impl Future<Output = OrcRes<Vec<ParsedLine>>> + 'a;
|
||||
}
|
||||
|
||||
pub trait DynParser: Send + Sync + 'static {
|
||||
fn line_head(&self) -> &'static str;
|
||||
fn parse<'a>(
|
||||
&self,
|
||||
ctx: SysCtx,
|
||||
module: Sym,
|
||||
ctx: ParsCtx<'a>,
|
||||
exported: bool,
|
||||
comments: Vec<Comment>,
|
||||
line: GenSnippet<'a>,
|
||||
) -> LocalBoxFuture<'a, OrcRes<Vec<GenTokTree>>>;
|
||||
) -> LocalBoxFuture<'a, OrcRes<Vec<ParsedLine>>>;
|
||||
}
|
||||
|
||||
impl<T: Parser> DynParser for T {
|
||||
fn line_head(&self) -> &'static str { Self::LINE_HEAD }
|
||||
fn parse<'a>(
|
||||
&self,
|
||||
ctx: SysCtx,
|
||||
module: Sym,
|
||||
ctx: ParsCtx<'a>,
|
||||
exported: bool,
|
||||
comments: Vec<Comment>,
|
||||
line: GenSnippet<'a>,
|
||||
) -> LocalBoxFuture<'a, OrcRes<Vec<GenTokTree>>> {
|
||||
Box::pin(async move { Self::parse(ctx, module, exported, comments, line).await })
|
||||
) -> LocalBoxFuture<'a, OrcRes<Vec<ParsedLine>>> {
|
||||
Box::pin(async move { Self::parse(ctx, exported, comments, line).await })
|
||||
}
|
||||
}
|
||||
|
||||
pub type ParserObj = &'static dyn DynParser;
|
||||
|
||||
pub struct ParsCtx<'a> {
|
||||
_parse: PhantomData<&'a mut ()>,
|
||||
ctx: SysCtx,
|
||||
module: Sym,
|
||||
}
|
||||
impl ParsCtx<'_> {
|
||||
pub(crate) fn new(ctx: SysCtx, module: Sym) -> Self { Self { _parse: PhantomData, ctx, module } }
|
||||
pub fn ctx(&self) -> &SysCtx { &self.ctx }
|
||||
pub fn module(&self) -> Sym { self.module.clone() }
|
||||
}
|
||||
|
||||
type BoxConstCallback = Box<dyn FnOnce(ConstCtx) -> LocalBoxFuture<'static, GExpr>>;
|
||||
|
||||
#[derive(Default)]
|
||||
struct ParsedConstCtxEntry {
|
||||
consts: IdStore<BoxConstCallback>,
|
||||
}
|
||||
impl SysCtxEntry for ParsedConstCtxEntry {}
|
||||
|
||||
pub struct ParsedLine {
|
||||
pub sr: SrcRange,
|
||||
pub comments: Vec<Comment>,
|
||||
pub kind: ParsedLineKind,
|
||||
}
|
||||
impl ParsedLine {
|
||||
pub async fn into_api(self, ctx: SysCtx, hand: &dyn ReqHandlish) -> api::ParsedLine {
|
||||
api::ParsedLine {
|
||||
comments: self.comments.into_iter().map(|c| c.to_api()).collect(),
|
||||
source_range: self.sr.to_api(),
|
||||
kind: match self.kind {
|
||||
ParsedLineKind::Mem(mem) => api::ParsedLineKind::Member(api::ParsedMember {
|
||||
name: mem.name.to_api(),
|
||||
exported: mem.exported,
|
||||
kind: match mem.kind {
|
||||
ParsedMemKind::Const(cb) => api::ParsedMemberKind::Constant(api::ParsedConstId(
|
||||
ctx.get_or_default::<ParsedConstCtxEntry>().consts.add(cb).id(),
|
||||
)),
|
||||
ParsedMemKind::Mod(plv) =>
|
||||
api::ParsedMemberKind::Module(linev_into_api(plv, ctx, hand).boxed_local().await),
|
||||
},
|
||||
}),
|
||||
ParsedLineKind::Rec(tv) =>
|
||||
api::ParsedLineKind::Recursive(ttv_into_api(tv, &mut (), &mut (ctx, hand)).await),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn linev_into_api(
|
||||
v: Vec<ParsedLine>,
|
||||
ctx: SysCtx,
|
||||
hand: &dyn ReqHandlish,
|
||||
) -> Vec<api::ParsedLine> {
|
||||
join_all(v.into_iter().map(|l| l.into_api(ctx.clone(), hand))).await
|
||||
}
|
||||
|
||||
pub enum ParsedLineKind {
|
||||
Mem(ParsedMem),
|
||||
Rec(Vec<GenTokTree>),
|
||||
}
|
||||
|
||||
pub struct ParsedMem {
|
||||
name: Tok<String>,
|
||||
exported: bool,
|
||||
kind: ParsedMemKind,
|
||||
}
|
||||
|
||||
pub enum ParsedMemKind {
|
||||
Const(BoxConstCallback),
|
||||
Mod(Vec<ParsedLine>),
|
||||
}
|
||||
|
||||
impl ParsedMemKind {
|
||||
pub fn cnst<F: AsyncFnOnce(ConstCtx) -> GExpr + 'static>(f: F) -> Self {
|
||||
Self::Const(Box::new(|ctx| Box::pin(f(ctx))))
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: how the macro runner uses the multi-stage loader
|
||||
|
||||
Since the macro runner actually has to invoke the interpreter,
|
||||
it'll run at const-time and not at postparse-time anyway.
|
||||
|
||||
pasing stage establishes the role of every constant as a macro keyword
|
||||
postparse / const load links up constants with every macro they can directly invoke
|
||||
the constants representing the keywords might not actually be postparsed,
|
||||
\ the connection is instead made by detecting in the macro system that the
|
||||
\ resolved name is owned by a macro
|
||||
the returned constant from this call is always an entrypoint call to
|
||||
\ the macro system
|
||||
the constants representing the keywords resolve to panic
|
||||
execute relies on these links detected in the extension to dispatch relevant macros
|
||||
*/
|
||||
|
||||
pub struct ConstCtx {
|
||||
ctx: SysCtx,
|
||||
constid: api::ParsedConstId,
|
||||
}
|
||||
impl ConstCtx {
|
||||
pub async fn names<const N: usize>(&self, names: [&Sym; N]) -> [Option<Sym>; N] {
|
||||
let resolve_names = ResolveNames {
|
||||
constid: self.constid,
|
||||
sys: self.ctx.sys_id(),
|
||||
names: names.into_iter().map(|n| n.to_api()).collect_vec(),
|
||||
};
|
||||
let names = self.ctx.reqnot().request(resolve_names).await;
|
||||
let mut results = [const { None }; N];
|
||||
for (i, name) in names.into_iter().enumerate().filter_map(|(i, n)| Some((i, n?))) {
|
||||
results[i] = Some(Sym::from_api(name, self.ctx.i()).await);
|
||||
}
|
||||
results
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn get_const(id: api::ParsedConstId, ctx: SysCtx) -> GExpr {
|
||||
let ent = ctx.get::<ParsedConstCtxEntry>();
|
||||
let rec = ent.consts.get(id.0).expect("Bad ID or double read of parsed const");
|
||||
let ctx = ConstCtx { constid: id, ctx: ctx.clone() };
|
||||
rec.remove()(ctx).await
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ use orchid_base::reqnot::{Receipt, ReqNot};
|
||||
use crate::api;
|
||||
use crate::atom::{AtomCtx, AtomDynfo, AtomTypeId, AtomicFeatures, ForeignAtom, TypAtom, get_info};
|
||||
use crate::entrypoint::ExtReq;
|
||||
use crate::fs::DeclFs;
|
||||
use crate::fs::DeclVmod;
|
||||
use crate::func_atom::Fun;
|
||||
use crate::lexer::LexerObj;
|
||||
use crate::parser::ParserObj;
|
||||
@@ -83,7 +83,7 @@ impl<T: SystemCard> DynSystemCard for T {
|
||||
/// System as defined by author
|
||||
pub trait System: Send + Sync + SystemCard + 'static {
|
||||
fn env() -> Vec<GenMember>;
|
||||
fn vfs() -> DeclFs;
|
||||
fn vfs() -> DeclVmod;
|
||||
fn lexers() -> Vec<LexerObj>;
|
||||
fn parsers() -> Vec<ParserObj>;
|
||||
fn request(hand: ExtReq<'_>, req: Self::Req) -> impl Future<Output = Receipt<'_>>;
|
||||
@@ -91,7 +91,7 @@ pub trait System: Send + Sync + SystemCard + 'static {
|
||||
|
||||
pub trait DynSystem: Send + Sync + DynSystemCard + 'static {
|
||||
fn dyn_env(&self) -> Vec<GenMember>;
|
||||
fn dyn_vfs(&self) -> DeclFs;
|
||||
fn dyn_vfs(&self) -> DeclVmod;
|
||||
fn dyn_lexers(&self) -> Vec<LexerObj>;
|
||||
fn dyn_parsers(&self) -> Vec<ParserObj>;
|
||||
fn dyn_request<'a>(&self, hand: ExtReq<'a>, req: Vec<u8>) -> LocalBoxFuture<'a, Receipt<'a>>;
|
||||
@@ -100,7 +100,7 @@ pub trait DynSystem: Send + Sync + DynSystemCard + 'static {
|
||||
|
||||
impl<T: System> DynSystem for T {
|
||||
fn dyn_env(&self) -> Vec<GenMember> { Self::env() }
|
||||
fn dyn_vfs(&self) -> DeclFs { Self::vfs() }
|
||||
fn dyn_vfs(&self) -> DeclVmod { Self::vfs() }
|
||||
fn dyn_lexers(&self) -> Vec<LexerObj> { Self::lexers() }
|
||||
fn dyn_parsers(&self) -> Vec<ParserObj> { Self::parsers() }
|
||||
fn dyn_request<'a>(&self, hand: ExtReq<'a>, req: Vec<u8>) -> LocalBoxFuture<'a, Receipt<'a>> {
|
||||
|
||||
@@ -90,7 +90,7 @@ impl<T: SystemCtor> DynSystemCtor for T {
|
||||
mod dep_set_tuple_impls {
|
||||
use orchid_base::box_chain;
|
||||
use orchid_base::boxed_iter::BoxedIter;
|
||||
use paste::paste;
|
||||
use pastey::paste;
|
||||
|
||||
use super::{DepDef, DepSat};
|
||||
use crate::api;
|
||||
|
||||
@@ -20,7 +20,7 @@ use crate::conv::ToExpr;
|
||||
use crate::entrypoint::MemberRecord;
|
||||
use crate::expr::{Expr, ExprHandle};
|
||||
use crate::func_atom::{ExprFunc, Fun};
|
||||
use crate::gen_expr::{GExpr, arg, call, lambda, seq};
|
||||
use crate::gen_expr::{GExpr, arg, call, lambda, seq, sym_ref};
|
||||
use crate::system::SysCtx;
|
||||
|
||||
pub type GenTokTree = TokTree<Expr, GExpr>;
|
||||
@@ -65,6 +65,9 @@ impl TokenVariant<api::ExprTicket> for Expr {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn x_tok(x: impl ToExpr) -> GenTok { GenTok::NewExpr(x.to_expr()) }
|
||||
pub fn ref_tok(path: Sym) -> GenTok { GenTok::NewExpr(sym_ref(path)) }
|
||||
|
||||
pub fn cnst(public: bool, name: &str, value: impl ToExpr) -> Vec<GenMember> {
|
||||
vec![GenMember {
|
||||
name: name.to_string(),
|
||||
|
||||
Reference in New Issue
Block a user