skullbrain-parser 0.1.0

Parses skullbrain tokens into a concrete syntax tree (CST).
Documentation
use super::*;
impl<'input, D: Diagnostics, C: ConcreteSyntaxTreeBuilder> ParserState<'input, D, C> {
    pub(super) fn parse_match(&mut self) {
        self.start_node(SyntaxKind::Match);
        self.parse_token(SyntaxKind::Keyword);
        self.skip_trivia();
        self.parse_expression_followed_by_braces();
        self.finish_node();
    }

    pub(super) fn parse_match_cond(&mut self) {
        self.start_node(SyntaxKind::MatchCondition);
        self.parse_token(SyntaxKind::Keyword);
        self.skip_trivia();

        let checkpoint = self.checkpoint();
        self.parse_expression();

        self.start_node_at(checkpoint, SyntaxKind::Condition);
        self.finish_node();
        
        self.parse_match_arm_part();
        self.finish_node();
    }

    pub(super) fn parse_match_default_cond(&mut self) {
        self.start_node(SyntaxKind::MatchConditionDefault);
        self.parse_token(SyntaxKind::Keyword);
        self.parse_match_arm_part();
        self.finish_node();
    }
}

impl<'input, D: Diagnostics, C: ConcreteSyntaxTreeBuilder> ParserState<'input, D, C> {
    pub(super) fn parse_match_arm_part(&mut self) {
        self.skip_trivia();

        if self.try_match_arm_possibilites() {
            self.recover();

            if self.try_match_arm_possibilites() {
                self.emit_missing_arrow();
                self.parse_brace_with_expression();
            } else {
            }
        } else {
        }
    }

    fn emit_missing_arrow(&mut self) {
        let diagnostic_details = self.diagnostic_details();
        let error =
            ParseError::expected_token_before(TokenKind::Punctuation(PunctuationKind::Arrow));
        self.emit_diagnostic(error, diagnostic_details);
    }

    fn try_match_arm_possibilites(&mut self) -> bool {
        match self.peek() {
            Some(item) if is_arrow(item.kind()) => {
                self.parse_token(SyntaxKind::Arrow);

                self.parse_brace_with_expression();

                false
            }
            Some(_) => true,
            None => true,
        }
    }
}

fn is_arrow(kind: &TokenKind) -> bool {
    kind.punctuation_ref().is_some_and(|k| k.is_arrow())
}

#[cfg(test)]
mod test {
    #[test]
    fn test_match() {
        crate::test::create_parsing_test("match/*.skull", |state| {
            state.parse_match();
        });
    }
}