1use super::{
2 CloseParenToken, CommaToken, DotToken, HornToken, Ident, NegationToken, OpenParenToken, Parse,
3 ParseBuffer, VAR_PREFIX,
4 repr::{Clause, Expr, Term},
5};
6use crate::{ClauseDatasetIn, ClauseIn, Error, ExprIn, Intern, NameIn, Result, TermIn};
7use std::{
8 borrow::Borrow,
9 fmt::{self, Debug, Display},
10 hash::Hash,
11 ops,
12};
13
14impl<'int, Int: Intern> Parse<'int, Int> for ClauseDatasetIn<'int, Int> {
15 fn parse(buf: &mut ParseBuffer<'_>, interner: &'int Int) -> Result<Self> {
16 let clauses = buf.parse(interner)?;
17 Ok(Self(clauses))
18 }
19}
20
21impl<'int, Int: Intern> Parse<'int, Int> for Vec<ClauseIn<'int, Int>> {
22 fn parse(buf: &mut ParseBuffer<'_>, interner: &'int Int) -> Result<Self> {
23 let mut v = Vec::new();
24 while let Some((clause, moved_buf)) = buf.peek_parse::<Int, Clause<Name<_>>>(interner) {
25 v.push(clause);
26 *buf = moved_buf;
27 }
28 Ok(v)
29 }
30}
31
32impl<'int, Int: Intern> Parse<'int, Int> for ClauseIn<'int, Int> {
33 fn parse(buf: &mut ParseBuffer<'_>, interner: &'int Int) -> Result<Self> {
34 let head = buf.parse::<Int, Term<Name<_>>>(interner)?;
35
36 let body = if let Some((_, mut body_buf)) = buf.peek_parse::<Int, HornToken>(interner) {
37 let dot = body_buf
38 .cur_text()
39 .find('.')
40 .ok_or(Error::from("clause must end with `.`"))?;
41 body_buf.end = body_buf.start + dot;
42 let body = body_buf.parse::<Int, Expr<Name<_>>>(interner)?;
43
44 buf.start = body_buf.end + 1; Some(body)
46 } else {
47 let _ = buf.parse::<Int, DotToken>(interner)?;
48 None
49 };
50
51 Ok(Self { head, body })
52 }
53}
54
55impl Expr<Name<()>> {
57 fn parse_or<'int, Int: Intern>(
58 buf: ParseBuffer<'_>,
59 interner: &'int Int,
60 ) -> Result<ExprIn<'int, Int>> {
61 Self::parse_by_delimiter(buf, interner, ';', Self::parse_and, Expr::Or)
62 }
63
64 fn parse_and<'int, Int: Intern>(
65 buf: ParseBuffer<'_>,
66 interner: &'int Int,
67 ) -> Result<ExprIn<'int, Int>> {
68 Self::parse_by_delimiter(buf, interner, ',', Self::parse_not, Expr::And)
69 }
70
71 fn parse_not<'int, Int: Intern>(
72 buf: ParseBuffer<'_>,
73 interner: &'int Int,
74 ) -> Result<ExprIn<'int, Int>> {
75 if let Some((_, moved_buf)) = buf.peek_parse::<Int, NegationToken>(interner) {
76 let inner = Self::parse_not(moved_buf, interner)?;
77 Ok(Expr::Not(Box::new(inner)))
78 } else {
79 Self::parse_paren(buf, interner)
80 }
81 }
82
83 fn parse_paren<'int, Int: Intern>(
84 buf: ParseBuffer<'_>,
85 interner: &'int Int,
86 ) -> Result<ExprIn<'int, Int>> {
87 if let Some((_, mut moved_buf)) = buf.peek_parse::<Int, OpenParenToken>(interner) {
88 let r = moved_buf.cur_text().rfind(')').unwrap();
89 moved_buf.end = moved_buf.start + r;
90 moved_buf.parse::<Int, Expr<Name<_>>>(interner)
91 } else {
92 Self::parse_term(buf, interner)
93 }
94 }
95
96 fn parse_term<'int, Int: Intern>(
97 mut buf: ParseBuffer<'_>,
98 interner: &'int Int,
99 ) -> Result<ExprIn<'int, Int>> {
100 if buf.cur_text().chars().all(|c: char| c.is_whitespace()) {
101 Err("expected a non-empty term expression".into())
102 } else {
103 buf.parse::<Int, Term<Name<_>>>(interner).map(Expr::Term)
104 }
105 }
106
107 fn parse_by_delimiter<'int, Int: Intern>(
108 buf: ParseBuffer<'_>,
109 interner: &'int Int,
110 del: char,
111 parse_partial: fn(ParseBuffer<'_>, &'int Int) -> Result<ExprIn<'int, Int>>,
112 wrap_vec: fn(Vec<ExprIn<'int, Int>>) -> ExprIn<'int, Int>,
113 ) -> Result<ExprIn<'int, Int>> {
114 let mut v = Vec::new();
115 let (mut l, mut r) = (buf.start, buf.start);
116 let mut open = 0;
117
118 for c in buf.cur_text().chars() {
119 if c == del && open == 0 {
120 let buf = ParseBuffer {
121 text: buf.text,
122 start: l,
123 end: r,
124 };
125 let partial = parse_partial(buf, interner)?;
126 v.push(partial);
127 l = r + c.len_utf8();
128 } else if c == '(' {
129 open += 1;
130 } else if c == ')' {
131 open -= 1;
132 }
133 r += c.len_utf8();
134 }
135
136 let buf = ParseBuffer {
137 text: buf.text,
138 start: l,
139 end: r,
140 };
141 let last = parse_partial(buf, interner)?;
142
143 if !v.is_empty() {
144 v.push(last);
145 Ok(wrap_vec(v))
146 } else {
147 Ok(last)
148 }
149 }
150}
151
152impl<'int, Int: Intern> Parse<'int, Int> for ExprIn<'int, Int> {
153 fn parse(buf: &mut ParseBuffer<'_>, interner: &'int Int) -> Result<Self> {
154 Expr::parse_or(*buf, interner)
156 }
157}
158
159impl Term<Name<()>> {
160 fn parse_args<'int, Int: Intern>(
161 buf: &mut ParseBuffer<'_>,
162 interner: &'int Int,
163 ) -> Result<Box<[TermIn<'int, Int>]>> {
164 let mut open = 0;
165 while let Some((_, moved_buf)) = buf.peek_parse::<Int, OpenParenToken>(interner) {
166 *buf = moved_buf;
167 open += 1;
168 }
169
170 if open == 0 {
171 return Ok([].into());
172 }
173
174 let mut args = Vec::new();
175 let mut well_seperated = true;
176 loop {
177 if let Some((_, moved_buf)) = buf.peek_parse::<Int, CloseParenToken>(interner) {
178 *buf = moved_buf;
179 open -= 1;
180 break;
181 }
182
183 if !well_seperated {
184 return Err(format!("expected `,` from {}", buf.cur_text()).into());
185 }
186
187 let arg = buf.parse::<Int, Term<Name<_>>>(interner)?;
188 args.push(arg);
189
190 let comma = buf.parse::<Int, CommaToken>(interner);
191 well_seperated = comma.is_ok();
192 }
193
194 for _ in 0..open {
195 buf.parse::<Int, CloseParenToken>(interner)?;
196 }
197
198 Ok(args.into())
199 }
200}
201
202impl<'int, Int: Intern> Parse<'int, Int> for TermIn<'int, Int> {
203 fn parse(buf: &mut ParseBuffer<'_>, interner: &'int Int) -> Result<Self> {
204 let functor = Name::parse(buf, interner)?;
205 let args = Term::parse_args(buf, interner)?;
206 Ok(Self { functor, args })
207 }
208}
209
210#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
211pub struct Name<T>(pub T); impl Name<()> {
214 pub fn with_intern<'int, Int: Intern>(s: &str, interner: &'int Int) -> NameIn<'int, Int> {
215 debug_assert!(!s.is_empty());
216
217 let interned = interner.intern_str(s);
218 Name(interned)
219 }
220}
221
222impl<T: AsRef<str>> Name<T> {
223 pub(crate) fn is_variable(&self) -> bool {
224 let first = self.0.as_ref().chars().next().unwrap();
225 first == VAR_PREFIX }
227}
228
229impl<'int, Int: Intern> Parse<'int, Int> for NameIn<'int, Int> {
230 fn parse(buf: &mut ParseBuffer<'_>, interner: &'int Int) -> Result<Self> {
231 let ident = buf.parse::<Int, Ident>(interner)?;
232 let interned = interner.intern_str(ident.to_text(buf.text));
233 debug_assert!(!interned.as_ref().is_empty());
234 Ok(Self(interned))
235 }
236}
237
238impl<T> Borrow<T> for Name<T> {
239 fn borrow(&self) -> &T {
240 &self.0
241 }
242}
243
244impl<T: Borrow<str>> Borrow<str> for Name<T> {
245 fn borrow(&self) -> &str {
246 self.0.borrow()
247 }
248}
249
250impl<T: AsRef<str>> AsRef<str> for Name<T> {
251 fn as_ref(&self) -> &str {
252 self.0.as_ref()
253 }
254}
255
256impl<T: PartialEq<str>> PartialEq<str> for Name<T> {
257 fn eq(&self, other: &str) -> bool {
258 self.0.eq(other)
259 }
260}
261
262impl<T: PartialOrd<str>> PartialOrd<str> for Name<T> {
263 fn partial_cmp(&self, other: &str) -> Option<std::cmp::Ordering> {
264 self.0.partial_cmp(other)
265 }
266}
267
268impl<T> ops::Deref for Name<T> {
269 type Target = T;
270
271 fn deref(&self) -> &Self::Target {
272 &self.0
273 }
274}
275
276impl<T: Display> Display for Name<T> {
277 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
278 self.0.fmt(f)
279 }
280}
281
282impl<T: Debug> Debug for Name<T> {
283 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
284 self.0.fmt(f)
285 }
286}