Add stepper skeleton.
This commit is contained in:
parent
1341911459
commit
1c48ccb6c6
143
stepper.py
Normal file
143
stepper.py
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
import ll
|
||||||
|
import parser
|
||||||
|
|
||||||
|
def TODO(msg):
|
||||||
|
print('TODO, not implemented yet at {}'
|
||||||
|
.format(msg))
|
||||||
|
|
||||||
|
def err(msg):
|
||||||
|
print('ERROR: {}'
|
||||||
|
.format(msg))
|
||||||
|
|
||||||
|
def step(insns, terminator, blocks, stack_frames, ssa_env, global_env, memory,
|
||||||
|
tdecs, fdecs, call_res):
|
||||||
|
if len(insns) == 0:
|
||||||
|
return terminate(terminator, blocks, stack_frames, ssa_env, global_env, memory)
|
||||||
|
ssa_target, next_insn = insns[0]
|
||||||
|
insns_rest = insns[1:]
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
print('Evaluating {}'
|
||||||
|
.format(ll.insn2s(next_insn)))
|
||||||
|
|
||||||
|
res = None
|
||||||
|
if isinstance(next_insn, ll.Binop):
|
||||||
|
bop = next_insn.bop
|
||||||
|
ty = next_insn.ty
|
||||||
|
left = next_insn.left
|
||||||
|
right = next_insn.right
|
||||||
|
left_v = eval_oper(left, ssa_env, global_env)
|
||||||
|
right_v = eval_oper(right, ssa_env, global_env)
|
||||||
|
res = eval_binop(bop, left_v, right_v)
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
print('{} {}, {}'
|
||||||
|
.format(bop, left_v, right_v))
|
||||||
|
else:
|
||||||
|
err('Unknown LLVM instruction: {}'
|
||||||
|
.format(next_insn))
|
||||||
|
|
||||||
|
if ssa_target is not None:
|
||||||
|
if ssa_target in ssa_env:
|
||||||
|
err('Cannot assign to variable twice: {}'
|
||||||
|
.format(ssa_target))
|
||||||
|
else:
|
||||||
|
# TODO
|
||||||
|
print('%{} <- {}'
|
||||||
|
.format(ssa_target, res))
|
||||||
|
ssa_env[ssa_target] = res
|
||||||
|
|
||||||
|
return insns_rest, terminator, blocks, stack_frames, ssa_env, memory, None
|
||||||
|
|
||||||
|
|
||||||
|
def terminate(terminator, blocks, stack_frames, ssa_env, global_env, memory):
|
||||||
|
if isinstance(terminator, ll.Ret):
|
||||||
|
oper = terminator.oper
|
||||||
|
if oper is None:
|
||||||
|
oper_v = None
|
||||||
|
else:
|
||||||
|
oper_v = eval_oper(oper, ssa_env, global_env)
|
||||||
|
if len(stack_frames) == 0:
|
||||||
|
return [], None, [], [], ssa_env, memory, oper_v
|
||||||
|
else:
|
||||||
|
new_insns, new_terminator, new_blocks, new_ssa_env = stack_frames[0]
|
||||||
|
new_stack_frames = stack_frames[1:]
|
||||||
|
return (new_insns, new_terminator, new_blocks, new_stack_frames,
|
||||||
|
new_ssa_env, memory, oper_v)
|
||||||
|
else:
|
||||||
|
err('Unknown LLVM terminator: {}'
|
||||||
|
.format(terminator))
|
||||||
|
|
||||||
|
|
||||||
|
def eval_oper(operand, ssa_env, global_env):
|
||||||
|
if isinstance(operand, ll.Null):
|
||||||
|
return 0
|
||||||
|
elif isinstance(operand, ll.Const):
|
||||||
|
return operand.val
|
||||||
|
elif isinstance(operand, ll.Gid):
|
||||||
|
TODO('eval_oper Gid')
|
||||||
|
elif isinstance(operand, ll.Id):
|
||||||
|
id = operand.val
|
||||||
|
try:
|
||||||
|
return ssa_env[id]
|
||||||
|
except KeyError:
|
||||||
|
err('Unable to find %{} in environment:\n{}'
|
||||||
|
.format(id, ssa_env))
|
||||||
|
|
||||||
|
|
||||||
|
def eval_binop(bop, left, right):
|
||||||
|
if bop == 'add':
|
||||||
|
return left + right
|
||||||
|
else:
|
||||||
|
err('Unknown LLVM Binary operator: {}'
|
||||||
|
.format(bop))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def gogo():
|
||||||
|
p = parser.LLVMParser()
|
||||||
|
p.build()
|
||||||
|
data = r'''
|
||||||
|
define i64 @tigermain (i64 %U_mainSL_8, i64 %U_mainDummy_9) {
|
||||||
|
%a = add i64 3, 5 ; please be 8
|
||||||
|
%b = add i64 %a, %a
|
||||||
|
%c = add i64 %a, %b
|
||||||
|
%d = add i64 100, %c
|
||||||
|
ret i64 %d
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
|
||||||
|
ast = p.parse(data)
|
||||||
|
|
||||||
|
tdecs = ast.tdecls
|
||||||
|
fdecs = ast.fdecls
|
||||||
|
global_env = ast.gdecls
|
||||||
|
|
||||||
|
tigermain = ast.fdecls['tigermain']
|
||||||
|
first_block = tigermain.body.first_block
|
||||||
|
blocks = tigermain.body.named_blocks
|
||||||
|
insns = first_block.insns
|
||||||
|
terminator = first_block.terminator
|
||||||
|
stack_frames = []
|
||||||
|
ssa_env = {}
|
||||||
|
# TODO: memory structure has not been decided yet
|
||||||
|
memory = [None]
|
||||||
|
call_res = None
|
||||||
|
|
||||||
|
while True:
|
||||||
|
(insns, terminator, blocks,
|
||||||
|
stack_frames, ssa_env, memory, call_res) = step(insns, terminator, blocks,
|
||||||
|
stack_frames, ssa_env,
|
||||||
|
global_env, memory, tdecs,
|
||||||
|
fdecs, call_res)
|
||||||
|
|
||||||
|
if terminator is None:
|
||||||
|
print('Stepping done! Final ssa_env:\n{}'
|
||||||
|
.format(ssa_env))
|
||||||
|
print('Program resulted in {}'.
|
||||||
|
format(call_res))
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
gogo()
|
Loading…
Reference in New Issue
Block a user