Add block expression parsing and test
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -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)
|
||||||
)
|
)
|
||||||
)
|
)))
|
||||||
))
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user