clua-0.2: PrintLua.hs
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"