esl_compiler/
reference.rs

1//! References types
2//!
3//! The reference is a special type in the compiler that is used to track references to things that
4//! might not yet exist in the context. They are usually created in the builder stage and the
5//! compiler will attempt to resolve them in the checker stage by replacing them with the
6//! appropriate type.
7
8use snafu::{OptionExt, Snafu};
9
10use crate::builder::behavior::Behavior;
11use crate::builder::component::Component;
12use crate::builder::def_component::ComponentDefinition;
13use crate::builder::def_relation::{RelationDefinition, RelationParameter};
14use crate::builder::def_type::TypeDefinition;
15use crate::builder::def_verb::VerbDefinition;
16use crate::builder::goal::Goal;
17use crate::builder::need::Need;
18use crate::builder::relation::Relation;
19use crate::builder::specification::Specification;
20use crate::builder::transformation::Transformation;
21use crate::builder::variable::{Variable, VariableGroup};
22use crate::cursor::{Cursor, Token};
23
24/// Reference that is to be resolved later.
25#[derive(Clone, Debug, PartialEq)]
26pub struct Reference<K, T> {
27    pub key: K,
28    pub target: Option<T>,
29}
30impl<K, T> Reference<K, T> {
31    pub fn new(key: K) -> Self {
32        Self { key, target: None }
33    }
34}
35impl<K: Default, T> Default for Reference<K, T> {
36    fn default() -> Self {
37        Self::new(K::default())
38    }
39}
40impl<K, T> Resolved for Reference<K, T> {
41    fn is_resolved(&self) -> bool {
42        self.target.is_some()
43    }
44}
45impl<K, T> From<K> for Reference<K, T> {
46    fn from(key: K) -> Self {
47        Self { key, target: None }
48    }
49}
50impl<'a, T> From<Cursor<'a>> for Reference<Token, T> {
51    fn from(value: Cursor<'a>) -> Self {
52        Self {
53            key: value.into(),
54            target: None,
55        }
56    }
57}
58
59/// Trait that signals whether something has all it's references resolved.
60pub trait Resolved {
61    fn is_resolved(&self) -> bool {
62        false
63    }
64}
65
66/// Trait that fetches a targeted item from a specification.
67pub trait FetchTarget<'a, V>
68where
69    Self: std::fmt::Debug + Clone,
70{
71    /// Fetch a reference to the target from the specification.
72    fn fetch(&self, spec: &'a Specification) -> Result<&'a V, TargetError<Self>> {
73        self.fetch_values(spec)?
74            .get(self.index())
75            .with_context(|| TargetSnafu::from(self))
76    }
77    /// Fetch a mutable reference to the target from the specification.
78    fn fetch_mut(&self, spec: &'a mut Specification) -> Result<&'a mut V, TargetError<Self>> {
79        self.fetch_values_mut(spec)?
80            .get_mut(self.index())
81            .with_context(|| TargetSnafu::from(self))
82    }
83    /// The index to access in the selected map.
84    fn index(&self) -> usize;
85    /// Fetch the map reference containing the targeted item.
86    fn fetch_values(&self, spec: &'a Specification) -> Result<&'a [V], TargetError<Self>>;
87    /// Fetch the mutable map reference containing the targeted item.
88    fn fetch_values_mut(
89        &self,
90        spec: &'a mut Specification,
91    ) -> Result<&'a mut [V], TargetError<Self>>;
92}
93
94#[derive(Debug, Snafu)]
95#[snafu(display("Could not retrieve target from the specification: {target:?}"))]
96pub struct TargetError<T: std::fmt::Debug> {
97    target: T,
98}
99impl<T: Clone + std::fmt::Debug> From<&T> for TargetSnafu<T> {
100    fn from(value: &T) -> Self {
101        Self {
102            target: value.to_owned(),
103        }
104    }
105}
106
107/// Definition target in the specification.
108#[derive(Clone, Copy, Debug, Default, PartialEq)]
109pub struct DefinitionTarget<M: Clone + std::fmt::Debug + Default> {
110    /// Index in the specification's respective definition map.
111    pub index: usize,
112    /// Marker for which definition this is.
113    marker: M,
114}
115impl<M: Clone + std::fmt::Debug + Default> DefinitionTarget<M> {
116    pub fn new(index: usize) -> Self {
117        Self {
118            index,
119            ..Default::default()
120        }
121    }
122}
123
124#[derive(Clone, Copy, Debug, Default, PartialEq)]
125pub struct ComponentDefinitionMarker;
126#[derive(Clone, Copy, Debug, Default, PartialEq)]
127pub struct RelationDefinitionMarker;
128#[derive(Clone, Copy, Debug, Default, PartialEq)]
129pub struct TypeDefinitionMarker;
130#[derive(Clone, Copy, Debug, Default, PartialEq)]
131pub struct VerbDefinitionMarker;
132
133/// Index target inside a definition. The correct container should be selected based on the type
134/// alias.
135#[derive(Clone, Copy, Debug, Default, PartialEq)]
136pub struct IndexTarget<D: Clone + std::fmt::Debug + Default, M: Clone + std::fmt::Debug + Default> {
137    /// Index in the specification's respective definition map.
138    pub definition: DefinitionTarget<D>,
139    /// Index in the specification's respective definition map.
140    pub index: usize,
141    /// Marker for what map to access inside the definition.
142    marker: M,
143}
144impl<D: Clone + std::fmt::Debug + Default, M: Clone + std::fmt::Debug + Default> IndexTarget<D, M> {
145    pub fn new(definition: usize, index: usize) -> Self {
146        Self {
147            definition: DefinitionTarget::new(definition),
148            index,
149            ..Default::default()
150        }
151    }
152    pub fn with_definition(definition: DefinitionTarget<D>, index: usize) -> Self {
153        Self {
154            definition,
155            index,
156            ..Default::default()
157        }
158    }
159}
160#[derive(Clone, Copy, Debug, Default, PartialEq)]
161pub struct RequiringParameterMarker;
162#[derive(Clone, Copy, Debug, Default, PartialEq)]
163pub struct RelatingParameterMarker;
164#[derive(Clone, Copy, Debug, Default, PartialEq)]
165pub struct ReturningParameterMarker;
166#[derive(Clone, Copy, Debug, Default, PartialEq)]
167pub struct ComponentMarker;
168#[derive(Clone, Copy, Debug, Default, PartialEq)]
169pub struct VariableMarker;
170#[derive(Clone, Copy, Debug, Default, PartialEq)]
171pub struct ParameterMarker;
172#[derive(Clone, Copy, Debug, Default, PartialEq)]
173pub struct VariableGroupMarker;
174#[derive(Clone, Copy, Debug, Default, PartialEq)]
175pub struct RelationMarker;
176#[derive(Clone, Copy, Debug, Default, PartialEq)]
177pub struct GoalMarker;
178#[derive(Clone, Copy, Debug, Default, PartialEq)]
179pub struct TransformationMarker;
180#[derive(Clone, Copy, Debug, Default, PartialEq)]
181pub struct BehaviorMarker;
182#[derive(Clone, Copy, Debug, Default, PartialEq)]
183pub struct NeedMarker;
184
185/// Type definition target.
186pub type TypeDefinitionTarget = DefinitionTarget<TypeDefinitionMarker>;
187
188impl<'a> FetchTarget<'a, TypeDefinition> for TypeDefinitionTarget {
189    fn fetch_values(
190        &self,
191        spec: &'a Specification,
192    ) -> Result<&'a [TypeDefinition], TargetError<Self>> {
193        Ok(&spec.types.values)
194    }
195    fn fetch_values_mut(
196        &self,
197        spec: &'a mut Specification,
198    ) -> Result<&'a mut [TypeDefinition], TargetError<Self>> {
199        Ok(&mut spec.types.values)
200    }
201    fn index(&self) -> usize {
202        self.index
203    }
204}
205
206/// Verb definition target.
207pub type VerbDefinitionTarget = DefinitionTarget<VerbDefinitionMarker>;
208impl<'a> FetchTarget<'a, VerbDefinition> for VerbDefinitionTarget {
209    fn fetch_values(
210        &self,
211        spec: &'a Specification,
212    ) -> Result<&'a [VerbDefinition], TargetError<Self>> {
213        Ok(&spec.verbs.values)
214    }
215    fn fetch_values_mut(
216        &self,
217        spec: &'a mut Specification,
218    ) -> Result<&'a mut [VerbDefinition], TargetError<Self>> {
219        Ok(&mut spec.verbs.values)
220    }
221    fn index(&self) -> usize {
222        self.index
223    }
224}
225
226// // RELATION DEFINITION ELEMENTS
227
228/// Relation definition target.
229pub type RelationDefinitionTarget = DefinitionTarget<RelationDefinitionMarker>;
230impl<'a> FetchTarget<'a, RelationDefinition> for RelationDefinitionTarget {
231    fn fetch_values(
232        &self,
233        spec: &'a Specification,
234    ) -> Result<&'a [RelationDefinition], TargetError<Self>> {
235        Ok(&spec.relations.values)
236    }
237    fn fetch_values_mut(
238        &self,
239        spec: &'a mut Specification,
240    ) -> Result<&'a mut [RelationDefinition], TargetError<Self>> {
241        Ok(&mut spec.relations.values)
242    }
243    fn index(&self) -> usize {
244        self.index
245    }
246}
247
248/// Requiring parameter target inside a relation definition.
249pub type RequiringParameterTarget = IndexTarget<RelationDefinitionMarker, RequiringParameterMarker>;
250impl<'a> FetchTarget<'a, RelationParameter> for RequiringParameterTarget {
251    fn fetch_values(
252        &self,
253        spec: &'a Specification,
254    ) -> Result<&'a [RelationParameter], TargetError<Self>> {
255        let def = self
256            .definition
257            .fetch(spec)
258            .ok()
259            .with_context(|| TargetSnafu::from(self))?;
260        Ok(&def.requiring.values)
261    }
262    fn fetch_values_mut(
263        &self,
264        spec: &'a mut Specification,
265    ) -> Result<&'a mut [RelationParameter], TargetError<Self>> {
266        let def = self
267            .definition
268            .fetch_mut(spec)
269            .ok()
270            .with_context(|| TargetSnafu::from(self))?;
271        Ok(&mut def.requiring.values)
272    }
273    fn index(&self) -> usize {
274        self.index
275    }
276}
277
278/// Relating parameter target inside a relation definition.
279pub type RelatingParameterTarget = IndexTarget<RelationDefinitionMarker, RelatingParameterMarker>;
280impl<'a> FetchTarget<'a, RelationParameter> for RelatingParameterTarget {
281    fn fetch_values(
282        &self,
283        spec: &'a Specification,
284    ) -> Result<&'a [RelationParameter], TargetError<Self>> {
285        let def = self
286            .definition
287            .fetch(spec)
288            .ok()
289            .with_context(|| TargetSnafu::from(self))?;
290        Ok(&def.relating.values)
291    }
292    fn fetch_values_mut(
293        &self,
294        spec: &'a mut Specification,
295    ) -> Result<&'a mut [RelationParameter], TargetError<Self>> {
296        let def = self
297            .definition
298            .fetch_mut(spec)
299            .ok()
300            .with_context(|| TargetSnafu::from(self))?;
301        Ok(&mut def.relating.values)
302    }
303    fn index(&self) -> usize {
304        self.index
305    }
306}
307
308/// Returning parameter target inside a relation definition.
309pub type ReturningParameterTarget = IndexTarget<RelationDefinitionMarker, ReturningParameterMarker>;
310impl<'a> FetchTarget<'a, RelationParameter> for ReturningParameterTarget {
311    fn fetch_values(
312        &self,
313        spec: &'a Specification,
314    ) -> Result<&'a [RelationParameter], TargetError<Self>> {
315        let def = self
316            .definition
317            .fetch(spec)
318            .ok()
319            .with_context(|| TargetSnafu::from(self))?;
320        Ok(&def.returning.values)
321    }
322    fn fetch_values_mut(
323        &self,
324        spec: &'a mut Specification,
325    ) -> Result<&'a mut [RelationParameter], TargetError<Self>> {
326        let def = self
327            .definition
328            .fetch_mut(spec)
329            .ok()
330            .with_context(|| TargetSnafu::from(self))?;
331        Ok(&mut def.returning.values)
332    }
333    fn index(&self) -> usize {
334        self.index
335    }
336}
337
338// COMPONENT DEFINITION ELEMENTS
339
340/// Component definition target.
341pub type ComponentDefinitionTarget = DefinitionTarget<ComponentDefinitionMarker>;
342impl<'a> FetchTarget<'a, ComponentDefinition> for ComponentDefinitionTarget {
343    fn fetch_values(
344        &self,
345        spec: &'a Specification,
346    ) -> Result<&'a [ComponentDefinition], TargetError<Self>> {
347        Ok(&spec.components.values)
348    }
349    fn fetch_values_mut(
350        &self,
351        spec: &'a mut Specification,
352    ) -> Result<&'a mut [ComponentDefinition], TargetError<Self>> {
353        Ok(&mut spec.components.values)
354    }
355    fn index(&self) -> usize {
356        self.index
357    }
358}
359
360/// Component target inside a component definition.
361pub type ComponentTarget = IndexTarget<ComponentDefinitionMarker, ComponentMarker>;
362impl<'a> FetchTarget<'a, Component> for ComponentTarget {
363    fn fetch_values(&self, spec: &'a Specification) -> Result<&'a [Component], TargetError<Self>> {
364        let def = self
365            .definition
366            .fetch(spec)
367            .ok()
368            .with_context(|| TargetSnafu::from(self))?;
369        Ok(&def.components.values)
370    }
371    fn fetch_values_mut(
372        &self,
373        spec: &'a mut Specification,
374    ) -> Result<&'a mut [Component], TargetError<Self>> {
375        let def = self
376            .definition
377            .fetch_mut(spec)
378            .ok()
379            .with_context(|| TargetSnafu::from(self))?;
380        Ok(&mut def.components.values)
381    }
382    fn index(&self) -> usize {
383        self.index
384    }
385}
386
387/// Variable target inside a component definition.
388pub type VariableTarget = IndexTarget<ComponentDefinitionMarker, VariableMarker>;
389impl<'a> FetchTarget<'a, Variable> for VariableTarget {
390    fn fetch_values(&self, spec: &'a Specification) -> Result<&'a [Variable], TargetError<Self>> {
391        let def = self
392            .definition
393            .fetch(spec)
394            .ok()
395            .with_context(|| TargetSnafu::from(self))?;
396        Ok(&def.variables.values)
397    }
398    fn fetch_values_mut(
399        &self,
400        spec: &'a mut Specification,
401    ) -> Result<&'a mut [Variable], TargetError<Self>> {
402        let def = self
403            .definition
404            .fetch_mut(spec)
405            .ok()
406            .with_context(|| TargetSnafu::from(self))?;
407        Ok(&mut def.variables.values)
408    }
409    fn index(&self) -> usize {
410        self.index
411    }
412}
413
414/// Parameter target inside a component definition.
415pub type ParameterTarget = IndexTarget<ComponentDefinitionMarker, ParameterMarker>;
416impl<'a> FetchTarget<'a, Variable> for ParameterTarget {
417    fn fetch_values(&self, spec: &'a Specification) -> Result<&'a [Variable], TargetError<Self>> {
418        let def = self
419            .definition
420            .fetch(spec)
421            .ok()
422            .with_context(|| TargetSnafu::from(self))?;
423        Ok(&def.parameters.values)
424    }
425    fn fetch_values_mut(
426        &self,
427        spec: &'a mut Specification,
428    ) -> Result<&'a mut [Variable], TargetError<Self>> {
429        let def = self
430            .definition
431            .fetch_mut(spec)
432            .ok()
433            .with_context(|| TargetSnafu::from(self))?;
434        Ok(&mut def.parameters.values)
435    }
436    fn index(&self) -> usize {
437        self.index
438    }
439}
440
441/// Variable group target inside a component definition.
442pub type VariableGroupTarget = IndexTarget<ComponentDefinitionMarker, VariableGroupMarker>;
443impl<'a> FetchTarget<'a, VariableGroup> for VariableGroupTarget {
444    fn fetch_values(
445        &self,
446        spec: &'a Specification,
447    ) -> Result<&'a [VariableGroup], TargetError<Self>> {
448        let def = self
449            .definition
450            .fetch(spec)
451            .ok()
452            .with_context(|| TargetSnafu::from(self))?;
453        Ok(&def.groups.values)
454    }
455    fn fetch_values_mut(
456        &self,
457        spec: &'a mut Specification,
458    ) -> Result<&'a mut [VariableGroup], TargetError<Self>> {
459        let def = self
460            .definition
461            .fetch_mut(spec)
462            .ok()
463            .with_context(|| TargetSnafu::from(self))?;
464        Ok(&mut def.groups.values)
465    }
466    fn index(&self) -> usize {
467        self.index
468    }
469}
470
471/// Relation target inside a component definition.
472pub type RelationTarget = IndexTarget<ComponentDefinitionMarker, RelationMarker>;
473impl<'a> FetchTarget<'a, Relation> for RelationTarget {
474    fn fetch_values(&self, spec: &'a Specification) -> Result<&'a [Relation], TargetError<Self>> {
475        let def = self
476            .definition
477            .fetch(spec)
478            .ok()
479            .with_context(|| TargetSnafu::from(self))?;
480        Ok(&def.relations.values)
481    }
482    fn fetch_values_mut(
483        &self,
484        spec: &'a mut Specification,
485    ) -> Result<&'a mut [Relation], TargetError<Self>> {
486        let def = self
487            .definition
488            .fetch_mut(spec)
489            .ok()
490            .with_context(|| TargetSnafu::from(self))?;
491        Ok(&mut def.relations.values)
492    }
493    fn index(&self) -> usize {
494        self.index
495    }
496}
497
498/// Behavior requirement target inside a component definition.
499pub type BehaviorTarget = IndexTarget<ComponentDefinitionMarker, BehaviorMarker>;
500impl<'a> FetchTarget<'a, Behavior> for BehaviorTarget {
501    fn fetch_values(&self, spec: &'a Specification) -> Result<&'a [Behavior], TargetError<Self>> {
502        let def = self
503            .definition
504            .fetch(spec)
505            .ok()
506            .with_context(|| TargetSnafu::from(self))?;
507        Ok(&def.behaviors.values)
508    }
509    fn fetch_values_mut(
510        &self,
511        spec: &'a mut Specification,
512    ) -> Result<&'a mut [Behavior], TargetError<Self>> {
513        let def = self
514            .definition
515            .fetch_mut(spec)
516            .ok()
517            .with_context(|| TargetSnafu::from(self))?;
518        Ok(&mut def.behaviors.values)
519    }
520    fn index(&self) -> usize {
521        self.index
522    }
523}
524
525/// Goal requirement target inside a component definition.
526pub type GoalTarget = IndexTarget<ComponentDefinitionMarker, GoalMarker>;
527impl<'a> FetchTarget<'a, Goal> for GoalTarget {
528    fn fetch_values(&self, spec: &'a Specification) -> Result<&'a [Goal], TargetError<Self>> {
529        let def = self
530            .definition
531            .fetch(spec)
532            .ok()
533            .with_context(|| TargetSnafu::from(self))?;
534        Ok(&def.goals.values)
535    }
536    fn fetch_values_mut(
537        &self,
538        spec: &'a mut Specification,
539    ) -> Result<&'a mut [Goal], TargetError<Self>> {
540        let def = self
541            .definition
542            .fetch_mut(spec)
543            .ok()
544            .with_context(|| TargetSnafu::from(self))?;
545        Ok(&mut def.goals.values)
546    }
547    fn index(&self) -> usize {
548        self.index
549    }
550}
551
552/// Need target inside a component definition.
553pub type NeedTarget = IndexTarget<ComponentDefinitionMarker, NeedMarker>;
554impl<'a> FetchTarget<'a, Need> for NeedTarget {
555    fn fetch_values(&self, spec: &'a Specification) -> Result<&'a [Need], TargetError<Self>> {
556        let def = self
557            .definition
558            .fetch(spec)
559            .ok()
560            .with_context(|| TargetSnafu::from(self))?;
561        Ok(&def.needs.values)
562    }
563    fn fetch_values_mut(
564        &self,
565        spec: &'a mut Specification,
566    ) -> Result<&'a mut [Need], TargetError<Self>> {
567        let def = self
568            .definition
569            .fetch_mut(spec)
570            .ok()
571            .with_context(|| TargetSnafu::from(self))?;
572        Ok(&mut def.needs.values)
573    }
574    fn index(&self) -> usize {
575        self.index
576    }
577}
578
579/// Transformation requirement target inside a component definition.
580pub type TransformationTarget = IndexTarget<ComponentDefinitionMarker, TransformationMarker>;
581impl<'a> FetchTarget<'a, Transformation> for TransformationTarget {
582    fn fetch_values(
583        &self,
584        spec: &'a Specification,
585    ) -> Result<&'a [Transformation], TargetError<Self>> {
586        let def = self
587            .definition
588            .fetch(spec)
589            .ok()
590            .with_context(|| TargetSnafu::from(self))?;
591        Ok(&def.transformations.values)
592    }
593    fn fetch_values_mut(
594        &self,
595        spec: &'a mut Specification,
596    ) -> Result<&'a mut [Transformation], TargetError<Self>> {
597        let def = self
598            .definition
599            .fetch_mut(spec)
600            .ok()
601            .with_context(|| TargetSnafu::from(self))?;
602        Ok(&mut def.transformations.values)
603    }
604    fn index(&self) -> usize {
605        self.index
606    }
607}