Strict functions fix
This commit is contained in:
parent
43ad544de9
commit
d2ba02cdd9
6 changed files with 81 additions and 80 deletions
10
lish.cabal
10
lish.cabal
|
@ -26,7 +26,7 @@ source-repository head
|
||||||
library
|
library
|
||||||
hs-source-dirs:
|
hs-source-dirs:
|
||||||
src
|
src
|
||||||
ghc-options: -Wall -Werror -O2
|
ghc-options: -Wall -O2
|
||||||
build-depends:
|
build-depends:
|
||||||
base >= 4.8 && < 5
|
base >= 4.8 && < 5
|
||||||
, containers
|
, containers
|
||||||
|
@ -52,7 +52,7 @@ executable lish
|
||||||
main-is: Main.hs
|
main-is: Main.hs
|
||||||
hs-source-dirs:
|
hs-source-dirs:
|
||||||
src-exe
|
src-exe
|
||||||
ghc-options: -Wall -Werror -O2 -Wall -Werror -O2 -threaded -rtsopts -with-rtsopts=-N
|
ghc-options: -Wall -O2 -threaded -rtsopts -with-rtsopts=-N
|
||||||
build-depends:
|
build-depends:
|
||||||
base >= 4.8 && < 5
|
base >= 4.8 && < 5
|
||||||
, containers
|
, containers
|
||||||
|
@ -71,7 +71,7 @@ test-suite lish-benchmark
|
||||||
main-is: Main.hs
|
main-is: Main.hs
|
||||||
hs-source-dirs:
|
hs-source-dirs:
|
||||||
src-benchmark
|
src-benchmark
|
||||||
ghc-options: -Wall -Werror -O2 -Wall -Werror -O2 -threaded -rtsopts -with-rtsopts=-N
|
ghc-options: -Wall -O2 -threaded -rtsopts -with-rtsopts=-N
|
||||||
build-depends:
|
build-depends:
|
||||||
base >= 4.8 && < 5
|
base >= 4.8 && < 5
|
||||||
, containers
|
, containers
|
||||||
|
@ -92,7 +92,7 @@ test-suite lish-doctest
|
||||||
main-is: Main.hs
|
main-is: Main.hs
|
||||||
hs-source-dirs:
|
hs-source-dirs:
|
||||||
src-doctest
|
src-doctest
|
||||||
ghc-options: -Wall -Werror -O2 -Wall -Werror -O2 -threaded -rtsopts -with-rtsopts=-N
|
ghc-options: -Wall -O2 -threaded -rtsopts -with-rtsopts=-N
|
||||||
build-depends:
|
build-depends:
|
||||||
base >= 4.8 && < 5
|
base >= 4.8 && < 5
|
||||||
, containers
|
, containers
|
||||||
|
@ -115,7 +115,7 @@ test-suite lish-test
|
||||||
main-is: Main.hs
|
main-is: Main.hs
|
||||||
hs-source-dirs:
|
hs-source-dirs:
|
||||||
src-test
|
src-test
|
||||||
ghc-options: -Wall -Werror -O2 -Wall -Werror -O2 -threaded -rtsopts -with-rtsopts=-N
|
ghc-options: -Wall -O2 -threaded -rtsopts -with-rtsopts=-N
|
||||||
build-depends:
|
build-depends:
|
||||||
base >= 4.8 && < 5
|
base >= 4.8 && < 5
|
||||||
, containers
|
, containers
|
||||||
|
|
10
package.yaml
10
package.yaml
|
@ -10,7 +10,7 @@ extra-source-files:
|
||||||
- README.md
|
- README.md
|
||||||
- stack.yaml
|
- stack.yaml
|
||||||
|
|
||||||
ghc-options: -Wall -Werror -O2
|
ghc-options: -Wall -O2
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
- base >= 4.8 && < 5
|
- base >= 4.8 && < 5
|
||||||
|
@ -28,7 +28,7 @@ library:
|
||||||
|
|
||||||
executables:
|
executables:
|
||||||
lish:
|
lish:
|
||||||
ghc-options: -Wall -Werror -O2 -threaded -rtsopts -with-rtsopts=-N
|
ghc-options: -threaded -rtsopts -with-rtsopts=-N
|
||||||
main: Main.hs
|
main: Main.hs
|
||||||
source-dirs: src-exe
|
source-dirs: src-exe
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -38,7 +38,7 @@ tests:
|
||||||
lish-test:
|
lish-test:
|
||||||
source-dirs: src-test
|
source-dirs: src-test
|
||||||
main: Main.hs
|
main: Main.hs
|
||||||
ghc-options: -Wall -Werror -O2 -threaded -rtsopts -with-rtsopts=-N
|
ghc-options: -threaded -rtsopts -with-rtsopts=-N
|
||||||
dependencies:
|
dependencies:
|
||||||
- lish
|
- lish
|
||||||
- base >= 4.8 && < 5
|
- base >= 4.8 && < 5
|
||||||
|
@ -50,7 +50,7 @@ tests:
|
||||||
lish-doctest:
|
lish-doctest:
|
||||||
source-dirs: src-doctest
|
source-dirs: src-doctest
|
||||||
main: Main.hs
|
main: Main.hs
|
||||||
ghc-options: -Wall -Werror -O2 -threaded -rtsopts -with-rtsopts=-N
|
ghc-options: -threaded -rtsopts -with-rtsopts=-N
|
||||||
dependencies:
|
dependencies:
|
||||||
- lish
|
- lish
|
||||||
- base >= 4.8 && < 5
|
- base >= 4.8 && < 5
|
||||||
|
@ -60,7 +60,7 @@ tests:
|
||||||
lish-benchmark:
|
lish-benchmark:
|
||||||
source-dirs: src-benchmark
|
source-dirs: src-benchmark
|
||||||
main: Main.hs
|
main: Main.hs
|
||||||
ghc-options: -Wall -Werror -O2 -threaded -rtsopts -with-rtsopts=-N
|
ghc-options: -threaded -rtsopts -with-rtsopts=-N
|
||||||
dependencies:
|
dependencies:
|
||||||
- lish
|
- lish
|
||||||
- base >= 4.8 && < 5
|
- base >= 4.8 && < 5
|
||||||
|
|
|
@ -26,7 +26,7 @@ runLish :: IO ()
|
||||||
runLish = do
|
runLish = do
|
||||||
env <- toEnv <$> getEnvironment
|
env <- toEnv <$> getEnvironment
|
||||||
runInputT (defaultSettings { historyFile = Just ".lish-history" })
|
runInputT (defaultSettings { historyFile = Just ".lish-history" })
|
||||||
(mainLoop Nothing env "")
|
(mainLoop Nothing mempty "")
|
||||||
|
|
||||||
-- | System Environment -> LISH Env
|
-- | System Environment -> LISH Env
|
||||||
toEnv :: [(String,String)] -> Env
|
toEnv :: [(String,String)] -> Env
|
||||||
|
|
|
@ -65,45 +65,40 @@ isReduced _ = True
|
||||||
-- | The main evaluation function
|
-- | The main evaluation function
|
||||||
-- its real type should be something isomorphic to
|
-- its real type should be something isomorphic to
|
||||||
-- (SExp,Environment) -> IO (SExp, Environment)
|
-- (SExp,Environment) -> IO (SExp, Environment)
|
||||||
reduceLambda :: SExp -> StateT Env IO SExp
|
_reduceLambda :: SExp -> StateT Env IO SExp
|
||||||
reduceLambda (Lambda (Fix expr:fexprs)) = do
|
_reduceLambda (Lambda (Fix expr:fexprs)) = do
|
||||||
let exprs = map unFix fexprs
|
let exprs = map unFix fexprs
|
||||||
reduced <- reduceLambda expr
|
reduced <- reduceLambda expr
|
||||||
if isReduced reduced
|
if isReduced reduced
|
||||||
then do
|
then do
|
||||||
-- DEBUG --env <- get
|
|
||||||
-- DEBUG --liftIO $ do
|
|
||||||
-- DEBUG -- putText "Lambda:"
|
|
||||||
-- DEBUG -- print $ (expr:exprs)
|
|
||||||
-- DEBUG -- putText "Env:"
|
|
||||||
-- DEBUG -- print env
|
|
||||||
-- DEBUG -- putText "Reduced Head:"
|
|
||||||
-- DEBUG -- print reduced
|
|
||||||
case reduced of
|
case reduced of
|
||||||
Atom f -> do
|
Internal command -> (_commandFn command) reduceLambda exprs
|
||||||
resultInternal <- tryInternalCommand f exprs
|
|
||||||
case resultInternal of
|
|
||||||
Just x -> return x
|
|
||||||
Nothing -> do
|
|
||||||
resultEnv <- tryEnvCommand f exprs
|
|
||||||
case resultEnv of
|
|
||||||
Just x -> return x
|
|
||||||
Nothing -> do
|
|
||||||
reducedArgs <- mapM reduceLambda exprs
|
|
||||||
executeCommand (Command (Fix (Str f))
|
|
||||||
(map Fix reducedArgs))
|
|
||||||
f@(Fn _ _ _ _) -> applyFn f exprs
|
f@(Fn _ _ _ _) -> applyFn f exprs
|
||||||
s -> do
|
s -> do
|
||||||
reducedArgs <- mapM reduceLambda exprs
|
reducedArgs <- mapM reduceLambda exprs
|
||||||
executeCommand $ Command (Fix s) (map Fix reducedArgs)
|
executeCommand (Cmd (Fix s) (map Fix reducedArgs))
|
||||||
else reduceLambda (Lambda . map Fix $ (reduced:exprs))
|
else reduceLambda (Lambda . map Fix $ (reduced:exprs))
|
||||||
reduceLambda command@(Command _ _) = executeCommand command
|
_reduceLambda command@(Internal _) = executeCommand command
|
||||||
reduceLambda (Atom x) = do
|
_reduceLambda (Atom x) = do
|
||||||
env <- get
|
env <- get
|
||||||
case Map.lookup x env of
|
case Map.lookup x env of
|
||||||
Just s -> return s
|
Just s -> return s
|
||||||
_ -> return $ Str x
|
_ -> case InternalCommands.lookup x of
|
||||||
reduceLambda x = return x
|
Just cmd -> return (Internal cmd)
|
||||||
|
_ -> return (Str x)
|
||||||
|
_reduceLambda x = return x
|
||||||
|
|
||||||
|
reduceLambda :: SExp -> StateT Env IO SExp
|
||||||
|
reduceLambda x = do
|
||||||
|
-- DEBUG --env <- get
|
||||||
|
-- DEBUG --liftIO $ do
|
||||||
|
-- DEBUG -- putText "------"
|
||||||
|
-- DEBUG -- putStr ("Env: " :: Text)
|
||||||
|
-- DEBUG -- print env
|
||||||
|
-- DEBUG -- putStr ("Arg: " :: Text)
|
||||||
|
-- DEBUG -- putStrLn $ pprint (Fix x)
|
||||||
|
_reduceLambda x
|
||||||
|
|
||||||
|
|
||||||
applyFn :: SExp -> ReduceUnawareCommand
|
applyFn :: SExp -> ReduceUnawareCommand
|
||||||
applyFn (Fn par bod clos _) args =
|
applyFn (Fn par bod clos _) args =
|
||||||
|
@ -114,25 +109,11 @@ applyFn (Fn par bod clos _) args =
|
||||||
currentEnv <- get
|
currentEnv <- get
|
||||||
-- Run the function in its own closure
|
-- Run the function in its own closure
|
||||||
fmap fst $ liftIO $
|
fmap fst $ liftIO $
|
||||||
runStateT (reduceLambda (unFix bod)) (Map.union currentEnv localClosure)
|
runStateT (reduceLambda (unFix bod)) (Map.union localClosure currentEnv)
|
||||||
where
|
where
|
||||||
bindVars oldenv newvars = Map.union oldenv (Map.fromList newvars)
|
bindVars oldenv newvars = Map.union oldenv (Map.fromList newvars)
|
||||||
applyFn x _ = return x
|
applyFn x _ = return x
|
||||||
|
|
||||||
tryEnvCommand :: Text -> [SExp] -> StateT Env IO (Maybe SExp)
|
|
||||||
tryEnvCommand f args = do
|
|
||||||
envcmd <- get
|
|
||||||
case Map.lookup f envcmd of
|
|
||||||
Just fn@(Fn _ _ _ _) -> Just <$> (applyFn fn args)
|
|
||||||
_ -> return Nothing
|
|
||||||
|
|
||||||
|
|
||||||
tryInternalCommand :: Text -> [SExp] -> StateT Env IO (Maybe SExp)
|
|
||||||
tryInternalCommand f args =
|
|
||||||
case InternalCommands.lookup f of
|
|
||||||
Just (fn) -> Just <$> fn reduceLambda args
|
|
||||||
_ -> return Nothing
|
|
||||||
|
|
||||||
-- | take a SExp
|
-- | take a SExp
|
||||||
toStdIn :: SExp -> Maybe Handle
|
toStdIn :: SExp -> Maybe Handle
|
||||||
toStdIn (WaitingStream h) = h
|
toStdIn (WaitingStream h) = h
|
||||||
|
@ -145,7 +126,7 @@ shellErr errmsg = do
|
||||||
|
|
||||||
-- | Execute a shell command
|
-- | Execute a shell command
|
||||||
executeCommand :: SExp -> StateT Env IO SExp
|
executeCommand :: SExp -> StateT Env IO SExp
|
||||||
executeCommand (Command (Fix (Str cmdName)) args) = do
|
executeCommand (Cmd (Fix (Str cmdName)) args) = do
|
||||||
res <- (mapM toArg (map unFix args)) >>= return . catMaybes
|
res <- (mapM toArg (map unFix args)) >>= return . catMaybes
|
||||||
let argsHandle = (filter isJust (map toStdIn (map unFix args)))
|
let argsHandle = (filter isJust (map toStdIn (map unFix args)))
|
||||||
stdinhandle = case argsHandle of
|
stdinhandle = case argsHandle of
|
||||||
|
|
|
@ -7,20 +7,21 @@ module Lish.InternalCommands
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
import Data.Fix
|
import Data.Fix
|
||||||
import qualified Data.Map.Strict as Map
|
import qualified Data.Map.Strict as Map
|
||||||
import qualified Data.Text as Text
|
import qualified Data.Text as Text
|
||||||
import GHC.IO.Handle (hGetContents)
|
import GHC.IO.Handle (hGetContents)
|
||||||
import Lish.Types
|
|
||||||
import Protolude hiding (show)
|
import Protolude hiding (show)
|
||||||
import System.Environment (setEnv)
|
import System.Environment (setEnv)
|
||||||
|
|
||||||
|
import Lish.Types
|
||||||
|
|
||||||
toArg :: SExp -> StateT Env IO (Maybe Text)
|
toArg :: SExp -> StateT Env IO (Maybe Text)
|
||||||
toArg (Atom x) = do
|
toArg (Atom x) = do
|
||||||
env <- get
|
env <- get
|
||||||
return $ Just $ case Map.lookup x env of
|
return $ Just $ case Map.lookup x env of
|
||||||
Just (Str s) -> s
|
Just (Str s) -> s
|
||||||
_ -> toS x
|
_ -> toS x
|
||||||
toArg (Str s) = return $ Just $ toS s
|
toArg (Str s) = return $ Just $ toS s
|
||||||
toArg (Num i) = return . Just . toS . show $ i
|
toArg (Num i) = return . Just . toS . show $ i
|
||||||
toArg (Stream (Just h)) = lift $ fmap (Just . Text.strip .toS) (hGetContents h)
|
toArg (Stream (Just h)) = lift $ fmap (Just . Text.strip .toS) (hGetContents h)
|
||||||
|
@ -100,7 +101,7 @@ bbinop _ _ = evalErr "boolean binary operator need two booleans arguments"
|
||||||
|
|
||||||
lnot :: ReduceUnawareCommand
|
lnot :: ReduceUnawareCommand
|
||||||
lnot ((Bool x):[]) = return ( Bool (not x))
|
lnot ((Bool x):[]) = return ( Bool (not x))
|
||||||
lnot _ = evalErr "not need a boolean"
|
lnot _ = evalErr "not need a boolean"
|
||||||
|
|
||||||
toWaitingStream :: ReduceUnawareCommand
|
toWaitingStream :: ReduceUnawareCommand
|
||||||
toWaitingStream (Stream (Just h) :[]) = return (WaitingStream (Just h))
|
toWaitingStream (Stream (Just h) :[]) = return (WaitingStream (Just h))
|
||||||
|
@ -108,19 +109,28 @@ toWaitingStream _ = return Void
|
||||||
|
|
||||||
equal :: ReduceUnawareCommand
|
equal :: ReduceUnawareCommand
|
||||||
equal (x:y:[]) = return (Bool (x == y))
|
equal (x:y:[]) = return (Bool (x == y))
|
||||||
equal args = evalErr $ "= need two args, got " <> (toS (show args))
|
equal args = evalErr $ "= need two args, got " <> (toS (show args))
|
||||||
|
|
||||||
bintest :: (Integer -> Integer -> Bool) -> ReduceUnawareCommand
|
bintest :: (Integer -> Integer -> Bool) -> ReduceUnawareCommand
|
||||||
bintest f ((Num x):(Num y):[]) = return $ Bool (f x y)
|
bintest f ((Num x):(Num y):[]) = return $ Bool (f x y)
|
||||||
bintest _ args = evalErr $ "bin test need two numbers got " <> (toS (show args))
|
bintest _ args = evalErr $ "bin test need two numbers got " <> (toS (show args))
|
||||||
|
|
||||||
|
isReduced :: SExp -> Bool
|
||||||
|
isReduced (Atom _) = False
|
||||||
|
isReduced (Lambda _) = False
|
||||||
|
isReduced _ = True
|
||||||
|
|
||||||
|
deepReduce :: (Monad m) => (SExp -> m SExp) -> SExp -> m SExp
|
||||||
|
deepReduce f x =
|
||||||
|
if isReduced x
|
||||||
|
then pure x
|
||||||
|
else do
|
||||||
|
reducedOnce <- f x
|
||||||
|
deepReduce f reducedOnce
|
||||||
|
|
||||||
toStrictCmd :: ReduceUnawareCommand -> Command
|
toStrictCmd :: ReduceUnawareCommand -> Command
|
||||||
toStrictCmd f reducer sexps = do
|
toStrictCmd f reducer sexps =
|
||||||
reduced <- mapM reducer sexps
|
f =<< mapM (deepReduce reducer) sexps
|
||||||
-- DEBUG -- liftIO $ putText "Reduced:"
|
|
||||||
-- DEBUG -- liftIO $ print reduced
|
|
||||||
-- DEBUG -- liftIO $ putText "----"
|
|
||||||
f reduced
|
|
||||||
|
|
||||||
-- | fn to declare a lish function
|
-- | fn to declare a lish function
|
||||||
-- (fn [arg1 arg2] body1 body2)
|
-- (fn [arg1 arg2] body1 body2)
|
||||||
|
@ -140,7 +150,7 @@ fn reducer (p:bodies) = do
|
||||||
else return Void
|
else return Void
|
||||||
_ -> return Void
|
_ -> return Void
|
||||||
where fromAtom (Fix (Atom a)) = Just a
|
where fromAtom (Fix (Atom a)) = Just a
|
||||||
fromAtom _ = Nothing
|
fromAtom _ = Nothing
|
||||||
fn _ _ = return Void
|
fn _ _ = return Void
|
||||||
|
|
||||||
strictCommands :: [(Text,ReduceUnawareCommand)]
|
strictCommands :: [(Text,ReduceUnawareCommand)]
|
||||||
|
@ -189,22 +199,22 @@ lishIf :: Command
|
||||||
lishIf reduceLambda (sexp:sexp1:sexp2:[]) = do
|
lishIf reduceLambda (sexp:sexp1:sexp2:[]) = do
|
||||||
reducedSexp <- reduceLambda sexp
|
reducedSexp <- reduceLambda sexp
|
||||||
case reducedSexp of
|
case reducedSexp of
|
||||||
Bool True -> reduceLambda sexp1
|
Bool True -> reduceLambda sexp1
|
||||||
Bool False -> reduceLambda sexp2
|
Bool False -> reduceLambda sexp2
|
||||||
_ -> evalErr "first argument to if must be a Bool"
|
_ -> evalErr "first argument to if must be a Bool"
|
||||||
lishIf _ _ = evalErr "if need a bool, a then body and an else one"
|
lishIf _ _ = evalErr "if need a bool, a then body and an else one"
|
||||||
|
|
||||||
unstrictCommands :: [(Text,Command)]
|
unstrictCommands :: [(Text,InternalCommand)]
|
||||||
unstrictCommands = [ ("if",lishIf)
|
unstrictCommands = [ ("if", InternalCommand "if" lishIf)
|
||||||
, ("def",def)
|
, ("def", InternalCommand "def" def)
|
||||||
, ("fn",fn)
|
, ("fn", InternalCommand "fn" fn)
|
||||||
, ("do",doCommand)
|
, ("do", InternalCommand "do" doCommand)
|
||||||
]
|
]
|
||||||
|
|
||||||
internalCommands :: Map.Map Text Command
|
internalCommands :: Map.Map Text InternalCommand
|
||||||
internalCommands = (strictCommands & map (\(x,y) -> (x,toStrictCmd y)))
|
internalCommands = (strictCommands & map (\(x,y) -> (x,InternalCommand x (toStrictCmd y))))
|
||||||
<> unstrictCommands
|
<> unstrictCommands
|
||||||
& Map.fromList
|
& Map.fromList
|
||||||
|
|
||||||
lookup :: Text -> Maybe Command
|
lookup :: Text -> Maybe InternalCommand
|
||||||
lookup = flip Map.lookup internalCommands
|
lookup = flip Map.lookup internalCommands
|
||||||
|
|
|
@ -12,6 +12,7 @@ module Lish.Types
|
||||||
, Env
|
, Env
|
||||||
, CmdStream
|
, CmdStream
|
||||||
, Command
|
, Command
|
||||||
|
, InternalCommand (..)
|
||||||
, ReduceUnawareCommand
|
, ReduceUnawareCommand
|
||||||
-- types
|
-- types
|
||||||
, LishType(..)
|
, LishType(..)
|
||||||
|
@ -34,16 +35,17 @@ data ExprF a = Atom Text
|
||||||
| Lambda [a]
|
| Lambda [a]
|
||||||
| Void
|
| Void
|
||||||
-- only exists during evaluation
|
-- only exists during evaluation
|
||||||
|
| Internal InternalCommand
|
||||||
| Fn { params :: [Text]
|
| Fn { params :: [Text]
|
||||||
, body :: a
|
, body :: a
|
||||||
, closure :: Env
|
, closure :: Env
|
||||||
, types :: ([LishType],LishType)
|
, types :: ([LishType],LishType)
|
||||||
}
|
}
|
||||||
| Command { _cmdName :: a
|
| Cmd { _cmdName :: a
|
||||||
, _cmdArgs :: [a]}
|
, _cmdArgs :: [a]}
|
||||||
| Stream CmdStream
|
| Stream CmdStream
|
||||||
| WaitingStream CmdStream
|
| WaitingStream CmdStream
|
||||||
deriving (Eq,Show,Functor)
|
deriving (Eq, Show, Functor)
|
||||||
|
|
||||||
type Expr = Fix ExprF
|
type Expr = Fix ExprF
|
||||||
type SExp = ExprF Expr
|
type SExp = ExprF Expr
|
||||||
|
@ -61,13 +63,14 @@ type Context = Map Text LishType
|
||||||
|
|
||||||
repr :: ExprF Text -> Text
|
repr :: ExprF Text -> Text
|
||||||
repr (Atom s) = s
|
repr (Atom s) = s
|
||||||
|
repr (Internal (InternalCommand n _)) = n
|
||||||
repr (Num n) = toS $ show n
|
repr (Num n) = toS $ show n
|
||||||
repr (Bool b) = if b then "true" else "false"
|
repr (Bool b) = if b then "true" else "false"
|
||||||
repr (Str s) = "\"" <> toS s <> "\""
|
repr (Str s) = "\"" <> toS s <> "\""
|
||||||
repr (List sexprs) = "[" <> (Text.intercalate " " sexprs) <> "]"
|
repr (List sexprs) = "[" <> (Text.intercalate " " sexprs) <> "]"
|
||||||
repr (Lambda sexprs) = "(" <> (Text.intercalate " " sexprs) <> ")"
|
repr (Lambda sexprs) = "(" <> (Text.intercalate " " sexprs) <> ")"
|
||||||
repr Void = "ε"
|
repr Void = "ε"
|
||||||
repr (Command n args) = "($ " <> n <> (Text.intercalate " " args) <> ")"
|
repr (Cmd n args) = "($ " <> n <> (Text.intercalate " " args) <> ")"
|
||||||
repr (Fn p _ _ _) = "(λ" <> (Text.intercalate "." p) <> ". ... )"
|
repr (Fn p _ _ _) = "(λ" <> (Text.intercalate "." p) <> ". ... )"
|
||||||
repr (Stream _) = "<stream>"
|
repr (Stream _) = "<stream>"
|
||||||
repr (WaitingStream _) = "<w-stream>"
|
repr (WaitingStream _) = "<w-stream>"
|
||||||
|
@ -79,3 +82,10 @@ type CmdStream = Maybe Handle
|
||||||
type Env = Map Text SExp
|
type Env = Map Text SExp
|
||||||
type ReduceUnawareCommand = [SExp] -> StateT Env IO SExp
|
type ReduceUnawareCommand = [SExp] -> StateT Env IO SExp
|
||||||
type Command = (SExp -> StateT Env IO SExp) -> ReduceUnawareCommand
|
type Command = (SExp -> StateT Env IO SExp) -> ReduceUnawareCommand
|
||||||
|
data InternalCommand =
|
||||||
|
InternalCommand { _commandName :: Text
|
||||||
|
, _commandFn :: Command }
|
||||||
|
instance Show InternalCommand where
|
||||||
|
show x = toS (_commandName x)
|
||||||
|
instance Eq InternalCommand where
|
||||||
|
(==) x y = (_commandName x) == (_commandName y)
|
||||||
|
|
Loading…
Reference in a new issue