X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=Translator.hs;h=3b0886086b055d3b34aaa8b8c368d0ce2d70bf39;hb=4fb701e41729143a897d43cd8a9c0217b8b3f68a;hp=8d69ea2626396094202437afc6c7ca570c123c42;hpb=2f1cf3a17e4d206c01031b3117779e99d21a4dce;p=matthijs%2Fmaster-project%2Fc%CE%BBash.git diff --git a/Translator.hs b/Translator.hs index 8d69ea2..3b08860 100644 --- a/Translator.hs +++ b/Translator.hs @@ -10,6 +10,7 @@ import qualified Maybe import qualified Module import qualified Control.Monad.State as State import Name +import qualified Data.Map as Map import Data.Generics import NameEnv ( lookupNameEnv ) import HscTypes ( cm_binds, cm_types ) @@ -32,8 +33,10 @@ import qualified ForSyDe.Backend.Ppr import Text.PrettyPrint.HughesPJ (render) import TranslatorTypes +import HsValueMap import Pretty import Flatten +import FlattenTypes import qualified VHDL main = @@ -53,7 +56,7 @@ main = let binds = Maybe.mapMaybe (findBind (cm_binds core)) ["sfull_adder"] liftIO $ putStr $ prettyShow binds -- Turn bind into VHDL - let (vhdl, sess) = State.runState (mkVHDL binds) (VHDLSession 0 []) + let (vhdl, sess) = State.runState (mkVHDL binds) (VHDLSession core 0 Map.empty) liftIO $ putStr $ render $ ForSyDe.Backend.Ppr.ppr vhdl liftIO $ ForSyDe.Backend.VHDL.FileIO.writeDesignFile vhdl "../vhdl/vhdl/output.vhdl" liftIO $ putStr $ "\n\nFinal session:\n" ++ prettyShow sess ++ "\n\n" @@ -62,9 +65,9 @@ main = -- Turns the given bind into VHDL mkVHDL binds = do -- Add the builtin functions - --mapM (uncurry addFunc) builtin_funcs + mapM addBuiltIn builtin_funcs -- Create entities and architectures for them - mapM flattenBind binds + mapM processBind binds return $ AST.DesignFile [] [] @@ -79,23 +82,33 @@ findBind binds lookfor = NonRec var _ -> lookfor == (occNameString $ nameOccName $ getName var) ) binds --- | Flattens the given bind and adds it to the session. Then (recursively) --- finds any functions it uses and does the same with them. -flattenBind :: - CoreBind -- The binder to flatten +-- | Processes the given bind as a top level bind. +processBind :: + CoreBind -- The bind to process -> VHDLState () -flattenBind (Rec _) = error "Recursive binders not supported" - -flattenBind bind@(NonRec var expr) = do +processBind (Rec _) = error "Recursive binders not supported" +processBind bind@(NonRec var expr) = do -- Create the function signature let ty = CoreUtils.exprType expr let hsfunc = mkHsFunction var ty - --hwfunc <- mkHWFunction bind hsfunc - -- Add it to the session - --addFunc hsfunc hwfunc + flattenBind hsfunc bind + +-- | Flattens the given bind into the given signature and adds it to the +-- session. Then (recursively) finds any functions it uses and does the same +-- with them. +flattenBind :: + HsFunction -- The signature to flatten into + -> CoreBind -- The bind to flatten + -> VHDLState () + +flattenBind _ (Rec _) = error "Recursive binders not supported" + +flattenBind hsfunc bind@(NonRec var expr) = do + -- Flatten the function let flatfunc = flattenFunction hsfunc bind - addFunc hsfunc flatfunc + addFunc hsfunc + setFlatFunc hsfunc (Left flatfunc) let used_hsfuncs = map appFunc (apps flatfunc) State.mapM resolvFunc used_hsfuncs return () @@ -106,8 +119,24 @@ resolvFunc :: HsFunction -- | The function to look for -> VHDLState () -resolvFunc hsfunc = - return () +resolvFunc hsfunc = do + -- See if the function is already known + func <- getFunc hsfunc + case func of + -- Already known, do nothing + Just _ -> do + return () + -- New function, resolve it + Nothing -> do + -- Get the current module + core <- getModule + -- Find the named function + let bind = findBind (cm_binds core) name + case bind of + Nothing -> error $ "Couldn't find function " ++ name ++ " in current module." + Just b -> flattenBind hsfunc b + where + name = hsFuncName hsfunc -- | Translate a top level function declaration to a HsFunction. i.e., which -- interface will be provided by this function. This function essentially @@ -152,4 +181,25 @@ splitTupleType ty = Nothing Nothing -> Nothing +-- | A consise representation of a (set of) ports on a builtin function +type PortMap = HsValueMap (String, AST.TypeMark) +-- | A consise representation of a builtin function +data BuiltIn = BuiltIn String [PortMap] PortMap + +-- | Translate a concise representation of a builtin function to something +-- that can be put into FuncMap directly. +addBuiltIn :: BuiltIn -> VHDLState () +addBuiltIn (BuiltIn name args res) = do + addFunc hsfunc + where + hsfunc = HsFunction name (map useAsPort args) (useAsPort res) + +builtin_funcs = + [ + BuiltIn "hwxor" [(Single ("a", VHDL.bit_ty)), (Single ("b", VHDL.bit_ty))] (Single ("o", VHDL.bit_ty)), + BuiltIn "hwand" [(Single ("a", VHDL.bit_ty)), (Single ("b", VHDL.bit_ty))] (Single ("o", VHDL.bit_ty)), + BuiltIn "hwor" [(Single ("a", VHDL.bit_ty)), (Single ("b", VHDL.bit_ty))] (Single ("o", VHDL.bit_ty)), + BuiltIn "hwnot" [(Single ("a", VHDL.bit_ty))] (Single ("o", VHDL.bit_ty)) + ] + -- vim: set ts=8 sw=2 sts=2 expandtab: