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.

asi support

+41 -30
+1 -1
meson.build
··· 74 74 build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip() 75 75 76 76 version_conf = configuration_data() 77 - version_conf.set('ANT_VERSION', '0.0.8.27') 77 + version_conf.set('ANT_VERSION', '0.0.8.28') 78 78 version_conf.set('ANT_GIT_HASH', git_hash) 79 79 version_conf.set('ANT_BUILD_DATE', build_date) 80 80
+40 -29
src/ant.c
··· 235 235 bool var_warning_shown; // flag to show var deprecation warning only once 236 236 bool owns_mem; // true if js owns the memory buffer (dynamic allocation) 237 237 jsoff_t max_size; // maximum allowed memory size (for dynamic growth) 238 + bool had_newline; // true if newline was crossed before current token 238 239 }; 239 240 240 241 enum { ··· 2356 2357 return freed; 2357 2358 } 2358 2359 2359 - static jsoff_t skiptonext(const char *code, jsoff_t len, jsoff_t n) { 2360 + static jsoff_t skiptonext(const char *code, jsoff_t len, jsoff_t n, bool *had_newline) { 2361 + if (had_newline) *had_newline = false; 2360 2362 while (n < len) { 2361 2363 if (is_space(code[n])) { 2364 + if (had_newline && code[n] == '\n') *had_newline = true; 2362 2365 n++; 2363 2366 } else if (n + 1 < len && code[n] == '/' && code[n + 1] == '/') { 2364 2367 for (n += 2; n < len && code[n] != '\n';) n++; 2368 + if (had_newline && n < len && code[n] == '\n') *had_newline = true; 2365 2369 } else if (n + 3 < len && code[n] == '/' && code[n + 1] == '*') { 2366 - for (n += 4; n < len && (code[n - 2] != '*' || code[n - 1] != '/');) n++; 2370 + for (n += 4; n < len && (code[n - 2] != '*' || code[n - 1] != '/');) { 2371 + if (had_newline && code[n] == '\n') *had_newline = true; 2372 + n++; 2373 + } 2367 2374 } else { 2368 2375 break; 2369 2376 } ··· 2427 2434 2428 2435 js->consumed = 0; 2429 2436 js->tok = TOK_ERR; 2430 - js->toff = js->pos = skiptonext(js->code, js->clen, js->pos); 2437 + js->toff = js->pos = skiptonext(js->code, js->clen, js->pos, &js->had_newline); 2431 2438 js->tlen = 0; 2432 2439 2433 2440 const char *buf = js->code + js->toff; ··· 2659 2666 while ((peek = next(js)) != TOK_EOF && peek != TOK_RBRACE && !is_err(res)) { 2660 2667 uint8_t t = js->tok; 2661 2668 res = js_stmt(js); 2662 - if (!is_err(res) && t != TOK_LBRACE && t != TOK_IF && t != TOK_WHILE && 2663 - t != TOK_DO && t != TOK_FUNC && t != TOK_FOR && t != TOK_IMPORT && 2664 - t != TOK_EXPORT && t != TOK_SEMICOLON && 2665 - js->tok != TOK_SEMICOLON && js->tok != TOK_RBRACE && js->tok != TOK_EOF) { 2669 + bool is_block_tok = (t == TOK_LBRACE || t == TOK_IF || t == TOK_WHILE || 2670 + t == TOK_DO || t == TOK_FUNC || t == TOK_FOR || t == TOK_IMPORT || 2671 + t == TOK_EXPORT || t == TOK_SEMICOLON || t == TOK_SWITCH || 2672 + t == TOK_TRY || t == TOK_CLASS || t == TOK_ASYNC); 2673 + bool asi_ok = js->had_newline || js->tok == TOK_SEMICOLON || js->tok == TOK_RBRACE || js->tok == TOK_EOF; 2674 + if (!is_err(res) && !is_block_tok && !asi_ok) { 2666 2675 res = js_mkerr(js, "; expected"); 2667 2676 break; 2668 2677 } ··· 3244 3253 } 3245 3254 3246 3255 static jsoff_t extract_default_param_value(const char *fn, jsoff_t fnlen, jsoff_t start_pos, jsoff_t *out_start, jsoff_t *out_len) { 3247 - jsoff_t after_ident = skiptonext(fn, fnlen, start_pos); 3256 + jsoff_t after_ident = skiptonext(fn, fnlen, start_pos, NULL); 3248 3257 if (after_ident >= fnlen || fn[after_ident] != '=') { 3249 3258 *out_start = 0; 3250 3259 *out_len = 0; 3251 3260 return after_ident; 3252 3261 } 3253 3262 3254 - jsoff_t default_start = skiptonext(fn, fnlen, after_ident + 1); 3263 + jsoff_t default_start = skiptonext(fn, fnlen, after_ident + 1, NULL); 3255 3264 jsoff_t default_len = 0; 3256 3265 jsoff_t depth = 0; 3257 3266 bool in_string = false; ··· 3290 3299 3291 3300 *out_start = default_start; 3292 3301 *out_len = default_len; 3293 - return skiptonext(fn, fnlen, default_start + default_len); 3302 + return skiptonext(fn, fnlen, default_start + default_len, NULL); 3294 3303 } 3295 3304 3296 3305 static jsval_t call_js(struct js *js, const char *fn, jsoff_t fnlen, jsval_t closure_scope) { ··· 3315 3324 3316 3325 jsval_t args[64]; 3317 3326 int argc = 0; 3318 - caller_pos = skiptonext(caller_code, caller_clen, caller_pos); 3327 + caller_pos = skiptonext(caller_code, caller_clen, caller_pos, NULL); 3319 3328 while (caller_pos < caller_clen && caller_code[caller_pos] != ')' && argc < 64) { 3320 3329 bool is_spread = (caller_code[caller_pos] == '.' && caller_pos + 2 < caller_clen && 3321 3330 caller_code[caller_pos + 1] == '.' && caller_code[caller_pos + 2] == '.'); ··· 3332 3341 } else { 3333 3342 args[argc++] = arg; 3334 3343 } 3335 - caller_pos = skiptonext(caller_code, caller_clen, caller_pos); 3344 + caller_pos = skiptonext(caller_code, caller_clen, caller_pos, NULL); 3336 3345 if (caller_pos < caller_clen && caller_code[caller_pos] == ',') caller_pos++; 3337 - caller_pos = skiptonext(caller_code, caller_clen, caller_pos); 3346 + caller_pos = skiptonext(caller_code, caller_clen, caller_pos, NULL); 3338 3347 } 3339 3348 js->pos = caller_pos; 3340 3349 ··· 3343 3352 jsoff_t rest_param_start = 0, rest_param_len = 0; 3344 3353 3345 3354 while (fnpos < fnlen) { 3346 - fnpos = skiptonext(fn, fnlen, fnpos); 3355 + fnpos = skiptonext(fn, fnlen, fnpos, NULL); 3347 3356 if (fnpos < fnlen && fn[fnpos] == ')') break; 3348 3357 3349 3358 bool is_rest = false; ··· 3351 3360 is_rest = true; 3352 3361 has_rest = true; 3353 3362 fnpos += 3; 3354 - fnpos = skiptonext(fn, fnlen, fnpos); 3363 + fnpos = skiptonext(fn, fnlen, fnpos, NULL); 3355 3364 } 3356 3365 3357 3366 jsoff_t identlen = 0; ··· 3361 3370 if (is_rest) { 3362 3371 rest_param_start = fnpos; 3363 3372 rest_param_len = identlen; 3364 - fnpos = skiptonext(fn, fnlen, fnpos + identlen); 3373 + fnpos = skiptonext(fn, fnlen, fnpos + identlen, NULL); 3365 3374 break; 3366 3375 } 3367 3376 ··· 3410 3419 3411 3420 js->scope = function_scope; 3412 3421 if (fnpos < fnlen && fn[fnpos] == ')') fnpos++; 3413 - fnpos = skiptonext(fn, fnlen, fnpos); 3422 + fnpos = skiptonext(fn, fnlen, fnpos, NULL); 3414 3423 if (fnpos < fnlen && fn[fnpos] == '{') fnpos++; 3415 3424 size_t n = fnlen - fnpos - 1U; 3416 3425 js->this_val = target_this; ··· 3505 3514 jsoff_t rest_param_start = 0, rest_param_len = 0; 3506 3515 3507 3516 while (fnpos < fnlen) { 3508 - fnpos = skiptonext(fn, fnlen, fnpos); 3517 + fnpos = skiptonext(fn, fnlen, fnpos, NULL); 3509 3518 if (fnpos < fnlen && fn[fnpos] == ')') break; 3510 3519 3511 3520 bool is_rest = false; ··· 3513 3522 is_rest = true; 3514 3523 has_rest = true; 3515 3524 fnpos += 3; 3516 - fnpos = skiptonext(fn, fnlen, fnpos); 3525 + fnpos = skiptonext(fn, fnlen, fnpos, NULL); 3517 3526 } 3518 3527 3519 3528 jsoff_t identlen = 0; ··· 3523 3532 if (is_rest) { 3524 3533 rest_param_start = fnpos; 3525 3534 rest_param_len = identlen; 3526 - fnpos = skiptonext(fn, fnlen, fnpos + identlen); 3535 + fnpos = skiptonext(fn, fnlen, fnpos + identlen, NULL); 3527 3536 break; 3528 3537 } 3529 3538 ··· 3575 3584 } 3576 3585 3577 3586 if (fnpos < fnlen && fn[fnpos] == ')') fnpos++; 3578 - fnpos = skiptonext(fn, fnlen, fnpos); 3587 + fnpos = skiptonext(fn, fnlen, fnpos, NULL); 3579 3588 if (fnpos < fnlen && fn[fnpos] == '{') fnpos++; 3580 3589 size_t body_len = fnlen - fnpos - 1; 3581 3590 ··· 3617 3626 3618 3627 js->code = &js->code[coderefoff(args)]; 3619 3628 js->clen = codereflen(args); 3620 - js->pos = skiptonext(js->code, js->clen, 0); 3629 + js->pos = skiptonext(js->code, js->clen, 0, NULL); 3621 3630 uint8_t tok = js->tok, flags = js->flags; 3622 3631 jsoff_t nogc = js->nogc; 3623 3632 jsval_t res = js_mkundef(); ··· 5458 5467 } 5459 5468 5460 5469 uint8_t decl_next = next(js); 5461 - if (decl_next == TOK_SEMICOLON || decl_next == TOK_EOF || decl_next == TOK_RBRACE) break; 5470 + bool asi = js->had_newline || decl_next == TOK_EOF || decl_next == TOK_RBRACE; 5471 + if (decl_next == TOK_SEMICOLON || asi) break; 5462 5472 EXPECT(TOK_COMMA, ); 5463 5473 } 5464 5474 return js_mkundef(); ··· 7236 7246 7237 7247 if (!is_block_statement) { 7238 7248 int next_tok = next(js); 7239 - bool missing_semicolon = next_tok != TOK_SEMICOLON && next_tok != TOK_EOF && next_tok != TOK_RBRACE; 7249 + bool asi_applies = js->had_newline || next_tok == TOK_EOF || next_tok == TOK_RBRACE; 7250 + bool missing_semicolon = next_tok != TOK_SEMICOLON && !asi_applies; 7240 7251 if (missing_semicolon) return js_mkerr(js, "; expected"); 7241 7252 if (next_tok == TOK_SEMICOLON) js->consumed = 1; 7242 7253 } ··· 12077 12088 jsoff_t rest_param_start = 0, rest_param_len = 0; 12078 12089 12079 12090 while (fnpos < fnlen) { 12080 - fnpos = skiptonext(fn, fnlen, fnpos); 12091 + fnpos = skiptonext(fn, fnlen, fnpos, NULL); 12081 12092 if (fnpos < fnlen && fn[fnpos] == ')') break; 12082 12093 12083 12094 bool is_rest = false; ··· 12085 12096 is_rest = true; 12086 12097 has_rest = true; 12087 12098 fnpos += 3; 12088 - fnpos = skiptonext(fn, fnlen, fnpos); 12099 + fnpos = skiptonext(fn, fnlen, fnpos, NULL); 12089 12100 } 12090 12101 12091 12102 jsoff_t identlen = 0; ··· 12095 12106 if (is_rest) { 12096 12107 rest_param_start = fnpos; 12097 12108 rest_param_len = identlen; 12098 - fnpos = skiptonext(fn, fnlen, fnpos + identlen); 12109 + fnpos = skiptonext(fn, fnlen, fnpos + identlen, NULL); 12099 12110 break; 12100 12111 } 12101 12112 12102 12113 jsval_t v = arg_idx < nargs ? args[arg_idx] : js_mkundef(); 12103 12114 setprop(js, js->scope, js_mkstr(js, &fn[fnpos], identlen), v); 12104 12115 arg_idx++; 12105 - fnpos = skiptonext(fn, fnlen, fnpos + identlen); 12116 + fnpos = skiptonext(fn, fnlen, fnpos + identlen, NULL); 12106 12117 if (fnpos < fnlen && fn[fnpos] == ',') fnpos++; 12107 12118 } 12108 12119 ··· 12126 12137 } 12127 12138 12128 12139 if (fnpos < fnlen && fn[fnpos] == ')') fnpos++; 12129 - fnpos = skiptonext(fn, fnlen, fnpos); 12140 + fnpos = skiptonext(fn, fnlen, fnpos, NULL); 12130 12141 12131 12142 if (fnpos < fnlen && fn[fnpos] == '{') fnpos++; 12132 12143 size_t body_len = fnlen - fnpos - 1;