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.

fix function scoping

+71 -7
+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.1.0.27') 77 + version_conf.set('ANT_VERSION', '0.1.0.28') 78 78 version_conf.set('ANT_GIT_HASH', git_hash) 79 79 version_conf.set('ANT_BUILD_DATE', build_date) 80 80
+70 -6
src/ant.c
··· 350 350 static jsval_t js_do_while(struct js *js); 351 351 static jsval_t js_block_or_stmt(struct js *js); 352 352 static jsval_t js_var_decl(struct js *js); 353 - static bool parse_func_params(struct js *js, uint8_t *flags); 353 + static bool parse_func_params(struct js *js, uint8_t *flags, int *out_count); 354 354 static jsval_t js_regex_literal(struct js *js); 355 355 static jsval_t js_try(struct js *js); 356 356 static jsval_t js_switch(struct js *js); ··· 4846 4846 uint8_t flags = js->flags; 4847 4847 jsoff_t pos = js->pos - 1; 4848 4848 js->consumed = 1; 4849 - if (!parse_func_params(js, &flags)) { 4849 + if (!parse_func_params(js, &flags, NULL)) { 4850 4850 js->flags = flags; 4851 4851 return js_mkerr(js, "invalid parameters"); 4852 4852 } ··· 4906 4906 return obj; 4907 4907 } 4908 4908 4909 - static bool parse_func_params(struct js *js, uint8_t *flags) { 4909 + static bool parse_func_params(struct js *js, uint8_t *flags, int *out_count) { 4910 4910 const char *param_names[32]; 4911 4911 size_t param_lens[32]; 4912 4912 int param_count = 0; ··· 4988 4988 } 4989 4989 js->consumed = 1; 4990 4990 } 4991 + if (out_count) *out_count = param_count; 4991 4992 return true; 4992 4993 } 4993 4994 ··· 5003 5004 5004 5005 EXPECT(TOK_LPAREN, js->flags = flags); 5005 5006 jsoff_t pos = js->pos - 1; 5006 - if (!parse_func_params(js, &flags)) { 5007 + int param_count = 0; 5008 + if (!parse_func_params(js, &flags, &param_count)) { 5007 5009 js->flags = flags; 5008 5010 return js_mkerr(js, "invalid parameters"); 5009 5011 } ··· 5027 5029 if (is_err(code_key)) return code_key; 5028 5030 jsval_t res2 = setprop(js, func_obj, code_key, str); 5029 5031 if (is_err(res2)) return res2; 5032 + 5033 + jsval_t len_key = js_mkstr(js, "length", 6); 5034 + if (is_err(len_key)) return len_key; 5035 + jsval_t res_len = setprop(js, func_obj, len_key, tov(param_count)); 5036 + if (is_err(res_len)) return res_len; 5030 5037 5031 5038 if (is_async) { 5032 5039 jsval_t async_key = js_mkstr(js, "__async", 7); ··· 5689 5696 return js_throw(js, result); 5690 5697 } 5691 5698 return result; 5699 + } else if (next(js) == TOK_POSTINC || js->tok == TOK_POSTDEC) { 5700 + uint8_t op = js->tok; 5701 + js->consumed = 1; 5702 + jsval_t operand = js_unary(js); 5703 + if (is_err(operand)) return operand; 5704 + if (js->flags & F_NOEXEC) return operand; 5705 + jsval_t resolved = resolveprop(js, operand); 5706 + if (vtype(operand) == T_PROP || vtype(operand) == T_PROPREF) { 5707 + do_assign_op(js, op == TOK_POSTINC ? TOK_PLUS_ASSIGN : TOK_MINUS_ASSIGN, operand, tov(1)); 5708 + } else { 5709 + return js_mkerr(js, "bad expr"); 5710 + } 5711 + return do_op(js, op == TOK_POSTINC ? TOK_PLUS : TOK_MINUS, resolved, tov(1)); 5692 5712 } else if (next(js) == TOK_NOT || js->tok == TOK_TILDA || js->tok == TOK_TYPEOF || 5693 5713 js->tok == TOK_VOID || js->tok == TOK_MINUS || js->tok == TOK_PLUS) { 5694 5714 uint8_t t = js->tok; ··· 6060 6080 js->consumed = 1; 6061 6081 EXPECT(TOK_LPAREN, ); 6062 6082 jsoff_t pos = js->pos - 1; 6083 + int param_count = 0; 6063 6084 for (bool comma = false; next(js) != TOK_EOF; comma = true) { 6064 6085 if (!comma && next(js) == TOK_RPAREN) break; 6065 6086 ··· 6071 6092 } 6072 6093 6073 6094 if (next(js) != TOK_IDENTIFIER) return js_mkerr(js, "identifier expected"); 6095 + param_count++; 6074 6096 js->consumed = 1; 6075 6097 6076 6098 if (next(js) == TOK_ASSIGN) { ··· 6117 6139 if (is_err(code_key)) return code_key; 6118 6140 jsval_t res2 = setprop(js, func_obj, code_key, str); 6119 6141 if (is_err(res2)) return res2; 6142 + jsval_t len_key = js_mkstr(js, "length", 6); 6143 + if (is_err(len_key)) return len_key; 6144 + jsval_t res_len = setprop(js, func_obj, len_key, tov(param_count)); 6145 + if (is_err(res_len)) return res_len; 6120 6146 jsval_t name_key = js_mkstr(js, "name", 4); 6121 6147 if (is_err(name_key)) return name_key; 6122 6148 jsval_t name_val = js_mkstr(js, name, nlen); ··· 6154 6180 js->consumed = 1; 6155 6181 EXPECT(TOK_LPAREN, ); 6156 6182 jsoff_t pos = js->pos - 1; 6157 - if (!parse_func_params(js, NULL)) { 6183 + if (!parse_func_params(js, NULL, NULL)) { 6158 6184 return js_mkerr(js, "invalid parameters"); 6159 6185 } 6160 6186 EXPECT(TOK_RPAREN, ); ··· 6275 6301 jsoff_t var_name_off = 0, var_name_len = 0; 6276 6302 bool is_const_var = false; 6277 6303 bool is_var_decl = false; 6304 + bool is_let_loop = false; 6305 + jsoff_t let_var_off = 0, let_var_len = 0; 6278 6306 6279 6307 if (next(js) == TOK_LET || next(js) == TOK_CONST || next(js) == TOK_VAR) { 6280 6308 if (js->tok == TOK_VAR) { ··· 6283 6311 fprintf(stderr, "Warning: 'var' is deprecated, use 'let' or 'const' instead\n"); 6284 6312 js->var_warning_shown = true; 6285 6313 } 6314 + } else if (js->tok == TOK_LET) { 6315 + is_let_loop = true; 6286 6316 } 6287 6317 is_const_var = (js->tok == TOK_CONST); 6288 6318 js->consumed = 1; 6289 6319 if (next(js) == TOK_IDENTIFIER) { 6290 6320 var_name_off = js->toff; 6291 6321 var_name_len = js->tlen; 6322 + if (is_let_loop) { 6323 + let_var_off = var_name_off; 6324 + let_var_len = var_name_len; 6325 + } 6292 6326 js->consumed = 1; 6293 6327 if (next(js) == TOK_IN) { 6294 6328 is_for_in = true; ··· 6576 6610 if (is_err2(&v, &res)) goto done; 6577 6611 if (!js_truthy(js, v)) break; 6578 6612 } 6613 + 6614 + jsval_t iter_scope = js_mkundef(); 6615 + jsval_t loop_var_val = js_mkundef(); 6616 + if (is_let_loop && let_var_len > 0) { 6617 + jsoff_t var_off = lkp(js, js->scope, &js->code[let_var_off], let_var_len); 6618 + if (var_off != 0) { 6619 + loop_var_val = resolveprop(js, mkval(T_PROP, var_off)); 6620 + } 6621 + mkscope(js); 6622 + iter_scope = js->scope; 6623 + jsval_t var_key = js_mkstr(js, &js->code[let_var_off], let_var_len); 6624 + mkprop(js, js->scope, var_key, loop_var_val, false); 6625 + } 6626 + 6579 6627 js->pos = pos3, js->consumed = 1, js->flags |= F_LOOP; 6580 6628 v = js_block_or_stmt(js); 6581 - if (is_err2(&v, &res)) goto done; 6629 + if (is_err2(&v, &res)) { 6630 + if (vtype(iter_scope) != T_UNDEF) delscope(js); 6631 + goto done; 6632 + } 6633 + 6634 + if (is_let_loop && let_var_len > 0) { 6635 + jsoff_t iter_var_off = lkp(js, iter_scope, &js->code[let_var_off], let_var_len); 6636 + if (iter_var_off != 0) { 6637 + loop_var_val = resolveprop(js, mkval(T_PROP, iter_var_off)); 6638 + } 6639 + delscope(js); 6640 + jsoff_t outer_var_off = lkp(js, js->scope, &js->code[let_var_off], let_var_len); 6641 + if (outer_var_off != 0) { 6642 + saveval(js, outer_var_off + sizeof(jsoff_t) * 2, loop_var_val); 6643 + } 6644 + } 6645 + 6582 6646 if (js->flags & F_BREAK) break; 6583 6647 if (js->flags & F_RETURN) { 6584 6648 res = v;