From: hongzhidao Date: Sun, 10 Mar 2019 09:44:16 +0000 (+0800) Subject: Refactored njs_parser_function_lambda(). X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=93b9577aad3fb388a3a7318aa01ceb4c06cb991c;p=njs.git Refactored njs_parser_function_lambda(). The function is split into reusable components. --- diff --git a/njs/njs_parser.c b/njs/njs_parser.c index ce1d76fb..6d279ef3 100644 --- a/njs/njs_parser.c +++ b/njs/njs_parser.c @@ -27,6 +27,15 @@ static njs_token_t njs_parser_function_declaration(njs_vm_t *vm, njs_parser_t *parser); static njs_token_t njs_parser_function_lambda(njs_vm_t *vm, njs_parser_t *parser, njs_function_lambda_t *lambda, njs_token_t token); +static njs_token_t njs_parser_lambda_arguments(njs_vm_t *vm, + njs_parser_t *parser, njs_function_lambda_t *lambda, njs_index_t index, + njs_token_t token); +static njs_token_t njs_parser_lambda_argument(njs_vm_t *vm, + njs_parser_t *parser, njs_index_t index); +static njs_token_t njs_parser_lambda_body(njs_vm_t *vm, njs_parser_t *parser, + njs_token_t token); +static njs_parser_node_t *njs_parser_return_set(njs_vm_t *vm, + njs_parser_t *parser, njs_parser_node_t *expr); static njs_token_t njs_parser_return_statement(njs_vm_t *vm, njs_parser_t *parser); static njs_token_t njs_parser_var_statement(njs_vm_t *vm, njs_parser_t *parser); @@ -735,25 +744,45 @@ static njs_token_t njs_parser_function_lambda(njs_vm_t *vm, njs_parser_t *parser, njs_function_lambda_t *lambda, njs_token_t token) { - njs_ret_t ret; - njs_index_t index; - njs_variable_t *arg; - njs_parser_node_t *node, *body, *last, *parent, *return_node; + njs_ret_t ret; + njs_index_t index; ret = njs_parser_scope_begin(vm, parser, NJS_SCOPE_FUNCTION); if (nxt_slow_path(ret != NXT_OK)) { return NJS_TOKEN_ERROR; } - token = njs_parser_match(vm, parser, token, NJS_TOKEN_OPEN_PARENTHESIS); + index = NJS_SCOPE_ARGUMENTS; + + /* A "this" reservation. */ + index += sizeof(njs_value_t); + + token = njs_parser_lambda_arguments(vm, parser, lambda, index, token); if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return token; } - index = NJS_SCOPE_ARGUMENTS; + token = njs_parser_lambda_body(vm, parser, token); + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { + return token; + } - /* A "this" reservation. */ - index += sizeof(njs_value_t); + njs_parser_scope_end(vm, parser); + + return token; +} + + +static njs_token_t +njs_parser_lambda_arguments(njs_vm_t *vm, njs_parser_t *parser, + njs_function_lambda_t *lambda, njs_index_t index, njs_token_t token) +{ + token = njs_parser_match(vm, parser, token, NJS_TOKEN_OPEN_PARENTHESIS); + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { + return token; + } + + lambda->nargs = 0; while (token != NJS_TOKEN_CLOSE_PARENTHESIS) { @@ -774,20 +803,7 @@ njs_parser_function_lambda(njs_vm_t *vm, njs_parser_t *parser, return NJS_TOKEN_ILLEGAL; } - arg = njs_parser_variable_add(vm, parser, NJS_VARIABLE_VAR); - if (nxt_slow_path(arg == NULL)) { - return NJS_TOKEN_ERROR; - } - - arg->index = index; - index += sizeof(njs_value_t); - - ret = njs_name_copy(vm, &arg->name, njs_parser_text(parser)); - if (nxt_slow_path(ret != NXT_OK)) { - return NJS_TOKEN_ERROR; - } - - token = njs_parser_token(parser); + token = njs_parser_lambda_argument(vm, parser, index); if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return token; } @@ -798,36 +814,46 @@ njs_parser_function_lambda(njs_vm_t *vm, njs_parser_t *parser, return token; } } + + lambda->nargs++; + index += sizeof(njs_value_t); } - lambda->nargs = njs_scope_offset(index) / sizeof(njs_value_t) - 1; + return njs_parser_token(parser); +} - token = njs_parser_token(parser); - if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { - return token; - } - if (nxt_slow_path(token != NJS_TOKEN_OPEN_BRACE)) { - return NJS_TOKEN_ILLEGAL; - } +static njs_token_t +njs_parser_lambda_argument(njs_vm_t *vm, njs_parser_t *parser, + njs_index_t index) +{ + njs_ret_t ret; + njs_variable_t *arg; - token = njs_parser_token(parser); - if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { - return token; + arg = njs_parser_variable_add(vm, parser, NJS_VARIABLE_VAR); + if (nxt_slow_path(arg == NULL)) { + return NJS_TOKEN_ERROR; } - parent = parser->node; - parser->node = NULL; + arg->index = index; - while (token != NJS_TOKEN_CLOSE_BRACE) { - token = njs_parser_statement_chain(vm, parser, token, - &njs_parser_chain_top(parser)); - if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { - return token; - } + ret = njs_name_copy(vm, &arg->name, njs_parser_text(parser)); + if (nxt_slow_path(ret != NXT_OK)) { + return NJS_TOKEN_ERROR; } - token = njs_parser_token(parser); + return njs_parser_token(parser); +} + + +static njs_token_t +njs_parser_lambda_body(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token) +{ + njs_parser_node_t *body, *last, *parent; + + parent = parser->node; + + token = njs_parser_lambda_statements(vm, parser, token); if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { return token; } @@ -853,31 +879,67 @@ 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. */ - return_node = njs_parser_node_new(vm, parser, NJS_TOKEN_RETURN); - if (nxt_slow_path(return_node == NULL)) { + body = njs_parser_return_set(vm, parser, NULL); + if (nxt_slow_path(body == NULL)) { return NJS_TOKEN_ERROR; } + } - node = njs_parser_node_new(vm, parser, NJS_TOKEN_STATEMENT); - if (nxt_slow_path(node == NULL)) { - return NJS_TOKEN_ERROR; - } + parent->right = body; - node->left = body; - node->right = return_node; + parser->node = parent; + + return token; +} - njs_parser_chain_top_set(parser, node); - body = node; +static njs_parser_node_t * +njs_parser_return_set(njs_vm_t *vm, njs_parser_t *parser, + njs_parser_node_t *expr) +{ + njs_parser_node_t *stmt, *node; + + node = njs_parser_node_new(vm, parser, NJS_TOKEN_RETURN); + if (nxt_slow_path(node == NULL)) { + return NULL; } - parent->right = body; + node->right = expr; - parser->node = parent; + stmt = njs_parser_node_new(vm, parser, NJS_TOKEN_STATEMENT); + if (nxt_slow_path(stmt == NULL)) { + return NULL; + } - njs_parser_scope_end(vm, parser); + stmt->left = njs_parser_chain_top(parser); + stmt->right = node; - return token; + njs_parser_chain_top_set(parser, stmt); + + return stmt; +} + + +njs_token_t +njs_parser_lambda_statements(njs_vm_t *vm, njs_parser_t *parser, + njs_token_t token) +{ + token = njs_parser_match(vm, parser, token, NJS_TOKEN_OPEN_BRACE); + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { + return token; + } + + parser->node = NULL; + + while (token != NJS_TOKEN_CLOSE_BRACE) { + token = njs_parser_statement_chain(vm, parser, token, + &njs_parser_chain_top(parser)); + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { + return token; + } + } + + return njs_parser_token(parser); } diff --git a/njs/njs_parser.h b/njs/njs_parser.h index fef43a16..ff16691d 100644 --- a/njs/njs_parser.h +++ b/njs/njs_parser.h @@ -90,6 +90,9 @@ njs_token_t njs_parser_terminal(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token); njs_token_t njs_parser_property_token(njs_vm_t *vm, njs_parser_t *parser); njs_token_t njs_parser_token(njs_parser_t *parser); +njs_token_t njs_parser_lambda_statements(njs_vm_t *vm, njs_parser_t *parser, + njs_token_t token); + njs_variable_t *njs_variable_resolve(njs_vm_t *vm, njs_parser_node_t *node); njs_index_t njs_variable_typeof(njs_vm_t *vm, njs_parser_node_t *node); njs_index_t njs_variable_index(njs_vm_t *vm, njs_parser_node_t *node);