This commit is contained in:
LunarAkai 2025-08-07 03:10:20 +02:00
commit 092dc94117

View file

@ -1,5 +1,5 @@
use chumsky::{
combinator::Or, error::Rich, extra, input::ValueInput, prelude::{choice, just, recursive}, recursive, select, select_ref, span::SimpleSpan, text::{self, ascii::ident, whitespace}, IterParser, Parser
combinator::Or, error::Rich, extra, input::ValueInput, prelude::{choice, just, recursive}, primitive::select, recursive, select, select_ref, span::SimpleSpan, text::{self, ascii::{ident, keyword}, whitespace}, Boxed, IterParser, Parser
};
use crate::{language_frontend::abstract_syntax_tree::ast::Expression, language_frontend::lexer::tokens::Token};
@ -7,17 +7,32 @@ use crate::{language_frontend::abstract_syntax_tree::ast::Expression, language_f
// goal of parsing is to construct an abstract syntax tree
#[allow(clippy::let_and_return)]
pub fn parser<'tokens, 'src: 'tokens, I>() -> impl Parser<'tokens, I, Expression<'src>, extra::Err<Rich<'tokens, Token<'src>>>>
pub fn parser<'tokens, 'src: 'tokens, I>()
-> impl Parser<'tokens, I, Expression<'src>, extra::Err<Rich<'tokens, Token<'src>>>>
where
I: ValueInput<'tokens, Token = Token<'src>, Span = SimpleSpan>,
{
let ident = select! {
Token::Ident(s) => s,
};
let keyword = |kw: &'static str| {
select! {
Token::Keyword(k) if k == kw => (),
}
};
let eq = just(Token::Equals).labelled("=");
let expr = recursive(|expr| {
let atom = select! {
Token::Float(x) => Expression::Float(x),
Token::Integer(x) => Expression::Integer(x),
};
}.or(expr.clone().delimited_by(just(Token::ParenBegin), just(Token::ParenEnd)));
let unary = just(Token::Substract)
.repeated()
@ -40,8 +55,37 @@ where
_ => unreachable!(),
},
);
add_sub
});
expr
let decl = recursive(|decl| {
let var = keyword("var")
.ignore_then(ident)
.then_ignore(eq.clone())
.then(expr.clone())
.then(decl.clone())
.map(|((name, rhs), then)| Expression::Var {
name,
rhs: Box::new(rhs),
then: Box::new(then),
});
let fun = keyword("fun")
.ignore_then(ident.clone())
.then(ident.repeated().collect::<Vec<_>>())
.then_ignore(eq.clone())
.then(expr.clone())
.then(decl)
.map(|(((name, args), body), then)| Expression::Function {
name,
args,
body: Box::new(body),
then: Box::new(then),
});
var.or(fun).or(expr)
});
decl
}