packages feed

hslua-repl (empty) → 0.1.0

raw patch · 6 files changed

+280/−0 lines, 6 filesdep +basedep +bytestringdep +hslua-core

Dependencies added: base, bytestring, hslua-core, hslua-repl, isocline, lua, text

Files

+ CHANGELOG.md view
@@ -0,0 +1,12 @@+# Changelog++`hslua-repl` uses [PVP Versioning](https://pvp.haskell.org).++## hslua-repl-0.1.0++Release pending.++-   A new package begins its way into the undiscovered land. May+    it live long and prosper.++  [PVP Versioning]: https://pvp.haskell.org
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright © 2023 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,19 @@+hslua-repl+==========++An embeddable, isocline-based Lua REPL.++Example+-------++``` haskell+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeApplications  #-}+import HsLua.Core  as Lua (Exception, openlibs, run)+import HsLua.REPL (defaultREPLConfig, startREPL)++-- | Run a default Lua interpreter.+main :: IO ()+main = run @Lua.Exception $ do+  startREPL defaultREPLConfig+```
+ app/luarepl.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeApplications  #-}+{- |+Module      : Main+Copyright   : © 2022-2023 Albert Krewinkel+License     : MIT+Maintainer  : Albert Krewinkel <tarleb@hslua.org>++A simple Lua REPL.+-}+module Main (main) where+import Control.Monad (void)+import HsLua.Core  as Lua (Exception, openlibs, run)+import HsLua.REPL (Config (..), defaultConfig, repl, setup)+import qualified Data.Text as T++-- | Run a default Lua interpreter.+main :: IO ()+main = run @Lua.Exception $ do+  let config = Config+        { replPrompt = "luarepl"+        , replInfo = replInfo defaultConfig `T.append`+                     "\nREPL: © 2023 Albert Krewinkel"+        , replHistory = Just ".luarepl-history"+        }+  openlibs+  setup config+  void repl
+ hslua-repl.cabal view
@@ -0,0 +1,78 @@+cabal-version:       2.2+name:                hslua-repl+version:             0.1.0+synopsis:            Isocline-based Lua REPL+description:         An embeddable Lua REPL built with Isocline and HsLua.+homepage:            https://hslua.org/+bug-reports:         https://github.com/hslua/hslua/issues+license:             MIT+license-file:        LICENSE+author:              Albert Krewinkel+maintainer:          Albert Krewinkel <tarleb@hslua.org>+copyright:           © lbert Krewinkel+category:            Foreign+build-type:          Simple+extra-doc-files:     README.md+                     CHANGELOG.md+tested-with:         GHC == 8.4.4+                   , GHC == 8.6.5+                   , GHC == 8.8.4+                   , GHC == 8.10.7+                   , GHC == 9.0.2+                   , GHC == 9.2.5+                   , GHC == 9.4.4++source-repository head+  type:                git+  location:            https://github.com/hslua/hslua+  subdir:              hslua-repl++Flag executable+  description:         Compile `luarepl` standalone executable.+  default:             False++common common-options+  build-depends:       base              >= 4.9.1  && < 5+                     , hslua-core        >= 2.3    && < 2.4+                     , text              >= 1.2    && < 2.1++  ghc-options:         -Wall+                       -Wcpp-undef+                       -Widentities+                       -Wincomplete-record-updates+                       -Wincomplete-uni-patterns+                       -Wmissing-export-lists+                       -Wmissing-signatures+                       -Wnoncanonical-monad-instances+                       -Wpartial-fields+                       -Wredundant-constraints+                       -fhide-source-paths++  if impl(ghc >= 8.10)+    ghc-options:       -Wunused-packages++  if impl(ghc >= 9.0)+    ghc-options:       -Winvalid-haddock+++  default-language:    Haskell2010++library+  import:              common-options+  hs-source-dirs:      src+  exposed-modules:     HsLua.REPL+  build-depends:       base              >= 4.11   && < 5+                     , bytestring        >= 0.10   && < 0.12+                     , isocline          >= 1.0    && < 1.1+                     , lua               >= 2.3    && < 2.4++executable luarepl+  import:              common-options+  hs-source-dirs:      app+  main-is:             luarepl.hs+  ghc-options:         -rtsopts -with-rtsopts=-A8m -threaded+  if flag(executable)+    buildable:           True+    build-depends:       hslua-repl+  else+   buildable:            False
+ src/HsLua/REPL.hs view
@@ -0,0 +1,123 @@+{-# LANGUAGE CPP               #-}+{-# LANGUAGE LambdaCase        #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE PatternSynonyms   #-}+{-# LANGUAGE ScopedTypeVariables #-}+{- |+Module      : HsLua.REPL+Copyright   : Copyright © 2017-2023 Albert Krewinkel+License     : MIT+Maintainer  : Albert Krewinkel <tarleb@hslua.org>++Embeddable Lua interpreter interface.+-}+module HsLua.REPL+  ( -- * Run scripts as program+    repl+  , setup+  , Config (..)+  , defaultConfig+  ) where++import Control.Applicative ((<|>))+import Control.Monad (void, when)+import Data.ByteString (ByteString)+import Data.Text (Text)+import Lua (pattern LUA_COPYRIGHT)+import HsLua.Core+import System.Console.Isocline+import qualified Data.ByteString.Char8 as Char8+import qualified Data.Text as T+import qualified Data.Text.IO as T+import qualified HsLua.Core.Utf8 as UTF8++-- | Lua runner command line options.+data Config = Config+  { replPrompt     :: Text+  , replInfo       :: Text+  , replHistory    :: Maybe FilePath+  }++defaultConfig :: Config+defaultConfig = Config+  { replPrompt = ""+  , replInfo = T.pack LUA_COPYRIGHT+  , replHistory = Nothing+  }++-- | Setup a new repl. Prints the version and extra info before the+-- first prompt.+setup :: Config -> LuaE e ()+setup config = do+  liftIO $ T.putStrLn (replInfo config)+  case replHistory config of+    Just histfile -> liftIO $ setHistory histfile 200+    Nothing -> pure ()++-- | Checks if the error message hints at incomplete input. Removes the+-- message from the stack in that case.+incomplete :: LuaError e => LuaE e Bool+incomplete = do+  let eofmark = "<eof>"+  msg <- tostring' top+  if eofmark `Char8.isSuffixOf` msg+    then True  <$ pop 2  -- error message (duplicated by tostring')+    else False <$ pop 1  -- value pushed by tostring'++-- | Load an input string, mark it as coming from @stdin@.+loadinput :: ByteString -> LuaE e Status+loadinput inp = loadbuffer inp "=stdin"++-- | Try to load input while prepending a @return@ statement.+loadExpression :: LuaError e => ByteString -> LuaE e ()+loadExpression input = loadinput ("return " <> input) >>= \case+  OK -> pure ()  -- yep, that worked+  _err   -> throwErrorAsException++-- | Load a multiline statement; prompts for more lines if the statement+-- looks incomplete.+loadStatement :: LuaError e+              => [ByteString]      -- ^ input lines+              -> LuaE e ()+loadStatement lns = do+  loadinput (Char8.unlines $ reverse lns) >>= \case+    OK -> pure ()+    ErrSyntax -> incomplete >>= \isincmplt ->+      if isincmplt+      then liftIO (readlineMaybe ">") >>= \case+        Nothing    -> failLua "Multiline input aborted"+        Just input -> loadStatement (UTF8.fromString input : lns)+      else throwErrorAsException+    _ -> throwErrorAsException++-- | Run a Lua repl.+repl :: LuaError e => LuaE e NumResults+repl = try repl' >>= \case+  Right n  -> pure n -- Ctrl-D or Ctrl-C+  Left err -> do+    -- something went wrong: report error, reset stack and try again+    void $ getglobal "print"+    pushException err+    call 1 0+    settop 0+    repl+ where+  repl' :: LuaError e => LuaE e NumResults+  repl' = liftIO (readlineMaybe "") >>= \case+    Nothing ->+      -- Return all values left on the stack as results+      NumResults . fromStackIndex <$> gettop+    Just inputStr -> do+      settop 0  -- reset stack+      let input = UTF8.fromString inputStr+      loadExpression input <|> loadStatement [input]+      -- run loaded input+      callTrace 0 multret+      nvalues <- gettop+      -- duplicate everything and call print on the results+      checkstack' (fromIntegral (fromStackIndex nvalues) + 1) "repl'"+      when (nvalues > 0) $ do+        void $ getglobal "print"+        mapM_ pushvalue [1..nvalues]+        call (fromIntegral $ fromStackIndex nvalues) 0+      repl'