aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.gitignore1
-rw-r--r--Makefile6
-rw-r--r--src/include/lexer.h2
-rw-r--r--src/include/parser.h17
-rw-r--r--src/include/pp.h2
-rw-r--r--src/include/tree.h2
-rw-r--r--src/parser.c86
-rw-r--r--test/include/test.h4
-rw-r--r--test/parser.c70
-rw-r--r--test/tree.c4
10 files changed, 143 insertions, 51 deletions
diff --git a/.gitignore b/.gitignore
index fb8b336..341b7fe 100755
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@
tags
*.out
*.tmp.*
+coredump
*.notes.md
[._]sw[a-p]
[._]*.sw[a-p]
diff --git a/Makefile b/Makefile
index 03203b4..0e61c64 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
BIN := halk
PREFIX := /usr/local/bin
CC := gcc
-REG_CFLAGS := -ansi -O3 -s
-DBG_CFLAGS := -ansi -Og -ggdb -pedantic
+REG_CFLAGS := -std=c99 -O3 -s
+DBG_CFLAGS := -std=c99 -Og -ggdb -pedantic
DBG_CFLAGS += -Wall -Wextra -Wformat -Werror -Wpedantic
DBG_CFLAGS += -fsanitize=leak,address,undefined -fno-omit-frame-pointer
CFLAGS := $(REG_CFLAGS)
@@ -35,7 +35,7 @@ dbg: CFLAGS := $(DBG_CFLAGS)
dbg: dbg_options $(OBJS)
$(CC) $(OBJS) $(DBG_CFLAGS) -o $(BIN).out
-test: dbg $(TEST_OUTS)
+test: clean dbg $(TEST_OUTS)
set -e
for f in $(TEST_OUTS); do ./$$f; done
diff --git a/src/include/lexer.h b/src/include/lexer.h
index 02275cb..5235f3b 100644
--- a/src/include/lexer.h
+++ b/src/include/lexer.h
@@ -23,7 +23,7 @@ typedef struct LEXER_STRUC {
/* Integer. */
LEXER_STATE_INT,
/* Keyword. */
- LEXER_STATE_KWD,
+ LEXER_STATE_KWD
} state;
/* The linked list of tokens generated. */
diff --git a/src/include/parser.h b/src/include/parser.h
index eae09d4..a442d60 100644
--- a/src/include/parser.h
+++ b/src/include/parser.h
@@ -14,7 +14,7 @@ typedef enum PARSER_STATE {
PARSER_STATE_DARG,
PARSER_STATE_CARG,
PARSER_STATE_DEF,
- PARSER_STATE_CALL,
+ PARSER_STATE_CALL
} parser_state_t;
typedef struct PARSER {
@@ -41,6 +41,15 @@ void parser_destroy(parser_t* parser);
/* Step the parser forward by 1 token. */
int parser_nxt_token(parser_t* parser);
+/* Get tree for first (implied) block. */
+tree_t* parser_parse_init(parser_t* parser);
+
+/* Get tree for a block. */
+tree_t* parser_parse_block(parser_t* parser);
+
+/* Get tree for an expression.*/
+tree_t* parser_parse_expr(parser_t* parser);
+
/*
Check whether the current token matches the given type.
- If it doesn't, return 0 and throw error.
@@ -56,12 +65,6 @@ tree_t* parser_parse_lint(parser_t* parser);
/* Return the tree for a string. */
tree_t* parser_parse_lstr(parser_t* parser);
-/* Return the tree for an expression.*/
-tree_t* parser_parse_expr(parser_t* parser);
-
-/* Return the tree for an block. */
-tree_t* parser_parse_block(parser_t* parser);
-
/* Return the tree for a definition's arguments. */
tree_t* parser_parse_darg(parser_t* parser);
diff --git a/src/include/pp.h b/src/include/pp.h
index 4186ef3..bbb901c 100644
--- a/src/include/pp.h
+++ b/src/include/pp.h
@@ -27,7 +27,7 @@ typedef struct PP_STRUC {
PP_STATE_REG, /* Regular. */
PP_STATE_STR, /* String. */
PP_STATE_COM, /* Comment. */
- PP_STATE_ESC, /* Escaped character in string. */
+ PP_STATE_ESC /* Escaped character in string. */
/* PP_STATE_MCO, */ /* Macro. */
} state;
} pp_t;
diff --git a/src/include/tree.h b/src/include/tree.h
index 31b8f3f..2a62f26 100644
--- a/src/include/tree.h
+++ b/src/include/tree.h
@@ -12,7 +12,7 @@ typedef enum TREE_TYPE {
TREE_TYPE_DARG,
TREE_TYPE_CARG,
TREE_TYPE_DEF,
- TREE_TYPE_CALL,
+ TREE_TYPE_CALL
} tree_type_t;
/* The Abstract Syntax Tree (AST) structure. */
diff --git a/src/parser.c b/src/parser.c
index 2cf9b2c..f94fe53 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -18,6 +18,7 @@ void parser_destroy(parser_t* 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. */
+ if (!parser->token) { return 0; }
parser->token = parser->token->nxt;
if (parser->token && parser->token->type == TOKEN_TYPE_EXPR_END) {
return parser_nxt_token(parser);
@@ -25,6 +26,59 @@ int parser_nxt_token(parser_t* parser) {
return parser->token ? 1 : 0;
}
+tree_t* parser_parse_init(parser_t* parser) {
+ /* There is nothing to do. */
+ if (!parser->token || parser->token->type == TOKEN_TYPE_RBLOCK) {
+ return NULL;
+ }
+ tree_t* block;
+ block = tree_init(TREE_TYPE_BLOCK);
+
+ block->data.block.val = parser_parse_expr(parser);
+ block->data.block.nxt = parser_parse_block(parser);
+
+ return block;
+}
+
+tree_t* parser_parse_block(parser_t* parser) {
+ /* There is nothing to do. */
+ if (!parser->token || parser->token->type == TOKEN_TYPE_RBLOCK) {
+ parser_nxt_token(parser); /* Skip over closing bracket. */
+ return NULL;
+ }
+ tree_t* block;
+ block = tree_init(TREE_TYPE_BLOCK);
+
+ block->data.block.val = parser_parse_expr(parser);
+ block->data.block.nxt = parser_parse_block(parser);
+
+ parser_nxt_token(parser); /* Skip over semicolon. */
+
+ return block;
+}
+
+tree_t* parser_parse_expr(parser_t* parser) {
+ tree_t* expr = NULL;
+
+ switch (parser->token->type) {
+ case TOKEN_TYPE_INT:
+ expr = parser_parse_lint(parser);
+ break;
+ case TOKEN_TYPE_STR:
+ expr = parser_parse_lstr(parser);
+ break;
+ case TOKEN_TYPE_LBLOCK:
+ parser_nxt_token(parser); /* Skip over opening curly bracket. */
+ expr = parser_parse_block(parser);
+ break;
+ default:
+ log_war("%s: Unknown token type: %d", __func__, parser->token->type);
+ parser_nxt_token(parser);
+ }
+
+ return expr;
+}
+
/* 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;
@@ -59,38 +113,6 @@ tree_t* parser_parse_lstr(parser_t* parser) {
return lstr;
}
-tree_t* parser_parse_expr(parser_t* parser) {
- tree_t* expr = NULL;
-
- switch (parser->token->type) {
- case TOKEN_TYPE_INT:
- expr = parser_parse_lint(parser);
- break;
- case TOKEN_TYPE_STR:
- expr = parser_parse_lstr(parser);
- break;
- default:
- log_war("%s: Unknown token type: %d", __func__, parser->token->type);
- parser_nxt_token(parser);
- }
-
- return expr;
-}
-
-tree_t* parser_parse_block(parser_t* parser) {
- /* There is nothing to do. */
- if (!parser->token || parser->token->type == TOKEN_TYPE_RBLOCK) {
- return NULL;
- }
- tree_t* block;
- block = tree_init(TREE_TYPE_BLOCK);
-
- block->data.block.val = parser_parse_expr(parser);
- block->data.block.nxt = parser_parse_block(parser);
-
- return block;
-}
-
tree_t* parser_parse_tag(parser_t* parser) {
if (parser->token->type != TOKEN_TYPE_TAG) { return NULL; }
diff --git a/test/include/test.h b/test/include/test.h
index 3193c52..8cde34d 100644
--- a/test/include/test.h
+++ b/test/include/test.h
@@ -12,6 +12,10 @@ extern unsigned int TESTS_PASSED;
#define TEST_INIT unsigned int TESTS_RUN = 0, TESTS_PASSED = 0;
+#ifndef __func__
+#define __func__ ""
+#endif
+
#define ASSERT(EXPR) \
TESTS_RUN++; \
(EXPR && ++TESTS_PASSED) ? \
diff --git a/test/parser.c b/test/parser.c
index feb9c70..f2fe908 100644
--- a/test/parser.c
+++ b/test/parser.c
@@ -249,7 +249,7 @@ void single_block() {
lexer_t* lexer;
parser_t* parser;
- char src[] = "{}";
+ char src[] = "{1}";
/*
@@ -257,7 +257,9 @@ void single_block() {
val:
[block]
val:
- NULL
+ [lint]
+ val:
+ 1
nxt:
NULL
nxt:
@@ -267,7 +269,8 @@ void single_block() {
tree = tree_init(TREE_TYPE_BLOCK);
tree_t* tree0block = tree->data.block.val = tree_init(TREE_TYPE_BLOCK);
- tree0block->data.block.val = NULL;
+ tree_t* tree0lint = tree0block->data.block.val = tree_init(TREE_TYPE_LINT);
+ tree0lint->data.lint.val = 1;
tree0block->data.block.nxt = NULL;
tree->data.block.nxt = NULL;
@@ -290,13 +293,72 @@ void single_block() {
parser_destroy(parser);
}
-int main(int argc, char** argv) {
+void lint_and_block() {
+ tree_t* tree;
+ pp_t* pp;
+ lexer_t* lexer;
+ parser_t* parser;
+
+ char src[] = "1;{1}";
+
+ /*
+
+ [block]
+ val:
+ [lint]
+ val:
+ 1
+ nxt:
+ [block]
+ val:
+ [block]
+ val:
+ [lint]
+ val:
+ 1
+ nxt:
+ NULL
+ nxt:
+ NULL
+
+ */
+
+ tree = tree_init(TREE_TYPE_BLOCK);
+ tree_t* tree0lint = tree->data.block.val = tree_init(TREE_TYPE_LINT);
+ tree0lint->data.lint.val = 1;
+ tree_t* tree0block = tree->data.block.nxt = tree_init(TREE_TYPE_BLOCK);
+ tree_t* tree1block = tree0block->data.block.val = tree_init(TREE_TYPE_BLOCK);
+ tree_t* tree1lint = tree1block->data.block.val = tree_init(TREE_TYPE_LINT);
+ tree1lint->data.lint.val = 1;
+ tree1block->data.block.nxt = NULL;
+ 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);
+}
+
+int main() {
empty();
single_lint();
double_lint();
single_lstr();
double_lstr();
single_block();
+ lint_and_block();
TEST_REPORT;
diff --git a/test/tree.c b/test/tree.c
index b9ef210..567daae 100644
--- a/test/tree.c
+++ b/test/tree.c
@@ -20,8 +20,6 @@ void test_things() {
tree_t* tree_lstr_1;
tree_t* tree_tag_0;
tree_t* tree_tag_1;
- tree_t* tree_def_0;
- tree_t* tree_def_1;
tree_t* tree_carg_0;
tree_t* tree_carg_1;
tree_t* tree_call_0;
@@ -245,6 +243,8 @@ void test_things() {
ASSERT(tree_cmp(tree_block_0, tree_block_0) == 1);
ASSERT(tree_cmp(tree_block_0, tree_block_1) == 0);
+
+ /* *Definitely* not cleaning up fully here. Oh, well. */
}
int main() {