blob: 6689dedaffa0f01702b3ddf7e3a82ac8bb19331f [file] [log] [blame]
/*
* Copyright (C) Igor Sysoev
* Copyright (C) NGINX, Inc.
*/
#ifndef _NJS_LEXER_H_INCLUDED_
#define _NJS_LEXER_H_INCLUDED_
typedef enum {
NJS_TOKEN_ERROR = -1,
NJS_TOKEN_ILLEGAL = 0,
NJS_TOKEN_END,
NJS_TOKEN_SPACE,
NJS_TOKEN_LINE_END,
NJS_TOKEN_DOUBLE_QUOTE,
NJS_TOKEN_SINGLE_QUOTE,
NJS_TOKEN_OPEN_PARENTHESIS,
NJS_TOKEN_CLOSE_PARENTHESIS,
NJS_TOKEN_OPEN_BRACKET,
NJS_TOKEN_CLOSE_BRACKET,
NJS_TOKEN_OPEN_BRACE,
NJS_TOKEN_CLOSE_BRACE,
NJS_TOKEN_COMMA,
NJS_TOKEN_DOT,
NJS_TOKEN_ELLIPSIS,
NJS_TOKEN_SEMICOLON,
NJS_TOKEN_COLON,
NJS_TOKEN_CONDITIONAL,
NJS_TOKEN_COMMENT,
NJS_TOKEN_ASSIGNMENT,
NJS_TOKEN_ARROW,
NJS_TOKEN_ADDITION_ASSIGNMENT,
NJS_TOKEN_SUBSTRACTION_ASSIGNMENT,
NJS_TOKEN_MULTIPLICATION_ASSIGNMENT,
NJS_TOKEN_EXPONENTIATION_ASSIGNMENT,
NJS_TOKEN_DIVISION_ASSIGNMENT,
NJS_TOKEN_REMAINDER_ASSIGNMENT,
NJS_TOKEN_LEFT_SHIFT_ASSIGNMENT,
NJS_TOKEN_RIGHT_SHIFT_ASSIGNMENT,
NJS_TOKEN_UNSIGNED_RIGHT_SHIFT_ASSIGNMENT,
NJS_TOKEN_BITWISE_OR_ASSIGNMENT,
NJS_TOKEN_BITWISE_XOR_ASSIGNMENT,
NJS_TOKEN_BITWISE_AND_ASSIGNMENT,
#define NJS_TOKEN_LAST_ASSIGNMENT NJS_TOKEN_BITWISE_AND_ASSIGNMENT
NJS_TOKEN_EQUAL,
NJS_TOKEN_STRICT_EQUAL,
NJS_TOKEN_NOT_EQUAL,
NJS_TOKEN_STRICT_NOT_EQUAL,
NJS_TOKEN_ADDITION,
NJS_TOKEN_UNARY_PLUS,
NJS_TOKEN_INCREMENT,
NJS_TOKEN_POST_INCREMENT,
NJS_TOKEN_SUBSTRACTION,
NJS_TOKEN_UNARY_NEGATION,
NJS_TOKEN_DECREMENT,
NJS_TOKEN_POST_DECREMENT,
NJS_TOKEN_MULTIPLICATION,
NJS_TOKEN_EXPONENTIATION,
NJS_TOKEN_DIVISION,
NJS_TOKEN_REMAINDER,
NJS_TOKEN_LESS,
NJS_TOKEN_LESS_OR_EQUAL,
NJS_TOKEN_LEFT_SHIFT,
NJS_TOKEN_GREATER,
NJS_TOKEN_GREATER_OR_EQUAL,
NJS_TOKEN_RIGHT_SHIFT,
NJS_TOKEN_UNSIGNED_RIGHT_SHIFT,
NJS_TOKEN_BITWISE_OR,
NJS_TOKEN_LOGICAL_OR,
NJS_TOKEN_BITWISE_XOR,
NJS_TOKEN_BITWISE_AND,
NJS_TOKEN_LOGICAL_AND,
NJS_TOKEN_BITWISE_NOT,
NJS_TOKEN_LOGICAL_NOT,
NJS_TOKEN_COALESCE,
NJS_TOKEN_IN,
NJS_TOKEN_OF,
NJS_TOKEN_INSTANCEOF,
NJS_TOKEN_TYPEOF,
NJS_TOKEN_VOID,
NJS_TOKEN_NEW,
NJS_TOKEN_DELETE,
NJS_TOKEN_YIELD,
NJS_TOKEN_DIGIT,
NJS_TOKEN_LETTER,
#define NJS_TOKEN_FIRST_CONST NJS_TOKEN_NULL
NJS_TOKEN_NULL,
NJS_TOKEN_NUMBER,
NJS_TOKEN_TRUE,
NJS_TOKEN_FALSE,
NJS_TOKEN_STRING,
#define NJS_TOKEN_LAST_CONST NJS_TOKEN_STRING
NJS_TOKEN_ESCAPE_STRING,
NJS_TOKEN_UNTERMINATED_STRING,
NJS_TOKEN_NAME,
NJS_TOKEN_OBJECT,
NJS_TOKEN_OBJECT_VALUE,
NJS_TOKEN_PROPERTY,
NJS_TOKEN_PROPERTY_INIT,
NJS_TOKEN_PROPERTY_DELETE,
NJS_TOKEN_PROPERTY_GETTER,
NJS_TOKEN_PROPERTY_SETTER,
NJS_TOKEN_PROTO_INIT,
NJS_TOKEN_ARRAY,
NJS_TOKEN_GRAVE,
NJS_TOKEN_TEMPLATE_LITERAL,
NJS_TOKEN_FUNCTION,
NJS_TOKEN_FUNCTION_EXPRESSION,
NJS_TOKEN_FUNCTION_CALL,
NJS_TOKEN_METHOD_CALL,
NJS_TOKEN_ARGUMENT,
NJS_TOKEN_RETURN,
NJS_TOKEN_REGEXP,
NJS_TOKEN_EXTERNAL,
NJS_TOKEN_STATEMENT,
NJS_TOKEN_BLOCK,
NJS_TOKEN_VAR,
NJS_TOKEN_IF,
NJS_TOKEN_ELSE,
NJS_TOKEN_BRANCHING,
NJS_TOKEN_WHILE,
NJS_TOKEN_DO,
NJS_TOKEN_FOR,
NJS_TOKEN_FOR_IN,
NJS_TOKEN_BREAK,
NJS_TOKEN_CONTINUE,
NJS_TOKEN_SWITCH,
NJS_TOKEN_CASE,
NJS_TOKEN_DEFAULT,
NJS_TOKEN_WITH,
NJS_TOKEN_TRY,
NJS_TOKEN_CATCH,
NJS_TOKEN_FINALLY,
NJS_TOKEN_THROW,
NJS_TOKEN_THIS,
NJS_TOKEN_GLOBAL_OBJECT,
NJS_TOKEN_NON_LOCAL_THIS,
NJS_TOKEN_ARGUMENTS,
NJS_TOKEN_EVAL,
NJS_TOKEN_IMPORT,
NJS_TOKEN_EXPORT,
NJS_TOKEN_TARGET,
NJS_TOKEN_FROM,
NJS_TOKEN_META,
NJS_TOKEN_AWAIT,
NJS_TOKEN_ASYNC,
NJS_TOKEN_CLASS,
NJS_TOKEN_CONST,
NJS_TOKEN_DEBUGGER,
NJS_TOKEN_ENUM,
NJS_TOKEN_EXTENDS,
NJS_TOKEN_IMPLEMENTS,
NJS_TOKEN_INTERFACE,
NJS_TOKEN_LET,
NJS_TOKEN_PACKAGE,
NJS_TOKEN_PRIVATE,
NJS_TOKEN_PROTECTED,
NJS_TOKEN_PUBLIC,
NJS_TOKEN_STATIC,
NJS_TOKEN_SUPER,
NJS_TOKEN_RESERVED,
} njs_token_type_t;
typedef enum {
NJS_KEYWORD_TYPE_UNDEF = 0,
NJS_KEYWORD_TYPE_RESERVED = 1,
NJS_KEYWORD_TYPE_KEYWORD = 2
} njs_keyword_type_t;
typedef struct {
njs_str_t name;
} njs_lexer_entry_t;
typedef struct {
njs_lexer_entry_t entry;
njs_token_type_t type;
njs_bool_t reserved;
} njs_keyword_t;
typedef struct {
const char *key;
const njs_keyword_t *value;
size_t length;
size_t next;
} njs_lexer_keyword_entry_t;
typedef struct {
njs_token_type_t type:16;
njs_keyword_type_t keyword_type;
uint32_t line;
uintptr_t unique_id;
njs_str_t text;
double number;
njs_queue_link_t link;
} njs_lexer_token_t;
typedef struct {
njs_lexer_token_t *token;
njs_queue_t preread; /* of njs_lexer_token_t */
u_char *prev_start;
njs_token_type_t prev_type:16;
njs_token_type_t last_type:16;
uint32_t line;
njs_str_t file;
njs_lvlhsh_t *keywords_hash;
njs_mp_t *mem_pool;
u_char *start;
u_char *end;
} njs_lexer_t;
njs_int_t njs_lexer_init(njs_vm_t *vm, njs_lexer_t *lexer, njs_str_t *file,
u_char *start, u_char *end);
njs_lexer_token_t *njs_lexer_token(njs_lexer_t *lexer,
njs_bool_t with_end_line);
njs_lexer_token_t *njs_lexer_peek_token(njs_lexer_t *lexer,
njs_lexer_token_t *current, njs_bool_t with_end_line);
void njs_lexer_consume_token(njs_lexer_t *lexer, unsigned length);
njs_int_t njs_lexer_make_token(njs_lexer_t *lexer, njs_lexer_token_t *token);
const njs_lexer_keyword_entry_t *njs_lexer_keyword(const u_char *key,
size_t length);
njs_int_t njs_lexer_keywords(njs_arr_t *array);
njs_inline const njs_lexer_entry_t *
njs_lexer_entry(uintptr_t unique_id)
{
return (const njs_lexer_entry_t *) unique_id;
}
njs_inline njs_bool_t
njs_lexer_token_is_keyword(njs_lexer_token_t *token)
{
return token->keyword_type & NJS_KEYWORD_TYPE_KEYWORD;
}
njs_inline njs_bool_t
njs_lexer_token_is_reserved(njs_lexer_token_t *token)
{
return token->keyword_type & NJS_KEYWORD_TYPE_RESERVED;
}
njs_inline njs_bool_t
njs_lexer_token_is_name(njs_lexer_token_t *token)
{
return token->type == NJS_TOKEN_NAME
|| (!njs_lexer_token_is_reserved(token)
&& njs_lexer_token_is_keyword(token));
}
njs_inline njs_bool_t
njs_lexer_token_is_identifier_name(njs_lexer_token_t *token)
{
return token->type == NJS_TOKEN_NAME || njs_lexer_token_is_keyword(token);
}
njs_inline njs_bool_t
njs_lexer_token_is_binding_identifier(njs_lexer_token_t *token)
{
switch (token->type) {
case NJS_TOKEN_NAME:
case NJS_TOKEN_YIELD:
case NJS_TOKEN_AWAIT:
return 1;
default:
return (!njs_lexer_token_is_reserved(token)
&& njs_lexer_token_is_keyword(token));
};
}
njs_inline njs_bool_t
njs_lexer_token_is_label_identifier(njs_lexer_token_t *token)
{
return njs_lexer_token_is_binding_identifier(token);
}
njs_inline njs_bool_t
njs_lexer_token_is_identifier_reference(njs_lexer_token_t *token)
{
return njs_lexer_token_is_binding_identifier(token);
}
extern const njs_lvlhsh_proto_t njs_lexer_hash_proto;
#endif /* _NJS_LEXER_H_INCLUDED_ */