packages feed

ministg-0.3: src/Main.hs

-----------------------------------------------------------------------------
-- |
-- Module      : Main 
-- Copyright   : (c) 2009 Bernie Pope 
-- License     : BSD-style
-- Maintainer  : bjpop@csse.unimelb.edu.au
-- Stability   : experimental
-- Portability : ghc
--
-- The main module of ministg. An interpreter for the operational semantics
-- of the STG machine, as set out in the "How to make a fast curry" paper
-- by Simon Marlow and Simon Peyton Jones.
-----------------------------------------------------------------------------

module Main where

import System.Exit (exitFailure)
import Ministg.AST (Program (Program))
import Ministg.Parser (parser)
import Ministg.Lexer (lexer, Token)
import Control.Monad (when, unless)
import System.Environment (getArgs)
import System.Directory (doesDirectoryExist, createDirectory)
import Ministg.Utils (safeReadFile)
import Ministg.Arity (runArity)
import Ministg.Eval (run)
import Ministg.Pretty (prettyText)
import Ministg.Options (processOptions, Flag (..), Dumped (..), existsFlag, getTraceDir)
import Ministg.Annotate

-- | The main driver of the program.
main :: IO ()
main = do
   args <- getArgs
   (flags, file) <- processOptions args
   -- create trace directory if necessary
   when (existsFlag flags Trace) $ do
      let traceDir = getTraceDir flags
      dirExist <- doesDirectoryExist traceDir
      unless dirExist $ createDirectory traceDir 
   -- parse the file
   Program userProgram <- parseFile flags file
   -- optionally include the Prelude
   fullProgram 
      <- if existsFlag flags NoPrelude
            then return (Program userProgram)
            else do Program preludeProgram <- parseFile flags "Prelude.stg"
                    return $ Program (preludeProgram ++ userProgram)
   -- possibly annotate the program with stack markers
   let annotated = if existsFlag flags Annotate 
                      then annotate fullProgram else fullProgram 
   -- compute arities of known functions
   let arityProgram = runArity annotated 
   dump flags DumpArity (prettyText arityProgram) $
      "The program after arity analysis:\n"
   -- interpret the program
   run flags arityProgram

parseFile :: [Flag] -> FilePath -> IO Program
parseFile flags file = do
   tryContents <- safeReadFile file
   case tryContents of
      Left error -> putStrLn error >> exitFailure
      Right contents -> do
         -- parse the program
         case parser file contents of
            Left e -> (putStrLn $ "Parse error: " ++ show e) >> exitFailure
            Right program -> do 
               dump flags DumpAST (show program) $ "The AST of the program from " ++ file ++ ":\n"
               dump flags DumpParsed (prettyText program) $
                    "The parsed program from " ++ file ++ ":\n"
               return program 

dump :: [Flag] -> Dumped -> String -> String -> IO () 
dump flags dumped str msg = 
   when (existsFlag flags $ Dump dumped) $ do
      putStrLn msg 
      putStrLn str 
      putStr "\n"