/** * Skip any whitespace and comment tokens * * @return true - if a newline token was skipped, * false - otherwise */ static bool lexer_skip_whitespace_and_comments (void) { bool new_lines_occurred = false; while (true) { ecma_char_t c = LA (0); if (lit_char_is_white_space (c)) { do { consume_char (); c = LA (0); } while (lit_char_is_white_space (c)); } else if (lit_char_is_line_terminator (c)) { dump_current_line (); new_lines_occurred = true; do { consume_char (); c = LA (0); } while (lit_char_is_line_terminator (c)); } else if (c == LIT_CHAR_SLASH && (LA (1) == LIT_CHAR_SLASH || LA (1) == LIT_CHAR_ASTERISK)) { /* ECMA-262 v5, 7.4, SingleLineComment or MultiLineComment */ if (lexer_parse_comment ()) { new_lines_occurred = true; } } else { break; } } return new_lines_occurred; } /* lexer_skip_whitespace_and_comments */
/** * The String.prototype object's 'trim' routine * * See also: * ECMA-262 v5, 15.5.4.20 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_string_prototype_object_trim (ecma_value_t this_arg) /**< this argument */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); /* 1 */ ECMA_TRY_CATCH (check_coercible_val, ecma_op_check_object_coercible (this_arg), ret_value); /* 2 */ ECMA_TRY_CATCH (to_string_val, ecma_op_to_string (this_arg), ret_value); ecma_string_t *original_string_p = ecma_get_string_from_value (to_string_val); /* 3 */ const lit_utf8_size_t size = ecma_string_get_size (original_string_p); const ecma_length_t length = ecma_string_get_size (original_string_p); /* Workaround: avoid repeated call of ecma_string_get_char_at_pos() because its overhead */ lit_utf8_byte_t *original_utf8_str_p = (lit_utf8_byte_t *) mem_heap_alloc_block (size + 1, MEM_HEAP_ALLOC_SHORT_TERM); ecma_string_to_utf8_string (original_string_p, original_utf8_str_p, (ssize_t) size); uint32_t prefix = 0, postfix = 0; uint32_t new_len = 0; while (prefix < length) { ecma_char_t next_char = lit_utf8_string_code_unit_at (original_utf8_str_p, size, prefix); if (lit_char_is_white_space (next_char) || lit_char_is_line_terminator (next_char)) { prefix++; } else { break; } } while (postfix < length - prefix) { ecma_char_t next_char = lit_utf8_string_code_unit_at (original_utf8_str_p, size, length - postfix - 1); if (lit_char_is_white_space (next_char) || lit_char_is_line_terminator (next_char)) { postfix++; } else { break; } } new_len = prefix < size ? size - prefix - postfix : 0; ecma_string_t *new_str_p = ecma_string_substr (original_string_p, prefix, prefix + new_len); /* 4 */ ret_value = ecma_make_normal_completion_value (ecma_make_string_value (new_str_p)); mem_heap_free_block (original_utf8_str_p); ECMA_FINALIZE (to_string_val); ECMA_FINALIZE (check_coercible_val); return ret_value; } /* ecma_builtin_string_prototype_object_trim */
/** * Parse and construct lexer token * * Note: * Currently, lexer token doesn't fully correspond to Token, defined in ECMA-262, v5, 7.5. * For example, there is no new-line token type in the token definition of ECMA-262 v5. * * @return constructed token */ static token lexer_parse_token (void) { ecma_char_t c = LA (0); if (lit_char_is_white_space (c)) { while (lit_char_is_white_space (c)) { consume_char (); c = LA (0); } } if (lit_char_is_line_terminator (c)) { while (lit_char_is_line_terminator (c)) { consume_char (); c = LA (0); } return create_token (TOK_NEWLINE, 0); } JERRY_ASSERT (is_token_parse_in_progress == false); /* ECMA-262 v5, 7.6, Identifier */ if (lexer_is_char_can_be_identifier_start (c)) { return lexer_parse_identifier_or_keyword (); } /* ECMA-262 v5, 7.8.3, Numeric literal */ if (lit_char_is_decimal_digit (c) || (c == LIT_CHAR_DOT && lit_char_is_decimal_digit (LA (1)))) { return lexer_parse_number (); } if (c == LIT_CHAR_LF) { consume_char (); return create_token (TOK_NEWLINE, 0); } if (c == LIT_CHAR_NULL) { return create_token (TOK_EOF, 0); } if (c == LIT_CHAR_SINGLE_QUOTE || c == LIT_CHAR_DOUBLE_QUOTE) { return lexer_parse_string (); } /* ECMA-262 v5, 7.4, SingleLineComment or MultiLineComment */ if (c == LIT_CHAR_SLASH && (LA (1) == LIT_CHAR_SLASH || LA (1) == LIT_CHAR_ASTERISK)) { if (lexer_parse_comment ()) { return create_token (TOK_NEWLINE, 0); } else { return lexer_parse_token (); } } if (c == LIT_CHAR_SLASH && !(prev_non_lf_token.type == TOK_NAME || prev_non_lf_token.type == TOK_NULL || prev_non_lf_token.type == TOK_BOOL || prev_non_lf_token.type == TOK_CLOSE_BRACE || prev_non_lf_token.type == TOK_CLOSE_SQUARE || prev_non_lf_token.type == TOK_CLOSE_PAREN || prev_non_lf_token.type == TOK_SMALL_INT || prev_non_lf_token.type == TOK_NUMBER || prev_non_lf_token.type == TOK_STRING || prev_non_lf_token.type == TOK_REGEXP)) { return lexer_parse_regexp (); } /* ECMA-262 v5, 7.7, Punctuator */ switch (c) { case LIT_CHAR_LEFT_BRACE: { RETURN_PUNC (TOK_OPEN_BRACE); break; } case LIT_CHAR_RIGHT_BRACE: { RETURN_PUNC (TOK_CLOSE_BRACE); break; } case LIT_CHAR_LEFT_PAREN: { RETURN_PUNC (TOK_OPEN_PAREN); break; } case LIT_CHAR_RIGHT_PAREN: { RETURN_PUNC (TOK_CLOSE_PAREN); break; } case LIT_CHAR_LEFT_SQUARE: { RETURN_PUNC (TOK_OPEN_SQUARE); break; } case LIT_CHAR_RIGHT_SQUARE: { RETURN_PUNC (TOK_CLOSE_SQUARE); break; } case LIT_CHAR_DOT: { RETURN_PUNC (TOK_DOT); break; } case LIT_CHAR_SEMICOLON: { RETURN_PUNC (TOK_SEMICOLON); break; } case LIT_CHAR_COMMA: { RETURN_PUNC (TOK_COMMA); break; } case LIT_CHAR_TILDE: { RETURN_PUNC (TOK_COMPL); break; } case LIT_CHAR_COLON: { RETURN_PUNC (TOK_COLON); break; } case LIT_CHAR_QUESTION: { RETURN_PUNC (TOK_QUERY); break; } case LIT_CHAR_ASTERISK: { IF_LA_IS (LIT_CHAR_EQUALS, TOK_MULT_EQ, TOK_MULT); break; } case LIT_CHAR_SLASH: { IF_LA_IS (LIT_CHAR_EQUALS, TOK_DIV_EQ, TOK_DIV); break; } case LIT_CHAR_CIRCUMFLEX: { IF_LA_IS (LIT_CHAR_EQUALS, TOK_XOR_EQ, TOK_XOR); break; } case LIT_CHAR_PERCENT: { IF_LA_IS (LIT_CHAR_EQUALS, TOK_MOD_EQ, TOK_MOD); break; } case LIT_CHAR_PLUS: { IF_LA_IS_OR (LIT_CHAR_PLUS, TOK_DOUBLE_PLUS, LIT_CHAR_EQUALS, TOK_PLUS_EQ, TOK_PLUS); break; } case LIT_CHAR_MINUS: { IF_LA_IS_OR (LIT_CHAR_MINUS, TOK_DOUBLE_MINUS, LIT_CHAR_EQUALS, TOK_MINUS_EQ, TOK_MINUS); break; } case LIT_CHAR_AMPERSAND: { IF_LA_IS_OR (LIT_CHAR_AMPERSAND, TOK_DOUBLE_AND, LIT_CHAR_EQUALS, TOK_AND_EQ, TOK_AND); break; } case LIT_CHAR_VLINE: { IF_LA_IS_OR (LIT_CHAR_VLINE, TOK_DOUBLE_OR, LIT_CHAR_EQUALS, TOK_OR_EQ, TOK_OR); break; } case LIT_CHAR_LESS_THAN: { switch (LA (1)) { case LIT_CHAR_LESS_THAN: IF_LA_N_IS (LIT_CHAR_EQUALS, TOK_LSHIFT_EQ, TOK_LSHIFT, 2); break; case LIT_CHAR_EQUALS: RETURN_PUNC_EX (TOK_LESS_EQ, 2); break; default: RETURN_PUNC (TOK_LESS); } break; } case LIT_CHAR_GREATER_THAN: { switch (LA (1)) { case LIT_CHAR_GREATER_THAN: { switch (LA (2)) { case LIT_CHAR_GREATER_THAN: IF_LA_N_IS (LIT_CHAR_EQUALS, TOK_RSHIFT_EX_EQ, TOK_RSHIFT_EX, 3); break; case LIT_CHAR_EQUALS: RETURN_PUNC_EX (TOK_RSHIFT_EQ, 3); break; default: RETURN_PUNC_EX (TOK_RSHIFT, 2); } break; } case LIT_CHAR_EQUALS: RETURN_PUNC_EX (TOK_GREATER_EQ, 2); break; default: RETURN_PUNC (TOK_GREATER); } break; } case LIT_CHAR_EQUALS: { if (LA (1) == LIT_CHAR_EQUALS) { IF_LA_N_IS (LIT_CHAR_EQUALS, TOK_TRIPLE_EQ, TOK_DOUBLE_EQ, 2); } else { RETURN_PUNC (TOK_EQ); } break; } case LIT_CHAR_EXCLAMATION: { if (LA (1) == LIT_CHAR_EQUALS) { IF_LA_N_IS (LIT_CHAR_EQUALS, TOK_NOT_DOUBLE_EQ, TOK_NOT_EQ, 2); } else { RETURN_PUNC (TOK_NOT); } break; } } PARSE_ERROR (JSP_EARLY_ERROR_SYNTAX, "Illegal character", lit_utf8_iterator_get_pos (&src_iter)); } /* lexer_parse_token */
/** * Trim leading and trailing whitespace characters from string. * * @return trimmed ecma string */ ecma_string_t * ecma_string_trim (const ecma_string_t *string_p) /**< pointer to an ecma string */ { ecma_string_t *ret_string_p; ECMA_STRING_TO_UTF8_STRING (string_p, utf8_str_p, utf8_str_size); if (utf8_str_size > 0) { ecma_char_t ch; lit_utf8_size_t read_size; const lit_utf8_byte_t *nonws_start_p = utf8_str_p + utf8_str_size; const lit_utf8_byte_t *current_p = utf8_str_p; /* Trim front. */ while (current_p < nonws_start_p) { read_size = lit_read_code_unit_from_utf8 (current_p, &ch); if (!lit_char_is_white_space (ch) && !lit_char_is_line_terminator (ch)) { nonws_start_p = current_p; break; } current_p += read_size; } current_p = utf8_str_p + utf8_str_size; /* Trim back. */ while (current_p > utf8_str_p) { read_size = lit_read_prev_code_unit_from_utf8 (current_p, &ch); if (!lit_char_is_white_space (ch) && !lit_char_is_line_terminator (ch)) { break; } current_p -= read_size; } /* Construct new string. */ if (current_p > nonws_start_p) { ret_string_p = ecma_new_ecma_string_from_utf8 (nonws_start_p, (lit_utf8_size_t) (current_p - nonws_start_p)); } else { ret_string_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY); } } else { ret_string_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY); } ECMA_FINALIZE_UTF8_STRING (utf8_str_p, utf8_str_size); return ret_string_p; } /* ecma_string_trim */