mcrl2/aterm/
symbol.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
use std::borrow::Borrow;
use std::marker::PhantomData;

use std::cmp::Ordering;
use std::fmt;
use std::hash::Hash;
use std::hash::Hasher;
use std::ops::Deref;

use mcrl2_sys::atermpp::ffi::{self};

#[derive(Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct SymbolRef<'a> {
    symbol: *const ffi::_function_symbol,
    marker: PhantomData<&'a ()>,
}

/// A Symbol references to an aterm function symbol, which has a name and an arity.
impl<'a> SymbolRef<'a> {
    fn new(symbol: *const ffi::_function_symbol) -> SymbolRef<'a> {
        SymbolRef {
            symbol,
            marker: PhantomData,
        }
    }

    pub fn protect(&self) -> Symbol {
        Symbol::new(self.symbol)
    }

    pub fn copy(&self) -> SymbolRef<'_> {
        SymbolRef::new(self.symbol)
    }
}

impl SymbolRef<'_> {
    /// Obtain the symbol's name
    pub fn name(&self) -> &str {
        unsafe { ffi::get_function_symbol_name(self.symbol) }
    }

    /// Obtain the symbol's arity
    pub fn arity(&self) -> usize {
        unsafe { ffi::get_function_symbol_arity(self.symbol) }
    }

    /// Returns the index of the function symbol
    pub fn address(&self) -> *const ffi::_function_symbol {
        self.symbol
    }
}

impl fmt::Display for SymbolRef<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.name())
    }
}

impl fmt::Debug for SymbolRef<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}:{} [{}]", self.name(), self.arity(), self.address() as usize,)
    }
}

impl From<*const ffi::_function_symbol> for SymbolRef<'_> {
    fn from(symbol: *const ffi::_function_symbol) -> Self {
        SymbolRef {
            symbol,
            marker: PhantomData,
        }
    }
}

pub struct Symbol {
    symbol: SymbolRef<'static>,
}

impl Symbol {
    /// Takes ownership of the given pointer without changing the reference counter.
    pub(crate) fn take(symbol: *const ffi::_function_symbol) -> Symbol {
        Symbol {
            symbol: SymbolRef::new(symbol),
        }
    }

    /// Protects the given pointer.
    pub(crate) fn new(symbol: *const ffi::_function_symbol) -> Symbol {
        unsafe { ffi::protect_function_symbol(symbol) };
        Symbol {
            symbol: SymbolRef::new(symbol),
        }
    }
}

impl Drop for Symbol {
    fn drop(&mut self) {
        unsafe { ffi::drop_function_symbol(self.symbol.symbol) };
    }
}

impl Symbol {
    pub fn copy(&self) -> SymbolRef<'_> {
        self.symbol.copy()
    }
}

impl From<&SymbolRef<'_>> for Symbol {
    fn from(value: &SymbolRef) -> Self {
        value.protect()
    }
}

impl Clone for Symbol {
    fn clone(&self) -> Self {
        self.copy().protect()
    }
}

impl Deref for Symbol {
    type Target = SymbolRef<'static>;

    fn deref(&self) -> &Self::Target {
        &self.symbol
    }
}

impl fmt::Display for Symbol {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.name())
    }
}

impl fmt::Debug for Symbol {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.name())
    }
}

impl Hash for Symbol {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.copy().hash(state)
    }
}

impl PartialEq for Symbol {
    fn eq(&self, other: &Self) -> bool {
        self.copy().eq(&other.copy())
    }
}

impl PartialOrd for Symbol {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.copy().cmp(&other.copy()))
    }
}

impl Ord for Symbol {
    fn cmp(&self, other: &Self) -> Ordering {
        self.copy().cmp(&other.copy())
    }
}

impl Borrow<SymbolRef<'static>> for Symbol {
    fn borrow(&self) -> &SymbolRef<'static> {
        &self.symbol
    }
}

impl Eq for Symbol {}