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,
}
}
BlockExpr::Block(_) => todo!(),
BlockExpr::Block(block) => todo!(),
},
};
Ok(t_expr)

View File

@ -2,21 +2,29 @@ use nom::{
branch::alt,
combinator::map,
error::context,
multi::separated_list1,
sequence::{delimited, separated_pair, tuple},
multi::{many0, separated_list1},
sequence::{delimited, separated_pair, terminated, tuple},
};
use crate::parser::{
expression::{expression, Expression},
tokens::{token, TokenKind as tk, TokenSpan},
tokens::{token, Token, TokenKind as tk, TokenSpan},
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)]
pub enum BlockExpr<'a> {
IfElse(IfElseBlock),
Match(MatchBlock<'a>),
Block(Vec<BlockExpr<'a>>),
Block(ExpressionBlock<'a>),
}
// TODO: postponed because annoying to implement
@ -51,6 +59,25 @@ fn match_block(input: TokenSpan) -> IResult<TokenSpan, MatchBlock> {
)(input)
}
pub fn block_expr(input: TokenSpan) -> IResult<TokenSpan, BlockExpr> {
alt((map(match_block, BlockExpr::Match),))(input)
fn expression_block(input: TokenSpan) -> IResult<TokenSpan, ExpressionBlock> {
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,
Proc,
Comb,
Let,
// whitespace
Comment,
// Error
@ -232,6 +233,7 @@ fn lex_keywords(input: Span) -> IResult<Span, Token> {
map(tag("proc"), |_| TokenKind::Proc),
map(tag("comb"), |_| TokenKind::Comb),
map(tag("state"), |_| TokenKind::State),
map(tag("let"), |_| TokenKind::Let),
))),
|(span, kind)| Token::new(span, kind),
)(input)