Skip to content

Commit

Permalink
Add function declaration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mifka01 committed Nov 15, 2023
1 parent ae9235d commit 2ff690f
Showing 1 changed file with 303 additions and 0 deletions.
303 changes: 303 additions & 0 deletions test/compiler/parser/Parser.test.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,307 @@ DESCRIBE(variable_declaration, "Variable declaration parsing") {
} TEST_END();

}

DESCRIBE(function_declaration, "Function declaration parsing") {
Lexer lexer;
Lexer_constructor(&lexer);

Parser parser;
Parser_constructor(&parser, &lexer);

ParserResult result;

TEST_BEGIN("No parameters empty body") {
Lexer_setSource(&lexer, "func empty_function(){}");
result = Parser_parse(&parser);

EXPECT_TRUE(result.success);
EXPECT_STATEMENT(result.node, NODE_FUNCTION_DECLARATION);

FunctionDeclarationASTNode *declaration = (FunctionDeclarationASTNode*)statement;

IdentifierASTNode *id = declaration->id;
EXPECT_NOT_NULL(id);
EXPECT_TRUE(String_equals(id->name, "empty_function"));

// return type
EXPECT_NULL(declaration->returnType);

// parameters
ParameterListASTNode *list = declaration->parameterList;
EXPECT_NOT_NULL(list->parameters);

Array *arr = list->parameters;
EXPECT_NULL(arr->data);
EXPECT_EQUAL_INT(arr->size, 0);

// body
BlockASTNode *body = declaration->body;
EXPECT_NOT_NULL(body->statements);
arr = body->statements;
EXPECT_NULL(arr->data);
EXPECT_EQUAL_INT(arr->size, 0);

} TEST_END();


TEST_BEGIN("With simple parameters empty body") {
Lexer_setSource(&lexer, "func parameters_function(a: Int, b: Int = 10, c: String = \"hello\"){}");
result = Parser_parse(&parser);

EXPECT_TRUE(result.success);
EXPECT_STATEMENT(result.node, NODE_FUNCTION_DECLARATION);

FunctionDeclarationASTNode *declaration = (FunctionDeclarationASTNode*)statement;

IdentifierASTNode *id = declaration->id;
EXPECT_NOT_NULL(id);
EXPECT_TRUE(String_equals(id->name, "parameters_function"));

// return type
EXPECT_NULL(declaration->returnType);

// parameters
ParameterListASTNode *list = declaration->parameterList;
EXPECT_NOT_NULL(list->parameters);

Array *arr = list->parameters;
EXPECT_NOT_NULL(arr->data);
EXPECT_EQUAL_INT(arr->size, 3);

// first parameter a: Int
ParameterASTNode *parameter = Array_get(arr, 0);
EXPECT_NOT_NULL(parameter);
EXPECT_FALSE(parameter->isLabeless);

EXPECT_NULL(parameter->externalId);
EXPECT_TRUE(String_equals(parameter->internalId->name, "a"));

EXPECT_NOT_NULL(parameter->type);
EXPECT_TRUE(parameter->type->_type == NODE_TYPE_REFERENCE);
EXPECT_TRUE(String_equals(parameter->type->id->name, "Int"));

EXPECT_NULL(parameter->initializer);

// second parameter b: Int = 10
parameter = Array_get(arr, 1);
EXPECT_NOT_NULL(parameter);
EXPECT_FALSE(parameter->isLabeless);

EXPECT_NULL(parameter->externalId);
EXPECT_TRUE(String_equals(parameter->internalId->name, "b"));

EXPECT_NOT_NULL(parameter->type);
EXPECT_TRUE(parameter->type->_type == NODE_TYPE_REFERENCE);
EXPECT_TRUE(String_equals(parameter->type->id->name, "Int"));

EXPECT_NOT_NULL(parameter->initializer);

LiteralExpressionASTNode *initializer = (LiteralExpressionASTNode*)parameter->initializer;
EXPECT_NOT_NULL(initializer);
EXPECT_TRUE(initializer->_type == NODE_LITERAL_EXPRESSION);
EXPECT_TRUE(initializer->type == LITERAL_INTEGER);
EXPECT_EQUAL_INT(initializer->value.integer, 10);

// third parameter c = "hello"
parameter = Array_get(arr, 2);
EXPECT_NOT_NULL(parameter);
EXPECT_FALSE(parameter->isLabeless);

EXPECT_NULL(parameter->externalId);
EXPECT_TRUE(String_equals(parameter->internalId->name, "c"));

EXPECT_NOT_NULL(parameter->type);
EXPECT_TRUE(parameter->type->_type == NODE_TYPE_REFERENCE);
EXPECT_TRUE(String_equals(parameter->type->id->name, "String"));

EXPECT_NOT_NULL(parameter->initializer);

initializer = (LiteralExpressionASTNode*)parameter->initializer;
EXPECT_NOT_NULL(initializer);
EXPECT_TRUE(initializer->_type == NODE_LITERAL_EXPRESSION);
EXPECT_TRUE(initializer->type == LITERAL_STRING);
EXPECT_TRUE(String_equals(initializer->value.string, "hello"));

// body
BlockASTNode *body = declaration->body;
EXPECT_NOT_NULL(body->statements);
arr = body->statements;
EXPECT_NULL(arr->data);
EXPECT_EQUAL_INT(arr->size, 0);

} TEST_END();

TEST_BEGIN("With advanced parameters empty body") {
Lexer_setSource(&lexer, "func parameters_function(a_external a_internal: Int, _ b_internal: Int = 100, _ _: Double = 12.3){}");
result = Parser_parse(&parser);

EXPECT_TRUE(result.success);
EXPECT_STATEMENT(result.node, NODE_FUNCTION_DECLARATION);

FunctionDeclarationASTNode *declaration = (FunctionDeclarationASTNode*)statement;

IdentifierASTNode *id = declaration->id;
EXPECT_NOT_NULL(id);
EXPECT_TRUE(String_equals(id->name, "parameters_function"));

// return type
EXPECT_NULL(declaration->returnType);

// parameters
ParameterListASTNode *list = declaration->parameterList;
EXPECT_NOT_NULL(list->parameters);

Array *arr = list->parameters;
EXPECT_NOT_NULL(arr->data);
EXPECT_EQUAL_INT(arr->size, 3);

// first parameter a_external a_internal: Int
ParameterASTNode *parameter = Array_get(arr, 0);
EXPECT_NOT_NULL(parameter);
EXPECT_FALSE(parameter->isLabeless);

EXPECT_TRUE(String_equals(parameter->externalId->name, "a_external"));
EXPECT_TRUE(String_equals(parameter->internalId->name, "a_internal"));

EXPECT_NOT_NULL(parameter->type);
EXPECT_TRUE(parameter->type->_type == NODE_TYPE_REFERENCE);
EXPECT_TRUE(String_equals(parameter->type->id->name, "Int"));

EXPECT_NULL(parameter->initializer);

// second parameter _ b_internal: Int = 100
parameter = Array_get(arr, 1);
EXPECT_NOT_NULL(parameter);
EXPECT_TRUE(parameter->isLabeless);

EXPECT_TRUE(String_equals(parameter->externalId->name, "_"));
EXPECT_TRUE(String_equals(parameter->internalId->name, "b_internal"));

EXPECT_NOT_NULL(parameter->type);
EXPECT_TRUE(parameter->type->_type == NODE_TYPE_REFERENCE);
EXPECT_TRUE(String_equals(parameter->type->id->name, "Int"));

EXPECT_NOT_NULL(parameter->initializer);

LiteralExpressionASTNode *initializer = (LiteralExpressionASTNode*)parameter->initializer;
EXPECT_NOT_NULL(initializer);
EXPECT_TRUE(initializer->_type == NODE_LITERAL_EXPRESSION);
EXPECT_TRUE(initializer->type == LITERAL_INTEGER);
EXPECT_EQUAL_INT(initializer->value.integer, 100);

// third parameter _ _: Double = 12.3
parameter = Array_get(arr, 2);
EXPECT_NOT_NULL(parameter);
EXPECT_TRUE(parameter->isLabeless);

EXPECT_TRUE(String_equals(parameter->externalId->name, "_"));
EXPECT_TRUE(String_equals(parameter->internalId->name, "_"));

EXPECT_NOT_NULL(parameter->type);
EXPECT_TRUE(parameter->type->_type == NODE_TYPE_REFERENCE);
EXPECT_TRUE(String_equals(parameter->type->id->name, "Double"));

EXPECT_NOT_NULL(parameter->initializer);

initializer = (LiteralExpressionASTNode*)parameter->initializer;
EXPECT_NOT_NULL(initializer);
EXPECT_TRUE(initializer->_type == NODE_LITERAL_EXPRESSION);
EXPECT_TRUE(initializer->type == LITERAL_FLOATING);
EXPECT_EQUAL_INT(initializer->value.floating, 12.3);

// body
BlockASTNode *body = declaration->body;
EXPECT_NOT_NULL(body->statements);
arr = body->statements;
EXPECT_NULL(arr->data);
EXPECT_EQUAL_INT(arr->size, 0);

} TEST_END();

TEST_BEGIN("With parameters and simple block") {
Lexer_setSource(&lexer, "func isGreater(_ a:Int, _ b:Int) -> Bool { return a > b}");
result = Parser_parse(&parser);

EXPECT_TRUE(result.success);
EXPECT_STATEMENT(result.node, NODE_FUNCTION_DECLARATION);

FunctionDeclarationASTNode *declaration = (FunctionDeclarationASTNode*)statement;

IdentifierASTNode *id = declaration->id;
EXPECT_NOT_NULL(id);
EXPECT_TRUE(String_equals(id->name, "isGreater"));

// return type
EXPECT_NOT_NULL(declaration->returnType);
EXPECT_TRUE(declaration->returnType->_type == NODE_TYPE_REFERENCE);
EXPECT_TRUE(String_equals(declaration->returnType->id->name, "Bool"));

// parameters
ParameterListASTNode *list = declaration->parameterList;
EXPECT_NOT_NULL(list->parameters);

Array *arr = list->parameters;
EXPECT_NOT_NULL(arr->data);
EXPECT_EQUAL_INT(arr->size, 2);

// first parameter a: Int
ParameterASTNode *parameter = Array_get(arr, 0);
EXPECT_NOT_NULL(parameter);
EXPECT_TRUE(parameter->isLabeless);

EXPECT_TRUE(String_equals(parameter->externalId->name, "_"));
EXPECT_TRUE(String_equals(parameter->internalId->name, "a"));

EXPECT_NOT_NULL(parameter->type);
EXPECT_TRUE(parameter->type->_type == NODE_TYPE_REFERENCE);
EXPECT_TRUE(String_equals(parameter->type->id->name, "Int"));

EXPECT_NULL(parameter->initializer);

// second parameter a: Int
parameter = Array_get(arr, 1);
EXPECT_NOT_NULL(parameter);
EXPECT_TRUE(parameter->isLabeless);

EXPECT_TRUE(String_equals(parameter->externalId->name, "_"));
EXPECT_TRUE(String_equals(parameter->internalId->name, "b"));

EXPECT_NOT_NULL(parameter->type);
EXPECT_TRUE(parameter->type->_type == NODE_TYPE_REFERENCE);
EXPECT_TRUE(String_equals(parameter->type->id->name, "Int"));

EXPECT_NULL(parameter->initializer);

// body
BlockASTNode *body = declaration->body;
EXPECT_NOT_NULL(body->statements);

arr = body->statements;
EXPECT_NOT_NULL(arr->data);
EXPECT_EQUAL_INT(arr->size, 1);

StatementASTNode *body_statement = Array_get(arr, 0);
EXPECT_TRUE(body_statement->_type == NODE_RETURN_STATEMENT);
ReturnStatementASTNode *return_statement = (ReturnStatementASTNode*)body_statement;

BinaryExpressionASTNode *function_return = (BinaryExpressionASTNode*)return_statement->expression;
EXPECT_NOT_NULL(function_return);
EXPECT_TRUE(function_return->_type == NODE_BINARY_EXPRESSION);

EXPECT_TRUE(function_return->left);

IdentifierASTNode *left = (IdentifierASTNode*)function_return->left;
EXPECT_NOT_NULL(left);
EXPECT_TRUE(left->_type == NODE_IDENTIFIER);
EXPECT_TRUE(String_equals(left->name, "a"));

IdentifierASTNode *right = (IdentifierASTNode*)function_return->right;
EXPECT_NOT_NULL(right);
EXPECT_TRUE(right->_type == NODE_IDENTIFIER);
EXPECT_TRUE(String_equals(right->name, "b"));

EXPECT_TRUE(function_return->operator == OPERATOR_GREATER);

} TEST_END();
}

0 comments on commit 2ff690f

Please sign in to comment.