summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederick Yin <fkfd@fkfd.me>2022-08-22 17:24:46 +0800
committerFrederick Yin <fkfd@fkfd.me>2022-08-22 17:24:46 +0800
commit51c8325661eab4667a11431175f12eb6a08cc36a (patch)
treed39105d6ddd7e81d19720c9547387b1a020c9a93
parent2632ca447c9925dca084c07cf76790fecffb2943 (diff)
hack-vm: branching
-rw-r--r--projects/hack-vm/__main__.py3
-rw-r--r--projects/hack-vm/branching.py24
2 files changed, 27 insertions, 0 deletions
diff --git a/projects/hack-vm/__main__.py b/projects/hack-vm/__main__.py
index a1dce1f..5373fe9 100644
--- a/projects/hack-vm/__main__.py
+++ b/projects/hack-vm/__main__.py
@@ -2,6 +2,7 @@ from argparse import ArgumentParser
from .memory import translate_memory
from .arith_logic import translate_arith_logic
from .compare import translate_compare
+from .branching import translate_branching
from .utils import *
@@ -38,6 +39,8 @@ def vm_translate(input_path):
asm += translate_arith_logic(command)
case [("lt" | "eq" | "gt") as command]:
asm += translate_compare(command)
+ case [("label" | "goto" | "if-goto") as action, label]:
+ asm += translate_branching(action, label)
case _:
exit_on_error(
f"Syntax error: invalid command: {cmd}", EXIT_CODE_SYNTAX_ERROR
diff --git a/projects/hack-vm/branching.py b/projects/hack-vm/branching.py
new file mode 100644
index 0000000..b73ed94
--- /dev/null
+++ b/projects/hack-vm/branching.py
@@ -0,0 +1,24 @@
+from .utils import *
+
+LABEL_ASM = "({label})\n"
+
+GOTO_ASM = """@{label}
+0;JMP
+"""
+
+IF_GOTO_ASM = """@SP
+AM=M-1
+D=M
+@{label}
+D;JNE
+"""
+
+BRANCHING_ASM = {
+ "label": LABEL_ASM,
+ "goto": GOTO_ASM,
+ "if-goto": IF_GOTO_ASM,
+}
+
+
+def translate_branching(action, label):
+ return BRANCHING_ASM[action].format(label=label)