aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/util.h2
-rw-r--r--src/main.c21
-rw-r--r--src/parser.c9
-rw-r--r--test/include/test.h8
-rw-r--r--test/parser.c173
-rw-r--r--test/tree.c16
6 files changed, 199 insertions, 30 deletions
diff --git a/src/include/util.h b/src/include/util.h
index 15f862e..839d3e4 100644
--- a/src/include/util.h
+++ b/src/include/util.h
@@ -8,7 +8,7 @@
/* Log some debug information. */
void log_dbg(const char*, ...);
-/* Log some congratulatory information. */
+/* c: */
void log_yay(const char*, ...);
/* Log some information. */
void log_inf(const char*, ...);
diff --git a/src/main.c b/src/main.c
index d8905b5..55053cd 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,26 +1,21 @@
#include "include/main.h"
-#ifdef TEST
-unsigned int TESTS_RUN;
-unsigned int TESTS_PASSED;
-#endif
-
+/* FIXME: Segfaults ~30% of the time. No idea why. Thx future self <3. */
int main(int argc, char* argv[]) {
- char* src;
- pp_t* pp;
+ char* src;
+ pp_t* pp;
lexer_t* lexer;
parser_t* parser;
- /* get source */
+ /* Get source. */
src = source_get(argv[1]);
- log_dbg("source gotten");
- log_inf("source: %s", src);
+ log_inf("Source: %s", src);
- /* create pre-processor */
+ /* Create pre-processor. */
pp = pp_init(src);
- log_dbg("preprocessor created");
+ log_dbg("Preprocessor created.");
- /* pre-process source */
+ /* Pre-process source. */
pp_run(pp);
free(src);
src = pp->psrc;
diff --git a/src/parser.c b/src/parser.c
index 344ca89..2cf9b2c 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -15,6 +15,7 @@ void parser_destroy(parser_t* parser) {
if (parser) { free(parser); }
}
+/* TODO: What if the program begins with a ";"? */
int parser_nxt_token(parser_t* parser) {
/* Preserve original token list, to be cleaned up by lexer. */
parser->token = parser->token->nxt;
@@ -24,6 +25,7 @@ int parser_nxt_token(parser_t* parser) {
return parser->token ? 1 : 0;
}
+/* I don't know if these need to exist. Guess I'll wait and see… */
int parser_match(parser_t* parser, token_type_t type) {
return parser->token->type == type;
}
@@ -49,9 +51,10 @@ tree_t* parser_parse_lstr(parser_t* parser) {
lstr = tree_init(TREE_TYPE_LSTR);
lstr->data.lstr.len = strlen(parser->token->val);
- /* Swap pointers to allow for future token destruction. */
+ /* Move token value to tree, to allow for future token destruction. */
lstr->data.lstr.val = parser->token->val;
parser->token->val = NULL;
+ parser_nxt_token(parser);
return lstr;
}
@@ -63,8 +66,8 @@ tree_t* parser_parse_expr(parser_t* parser) {
case TOKEN_TYPE_INT:
expr = parser_parse_lint(parser);
break;
- case TOKEN_TYPE_EXPR_END:
- parser_nxt_token(parser);
+ case TOKEN_TYPE_STR:
+ expr = parser_parse_lstr(parser);
break;
default:
log_war("%s: Unknown token type: %d", __func__, parser->token->type);
diff --git a/test/include/test.h b/test/include/test.h
index 02c3d18..3193c52 100644
--- a/test/include/test.h
+++ b/test/include/test.h
@@ -3,6 +3,10 @@
#include "../../src/include/util.h"
+/*
+ This is probably how it's supposed to work. In what other cases would you
+ need `extern`?
+*/
extern unsigned int TESTS_RUN;
extern unsigned int TESTS_PASSED;
@@ -11,8 +15,8 @@ extern unsigned int TESTS_PASSED;
#define ASSERT(EXPR) \
TESTS_RUN++; \
(EXPR && ++TESTS_PASSED) ? \
- log_inf("%s:%s:%d: Assertion passed!", __func__, __FILE__, __LINE__) : \
- log_err("%s:%s:%d: Assertion failed:\n\t%s", __func__, __FILE__, __LINE__, #EXPR);
+ log_inf("%s:%s:%d: Assertion passed!", __FILE__, __func__, __LINE__) : \
+ log_err("%s:%s:%d: Assertion failed:\n\t%s", __FILE__, __func__, __LINE__, #EXPR);
#define TEST_REPORT \
(TESTS_RUN == TESTS_PASSED) ? \
diff --git a/test/parser.c b/test/parser.c
index 2007e93..feb9c70 100644
--- a/test/parser.c
+++ b/test/parser.c
@@ -6,13 +6,17 @@
TEST_INIT
-void test_simple_empty() {
+void empty() {
+ /*
+ Hmm… I feel as though this setup/cleanup process could be wrapped in a
+ macro. Tentative TODO?
+ */
tree_t* tree;
pp_t* pp;
lexer_t* lexer;
parser_t* parser;
- char src[] = " ";
+ char src[] = "";
/*
@@ -32,6 +36,7 @@ void test_simple_empty() {
ASSERT(tree_cmp(parser->tree, tree) == 1);
+ /* Probably not cleaning up fully here. Whatever. */
token_destroy(lexer->tokenl);
lexer_destroy(lexer);
pp_destroy(pp);
@@ -39,7 +44,7 @@ void test_simple_empty() {
parser_destroy(parser);
}
-void test_single_lint() {
+void single_lint() {
tree_t* tree;
pp_t* pp;
lexer_t* lexer;
@@ -82,7 +87,7 @@ void test_single_lint() {
parser_destroy(parser);
}
-void test_double_lint() {
+void double_lint() {
tree_t* tree;
pp_t* pp;
lexer_t* lexer;
@@ -134,10 +139,164 @@ void test_double_lint() {
parser_destroy(parser);
}
+void single_lstr() {
+ tree_t* tree;
+ pp_t* pp;
+ lexer_t* lexer;
+ parser_t* parser;
+
+ char src[] = "\"Hello, World.\"";
+
+ /*
+
+ [block]
+ val:
+ [lstr]
+ val:
+ "Hello, World."
+ len:
+ 13
+ nxt:
+ NULL
+
+ */
+
+ tree = tree_init(TREE_TYPE_BLOCK);
+ tree_t* tree0lstr = tree->data.block.val = tree_init(TREE_TYPE_LSTR);
+ tree0lstr->data.lstr.val = "Hello, World.";
+ tree0lstr->data.lstr.len = 13;
+ tree->data.block.nxt = NULL;
+
+ pp = pp_init(src);
+ pp_run(pp);
+
+ lexer = lexer_init(pp->psrc);
+ lexer_run(lexer);
+
+ parser = parser_init(lexer->tokenl);
+ parser_run(parser);
+
+ ASSERT(tree_cmp(parser->tree, tree) == 1);
+
+ token_destroy(lexer->tokenl);
+ lexer_destroy(lexer);
+ pp_destroy(pp);
+ tree_destroy(parser->tree);
+ parser_destroy(parser);
+}
+
+void double_lstr() {
+ tree_t* tree;
+ pp_t* pp;
+ lexer_t* lexer;
+ parser_t* parser;
+
+ char src[] = "\"foo\";\"bar\"";
+
+ /*
+
+ [block]
+ val:
+ [lstr]
+ val:
+ "foo"
+ len:
+ 3
+ nxt:
+ [block]
+ val:
+ [lstr]
+ val:
+ "bar"
+ len:
+ 3
+ nxt:
+ NULL
+
+ */
+
+ tree = tree_init(TREE_TYPE_BLOCK);
+ tree_t* tree0lstr = tree->data.block.val = tree_init(TREE_TYPE_LSTR);
+ tree0lstr->data.lstr.val = "foo";
+ tree0lstr->data.lstr.len = 3;
+ tree_t* tree0block = tree->data.block.nxt = tree_init(TREE_TYPE_BLOCK);
+ tree_t* tree1lstr = tree0block->data.block.val = tree_init(TREE_TYPE_LSTR);
+ tree1lstr->data.lstr.val = "bar";
+ tree1lstr->data.lstr.len = 3;
+ tree0block->data.block.nxt = NULL;
+
+ pp = pp_init(src);
+ pp_run(pp);
+
+ lexer = lexer_init(pp->psrc);
+ lexer_run(lexer);
+
+ parser = parser_init(lexer->tokenl);
+ parser_run(parser);
+
+ ASSERT(tree_cmp(parser->tree, tree) == 1);
+
+ token_destroy(lexer->tokenl);
+ lexer_destroy(lexer);
+ pp_destroy(pp);
+ tree_destroy(parser->tree);
+ parser_destroy(parser);
+}
+
+void single_block() {
+ tree_t* tree;
+ pp_t* pp;
+ lexer_t* lexer;
+ parser_t* parser;
+
+ char src[] = "{}";
+
+ /*
+
+ [block]
+ val:
+ [block]
+ val:
+ NULL
+ nxt:
+ NULL
+ nxt:
+ NULL
+
+ */
+
+ tree = tree_init(TREE_TYPE_BLOCK);
+ tree_t* tree0block = tree->data.block.val = tree_init(TREE_TYPE_BLOCK);
+ tree0block->data.block.val = NULL;
+ tree0block->data.block.nxt = NULL;
+ tree->data.block.nxt = NULL;
+
+
+ pp = pp_init(src);
+ pp_run(pp);
+
+ lexer = lexer_init(pp->psrc);
+ lexer_run(lexer);
+
+ parser = parser_init(lexer->tokenl);
+ parser_run(parser);
+
+ ASSERT(tree_cmp(parser->tree, tree) == 1);
+
+ token_destroy(lexer->tokenl);
+ lexer_destroy(lexer);
+ pp_destroy(pp);
+ tree_destroy(parser->tree);
+ parser_destroy(parser);
+}
+
int main(int argc, char** argv) {
- test_simple_empty();
- test_single_lint();
- test_double_lint();
+ empty();
+ single_lint();
+ double_lint();
+ single_lstr();
+ double_lstr();
+ single_block();
TEST_REPORT;
diff --git a/test/tree.c b/test/tree.c
index 1b2742c..b9ef210 100644
--- a/test/tree.c
+++ b/test/tree.c
@@ -3,12 +3,17 @@
#include "../src/include/lexer.h"
#include "../src/include/tree.h"
-unsigned int TESTS_RUN = 0, TESTS_PASSED = 0;
+TEST_INIT
-int main(int argc, char** argv) {
+/*
+ I wrote these before I started putting tests in their own functions, so
+ this'll have to do for now.
+*/
+void test_things() {
tree_t* tree_0;
tree_t* tree_1;
+ /* Not refactoring this. */
tree_t* tree_lint_0;
tree_t* tree_lint_1;
tree_t* tree_lstr_0;
@@ -240,7 +245,10 @@ int main(int argc, char** argv) {
ASSERT(tree_cmp(tree_block_0, tree_block_0) == 1);
ASSERT(tree_cmp(tree_block_0, tree_block_1) == 0);
+}
+
+int main() {
+ test_things();
- TEST_REPORT;
- return 0;
+ TEST_REPORT
}