packages feed

hslua-examples (empty) → 2.0.0

raw patch · 10 files changed

+346/−0 lines, 10 filesdep +basedep +bytestringdep +hslua

Dependencies added: base, bytestring, hslua, hslua-marshalling, lua, text

Files

+ CHANGELOG.md view
@@ -0,0 +1,7 @@+## Changelog++### 2.0.0++Release pending.++Complete rewrite.
+ LICENSE view
@@ -0,0 +1,23 @@+Copyright © 1994-2020 Lua.org, PUC-Rio.+Copyright © 2007-2012 Gracjan Polak+Copyright © 2012-2015 Ömer Sinan Ağacan+Copyright © 2016-2021 Albert Krewinkel++Permission is hereby granted, free of charge, to any person obtaining a+copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ README.md view
@@ -0,0 +1,41 @@+HsLua examples+==============++[![Build status][GitHub Actions badge]][GitHub Actions]+[![AppVeyor Status]](https://ci.appveyor.com/project/tarleb/hslua-r2y18)+[![Hackage]](https://hackage.haskell.org/package/hslua-examples)++Example programs showcasing the [HsLua] framework.++[GitHub Actions badge]: https://img.shields.io/github/workflow/status/hslua/hslua/CI.svg?logo=github+[GitHub Actions]: https://github.com/hslua/hslua/actions+[AppVeyor Status]: https://ci.appveyor.com/api/projects/status/ldutrilgxhpcau94/branch/main?svg=true+[Hackage]: https://img.shields.io/hackage/v/hslua-core.svg+[HsLua]: https://hslua.org/++run-lua+-----------++A simple program which uses Lua to calculate and print Fibonacci+numbers. It demonstrates how a Lua script can be embedded and+executed.++print-version+-------------++Demonstrates the use of the the low-level C API functions from the+`lua` package. Prints the Lua version.++wishlist+----------++The code for [Santa's Little Lua Scripts][SLLS].++low-level-factorial+-------------------++Calculate integer factorials in Haskell, allowing for results+which don't fit into a normal Lua integer. Uses only the low-level+C API functions from the `lua` package.++[SLLS]: https://hslua.org/santas-little-lua-scripts.html
+ factorial/factorial.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeApplications  #-}+{-| Compute factorials in Haskell -}+module Main where+import Control.Monad (void)+import HsLua+import Prelude++-- | Factorial function.+factorial :: DocumentedFunction e+factorial = defun "factorial"+  ### liftPure (\n -> product [1..n] :: Prelude.Integer)+  --                 get arg      type of arg      name  description+  <#> parameter      peekIntegral "integer"        "n"   "input number"+  =#> functionResult pushIntegral "integer|string"       "factorial of n"+  #? "Computes the factorial of an integer."++main :: IO ()+main = run @HsLua.Exception $ do+  openlibs+  pushDocumentedFunction factorial *> setglobal "factorial"+  -- run a script+  void . dostring $ mconcat+    [ "print(' 5! =', factorial(5), type(factorial(5)))\n"+    , "print('30! =', factorial(30), type(factorial(30)))\n"+    ]
+ hslua-examples.cabal view
@@ -0,0 +1,79 @@+cabal-version:       2.2+name:                hslua-examples+version:             2.0.0+synopsis:            Examples of how to combine Haskell and Lua.+description:         The HsLua modules provide wrappers of Lua language+                     interpreter as described on the official+                     <https://www.lua.org/ Lua website).+                     .+                     This package contains example programs, demonstrating+                     the possibility to work with Lua from within Haskell+                     and /vice versa/.+homepage:            https://hslua.org/+bug-reports:         https://github.com/hslua/hslua/issues+license:             MIT+license-File:        LICENSE+author:              Albert Krewinkel+copyright:           © 2020–2021 Albert Krewinkel+maintainer:          Albert Krewinkel <albert+hslua@zeitkraut.de>+category:            Foreign+build-type:          Simple+extra-source-files:  README.md+                     CHANGELOG.md+                     wishlist/filter.lua++source-repository head+  type:                git+  location:            https://github.com/hslua/hslua.git+  subdir:              hslua-examples++common common-options+  default-language:    Haskell2010+  build-depends:       base              >= 4.9 && < 5+  ghc-options:         -Wall+                       -Wincomplete-record-updates+                       -Wnoncanonical-monad-instances+                       -Wredundant-constraints+  if impl(ghc >= 8.2)+    ghc-options:         -Wcpp-undef+                         -Werror=missing-home-modules+  if impl(ghc >= 8.4)+    ghc-options:         -Widentities+                         -Wincomplete-uni-patterns+                         -Wpartial-fields+                         -fhide-source-paths++executable print-version+  import:              common-options+  main-is:             print-version.hs+  hs-source-dirs:      print-version+  build-depends:       lua               >= 2.0 && < 2.1++executable run-lua+  import:              common-options+  main-is:             run-lua.hs+  hs-source-dirs:      run-lua+  build-depends:       bytestring+                     , hslua             >= 2.0 && < 2.1++executable wishlist+  import:              common-options+  main-is:             wishlist.hs+  hs-source-dirs:      wishlist+  build-depends:       bytestring+                     , hslua             >= 2.0 && < 2.1+                     , hslua-marshalling >= 2.0 && < 2.1+                     , text++executable factorial+  import:              common-options+  main-is:             factorial.hs+  hs-source-dirs:      factorial+  build-depends:       bytestring+                     , hslua             >= 2.0 && < 2.1++executable low-level-factorial+  import:              common-options+  main-is:             low-level-factorial.hs+  hs-source-dirs:      low-level-factorial+  build-depends:       lua               >= 2.0 && < 2.1
+ low-level-factorial/low-level-factorial.hs view
@@ -0,0 +1,41 @@+-- lua_setglobal is unsafe in general and causes a compiler warning.+{-# OPTIONS_GHC -Wno-warnings-deprecations #-}+{-| Expose factorial function to Lua, using the low-level API. -}+module Main where+import Prelude+import Control.Monad (void)+import Foreign.C (withCString, withCStringLen)+import Foreign.Ptr (nullPtr)+import Lua++luaScript :: String+luaScript = unlines+  [ "print(' 5! =', factorial(5), type(factorial(5)))"+  , "print('30! =', factorial(30), type(factorial(30)))"+  ]++factorial :: PreCFunction+factorial l = do+  -- Get the first function argument as an integer.+  n <- lua_tointegerx l (nthBottom 1) nullPtr+  let result = product [1..fromIntegral n] :: Prelude.Integer+  -- push as integer if the result is small enough,+  -- and as string otherwise.+  if result <= fromIntegral (maxBound :: Lua.Integer)+    then lua_pushinteger l (fromIntegral result)+    else withCString (show result) (void . lua_pushstring l)+  -- Signal that one result value is on the top of the stack.+  return (NumResults 1)++main :: IO ()+main = void . withNewState $ \l -> do+  luaL_openlibs l+  -- expose Haskell function `factorial` as a Lua function of the same name.+  hslua_pushhsfunction l factorial+  _ <- withCString "factorial" (lua_setglobal l)+  -- Load the script.+  LUA_OK <- withCStringLen luaScript $ \(sPtr, sLen) ->+    withCString "script" $ luaL_loadbuffer l sPtr (fromIntegral sLen)+  -- Call the loaded script.+  LUA_OK <- lua_pcall l (NumArgs 0) LUA_MULTRET (StackIndex 0)+  return ()
+ print-version/print-version.hs view
@@ -0,0 +1,17 @@+-- @lua_getglobal@ is unsafe in general, but safe in this case.+{-# OPTIONS_GHC -Wno-warnings-deprecations #-}+{-| Use low-level API functions to output the Lua version. -}+module Main where+import Control.Monad (void)+import Foreign.C (withCString)+import Lua++main :: IO ()+main = void . withNewState $ \l -> do+  luaL_openlibs l+  -- Prepare call `print(_VERSION)`: first push the `print` function+  -- to the stack, then the arguments.+  LUA_TFUNCTION <- withCString "print" (lua_getglobal l)+  LUA_TSTRING <- withCString "_VERSION" (lua_getglobal l)+  -- Call the function with one argument.+  lua_pcall l (NumArgs 1) (NumResults 0) (StackIndex 0)
+ run-lua/run-lua.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE OverloadedStrings #-}+{-| Simple program running Lua code.+-}+module Main where+import HsLua.Core+import qualified Data.ByteString as B++main :: IO ()+main = do+  putStrLn "Calling Lua to output some Fibonacci numbers."+  luaStatus <- run $ do+    openlibs             -- load the default Lua packages+    dostring luaProgram  -- load and run the program+  putStrLn ("Lua finished with status '" ++ show luaStatus ++ "'.")+++-- | The Lua program. It uses a simple loop to calculate and print the+-- first 11 Fibonacci numbers.+--+-- Note that we are using the /OverloadedStrings/ extension. The+-- @IsString@ instance for ByteString behaves weirdly with non-ASCII+-- characters, but we don't use any here.+luaProgram :: B.ByteString+luaProgram = B.concat+  [ "local a, b = 0, 1\n"+  , "for i = 0, 10 do\n"+  , "  print(i, a)\n"+  , "  a, b = b, a + b\n"+  , "end\n"+  ]
+ wishlist/filter.lua view
@@ -0,0 +1,4 @@+return function (wish)+  return wish.child.nice and+    wish.toy == 'TrainSet'+end
+ wishlist/wishlist.hs view
@@ -0,0 +1,78 @@+{-# LANGUAGE OverloadedStrings #-}+{-| Santa's wishlist processor.++The program expexts the path to a filter file as its only argument.+See the blog-post for more details:+https://hslua.org/santas-little-lua-scripts.html+-}+module Main where+import Control.Monad (filterM)+import Data.Text (Text, pack)+import HsLua.Core ( Lua, NumResults (..), NumArgs (..)+                  , call, dofile, newtable, nth, pop, pushvalue, run+                  , setfield, top, toboolean)+import HsLua.Marshalling (pushBool, pushText)+import System.Environment (getArgs)++data Toy = Bricks | TrainSet | Doll deriving Show+data Behavior = Nice | Naughty deriving (Eq, Show)++data Wish = Wish+  { wishingChild :: Child+  , wishedToy :: Toy+  } deriving Show++data Child = Child+  { childName     :: Text+  , childBehavior :: Behavior+  } deriving Show++pushToy :: Toy -> Lua ()+pushToy = pushText . pack . show++pushChild :: Child -> Lua ()+pushChild (Child name behavior) = do+  -- create new Lua table on the stack+  newtable+  -- push boolean to stack+  pushText name+  -- table now in position 2; assign string to field in table+  setfield (nth 2) "name"++  -- push boolean to stack+  pushBool (behavior == Nice)+  setfield (nth 2) "nice"++pushWish :: Wish -> Lua ()+pushWish (Wish child toy) = do+  newtable+  pushChild child+  setfield (nth 2) "child"+  pushToy toy+  setfield (nth 2) "toy"++wishes :: [Wish]+wishes =+  [ Wish (Child "Theodor" Nice) Bricks+  , Wish (Child "Philine" Nice) TrainSet+  , Wish (Child "Steve" Naughty) Doll+  ]++hasPredicate :: Wish -> Lua Bool+hasPredicate wish = do+  -- Assume filter function is at the top of the stack;+  -- create a copy so we can re-use it.+  pushvalue top+  pushWish wish+  -- Call the function. There is one argument on the stack,+  -- and we expect one result to be returned.+  call (NumArgs 1) (NumResults 1)+  toboolean top <* pop 1++main :: IO ()+main = do+  filterFile <- fmap (!! 0) getArgs -- get first argument+  result <- run $ do+    _status <- dofile filterFile+    filterM hasPredicate wishes+  print result