plotnik_compiler/parser/grammar/
items.rs1use rowan::TextRange;
2
3use crate::diagnostics::DiagnosticKind;
4use crate::parser::Parser;
5use crate::parser::cst::SyntaxKind;
6use crate::parser::cst::token_sets::{EXPR_FIRST_TOKENS, ROOT_EXPR_FIRST_TOKENS};
7use crate::parser::lexer::token_text;
8
9impl Parser<'_, '_> {
10 pub fn parse_root(&mut self) {
11 self.start_node(SyntaxKind::Root);
12
13 while !self.should_stop() && !self.currently_is(SyntaxKind::Error) {
14 if self.currently_is(SyntaxKind::Id) && self.next_is(SyntaxKind::Equals) {
16 self.parse_def();
17 continue;
18 }
19
20 let start = self.current_span().start();
21 self.start_node(SyntaxKind::Def);
22 let success = self.parse_expr_or_error();
23 if !success {
24 self.error_until_next_def();
25 }
26 self.finish_node();
27 if success {
28 let end = self.last_non_trivia_end().unwrap_or(start);
29 let span = TextRange::new(start, end);
30 let def_text = &self.source[usize::from(start)..usize::from(end)];
31 self.diagnostics
32 .report(self.source_id, DiagnosticKind::UnnamedDef, span)
33 .hint(format!("give it a name like `Name = {}`", def_text.trim()))
34 .emit();
35 }
36 }
37
38 self.eat_trivia();
39 self.finish_node();
40 }
41
42 pub(crate) fn error_until_next_def(&mut self) {
43 if self.should_stop() {
44 return;
45 }
46
47 if self.currently_at_def_start() {
49 return;
50 }
51
52 self.start_node(SyntaxKind::Error);
53 while !self.should_stop() && !self.currently_at_def_start() {
54 self.bump();
55 self.skip_trivia_to_buffer();
56 }
57 self.finish_node();
58 }
59
60 pub(crate) fn currently_at_def_start(&mut self) -> bool {
61 if self.currently_is(SyntaxKind::Id) && self.next_is(SyntaxKind::Equals) {
62 return true;
63 }
64 self.currently_is_one_of(ROOT_EXPR_FIRST_TOKENS)
65 }
66
67 fn parse_def(&mut self) {
69 self.start_node(SyntaxKind::Def);
70
71 let span = self.current_span();
72 let name = token_text(self.source, &self.tokens[self.pos]);
73 self.bump();
74 self.validate_def_name(name, span);
75
76 let ate_equals = self.eat_token(SyntaxKind::Equals);
77 assert!(
78 ate_equals,
79 "parse_def: expected '=' but found {:?} (caller should verify Equals is present)",
80 self.current()
81 );
82
83 if self.currently_is_one_of(EXPR_FIRST_TOKENS) {
84 self.parse_expr();
85 } else {
86 self.error(DiagnosticKind::ExpectedExpression);
87 }
88
89 self.finish_node();
90 }
91}