This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use std::any::{Any, TypeId, type_name};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::fmt::{self, Debug};
|
||||
use std::future::Future;
|
||||
use std::num::NonZeroU32;
|
||||
use std::ops::Deref;
|
||||
@@ -144,6 +144,15 @@ impl NotTypAtom {
|
||||
)
|
||||
}
|
||||
}
|
||||
impl Debug for NotTypAtom {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("NotTypAtom")
|
||||
.field("pos", &self.pos)
|
||||
.field("expr", &self.expr)
|
||||
.field("typ.name", &self.typ.name())
|
||||
.finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AtomMethod: Request + Coding {
|
||||
const NAME: &str;
|
||||
|
||||
@@ -136,6 +136,7 @@ impl Expr {
|
||||
_ => Err(self),
|
||||
}
|
||||
}
|
||||
pub async fn pos(&self) -> Pos { self.data().await.pos.clone() }
|
||||
pub fn handle(&self) -> Rc<ExprHandle> { self.handle.clone() }
|
||||
|
||||
pub fn slot(&self) -> GExpr {
|
||||
|
||||
@@ -31,6 +31,19 @@ trait_set! {
|
||||
trait FunCB = Fn(Vec<Expr>) -> LocalBoxFuture<'static, OrcRes<GExpr>> + 'static;
|
||||
}
|
||||
|
||||
task_local! {
|
||||
static ARGV: Vec<Expr>;
|
||||
}
|
||||
|
||||
pub fn get_arg(idx: usize) -> Expr {
|
||||
ARGV
|
||||
.try_with(|argv| {
|
||||
(argv.get(idx).cloned())
|
||||
.unwrap_or_else(|| panic!("Cannot read argument ##{idx}, only have {}", argv.len()))
|
||||
})
|
||||
.expect("get_arg called outside ExprFunc")
|
||||
}
|
||||
|
||||
pub trait ExprFunc<I, O>: Clone + 'static {
|
||||
fn argtyps() -> &'static [TypeId];
|
||||
fn apply<'a>(&self, hand: ExecHandle<'a>, v: Vec<Expr>) -> impl Future<Output = OrcRes<GExpr>>;
|
||||
|
||||
@@ -184,12 +184,12 @@ impl ConstCtx {
|
||||
&'b self,
|
||||
names: impl IntoIterator<Item = &'b Sym> + 'b,
|
||||
) -> impl Stream<Item = OrcRes<Sym>> + 'b {
|
||||
let resolve_names = api::ResolveNames {
|
||||
constid: self.constid,
|
||||
sys: sys_id(),
|
||||
names: names.into_iter().map(|n| n.to_api()).collect_vec(),
|
||||
};
|
||||
let names = names.into_iter().map(|n| n.to_api()).collect_vec();
|
||||
stream(async |mut cx| {
|
||||
if names.is_empty() {
|
||||
return;
|
||||
}
|
||||
let resolve_names = api::ResolveNames { constid: self.constid, sys: sys_id(), names };
|
||||
for name_opt in request(resolve_names).await {
|
||||
cx.emit(match name_opt {
|
||||
Err(e) => Err(OrcErrv::from_api(&e).await),
|
||||
|
||||
@@ -47,8 +47,9 @@ impl ReflMod {
|
||||
async fn try_populate(&self) -> Result<(), api::LsModuleError> {
|
||||
let path_tok = iv(&self.0.path[..]).await;
|
||||
let reply = match request(api::LsModule(sys_id(), path_tok.to_api())).await {
|
||||
Err(api::LsModuleError::TreeUnavailable) =>
|
||||
panic!("Reflected tree accessed outside an interpreter call. This extension is faulty."),
|
||||
Err(api::LsModuleError::TreeUnavailable) => {
|
||||
panic!("Reflected tree accessed outside an interpreter call. This extension is faulty.")
|
||||
},
|
||||
Err(err) => return Err(err),
|
||||
Ok(details) => details,
|
||||
};
|
||||
@@ -79,10 +80,12 @@ impl ReflMod {
|
||||
return None;
|
||||
}
|
||||
match self.try_populate().await {
|
||||
Err(api::LsModuleError::InvalidPath) =>
|
||||
panic!("Path became invalid since module was created"),
|
||||
Err(api::LsModuleError::IsConstant) =>
|
||||
panic!("Path previously contained a module but now contains a constant"),
|
||||
Err(api::LsModuleError::InvalidPath) => {
|
||||
panic!("Path became invalid since module was created")
|
||||
},
|
||||
Err(api::LsModuleError::IsConstant) => {
|
||||
panic!("Path previously contained a module but now contains a constant")
|
||||
},
|
||||
Err(api::LsModuleError::TreeUnavailable) => unreachable!(),
|
||||
Ok(()) => (),
|
||||
}
|
||||
|
||||
@@ -71,8 +71,7 @@ pub fn module(
|
||||
vec![GenMember { name, kind, public, comments: vec![] }]
|
||||
}
|
||||
pub fn root_mod(name: &str, mems: impl IntoIterator<Item = Vec<GenMember>>) -> (String, MemKind) {
|
||||
let kind = MemKind::Mod { members: mems.into_iter().flatten().collect() };
|
||||
(name.to_string(), kind)
|
||||
(name.to_string(), MemKind::module(mems))
|
||||
}
|
||||
pub fn fun<I, O>(public: bool, name: &str, xf: impl ExprFunc<I, O>) -> Vec<GenMember> {
|
||||
let fac =
|
||||
@@ -113,12 +112,12 @@ pub fn merge_trivial(trees: impl IntoIterator<Item = Vec<GenMember>>) -> Vec<Gen
|
||||
let prev = all_members.insert(mem.name.clone(), (unit, mem.comments.into_iter().collect()));
|
||||
assert!(prev.is_none(), "Conflict in trivial tree merge on {}", mem.name);
|
||||
},
|
||||
MemKind::Mod { members } => match all_members.entry(mem.name.clone()) {
|
||||
MemKind::Mod(members) => match all_members.entry(mem.name.clone()) {
|
||||
hashbrown::hash_map::Entry::Vacant(slot) => {
|
||||
slot.insert((MemKind::Mod { members }, mem.comments.into_iter().collect()));
|
||||
slot.insert((MemKind::Mod(members), mem.comments.into_iter().collect()));
|
||||
},
|
||||
hashbrown::hash_map::Entry::Occupied(mut old) => match old.get_mut() {
|
||||
(MemKind::Mod { members: old_items, .. }, old_cmts) => {
|
||||
(MemKind::Mod(old_items), old_cmts) => {
|
||||
let mut swap = vec![];
|
||||
std::mem::swap(&mut swap, old_items);
|
||||
*old_items = merge_trivial([swap, members]);
|
||||
@@ -167,15 +166,19 @@ impl GenMember {
|
||||
|
||||
pub enum MemKind {
|
||||
Const(GExpr),
|
||||
Mod { members: Vec<GenMember> },
|
||||
Mod(Vec<GenMember>),
|
||||
Lazy(LazyMemberFactory),
|
||||
}
|
||||
impl MemKind {
|
||||
pub async fn cnst(val: impl ToExpr) -> Self { Self::Const(val.to_gen().await) }
|
||||
pub fn module(mems: impl IntoIterator<Item = Vec<GenMember>>) -> Self {
|
||||
Self::Mod(mems.into_iter().flatten().collect())
|
||||
}
|
||||
pub(crate) async fn into_api(self, ctx: &mut impl TreeIntoApiCtx) -> api::MemberKind {
|
||||
match self {
|
||||
Self::Lazy(lazy) => api::MemberKind::Lazy(add_lazy(ctx, lazy)),
|
||||
Self::Const(c) => api::MemberKind::Const(c.serialize().await),
|
||||
Self::Mod { members } => api::MemberKind::Module(api::Module {
|
||||
Self::Mod(members) => api::MemberKind::Module(api::Module {
|
||||
members: stream(async |mut cx| {
|
||||
for m in members {
|
||||
cx.emit(m.into_api(ctx).await).await
|
||||
|
||||
Reference in New Issue
Block a user