Adds smart constructors and support for MIPS `(x)` references.

parent e24a8ad7
......@@ -28,6 +28,19 @@ data Inst = Ident String
| Ascii String
deriving Show
mkLong :: Word32 -> Inst
mkLong = Long
mkQuad :: Word64 -> Inst
mkQuad = Quad
-- | turn @x@ and @(x)@ into @Ref x@.
-- The (x) syntax can be found in mips assembly.
mkRef :: String -> Inst
mkRef ('(':r) | (')':r') <- reverse r = Ref $ reverse r'
mkRef r = Ref r
mkAscii :: String -> Inst
mkAscii = Ascii
type ASM = [(String, Inst)]
isIdent :: Inst -> Bool
......@@ -55,36 +68,36 @@ preprocess [] = []
preprocess ('\t':attr) = let (h, t) = break isSpace attr
in case h:words' (=='\t') t of
-- 8 byte values
(".quad":x:_) | isNumber (w x) -> [Quad $ read (w x)]
| otherwise -> [Ref $ (w x)]
(".xword":x:_)| isNumber (w x) -> [Quad $ read (w x)]
| otherwise -> [Ref $ (w x)]
(".8byte":x:_)| isNumber (w x) -> [Quad $ read (w x)]
| otherwise -> [Ref $ (w x)]
("data8":x:_) | isNumber (w x) -> [Quad $ read (w x)]
| otherwise -> [Ref $ (w x)]
(".quad":x:_) | isNumber (w x) -> [mkQuad $ read (w x)]
| otherwise -> [mkRef $ (w x)]
(".xword":x:_)| isNumber (w x) -> [mkQuad $ read (w x)]
| otherwise -> [mkRef $ (w x)]
(".8byte":x:_)| isNumber (w x) -> [mkQuad $ read (w x)]
| otherwise -> [mkRef $ (w x)]
("data8":x:_) | isNumber (w x) -> [mkQuad $ read (w x)]
| otherwise -> [mkRef $ (w x)]
-- 4 byte values
(".long":x:_) | isNumber (w x) -> [Long $ read (w x)]
| otherwise -> [Ref $ (w x)]
(".word":x:_) | isNumber (w x) -> [Long $ read (w x)]
| otherwise -> [Ref $ (w x)]
(".4byte":x:_)| isNumber (w x) -> [Long $ read (w x)]
| otherwise -> [Ref $ (w x)]
(".space":x:_)| (w x) == "4" -> [Long 0]
| (w x) == "8" -> [Quad 0]
(".skip":x:_) | (w x) == "4" -> [Long 0]
| (w x) == "8" -> [Quad 0]
(".ascii":x:_) -> [Ascii $ read x]
(".asciz":x:_) -> [Ascii $ read x ++ "\0"]
("stringz":x:_) -> [Ascii $ read x ++ "\0"]
(".long":x:_) | isNumber (w x) -> [mkLong $ read (w x)]
| otherwise -> [mkRef $ (w x)]
(".word":x:_) | isNumber (w x) -> [mkLong $ read (w x)]
| otherwise -> [mkRef $ (w x)]
(".4byte":x:_)| isNumber (w x) -> [mkLong $ read (w x)]
| otherwise -> [mkRef $ (w x)]
(".space":x:_)| (w x) == "4" -> [mkLong 0]
| (w x) == "8" -> [mkQuad 0]
(".skip":x:_) | (w x) == "4" -> [mkLong 0]
| (w x) == "8" -> [mkQuad 0]
(".ascii":x:_) -> [mkAscii $ read x]
(".asciz":x:_) -> [mkAscii $ read x ++ "\0"]
("stringz":x:_) -> [mkAscii $ read x ++ "\0"]
_ -> []
where w = head . words
preprocess ('.':'z':'e':'r':'o':'f':'i':'l':'l':' ':x) = case words' (==',') x of
(_seg:_sect:sym:size:_) | size == "4" -> [Ident sym, Long 0]
| size == "8" -> [Ident sym, Quad 0]
(_seg:_sect:sym:size:_) | size == "4" -> [Ident sym, mkLong 0]
| size == "8" -> [Ident sym, mkQuad 0]
_ -> []
preprocess (c:cs) | not (isSpace c) = [Ident $ takeWhile (/= ':') (c:cs)]
| otherwise = []
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment