1use crate::builder::behavior::{build_behavior_instantiation, Behavior};
3use crate::builder::component::{build_component_instantiation, Component};
4use crate::builder::design::{build_design_instantiation, Design};
5use crate::builder::goal::{build_goal_instantiation, Goal};
6use crate::builder::need::{build_need_instantiation, Need};
7use crate::builder::relation::{build_relation_instantiation, Relation};
8use crate::builder::transformation::{build_transformation_instantiation, Transformation};
9use crate::builder::variable::{
10 build_parameter_declaration, build_variable_declaration, build_variable_group_declaration,
11 Variable, VariableGroup,
12};
13use crate::builder::Stringency;
14use crate::context::Context;
15use crate::cursor::{Cursor, Error, ExhaustedSnafu, Token, UnexpectedRuleSnafu};
16use crate::diagnostics::{DiagnosticError, DiagnosticWarning};
17use crate::location::FileLocation;
18use crate::map::Map;
19use crate::parser::Rule;
20
21#[derive(Clone, Debug, Default, PartialEq)]
23pub struct ComponentDefinition {
24 pub name: Token,
26 pub loc: FileLocation,
28 pub parameters: Map<String, Variable>,
30 pub variables: Map<String, Variable>,
32 pub groups: Map<String, VariableGroup>,
34 pub relations: Map<String, Relation>,
36 pub components: Map<String, Component>,
38 pub designs: Map<String, Design>,
40 pub goals: Map<String, Goal>,
42 pub transformations: Map<String, Transformation>,
44 pub behaviors: Map<String, Behavior>,
46 pub needs: Map<String, Need>,
48}
49impl std::fmt::Display for ComponentDefinition {
50 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51 write!(f, "{}", self.name)
52 }
53}
54
55pub fn build_component_definition(
57 ctx: &mut Context,
58 component_definition: Cursor,
59) -> Result<(), Error> {
60 let mut cs = component_definition.into_inner();
61 let header = cs.req_first(Rule::component_definition_header)?;
62 let name = build_component_definition_header(ctx, header)?;
63
64 let mut def = ComponentDefinition {
65 name,
66 loc: cs.as_location(),
67 ..Default::default()
68 };
69
70 if let Some(component_definition_contents) = cs.find_first(Rule::component_definition_contents)
71 {
72 build_component_definition_contents(ctx, &mut def, component_definition_contents)?;
73 } else {
74 ctx.warn(DiagnosticWarning::ImplicitEmpty, &cs.as_location());
75 }
76
77 if let Err(dupe) = ctx.specification.components.insert(def.to_string(), def) {
78 ctx.error(DiagnosticError::DuplicateDefinition, &dupe.loc);
79 }
80
81 Ok(())
82}
83
84pub fn build_component_definition_header(
86 ctx: &mut Context,
87 component_definition_header: Cursor,
88) -> Result<Token, Error> {
89 let loc = component_definition_header.as_location();
90 for cursor in component_definition_header.into_inner() {
91 match cursor.as_rule() {
92 Rule::kw_definition_world => return Ok(cursor.into()),
93 Rule::some_name => return Ok(cursor.into()),
94 _ => (),
95 }
96 }
97 ExhaustedSnafu { loc }.fail()
98}
99
100pub fn build_component_definition_contents(
102 ctx: &mut Context,
103 def: &mut ComponentDefinition,
104 component_definition_contents: Cursor,
105) -> Result<(), Error> {
106 for c in component_definition_contents.into_inner() {
107 match c.as_rule() {
108 Rule::kw_control_empty => Ok(()),
109 Rule::parameters_section => build_parameters_section(ctx, &mut def.parameters, c),
110 Rule::variables_section => build_variables_section(ctx, &mut def.variables, c),
111 Rule::variable_groups_section => build_variable_groups_section(ctx, &mut def.groups, c),
112 Rule::relations_section => build_relations_section(ctx, &mut def.relations, c),
113 Rule::components_section => build_components_section(ctx, &mut def.components, c),
114 Rule::designs_section => build_designs_section(ctx, &mut def.designs, c),
115 Rule::goals_section => build_goals_section(ctx, &mut def.goals, c),
116 Rule::transformations_section => {
117 build_transformations_section(ctx, &mut def.transformations, c)
118 }
119 Rule::behaviors_section => build_behaviors_section(ctx, &mut def.behaviors, c),
120 Rule::needs_section => build_needs_section(ctx, &mut def.needs, c),
121 Rule::comments_section => Ok(()),
122 _ => UnexpectedRuleSnafu::from(c).fail(),
123 }?;
124 }
125 Ok(())
126}
127
128pub fn build_parameters_section(
130 ctx: &mut Context,
131 parameters: &mut Map<String, Variable>,
132 parameters_section: Cursor,
133) -> Result<(), Error> {
134 let cs = parameters_section.into_inner();
135 for parameter_declaration in cs.get_all(Rule::parameter_declaration) {
136 for parameter in build_parameter_declaration(ctx, parameter_declaration)? {
137 if let Err(dupe) = parameters.insert(parameter.to_string(), parameter) {
138 ctx.error(DiagnosticError::DuplicateDefinition, &dupe.loc);
139 }
140 }
141 }
142 Ok(())
143}
144
145pub fn build_variables_section(
147 ctx: &mut Context,
148 variables: &mut Map<String, Variable>,
149 variables_section: Cursor,
150) -> Result<(), Error> {
151 let cs = variables_section.into_inner();
152 for variable_declaration in cs.get_all(Rule::variable_declaration) {
153 for variable in build_variable_declaration(ctx, variable_declaration, false)? {
154 if let Err(dupe) = variables.insert(variable.to_string(), variable) {
155 ctx.error(DiagnosticError::DuplicateDefinition, &dupe.loc);
156 }
157 }
158 }
159 Ok(())
160}
161
162pub fn build_variable_groups_section(
164 ctx: &mut Context,
165 groups: &mut Map<String, VariableGroup>,
166 variable_groups_section: Cursor,
167) -> Result<(), Error> {
168 let cs = variable_groups_section.into_inner();
169 for variable_group_declaration in cs.get_all(Rule::variable_group_declaration) {
170 for group in build_variable_group_declaration(ctx, variable_group_declaration)? {
171 if let Err(dupe) = groups.insert(group.to_string(), group) {
172 ctx.error(DiagnosticError::DuplicateDefinition, &dupe.loc);
173 }
174 }
175 }
176 Ok(())
177}
178
179pub fn build_relations_section(
181 ctx: &mut Context,
182 relations: &mut Map<String, Relation>,
183 relations_section: Cursor,
184) -> Result<(), Error> {
185 let cs = relations_section.into_inner();
186 for relation_instantiation in cs.get_all(Rule::relation_instantiation) {
187 let inst = build_relation_instantiation(ctx, relation_instantiation)?;
188 if let Err(dupe) = relations.insert(inst.to_string(), inst) {
189 ctx.error(DiagnosticError::DuplicateDefinition, &dupe.loc);
190 }
191 }
192 Ok(())
193}
194
195pub fn build_components_section(
197 ctx: &mut Context,
198 components: &mut Map<String, Component>,
199 components_section: Cursor,
200) -> Result<(), Error> {
201 let cs = components_section.into_inner();
202 for component_instantiation in cs.get_all(Rule::component_instantiation) {
203 let inst = build_component_instantiation(ctx, component_instantiation)?;
204 if let Err(dupe) = components.insert(inst.to_string(), inst) {
205 ctx.error(DiagnosticError::DuplicateDefinition, &dupe.loc);
206 }
207 }
208 Ok(())
209}
210
211pub fn build_designs_section(
213 ctx: &mut Context,
214 designs: &mut Map<String, Design>,
215 designs_section: Cursor,
216) -> Result<(), Error> {
217 let mut cs = designs_section.into_inner();
218 let stringency: Stringency = cs
219 .req_first(Rule::kw_section_designs)
220 .map(|c| c.into_inner().into())?;
221 for design_instantiation in cs.get_all(Rule::design_instantiation) {
222 let inst = build_design_instantiation(ctx, design_instantiation, stringency.clone())?;
223 if let Err(dupe) = designs.insert(inst.to_string(), inst) {
224 ctx.error(DiagnosticError::DuplicateDefinition, &dupe.loc);
225 }
226 }
227 Ok(())
228}
229
230pub fn build_goals_section(
232 ctx: &mut Context,
233 goals: &mut Map<String, Goal>,
234 goals_section: Cursor,
235) -> Result<(), Error> {
236 let mut cs = goals_section.into_inner();
237 let stringency: Stringency = cs
238 .req_first(Rule::kw_section_goals)
239 .map(|c| c.into_inner().into())?;
240 for goal_instantiation in cs.get_all(Rule::goal_instantiation) {
241 let inst = build_goal_instantiation(ctx, goal_instantiation, stringency.clone())?;
242 if let Err(dupe) = goals.insert(inst.to_string(), inst) {
243 ctx.error(DiagnosticError::DuplicateDefinition, &dupe.loc);
244 }
245 }
246 Ok(())
247}
248
249pub fn build_transformations_section(
251 ctx: &mut Context,
252 transformations: &mut Map<String, Transformation>,
253 transformations_section: Cursor,
254) -> Result<(), Error> {
255 let mut cs = transformations_section.into_inner();
256 let stringency: Stringency = cs
257 .req_first(Rule::kw_section_transformations)
258 .map(|c| c.into_inner().into())?;
259 for transformation_instantiation in cs.get_all(Rule::transformation_instantiation) {
260 let inst = build_transformation_instantiation(
261 ctx,
262 transformation_instantiation,
263 stringency.clone(),
264 )?;
265 if let Err(dupe) = transformations.insert(inst.to_string(), inst) {
266 ctx.error(DiagnosticError::DuplicateDefinition, &dupe.loc);
267 }
268 }
269 Ok(())
270}
271
272pub fn build_behaviors_section(
274 ctx: &mut Context,
275 behaviors: &mut Map<String, Behavior>,
276 behaviors_section: Cursor,
277) -> Result<(), Error> {
278 let mut cs = behaviors_section.into_inner();
279 let stringency: Stringency = cs
280 .req_first(Rule::kw_section_behaviors)
281 .map(|c| c.into_inner().into())?;
282 for behavior_instantiation in cs.get_all(Rule::behavior_instantiation) {
283 let behavior = build_behavior_instantiation(ctx, behavior_instantiation, &stringency)?;
284 if let Err(dupe) = behaviors.insert(behavior.to_string(), behavior) {
285 ctx.error(DiagnosticError::DuplicateDefinition, &dupe.loc);
286 }
287 }
288 Ok(())
289}
290
291pub fn build_needs_section(
293 ctx: &mut Context,
294 needs: &mut Map<String, Need>,
295 needs_section: Cursor,
296) -> Result<(), Error> {
297 let cs = needs_section.into_inner();
298 for need_instantiation in cs.get_all(Rule::need_instantiation) {
299 let need = build_need_instantiation(ctx, need_instantiation)?;
300 if let Err(dupe) = needs.insert(need.to_string(), need) {
301 ctx.error(DiagnosticError::DuplicateDefinition, &dupe.loc);
302 }
303 }
304 Ok(())
305}