-
Notifications
You must be signed in to change notification settings - Fork 0
/
stdlib.py
225 lines (187 loc) · 6.38 KB
/
stdlib.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#!/usr/bin/python3
# Slang stdlib
from .ast import Signature, Function, Object, Collection, CallArguments, MultiCollection
from .tokens import *
from utils import *
class Builtin(Signature):
@classitemget
def attrops(cls, optype, attr):
if (optype == '.'):
try: return getattr(cls, attr)()
except AttributeError: raise KeyError()
raise KeyError()
@property
def __reprname__(self):
return first(i.__name__ for i in self.__class__.mro() if i.__name__.startswith('Builtin'))
@property
def typename(self):
return self.__class__.__name__
class BuiltinFunction(Builtin, Function):
def __init__(self):
super().__init__(name=self.__class__.__name__)
class BuiltinObject(Builtin, Object): pass
class BuiltinType(Builtin):
def __eq__(self, x):
return (super().__eq__(x) or issubclass(x.__class__, self.__class__) or issubclass(self.__class__, x.__class__))
@staticitemget
@instantiate
def operators(op, valsig=None, selftype=None):
if (valsig is None):
if (op in operators[9]): return bool # unary `not'
else:
assert (selftype is not None)
if (isinstance(valsig, selftype) and op in operators[8]): return bool # comparisons
if (op in operators[10]+operators[11]+operators[12]): return type(valsig) # binary `and'. `xor', `or'
raise KeyError()
@singleton
class Any(BuiltinType):
def __eq__(self, x):
return True
class auto(BuiltinType): pass
class void(BuiltinType):
@staticitemget
def operators(op, valsig=None):
raise KeyError()
class bool(BuiltinType):
@staticitemget
@instantiate
def operators(op, valsig=None):
try: return BuiltinType.operators(op, valsig=valsig, selftype=bool)
except KeyError: pass
if (valsig is None):
if (op in map(UnaryOperator, '+-~')): return int
if (op == UnaryOperator('!')): return bool
raise KeyError()
class int(BuiltinType):
@staticitemget
@instantiate
def operators(op, valsig=None):
try: return BuiltinType.operators(op, valsig=valsig, selftype=int)
except KeyError: pass
if (valsig is None):
if (op in map(UnaryOperator, '+-~')): return int
if (op == UnaryOperator('!')): return bool
if (isinstance(valsig, (int, float))):
if (op in map(BinaryOperator, ('**', *'+-*%'))): return valsig
if (op in map(BinaryOperator, ('//', '<<', '>>', *'&^|'))): return int
if (op == BinaryOperator('/')): return float
if (isinstance(valsig, int)):
if (op == BinaryOperator('to')): return range
raise KeyError()
class float(BuiltinType):
@staticitemget
@instantiate
def operators(op, valsig=None):
try: return BuiltinType.operators(op, valsig=valsig, selftype=float)
except KeyError: pass
if (valsig is None):
if (op in map(UnaryOperator, '+-')): return float
if (op == UnaryOperator('!')): return bool
if (isinstance(valsig, (int, float))):
if (op in map(BinaryOperator, ('**', *'+-*%'))): return float
if (op == BinaryOperator('/')): return float
if (op == BinaryOperator('//')): return int
raise KeyError()
class str(BuiltinType):
@staticitemget
@instantiate
def operators(op, valsig=None):
try: return BuiltinType.operators(op, valsig=valsig, selftype=str)
except KeyError: pass
if (valsig is not None):
if (isinstance(valsig, (char, str)) and op == BinaryOperator('+')): return str
if (isinstance(valsig, int) and op == BinaryOperator('*')): return str
raise KeyError()
@staticitemget
@instantiate
def itemget(keysig, key):
if (isinstance(keysig, int)): return char
raise KeyError()
class rstrip(BuiltinFunction):
callargssigstr: "rstrip(char)"
@staticmethod
@instantiate
def compatible_call(callarguments, ns):
if (callarguments.kwargs or callarguments.starkwargs): return None
return (None, str())
class count(BuiltinFunction):
callargssig: "count(char)"
@staticmethod
@instantiate
def compatible_call(callarguments, ns):
if (callarguments.kwargs or callarguments.starkwargs): return None
return (None, int())
class char(BuiltinType):
@staticitemget
@instantiate
def operators(op, valsig=None):
try: return BuiltinType.operators(op, valsig=valsig, selftype=char)
except KeyError: pass
if (valsig is not None):
if (isinstance(valsig, str) and op in map(BinaryOperator, ('+', 'in'))): return str
if (isinstance(valsig, int) and op == BinaryOperator('*')): return str
if (isinstance(valsig, (char, int)) and op in map(BinaryOperator, '+-')): return char
raise KeyError()
class i8(int): fmt: 'b'
class u8(int): fmt: 'B'
class i16(int): fmt: 'h'
class u16(int): fmt: 'H'
class i32(int): fmt: 'i'
class u32(int): fmt: 'I'
class i64(int): fmt: 'q'
class u64(int): fmt: 'Q'
#class i128(int): fmt: '
#class u128(int): fmt: '
#class f8(float): fmt: '
#class f16(float): fmt: 'e'
#class f32(float): fmt: 'f'
#class f64(float): fmt: 'd'
#class f128(float): fmt: '
#uf8 = uf16 = uf32 = uf64 = uf128 = float
class range(BuiltinType):
keytype: int
valtype: int
@staticitemget
def operators(op, valsig=None):
raise KeyError()
class iterable(Collection, BuiltinType): pass
class list(iterable):
keytype: int
def __init__(self, *, valtype=Any):
super().__init__(keytype=self.keytype, valtype=valtype)
@staticitemget
def attrops(optype, attr):
if (optype == '.'):
if (attr == 'each'): return _each()
raise KeyError()
class tuple(iterable, MultiCollection):
keytype: int
def __init__(self, *, valtypes=()):
super().__init__(keytype=self.keytype, valtypes=valtypes)
class stdio(BuiltinObject):
class println(BuiltinFunction):
callargssigstr: "println(...)"
@staticmethod
def compatible_call(callarguments, ns):
if (callarguments.kwargs or callarguments.starkwargs): return None
return (None, void())
class _map(BuiltinFunction):
@staticmethod
def compatible_call(callarguments, ns):
if (len(callarguments.args) != 1 or
callarguments.starargs or
callarguments.kwargs or
callarguments.starkwargs): return None
return (None, list(valtype=Any))
class _each(BuiltinFunction):
@staticmethod
def compatible_call(callarguments, ns):
if (len(callarguments.args) != 1 or
callarguments.starargs or
callarguments.kwargs or
callarguments.starkwargs): return None
#fsig = Signature.build(callarguments.args[0], ns)
return (None, list(valtype=Any))
builtin_names = {k: v for i in map(allsubclassdict, Builtin.__subclasses__()) for k, v in i.items()}
builtin_names.update({i: globals()[i] for i in (i+j for j in map(builtins.str, (8, 16, 32, 64, 128)) for i in (*'iuf', 'uf') if i+j in globals())})
# by Sdore, 2020