packages feed

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"