aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/Binary.hs12
-rw-r--r--src/Eval.hs46
-rw-r--r--src/Helper.hs64
-rw-r--r--src/Parser.hs43
-rw-r--r--src/Reducer.hs17
5 files changed, 85 insertions, 97 deletions
diff --git a/src/Binary.hs b/src/Binary.hs
index a9e8028..79d3fb6 100644
--- a/src/Binary.hs
+++ b/src/Binary.hs
@@ -14,9 +14,9 @@ import Data.Word ( Word8 )
import Helper
toBinary :: Expression -> String
-toBinary (Bruijn x ) = (replicate (x + 1) '1') ++ "0"
+toBinary (Bruijn x ) = replicate (x + 1) '1' ++ "0"
toBinary (Abstraction e ) = "00" ++ toBinary e
-toBinary (Application exp1 exp2) = "01" ++ (toBinary exp1) ++ (toBinary exp2)
+toBinary (Application exp1 exp2) = "01" ++ toBinary exp1 ++ toBinary exp2
toBinary _ = invalidProgramState
fromBinary' :: String -> (Expression, String)
@@ -30,10 +30,10 @@ fromBinary' inp = case inp of
_ -> invalidProgramState
where
binaryBruijn rst =
- let idx = (length $ takeWhile (== '1') $ inp) - 1
+ let idx = length (takeWhile (== '1') inp) - 1
in case rst of
- "" -> (Bruijn $ idx, "")
- _ -> (Bruijn $ idx, drop idx rst)
+ "" -> (Bruijn idx, "")
+ _ -> (Bruijn idx, drop idx rst)
fromBinary :: String -> Expression
fromBinary = fst . fromBinary'
@@ -60,7 +60,7 @@ fromBitString bits =
True -> '1'
)
$ Bit.toList
- $ Bit.take (Bit.length bits - (fromIntegral $ pad bits))
+ $ Bit.take (Bit.length bits - fromIntegral (pad bits))
$ Bit.drop 8 bits
where
pad :: Bit.BitString -> Word8
diff --git a/src/Eval.hs b/src/Eval.hs
index 3ee762f..5ef743c 100644
--- a/src/Eval.hs
+++ b/src/Eval.hs
@@ -12,6 +12,7 @@ import qualified Control.Monad.State.Strict as StrictState
import qualified Data.BitString as Bit
import qualified Data.ByteString.Lazy as Byte
import Data.Function ( on )
+import Data.Functor
import Data.List
import qualified Data.Map as M
import Data.Maybe
@@ -64,7 +65,7 @@ loadFile path conf cache = do
(filter (not . null) $ split "\n\n" f')
(EnvState
(Environment M.empty)
- (conf { _isRepl = False, _evalPaths = (path : (_evalPaths conf)) })
+ (conf { _isRepl = False, _evalPaths = path : _evalPaths conf })
cache
)
@@ -86,7 +87,7 @@ evalFun fun (Environment sub) = state $ \env@(Environment e) ->
_ -> (suggest $ lookup' e, env) -- search in global env
evalAbs :: Expression -> Environment -> EvalState (Failable Expression)
-evalAbs e sub = evalExp e sub >>= pure . fmap Abstraction
+evalAbs e sub = evalExp e sub <&> fmap Abstraction
evalApp
:: Expression -> Expression -> Environment -> EvalState (Failable Expression)
@@ -102,7 +103,7 @@ evalMixfix m sub = resolve (mixfixKind m) mixfixArgs
longestMatching x = evalFun (MixfixFunction x) sub >>= \case
Left _ -> longestMatching $ init x
Right _ -> pure $ Right $ Function $ MixfixFunction x
- holeCount f = length [ h | h@(MixfixNone) <- f ]
+ holeCount f = length [ h | h@MixfixNone <- f ]
resolve f args
| null [ s | s@(MixfixSome _) <- f ] = evalExp (foldl1 Application args) sub
| otherwise = longestMatching f >>= \case
@@ -114,7 +115,7 @@ evalMixfix m sub = resolve (mixfixKind m) mixfixArgs
[] -> evalExp (foldl1 Application $ l : splitted) sub
_ -> evalExp
( MixfixChain
- $ (MixfixExpression $ foldl1 Application $ l : splitted)
+ $ MixfixExpression (foldl1 Application $ l : splitted)
: chainRst
)
sub
@@ -183,10 +184,10 @@ evalCommand inp s@(EnvState env@(Environment envDefs) conf cache) = \case
full
(conf { _nicePath = path })
cache -- TODO: Fix wrong `within` in import error
- cache'' <- pure $ cache
- { _imported = M.insert path (Environment env')
- $ M.union (_imported cache) (_imported cache')
- }
+ let cache'' = cache
+ { _imported = M.insert path (Environment env')
+ $ M.union (_imported cache) (_imported cache')
+ }
pure $ EnvState (Environment $ M.union env' envDefs) conf cache'' -- import => _isRepl = False
Watch path ->
let
@@ -220,7 +221,7 @@ evalCommand inp s@(EnvState env@(Environment envDefs) conf cache) = \case
rewriteFuns =
M.map $ \d -> d { _flags = (_flags d) { _isImported = True } }
filterImported =
- M.filter $ \(EnvDef { _flags = f }) -> _isImported f == False
+ M.filter $ \(EnvDef { _flags = f }) -> not $ _isImported f
env'' = rewriteFuns $ rewriteKeys prefix $ filterImported env'
in
pure $ s { _env = Environment $ M.union env'' envDefs }
@@ -229,11 +230,11 @@ evalCommand inp s@(EnvState env@(Environment envDefs) conf cache) = \case
full
(conf { _nicePath = path })
cache -- TODO: Fix wrong `within` in import error
- cache'' <- pure $ cache
- { _imported = M.insert path (Environment env')
- $ M.union (_imported cache) (_imported cache')
- }
let
+ cache'' = cache
+ { _imported = M.insert path (Environment env')
+ $ M.union (_imported cache) (_imported cache')
+ }
prefix | null namespace = takeBaseName path ++ "."
| namespace == "." = ""
| otherwise = namespace ++ "."
@@ -242,8 +243,8 @@ evalCommand inp s@(EnvState env@(Environment envDefs) conf cache) = \case
rewriteFuns =
M.map $ \d -> d { _flags = (_flags d) { _isImported = True } }
filterImported =
- M.filter $ \(EnvDef { _flags = f }) -> _isImported f == False
- env'' <- pure $ rewriteFuns $ rewriteKeys prefix $ filterImported env'
+ M.filter $ \(EnvDef { _flags = f }) -> not $ _isImported f
+ env'' = rewriteFuns $ rewriteKeys prefix $ filterImported env'
pure $ EnvState (Environment $ M.union env'' envDefs) conf cache'' -- import => _isRepl = False
Test e1 e2
| _evalTests conf
@@ -273,8 +274,7 @@ evalCommand inp s@(EnvState env@(Environment envDefs) conf cache) = \case
Right e' -> do
red <- reduce e'
deepseq red (getTime Monotonic)
- let roundSecs x =
- (fromIntegral (round $ x * 1e6 :: Integer)) / 1e6 :: Double
+ let roundSecs x = fromIntegral (round $ x * 1e6 :: Integer) / 1e6 :: Double
putStr
$ show
$ roundSecs
@@ -290,7 +290,7 @@ showResult reduced env =
humanified = humanifyExpression reduced
in putStrLn
$ "*> "
- <> (show reduced)
+ <> show reduced
<> (if null humanified then "" else "\n?> " <> humanified)
<> (if null matching then "" else "\n#> " <> matching)
@@ -305,7 +305,7 @@ evalInstruction (ContextualInstruction instr inp) s@(EnvState env conf _) rec =
Left err ->
print (ContextualError err $ Context inp $ _nicePath conf) >> pure s -- don't continue
Right _
- | _isRepl conf -> (putStrLn $ show i <> " = " <> show e)
+ | _isRepl conf -> putStrLn (show i <> " = " <> show e)
>> return s { _env = env' }
| otherwise -> rec s { _env = env' }
Evaluate e ->
@@ -385,9 +385,8 @@ exec path rd conv = do
repl :: EnvState -> InputT M ()
repl (EnvState env conf cache) =
- (handleInterrupt (return $ Just "") $ withInterrupt $ getInputLine
- "\ESC[36mλ\ESC[0m "
- )
+ handleInterrupt (return $ Just "")
+ (withInterrupt $ getInputLine "\ESC[36mλ\ESC[0m ")
>>= \case -- TODO: Add non-parser error support for REPL
Nothing -> return ()
Just line -> do -- setting imported [] for better debugging
@@ -428,10 +427,9 @@ runRepl = do
conf
(EnvCache M.empty)
)
- code <- StrictState.evalStateT
+ StrictState.evalStateT
looper
(EnvState (Environment M.empty) conf (EnvCache M.empty))
- return code
usage :: IO ()
usage = do
diff --git a/src/Helper.hs b/src/Helper.hs
index bf5bc23..bfeeb66 100644
--- a/src/Helper.hs
+++ b/src/Helper.hs
@@ -16,6 +16,7 @@ import qualified Data.ByteString.Lazy as Byte
import qualified Data.ByteString.Lazy.Char8 as C
import Data.List
import qualified Data.Map as M
+import Data.Maybe ( fromMaybe )
import GHC.Generics ( Generic )
import Text.Megaparsec
@@ -37,16 +38,13 @@ printContext (Context inp path) = p $ lines inp
p [] = withinText <> show path <> "\n"
p [l] = inText <> l <> "\n" <> withinText <> path <> "\n"
p (l : ls) =
- (p [l])
- <> nearText
- <> (intercalate "\n" $ map (" | " ++) $ take 3 $ ls)
- <> "\n"
+ p [l] <> nearText <> intercalate "\n" (map (" | " ++) $ take 3 ls) <> "\n"
errPrefix :: String
errPrefix = "\ESC[101m\ESC[30mERROR\ESC[0m "
data Error = SyntaxError String | UndefinedIdentifier Identifier | UnmatchedMixfix [MixfixIdentifierKind] [Mixfix] | InvalidIndex Int | FailedTest Expression Expression Expression Expression | ContextualError Error Context | SuggestSolution Error String | ImportError String
instance Show Error where
- show (ContextualError err ctx) = show err <> "\n" <> (printContext ctx)
+ show (ContextualError err ctx) = show err <> "\n" <> printContext ctx
show (SuggestSolution err sol) =
show err <> "\n\ESC[102m\ESC[30msuggestion\ESC[0m Perhaps you meant " <> sol
show (SyntaxError err) =
@@ -56,9 +54,9 @@ instance Show Error where
show (UnmatchedMixfix ks ms) =
errPrefix
<> "couldn't find matching mixfix for "
- <> (intercalate "" (map show ks))
+ <> intercalate "" (map show ks)
<> "\n\ESC[105m\ESC[30mnear\ESC[0m "
- <> (intercalate " " (map show ms))
+ <> unwords (map show ms)
show (InvalidIndex err) = errPrefix <> "invalid index " <> show err
show (FailedTest exp1 exp2 red1 red2) =
errPrefix
@@ -87,7 +85,7 @@ printBundle ParseErrorBundle {..} =
where
(msline, pst') = reachOffset (errorOffset e) pst
epos = pstateSourcePos pst'
- outChunk = "\n\n" <> offendingLine <> (init $ parseErrorTextPretty e)
+ outChunk = "\n\n" <> offendingLine <> init (parseErrorTextPretty e)
offendingLine = case msline of
Nothing -> ""
Just sline ->
@@ -131,25 +129,24 @@ instance Show Mixfix where
-- TODO: Remove Application and replace with Chain (renaming of MixfixChain)
data Expression = Bruijn Int | Function Identifier | Abstraction Expression | Application Expression Expression | MixfixChain [Mixfix] | Prefix Identifier Expression
deriving (Ord, Eq, Generic, NFData)
-instance Show Expression where -- TODO: make use of precedence value?
+instance Show Expression where
showsPrec _ (Bruijn x) =
showString "\ESC[91m" . shows x . showString "\ESC[0m"
showsPrec _ (Function ident) =
showString "\ESC[95m" . shows ident . showString "\ESC[0m"
showsPrec _ (Abstraction e) =
- showString "\ESC[36m[\ESC[0m" . showsPrec 0 e . showString
- "\ESC[36m]\ESC[0m"
+ showString "\ESC[36m[\ESC[0m" . shows e . showString "\ESC[36m]\ESC[0m"
showsPrec _ (Application exp1 exp2) =
showString "\ESC[33m(\ESC[0m"
- . showsPrec 0 exp1
+ . shows exp1
. showString " "
- . showsPrec 0 exp2
+ . shows exp2
. showString "\ESC[33m)\ESC[0m"
showsPrec _ (MixfixChain ms) =
showString "\ESC[33m(\ESC[0m"
- . foldr (.) id (map (showsPrec 0) ms)
+ . foldr1 (\x y -> x . showString " " . y) (map shows ms)
. showString "\ESC[33m)\ESC[0m"
- showsPrec _ (Prefix p e) = shows p . showString " " . showsPrec 0 e
+ showsPrec _ (Prefix p e) = shows p . showString " " . shows e
data Command = Input String | Watch String | Import String String | Test Expression Expression | ClearState | Time Expression
deriving (Show)
data Instruction = Define Identifier Expression [Instruction] | Evaluate Expression | Comment | Commands [Command] | ContextualInstruction Instruction String
@@ -161,7 +158,7 @@ data EvalConf = EvalConf
, _nicePath :: String
, _evalPaths :: [String]
}
-data ExpFlags = ExpFlags
+newtype ExpFlags = ExpFlags
{ _isImported :: Bool
}
deriving Show
@@ -171,9 +168,9 @@ data EnvDef = EnvDef
, _flags :: ExpFlags
}
deriving Show
-data Environment = Environment (M.Map Identifier EnvDef)
+newtype Environment = Environment (M.Map Identifier EnvDef)
deriving Show
-data EnvCache = EnvCache
+newtype EnvCache = EnvCache
{ _imported :: M.Map String Environment
}
type EvalState = S.State Environment
@@ -196,8 +193,7 @@ listify (e : es) =
Abstraction (Application (Application (Bruijn 0) e) (listify es))
binarify :: [Expression] -> Expression
-binarify [] = Bruijn 2
-binarify (e : es) = Application e (binarify es)
+binarify = foldr Application (Bruijn 2)
encodeByte :: [Bool] -> Expression
encodeByte bits = Abstraction $ Abstraction $ Abstraction $ binarify
@@ -219,14 +215,12 @@ charToExpression :: Char -> Expression
charToExpression ch = encodeByte $ Bit.toList $ Bit.bitStringLazy $ C.pack [ch]
encodeStdin :: IO Expression
-encodeStdin = do
- bytes <- Byte.getContents
- pure $ encodeBytes bytes
+encodeStdin = encodeBytes <$> Byte.getContents
unlistify :: Expression -> Maybe [Expression]
unlistify (Abstraction (Abstraction (Bruijn 0))) = Just []
unlistify (Abstraction (Application (Application (Bruijn 0) e) es)) =
- (:) <$> Just e <*> (unlistify es)
+ (:) <$> Just e <*> unlistify es
unlistify _ = Nothing
unpairify :: Expression -> Maybe [Expression]
@@ -236,8 +230,8 @@ unpairify _ = Nothing
decodeByte :: Expression -> Maybe [Bool]
decodeByte (Abstraction (Abstraction (Abstraction es))) = decodeByte es
-decodeByte (Application (Bruijn 0) es) = (:) <$> Just False <*> (decodeByte es)
-decodeByte (Application (Bruijn 1) es) = (:) <$> Just True <*> (decodeByte es)
+decodeByte (Application (Bruijn 0) es) = (:) <$> Just False <*> decodeByte es
+decodeByte (Application (Bruijn 1) es) = (:) <$> Just True <*> decodeByte es
decodeByte (Bruijn 2 ) = Just []
decodeByte _ = Nothing
@@ -290,21 +284,19 @@ maybeHumanifyExpression e =
<|> humanifyPair e
humanifyExpression :: Expression -> String
-humanifyExpression e = case maybeHumanifyExpression e of
- Nothing -> ""
- Just h -> h
+humanifyExpression e = fromMaybe "" (maybeHumanifyExpression e)
humanifyList :: Expression -> Maybe String
humanifyList e = do
es <- unlistify e
- let conv x = maybe (show x) id (maybeHumanifyExpression x)
+ let conv x = fromMaybe (show x) (maybeHumanifyExpression x)
m = map conv es
pure $ "{" <> intercalate ", " m <> "}"
humanifyPair :: Expression -> Maybe String
humanifyPair e = do
es <- unpairify e
- let conv x = maybe (show x) id (maybeHumanifyExpression x)
+ let conv x = fromMaybe (show x) (maybeHumanifyExpression x)
m = map conv es
pure $ "<" <> intercalate " : " m <> ">"
@@ -323,7 +315,7 @@ decimalToTernary n =
-- Decimal to binary encoding
decimalToBinary :: Integer -> Expression
decimalToBinary n | n < 0 = decimalToBinary 0
-decimalToBinary n | otherwise = Abstraction $ Abstraction $ Abstraction $ gen n
+ | otherwise = Abstraction $ Abstraction $ Abstraction $ gen n
where
gen 0 = Bruijn 2
gen n' = Application (Bruijn $ fromIntegral $ mod n' 2) (gen $ div n' 2)
@@ -331,7 +323,7 @@ decimalToBinary n | otherwise = Abstraction $ Abstraction $ Abstraction $ gen n
-- Decimal to unary (church) encoding
decimalToUnary :: Integer -> Expression
decimalToUnary n | n < 0 = decimalToUnary 0
-decimalToUnary n | otherwise = Abstraction $ Abstraction $ gen n
+ | otherwise = Abstraction $ Abstraction $ gen n
where
gen 0 = Bruijn 0
gen n' = Application (Bruijn 1) (gen (n' - 1))
@@ -347,7 +339,7 @@ unaryToDecimal e = do
resolve' (Application x@(Bruijn _) (Bruijn 0)) =
(:) <$> multiplier x <*> Just []
resolve' (Application x@(Bruijn _) xs@(Application _ _)) =
- (:) <$> (multiplier x) <*> (resolve' xs)
+ (:) <$> multiplier x <*> resolve' xs
resolve' _ = Nothing
resolve (Abstraction (Abstraction n)) = resolve' n
resolve _ = Nothing
@@ -364,7 +356,7 @@ binaryToDecimal e = do
resolve' (Application x@(Bruijn _) (Bruijn 2)) =
(:) <$> multiplier x <*> Just []
resolve' (Application x@(Bruijn _) xs@(Application _ _)) =
- (:) <$> (multiplier x) <*> (resolve' xs)
+ (:) <$> multiplier x <*> resolve' xs
resolve' _ = Nothing
resolve (Abstraction (Abstraction (Abstraction n))) = resolve' n
resolve _ = Nothing
@@ -382,7 +374,7 @@ ternaryToDecimal e = do
resolve' (Application x@(Bruijn _) (Bruijn 3)) =
(:) <$> multiplier x <*> Just []
resolve' (Application x@(Bruijn _) xs@(Application _ _)) =
- (:) <$> (multiplier x) <*> (resolve' xs)
+ (:) <$> multiplier x <*> resolve' xs
resolve' _ = Nothing
resolve (Abstraction (Abstraction (Abstraction (Abstraction n)))) =
resolve' n
diff --git a/src/Parser.hs b/src/Parser.hs
index b82a266..d796682 100644
--- a/src/Parser.hs
+++ b/src/Parser.hs
@@ -25,7 +25,7 @@ greekLetter = satisfy isGreek
emoticon :: Parser Char
emoticon = satisfy isEmoticon
- where isEmoticon c = ('\128512' <= c && c <= '\128591')
+ where isEmoticon c = '\128512' <= c && c <= '\128591'
mathematicalOperator :: Parser Char
mathematicalOperator =
@@ -33,8 +33,8 @@ mathematicalOperator =
<|> satisfy isMiscMathematicalAUnicodeBlock
<|> oneOf "¬₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾"
where
- isMathematicalUnicodeBlock c = ('∀' <= c && c <= '⋿')
- isMiscMathematicalAUnicodeBlock c = ('⟀' <= c && c <= '⟯')
+ isMathematicalUnicodeBlock c = '∀' <= c && c <= '⋿'
+ isMiscMathematicalAUnicodeBlock c = '⟀' <= c && c <= '⟯'
mathematicalArrow :: Parser Char
mathematicalArrow = satisfy isMathematicalOperator
@@ -51,12 +51,12 @@ mixfixNone :: Parser MixfixIdentifierKind
mixfixNone = char '…' >> pure MixfixNone
mixfixSome :: Parser MixfixIdentifierKind
-mixfixSome = MixfixSome <$> (some specialChar)
+mixfixSome = MixfixSome <$> some specialChar
mixfixOperator :: Parser Identifier
mixfixOperator = normalMixfix <|> namespacedMixfix
where
- normalMixfix = MixfixFunction <$> (some $ mixfixNone <|> mixfixSome)
+ normalMixfix = MixfixFunction <$> some (mixfixNone <|> mixfixSome)
namespacedMixfix = NamespacedFunction <$> dottedNamespace <*> mixfixOperator
prefixOperator :: Parser Identifier
@@ -117,9 +117,9 @@ parseNumeral :: Parser Expression
parseNumeral = do
_ <- string "(" <?> "number start"
num <- number <?> "signed number"
- base <- (try (oneOf "ubt") <|> return 't')
+ base <- try (oneOf "ubt") <|> return 't'
_ <- string ")" <?> "number end"
- pure $ (f base) num
+ pure $ f base num
where
f 't' = decimalToTernary
f 'b' = decimalToBinary
@@ -142,7 +142,7 @@ parseString = do
between
(char '\"')
(char '\"')
- (some $ (char '\\' *> specialEscape) <|> (satisfy (`notElem` "\"\\")))
+ (some $ (char '\\' *> specialEscape) <|> satisfy (`notElem` "\"\\"))
<?> "quoted string"
pure $ stringToExpression str
@@ -156,9 +156,7 @@ parseChar = do
pure $ charToExpression ch
parseFunction :: Parser Expression
-parseFunction = do
- var <- identifier
- pure $ Function var
+parseFunction = Function <$> identifier
parseMixfix :: Parser Expression
parseMixfix = do
@@ -237,7 +235,7 @@ parseTypeExpression = parseFunctionType <?> "type expression"
parseDefineType :: Parser ()
parseDefineType = do
- (try $ char '⧗' <* sc *> parseTypeExpression) <|> (return ())
+ try (char '⧗' <* sc *> parseTypeExpression) <|> return ()
parseDefine :: Int -> Parser Instruction
parseDefine lvl = do
@@ -247,7 +245,7 @@ parseDefine lvl = do
e <- parseExpression
_ <- parseDefineType
subs <-
- (try $ newline *> (many $ parseBlock $ lvl + 1)) <|> (try eof >> return [])
+ try (newline *> many (parseBlock $ lvl + 1)) <|> (try eof >> return [])
pure $ ContextualInstruction (Define var e subs) inp
parseReplDefine :: Parser Instruction
@@ -280,7 +278,7 @@ parseImport :: Parser Command
parseImport = do
_ <- string ":import" <* sc <?> "import instruction"
path <- importPath
- ns <- (try $ sc *> (namespace <|> string ".")) <|> (eof >> return "")
+ ns <- try (sc *> (namespace <|> string ".")) <|> (eof >> return "")
pure $ Import (path ++ ".bruijn") ns
parseInput :: Parser Command
@@ -321,9 +319,8 @@ parseCommandBlock = do
parseDefBlock :: Int -> Parser Instruction
parseDefBlock lvl =
- (sepEndBy parseComment newline)
- *> string (replicate lvl '\t')
- *> (try $ parseDefine lvl)
+ sepEndBy parseComment newline *> string (replicate lvl '\t') *> try
+ (parseDefine lvl)
parseBlock :: Int -> Parser Instruction
parseBlock lvl =
@@ -332,10 +329,10 @@ parseBlock lvl =
parseReplLine :: Parser Instruction
parseReplLine =
try parseReplDefine -- TODO: This is kinda hacky
- <|> ((Commands . (: [])) <$> try parseTest)
- <|> ((Commands . (: [])) <$> try parseInput)
- <|> ((Commands . (: [])) <$> try parseWatch)
- <|> ((Commands . (: [])) <$> try parseImport)
- <|> ((Commands . (: [])) <$> try parseTime)
- <|> ((Commands . (: [])) <$> try parseClearState)
+ <|> (Commands . (: []) <$> try parseTest)
+ <|> (Commands . (: []) <$> try parseInput)
+ <|> (Commands . (: []) <$> try parseWatch)
+ <|> (Commands . (: []) <$> try parseImport)
+ <|> (Commands . (: []) <$> try parseTime)
+ <|> (Commands . (: []) <$> try parseClearState)
<|> try parseEvaluate
diff --git a/src/Reducer.hs b/src/Reducer.hs
index ba63675..cfa9a35 100644
--- a/src/Reducer.hs
+++ b/src/Reducer.hs
@@ -8,14 +8,15 @@ import Control.Concurrent.MVar
import Data.List ( elemIndex )
import Data.Map ( Map )
import qualified Data.Map as Map
+import Data.Maybe ( fromMaybe )
import Helper
type Store = Map Int Box
type Stack = [Redex]
-data NameGen = NameGen Int
+newtype NameGen = NameGen Int
data BoxValue = Todo Redex | Done Redex | Empty
-data Box = Box (MVar BoxValue)
+newtype Box = Box (MVar BoxValue)
data Rvar = Num Int | Hole
data Redex = Rabs Int Redex | Rapp Redex Redex | Rvar Rvar | Rclosure Redex Store | Rcache Box Redex
data Conf = Econf NameGen Redex Store Stack | Cconf NameGen Stack Redex | End
@@ -46,12 +47,12 @@ fromRedex = convertWorker []
let lhs = convertWorker es l
rhs = convertWorker es r
in Application lhs rhs
- convertWorker es (Rvar (Num n)) = Bruijn $ maybe n id (elemIndex n es)
+ convertWorker es (Rvar (Num n)) = Bruijn $ fromMaybe n (elemIndex n es)
convertWorker _ _ = invalidProgramState
transition :: Conf -> IO Conf
transition (Econf g (Rapp u v) e s) =
- pure $ Econf g u e ((Rapp (Rvar Hole) (Rclosure v e)) : s)
+ pure $ Econf g u e (Rapp (Rvar Hole) (Rclosure v e) : s)
transition (Econf g (Rabs x t) e s) = do
box <- newMVar Empty
pure $ Cconf g s (Rcache (Box box) (Rclosure (Rabs x t) e))
@@ -60,7 +61,7 @@ transition (Econf g (Rvar (Num x)) e s) = do
let b@(Box m) = Map.findWithDefault (Box def) x e
rd <- readMVar m
case rd of
- Todo (Rclosure v e') -> pure $ Econf g v e' ((Rcache b (Rvar Hole)) : s)
+ Todo (Rclosure v e') -> pure $ Econf g v e' (Rcache b (Rvar Hole) : s)
Done t -> pure $ Cconf g s t
_ -> invalidProgramState
transition (Cconf g ((Rcache (Box m) (Rvar Hole)) : s) t) = do
@@ -80,10 +81,10 @@ transition (Cconf g s (Rcache (Box m) (Rclosure (Rabs x t) e))) = do
pure $ Econf g'
t
(Map.insert x (Box box) e)
- ((Rabs x1 (Rvar Hole)) : (Rcache (Box m) (Rvar Hole)) : s)
+ (Rabs x1 (Rvar Hole) : Rcache (Box m) (Rvar Hole) : s)
Todo _ -> invalidProgramState
transition (Cconf g ((Rapp (Rvar Hole) (Rclosure v e)) : s) t) =
- pure $ Econf g v e ((Rapp t (Rvar Hole)) : s)
+ pure $ Econf g v e (Rapp t (Rvar Hole) : s)
transition (Cconf g ((Rapp t (Rvar Hole)) : s) v) = pure $ Cconf g s (Rapp t v)
transition (Cconf g ((Rabs x1 (Rvar Hole)) : s) v) =
pure $ Cconf g s (Rabs x1 v)
@@ -101,7 +102,7 @@ loadTerm t = Econf (NameGen 1000000) t Map.empty []
reduce :: Expression -> IO Expression
reduce e = do
- redex <- pure $ toRedex e
+ let redex = toRedex e
forEachState (loadTerm redex) transition >>= \case
Cconf _ [] v -> pure $ fromRedex v
_ -> invalidProgramState