1pub mod element_type;
3
4use crate::language::SwiftLanguage;
5use oak_core::{
6 GreenNode, OakError, TextEdit,
7 parser::{
8 ParseCache, ParseOutput, Parser, ParserState, parse_with_lexer,
9 pratt::{Associativity, Pratt, PrattParser, binary, unary},
10 },
11 source::Source,
12};
13
14pub(crate) type State<'a, S> = ParserState<'a, SwiftLanguage, S>;
15
16pub struct SwiftParser<'config> {
18 pub(crate) config: &'config SwiftLanguage,
19}
20
21impl<'config> SwiftParser<'config> {
22 pub fn new(config: &'config SwiftLanguage) -> Self {
24 Self { config }
25 }
26
27 fn parse_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
28 use crate::lexer::SwiftTokenType::*;
29 let kind = state.peek_kind();
30 match kind {
32 Some(Eof) | None => return Ok(()),
33 Some(Func) => self.parse_function_declaration(state)?,
34 Some(Var) | Some(Let) => self.parse_variable_declaration(state)?,
35 Some(If) => self.parse_if_statement(state)?,
36 Some(While) => self.parse_while_statement(state)?,
37 Some(For) => self.parse_for_statement(state)?,
38 Some(Return) => self.parse_return_statement(state)?,
39 Some(LeftBrace) => self.parse_block(state)?,
40 _ => {
41 let cp = state.checkpoint();
42 PrattParser::parse(state, 0, self);
43 state.eat(Semicolon);
44 state.finish_at(cp, crate::parser::element_type::SwiftElementType::ExpressionStatement);
45 }
46 }
47 Ok(())
48 }
49
50 fn parse_function_declaration<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
51 use crate::lexer::SwiftTokenType::*;
52 let cp = state.checkpoint();
53 state.expect(Func).ok();
54 state.expect(Identifier).ok();
55
56 if state.at(LeftParen) {
57 let pcp = state.checkpoint();
58 state.bump(); while state.not_at_end() && !state.at(RightParen) {
60 let ppcp = state.checkpoint();
61 state.expect(Identifier).ok();
62 if state.eat(Colon) {
63 state.expect(Identifier).ok();
64 }
65 state.finish_at(ppcp, crate::parser::element_type::SwiftElementType::Parameter);
66 if state.eat(Comma) {
67 continue;
68 }
69 break;
70 }
71 state.expect(RightParen).ok();
72 state.finish_at(pcp, crate::parser::element_type::SwiftElementType::ParameterList);
73 }
74
75 if state.eat(Arrow) {
76 state.expect(Identifier).ok();
77 }
78
79 self.parse_block(state)?;
80 state.finish_at(cp, crate::parser::element_type::SwiftElementType::FunctionDeclaration);
81 Ok(())
82 }
83
84 fn parse_variable_declaration<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
85 use crate::lexer::SwiftTokenType::*;
86 let cp = state.checkpoint();
87 state.bump(); state.expect(Identifier).ok();
89 if state.eat(Colon) {
90 state.expect(Identifier).ok(); }
92 if state.eat(Assign) {
93 PrattParser::parse(state, 0, self);
94 }
95 state.eat(Semicolon);
96 state.finish_at(cp, crate::parser::element_type::SwiftElementType::VariableDeclaration);
97 Ok(())
98 }
99
100 fn parse_if_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
101 use crate::lexer::SwiftTokenType::*;
102 let cp = state.checkpoint();
103 state.expect(If).ok();
104 PrattParser::parse(state, 0, self);
105 self.parse_block(state)?;
106 if state.eat(Else) {
107 if state.at(If) { self.parse_if_statement(state)? } else { self.parse_block(state)? }
108 }
109 state.finish_at(cp, crate::parser::element_type::SwiftElementType::IfStatement);
110 Ok(())
111 }
112
113 fn parse_while_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
114 use crate::lexer::SwiftTokenType::*;
115 let cp = state.checkpoint();
116 state.expect(While).ok();
117 PrattParser::parse(state, 0, self);
118 self.parse_block(state)?;
119 state.finish_at(cp, crate::parser::element_type::SwiftElementType::WhileStatement);
120 Ok(())
121 }
122
123 fn parse_for_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
124 use crate::lexer::SwiftTokenType::*;
125 let cp = state.checkpoint();
126 state.expect(For).ok();
127 state.expect(Identifier).ok();
128 state.expect(In).ok();
129 PrattParser::parse(state, 0, self);
130 self.parse_block(state)?;
131 state.finish_at(cp, crate::parser::element_type::SwiftElementType::ForStatement);
132 Ok(())
133 }
134
135 fn parse_return_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
136 use crate::lexer::SwiftTokenType::*;
137 let cp = state.checkpoint();
138 state.expect(Return).ok();
139 if state.not_at_end() && !state.at(Semicolon) && !state.at(RightBrace) {
140 PrattParser::parse(state, 0, self);
141 }
142 state.eat(Semicolon);
143 state.finish_at(cp, crate::parser::element_type::SwiftElementType::ReturnStatement);
144 Ok(())
145 }
146
147 fn parse_block<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
148 use crate::lexer::SwiftTokenType::*;
149 let cp = state.checkpoint();
150 state.expect(LeftBrace).ok();
151 while state.not_at_end() && !state.at(RightBrace) {
152 self.parse_statement(state)?;
153 }
154 state.expect(RightBrace).ok();
155 state.finish_at(cp, crate::parser::element_type::SwiftElementType::Block);
156 Ok(())
157 }
158}
159
160impl<'config> Pratt<SwiftLanguage> for SwiftParser<'config> {
161 fn primary<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> &'a GreenNode<'a, SwiftLanguage> {
162 use crate::lexer::SwiftTokenType::*;
163 state.skip_trivia();
164 let cp = state.checkpoint();
165 match state.peek_kind() {
166 Some(Identifier) => {
167 state.bump();
168 state.finish_at(cp, crate::parser::element_type::SwiftElementType::IdentifierExpression)
169 }
170 Some(NumberLiteral) | Some(StringLiteral) | Some(CharLiteral) | Some(BooleanLiteral) | Some(Nil) | Some(True) | Some(False) => {
171 state.bump();
172 state.finish_at(cp, crate::parser::element_type::SwiftElementType::LiteralExpression)
173 }
174 Some(LeftParen) => {
175 state.bump();
176 PrattParser::parse(state, 0, self);
177 state.expect(RightParen).ok();
178 state.finish_at(cp, crate::parser::element_type::SwiftElementType::IdentifierExpression) }
180 _ => {
181 let kind = state.peek_kind();
182 eprintln!("Unsupported primary kind: {:?}", kind);
183 state.bump();
184 state.finish_at(cp, crate::parser::element_type::SwiftElementType::Error)
185 }
186 }
187 }
188
189 fn prefix<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> &'a GreenNode<'a, SwiftLanguage> {
190 use crate::lexer::token_type::SwiftTokenType::*;
191 let kind = match state.peek_kind() {
192 Some(k) => k,
193 None => return self.primary(state),
194 };
195
196 match kind {
197 Plus | Minus | LogicalNot | BitNot => unary(state, kind, 12, UnaryExpression.into(), |s, p| PrattParser::parse(s, p, self)),
198 _ => self.primary(state),
199 }
200 }
201
202 fn infix<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>, left: &'a GreenNode<'a, SwiftLanguage>, min_precedence: u8) -> Option<&'a GreenNode<'a, SwiftLanguage>> {
203 use crate::lexer::token_type::SwiftTokenType::*;
204 let kind = state.peek_kind()?;
205
206 let (prec, assoc) = match kind {
207 Assign | PlusAssign | MinusAssign | StarAssign | SlashAssign | PercentAssign | AndAssign | OrAssign | XorAssign | LeftShiftAssign | RightShiftAssign => (1, Associativity::Right),
208 LogicalOr => (2, Associativity::Left),
209 LogicalAnd => (3, Associativity::Left),
210 Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | As | Is => (5, Associativity::Left),
211 Range | ClosedRange => (6, Associativity::None),
212 Plus | Minus | BitOr | BitXor => (7, Associativity::Left),
213 Star | Slash | Percent | BitAnd | LeftShift | RightShift => (8, Associativity::Left),
214 Dot | QuestionQuestion => (9, Associativity::Left),
215 LeftParen | LeftBracket => (10, Associativity::Left),
216 _ => return None,
217 };
218
219 if prec < min_precedence {
220 return None;
221 }
222
223 match kind {
224 Dot => {
225 let cp = state.checkpoint_before(left);
226 state.bump();
227 state.expect(Identifier).ok();
228 Some(state.finish_at(cp, crate::parser::element_type::SwiftElementType::MemberExpression))
229 }
230 LeftParen => {
231 let cp = state.checkpoint_before(left);
232 state.bump();
233 while state.not_at_end() && !state.at(RightParen) {
234 PrattParser::parse(state, 0, self);
235 if !state.eat(Comma) {
236 break;
237 }
238 }
239 state.expect(RightParen).ok();
240 Some(state.finish_at(cp, crate::parser::element_type::SwiftElementType::CallExpression))
241 }
242 LeftBracket => {
243 let cp = state.checkpoint_before(left);
244 state.bump();
245 PrattParser::parse(state, 0, self);
246 state.expect(RightBracket).ok();
247 Some(state.finish_at(cp, crate::parser::element_type::SwiftElementType::MemberExpression))
248 }
249 _ => Some(binary(state, left, kind, prec, assoc, BinaryExpression.into(), |s, p| PrattParser::parse(s, p, self))),
250 }
251 }
252}
253
254impl<'config> Parser<SwiftLanguage> for SwiftParser<'config> {
255 fn parse<'a, S: Source + ?Sized>(&self, text: &'a S, edits: &[TextEdit], cache: &'a mut impl ParseCache<SwiftLanguage>) -> ParseOutput<'a, SwiftLanguage> {
256 let lexer = crate::lexer::SwiftLexer::new(self.config);
257 parse_with_lexer(&lexer, text, edits, cache, |state| {
258 use crate::lexer::SwiftTokenType::*;
259 let checkpoint = (0, 0);
260
261 while state.not_at_end() && !state.at(Eof) {
262 self.parse_statement(state)?
263 }
264
265 state.eat(Eof);
266
267 Ok(state.finish_at(checkpoint, crate::parser::element_type::SwiftElementType::SourceFile))
268 })
269 }
270}