Pattern matching works now
This commit is contained in:
4
LICENCE
4
LICENCE
@@ -4,8 +4,8 @@ The code in this repository is free for noncommercial use, including derivative
|
||||
|
||||
Identifying marks stored in the repository are restricted for use with an unmodified copy of this software. If you distribute modified versions of this software, you must either replace these identifying marks or modify them in a way that clearly indicates that what you are distributing is a derivative work and not this official vversion. You must also replace any contact information in such a way that your derivative work does not suggest that we may be contacted about issues. Your derivative work may use the original identifying marks and contact information to identify this project as its basis, while emphasizing that the authors of the original project are neither in control of, nor liable for the derivative work.
|
||||
|
||||
Identifying marks include the Orchid logo, the ribbon image above, and the names "Orchid", "Orchidlang" unless they are part of a technical interface.
|
||||
Identifying marks include the Orchid logo, the ribbon image in the readme, and the names "Orchid", "Orchidlang" unless they are part of a technical interface.
|
||||
|
||||
Contact information includes email addresses, links to the source code and issue tracker.
|
||||
|
||||
Words listed as identifying marks are explicltly not considered as such when they appear in technical interfaces or APIs. For example, shell commands, identifiers within Orchid or Rust code, and names in package registries are not considered as identifying marks.
|
||||
Words listed as identifying marks are explicltly not considered as such when they appear in technical interfaces or APIs. For example, shell commands, identifiers within Orchid or Rust code, and names in package registries are not considered identifying marks.
|
||||
@@ -35,9 +35,7 @@ Orchids and mangrove trees form complex ecosystems; The flowers persuade the tre
|
||||
|
||||
All contributions are welcome. For the time being, use the issue tracker to discuss ideas.
|
||||
|
||||
Unless we agree on different terms, by contributing to this software you declare that you have created or otherwise have the right to license your contribution, agree to license it publicly under the general noncommercial licence included in this repository, and grant me (the owner of the project) a permanent, unrestricted license to use, modify, distribute and relicense your contribution.
|
||||
|
||||
You retain ownership of your intellectual property to ensure that the copyleft protections cementing the noncommercial availability of the code are preserved.
|
||||
Unless we agree on different terms, by contributing to this software you declare that you have created or otherwise have the right to license your contribution, agree to license it publicly under the general noncommercial licence included in this repository, and grant me (the owner of the project) a permanent, unrestricted license to use, modify, distribute and relicense your contribution. You retain ownership of your intellectual property to ensure that the copyleft protections cementing the noncommercial availability of the code are preserved.
|
||||
|
||||
## About the license
|
||||
|
||||
|
||||
@@ -1,2 +1,6 @@
|
||||
let my_tuple = option::some t[1, 2]
|
||||
let main = tuple::get (option::expect my_tuple "tuple is none") 1
|
||||
|
||||
let main = match my_tuple {
|
||||
option::of t[ref head, ..] => head;
|
||||
option::empty => "foo";
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ float_impl!(f32, 4);
|
||||
|
||||
impl Decode for String {
|
||||
async fn decode<R: AsyncRead + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
let len = u64::decode(read.as_mut()).await.try_into().unwrap();
|
||||
let len: usize = u64::decode(read.as_mut()).await.try_into().unwrap();
|
||||
let mut data = vec![0u8; len];
|
||||
read.read_exact(&mut data).await.unwrap();
|
||||
std::str::from_utf8(&data).expect("String invalid UTF-8").to_owned()
|
||||
@@ -132,7 +132,7 @@ impl Encode for str {
|
||||
}
|
||||
impl<T: Decode> Decode for Vec<T> {
|
||||
async fn decode<R: AsyncRead + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
let len = u64::decode(read.as_mut()).await.try_into().unwrap();
|
||||
let len = u64::decode(read.as_mut()).await;
|
||||
stream(async |mut cx| {
|
||||
for _ in 0..len {
|
||||
cx.emit(T::decode(read.as_mut()).await).await
|
||||
@@ -191,7 +191,7 @@ impl<T: Encode, E: Encode> Encode for Result<T, E> {
|
||||
}
|
||||
impl<K: Decode + Eq + Hash, V: Decode> Decode for HashMap<K, V> {
|
||||
async fn decode<R: AsyncRead + ?Sized>(mut read: Pin<&mut R>) -> Self {
|
||||
let len = u64::decode(read.as_mut()).await.try_into().unwrap();
|
||||
let len = u64::decode(read.as_mut()).await;
|
||||
stream(async |mut cx| {
|
||||
for _ in 0..len {
|
||||
cx.emit(<(K, V)>::decode(read.as_mut()).await).await
|
||||
|
||||
@@ -13,6 +13,7 @@ impl Logger {
|
||||
pub fn new(strat: api::LogStrategy) -> Self { Self(strat) }
|
||||
pub fn log(&self, msg: impl AsRef<str>) { writeln!(self, "{}", msg.as_ref()) }
|
||||
pub fn strat(&self) -> api::LogStrategy { self.0.clone() }
|
||||
pub fn is_active(&self) -> bool { !matches!(self.0, api::LogStrategy::Discard) }
|
||||
pub fn log_buf(&self, event: impl AsRef<str>, buf: &[u8]) {
|
||||
if std::env::var("ORCHID_LOG_BUFFERS").is_ok_and(|v| !v.is_empty()) {
|
||||
writeln!(self, "{}: [{}]", event.as_ref(), buf.iter().map(|b| format!("{b:02x}")).join(" "))
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::mem;
|
||||
use std::ops::{BitAnd, Deref};
|
||||
use std::pin::Pin;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::thread::panicking;
|
||||
|
||||
use derive_destructure::destructure;
|
||||
use dyn_clone::{DynClone, clone_box};
|
||||
@@ -14,7 +14,7 @@ use futures::future::LocalBoxFuture;
|
||||
use futures::lock::Mutex;
|
||||
use futures::{SinkExt, StreamExt};
|
||||
use hashbrown::HashMap;
|
||||
use orchid_api_traits::{Channel, Coding, Decode, Encode, MsgSet, Request};
|
||||
use orchid_api_traits::{Channel, Coding, Decode, Encode, MsgSet, Request, enc_vec};
|
||||
use trait_set::trait_set;
|
||||
|
||||
use crate::clone;
|
||||
@@ -50,17 +50,23 @@ impl ReqHandlish for &'_ dyn ReqHandlish {
|
||||
fn defer_objsafe(&self, val: Pin<Box<dyn Future<Output = ()>>>) { (**self).defer_objsafe(val) }
|
||||
}
|
||||
|
||||
type LocalAsyncFnOnceBox = Box<dyn FnOnce(Vec<u8>) -> LocalBoxFuture<'static, ()>>;
|
||||
|
||||
#[derive(destructure)]
|
||||
pub struct RequestHandle<'a, MS: MsgSet> {
|
||||
defer: RefCell<Vec<Pin<Box<dyn Future<Output = ()>>>>>,
|
||||
fulfilled: AtomicBool,
|
||||
id: u64,
|
||||
_reqlt: PhantomData<&'a mut ()>,
|
||||
parent: ReqNot<MS>,
|
||||
raw_reply: RefCell<Option<LocalAsyncFnOnceBox>>,
|
||||
}
|
||||
impl<'a, MS: MsgSet + 'static> RequestHandle<'a, MS> {
|
||||
fn new(parent: ReqNot<MS>, id: u64) -> Self {
|
||||
Self { defer: RefCell::default(), fulfilled: false.into(), _reqlt: PhantomData, parent, id }
|
||||
pub fn new(parent: ReqNot<MS>, raw_reply: impl AsyncFnOnce(Vec<u8>) + 'static) -> Self {
|
||||
Self {
|
||||
defer: RefCell::default(),
|
||||
_reqlt: PhantomData,
|
||||
parent,
|
||||
raw_reply: RefCell::new(Some(Box::new(|v| Box::pin(raw_reply(v))))),
|
||||
}
|
||||
}
|
||||
pub fn reqnot(&self) -> ReqNot<MS> { self.parent.clone() }
|
||||
pub async fn handle<U: Request>(&self, _: &U, rep: &U::Response) -> Receipt<'a> {
|
||||
@@ -71,11 +77,9 @@ impl<'a, MS: MsgSet + 'static> RequestHandle<'a, MS> {
|
||||
self.respond(rep).await
|
||||
}
|
||||
pub async fn respond(&self, response: &impl Encode) -> Receipt<'a> {
|
||||
assert!(!self.fulfilled.swap(true, Ordering::Relaxed), "Already responded to {}", self.id);
|
||||
let mut buf = (!self.id).to_be_bytes().to_vec();
|
||||
response.encode(Pin::new(&mut buf)).await;
|
||||
let mut send = clone_box(&*self.reqnot().0.lock().await.send);
|
||||
(send)(&buf, self.parent.clone()).await;
|
||||
let replier = self.raw_reply.borrow_mut().take().expect("Already responded to request");
|
||||
let buf = enc_vec(response).await;
|
||||
(replier)(buf).await;
|
||||
let deferred = mem::take(&mut *self.defer.borrow_mut());
|
||||
for item in deferred {
|
||||
item.await
|
||||
@@ -90,8 +94,9 @@ impl<MS: MsgSet> ReqHandlish for RequestHandle<'_, MS> {
|
||||
}
|
||||
impl<MS: MsgSet> Drop for RequestHandle<'_, MS> {
|
||||
fn drop(&mut self) {
|
||||
let done = self.fulfilled.load(Ordering::Relaxed);
|
||||
debug_assert!(done, "Request {} dropped without response", self.id)
|
||||
if !panicking() {
|
||||
debug_assert!(self.raw_reply.borrow().is_none(), "Request dropped without response")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +156,17 @@ impl<T: MsgSet> ReqNot<T> {
|
||||
let mut req_cb = clone_box(&*g.req);
|
||||
mem::drop(g);
|
||||
let rn = self.clone();
|
||||
req_cb(RequestHandle::new(rn, id), message).await;
|
||||
let rn2 = self.clone();
|
||||
req_cb(
|
||||
RequestHandle::new(rn, async move |vec| {
|
||||
let mut buf = (!id).to_be_bytes().to_vec();
|
||||
buf.extend(vec);
|
||||
let mut send = clone_box(&*rn2.0.lock().await.send);
|
||||
(send)(&buf, rn2.clone()).await;
|
||||
}),
|
||||
message,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -123,6 +123,10 @@ impl Format for ForeignAtom {
|
||||
}
|
||||
}
|
||||
impl ToExpr for ForeignAtom {
|
||||
async fn to_expr(self) -> Expr
|
||||
where Self: Sized {
|
||||
self.ex()
|
||||
}
|
||||
async fn to_gen(self) -> GExpr { self.ex().to_gen().await }
|
||||
}
|
||||
|
||||
|
||||
@@ -241,11 +241,20 @@ pub fn extension_init(
|
||||
})
|
||||
.await,
|
||||
api::HostExtReq::SysReq(api::SysReq::SysFwded(fwd)) => {
|
||||
let fwd_tok = hand.will_handle_as(&fwd);
|
||||
let api::SysFwded(sys_id, payload) = fwd;
|
||||
let ctx = get_ctx(sys_id).await;
|
||||
with_ctx(ctx.clone(), async move {
|
||||
let sys = ctx.cted().inst();
|
||||
sys.dyn_request(hand, payload).await
|
||||
let reply = Rc::new(RefCell::new(None));
|
||||
let reply2 = reply.clone();
|
||||
let sub_hand = ExtReq::new(hand.reqnot(), async move |v| {
|
||||
reply2.borrow_mut().replace(v);
|
||||
});
|
||||
sys.dyn_request(sub_hand, payload).await;
|
||||
let reply_buf =
|
||||
reply.borrow_mut().take().expect("Request discarded but did not throw");
|
||||
hand.handle_as(fwd_tok, &reply_buf).await
|
||||
})
|
||||
.await
|
||||
},
|
||||
|
||||
@@ -2,6 +2,7 @@ use std::cell::RefCell;
|
||||
use std::fmt;
|
||||
use std::hash::Hash;
|
||||
use std::rc::Rc;
|
||||
use std::thread::panicking;
|
||||
|
||||
use async_once_cell::OnceCell;
|
||||
use derive_destructure::destructure;
|
||||
@@ -28,7 +29,7 @@ impl BorrowedExprStore {
|
||||
}
|
||||
impl Drop for BorrowedExprStore {
|
||||
fn drop(&mut self) {
|
||||
if self.0.borrow().is_some() {
|
||||
if self.0.borrow().is_some() && !panicking() {
|
||||
panic!("This should always be explicitly disposed")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,9 @@ fn process_args<I, O, F: ExprFunc<I, O>>(f: F) -> FunRecord {
|
||||
exec(async move |mut hand| {
|
||||
let mut norm_args = Vec::with_capacity(v.len());
|
||||
for (expr, typ) in v.into_iter().zip(argtyps) {
|
||||
if *typ != TypeId::of::<Expr>() {
|
||||
if *typ == TypeId::of::<Expr>() {
|
||||
norm_args.push(expr);
|
||||
} else {
|
||||
norm_args.push(hand.exec(expr).await?);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,9 +32,9 @@ pub async fn ext_command(
|
||||
.await;
|
||||
let mut stdout = child.stdout.take().unwrap();
|
||||
let header = api::ExtensionHeader::decode(Pin::new(&mut stdout)).await;
|
||||
let child_stderr = child.stderr.take().unwrap();
|
||||
let mut child_stderr = child.stderr.take().unwrap();
|
||||
(ctx.spawn)(Box::pin(async move {
|
||||
let mut reader = BufReader::new(child_stderr);
|
||||
let mut reader = BufReader::new(&mut child_stderr);
|
||||
loop {
|
||||
let mut buf = String::new();
|
||||
if 0 == reader.read_line(&mut buf).await.unwrap() {
|
||||
|
||||
@@ -48,13 +48,13 @@ pub async fn gen_macro_lib() -> Vec<GenMember> {
|
||||
mactreev!(macros::common::semi_list ( "...$" head 0 macros::common::; "...$" tail 1)),
|
||||
[async |[head, tail]| {
|
||||
call(sym_ref(sym!(std::tuple::cat; i())), [
|
||||
call(sym_ref(sym!(std::tuple::one; i())), [resolve(head).await]),
|
||||
call(sym_ref(sym!(std::tuple::one; i())), [head.to_gen().await]),
|
||||
resolve(mactree!(macros::common::semi_list "push" tail ;)).await,
|
||||
])
|
||||
}],
|
||||
)
|
||||
.rule(mactreev!(macros::common::semi_list ( "...$" final_tail 0 )), [async |[tail]| {
|
||||
call(sym_ref(sym!(std::tuple::one; i())), [resolve(tail).await])
|
||||
call(sym_ref(sym!(std::tuple::one; i())), [tail.to_gen().await])
|
||||
}])
|
||||
.rule(mactreev!(macros::common::semi_list()), [async |[]| {
|
||||
sym_ref(sym!(std::tuple::empty; i()))
|
||||
|
||||
@@ -144,7 +144,7 @@ impl Parser for MacroLine {
|
||||
let mac_cell = Rc::new(OnceCell::new());
|
||||
let rules = Rc::new(RefCell::new(Some(rules)));
|
||||
for (kw, sr) in &*keywords {
|
||||
clone!(mac_cell, rules, module, prio);
|
||||
clone!(mac_cell, rules, module, macro_name, prio);
|
||||
lines.push(ParsedLine::cnst(&sr.clone(), &comments, true, kw.clone(), async move |cctx| {
|
||||
let mac = mac_cell
|
||||
.get_or_init(async {
|
||||
@@ -170,7 +170,12 @@ impl Parser for MacroLine {
|
||||
.flat_map(stream::iter)
|
||||
.collect::<Vec<_>>()
|
||||
.await;
|
||||
Macro(Rc::new(MacroData { module, prio: prio.map(|i| i.0 as u64), rules }))
|
||||
Macro(Rc::new(MacroData {
|
||||
canonical_name: module.suffix([macro_name], &i()).await,
|
||||
module,
|
||||
prio: prio.map(|i| i.0 as u64),
|
||||
rules,
|
||||
}))
|
||||
})
|
||||
.await;
|
||||
atom(mac.clone())
|
||||
|
||||
@@ -18,7 +18,7 @@ use crate::macros::macro_lib::gen_macro_lib;
|
||||
use crate::macros::macro_line::MacroLine;
|
||||
use crate::macros::macro_value::Macro;
|
||||
use crate::macros::mactree_lexer::MacTreeLexer;
|
||||
use crate::macros::match_macros::gen_match_macro_lib;
|
||||
use crate::macros::match_macros::{MatcherAtom, gen_match_macro_lib};
|
||||
use crate::macros::ph_lexer::{PhAtom, PhLexer};
|
||||
use crate::macros::std_macros::gen_std_macro_lib;
|
||||
use crate::macros::utils::MacroBodyArgCollector;
|
||||
@@ -43,6 +43,7 @@ impl SystemCard for MacroSystem {
|
||||
Some(Macro::dynfo()),
|
||||
Some(PhAtom::dynfo()),
|
||||
Some(MacroBodyArgCollector::dynfo()),
|
||||
Some(MatcherAtom::dynfo()),
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -53,7 +54,13 @@ impl System for MacroSystem {
|
||||
sym!(macros::common::+; i()),
|
||||
sym!(macros::common::*; i()),
|
||||
sym!(macros::common::,; i()),
|
||||
sym!(macros::common::;; i()),
|
||||
sym!(macros::common::..; i()),
|
||||
sym!(macros::common::_; i()),
|
||||
sym!(std::tuple::t; i()),
|
||||
sym!(pattern::match; i()),
|
||||
sym!(pattern::ref; i()),
|
||||
sym!(pattern::=>; i()),
|
||||
]
|
||||
}
|
||||
fn lexers() -> Vec<LexerObj> { vec![&MacTreeLexer, &PhLexer] }
|
||||
|
||||
@@ -6,13 +6,13 @@ use orchid_base::interner::Tok;
|
||||
use orchid_base::name::Sym;
|
||||
use orchid_extension::atom::Atomic;
|
||||
use orchid_extension::atom_owned::{OwnedAtom, OwnedVariant};
|
||||
use orchid_extension::context::i;
|
||||
|
||||
use crate::macros::mactree::MacTreeSeq;
|
||||
use crate::macros::rule::matcher::Matcher;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MacroData {
|
||||
pub canonical_name: Sym,
|
||||
pub module: Sym,
|
||||
pub prio: Option<u64>,
|
||||
pub rules: Vec<Rule>,
|
||||
@@ -20,11 +20,6 @@ pub struct MacroData {
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Macro(pub Rc<MacroData>);
|
||||
impl Macro {
|
||||
pub async fn canonical_name(&self) -> Sym {
|
||||
self.0.module.suffix([self.0.rules[0].body_name.clone()], &i()).await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Rule {
|
||||
|
||||
@@ -89,47 +89,57 @@ pub async fn gen_match_macro_lib() -> Vec<GenMember> {
|
||||
matcher,
|
||||
}),
|
||||
build_macro(None, ["match", "match_rule", "_row", "=>"])
|
||||
.rule(mactreev!("pattern::match" { "..$" rules 0 }), [async |[rules]| {
|
||||
exec(async move |mut h| {
|
||||
let rule_lines = h
|
||||
.exec::<TAtom<Tuple>>(call(sym_ref(sym!(macros::resolve; i())), [
|
||||
mactree!(macros::common::semi_list "push" rules.clone();).to_gen().await,
|
||||
]))
|
||||
.await?;
|
||||
let mut rule_atoms = Vec::<(TAtom<MatcherAtom>, Expr)>::new();
|
||||
for line_exprh in rule_lines.iter() {
|
||||
let line_mac = h
|
||||
.exec::<TAtom<MacTree>>(Expr::from_handle(ExprHandle::from_ticket(*line_exprh).await))
|
||||
.await?;
|
||||
let Tpl((matcher, body)) = h
|
||||
.exec(call(sym_ref(sym!(macros::resolve; i())), [
|
||||
mactree!(pattern::_row "push" own(&line_mac).await ;).to_gen().await,
|
||||
.rule(mactreev!("pattern::match" "...$" value 0 { "..$" rules 0 }), [
|
||||
async |[value, rules]| {
|
||||
exec(async move |mut h| {
|
||||
let rule_lines = h
|
||||
.exec::<TAtom<Tuple>>(call(sym_ref(sym!(macros::resolve; i())), [
|
||||
mactree!(macros::common::semi_list "push" rules.clone();).to_gen().await,
|
||||
]))
|
||||
.await?;
|
||||
rule_atoms.push((matcher, body));
|
||||
}
|
||||
let base_case = lambda(0, [bot(mk_errv(
|
||||
i().i("No branches match").await,
|
||||
"None of the pattern provided matches this value",
|
||||
[rules.pos()],
|
||||
))]);
|
||||
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; i())), [
|
||||
mat.to_gen().await,
|
||||
arg(0),
|
||||
body.to_gen().await,
|
||||
call(tail, [arg(0)]),
|
||||
])])
|
||||
})
|
||||
.await;
|
||||
Ok(match_expr)
|
||||
})
|
||||
.await
|
||||
}])
|
||||
let mut rule_atoms = Vec::<(TAtom<MatcherAtom>, Expr)>::new();
|
||||
for line_exprh in rule_lines.iter() {
|
||||
let line_mac = h
|
||||
.exec::<TAtom<MacTree>>(Expr::from_handle(
|
||||
ExprHandle::from_ticket(*line_exprh).await,
|
||||
))
|
||||
.await?;
|
||||
let Tpl((matcher, body)) = h
|
||||
.exec(call(sym_ref(sym!(macros::resolve; i())), [
|
||||
mactree!(pattern::_row "push" own(&line_mac).await ;).to_gen().await,
|
||||
]))
|
||||
.await?;
|
||||
rule_atoms.push((matcher, body));
|
||||
}
|
||||
let base_case = lambda(0, [bot(mk_errv(
|
||||
i().i("No branches match").await,
|
||||
"None of the patterns matches this value",
|
||||
[rules.pos()],
|
||||
))]);
|
||||
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; i())), [
|
||||
mat.to_gen().await,
|
||||
arg(0),
|
||||
body.to_gen().await,
|
||||
call(tail, [arg(0)]),
|
||||
])])
|
||||
})
|
||||
.await;
|
||||
Ok(call(match_expr, [resolve(value).await]))
|
||||
})
|
||||
.await
|
||||
},
|
||||
])
|
||||
.rule(mactreev!(pattern::match_rule (( "...$" pattern 0 ))), [async |[pattern]| {
|
||||
resolve(mactree!(pattern::match_rule "push" pattern; )).await
|
||||
}])
|
||||
.rule(mactreev!(pattern::match_rule ( macros::common::_ )), [async |[]| {
|
||||
Ok(MatcherAtom {
|
||||
keys: Vec::new(),
|
||||
matcher: lambda(0, [OrcOpt(Some(Tpl(()))).to_gen().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)>> {
|
||||
|
||||
@@ -11,10 +11,10 @@ use orchid_base::name::Sym;
|
||||
use orchid_base::tree::Paren;
|
||||
use orchid_extension::atom::TAtom;
|
||||
use orchid_extension::atom_owned::own;
|
||||
use orchid_extension::context::i;
|
||||
use orchid_extension::context::{ctx, i};
|
||||
use orchid_extension::conv::ToExpr;
|
||||
use orchid_extension::coroutine_exec::{ExecHandle, exec};
|
||||
use orchid_extension::gen_expr::{GExpr, bot, call, lambda, sym_ref};
|
||||
use orchid_extension::gen_expr::{GExpr, arg, bot, call, lambda, sym_ref};
|
||||
use orchid_extension::reflection::{ReflMemKind, refl};
|
||||
use subslice_offset::SubsliceOffset;
|
||||
use substack::Substack;
|
||||
@@ -26,13 +26,17 @@ use crate::{MacTok, MacTree};
|
||||
|
||||
pub async fn resolve(tpl: MacTree) -> GExpr {
|
||||
exec(async move |mut h| {
|
||||
let ctx = ctx();
|
||||
// if ctx.logger().is_active() {
|
||||
writeln!(ctx.logger(), "Macro-resolving {}", fmt(&tpl, &i()).await);
|
||||
// }
|
||||
let root = refl();
|
||||
let mut macros = HashMap::new();
|
||||
for n in tpl.glossary() {
|
||||
if let Ok(ReflMemKind::Const) = root.get_by_path(n).await.map(|m| m.kind()) {
|
||||
let Ok(mac) = h.exec::<TAtom<Macro>>(sym_ref(n.clone())).await else { continue };
|
||||
let mac = own(&mac).await;
|
||||
macros.entry(mac.canonical_name().await).or_insert(mac);
|
||||
macros.entry(mac.0.canonical_name.clone()).or_insert(mac);
|
||||
}
|
||||
}
|
||||
let mut exclusive = Vec::new();
|
||||
@@ -87,7 +91,10 @@ async fn resolve_one(
|
||||
MacTok::Ph(_) | MacTok::Slot => panic!("Forbidden element in value mactree"),
|
||||
MacTok::Bottom(err) => bot(err.clone()),
|
||||
MacTok::Value(v) => v.clone().to_gen().await,
|
||||
MacTok::Name(n) => sym_ref(n.clone()),
|
||||
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()),
|
||||
},
|
||||
MacTok::Lambda(arg, body) => {
|
||||
let MacTok::Name(name) = &*arg.tok else {
|
||||
return bot(mk_errv(
|
||||
|
||||
@@ -182,7 +182,7 @@ mod test {
|
||||
.await,
|
||||
];
|
||||
let matcher = mk_any(&pattern).await.expect("This matcher isn't broken");
|
||||
println!("{matcher}");
|
||||
eprintln!("{matcher}");
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ pub async fn gen_std_macro_lib() -> Vec<GenMember> {
|
||||
fun(false, "is_some_body", |sub: TAtom<MatcherAtom>, val: OrcOpt<Expr>| {
|
||||
exec(async move |mut h| {
|
||||
let Some(sub_val) = val.0 else { return Ok(OrcOpt(None)) };
|
||||
h.exec::<OrcOpt<Expr>>(call(sub.to_gen().await, [sub_val.to_gen().await])).await
|
||||
sub.run_matcher(&mut h, sub_val).await
|
||||
})
|
||||
}),
|
||||
fun(false, "is_none_body", async |val: OrcOpt<Expr>| {
|
||||
@@ -81,12 +81,12 @@ pub async fn gen_std_macro_lib() -> Vec<GenMember> {
|
||||
})
|
||||
}])
|
||||
.rule(
|
||||
mactreev!(pattern::match_rule(std::tuple::t[ "...$" elements 0 macros::common::..])),
|
||||
mactreev!(pattern::match_rule(std::tuple::t[ "...$" elements 0 macros::common::, macros::common::..])),
|
||||
[async |[elements]: [_; _]| parse_tpl(elements, Some(mactree!(macros::common::_))).await],
|
||||
)
|
||||
.rule(
|
||||
mactreev!(pattern::match_rule(
|
||||
std::tuple::t[ "...$" elements 1 macros::common::.. "...$" tail 0]
|
||||
std::tuple::t[ "...$" elements 1 macros::common::, macros::common::.. "...$" tail 0]
|
||||
)),
|
||||
[async |[elements, tail]: [_; _]| parse_tpl(elements, Some(tail)).await],
|
||||
)
|
||||
@@ -111,7 +111,7 @@ fn parse_tpl(elements: MacTree, tail_matcher: Option<MacTree>) -> impl Future<Ou
|
||||
let mac = own(mac_a).await;
|
||||
let sub = h
|
||||
.exec::<TAtom<MatcherAtom>>(call(sym_ref(sym!(macros::resolve; i())), [
|
||||
mactree!(pattern::match_rule "push" mac ;).to_gen().await,
|
||||
mactree!(pattern::match_rule ("push" mac ;)).to_gen().await,
|
||||
]))
|
||||
.await?;
|
||||
subs.push(sub);
|
||||
@@ -146,7 +146,7 @@ fn tuple_matcher_body(
|
||||
tail: OrcOpt<TAtom<MatcherAtom>>,
|
||||
value: HomoTpl<Expr>,
|
||||
) -> impl Future<Output = GExpr> {
|
||||
exec(async move |mut h| -> OrcRes<OrcOpt<GExpr>> {
|
||||
exec(async move |mut h| -> OrcRes<OrcOpt<HomoTpl<Expr>>> {
|
||||
if value.0.len() < children.0.len() {
|
||||
return Ok(OrcOpt(None));
|
||||
}
|
||||
@@ -172,6 +172,6 @@ fn tuple_matcher_body(
|
||||
}
|
||||
},
|
||||
};
|
||||
todo!()
|
||||
Ok(OrcOpt(Some(HomoTpl(binds))))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -105,6 +105,7 @@ impl MacroBuilder {
|
||||
.expect("Default macro in global root");
|
||||
MemKind::Const(
|
||||
Macro(Rc::new(MacroData {
|
||||
canonical_name: module.suffix([i().i(name).await], &i()).await,
|
||||
module,
|
||||
prio,
|
||||
rules: stream(async |mut h| {
|
||||
|
||||
@@ -323,7 +323,7 @@ async fn main() -> io::Result<ExitCode> {
|
||||
let root = root.add_parsed(&entrypoint, path.clone(), &reporter).await;
|
||||
let expr = ExprKind::Const(sym!(usercode::entrypoint; i)).at(prefix_sr.pos());
|
||||
let mut xctx = ExecCtx::new(ctx.clone(), logger.clone(), root, expr).await;
|
||||
xctx.set_gas(Some(1000));
|
||||
xctx.set_gas(Some(10_000));
|
||||
xctx.execute().await;
|
||||
match xctx.result() {
|
||||
ExecResult::Value(val) =>
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
thread 'main' panicked at /rust/deps\annotate-snippets-0.9.2\src\display_list\from_snippet.rs:275:9:
|
||||
SourceAnnotation range `(100, 102)` is bigger than source length `100`
|
||||
stack backtrace:
|
||||
0: 0x7fffc1edead3 - std::backtrace_rs::backtrace::dbghelp64::trace
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\..\..\backtrace\src\backtrace\dbghelp64.rs:91
|
||||
1: 0x7fffc1edead3 - std::backtrace_rs::backtrace::trace_unsynchronized
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\..\..\backtrace\src\backtrace\mod.rs:66
|
||||
2: 0x7fffc1edead3 - std::backtrace::Backtrace::create
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\backtrace.rs:331
|
||||
3: 0x7fffc1edea1a - std::backtrace::Backtrace::force_capture
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\backtrace.rs:312
|
||||
4: 0x7fffc350c6bd - core[fb98b8b4feea0183]::slice::sort::unstable::heapsort::heapsort::<((rustc_lint_defs[b054f3c0774bcbdc]::Level, &str), usize), <((rustc_lint_defs[b054f3c0774bcbdc]::Level, &str), usize) as core[fb98b8b4feea0183]::cmp::PartialOrd>::lt>
|
||||
5: 0x7fffc1efa4ae - alloc::boxed::impl$30::call
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\alloc\src\boxed.rs:2027
|
||||
6: 0x7fffc1efa4ae - std::panicking::rust_panic_with_hook
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\panicking.rs:836
|
||||
7: 0x7fffc1efa209 - std::panicking::begin_panic_handler::closure$0
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\panicking.rs:701
|
||||
8: 0x7fffc1ef78af - std::sys::backtrace::__rust_end_short_backtrace<std::panicking::begin_panic_handler::closure_env$0,never$>
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\sys\backtrace.rs:168
|
||||
9: 0x7fffc1ef9e0e - std::panicking::begin_panic_handler
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\panicking.rs:692
|
||||
10: 0x7fffc4ddba91 - core::panicking::panic_fmt
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\core\src\panicking.rs:75
|
||||
11: 0x7ff6008d1f04 - <unknown>
|
||||
12: 0x7ff6006c56c5 - <unknown>
|
||||
13: 0x7fffc1f29a2a - core::fmt::rt::Argument::fmt
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\core\src\fmt\rt.rs:177
|
||||
14: 0x7fffc1f29a2a - core::fmt::write
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\core\src\fmt\mod.rs:1440
|
||||
15: 0x7fffc1eea19b - std::io::Write::write_fmt
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\io\mod.rs:1887
|
||||
16: 0x7fffc1eea19b - std::io::stdio::impl$26::write_fmt
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\io\stdio.rs:1024
|
||||
17: 0x7fffc1eeade6 - std::io::stdio::impl$25::write_fmt
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\io\stdio.rs:998
|
||||
18: 0x7fffc1eeade6 - std::io::stdio::print_to
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\io\stdio.rs:1122
|
||||
19: 0x7fffc1eeade6 - std::io::stdio::_eprint
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\io\stdio.rs:1244
|
||||
20: 0x7ff6005a494b - <unknown>
|
||||
21: 0x7ff6005a065d - <unknown>
|
||||
22: 0x7ff60059c57c - <unknown>
|
||||
23: 0x7ff60058a246 - <unknown>
|
||||
24: 0x7ff60058a70c - <unknown>
|
||||
25: 0x7fffc1edc62c - std::rt::lang_start_internal::closure$1
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\rt.rs:174
|
||||
26: 0x7fffc1edc62c - std::panicking::try::do_call
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\panicking.rs:584
|
||||
27: 0x7fffc1edc62c - std::panicking::try
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\panicking.rs:547
|
||||
28: 0x7fffc1edc62c - std::panic::catch_unwind
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\panic.rs:358
|
||||
29: 0x7fffc1edc62c - std::rt::lang_start_internal
|
||||
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\rt.rs:174
|
||||
30: 0x7ff6005a5dbc - <unknown>
|
||||
31: 0x7ff6008e3bd0 - <unknown>
|
||||
32: 0x7ff8c09a7374 - BaseThreadInitThunk
|
||||
33: 0x7ff8c167cc91 - RtlUserThreadStart
|
||||
|
||||
|
||||
rustc version: 1.86.0-nightly (b1a7dfb91 2025-01-10)
|
||||
platform: x86_64-pc-windows-msvc
|
||||
Reference in New Issue
Block a user