diff options
Diffstat (limited to 'src/lisp')
-rw-r--r-- | src/lisp/parse.rs | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/src/lisp/parse.rs b/src/lisp/parse.rs index 6a8de9f..737e7ad 100644 --- a/src/lisp/parse.rs +++ b/src/lisp/parse.rs | |||
@@ -25,22 +25,28 @@ impl<'lex> Parser<'lex> { | |||
25 | } | 25 | } |
26 | } | 26 | } |
27 | 27 | ||
28 | pub fn parse_expr(&mut self) -> Result<LispExpr, LispError> { | 28 | pub fn parse_expr(&mut self) -> Result<LispExpr, ParseError> { |
29 | let mut stack = Vec::new(); | 29 | let mut stack = Vec::new(); |
30 | let mut total_backticks = 0; | 30 | let mut total_backticks = 0; |
31 | loop { | 31 | loop { |
32 | let (span, token) = self.next()?; | 32 | let (span, token) = self.next()?; |
33 | let r: Result<LispExpr, LispError> = match token { | 33 | let r: Result<LispExpr, ParseError> = match token { |
34 | Token::LeftParen => { | 34 | Token::LeftParen => { |
35 | stack.push(Group::Parens(Vec::new())); | 35 | stack.push(Group::Parens(Vec::new())); |
36 | continue; | 36 | continue; |
37 | } | 37 | } |
38 | Token::RightParen => { | 38 | Token::RightParen => { |
39 | let group = stack.pop().ok_or_else( | 39 | let group = stack |
40 | || (ParseError::new(span, ParseErrorKind::UnmatchedParen)), // unmatched paren here | 40 | .pop() |
41 | )?; | 41 | .ok_or_else(|| (ParseError::new(span, ParseErrorKind::UnmatchedParen)))?; |
42 | match group { | 42 | match group { |
43 | Group::Parens(v) => Ok(LispExpr::List(v)), | 43 | Group::Parens(v) => { |
44 | if v.len() == 0 { | ||
45 | Ok(LispExpr::Unit) | ||
46 | } else { | ||
47 | Ok(LispExpr::List(v)) | ||
48 | } | ||
49 | } | ||
44 | _ => Err(From::from(ParseError::new( | 50 | _ => Err(From::from(ParseError::new( |
45 | span, | 51 | span, |
46 | ParseErrorKind::UnexpectedToken { | 52 | ParseErrorKind::UnexpectedToken { |
@@ -59,11 +65,11 @@ impl<'lex> Parser<'lex> { | |||
59 | .map(|n| LispExpr::Number(LispNumber::Integer(n))) | 65 | .map(|n| LispExpr::Number(LispNumber::Integer(n))) |
60 | .map_err(|_| ParseError::new(span, ParseErrorKind::LiteralParseError).into()), | 66 | .map_err(|_| ParseError::new(span, ParseErrorKind::LiteralParseError).into()), |
61 | Token::String(s) => Ok(LispExpr::StringLit(s[1..s.len() - 1].into())), | 67 | Token::String(s) => Ok(LispExpr::StringLit(s[1..s.len() - 1].into())), |
62 | Token::Char(s) => Ok(LispExpr::Char(s.chars().nth(2).ok_or_else( | 68 | Token::Char(s) => { |
63 | || -> LispError { | 69 | Ok(LispExpr::Char(s.chars().nth(2).ok_or_else(|| { |
64 | ParseError::new(span, ParseErrorKind::LiteralParseError).into() | 70 | ParseError::new(span, ParseErrorKind::LiteralParseError) |
65 | }, | 71 | })?)) |
66 | )?)), | 72 | } |
67 | Token::Name(n) => Ok(name_expr(n)), | 73 | Token::Name(n) => Ok(name_expr(n)), |
68 | Token::BackQuote => { | 74 | Token::BackQuote => { |
69 | total_backticks += 1; | 75 | total_backticks += 1; |
@@ -76,7 +82,7 @@ impl<'lex> Parser<'lex> { | |||
76 | } | 82 | } |
77 | Token::Comma => { | 83 | Token::Comma => { |
78 | if total_backticks <= 0 { | 84 | if total_backticks <= 0 { |
79 | return Err(ParseError::new(span, ParseErrorKind::UnbalancedComma).into()); | 85 | return Err(ParseError::new(span, ParseErrorKind::UnbalancedComma)); |
80 | } | 86 | } |
81 | total_backticks -= 1; | 87 | total_backticks -= 1; |
82 | if let Some(&mut Group::Backticks(ref mut n)) = stack.last_mut() { | 88 | if let Some(&mut Group::Backticks(ref mut n)) = stack.last_mut() { |
@@ -88,7 +94,7 @@ impl<'lex> Parser<'lex> { | |||
88 | } | 94 | } |
89 | Token::CommaAt => { | 95 | Token::CommaAt => { |
90 | if total_backticks <= 0 { | 96 | if total_backticks <= 0 { |
91 | return Err(ParseError::new(span, ParseErrorKind::UnbalancedComma).into()); | 97 | return Err(ParseError::new(span, ParseErrorKind::UnbalancedComma)); |
92 | } | 98 | } |
93 | total_backticks -= 1; | 99 | total_backticks -= 1; |
94 | stack.push(Group::CommaAt); | 100 | stack.push(Group::CommaAt); |
@@ -109,9 +115,9 @@ impl<'lex> Parser<'lex> { | |||
109 | }); | 115 | }); |
110 | 116 | ||
111 | if any_paren { | 117 | if any_paren { |
112 | Err(ParseError::new(span, ParseErrorKind::MissingCloseParen).into()) | 118 | Err(ParseError::new(span, ParseErrorKind::MissingCloseParen)) |
113 | } else { | 119 | } else { |
114 | Err(ParseError::new(span, ParseErrorKind::UnexpectedEof).into()) | 120 | Err(ParseError::new(span, ParseErrorKind::UnexpectedEof)) |
115 | } | 121 | } |
116 | } | 122 | } |
117 | }; | 123 | }; |
@@ -148,13 +154,13 @@ impl<'lex> Parser<'lex> { | |||
148 | } | 154 | } |
149 | } | 155 | } |
150 | 156 | ||
151 | fn next(&mut self) -> Result<(Span, Token<'lex>), LispError> { | 157 | fn next(&mut self) -> Result<(Span, Token<'lex>), ParseError> { |
152 | let r = self.peek()?; | 158 | let r = self.peek()?; |
153 | self.cur_token = None; | 159 | self.cur_token = None; |
154 | Ok(r) | 160 | Ok(r) |
155 | } | 161 | } |
156 | 162 | ||
157 | fn peek(&mut self) -> Result<(Span, Token<'lex>), LispError> { | 163 | fn peek(&mut self) -> Result<(Span, Token<'lex>), ParseError> { |
158 | if let Some(tok) = self.cur_token { | 164 | if let Some(tok) = self.cur_token { |
159 | Ok(tok) | 165 | Ok(tok) |
160 | } else { | 166 | } else { |
@@ -164,7 +170,7 @@ impl<'lex> Parser<'lex> { | |||
164 | } | 170 | } |
165 | } | 171 | } |
166 | 172 | ||
167 | pub fn parse_single_expr(&mut self) -> Result<LispExpr, LispError> { | 173 | pub fn parse_single_expr(&mut self) -> Result<LispExpr, ParseError> { |
168 | let expr = self.parse_expr()?; | 174 | let expr = self.parse_expr()?; |
169 | 175 | ||
170 | match self.next()? { | 176 | match self.next()? { |
@@ -180,7 +186,7 @@ impl<'lex> Parser<'lex> { | |||
180 | } | 186 | } |
181 | } | 187 | } |
182 | 188 | ||
183 | pub fn parse_exprs(&mut self) -> Result<Vec<LispExpr>, LispError> { | 189 | pub fn parse_exprs(&mut self) -> Result<Vec<LispExpr>, ParseError> { |
184 | let mut res = Vec::new(); | 190 | let mut res = Vec::new(); |
185 | loop { | 191 | loop { |
186 | match self.peek()? { | 192 | match self.peek()? { |
@@ -203,7 +209,7 @@ fn name_expr(input: &str) -> LispExpr { | |||
203 | #[cfg(test)] | 209 | #[cfg(test)] |
204 | mod tests { | 210 | mod tests { |
205 | use super::*; | 211 | use super::*; |
206 | fn parse(input: &str) -> Result<LispExpr, LispError> { | 212 | fn parse(input: &str) -> Result<LispExpr, ParseError> { |
207 | let mut parser = Parser::new(Lexer::new(input, 0)); | 213 | let mut parser = Parser::new(Lexer::new(input, 0)); |
208 | 214 | ||
209 | parser.parse_single_expr() | 215 | parser.parse_single_expr() |