New macro system and stdlib additions

This commit is contained in:
2025-11-21 14:25:03 +01:00
parent b77653f841
commit 603efef28e
230 changed files with 3033 additions and 16640 deletions

View File

@@ -0,0 +1,78 @@
use itertools::{Itertools, chain};
use orchid_base::error::{OrcRes, mk_errv};
use orchid_base::interner::Tok;
use orchid_base::name::Sym;
use orchid_base::parse::{
Import, ParseCtx, Parsed, Snippet, expect_tok, line_items, parse_multiname, token_errv,
};
use orchid_base::tree::{Paren, Token};
use orchid_extension::parser::{
PTokTree, ParsCtx, ParsedLine, ParsedLineKind, p_tree2gen, p_v2gen,
};
pub async fn parse_impls(
ctx: &ParsCtx<'_>,
lines: &mut Vec<ParsedLine>,
impls: &mut Vec<(Sym, Tok<String>)>,
body_tt: &PTokTree,
) -> OrcRes<()> {
let i = ctx.i().clone();
let body = match &body_tt.tok {
Token::S(Paren::Round, body) => line_items(ctx, Snippet::new(body_tt, body)).await,
Token::S(ptyp, _) =>
return Err(mk_errv(
i.i("Incorrect paren type").await,
format!("Expected () block, found {ptyp}"),
[body_tt.sr().pos()],
)),
_ =>
return Err(
token_errv(ctx, body_tt, "Expected body", |s| {
format!("Expected (impl ...) block, found {s}")
})
.await,
),
};
for Parsed { tail: line, output: comments } in body {
if let Ok(Parsed { tail, .. }) = expect_tok(ctx, line, i.i("impl").await).await {
let Parsed { tail, output: name_tt } = parse_multiname(ctx, tail).await?;
let (name, name_sr) = match name_tt.into_iter().at_most_one() {
Ok(None) => panic!("multiname is always at least one name"),
Ok(Some(ref n @ Import { name: Some(_), ref sr, .. })) =>
(n.clone().mspath().to_sym(&i).await, sr.clone()),
Ok(Some(Import { name: None, sr, .. })) =>
return Err(mk_errv(
i.i("impl line with globstar").await,
"::* is not permitted in a protocol impl",
[sr.pos()],
)),
Err(e) =>
return Err(mk_errv(
i.i("Impl line with multiple protocol names").await,
"::() is not permitted in a protocol impl",
e.map(|i| i.sr.pos()),
)),
};
let Parsed { tail, .. } = expect_tok(ctx, tail, i.i("as").await).await?;
let cnst_name = i.i(&format!("{}{}", lines.len(), name.iter().join("__"))).await;
lines.push(ParsedLine {
comments,
sr: line.sr(),
kind: ParsedLineKind::Rec(Vec::from_iter(chain![
[Token::Name(i.i("let").await).at(line.sr())],
[Token::Name(cnst_name.clone()).at(name_sr)],
[Token::Name(i.i("=").await).at(line.sr())],
tail.iter().cloned().map(p_tree2gen),
])),
});
impls.push((name, cnst_name));
} else {
lines.push(ParsedLine {
sr: line.sr(),
comments,
kind: ParsedLineKind::Rec(p_v2gen(line.to_vec())),
});
}
}
Ok(())
}