MIRROR: javascript for 馃悳's, a tiny runtime with big ambitions
1import { test, summary } from './helpers.js';
2
3console.log('TCO Bracket Edge Cases\n');
4
5function indexCallResult(n) {
6 if (n <= 0) return [42];
7 return indexCallResult(n - 1);
8}
9test('f() then index (small)', indexCallResult(5)[0], 42);
10
11function indexByCall(n) {
12 if (n <= 0) return [99];
13 return indexByCall(n - 1);
14}
15function zeroFn() {
16 return 0;
17}
18test('f()[g()] (small)', indexByCall(3)[zeroFn()], 99);
19
20function returnBracketAccess(arr) {
21 return arr[0];
22}
23test('bare bracket access', returnBracketAccess([7]), 7);
24
25function indexArrByCall(arr) {
26 return arr[zeroFn()];
27}
28test('arr[f()] access', indexArrByCall([55]), 55);
29
30const methods = {
31 greet() {
32 return 'hello';
33 },
34 farewell() {
35 return 'bye';
36 }
37};
38function computedCall(key) {
39 return methods[key]();
40}
41test('obj[key]() simple', computedCall('greet'), 'hello');
42test('obj[key]() simple 2', computedCall('farewell'), 'bye');
43
44const ops = {
45 dec(n) {
46 return recurseViaComputed(n - 1);
47 }
48};
49function recurseViaComputed(n) {
50 if (n <= 0) return 'done';
51 return ops['dec'](n);
52}
53test('obj[key]() deep recursion', recurseViaComputed(100000), 'done');
54
55function callWithBracketArg(arr) {
56 return identity(arr[0]);
57}
58function identity(x) {
59 return x;
60}
61test('f(a[0]) bracket in arg', callWithBracketArg([33]), 33);
62
63function callWithBracketBinopArg(arr) {
64 return identity(arr[0] + arr[1]);
65}
66test('f(a[0]+a[1]) binop inside args', callWithBracketBinopArg([10, 20]), 30);
67
68function recurseWithBracketArg(arr, i) {
69 if (i >= arr.length) return 0;
70 return recurseWithBracketArg(arr, i + 1);
71}
72test('deep with bracket arg', recurseWithBracketArg(new Array(100000), 0), 0);
73
74const handlers = {};
75for (let i = 0; i < 10; i++) {
76 handlers['h' + i] = function (n) {
77 if (n <= 0) return 'handled';
78 return handlers['h' + i](n - 1);
79 };
80}
81test('obj[key+expr]() result', handlers['h0'](50), 'handled');
82
83const dispatch = {
84 action_run(n) {
85 if (n <= 0) return 'ran';
86 return dispatch['action' + '_' + 'run'](n - 1);
87 }
88};
89test('obj[a+b]() deep (may fail without bracket fix)', dispatch['action_run'](100000), 'ran');
90
91const table = [];
92for (let i = 0; i < 20; i++) {
93 table[i] = function () {
94 return i;
95 };
96}
97function callFromTable(a) {
98 return table[a * 2 + 1]();
99}
100test('table[a*2+1]() computed', callFromTable(3), 7);
101
102function ternaryBracket(arr, flag) {
103 return flag ? identity(arr[0]) : identity(arr[1]);
104}
105test('ternary with bracket args true', ternaryBracket([10, 20], true), 10);
106test('ternary with bracket args false', ternaryBracket([10, 20], false), 20);
107
108function ternaryComputedVsPlain(flag, n) {
109 if (n <= 0) return 'end';
110 return flag ? ops['dec'](n) : ternaryComputedVsPlain(flag, n - 1);
111}
112test('ternary computed vs plain', ternaryComputedVsPlain(false, 100000), 'end');
113
114summary();