1use super::*;
2
3impl Parser {
4 pub fn new(tokens: Vec<Token>) -> Self {
5 Parser { tokens, pos: 0 }
6 }
7
8 pub(super) fn error(&self, msg: impl Into<String>) -> ParseError {
9 let tok = self.current();
10 ParseError::Error {
11 msg: msg.into(),
12 line: tok.line,
13 col: tok.col,
14 }
15 }
16
17 pub(super) fn current(&self) -> &Token {
18 if self.pos < self.tokens.len() {
19 &self.tokens[self.pos]
20 } else {
21 self.tokens.last().unwrap()
22 }
23 }
24
25 #[allow(dead_code)]
26 pub(super) fn peek(&self, offset: usize) -> &Token {
27 let idx = self.pos + offset;
28 if idx < self.tokens.len() {
29 &self.tokens[idx]
30 } else {
31 self.tokens.last().unwrap()
32 }
33 }
34
35 pub(super) fn peek_skip_formatting(&self, nth: usize) -> &Token {
37 let mut count = 0;
38 let mut idx = self.pos;
39 while idx < self.tokens.len() {
40 if !matches!(
41 self.tokens[idx].kind,
42 TokenKind::Newline | TokenKind::Indent | TokenKind::Dedent
43 ) {
44 if count == nth {
45 return &self.tokens[idx];
46 }
47 count += 1;
48 }
49 idx += 1;
50 }
51 self.tokens.last().unwrap()
52 }
53
54 pub(super) fn advance(&mut self) -> &Token {
55 let tok = if self.pos < self.tokens.len() {
56 &self.tokens[self.pos]
57 } else {
58 self.tokens.last().unwrap()
59 };
60 if self.pos < self.tokens.len() {
61 self.pos += 1;
62 }
63 tok
64 }
65
66 pub(super) fn check_exact(&self, kind: &TokenKind) -> bool {
67 &self.current().kind == kind
68 }
69
70 pub(super) fn is_newline(&self) -> bool {
71 matches!(self.current().kind, TokenKind::Newline)
72 }
73
74 pub(super) fn is_indent(&self) -> bool {
75 matches!(self.current().kind, TokenKind::Indent)
76 }
77
78 pub(super) fn is_dedent(&self) -> bool {
79 matches!(self.current().kind, TokenKind::Dedent)
80 }
81
82 pub(super) fn is_eof(&self) -> bool {
83 matches!(self.current().kind, TokenKind::Eof)
84 }
85
86 #[allow(dead_code)]
87 pub(super) fn match_token(&mut self, kind: &TokenKind) -> Option<Token> {
88 if std::mem::discriminant(&self.current().kind) == std::mem::discriminant(kind) {
89 Some(self.advance().clone())
90 } else {
91 None
92 }
93 }
94
95 pub(super) fn expect_kind(&mut self, kind: &TokenKind, msg: &str) -> Result<Token, ParseError> {
96 if std::mem::discriminant(&self.current().kind) == std::mem::discriminant(kind) {
97 Ok(self.advance().clone())
98 } else {
99 Err(self.error(format!("{}, found {}", msg, self.current().kind)))
100 }
101 }
102
103 pub(super) fn expect_exact(&mut self, kind: &TokenKind) -> Result<Token, ParseError> {
104 if &self.current().kind == kind {
105 Ok(self.advance().clone())
106 } else {
107 Err(self.error(format!("Expected {}, found {}", kind, self.current().kind)))
108 }
109 }
110
111 pub(super) fn skip_formatting(&mut self) {
112 while matches!(
113 self.current().kind,
114 TokenKind::Newline | TokenKind::Indent | TokenKind::Dedent
115 ) {
116 self.advance();
117 }
118 }
119
120 pub(super) fn skip_newlines(&mut self) {
121 while self.is_newline() {
122 self.advance();
123 }
124 }
125
126 pub fn parse(&mut self) -> Result<Vec<TopLevel>, ParseError> {
127 let mut items = Vec::new();
128 self.skip_newlines();
129
130 while !self.is_eof() {
131 if let Some(item) = self.parse_top_level()? {
132 items.push(item);
133 }
134 self.skip_newlines();
135 }
136
137 Ok(items)
138 }
139
140 pub(super) fn parse_top_level(&mut self) -> Result<Option<TopLevel>, ParseError> {
141 match &self.current().kind {
142 TokenKind::Module => Ok(Some(TopLevel::Module(self.parse_module()?))),
143 TokenKind::Fn => Ok(Some(TopLevel::FnDef(self.parse_fn()?))),
144 TokenKind::Verify => Ok(Some(TopLevel::Verify(self.parse_verify()?))),
145 TokenKind::Decision => Ok(Some(TopLevel::Decision(self.parse_decision()?))),
146 TokenKind::Type => Ok(Some(TopLevel::TypeDef(self.parse_sum_type_def()?))),
147 TokenKind::Record => Ok(Some(TopLevel::TypeDef(self.parse_record_def()?))),
148 TokenKind::Effects => Ok(Some(self.parse_effect_set()?)),
149 TokenKind::Ident(s) if s == "val" || s == "var" => {
150 let kw = s.clone();
151 Err(self.error(format!(
152 "Unknown keyword '{}'. Bindings are just: x = 5",
153 kw
154 )))
155 }
156 TokenKind::Ident(_)
157 if matches!(&self.peek(1).kind, TokenKind::Assign | TokenKind::Colon) =>
158 {
159 let stmt = self.parse_binding()?;
160 Ok(Some(TopLevel::Stmt(stmt)))
161 }
162 TokenKind::Newline | TokenKind::Dedent | TokenKind::Indent => {
163 self.advance();
164 Ok(None)
165 }
166 TokenKind::Eof => Ok(None),
167 _ => {
168 let expr = self.parse_expr()?;
169 self.skip_newlines();
170 Ok(Some(TopLevel::Stmt(Stmt::Expr(expr))))
171 }
172 }
173 }
174}