Skip to main content

oak_matlab/parser/
mod.rs

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