-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathop_type.py
100 lines (87 loc) · 2.5 KB
/
op_type.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
"""Built-in type/attribute/conversion operators for Stilted."""
import string
from error import Tilted
from evaluate import operator, Engine
from dtypes import (
from_py, typecheck,
Integer, Name, Number, Object, Real, String,
)
from lex import lexer
from util import rangecheck
@operator
def cvi(engine: Engine) -> None:
obj = engine.opop()
if isinstance(obj, String):
obj = next(iter(lexer.tokens(obj.str_value)))
match obj:
case Integer():
val: Object = obj
case Real():
val = from_py(int(obj.value))
case _:
print(f"{obj=}")
raise Tilted("typecheck")
engine.opush(val)
@operator
def cvlit(engine: Engine) -> None:
engine.otop().literal = True
@operator
def cvn(engine: Engine) -> None:
s = engine.opop(String)
engine.opush(Name(literal=s.literal, value=s.str_value))
@operator
def cvr(engine: Engine) -> None:
obj = engine.opop()
match obj:
case Integer() | Real() | String():
try:
val = float(obj.value)
except ValueError:
raise Tilted("undefinedresult")
engine.opush(from_py(val))
case _:
raise Tilted("typecheck")
DIGITS = (string.digits + string.ascii_uppercase).encode("ascii")
@operator
def cvrs(engine: Engine) -> None:
num, radix, s = engine.opopn(3)
typecheck(Number, num)
typecheck(Integer, radix)
typecheck(String, s)
radixv = radix.value
rangecheck(2, radixv, 36)
if radixv == 10:
res = num.op_eq().encode("ascii")
else:
n = int(num.value) % 2**32
res = []
while True:
n, digit = divmod(n, radixv)
res.append(DIGITS[digit])
if n == 0:
break
res = res[::-1]
rangecheck(len(res), s.length)
for i in range(len(res)):
s[i] = res[i]
engine.opush(s.new_sub(0, len(res)))
@operator
def cvs(engine: Engine) -> None:
obj, s = engine.opopn(2)
typecheck(String, s)
eqs = obj.op_eq().encode("iso8859-1")
rangecheck(len(eqs), s.length)
for i in range(len(eqs)):
s[i] = eqs[i]
engine.opush(s.new_sub(0, len(eqs)))
@operator
def cvx(engine: Engine) -> None:
engine.otop().literal = False
@operator("type")
def type_(engine: Engine) -> None:
obj = engine.opop()
engine.opush(Name(literal=False, value=obj.typename + "type"))
@operator
def xcheck(engine: Engine) -> None:
obj = engine.opop()
engine.opush(from_py(not obj.literal))