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.rs55
1 files changed, 24 insertions, 31 deletions
diff --git a/src/lisp/parse.rs b/src/lisp/parse.rs
index 89a272a..4e0f427 100644
--- a/src/lisp/parse.rs
+++ b/src/lisp/parse.rs
@@ -1,5 +1,5 @@
1use crate::lisp::{ 1use crate::lisp::{
2 error::LispError, 2 error::{LispError, ParseError, ParseErrorKind},
3 lex::{Lexer, Span, Token}, 3 lex::{Lexer, Span, Token},
4 number::LispNumber, 4 number::LispNumber,
5 LispExpr, 5 LispExpr,
@@ -10,26 +10,6 @@ pub struct Parser<'lex> {
10 cur_token: Option<(Span, Token<'lex>)>, 10 cur_token: Option<(Span, Token<'lex>)>,
11} 11}
12 12
13// pub struct ParseError {
14// pub span: Span,
15// pub kind: ParseErrorKind,
16// }
17//
18// pub enum ParseErrorKind {
19// InvalidLiteral,
20// InvalidToken,
21// LiteralParseError,
22// MissingCloseParen,
23// UnbalancedComma,
24// UnexpectedEof,
25// UnexpectedToken {
26// expected: &'static str,
27// found: &'static str,
28// },
29// UnmatchedParen,
30// UnterminatedString,
31// }
32
33enum Group { 13enum Group {
34 Backticks(i32), 14 Backticks(i32),
35 CommaAt, 15 CommaAt,
@@ -49,7 +29,7 @@ impl<'lex> Parser<'lex> {
49 let mut stack = Vec::new(); 29 let mut stack = Vec::new();
50 let mut total_backticks = 0; 30 let mut total_backticks = 0;
51 loop { 31 loop {
52 let (_, token) = self.next()?; 32 let (span, token) = self.next()?;
53 let r: Result<LispExpr, LispError> = match token { 33 let r: Result<LispExpr, LispError> = match token {
54 Token::LeftParen => { 34 Token::LeftParen => {
55 stack.push(Group::Parens(Vec::new())); 35 stack.push(Group::Parens(Vec::new()));
@@ -57,21 +37,27 @@ impl<'lex> Parser<'lex> {
57 } 37 }
58 Token::RightParen => { 38 Token::RightParen => {
59 let group = stack.pop().ok_or_else( 39 let group = stack.pop().ok_or_else(
60 || LispError::ParseError, // unmatched paren here 40 || (ParseError::new(span, ParseErrorKind::UnmatchedParen)), // unmatched paren here
61 )?; 41 )?;
62 match group { 42 match group {
63 Group::Parens(v) => Ok(LispExpr::List(v)), 43 Group::Parens(v) => Ok(LispExpr::List(v)),
64 _ => Err(LispError::ParseError), 44 _ => Err(From::from(ParseError::new(
45 span,
46 ParseErrorKind::UnexpectedToken {
47 expected: "expression",
48 found: "(",
49 },
50 ))),
65 } 51 }
66 } 52 }
67 Token::Float(f) => f 53 Token::Float(f) => f
68 .parse::<f64>() 54 .parse::<f64>()
69 .map(|n| LispExpr::Number(LispNumber::Float(n))) 55 .map(|n| LispExpr::Number(LispNumber::Float(n)))
70 .map_err(|_| LispError::ParseError), 56 .map_err(|_| ParseError::new(span, ParseErrorKind::LiteralParseError).into()),
71 Token::Integer(i) => i 57 Token::Integer(i) => i
72 .parse::<i64>() 58 .parse::<i64>()
73 .map(|n| LispExpr::Number(LispNumber::Integer(n))) 59 .map(|n| LispExpr::Number(LispNumber::Integer(n)))
74 .map_err(|_| LispError::ParseError), 60 .map_err(|_| ParseError::new(span, ParseErrorKind::LiteralParseError).into()),
75 Token::String(s) => Ok(LispExpr::StringLit(s.into())), 61 Token::String(s) => Ok(LispExpr::StringLit(s.into())),
76 Token::Name(n) => Ok(name_expr(n)), 62 Token::Name(n) => Ok(name_expr(n)),
77 Token::BackQuote => { 63 Token::BackQuote => {
@@ -85,7 +71,7 @@ impl<'lex> Parser<'lex> {
85 } 71 }
86 Token::Comma => { 72 Token::Comma => {
87 if total_backticks <= 0 { 73 if total_backticks <= 0 {
88 return Err(LispError::ParseError); // unbalanced comma 74 return Err(ParseError::new(span, ParseErrorKind::UnbalancedComma).into());
89 } 75 }
90 total_backticks -= 1; 76 total_backticks -= 1;
91 if let Some(&mut Group::Backticks(ref mut n)) = stack.last_mut() { 77 if let Some(&mut Group::Backticks(ref mut n)) = stack.last_mut() {
@@ -97,7 +83,7 @@ impl<'lex> Parser<'lex> {
97 } 83 }
98 Token::CommaAt => { 84 Token::CommaAt => {
99 if total_backticks <= 0 { 85 if total_backticks <= 0 {
100 return Err(LispError::ParseError); // unbalanced comma 86 return Err(ParseError::new(span, ParseErrorKind::UnbalancedComma).into());
101 } 87 }
102 total_backticks -= 1; 88 total_backticks -= 1;
103 stack.push(Group::CommaAt); 89 stack.push(Group::CommaAt);
@@ -118,9 +104,9 @@ impl<'lex> Parser<'lex> {
118 }); 104 });
119 105
120 if any_paren { 106 if any_paren {
121 Err(LispError::ParseError) // unbalanced paren 107 Err(ParseError::new(span, ParseErrorKind::MissingCloseParen).into())
122 } else { 108 } else {
123 Err(LispError::ParseError) // unexpected eof 109 Err(ParseError::new(span, ParseErrorKind::UnexpectedEof).into())
124 } 110 }
125 } 111 }
126 }; 112 };
@@ -178,7 +164,14 @@ impl<'lex> Parser<'lex> {
178 164
179 match self.next()? { 165 match self.next()? {
180 (_, Token::End) => Ok(expr), 166 (_, Token::End) => Ok(expr),
181 _ => Err(LispError::ParseError), // too many tokens 167 (span, token) => Err(ParseError::new(
168 span,
169 ParseErrorKind::UnexpectedToken {
170 expected: "EOF",
171 found: token.name(),
172 },
173 )
174 .into()),
182 } 175 }
183 } 176 }
184 177