Add check for duplicate identifiers
[barrelfish] / tools / sockeye2 / Main.hs
1 {-
2   SockeyeMain.hs: Sockeye
3
4   Copyright (c) 2017, ETH Zurich.
5
6   All rights reserved.
7
8   This file is distributed under the terms in the attached LICENSE file.
9   If you do not find this file, copies can be found by writing to:
10   ETH Zurich D-INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich,
11   Attn: Systems Group.
12 -}
13
14 module Main where
15
16 import Control.Monad
17 import Data.List
18 import System.Console.GetOpt
19 import System.Exit
20 import System.Environment
21 import System.IO
22
23 import SockeyeAST as AST
24 import SockeyeParser
25 import SockeyeChecker
26
27 {- Possible options for the Sockeye Compiler -}
28 data Options = Options { optInputFile :: FilePath }
29
30 {- Default options -}
31 defaultOptions :: Options
32 defaultOptions = Options { optInputFile = ""}
33
34 {- Set the input file name -}
35 optSetInputFileName :: FilePath -> Options -> Options
36 optSetInputFileName f o = o { optInputFile = f }
37
38 {- Prints usage information possibly with usage errors -}
39 usage :: [String] -> IO ()
40 usage errors = do
41     prg <- getProgName
42     let usageString = "Usage: " ++ prg ++ " [options] file\nOptions:"
43         in hPutStrLn stderr (usageInfo (concat errors ++ usageString) options)
44
45 {- Setup option parser -}
46 options :: [OptDescr (Options -> IO Options)]
47 options = 
48     [ Option "h" ["help"]
49         (NoArg (\_ -> do
50                     usage []
51                     exitWith ExitSuccess))
52         "Show help"
53     ]
54
55 {- evaluates the compiler options -}
56 compilerOpts :: [String] -> IO (Options)
57 compilerOpts argv =
58     case getOpt Permute options argv of
59         (actions, [f], []) -> liftM (optSetInputFileName f) $ foldl (>>=) (return defaultOptions) actions
60         (actions, [], [])  -> usage ["No input file\n"] >> exitWith (ExitFailure 1)
61         (_, _, errors)     -> usage errors >> exitWith (ExitFailure 1)
62
63 {- Runs the parser -}
64 parseFile :: FilePath -> IO (AST.NetSpec)
65 parseFile file = do
66     src <- readFile file
67     case parseSockeye file src of
68         Left err -> hPutStrLn stderr ("Parse error at " ++ show err) >> exitWith (ExitFailure 2)
69         Right ast -> return ast
70
71 {- Runs the chekcer -}
72 checkAst :: AST.NetSpec -> IO ()
73 checkAst ast = do
74     case checkSockeye ast of 
75         [] -> return ()
76         errors -> hPutStrLn stderr (intercalate "\n" errors) >> exitWith (ExitFailure 2)
77
78 main = do
79     args <- getArgs
80     opts <- compilerOpts args
81     let inFile = optInputFile opts
82     ast <- parseFile inFile
83     checkAst ast
84     print ast
85