bit of cleanup, few steps towards commands demo

This commit is contained in:
2026-04-18 15:13:27 +00:00
parent 6eed6b9831
commit 60c96964d9
12 changed files with 228 additions and 538 deletions

View File

@@ -13,61 +13,6 @@ use crate::macros::mactree::MacTreeSeq;
use crate::macros::rule::state::{MatchState, StateEntry};
use crate::{MacTok, MacTree};
/// # TODO
///
/// convert macro system to return MacTree or otherwise bring it up to
/// speed with the new [ToExpr] / [GExpr] division
///
/// Idea: MacTree needs to be passed wherever the meaning of an expression can
/// change depending on where in the tree it is bound
///
/// Idea: lowering MacTree to ToExpr implementors is possible by just knowing
/// what names are bound, not their values, but lowering it to GExpr is not.
///
/// Problem: The required information is stackbound, so recursive macro matching
/// needs to be a single coroutine. Even when it forks out to Orchid, recursive
/// calls need to point back to this coroutine. Being a coroutine, this
/// recursion can overflow the Rust stack.
///
/// Limits:
///
/// - The concrete MacTree being generated sometimes depends on recursive macro
/// calls which need to complete before we return a MacTree
/// - Any placeholders representing expressions must be recursed over before
/// returning in a MacTree
/// - Exactly one of these things must be done on a subtree
///
/// Takeaways:
///
/// - Resolution should not lower to GExpr
/// - Consider separate types MacTree vs resolved tree
/// - MacTree can be built for the purpose of passing into recur
/// - Resolved tree can be built for the purpose of returning
/// - cannot contain [...], {...}, (), ( ... \. )
/// - is pretty much GExpr with sym / dynamic arg binding instead of
/// numbered. Can this be a wrapper type over ToExpr instead?
/// - In order to move recursive state off the stack, we need a loophole
/// for lambdas
/// - Ensures that resolution only happens exactly once which is important
/// because double resolve can produce bugs that are difficult to catch
/// - Macros may return ResolvedTree but they can also return a datastructure
/// containing MacTree
/// - Macros may never lower ResolvedTree to GExpr directly because it may
/// refer to bound arguments by name
/// - Macros returning datastructures can only ever be called as logic while
/// those returning ResolvedTree can only ever be inlined
/// - this is a type system concern so addressing it here is unnecessary
///
/// Problems:
/// - ToExpr are not usually copiable by default
/// - plain-orchid macros should be able to annotate data-to-return and
/// data-to-resolve with the same tick symbol to limit conceptual complexity,
/// - the case where a macro deliberately wants to bind a name explicitly within
/// a subexpression is tricky
///
/// The best option probably remains for resolve to process and return MacTree,
/// and for there to be a separate "lower" function. Nothing as yet suggests
/// however that macros can't be allowed to return different types
pub async fn resolve(h: &mut ExecHandle<'_>, val: MacTree) -> MacTree {
writeln!(log("debug"), "Macro-resolving {}", fmt(&val).await).await;
let root = refl();
@@ -290,10 +235,6 @@ async fn resolve_seq(
*item = new;
any_match = true;
}
/* TODO:
The macro system was previously built on the assumption that whatever is returned by call_body
can never be matched. This is no longer true, but now double-matches are possible. Address this.
*/
any_match.then_some(MacTreeSeq::new(new_val))
}