From f84dcda74e13120c5433591feeeed7e7d4c5f322 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Sat, 6 Jan 2018 16:18:30 +0100 Subject: checkpoint: passed FibonacciElement test --- .../FibonacciElement/FibonacciElement.asm | 413 +++++++++++++++++++++ .../FibonacciElement/FibonacciElement.out | 2 + projects/08/VMTranslator | Bin 86992 -> 93776 bytes projects/08/VMTranslator.hs | 40 +- projects/08/VMTranslator.o | Bin 104536 -> 118200 bytes 5 files changed, 443 insertions(+), 12 deletions(-) create mode 100644 projects/08/FunctionCalls/FibonacciElement/FibonacciElement.asm create mode 100644 projects/08/FunctionCalls/FibonacciElement/FibonacciElement.out 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 index b1b665f..c4481c4 100755 Binary files a/projects/08/VMTranslator and b/projects/08/VMTranslator differ 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 index 09c5269..3afefab 100644 Binary files a/projects/08/VMTranslator.o and b/projects/08/VMTranslator.o differ -- cgit v1.2.3