1use super::*;
2
3impl Parser {
4 pub fn new(tokens: Vec<Token>) -> Self {
5 Parser {
6 tokens,
7 pos: 0,
8 recursion_depth: 0,
9 }
10 }
11
12 pub(super) fn enter_recursion(&mut self) -> Result<(), ParseError> {
18 if self.recursion_depth >= super::MAX_PARSE_DEPTH {
19 return Err(self.error(format!(
20 "Expression too deeply nested (max {} levels). Refactor with named bindings or smaller sub-expressions.",
21 super::MAX_PARSE_DEPTH
22 )));
23 }
24 self.recursion_depth += 1;
25 Ok(())
26 }
27
28 pub(super) fn exit_recursion(&mut self) {
29 self.recursion_depth = self.recursion_depth.saturating_sub(1);
30 }
31
32 pub(super) fn error(&self, msg: impl Into<String>) -> ParseError {
33 let tok = self.current();
34 ParseError::Error {
35 msg: msg.into(),
36 line: tok.line,
37 col: tok.col,
38 }
39 }
40
41 pub(super) fn current(&self) -> &Token {
42 if self.pos < self.tokens.len() {
43 &self.tokens[self.pos]
44 } else {
45 self.tokens.last().unwrap()
46 }
47 }
48
49 #[allow(dead_code)]
50 pub(super) fn peek(&self, offset: usize) -> &Token {
51 let idx = self.pos + offset;
52 if idx < self.tokens.len() {
53 &self.tokens[idx]
54 } else {
55 self.tokens.last().unwrap()
56 }
57 }
58
59 pub(super) fn peek_skip_formatting(&self, nth: usize) -> &Token {
61 let mut count = 0;
62 let mut idx = self.pos;
63 while idx < self.tokens.len() {
64 if !matches!(
65 self.tokens[idx].kind,
66 TokenKind::Newline | TokenKind::Indent | TokenKind::Dedent
67 ) {
68 if count == nth {
69 return &self.tokens[idx];
70 }
71 count += 1;
72 }
73 idx += 1;
74 }
75 self.tokens.last().unwrap()
76 }
77
78 pub(super) fn advance(&mut self) -> &Token {
79 let tok = if self.pos < self.tokens.len() {
80 &self.tokens[self.pos]
81 } else {
82 self.tokens.last().unwrap()
83 };
84 if self.pos < self.tokens.len() {
85 self.pos += 1;
86 }
87 tok
88 }
89
90 pub(super) fn check_exact(&self, kind: &TokenKind) -> bool {
91 &self.current().kind == kind
92 }
93
94 pub(super) fn is_newline(&self) -> bool {
95 matches!(self.current().kind, TokenKind::Newline)
96 }
97
98 pub(super) fn is_indent(&self) -> bool {
99 matches!(self.current().kind, TokenKind::Indent)
100 }
101
102 pub(super) fn is_dedent(&self) -> bool {
103 matches!(self.current().kind, TokenKind::Dedent)
104 }
105
106 pub(super) fn is_eof(&self) -> bool {
107 matches!(self.current().kind, TokenKind::Eof)
108 }
109
110 #[allow(dead_code)]
111 pub(super) fn match_token(&mut self, kind: &TokenKind) -> Option<Token> {
112 if std::mem::discriminant(&self.current().kind) == std::mem::discriminant(kind) {
113 Some(self.advance().clone())
114 } else {
115 None
116 }
117 }
118
119 pub(super) fn expect_kind(&mut self, kind: &TokenKind, msg: &str) -> Result<Token, ParseError> {
120 if std::mem::discriminant(&self.current().kind) == std::mem::discriminant(kind) {
121 Ok(self.advance().clone())
122 } else {
123 Err(self.error(format!("{}, found {}", msg, self.current().kind)))
124 }
125 }
126
127 pub(super) fn expect_exact(&mut self, kind: &TokenKind) -> Result<Token, ParseError> {
128 if &self.current().kind == kind {
129 Ok(self.advance().clone())
130 } else {
131 Err(self.error(format!("Expected {}, found {}", kind, self.current().kind)))
132 }
133 }
134
135 pub(super) fn skip_formatting(&mut self) {
136 while matches!(
137 self.current().kind,
138 TokenKind::Newline | TokenKind::Indent | TokenKind::Dedent
139 ) {
140 self.advance();
141 }
142 }
143
144 pub(super) fn skip_newlines(&mut self) {
145 while self.is_newline() {
146 self.advance();
147 }
148 }
149
150 pub fn parse(&mut self) -> Result<Vec<TopLevel>, ParseError> {
151 let mut items = Vec::new();
152 self.skip_newlines();
153
154 while !self.is_eof() {
155 if let Some(item) = self.parse_top_level()? {
156 items.push(item);
157 }
158 self.skip_newlines();
159 }
160
161 Ok(items)
162 }
163
164 pub(super) fn parse_top_level(&mut self) -> Result<Option<TopLevel>, ParseError> {
165 match &self.current().kind {
166 TokenKind::Module => Ok(Some(TopLevel::Module(self.parse_module()?))),
167 TokenKind::Fn => Ok(Some(TopLevel::FnDef(self.parse_fn()?))),
168 TokenKind::Verify => Ok(Some(TopLevel::Verify(self.parse_verify()?))),
169 TokenKind::Decision => Ok(Some(TopLevel::Decision(self.parse_decision()?))),
170 TokenKind::Type => Ok(Some(TopLevel::TypeDef(self.parse_sum_type_def()?))),
171 TokenKind::Record => Ok(Some(TopLevel::TypeDef(self.parse_record_def()?))),
172 TokenKind::Effects => Err(self.error(
173 "`effects [...]` is a module-level declaration — it must be \
174 indented inside a `module` block. For files without a module \
175 header, the per-fn `! [...]` annotations already cover the \
176 effect surface; drop the top-level `effects` line.",
177 )),
178 TokenKind::Ident(s) if s == "val" || s == "var" => {
179 let kw = s.clone();
180 Err(self.error(format!(
181 "Unknown keyword '{}'. Bindings are just: x = 5",
182 kw
183 )))
184 }
185 TokenKind::Ident(_)
186 if matches!(&self.peek(1).kind, TokenKind::Assign | TokenKind::Colon) =>
187 {
188 let stmt = self.parse_binding()?;
189 Ok(Some(TopLevel::Stmt(stmt)))
190 }
191 TokenKind::Newline | TokenKind::Dedent | TokenKind::Indent => {
192 self.advance();
193 Ok(None)
194 }
195 TokenKind::Eof => Ok(None),
196 _ => {
197 let expr = self.parse_expr()?;
198 self.skip_newlines();
199 Ok(Some(TopLevel::Stmt(Stmt::Expr(expr))))
200 }
201 }
202 }
203}