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.rs159
1 files changed, 76 insertions, 83 deletions
diff --git a/src/lisp/parse.rs b/src/lisp/parse.rs
index 737e7ad..8aeb672 100644
--- a/src/lisp/parse.rs
+++ b/src/lisp/parse.rs
@@ -1,5 +1,5 @@
1use crate::lisp::{ 1use crate::lisp::{
2 error::{LispError, ParseError, ParseErrorKind}, 2 error::{ParseError, ParseErrorKind},
3 lex::{Lexer, Span, Token}, 3 lex::{Lexer, Span, Token},
4 number::LispNumber, 4 number::LispNumber,
5 LispExpr, 5 LispExpr,
@@ -30,97 +30,91 @@ impl<'lex> Parser<'lex> {
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, ParseError> = match token { 33 let r: Result<LispExpr, ParseError> =
34 Token::LeftParen => { 34 match token {
35 stack.push(Group::Parens(Vec::new())); 35 Token::LeftParen => {
36 continue; 36 stack.push(Group::Parens(Vec::new()));
37 } 37 continue;
38 Token::RightParen => { 38 }
39 let group = stack 39 Token::RightParen => {
40 .pop() 40 let group = stack
41 .ok_or_else(|| (ParseError::new(span, ParseErrorKind::UnmatchedParen)))?; 41 .pop()
42 match group { 42 .ok_or_else(|| ParseError::new(span, ParseErrorKind::UnmatchedParen))?;
43 Group::Parens(v) => { 43 match group {
44 if v.len() == 0 { 44 Group::Parens(v) => {
45 Ok(LispExpr::Unit) 45 if v.is_empty() {
46 } else { 46 Ok(LispExpr::Unit)
47 Ok(LispExpr::List(v)) 47 } else {
48 Ok(LispExpr::List(v))
49 }
48 } 50 }
51 _ => Err(ParseError::new(
52 span,
53 ParseErrorKind::UnexpectedToken {
54 expected: "expression",
55 found: "(",
56 },
57 )),
49 } 58 }
50 _ => Err(From::from(ParseError::new(
51 span,
52 ParseErrorKind::UnexpectedToken {
53 expected: "expression",
54 found: "(",
55 },
56 ))),
57 } 59 }
58 } 60 Token::Float(f) => f
59 Token::Float(f) => f 61 .parse::<f64>()
60 .parse::<f64>() 62 .map(|n| LispExpr::Number(LispNumber::Float(n)))
61 .map(|n| LispExpr::Number(LispNumber::Float(n))) 63 .map_err(|_| ParseError::new(span, ParseErrorKind::LiteralParseError)),
62 .map_err(|_| ParseError::new(span, ParseErrorKind::LiteralParseError).into()), 64 Token::Integer(i) => i
63 Token::Integer(i) => i 65 .parse::<i64>()
64 .parse::<i64>() 66 .map(|n| LispExpr::Number(LispNumber::Integer(n)))
65 .map(|n| LispExpr::Number(LispNumber::Integer(n))) 67 .map_err(|_| ParseError::new(span, ParseErrorKind::LiteralParseError)),
66 .map_err(|_| ParseError::new(span, ParseErrorKind::LiteralParseError).into()), 68 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())), 69 Token::Char(s) => Ok(LispExpr::Char(s.chars().nth(2).ok_or_else(|| {
68 Token::Char(s) => {
69 Ok(LispExpr::Char(s.chars().nth(2).ok_or_else(|| {
70 ParseError::new(span, ParseErrorKind::LiteralParseError) 70 ParseError::new(span, ParseErrorKind::LiteralParseError)
71 })?)) 71 })?)),
72 } 72 Token::Name(n) => Ok(name_expr(n)),
73 Token::Name(n) => Ok(name_expr(n)), 73 Token::BackQuote => {
74 Token::BackQuote => { 74 total_backticks += 1;
75 total_backticks += 1; 75 if let Some(&mut Group::Backticks(ref mut n)) = stack.last_mut() {
76 if let Some(&mut Group::Backticks(ref mut n)) = stack.last_mut() { 76 *n += 1;
77 *n += 1; 77 continue;
78 }
79 stack.push(Group::Backticks(1));
78 continue; 80 continue;
79 } 81 }
80 stack.push(Group::Backticks(1)); 82 Token::Comma => {
81 continue; 83 if total_backticks <= 0 {
82 } 84 return Err(ParseError::new(span, ParseErrorKind::UnbalancedComma));
83 Token::Comma => { 85 }
84 if total_backticks <= 0 { 86 total_backticks -= 1;
85 return Err(ParseError::new(span, ParseErrorKind::UnbalancedComma)); 87 if let Some(&mut Group::Backticks(ref mut n)) = stack.last_mut() {
86 } 88 *n -= 1;
87 total_backticks -= 1; 89 continue;
88 if let Some(&mut Group::Backticks(ref mut n)) = stack.last_mut() { 90 }
89 *n -= 1; 91 stack.push(Group::Backticks(-1));
90 continue; 92 continue;
91 } 93 }
92 stack.push(Group::Backticks(-1)); 94 Token::CommaAt => {
93 continue; 95 if total_backticks <= 0 {
94 } 96 return Err(ParseError::new(span, ParseErrorKind::UnbalancedComma));
95 Token::CommaAt => { 97 }
96 if total_backticks <= 0 { 98 total_backticks -= 1;
97 return Err(ParseError::new(span, ParseErrorKind::UnbalancedComma)); 99 stack.push(Group::CommaAt);
100 continue;
98 } 101 }
99 total_backticks -= 1; 102 Token::Quote => {
100 stack.push(Group::CommaAt); 103 if let Some(&mut Group::Quotes(ref mut n)) = stack.last_mut() {
101 continue; 104 *n += 1;
102 } 105 continue;
103 Token::Quote => { 106 }
104 if let Some(&mut Group::Quotes(ref mut n)) = stack.last_mut() { 107 stack.push(Group::Quotes(1));
105 *n += 1;
106 continue; 108 continue;
107 } 109 }
108 stack.push(Group::Quotes(1)); 110 Token::End => {
109 continue; 111 if stack.iter().any(|group| matches!(*group, Group::Parens(_))) {
110 } 112 Err(ParseError::new(span, ParseErrorKind::MissingCloseParen))
111 Token::End => { 113 } else {
112 let any_paren = stack.iter().any(|group| match *group { 114 Err(ParseError::new(span, ParseErrorKind::UnexpectedEof))
113 Group::Parens(_) => true, 115 }
114 _ => false,
115 });
116
117 if any_paren {
118 Err(ParseError::new(span, ParseErrorKind::MissingCloseParen))
119 } else {
120 Err(ParseError::new(span, ParseErrorKind::UnexpectedEof))
121 } 116 }
122 } 117 };
123 };
124 let mut v = r?; 118 let mut v = r?;
125 loop { 119 loop {
126 match stack.last_mut() { 120 match stack.last_mut() {
@@ -181,8 +175,7 @@ impl<'lex> Parser<'lex> {
181 expected: "EOF", 175 expected: "EOF",
182 found: token.name(), 176 found: token.name(),
183 }, 177 },
184 ) 178 )),
185 .into()),
186 } 179 }
187 } 180 }
188 181
@@ -210,7 +203,7 @@ fn name_expr(input: &str) -> LispExpr {
210mod tests { 203mod tests {
211 use super::*; 204 use super::*;
212 fn parse(input: &str) -> Result<LispExpr, ParseError> { 205 fn parse(input: &str) -> Result<LispExpr, ParseError> {
213 let mut parser = Parser::new(Lexer::new(input, 0)); 206 let mut parser = Parser::new(Lexer::new(input));
214 207
215 parser.parse_single_expr() 208 parser.parse_single_expr()
216 } 209 }