Skip to main content

oak_powershell/parser/
mod.rs

1use crate::{kind::PowerShellSyntaxKind, language::PowerShellLanguage};
2use oak_core::{
3    parser::{ParseCache, ParseOutput, Parser, ParserState, parse_with_lexer},
4    source::{Source, TextEdit},
5};
6pub struct PowerShellParser<'a> {
7    _config: &'a PowerShellLanguage,
8}
9
10impl<'a> PowerShellParser<'a> {
11    pub fn new(config: &'a PowerShellLanguage) -> Self {
12        Self { _config: config }
13    }
14
15    fn parse_program<'b, S: Source + ?Sized>(&self, state: &mut ParserState<'b, PowerShellLanguage, S>) {
16        while state.not_at_end() {
17            if state.at(PowerShellSyntaxKind::Function) {
18                self.parse_function(state);
19            }
20            else if state.at(PowerShellSyntaxKind::Class) {
21                self.parse_class(state);
22            }
23            else if state.at(PowerShellSyntaxKind::If) {
24                self.parse_if(state);
25            }
26            else {
27                self.parse_statement(state);
28            }
29        }
30    }
31
32    fn parse_function<'b, S: Source + ?Sized>(&self, state: &mut ParserState<'b, PowerShellLanguage, S>) {
33        let checkpoint = state.checkpoint();
34        state.expect(PowerShellSyntaxKind::Function).ok();
35        state.expect(PowerShellSyntaxKind::Identifier).ok();
36        if state.at(PowerShellSyntaxKind::LeftBrace) {
37            self.parse_block(state);
38        }
39        state.finish_at(checkpoint, PowerShellSyntaxKind::FunctionDef);
40    }
41
42    fn parse_class<'b, S: Source + ?Sized>(&self, state: &mut ParserState<'b, PowerShellLanguage, S>) {
43        let checkpoint = state.checkpoint();
44        state.expect(PowerShellSyntaxKind::Class).ok();
45        state.expect(PowerShellSyntaxKind::Identifier).ok();
46        if state.at(PowerShellSyntaxKind::LeftBrace) {
47            self.parse_block(state);
48        }
49        state.finish_at(checkpoint, PowerShellSyntaxKind::ClassDef);
50    }
51
52    fn parse_if<'b, S: Source + ?Sized>(&self, state: &mut ParserState<'b, PowerShellLanguage, S>) {
53        let checkpoint = state.checkpoint();
54        state.expect(PowerShellSyntaxKind::If).ok();
55        state.expect(PowerShellSyntaxKind::LeftParen).ok();
56        while !state.at(PowerShellSyntaxKind::RightParen) && state.not_at_end() {
57            state.bump();
58        }
59        state.expect(PowerShellSyntaxKind::RightParen).ok();
60        self.parse_block(state);
61        state.finish_at(checkpoint, PowerShellSyntaxKind::IfStatement);
62    }
63
64    fn parse_block<'b, S: Source + ?Sized>(&self, state: &mut ParserState<'b, PowerShellLanguage, S>) {
65        state.expect(PowerShellSyntaxKind::LeftBrace).ok();
66        while !state.at(PowerShellSyntaxKind::RightBrace) && state.not_at_end() {
67            self.parse_statement(state);
68        }
69        state.expect(PowerShellSyntaxKind::RightBrace).ok();
70    }
71
72    fn parse_statement<'b, S: Source + ?Sized>(&self, state: &mut ParserState<'b, PowerShellLanguage, S>) {
73        let checkpoint = state.checkpoint();
74        while !state.at(PowerShellSyntaxKind::Semicolon) && !state.at(PowerShellSyntaxKind::Newline) && state.not_at_end() {
75            state.bump();
76        }
77        if state.at(PowerShellSyntaxKind::Semicolon) || state.at(PowerShellSyntaxKind::Newline) {
78            state.bump();
79        }
80        state.finish_at(checkpoint, PowerShellSyntaxKind::ExpressionStatement);
81    }
82}
83
84impl<'a> Parser<PowerShellLanguage> for PowerShellParser<'a> {
85    fn parse<'b, S: Source + ?Sized>(&self, text: &'b S, edits: &[TextEdit], cache: &'b mut impl ParseCache<PowerShellLanguage>) -> ParseOutput<'b, PowerShellLanguage> {
86        let lexer = crate::lexer::PowerShellLexer::new(self._config);
87        parse_with_lexer(&lexer, text, edits, cache, |state| {
88            let checkpoint = state.checkpoint();
89            self.parse_program(state);
90            Ok(state.finish_at(checkpoint, PowerShellSyntaxKind::Root))
91        })
92    }
93}