1pub mod element_type;
3
4use crate::{
5 language::MatlabLanguage,
6 lexer::{MatlabLexer, token_type::MatlabTokenType},
7 parser::element_type::MatlabElementType,
8};
9use oak_core::{
10 GreenNode, OakError, TextEdit,
11 parser::{ParseCache, ParseOutput, Parser, ParserState},
12 source::Source,
13};
14
15pub(crate) type State<'a, S> = ParserState<'a, MatlabLanguage, S>;
16
17pub struct MatlabParser<'a> {
19 pub(crate) _language: &'a MatlabLanguage,
20}
21
22impl<'a> MatlabParser<'a> {
23 pub fn new(language: &'a MatlabLanguage) -> Self {
25 Self { _language: language }
26 }
27}
28
29impl<'p> Parser<MatlabLanguage> for MatlabParser<'p> {
30 fn parse<'a, S: Source + ?Sized>(&self, text: &'a S, edits: &[TextEdit], cache: &'a mut impl ParseCache<MatlabLanguage>) -> ParseOutput<'a, MatlabLanguage> {
31 let lexer = MatlabLexer::new(self._language);
32 oak_core::parser::parse_with_lexer(&lexer, text, edits, cache, |state| {
33 let cp = state.checkpoint();
34
35 while state.not_at_end() {
36 self.parse_statement(state)
37 }
38
39 Ok(state.finish_at(cp, MatlabElementType::Script))
40 })
41 }
42}
43
44impl<'p> MatlabParser<'p> {
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(); 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(); self.parse_expression(state);
72 }
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}