Skip to main content

oak_matlab/parser/
mod.rs

1use crate::{kind::MatlabSyntaxKind, language::MatlabLanguage, lexer::MatlabLexer};
2use oak_core::{
3    GreenNode, OakError, TextEdit,
4    parser::{ParseCache, ParseOutput, Parser, ParserState},
5    source::Source,
6};
7
8type State<'a, S> = ParserState<'a, MatlabLanguage, S>;
9
10/// MATLAB parser implementation.
11pub struct MatlabParser<'a> {
12    pub(crate) _language: &'a MatlabLanguage,
13}
14
15impl<'a> MatlabParser<'a> {
16    pub fn new(language: &'a MatlabLanguage) -> Self {
17        Self { _language: language }
18    }
19}
20
21impl<'p> Parser<MatlabLanguage> for MatlabParser<'p> {
22    fn parse<'a, S: Source + ?Sized>(&self, text: &'a S, edits: &[TextEdit], cache: &'a mut impl ParseCache<MatlabLanguage>) -> ParseOutput<'a, MatlabLanguage> {
23        let lexer = MatlabLexer::new(self._language);
24        oak_core::parser::parse_with_lexer(&lexer, text, edits, cache, |state| self.parse_root_internal(state))
25    }
26}
27
28impl<'p> MatlabParser<'p> {
29    fn parse_root_internal<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<&'a GreenNode<'a, MatlabLanguage>, OakError> {
30        let cp = state.checkpoint();
31
32        while state.not_at_end() {
33            self.parse_statement(state);
34        }
35
36        Ok(state.finish_at(cp, MatlabSyntaxKind::Script))
37    }
38
39    fn parse_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) {
40        let checkpoint = state.checkpoint();
41
42        match state.peek_kind() {
43            Some(MatlabSyntaxKind::Function) => self.parse_function_def(state),
44            Some(MatlabSyntaxKind::If) => self.parse_if_statement(state),
45            _ => {
46                self.parse_expression(state);
47                if state.at(MatlabSyntaxKind::Semicolon) {
48                    state.bump();
49                }
50            }
51        }
52
53        state.finish_at(checkpoint, MatlabSyntaxKind::Statement);
54    }
55
56    fn parse_function_def<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) {
57        let checkpoint = state.checkpoint();
58        state.bump(); // function
59        // ... simple function parsing logic
60        state.finish_at(checkpoint, MatlabSyntaxKind::FunctionDef);
61    }
62
63    fn parse_if_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) {
64        state.bump(); // if
65        self.parse_expression(state);
66        // ... simple if parsing logic
67    }
68
69    fn parse_expression<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) {
70        let checkpoint = state.checkpoint();
71        state.bump();
72        state.finish_at(checkpoint, MatlabSyntaxKind::Expression);
73    }
74}