From 4d095367dfd58825a4d8ad17c92c146993add538 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Tue, 19 Dec 2017 16:43:37 +0100 Subject: finished first draft of assembler --- projects/06/Assembler | Bin 0 -> 65896 bytes projects/06/Assembler.hi | Bin 0 -> 1961 bytes projects/06/Assembler.hs | 38 +++++++++++++++++++++++++++++--------- projects/06/Assembler.o | Bin 0 -> 76496 bytes 4 files changed, 29 insertions(+), 9 deletions(-) create mode 100755 projects/06/Assembler create mode 100644 projects/06/Assembler.hi create mode 100644 projects/06/Assembler.o diff --git a/projects/06/Assembler b/projects/06/Assembler new file mode 100755 index 0000000..7cd3b78 Binary files /dev/null and b/projects/06/Assembler differ diff --git a/projects/06/Assembler.hi b/projects/06/Assembler.hi new file mode 100644 index 0000000..5e0382b Binary files /dev/null and b/projects/06/Assembler.hi differ diff --git a/projects/06/Assembler.hs b/projects/06/Assembler.hs index 1545e15..28f506d 100644 --- a/projects/06/Assembler.hs +++ b/projects/06/Assembler.hs @@ -2,16 +2,17 @@ import Numeric (showIntAtBase) import Data.Char (intToDigit) import Data.Map (Map) import qualified Data.Map as Map -import Data.List.Split (splitOn) +import Data.List.Split (splitOn, splitOneOf) parseLine :: Map [Char] [Char] -> [Char] -> [Char] parseLine table (x:xs) - | x == '@' && (head xs `elem` ['0'..'9']) = int2Bin16 $ read xs - | x == '@' = table Map.! xs - | '=' `elem` xs = let [dests, alu] = splitOn "=" (x:xs) in "111" ++ (parseALU alu) ++ (parseDests dests) ++ "000" - | ';' + | x == '@' && (head xs `elem` ['0'..'9']) = (int2Bin16 $ read xs) ++ "\n" + | x == '@' = table Map.! xs ++ "\n" + | '=' `elem` (x:xs) && ';' `elem` (x:xs) = let [dest, comp, jump] = splitOneOf "=;" (x:xs) in "111" ++ (parseComp comp) ++ (parseDest dest) ++ (parseJump jump) ++ "\n" + | '=' `elem` (x:xs) = let [dest, comp] = splitOn "=" (x:xs) in "111" ++ (parseComp comp) ++ (parseDest dest) ++ "000" ++ "\n" + | ';' `elem` (x:xs) = let [comp, jump] = splitOn ";" (x:xs) in "111" ++ (parseComp comp) ++ "000" ++ (parseJump jump) ++ "\n" -parseALU xs = case xs of +parseComp xs = case xs of "0" -> "0101010" "1" -> "0111111" "-1" -> "0111010" @@ -47,10 +48,19 @@ parseALU xs = case xs of "D|M" -> "1010101" "M|D" -> "1010101" - -parseDests xs = (f 'A'):(f 'D'):(f 'M'):[] +parseDest xs = (f 'A'):(f 'D'):(f 'M'):[] where f x = if x `elem` xs then '1' else '0' +parseJump xs = case xs of + "" -> "000" + "JGT" -> "001" + "JEQ" -> "010" + "JGE" -> "011" + "JLT" -> "100" + "JNE" -> "101" + "JLE" -> "110" + "JMP" -> "111" + int2Bin x = showIntAtBase 2 intToDigit x "" int2Bin16 :: Int -> [Char] @@ -63,6 +73,9 @@ initTable = Map.fromList $ (\(x, y) -> (x, int2Bin16 y)) <$> ("SP", 0):("LCL", 1 stripJunk :: [Char] -> [[Char]] stripJunk xs = filter (not . null) $ (filter (not . (flip elem " \t")) . head . (splitOn "//")) <$> splitOn "\n" xs +stripLabels :: [[Char]] -> [[Char]] +stripLabels = filter (not . (elem '(')) + addSyms :: [[Char]] -> Int -> Int -> Map [Char] [Char] -> Map [Char] [Char] addSyms [] _ _ table = table addSyms ((hd:tl):rest) addr vaddr table @@ -70,4 +83,11 @@ addSyms ((hd:tl):rest) addr vaddr table | hd == '@' && tl `Map.notMember` table = addSyms rest (addr + 1) (vaddr + 1) (Map.insert tl (int2Bin16 vaddr) table) | otherwise = addSyms rest (addr + 1) vaddr table ---addSyms (stripJunk input) 0 16 initTable +parseCode :: [Char] -> [Char] +parseCode code = mconcat $ parseLine (addSyms codeWithoutJunk 0 16 initTable) <$> codeWithoutLabels + where codeWithoutJunk = stripJunk code + codeWithoutLabels = stripLabels codeWithoutJunk + +main = do + code <- getContents + putStr $ parseCode code diff --git a/projects/06/Assembler.o b/projects/06/Assembler.o new file mode 100644 index 0000000..09d8785 Binary files /dev/null and b/projects/06/Assembler.o differ -- cgit v1.2.3