Robert Fancsik 213544ae47 Implement array/object destructuring (#3305)
This patch implements the core functionality of destructuring patterns.
Function argument/for in-of pattern are currently unsupported.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
2019-11-14 13:49:49 +01:00

197 lines
6.3 KiB
C

/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef JS_SCANNER_H
#define JS_SCANNER_H
/** \addtogroup parser Parser
* @{
*
* \addtogroup jsparser JavaScript
* @{
*
* \addtogroup jsparser_scanner Scanner
* @{
*/
/**
* Allowed types for scanner_info_t structures.
*/
typedef enum
{
SCANNER_TYPE_END, /**< mark the last info block */
SCANNER_TYPE_END_ARGUMENTS, /**< mark the end of function arguments
* (only present if a function script is parsed) */
SCANNER_TYPE_FUNCTION, /**< declarations in a function */
SCANNER_TYPE_BLOCK, /**< declarations in a code block (usually enclosed in {}) */
SCANNER_TYPE_WHILE, /**< while statement */
SCANNER_TYPE_FOR, /**< for statement */
SCANNER_TYPE_FOR_IN, /**< for-in statement */
#if ENABLED (JERRY_ES2015)
SCANNER_TYPE_FOR_OF, /**< for-of statement */
#endif /* ENABLED (JERRY_ES2015) */
SCANNER_TYPE_SWITCH, /**< switch statement */
SCANNER_TYPE_CASE, /**< case statement */
#if ENABLED (JERRY_ES2015)
SCANNER_TYPE_INITIALIZER, /**< destructuring binding or assignment pattern with initializer */
SCANNER_TYPE_ERR_REDECLARED, /**< syntax error: a variable is redeclared */
#endif /* ENABLED (JERRY_ES2015) */
} scanner_info_type_t;
/**
* Source code location which can be used to change the position of parsing.
*/
typedef struct
{
const uint8_t *source_p; /**< next source byte */
parser_line_counter_t line; /**< token start line */
parser_line_counter_t column; /**< token start column */
} scanner_location_t;
/**
* Scanner info blocks which provides information for the parser.
*/
typedef struct scanner_info_t
{
struct scanner_info_t *next_p; /**< next info structure */
const uint8_t *source_p; /**< triggering position of this scanner info */
uint8_t type; /**< type of the scanner info */
uint8_t u8_arg; /**< custom 8-bit value */
uint16_t u16_arg; /**< custom 16-bit value */
} scanner_info_t;
/**
* Scanner info extended with a location.
*/
typedef struct
{
scanner_info_t info; /**< header */
scanner_location_t location; /**< location */
} scanner_location_info_t;
/**
* Scanner info for "for" statements.
*/
typedef struct
{
scanner_info_t info; /**< header */
scanner_location_t expression_location; /**< location of expression start */
scanner_location_t end_location; /**< location of expression end */
} scanner_for_info_t;
/**
* Case statement list for scanner_switch_info_t structure.
*/
typedef struct scanner_case_info_t
{
struct scanner_case_info_t *next_p; /**< next case statement info */
scanner_location_t location; /**< location of case statement */
} scanner_case_info_t;
/**
* Scanner info for "switch" statements.
*/
typedef struct
{
scanner_info_t info; /**< header */
scanner_case_info_t *case_p; /**< list of switch cases */
} scanner_switch_info_t;
/*
* Description of compressed streams.
*
* The stream is a sequence of commands which encoded as bytes. The first byte
* contains the type of the command (see scanner_function_compressed_stream_types_t).
*
* The variable declaration commands has two arguments:
* - The first represents the length of the declared identifier
* - The second contains the relative distance from the end of the previous declaration
* Usually the distance is between 1 and 255, and represented as a single byte
* Distances between -256 and 65535 are encoded as two bytes
* Larger distances are encoded as pointers
*/
/**
* Constants for compressed streams.
*/
typedef enum
{
SCANNER_STREAM_UINT16_DIFF = (1 << 7), /**< relative distance is between -256 and 65535 */
SCANNER_STREAM_HAS_ESCAPE = (1 << 6), /**< literal has escape */
SCANNER_STREAM_NO_REG = (1 << 5), /**< identifier cannot be stored in register */
/* Update SCANNER_STREAM_TYPE_MASK macro if more bits are added. */
} scanner_compressed_stream_flags_t;
/**
* Types for compressed streams.
*/
typedef enum
{
SCANNER_STREAM_TYPE_END, /**< end of scanner data */
SCANNER_STREAM_TYPE_HOLE, /**< no name is assigned to this argument */
SCANNER_STREAM_TYPE_VAR, /**< var declaration */
#if ENABLED (JERRY_ES2015)
SCANNER_STREAM_TYPE_LET, /**< let declaration */
SCANNER_STREAM_TYPE_CONST, /**< const declaration */
#endif /* ENABLED (JERRY_ES2015) */
#if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
SCANNER_STREAM_TYPE_IMPORT, /**< module import */
#endif /* ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
SCANNER_STREAM_TYPE_ARG, /**< argument declaration */
/* Function types should be at the end. See the SCANNER_STREAM_TYPE_IS_FUNCTION macro. */
SCANNER_STREAM_TYPE_ARG_FUNC, /**< argument declaration which is later initialized with a function */
SCANNER_STREAM_TYPE_FUNC, /**< local or global function declaration */
#if ENABLED (JERRY_ES2015)
SCANNER_STREAM_TYPE_FUNC_LOCAL, /**< always local function declaration */
#endif /* ENABLED (JERRY_ES2015) */
} scanner_compressed_stream_types_t;
/**
* Mask for decoding the type from the compressed stream.
*/
#define SCANNER_STREAM_TYPE_MASK 0xf
/**
* Mask for decoding the type from the compressed stream.
*/
#define SCANNER_STREAM_TYPE_IS_FUNCTION(type) ((type) >= SCANNER_STREAM_TYPE_ARG_FUNC)
/**
* Constants for u8_arg flags in scanner_function_info_t.
*/
typedef enum
{
SCANNER_FUNCTION_ARGUMENTS_NEEDED = (1 << 0), /**< arguments object needs to be created */
} scanner_function_flags_t;
/**
* Option bits for scanner_create_variables function.
*/
typedef enum
{
SCANNER_CREATE_VARS_NO_OPTS = 0, /**< no options */
SCANNER_CREATE_VARS_IS_EVAL = (1 << 0), /**< create variables for script / direct eval */
SCANNER_CREATE_VARS_IS_FUNCTION_ARGS = (1 << 1), /**< create variables for function arguments */
SCANNER_CREATE_VARS_IS_FUNCTION_BODY = (1 << 2), /**< create variables for function body */
} scanner_create_variables_flags_t;
/**
* @}
* @}
* @}
*/
#endif /* !JS_SCANNER_H */