33
44from collections import defaultdict
55from dataclasses import dataclass
6+
67from utils import *
78
8- from .parser_x86 import x86_parser , x86_parser_instrs
99from .convert_x86 import convert_program
10+ from .parser_x86 import x86_parser , x86_parser_instrs
11+
1012
1113def interp_x86 (program ):
1214 x86_program = convert_program (program )
1315 emu = X86Emulator (logging = False )
1416 x86_output = emu .eval_program (x86_program )
1517 for s in x86_output :
1618 print (s , end = '' )
17-
19+
1820@dataclass
1921class FunPointer :
2022 fun_name : str
@@ -29,14 +31,14 @@ def __init__(self, logging=True):
2931 self .registers ['rsp' ] = 1000
3032
3133 self .global_vals = {}
32-
34+
3335 def log (self , s ):
3436 if self .logging :
3537 print (s )
36-
38+
3739 def parse_and_eval_program (self , s ):
3840 p = x86_parser .parse (s )
39-
41+
4042 def eval_program (self , p ):
4143 assert p .data == 'prog'
4244 blocks = {}
@@ -51,15 +53,15 @@ def eval_program(self, p):
5153 self .global_vals [name ] = FunPointer (name )
5254
5355 self .log ('========== STARTING EXECUTION ==============================' )
54-
56+
5557 # start evaluating at "main" or at "start"
5658 if label_name ('main' ) in blocks .keys ():
5759 self .eval_instrs (blocks [label_name ('main' )], blocks ,
5860 output )
5961 elif label_name ('start' ) in blocks .keys ():
6062 self .eval_instrs (blocks [label_name ('start' )], blocks ,
6163 output )
62-
64+
6365
6466 self .log ('FINAL STATE:' )
6567 if self .logging :
@@ -83,13 +85,13 @@ def eval_instructions(self, s):
8385 orig_registers = self .registers .copy ()
8486 orig_variables = self .variables .copy ()
8587
86-
88+
8789
8890 self .log ('Executing instructions:' )
8991 self .log (s )
9092
9193 self .log ('========== STARTING EXECUTION ==============================' )
92-
94+
9395 # start evaluating at "main"
9496 self .eval_instrs (p .children , blocks , output )
9597
@@ -113,7 +115,7 @@ def eval_instructions(self, s):
113115
114116 changes_df = pd .DataFrame (all_changes ,
115117 columns = ['Location' , 'Old' , 'New' ])
116-
118+
117119 return changes_df
118120
119121 def diff_dicts (self , d_after , d_orig ):
@@ -122,10 +124,10 @@ def diff_dicts(self, d_after, d_orig):
122124 if d_orig [k ] != d_after [k ]:
123125 keys_diff .append (k )
124126 return keys_diff
125-
127+
126128 def print_state (self ):
127129 import pandas as pd
128-
130+
129131 pd .set_option ("display.max_rows" , None )
130132 memory = [[ f'mem { k } ' , self .memory [k ] ] \
131133 for k in sorted (self .memory .keys ()) ]
@@ -146,24 +148,22 @@ def print_mem(self, mem):
146148 for k , v in mem .items ():
147149 self .log (f' { k } :\t { v } ' )
148150
149- def eval_imm (self , e ):
151+ def eval_imm (self , e ) -> int :
150152 if e .data == 'int_a' :
151153 return int (e .children [0 ])
152154 elif e .data == 'neg_a' :
153155 return - self .eval_imm (e .children [0 ])
154156 else :
155157 raise Exception ('eval_imm: unknown immediate:' , e )
156158
157-
159+
158160 def eval_arg (self , a ):
159161 if a .data == 'reg_a' :
160162 return self .registers [str (a .children [0 ])]
161163 elif a .data == 'var_a' :
162164 return self .variables [str (a .children [0 ])]
163- elif a .data == 'int_a' :
164- return self .eval_imm (a .children [0 ])
165- elif a .data == 'neg_a' :
166- return - self .eval_imm (a .children [0 ])
165+ elif a .data == 'int_a' or a .data == 'neg_a' :
166+ return self .eval_imm (a )
167167 elif a .data == 'mem_a' :
168168 offset , reg = a .children
169169 addr = self .registers [reg ]
@@ -311,7 +311,7 @@ def eval_instrs(self, instrs, blocks, output):
311311 self .log (f'CALL TO read_int: { self .registers ["rax" ]} ' )
312312 if self .logging :
313313 print (self .print_state ())
314-
314+
315315 elif target == 'initialize' :
316316 self .log (f'CALL TO initialize: { self .registers ["rdi" ]} , { self .registers ["rsi" ]} ' )
317317 rootstack_size = self .registers ['rdi' ]
@@ -398,7 +398,7 @@ def eval_instrs(self, instrs, blocks, output):
398398
399399 if self .logging :
400400 print (self .print_state ())
401-
401+
402402
403403
404404
0 commit comments