aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/parser.h1
-rw-r--r--src/parser.c38
-rw-r--r--test/parser.c93
3 files changed, 125 insertions, 7 deletions
diff --git a/src/include/parser.h b/src/include/parser.h
index 839e372..6961be8 100644
--- a/src/include/parser.h
+++ b/src/include/parser.h
@@ -5,6 +5,7 @@
#include "tree.h"
#include "token.h"
+/* Parser states. */
typedef enum PARSER_STATE {
PARSER_STATE_BLOCK,
PARSER_STATE_EXPR,
diff --git a/src/parser.c b/src/parser.c
index ea2245c..b42d2f0 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -1,5 +1,6 @@
#include "include/parser.h"
#include "include/token.h"
+#include "include/util.h"
parser_t* parser_init(token_t* token) {
parser_t* parser;
@@ -73,7 +74,8 @@ tree_t* parser_parse_expr(parser_t* parser) {
expr = parser_parse_block(parser);
break;
case TOKEN_TYPE_KWD:
- expr = parser_parse_kwd(parser);
+// expr = parser_parse_kwd(parser);
+ expr = parser_parse_call(parser);
break;
case TOKEN_TYPE_TAG:
expr = parser_parse_def(parser);
@@ -146,9 +148,22 @@ tree_t* parser_parse_darg(parser_t* parser) {
tree_t* parser_parse_carg(parser_t* parser) {
tree_t* carg;
+ /*
+ f.x,y,z;
+ */
+
carg = tree_init(TREE_TYPE_CARG);
carg->data.carg.val = parser_parse_expr(parser);
- carg->data.carg.nxt = NULL;
+
+ if (
+ parser->token
+ && parser->token->type == TOKEN_TYPE_LIST_DELIM
+ && parser_nxt_token(parser)
+ ) {
+ carg->data.carg.nxt = parser_parse_carg(parser);
+ } else {
+ carg->data.carg.nxt = NULL;
+ }
return carg;
}
@@ -218,11 +233,20 @@ tree_t* parser_parse_call(parser_t* parser) {
call->data.call.target = parser->token->val;
parser->token->val = NULL;
- call->data.call.arg = (
- parser_nxt_token_match(parser, TOKEN_TYPE_APPLY) && parser_nxt_token(parser) ?
- parser_parse_carg(parser) :
- NULL
- );
+
+ /*
+ If there's a call with an apply, but the file ends just after, NULL.
+ ¯\_(ツ)_/¯
+ */
+ if (
+ parser_nxt_token(parser)
+ && parser->token->type == TOKEN_TYPE_APPLY
+ && parser_nxt_token(parser)
+ ) {
+ call->data.call.arg = parser_parse_carg(parser);
+ } else {
+ call->data.call.arg = NULL;
+ }
return call;
}
diff --git a/test/parser.c b/test/parser.c
index abc1ea9..30fee73 100644
--- a/test/parser.c
+++ b/test/parser.c
@@ -797,6 +797,98 @@ void cargumented_call_of_lint() {
tree_destroy(tree);
}
+void call_many_arg() {
+ tree_t* tree;
+ pp_t* pp;
+ lexer_t* lexer;
+ parser_t* parser;
+
+ char src[] = "f.x,y,z";
+
+ /*
+
+ [block]
+ val:
+ [call]
+ target:
+ f
+ arg:
+ [carg]
+ val:
+ [call]
+ target:
+ x
+ arg:
+ NULL
+ nxt:
+ [carg]
+ val:
+ [call]
+ target:
+ y
+ arg:
+ NULL
+ nxt:
+ [carg]
+ val:
+ [call]
+ target:
+ z
+ arg:
+ NULL
+ nxt:
+ NULL
+ nxt:
+ NULL
+ nxt:
+ NULL
+
+ */
+
+ tree = tree_init(TREE_TYPE_BLOCK);
+ tree_t* tree0call = tree->data.block.val = tree_init(TREE_TYPE_CALL);
+ char* target0 = tree0call->data.call.target = ecalloc(2, sizeof(char));
+ strcpy(target0, "f");
+ tree_t* tree0carg = tree0call->data.call.arg = tree_init(TREE_TYPE_CARG);
+ tree_t* tree1call = tree0carg->data.carg.val = tree_init(TREE_TYPE_CALL);
+ char* target1 = tree1call->data.call.target = ecalloc(2, sizeof(char));
+ strcpy(target1, "x");
+ tree1call->data.call.arg = NULL;
+ tree_t* tree1carg = tree0carg->data.carg.nxt = tree_init(TREE_TYPE_CARG);
+ tree_t* tree2call = tree1carg->data.carg.val = tree_init(TREE_TYPE_CALL);
+ char* target2 = tree2call->data.call.target = ecalloc(2, sizeof(char));
+ strcpy(target2, "y");
+ tree2call->data.call.arg = NULL;
+ tree_t* tree2carg = tree1carg->data.carg.nxt = tree_init(TREE_TYPE_CARG);
+ tree_t* tree3call = tree2carg->data.carg.val = tree_init(TREE_TYPE_CALL);
+ char* target3 = tree3call->data.call.target = ecalloc(2, sizeof(char));
+ strcpy(target3, "z");
+ tree3call->data.call.arg = NULL;
+ tree2carg->data.carg.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);
+
+ tree_print(tree, 0);
+
+ 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_bare_lint() {
tree_t* tree;
pp_t* pp;
@@ -977,6 +1069,7 @@ int main() {
double_bare_call();
cargumented_call_of_call();
cargumented_call_of_lint();
+ call_many_arg();
def_bare_lint();
TEST_REPORT;