oppc: decouple call name class
[openpower-isa.git] / src / openpower / oppc / pc_ast.py
1 import copy
2 import dataclasses
3
4
5 class NodeMeta(type):
6 pass
7
8
9 class Node(metaclass=NodeMeta):
10 def __repr__(self):
11 return f"{hex(id(self))}@{self.__class__.__name__}()"
12
13 def __eq__(self, other):
14 if not isinstance(other, self.__class__):
15 return NotImplemented
16 return (hex(id(self)) == id(other))
17
18 def clone(self):
19 return copy.deepcopy(self)
20
21
22 class TokenMeta(NodeMeta):
23 pass
24
25
26 class Token(Node, str, metaclass=TokenMeta):
27 def __new__(cls, value):
28 if isinstance(value, cls):
29 value = str(value)
30 if not isinstance(value, str):
31 raise ValueError(value)
32
33 return super().__new__(cls, value)
34
35 def __str__(self):
36 return super(Node, self).__str__()
37
38 def __hash__(self):
39 return super(Node, self).__hash__()
40
41 def __repr__(self):
42 return f"{hex(id(self))}@{self.__class__.__name__}({str(self)})"
43
44
45 class SequenceMeta(NodeMeta):
46 __typeid__ = Node
47
48 def __new__(metacls, clsname, bases, ns, *, typeid=Node):
49 ns.setdefault("__typeid__", typeid)
50
51 return super().__new__(metacls, clsname, bases, ns)
52
53
54 class Sequence(Node, tuple, metaclass=SequenceMeta):
55 def __new__(cls, iterable=tuple()):
56 def validate(item):
57 if not isinstance(item, cls.__typeid__):
58 raise ValueError(cls, item)
59 return item
60
61 return super().__new__(cls, map(validate, iterable))
62
63 def __hash__(self):
64 return super(Node, self).__hash__()
65
66 def __repr__(self):
67 return f"{hex(id(self))}@{self.__class__.__name__}({repr(list(self))})"
68
69
70 class Scope(Sequence):
71 pass
72
73
74 class Module(Sequence):
75 pass
76
77
78 class DataclassMeta(NodeMeta):
79 def __new__(metacls, clsname, bases, ns):
80 cls = super().__new__(metacls, clsname, bases, ns)
81 wrap = dataclasses.dataclass(init=True, eq=False, unsafe_hash=True, frozen=False)
82 datacls = wrap(cls)
83 origin = datacls.__repr__
84 datacls.__repr__ = lambda self: f"{hex(id(self))}@{origin(self)}"
85
86 return datacls
87
88
89 class Dataclass(Node, metaclass=DataclassMeta):
90 def __post_init__(self):
91 for field in dataclasses.fields(self):
92 key = field.name
93 value = getattr(self, key)
94 if not isinstance(value, field.type):
95 raise ValueError(f"{self.__class__.__name__}.{key}: {value!r}")
96
97 def clone(self, **kwargs):
98 return copy.deepcopy(dataclasses.replace(self, **kwargs))
99
100
101 class LiteralMeta(TokenMeta):
102 def __new__(metacls, clsname, bases, ns, *, choices=()):
103 ns.setdefault("__choices__", choices)
104
105 return super().__new__(metacls, clsname, bases, ns)
106
107 def __iter__(cls):
108 yield from cls.__choices__
109
110
111 class Literal(Token, metaclass=LiteralMeta):
112 __choices__ = ()
113
114 def __new__(cls, value):
115 choices = cls.__choices__
116 if isinstance(value, Token):
117 value = str(value)
118 if choices and value not in choices:
119 raise ValueError(value)
120
121 return super().__new__(cls, value)
122
123
124 class GPR(Literal, choices=("RA", "RB", "RC", "RS", "RSp", "RT", "RTp")):
125 pass
126
127
128 class GPRZero(GPR, choices=("RA", "RB", "RC")):
129 pass
130
131
132 class FPR(Literal, choices=("FPR", "FRA", "FRAp", "FRB", "FRBp", "FRC", "FRS", "FRSp", "FRT", "FRTp")):
133 pass
134
135
136 class CR3(Literal, choices=("BF", "BFA")):
137 pass
138
139
140 class CR5(Literal, choices=("BA", "BB", "BC", "BI", "BT")):
141 pass
142
143
144 class XER(Literal, choices=("OV", "OV32", "CA", "CA32", "SO")):
145 pass
146
147
148 class IntLiteral(Literal):
149 pass
150
151
152 class BinLiteral(IntLiteral):
153 r"""0b[01_]+"""
154 pass
155
156
157 class HexLiteral(IntLiteral):
158 r"""0x[0-9A-Fa-f_]+"""
159 pass
160
161
162 class DecLiteral(IntLiteral):
163 r"""(\d+(\.\d*)?|\.\d+)([eE][-+]? \d+)?"""
164 pass
165
166
167 class Symbol(Token):
168 r"""[A-Za-z_]+[A-Za-z0-9_]*"""
169 pass
170
171
172 class Attribute(Dataclass):
173 name: Symbol
174 subject: Node = Node()
175
176
177 class StringLiteral(Literal):
178 __STRING_ESCAPE = r"""(\\[0-9a-zA-Z._~!=&\^\-\\?'"])"""
179 __STRING_CHAR = (r"""([^"\\\n]|""" + __STRING_ESCAPE + ")")
180 __STRING = ("[\"']" + __STRING_CHAR + "*" + "[\"']")
181
182 __doc__ = __STRING
183
184 def __repr__(self):
185 return f"{hex(id(self))}@{self.__class__.__name__}({self.__str__()!r})"
186
187
188 class Whitespace(Token):
189 r"""[^\S\r\n]+"""
190
191
192 class Linebreak(Token):
193 r"""[\r\n]+"""
194
195
196 class Comment(Token):
197 r"""[ ]*(?:\043|<!--)[^\n]*"""
198 pass
199
200
201 class Indent(Node):
202 pass
203
204
205 class Dedent(Node):
206 pass
207
208
209 class LBracket(Token):
210 r"""\["""
211 pass
212
213
214 class RBracket(Token):
215 r"""\]"""
216 pass
217
218
219 class LParenthesis(Token):
220 r"""\("""
221 pass
222
223
224 class RParenthesis(Token):
225 r"""\)"""
226 pass
227
228
229 class Call(Dataclass):
230 class Name(Symbol):
231 pass
232
233 class Arguments(Sequence):
234 pass
235
236 name: Name
237 args: Arguments
238
239
240 class AssignOp(Token):
241 r"""<-"""
242 pass
243
244
245 class AssignIEAOp(Token):
246 r"""<-iea"""
247 pass
248
249
250 class AssignExpr(Dataclass):
251 lvalue: Node
252 rvalue: Node
253
254
255 class AssignIEAExpr(AssignExpr):
256 lvalue: Node
257 rvalue: Node
258
259
260 class Not(Token):
261 r"""(?:¬|~)"""
262 pass
263
264
265 class Add(Token):
266 r"""\+"""
267 pass
268
269
270 class Sub(Token):
271 r"""\-"""
272 pass
273
274
275 class Plus(Node):
276 pass
277
278
279 class Minus(Node):
280 pass
281
282
283 class Mul(Token):
284 r"""(?:×|\*)"""
285 pass
286
287
288 class MulS(Token):
289 r"""(?:×si|×s|\*si|\*s)"""
290 pass
291
292
293 class MulU(Token):
294 r"""(?:×ui|×u|\*ui|\*u)"""
295 pass
296
297
298 class Div(Token):
299 r"""/"""
300 pass
301
302
303 class DivT(Token):
304 r"""÷"""
305 pass
306
307
308 class Mod(Token):
309 r"""%"""
310 pass
311
312
313 class Sqrt(Token):
314 r"""√"""
315 pass
316
317
318 class Eq(Token):
319 r"""="""
320 pass
321
322
323 class NotEq(Token):
324 r"""(?:≠|!=)"""
325 pass
326
327
328 class Lt(Token):
329 r"""<"""
330 pass
331
332
333 class Le(Token):
334 r"""<="""
335 pass
336
337
338 class Ge(Token):
339 r""">="""
340 pass
341
342
343 class Gt(Token):
344 r""">"""
345 pass
346
347
348 class LtU(Token):
349 r"""<u"""
350 pass
351
352
353 class GtU(Token):
354 r""">u"""
355 pass
356
357
358 class BitAnd(Token):
359 r"""&"""
360 pass
361
362
363 class BitOr(Token):
364 r"""\|"""
365 pass
366
367
368 class BitXor(Token):
369 r"""(?:⊕|≡|\^)"""
370 pass
371
372
373 class UnaryExpr(Dataclass):
374 op: Node
375 value: Node
376
377
378 class BinaryExpr(Dataclass):
379 left: Node
380 op: Node
381 right: Node
382
383
384 class Keyword(Token):
385 pass
386
387
388 class FunctionKeyword(Token):
389 f"""def"""
390 pass
391
392
393 class IfKeyword(Keyword):
394 r"""if"""
395 pass
396
397
398 class ThenKeyword(Keyword):
399 r"""then"""
400 pass
401
402
403 class ElseKeyword(Keyword):
404 r"""else"""
405 pass
406
407
408 class LeaveKeyword(Keyword):
409 r"""leave"""
410 pass
411
412
413 class ForKeyword(Keyword):
414 r"""for"""
415 pass
416
417
418 class ToKeyword(Keyword):
419 r"""to"""
420 pass
421
422
423 class WhileKeyword(Keyword):
424 r"""while"""
425 pass
426
427
428 class DoKeyword(Keyword):
429 r"""while"""
430 pass
431
432
433 class ReturnKeyword(Keyword):
434 r"""return"""
435 pass
436
437
438 class SwitchKeyword(Keyword):
439 r"""switch"""
440 pass
441
442
443 class CaseKeyword(Keyword):
444 r"""case"""
445 pass
446
447
448 class DefaultKeyword(Keyword):
449 r"""while"""
450 pass
451
452
453 class Colon(Token):
454 r""":"""
455 pass
456
457
458 class LShift(Token):
459 r"""<<"""
460 pass
461
462
463 class RShift(Token):
464 r""">>"""
465 pass
466
467
468 class Comma(Token):
469 r""","""
470 pass
471
472
473 class Period(Token):
474 r"""\."""
475 pass
476
477
478 class Semicolon(Token):
479 r""";"""
480 pass
481
482
483 class BitConcat(Token):
484 r"""\|\|"""
485 pass
486
487
488 class Question(Token):
489 r"""\?"""
490 pass
491
492
493 class Endmarker(Node):
494 pass
495
496
497 class IfExpr(Dataclass):
498 test: Node
499 body: Scope
500 orelse: Scope
501
502
503 class ForExpr(Dataclass):
504 subject: Node
505 start: Node
506 end: Node
507 body: Scope
508
509
510 class WhileExpr(Dataclass):
511 test: Node
512 body: Scope
513 orelse: Scope
514
515
516 class RepeatExpr(Dataclass):
517 subject: Node
518 times: Node
519
520
521 class Subscript(Dataclass):
522 index: Node
523 subject: Node = Node()
524
525
526 class RangeSubscript(Dataclass):
527 start: Node
528 end: Node = Node()
529 subject: Node = Node()
530
531
532 class Label(Literal):
533 pass
534
535
536 class DefaultLabel(Label):
537 def __new__(cls):
538 return super().__new__(cls, "default")
539
540
541 class Labels(Sequence, typeid=Label):
542 pass
543
544
545 class Case(Dataclass):
546 labels: Labels
547 body: Scope
548
549
550 class Cases(Sequence, typeid=Case):
551 pass
552
553
554 class SwitchExpr(Dataclass):
555 subject: Node
556 cases: Cases