packages feed

copilot-c99 3.19.1 → 3.20

raw patch · 4 files changed

+118/−43 lines, 4 filesdep ~copilot-corePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: copilot-core

API changes (from Hackage documentation)

Files

CHANGELOG view
@@ -1,3 +1,7 @@+2024-07-07+        * Version bump (3.20). (#522)+        * Add support for struct field updates. (#520)+ 2024-05-07         * Version bump (3.19.1). (#512) 
copilot-c99.cabal view
@@ -1,6 +1,6 @@ cabal-version             : >= 1.10 name                      : copilot-c99-version                   : 3.19.1+version                   : 3.20 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.19.1 && < 3.20-                          , language-c99        >= 0.2.0  && < 0.3-                          , language-c99-simple >= 0.3    && < 0.4+                          , copilot-core        >= 3.20  && < 3.21+                          , language-c99        >= 0.2.0 && < 0.3+                          , language-c99-simple >= 0.3   && < 0.4    exposed-modules         : Copilot.Compile.C99 
src/Copilot/Compile/C99/CodeGen.hs view
@@ -121,11 +121,13 @@ -- | Write a generator function for a stream. mkGenFun :: String -> Expr a -> Type a -> C.FunDef mkGenFun name expr ty =-    C.FunDef static cTy name [] cVars [C.Return $ Just cExpr]+    C.FunDef static cTy name [] cVars stmts   where-    static         = Just C.Static-    cTy            = C.decay $ transType ty-    (cExpr, cVars) = runState (transExpr expr) mempty+    static             = Just C.Static+    cTy                = C.decay $ transType ty+    (cExpr, state')    = runState (transExpr expr) (0, mempty, mempty)+    (_, cVars, stmts') = state'+    stmts              = stmts' ++ [C.Return $ Just cExpr]  -- | Write a generator function for a stream that returns an array. mkGenFunArray :: String -> String -> Expr a -> Type a -> C.FunDef@@ -139,13 +141,20 @@     outputParam = C.Param cArrayType nameArg     cArrayType  = transType ty -    -- Output value, and any variable declarations needed-    (cExpr, varDecls) = runState (transExpr expr) mempty+    -- Statements to execute as part of the generator. They include statements+    -- related to calculating the values of intermediate expressions, and+    -- statements related to copying the final value to the destination array.+    stmts = stmts' ++ [ copyStmt ] -    -- Copy expression to output argument-    stmts = [ C.Expr $ memcpy (C.Ident nameArg) cExpr size ]-    size  = C.LitInt (fromIntegral $ typeSize ty)-              C..* C.SizeOfType (C.TypeName $ tyElemName ty)+    -- Output value, variable declarations needed, and other statements that+    -- must be executed to calculate intermediate values.+    (cExpr, state')       = runState (transExpr expr) (0, mempty, mempty)+    (_, varDecls, stmts') = state'++    -- Copy expression to output argument.+    copyStmt = C.Expr $ memcpy (C.Ident nameArg) cExpr size+    size     = C.LitInt (fromIntegral $ typeSize ty)+                 C..* C.SizeOfType (C.TypeName $ tyElemName ty)  mkGenFunArray _name _nameArg _expr _ty =   impossible "mkGenFunArray" "copilot-c99"
src/Copilot/Compile/C99/Expr.hs view
@@ -8,19 +8,20 @@   where  -- External imports-import           Control.Monad.State ( State, modify )+import           Control.Monad.State ( State, get, modify ) import qualified Data.List.NonEmpty  as NonEmpty import qualified Language.C99.Simple as C  -- Internal imports: Copilot import Copilot.Core ( Expr (..), Field (..), Op1 (..), Op2 (..), Op3 (..),                       Type (..), Value (..), accessorName, arrayElems,-                      toValues )+                      toValues, typeSize )  -- Internal imports import Copilot.Compile.C99.Error ( impossible ) import Copilot.Compile.C99.Name  ( exCpyName, streamAccessorName )-import Copilot.Compile.C99.Type  ( transLocalVarDeclType, transTypeName )+import Copilot.Compile.C99.Type  ( transLocalVarDeclType, transType,+                                   transTypeName )  -- | Translates a Copilot Core expression into a C99 expression. transExpr :: Expr a -> State FunEnv C.Expr@@ -32,7 +33,9 @@       initExpr = Just $ C.InitExpr e1'    -- Add new decl to the tail of the fun env-  modify (++ [C.VarDecln Nothing cTy1 name initExpr])+  modify (\(i, x, y)+             -> (i, x ++ [C.VarDecln Nothing cTy1 name initExpr], y)+         )    transExpr e2 @@ -51,6 +54,48 @@   e' <- transExpr e   return $ transOp1 op e' +transExpr (Op2 (UpdateField ty1@(Struct _) ty2 f) e1 e2) = do+  -- Translating a struct update Op requires initializing a variable to the+  -- "old" value, updating the field, and returning the new value.+  e1' <- transExpr e1+  e2' <- transExpr e2++  -- Variable to hold the updated struct+  (i, _, _) <- get+  let varName = "_v" ++ show i+  modify (\(i, x, y) -> (i + 1, x, y))++  -- Add new var decl+  let initDecl = C.VarDecln Nothing cTy1 varName Nothing+      cTy1     = transLocalVarDeclType ty1+  modify (\(i, x, y) -> (i, x ++ [initDecl], y))++  -- Initialize the var to the same value as the original struct+  let initStmt = C.Expr+               $ C.AssignOp+                   C.Assign+                   (C.Ident varName)+                   e1'++  -- Update field f with given value e2.+  let updateStmt = case ty2 of+        Array _ -> C.Expr $ memcpy dest e2' size+          where+            dest = C.Dot (C.Ident varName) (accessorName f)+            size = C.LitInt+                       (fromIntegral $ typeSize ty2)+                       C..* C.SizeOfType (C.TypeName (tyElemName ty2))++        _       -> C.Expr+                 $ C.AssignOp+                     C.Assign+                     (C.Dot (C.Ident varName) (accessorName f))+                     e2'++  modify (\(i, x, y) -> (i, x, y ++ [ initStmt, updateStmt ]))++  return $ C.Ident varName+ transExpr (Op2 op e1 e2) = do   e1' <- transExpr e1   e2' <- transExpr e2@@ -100,32 +145,35 @@  -- | Translates a Copilot binary operator and its arguments into a C99 -- expression.+--+-- PRE: op is not a struct update operation (i.e., 'UpdateField'). transOp2 :: Op2 a b c -> C.Expr -> C.Expr -> C.Expr transOp2 op e1 e2 = case op of-  And          -> e1 C..&& e2-  Or           -> e1 C..|| e2-  Add      _   -> e1 C..+  e2-  Sub      _   -> e1 C..-  e2-  Mul      _   -> e1 C..*  e2-  Mod      _   -> e1 C..%  e2-  Div      _   -> e1 C../  e2-  Fdiv     _   -> e1 C../  e2-  Pow      ty  -> funCall (specializeMathFunName ty "pow") [e1, e2]-  Logb     ty  -> funCall (specializeMathFunName ty "log") [e2] C../-                  funCall (specializeMathFunName ty "log") [e1]-  Atan2    ty  -> funCall (specializeMathFunName ty "atan2") [e1, e2]-  Eq       _   -> e1 C..== e2-  Ne       _   -> e1 C..!= e2-  Le       _   -> e1 C..<= e2-  Ge       _   -> e1 C..>= e2-  Lt       _   -> e1 C..<  e2-  Gt       _   -> e1 C..>  e2-  BwAnd    _   -> e1 C..&  e2-  BwOr     _   -> e1 C..|  e2-  BwXor    _   -> e1 C..^  e2-  BwShiftL _ _ -> e1 C..<< e2-  BwShiftR _ _ -> e1 C..>> e2-  Index    _   -> C.Index e1 e2+  And               -> e1 C..&& e2+  Or                -> e1 C..|| e2+  Add         _     -> e1 C..+  e2+  Sub         _     -> e1 C..-  e2+  Mul         _     -> e1 C..*  e2+  Mod         _     -> e1 C..%  e2+  Div         _     -> e1 C../  e2+  Fdiv        _     -> e1 C../  e2+  Pow         ty    -> funCall (specializeMathFunName ty "pow") [e1, e2]+  Logb        ty    -> funCall (specializeMathFunName ty "log") [e2] C../+                       funCall (specializeMathFunName ty "log") [e1]+  Atan2       ty    -> funCall (specializeMathFunName ty "atan2") [e1, e2]+  Eq          _     -> e1 C..== e2+  Ne          _     -> e1 C..!= e2+  Le          _     -> e1 C..<= e2+  Ge          _     -> e1 C..>= e2+  Lt          _     -> e1 C..<  e2+  Gt          _     -> e1 C..>  e2+  BwAnd       _     -> e1 C..&  e2+  BwOr        _     -> e1 C..|  e2+  BwXor       _     -> e1 C..^  e2+  BwShiftL    _ _   -> e1 C..<< e2+  BwShiftR    _ _   -> e1 C..>> e2+  Index       _     -> C.Index e1 e2+  UpdateField _ _ _ -> impossible "transOp2" "copilot-c99"  -- | Translates a Copilot ternary operator and its arguments into a C99 -- expression.@@ -368,10 +416,24 @@ -- | Auxiliary type used to collect all the declarations of all the variables -- used in a function to be generated, since variable declarations are always -- listed first at the top of the function body.-type FunEnv = [C.Decln]+type FunEnv = (Int, [C.Decln], [C.Stmt])  -- | Define a C expression that calls a function with arguments. funCall :: C.Ident   -- ^ Function name         -> [C.Expr]  -- ^ Arguments         -> C.Expr funCall name = C.Funcall (C.Ident name)++-- Write a call to the memcpy function.+memcpy :: C.Expr -> C.Expr -> C.Expr -> C.Expr+memcpy dest src size = C.Funcall (C.Ident "memcpy") [dest, src, size]++-- Translate a Copilot type to a C99 type, handling arrays especially.+--+-- If the given type is an array (including multi-dimensional arrays), the+-- type is that of the elements in the array. Otherwise, it is just the+-- equivalent representation of the given type in C.+tyElemName :: Type a -> C.Type+tyElemName ty = case ty of+  Array ty' -> tyElemName ty'+  _         -> transType ty