yatima_core/parse/
package.rs

1use crate::{
2  defs::{
3    Def,
4    Defs,
5  },
6  name::Name,
7  package::{
8    Entry,
9    Import,
10    Index,
11  },
12  parse::{
13    base::parse_multibase,
14    error::{
15      ParseError,
16      ParseErrorKind,
17    },
18    span::Span,
19    term::*,
20    typedef::parse_typedef_elaborated,
21  },
22  term::*,
23};
24
25use sp_std::{
26  cell::RefCell,
27  collections::vec_deque::VecDeque,
28  convert::TryFrom,
29  rc::Rc,
30  vec::Vec,
31};
32
33use nom::{
34  branch::alt,
35  bytes::complete::tag,
36  combinator::{
37    eof,
38    opt,
39  },
40  multi::separated_list0,
41  sequence::terminated,
42  Err,
43  IResult,
44};
45
46use sp_cid::Cid;
47use sp_im::conslist::ConsList;
48
49pub fn parse_link(from: Span) -> IResult<Span, Cid, ParseError<Span>> {
50  let (upto, (_, bytes)) = parse_multibase()(from)?;
51  match Cid::try_from(bytes) {
52    Ok(cid) => Ok((upto, cid)),
53    Err(_) => Err(Err::Error(ParseError::new(upto, ParseErrorKind::CidError))),
54  }
55}
56
57pub fn parse_alias(i: Span) -> IResult<Span, Name, ParseError<Span>> {
58  let (i, _) = tag("as")(i)?;
59  let (i, _) = parse_space(i)?;
60  let (i, a) = parse_name(i)?;
61  Ok((i, a))
62}
63
64pub fn parse_with(i: Span) -> IResult<Span, Vec<Name>, ParseError<Span>> {
65  let (i, _) = tag("(")(i)?;
66  let (i, ns) = separated_list0(
67    terminated(tag(","), parse_space),
68    terminated(parse_name, parse_space),
69  )(i)?;
70  let (i, _) = tag(")")(i)?;
71  Ok((i, ns))
72}
73
74pub fn parse_import(i: Span) -> IResult<Span, Import, ParseError<Span>> {
75  let (i, _) = tag("import")(i)?;
76  let (i, _) = parse_space(i)?;
77  let (i, name) = parse_name(i)?;
78  let (i, _) = parse_space(i)?;
79  let (i, alias) = opt(terminated(parse_alias, parse_space))(i)?;
80  let alias = alias.unwrap_or_else(|| Name::from(""));
81  let (i, with) = terminated(parse_with, parse_space)(i)?;
82  let (i, from) = terminated(parse_link, parse_space)(i)?;
83  Ok((i, Import { cid: from, name, alias, with }))
84}
85
86pub fn parse_entry(
87  input: Cid,
88  defs: Rc<RefCell<Defs>>,
89) -> impl Fn(Span) -> IResult<Span, Vec<(Name, Def, Entry)>, ParseError<Span>> {
90  move |from: Span| {
91    let (i, _) = tag("def")(from)?;
92    let (i, _) = parse_space(i)?;
93    let (i, nam) = parse_name(i)?;
94    if defs.borrow().names.get(&nam.clone()).is_some() {
95      Err(Err::Error(ParseError::new(
96        from,
97        ParseErrorKind::TopLevelRedefinition(nam),
98      )))
99    }
100    else {
101      let (i, _) = parse_space(i)?;
102      let (upto, (typ_, term)) = parse_bound_expression(
103        input,
104        defs.clone(),
105        None,
106        Some(nam.clone()),
107        ConsList::new(),
108        Rc::new(VecDeque::new()),
109        nam.clone(),
110        false,
111      )(i)?;
112      let pos = Pos::from_upto(input, from, upto);
113      let (def, entry) = Def::make(pos, typ_, term);
114      Ok((upto, vec![(nam, def, entry)]))
115    }
116  }
117}
118
119pub fn parse_defs(
120  input: Cid,
121  import_defs: Defs,
122) -> impl Fn(Span) -> IResult<Span, (Defs, Index), ParseError<Span>> {
123  move |i: Span| {
124    let defs = Rc::new(RefCell::new(import_defs.clone()));
125    let mut ind: Vec<(Name, Cid)> = Vec::new();
126    let mut i = i;
127    loop {
128      let (i2, _) = parse_space(i)?;
129      i = i2;
130      let end: IResult<Span, Span, ParseError<Span>> = eof(i);
131      if end.is_ok() {
132        return Ok((i2, (defs.as_ref().clone().into_inner(), Index(ind))));
133      }
134      else {
135        let (i2, entries) = alt((
136          parse_entry(input, defs.clone()),
137          parse_typedef_elaborated(input, defs.clone()),
138        ))(i)?;
139        for (name, def, _) in entries {
140          ind.push((name.clone(), def.def_cid));
141          defs.borrow_mut().insert(name, def);
142        }
143        i = i2;
144      }
145    }
146  }
147}
148
149// #[cfg(test)]
150// pub mod tests {
151//  use super::*;
152//
153//  #[test]
154//  fn test_cases() {
155//    let res = parse_with(Span::new("()"));
156//    println!("res: {:?}", res);
157//    assert!(res.is_ok());
158//    let res = parse_with(Span::new("(a)"));
159//    println!("res: {:?}", res);
160//    assert!(res.is_ok());
161//    let res = parse_with(Span::new("(a,b)"));
162//    println!("res: {:?}", res);
163//    assert!(res.is_ok());
164//    let res = parse_with(Span::new("(a,b,c)"));
165//    println!("res: {:?}", res);
166//    assert!(res.is_ok());
167//  }
168// }