···5252 jsoff_t maxcss; // maximum allowed C stack size usage
5353 void *cstk; // C stack pointer at the beginning of js_eval()
5454 jsval_t current_func; // currently executing function (for native closures)
5555+ bool var_warning_shown; // flag to show var deprecation warning only once
5556};
56575758enum {
···28082809 if (!expect(js, TOK_FOR, &res)) goto done;
28092810 if (!expect(js, TOK_LPAREN, &res)) goto done;
2810281128112811- // Check for for-in loop: for (let/const/var x in obj)
28122812 bool is_for_in = false;
28132813 jsoff_t var_name_off = 0, var_name_len = 0;
28142814 bool is_const_var = false;
2815281528162816- if (next(js) == TOK_LET || next(js) == TOK_CONST) {
28162816+ if (next(js) == TOK_LET || next(js) == TOK_CONST || next(js) == TOK_VAR) {
28172817+ if (js->tok == TOK_VAR) {
28182818+ if (!js->var_warning_shown) {
28192819+ fprintf(stderr, "Warning: 'var' is deprecated, use 'let' or 'const' instead\n");
28202820+ js->var_warning_shown = true;
28212821+ }
28222822+ }
28172823 is_const_var = (js->tok == TOK_CONST);
28182824 js->consumed = 1;
28192825 if (next(js) == TOK_IDENTIFIER) {
···28242830 is_for_in = true;
28252831 js->consumed = 1;
28262832 } else {
28272827- // Not for-in, backtrack and handle as regular for loop
28282833 js->pos = var_name_off;
28292834 js->consumed = 1;
28302835 if (is_const_var) {
···28432848 is_for_in = true;
28442849 js->consumed = 1;
28452850 } else {
28462846- // Not for-in, parse as expression
28472851 js->pos = var_name_off;
28482852 js->consumed = 1;
28492853 v = js_expr(js);
28502854 if (is_err2(&v, &res)) goto done;
28512855 }
28522856 } else if (next(js) == TOK_SEMICOLON) {
28532853- // Empty init in regular for loop
28542857 } else {
28552858 v = js_expr(js);
28562859 if (is_err2(&v, &res)) goto done;
28572860 }
2858286128592862 if (is_for_in) {
28602860- // Handle for-in loop
28612863 jsval_t obj_expr = js_expr(js);
28622864 if (is_err2(&obj_expr, &res)) goto done;
28632865 if (!expect(js, TOK_RPAREN, &res)) goto done;
···28802882 iter_obj = mkval(T_OBJ, vdata(obj));
28812883 }
2882288428832883- // Iterate over object properties
28842885 jsoff_t prop_off = loadoff(js, (jsoff_t) vdata(iter_obj)) & ~(3U | CONSTMASK);
2885288628862887 while (prop_off < js->brk && prop_off != 0) {
28872887- // Get property key
28882888 jsoff_t koff = loadoff(js, prop_off + (jsoff_t) sizeof(prop_off));
28892889 jsoff_t klen = offtolen(loadoff(js, koff));
28902890 jsval_t key_str = js_mkstr(js, (char *) &js->mem[koff + sizeof(koff)], klen);
2891289128922892- // Set loop variable to the key
28932892 const char *var_name = &js->code[var_name_off];
28942893 jsoff_t existing = lkp(js, js->scope, var_name, var_name_len);
28952894 if (existing > 0) {
···29022901 }
29032902 }
2904290329052905- // Execute loop body
29062904 js->pos = body_start;
29072905 js->consumed = 1;
29082906 js->flags = (flags & ~F_NOEXEC) | F_LOOP;
···29182916 goto done;
29192917 }
2920291829212921- // Move to next property
29222919 prop_off = loadoff(js, prop_off) & ~(3U | CONSTMASK);
29232920 }
29242921 }
···29292926 goto done;
29302927 }
2931292829322932- // Regular for loop
29332929 if (!expect(js, TOK_SEMICOLON, &res)) goto done;
29342930 js->flags |= F_NOEXEC;
29352931 pos1 = js->pos;
···33293325 case TOK_CASE: case TOK_CATCH:
33303326 case TOK_DEFAULT: case TOK_FINALLY:
33313327 case TOK_SWITCH:
33323332- case TOK_THROW: case TOK_TRY: case TOK_VAR:
33283328+ case TOK_THROW: case TOK_TRY:
33333329 case TOK_WITH: case TOK_YIELD:
33343330 res = js_mkerr(js, "'%.*s' not implemented", (int) js->tlen, js->code + js->toff);
33313331+ break;
33323332+ case TOK_VAR:
33333333+ if (!js->var_warning_shown) {
33343334+ fprintf(stderr, "Warning: 'var' is deprecated, use 'let' or 'const' instead\n");
33353335+ js->var_warning_shown = true;
33363336+ }
33373337+ res = js_let(js);
33353338 break;
33363339 case TOK_WHILE: res = js_while(js); break;
33373340 case TOK_DO: res = js_do_while(js); break;
···43274330}
4328433143294332static jsval_t do_in(struct js *js, jsval_t l, jsval_t r) {
43304330- // l should be a string (property name), r should be an object
43314333 if (vtype(l) != T_STR) {
43324334 return js_mkerr(js, "left operand of 'in' must be string");
43334335 }
···43364338 return js_mkerr(js, "right operand of 'in' must be object");
43374339 }
4338434043394339- // Get the property name
43404341 jsoff_t prop_len;
43414342 jsoff_t prop_off = vstr(js, l, &prop_len);
43424343 const char *prop_name = (char *) &js->mem[prop_off];
4343434443444344- // For functions, check the function object
43454345 jsval_t check_obj = r;
43464346 if (vtype(r) == T_FUNC) {
43474347 check_obj = mkval(T_OBJ, vdata(r));
43484348 }
4349434943504350- // Look up the property
43514350 jsoff_t found = lkp(js, check_obj, prop_name, prop_len);
43524352-43534351 return mkval(T_BOOL, found != 0 ? 1 : 0);
43544352}
43554353
+74
tests/test_var.cjs
···11+// Test var keyword (should work like let but show warnings)
22+Ant.println('=== Var Keyword Tests ===');
33+44+// Test 1: Basic var declaration
55+Ant.println('\nTest 1: Basic var declaration');
66+var x = 10;
77+Ant.println('var x = 10: ' + x);
88+99+// Test 2: Var reassignment
1010+Ant.println('\nTest 2: Var reassignment');
1111+var y = 5;
1212+y = y + 10;
1313+Ant.println('var y reassigned: ' + y);
1414+1515+// Test 3: Var in for loop
1616+Ant.println('\nTest 3: Var in for loop');
1717+var sum = 0;
1818+for (var i = 0; i < 5; i = i + 1) {
1919+ sum = sum + i;
2020+}
2121+Ant.println('Sum with var: ' + sum);
2222+2323+// Test 4: Var in for-in loop
2424+Ant.println('\nTest 4: Var in for-in loop');
2525+const obj = { a: 1, b: 2, c: 3 };
2626+var keys = '';
2727+for (var key in obj) {
2828+ keys = keys + key + ',';
2929+}
3030+Ant.println('Keys with var: ' + keys);
3131+3232+// Test 5: Multiple var declarations
3333+Ant.println('\nTest 5: Multiple var declarations');
3434+var a = 1, b = 2, c = 3;
3535+Ant.println('var a, b, c: ' + (a + b + c));
3636+3737+// Test 6: Var in while loop
3838+Ant.println('\nTest 6: Var in while loop');
3939+var count = 0;
4040+while (count < 3) {
4141+ count = count + 1;
4242+}
4343+Ant.println('While with var: ' + count);
4444+4545+// Test 7: Var with objects
4646+Ant.println('\nTest 7: Var with objects');
4747+var obj2 = { name: 'test', value: 42 };
4848+Ant.println('var object: ' + obj2.name + ' = ' + obj2.value);
4949+5050+// Test 8: Var with arrays
5151+Ant.println('\nTest 8: Var with arrays');
5252+var arr = [10, 20, 30];
5353+Ant.println('var array[1]: ' + arr[1]);
5454+5555+// Test 9: Var in nested scopes
5656+Ant.println('\nTest 9: Var in nested scopes');
5757+var outer = 'outer';
5858+if (true) {
5959+ var inner = 'inner';
6060+ Ant.println('Inner var: ' + inner);
6161+}
6262+Ant.println('Outer var: ' + outer);
6363+6464+// Test 10: Var works like let
6565+Ant.println('\nTest 10: Var behavior like let');
6666+var testVar = 100;
6767+if (testVar > 50) {
6868+ var modified = testVar * 2;
6969+ Ant.println('Modified: ' + modified);
7070+}
7171+Ant.println('Original: ' + testVar);
7272+7373+Ant.println('\n=== All var tests completed ===');
7474+Ant.println('Note: You should see deprecation warnings above');