MIRROR: javascript for 馃悳's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 2257 lines 61 kB view raw
1#include "silver/ast.h" 2#include "silver/lexer.h" 3#include "silver/directives.h" 4 5#include "escape.h" 6#include "debug.h" 7#include "errors.h" 8#include "internal.h" 9#include "tokens.h" 10 11#include <runtime.h> 12#include <stdio.h> 13#include <stdlib.h> 14#include <string.h> 15 16sv_ast_t *sv_ast_new(sv_node_type_t type) { 17 sv_ast_t *n = parse_arena_bump(sizeof(sv_ast_t)); 18 if (!n) return NULL; 19 memset(n, 0, sizeof(sv_ast_t)); 20 n->type = type; 21 return n; 22} 23 24void sv_ast_list_push(sv_ast_list_t *list, sv_ast_t *node) { 25 if (list->count >= list->cap) { 26 int new_cap = list->cap ? list->cap * 2 : 4; 27 sv_ast_t **new_items = parse_arena_bump((size_t)new_cap * sizeof(sv_ast_t *)); 28 if (!new_items) return; 29 if (list->items) 30 memcpy(new_items, list->items, (size_t)list->count * sizeof(sv_ast_t *)); 31 list->items = new_items; 32 list->cap = new_cap; 33 } 34 list->items[list->count++] = node; 35} 36 37bool sv_ast_can_be_expression_statement(const sv_ast_t *node) { 38 if (!node) return false; 39 if ((node->type == N_FUNC || node->type == N_CLASS) && (node->flags & FN_PAREN)) return true; 40 41 static const uint8_t expr_stmt_nodes[N__COUNT] = { 42 [N_NUMBER] = 1, [N_STRING] = 1, [N_BIGINT] = 1, [N_BOOL] = 1, 43 [N_NULL] = 1, [N_UNDEF] = 1, [N_THIS] = 1, [N_GLOBAL_THIS] = 1, 44 [N_TEMPLATE] = 1, [N_REGEXP] = 1, [N_IDENT] = 1, [N_BINARY] = 1, 45 [N_UNARY] = 1, [N_UPDATE] = 1, [N_ASSIGN] = 1, [N_TERNARY] = 1, 46 [N_CALL] = 1, [N_NEW] = 1, [N_MEMBER] = 1, [N_OPTIONAL] = 1, 47 [N_ARRAY] = 1, [N_OBJECT] = 1, [N_PROPERTY] = 1, [N_SPREAD] = 1, 48 [N_SEQUENCE] = 1, [N_ARROW] = 1, [N_YIELD] = 1, [N_AWAIT] = 1, 49 [N_TYPEOF] = 1, [N_DELETE] = 1, [N_VOID] = 1, [N_TAGGED_TEMPLATE] = 1, 50 [N_IMPORT] = 1, 51 }; 52 53 if (node->type == N_FUNC) 54 return !(node->str && !(node->flags & FN_ARROW)); 55 if ((unsigned)node->type >= N__COUNT) return false; 56 return expr_stmt_nodes[node->type] != 0; 57} 58 59typedef struct { 60 ant_t *js; 61 sv_lexer_t lx; 62 bool no_in; 63} sv_parser_t; 64 65#define P sv_parser_t *p 66#define JS p->js 67#define TOK p->lx.st.tok 68#define TOFF p->lx.st.toff 69#define TLEN p->lx.st.tlen 70#define TVAL p->lx.st.tval 71#define POS p->lx.st.pos 72#define CONSUMED p->lx.st.consumed 73#define HAD_NEWLINE p->lx.st.had_newline 74#define CODE p->lx.code 75#define CLEN p->lx.clen 76#define CONSUME() ((void)(CONSUMED = 1)) 77#define NEXT() sv_lexer_next(&p->lx) 78#define LA() sv_lexer_lookahead(&p->lx) 79 80static bool lookahead_crosses_line_terminator(P) { 81 sv_lexer_state_t saved; 82 sv_lexer_save_state(&p->lx, &saved); 83 CONSUMED = 1; 84 (void)NEXT(); 85 bool had_newline = HAD_NEWLINE; 86 sv_lexer_restore_state(&p->lx, &saved); 87 return had_newline; 88} 89 90static sv_ast_t *parse_stmt(P); 91static sv_ast_t *parse_expr(P); 92static sv_ast_t *parse_paren_expr(P); 93static sv_ast_t *parse_assign(P); 94static sv_ast_t *parse_ternary(P); 95static sv_ast_t *parse_binary(P, int min_prec); 96static sv_ast_t *parse_unary(P); 97static sv_ast_t *parse_postfix(P); 98static sv_ast_t *parse_call(P); 99static sv_ast_t *parse_primary(P); 100static sv_ast_t *parse_block(P, bool directive_ctx); 101static sv_ast_t *parse_func(P); 102static sv_ast_t *parse_class(P); 103static sv_ast_t *parse_object(P); 104static sv_ast_t *parse_array(P); 105static sv_ast_t *parse_import_stmt(P); 106static sv_ast_t *parse_export_stmt(P); 107static sv_ast_t *parse_arrow_body(P); 108static sv_ast_t *parse_binding_pattern(P); 109 110#define SV_SYNC_ERR() ((void)sv_lexer_set_error_site(&p->lx)) 111#define SV_MKERR(...) (SV_SYNC_ERR(), js_mkerr(__VA_ARGS__)) 112#define SV_MKERR_TYPED(...) (SV_SYNC_ERR(), js_mkerr_typed(__VA_ARGS__)) 113 114static inline const char *tok_str(P) { 115 return &CODE[TOFF]; 116} 117 118static inline bool eat(P, uint8_t tok) { 119 NEXT(); 120 if (TOK == tok) { CONSUME(); return true; } 121 return false; 122} 123 124static inline void expect(P, uint8_t tok) { 125 NEXT(); 126 if (TOK == tok) CONSUME(); 127} 128 129static inline sv_ast_t *mk_plain(sv_node_type_t type) { 130 return sv_ast_new(type); 131} 132 133#define mk(type) ({ \ 134 sv_ast_t *_n = mk_plain(type); \ 135 _n->src_off = (uint32_t)TOFF; _n; \ 136}) 137 138static inline sv_ast_t *mk_num(double val) { 139 sv_ast_t *n = mk_plain(N_NUMBER); 140 n->num = val; 141 return n; 142} 143 144static inline sv_ast_t *mk_ident(const char *s, uint32_t len) { 145 sv_ast_t *n = mk_plain(N_IDENT); 146 n->str = s; 147 n->len = len; 148 return n; 149} 150 151static inline void sv_ast_set_string(sv_ast_t *n, sv_lex_string_t s) { 152 if (!n || !s.ok) return; 153 n->str = s.str; 154 n->len = s.len; 155} 156 157typedef struct { 158 const char *str; 159 uint32_t len; 160 bool ok; 161 bool valid_cooked; 162} sv_tpl_cooked_t; 163 164static inline const char *decode_ident_into_arena(const char *src, uint32_t len, uint32_t *out_len) { 165 if (!src || len == 0 || !memchr(src, '\\', len)) { 166 if (out_len) *out_len = len; 167 return src; 168 } 169 170 char *dst = parse_arena_bump((size_t)len + 1); 171 if (!dst) { 172 if (out_len) *out_len = len; 173 return src; 174 } 175 176 size_t di = 0; size_t i = 0; 177 const uint8_t *in = (const uint8_t *)src; 178 uint8_t *out = (uint8_t *)dst; 179 180 while (i < len) { 181 if (in[i] == '\\' && i + 1 < len && in[i + 1] == 'u') { 182 size_t adv = decode_escape(in, i, len, out, &di, 0); 183 if (adv > 0) { i += 2 + adv; continue; } 184 } 185 out[di++] = in[i++]; 186 } 187 188 out[di] = '\0'; 189 if (out_len) *out_len = (uint32_t)di; 190 return dst; 191} 192 193static inline bool is_contextual_ident_tok(uint8_t tok) { 194 return 195 tok == TOK_AS || 196 tok == TOK_FROM || 197 tok == TOK_OF || 198 tok == TOK_ASYNC || 199 tok == TOK_USING; 200} 201 202static inline const char *tok_ident_str(P, uint32_t *out_len) { 203 return decode_ident_into_arena(tok_str(p), (uint32_t)TLEN, out_len); 204} 205 206static inline bool is_ident_like_tok(uint8_t tok) { 207 return tok == TOK_IDENTIFIER || tok == TOK_DEFAULT || is_contextual_ident_tok(tok); 208} 209 210static inline bool is_private_ident_like_tok(uint8_t tok) { 211 return tok >= TOK_IDENTIFIER && tok < TOK_IDENT_LIKE_END; 212} 213 214static inline bool sv_strict_forbidden_binding_ident(const char *s, uint32_t len) { 215 return is_eval_or_arguments_name(s, len) || is_strict_reserved_name(s, len); 216} 217 218static inline bool sv_is_strict_restricted_assign_target(P, sv_ast_t *n) { 219 return p->lx.strict && n && n->type == N_IDENT && is_eval_or_arguments_name(n->str, n->len); 220} 221 222static inline sv_ast_t *mk_ident_from_tok(P) { 223 uint32_t len = 0; 224 const char *name = tok_ident_str(p, &len); 225 sv_ast_t *n = mk_ident(name, len); 226 n->src_off = (uint32_t)TOFF; 227 n->src_end = (uint32_t)(TOFF + TLEN); 228 return n; 229} 230 231static inline sv_ast_t *mk_private_ident_from_tok(P) { 232 sv_ast_t *n = mk(N_IDENT); 233 n->str = &CODE[TOFF - 1]; 234 n->len = (uint32_t)(TLEN + 1); 235 n->src_off = (uint32_t)(TOFF > 0 ? TOFF - 1 : TOFF); 236 n->src_end = (uint32_t)(TOFF + TLEN); 237 return n; 238} 239 240static inline void sv_strict_check_binding_ident(P, const char *s, uint32_t len) { 241 if (!p->lx.strict || !s || len == 0) return; 242 if (sv_strict_forbidden_binding_ident(s, len)) SV_MKERR_TYPED( 243 JS, JS_ERR_SYNTAX, "Invalid binding identifier '%.*s' in strict mode", 244 (int)len, s 245 ); 246} 247 248static inline void sv_parse_unexpected_token(P) { 249 size_t tok_len = 0; 250 251 if (TOFF < CLEN && TLEN > 0) { 252 ant_offset_t rem = CLEN - TOFF; 253 tok_len = (size_t)TLEN; 254 if ((ant_offset_t)tok_len > rem) tok_len = (size_t)rem; 255 } 256 257 if (tok_len == 0) { 258 SV_MKERR_TYPED(JS, JS_ERR_SYNTAX, "Unexpected token 'EOF'"); 259 return; 260 } 261 262 SV_MKERR_TYPED( 263 JS, JS_ERR_SYNTAX, 264 "Unexpected token '%.*s'", 265 (int)tok_len, &CODE[TOFF] 266 ); 267} 268 269static inline sv_ast_t *parse_dot_property_name(P) { 270 if (!is_private_ident_like_tok(TOK)) { 271 sv_parse_unexpected_token(p); 272 return NULL; 273 } 274 275 sv_ast_t *name = mk_ident_from_tok(p); 276 CONSUME(); 277 return name; 278} 279 280static sv_ast_t *parse_arrow_body(P) { 281 if (NEXT() == TOK_LBRACE) return parse_block(p, true); 282 return parse_assign(p); 283} 284 285static inline uint32_t node_src_end(P, sv_ast_t *node) { 286 if (node && node->src_end > node->src_off) return node->src_end; 287 return (uint32_t)(TOFF + TLEN); 288} 289 290static void sv_parse_stmt_list(P, sv_ast_list_t *out, bool stop_at_rbrace, bool directive_ctx) { 291 bool strict_mode = p->lx.strict; 292 bool saved_lexer_strict = p->lx.strict; 293 bool in_directive_prologue = directive_ctx; 294 p->lx.strict = strict_mode; 295 296 for (;;) { 297 NEXT(); 298 if (TOK == TOK_EOF) break; 299 if (stop_at_rbrace && TOK == TOK_RBRACE) break; 300 301 if (TOK == TOK_ERR) { 302 sv_parse_unexpected_token(p); 303 break; 304 } 305 306 sv_ast_t *stmt = parse_stmt(p); 307 if (stmt) sv_ast_list_push(out, stmt); 308 if (JS->thrown_exists) break; 309 if (!in_directive_prologue) continue; 310 if (!stmt || stmt->type == N_EMPTY) continue; 311 312 if (!sv_ast_can_be_expression_statement(stmt)) { 313 in_directive_prologue = false; 314 continue; 315 } 316 317 if (sv_ast_is_use_strict(JS, stmt)) { 318 strict_mode = true; 319 p->lx.strict = true; 320 continue; 321 } 322 in_directive_prologue = false; 323 } 324 p->lx.strict = saved_lexer_strict; 325} 326 327static sv_ast_t *parse_binding_pattern(P) { 328 NEXT(); 329 if (TOK == TOK_LBRACKET) return parse_array(p); 330 if (TOK == TOK_LBRACE) return parse_object(p); 331 if (is_ident_like_tok(TOK)) { 332 sv_ast_t *id = mk_ident_from_tok(p); 333 sv_strict_check_binding_ident(p, id->str, id->len); 334 CONSUME(); 335 return id; 336 } 337 CONSUME(); 338 return mk(N_EMPTY); 339} 340 341static void push_arrow_params_from_expr(sv_ast_t *fn, sv_ast_t *expr) { 342 if (!fn || !expr) return; 343 if (expr->type == N_SEQUENCE) { 344 push_arrow_params_from_expr(fn, expr->left); 345 push_arrow_params_from_expr(fn, expr->right); 346 return; 347 } 348 if (expr->type == N_ASSIGN && expr->op == TOK_ASSIGN) { 349 sv_ast_t *def = mk_plain(N_ASSIGN_PAT); 350 def->left = expr->left; 351 def->right = expr->right; 352 def->src_off = expr->src_off; 353 sv_ast_list_push(&fn->args, def); 354 return; 355 } 356 if (expr->type == N_SPREAD) { 357 sv_ast_t *rest = mk_plain(N_REST); 358 rest->right = expr->right; 359 rest->src_off = expr->src_off; 360 sv_ast_list_push(&fn->args, rest); 361 return; 362 } 363 sv_ast_list_push(&fn->args, expr); 364} 365 366static sv_tpl_cooked_t decode_template_segment(P, const uint8_t *in, size_t start, size_t end) { 367 sv_tpl_cooked_t outv = { .str = NULL, .len = 0, .ok = true, .valid_cooked = true }; 368 size_t raw_len = (end > start) ? (end - start) : 0; 369 if (raw_len == 0) { 370 outv.str = ""; 371 return outv; 372 } 373 374 uint8_t *out = parse_arena_bump(raw_len); 375 if (!out) { 376 (void)SV_MKERR(JS, "oom"); 377 outv.ok = false; 378 return outv; 379 } 380 381 size_t out_len = 0; 382 for (size_t i = start; i < end; i++) { 383 if (in[i] == '\r') { 384 out[out_len++] = '\n'; 385 if (i + 1 < end && in[i + 1] == '\n') i++; 386 continue; 387 } 388 if (in[i] != '\\' || i + 1 >= end) { 389 out[out_len++] = in[i]; 390 continue; 391 } 392 uint8_t c = in[i + 1]; 393 if (c >= '1' && c <= '9') { outv.valid_cooked = false; return outv; } 394 if (c == '0' && i + 2 < end && in[i + 2] >= '0' && in[i + 2] <= '9') { 395 outv.valid_cooked = false; return outv; 396 } 397 if (c == 'x' && !(i + 3 < end && is_xdigit(in[i + 2]) && is_xdigit(in[i + 3]))) { 398 outv.valid_cooked = false; return outv; 399 } 400 if (c == 'u') { 401 if (i + 2 < end && in[i + 2] == '{') { 402 uint32_t cp = 0; size_t j = i + 3; 403 while (j < end && is_xdigit(in[j])) { cp = (cp << 4) | unhex(in[j]); j++; } 404 if (!(j < end && in[j] == '}' && j > i + 3 && cp <= 0x10FFFF)) { 405 outv.valid_cooked = false; return outv; 406 } 407 } else if ( 408 !(i + 5 < end && is_xdigit(in[i + 2]) 409 && is_xdigit(in[i + 3]) 410 && is_xdigit(in[i + 4]) 411 && is_xdigit(in[i + 5]))) { outv.valid_cooked = false; return outv; } 412 } 413 i += 1 + decode_escape(in, i, end, out, &out_len, '`'); 414 } 415 416 outv.str = (const char *)out; 417 outv.len = (uint32_t)out_len; 418 return outv; 419} 420 421static sv_ast_t *try_parse_async_arrow(P) { 422 uint8_t la = LA(); 423 uint32_t async_off = (uint32_t)TOFF; 424 425 if (la == TOK_LPAREN) { 426 sv_lexer_state_t saved; 427 sv_lexer_save_state(&p->lx, &saved); 428 NEXT(); CONSUME(); 429 if (NEXT() == TOK_RPAREN) { 430 CONSUME(); 431 if (LA() == TOK_ARROW) { 432 NEXT(); CONSUME(); 433 sv_ast_t *fn = mk(N_FUNC); 434 fn->flags = FN_ARROW | FN_ASYNC; 435 fn->body = parse_arrow_body(p); 436 fn->src_off = async_off; 437 fn->src_end = node_src_end(p, fn->body); 438 return fn; 439 } 440 } 441 sv_lexer_restore_state(&p->lx, &saved); 442 NEXT(); CONSUME(); 443 sv_ast_t *expr = parse_paren_expr(p); 444 expect(p, TOK_RPAREN); 445 if (LA() == TOK_ARROW) { 446 NEXT(); CONSUME(); 447 sv_ast_t *fn = mk(N_FUNC); 448 fn->flags = FN_ARROW | FN_ASYNC; 449 push_arrow_params_from_expr(fn, expr); 450 fn->body = parse_arrow_body(p); 451 fn->src_off = async_off; 452 fn->src_end = node_src_end(p, fn->body); 453 return fn; 454 } 455 sv_lexer_restore_state(&p->lx, &saved); 456 return NULL; 457 } 458 459 if (la == TOK_IDENTIFIER) { 460 sv_lexer_state_t saved; 461 sv_lexer_save_state(&p->lx, &saved); 462 NEXT(); CONSUME(); 463 sv_ast_t *id = mk_ident_from_tok(p); 464 if (LA() == TOK_ARROW) { 465 NEXT(); CONSUME(); 466 sv_ast_t *fn = mk(N_FUNC); 467 fn->flags = FN_ARROW | FN_ASYNC; 468 sv_ast_list_push(&fn->args, id); 469 fn->body = parse_arrow_body(p); 470 fn->src_off = async_off; 471 fn->src_end = node_src_end(p, fn->body); 472 return fn; 473 } 474 sv_lexer_restore_state(&p->lx, &saved); 475 return NULL; 476 } 477 478 return NULL; 479} 480 481static sv_ast_t *parse_primary(P) { 482 NEXT(); 483 484 static const void *dispatch[TOK_MAX] = { 485 [TOK_NUMBER] = &&l_number, 486 [TOK_STRING] = &&l_string, 487 [TOK_BIGINT] = &&l_bigint, 488 [TOK_TRUE] = &&l_true, 489 [TOK_FALSE] = &&l_false, 490 [TOK_NULL] = &&l_null, 491 [TOK_UNDEF] = &&l_undef, 492 [TOK_THIS] = &&l_this, 493 [TOK_IDENTIFIER] = &&l_ident, 494 [TOK_AS] = &&l_ident, 495 [TOK_FROM] = &&l_ident, 496 [TOK_OF] = &&l_ident, 497 [TOK_USING] = &&l_ident, 498 [TOK_LPAREN] = &&l_paren, 499 [TOK_LBRACKET] = &&l_array, 500 [TOK_LBRACE] = &&l_object, 501 [TOK_FUNC] = &&l_func, 502 [TOK_CLASS] = &&l_class, 503 [TOK_ASYNC] = &&l_async, 504 [TOK_TEMPLATE] = &&l_template, 505 [TOK_NEW] = &&l_new, 506 [TOK_TYPEOF] = &&l_typeof, 507 [TOK_VOID] = &&l_void, 508 [TOK_DELETE] = &&l_delete, 509 [TOK_YIELD] = &&l_yield, 510 [TOK_AWAIT] = &&l_await, 511 [TOK_SUPER] = &&l_super, 512 [TOK_REST] = &&l_spread, 513 [TOK_IMPORT] = &&l_import_expr, 514 [TOK_DIV] = &&l_regex, 515 [TOK_DIV_ASSIGN] = &&l_regex, 516 [TOK_GLOBAL_THIS] = &&l_globalthis, 517 [TOK_WINDOW] = &&l_globalthis, 518 [TOK_HASH] = &&l_private_name, 519 }; 520 521 if (TOK < TOK_MAX && dispatch[TOK]) 522 goto *dispatch[TOK]; 523 524 sv_parse_unexpected_token(p); 525 return mk(N_EMPTY); 526 527 l_number: { 528 CONSUME(); 529 return mk_num(tod(TVAL)); 530 } 531 532 l_string: { 533 sv_ast_t *n = mk(N_STRING); 534 sv_ast_set_string(n, sv_lexer_str_literal(&p->lx)); 535 CONSUME(); 536 return n; 537 } 538 539 l_bigint: { 540 CONSUME(); 541 sv_ast_t *n = mk(N_BIGINT); 542 n->str = tok_str(p); 543 n->len = (uint32_t)TLEN; 544 return n; 545 } 546 547 l_true: { CONSUME(); sv_ast_t *n = mk(N_BOOL); n->num = 1; return n; } 548 l_false: { CONSUME(); sv_ast_t *n = mk(N_BOOL); n->num = 0; return n; } 549 l_null: { CONSUME(); return mk(N_NULL); } 550 l_undef: { CONSUME(); return mk(N_UNDEF); } 551 l_this: { CONSUME(); return mk(N_THIS); } 552 l_globalthis: { CONSUME(); return mk(N_GLOBAL_THIS); } 553 554 l_ident: { 555 CONSUME(); 556 return mk_ident_from_tok(p); 557 } 558 559 l_paren: { 560 uint32_t paren_off = (uint32_t)TOFF; 561 CONSUME(); 562 if (NEXT() == TOK_RPAREN) { 563 CONSUME(); 564 sv_ast_t *n = mk(N_UNDEF); 565 n->flags |= FN_PAREN; 566 n->src_off = paren_off; 567 return n; 568 } 569 sv_ast_t *expr = parse_paren_expr(p); 570 expect(p, TOK_RPAREN); 571 expr->flags |= FN_PAREN; 572 if (expr->type != N_FUNC && expr->type != N_CLASS) expr->src_off = paren_off; 573 return expr; 574 } 575 576 l_array: return parse_array(p); 577 l_object: return parse_object(p); 578 l_func: { CONSUME(); return parse_func(p); } 579 580 l_class: { 581 uint32_t class_off = (uint32_t)TOFF; 582 CONSUME(); 583 sv_ast_t *cls = parse_class(p); 584 cls->src_off = class_off; 585 return cls; 586 } 587 588 l_async: { 589 uint32_t async_off = (uint32_t)TOFF; 590 CONSUME(); 591 bool has_line_term = lookahead_crosses_line_terminator(p); 592 if (!has_line_term && LA() == TOK_FUNC) { 593 NEXT(); CONSUME(); 594 sv_ast_t *fn = parse_func(p); 595 fn->flags |= FN_ASYNC; 596 fn->src_off = async_off; 597 return fn; 598 } 599 if (has_line_term) return mk_ident_from_tok(p); 600 sv_ast_t *arrow = try_parse_async_arrow(p); 601 if (arrow) return arrow; 602 return mk_ident_from_tok(p); 603 } 604 605 l_template: { 606 CONSUME(); 607 sv_ast_t *n = mk(N_TEMPLATE); 608 const uint8_t *in = (const uint8_t *)&CODE[TOFF]; 609 size_t tpl_len = TLEN; 610 size_t i = 1; 611 612 for (;;) { 613 size_t seg_start = i; 614 while (i < tpl_len - 1) { 615 if (in[i] == '\\' && i + 1 < tpl_len - 1) { i += 2; continue; } 616 if (in[i] == '$' && i + 1 < tpl_len - 1 && in[i + 1] == '{') break; 617 i++; 618 } 619 sv_ast_t *s = mk(N_STRING); 620 s->flags |= FN_TEMPLATE_SEGMENT; 621 s->aux = (const char *)&in[seg_start]; 622 s->aux_len = (uint32_t)(i - seg_start); 623 sv_tpl_cooked_t cooked = decode_template_segment(p, in, seg_start, i); 624 if (cooked.ok && cooked.valid_cooked) { 625 s->str = cooked.str; 626 s->len = cooked.len; 627 } else if (cooked.ok) s->flags |= FN_INVALID_COOKED; 628 629 sv_ast_list_push(&n->args, s); 630 if (i >= tpl_len - 1 || in[i] != '$') break; 631 632 i += 2; 633 size_t expr_start = i; 634 size_t expr_max_len = ( 635 tpl_len > 0 && expr_start < tpl_len - 1) 636 ? (tpl_len - 1 - expr_start) : 0; 637 638 sv_lexer_checkpoint_t cp; 639 sv_lexer_push_source(&p->lx, &cp, (const char *)&in[expr_start], (ant_offset_t)expr_max_len); 640 641 sv_ast_t *expr = parse_expr(p); 642 sv_ast_list_push(&n->args, expr); 643 644 if (NEXT() != TOK_RBRACE) { 645 SV_MKERR_TYPED(JS, JS_ERR_SYNTAX, "Unterminated template expression"); 646 sv_lexer_pop_source(&p->lx, &cp); 647 return n; 648 } 649 CONSUME(); 650 651 size_t consumed_expr = (size_t)POS; 652 sv_lexer_pop_source(&p->lx, &cp); 653 654 if (consumed_expr == 0) { 655 SV_MKERR_TYPED(JS, JS_ERR_SYNTAX, "Unterminated template expression"); 656 return n; 657 } i = expr_start + consumed_expr; 658 } 659 return n; 660 } 661 662 l_new: { 663 CONSUME(); 664 665 if (NEXT() == TOK_DOT) { 666 CONSUME(); 667 if (NEXT() == TOK_IDENTIFIER && TLEN == 6 && memcmp(tok_str(p), "target", 6) == 0) { 668 CONSUME(); 669 return mk(N_NEW_TARGET); 670 } 671 sv_parse_unexpected_token(p); 672 return mk(N_EMPTY); 673 } 674 675 sv_ast_t *n = mk(N_NEW); 676 sv_ast_t *callee = parse_primary(p); 677 678 for (;;) { 679 uint8_t la = NEXT(); 680 if (la == TOK_DOT) { 681 CONSUME(); 682 NEXT(); 683 sv_ast_t *mem = mk(N_MEMBER); 684 mem->left = callee; 685 mem->right = parse_dot_property_name(p); 686 if (!mem->right) return mk(N_EMPTY); 687 callee = mem; 688 } else if (la == TOK_LBRACKET) { 689 CONSUME(); 690 sv_ast_t *mem = mk(N_MEMBER); 691 mem->left = callee; 692 mem->right = parse_expr(p); 693 mem->flags = 1; 694 expect(p, TOK_RBRACKET); 695 callee = mem; 696 } else break; 697 } 698 n->left = callee; 699 700 if (NEXT() == TOK_LPAREN) { 701 CONSUME(); 702 while (NEXT() != TOK_RPAREN && TOK != TOK_EOF) { 703 if (TOK == TOK_REST) { 704 CONSUME(); 705 sv_ast_t *spread = mk(N_SPREAD); 706 spread->right = parse_assign(p); 707 sv_ast_list_push(&n->args, spread); 708 } else sv_ast_list_push(&n->args, parse_assign(p)); 709 if (NEXT() == TOK_COMMA) CONSUME(); 710 else break; 711 } expect(p, TOK_RPAREN); 712 } 713 return n; 714 } 715 716 l_typeof: { 717 CONSUME(); 718 sv_ast_t *n = mk(N_TYPEOF); 719 n->right = parse_unary(p); 720 return n; 721 } 722 723 l_void: { 724 CONSUME(); 725 sv_ast_t *n = mk(N_VOID); 726 n->right = parse_unary(p); 727 return n; 728 } 729 730 l_delete: { 731 CONSUME(); 732 sv_ast_t *n = mk(N_DELETE); 733 n->right = parse_unary(p); 734 if (p->lx.strict && n->right && n->right->type == N_IDENT) { 735 SV_MKERR_TYPED(JS, JS_ERR_SYNTAX, "cannot delete bindings in strict mode"); 736 return mk(N_EMPTY); 737 } 738 return n; 739 } 740 741 l_yield: { 742 CONSUME(); 743 sv_ast_t *n = mk(N_YIELD); 744 if (NEXT() == TOK_MUL) { 745 CONSUME(); 746 n->flags = 1; 747 } 748 if (TOK != TOK_SEMICOLON && TOK != TOK_RBRACE && 749 TOK != TOK_RPAREN && TOK != TOK_RBRACKET && 750 TOK != TOK_EOF && TOK != TOK_COMMA) 751 n->right = parse_assign(p); 752 return n; 753 } 754 755 l_await: { 756 CONSUME(); 757 sv_ast_t *n = mk(N_AWAIT); 758 n->right = parse_unary(p); 759 return n; 760 } 761 762 l_super: { 763 CONSUME(); 764 return mk_ident("super", 5); 765 } 766 767 l_spread: { 768 CONSUME(); 769 sv_ast_t *n = mk(N_SPREAD); 770 n->right = parse_assign(p); 771 return n; 772 } 773 774 l_import_expr: { 775 CONSUME(); 776 if (NEXT() != TOK_LPAREN) return mk_ident("import", 6); 777 CONSUME(); 778 sv_ast_t *n = mk(N_IMPORT); 779 n->right = parse_expr(p); 780 expect(p, TOK_RPAREN); 781 return n; 782 } 783 784 l_regex: { 785 CONSUME(); 786 ant_offset_t pattern_start = (TOK == TOK_DIV_ASSIGN) ? (TOFF + 1) : POS; 787 if (TOK == TOK_DIV_ASSIGN) POS = pattern_start; 788 bool in_class = false; 789 790 while (POS < CLEN) { 791 char c = CODE[POS]; 792 if (c == '\\' && POS + 1 < CLEN) { 793 POS += 2; 794 continue; 795 } 796 if (c == '[') in_class = true; 797 else if (c == ']') in_class = false; 798 else if (c == '/' && !in_class) break; 799 POS++; 800 } 801 802 ant_offset_t pattern_end = POS; 803 if (POS < CLEN) POS++; 804 805 ant_offset_t flags_start = POS; 806 while (POS < CLEN) { 807 char c = CODE[POS]; 808 if ( 809 c == 'd' || c == 'g' || c == 'i' || c == 'm' || 810 c == 's' || c == 'u' || c == 'v' || c == 'y') POS++; 811 else break; 812 } 813 814 ant_offset_t flags_end = POS; 815 sv_ast_t *n = mk(N_REGEXP); 816 817 n->str = &CODE[pattern_start]; 818 n->len = (uint32_t)(pattern_end - pattern_start); 819 n->aux = &CODE[flags_start]; 820 n->aux_len = (uint32_t)(flags_end - flags_start); 821 CONSUMED = 1; 822 return n; 823 } 824 825 l_private_name: { 826 CONSUME(); 827 NEXT(); 828 if (!is_private_ident_like_tok(TOK)) { 829 SV_MKERR_TYPED(JS, JS_ERR_SYNTAX, "private field name expected"); 830 return mk(N_EMPTY); 831 } 832 sv_ast_t *n = mk_private_ident_from_tok(p); 833 CONSUME(); 834 return n; 835 } 836} 837 838static sv_ast_t *parse_array(P) { 839 CONSUME(); 840 sv_ast_t *n = mk(N_ARRAY); 841 while (NEXT() != TOK_RBRACKET && TOK != TOK_EOF) { 842 if (TOK == TOK_COMMA) { 843 CONSUME(); 844 sv_ast_list_push(&n->args, mk(N_EMPTY)); 845 continue; 846 } 847 if (TOK == TOK_REST) { 848 CONSUME(); 849 sv_ast_t *spread = mk(N_SPREAD); 850 spread->right = parse_assign(p); 851 sv_ast_list_push(&n->args, spread); 852 } else { 853 sv_ast_list_push(&n->args, parse_assign(p)); 854 } 855 if (NEXT() == TOK_COMMA) CONSUME(); 856 else break; 857 } 858 expect(p, TOK_RBRACKET); 859 return n; 860} 861 862static sv_ast_t *parse_object(P) { 863 CONSUME(); 864 sv_ast_t *n = mk(N_OBJECT); 865 bool proto_set = false; 866 while (NEXT() != TOK_RBRACE && TOK != TOK_EOF) { 867 sv_ast_t *prop = mk(N_PROPERTY); 868 869 if (TOK == TOK_REST) { 870 CONSUME(); 871 sv_ast_t *spread = mk(N_SPREAD); 872 spread->right = parse_assign(p); 873 sv_ast_list_push(&n->args, spread); 874 if (NEXT() == TOK_COMMA) CONSUME(); 875 continue; 876 } 877 878 if (TOK == TOK_LBRACKET) { 879 CONSUME(); 880 prop->left = parse_assign(p); 881 expect(p, TOK_RBRACKET); 882 prop->flags |= FN_COMPUTED; 883 } 884 else if (TOK == TOK_MUL) { 885 prop->flags |= FN_GENERATOR; 886 CONSUME(); 887 NEXT(); 888 889 if (TOK == TOK_LBRACKET) { 890 CONSUME(); 891 prop->left = parse_assign(p); 892 expect(p, TOK_RBRACKET); 893 prop->flags |= FN_COMPUTED; 894 } else if (TOK == TOK_NUMBER) { 895 CONSUME(); 896 prop->left = mk_num(tod(TVAL)); 897 } else if (TOK == TOK_STRING) { 898 prop->left = mk(N_STRING); 899 sv_ast_set_string(prop->left, sv_lexer_str_literal(&p->lx)); 900 CONSUME(); 901 } else { 902 prop->left = mk_ident_from_tok(p); 903 CONSUME(); 904 } 905 906 prop->right = parse_func(p); 907 prop->right->flags |= FN_GENERATOR | FN_METHOD; 908 prop->right->src_off = prop->src_off; 909 sv_ast_list_push(&n->args, prop); 910 if (NEXT() == TOK_COMMA) CONSUME(); 911 continue; 912 } 913 else if ( 914 (TLEN == 3 && memcmp(tok_str(p), "get", 3) == 0) || 915 (TLEN == 3 && memcmp(tok_str(p), "set", 3) == 0)) { 916 uint8_t gs = tok_str(p)[0]; 917 uint8_t la = LA(); 918 if (la != TOK_COLON && la != TOK_LPAREN && la != TOK_COMMA && 919 la != TOK_RBRACE) { 920 CONSUME(); 921 prop->flags |= (gs == 'g') ? FN_GETTER : FN_SETTER; 922 NEXT(); 923 924 if (TOK == TOK_LBRACKET) { 925 CONSUME(); 926 prop->left = parse_assign(p); 927 expect(p, TOK_RBRACKET); 928 prop->flags |= FN_COMPUTED; 929 } else if (TOK == TOK_NUMBER) { 930 CONSUME(); 931 prop->left = mk_num(tod(TVAL)); 932 } else if (TOK == TOK_STRING) { 933 prop->left = mk(N_STRING); 934 sv_ast_set_string(prop->left, sv_lexer_str_literal(&p->lx)); 935 CONSUME(); 936 } else { 937 prop->left = mk_ident_from_tok(p); 938 CONSUME(); 939 } 940 941 prop->right = parse_func(p); 942 prop->right->flags |= FN_METHOD; 943 prop->right->src_off = prop->src_off; 944 sv_ast_list_push(&n->args, prop); 945 if (NEXT() == TOK_COMMA) CONSUME(); 946 continue; 947 } 948 prop->left = mk_ident_from_tok(p); 949 CONSUME(); 950 } 951 else if (TOK == TOK_ASYNC) { 952 uint8_t la = LA(); 953 if (la != TOK_COLON && la != TOK_LPAREN && la != TOK_COMMA && la != TOK_RBRACE) { 954 CONSUME(); 955 prop->flags |= FN_ASYNC; 956 NEXT(); 957 958 if (TOK == TOK_MUL) { 959 prop->flags |= FN_GENERATOR; 960 CONSUME(); 961 NEXT(); 962 } 963 964 if (TOK == TOK_LBRACKET) { 965 CONSUME(); 966 prop->left = parse_assign(p); 967 expect(p, TOK_RBRACKET); 968 prop->flags |= FN_COMPUTED; 969 } else if (TOK == TOK_NUMBER) { 970 CONSUME(); 971 prop->left = mk_num(tod(TVAL)); 972 } else if (TOK == TOK_STRING) { 973 prop->left = mk(N_STRING); 974 sv_ast_set_string(prop->left, sv_lexer_str_literal(&p->lx)); 975 CONSUME(); 976 } else { 977 prop->left = mk_ident_from_tok(p); 978 CONSUME(); 979 } 980 981 prop->right = parse_func(p); 982 prop->right->flags |= FN_ASYNC | FN_METHOD; 983 if (prop->flags & FN_GENERATOR) 984 prop->right->flags |= FN_GENERATOR; 985 prop->right->src_off = prop->src_off; 986 sv_ast_list_push(&n->args, prop); 987 if (NEXT() == TOK_COMMA) CONSUME(); 988 continue; 989 } 990 prop->left = mk_ident_from_tok(p); 991 CONSUME(); 992 } 993 else if (TOK == TOK_NUMBER) { 994 CONSUME(); 995 prop->left = mk_num(tod(TVAL)); 996 } 997 else if (TOK == TOK_STRING) { 998 prop->left = mk(N_STRING); 999 sv_ast_set_string(prop->left, sv_lexer_str_literal(&p->lx)); 1000 CONSUME(); 1001 } 1002 else { 1003 prop->left = mk_ident_from_tok(p); 1004 CONSUME(); 1005 } 1006 1007 if (NEXT() == TOK_COLON) { 1008 CONSUME(); 1009 prop->flags |= FN_COLON; 1010 if (prop->left && prop->left->type == N_IDENT && 1011 prop->left->len == 9 && memcmp(prop->left->str, "__proto__", 9) == 0) { 1012 if (proto_set) { SV_MKERR_TYPED(JS, JS_ERR_SYNTAX, "Duplicate __proto__ fields are not allowed in object literals"); return n; } 1013 proto_set = true; 1014 } 1015 prop->right = parse_assign(p); 1016 } else if (TOK == TOK_LPAREN) { 1017 prop->right = parse_func(p); 1018 prop->right->flags |= FN_METHOD; 1019 prop->right->src_off = prop->src_off; 1020 } else { 1021 prop->right = mk_ident(prop->left->str, prop->left->len); 1022 if (NEXT() == TOK_ASSIGN) { 1023 CONSUME(); 1024 sv_ast_t *def = mk(N_ASSIGN); 1025 def->op = TOK_ASSIGN; 1026 def->left = prop->right; 1027 def->right = parse_assign(p); 1028 prop->right = def; 1029 } 1030 } 1031 1032 sv_ast_list_push(&n->args, prop); 1033 if (NEXT() == TOK_COMMA) CONSUME(); 1034 else break; 1035 } 1036 expect(p, TOK_RBRACE); 1037 return n; 1038} 1039 1040static sv_ast_t *parse_call(P) { 1041 sv_ast_t *n = parse_primary(p); 1042 1043 for (;;) { 1044 uint8_t la = NEXT(); 1045 if (la == TOK_LPAREN) { 1046 CONSUME(); 1047 sv_ast_t *call = mk(N_CALL); 1048 call->left = n; 1049 while (NEXT() != TOK_RPAREN && TOK != TOK_EOF) { 1050 if (TOK == TOK_REST) { 1051 CONSUME(); 1052 sv_ast_t *spread = mk(N_SPREAD); 1053 spread->right = parse_assign(p); 1054 sv_ast_list_push(&call->args, spread); 1055 } else { 1056 sv_ast_list_push(&call->args, parse_assign(p)); 1057 } 1058 if (NEXT() == TOK_COMMA) CONSUME(); 1059 else break; 1060 } 1061 expect(p, TOK_RPAREN); 1062 n = call; 1063 } else if (la == TOK_DOT) { 1064 CONSUME(); 1065 NEXT(); 1066 sv_ast_t *mem = mk(N_MEMBER); 1067 mem->left = n; 1068 if (TOK == TOK_HASH) { 1069 CONSUME(); 1070 NEXT(); 1071 if (!is_private_ident_like_tok(TOK)) { 1072 SV_MKERR_TYPED(JS, JS_ERR_SYNTAX, "private field name expected"); 1073 return mk(N_EMPTY); 1074 } 1075 mem->right = mk_private_ident_from_tok(p); 1076 CONSUME(); 1077 } else { 1078 mem->right = parse_dot_property_name(p); 1079 if (!mem->right) return mk(N_EMPTY); 1080 } 1081 n = mem; 1082 } else if (la == TOK_LBRACKET) { 1083 CONSUME(); 1084 sv_ast_t *mem = mk(N_MEMBER); 1085 mem->left = n; 1086 mem->right = parse_expr(p); 1087 mem->flags = 1; 1088 expect(p, TOK_RBRACKET); 1089 n = mem; 1090 } else if (la == TOK_OPTIONAL_CHAIN) { 1091 CONSUME(); 1092 sv_ast_t *opt = mk(N_OPTIONAL); 1093 opt->left = n; 1094 if (NEXT() == TOK_LBRACKET) { 1095 CONSUME(); 1096 opt->right = parse_expr(p); 1097 opt->flags = 1; 1098 expect(p, TOK_RBRACKET); 1099 } else if (TOK == TOK_LPAREN) { 1100 sv_ast_t *call = mk(N_CALL); 1101 call->left = opt; 1102 CONSUME(); 1103 while (NEXT() != TOK_RPAREN && TOK != TOK_EOF) { 1104 sv_ast_list_push(&call->args, parse_assign(p)); 1105 if (NEXT() == TOK_COMMA) CONSUME(); 1106 else break; 1107 } 1108 expect(p, TOK_RPAREN); 1109 n = call; 1110 continue; 1111 } else if (TOK == TOK_HASH) { 1112 CONSUME(); 1113 NEXT(); 1114 if (!is_private_ident_like_tok(TOK)) { 1115 SV_MKERR_TYPED(JS, JS_ERR_SYNTAX, "private field name expected"); 1116 return mk(N_EMPTY); 1117 } 1118 opt->right = mk_private_ident_from_tok(p); 1119 CONSUME(); 1120 } else { 1121 opt->right = parse_dot_property_name(p); 1122 if (!opt->right) return mk(N_EMPTY); 1123 } 1124 n = opt; 1125 } else if (la == TOK_TEMPLATE) { 1126 sv_ast_t *tagged = mk(N_TAGGED_TEMPLATE); 1127 tagged->left = n; 1128 tagged->right = parse_primary(p); 1129 n = tagged; 1130 } else break; 1131 } 1132 return n; 1133} 1134 1135static sv_ast_t *parse_postfix(P) { 1136 sv_ast_t *n = parse_call(p); 1137 uint8_t la = NEXT(); 1138 if ((la == TOK_POSTINC || la == TOK_POSTDEC) && !HAD_NEWLINE) { 1139 if (sv_is_strict_restricted_assign_target(p, n)) { 1140 SV_MKERR_TYPED( 1141 JS, JS_ERR_SYNTAX, 1142 "cannot modify eval or arguments in strict mode"); 1143 return mk(N_EMPTY); 1144 } 1145 CONSUME(); 1146 sv_ast_t *u = mk(N_UPDATE); 1147 u->op = la; 1148 u->right = n; 1149 return u; 1150 } 1151 return n; 1152} 1153 1154static sv_ast_t *parse_unary(P) { 1155 uint8_t la = NEXT(); 1156 if (la == TOK_NOT || la == TOK_TILDA || 1157 la == TOK_UPLUS || la == TOK_UMINUS || 1158 la == TOK_PLUS || la == TOK_MINUS) { 1159 CONSUME(); 1160 sv_ast_t *n = mk(N_UNARY); 1161 n->op = (la == TOK_PLUS) ? TOK_UPLUS : 1162 (la == TOK_MINUS) ? TOK_UMINUS : la; 1163 n->right = parse_unary(p); 1164 if (NEXT() == TOK_EXP) { 1165 SV_MKERR_TYPED( 1166 JS, JS_ERR_SYNTAX, 1167 "Unary operator used immediately before exponentiation expression. " 1168 "Parenthesis must be used to disambiguate operator precedence"); 1169 return mk(N_EMPTY); 1170 } 1171 return n; 1172 } 1173 if (la == TOK_POSTINC || la == TOK_POSTDEC) { 1174 CONSUME(); 1175 sv_ast_t *target = parse_unary(p); 1176 if (sv_is_strict_restricted_assign_target(p, target)) { 1177 SV_MKERR_TYPED( 1178 JS, JS_ERR_SYNTAX, 1179 "cannot modify eval or arguments in strict mode"); 1180 return mk(N_EMPTY); 1181 } 1182 sv_ast_t *n = mk(N_UPDATE); 1183 n->op = la; 1184 n->right = target; 1185 n->flags = 1; 1186 return n; 1187 } 1188 if (la == TOK_THROW) { 1189 CONSUME(); 1190 sv_ast_t *n = mk(N_THROW); 1191 n->right = parse_assign(p); 1192 return n; 1193 } 1194 return parse_postfix(p); 1195} 1196 1197static sv_ast_t *parse_binary(P, int min_prec) { 1198 sv_ast_t *left = parse_unary(p); 1199 1200 for (;;) { 1201 uint8_t op = NEXT(); 1202 if (op >= TOK_MAX) break; 1203 if (op == TOK_IN && p->no_in) break; 1204 int prec = prec_table[op]; 1205 if (prec == 0 || prec < min_prec) break; 1206 CONSUME(); 1207 int next_prec = (op == TOK_EXP) ? prec : prec + 1; 1208 sv_ast_t *right = parse_binary(p, next_prec); 1209 sv_ast_t *bin = mk(N_BINARY); 1210 bin->op = op; 1211 bin->left = left; 1212 bin->right = right; 1213 left = bin; 1214 } 1215 return left; 1216} 1217 1218static sv_ast_t *parse_ternary(P) { 1219 sv_ast_t *cond = parse_binary(p, 1); 1220 if (NEXT() == TOK_Q) { 1221 CONSUME(); 1222 sv_ast_t *n = mk(N_TERNARY); 1223 n->cond = cond; 1224 n->left = parse_assign(p); 1225 expect(p, TOK_COLON); 1226 n->right = parse_assign(p); 1227 return n; 1228 } 1229 return cond; 1230} 1231 1232static bool is_assign_op(uint8_t tok) { 1233 return tok >= TOK_ASSIGN && tok <= TOK_NULLISH_ASSIGN; 1234} 1235 1236static sv_ast_t *parse_assign(P) { 1237 sv_ast_t *left = parse_ternary(p); 1238 uint8_t op = NEXT(); 1239 if (op == TOK_ARROW) { 1240 CONSUME(); 1241 sv_ast_t *fn = mk(N_FUNC); 1242 fn->flags = FN_ARROW; 1243 fn->src_off = left->src_off; 1244 if (left->type == N_IDENT) { 1245 sv_ast_list_push(&fn->args, left); 1246 } else if (left->flags & FN_PAREN) { 1247 if (left->type != N_UNDEF) 1248 push_arrow_params_from_expr(fn, left); 1249 } else { 1250 SV_MKERR_TYPED(JS, JS_ERR_SYNTAX, "Malformed arrow function parameter list"); 1251 return mk(N_EMPTY); 1252 } 1253 fn->body = parse_arrow_body(p); 1254 fn->src_end = node_src_end(p, fn->body); 1255 return fn; 1256 } 1257 if (is_assign_op(op)) { 1258 if (left->type == N_NEW_TARGET) { 1259 SV_MKERR_TYPED(JS, JS_ERR_SYNTAX, "Invalid left-hand side in assignment"); 1260 return mk(N_EMPTY); 1261 } 1262 if ((left->flags & FN_PAREN) && op == TOK_ASSIGN && 1263 (left->type == N_OBJECT || left->type == N_OBJECT_PAT || 1264 left->type == N_ARRAY || left->type == N_ARRAY_PAT)) { 1265 SV_MKERR_TYPED( 1266 JS, JS_ERR_SYNTAX, 1267 "Invalid destructuring assignment target"); 1268 return mk(N_EMPTY); 1269 } 1270 if (sv_is_strict_restricted_assign_target(p, left)) { 1271 SV_MKERR_TYPED( 1272 JS, JS_ERR_SYNTAX, 1273 "cannot modify eval or arguments in strict mode"); 1274 return mk(N_EMPTY); 1275 } 1276 CONSUME(); 1277 sv_ast_t *n = mk(N_ASSIGN); 1278 n->op = op; 1279 n->left = left; 1280 n->right = parse_assign(p); 1281 return n; 1282 } 1283 return left; 1284} 1285 1286static sv_ast_t *parse_expr(P) { 1287 sv_ast_t *left = parse_assign(p); 1288 while (NEXT() == TOK_COMMA) { 1289 CONSUME(); 1290 sv_ast_t *n = mk(N_SEQUENCE); 1291 n->left = left; 1292 n->right = parse_assign(p); 1293 left = n; 1294 } 1295 return left; 1296} 1297 1298static sv_ast_t *parse_paren_expr(P) { 1299 sv_ast_t *left = parse_assign(p); 1300 while (NEXT() == TOK_COMMA) { 1301 CONSUME(); 1302 if (NEXT() == TOK_RPAREN && LA() == TOK_ARROW) break; 1303 1304 sv_ast_t *n = mk(N_SEQUENCE); 1305 n->left = left; 1306 n->right = parse_assign(p); 1307 left = n; 1308 } 1309 return left; 1310} 1311 1312bool ast_references_arguments(const sv_ast_t *node) { 1313 if (!node) return false; 1314 if (node->type == N_IDENT && node->len == 9 && memcmp(node->str, "arguments", 9) == 0) 1315 return true; 1316 1317 if (node->type == N_FUNC && !(node->flags & FN_ARROW)) { 1318 for (int i = 0; i < node->args.count; i++) 1319 if (ast_references_arguments(node->args.items[i])) return true; 1320 return false; 1321 } 1322 1323 if (ast_references_arguments(node->left)) return true; 1324 if (ast_references_arguments(node->right)) return true; 1325 if (ast_references_arguments(node->body)) return true; 1326 if (ast_references_arguments(node->catch_body)) return true; 1327 if (ast_references_arguments(node->finally_body)) return true; 1328 for (int i = 0; i < node->args.count; i++) 1329 if (ast_references_arguments(node->args.items[i])) return true; 1330 1331 return false; 1332} 1333 1334static bool ast_references_new_target(const sv_ast_t *node) { 1335 if (!node) return false; 1336 if (node->type == N_NEW_TARGET) return true; 1337 if (node->type == N_FUNC && !(node->flags & FN_ARROW)) return false; 1338 1339 if (ast_references_new_target(node->left)) return true; 1340 if (ast_references_new_target(node->right)) return true; 1341 if (ast_references_new_target(node->cond)) return true; 1342 if (ast_references_new_target(node->body)) return true; 1343 if (ast_references_new_target(node->catch_body)) return true; 1344 if (ast_references_new_target(node->finally_body)) return true; 1345 if (ast_references_new_target(node->catch_param)) return true; 1346 if (ast_references_new_target(node->init)) return true; 1347 if (ast_references_new_target(node->update)) return true; 1348 1349 for (int i = 0; i < node->args.count; i++) 1350 if (ast_references_new_target(node->args.items[i])) return true; 1351 1352 return false; 1353} 1354 1355static sv_ast_t *parse_func(P) { 1356 sv_ast_t *fn = mk(N_FUNC); 1357 1358 if (NEXT() == TOK_MUL) { 1359 CONSUME(); 1360 fn->flags |= FN_GENERATOR; 1361 } 1362 1363 if (is_ident_like_tok(NEXT())) { 1364 fn->str = tok_ident_str(p, &fn->len); 1365 sv_strict_check_binding_ident(p, fn->str, fn->len); 1366 CONSUME(); 1367 } 1368 1369 expect(p, TOK_LPAREN); 1370 while (NEXT() != TOK_RPAREN && TOK != TOK_EOF) { 1371 if (TOK == TOK_REST) { 1372 CONSUME(); 1373 sv_ast_t *rest = mk(N_REST); 1374 rest->right = parse_binding_pattern(p); 1375 sv_ast_list_push(&fn->args, rest); 1376 break; 1377 } 1378 sv_ast_t *param = parse_binding_pattern(p); 1379 if (NEXT() == TOK_ASSIGN) { 1380 CONSUME(); 1381 sv_ast_t *def = mk(N_ASSIGN_PAT); 1382 def->left = param; 1383 def->right = parse_assign(p); 1384 param = def; 1385 } 1386 sv_ast_list_push(&fn->args, param); 1387 if (NEXT() == TOK_COMMA) { 1388 CONSUME(); 1389 if (NEXT() == TOK_RPAREN) break; 1390 } else break; 1391 } 1392 expect(p, TOK_RPAREN); 1393 1394 fn->body = parse_block(p, true); 1395 fn->src_end = (uint32_t)(TOFF + TLEN); 1396 if (!(fn->flags & FN_ARROW) && ast_references_arguments(fn->body)) 1397 fn->flags |= FN_USES_ARGS; 1398 if (!(fn->flags & FN_ARROW) && ast_references_new_target(fn->body)) 1399 fn->flags |= FN_USES_NEW_TARGET; 1400 return fn; 1401} 1402 1403static sv_ast_t *parse_class(P) { 1404 sv_ast_t *cls = mk(N_CLASS); 1405 1406 if (is_ident_like_tok(NEXT()) && 1407 !(TLEN == 7 && memcmp(tok_str(p), "extends", 7) == 0)) { 1408 cls->str = tok_ident_str(p, &cls->len); 1409 CONSUME(); 1410 } 1411 1412 if (NEXT() == TOK_IDENTIFIER && TLEN == 7 && memcmp(tok_str(p), "extends", 7) == 0) { 1413 CONSUME(); 1414 cls->left = parse_assign(p); 1415 } 1416 1417 expect(p, TOK_LBRACE); 1418 while (NEXT() != TOK_RBRACE && TOK != TOK_EOF) { 1419 if (TOK == TOK_SEMICOLON) { CONSUME(); continue; } 1420 1421 uint8_t flags = 0; 1422 1423 if ( 1424 TOK == TOK_STATIC && 1425 LA() != TOK_LPAREN && 1426 LA() != TOK_ASSIGN && 1427 LA() != TOK_SEMICOLON && 1428 LA() != TOK_RBRACE 1429 ) { 1430 flags |= FN_STATIC; 1431 CONSUME(); 1432 NEXT(); 1433 1434 if (TOK == TOK_LBRACE) { 1435 sv_ast_t *block = parse_block(p, false); 1436 block->type = N_STATIC_BLOCK; 1437 block->flags = FN_STATIC; 1438 sv_ast_list_push(&cls->args, block); 1439 continue; 1440 } 1441 } 1442 1443 sv_ast_t *method = mk(N_METHOD); 1444 uint32_t method_src_off = (uint32_t)TOFF; 1445 1446 if (TOK == TOK_ASYNC && LA() != TOK_LPAREN) { 1447 flags |= FN_ASYNC; 1448 CONSUME(); 1449 NEXT(); 1450 } 1451 1452 if (TOK == TOK_MUL) { 1453 flags |= FN_GENERATOR; 1454 CONSUME(); 1455 NEXT(); 1456 } 1457 1458 if ((TLEN == 3 && memcmp(tok_str(p), "get", 3) == 0) || 1459 (TLEN == 3 && memcmp(tok_str(p), "set", 3) == 0)) { 1460 uint8_t la = LA(); 1461 if (la != TOK_LPAREN && la != TOK_ASSIGN && la != TOK_SEMICOLON && la != TOK_RBRACE) { 1462 flags |= (tok_str(p)[0] == 'g') ? FN_GETTER : FN_SETTER; 1463 CONSUME(); 1464 NEXT(); 1465 } 1466 } 1467 1468 if (TOK == TOK_LBRACKET) { 1469 CONSUME(); 1470 method->left = parse_assign(p); 1471 expect(p, TOK_RBRACKET); 1472 flags |= FN_COMPUTED; 1473 } else if (TOK == TOK_HASH) { 1474 CONSUME(); 1475 NEXT(); 1476 if (!is_private_ident_like_tok(TOK)) { 1477 SV_MKERR_TYPED(JS, JS_ERR_SYNTAX, "private field name expected"); 1478 return mk(N_EMPTY); 1479 } 1480 method->left = mk_private_ident_from_tok(p); 1481 CONSUME(); 1482 } else { 1483 method->left = mk_ident_from_tok(p); 1484 CONSUME(); 1485 } 1486 1487 method->flags = flags; 1488 1489 if (!(flags & FN_STATIC) && (flags & FN_GENERATOR) && 1490 method->left && method->left->type == N_IDENT && 1491 method->left->len == 11 && 1492 memcmp(method->left->str, "constructor", 11) == 0) { 1493 SV_MKERR_TYPED(JS, JS_ERR_SYNTAX, "Class constructor may not be a generator"); 1494 return cls; 1495 } 1496 1497 if (NEXT() == TOK_LPAREN) { 1498 method->right = parse_func(p); 1499 method->right->flags |= (flags & (FN_ASYNC | FN_GENERATOR)) | FN_METHOD; 1500 method->right->src_off = method_src_off; 1501 } else if (TOK == TOK_ASSIGN) { 1502 CONSUME(); 1503 method->right = parse_assign(p); 1504 if (NEXT() == TOK_SEMICOLON) CONSUME(); 1505 } else { 1506 method->right = mk(N_UNDEF); 1507 if (TOK == TOK_SEMICOLON) CONSUME(); 1508 } 1509 1510 sv_ast_list_push(&cls->args, method); 1511 } 1512 expect(p, TOK_RBRACE); 1513 cls->src_end = (uint32_t)(TOFF + TLEN); 1514 return cls; 1515} 1516 1517static sv_ast_t *parse_block(P, bool directive_ctx) { 1518 expect(p, TOK_LBRACE); 1519 sv_ast_t *block = mk(N_BLOCK); 1520 sv_parse_stmt_list(p, &block->args, true, directive_ctx); 1521 if (JS->thrown_exists) return block; 1522 expect(p, TOK_RBRACE); 1523 return block; 1524} 1525 1526static sv_ast_t *parse_var_decl(P, sv_var_kind_t kind, bool allow_uninit_const) { 1527 sv_ast_t *var = mk(N_VAR); 1528 var->var_kind = kind; 1529 1530 do { 1531 NEXT(); 1532 sv_ast_t *decl = mk(N_VARDECL); 1533 1534 if (TOK == TOK_LBRACKET) { 1535 decl->left = parse_array(p); 1536 } else if (TOK == TOK_LBRACE) { 1537 decl->left = parse_object(p); 1538 } else if (TOK == TOK_ERR) { 1539 sv_parse_unexpected_token(p); 1540 return var; 1541 } else { 1542 decl->left = mk_ident_from_tok(p); 1543 sv_strict_check_binding_ident(p, decl->left->str, decl->left->len); 1544 CONSUME(); 1545 } 1546 if (NEXT() == TOK_ASSIGN) { 1547 CONSUME(); 1548 decl->right = parse_assign(p); 1549 } else if ((kind == SV_VAR_CONST || kind == SV_VAR_USING || kind == SV_VAR_AWAIT_USING) && !allow_uninit_const) { 1550 SV_MKERR_TYPED(JS, JS_ERR_SYNTAX, "Missing initializer in const declaration"); 1551 } 1552 sv_ast_list_push(&var->args, decl); 1553 } while (NEXT() == TOK_COMMA && (CONSUME(), 1)); 1554 1555 return var; 1556} 1557 1558static sv_ast_t *skip_import_stmt(P) { 1559 while (NEXT() != TOK_SEMICOLON && TOK != TOK_EOF) CONSUME(); 1560 if (TOK == TOK_SEMICOLON) CONSUME(); 1561 return mk(N_EMPTY); 1562} 1563 1564enum { 1565 IMPORT_BIND_DEFAULT = 1 << 0, 1566 IMPORT_BIND_NAMESPACE = 1 << 1, 1567}; 1568 1569static inline void import_decl_add_binding( 1570 sv_ast_t *decl, 1571 const char *import_name, uint32_t import_len, 1572 const char *local_name, uint32_t local_len, 1573 uint8_t flags 1574) { 1575 sv_ast_t *spec = mk_plain(N_IMPORT_SPEC); 1576 spec->flags = flags; 1577 if (import_name) 1578 spec->left = mk_ident(import_name, import_len); 1579 spec->right = mk_ident(local_name, local_len); 1580 sv_ast_list_push(&decl->args, spec); 1581} 1582 1583static sv_ast_t *parse_import_stmt(P) { 1584 static const char default_name[] = "default"; 1585 sv_ast_t *decl = mk(N_IMPORT_DECL); 1586 1587 if (NEXT() == TOK_STRING) { 1588 sv_ast_t *spec = mk(N_STRING); 1589 sv_ast_set_string(spec, sv_lexer_str_literal(&p->lx)); 1590 CONSUME(); 1591 if (NEXT() == TOK_SEMICOLON) CONSUME(); 1592 decl->right = spec; 1593 return decl; 1594 } 1595 1596 bool saw_clause = false; 1597 1598 if (is_ident_like_tok(NEXT())) { 1599 saw_clause = true; 1600 uint32_t local_len = 0; 1601 const char *local_name = tok_ident_str(p, &local_len); 1602 import_decl_add_binding( 1603 decl, 1604 default_name, (uint32_t)(sizeof(default_name) - 1), 1605 local_name, local_len, 1606 IMPORT_BIND_DEFAULT 1607 ); 1608 CONSUME(); 1609 if (NEXT() == TOK_COMMA) CONSUME(); 1610 else goto parse_from; 1611 } 1612 1613 if (NEXT() == TOK_MUL) { 1614 saw_clause = true; 1615 CONSUME(); 1616 expect(p, TOK_AS); 1617 NEXT(); 1618 if (!is_ident_like_tok(TOK)) return skip_import_stmt(p); 1619 uint32_t ns_len = 0; 1620 const char *ns_name = tok_ident_str(p, &ns_len); 1621 import_decl_add_binding( 1622 decl, 1623 NULL, 0, 1624 ns_name, ns_len, 1625 IMPORT_BIND_NAMESPACE 1626 ); 1627 CONSUME(); 1628 } else if (NEXT() == TOK_LBRACE) { 1629 saw_clause = true; 1630 CONSUME(); 1631 while (NEXT() != TOK_RBRACE && TOK != TOK_EOF) { 1632 const char *import_name; 1633 uint32_t import_len; 1634 1635 if (TOK == TOK_STRING) { 1636 sv_lex_string_t s = sv_lexer_str_literal(&p->lx); 1637 import_name = s.str; 1638 import_len = s.len; 1639 CONSUME(); 1640 } else if (!(TOK >= TOK_IDENTIFIER && TOK < TOK_IDENT_LIKE_END)) { 1641 CONSUME(); 1642 continue; 1643 } else { 1644 import_name = tok_ident_str(p, &import_len); 1645 CONSUME(); 1646 } 1647 1648 const char *local_name = import_name; 1649 uint32_t local_len = import_len; 1650 1651 if (NEXT() == TOK_AS) { 1652 CONSUME(); 1653 NEXT(); 1654 if (!is_ident_like_tok(TOK)) return skip_import_stmt(p); 1655 local_name = tok_ident_str(p, &local_len); 1656 CONSUME(); 1657 } 1658 1659 import_decl_add_binding(decl, import_name, import_len, local_name, local_len, 0); 1660 1661 if (NEXT() == TOK_COMMA) { 1662 CONSUME(); 1663 if (NEXT() == TOK_RBRACE) break; 1664 } 1665 } 1666 expect(p, TOK_RBRACE); 1667 } 1668 1669parse_from: 1670 if (!saw_clause) return skip_import_stmt(p); 1671 expect(p, TOK_FROM); 1672 if (NEXT() != TOK_STRING) return skip_import_stmt(p); 1673 1674 sv_ast_t *spec = mk(N_STRING); 1675 sv_ast_set_string(spec, sv_lexer_str_literal(&p->lx)); 1676 CONSUME(); 1677 decl->right = spec; 1678 1679 if (NEXT() == TOK_SEMICOLON) CONSUME(); 1680 return decl; 1681} 1682 1683static sv_ast_t *parse_export_name(P) { 1684 NEXT(); 1685 if (TOK == TOK_STRING) { 1686 sv_lex_string_t s = sv_lexer_str_literal(&p->lx); 1687 sv_ast_t *name = mk(N_IDENT); 1688 name->str = s.str; 1689 name->len = s.len; 1690 CONSUME(); 1691 return name; 1692 } 1693 1694 if (!(TOK >= TOK_IDENTIFIER && TOK < TOK_IDENT_LIKE_END)) { 1695 sv_parse_unexpected_token(p); 1696 return NULL; 1697 } 1698 sv_ast_t *name = mk_ident_from_tok(p); 1699 CONSUME(); 1700 return name; 1701} 1702 1703static sv_ast_t *parse_export_stmt(P) { 1704 sv_ast_t *decl = mk(N_EXPORT); 1705 NEXT(); 1706 1707 if (TOK == TOK_DEFAULT) { 1708 CONSUME(); 1709 decl->flags |= EX_DEFAULT; 1710 1711 if (NEXT() == TOK_ASYNC && LA() == TOK_FUNC && !lookahead_crosses_line_terminator(p)) { 1712 uint32_t async_off = (uint32_t)TOFF; 1713 CONSUME(); 1714 NEXT(); CONSUME(); 1715 decl->left = parse_func(p); 1716 decl->left->flags |= FN_ASYNC; 1717 decl->left->src_off = async_off; 1718 if (NEXT() == TOK_SEMICOLON) CONSUME(); 1719 return decl; 1720 } 1721 if (TOK == TOK_FUNC) { 1722 CONSUME(); 1723 decl->left = parse_func(p); 1724 if (NEXT() == TOK_SEMICOLON) CONSUME(); 1725 return decl; 1726 } 1727 if (TOK == TOK_CLASS) { 1728 uint32_t class_off = (uint32_t)TOFF; 1729 CONSUME(); 1730 decl->left = parse_class(p); 1731 decl->left->src_off = class_off; 1732 if (NEXT() == TOK_SEMICOLON) CONSUME(); 1733 return decl; 1734 } 1735 1736 decl->left = parse_assign(p); 1737 if (NEXT() == TOK_SEMICOLON) CONSUME(); 1738 return decl; 1739 } 1740 1741 if (TOK == TOK_ASYNC && LA() == TOK_FUNC && !lookahead_crosses_line_terminator(p)) { 1742 decl->flags |= EX_DECL; 1743 uint32_t async_off = (uint32_t)TOFF; 1744 CONSUME(); 1745 NEXT(); CONSUME(); 1746 decl->left = parse_func(p); 1747 decl->left->flags |= FN_ASYNC; 1748 decl->left->src_off = async_off; 1749 if (!decl->left->str || decl->left->len == 0) 1750 SV_MKERR_TYPED(JS, JS_ERR_SYNTAX, "exported function declarations require a name"); 1751 return decl; 1752 } 1753 1754 if (TOK == TOK_FUNC) { 1755 decl->flags |= EX_DECL; 1756 CONSUME(); 1757 decl->left = parse_func(p); 1758 if (!decl->left->str || decl->left->len == 0) 1759 SV_MKERR_TYPED(JS, JS_ERR_SYNTAX, "exported function declarations require a name"); 1760 return decl; 1761 } 1762 if (TOK == TOK_CLASS) { 1763 decl->flags |= EX_DECL; 1764 uint32_t class_off = (uint32_t)TOFF; 1765 CONSUME(); 1766 decl->left = parse_class(p); 1767 decl->left->src_off = class_off; 1768 if (!decl->left->str || decl->left->len == 0) 1769 SV_MKERR_TYPED(JS, JS_ERR_SYNTAX, "exported class declarations require a name"); 1770 return decl; 1771 } 1772 1773 if (TOK == TOK_VAR || TOK == TOK_LET || TOK == TOK_CONST) { 1774 decl->flags |= EX_DECL; 1775 sv_var_kind_t kind = ( 1776 TOK == TOK_VAR) ? SV_VAR_VAR : 1777 (TOK == TOK_LET) ? SV_VAR_LET : SV_VAR_CONST; 1778 CONSUME(); 1779 decl->left = parse_var_decl(p, kind, false); 1780 if (NEXT() == TOK_SEMICOLON) CONSUME(); 1781 return decl; 1782 } 1783 1784 if (TOK == TOK_LBRACE) { 1785 decl->flags |= EX_NAMED; 1786 CONSUME(); 1787 while (NEXT() != TOK_RBRACE && TOK != TOK_EOF) { 1788 sv_ast_t *local_name = parse_export_name(p); 1789 if (!local_name) return decl; 1790 1791 sv_ast_t *export_name = local_name; 1792 if (NEXT() == TOK_AS) { 1793 CONSUME(); 1794 export_name = parse_export_name(p); 1795 if (!export_name) return decl; 1796 } 1797 1798 sv_ast_t *spec = mk(N_IMPORT_SPEC); 1799 spec->left = local_name; 1800 spec->right = export_name; 1801 sv_ast_list_push(&decl->args, spec); 1802 1803 if (NEXT() == TOK_COMMA) { 1804 CONSUME(); 1805 if (NEXT() == TOK_RBRACE) break; 1806 } else { 1807 break; 1808 } 1809 } 1810 expect(p, TOK_RBRACE); 1811 1812 if (NEXT() == TOK_FROM) { 1813 CONSUME(); 1814 if (NEXT() != TOK_STRING) { 1815 sv_parse_unexpected_token(p); 1816 return decl; 1817 } 1818 sv_ast_t *spec = mk(N_STRING); 1819 sv_ast_set_string(spec, sv_lexer_str_literal(&p->lx)); 1820 decl->right = spec; 1821 decl->flags |= EX_FROM; 1822 CONSUME(); 1823 } 1824 1825 if (NEXT() == TOK_SEMICOLON) CONSUME(); 1826 return decl; 1827 } 1828 1829 if (TOK == TOK_MUL) { 1830 decl->flags |= EX_STAR; 1831 CONSUME(); 1832 1833 if (NEXT() == TOK_AS) { 1834 decl->flags |= EX_NAMESPACE; 1835 CONSUME(); 1836 1837 sv_ast_t *name = parse_export_name(p); 1838 if (!name) return decl; 1839 1840 sv_ast_t *spec = mk(N_IMPORT_SPEC); 1841 spec->right = name; 1842 sv_ast_list_push(&decl->args, spec); 1843 } 1844 1845 expect(p, TOK_FROM); 1846 if (NEXT() != TOK_STRING) { 1847 sv_parse_unexpected_token(p); 1848 return decl; 1849 } 1850 sv_ast_t *spec = mk(N_STRING); 1851 sv_ast_set_string(spec, sv_lexer_str_literal(&p->lx)); 1852 decl->right = spec; 1853 decl->flags |= EX_FROM; 1854 CONSUME(); 1855 1856 if (NEXT() == TOK_SEMICOLON) CONSUME(); 1857 return decl; 1858 } 1859 1860 sv_parse_unexpected_token(p); 1861 return decl; 1862} 1863 1864static sv_ast_t *parse_stmt(P) { 1865 NEXT(); 1866 1867 static const void *dispatch[TOK_MAX] = { 1868 [TOK_SEMICOLON] = &&l_semi, 1869 [TOK_LBRACE] = &&l_block, 1870 [TOK_VAR] = &&l_var, 1871 [TOK_LET] = &&l_let, 1872 [TOK_CONST] = &&l_const, 1873 [TOK_IF] = &&l_if, 1874 [TOK_WHILE] = &&l_while, 1875 [TOK_DO] = &&l_do, 1876 [TOK_FOR] = &&l_for, 1877 [TOK_RETURN] = &&l_return, 1878 [TOK_THROW] = &&l_throw, 1879 [TOK_BREAK] = &&l_break, 1880 [TOK_CONTINUE] = &&l_continue, 1881 [TOK_TRY] = &&l_try, 1882 [TOK_SWITCH] = &&l_switch, 1883 [TOK_DEBUGGER] = &&l_debugger, 1884 [TOK_WITH] = &&l_with, 1885 [TOK_FUNC] = &&l_func, 1886 [TOK_CLASS] = &&l_class, 1887 [TOK_ASYNC] = &&l_async, 1888 [TOK_EXPORT] = &&l_export, 1889 [TOK_IMPORT] = &&l_import, 1890 }; 1891 1892 if (TOK == TOK_USING) { 1893 CONSUME(); 1894 sv_ast_t *n = parse_var_decl(p, SV_VAR_USING, false); 1895 if (NEXT() == TOK_SEMICOLON) CONSUME(); 1896 return n; 1897 } 1898 1899 if (TOK == TOK_AWAIT) { 1900 sv_lexer_state_t saved; 1901 sv_lexer_save_state(&p->lx, &saved); 1902 CONSUME(); 1903 NEXT(); 1904 if (TOK == TOK_USING) { 1905 CONSUME(); 1906 sv_ast_t *n = parse_var_decl(p, SV_VAR_AWAIT_USING, false); 1907 if (NEXT() == TOK_SEMICOLON) CONSUME(); 1908 return n; 1909 } 1910 sv_lexer_restore_state(&p->lx, &saved); 1911 } 1912 1913 if (TOK < TOK_MAX && dispatch[TOK]) 1914 goto *dispatch[TOK]; 1915 goto l_expr_stmt; 1916 1917 l_semi: { CONSUME(); return mk(N_EMPTY); } 1918 l_block: return parse_block(p, false); 1919 1920 l_var: { 1921 CONSUME(); 1922 sv_ast_t *n = parse_var_decl(p, SV_VAR_VAR, false); 1923 if (NEXT() == TOK_SEMICOLON) CONSUME(); 1924 return n; 1925 } 1926 l_let: { 1927 CONSUME(); 1928 sv_ast_t *n = parse_var_decl(p, SV_VAR_LET, false); 1929 if (NEXT() == TOK_SEMICOLON) CONSUME(); 1930 return n; 1931 } 1932 l_const: { 1933 CONSUME(); 1934 sv_ast_t *n = parse_var_decl(p, SV_VAR_CONST, false); 1935 if (NEXT() == TOK_SEMICOLON) CONSUME(); 1936 return n; 1937 } 1938 1939 l_if: { 1940 CONSUME(); 1941 sv_ast_t *n = mk(N_IF); 1942 expect(p, TOK_LPAREN); 1943 n->cond = parse_expr(p); 1944 expect(p, TOK_RPAREN); 1945 n->left = parse_stmt(p); 1946 if (NEXT() == TOK_ELSE) { 1947 CONSUME(); 1948 n->right = parse_stmt(p); 1949 } 1950 return n; 1951 } 1952 1953 l_while: { 1954 CONSUME(); 1955 sv_ast_t *n = mk(N_WHILE); 1956 expect(p, TOK_LPAREN); 1957 n->cond = parse_expr(p); 1958 expect(p, TOK_RPAREN); 1959 n->body = parse_stmt(p); 1960 return n; 1961 } 1962 1963 l_do: { 1964 CONSUME(); 1965 sv_ast_t *n = mk(N_DO_WHILE); 1966 n->body = parse_stmt(p); 1967 expect(p, TOK_WHILE); 1968 expect(p, TOK_LPAREN); 1969 n->cond = parse_expr(p); 1970 expect(p, TOK_RPAREN); 1971 if (NEXT() == TOK_SEMICOLON) CONSUME(); 1972 return n; 1973 } 1974 1975 l_for: { 1976 CONSUME(); 1977 bool is_for_await = false; 1978 if (NEXT() == TOK_AWAIT) { 1979 CONSUME(); 1980 is_for_await = true; 1981 } 1982 expect(p, TOK_LPAREN); 1983 sv_ast_t *init_node = NULL; 1984 1985 NEXT(); 1986 if (TOK == TOK_AWAIT) { 1987 sv_lexer_state_t saved; 1988 sv_lexer_save_state(&p->lx, &saved); 1989 CONSUME(); 1990 NEXT(); 1991 if (TOK == TOK_USING) { 1992 CONSUME(); 1993 p->no_in = true; 1994 init_node = parse_var_decl(p, SV_VAR_AWAIT_USING, true); 1995 p->no_in = false; 1996 } else sv_lexer_restore_state(&p->lx, &saved); 1997 } 1998 1999 if (!init_node && TOK == TOK_USING) { 2000 CONSUME(); 2001 p->no_in = true; 2002 init_node = parse_var_decl(p, SV_VAR_USING, true); 2003 p->no_in = false; 2004 } else if (!init_node && (TOK == TOK_VAR || TOK == TOK_LET || TOK == TOK_CONST)) { 2005 sv_var_kind_t kind = ( 2006 TOK == TOK_VAR) ? SV_VAR_VAR : 2007 (TOK == TOK_LET) ? SV_VAR_LET : SV_VAR_CONST; 2008 CONSUME(); 2009 p->no_in = true; 2010 init_node = parse_var_decl(p, kind, true); 2011 p->no_in = false; 2012 } else if (!init_node && TOK != TOK_SEMICOLON) { 2013 p->no_in = true; 2014 init_node = parse_expr(p); 2015 p->no_in = false; 2016 } 2017 2018 uint8_t la = NEXT(); 2019 if (la == TOK_IN) { 2020 CONSUME(); 2021 sv_ast_t *n = mk(N_FOR_IN); 2022 n->left = init_node; 2023 n->right = parse_expr(p); 2024 expect(p, TOK_RPAREN); 2025 n->body = parse_stmt(p); 2026 return n; 2027 } 2028 if (la == TOK_OF || (la == TOK_IDENTIFIER && TLEN == 2 && 2029 memcmp(tok_str(p), "of", 2) == 0)) { 2030 CONSUME(); 2031 sv_ast_t *n = mk(is_for_await ? N_FOR_AWAIT_OF : N_FOR_OF); 2032 n->left = init_node; 2033 n->right = parse_assign(p); 2034 expect(p, TOK_RPAREN); 2035 n->body = parse_stmt(p); 2036 return n; 2037 } 2038 2039 if (init_node && init_node->type == N_VAR && ( 2040 init_node->var_kind == SV_VAR_CONST || 2041 init_node->var_kind == SV_VAR_USING || 2042 init_node->var_kind == SV_VAR_AWAIT_USING)) { 2043 for (int i = 0; i < init_node->args.count; i++) { 2044 sv_ast_t *decl = init_node->args.items[i]; 2045 if (decl && decl->type == N_VARDECL && !decl->right) { 2046 SV_MKERR_TYPED(JS, JS_ERR_SYNTAX, "Missing initializer in const declaration"); 2047 return mk(N_EMPTY); 2048 } 2049 } 2050 } 2051 2052 sv_ast_t *n = mk(N_FOR); 2053 n->init = init_node; 2054 expect(p, TOK_SEMICOLON); 2055 if (NEXT() != TOK_SEMICOLON) 2056 n->cond = parse_expr(p); 2057 expect(p, TOK_SEMICOLON); 2058 if (NEXT() != TOK_RPAREN) 2059 n->update = parse_expr(p); 2060 expect(p, TOK_RPAREN); 2061 n->body = parse_stmt(p); 2062 return n; 2063 } 2064 2065 l_return: { 2066 CONSUME(); 2067 sv_ast_t *n = mk(N_RETURN); 2068 if (NEXT() != TOK_SEMICOLON && TOK != TOK_RBRACE && TOK != TOK_EOF && 2069 !HAD_NEWLINE) 2070 n->right = parse_expr(p); 2071 if (NEXT() == TOK_SEMICOLON) CONSUME(); 2072 return n; 2073 } 2074 2075 l_throw: { 2076 CONSUME(); 2077 sv_ast_t *n = mk(N_THROW); 2078 n->right = parse_expr(p); 2079 if (NEXT() == TOK_SEMICOLON) CONSUME(); 2080 return n; 2081 } 2082 2083 l_break: { 2084 CONSUME(); 2085 sv_ast_t *n = mk(N_BREAK); 2086 if ((NEXT() == TOK_IDENTIFIER || is_contextual_ident_tok(TOK)) && !HAD_NEWLINE) { 2087 n->str = tok_ident_str(p, &n->len); 2088 CONSUME(); 2089 } 2090 if (NEXT() == TOK_SEMICOLON) CONSUME(); 2091 return n; 2092 } 2093 2094 l_continue: { 2095 CONSUME(); 2096 sv_ast_t *n = mk(N_CONTINUE); 2097 if ((NEXT() == TOK_IDENTIFIER || is_contextual_ident_tok(TOK)) && !HAD_NEWLINE) { 2098 n->str = tok_ident_str(p, &n->len); 2099 CONSUME(); 2100 } 2101 if (NEXT() == TOK_SEMICOLON) CONSUME(); 2102 return n; 2103 } 2104 2105 l_try: { 2106 CONSUME(); 2107 sv_ast_t *n = mk(N_TRY); 2108 n->body = parse_block(p, false); 2109 if (NEXT() == TOK_CATCH) { 2110 CONSUME(); 2111 if (NEXT() == TOK_LPAREN) { 2112 CONSUME(); 2113 n->catch_param = parse_binding_pattern(p); 2114 if (n->catch_param->type == N_IDENT) 2115 sv_strict_check_binding_ident(p, n->catch_param->str, n->catch_param->len); 2116 expect(p, TOK_RPAREN); 2117 } 2118 n->catch_body = parse_block(p, false); 2119 } 2120 if (NEXT() == TOK_FINALLY) { 2121 CONSUME(); 2122 n->finally_body = parse_block(p, false); 2123 } 2124 return n; 2125 } 2126 2127 l_switch: { 2128 CONSUME(); 2129 sv_ast_t *n = mk(N_SWITCH); 2130 expect(p, TOK_LPAREN); 2131 n->cond = parse_expr(p); 2132 expect(p, TOK_RPAREN); 2133 expect(p, TOK_LBRACE); 2134 while (NEXT() != TOK_RBRACE && TOK != TOK_EOF) { 2135 sv_ast_t *c = mk(N_CASE); 2136 if (TOK == TOK_CASE) { 2137 CONSUME(); 2138 c->left = parse_expr(p); 2139 } else if (TOK == TOK_DEFAULT) { 2140 CONSUME(); 2141 } 2142 expect(p, TOK_COLON); 2143 while (NEXT() != TOK_CASE && TOK != TOK_DEFAULT && 2144 TOK != TOK_RBRACE && TOK != TOK_EOF) 2145 sv_ast_list_push(&c->args, parse_stmt(p)); 2146 sv_ast_list_push(&n->args, c); 2147 } 2148 expect(p, TOK_RBRACE); 2149 return n; 2150 } 2151 2152 l_debugger: { CONSUME(); if (NEXT() == TOK_SEMICOLON) CONSUME(); return mk(N_DEBUGGER); } 2153 2154 l_with: { 2155 if (p->lx.strict) { 2156 SV_MKERR_TYPED(JS, JS_ERR_SYNTAX, "with statement not allowed in strict mode"); 2157 return mk(N_EMPTY); 2158 } 2159 CONSUME(); 2160 sv_ast_t *n = mk(N_WITH); 2161 expect(p, TOK_LPAREN); 2162 n->left = parse_expr(p); 2163 expect(p, TOK_RPAREN); 2164 n->body = parse_stmt(p); 2165 return n; 2166 } 2167 2168 l_func: { 2169 CONSUME(); 2170 return parse_func(p); 2171 } 2172 2173 l_class: { 2174 uint32_t class_off = (uint32_t)TOFF; 2175 CONSUME(); 2176 sv_ast_t *cls = parse_class(p); 2177 cls->src_off = class_off; 2178 return cls; 2179 } 2180 2181 l_async: { 2182 uint8_t la = LA(); 2183 uint32_t async_off = (uint32_t)TOFF; 2184 if (la == TOK_FUNC && !lookahead_crosses_line_terminator(p)) { 2185 CONSUME(); 2186 NEXT(); CONSUME(); 2187 sv_ast_t *fn = parse_func(p); 2188 fn->flags |= FN_ASYNC; 2189 fn->src_off = async_off; 2190 return fn; 2191 } 2192 goto l_expr_stmt; 2193 } 2194 2195 l_import: { 2196 uint8_t la = LA(); 2197 if (la == TOK_LPAREN || la == TOK_DOT) 2198 goto l_expr_stmt; 2199 CONSUME(); 2200 return parse_import_stmt(p); 2201 } 2202 2203 l_export: { 2204 CONSUME(); 2205 return parse_export_stmt(p); 2206 } 2207 2208 l_expr_stmt: { 2209 if (TOK == TOK_IDENTIFIER || is_contextual_ident_tok(TOK)) { 2210 uint8_t la = LA(); 2211 if (la == TOK_COLON) { 2212 sv_ast_t *label = mk(N_LABEL); 2213 label->str = tok_ident_str(p, &label->len); 2214 CONSUME(); 2215 NEXT(); CONSUME(); 2216 label->body = parse_stmt(p); 2217 return label; 2218 } 2219 } 2220 2221 sv_ast_t *expr = parse_expr(p); 2222 if (NEXT() == TOK_SEMICOLON) CONSUME(); 2223 return expr; 2224 } 2225} 2226 2227sv_ast_t *sv_parse(ant_t *js, const char *code, ant_offset_t clen, bool strict){ 2228 if (sv_parse_trace_unlikely) { 2229 fprintf(stderr, "[parse] start len=%u strict=%d\n", (unsigned)clen, strict ? 1 : 0); 2230 } 2231 2232 sv_parser_t parser = { .js = js }; 2233 sv_parser_t *p = &parser; 2234 sv_lexer_init(&p->lx, js, code, clen, strict); 2235 2236 sv_ast_t *program = mk(N_PROGRAM); 2237 sv_parse_stmt_list(p, &program->args, false, true); 2238 if (sv_parse_trace_unlikely) fprintf( 2239 stderr, "[parse] after-stmt-list thrown=%d strict=%d body=%d\n", 2240 js->thrown_exists ? 1 : 0, 2241 p->lx.strict ? 1 : 0, 2242 program ? program->args.count : -1 2243 ); 2244 2245 if (js->thrown_exists) { 2246 if (sv_parse_trace_unlikely) fprintf(stderr, "[parse] return null\n"); 2247 return NULL; 2248 } 2249 2250 if (p->lx.strict) program->flags |= FN_PARSE_STRICT; 2251 if (sv_parse_trace_unlikely) fprintf(stderr, 2252 "[parse] return program strict=%d body=%d\n", 2253 p->lx.strict ? 1 : 0, program->args.count 2254 ); 2255 2256 return program; 2257}