From bd87e9dd30fcdd109f4df6abc8364644150808f4 Mon Sep 17 00:00:00 2001 From: Alek Ratzloff Date: Wed, 6 May 2020 17:14:55 -0400 Subject: [PATCH] Add block expression parsing and test Signed-off-by: Alek Ratzloff --- src/syn/parser.rs | 113 +++++++++++++++++++++++++++------------------- 1 file changed, 67 insertions(+), 46 deletions(-) diff --git a/src/syn/parser.rs b/src/syn/parser.rs index 22b2b69..b4c53a8 100644 --- a/src/syn/parser.rs +++ b/src/syn/parser.rs @@ -20,7 +20,6 @@ lazy_static! { start.extend(UN_EXPR_START.iter()); start }; - static ref EOL: Vec = vec![TokenKind::Eol, TokenKind::Newline]; } @@ -90,7 +89,11 @@ impl<'t> Parser<'t> { let rhs = self.next_expr()?; self.expect_eol_or_eof("end-of-line after assignment")?; let span = expr.span().union(rhs.span()); - Ok(Some(Stmt::Assign(AssignStmt { lhs: expr, rhs, span, }))) + Ok(Some(Stmt::Assign(AssignStmt { + lhs: expr, + rhs, + span, + }))) } else { // TODO catch EOF self.expect_eol_or_eof("end-of-line after expression")?; @@ -101,12 +104,7 @@ impl<'t> Parser<'t> { } } - /// Parses a brace-enclosed list of statements. - pub fn next_block(&mut self) -> Result> { - todo!() - } - - /// Parses a list of statements. + /// Parses a list of statements until it reaches a right curly brace. pub fn next_body(&mut self) -> Result> { let mut body = Vec::new(); @@ -194,8 +192,7 @@ impl<'t> Parser<'t> { } fn next_base_expr(&mut self) -> Result { - let token = - self.expect_any_token_kind(&BASE_EXPR_START, "base expression")?; + let token = self.expect_any_token_kind(&BASE_EXPR_START, "base expression")?; let expr: Expr = match token.kind() { TokenKind::Ident => BaseExpr { kind: BaseExprKind::Ident, @@ -230,7 +227,16 @@ impl<'t> Parser<'t> { } .into() } - TokenKind::LBrace => todo!("TODO body expressions"), + TokenKind::LBrace => { + let body = self.next_body()?; + let end_token = + self.expect_token_kind(TokenKind::RBrace, "end of block (right curly brace)")?; + let span = token.span().union(end_token.span()); + Expr::Base(BaseExpr { + kind: BaseExprKind::Block(body), + span, + }) + } TokenKind::ObjBrace => { let prev_skip = self.set_skip_newlines(true)?; let object = self.next_obj_list()?; @@ -404,7 +410,11 @@ impl<'t> Parser<'t> { self.expect_token_where(|t| t.kind() == kind, expected) } - fn expect_any_token_kind(&mut self, kinds: &[TokenKind], expected: impl ToString) -> Result { + fn expect_any_token_kind( + &mut self, + kinds: &[TokenKind], + expected: impl ToString, + ) -> Result { self.expect_token_where(|t| kinds.contains(&t.kind()), expected) } @@ -628,6 +638,26 @@ mod test { ); } + #[test] + fn test_block_expr() { + test_parser!( + Parser::try_from( + r#"{ + value = :sym + key = "value" + :ok + }"# + ) + .unwrap(), + next_expr, + base_expr(BaseExprKind::Block(vec![ + assign_stmt(base_expr(BaseExprKind::Ident), base_expr(BaseExprKind::Sym)), + assign_stmt(base_expr(BaseExprKind::Ident), base_expr(BaseExprKind::Str)), + Stmt::Expr(base_expr(BaseExprKind::Sym)) + ])) + ); + } + #[test] fn test_object_expr() { test_parser!( @@ -863,19 +893,17 @@ mod test { )])) ); } - + //////////////////////////////////////////////////////////////////////////////// // Stmt testing //////////////////////////////////////////////////////////////////////////////// fn assign_stmt(lhs: Expr, rhs: Expr) -> Stmt { - Stmt::Assign( - AssignStmt { - lhs, - rhs, - span: Default::default(), - } - ) + Stmt::Assign(AssignStmt { + lhs, + rhs, + span: Default::default(), + }) } #[test] @@ -887,7 +915,8 @@ mod test { b = :sym " - ).unwrap(), + ) + .unwrap(), next_stmt, Some(assign_stmt( base_expr(BaseExprKind::Ident), @@ -911,23 +940,16 @@ mod test { :sym 1 " - ).unwrap(), + ) + .unwrap(), next_stmt, - Some(Stmt::Expr ( - base_expr(BaseExprKind::Ident), - )), + Some(Stmt::Expr(base_expr(BaseExprKind::Ident),)), next_stmt, - Some(Stmt::Expr ( - base_expr(BaseExprKind::Str), - )), + Some(Stmt::Expr(base_expr(BaseExprKind::Str),)), next_stmt, - Some(Stmt::Expr ( - base_expr(BaseExprKind::Sym), - )), + Some(Stmt::Expr(base_expr(BaseExprKind::Sym),)), next_stmt, - Some(Stmt::Expr ( - base_expr(BaseExprKind::Num), - )) + Some(Stmt::Expr(base_expr(BaseExprKind::Num),)) ); test_parser!( @@ -938,19 +960,18 @@ mod test { 1 * 3)" - ).unwrap(), + ) + .unwrap(), next_stmt, - Some(Stmt::Expr( - bin_expr( - base_expr(BaseExprKind::Ident), - BinOp::Plus, - bin_expr( - base_expr(BaseExprKind::Num), - BinOp::Times, - base_expr(BaseExprKind::Num) - ) - ) - )) + Some(Stmt::Expr(bin_expr( + base_expr(BaseExprKind::Ident), + BinOp::Plus, + bin_expr( + base_expr(BaseExprKind::Num), + BinOp::Times, + base_expr(BaseExprKind::Num) + ) + ))) ); } }