conjure_core/
representation.rs

1use std::collections::BTreeMap;
2
3use core::fmt::Debug;
4use linkme::distributed_slice;
5
6//TODO: write good documentation on this! ~niklasdewally
7
8use crate::{
9    ast::{Declaration, Expression, Literal, Name, SymbolTable},
10    rule_engine::ApplicationError,
11};
12
13#[distributed_slice]
14#[doc(hidden)]
15pub static REPRESENTATION_RULES: [RepresentationRule];
16
17#[doc(hidden)]
18pub struct RepresentationRule {
19    pub name: &'static str,
20    pub init: fn(&Name, &SymbolTable) -> Option<Box<dyn Representation>>,
21}
22
23/// Gets the representation rule named `name`.
24#[allow(clippy::type_complexity)]
25pub fn get_repr_rule(
26    name: &str,
27) -> Option<fn(&Name, &SymbolTable) -> Option<Box<dyn Representation>>> {
28    REPRESENTATION_RULES
29        .iter()
30        .find(|x| x.name == name)
31        .map(|x| x.init)
32}
33
34#[macro_export]
35macro_rules! register_represention {
36    ($ruleType:ident, $ruleName:literal) => {
37        paste::paste!{
38        #[linkme::distributed_slice($crate::representation::REPRESENTATION_RULES)]
39        pub static [<__ $ruleType:snake:upper _REPRESENTATION_RULE>]: $crate::representation::RepresentationRule = $crate::representation::RepresentationRule {
40            name: $ruleName,
41            init: [<__create_representation_ $ruleType:snake>]
42        };
43
44
45        fn [<__create_representation_ $ruleType:snake>] (name: &$crate::ast::Name, symtab: &$crate::ast::SymbolTable) -> Option<Box<dyn Representation>>  {
46                $ruleType::init(name,symtab).map(|x| Box::new(x) as Box<dyn Representation>)
47            }
48        }
49    };
50}
51
52// This alongside Representation::box_clone() allows Representation to be a trait-object but still
53// cloneable.
54impl Clone for Box<dyn Representation> {
55    fn clone(&self) -> Self {
56        self.box_clone()
57    }
58}
59
60pub trait Representation: Send + Sync + Debug {
61    /// Creates a representation object for the given name.
62    fn init(name: &Name, symtab: &SymbolTable) -> Option<Self>
63    where
64        Self: Sized;
65
66    /// The variable being represented.
67    fn variable_name(&self) -> &Name;
68
69    /// Given an assignment for `self`, creates assignments for its representation variables.
70    fn value_down(&self, value: Literal) -> Result<BTreeMap<Name, Literal>, ApplicationError>;
71
72    /// Given assignments for its representation variables, creates an assignment for `self`.
73    fn value_up(&self, values: &BTreeMap<Name, Literal>) -> Result<Literal, ApplicationError>;
74
75    /// Returns [`Expression`]s representing each representation variable.
76    fn expression_down(
77        &self,
78        symtab: &SymbolTable,
79    ) -> Result<BTreeMap<Name, Expression>, ApplicationError>;
80
81    /// Creates [`Declaration`]s for the representation variables of `self`.
82    fn declaration_down(&self) -> Result<Vec<Declaration>, ApplicationError>;
83
84    /// The rule name for this representaion.
85    fn repr_name(&self) -> &str;
86
87    /// Makes a clone of `self` into a `Representation` trait object.
88    fn box_clone(&self) -> Box<dyn Representation>;
89}