|
15 | 15 | */
|
16 | 16 |
|
17 | 17 | #include "ecma-helpers.h"
|
| 18 | +#include "ecma-exceptions.h" |
18 | 19 | #include "jrt-libc-includes.h"
|
19 | 20 | #include "jsp-mm.h"
|
20 | 21 | #include "lexer.h"
|
| 22 | +#include "mem-allocator.h" |
| 23 | +#include "opcodes.h" |
| 24 | +#include "parser.h" |
| 25 | +#include "stack.h" |
21 | 26 | #include "syntax-errors.h"
|
22 | 27 |
|
23 | 28 | static token saved_token, prev_token, sent_token, empty_token;
|
@@ -961,6 +966,76 @@ parse_string (void)
|
961 | 966 | return ret;
|
962 | 967 | } /* parse_string */
|
963 | 968 |
|
| 969 | +/** |
| 970 | + * Parse string literal (ECMA-262 v5, 7.8.5) |
| 971 | + */ |
| 972 | +static token |
| 973 | +parse_regexp (void) |
| 974 | +{ |
| 975 | + token result; |
| 976 | + bool is_char_class = false; |
| 977 | + |
| 978 | + /* Eat up '/' */ |
| 979 | + JERRY_ASSERT ((ecma_char_t) LA (0) == '/'); |
| 980 | + consume_char (); |
| 981 | + new_token (); |
| 982 | + |
| 983 | + while (true) |
| 984 | + { |
| 985 | + ecma_char_t c = (ecma_char_t) LA (0); |
| 986 | + |
| 987 | + if (c == '\0') |
| 988 | + { |
| 989 | + PARSE_ERROR ("Unclosed string", token_start - buffer_start); |
| 990 | + } |
| 991 | + else if (c == '\n') |
| 992 | + { |
| 993 | + PARSE_ERROR ("RegExp literal shall not contain newline character", token_start - buffer_start); |
| 994 | + } |
| 995 | + else if (c == '\\') |
| 996 | + { |
| 997 | + consume_char (); |
| 998 | + } |
| 999 | + else if (c == '[') |
| 1000 | + { |
| 1001 | + is_char_class = true; |
| 1002 | + } |
| 1003 | + else if (c == ']') |
| 1004 | + { |
| 1005 | + is_char_class = false; |
| 1006 | + } |
| 1007 | + else if (c == '/' && !is_char_class) |
| 1008 | + { |
| 1009 | + /* Eat up '/' */ |
| 1010 | + consume_char (); |
| 1011 | + break; |
| 1012 | + } |
| 1013 | + |
| 1014 | + consume_char (); |
| 1015 | + } |
| 1016 | + |
| 1017 | + /* Try to parse RegExp flags */ |
| 1018 | + while (true) |
| 1019 | + { |
| 1020 | + ecma_char_t c = (ecma_char_t) LA (0); |
| 1021 | + |
| 1022 | + if (c == '\0' |
| 1023 | + || !ecma_char_is_word_char (c) |
| 1024 | + || ecma_char_is_line_terminator (c)) |
| 1025 | + { |
| 1026 | + break; |
| 1027 | + } |
| 1028 | + consume_char (); |
| 1029 | + } |
| 1030 | + |
| 1031 | + result = convert_string_to_token (TOK_REGEXP, |
| 1032 | + (const ecma_char_t*) token_start, |
| 1033 | + static_cast<ecma_length_t> (buffer - token_start)); |
| 1034 | + |
| 1035 | + token_start = NULL; |
| 1036 | + return result; |
| 1037 | +} /* parse_regexp */ |
| 1038 | + |
964 | 1039 | static void
|
965 | 1040 | grobble_whitespaces (void)
|
966 | 1041 | {
|
@@ -1084,10 +1159,27 @@ lexer_next_token_private (void)
|
1084 | 1159 | }
|
1085 | 1160 | }
|
1086 | 1161 |
|
1087 |
| - if (c == '/' && LA (1) == '/') |
| 1162 | + |
| 1163 | + if (c == '/') |
1088 | 1164 | {
|
1089 |
| - replace_comment_by_newline (); |
1090 |
| - return lexer_next_token_private (); |
| 1165 | + if (LA (1) == '/') |
| 1166 | + { |
| 1167 | + replace_comment_by_newline (); |
| 1168 | + return lexer_next_token_private (); |
| 1169 | + } |
| 1170 | + else if (!(sent_token.type == TOK_NAME |
| 1171 | + || sent_token.type == TOK_NULL |
| 1172 | + || sent_token.type == TOK_BOOL |
| 1173 | + || sent_token.type == TOK_CLOSE_BRACE |
| 1174 | + || sent_token.type == TOK_CLOSE_SQUARE |
| 1175 | + || sent_token.type == TOK_CLOSE_PAREN |
| 1176 | + || sent_token.type == TOK_SMALL_INT |
| 1177 | + || sent_token.type == TOK_NUMBER |
| 1178 | + || sent_token.type == TOK_STRING |
| 1179 | + || sent_token.type == TOK_REGEXP)) |
| 1180 | + { |
| 1181 | + return parse_regexp (); |
| 1182 | + } |
1091 | 1183 | }
|
1092 | 1184 |
|
1093 | 1185 | switch (c)
|
@@ -1203,7 +1295,6 @@ lexer_next_token (void)
|
1203 | 1295 |
|
1204 | 1296 | prev_token = sent_token;
|
1205 | 1297 | sent_token = lexer_next_token_private ();
|
1206 |
| - |
1207 | 1298 | if (sent_token.type == TOK_NEWLINE)
|
1208 | 1299 | {
|
1209 | 1300 | dump_current_line ();
|
|
0 commit comments