200
|
1 from asmnodes import ASymbol, AInstruction
|
|
2 from ppci import CompilerError
|
199
|
3
|
|
4 """
|
|
5 Base classes for defining a target
|
|
6 """
|
|
7
|
|
8 # Machine code interface:
|
|
9 class Operand:
|
|
10 """ Single machine operand """
|
|
11 pass
|
|
12
|
|
13 class Register(Operand):
|
|
14 def __init__(self, name):
|
|
15 self.name = name
|
|
16
|
|
17 class Instruction:
|
|
18 def __init__(self, opcode):
|
|
19 self.opcode = opcode
|
|
20
|
|
21 class Target:
|
|
22 def __init__(self):
|
200
|
23 self.registers = []
|
199
|
24 self.instructions = []
|
200
|
25
|
|
26 def mapOperand(self, operand):
|
|
27 """ Try to map an operand to a target type """
|
|
28 if type(operand) is ASymbol:
|
|
29 # Try to map to register:
|
|
30 regs = {}
|
|
31 for r in self.registers:
|
|
32 regs[r.name] = r
|
|
33 if operand.name in regs:
|
|
34 return regs[operand.name]
|
|
35 else:
|
|
36 return
|
199
|
37
|
200
|
38 def mapInstruction(self, vi):
|
|
39 """ Map ast tree to real instruction for this target """
|
199
|
40
|
200
|
41 # map to real operands:
|
|
42 rops = tuple(map(self.mapOperand, vi.operands))
|
|
43 optypes = tuple(map(type, rops))
|
|
44
|
|
45 # look for a suitable instruction
|
|
46 for ic in self.instructions:
|
|
47 if ic.mnemonic == vi.opcode and ic.operands == optypes:
|
|
48 ri = ic(*rops)
|
|
49 return ri
|
|
50 raise CompilerError('No suitable instruction found')
|
|
51
|