diff --git a/src/frontend.rs b/src/frontend.rs index c8378d8..2b41f02 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -219,7 +219,7 @@ impl Context { typ: self.types.primitives.infer, } } - BlockExpr::Block(_) => todo!(), + BlockExpr::Block(block) => todo!(), }, }; Ok(t_expr) diff --git a/src/parser/block_expression.rs b/src/parser/block_expression.rs index 370f979..47ccfb5 100644 --- a/src/parser/block_expression.rs +++ b/src/parser/block_expression.rs @@ -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>), + Block(ExpressionBlock<'a>), } // TODO: postponed because annoying to implement @@ -51,6 +59,25 @@ fn match_block(input: TokenSpan) -> IResult { )(input) } -pub fn block_expr(input: TokenSpan) -> IResult { - alt((map(match_block, BlockExpr::Match),))(input) +fn expression_block(input: TokenSpan) -> IResult { + 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 { + alt(( + map(match_block, BlockExpr::Match), + map( + delimited(token(tk::LBrace), expression_block, token(tk::RBrace)), + BlockExpr::Block, + ), + ))(input) } diff --git a/src/parser/tokens.rs b/src/parser/tokens.rs index 78c8f9a..a3c23a6 100644 --- a/src/parser/tokens.rs +++ b/src/parser/tokens.rs @@ -86,6 +86,7 @@ pub enum TokenKind { State, Proc, Comb, + Let, // whitespace Comment, // Error @@ -232,6 +233,7 @@ fn lex_keywords(input: Span) -> IResult { 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)