diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ab8afdc..b5c1111 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -7,4 +7,5 @@ set(CTEST_BINARY_DIRECTORY ${PROJECT_BINARY_DIR}/tests) # Provide test to run here or include another CMakeLists.txt add_subdirectory(logging) -add_subdirectory(input_file) \ No newline at end of file +add_subdirectory(input_file) +add_subdirectory(ast) \ No newline at end of file diff --git a/tests/ast/CMakeLists.txt b/tests/ast/CMakeLists.txt new file mode 100644 index 0000000..81e7b96 --- /dev/null +++ b/tests/ast/CMakeLists.txt @@ -0,0 +1,35 @@ +include(CTest) + +include_directories(${PROJECT_SOURCE_DIR}/src) + +# ------------------------------------------------------- # +# CTEST 1 +# test building the syntax tree + +add_executable(ast_build_tree + ${PROJECT_SOURCE_DIR}/src/ast/ast.c + ${PROJECT_SOURCE_DIR}/src/sys/log.c + build_tree.c) +set_target_properties(ast_build_tree + PROPERTIES + OUTPUT_NAME "build_tree" + RUNTIME_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/tests/ast) +add_test(NAME ast_build_tree + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + COMMAND python ${GEMSTONE_TEST_DIR}/ast/test_ast.py check_build_tree) + +# ------------------------------------------------------- # +# CTEST 2 +# test node to string output + +add_executable(ast_print_node + ${PROJECT_SOURCE_DIR}/src/ast/ast.c + print_node.c) +set_target_properties(ast_build_tree + PROPERTIES + OUTPUT_NAME "build_tree" + RUNTIME_OUTPUT_DIRECTORY ${GEMSTONE_BINARY_DIR}/tests/ast) +add_test(NAME ast_print_node + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + COMMAND python ${GEMSTONE_TEST_DIR}/ast/test_ast.py check_print_node) + diff --git a/tests/ast/build_tree.c b/tests/ast/build_tree.c new file mode 100644 index 0000000..dec7b85 --- /dev/null +++ b/tests/ast/build_tree.c @@ -0,0 +1,40 @@ +// +// Created by servostar on 5/7/24. +// + +#include +#include + +void generate_statement(const AST_NODE_PTR stmt) { + const AST_NODE_PTR add = AST_new_node(AST_Add, NULL); + + AST_push_node(add, AST_new_node(AST_Int, "3")); + AST_push_node(add, AST_new_node(AST_Int, "6")); + + AST_push_node(stmt, add); +} + +void generate_branch(const AST_NODE_PTR stmt) { + const AST_NODE_PTR branch = AST_new_node(AST_If, NULL); + const AST_NODE_PTR gt = AST_new_node(AST_Greater, NULL); + + AST_push_node(branch, gt); + + AST_push_node(gt, AST_new_node(AST_Float, "2.3")); + AST_push_node(gt, AST_new_node(AST_Float, "0.79")); + + AST_push_node(stmt, branch); + + generate_statement(branch); +} + +int main(void) { + + const AST_NODE_PTR root = AST_new_node(AST_Stmt, NULL); + + generate_branch(root); + + AST_delete_node(root); + + return 0; +} diff --git a/tests/ast/gen_graph.c b/tests/ast/gen_graph.c new file mode 100644 index 0000000..186d571 --- /dev/null +++ b/tests/ast/gen_graph.c @@ -0,0 +1,32 @@ +// +// Created by servostar on 5/7/24. +// + +#include +#include + +int main(void) { + + struct AST_Node_t* node = AST_new_node(AST_If, NULL); + + struct AST_Node_t* child = AST_new_node(AST_Add, NULL); + AST_push_node(child, AST_new_node(AST_Int, "43")); + AST_push_node(child, AST_new_node(AST_Int, "9")); + + AST_push_node(node, child); + AST_push_node(node, AST_new_node(AST_Expr, NULL)); + AST_push_node(node, AST_new_node(AST_Expr, NULL)); + + FILE* out = fopen("ast.gv", "w+"); + // convert this file ^^^^^^ + // to an svg with: `dot -Tsvg ast.gv > graph.svg` + + AST_fprint_graphviz(out, node); + + AST_delete_node(node); + + fflush(out); + fclose(out); + + return 0; +} diff --git a/tests/ast/print_node.c b/tests/ast/print_node.c new file mode 100644 index 0000000..83d3d43 --- /dev/null +++ b/tests/ast/print_node.c @@ -0,0 +1,19 @@ +// +// Created by servostar on 5/7/24. +// + +#include + +int main(void) { + + const AST_NODE_PTR node = AST_new_node(0, "value"); + + for (size_t i = 0; i < AST_ELEMENT_COUNT; i++) { + // set kind + node->kind = i; + // print symbol + printf("%ld %s\n", i, AST_node_to_string(node)); + } + + AST_delete_node(node); +} diff --git a/tests/ast/test_ast.py b/tests/ast/test_ast.py new file mode 100644 index 0000000..111e9c3 --- /dev/null +++ b/tests/ast/test_ast.py @@ -0,0 +1,46 @@ +import subprocess +import sys +import logging +from logging import info, error +import os + +BIN_DIR = "bin/tests/ast/" + + +def run_check_build_tree(): + info("started check tree build...") + + p = subprocess.run(BIN_DIR + "build_tree", capture_output=True, text=True) + + info("checking exit code...") + + # check exit code + assert p.returncode == 0 + + +def run_check_print_node(): + info("started check node print...") + + p = subprocess.run(BIN_DIR + "print_node", capture_output=True, text=True) + + info("checking exit code...") + + # check exit code + assert p.returncode == 0 + + +if __name__ == "__main__": + logging.basicConfig(level=logging.INFO) + + target = sys.argv[1] + + info(f"starting ast test suite with target: {target}") + + match target: + case "check_build_tree": + run_check_build_tree() + case "check_print_node": + run_check_print_node() + case _: + error(f"unknown target: {target}") + exit(1)