Sockeye: Start reimplementing net builder on top of instantiator
authorDaniel Schwyn <schwyda@student.ethz.ch>
Fri, 28 Jul 2017 16:00:43 +0000 (18:00 +0200)
committerDaniel Schwyn <schwyda@student.ethz.ch>
Fri, 28 Jul 2017 16:00:43 +0000 (18:00 +0200)
Signed-off-by: Daniel Schwyn <schwyda@student.ethz.ch>

tools/sockeye/Main.hs
tools/sockeye/SockeyeAST.hs
tools/sockeye/SockeyeASTDecodingNet.hs
tools/sockeye/SockeyeASTInstantiator.hs
tools/sockeye/SockeyeBackendProlog.hs
tools/sockeye/SockeyeInstantiator.hs
tools/sockeye/SockeyeNetBuilder.hs

index dbd7b24..6a29119 100644 (file)
@@ -225,7 +225,7 @@ instanitateModules ast = do
         Right simpleAST -> return simpleAST
 
 {- Builds the decoding net from the Sockeye AST -}
-buildNet :: AST.SockeyeSpec -> IO NetAST.NetSpec
+buildNet :: InstAST.SockeyeSpec -> IO NetAST.NetSpec
 buildNet ast = do
     case sockeyeBuildNet ast of 
         Left fail -> do
@@ -264,9 +264,10 @@ main = do
             out <- dependencyFile outFile f deps
             output f out
     ast <- checkAST parsedAst
-    instAST <- instanitateModules ast
-    putStrLn $ groom instAST
-    netAst <- buildNet ast
+    instAst <- instanitateModules ast
+    -- putStrLn $ groom instAST
+    netAst <- buildNet instAst
+    putStrLn $ groom netAst
     out <- compile (optTarget opts) netAst
     output outFile out
     
\ No newline at end of file
index 4856eb2..323f8d7 100644 (file)
   Attn: Systems Group.
 -}
 
-module SockeyeAST where
+module SockeyeAST 
+ ( module SockeyeAST
+ , module SockeyeASTInstantiator
+ ) where
 
 import Data.Map (Map)
 
+import SockeyeASTInstantiator
+    ( NodeType(Other, Device, Memory) )
+
 newtype SockeyeSpec = SockeyeSpec
     { modules :: Map String Module }
     deriving (Show)
@@ -102,12 +108,6 @@ data NodeSpec = NodeSpec
     , overlay   :: Maybe OverlaySpec
     } deriving (Show)
 
-data NodeType
-    = Memory
-    | Device
-    | Other
-    deriving (Show)
-
 data BlockSpec 
     = SingletonBlock
         { base :: Address }
index e3aadcf..eb0ab90 100644 (file)
@@ -18,28 +18,15 @@ module SockeyeASTDecodingNet where
 import Data.List (intercalate)
 import Data.Map (Map)
 
-newtype NetSpec =
-    NetSpec
-        { net :: Map NodeId NodeSpec }
-    deriving (Show)
+type NetSpec = Map NodeId NodeSpec
 
 data NodeId = NodeId
-    { namespace :: Namespace
+    { namespace :: [String]
     , name      :: !String
     } deriving (Eq, Ord)
 
 instance Show NodeId where
-    show (NodeId namespace name) = 
-        case ns namespace of
-            [] -> name
-            _  -> concat [show namespace, ".", name]
-
-newtype Namespace = Namespace
-    { ns :: [String] }
-    deriving (Eq, Ord)
-
-instance Show Namespace where
-    show (Namespace ns) = intercalate "." $ reverse ns
+    show (NodeId ns n) = intercalate "." $ reverse (n:ns)
 
 data NodeSpec
     = NodeSpec
@@ -66,7 +53,4 @@ data MapSpec = MapSpec
     , destBase :: Address
     } deriving (Show)
 
-newtype Address =
-    Address
-        { address :: Integer }
-    deriving (Show)
+type Address = Integer
index 1b2954a..46debd5 100644 (file)
 
 module SockeyeASTInstantiator
     ( module SockeyeASTInstantiator
-    , module SockeyeAST
+    , module SockeyeASTDecodingNet
     ) where
 
 import Data.Map (Map)
 
-import SockeyeAST
-    ( NodeType(Other, Memory, Device) )
+import SockeyeASTDecodingNet
+    ( NodeType(Other, Memory, Device)
+    , BlockSpec(BlockSpec)
+    , base, limit
+    , Address
+    )
 
 data SockeyeSpec = SockeyeSpec
     { root :: ModuleInst
@@ -29,19 +33,27 @@ data SockeyeSpec = SockeyeSpec
     } deriving (Show)
 
 data Module = Module
-    { inputPorts   :: Map String Integer
-    , outputPorts  :: Map String Integer
-    , nodeDecls    :: Map String NodeSpec
-    , moduleInsts  :: Map String ModuleInst
+    { inputPorts   :: PortMap
+    , outputPorts  :: PortMap
+    , moduleInsts  :: ModuleInstMap
+    , nodeDecls    :: NodeDeclMap
     } deriving (Show)
 
+type PortMap = Map Identifier Integer
+type ModuleInstMap = Map String ModuleInst
+type NodeDeclMap = Map Identifier NodeSpec
+
 data ModuleInst
     = ModuleInst
-        { moduleName :: String
-        , inPortMap  :: Map String String
-        , outPortMap :: Map String String
+        { moduleName :: Identifier
+        , inPortMap  :: PortMappingMap
+        , outPortMap :: PortMappingMap
         } deriving (Show)
 
+type PortMappingMap = Map Identifier Identifier
+
+type Identifier = String
+
 data NodeSpec = NodeSpec
     { nodeType  :: NodeType
     , accept    :: [BlockSpec]
@@ -50,22 +62,16 @@ data NodeSpec = NodeSpec
     , overlay   :: Maybe OverlaySpec
     } deriving (Show)
 
-data BlockSpec 
-    = BlockSpec
-        { base  :: !Integer
-        , limit :: !Integer
-        } deriving (Show)
-
 data MapSpec 
     = MapSpec
-        { block    :: BlockSpec
-        , destNode :: !String
-        , destBase :: !Integer
+        { srcBlock :: BlockSpec
+        , destNode :: !Identifier
+        , destBase :: !Address
         } deriving (Show)
 
 data OverlaySpec
     = OverlaySpec
-        { over  :: !String
+        { over  :: !Identifier
         , width :: !Integer
         } deriving (Show)
 
index d819d38..4be1bcb 100644 (file)
@@ -13,6 +13,9 @@
   Attn: Systems Group.
 -}
 
+{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE FlexibleInstances #-}
+
 module SockeyeBackendProlog
 ( compile ) where
 
@@ -31,7 +34,7 @@ class PrologGenerator a where
     generate :: a -> String
 
 instance PrologGenerator AST.NetSpec where
-    generate (AST.NetSpec net) = let
+    generate net = let
         mapped = Map.mapWithKey toFact net
         facts = Map.elems mapped
         in unlines facts
@@ -45,12 +48,7 @@ instance PrologGenerator AST.NodeId where
     generate ast = let
         name = AST.name ast
         namespace = AST.namespace ast
-        in predicate "nodeId" [atom name, generate namespace]
-
-instance PrologGenerator AST.Namespace where
-    generate ast = let
-        ns = AST.ns ast
-        in list $ map atom ns
+        in predicate "nodeId" [atom name, list $ map atom namespace]
 
 instance PrologGenerator AST.NodeSpec where
     generate ast = let
@@ -78,7 +76,7 @@ instance PrologGenerator AST.NodeType where
     generate AST.Other  = atom "other"
 
 instance PrologGenerator AST.Address where
-    generate (AST.Address addr) = "16'" ++ showHex addr ""
+    generate addr = "16'" ++ showHex addr ""
 
 instance PrologGenerator a => PrologGenerator [a] where
     generate ast = let
index c69d86d..8602bde 100644 (file)
@@ -63,6 +63,11 @@ instance Show InstFails where
     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, "'"]
 
+type Port = (InstAST.Identifier, Integer)
+type NodeDecl = (InstAST.Identifier, InstAST.NodeSpec)
+type ModuleInst = (InstAST.Identifier, InstAST.ModuleInst)
+type PortMapping = (InstAST.Identifier, InstAST.Identifier)
+
 data Context = Context
     { spec        :: AST.SockeyeSpec
     , modulePath  :: [String]
@@ -129,16 +134,16 @@ instance Instantiatable AST.Module InstAST.Module where
                 modify $ Map.insert modName sentinel
                 instInPorts <- do
                     instPorts <- instantiate context inPorts
-                    return $ concat (instPorts :: [[(String, Integer)]])
+                    return $ concat (instPorts :: [[Port]])
                 instOutPorts <- do
                     instPorts <- instantiate context outPorts
-                    return $ concat (instPorts :: [[(String, Integer)]])
+                    return $ concat (instPorts :: [[Port]])
                 instDecls <- do
                     decls <- instantiate context nodeDecls
-                    return $ concat (decls :: [[(String, InstAST.NodeSpec)]])
+                    return $ concat (decls :: [[NodeDecl]])
                 instInsts <- do
                     insts <- instantiate context moduleInsts
-                    return $ concat (insts :: [[(String, InstAST.ModuleInst)]])
+                    return $ concat (insts :: [[ModuleInst]])
                 lift $ checkDuplicates modName DuplicateInPort    $ (map fst instInPorts)
                 lift $ checkDuplicates modName DuplicateOutPort   $ (map fst instOutPorts)
                 lift $ checkDuplicates modName DuplicateIdentifer $ (map fst instDecls)
@@ -150,10 +155,10 @@ instance Instantiatable AST.Module InstAST.Module where
                     , InstAST.moduleInsts  = Map.fromList instInsts
                     }
 
-instance Instantiatable AST.Port [(String, Integer)] where
+instance Instantiatable AST.Port [Port] where
     instantiate context (AST.MultiPort for) = do
         instFor <- instantiate context for
-        return $ concat (instFor :: [[(String, Integer)]])
+        return $ concat (instFor :: [[Port]])
     instantiate context ast = do
         let
             ident = AST.portId ast
@@ -161,10 +166,10 @@ instance Instantiatable AST.Port [(String, Integer)] where
         instIdent <- instantiate context ident
         return [(instIdent, width)]
 
-instance Instantiatable AST.ModuleInst [(String, InstAST.ModuleInst)] where
+instance Instantiatable AST.ModuleInst [ModuleInst] where
     instantiate context (AST.MultiModuleInst for) = do 
         simpleFor <- instantiate context for
-        return $ concat (simpleFor :: [[(String, InstAST.ModuleInst)]])
+        return $ concat (simpleFor :: [[ModuleInst]])
     instantiate context ast = do
         let
             namespace = AST.namespace ast
@@ -177,10 +182,10 @@ instance Instantiatable AST.ModuleInst [(String, InstAST.ModuleInst)] where
         instNs <- instantiate context namespace
         instInMap <- do
             inMaps <- instantiate context inPortMap
-            return $ concat (inMaps :: [[(String, String)]])
+            return $ concat (inMaps :: [[PortMapping]])
         instOutMap <- do
             outMaps <- instantiate context outPortMap
-            return $ concat (outMaps :: [[(String, String)]])
+            return $ concat (outMaps :: [[PortMapping]])
         instArgs <- instantiate context args
         let
             instName = concat [name, "(", intercalate ", " $ argStrings instArgs mod, ")"]
@@ -226,10 +231,10 @@ instance Instantiatable AST.ModuleArg Integer where
     instantiate _ (AST.NaturalArg v) = return v
     instantiate context (AST.ParamArg name) = return $ getParamValue context name
 
-instance Instantiatable AST.PortMap [(String, String)] where
+instance Instantiatable AST.PortMap [PortMapping] where
     instantiate context (AST.MultiPortMap for) = do
         instFor <- instantiate context for
-        return $ concat (instFor :: [[(String, String)]])
+        return $ concat (instFor :: [[PortMapping]])
     instantiate context ast = do
         let
             mappedId = AST.mappedId ast
@@ -238,10 +243,10 @@ instance Instantiatable AST.PortMap [(String, String)] where
         instPort <- instantiate context mappedPort
         return [(instPort, instId)]
 
-instance Instantiatable AST.NodeDecl [(String, InstAST.NodeSpec)] where
+instance Instantiatable AST.NodeDecl [NodeDecl] where
     instantiate context (AST.MultiNodeDecl for) = do
         instFor <- instantiate context for
-        return $ concat (instFor :: [[(String, InstAST.NodeSpec)]])
+        return $ concat (instFor :: [[NodeDecl]])
     instantiate context ast = do
         let
             nodeId = AST.nodeId ast
@@ -250,7 +255,7 @@ instance Instantiatable AST.NodeDecl [(String, InstAST.NodeSpec)] where
         instNodeSpec <- instantiate context nodeSpec
         return [(instNodeId, instNodeSpec)]
 
-instance Instantiatable AST.Identifier String where
+instance Instantiatable AST.Identifier InstAST.Identifier where
     instantiate context (AST.SimpleIdent name) = do
         return name
     instantiate context ast = do
@@ -322,7 +327,7 @@ instance Instantiatable AST.MapSpec InstAST.MapSpec where
         instDestNode <- instantiate context destNode
         instDestBase <- instantiate context destBase
         return InstAST.MapSpec
-            { InstAST.block    = instBlock
+            { InstAST.srcBlock    = instBlock
             , InstAST.destNode = instDestNode
             , InstAST.destBase = instDestBase
             }
@@ -338,7 +343,7 @@ instance Instantiatable AST.OverlaySpec InstAST.OverlaySpec where
             , InstAST.width = width
             }
 
-instance Instantiatable AST.Address Integer where
+instance Instantiatable AST.Address InstAST.Address where
     instantiate context (AST.ParamAddress name) = do
         let value = getParamValue context name
         return value
index fe76bb2..b0f5e33 100644 (file)
@@ -30,352 +30,232 @@ import Data.Maybe (fromMaybe)
 import Data.Set (Set)
 import qualified Data.Set as Set
 
-import qualified SockeyeAST as AST
+import SockeyeChecks
+
+import qualified SockeyeASTInstantiator as InstAST
 import qualified SockeyeASTDecodingNet as NetAST
 
-type NetNodeDecl = (NetAST.NodeId, NetAST.NodeSpec)
-type NetList = [NetNodeDecl]
-type PortMap = [(String, NetAST.NodeId)]
-
-data FailedCheck
-    = ModuleInstLoop [String]
-    | DuplicateInPort !String !String
-    | DuplicateInMap !String !String
-    | UndefinedInPort !String !String
-    | DuplicateOutPort !String !String
-    | DuplicateOutMap !String !String
-    | UndefinedOutPort !String !String
-    | DuplicateIdentifer !String
-    | UndefinedReference !String
-
-instance Show FailedCheck where
-    show (ModuleInstLoop loop) = concat ["Module instantiation loop:'", intercalate "' -> '" loop, "'"]
-    show (DuplicateInPort  modName port) = concat ["Multiple declarations of input port '", port, "' in '", modName, "'"]
-    show (DuplicateInMap   ns      port) = concat ["Multiple mappings for input port '", port, "' in '", ns, "'"]
-    show (UndefinedInPort  modName port) = concat ["'", port, "' is not an input port in '", modName, "'"]
-    show (DuplicateOutPort modName port) = concat ["Multiple declarations of output port '", port, "' in '", modName, "'"]
-    show (DuplicateOutMap   ns      port) = concat ["Multiple mappings for output port '", port, "' in '", ns, "'"]
-    show (UndefinedOutPort modName port) = concat ["'", port, "' is not an output port in '", modName, "'"]
-    show (DuplicateIdentifer ident)   = concat ["Multiple declarations of node '", show ident, "'"]
-    show (UndefinedReference ident)   = concat ["Reference to undefined node '", show ident, "'"]
-
-newtype CheckFailure = CheckFailure
-    { failures :: [FailedCheck] }
-
-instance Show CheckFailure where
-    show (CheckFailure fs) = unlines $ "":(map show fs)
+import Debug.Trace
+
+data NetBuildFails
+    = UndefinedOutPort   !String !String
+    | UndefinedInPort    !String !String
+    | UndefinedReference !String !String
+
+instance Show NetBuildFails where
+    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, "'"]
 
 data Context = Context
-    { spec         :: AST.SockeyeSpec
-    , modulePath   :: [String]
-    , curNamespace :: NetAST.Namespace
-    , paramValues  :: Map String Integer
-    , varValues    :: Map String Integer
-    , inPortMaps   :: Map String NetAST.NodeId
-    , outPortMaps  :: Map String NetAST.NodeId
-    , mappedBlocks :: [NetAST.BlockSpec]
+    { modules      :: Map String InstAST.Module
+    , curNamespace :: [String]
+    -- , inPortMaps   :: Map String NetAST.NodeId
+    -- , outPortMaps  :: Map String NetAST.NodeId
+    , mappedBlocks :: [InstAST.BlockSpec]
     }
 
-sockeyeBuildNet :: AST.SockeyeSpec -> Either CheckFailure NetAST.NetSpec
+sockeyeBuildNet :: InstAST.SockeyeSpec -> Either (FailedChecks NetBuildFails) NetAST.NetSpec
 sockeyeBuildNet ast = do
     let
         context = Context
-            { spec         = AST.SockeyeSpec Map.empty
-            , modulePath   = []
-            , curNamespace = NetAST.Namespace []
-            , paramValues  = Map.empty
-            , varValues    = Map.empty
-            , inPortMaps   = Map.empty
-            , outPortMaps  = Map.empty
+            { modules      = Map.empty
+            , curNamespace = []
+            -- , inPortMaps   = Map.empty
+            -- , outPortMaps  = Map.empty
             , mappedBlocks = []
             }        
-    net <- transform context ast
-    check Set.empty net
+    net <- runChecks $ transform context ast
+    -- check Set.empty net
     return net
 --            
 -- Build net
 --
 class NetTransformable a b where
-    transform :: Context -> a -> Either CheckFailure b
+    transform :: Context -> a -> Checks NetBuildFails b
 
-instance NetTransformable AST.SockeyeSpec NetAST.NetSpec where
+instance NetTransformable InstAST.SockeyeSpec NetAST.NetSpec where
     transform context ast = do
         let
-            rootInst = AST.ModuleInst
-                { AST.namespace  = AST.SimpleIdent ""
-                , AST.moduleName = "@root"
-                , AST.arguments  = Map.empty
-                , AST.inPortMap  = []
-                , AST.outPortMap = []
-                }
+            rootInst = InstAST.root ast
+            mods = InstAST.modules ast
             specContext = context
-                { spec = ast }
-        netList <- transform specContext rootInst
-        let
-            nodeIds = map fst netList
-        checkDuplicates nodeIds DuplicateIdentifer
-        let
-            nodeMap = Map.fromList netList
-        return $ NetAST.NetSpec nodeMap
+                { modules = mods }
+        transform specContext rootInst
 
-instance NetTransformable AST.Module NetList where
+instance NetTransformable InstAST.Module NetAST.NetSpec where
     transform context ast = do
-        let
-            inPorts = AST.inputPorts ast
-            outPorts = AST.outputPorts ast
-            nodeDecls = AST.nodeDecls ast
-            moduleInsts = AST.moduleInsts ast
-        inDecls <- do
-            net <- transform context inPorts
-            return $ concat (net :: [NetList])
-        outDecls <- do
-            net <- transform context outPorts
-            return $ concat (net :: [NetList])
-        -- TODO check duplicate ports
+        let inPorts = InstAST.inputPorts ast
+            outPorts = InstAST.outputPorts ast
+            nodeDecls = InstAST.nodeDecls ast
+            moduleInsts = InstAST.moduleInsts ast
+        -- inDecls <- transform context inPorts
+        -- outDecls <- transform context outPorts
         -- TODO check mappings to non existing port
         netDecls <- transform context nodeDecls
         netInsts <- transform context moduleInsts
-        return $ concat (inDecls:outDecls:netDecls ++ netInsts)            
-
-instance NetTransformable AST.Port NetList where
-    transform context (AST.MultiPort for) = do
-        netPorts <- transform context for
-        return $ concat (netPorts :: [NetList])
-    transform context (AST.InputPort portId portWidth) = do
-        netPortId <- transform context portId
-        let
-            portMap = inPortMaps context
-            name = NetAST.name netPortId
-            mappedId = Map.lookup name portMap
-        case mappedId of
-            Nothing    -> return []
-            Just ident -> do
-                let
-                    node = portNode netPortId portWidth
-                return [(ident, node)]
-    transform context (AST.OutputPort portId portWidth) = do
-        netPortId <- transform context portId
-        let
-            portMap = outPortMaps context
-            name = NetAST.name netPortId
-            mappedId = Map.lookup name portMap
-        case mappedId of
-            Nothing    -> return [(netPortId, portNodeTemplate)]
-            Just ident -> do
-                let
-                    node = portNode ident portWidth
-                return [(netPortId, node)]
-
-portNode :: NetAST.NodeId -> Integer -> NetAST.NodeSpec
-portNode destNode width =
-    let
-        base = NetAST.Address 0
-        limit = NetAST.Address $ 2^width - 1
-        srcBlock = NetAST.BlockSpec
-            { NetAST.base  = base
-            , NetAST.limit = limit
-            }
-        map = NetAST.MapSpec
-                { NetAST.srcBlock = srcBlock
-                , NetAST.destNode = destNode
-                , NetAST.destBase = base
-                }
-    in portNodeTemplate { NetAST.translate = [map] }
-
-portNodeTemplate :: NetAST.NodeSpec
-portNodeTemplate = NetAST.NodeSpec
-    { NetAST.nodeType  = NetAST.Other
-    , NetAST.accept    = []
-    , NetAST.translate = []
-    }    
-
-instance NetTransformable AST.ModuleInst NetList where
-    transform context (AST.MultiModuleInst for) = do
-        net <- transform context for
-        return $ concat (net :: [NetList])
-    transform context ast = do
-        let
-            namespace = AST.namespace ast
-            name = AST.moduleName ast
-            args = AST.arguments ast
-            inPortMap = AST.inPortMap ast
-            outPortMap = AST.outPortMap ast
-            mod = getModule context name
-        checkSelfInst name
-        netNamespace <- transform context namespace
-        netArgs <- transform context args
-        netInMap <- transform context inPortMap
-        netOutMap <- transform context outPortMap
-        let
-            inMaps = concat (netInMap :: [PortMap])
-            outMaps = concat (netOutMap :: [PortMap])
-        checkDuplicates (map fst inMaps) (DuplicateInMap $ show netNamespace) 
-        checkDuplicates (map fst outMaps) (DuplicateOutMap $ show netNamespace)
-        let
-            modContext = moduleContext name netNamespace netArgs inMaps outMaps
-        transform modContext mod
+        -- return $ concat (inDecls:outDecls:netDecls ++ netInsts)            
+        return $ Map.unions [netDecls, netInsts]
+
+-- instance NetTransformable InstAST.Port NetList where
+--     transform context (AST.MultiPort for) = do
+--         netPorts <- transform context for
+--         return $ concat (netPorts :: [NetList])
+--     transform context (AST.InputPort portId portWidth) = do
+--         netPortId <- transform context portId
+--         let
+--             portMap = inPortMaps context
+--             name = NetAST.name netPortId
+--             mappedId = Map.lookup name portMap
+--         case mappedId of
+--             Nothing    -> return []
+--             Just ident -> do
+--                 let
+--                     node = portNode netPortId portWidth
+--                 return [(ident, node)]
+--     transform context (AST.OutputPort portId portWidth) = do
+--         netPortId <- transform context portId
+--         let
+--             portMap = outPortMaps context
+--             name = NetAST.name netPortId
+--             mappedId = Map.lookup name portMap
+--         case mappedId of
+--             Nothing    -> return [(netPortId, portNodeTemplate)]
+--             Just ident -> do
+--                 let
+--                     node = portNode ident portWidth
+--                 return [(netPortId, node)]
+
+-- portNode :: NetAST.NodeId -> Integer -> NetAST.NodeSpec
+-- portNode destNode width =
+--     let
+--         base = NetAST.Address 0
+--         limit = NetAST.Address $ 2^width - 1
+--         srcBlock = NetAST.BlockSpec
+--             { NetAST.base  = base
+--             , NetAST.limit = limit
+--             }
+--         map = NetAST.MapSpec
+--                 { NetAST.srcBlock = srcBlock
+--                 , NetAST.destNode = destNode
+--                 , NetAST.destBase = base
+--                 }
+--     in portNodeTemplate { NetAST.translate = [map] }
+
+-- portNodeTemplate :: NetAST.NodeSpec
+-- portNodeTemplate = NetAST.NodeSpec
+--     { NetAST.nodeType  = NetAST.Other
+--     , NetAST.accept    = []
+--     , NetAST.translate = []
+--     }
+
+instance NetTransformable InstAST.ModuleInstMap NetAST.NetSpec where
+        transform context ast = do
+            let namespaces = Map.keys ast
+                modInsts = Map.elems ast
+            let
+                contexts = map addNamespace namespaces
+            netModInsts <- mapM (uncurry transform) $ zip contexts modInsts
+            return $ Map.unions netModInsts
             where
-                moduleContext name namespace args inMaps outMaps =
-                    let
-                        path = modulePath context
-                        base = NetAST.ns $ NetAST.namespace namespace
-                        newNs = case NetAST.name namespace of
-                            "" -> NetAST.Namespace base
-                            n  -> NetAST.Namespace $ n:base
+                addNamespace n =
+                    let ns = curNamespace context
                     in context
-                        { modulePath   = name:path
-                        , curNamespace = newNs
-                        , paramValues  = args
-                        , varValues    = Map.empty
-                        , inPortMaps   = Map.fromList inMaps
-                        , outPortMaps  = Map.fromList outMaps
-                        }
-                checkSelfInst name = do
-                    let
-                        path = modulePath context
-                    case loop path of
-                        [] -> return ()
-                        l  -> Left $ CheckFailure [ModuleInstLoop (reverse $ name:l)]
-                        where
-                            loop [] = []
-                            loop path@(p:ps)
-                                | name `elem` path = p:(loop ps)
-                                | otherwise = []
-
-
-instance NetTransformable AST.PortMap PortMap where
-    transform context (AST.MultiPortMap for) = do
-        ts <- transform context for
-        return $ concat (ts :: [PortMap])
+                        { curNamespace = n:ns }
+
+
+instance NetTransformable InstAST.ModuleInst NetAST.NetSpec where
+    transform context ast = do
+        let name = InstAST.moduleName ast
+            inPortMap = InstAST.inPortMap ast
+            outPortMap = InstAST.outPortMap ast
+            mod = getModule context name
+        -- netInMap <- transform context inPortMap
+        -- netOutMap <- transform context outPortMap
+        transform context mod
+
+-- instance NetTransformable AST.PortMap PortMap where
+--     transform context (AST.MultiPortMap for) = do
+--         ts <- transform context for
+--         return $ concat (ts :: [PortMap])
+--     transform context ast = do
+--         let
+--             mappedId = AST.mappedId ast
+--             mappedPort = AST.mappedPort ast
+--         netMappedId <- transform context mappedId
+--         netMappedPort <- transform context mappedPort
+--         return [(NetAST.name netMappedPort, netMappedId)]
+
+-- instance NetTransformable AST.ModuleArg Integer where
+--     transform _ (AST.AddressArg value) = return value
+--     transform _ (AST.NaturalArg value) = return value
+--     transform context (AST.ParamArg name) = return $ getParamValue context name
+
+instance NetTransformable InstAST.NodeDeclMap NetAST.NetSpec where
     transform context ast = do
         let
-            mappedId = AST.mappedId ast
-            mappedPort = AST.mappedPort ast
-        netMappedId <- transform context mappedId
-        netMappedPort <- transform context mappedPort
-        return [(NetAST.name netMappedPort, netMappedId)]
-
-instance NetTransformable AST.ModuleArg Integer where
-    transform _ (AST.AddressArg value) = return value
-    transform _ (AST.NaturalArg value) = return value
-    transform context (AST.ParamArg name) = return $ getParamValue context name
-
-instance NetTransformable AST.Identifier NetAST.NodeId where
+            idents = Map.keys ast
+            nodeSpecs = Map.elems ast
+        netNodeIds <- transform context idents
+        netNodeSpec <- transform context nodeSpecs
+        return $ Map.fromList (zip netNodeIds netNodeSpec)
+
+instance NetTransformable InstAST.Identifier NetAST.NodeId where
     transform context ast = do
         let
             namespace = curNamespace context
-            name = identName ast
         return NetAST.NodeId
             { NetAST.namespace = namespace
-            , NetAST.name      = name
+            , NetAST.name      = ast
             }
-            where
-                identName (AST.SimpleIdent name) = name
-                identName ident =
-                    let
-                        prefix = AST.prefix ident
-                        varName = AST.varName ident
-                        suffix = AST.suffix ident
-                        varValue = show $ getVarValue context varName
-                        suffixName = case suffix of
-                            Nothing -> ""
-                            Just s  -> identName s
-                    in prefix ++ varValue ++ suffixName
-
-instance NetTransformable AST.NodeDecl NetList where
-    transform context (AST.MultiNodeDecl for) = do
-        ts <- transform context for
-        return $ concat (ts :: [NetList])
-    transform context ast = do
-        let
-            ident = AST.nodeId ast
-            nodeSpec = AST.nodeSpec ast
-        nodeId <- transform context ident
-        netNodeSpec <- transform context nodeSpec
-        return [(nodeId, netNodeSpec)]
 
-instance NetTransformable AST.NodeSpec NetAST.NodeSpec where
+instance NetTransformable InstAST.NodeSpec NetAST.NodeSpec where
     transform context ast = do
         let
-            nodeType = AST.nodeType ast
-            accept = AST.accept ast
-            translate = AST.translate ast
-            reserved = AST.reserved ast
-            overlay = AST.overlay ast
-        netNodeType <- transform context nodeType
-        netAccept <- transform context accept
+            nodeType = InstAST.nodeType ast
+            accept = InstAST.accept ast
+            translate = InstAST.translate ast
+            reserved = InstAST.reserved ast
+            overlay = InstAST.overlay ast
         netTranslate <- transform context translate
-        netReserved <- transform context reserved
         let
             mapBlocks = map NetAST.srcBlock netTranslate
             nodeContext = context
-                { mappedBlocks = netAccept ++ mapBlocks ++ netReserved }
+                { mappedBlocks = accept ++ mapBlocks ++ reserved }
         netOverlay <- case overlay of
                 Nothing -> return []
                 Just o  -> transform nodeContext o
         return NetAST.NodeSpec
-            { NetAST.nodeType  = netNodeType
-            , NetAST.accept    = netAccept
+            { NetAST.nodeType  = nodeType
+            , NetAST.accept    = accept
             , NetAST.translate = netTranslate ++ netOverlay
             }
 
-instance NetTransformable AST.NodeType NetAST.NodeType where
-    transform _ AST.Memory = return NetAST.Memory
-    transform _ AST.Device = return NetAST.Device
-    transform _ AST.Other  = return NetAST.Other
-
-instance NetTransformable AST.BlockSpec NetAST.BlockSpec where
-    transform context (AST.SingletonBlock address) = do
-        netAddress <- transform context address
-        return NetAST.BlockSpec
-            { NetAST.base  = netAddress
-            , NetAST.limit = netAddress
-            }
-    transform context (AST.RangeBlock base limit) = do
-        netBase <- transform context base
-        netLimit <- transform context limit
-        return NetAST.BlockSpec
-            { NetAST.base  = netBase
-            , NetAST.limit = netLimit
-            }
-    transform context (AST.LengthBlock base bits) = do
-        netBase <- transform context base
-        let
-            baseAddress = NetAST.address netBase
-            limit = baseAddress + 2^bits - 1
-            netLimit = NetAST.Address limit
-        return NetAST.BlockSpec
-            { NetAST.base  = netBase
-            , NetAST.limit = netLimit
-            }
-
-instance NetTransformable AST.MapSpec NetAST.MapSpec where
+instance NetTransformable InstAST.MapSpec NetAST.MapSpec where
     transform context ast = do
         let
-            block = AST.block ast
-            destNode = AST.destNode ast
-            destBase = fromMaybe (AST.LiteralAddress 0) (AST.destBase ast)
-        netBlock <- transform context block
+            srcBlock = InstAST.srcBlock ast
+            destNode = InstAST.destNode ast
+            destBase = InstAST.destBase ast
         netDestNode <- transform context destNode
-        netDestBase <- transform context destBase
         return NetAST.MapSpec
-            { NetAST.srcBlock = netBlock
+            { NetAST.srcBlock = srcBlock
             , NetAST.destNode = netDestNode
-            , NetAST.destBase = netDestBase
+            , NetAST.destBase = destBase
             }
 
-instance NetTransformable AST.OverlaySpec [NetAST.MapSpec] where
+instance NetTransformable InstAST.OverlaySpec [NetAST.MapSpec] where
     transform context ast = do
         let
-            over = AST.over ast
-            width = AST.width ast
+            over = InstAST.over ast
+            width = InstAST.width ast
             blocks = mappedBlocks context
         netOver <- transform context over
         let
             maps = overlayMaps netOver width blocks
         return maps
 
-overlayMaps :: NetAST.NodeId -> Integer ->[NetAST.BlockSpec] -> [NetAST.MapSpec]
+overlayMaps :: NetAST.NodeId -> Integer -> [NetAST.BlockSpec] -> [NetAST.MapSpec]
 overlayMaps destId width blocks =
     let
         blockPoints = concat $ map toScanPoints blocks
@@ -389,8 +269,8 @@ overlayMaps destId width blocks =
     in evalState (scanLine scanPoints []) startState
     where
         toScanPoints (NetAST.BlockSpec base limit) =
-                [ BlockStart $ NetAST.address base
-                , BlockEnd   $ NetAST.address limit
+                [ BlockStart base
+                , BlockEnd   limit
                 ]
         scanLine [] ms = return ms
         scanLine (p:ps) ms = do
@@ -405,8 +285,8 @@ overlayMaps destId width blocks =
             maps <- if (i == 0) && (base <= limit)
                 then
                     let
-                        baseAddress = NetAST.Address $ startAddress s
-                        limitAddress = NetAST.Address $ a - 1
+                        baseAddress = startAddress s
+                        limitAddress = a - 1
                         srcBlock = NetAST.BlockSpec baseAddress limitAddress
                         m = NetAST.MapSpec srcBlock destId baseAddress
                     in return $ m:ms
@@ -421,8 +301,8 @@ overlayMaps destId width blocks =
             return ms
 
 data StoppingPoint
-    = BlockStart { address :: !Integer }
-    | BlockEnd   { address :: !Integer }
+    = BlockStart { address :: !NetAST.Address }
+    | BlockEnd   { address :: !NetAST.Address }
     deriving (Eq, Show)
 
 instance Ord StoppingPoint where
@@ -437,140 +317,58 @@ instance Ord StoppingPoint where
 data ScanLineState
     = ScanLineState
         { insideBlocks :: !Integer
-        , startAddress :: !Integer
+        , startAddress :: !NetAST.Address
         } deriving (Show)
 
-instance NetTransformable AST.Address NetAST.Address where
-    transform _ (AST.LiteralAddress value) = do
-        return $ NetAST.Address value
-    transform context (AST.ParamAddress name) = do
-        let
-            value = getParamValue context name
-        return $ NetAST.Address value
-
-instance NetTransformable a b => NetTransformable (AST.For a) [b] where
-    transform context ast = do
-        let
-            body = AST.body ast
-            varRanges = AST.varRanges ast
-        concreteRanges <- transform context varRanges
-        let
-            valueList = Map.foldWithKey iterations [] concreteRanges
-            iterContexts = map iterationContext valueList
-            ts = map (\c -> transform c body) iterContexts
-            fs = lefts ts
-            bs = rights ts
-        case fs of
-            [] -> return $ bs
-            _  -> Left $ CheckFailure (concat $ map failures fs)
-        where
-            iterations k vs [] = [Map.fromList [(k,v)] | v <- vs]
-            iterations k vs ms = concat $ map (f ms k) vs
-                where
-                    f ms k v = map (Map.insert k v) ms
-            iterationContext varMap =
-                let
-                    values = varValues context
-                in context
-                    { varValues = values `Map.union` varMap }
-
-instance NetTransformable AST.ForRange [Integer] where
-    transform context ast = do
-        let
-            start = AST.start ast
-            end = AST.end ast
-        startVal <- transform context start
-        endVal <- transform context end
-        return [startVal..endVal]
-
-instance NetTransformable AST.ForLimit Integer where
-    transform _ (AST.LiteralLimit value) = return value
-    transform context (AST.ParamLimit name) = return $ getParamValue context name
-
 instance NetTransformable a b => NetTransformable [a] [b] where
-    transform context ast = do
-        let
-            ts = map (transform context) ast
-            fs = lefts ts
-            bs = rights ts
-        case fs of
-            [] -> return bs
-            _  -> Left $ CheckFailure (concat $ map failures fs)
-
-instance (Ord k, NetTransformable a b) => NetTransformable (Map k a) (Map k b) where
-    transform context ast = do
-        let
-            ks = Map.keys ast
-            es = Map.elems ast
-        ts <- transform context es
-        return $ Map.fromList (zip ks ts)
-
---
--- Checks
---
-class NetCheckable a where
-    check :: Set NetAST.NodeId -> a -> Either CheckFailure ()
-
-instance NetCheckable NetAST.NetSpec where
-    check _ (NetAST.NetSpec net) = do
-        let
-            specContext = Map.keysSet net
-        check specContext $ Map.elems net
-
-instance NetCheckable NetAST.NodeSpec where
-    check context net = do
-        let
-            translate = NetAST.translate net
-        check context translate
-
-instance NetCheckable NetAST.MapSpec where
-    check context net = do
-        let
-           destNode = NetAST.destNode net
-        check context destNode
-
-instance NetCheckable NetAST.NodeId where
-    check context net = do
-        if net `Set.member` context
-            then return ()
-            else Left $ CheckFailure [UndefinedReference $ show net]
-
-instance NetCheckable a => NetCheckable [a] where
-    check context net = do
-        let
-            checked = map (check context) net
-            fs = lefts $ checked
-        case fs of
-            [] -> return ()
-            _  -> Left $ CheckFailure (concat $ map failures fs)
-
-getModule :: Context -> String -> AST.Module
-getModule context name =
-    let
-        modules = AST.modules $ spec context
-    in modules Map.! name
-
-getParamValue :: Context -> String -> Integer
-getParamValue context name =
-    let
-        params = paramValues context
-    in params Map.! name
-
-getVarValue :: Context -> String -> Integer
-getVarValue context name =
-    let
-        vars = varValues context
-    in vars Map.! name
-
-checkDuplicates :: (Eq a, Show a) => [a] -> (String -> FailedCheck) -> Either CheckFailure ()
-checkDuplicates nodeIds fail = do
-    let
-        duplicates = duplicateNames nodeIds
-    case duplicates of
-        [] -> return ()
-        _  -> Left $ CheckFailure (map (fail . show) duplicates)
-    where
-        duplicateNames [] = []
-        duplicateNames (x:xs)
-            | x `elem` xs = nub $ [x] ++ duplicateNames xs
-            | otherwise = duplicateNames xs
+    transform context as = mapM (transform context) as
+
+-- instance (Ord k, NetTransformable a b) => NetTransformable (Map k a) (Map k b) where
+--     transform context ast = do
+--         let
+--             ks = Map.keys ast
+--             es = Map.elems ast
+--         ts <- transform context es
+--         return $ Map.fromList (zip ks ts)
+
+-- --
+-- -- Checks
+-- --
+-- class NetCheckable a where
+--     check :: Set NetAST.NodeId -> a -> Either CheckFailure ()
+
+-- instance NetCheckable NetAST.NetSpec where
+--     check _ (NetAST.NetSpec net) = do
+--         let
+--             specContext = Map.keysSet net
+--         check specContext $ Map.elems net
+
+-- instance NetCheckable NetAST.NodeSpec where
+--     check context net = do
+--         let
+--             translate = NetAST.translate net
+--         check context translate
+
+-- instance NetCheckable NetAST.MapSpec where
+--     check context net = do
+--         let
+--            destNode = NetAST.destNode net
+--         check context destNode
+
+-- instance NetCheckable NetAST.NodeId where
+--     check context net = do
+--         if net `Set.member` context
+--             then return ()
+--             else Left $ CheckFailure [UndefinedReference $ show net]
+
+-- instance NetCheckable a => NetCheckable [a] where
+--     check context net = do
+--         let
+--             checked = map (check context) net
+--             fs = lefts $ checked
+--         case fs of
+--             [] -> return ()
+--             _  -> Left $ CheckFailure (concat $ map failures fs)
+
+getModule :: Context -> String -> InstAST.Module
+getModule context name = (modules context) Map.! name