1
use core::fmt;
2

            
3
use crate::aterm::ATerm;
4
use crate::aterm::ATermRef;
5
use mcrl2_macros::mcrl2_derive_terms;
6
use mcrl2_sys::data::ffi;
7

            
8
pub fn is_sort_expression(term: &ATermRef<'_>) -> bool {
9
    term.require_valid();
10
    unsafe { ffi::is_data_sort_expression(term.get()) }
11
}
12

            
13
pub fn is_bool_sort(term: &ATermRef<'_>) -> bool {
14
    term.require_valid();
15
    true
16
}
17

            
18
pub fn is_basic_sort(term: &ATermRef<'_>) -> bool {
19
    term.require_valid();
20
    unsafe { ffi::is_data_basic_sort(term.get()) }
21
}
22

            
23
pub fn is_data_function_sort(term: &ATermRef<'_>) -> bool {
24
    term.require_valid();
25
    unsafe { ffi::is_data_function_sort(term.get()) }
26
}
27

            
28
// This module is only used internally to run the proc macro.
29
#[mcrl2_derive_terms]
30
mod inner {
31
    use super::*;
32

            
33
    use std::borrow::Borrow;
34
    use std::ops::Deref;
35

            
36
    use crate::aterm::ATermList;
37
    use crate::aterm::Markable;
38
    use crate::aterm::Todo;
39
    use crate::data::DataExpression;
40
    use mcrl2_macros::mcrl2_ignore;
41
    use mcrl2_macros::mcrl2_term;
42

            
43
    #[mcrl2_term(is_bool_sort)]
44
    pub struct BoolSort {
45
        pub(crate) term: ATerm,
46
    }
47

            
48
    impl BoolSort {
49
        /// Returns the term representing true.
50
46503
        pub fn true_term() -> DataExpression {
51
46503
            DataExpression::from(ATerm::from(ffi::true_term()))
52
46503
        }
53

            
54
        /// Returns the term representing false.
55
        pub fn false_term() -> DataExpression {
56
            DataExpression::from(ATerm::from(ffi::false_term()))
57
        }
58
    }
59

            
60
    #[mcrl2_term(is_sort_expression)]
61
    pub struct SortExpression {
62
        term: ATerm,
63
    }
64

            
65
    impl SortExpression {
66
        /// Returns the name of the sort.
67
        pub fn name(&self) -> &str {
68
            // We only change the lifetime, but that is fine since it is derived from the current term.
69
            unsafe { std::mem::transmute(self.term.arg(0).get_head_symbol().name()) }
70
        }
71

            
72
        /// Returns true iff this is a basic sort
73
        pub fn is_basic_sort(&self) -> bool {
74
            is_basic_sort(&self.term)
75
        }
76

            
77
        /// Returns true iff this is a function sort
78
        pub fn is_function_sort(&self) -> bool {
79
            is_data_function_sort(&self.term)
80
        }
81
    }
82

            
83
    impl fmt::Display for SortExpression {
84
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85
            write!(f, "{}", self.name())
86
        }
87
    }
88

            
89
    #[mcrl2_term(is_basic_sort)]
90
    pub struct BasicSort {
91
        term: ATerm,
92
    }
93

            
94
    impl BasicSort {
95
        /// Returns the name of the sort.
96
        pub fn name(&self) -> &str {
97
            unsafe { std::mem::transmute(self.term.arg(0).get_head_symbol().name()) }
98
        }
99
    }
100

            
101
    /// Derived from SortExpression
102
    #[mcrl2_term(is_data_function_sort)]
103
    pub struct FunctionSort {
104
        term: ATerm,
105
    }
106

            
107
    impl FunctionSort {
108
        /// Returns the name of the sort.
109
        pub fn domain(&self) -> ATermList<SortExpression> {
110
            ATermList::<SortExpression>::from(self.term.arg(0).protect())
111
        }
112

            
113
        /// Returns the name of the sort.
114
        pub fn codomain(&self) -> SortExpression {
115
            SortExpression::from(self.term.arg(1).protect())
116
        }
117
    }
118

            
119
    #[mcrl2_ignore]
120
    impl From<SortExpression> for FunctionSort {
121
        fn from(sort: SortExpression) -> Self {
122
            Self { term: sort.term }
123
        }
124
    }
125

            
126
    #[mcrl2_ignore]
127
    impl<'a> From<SortExpressionRef<'a>> for FunctionSortRef<'a> {
128
        fn from(sort: SortExpressionRef<'a>) -> Self {
129
            unsafe { std::mem::transmute(sort) }
130
        }
131
    }
132
}
133

            
134
pub use inner::*;