pi-forall-0.1.1: src/Main.hs
{- PiForall language, OPLSS -}
{-# OPTIONS_GHC -Wall -fno-warn-unused-matches #-}
-- | The command line interface to the pi type checker.
-- Also provides functions for type checking individual terms
-- and files.
module Main(goFilename,go,main, test) where
import Modules (getModules)
import PrettyPrint
import Environment
import TypeCheck
import Parser
import Text.PrettyPrint.HughesPJ (render)
import Text.ParserCombinators.Parsec.Error
import Control.Monad.Except
import System.Environment(getArgs)
import System.Exit (exitFailure,exitSuccess)
import System.FilePath (splitFileName)
exitWith :: Either a b -> (a -> IO ()) -> IO b
exitWith res f =
case res of
Left x -> f x >> exitFailure
Right y -> return y
-- | Type check the given string in the empty environment
go :: String -> IO ()
go str = do
case parseExpr str of
Left parseError -> putParseError parseError
Right term -> do
putStrLn "parsed as"
putStrLn $ render $ disp term
res <- runTcMonad emptyEnv (inferType term)
case res of
Left typeError -> putTypeError typeError
Right (aterm, ty) -> do
putStrLn $ render $ disp aterm
putStrLn "typed with type"
putStrLn $ render $ disp ty
-- | Display a parse error to the user
putParseError :: ParseError -> IO ()
putParseError parseError = do
putStrLn $ render $ disp $ errorPos parseError
putStrLn $ show parseError
-- | Display a type error to the user
putTypeError :: Disp d => d -> IO ()
putTypeError typeError = do
putStrLn "Type Error:"
putStrLn $ render $ disp typeError
-- | Type check the given file
goFilename :: String -> IO ()
goFilename pathToMainFile = do
let prefixes = currentDir : mainFilePrefix : []
(mainFilePrefix, name) = splitFileName pathToMainFile
currentDir = ""
putStrLn $ "processing " ++ name ++ "..."
v <- runExceptT (getModules prefixes name)
val <- v `exitWith` putParseError
putStrLn "type checking..."
d <- runTcMonad emptyEnv (tcModules val)
defs <- d `exitWith` putTypeError
putStrLn $ render $ disp (last defs)
test :: IO ()
test = do
goFilename "../test/Lec1.pi"
goFilename "../test/Hw1.pi"
goFilename "../test/Lec2.pi"
goFilename "../test/Hw2.pi"
goFilename "../test/Lec3.pi"
goFilename "../test/Fin1.pi"
goFilename "../test/Lec4.pi"
goFilename "../test/Logic.pi"
goFilename "../test/Equality.pi"
goFilename "../test/Product.pi"
goFilename "../test/Nat.pi"
goFilename "../test/Fin.pi"
goFilename "../test/Vec.pi"
goFilename "../test/Lambda0.pi"
goFilename "../test/Lambda1.pi"
goFilename "../test/Lambda2.pi"
-- | 'pi <filename>' invokes the type checker on the given
-- file and either prints the types of all definitions in the module
-- or prints an error message.
main :: IO ()
main = do
[pathToMainFile] <- getArgs
goFilename pathToMainFile
exitSuccess