hoshi-lang dev
Yet another programming language
Loading...
Searching...
No Matches
parser.cpp
Go to the documentation of this file.
1//
2// Created by XIaokang00010 on 2023/2/11.
3//
4
7#include "compiler/ir/IR.h"
8#include "share/def.hpp"
9#include <cstdint>
10#pragma clang diagnostic push
11#pragma clang diagnostic ignored "-Wextra-qualification"
12#pragma ide diagnostic ignored "misc-no-recursion"
13
14#include "parser.hpp"
15
16namespace yoi {
17 // Helper to finalize children in vectors on error
18 template <typename T> void finalizeAST_vec(yoi::vec<T *> &vec) {
19 for (auto &i : vec) {
20 finalizeAST(i);
21 }
22 vec.clear(); // Clear the pointers from the vector
23 }
24
43
44 void parse(identifier *&o, lexer &lex) {
46 o = new identifier{lex.curToken, lex.curToken};
47 lex.scan();
48 } else {
49 o = nullptr;
50 }
51 }
52
54 lex.saveState();
55 identifier *id = nullptr;
56 typeSpec *spec = nullptr;
57
58 lexer::token node_start_token = lex.curToken;
59
60 parse(id, lex);
61 if (!id) {
62 lex.dropState(); // No identifier parsed, so no state to return. Drop it.
63 o = nullptr;
64 return;
65 }
66
68 lex.scan();
69 } else {
70 lex.returnState();
71 finalizeAST(id);
72 o = nullptr;
73 return;
74 }
75
76 parse(spec, lex);
77 if (!spec) { // If typeSpec parsing fails
78 finalizeAST(id);
79 lex.returnState(); // Backtrack because we couldn't complete the rule
80 o = nullptr;
81 return;
82 }
83
84 lex.dropState();
85 o = new identifierWithTypeSpec{node_start_token, id, spec};
86 }
87
88 void parse(defTemplateArgSpec *&o, lexer &lex) {
89 identifier *id = nullptr;
90 satisfyClause *satisfyCondition = nullptr;
91 lexer::token node_start_token = lex.curToken;
92
93 parse(id, lex);
94 if (!id) {
95 o = nullptr;
96 return;
97 }
98
100 parse(satisfyCondition, lex);
101 if (!satisfyCondition) {
102 finalizeAST(id);
103 panic(lex.line, lex.col, "expected satisfyClause after `satisfy` in defTemplateArgSpec");
104 o = nullptr; // Ensure o is null on failure
105 return;
106 }
107 o = new defTemplateArgSpec{node_start_token, id, satisfyCondition};
108 } else {
109 o = new defTemplateArgSpec{node_start_token, id, nullptr};
110 }
111 }
112
113 void parse(defTemplateArg *&o, lexer &lex) {
114 lex.saveState();
116 lex.dropState();
117 o = nullptr;
118 return;
119 }
120 lexer::token node_start_token = lex.curToken;
121 lex.scan();
122
124 defTemplateArgSpec *t = nullptr; // Initialize t
125
126 parse(t, lex);
127 if (t) { // Parse first argument if present
128 specs.push_back(t);
130 lex.scan();
131 t = nullptr; // Reset for next parse
132 parse(t, lex);
133 if (!t) { // Comma must be followed by an argument
134 finalizeAST_vec(specs);
135 lex.returnState();
136 panic(lex.line, lex.col, "expected defTemplateArgSpec after comma in defTemplateArg");
137 o = nullptr;
138 return;
139 }
140 specs.push_back(t);
141 }
142 }
143
145 lex.scan();
146 o = new defTemplateArg{node_start_token, specs};
147 lex.dropState();
148 } else {
149 finalizeAST_vec(specs);
150 lex.returnState();
151 panic(lex.line, lex.col, "expected `>` to close a defTemplateArg node"); // More specific panic message
152 o = nullptr;
153 return;
154 }
155 }
156
157 void parse(templateArgSpec *&o, lexer &lex) {
158 typeSpec *spec = nullptr;
159 lexer::token node_start_token = lex.curToken;
160 parse(spec, lex);
161 o = spec ? new templateArgSpec{node_start_token, spec} : nullptr;
162 }
163
164 void parse(templateArg *&o, lexer &lex) {
165 lex.saveState();
167 lex.dropState();
168 o = nullptr;
169 return;
170 }
171 lexer::token node_start_token = lex.curToken;
172 lex.scan();
173
175 templateArgSpec *t = nullptr; // Initialize t
176
177 parse(t, lex);
178 if (t) { // Parse first argument if present
179 specs.push_back(t);
181 lex.scan();
182 t = nullptr; // Reset for next parse
183 parse(t, lex);
184 if (!t) { // Comma must be followed by an argument
185 finalizeAST_vec(specs);
186 lex.returnState();
187 panic(lex.line, lex.col, "expected templateArgSpec after comma in templateArg");
188 o = nullptr;
189 return;
190 }
191 specs.push_back(t);
192 }
193 }
194
196 lex.scan();
197 o = new templateArg{node_start_token, specs};
198 lex.dropState();
199 } else {
200 lex.returnState();
201 finalizeAST_vec(specs);
202 o = nullptr;
203 return;
204 }
205 }
206
209 o = nullptr;
210 return;
211 }
212 lexer::token node_start_token = lex.curToken;
213 lex.scan();
214
216 rExpr *t = nullptr; // Initialize t
217
218 parse(t, lex);
219 if (t) { // Parse first argument if present
220 args.emplace_back(t);
222 lex.scan();
223 t = nullptr; // Reset for next parse
224 parse(t, lex);
225 if (!t) { // Comma must be followed by an argument
226 finalizeAST_vec(args);
227 panic(lex.line, lex.col, "expected rightValueExpr after comma in invocationArguments");
228 o = nullptr;
229 return;
230 }
231 args.emplace_back(t);
232 }
233 }
234
236 lex.scan();
237 o = new invocationArguments{node_start_token, args};
238 } else {
239 finalizeAST_vec(args);
240 panic(lex.line, lex.col, "expected `)` to close an invocationArguments node");
241 o = nullptr;
242 return;
243 }
244 }
245
248 o = nullptr;
249 return;
250 }
251 lexer::token node_start_token = lex.curToken;
252 lex.scan();
253
255 identifierWithTypeSpec *t = nullptr; // Initialize t
256
257 parse(t, lex);
258 if (t) { // Parse first argument if present
259 args.push_back(t);
261 lex.scan();
262 t = nullptr; // Reset for next parse
263 parse(t, lex);
264 if (!t) { // Comma must be followed by an argument
265 finalizeAST_vec(args);
266 panic(lex.line, lex.col, "expected identifierWithTypeSpec after comma in definitionArguments");
267 o = nullptr;
268 return;
269 }
270 args.push_back(t);
271 }
272 }
273
275 lex.scan();
276 o = new definitionArguments{node_start_token, args};
277 } else {
278 finalizeAST_vec(args);
279 panic(lex.line, lex.col, "expected `)` to close a definitionArguments node");
280 o = nullptr;
281 return;
282 }
283 }
284
285 void parse(funcTypeSpec *&o, lexer &lex) {
287 lex.scan();
288 } else {
289 o = nullptr;
290 return;
291 }
292 lexer::token node_start_token = lex.curToken;
293
294 unnamedDefinitionArguments *args = nullptr;
295 typeSpec *spec = nullptr;
296
297 parse(args, lex);
298 if (!args) {
299 panic(lex.line, lex.col, "expected definitionArguments after `func`");
300 o = nullptr;
301 return;
302 }
304 lex.scan();
305 else {
306 finalizeAST(args);
307 panic(lex.line, lex.col, "expected `:` after definitionArguments");
308 o = nullptr;
309 return;
310 }
311 parse(spec, lex);
312 if (!spec) {
313 finalizeAST(args);
314 panic(lex.line, lex.col, "expected typeSpec after `:`");
315 o = nullptr;
316 return;
317 }
318 o = new funcTypeSpec{node_start_token, args, spec};
319 }
320
321 void parse(typeSpec *&o, lexer &lex) {
322 externModuleAccessExpression *expr = nullptr;
323 funcTypeSpec *spec = nullptr;
324 decltypeExpr *decltypeExpression = nullptr;
325 lexer::token node_start_token = lex.curToken;
326
328 lex.scan();
329 o = new typeSpec{node_start_token, typeSpec::typeSpecKind::Null, nullptr, nullptr, nullptr, nullptr, true};
330 return;
332 lex.scan();
333 typeSpec *t = nullptr;
334 parse(t, lex);
335 if (!t) {
336 o = new typeSpec{node_start_token, typeSpec::typeSpecKind::Elipsis, nullptr, nullptr, nullptr, nullptr, false, nullptr};
337 } else {
339 finalizeAST(t);
340 o = nullptr;
341 panic(lex.line, lex.col, "expected typeSpec after `...`");
342 }
343 o = new typeSpec{node_start_token, typeSpec::typeSpecKind::Elipsis, nullptr, nullptr, t, nullptr, false, nullptr};
344 }
345 return;
346 }
348
349 parse(spec, lex);
350 if (spec) {
352 } else {
353 parse(expr, lex);
354 if (expr) {
356 } else {
357 parse(decltypeExpression, lex);
358 if (decltypeExpression) {
360 } else {
361 o = nullptr;
362 return;
363 }
364 }
365 }
366
367 yoi::vec<uint64_t> *arraySubscript = nullptr;
369 lex.scan();
371 lex.scan();
372 arraySubscript = new vec<uint64_t>{(uint64_t)-1};
374 arraySubscript = new yoi::vec<uint64_t>{lex.curToken.basicVal.vUint};
375 while (lex.scan().kind == lexer::token::tokenKind::comma) {
376 lex.scan();
378 arraySubscript->push_back(lex.curToken.basicVal.vInt);
379 } else {
380 if (spec) finalizeAST(spec);
381 if (expr) finalizeAST(expr);
382 if (decltypeExpression) finalizeAST(decltypeExpression);
383 delete arraySubscript;
384 o = nullptr;
385 panic(lex.line, lex.col, "expected integer after `,` in array type specifier");
386 return;
387 }
388 }
390 lex.scan();
391 } else {
392 if (spec) finalizeAST(spec);
393 if (expr) finalizeAST(expr);
394 if (decltypeExpression) finalizeAST(decltypeExpression);
395 delete arraySubscript;
396 o = nullptr;
397 return;
398 }
399 } else {
400 if (spec) finalizeAST(spec);
401 if (expr) finalizeAST(expr);
402 if (decltypeExpression) finalizeAST(decltypeExpression);
403 o = nullptr;
404 return;
405 }
406 }
407
408 o = new typeSpec{node_start_token, kind, expr, spec, nullptr, decltypeExpression, false, arraySubscript};
409 }
410
411 void parse(subscript *&o, lexer &lex) {
413 lex.saveState();
414 lexer::token node_start_token = lex.curToken;
415 lex.scan();
416 rExpr *r = nullptr;
417 parse(r, lex);
418 if (!r) {
419 // panic(lex.line, lex.col, "expected rightValueExpr in subscript");
420 lex.returnState();
421 o = nullptr;
422 return;
423 }
425 lex.dropState();
426 lex.scan();
427 o = new subscript{node_start_token, r};
428 } else {
429 lex.dropState();
430 finalizeAST(r);
431 panic(lex.line, lex.col, "expected `]` to close a subscript");
432 o = nullptr;
433 return;
434 }
436 lexer::token node_start_token = lex.curToken;
437 invocationArguments *args = nullptr;
438 parse(args, lex);
439 if (!args) {
440 panic(lex.line, lex.col, "expected invocationArguments in subscript");
441 o = nullptr;
442 return;
443 }
444 o = new subscript{node_start_token, nullptr, args};
445 } else {
446 o = nullptr;
447 }
448 }
449
451 identifier *id = nullptr;
452 templateArg *arg = nullptr;
453 lexer::token node_start_token = lex.curToken;
454
455 parse(id, lex);
456 if (!id) {
457 o = nullptr;
458 return;
459 }
460 o = new identifierWithTemplateArg{node_start_token, id, nullptr};
461
462 parse(arg, lex);
463 if (!arg) {
464 // No template arg, 'o' is already created with 'nullptr' for arg.
465 return;
466 }
467 o->arg = arg;
468 }
469
471 identifier *id = nullptr;
472 defTemplateArg *arg = nullptr;
473 lexer::token node_start_token = lex.curToken;
474
475 parse(id, lex);
476 if (!id) {
477 o = nullptr;
478 return;
479 }
480 o = new identifierWithDefTemplateArg{node_start_token, id, nullptr};
481
482 parse(arg, lex);
483 if (!arg) {
484 // No def template arg, 'o' is already created with 'nullptr' for arg.
485 return;
486 }
487 o->arg = arg;
488 }
489
492 identifierWithTemplateArg *a = nullptr;
493 lexer::token node_start_token = lex.curToken;
494
495 parse(a, lex);
496 if (!a) {
497 o = nullptr;
498 return;
499 }
500
501 while (true) {
502 vecA.push_back(a); // Add current 'a' to vector
504 break; // No more dots, end of expression
505 } else if (a->hasTemplateArg()) { // Logic: an identifier with template arg cannot be followed by a dot.
506 finalizeAST_vec(vecA);
507 panic(lex.line,
508 lex.col,
509 "expected identifier (except the last term) in externModuleAccessExpression, found identifier with template arguments followed "
510 "by '.'");
511 o = nullptr;
512 return;
513 } else {
514 lex.scan(); // Consume the dot
515 }
516 a = nullptr; // Reset 'a' for the next parse call
517 parse(a, lex);
518 if (!a) { // A dot must be followed by another identifier.
519 finalizeAST_vec(vecA);
520 panic(lex.line, lex.col, "expected identifier after `.` in externModuleAccessExpression");
521 o = nullptr;
522 return;
523 }
524 }
525 o = new externModuleAccessExpression{node_start_token, vecA};
526 }
527
528 void parse(subscriptExpr *&o, lexer &lex) {
529 identifierWithTemplateArg *a = nullptr;
531 lexer::token node_start_token = lex.curToken;
532
533 parse(a, lex);
534 if (!a) {
535 o = nullptr;
536 return;
537 }
538
539 subscript *s = nullptr;
540 for (parse(s, lex); s; parse(s, lex)) {
541 b.push_back(s);
542 }
543
544 o = new subscriptExpr{node_start_token, a, b};
545 }
546
547 void parse(memberExpr *&o, lexer &lex) {
549 subscriptExpr *a = nullptr;
550 lexer::token node_start_token = lex.curToken;
551
552 parse(a, lex);
553 if (!a) {
554 o = nullptr;
555 return;
556 }
557 while (true) {
558 vecA.push_back(a);
560 break;
561 } else {
562 lex.scan();
563 }
564 a = nullptr; // Reset for next parse
565 parse(a, lex);
566 if (!a) { // Dot must be followed by another subscriptExpr
567 finalizeAST_vec(vecA);
568 panic(lex.line, lex.col, "expected subscriptExpr after `.` in memberExpr");
569 o = nullptr;
570 return;
571 }
572 }
573 o = new memberExpr{node_start_token, vecA};
574 }
575
576 void parse(newExpression *&o, lexer &lex) {
577 lexer::token node_start_token = lex.curToken;
579 o = nullptr;
580 return;
581 }
582 lex.scan();
583
584 externModuleAccessExpression *expr = nullptr;
585 parse(expr, lex);
586 if (!expr) {
587 panic(lex.line, lex.col, "expected externModuleAccessExpression after `new` in newExpression");
588 }
589
590 o = new newExpression{node_start_token, expr, nullptr, nullptr};
591 parse(o->length, lex);
592 if (!o->length) {
594 o->length = nullptr;
595 lex.scan(); // Consume ']'
596 } else {
597 panic(lex.line, lex.col, "expected lengthExpr after `new` in newExpression");
598 finalizeAST(o->type);
599 delete o;
600 o = nullptr;
601 }
602 }
603 parse(o->args, lex);
604 if (!o->args) {
605 panic(lex.line, lex.col, "expected invocationArguments after `new` in newExpression");
606 finalizeAST(o->type);
608 delete o;
609 o = nullptr;
610 }
611 }
612
613 void parse(primary *&o, lexer &lex) {
614 memberExpr *a = nullptr;
615 basicLiterals *b = nullptr;
616 typeIdExpression *d = nullptr;
617 dynCastExpression *e = nullptr;
618 newExpression *f = nullptr;
619 lambdaExpr *g = nullptr;
620 funcExpr *h = nullptr;
621 bracedInitalizerList *i = nullptr;
622 rExpr *c = nullptr;
623
624 lexer::token node_start_token = lex.curToken;
625
626 parse(a, lex);
627 if (a) {
628 o = new primary{node_start_token, primary::primaryKind::memberExpr, a, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
629 return;
630 }
631 parse(b, lex);
632 if (b) {
633 o = new primary{node_start_token, primary::primaryKind::basicLiterals, nullptr, b, nullptr, nullptr, nullptr, nullptr, nullptr};
634 return;
635 }
636 parse(d, lex);
637 if (d) {
638 o = new primary{
639 node_start_token, primary::primaryKind::typeIdExpression, nullptr, nullptr, nullptr, d, nullptr, nullptr, nullptr, nullptr};
640 return;
641 }
642 parse(e, lex);
643 if (e) {
644 o = new primary{
645 node_start_token, primary::primaryKind::dynCastExpression, nullptr, nullptr, nullptr, nullptr, e, nullptr, nullptr, nullptr, nullptr};
646 return;
647 }
648 parse(f, lex);
649 if (f) {
650 o = new primary{
651 node_start_token, primary::primaryKind::newExpression, nullptr, nullptr, nullptr, nullptr, nullptr, f, nullptr, nullptr, nullptr};
652 return;
653 }
654 parse(g, lex);
655 if (g) {
656 o = new primary{
657 node_start_token, primary::primaryKind::lambdaExpr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, g, nullptr, nullptr};
658 return;
659 }
660 parse(h, lex);
661 if (h) {
662 o = new primary{
663 node_start_token, primary::primaryKind::funcExpr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, h, nullptr};
664 return;
665 }
666 parse(i, lex);
667 if (i) {
668 o = new primary{node_start_token,
670 nullptr,
671 nullptr,
672 nullptr,
673 nullptr,
674 nullptr,
675 nullptr,
676 nullptr,
677 nullptr,
678 i};
679 return;
680 }
682 lex.scan(); // Consume '('
683 parse(c, lex);
684 if (!c) {
685 panic(lex.line, lex.col, "expected rightValueExpr after `(` while parsing primary");
686 o = nullptr; // Ensure o is null on failure
687 return;
688 }
690 lex.scan(); // Consume ')'
691 o = new primary{node_start_token, primary::primaryKind::rExpr, nullptr, nullptr, c};
692 return;
693 } else {
694 finalizeAST(c);
695 panic(lex.line, lex.col, "expected `)` after rightValueExpr while parsing primary");
696 o = nullptr; // Ensure o is null on failure
697 return;
698 }
699 }
700 o = nullptr;
701 }
702
703 void parse(uniqueExpr *&o, lexer &lex) {
704 lex.saveState();
705 lexer::token t{};
706 switch (lex.curToken.kind) {
711 t = lex.curToken;
712 lex.scan(); // Consume the operator
713 break;
714 }
715 default: {
717 break;
718 }
719 }
720 abstractExpr *expr = nullptr;
721 lexer::token node_start_token = lex.curToken;
722
723 parse(expr, lex);
724 if (!expr) {
725 lex.returnState();
726 o = nullptr;
727 return;
728 }
729 o = new uniqueExpr{node_start_token, t, expr};
730 lex.dropState();
731 }
732
733 void parse(leftExpr *&o, lexer &lex) {
734 uniqueExpr *a = nullptr;
735 lexer::token t{};
736 rExpr *expr = nullptr;
737 lexer::token node_start_token = lex.curToken;
738
739 parse(a, lex);
740 if (!a) {
741 o = nullptr;
742 return;
743 }
744
745 switch (lex.curToken.kind) {
752 t = lex.curToken;
753 lex.scan();
754 parse(expr, lex);
755 if (!expr) {
756 finalizeAST(a);
757 panic(lex.line, lex.col, "expected rightValueExpr after assignment operator");
758 o = nullptr;
759 return;
760 }
761 o = new leftExpr{node_start_token, t, a, expr};
762 break;
763 }
764 default: {
765 o = new leftExpr{node_start_token, t, a, nullptr}; // 't' will be an empty token, 'expr' will be nullptr.
766 break;
767 }
768 }
769 }
770
771// Common pattern for binary expressions (mulExpr, addExpr, shiftExpr, etc.)
772// Applied to all binary expression parsers below.
773#define PARSE_BINARY_EXPR(NODE_TYPE, CHILD_TYPE, OPERATORS, ERROR_MSG) \
774 void parse(NODE_TYPE *&o, lexer &lex) { \
775 yoi::vec<CHILD_TYPE *> vecA; \
776 yoi::vec<lexer::token> vecB; \
777 CHILD_TYPE *a = nullptr; \
778 lexer::token node_start_token = lex.curToken; \
779 \
780 parse(a, lex); \
781 if (a) { \
782 vecA.push_back(a); \
783 while \
784 OPERATORS { \
785 vecB.push_back(lex.curToken); \
786 lex.scan(); \
787 a = nullptr; \
788 parse(a, lex); \
789 if (!a) { \
790 finalizeAST_vec(vecA); \
791 panic(lex.line, lex.col, ERROR_MSG); \
792 o = nullptr; \
793 return; \
794 } \
795 vecA.push_back(a); \
796 } \
797 o = new NODE_TYPE{node_start_token, vecA, vecB}; \
798 } else { \
799 o = nullptr; \
800 } \
801 }
802
804 leftExpr,
805 (lex.curToken.kind == lexer::token::tokenKind::asterisk || lex.curToken.kind == lexer::token::tokenKind::slash ||
806 lex.curToken.kind == lexer::token::tokenKind::percentSign),
807 "expected uniqueExpr after operators while parsing mulExpr")
810 (lex.curToken.kind == lexer::token::tokenKind::plus || lex.curToken.kind == lexer::token::tokenKind::minus),
811 "expected mulExpr after operators while parsing addExpr")
813 addExpr,
814 (lex.curToken.kind == lexer::token::tokenKind::binaryShiftLeft ||
815 lex.curToken.kind == lexer::token::tokenKind::binaryShiftRight),
816 "expected addExpr after operators while parsing shiftExpr")
818 shiftExpr,
819 (lex.curToken.kind == lexer::token::tokenKind::lessThan || lex.curToken.kind == lexer::token::tokenKind::greaterThan ||
820 lex.curToken.kind == lexer::token::tokenKind::lessEqual || lex.curToken.kind == lexer::token::tokenKind::greaterEqual),
821 "expected shiftExpr after operators while parsing relationalExpr")
824 (lex.curToken.kind == lexer::token::tokenKind::equal || lex.curToken.kind == lexer::token::tokenKind::notEqual),
825 "expected relationalExpr after operators while parsing equalityExpr")
828 (lex.curToken.kind == lexer::token::tokenKind::binaryAnd),
829 "expected equalityExpr after operators while parsing andExpr") // Corrected from relationalExpr
831 andExpr,
832 (lex.curToken.kind == lexer::token::tokenKind::binaryXor),
833 "expected andExpr after operators while parsing exclusiveExpr")
836 (lex.curToken.kind == lexer::token::tokenKind::binaryOr),
837 "expected exclusiveExpr after operators while parsing inclusiveExpr")
840 (lex.curToken.kind == lexer::token::tokenKind::logicAnd),
841 "expected inclusiveExpr after operators while parsing logicalAndExpr")
844 (lex.curToken.kind == lexer::token::tokenKind::logicOr),
845 "expected logicalAndExpr after operators while parsing logicalOrExpr")
846
847#undef PARSE_BINARY_EXPR
848
849 void parse(rExpr *&o, lexer &lex) {
850 logicalOrExpr *expr = nullptr;
851 lexer::token node_start_token = lex.curToken;
852 parse(expr, lex);
853 if (expr) {
854 o = new rExpr{node_start_token, expr};
855 } else {
856 o = nullptr;
857 }
858 }
859
860 void parse(codeBlock *&o, lexer &lex) {
861 if (lex.curToken.kind == lexer::token::tokenKind::leftBraces) {
862 lexer::token node_start_token = lex.curToken;
863 lex.scan();
865 inCodeBlockStmt *stmt = nullptr; // Initialize stmt
866
867 while (true) {
868 parse(stmt, lex);
869 if (!stmt)
870 break;
871 stmts.push_back(stmt);
872 stmt = nullptr; // Reset stmt for the next parse call
873 }
874 if (lex.curToken.kind == lexer::token::tokenKind::rightBraces) {
875 yoi::indexT endLine = lex.curToken.line;
876 yoi::indexT endColumn = lex.curToken.col;
877 lex.scan();
878 o = new codeBlock{node_start_token, stmts};
879 o->endLine = endLine;
880 o->endColumn = endColumn;
881 } else {
882 finalizeAST_vec(stmts);
883 panic(lex.line, lex.col, "expected `}` to close codeBlock");
884 o = nullptr;
885 return;
886 }
887 } else {
888 o = nullptr;
889 return;
890 }
891 }
892
893 void parse(useStmt *&o, lexer &lex) {
894 lexer::token node_start_token;
895 if (lex.curToken.kind == lexer::token::tokenKind::kUse) {
896 node_start_token = lex.curToken;
897 lex.scan();
898 } else {
899 o = nullptr;
900 return;
901 }
902 identifier *id = nullptr;
903 lexer::token str_token{}; // Not a pointer, directly stored
904
905 parse(id, lex);
906 if (!id) {
907 panic(lex.line, lex.col, "expected identifier after `use`");
908 o = nullptr;
909 return;
910 }
911 if (lex.curToken.kind != lexer::token::tokenKind::string) {
912 finalizeAST(id);
913 panic(lex.line, lex.col, "expected string token after identifier while parsing useStmt");
914 o = nullptr;
915 return;
916 }
917 str_token = lex.curToken; // Store the string token by value
918 lex.scan();
919 o = new useStmt{node_start_token, id, str_token};
920 }
921
922 void parse(funcDefStmt *&o, lexer &lex) {
923 if (lex.curToken.kind == lexer::token::tokenKind::kFunc) {
924 lex.scan();
925 } else {
926 o = nullptr;
927 return;
928 }
929 lexer::token node_start_token = lex.curToken;
930
932 identifierWithDefTemplateArg *name = nullptr;
933 definitionArguments *args = nullptr;
934 typeSpec *spec = nullptr;
935 codeBlock *block = nullptr;
936
937 while (lex.curToken.kind >= lexer::token::tokenKind::kNoFFI && lex.curToken.kind <= lexer::token::tokenKind::kAlwaysInline) {
938 attrs.push_back(lex.curToken);
939 lex.scan();
940 }
941
942 parse(name, lex);
943 if (!name) {
944 panic(lex.line, lex.col, "expected function name");
945 o = nullptr;
946 return;
947 }
948 parse(args, lex);
949 if (!args) {
950 finalizeAST(name);
951 panic(lex.line, lex.col, "expected definitionArguments after identifierWithDefTemplateArg");
952 o = nullptr;
953 return;
954 }
955 if (lex.curToken.kind == lexer::token::tokenKind::colon)
956 lex.scan();
957 else {
958 finalizeAST(name);
959 finalizeAST(args);
960 panic(lex.line, lex.col, "expected `:` after definitionArguments");
961 o = nullptr;
962 return;
963 }
964 parse(spec, lex);
965 if (!spec) {
966 finalizeAST(name);
967 finalizeAST(args);
968 panic(lex.line, lex.col, "expected typeSpec after `:`");
969 o = nullptr;
970 return;
971 }
972 parse(block, lex);
973 if (!block) {
974 finalizeAST(name);
975 finalizeAST(args);
976 finalizeAST(spec);
977 panic(lex.line, lex.col, "expected codeBlock after typeSpec");
978 o = nullptr;
979 return;
980 }
981 o = new funcDefStmt{node_start_token, attrs, name, args, spec, block};
982 }
983
984 void parse(interfaceDefInnerPair *&o, lexer &lex) {
985 identifierWithTypeSpec *var = nullptr;
986 innerMethodDecl *method = nullptr;
987 lexer::token node_start_token = lex.curToken;
988
989 parse(method, lex);
990 if (method) {
991 o = new interfaceDefInnerPair{node_start_token, nullptr, method};
992 return;
993 }
994 parse(var, lex);
995 if (var) {
996 o = new interfaceDefInnerPair{node_start_token, var, nullptr};
997 return;
998 }
999 o = nullptr;
1000 }
1001
1002 void parse(structDefInnerPair *&o, lexer &lex) {
1003 identifierWithTypeSpec *var = nullptr;
1004 innerMethodDecl *method = nullptr;
1005 constructorDecl *con = nullptr;
1006 finalizerDecl *fin = nullptr;
1007 lexer::token node_start_token = lex.curToken;
1009
1010 if (lex.curToken.kind == lexer::token::tokenKind::kWeak) {
1012 lex.scan();
1013 } else if (lex.curToken.kind == lexer::token::tokenKind::kDataField) {
1015 lex.scan();
1016 }
1017
1018 parse(con, lex);
1019 if (con) {
1020 o = new structDefInnerPair{node_start_token, 1, mod, nullptr, con, nullptr, nullptr};
1021 return;
1022 }
1023 parse(method, lex);
1024 if (method) {
1025 o = new structDefInnerPair{node_start_token, 2, mod, nullptr, nullptr, method, nullptr};
1026 return;
1027 }
1028 parse(fin, lex);
1029 if (fin) {
1030 o = new structDefInnerPair{node_start_token, 3, mod, nullptr, nullptr, nullptr, fin};
1031 return;
1032 }
1033 parse(var, lex);
1034 if (var) {
1035 o = new structDefInnerPair{node_start_token, 0, mod, var, nullptr, nullptr, nullptr};
1036 return;
1037 }
1038 o = nullptr;
1039 }
1040
1041 void parse(implInnerPair *&o, lexer &lex) {
1042 innerMethodDef *method = nullptr;
1043 constructorDef *con = nullptr;
1044 finalizerDef *fin = nullptr;
1045 lexer::token node_start_token = lex.curToken;
1046
1047 parse(con, lex);
1048 if (con) {
1049 o = new implInnerPair{node_start_token, con, nullptr, nullptr};
1050 return;
1051 }
1052 parse(method, lex);
1053 if (method) {
1054 o = new implInnerPair{node_start_token, nullptr, method, nullptr};
1055 return;
1056 }
1057 parse(fin, lex);
1058 if (fin) {
1059 o = new implInnerPair{node_start_token, nullptr, nullptr, fin};
1060 return;
1061 }
1062 o = nullptr;
1063 }
1064
1065 void parse(interfaceDefInner *&o, lexer &lex) {
1066 if (lex.curToken.kind == lexer::token::tokenKind::leftBraces) {
1067 lexer::token node_start_token = lex.curToken;
1068 lex.scan();
1070 interfaceDefInnerPair *a = nullptr; // Initialize a
1071
1072 while (true) {
1073 parse(a, lex);
1074 if (!a) {
1075 break;
1076 }
1077 vecA.push_back(a);
1078 a = nullptr; // Reset 'a' for next parse
1079
1080 if (lex.curToken.kind == lexer::token::tokenKind::comma) {
1081 lex.scan();
1082 } else {
1083 break;
1084 }
1085 }
1086 if (lex.curToken.kind == lexer::token::tokenKind::rightBraces) {
1087 lex.scan();
1088 o = new interfaceDefInner{node_start_token, vecA};
1089 } else {
1090 finalizeAST_vec(vecA);
1091 panic(lex.line, lex.col, "expected `}` to close interfaceDefInner");
1092 o = nullptr;
1093 return;
1094 }
1095 } else {
1096 o = nullptr;
1097 return;
1098 }
1099 }
1100
1101 void parse(structDefInner *&o, lexer &lex) {
1102 if (lex.curToken.kind == lexer::token::tokenKind::leftBraces) {
1103 lexer::token node_start_token = lex.curToken;
1104 lex.scan();
1106 structDefInnerPair *a = nullptr; // Initialize a
1107
1108 while (true) {
1109 parse(a, lex);
1110 if (!a) {
1111 break;
1112 }
1113 vecA.push_back(a);
1114 a = nullptr; // Reset 'a' for next parse
1115
1116 if (lex.curToken.kind == lexer::token::tokenKind::comma) {
1117 lex.scan();
1118 } else {
1119 break;
1120 }
1121 }
1122 if (lex.curToken.kind == lexer::token::tokenKind::rightBraces) {
1123 lex.scan();
1124 o = new structDefInner{node_start_token, vecA};
1125 } else {
1126 finalizeAST_vec(vecA);
1127 panic(lex.line, lex.col, "expected `}` to close structDefInner");
1128 o = nullptr;
1129 return;
1130 }
1131 } else {
1132 o = nullptr;
1133 return;
1134 }
1135 }
1136
1137 void parse(implInner *&o, lexer &lex) {
1138 if (lex.curToken.kind == lexer::token::tokenKind::leftBraces) {
1139 lexer::token node_start_token = lex.curToken;
1140 lex.scan();
1142 implInnerPair *a = nullptr; // Initialize a
1143
1144 while (true) {
1145 parse(a, lex);
1146 if (!a) {
1147 break;
1148 }
1149 vecA.push_back(a);
1150 a = nullptr; // Reset 'a' for next parse
1151
1152 if (lex.curToken.kind == lexer::token::tokenKind::comma) {
1153 lex.scan();
1154 } else {
1155 break;
1156 }
1157 }
1158 if (lex.curToken.kind == lexer::token::tokenKind::rightBraces) {
1159 lex.scan();
1160 o = new implInner{node_start_token, vecA};
1161 } else {
1162 finalizeAST_vec(vecA);
1163 panic(lex.line, lex.col, "expected `}` to close implInner");
1164 o = nullptr;
1165 return;
1166 }
1167 } else {
1168 o = nullptr;
1169 return;
1170 }
1171 }
1172
1173 void parse(interfaceDefStmt *&o, lexer &lex) {
1174 if (lex.curToken.kind == lexer::token::tokenKind::kInterface) {
1175 lex.scan();
1176 } else {
1177 o = nullptr;
1178 return;
1179 }
1180 lexer::token node_start_token = lex.curToken;
1181
1182 identifierWithDefTemplateArg *id = nullptr;
1183 interfaceDefInner *inner = nullptr;
1184
1185 parse(id, lex);
1186 if (!id) {
1187 panic(lex.line, lex.col, "expected interface name after `interface`");
1188 o = nullptr;
1189 return;
1190 }
1191 parse(inner, lex);
1192 if (!inner) {
1193 finalizeAST(id);
1194 panic(lex.line, lex.col, "expected interfaceDefInner after identifier");
1195 o = nullptr;
1196 return;
1197 }
1198 o = new interfaceDefStmt{node_start_token, id, inner};
1199 }
1200
1201 void parse(structDefStmt *&o, lexer &lex) {
1202 if (lex.curToken.kind == lexer::token::tokenKind::kStruct) {
1203 lex.scan();
1204 } else {
1205 o = nullptr;
1206 return;
1207 }
1208 lexer::token node_start_token = lex.curToken;
1209
1210 identifierWithDefTemplateArg *id = nullptr;
1211 structDefInner *inner = nullptr;
1212
1213 parse(id, lex);
1214 if (!id) {
1215 panic(lex.line, lex.col, "expected struct name after `struct`");
1216 o = nullptr;
1217 return;
1218 }
1219 parse(inner, lex);
1220 if (!inner) {
1221 finalizeAST(id);
1222 panic(lex.line, lex.col, "expected structDefInner after identifier");
1223 o = nullptr;
1224 return;
1225 }
1226 o = new structDefStmt{node_start_token, id, inner};
1227 }
1228
1229 void parse(dataStructDefStmt *&o, lexer &lex) {
1230 if (lex.curToken.kind == lexer::token::tokenKind::kDataStruct) {
1231 lex.scan();
1232 } else {
1233 o = nullptr;
1234 return;
1235 }
1236 lexer::token node_start_token = lex.curToken;
1237
1238 identifier *id = nullptr;
1239 structDefInner *inner = nullptr;
1240
1241 parse(id, lex);
1242 if (!id) {
1243 panic(lex.line, lex.col, "expected datastruct name after `datastruct`");
1244 o = nullptr;
1245 return;
1246 }
1247 parse(inner, lex);
1248 if (!inner) {
1249 finalizeAST(id);
1250 panic(lex.line, lex.col, "expected datastruct body after identifier");
1251 o = nullptr;
1252 return;
1253 }
1254
1255 for (auto &pair : inner->getInner()) {
1256 if (pair->kind != 0) {
1257 finalizeAST(id);
1258 finalizeAST(inner);
1259 panic(lex.line, lex.col, "datastruct can only contain fields, no methods or constructors allowed");
1260 o = nullptr;
1261 return;
1262 }
1263 }
1264
1265 o = new dataStructDefStmt{node_start_token, id, inner};
1266 }
1267
1268 void parse(implStmt *&o, lexer &lex) {
1269 if (lex.curToken.kind == lexer::token::tokenKind::kImpl) {
1270 lex.scan();
1271 } else {
1272 o = nullptr;
1273 return;
1274 }
1275 lexer::token node_start_token = lex.curToken;
1276
1277 externModuleAccessExpression *first = nullptr; // Represents the interface (optional)
1278 externModuleAccessExpression *second = nullptr; // Represents the struct
1279 implInner *inner = nullptr;
1280
1281 // Save state for potential backtracking related to the optional ':' interface
1282 lex.saveState();
1283
1284 parse(second, lex); // Try to parse the struct name first
1285 if (!second) {
1286 lex.dropState(); // Drop the saved state as we failed at the very beginning of the rule
1287 panic(lex.line, lex.col, "expected struct name after `impl`");
1288 o = nullptr;
1289 return;
1290 }
1291
1292 if (lex.curToken.kind == lexer::token::tokenKind::colon) {
1293 lex.scan(); // Consume the colon
1294 parse(first, lex); // Now try to parse the interface name
1295 if (!first) {
1296 finalizeAST(second);
1297 lex.returnState(); // Backtrack because we tried to parse an interface but failed
1298 panic(lex.line, lex.col, "expected interface name after `:`");
1299 o = nullptr;
1300 return;
1301 }
1302 } else {
1303 // No colon means no interface specified, 'first' remains nullptr.
1304 // No returnState() here, as this is a successful path for the "impl struct" variant.
1305 }
1306
1307 // Now parse the inner block
1308 parse(inner, lex);
1309 if (!inner) {
1310 o = new implStmt{node_start_token, first, second, nullptr};
1311 return;
1312 }
1313
1314 lex.dropState(); // Drop state on success.
1315 o = new implStmt{node_start_token, first, second, inner};
1316 }
1317
1318 void parse(letAssignmentPair *&o, lexer &lex) {
1319 letAssignmentPairLHS *lhs = nullptr;
1320 typeSpec *type = nullptr;
1321 rExpr *rhs = nullptr;
1322 lexer::token node_start_token = lex.curToken;
1323
1324 parse(lhs, lex);
1325 if (!lhs) {
1326 panic(lex.line, lex.col, "expected left-hand-side in letAssignmentPair");
1327 o = nullptr;
1328 return;
1329 }
1330 if (lex.curToken.kind == lexer::token::tokenKind::colon) {
1331 lex.scan();
1332 parse(type, lex);
1333 if (!type) {
1334 panic(lex.line, lex.col, "expected typeSpec after `:` in letAssignmentPair");
1335 o = nullptr;
1336 return;
1337 }
1338 }
1339 if (lex.curToken.kind == lexer::token::tokenKind::assignSign) {
1340 lex.scan();
1341 } else {
1342 finalizeAST(lhs);
1343 panic(lex.line, lex.col, "expected `=` after left-hand-side in letAssignmentPair");
1344 o = nullptr;
1345 return;
1346 }
1347 parse(rhs, lex);
1348 if (!rhs) {
1349 finalizeAST(lhs);
1350 panic(lex.line, lex.col, "expected right-hand-side in letAssignmentPair");
1351 o = nullptr;
1352 return;
1353 }
1354 o = new letAssignmentPair{node_start_token, lhs, type, rhs};
1355 }
1356
1357 void parse(letAssignmentPairLHS *&o, lexer &lex) {
1358 lexer::token node_start_token = lex.curToken;
1359 if (lex.curToken.kind == lexer::token::tokenKind::identifier) {
1360 identifier *id = new identifier{lex.curToken, lex.curToken};
1361 lex.scan();
1362 o = new letAssignmentPairLHS{node_start_token, letAssignmentPairLHS::vKind::identifier, id};
1363 } else if (lex.curToken.kind == lexer::token::tokenKind::leftBracket) {
1364 lex.scan();
1366 while (true) {
1367 if (lex.curToken.kind != lexer::token::tokenKind::identifier && lex.curToken.kind != lexer::token::tokenKind::kThreeDots) {
1368 break;
1369 }
1370 vecA.push_back(lex.curToken);
1371 lex.scan();
1372 if (lex.curToken.kind == lexer::token::tokenKind::comma) {
1373 lex.scan();
1374 } else {
1375 break;
1376 }
1377 }
1378 if (lex.curToken.kind == lexer::token::tokenKind::kThreeDots) {
1379 vecA.push_back(lex.curToken);
1380 lex.scan();
1381 }
1382 yoi_assert(vecA.empty() || vecA.size() < 2 ||
1383 (vecA.front().kind != lexer::token::tokenKind::kThreeDots || vecA.back().kind != lexer::token::tokenKind::kThreeDots),
1384 lex.line,
1385 lex.col,
1386 "structured binding cannot have `...` both in the front and in the back of the list");
1387 if (vecA.size() > 2)
1388 for (yoi::indexT i = 1; i < vecA.size() - 1; i++)
1390 lex.line,
1391 lex.col,
1392 "structured binding cannot have `...` in the middle of the list");
1393
1394 yoi_assert(lex.curToken.kind == lexer::token::tokenKind::rightBracket, lex.curToken.line, lex.curToken.col, "expected `]`");
1395 lex.scan();
1396 o = new letAssignmentPairLHS{node_start_token, letAssignmentPairLHS::vKind::list, nullptr, vecA};
1397 } else {
1398 panic(lex.line, lex.col, "expected identifier or `[...]` after `let`");
1399 o = nullptr;
1400 }
1401 }
1402
1403 void parse(letStmt *&o, lexer &lex) {
1404 lexer::token node_start_token;
1405 if (lex.curToken.kind == lexer::token::tokenKind::kLet) {
1406 node_start_token = lex.curToken;
1407 lex.scan();
1408 } else {
1409 o = nullptr;
1410 return;
1411 }
1413 letAssignmentPair *a = nullptr; // Initialize a
1414
1415 while (true) {
1416 parse(a, lex);
1417 if (!a) { // If 'a' could not be parsed
1418 if (vecA.empty()) { // If it's the first assignment and it failed
1419 panic(lex.line, lex.col, "expected letAssignmentPair after `let`");
1420 } else { // If it's a subsequent assignment after a comma and it failed
1421 panic(lex.line, lex.col, "expected letAssignmentPair after comma in let statement");
1422 }
1423 finalizeAST_vec(vecA);
1424 o = nullptr;
1425 return;
1426 }
1427 vecA.push_back(a);
1428 a = nullptr; // Reset 'a' for the next parse
1429
1430 if (lex.curToken.kind == lexer::token::tokenKind::comma) {
1431 lex.scan();
1432 } else {
1433 break;
1434 }
1435 }
1436 o = new letStmt{node_start_token, vecA};
1437 }
1438
1439 void parse(globalStmt *&o, lexer &lex) {
1440 // Initialize all pointers to nullptr to avoid uninitialized checks
1441 marcoDescriptor *marco = nullptr;
1442 useStmt *a = nullptr;
1443 interfaceDefStmt *b = nullptr;
1444 structDefStmt *c = nullptr;
1445 implStmt *d = nullptr;
1446 letStmt *e = nullptr;
1447 funcDefStmt *f = nullptr;
1448 exportDecl *g = nullptr;
1449 importDecl *h = nullptr;
1450 typeAliasStmt *i = nullptr;
1451 enumerationDefinition *j = nullptr;
1452 conceptDefinition *k = nullptr;
1453
1454 lexer::token node_start_token = lex.curToken;
1455
1456 parse(marco, lex);
1457
1458 parse(a, lex);
1459 if (a) {
1460 o = new globalStmt{node_start_token, globalStmt::vKind::useStmt, marco, {a}};
1461 return;
1462 }
1463
1464 parse(b, lex);
1465 if (b) {
1466 o = new globalStmt{node_start_token, globalStmt::vKind::interfaceDefStmt, marco, {b}};
1467 return;
1468 }
1469
1470 parse(c, lex);
1471 if (c) {
1472 o = new globalStmt{node_start_token, globalStmt::vKind::structDefStmt, marco, {c}};
1473 return;
1474 }
1475
1476 dataStructDefStmt *ds = nullptr;
1477 parse(ds, lex);
1478 if (ds) {
1479 o = new globalStmt{node_start_token, globalStmt::vKind::dataStructDefStmt, marco, {ds}};
1480 return;
1481 }
1482
1483 parse(d, lex);
1484 if (d) {
1485 o = new globalStmt{node_start_token, globalStmt::vKind::implStmt, marco, {d}};
1486 return;
1487 }
1488
1489 parse(e, lex);
1490 if (e) {
1491 o = new globalStmt{node_start_token, globalStmt::vKind::letStmt, marco, {e}};
1492 return;
1493 }
1494
1495 parse(f, lex);
1496 if (f) {
1497 o = new globalStmt{node_start_token, globalStmt::vKind::funcDefStmt, marco, {f}};
1498 return;
1499 }
1500
1501 parse(g, lex);
1502 if (g) {
1503 o = new globalStmt{node_start_token, globalStmt::vKind::exportDecl, marco, {g}};
1504 return;
1505 }
1506
1507 parse(h, lex);
1508 if (h) {
1509 o = new globalStmt{node_start_token, globalStmt::vKind::importDecl, marco, {h}};
1510 return;
1511 }
1512
1513 parse(i, lex);
1514 if (i) {
1515 o = new globalStmt{node_start_token, globalStmt::vKind::typeAliasStmt, marco, {i}};
1516 return;
1517 }
1518
1519 parse(j, lex);
1520 if (j) {
1521 o = new globalStmt{node_start_token, globalStmt::vKind::enumerationDef, marco, {j}};
1522 return;
1523 }
1524
1525 parse(k, lex);
1526 if (k) {
1527 o = new globalStmt{node_start_token, globalStmt::vKind::conceptDef, marco, {k}};
1528 return;
1529 }
1530
1531 if (marco)
1532 finalizeAST(marco);
1533 o = nullptr; // No global statement matched
1534 }
1535
1536 // ifBlock parse for ifStmt
1537 void parse(ifStmt::ifBlock &o, lexer &lex) {
1538 // Initialize members to nullptr to be safe in case of early return
1539 o.cond = nullptr;
1540 o.block = nullptr;
1541
1542 if (lex.curToken.kind == lexer::token::tokenKind::leftParentheses) {
1543 lex.scan();
1544 } else {
1545 panic(lex.line, lex.col, "expected `(`");
1546 return;
1547 }
1548
1549 parse(o.cond, lex);
1550 if (!o.cond) {
1551 panic(lex.line, lex.col, "expected rExpr after `(`");
1552 return;
1553 }
1554
1555 if (lex.curToken.kind == lexer::token::tokenKind::rightParentheses) {
1556 lex.scan();
1557 } else {
1558 finalizeAST(o.cond);
1559 panic(lex.line, lex.col, "expected `)` after rExpr");
1560 return;
1561 }
1562
1563 parse(o.block, lex);
1564 if (!o.block) {
1565 finalizeAST(o.cond);
1566 panic(lex.line, lex.col, "expected codeBlock after `)`");
1567 return;
1568 }
1569 }
1570
1571 void parse(ifStmt *&o, lexer &lex) {
1572 if (lex.curToken.kind == lexer::token::tokenKind::kIf) {
1573 lexer::token node_start_token = lex.curToken;
1574 lex.scan();
1575 o = new ifStmt{node_start_token, {}, {}, nullptr}; // Create ifStmt node early for cleanup
1576 } else {
1577 o = nullptr;
1578 return;
1579 }
1580
1581 // Parse the initial ifBlock
1582 ifStmt::ifBlock temp_if_block{}; // Use a stack variable for parsing
1583 parse(temp_if_block, lex);
1584 if (!temp_if_block.cond || !temp_if_block.block) { // Check if parsing failed (parse(ifBlock) panics and returns)
1585 finalizeAST(o);
1586 o = nullptr;
1587 return;
1588 }
1589 o->ifB = temp_if_block; // Assign the struct by value (copying the pointers)
1590
1591 // Parse elif blocks
1592 while (lex.curToken.kind == lexer::token::tokenKind::kElif) {
1593 lex.scan();
1594 temp_if_block = {}; // Reset stack variable for the next elif block
1595 parse(temp_if_block, lex);
1596 if (!temp_if_block.cond || !temp_if_block.block) { // If elif block parsing failed
1597 finalizeAST(o);
1598 panic(lex.line, lex.col, "expected ifBlock after `elif`");
1599 o = nullptr;
1600 return;
1601 }
1602 o->elifB.push_back(temp_if_block); // Push a *copy* of the struct
1603 }
1604
1605 // Parse else block
1606 if (lex.curToken.kind == lexer::token::tokenKind::kElse) {
1607 lex.scan();
1608 parse(o->elseB, lex);
1609 if (!o->elseB) {
1610 finalizeAST(o);
1611 panic(lex.line, lex.col, "expected codeBlock after `else`");
1612 o = nullptr;
1613 return;
1614 }
1615 }
1616 }
1617
1618 void parse(whileStmt *&o, lexer &lex) {
1619 lexer::token node_start_token;
1620 if (lex.curToken.kind == lexer::token::tokenKind::kWhile) {
1621 node_start_token = lex.curToken;
1622 lex.scan();
1623 } else {
1624 o = nullptr;
1625 return;
1626 }
1627
1628 rExpr *expr = nullptr;
1629 codeBlock *block = nullptr;
1630
1631 if (lex.curToken.kind == lexer::token::tokenKind::leftParentheses) {
1632 lex.scan();
1633 } else {
1634 panic(lex.line, lex.col, "expected `(` after `while`");
1635 o = nullptr;
1636 return;
1637 }
1638
1639 parse(expr, lex);
1640 if (!expr) {
1641 panic(lex.line, lex.col, "expected rExpr after `(`");
1642 o = nullptr;
1643 return;
1644 }
1645
1646 if (lex.curToken.kind == lexer::token::tokenKind::rightParentheses) {
1647 lex.scan();
1648 } else {
1649 finalizeAST(expr);
1650 panic(lex.line, lex.col, "expected `)` after rExpr");
1651 o = nullptr;
1652 return;
1653 }
1654
1655 parse(block, lex);
1656 if (!block) {
1657 finalizeAST(expr);
1658 panic(lex.line, lex.col, "expected codeBlock after `)`");
1659 o = nullptr;
1660 return;
1661 }
1662
1663 o = new whileStmt{node_start_token, expr, block};
1664 }
1665
1666 void parse(forStmt *&o, lexer &lex) {
1667 lexer::token node_start_token;
1668 if (lex.curToken.kind == lexer::token::tokenKind::kFor) {
1669 node_start_token = lex.curToken;
1670 lex.scan();
1671 } else {
1672 o = nullptr;
1673 return;
1674 }
1675
1676 inCodeBlockStmt *initStmt = nullptr;
1677 rExpr *cond = nullptr;
1678 inCodeBlockStmt *afterStmt = nullptr;
1679 codeBlock *block = nullptr;
1680
1681 if (lex.curToken.kind == lexer::token::tokenKind::leftParentheses) {
1682 lex.scan();
1683 } else {
1684 panic(lex.line, lex.col, "expected `(` after `for`");
1685 o = nullptr;
1686 return;
1687 }
1688
1689 parse(initStmt, lex);
1690 // Original code implies initStmt can be empty. "expected initStmt" panic removed if this is allowed.
1691
1692 // Reconciling with original panic: it seems intended to be mandatory.
1693 if (!initStmt) {
1694 panic(lex.line, lex.col, "expected initStmt after `(`");
1695 o = nullptr;
1696 return;
1697 }
1698
1699 if (lex.curToken.kind == lexer::token::tokenKind::semicolon) {
1700 lex.scan();
1701 } else {
1702 finalizeAST(initStmt);
1703 panic(lex.line, lex.col, "expected `;` after initStmt");
1704 o = nullptr;
1705 return;
1706 }
1707
1708 parse(cond, lex);
1709
1710 if (!cond) {
1711 finalizeAST(initStmt);
1712 panic(lex.line, lex.col, "expected condition after `;`");
1713 o = nullptr;
1714 return;
1715 }
1716
1717 if (lex.curToken.kind == lexer::token::tokenKind::semicolon) {
1718 lex.scan();
1719 } else {
1720 finalizeAST(initStmt);
1721 finalizeAST(cond);
1722 panic(lex.line, lex.col, "expected `;` after condition");
1723 o = nullptr;
1724 return;
1725 }
1726
1727 parse(afterStmt, lex);
1728 if (!afterStmt) {
1729 finalizeAST(initStmt);
1730 finalizeAST(cond);
1731 panic(lex.line, lex.col, "expected afterStmt after `;`");
1732 o = nullptr;
1733 return;
1734 }
1735
1736 if (lex.curToken.kind == lexer::token::tokenKind::rightParentheses) {
1737 lex.scan();
1738 } else {
1739 finalizeAST(initStmt);
1740 finalizeAST(cond);
1741 finalizeAST(afterStmt);
1742 panic(lex.line, lex.col, "expected `)` after afterStmt");
1743 o = nullptr;
1744 return;
1745 }
1746 parse(block, lex);
1747 if (!block) {
1748 finalizeAST(initStmt);
1749 finalizeAST(cond);
1750 finalizeAST(afterStmt);
1751 panic(lex.line, lex.col, "expected codeBlock after `)`");
1752 o = nullptr;
1753 return;
1754 }
1755 o = new forStmt{node_start_token, initStmt, cond, afterStmt, block};
1756 }
1757
1758 void parse(forEachStmt *&o, lexer &lex) {
1759 lexer::token node_start_token;
1760 if (lex.curToken.kind == lexer::token::tokenKind::kForEach) {
1761 node_start_token = lex.curToken;
1762 lex.scan();
1763 } else {
1764 o = nullptr;
1765 return;
1766 }
1767 // Initialize children to nullptr
1768 identifier *var = nullptr;
1769 rExpr *container = nullptr;
1770 codeBlock *block = nullptr;
1771
1772 if (lex.curToken.kind == lexer::token::tokenKind::leftParentheses) {
1773 lex.scan();
1774 } else {
1775 panic(lex.line, lex.col, "expected `(` after `forEach`");
1776 o = nullptr;
1777 return;
1778 }
1779 parse(var, lex);
1780 if (!var) {
1781 panic(lex.line, lex.col, "expected variable name after `(`");
1782 o = nullptr;
1783 return;
1784 }
1785 if (lex.curToken.kind == lexer::token::tokenKind::colon) {
1786 lex.scan();
1787 } else {
1788 finalizeAST(var);
1789 panic(lex.line, lex.col, "expected `:` after variable name");
1790 o = nullptr;
1791 return;
1792 }
1793 parse(container, lex);
1794 if (!container) {
1795 finalizeAST(var);
1796 panic(lex.line, lex.col, "expected container after `:`");
1797 o = nullptr;
1798 return;
1799 }
1800 if (lex.curToken.kind == lexer::token::tokenKind::rightParentheses) {
1801 lex.scan();
1802 } else {
1803 finalizeAST(var);
1804 finalizeAST(container);
1805 panic(lex.line, lex.col, "expected `)` after container");
1806 o = nullptr;
1807 return;
1808 }
1809 parse(block, lex);
1810 if (!block) {
1811 finalizeAST(var);
1812 finalizeAST(container);
1813 panic(lex.line, lex.col, "expected codeBlock after `)`");
1814 o = nullptr;
1815 return;
1816 }
1817 o = new forEachStmt{node_start_token, var, container, block};
1818 }
1819
1820 void parse(returnStmt *&o, lexer &lex) {
1821 if (lex.curToken.kind == lexer::token::tokenKind::kReturn) {
1822 lexer::token node_start_token = lex.curToken;
1823 lex.scan();
1824 rExpr *expr = nullptr;
1825 parse(expr, lex); // expr is optional
1826 o = new returnStmt{node_start_token, expr};
1827 } else {
1828 o = nullptr;
1829 }
1830 }
1831
1832 void parse(continueStmt *&o, lexer &lex) {
1833 if (lex.curToken.kind == lexer::token::tokenKind::kContinue) {
1834 lexer::token node_start_token = lex.curToken;
1835 lex.scan();
1836 o = new continueStmt{node_start_token}; // Add token for consistency
1837 } else {
1838 o = nullptr;
1839 return;
1840 }
1841 }
1842
1843 void parse(breakStmt *&o, lexer &lex) {
1844 if (lex.curToken.kind == lexer::token::tokenKind::kBreak) {
1845 lexer::token node_start_token = lex.curToken;
1846 lex.scan();
1847 o = new breakStmt{node_start_token}; // Add token for consistency
1848 } else {
1849 o = nullptr;
1850 return;
1851 }
1852 }
1853
1854 void parse(inCodeBlockStmt *&o, lexer &lex) {
1855 // Initialize all potential children to nullptr before trying to parse
1856 marcoDescriptor *marco = nullptr;
1857 letStmt *letStmtVal = nullptr;
1858 ifStmt *ifStmtVal = nullptr;
1859 breakStmt *breakStmtVal = nullptr;
1860 continueStmt *continueStmtVal = nullptr;
1861 returnStmt *returnStmtVal = nullptr;
1862 forEachStmt *forEachStmtVal = nullptr;
1863 whileStmt *whileStmtVal = nullptr;
1864 forStmt *forStmtVal = nullptr;
1865 codeBlock *codeBlockVal = nullptr;
1866 tryCatchStmt *tryCatchStmtVal = nullptr;
1867 throwStmt *throwStmtVal = nullptr;
1868 yieldStmt *yieldStmtVal = nullptr;
1869 rExpr *rExprVal = nullptr;
1870
1871 lexer::token node_start_token = lex.curToken;
1872
1873 parse(marco, lex);
1874
1875 // Try parsing each type, and if successful, create the inCodeBlockStmt and return.
1876 // This avoids creating the inCodeBlockStmt node until a successful child parse.
1877
1878 parse(letStmtVal, lex);
1879 if (letStmtVal) {
1880 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::letStmt, marco, {letStmtVal}};
1881 return;
1882 }
1883 parse(ifStmtVal, lex);
1884 if (ifStmtVal) {
1885 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::ifStmt, marco, {ifStmtVal}};
1886 return;
1887 }
1888 parse(breakStmtVal, lex);
1889 if (breakStmtVal) {
1890 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::breakStmt, marco, {breakStmtVal}};
1891 return;
1892 }
1893 parse(continueStmtVal, lex);
1894 if (continueStmtVal) {
1895 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::continueStmt, marco, {continueStmtVal}};
1896 return;
1897 }
1898 parse(returnStmtVal, lex);
1899 if (returnStmtVal) {
1900 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::returnStmt, marco, {returnStmtVal}};
1901 return;
1902 }
1903 parse(forEachStmtVal, lex); // Only parse once
1904 if (forEachStmtVal) {
1905 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::forEachStmt, marco, {forEachStmtVal}};
1906 return;
1907 }
1908 parse(whileStmtVal, lex);
1909 if (whileStmtVal) {
1910 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::whileStmt, marco, {whileStmtVal}};
1911 return;
1912 }
1913
1914 parse(forStmtVal, lex);
1915 if (forStmtVal) {
1916 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::forStmt, marco, {forStmtVal}};
1917 return;
1918 }
1919
1920 parse(tryCatchStmtVal, lex);
1921 if (tryCatchStmtVal) {
1922 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::tryCatchStmt, marco, {tryCatchStmtVal}};
1923 return;
1924 }
1925
1926 parse(throwStmtVal, lex);
1927 if (throwStmtVal) {
1928 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::throwStmt, marco, {throwStmtVal}};
1929 return;
1930 }
1931
1932 parse(codeBlockVal, lex);
1933 if (codeBlockVal) {
1934 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::codeBlock, marco, {codeBlockVal}};
1935 return;
1936 }
1937
1938 parse(yieldStmtVal, lex);
1939 if (yieldStmtVal) {
1940 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::yieldStmt, marco, {yieldStmtVal}};
1941 return;
1942 }
1943
1944 // rExpr should typically be last, as it's the most general expression statement.
1945 parse(rExprVal, lex);
1946 if (rExprVal) {
1947 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::rExpr, marco, {rExprVal}};
1948 return;
1949 }
1950
1951 if (marco)
1952 finalizeAST(marco);
1953 o = nullptr; // If no statement type matched
1954 }
1955
1956 void parse(innerMethodDecl *&o, lexer &lex) {
1957 lex.saveState();
1958 lexer::token node_start_token = lex.curToken;
1959
1960 o = new innerMethodDecl{node_start_token, {}, nullptr, nullptr, nullptr};
1961
1962 while (lex.curToken.kind >= lexer::token::tokenKind::kNoFFI && lex.curToken.kind <= lexer::token::tokenKind::kAlwaysInline) {
1963 o->attrs.push_back(lex.curToken);
1964 lex.scan();
1965 }
1966
1967 parse(o->name, lex);
1968 if (!o->name) {
1969 lex.returnState();
1970 delete o; // Delete the partially constructed node
1971 o = nullptr;
1972 return;
1973 }
1974 parse(o->args, lex);
1975 if (!o->args) {
1976 finalizeAST(o->name);
1977 lex.returnState();
1978 delete o;
1979 o = nullptr;
1980 return;
1981 }
1982 if (lex.curToken.kind == lexer::token::tokenKind::colon) {
1983 lex.scan();
1984 } else {
1985 finalizeAST(o->name);
1986 finalizeAST(o->args);
1987 lex.returnState();
1988 delete o;
1989 o = nullptr;
1990 return;
1991 }
1992 parse(o->resultType, lex);
1993 if (!o->resultType) {
1994 finalizeAST(o->name);
1995 finalizeAST(o->args);
1996 lex.returnState();
1997 delete o;
1998 o = nullptr;
1999 return;
2000 }
2001 lex.dropState();
2002 }
2003
2004 void parse(innerMethodDef *&o, lexer &lex) {
2005 lex.saveState();
2006 lexer::token node_start_token = lex.curToken;
2007
2008 o = new innerMethodDef{node_start_token, {}, nullptr, nullptr, nullptr, nullptr};
2009
2010 while (lex.curToken.kind >= lexer::token::tokenKind::kNoFFI && lex.curToken.kind <= lexer::token::tokenKind::kAlwaysInline) {
2011 o->attrs.push_back(lex.curToken);
2012 lex.scan();
2013 }
2014
2015 parse(o->name, lex);
2016 if (!o->name) {
2017 lex.returnState();
2018 delete o;
2019 o = nullptr;
2020 return;
2021 }
2022 parse(o->args, lex);
2023 if (!o->args) {
2024 finalizeAST(o->name);
2025 lex.returnState();
2026 delete o;
2027 o = nullptr;
2028 return;
2029 }
2030 if (lex.curToken.kind == lexer::token::tokenKind::colon) {
2031 lex.scan();
2032 } else {
2033 finalizeAST(o->name);
2034 finalizeAST(o->args);
2035 lex.returnState();
2036 delete o;
2037 o = nullptr;
2038 return;
2039 }
2040 parse(o->resultType, lex);
2041 if (!o->resultType) {
2042 finalizeAST(o->name);
2043 finalizeAST(o->args);
2044 lex.returnState();
2045 delete o;
2046 o = nullptr;
2047 return;
2048 }
2049 parse(o->block, lex);
2050 if (!o->block) {
2051 finalizeAST(o->name);
2052 finalizeAST(o->args);
2053 finalizeAST(o->resultType);
2054 lex.returnState();
2055 delete o;
2056 o = nullptr;
2057 return;
2058 }
2059 lex.dropState();
2060 }
2061
2062 void parse(constructorDecl *&o, lexer &lex) {
2063 lexer::token node_start_token;
2064 if (lex.curToken.kind == lexer::token::tokenKind::kConstructor) {
2065 node_start_token = lex.curToken;
2066 lex.scan();
2067 } else {
2068 o = nullptr;
2069 return;
2070 }
2071 defTemplateArg *tempArg = nullptr;
2072 if (lex.curToken.kind == lexer::token::tokenKind::lessThan) {
2073 parse(tempArg, lex);
2074 if (!tempArg) {
2075 panic(lex.line, lex.col, "expected template argument after `<` in constructor declaration");
2076 o = nullptr;
2077 return;
2078 }
2079 }
2080 definitionArguments *args = nullptr;
2081 parse(args, lex);
2082 if (!args) {
2083 panic(lex.line, lex.col, "expected arguments after `constructor`");
2084 o = nullptr;
2085 return;
2086 }
2087 if (lex.curToken.kind == lexer::token::tokenKind::colon) {
2088 finalizeAST(args);
2089 panic(lex.line, lex.col, "constructor declaration cannot have a return type");
2090 o = nullptr;
2091 }
2092 o = new constructorDecl{node_start_token, tempArg, args};
2093 }
2094
2095 void parse(constructorDef *&o, lexer &lex) {
2096 lexer::token node_start_token;
2097 if (lex.curToken.kind == lexer::token::tokenKind::kConstructor) {
2098 node_start_token = lex.curToken;
2099 lex.scan();
2100 } else {
2101 o = nullptr;
2102 return;
2103 }
2104 templateArg *tempArg = nullptr;
2105 definitionArguments *args = nullptr;
2106 codeBlock *block = nullptr;
2107
2108 if (lex.curToken.kind == lexer::token::tokenKind::lessThan) {
2109 parse(tempArg, lex);
2110 if (!tempArg) {
2111 panic(lex.line, lex.col, "expected template argument after `<` in constructor definition");
2112 o = nullptr;
2113 return;
2114 }
2115 }
2116 parse(args, lex);
2117 if (!args) {
2118 panic(lex.line, lex.col, "expected arguments after `constructor`");
2119 o = nullptr;
2120 return;
2121 }
2122 if (lex.curToken.kind == lexer::token::tokenKind::colon) {
2123 finalizeAST(args);
2124 panic(lex.line, lex.col, "constructor declaration cannot have a return type");
2125 o = nullptr;
2126 }
2127 parse(block, lex);
2128 if (!block) {
2129 finalizeAST(args);
2130 panic(lex.line, lex.col, "expected codeBlock after arguments");
2131 o = nullptr;
2132 return;
2133 }
2134 o = new constructorDef{node_start_token, tempArg, args, block};
2135 }
2136
2137 void parse(hoshiModule *&o, lexer &lex) {
2139 globalStmt *a = nullptr; // Initialize a
2140
2141 lexer::token node_start_token = lex.curToken;
2142
2143 while (true) {
2144 if (lex.curToken.kind == lexer::token::tokenKind::eof)
2145 break;
2146 parse(a, lex);
2147 if (!a) { // If parsing a global statement fails, it's an error.
2148 finalizeAST_vec(vecA);
2149 panic(lex.line, lex.col, "expected globalStmt");
2150 o = nullptr;
2151 return;
2152 }
2153 vecA.push_back(a);
2154 a = nullptr; // Reset 'a' for the next parse call
2155 }
2156 o = new hoshiModule{node_start_token, vecA};
2157 }
2158
2159 void parse(importDecl *&o, lexer &lex) {
2160 lexer::token node_start_token;
2161 if (lex.curToken.kind == lexer::token::tokenKind::kImport) {
2162 lexer::token node_start_token = lex.curToken;
2163 lex.scan();
2164 } else {
2165 o = nullptr; // Consistent with other functions
2166 return;
2167 }
2168
2169 innerMethodDecl *a = nullptr;
2170 parse(a, lex);
2171 if (!a) {
2172 panic(lex.line, lex.col, "expected innerMethodDecl after `import`"); // Corrected panic message
2173 o = nullptr;
2174 return;
2175 }
2176
2177 o = new importDecl{node_start_token, a}; // Create the node here, now that 'a' is successfully parsed
2178
2179 if (lex.curToken.kind == lexer::token::tokenKind::kFrom) {
2180 lex.scan(); // Consume 'from'
2181 if (lex.curToken.kind == lexer::token::tokenKind::string) {
2182 o->from_path = lex.curToken;
2183 lex.scan(); // Consume string
2184 } else {
2185 finalizeAST(o);
2186 panic(lex.line, lex.col, "expected string literal after `from` in import declaration");
2187 o = nullptr;
2188 return;
2189 }
2190 } else {
2191 finalizeAST(o);
2192 panic(lex.line, lex.col, "expected `from` after import declaration");
2193 o = nullptr;
2194 return;
2195 }
2196 }
2197
2198 void parse(exportDecl *&o, lexer &lex) {
2199 lexer::token node_start_token;
2200 if (lex.curToken.kind == lexer::token::tokenKind::kExport) {
2201 node_start_token = lex.curToken;
2202 lex.scan();
2203 } else {
2204 o = nullptr; // Consistent
2205 return;
2206 }
2207
2209 while (lex.curToken.kind >= lexer::token::tokenKind::kNoFFI && lex.curToken.kind <= lexer::token::tokenKind::kAlwaysInline) {
2210 attrs.push_back(lex.curToken);
2211 lex.scan();
2212 }
2213
2214 typeSpec *a = nullptr;
2215 parse(a, lex);
2216 if (!a) {
2217 panic(lex.line, lex.col, "expected typeSpec after `export`"); // Corrected panic message
2218 o = nullptr;
2219 return;
2220 }
2221
2222 o = new exportDecl{node_start_token, attrs, a, nullptr}; // Create the node here, now that 'a' is parsed.
2223
2224 if (lex.curToken.kind == lexer::token::tokenKind::kAs) {
2225 lex.scan(); // Consume 'as'
2226 identifier *b = nullptr;
2227 parse(b, lex);
2228 if (!b) {
2229 finalizeAST(o);
2230 panic(lex.line, lex.col, "expected identifier after `as` in export declaration");
2231 o = nullptr;
2232 return;
2233 }
2234 o->as = b;
2235 } else {
2236 finalizeAST(o);
2237 panic(lex.line, lex.col, "expected `as` after export declaration");
2238 o = nullptr;
2239 return;
2240 }
2241 }
2242
2243 void parse(tryCatchStmt *&o, lexer &lex) {
2244 if (lex.curToken.kind != lexer::token::tokenKind::kTry) {
2245 o = nullptr;
2246 return;
2247 }
2248 lexer::token node_start_token = lex.curToken;
2249 lex.scan();
2250 codeBlock *tryBlock = nullptr;
2251 parse(tryBlock, lex);
2252 yoi_assert(tryBlock, lex.line, lex.col, "expected codeBlock after `try`");
2253 yoi::vec<catchParam *> catchParams;
2254 while (lex.curToken.kind == lexer::token::tokenKind::kCatch) {
2255 catchParam *param;
2256 parse(param, lex);
2257 if (!param) {
2258 finalizeAST(tryBlock);
2259 o = nullptr;
2260 panic(lex.line, lex.col, "expected catchParam after `catch`");
2261 }
2262 catchParams.push_back(param);
2263 }
2264 codeBlock *finallyBlock = nullptr;
2265 parse(finallyBlock, lex);
2266 if (!finallyBlock) {
2267 finalizeAST(tryBlock);
2268 for (auto p : catchParams)
2269 finalizeAST(p);
2270 o = nullptr;
2271 panic(lex.line, lex.col, "expected codeBlock after `catch`");
2272 }
2273 o = new tryCatchStmt{node_start_token, tryBlock, catchParams, finallyBlock};
2274 }
2275
2276 void parse(throwStmt *&o, lexer &lex) {
2277 if (lex.curToken.kind != lexer::token::tokenKind::kThrow) {
2278 o = nullptr;
2279 return;
2280 }
2281 lexer::token node_start_token = lex.curToken;
2282 lex.scan();
2283 rExpr *expr = nullptr;
2284 parse(expr, lex);
2285 if (!expr) {
2286 o = nullptr;
2287 panic(lex.line, lex.col, "expected expression after `throw`");
2288 }
2289 o = new throwStmt{node_start_token, expr};
2290 }
2291
2292 void parse(catchParam *&o, lexer &lex) {
2293 if (lex.curToken.kind != lexer::token::tokenKind::kCatch) {
2294 o = nullptr;
2295 return;
2296 }
2297 lexer::token node_start_token = lex.curToken;
2298 lex.scan();
2299 if (lex.curToken.kind != lexer::token::tokenKind::leftParentheses) {
2300 o = nullptr;
2301 panic(lex.line, lex.col, "expected `(` after `catch`");
2302 }
2303 lex.scan();
2304 identifier *name = nullptr;
2305 parse(name, lex);
2306 if (!name) {
2307 o = nullptr;
2308 panic(lex.line, lex.col, "expected identifier after typeSpec in catchParam");
2309 }
2310 if (lex.curToken.kind != lexer::token::tokenKind::colon) {
2311 o = nullptr;
2312 finalizeAST(name);
2313 panic(lex.line, lex.col, "expected `)` after identifier in catchParam");
2314 }
2315 lex.scan();
2316 typeSpec *type = nullptr;
2317 parse(type, lex);
2318 if (!type) {
2319 o = nullptr;
2320 finalizeAST(name);
2321 panic(lex.line, lex.col, "expected typeSpec after `(` in catchParam");
2322 }
2323 if (lex.curToken.kind != lexer::token::tokenKind::rightParentheses) {
2324 o = nullptr;
2325 finalizeAST(name);
2326 finalizeAST(type);
2327 panic(lex.line, lex.col, "expected `)` after typeSpec in catchParam");
2328 }
2329 lex.scan();
2330 codeBlock *block = nullptr;
2331 parse(block, lex);
2332 if (!block) {
2333 o = nullptr;
2334 finalizeAST(type);
2335 finalizeAST(name);
2336 panic(lex.line, lex.col, "expected codeBlock after identifier in catchParam");
2337 }
2338 o = new catchParam{node_start_token, type, name, block};
2339 }
2340
2341 void parse(typeIdExpression *&o, lexer &lex) {
2342 if (lex.curToken.kind != lexer::token::tokenKind::kTypeId) {
2343 o = nullptr;
2344 return;
2345 }
2346 lexer::token node_start_token = lex.curToken;
2347 lex.scan();
2348 if (lex.curToken.kind == lexer::token::tokenKind::leftParentheses) {
2349 lex.scan();
2350 rExpr *expr = nullptr;
2351 parse(expr, lex);
2352 if (!expr) {
2353 o = nullptr;
2354 panic(lex.line, lex.col, "expected expression after `(` in `type_id` expression");
2355 }
2356 if (lex.curToken.kind != lexer::token::tokenKind::rightParentheses) {
2357 o = nullptr;
2358 finalizeAST(expr);
2359 panic(lex.line, lex.col, "expected `)` after expression in `type_id` expression");
2360 }
2361 lex.scan();
2362 o = new typeIdExpression{node_start_token, nullptr, expr};
2363 } else if (lex.curToken.kind == lexer::token::tokenKind::lessThan) {
2364 lex.scan();
2365 typeSpec *type = nullptr;
2366 parse(type, lex);
2367 if (!type) {
2368 o = nullptr;
2369 panic(lex.line, lex.col, "expected typeSpec after `<` in `type_id` expression");
2370 }
2371 if (lex.curToken.kind != lexer::token::tokenKind::greaterThan) {
2372 o = nullptr;
2373 finalizeAST(type);
2374 panic(lex.line, lex.col, "expected `>` after typeSpec in `type_id` expression");
2375 }
2376 lex.scan();
2377 o = new typeIdExpression{node_start_token, type, nullptr};
2378 } else {
2379 o = nullptr;
2380 panic(lex.line, lex.col, "expected `(` or `<` after `type_id` in `type_id` expression");
2381 }
2382 }
2383
2384 void parse(dynCastExpression *&o, lexer &lex) {
2385 if (lex.curToken.kind != lexer::token::tokenKind::kDynCast) {
2386 o = nullptr;
2387 return;
2388 }
2389 lexer::token node_start_token = lex.curToken;
2390 lex.scan();
2391 if (lex.curToken.kind != lexer::token::tokenKind::lessThan) {
2392 o = nullptr;
2393 panic(lex.line, lex.col, "expected `<` after `dyn_cast`");
2394 }
2395 lex.scan();
2396 typeSpec *type = nullptr;
2397 parse(type, lex);
2398 if (!type) {
2399 o = nullptr;
2400 panic(lex.line, lex.col, "expected typeSpec after `<` in `dyn_cast` expression");
2401 }
2402 if (lex.curToken.kind != lexer::token::tokenKind::greaterThan) {
2403 o = nullptr;
2404 finalizeAST(type);
2405 panic(lex.line, lex.col, "expected `>` after typeSpec in `dyn_cast` expression");
2406 }
2407 lex.scan();
2408 if (lex.curToken.kind != lexer::token::tokenKind::leftParentheses) {
2409 o = nullptr;
2410 finalizeAST(type);
2411 panic(lex.line, lex.col, "expected `(` after `>` in `dyn_cast` expression");
2412 }
2413 lex.scan();
2414 rExpr *expr = nullptr;
2415 parse(expr, lex);
2416 if (!expr) {
2417 o = nullptr;
2418 finalizeAST(type);
2419 panic(lex.line, lex.col, "expected expression after `(` in `dyn_cast` expression");
2420 }
2421 if (lex.curToken.kind != lexer::token::tokenKind::rightParentheses) {
2422 o = nullptr;
2423 finalizeAST(type);
2424 finalizeAST(expr);
2425 panic(lex.line, lex.col, "expected `)` after expression in `dyn_cast` expression");
2426 }
2427 lex.scan();
2428 o = new dynCastExpression{node_start_token, type, expr};
2429 }
2430
2431 void parse(abstractExpr *&o, lexer &lex) {
2432 lexer::token node_start_token = lex.curToken;
2433 primary *lhs{};
2434 parse(lhs, lex);
2435 if (!lhs) {
2436 o = nullptr;
2437 return;
2438 }
2439 if (lex.curToken.kind != lexer::token::tokenKind::kInterfaceOf && lex.curToken.kind != lexer::token::tokenKind::kImpl &&
2440 lex.curToken.kind != lexer::token::tokenKind::kAs) {
2441 o = new abstractExpr{node_start_token, lhs, {}, nullptr};
2442 return;
2443 }
2444 o = new abstractExpr{node_start_token, lhs, lex.curToken, nullptr};
2445 lex.scan();
2446
2447 parse(o->rhs, lex);
2448 if (!o->rhs) {
2449 finalizeAST(o);
2450 o = nullptr;
2451 panic(lex.line, lex.col, "expected extern module access expression after `interfaceof` or `impl`");
2452 }
2453 }
2454
2455 void parse(lambdaExpr *&o, lexer &lex) {
2456 lexer::token node_start_token = lex.curToken;
2457 if (lex.curToken.kind != lexer::token::tokenKind::kFunc) {
2458 o = nullptr;
2459 return;
2460 }
2461 lex.saveState();
2462 lex.scan();
2463 if (lex.curToken.kind != lexer::token::tokenKind::leftBracket) {
2464 o = nullptr;
2465 lex.returnState();
2466 return;
2467 }
2468 lex.scan();
2469 vec<yoi::lambdaCapture *> captures;
2470 while (lex.curToken.kind != lexer::token::tokenKind::rightBracket) {
2471 yoi::lambdaCapture *capture = nullptr;
2472 parse(capture, lex);
2473 if (!capture) {
2474 for (auto c : captures)
2475 finalizeAST(c);
2476 o = nullptr;
2477 panic(lex.line, lex.col, "expected identifier in capture list in lambda expression");
2478 }
2479 captures.push_back(capture);
2480 if (lex.curToken.kind != lexer::token::tokenKind::comma) {
2481 break;
2482 }
2483 lex.scan();
2484 }
2485 if (lex.curToken.kind != lexer::token::tokenKind::rightBracket) {
2486 o = nullptr;
2487 panic(lex.line, lex.col, "expected `]` after capture list in lambda expression");
2488 }
2489 lex.scan();
2490 definitionArguments *args = nullptr;
2491 parse(args, lex);
2492 if (!args) {
2493 o = nullptr;
2494 panic(lex.line, lex.col, "expected arguments after capture list in lambda expression");
2495 }
2496 if (lex.curToken.kind != lexer::token::tokenKind::colon) {
2497 o = nullptr;
2498 finalizeAST(args);
2499 panic(lex.line, lex.col, "expected `:` after arguments in lambda expression");
2500 }
2501 lex.scan();
2502 typeSpec *resultType = nullptr;
2503 parse(resultType, lex);
2504 if (!resultType) {
2505 o = nullptr;
2506 finalizeAST(args);
2507 panic(lex.line, lex.col, "expected typeSpec after `:` in lambda expression");
2508 }
2509 codeBlock *block = nullptr;
2510 parse(block, lex);
2511 if (!block) {
2512 o = nullptr;
2513 finalizeAST(args);
2514 finalizeAST(resultType);
2515 panic(lex.line, lex.col, "expected codeBlock after `:` in lambda expression");
2516 }
2517 lex.dropState();
2518 o = new lambdaExpr{node_start_token, captures, args, resultType, block};
2519 }
2520
2521 void parse(unnamedDefinitionArguments *&o, lexer &lex) {
2522 if (lex.curToken.kind != lexer::token::tokenKind::leftParentheses) {
2523 o = nullptr;
2524 return;
2525 }
2526 lexer::token node_start_token = lex.curToken;
2527 lex.scan();
2528 vec<typeSpec *> types;
2529 while (true) {
2530 typeSpec *type = nullptr;
2531 parse(type, lex);
2532 if (!type) {
2533 o = nullptr;
2534 break;
2535 }
2536 types.push_back(type);
2537 if (lex.curToken.kind != lexer::token::tokenKind::comma) {
2538 break;
2539 }
2540 lex.scan();
2541 }
2542 if (lex.curToken.kind != lexer::token::tokenKind::rightParentheses) {
2543 o = nullptr;
2544 for (auto t : types)
2545 finalizeAST(t);
2546 panic(lex.line, lex.col, "expected `)` after typeSpecs in unnamed definition arguments");
2547 }
2548 lex.scan();
2549 o = new unnamedDefinitionArguments{node_start_token, types};
2550 }
2551
2552 void parse(marcoPair *&o, lexer &lex) {
2553 lexer::token node_start_token = lex.curToken;
2554 lex.saveState();
2555 lexer::token lhs, constraint, rhs;
2556 if (lex.curToken.kind == lexer::token::tokenKind::identifier) {
2557 lhs = lex.curToken;
2558 } else {
2559 lex.returnState();
2560 o = nullptr;
2561 return;
2562 }
2563 lex.scan();
2564 switch (lex.curToken.kind) {
2571 constraint = lex.curToken;
2572 break;
2573 }
2574 default: {
2575 lex.returnState();
2576 o = nullptr;
2577 return;
2578 }
2579 }
2580 lex.scan();
2581 switch (lex.curToken.kind) {
2586 rhs = lex.curToken;
2587 break;
2588 }
2589 default: {
2590 lex.returnState();
2591 o = nullptr;
2592 return;
2593 }
2594 }
2595 lex.scan();
2596 lex.dropState();
2597 o = new marcoPair{node_start_token, lhs, constraint, rhs};
2598 }
2599
2600 void parse(marcoDescriptor *&o, lexer &lex) {
2601 lexer::token current_token = lex.curToken;
2602 lex.saveState();
2603 if (current_token.kind != lexer::token::tokenKind::leftBracket) {
2604 lex.returnState();
2605 o = new marcoDescriptor{current_token, {}};
2606 return;
2607 }
2608 lex.scan();
2609 if (lex.curToken.kind != lexer::token::tokenKind::leftBracket) {
2610 lex.returnState();
2611 o = new marcoDescriptor{current_token, {}};
2612 return;
2613 }
2614 lex.scan();
2615 vec<marcoPair *> pairs;
2616 marcoPair *pair = nullptr;
2617 parse(pair, lex);
2618 while (pair) {
2619 pairs.push_back(pair);
2620 pair = nullptr;
2621 parse(pair, lex);
2622 }
2623 if (lex.curToken.kind != lexer::token::tokenKind::rightBracket) {
2624 o = nullptr;
2625 for (auto p : pairs)
2626 finalizeAST(p);
2627 return;
2628 }
2629 lex.scan();
2630 if (lex.curToken.kind != lexer::token::tokenKind::rightBracket) {
2631 o = nullptr;
2632 for (auto p : pairs)
2633 finalizeAST(p);
2634 return;
2635 }
2636 lex.scan();
2637 lex.dropState();
2638 o = new marcoDescriptor{current_token, pairs};
2639 }
2640
2641 void parse(typeAliasStmt *&o, lexer &lex) {
2642 lexer::token node_start_token = lex.curToken;
2643 if (lex.curToken.kind != lexer::token::tokenKind::kAlias) {
2644 o = nullptr;
2645 return;
2646 }
2647 lex.scan();
2648 identifierWithDefTemplateArg *lhs;
2649 parse(lhs, lex);
2650 if (!lhs) {
2651 panic(lex.line, lex.col, "expected identifier with definition template arguments in type alias statement");
2652 o = nullptr;
2653 return;
2654 }
2655 if (lex.curToken.kind != lexer::token::tokenKind::assignSign) {
2656 o = nullptr;
2657 finalizeAST(lhs);
2658 panic(lex.line, lex.col, "expected `=` after identifier in type alias statement");
2659 return;
2660 }
2661 lex.scan();
2662 typeSpec *rhs = nullptr;
2663 parse(rhs, lex);
2664 if (!rhs) {
2665 o = nullptr;
2666 finalizeAST(lhs);
2667 panic(lex.line, lex.col, "expected typeSpec after `=` in type alias statement");
2668 return;
2669 }
2670 o = new typeAliasStmt{node_start_token, lhs, rhs};
2671 }
2672
2673 void parse(finalizerDecl *&o, lexer &lex) {
2674 lexer::token node_start_token = lex.curToken;
2675 if (lex.curToken.kind != lexer::token::tokenKind::kFinalizer) {
2676 o = nullptr;
2677 return;
2678 }
2679 lex.scan();
2680 if (lex.curToken.kind != lexer::token::tokenKind::leftParentheses) {
2681 o = nullptr;
2682 panic(lex.line, lex.col, "expected `(` after `finalizer` in finalizer declaration");
2683 }
2684 lex.scan();
2685 if (lex.curToken.kind != lexer::token::tokenKind::rightParentheses) {
2686 o = nullptr;
2687 panic(lex.line, lex.col, "expected `)` after `finalizer` in finalizer declaration");
2688 }
2689 lex.scan();
2690 o = new finalizerDecl{node_start_token};
2691 }
2692
2693 void parse(finalizerDef *&o, lexer &lex) {
2694 lexer::token node_start_token = lex.curToken;
2695 if (lex.curToken.kind != lexer::token::tokenKind::kFinalizer) {
2696 o = nullptr;
2697 return;
2698 }
2699 lex.scan();
2700 if (lex.curToken.kind != lexer::token::tokenKind::leftParentheses) {
2701 o = nullptr;
2702 panic(lex.line, lex.col, "expected `(` after `finalizer` in finalizer definition");
2703 }
2704 lex.scan();
2705 if (lex.curToken.kind != lexer::token::tokenKind::rightParentheses) {
2706 o = nullptr;
2707 panic(lex.line, lex.col, "expected `)` after `finalizer` in finalizer definition");
2708 }
2709 lex.scan();
2710 codeBlock *block = nullptr;
2711 parse(block, lex);
2712 if (!block) {
2713 o = nullptr;
2714 panic(lex.line, lex.col, "expected codeBlock after `finalizer` declaration");
2715 return;
2716 }
2717 o = new finalizerDef{node_start_token, block};
2718 }
2719
2720 void parse(funcExpr *&o, lexer &lex) {
2721 lexer::token node_start_token = lex.curToken;
2722 if (lex.curToken.kind != lexer::token::tokenKind::kFunc) {
2723 o = nullptr;
2724 return;
2725 }
2726 lex.saveState();
2727 lex.scan();
2728 externModuleAccessExpression *name = nullptr;
2729 parse(name, lex);
2730 if (!name) {
2731 o = nullptr;
2732 lex.returnState();
2733 return;
2734 }
2735 lex.dropState();
2736 unnamedDefinitionArguments *args = nullptr;
2737 parse(args, lex);
2738 if (!args) {
2739 o = new funcExpr{node_start_token, name, nullptr};
2740 return;
2741 }
2742 o = new funcExpr{node_start_token, name, args};
2743 }
2744
2745 void parse(enumerationDefinition *&o, lexer &lex) {
2746 lexer::token node_start_token = lex.curToken;
2747 if (lex.curToken.kind != lexer::token::tokenKind::kEnum) {
2748 o = nullptr;
2749 return;
2750 }
2751 lex.scan();
2752 identifier *name = nullptr;
2753 parse(name, lex);
2754 if (!name) {
2755 o = nullptr;
2756 panic(lex.line, lex.col, "expected identifier after `enum` in enumeration definition");
2757 return;
2758 }
2759 if (lex.curToken.kind != lexer::token::tokenKind::leftBraces) {
2760 o = nullptr;
2761 finalizeAST(name);
2762 panic(lex.line, lex.col, "expected `{` after identifier in enumeration definition");
2763 return;
2764 }
2765 lex.scan();
2766 vec<enumerationPair *> enumerators;
2767 enumerationPair *enumerator = nullptr;
2768 parse(enumerator, lex);
2769 while (enumerator) {
2770 enumerators.push_back(enumerator);
2771 if (lex.curToken.kind != lexer::token::tokenKind::comma) {
2772 break;
2773 } else {
2774 enumerator = nullptr;
2775 lex.scan();
2776 parse(enumerator, lex);
2777 }
2778 }
2779 if (lex.curToken.kind != lexer::token::tokenKind::rightBraces) {
2780 o = nullptr;
2781 for (auto e : enumerators)
2782 finalizeAST(e);
2783 finalizeAST(name);
2784 panic(lex.line, lex.col, "expected `}` after enumerators in enumeration definition");
2785 return;
2786 }
2787 lex.scan();
2788 o = new enumerationDefinition{node_start_token, name, enumerators};
2789 }
2790
2791 void parse(enumerationPair *&o, lexer &lex) {
2792 lexer::token node_start_token = lex.curToken;
2793 identifier *name = nullptr;
2794 parse(name, lex);
2795 if (!name) {
2796 o = nullptr;
2797 return;
2798 }
2799 if (lex.curToken.kind != lexer::token::tokenKind::assignSign) {
2800 o = new enumerationPair{node_start_token, name, {}};
2801 return;
2802 }
2803 lex.scan();
2804 lexer::token value = lex.curToken;
2806 o = new enumerationPair{node_start_token, name, value};
2807 lex.scan();
2808 } else if (value.kind == lexer::token::tokenKind::minus) {
2809 lex.scan();
2810 if (lex.curToken.kind != lexer::token::tokenKind::integer) {
2811 o = nullptr;
2812 finalizeAST(name);
2813 panic(lex.line, lex.col, "expected integer literal after `-` in enumeration pair");
2814 return;
2815 }
2816 value = lex.curToken;
2817 value.basicVal.vInt = -value.basicVal.vInt;
2818 o = new enumerationPair{node_start_token, name, value};
2819 lex.scan();
2820 } else {
2821 o = nullptr;
2822 finalizeAST(name);
2823 panic(lex.line, lex.col, "expected integer literal after `=` in enumeration pair");
2824 return;
2825 }
2826 }
2827
2828 void parse(bracedInitalizerList *&o, lexer &lex) {
2829 if (lex.curToken.kind != lexer::token::tokenKind::leftBraces) {
2830 o = nullptr;
2831 return;
2832 }
2833 yoi::lexer::token node_start_token = lex.curToken;
2834 lex.saveState();
2835 lex.scan();
2836 vec<rExpr *> expressions;
2837 rExpr *expression = nullptr;
2838 parse(expression, lex);
2839 while (expression) {
2840 expressions.push_back(expression);
2841 if (lex.curToken.kind != lexer::token::tokenKind::comma) {
2842 break;
2843 } else {
2844 expression = nullptr;
2845 lex.scan();
2846 parse(expression, lex);
2847 }
2848 }
2849 if (lex.curToken.kind != lexer::token::tokenKind::rightBraces) {
2850 o = nullptr;
2851 for (auto e : expressions)
2852 finalizeAST(e);
2853 lex.returnState();
2854 return;
2855 }
2856 lex.scan();
2857 lex.dropState();
2858 o = new bracedInitalizerList{node_start_token, expressions};
2859 }
2860
2861 void parse(yieldStmt *&o, lexer &lex) {
2862 if (lex.curToken.kind != lexer::token::tokenKind::kYield) {
2863 o = nullptr;
2864 return;
2865 }
2866 yoi::lexer::token node_start_token = lex.curToken;
2867 lex.scan();
2868 rExpr *expr = nullptr;
2869 parse(expr, lex);
2870 if (!expr) {
2871 o = nullptr;
2872 panic(lex.line, lex.col, "expected rExpr after `yield` in yieldStmt");
2873 return;
2874 }
2875 o = new yieldStmt{node_start_token, expr};
2876 }
2877
2878 void parse(decltypeExpr *&o, lexer &lex) {
2879 lexer::token node_start_token{lex.curToken};
2880 if (lex.curToken.kind != lexer::token::tokenKind::kDecltype) {
2881 o = nullptr;
2882 return;
2883 }
2884 lex.scan();
2885 yoi_assert(lex.curToken.kind == lexer::token::tokenKind::leftParentheses, lex.curToken.line, lex.curToken.col, "expected `(` after `decltype` keyword");
2886 lex.scan();
2887 rExpr *expr{};
2888 parse(expr, lex);
2889 yoi_assert(expr, lex.line, lex.col, "expected expression after `(` for decltype-expression");
2890 if (lex.curToken.kind != lexer::token::tokenKind::rightParentheses) {
2891 o = nullptr;
2892 finalizeAST(expr);
2893 panic(lex.line, lex.col, "expected `)` after expression");
2894 }
2895 lex.scan();
2896 o = new decltypeExpr{node_start_token, expr};
2897 }
2898
2899 void parse(satisfyStmt *&o, lexer &lex) {
2900 if (lex.curToken.kind != lexer::token::tokenKind::kSatisfy) {
2901 o = nullptr;
2902 return;
2903 }
2904 yoi::lexer::token node_start_token = lex.curToken;
2905 lex.scan();
2906 externModuleAccessExpression *emae = nullptr;
2907 parse(emae, lex);
2908 if (!emae) {
2909 o = nullptr;
2910 panic(lex.line, lex.col, "expected externModuleAccessExpression after `satisfy` in satisfyStmt");
2911 return;
2912 }
2913 o = new satisfyStmt{node_start_token, emae};
2914 }
2915
2916 void parse(conceptStmt *&o, lexer &lex) {
2917 yoi::lexer::token node_start_token = lex.curToken;
2918
2919 satisfyStmt *s{};
2920 parse(s, lex);
2921 if (s) {
2922 o = new conceptStmt{node_start_token, conceptStmt::Kind::SatisfyStmt, s};
2923 return;
2924 }
2925
2926 rExpr *e{};
2927 parse(e, lex);
2928 if (e) {
2929 o = new conceptStmt{node_start_token, conceptStmt::Kind::Expression, e};
2930 return;
2931 }
2932 }
2933
2934 void parse(conceptDefinition *&o, lexer &lex) {
2935 if (lex.curToken.kind != lexer::token::tokenKind::kConcept) {
2936 o = nullptr;
2937 return;
2938 }
2939 yoi::lexer::token node_start_token = lex.curToken;
2940 lex.scan();
2941
2942 lexer::token name{};
2943 yoi::vec<lexer::token> typeParams;
2944 yoi_assert(lex.curToken.kind == lexer::token::tokenKind::identifier, lex.curToken.line, lex.curToken.col, "expected identifier after `concept` in conceptDefinition");
2945 name = lex.curToken;
2946 lex.scan();
2947
2948 yoi_assert(lex.curToken.kind == lexer::token::tokenKind::lessThan, lex.curToken.line, lex.curToken.col, "expected `<` after concept name in conceptDefinition");
2949 lex.scan();
2950
2951 while (lex.curToken.kind == lexer::token::tokenKind::identifier) {
2952 typeParams.push_back(lex.curToken);
2953 lex.scan();
2954 if (lex.curToken.kind == lexer::token::tokenKind::comma) {
2955 lex.scan();
2956 } else {
2957 break;
2958 }
2959 }
2960 yoi_assert(lex.curToken.kind == lexer::token::tokenKind::greaterThan, lex.curToken.line, lex.curToken.col, "expected `>` after type parameters in conceptDefinition");
2961 lex.scan();
2962
2963 yoi_assert(lex.curToken.kind == lexer::token::tokenKind::leftParentheses, lex.curToken.line, lex.curToken.col, "expected `(` after `>`");
2964 lex.scan();
2965
2967 identifierWithTypeSpec *spec{};
2968 parse(spec, lex);
2969 while (spec) {
2970 specs.push_back(spec);
2971 if (lex.curToken.kind == lexer::token::tokenKind::comma) {
2972 lex.scan();
2973 spec = nullptr;
2974 parse(spec, lex);
2975 } else {
2976 break;
2977 }
2978 }
2979 yoi_assert(lex.curToken.kind == lexer::token::tokenKind::rightParentheses, lex.curToken.line, lex.curToken.col, "expected `)` after specs");
2980 lex.scan();
2981
2982 if (lex.curToken.kind != lexer::token::tokenKind::leftBraces) {
2983 o = nullptr;
2984 for (auto s : specs)
2985 finalizeAST(s);
2986 panic(lex.line, lex.col, "expected `{` after `)`");
2987 return;
2988 }
2989 lex.scan();
2990
2991 yoi::vec<conceptStmt *> conceptStmts;
2992 conceptStmt *stmt{};
2993 parse(stmt, lex);
2994 while (stmt) {
2995 conceptStmts.push_back(stmt);
2996 stmt = nullptr;
2997 parse(stmt, lex);
2998 }
2999 yoi_assert(lex.curToken.kind == lexer::token::tokenKind::rightBraces, lex.curToken.line, lex.curToken.col, "expected `}` after satisfyClauses");
3000 lex.scan();
3001
3002 o = new conceptDefinition{node_start_token, name, typeParams, specs, conceptStmts};
3003 }
3004
3005 void parse(satisfyClause *&o, lexer &lex) {
3006 if (lex.curToken.kind != lexer::token::tokenKind::kSatisfy) {
3007 o = nullptr;
3008 return;
3009 }
3010 lexer::token node_start_token = lex.curToken;
3011 lex.scan();
3012 yoi_assert(lex.curToken.kind == lexer::token::tokenKind::leftParentheses, lex.curToken.line, lex.curToken.col, "expected `(` after `satisfy`");
3013 lex.scan();
3014
3016 externModuleAccessExpression *spec{};
3017 parse(spec, lex);
3018 while (spec) {
3019 specs.push_back(spec);
3020 if (lex.curToken.kind == lexer::token::tokenKind::comma) {
3021 lex.scan();
3022 spec = nullptr;
3023 parse(spec, lex);
3024 } else {
3025 break;
3026 }
3027 }
3028 if (lex.curToken.kind != lexer::token::tokenKind::rightParentheses) {
3029 o = nullptr;
3030 for (auto s : specs)
3031 finalizeAST(s);
3032 panic(lex.line, lex.col, "expected `)` after specs");
3033 return;
3034 }
3035 lex.scan();
3036 o = new satisfyClause{node_start_token, specs};
3037 }
3038
3039 void parse(lambdaCapture *&o, lexer &lex) {
3040 lexer::token node_start_token = lex.curToken;
3042
3043 if (lex.curToken.kind == lexer::token::tokenKind::kWeak) {
3045 lex.scan();
3046 } else if (lex.curToken.kind == lexer::token::tokenKind::kDataField) {
3048 lex.scan();
3049 }
3050
3051 if (lex.curToken.kind != lexer::token::tokenKind::identifier) {
3052 o = nullptr;
3053 return;
3054 }
3055 identifier *name = nullptr;
3056 parse(name, lex);
3057 if (!name) {
3058 o = nullptr;
3059 return;
3060 }
3061
3062 o = new lambdaCapture{node_start_token, mod, name};
3063 }
3064} // namespace yoi
3065
3066#pragma clang diagnostic pop
bool hasTemplateArg() const
Definition ast.cpp:75
token scan()
Definition lexer.cpp:29
token curToken
Definition lexer.hpp:173
int64_t col
Definition lexer.hpp:176
int64_t line
Definition lexer.hpp:176
void saveState()
Definition lexer.cpp:545
void returnState()
Definition lexer.cpp:549
void dropState()
Definition lexer.cpp:557
subscript * length
Definition ast.hpp:399
invocationArguments * args
Definition ast.hpp:400
externModuleAccessExpression * type
Definition ast.hpp:398
enum yoi::typeSpec::typeSpecKind kind
constexpr E value(std::size_t i) noexcept
Definition magic_enum.h:668
std::vector< t > vec
Definition def.hpp:56
void yoi_assert(bool condition, yoi::indexT line, yoi::indexT col, const std::string &msg)
Asserts a condition that would be true and throws a runtime_error if it is false.
Definition def.cpp:217
void finalizeAST(funcTypeSpec *ptr)
Definition ast.cpp:475
uint64_t indexT
Definition def.hpp:54
void finalizeAST_vec(yoi::vec< T * > &vec)
Definition parser.cpp:18
void parse(yoi::basicLiterals *&o, yoi::lexer &lex)
Definition parser.cpp:25
void panic(yoi::indexT line, yoi::indexT col, const std::string &msg)
Definition def.cpp:141
#define PARSE_BINARY_EXPR(NODE_TYPE, CHILD_TYPE, OPERATORS, ERROR_MSG)
Definition parser.cpp:773
enum yoi::lexer::token::tokenKind kind
union yoi::lexer::token::vBasicValue basicVal