1
0

Porting to Python 3 v2: Something works now

This commit is contained in:
Jon Michael Aanes 2024-07-10 01:09:11 +02:00
parent e0f8c0c2a1
commit 683c22cea2
Signed by: Jmaa
SSH Key Fingerprint: SHA256:Ab0GfHGCblESJx7JRE4fj4bFy/KRpeLhi41y4pF3sNA
5 changed files with 38 additions and 45 deletions

View File

@ -19,12 +19,12 @@ class AsciiPainter:
self.max_stack_size = max_stack_size
self.stack_draw_mode = stack_draw_mode
def saveState (self, emu, line_nr=None):
def saveState (self, emu, line_nr: int | None=None) -> None:
# Init state
state = []
self.states.append(state)
# Write opcode to state
if line_nr != None:
if line_nr is not None:
signature = emu.getLineSignature(line_nr)
for token in signature:
state.append({ 'state': 'none', 'val': token })
@ -42,7 +42,7 @@ class AsciiPainter:
# Write stack to state
stack_base_pointer = emu.getVal('%rbp')
base_sp = emu.getVal('%rsp')
assert(isinstance(emu.getVal('%rsp'), (int, long)))
assert(isinstance(emu.getVal('%rsp'), int))
state.append({'state':'none', 'val': ''})
if emu.regState('m'+str(base_sp-1)) == 'remove':
state.append({'state': emu.regState('m'+str(base_sp-1)), 'val': emu.stack[base_sp-1]})
@ -58,47 +58,48 @@ class AsciiPainter:
else:
state.append({'state':'none', 'val': ''})
def getWidthOfColumns(self, number_states, number_states_pr_block, number_state_vars):
widths = [0 for i in range(0, number_states_pr_block)]
for base_state in range(0, number_states, number_states_pr_block):
def getWidthOfColumns(self, number_states: int, number_states_per_block: int, number_state_vars: int) -> list[int]:
widths = [0 for i in range(0, number_states_per_block)]
for base_state in range(0, number_states, number_states_per_block):
for var_i in range(0, number_state_vars):
for state_i in range(0, min(number_states_pr_block, number_states - base_state)):
for state_i in range(0, min(number_states_per_block, number_states - base_state)):
width = len(str(self.states[base_state+state_i][var_i]['val']))
widths[state_i] = max(widths[state_i], width)
return widths
def getWidthOfNameColumn (self, number_state_vars):
def getWidthOfNameColumn (self, number_state_vars: int) -> int:
widest = 0
for var_i in range(0, number_state_vars):
widest = max(widest, len(self.nameOfVar(var_i-4)))
return widest
def to_string (self, emu):
def to_string (self, emu) -> str:
number_states = len(self.states)
number_state_vars = len(self.states[0])
term_width = int(subprocess.check_output(['tput', 'cols']))
number_states_pr_block = term_width / (10+2) - 1
number_states_per_block: int = term_width // (10+2) - 1
separator = '-' * term_width
l = []
output: list[str] = []
name_fmt = '{}{:'+str(self.getWidthOfNameColumn(number_state_vars))+'} '
column_fmt = map(lambda width: '{}{:>'+str(width)+'} ', self.getWidthOfColumns(number_states, number_states_pr_block, number_state_vars))
column_fmt = ['{}{:>'+str(width)+'} ' for width in self.getWidthOfColumns(number_states, number_states_per_block, number_state_vars)]
for base_state in range(0, number_states, number_states_pr_block):
l.append(separator)
for base_state in range(0, number_states, number_states_per_block):
output.append(separator)
for var_i in range(0, number_state_vars):
l.append(name_fmt.format(NORMAL_COLOR, self.nameOfVar(var_i-4)))
for state_i in range(0, min(number_states_pr_block, number_states - base_state)):
output.append(name_fmt.format(NORMAL_COLOR, self.nameOfVar(var_i-4)))
for state_i in range(0, min(number_states_per_block, number_states - base_state)):
var = self.states[base_state+state_i][var_i]
l.append(column_fmt[state_i].format(REG_STATUS_TO_COLOR[var['state']], var['val'], NORMAL_COLOR))
l.append('\n')
l.append(separator)
output.append(column_fmt[state_i].format(REG_STATUS_TO_COLOR[var['state']], var['val'], NORMAL_COLOR))
output.append('\n')
output.append(separator)
return ''.join(l)
return ''.join(output)
def nameOfVar (self, i):
if i < 0: return ''
if i < 0:
return ''
if i < len(self.registers):
return self.registers[i]
elif i != len(self.registers):

View File

@ -49,7 +49,7 @@ class Emulator:
self.last_sp = i-1
def setRegs (self, **reg_dict):
for reg_name, reg_val in reg_dict.iteritems():
for reg_name, reg_val in reg_dict.items():
assert(reg_name[0] != '%')
self.registers["%"+reg_name] = reg_val
@ -115,7 +115,7 @@ class Emulator:
if len(conditions)>0 and self.status["i"]:
raise Junk.JunkComparisonException(*self.status['i'])
and_, or_ = True, False
for cnd_name, cnd_val in conditions.iteritems():
for cnd_name, cnd_val in conditions.items():
if self.status[cnd_name] == cnd_val:
or_ = True
else:
@ -129,9 +129,9 @@ class Emulator:
def iterate (self):
old_rip = self.registers['%rip']
self.last_sp = self.registers['%rsp']
if self.registers['%rip'] >= len(self.code) or isinstance(self.registers['%rip'], Junk.Junk):
if isinstance(old_rip , Junk.Junk) or old_rip >= len(self.code):
return None
if not isinstance(self.registers['%rip'], (int, long)):
if not isinstance(self.registers['%rip'], int):
raise InternalExecutionException("Register %rip should be integer, but was "+str(self.registers['%rip']))
instruct = self.code[self.registers['%rip']]
opcode = instruct[0]
@ -149,7 +149,7 @@ class Emulator:
def __iter__(self):
return self
def next(self):
def __next__(self):
output = self.iterate()
if output is None:
raise StopIteration()
@ -157,5 +157,5 @@ class Emulator:
return output
def getUsedRegisters (self):
return [reg_name for reg_name, reg_val in self.registers.iteritems() if not isinstance(reg_val, Junk.Junk)]
return [reg_name for reg_name, reg_val in self.registers.items() if not isinstance(reg_val, Junk.Junk)]

View File

@ -1,23 +1,24 @@
class JunkComparisonException (BaseException):
import dataclasses
class JunkComparisonException(BaseException):
def __str__ (self):
return "Attempting to perform calculations involving junk values."
@dataclasses.dataclass
class Junk:
def __init__ (self, represents: str = None):
assert represents is None or isinstance(represents, str)
self.repr = represents
represents: str | None = None
def __str__ (self):
if self.repr:
return '['+self.repr+']'
return "[junk]"
return '[{}]'.format(self.represents or 'junk')
def __repr__ (self):
return self.__str__()
def __format__ (self, format):
return self.__str__()
def __add__ (self, other):
return self

View File

@ -36,7 +36,7 @@ class TikzPainter:
pos -= 1.5
base_sp = min(emu.last_sp, emu.getVal('%rsp'))
pos += 0.5 * max(0, emu.getVal('%rsp')-emu.last_sp)
assert(isinstance(emu.getVal('%rsp'), (int, long)))
assert(isinstance(emu.getVal('%rsp'), int))
for index in range(base_sp, 3+min(emu.max_stack_size, emu.getVal('%rsp')+self.max_stack_size)):
reg_state = emu.regState("m"+str(index))
reg_dect = "register_node, fill="+self.getRegColor(reg_state)+"!10"

View File

@ -13,13 +13,4 @@ Compiling the LaTeX requires both a LaTeX compiler, and packages
Please ignore the `/tests` folder. It is very old, and unsupported,
but kept for archival purposes.
## License ##
License is `beerware`:
<jonjmaa@gmail.com> wrote this program. As long as you retain
this notice you can do whatever you want with this stuff. If we
meet some day, and you think this stuff is worth it, you can buy
me a beer in return.
"""