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.

'var' warning if used

+90 -18
+16 -18
src/ant.c
··· 52 52 jsoff_t maxcss; // maximum allowed C stack size usage 53 53 void *cstk; // C stack pointer at the beginning of js_eval() 54 54 jsval_t current_func; // currently executing function (for native closures) 55 + bool var_warning_shown; // flag to show var deprecation warning only once 55 56 }; 56 57 57 58 enum { ··· 2808 2809 if (!expect(js, TOK_FOR, &res)) goto done; 2809 2810 if (!expect(js, TOK_LPAREN, &res)) goto done; 2810 2811 2811 - // Check for for-in loop: for (let/const/var x in obj) 2812 2812 bool is_for_in = false; 2813 2813 jsoff_t var_name_off = 0, var_name_len = 0; 2814 2814 bool is_const_var = false; 2815 2815 2816 - if (next(js) == TOK_LET || next(js) == TOK_CONST) { 2816 + if (next(js) == TOK_LET || next(js) == TOK_CONST || next(js) == TOK_VAR) { 2817 + if (js->tok == TOK_VAR) { 2818 + if (!js->var_warning_shown) { 2819 + fprintf(stderr, "Warning: 'var' is deprecated, use 'let' or 'const' instead\n"); 2820 + js->var_warning_shown = true; 2821 + } 2822 + } 2817 2823 is_const_var = (js->tok == TOK_CONST); 2818 2824 js->consumed = 1; 2819 2825 if (next(js) == TOK_IDENTIFIER) { ··· 2824 2830 is_for_in = true; 2825 2831 js->consumed = 1; 2826 2832 } else { 2827 - // Not for-in, backtrack and handle as regular for loop 2828 2833 js->pos = var_name_off; 2829 2834 js->consumed = 1; 2830 2835 if (is_const_var) { ··· 2843 2848 is_for_in = true; 2844 2849 js->consumed = 1; 2845 2850 } else { 2846 - // Not for-in, parse as expression 2847 2851 js->pos = var_name_off; 2848 2852 js->consumed = 1; 2849 2853 v = js_expr(js); 2850 2854 if (is_err2(&v, &res)) goto done; 2851 2855 } 2852 2856 } else if (next(js) == TOK_SEMICOLON) { 2853 - // Empty init in regular for loop 2854 2857 } else { 2855 2858 v = js_expr(js); 2856 2859 if (is_err2(&v, &res)) goto done; 2857 2860 } 2858 2861 2859 2862 if (is_for_in) { 2860 - // Handle for-in loop 2861 2863 jsval_t obj_expr = js_expr(js); 2862 2864 if (is_err2(&obj_expr, &res)) goto done; 2863 2865 if (!expect(js, TOK_RPAREN, &res)) goto done; ··· 2880 2882 iter_obj = mkval(T_OBJ, vdata(obj)); 2881 2883 } 2882 2884 2883 - // Iterate over object properties 2884 2885 jsoff_t prop_off = loadoff(js, (jsoff_t) vdata(iter_obj)) & ~(3U | CONSTMASK); 2885 2886 2886 2887 while (prop_off < js->brk && prop_off != 0) { 2887 - // Get property key 2888 2888 jsoff_t koff = loadoff(js, prop_off + (jsoff_t) sizeof(prop_off)); 2889 2889 jsoff_t klen = offtolen(loadoff(js, koff)); 2890 2890 jsval_t key_str = js_mkstr(js, (char *) &js->mem[koff + sizeof(koff)], klen); 2891 2891 2892 - // Set loop variable to the key 2893 2892 const char *var_name = &js->code[var_name_off]; 2894 2893 jsoff_t existing = lkp(js, js->scope, var_name, var_name_len); 2895 2894 if (existing > 0) { ··· 2902 2901 } 2903 2902 } 2904 2903 2905 - // Execute loop body 2906 2904 js->pos = body_start; 2907 2905 js->consumed = 1; 2908 2906 js->flags = (flags & ~F_NOEXEC) | F_LOOP; ··· 2918 2916 goto done; 2919 2917 } 2920 2918 2921 - // Move to next property 2922 2919 prop_off = loadoff(js, prop_off) & ~(3U | CONSTMASK); 2923 2920 } 2924 2921 } ··· 2929 2926 goto done; 2930 2927 } 2931 2928 2932 - // Regular for loop 2933 2929 if (!expect(js, TOK_SEMICOLON, &res)) goto done; 2934 2930 js->flags |= F_NOEXEC; 2935 2931 pos1 = js->pos; ··· 3329 3325 case TOK_CASE: case TOK_CATCH: 3330 3326 case TOK_DEFAULT: case TOK_FINALLY: 3331 3327 case TOK_SWITCH: 3332 - case TOK_THROW: case TOK_TRY: case TOK_VAR: 3328 + case TOK_THROW: case TOK_TRY: 3333 3329 case TOK_WITH: case TOK_YIELD: 3334 3330 res = js_mkerr(js, "'%.*s' not implemented", (int) js->tlen, js->code + js->toff); 3331 + break; 3332 + case TOK_VAR: 3333 + if (!js->var_warning_shown) { 3334 + fprintf(stderr, "Warning: 'var' is deprecated, use 'let' or 'const' instead\n"); 3335 + js->var_warning_shown = true; 3336 + } 3337 + res = js_let(js); 3335 3338 break; 3336 3339 case TOK_WHILE: res = js_while(js); break; 3337 3340 case TOK_DO: res = js_do_while(js); break; ··· 4327 4330 } 4328 4331 4329 4332 static jsval_t do_in(struct js *js, jsval_t l, jsval_t r) { 4330 - // l should be a string (property name), r should be an object 4331 4333 if (vtype(l) != T_STR) { 4332 4334 return js_mkerr(js, "left operand of 'in' must be string"); 4333 4335 } ··· 4336 4338 return js_mkerr(js, "right operand of 'in' must be object"); 4337 4339 } 4338 4340 4339 - // Get the property name 4340 4341 jsoff_t prop_len; 4341 4342 jsoff_t prop_off = vstr(js, l, &prop_len); 4342 4343 const char *prop_name = (char *) &js->mem[prop_off]; 4343 4344 4344 - // For functions, check the function object 4345 4345 jsval_t check_obj = r; 4346 4346 if (vtype(r) == T_FUNC) { 4347 4347 check_obj = mkval(T_OBJ, vdata(r)); 4348 4348 } 4349 4349 4350 - // Look up the property 4351 4350 jsoff_t found = lkp(js, check_obj, prop_name, prop_len); 4352 - 4353 4351 return mkval(T_BOOL, found != 0 ? 1 : 0); 4354 4352 } 4355 4353
+74
tests/test_var.cjs
··· 1 + // Test var keyword (should work like let but show warnings) 2 + Ant.println('=== Var Keyword Tests ==='); 3 + 4 + // Test 1: Basic var declaration 5 + Ant.println('\nTest 1: Basic var declaration'); 6 + var x = 10; 7 + Ant.println('var x = 10: ' + x); 8 + 9 + // Test 2: Var reassignment 10 + Ant.println('\nTest 2: Var reassignment'); 11 + var y = 5; 12 + y = y + 10; 13 + Ant.println('var y reassigned: ' + y); 14 + 15 + // Test 3: Var in for loop 16 + Ant.println('\nTest 3: Var in for loop'); 17 + var sum = 0; 18 + for (var i = 0; i < 5; i = i + 1) { 19 + sum = sum + i; 20 + } 21 + Ant.println('Sum with var: ' + sum); 22 + 23 + // Test 4: Var in for-in loop 24 + Ant.println('\nTest 4: Var in for-in loop'); 25 + const obj = { a: 1, b: 2, c: 3 }; 26 + var keys = ''; 27 + for (var key in obj) { 28 + keys = keys + key + ','; 29 + } 30 + Ant.println('Keys with var: ' + keys); 31 + 32 + // Test 5: Multiple var declarations 33 + Ant.println('\nTest 5: Multiple var declarations'); 34 + var a = 1, b = 2, c = 3; 35 + Ant.println('var a, b, c: ' + (a + b + c)); 36 + 37 + // Test 6: Var in while loop 38 + Ant.println('\nTest 6: Var in while loop'); 39 + var count = 0; 40 + while (count < 3) { 41 + count = count + 1; 42 + } 43 + Ant.println('While with var: ' + count); 44 + 45 + // Test 7: Var with objects 46 + Ant.println('\nTest 7: Var with objects'); 47 + var obj2 = { name: 'test', value: 42 }; 48 + Ant.println('var object: ' + obj2.name + ' = ' + obj2.value); 49 + 50 + // Test 8: Var with arrays 51 + Ant.println('\nTest 8: Var with arrays'); 52 + var arr = [10, 20, 30]; 53 + Ant.println('var array[1]: ' + arr[1]); 54 + 55 + // Test 9: Var in nested scopes 56 + Ant.println('\nTest 9: Var in nested scopes'); 57 + var outer = 'outer'; 58 + if (true) { 59 + var inner = 'inner'; 60 + Ant.println('Inner var: ' + inner); 61 + } 62 + Ant.println('Outer var: ' + outer); 63 + 64 + // Test 10: Var works like let 65 + Ant.println('\nTest 10: Var behavior like let'); 66 + var testVar = 100; 67 + if (testVar > 50) { 68 + var modified = testVar * 2; 69 + Ant.println('Modified: ' + modified); 70 + } 71 + Ant.println('Original: ' + testVar); 72 + 73 + Ant.println('\n=== All var tests completed ==='); 74 + Ant.println('Note: You should see deprecation warnings above');