lexer = &parser->lexer0;
parser->lexer = lexer;
+ njs_rbtree_init(&parser->labels, njs_parser_scope_rbtree_compare);
+
return njs_lexer_init(vm, lexer, file, start, end);
}
scope->type = type;
njs_rbtree_init(&scope->variables, njs_parser_scope_rbtree_compare);
- njs_rbtree_init(&scope->labels, njs_parser_scope_rbtree_compare);
njs_rbtree_init(&scope->references, njs_parser_scope_rbtree_compare);
parent = parser->scope;
return njs_parser_stack_pop(parser);
}
- if (njs_label_find(parser->vm, parser->scope, token->atom_id)
- == NULL)
+ if (!njs_label_find(parser, token->atom_id))
{
njs_parser_syntax_error(parser, "Undefined label \"%V\"",
&token->text);
njs_queue_link_t *current)
{
uintptr_t atom_id;
- njs_variable_t *label;
atom_id = token->atom_id;
- label = njs_label_find(parser->vm, parser->scope, atom_id);
- if (label != NULL) {
+ if (njs_label_find(parser, atom_id)) {
njs_parser_syntax_error(parser, "Label \"%V\" "
"has already been declared", &token->text);
return NJS_DONE;
}
- label = njs_label_add(parser->vm, parser->scope, atom_id);
- if (label == NULL) {
+ if (njs_label_add(parser, atom_id) != NJS_OK) {
return NJS_ERROR;
}
return NJS_ERROR;
}
- ret = njs_label_remove(parser->vm, parser->scope, atom_id);
+ ret = njs_label_remove(parser, atom_id);
if (ret != NJS_OK) {
return NJS_ERROR;
}
njs_value_null_set(&parser->node->u.value);
ret = njs_parser_variable_reference(parser, parser->scope, parser->node,
- atom_id, NJS_DECLARATION);
+ atom_id);
if (ret != NJS_OK) {
return NJS_ERROR;
}
var->self = 1;
ret = njs_parser_variable_reference(parser, parser->scope,
- parser->node->left, atom_id,
- NJS_DECLARATION);
+ parser->node->left, atom_id);
if (ret != NJS_OK) {
return NJS_ERROR;
}
}
ret = njs_parser_variable_reference(parser, parser->scope, node->left,
- NJS_ATOM_STRING_empty, NJS_DECLARATION);
+ NJS_ATOM_STRING_empty);
if (ret != NJS_OK) {
return NJS_ERROR;
}
return NULL;
}
- ret = njs_parser_variable_reference(parser, parser->scope, node, atom_id,
- NJS_DECLARATION);
+ ret = njs_parser_variable_reference(parser, parser->scope, node, atom_id);
if (njs_slow_path(ret != NJS_OK)) {
return NULL;
}
node->token_line = token->line;
ret = njs_parser_variable_reference(parser, parser->scope, node,
- token->atom_id, NJS_REFERENCE);
+ token->atom_id);
if (njs_slow_path(ret != NJS_OK)) {
return NULL;
}
node->token_line = token->line;
ret = njs_parser_variable_reference(parser, parser->scope, node,
- token->atom_id, NJS_REFERENCE);
+ token->atom_id);
if (njs_slow_path(ret != NJS_OK)) {
return NULL;
}
node->token_line = token->line;
ret = njs_parser_variable_reference(parser, parser->scope, node,
- token->atom_id, NJS_REFERENCE);
+ token->atom_id);
if (njs_slow_path(ret != NJS_OK)) {
return NULL;
}
njs_int_t
njs_parser_variable_reference(njs_parser_t *parser, njs_parser_scope_t *scope,
- njs_parser_node_t *node, uintptr_t atom_id, njs_reference_type_t type)
+ njs_parser_node_t *node, uintptr_t atom_id)
{
njs_rbtree_node_t *rb_node;
njs_variable_reference_t *vr;
njs_parser_scope_t *parent;
njs_rbtree_t variables;
- njs_rbtree_t labels;
njs_rbtree_t references;
njs_arr_t *closures;
} njs_parser_array_item_t;
+typedef struct njs_parser_label_s njs_parser_label_t;
+
+struct njs_parser_label_s {
+ NJS_RBTREE_NODE (node);
+ uintptr_t key;
+};
+
+
struct njs_parser_node_s {
njs_token_type_t token_type:16;
uint8_t ctor:1;
njs_parser_node_t *node;
njs_parser_node_t *target;
njs_parser_scope_t *scope;
+ njs_rbtree_t labels;
njs_variable_type_t var_type;
njs_int_t ret;
njs_index_t njs_variable_index(njs_vm_t *vm, njs_parser_node_t *node);
njs_bool_t njs_parser_has_side_effect(njs_parser_node_t *node);
njs_int_t njs_parser_variable_reference(njs_parser_t *parser,
- njs_parser_scope_t *scope, njs_parser_node_t *node, uintptr_t atom_id,
- njs_reference_type_t type);
+ njs_parser_scope_t *scope, njs_parser_node_t *node, uintptr_t atom_id);
njs_token_type_t njs_parser_unexpected_token(njs_vm_t *vm, njs_parser_t *parser,
njs_str_t *name, njs_token_type_t type);
njs_int_t njs_parser_string_create(njs_vm_t *vm, njs_lexer_token_t *token,
}
-njs_variable_t *
-njs_label_add(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t atom_id)
+njs_int_t
+njs_label_add(njs_parser_t *parser, uintptr_t atom_id)
{
- njs_variable_t *label;
- njs_rbtree_node_t *node;
- njs_variable_node_t var_node, *var_node_new;
-
- var_node.key = atom_id;
-
- node = njs_rbtree_find(&scope->labels, &var_node.node);
-
- if (node != NULL) {
- return ((njs_variable_node_t *) node)->variable;
- }
+ njs_parser_label_t *label;
- label = njs_variable_alloc(vm, atom_id, NJS_VARIABLE_CONST);
+ label = njs_mp_alloc(parser->vm->mem_pool, sizeof(njs_parser_label_t));
if (njs_slow_path(label == NULL)) {
- goto memory_error;
- }
-
- var_node_new = njs_variable_node_alloc(vm, label, atom_id);
- if (njs_slow_path(var_node_new == NULL)) {
- goto memory_error;
+ njs_memory_error(parser->vm);
+ return NJS_ERROR;
}
- njs_rbtree_insert(&scope->labels, &var_node_new->node);
-
- return label;
+ label->key = atom_id;
-memory_error:
-
- njs_memory_error(vm);
+ njs_rbtree_insert(&parser->labels, &label->node);
- return NULL;
+ return NJS_OK;
}
njs_int_t
-njs_label_remove(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t atom_id)
+njs_label_remove(njs_parser_t *parser, uintptr_t atom_id)
{
- njs_rbtree_node_t *node;
- njs_variable_node_t var_node;
+ njs_rbtree_node_t *node;
+ njs_parser_label_t label;
- var_node.key = atom_id;
+ label.key = atom_id;
- node = njs_rbtree_find(&scope->labels, &var_node.node);
+ node = njs_rbtree_find(&parser->labels, &label.node);
if (njs_slow_path(node == NULL)) {
- njs_internal_error(vm, "failed to find label while removing");
+ njs_internal_error(parser->vm, "failed to find label while removing");
return NJS_ERROR;
}
- njs_rbtree_delete(&scope->labels, (njs_rbtree_part_t *) node);
- njs_variable_node_free(vm, (njs_variable_node_t *) node);
+ njs_rbtree_delete(&parser->labels, (njs_rbtree_part_t *) node);
+ njs_mp_free(parser->vm->mem_pool, node);
return NJS_OK;
}
}
-njs_variable_t *
-njs_label_find(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t atom_id)
+njs_bool_t
+njs_label_find(njs_parser_t *parser, uintptr_t atom_id)
{
- njs_rbtree_node_t *node;
- njs_variable_node_t var_node;
-
- var_node.key = atom_id;
-
- do {
- node = njs_rbtree_find(&scope->labels, &var_node.node);
-
- if (node != NULL) {
- return ((njs_variable_node_t *) node)->variable;
- }
+ njs_parser_label_t label;
- scope = scope->parent;
+ label.key = atom_id;
- } while (scope != NULL);
-
- return NULL;
+ return njs_rbtree_find(&parser->labels, &label.node) != NULL;
}
njs_parser_scope_t *scope, uintptr_t atom_id, njs_variable_type_t type);
njs_variable_t *njs_variable_function_add(njs_parser_t *parser,
njs_parser_scope_t *scope, uintptr_t atom_id);
-njs_variable_t * njs_label_add(njs_vm_t *vm, njs_parser_scope_t *scope,
- uintptr_t atom_id);
-njs_variable_t *njs_label_find(njs_vm_t *vm, njs_parser_scope_t *scope,
- uintptr_t atom_id);
-njs_int_t njs_label_remove(njs_vm_t *vm, njs_parser_scope_t *scope,
- uintptr_t atom_id);
+njs_int_t njs_label_add(njs_parser_t *parser, uintptr_t atom_id);
+njs_bool_t njs_label_find(njs_parser_t *parser, uintptr_t atom_id);
+njs_int_t njs_label_remove(njs_parser_t *parser, uintptr_t atom_id);
njs_variable_t *njs_variable_reference(njs_vm_t *vm, njs_parser_node_t *node);
njs_variable_t *njs_variable_scope_add(njs_parser_t *parser,
njs_parser_scope_t *scope, njs_parser_scope_t *original,