diff --git a/infernal_interpreter/AsciiPainter.py b/infernal_interpreter/AsciiPainter.py index c4d3bf4..787f3f0 100644 --- a/infernal_interpreter/AsciiPainter.py +++ b/infernal_interpreter/AsciiPainter.py @@ -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): diff --git a/infernal_interpreter/Emulator.py b/infernal_interpreter/Emulator.py index df82349..c9797fb 100644 --- a/infernal_interpreter/Emulator.py +++ b/infernal_interpreter/Emulator.py @@ -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)] diff --git a/infernal_interpreter/Junk.py b/infernal_interpreter/Junk.py index 8fd5baa..1d580f4 100644 --- a/infernal_interpreter/Junk.py +++ b/infernal_interpreter/Junk.py @@ -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 diff --git a/infernal_interpreter/TikzPainter.py b/infernal_interpreter/TikzPainter.py index fd6e2e1..f83218c 100644 --- a/infernal_interpreter/TikzPainter.py +++ b/infernal_interpreter/TikzPainter.py @@ -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" diff --git a/infernal_interpreter/__init__.py b/infernal_interpreter/__init__.py index b05803c..856a94c 100644 --- a/infernal_interpreter/__init__.py +++ b/infernal_interpreter/__init__.py @@ -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`: - - 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. """