HsLua Table support

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
-- here is a quick lua table interface for HsLua

instance (Lua.StackValue k, Lua.StackValue v) => Lua.StackValue [(k,v)] where
  push l m = do
    Lua.newtable l
    forM_ m $ \(k,v) -> do
      Lua.push l k
      Lua.push l v
      Lua.settable l (-3)
  peek l n = maybepeek l n Lua.istable getTable
  valuetype _ = Lua.TTABLE


getTable :: (Lua.StackValue k, Lua.StackValue v) => Lua.LuaState -> Int -> IO [(k,v)]
getTable lua i = do
  Lua.pushnil lua
  getTable' (i - 1)
  where
    getTable' idx = do
      hasNext <- Lua.next lua idx
      if hasNext then do
        k <- Lua.peek lua (-2)
        v <- Lua.peek lua (-1)
        Lua.pop lua 1
        getTable' idx >>= \tl -> return $ (fromJust k, fromJust v):tl
        else return []
        
      
maybepeek :: l -> n -> (l -> n -> IO Bool) -> (l -> n -> IO r) -> IO (Maybe r)
maybepeek l n test peek = do
    v <- test l n
    if v
        then liftM Just (peek l n)
        else return Nothing

-- It uses [(k,v)] as a Haskell-side representation for Lua table. It is
-- not very satisfactory, since it can not handle heterogeneous table.
-- However, HsLua currently lacks a dynamic typing interface to Lua
-- values. This is the reason why the interface above relies on the
-- static interface (StackValue class). There are ideas to support
-- a dynamic interface in this blog post :

-- http://forfunand.wordpress.com/2011/11/16/haskell-and-lua/

-- We could maybe get in touch with the HsLua author and discuss what
-- are the plan for this package. At the moment, there is no public
-- home for it. Before I dig further, are there other people
-- interested by a tighter integration of lua into Haskell ?