Add block expression parsing and test

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2020-05-06 17:14:55 -04:00
parent 66af3dcc53
commit bd87e9dd30

View File

@@ -20,7 +20,6 @@ lazy_static! {
start.extend(UN_EXPR_START.iter()); start.extend(UN_EXPR_START.iter());
start start
}; };
static ref EOL: Vec<TokenKind> = vec![TokenKind::Eol, TokenKind::Newline]; static ref EOL: Vec<TokenKind> = vec![TokenKind::Eol, TokenKind::Newline];
} }
@@ -90,7 +89,11 @@ impl<'t> Parser<'t> {
let rhs = self.next_expr()?; let rhs = self.next_expr()?;
self.expect_eol_or_eof("end-of-line after assignment")?; self.expect_eol_or_eof("end-of-line after assignment")?;
let span = expr.span().union(rhs.span()); 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 { } else {
// TODO catch EOF // TODO catch EOF
self.expect_eol_or_eof("end-of-line after expression")?; 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. /// Parses a list of statements until it reaches a right curly brace.
pub fn next_block(&mut self) -> Result<Vec<Stmt>> {
todo!()
}
/// Parses a list of statements.
pub fn next_body(&mut self) -> Result<Vec<Stmt>> { pub fn next_body(&mut self) -> Result<Vec<Stmt>> {
let mut body = Vec::new(); let mut body = Vec::new();
@@ -194,8 +192,7 @@ impl<'t> Parser<'t> {
} }
fn next_base_expr(&mut self) -> Result<Expr> { fn next_base_expr(&mut self) -> Result<Expr> {
let token = let token = self.expect_any_token_kind(&BASE_EXPR_START, "base expression")?;
self.expect_any_token_kind(&BASE_EXPR_START, "base expression")?;
let expr: Expr = match token.kind() { let expr: Expr = match token.kind() {
TokenKind::Ident => BaseExpr { TokenKind::Ident => BaseExpr {
kind: BaseExprKind::Ident, kind: BaseExprKind::Ident,
@@ -230,7 +227,16 @@ impl<'t> Parser<'t> {
} }
.into() .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 => { TokenKind::ObjBrace => {
let prev_skip = self.set_skip_newlines(true)?; let prev_skip = self.set_skip_newlines(true)?;
let object = self.next_obj_list()?; let object = self.next_obj_list()?;
@@ -404,7 +410,11 @@ impl<'t> Parser<'t> {
self.expect_token_where(|t| t.kind() == kind, expected) self.expect_token_where(|t| t.kind() == kind, expected)
} }
fn expect_any_token_kind(&mut self, kinds: &[TokenKind], expected: impl ToString) -> Result<Token> { fn expect_any_token_kind(
&mut self,
kinds: &[TokenKind],
expected: impl ToString,
) -> Result<Token> {
self.expect_token_where(|t| kinds.contains(&t.kind()), expected) 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] #[test]
fn test_object_expr() { fn test_object_expr() {
test_parser!( test_parser!(
@@ -869,13 +899,11 @@ mod test {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
fn assign_stmt(lhs: Expr, rhs: Expr) -> Stmt { fn assign_stmt(lhs: Expr, rhs: Expr) -> Stmt {
Stmt::Assign( Stmt::Assign(AssignStmt {
AssignStmt {
lhs, lhs,
rhs, rhs,
span: Default::default(), span: Default::default(),
} })
)
} }
#[test] #[test]
@@ -887,7 +915,8 @@ mod test {
b = :sym b = :sym
" "
).unwrap(), )
.unwrap(),
next_stmt, next_stmt,
Some(assign_stmt( Some(assign_stmt(
base_expr(BaseExprKind::Ident), base_expr(BaseExprKind::Ident),
@@ -911,23 +940,16 @@ mod test {
:sym :sym
1 1
" "
).unwrap(), )
.unwrap(),
next_stmt, next_stmt,
Some(Stmt::Expr ( Some(Stmt::Expr(base_expr(BaseExprKind::Ident),)),
base_expr(BaseExprKind::Ident),
)),
next_stmt, next_stmt,
Some(Stmt::Expr ( Some(Stmt::Expr(base_expr(BaseExprKind::Str),)),
base_expr(BaseExprKind::Str),
)),
next_stmt, next_stmt,
Some(Stmt::Expr ( Some(Stmt::Expr(base_expr(BaseExprKind::Sym),)),
base_expr(BaseExprKind::Sym),
)),
next_stmt, next_stmt,
Some(Stmt::Expr ( Some(Stmt::Expr(base_expr(BaseExprKind::Num),))
base_expr(BaseExprKind::Num),
))
); );
test_parser!( test_parser!(
@@ -938,10 +960,10 @@ mod test {
1 1
* *
3)" 3)"
).unwrap(), )
.unwrap(),
next_stmt, next_stmt,
Some(Stmt::Expr( Some(Stmt::Expr(bin_expr(
bin_expr(
base_expr(BaseExprKind::Ident), base_expr(BaseExprKind::Ident),
BinOp::Plus, BinOp::Plus,
bin_expr( bin_expr(
@@ -949,8 +971,7 @@ mod test {
BinOp::Times, BinOp::Times,
base_expr(BaseExprKind::Num) base_expr(BaseExprKind::Num)
) )
) )))
))
); );
} }
} }