summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuchen Pei <me@ypei.me>2018-01-06 16:18:30 +0100
committerYuchen Pei <me@ypei.me>2018-01-06 16:18:30 +0100
commitf84dcda74e13120c5433591feeeed7e7d4c5f322 (patch)
tree50e25247c426e1ac3be9f0c24de65489ee32b4a6
parent19cf47dd1c6e9d7c265ed52270eebd9095b49a8c (diff)
checkpoint: passed FibonacciElement test
-rw-r--r--projects/08/FunctionCalls/FibonacciElement/FibonacciElement.asm413
-rw-r--r--projects/08/FunctionCalls/FibonacciElement/FibonacciElement.out2
-rwxr-xr-xprojects/08/VMTranslatorbin86992 -> 93776 bytes
-rw-r--r--projects/08/VMTranslator.hs40
-rw-r--r--projects/08/VMTranslator.obin104536 -> 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
index b1b665f..c4481c4 100755
--- a/projects/08/VMTranslator
+++ b/projects/08/VMTranslator
Binary files 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
--- a/projects/08/VMTranslator.o
+++ b/projects/08/VMTranslator.o
Binary files differ