1 -- as for deep thoughts ISA
2 -----------------------------------------------------------------------------
9 import Control.Applicative hiding ((<|>),many)
12 import System.Environment
15 import Text.Parsec.String
16 import Text.Parsec.Combinator
17 import qualified Data.Map as M
20 import qualified Data.ByteString.Lazy as BL
27 content <- getContents
28 let src = (filter (((/=) "") . snd) $ (zip [1..] (lines content)))
29 let (dict,formatedsrc) = convertDTF src NoState 0x00 0x00 []
31 sequence_ [printf "%10s @ 0x%08x\n" l a | (l,a) <- (reverse dict)]
32 printf "\nparsed asm:\n"
33 sequence_ [printf "%s" (show x) | x <- formatedsrc]
38 inc :: Counter -> Counter
42 type DictLabel = (String,Word32)
44 get_label :: String -> [DictLabel] -> Maybe Word32
47 add_label :: [DictLabel] -> (String,Word32) -> [DictLabel]
49 | s == "" = dic -- ignore empty string
50 | already_in = error ("Label " ++ s ++ " already exists")
51 | otherwise = (s,w):dic
53 already_in = case (get_label s dic) of
58 convertDTF :: [(Int,String)] -> DT_State -> Counter -> Counter -> [DictLabel] -> ([DictLabel], [DTF])
59 convertDTF [] _ _ _ d = (d,[])
60 convertDTF ((lno,str):xs) state datacnt instrcnt dict = (newdict, (actlist newdtf))
62 actlist (DTF_Org _) = next
63 actlist (DTF_State _) = next
66 (newdict,next) = convertDTF xs (nstate newdtf) (ndatacnt newdtf) (ninstrcnt newdtf) (ndict newdtf)
68 ndatacnt (DTF_Org adr)
69 | state == InData = adr
71 ndatacnt (DTF_Data _ _ _ _ _) = inc datacnt
74 ninstrcnt (DTF_Org adr)
75 | state == InText = adr
76 | otherwise = instrcnt
77 ninstrcnt (DTF_Instr _ _ _ _ _) = inc instrcnt
78 ninstrcnt (DTF_InstrToParse _ _ _ _ _) = inc instrcnt
79 ninstrcnt _ = instrcnt
81 nstate (DTF_State s) = s
84 ndict (DTF_Label l _ a) = dict `add_label` (l,a)
85 ndict (DTF_SectionToDet a _ _ l _) = dict `add_label` (l,a)
86 ndict (DTF_InstrToParse a _ _ l _) = dict `add_label` (l,a)
87 ndict (DTF_Data a _ _ l _) = dict `add_label` (l,a)
88 ndict (DTF_Instr a _ _ l _) = dict `add_label` (l,a)
91 newdtf = case (parse parseDTFLine "" (str++"\n")) of
92 Left err -> error ("couldn't parse line " ++ (show lno) ++ ": " ++ (show err))
93 Right (DTF_SectionToDet _ v c l s) ->
95 NoState -> error "missing .data or .text"
96 InData -> (DTF_Data datacnt v c l s)
97 InText -> (DTF_Instr instrcnt v c l s)
98 Right (DTF_InstrToParse _ v c l s) ->
99 (DTF_InstrToParse instrcnt v c l s)
100 Right y@(DTF_Org _) ->
102 NoState -> error "missing .data or .text"
104 Right (DTF_Label l c _) ->
106 NoState -> error "missing .data or .text"
107 InData -> (DTF_Label l c datacnt)
108 InText -> (DTF_Label l c instrcnt)
109 Right z -> z -- DTF_Comment, DTF_State
113 testDTF :: String -> IO ()
115 case (parse parseDTFLine "" (input++"\n")) of
116 Left err -> do { putStr "failz ;(\n"; print err}
117 Right x -> do { print x }
119 parseDTFLine :: Parser DTF
120 parseDTFLine = foldl1 (<|>) (fmap try lineFormats) <* char '\n'
122 lineFormats = [lf_sdata, lf_stext, lf_org, lf_data, lf_comment, lf_toparse, lf_label]
125 parseLabel :: Parser String
128 labels <- many $ (letter <|> digit <|> char '_')
130 return $ (label:labels)
132 parseComment :: Parser String
136 comment <- many $ noneOf "\n"
139 parseConst :: Parser Word32
142 -- TODO: only decimal and hex (since this is supported by read)
143 -- TODO: howto check too big values? atm they get truncated
144 str <- try(do pref <- string "0x"; z <- many1 hexDigit; return $ (pref ++ z)) <|> (many1 digit)
148 parseMySpaces :: Parser String
150 ret <- many $ oneOf "\t "
155 l <- try (parseLabel) <|> string ""
157 fill <- string ".fill "
158 -- TODO: atm 32bit imm only
159 code <- many1 $ noneOf "\n;"
160 -- TODO: this is quite ugly here :/
161 let (Right val) = parse parseConst "" code
162 comment <- try(parseComment) <|> parseMySpaces
163 return $ DTF_SectionToDet 0 val (fill ++ code) l comment
166 comment <- parseComment
167 return $ DTF_Comment comment
171 comment <- try(parseComment) <|> parseMySpaces
172 return $ DTF_Label l comment 0
175 l <- try(parseLabel) <|> string ""
177 code <- many1 $ noneOf "\n;"
178 comment <- try(parseComment) <|> parseMySpaces
179 return $ DTF_InstrToParse 0 code code l comment
192 return $ DTF_State InData
198 return $ DTF_State InText