From a93092e925c24c54830cf3de40a2c61b00d8636c Mon Sep 17 00:00:00 2001 From: mehbark Date: Fri, 2 Jan 2026 00:09:49 -0500 Subject: [PATCH] better parser labelling --- src/ast.rs | 4 +++- src/parser.rs | 64 ++++++++++++++++++++++++++++----------------------- 2 files changed, 38 insertions(+), 30 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index e85b72c..f8e96dc 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -13,7 +13,7 @@ pub enum Ident { pub enum Ast { /// `x`, `^x` Var(Ident), - /// `x = y; => y` + /// `x := y; #=> y` Set(Ident, Box), /// `fn ([a b] [c d]) ( ... )` Fn { @@ -29,4 +29,6 @@ pub enum Ast { BinOp(Box, fn(Val, Val) -> Val, Box), /// `3` Num(f64), + /// `(println bla; 3) #=> 3` + Block(Vec), } diff --git a/src/parser.rs b/src/parser.rs index a2958a0..ecb4145 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -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::() { - 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::() { + 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 { 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";