r7rs_parser/
parser.rs

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}