elm-repl-0.4: src/Environment.hs
{-# LANGUAGE OverloadedStrings #-}
module Environment where
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as BS
import Data.Monoid ((<>))
import Data.Trie (Trie) -- TODO: Switch to a Char-based trie.
import qualified Data.Trie as Trie
import qualified Input
data Env = Env
{ compilerPath :: FilePath
, interpreterPath :: FilePath
, flags :: [String]
, imports :: Trie String
, adts :: Trie String
, defs :: Trie String
}
deriving Show
empty :: FilePath -> FilePath -> Env
empty compiler interpreter =
Env compiler
interpreter
[]
Trie.empty
Trie.empty
(Trie.singleton firstVar (BS.unpack firstVar <> " = ()"))
firstVar :: ByteString
firstVar = "tsol"
lastVar :: ByteString
lastVar = "deltron3030"
lastVarString :: String
lastVarString =
BS.unpack lastVar
toElmCode :: Env -> String
toElmCode env =
unlines $ "module Repl where" : decls
where
decls =
concatMap Trie.elems [ imports env, adts env, defs env ]
insert :: (Maybe Input.DefName, String) -> Env -> Env
insert (maybeName, src) env =
case maybeName of
Nothing ->
display src env
Just (Input.Import name) ->
noDisplay $ env
{ imports = Trie.insert (BS.pack name) src (imports env)
}
Just (Input.DataDef name) ->
noDisplay $ env
{ adts = Trie.insert (BS.pack name) src (adts env)
}
Just (Input.VarDef name) ->
define (BS.pack name) src (display name env)
define :: ByteString -> String -> Env -> Env
define name body env =
env { defs = Trie.insert name body (defs env) }
display :: String -> Env -> Env
display body env =
define lastVar (format body) env
where
format body =
lastVarString ++ " =" ++ concatMap ("\n "++) (lines body)
noDisplay :: Env -> Env
noDisplay env =
env { defs = Trie.delete lastVar (defs env) }