Sockeye: Implement proper module instantiation check
[barrelfish] / tools / sockeye / Main.hs
index c3793f6..e0e6eaf 100644 (file)
 module Main where
 
 import Control.Monad
+
 import Data.List
+
 import System.Console.GetOpt
 import System.Exit
 import System.Environment
 import System.IO
 
-import SockeyeAST as AST
+import qualified SockeyeASTParser as ParseAST
+import qualified SockeyeAST as AST
+import qualified SockeyeASTDecodingNet as NetAST
+
 import SockeyeParser
 import SockeyeChecker
-import qualified SockeyeBackendPrintAST as PrintAST
+import SockeyeNetBuilder
+
 import qualified SockeyeBackendProlog as Prolog
 
+import Debug.Trace
+import Text.Groom(groom)
+
+{- Exit codes -}
+usageError :: ExitCode
+usageError = ExitFailure 1
+
+parseError :: ExitCode
+parseError = ExitFailure 2
+
+checkError :: ExitCode
+checkError = ExitFailure 3
+
+buildError :: ExitCode
+buildError = ExitFailure 4
+
 {- Compilation targets -}
-data Target = None | PrintAST | Prolog
+data Target = None | Prolog
 
 {- Possible options for the Sockeye Compiler -}
 data Options = Options { optInputFile  :: FilePath
@@ -69,9 +91,6 @@ options =
     [ Option "P" ["Prolog"]
         (NoArg (\opts -> return $ optSetTarget Prolog opts))
         "Generate a prolog file that can be loaded into the SKB (default)."
-    , Option "A" ["AST"]
-        (NoArg (\opts -> return $ optSetTarget PrintAST opts))
-        "Print the AST."
     , Option "C" ["Check"]
         (NoArg (\opts -> return $ optSetTarget None opts))
         "Just check the file, do not compile."
@@ -91,59 +110,66 @@ compilerOpts argv =
     case getOpt Permute options argv of
         (actions, fs, []) -> do
             opts <- foldl (>>=) (return defaultOptions) actions
-            case fs of []  -> do
-                                usage ["No input file\n"]
-                                exitWith $ ExitFailure 1
-                       [f] -> return $ optSetInputFileName f opts
-                       _   -> do
-                                usage ["Multiple input files not supported\n"]
-                                exitWith $ ExitFailure 1
+            case fs of
+                []  -> do
+                    usage ["No input file\n"]
+                    exitWith usageError
+                [f] -> return $ optSetInputFileName f opts
+                _   -> do
+                    usage ["Multiple input files not supported\n"]
+                    exitWith usageError
 
         (_, _, errors) -> do
             usage errors
-            exitWith $ ExitFailure 1
+            exitWith $ usageError
 
 {- Runs the parser -}
-parseFile :: FilePath -> IO (AST.NetSpec)
+parseFile :: FilePath -> IO (ParseAST.SockeyeSpec)
 parseFile file = do
     src <- readFile file
     case parseSockeye file src of
         Left err -> do
             hPutStrLn stderr $ "Parse error at " ++ show err
-            exitWith $ ExitFailure 2
+            exitWith parseError
         Right ast -> return ast
 
 {- Runs the checker -}
-checkAST :: AST.NetSpec -> IO ()
-checkAST ast = do
-    case checkSockeye ast of 
-        [] -> return ()
-        errors -> do
-            hPutStr stderr $ unlines (foldl flattenErrors ["Failed checks:"] errors)
-            exitWith $ ExitFailure 3
-        where flattenErrors es (key, errors)
-                = let indented = map ((replicate 4 ' ') ++) errors
-                  in es ++ case key of Nothing     -> errors
-                                       Just nodeId -> ("In specification of node '" ++ show nodeId ++ "':"):indented
+checkAST :: ParseAST.SockeyeSpec -> IO AST.SockeyeSpec
+checkAST parsedAst = do
+    case checkSockeye parsedAst of 
+        Left fail -> do
+            hPutStr stderr $ show fail
+            exitWith checkError
+        Right intermAst -> return intermAst
+
+{- Builds the decoding net from the Sockeye AST -}
+buildNet :: AST.SockeyeSpec -> IO NetAST.NetSpec
+buildNet ast = do
+    case sockeyeBuildNet ast of 
+        Left fail -> do
+            hPutStr stderr $ show fail
+            exitWith buildError
+        Right netAst -> return netAst
 
 {- Compiles the AST with the appropriate backend -}
-compile :: Target -> AST.NetSpec -> IO String
+compile :: Target -> NetAST.NetSpec -> IO String
 compile None     _   = return ""
-compile PrintAST ast = return $ PrintAST.compile ast
 compile Prolog   ast = return $ Prolog.compile ast
 
 {- Outputs the compilation result -}
 output :: Maybe FilePath -> String -> IO ()
 output outFile out = do
-    case outFile of Nothing -> putStr out
-                    Just f  -> writeFile f out
+    case outFile of
+        Nothing -> putStr out
+        Just f  -> writeFile f out
 
 main = do
     args <- getArgs
     opts <- compilerOpts args
     let inFile = optInputFile opts
-    ast <- parseFile inFile
-    checkAST ast
-    out <- compile (optTarget opts) ast
+    parsedAst <- parseFile inFile
+    ast <- checkAST parsedAst
+    netAst <- buildNet ast
+    out <- compile (optTarget opts) netAst
     output (optOutputFile opts) out
     
\ No newline at end of file