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