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
10pub 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(); 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(); self.parse_expression(state);
66 }
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}