Macro system done in theory

too afraid to begin debugging, resting for a moment
This commit is contained in:
2025-09-03 16:05:26 +02:00
parent 051b5e666f
commit 7031f3a7d8
51 changed files with 1463 additions and 458 deletions

View File

@@ -1,12 +1,16 @@
use std::ops::RangeInclusive;
use std::rc::Rc;
use futures::FutureExt;
use orchid_base::error::{OrcRes, mk_errv};
use orchid_base::parse::ParseCtx;
use orchid_base::sym;
use orchid_base::tokens::PARENS;
use orchid_base::tree::Paren;
use orchid_extension::lexer::{LexContext, Lexer, err_not_applicable};
use orchid_extension::tree::{GenTok, GenTokTree, x_tok};
use orchid_extension::parser::p_tree2gen;
use orchid_extension::tree::{GenTok, GenTokTree, ref_tok, x_tok};
use crate::macros::let_line::parse_tok;
use crate::macros::mactree::{MacTok, MacTree};
#[derive(Default)]
@@ -15,24 +19,41 @@ impl Lexer for MacTreeLexer {
const CHAR_FILTER: &'static [RangeInclusive<char>] = &['\''..='\''];
async fn lex<'a>(tail: &'a str, ctx: &'a LexContext<'a>) -> OrcRes<(&'a str, GenTokTree)> {
let Some(tail2) = tail.strip_prefix('\'') else {
return Err(err_not_applicable(ctx.i()).await.into());
return Err(err_not_applicable(ctx.i()).await);
};
let tail3 = tail2.trim_start();
return match mac_tree(tail3, ctx).await {
Ok((tail4, mactree)) => Ok((tail4, x_tok(mactree).at(ctx.pos_tt(tail, tail4)))),
let mut args = Vec::new();
return match mac_tree(tail3, &mut args, ctx).await {
Ok((tail4, mactree)) => {
let range = ctx.pos_tt(tail, tail4);
let tok = match &args[..] {
[] => x_tok(mactree).await,
_ => {
let call = ([
ref_tok(sym!(macros::instantiate_tpl; ctx.i()).await).await.at(range.clone()),
x_tok(mactree).await.at(range.clone()),
]
.into_iter())
.chain(args.into_iter());
GenTok::S(Paren::Round, call.collect())
},
};
Ok((tail4, tok.at(range)))
},
Err(e) => Ok((tail2, GenTok::Bottom(e).at(ctx.pos_lt(1, tail2)))),
};
async fn mac_tree<'a>(tail: &'a str, ctx: &'a LexContext<'a>) -> OrcRes<(&'a str, MacTree)> {
async fn mac_tree<'a>(
tail: &'a str,
args: &mut Vec<GenTokTree>,
ctx: &'a LexContext<'a>,
) -> OrcRes<(&'a str, MacTree)> {
for (lp, rp, paren) in PARENS {
let Some(mut body_tail) = tail.strip_prefix(*lp) else { continue };
let mut items = Vec::new();
return loop {
let tail2 = body_tail.trim();
let tail2 = body_tail.trim_start();
if let Some(tail3) = tail2.strip_prefix(*rp) {
break Ok((tail3, MacTree {
pos: ctx.pos_tt(tail, tail3).pos(),
tok: Rc::new(MacTok::S(*paren, items)),
}));
break Ok((tail3, MacTok::S(*paren, items).at(ctx.pos_tt(tail, tail3).pos())));
} else if tail2.is_empty() {
return Err(mk_errv(
ctx.i().i("Unclosed block").await,
@@ -40,22 +61,36 @@ impl Lexer for MacTreeLexer {
[ctx.pos_lt(1, tail)],
));
}
let (new_tail, new_item) = mac_tree(tail2, ctx).boxed_local().await?;
let (new_tail, new_item) = mac_tree(tail2, args, ctx).boxed_local().await?;
body_tail = new_tail;
items.push(new_item);
};
}
const INTERPOL: &[&str] = &["$", "..$"];
for pref in INTERPOL {
let Some(code) = tail.strip_prefix(pref) else { continue };
todo!("Register parameter, and push this onto the argument stack held in the atom")
if let Some(tail2) = tail.strip_prefix("$") {
let (tail3, sub) = ctx.recurse(tail2).await?;
let sr = ctx.pos_tt(tail, tail3);
args.push(p_tree2gen(sub));
return Ok((tail3, MacTok::Slot.at(sr.pos())));
}
if let Some(tail2) = tail.strip_prefix("\\") {
let tail2 = tail2.trim_start();
let (mut tail3, param) = mac_tree(tail2, args, ctx).boxed_local().await?;
let mut body = Vec::new();
loop {
let tail4 = tail3.trim_start();
if tail4.is_empty() || tail4.starts_with(|c| ")]}".contains(c)) {
break;
};
let (tail5, body_tok) = mac_tree(tail4, args, ctx).boxed_local().await?;
body.push(body_tok);
tail3 = tail5;
}
Ok((tail3, MacTok::Lambda(param, body).at(ctx.pos_tt(tail, tail3).pos())))
} else {
let (tail2, sub) = ctx.recurse(tail).await?;
let parsed = parse_tok(&sub, ctx).await.expect("Unexpected invalid token");
Ok((tail2, parsed))
}
todo!("recursive lexer call");
return Err(mk_errv(
ctx.i().i("Expected token after '").await,
format!("Expected a token after ', found {tail:?}"),
[ctx.pos_lt(1, tail)],
));
}
}
}