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(fst, None, extend(snd, None, ctx));
177 let (code, val) = parse_term(code, ctx, idx, comment);
178 let (code, nxt) = parse_term(code, ctx, idx, comment);
179 narrow(ctx);
180 let tag = name_idx(&tag.to_vec());
181 let fst = fst.to_vec();
182 let snd = snd.to_vec();
183 let val = Box::new(val);
184 let nxt = Box::new(nxt);
185 (code, Let{tag, fst, snd, val, nxt})
186 },
187 b'/' => {
189 let (code, nam) = parse_name(&code[1..]);
190 let (code, val) = parse_term(code, ctx, idx, comment);
191 extend(nam, Some(val), ctx);
192 let (code, bod) = parse_term(code, ctx, idx, comment);
193 narrow(ctx);
194 (code, bod)
195 },
196 b'*' => {
198 (code, Set)
199 },
200 _ => {
202 let (code, nam) = parse_name(code);
203 let mut val : Option<Term> = None;
204 for i in (0..ctx.len()).rev() {
205 if ctx[i].0 == nam {
206 match ctx[i].1 {
207 Some(ref term) => {
208 let mut name = nam.clone().to_vec();
209 val = Some(copy(&name, *idx, term));
210 *idx += 1;
211 break;
212 },
213 None => {
214 break;
215 }
216 }
217 }
218 }
219 let nam = nam.to_vec();
220 (code, match val { Some(term) => term, None => Var{nam} })
221 }
222 }
223 }
224}
225
226pub fn from_string<'a>(code : &'a Str) -> Term {
228 let mut ctx = Vec::new();
229 let mut idx = 0;
230 parse_term(code, &mut ctx, &mut idx, 0).1
231}
232
233pub fn to_string(term : &Term) -> Vec<Chr> {
235 fn stringify_term(code : &mut Vec<u8>, term : &Term) {
236 match term {
237 &Lam{ref nam, ref bod} => {
238 code.extend_from_slice(b"#");
239 code.append(&mut nam.clone());
240 code.extend_from_slice(b" ");
241 stringify_term(code, &bod);
242 },
243 &App{ref fun, ref arg} => {
244 code.extend_from_slice(b":");
245 stringify_term(code, &fun);
246 code.extend_from_slice(b" ");
247 stringify_term(code, &arg);
248 },
249 &Par{tag, ref fst, ref snd} => {
250 code.extend_from_slice(b"&");
251 code.append(&mut new_name(tag));
252 code.extend_from_slice(b" ");
253 stringify_term(code, &fst);
254 code.extend_from_slice(b" ");
255 stringify_term(code, &snd);
256 },
257 &Let{tag, ref fst, ref snd, ref val, ref nxt} => {
258 code.extend_from_slice(b"=");
259 code.append(&mut new_name(tag));
260 code.extend_from_slice(b" ");
261 code.append(&mut fst.clone());
262 code.extend_from_slice(b" ");
263 code.append(&mut snd.clone());
264 code.extend_from_slice(b" ");
265 stringify_term(code, &val);
266 code.extend_from_slice(b"\n");
267 stringify_term(code, &nxt);
268 },
269 &Set => {
270 code.extend_from_slice(b"*");
271 },
272 &Var{ref nam} => {
273 code.append(&mut nam.clone());
274 },
275 }
276 }
277 let mut code = Vec::new();
278 stringify_term(&mut code, &term);
279 return code;
280}
281
282impl std::fmt::Display for Term {
284 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
285 write!(f, "{}", String::from_utf8_lossy(&to_string(&self)))
286 }
287}
288
289pub fn to_net(term : &Term) -> Net {
292 fn encode_term
293 ( net : &mut Net
294 , term : &Term
295 , up : Port
296 , scope : &mut HashMap<Vec<u8>,u32>
297 , vars : &mut Vec<(Vec<u8>,u32)>
298 ) -> Port {
299 match term {
300 &Lam{ref nam, ref bod} => {
305 let fun = new_node(net, CON);
306 scope.insert(nam.to_vec(), port(fun, 1));
307 if nam == b"-" {
309 let era = new_node(net, ERA);
310 link(net, port(era, 1), port(era, 2));
311 link(net, port(fun, 1), port(era, 0));
312 }
313 let bod = encode_term(net, bod, port(fun, 2), scope, vars);
314 link(net, port(fun, 2), bod);
315 port(fun, 0)
316 },
317 &App{ref fun, ref arg} => {
322 let app = new_node(net, CON);
323 let fun = encode_term(net, fun, port(app, 0), scope, vars);
324 link(net, port(app, 0), fun);
325 let arg = encode_term(net, arg, port(app, 1), scope, vars);
326 link(net, port(app, 1), arg);
327 port(app, 2)
328 },
329 &Par{tag, ref fst, ref snd} => {
334 let dup = new_node(net, FAN + tag);
335 let fst = encode_term(net, fst, port(dup, 1), scope, vars);
336 link(net, port(dup, 1), fst);
337 let snd = encode_term(net, snd, port(dup, 2), scope, vars);
338 link(net, port(dup, 2), snd);
339 port(dup, 0)
340 },
341 &Let{tag, ref fst, ref snd, ref val, ref nxt} => {
346 let dup = new_node(net, FAN + tag);
347 scope.insert(fst.to_vec(), port(dup, 1));
348 scope.insert(snd.to_vec(), port(dup, 2));
349 if fst == b"-" {
351 let era = new_node(net, ERA);
352 link(net, port(era, 1), port(era, 2));
353 link(net, port(dup, 1), port(era, 0));
354 }
355 if snd == b"-" {
357 let era = new_node(net, ERA);
358 link(net, port(era, 1), port(era, 2));
359 link(net, port(dup, 2), port(era, 0));
360 }
361 let val = encode_term(net, &val, port(dup, 0), scope, vars);
362 link(net, val, port(dup, 0));
363 encode_term(net, &nxt, up, scope, vars)
364 },
365 &Set => {
367 let set = new_node(net, ERA);
368 link(net, port(set, 1), port(set, 2));
369 port(set, 0)
370 },
371 Var{ref nam} => {
372 vars.push((nam.to_vec(), up));
373 up
374 }
375 }
376 }
377
378 let mut net = Net { nodes: vec![0,2,1,4], reuse: vec![] };
380 let mut vars = Vec::new();
381 let mut scope = HashMap::new();
382
383 let main = encode_term(&mut net, &term, 0, &mut scope, &mut vars);
385
386 for i in 0..vars.len() {
388 let (ref nam, var) = vars[i];
389 match scope.get(nam) {
390 Some(next) => {
391 let next = *next;
392 if enter(&net, next) == next {
393 link(&mut net, var, next);
394 } else {
395 panic!("Variable used more than once: {}.", std::str::from_utf8(nam).unwrap());
396 }
397 },
398 None => panic!("Unbound variable: {}.", std::str::from_utf8(nam).unwrap())
399 }
400 }
401
402 link(&mut net, 0, main);
404
405 net
406}
407
408pub fn from_net(net : &Net) -> Term {
410 fn name_of(net : &Net, var_port : Port, var_name : &mut HashMap<u32, Vec<u8>>) -> Vec<u8> {
412 if kind(net, addr(enter(net, var_port))) == ERA {
414 return b"-".to_vec();
415 }
416 if !var_name.contains_key(&var_port) {
417 let nam = new_name(var_name.len() as u32 + 1);
418 var_name.insert(var_port, nam.clone());
419 }
420 var_name.get(&var_port).unwrap().to_vec()
421 }
422
423 fn read_term
425 ( net : &Net
426 , next : Port
427 , var_name : &mut HashMap<u32, Vec<u8>>
428 , lets_vec : &mut Vec<u32>
429 , lets_set : &mut HashSet<(u32)>
430 ) -> Term {
431 match kind(net, addr(next)) {
432 ERA => Set,
434 CON => match slot(next) {
436 0 => {
438 let nam = name_of(net, port(addr(next),1), var_name);
439 let prt = enter(net, port(addr(next), 2));
440 let bod = read_term(net, prt, var_name, lets_vec, lets_set);
441 let mut lam = Lam{nam: nam, bod: Box::new(bod)};
442 lam
443 },
444 1 => {
446 Var{nam: name_of(net, next, var_name)}
447 },
448 _ => {
450 let prt = enter(net, port(addr(next), 0));
451 let fun = read_term(net, prt, var_name, lets_vec, lets_set);
452 let prt = enter(net, port(addr(next), 1));
453 let arg = read_term(net, prt, var_name, lets_vec, lets_set);
454 App{fun: Box::new(fun), arg: Box::new(arg)}
455 }
456 },
457 tag => match slot(next) {
459 0 => {
461 let tag = tag - FAN;
462 let prt = enter(net, port(addr(next), 1));
463 let fst = read_term(net, prt, var_name, lets_vec, lets_set);
464 let prt = enter(net, port(addr(next), 2));
465 let snd = read_term(net, prt, var_name, lets_vec, lets_set);
466 Par{tag, fst: Box::new(fst), snd: Box::new(snd)}
467 },
468 _ => {
471 if !lets_set.contains(&addr(next)) {
472 lets_set.insert(addr(next));
473 lets_vec.push(addr(next));
474 }
475 let nam = name_of(net, next, var_name);
476 Var{nam}
477 }
478 }
479 }
480 }
481
482 let mut binder_name = HashMap::new();
485
486 let mut lets_vec = Vec::new();
490 let mut lets_set = HashSet::new();
491
492 let mut main = read_term(net, enter(net, 0), &mut binder_name, &mut lets_vec, &mut lets_set);
494
495 while lets_vec.len() > 0 {
497 let dup = lets_vec.pop().unwrap();
498 let val = read_term(net, enter(net,port(dup,0)), &mut binder_name, &mut lets_vec, &mut lets_set);
499 let tag = kind(net, dup) - FAN;
500 let fst = name_of(net, port(dup,1), &mut binder_name);
501 let snd = name_of(net, port(dup,2), &mut binder_name);
502 let val = Box::new(val);
503 let nxt = Box::new(main);
504 main = Let{tag, fst, snd, val, nxt};
505 }
506 main
507}
508
509pub fn reduce(term : &Term) -> Term {
511 let mut net : Net = to_net(&term);
512 ::net::reduce(&mut net);
513 from_net(&net)
514}