diff --git a/gen/generators/assembly.py b/gen/generators/assembly.py index 04bd0ff1..420dda7a 100644 --- a/gen/generators/assembly.py +++ b/gen/generators/assembly.py @@ -15,6 +15,7 @@ "assembly/name.ads", "assembly/name.adb", "assembly/name.dot", + "assembly/name_components.ads", "assembly/name_commands.ads", "assembly/name_data_products.ads", "assembly/name_data_dependencies.ads", diff --git a/gen/models/assembly.py b/gen/models/assembly.py index 24bc44e7..553b4fcb 100644 --- a/gen/models/assembly.py +++ b/gen/models/assembly.py @@ -388,6 +388,8 @@ def load(self): # file: if "with" in self.data and self.data["with"]: self.includes = list(self.data["with"]) + if "with_adb" in self.data and self.data["with_adb"]: + self.adb_includes = list(self.data["with_adb"]) for include in self.includes: include = ada.formatType(include) if "preamble" in self.data: @@ -607,6 +609,7 @@ def load(self): self.interrupt_list = None # list of interrupts in assembly self.ads_includes = [] self.adb_includes = [] + self.components_ads_includes = [] self.task_dict = {} # Tasks indexed by priority self.task_list = [] # Tasks in order of task number (and priority rank) self.entity_dict = ( @@ -908,7 +911,18 @@ def load_subassembly(name): self.interrupt_list = sorted_interrupts # Store all includes for the assembly: - self.ads_includes.extend( + self.adb_includes.extend( + list( + OrderedDict.fromkeys( + [self.name + "_Components"] + + (["Ada.Synchronous_Task_Control"] + if self.task_list + else []) + ) + ) + ) + self.adb_includes = list(OrderedDict.fromkeys(self.adb_includes)) + self.components_ads_includes.extend( list( OrderedDict.fromkeys( ["Task_Types", "Interrupt_Types"] @@ -929,17 +943,11 @@ def load_subassembly(name): ] ) + (self.generic_type_includes) - + (self.includes) ) ) ) - self.ads_includes = list(OrderedDict.fromkeys(self.ads_includes)) - - # Store all includes for the assembly: - self.adb_includes.extend( - [inc for inc in self.adb_includes if inc not in self.ads_includes] - ) - self.adb_includes = list(OrderedDict.fromkeys(self.adb_includes)) + self.components_ads_includes = list(OrderedDict.fromkeys(self.components_ads_includes)) + self.includes = list(OrderedDict.fromkeys(self.includes)) # Now generate all entity ids each component: if not self.shallow_load: diff --git a/gen/models/submodels/generic_unit.py b/gen/models/submodels/generic_unit.py index 18279f29..e430919b 100644 --- a/gen/models/submodels/generic_unit.py +++ b/gen/models/submodels/generic_unit.py @@ -66,10 +66,15 @@ def instantiate(self, type): + "'." ) - self.type = ada.formatType(type) - # Calculate type package, if one: - if not ada.isTypePrimitive(self.type): - self.type_package = ada.getPackage(self.type) + try: + # Handle integer formal parameters + self.type = str(int(type)) + except ValueError: + # Handle normal formal parameters + self.type = ada.formatType(type) + # Calculate type package, if one: + if not ada.isTypePrimitive(self.type): + self.type_package = ada.getPackage(self.type) class generic_unit(object): diff --git a/gen/schemas/assembly.yaml b/gen/schemas/assembly.yaml index b040551c..42021246 100644 --- a/gen/schemas/assembly.yaml +++ b/gen/schemas/assembly.yaml @@ -13,6 +13,11 @@ mapping: seq: - type: str required: False + # Manual "with" statements that should only appear in the .adb generation + with_adb: + seq: + - type: str + required: False # Any useful handcode to include in the .ads file can be included here. # You can think of this as inline Ada, which might be useful for declaring # custom enum types and the like. The code here is copied immediately diff --git a/gen/templates/assembly/name.adb b/gen/templates/assembly/name.adb index 0338d07d..22c889e9 100644 --- a/gen/templates/assembly/name.adb +++ b/gen/templates/assembly/name.adb @@ -9,10 +9,19 @@ {% for include in adb_includes %} with {{ include }}; {% endfor %} +{% for include in includes %} +{% if include not in adb_includes %} +pragma Warnings (Off, "unit ""{{ include }}"" is not referenced"); +with {{ include }}; +pragma Warnings (On, "unit ""{{ include }}"" is not referenced"); +{% endif %} +{% endfor %} {% endif %} package body {{ name }} is + use {{ name }}_Components; + {% if component_kind_dict["init_base"] %} procedure Init_Base is begin diff --git a/gen/templates/assembly/name.ads b/gen/templates/assembly/name.ads index 0c3beb97..174b6b23 100644 --- a/gen/templates/assembly/name.ads +++ b/gen/templates/assembly/name.ads @@ -4,29 +4,12 @@ -- Generated from {{ filename }} on {{ time }}. -------------------------------------------------------------------------------- -{% if ads_includes %} --- Includes: -pragma Warnings (Off, "with clause might be moved to body"); -{% for include in ads_includes %} -with {{ include }}; -{% endfor %} -pragma Warnings (On, "with clause might be moved to body"); - -{% endif %} -{% if prepreamble %} --- Pre-Preamble code: -{{ printMultiLine(prepreamble, '', 10000) }} -{% endif %} {% if description %} {{ printMultiLine(description, '-- ') }} {% endif %} package {{ name }} is -{% if preamble %} - - -- Preamble code: -{{ printMultiLine(preamble, ' ', 10000) }} -{% endif %} {% if components %} + ----------------------------------- -- Public Subprograms: ----------------------------------- @@ -65,102 +48,5 @@ package {{ name }} is -- component initialization has been completed and tasks have been started. procedure Set_Up_Components; -{% endif %} -{% if components %} - ----------------------------------- - -- Component Instances: - ----------------------------------- - -- Remove some reference style checking to deal with incorrect capitalization in system packages. - pragma Style_Checks ("-rn"); - -{% for component in components.values() %} -{% if component.instance_description %} -{{ printMultiLine(component.instance_description, ' -- ') }} -{% endif %} -{% macro capfirst(text) %}{{ text[0]|upper}}{{text[1:] }}{% endmacro %} -{% if component.generic %} - package {{ capfirst(component.instance_name) }}_Base_Package is new Component.{{ component.name }} ({{ component.generic.resolved_formal_parameter_call_string() }}); - package {{ capfirst(component.instance_name) }}_Package is new {{ capfirst(component.instance_name) }}_Base_Package.Implementation; -{% endif %} - {{ component.instance_name }} : aliased {% if component.generic %}{{ capfirst(component.instance_name) }}_Package{% else %}Component.{{ component.name }}.Implementation{% endif %}.Instance{% if component.discriminant.parameters %} ({{ component.discriminant.parameter_call_string() }}){% endif %}; -{% endfor %} - -{% endif %} - -- Remove some reference style checking to deal with incorrect capitalization in system packages. - pragma Style_Checks ("+rn"); - -{% if task_list %} - ----------------------------------- - -- Task Creation: - ----------------------------------- -{% for task in task_list %} - -- Instantiation of the {{ task.component_name }} component: - {{ task.component_name }}_{{ task.name }}_Task_Info : aliased Task_Types.Task_Info := ( - Number => {{ task.number }}, - Id => Ada.Task_Identification.Null_Task_Id, - -- The following is initialized by the component itself. - Priority => 0, - Stack_Address => System.Null_Address, - Stack_Size => 0, - Secondary_Stack_Address => System.Null_Address, - Secondary_Stack_Size => 0, - Secondary_Stack_Max_Usage => 0 - ); - {{ task.component_name }}_{{ task.name }}_Task_Signal : aliased Ada.Synchronous_Task_Control.Suspension_Object; - {{ task.component_name }}_{{ task.name }}_Task : Component.{% if task.name != "Active" %}{{ task.component_type }}.{% endif %}{{ task.name }}_Task ( - Task_Data => {{ task.component_name }}_{{ task.name }}_Task_Info'Access, - Class_Self => {{ task.component_name }}'Access, - Signal => {{ task.component_name }}_{{ task.name }}_Task_Signal'Access, - Pri => {{ task.priority }}, - Stack_Size => {{ task.stack_size }}, - Secondary_Stack_Size => {{ task.secondary_stack_size }} - ); - -{% endfor %} - -- List of task infos for all tasks: - Task_List : aliased Task_Types.Task_Info_List := [ -{% for task in task_list %} - -- {{ task.component_name }}.{{ task.name }}: - {{ task.number }} => {{ task.component_name }}_{{ task.name }}_Task_Info'Access{{ "," if not loop.last }} -{% endfor %} - ]; - -{% else %} - -- List of task infos for all tasks: - Task_List : aliased Task_Types.Task_Info_List := [1 .. 0 => null]; -- empty - -{% endif %} -{% if interrupt_list %} - -- Remove some reference style checking to deal with incorrect capitalization in system packages. - pragma Style_Checks ("-rn"); - - -- List of all interrupts used in the system: - Interrupt_List : aliased Interrupt_Types.Interrupt_Id_List := [ -{% for interrupt in interrupt_list %} - -- {{ interrupt.component_name }}.{{ interrupt.name }}: - {{ loop.index0 }} => {{ interrupt.id }}{{ "," if not loop.last }} -{% endfor %} - ]; - - -- Remove some reference style checking to deal with incorrect capitalization in system packages. - pragma Style_Checks ("+rn"); - -{% else %} - -- List of all interrupts used in the system: - Interrupt_List : aliased Interrupt_Types.Interrupt_Id_List := [1 .. 0 => 0]; -- empty - -{% endif %} -{% if component_kind_dict["queued"] %} - -- List of all components with positive queue sizes in the system: - Queued_Component_List : aliased Component.Component_List := [ -{% for component in component_kind_dict["queued"] %} - {{ loop.index0 }} => {{ component.instance_name }}'Access{{ "," if not loop.last }} -{% endfor %} - ]; - -{% else %} - -- List of all components with positive queue sizes in the system: - Queued_Component_List : aliased Component.Component_List := [1 .. 0 => null]; -- empty - {% endif %} end {{ name }}; diff --git a/gen/templates/assembly/name_components.ads b/gen/templates/assembly/name_components.ads new file mode 100644 index 00000000..473b65e2 --- /dev/null +++ b/gen/templates/assembly/name_components.ads @@ -0,0 +1,132 @@ +-------------------------------------------------------------------------------- +-- {{ formatType(model_name) }} {{ formatType(model_type) }} Components Spec +-- +-- Generated from {{ filename }} on {{ time }}. +-------------------------------------------------------------------------------- + +{% if components_ads_includes %} +-- Includes: +{% for include in components_ads_includes %} +with {{ include }}; +{% endfor %} +{% for include in includes %} +{% if include not in components_ads_includes %} +pragma Warnings (Off, "unit ""{{ include }}"" is not referenced"); +with {{ include }}; +pragma Warnings (On, "unit ""{{ include }}"" is not referenced"); +{% endif %} +{% endfor %} + +{% endif %} +{% if prepreamble %} +-- Pre-Preamble code: +{{ printMultiLine(prepreamble, '', 10000) }} +{% endif %} +{% if description %} +{{ printMultiLine(description, '-- ') }} +{% endif %} +package {{ name }}_Components is +{% if preamble %} + + -- Preamble code: +{{ printMultiLine(preamble, ' ', 10000) }} +{% endif %} +{% if components %} + + ----------------------------------- + -- Component Instances: + ----------------------------------- + -- Remove some reference style checking to deal with incorrect capitalization in system packages. + pragma Style_Checks ("-rn"); + +{% for component in components.values() %} +{% if component.instance_description %} +{{ printMultiLine(component.instance_description, ' -- ') }} +{% endif %} +{% macro capfirst(text) %}{{ text[0]|upper}}{{text[1:] }}{% endmacro %} +{% if component.generic %} + package {{ capfirst(component.instance_name) }}_Base_Package is new Component.{{ component.name }} ({{ component.generic.resolved_formal_parameter_call_string() }}); + package {{ capfirst(component.instance_name) }}_Package is new {{ capfirst(component.instance_name) }}_Base_Package.Implementation; +{% endif %} + {{ component.instance_name }} : aliased {% if component.generic %}{{ capfirst(component.instance_name) }}_Package{% else %}Component.{{ component.name }}.Implementation{% endif %}.Instance{% if component.discriminant.parameters %} ({{ component.discriminant.parameter_call_string() }}){% endif %}; +{% endfor %} + +{% endif %} + -- Remove some reference style checking to deal with incorrect capitalization in system packages. + pragma Style_Checks ("+rn"); + +{% if task_list %} + ----------------------------------- + -- Task Creation: + ----------------------------------- +{% for task in task_list %} + -- Instantiation of the {{ task.component_name }} component: + {{ task.component_name }}_{{ task.name }}_Task_Info : aliased Task_Types.Task_Info := ( + Number => {{ task.number }}, + Id => Ada.Task_Identification.Null_Task_Id, + -- The following is initialized by the component itself. + Priority => 0, + Stack_Address => System.Null_Address, + Stack_Size => 0, + Secondary_Stack_Address => System.Null_Address, + Secondary_Stack_Size => 0, + Secondary_Stack_Max_Usage => 0 + ); + {{ task.component_name }}_{{ task.name }}_Task_Signal : aliased Ada.Synchronous_Task_Control.Suspension_Object; + {{ task.component_name }}_{{ task.name }}_Task : Component.{% if task.name != "Active" %}{{ task.component_type }}.{% endif %}{{ task.name }}_Task ( + Task_Data => {{ task.component_name }}_{{ task.name }}_Task_Info'Access, + Class_Self => {{ task.component_name }}'Access, + Signal => {{ task.component_name }}_{{ task.name }}_Task_Signal'Access, + Pri => {{ task.priority }}, + Stack_Size => {{ task.stack_size }}, + Secondary_Stack_Size => {{ task.secondary_stack_size }} + ); + +{% endfor %} + -- List of task infos for all tasks: + Task_List : aliased Task_Types.Task_Info_List := [ +{% for task in task_list %} + -- {{ task.component_name }}.{{ task.name }}: + {{ task.number }} => {{ task.component_name }}_{{ task.name }}_Task_Info'Access{{ "," if not loop.last }} +{% endfor %} + ]; + +{% else %} + -- List of task infos for all tasks: + Task_List : aliased Task_Types.Task_Info_List := [1 .. 0 => null]; -- empty + +{% endif %} +{% if interrupt_list %} + -- Remove some reference style checking to deal with incorrect capitalization in system packages. + pragma Style_Checks ("-rn"); + + -- List of all interrupts used in the system: + Interrupt_List : aliased Interrupt_Types.Interrupt_Id_List := [ +{% for interrupt in interrupt_list %} + -- {{ interrupt.component_name }}.{{ interrupt.name }}: + {{ loop.index0 }} => {{ interrupt.id }}{{ "," if not loop.last }} +{% endfor %} + ]; + + -- Remove some reference style checking to deal with incorrect capitalization in system packages. + pragma Style_Checks ("+rn"); + +{% else %} + -- List of all interrupts used in the system: + Interrupt_List : aliased Interrupt_Types.Interrupt_Id_List := [1 .. 0 => 0]; -- empty + +{% endif %} +{% if component_kind_dict["queued"] %} + -- List of all components with positive queue sizes in the system: + Queued_Component_List : aliased Component.Component_List := [ +{% for component in component_kind_dict["queued"] %} + {{ loop.index0 }} => {{ component.instance_name }}'Access{{ "," if not loop.last }} +{% endfor %} + ]; + +{% else %} + -- List of all components with positive queue sizes in the system: + Queued_Component_List : aliased Component.Component_List := [1 .. 0 => null]; -- empty + +{% endif %} +end {{ name }}_Components;