1#[derive(Debug, Clone, PartialEq, Eq)]
2pub enum TokenTree {
3 Ident(String, Span),
4 Punct(char, Spacing, Span),
5 Literal(String, Span),
6 Group(Delimiter, Vec<TokenTree>, Span)
7}
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum Spacing {
11 Alone,
12 Joint
13}
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum Delimiter {
17 Parenthesis,
18 Brace,
19 Bracket,
20 None
21}
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
24pub struct Span {
25 pub line: usize,
26 pub col: usize,
27 pub pos: usize,
28 pub id: usize
29}
30
31pub struct TokenIter {
32 tokens: Vec<TokenTree>,
33 pos: usize
34}
35
36impl TokenIter {
37 pub fn new(tokens: Vec<TokenTree>) -> Self {
38 Self {
39 tokens,
40 pos: 0
41 }
42 }
43
44 pub fn pos(&self) -> usize {
45 self.pos
46 }
47
48 pub fn next(&mut self) -> Option<&TokenTree> {
49 if self.pos >= self.tokens.len() {
50 return None;
51 }
52 let tok = Some(&self.tokens[self.pos]);
53 self.pos += 1;
54
55 tok
56 }
57
58 pub fn peek(&self) -> Option<&TokenTree> {
59 if self.pos >= self.tokens.len() {
60 return None;
61 }
62 Some(&self.tokens[self.pos])
63 }
64
65 pub fn expect_ident(&mut self, s: Option<String>) -> Result<(String, Span), ParseError> {
66 match self.next() {
67 Some(tok) => match tok {
68 TokenTree::Ident(ident, span) => {
69 match s {
70 Some(s) => {
71 if *ident == s {
72 Ok((s, *span))
73 }
74 else {
75 Err(ParseError::IncorrectIdent(ident.to_owned(), *span))
76 }
77 }
78 None => Ok((ident.to_owned(), *span))
79 }
80 }
81 TokenTree::Punct(c, _, span) => Err(ParseError::UnexpectedPunct(c.to_owned(), *span)),
82 TokenTree::Literal(lit, span) => Err(ParseError::UnexpectedLiteral(lit.to_owned(), *span)),
83 TokenTree::Group(del, _, span) => Err(ParseError::UnexpectedGroup(*del, *span))
84 }
85 None => Err(ParseError::UnexpectedEOT)
86 }
87 }
88
89 pub fn expect_punct(&mut self, c: Option<char>) -> Result<(char, Span), ParseError> {
90 match self.next() {
91 Some(tok) => match tok {
92 TokenTree::Ident(ident, span) => Err(ParseError::UnexpectedIdent(ident.to_owned(), *span)),
93 TokenTree::Punct(punct, _, span) => {
94 match c {
95 Some(c) => {
96 if *punct == c {
97 Ok((c, *span))
98 }
99 else {
100 Err(ParseError::IncorrectPunct(punct.to_owned(), *span))
101 }
102 }
103 None => Ok((punct.to_owned(), *span))
104 }
105 }
106 TokenTree::Literal(lit, span) => Err(ParseError::UnexpectedLiteral(lit.to_owned(), *span)),
107 TokenTree::Group(del, _, span) => Err(ParseError::UnexpectedGroup(*del, *span))
108 }
109 None => Err(ParseError::UnexpectedEOT)
110 }
111 }
112
113 pub fn expect_literal(&mut self, s: Option<String>) -> Result<(String, Span), ParseError> {
114 match self.next() {
115 Some(tok) => match tok {
116 TokenTree::Ident(ident, span) => Err(ParseError::UnexpectedIdent(ident.to_owned(), *span)),
117 TokenTree::Punct(c, _, span) => Err(ParseError::UnexpectedPunct(c.to_owned(), *span)),
118 TokenTree::Literal(lit, span) => {
119 match s {
120 Some(s) => {
121 if *lit == s {
122 Ok((s, *span))
123 }
124 else {
125 Err(ParseError::IncorrectLiteral(lit.to_owned(), *span))
126 }
127 }
128 None => Ok((lit.to_owned(), *span))
129 }
130 }
131 TokenTree::Group(del, _, span) => Err(ParseError::UnexpectedGroup(*del, *span))
132 }
133 None => Err(ParseError::UnexpectedEOT)
134 }
135 }
136
137 pub fn expect_group(&mut self, g: Option<(Delimiter, Vec<TokenTree>, Span)>) -> Result<(Delimiter, Vec<TokenTree>, Span), ParseError> {
138 match self.next() {
139 Some(tok) => match tok {
140 TokenTree::Ident(ident, span) => Err(ParseError::UnexpectedIdent(ident.to_owned(), *span)),
141 TokenTree::Punct(c, _, span) => Err(ParseError::UnexpectedPunct(c.to_owned(), *span)),
142 TokenTree::Literal(lit, span) => Err(ParseError::UnexpectedLiteral(lit.to_owned(), *span)),
143 TokenTree::Group(del, tree, span) => {
144 match g {
145 Some(g) => {
146 if *del == g.0 && tree.as_slice() == g.1.as_slice() {
147 Ok(g)
148 }
149 else {
150 Err(ParseError::IncorrectGroup(*del, tree.to_vec(), *span))
151 }
152 }
153 None => Ok((*del, tree.to_vec(), *span))
154 }
155 }
156 }
157 None => Err(ParseError::UnexpectedEOT)
158 }
159 }
160}
161
162#[derive(Debug)]
163pub enum ParseError {
164 UnexpectedIdent(String, Span),
165 UnexpectedPunct(char, Span),
166 UnexpectedLiteral(String, Span),
167 UnexpectedGroup(Delimiter, Span),
168 UnexpectedEOT, IncorrectIdent(String, Span),
170 IncorrectPunct(char, Span),
171 IncorrectLiteral(String, Span),
172 IncorrectGroup(Delimiter, Vec<TokenTree>, Span),
173 IncorrectDelimiter(Delimiter, Span),
174 UnmatchedAngleBracket(Span)
175}