1use crate::{
2 anon::Anon,
3 embed_error::EmbedError,
4 name::Name,
5 package::{
6 import_alias,
7 Entry,
8 Import,
9 },
10 position::Pos,
11 term::Term,
12};
13
14use sp_cid::Cid;
15
16use sp_std::{
17 collections::btree_map::BTreeMap,
18 fmt,
19 rc::Rc,
20 vec::Vec,
21};
22
23use alloc::string::{
24 String,
25 ToString,
26};
27
28#[derive(Clone, Debug)]
31pub struct Def {
32 pub pos: Pos,
33 pub def_cid: Cid,
34 pub ast_cid: Cid,
35 pub typ_: Term,
36 pub term: Term,
37}
38
39impl PartialEq for Def {
40 fn eq(&self, other: &Def) -> bool {
41 self.def_cid == other.def_cid
42 && self.ast_cid == other.ast_cid
43 && self.typ_ == other.typ_
44 && self.term == other.term
45 }
46}
47
48#[derive(PartialEq, Clone, Debug)]
50pub struct Defs {
51 pub defs: BTreeMap<Cid, Def>,
52 pub names: BTreeMap<Name, Cid>,
53}
54
55impl Def {
56 pub fn make(pos: Pos, typ_: Term, term: Term) -> (Self, Entry) {
58 let (type_anon, type_meta) = typ_.embed();
59 let (term_anon, term_meta) = term.embed();
60 let ast_cid = term_anon.cid();
61 let defn = Entry {
62 pos,
63 type_anon: type_anon.cid(),
64 type_meta,
65 term_anon: ast_cid,
66 term_meta,
67 };
68 let def = Def { pos, def_cid: defn.cid(), ast_cid, typ_, term };
69 (def, defn)
70 }
71
72 pub fn embed(&self) -> (Entry, Anon, Anon) {
74 let (type_anon, type_meta) = self.typ_.embed();
75 let (term_anon, term_meta) = self.term.embed();
76 let d = Entry {
77 pos: self.pos,
78 type_anon: type_anon.cid(),
79 term_anon: self.ast_cid,
80 type_meta,
81 term_meta,
82 };
83 (d, type_anon, term_anon)
84 }
85
86 pub fn unembed(
88 def: Entry,
89 type_anon: Anon,
90 term_anon: Anon,
91 ) -> Result<Self, EmbedError> {
92 let typ_ = Term::unembed(&type_anon, &def.type_meta)?;
93 let term = Term::unembed(&term_anon, &def.term_meta)?;
94 Ok(Def {
95 pos: def.pos,
96 def_cid: def.cid(),
97 ast_cid: def.term_anon,
98 typ_,
99 term,
100 })
101 }
102
103 pub fn pretty(&self, name: String, ind: bool) -> String {
105 format!(
106 "def {} : {} = {}",
107 name,
108 self.typ_.pretty(Some(&name), ind),
109 self.term.pretty(Some(&name), ind)
110 )
111 }
112}
113
114impl Defs {
115 pub fn new() -> Self {
117 Defs { defs: BTreeMap::new(), names: BTreeMap::new() }
118 }
119
120 pub fn names(&self) -> Vec<Name> {
122 self.names.keys().cloned().collect()
123 }
124
125 pub fn named_defs(&self) -> Vec<(Name, Def)> {
127 let mut res = Vec::new();
128 for (n, cid) in &self.names {
129 res.push((n.clone(), self.defs.get(cid).unwrap().clone()))
130 }
131 res
132 }
133
134 pub fn insert(&mut self, name: Name, def: Def) -> Option<Def> {
136 self.names.insert(name, def.def_cid);
137 self.defs.insert(def.def_cid, def)
138 }
139
140 pub fn get(&self, name: &Name) -> Option<&Def> {
142 let def_cid = self.names.get(name)?;
143 self.defs.get(def_cid)
144 }
145
146 pub fn merge(self, other: Defs, import: &Import) -> Self {
148 let mut defs = self.defs;
149 for (k, v) in other.defs {
150 defs.insert(k, v);
151 }
152 let mut names = self.names;
153 for k in import.with.iter() {
154 let k = k.clone();
155 let v = other.names.get(&k).unwrap();
156 names.insert(import_alias(k, import), *v);
157 }
158 Defs { defs, names }
159 }
160
161 pub fn flat_merge_mut(&mut self, other: Rc<Defs>) {
163 for (k, v) in other.defs.iter() {
164 self.defs.insert(*k, v.clone());
165 }
166 for (k, v) in other.names.iter() {
167 self.names.insert(k.clone(), *v);
168 }
169 }
170
171 pub fn flat_merge(self, other: Defs) -> Self {
173 let mut defs = self.defs;
174 for (k, v) in other.defs {
175 defs.insert(k, v);
176 }
177 let mut names = self.names;
178 for (k, v) in other.names.iter() {
179 names.insert(k.clone(), *v);
180 }
181 Defs { defs, names }
182 }
183}
184
185impl Default for Defs {
186 fn default() -> Self { Self::new() }
187}
188
189impl fmt::Display for Def {
190 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
191 write!(f, "{}", self.pretty("#^".to_string(), false))
192 }
193}
194impl fmt::Display for Defs {
195 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
196 for (k, v) in &self.names {
197 let def = self.defs.get(v).unwrap();
198 writeln!(f, "{}:", def.def_cid)?;
199 writeln!(
200 f,
201 "def {} : {} = {}",
202 k.clone(),
203 def.typ_.pretty(Some(&k.to_string()), false),
204 def.term.pretty(Some(&k.to_string()), false),
205 )?;
206 writeln!(f)?;
207 }
208 Ok(())
209 }
210}
211
212#[cfg(test)]
213pub mod tests {
214 use super::*;
215 use crate::term::tests::{
216 arbitrary_term,
217 test_defs,
218 };
219 use quickcheck::{
220 Arbitrary,
221 Gen,
222 };
223 use sp_im::Vector;
224
225 pub fn arbitrary_def(g: &mut Gen) -> (Def, Entry) {
226 let typ_: Term = Arbitrary::arbitrary(g);
227 let term = arbitrary_term(g, true, test_defs(), Vector::new());
228 Def::make(Pos::None, typ_, term)
229 }
230
231 impl Arbitrary for Def {
232 fn arbitrary(g: &mut Gen) -> Self { arbitrary_def(g).0 }
233 }
234
235 #[quickcheck]
236 fn def_embed_unembed(x: Def) -> bool {
237 let (d, ta, xa) = x.clone().embed();
238 match Def::unembed(d, ta, xa) {
239 Ok(y) => {
240 if x == y {
241 true
242 }
243 else {
244 false
247 }
248 }
249 _e => {
250 false
255 }
256 }
257 }
258}