1
- from typing import List
2
- from utils import label_name , indent , dedent , indent_stmt
1
+ from __future__ import annotations
3
2
3
+ import ast
4
+ from dataclasses import dataclass
5
+ from typing import Iterable
6
+
7
+ from utils import dedent , indent , indent_stmt , label_name
8
+
9
+
10
+ @dataclass
4
11
class X86Program :
5
- __match_args__ = ("body" ,)
6
- def __init__ (self , body ):
7
- self .body = body
12
+ body : dict [str , list [instr ]] | list [instr ]
13
+
8
14
def __str__ (self ):
9
15
result = ''
10
- if type (self .body ) == dict :
16
+ if isinstance (self .body , dict ) :
11
17
for (l ,ss ) in self .body .items ():
12
18
if l == label_name ('main' ):
13
19
result += '\t .globl ' + label_name ('main' ) + '\n '
@@ -24,189 +30,117 @@ def __str__(self):
24
30
dedent ()
25
31
result += '\n '
26
32
return result
27
- def __repr__ (self ):
28
- return 'X86Program(' + repr (self .body ) + ')'
29
33
34
+ @dataclass
30
35
class X86ProgramDefs :
31
- __match_args__ = ("defs" ,)
32
- def __init__ (self , defs ):
33
- self .defs = defs
36
+ defs : list [ast .FunctionDef ]
37
+
34
38
def __str__ (self ):
35
- return '\n ' .join ([str (d ) for d in self .defs ])
36
- def __repr__ (self ):
37
- return 'X86ProgramDefs(' + repr (self .defs ) + ')'
38
-
39
+ return "\n " .join ([str (d ) for d in self .defs ])
40
+
39
41
class instr : ...
40
42
class arg : ...
41
43
class location (arg ): ...
42
-
44
+
45
+ @dataclass (frozen = True , eq = False )
43
46
class Instr (instr ):
44
47
instr : str
45
- args : List [arg ]
46
-
47
- __match_args__ = ("instr" , "args" )
48
- def __init__ (self , instr , args ):
49
- self .instr = instr
50
- self .args = args
48
+ args : tuple [arg , ...]
49
+
50
+ def __init__ (self , name : str , args : Iterable [arg ]):
51
+ # https://docs.python.org/3/library/dataclasses.html#frozen-instances
52
+ object .__setattr__ (self , 'instr' , name )
53
+ object .__setattr__ (self , 'args' , tuple (args ))
54
+
51
55
def source (self ):
52
56
return self .args [0 ]
53
57
def target (self ):
54
58
return self .args [- 1 ]
55
59
def __str__ (self ):
56
60
return indent_stmt () + self .instr + ' ' + ', ' .join (str (a ) for a in self .args ) + '\n '
57
- def __repr__ (self ):
58
- return 'Instr(' + repr (self .instr ) + ', ' + repr (self .args ) + ')'
59
-
61
+
62
+ @dataclass (frozen = True , eq = False )
60
63
class Callq (instr ):
61
- __match_args__ = ("func" , "num_args" )
62
- def __init__ (self , func , num_args ):
63
- self .func = func
64
- self .num_args = num_args
64
+ func : str
65
+ num_args : int
66
+
65
67
def __str__ (self ):
66
68
return indent_stmt () + 'callq' + ' ' + self .func + '\n '
67
- def __repr__ (self ):
68
- return 'Callq(' + repr (self .func ) + ', ' + repr (self .num_args ) + ')'
69
69
70
+ @dataclass (frozen = True , eq = False )
70
71
class IndirectCallq (instr ):
71
- __match_args__ = ("func" , "num_args" )
72
- def __init__ (self , func , num_args ):
73
- self .func = func
74
- self .num_args = num_args
72
+ func : arg
73
+ num_args : int
74
+
75
75
def __str__ (self ):
76
76
return indent_stmt () + 'callq' + ' *' + str (self .func ) + '\n '
77
- def __repr__ (self ):
78
- return 'IndirectCallq(' + repr (self .func ) + ', ' + repr (self .num_args ) + ')'
79
-
77
+
78
+ @dataclass (frozen = True , eq = False )
80
79
class JumpIf (instr ):
81
80
cc : str
82
81
label : str
83
-
84
- __match_args__ = ("cc" , "label" )
85
- def __init__ (self , cc , label ):
86
- self .cc = cc
87
- self .label = label
82
+
88
83
def __str__ (self ):
89
84
return indent_stmt () + 'j' + self .cc + ' ' + self .label + '\n '
90
- def __repr__ (self ):
91
- return 'JumpIf(' + repr (self .cc ) + ', ' + repr (self .label ) + ')'
92
85
86
+ @dataclass (frozen = True , eq = False )
93
87
class Jump (instr ):
94
88
label : str
95
-
96
- __match_args__ = ("label" ,)
97
- def __init__ (self , label ):
98
- self .label = label
89
+
99
90
def __str__ (self ):
100
91
return indent_stmt () + 'jmp ' + self .label + '\n '
101
- def __repr__ (self ):
102
- return 'Jump(' + repr (self .label ) + ')'
103
92
93
+ @dataclass (frozen = True , eq = False )
104
94
class IndirectJump (instr ):
105
- __match_args__ = ("target" ,)
106
- def __init__ (self , target ):
107
- self .target = target
95
+ target : location
96
+
108
97
def __str__ (self ):
109
98
return indent_stmt () + 'jmp *' + str (self .target ) + '\n '
110
- def __repr__ (self ):
111
- return 'IndirectJump(' + repr (self .target ) + ')'
112
-
99
+
100
+ @dataclass (frozen = True , eq = False )
113
101
class TailJump (instr ):
114
- __match_args__ = ("func" ,"arity" )
115
- def __init__ (self , func , arity ):
116
- self .func = func
117
- self .arity = arity
102
+ func : arg
103
+ arity : int
104
+
118
105
def __str__ (self ):
119
106
return indent_stmt () + 'tailjmp ' + str (self .func ) + '\n '
120
- def __repr__ (self ):
121
- return 'TailJump(' + repr (self .func ) + ',' + repr (self .arity ) + ')'
122
-
107
+
108
+ @dataclass (frozen = True )
123
109
class Variable (location ):
124
- __match_args__ = ("id" ,)
125
- def __init__ (self , id ):
126
- self .id = id
110
+ id : str
111
+
127
112
def __str__ (self ):
128
113
return self .id
129
- def __repr__ (self ):
130
- return 'Variable(' + repr (self .id ) + ')'
131
- def __eq__ (self , other ):
132
- if isinstance (other , Variable ):
133
- return self .id == other .id
134
- else :
135
- return False
136
- def __hash__ (self ):
137
- return hash (self .id )
138
114
115
+ @dataclass (frozen = True )
139
116
class Immediate (arg ):
140
- __match_args__ = ("value" ,)
141
- def __init__ (self , value ):
142
- self .value = value
117
+ value : int
118
+
143
119
def __str__ (self ):
144
120
return '$' + str (self .value )
145
- def __repr__ (self ):
146
- return 'Immediate(' + repr (self .value ) + ')'
147
- def __eq__ (self , other ):
148
- if isinstance (other , Immediate ):
149
- return self .value == other .value
150
- else :
151
- return False
152
- def __hash__ (self ):
153
- return hash (self .value )
154
-
121
+
122
+ @dataclass (frozen = True )
155
123
class Reg (location ):
156
- __match_args__ = ("id" ,)
157
- def __init__ (self , id ):
158
- self .id = id
159
- def __str__ (self ):
160
- return '%' + self .id
161
- def __repr__ (self ):
162
- return 'Reg(' + repr (self .id ) + ')'
163
- def __eq__ (self , other ):
164
- if isinstance (other , Reg ):
165
- return self .id == other .id
166
- else :
167
- return False
168
- def __hash__ (self ):
169
- return hash (self .id )
170
-
171
- class ByteReg (arg ):
172
- __match_args__ = ("id" ,)
173
- def __init__ (self , id ):
174
- self .id = id
124
+ id : str
125
+
175
126
def __str__ (self ):
176
127
return '%' + self .id
177
- def __repr__ (self ):
178
- return 'ByteReg(' + repr (self .id ) + ')'
179
- def __eq__ (self , other ):
180
- if isinstance (other , ByteReg ):
181
- return self .id == other .id
182
- else :
183
- return False
184
- def __hash__ (self ):
185
- return hash (self .id )
186
-
128
+
129
+ @dataclass (frozen = True )
130
+ class ByteReg (Reg ):
131
+ pass
132
+
133
+ @dataclass (frozen = True )
187
134
class Deref (arg ):
188
- __match_args__ = ("reg" , "offset" )
189
- def __init__ (self , reg , offset ):
190
- self .reg = reg
191
- self .offset = offset
135
+ reg : str
136
+ offset : int
137
+
192
138
def __str__ (self ):
193
139
return str (self .offset ) + '(%' + self .reg + ')'
194
- def __repr__ (self ):
195
- return 'Deref(' + repr (self .reg ) + ', ' + repr (self .offset ) + ')'
196
- def __eq__ (self , other ):
197
- if isinstance (other , Deref ):
198
- return self .reg == other .reg and self .offset == other .offset
199
- else :
200
- return False
201
- def __hash__ (self ):
202
- return hash ((self .reg , self .offset ))
203
140
141
+ @dataclass (frozen = True )
204
142
class Global (arg ):
205
- __match_args__ = ("name" ,)
206
- def __init__ (self , name ):
207
- self .name = name
143
+ name : str
144
+
208
145
def __str__ (self ):
209
- return str (self .name ) + "(%rip)"
210
- def __repr__ (self ):
211
- return 'Global(' + repr (self .name ) + ')'
212
-
146
+ return self .name + "(%rip)"
0 commit comments