module PrintLua(packedLua, LuaData(..)) where import CAnalyze import BStruct import Text.PrettyPrint.HughesPJ import Control.Monad -- (useful subset of) Lua data syntax. data LuaData = LuaStr String | LuaNum String | LuaTable [(LuaData, LuaData)] deriving (Eq) -- Prettyprinting with Text.PrettyPrint.HughesPJ instance Show LuaData where show = (++"\n") . show . docLua docLua (LuaNum s) = text s docLua (LuaStr s) = quotes $ text s docLua (LuaTable xs) = doc where doc = nest 2 $ braces $ cat $ punctuate comma $ list xs list xs = zipWith pair [1..] xs pair i (k,v) = docPair i k $ docLua v -- If i is in sequence, don't print index. docPair i (LuaNum n) sv | show i == n = sv docPair _ n@(LuaNum _) sv = cat [ brackets $ docLua n, sv ] docPair _ (LuaStr s) sv = cat [cat [text s, equals], sv] docPair _ (LuaTable t) sv = error $ "Table as key." -- Compile BStruct list to Lua -- List as table. luaList :: [LuaData] -> LuaData luaList es = LuaTable $ zipWith entry [1..] es where entry i e = (LuaNum $ show i, e) -- We only use string-indexed pairs. For index: use luaList. luaPair s e = (LuaStr s, e) -- Can't use keys because order is important, so we just use the first -- element of an array as the tag. luaTagList tag ls = luaList (LuaStr tag : ls) luaBStructs = LuaTable . (map pair) where pair (BStruct name mems) = luaPair name $ luaList $ map mem mems mem (t, n) = luaList [typ t, LuaStr n] typ (BInt s b) = luaTagList "int" [sign s, bits b] typ (BFloat b) = luaTagList "float" [bits b] typ (BComp r) = luaTagList "struct" [ref r] typ (BArr s t) = luaTagList "array" [size s, typ t] sign = LuaStr . show bits = LuaNum . show size = LuaNum . show ref = LuaStr . show luaBEnums (BEnum ls) = LuaTable $ map be ls where be (nam, val) = luaPair nam $ LuaNum $ show val -- Wrap around C analyser. packedLua = reportC process where process ast = do bs <- bStructs ast be <- bEnums ast let ls = luaBStructs bs es = luaBEnums be tab = LuaTable [(LuaStr "struct", ls), (LuaStr "enum", es)] in do return $ ("return\n" ++) $ show $ tab -- TEST -- x = packedLua "/tmp/test.c" -- x = packedLua "/home/tom/structs.E.c"