Skip to content
Snippets Groups Projects
Commit a7a8015a authored by Martin Högstedt's avatar Martin Högstedt
Browse files

Merge branch '10-ignore_keys-default-argument' into 'main'

Removed default argument as list everywhere i found it

Closes #10

See merge request !18
parents a64c0b80 f01ee7b5
No related branches found
No related tags found
1 merge request!18Removed default argument as list everywhere i found it
Pipeline #131681 passed
......@@ -81,12 +81,15 @@ class Module:
"""
pass
def get_longest_line_len(self, ignore_keys=[]) -> int:
def get_longest_line_len(self, ignore_keys=None) -> int:
"""
Helper function for pretty_print that returns the length of
the longest line to print for a module.
"""
if ignore_keys == None:
ignore_keys = []
longest_line_len = 0
state = self.get_state()
......
......@@ -26,7 +26,7 @@ class Processor:
self.clock = 0
self.update_queue = []
self.module_history: list[dict[str, dict[str, Any]]] = []
self.signal_history: list[list] = [] # TODO: Is this needed?
self.signal_history: list[list] = [] # TODO: Is this needed?
self.breakpoint_id_counter = 1
self.breakpoints: dict[int, Breakpoint] = {}
self.breakpoint_reached = False
......@@ -43,9 +43,14 @@ class Processor:
# Maybe implemenet a 'get_pretty_print_state' at module
# level?
self.ignore_keys = [
"bit_length", "mask", "increment", "read_from_bus",
"read_from_uADR", "decrement_by_one", "bus_id"
]
"bit_length",
"mask",
"increment",
"read_from_bus",
"read_from_uADR",
"decrement_by_one",
"bus_id",
]
self.lambdas: dict[str, Callable[..., bool]] = {}
# List containing all clock cycles where a new asm instruction started
......@@ -63,8 +68,8 @@ class Processor:
# If a previous stored cycle has been loaded, discard
# all stored cycles from that cycle and onward in
# the history of saved cycles
self.module_history = self.module_history[0:self.clock]
self.signal_history = self.signal_history[0:self.clock]
self.module_history = self.module_history[0 : self.clock]
self.signal_history = self.signal_history[0 : self.clock]
self.unstop()
self.save_cycle()
......@@ -99,7 +104,7 @@ class Processor:
"""
raise NotImplemented
def run_asm_instruction(self, num_instructions = 1) -> None:
def run_asm_instruction(self, num_instructions=1) -> None:
"""
Runs assembler instructions on the processors 'num_instructions' times.
......@@ -109,7 +114,7 @@ class Processor:
raise NotImplemented
def undo_asm_instruction(self, num_instructions = 1) -> None:
def undo_asm_instruction(self, num_instructions=1) -> None:
"""
Undos 'num_instructions' numbers of assembler instructions on the CPU.
......@@ -117,18 +122,18 @@ class Processor:
Undo assembler instrucion assumes the CPU is always at the end of the list
'self.assembly_cycles'.
Undos asm instructions by finding the corresponding clock cycle before
Undos asm instructions by finding the corresponding clock cycle before
said number of asm intructions started and loading that clock cycle.
"""
current_clock_cycle = self.clock
index = len(self.assembly_cycles)
saved_cycle = self.assembly_cycles[index-1]
saved_cycle = self.assembly_cycles[index - 1]
# Make sure we are undoing the instruction(s) we are currently on
while saved_cycle >= current_clock_cycle:
index -= 1
saved_cycle = self.assembly_cycles[index-1]
saved_cycle = self.assembly_cycles[index - 1]
index -= num_instructions
......@@ -140,12 +145,11 @@ class Processor:
self.load_cycle(clockcycle)
# Need +1 here since we save the start state to enable to
# Need +1 here since we save the start state to enable to
# load the start state. This is done since we only append clock
# cycles to the list self.assembly_cycles when we reach a new state
# that has uPC set to 0, which wont happend when we load a new file.
self.assembly_cycles = self.assembly_cycles[:index+1]
self.assembly_cycles = self.assembly_cycles[: index + 1]
def run_continuously(self) -> None:
"""
......@@ -156,11 +160,21 @@ class Processor:
self.do_tick()
def should_halt(self) -> bool:
"""
Return True when the processor should halt, otherwise False.
Note
----
Each processor should implement the condition for True in its subclass.
If we intead raise NotImplemented as we do in all other cases when the
functionality should be implemented in the subclass we lose the ability
to test modules on the base processor class.
"""
return False
def stop(self) -> None:
"""
Signal to stop the execution of the processor until the processor is
Signal to stop the execution of the processor until the processor is
instructed to run continuously or do some ticks again.
"""
self.is_stopped = True
......@@ -188,7 +202,7 @@ class Processor:
"""
self.breakpoint_reached = False
for _, bp in self.breakpoints.items():
#TODO: Can make this more efficient by only checking enabled breakpoints
# TODO: Can make this more efficient by only checking enabled breakpoints
if bp.is_break() and bp.is_enabled:
self.breakpoint_reached = True
self.last_breakpoint = bp
......@@ -196,7 +210,6 @@ class Processor:
if self.breakpoint_reached:
self.stop()
def reset(self):
"""
Resets all values in the processor and
......@@ -216,7 +229,6 @@ class Processor:
module = self.update_queue.pop(0)
module.update_logic()
def add_modules_to_update(self, module: Module) -> None:
"""
Queues module to be updated at the end of clock cycle.
......@@ -254,7 +266,7 @@ class Processor:
"""
return self.clock
def set_clock(self, value: int) -> int:
def set_clock(self, value: int) -> None:
"""
Set current clockcycle.
"""
......@@ -294,7 +306,6 @@ class Processor:
except IndexError:
raise IndexError
for module_name, module_state in module_states.items():
self.modules[module_name].set_state(module_state)
......@@ -320,12 +331,11 @@ class Processor:
file = open(file_path)
# Ensure we are at the start of the file
file.seek(0, os.SEEK_END) # Go to end of file
if file.tell(): # If current pos != 0
file.seek(0) # Return to the start of the file
file.seek(0, os.SEEK_END) # Go to end of file
if file.tell(): # If current pos != 0
file.seek(0) # Return to the start of the file
else:
raise ValueError # Else raise error
raise ValueError # Else raise error
module_name = None
module_str = ""
......@@ -373,7 +383,7 @@ class Processor:
def pretty_print(self) -> None:
self.pretty_print_verbose(self.ignore_keys)
def pretty_print_verbose(self, ignore_keys = []) -> None:
def pretty_print_verbose(self, ignore_keys=None) -> None:
"""
Prints the most relevant information about each module
compact and pretty. Fields of modules can be ignored with the
......@@ -383,11 +393,13 @@ class Processor:
memory_modules = []
other_modules = []
if ignore_keys == None:
ignore_keys = []
# TODO: remove isinstance(module, micro_memory)
for module in self.modules.values():
if not isinstance(module, Bus):
if isinstance(module, Memory) \
or isinstance(module, MicroMemory):
if isinstance(module, Memory) or isinstance(module, MicroMemory):
memory_modules.append(module)
else:
other_modules.append(module)
......@@ -405,7 +417,7 @@ class Processor:
module_to_line_length = {}
# get the longest line length for all other_modules
for module in other_modules:
line_len = module.get_longest_line_len(ignore_keys) + 3 #+3 for padding
line_len = module.get_longest_line_len(ignore_keys) + 3 # +3 for padding
# TODO: what to do if two or more modules has the same name
module_to_line_length[module] = line_len
......@@ -433,16 +445,15 @@ class Processor:
# If this is not done, the keys we want to print
# could end up on an index that is higher than the
# number of rows printed and will therefore be missed
real_keys = [key for key in keys
if key not in ignore_keys]
real_keys = [key for key in keys if key not in ignore_keys]
# Dont go out of index
# Needed since one module might want to print 4
# fields and another only 1
if row < len(real_keys) and real_keys[row] \
not in ignore_keys:
string += real_keys[row] + ": " \
+ str(module_state[real_keys[row]])
if row < len(real_keys) and real_keys[row] not in ignore_keys:
string += (
real_keys[row] + ": " + str(module_state[real_keys[row]])
)
# padd the string so each string has the same
# length
......@@ -462,7 +473,7 @@ class Processor:
print(self.line_seperator * self.max_line_len)
longest_line_len = module.get_longest_line_len()
#longest_line_len = self.get_longest_memory_value(module.memory)
# longest_line_len = self.get_longest_memory_value(module.memory)
string = ""
last_mem_len = module.get_largest_mem_adr()
......@@ -471,11 +482,9 @@ class Processor:
# create a new string containg the adress and the value
# of the memory adress formattet to fit with the largest
# adress and largest memory value
new_row = ((str(i).ljust(last_mem_len)
+ ": "
+ str(value)).ljust(longest_line_len
+ last_mem_len + 3)
+ "|")
new_row = (str(i).ljust(last_mem_len) + ": " + str(value)).ljust(
longest_line_len + last_mem_len + 3
) + "|"
# only add the string if there is space for it, else
# print the string and start a new
......@@ -493,9 +502,7 @@ class Processor:
print(self.line_seperator * self.max_line_len)
print()
def pretty_print_names(self,
module_to_line_length: dict[Module, int]
) -> None:
def pretty_print_names(self, module_to_line_length: dict[Module, int]) -> None:
"""
Prints the name of the modules in one row with enough
added spacing between the names so that the modules
......@@ -511,9 +518,9 @@ class Processor:
print(name_string)
def group_pp_modules(self,
module_to_line_length: dict[Module, int]
) -> list[dict[Module, int]]:
def group_pp_modules(
self, module_to_line_length: dict[Module, int]
) -> list[dict[Module, int]]:
"""
Groups the modules to be pretty printed into groups with a
total line length lower than 'self.max_line_len'.
......@@ -542,11 +549,13 @@ class Processor:
Return a list containing all the keys for a module except the name.
Optinal argument to ignore specific keys.
"""
return [key for key in module.get_state() if key != "name"
and key not in ignore_keys]
return [
key
for key in module.get_state()
if key != "name" and key not in ignore_keys
]
def get_most_fields(self, modules: dict[Module: int],
ignore_keys=[]) -> int:
def get_most_fields(self, modules: dict[Module:int], ignore_keys=[]) -> int:
"""
Return the most number of a fields a module has. Can optionally
ignore keys.
......@@ -559,8 +568,9 @@ class Processor:
return fields
def add_state_breakpoint(self, module_name: str, state_name: str,
value: Any) -> None:
def add_state_breakpoint(
self, module_name: str, state_name: str, value: Any
) -> None:
if module_name not in self.modules:
raise ValueError(f"No module named {module_name}")
......@@ -568,8 +578,7 @@ class Processor:
module = self.modules[module_name]
if state_name not in module.get_state():
raise ValueError(f"No state named {state_name} in "
f"module {module_name}")
raise ValueError(f"No state named {state_name} in " f"module {module_name}")
bp = StateBreakpoint(module, state_name, value)
self.breakpoints[self.breakpoint_id_counter] = bp
......@@ -588,7 +597,7 @@ class Processor:
for bp_id, bp in self.breakpoints.items():
print(f"BP {bp_id}: {bp}")
def add_memory_breakpoint(self, module_name:str, adress: int, value: Any) -> None:
def add_memory_breakpoint(self, module_name: str, adress: int, value: Any) -> None:
if module_name not in self.modules:
raise ValueError(f"No module named {module_name}")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment