Skip to content

Commit

Permalink
copilot-c99: Adapt mkStep to use unique triggers. Refs Copilot-Lang…
Browse files Browse the repository at this point in the history
…uage#296.

The current implementation of Copilot does not allow using the same
trigger handler name multiple times, since the C99 backend produces
multiple repeated declarations, which is invalid.

A prior commit has introduced a representation of triggers with unique
IDs, allowing us to distinguish between a monitor for one condition
within a Copilot spec vs the external C function being called when the
condition becomes true.

This commit updates the generation of the `step` function to use unique
names for the triggers.
  • Loading branch information
fdedden committed Jan 2, 2025
1 parent 5bc2d09 commit b740830
Showing 1 changed file with 19 additions and 14 deletions.
33 changes: 19 additions & 14 deletions copilot-c99/src/Copilot/Compile/C99/CodeGen.hs
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,17 @@ import Copilot.Core ( Expr (..), Id, Stream (..), Struct (..), Trigger (..),
Type (..), UExpr (..), Value (..), fieldName, typeSize )

-- Internal imports
import Copilot.Compile.C99.Error ( impossible )
import Copilot.Compile.C99.Expr ( constArray, transExpr )
import Copilot.Compile.C99.External ( External (..) )
import Copilot.Compile.C99.Name ( argNames, argTempNames, generatorName,
guardName, indexName, streamAccessorName,
streamName )
import Copilot.Compile.C99.Settings ( CSettings, cSettingsStepFunctionName )
import Copilot.Compile.C99.Type ( transType )
import Copilot.Compile.C99.Error ( impossible )
import Copilot.Compile.C99.Expr ( constArray, transExpr )
import Copilot.Compile.C99.External ( External (..) )
import Copilot.Compile.C99.Name ( argNames, argTempNames,
generatorName, guardName,
indexName, streamAccessorName,
streamName )
import Copilot.Compile.C99.Settings ( CSettings,
cSettingsStepFunctionName )
import Copilot.Compile.C99.Type ( transType )
import Copilot.Compile.C99.Representation ( UniqueTrigger (..) )

-- * Externs

Expand Down Expand Up @@ -162,7 +165,7 @@ mkGenFunArray _name _nameArg _expr _ty =
-- * Monitor processing

-- | Define the step function that updates all streams.
mkStep :: CSettings -> [Stream] -> [Trigger] -> [External] -> C.FunDef
mkStep :: CSettings -> [Stream] -> [UniqueTrigger] -> [External] -> C.FunDef
mkStep cSettings streams triggers exts =
C.FunDef Nothing void (cSettingsStepFunctionName cSettings) [] declns stmts
where
Expand Down Expand Up @@ -271,8 +274,8 @@ mkStep cSettings streams triggers exts =
-- 2. Assigning a struct to a temporary variable defensively ensures that
-- any modifications that the handler called makes to the struct argument
-- will not affect the internals of the monitoring code.
mkTriggerCheck :: Trigger -> ([C.Decln], C.Stmt)
mkTriggerCheck (Trigger name _guard args) =
mkTriggerCheck :: UniqueTrigger -> ([C.Decln], C.Stmt)
mkTriggerCheck (UniqueTrigger uniqueName (Trigger name _guard args)) =
(aTmpDeclns, triggerCheckStmt)
where
aTmpDeclns :: [C.Decln]
Expand All @@ -285,12 +288,14 @@ mkStep cSettings streams triggers exts =
triggerCheckStmt :: C.Stmt
triggerCheckStmt = C.If guard' fireTrigger
where
guard' = C.Funcall (C.Ident $ guardName name) []
guard' = C.Funcall (C.Ident $ guardName uniqueName) []

-- The body of the if-statement. This consists of statements that
-- assign the values of the temporary variables, following by a
-- final statement that passes the temporary variables to the
-- handler function.
-- Note that we call 'name' here instead of 'uniqueName', as 'name'
-- is the name of the actual external function.
fireTrigger = map C.Expr argAssigns
++ [C.Expr $
C.Funcall (C.Ident name)
Expand All @@ -305,7 +310,7 @@ mkStep cSettings streams triggers exts =
updateVar aTempName aArgName ty

aArgNames :: [C.Ident]
aArgNames = take (length args) (argNames name)
aArgNames = take (length args) (argNames uniqueName)

-- Build an expression to pass a temporary variable as argument
-- to a trigger handler.
Expand All @@ -323,7 +328,7 @@ mkStep cSettings streams triggers exts =
_ -> C.Ident aTempName

aTempNames :: [String]
aTempNames = take (length args) (argTempNames name)
aTempNames = take (length args) (argTempNames uniqueName)

-- * Auxiliary functions

Expand Down

0 comments on commit b740830

Please sign in to comment.