skullbrain-parser 0.1.0

Parses skullbrain tokens into a concrete syntax tree (CST).
Documentation
use skullbrain_diagnostics::DiagnosticDetails;

use super::*;

impl<'input, D: Diagnostics, C: ConcreteSyntaxTreeBuilder> ParserState<'input, D, C> {
    pub(super) fn parse_enum_delc(&mut self) {
        self.parse_in_context(ScopeContext::Enum, Self::_parse_enum_delc)
    }

    fn _parse_enum_delc(&mut self) {
        self.start_node(SyntaxKind::Enum);
        self.parse_optional_modifiers();
        self.parse_token(SyntaxKind::Keyword);
        self.parse_name_followed_by_braced_expression(ParseError::expected_enum_name_before());
        self.finish_node();
    }
}

impl<'input, D: Diagnostics, C: ConcreteSyntaxTreeBuilder> ParserState<'input, D, C> {
    pub(super) fn parse_enum_variant(&mut self) {
        self.start_node(SyntaxKind::EnumVariant);
        let mut diagnostic_details = self.diagnostic_details();

        self.parse_token(SyntaxKind::Keyword);
        self.skip_trivia();

        if self.peek().is_some_and(|i| i.kind().is_ident()) {
            self.parse_ident();
        } else {
            self.emit_expected_enum_variant_name();
        }

        if self.peek_sequence(Self::peek_sequence_for_function_parameters) {
            self.parse_function_parameters();
        } else {
            // Assumed in form of <VARIANT> NAME <SEMICOLON> }
        }

        if !self.is_directly_in_ctx(ScopeContext::Enum) {
            diagnostic_details.span.end = self.diagnostic_details().span.start;
            self.emit_enum_variant_invalid_use(diagnostic_details);
        }

        self.finish_node();
    }

    fn emit_enum_variant_invalid_use(&mut self, diagnostic_details: DiagnosticDetails<'_>) {
        let error = ParseError::invalid_use_of_enum_variant();
        self.emit_diagnostic(error, diagnostic_details);
    }

    fn emit_expected_enum_variant_name(&mut self) {
        let diagnostic_details = self.diagnostic_details();
        let error = ParseError::expected_enum_name_before();
        self.emit_diagnostic(error, diagnostic_details);
    }
}

#[cfg(test)]
mod test {
    #[test]
    fn test_enum() {
        crate::test::create_parsing_test("enum/*.skull", |state| {
            state.parse_enum_delc();
        });
    }
}