Skip to content

Commit

Permalink
Ast alloc dealloc (#62)
Browse files Browse the repository at this point in the history
* AST Prototypes

* AST create, init and free
  • Loading branch information
mkpro118 authored Jun 30, 2024
1 parent 3522fff commit 647b309
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 0 deletions.
30 changes: 30 additions & 0 deletions include/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,34 @@ typedef struct ASTNode {
} extra;
} ASTNode;


/**
* Allocate a new AST Node, and initialize it with the given type
*
* @param type The type of the AST Node
*
* @return A pointer to a heap allocated AST Node on success,
* NULL on failure
*/
ASTNode* ast_node_create(ASTNodeType type);


/**
* Initialize an AST Node
*
* @param node A Pointer to the AST Node to initialize
* @param type The type of the AST Node
*
* @return 0 on success, -1 on failure
*/
int ast_node_init(ASTNode* node, ASTNodeType type);


/**
* Release memory allocated for the given AST Node
*
* @param node The AST Node to free
*/
void ast_node_free(ASTNode* node);

#endif // REGEX_AST
53 changes: 53 additions & 0 deletions src/ast.c
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

View workflow job for this annotation

GitHub Actions / linter

Run clang-format on src/ast.c

File src/ast.c does not conform to Custom style guidelines. (lines 6, 7, 9, 10, 11, 12, 13, 16, 20, 21, 22, 23, 25, 26, 27, 28, 29, 32, 36, 37, 38, 39, 41, 42, 43, 44, 46, 48, 49, 50)

#include "ast.h"

Check failure on line 3 in src/ast.c

View workflow job for this annotation

GitHub Actions / linter

src/ast.c:3:10 [clang-diagnostic-error]

'ast.h' file not found

// 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);
}
72 changes: 72 additions & 0 deletions tests/test_ast.c
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

View workflow job for this annotation

GitHub Actions / linter

Run clang-format on tests/test_ast.c

File tests/test_ast.c does not conform to Custom style guidelines. (lines 1, 6, 7, 8, 9, 10, 11, 13, 15, 16, 18, 19, 20, 21, 25, 26, 27, 28, 29, 30, 32, 34, 35, 36, 38, 39, 40, 42, 43, 46, 50, 51, 52, 53, 56, 57, 58, 59, 60, 61, 62, 64, 66, 68, 69)
#include "testlib/tests.h"
#include "ast.h"

Check failure on line 3 in tests/test_ast.c

View workflow job for this annotation

GitHub Actions / linter

tests/test_ast.c:3:10 [clang-diagnostic-error]

'ast.h' file not found

// 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);

Check warning on line 13 in tests/test_ast.c

View workflow job for this annotation

GitHub Actions / linter

tests/test_ast.c:13:12 [cppcoreguidelines-init-variables]

variable 'n_types' is not initialized

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);

Check warning on line 32 in tests/test_ast.c

View workflow job for this annotation

GitHub Actions / linter

tests/test_ast.c:32:12 [cppcoreguidelines-init-variables]

variable 'n_types' is not initialized

ASTNode node;
for (size_t i = 0; i < n_types; i++) {
int ret = ast_node_init(&node, types[i]);

Check warning on line 36 in tests/test_ast.c

View workflow job for this annotation

GitHub Actions / linter

tests/test_ast.c:36:13 [cppcoreguidelines-init-variables]

variable 'ret' is not initialized

assert_equals_int(ret, 0);
assert_equals_int(node.type, types[i]);
}

int ret = ast_node_init(NULL, *types);

Check warning on line 42 in tests/test_ast.c

View workflow job for this annotation

GitHub Actions / linter

tests/test_ast.c:42:9 [cppcoreguidelines-init-variables]

variable 'ret' is not initialized
assert_equals_int(ret, -1);

TEST_END;
}


Test tests[] = {

Check warning on line 49 in tests/test_ast.c

View workflow job for this annotation

GitHub Actions / linter

tests/test_ast.c:49:6 [cppcoreguidelines-avoid-non-const-global-variables]

variable 'tests' is non-const and globally accessible, consider making it const
{.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;
}

0 comments on commit 647b309

Please sign in to comment.