1use std::fmt;
2
3use crate::{
4 expr::{Expr, Interner, NoIntern},
5 lexer::{
6 lexical_error::LexicalError,
7 scanner::{Position, Scanner, TokenKind},
8 },
9};
10
11use self::syntax_error::SyntaxError;
12
13pub mod syntax_error;
14
15pub struct Parser<'a, I: Interner = NoIntern> {
16 symbols: &'a mut I,
17 scanner: Scanner<'a>,
18}
19
20impl<'a, I: Interner> Parser<'a, I> {
21 pub fn new(symbols: &'a mut I, source: &'a str, fold_case: bool) -> Self {
22 Self {
23 symbols,
24 scanner: Scanner::new(source, fold_case, true),
25 }
26 }
27
28 pub fn finished(&self) -> bool {
29 !self.scanner.has_next()
30 }
31
32 pub fn parse(&mut self, prescan: bool) -> Result<Box<Expr<I>>, ParseError> {
33 let token = self.scanner.token();
34 let pos = token.pos;
35 let res;
36 match token.kind {
37 TokenKind::Error => {
38 let err = token.error_val.unwrap();
39 self.scanner.next();
40
41 return Err(ParseError::Lexical(pos, err));
42 }
43
44 TokenKind::Eof => {
45 return Err(ParseError::Syntax(pos, SyntaxError::Empty));
46 }
47
48 TokenKind::HashSemi => {
49 self.scanner.next();
50 self.parse(true)?;
51
52 return self.parse(true);
53 }
54
55 TokenKind::Ident => {
56 let s = if self.scanner.fold_case {
57 token.str_val.to_lowercase()
58 } else {
59 token.str_val.clone()
60 };
61 res = Box::new(Expr::Symbol(self.symbols.intern(&s)));
62 }
63
64 TokenKind::TrueLit => res = Box::new(Expr::Bool(true)),
65
66 TokenKind::FalseLit => res = Box::new(Expr::Bool(false)),
67
68 TokenKind::Int => {
69 res = Box::new(Expr::Fixnum(token.int_val));
70 }
71
72 TokenKind::BigInt => {
73 res = Box::new(Expr::BigInt(token.big_int_val.clone()));
74 }
75
76 TokenKind::Rat => res = Box::new(Expr::Rational(token.rat_val)),
77 TokenKind::Float => {
78 res = Box::new(Expr::Float(token.float_val));
79 }
80
81 TokenKind::BigRat => res = Box::new(Expr::BigRational(token.big_rat_val.clone())),
82
83 TokenKind::Complex => res = Box::new(Expr::Complex(token.complex_val)),
84
85 TokenKind::Char => {
86 res = Box::new(Expr::Char(char::from_u32(token.int_val as u32).unwrap()))
87 }
88
89 TokenKind::String => res = Box::new(Expr::Str(token.str_val.clone())),
90
91 TokenKind::LParent => {
92 self.scanner.next();
93 let mut exprs = vec![];
94 while !self
95 .scanner
96 .has_token(&[TokenKind::Eof, TokenKind::RParent, TokenKind::Dot])
97 {
98 exprs.push(self.parse(true)?);
99 }
100
101 if self.scanner.has_token(&[TokenKind::Dot]) {
102 self.scanner.next();
103
104 res = Expr::from_slice(exprs, self.parse(true)?);
105 } else {
106 res = Expr::from_slice(exprs, Box::new(Expr::Null));
107 }
108
109 if !self.scanner.has_token(&[TokenKind::RParent]) {
110 return Err(ParseError::Syntax(
111 self.position(),
112 SyntaxError::ClosingParenthesisMissing,
113 ));
114 }
115 }
116
117 TokenKind::RParent => {
118 self.scanner.next();
119 return Err(ParseError::Syntax(
120 pos,
121 SyntaxError::UnexpectedClosingParenthesis,
122 ));
123 }
124
125 TokenKind::HashLParen => {
126 self.scanner.next();
127
128 let mut exprs = vec![];
129
130 while !self
131 .scanner
132 .has_token(&[TokenKind::Eof, TokenKind::RParent])
133 {
134 exprs.push(self.parse(true)?.datum());
135 }
136
137 if !self.scanner.has_token(&[TokenKind::RParent]) {
138 return Err(ParseError::Syntax(
139 self.position(),
140 SyntaxError::ClosingParenthesisMissing,
141 ));
142 }
143 res = Box::new(Expr::ImmutableVector(exprs.into_boxed_slice()))
144 }
145
146 TokenKind::HashGLParen => {
147 self.scanner.next();
148
149 let mut exprs = vec![];
150
151 while !self
152 .scanner
153 .has_token(&[TokenKind::Eof, TokenKind::RParent])
154 {
155 exprs.push(self.parse(true)?.datum());
156 }
157
158 if !self.scanner.has_token(&[TokenKind::RParent]) {
159 return Err(ParseError::Syntax(
160 self.position(),
161 SyntaxError::ClosingParenthesisMissing,
162 ));
163 }
164 res = Box::new(Expr::GrowableVector(exprs.into_boxed_slice()))
165 }
166
167 TokenKind::U8LParen => {
168 self.scanner.next();
169
170 let mut bytes = vec![];
171
172 while !self
173 .scanner
174 .has_token(&[TokenKind::Eof, TokenKind::RParent])
175 {
176 let number = self.scanner.token().int_val;
177 if number > 0 && number <= 255 {
178 bytes.push(number as u8);
179 } else {
180 return Err(ParseError::Syntax(
181 self.position(),
182 SyntaxError::NotAByteValue,
183 ));
184 }
185 }
186
187 if !self.scanner.has_token(&[TokenKind::RParent]) {
188 return Err(ParseError::Syntax(
189 self.position(),
190 SyntaxError::ClosingParenthesisMissing,
191 ));
192 }
193 res = Box::new(Expr::ByteVector(bytes.into_boxed_slice()))
194 }
195
196 TokenKind::Quote => {
197 self.scanner.next();
198
199 res = Expr::from_slice(
200 vec![
201 Box::new(Expr::Symbol(self.symbols.intern("quote"))),
202 self.parse(true)?,
203 ],
204 Box::new(Expr::Null),
205 );
206 }
207
208 TokenKind::BackQuote => {
209 self.scanner.next();
210
211 res = Expr::from_slice(
212 vec![
213 Box::new(Expr::Symbol(self.symbols.intern("quasiquote"))),
214 self.parse(true)?,
215 ],
216 Box::new(Expr::Null),
217 );
218 }
219
220 TokenKind::Comma => {
221 self.scanner.next();
222
223 res = Expr::from_slice(
224 vec![
225 Box::new(Expr::Symbol(self.symbols.intern("unquote"))),
226 self.parse(true)?,
227 ],
228 Box::new(Expr::Null),
229 );
230 }
231
232 TokenKind::CommaAt => {
233 self.scanner.next();
234
235 res = Expr::from_slice(
236 vec![
237 Box::new(Expr::Symbol(self.symbols.intern("unquote-splicing"))),
238 self.parse(true)?,
239 ],
240 Box::new(Expr::Null),
241 );
242 }
243 TokenKind::Dot => {
244 self.scanner.next();
245 return Err(ParseError::Syntax(pos, SyntaxError::UnexpectedDot));
246 }
247 }
248
249 if prescan {
250 self.scanner.next();
251 }
252
253 Ok(Box::new(Expr::Syntax(pos, res)))
254 }
255
256 pub fn position(&self) -> Position {
257 self.scanner.token().pos
258 }
259}
260
261#[derive(Clone, Copy, PartialEq, Eq, Debug)]
262pub enum ParseError {
263 Lexical(Position, LexicalError),
264 Syntax(Position, SyntaxError),
265}
266
267impl fmt::Display for ParseError {
268 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
269 match self {
270 Self::Lexical(pos, err) => {
271 write!(f, "error {} at {}", pos, err)
272 }
273
274 Self::Syntax(pos, err) => {
275 write!(f, "error {} at {}", pos, err)
276 }
277 }
278 }
279}