Experiment with monadic bind.

This commit is contained in:
KtorZ
2024-03-10 11:26:41 +01:00
parent 0e0bed3c9d
commit 1f530f3b24
6 changed files with 109 additions and 20 deletions

View File

@@ -1,10 +1,9 @@
use chumsky::prelude::*;
use crate::{
ast,
expr::UntypedExpr,
parser::{annotation, error::ParseError, pattern, token::Token},
};
use chumsky::prelude::*;
pub fn let_(
r: Recursive<'_, Token, UntypedExpr, ParseError>,
@@ -12,9 +11,9 @@ pub fn let_(
just(Token::Let)
.ignore_then(pattern())
.then(just(Token::Colon).ignore_then(annotation()).or_not())
.then_ignore(just(Token::Equal))
.then(choice((just(Token::Equal), just(Token::LArrow))))
.then(r.clone())
.validate(move |((pattern, annotation), value), span, emit| {
.validate(move |(((pattern, annotation), kind), value), span, emit| {
if matches!(value, UntypedExpr::Assignment { .. }) {
emit(ParseError::invalid_assignment_right_hand_side(span))
}
@@ -23,7 +22,11 @@ pub fn let_(
location: span,
value: Box::new(value),
pattern,
kind: ast::AssignmentKind::Let,
kind: if kind == Token::LArrow {
ast::AssignmentKind::Bind
} else {
ast::AssignmentKind::Let
},
annotation,
}
})

View File

@@ -163,6 +163,8 @@ pub fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = ParseError> {
just("!=").to(Token::NotEqual),
just('!').to(Token::Bang),
just('?').to(Token::Question),
just("<-").to(Token::LArrow),
just("->").to(Token::RArrow),
choice((
just("<=").to(Token::LessEqual),
just('<').to(Token::Less),
@@ -170,7 +172,6 @@ pub fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = ParseError> {
just('>').to(Token::Greater),
)),
just('+').to(Token::Plus),
just("->").to(Token::RArrow),
just('-').to(Token::Minus),
just('*').to(Token::Star),
just('/').to(Token::Slash),

View File

@@ -62,6 +62,7 @@ pub enum Token {
Pipe, // '|>'
Dot, // '.'
RArrow, // '->'
LArrow, // '<-'
DotDot, // '..'
EndOfFile,
// Docs/Extra
@@ -152,6 +153,7 @@ impl fmt::Display for Token {
Token::Pipe => "|>",
Token::Dot => ".",
Token::RArrow => "->",
Token::LArrow => "<-",
Token::DotDot => "..",
Token::EndOfFile => "EOF",
Token::Comment => "//",