better parser labelling

This commit is contained in:
mehbark 2026-01-02 00:09:49 -05:00
parent cb714e70b7
commit a93092e925
2 changed files with 38 additions and 30 deletions

View file

@ -13,7 +13,7 @@ pub enum Ident {
pub enum Ast {
/// `x`, `^x`
Var(Ident),
/// `x = y; => y`
/// `x := y; #=> y`
Set(Ident, Box<Ast>),
/// `fn ([a b] [c d]) ( ... )`
Fn {
@ -29,4 +29,6 @@ pub enum Ast {
BinOp(Box<Ast>, fn(Val, Val) -> Val, Box<Ast>),
/// `3`
Num(f64),
/// `(println bla; 3) #=> 3`
Block(Vec<Ast>),
}

View file

@ -93,35 +93,42 @@ where
select! {
Token::Var(s) => Ident::Local(s.to_owned()),
},
));
// let semicolon = just(Token::Semicolon).repeated().at_least(1);
choice((
just(Token::OpenParen)
.ignore_then(expr.clone())
.then_ignore(just(Token::CloseParen)),
// expr.clone()
// .then(expr.clone())
// .map(|(f, x)| Ast::App(Box::new(f), Box::new(x))),
ident
.clone()
.then_ignore(just(Token::Set))
.then(expr)
.map(|(id, val)| Ast::Set(id, Box::new(val))),
ident.map(Ast::Var),
select! {
Token::Num(n) => n,
}
.validate(|n, e, emitter| match n.parse::<f64>() {
Ok(n) => Ast::Num(n),
Err(err) => {
emitter.emit(Rich::custom(e.span(), format!("Invalid number: {err}")));
error_ast()
}
}),
))
.labelled("identifier");
let set = ident
.clone()
.then_ignore(just(Token::Set))
.then(expr.clone())
.map(|(id, val)| Ast::Set(id, Box::new(val)))
.labelled("assignment");
let num = select! {
Token::Num(n) => n,
}
.validate(|n, e, emitter| match n.parse::<f64>() {
Ok(n) => Ast::Num(n),
Err(err) => {
emitter.emit(Rich::custom(e.span(), format!("Invalid number: {err}")));
error_ast()
}
})
.labelled("number");
let semicolon = just(Token::Semicolon)
.repeated()
.at_least(1)
.labelled("semicolon");
let block = just(Token::OpenParen)
.ignore_then(expr.clone().separated_by(semicolon).collect())
.then_ignore(just(Token::CloseParen))
.map(Ast::Block)
.labelled("block");
choice((set, ident.map(Ast::Var).labelled("variable"), num, block))
})
.labelled("expression")
.then_ignore(just(Token::Semicolon).repeated().at_least(1))
.repeated()
.collect()
@ -134,8 +141,7 @@ pub fn parse(src: &str) -> Vec<Ast> {
Err(()) => (Token::Error, span.into()),
});
let token_stream =
Stream::from_iter(token_iter).map((0..src.len()).into(), |(t, s): (_, _)| (t, s));
let token_stream = Stream::from_iter(token_iter).map((src.len()..src.len()).into(), |x| x);
let source_filename = "input";