From ceea52be42ecd0026b314dccced888eb2ea2c55e Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Wed, 21 Aug 2019 13:02:12 -0400 Subject: [PATCH 1/4] Developer improvements --- dashmips/__main__.py | 45 +++--- dashmips/debugger.py | 28 +--- dashmips/directives.py | 55 ++------ dashmips/extension.py | 3 +- dashmips/instructions/Instruction.py | 9 +- dashmips/instructions/__init__.py | 11 +- dashmips/instructions/imm_instructions.py | 17 +-- dashmips/instructions/pseudo_instructions.py | 71 ++-------- dashmips/instructions/rd_imm_instructions.py | 12 +- dashmips/instructions/rd_instructions.py | 29 +--- .../instructions/rd_rs_lbl_instructions.py | 21 +-- .../instructions/rd_rs_rt_instructions.py | 133 +++--------------- dashmips/instructions/rs_imm_instructions.py | 47 +------ dashmips/instructions/rs_instructions.py | 11 +- dashmips/instructions/rs_mem_instructions.py | 69 ++------- .../instructions/rs_rt_imm_instructions.py | 85 ++--------- dashmips/instructions/rs_rt_instructions.py | 82 ++--------- dashmips/instructions/special_instructions.py | 15 +- dashmips/models.py | 34 ++--- dashmips/preprocessor.py | 22 +-- dashmips/run.py | 11 +- dashmips/syscalls/__init__.py | 7 +- dashmips/syscalls/print_syscalls.py | 30 +--- 23 files changed, 160 insertions(+), 687 deletions(-) diff --git a/dashmips/__main__.py b/dashmips/__main__.py index 0a6294f..293ee2b 100644 --- a/dashmips/__main__.py +++ b/dashmips/__main__.py @@ -11,21 +11,11 @@ def main_compile(args: argparse.Namespace) -> int: """Compile/Exec mips code.""" - if args.file: - program = preprocess(args.file) + program = preprocess(args.FILE) if args.out: json.dump(program.to_dict(), args.out) - - if args.json: - # Ending matches socket communication + else: print(json.dumps(program.to_dict())) - - if args.vscode: - snippets = generate_snippets() - print(json.dumps(snippets, indent=4)) - print("\n\n\n") - print(instruction_name_regex()) - return 0 @@ -75,44 +65,53 @@ def main_docs(args: argparse.Namespace) -> int: print("Instructions") print(f"{'format':<35}{'description'}") print(f"{'------':<35}{'-----------'}") - snips = generate_snippets(examples=True) + snippets = generate_snippets(examples=True) instr_list = list(Instructions.items()) instr_list.sort(key=lambda i: i[0]) for instrname, instruction in instr_list: - ex_str = snips[instrname]["example"] - desc = snips[instrname]["description"] + ex_str = snippets[instrname]["example"] + desc = snippets[instrname]["description"] print(f"{ex_str:35}# ", end="") print(f"{desc}") return 0 +def main_utils(args: argparse.Namespace) -> int: + """General utilities to help a mips developer.""" + if args.snippets: + snippets = generate_snippets() + print(json.dumps(snippets, indent=4)) + if args.instruction_regex: + print(instruction_name_regex()) + return 0 + + def main() -> NoReturn: """Entry function for Dashmips.""" parser = argparse.ArgumentParser("dashmips") - parser.add_argument("-v", "--version", action="version", version="0.0.11") + parser.add_argument("-v", "--version", action="version", version="0.1.0") sbp = parser.add_subparsers(title="commands", dest="command") compileparse = sbp.add_parser("compile", aliases=["c"]) runparse = sbp.add_parser("run", aliases=["r"]) debugparse = sbp.add_parser("debug", aliases=["d"]) docsparse = sbp.add_parser("docs", aliases=["h"]) + utilsparse = sbp.add_parser("utils", aliases=["u"]) - compileparse.add_argument("-f", "--file", type=argparse.FileType("r", encoding="utf8"), help="Input file") + compileparse.add_argument("FILE", type=argparse.FileType("r", encoding="utf8"), help="Input file") compileparse.add_argument("-o", "--out", type=argparse.FileType("w", encoding="utf8"), help="Output file name") - compileparse.add_argument("-j", "--json", action="store_true", help="Output json to stdout") - compileparse.add_argument("--vscode", action="store_true", help="Output json for vscode") compileparse.set_defaults(func=main_compile) runparse.add_argument("FILE", type=argparse.FileType("r", encoding="utf8"), help="Input file") runparse.add_argument("-a", "--args", dest="mips_args", nargs="*", help="Arguments to pass into the mips main") - runparse.add_argument("-t", "--vt100", action="store_true", help="Start VT100 Simulator") + runparse.add_argument("--vt100", action="store_true", help="Start VT100 Simulator") runparse.set_defaults(func=main_run) debugparse.add_argument("FILE", type=argparse.FileType("r", encoding="utf8"), help="Input file") debugparse.add_argument("-a", "--args", dest="mips_args", nargs="*", help="Arguments to pass into the mips main") - debugparse.add_argument("-t", "--vt100", action="store_true", help="Start VT100 Simulator") + debugparse.add_argument("--vt100", action="store_true", help="Start VT100 Simulator") debugparse.add_argument("-p", "--port", type=int, default=2390, help="run debugger on port") debugparse.add_argument("-i", "--host", default="0.0.0.0", help="run debugger on host") debugparse.add_argument("-l", "--log", dest="log", action="store_true", help="Log all network traffic") @@ -122,6 +121,10 @@ def main() -> NoReturn: docsparse.add_argument("-i", "--instr", action="store_true", help="Show instruction table") docsparse.set_defaults(func=main_docs) + utilsparse.add_argument("--snippets", action="store_true", help="Output snippets json") + utilsparse.add_argument("--instruction_regex", action="store_true", help="Output regex that matches instructions") + utilsparse.set_defaults(func=main_utils) + prog_args = parser.parse_args() if not hasattr(prog_args, "func"): # This is for python 3.6 compatibility diff --git a/dashmips/debugger.py b/dashmips/debugger.py index 22a3b36..cdd7e2c 100644 --- a/dashmips/debugger.py +++ b/dashmips/debugger.py @@ -15,21 +15,13 @@ def debug_start(program: MipsProgram, params=None) -> Dict[str, int]: - """Debug start. - - :param operation: dict - :param program: MipsProgram - """ + """Debug start.""" program.registers["pc"] = program.labels["main"].value return {"pid": os.getpid()} def debug_step(program: MipsProgram, params) -> Dict[str, Any]: - """Debug step. - - :param operation: dict - :param program: MipsProgram - """ + """Debug step.""" try: next_instruction(program) @@ -43,20 +35,14 @@ def debug_step(program: MipsProgram, params) -> Dict[str, Any]: def debug_continue(program: MipsProgram, params) -> Dict[str, Any]: - """Debug continue. - - :param program: MipsProgram - """ + """Debug continue.""" starting_pc = program.registers["pc"] # vscode should have done the translation # these are pc values (aka index into srclines) verified, breakpoints = verify_breakpoints(program, params) def breaking_condition(program: MipsProgram) -> bool: - """Condition function to stop execution. - - :param program: - """ + """Condition function to stop execution.""" nonlocal starting_pc if program.registers["pc"] == starting_pc: # current instruction will execute even if on breakpoint @@ -79,11 +65,7 @@ def breaking_condition(program: MipsProgram) -> bool: def debug_stop(program: MipsProgram, params) -> Dict[str, bool]: - """Stop messages incoming mean nothing to a server. - - :param operation: dict - :param program: MipsProgram - """ + """Stop messages incoming mean nothing to a server.""" return {"exited": True} diff --git a/dashmips/directives.py b/dashmips/directives.py index cdf4dde..74af85c 100644 --- a/dashmips/directives.py +++ b/dashmips/directives.py @@ -1,91 +1,56 @@ """Directive handling.""" from typing import Union -from .utils import parse_int, bytesify +from .utils import parse_int, bytesify, MipsException from .hardware import Memory def directive_align(data: str, memory: Memory): - """Align directive. - - :param name: str: - :param data: str: - :param memory: Memory: - """ - raise Exception("Unsupported directive.") + """Align directive.""" + raise MipsException("Unsupported directive.") return None def directive_asciiz(data: str, memory: Memory) -> int: - """Asciiz directive. - - :param name: str: - :param data: str: - :param memory: Memory: - """ + """Asciiz directive.""" string = data[1:-1].encode("ascii", "ignore").decode("unicode_escape") address = memory.extend_data(bytesify(string, null_byte=True)) return address def directive_ascii(data: str, memory: Memory) -> int: - """Ascii directive. - - :param name: str: - :param data: str: - :param memory: Memory: - """ + """Ascii directive.""" string = data[1:-1].encode("ascii", "ignore").decode("unicode_escape") address = memory.extend_data(bytesify(string, null_byte=False)) return address def directive_byte(data: str, memory: Memory) -> int: - """Byte directive. - - :param name: str: - :param data: str: - :param memory: Memory: - """ + """Byte directive.""" value = bytesify(parse_int(data), size=1) address = memory.extend_data(value) return address def directive_half(data: str, memory: Memory) -> int: - """Half directive. - - :param name: str: - :param data: str: - :param memory: Memory: - """ + """Half directive.""" value = bytesify(parse_int(data), size=2) address = memory.extend_data(value) return address def directive_word(data: str, memory: Memory) -> int: - """Word directive. - - :param name: str: - :param data: str: - :param memory: Memory: - """ + """Word directive.""" value = bytesify(parse_int(data), size=4) address = memory.extend_data(value) return address def directive_space(data: str, memory: Memory) -> int: - """Space directive. - - :param name: str: - :param data: str: - :param memory: Memory: - """ + """Space directive.""" value = parse_int(data) if value > 0x77359400: # 2 Gigabytes of space... - raise Exception("Please use less memory...") + raise MipsException("Please use less memory...") address = memory.extend_data(bytes([0] * value)) return address diff --git a/dashmips/extension.py b/dashmips/extension.py index 432108d..9521b31 100644 --- a/dashmips/extension.py +++ b/dashmips/extension.py @@ -32,7 +32,7 @@ def generate_snippets(examples: bool = False) -> Dict[str, Dict[str, str]]: "scope": "mips", } if examples: - example = build_example(ins.name, ins.pattern, ins.label) + example = build_example(ins.name, ins.pattern) snippets[name]["example"] = example return snippets @@ -40,7 +40,6 @@ def generate_snippets(examples: bool = False) -> Dict[str, Dict[str, str]]: def build_body(name: str, pattern: str, label: bool) -> str: """Create snippet body. - :param label: :param name: Instruction name :param pattern: Instruction regex pattern """ diff --git a/dashmips/instructions/Instruction.py b/dashmips/instructions/Instruction.py index 3c92394..0bbca4c 100644 --- a/dashmips/instructions/Instruction.py +++ b/dashmips/instructions/Instruction.py @@ -8,9 +8,8 @@ class Instruction: """Instruction Class, callable.""" - def __init__(self, fn, regex_ptrn: str, parser, label: bool = False): - """ - Regex and argument parser for instruction. + def __init__(self, fn, regex_pattern: str, parser, label: bool = False): + """Regex and argument parser for instruction. Adds itself to list upon instantiation. """ @@ -27,8 +26,8 @@ def __init__(self, fn, regex_ptrn: str, parser, label: bool = False): self.description = "" self.label = label - self.pattern = regex_ptrn - self.regex = f"({self.name}){regex_ptrn}".format(**RE.ALL) + self.pattern = regex_pattern + self.regex = f"({self.name}){regex_pattern}".format(**RE.ALL) self.parser = parser def __call__(self, program: MipsProgram, args: Iterable[Any] = tuple()): diff --git a/dashmips/instructions/__init__.py b/dashmips/instructions/__init__.py index b4ceebe..af6f4e3 100644 --- a/dashmips/instructions/__init__.py +++ b/dashmips/instructions/__init__.py @@ -11,16 +11,9 @@ def mips_instruction(pattern: str, parser, label: bool = False): - """Make an Instruction object from decorated function. - - :param pattern: param parser: - :param parser: - """ + """Make an Instruction object from decorated function.""" def decorator(function) -> Instruction: - """Instruction Decorator wrapper. - - :param function: - """ + """Instruction Decorator wrapper.""" instr = Instruction(function, pattern, parser, label=label) Instructions[instr.name] = instr return instr diff --git a/dashmips/instructions/imm_instructions.py b/dashmips/instructions/imm_instructions.py index 9cfeb68..e52f28b 100644 --- a/dashmips/instructions/imm_instructions.py +++ b/dashmips/instructions/imm_instructions.py @@ -8,29 +8,18 @@ def parse(args: Tuple[str, str, str]) -> Tuple[str]: - """Parse label to pass to instruction function. - - :param args: - """ + """Parse label to pass to instruction function.""" return (args[2],) @mips_instruction(PATTERN, parse, label=True) def j(program: MipsProgram, address: str): - """Jump unconditionally to label. - - :param program: - :param address: - """ + """Jump unconditionally to label.""" program.registers["pc"] = program.labels[address].value - 1 @mips_instruction(PATTERN, parse, label=True) def jal(program: MipsProgram, address: str): - """Jump unconditionally to label and set $ra to current $pc. - - :param program: - :param address: - """ + """Jump unconditionally to label and set $ra to current $pc.""" program.registers["$ra"] = program.registers["pc"] + 1 program.registers["pc"] = program.labels[address].value - 1 diff --git a/dashmips/instructions/pseudo_instructions.py b/dashmips/instructions/pseudo_instructions.py index 0a23339..bbc1ab9 100644 --- a/dashmips/instructions/pseudo_instructions.py +++ b/dashmips/instructions/pseudo_instructions.py @@ -6,68 +6,39 @@ @mips_instruction(r"{instr_gap}({register}){args_gap}({label})", lambda args: (args[2], args[3]), label=True) def la(program: MipsProgram, rd: str, address: str): - """Load address from immediate. - - :param program: - :param address: - :param rd: - """ + """Load address from immediate.""" program.registers[rd] = program.labels[address].value @mips_instruction(r"{instr_gap}({register}){args_gap}({number})", lambda args: (args[2], parse_int(args[3]))) def li(program: MipsProgram, rd: str, number: int): - """Load immediate. - - :param program: - :param number: - :param rd: - """ + """Load immediate.""" program.registers[rd] = number @mips_instruction(r"{instr_gap}({register}){args_gap}({register})", lambda args: (args[2], args[3])) def move(program: MipsProgram, rd: str, rs: str): - """Overwrite rd with rs. - - :param program: - :param rs: - :param rd: - """ + """Overwrite rd with rs.""" program.registers[rd] = program.registers[rs] @mips_instruction(r"{instr_gap}({register}){args_gap}({label})", lambda args: (args[2], args[3])) def beqz(program: MipsProgram, rd: str, label: str): - """Branch to label if Reg[rd] == 0. - - :param program: - :param rd: - :param label: - """ + """Branch to label if Reg[rd] == 0.""" if program.registers[rd] == 0: program.registers["pc"] = program.labels[label].value - 1 @mips_instruction(r"{instr_gap}({register}){args_gap}({label})", lambda args: (args[2], args[3])) def bnez(program: MipsProgram, rd: str, label: str): - """Branch to label if Reg[rd] != 0. - - :param program: - :param rd: - :param label: - """ + """Branch to label if Reg[rd] != 0.""" if program.registers[rd] != 0: program.registers["pc"] = program.labels[label].value - 1 @mips_instruction(r"{instr_gap}({label})", lambda args: (args[2],)) def b(program: MipsProgram, label: str): - """Branch. - - :param program: - :param label: - """ + """Branch unconditionally to label.""" program.registers["pc"] = program.labels[label].value - 1 @@ -76,11 +47,7 @@ def b(program: MipsProgram, label: str): lambda args: (args[2], args[3], args[4]), ) def bgt(program: MipsProgram, rd: str, rs: str, label: str): - """Branch to label if Reg[rd]>Reg[rs]. - - :param program: - :param label: - """ + """Branch to label if Reg[rd]>Reg[rs].""" if rs not in program.registers: rs_val = parse_int(rs) else: @@ -95,11 +62,7 @@ def bgt(program: MipsProgram, rd: str, rs: str, label: str): lambda args: (args[2], args[3], args[4]) ) def blt(program: MipsProgram, rd: str, rs: str, label: str): - """Branch to label if Reg[rd]Reg[rs]. - - :param program: - :param label: - """ + """Branch to label if Reg[rd]>Reg[rs].""" if program.registers[rd] > program.registers[rs]: program.registers["pc"] = program.labels[label].value - 1 @@ -138,10 +93,6 @@ def bge(program: MipsProgram, rd: str, rs: str, label: str): lambda args: (args[2], args[3], args[4]), ) def ble(program: MipsProgram, rd: str, rs: str, label: str): - """Branch to label if Reg[rd] Tuple[str, int]: - """Parse rd and imm to pass to instruction function. - - :param args: - """ + """Parse rd and imm to pass to instruction function.""" return (args[2], parse_int(args[3])) @mips_instruction(PATTERN, parse) def lui(program: MipsProgram, rd: str, immediate: int): - """Load upper bits from immediate. - - :param program: - :param rd: - :param immediate: - """ + """Load upper bits from immediate.""" program.registers[rd] = (immediate << 16) & 0xFFFF_0000 diff --git a/dashmips/instructions/rd_instructions.py b/dashmips/instructions/rd_instructions.py index f8c370c..e98ee65 100644 --- a/dashmips/instructions/rd_instructions.py +++ b/dashmips/instructions/rd_instructions.py @@ -8,48 +8,29 @@ def parse(args: Tuple[str, str, str]) -> Tuple[str]: - """Parser for single register instructions. - - :param args: - """ + """Parser for single register instructions.""" return (args[2],) @mips_instruction(PATTERN, parse) def mflo(program: MipsProgram, rd: str): - """Move from lo register to Reg[rd]. - - :param program: - :param rd: - """ + """Move from lo register to Reg[rd].""" program.registers[rd] = program.registers["lo"] @mips_instruction(PATTERN, parse) def mfhi(program: MipsProgram, rd: str): - """Move from hi register to Reg[rd]. - - :param program: - :param rd: - """ + """Move from hi register to Reg[rd].""" program.registers[rd] = program.registers["hi"] @mips_instruction(PATTERN, parse) def mthi(program: MipsProgram, rd: str): - """Move to hi register from Reg[rd]. - - :param program: - :param rd: - """ + """Move to hi register from Reg[rd].""" program.registers["hi"] = program.registers[rd] @mips_instruction(PATTERN, parse) def mtlo(program: MipsProgram, rd: str): - """Move to lo register from Reg[rd]. - - :param program: - :param rd: - """ + """Move to lo register from Reg[rd].""" program.registers["lo"] = program.registers[rd] diff --git a/dashmips/instructions/rd_rs_lbl_instructions.py b/dashmips/instructions/rd_rs_lbl_instructions.py index cc5e245..9b5a739 100644 --- a/dashmips/instructions/rd_rs_lbl_instructions.py +++ b/dashmips/instructions/rd_rs_lbl_instructions.py @@ -8,34 +8,19 @@ def parse(arg: Tuple[str, str, str, str, str]) -> Tuple[str, str, str]: - """Two Register and Immediate instructions Parser. - - :param arg: - """ + """Two Register and Immediate instructions Parser.""" return (arg[2], arg[3], arg[4]) @mips_instruction(PATTERN, parse) def beq(program: MipsProgram, rs: str, rt: str, label: str): - """Branch to label if Reg[rs] == Reg[rt]. - - :param program: - :param rt: - :param rs: - :param label: - """ + """Branch to label if Reg[rs] == Reg[rt].""" if program.registers[rs] == program.registers[rt]: program.registers["pc"] = program.labels[label].value - 1 @mips_instruction(PATTERN, parse) def bne(program: MipsProgram, rs: str, rt: str, label: str): - """Branch to label if Reg[rs] != Reg[rt]. - - :param program: - :param rt: - :param rs: - :param label: - """ + """Branch to label if Reg[rs] != Reg[rt].""" if program.registers[rs] != program.registers[rt]: program.registers["pc"] = program.labels[label].value - 1 diff --git a/dashmips/instructions/rd_rs_rt_instructions.py b/dashmips/instructions/rd_rs_rt_instructions.py index f8a060d..d45c227 100644 --- a/dashmips/instructions/rd_rs_rt_instructions.py +++ b/dashmips/instructions/rd_rs_rt_instructions.py @@ -8,84 +8,45 @@ def parse(args: Tuple[str, str, str, str, str]) -> Tuple[str, str, str]: - """Parser for rd rs rt format instructions. - - :param args: - """ + """Parser for rd rs rt format instructions.""" return (args[2], args[3], args[4]) @mips_instruction(PATTERN, parse) def add(program: MipsProgram, rd: str, rs: str, rt: str): - """Add Reg[rd] = Reg[rs] + Reg[rt]. - - :param program: - :param rs: - :param rd: - :param rt: - """ + """Add Reg[rd] = Reg[rs] + Reg[rt].""" program.registers[rd] = program.registers[rs] + program.registers[rt] @mips_instruction(PATTERN, parse) def addu(program: MipsProgram, rd: str, rs: str, rt: str): - """Add unsigned Reg[rd] = Reg[rs] + Reg[rt]. - - :param program: - :param rs: - :param rd: - :param rt: - """ + """Add unsigned Reg[rd] = Reg[rs] + Reg[rt].""" program.registers[rd] = program.registers[rs] + program.registers[rt] @mips_instruction(PATTERN, parse) def _and(program: MipsProgram, rd: str, rs: str, rt: str): - """Bitwise And Reg[rd] = Reg[rs] & Reg[rt]. - - :param program: - :param rs: - :param rd: - :param rt: - """ + """Bitwise And Reg[rd] = Reg[rs] & Reg[rt].""" program.registers[rd] = program.registers[rs] & program.registers[rt] @mips_instruction(PATTERN, parse) def movn(program: MipsProgram, rd: str, rs: str, rt: str): - """Move conditional Reg[rd] = Reg[rs] if Reg[rt] != 0. - - :param program: - :param rs: - :param rd: - :param rt: - """ + """Move conditional Reg[rd] = Reg[rs] if Reg[rt] != 0.""" if program.registers[rt] != 0: program.registers[rd] = program.registers[rs] @mips_instruction(PATTERN, parse) def movz(program: MipsProgram, rd: str, rs: str, rt: str): - """Move conditional Reg[rd] = Reg[rs] if Reg[rt] == 0. - - :param program: - :param rs: - :param rd: - :param rt: - """ + """Move conditional Reg[rd] = Reg[rs] if Reg[rt] == 0.""" if program.registers[rt] == 0: program.registers[rd] = program.registers[rs] @mips_instruction(PATTERN, parse) def mul(program: MipsProgram, rd: str, rs: str, rt: str): - """Multiplication without overflow. - - :param program: - :param rs: - :param rd: - :param rt: - """ + """Multiplication without overflow.""" # FIXME: Correctness check. product = program.registers[rs] * program.registers[rt] program.registers["hi"] = product & 0xFFFFFFFF_00000000 @@ -94,49 +55,25 @@ def mul(program: MipsProgram, rd: str, rs: str, rt: str): @mips_instruction(PATTERN, parse) def nor(program: MipsProgram, rd: str, rs: str, rt: str): - """Bitwise Nor Reg[rd] = ~(Reg[rs] | Reg[rt]). - - :param program: - :param rs: - :param rd: - :param rt: - """ + """Bitwise Nor Reg[rd] = ~(Reg[rs] | Reg[rt]).""" program.registers[rd] = ~(program.registers[rs] | program.registers[rt]) @mips_instruction(PATTERN, parse) def _or(program: MipsProgram, rd: str, rs: str, rt: str): - """Bitwise And Reg[rd] = Reg[rs] | Reg[rt]. - - :param program: - :param rs: - :param rd: - :param rt: - """ + """Bitwise And Reg[rd] = Reg[rs] | Reg[rt].""" program.registers[rd] = program.registers[rs] | program.registers[rt] @mips_instruction(PATTERN, parse) def sllv(program: MipsProgram, rd: str, rs: str, rt: str): - """Shift Left Logical. - - :param program: - :param rs: - :param rd: - :param rt: - """ + """Shift Left Logical.""" program.registers[rd] = program.registers[rs] << program.registers[rt] @mips_instruction(PATTERN, parse) def slt(program: MipsProgram, rd: str, rs: str, rt: str): - """Set on less than. - - :param program: - :param rs: - :param rd: - :param rt: - """ + """Set on less than.""" if program.registers[rs] < program.registers[rt]: program.registers[rd] = 1 else: @@ -145,13 +82,7 @@ def slt(program: MipsProgram, rd: str, rs: str, rt: str): @mips_instruction(PATTERN, parse) def sltu(program: MipsProgram, rd: str, rs: str, rt: str): - """Set on less than unsigned. - - :param program: - :param rs: - :param rd: - :param rt: - """ + """Set on less than unsigned.""" if abs(program.registers[rs]) < abs(program.registers[rt]): program.registers[rd] = 1 else: @@ -160,13 +91,7 @@ def sltu(program: MipsProgram, rd: str, rs: str, rt: str): @mips_instruction(PATTERN, parse) def srav(program: MipsProgram, rd: str, rs: str, rt: str): - """Bitwise Shift Right Arithmetic Variable. - - :param program: - :param rs: - :param rd: - :param rt: - """ + """Bitwise Shift Right Arithmetic Variable.""" msb = program.registers[rs] & 0x8000_0000 program.registers[rd] = program.registers[rs] << program.registers[rt] program.registers[rd] |= msb @@ -174,47 +99,23 @@ def srav(program: MipsProgram, rd: str, rs: str, rt: str): @mips_instruction(PATTERN, parse) def srlv(program: MipsProgram, rd: str, rs: str, rt: str): - """Bitwise Shift Right Logical Variable. - - :param program: - :param rs: - :param rd: - :param rt: - """ + """Bitwise Shift Right Logical Variable.""" program.registers[rd] = program.registers[rs] >> program.registers[rt] @mips_instruction(PATTERN, parse) def sub(program: MipsProgram, rd: str, rs: str, rt: str): - """Subtract Reg[rd] = Reg[rs] - Reg[rt]. - - :param program: - :param rs: - :param rd: - :param rt: - """ + """Subtract Reg[rd] = Reg[rs] - Reg[rt].""" program.registers[rd] = program.registers[rs] - program.registers[rt] @mips_instruction(PATTERN, parse) def subu(program: MipsProgram, rd: str, rs: str, rt: str): - """Subtract unsigned Reg[rd] = Reg[rs] - Reg[rt]. - - :param program: - :param rs: - :param rd: - :param rt: - """ + """Subtract unsigned Reg[rd] = Reg[rs] - Reg[rt].""" program.registers[rd] = program.registers[rs] - program.registers[rt] @mips_instruction(PATTERN, parse) def xor(program: MipsProgram, rd: str, rs: str, rt: str): - """Bitwise And Reg[rd] = Reg[rs] ^ Reg[rt]. - - :param program: - :param rs: - :param rd: - :param rt: - """ + """Bitwise And Reg[rd] = Reg[rs] ^ Reg[rt].""" program.registers[rd] = program.registers[rs] ^ program.registers[rt] diff --git a/dashmips/instructions/rs_imm_instructions.py b/dashmips/instructions/rs_imm_instructions.py index 57357b7..e8a8acf 100644 --- a/dashmips/instructions/rs_imm_instructions.py +++ b/dashmips/instructions/rs_imm_instructions.py @@ -8,81 +8,48 @@ def parse(arg: Tuple[str, str, str, str]) -> Tuple[str, str]: - """Parser for reg imm insructions. - - :param arg: - """ + """Parser for reg imm insructions.""" return (arg[2], arg[3]) @mips_instruction(PATTERN, parse, label=True) def bgez(program: MipsProgram, rs: str, label: str): - """Branch if Reg[rs] >= 0. - - :param program: - :param label: - :param rs: - """ + """Branch if Reg[rs] >= 0.""" if program.registers[rs] >= 0: program.registers["pc"] = program.labels[label].value - 1 @mips_instruction(PATTERN, parse, label=True) def bgezal(program: MipsProgram, rs: str, label: str): - """Branch if Reg[rs] >= 0 and link. - - :param program: - :param label: - :param rs: - """ + """Branch if Reg[rs] >= 0 and link.""" if program.registers[rs] >= 0: program.registers["pc"] = program.labels[label].value - 1 @mips_instruction(PATTERN, parse, label=True) def bgtz(program: MipsProgram, rs: str, label: str): - """Branch if Reg[rs] > 0. - - :param program: - :param label: - :param rs: - """ + """Branch if Reg[rs] > 0.""" if program.registers[rs] > 0: program.registers["pc"] = program.labels[label].value - 1 @mips_instruction(PATTERN, parse, label=True) def blez(program: MipsProgram, rs: str, label: str): - """Branch if Reg[rs] <= 0. - - :param program: - :param label: - :param rs: - """ + """Branch if Reg[rs] <= 0.""" if program.registers[rs] <= 0: program.registers["pc"] = program.labels[label].value - 1 @mips_instruction(PATTERN, parse, label=True) def bltz(program: MipsProgram, rs: str, label: str): - """Branch if Reg[rs] < 0. - - :param program: - :param label: - :param rs: - """ + """Branch if Reg[rs] < 0.""" if program.registers[rs] < 0: program.registers["pc"] = program.labels[label].value - 1 @mips_instruction(PATTERN, parse, label=True) def bltzal(program: MipsProgram, rs: str, label: str): - """Branch if Reg[rs] < 0 and link. - - :param program: - :param label: - :param rs: - """ + """Branch if Reg[rs] < 0 and link.""" if program.registers[rs] < 0: program.registers["$ra"] = program.registers["pc"] program.registers["pc"] = program.labels[label].value - 1 diff --git a/dashmips/instructions/rs_instructions.py b/dashmips/instructions/rs_instructions.py index 052c543..b325281 100644 --- a/dashmips/instructions/rs_instructions.py +++ b/dashmips/instructions/rs_instructions.py @@ -8,18 +8,11 @@ def parse(arg: Tuple[str, str, str]) -> Tuple[str]: - """Single Register instruction parser. - - :param arg: - """ + """Single Register instruction parser.""" return (arg[2],) @mips_instruction(PATTERN, parse) def jr(program: MipsProgram, rs: str): - """Jump to address in Reg[rs]. - - :param program: - :param rs: - """ + """Jump to address in Reg[rs].""" program.registers["pc"] = program.registers[rs] - 1 diff --git a/dashmips/instructions/rs_mem_instructions.py b/dashmips/instructions/rs_mem_instructions.py index a42dc74..abee443 100644 --- a/dashmips/instructions/rs_mem_instructions.py +++ b/dashmips/instructions/rs_mem_instructions.py @@ -9,10 +9,7 @@ def parse(args: Tuple[str, str, str, str, str]) -> Tuple[str, int, str]: - """Register and Memory access Instructions Parser. - - :param arg: - """ + """Register and Memory access Instructions Parser.""" offset = 0 if args[3]: offset = parse_int(args[3]) @@ -22,37 +19,19 @@ def parse(args: Tuple[str, str, str, str, str]) -> Tuple[str, int, str]: @mips_instruction(PATTERN, parse) def lb(program: MipsProgram, rs: str, num: int, rt: str): - """Load Byte from memory. - - :param program: - :param num: - :param rs: - :param rt: - """ + """Load Byte from memory.""" program.registers[rs] = intify(program.memory.read08(num + program.registers[rt])) @mips_instruction(PATTERN, parse) def lbu(program: MipsProgram, rs: str, num: int, rt: str): - """Load Byte Unsigned from memory. - - :param program: - :param num: - :param rs: - :param rt: - """ + """Load Byte Unsigned from memory.""" program.registers[rs] = intify(program.memory.read08(num + program.registers[rt]), unsigned=True) @mips_instruction(PATTERN, parse) def lh(program: MipsProgram, rs: str, num: int, rt: str): - """Load half-word from memory. - - :param program: - :param num: - :param rs: - :param rt: - """ + """Load half-word from memory.""" # FIXME: This does not sign extend correctly address = num + program.registers[rt] val = 0 @@ -62,13 +41,7 @@ def lh(program: MipsProgram, rs: str, num: int, rt: str): @mips_instruction(PATTERN, parse) def lhu(program: MipsProgram, rs: str, num: int, rt: str): - """Load half-word unsigned from memory. - - :param program: - :param num: - :param rs: - :param rt: - """ + """Load half-word unsigned from memory.""" address = num + program.registers[rt] val = 0 values = program.memory.read16(address) @@ -77,13 +50,7 @@ def lhu(program: MipsProgram, rs: str, num: int, rt: str): @mips_instruction(PATTERN, parse) def lw(program: MipsProgram, rs: str, num: int, rt: str): - """Load word from memory. - - :param program: - :param num: - :param rs: - :param rt: - """ + """Load word from memory.""" address = num + program.registers[rt] val = 0 values = program.memory.read32(address) @@ -92,13 +59,7 @@ def lw(program: MipsProgram, rs: str, num: int, rt: str): @mips_instruction(PATTERN, parse) def sb(program: MipsProgram, rs: str, num: int, rt: str): - """Store Byte to memory. - - :param program: - :param num: - :param rs: - :param rt: - """ + """Store Byte to memory.""" value = program.registers[rs] address = num + program.registers[rt] program.memory.write08(address, bytesify(value, size=1)) @@ -106,13 +67,7 @@ def sb(program: MipsProgram, rs: str, num: int, rt: str): @mips_instruction(PATTERN, parse) def sh(program: MipsProgram, rs: str, num: int, rt: str): - """Store halfword to memory. - - :param program: - :param num: - :param rs: - :param rt: - """ + """Store halfword to memory.""" value = program.registers[rs] address = num + program.registers[rt] program.memory.write16(address, bytesify(value, size=2)) @@ -120,13 +75,7 @@ def sh(program: MipsProgram, rs: str, num: int, rt: str): @mips_instruction(PATTERN, parse) def sw(program: MipsProgram, rs: str, num: int, rt: str): - """Store word to memory. - - :param program: - :param num: - :param rs: - :param rt: - """ + """Store word to memory.""" value = program.registers[rs] address = num + program.registers[rt] program.memory.write32(address, bytesify(value, size=4)) diff --git a/dashmips/instructions/rs_rt_imm_instructions.py b/dashmips/instructions/rs_rt_imm_instructions.py index ba331f7..4dc9925 100644 --- a/dashmips/instructions/rs_rt_imm_instructions.py +++ b/dashmips/instructions/rs_rt_imm_instructions.py @@ -9,71 +9,38 @@ def parse(arg: Tuple[str, str, str, str, str]) -> Tuple[str, str, int]: - """Two Register and Immediate instructions Parser. - - :param arg: - """ + """Two Register and Immediate instructions Parser.""" return (arg[2], arg[3], parse_int(arg[4])) @mips_instruction(PATTERN, parse) def addi(program: MipsProgram, rs: str, rt: str, num: int): - """Add immediate Reg[rs] = Reg[rt] + immediate. - - :param program: - :param rt: - :param rs: - :param num: - """ + """Add immediate Reg[rs] = Reg[rt] + immediate.""" program.registers[rs] = program.registers[rt] + num @mips_instruction(PATTERN, parse) def addiu(program: MipsProgram, rs: str, rt: str, num: int): - """Add immediate unsigned Reg[rs] = Reg[rt] + immediate. - - :param program: - :param rt: - :param rs: - :param num: - """ + """Add immediate unsigned Reg[rs] = Reg[rt] + immediate.""" program.registers[rs] = ( abs(program.registers[rt]) + abs(num)) & 0xFFFF_FFFF @mips_instruction(PATTERN, parse) def ori(program: MipsProgram, rs: str, rt: str, num: int): - """Or immediate Reg[rs] = Reg[rt] | immediate. - - :param program: - :param rt: - :param rs: - :param num: - """ + """Or immediate Reg[rs] = Reg[rt] | immediate.""" program.registers[rs] = program.registers[rt] | num @mips_instruction(PATTERN, parse) def andi(program: MipsProgram, rs: str, rt: str, num: int): - """And immediate Reg[rs] = Reg[rt] & immediate. - - :param program: - :param rt: - :param rs: - :param num: - """ + """And immediate Reg[rs] = Reg[rt] & immediate.""" program.registers[rs] = program.registers[rt] & num @mips_instruction(PATTERN, parse) def slti(program: MipsProgram, rs: str, rt: str, num: int): - """Set on less than immediate. - - :param program: - :param rt: - :param rs: - :param num: - """ + """Set on less than immediate.""" if program.registers[rt] < num: program.registers[rs] = 1 else: @@ -82,13 +49,7 @@ def slti(program: MipsProgram, rs: str, rt: str, num: int): @mips_instruction(PATTERN, parse) def sltiu(program: MipsProgram, rs: str, rt: str, num: int): - """Set on less than immediate unsigned. - - :param program: - :param rt: - :param rs: - :param num: - """ + """Set on less than immediate unsigned.""" if abs(program.registers[rt]) < abs(num): program.registers[rs] = 1 else: @@ -97,25 +58,13 @@ def sltiu(program: MipsProgram, rs: str, rt: str, num: int): @mips_instruction(PATTERN, parse) def xori(program: MipsProgram, rs: str, rt: str, num: int): - """Xor immediate Reg[rs] = Reg[rt] ^ immediate. - - :param program: - :param rt: - :param rs: - :param num: - """ + """Xor immediate Reg[rs] = Reg[rt] ^ immediate.""" program.registers[rs] = program.registers[rt] ^ num @mips_instruction(PATTERN, parse) def sra(program: MipsProgram, rd: str, rs: str, num: int): - """Shift Right Arithmetic. - - :param program: - :param rd: - :param rs: - :param num: - """ + """Shift Right Arithmetic.""" msb = program.registers[rs] & 0x8000_0000 program.registers[rd] = program.registers[rs] << num program.registers[rd] |= msb @@ -123,23 +72,11 @@ def sra(program: MipsProgram, rd: str, rs: str, num: int): @mips_instruction(PATTERN, parse) def sll(program: MipsProgram, rd: str, rt: str, num: int): - """Shift Left Logical. - - :param program: - :param rt: - :param rs: - :param num: - """ + """Shift Left Logical.""" program.registers[rd] = (program.registers[rt] << num) & 0xFFFF_FFFF @mips_instruction(PATTERN, parse) def srl(program: MipsProgram, rd: str, rt: str, num: int): - """Shift Right Logical. - - :param program: - :param rt: - :param rs: - :param num: - """ + """Shift Right Logical.""" program.registers[rd] = (program.registers[rt] >> num) & 0xFFFF_FFFF diff --git a/dashmips/instructions/rs_rt_instructions.py b/dashmips/instructions/rs_rt_instructions.py index 981f1d0..6ce5d7f 100644 --- a/dashmips/instructions/rs_rt_instructions.py +++ b/dashmips/instructions/rs_rt_instructions.py @@ -8,33 +8,20 @@ def parse(arg: Tuple[str, str, str, str]) -> Tuple[str, str]: - """Two Register Instructions Parser. - - :param arg: - """ + """Two Register Instructions Parser.""" return (arg[2], arg[3]) @mips_instruction(PATTERN, parse) def jalr(program: MipsProgram, rs: str, rt: str): - """Jump and link register. Store pc into rs, jump to rt. - - :param program: - :param rt: - :param rs: - """ + """Jump and link register. Store pc into rs, jump to rt.""" program.registers[rs] = program.registers["pc"] program.registers["pc"] = program.registers[rt] - 1 @mips_instruction(PATTERN, parse) def madd(program: MipsProgram, rs: str, rt: str): - """Multiply Add. - - :param program: - :param rt: - :param rs: - """ + """Multiply Add.""" product = program.registers[rs] * program.registers[rt] program.registers["hi"] += product & 0xFFFFFFFF_00000000 program.registers["lo"] += product & 0x00000000_FFFFFFFF @@ -42,12 +29,7 @@ def madd(program: MipsProgram, rs: str, rt: str): @mips_instruction(PATTERN, parse) def maddu(program: MipsProgram, rs: str, rt: str): - """Multiply Add Unsigned. - - :param program: - :param rt: - :param rs: - """ + """Multiply Add Unsigned.""" product = abs(program.registers[rs]) * abs(program.registers[rt]) program.registers["hi"] += product & 0xFFFFFFFF_00000000 program.registers["lo"] += product & 0x00000000_FFFFFFFF @@ -55,12 +37,7 @@ def maddu(program: MipsProgram, rs: str, rt: str): @mips_instruction(PATTERN, parse) def msubu(program: MipsProgram, rs: str, rt: str): - """Multiply Subtract Unsigned. - - :param program: - :param rt: - :param rs: - """ + """Multiply Subtract Unsigned.""" product = abs(program.registers[rs]) * abs(program.registers[rt]) program.registers["hi"] -= product & 0xFFFFFFFF_00000000 program.registers["lo"] -= product & 0x00000000_FFFFFFFF @@ -68,12 +45,7 @@ def msubu(program: MipsProgram, rs: str, rt: str): @mips_instruction(PATTERN, parse) def msub(program: MipsProgram, rs: str, rt: str): - """Multiply Subtract. - - :param program: - :param rt: - :param rs: - """ + """Multiply Subtract.""" product = program.registers[rs] * program.registers[rt] program.registers["hi"] -= product & 0xFFFFFFFF_00000000 program.registers["lo"] -= product & 0x00000000_FFFFFFFF @@ -81,12 +53,7 @@ def msub(program: MipsProgram, rs: str, rt: str): @mips_instruction(PATTERN, parse) def multu(program: MipsProgram, rs: str, rt: str): - """Multiply Unsigned. - - :param program: - :param rt: - :param rs: - """ + """Multiply Unsigned.""" product = abs(program.registers[rs]) * abs(program.registers[rt]) program.registers["hi"] = product & 0xFFFFFFFF_00000000 program.registers["lo"] = product & 0x00000000_FFFFFFFF @@ -94,12 +61,7 @@ def multu(program: MipsProgram, rs: str, rt: str): @mips_instruction(PATTERN, parse) def mult(program: MipsProgram, rs: str, rt: str): - """Multiply. - - :param program: - :param rt: - :param rs: - """ + """Multiply.""" product = program.registers[rs] * program.registers[rt] program.registers["hi"] = product & 0xFFFFFFFF_00000000 program.registers["lo"] = product & 0x00000000_FFFFFFFF @@ -107,12 +69,7 @@ def mult(program: MipsProgram, rs: str, rt: str): @mips_instruction(PATTERN, parse) def clo(program: MipsProgram, rs: str, rt: str): - """Count number of leading ones in Reg[rt]. - - :param program: - :param rt: - :param rs: - """ + """Count number of leading ones in Reg[rt].""" bit_to_check = 1 << 32 val = program.registers[rt] count = 0 @@ -124,12 +81,7 @@ def clo(program: MipsProgram, rs: str, rt: str): @mips_instruction(PATTERN, parse) def clz(program: MipsProgram, rs: str, rt: str): - """Count number of leading zeros in Reg[rt]. - - :param program: - :param rt: - :param rs: - """ + """Count number of leading zeros in Reg[rt].""" bit_to_check = 1 << 32 val = program.registers[rt] count = 0 @@ -141,12 +93,7 @@ def clz(program: MipsProgram, rs: str, rt: str): @mips_instruction(PATTERN, parse) def div(program: MipsProgram, rs: str, rt: str): - """Divide. - - :param program: - :param rt: - :param rs: - """ + """Divide.""" quotient = program.registers[rs] / program.registers[rt] remainder = program.registers[rs] % program.registers[rt] program.registers["hi"] = remainder @@ -155,12 +102,7 @@ def div(program: MipsProgram, rs: str, rt: str): @mips_instruction(PATTERN, parse) def divu(program: MipsProgram, rs: str, rt: str): - """Divide unsigned. - - :param program: - :param rt: - :param rs: - """ + """Divide unsigned.""" quotient = abs(program.registers[rs]) / abs(program.registers[rt]) remainder = abs(program.registers[rs]) % abs(program.registers[rt]) program.registers["hi"] = remainder diff --git a/dashmips/instructions/special_instructions.py b/dashmips/instructions/special_instructions.py index b4bbb99..74ebdc3 100644 --- a/dashmips/instructions/special_instructions.py +++ b/dashmips/instructions/special_instructions.py @@ -7,26 +7,17 @@ def parse(arg: Tuple[str, str]): - """Instructions that take no arguments. - - :param arg: - """ + """Instructions that take no arguments.""" return tuple() @mips_instruction("", parse) def nop(program: MipsProgram): - """Do nothing. - - :param program: - """ + """Do nothing.""" pass @mips_instruction("", parse) def syscall(program: MipsProgram): - """Call syscall specified in $v0. - - :param program: - """ + """Call syscall specified in $v0.""" return Syscalls[program.registers["$v0"]](program) diff --git a/dashmips/models.py b/dashmips/models.py index 4dca5f4..2232c2d 100644 --- a/dashmips/models.py +++ b/dashmips/models.py @@ -2,8 +2,10 @@ from dataclasses import dataclass, field, asdict from typing import Dict, List, Any +from .utils import hexdump from .hardware import Memory, Registers + @dataclass class SourceLine: """Mips Preprocessor Label.""" @@ -42,23 +44,23 @@ class MipsProgram: eqvs: Dict[str, str] = field(default_factory=dict) exited: bool = False - @staticmethod - def from_dict(prg: Dict[str, Any]) -> "MipsProgram": - """From Basic dictionary to MipsProgram. - - :param prg: - """ - prg["memory"] = bytearray().fromhex(prg["memory"]) - # prg["registers"] = check_registers(prg["registers"]) - prg["labels"] = {ln: Label(**l) for ln, l in prg["labels"].items()} - prg["source"] = [SourceLine(**m) for m in prg["source"]] - return MipsProgram(**prg) - def to_dict(self) -> Dict[str, Any]: - """Two item iterable for dictionary making.""" - program_dict = asdict(self) - program_dict["memory"] = program_dict["memory"].hex() - return program_dict + """Program object to simple dict.""" + memory_str = { + "stack": hexdump(self.memory.ram["stack"]["m"]), + "data": hexdump(self.memory.ram["data"]["m"]), + "heap": hexdump(self.memory.ram["heap"]["m"]), + } + return { + "name": self.name, + "filenames": self.filenames, + "labels": {n: asdict(l) for n, l in self.labels.items()}, + "source": [asdict(s) for s in self.source], + "memory": memory_str, + "registers": self.registers, + "eqvs": self.eqvs, + "exited": self.exited, + } @property def current_line(self) -> SourceLine: diff --git a/dashmips/preprocessor.py b/dashmips/preprocessor.py index 649e7bd..eb82f19 100644 --- a/dashmips/preprocessor.py +++ b/dashmips/preprocessor.py @@ -13,9 +13,6 @@ def preprocess(file: TextIO, args: Optional[List[str]] = None) -> MipsProgram: """Prepare Mips for running. Breaks the code into directive and text sections. - - :param args: - :param file: TextIO: """ filename = os.path.abspath(file.name) memory = Memory() # type: ignore @@ -64,8 +61,6 @@ def split_to_sections(code: List[SourceLine]) -> Tuple[List[str], List[SourceLin """Handle file with mixed sections. .text and .data sections can come in any order. - - :param code: """ section: Optional[str] = None if code[0].line in [mipsRE.DATA_SEC, mipsRE.TEXT_SEC]: @@ -93,10 +88,6 @@ def data_labels(labels: Dict[str, Label], data_sec: List[str], memory: Memory): """Construct the .data section to spec. Fill the .data section memory with user defined static data - - :param labels: - :param data_sec: - :param memory: """ data_line_re = f"(?:({mipsRE.LABEL}):)?\\s*({mipsRE.DIRECTIVE})\\s+(.*)" for line in data_sec: @@ -120,9 +111,6 @@ def code_labels(labels: Dict[str, Label], text_sec: List[SourceLine]) -> List[So """Construct the .text section to spec. Fill the .text section memory with user code - - :param labels: - :param text_sec: """ from .instructions import Instructions @@ -155,10 +143,7 @@ def code_labels(labels: Dict[str, Label], text_sec: List[SourceLine]) -> List[So def process_file(file: TextIO) -> List[SourceLine]: - """Process Mips File. - - :param file: Mips source file - """ + """Process Mips File.""" filename = os.path.abspath(file.name) code = file.read() linenumbers = list(enumerate(code.splitlines())) @@ -184,10 +169,7 @@ def manyspaces_to_onespace(ln: SourceLine) -> SourceLine: def preprocessor_directives(lines: List[SourceLine]) -> Tuple[List[str], Dict[str, str], List[SourceLine]]: - """Preprocessor Directives handler. - - :param lines: lines to compile. - """ + """Preprocessor Directives handler.""" for idx, srcline in enumerate(lines): if ".globl" in srcline.line: del lines[idx] diff --git a/dashmips/run.py b/dashmips/run.py index 1b57c6b..27a7b9b 100644 --- a/dashmips/run.py +++ b/dashmips/run.py @@ -11,11 +11,7 @@ def run(program: MipsProgram, runnable: Callable[[MipsProgram], bool] = RUN_CONDITION) -> int: - """Execute Preprocessed Mips. - - :param program: MipsProgram: - :param runnable: (Default value = lambda p: p.registers["pc"] != -1) - """ + """Execute Preprocessed Mips.""" try: while runnable(program): next_instruction(program) @@ -28,10 +24,7 @@ def run(program: MipsProgram, runnable: Callable[[MipsProgram], bool] = RUN_COND def next_instruction(program: MipsProgram): - """Execute One Instruction. - - :param program: - """ + """Execute One Instruction.""" current_pc = program.registers["pc"] if current_pc >= len(program.source): # We jumped or executed beyond available text diff --git a/dashmips/syscalls/__init__.py b/dashmips/syscalls/__init__.py index 668b459..b014857 100644 --- a/dashmips/syscalls/__init__.py +++ b/dashmips/syscalls/__init__.py @@ -16,14 +16,9 @@ def mips_syscall(number: int): Note: If you use this to make a new instruction YOU MUST import that function in `dashmips/__init__.py` - - :param number: """ def decorator(function: Callable[[MipsProgram], None]) -> Syscall: - """Syscall Decorator wrapper. - - :param function: - """ + """Syscall Decorator wrapper.""" syscall = Syscall(function, number) Syscalls[syscall.number] = syscall return syscall diff --git a/dashmips/syscalls/print_syscalls.py b/dashmips/syscalls/print_syscalls.py index f993ca3..e007073 100644 --- a/dashmips/syscalls/print_syscalls.py +++ b/dashmips/syscalls/print_syscalls.py @@ -6,10 +6,7 @@ @mips_syscall(4) def print_string(program: MipsProgram): - """Print string at address provided in $a0. - - :param program: - """ + """Print string at address provided in $a0.""" address = program.registers["$a0"] bin_string = [] offset = 0 @@ -34,10 +31,7 @@ def print_char(program: MipsProgram): @mips_syscall(5) def read_int(program: MipsProgram): - """Read Int from stdin. - - :param program: - """ + """Read Int from stdin.""" user_in = input("") try: program.registers["$v0"] = int(user_in, 10) @@ -47,38 +41,26 @@ def read_int(program: MipsProgram): @mips_syscall(1) def print_int(program: MipsProgram): - """Print Int. - - :param program: - """ + """Print Int.""" print(program.registers["$a0"], end="") @mips_syscall(34) def print_hex_int(program: MipsProgram): - """Print Int in Hex. - - :param program: - """ + """Print Int in Hex.""" print(f"0x{program.registers['$a0']:08x}", end="") @mips_syscall(10) def _exit(program: MipsProgram): - """Exit MIPS Program. - - :param program: - """ + """Exit MIPS Program.""" # Internal definition of exited program program.exited = True @mips_syscall(45) def dump_program(program: MipsProgram): - """Print json format of program. - - :param program: - """ + """Print json format of program.""" import json print(json.dumps(program.to_dict(), indent=4)) From 2da7155f6a9b76650f7f8b01785bcf36771f5bb9 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Wed, 21 Aug 2019 13:05:33 -0400 Subject: [PATCH 2/4] compile command update --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5225613..7d83581 100644 --- a/README.md +++ b/README.md @@ -23,12 +23,18 @@ If you installed via pip you should now have a binary in your path that you can dashmips ``` +or equivalently + +```sh +python -m dashmips +``` + ## "Compiling" To compile or run a mips program you run: ```sh -dashmips compile -f FILE.mips +dashmips compile FILE.mips ``` What "compilation" means in dashmips is a conversion of the source file to a json format that is better understood by the program. You can use this json format to inspect the internals of how your mips program is interpreted by dashmips. From f930b3b9c1c7ea7b70e94c853de364ff66b519e4 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Wed, 21 Aug 2019 13:09:33 -0400 Subject: [PATCH 3/4] Optimized imports --- dashmips/debugger.py | 2 +- dashmips/directives.py | 3 +-- dashmips/instructions/__init__.py | 1 - dashmips/instructions/pseudo_instructions.py | 2 +- dashmips/instructions/rd_imm_instructions.py | 2 +- dashmips/instructions/rs_mem_instructions.py | 2 +- dashmips/instructions/rs_rt_imm_instructions.py | 2 +- dashmips/models.py | 2 +- dashmips/preprocessor.py | 2 +- dashmips/run.py | 2 +- dashmips/syscalls/print_syscalls.py | 2 +- 11 files changed, 10 insertions(+), 12 deletions(-) diff --git a/dashmips/debugger.py b/dashmips/debugger.py index cdd7e2c..d92e8cc 100644 --- a/dashmips/debugger.py +++ b/dashmips/debugger.py @@ -9,9 +9,9 @@ import os from typing import List, Dict, Any, Tuple -from .utils import MipsException from .models import MipsProgram from .run import next_instruction, run +from .utils import MipsException def debug_start(program: MipsProgram, params=None) -> Dict[str, int]: diff --git a/dashmips/directives.py b/dashmips/directives.py index 74af85c..eb9059e 100644 --- a/dashmips/directives.py +++ b/dashmips/directives.py @@ -1,8 +1,7 @@ """Directive handling.""" -from typing import Union -from .utils import parse_int, bytesify, MipsException from .hardware import Memory +from .utils import parse_int, bytesify, MipsException def directive_align(data: str, memory: Memory): diff --git a/dashmips/instructions/__init__.py b/dashmips/instructions/__init__.py index af6f4e3..6a46b65 100644 --- a/dashmips/instructions/__init__.py +++ b/dashmips/instructions/__init__.py @@ -3,7 +3,6 @@ NOTE: If you add a new file/module to this package *YOU MUST* import the file to `dashmips/__init__.py` """ -from typing import Union from .Instruction import Instruction diff --git a/dashmips/instructions/pseudo_instructions.py b/dashmips/instructions/pseudo_instructions.py index bbc1ab9..5c3b596 100644 --- a/dashmips/instructions/pseudo_instructions.py +++ b/dashmips/instructions/pseudo_instructions.py @@ -1,7 +1,7 @@ """Instructions that are not real.""" -from ..utils import parse_int from . import mips_instruction from ..models import MipsProgram +from ..utils import parse_int @mips_instruction(r"{instr_gap}({register}){args_gap}({label})", lambda args: (args[2], args[3]), label=True) diff --git a/dashmips/instructions/rd_imm_instructions.py b/dashmips/instructions/rd_imm_instructions.py index e6ca399..3e142e9 100644 --- a/dashmips/instructions/rd_imm_instructions.py +++ b/dashmips/instructions/rd_imm_instructions.py @@ -1,9 +1,9 @@ """Instructions that accept a register and immediate as an argument.""" from typing import Tuple -from ..utils import parse_int from . import mips_instruction from ..models import MipsProgram +from ..utils import parse_int PATTERN = r"{instr_gap}({register}){args_gap}({number})" diff --git a/dashmips/instructions/rs_mem_instructions.py b/dashmips/instructions/rs_mem_instructions.py index abee443..9515b3e 100644 --- a/dashmips/instructions/rs_mem_instructions.py +++ b/dashmips/instructions/rs_mem_instructions.py @@ -2,8 +2,8 @@ from typing import Tuple from . import mips_instruction -from ..utils import parse_int, intify, bytesify from ..models import MipsProgram +from ..utils import parse_int, intify, bytesify PATTERN = r"{instr_gap}({register}){args_gap}({number}?)\(({register})\)" diff --git a/dashmips/instructions/rs_rt_imm_instructions.py b/dashmips/instructions/rs_rt_imm_instructions.py index 4dc9925..6b88314 100644 --- a/dashmips/instructions/rs_rt_imm_instructions.py +++ b/dashmips/instructions/rs_rt_imm_instructions.py @@ -1,9 +1,9 @@ """Two Register and Immediate instructions.""" from typing import Tuple -from ..utils import parse_int from . import mips_instruction from ..models import MipsProgram +from ..utils import parse_int PATTERN = r"{instr_gap}({register}){args_gap}({register}){args_gap}({number})" diff --git a/dashmips/models.py b/dashmips/models.py index 2232c2d..07c3241 100644 --- a/dashmips/models.py +++ b/dashmips/models.py @@ -2,8 +2,8 @@ from dataclasses import dataclass, field, asdict from typing import Dict, List, Any -from .utils import hexdump from .hardware import Memory, Registers +from .utils import hexdump @dataclass diff --git a/dashmips/preprocessor.py b/dashmips/preprocessor.py index eb82f19..0b73168 100644 --- a/dashmips/preprocessor.py +++ b/dashmips/preprocessor.py @@ -3,10 +3,10 @@ import re from typing import Any, Dict, Iterable, List, Optional, TextIO, Tuple -from .utils import MipsException, bytesify, hexdump from .hardware import Memory, Registers from .mips import RE as mipsRE, Directives from .models import Label, MipsProgram, SourceLine +from .utils import MipsException, bytesify def preprocess(file: TextIO, args: Optional[List[str]] = None) -> MipsProgram: diff --git a/dashmips/run.py b/dashmips/run.py index 27a7b9b..fead23c 100644 --- a/dashmips/run.py +++ b/dashmips/run.py @@ -3,9 +3,9 @@ import sys from typing import Callable -from .utils import MipsException from .instructions import Instructions from .models import MipsProgram +from .utils import MipsException RUN_CONDITION: Callable[[MipsProgram], bool] = (lambda p: not p.exited) diff --git a/dashmips/syscalls/print_syscalls.py b/dashmips/syscalls/print_syscalls.py index e007073..589070a 100644 --- a/dashmips/syscalls/print_syscalls.py +++ b/dashmips/syscalls/print_syscalls.py @@ -1,7 +1,7 @@ """Syscalls related to printing.""" from . import mips_syscall -from ..utils import intify from ..models import MipsProgram +from ..utils import intify @mips_syscall(4) From 11d29831480e9dd91c36715f2b9705567f5b9313 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Wed, 21 Aug 2019 13:13:22 -0400 Subject: [PATCH 4/4] version bump --- poetry.lock | 4 ++-- pyproject.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 66ba4f3..65e2c1a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -164,7 +164,7 @@ description = "pytest: simple powerful testing with Python" name = "pytest" optional = false python-versions = ">=3.5" -version = "5.1.0" +version = "5.1.1" [package.dependencies] atomicwrites = ">=1.0" @@ -345,7 +345,7 @@ py = ["64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa", "dc639 pycodestyle = ["95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56", "e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c"] pydocstyle = ["2258f9b0df68b97bf3a6c29003edc5238ff8879f1efb6f1999988d934e432bd8", "5741c85e408f9e0ddf873611085e819b809fca90b619f5fd7f34bd4959da3dd4", "ed79d4ec5e92655eccc21eb0c6cf512e69512b4a97d215ace46d17e4990f2039"] pyparsing = ["6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80", "d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4"] -pytest = ["3805d095f1ea279b9870c3eeae5dddf8a81b10952c8835cd628cf1875b0ef031", "abc562321c2d190dd63c2faadf70b86b7af21a553b61f0df5f5e1270717dc5a3"] +pytest = ["95b1f6db806e5b1b5b443efeb58984c24945508f93a866c1719e1a507a957d7c", "c3d5020755f70c82eceda3feaf556af9a341334414a8eca521a18f463bcead88"] pytest-mypy = ["419d1d4877d41a6a80f0eb31faa7c50bb9445557f7ff1b02a1a26d10d7dc7691", "917438af835beb87f14c9f6261137f8e992b3bf87ebf73f836ac7ede03424a0f"] pytest-pycodestyle = ["d4f1c1d633158c1a27b02a40cf8e27da7264a9cbd6f59b5d692368e82412ac78"] pytest-pydocstyle = ["701d0590be48bf80691521c646d956c5fa5ebb40324505dcd107e3022a773d7a"] diff --git a/pyproject.toml b/pyproject.toml index 4b4f23e..eb52228 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "dashmips" -version = "0.0.11" +version = "0.1.0" description = "Mips Interpreter" authors = ["Neal Beeken "] license = "MIT"