Code Generation

This section contains an outline of recommendations to ensure that Coco code can be easily integrated into existing C++ projects. For details on how to generate code for a specific language, see the language-specific guides:

Structuring Systems

To easily use the resulting generated code, it is best to:

  1. Define your overall system in Coco using an encapsulating component.
  2. Create external components for each of the provided or required ports of your encapsulating components. These correspond to:
    • In the case of provided ports, code that will make use of the Coco-generated code either by calling functions, or receiving functions over the provided port.
    • In the case of required ports, code that either sends signals to the Coco-generated code, or the Coco-generated code will make use of by calling functions on it.
  3. Create a top-level encapsulating component that has no provided or required ports. Such encapsulating components are known as sealed encapsulating components.

This approach has several advantages:

  • Coco will ensure that the components are all connected correctly and are obeying all of the Coco rules about how components must be connected.
  • The generated code will contain easy-to-integrate hooks for both code at the top and at the bottom of your system. Generally speaking, the code generators provide easier-to-use hooks for interacting with Coco-generated code via external components than directly via ports.

For example, suppose the overall encapsulating component from (1) is:

component System {
  client : Provided<PTopLevel>;
  bottom : Required<PBottom>;
}

Then, as part of (2) you would define:

external component User {
  system : Required<PTopLevel>;
}

external component Bottom {
  bottom : Provided<PBottom>;
}

Using this, (3) can be defined as:

component CombinedSystem {
  user : User;
  system : System;
  bottom : Bottom;

  init() = {
    connect(user.system, system.client);
    connect(system.bottom, bottom.bottom);
  }
}