Skip to main content

oak_ocaml/parser/
mod.rs

1use crate::{kind::OCamlSyntaxKind, language::OCamlLanguage, lexer::OCamlLexer};
2use oak_core::{
3    GreenNode, OakError,
4    parser::{ParseCache, ParseOutput, Parser, ParserState},
5    source::{Source, TextEdit},
6};
7
8pub struct OCamlParser<'config> {
9    pub language: &'config OCamlLanguage,
10}
11
12impl<'config> OCamlParser<'config> {
13    pub fn new(language: &'config OCamlLanguage) -> Self {
14        Self { language }
15    }
16
17    fn parse_item<'s, S: Source + ?Sized>(&self, state: &mut ParserState<'s, OCamlLanguage, S>) {
18        let kind = state.peek_kind();
19        match kind {
20            Some(OCamlSyntaxKind::Let) => self.parse_let_binding(state),
21            Some(OCamlSyntaxKind::Module) => self.parse_module_def(state),
22            Some(OCamlSyntaxKind::Type) => self.parse_type_definition(state),
23            _ => self.parse_expression(state),
24        }
25    }
26
27    fn parse_let_binding<'s, S: Source + ?Sized>(&self, state: &mut ParserState<'s, OCamlLanguage, S>) {
28        let checkpoint = state.checkpoint();
29        state.bump(); // Let
30        if state.at(OCamlSyntaxKind::Rec) {
31            state.bump(); // Rec
32        }
33        // Simplified: consume identifier and until = or ;;
34        while state.not_at_end() && !state.at(OCamlSyntaxKind::Equal) && !state.at(OCamlSyntaxKind::Semicolon) {
35            state.bump();
36        }
37        if state.at(OCamlSyntaxKind::Equal) {
38            state.bump(); // Equal
39            self.parse_expression(state);
40        }
41        state.finish_at(checkpoint, OCamlSyntaxKind::LetBinding.into());
42    }
43
44    fn parse_module_def<'s, S: Source + ?Sized>(&self, state: &mut ParserState<'s, OCamlLanguage, S>) {
45        let checkpoint = state.checkpoint();
46        state.bump(); // Module
47        while state.not_at_end() && !state.at(OCamlSyntaxKind::Equal) && !state.at(OCamlSyntaxKind::Semicolon) {
48            state.bump();
49        }
50        if state.at(OCamlSyntaxKind::Equal) {
51            state.bump(); // Equal
52            while state.not_at_end() && !state.at(OCamlSyntaxKind::Semicolon) {
53                state.bump();
54            }
55        }
56        state.finish_at(checkpoint, OCamlSyntaxKind::ModuleDef.into());
57    }
58
59    fn parse_type_definition<'s, S: Source + ?Sized>(&self, state: &mut ParserState<'s, OCamlLanguage, S>) {
60        let checkpoint = state.checkpoint();
61        state.bump(); // Type
62        while state.not_at_end() && !state.at(OCamlSyntaxKind::Semicolon) {
63            state.bump();
64        }
65        state.finish_at(checkpoint, OCamlSyntaxKind::TypeDefinition.into());
66    }
67
68    fn parse_expression<'s, S: Source + ?Sized>(&self, state: &mut ParserState<'s, OCamlLanguage, S>) {
69        let checkpoint = state.checkpoint();
70        while state.not_at_end() && !state.at(OCamlSyntaxKind::Semicolon) {
71            state.bump();
72        }
73        if state.at(OCamlSyntaxKind::Semicolon) {
74            state.bump(); // Semicolon
75            if state.at(OCamlSyntaxKind::Semicolon) {
76                state.bump(); // Semicolon
77            }
78        }
79        state.finish_at(checkpoint, OCamlSyntaxKind::Expression.into());
80    }
81
82    fn parse_root_internal<'s, S: Source + ?Sized>(&self, state: &mut ParserState<'s, OCamlLanguage, S>) -> Result<&'s GreenNode<'s, OCamlLanguage>, OakError> {
83        let checkpoint = state.checkpoint();
84
85        while state.not_at_end() {
86            self.parse_item(state);
87        }
88
89        Ok(state.finish_at(checkpoint, OCamlSyntaxKind::Root.into()))
90    }
91}
92
93impl<'config> Parser<OCamlLanguage> for OCamlParser<'config> {
94    fn parse<'s, S: Source + ?Sized>(&self, text: &'s S, edits: &[TextEdit], cache: &'s mut impl ParseCache<OCamlLanguage>) -> ParseOutput<'s, OCamlLanguage> {
95        let lexer = OCamlLexer::new(self.language);
96        oak_core::parser::parse_with_lexer(&lexer, text, edits, cache, |state| self.parse_root_internal(state))
97    }
98}