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