diff options
author | Yuchen Pei <me@ypei.me> | 2018-01-06 16:18:30 +0100 |
---|---|---|
committer | Yuchen Pei <me@ypei.me> | 2018-01-06 16:18:30 +0100 |
commit | f84dcda74e13120c5433591feeeed7e7d4c5f322 (patch) | |
tree | 50e25247c426e1ac3be9f0c24de65489ee32b4a6 | |
parent | 19cf47dd1c6e9d7c265ed52270eebd9095b49a8c (diff) |
checkpoint: passed FibonacciElement test
-rw-r--r-- | projects/08/FunctionCalls/FibonacciElement/FibonacciElement.asm | 413 | ||||
-rw-r--r-- | projects/08/FunctionCalls/FibonacciElement/FibonacciElement.out | 2 | ||||
-rwxr-xr-x | projects/08/VMTranslator | bin | 86992 -> 93776 bytes | |||
-rw-r--r-- | projects/08/VMTranslator.hs | 40 | ||||
-rw-r--r-- | projects/08/VMTranslator.o | bin | 104536 -> 118200 bytes |
5 files changed, 443 insertions, 12 deletions
diff --git a/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.asm b/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.asm new file mode 100644 index 0000000..9d98a3f --- /dev/null +++ b/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.asm @@ -0,0 +1,413 @@ +@256 +D=A +@SP +M=D +@RET0 +D=A +@SP +A=M +M=D +@SP +M=M+1 +@LCL +D=M +@SP +A=M +M=D +@SP +M=M+1 +@ARG +D=M +@SP +A=M +M=D +@SP +M=M+1 +@THIS +D=M +@SP +A=M +M=D +@SP +M=M+1 +@THAT +D=M +@SP +A=M +M=D +@SP +M=M+1 +@SP +D=M +@LCL +M=D +@5 +D=D-A +@0 +D=D-A +@ARG +M=D +@Sys.init +0;JMP +(RET0) +(Main.fibonacci) +@ARG +D=M +@0 +D=A+D +A=D +D=M +@SP +A=M +M=D +@SP +M=M+1 +@2 +D=A +@SP +A=M +M=D +@SP +M=M+1 +@SP +AM=M-1 +D=M +@SP +AM=M-1 +D=M-D +@IFMain3 +D;JLT +@SP +A=M +M=0 +@SP +M=M+1 +@ENDIFMain3 +0;JMP +(IFMain3) +@SP +A=M +M=-1 +@SP +M=M+1 +(ENDIFMain3) +@SP +AM=M-1 +D=M +@Main.fibonacci$IF_TRUE +D;JNE +@Main.fibonacci$IF_FALSE +0;JMP +(Main.fibonacci$IF_TRUE) +@ARG +D=M +@0 +D=A+D +A=D +D=M +@SP +A=M +M=D +@SP +M=M+1 +@LCL +D=M +@R13 +M=D +@SP +AM=M-1 +D=M +@ARG +A=M +M=D +@ARG +D=M+1 +@SP +M=D +@R13 +AM=M-1 +D=M +@THAT +M=D +@R13 +AM=M-1 +D=M +@THIS +M=D +@R13 +AM=M-1 +D=M +@ARG +M=D +@R13 +AM=M-1 +D=M +@LCL +M=D +@R13 +A=M-1 +A=M +0;JMP +(Main.fibonacci$IF_FALSE) +@ARG +D=M +@0 +D=A+D +A=D +D=M +@SP +A=M +M=D +@SP +M=M+1 +@2 +D=A +@SP +A=M +M=D +@SP +M=M+1 +@SP +AM=M-1 +D=M +@SP +AM=M-1 +D=M-D +@SP +A=M +M=D +@SP +M=M+1 +@RET13 +D=A +@SP +A=M +M=D +@SP +M=M+1 +@LCL +D=M +@SP +A=M +M=D +@SP +M=M+1 +@ARG +D=M +@SP +A=M +M=D +@SP +M=M+1 +@THIS +D=M +@SP +A=M +M=D +@SP +M=M+1 +@THAT +D=M +@SP +A=M +M=D +@SP +M=M+1 +@SP +D=M +@LCL +M=D +@5 +D=D-A +@1 +D=D-A +@ARG +M=D +@Main.fibonacci +0;JMP +(RET13) +@ARG +D=M +@0 +D=A+D +A=D +D=M +@SP +A=M +M=D +@SP +M=M+1 +@1 +D=A +@SP +A=M +M=D +@SP +M=M+1 +@SP +AM=M-1 +D=M +@SP +AM=M-1 +D=M-D +@SP +A=M +M=D +@SP +M=M+1 +@RET17 +D=A +@SP +A=M +M=D +@SP +M=M+1 +@LCL +D=M +@SP +A=M +M=D +@SP +M=M+1 +@ARG +D=M +@SP +A=M +M=D +@SP +M=M+1 +@THIS +D=M +@SP +A=M +M=D +@SP +M=M+1 +@THAT +D=M +@SP +A=M +M=D +@SP +M=M+1 +@SP +D=M +@LCL +M=D +@5 +D=D-A +@1 +D=D-A +@ARG +M=D +@Main.fibonacci +0;JMP +(RET17) +@SP +AM=M-1 +D=M +@SP +AM=M-1 +D=M+D +@SP +A=M +M=D +@SP +M=M+1 +@LCL +D=M +@R13 +M=D +@SP +AM=M-1 +D=M +@ARG +A=M +M=D +@ARG +D=M+1 +@SP +M=D +@R13 +AM=M-1 +D=M +@THAT +M=D +@R13 +AM=M-1 +D=M +@THIS +M=D +@R13 +AM=M-1 +D=M +@ARG +M=D +@R13 +AM=M-1 +D=M +@LCL +M=D +@R13 +A=M-1 +A=M +0;JMP +(Sys.init) +@4 +D=A +@SP +A=M +M=D +@SP +M=M+1 +@RET2 +D=A +@SP +A=M +M=D +@SP +M=M+1 +@LCL +D=M +@SP +A=M +M=D +@SP +M=M+1 +@ARG +D=M +@SP +A=M +M=D +@SP +M=M+1 +@THIS +D=M +@SP +A=M +M=D +@SP +M=M+1 +@THAT +D=M +@SP +A=M +M=D +@SP +M=M+1 +@SP +D=M +@LCL +M=D +@5 +D=D-A +@1 +D=D-A +@ARG +M=D +@Main.fibonacci +0;JMP +(RET2) +(Sys.init$WHILE) +@Sys.init$WHILE +0;JMP diff --git a/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.out b/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.out new file mode 100644 index 0000000..fdf5e2d --- /dev/null +++ b/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.out @@ -0,0 +1,2 @@ +| RAM[0] |RAM[261]| +| 262 | 3 | diff --git a/projects/08/VMTranslator b/projects/08/VMTranslator Binary files differindex b1b665f..c4481c4 100755 --- a/projects/08/VMTranslator +++ b/projects/08/VMTranslator diff --git a/projects/08/VMTranslator.hs b/projects/08/VMTranslator.hs index c3a7047..d8a2e46 100644 --- a/projects/08/VMTranslator.hs +++ b/projects/08/VMTranslator.hs @@ -6,9 +6,12 @@ import Data.List (elemIndex) import System.Directory (listDirectory) --preamble = "@256\nD=A\n@SP\nM=D\n" -preamble = "" +preamble = setSP ++ callInit + where setSP = "@256\nD=A\n@SP\nM=D\n" + callInit = parse' "call" ["Sys.init", "0"] 0 "" "" -epilogue = "(END)\n@END\n0;JMP" +--epilogue = "(END)\n@END\n0;JMP" +epilogue = "" -- parse' command restOfCommand vmLineNumber fileName functionName = asm code parse' :: [Char] -> [[Char]] -> Int -> [Char] -> [Char] -> [Char] @@ -22,9 +25,9 @@ parse' "return" [] _ _ _ = backupLCL ++ popToARG ++ moveSP ++ restore "THAT" restore name = "@R13\nAM=M-1\nD=M\n@" ++ name ++ "\nM=D\n" gotoRet = "@R13\nA=M-1\nA=M\n0;JMP\n" -parse' op [] n _ _ +parse' op [] n fileName _ | op `elem` ["add", "sub", "and", "or"] = pop "M" ++ pop ('M':(f op):"D") ++ push "D" - | op `elem` ["eq", "gt", "lt"] = pop "M" ++ pop "M-D" ++ ifThenElse op n + | op `elem` ["eq", "gt", "lt"] = pop "M" ++ pop "M-D" ++ ifThenElse op n fileName | otherwise = pop "M" ++ push (f op:"D") where f "add" = '+'; f "sub" = '-'; f "and" = '&'; f "or" = '|'; f "neg" = '-'; f "not" = '!' @@ -54,7 +57,15 @@ parse' "if-goto" [x] _ _ fName = pop "M" ++ "@" ++ fName ++ "$" ++ x ++ "\nD;JNE parse' "function" [f, n] _ _ _ = "(" ++ f ++ ")\n" ++ (mconcat $ replicate (read n) $ push "0") ---parse' "call" [f, m] n _ = +parse' "call" [f, m] n _ _ = pushRet ++ save "LCL" ++ save "ARG" ++ save "THIS" + ++ save "THAT" ++ setLCL ++ setARG ++ gotoF ++ placeRet + where pushRet = "@RET" ++ show n ++ "\nD=A\n" ++ push "D" + save x = "@" ++ x ++ "\nD=M\n" ++ push "D" + setLCL = "@SP\nD=M\n@LCL\nM=D\n" + setARG = "@5\nD=D-A\n@" ++ m ++ "\nD=D-A\n@ARG\nM=D\n" + placeRet = "(RET" ++ show n ++ ")\n" + gotoF = "@" ++ f ++ "\n0;JMP\n" +--To do the return-addr: generate label RET582 if say n==582, place the label after the goto f jump getAddr seg x = "@" ++ seg2Lab seg ++ "\nD=M\n@" ++ x ++ "\nD=A+D\n" @@ -71,11 +82,13 @@ seg2Lab seg = case seg of push :: [Char] -> [Char] push xs = "@SP\nA=M\nM=" ++ xs ++ "\n@SP\nM=M+1\n" -ifThenElse :: [Char] -> Int -> [Char] -ifThenElse cond n = "@" ++ cond' ++ show n ++ "\nD;J" ++ cond' ++ "\n" ++ push "0" - ++ "@ENDIF" ++ cond' ++ show n ++ "\n0;JMP\n(" ++ cond' ++ show n ++ ")\n" - ++ push "-1" ++ "(ENDIF" ++ cond' ++ show n ++ ")\n" - where cond' = toUpper <$> cond +-- should change @label to @IFlabel +ifThenElse :: [Char] -> Int -> [Char] -> [Char] +ifThenElse cond n fileName = "@IF" ++ label ++ "\nD;J" ++ cond' ++ "\n" ++ push "0" + ++ "@ENDIF" ++ label ++ "\n0;JMP\n(IF" ++ label ++ ")\n" + ++ push "-1" ++ "(ENDIF" ++ label ++ ")\n" + where label = fileName ++ show n + cond' = toUpper <$> cond pop :: [Char] -> [Char] pop xs = "@SP\nAM=M-1\nD=" ++ xs ++ "\n" @@ -93,7 +106,10 @@ isEmptyLine :: [Char] -> Bool isEmptyLine = null . filter (not . flip elem " \t") parseCode :: [Char] -> [Char] -> [Char] -parseCode xs filename = preamble ++ (parseline (stripJunk xs) 0 "" filename "") ++ epilogue +parseCode xs filename = (parseline (stripJunk xs) 0 "" filename "") + +parseCodes :: [[Char]] -> [[Char]] -> [Char] +parseCodes codes filenames = preamble ++ (mconcat $ zipWith parseCode codes filenames) ++ epilogue replCrWithNl :: [Char] -> [Char] replCrWithNl = fmap cr2nl @@ -112,6 +128,6 @@ main = do let ofPath = dir ++ (snd $ lastSplit '/' $ init dir) ++ ".asm" let filenames = removeExt <$> filesWODir codes <- sequence $ readFile <$> vmFiles - writeFile ofPath (mconcat $ zipWith parseCode codes filenames) + writeFile ofPath $ parseCodes codes filenames where isVMfile xs = drop (length xs - 3) xs == ".vm" removeExt xs = take (length xs - 3) xs diff --git a/projects/08/VMTranslator.o b/projects/08/VMTranslator.o Binary files differindex 09c5269..3afefab 100644 --- a/projects/08/VMTranslator.o +++ b/projects/08/VMTranslator.o |