Add check for duplicate identifiers
authorDaniel Schwyn <danielschwyn@gmail.com>
Thu, 11 May 2017 08:00:27 +0000 (10:00 +0200)
committerDaniel Schwyn <schwyda@student.ethz.ch>
Tue, 13 Jun 2017 12:20:33 +0000 (14:20 +0200)
Signed-off-by: Daniel Schwyn <schwyda@student.ethz.ch>

tools/sockeye2/Main.hs
tools/sockeye2/SockeyeChecker.hs [new file with mode: 0644]

index c7cfad5..246703e 100644 (file)
@@ -14,6 +14,7 @@
 module Main where
 
 import Control.Monad
+import Data.List
 import System.Console.GetOpt
 import System.Exit
 import System.Environment
@@ -21,6 +22,7 @@ import System.IO
 
 import SockeyeAST as AST
 import SockeyeParser
+import SockeyeChecker
 
 {- Possible options for the Sockeye Compiler -}
 data Options = Options { optInputFile :: FilePath }
@@ -66,10 +68,18 @@ parseFile file = do
         Left err -> hPutStrLn stderr ("Parse error at " ++ show err) >> exitWith (ExitFailure 2)
         Right ast -> return ast
 
+{- Runs the chekcer -}
+checkAst :: AST.NetSpec -> IO ()
+checkAst ast = do
+    case checkSockeye ast of 
+        [] -> return ()
+        errors -> hPutStrLn stderr (intercalate "\n" errors) >> exitWith (ExitFailure 2)
+
 main = do
     args <- getArgs
     opts <- compilerOpts args
     let inFile = optInputFile opts
     ast <- parseFile inFile
+    checkAst ast
     print ast
     
diff --git a/tools/sockeye2/SockeyeChecker.hs b/tools/sockeye2/SockeyeChecker.hs
new file mode 100644 (file)
index 0000000..aabb416
--- /dev/null
@@ -0,0 +1,37 @@
+{-
+  SockeyeChecker.hs: AST checker for Sockeye
+
+  Part of Sockeye
+
+  Copyright (c) 2017, ETH Zurich.
+
+  All rights reserved.
+
+  This file is distributed under the terms in the attached LICENSE file.
+  If you do not find this file, copies can be found by writing to:
+  ETH Zurich D-INFK, CAB F.78, Universitaetstr. 6, CH-8092 Zurich,
+  Attn: Systems Group.
+-}
+
+module SockeyeChecker
+( checkSockeye ) where
+
+import Control.Monad.Trans.Writer
+
+import Data.Set (Set)
+import qualified Data.Set as Set
+
+import qualified SockeyeAST as AST
+
+findUniqueIdentifiers :: AST.NetSpec -> Writer [String] (Set String)
+findUniqueIdentifiers ast = let allIds = map fst $ AST.getNodes ast
+                            in foldl checkAndAdd (return Set.empty) allIds
+                            where checkAndAdd w id = do
+                                    uids <- w
+                                    tell $ if id `Set.member` uids then ["Duplicate identifier " ++ show id] else []
+                                    return $ id `Set.insert` uids
+
+checkSockeye :: AST.NetSpec -> [String]
+checkSockeye ast = reverse $ snd $ runWriter $ do
+    ids <- findUniqueIdentifiers ast
+    return ids
\ No newline at end of file