1#![allow(dead_code)]
2
3use std::collections::*;
4use net::*;
5use std;
6
7#[derive(Clone, Debug)]
9pub enum Term {
10 Lam {nam: Vec<u8>, bod: Box<Term>},
12
13 App {fun: Box<Term>, arg: Box<Term>},
15
16 Par {tag: u32, fst: Box<Term>, snd: Box<Term>},
18
19 Let {tag: u32, fst: Vec<u8>, snd: Vec<u8>, val: Box<Term>, nxt: Box<Term>},
21
22 Var {nam: Vec<u8>},
24
25 Set
27}
28use self::Term::{*};
29
30pub type Str = [u8];
32pub type Chr = u8;
33
34pub fn new_name(idx : u32) -> Vec<Chr> {
36 let mut name = Vec::new();
37 let mut idx = idx;
38 while idx > 0 {
39 idx = idx - 1;
40 name.push((97 + idx % 26) as u8);
41 idx = idx / 26;
42 }
43 return name;
44}
45
46pub fn name_idx(name : &Vec<Chr>) -> u32 {
47 let mut idx : u32 = 0;
48 for byte in name.iter().rev() {
49 idx = (idx * 26) + (*byte as u32 - 97) + 1;
50 }
51 return idx;
52}
53
54type Context<'a> = Vec<(&'a Str, Option<Term>)>;
56
57fn extend<'a,'b>(nam : &'a Str, val : Option<Term>, ctx : &'b mut Context<'a>) -> &'b mut Context<'a> {
59 ctx.push((nam,val));
60 ctx
61}
62
63fn narrow<'a,'b>(ctx : &'b mut Context<'a>) -> &'b mut Context<'a> {
65 ctx.pop();
66 ctx
67}
68
69
70fn parse_name(code : &Str) -> (&Str, &Str) {
72 let mut i : usize = 0;
73 while i < code.len() && !(code[i] == b' ' || code[i] == b'\n') {
74 i += 1;
75 }
76 (&code[i..], &code[0..i])
77}
78
79pub fn namespace(space : &Vec<u8>, idx : u32, var : &Vec<u8>) -> Vec<u8> {
80 if var != b"-" {
81 let mut nam = space.clone();
82 nam.extend_from_slice(b"/");
83 nam.append(&mut idx.to_string().as_bytes().to_vec());
84 nam.extend_from_slice(b"/");
85 nam.append(&mut var.clone());
86 nam
87 } else {
88 var.clone()
89 }
90}
91
92pub fn copy(space : &Vec<u8>, idx : u32, term : &Term) -> Term {
94 match term {
95 Lam{nam, bod} => {
96 let nam = namespace(space, idx, nam);
97 let bod = Box::new(copy(space, idx, bod));
98 Lam{nam, bod}
99 },
100 App{fun, arg} => {
101 let fun = Box::new(copy(space, idx, fun));
102 let arg = Box::new(copy(space, idx, arg));
103 App{fun, arg}
104 },
105 Par{tag, fst, snd} => {
106 let tag = *tag;
107 let fst = Box::new(copy(space, idx, fst));
108 let snd = Box::new(copy(space, idx, snd));
109 Par{tag, fst, snd}
110 },
111 Let{tag, fst, snd, val, nxt} => {
112 let tag = *tag;
113 let fst = namespace(space, idx, fst);
114 let snd = namespace(space, idx, snd);
115 let val = Box::new(copy(space, idx, val));
116 let nxt = Box::new(copy(space, idx, nxt));
117 Let{tag, fst, snd, val, nxt}
118 },
119 Var{nam} => {
120 let nam = namespace(space, idx, nam);
121 Var{nam}
122 },
123 Set => Set
124 }
125}
126
127pub fn parse_term<'a>(code : &'a Str, ctx : &mut Context<'a>, idx : &mut u32, comment : u32) -> (&'a Str, Term) {
129 if comment > 0 {
130 match code[0] {
131 b'(' => parse_term(&code[1..], ctx, idx, comment + 1),
132 b')' => parse_term(&code[1..], ctx, idx, comment - if comment == 0 { 0 } else { 1 }),
133 _ => parse_term(&code[1..], ctx, idx, comment)
134 }
135 } else {
136 match code[0] {
137 b' ' => parse_term(&code[1..], ctx, idx, comment),
139 b'\n' => parse_term(&code[1..], ctx, idx, comment),
141 b'(' => parse_term(&code[1..], ctx, idx, comment + 1),
143 b'#' => {
145 let (code, nam) = parse_name(&code[1..]);
146 extend(nam, None, ctx);
147 let (code, bod) = parse_term(code, ctx, idx, comment);
148 narrow(ctx);
149 let nam = nam.to_vec();
150 let bod = Box::new(bod);
151 (code, Lam{nam,bod})
152 },
153 b':' => {
155 let (code, fun) = parse_term(&code[1..], ctx, idx, comment);
156 let (code, arg) = parse_term(code, ctx, idx, comment);
157 let fun = Box::new(fun);
158 let arg = Box::new(arg);
159 (code, App{fun,arg})
160 },
161 b'&' => {
163 let (code, tag) = parse_name(&code[1..]);
164 let (code, fst) = parse_term(code, ctx, idx, comment);
165 let (code, snd) = parse_term(code, ctx, idx, comment);
166 let tag = name_idx(&tag.to_vec());
167 let fst = Box::new(fst);
168 let snd = Box::new(snd);
169 (code, Par{tag,fst,snd})
170 },
171 b'=' => {
173 let (code, tag) = parse_name(&code[1..]);
174 let (code, fst) = parse_name(&code[1..]);
175 let (code, snd) = parse_name(&code[1..]);
176 extend(snd, None, ctx);
177 extend(fst, None, ctx);
178 let (code, val) = parse_term(code, ctx, idx, comment);
179 let (code, nxt) = parse_term(code, ctx, idx, comment);
180 narrow(ctx);
181 narrow(ctx);
182 let tag = name_idx(&tag.to_vec());
183 let fst = fst.to_vec();
184 let snd = snd.to_vec();
185 let val = Box::new(val);
186 let nxt = Box::new(nxt);
187 (code, Let{tag, fst, snd, val, nxt})
188 },
189 b'/' => {
191 let (code, nam) = parse_name(&code[1..]);
192 let (code, val) = parse_term(code, ctx, idx, comment);
193 extend(nam, Some(val), ctx);
194 let (code, bod) = parse_term(code, ctx, idx, comment);
195 narrow(ctx);
196 (code, bod)
197 },
198 b'*' => {
200 (&code[1..], Set)
201 },
202 _ => {
204 let (code, nam) = parse_name(code);
205 let mut val : Option<Term> = None;
206 for i in (0..ctx.len()).rev() {
207 if ctx[i].0 == nam {
208 match ctx[i].1 {
209 Some(ref term) => {
210 let mut name = nam.clone().to_vec();
211 val = Some(copy(&name, *idx, term));
212 *idx += 1;
213 break;
214 },
215 None => {
216 break;
217 }
218 }
219 }
220 }
221 let nam = nam.to_vec();
222 (code, match val { Some(term) => term, None => Var{nam} })
223 }
224 }
225 }
226}
227
228pub fn from_string<'a>(code : &'a Str) -> Term {
230 let mut ctx = Vec::new();
231 let mut idx = 0;
232 parse_term(code, &mut ctx, &mut idx, 0).1
233}
234
235pub fn to_string(term : &Term) -> Vec<Chr> {
237 fn stringify_term(code : &mut Vec<u8>, term : &Term) {
238 match term {
239 &Lam{ref nam, ref bod} => {
240 code.extend_from_slice(b"#");
241 code.append(&mut nam.clone());
242 code.extend_from_slice(b" ");
243 stringify_term(code, &bod);
244 },
245 &App{ref fun, ref arg} => {
246 code.extend_from_slice(b":");
247 stringify_term(code, &fun);
248 code.extend_from_slice(b" ");
249 stringify_term(code, &arg);
250 },
251 &Par{tag, ref fst, ref snd} => {
252 code.extend_from_slice(b"&");
253 code.append(&mut new_name(tag));
254 code.extend_from_slice(b" ");
255 stringify_term(code, &fst);
256 code.extend_from_slice(b" ");
257 stringify_term(code, &snd);
258 },
259 &Let{tag, ref fst, ref snd, ref val, ref nxt} => {
260 code.extend_from_slice(b"=");
261 code.append(&mut new_name(tag));
262 code.extend_from_slice(b" ");
263 code.append(&mut fst.clone());
264 code.extend_from_slice(b" ");
265 code.append(&mut snd.clone());
266 code.extend_from_slice(b" ");
267 stringify_term(code, &val);
268 code.extend_from_slice(b"\n");
269 stringify_term(code, &nxt);
270 },
271 &Set => {
272 code.extend_from_slice(b"*");
273 },
274 &Var{ref nam} => {
275 code.append(&mut nam.clone());
276 },
277 }
278 }
279 let mut code = Vec::new();
280 stringify_term(&mut code, &term);
281 return code;
282}
283
284impl std::fmt::Display for Term {
286 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
287 write!(f, "{}", String::from_utf8_lossy(&to_string(&self)))
288 }
289}
290
291pub fn to_net(term : &Term) -> Net {
294 fn encode_term
295 ( net : &mut Net
296 , term : &Term
297 , up : Port
298 , scope : &mut HashMap<Vec<u8>,u32>
299 , vars : &mut Vec<(Vec<u8>,u32)>
300 ) -> Port {
301 match term {
302 &Lam{ref nam, ref bod} => {
307 let fun = new_node(net, CON);
308 scope.insert(nam.to_vec(), port(fun, 1));
309 if nam == b"-" {
311 let era = new_node(net, ERA);
312 link(net, port(era, 1), port(era, 2));
313 link(net, port(fun, 1), port(era, 0));
314 }
315 let bod = encode_term(net, bod, port(fun, 2), scope, vars);
316 link(net, port(fun, 2), bod);
317 port(fun, 0)
318 },
319 &App{ref fun, ref arg} => {
324 let app = new_node(net, CON);
325 let fun = encode_term(net, fun, port(app, 0), scope, vars);
326 link(net, port(app, 0), fun);
327 let arg = encode_term(net, arg, port(app, 1), scope, vars);
328 link(net, port(app, 1), arg);
329 port(app, 2)
330 },
331 &Par{tag, ref fst, ref snd} => {
336 let dup = new_node(net, FAN + tag);
337 let fst = encode_term(net, fst, port(dup, 1), scope, vars);
338 link(net, port(dup, 1), fst);
339 let snd = encode_term(net, snd, port(dup, 2), scope, vars);
340 link(net, port(dup, 2), snd);
341 port(dup, 0)
342 },
343 &Let{tag, ref fst, ref snd, ref val, ref nxt} => {
348 let dup = new_node(net, FAN + tag);
349 scope.insert(fst.to_vec(), port(dup, 1));
350 scope.insert(snd.to_vec(), port(dup, 2));
351 if fst == b"-" {
353 let era = new_node(net, ERA);
354 link(net, port(era, 1), port(era, 2));
355 link(net, port(dup, 1), port(era, 0));
356 }
357 if snd == b"-" {
359 let era = new_node(net, ERA);
360 link(net, port(era, 1), port(era, 2));
361 link(net, port(dup, 2), port(era, 0));
362 }
363 let val = encode_term(net, &val, port(dup, 0), scope, vars);
364 link(net, val, port(dup, 0));
365 encode_term(net, &nxt, up, scope, vars)
366 },
367 &Set => {
369 let set = new_node(net, ERA);
370 link(net, port(set, 1), port(set, 2));
371 port(set, 0)
372 },
373 Var{ref nam} => {
374 vars.push((nam.to_vec(), up));
375 up
376 }
377 }
378 }
379
380 let mut net = Net { nodes: vec![0,2,1,4], reuse: vec![] };
382 let mut vars = Vec::new();
383 let mut scope = HashMap::new();
384
385 let main = encode_term(&mut net, &term, 0, &mut scope, &mut vars);
387
388 for i in 0..vars.len() {
390 let (ref nam, var) = vars[i];
391 match scope.get(nam) {
392 Some(next) => {
393 let next = *next;
394 if enter(&net, next) == next {
395 link(&mut net, var, next);
396 } else {
397 panic!("Variable used more than once: {}.", std::str::from_utf8(nam).unwrap());
398 }
399 },
400 None => panic!("Unbound variable: {}.", std::str::from_utf8(nam).unwrap())
401 }
402 }
403
404 for (_, addr) in scope {
406 if enter(&net, addr) == addr {
407 let era = new_node(&mut net, ERA);
408 link(&mut net, port(era, 1), port(era, 2));
409 link(&mut net, addr, port(era, 0));
410 }
411 }
412
413 link(&mut net, 0, main);
415
416 net
417}
418
419pub fn from_net(net : &Net) -> Term {
421 fn name_of(net : &Net, var_port : Port, var_name : &mut HashMap<u32, Vec<u8>>) -> Vec<u8> {
423 if kind(net, addr(enter(net, var_port))) == ERA {
425 return b"-".to_vec();
426 }
427 if !var_name.contains_key(&var_port) {
428 let nam = new_name(var_name.len() as u32 + 1);
429 var_name.insert(var_port, nam.clone());
430 }
431 var_name.get(&var_port).unwrap().to_vec()
432 }
433
434 fn read_term
436 ( net : &Net
437 , next : Port
438 , var_name : &mut HashMap<u32, Vec<u8>>
439 , lets_vec : &mut Vec<u32>
440 , lets_set : &mut HashSet<(u32)>
441 ) -> Term {
442 match kind(net, addr(next)) {
443 ERA => Set,
445 CON => match slot(next) {
447 0 => {
449 let nam = name_of(net, port(addr(next),1), var_name);
450 let prt = enter(net, port(addr(next), 2));
451 let bod = read_term(net, prt, var_name, lets_vec, lets_set);
452 let mut lam = Lam{nam: nam, bod: Box::new(bod)};
453 lam
454 },
455 1 => {
457 Var{nam: name_of(net, next, var_name)}
458 },
459 _ => {
461 let prt = enter(net, port(addr(next), 0));
462 let fun = read_term(net, prt, var_name, lets_vec, lets_set);
463 let prt = enter(net, port(addr(next), 1));
464 let arg = read_term(net, prt, var_name, lets_vec, lets_set);
465 App{fun: Box::new(fun), arg: Box::new(arg)}
466 }
467 },
468 tag => match slot(next) {
470 0 => {
472 let tag = tag - FAN;
473 let prt = enter(net, port(addr(next), 1));
474 let fst = read_term(net, prt, var_name, lets_vec, lets_set);
475 let prt = enter(net, port(addr(next), 2));
476 let snd = read_term(net, prt, var_name, lets_vec, lets_set);
477 Par{tag, fst: Box::new(fst), snd: Box::new(snd)}
478 },
479 _ => {
482 if !lets_set.contains(&addr(next)) {
483 lets_set.insert(addr(next));
484 lets_vec.push(addr(next));
485 }
486 let nam = name_of(net, next, var_name);
487 Var{nam}
488 }
489 }
490 }
491 }
492
493 let mut binder_name = HashMap::new();
496
497 let mut lets_vec = Vec::new();
501 let mut lets_set = HashSet::new();
502
503 let mut main = read_term(net, enter(net, 0), &mut binder_name, &mut lets_vec, &mut lets_set);
505
506 while lets_vec.len() > 0 {
508 let dup = lets_vec.pop().unwrap();
509 let val = read_term(net, enter(net,port(dup,0)), &mut binder_name, &mut lets_vec, &mut lets_set);
510 let tag = kind(net, dup) - FAN;
511 let fst = name_of(net, port(dup,1), &mut binder_name);
512 let snd = name_of(net, port(dup,2), &mut binder_name);
513 let val = Box::new(val);
514 let nxt = Box::new(main);
515 main = Let{tag, fst, snd, val, nxt};
516 }
517 main
518}
519
520pub fn reduce(term : &Term) -> Term {
522 let mut net : Net = to_net(&term);
523 ::net::reduce(&mut net);
524 from_net(&net)
525}