packages feed

hslua-objectorientation 2.0.1 → 2.1.0

raw patch · 8 files changed

+296/−68 lines, 8 filesdep ~hslua-coredep ~hslua-marshallingdep ~textPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: hslua-core, hslua-marshalling, text

API changes (from Hackage documentation)

+ HsLua.ObjectOrientation: instance GHC.Classes.Eq HsLua.ObjectOrientation.AliasIndex
+ HsLua.ObjectOrientation: instance GHC.Classes.Ord HsLua.ObjectOrientation.AliasIndex
+ HsLua.ObjectOrientation: type Alias = [AliasIndex]
- HsLua.ObjectOrientation: UDTypeWithList :: Name -> [(Operation, fn)] -> Map Name (Property e a) -> Map Name fn -> Map Name Alias -> Maybe (ListSpec e a itemtype) -> (fn -> LuaE e ()) -> UDTypeWithList e fn a itemtype
+ HsLua.ObjectOrientation: UDTypeWithList :: Name -> [(Operation, fn)] -> Map Name (Property e a) -> Map Name fn -> Map AliasIndex Alias -> Maybe (ListSpec e a itemtype) -> (fn -> LuaE e ()) -> UDTypeWithList e fn a itemtype
- HsLua.ObjectOrientation: [udAliases] :: UDTypeWithList e fn a itemtype -> Map Name Alias
+ HsLua.ObjectOrientation: [udAliases] :: UDTypeWithList e fn a itemtype -> Map AliasIndex Alias
- HsLua.ObjectOrientation: alias :: Name -> Text -> [AliasIndex] -> Member e fn a
+ HsLua.ObjectOrientation: alias :: AliasIndex -> Text -> [AliasIndex] -> Member e fn a
- HsLua.ObjectOrientation: type ListSpec e a itemtype = (a -> [itemtype], Pusher e itemtype)
+ HsLua.ObjectOrientation: type ListSpec e a itemtype = ((Pusher e itemtype, a -> [itemtype]), (Peeker e itemtype, a -> [itemtype] -> a))

Files

CHANGELOG.md view
@@ -1,21 +1,49 @@ # Changelog -`hslua-objectorientation` uses [PVP Versioning][1].+`hslua-objectorientation` uses [PVP Versioning][]. -## hslua-objectorientation 2.0.1+## hslua-objectorientation-2.1.0 -Release 2021-11-04.+Released 29-01-2022. -  - Excludes absent properties from `pairs`: Properties that are+-   Allow integers as aliases: Aliases can now be of type+    `AliasIndex`, so integers can now be defined as aliases for+    other properties. The function `alias` now takes an+    `AliasIndex` instead of a `Name`; the change entails+    modifications to the types `UDTypeWithList`, `UDType`, and+    `Member`. Also, `AliasIndex` is made into an instance of the+    Eq and Ord type classes.++-   Reworked list representation of objects, allowing write access+    to list components.++    The `ListSpec` type has been updated and contains now a pair+    of pairs, where the inner pairs define how to push and+    retrieve lists, respectively. Users of the `deftypeGeneric'`+    function will have to update their code.++-   Fixed some integer type declarations in C code. Some variables+    had been given incorrect types, like `int` instead of+    `lua_Integer`. They are usually the same, but may differ in+    some setups.++-   Require hslua-core-2.1.0 and hslua-marshalling-2.1.0, or+    later.++## hslua-objectorientation-2.0.1++Released 2021-11-04.++-   Excludes absent properties from `pairs`: Properties that are     optional and not present in a sum-type value are no longer     included in the iterator output produced by `pairs` (i.e., the     `__pairs` metamethod). Previously, the names of absent     properties were pushed with a `nil` value. -## hslua-objectorientation 2.0.0+## hslua-objectorientation-2.0.0 -Release 2021-10-21.+Released 2021-10-21. -- Published without warning.+-   Published without warning. -[1]: https://pvp.haskell.org+  [PVP Versioning]: https://pvp.haskell.org
LICENSE view
@@ -1,7 +1,7 @@ Copyright © 1994-2020 Lua.org, PUC-Rio. Copyright © 2007-2012 Gracjan Polak Copyright © 2012-2015 Ömer Sinan Ağacan-Copyright © 2016-2021 Albert Krewinkel+Copyright © 2016-2022 Albert Krewinkel  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the
cbits/hslobj.c view
@@ -89,14 +89,16 @@   }   lua_pushvalue(L, 2);   if (lua_rawget(L, -2) != LUA_TTABLE) {-    return 0;             /* key is not an alias */+    lua_pop(L, 2);       /* key is not an alias */+    return 0;            /* try a different method */   }    /* key is an alias */   lua_pushvalue(L, 1);    /* start with the original object */   /* Iterate over properties; last object is on top of stack,    * list of properties is the second object. */-  for (int i = 1; i <= lua_rawlen(L, -2); i++) {+  lua_Integer len = (lua_Integer) lua_rawlen(L, -2);+  for (lua_Integer i = 1; i <= len; i++) {     lua_rawgeti(L, -2, i);     int objtype = lua_gettable(L, -2);  /* get property */     lua_remove(L, -2);    /* remove previous object */@@ -127,16 +129,25 @@ int hsluaO_get_numerical(lua_State *L) {   hsluaO_get_caching_table(L, 1);-  int requested = lua_tointeger(L, 2);+  lua_Integer requested = lua_tointeger(L, 2); -  lua_getfield(L, 1, "__lazylistindex");-  int last_index = lua_tointeger(L, -1);-  lua_pop(L, 1);                        /* pop last-index value */+  /* The __lazylistindex is set to `nil` or an integer if part of the+     list is still unevaluated. If it's `false`, then all list values are+     already in the cache. */+  if (lua_getfield(L, 1, "__lazylistindex") == LUA_TBOOLEAN) {+    lua_pop(L, 1);                      /* remove nil */+  } else {+    lua_Integer last_index = lua_tointeger(L, -1);+    lua_pop(L, 1);                      /* pop last-index value */ -  if (requested > last_index) {-    /* index not in cache, force lazy evaluation of list items */-    if (luaL_getmetafield(L, 1, "lazylisteval") == LUA_TFUNCTION &&-        lua_getfield(L, 3, "__lazylist") == LUA_TUSERDATA) {+    if (requested > last_index &&+        /* index not in cache, force lazy evaluation of list items */+        luaL_getmetafield(L, 1, "lazylisteval") == LUA_TFUNCTION) {+      if (lua_getfield(L, 3, "__lazylist") != LUA_TUSERDATA) {+        /* lazy list thunk is missing; that shouldn't happen!!  */+        luaL_error(L, "Error while getting numerical index %d: "+                   "lazy list thunk is missing", requested);+      }       lua_pushinteger(L, last_index);       lua_pushinteger(L, requested);       lua_pushvalue(L, 3);              /* caching table */@@ -168,12 +179,12 @@   lua_settop(L, 2);   /* do numeric lookup for integer keys */   return lua_isinteger(L, 2)-    ? hsluaO_get_numerical(L)+    ? (hsluaO_get_via_alias(L) || hsluaO_get_numerical(L))     /* try various sources in order; return 0 if nothing is found. */-    : (hsluaO_get_from_cache(L)-       || hsluaO_get_via_getter(L)-       || hsluaO_get_via_alias(L)-       || hsluaO_get_method(L));+    : (hsluaO_get_from_cache(L) ||+       hsluaO_get_via_getter(L) ||+       hsluaO_get_via_alias(L)  ||+       hsluaO_get_method(L)); }  /*@@ -193,18 +204,55 @@   lua_pushvalue(L, 1);    /* start with the original object */   /* Iterate over properties; last object is on top of stack,    * list of properties is the second object. */-  for (int i = 1; i < lua_rawlen(L, -2); i++) {+  lua_Integer len = (lua_Integer) lua_rawlen(L, -2);+  for (int i = 1; i < len; i++) {     lua_rawgeti(L, -2, i);     lua_gettable(L, -2);  /* get property */     lua_remove(L, -2);    /* remove previous object */   }-  lua_rawgeti(L, -2, lua_rawlen(L, -2)); /* last element */-  lua_pushvalue(L, 3);    /* new value */+  lua_rawgeti(L, -2, len); /* last element */+  lua_pushvalue(L, 3);     /* new value */   lua_settable(L, -3);   return 1; }  /*+** Sets a numerical index on this object. The userdata must be in+** position 1, the key in position 2, and the new value in position 3.+** Returns 1 on success and 0 otherwise.+*/+int hsluaO_set_numerical(lua_State *L)+{+  hsluaO_get_caching_table(L, 1);+  lua_Integer target = lua_tointeger(L, 2);++  /* The `__lazylistindex` field is set to `false` if each list element+     has already been evaluated and stored in the cache. Otherwise it+     will be either `nil` or an integer. */+  if (lua_getfield(L, 1, "__lazylistindex") == LUA_TBOOLEAN) {+    lua_pop(L, 1);                      /* pop boolean from last-index */+  } else {+    /* list is not fully evaluated yet, we may have to evaluate it+       further. */+    lua_Integer last_index = lua_tointeger(L, -1);+    lua_pop(L, 1);                      /* pop last-index value */++    if (target > last_index) {+      /* the index we want to assign has not been cached yet. Evaluation+       * is forced to avoid any uncertainty about the meaning of+       * `nil`-valued indices. */+      lua_pushcfunction(L, &hsluaO_get_numerical);+      lua_pushvalue(L, 1);+      lua_pushvalue(L, 2);+      lua_call(L, 2, 0);+    }+  }+  lua_pushvalue(L, 3);                  /* new value */+  lua_rawseti(L, -2, target);           /* set in caching table */+  return 1;+}++/* ** Set value via a property alias. Assumes the stack to be in a state as ** after __newindex is called. Returns 1 on success, 0 if the object is ** readonly, and throws an error if there is no setter for the given@@ -239,6 +287,9 @@ int hslua_udnewindex(lua_State *L) {   if (lua_type(L, 2) == LUA_TNUMBER) {+    if (hsluaO_set_via_alias(L) || hsluaO_set_numerical(L)) {+      return 0;+    }     lua_pushliteral(L, "Cannot set a numerical value.");     return lua_error(L);   }
hslua-objectorientation.cabal view
@@ -1,6 +1,6 @@ cabal-version:       2.2 name:                hslua-objectorientation-version:             2.0.1+version:             2.1.0 synopsis:            Object orientation tools for HsLua description:         Expose Haskell objects to Lua with an object oriented                      interface.@@ -10,7 +10,7 @@ license-file:        LICENSE author:              Albert Krewinkel maintainer:          albert+hslua@zeitkraut.de-copyright:           © 2021 Albert Krewinkel+copyright:           © 2021-2022 Albert Krewinkel category:            Foreign build-type:          Simple extra-source-files:  README.md@@ -20,8 +20,9 @@                    , GHC == 8.4.4                    , GHC == 8.6.5                    , GHC == 8.8.4-                   , GHC == 8.10.4+                   , GHC == 8.10.7                    , GHC == 9.0.1+                   , GHC == 9.2.1  source-repository head   type:                git@@ -34,10 +35,10 @@                      , bytestring        >= 0.10.2 && < 0.12                      , containers        >= 0.5.9  && < 0.7                      , exceptions        >= 0.8    && < 0.11-                     , hslua-core        >= 2.0    && < 2.1-                     , hslua-marshalling >= 2.0.1  && < 2.1+                     , hslua-core        >= 2.1    && < 2.2+                     , hslua-marshalling >= 2.1    && < 2.2                      , mtl               >= 2.2    && < 2.3-                     , text              >= 1.0    && < 1.3+                     , text              >= 1.2    && < 2.1   ghc-options:         -Wall                        -Wincomplete-record-updates                        -Wnoncanonical-monad-instances@@ -59,6 +60,7 @@                      , HsLua.ObjectOrientation.Operation   hs-source-dirs:      src   default-extensions:  LambdaCase+                     , StrictData   other-extensions:    AllowAmbiguousTypes                      , CPP                      , FlexibleInstances
src/HsLua/ObjectOrientation.hs view
@@ -5,7 +5,7 @@ {-# LANGUAGE TypeApplications    #-} {-| Module      : HsLua.ObjectOrientation-Copyright   : © 2021 Albert Krewinkel+Copyright   : © 2021-2022 Albert Krewinkel License     : MIT Maintainer  : Albert Krewinkel <tarleb+hslua@zeitkraut.de> @@ -34,6 +34,7 @@   , Operation (..)   , ListSpec   , Possible (..)+  , Alias   , AliasIndex (..)   ) where @@ -58,18 +59,33 @@ -- Haskell values. The type name must be unique; once the type has been -- used to push or retrieve a value, the behavior can no longer be -- modified through this type.+--+-- This type includes methods to define how the object should behave as+-- a read-only list of type @itemtype@. data UDTypeWithList e fn a itemtype = UDTypeWithList   { udName          :: Name   , udOperations    :: [(Operation, fn)]   , udProperties    :: Map Name (Property e a)   , udMethods       :: Map Name fn-  , udAliases       :: Map Name Alias+  , udAliases       :: Map AliasIndex Alias   , udListSpec      :: Maybe (ListSpec e a itemtype)   , udFnPusher      :: fn -> LuaE e ()   } -type ListSpec e a itemtype = (a -> [itemtype], Pusher e itemtype)+-- | Pair of pairs, describing how a type can be used as a Lua list. The+-- first pair describes how to push the list items, and how the list is+-- extracted from the type; the second pair contains a method to+-- retrieve list items, and defines how the list is used to create an+-- updated value.+type ListSpec e a itemtype =+  ( (Pusher e itemtype, a -> [itemtype])+  , (Peeker e itemtype, a -> [itemtype] -> a)+  ) +-- | A userdata type, capturing the behavior of Lua objects that wrap+-- Haskell values. The type name must be unique; once the type has been+-- used to push or retrieve a value, the behavior can no longer be+-- modified through this type. type UDType e fn a = UDTypeWithList e fn a Void  -- | Defines a new type, defining the behavior of objects in Lua.@@ -125,6 +141,7 @@ data AliasIndex   = StringIndex Name   | IntegerIndex Lua.Integer+  deriving (Eq, Ord)  instance IsString AliasIndex where   fromString = StringIndex . fromString@@ -133,7 +150,7 @@ data Member e fn a   = MemberProperty Name (Property e a)   | MemberMethod Name fn-  | MemberAlias Name Alias+  | MemberAlias AliasIndex Alias  -- | Use a documented function as an object method. methodGeneric :: Name -> fn -> Member e fn a@@ -197,9 +214,9 @@   }  -- | Define an alias for another, possibly nested, property.-alias :: Name  -- ^ property alias-      -> Text  -- ^ description-      -> [AliasIndex] -- ^ sequence of nested properties+alias :: AliasIndex    -- ^ property alias+      -> Text          -- ^ description+      -> [AliasIndex]  -- ^ sequence of nested properties       -> Member e fn a alias name _desc = MemberAlias name @@ -221,7 +238,7 @@     add "aliases" $ pushAliases ty     case udListSpec ty of       Nothing -> pure ()-      Just (_, pushItem) -> do+      Just ((pushItem, _), _) -> do         add "lazylisteval" $ pushHaskellFunction (lazylisteval pushItem)   where     add :: LuaError e => Name -> LuaE e () -> LuaE e ()@@ -294,7 +311,7 @@ pushAliases ty = do   newtable   void $ flip Map.traverseWithKey (udAliases ty) $ \name propSeq -> do-    pushName name+    pushAliasIndex name     pushList pushAliasIndex propSeq     rawset (nth 3) @@ -330,7 +347,7 @@ -- -- 1. userdata wrapping the unevalled part of the lazy list -- 2. index of the last evaluated element--- 3. index of the last requested element+-- 3. index of the requested element -- 4. the caching table lazylisteval :: forall itemtype e. LuaError e              => Pusher e itemtype -> LuaE e NumResults@@ -342,16 +359,22 @@     (Just unevaled, Just curindex, Just newindex) -> do       let numElems = fromIntegral $ max (newindex - curindex) 0           (as, rest) = splitAt numElems unevaled-      -- put back remaining unevalled list-      _ <- putuserdata @[itemtype] (nthBottom 1) lazyListStateName rest+      if null rest+        then do+          -- no more elements in list; unset variable+          pushName "__lazylistindex"+          pushBool False+          rawset (nthBottom 4)+        else do+          -- put back remaining unevalled list+          void $ putuserdata @[itemtype] (nthBottom 1) lazyListStateName rest+          pushName "__lazylistindex"+          pushinteger (curindex + fromIntegral (length as))+          rawset (nthBottom 4)       -- push evaluated elements-      settop 4  -- ensure caching table is at the top of the stack       forM_ (zip [(curindex + 1)..] as) $ \(i, a) -> do         pushItem a         rawseti (nthBottom 4) i-      pushName "__lazylistindex"-      pushinteger (curindex + fromIntegral (length as))-      rawset (nthBottom 4)       return (NumResults 0)     _ -> pure (NumResults 0) @@ -368,7 +391,7 @@   -- add list as value in caching table   case udListSpec ty of     Nothing -> pure ()-    Just (toList, _) -> do+    Just ((_, toList), _) -> do       newtable       pushName "__lazylist"       newhsuserdata (toList x)@@ -382,16 +405,17 @@ peekUD ty idx = do   let name = udName ty   x <- reportValueOnFailure name (`fromuserdata` name) idx-  liftLua $ do-    result <- getuservalue idx >>= \case-      TypeTable -> do+  (`lastly` pop 1) $ liftLua (getuservalue idx) >>= \case+    TypeTable -> do+      -- set list+      xWithList <- maybe pure setList (udListSpec ty) x+      liftLua $ do         pushnil-        setProperties (udProperties ty) x-      _ -> do-        return x-    pop 1          -- uservalue (caching) table-    return result+        setProperties (udProperties ty) xWithList+    _ -> return x +-- | Retrieves object properties from a uservalue table and sets them on+-- the given value. Expects the uservalue table at the top of the stack. setProperties :: LuaError e => Map Name (Property e a) -> a -> LuaE e a setProperties props x = do   hasNext <- Unsafe.next (nth 2)@@ -407,3 +431,37 @@             pop 1             setProperties props x'       _ -> x <$ pop 1++-- | Gets a list from a uservalue table and sets it on the given value.+-- Expects the uservalue (i.e., caching) table to be at the top of the+-- stack.+setList :: forall itemtype e a. LuaError e+        => ListSpec e a itemtype -> a+        -> Peek e a+setList (_pushspec, (peekItem, updateList)) x = (x `updateList`) <$!> do+  liftLua (getfield top "__lazylistindex") >>= \case+    TypeBoolean -> do+      -- list had been fully evaluated+      liftLua $ pop 1+      peekList peekItem top+    _ -> do+      let getLazyList = do+            liftLua (getfield top "__lazylist") >>= \case+              TypeUserdata -> pure ()+              _ -> failPeek "unevaled items of lazy list cannot be peeked"+            (`lastly` pop 1) $ reportValueOnFailure+              lazyListStateName+              (\idx -> fromuserdata @[itemtype] idx lazyListStateName)+              top+      mlastIndex <- liftLua (tointeger top <* pop 1)+      let itemsAfter = case mlastIndex of+            Nothing -> const getLazyList+            Just lastIndex -> \i ->+              if i <= lastIndex+              then liftLua (rawgeti top i) >>= \case+                TypeNil -> [] <$ liftLua (pop 1)+                _ -> do+                  y <- peekItem top `lastly` pop 1+                  (y:) <$!> itemsAfter (i + 1)+              else getLazyList+      itemsAfter 1
src/HsLua/ObjectOrientation/Operation.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE OverloadedStrings #-} {-| Module      : HsLua.ObjectOrientation.Operation-Copyright   : © 2020-2021 Albert Krewinkel+Copyright   : © 2020-2022 Albert Krewinkel License     : MIT Maintainer  : Albert Krewinkel <tarleb+hslua@zeitkraut.de> 
test/HsLua/ObjectOrientationTests.hs view
@@ -5,7 +5,7 @@ Module      : HsLua.ObjectOrientationTests Copyright   : © 2007–2012 Gracjan Polak;               © 2012–2016 Ömer Sinan Ağacan;-              © 2017-2021 Albert Krewinkel+              © 2017-2022 Albert Krewinkel License     : MIT Maintainer  : Albert Krewinkel <tarleb+hslua@zeitkraut.de> Stability   : beta@@ -193,14 +193,71 @@         _ <- dostring "return list[0], list[5]"         (,) <$> ltype (nth 1) <*> ltype (nth 2) -    , "List is read-only" =:-      (ErrRun, "Cannot set a numerical value.") `shouldBeResultOf` do+    , "Last evaled index is available in __lazylistindex" =:+      3 `shouldBeResultOf` do         openlibs+        pushUD typeLazyIntList $ LazyIntList [9..17]+        setglobal "quuz"+        _ <- dostring "local foo = quuz[3]; return quuz.__lazylistindex"+        forcePeek $ peekIntegral @Int top++    , "__lazylistindex becomes `false` when all items are evaled" =:+      False `shouldBeResultOf` do+        openlibs+        pushUD typeLazyIntList $ LazyIntList [1..3]+        setglobal "quuz"+        _ <- dostring "local foo = quuz[3]; return quuz.__lazylistindex"+        forcePeek $ peekBool top++    , "Input can be retrieved unchanged" =:+      LazyIntList [9..17] `shouldBeResultOf` do+        openlibs+        pushUD typeLazyIntList $ LazyIntList [9..17]+        setglobal "ninetofive"+        _ <- dostring "assert(ninetofive[3] == 11); return ninetofive"+        forcePeek $ peekUD typeLazyIntList top++    , "List is writable" =:+      LazyIntList [1, 4, 9, 16] `shouldBeResultOf` do+        openlibs+        pushUD typeLazyIntList $ LazyIntList [0,4,9,16]+        setglobal "list"+        OK <- dostring "list[1] = 1; return list"+        forcePeek $ peekUD typeLazyIntList top++    , "List can be extended" =:+      LazyIntList [1, 4, 9, 16, 25] `shouldBeResultOf` do+        openlibs         pushUD typeLazyIntList $ LazyIntList [1,4,9,16]         setglobal "list"-        statusCode <- dostring "list[1] = 2"-        err <- forcePeek $ peekString top-        pure (statusCode, err)+        OK <- dostring "list[5] = 25; return list"+        forcePeek $ peekUD typeLazyIntList top++    , "List can be shortened" =:+      LazyIntList [1, 9, 27, 81] `shouldBeResultOf` do+        openlibs+        pushUD typeLazyIntList $ LazyIntList [1, 9, 27, 81, 243]+        setglobal "list"+        OK <- dostring "list[5] = nil; return list"+        forcePeek $ peekUD typeLazyIntList top++    , "Setting element to nil shortenes the list" =:+      LazyIntList [1, 9, 27] `shouldBeResultOf` do+        openlibs+        pushUD typeLazyIntList $ LazyIntList [1, 9, 27, 81, 243]+        setglobal "list"+        OK <- dostring "list[4] = nil; return list"+        forcePeek $ peekUD typeLazyIntList top++    , "Infinite lists are ok" =:+      233 `shouldBeResultOf` do+        openlibs+        let fibs = 0 : 1 : zipWith (+) fibs (tail fibs)+        pushUD typeLazyIntList $ LazyIntList fibs+        setglobal "fibs"+        dostring "return fibs[14]" >>= \case+          OK -> forcePeek $ peekIntegral @Int top+          _ -> failLua =<< forcePeek (peekString top)     ]    , testGroup "possible properties"@@ -253,6 +310,27 @@           -- msg <- forcePeek $ peekString top           -- liftIO $ putStrLn msg           forcePeek $ peekPoint top+      , "read subelement via integer alias" =:+        13.37 `shouldBeResultOf` do+          openlibs+          pushUD typeQux $ Quuz (Point 13.37 0) undefined+          setglobal "quuz"+          _ <- dostring "return quuz[1]"+          forcePeek $ peekRealFloat @Double top+      , "set subelement via integer alias" =:+        Point 42 1 `shouldBeResultOf` do+          openlibs+          pushUD typeQux $ Quuz (Point 1 1) undefined+          setglobal "quuz"+          _ <- dostring "quuz[1] = 42; return quuz.point"+          forcePeek $ peekPoint top+      , "non-aliased integer fields are nil" =:+        TypeNil `shouldBeResultOf` do+          openlibs+          pushUD typeQux (Quuz undefined undefined)+          setglobal "quuz"+          _ <- dostring "return quuz[3]"+          ltype top       , "absent alias returns `nil`" =:         TypeNil `shouldBeResultOf` do           openlibs@@ -261,6 +339,14 @@           dostring "return quux.x" >>= \case             OK -> ltype top             _ -> failLua =<< forcePeek (peekString top)+      , "alias can point to the element itself" =:+        9 `shouldBeResultOf` do+          openlibs+          pushUD typeLazyIntList (LazyIntList [1, 1, 1, 3, 5, 9, 17, 31])+          setglobal "tribonacci"+          dostring "return tribonacci.seq[6]" >>= \case+            OK -> forcePeek $ peekIntegral @Int top+            _ -> failLua =<< forcePeek (peekString top)       ]     ]   ]@@ -327,8 +413,10 @@       pushString (show lazyList)       return (NumResults 1)   ]-  []-  (Just (fromLazyIntList, pushIntegral))+  [ alias "seq" "sequence" [] ]+  (Just ( (pushIntegral, fromLazyIntList)+        , (peekIntegral, \_ lst -> LazyIntList lst)+        ))  -- -- Sample sum type@@ -391,4 +479,5 @@         Quux {}  -> const Absent)    , alias "x" "The x coordinate of a point in Quuz" ["point", "x"]+  , alias (IntegerIndex 1) "The x coordinate of a point in Quuz" ["point", "x"]   ]
test/test-hslua-objectorientation.hs view
@@ -2,7 +2,7 @@ Module      : Main Copyright   : © 2007–2012 Gracjan Polak;               © 2012–2016 Ömer Sinan Ağacan;-              © 2017-2021 Albert Krewinkel+              © 2017-2022 Albert Krewinkel License     : MIT Maintainer  : Albert Krewinkel <tarleb+hslua@zeitkraut.de> Stability   : beta