1use extra;
2
3use term::*;
4use term::Vars;
5use term::Defs;
6use term::Term::*;
7use term::TypeError::*;
8
9use std;
10use std::string::*;
11use std::str::*;
12use std::collections::*;
13
14pub struct Cursor {
16 index : usize,
17 line : usize,
18 column : usize
19}
20
21pub fn advance_char(cursor : &mut Cursor, n : usize) {
23 cursor.index += n;
24 cursor.column += n;
25}
26
27pub fn advance_line(cursor : &mut Cursor) {
29 cursor.index += 1;
30 cursor.line += 1;
31 cursor.column = 0;
32}
33
34pub fn is_name_char(chr : u8) -> bool {
36 chr >= b'a' && chr <= b'z' ||
37 chr >= b'A' && chr <= b'Z' ||
38 chr >= b'0' && chr <= b'9' ||
39 chr == b'_' ||
40 chr == b'-' ||
41 chr == b'\''
42}
43
44pub fn skip_whites(cursor : &mut Cursor, code : &[u8]) {
46 while cursor.index < code.len() {
47 if code[cursor.index] == b'\n' {
48 advance_line(cursor);
49 } else if code[cursor.index] == b' ' {
50 advance_char(cursor, 1);
51 } else if match_exact(cursor, code, b"{-") {
52 while cursor.index < code.len() - 1 && !match_exact(cursor, code, b"-}") {
53 advance_char(cursor, 1);
54 }
55 advance_char(cursor, 2);
56 } else if match_exact(cursor, code, b"--") {
57 while cursor.index < code.len() && !match_exact(cursor, code, b"\n") {
58 advance_char(cursor, 1);
59 }
60 advance_line(cursor);
61 } else {
62 break;
63 }
64 }
65}
66
67fn parse_not_eof(cursor : &mut Cursor, code : &[u8]) -> Result<(), String> {
69 if cursor.index >= code.len() {
70 Err(format!("Unexpected end of file."))
71 } else {
72 Ok(())
73 }
74}
75
76fn prepare_to_parse(cursor : &mut Cursor, code : &[u8]) -> Result<(), String> {
78 skip_whites(cursor, code);
79 parse_not_eof(cursor, code)?;
80 Ok(())
81}
82
83fn parse_name(cursor : &mut Cursor, code : &[u8]) -> Result<Vec<u8>, String> {
85 prepare_to_parse(cursor, code)?;
86 let mut name = Vec::new();
87 while cursor.index < code.len() && is_name_char(code[cursor.index]) {
88 name.push(code[cursor.index]);
89 advance_char(cursor, 1);
90 }
91 if name.len() == 0 {
92 Err(format!("Syntax error (at line {}, col {}): expected a name, found `{}`.",
93 cursor.line,
94 cursor.column,
95 if cursor.index < code.len() {
96 String::from_utf8_lossy(&[code[cursor.index]]).to_string()
97 } else {
98 "EOF".to_string()
99 }))
100 } else {
101 Ok(name)
102 }
103}
104
105fn match_exact(cursor : &mut Cursor, code : &[u8], string : &[u8]) -> bool {
107 cursor.index + string.len() <= code.len() &&
108 code[cursor.index .. cursor.index + string.len()] == *string
109}
110
111fn parse_one_of(cursor : &mut Cursor, code : &[u8], strings : &[&[u8]]) -> Result<usize, String> {
113 prepare_to_parse(cursor, code)?;
114
115 for i in 0..strings.len() {
117 if match_exact(cursor, code, strings[i]) {
118 advance_char(cursor, strings[i].len());
119 return Ok(i);
120 }
121 }
122
123 let mut error = String::new();
125 error.push_str(&format!("Syntax error (at line {}, col {}): ", cursor.line, cursor.column));
126 if strings.len() > 1 {
127 error.push_str("expected one of: ");
128 } else {
129 error.push_str("expected: ");
130 }
131 for i in 0..strings.len() {
132 error.push_str("'");
133 unsafe { error.push_str(from_utf8_unchecked(strings[i])); }
134 error.push_str("'");
135 if i < strings.len() {
136 error.push_str(", ");
137 }
138 }
139 error.push_str("found '");
140 error.push(code[cursor.index] as char);
141 error.push_str("'.");
142 Err(error)
143}
144
145pub fn parse_term
147 ( cursor : &mut Cursor
148 , code : &[u8]
149 , vars : &mut Vars
150 , defs : &mut Defs)
151 -> Result<Term, String> {
152
153 prepare_to_parse(cursor, code)?;
154
155 let parsed : Term;
156 let appliable : bool;
157
158 if match_exact(cursor, code, b"((") || match_exact(cursor, code, b"(case ") || match_exact(cursor, code, b"(data ") {
160 advance_char(cursor, 1);
161 parsed = parse_term(cursor, code, vars, defs)?;
162 appliable = true;
163 parse_one_of(cursor, code, &[b")"])?;
164
165 } else if match_exact(cursor, code, b"(") {
167 advance_char(cursor, 1);
168 prepare_to_parse(cursor, code)?;
169
170 let mut args : Vec<(Vec<u8>, Term)> = Vec::new();
172 while code[cursor.index] != b')' {
173 let var = parse_name(cursor, code)?;
174 prepare_to_parse(cursor, code)?;
175 parse_one_of(cursor, code, &[b":"])?;
176 let typ = parse_term(cursor, code, vars, defs)?;
177 vars.push(var.clone());
178 args.push((var, typ));
179 prepare_to_parse(cursor, code)?;
180 if code[cursor.index] == b',' {
181 advance_char(cursor, 1);
182 prepare_to_parse(cursor, code)?;
183 }
184 }
185 advance_char(cursor, 1);
186
187 prepare_to_parse(cursor, code)?;
189 let kind = parse_one_of(cursor, code, &[b"-", b"="])?;
190 parse_one_of(cursor, code, &[b">"])?;
191 let mut abs = parse_term(cursor, code, vars, defs)?;
192
193 for i in (0..args.len()).rev() {
195 let nam = args[i].0.to_vec();
196 let typ = Box::new(args[i].1.clone());
197 let bod = Box::new(abs);
198 abs = match kind {
199 0 => All{nam, typ, bod},
200 1 => Lam{nam, typ, bod},
201 _ => panic!("Should not happen.")
202 };
203 vars.pop();
204 }
205 parsed = abs;
206 appliable = false;
207
208 } else if match_exact(cursor, code, b"Type") {
210 advance_char(cursor, 4);
211 parsed = Set;
212 appliable = false;
213
214 } else if match_exact(cursor, code, b"data") {
216 advance_char(cursor, 4);
217 let nam = parse_name(cursor, code)?;
218 prepare_to_parse(cursor, code)?;
219 let arg = Vec::new();
220 let mut par = Vec::new();
221 if match_exact(cursor, code, b"<") {
222 advance_char(cursor, 1);
223 while code[cursor.index] != b'>' {
224 let var = parse_name(cursor, code)?;
225 prepare_to_parse(cursor, code)?;
226 parse_one_of(cursor, code, &[b":"])?;
227 let typ = Box::new(parse_term(cursor, code, vars, defs)?);
228 par.push((var, typ));
229 prepare_to_parse(cursor, code)?;
230 if code[cursor.index] == b',' {
231 advance_char(cursor, 1);
232 prepare_to_parse(cursor, code)?;
233 }
234 }
235 advance_char(cursor, 1);
236 }
237 for i in 0..par.len() {
238 vars.push(par[i].0.clone());
239 }
240 parse_one_of(cursor, code, &[b":"])?;
241 prepare_to_parse(cursor, code)?;
242 let typ = parse_term(cursor, code, vars, defs)?;
243 skip_whites(cursor, code);
244 let mut ctr : Vec<(Vec<u8>, Box<Term>)> = Vec::new();
245 vars.push(nam.to_vec());
246 while cursor.index < code.len() && match_exact(cursor, code, b"|") {
247 advance_char(cursor, 1);
248 let ctr_nam = parse_name(cursor, code)?;
249 parse_one_of(cursor, code, &[b":"])?;
250 let ctr_typ = parse_term(cursor, code, vars, defs)?;
251 let ctr_typ = Box::new(ctr_typ);
252 ctr.push((ctr_nam, ctr_typ));
253 skip_whites(cursor, code);
254 }
255 for _ in 0..par.len() {
256 vars.pop();
257 }
258 vars.pop();
259 let typ = Box::new(typ);
260 let def = nam.to_vec();
261 let idt = Idt{nam, arg, par, typ, ctr};
262 defs.insert(def, idt.clone());
263 skip_whites(cursor, code);
264 if match_exact(cursor, code, b")") {
265 parsed = idt;
266 } else {
267 parsed = parse_term(cursor, code, vars, defs)?;
268 }
269 appliable = false;
270
271 } else if match_exact(cursor, code, b"case") {
273 advance_char(cursor, 4);
274
275 let val = parse_term(cursor, code, vars, defs)?;
277 prepare_to_parse(cursor, code)?;
278
279 parse_one_of(cursor, code, &[b"->"])?;
281 vars.push(b"self".to_vec());
282 let mut ret_arg = Vec::new();
283 prepare_to_parse(cursor, code)?;
284 if match_exact(cursor, code, b"(") {
285 advance_char(cursor, 1);
286 while !match_exact(cursor, code, b")") {
287 let arg = parse_name(cursor, code)?;
288 vars.push(arg.clone());
289 ret_arg.push(arg);
290 prepare_to_parse(cursor, code)?;
291 if code[cursor.index] == b',' {
292 advance_char(cursor, 1);
293 prepare_to_parse(cursor, code)?;
294 }
295 }
296 advance_char(cursor, 1);
297 parse_one_of(cursor, code, &[b"=>"])?;
298 }
299 let ret_bod = parse_term(cursor, code, vars, defs)?;
300 for _ in 0..ret_arg.len() {
301 vars.pop();
302 }
303 vars.pop();
304 skip_whites(cursor, code);
305
306 let mut cas : Vec<(Vec<u8>, Vars, Box<Term>)> = Vec::new();
308 while cursor.index < code.len() && match_exact(cursor, code, b"|") {
309 advance_char(cursor, 1);
310
311 let cas_nam = parse_name(cursor, code)?;
313
314 vars.push(b"fold".to_vec());
316
317 let mut cas_arg = Vec::new();
319 prepare_to_parse(cursor, code)?;
320 if match_exact(cursor, code, b"(") {
321 advance_char(cursor, 1);
322 while !match_exact(cursor, code, b")") {
323 let arg = parse_name(cursor, code)?;
324 vars.push(arg.clone());
325 cas_arg.push(arg);
326 prepare_to_parse(cursor, code)?;
327 if code[cursor.index] == b',' {
328 advance_char(cursor, 1);
329 prepare_to_parse(cursor, code)?;
330 }
331 }
332 advance_char(cursor, 1);
333 }
334
335 parse_one_of(cursor, code, &[b"=>"])?;
337
338 let cas_bod = parse_term(cursor, code, vars, defs)?;
340 let cas_bod = Box::new(cas_bod);
341
342 for _ in 0..cas_arg.len() {
344 vars.pop();
345 }
346 vars.pop();
347 cas.push((cas_nam, cas_arg, cas_bod));
348 skip_whites(cursor, code);
349 }
350
351 let val = Box::new(val);
353 let ret = (ret_arg, Box::new(ret_bod));
354 parsed = Cas{val, cas, ret};
355 appliable = false;
356
357 } else if match_exact(cursor, code, b"copy") {
359 advance_char(cursor, 4);
360 let val = parse_term(cursor, code, vars, defs)?;
361 parse_one_of(cursor, code, &[b"as"])?;
362 let nam_a = parse_name(cursor, code)?;
363 vars.push(nam_a.clone());
364 parse_one_of(cursor, code, &[b","])?;
365 let nam_b = parse_name(cursor, code)?;
366 vars.push(nam_b.clone());
367 let nam = (nam_a, nam_b);
368 parse_one_of(cursor, code, &[b"in"])?;
369 let bod = parse_term(cursor, code, vars, defs)?;
370 vars.pop();
371 vars.pop();
372 let val = Box::new(val);
373 let bod = Box::new(bod);
374 parsed = Cpy{nam, val, bod};
375 appliable = false;
376
377 } else if match_exact(cursor, code, b"let") {
379 advance_char(cursor, 3);
380 let nam = parse_name(cursor, code)?;
381 let val = parse_term(cursor, code, vars, defs)?;
382 defs.insert(nam.to_vec(), val);
383 let bod = parse_term(cursor, code, vars, defs)?;
384 parsed = bod;
385 appliable = false;
386
387 } else {
389 let nam = parse_name(cursor, code)?;
390 if nam.len() > 0 && nam[0] >= b'0' && nam[0] <= b'9' {
391 let nam = unsafe { String::from_utf8_unchecked(nam) };
392 let nat = nam.parse::<i32>().unwrap();
393 parsed = extra::build_church_nat(nat);
394 } else {
395 let mut idx : Option<usize> = None;
396 for i in (0..vars.len()).rev() {
397 if vars[i] == nam {
398 idx = Some(vars.len() - i - 1);
399 break;
400 }
401 }
402 parsed = match idx {
403 Some(idx) => Var{idx: idx as i32},
404 None => Ref{nam: nam.to_vec()}
405 };
406 }
407 appliable = true;
408 };
409
410 let (parsed, appliable) = if match_exact(cursor, code, b"<") {
412 advance_char(cursor, 1);
413 prepare_to_parse(cursor, code)?;
414 let mut idt = parsed.clone();
415 weak_reduce(&mut idt, defs, true);
416 match idt {
417 Idt{nam: _, ref mut arg, par: _, typ: _, ctr: _} => {
418 while !match_exact(cursor, code, b">") {
419 arg.push(Box::new(parse_term(cursor, code, vars, defs)?));
420 prepare_to_parse(cursor, code)?;
421 if code[cursor.index] == b',' {
422 advance_char(cursor, 1);
423 prepare_to_parse(cursor, code)?;
424 }
425 }
426 advance_char(cursor, 1);
427 },
428 _ => panic!("TODO")
429 }
430 (idt, true)
431 } else {
432 (parsed, appliable)
433 };
434
435 let (parsed, appliable) = if match_exact(cursor, code, b".") {
437 advance_char(cursor, 1);
438 let idt = weak_reduced(&parsed, defs, true);
439 let nam = parse_name(cursor, code)?;
440 let ctr = extra::build_idt_ctr(&idt, nam);
441 (ctr, true)
442 } else {
443 (parsed, appliable)
444 };
445
446 let (parsed, appliable) = if match_exact(cursor, code, b"{") {
448 advance_char(cursor, 1);
449 prepare_to_parse(cursor, code)?;
450 let idt = parsed.clone();
451 let mut ctr = Vec::new();
452 match weak_reduced(&idt, defs, true) {
453 Idt{nam: _, arg: _, par: _, typ: _, ctr: idt_ctr} => {
454 for i in 0..idt_ctr.len() {
455 ctr.push(idt_ctr[i].0.clone());
456 }
457 },
458 _ => {}
459 }
460 for i in 0..ctr.len() {
461 vars.push(ctr[i].to_vec())
462 }
463 let bod = parse_term(cursor, code, vars, defs)?;
464 for _ in 0..ctr.len() {
465 vars.pop();
466 }
467 parse_one_of(cursor, code, &[b"}"])?;
468 let idt = Box::new(idt);
469 let bod = Box::new(bod);
470 (New{idt, ctr, bod}, true)
471 } else {
472 (parsed, appliable)
473 };
474
475 if appliable {
477 let mut app = parsed;
478 while match_exact(cursor, code, b"(") {
479 advance_char(cursor, 1);
480 let mut args : Vec<Term> = Vec::new();
482 while !match_exact(cursor, code, b")") {
483 let arg = parse_term(cursor, code, vars, defs)?;
484 args.push(arg);
485 prepare_to_parse(cursor, code)?;
486 if code[cursor.index] == b',' {
487 advance_char(cursor, 1);
488 prepare_to_parse(cursor, code)?;
489 }
490 }
491 advance_char(cursor, 1);
492 for i in 0..args.len() {
494 let fun = Box::new(app);
495 let arg = Box::new(args[i].clone());
496 app = App{fun, arg}
497 }
498 }
499 Ok(app)
500 } else {
501 Ok(parsed)
502 }
503}
504
505pub fn term_from_ascii_slice<'a>(code : &'a [u8]) -> Result<(Term, Defs), String> {
507 let mut cursor = Cursor{index: 0, line: 0, column: 0};
508 let mut vars = Vec::new();
509 let mut defs = HashMap::new();
510 let term = parse_term(&mut cursor, code, &mut vars, &mut defs)?;
511 Ok((term, defs))
512}
513
514pub fn term_from_ascii(code : Vec<u8>) -> Result<(Term, Defs), String> {
516 term_from_ascii_slice(&code)
517}
518
519pub fn term_from_string_slice(code : &str) -> Result<(Term, Defs), String> {
521 term_from_ascii_slice(code.as_bytes())
522}
523
524pub fn term_from_string(code : String) -> Result<(Term, Defs), String> {
526 term_from_string_slice(&code)
527}
528
529pub fn term_to_ascii(term : &Term, vars : &mut Vars, short : bool) -> Vec<u8> {
531 fn build(code : &mut Vec<u8>, term : &Term, vars : &mut Vars, short : bool) {
532 match term {
533 &App{ref fun, ref arg} => {
534 build(code, &fun, vars, short);
535 code.extend_from_slice(b"(");
536 build(code, &arg, vars, short);
537 code.extend_from_slice(b")");
538 },
539 &Lam{ref nam, ref typ, ref bod} => {
540 let nam = rename(nam, vars);
541 code.extend_from_slice(b"((");
542 code.append(&mut nam.clone());
543 code.extend_from_slice(b" : ");
544 build(code, &typ, vars, short);
545 code.extend_from_slice(b") => ");
546 vars.push(nam.to_vec());
547 build(code, &bod, vars, short);
548 vars.pop();
549 code.extend_from_slice(b")");
550 },
551 &All{ref nam, ref typ, ref bod} => {
552 let nam = rename(nam, vars);
553 code.extend_from_slice(b"((");
554 code.append(&mut nam.clone());
555 code.extend_from_slice(b" : ");
556 build(code, &typ, vars, short);
557 code.extend_from_slice(b") -> ");
558 vars.push(nam.to_vec());
559 build(code, &bod, vars, short);
560 vars.pop();
561 code.extend_from_slice(b")");
562 },
563 &Var{idx} => {
564 let new_idx = vars.len() - idx as usize - 1;
565 let mut quo = b"X".to_vec();
566 quo.append(&mut idx.to_string().into_bytes());
567 let nam = if new_idx < vars.len() { &vars[new_idx] } else { &quo };
568 code.append(&mut nam.clone());
569 },
570 &Ref{ref nam} => {
571 code.append(&mut nam.clone());
572 },
573 &Idt{ref nam, ref arg, ref par, ref typ, ref ctr} => {
574 let nam = rename(nam, vars);
575 if short {
576 code.append(&mut nam.clone());
577 } else {
578 code.extend_from_slice(b"(data ");
579 code.append(&mut nam.clone());
580 code.extend_from_slice(b" : ");
581 for i in 0..par.len() {
582 vars.push(par[i].0.clone());
583 }
584 vars.push(nam.to_vec());
585 build(code, &typ, vars, short);
586 for (nam,typ) in ctr {
587 code.extend_from_slice(b" ");
588 code.extend_from_slice(b"| ");
589 code.append(&mut nam.clone());
590 code.extend_from_slice(b" : ");
591 build(code, &typ, vars, short);
592 }
593 for _ in 0..par.len() {
594 vars.pop();
595 }
596 vars.pop();
597 code.extend_from_slice(b")");
598 }
599 if arg.len() > 0 {
600 code.extend_from_slice(b"<");
601 for i in 0..arg.len() {
602 build(code, &arg[i], vars, short);
603 if i < arg.len() - 1 {
604 code.extend_from_slice(b",");
605 }
606 }
607 code.extend_from_slice(b">");
608 }
609 },
610 &New{ref idt, ref ctr, ref bod} => {
611 build(code, &idt, vars, short);
612 code.extend_from_slice(b"{");
613 for i in 0..ctr.len() {
614 vars.push(ctr[i].to_vec())
615 }
616 build(code, &bod, vars, short);
617 for _ in 0..ctr.len() {
618 vars.pop();
619 }
620 code.extend_from_slice(b"}");
621 },
622 &Cas{ref val, ref cas, ref ret} => {
623 code.extend_from_slice(b"(case ");
624 build(code, &val, vars, short);
625 code.extend_from_slice(b" -> ");
626 vars.push(b"self".to_vec());
627 code.extend_from_slice(b"(");
628 for i in 0..ret.0.len() {
629 let mut ret_arg_nam = rename(&ret.0[i], vars);
630 code.append(&mut ret_arg_nam.clone());
631 vars.push(ret_arg_nam.to_vec());
632 if i < ret.0.len() - 1 {
633 code.extend_from_slice(b",");
634 }
635 }
636 code.extend_from_slice(b") => ");
637 build(code, &ret.1, vars, short);
638 for (nam, arg, bod) in cas {
639 code.extend_from_slice(b" ");
640 code.extend_from_slice(b"| ");
641 code.append(&mut nam.clone());
642 vars.push(b"fold".to_vec());
643 code.extend_from_slice(b"(");
644 for i in 0..arg.len() {
645 let mut arg_nam = rename(&arg[i], vars);
646 code.append(&mut arg_nam.clone());
647 vars.push(arg_nam.to_vec());
648 if i < arg.len() - 1 {
649 code.extend_from_slice(b",");
650 }
651 }
652 code.extend_from_slice(b")");
653 code.extend_from_slice(b" => ");
654 build(code, &bod, vars, short);
655 for _ in 0..arg.len() {
656 vars.pop();
657 }
658 vars.pop();
659 }
660 code.extend_from_slice(b")");
661 for _ in 0..ret.0.len() {
662 vars.pop();
663 }
664 vars.pop();
665 },
666 &Cpy{ref nam, ref val, ref bod} => {
667 code.extend_from_slice(b"copy ");
668 build(code, &val, vars, short);
669 code.extend_from_slice(b" as ");
670 code.append(&mut nam.0.clone());
671 vars.push(nam.0.to_vec());
672 code.extend_from_slice(b", ");
673 code.append(&mut nam.1.clone());
674 vars.push(nam.1.to_vec());
675 code.extend_from_slice(b" in ");
676 build(code, &bod, vars, short);
677 vars.pop();
678 vars.pop();
679 },
680 &Set => {
681 code.extend_from_slice(b"Type");
682 }
683 }
684 }
685 let mut code = Vec::new();
686 build(&mut code, term, vars, short);
687 return code;
688}
689
690pub fn ascii_to_string(ascii : Vec<u8>) -> String {
691 match String::from_utf8(ascii) {
692 Ok(s) => s,
693 Err(_) => String::from("Stringified code not a valid UTF8 string. This is a ironically a Formality bug.")
694 }
695}
696
697pub fn term_to_string(term : &Term, vars : &mut Vars, short : bool) -> String {
699 ascii_to_string(term_to_ascii(term, vars, short))
700}
701
702pub fn type_error_to_ascii(type_error : &TypeError, short : bool) -> Vec<u8> {
704 let mut message = Vec::new();
705 match type_error {
706 AppTypeMismatch{ref expect, ref actual, ref argval, ref term, ref vars} => {
707 message.extend_from_slice(b"Type mismatch.\n");
708 message.extend_from_slice(b"- This term : ");
709 message.append(&mut term_to_ascii(argval, &mut vars.clone(), short));
710 message.extend_from_slice(b"\n");
711 message.extend_from_slice(b"- Has type : ");
712 message.append(&mut term_to_ascii(actual, &mut vars.clone(), short));
713 message.extend_from_slice(b"\n");
714 message.extend_from_slice(b"- Instead of : ");
715 message.append(&mut term_to_ascii(expect, &mut vars.clone(), short));
716 message.extend_from_slice(b"\n");
717 message.extend_from_slice(b"- On call : ");
718 message.append(&mut term_to_ascii(term, &mut vars.clone(), short));
719 message.extend_from_slice(b"\n");
720 },
721 AppNotAll{ref funval, ref funtyp, ref term, ref vars} => {
722 message.extend_from_slice(b"Not a function.\n");
723 message.extend_from_slice(b"- This term : ");
724 message.append(&mut term_to_ascii(funval, &mut vars.clone(), short));
725 message.extend_from_slice(b"\n");
726 message.extend_from_slice(b"- Has type : ");
727 message.append(&mut term_to_ascii(funtyp, &mut vars.clone(), short));
728 message.extend_from_slice(b"\n");
729 message.extend_from_slice(b"- On call : ");
730 message.append(&mut term_to_ascii(term, &mut vars.clone(), short));
731 message.extend_from_slice(b"\n");
732 message.extend_from_slice(b"* It should have a function type (i.e., `(a : A) -> B`) instead.\n");
733 },
734 ForallNotAType{ref typtyp, ref bodtyp, ref term, ref vars} => {
735 message.extend_from_slice(b"Invalid arrow.\n");
736 message.extend_from_slice(b"- Left type : ");
737 message.append(&mut term_to_ascii(typtyp, &mut vars.clone(), short));
738 message.extend_from_slice(b"\n");
739 message.extend_from_slice(b"- Right type : ");
740 message.append(&mut term_to_ascii(bodtyp, &mut vars.clone(), short));
741 message.extend_from_slice(b"\n");
742 message.extend_from_slice(b"- On forall : ");
743 message.append(&mut term_to_ascii(term, &mut vars.clone(), short));
744 message.extend_from_slice(b"\n");
745 message.extend_from_slice(b"* To create an arrow, you need both sides to have type `Type`.\n");
746 },
747 Unbound{ref name, ref vars} => {
748 message.extend_from_slice(b"Undefined variable: `");
749 message.append(&mut name.clone());
750 message.extend_from_slice(b"`.\n");
751 message.extend_from_slice(b"- Vars in scope: ");
752 for i in 0..vars.len() {
753 let mut var : Vec<u8> = vars[i].clone();
754 message.extend_from_slice(b"`");
755 message.append(&mut var);
756 message.extend_from_slice(b"`");
757 if i < vars.len() - 1 {
758 message.extend_from_slice(b", ");
759 }
760 }
761 message.extend_from_slice(b".");
762 },
763 NewTypeMismatch{ref expect, ref actual, ref term, ref vars} => {
764 message.extend_from_slice(b"Type mismatch.\n");
765 message.extend_from_slice(b"- This term : ");
766 message.append(&mut term_to_ascii(term, &mut vars.clone(), short));
767 message.extend_from_slice(b"\n");
768 message.extend_from_slice(b"- Has type : ");
769 message.append(&mut term_to_ascii(actual, &mut vars.clone(), short));
770 message.extend_from_slice(b"\n");
771 message.extend_from_slice(b"- Instead of : ");
772 message.append(&mut term_to_ascii(expect, &mut vars.clone(), short));
773 message.extend_from_slice(b"\n");
774 message.extend_from_slice(b"- On inst : ");
775 message.append(&mut term_to_ascii(term, &mut vars.clone(), short));
776 message.extend_from_slice(b"\n");
777 },
778 MatchNotIDT{ref actual, term: _, ref vars} => {
779 message.extend_from_slice(b"Not a datatype.");
780 message.extend_from_slice(b"- Expected : (a datatype).\n");
781 message.extend_from_slice(b"- Found : ");
782 message.append(&mut term_to_ascii(actual, &mut vars.clone(), short));
783 message.extend_from_slice(b"\n");
784 message.extend_from_slice(b"* You attempted to pattern match a value that isn't member of a datatype.");
789 },
790 WrongMatchIndexCount{ref expect, ref actual, term: ref _term, vars: ref _vars} => {
791 message.extend_from_slice(b"Incorrect match index count.");
792 message.extend_from_slice(b"- Expected : ");
793 message.append(&mut expect.to_string().into_bytes());
794 message.extend_from_slice(b"\n");
795 message.extend_from_slice(b"- Found : ");
796 message.append(&mut actual.to_string().into_bytes());
797 message.extend_from_slice(b"\n");
798 message.extend_from_slice(b"* The matched value isn't a concrete datatype.\n");
802 },
803 WrongMatchReturnArity{ref expect, ref actual, term: ref _term, vars: ref _vars} => {
804 message.extend_from_slice(b"Incorrect match return arity.\n");
805 message.extend_from_slice(b"- Expected : ");
806 message.append(&mut expect.to_string().into_bytes());
807 message.extend_from_slice(b"\n");
808 message.extend_from_slice(b"- Found : ");
809 message.append(&mut actual.to_string().into_bytes());
810 message.extend_from_slice(b"\n");
811 message.extend_from_slice(b"* The specified return type of pattern match has the wrong number of arguments.\n");
815 },
816 WrongMatchCaseCount{ref expect, ref actual, term: ref _term, vars: ref _vars} => {
817 message.extend_from_slice(b"Incorrect case count.\n");
818 message.extend_from_slice(b"- Expected : ");
819 message.append(&mut expect.to_string().into_bytes());
820 message.extend_from_slice(b"\n");
821 message.extend_from_slice(b"- Found : ");
822 message.append(&mut actual.to_string().into_bytes());
823 message.extend_from_slice(b"\n");
824 message.extend_from_slice(b"* The number of cases should be equal to the number of constructors.\n");
828 },
829 WrongCaseName{ref expect, ref actual, term: ref _term, vars: ref _vars} => {
830 message.extend_from_slice(b"Incorrect case name.\n");
831 message.extend_from_slice(b"- Expected : ");
832 message.append(&mut expect.clone());
833 message.extend_from_slice(b"\n");
834 message.extend_from_slice(b"- Found : ");
835 message.append(&mut actual.clone());
836 message.extend_from_slice(b"\n");
837 },
841 WrongCaseArity{ref expect, ref actual, ref name, term: ref _term, vars: ref _vars} => {
842 message.extend_from_slice(b"Incorrect case arity.\n");
843 message.extend_from_slice(b"- Expected : ");
844 message.append(&mut expect.to_string().into_bytes());
845 message.extend_from_slice(b"\n");
846 message.extend_from_slice(b"- Found : ");
847 message.append(&mut actual.to_string().into_bytes());
848 message.extend_from_slice(b"\n");
849 message.extend_from_slice(b"* The case `");
853 message.append(&mut name.clone());
854 message.extend_from_slice(b"` of this match has the incorrect number of fields.");
855 },
856 WrongCaseType{ref expect, ref actual, ref name, term: ref _term, vars} => {
857 message.extend_from_slice(b"Incorrect case type.\n");
858 message.extend_from_slice(b"- Expected : ");
859 message.append(&mut term_to_ascii(expect, &mut vars.clone(), short));
860 message.extend_from_slice(b"\n");
861 message.extend_from_slice(b"- Found : ");
862 message.append(&mut term_to_ascii(actual, &mut vars.clone(), short));
863 message.extend_from_slice(b"\n");
864 message.extend_from_slice(b"* The case `");
868 message.append(&mut name.clone());
869 message.extend_from_slice(b"` of this match has the incorrect type.");
870 }
871 }
872 return message;
873}
874
875pub fn type_error_to_string(type_error : &TypeError, short : bool) -> String {
877 ascii_to_string(type_error_to_ascii(type_error, short))
878}
879
880pub fn infer_with_string_error(term : &Term, defs : &Defs, checked : bool, short : bool) -> Result<Term, String> {
882 match infer(term, defs, checked) {
883 Ok(term) => Ok(term),
884 Err(err) => Err(type_error_to_string(&err, short))
885 }
886}
887
888impl std::fmt::Display for Term {
890 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
891 write!(f, "{}", String::from_utf8_lossy(&term_to_ascii(&self, &mut Vec::new(), true)))
892 }
893}