Skip to content

Commit

Permalink
Merge pull request #89 from dinkelk/generic-circ-dep
Browse files Browse the repository at this point in the history
Refactor assembly autocode output
  • Loading branch information
dinkelk authored Nov 19, 2024
2 parents eb6408f + a420b1d commit 1d9d0b1
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 128 deletions.
1 change: 1 addition & 0 deletions gen/generators/assembly.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
26 changes: 17 additions & 9 deletions gen/models/assembly.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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 = (
Expand Down Expand Up @@ -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"]
Expand All @@ -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:
Expand Down
13 changes: 9 additions & 4 deletions gen/models/submodels/generic_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
5 changes: 5 additions & 0 deletions gen/schemas/assembly.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions gen/templates/assembly/name.adb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
116 changes: 1 addition & 115 deletions gen/templates/assembly/name.ads
Original file line number Diff line number Diff line change
Expand Up @@ -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:
-----------------------------------
Expand Down Expand Up @@ -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 }};
132 changes: 132 additions & 0 deletions gen/templates/assembly/name_components.ads
Original file line number Diff line number Diff line change
@@ -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;

0 comments on commit 1d9d0b1

Please sign in to comment.