1 #include "Enumeration.hpp"
2 #include <soulng/util/Unicode.hpp>
3 #include <sngcm/cmparser/Specifier.hpp>
4 #include <sngcm/cmparser/Identifier.hpp>
5 #include <sngcm/cmparser/TypeExpr.hpp>
6 #include <sngcm/cmparser/Expression.hpp>
7 #include <sngcm/cmlexer/CmajorLexer.hpp>
8 #include <sngcm/cmlexer/CmajorTokens.hpp>
9
10
11
12 using namespace soulng::unicode;
13 using namespace sngcm::ast;
14 using namespace CmajorTokens;
15
16 soulng::parser::Match EnumerationParser::EnumType(CmajorLexer& lexer, ParsingContext* ctx)
17 {
18 #ifdef SOULNG_PARSER_DEBUG_SUPPORT
19
20
21
22
23
24
25
26 #endif // SOULNG_PARSER_DEBUG_SUPPORT
27 std::unique_ptr<EnumTypeNode> enumTypeNode = std::unique_ptr<EnumTypeNode>();
28 Span s = Span();
29 Span beginBraceSpan = Span();
30 Span endBraceSpan = Span();
31 std::unique_ptr<soulng::parser::soulng::parser::Value<sngcm::ast::Specifiers>>specifiers;
32 std::unique_ptr<IdentifierNode> enumTypeId;
33 std::unique_ptr<Node> underlyingType;
34 soulng::parser::Match match(false);
35 soulng::parser::Match* parentMatch0 = &match;
36 {
37 soulng::parser::Match match(false);
38 soulng::parser::Match* parentMatch1 = &match;
39 {
40 soulng::parser::Match match(false);
41 soulng::parser::Match* parentMatch2 = &match;
42 {
43 soulng::parser::Match match(false);
44 soulng::parser::Match* parentMatch3 = &match;
45 {
46 soulng::parser::Match match(false);
47 soulng::parser::Match* parentMatch4 = &match;
48 {
49 soulng::parser::Match match(false);
50 soulng::parser::Match* parentMatch5 = &match;
51 {
52 soulng::parser::Match match(false);
53 soulng::parser::Match* parentMatch6 = &match;
54 {
55 int64_t pos = lexer.GetPos();
56 soulng::lexer::Span span = lexer.GetSpan();
57 soulng::parser::Match match = SpecifierParser::Specifiers(lexer);
58 specifiers.reset(static_cast<soulng::parser::soulng::parser::Value<sngcm::ast::Specifiers>*>(match.value));
59 if (match.hit)
60 {
61 s = span;
62 }
63 *parentMatch6 = match;
64 }
65 *parentMatch5 = match;
66 }
67 if (match.hit)
68 {
69 soulng::parser::Match match(false);
70 soulng::parser::Match* parentMatch7 = &match;
71 {
72 soulng::parser::Match match(false);
73 if (*lexer == ENUM)
74 {
75 ++lexer;
76 match.hit = true;
77 }
78 *parentMatch7 = match;
79 }
80 *parentMatch5 = match;
81 }
82 *parentMatch4 = match;
83 }
84 if (match.hit)
85 {
86 soulng::parser::Match match(false);
87 soulng::parser::Match* parentMatch8 = &match;
88 {
89 soulng::parser::Match match(false);
90 soulng::parser::Match* parentMatch9 = &match;
91 {
92 int64_t pos = lexer.GetPos();
93 soulng::lexer::Span span = lexer.GetSpan();
94 soulng::parser::Match match(true);
95 soulng::parser::Match* parentMatch10 = &match;
96 {
97 soulng::lexer::Span span = lexer.GetSpan();
98 soulng::parser::Match match = IdentifierParser::Identifier(lexer);
99 enumTypeId.reset(static_cast<IdentifierNode*>(match.value));
100 if (match.hit)
101 {
102 *parentMatch10 = match;
103 }
104 else
105 {
106 lexer.ThrowExpectationFailure(span, U"identifier");
107 }
108 }
109 if (match.hit)
110 {
111 s.end = span.end;
112 enumTypeNode.reset(new EnumTypeNode(s, specifiers->value, enumTypeId.release()));
113 }
114 *parentMatch9 = match;
115 }
116 *parentMatch8 = match;
117 }
118 *parentMatch4 = match;
119 }
120 *parentMatch3 = match;
121 }
122 if (match.hit)
123 {
124 soulng::parser::Match match(false);
125 soulng::parser::Match* parentMatch11 = &match;
126 {
127 soulng::parser::Match match(true);
128 int64_t save = lexer.GetPos();
129 soulng::parser::Match* parentMatch12 = &match;
130 {
131 soulng::parser::Match match(false);
132 soulng::parser::Match* parentMatch13 = &match;
133 {
134 soulng::parser::Match match(false);
135 soulng::parser::Match* parentMatch14 = &match;
136 {
137 int64_t pos = lexer.GetPos();
138 soulng::parser::Match match = EnumerationParser::UnderlyingType(lexer, ctx);
139 underlyingType.reset(static_cast<Node*>(match.value));
140 if (match.hit)
141 {
142 enumTypeNode->SetUnderlyingType(underlyingType.release());
143 }
144 *parentMatch14 = match;
145 }
146 *parentMatch13 = match;
147 }
148 if (match.hit)
149 {
150 *parentMatch12 = match;
151 }
152 else
153 {
154 lexer.SetPos(save);
155 }
156 }
157 *parentMatch11 = match;
158 }
159 *parentMatch3 = match;
160 }
161 *parentMatch2 = match;
162 }
163 if (match.hit)
164 {
165 soulng::parser::Match match(false);
166 soulng::parser::Match* parentMatch15 = &match;
167 {
168 soulng::parser::Match match(false);
169 soulng::parser::Match* parentMatch16 = &match;
170 {
171 int64_t pos = lexer.GetPos();
172 soulng::lexer::Span span = lexer.GetSpan();
173 soulng::parser::Match match(true);
174 soulng::parser::Match* parentMatch17 = &match;
175 {
176 soulng::lexer::Span span = lexer.GetSpan();
177 soulng::parser::Match match(false);
178 if (*lexer == LBRACE)
179 {
180 ++lexer;
181 match.hit = true;
182 }
183 if (match.hit)
184 {
185 *parentMatch17 = match;
186 }
187 else
188 {
189 lexer.ThrowExpectationFailure(span, ToUtf32(GetTokenInfo(LBRACE)));
190 }
191 }
192 if (match.hit)
193 {
194 beginBraceSpan = span;
195 }
196 *parentMatch16 = match;
197 }
198 *parentMatch15 = match;
199 }
200 *parentMatch2 = match;
201 }
202 *parentMatch1 = match;
203 }
204 if (match.hit)
205 {
206 soulng::parser::Match match(false);
207 soulng::parser::Match* parentMatch18 = &match;
208 {
209 soulng::parser::Match match = EnumerationParser::EnumConstants(lexer, ctx, enumTypeNode.get());
210 *parentMatch18 = match;
211 }
212 *parentMatch1 = match;
213 }
214 *parentMatch0 = match;
215 }
216 if (match.hit)
217 {
218 soulng::parser::Match match(false);
219 soulng::parser::Match* parentMatch19 = &match;
220 {
221 soulng::parser::Match match(false);
222 soulng::parser::Match* parentMatch20 = &match;
223 {
224 int64_t pos = lexer.GetPos();
225 soulng::lexer::Span span = lexer.GetSpan();
226 soulng::parser::Match match(true);
227 soulng::parser::Match* parentMatch21 = &match;
228 {
229 soulng::lexer::Span span = lexer.GetSpan();
230 soulng::parser::Match match(false);
231 if (*lexer == RBRACE)
232 {
233 ++lexer;
234 match.hit = true;
235 }
236 if (match.hit)
237 {
238 *parentMatch21 = match;
239 }
240 else
241 {
242 lexer.ThrowExpectationFailure(span, ToUtf32(GetTokenInfo(RBRACE)));
243 }
244 }
245 if (match.hit)
246 {
247 endBraceSpan = span;
248 enumTypeNode->SetBeginBraceSpan(beginBraceSpan);
249 enumTypeNode->SetEndBraceSpan(endBraceSpan);
250 {
251 #ifdef SOULNG_PARSER_DEBUG_SUPPORT
252
253 #endif // SOULNG_PARSER_DEBUG_SUPPORT
254 return soulng::parser::Match(true, enumTypeNode.release());
255 }
256 }
257 *parentMatch20 = match;
258 }
259 *parentMatch19 = match;
260 }
261 *parentMatch0 = match;
262 }
263 #ifdef SOULNG_PARSER_DEBUG_SUPPORT
264
265
266
267
268
269 #endif // SOULNG_PARSER_DEBUG_SUPPORT
270 if (!match.hit)
271 {
272 match.value = nullptr;
273 }
274 return match;
275 }
276
277 soulng::parser::Match EnumerationParser::UnderlyingType(CmajorLexer& lexer, ParsingContext* ctx)
278 {
279 #ifdef SOULNG_PARSER_DEBUG_SUPPORT
280
281
282
283
284
285
286
287 #endif // SOULNG_PARSER_DEBUG_SUPPORT
288 std::unique_ptr<sngcm::ast::Node> type;
289 soulng::parser::Match match(false);
290 soulng::parser::Match* parentMatch0 = &match;
291 {
292 soulng::parser::Match match(false);
293 if (*lexer == COLON)
294 {
295 ++lexer;
296 match.hit = true;
297 }
298 *parentMatch0 = match;
299 }
300 if (match.hit)
301 {
302 soulng::parser::Match match(false);
303 soulng::parser::Match* parentMatch1 = &match;
304 {
305 soulng::parser::Match match(false);
306 soulng::parser::Match* parentMatch2 = &match;
307 {
308 int64_t pos = lexer.GetPos();
309 soulng::parser::Match match = TypeExprParser::TypeExpr(lexer, ctx);
310 type.reset(static_cast<sngcm::ast::Node*>(match.value));
311 if (match.hit)
312 {
313 {
314 #ifdef SOULNG_PARSER_DEBUG_SUPPORT
315
316 #endif // SOULNG_PARSER_DEBUG_SUPPORT
317 return soulng::parser::Match(true, type.release());
318 }
319 }
320 *parentMatch2 = match;
321 }
322 *parentMatch1 = match;
323 }
324 *parentMatch0 = match;
325 }
326 #ifdef SOULNG_PARSER_DEBUG_SUPPORT
327
328
329
330
331
332 #endif // SOULNG_PARSER_DEBUG_SUPPORT
333 if (!match.hit)
334 {
335 match.value = nullptr;
336 }
337 return match;
338 }
339
340 soulng::parser::Match EnumerationParser::EnumConstants(CmajorLexer& lexer, ParsingContext* ctx, sngcm::ast::EnumTypeNode* enumType)
341 {
342 #ifdef SOULNG_PARSER_DEBUG_SUPPORT
343
344
345
346
347
348
349
350 #endif // SOULNG_PARSER_DEBUG_SUPPORT
351 std::unique_ptr<EnumConstantNode> enumConstant;
352 soulng::parser::Match match(false);
353 soulng::parser::Match* parentMatch0 = &match;
354 {
355 soulng::parser::Match match(false);
356 soulng::parser::Match* parentMatch1 = &match;
357 {
358 int64_t pos = lexer.GetPos();
359 soulng::parser::Match match(true);
360 soulng::parser::Match* parentMatch2 = &match;
361 {
362 soulng::lexer::Span span = lexer.GetSpan();
363 soulng::parser::Match match = EnumerationParser::EnumConstant(lexer, ctx, enumType);
364 enumConstant.reset(static_cast<EnumConstantNode*>(match.value));
365 if (match.hit)
366 {
367 *parentMatch2 = match;
368 }
369 else
370 {
371 lexer.ThrowExpectationFailure(span, U"enumeration constant");
372 }
373 }
374 if (match.hit)
375 {
376 enumType->AddConstant(enumConstant.release());
377 }
378 *parentMatch1 = match;
379 }
380 *parentMatch0 = match;
381 }
382 if (match.hit)
383 {
384 soulng::parser::Match match(false);
385 soulng::parser::Match* parentMatch3 = &match;
386 {
387 soulng::parser::Match match(true);
388 soulng::parser::Match* parentMatch4 = &match;
389 {
390 while (true)
391 {
392 int64_t save = lexer.GetPos();
393 {
394 soulng::parser::Match match(false);
395 soulng::parser::Match* parentMatch5 = &match;
396 {
397 soulng::parser::Match match(false);
398 if (*lexer == COMMA)
399 {
400 ++lexer;
401 match.hit = true;
402 }
403 *parentMatch5 = match;
404 }
405 if (match.hit)
406 {
407 soulng::parser::Match match(false);
408 soulng::parser::Match* parentMatch6 = &match;
409 {
410 soulng::parser::Match match(false);
411 soulng::parser::Match* parentMatch7 = &match;
412 {
413 int64_t pos = lexer.GetPos();
414 soulng::parser::Match match(true);
415 soulng::parser::Match* parentMatch8 = &match;
416 {
417 soulng::lexer::Span span = lexer.GetSpan();
418 soulng::parser::Match match = EnumerationParser::EnumConstant(lexer, ctx, enumType);
419 enumConstant.reset(static_cast<EnumConstantNode*>(match.value));
420 if (match.hit)
421 {
422 *parentMatch8 = match;
423 }
424 else
425 {
426 lexer.ThrowExpectationFailure(span, U"enumeration constant");
427 }
428 }
429 if (match.hit)
430 {
431 enumType->AddConstant(enumConstant.release());
432 }
433 *parentMatch7 = match;
434 }
435 *parentMatch6 = match;
436 }
437 *parentMatch5 = match;
438 }
439 if (match.hit)
440 {
441 *parentMatch4 = match;
442 }
443 else
444 {
445 lexer.SetPos(save);
446 break;
447 }
448 }
449 }
450 }
451 *parentMatch3 = match;
452 }
453 *parentMatch0 = match;
454 }
455 #ifdef SOULNG_PARSER_DEBUG_SUPPORT
456
457
458
459
460
461 #endif // SOULNG_PARSER_DEBUG_SUPPORT
462 if (!match.hit)
463 {
464 match.value = nullptr;
465 }
466 return match;
467 }
468
469 soulng::parser::Match EnumerationParser::EnumConstant(CmajorLexer& lexer, ParsingContext* ctx, sngcm::ast::EnumTypeNode* enumType)
470 {
471 #ifdef SOULNG_PARSER_DEBUG_SUPPORT
472
473
474
475
476
477
478
479 #endif // SOULNG_PARSER_DEBUG_SUPPORT
480 Span s = Span();
481 std::unique_ptr<Node> expr = std::unique_ptr<Node>();
482 std::unique_ptr<IdentifierNode> constantId;
483 std::unique_ptr<Node> constantValue;
484 soulng::parser::Match match(false);
485 soulng::parser::Match* parentMatch0 = &match;
486 {
487 soulng::parser::Match match(false);
488 soulng::parser::Match* parentMatch1 = &match;
489 {
490 int64_t pos = lexer.GetPos();
491 soulng::lexer::Span span = lexer.GetSpan();
492 soulng::parser::Match match(true);
493 soulng::parser::Match* parentMatch2 = &match;
494 {
495 soulng::lexer::Span span = lexer.GetSpan();
496 soulng::parser::Match match = IdentifierParser::Identifier(lexer);
497 constantId.reset(static_cast<IdentifierNode*>(match.value));
498 if (match.hit)
499 {
500 *parentMatch2 = match;
501 }
502 else
503 {
504 lexer.ThrowExpectationFailure(span, U"identifier");
505 }
506 }
507 if (match.hit)
508 {
509 s = span;
510 }
511 *parentMatch1 = match;
512 }
513 *parentMatch0 = match;
514 }
515 if (match.hit)
516 {
517 soulng::parser::Match match(false);
518 soulng::parser::Match* parentMatch3 = &match;
519 {
520 soulng::parser::Match match(false);
521 soulng::parser::Match* parentMatch4 = &match;
522 {
523 soulng::parser::Match match(false);
524 soulng::parser::Match* parentMatch5 = &match;
525 {
526 int64_t save = lexer.GetPos();
527 soulng::parser::Match match(false);
528 soulng::parser::Match* parentMatch6 = &match;
529 {
530 soulng::parser::Match match(false);
531 if (*lexer == ASSIGN)
532 {
533 ++lexer;
534 match.hit = true;
535 }
536 *parentMatch6 = match;
537 }
538 if (match.hit)
539 {
540 soulng::parser::Match match(false);
541 soulng::parser::Match* parentMatch7 = &match;
542 {
543 soulng::parser::Match match(false);
544 soulng::parser::Match* parentMatch8 = &match;
545 {
546 int64_t pos = lexer.GetPos();
547 soulng::parser::Match match = ExpressionParser::Expression(lexer, ctx);
548 constantValue.reset(static_cast<Node*>(match.value));
549 if (match.hit)
550 {
551 expr.reset(constantValue.release());
552 expr->SetFullSpan();
553 Span v = expr->GetSpan();
554 s.end = expr->GetSpan().end;
555 EnumConstantNode* value = new EnumConstantNode(s, constantId.release(), expr.release());
556 value->SetHasValue();
557 value->SetStrValue(lexer.GetMatch(v));
558 {
559 #ifdef SOULNG_PARSER_DEBUG_SUPPORT
560
561 #endif // SOULNG_PARSER_DEBUG_SUPPORT
562 return soulng::parser::Match(true, value);
563 }
564 }
565 *parentMatch8 = match;
566 }
567 *parentMatch7 = match;
568 }
569 *parentMatch6 = match;
570 }
571 *parentMatch5 = match;
572 if (!match.hit)
573 {
574 soulng::parser::Match match(false);
575 soulng::parser::Match* parentMatch9 = &match;
576 lexer.SetPos(save);
577 {
578 soulng::parser::Match match(false);
579 soulng::parser::Match* parentMatch10 = &match;
580 {
581 int64_t pos = lexer.GetPos();
582 soulng::parser::Match match(true);
583 if (match.hit)
584 {
585 {
586 #ifdef SOULNG_PARSER_DEBUG_SUPPORT
587
588 #endif // SOULNG_PARSER_DEBUG_SUPPORT
589 return soulng::parser::Match(true, new EnumConstantNode(s, constantId.release(), MakeNextEnumConstantValue(s, enumType)));
590 }
591 }
592 *parentMatch10 = match;
593 }
594 *parentMatch9 = match;
595 }
596 *parentMatch5 = match;
597 }
598 }
599 *parentMatch4 = match;
600 }
601 *parentMatch3 = match;
602 }
603 *parentMatch0 = match;
604 }
605 #ifdef SOULNG_PARSER_DEBUG_SUPPORT
606
607
608
609
610
611 #endif // SOULNG_PARSER_DEBUG_SUPPORT
612 if (!match.hit)
613 {
614 match.value = nullptr;
615 }
616 return match;
617 }