Skip to content

Commit

Permalink
Implement logical assignment operators (#4834)
Browse files Browse the repository at this point in the history
JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik [email protected]
  • Loading branch information
Robert Fancsik authored Nov 30, 2021
1 parent 70e275e commit d69ac0e
Show file tree
Hide file tree
Showing 9 changed files with 656 additions and 222 deletions.
2 changes: 1 addition & 1 deletion jerry-core/parser/js/byte-code.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ JERRY_STATIC_ASSERT (offsetof (cbc_uint8_arguments_t, script_value) == offsetof
* whenever new bytecodes are introduced or existing ones have been deleted.
*/
JERRY_STATIC_ASSERT (CBC_END == 238, number_of_cbc_opcodes_changed);
JERRY_STATIC_ASSERT (CBC_EXT_END == 165, number_of_cbc_ext_opcodes_changed);
JERRY_STATIC_ASSERT (CBC_EXT_END == 166, number_of_cbc_ext_opcodes_changed);

#if JERRY_PARSER || JERRY_PARSER_DUMP_BYTE_CODE

Expand Down
1 change: 1 addition & 0 deletions jerry-core/parser/js/byte-code.h
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@
CBC_FORWARD_BRANCH (CBC_EXT_BRANCH_IF_NULLISH, -1, VM_OC_BRANCH_IF_NULLISH) \
\
/* Basic opcodes. */ \
CBC_OPCODE (CBC_EXT_POP_REFERENCE, CBC_NO_FLAG, -2, VM_OC_POP_REFERENCE) \
CBC_OPCODE (CBC_EXT_CREATE_ARGUMENTS, CBC_HAS_LITERAL_ARG, 0, VM_OC_CREATE_ARGUMENTS) \
CBC_OPCODE (CBC_EXT_CREATE_VAR_EVAL, CBC_HAS_LITERAL_ARG, 0, VM_OC_EXT_VAR_EVAL) \
CBC_OPCODE (CBC_EXT_CREATE_VAR_FUNC_EVAL, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, VM_OC_EXT_VAR_EVAL) \
Expand Down
67 changes: 63 additions & 4 deletions jerry-core/parser/js/js-lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1509,6 +1509,55 @@ lexer_parse_number (parser_context_t *context_p) /**< context */
break; \
}

/**
* Four tokens, where the first is the prefix of the other three
* and the second is prefix of the fourth (e.g. &, &&, &=, &&= ).
*
* @param char1 first character
* @param type1 type of the first character
* @param char2 second character
* @param type2 type of the second character
* @param char3 third character
* @param type3 type of the third character
* @param char4 fourth character
* @param type4 type of the fourth character
*/
#if JERRY_ESNEXT
#define LEXER_TYPE_D_TOKEN(char1, type1, char2, type2, char3, type3, char4, type4) \
case (uint8_t) (char1): \
{ \
if (length >= 2) \
{ \
if (context_p->source_p[1] == (uint8_t) (char2)) \
{ \
context_p->token.type = (type2); \
length = 2; \
break; \
} \
\
if (context_p->source_p[1] == (uint8_t) (char3)) \
{ \
if (length >= 3 && context_p->source_p[2] == (uint8_t) (char4)) \
{ \
context_p->token.type = (type4); \
length = 3; \
break; \
} \
context_p->token.type = (type3); \
length = 2; \
break; \
} \
} \
\
context_p->token.type = (type1); \
length = 1; \
break; \
}
#else /* !JERRY_ESNEXT */
#define LEXER_TYPE_D_TOKEN(char1, type1, char2, type2, char3, type3, char4, type4) \
LEXER_TYPE_C_TOKEN (char1, type1, char2, type2, char3, type3)
#endif /* JERRY_ESNEXT */

/**
* Get next token.
*/
Expand Down Expand Up @@ -1759,18 +1808,22 @@ lexer_next_token (parser_context_t *context_p) /**< context */
LEXER_TYPE_B_TOKEN (LIT_CHAR_SLASH, LEXER_DIVIDE, LIT_CHAR_EQUALS, LEXER_ASSIGN_DIVIDE)
LEXER_TYPE_B_TOKEN (LIT_CHAR_PERCENT, LEXER_MODULO, LIT_CHAR_EQUALS, LEXER_ASSIGN_MODULO)

LEXER_TYPE_C_TOKEN (LIT_CHAR_AMPERSAND,
LEXER_TYPE_D_TOKEN (LIT_CHAR_AMPERSAND,
LEXER_BIT_AND,
LIT_CHAR_EQUALS,
LEXER_ASSIGN_BIT_AND,
LIT_CHAR_AMPERSAND,
LEXER_LOGICAL_AND)
LEXER_TYPE_C_TOKEN (LIT_CHAR_VLINE,
LEXER_LOGICAL_AND,
LIT_CHAR_EQUALS,
LEXER_ASSIGN_LOGICAL_AND)
LEXER_TYPE_D_TOKEN (LIT_CHAR_VLINE,
LEXER_BIT_OR,
LIT_CHAR_EQUALS,
LEXER_ASSIGN_BIT_OR,
LIT_CHAR_VLINE,
LEXER_LOGICAL_OR)
LEXER_LOGICAL_OR,
LIT_CHAR_EQUALS,
LEXER_ASSIGN_LOGICAL_OR)

LEXER_TYPE_B_TOKEN (LIT_CHAR_CIRCUMFLEX, LEXER_BIT_XOR, LIT_CHAR_EQUALS, LEXER_ASSIGN_BIT_XOR)

Expand All @@ -1782,6 +1835,12 @@ lexer_next_token (parser_context_t *context_p) /**< context */
{
if (context_p->source_p[1] == (uint8_t) LIT_CHAR_QUESTION)
{
if (length >= 3 && context_p->source_p[2] == (uint8_t) LIT_CHAR_EQUALS)
{
context_p->token.type = LEXER_ASSIGN_NULLISH_COALESCING;
length = 3;
break;
}
context_p->token.type = LEXER_NULLISH_COALESCING;
length = 2;
break;
Expand Down
4 changes: 4 additions & 0 deletions jerry-core/parser/js/js-lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ typedef enum
LEXER_ASSIGN_MODULO, /**< "%=" (prec: 3) */
#if JERRY_ESNEXT
LEXER_ASSIGN_EXPONENTIATION, /**< "**=" (prec: 3) */
LEXER_ASSIGN_NULLISH_COALESCING, /**< "??=" (prec: 3) */
LEXER_ASSIGN_LOGICAL_OR, /**< "||=" (prec: 3) */
LEXER_ASSIGN_LOGICAL_AND, /**< "&&=" (prec: 3) */
#endif /* JERRY_ESNEXT */
LEXER_ASSIGN_LEFT_SHIFT, /**< "<<=" (prec: 3) */
LEXER_ASSIGN_RIGHT_SHIFT, /**< ">>=" (prec: 3) */
Expand Down Expand Up @@ -217,6 +220,7 @@ typedef enum
LEXER_ASSIGN_CONST, /**< a const binding is reassigned */
LEXER_INVALID_PATTERN, /**< special value for invalid destructuring pattern */
LEXER_PRIVATE_PRIMARY_EXPR, /**< private field in primary expession position */
LEXER_ASSIGN_REFERENCE, /**< special value for reference assignment */
#endif /* JERRY_ESNEXT */

/* Keywords which are not keyword tokens. */
Expand Down
Loading

0 comments on commit d69ac0e

Please sign in to comment.