partway towards commands

I got very confused and started mucking about with "spawn" when in fact all I needed was the "inline" extension type in orcx that allows the interpreter to expose custom constants.
This commit is contained in:
2026-03-13 16:48:42 +01:00
parent cdcca694c5
commit 09cfcb1839
146 changed files with 3582 additions and 2822 deletions

View File

@@ -1,13 +1,12 @@
use std::borrow::Cow;
use never::Never;
use orchid_base::format::fmt;
use orchid_extension::atom::{Atomic, TAtom};
use orchid_extension::atom_owned::{OwnedAtom, OwnedVariant, own};
use orchid_base::fmt;
use orchid_extension::conv::ToExpr;
use orchid_extension::coroutine_exec::exec;
use orchid_extension::expr::Expr;
use orchid_extension::gen_expr::{GExpr, new_atom};
use orchid_extension::gen_expr::new_atom;
use orchid_extension::{Atomic, OwnedAtom, OwnedVariant, TAtom};
use crate::macros::mactree::{MacTok, MacTree};
@@ -25,7 +24,7 @@ impl OwnedAtom for InstantiateTplCall {
async fn val(&self) -> Cow<'_, Self::Data> { Cow::Owned(()) }
type Refs = Never;
// Technically must be supported but shouldn't actually ever be called
async fn call_ref(&self, arg: Expr) -> GExpr {
async fn call_ref(&self, arg: Expr) -> impl ToExpr {
if !self.argv.is_empty() {
eprintln!(
"Copying partially applied instantiate_tpl call. This is an internal value.\
@@ -34,11 +33,11 @@ impl OwnedAtom for InstantiateTplCall {
}
self.clone().call(arg).await
}
async fn call(mut self, arg: Expr) -> GExpr {
async fn call(mut self, arg: Expr) -> impl ToExpr {
exec(async move |mut h| {
match h.exec::<TAtom<MacTree>>(arg.clone()).await {
Err(_) => panic!("Expected a macro param, found {}", fmt(&arg).await),
Ok(t) => self.argv.push(own(&t).await),
Ok(t) => self.argv.push(t.own().await),
};
if self.argv.len() < self.argc {
return new_atom(self);
@@ -52,7 +51,5 @@ impl OwnedAtom for InstantiateTplCall {
new_atom(ret)
})
.await
.to_gen()
.await
}
}

View File

@@ -3,15 +3,13 @@ use std::pin::pin;
use futures::{FutureExt, StreamExt, stream};
use hashbrown::HashMap;
use itertools::Itertools;
use orchid_base::error::{OrcRes, report, with_reporter};
use orchid_base::interner::is;
use orchid_base::name::Sym;
use orchid_base::parse::{Comment, Parsed, Snippet, expect_tok, token_errv, try_pop_no_fluff};
use orchid_base::sym;
use orchid_base::tree::Paren;
use orchid_extension::atom::TAtom;
use orchid_base::{
Comment, OrcRes, Paren, Parsed, Snippet, Sym, expect_tok, is, report, sym, token_errv,
try_pop_no_fluff, with_reporter,
};
use orchid_extension::TAtom;
use orchid_extension::conv::TryFromExpr;
use orchid_extension::gen_expr::{call, new_atom, sym_ref};
use orchid_extension::gen_expr::{call, new_atom};
use orchid_extension::parser::{ConstCtx, PSnippet, PTok, PTokTree, ParsCtx, ParsedLine, Parser};
use crate::macros::mactree::{MacTok, MacTree, MacTreeSeq};
@@ -40,7 +38,7 @@ impl Parser for LetLine {
Ok(vec![ParsedLine::cnst(&line.sr(), &comments, exported, name, async move |ctx| {
let macro_input =
MacTok::S(Paren::Round, with_reporter(dealias_mac_v(&aliased, &ctx)).await?).at(sr.pos());
Ok(call(sym_ref(sym!(macros::resolve)), [new_atom(macro_input)]))
Ok(call(sym!(macros::resolve), new_atom(macro_input)))
})])
}
}
@@ -66,7 +64,7 @@ pub async fn dealias_mac_v(aliased: &MacTreeSeq, ctx: &ConstCtx) -> MacTreeSeq {
pub async fn parse_tokv(line: PSnippet<'_>) -> MacTreeSeq {
if let Some((idx, arg)) = line.iter().enumerate().find_map(|(i, x)| Some((i, x.as_lambda()?))) {
let (head, lambda) = line.split_at(idx as u32);
let (_, body) = lambda.pop_front().unwrap();
let (_, body) = lambda.split_first().unwrap();
let body = parse_tokv(body).boxed_local().await;
let mut all = parse_tokv_no_lambdas(&head).await;
match parse_tok(arg).await {

View File

@@ -1,8 +1,7 @@
use orchid_base::sym;
use orchid_extension::atom::TAtom;
use orchid_extension::atom_owned::own;
use orchid_extension::TAtom;
use orchid_extension::coroutine_exec::exec;
use orchid_extension::gen_expr::{call, new_atom, sym_ref};
use orchid_extension::gen_expr::{call, new_atom};
use orchid_extension::tree::{GenMember, fun, prefix};
use crate::macros::mactree::MacTree;
@@ -12,37 +11,37 @@ use crate::{HomoTpl, UntypedTuple};
pub async fn gen_macro_lib() -> Vec<GenMember> {
prefix("macros", [
fun(true, "resolve", async |tpl: TAtom<MacTree>| resolve(own(&tpl).await).await),
fun(true, "resolve", async |tpl: TAtom<MacTree>| resolve(tpl.own().await).await),
prefix("common", [
build_macro(None, ["..", "_", "="]).finish(),
build_macro(Some(1), ["+"])
.rule(mactreev!("...$" lhs 1 macros::common::+ "...$" rhs 0), [async |[lhs, rhs]| {
call(sym_ref(sym!(std::ops::add::resolve)), [resolve(lhs).await, resolve(rhs).await])
call(sym!(std::ops::add::resolve), (resolve(lhs).await, resolve(rhs).await)).await
}])
.finish(),
build_macro(Some(1), ["-"])
.rule(mactreev!("...$" lhs 1 macros::common::- "...$" rhs 0), [async |[lhs, rhs]| {
call(sym_ref(sym!(std::ops::sub::resolve)), [resolve(lhs).await, resolve(rhs).await])
call(sym!(std::ops::sub::resolve), (resolve(lhs).await, resolve(rhs).await)).await
}])
.finish(),
build_macro(Some(2), ["*"])
.rule(mactreev!("...$" lhs 1 macros::common::* "...$" rhs 0), [async |[lhs, rhs]| {
call(sym_ref(sym!(std::ops::mul::resolve)), [resolve(lhs).await, resolve(rhs).await])
call(sym!(std::ops::mul::resolve), (resolve(lhs).await, resolve(rhs).await)).await
}])
.finish(),
build_macro(Some(2), ["/"])
.rule(mactreev!("...$" lhs 1 macros::common::/ "...$" rhs 0), [async |[lhs, rhs]| {
call(sym_ref(sym!(std::ops::div::resolve)), [resolve(lhs).await, resolve(rhs).await])
call(sym!(std::ops::div::resolve), (resolve(lhs).await, resolve(rhs).await)).await
}])
.finish(),
build_macro(Some(2), ["%"])
.rule(mactreev!("...$" lhs 1 macros::common::% "...$" rhs 0), [async |[lhs, rhs]| {
call(sym_ref(sym!(std::ops::mod::resolve)), [resolve(lhs).await, resolve(rhs).await])
call(sym!(std::ops::mod::resolve), (resolve(lhs).await, resolve(rhs).await)).await
}])
.finish(),
build_macro(Some(3), ["."])
.rule(mactreev!("...$" lhs 1 macros::common::. "...$" rhs 0), [async |[lhs, rhs]| {
call(sym_ref(sym!(std::ops::get::resolve)), [resolve(lhs).await, resolve(rhs).await])
call(sym!(std::ops::get::resolve), (resolve(lhs).await, resolve(rhs).await)).await
}])
.finish(),
build_macro(None, ["comma_list", ","])

View File

@@ -4,16 +4,13 @@ use async_fn_stream::stream;
use async_once_cell::OnceCell;
use futures::StreamExt;
use itertools::Itertools;
use orchid_base::error::{OrcRes, mk_errv, report, with_reporter};
use orchid_base::interner::is;
use orchid_base::parse::{
Comment, Parsed, Snippet, expect_end, expect_tok, line_items, token_errv, try_pop_no_fluff,
use orchid_base::{
Comment, OrcRes, Paren, Parsed, Snippet, Token, clone, expect_end, expect_tok, is, line_items,
mk_errv, report, sym, token_errv, try_pop_no_fluff, with_reporter,
};
use orchid_base::tree::{Paren, Token};
use orchid_base::{clone, sym};
use orchid_extension::atom::TAtom;
use orchid_extension::TAtom;
use orchid_extension::conv::{ToExpr, TryFromExpr};
use orchid_extension::gen_expr::{call, new_atom, sym_ref};
use orchid_extension::gen_expr::{call, new_atom};
use orchid_extension::parser::{PSnippet, ParsCtx, ParsedLine, Parser};
use crate::macros::let_line::{dealias_mac_v, parse_tokv};
@@ -133,7 +130,7 @@ impl Parser for MacroLine {
let macro_input =
MacTok::S(Paren::Round, with_reporter(dealias_mac_v(&body_mactree, &ctx)).await?)
.at(body_sr.pos());
Ok(call(sym_ref(sym!(macros::resolve)), [new_atom(macro_input)]))
Ok(call(sym!(macros::resolve), new_atom(macro_input)))
}))
}
let mac_cell = Rc::new(OnceCell::new());

View File

@@ -1,8 +1,6 @@
use never::Never;
use orchid_base::name::Sym;
use orchid_base::reqnot::{Receipt, ReqHandle};
use orchid_base::sym;
use orchid_extension::atom::{AtomDynfo, AtomicFeatures};
use orchid_base::{Receipt, ReqHandle, Sym, sym};
use orchid_extension::{AtomOps, AtomicFeatures};
use orchid_extension::lexer::LexerObj;
use orchid_extension::other_system::SystemHandle;
use orchid_extension::parser::ParserObj;
@@ -34,20 +32,22 @@ impl SystemCtor for MacroSystem {
impl SystemCard for MacroSystem {
type Ctor = Self;
type Req = Never;
fn atoms() -> impl IntoIterator<Item = Option<Box<dyn AtomDynfo>>> {
fn atoms() -> impl IntoIterator<Item = Option<Box<dyn AtomOps>>> {
[
Some(InstantiateTplCall::dynfo()),
Some(MacTree::dynfo()),
Some(Macro::dynfo()),
Some(PhAtom::dynfo()),
Some(MacroBodyArgCollector::dynfo()),
Some(MatcherAtom::dynfo()),
Some(InstantiateTplCall::ops()),
Some(MacTree::ops()),
Some(Macro::ops()),
Some(PhAtom::ops()),
Some(MacroBodyArgCollector::ops()),
Some(MatcherAtom::ops()),
]
}
}
impl System for MacroSystem {
async fn request<'a>(_: Box<dyn ReqHandle<'a> + 'a>, req: Never) -> Receipt<'a> { match req {} }
async fn prelude() -> Vec<Sym> {
async fn request<'a>(&self, _: Box<dyn ReqHandle<'a> + 'a>, req: Never) -> Receipt<'a> {
match req {}
}
async fn prelude(&self) -> Vec<Sym> {
vec![
sym!(macros::common::+),
sym!(macros::common::*),
@@ -65,9 +65,9 @@ impl System for MacroSystem {
sym!(std::fn::[|>]),
]
}
fn lexers() -> Vec<LexerObj> { vec![&MacTreeLexer, &PhLexer] }
fn parsers() -> Vec<ParserObj> { vec![&LetLine, &MacroLine] }
async fn env() -> Vec<GenMember> {
fn lexers(&self) -> Vec<LexerObj> { vec![&MacTreeLexer, &PhLexer] }
fn parsers(&self) -> Vec<ParserObj> { vec![&LetLine, &MacroLine] }
async fn env(&self) -> Vec<GenMember> {
merge_trivial([gen_macro_lib().await, gen_std_macro_lib().await, gen_match_macro_lib().await])
}
}

View File

@@ -2,10 +2,10 @@ use std::borrow::Cow;
use std::rc::Rc;
use never::Never;
use orchid_base::interner::IStr;
use orchid_base::name::Sym;
use orchid_extension::atom::Atomic;
use orchid_extension::atom_owned::{OwnedAtom, OwnedVariant};
use orchid_base::IStr;
use orchid_base::Sym;
use orchid_extension::Atomic;
use orchid_extension::{OwnedAtom, OwnedVariant};
use crate::macros::mactree::MacTreeSeq;
use crate::macros::rule::matcher::Matcher;

View File

@@ -6,16 +6,12 @@ use futures::FutureExt;
use futures::future::join_all;
use hashbrown::HashSet;
use orchid_api_derive::Coding;
use orchid_base::error::OrcErrv;
use orchid_base::format::{FmtCtx, FmtUnit, Format, Variants};
use orchid_base::interner::IStr;
use orchid_base::location::Pos;
use orchid_base::name::Sym;
use orchid_base::tl_cache;
use orchid_base::tree::{Paren, indent};
use orchid_extension::atom::Atomic;
use orchid_extension::atom_owned::{OwnedAtom, OwnedVariant};
use orchid_base::{
FmtCtx, FmtUnit, Format, IStr, OrcErrv, Paren, Pos, Sym, Variants, indent, tl_cache,
};
use orchid_extension::Atomic;
use orchid_extension::expr::Expr;
use orchid_extension::{OwnedAtom, OwnedVariant};
fn union_rc_sets(seq: impl IntoIterator<Item = Rc<HashSet<Sym>>>) -> Rc<HashSet<Sym>> {
let mut acc = Rc::<HashSet<Sym>>::default();
@@ -190,8 +186,10 @@ impl Format for MacTok {
}
.units([body.print(c).await]),
Self::Slot => "$SLOT".into(),
Self::Bottom(err) if err.len() == 1 => format!("Bottom({}) ", err.one().unwrap()).into(),
Self::Bottom(err) => format!("Botttom(\n{}) ", indent(&err.to_string())).into(),
Self::Bottom(err) => match err.one() {
Some(err) => format!("Bottom({err}) ").into(),
None => format!("Botttom(\n{}) ", indent(&err.to_string())).into(),
},
}
}
}
@@ -200,7 +198,7 @@ pub async fn mtreev_fmt<'b>(
v: impl IntoIterator<Item = &'b MacTree>,
c: &(impl FmtCtx + ?Sized),
) -> FmtUnit {
FmtUnit::sequence("", " ", "", None, join_all(v.into_iter().map(|t| t.print(c))).await)
FmtUnit::sequence("", " ", "", true, join_all(v.into_iter().map(|t| t.print(c))).await)
}
#[derive(Clone, Debug, Hash, PartialEq, Eq)]

View File

@@ -2,10 +2,8 @@ use std::ops::RangeInclusive;
use futures::FutureExt;
use itertools::chain;
use orchid_base::error::{OrcRes, mk_errv};
use orchid_base::interner::is;
use orchid_base::tokens::PARENS;
use orchid_base::tree::Paren;
use orchid_base::Paren;
use orchid_base::{OrcRes, PARENS, is, mk_errv};
use orchid_extension::gen_expr::new_atom;
use orchid_extension::lexer::{LexContext, Lexer, err_not_applicable};
use orchid_extension::parser::p_tree2gen;

View File

@@ -5,18 +5,13 @@ use futures::future::join_all;
use futures::{Stream, StreamExt, stream};
use never::Never;
use orchid_api_derive::Coding;
use orchid_base::error::{OrcRes, mk_errv};
use orchid_base::format::fmt;
use orchid_base::interner::is;
use orchid_base::name::Sym;
use orchid_base::sym;
use orchid_extension::atom::{Atomic, TAtom};
use orchid_extension::atom_owned::{OwnedAtom, OwnedVariant, own};
use orchid_base::{OrcRes, Sym, fmt, is, mk_errv, sym};
use orchid_extension::conv::ToExpr;
use orchid_extension::coroutine_exec::{ExecHandle, exec};
use orchid_extension::expr::{Expr, ExprHandle};
use orchid_extension::gen_expr::{GExpr, arg, bot, call, lambda, new_atom, sym_ref};
use orchid_extension::gen_expr::{GExpr, arg, bot, call, call_v, lam, new_atom};
use orchid_extension::tree::{GenMember, fun, prefix};
use orchid_extension::{Atomic, OwnedAtom, OwnedVariant, TAtom};
use crate::macros::resolve::resolve;
use crate::macros::utils::{build_macro, mactree, mactreev};
@@ -35,8 +30,7 @@ impl MatcherData {
h: &mut ExecHandle<'_>,
val: impl ToExpr,
) -> OrcRes<OrcOpt<HomoTpl<Expr>>> {
h.exec::<OrcOpt<HomoTpl<Expr>>>(call(self.matcher().await.to_gen().await, [val.to_gen().await]))
.await
h.exec::<OrcOpt<HomoTpl<Expr>>>(call(self.matcher().await, val)).await
}
pub fn keys(&self) -> impl Stream<Item = Sym> {
stream(async |mut h| {
@@ -75,8 +69,7 @@ pub async fn gen_match_macro_lib() -> Vec<GenMember> {
"match_one",
async |mat: TAtom<MatcherAtom>, value: Expr, then: Expr, default: Expr| {
exec(async move |mut h| match mat.run_matcher(&mut h, value).await? {
OrcOpt(Some(values)) =>
Ok(call(then.to_gen().await, join_all(values.0.into_iter().map(|x| x.to_gen())).await)),
OrcOpt(Some(values)) => Ok(call_v(then, values.0).await),
OrcOpt(None) => Ok(default.to_gen().await),
})
.await
@@ -93,35 +86,34 @@ pub async fn gen_match_macro_lib() -> Vec<GenMember> {
async |[value, rules]| {
exec(async move |mut h| {
let rule_lines = h
.exec::<HomoTpl<TAtom<MacTree>>>(call(sym_ref(sym!(macros::resolve)), [new_atom(
mactree!(macros::common::semi_list "push" rules.clone();),
)]))
.exec::<HomoTpl<TAtom<MacTree>>>(call(
sym!(macros::resolve),
new_atom(mactree!(macros::common::semi_list "push" rules.clone();)),
))
.await?;
let mut rule_atoms = Vec::<(TAtom<MatcherAtom>, Expr)>::new();
for line_mac in rule_lines.0.iter() {
let Tpl((matcher, body)) = h
.exec(call(sym_ref(sym!(macros::resolve)), [new_atom(
mactree!(pattern::_row "push" own(line_mac).await ;),
)]))
.exec(call(
sym!(macros::resolve),
new_atom(mactree!(pattern::_row "push" line_mac.own().await ;)),
))
.await?;
rule_atoms.push((matcher, body));
}
let base_case = lambda(0, [bot(mk_errv(
let base_case = lam::<0>(bot(mk_errv(
is("No branches match").await,
"None of the patterns matches this value",
[rules.pos()],
))]);
)))
.await;
let match_expr = stream::iter(rule_atoms.into_iter().rev())
.fold(base_case, async |tail, (mat, body)| {
lambda(0, [call(sym_ref(sym!(pattern::match_one)), [
mat.to_gen().await,
arg(0),
body.to_gen().await,
call(tail, [arg(0)]),
])])
lam::<0>(call(sym!(pattern::match_one), (mat, arg(0), body, call(tail, arg(0)))))
.await
})
.await;
Ok(call(match_expr, [resolve(value).await]))
Ok(call(match_expr, resolve(value).await))
})
.await
},
@@ -132,16 +124,17 @@ pub async fn gen_match_macro_lib() -> Vec<GenMember> {
.rule(mactreev!(pattern::match_rule ( macros::common::_ )), [async |[]| {
Ok(new_atom(MatcherAtom {
keys: Vec::new(),
matcher: lambda(0, [OrcOpt(Some(Tpl(()))).to_gen().await]).create().await,
matcher: lam::<0>(OrcOpt(Some(Tpl(())))).await.create().await,
}))
}])
.rule(mactreev!(pattern::_row ( "...$" pattern 0 pattern::=> "...$" value 1 )), [
async |[pattern, mut value]| {
exec(async move |mut h| -> OrcRes<Tpl<(TAtom<MatcherAtom>, GExpr)>> {
let Ok(pat) = h
.exec::<TAtom<MatcherAtom>>(call(sym_ref(sym!(macros::resolve)), [new_atom(
mactree!(pattern::match_rule "push" pattern.clone();),
)]))
.exec::<TAtom<MatcherAtom>>(call(
sym!(macros::resolve),
new_atom(mactree!(pattern::match_rule "push" pattern.clone();)),
))
.await
else {
return Err(mk_errv(
@@ -175,7 +168,7 @@ pub async fn gen_match_macro_lib() -> Vec<GenMember> {
};
Ok(new_atom(MatcherAtom {
keys: vec![name.clone()],
matcher: sym_ref(sym!(pattern::ref_body)).to_expr().await,
matcher: sym!(pattern::ref_body).to_expr().await,
}))
}])
.finish(),

View File

@@ -1,13 +1,10 @@
use orchid_api_derive::Coding;
use orchid_base::error::{OrcRes, mk_errv};
use orchid_base::format::FmtUnit;
use orchid_base::interner::{es, is};
use orchid_base::parse::{name_char, name_start};
use orchid_extension::atom::Atomic;
use orchid_extension::atom_thin::{ThinAtom, ThinVariant};
use orchid_base::{FmtUnit, OrcRes, es, is, mk_errv, name_char, name_start};
use orchid_extension::Atomic;
use orchid_extension::gen_expr::new_atom;
use orchid_extension::lexer::{LexContext, Lexer, err_not_applicable};
use orchid_extension::tree::{GenTokTree, x_tok};
use orchid_extension::{ThinAtom, ThinVariant};
use crate::macros::mactree::{Ph, PhKind};

View File

@@ -1,21 +1,15 @@
use std::collections::VecDeque;
use std::ops::{Add, Range};
use async_fn_stream::stream;
use futures::{FutureExt, StreamExt};
use futures::{FutureExt, StreamExt, stream};
use hashbrown::{HashMap, HashSet};
use itertools::Itertools;
use orchid_base::error::mk_errv;
use orchid_base::format::fmt;
use orchid_base::interner::is;
use orchid_base::location::Pos;
use orchid_base::logging::log;
use orchid_base::name::{NameLike, Sym, VPath};
use orchid_base::tree::Paren;
use orchid_extension::atom::TAtom;
use orchid_extension::atom_owned::own;
use orchid_base::{NameLike, Paren, Pos, Sym, VPath, fmt, is, log, mk_errv};
use orchid_extension::TAtom;
use orchid_extension::conv::ToExpr;
use orchid_extension::coroutine_exec::{ExecHandle, exec};
use orchid_extension::gen_expr::{GExpr, arg, bot, call, lambda, new_atom, sym_ref};
use orchid_extension::coroutine_exec::exec;
use orchid_extension::gen_expr::{GExpr, arg, bot, call, call_v, dyn_lambda, new_atom};
use orchid_extension::reflection::{ReflMemKind, refl};
use subslice_offset::SubsliceOffset;
use substack::Substack;
@@ -37,8 +31,8 @@ pub async fn resolve(val: MacTree) -> GExpr {
.to_sym()
.await;
if let Ok(ReflMemKind::Const) = root.get_by_path(&new_name).await.map(|m| m.kind()) {
let Ok(mac) = h.exec::<TAtom<Macro>>(sym_ref(new_name)).await else { continue };
let mac = own(&mac).await;
let Ok(mac) = h.exec::<TAtom<Macro>>(new_name).await else { continue };
let mac = mac.own().await;
macros.entry(mac.0.canonical_name.clone()).or_insert(mac);
}
}
@@ -63,7 +57,7 @@ pub async fn resolve(val: MacTree) -> GExpr {
}
}
}
let mut rctx = ResolveCtx { h, exclusive, priod };
let mut rctx = ResolveCtx { exclusive, priod };
let gex = resolve_one(&mut rctx, Substack::Bottom, &val).await;
writeln!(
log("debug"),
@@ -85,7 +79,6 @@ pub struct FilteredMacroRecord<'a> {
}
struct ResolveCtx<'a> {
pub h: ExecHandle<'a>,
/// If these overlap, that's a compile-time error
pub exclusive: Vec<FilteredMacroRecord<'a>>,
/// If these overlap, the priorities decide the order. In case of a tie, the
@@ -104,7 +97,7 @@ async fn resolve_one(
MacTok::Value(v) => v.clone().to_gen().await,
MacTok::Name(n) => match arg_stk.iter().position(|arg| arg == n) {
Some(de_bruijn) => arg((arg_stk.len() - 1 - de_bruijn).try_into().unwrap()),
None => sym_ref(n.clone()),
None => n.clone().to_gen().await,
},
MacTok::Lambda(arg, body) => {
let MacTok::Name(name) = &*arg.tok else {
@@ -116,7 +109,7 @@ async fn resolve_one(
};
let arg_pos = arg_stk.len() as u64;
let arg_stk = arg_stk.push(name.clone());
lambda(arg_pos, [resolve_seq(ctx, arg_stk, body.clone(), value.pos()).await])
dyn_lambda(arg_pos, resolve_seq(ctx, arg_stk, body.clone(), value.pos()).await).await
},
MacTok::S(Paren::Round, body) => resolve_seq(ctx, arg_stk, body.clone(), value.pos()).await,
MacTok::S(..) => bot(mk_errv(
@@ -243,7 +236,7 @@ async fn resolve_seq(
// backwards so that the non-overlapping ranges remain valid
let pos = (state.names().flat_map(|r| r.1).cloned().reduce(Pos::add))
.expect("All macro rules must contain at least one locally defined name");
let subex = ctx.h.register(mk_body_call(mac, rule, &state, pos.clone()).await).await;
let subex = mk_body_call(mac, rule, &state, pos.clone()).await.to_expr().await;
new_val.splice(range, [MacTok::Value(subex).at(pos)]);
}
};
@@ -261,22 +254,23 @@ async fn resolve_seq(
let range = pre.len()..new_val.len() - suf.len();
let pos = (state.names().flat_map(|pair| pair.1).cloned().reduce(Pos::add))
.expect("All macro rules must contain at least one locally defined name");
let subex = ctx.h.register(mk_body_call(mac, rule, &state, pos.clone()).await).await;
let subex = mk_body_call(mac, rule, &state, pos.clone()).await.to_expr().await;
std::mem::drop(state);
new_val.splice(range, [MacTok::Value(subex).at(pos)]);
}
}
let exprs = stream(async |mut h| {
let mut exprs = stream(async |mut h| {
for mt in new_val {
h.emit(resolve_one(ctx, arg_stk.clone(), &mt).await).await
}
})
.collect::<Vec<_>>()
.collect::<VecDeque<_>>()
.boxed_local()
.await;
exprs.into_iter().reduce(|f, x| call(f, [x])).expect(
let first = exprs.pop_front().expect(
"We checked first that it isn't empty, and named macros get replaced with their results",
)
);
stream::iter(exprs).fold(first, async |f, x| call(f, x).await).await
}
async fn mk_body_call(mac: &Macro, rule: &Rule, state: &MatchState<'_>, pos: Pos) -> GExpr {
@@ -288,5 +282,5 @@ async fn mk_body_call(mac: &Macro, rule: &Rule, state: &MatchState<'_>, pos: Pos
new_atom(MacTok::S(Paren::Round, MacTreeSeq::new(vec.iter().cloned())).at(Pos::None)),
});
}
call(sym_ref(mac.0.module.suffix([rule.body.clone()]).await), call_args).at(pos.clone())
call_v(mac.0.module.suffix([rule.body.clone()]).await, call_args).await.at(pos.clone())
}

View File

@@ -1,4 +1,4 @@
use orchid_base::name::Sym;
use orchid_base::Sym;
use super::scal_match::scalv_match;
use super::shared::AnyMatcher;

View File

@@ -1,10 +1,7 @@
use futures::FutureExt;
use futures::future::join_all;
use itertools::Itertools;
use orchid_base::error::{OrcRes, mk_errv};
use orchid_base::interner::{IStr, is};
use orchid_base::join_ok;
use orchid_base::side::Side;
use orchid_base::{IStr, OrcRes, Side, is, join_ok, mk_errv};
use super::shared::{AnyMatcher, ScalMatcher, VecMatcher};
use super::vec_attrs::vec_attrs;
@@ -137,11 +134,8 @@ async fn mk_scalar(pattern: &MacTree) -> OrcRes<ScalMatcher> {
#[cfg(test)]
mod test {
use orchid_base::interner::local_interner::local_interner;
use orchid_base::interner::{is, with_interner};
use orchid_base::location::SrcRange;
use orchid_base::sym;
use orchid_base::tokens::Paren;
use orchid_base::local_interner::local_interner;
use orchid_base::{Paren, SrcRange, is, sym, with_interner};
use test_executors::spin_on;
use super::mk_any;

View File

@@ -1,9 +1,8 @@
use std::fmt;
use std::rc::Rc;
use orchid_base::error::OrcRes;
use orchid_base::interner::is;
use orchid_base::name::Sym;
use orchid_base::Sym;
use orchid_base::{OrcRes, is};
use super::any_match::any_match;
use super::build::mk_any;

View File

@@ -1,4 +1,4 @@
use orchid_base::name::Sym;
use orchid_base::Sym;
use super::any_match::any_match;
use super::shared::ScalMatcher;

View File

@@ -3,10 +3,8 @@
use std::fmt;
use itertools::Itertools;
use orchid_base::interner::IStr;
use orchid_base::name::Sym;
use orchid_base::side::Side;
use orchid_base::tokens::{PARENS, Paren};
use orchid_base::{PARENS, Paren};
use orchid_base::{IStr, Side, Sym};
pub enum ScalMatcher {
Name(Sym),

View File

@@ -2,11 +2,9 @@
use std::any::Any;
use hashbrown::HashMap;
use orchid_base::interner::IStr;
use orchid_base::join::join_maps;
use orchid_base::location::Pos;
use orchid_base::match_mapping;
use orchid_base::name::Sym;
use orchid_base::Pos;
use orchid_base::Sym;
use orchid_base::{IStr, join_maps, match_mapping};
use crate::macros::MacTree;

View File

@@ -1,4 +1,4 @@
use orchid_base::interner::IStr;
use orchid_base::IStr;
use crate::macros::mactree::{Ph, PhKind};
use crate::macros::{MacTok, MacTree};

View File

@@ -1,7 +1,7 @@
use std::cmp::Ordering;
use itertools::Itertools;
use orchid_base::name::Sym;
use orchid_base::Sym;
use super::scal_match::scalv_match;
use super::shared::VecMatcher;

View File

@@ -1,10 +1,10 @@
use futures::StreamExt;
use orchid_base::sym;
use orchid_extension::atom::TAtom;
use orchid_extension::TAtom;
use orchid_extension::conv::ToExpr;
use orchid_extension::coroutine_exec::exec;
use orchid_extension::expr::Expr;
use orchid_extension::gen_expr::{call, new_atom, sym_ref};
use orchid_extension::gen_expr::{call, new_atom};
use orchid_extension::tree::{GenMember, fun, prefix};
use crate::macros::match_macros::MatcherAtom;
@@ -36,19 +36,15 @@ pub async fn gen_option_macro_lib() -> Vec<GenMember> {
.await?;
Ok(new_atom(MatcherAtom {
keys: sub.keys().collect().await,
matcher: h
.register(call(sym_ref(sym!(std::option::is_some_body)), [sub.to_gen().await]))
.await,
matcher: call(sym!(std::option::is_some_body), sub).await.create().await,
}))
})
},
])
.rule(mactreev!(pattern::match_rule(std::option::none)), [|[]: [_; _]| {
exec(async |mut h| {
Ok(new_atom(MatcherAtom {
keys: vec![],
matcher: h.register(sym_ref(sym!(std::option::is_none_body))).await,
}))
.rule(mactreev!(pattern::match_rule(std::option::none)), [async |[]: [_; _]| {
new_atom(MatcherAtom {
keys: vec![],
matcher: sym!(std::option::is_none_body).to_expr().await,
})
}])
.finish(),

View File

@@ -1,10 +1,9 @@
use orchid_base::sym;
use orchid_extension::atom::TAtom;
use orchid_extension::atom_owned::own;
use orchid_extension::TAtom;
use orchid_extension::conv::ToExpr;
use orchid_extension::coroutine_exec::exec;
use orchid_extension::expr::Expr;
use orchid_extension::gen_expr::{call, new_atom, sym_ref};
use orchid_extension::gen_expr::{call, new_atom};
use orchid_extension::tree::{GenMember, prefix};
use crate::macros::resolve::resolve;
@@ -17,22 +16,19 @@ pub async fn gen_record_macro_lib() -> Vec<GenMember> {
.rule(mactreev!(std::record::r[ "...$" elements 0 ]), [async |[elements]: [_; _]| {
exec(async move |mut h| {
let tup = h
.exec::<HomoTpl<TAtom<MacTree>>>(call(sym_ref(sym!(macros::resolve)), [new_atom(
mactree!((macros::common::comma_list "push" elements ;)),
)]))
.exec::<HomoTpl<TAtom<MacTree>>>(call(
sym!(macros::resolve),
new_atom(mactree!((macros::common::comma_list "push" elements ;))),
))
.await?;
let mut record = sym_ref(sym!(std::record::empty));
let mut record = sym!(std::record::empty).to_gen().await;
for item_exprh in tup.0 {
let Tpl((key, value)) = h
.exec::<Tpl<(TAtom<IntStrAtom>, Expr)>>(
resolve(mactree!(std::record::_row "push" own(&item_exprh).await ;)).await,
resolve(mactree!(std::record::_row "push" item_exprh.own().await ;)).await,
)
.await?;
record = call(sym_ref(sym!(std::record::set)), [
record.to_gen().await,
key.to_gen().await,
value.to_gen().await,
]);
record = call(sym!(std::record::set), (record, key, value)).await;
}
Ok(record)
})

View File

@@ -1,12 +1,10 @@
use futures::{StreamExt, stream};
use orchid_base::error::OrcRes;
use orchid_base::sym;
use orchid_extension::atom::TAtom;
use orchid_extension::atom_owned::own;
use orchid_base::{OrcRes, sym};
use orchid_extension::TAtom;
use orchid_extension::conv::ToExpr;
use orchid_extension::coroutine_exec::exec;
use orchid_extension::expr::Expr;
use orchid_extension::gen_expr::{GExpr, call, new_atom, sym_ref};
use orchid_extension::gen_expr::{GExpr, call, new_atom};
use orchid_extension::tree::{GenMember, fun, prefix};
use crate::macros::match_macros::MatcherAtom;
@@ -19,19 +17,19 @@ pub async fn gen_tuple_macro_lib() -> Vec<GenMember> {
.rule(mactreev!(std::tuple::t [ "...$" elements 0 ]), [|[elements]: [_; _]| {
exec(async move |mut h| {
let tup = h
.exec::<HomoTpl<TAtom<MacTree>>>(call(sym_ref(sym!(macros::resolve)), [
.exec::<HomoTpl<TAtom<MacTree>>>(call(sym!(macros::resolve),
new_atom(mactree!((macros::common::comma_list "push" elements ;))),
]))
))
.await?;
let val = stream::iter(&tup.0[..])
.fold(sym_ref(sym!(std::tuple::empty)), async |head, new| {
call(sym_ref(sym!(std::tuple::cat)), [
.fold(sym!(std::tuple::empty).to_gen().await, async |head, new| {
call(sym!(std::tuple::cat), (
head,
call(sym_ref(sym!(std::tuple::one)), [call(
sym_ref(sym!(macros::resolve)),
[new.clone().to_gen().await],
)]),
])
call(sym!(std::tuple::one), call(
sym!(macros::resolve),
new.clone(),
)),
)).await
})
.await;
Ok(val)
@@ -58,25 +56,24 @@ pub async fn gen_tuple_macro_lib() -> Vec<GenMember> {
fn parse_tpl(elements: MacTree, tail_matcher: Option<MacTree>) -> impl Future<Output = GExpr> {
exec(async move |mut h| -> OrcRes<GExpr> {
let tup = h
.exec::<HomoTpl<TAtom<MacTree>>>(call(sym_ref(sym!(macros::resolve)), [new_atom(
.exec::<HomoTpl<TAtom<MacTree>>>(call(sym!(macros::resolve), new_atom(
mactree!((macros::common::comma_list "push" elements ;)),
)]))
)))
.await?;
let mut subs = Vec::with_capacity(tup.0.len());
for mac_a in &tup.0[..] {
let mac = own(mac_a).await;
let sub = h
.exec::<TAtom<MatcherAtom>>(call(sym_ref(sym!(macros::resolve)), [new_atom(
mactree!(pattern::match_rule ("push" mac ;)),
)]))
.exec::<TAtom<MatcherAtom>>(call(sym!(macros::resolve), new_atom(
mactree!(pattern::match_rule ("push" mac_a.own().await ;)),
)))
.await?;
subs.push(sub);
}
let tail_matcher = match tail_matcher {
Some(mac) => Some(
h.exec::<TAtom<MatcherAtom>>(call(sym_ref(sym!(macros::resolve)), [new_atom(
h.exec::<TAtom<MatcherAtom>>(call(sym!(macros::resolve), new_atom(
mactree!(pattern::match_rule "push" mac ;),
)]))
)))
.await?,
),
None => None,
@@ -87,10 +84,10 @@ fn parse_tpl(elements: MacTree, tail_matcher: Option<MacTree>) -> impl Future<Ou
.chain(stream::iter(&tail_matcher).flat_map(|mat| mat.keys()))
.collect()
.await,
matcher: call(sym_ref(sym!(std::tuple::matcher_body)), [
HomoTpl(subs).to_gen().await,
OrcOpt(tail_matcher).to_gen().await,
])
matcher: call(sym!(std::tuple::matcher_body), (
HomoTpl(subs),
OrcOpt(tail_matcher),
))
.to_expr()
.await,
}))
@@ -118,8 +115,8 @@ fn tuple_matcher_body(
None => (),
Some(tail_mat) => {
let tail_tpl = stream::iter(&value.0[children.0.len()..])
.fold(sym_ref(sym!(std::tuple::empty)), async |prefix, new| {
call(sym_ref(sym!(std::tuple::cat)), [prefix, new.clone().to_gen().await])
.fold(sym!(std::tuple::empty).to_gen().await, async |prefix, new| {
call(sym!(std::tuple::cat), (prefix, new.clone())).await
})
.await;
match tail_mat.run_matcher(&mut h, tail_tpl).await? {

View File

@@ -6,13 +6,11 @@ use futures::StreamExt;
use futures::future::LocalBoxFuture;
use itertools::{Itertools, chain};
use never::Never;
use orchid_base::interner::is;
use orchid_base::name::{NameLike, Sym, VPath};
use orchid_extension::atom::{Atomic, TAtom};
use orchid_extension::atom_owned::{OwnedAtom, OwnedVariant, own};
use orchid_base::{NameLike, Sym, VPath, is};
use orchid_extension::conv::ToExpr;
use orchid_extension::gen_expr::{GExpr, new_atom, sym_ref};
use orchid_extension::gen_expr::{GExpr, new_atom};
use orchid_extension::tree::{GenMember, MemKind, cnst, lazy};
use orchid_extension::{Atomic, OwnedAtom, OwnedVariant, TAtom};
use crate::macros::macro_value::{Macro, MacroData, Rule};
use crate::macros::mactree::MacTreeSeq;
@@ -41,10 +39,10 @@ impl OwnedAtom for MacroBodyArgCollector {
self.clone().call(arg).await
}
async fn call(mut self, arg: orchid_extension::expr::Expr) -> GExpr {
let atom = (TAtom::downcast(arg.handle()).await).unwrap_or_else(|_| {
let atom = (TAtom::<MacTree>::downcast(arg.handle()).await).unwrap_or_else(|_| {
panic!("This is an intermediary value, the argument types are known in advance")
});
self.args.push(own(&atom).await);
self.args.push(atom.own().await);
if self.argc == self.args.len() {
(self.cb)(self.args).await.to_gen().await
} else {
@@ -142,7 +140,7 @@ impl MacroBuilder {
.name_with_suffix(is(&format!("__macro__{name}")).await)
.to_sym()
.await;
MemKind::Const(sym_ref(main_const_name))
MemKind::Const(main_const_name.to_gen().await)
})
});
chain!(main_const, kw_consts, body_consts).collect()
@@ -159,29 +157,29 @@ macro_rules! mactreev_impl {
(@RECUR $ret:ident) => {};
(@RECUR $ret:ident "..$" $name:ident $prio:literal $($tail:tt)*) => {
$ret.push($crate::macros::mactree::MacTok::Ph($crate::macros::mactree::Ph{
name: orchid_base::interner::is(stringify!($name)).await,
name: orchid_base::is(stringify!($name)).await,
kind: $crate::macros::mactree::PhKind::Vector{ at_least_one: false, priority: $prio }
}).at(orchid_base::location::Pos::Inherit));
}).at(orchid_base::Pos::Inherit));
$crate::macros::utils::mactreev_impl!(@RECUR $ret $($tail)*);
};
(@RECUR $ret:ident "...$" $name:ident $prio:literal $($tail:tt)*) => {
$ret.push($crate::macros::mactree::MacTok::Ph($crate::macros::mactree::Ph{
name: orchid_base::interner::is(stringify!($name)).await,
name: orchid_base::is(stringify!($name)).await,
kind: $crate::macros::mactree::PhKind::Vector{ at_least_one: true, priority: $prio }
}).at(orchid_base::location::Pos::Inherit));
}).at(orchid_base::Pos::Inherit));
$crate::macros::utils::mactreev_impl!(@RECUR $ret $($tail)*);
};
(@RECUR $ret:ident "$" $name:ident $($tail:tt)*) => {
$ret.push($crate::macros::mactree::MacTok::Ph($crate::macros::mactree::Ph{
name: orchid_base::interner::is(stringify!(name)).await,
name: orchid_base::is(stringify!(name)).await,
kind: $crate::macros::mactree::PhKind::Scalar
}).at(orchid_base::location::Pos::Inherit));
}).at(orchid_base::Pos::Inherit));
$crate::macros::utils::mactreev_impl!(@RECUR $ret $($tail)*);
};
(@RECUR $ret:ident "Val" $arg:expr ; $($tail:tt)*) => {
$ret.push(
$crate::macros::mactree::MacTok::Value($arg)
.at(orchid_base::location::Pos::Inherit)
.at(orchid_base::Pos::Inherit)
);
$crate::macros::utils::mactreev_impl!(@RECUR $ret $($tail)*);
};
@@ -200,16 +198,16 @@ macro_rules! mactreev_impl {
};
(@RECUR $ret:ident "l_" $arg:expr ; ($($body:tt)*) $($tail:tt)*) => {
$ret.push(MacTok::Lambda(
MacTok::Name($arg).at(orchid_base::location::Pos::Inherit),
MacTok::Name($arg).at(orchid_base::Pos::Inherit),
$crate::macros::utils::mactreev!($($body)*)
).at(orchid_base::location::Pos::Inherit));
).at(orchid_base::Pos::Inherit));
$crate::macros::utils::mactreev_impl!(@RECUR $ret $($tail)*);
};
(@RECUR $ret:ident "l" $argh:tt $(:: $arg:tt)+ ($($body:tt)*) $($tail:tt)*) => {
$ret.push(MacTok::Lambda(
MacTok::Name(sym!($argh $(:: $arg)+).await).at(orchid_base::location::Pos::Inherit),
MacTok::Name(sym!($argh $(:: $arg)+).await).at(orchid_base::Pos::Inherit),
$crate::macros::utils::mactreev!($($body)*)
).at(orchid_base::location::Pos::Inherit));
).at(orchid_base::Pos::Inherit));
$crate::macros::utils::mactreev_impl!(@RECUR $ret $($tail)*);
};
(@RECUR $ret:ident $name:literal $($tail:tt)*) => {
@@ -218,42 +216,42 @@ macro_rules! mactreev_impl {
"{} was treated as a name, but it doesn't have a namespace prefix",
$name
);
let sym = orchid_base::name::Sym::parse(
let sym = orchid_base::Sym::parse(
$name
).await.expect("Empty string in sym literal in Rust");
$ret.push(
$crate::macros::mactree::MacTok::Name(sym)
.at(orchid_base::location::Pos::Inherit)
.at(orchid_base::Pos::Inherit)
);
$crate::macros::utils::mactreev_impl!(@RECUR $ret $($tail)*);
};
(@RECUR $ret:ident ( $($body:tt)* ) $($tail:tt)*) => {
$ret.push(
$crate::macros::mactree::MacTok::S(
orchid_base::tree::Paren::Round,
orchid_base::Paren::Round,
$crate::macros::utils::mactreev!($($body)*)
)
.at(orchid_base::location::Pos::Inherit)
.at(orchid_base::Pos::Inherit)
);
$crate::macros::utils::mactreev_impl!(@RECUR $ret $($tail)*);
};
(@RECUR $ret:ident [ $($body:tt)* ] $($tail:tt)*) => {
$ret.push(
$crate::macros::mactree::MacTok::S(
orchid_base::tree::Paren::Square,
orchid_base::Paren::Square,
$crate::macros::utils::mactreev!($($body)*)
)
.at(orchid_base::location::Pos::Inherit)
.at(orchid_base::Pos::Inherit)
);
$crate::macros::utils::mactreev_impl!(@RECUR $ret $($tail)*);
};
(@RECUR $ret:ident { $($body:tt)* } $($tail:tt)*) => {
$ret.push(
$crate::macros::mactree::MacTok::S(
orchid_base::tree::Paren::Curly,
orchid_base::Paren::Curly,
$crate::macros::utils::mactreev!($($body)*)
)
.at(orchid_base::location::Pos::Inherit)
.at(orchid_base::Pos::Inherit)
);
$crate::macros::utils::mactreev_impl!(@RECUR $ret $($tail)*);
};
@@ -267,7 +265,7 @@ macro_rules! mactreev_impl {
let sym = orchid_base::sym!($($munched)*);
$ret.push(
$crate::macros::mactree::MacTok::Name(sym)
.at(orchid_base::location::Pos::Inherit)
.at(orchid_base::Pos::Inherit)
);
$crate::macros::utils::mactreev_impl!(@RECUR $ret $($tail)*);
};