-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patht.py
110 lines (88 loc) · 2.41 KB
/
t.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
"""
Run the APL-level tests from the file found in
tests/apltests.py
These tests originate from
https://raw.githubusercontent.com/abrudz/ngn-apl/master/t.apl
"""
from apl.arr import Array, match
from apl.errors import SyntaxError, RankError
from apl.parser import Parser
from apl.skalpel import run, Value
from apl.stack import Stack
class TestFailure(Exception):
pass
EXCEPTIONS = {
'RANK ERROR': RankError,
}
SKIP = {
'⍟', '∞', '⍶', '⍹', '⍫', '»', '√'
}
def eval_apl(src: str) -> Array:
parser = Parser()
ast = parser.parse(src)
if ast is None:
raise SyntaxError
code = ast.emit()
if code is None:
raise ValueError
env:dict[str, Value] = {}
stack = Stack()
run(code, env, 0, stack)
return stack.stack[0].payload # type: ignore
def compare(a: str, b: str) -> bool:
try:
result_a = eval_apl(a)
except:
return False
try:
result_b = eval_apl(b)
except:
return False
try:
return match(result_a, result_b)
except:
print(f"Exception thrown for match({a}, {b})")
return False
def compare_throws(a: str, aplerror: Exception) -> bool:
try:
eval_apl(a)
except aplerror: # type: ignore
return True
except:
return False
return False
def main() -> None:
with open('tests/apltests.txt') as f:
# with open('tests/aplbasic.txt') as f:
tests = f.read().splitlines()
failed = []
succeeded = []
for t in tests:
skip = False
for glyph in SKIP:
if glyph in t: # ngn/apl has a few custom glyphs; skip for now
skip = True
break
if skip:
continue
if " ←→ " in t:
data = t.split(" ←→ ")
if not compare(data[0], data[1]):
# raise TestFailure(t)
print(t)
failed.append(t)
else:
succeeded.append(t)
elif " !! " in t:
data = t.split(" !! ")
if data[1] not in EXCEPTIONS:
failed.append(t)
elif not compare_throws(data[0], EXCEPTIONS[data[1]]): # type: ignore
failed.append(t)
else:
succeeded.append(t)
else:
pass
print(f'failed: {len(failed)}\nsucceeded: {len(succeeded)}')
if __name__ == "__main__":
main()