Skip to content

Commit 52e8f6d

Browse files
committed
some play with type checking
1 parent 3d87b45 commit 52e8f6d

File tree

2 files changed

+279
-70
lines changed

2 files changed

+279
-70
lines changed

tests/playTypes_test.js

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
const r = require('ramda');
2+
const parse = require('../dist/index').parse;
3+
const interpreter = require('../dist/index').interpreter;
4+
const preProcessDefs = require('../dist/index').preProcessDefines;
5+
const purr = require('../dist/index').purr;
6+
7+
const runDebug = (p, logLevel = 10, wd = {}) => {
8+
const test2 = interpreter(p, { logLevel, wd });
9+
let result2 = test2.next();
10+
console.error(result2.value);
11+
while (result2.value && result2.value.active) {
12+
result2 = test2.next();
13+
console.error(result2.value);
14+
}
15+
return result2.value.stack;
16+
};
17+
18+
const testIt = (p, expected_result, dict) => {
19+
let pp;
20+
try {
21+
pp = parse(p);
22+
}
23+
catch (e) {
24+
console.error("parse error:", p);
25+
return false;
26+
}
27+
if (!pp) {
28+
console.error("no parse result:", p);
29+
return false;
30+
}
31+
let wd;
32+
try {
33+
[pp, wd] = preProcessDefs(pp, dict);
34+
}
35+
catch (e) {
36+
console.error("preProcessDefs error:", p);
37+
return false;
38+
}
39+
if (!wd) {
40+
console.error("no preProcessDefs result:", p);
41+
return false;
42+
}
43+
const itest = interpreter(p, {wd});
44+
let iresult = itest.next();
45+
while (iresult.value && iresult.value.active) {
46+
iresult = itest.next();
47+
}
48+
const str_exp = JSON.stringify(expected_result);
49+
const str_res = JSON.stringify(iresult.value ? iresult.value.stack : "error");
50+
if (str_exp === str_res) {
51+
try {
52+
const ptest = purr(pp, wd);
53+
if (!ptest) {
54+
console.error("purr null result:", test);
55+
return false;
56+
}
57+
let presult = ptest.next();
58+
while (presult.value && presult.value.active) {
59+
presult = ptest.next();
60+
}
61+
const str_exp2 = JSON.stringify(expected_result);
62+
const str_res2 = JSON.stringify(presult.value ? presult.value.stack : "error");
63+
if (str_exp2 === str_res2) {
64+
return true;
65+
}
66+
}
67+
catch (e) {
68+
console.error("purr error:", e, p);
69+
return false;
70+
}
71+
}
72+
73+
console.error("failed test for:", p);
74+
console.error("Expected result", str_exp);
75+
console.error("Erroneously got", str_res);
76+
console.error("Re running in debug mode:");
77+
const result2 = runDebug(p, 2, wd);
78+
console.error(result2 ? result2 : "error", "!=", expected_result);
79+
80+
return false;
81+
};
82+
83+
let allPassing = 1;
84+
85+
// test playType dictionaries
86+
const program0 = "t-number t-string swap t-number + ";
87+
const parsedProgram0 = parse(program0);
88+
const customWords0 = {
89+
'times': {
90+
compose: (s, pl) => {
91+
const c = s.pop();
92+
const phrase = s.pop();
93+
if (c === 't-number' && phrase) {
94+
s.push(phrase);
95+
pl.unshift('play');
96+
}
97+
else if (c === 't-number' && !phrase) {
98+
s.push('-t-phrase');
99+
pl.unshift('play');
100+
}
101+
else if (!c && !phrase) {
102+
s.push('-t-phrase');
103+
s.push('-t-number');
104+
}
105+
else {
106+
s.push("type error at 'times'");
107+
}
108+
return [s, pl];
109+
}
110+
},
111+
'play': {
112+
compose: (s, pl) => {
113+
const block = s.pop();
114+
if (block) {
115+
pl = block.concat(pl);
116+
}
117+
else {
118+
pl.unshift(block);
119+
}
120+
return [s, pl];
121+
}
122+
},
123+
"-t-number": {
124+
compose: (s) => {
125+
const a = s.pop();
126+
if (a !== 't-number') {
127+
s.push('-t-number');
128+
}
129+
return [s];
130+
},
131+
},
132+
"dup": {
133+
compose: (s) => {
134+
const a = s.pop();
135+
s.push(a);
136+
s.push(a);
137+
return [s];
138+
},
139+
},
140+
"swap": {
141+
compose: (s) => {
142+
const a = s.pop();
143+
const b = s.pop();
144+
s.push(a);
145+
s.push(b);
146+
return [s];
147+
}
148+
},
149+
"+": {
150+
compose: (s) => {
151+
const a = s.pop();
152+
const b = s.pop();
153+
if (a === 't-number' && b === 't-number') {
154+
s.push(a);
155+
}
156+
else if (a === 't-number' && !b) {
157+
s.push('-t-number');
158+
}
159+
else if (!a && !b) {
160+
s.push('-t-number');
161+
s.push('-t-number');
162+
}
163+
else {
164+
s.push("type error at '+'");
165+
}
166+
return [s];
167+
},
168+
// sig: [[], [{ type: 'number' }]],
169+
}
170+
};
171+
const [preProcessedProgram0, corePlusUserDefinedWords0] = preProcessDefs(parsedProgram0, customWords0);
172+
const runner0 = interpreter(preProcessedProgram0, { wd: corePlusUserDefinedWords0 });
173+
const result0 = runner0.next();
174+
if (!(result0.value.active === false && result0.value.stack[0] === 't-string' && result0.value.stack[1] === 't-number')) {
175+
console.log("hmmm", result0.value.stack);
176+
}
177+
allPassing &= (result0.value.active === false && result0.value.stack[0] === 't-string' && result0.value.stack[1] === 't-number');
178+
179+
180+
// set up a production configuration and test purr
181+
const program1 = `t-number increment increment
182+
[t-number +] [increment] compose `;
183+
const parsedProgram1 = parse(program1);
184+
const [preProcessedProgram1, corePlusUserDefinedWords1] = preProcessDefs(parsedProgram1, customWords0);
185+
const runner1 = purr(preProcessedProgram1, corePlusUserDefinedWords1);
186+
const result1 = runner1.next();
187+
allPassing &= (result1.value.active === false && result1.value.stack[0] === 't-number');
188+
189+
allPassing &= testIt("t-number t-number +", ['t-number'], customWords0);
190+
allPassing &= testIt("t-number +", ['-t-number'], customWords0);
191+
allPassing &= testIt("+", ['-t-number','-t-number'], customWords0);
192+
allPassing &= testIt("t-number t-string swap t-number +", ['t-string', 't-number'], customWords0);
193+
allPassing &= testIt("t-number t-number [+] play", ['t-number'], customWords0);
194+
allPassing &= testIt("t-string t-number t-number [+ swap] play", ['t-number', 't-string'], customWords0);
195+
allPassing &= testIt('t-number t-number [[[+] play] play] play', ["t-number"], customWords0);
196+
allPassing &= testIt('t-number [[t-number [+] play] play] play', ["t-number"], customWords0);
197+
allPassing &= testIt('[t-number [[+] play] play] play', ["-t-number"], customWords0);
198+
allPassing &= testIt('t-number t-number -t-number', ["t-number"], customWords0);
199+
allPassing &= testIt('t-number [dup +] t-number times', ["t-number"], customWords0);
200+
allPassing &= testIt('t-number [dup dup +] t-number times', ["t-number", "t-number"], customWords0);
201+
202+
203+
console.log("playType Tests Pass:", allPassing === 1);
204+
205+
// runDebug(`
206+
// [3 8 5 7 10 2 9 1] [2 % 0 !=] filter
207+
// `, 1, someWD);

tests/typecheck_test.js

Lines changed: 72 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -4,77 +4,79 @@ const coreWords = require('../dist/index').coreWordDictionary;
44

55

66
let tests = [
7-
['2', ["number_t"]],
8-
['true', ["boolean_t"]],
9-
['false', ["boolean_t"]],
10-
['"abc"', ["string_t"]],
11-
['2 3 +', ["number_t"]],
12-
['2 3 + -4 +', ["number_t"]],
13-
// // ['2 abc +', [{"error":"An unexpected stack type of 'string' was encountered!","expectedType":"number","encounteredType":"string"}]],
14-
// // ['twelve 12 +', [{"error":"An unexpected stack type of 'string' was encountered!","expectedType":"number","encounteredType":"string"}]],
15-
['hello world', ["string_t","string_t"]],
16-
['"hello world"', ["string_t"]],
17-
['2 3 -', ["number_t"]],
18-
// // ['2 abc -', [{"error":"An unexpected stack type of 'string' was encountered!","expectedType":"number","encounteredType":"string"}]],
19-
// // ['twelve 12 -', [{"error":"An unexpected stack type of 'string' was encountered!","expectedType":"number","encounteredType":"string"}]],
20-
['2 3 *', ["number_t"]],
21-
['2 3 * 6 -', ["number_t"]],
22-
// // ['2 abc *', [{"error":"An unexpected stack type of 'string' was encountered!","expectedType":"number","encounteredType":"string"}]],
23-
// // ['twelve 12 *', [{"error":"An unexpected stack type of 'string' was encountered!","expectedType":"number","encounteredType":"string"}]],
24-
['2 3 /', ["number_t"]],
25-
// // ['2 abc /', [{"error":"An unexpected stack type of 'string' was encountered!","expectedType":"number","encounteredType":"string"}]],
26-
// // ['twelve 12 /', [{"error":"An unexpected stack type of 'string' was encountered!","expectedType":"number","encounteredType":"string"}]],
27-
// // ['2 0 /', [{"error":"Guard found that the static value 0 failed to pass its requirement [0 !=]"}]],
28-
['[]', [[]]],
29-
['[][]', [[],[]]],
30-
['[2 4 7]', [["number_t","number_t","number_t"]]],
31-
['[[]]', [[[]]]],
32-
['[[[]]]', [[[[]]]]],
33-
['[a[b b2]]', [["string_t", ["string_t", "string_t"]]]],
34-
['[a[b b2]] 7', [["string_t", ["string_t", "string_t"]],"number_t"]],
35-
['[a[b b2[c c2]d]e]', [["string_t", ["string_t", "string_t", ["string_t", "string_t"], "string_t"], "string_t"]]],
36-
['[a[b b2]c c2[d]e]', [["string_t", ["string_t", "string_t"], "string_t", "string_t", ["string_t"], "string_t"]]],
37-
['a 2 swap', ["number_t","string_t"]],
38-
['a 2 swap dup', ["number_t","string_t","string_t"]],
39-
['[a] 2 swap dup', ["number_t",["string_t"],["string_t"]]],
40-
['3 2 a [+] dip', ["number_t","string_t"]],
41-
['3 a [2 +] dip', ["number_t","string_t"]],
42-
['d 2 a [swap] dip', ["number_t","string_t","string_t"]],
7+
// ['2', ["number_t"]],
8+
// ['true', ["boolean_t"]],
9+
// ['false', ["boolean_t"]],
10+
// ['"abc"', ["string_t"]],
11+
// ['2 3 +', ["number_t"]],
12+
// ['2 3 + -4 +', ["number_t"]],
13+
// // // ['2 abc +', [{"error":"An unexpected stack type of 'string' was encountered!","expectedType":"number","encounteredType":"string"}]],
14+
// // // ['twelve 12 +', [{"error":"An unexpected stack type of 'string' was encountered!","expectedType":"number","encounteredType":"string"}]],
15+
// ['hello world', ["string_t","string_t"]],
16+
// ['"hello world"', ["string_t"]],
17+
// ['2 3 -', ["number_t"]],
18+
// // // ['2 abc -', [{"error":"An unexpected stack type of 'string' was encountered!","expectedType":"number","encounteredType":"string"}]],
19+
// // // ['twelve 12 -', [{"error":"An unexpected stack type of 'string' was encountered!","expectedType":"number","encounteredType":"string"}]],
20+
// ['2 3 *', ["number_t"]],
21+
// ['2 3 * 6 -', ["number_t"]],
22+
// // // ['2 abc *', [{"error":"An unexpected stack type of 'string' was encountered!","expectedType":"number","encounteredType":"string"}]],
23+
// // // ['twelve 12 *', [{"error":"An unexpected stack type of 'string' was encountered!","expectedType":"number","encounteredType":"string"}]],
24+
// ['2 3 /', ["number_t"]],
25+
// // // ['2 abc /', [{"error":"An unexpected stack type of 'string' was encountered!","expectedType":"number","encounteredType":"string"}]],
26+
// // // ['twelve 12 /', [{"error":"An unexpected stack type of 'string' was encountered!","expectedType":"number","encounteredType":"string"}]],
27+
// // // ['2 0 /', [{"error":"Guard found that the static value 0 failed to pass its requirement [0 !=]"}]],
28+
// ['[]', [[]]],
29+
// ['[][]', [[],[]]],
30+
// ['[2 4 7]', [["number_t","number_t","number_t"]]],
31+
// ['[[]]', [[[]]]],
32+
// ['[[[]]]', [[[[]]]]],
33+
// ['[a[b b2]]', [["string_t", ["string_t", "string_t"]]]],
34+
// ['[a[b b2]] 7', [["string_t", ["string_t", "string_t"]],"number_t"]],
35+
// ['[a[b b2[c c2]d]e]', [["string_t", ["string_t", "string_t", ["string_t", "string_t"], "string_t"], "string_t"]]],
36+
// ['[a[b b2]c c2[d]e]', [["string_t", ["string_t", "string_t"], "string_t", "string_t", ["string_t"], "string_t"]]],
37+
// ['a 2 swap', ["number_t","string_t"]],
38+
// ['a 2 swap dup', ["number_t","string_t","string_t"]],
39+
// ['[a] 2 swap dup', ["number_t",["string_t"],["string_t"]]],
40+
// ['3 2 a [+] dip', ["number_t","string_t"]],
41+
// ['3 a [2 +] dip', ["number_t","string_t"]],
42+
// ['d 2 a [swap] dip', ["number_t","string_t","string_t"]],
4343

44-
['3 2 5 rotate', ["number_t", "number_t", "number_t"]],
45-
['aa cc 3 rotate', ["number_t", "string_t", "string_t"]],
46-
['3 2 "3" rollup', ["string_t", "number_t", "number_t"]],
47-
['a 3.14 "c3p0" rolldown', ["number_t", "string_t", "string_t"]],
48-
['2 a [dup] dip', ["number_t","number_t","string_t"]],
49-
['[a] 3 dup2', [["string_t"],"number_t",["string_t"],"number_t"]],
50-
['a 3 dup2', ["string_t", "number_t","string_t", "number_t"]],
51-
['a 3 drop', ["string_t"]],
52-
['a 3 [drop] dip', ["number_t"]],
53-
['3 3 =', ["number_t","boolean_t"]],
54-
55-
['3 a [3 =] dip', ["number_t","boolean_t","string_t"]],
56-
['a [3 3 =] dip', ["number_t","boolean_t","string_t"]],
57-
['a [3 3 =] dip drop', ["number_t","boolean_t"]],
58-
['5 5 ==', ["boolean_t"]],
59-
// // // ['5 a ==', ["type error in '==' must have matching types: number_t and string_t do not match"]],
60-
['5 a [6 ==] dip', ["boolean_t","string_t"]],
61-
['a [5 5 ==] dip', ["boolean_t","string_t"]],
62-
['2 3 [+] play', ["number_t"]],
63-
['2 3 [[+] play] play', ["number_t"]],
64-
['2 3 [[[+] play] play] play', ["number_t"]],
65-
['2 [3 [[+] play] play] play', ["number_t"]],
66-
['2 [3 [+] play] play', ["number_t"]],
67-
['true [a] [b] if-else', ["string_t"]],
68-
['3 true [1 +] [2 +] if-else', ["number_t"]],
69-
['3 true [2 1 +] [3 2 +] if-else', ["number_t","number_t"]],
70-
['3 true [4 1 +] [2 +] if-else', ["'if-else' type check error: then and else clauses types do not match",["number_t"],["-number_t","number_t"]]],
71-
['true [a] [b] if-else', ["string_t"]],
72-
['[true] [a] [a] ifte', ["string_t"]],
73-
// // ['3 [a b c] [<] split', ["string_t"]],
74-
['2 +', ["-number_t", "number_t"]],
75-
['4 3 true [1 +] [[8 +] dip 5 -] if-else', ["number_t","number_t"]],
76-
['3 a ==', ["'==' type check error: stack elements types do not match",["string_t"],["number_t"]]],
77-
['3 a =', ["'=' type check error: stack elements types do not match",["string_t"],["number_t"]]],
44+
// ['3 2 5 rotate', ["number_t", "number_t", "number_t"]],
45+
// ['aa cc 3 rotate', ["number_t", "string_t", "string_t"]],
46+
// ['3 2 "3" rollup', ["string_t", "number_t", "number_t"]],
47+
// ['a 3.14 "c3p0" rolldown', ["number_t", "string_t", "string_t"]],
48+
// ['2 a [dup] dip', ["number_t","number_t","string_t"]],
49+
// ['[a] 3 dup2', [["string_t"],"number_t",["string_t"],"number_t"]],
50+
// ['a 3 dup2', ["string_t", "number_t","string_t", "number_t"]],
51+
// ['a 3 drop', ["string_t"]],
52+
// ['a 3 [drop] dip', ["number_t"]],
53+
// ['3 3 =', ["number_t","boolean_t"]],
54+
55+
// ['3 a [3 =] dip', ["number_t","boolean_t","string_t"]],
56+
// ['a [3 3 =] dip', ["number_t","boolean_t","string_t"]],
57+
// ['a [3 3 =] dip drop', ["number_t","boolean_t"]],
58+
// ['5 5 ==', ["boolean_t"]],
59+
// // // // ['5 a ==', ["type error in '==' must have matching types: number_t and string_t do not match"]],
60+
// ['5 a [6 ==] dip', ["boolean_t","string_t"]],
61+
// ['a [5 5 ==] dip', ["boolean_t","string_t"]],
62+
// ['2 3 [+] play', ["number_t"]],
63+
// ['2 3 [[+] play] play', ["number_t"]],
64+
// ['2 3 [[[+] play] play] play', ["number_t"]],
65+
// ['2 [3 [[+] play] play] play', ["number_t"]],
66+
// ['2 [3 [+] play] play', ["number_t"]],
67+
// ['true [a] [b] if-else', ["string_t"]],
68+
// ['3 true [1 +] [2 +] if-else', ["number_t"]],
69+
// ['3 true [2 1 +] [3 2 +] if-else', ["number_t","number_t"]],
70+
// ['3 true [4 1 +] [2 +] if-else', ["'if-else' type check error: then and else clauses types do not match",["number_t"],["-number_t","number_t"]]],
71+
// ['true [a] [b] if-else', ["string_t"]],
72+
// ['[true] [a] [a] ifte', ["string_t"]],
73+
// ['2 +', ["-number_t", "number_t"]],
74+
// ['4 3 true [1 +] [[8 +] dip 5 -] if-else', ["number_t","number_t"]],
75+
// ['3 a ==', ["'==' type check error: stack elements types do not match",["string_t"],["number_t"]]],
76+
// ['3 a =', ["'=' type check error: stack elements types do not match",["string_t"],["number_t"]]],
77+
// ['true a 3 [drop] dip2', ["string_t", "number_t"]],
78+
['0 1 [dup2 +] 5 times', [["*number_t"]]],
79+
// ['6 [3 8 5 7 10 2 9 1] [>] split', [["*number_t"],["*number_t"]]],
7880

7981
];
8082

0 commit comments

Comments
 (0)