X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=Translator.hs;h=53e626903b26c68fb3dfdd91e75382a281590917;hb=b355ab9f758667b108c017b11d9e64188b257f3e;hp=dea1fd7dfdf8730698316dac554f11c38b34a437;hpb=3296335286c7985374420af278b006856e250ce0;p=matthijs%2Fmaster-project%2Fc%CE%BBash.git diff --git a/Translator.hs b/Translator.hs index dea1fd7..53e6269 100644 --- a/Translator.hs +++ b/Translator.hs @@ -8,6 +8,7 @@ import qualified TyCon import qualified DataCon import qualified Maybe import qualified Module +import qualified Control.Monad.State as State import Name import Data.Generics import NameEnv ( lookupNameEnv ) @@ -42,13 +43,21 @@ main = liftIO $ printBinds (cm_binds core) let bind = findBind "half_adder" (cm_binds core) let NonRec var expr = bind - let sess = VHDLSession 0 builtin_funcs - let (sess', name, f) = mkHWFunction sess bind - let sess = addFunc sess' name f + -- Turn bind into VHDL + let vhdl = State.evalState (mkVHDL bind) (VHDLSession 0 builtin_funcs) liftIO $ putStr $ showSDoc $ ppr expr liftIO $ putStr "\n\n" - liftIO $ putStr $ render $ ForSyDe.Backend.Ppr.ppr $ getArchitecture sess bind + liftIO $ putStr $ render $ ForSyDe.Backend.Ppr.ppr $ vhdl return expr + where + -- Turns the given bind into VHDL + mkVHDL bind = do + -- Get the function signature + (name, f) <- mkHWFunction bind + -- Add it to the session + addFunc name f + arch <- getArchitecture bind + return arch printTarget (Target (TargetFile file (Just x)) obj Nothing) = print $ show file @@ -192,14 +201,15 @@ mapOutputPorts (Tuple ports) (Tuple signals) = concat (zipWith mapOutputPorts ports signals) getArchitecture :: - VHDLSession - -> CoreBind -- The binder to expand into an architecture - -> AST.ArchBody -- The resulting architecture + CoreBind -- The binder to expand into an architecture + -> VHDLState AST.ArchBody -- The resulting architecture -getArchitecture sess (Rec _) = error "Recursive binders not supported" +getArchitecture (Rec _) = error "Recursive binders not supported" -getArchitecture sess (NonRec var expr) = - AST.ArchBody +getArchitecture (NonRec var expr) = do + HWFunction inports outport <- getHWFunc name + sess <- State.get + return $ AST.ArchBody (AST.unsafeVHDLBasicId "structural") -- Use unsafe for now, to prevent pulling in ForSyDe error handling (AST.NSimple (AST.unsafeVHDLBasicId name)) @@ -207,14 +217,11 @@ getArchitecture sess (NonRec var expr) = (getInstantiations sess inports outport [] expr) where name = (getOccString var) - hwfunc = Maybe.fromMaybe - (error $ "Function " ++ name ++ "is unknown? This should not happen!") - (lookup name (funcs sess)) - HWFunction inports outport = hwfunc data PortNameMap = Tuple [PortNameMap] | Port String + deriving (Show) -- Generate a port name map (or multiple for tuple types) in the given direction for -- each type given. @@ -238,17 +245,16 @@ data HWFunction = HWFunction { -- A function that is available in hardware inPorts :: [PortNameMap], outPort :: PortNameMap --entity :: AST.EntityDec -} +} deriving (Show) -- Turns a CoreExpr describing a function into a description of its input and -- output ports. mkHWFunction :: - VHDLSession - -> CoreBind -- The core binder to generate the interface for - -> (VHDLSession, String, HWFunction) -- The name of the function and its interface + CoreBind -- The core binder to generate the interface for + -> VHDLState (String, HWFunction) -- The name of the function and its interface -mkHWFunction sess (NonRec var expr) = - (sess, name, HWFunction inports outport) +mkHWFunction (NonRec var expr) = + return (name, HWFunction inports outport) where name = (getOccString var) ty = CoreUtils.exprType expr @@ -261,18 +267,30 @@ mkHWFunction sess (NonRec var expr) = ps -> getPortNameMapForTys "portin" 0 ps outport = getPortNameMapForTy "portout" res -mkHWFunction sess (Rec _) = +mkHWFunction (Rec _) = error "Recursive binders not supported" data VHDLSession = VHDLSession { nameCount :: Int, -- A counter that can be used to generate unique names funcs :: [(String, HWFunction)] -- All functions available, indexed by name -} +} deriving (Show) + +type VHDLState = State.State VHDLSession -- Add the function to the session -addFunc :: VHDLSession -> String -> HWFunction -> VHDLSession -addFunc sess name f = - sess {funcs = (name, f) : (funcs sess) } +addFunc :: String -> HWFunction -> VHDLState () +addFunc name f = do + fs <- State.gets funcs -- Get the funcs element from the session + State.modify (\x -> x {funcs = (name, f) : fs }) -- Prepend name and f + +-- Lookup the function with the given name in the current session. Errors if +-- it was not found. +getHWFunc :: String -> VHDLState HWFunction +getHWFunc name = do + fs <- State.gets funcs -- Get the funcs element from the session + return $ Maybe.fromMaybe + (error $ "Function " ++ name ++ "is unknown? This should not happen!") + (lookup name fs) builtin_funcs = [