1use std::fmt::Debug;
11use crate::adapton::reflect::{Loc,Path,Val,ArtContent,Const};
12use crate::adapton::engine::{Name, name_of_str, name_of_string};
13
14#[derive(Debug, Eq, PartialEq)]
17enum BalTok {
18 Paren,
19 Bracket,
20 Brace
21}
22
23#[derive(Debug, Eq, PartialEq)]
26enum Tok {
27 Left(BalTok),
29 Right(BalTok),
31 Const(Const),
33 Ident(String),
35 Colon,
37 Comma,
39}
40
41
42pub fn parse_val <V:Debug> (v:&V) -> Val {
60 let s = format!("{:?}", v);
61 let toks = lex(s.into_bytes());
63 parse_toks(toks)
65}
66
67fn lex (mut chars: Vec<u8>) -> Vec<Tok> {
69 let mut toks = vec![];
70 chars.reverse(); loop {
72 match chars.pop() {
73 None => return toks,
74 Some(c) => {
75 let c : char = c as char ;
76 if c == ' ' { continue }
77 else if c == ':' { toks.push(Tok::Colon); continue }
78 else if c == ',' { toks.push(Tok::Comma); continue }
79 else if c == '{' { toks.push(Tok::Left (BalTok::Brace)); continue }
80 else if c == '[' { toks.push(Tok::Left (BalTok::Bracket)); continue }
81 else if c == '(' { toks.push(Tok::Left (BalTok::Paren)); continue }
82 else if c == '}' { toks.push(Tok::Right(BalTok::Brace)); continue }
83 else if c == ']' { toks.push(Tok::Right(BalTok::Bracket)); continue }
84 else if c == ')' { toks.push(Tok::Right(BalTok::Paren)); continue }
85 else if c == '"' {
86 let mut string_chars = vec![];
87 loop {
88 match chars.pop() {
89 None => break,
90 Some(c) => {
91 let c : char = c as char ;
92 if c == '"' { break } else {
93 string_chars.push(c);
94 continue
95 }
96 }
97 }
98 };
99 toks.push(Tok::Const(Const::String(
100 string_chars.into_iter().collect()
101 )));
102 continue
103 }
104 else if c == '-' || (c >= '0' && c <= '9') {
105 let mut digs = vec![c];
106 loop {
107 match chars.pop() {
108 None => break,
109 Some(c) => {
110 let c : char = c as char ;
111 if c >= '0' && c <= '9' {
112 digs.push(c);
113 continue
114 } else {
115 chars.push(c as u8);
116 break
117 }
118 }
119 }
120 };
121 if c == '-' {
122 let s : String = digs.into_iter().collect();
123 toks.push(Tok::Const(Const::Num(
124 isize::from_str_radix(s.as_str(), 10).unwrap()
125 )));
126 } else {
127 let s : String = digs.into_iter().collect();
128 toks.push(Tok::Const(Const::Nat(
129 usize::from_str_radix(s.as_str(), 10).unwrap()
130 )));
131 }
132 continue
133 }
134 else if (c >= 'a' && c <= 'z') ||
135 (c >= 'A' && c <= 'Z') ||
136 (c == '_')
137 {
138 let mut ident = vec![c];
139 loop {
140 match chars.pop() {
141 None => break,
142 Some(c) => {
143 let c : char = c as char ;
144 if (c >= 'a' && c <= 'z') ||
145 (c >= 'A' && c <= 'Z') ||
146 (c >= '0' && c <= '9') ||
147 (c == '_')
148 {
149 ident.push(c);
150 continue
151 } else {
152 chars.push(c as u8);
153 break
154 }
155 }
156 }
157 };
158 toks.push(Tok::Ident( ident.into_iter().collect() ));
159 continue
160 }
161 }
162 }
163 } ;
164}
165
166fn parse_fields (mut toks:Vec<Tok>, mut fields:Vec<(Name, Val)>, bal:Tok) -> (Vec<(Name, Val)>, Vec<Tok>) {
169 match toks.pop() {
170 None => panic!("parse_vals: expected more vals, or end of sequence; but no more tokens"),
171 Some(t) => {
172 if t == bal { (fields, toks) }
173 else if t == Tok::Comma {
174 return parse_fields(toks, fields, bal)
175 } else {
176 match t {
177 Tok::Ident(i) => {
178 let toks = expect_tok(toks, Tok::Colon);
179 let (v, toks) = parse_val_rec(toks);
180 fields.push((name_of_string(i), v));
181 return parse_fields(toks, fields, bal)
182 }
183 t => {
184 panic!("parse_fields: expected identifier, but found {:?}", t)
185 }
186 }
187 }
188 }
189 }
190}
191
192fn parse_vals (mut toks:Vec<Tok>, mut vals:Vec<Val>, bal:Tok) -> (Vec<Val>, Vec<Tok>) {
195 match toks.pop() {
196 None => panic!("parse_vals: expected more vals, or end of sequence; but no more tokens"),
197 Some(t) => {
198 if t == bal { (vals, toks) }
199 else if t == Tok::Comma {
200 return parse_vals(toks, vals, bal)
201 }
202 else {
203 toks.push(t);
204 let (v, toks) = parse_val_rec(toks);
205 vals.push(v);
206 return parse_vals(toks, vals, bal)
207 }
208 }
209 }
210}
211
212fn expect_tok (mut toks: Vec<Tok>, tok:Tok) -> Vec<Tok> {
214 match toks.pop() {
215 None => panic!("expected token `{:?}`, but, no more tokens", tok),
216 Some(t) => {
217 if t == tok { toks }
218 else { panic!("expected token `{:?}`, but instead found token `{:?}`", tok, t) }
219 }
220 }
221}
222
223fn parse_toks(mut toks:Vec<Tok>) -> Val {
224 toks.reverse();
225 let (v, toks) = parse_val_rec(toks);
226 assert!(toks.len() == 0);
227 v
228}
229
230fn path_of_val ( p:&Val ) -> Path {
231 match *p {
232 Val::Vec( ref vs ) => vs.iter().map( name_of_val ).collect(),
233 _ => panic!("expected a vector of values representing names"),
234 }
235}
236
237fn name_of_val ( n:&Val ) -> Name {
238 use crate::engine::*;
239
240 match *n {
241 Val::Constr( ref cons_name, ref cons_args ) => {
242 if *cons_name == name_of_str("Unit") {
243 name_unit()
244 }
245 else if *cons_name == name_of_str("Hash64") {
246 name_of_hash64( 0 ) }
248 else if *cons_name == name_of_str("String") {
249 name_of_string( match cons_args[0] {
250 Val::Const( Const::String( ref s ) ) => s.clone(),
251 _ => panic!("expected a String"),
252 })
253 }
254 else if *cons_name == name_of_str("Usize") {
255 name_of_usize( match cons_args[0] {
256 Val::Const( Const::Nat( ref n ) ) => n.clone(),
257 _ => panic!("expected a Nat"),
258 })
259 }
260 else if *cons_name == name_of_str("Isize") {
261 panic!("")
262 }
263 else if *cons_name == name_of_str("Pair") {
264 let n1 = name_of_val( & cons_args[0] );
265 let n2 = name_of_val( & cons_args[1] );
266 name_pair(n1, n2)
267 }
268 else if *cons_name == name_of_str("ForkL") {
269 let n = name_of_val( & cons_args[0] );
270 name_fork(n).0
271 }
272 else if *cons_name == name_of_str("ForkR") {
273 let n = name_of_val( & cons_args[0] );
274 name_fork(n).1
275 }
276 else {
277 unreachable!()
278 }
279 },
280 Val::Name(ref n) => n.clone(),
281 _ => panic!("expected a constructor for a NameSym")
282 }
283}
284
285fn name_option_of_val ( n:&Val ) -> Option<Name> {
286 use crate::engine::*;
287
288 match *n {
289 Val::Constr( ref cons_name, ref cons_args ) => {
290 if *cons_name == name_of_str("Unit") {
291 Some(name_unit())
292 }
293 else if *cons_name == name_of_str("Hash64") {
294 Some(name_of_hash64( 0 )) }
296 else if *cons_name == name_of_str("String") {
297 if cons_args.len() < 1 { None } else {
298 match cons_args[0] {
299 Val::Const( Const::String( ref s ) ) =>
300 Some(name_of_string( s.clone() )),
301 _ => None,
302 }}
303 }
304 else if *cons_name == name_of_str("Usize") {
305 if cons_args.len() < 1 { None } else {
306 match cons_args[0] {
307 Val::Const( Const::Nat( ref n ) ) => Some( name_of_usize( n.clone() ) ),
308 _ => None,
309 }}
310 }
311 else if *cons_name == name_of_str("Isize") {
312 panic!("TODO")
313 }
314 else if *cons_name == name_of_str("Pair") {
315 if cons_args.len() < 2 { None } else {
316 let n1 = name_option_of_val( & cons_args[0] );
317 let n2 = name_option_of_val( & cons_args[1] );
318 if cons_args.len() < 2 { None } else {
319 match (n1,n2) {
320 (Some(n1),Some(n2)) => Some(name_pair(n1, n2)),
321 (_, _) => None,
322 }}}
323 }
324 else if *cons_name == name_of_str("ForkL") {
325 if cons_args.len() < 1 { None } else {
326 let n = name_option_of_val( & cons_args[0] );
327 match n {
328 None => None,
329 Some(n) => Some(name_fork(n).0)
330 }}
331 }
332 else if *cons_name == name_of_str("ForkR") {
333 if cons_args.len() < 1 { None } else {
334 let n = name_option_of_val( & cons_args[0] );
335 match n {
336 None => None,
337 Some(n) => Some(name_fork(n).1)
338 }}
339 }
340 else { None }
341 },
342 Val::Name(ref n) => Some(n.clone()),
343 _ => None,
344 }
345}
346
347
348fn parse_art_val ( i:&String, fields:&Vec<(Name, Val)> ) -> Option<Val> {
354 if i == "Art" && fields.len() == 1 {
355 match fields[0] {
356 (ref nf, ref vf) =>
357 if *nf == name_of_str("art") {
358 match *vf {
362 Val::Struct( ref j, ref ws ) =>
363 if *j == name_of_str("Loc")
364 && ws.len() == 2
365 && ws[0].0 == name_of_str("path")
366 && ws[1].0 == name_of_str("id")
367 {
368 let path = path_of_val( & ws[0].1 );
371 let name = name_of_val( & ws[1].1 );
372 Some( Val::Art(Loc{path:path, name:name}, ArtContent::Unknown) )
373 }
374
375
376 else {
377 None
378 },
379 _ => None,
380 }
381 } else { None }
382 }} else { None }
383}
384
385fn parse_val_rec (mut toks:Vec<Tok>) -> (Val, Vec<Tok>) {
387 let (v, toks) = match toks.pop() {
389 None => panic!("expected value; but, no more tokens"),
390 Some(Tok::Right(r)) => panic!("expected value, but found {:?} instead", Tok::Right(r)),
391 Some(Tok::Comma) => panic!("expected value, but found Comma instead"),
392 Some(Tok::Colon) => panic!("expected value, but found Colon instead"),
393 Some(Tok::Left(BalTok::Bracket)) => {
394 let (vs, toks) = parse_vals(toks, vec![], Tok::Right(BalTok::Bracket));
396 (Val::Vec(vs), toks)
397 },
398 Some(Tok::Left(BalTok::Paren)) => {
399 let (vs, toks) = parse_vals(toks, vec![], Tok::Right(BalTok::Paren));
401 (Val::Tuple(vs), toks)
402 },
403 Some(Tok::Left(l)) => panic!("expected value, but found {:?} instead", Tok::Left(l)),
404 Some(Tok::Ident(i)) => {
405 match toks.pop() {
406 None => {
407 (Val::Constr(name_of_string(i), vec![]), toks)
409 }
410 Some(Tok::Left(BalTok::Brace)) => {
411 let (fields, toks) = parse_fields(toks, vec![], Tok::Right(BalTok::Brace));
413 let art_op = parse_art_val(&i, &fields);
414 let v = match art_op {
415 Some(a) => a,
416 None => Val::Struct(name_of_string(i.clone()), fields.clone())
417 };
418 (v, toks)
419 }
420 Some(Tok::Left(BalTok::Paren)) => {
421 let (vs, toks) = parse_vals(toks, vec![], Tok::Right(BalTok::Paren));
423 let v = Val::Constr(name_of_string(i), vs);
424 match name_option_of_val(&v) {
425 Some(n) => (Val::Name(n), toks),
426 None => (v, toks)
427 }
428 },
429 Some(Tok::Comma) => {
430 toks.push(Tok::Comma);
431 (Val::Constr(name_of_string(i), vec![]), toks)
432 },
433 Some(Tok::Right(baltok)) => {
434 toks.push(Tok::Right(baltok));
435 (Val::Constr(name_of_string(i), vec![]), toks)
436 },
437 Some(t) => {
438 panic!("expected left balanced token, or comma, but instead found token {:?}", t)
439 }}},
440 Some(Tok::Const(Const::Nat(n))) => (Val::Const(Const::Nat(n)), toks),
441 Some(Tok::Const(Const::Num(n))) => (Val::Const(Const::Num(n)), toks),
442 Some(Tok::Const(Const::String(s))) => (Val::Const(Const::String(s)), toks)
443 };
444 (v,toks)
445}