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