1
2
3use alloc::{rc::Rc, string::String};
4use core::{fmt::Display, iter::Peekable, str};
5use hashbrown::HashMap;
6use thiserror::Error;
7
8use crate::theory::{ID, Kind};
9
10pub struct Dict {
11 map: HashMap< Rc<String>, ID>,
12 rev: HashMap<ID, Rc<String>>,
13 i: ID
14}
15impl Dict {
16 pub fn new() -> Self { Self {map: HashMap::new(), rev: HashMap::new(), i: 0} }
17 pub fn get(&mut self, name: String) -> Option<ID> {
18 match self.map.get(&name) {
19 Some(id) => Some(*id),
20 None => {
21 let owd: Rc<String> = Rc::from(name);
22 self.map.insert(owd.clone(), self.i);
23 self.rev.insert(self.i, owd);
24
25 let ret = self.i;
26 match self.i.checked_add(1) {
27 Some(ni) => {
28 self.i = ni;
29 Some(ret)
30 },
31 None => None,
32 }
33 },
34 }
35 }
36 pub fn get_name(&self, id: ID) -> Option<&str> {
38 self.rev.get(&id).map(Rc::as_ref).map(|x| x.as_str())
39 }
40}
41
42#[derive(Debug, Error)]
44pub enum ParserErr {
45 #[error("expected '{what}' at {pos}")]
46 Expected { what: char, pos: usize },
47
48 #[error("expected an atom at {pos}")]
49 NeedAtom { pos: usize },
50
51 #[error("namespace full while at {pos}")]
52 NamespaceFull { pos: usize },
53
54 #[error("unexpected end of input at {pos}")]
55 EndOfInput { pos: usize },
56
57 #[error("pair has more than 2 members at {pos}")]
58 PairHasMore { pos: usize },
59}
60type PrsErr = ParserErr;
61
62struct Prsable<It: Iterator<Item = char>> {
63 inner: Peekable<It>,
64 pos: usize
65}
66impl<It: Iterator<Item = char>> Prsable<It> {
67 fn new(it: It) -> Self { Self { inner: it.peekable(), pos: 0 }}
68 fn next(&mut self) -> Option<char> {
69 let n = self.inner.next()?;
70 self.pos += 1;
71 Some(n)
72 }
73 fn peek(&mut self) -> Option<char> { self.inner.peek().copied() }
74}
75
76pub struct Parser<It: Iterator<Item = char>> {
78 it: Prsable<It>
79}
80
81type Prsr<It> = Parser<It>;
82impl<It: Iterator<Item = char>> Prsr<It> {
83 pub fn new(it: It) -> Self { Self { it: Prsable::new(it) }}
84
85 fn skip_ws(&mut self) {
86 while let Some(b) = self.it.peek() {
87 match b {
88 ' ' | '\t' | '\r' | '\n' => { self.it.next(); },
89 ';' => { while let Some(c) = self.it.next() {
91 if c == '\n' { break }
92 }
93 }
94 _ => break,
95 }
96 }
97 }
98
99 pub fn parse_atom(&mut self, dict: &mut Dict) -> Result<Kind, PrsErr> {
100 self.skip_ws();
101 let mut st = String::new();
102 let start = self.it.pos;
103
104 while let Some(b) = self.it.peek() {
105 if !matches!(b, ' ' | '\t' | '\r' | '\n' | '(' | ')' | ';') {
107 self.it.next(); st.push(b);
109 } else { break; }
110 }
111
112 if self.it.pos == start {
113 return Err(PrsErr::NeedAtom { pos: self.it.pos });
114 }
115
116 match dict.get(st) {
117 Some(sy) => Ok(Kind::from(sy)),
118 None => Err(PrsErr::NamespaceFull { pos: self.it.pos }),
119 }
120 }
121
122 pub fn parse_expr(&mut self, dict: &mut Dict) -> Result<Kind, PrsErr> {
123 self.skip_ws();
124 match self.it.peek() {
125 Some('(') => self.parse_spair(dict),
126 Some(_) => self.parse_atom(dict),
127 None => Err(PrsErr::EndOfInput { pos: self.it.pos }),
128 }
129 }
130
131 pub fn parse_spair(&mut self, dict: &mut Dict) -> Result<Kind, PrsErr> {
133 self.skip_ws();
134 match self.it.peek() {
135 Some('(') => { self.it.next(); } _ => return Err(PrsErr::Expected { what: '(', pos: self.it.pos }),
137 }
138
139 let l = self.parse_expr(dict)?;
140 let r = self.parse_expr(dict)?;
141
142 self.skip_ws();
143 match self.it.peek() {
144 Some(')') => {
145 self.it.next(); Ok(Kind::from((l, r)))
147 }
148 Some(_) => Err(PrsErr::PairHasMore { pos: self.it.pos }),
149 None => Err(PrsErr::Expected { what: ')', pos: self.it.pos }),
150 }
151 }
152
153 pub fn has_more(&mut self) -> Option<usize> {
154 self.skip_ws();
155 match self.it.peek() {
156 Some(_) => Some(self.it.pos),
157 None => None
158 }
159 }
160}
161
162pub struct View<'a> {
163 root: &'a Kind,
164 dict: &'a Dict
165}
166impl<'a> View<'a> {
167 pub fn new(root: &'a Kind, dict: &'a Dict) -> Self { Self { root, dict } }
168}
169
170impl<'a> Display for View<'a> {
171 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
172 match self.root {
173 Kind::Alp { id } => match self.dict.get_name(*id) {
174 Some(name) => write!(f, "{name}"),
175 None => write!(f, "#{:?}", self.root),
176 },
177 Kind::Zta { sid, .. } => match *sid {
178 None => write!(f, "#{:?}", self.root),
179 Some(id) => match self.dict.get_name(id) {
180 Some(name) => write!(f, "{name}"),
181 None => write!(f, "#{:?}", self.root),
182 },
183 }
184 Kind::Pir { l, r } => write!(
185 f, "({} {})",
186 View::new(l, self.dict),
187 View::new(r, self.dict)
188 )
189 }
190 }
191}