Various progress, doesnt compile

Added prelude, made lambdas a single-token prefix like NS, made progress on implementations, removed const line type
This commit is contained in:
2025-07-31 00:30:41 +02:00
parent 19f2c6426a
commit 769c6cfc9f
31 changed files with 450 additions and 250 deletions

View File

@@ -39,7 +39,9 @@ pub enum MacTok {
/// Only permitted in arguments to `instantiate_tpl`
Slot,
Value(Expr),
Lambda(Vec<MacTree>, Vec<MacTree>),
Lambda(MacTree, Vec<MacTree>),
/// Only permitted in "pattern" values produced by macro blocks, which are
/// never accessed as variables by usercode
Ph(Ph),
}
impl Format for MacTok {
@@ -50,7 +52,7 @@ impl Format for MacTok {
tl_cache!(Rc<Variants>: Rc::new(Variants::default()
.unbounded("\\{0b}.{1l}")
.bounded("(\\{0b}.{1b})"))),
[mtreev_fmt(arg, c).await, mtreev_fmt(b, c).await],
[arg.print(c).await, mtreev_fmt(b, c).await],
),
Self::Name(n) => format!("{n}").into(),
Self::Ph(ph) => format!("{ph}").into(),
@@ -96,3 +98,41 @@ pub enum PhKind {
Scalar,
Vector { at_least_one: bool, priority: u8 },
}
pub fn map_mactree(
tpl: &MacTree,
map: &mut impl FnMut(MacTree) -> Option<MacTree>,
argv: &mut impl Iterator<Item = MacTree>,
changed: &mut bool,
) -> MacTree {
let tok = match &*tpl.tok {
MacTok::Slot => {
*changed = true;
return argv.next().expect("Not enough arguments to fill all slots!");
},
MacTok::Lambda(arg, body) => MacTok::Lambda(
ro(changed, |changed| instantiate_tpl(arg, argv, changed)),
instantiate_tpl_v(body, argv, changed),
),
MacTok::Name(_) | MacTok::Value(_) => return tpl.clone(),
MacTok::Ph(_) => panic!("instantiate_tpl received a placeholder"),
MacTok::S(p, body) => MacTok::S(*p, instantiate_tpl_v(body, argv, changed)),
};
if *changed { MacTree { pos: tpl.pos.clone(), tok: Rc::new(tok) } } else { tpl.clone() }
}
pub fn map_mactree_v(
tpl: &[MacTree],
argv: &mut impl Iterator<Item = MacTree>,
changed: &mut bool,
) -> Vec<MacTree> {
tpl.iter().map(|tree| ro(changed, |changed| instantiate_tpl(tree, argv, changed))).collect_vec()
}
/// reverse "or". Inside, the flag is always false, but raising it will raise
/// the outside flag too.
fn ro<T>(flag: &mut bool, cb: impl FnOnce(&mut bool) -> T) -> T {
let mut new_flag = false;
let val = cb(&mut new_flag);
*flag |= new_flag;
val
}