-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* AST Prototypes * AST create, init and free
- Loading branch information
Showing
3 changed files
with
155 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#include <stdlib.h> | ||
Check notice on line 1 in src/ast.c GitHub Actions / linterRun clang-format on src/ast.c
|
||
|
||
#include "ast.h" | ||
|
||
// Allocate a new AST Node, and initialize it with the given type | ||
ASTNode* ast_node_create(ASTNodeType type) { | ||
ASTNode* node = malloc(sizeof(ASTNode)); | ||
|
||
// Initialize the created node, this implicitly checks for NULL | ||
if (ast_node_init(node, type) != 0) { | ||
free(node); // free of NULL is a no-op | ||
return NULL; | ||
} | ||
|
||
return node; | ||
} | ||
|
||
|
||
// Initialize an AST Node | ||
int ast_node_init(ASTNode* node, ASTNodeType type) { | ||
if (node == NULL) { | ||
return -1; | ||
} | ||
|
||
*node = (ASTNode){ | ||
.type = type, | ||
.child1 = NULL, | ||
.extra = {0}, | ||
}; | ||
|
||
return 0; | ||
} | ||
|
||
|
||
// Release memory allocated for the given AST Node | ||
void ast_node_free(ASTNode* node) { | ||
if (node == NULL) { | ||
return; | ||
} | ||
|
||
if (node->type == CHAR_NODE) { | ||
free(node); | ||
return; | ||
} | ||
|
||
ast_node_free(node->child1); | ||
|
||
if (node->type == OR_NODE || node->type == CONCAT_NODE) { | ||
ast_node_free(node->extra.child2); | ||
} | ||
|
||
free(node); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#include "testlib/asserts.h" | ||
Check notice on line 1 in tests/test_ast.c GitHub Actions / linterRun clang-format on tests/test_ast.c
|
||
#include "testlib/tests.h" | ||
#include "ast.h" | ||
|
||
// Test creating AST dynamically | ||
int test_ast_create() { | ||
TEST_BEGIN; | ||
ASTNodeType types[] = { | ||
CHAR_NODE, STAR_NODE, PLUS_NODE, | ||
OR_NODE, QUESTION_NODE, CONCAT_NODE, | ||
}; | ||
|
||
size_t n_types = sizeof(types) / sizeof(ASTNodeType); | ||
|
||
for (size_t i = 0; i < n_types; i++) { | ||
ASTNode* node = ast_node_create(types[i]); | ||
|
||
assert_is_not_null(node); | ||
assert_equals_int(node->type, types[i]); | ||
ast_node_free(node); | ||
} | ||
TEST_END; | ||
} | ||
|
||
int test_ast_init() { | ||
TEST_BEGIN; | ||
ASTNodeType types[] = { | ||
CHAR_NODE, STAR_NODE, PLUS_NODE, | ||
OR_NODE, QUESTION_NODE, CONCAT_NODE, | ||
}; | ||
|
||
size_t n_types = sizeof(types) / sizeof(ASTNodeType); | ||
|
||
ASTNode node; | ||
for (size_t i = 0; i < n_types; i++) { | ||
int ret = ast_node_init(&node, types[i]); | ||
|
||
assert_equals_int(ret, 0); | ||
assert_equals_int(node.type, types[i]); | ||
} | ||
|
||
int ret = ast_node_init(NULL, *types); | ||
assert_equals_int(ret, -1); | ||
|
||
TEST_END; | ||
} | ||
|
||
|
||
Test tests[] = { | ||
{.name="test_ast_create", .func=test_ast_create}, | ||
{.name="test_ast_init", .func=test_ast_init}, | ||
{.name=NULL}, | ||
}; | ||
|
||
|
||
int main(int argc, char* argv[]) { | ||
TestOpts opts; | ||
int ret = parse_test_opts(&opts, &argv[1], argc - 1); | ||
if (ret != 0) { | ||
printf("%s\n", str_parse_error(ret)); | ||
exit(1); | ||
} | ||
|
||
const TestSuite* suite = create_test_suite(&opts); | ||
|
||
int n_failures = run_test_suite(suite); | ||
|
||
free_opts(&opts); | ||
free_test_suite(suite); | ||
|
||
return n_failures; | ||
} |