1
0
Fork 0

Added more tests for call expression parser

This commit is contained in:
Ishan Jain 2020-01-20 16:57:19 +05:30
parent 8ec7ec1ba1
commit a1c316a43e
2 changed files with 154 additions and 4 deletions

View File

@ -645,16 +645,22 @@ impl CallExpression {
None => return Some(expressions),
};
Expression::parse(parser, ntoken, ExpressionPriority::Lowest).map(|e| expressions.push(e));
if let Some(expr) = Expression::parse(parser, ntoken, ExpressionPriority::Lowest) {
expressions.push(expr);
} else {
return Some(expressions);
}
while parser.peek_token_is(TokenType::Comma) {
parser.lexer.next();
let token = match parser.lexer.next() {
Some(v) => v,
None => return Some(expressions),
};
Expression::parse(parser, token, ExpressionPriority::Lowest)
.map(|e| expressions.push(e));
if let Some(expr) = Expression::parse(parser, token, ExpressionPriority::Lowest) {
expressions.push(expr);
} else {
return Some(expressions);
}
}
if parser.expect_peek(TokenType::RParen).is_none() {

View File

@ -793,6 +793,119 @@ mod tests {
)),
))],
),
(
"a + add(1, 2 * 3, 4 + 5) + d;",
vec![Statement::ExpressionStatement(ExpressionStatement::new(
Token::with_value(TokenType::Ident, "a"),
Expression::InfixExpression(InfixExpression::new(
TokenType::Plus,
Expression::InfixExpression(InfixExpression::new(
TokenType::Plus,
Expression::Identifier(Identifier::new(TokenType::Ident, "a")),
"+",
Expression::CallExpression(CallExpression::new(
Expression::Identifier(Identifier::new(TokenType::Ident, "add")),
vec![
Expression::IntegerLiteral(IntegerLiteral::new(1)),
Expression::InfixExpression(InfixExpression::new(
TokenType::Asterisk,
Expression::IntegerLiteral(IntegerLiteral::new(2)),
"*",
Expression::IntegerLiteral(IntegerLiteral::new(3)),
)),
Expression::InfixExpression(InfixExpression::new(
TokenType::Plus,
Expression::IntegerLiteral(IntegerLiteral::new(4)),
"+",
Expression::IntegerLiteral(IntegerLiteral::new(5)),
)),
],
)),
)),
"+",
Expression::Identifier(Identifier::new(TokenType::Ident, "d")),
)),
))],
),
(
"add(a,b,1, 2 * 3, 4 + 5, add(6,7 *8));",
vec![Statement::ExpressionStatement(ExpressionStatement::new(
Token::with_value(TokenType::Ident, "add"),
Expression::CallExpression(CallExpression::new(
Expression::Identifier(Identifier::new(TokenType::Ident, "add")),
vec![
Expression::Identifier(Identifier::new(TokenType::Ident, "a")),
Expression::Identifier(Identifier::new(TokenType::Ident, "b")),
Expression::IntegerLiteral(IntegerLiteral::new(1)),
Expression::InfixExpression(InfixExpression::new(
TokenType::Asterisk,
Expression::IntegerLiteral(IntegerLiteral::new(2)),
"*",
Expression::IntegerLiteral(IntegerLiteral::new(3)),
)),
Expression::InfixExpression(InfixExpression::new(
TokenType::Plus,
Expression::IntegerLiteral(IntegerLiteral::new(4)),
"+",
Expression::IntegerLiteral(IntegerLiteral::new(5)),
)),
Expression::CallExpression(CallExpression::new(
Expression::Identifier(Identifier::new(TokenType::Ident, "add")),
vec![
Expression::IntegerLiteral(IntegerLiteral::new(6)),
Expression::InfixExpression(InfixExpression::new(
TokenType::Asterisk,
Expression::IntegerLiteral(IntegerLiteral::new(7)),
"*",
Expression::IntegerLiteral(IntegerLiteral::new(8)),
)),
],
)),
],
)),
))],
),
(
"add(a + b + c * d / f + g);",
vec![Statement::ExpressionStatement(ExpressionStatement::new(
Token::with_value(TokenType::Ident, "add"),
Expression::CallExpression(CallExpression::new(
Expression::Identifier(Identifier::new(TokenType::Ident, "add")),
vec![Expression::InfixExpression(InfixExpression::new(
TokenType::Plus,
Expression::InfixExpression(InfixExpression::new(
TokenType::Plus,
Expression::InfixExpression(InfixExpression::new(
TokenType::Plus,
Expression::Identifier(Identifier::new(TokenType::Ident, "a")),
"+",
Expression::Identifier(Identifier::new(TokenType::Ident, "b")),
)),
"+",
Expression::InfixExpression(InfixExpression::new(
TokenType::Slash,
Expression::InfixExpression(InfixExpression::new(
TokenType::Asterisk,
Expression::Identifier(Identifier::new(
TokenType::Ident,
"c",
)),
"*",
Expression::Identifier(Identifier::new(
TokenType::Ident,
"d",
)),
)),
"/",
Expression::Identifier(Identifier::new(TokenType::Ident, "f")),
)),
)),
"+",
Expression::Identifier(Identifier::new(TokenType::Ident, "g")),
))],
)),
))],
),
(
"add();",
vec![Statement::ExpressionStatement(ExpressionStatement::new(
@ -815,4 +928,35 @@ mod tests {
assert_eq!(program.unwrap().statements, test.1);
}
}
#[test]
fn call_expression_parsing_string() {
// TODO: Figure out why are there inconsistencies in BlockStatements Token
let test_cases = [
("add(1, 2 * 3, 4 + 5);", "add(1, (2 * 3), (4 + 5))"),
(
"a + add(1, 2 * 3, 4 + 5) + d;",
"((a + add(1, (2 * 3), (4 + 5))) + d)",
),
(
"add(a,b,1, 2 * 3, 4 + 5, add(6,7 *8));",
"add(a, b, 1, (2 * 3), (4 + 5), add(6, (7 * 8)))",
),
(
"add(a + b + c * d / f + g);",
"add((((a + b) + ((c * d) / f)) + g))",
),
("add();", "add()"),
("a + add(b * c) + d", "((a + add((b * c))) + d)"),
];
for test in test_cases.iter() {
let lexer = Lexer::new(test.0);
let mut parser = Parser::new(lexer);
let program = parser.parse_program();
check_parser_errors(&parser);
assert_eq!(parser.errors.len(), 0);
assert!(program.is_some());
assert_eq!(program.unwrap().to_string(), test.1);
}
}
}