From e39267c83a8af189a624891813ebd6014543b01a Mon Sep 17 00:00:00 2001 From: c Date: Sun, 24 Dec 2023 10:28:00 -0500 Subject: Proper tests. --- src/include/main.h | 14 ++++++++++++++ src/include/stack.h | 23 +++++++++++++++++++++++ src/include/test.h | 27 --------------------------- src/include/tree.h | 24 +++++++++++++++--------- src/lexer.c | 4 ---- src/main.c | 24 +++++++++--------------- src/parser.c | 2 -- src/stack.c | 38 ++++++++++++++++++++++++++++++++++++++ src/tree.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 142 insertions(+), 57 deletions(-) create mode 100644 src/include/main.h create mode 100644 src/include/stack.h delete mode 100644 src/include/test.h create mode 100644 src/stack.c (limited to 'src') diff --git a/src/include/main.h b/src/include/main.h new file mode 100644 index 0000000..63dd15c --- /dev/null +++ b/src/include/main.h @@ -0,0 +1,14 @@ +#ifndef MAIN_H +#define MAIN_H + +#include +#include + +#include "util.h" +#include "source.h" +#include "token.h" +#include "pp.h" +#include "lexer.h" +#include "parser.h" + +#endif diff --git a/src/include/stack.h b/src/include/stack.h new file mode 100644 index 0000000..7a16366 --- /dev/null +++ b/src/include/stack.h @@ -0,0 +1,23 @@ +#ifndef STACK_H +#define STACK_H + +#include +#include "util.h" + +#define STACK_MAXLEN 256 + +typedef struct STACK { + int sp; /* Index of first unused element of val. */ + void* val[STACK_MAXLEN]; +} stack_t; + +stack_t* stack_init(); +void stack_destroy(stack_t*); + +void stack_push(stack_t* stack, void* val); +void* stack_pop(stack_t* stack); +size_t stack_len(stack_t* stack); + +void stack_print(stack_t* stack); + +#endif diff --git a/src/include/test.h b/src/include/test.h deleted file mode 100644 index e862467..0000000 --- a/src/include/test.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef TEST_H -#define TEST_H - -#include "util.h" - -#ifdef TEST - -unsigned int TESTS_RUN = 0; -unsigned int TESTS_PASSED = 0; - -#define ASSERT(EXPR) \ - TESTS_RUN++; \ - (EXPR && ++TESTS_PASSED) ? \ - log_yay("Assertion passed!") : \ - log_err("%s:%d: Assertion failed:\n\t%s", __FILE__, __LINE__, #EXPR); - -#define TEST_REPORT \ - (TESTS_RUN == TESTS_PASSED) ? \ - log_yay("All %d tests passed!", TESTS_RUN) : \ - log_err("%d/%d tests failed.", TESTS_RUN - TESTS_PASSED, TESTS_RUN); - -#else -#define ASSERT(EXPR) NULL; -#define TEST_REPORT NULL; -#endif - -#endif diff --git a/src/include/tree.h b/src/include/tree.h index 20d97be..8b8e14a 100644 --- a/src/include/tree.h +++ b/src/include/tree.h @@ -4,15 +4,15 @@ #include "util.h" typedef enum TREE_TYPE { - TREE_TYPE_BLOCK, - TREE_TYPE_EXPR, - TREE_TYPE_LINT, - TREE_TYPE_LSTR, - TREE_TYPE_TAG, - TREE_TYPE_DARG, - TREE_TYPE_CARG, - TREE_TYPE_DEF, - TREE_TYPE_CALL, + TREE_TYPE_BLOCK, + TREE_TYPE_EXPR, + TREE_TYPE_LINT, + TREE_TYPE_LSTR, + TREE_TYPE_TAG, + TREE_TYPE_DARG, + TREE_TYPE_CARG, + TREE_TYPE_DEF, + TREE_TYPE_CALL, } tree_type_t; /* The Abstract Syntax Tree (AST) structure. */ @@ -86,6 +86,12 @@ tree_t* tree_init(int type); /* Destroy the AST. */ void tree_destroy(tree_t* tree); +/* + Compare two trees. For testing. + Returns 1 if the same, otherwise 0. +*/ +int tree_cmp(tree_t* tree_0, tree_t* tree_1); + /* Print a tree. */ void tree_print(tree_t* tree, int nest); diff --git a/src/lexer.c b/src/lexer.c index 13892a5..74bea85 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -36,7 +36,6 @@ void lexer_add_token(lexer_t* lexer, token_t* token) { lexer->tokenl_last = token; } - lexer->tokenc ++; } @@ -171,7 +170,4 @@ void lexer_run(lexer_t* lexer) { else if (lexer->state == LEXER_STATE_KWD) { lexer_do_kwd(lexer); } lexer->src ++; } - - /* print tokens *AFTER* they've been discovered */ - token_print(lexer->tokenl); } diff --git a/src/main.c b/src/main.c index d40da66..d8905b5 100644 --- a/src/main.c +++ b/src/main.c @@ -1,17 +1,12 @@ -#include -#include +#include "include/main.h" -#include "include/test.h" - -#include "include/util.h" -#include "include/source.h" -#include "include/token.h" -#include "include/pp.h" -#include "include/lexer.h" -#include "include/parser.h" +#ifdef TEST +unsigned int TESTS_RUN; +unsigned int TESTS_PASSED; +#endif int main(int argc, char* argv[]) { - char* src; /* the source "code" */ + char* src; pp_t* pp; lexer_t* lexer; parser_t* parser; @@ -21,8 +16,6 @@ int main(int argc, char* argv[]) { log_dbg("source gotten"); log_inf("source: %s", src); - ASSERT(src); - /* create pre-processor */ pp = pp_init(src); log_dbg("preprocessor created"); @@ -44,6 +37,9 @@ int main(int argc, char* argv[]) { lexer_run(lexer); log_dbg("lexer ran"); + /* Print the lexer's tokens. */ + token_print(lexer->tokenl); + /* Create the parser from the lexer's tokens. */ parser = parser_init(lexer->tokenl); parser_run(parser); @@ -56,7 +52,5 @@ int main(int argc, char* argv[]) { parser_destroy(parser); free(src); - TEST_REPORT; - return 0; } diff --git a/src/parser.c b/src/parser.c index 09ce7bc..0359c80 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,6 +1,4 @@ #include "include/parser.h" -#include "include/token.h" -#include "include/tree.h" parser_t* parser_init(token_t* token) { parser_t* parser; diff --git a/src/stack.c b/src/stack.c new file mode 100644 index 0000000..5c4d0ca --- /dev/null +++ b/src/stack.c @@ -0,0 +1,38 @@ +#include "include/stack.h" + +stack_t* stack_init() { + stack_t* stack = emalloc(sizeof(stack_t)); + + stack->sp = 0; + for (int i = 0; i < STACK_MAXLEN; stack->val[i++] = 0); + + return stack; +} + +void stack_destroy(stack_t* stack) { + free(stack); +} + +void stack_push(stack_t* stack, void* val) { + stack->val[stack->sp++] = val; +} + +void* stack_pop(stack_t* stack) { + void* tmpval; + + tmpval = stack->val[--stack->sp]; + stack->val[stack->sp] = NULL; + + return tmpval; +} + +size_t stack_len(stack_t* stack) { + return stack->sp - 1; +} + +void stack_print(stack_t* stack) { + log_inf("stack_print(): %p", stack); + for (int i = stack_len(stack) - 1; i >= 0; --i) { + log_inf("%d: %p", i, stack[i]); + } +} diff --git a/src/tree.c b/src/tree.c index 8876e47..4729200 100644 --- a/src/tree.c +++ b/src/tree.c @@ -90,6 +90,49 @@ void tree_destroy(tree_t* tree) { free(tree); } +int tree_cmp(tree_t* tree_0, tree_t* tree_1) { + if ((tree_0 && !tree_1) || (!tree_0 && tree_1)) { return 0; } /* Only 1 is defined (failure). */ + if (!tree_0 && !tree_1) { return 1; } /* Both are undefined (success). */ + if (tree_0->type != tree_1->type) { return 0; } /* Types do not match (failure). */ + + switch (tree_0->type) { + case TREE_TYPE_BLOCK: + return tree_cmp(tree_0->data.block.val, tree_1->data.block.val) && + tree_cmp(tree_0->data.block.val, tree_1->data.block.val); + break; + case TREE_TYPE_EXPR: + return tree_cmp(tree_0->data.expr.val, tree_1->data.expr.val); + break; + case TREE_TYPE_LINT: + return tree_0->data.lint.val == tree_1->data.lint.val; + break; + case TREE_TYPE_LSTR: + return strcmp(tree_0->data.lstr.val, tree_1->data.lstr.val) == 0; + break; + case TREE_TYPE_TAG: + return (strcmp(tree_0->data.tag.val, tree_1->data.tag.val) == 0) && + tree_cmp(tree_0->data.tag.nxt, tree_1->data.tag.nxt); + break; + case TREE_TYPE_DARG: + return tree_cmp(tree_0->data.darg.tag, tree_1->data.darg.tag) && + tree_cmp(tree_0->data.darg.nxt, tree_1->data.darg.nxt); + break; + case TREE_TYPE_CARG: + return tree_cmp(tree_0->data.carg.val, tree_1->data.carg.val) && + tree_cmp(tree_0->data.carg.nxt, tree_1->data.carg.nxt); + break; + case TREE_TYPE_DEF: + return tree_cmp(tree_0->data.def.tag, tree_1->data.def.tag) && + tree_cmp(tree_0->data.def.arg, tree_1->data.def.arg) && + tree_cmp(tree_0->data.def.val, tree_1->data.def.val); + break; + case TREE_TYPE_CALL: + return (strcmp(tree_0->data.call.target, tree_1->data.call.target) == 0) && + tree_cmp(tree_0->data.call.arg, tree_1->data.call.arg); + break; + } +} + /* Every time I think there's a problem with the parser, it turns out it's just this stupid tree print function. -- cgit v1.2.3