[njs] Refactored njs_parser_terminal().
Dmitry Volyntsev
xeioex at nginx.com
Mon Feb 11 15:16:22 UTC 2019
details: https://hg.nginx.org/njs/rev/a091eaa9d8eb
branches:
changeset: 773:a091eaa9d8eb
user: hongzhidao <hongzhidao at gmail.com>
date: Sat Feb 09 17:34:04 2019 +0800
description:
Refactored njs_parser_terminal().
1) Introduced njs_parser_reference().
2) njs_parser_builtin_object() and njs_parser_builtin_function()
are refactored into njs_parser_builtin().
3) njs_parser_external() is simplified and renamed as
njs_external_lookup().
diffstat:
njs/njs_extern.c | 6 +-
njs/njs_extern.h | 1 +
njs/njs_parser.c | 267 ++++++++++++++++++++++++++++++------------------------
njs/njs_parser.h | 2 -
4 files changed, 153 insertions(+), 123 deletions(-)
diffs (442 lines):
diff -r 08285ce7dd7c -r a091eaa9d8eb njs/njs_extern.c
--- a/njs/njs_extern.c Sat Feb 09 16:26:08 2019 +0800
+++ b/njs/njs_extern.c Sat Feb 09 17:34:04 2019 +0800
@@ -304,13 +304,13 @@ njs_extern_keys_array(njs_vm_t *vm, cons
njs_value_t *
-njs_parser_external(njs_vm_t *vm, njs_parser_t *parser)
+njs_external_lookup(njs_vm_t *vm, nxt_str_t *name, uint32_t hash)
{
nxt_lvlhsh_query_t lhq;
njs_extern_value_t *ev;
- lhq.key_hash = parser->lexer->key_hash;
- lhq.key = parser->lexer->text;
+ lhq.key_hash = hash;
+ lhq.key = *name;
lhq.proto = &njs_extern_value_hash_proto;
if (nxt_lvlhsh_find(&vm->externals_hash, &lhq) == NXT_OK) {
diff -r 08285ce7dd7c -r a091eaa9d8eb njs/njs_extern.h
--- a/njs/njs_extern.h Sat Feb 09 16:26:08 2019 +0800
+++ b/njs/njs_extern.h Sat Feb 09 17:34:04 2019 +0800
@@ -42,6 +42,7 @@ typedef struct {
njs_array_t *njs_extern_keys_array(njs_vm_t *vm, const njs_extern_t *external);
+njs_value_t *njs_external_lookup(njs_vm_t *vm, nxt_str_t *name, uint32_t hash);
nxt_int_t njs_external_match_native_function(njs_vm_t *vm,
njs_function_native_t func, nxt_str_t *name);
diff -r 08285ce7dd7c -r a091eaa9d8eb njs/njs_parser.c
--- a/njs/njs_parser.c Sat Feb 09 16:26:08 2019 +0800
+++ b/njs/njs_parser.c Sat Feb 09 17:34:04 2019 +0800
@@ -52,10 +52,11 @@ static njs_token_t njs_parser_throw_stat
njs_parser_t *parser);
static njs_token_t njs_parser_grouping_expression(njs_vm_t *vm,
njs_parser_t *parser);
-static njs_token_t njs_parser_builtin_object(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *node);
-static njs_token_t njs_parser_builtin_function(njs_vm_t *vm,
- njs_parser_t *parser, njs_parser_node_t *node);
+static njs_parser_node_t *njs_parser_reference(njs_vm_t *vm,
+ njs_parser_t *parser, njs_token_t token, nxt_str_t *name, uint32_t hash);
+static nxt_int_t njs_parser_builtin(njs_vm_t *vm, njs_parser_t *parser,
+ njs_parser_node_t *node, njs_value_type_t type, nxt_str_t *name,
+ uint32_t hash);
static njs_token_t njs_parser_object(njs_vm_t *vm, njs_parser_t *parser,
njs_parser_node_t *obj);
static njs_token_t njs_parser_array(njs_vm_t *vm, njs_parser_t *parser,
@@ -1808,11 +1809,12 @@ njs_parser_token(njs_parser_t *parser)
njs_token_t
njs_parser_terminal(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token)
{
- double num;
- njs_ret_t ret;
- njs_value_t *ext;
- njs_parser_node_t *node;
- njs_parser_scope_t *scope;
+ double num;
+ njs_ret_t ret;
+ njs_lexer_t *lexer;
+ njs_parser_node_t *node;
+
+ lexer = parser->lexer;
if (token == NJS_TOKEN_OPEN_PARENTHESIS) {
@@ -1833,37 +1835,16 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
return njs_parser_function_expression(vm, parser);
}
- node = njs_parser_node_new(vm, parser, token);
- if (nxt_slow_path(node == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
switch (token) {
- case NJS_TOKEN_NAME:
- nxt_thread_log_debug("JS: %V", &parser->lexer->text);
-
- ext = njs_parser_external(vm, parser);
-
- if (ext != NULL) {
- node->token = NJS_TOKEN_EXTERNAL;
- node->u.value = *ext;
- node->index = (njs_index_t) ext;
- break;
- }
-
- ret = njs_parser_variable_reference(vm, parser, node, NJS_REFERENCE);
- if (nxt_slow_path(ret != NXT_OK)) {
+ case NJS_TOKEN_OPEN_BRACE:
+ nxt_thread_log_debug("JS: OBJECT");
+
+ node = njs_parser_node_new(vm, parser, NJS_TOKEN_OBJECT);
+ if (nxt_slow_path(node == NULL)) {
return NJS_TOKEN_ERROR;
}
- break;
-
- case NJS_TOKEN_OPEN_BRACE:
- node->token = NJS_TOKEN_OBJECT;
-
- nxt_thread_log_debug("JS: OBJECT");
-
parser->node = node;
token = njs_parser_object(vm, parser, node);
@@ -1877,10 +1858,13 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
return token;
case NJS_TOKEN_OPEN_BRACKET:
- node->token = NJS_TOKEN_ARRAY;
-
nxt_thread_log_debug("JS: ARRAY");
+ node = njs_parser_node_new(vm, parser, NJS_TOKEN_ARRAY);
+ if (nxt_slow_path(node == NULL)) {
+ return NJS_TOKEN_ERROR;
+ }
+
parser->node = node;
token = njs_parser_array(vm, parser, node);
@@ -1894,19 +1878,27 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
return token;
case NJS_TOKEN_DIVISION:
+ node = njs_parser_node_new(vm, parser, NJS_TOKEN_REGEXP);
+ if (nxt_slow_path(node == NULL)) {
+ return NJS_TOKEN_ERROR;
+ }
+
token = njs_regexp_literal(vm, parser, &node->u.value);
if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
return token;
}
- nxt_thread_log_debug("REGEX: '%V'", &parser->lexer->text);
-
- node->token = NJS_TOKEN_REGEXP;
+ nxt_thread_log_debug("REGEX: '%V'", &lexer->text);
break;
case NJS_TOKEN_STRING:
- nxt_thread_log_debug("JS: '%V'", &parser->lexer->text);
+ nxt_thread_log_debug("JS: '%V'", &lexer->text);
+
+ node = njs_parser_node_new(vm, parser, NJS_TOKEN_STRING);
+ if (nxt_slow_path(node == NULL)) {
+ return NJS_TOKEN_ERROR;
+ }
ret = njs_parser_string_create(vm, &node->u.value);
if (nxt_slow_path(ret != NXT_OK)) {
@@ -1916,9 +1908,12 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
break;
case NJS_TOKEN_ESCAPE_STRING:
- node->token = NJS_TOKEN_STRING;
-
- nxt_thread_log_debug("JS: '%V'", &parser->lexer->text);
+ nxt_thread_log_debug("JS: '%V'", &lexer->text);
+
+ node = njs_parser_node_new(vm, parser, NJS_TOKEN_STRING);
+ if (nxt_slow_path(node == NULL)) {
+ return NJS_TOKEN_ERROR;
+ }
ret = njs_parser_escape_string_create(vm, parser, &node->u.value);
if (nxt_slow_path(ret != NJS_TOKEN_STRING)) {
@@ -1929,14 +1924,19 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
case NJS_TOKEN_UNTERMINATED_STRING:
njs_parser_syntax_error(vm, parser, "Unterminated string \"%V\"",
- &parser->lexer->text);
+ &lexer->text);
return NJS_TOKEN_ILLEGAL;
case NJS_TOKEN_NUMBER:
- nxt_thread_log_debug("JS: %f", parser->lexer->number);
-
- num = parser->lexer->number;
+ num = lexer->number;
+ nxt_thread_log_debug("JS: %f", num);
+
+ node = njs_parser_node_new(vm, parser, NJS_TOKEN_NUMBER);
+ if (nxt_slow_path(node == NULL)) {
+ return NJS_TOKEN_ERROR;
+ }
+
node->u.value.data.u.number = num;
node->u.value.type = NJS_NUMBER;
node->u.value.data.truth = njs_is_number_true(num);
@@ -1944,9 +1944,14 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
break;
case NJS_TOKEN_BOOLEAN:
- nxt_thread_log_debug("JS: boolean: %V", &parser->lexer->text);
-
- if (parser->lexer->number == 0) {
+ nxt_thread_log_debug("JS: boolean: %V", &lexer->text);
+
+ node = njs_parser_node_new(vm, parser, NJS_TOKEN_BOOLEAN);
+ if (nxt_slow_path(node == NULL)) {
+ return NJS_TOKEN_ERROR;
+ }
+
+ if (lexer->number == 0) {
node->u.value = njs_value_false;
} else {
@@ -1955,6 +1960,39 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
break;
+ default:
+ node = njs_parser_reference(vm, parser, token, &lexer->text,
+ lexer->key_hash);
+
+ if (nxt_slow_path(node == NULL)) {
+ return NJS_TOKEN_ERROR;
+ }
+
+ break;
+ }
+
+ parser->node = node;
+
+ return njs_parser_token(parser);
+}
+
+
+static njs_parser_node_t *
+njs_parser_reference(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token,
+ nxt_str_t *name, uint32_t hash)
+{
+ njs_ret_t ret;
+ njs_value_t *ext;
+ njs_parser_node_t *node;
+ njs_parser_scope_t *scope;
+
+ node = njs_parser_node_new(vm, parser, token);
+ if (nxt_slow_path(node == NULL)) {
+ return NULL;
+ }
+
+ switch (token) {
+
case NJS_TOKEN_NULL:
nxt_thread_log_debug("JS: null");
@@ -1992,16 +2030,21 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
case NJS_TOKEN_NJS:
case NJS_TOKEN_MATH:
case NJS_TOKEN_JSON:
- return njs_parser_builtin_object(vm, parser, node);
+ ret = njs_parser_builtin(vm, parser, node, NJS_OBJECT, name, hash);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return NULL;
+ }
+
+ break;
case NJS_TOKEN_ARGUMENTS:
nxt_thread_log_debug("JS: arguments");
if (parser->scope->type <= NJS_SCOPE_GLOBAL) {
njs_parser_syntax_error(vm, parser, "\"%V\" object "
- "in global scope", &parser->lexer->text);
-
- return NJS_TOKEN_ILLEGAL;
+ "in global scope", name);
+
+ return NULL;
}
break;
@@ -2088,24 +2131,46 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
case NJS_TOKEN_SET_TIMEOUT:
case NJS_TOKEN_SET_IMMEDIATE:
case NJS_TOKEN_CLEAR_TIMEOUT:
- return njs_parser_builtin_function(vm, parser, node);
+ ret = njs_parser_builtin(vm, parser, node, NJS_FUNCTION, name, hash);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return NULL;
+ }
+
+ break;
+
+ case NJS_TOKEN_NAME:
+ nxt_thread_log_debug("JS: %V", name);
+
+ ext = njs_external_lookup(vm, name, hash);
+
+ if (ext != NULL) {
+ node->token = NJS_TOKEN_EXTERNAL;
+ node->u.value = *ext;
+ node->index = (njs_index_t) ext;
+ break;
+ }
+
+ ret = njs_variable_reference(vm, parser->scope, node, name, hash,
+ NJS_REFERENCE);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return NULL;
+ }
+
+ break;
default:
- return njs_parser_unexpected_token(vm, parser, token);
+ (void) njs_parser_unexpected_token(vm, parser, token);
+ return NULL;
}
- parser->node = node;
-
- return njs_parser_token(parser);
+ return node;
}
-static njs_token_t
-njs_parser_builtin_object(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *node)
+static nxt_int_t
+njs_parser_builtin(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node,
+ njs_value_type_t type, nxt_str_t *name, uint32_t hash)
{
- uint32_t hash;
- nxt_str_t *name;
njs_ret_t ret;
nxt_uint_t index;
njs_variable_t *var;
@@ -2117,70 +2182,36 @@ njs_parser_builtin_object(njs_vm_t *vm,
scope = scope->parent;
}
- hash = parser->lexer->key_hash;
- name = &parser->lexer->text;
-
var = njs_variable_add(vm, scope, name, hash, NJS_VARIABLE_VAR);
if (nxt_slow_path(var == NULL)) {
- return NJS_TOKEN_ERROR;
+ return NXT_ERROR;
}
/* TODO: once */
- index = node->token - NJS_TOKEN_FIRST_OBJECT;
- var->value.data.u.object = &vm->shared->objects[index];
- var->value.type = NJS_OBJECT;
+ switch (type) {
+ case NJS_OBJECT:
+ index = node->token - NJS_TOKEN_FIRST_OBJECT;
+ var->value.data.u.object = &vm->shared->objects[index];
+ break;
+
+ case NJS_FUNCTION:
+ index = node->token - NJS_TOKEN_FIRST_FUNCTION;
+ var->value.data.u.function = &vm->shared->functions[index];
+ break;
+
+ default:
+ return NXT_ERROR;
+ }
+
+ var->value.type = type;
var->value.data.truth = 1;
ret = njs_variable_reference(vm, scope, node, name, hash, NJS_REFERENCE);
if (nxt_slow_path(ret != NXT_OK)) {
- return NJS_TOKEN_ERROR;
+ return NXT_ERROR;
}
- parser->node = node;
-
- return njs_parser_token(parser);
-}
-
-
-static njs_token_t
-njs_parser_builtin_function(njs_vm_t *vm, njs_parser_t *parser,
- njs_parser_node_t *node)
-{
- uint32_t hash;
- nxt_str_t *name;
- njs_ret_t ret;
- nxt_uint_t index;
- njs_variable_t *var;
- njs_parser_scope_t *scope;
-
- scope = parser->scope;
-
- while (scope->type != NJS_SCOPE_GLOBAL) {
- scope = scope->parent;
- }
-
- hash = parser->lexer->key_hash;
- name = &parser->lexer->text;
-
- var = njs_variable_add(vm, scope, name, hash, NJS_VARIABLE_VAR);
- if (nxt_slow_path(var == NULL)) {
- return NJS_TOKEN_ERROR;
- }
-
- /* TODO: once */
- index = node->token - NJS_TOKEN_FIRST_FUNCTION;
- var->value.data.u.function = &vm->shared->functions[index];
- var->value.type = NJS_FUNCTION;
- var->value.data.truth = 1;
-
- ret = njs_variable_reference(vm, scope, node, name, hash, NJS_REFERENCE);
- if (nxt_slow_path(ret != NXT_OK)) {
- return NJS_TOKEN_ERROR;
- }
-
- parser->node = node;
-
- return njs_parser_token(parser);
+ return NXT_OK;
}
diff -r 08285ce7dd7c -r a091eaa9d8eb njs/njs_parser.h
--- a/njs/njs_parser.h Sat Feb 09 16:26:08 2019 +0800
+++ b/njs/njs_parser.h Sat Feb 09 17:34:04 2019 +0800
@@ -306,8 +306,6 @@ void njs_lexer_rollback(njs_lexer_t *lex
nxt_int_t njs_lexer_keywords_init(nxt_mp_t *mcp, nxt_lvlhsh_t *hash);
njs_token_t njs_lexer_keyword(njs_lexer_t *lexer);
-njs_value_t *njs_parser_external(njs_vm_t *vm, njs_parser_t *parser);
-
nxt_int_t njs_parser(njs_vm_t *vm, njs_parser_t *parser,
njs_parser_t *prev);
njs_token_t njs_parser_arguments(njs_vm_t *vm, njs_parser_t *parser,
More information about the nginx-devel
mailing list