1#![macro_use]
6
7use crate::{
8 beta::{Beta, ExportBeta},
9 form::Form,
10 name::*,
11 util::mbe::EnvMBE,
12};
13use std::{fmt, iter, rc::Rc};
14
15#[derive(Clone, PartialEq)]
17pub enum AstContents {
18 Trivial,
19 Atom(Name),
21 VariableReference(Name),
22
23 QuoteMore(Ast, bool),
25 QuoteLess(Ast, u8),
27
28 Node(std::rc::Rc<Form>, EnvMBE<Ast>, ExportBeta),
31
32 IncompleteNode(EnvMBE<Ast>),
34 Shape(Vec<Ast>),
36
37 ExtendEnv(Ast, Beta),
39 ExtendEnvPhaseless(Ast, Beta),
42}
43
44#[derive(Clone, PartialEq)]
45pub struct LocatedAst {
46 pub c: AstContents,
48 pub file_id: usize,
49 pub begin: usize,
50 pub end: usize,
51}
52
53#[derive(Clone)]
54pub struct Ast(pub Rc<LocatedAst>);
55
56impl PartialEq for Ast {
58 fn eq(&self, other: &Ast) -> bool { self.c() == other.c() }
59}
60
61impl crate::runtime::reify::Reifiable for Ast {
64 fn ty_name() -> Name { n("Ast") }
65
66 fn reify(&self) -> crate::runtime::eval::Value {
67 crate::runtime::eval::Value::AbstractSyntax(self.clone())
68 }
69
70 fn reflect(v: &crate::runtime::eval::Value) -> Ast {
71 extract!((v) crate::runtime::eval::Value::AbstractSyntax = (ref ast) => ast.clone())
72 }
73}
74
75pub use self::AstContents::*;
76
77impl fmt::Debug for Ast {
78 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:#?}", self.c()) }
79}
80
81impl fmt::Debug for AstContents {
82 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
83 match self {
84 Trivial => write!(f, "⨉"),
85 Atom(n) => write!(f, "∘{}∘", n.print()),
86 VariableReference(v) => write!(f, "{}", v.print()),
87 Shape(v) => {
88 write!(f, "(")?;
89 let mut first = true;
90 for elt in v {
91 if !first {
92 write!(f, " ")?
93 }
94 elt.fmt(f)?;
95 first = false;
96 }
97 write!(f, ")")
98 }
99 Node(form, body, export) => {
100 write!(f, "{{ ({}); {:#?}", form.name.sp(), body)?;
101 match *export {
102 crate::beta::ExportBeta::Nothing => {}
103 _ => write!(f, " ⇑{:#?}", export)?,
104 }
105 write!(f, "}}")
106 }
107 QuoteMore(body, pos) => {
108 if *pos {
109 write!(f, "pos``{:#?}``", body)
110 } else {
111 write!(f, "neg``{:#?}``", body)
112 }
113 }
114 QuoteLess(body, depth) => write!(f, ",,({}){:#?},,", depth, body),
115 IncompleteNode(body) => write!(f, "{{ INCOMPLETE; {:#?} }}", body),
116 ExtendEnv(body, beta) => write!(f, "{:#?}↓{:#?}", body, beta),
117 ExtendEnvPhaseless(body, beta) => write!(f, "{:#?}±↓{:#?}", body, beta),
118 }
119 }
120}
121
122impl fmt::Display for Ast {
124 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.c()) }
125}
126
127impl fmt::Display for AstContents {
128 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
129 match self {
130 Atom(ref n) => write!(f, "{}", n.print()),
131 VariableReference(ref v) => write!(f, "{}", v.print()),
132 Node(ref form, ref body, _) => {
133 let s = crate::unparse::unparse_mbe(
134 &form.grammar,
135 self,
136 body,
137 &crate::core_forms::get_core_forms(),
138 );
139 write!(f, "{}", s)
140 }
141 Shape(ref v) => {
142 write!(f, "(")?;
143 let mut first = true;
144 for elt in v {
145 if !first {
146 write!(f, " ")?
147 }
148 elt.fmt(f)?;
149 first = false;
150 }
151 write!(f, ")")
152 }
153 ExtendEnv(ref body, _) => write!(f, "{}↓", body),
154 ExtendEnvPhaseless(ref body, _) => write!(f, "{}±↓", body),
155 QuoteMore(body, _) => {
156 write!(f, "``{}``", body)
157 }
158 QuoteLess(body, _) => write!(f, ",,{},,", body),
159 _ => write!(f, "{:#?}", self),
160 }
161 }
162}
163
164impl Ast {
165 pub fn c(&self) -> &AstContents { &self.0.c }
167
168 pub fn c_map(&self, f: &dyn Fn(&AstContents) -> AstContents) -> Ast { self.with_c(f(self.c())) }
170
171 pub fn with_c(&self, c: AstContents) -> Ast {
173 Ast(Rc::new(LocatedAst {
174 c: c,
175 file_id: self.0.file_id,
176 begin: self.0.begin,
177 end: self.0.end,
178 }))
179 }
180
181 pub fn flatten(&self) -> EnvMBE<Ast> {
183 match self.c() {
184 Trivial | Atom(_) => EnvMBE::new(),
185 VariableReference(_) => EnvMBE::new(),
186 Shape(ref v) => {
187 let mut accum = EnvMBE::new();
188 for sub_a in v {
189 accum = accum.combine_overriding(&sub_a.flatten())
190 }
191 accum
192 }
193 IncompleteNode(ref env) => env.clone(),
194 Node(ref _f, ref _body, ref _export) => {
195 panic!("I don't know what to do with {:#?}!", self)
198 }
199 QuoteMore(ref body, _) => body.flatten(),
200 QuoteLess(ref body, _) => body.flatten(),
201 ExtendEnv(ref body, _) | ExtendEnvPhaseless(ref body, _) => body.flatten(),
202 }
203 }
204
205 pub fn destructure(
207 &self,
208 expd_form: std::rc::Rc<Form>,
209 ) -> Option<crate::util::mbe::EnvMBE<Ast>> {
210 if let Node(ref f, ref parts, _) = self.c() {
211 if f == &expd_form {
212 return Some(parts.clone());
213 }
214 }
215 None
216 }
217
218 pub fn is_node(&self) -> bool {
219 match self.c() {
220 Node(_, _, _) => true,
221 _ => false,
222 }
223 }
224
225 pub fn node_parts(&self) -> &EnvMBE<Ast> {
227 match self.c() {
228 Node(_, ref body, _) => body,
229 _ => icp!(),
230 }
231 }
232
233 pub fn maybe_node_parts(&self) -> Option<&EnvMBE<Ast>> {
234 match self.c() {
235 Node(_, ref body, _) => Some(body),
236 _ => None,
237 }
238 }
239
240 pub fn node_form(&self) -> &Form {
241 match self.c() {
242 Node(ref form, _, _) => form,
243 _ => icp!(),
244 }
245 }
246
247 pub fn free_vrs(&self) -> Vec<Name> {
248 match self.c() {
249 Trivial | Atom(_) => vec![],
250 VariableReference(v) => vec![*v],
251 Shape(_) | IncompleteNode(_) => unimplemented!("TODO"),
252 QuoteLess(_, _) | QuoteMore(_, _) => unimplemented!("TODO"),
253 ExtendEnv(_, _) | ExtendEnvPhaseless(_, _) => unimplemented!("TODO"),
257 Node(_, ref body, _) => body.map_reduce(
258 &|a| a.free_vrs(),
259 &|v0, v1| {
260 let mut res = v0.clone();
261 res.append(&mut v1.clone());
262 res
263 },
264 vec![],
265 ),
266 }
267 }
268
269 pub fn to_name(&self) -> Name {
270 match self.c() {
271 Atom(n) => *n,
272 _ => icp!("{:#?} is not an atom", self),
273 }
274 }
275
276 pub fn vr_to_name(&self) -> Name {
277 match self.c() {
278 VariableReference(n) => *n,
279 _ => icp!("{:#?} is not an atom", self),
280 }
281 }
282
283 pub fn orig_str<'a, 'b>(&'a self, prog: &'b str) -> &'b str { &prog[self.0.begin..self.0.end] }
284}
285
286impl iter::FromIterator<Ast> for Ast {
288 fn from_iter<I: IntoIterator<Item = Ast>>(i: I) -> Self {
289 raw_ast!(IncompleteNode(EnvMBE::new_from_anon_repeat(
290 i.into_iter().map(|a| a.flatten()).collect()
291 )))
292 }
293}
294
295#[test]
303fn combine_from_kleene_star() {
304 use std::iter::FromIterator;
305
306 let parse_parts = vec![
307 ast!({ - "b" => "8.0"}),
308 ast!({ - "a" => ["1", "2"], "b" => "8.1"}),
309 ast!({ - "a" => ["1", "2", "3"], "b" => "8.2"}),
310 ];
311 let parsed = Ast::from_iter(parse_parts);
312
313 let mut expected_mbe = mbe!("a" => [@"triple" [], ["1", "2"], ["1", "2", "3"]],
314 "b" => [@"triple" "8.0", "8.1", "8.2"]);
315 expected_mbe.anonimize_repeat(n("triple"));
316
317 assert_eq!(parsed.c(), &IncompleteNode(expected_mbe));
318}
319
320#[test]
321fn star_construction() {
322 let env = mbe!( "a" => ["1", "2"]);
323
324 assert_eq!(
325 ast!( { - "x" => [* env =>("a") env : (, env.get_leaf_or_panic(&n("a")).clone())]} ),
326 ast!( { - "x" => ["1", "2"] })
327 );
328
329 let env = mbe!( "a" => [@"duo" "1", "2"], "b" => [@"duo" "11", "22"]);
330
331 assert_eq!(
332 ast!( { - "x" => [* env =>("a", "b") env :
333 ((, env.get_leaf_or_panic(&n("b")).clone())
334 (, env.get_leaf_or_panic(&n("a")).clone()))]} ),
335 ast!( { - "x" => [("11" "1"), ("22" "2")] })
336 );
337}
338
339#[test]
340fn mbe_r_and_r_roundtrip() {
341 use crate::runtime::reify::Reifiable;
342 let mbe1 = mbe!( "a" => [@"duo" "1", "2"], "b" => [@"duo" "11", "22"]);
343 assert_eq!(mbe1, EnvMBE::<Ast>::reflect(&mbe1.reify()));
344}