1 -- as for deep thoughts ISA
2 -----------------------------------------------------------------------------
7 import Control.Applicative hiding ((<|>),many)
10 import System.Environment
13 import Text.Parsec.String
14 import Text.Parsec.Combinator
15 import qualified Data.Map as M
18 import qualified Data.ByteString.Lazy as BL
25 content <- getContents
26 let src = (filter (((/=) "") . snd) $ (zip [1..] (lines content)))
27 let (dict,formatedsrc) = convertDTF src NoState 0x00 0x00 [("start_",0x00)]
28 if (not $ null args) && ("-d" `elem` args)
31 sequence_ [printf "%20s @ 0x%08x\n" l a | (l,a) <- (reverse dict)]
32 printf "\nparsed asm:\n"
33 sequence_ [printf "%s" (show x) | x <- formatedsrc]
34 printf "\nafter parsing the instructions:\n"
37 let base = if "-b" `elem` args then 2 else 16
38 let parsed = parseInstr dict formatedsrc
39 sequence_ [printf "%s" (showsDTFBase x base "") | x <- parsed]
42 parseInstr :: [DictElem] -> [DTF] -> [DTF]
44 parseInstr dict ((DTF_InstrToParse a instr c l s):xs) =
45 (DTF_Instr a bytecode c l s):(parseInstr dict xs)
47 bytecode = case (parse (instruction (a,dict)) "" (instr++"\n")) of
48 Left err -> error ("couldn't parse Instruction: " ++ instr ++ "\n" ++ show err)
50 parseInstr dict (x:xs) = x:(parseInstr dict xs)
55 inc :: Counter -> Counter
59 convertDTF :: [(Int,String)] -> DT_State -> Counter -> Counter -> [DictElem] -> ([DictElem], [DTF])
60 convertDTF [] _ _ _ d = (d,[])
61 convertDTF ((lno,str):xs) state datacnt instrcnt dict = (newdict, (actlist newdtf))
63 actlist (DTF_Org _) = next
64 actlist (DTF_State _) = next
65 actlist (DTF_Define _ _ _) = next
66 actlist (DTF_Fill rep val code l c) = if state == InData then
67 (DTF_Data datacnt val code l c):[(DTF_Data dc val "" "" "") | i<-[2..repi], let dc = [(datacnt+0x4),(datacnt+0x8)..]!!(i-2)] ++ next
69 (DTF_Instr instrcnt val code l c):[(DTF_Instr ic val "" "" "") | i<-[2..repi], let ic = [(instrcnt+0x4),(instrcnt+0x8)..]!!(i-2)] ++ next
72 repi = fromInteger (toInteger rep)
75 (newdict,next) = convertDTF xs (nstate newdtf) (ndatacnt newdtf) (ninstrcnt newdtf) (ndict newdtf)
77 ndatacnt (DTF_Org adr)
78 | state == InData = adr
80 ndatacnt (DTF_Fill rep _ _ _ _)
81 | state == InData = datacnt + (4*rep)
83 ndatacnt (DTF_Data _ _ _ _ _) = inc datacnt
86 ninstrcnt (DTF_Org adr)
87 | state == InText = adr
88 | otherwise = instrcnt
89 ninstrcnt (DTF_Fill rep _ _ _ _)
90 | state == InText = instrcnt + (4*rep)
91 | otherwise = instrcnt
92 ninstrcnt (DTF_Instr _ _ _ _ _) = inc instrcnt
93 ninstrcnt (DTF_InstrToParse _ _ _ _ _) = inc instrcnt
94 ninstrcnt _ = instrcnt
96 nstate (DTF_State s) = s
99 ndict (DTF_Label l _ a) = dict `add_elem` (l,a)
100 ndict (DTF_SectionToDet a _ _ l _) = dict `add_elem` (l,a)
101 ndict (DTF_InstrToParse a _ _ l _) = dict `add_elem` (l,a)
102 ndict (DTF_Data a _ _ l _) = dict `add_elem` (l,a)
103 ndict (DTF_Instr a _ _ l _) = dict `add_elem` (l,a)
104 ndict (DTF_Define l v _) = dict `add_elem` (l,v)
105 ndict (DTF_Fill _ _ _ l _)
106 | state == InText = dict `add_elem` (l,instrcnt)
107 | state == InData = dict `add_elem` (l,datacnt)
110 newdtf = case (parse (parseDTFLine dict) "" (str++"\n")) of
111 Left err -> error ("couldn't parse line " ++ (show lno) ++ ": " ++ (show err))
112 Right (DTF_SectionToDet _ v c l s) ->
114 NoState -> error "missing .data or .text"
115 InData -> (DTF_Data datacnt v c l s)
116 InText -> (DTF_Instr instrcnt v c l s)
117 Right (DTF_InstrToParse _ v c l s) ->
118 (DTF_InstrToParse instrcnt v c l s)
119 Right y@(DTF_Org _) ->
121 NoState -> error "missing .data or .text"
123 Right (DTF_Label l c _) ->
125 NoState -> error "missing .data or .text"
126 InData -> (DTF_Label l c datacnt)
127 InText -> (DTF_Label l c instrcnt)
128 Right z -> z -- DTF_Comment, DTF_State, DTF_Define, DTF_Fill
132 testDTF :: String -> IO ()
134 case (parse (parseDTFLine dict) "" (input++"\n")) of
135 Left err -> do { putStr "failz ;(\n"; print err}
136 Right x -> do { print x }
138 dict = [("lolz", 0x1337), ("rofl", 0xaaaa)]
140 parseDTFLine :: [DictElem] -> Parser DTF
141 parseDTFLine dict = foldl1 (<|>) (fmap (\x -> try (x dict)) lineFormats) <* char '\n'
143 lineFormats = [lf_define, lf_sdata, lf_stext, lf_org, lf_data, lf_comment, lf_toparse, lf_label]
146 parseIdent :: Parser String
149 idents <- many $ (letter <|> digit <|> char '_')
150 return $ (ident:idents)
152 parseLabel :: Parser String
158 parseComment :: Parser String
162 comment <- many $ noneOf "\n"
165 parseConst :: [DictElem] -> Parser Word32
166 parseConst d = expr d
170 l <- try (parseLabel) <|> string ""
172 fill <- string ".fill "
173 repeat <- try (do {size <- many1 $ noneOf "\n;,"; char ','; return $ size}) <|> return "1"
174 -- TODO: atm 32bit imm only
175 code <- many1 $ noneOf "\n;"
176 let val = case parse (parseConst d) "" code of
178 Left err -> error $ show err
179 let r = case parse (parseConst d) "" repeat of
181 Left err -> error $ show err
182 comment <- try(parseComment) <|> parseMySpaces
183 return $ DTF_Fill r val (fill ++ (if repeat == "1" then "" else repeat) ++ code) l comment
186 comment <- parseComment
187 return $ DTF_Comment comment
191 comment <- try(parseComment) <|> parseMySpaces
192 return $ DTF_Label l comment 0
195 l <- try(parseLabel) <|> string ""
197 code <- many1 $ noneOf "\n;"
198 comment <- try(parseComment) <|> parseMySpaces
199 return $ DTF_InstrToParse 0 code code l comment
212 return $ DTF_State InData
218 return $ DTF_State InText
226 -- TODO: expressions with (expr) do not work ;(
228 comment <- try(parseComment) <|> parseMySpaces
229 return $ DTF_Define id ret comment