git.iko.soy/typeable/pandoc
on master help sign in
Lua: move getTag from StackInstances to Util
2e0bb77Albert Krewinkel
src/Text/Pandoc/Lua/StackInstances.hs+1−10
@@ -42,8 +42,7 @@ import Foreign.Lua (FromLuaStack (peek), Lua, LuaInteger, LuaNumber, StackIndex,
42 ToLuaStack (push), Type (..), throwLuaError, tryLua)
42 ToLuaStack (push), Type (..), throwLuaError, tryLua)
43import Text.Pandoc.Definition
43import Text.Pandoc.Definition
44import Text.Pandoc.Extensions (Extensions)
44import Text.Pandoc.Extensions (Extensions)
45−import Text.Pandoc.Lua.Util (adjustIndexBy, getTable, pushViaConstructor,
45+import Text.Pandoc.Lua.Util (getTable, getTag, pushViaConstructor, typeCheck)
46− typeCheck)
47import Text.Pandoc.Options (ReaderOptions (..), TrackChanges)
46import Text.Pandoc.Options (ReaderOptions (..), TrackChanges)
48import Text.Pandoc.Shared (Element (Blk, Sec), safeRead)
47import Text.Pandoc.Shared (Element (Blk, Sec), safeRead)
49
48
@@ -300,14 +299,6 @@ peekInline idx = defineHowTo "get Inline value" $ do
300 elementContent :: FromLuaStack a => Lua a
299 elementContent :: FromLuaStack a => Lua a
301 elementContent = getTable idx "c"
300 elementContent = getTable idx "c"
302
301
303−getTag :: StackIndex -> Lua String
304−getTag idx = do
305− top <- Lua.gettop
306− hasMT <- Lua.getmetatable idx
307− push "tag"
308− if hasMT then Lua.rawget (-2) else Lua.rawget (idx `adjustIndexBy` 1)
309− peek Lua.stackTop `finally` Lua.settop top
310−
311withAttr :: (Attr -> a -> b) -> (LuaAttr, a) -> b
302withAttr :: (Attr -> a -> b) -> (LuaAttr, a) -> b
312withAttr f (attributes, x) = f (fromLuaAttr attributes) x
303withAttr f (attributes, x) = f (fromLuaAttr attributes) x
313
304
src/Text/Pandoc/Lua/Util.hs+16−3
@@ -29,7 +29,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29Lua utility functions.
29Lua utility functions.
30-}
30-}
31module Text.Pandoc.Lua.Util
31module Text.Pandoc.Lua.Util
32− ( adjustIndexBy
32+ ( getTag
33 , getTable
33 , getTable
34 , addValue
34 , addValue
35 , addFunction
35 , addFunction
@@ -47,6 +47,7 @@ module Text.Pandoc.Lua.Util
47 ) where
47 ) where
48
48
49import Control.Monad (when)
49import Control.Monad (when)
50+import Control.Monad.Catch (finally)
50import Data.ByteString.Char8 (unpack)
51import Data.ByteString.Char8 (unpack)
51import Foreign.Lua (FromLuaStack (..), NumResults, Lua, NumArgs, StackIndex,
52import Foreign.Lua (FromLuaStack (..), NumResults, Lua, NumArgs, StackIndex,
52 ToLuaStack (..), ToHaskellFunction, getglobal')
53 ToLuaStack (..), ToHaskellFunction, getglobal')
@@ -163,11 +164,23 @@ loadScriptFromDataDir datadir scriptFile = do
163-- to @require@, the a new loader function was created which then become
164-- to @require@, the a new loader function was created which then become
164-- garbage. If that function is collected at an inopportune times, i.e. when the
165-- garbage. If that function is collected at an inopportune times, i.e. when the
165-- Lua API is called via a function that doesn't allow calling back into Haskell
166-- Lua API is called via a function that doesn't allow calling back into Haskell
166−-- (getraw, setraw, …). The function's finalizer, and the full program, hangs
167+-- (getraw, setraw, …), then the function's finalizer, and the full program,
167−-- when that happens.
168+-- will hang.
168dostring' :: String -> Lua Status
169dostring' :: String -> Lua Status
169dostring' script = do
170dostring' script = do
170 loadRes <- Lua.loadstring script
171 loadRes <- Lua.loadstring script
171 if loadRes == Lua.OK
172 if loadRes == Lua.OK
172 then Lua.pcall 0 1 Nothing <* Lua.gc Lua.GCCOLLECT 0
173 then Lua.pcall 0 1 Nothing <* Lua.gc Lua.GCCOLLECT 0
173 else return loadRes
174 else return loadRes
175+
176+-- | Get the tag of a value. This is an optimized and specialized version of
177+-- @Lua.getfield idx "tag"@. It only checks for the field on the table at index
178+-- @idx@ and on its metatable, also ignoring any @__index@ value on the
179+-- metatable.
180+getTag :: StackIndex -> Lua String
181+getTag idx = do
182+ top <- Lua.gettop
183+ hasMT <- Lua.getmetatable idx
184+ push "tag"
185+ if hasMT then Lua.rawget (-2) else Lua.rawget (idx `adjustIndexBy` 1)
186+ peek Lua.stackTop `finally` Lua.settop top