1 {-# OPTIONS_GHC -fno-warn-unused-do-bind #-}
3 module HM.Interpreter (
7 import Data.Text as T (Text, pack)
8 import qualified Data.Text.IO as T
9 import Data.Attoparsec.Text
10 import qualified Data.Map as M
11 import Control.Applicative
13 import System.Environment
19 data Definition = Definition String TypedTerm
21 dictionary :: [Definition] -> M.Map VarName TypedTerm
22 dictionary = M.fromList . map (\ (Definition s t) -> (s, t))
24 parseDefinition :: Parser Definition
29 return $! Definition name t
31 parseImport :: Parser String
33 string (T.pack "import ")
36 parseFile :: Text -> ([FilePath], [Definition], [Term])
37 parseFile txt = case cnt of
40 where cnt = parseOnly (parserF <* endOfInput) txt
42 imports <- many (parseImport <* char '\n')
43 defs <- many (parseDefinition <* char '\n')
44 terms <- many (parseTypedTerm <* char '\n')
45 return (imports, defs, terms)
47 printEval :: (Term -> Term) -> Term -> IO ()
49 putStrLn $ show t ++ ":"
50 putStrLn $ " " ++ show (reduce $ def t)
53 makeDefTerm :: [Definition] -> Term -> Term
54 makeDefTerm (Definition name dTerm : ds) t = App (Lambda name (makeDefTerm ds t)) dTerm
57 interpret :: FilePath -> IO ()
58 interpret filename = do
59 (imports, defs, terms) <- parseFile <$> T.readFile filename
60 importDefs <- forM imports $ \ file -> do
61 (_, idefs, _) <- parseFile <$> T.readFile (file ++ ".hm")
63 let defT = makeDefTerm $ concat importDefs ++ defs
64 mapM_ (printEval defT) terms