Skip to content
Snippets Groups Projects
Commit 43cef2ba authored by Johannes Kung's avatar Johannes Kung
Browse files

Refactored CLI for code readability

parent 019d137e
No related branches found
No related tags found
1 merge request!14Updated CLI help text + refactoring
Pipeline #131582 passed
...@@ -5,6 +5,74 @@ from os.path import exists, isdir ...@@ -5,6 +5,74 @@ from os.path import exists, isdir
from simudator.core.processor import Processor from simudator.core.processor import Processor
HELP_TEXT = """Here is a list of possible commands:
CLI control:
- h, help : Shows this message.
- q, quit : Closes the program. Nothing will be saved.
Simulation control:
- n [x], next [x]: Simulates x ticks.
If no x is given simulates one tick.
- rc, run_continuously:
Continuously simulate ticks until a HALT is signalled
or a breakpoint is reached.
- u [x], undo [x]: Undoes the last x clock cycle.
If no x is given one cycle is undone.
- r, reset : Resets processor to initial state.
State information:
- c, clock: Prints the processors current clock cycle.
- p, print: Prints all states of all modules.
- p [name*], print [name*]:
Prints the states with given name. Prints all modules if no names are given.
- pl, printlist [add/remove]:
Prints all modules in the print list. Add or remove followed by a modules
name will add or remove them from the print list.
- pp, pretty print: Prints relevant processor state information in a
readable and compact format.
- ppv, pretty print verbose: Prints all processor state information in a
readable and compact format.
Breakpoints:
- p br, print breaks: Prints all breakpoints.
- p br lam, print break lambdas:
Prints all available lambdas of this processor to use for lambda
breakpoints.
- br state, break state [module name] [state name] [value]:
Add a breakpoint for the module with the given name. The breakpoint brakes
when the specified state of the module has the specified value.
- br mem, break memory [module name] [adress] [value]:
Add a breakpoint for a memory module with the given name. The breakpoint
breaks when the specified adress of the memory has the specified value.
- br lam, break lambda [lambda_name] [keyword argument] ...:
Add a breakpoint that uses the referenced lambda to evaluate when to
break. Any module names in the keyword arguments will be substituted with
the actual module. Strings must be enclosed with quotation marks.
- rm br [id], remove break [id]:
Remove the breakpoint with the given ID.
File I/O:
- l, load [path]:
Loads a processors state from a given file path.
- sf, save to file [path]:
Saves the processor state to the specified file.
"""
class CLI: class CLI:
""" """
...@@ -29,38 +97,20 @@ class CLI: ...@@ -29,38 +97,20 @@ class CLI:
# Get user commands here # Get user commands here
user_input = input("> ") user_input = input("> ")
# Note: Keep the order of the cases consistent with the help text
# for convenience
match user_input.split(): match user_input.split():
case ["c"] | ["clock"]: # CLI control -------------------------------------------------
# shows current clockcycle case ["h"] | ["help"]:
print("Clock is at: ", str(self.processor.get_clock())) # prints help message
print(HELP_TEXT)
case ["p"] | ["print"]:
print("\n")
# prints all module states, is most prbably hard to read
for module in self.processor.get_modules():
module.print_module()
print("\n")
case ["p", "br"] | ["print", "breaks"]:
self.processor.print_breakpoints()
case ["p", "br", "lam"] | ["print", "break", "lambdas"]:
lambdas = self.processor.get_breakpoint_lambdas()
if not lambdas:
print("There are no lambdas for this processor.")
else:
print(lambdas)
case ["p", *_] | ["print", *_]: case ["q"] | ["quit"]:
print("\n") # Ends the loop
# print modules with given names print("Goodbye")
for name in user_input.split()[1:]: self.running = False
try:
self.processor.get_module(name).print_module()
print("\n")
except KeyError:
print("\nNo module named", name, "\n")
# Simulation control ------------------------------------------
case ["n"] | ["next"]: case ["n"] | ["next"]:
# runs next tick in the processor # runs next tick in the processor
# this could take time for larger simulations, # this could take time for larger simulations,
...@@ -68,20 +118,6 @@ class CLI: ...@@ -68,20 +118,6 @@ class CLI:
self.processor.do_tick() self.processor.do_tick()
case ["rc"] | ["run_continuously"]:
self.processor.run_continuously()
if self.processor.breakpoint_reached:
bp = self.processor.last_breakpoint
print(f"Reached breakpoint: {bp}")
if self.processor.should_halt():
print("The processor halted")
case ["r"] | ["resets"]:
# self.processor.load_cycle(0)
self.processor.reset()
case ["n", _] | ["next", _]: case ["n", _] | ["next", _]:
# runs a given number of ticks # runs a given number of ticks
# this could take time for larger simulations, # this could take time for larger simulations,
...@@ -100,16 +136,23 @@ class CLI: ...@@ -100,16 +136,23 @@ class CLI:
except ValueError: except ValueError:
print("Invalid value") print("Invalid value")
case ["l", _] | ["load", _]: case ["rc"] | ["run_continuously"]:
# load processor state from file self.processor.run_continuously()
try: if self.processor.breakpoint_reached:
self.processor.reset() bp = self.processor.last_breakpoint
self.processor.load_state_from_file(user_input.split()[1]) print(f"Reached breakpoint: {bp}")
except FileNotFoundError:
print("No file called ", user_input.split()[1], " was found")
case ["pl", *_] | ["printlist", *_]: if self.processor.should_halt():
self.print_list_command(user_input.split()) print("The processor halted")
case ["u"] | ["undo"]:
# undo one clock cycles
current_cycle = self.processor.get_clock()
try:
self.processor.load_cycle(max(current_cycle - 1, 0))
except IndexError:
print("Index out of range")
case ["u", _] | ["undo", _]: case ["u", _] | ["undo", _]:
# undo many clock cycles # undo many clock cycles
...@@ -127,14 +170,54 @@ class CLI: ...@@ -127,14 +170,54 @@ class CLI:
except IndexError: except IndexError:
print("Index out of range") print("Index out of range")
case ["u"] | ["undo"]: case ["r"] | ["resets"]:
# undo one clock cycles # self.processor.load_cycle(0)
self.processor.reset()
current_cycle = self.processor.get_clock() # State information -------------------------------------------
try: case ["c"] | ["clock"]:
self.processor.load_cycle(max(current_cycle - 1, 0)) # shows current clockcycle
except IndexError: print("Clock is at: ", str(self.processor.get_clock()))
print("Index out of range")
case ["p"] | ["print"]:
print("\n")
# prints all module states, is most prbably hard to read
for module in self.processor.get_modules():
module.print_module()
print("\n")
case ["p", *_] | ["print", *_]:
print("\n")
# print modules with given names
for name in user_input.split()[1:]:
try:
self.processor.get_module(name).print_module()
print("\n")
except KeyError:
print("\nNo module named", name, "\n")
case ["pl", *_] | ["printlist", *_]:
self.print_list_command(user_input.split())
case ["pp"] | ["pretty print"]:
# pretty print the modules of the processor
self.processor.pretty_print()
case ["ppv"] | ["pretty print verbose"]:
# pretty print the modules of the processor
# with all available information
self.processor.pretty_print_verbose()
# Breakpoints -------------------------------------------------
case ["p", "br"] | ["print", "breaks"]:
self.processor.print_breakpoints()
case ["p", "br", "lam"] | ["print", "break", "lambdas"]:
lambdas = self.processor.get_breakpoint_lambdas()
if not lambdas:
print("There are no lambdas for this processor.")
else:
print(lambdas)
case ["br", "state", _, _, _] | ["break", "state", _, _, _]: case ["br", "state", _, _, _] | ["break", "state", _, _, _]:
module_name = user_input.split()[2] module_name = user_input.split()[2]
...@@ -176,104 +259,14 @@ class CLI: ...@@ -176,104 +259,14 @@ class CLI:
except ValueError: except ValueError:
print("Breakpoint ID must be an integer") print("Breakpoint ID must be an integer")
case ["h"] | ["help"]: # File I/O ----------------------------------------------------
# prints help message case ["l", _] | ["load", _]:
print( # load processor state from file
"Here is a list of possible commands:\n" try:
"CLI control: \n" self.processor.reset()
" - h, help : Shows this message.\n" self.processor.load_state_from_file(user_input.split()[1])
except FileNotFoundError:
" - q, quit : Closes the program. Nothing will be saved.\n" print("No file called ", user_input.split()[1], " was found")
"\n"
# ---------------------------------------------------
"Simulation control: \n"
" - n [x], next [x]: Simulates x ticks. "
"If no x is given simulates one tick.\n"
" - rc, run_continuously: "
"Continuously simulate ticks until a HALT is signalled "
"or a breakpoint is reached.\n"
" - r, reset : Resets processor to initial state.\n"
" - u [x], undo [x]: Undos the last x clock cycle. "
"If no x is given one cycle is undone.\n"
"\n"
# ---------------------------------------------------
"State information: \n"
" - c, clock: Prints the processors current clock cycle.\n"
" - p, print: Prints all states of all modules.\n"
" - p [name*], print [name*]: Prints the states with "
"given name. "
"Will print all modules if no names are given.\n"
" - pl, printlist [add] [remove]: "
"Prints all modules in the print list. "
"Add or remove followed by a modules name "
"will add or remove them from the print list.\n"
" - pp, pretty print: Prints relevant processor state information in a readable and compact format.\n"
" - ppv, pretty print verbose: Prints all processor state information in a readable and compact format.\n"
"\n"
# ---------------------------------------------------
"Breakpoints: \n"
" - p br, print breaks: Prints all breakpoints.\n"
" - p br lam, print break lambdas: Prints all available "
"lambdas of this processor to use for lambda "
"breakpoints. \n"
" - br state, break state [module name] [state name] [value]: "
"Add a breakpoint for the module with the given name. "
"The breakpoint brakes when the specified state of the "
"module has the specified value.\n"
" - br mem, break memory [module name] [adress] [value]: "
"Add a breakpoint for a memory module with the given "
"name. The breakpoint breaks when the specified adress "
"of the memory has the specified value.\n"
" - br lam, break lambda [lambda_name] [keyword argument] ...: "
"Add a breakpoint that uses "
"the referenced lambda to evaluate when to break. Any "
"module names in the keyword arguments will be "
"substituted with the actual module. Strings must be "
"enclosed with quotation marks. \n"
" - rm br [id], remove break [id]: "
"Remove the breakpoint with the given ID.\n"
"\n"
# ---------------------------------------------------
"File I/O: \n"
" - l, load [path]: "
"Loads a processors state from a given file path.\n"
" - sf, save to file [path]: "
"Saves the processor state to the specified file. \n"
)
case ["q"] | ["quit"]:
# Ends the loop
print("Goodbye")
self.running = False
case ["pp"] | ["pretty print"]:
# pretty print the modules of the processor
self.processor.pretty_print()
case ["ppv"] | ["pretty print verbose"]:
# pretty print the modules of the processor
# with all available information
self.processor.pretty_print_verbose()
case ["sf"] | ["save to file"]: case ["sf"] | ["save to file"]:
file_path = "cpu_save_file" file_path = "cpu_save_file"
...@@ -283,6 +276,7 @@ class CLI: ...@@ -283,6 +276,7 @@ class CLI:
file_path = user_input.split()[1] file_path = user_input.split()[1]
self.check_file_path(file_path) self.check_file_path(file_path)
# -------------------------------------------------------------
case _: case _:
# message for unknown command # message for unknown command
print("Unknown command. Write \"help\" for assistance.") print("Unknown command. Write \"help\" for assistance.")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment