aboutsummaryrefslogtreecommitdiff
path: root/src/lisp/parse.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lisp/parse.rs')
-rw-r--r--src/lisp/parse.rs46
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)]
204mod tests { 210mod 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()