Add function call expressions

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2020-05-06 17:39:31 -04:00
parent bd87e9dd30
commit 5c505e5ae5
2 changed files with 105 additions and 2 deletions

View File

@@ -276,7 +276,32 @@ impl<'t> Parser<'t> {
_ => unreachable!(),
};
Ok(expr)
self.next_suffix_expr(expr)
}
/// Takes an expression and attempts to match a suffix for it - either a function call or
/// index access.
fn next_suffix_expr(&mut self, expr: Expr) -> Result<Expr> {
if self.match_token_kind(TokenKind::LParen)?.is_some() {
let prev_skip = self.set_skip_newlines(true)?;
let args = self.next_expr_list(TokenKind::RParen)?;
self.set_skip_newlines(prev_skip)?;
let end_token =
self.expect_token_kind(TokenKind::RParen, "end of function call (left paren)")?;
let span = expr.span().union(end_token.span());
let fun_call = Expr::FunCall(
FunCallExpr {
expr,
args,
span,
}.into()
);
self.next_suffix_expr(fun_call)
} else if self.match_token_kind(TokenKind::LBracket)?.is_some() {
todo!()
} else {
Ok(expr)
}
}
/// Gets a list of expressions separated by commas, stopping when EOF or specified end token is
@@ -570,6 +595,14 @@ mod test {
})
}
fn fun_call_expr(expr: Expr, args: Vec<Expr>) -> Expr {
Expr::FunCall(FunCallExpr {
expr,
args,
span: Default::default(),
}.into())
}
#[test]
fn test_base_expr() {
test_parser!(
@@ -894,6 +927,59 @@ mod test {
);
}
#[test]
fn test_fun_call_expr() {
test_parser!(
Parser::try_from(r"foo()").unwrap(),
next_expr,
fun_call_expr(
base_expr(BaseExprKind::Ident),
vec![]
)
);
test_parser!(
Parser::try_from(r"foo(bar)").unwrap(),
next_expr,
fun_call_expr(
base_expr(BaseExprKind::Ident),
vec![
base_expr(BaseExprKind::Ident)
]
)
);
test_parser!(
Parser::try_from(r"foo(bar, 1, :sym)").unwrap(),
next_expr,
fun_call_expr(
base_expr(BaseExprKind::Ident),
vec![
base_expr(BaseExprKind::Ident),
base_expr(BaseExprKind::Num),
base_expr(BaseExprKind::Sym)
]
)
);
test_parser!(
Parser::try_from(r"foo(
bar,
1,
:sym
)").unwrap(),
next_expr,
fun_call_expr(
base_expr(BaseExprKind::Ident),
vec![
base_expr(BaseExprKind::Ident),
base_expr(BaseExprKind::Num),
base_expr(BaseExprKind::Sym)
]
)
);
}
////////////////////////////////////////////////////////////////////////////////
// Stmt testing
////////////////////////////////////////////////////////////////////////////////