X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;ds=sidebyside;f=Generate.hs;h=947c22254a7a1369b86bcd25d6918cfe6a12523e;hb=c170d5cf53ad578ea96b3e80b926e23c3b512295;hp=b3045def5bfcee16e869fac00e08e603e7335e15;hpb=c8034ff49822eb6e0e0696f288e20e49a1b9af6e;p=matthijs%2Fmaster-project%2Fc%CE%BBash.git diff --git a/Generate.hs b/Generate.hs index b3045de..947c222 100644 --- a/Generate.hs +++ b/Generate.hs @@ -17,6 +17,9 @@ import CoreSyn import Type import qualified Var import qualified IdInfo +import qualified Literal +import qualified Name +import qualified TyCon -- Local imports import Constants @@ -48,6 +51,18 @@ genVarArgs wrap dst func args = wrap dst func args' -- Check (rather crudely) that all arguments are CoreExprs (exprargs, []) = Either.partitionEithers args +-- | A function to wrap a builder-like function that expects its arguments to +-- be Literals +genLitArgs :: + (dst -> func -> [Literal.Literal] -> res) + -> (dst -> func -> [Either CoreSyn.CoreExpr AST.Expr] -> res) +genLitArgs wrap dst func args = wrap dst func args' + where + args' = map exprToLit litargs + -- FIXME: Check if we were passed an CoreSyn.App + litargs = concat (map getLiterals exprargs) + (exprargs, []) = Either.partitionEithers args + -- | A function to wrap a builder-like function that produces an expression -- and expects it to be assigned to the destination. genExprRes :: @@ -83,6 +98,37 @@ genFCall' switch (Left res) f args = do map (\exp -> Nothing AST.:=>: AST.ADExpr exp) args genFCall' _ (Right name) _ _ = error $ "\nGenerate.genFCall': Cannot generate builtin function call assigned to a VHDLName: " ++ show name +genFromSizedWord :: BuiltinBuilder +genFromSizedWord = genExprArgs $ genExprRes genFromSizedWord' +genFromSizedWord' :: Either CoreSyn.CoreBndr AST.VHDLName -> CoreSyn.CoreBndr -> [AST.Expr] -> VHDLSession AST.Expr +genFromSizedWord' (Left res) f args = do + let fname = varToString f + return $ AST.PrimFCall $ AST.FCall (AST.NSimple (mkVHDLBasicId toIntegerId)) $ + map (\exp -> Nothing AST.:=>: AST.ADExpr exp) args +genFromSizedWord' (Right name) _ _ = error $ "\nGenerate.genFromSizedWord': Cannot generate builtin function call assigned to a VHDLName: " ++ show name + +-- FIXME: I'm calling genLitArgs which is very specific function, +-- which needs to be fixed as well +genFromInteger :: BuiltinBuilder +genFromInteger = genLitArgs $ genExprRes genFromInteger' +genFromInteger' :: Either CoreSyn.CoreBndr AST.VHDLName -> CoreSyn.CoreBndr -> [Literal.Literal] -> VHDLSession AST.Expr +genFromInteger' (Left res) f lits = + return $ AST.PrimFCall $ AST.FCall (AST.NSimple (mkVHDLBasicId fname)) + [Nothing AST.:=>: AST.ADExpr (AST.PrimLit (show (last lits))), Nothing AST.:=>: AST.ADExpr( AST.PrimLit (show len))] + where + ty = Var.varType res + (tycon, args) = Type.splitTyConApp ty + name = Name.getOccString (TyCon.tyConName tycon) + len = case name of + "SizedInt" -> sized_int_len ty + "SizedWord" -> sized_word_len ty + fname = case name of + "SizedInt" -> toSignedId + "SizedWord" -> toUnsignedId + +genFromInteger' (Right name) _ _ = error $ "\nGenerate.genFromInteger': Cannot generate builtin function call assigned to a VHDLName: " ++ show name + + -- | Generate a generate statement for the builtin function "map" genMap :: BuiltinBuilder genMap (Left res) f [Left mapped_f, Left (Var arg)] = @@ -440,8 +486,8 @@ genApplication dst f args = if length args == arg_count then builder dst f args else - error $ "\nGenerate.genApplication: Incorrect number of arguments to builtin function: " ++ pprString f ++ " Args: " ++ show args - Nothing -> error $ "\nGenerate.genApplication: Using function from another module that is not a known builtin: " ++ pprString f + error $ "\nGenerate.genApplication(VanillaGlobal): Incorrect number of arguments to builtin function: " ++ pprString f ++ " Args: " ++ show args + Nothing -> error $ "\nGenerate.genApplication(VanillaGlobal): Using function from another module that is not a known builtin: " ++ pprString f IdInfo.NotGlobalId -> do signatures <- getA vsSignatures -- This is a local id, so it should be a function whose definition we @@ -457,6 +503,16 @@ genApplication dst f args = portmaps = mkAssocElems (map (either exprToVHDLExpr id) args) ((either varToVHDLName id) dst) signature in return [mkComponentInst label entity_id portmaps] + IdInfo.ClassOpId cls -> do + -- FIXME: Not looking for what instance this class op is called for + -- Is quite stupid of course. + case (Map.lookup (varToString f) globalNameTable) of + Just (arg_count, builder) -> + if length args == arg_count then + builder dst f args + else + error $ "\nGenerate.genApplication(ClassOpId): Incorrect number of arguments to builtin function: " ++ pprString f ++ " Args: " ++ show args + Nothing -> error $ "\nGenerate.genApplication(ClassOpId): Using function from another module that is not a known builtin: " ++ pprString f details -> error $ "\nGenerate.genApplication: Calling unsupported function " ++ pprString f ++ " with GlobalIdDetails " ++ pprString details ----------------------------------------------------------------------------- @@ -913,4 +969,10 @@ globalNameTable = Map.fromList , (hwandId , (2, genOperator2 AST.And ) ) , (hworId , (2, genOperator2 AST.Or ) ) , (hwnotId , (1, genOperator1 AST.Not ) ) + , (plusId , (2, genOperator2 (AST.:+:) ) ) + , (timesId , (2, genOperator2 (AST.:*:) ) ) + , (negateId , (1, genOperator1 AST.Neg ) ) + , (minusId , (2, genOperator2 (AST.:-:) ) ) + , (fromSizedWordId , (1, genFromSizedWord ) ) + , (fromIntegerId , (1, genFromInteger ) ) ]