add parsing for expression blocks

main
NotAFile 2022-04-05 14:14:49 +02:00
parent da0d1dd6d8
commit 2dd99ae641
3 changed files with 36 additions and 7 deletions

View File

@ -219,7 +219,7 @@ impl Context {
typ: self.types.primitives.infer, typ: self.types.primitives.infer,
} }
} }
BlockExpr::Block(_) => todo!(), BlockExpr::Block(block) => todo!(),
}, },
}; };
Ok(t_expr) Ok(t_expr)

View File

@ -2,21 +2,29 @@ use nom::{
branch::alt, branch::alt,
combinator::map, combinator::map,
error::context, error::context,
multi::separated_list1, multi::{many0, separated_list1},
sequence::{delimited, separated_pair, tuple}, sequence::{delimited, separated_pair, terminated, tuple},
}; };
use crate::parser::{ use crate::parser::{
expression::{expression, Expression}, expression::{expression, Expression},
tokens::{token, TokenKind as tk, TokenSpan}, tokens::{token, Token, TokenKind as tk, TokenSpan},
IResult, IResult,
}; };
/// a block that is a single expression
#[derive(Debug, Clone)]
pub struct ExpressionBlock<'a> {
assignments: Vec<(Token<'a>, Expression<'a>)>,
value: Expression<'a>,
}
/// an expression that contains a block
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum BlockExpr<'a> { pub enum BlockExpr<'a> {
IfElse(IfElseBlock), IfElse(IfElseBlock),
Match(MatchBlock<'a>), Match(MatchBlock<'a>),
Block(Vec<BlockExpr<'a>>), Block(ExpressionBlock<'a>),
} }
// TODO: postponed because annoying to implement // TODO: postponed because annoying to implement
@ -51,6 +59,25 @@ fn match_block(input: TokenSpan) -> IResult<TokenSpan, MatchBlock> {
)(input) )(input)
} }
pub fn block_expr(input: TokenSpan) -> IResult<TokenSpan, BlockExpr> { fn expression_block(input: TokenSpan) -> IResult<TokenSpan, ExpressionBlock> {
alt((map(match_block, BlockExpr::Match),))(input) map(
tuple((
many0(tuple((
delimited(token(tk::Let), token(tk::Ident), token(tk::EqAssign)),
terminated(expression, token(tk::Semicolon)),
))),
expression,
)),
|(assignments, value)| ExpressionBlock { assignments, value },
)(input)
}
pub fn block_expr(input: TokenSpan) -> IResult<TokenSpan, BlockExpr> {
alt((
map(match_block, BlockExpr::Match),
map(
delimited(token(tk::LBrace), expression_block, token(tk::RBrace)),
BlockExpr::Block,
),
))(input)
} }

View File

@ -86,6 +86,7 @@ pub enum TokenKind {
State, State,
Proc, Proc,
Comb, Comb,
Let,
// whitespace // whitespace
Comment, Comment,
// Error // Error
@ -232,6 +233,7 @@ fn lex_keywords(input: Span) -> IResult<Span, Token> {
map(tag("proc"), |_| TokenKind::Proc), map(tag("proc"), |_| TokenKind::Proc),
map(tag("comb"), |_| TokenKind::Comb), map(tag("comb"), |_| TokenKind::Comb),
map(tag("state"), |_| TokenKind::State), map(tag("state"), |_| TokenKind::State),
map(tag("let"), |_| TokenKind::Let),
))), ))),
|(span, kind)| Token::new(span, kind), |(span, kind)| Token::new(span, kind),
)(input) )(input)