aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorc2024-02-13 11:49:26 -0500
committerc2024-02-13 11:49:26 -0500
commit3dbe235f65987ae2bb34c6859926f33791feab67 (patch)
treef4ebe27796c02eba3bda728a17b98696c1fcdbe1
parent78bdd279d90ace6e53a853a898f4819327e82743 (diff)
Definitions may now be parsed.
-rw-r--r--Makefile2
-rw-r--r--src/include/parser.h34
-rw-r--r--src/lexer.c4
-rw-r--r--src/parser.c116
-rw-r--r--test/parser.c166
5 files changed, 248 insertions, 74 deletions
diff --git a/Makefile b/Makefile
index 6c8bc12..51c9d5f 100644
--- a/Makefile
+++ b/Makefile
@@ -39,7 +39,7 @@ test: $(TEST_OUTS)
$(CC) -c $< -o $@ $(CFLAGS)
%.out: %.c
- $(CC) $< $(filter-out %main.o,$(OBJS)) -o $@ $(DBG_CFLAGS)
+ $(CC) $< $(filter-out %main.o,$(OBJS)) -o $@ $(CFLAGS)
install: all
mkdir -p $(PREFIX)
diff --git a/src/include/parser.h b/src/include/parser.h
index 257189d..839e372 100644
--- a/src/include/parser.h
+++ b/src/include/parser.h
@@ -47,37 +47,41 @@ tree_t* parser_parse_init(parser_t* parser);
/* Get tree for a block. */
tree_t* parser_parse_block(parser_t* parser);
+/* Get tree for a keyword. */
tree_t* parser_parse_kwd(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.
-*/
-int parser_match(parser_t* parser, token_type_t type);
-
-/* Steps the parser forward by one token, then check whether the new token matches the given type. */
-int parser_nxt_token_match(parser_t* parser, token_type_t type);
-
/* Return the tree for an integer. */
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 a definition's arguments. */
-tree_t* parser_parse_darg(parser_t* parser);
+/* Return the tree for a call. */
+tree_t* parser_parse_call(parser_t* parser);
+
+/* Return the tree for a call's arguments. */
+tree_t* parser_parse_carg(parser_t* parser);
/* Return the tree for a definition. */
tree_t* parser_parse_def(parser_t* parser);
-/* Return the tree for a call's arguments. */
-tree_t* parser_parse_carg(parser_t* parser);
+/* Return the tree for a definition tag. */
+tree_t* parser_parse_tag(parser_t* parser);
-/* Return the tree for a call. */
-tree_t* parser_parse_call(parser_t* parser);
+/* Return the tree for a definition's arguments. */
+tree_t* parser_parse_darg(parser_t* parser);
+
+/*
+ Check whether the current token matches the given type.
+ - If it doesn't, return 0 and throw error.
+*/
+int parser_match(parser_t* parser, token_type_t type);
+
+/* Steps the parser forward by one token, then check whether the new token matches the given type. */
+int parser_nxt_token_match(parser_t* parser, token_type_t type);
/* Parse. */
void parser_parse(parser_t* parser);
diff --git a/src/lexer.c b/src/lexer.c
index 5094b00..aa068a9 100644
--- a/src/lexer.c
+++ b/src/lexer.c
@@ -61,9 +61,9 @@ void lexer_do_reg(lexer_t* lexer) {
case SYNTAX_TAG_DELIM:
lexer->state = LEXER_STATE_TAG;
break;
-/* case SYNTAX_NAMESPACE_DELIM:
+ /*case SYNTAX_NAMESPACE_DELIM:
lexer_add_current_char(lexer, TOKEN_NAMESPACE_DELIM);
- break; */
+ break;*/
case SYNTAX_SET:
lexer_add_current_char(lexer, TOKEN_TYPE_SET);
break;
diff --git a/src/parser.c b/src/parser.c
index 731df78..ea2245c 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -75,6 +75,9 @@ tree_t* parser_parse_expr(parser_t* parser) {
case TOKEN_TYPE_KWD:
expr = parser_parse_kwd(parser);
break;
+ case TOKEN_TYPE_TAG:
+ expr = parser_parse_def(parser);
+ break;
default:
LOG_WARF("%s: Unknown token type: %d", __func__, parser->token->type);
parser_nxt_token(parser);
@@ -83,6 +86,63 @@ tree_t* parser_parse_expr(parser_t* parser) {
return expr;
}
+tree_t* parser_parse_def(parser_t* parser) {
+ tree_t* def = tree_init(TREE_TYPE_DEF);
+
+ def->data.def.tag = parser_parse_tag(parser);
+
+ if (parser->token->type == TOKEN_TYPE_APPLY) {
+ parser_nxt_token(parser);
+ def->data.def.arg = parser_parse_darg(parser);
+ } else {
+ def->data.def.arg = NULL;
+ }
+
+ if (parser->token->type == TOKEN_TYPE_SET) {
+ parser_nxt_token(parser);
+ def->data.def.val = parser_parse_expr(parser);
+ } else {
+ def->data.def.val = NULL;
+ }
+
+ return def;
+}
+
+tree_t* parser_parse_tag(parser_t* parser) {
+ if (
+ parser->token &&
+ parser->token->type != TOKEN_TYPE_TAG
+ ) { return NULL; }
+
+ tree_t* tag = tree_init(TREE_TYPE_TAG);
+
+ tag->data.tag.val = parser->token->val;
+ parser->token->val = NULL;
+
+ parser_nxt_token(parser);
+
+ tag->data.tag.nxt = parser_parse_tag(parser);
+
+ return tag;
+}
+
+tree_t* parser_parse_darg(parser_t* parser) {
+ tree_t* darg = tree_init(TREE_TYPE_DARG);
+
+ darg->data.darg.tag = parser_parse_tag(parser);
+
+ parser_nxt_token(parser);
+
+ if (parser->token->type == TOKEN_TYPE_LIST_DELIM) {
+ parser_nxt_token(parser);
+ darg->data.darg.nxt = parser_parse_darg(parser);
+ } else {
+ darg->data.darg.nxt = NULL;
+ }
+
+ return darg;
+}
+
tree_t* parser_parse_carg(parser_t* parser) {
tree_t* carg;
@@ -151,62 +211,6 @@ tree_t* parser_parse_lstr(parser_t* parser) {
return lstr;
}
-tree_t* parser_parse_tag(parser_t* parser) {
- if (parser->token->type != TOKEN_TYPE_TAG) { return NULL; }
-
- tree_t* tag;
-
- tag = tree_init(TREE_TYPE_TAG);
-
- tag->data.tag.val = parser->token->val;
- parser->token->val = NULL;
- tag->data.tag.nxt = (
- parser_nxt_token(parser) ?
- parser_parse_tag(parser) :
- NULL
- );
-
- return tag;
-}
-
-tree_t* parser_parse_darg(parser_t* parser) {
- tree_t* darg;
-
- darg = tree_init(TREE_TYPE_DARG);
-
- if (parser->token->type != TOKEN_TYPE_TAG) { return NULL; }
-
- darg->data.darg.tag = parser_parse_tag(parser);
-
- LOG_WARF("%d", parser->token->type);
-
- if (parser->token->type != TOKEN_TYPE_LIST_DELIM) {
- darg->data.darg.nxt = NULL;
- } else {
- parser_nxt_token(parser) &&
- (darg->data.darg.nxt = parser_parse_darg(parser));
- }
-
- return darg;
-}
-
-tree_t* parser_parse_def(parser_t* parser) {
- tree_t* def;
-
- def = tree_init(TREE_TYPE_DEF);
-
- def->data.def.tag = parser_parse_tag(parser);
-
- parser->token->type == TOKEN_TYPE_APPLY &&
- parser_nxt_token(parser) &&
- ( def->data.def.arg = parser_parse_darg(parser) );
- parser->token->type == TOKEN_TYPE_SET &&
- parser_nxt_token(parser) &&
- ( def->data.def.val = parser_parse_expr(parser) );
-
- return def;
-}
-
tree_t* parser_parse_call(parser_t* parser) {
tree_t* call;
diff --git a/test/parser.c b/test/parser.c
index 503244f..abc1ea9 100644
--- a/test/parser.c
+++ b/test/parser.c
@@ -797,6 +797,171 @@ void cargumented_call_of_lint() {
tree_destroy(tree);
}
+void def_bare_lint() {
+ tree_t* tree;
+ pp_t* pp;
+ lexer_t* lexer;
+ parser_t* parser;
+
+ char src[] = ":i:n = 3";
+
+ /*
+
+ [block]
+ val:
+ [def]
+ tag:
+ [tag]
+ val:
+ i
+ nxt:
+ [tag]
+ val:
+ n
+ nxt:
+ NULL
+ arg:
+ NULL
+ val:
+ [lint]
+ val:
+ 3
+ nxt:
+ NULL
+
+ */
+
+ tree = tree_init(TREE_TYPE_BLOCK);
+ tree_t* tree0def = tree->data.block.val = tree_init(TREE_TYPE_DEF);
+ tree_t* tree0tag = tree0def->data.def.tag = tree_init(TREE_TYPE_TAG);
+ char* val0 = tree0tag->data.tag.val = ecalloc(2, sizeof(char));
+ strcpy(val0, "i");
+ tree_t* tree1tag = tree0tag->data.tag.nxt = tree_init(TREE_TYPE_TAG);
+ char* val1 = tree1tag->data.tag.val = ecalloc(2, sizeof(char));
+ strcpy(val1, "n");
+ tree1tag->data.tag.nxt = NULL;
+ tree0def->data.def.arg = NULL;
+ tree_t* tree0lint = tree0def->data.def.val = tree_init(TREE_TYPE_LINT);
+ tree0lint->data.lint.val = 3;
+ 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);
+ free(pp->psrc);
+ pp_destroy(pp);
+ tree_destroy(parser->tree);
+ parser_destroy(parser);
+ tree_destroy(tree);
+}
+
+void def_add1() {
+ tree_t* tree;
+ pp_t* pp;
+ lexer_t* lexer;
+ parser_t* parser;
+
+ char src[] = ":i:add1.:i:n = +.n, 1";
+
+ /*
+
+ [block]
+ val:
+ [def]
+ tag:
+ [tag]
+ val:
+ i
+ nxt:
+ [tag]
+ val:
+ add1
+ nxt:
+ NULL
+ arg:
+ [darg]
+ tag:
+ [tag]
+ val:
+ i
+ nxt:
+ [tag]
+ val:
+ n
+ nxt:
+ NULL
+ nxt:
+ NULL
+ val:
+ [call]
+ target:
+ +
+ arg:
+ [carg]
+ val:
+ [call]
+ target:
+ n
+ arg:
+ NULL
+ nxt:
+ [carg]
+ val:
+ [lint]
+ val:
+ 1
+ nxt:
+ NULL
+ nxt:
+ NULL
+
+ */
+
+ /* TODO: Write this test. */
+ tree = tree_init(TREE_TYPE_BLOCK);
+ tree_t* tree0def = tree->data.block.val = tree_init(TREE_TYPE_DEF);
+ tree_t* tree0tag = tree0def->data.def.tag = tree_init(TREE_TYPE_TAG);
+ char* val0 = tree0tag->data.tag.val = ecalloc(2, sizeof(char));
+ strcpy(val0, "i");
+ tree_t* tree1tag = tree0tag->data.tag.nxt = tree_init(TREE_TYPE_TAG);
+ char* val1 = tree1tag->data.tag.val = ecalloc(2, sizeof(char));
+ strcpy(val1, "n");
+ tree1tag->data.tag.nxt = NULL;
+ tree0def->data.def.arg = NULL;
+ tree_t* tree0lint = tree0def->data.def.val = tree_init(TREE_TYPE_LINT);
+ tree0lint->data.lint.val = 3;
+ 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);
+ free(pp->psrc);
+ pp_destroy(pp);
+ tree_destroy(parser->tree);
+ parser_destroy(parser);
+ tree_destroy(tree);
+}
+
int main() {
empty();
single_lint();
@@ -812,6 +977,7 @@ int main() {
double_bare_call();
cargumented_call_of_call();
cargumented_call_of_lint();
+ def_bare_lint();
TEST_REPORT;