diff options
-rw-r--r-- | src/include/parser.h | 1 | ||||
-rw-r--r-- | src/parser.c | 38 | ||||
-rw-r--r-- | test/parser.c | 93 |
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; |