From d925561bfa2dcfe021e6c325c27e565b6be53743 Mon Sep 17 00:00:00 2001 From: hongzhidao Date: Sat, 2 Feb 2019 14:21:26 +0800 Subject: [PATCH] Improved njs_parser_statement_chain(). --- njs/njs_generator.c | 4 +-- njs/njs_parser.c | 61 +++++++++++++++++++++++++++++---------------- njs/njs_parser.h | 2 +- 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/njs/njs_generator.c b/njs/njs_generator.c index 37725ed5..e747ec52 100644 --- a/njs/njs_generator.c +++ b/njs/njs_generator.c @@ -2348,12 +2348,12 @@ njs_generate_scope(njs_vm_t *vm, njs_generator_t *generator, generator->code_start = p; generator->code_end = p; - ret = njs_generate_argument_closures(vm, generator, scope->node); + ret = njs_generate_argument_closures(vm, generator, scope->top); if (nxt_slow_path(ret != NXT_OK)) { return NXT_ERROR; } - if (nxt_slow_path(njs_generator(vm, generator, scope->node) != NXT_OK)) { + if (nxt_slow_path(njs_generator(vm, generator, scope->top) != NXT_OK)) { return NXT_ERROR; } diff --git a/njs/njs_parser.c b/njs/njs_parser.c index 19516b9c..0a66e9c0 100644 --- a/njs/njs_parser.c +++ b/njs/njs_parser.c @@ -14,7 +14,7 @@ static njs_ret_t njs_parser_scope_begin(njs_vm_t *vm, njs_parser_t *parser, njs_scope_t type); static void njs_parser_scope_end(njs_vm_t *vm, njs_parser_t *parser); static njs_token_t njs_parser_statement_chain(njs_vm_t *vm, - njs_parser_t *parser, njs_token_t token); + njs_parser_t *parser, njs_token_t token, njs_parser_node_t **dest); static njs_token_t njs_parser_statement(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token); static njs_token_t njs_parser_block_statement(njs_vm_t *vm, @@ -66,6 +66,16 @@ static njs_token_t njs_parser_unexpected_token(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token); +#define njs_parser_chain_current(parser) \ + ((parser)->node) + +#define njs_parser_chain_top(parser) \ + ((parser)->scope->top) + +#define njs_parser_chain_top_set(parser, node) \ + (parser)->scope->top = node + + nxt_int_t njs_parser(njs_vm_t *vm, njs_parser_t *parser, njs_parser_t *prev) { @@ -118,7 +128,8 @@ njs_parser(njs_vm_t *vm, njs_parser_t *parser, njs_parser_t *prev) while (token != NJS_TOKEN_END) { - token = njs_parser_statement_chain(vm, parser, token); + token = njs_parser_statement_chain(vm, parser, token, + &njs_parser_chain_top(parser)); if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return NXT_ERROR; } @@ -129,7 +140,7 @@ njs_parser(njs_vm_t *vm, njs_parser_t *parser, njs_parser_t *prev) } } - node = parser->node; + node = njs_parser_chain_top(parser); if (node == NULL) { /* Empty string, just semicolons or variables declarations. */ @@ -138,12 +149,12 @@ njs_parser(njs_vm_t *vm, njs_parser_t *parser, njs_parser_t *prev) if (nxt_slow_path(node == NULL)) { return NXT_ERROR; } + + njs_parser_chain_top_set(parser, node); } node->token = NJS_TOKEN_END; - parser->scope->node = node; - return NXT_OK; } @@ -183,6 +194,7 @@ njs_parser_scope_begin(njs_vm_t *vm, njs_parser_t *parser, njs_scope_t type) } scope->type = type; + scope->top = NULL; if (type == NJS_SCOPE_FUNCTION) { scope->next_index[0] = type; @@ -249,11 +261,11 @@ njs_parser_scope_end(njs_vm_t *vm, njs_parser_t *parser) static njs_token_t njs_parser_statement_chain(njs_vm_t *vm, njs_parser_t *parser, - njs_token_t token) + njs_token_t token, njs_parser_node_t **dest) { njs_parser_node_t *node, *last; - last = parser->node; + last = *dest; token = njs_parser_statement(vm, parser, token); @@ -269,7 +281,7 @@ njs_parser_statement_chain(njs_vm_t *vm, njs_parser_t *parser, node->left = last; node->right = parser->node; - parser->node = node; + *dest = node; while (token == NJS_TOKEN_SEMICOLON) { token = njs_parser_token(parser); @@ -407,7 +419,8 @@ njs_parser_block_statement(njs_vm_t *vm, njs_parser_t *parser) parser->node = NULL; while (token != NJS_TOKEN_CLOSE_BRACE) { - token = njs_parser_statement_chain(vm, parser, token); + token = njs_parser_statement_chain(vm, parser, token, + &njs_parser_chain_current(parser)); if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return token; } @@ -625,7 +638,7 @@ njs_parser_function_lambda(njs_vm_t *vm, njs_parser_t *parser, njs_ret_t ret; njs_index_t index; njs_variable_t *arg; - njs_parser_node_t *node, *body, *last, *parent; + njs_parser_node_t *node, *body, *last, *parent, *return_node; ret = njs_parser_scope_begin(vm, parser, NJS_SCOPE_FUNCTION); if (nxt_slow_path(ret != NXT_OK)) { @@ -707,7 +720,8 @@ njs_parser_function_lambda(njs_vm_t *vm, njs_parser_t *parser, parser->node = NULL; while (token != NJS_TOKEN_CLOSE_BRACE) { - token = njs_parser_statement_chain(vm, parser, token); + token = njs_parser_statement_chain(vm, parser, token, + &njs_parser_chain_top(parser)); if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return token; } @@ -719,7 +733,7 @@ njs_parser_function_lambda(njs_vm_t *vm, njs_parser_t *parser, } last = NULL; - body = parser->node; + body = njs_parser_chain_top(parser); if (body != NULL) { /* Take the last function body statement. */ @@ -739,23 +753,25 @@ njs_parser_function_lambda(njs_vm_t *vm, njs_parser_t *parser, * There is no function body or the last function body * body statement is not "return" statement. */ - node = njs_parser_node_new(vm, parser, NJS_TOKEN_STATEMENT); - if (nxt_slow_path(node == NULL)) { + return_node = njs_parser_node_new(vm, parser, NJS_TOKEN_RETURN); + if (nxt_slow_path(return_node == NULL)) { return NJS_TOKEN_ERROR; } - node->left = parser->node; - node->right = njs_parser_node_new(vm, parser, NJS_TOKEN_RETURN); - if (nxt_slow_path(node->right == NULL)) { + node = njs_parser_node_new(vm, parser, NJS_TOKEN_STATEMENT); + if (nxt_slow_path(node == NULL)) { return NJS_TOKEN_ERROR; } - parser->node = node; - } + node->left = body; + node->right = return_node; - parent->right = parser->node; + njs_parser_chain_top_set(parser, node); + + body = node; + } - parser->scope->node = parser->node; + parent->right = body; parser->node = parent; @@ -1066,7 +1082,8 @@ njs_parser_switch_statement(njs_vm_t *vm, njs_parser_t *parser) return NJS_TOKEN_ILLEGAL; } - token = njs_parser_statement_chain(vm, parser, token); + token = njs_parser_statement_chain(vm, parser, token, + &njs_parser_chain_current(parser)); if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return token; } diff --git a/njs/njs_parser.h b/njs/njs_parser.h index 4cd9b654..c82aa6fd 100644 --- a/njs/njs_parser.h +++ b/njs/njs_parser.h @@ -232,7 +232,7 @@ typedef struct { struct njs_parser_scope_s { - njs_parser_node_t *node; + njs_parser_node_t *top; nxt_queue_link_t link; nxt_queue_t nested; -- 2.47.3