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(); if state.at(OCamlSyntaxKind::Rec) {
31 state.bump(); }
33 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(); 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(); 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(); 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(); 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(); if state.at(OCamlSyntaxKind::Semicolon) {
76 state.bump(); }
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}