Sockeye: Code cleanup
[barrelfish] / tools / sockeye / SockeyeInstantiator.hs
index 0e345b0..a5f2437 100644 (file)
@@ -1,5 +1,5 @@
 {-
-    SockeyeModuleInstantiator.hs: Module instantiator for Sockeye
+    SockeyeInstantiator.hs: Module instantiator for Sockeye
 
     Part of Sockeye
 
@@ -25,9 +25,7 @@ import Control.Monad.State
 import Data.List (intercalate)
 import Data.Map (Map)
 import qualified Data.Map as Map
-import Data.Maybe (fromMaybe, maybe)
-import Data.Set (Set)
-import qualified Data.Set as Set
+import Data.Maybe (catMaybes, fromMaybe)
 
 import Numeric (showHex)
 
@@ -36,9 +34,6 @@ import SockeyeChecks
 import qualified SockeyeASTTypeChecker as CheckAST
 import qualified SockeyeASTInstantiator as InstAST
 
-import Text.Groom (groom)
-import Debug.Trace
-
 data InstFail
     = ModuleInstLoop     [String]
     | DuplicateNamespace !String
@@ -47,21 +42,15 @@ data InstFail
     | DuplicateOutPort   !String
     | DuplicateInMap     !String !String
     | DuplicateOutMap    !String !String
-    | UndefinedOutPort   !String !String
-    | UndefinedInPort    !String !String
-    | UndefinedReference !String !String
 
 instance Show InstFail where
-    show (ModuleInstLoop     loop)       = concat ["Module instantiation loop: '", intercalate "' -> '" loop, "'"]
-    show (DuplicateInPort    port)       = concat ["Multiple declarations of input port '", port, "'"]
-    show (DuplicateOutPort   port)       = concat ["Multiple declarations of output port '", port, "'"]
-    show (DuplicateNamespace ident)      = concat ["Multiple usage of namespace '", ident, "'"]
-    show (DuplicateIdentifer ident)      = concat ["Multiple declarations of node '", ident, "'"]
-    show (DuplicateInMap   inst port)    = concat ["Multiple mappings for input port '",  port, "' in module instantiation '", inst, "'"]
-    show (DuplicateOutMap  inst port)    = concat ["Multiple mappings for output port '", port, "' in module instantiation '", inst, "'"]
-    show (UndefinedInPort  inst port)    = concat ["Mapping to undefined input port '",   port, "' in module instantiation '", inst, "'"]
-    show (UndefinedOutPort inst port)    = concat ["Mapping to undefined output port '",  port, "' in module instantiation '", inst, "'"]
-    show (UndefinedReference decl ident) = concat ["Reference to undefined node '", ident, "' in declaration of node '", decl, "'"]
+    show (ModuleInstLoop     loop)    = concat ["Module instantiation loop: '", intercalate "' -> '" loop, "'"]
+    show (DuplicateInPort    port)    = concat ["Multiple declarations of input port '", port, "'"]
+    show (DuplicateOutPort   port)    = concat ["Multiple declarations of output port '", port, "'"]
+    show (DuplicateNamespace ident)   = concat ["Multiple usage of namespace '", ident, "'"]
+    show (DuplicateIdentifer ident)   = concat ["Multiple declarations of node '", ident, "'"]
+    show (DuplicateInMap   inst port) = concat ["Multiple mappings for input port '",  port, "' in module instantiation '", inst, "'"]
+    show (DuplicateOutMap  inst port) = concat ["Multiple mappings for output port '", port, "' in module instantiation '", inst, "'"]
 
 type PortMapping = (InstAST.Identifier, InstAST.Identifier)
 
@@ -74,8 +63,7 @@ data Context = Context
 
 instantiateSockeye :: CheckAST.SockeyeSpec -> Either (FailedChecks InstFail) InstAST.SockeyeSpec
 instantiateSockeye ast = do
-    let emptySpec = CheckAST.SockeyeSpec 
-        context = Context
+    let context = Context
             { modules     = Map.empty
             , modulePath  = []
             , paramValues = Map.empty
@@ -105,8 +93,8 @@ instance Instantiatable CheckAST.SockeyeSpec InstAST.SockeyeSpec where
 instance Instantiatable CheckAST.Module InstAST.Module where
     instantiate context ast = do
         let ports = CheckAST.ports ast
-            nodeDecls = CheckAST.nodeDecls ast
             moduleInsts = CheckAST.moduleInsts ast
+            nodeDecls = CheckAST.nodeDecls ast
             modName = head $ modulePath context
         modules <- get
         if modName `Map.member` modules
@@ -114,27 +102,36 @@ instance Instantiatable CheckAST.Module InstAST.Module where
                 return $ modules Map.! modName
             else do
                 let sentinel = InstAST.Module
-                        { InstAST.ports       = []
+                        { InstAST.inputPorts  = []
+                        , InstAST.outputPorts = []
                         , InstAST.nodeDecls   = []
                         , InstAST.moduleInsts = []
                         }
                 modify $ Map.insert modName sentinel
-                instPorts <- do
+                (instInPorts, instOutPorts) <- do
                     instPorts <- instantiate context ports
-                    return $ concat (instPorts :: [[InstAST.Port]])
-                instDecls <- do
-                    decls <- instantiate context nodeDecls
-                    return $ concat (decls :: [[InstAST.NodeDecl]])
+                    let allPorts = concat (instPorts :: [[InstAST.Port]])
+                        inPorts = filter isInPort allPorts
+                        outPorts = filter isOutPort allPorts
+                    return (inPorts, outPorts)
                 instInsts <- do
                     insts <- instantiate context moduleInsts
                     return $ concat (insts :: [[InstAST.ModuleInst]])
-                lift $ checkDuplicates modName DuplicateInPort    $ (map InstAST.portId $ filter isInPort  instPorts)
-                lift $ checkDuplicates modName DuplicateOutPort   $ (map InstAST.portId $ filter isOutPort instPorts)
-                lift $ checkDuplicates modName DuplicateIdentifer $ (map InstAST.nodeId instDecls)
-                lift $ checkDuplicates modName DuplicateNamespace $ (map InstAST.namespace instInsts)
-                -- TODO: check duplicates with input/output ports
+                instDecls <- do
+                    decls <- instantiate context nodeDecls
+                    return $ concat (decls :: [[InstAST.NodeDecl]])
+                let
+                    inPortIds = map InstAST.portId instInPorts
+                    outPortIds = map InstAST.portId instOutPorts
+                    inMapNodeIds = concat $ map (Map.elems . InstAST.inPortMap) instInsts
+                    declNodeIds = map InstAST.nodeId instDecls
+                lift $ checkDuplicates modName DuplicateInPort  inPortIds
+                lift $ checkDuplicates modName DuplicateOutPort outPortIds
+                lift $ checkDuplicates modName DuplicateNamespace (catMaybes $ map InstAST.namespace instInsts)
+                lift $ checkDuplicates modName DuplicateIdentifer $ outPortIds ++ inMapNodeIds ++ declNodeIds
                 return InstAST.Module
-                    { InstAST.ports       = instPorts
+                    { InstAST.inputPorts  = instInPorts
+                    , InstAST.outputPorts = instOutPorts
                     , InstAST.nodeDecls   = instDecls
                     , InstAST.moduleInsts = instInsts
                     }
@@ -179,7 +176,7 @@ instance Instantiatable CheckAST.ModuleInst [InstAST.ModuleInst] where
             outPortMap = CheckAST.outPortMap ast
             modPath = modulePath context
             mod = getModule context name
-        instNs <- instantiate context namespace
+        instNs <- maybe (return Nothing) (\ns -> instantiate context ns >>= return . Just) namespace
         instInMap <- do
             inMaps <- instantiate context inPortMap
             return $ concat (inMaps :: [[PortMapping]])
@@ -194,8 +191,8 @@ instance Instantiatable CheckAST.ModuleInst [InstAST.ModuleInst] where
                     , varValues   = Map.empty
                     }
         lift $ checkSelfInst modPath instName
-        lift $ checkDuplicates name (DuplicateInMap  instName) $ map fst instInMap
-        lift $ checkDuplicates name (DuplicateOutMap instName) $ map fst instOutMap
+        lift $ checkDuplicates (head modPath) (DuplicateInMap  instName) $ map fst instInMap
+        lift $ checkDuplicates (head modPath) (DuplicateOutMap instName) $ map fst instOutMap
         let instantiated = InstAST.ModuleInst
                 { InstAST.moduleName = instName
                 , InstAST.namespace  = instNs
@@ -256,7 +253,7 @@ instance Instantiatable CheckAST.NodeDecl [InstAST.NodeDecl] where
         return $ [instDecl]
 
 instance Instantiatable CheckAST.Identifier InstAST.Identifier where
-    instantiate context (CheckAST.SimpleIdent name) = do
+    instantiate _ (CheckAST.SimpleIdent name) = do
         return name
     instantiate context ast = do
         let prefix = CheckAST.prefix ast
@@ -318,7 +315,7 @@ instance Instantiatable CheckAST.MapSpec InstAST.MapSpec where
     instantiate context ast = do
         let block = CheckAST.block ast
             destNode = CheckAST.destNode ast
-            destBase = fromMaybe (CheckAST.base block) (CheckAST.destBase ast)
+            destBase = fromMaybe (CheckAST.LiteralAddress 0) (CheckAST.destBase ast)
         instBlock <- instantiate context block
         instDestNode <- instantiate context destNode
         instDestBase <- instantiate context destBase
@@ -378,7 +375,9 @@ instance Instantiatable CheckAST.ForLimit Integer where
 instance (Traversable t, Instantiatable a b) => Instantiatable (t a) (t b) where
     instantiate context ast = mapM (instantiate context) ast
 
-
+---
+--- Helpers
+---
 getModule :: Context -> String -> CheckAST.Module
 getModule context name = (modules context) Map.! name