oak_powershell/parser/
mod.rs1use 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}