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)]
29 sequence_ [printf "%20s @ 0x%08x\n" l a | (l,a) <- (reverse dict)]
30 printf "\nparsed asm:\n"
31 sequence_ [printf "%s" (show x) | x <- formatedsrc]
32 let parsed = parseInstr dict formatedsrc
33 printf "\nafter parsing the instructions:\n"
34 sequence_ [printf "%s" (show x) | x <- parsed]
37 parseInstr :: [DictElem] -> [DTF] -> [DTF]
39 parseInstr dict ((DTF_InstrToParse a instr c l s):xs) =
40 (DTF_Instr a bytecode c l s):(parseInstr dict xs)
42 bytecode = case (parse (instruction (a,dict)) "" (instr++"\n")) of
43 Left err -> error ("couldn't parse Instruction: " ++ instr ++ "\n" ++ show err)
45 parseInstr dict (x:xs) = x:(parseInstr dict xs)
50 inc :: Counter -> Counter
54 convertDTF :: [(Int,String)] -> DT_State -> Counter -> Counter -> [DictElem] -> ([DictElem], [DTF])
55 convertDTF [] _ _ _ d = (d,[])
56 convertDTF ((lno,str):xs) state datacnt instrcnt dict = (newdict, (actlist newdtf))
58 actlist (DTF_Org _) = next
59 actlist (DTF_State _) = next
60 actlist (DTF_Define _ _ _) = next
61 actlist (DTF_Fill rep val code l c) = if state == InData then
62 (DTF_Data datacnt val code l c):[(DTF_Data dc val "" "" "") | i<-[2..repi], let dc = [(datacnt+0x4),(datacnt+0x8)..]!!(i-2)] ++ next
64 (DTF_Instr instrcnt val code l c):[(DTF_Instr ic val "" "" "") | i<-[2..repi], let ic = [(instrcnt+0x4),(instrcnt+0x8)..]!!(i-2)] ++ next
67 repi = fromInteger (toInteger rep)
70 (newdict,next) = convertDTF xs (nstate newdtf) (ndatacnt newdtf) (ninstrcnt newdtf) (ndict newdtf)
72 ndatacnt (DTF_Org adr)
73 | state == InData = adr
75 ndatacnt (DTF_Fill rep _ _ _ _)
76 | state == InData = datacnt + (4*rep)
78 ndatacnt (DTF_Data _ _ _ _ _) = inc datacnt
81 ninstrcnt (DTF_Org adr)
82 | state == InText = adr
83 | otherwise = instrcnt
84 ninstrcnt (DTF_Fill rep _ _ _ _)
85 | state == InText = instrcnt + (4*rep)
86 | otherwise = instrcnt
87 ninstrcnt (DTF_Instr _ _ _ _ _) = inc instrcnt
88 ninstrcnt (DTF_InstrToParse _ _ _ _ _) = inc instrcnt
89 ninstrcnt _ = instrcnt
91 nstate (DTF_State s) = s
94 ndict (DTF_Label l _ a) = dict `add_elem` (l,a)
95 ndict (DTF_SectionToDet a _ _ l _) = dict `add_elem` (l,a)
96 ndict (DTF_InstrToParse a _ _ l _) = dict `add_elem` (l,a)
97 ndict (DTF_Data a _ _ l _) = dict `add_elem` (l,a)
98 ndict (DTF_Instr a _ _ l _) = dict `add_elem` (l,a)
99 ndict (DTF_Define l v _) = dict `add_elem` (l,v)
100 ndict (DTF_Fill _ _ _ l _)
101 | state == InText = dict `add_elem` (l,instrcnt)
102 | state == InData = dict `add_elem` (l,datacnt)
105 newdtf = case (parse (parseDTFLine dict) "" (str++"\n")) of
106 Left err -> error ("couldn't parse line " ++ (show lno) ++ ": " ++ (show err))
107 Right (DTF_SectionToDet _ v c l s) ->
109 NoState -> error "missing .data or .text"
110 InData -> (DTF_Data datacnt v c l s)
111 InText -> (DTF_Instr instrcnt v c l s)
112 Right (DTF_InstrToParse _ v c l s) ->
113 (DTF_InstrToParse instrcnt v c l s)
114 Right y@(DTF_Org _) ->
116 NoState -> error "missing .data or .text"
118 Right (DTF_Label l c _) ->
120 NoState -> error "missing .data or .text"
121 InData -> (DTF_Label l c datacnt)
122 InText -> (DTF_Label l c instrcnt)
123 Right z -> z -- DTF_Comment, DTF_State, DTF_Define, DTF_Fill
127 testDTF :: String -> IO ()
129 case (parse (parseDTFLine dict) "" (input++"\n")) of
130 Left err -> do { putStr "failz ;(\n"; print err}
131 Right x -> do { print x }
133 dict = [("lolz", 0x1337), ("rofl", 0xaaaa)]
135 parseDTFLine :: [DictElem] -> Parser DTF
136 parseDTFLine dict = foldl1 (<|>) (fmap (\x -> try (x dict)) lineFormats) <* char '\n'
138 lineFormats = [lf_define, lf_sdata, lf_stext, lf_org, lf_data, lf_comment, lf_toparse, lf_label]
141 parseIdent :: Parser String
144 idents <- many $ (letter <|> digit <|> char '_')
145 return $ (ident:idents)
147 parseLabel :: Parser String
153 parseComment :: Parser String
157 comment <- many $ noneOf "\n"
160 parseConst :: [DictElem] -> Parser Word32
161 parseConst d = expr d
165 l <- try (parseLabel) <|> string ""
167 fill <- string ".fill "
168 repeat <- try (do {size <- many1 $ noneOf "\n;,"; char ','; return $ size}) <|> return "1"
169 -- TODO: atm 32bit imm only
170 code <- many1 $ noneOf "\n;"
171 -- TODO: this is quite ugly here :/
172 let (Right val) = parse (parseConst d) "" code
173 let (Right r) = parse (parseConst d) "" repeat
174 comment <- try(parseComment) <|> parseMySpaces
175 return $ DTF_Fill r val (fill ++ (if repeat == "1" then "" else repeat) ++ code) l comment
178 comment <- parseComment
179 return $ DTF_Comment comment
183 comment <- try(parseComment) <|> parseMySpaces
184 return $ DTF_Label l comment 0
187 l <- try(parseLabel) <|> string ""
189 code <- many1 $ noneOf "\n;"
190 comment <- try(parseComment) <|> parseMySpaces
191 return $ DTF_InstrToParse 0 code code l comment
204 return $ DTF_State InData
210 return $ DTF_State InText
218 -- TODO: expressions with (expr) do not work ;(
220 comment <- try(parseComment) <|> parseMySpaces
221 return $ DTF_Define id ret comment