1pub mod element_type;
3
4use crate::{
5 language::FSharpLanguage,
6 lexer::{FSharpLexer, token_type::FSharpTokenType},
7 parser::element_type::FSharpElementType,
8};
9use oak_core::{
10 GreenNode, OakError,
11 parser::{ParseCache, ParseOutput, Parser, ParserState, parse_with_lexer},
12 source::{Source, TextEdit},
13};
14
15pub(crate) type State<'a, S> = ParserState<'a, FSharpLanguage, S>;
16
17pub struct FSharpParser<'config> {
19 pub(crate) config: &'config FSharpLanguage,
20}
21
22impl<'config> FSharpParser<'config> {
23 pub fn new(config: &'config FSharpLanguage) -> Self {
25 Self { config }
26 }
27
28 fn parse_namespace<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
29 let checkpoint = state.checkpoint();
30 state.expect(FSharpTokenType::Namespace)?;
31
32 while state.not_at_end() && state.at(FSharpTokenType::Identifier) {
34 state.bump();
35 if state.at(FSharpTokenType::Dot) { state.bump() } else { break }
36 }
37
38 state.finish_at(checkpoint, FSharpElementType::Namespace);
39 Ok(())
40 }
41
42 fn parse_module<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
43 let checkpoint = state.checkpoint();
44 state.expect(FSharpTokenType::Module)?;
45
46 if state.at(FSharpTokenType::Identifier) {
47 state.bump()
48 }
49
50 state.finish_at(checkpoint, FSharpElementType::Module);
51 Ok(())
52 }
53
54 fn parse_open<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
55 let checkpoint = state.checkpoint();
56 state.expect(FSharpTokenType::Open)?;
57
58 while state.not_at_end() && state.at(FSharpTokenType::Identifier) {
60 state.bump();
61 if state.at(FSharpTokenType::Dot) { state.bump() } else { break }
62 }
63
64 state.finish_at(checkpoint, FSharpElementType::Open);
65 Ok(())
66 }
67
68 fn parse_binding<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
69 let checkpoint = state.checkpoint();
70 state.expect(FSharpTokenType::Let)?;
71
72 if state.eat(FSharpTokenType::Rec) {
73 }
75
76 state.expect(FSharpTokenType::Identifier)?;
78
79 while state.not_at_end() && state.at(FSharpTokenType::Identifier) {
81 state.bump()
82 }
83
84 state.expect(FSharpTokenType::Equal)?;
86
87 self.parse_expression(state)?;
89
90 state.finish_at(checkpoint, FSharpElementType::Let);
91 Ok(())
92 }
93
94 fn parse_expression<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
95 let checkpoint = state.checkpoint();
96 let kind = state.peek_kind();
97 match kind {
98 Some(FSharpTokenType::If) => {
99 state.expect(FSharpTokenType::If)?;
100 self.parse_expression(state)?;
101 state.expect(FSharpTokenType::Then)?;
102 self.parse_expression(state)?;
103 if state.eat(FSharpTokenType::Else) {
104 self.parse_expression(state)?
105 }
106 state.finish_at(checkpoint, FSharpElementType::If);
107 }
108 Some(FSharpTokenType::Match) => {
109 self.parse_match_expression(state, checkpoint)?;
110 }
111 Some(FSharpTokenType::Let) => {
112 self.parse_let_expression(state, checkpoint)?;
113 }
114 Some(FSharpTokenType::Fun) => {
115 self.parse_lambda_expression(state, checkpoint)?;
116 }
117 Some(FSharpTokenType::Function) => {
118 self.parse_function_expression(state, checkpoint)?;
119 }
120 Some(FSharpTokenType::Open) => {
121 self.parse_open(state)?;
122 }
123 Some(FSharpTokenType::LeftParen) => {
124 self.parse_parenthesized_expression(state, checkpoint)?;
125 }
126 Some(FSharpTokenType::LeftBracket) => {
127 self.parse_list_or_array_expression(state, checkpoint)?;
128 }
129 Some(FSharpTokenType::LeftBrace) => {
130 self.parse_record_expression(state, checkpoint)?;
131 }
132 Some(FSharpTokenType::Identifier) => {
133 self.parse_identifier_expression(state, checkpoint)?;
134 }
135 Some(FSharpTokenType::IntegerLiteral) | Some(FSharpTokenType::FloatLiteral) | Some(FSharpTokenType::StringLiteral) | Some(FSharpTokenType::CharLiteral) => {
136 self.parse_literal_expression(state, checkpoint)?;
137 }
138 _ => {
139 while state.not_at_end() {
141 let kind = state.peek_kind();
142 if matches!(kind, Some(FSharpTokenType::Newline | FSharpTokenType::Then | FSharpTokenType::Else | FSharpTokenType::In | FSharpTokenType::PipeRight | FSharpTokenType::PipeGreater)) {
143 break;
144 }
145 state.bump()
146 }
147 if state.checkpoint().0 == checkpoint.0 {
149 state.bump()
150 }
151 state.finish_at(checkpoint, FSharpElementType::Expression);
152 }
153 }
154 Ok(())
155 }
156
157 fn parse_function_expression<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>, checkpoint: (usize, usize)) -> Result<(), OakError> {
158 state.expect(FSharpTokenType::Function)?;
159
160 while state.not_at_end() && state.at(FSharpTokenType::Identifier) {
162 state.bump();
163 if state.eat(FSharpTokenType::Colon) {
165 self.parse_type(state)?;
166 }
167 }
168
169 while state.not_at_end() && !state.at(FSharpTokenType::End) {
171 self.parse_match_case(state)?;
172 }
173
174 state.eat(FSharpTokenType::End);
175 state.finish_at(checkpoint, FSharpElementType::Function);
176 Ok(())
177 }
178
179 fn parse_match_expression<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>, checkpoint: (usize, usize)) -> Result<(), OakError> {
180 state.expect(FSharpTokenType::Match)?;
181 self.parse_expression(state)?;
182 state.expect(FSharpTokenType::With)?;
183
184 while state.not_at_end() && !state.at(FSharpTokenType::End) {
185 self.parse_match_case(state)?;
186 }
187
188 state.eat(FSharpTokenType::End);
189 state.finish_at(checkpoint, FSharpElementType::Match);
190 Ok(())
191 }
192
193 fn parse_match_case<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
194 let checkpoint = state.checkpoint();
195
196 self.parse_pattern(state)?;
198
199 if state.eat(FSharpTokenType::When) {
201 self.parse_expression(state)?;
202 }
203
204 state.expect(FSharpTokenType::Arrow)?;
205 self.parse_expression(state)?;
206
207 state.finish_at(checkpoint, FSharpElementType::MatchCase);
208 Ok(())
209 }
210
211 fn parse_pattern<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
212 let checkpoint = state.checkpoint();
213 let kind = state.peek_kind();
214
215 match kind {
216 Some(FSharpTokenType::Underscore) => {
217 state.bump();
218 state.finish_at(checkpoint, FSharpElementType::WildcardPattern);
219 }
220 Some(FSharpTokenType::Identifier) => {
221 state.bump();
222 if state.at(FSharpTokenType::LeftParen) {
224 state.bump();
225 while state.not_at_end() && !state.at(FSharpTokenType::RightParen) {
227 self.parse_expression(state)?;
228 if state.at(FSharpTokenType::Comma) {
229 state.bump();
230 }
231 }
232 state.expect(FSharpTokenType::RightParen)?;
233 state.finish_at(checkpoint, FSharpElementType::ActivePattern);
234 }
235 else if state.at(FSharpTokenType::Pipe) {
236 state.bump();
238 if state.at(FSharpTokenType::Identifier) {
239 state.bump();
240 }
241 state.finish_at(checkpoint, FSharpElementType::ActivePattern);
242 }
243 else {
244 state.finish_at(checkpoint, FSharpElementType::IdentifierPattern);
245 }
246 }
247 Some(FSharpTokenType::LeftParen) => {
248 state.bump();
249 while state.not_at_end() && !state.at(FSharpTokenType::RightParen) {
250 self.parse_pattern(state)?;
251 if state.at(FSharpTokenType::Comma) {
252 state.bump();
253 }
254 }
255 state.expect(FSharpTokenType::RightParen)?;
256 state.finish_at(checkpoint, FSharpElementType::TuplePattern);
257 }
258 Some(FSharpTokenType::LeftBracket) => {
259 state.bump();
260 while state.not_at_end() && !state.at(FSharpTokenType::RightBracket) {
261 self.parse_pattern(state)?;
262 if state.at(FSharpTokenType::Comma) {
263 state.bump();
264 }
265 }
266 state.expect(FSharpTokenType::RightBracket)?;
267 state.finish_at(checkpoint, FSharpElementType::ListPattern);
268 }
269 Some(FSharpTokenType::Pipe) => {
270 state.bump();
272 if state.at(FSharpTokenType::Identifier) {
273 state.bump();
274 }
275 state.finish_at(checkpoint, FSharpElementType::ActivePattern);
276 }
277 _ => {
278 state.bump();
279 state.finish_at(checkpoint, FSharpElementType::Pattern);
280 }
281 }
282 Ok(())
283 }
284
285 fn parse_let_expression<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>, checkpoint: (usize, usize)) -> Result<(), OakError> {
286 state.expect(FSharpTokenType::Let)?;
287
288 let is_rec = state.eat(FSharpTokenType::Rec);
289
290 state.expect(FSharpTokenType::Identifier)?;
292
293 while state.not_at_end() && state.at(FSharpTokenType::Identifier) {
295 state.bump();
296 }
297
298 if state.eat(FSharpTokenType::Colon) {
300 self.parse_type(state)?;
301 }
302
303 state.expect(FSharpTokenType::Equal)?;
304 self.parse_expression(state)?;
305
306 if state.eat(FSharpTokenType::In) {
307 self.parse_expression(state)?;
308 }
309
310 state.finish_at(checkpoint, FSharpElementType::Let);
311 Ok(())
312 }
313
314 fn parse_lambda_expression<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>, checkpoint: (usize, usize)) -> Result<(), OakError> {
315 state.expect(FSharpTokenType::Fun)?;
316
317 while state.not_at_end() && state.at(FSharpTokenType::Identifier) {
319 state.bump();
320 }
321
322 state.expect(FSharpTokenType::Arrow)?;
323 self.parse_expression(state)?;
324
325 state.finish_at(checkpoint, FSharpElementType::Lambda);
326 Ok(())
327 }
328
329 fn parse_parenthesized_expression<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>, checkpoint: (usize, usize)) -> Result<(), OakError> {
330 state.bump(); self.parse_expression(state)?;
332 state.expect(FSharpTokenType::RightParen)?;
333 state.finish_at(checkpoint, FSharpElementType::Parenthesized);
334 Ok(())
335 }
336
337 fn parse_list_or_array_expression<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>, checkpoint: (usize, usize)) -> Result<(), OakError> {
338 state.bump(); while state.not_at_end() && !state.at(FSharpTokenType::RightBracket) {
341 self.parse_expression(state)?;
342 if state.at(FSharpTokenType::Comma) {
343 state.bump();
344 }
345 }
346
347 state.expect(FSharpTokenType::RightBracket)?;
348 state.finish_at(checkpoint, FSharpElementType::List);
349 Ok(())
350 }
351
352 fn parse_record_expression<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>, checkpoint: (usize, usize)) -> Result<(), OakError> {
353 state.bump(); while state.not_at_end() && !state.at(FSharpTokenType::RightBrace) {
356 state.expect(FSharpTokenType::Identifier)?;
357 state.expect(FSharpTokenType::Equal)?;
358 self.parse_expression(state)?;
359 if state.at(FSharpTokenType::Comma) {
360 state.bump();
361 }
362 }
363
364 state.expect(FSharpTokenType::RightBrace)?;
365 state.finish_at(checkpoint, FSharpElementType::Record);
366 Ok(())
367 }
368
369 fn parse_identifier_expression<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>, checkpoint: (usize, usize)) -> Result<(), OakError> {
370 state.bump(); if state.not_at_end() && !matches!(state.peek_kind(), Some(FSharpTokenType::Newline | FSharpTokenType::Then | FSharpTokenType::Else | FSharpTokenType::In | FSharpTokenType::PipeRight | FSharpTokenType::PipeGreater)) {
374 self.parse_expression(state)?;
375 state.finish_at(checkpoint, FSharpElementType::Application);
376 }
377 else {
378 state.finish_at(checkpoint, FSharpElementType::Identifier);
379 }
380 Ok(())
381 }
382
383 fn parse_literal_expression<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>, checkpoint: (usize, usize)) -> Result<(), OakError> {
384 state.bump(); state.finish_at(checkpoint, FSharpElementType::Literal);
386 Ok(())
387 }
388
389 fn parse_type<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
390 while state.not_at_end() && !matches!(state.peek_kind(), Some(FSharpTokenType::Equal | FSharpTokenType::Newline)) {
392 state.bump();
393 }
394 Ok(())
395 }
396}
397
398impl<'config> Parser<FSharpLanguage> for FSharpParser<'config> {
399 fn parse<'a, S: Source + ?Sized>(&self, text: &'a S, edits: &[TextEdit], cache: &'a mut impl ParseCache<FSharpLanguage>) -> ParseOutput<'a, FSharpLanguage> {
400 let lexer = FSharpLexer::new(self.config);
401 parse_with_lexer(&lexer, text, edits, cache, |state| {
402 let cp = (0, 0); while state.not_at_end() {
404 let kind = state.peek_kind();
405 match kind {
406 Some(FSharpTokenType::Namespace) => self.parse_namespace(state)?,
407 Some(FSharpTokenType::Module) => self.parse_module(state)?,
408 Some(FSharpTokenType::Open) => self.parse_open(state)?,
409 Some(FSharpTokenType::Let) => self.parse_binding(state)?,
410 _ => state.bump(),
411 }
412 }
413
414 Ok(state.finish_at(cp, FSharpElementType::Root))
415 })
416 }
417}