1use crate::ParseError;
2
3use crate::block::check_callback_tails;
4
5use crate::block::condition;
6
7use crate::block::stmt;
8
9use crate::datatype::data_decl;
10
11use crate::datatype::derive_template;
12
13use crate::datatype::errors_decl;
14
15use crate::datatype::generalise;
16
17use crate::expr::parse_expr;
18
19use crate::expr::parse_spine;
20
21use crate::item::const_decl;
22
23use crate::item::declares_an_operator;
24
25use crate::item::extern_block;
26
27use crate::item::import_decl;
28
29use crate::item::module_decl;
30
31use crate::item::operator_decl;
32
33use crate::item::pattern_synonym;
34
35use crate::item::test_decl;
36
37use crate::item::type_alias;
38
39use crate::item::visibility;
40
41use crate::pattern::pattern_alt;
42
43use crate::pattern::patterns;
44
45use crate::signature::SignatureHead;
46
47use crate::signature::TypeStop;
48
49use crate::signature::capture_type;
50
51use crate::signature::clause;
52
53use crate::signature::signature_from;
54
55use crate::signature::signature_only;
56
57use crate::support::MAX_NESTING;
58
59use crate::support::nesting_depth;
60
61use crate::token::inline_rust;
62
63use crate::type_class::class_decl;
64
65use crate::type_class::constraints;
66
67use crate::type_class::given_clause;
68
69use crate::type_class::instance_decl;
70
71use crate::where_clause::where_predicates;
72
73use voltaic_ast::Binding;
74
75use voltaic_ast::Block;
76
77use voltaic_ast::Expr;
78
79use voltaic_ast::Fixity;
80
81use voltaic_ast::FnDecl;
82
83use voltaic_ast::Guard;
84
85use voltaic_ast::Ident;
86
87use voltaic_ast::Item;
88
89use voltaic_ast::Program;
90
91use voltaic_ast::Stmt;
92
93use voltaic_ast::TypeExpr;
94
95use voltaic_ast::Visibility;
96
97use voltaic_diag::Code;
98
99use voltaic_lexer::Keyword;
100
101use voltaic_lexer::Span;
102
103use voltaic_lexer::Token;
104
105use voltaic_lexer::TokenKind;
106
107use voltaic_lexer::Trivia;
108
109pub fn parse(toks: &[Token], src_len: usize) -> Result<Program, Vec<ParseError>> {
110 let deepest = nesting_depth(toks);
111 if deepest > MAX_NESTING {
112 let message = format!(
113 "this input nests brackets {} deep, and the limit is {}: deeper than that overflows the parser's stack",
114 deepest, MAX_NESTING
115 );
116 return Err(vec![ParseError {
117 code: Code::NestingTooDeep,
118 message,
119 span: (0, 0),
120 help: None,
121 }]);
122 }
123 Parser::new(toks).run(src_len)
124}
125
126pub(crate) struct Parser<'a> {
127 toks: &'a [Token],
128 pos: usize,
129 pub(crate) r#errors: Vec<ParseError>,
130 class_heads: std::collections::BTreeMap<(String, String), SignatureHead>,
131 pub(crate) fixities: std::collections::BTreeMap<String, (Fixity, u8, String)>,
132}
133
134impl<'a> Parser<'a> {
135 pub(crate) fn new(toks: &'a [Token]) -> Self {
136 Parser {
137 toks,
138 pos: 0,
139 r#errors: Vec::new(),
140 class_heads: std::collections::BTreeMap::new(),
141 fixities: std::collections::BTreeMap::new(),
142 }
143 }
144 pub(crate) fn run(mut self, src_len: usize) -> Result<Program, Vec<ParseError>> {
145 let items = self.program();
146 if self.r#errors.is_empty() {
147 let probe = Program {
148 items: items.clone(),
149 span: (0, src_len),
150 trailing: Vec::new(),
151 };
152 self.r#errors.extend(check_callback_tails(&probe));
153 }
154 if self.r#errors.is_empty() {
155 let trailing = self.eof_trivia();
156 return Ok(Program {
157 items,
158 span: (0, src_len),
159 trailing,
160 });
161 }
162 Err(self.r#errors)
163 }
164 fn program(&mut self) -> Vec<Item> {
165 let mut items = Vec::new();
166 self.skip_separators();
167 while !self.at_eof() {
168 match self.item() {
169 Ok(found) => items.push(found),
170 Err(e) => {
171 self.r#errors.push(e);
172 self.recover_to_item()
173 }
174 };
175 self.skip_separators();
176 }
177 items
178 }
179 pub(crate) fn items_until_dedent(&mut self) -> Result<Vec<Item>, ParseError> {
180 let mut items = Vec::new();
181 loop {
182 self.skip_separators();
183 if self.check(&TokenKind::Dedent) || self.at_eof() {
184 break;
185 }
186 match self.item() {
187 Ok(found) => items.push(found),
188 Err(e) => {
189 self.r#errors.push(e);
190 self.recover_to_item()
191 }
192 };
193 }
194 self.expect(&TokenKind::Dedent, "expected the module body to end")?;
195 Ok(items)
196 }
197 pub(crate) fn item(&mut self) -> Result<Item, ParseError> {
198 let leading = self.peek_leading();
199 let start = self.peek_span().0;
200 let marker = visibility(self)?;
201 if self.check(&TokenKind::Kw(Keyword::Data))
202 || self.check(&TokenKind::Kw(Keyword::Newtype))
203 || self.check(&TokenKind::Kw(Keyword::Union))
204 {
205 let decl = data_decl(self, leading, start, marker)?;
206 self.newline_with_trailing("expected a line break after the declaration")?;
207 return Ok(Item::Data(decl));
208 }
209 if self.check(&TokenKind::Kw(Keyword::Type)) {
210 let alias = type_alias(self, leading, start, marker)?;
211 self.newline_with_trailing("expected a line break after the alias")?;
212 return Ok(Item::Type(alias));
213 }
214 if self.check(&TokenKind::Kw(Keyword::Const)) || self.check(&TokenKind::Kw(Keyword::Static)) {
215 let decl = const_decl(self, leading, start, marker)?;
216 self.newline_with_trailing("expected a line break after the binding")?;
217 return Ok(Item::Const(decl));
218 }
219 if self.check(&TokenKind::Kw(Keyword::Import)) {
220 let decl = import_decl(self, leading, start, marker)?;
221 self.newline_with_trailing("expected a line break after the import")?;
222 return Ok(Item::Import(decl));
223 }
224 if self.check(&TokenKind::Kw(Keyword::Module)) {
225 let decl = module_decl(self, leading, start, marker)?;
226 self.newline_with_trailing("expected a line break after the module")?;
227 return Ok(Item::Module(decl));
228 }
229 if self.check(&TokenKind::Kw(Keyword::Test)) {
230 let decl = test_decl(self, leading, start)?;
231 self.newline_with_trailing("expected a line break after the test")?;
232 return Ok(Item::Test(decl));
233 }
234 if self.check(&TokenKind::Kw(Keyword::Rust)) {
235 let block = inline_rust(self, leading, start)?;
236 self.newline_with_trailing("expected a line break after the inline Rust")?;
237 return Ok(Item::InlineRust(block));
238 }
239 let word_is_pattern = match &self.peek().kind {
240 TokenKind::Ident(text) => text == "pattern",
241 _ => false,
242 };
243 let names_a_constructor = self.peek_at(1).is_some_and(|t| match &t.kind {
244 TokenKind::Ident(next) => next.chars().next().is_some_and(char::is_uppercase),
245 _ => false,
246 });
247 if word_is_pattern && names_a_constructor {
248 let decl = pattern_synonym(self, leading, start)?;
249 return Ok(Item::PatternSynonym(decl));
250 }
251 if declares_an_operator(self) {
252 let decl = operator_decl(self, leading, start)?;
253 return Ok(Item::OperatorDecl(decl));
254 }
255 if self.check(&TokenKind::Kw(Keyword::Deriving)) {
256 let decl = derive_template(self, leading, start)?;
257 self.newline_with_trailing("expected a line break after the deriving template")?;
258 return Ok(Item::DeriveTemplate(decl));
259 }
260 if self.check(&TokenKind::Kw(Keyword::Extern)) {
261 let block = extern_block(self, leading, start)?;
262 return Ok(Item::Extern(block));
263 }
264 if self.check(&TokenKind::Kw(Keyword::Errors)) {
265 let decl = errors_decl(self, leading, start, marker)?;
266 self.newline_with_trailing("expected a line break after the declaration")?;
267 return Ok(Item::Errors(decl));
268 }
269 if self.check(&TokenKind::Kw(Keyword::Class)) {
270 let decl = class_decl(self, leading, start, marker)?;
271 self.newline_with_trailing("expected a line break after the class")?;
272 return Ok(Item::Class(decl));
273 }
274 if self.check(&TokenKind::Kw(Keyword::Instance)) {
275 let decl = instance_decl(self, leading, start)?;
276 self.newline_with_trailing("expected a line break after the instance")?;
277 return Ok(Item::Instance(decl));
278 }
279 let mut decl = self.function(&[])?;
280 decl.leading = leading;
281 decl.visibility = marker;
282 decl.span = (start, decl.span.1);
283 Ok(Item::Fn(decl))
284 }
285 pub(crate) fn function(&mut self, reserved: &[String]) -> Result<FnDecl, ParseError> {
286 let leading = self.peek_leading();
287 let start = self.peek_span().0;
288 let name = self.ident("expected a name to begin a declaration")?;
289 let head = self.signature_head(&name)?;
290 self.equations(name, leading, start, &head, reserved, false)
291 }
292 pub(crate) fn where_function(&mut self) -> Result<FnDecl, ParseError> {
293 let leading = self.peek_leading();
294 let start = self.peek_span().0;
295 let name = self.ident("expected a name to begin a declaration")?;
296 let head = self.signature_head(&name)?;
297 self.equations(name, leading, start, &head, &[], true)
298 }
299 pub(crate) fn signature_head(&mut self, name: &Ident) -> Result<SignatureHead, ParseError> {
300 let binds_on_this_line = self.check(&TokenKind::Eq)
301 && self
302 .peek_at(1)
303 .is_some_and(|t| t.kind != TokenKind::Newline);
304 if binds_on_this_line {
305 let message = format!(
306 "a module-scope binding needs `const` or `static` and a type: `const {} : T = …`. Rust forbids `let` at module scope, and doc 03 §13.4 corrects doc 01 §4.3 accordingly",
307 name.text
308 );
309 return Err(ParseError::r#with(
310 Code::ModuleScopeBinding,
311 message,
312 name.span,
313 ));
314 }
315 self.expect(
316 &TokenKind::Colon,
317 "expected `:` after the name, to begin the signature",
318 )?;
319 let binder = given_clause(self)?;
320 let bounds = if binder.is_some() {
321 Vec::new()
322 } else {
323 constraints(self)?
324 };
325 let is_const = self.eat_keyword(Keyword::Const);
326 let is_async = self.eat_keyword(Keyword::Async);
327 let is_unsafe = self.eat_keyword(Keyword::Unsafe);
328 let spine = parse_spine(self)?;
329 let predicates = where_predicates(self)?;
330 self.newline_with_trailing("expected a line break after the signature")?;
331 Ok(SignatureHead {
332 types: spine,
333 bounds,
334 r#given: binder,
335 predicates,
336 is_const,
337 is_async,
338 is_unsafe,
339 })
340 }
341 pub(crate) fn record_head(&mut self, class_name: &str, member: &str, head: &SignatureHead) {
342 let key = (class_name.to_string(), member.to_string());
343 self.class_heads.insert(key, head.clone());
344 ();
345 }
346 pub(crate) fn borrowed_head(&self, class_name: &str, member: &str) -> Option<SignatureHead> {
347 let key = (class_name.to_string(), member.to_string());
348 self.class_heads.get(&key).cloned()
349 }
350 pub(crate) fn equations(
351 &mut self,
352 name: Ident,
353 leading: Vec<Trivia>,
354 start: usize,
355 head: &SignatureHead,
356 reserved: &[String],
357 ends_on_a_new_name: bool,
358 ) -> Result<FnDecl, ParseError> {
359 let spine = &head.types;
360 let bounds = &head.bounds;
361 let mut clauses = Vec::new();
362 let mut sig = None;
363 loop {
364 let is_equation = match &self.peek().kind {
365 TokenKind::Ident(_) => !self.peek_at(1).is_some_and(|t| t.kind == TokenKind::Colon),
366 _ => false,
367 };
368 if !is_equation {
369 break;
370 }
371 if declares_an_operator(self) {
372 break;
373 }
374 let same_name = match &self.peek().kind {
375 TokenKind::Ident(text) if text == &name.text => true,
376 _ => false,
377 };
378 if ends_on_a_new_name && !same_name {
379 break;
380 }
381 let again = self.ident("expected the equation to repeat the name")?;
382 if again.text != name.text {
383 let message = format!(
384 "this equation defines `{}`, but the signature above it is for `{}`",
385 again.text, name.text
386 );
387 return Err(ParseError::r#with(Code::ExpectedName, message, again.span));
388 }
389 let row = patterns(self)?;
390 let built = signature_from(spine, &row, (again.span.0, self.prev_span().1))?;
391 let returns_unit = built.returns_unit();
392 if sig.is_none() {
393 sig = Some(built);
394 }
395 clauses.push(clause(row, &name, returns_unit, self)?);
396 self.skip_separators();
397 }
398 let mut settled =
399 sig.unwrap_or_else(|| signature_only(spine, (name.span.0, self.prev_span().1)));
400 settled.r#given = head.r#given.clone();
401 settled.predicates = head.predicates.clone();
402 generalise(&mut settled, bounds, reserved);
403 settled.is_const = head.is_const;
404 settled.is_async = head.is_async;
405 settled.is_unsafe = head.is_unsafe;
406 let end = self.prev_span().1;
407 let trailing = clauses.last().and_then(|c| c.trailing.clone());
408 Ok(FnDecl {
409 name,
410 sig: settled,
411 clauses,
412 visibility: Visibility::Private,
413 span: (start, end),
414 leading,
415 trailing,
416 })
417 }
418 pub(crate) fn statements(&mut self) -> Result<Block, ParseError> {
419 let start = self.peek_span().0;
420 let mut stmts = Vec::new();
421 loop {
422 self.skip_separators();
423 if self.check(&TokenKind::Dedent) || self.at_eof() {
424 break;
425 }
426 match stmt(self) {
427 Ok(found) => stmts.push(found),
428 Err(e) => {
429 self.r#errors.push(e);
430 self.recover_to_stmt()
431 }
432 };
433 }
434 let end = self.prev_span().1;
435 self.expect(&TokenKind::Dedent, "expected the body to end")?;
436 if stmts.is_empty() && self.r#errors.is_empty() {
437 return Err(ParseError::r#with(
438 Code::EmptyBody,
439 "a declaration body must contain at least one statement",
440 (start, start),
441 ));
442 }
443 Ok(Block {
444 stmts,
445 span: (start, end),
446 })
447 }
448 pub(crate) fn indented_block(&mut self, code: Code, message: &str) -> Result<Block, ParseError> {
449 self.expect_with(code, &TokenKind::Indent, message)?;
450 self.statements()
451 }
452 pub(crate) fn statement_block(&mut self, message: &str) -> Result<Block, ParseError> {
453 self.newline_with_trailing("expected a line break before the body")?;
454 self.indented_block(Code::EmptyBody, message)
455 }
456 pub(crate) fn at_statement_end(&self) -> bool {
457 self.check(&TokenKind::Newline) || self.check(&TokenKind::Dedent) || self.at_eof()
458 }
459 pub(crate) fn if_statement(&mut self) -> Result<Expr, ParseError> {
460 let open = self.peek_span().0;
461 self.expect(&TokenKind::Kw(Keyword::If), "expected `if`")?;
462 let cond = condition(self)?;
463 let then_block = self.statement_block("expected an indented `if` body")?;
464 self.skip_separators();
465 if !self.check(&TokenKind::Kw(Keyword::Else)) {
466 return Ok(Expr::If {
467 condition: cond,
468 then_block,
469 r#otherwise: None,
470 span: (open, self.prev_span().1),
471 });
472 }
473 self.advance();
474 if self.check(&TokenKind::Kw(Keyword::If)) {
475 let start = self.peek_span().0;
476 let nested = self.if_statement()?;
477 let end = self.prev_span().1;
478 let only = Stmt {
479 expr: nested,
480 span: (start, end),
481 leading: Vec::new(),
482 trailing: None,
483 };
484 let chained = Block {
485 stmts: vec![only],
486 span: (start, end),
487 };
488 return Ok(Expr::If {
489 condition: cond,
490 then_block,
491 r#otherwise: Some(chained),
492 span: (open, end),
493 });
494 }
495 let fallback = self.statement_block("expected an indented `else` body")?;
496 Ok(Expr::If {
497 condition: cond,
498 then_block,
499 r#otherwise: Some(fallback),
500 span: (open, self.prev_span().1),
501 })
502 }
503 pub(crate) fn inline_body(&mut self) -> Result<Block, ParseError> {
504 let start = self.peek_span().0;
505 let value = parse_expr(self, 0)?;
506 let end = self.prev_span().1;
507 let only = Stmt {
508 expr: value,
509 span: (start, end),
510 leading: Vec::new(),
511 trailing: None,
512 };
513 Ok(Block {
514 stmts: vec![only],
515 span: (start, end),
516 })
517 }
518 pub(crate) fn opens_a_guard_list(&self) -> bool {
519 self.check(&TokenKind::Newline)
520 && self.peek_at(1).is_some_and(|t| t.kind == TokenKind::Indent)
521 && self.peek_at(2).is_some_and(|t| t.kind == TokenKind::Or)
522 }
523 pub(crate) fn guards(&mut self) -> Result<Vec<Guard>, ParseError> {
524 let mut rows = Vec::new();
525 loop {
526 self.skip_separators();
527 if !self.check(&TokenKind::Or) {
528 break;
529 }
530 let start = self.peek_span().0;
531 self.advance();
532 let cond = if self.check(&TokenKind::Kw(Keyword::Otherwise)) {
533 self.advance();
534 None
535 } else {
536 Some(parse_expr(self, 0)?)
537 };
538 self.expect(&TokenKind::Eq, "expected `=` after a guard's condition")?;
539 let body = self.inline_body()?;
540 self.newline_with_trailing("expected a line break after a guard's body")?;
541 rows.push(Guard {
542 condition: cond,
543 body,
544 span: (start, self.prev_span().1),
545 });
546 }
547 debug_assert!(
548 !rows.is_empty(),
549 "`opens_a_guard_list` guarantees a first `|`"
550 );
551 Ok(rows)
552 }
553 pub(crate) fn try_draw(&mut self) -> Result<Option<Expr>, ParseError> {
554 if !self.check(&TokenKind::Kw(Keyword::With)) {
555 return Ok(None);
556 }
557 let start = self.peek_span().0;
558 self.advance();
559 let name = self.ident("expected a name after `with`")?;
560 self.expect(
561 &TokenKind::Eq,
562 "expected `=` after a `with` binder — doc 30 §3.3",
563 )?;
564 let value = Box::new(parse_expr(self, 0)?);
565 Ok(Some(Expr::Draw {
566 name,
567 value,
568 span: (start, self.prev_span().1),
569 }))
570 }
571 pub(crate) fn try_binding(&mut self) -> Result<Option<Binding>, ParseError> {
572 let is_mut = self.check(&TokenKind::Kw(Keyword::Mut));
573 if !is_mut && !self.looks_like_a_binding() {
574 return Ok(None);
575 }
576 let start = self.peek_span().0;
577 if is_mut {
578 self.advance();
579 }
580 let bound = pattern_alt(self)?;
581 let ty = if self.check(&TokenKind::Colon) {
582 self.advance();
583 Some(self.type_expr("expected a type after `:`")?)
584 } else {
585 None
586 };
587 self.expect(&TokenKind::Eq, "expected `=` in a binding")?;
588 let value = parse_expr(self, 0)?;
589 Ok(Some(Binding {
590 pattern: bound,
591 ty,
592 value,
593 is_mut,
594 span: (start, self.prev_span().1),
595 }))
596 }
597 fn looks_like_a_binding(&self) -> bool {
598 match &self.peek().kind {
599 TokenKind::Ident(_) => {
600 let opener = if let Some(next) = self.peek_at(1) {
601 match next.kind {
602 TokenKind::Eq | TokenKind::Colon | TokenKind::LBrace => true,
603 _ => false,
604 }
605 } else {
606 false
607 };
608 opener && self.reaches_a_binding_eq()
609 }
610 TokenKind::LParen | TokenKind::LBracket => self.reaches_a_binding_eq(),
611 _ => false,
612 }
613 }
614 pub(crate) fn reaches_a_binding_eq(&self) -> bool {
615 let mut depth: i32 = 0;
616 let mut i = 0;
617 while let Some(tok) = self.peek_at(i) {
618 match &tok.kind {
619 TokenKind::Eq if depth == 0 => {
620 return true;
621 }
622 TokenKind::LParen | TokenKind::LBracket | TokenKind::LBrace => depth += 1,
623 TokenKind::RParen | TokenKind::RBracket | TokenKind::RBrace => {
624 depth -= 1;
625 if depth < 0 {
626 return false;
627 }
628 }
629 TokenKind::Newline | TokenKind::Indent | TokenKind::Dedent | TokenKind::Eof => {
630 return false;
631 }
632 _ => (),
633 };
634 i += 1;
635 }
636 false
637 }
638 pub(crate) fn type_expr(&mut self, message: &str) -> Result<TypeExpr, ParseError> {
639 capture_type(self, message, TypeStop::Greedy)
640 }
641
642 pub(crate) fn peek(&self) -> &'a Token {
643 self.toks.get(self.pos).unwrap_or_else(|| {
644 self
645 .toks
646 .last()
647 .expect("the token stream always contains at least Eof")
648 })
649 }
650 pub(crate) fn peek_at(&self, n: usize) -> Option<&'a Token> {
651 self.toks.get(self.pos + n)
652 }
653 pub(crate) fn peek_span(&self) -> Span {
654 self.peek().span
655 }
656 pub(crate) fn peek_leading(&self) -> Vec<Trivia> {
657 self.peek().leading.clone()
658 }
659 pub(crate) fn prev_span(&self) -> Span {
660 if self.pos == 0 {
661 return (0, 0);
662 }
663 self.toks[self.pos - 1].span
664 }
665 pub(crate) fn at_eof(&self) -> bool {
666 match self.peek().kind {
667 TokenKind::Eof => true,
668 _ => false,
669 }
670 }
671 pub(crate) fn check(&self, kind: &TokenKind) -> bool {
672 &self.peek().kind == kind
673 }
674 pub(crate) fn advance(&mut self) {
675 if !self.at_eof() {
676 self.pos += 1;
677 }
678 ();
679 }
680 pub(crate) fn expect(&mut self, kind: &TokenKind, message: &str) -> Result<(), ParseError> {
681 self.expect_with(Code::ExpectedToken, kind, message)
682 }
683 pub(crate) fn expect_with(
684 &mut self,
685 code: Code,
686 kind: &TokenKind,
687 message: &str,
688 ) -> Result<(), ParseError> {
689 if self.check(kind) {
690 self.advance();
691 return Ok(());
692 }
693 Err(ParseError::r#with(code, message, self.peek_span()))
694 }
695 pub(crate) fn eat_keyword(&mut self, kw: Keyword) -> bool {
696 if self.check(&TokenKind::Kw(kw)) {
697 self.advance();
698 return true;
699 }
700 false
701 }
702 pub(crate) fn position(&self) -> usize {
703 self.pos
704 }
705 pub(crate) fn rewind(&mut self, mark: usize) {
706 self.pos = mark;
707 ();
708 }
709 pub(crate) fn try_ident(&mut self) -> Option<Ident> {
710 if let TokenKind::Ident(text) = &self.peek().kind {
711 let found = Ident {
712 text: text.clone(),
713 span: self.peek_span(),
714 };
715 self.advance();
716 return Some(found);
717 }
718 None
719 }
720 pub(crate) fn ident(&mut self, message: &str) -> Result<Ident, ParseError> {
721 if let TokenKind::Ident(text) = &self.peek().kind {
722 let found = Ident {
723 text: text.clone(),
724 span: self.peek_span(),
725 };
726 self.advance();
727 return Ok(found);
728 }
729 Err(ParseError::r#with(
730 Code::ExpectedName,
731 message,
732 self.peek_span(),
733 ))
734 }
735 pub(crate) fn newline_with_trailing(
736 &mut self,
737 message: &str,
738 ) -> Result<Option<Trivia>, ParseError> {
739 if self.check(&TokenKind::Newline) {
740 let trailing = self.peek().trailing.clone();
741 self.advance();
742 return Ok(trailing);
743 }
744 if self.at_eof() || self.check(&TokenKind::Dedent) || self.just_dedented() {
745 return Ok(None);
746 }
747 Err(ParseError::expected(message, self.peek_span()))
748 }
749 pub(crate) fn just_dedented(&self) -> bool {
750 self
751 .pos
752 .checked_sub(1)
753 .and_then(|i| self.toks.get(i))
754 .is_some_and(|t| t.kind == TokenKind::Dedent)
755 }
756 pub(crate) fn skip_separators(&mut self) {
757 while self.check(&TokenKind::Newline) {
758 self.advance();
759 }
760 ();
761 }
762 pub(crate) fn skip_layout(&mut self) {
763 while self.check(&TokenKind::Newline)
764 || self.check(&TokenKind::Indent)
765 || self.check(&TokenKind::Dedent)
766 {
767 self.advance();
768 }
769 ();
770 }
771 fn eof_trivia(&self) -> Vec<Trivia> {
772 let Some(last) = self.toks.last() else {
773 return Vec::new();
774 };
775 let ends = match last.kind {
776 TokenKind::Eof => true,
777 _ => false,
778 };
779 if !ends {
780 return Vec::new();
781 }
782 last.leading.clone()
783 }
784 fn recover_to_item(&mut self) {
785 let mut depth: usize = 0;
786 let mut running = true;
787 while running {
788 match &self.peek().kind {
789 TokenKind::Eof => running = false,
790 TokenKind::Indent => {
791 depth += 1;
792 self.advance()
793 }
794 TokenKind::Dedent => {
795 depth = depth.saturating_sub(1);
796 self.advance()
797 }
798 TokenKind::Ident(_) if depth == 0 => running = false,
799 _ => self.advance(),
800 };
801 }
802 ();
803 }
804 fn recover_to_stmt(&mut self) {
805 let mut depth: usize = 0;
806 let mut running = true;
807 while running {
808 match &self.peek().kind {
809 TokenKind::Eof => running = false,
810 TokenKind::Newline if depth == 0 => {
811 self.advance();
812 running = false;
813 }
814 TokenKind::Dedent if depth == 0 => running = false,
815 TokenKind::Indent => {
816 depth += 1;
817 self.advance()
818 }
819 TokenKind::Dedent => {
820 depth = depth.saturating_sub(1);
821 self.advance()
822 }
823 _ => self.advance(),
824 };
825 }
826 ();
827 }
828}