From d6a48c54755a6f1bde076f4bbdd2cc218a092f60 Mon Sep 17 00:00:00 2001 From: Frederick Yin Date: Tue, 23 Aug 2022 20:30:57 +0800 Subject: hack-vm: function commands and verbose mode --- projects/hack-vm/function.py | 125 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 projects/hack-vm/function.py (limited to 'projects/hack-vm/function.py') diff --git a/projects/hack-vm/function.py b/projects/hack-vm/function.py new file mode 100644 index 0000000..596c9cf --- /dev/null +++ b/projects/hack-vm/function.py @@ -0,0 +1,125 @@ +CALL_ASM = """@{return_address} +D=A +@SP +A=M +M=D +@LCL +D=A +@SP +AM=M+1 +M=D +@ARG +D=A +@SP +AM=M+1 +M=D +@THIS +D=A +@SP +AM=M+1 +M=D +@THAT +D=A +@SP +AM=M+1 +M=D +@SP +DM=M+1 +@LCL +M=D +@{arg_lcl_offset} +D=D-A +@ARG +M=D +@{function_label} +0;JMP +({return_address}) +""" + +FUNCTION_ASM = """({function_label}) +@SP +A=M +M=0 +{init_vars}@SP +M=M+1 +""" + +# repeated for each local variable of function +INIT_VAR_ASM = """@SP +AM=M+1 +M=0 +""" + +RETURN_ASM = """@ARG +A=M +D=M +@{tmp} +M=D +@SP +A=M-1 +D=M +@ARG +A=M +M=D +@ARG +D=M+1 +@SP +M=D +@LCL +AM=M-1 +D=M +@THAT +M=D +@LCL +AM=M-1 +D=M +@THIS +M=D +@LCL +AM=M-1 +D=M +@ARG +M=D +@LCL +AM=M-1 +D=M +@LCL +M=D +@{tmp} +A=M +0;JMP +""" + +ret_idx = {} + + +def translate_function(action, function, n, prog, verbose=False): + global ret_idx + try: + n = int(n) + except ValueError: + exit_on_error(f"Syntax error: not an integer: {n}", EXIT_CODE_SYNTAX_ERROR) + + asm = f"// {action} {function} {n}\n" if verbose else "" + if action == "call": + if prog not in ret_idx: + ret_idx[prog] = 0 + else: + ret_idx[prog] += 1 + asm += CALL_ASM.format( + return_address=f"{prog}$ret.{ret_idx[prog]}", + arg_lcl_offset=(5 + n), + function_label=f"{function}", + ) + else: + asm += FUNCTION_ASM.format( + function_label=f"{function}", init_vars=INIT_VAR_ASM * (n - 1) + ) + + return asm + + +def translate_return(verbose=False): + asm = "// return\n" if verbose else "" + asm += RETURN_ASM.format(tmp="R13") + return asm -- cgit v1.2.3