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.

while loops

+484 -3
+147 -3
src/ant.c
··· 128 128 static jsval_t js_stmt(struct js *js); 129 129 static jsval_t js_assignment(struct js *js); 130 130 static jsval_t js_arrow_func(struct js *js, jsoff_t params_start, jsoff_t params_end, bool is_async); 131 + static jsval_t js_while(struct js *js); 132 + static jsval_t js_do_while(struct js *js); 133 + static jsval_t js_block_or_stmt(struct js *js); 131 134 static jsval_t do_op(struct js *, uint8_t op, jsval_t l, jsval_t r); 132 135 static jsval_t do_instanceof(struct js *js, jsval_t l, jsval_t r); 133 136 static jsval_t resolveprop(struct js *js, jsval_t v); ··· 753 756 uint8_t t = js->tok; 754 757 res = js_stmt(js); 755 758 if (!is_err(res) && t != TOK_LBRACE && t != TOK_IF && t != TOK_WHILE && 756 - t != TOK_FUNC && js->tok != TOK_SEMICOLON) { 759 + t != TOK_DO && t != TOK_FUNC && t != TOK_FOR && js->tok != TOK_SEMICOLON) { 757 760 res = js_mkerr(js, "; expected"); 758 761 break; 759 762 } ··· 2863 2866 return res; 2864 2867 } 2865 2868 2869 + static jsval_t js_while(struct js *js) { 2870 + uint8_t flags = js->flags, exe = !(flags & F_NOEXEC); 2871 + jsval_t res = js_mkundef(), v; 2872 + 2873 + js->consumed = 1; 2874 + if (!expect(js, TOK_LPAREN, &res)) return res; 2875 + 2876 + jsoff_t cond_start = js->pos; 2877 + js->flags |= F_NOEXEC; 2878 + v = js_expr(js); 2879 + if (is_err(v)) return v; 2880 + 2881 + if (!expect(js, TOK_RPAREN, &res)) return res; 2882 + 2883 + jsoff_t body_start = js->pos; 2884 + v = js_block_or_stmt(js); 2885 + if (is_err(v)) return v; 2886 + jsoff_t body_end = js->pos; 2887 + 2888 + if (exe) { 2889 + while (true) { 2890 + js->flags = flags; 2891 + js->pos = cond_start; 2892 + js->consumed = 1; 2893 + 2894 + v = resolveprop(js, js_expr(js)); 2895 + if (is_err(v)) { 2896 + res = v; 2897 + break; 2898 + } 2899 + 2900 + if (!js_truthy(js, v)) break; 2901 + 2902 + js->pos = body_start; 2903 + js->consumed = 1; 2904 + js->flags = (flags & ~F_NOEXEC) | F_LOOP; 2905 + 2906 + v = js_block_or_stmt(js); 2907 + if (is_err(v)) { 2908 + res = v; 2909 + break; 2910 + } 2911 + 2912 + if (js->flags & F_BREAK) { 2913 + break; 2914 + } 2915 + 2916 + if (js->flags & F_RETURN) { 2917 + res = v; 2918 + break; 2919 + } 2920 + } 2921 + } 2922 + 2923 + js->pos = body_end; 2924 + js->tok = TOK_SEMICOLON; 2925 + js->consumed = 0; 2926 + 2927 + uint8_t preserve = 0; 2928 + if (js->flags & F_RETURN) { 2929 + preserve = js->flags & (F_RETURN | F_NOEXEC); 2930 + } 2931 + js->flags = flags | preserve; 2932 + 2933 + return res; 2934 + } 2935 + 2936 + static jsval_t js_do_while(struct js *js) { 2937 + uint8_t flags = js->flags, exe = !(flags & F_NOEXEC); 2938 + jsval_t res = js_mkundef(), v; 2939 + 2940 + js->consumed = 1; 2941 + 2942 + jsoff_t body_start = js->pos; 2943 + bool is_block = (next(js) == TOK_LBRACE); 2944 + js->flags |= F_NOEXEC; 2945 + v = js_block_or_stmt(js); 2946 + if (is_err(v)) return v; 2947 + 2948 + if (is_block && next(js) == TOK_RBRACE) { 2949 + js->consumed = 1; 2950 + } 2951 + (void) js->pos; 2952 + 2953 + if (!expect(js, TOK_WHILE, &res)) return res; 2954 + if (!expect(js, TOK_LPAREN, &res)) return res; 2955 + 2956 + jsoff_t cond_start = js->pos; 2957 + v = js_expr(js); 2958 + if (is_err(v)) return v; 2959 + 2960 + if (!expect(js, TOK_RPAREN, &res)) return res; 2961 + jsoff_t cond_end = js->pos; 2962 + 2963 + if (exe) { 2964 + do { 2965 + js->pos = body_start; 2966 + js->consumed = 1; 2967 + js->flags = (flags & ~F_NOEXEC) | F_LOOP; 2968 + 2969 + v = js_block_or_stmt(js); 2970 + if (is_err(v)) { 2971 + res = v; 2972 + break; 2973 + } 2974 + 2975 + if (js->flags & F_BREAK) { 2976 + break; 2977 + } 2978 + 2979 + if (js->flags & F_RETURN) { 2980 + res = v; 2981 + break; 2982 + } 2983 + 2984 + js->flags = flags; 2985 + js->pos = cond_start; 2986 + js->consumed = 1; 2987 + 2988 + v = resolveprop(js, js_expr(js)); 2989 + if (is_err(v)) { 2990 + res = v; 2991 + break; 2992 + } 2993 + } while (js_truthy(js, v)); 2994 + } 2995 + 2996 + js->pos = cond_end; 2997 + js->consumed = 1; 2998 + 2999 + uint8_t preserve = 0; 3000 + if (js->flags & F_RETURN) { 3001 + preserve = js->flags & (F_RETURN | F_NOEXEC); 3002 + } 3003 + js->flags = flags | preserve; 3004 + 3005 + return res; 3006 + } 3007 + 2866 3008 static jsval_t js_break(struct js *js) { 2867 3009 if (js->flags & F_NOEXEC) { 2868 3010 } else { ··· 3071 3213 3072 3214 switch (next(js)) { 3073 3215 case TOK_CASE: case TOK_CATCH: 3074 - case TOK_DEFAULT: case TOK_DO: case TOK_FINALLY: 3216 + case TOK_DEFAULT: case TOK_FINALLY: 3075 3217 case TOK_IN: case TOK_SWITCH: 3076 3218 case TOK_THROW: case TOK_TRY: case TOK_VAR: 3077 - case TOK_WITH: case TOK_WHILE: case TOK_YIELD: 3219 + case TOK_WITH: case TOK_YIELD: 3078 3220 res = js_mkerr(js, "'%.*s' not implemented", (int) js->tlen, js->code + js->toff); 3079 3221 break; 3222 + case TOK_WHILE: res = js_while(js); break; 3223 + case TOK_DO: res = js_do_while(js); break; 3080 3224 case TOK_CONTINUE: res = js_continue(js); break; 3081 3225 case TOK_BREAK: res = js_break(js); break; 3082 3226 case TOK_LET: res = js_let(js); break;
+140
tests/test_async_loops.cjs
··· 1 + // Test async/await with loops 2 + Ant.println('=== Async/Await with Loops Tests ==='); 3 + 4 + // Test 1: Await in for loop 5 + Ant.println('\nTest 1: Await in for loop'); 6 + async function test1() { 7 + let sum = 0; 8 + for (let i = 0; i < 3; i = i + 1) { 9 + const val = await Promise.resolve(i); 10 + sum = sum + val; 11 + } 12 + return sum; 13 + } 14 + test1().then(v => Ant.println('Test 1: ' + v)); 15 + 16 + // Test 2: Await in while loop 17 + Ant.println('\nTest 2: Await in while loop'); 18 + async function test2() { 19 + let i = 0; 20 + let sum = 0; 21 + while (i < 3) { 22 + const val = await Promise.resolve(i); 23 + sum = sum + val; 24 + i = i + 1; 25 + } 26 + return sum; 27 + } 28 + test2().then(v => Ant.println('Test 2: ' + v)); 29 + 30 + // Test 3: Await in do-while loop 31 + Ant.println('\nTest 3: Await in do-while loop'); 32 + async function test3() { 33 + let i = 0; 34 + let sum = 0; 35 + do { 36 + const val = await Promise.resolve(i); 37 + sum = sum + val; 38 + i = i + 1; 39 + } while (i < 3); 40 + return sum; 41 + } 42 + test3().then(v => Ant.println('Test 3: ' + v)); 43 + 44 + // Test 4: Multiple awaits in loop 45 + Ant.println('\nTest 4: Multiple awaits in loop'); 46 + async function test4() { 47 + let result = 0; 48 + for (let i = 0; i < 2; i = i + 1) { 49 + const a = await Promise.resolve(i); 50 + const b = await Promise.resolve(i + 10); 51 + result = result + a + b; 52 + } 53 + return result; 54 + } 55 + test4().then(v => Ant.println('Test 4: ' + v)); 56 + 57 + // Test 5: Await with break 58 + Ant.println('\nTest 5: Await with break'); 59 + async function test5() { 60 + let i = 0; 61 + while (i < 10) { 62 + const val = await Promise.resolve(i); 63 + if (val === 3) { 64 + break; 65 + } 66 + i = i + 1; 67 + } 68 + return i; 69 + } 70 + test5().then(v => Ant.println('Test 5: ' + v)); 71 + 72 + // Test 6: Await with continue 73 + Ant.println('\nTest 6: Await with continue'); 74 + async function test6() { 75 + let sum = 0; 76 + for (let i = 0; i < 5; i = i + 1) { 77 + const val = await Promise.resolve(i); 78 + if (val % 2 === 0) { 79 + continue; 80 + } 81 + sum = sum + val; 82 + } 83 + return sum; 84 + } 85 + test6().then(v => Ant.println('Test 6: ' + v)); 86 + 87 + // Test 7: Nested loops with await 88 + Ant.println('\nTest 7: Nested loops with await'); 89 + async function test7() { 90 + let count = 0; 91 + for (let i = 0; i < 2; i = i + 1) { 92 + for (let j = 0; j < 2; j = j + 1) { 93 + const val = await Promise.resolve(1); 94 + count = count + val; 95 + } 96 + } 97 + return count; 98 + } 99 + test7().then(v => Ant.println('Test 7: ' + v)); 100 + 101 + // Test 8: While loop with async condition check 102 + Ant.println('\nTest 8: While loop awaiting values'); 103 + async function test8() { 104 + let i = 0; 105 + let product = 1; 106 + while (i < 3) { 107 + const multiplier = await Promise.resolve(2); 108 + product = product * multiplier; 109 + i = i + 1; 110 + } 111 + return product; 112 + } 113 + test8().then(v => Ant.println('Test 8: ' + v)); 114 + 115 + // Test 9: Do-while with await and condition 116 + Ant.println('\nTest 9: Do-while with await'); 117 + async function test9() { 118 + let count = 0; 119 + let val; 120 + do { 121 + val = await Promise.resolve(count); 122 + count = count + 1; 123 + } while (val < 2); 124 + return count; 125 + } 126 + test9().then(v => Ant.println('Test 9: ' + v)); 127 + 128 + // Test 10: For loop building array with await 129 + Ant.println('\nTest 10: Building array with await in loop'); 130 + async function test10() { 131 + const arr = []; 132 + for (let i = 0; i < 3; i = i + 1) { 133 + const val = await Promise.resolve(i * 2); 134 + arr[i] = val; 135 + } 136 + return arr[0] + arr[1] + arr[2]; 137 + } 138 + test10().then(v => Ant.println('Test 10: ' + v)); 139 + 140 + Ant.println('\n=== All async loop tests initiated ===');
+197
tests/test_loops.cjs
··· 1 + // Test all loop types: for, while, do-while 2 + Ant.println('=== Loop Tests ==='); 3 + 4 + // Test 1: Basic while loop 5 + Ant.println('\nTest 1: Basic while loop'); 6 + let i = 0; 7 + let sum = 0; 8 + while (i < 5) { 9 + sum = sum + i; 10 + i = i + 1; 11 + } 12 + Ant.println('While loop sum (0-4): ' + sum); 13 + 14 + // Test 2: While loop with break 15 + Ant.println('\nTest 2: While loop with break'); 16 + let count = 0; 17 + while (count < 10) { 18 + if (count === 5) { 19 + break; 20 + } 21 + count = count + 1; 22 + } 23 + Ant.println('While with break, count: ' + count); 24 + 25 + // Test 3: While loop with continue 26 + Ant.println('\nTest 3: While loop with continue'); 27 + let j = 0; 28 + let evenSum = 0; 29 + while (j < 10) { 30 + j = j + 1; 31 + if (j % 2 === 1) { 32 + continue; 33 + } 34 + evenSum = evenSum + j; 35 + } 36 + Ant.println('Even sum (2,4,6,8,10): ' + evenSum); 37 + 38 + // Test 4: Basic do-while loop 39 + Ant.println('\nTest 4: Basic do-while loop'); 40 + let k = 0; 41 + let result = 0; 42 + do { 43 + result = result + k; 44 + k = k + 1; 45 + } while (k < 5); 46 + Ant.println('Do-while sum (0-4): ' + result); 47 + 48 + // Test 5: Do-while executes at least once 49 + Ant.println('\nTest 5: Do-while executes at least once'); 50 + let executed = false; 51 + do { 52 + executed = true; 53 + Ant.println('Do-while executed even when condition is false'); 54 + } while (false); 55 + 56 + // Test 6: Do-while with break 57 + Ant.println('\nTest 6: Do-while with break'); 58 + let n = 0; 59 + do { 60 + n = n + 1; 61 + if (n === 3) { 62 + break; 63 + } 64 + } while (n < 10); 65 + Ant.println('Do-while with break, n: ' + n); 66 + 67 + // Test 7: Do-while with continue 68 + Ant.println('\nTest 7: Do-while with continue'); 69 + let m = 0; 70 + let oddSum = 0; 71 + do { 72 + m = m + 1; 73 + if (m % 2 === 0) { 74 + continue; 75 + } 76 + oddSum = oddSum + m; 77 + } while (m < 9); 78 + Ant.println('Odd sum (1,3,5,7,9): ' + oddSum); 79 + 80 + // Test 8: For loop basic 81 + Ant.println('\nTest 8: For loop basic'); 82 + let forSum = 0; 83 + for (let x = 0; x < 5; x = x + 1) { 84 + forSum = forSum + x; 85 + } 86 + Ant.println('For loop sum (0-4): ' + forSum); 87 + 88 + // Test 9: For loop with break 89 + Ant.println('\nTest 9: For loop with break'); 90 + let breakCount = 0; 91 + for (let y = 0; y < 10; y = y + 1) { 92 + if (y === 5) { 93 + break; 94 + } 95 + breakCount = breakCount + 1; 96 + } 97 + Ant.println('For loop with break, count: ' + breakCount); 98 + 99 + // Test 10: For loop with continue 100 + Ant.println('\nTest 10: For loop with continue'); 101 + let skipSum = 0; 102 + for (let z = 0; z < 10; z = z + 1) { 103 + if (z % 2 === 0) { 104 + continue; 105 + } 106 + skipSum = skipSum + z; 107 + } 108 + Ant.println('For loop skip evens (1+3+5+7+9): ' + skipSum); 109 + 110 + // Test 11: Nested while loops 111 + Ant.println('\nTest 11: Nested while loops'); 112 + let outer = 0; 113 + let nestedSum = 0; 114 + while (outer < 3) { 115 + let inner = 0; 116 + while (inner < 3) { 117 + nestedSum = nestedSum + 1; 118 + inner = inner + 1; 119 + } 120 + outer = outer + 1; 121 + } 122 + Ant.println('Nested while loops, count: ' + nestedSum); 123 + 124 + // Test 12: Nested for loops 125 + Ant.println('\nTest 12: Nested for loops'); 126 + let product = 0; 127 + for (let a = 1; a <= 3; a = a + 1) { 128 + for (let b = 1; b <= 3; b = b + 1) { 129 + product = a * b; 130 + } 131 + } 132 + Ant.println('Last nested for product: ' + product); 133 + 134 + // Test 13: While with complex condition 135 + Ant.println('\nTest 13: While with complex condition'); 136 + let p = 0; 137 + let q = 10; 138 + while (p < 5 && q > 5) { 139 + p = p + 1; 140 + q = q - 1; 141 + } 142 + Ant.println('Complex while, p: ' + p + ', q: ' + q); 143 + 144 + // Test 14: For loop with let declaration 145 + Ant.println('\nTest 14: For loop with let'); 146 + for (let temp = 0; temp < 3; temp = temp + 1) { 147 + Ant.println('For loop iteration: ' + temp); 148 + } 149 + 150 + // Test 15: While loop with single statement 151 + Ant.println('\nTest 15: While with single statement'); 152 + let single = 0; 153 + while (single < 3) single = single + 1; 154 + Ant.println('Single statement while: ' + single); 155 + 156 + // Test 16: Do-while with single statement (in block) 157 + Ant.println('\nTest 16: Do-while with single statement'); 158 + let singleDo = 0; 159 + do { singleDo = singleDo + 1; } while (singleDo < 3); 160 + Ant.println('Single statement do-while: ' + singleDo); 161 + 162 + // Test 17: Empty while loop 163 + Ant.println('\nTest 17: Empty while loop'); 164 + let empty = 5; 165 + while (empty < 5) { 166 + Ant.println('Should not print'); 167 + } 168 + Ant.println('Empty while executed: no output above'); 169 + 170 + // Test 18: For loop with const 171 + Ant.println('\nTest 18: For loop counting down'); 172 + let countdown = 0; 173 + for (let val = 5; val > 0; val = val - 1) { 174 + countdown = countdown + val; 175 + } 176 + Ant.println('Countdown sum (5+4+3+2+1): ' + countdown); 177 + 178 + // Test 19: While loop with array 179 + Ant.println('\nTest 19: While loop with array'); 180 + const arr = [10, 20, 30]; 181 + let idx = 0; 182 + let arrSum = 0; 183 + while (idx < arr.length) { 184 + arrSum = arrSum + arr[idx]; 185 + idx = idx + 1; 186 + } 187 + Ant.println('Array sum via while: ' + arrSum); 188 + 189 + // Test 20: Do-while minimal 190 + Ant.println('\nTest 20: Do-while minimal'); 191 + let minimal = 0; 192 + do { 193 + minimal = minimal + 1; 194 + } while (minimal < 1); 195 + Ant.println('Minimal do-while: ' + minimal); 196 + 197 + Ant.println('\n=== All loop tests completed ===');