packages feed

copilot-c99 3.17 → 3.18

raw patch · 5 files changed

+98/−49 lines, 5 filesdep ~copilot-coredep ~language-c99-simplePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: copilot-core, language-c99-simple

API changes (from Hackage documentation)

Files

CHANGELOG view
@@ -1,3 +1,10 @@+2024-01-07+        * Version bump (3.18). (#487)+        * Change return type of main generated for tests. (#468)+        * Print constants in tests using portable suffixes. (#471).+        * Pass output arrays as arguments to trigger argument functions. (#431)+        * Compliance with MISRA C 2023 / MISRA C 2012. (#472)+ 2023-11-07         * Version bump (3.17). (#466)         * Replace uses of deprecated functions. (#457)
copilot-c99.cabal view
@@ -1,6 +1,6 @@ cabal-version             : >= 1.10 name                      : copilot-c99-version                   : 3.17+version                   : 3.18 synopsis                  : A compiler for Copilot targeting C99. description               :   This package is a back-end from Copilot to C.@@ -45,9 +45,9 @@                           , mtl                 >= 2.2 && < 2.4                           , pretty              >= 1.1 && < 1.2 -                          , copilot-core        >= 3.17  && < 3.18+                          , copilot-core        >= 3.18  && < 3.19                           , language-c99        >= 0.2.0 && < 0.3-                          , language-c99-simple >= 0.2.2 && < 0.3+                          , language-c99-simple >= 0.3   && < 0.4    exposed-modules         : Copilot.Compile.C99 
src/Copilot/Compile/C99/CodeGen.hs view
@@ -100,11 +100,18 @@  -- | Define an accessor functions for the ring buffer associated with a stream. mkAccessDecln :: Id -> Type a -> [a] -> C.FunDef-mkAccessDecln sId ty xs = C.FunDef cTy name params [] [C.Return (Just expr)]+mkAccessDecln sId ty xs =+    C.FunDef static cTy name params [] [C.Return (Just expr)]   where+    static     = Just C.Static     cTy        = C.decay $ transType ty     name       = streamAccessorName sId-    buffLength = C.LitInt $ fromIntegral $ length xs++    -- We cast the buffer length to a size_t to make sure that there are no+    -- implicit conversions. This is a requirement for compliance with MISRA C+    -- (Rule 10.4).+    buffLength = C.Cast sizeT $ C.LitInt $ fromIntegral $ length xs+    sizeT      = C.TypeName $ C.TypeSpec $ C.TypedefName "size_t"     params     = [C.Param (C.TypeSpec $ C.TypedefName "size_t") "x"]     index      = (C.Ident (indexName sId) C..+ C.Ident "x") C..% buffLength     expr       = C.Index (C.Ident (streamName sId)) index@@ -113,16 +120,19 @@  -- | Write a generator function for a stream. mkGenFun :: String -> Expr a -> Type a -> C.FunDef-mkGenFun name expr ty = C.FunDef cTy name [] cVars [C.Return $ Just cExpr]+mkGenFun name expr ty =+    C.FunDef static cTy name [] cVars [C.Return $ Just cExpr]   where+    static         = Just C.Static     cTy            = C.decay $ transType ty     (cExpr, cVars) = runState (transExpr expr) mempty  -- | Write a generator function for a stream that returns an array. mkGenFunArray :: String -> String -> Expr a -> Type a -> C.FunDef mkGenFunArray name nameArg expr ty@(Array _) =-    C.FunDef funType name [ outputParam ] varDecls stmts+    C.FunDef static funType name [ outputParam ] varDecls stmts   where+    static  = Just C.Static     funType = C.TypeSpec C.Void      -- The output value is an array@@ -145,7 +155,7 @@ -- | Define the step function that updates all streams. mkStep :: CSettings -> [Stream] -> [Trigger] -> [External] -> C.FunDef mkStep cSettings streams triggers exts =-    C.FunDef void (cSettingsStepFunctionName cSettings) [] declns stmts+    C.FunDef Nothing void (cSettingsStepFunctionName cSettings) [] declns stmts   where     void = C.TypeSpec C.Void @@ -163,6 +173,16 @@     (triggerDeclns, triggerStmts) =       unzip $ map mkTriggerCheck triggers +    -- Update the value of a variable with the result of calling a function that+    -- generates the next value in a stream expression. If the type of the+    -- variable is an array, then we cannot perform a direct C assignment, so+    -- we instead pass the variable as an output array to the function.+    updateVar :: C.Ident -> C.Ident -> Type a -> C.Expr+    updateVar varName genName (Array _) =+      C.Funcall (C.Ident genName) [C.Ident varName]+    updateVar varName genName _ =+      C.AssignOp C.Assign (C.Ident varName) (C.Funcall (C.Ident genName) [])+     -- Write code to update global stream buffers and index.     mkUpdateGlobals :: Stream -> (C.Decln, C.Stmt, C.Stmt, C.Stmt)     mkUpdateGlobals (Stream sId buff _expr ty) =@@ -170,10 +190,7 @@         where           tmpDecln = C.VarDecln Nothing cTy tmpVar Nothing -          tmpAssign = case ty of-            Array _ -> C.Expr $ C.Funcall (C.Ident $ generatorName sId)-                                          [ C.Ident tmpVar ]-            _       -> C.Expr $ C.Ident tmpVar C..= val+          tmpAssign = C.Expr $ updateVar tmpVar (generatorName sId) ty            bufferUpdate = case ty of             Array _ -> C.Expr $ memcpy dest (C.Ident tmpVar) size@@ -187,13 +204,16 @@            indexUpdate = C.Expr $ indexVar C..= (incIndex C..% buffLength)             where-              buffLength = C.LitInt $ fromIntegral $ length buff-              incIndex   = indexVar C..+ C.LitInt 1+              -- We cast the buffer length and the literal one to a size_t to+              -- make sure that there are no implicit conversions. This is a+              -- requirement for compliance with MISRA C (Rule 10.4).+              buffLength = C.Cast sizeT $ C.LitInt $ fromIntegral $ length buff+              incIndex   = indexVar C..+ C.Cast sizeT (C.LitInt 1)+              sizeT      = C.TypeName $ C.TypeSpec $ C.TypedefName "size_t"            tmpVar   = streamName sId ++ "_tmp"           buffVar  = C.Ident $ streamName sId           indexVar = C.Ident $ indexName sId-          val      = C.Funcall (C.Ident $ generatorName sId) []           cTy      = transType ty      -- Make code that copies an external variable to its local one.@@ -250,22 +270,8 @@         aTmpDeclns = zipWith declare args aTempNames           where             declare :: UExpr -> C.Ident -> C.Decln-            declare arg tmpVar =-              C.VarDecln Nothing (tempType arg) tmpVar Nothing--            -- Type of the temporary variable used to store values of the type-            -- of a given expression.-            tempType :: UExpr -> C.Type-            tempType (UExpr { uExprType = ty }) =-              case ty of-                -- If a temporary variable is being used to store an array,-                -- declare the type of the temporary variable as a pointer, not-                -- an array. The problem with declaring it as an array is that-                -- the `arg` function will return a pointer, not an array, and-                -- C doesn't make it easy to cast directly from an array to a-                -- pointer.-                Array ty' -> C.Ptr $ transType ty'-                _         -> transType ty+            declare (UExpr { uExprType = ty }) tmpVar =+              C.VarDecln Nothing (transType ty) tmpVar Nothing          triggerCheckStmt :: C.Stmt         triggerCheckStmt = C.If guard' fireTrigger@@ -283,13 +289,14 @@               where                 -- List of assignments of values of temporary variables.                 argAssigns :: [C.Expr]-                argAssigns = zipWith assign aTempNames args'+                argAssigns = zipWith3 assign aTempNames aArgNames args -                assign :: C.Ident -> C.Expr -> C.Expr-                assign aTempName = C.AssignOp C.Assign (C.Ident aTempName)+                assign :: C.Ident -> C.Ident -> UExpr -> C.Expr+                assign aTempName aArgName (UExpr { uExprType = ty }) =+                  updateVar aTempName aArgName ty -                args'         = take (length args) (map argCall (argNames name))-                argCall name' = C.Funcall (C.Ident name') []+                aArgNames :: [C.Ident]+                aArgNames = take (length args) (argNames name)                  -- Build an expression to pass a temporary variable as argument                 -- to a trigger handler.
src/Copilot/Compile/C99/Compile.hs view
@@ -119,9 +119,8 @@         accessDecln (Stream sId buff _ ty) = mkAccessDecln sId ty buff          streamGen :: Stream -> C.FunDef-        streamGen (Stream sId _ expr ty@(Array _)) =-          mkGenFunArray (generatorName sId) (generatorOutputArgName sId) expr ty-        streamGen (Stream sId _ expr ty) = mkGenFun (generatorName sId) expr ty+        streamGen (Stream sId _ expr ty) =+          exprGen (generatorName sId) (generatorOutputArgName sId) expr ty          triggerGen :: Trigger -> [C.FunDef]         triggerGen (Trigger name guard args) = guardDef : argDefs@@ -130,7 +129,19 @@             argDefs  = zipWith argGen (argNames name) args              argGen :: String -> UExpr -> C.FunDef-            argGen argName (UExpr ty expr) = mkGenFun argName expr ty+            argGen argName (UExpr ty expr) =+              exprGen argName (argName ++ "_output") expr ty++        -- Create a function that calculates the current value generated by an+        -- expression `expr` of type `ty`. The generator treats arrays+        -- specially, and the function takes an output array as a parameter.+        -- The second identifier `outputArrName` is not used if `expr` is not an+        -- array.+        exprGen :: C.Ident -> C.Ident -> Expr a -> Type a -> C.FunDef+        exprGen funName outputArrName expr ty@(Array _) =+          mkGenFunArray funName outputArrName expr ty+        exprGen funName _ expr ty =+          mkGenFun funName expr ty  -- | Generate the .h file from a 'Spec'. compileH :: CSettings -> Spec -> C.TransUnit
tests/Test/Copilot/Compile/C99.hs view
@@ -157,7 +157,7 @@           , "void nop () {"           , "}"           , ""-          , "void main () {"+          , "int main () {"           , "  step();"           , "}"           ]@@ -886,28 +886,52 @@   cshow :: s -> String  instance CShow Int8 where-  cshow = show+  -- Use a macro to ensure that any necessary suffixes are added to the number.+  -- We choose this macro instead of specifically adding a suffix for reasons+  -- of portability.+  cshow x = "INT8_C(" ++ show x ++ ")"  instance CShow Int16 where-  cshow = show+  -- Use a macro to ensure that any necessary suffixes are added to the number.+  -- We choose this macro instead of specifically adding a suffix for reasons+  -- of portability.+  cshow x = "INT16_C(" ++ show x ++ ")"  instance CShow Int32 where-  cshow = show+  -- Use a macro to ensure that any necessary suffixes are added to the number.+  -- We choose this macro instead of specifically adding a suffix for reasons+  -- of portability.+  cshow x = "INT32_C(" ++ show x ++ ")"  instance CShow Int64 where-  cshow = show+  -- Use a macro to ensure that any necessary suffixes are added to the number.+  -- We choose this macro instead of specifically adding a suffix for reasons+  -- of portability.+  cshow x = "INT64_C(" ++ show x ++ ")"  instance CShow Word8 where-  cshow = show+  -- Use a macro to ensure that any necessary suffixes are added to the number.+  -- We choose this macro instead of specifically adding a suffix for reasons+  -- of portability.+  cshow x = "UINT8_C(" ++ show x ++ ")"  instance CShow Word16 where-  cshow = show+  -- Use a macro to ensure that any necessary suffixes are added to the number.+  -- We choose this macro instead of specifically adding a suffix for reasons+  -- of portability.+  cshow x = "UINT16_C(" ++ show x ++ ")"  instance CShow Word32 where-  cshow = show+  -- Use a macro to ensure that any necessary suffixes are added to the number.+  -- We choose this macro instead of specifically adding a suffix for reasons+  -- of portability.+  cshow x = "UINT32_C(" ++ show x ++ ")"  instance CShow Word64 where-  cshow = show+  -- Use a macro to ensure that any necessary suffixes are added to the number.+  -- We choose this macro instead of specifically adding a suffix for reasons+  -- of portability.+  cshow x = "UINT64_C(" ++ show x ++ ")"  instance CShow Float where   cshow = show