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.

repl newline fixes

+41 -52
+41 -52
src/repl.c
··· 416 416 } while (1); 417 417 } 418 418 419 + typedef struct { 420 + int paren, bracket, brace; 421 + int *templates; 422 + int template_count, template_cap; 423 + char string_char; 424 + bool in_string, escaped; 425 + } parse_state_t; 426 + 427 + static void push_template(parse_state_t *s) { 428 + if (s->template_count >= s->template_cap) { 429 + s->template_cap = s->template_cap ? s->template_cap * 2 : 8; 430 + s->templates = realloc(s->templates, s->template_cap * sizeof(int)); 431 + } 432 + s->templates[s->template_count++] = s->brace; 433 + } 434 + 435 + static bool in_template_text(parse_state_t *s) { 436 + return s->template_count > 0 && s->brace == s->templates[s->template_count - 1]; 437 + } 438 + 419 439 static bool is_incomplete_input(const char *code, size_t len) { 420 - int paren_depth = 0; 421 - int bracket_depth = 0; 422 - int brace_depth = 0; 423 - 424 - bool in_string = false; 425 - bool in_template = false; 426 - char string_char = 0; 427 - bool escape_next = false; 440 + parse_state_t s = {0}; 428 441 429 442 for (size_t i = 0; i < len; i++) { 430 443 char c = code[i]; 431 444 432 - if (escape_next) { 433 - escape_next = false; 434 - continue; 435 - } 445 + if (s.escaped) { s.escaped = false; continue; } 446 + if (c == '\\' && (s.in_string || s.template_count > 0)) { s.escaped = true; continue; } 447 + if (s.in_string) { if (c == s.string_char) s.in_string = false; continue; } 436 448 437 - if (c == '\\' && (in_string || in_template)) { 438 - escape_next = true; 449 + if (in_template_text(&s)) { 450 + if (c == '`') s.template_count--; 451 + else if (c == '$' && i + 1 < len && code[i + 1] == '{') { s.brace++; i++; } 439 452 continue; 440 453 } 441 454 442 - if (in_string) { 443 - if (c == string_char) in_string = false; 444 - continue; 445 - } 446 - 447 - if (in_template) { 448 - if (c == '`') { 449 - in_template = false; 450 - } else if (c == '$' && i + 1 < len && code[i + 1] == '{') { 451 - brace_depth++; i++; 455 + if (c == '/' && i + 1 < len) { 456 + if (code[i + 1] == '/') { while (i < len && code[i] != '\n') i++; continue; } 457 + if (code[i + 1] == '*') { 458 + for (i += 2; i + 1 < len && !(code[i] == '*' && code[i + 1] == '/'); i++); 459 + if (i + 1 >= len) { free(s.templates); return true; } 460 + i++; continue; 452 461 } 453 - continue; 454 - } 455 - 456 - if (c == '/' && i + 1 < len && code[i + 1] == '/') { 457 - while (i < len && code[i] != '\n') i++; 458 - continue; 459 - } 460 - 461 - if (c == '/' && i + 1 < len && code[i + 1] == '*') { 462 - i += 2; 463 - while (i + 1 < len && !(code[i] == '*' && code[i + 1] == '/')) i++; 464 - if (i + 1 >= len) return true; 465 - i++; continue; 466 462 } 467 463 468 464 switch (c) { 469 - case '"': 470 - case '\'': 471 - in_string = true; 472 - string_char = c; 473 - break; 474 - case '`': 475 - in_template = true; 476 - break; 477 - case '(': paren_depth++; break; 478 - case ')': paren_depth--; break; 479 - case '[': bracket_depth++; break; 480 - case ']': bracket_depth--; break; 481 - case '{': brace_depth++; break; 482 - case '}': brace_depth--; break; 465 + case '"': case '\'': s.in_string = true; s.string_char = c; break; 466 + case '`': push_template(&s); break; 467 + case '(': s.paren++; break; case ')': s.paren--; break; 468 + case '[': s.bracket++; break; case ']': s.bracket--; break; 469 + case '{': s.brace++; break; case '}': s.brace--; break; 483 470 } 484 471 } 485 472 486 - return in_string || in_template || paren_depth > 0 || bracket_depth > 0 || brace_depth > 0; 473 + bool incomplete = s.in_string || s.template_count > 0 || s.paren > 0 || s.bracket > 0 || s.brace > 0; 474 + free(s.templates); 475 + return incomplete; 487 476 } 488 477 489 478 void ant_repl_run() {