forked from Orchid/orchid
RA leaks memory in code-server, switching back to desktop
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use futures::FutureExt;
|
use async_stream::stream;
|
||||||
use futures::future::{LocalBoxFuture, join_all};
|
use futures::future::{LocalBoxFuture, join_all};
|
||||||
|
use futures::{FutureExt, Stream, StreamExt, pin_mut};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use orchid_api::ResolveNames;
|
use orchid_api::ResolveNames;
|
||||||
use orchid_base::error::{OrcRes, Reporter};
|
use orchid_base::error::{OrcRes, Reporter};
|
||||||
@@ -171,16 +172,31 @@ pub struct ConstCtx {
|
|||||||
constid: api::ParsedConstId,
|
constid: api::ParsedConstId,
|
||||||
}
|
}
|
||||||
impl ConstCtx {
|
impl ConstCtx {
|
||||||
pub async fn names<const N: usize>(&self, names: [&Sym; N]) -> [Option<Sym>; N] {
|
pub fn names<'a>(
|
||||||
|
&'a self,
|
||||||
|
names: impl IntoIterator<Item = &'a Sym> + Clone + 'a,
|
||||||
|
) -> impl Stream<Item = (Sym, Option<Sym>)> + 'a {
|
||||||
let resolve_names = ResolveNames {
|
let resolve_names = ResolveNames {
|
||||||
constid: self.constid,
|
constid: self.constid,
|
||||||
sys: self.ctx.sys_id(),
|
sys: self.ctx.sys_id(),
|
||||||
names: names.into_iter().map(|n| n.to_api()).collect_vec(),
|
names: names.clone().into_iter().map(|n| n.to_api()).collect_vec(),
|
||||||
};
|
};
|
||||||
let names = self.ctx.reqnot().request(resolve_names).await;
|
stream! {
|
||||||
|
let new_names = self.ctx.reqnot().request(resolve_names).await;
|
||||||
|
for (name, name_opt) in names.into_iter().zip(new_names) {
|
||||||
|
yield (name.clone(), match name_opt {
|
||||||
|
None => None,
|
||||||
|
Some(name) => Some(Sym::from_api(name, self.ctx.i()).await)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub async fn names_n<const N: usize>(&self, names: [&Sym; N]) -> [Option<Sym>; N] {
|
||||||
let mut results = [const { None }; N];
|
let mut results = [const { None }; N];
|
||||||
for (i, name) in names.into_iter().enumerate().filter_map(|(i, n)| Some((i, n?))) {
|
let names = self.names(names).enumerate().filter_map(|(i, n)| async move { Some((i, n.1?)) });
|
||||||
results[i] = Some(Sym::from_api(name, self.ctx.i()).await);
|
pin_mut!(names);
|
||||||
|
while let Some((i, name)) = names.next().await {
|
||||||
|
results[i] = Some(name);
|
||||||
}
|
}
|
||||||
results
|
results
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use orchid_extension::expr::Expr;
|
|||||||
use orchid_extension::gen_expr::GExpr;
|
use orchid_extension::gen_expr::GExpr;
|
||||||
use orchid_extension::system::SysCtx;
|
use orchid_extension::system::SysCtx;
|
||||||
|
|
||||||
use crate::macros::mactree::{MacTok, MacTree};
|
use crate::macros::mactree::{MacTok, MacTree, map_mactree};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct InstantiateTplCall {
|
pub struct InstantiateTplCall {
|
||||||
@@ -53,42 +53,12 @@ impl OwnedAtom for InstantiateTplCall {
|
|||||||
if self.argv.len() < self.argc {
|
if self.argv.len() < self.argc {
|
||||||
return self.to_expr();
|
return self.to_expr();
|
||||||
}
|
}
|
||||||
instantiate_tpl(&self.tpl, &mut self.argv.into_iter(), &mut false).to_expr()
|
let mut args = self.argv.into_iter();
|
||||||
|
map_mactree(&self.tpl, &mut false, &mut |tpl| match &*tpl.tok {
|
||||||
|
MacTok::Ph(_) => panic!("instantiate_tpl received a placeholder"),
|
||||||
|
MacTok::Slot => Some(args.next().expect("Not enough arguments to fill all slots!")),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.to_expr()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn instantiate_tpl(
|
|
||||||
tpl: &MacTree,
|
|
||||||
argv: &mut impl Iterator<Item = MacTree>,
|
|
||||||
changed: &mut bool,
|
|
||||||
) -> MacTree {
|
|
||||||
let tok = match &*tpl.tok {
|
|
||||||
MacTok::Slot => {
|
|
||||||
*changed = true;
|
|
||||||
return argv.next().expect("Not enough arguments to fill all slots!");
|
|
||||||
},
|
|
||||||
MacTok::Lambda(arg, body) => MacTok::Lambda(
|
|
||||||
ro(changed, |changed| instantiate_tpl(arg, argv, changed)),
|
|
||||||
instantiate_tpl_v(body, argv, changed),
|
|
||||||
),
|
|
||||||
MacTok::Name(_) | MacTok::Value(_) => return tpl.clone(),
|
|
||||||
MacTok::Ph(_) => panic!("instantiate_tpl received a placeholder"),
|
|
||||||
MacTok::S(p, body) => MacTok::S(*p, instantiate_tpl_v(body, argv, changed)),
|
|
||||||
};
|
|
||||||
if *changed { MacTree { pos: tpl.pos.clone(), tok: Rc::new(tok) } } else { tpl.clone() }
|
|
||||||
}
|
|
||||||
fn instantiate_tpl_v(
|
|
||||||
tpl: &[MacTree],
|
|
||||||
argv: &mut impl Iterator<Item = MacTree>,
|
|
||||||
changed: &mut bool,
|
|
||||||
) -> Vec<MacTree> {
|
|
||||||
tpl.iter().map(|tree| ro(changed, |changed| instantiate_tpl(tree, argv, changed))).collect_vec()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// reverse "or". Inside, the flag is always false, but raising it will raise
|
|
||||||
/// the outside flag too.
|
|
||||||
fn ro<T>(flag: &mut bool, cb: impl FnOnce(&mut bool) -> T) -> T {
|
|
||||||
let mut new_flag = false;
|
|
||||||
let val = cb(&mut new_flag);
|
|
||||||
*flag |= new_flag;
|
|
||||||
val
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use futures::future::LocalBoxFuture;
|
use futures::future::LocalBoxFuture;
|
||||||
|
use hashbrown::HashMap;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use orchid_base::error::{OrcRes, mk_errv};
|
use orchid_base::error::{OrcRes, mk_errv};
|
||||||
use orchid_base::interner::Tok;
|
use orchid_base::interner::Tok;
|
||||||
@@ -10,6 +11,8 @@ use orchid_extension::parser::{
|
|||||||
};
|
};
|
||||||
use substack::Substack;
|
use substack::Substack;
|
||||||
|
|
||||||
|
use crate::macros::mactree::{MacTok, MacTree, map_mactree, map_mactree_v};
|
||||||
|
|
||||||
type ExprGenerator =
|
type ExprGenerator =
|
||||||
Box<dyn for<'a> FnOnce(ConstCtx, Substack<'a, Sym>) -> LocalBoxFuture<'a, GExpr>>;
|
Box<dyn for<'a> FnOnce(ConstCtx, Substack<'a, Sym>) -> LocalBoxFuture<'a, GExpr>>;
|
||||||
|
|
||||||
@@ -31,29 +34,36 @@ impl Parser for LetLine {
|
|||||||
return Err(err.await);
|
return Err(err.await);
|
||||||
};
|
};
|
||||||
let Parsed { tail, .. } = expect_tok(&ctx, tail, ctx.i().i("=").await).await?;
|
let Parsed { tail, .. } = expect_tok(&ctx, tail, ctx.i().i("=").await).await?;
|
||||||
fn do_tokv(line: GenSnippet<'_>) -> ExprGenerator {
|
fn parse_tokv(line: GenSnippet<'_>) -> Vec<MacTree> {
|
||||||
let first: ExprGenerator = if let Some((idx, arg)) =
|
let first: MacTree = if let Some((idx, arg)) =
|
||||||
line.iter().enumerate().find_map(|(i, x)| Some((i, x.as_lambda()?)))
|
line.iter().enumerate().find_map(|(i, x)| Some((i, x.as_lambda()?)))
|
||||||
{
|
{
|
||||||
Box::new(move |ctx, stack| Box::pin(async move {
|
|
||||||
let name = ctx.names([])
|
|
||||||
}))
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
};
|
};
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
let expr_generator = do_tokv(tail);
|
let mut names = HashMap::new();
|
||||||
|
let aliased = parse_tokv(tail);
|
||||||
|
map_mactree_v(&aliased, &mut false, &mut |tpl| {
|
||||||
|
if let MacTok::Name(n) = &*tpl.tok {
|
||||||
|
names.insert(n.clone(), n);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
});
|
||||||
Ok(vec![ParsedLine {
|
Ok(vec![ParsedLine {
|
||||||
comments,
|
comments,
|
||||||
sr: line.sr(),
|
sr: line.sr(),
|
||||||
kind: ParsedLineKind::Mem(ParsedMem {
|
kind: ParsedLineKind::Mem(ParsedMem {
|
||||||
exported,
|
exported,
|
||||||
name,
|
name,
|
||||||
kind: ParsedMemKind::cnst(async |ctx| expr_generator(ctx, Substack::Bottom).await),
|
kind: ParsedMemKind::cnst(async |ctx| {
|
||||||
|
let mut names_str = ctx.names(names.keys());
|
||||||
|
while let Some(()) = names_str.next().await {
|
||||||
|
names[]
|
||||||
|
}
|
||||||
|
todo!()
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
}])
|
}])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_names(tree: MacTree)
|
|
||||||
@@ -3,6 +3,7 @@ use std::fmt::Display;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use futures::future::join_all;
|
use futures::future::join_all;
|
||||||
|
use itertools::Itertools;
|
||||||
use orchid_api::Paren;
|
use orchid_api::Paren;
|
||||||
use orchid_base::format::{FmtCtx, FmtUnit, Format, Variants};
|
use orchid_base::format::{FmtCtx, FmtUnit, Format, Variants};
|
||||||
use orchid_base::interner::Tok;
|
use orchid_base::interner::Tok;
|
||||||
@@ -18,7 +19,9 @@ pub struct MacTree {
|
|||||||
pub pos: Pos,
|
pub pos: Pos,
|
||||||
pub tok: Rc<MacTok>,
|
pub tok: Rc<MacTok>,
|
||||||
}
|
}
|
||||||
impl MacTree {}
|
impl MacTree {
|
||||||
|
fn tok(&self) -> &MacTok { &*self.tok }
|
||||||
|
}
|
||||||
impl Atomic for MacTree {
|
impl Atomic for MacTree {
|
||||||
type Data = ();
|
type Data = ();
|
||||||
type Variant = OwnedVariant;
|
type Variant = OwnedVariant;
|
||||||
@@ -99,33 +102,33 @@ pub enum PhKind {
|
|||||||
Vector { at_least_one: bool, priority: u8 },
|
Vector { at_least_one: bool, priority: u8 },
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_mactree(
|
pub fn map_mactree<F: FnMut(MacTree) -> Option<MacTree>>(
|
||||||
tpl: &MacTree,
|
src: &MacTree,
|
||||||
map: &mut impl FnMut(MacTree) -> Option<MacTree>,
|
|
||||||
argv: &mut impl Iterator<Item = MacTree>,
|
|
||||||
changed: &mut bool,
|
changed: &mut bool,
|
||||||
|
map: &mut F,
|
||||||
) -> MacTree {
|
) -> MacTree {
|
||||||
let tok = match &*tpl.tok {
|
let tok = match map(src.clone()) {
|
||||||
MacTok::Slot => {
|
Some(new_tok) => {
|
||||||
*changed = true;
|
*changed = true;
|
||||||
return argv.next().expect("Not enough arguments to fill all slots!");
|
return new_tok;
|
||||||
|
},
|
||||||
|
None => match &*src.tok {
|
||||||
|
MacTok::Lambda(arg, body) => MacTok::Lambda(
|
||||||
|
ro(changed, |changed| map_mactree(arg, changed, map)),
|
||||||
|
map_mactree_v(body, changed, map),
|
||||||
|
),
|
||||||
|
MacTok::Name(_) | MacTok::Value(_) | MacTok::Slot | MacTok::Ph(_) => return src.clone(),
|
||||||
|
MacTok::S(p, body) => MacTok::S(*p, map_mactree_v(body, changed, map)),
|
||||||
},
|
},
|
||||||
MacTok::Lambda(arg, body) => MacTok::Lambda(
|
|
||||||
ro(changed, |changed| instantiate_tpl(arg, argv, changed)),
|
|
||||||
instantiate_tpl_v(body, argv, changed),
|
|
||||||
),
|
|
||||||
MacTok::Name(_) | MacTok::Value(_) => return tpl.clone(),
|
|
||||||
MacTok::Ph(_) => panic!("instantiate_tpl received a placeholder"),
|
|
||||||
MacTok::S(p, body) => MacTok::S(*p, instantiate_tpl_v(body, argv, changed)),
|
|
||||||
};
|
};
|
||||||
if *changed { MacTree { pos: tpl.pos.clone(), tok: Rc::new(tok) } } else { tpl.clone() }
|
if *changed { MacTree { pos: src.pos.clone(), tok: Rc::new(tok) } } else { src.clone() }
|
||||||
}
|
}
|
||||||
pub fn map_mactree_v(
|
pub fn map_mactree_v<F: FnMut(MacTree) -> Option<MacTree>>(
|
||||||
tpl: &[MacTree],
|
src: &[MacTree],
|
||||||
argv: &mut impl Iterator<Item = MacTree>,
|
|
||||||
changed: &mut bool,
|
changed: &mut bool,
|
||||||
|
map: &mut F,
|
||||||
) -> Vec<MacTree> {
|
) -> Vec<MacTree> {
|
||||||
tpl.iter().map(|tree| ro(changed, |changed| instantiate_tpl(tree, argv, changed))).collect_vec()
|
src.iter().map(|tree| ro(changed, |changed| map_mactree(tree, changed, map))).collect_vec()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// reverse "or". Inside, the flag is always false, but raising it will raise
|
/// reverse "or". Inside, the flag is always false, but raising it will raise
|
||||||
|
|||||||
Reference in New Issue
Block a user