Skip to content

Commit 8dd6297

Browse files
author
Kartik Sabharwal
authored
Merge pull request #4 from murcake/murcake/x86-dataclasses
Murcake/x86 dataclasses
2 parents d487f38 + c4595ea commit 8dd6297

22 files changed

+74
-138
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
**/__pycache__/
2+
/runtime.o
-163 Bytes
Binary file not shown.
-161 Bytes
Binary file not shown.
-13 KB
Binary file not shown.
-13.1 KB
Binary file not shown.
-8.5 KB
Binary file not shown.
-8.5 KB
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-4.5 KB
Binary file not shown.
-4.49 KB
Binary file not shown.

x86_ast.py

Lines changed: 72 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
1-
from typing import List
2-
from utils import label_name, indent, dedent, indent_stmt
1+
from __future__ import annotations
32

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
411
class X86Program:
5-
__match_args__ = ("body",)
6-
def __init__(self, body):
7-
self.body = body
12+
body: dict[str, list[instr]] | list[instr]
13+
814
def __str__(self):
915
result = ''
10-
if type(self.body) == dict:
16+
if isinstance(self.body, dict):
1117
for (l,ss) in self.body.items():
1218
if l == label_name('main'):
1319
result += '\t.globl ' + label_name('main') + '\n'
@@ -24,189 +30,117 @@ def __str__(self):
2430
dedent()
2531
result += '\n'
2632
return result
27-
def __repr__(self):
28-
return 'X86Program(' + repr(self.body) + ')'
2933

34+
@dataclass
3035
class X86ProgramDefs:
31-
__match_args__ = ("defs",)
32-
def __init__(self, defs):
33-
self.defs = defs
36+
defs: list[ast.FunctionDef]
37+
3438
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+
3941
class instr: ...
4042
class arg: ...
4143
class location(arg): ...
42-
44+
45+
@dataclass(frozen=True, eq=False)
4346
class Instr(instr):
4447
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+
5155
def source(self):
5256
return self.args[0]
5357
def target(self):
5458
return self.args[-1]
5559
def __str__(self):
5660
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)
6063
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+
6567
def __str__(self):
6668
return indent_stmt() + 'callq' + ' ' + self.func + '\n'
67-
def __repr__(self):
68-
return 'Callq(' + repr(self.func) + ', ' + repr(self.num_args) + ')'
6969

70+
@dataclass(frozen=True, eq=False)
7071
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+
7575
def __str__(self):
7676
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)
8079
class JumpIf(instr):
8180
cc: str
8281
label: str
83-
84-
__match_args__ = ("cc", "label")
85-
def __init__(self, cc, label):
86-
self.cc = cc
87-
self.label = label
82+
8883
def __str__(self):
8984
return indent_stmt() + 'j' + self.cc + ' ' + self.label + '\n'
90-
def __repr__(self):
91-
return 'JumpIf(' + repr(self.cc) + ', ' + repr(self.label) + ')'
9285

86+
@dataclass(frozen=True, eq=False)
9387
class Jump(instr):
9488
label: str
95-
96-
__match_args__ = ("label",)
97-
def __init__(self, label):
98-
self.label = label
89+
9990
def __str__(self):
10091
return indent_stmt() + 'jmp ' + self.label + '\n'
101-
def __repr__(self):
102-
return 'Jump(' + repr(self.label) + ')'
10392

93+
@dataclass(frozen=True, eq=False)
10494
class IndirectJump(instr):
105-
__match_args__ = ("target",)
106-
def __init__(self, target):
107-
self.target = target
95+
target: location
96+
10897
def __str__(self):
10998
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)
113101
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+
118105
def __str__(self):
119106
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)
123109
class Variable(location):
124-
__match_args__ = ("id",)
125-
def __init__(self, id):
126-
self.id = id
110+
id: str
111+
127112
def __str__(self):
128113
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)
138114

115+
@dataclass(frozen=True)
139116
class Immediate(arg):
140-
__match_args__ = ("value",)
141-
def __init__(self, value):
142-
self.value = value
117+
value: int
118+
143119
def __str__(self):
144120
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)
155123
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+
175126
def __str__(self):
176127
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)
187134
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+
192138
def __str__(self):
193139
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))
203140

141+
@dataclass(frozen=True)
204142
class Global(arg):
205-
__match_args__ = ("name",)
206-
def __init__(self, name):
207-
self.name = name
143+
name: str
144+
208145
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

Comments
 (0)