diff options
author | Yuchen Pei <me@ypei.me> | 2018-01-02 19:14:29 +0100 |
---|---|---|
committer | Yuchen Pei <me@ypei.me> | 2018-01-02 19:14:29 +0100 |
commit | 98111ae037b165ca8deb2d0b73d3194a1e71d45c (patch) | |
tree | 646b12ad2e8fd8242fd743248b8506efc23b5c7a /projects | |
parent | 381e730b9b4f07eec97865ed94cff4c189c39ad1 (diff) |
almost done with project 07 part 2
Diffstat (limited to 'projects')
-rw-r--r-- | projects/07/VMTranslator.hs | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/projects/07/VMTranslator.hs b/projects/07/VMTranslator.hs index 289c0d4..a1f93e6 100644 --- a/projects/07/VMTranslator.hs +++ b/projects/07/VMTranslator.hs @@ -15,6 +15,32 @@ parse' op [] n f "or" = '|'; f "neg" = '-'; f "not" = '!' parse' "push" ["constant", x] _ = "@" ++ x ++ "\nD=A\n" ++ push "D" +parse' cmd [seg, x] _ | seg `elem` ["local", "argument", "this", "that"] = + case cmd of + | "push" -> getAddr seg x ++ push "D" + | "pop" -> getAddr seg x ++ "@R13\nM=D\n" ++ pop "M" ++ "@R13\nA=M\nM=D\n" + +parse' cmd [seg, x] _ | seg `elem` ["pointer", "temp"] = + case cmd of + | "push" -> getAddr' seg x ++ "D=M\n" ++ push "D" + | "pop" -> pop "M" ++ getAddr' seg x ++ "M=D\n" + +parse' cmd ["static", x] _ = + case cmd of + | "push" -> getAddr'' x ++ "D=M\n" ++ push "D" + | "pop" -> pop "M" ++ getAddr'' x ++ "M=D\n" + +getAddr seg x = "@" ++ seg2Lab seg ++ "\nD=M\n@" ++ x ++ "\nA=D+M\nD=M\n" + +getAddr' seg x = "@" ++ show (read x + (if seg == "pointer" then 3 else 5)) ++ "\n" + +getAddr'' x = "@" ++ filename ++ "." ++ x ++ "\n" + +seg2Lab seg = case seg of + | "local" -> "LCL" + | "argument" -> "ARG" + | "this" -> "THIS" + | "that" -> "THAT" push :: [Char] -> [Char] push xs = "@SP\nA=M\nM=" ++ xs ++ "\n@SP\nM=M+1\n" |