1use crate::{
2 defs::Defs,
3 name::Name,
4 parse::{
5 error::{
6 throw_err,
7 ParseError,
8 ParseErrorKind,
9 },
10 literal::*,
11 op::parse_opr,
12 },
13 position::Pos,
14 term::{
15 LitType,
16 Term,
17 Uses,
18 },
19};
20
21use sp_cid::Cid;
22use sp_multihash::{
23 Code,
24 MultihashDigest,
25};
26
27use sp_im::conslist::ConsList;
28use sp_ipld::{
29 dag_cbor::DagCborCodec,
30 Codec,
31};
32
33use sp_std::{
34 borrow::ToOwned,
35 boxed::Box,
36 cell::RefCell,
37 rc::Rc,
38 vec::Vec,
39};
40
41use alloc::string::{
42 String,
43 ToString,
44};
45
46use crate::parse::span::Span;
47
48use nom::{
49 branch::alt,
50 bytes::complete::{
51 tag,
52 take_till,
53 take_till1,
54 },
55 character::complete::{
56 digit1,
57 multispace0,
58 multispace1,
59 satisfy,
60 },
61 combinator::{
62 eof,
63 map,
64 opt,
65 peek,
66 success,
67 value,
68 },
69 error::context,
70 multi::{
71 many0,
72 many1,
73 separated_list1,
74 },
75 sequence::{
76 delimited,
77 preceded,
78 terminated,
79 },
80 Err,
81 IResult,
82};
83use sp_std::collections::vec_deque::VecDeque;
84
85pub type Ctx = ConsList<Name>;
87
88pub fn reserved_symbols() -> VecDeque<String> {
90 VecDeque::from(vec![
91 String::from("//"),
92 String::from("λ"),
93 String::from("ω"),
94 String::from("lambda"),
95 String::from("=>"),
96 String::from("∀"),
97 String::from("forall"),
98 String::from("->"),
99 String::from("@"),
100 String::from("="),
101 String::from(";"),
102 String::from("::"),
103 String::from("let"),
104 String::from("in"),
105 String::from("type"),
106 String::from("data"),
107 String::from("def"),
108 String::from("open"),
109 String::from("case"),
110 String::from("Type"),
111 ])
112}
113
114pub fn parse_line_comment(i: Span) -> IResult<Span, Span, ParseError<Span>> {
116 let (i, _) = tag("//")(i)?;
117 let (i, com) = take_till(|c| c == '\n')(i)?;
118 Ok((i, com))
119}
120
121pub fn parse_space(i: Span) -> IResult<Span, Vec<Span>, ParseError<Span>> {
123 let (i, _) = multispace0(i)?;
124 let (i, com) = many0(terminated(parse_line_comment, multispace1))(i)?;
125 Ok((i, com))
126}
127
128pub fn parse_space1(i: Span) -> IResult<Span, Vec<Span>, ParseError<Span>> {
130 let (i, _) = multispace1(i)?;
131 let (i, com) = many0(terminated(parse_line_comment, multispace1))(i)?;
132 Ok((i, com))
133}
134
135pub fn parse_name(from: Span) -> IResult<Span, Name, ParseError<Span>> {
137 let (i, s) = take_till1(|x| {
138 char::is_whitespace(x)
139 | (x == ':')
140 | (x == ';')
141 | (x == ')')
142 | (x == '(')
143 | (x == '{')
144 | (x == '}')
145 | (x == ',')
146 })(from)?;
147 let s: String = String::from(s.fragment().to_owned());
148 if reserved_symbols().contains(&s) {
149 Err(Err::Error(ParseError::new(from, ParseErrorKind::ReservedKeyword(s))))
150 }
151 else if s.starts_with('#') {
152 Err(Err::Error(ParseError::new(from, ParseErrorKind::ReservedSyntax(s))))
153 }
154 else if is_numeric_symbol_string1(&s) | is_numeric_symbol_string2(&s) {
155 Err(Err::Error(ParseError::new(from, ParseErrorKind::NumericSyntax(s))))
156 }
157 else if !is_valid_symbol_string(&s) {
158 Err(Err::Error(ParseError::new(from, ParseErrorKind::InvalidSymbol(s))))
159 }
160 else {
161 Ok((i, Name::from(s)))
162 }
163}
164
165pub fn is_numeric_symbol_string1(s: &str) -> bool {
167 s.starts_with('0')
168 || s.starts_with('1')
169 || s.starts_with('2')
170 || s.starts_with('3')
171 || s.starts_with('4')
172 || s.starts_with('5')
173 || s.starts_with('6')
174 || s.starts_with('7')
175 || s.starts_with('8')
176 || s.starts_with('9')
177}
178
179pub fn is_numeric_symbol_string2(s: &str) -> bool {
181 s.starts_with("-0")
182 || s.starts_with("-1")
183 || s.starts_with("-2")
184 || s.starts_with("-3")
185 || s.starts_with("-4")
186 || s.starts_with("-5")
187 || s.starts_with("-6")
188 || s.starts_with("-7")
189 || s.starts_with("-8")
190 || s.starts_with("-9")
191 || s.starts_with("+0")
192 || s.starts_with("+1")
193 || s.starts_with("+2")
194 || s.starts_with("+3")
195 || s.starts_with("+4")
196 || s.starts_with("+5")
197 || s.starts_with("+6")
198 || s.starts_with("+7")
199 || s.starts_with("+8")
200 || s.starts_with("+9")
201}
202
203pub fn is_valid_symbol_char(c: char) -> bool {
205 c != ':'
206 && c != ';'
207 && c != '('
208 && c != ')'
209 && c != '{'
210 && c != '}'
211 && c != ','
212 && !char::is_whitespace(c)
213 && !char::is_control(c)
214}
215
216pub fn is_valid_symbol_string(s: &str) -> bool {
218 let invalid_chars = s.starts_with('"')
219 || s.starts_with('\'')
220 || s.starts_with('#')
221 || s.chars().any(|x| !is_valid_symbol_char(x));
222 !s.is_empty() && !invalid_chars
223}
224
225pub fn parse_antiquote(
228 ctx: Ctx,
229 quasi: Rc<VecDeque<Term>>,
230) -> impl Fn(Span) -> IResult<Span, Term, ParseError<Span>> {
231 move |from: Span| {
232 let (upto, nam) =
233 context("quasiquoted value", preceded(tag("#$"), digit1))(from)?;
234 if let Some((_, trm)) = quasi
235 .iter()
236 .enumerate()
237 .find(|(i, _)| format!("{}", i) == nam.to_string())
238 {
239 Ok((upto, trm.clone()))
240 }
241 else {
242 Err(Err::Error(ParseError::new(
243 upto,
244 ParseErrorKind::UndefinedReference(
245 Name::from(format!("#${}", nam.to_string())),
246 ctx.clone(),
247 ),
248 )))
249 }
250 }
251}
252
253pub fn parse_var(
255 input: Cid,
256 defs: Rc<RefCell<Defs>>,
257 rec: Option<Name>,
258 ctx: Ctx,
259) -> impl Fn(Span) -> IResult<Span, Term, ParseError<Span>> {
260 move |from: Span| {
261 let (upto, nam) = context("local or global reference", parse_name)(from)?;
262 let pos = Pos::from_upto(input, from, upto);
263 let is_rec_name = match rec.clone() {
264 Some(rec_ref) => nam == rec_ref,
265 _ => false,
266 };
267 if let Some((idx, _)) = ctx.iter().enumerate().find(|(_, x)| **x == nam) {
268 Ok((upto, Term::Var(pos, nam.clone(), idx as u64)))
269 }
270 else if is_rec_name {
271 Ok((upto, Term::Rec(pos)))
272 }
273 else if let Some(def) = defs.as_ref().borrow().get(&nam) {
274 Ok((upto, Term::Ref(pos, nam.clone(), def.def_cid, def.ast_cid)))
275 }
276 else {
277 Err(Err::Error(ParseError::new(
278 upto,
279 ParseErrorKind::UndefinedReference(nam.clone(), ctx.clone()),
280 )))
281 }
282 }
283}
284
285pub fn parse_lam(
287 input: Cid,
288 defs: Rc<RefCell<Defs>>,
289 rec: Option<Name>,
290 ctx: Ctx,
291 quasi: Rc<VecDeque<Term>>,
292) -> impl Fn(Span) -> IResult<Span, Term, ParseError<Span>> {
293 move |from: Span| {
294 let (i, _) = alt((tag("λ"), tag("lambda")))(from)?;
295 let (i, _) = parse_space(i)?;
296 let (i, ns) = separated_list1(multispace1, parse_name)(i)?;
297 let (i, _) = parse_space(i)?;
298 let (i, _) = tag("=>")(i)?;
299 let (i, _) = parse_space(i)?;
300 let mut ctx2 = ctx.clone();
301 for n in ns.clone().into_iter() {
302 ctx2 = ctx2.cons(n);
303 }
304 let (upto, bod) = parse_expression(
305 input,
306 defs.clone(),
307 rec.clone(),
308 ctx2,
309 quasi.to_owned(),
310 )(i)?;
311 let pos = Pos::from_upto(input, from, upto);
312 let trm = ns
313 .iter()
314 .rev()
315 .fold(bod, |acc, n| Term::Lam(pos, n.clone(), Box::new(acc)));
316 Ok((upto, trm))
317 }
318}
319
320pub fn parse_uses(
322 default: Uses,
323) -> impl Fn(Span) -> IResult<Span, Uses, ParseError<Span>> {
324 move |i: Span| {
325 alt((
326 value(Uses::Many, terminated(tag("ω"), multispace1)),
327 value(Uses::None, terminated(tag("0"), multispace1)),
328 value(Uses::Affi, terminated(tag("&"), multispace1)),
329 value(Uses::Once, terminated(tag("1"), multispace1)),
330 success(default),
331 ))(i)
332 }
333}
334
335pub fn parse_binder_full(
337 input: Cid,
338 defs: Rc<RefCell<Defs>>,
339 rec: Option<Name>,
340 ctx: Ctx,
341 quasi: Rc<VecDeque<Term>>,
342 uses: Uses,
343) -> impl Fn(Span) -> IResult<Span, Vec<(Uses, Name, Term)>, ParseError<Span>> {
344 move |i: Span| {
345 let (i, _) = tag("(")(i)?;
346 let (i, _) = parse_space(i)?;
347 let (i, u) = parse_uses(uses)(i)?;
348 let (i, ns) = many1(terminated(parse_name, parse_space))(i)?;
349 let (i, _) = tag(":")(i)?;
350 let (i, _) = parse_space(i)?;
351 let (i, typ) = parse_expression(
352 input,
353 defs.clone(),
354 rec.clone(),
355 ctx.clone(),
356 quasi.to_owned(),
357 )(i)?;
358 let (i, _) = tag(")")(i)?;
359 let mut res = Vec::new();
360 for (i, n) in ns.iter().enumerate() {
361 res.push((u, n.to_owned(), typ.clone().shift(i as i64, Some(0))))
362 }
363 Ok((i, res))
364 }
365}
366
367pub fn parse_binder_short(
369 input: Cid,
370 defs: Rc<RefCell<Defs>>,
371 rec: Option<Name>,
372 ctx: Ctx,
373 quasi: Rc<VecDeque<Term>>,
374 uses: Uses,
375) -> impl Fn(Span) -> IResult<Span, Vec<(Uses, Name, Term)>, ParseError<Span>> {
376 move |i: Span| {
377 map(
378 parse_term(
379 input,
380 defs.clone(),
381 rec.clone(),
382 ctx.clone(),
383 quasi.to_owned(),
384 ),
385 |t| vec![(uses, Name::from("_"), t)],
386 )(i)
387 }
388}
389
390pub fn parse_binder(
392 input: Cid,
393 defs: Rc<RefCell<Defs>>,
394 rec: Option<Name>,
395 ctx: Ctx,
396 quasi: Rc<VecDeque<Term>>,
397 nam_opt: bool,
398 uses: Uses,
399) -> impl Fn(Span) -> IResult<Span, Vec<(Uses, Name, Term)>, ParseError<Span>> {
400 move |i: Span| {
401 if nam_opt {
402 alt((
403 parse_binder_full(
404 input,
405 defs.clone(),
406 rec.clone(),
407 ctx.clone(),
408 quasi.clone(),
409 uses,
410 ),
411 parse_binder_short(
412 input,
413 defs.to_owned(),
414 rec.clone(),
415 ctx.clone(),
416 quasi.to_owned(),
417 uses,
418 ),
419 ))(i)
420 }
421 else {
422 parse_binder_full(
423 input,
424 defs.to_owned(),
425 rec.clone(),
426 ctx.clone(),
427 quasi.to_owned(),
428 uses,
429 )(i)
430 }
431 }
432}
433
434pub fn parse_binders(
436 input: Cid,
437 defs: Rc<RefCell<Defs>>,
438 rec: Option<Name>,
439 ctx: Ctx,
440 quasi: Rc<VecDeque<Term>>,
441 nam_opt: bool,
442 terminator: Vec<char>,
443 uses: Uses,
444) -> impl FnMut(Span) -> IResult<Span, Vec<(Uses, Name, Term)>, ParseError<Span>>
445{
446 move |mut i: Span| {
447 let mut ctx = ctx.clone();
448 let mut res = Vec::new();
449
450 loop {
451 match preceded(parse_space, peek(satisfy(|x| terminator.contains(&x))))(i)
452 {
453 Ok((i2, _)) => return Ok((i2, res)),
454 _ => {}
455 }
456 match preceded(
457 parse_space,
458 parse_binder(
459 input,
460 defs.to_owned(),
461 rec.clone(),
462 ctx.clone(),
463 quasi.to_owned(),
464 nam_opt,
465 uses,
466 ),
467 )(i)
468 {
469 Err(e) => return Err(e),
470 Ok((i2, bs)) => {
471 for (u, n, t) in bs {
472 ctx = ctx.cons(n.to_owned());
473 res.push((u, n, t));
474 }
475 i = i2;
476 }
477 }
478 }
479 }
480}
481
482pub fn parse_binders1(
484 input: Cid,
485 defs: Rc<RefCell<Defs>>,
486 rec: Option<Name>,
487 ctx: Ctx,
488 quasi: Rc<VecDeque<Term>>,
489 nam_opt: bool,
490 terminator: Vec<char>,
491 uses: Uses,
492) -> impl FnMut(Span) -> IResult<Span, Vec<(Uses, Name, Term)>, ParseError<Span>>
493{
494 move |mut i: Span| {
495 let mut ctx = ctx.clone();
496 let mut res = Vec::new();
497
498 match parse_binder(
499 input,
500 defs.to_owned(),
501 rec.clone(),
502 ctx.clone(),
503 quasi.to_owned(),
504 nam_opt,
505 uses,
506 )(i.to_owned())
507 {
508 Err(e) => return Err(e),
509 Ok((i1, bs)) => {
510 for (u, n, t) in bs {
511 ctx = ctx.cons(n.to_owned());
512 res.push((u, n, t));
513 }
514 i = i1;
515 }
516 }
517 let (i, mut res2) = parse_binders(
518 input,
519 defs.to_owned(),
520 rec.clone(),
521 ctx.clone(),
522 quasi.to_owned(),
523 nam_opt,
524 terminator.clone(),
525 uses,
526 )(i)?;
527 res.append(&mut res2);
528 Ok((i, res))
529 }
530}
531
532pub fn parse_all(
534 input: Cid,
535 defs: Rc<RefCell<Defs>>,
536 rec: Option<Name>,
537 ctx: Ctx,
538 quasi: Rc<VecDeque<Term>>,
539) -> impl Fn(Span) -> IResult<Span, Term, ParseError<Span>> {
540 move |from: Span| {
541 let (i, _) = alt((tag("∀"), tag("forall")))(from)?;
542 let (i, _) = parse_space(i)?;
543 let (i, bs) = parse_binders1(
544 input,
545 defs.clone(),
546 rec.clone(),
547 ctx.clone(),
548 quasi.clone(),
549 true,
550 vec!['-'],
551 Uses::Many,
552 )(i)?;
553 let (i, _) = tag("->")(i)?;
554 let (i, _) = parse_space(i)?;
555 let mut ctx2 = ctx.clone();
556 for (_, n, _) in bs.iter() {
557 ctx2 = ctx2.cons(n.clone());
558 }
559 let (upto, bod) = parse_expression(
560 input,
561 defs.to_owned(),
562 rec.clone(),
563 ctx2,
564 quasi.to_owned(),
565 )(i)?;
566 let pos = Pos::from_upto(input, from, upto);
567 let trm = bs
568 .into_iter()
569 .rev()
570 .fold(bod, |acc, (u, n, t)| Term::All(pos, u, n, Box::new((t, acc))));
571 Ok((upto, trm))
572 }
573}
574
575pub fn parse_type(
577 input: Cid,
578) -> impl Fn(Span) -> IResult<Span, Term, ParseError<Span>> {
579 move |from: Span| {
580 let (upto, _) = tag("Type")(from)?;
581 let pos = Pos::from_upto(input, from, upto);
582 Ok((upto, Term::Typ(pos)))
583 }
584}
585
586pub fn parse_self(
588 input: Cid,
589 defs: Rc<RefCell<Defs>>,
590 rec: Option<Name>,
591 ctx: Ctx,
592 quasi: Rc<VecDeque<Term>>,
593) -> impl Fn(Span) -> IResult<Span, Term, ParseError<Span>> {
594 move |from: Span| {
595 let (i, _) = nom::character::complete::char('@')(from)?;
596 let (i, n) = parse_name(i)?;
597 let (i, _) = parse_space(i)?;
598 let mut ctx2 = ctx.clone();
599 ctx2 = ctx2.cons(n.clone());
600 let (upto, bod) = parse_expression(
601 input,
602 defs.to_owned(),
603 rec.clone(),
604 ctx2.clone(),
605 quasi.to_owned(),
606 )(i)?;
607 let pos = Pos::from_upto(input, from, upto);
608 Ok((upto, Term::Slf(pos, n, Box::new(bod))))
609 }
610}
611
612pub fn parse_case(
614 input: Cid,
615 defs: Rc<RefCell<Defs>>,
616 rec: Option<Name>,
617 ctx: Ctx,
618 quasi: Rc<VecDeque<Term>>,
619) -> impl Fn(Span) -> IResult<Span, Term, ParseError<Span>> {
620 move |from: Span| {
621 let (i, _) = tag("case")(from)?;
622 let (i, _) = parse_space(i)?;
623 let (upto, bod) = parse_expression(
624 input,
625 defs.to_owned(),
626 rec.clone(),
627 ctx.clone(),
628 quasi.to_owned(),
629 )(i)?;
630 let pos = Pos::from_upto(input, from, upto);
631 Ok((upto, Term::Cse(pos, Box::new(bod))))
632 }
633}
634
635pub fn parse_data(
637 input: Cid,
638 defs: Rc<RefCell<Defs>>,
639 rec: Option<Name>,
640 ctx: Ctx,
641 quasi: Rc<VecDeque<Term>>,
642) -> impl Fn(Span) -> IResult<Span, Term, ParseError<Span>> {
643 move |from: Span| {
644 let (i, _) = tag("data")(from)?;
645 let (i, _) = parse_space(i)?;
646 let (upto, bod) = parse_expression(
647 input,
648 defs.to_owned(),
649 rec.clone(),
650 ctx.clone(),
651 quasi.to_owned(),
652 )(i)?;
653 let pos = Pos::from_upto(input, from, upto);
654 Ok((upto, Term::Dat(pos, Box::new(bod))))
655 }
656}
657
658pub fn parse_bound_expression(
663 input: Cid,
664 defs: Rc<RefCell<Defs>>,
665 type_rec: Option<Name>,
666 term_rec: Option<Name>,
667 ctx: Ctx,
668 quasi: Rc<VecDeque<Term>>,
669 nam: Name,
670 letrec: bool,
671) -> impl Fn(Span) -> IResult<Span, (Term, Term), ParseError<Span>> {
672 move |from: Span| {
673 let (i, bs) = parse_binders(
674 input,
675 defs.clone(),
676 type_rec.clone(),
677 ctx.clone(),
678 quasi.clone(),
679 false,
680 vec![':'],
681 Uses::Many,
682 )(from)?;
683 let (i, _) = tag(":")(i)?;
684 let (i, _) = parse_space(i)?;
685 let mut type_ctx = ctx.clone();
686 for (_, n, _) in bs.iter() {
687 type_ctx = type_ctx.cons(n.clone());
688 }
689 let (i, typ) = parse_expression(
690 input,
691 defs.clone(),
692 type_rec.clone(),
693 type_ctx,
694 quasi.clone(),
695 )(i)?;
696 let mut term_ctx = ctx.clone();
697 if letrec {
698 term_ctx = term_ctx.cons(nam.clone());
699 };
700 for (_, n, _) in bs.iter() {
701 term_ctx = term_ctx.cons(n.clone());
702 }
703 let (i, _) = parse_space(i)?;
704 let (i, _) = tag("=")(i)?;
705 let (i, _) = parse_space(i)?;
706 let (upto, trm) = parse_expression(
707 input,
708 defs.clone(),
709 term_rec.clone(),
710 term_ctx,
711 quasi.clone(),
712 )(i)?;
713 let pos = Pos::from_upto(input, from, upto);
714 let trm = bs
715 .iter()
716 .rev()
717 .fold(trm, |acc, (_, n, _)| Term::Lam(pos, n.clone(), Box::new(acc)));
718 let typ = bs
719 .into_iter()
720 .rev()
721 .fold(typ, |acc, (u, n, t)| Term::All(pos, u, n, Box::new((t, acc))));
722 Ok((upto, (typ, trm)))
723 }
724}
725
726pub fn parse_let(
728 input: Cid,
729 defs: Rc<RefCell<Defs>>,
730 rec: Option<Name>,
731 ctx: Ctx,
732 quasi: Rc<VecDeque<Term>>,
733) -> impl Fn(Span) -> IResult<Span, Term, ParseError<Span>> {
734 move |from: Span| {
735 let (i, letrec) =
736 alt((value(true, tag("letrec")), value(false, tag("let"))))(from)?;
737 let (i, _) = parse_space(i)?;
738 let (i, uses) = parse_uses(Uses::Many)(i)?;
739 let (i, _) = parse_space(i)?;
740 let (i, nam) = parse_name(i)?;
741 let (i, _) = parse_space(i)?;
742 let (i, (typ, exp)) = parse_bound_expression(
743 input,
744 defs.clone(),
745 rec.clone(),
746 rec.clone(),
747 ctx.clone(),
748 quasi.clone(),
749 nam.clone(),
750 letrec,
751 )(i)?;
752 let (i, _) = alt((tag(";"), tag("in")))(i)?;
753 let (i, _) = parse_space(i)?;
754 let mut ctx2 = ctx.clone();
755 ctx2 = ctx2.cons(nam.clone());
756 let (upto, bod) = parse_expression(
757 input,
758 defs.to_owned(),
759 rec.clone(),
760 ctx2,
761 quasi.to_owned(),
762 )(i)?;
763 let pos = Pos::from_upto(input, from, upto);
764 Ok((upto, Term::Let(pos, letrec, uses, nam, Box::new((typ, exp, bod)))))
765 }
766}
767
768pub fn parse_builtin_symbol_end()
770-> impl Fn(Span) -> IResult<Span, (), ParseError<Span>> {
771 move |from: Span| {
772 alt((
773 peek(value((), parse_space1)),
774 peek(value((), eof)),
775 peek(value((), tag("("))),
776 peek(value((), tag(")"))),
777 peek(value((), tag("{"))),
778 peek(value((), tag("}"))),
779 peek(value((), tag(";"))),
780 peek(value((), tag(":"))),
781 peek(value((), tag(","))),
782 ))(from)
783 }
784}
785
786pub fn parse_lty(
788 input: Cid,
789) -> impl Fn(Span) -> IResult<Span, Term, ParseError<Span>> {
790 move |from: Span| {
791 let (i, lty) = alt((
792 value(LitType::Nat, tag("#Nat")),
793 value(LitType::Int, tag("#Int")),
794 value(LitType::Bits, tag("#Bits")),
795 value(LitType::Bytes, tag("#Bytes")),
796 value(LitType::Bool, tag("#Bool")),
797 value(LitType::Text, tag("#Text")),
798 value(LitType::Char, tag("#Char")),
799 value(LitType::U8, tag("#U8")),
800 value(LitType::U16, tag("#U16")),
801 value(LitType::U32, tag("#U32")),
802 value(LitType::U64, tag("#U64")),
803 value(LitType::U128, tag("#U128")),
804 value(LitType::I8, tag("#I8")),
805 value(LitType::I16, tag("#I16")),
806 value(LitType::I32, tag("#I32")),
807 value(LitType::I64, tag("#I64")),
808 value(LitType::I128, tag("#I128")),
809 ))(from)?;
810 let (upto, _) = throw_err(parse_builtin_symbol_end()(i), |_| {
811 ParseError::new(
812 i,
813 ParseErrorKind::LitTypeLacksWhitespaceTermination(lty.to_owned()),
814 )
815 })?;
816 let pos = Pos::from_upto(input, from, upto);
817 Ok((upto, Term::LTy(pos, lty)))
818 }
819}
820pub fn parse_lit(
834 input: Cid,
835) -> impl Fn(Span) -> IResult<Span, Term, ParseError<Span>> {
836 move |from: Span| {
837 let (i, lit) = alt((
838 parse_bits,
839 parse_bytes,
840 parse_bool,
841 parse_text,
842 parse_char,
843 parse_int,
844 parse_nat,
845 ))(from)?;
846 let (upto, _) = throw_err(parse_builtin_symbol_end()(i), |_| {
847 ParseError::new(
848 i,
849 ParseErrorKind::LiteralLacksWhitespaceTermination(lit.to_owned()),
850 )
851 })?;
852 let pos = Pos::from_upto(input, from, upto);
853 Ok((upto, Term::Lit(pos, lit)))
854 }
855}
856
857pub fn parse_expression(
860 input: Cid,
861 defs: Rc<RefCell<Defs>>,
862 rec: Option<Name>,
863 ctx: Ctx,
864 quasi: Rc<VecDeque<Term>>,
865) -> impl Fn(Span) -> IResult<Span, Term, ParseError<Span>> {
866 move |from: Span| {
867 let (i, trm) =
868 parse_apps(input, defs.clone(), rec.clone(), ctx.clone(), quasi.clone())(
869 from,
870 )?;
871 let (i, has_ann) = opt(tag("::"))(i)?;
872 if has_ann.is_some() {
873 let (i, typ) = context(
874 "type annotation",
875 parse_apps(
876 input,
877 defs.clone(),
878 rec.clone(),
879 ctx.clone(),
880 quasi.clone(),
881 ),
882 )(i)?;
883 let pos = Pos::from_upto(input, from, i);
884 Ok((i, Term::Ann(pos, Box::new((typ, trm)))))
885 }
886 else {
887 Ok((i, trm))
888 }
889 }
890}
891pub fn parse_app_end(i: Span) -> IResult<Span, (), ParseError<Span>> {
893 let (i, _) = alt((
894 peek(tag("def")),
895 peek(tag("type")),
896 peek(tag("::")),
897 peek(tag("=")),
898 peek(tag("->")),
899 peek(tag(";")),
900 peek(tag(")")),
901 peek(tag("{")),
902 peek(tag("}")),
903 peek(tag(",")),
904 peek(eof),
905 ))(i)?;
906 Ok((i, ()))
907}
908
909pub fn parse_apps(
911 input: Cid,
912 defs: Rc<RefCell<Defs>>,
913 rec: Option<Name>,
914 ctx: Ctx,
915 quasi: Rc<VecDeque<Term>>,
916) -> impl Fn(Span) -> IResult<Span, Term, ParseError<Span>> {
917 move |from: Span| {
918 let (i2, _) = parse_space(from)?;
919 let (i2, fun) =
920 parse_term(input, defs.clone(), rec.clone(), ctx.clone(), quasi.clone())(
921 i2,
922 )?;
923 let mut i = i2;
924 let mut args = Vec::new();
925 loop {
926 let (i2, _) = parse_space(i)?;
927 match parse_app_end(i2) {
928 Ok((..)) => {
929 let pos = Pos::from_upto(input, from, i2);
930 let trm = args
931 .into_iter()
932 .fold(fun, |acc, arg| Term::App(pos, Box::new((acc, arg))));
933 return Ok((i2, trm));
934 }
935 _ => {
936 let (i2, arg) = parse_term(
937 input,
938 defs.clone(),
939 rec.clone(),
940 ctx.clone(),
941 quasi.clone(),
942 )(i2)?;
943 args.push(arg);
944 i = i2
945 }
946 }
947 }
948 }
949}
950
951pub fn parse_term(
953 input: Cid,
954 defs: Rc<RefCell<Defs>>,
955 rec: Option<Name>,
956 ctx: Ctx,
957 quasi: Rc<VecDeque<Term>>,
958) -> impl Fn(Span) -> IResult<Span, Term, ParseError<Span>> {
959 move |i: Span| {
960 context(
961 "term",
962 alt((
963 delimited(
964 preceded(tag("("), parse_space),
965 context(
966 "expression",
967 parse_expression(
968 input,
969 defs.clone(),
970 rec.clone(),
971 ctx.clone(),
972 quasi.clone(),
973 ),
974 ),
975 context(
976 "close parenthesis ')' of an expression",
977 preceded(parse_space, tag(")")),
978 ),
979 ),
980 parse_self(
981 input,
982 defs.clone(),
983 rec.clone(),
984 ctx.clone(),
985 quasi.clone(),
986 ),
987 parse_data(
988 input,
989 defs.clone(),
990 rec.clone(),
991 ctx.clone(),
992 quasi.clone(),
993 ),
994 parse_case(
995 input,
996 defs.clone(),
997 rec.clone(),
998 ctx.clone(),
999 quasi.clone(),
1000 ),
1001 parse_all(input, defs.clone(), rec.clone(), ctx.clone(), quasi.clone()),
1002 parse_lam(input, defs.clone(), rec.clone(), ctx.clone(), quasi.clone()),
1003 parse_let(input, defs.clone(), rec.clone(), ctx.clone(), quasi.clone()),
1004 parse_type(input),
1005 parse_lty(input),
1006 parse_opr(input),
1007 parse_lit(input),
1008 parse_antiquote(ctx.clone(), quasi.clone()),
1009 parse_var(input, defs.to_owned(), rec.clone(), ctx.clone()),
1010 )),
1011 )(i)
1012 }
1013}
1014
1015pub fn input_cid(i: &str) -> Cid {
1017 Cid::new_v1(
1018 0x55,
1019 Code::Blake2b256.digest(
1020 DagCborCodec.encode(&i.to_owned()).unwrap().into_inner().as_ref(),
1021 ),
1022 )
1023}
1024
1025pub fn parse(i: &str, defs: Defs) -> IResult<Span, Term, ParseError<Span>> {
1027 parse_expression(
1028 input_cid(i),
1029 Rc::new(RefCell::new(defs)),
1030 None,
1031 ConsList::new(),
1032 Rc::new(VecDeque::new()),
1033 )(Span::new(i))
1034}
1035
1036pub fn parse_quasi(
1038 i: &str,
1039 defs: Rc<RefCell<Defs>>,
1040 quasi: Rc<VecDeque<Term>>,
1041) -> IResult<Span, Term, ParseError<Span>> {
1042 parse_expression(input_cid(i), defs, None, ConsList::new(), quasi)(Span::new(
1043 i,
1044 ))
1045}
1046
1047#[macro_export]
1056macro_rules! yatima {
1057 ($i:literal) => {
1058 parse::term::parse($i, defs::Defs::new()).unwrap().1
1059 };
1060 ($i:literal, $($q: expr),*) => {{
1061 let mut quasi = Vec::new();
1062 $(quasi.push($q);)*
1063 parse::term::parse_quasi($i,
1064 sp_std::rc::Rc::new(sp_std::cell::RefCell::new(defs::Defs::new())),
1065 sp_std::rc::Rc::new(sp_std::collections::vec_deque::VecDeque::from(quasi)))
1066 .unwrap().1
1067 }}
1068}
1069
1070#[cfg(test)]
1071pub mod tests {
1072 use super::*;
1073 use crate::term::tests::test_defs;
1074
1075 #[test]
1076 fn test_parse_apps() {
1077 fn test(i: &str) -> IResult<Span, Term, ParseError<Span>> {
1078 parse_apps(
1079 input_cid(i),
1080 Rc::new(RefCell::new(Defs::new())),
1081 None,
1082 ConsList::new(),
1083 Rc::new(VecDeque::new()),
1084 )(Span::new(i))
1085 }
1086 let res = test("0d1");
1087 assert!(res.is_ok());
1088 let res = test("0d1 0d1");
1089 assert!(res.is_ok());
1090 let res = test("0d1 0d1 def");
1091 assert!(res.is_ok());
1092 }
1093
1094 #[test]
1095 fn test_parse_expression() {
1096 fn test(i: &str) -> IResult<Span, Term, ParseError<Span>> {
1097 parse_expression(
1098 input_cid(i),
1099 Rc::new(RefCell::new(Defs::new())),
1100 None,
1101 ConsList::new(),
1102 Rc::new(VecDeque::new()),
1103 )(Span::new(i))
1104 }
1105 let res = test("(Type :: Type)");
1106 assert!(res.is_ok());
1107 let res = test("(Type (Type Type) )");
1108 assert!(res.is_ok());
1109 let res = test(
1110 "λ x c n => (c x (c x (c x (c x (c x (c x (c x (c x (c x (c x (c x x (c \
1111 x (c x (c x (c x n)))))))))))))))",
1112 );
1113 assert!(res.is_ok());
1114 let res = test("∀ Type -> Type");
1115 assert!(res.is_ok());
1116 let res = test("∀ (_ :Type) -> Type");
1117 assert!(res.is_ok());
1118 }
1119 #[test]
1120 fn test_parse_binder_full() {
1121 use crate::{
1122 defs,
1123 parse,
1124 };
1125 fn test(
1126 ctx: Vec<Name>,
1127 i: &str,
1128 ) -> IResult<Span, Vec<(Uses, Name, Term)>, ParseError<Span>> {
1129 parse_binder_full(
1130 input_cid(i),
1131 Rc::new(RefCell::new(Defs::new())),
1132 None,
1133 ConsList::from(ctx),
1134 Rc::new(VecDeque::new()),
1135 Uses::Many,
1136 )(Span::new(i))
1137 }
1138 let res = test(vec![], "(a b c: Type)");
1139 assert!(res.is_ok());
1140 let res = res.unwrap().1;
1141 assert_eq!(res, vec![
1142 (Uses::Many, Name::from("a"), yatima!("Type")),
1143 (Uses::Many, Name::from("b"), yatima!("Type")),
1144 (Uses::Many, Name::from("c"), yatima!("Type"))
1145 ]);
1146 let res = test(vec![Name::from("A")], "(a b c: A)");
1147 assert!(res.is_ok());
1148 let res = res.unwrap().1;
1149 assert_eq!(res, vec![
1150 (Uses::Many, Name::from("a"), Term::Var(Pos::None, Name::from("A"), 0)),
1151 (Uses::Many, Name::from("b"), Term::Var(Pos::None, Name::from("A"), 1)),
1152 (Uses::Many, Name::from("c"), Term::Var(Pos::None, Name::from("A"), 2)),
1153 ]);
1154 let res = test(vec![Name::from("A")], "(a : ∀ (x: A) -> A)");
1155 assert!(res.is_ok());
1156 let res = res.unwrap().1;
1157 assert_eq!(res, vec![(
1158 Uses::Many,
1159 Name::from("a"),
1160 Term::All(
1161 Pos::None,
1162 Uses::Many,
1163 Name::from("x"),
1164 Box::new((
1165 Term::Var(Pos::None, Name::from("A"), 0),
1166 Term::Var(Pos::None, Name::from("A"), 1)
1167 ))
1168 )
1169 ),]);
1170 fn test_binders(
1171 ctx: Vec<Name>,
1172 i: &str,
1173 ) -> IResult<Span, Vec<(Uses, Name, Term)>, ParseError<Span>> {
1174 parse_binders(
1175 input_cid(i),
1176 Rc::new(RefCell::new(Defs::new())),
1177 None,
1178 Ctx::from(ctx),
1179 Rc::new(VecDeque::new()),
1180 false,
1181 vec![':'],
1182 Uses::Many,
1183 )(Span::new(i))
1184 }
1185 let res1 = test(vec![Name::from("A")], "(a : ∀ (x: A) -> A)");
1186 let res2 = test_binders(vec![Name::from("A")], "(a : ∀ (x: A) -> A):");
1187 assert!(res1.is_ok() && res2.is_ok());
1188 let (res1, res2) = (res1.unwrap().1, res2.unwrap().1);
1189 assert_eq!(res1, res2);
1190 let res1 = test(vec![Name::from("A")], "(a b c: ∀ (x: A) -> A)");
1191 let res2 = test_binders(
1192 vec![Name::from("A")],
1193 "(a : ∀ (x: A) -> A)
1194 (b : ∀ (x: A) -> A)
1195 (c : ∀ (x: A) -> A)
1196 :",
1197 );
1198 assert!(res1.is_ok() && res2.is_ok());
1199 let (res1, res2) = (res1.unwrap().1, res2.unwrap().1);
1200 assert_eq!(res1, res2);
1201 let res1 =
1202 test(vec![Name::from("A")], "(a b c d e f g: ∀ (x y z w: A) -> A)");
1203 let res2 = test_binders(
1204 vec![Name::from("A")],
1205 "(a: ∀ (x y z w: A) -> A)
1206 (b: ∀ (x y z w: A) -> A)
1207 (c: ∀ (x y z w: A) -> A)
1208 (d: ∀ (x y z w: A) -> A)
1209 (e: ∀ (x y z w: A) -> A)
1210 (f: ∀ (x y z w: A) -> A)
1211 (g: ∀ (x y z w: A) -> A)
1212 :",
1213 );
1214 assert!(res1.is_ok() && res2.is_ok());
1215 let (res1, res2) = (res1.unwrap().1, res2.unwrap().1);
1216 assert_eq!(res1, res2)
1217 }
1218
1219 #[test]
1220 fn test_parse_alls() {
1221 fn test(i: &str) -> IResult<Span, Term, ParseError<Span>> {
1222 parse_all(
1223 input_cid(i),
1224 Rc::new(RefCell::new(Defs::new())),
1225 None,
1226 ConsList::new(),
1227 Rc::new(VecDeque::new()),
1228 )(Span::new(i))
1229 }
1230 let res = test("∀ (a b c: Type) -> Type");
1231 println!("res: {:?}", res);
1232 assert!(res.is_ok());
1233 }
1234
1235 #[test]
1236 fn test_parse_let() {
1237 fn test(i: &str) -> IResult<Span, Term, ParseError<Span>> {
1238 parse_let(
1239 input_cid(i),
1240 Rc::new(RefCell::new(Defs::new())),
1241 None,
1242 ConsList::new(),
1243 Rc::new(VecDeque::new()),
1244 )(Span::new(i))
1245 }
1246 let res = test("let 0 x: Type = Type; x");
1247 assert!(res.is_ok());
1248 let res = test("let 0 f (x: Unknown) = Type; x");
1249 println!("res: {:?}", res);
1250 match res.unwrap_err() {
1251 Err::Error(err) => {
1252 assert!(
1253 err.errors
1254 == vec![ParseErrorKind::UndefinedReference(
1255 Name::from("Unknown"),
1256 ConsList::new(),
1257 )]
1258 )
1259 }
1260 _ => {
1261 assert!(false)
1262 }
1263 }
1264 }
1265 #[test]
1266 fn test_parse_bound_expression() {
1267 fn test(
1268 type_rec: Option<Name>,
1269 term_rec: Option<Name>,
1270 i: &str,
1271 ) -> IResult<Span, (Term, Term), ParseError<Span>> {
1272 parse_bound_expression(
1273 input_cid(i),
1274 Rc::new(RefCell::new(Defs::new())),
1275 type_rec,
1276 term_rec,
1277 ConsList::new(),
1278 Rc::new(VecDeque::new()),
1279 Name::from("test"),
1280 false,
1281 )(Span::new(i))
1282 }
1283 let res = test(None, None, ": Type = Type");
1284 assert!(res.is_ok());
1285 let res = test(None, None, "(x: Type): Type = Type");
1286 assert!(res.is_ok());
1287 let res = test(None, None, "(x: Unknown): Type = Type");
1288 match res.unwrap_err() {
1289 Err::Error(err) => {
1290 assert!(
1292 err.errors
1293 == vec![ParseErrorKind::UndefinedReference(
1294 Name::from("Unknown"),
1295 ConsList::new()
1296 )]
1297 );
1298 }
1299 _ => {
1300 assert!(false);
1301 }
1302 };
1303 let res = test(Some(Name::from("Test")), None, "(x: Test): Type = Type");
1304 assert!(res.is_ok());
1305 let res = test(Some(Name::from("Test")), None, "(x: Type): Type = Test");
1306 assert!(res.is_err());
1307 let res = test(None, Some(Name::from("Test")), "(x: Test): Type = Type");
1308 assert!(res.is_err());
1309 let res = test(None, Some(Name::from("Test")), "(x: Type): Type = Test");
1310 assert!(res.is_ok());
1311 }
1312 #[test]
1313 fn test_parse_binders1() {
1314 use Term::*;
1315 fn test(
1316 nam_opt: bool,
1317 i: &str,
1318 ) -> IResult<Span, Vec<(Uses, Name, Term)>, ParseError<Span>> {
1319 parse_binders(
1320 input_cid(i),
1321 Rc::new(RefCell::new(Defs::new())),
1322 None,
1323 ConsList::new(),
1324 Rc::new(VecDeque::new()),
1325 nam_opt,
1326 vec![':'],
1327 Uses::Many,
1328 )(Span::new(i))
1329 }
1330 let res = test(true, "Type #Text:");
1331 assert!(res.is_ok());
1332 assert!(
1333 res.unwrap().1
1334 == vec![
1335 (Uses::Many, Name::from("_"), Typ(Pos::None)),
1336 (Uses::Many, Name::from("_"), LTy(Pos::None, LitType::Text)),
1337 ]
1338 );
1339 }
1340
1341 #[test]
1342 fn test_parse_binders() {
1343 use Term::*;
1344 fn test(
1345 nam_opt: bool,
1346 i: &str,
1347 ) -> IResult<Span, Vec<(Uses, Name, Term)>, ParseError<Span>> {
1348 parse_binders(
1349 input_cid(i),
1350 Rc::new(RefCell::new(Defs::new())),
1351 None,
1352 ConsList::new(),
1353 Rc::new(VecDeque::new()),
1354 nam_opt,
1355 vec![':'],
1356 Uses::Many,
1357 )(Span::new(i))
1358 }
1359 let res = test(true, ":");
1360 assert!(res.is_ok());
1361 let res = test(true, "Type Type:");
1362 assert!(res.is_ok());
1363 assert!(
1364 res.unwrap().1
1365 == vec![
1366 (Uses::Many, Name::from("_"), Typ(Pos::None)),
1367 (Uses::Many, Name::from("_"), Typ(Pos::None)),
1368 ]
1369 );
1370 let res = test(true, "(A: Type) (a b c: A):");
1371 assert!(res.is_ok());
1372 assert!(
1373 res.unwrap().1
1374 == vec![
1375 (Uses::Many, Name::from("A"), Typ(Pos::None)),
1376 (Uses::Many, Name::from("a"), Var(Pos::None, Name::from("A"), 0)),
1377 (Uses::Many, Name::from("b"), Var(Pos::None, Name::from("A"), 1)),
1378 (Uses::Many, Name::from("c"), Var(Pos::None, Name::from("A"), 2)),
1379 ]
1380 );
1381 let res = test(true, "(A: Type) (a b c: Unknown):");
1382 assert!(res.is_err());
1383 match res.unwrap_err() {
1384 Err::Error(err) => {
1385 assert!(
1386 err.errors
1387 == vec![ParseErrorKind::UndefinedReference(
1388 Name::from("Unknown"),
1389 ConsList::from(vec!(Name::from("A")))
1390 )]
1391 )
1392 }
1393 _ => {
1394 assert!(false)
1395 }
1396 }
1397 let res = test(false, "(x: Unknown):");
1398 assert!(res.is_err());
1399 match res.unwrap_err() {
1400 Err::Error(err) => {
1401 assert!(
1402 err.errors
1403 == vec![ParseErrorKind::UndefinedReference(
1404 Name::from("Unknown"),
1405 ConsList::new(),
1406 )]
1407 );
1408 }
1409 _ => {
1410 assert!(false)
1411 }
1412 }
1413 }
1414
1415 #[quickcheck]
1416 fn term_parse_print(x: Term) -> bool {
1417 let i = format!("{}", x);
1418 match parse_expression(
1419 input_cid(&i),
1420 Rc::new(RefCell::new(test_defs())),
1421 None,
1422 ConsList::new(),
1423 Rc::new(VecDeque::new()),
1424 )(Span::new(&i))
1425 {
1426 Ok((_, y)) => x == y,
1427 Err(e) => {
1428 println!("{}", x);
1429 println!("{}", e);
1430 false
1431 }
1432 }
1433 }
1434}