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 lex.scan();
876 o = new codeBlock{node_start_token, stmts};
877 } else {
878 finalizeAST_vec(stmts);
879 panic(lex.line, lex.col, "expected `}` to close codeBlock");
880 o = nullptr;
881 return;
882 }
883 } else {
884 o = nullptr;
885 return;
886 }
887 }
888
889 void parse(useStmt *&o, lexer &lex) {
890 lexer::token node_start_token;
891 if (lex.curToken.kind == lexer::token::tokenKind::kUse) {
892 node_start_token = lex.curToken;
893 lex.scan();
894 } else {
895 o = nullptr;
896 return;
897 }
898 identifier *id = nullptr;
899 lexer::token str_token{}; // Not a pointer, directly stored
900
901 parse(id, lex);
902 if (!id) {
903 panic(lex.line, lex.col, "expected identifier after `use`");
904 o = nullptr;
905 return;
906 }
907 if (lex.curToken.kind != lexer::token::tokenKind::string) {
908 finalizeAST(id);
909 panic(lex.line, lex.col, "expected string token after identifier while parsing useStmt");
910 o = nullptr;
911 return;
912 }
913 str_token = lex.curToken; // Store the string token by value
914 lex.scan();
915 o = new useStmt{node_start_token, id, str_token};
916 }
917
918 void parse(funcDefStmt *&o, lexer &lex) {
919 if (lex.curToken.kind == lexer::token::tokenKind::kFunc) {
920 lex.scan();
921 } else {
922 o = nullptr;
923 return;
924 }
925 lexer::token node_start_token = lex.curToken;
926
928 identifierWithDefTemplateArg *name = nullptr;
929 definitionArguments *args = nullptr;
930 typeSpec *spec = nullptr;
931 codeBlock *block = nullptr;
932
933 while (lex.curToken.kind >= lexer::token::tokenKind::kNoFFI && lex.curToken.kind <= lexer::token::tokenKind::kAlwaysInline) {
934 attrs.push_back(lex.curToken);
935 lex.scan();
936 }
937
938 parse(name, lex);
939 if (!name) {
940 panic(lex.line, lex.col, "expected function name");
941 o = nullptr;
942 return;
943 }
944 parse(args, lex);
945 if (!args) {
946 finalizeAST(name);
947 panic(lex.line, lex.col, "expected definitionArguments after identifierWithDefTemplateArg");
948 o = nullptr;
949 return;
950 }
951 if (lex.curToken.kind == lexer::token::tokenKind::colon)
952 lex.scan();
953 else {
954 finalizeAST(name);
955 finalizeAST(args);
956 panic(lex.line, lex.col, "expected `:` after definitionArguments");
957 o = nullptr;
958 return;
959 }
960 parse(spec, lex);
961 if (!spec) {
962 finalizeAST(name);
963 finalizeAST(args);
964 panic(lex.line, lex.col, "expected typeSpec after `:`");
965 o = nullptr;
966 return;
967 }
968 parse(block, lex);
969 if (!block) {
970 finalizeAST(name);
971 finalizeAST(args);
972 finalizeAST(spec);
973 panic(lex.line, lex.col, "expected codeBlock after typeSpec");
974 o = nullptr;
975 return;
976 }
977 o = new funcDefStmt{node_start_token, attrs, name, args, spec, block};
978 }
979
980 void parse(interfaceDefInnerPair *&o, lexer &lex) {
981 identifierWithTypeSpec *var = nullptr;
982 innerMethodDecl *method = nullptr;
983 lexer::token node_start_token = lex.curToken;
984
985 parse(method, lex);
986 if (method) {
987 o = new interfaceDefInnerPair{node_start_token, nullptr, method};
988 return;
989 }
990 parse(var, lex);
991 if (var) {
992 o = new interfaceDefInnerPair{node_start_token, var, nullptr};
993 return;
994 }
995 o = nullptr;
996 }
997
998 void parse(structDefInnerPair *&o, lexer &lex) {
999 identifierWithTypeSpec *var = nullptr;
1000 innerMethodDecl *method = nullptr;
1001 constructorDecl *con = nullptr;
1002 finalizerDecl *fin = nullptr;
1003 lexer::token node_start_token = lex.curToken;
1005
1006 if (lex.curToken.kind == lexer::token::tokenKind::kDataField) {
1008 lex.scan();
1009 }
1010
1011 parse(con, lex);
1012 if (con) {
1013 o = new structDefInnerPair{node_start_token, 1, mod, nullptr, con, nullptr, nullptr};
1014 return;
1015 }
1016 parse(method, lex);
1017 if (method) {
1018 o = new structDefInnerPair{node_start_token, 2, mod, nullptr, nullptr, method, nullptr};
1019 return;
1020 }
1021 parse(fin, lex);
1022 if (fin) {
1023 o = new structDefInnerPair{node_start_token, 3, mod, nullptr, nullptr, nullptr, fin};
1024 return;
1025 }
1026 parse(var, lex);
1027 if (var) {
1028 o = new structDefInnerPair{node_start_token, 0, mod, var, nullptr, nullptr, nullptr};
1029 return;
1030 }
1031 o = nullptr;
1032 }
1033
1034 void parse(implInnerPair *&o, lexer &lex) {
1035 innerMethodDef *method = nullptr;
1036 constructorDef *con = nullptr;
1037 finalizerDef *fin = nullptr;
1038 lexer::token node_start_token = lex.curToken;
1039
1040 parse(con, lex);
1041 if (con) {
1042 o = new implInnerPair{node_start_token, con, nullptr, nullptr};
1043 return;
1044 }
1045 parse(method, lex);
1046 if (method) {
1047 o = new implInnerPair{node_start_token, nullptr, method, nullptr};
1048 return;
1049 }
1050 parse(fin, lex);
1051 if (fin) {
1052 o = new implInnerPair{node_start_token, nullptr, nullptr, fin};
1053 return;
1054 }
1055 o = nullptr;
1056 }
1057
1058 void parse(interfaceDefInner *&o, lexer &lex) {
1059 if (lex.curToken.kind == lexer::token::tokenKind::leftBraces) {
1060 lexer::token node_start_token = lex.curToken;
1061 lex.scan();
1063 interfaceDefInnerPair *a = nullptr; // Initialize a
1064
1065 while (true) {
1066 parse(a, lex);
1067 if (!a) {
1068 break;
1069 }
1070 vecA.push_back(a);
1071 a = nullptr; // Reset 'a' for next parse
1072
1073 if (lex.curToken.kind == lexer::token::tokenKind::comma) {
1074 lex.scan();
1075 } else {
1076 break;
1077 }
1078 }
1079 if (lex.curToken.kind == lexer::token::tokenKind::rightBraces) {
1080 lex.scan();
1081 o = new interfaceDefInner{node_start_token, vecA};
1082 } else {
1083 finalizeAST_vec(vecA);
1084 panic(lex.line, lex.col, "expected `}` to close interfaceDefInner");
1085 o = nullptr;
1086 return;
1087 }
1088 } else {
1089 o = nullptr;
1090 return;
1091 }
1092 }
1093
1094 void parse(structDefInner *&o, lexer &lex) {
1095 if (lex.curToken.kind == lexer::token::tokenKind::leftBraces) {
1096 lexer::token node_start_token = lex.curToken;
1097 lex.scan();
1099 structDefInnerPair *a = nullptr; // Initialize a
1100
1101 while (true) {
1102 parse(a, lex);
1103 if (!a) {
1104 break;
1105 }
1106 vecA.push_back(a);
1107 a = nullptr; // Reset 'a' for next parse
1108
1109 if (lex.curToken.kind == lexer::token::tokenKind::comma) {
1110 lex.scan();
1111 } else {
1112 break;
1113 }
1114 }
1115 if (lex.curToken.kind == lexer::token::tokenKind::rightBraces) {
1116 lex.scan();
1117 o = new structDefInner{node_start_token, vecA};
1118 } else {
1119 finalizeAST_vec(vecA);
1120 panic(lex.line, lex.col, "expected `}` to close structDefInner");
1121 o = nullptr;
1122 return;
1123 }
1124 } else {
1125 o = nullptr;
1126 return;
1127 }
1128 }
1129
1130 void parse(implInner *&o, lexer &lex) {
1131 if (lex.curToken.kind == lexer::token::tokenKind::leftBraces) {
1132 lexer::token node_start_token = lex.curToken;
1133 lex.scan();
1135 implInnerPair *a = nullptr; // Initialize a
1136
1137 while (true) {
1138 parse(a, lex);
1139 if (!a) {
1140 break;
1141 }
1142 vecA.push_back(a);
1143 a = nullptr; // Reset 'a' for next parse
1144
1145 if (lex.curToken.kind == lexer::token::tokenKind::comma) {
1146 lex.scan();
1147 } else {
1148 break;
1149 }
1150 }
1151 if (lex.curToken.kind == lexer::token::tokenKind::rightBraces) {
1152 lex.scan();
1153 o = new implInner{node_start_token, vecA};
1154 } else {
1155 finalizeAST_vec(vecA);
1156 panic(lex.line, lex.col, "expected `}` to close implInner");
1157 o = nullptr;
1158 return;
1159 }
1160 } else {
1161 o = nullptr;
1162 return;
1163 }
1164 }
1165
1166 void parse(interfaceDefStmt *&o, lexer &lex) {
1167 if (lex.curToken.kind == lexer::token::tokenKind::kInterface) {
1168 lex.scan();
1169 } else {
1170 o = nullptr;
1171 return;
1172 }
1173 lexer::token node_start_token = lex.curToken;
1174
1175 identifierWithDefTemplateArg *id = nullptr;
1176 interfaceDefInner *inner = nullptr;
1177
1178 parse(id, lex);
1179 if (!id) {
1180 panic(lex.line, lex.col, "expected interface name after `interface`");
1181 o = nullptr;
1182 return;
1183 }
1184 parse(inner, lex);
1185 if (!inner) {
1186 finalizeAST(id);
1187 panic(lex.line, lex.col, "expected interfaceDefInner after identifier");
1188 o = nullptr;
1189 return;
1190 }
1191 o = new interfaceDefStmt{node_start_token, id, inner};
1192 }
1193
1194 void parse(structDefStmt *&o, lexer &lex) {
1195 if (lex.curToken.kind == lexer::token::tokenKind::kStruct) {
1196 lex.scan();
1197 } else {
1198 o = nullptr;
1199 return;
1200 }
1201 lexer::token node_start_token = lex.curToken;
1202
1203 identifierWithDefTemplateArg *id = nullptr;
1204 structDefInner *inner = nullptr;
1205
1206 parse(id, lex);
1207 if (!id) {
1208 panic(lex.line, lex.col, "expected struct name after `struct`");
1209 o = nullptr;
1210 return;
1211 }
1212 parse(inner, lex);
1213 if (!inner) {
1214 finalizeAST(id);
1215 panic(lex.line, lex.col, "expected structDefInner after identifier");
1216 o = nullptr;
1217 return;
1218 }
1219 o = new structDefStmt{node_start_token, id, inner};
1220 }
1221
1222 void parse(dataStructDefStmt *&o, lexer &lex) {
1223 if (lex.curToken.kind == lexer::token::tokenKind::kDataStruct) {
1224 lex.scan();
1225 } else {
1226 o = nullptr;
1227 return;
1228 }
1229 lexer::token node_start_token = lex.curToken;
1230
1231 identifier *id = nullptr;
1232 structDefInner *inner = nullptr;
1233
1234 parse(id, lex);
1235 if (!id) {
1236 panic(lex.line, lex.col, "expected datastruct name after `datastruct`");
1237 o = nullptr;
1238 return;
1239 }
1240 parse(inner, lex);
1241 if (!inner) {
1242 finalizeAST(id);
1243 panic(lex.line, lex.col, "expected datastruct body after identifier");
1244 o = nullptr;
1245 return;
1246 }
1247
1248 for (auto &pair : inner->getInner()) {
1249 if (pair->kind != 0) {
1250 finalizeAST(id);
1251 finalizeAST(inner);
1252 panic(lex.line, lex.col, "datastruct can only contain fields, no methods or constructors allowed");
1253 o = nullptr;
1254 return;
1255 }
1256 }
1257
1258 o = new dataStructDefStmt{node_start_token, id, inner};
1259 }
1260
1261 void parse(implStmt *&o, lexer &lex) {
1262 if (lex.curToken.kind == lexer::token::tokenKind::kImpl) {
1263 lex.scan();
1264 } else {
1265 o = nullptr;
1266 return;
1267 }
1268 lexer::token node_start_token = lex.curToken;
1269
1270 externModuleAccessExpression *first = nullptr; // Represents the interface (optional)
1271 externModuleAccessExpression *second = nullptr; // Represents the struct
1272 implInner *inner = nullptr;
1273
1274 // Save state for potential backtracking related to the optional ':' interface
1275 lex.saveState();
1276
1277 parse(second, lex); // Try to parse the struct name first
1278 if (!second) {
1279 lex.dropState(); // Drop the saved state as we failed at the very beginning of the rule
1280 panic(lex.line, lex.col, "expected struct name after `impl`");
1281 o = nullptr;
1282 return;
1283 }
1284
1285 if (lex.curToken.kind == lexer::token::tokenKind::colon) {
1286 lex.scan(); // Consume the colon
1287 parse(first, lex); // Now try to parse the interface name
1288 if (!first) {
1289 finalizeAST(second);
1290 lex.returnState(); // Backtrack because we tried to parse an interface but failed
1291 panic(lex.line, lex.col, "expected interface name after `:`");
1292 o = nullptr;
1293 return;
1294 }
1295 } else {
1296 // No colon means no interface specified, 'first' remains nullptr.
1297 // No returnState() here, as this is a successful path for the "impl struct" variant.
1298 }
1299
1300 // Now parse the inner block
1301 parse(inner, lex);
1302 if (!inner) {
1303 o = new implStmt{node_start_token, first, second, nullptr};
1304 return;
1305 }
1306
1307 lex.dropState(); // Drop state on success.
1308 o = new implStmt{node_start_token, first, second, inner};
1309 }
1310
1311 void parse(letAssignmentPair *&o, lexer &lex) {
1312 letAssignmentPairLHS *lhs = nullptr;
1313 typeSpec *type = nullptr;
1314 rExpr *rhs = nullptr;
1315 lexer::token node_start_token = lex.curToken;
1316
1317 parse(lhs, lex);
1318 if (!lhs) {
1319 panic(lex.line, lex.col, "expected left-hand-side in letAssignmentPair");
1320 o = nullptr;
1321 return;
1322 }
1323 if (lex.curToken.kind == lexer::token::tokenKind::colon) {
1324 lex.scan();
1325 parse(type, lex);
1326 if (!type) {
1327 panic(lex.line, lex.col, "expected typeSpec after `:` in letAssignmentPair");
1328 o = nullptr;
1329 return;
1330 }
1331 }
1332 if (lex.curToken.kind == lexer::token::tokenKind::assignSign) {
1333 lex.scan();
1334 } else {
1335 finalizeAST(lhs);
1336 panic(lex.line, lex.col, "expected `=` after left-hand-side in letAssignmentPair");
1337 o = nullptr;
1338 return;
1339 }
1340 parse(rhs, lex);
1341 if (!rhs) {
1342 finalizeAST(lhs);
1343 panic(lex.line, lex.col, "expected right-hand-side in letAssignmentPair");
1344 o = nullptr;
1345 return;
1346 }
1347 o = new letAssignmentPair{node_start_token, lhs, type, rhs};
1348 }
1349
1350 void parse(letAssignmentPairLHS *&o, lexer &lex) {
1351 lexer::token node_start_token = lex.curToken;
1352 if (lex.curToken.kind == lexer::token::tokenKind::identifier) {
1353 identifier *id = new identifier{lex.curToken, lex.curToken};
1354 lex.scan();
1355 o = new letAssignmentPairLHS{node_start_token, letAssignmentPairLHS::vKind::identifier, id};
1356 } else if (lex.curToken.kind == lexer::token::tokenKind::leftBracket) {
1357 lex.scan();
1359 while (true) {
1360 if (lex.curToken.kind != lexer::token::tokenKind::identifier && lex.curToken.kind != lexer::token::tokenKind::kThreeDots) {
1361 break;
1362 }
1363 vecA.push_back(lex.curToken);
1364 lex.scan();
1365 if (lex.curToken.kind == lexer::token::tokenKind::comma) {
1366 lex.scan();
1367 } else {
1368 break;
1369 }
1370 }
1371 if (lex.curToken.kind == lexer::token::tokenKind::kThreeDots) {
1372 vecA.push_back(lex.curToken);
1373 lex.scan();
1374 }
1375 yoi_assert(vecA.empty() || vecA.size() < 2 ||
1376 (vecA.front().kind != lexer::token::tokenKind::kThreeDots || vecA.back().kind != lexer::token::tokenKind::kThreeDots),
1377 lex.line,
1378 lex.col,
1379 "structured binding cannot have `...` both in the front and in the back of the list");
1380 if (vecA.size() > 2)
1381 for (yoi::indexT i = 1; i < vecA.size() - 1; i++)
1383 lex.line,
1384 lex.col,
1385 "structured binding cannot have `...` in the middle of the list");
1386
1387 yoi_assert(lex.curToken.kind == lexer::token::tokenKind::rightBracket, lex.curToken.line, lex.curToken.col, "expected `]`");
1388 lex.scan();
1389 o = new letAssignmentPairLHS{node_start_token, letAssignmentPairLHS::vKind::list, nullptr, vecA};
1390 } else {
1391 panic(lex.line, lex.col, "expected identifier or `[...]` after `let`");
1392 o = nullptr;
1393 }
1394 }
1395
1396 void parse(letStmt *&o, lexer &lex) {
1397 lexer::token node_start_token;
1398 if (lex.curToken.kind == lexer::token::tokenKind::kLet) {
1399 node_start_token = lex.curToken;
1400 lex.scan();
1401 } else {
1402 o = nullptr;
1403 return;
1404 }
1406 letAssignmentPair *a = nullptr; // Initialize a
1407
1408 while (true) {
1409 parse(a, lex);
1410 if (!a) { // If 'a' could not be parsed
1411 if (vecA.empty()) { // If it's the first assignment and it failed
1412 panic(lex.line, lex.col, "expected letAssignmentPair after `let`");
1413 } else { // If it's a subsequent assignment after a comma and it failed
1414 panic(lex.line, lex.col, "expected letAssignmentPair after comma in let statement");
1415 }
1416 finalizeAST_vec(vecA);
1417 o = nullptr;
1418 return;
1419 }
1420 vecA.push_back(a);
1421 a = nullptr; // Reset 'a' for the next parse
1422
1423 if (lex.curToken.kind == lexer::token::tokenKind::comma) {
1424 lex.scan();
1425 } else {
1426 break;
1427 }
1428 }
1429 o = new letStmt{node_start_token, vecA};
1430 }
1431
1432 void parse(globalStmt *&o, lexer &lex) {
1433 // Initialize all pointers to nullptr to avoid uninitialized checks
1434 marcoDescriptor *marco = nullptr;
1435 useStmt *a = nullptr;
1436 interfaceDefStmt *b = nullptr;
1437 structDefStmt *c = nullptr;
1438 implStmt *d = nullptr;
1439 letStmt *e = nullptr;
1440 funcDefStmt *f = nullptr;
1441 exportDecl *g = nullptr;
1442 importDecl *h = nullptr;
1443 typeAliasStmt *i = nullptr;
1444 enumerationDefinition *j = nullptr;
1445 conceptDefinition *k = nullptr;
1446
1447 lexer::token node_start_token = lex.curToken;
1448
1449 parse(marco, lex);
1450
1451 parse(a, lex);
1452 if (a) {
1453 o = new globalStmt{node_start_token, globalStmt::vKind::useStmt, marco, {a}};
1454 return;
1455 }
1456
1457 parse(b, lex);
1458 if (b) {
1459 o = new globalStmt{node_start_token, globalStmt::vKind::interfaceDefStmt, marco, {b}};
1460 return;
1461 }
1462
1463 parse(c, lex);
1464 if (c) {
1465 o = new globalStmt{node_start_token, globalStmt::vKind::structDefStmt, marco, {c}};
1466 return;
1467 }
1468
1469 dataStructDefStmt *ds = nullptr;
1470 parse(ds, lex);
1471 if (ds) {
1472 o = new globalStmt{node_start_token, globalStmt::vKind::dataStructDefStmt, marco, {ds}};
1473 return;
1474 }
1475
1476 parse(d, lex);
1477 if (d) {
1478 o = new globalStmt{node_start_token, globalStmt::vKind::implStmt, marco, {d}};
1479 return;
1480 }
1481
1482 parse(e, lex);
1483 if (e) {
1484 o = new globalStmt{node_start_token, globalStmt::vKind::letStmt, marco, {e}};
1485 return;
1486 }
1487
1488 parse(f, lex);
1489 if (f) {
1490 o = new globalStmt{node_start_token, globalStmt::vKind::funcDefStmt, marco, {f}};
1491 return;
1492 }
1493
1494 parse(g, lex);
1495 if (g) {
1496 o = new globalStmt{node_start_token, globalStmt::vKind::exportDecl, marco, {g}};
1497 return;
1498 }
1499
1500 parse(h, lex);
1501 if (h) {
1502 o = new globalStmt{node_start_token, globalStmt::vKind::importDecl, marco, {h}};
1503 return;
1504 }
1505
1506 parse(i, lex);
1507 if (i) {
1508 o = new globalStmt{node_start_token, globalStmt::vKind::typeAliasStmt, marco, {i}};
1509 return;
1510 }
1511
1512 parse(j, lex);
1513 if (j) {
1514 o = new globalStmt{node_start_token, globalStmt::vKind::enumerationDef, marco, {j}};
1515 return;
1516 }
1517
1518 parse(k, lex);
1519 if (k) {
1520 o = new globalStmt{node_start_token, globalStmt::vKind::conceptDef, marco, {k}};
1521 return;
1522 }
1523
1524 if (marco)
1525 finalizeAST(marco);
1526 o = nullptr; // No global statement matched
1527 }
1528
1529 // ifBlock parse for ifStmt
1530 void parse(ifStmt::ifBlock &o, lexer &lex) {
1531 // Initialize members to nullptr to be safe in case of early return
1532 o.cond = nullptr;
1533 o.block = nullptr;
1534
1535 if (lex.curToken.kind == lexer::token::tokenKind::leftParentheses) {
1536 lex.scan();
1537 } else {
1538 panic(lex.line, lex.col, "expected `(`");
1539 return;
1540 }
1541
1542 parse(o.cond, lex);
1543 if (!o.cond) {
1544 panic(lex.line, lex.col, "expected rExpr after `(`");
1545 return;
1546 }
1547
1548 if (lex.curToken.kind == lexer::token::tokenKind::rightParentheses) {
1549 lex.scan();
1550 } else {
1551 finalizeAST(o.cond);
1552 panic(lex.line, lex.col, "expected `)` after rExpr");
1553 return;
1554 }
1555
1556 parse(o.block, lex);
1557 if (!o.block) {
1558 finalizeAST(o.cond);
1559 panic(lex.line, lex.col, "expected codeBlock after `)`");
1560 return;
1561 }
1562 }
1563
1564 void parse(ifStmt *&o, lexer &lex) {
1565 if (lex.curToken.kind == lexer::token::tokenKind::kIf) {
1566 lexer::token node_start_token = lex.curToken;
1567 lex.scan();
1568 o = new ifStmt{node_start_token, {}, {}, nullptr}; // Create ifStmt node early for cleanup
1569 } else {
1570 o = nullptr;
1571 return;
1572 }
1573
1574 // Parse the initial ifBlock
1575 ifStmt::ifBlock temp_if_block{}; // Use a stack variable for parsing
1576 parse(temp_if_block, lex);
1577 if (!temp_if_block.cond || !temp_if_block.block) { // Check if parsing failed (parse(ifBlock) panics and returns)
1578 finalizeAST(o);
1579 o = nullptr;
1580 return;
1581 }
1582 o->ifB = temp_if_block; // Assign the struct by value (copying the pointers)
1583
1584 // Parse elif blocks
1585 while (lex.curToken.kind == lexer::token::tokenKind::kElif) {
1586 lex.scan();
1587 temp_if_block = {}; // Reset stack variable for the next elif block
1588 parse(temp_if_block, lex);
1589 if (!temp_if_block.cond || !temp_if_block.block) { // If elif block parsing failed
1590 finalizeAST(o);
1591 panic(lex.line, lex.col, "expected ifBlock after `elif`");
1592 o = nullptr;
1593 return;
1594 }
1595 o->elifB.push_back(temp_if_block); // Push a *copy* of the struct
1596 }
1597
1598 // Parse else block
1599 if (lex.curToken.kind == lexer::token::tokenKind::kElse) {
1600 lex.scan();
1601 parse(o->elseB, lex);
1602 if (!o->elseB) {
1603 finalizeAST(o);
1604 panic(lex.line, lex.col, "expected codeBlock after `else`");
1605 o = nullptr;
1606 return;
1607 }
1608 }
1609 }
1610
1611 void parse(whileStmt *&o, lexer &lex) {
1612 lexer::token node_start_token;
1613 if (lex.curToken.kind == lexer::token::tokenKind::kWhile) {
1614 node_start_token = lex.curToken;
1615 lex.scan();
1616 } else {
1617 o = nullptr;
1618 return;
1619 }
1620
1621 rExpr *expr = nullptr;
1622 codeBlock *block = nullptr;
1623
1624 if (lex.curToken.kind == lexer::token::tokenKind::leftParentheses) {
1625 lex.scan();
1626 } else {
1627 panic(lex.line, lex.col, "expected `(` after `while`");
1628 o = nullptr;
1629 return;
1630 }
1631
1632 parse(expr, lex);
1633 if (!expr) {
1634 panic(lex.line, lex.col, "expected rExpr after `(`");
1635 o = nullptr;
1636 return;
1637 }
1638
1639 if (lex.curToken.kind == lexer::token::tokenKind::rightParentheses) {
1640 lex.scan();
1641 } else {
1642 finalizeAST(expr);
1643 panic(lex.line, lex.col, "expected `)` after rExpr");
1644 o = nullptr;
1645 return;
1646 }
1647
1648 parse(block, lex);
1649 if (!block) {
1650 finalizeAST(expr);
1651 panic(lex.line, lex.col, "expected codeBlock after `)`");
1652 o = nullptr;
1653 return;
1654 }
1655
1656 o = new whileStmt{node_start_token, expr, block};
1657 }
1658
1659 void parse(forStmt *&o, lexer &lex) {
1660 lexer::token node_start_token;
1661 if (lex.curToken.kind == lexer::token::tokenKind::kFor) {
1662 node_start_token = lex.curToken;
1663 lex.scan();
1664 } else {
1665 o = nullptr;
1666 return;
1667 }
1668
1669 inCodeBlockStmt *initStmt = nullptr;
1670 rExpr *cond = nullptr;
1671 inCodeBlockStmt *afterStmt = nullptr;
1672 codeBlock *block = nullptr;
1673
1674 if (lex.curToken.kind == lexer::token::tokenKind::leftParentheses) {
1675 lex.scan();
1676 } else {
1677 panic(lex.line, lex.col, "expected `(` after `for`");
1678 o = nullptr;
1679 return;
1680 }
1681
1682 parse(initStmt, lex);
1683 // Original code implies initStmt can be empty. "expected initStmt" panic removed if this is allowed.
1684
1685 // Reconciling with original panic: it seems intended to be mandatory.
1686 if (!initStmt) {
1687 panic(lex.line, lex.col, "expected initStmt after `(`");
1688 o = nullptr;
1689 return;
1690 }
1691
1692 if (lex.curToken.kind == lexer::token::tokenKind::semicolon) {
1693 lex.scan();
1694 } else {
1695 finalizeAST(initStmt);
1696 panic(lex.line, lex.col, "expected `;` after initStmt");
1697 o = nullptr;
1698 return;
1699 }
1700
1701 parse(cond, lex);
1702
1703 if (!cond) {
1704 finalizeAST(initStmt);
1705 panic(lex.line, lex.col, "expected condition after `;`");
1706 o = nullptr;
1707 return;
1708 }
1709
1710 if (lex.curToken.kind == lexer::token::tokenKind::semicolon) {
1711 lex.scan();
1712 } else {
1713 finalizeAST(initStmt);
1714 finalizeAST(cond);
1715 panic(lex.line, lex.col, "expected `;` after condition");
1716 o = nullptr;
1717 return;
1718 }
1719
1720 parse(afterStmt, lex);
1721 if (!afterStmt) {
1722 finalizeAST(initStmt);
1723 finalizeAST(cond);
1724 panic(lex.line, lex.col, "expected afterStmt after `;`");
1725 o = nullptr;
1726 return;
1727 }
1728
1729 if (lex.curToken.kind == lexer::token::tokenKind::rightParentheses) {
1730 lex.scan();
1731 } else {
1732 finalizeAST(initStmt);
1733 finalizeAST(cond);
1734 finalizeAST(afterStmt);
1735 panic(lex.line, lex.col, "expected `)` after afterStmt");
1736 o = nullptr;
1737 return;
1738 }
1739 parse(block, lex);
1740 if (!block) {
1741 finalizeAST(initStmt);
1742 finalizeAST(cond);
1743 finalizeAST(afterStmt);
1744 panic(lex.line, lex.col, "expected codeBlock after `)`");
1745 o = nullptr;
1746 return;
1747 }
1748 o = new forStmt{node_start_token, initStmt, cond, afterStmt, block};
1749 }
1750
1751 void parse(forEachStmt *&o, lexer &lex) {
1752 lexer::token node_start_token;
1753 if (lex.curToken.kind == lexer::token::tokenKind::kForEach) {
1754 node_start_token = lex.curToken;
1755 lex.scan();
1756 } else {
1757 o = nullptr;
1758 return;
1759 }
1760 // Initialize children to nullptr
1761 identifier *var = nullptr;
1762 rExpr *container = nullptr;
1763 codeBlock *block = nullptr;
1764
1765 if (lex.curToken.kind == lexer::token::tokenKind::leftParentheses) {
1766 lex.scan();
1767 } else {
1768 panic(lex.line, lex.col, "expected `(` after `forEach`");
1769 o = nullptr;
1770 return;
1771 }
1772 parse(var, lex);
1773 if (!var) {
1774 panic(lex.line, lex.col, "expected variable name after `(`");
1775 o = nullptr;
1776 return;
1777 }
1778 if (lex.curToken.kind == lexer::token::tokenKind::colon) {
1779 lex.scan();
1780 } else {
1781 finalizeAST(var);
1782 panic(lex.line, lex.col, "expected `:` after variable name");
1783 o = nullptr;
1784 return;
1785 }
1786 parse(container, lex);
1787 if (!container) {
1788 finalizeAST(var);
1789 panic(lex.line, lex.col, "expected container after `:`");
1790 o = nullptr;
1791 return;
1792 }
1793 if (lex.curToken.kind == lexer::token::tokenKind::rightParentheses) {
1794 lex.scan();
1795 } else {
1796 finalizeAST(var);
1797 finalizeAST(container);
1798 panic(lex.line, lex.col, "expected `)` after container");
1799 o = nullptr;
1800 return;
1801 }
1802 parse(block, lex);
1803 if (!block) {
1804 finalizeAST(var);
1805 finalizeAST(container);
1806 panic(lex.line, lex.col, "expected codeBlock after `)`");
1807 o = nullptr;
1808 return;
1809 }
1810 o = new forEachStmt{node_start_token, var, container, block};
1811 }
1812
1813 void parse(returnStmt *&o, lexer &lex) {
1814 if (lex.curToken.kind == lexer::token::tokenKind::kReturn) {
1815 lexer::token node_start_token = lex.curToken;
1816 lex.scan();
1817 rExpr *expr = nullptr;
1818 parse(expr, lex); // expr is optional
1819 o = new returnStmt{node_start_token, expr};
1820 } else {
1821 o = nullptr;
1822 }
1823 }
1824
1825 void parse(continueStmt *&o, lexer &lex) {
1826 if (lex.curToken.kind == lexer::token::tokenKind::kContinue) {
1827 lexer::token node_start_token = lex.curToken;
1828 lex.scan();
1829 o = new continueStmt{node_start_token}; // Add token for consistency
1830 } else {
1831 o = nullptr;
1832 return;
1833 }
1834 }
1835
1836 void parse(breakStmt *&o, lexer &lex) {
1837 if (lex.curToken.kind == lexer::token::tokenKind::kBreak) {
1838 lexer::token node_start_token = lex.curToken;
1839 lex.scan();
1840 o = new breakStmt{node_start_token}; // Add token for consistency
1841 } else {
1842 o = nullptr;
1843 return;
1844 }
1845 }
1846
1847 void parse(inCodeBlockStmt *&o, lexer &lex) {
1848 // Initialize all potential children to nullptr before trying to parse
1849 marcoDescriptor *marco = nullptr;
1850 letStmt *letStmtVal = nullptr;
1851 ifStmt *ifStmtVal = nullptr;
1852 breakStmt *breakStmtVal = nullptr;
1853 continueStmt *continueStmtVal = nullptr;
1854 returnStmt *returnStmtVal = nullptr;
1855 forEachStmt *forEachStmtVal = nullptr;
1856 whileStmt *whileStmtVal = nullptr;
1857 forStmt *forStmtVal = nullptr;
1858 codeBlock *codeBlockVal = nullptr;
1859 tryCatchStmt *tryCatchStmtVal = nullptr;
1860 throwStmt *throwStmtVal = nullptr;
1861 yieldStmt *yieldStmtVal = nullptr;
1862 rExpr *rExprVal = nullptr;
1863
1864 lexer::token node_start_token = lex.curToken;
1865
1866 parse(marco, lex);
1867
1868 // Try parsing each type, and if successful, create the inCodeBlockStmt and return.
1869 // This avoids creating the inCodeBlockStmt node until a successful child parse.
1870
1871 parse(letStmtVal, lex);
1872 if (letStmtVal) {
1873 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::letStmt, marco, {letStmtVal}};
1874 return;
1875 }
1876 parse(ifStmtVal, lex);
1877 if (ifStmtVal) {
1878 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::ifStmt, marco, {ifStmtVal}};
1879 return;
1880 }
1881 parse(breakStmtVal, lex);
1882 if (breakStmtVal) {
1883 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::breakStmt, marco, {breakStmtVal}};
1884 return;
1885 }
1886 parse(continueStmtVal, lex);
1887 if (continueStmtVal) {
1888 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::continueStmt, marco, {continueStmtVal}};
1889 return;
1890 }
1891 parse(returnStmtVal, lex);
1892 if (returnStmtVal) {
1893 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::returnStmt, marco, {returnStmtVal}};
1894 return;
1895 }
1896 parse(forEachStmtVal, lex); // Only parse once
1897 if (forEachStmtVal) {
1898 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::forEachStmt, marco, {forEachStmtVal}};
1899 return;
1900 }
1901 parse(whileStmtVal, lex);
1902 if (whileStmtVal) {
1903 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::whileStmt, marco, {whileStmtVal}};
1904 return;
1905 }
1906
1907 parse(forStmtVal, lex);
1908 if (forStmtVal) {
1909 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::forStmt, marco, {forStmtVal}};
1910 return;
1911 }
1912
1913 parse(tryCatchStmtVal, lex);
1914 if (tryCatchStmtVal) {
1915 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::tryCatchStmt, marco, {tryCatchStmtVal}};
1916 return;
1917 }
1918
1919 parse(throwStmtVal, lex);
1920 if (throwStmtVal) {
1921 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::throwStmt, marco, {throwStmtVal}};
1922 return;
1923 }
1924
1925 parse(codeBlockVal, lex);
1926 if (codeBlockVal) {
1927 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::codeBlock, marco, {codeBlockVal}};
1928 return;
1929 }
1930
1931 parse(yieldStmtVal, lex);
1932 if (yieldStmtVal) {
1933 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::yieldStmt, marco, {yieldStmtVal}};
1934 return;
1935 }
1936
1937 // rExpr should typically be last, as it's the most general expression statement.
1938 parse(rExprVal, lex);
1939 if (rExprVal) {
1940 o = new inCodeBlockStmt{node_start_token, inCodeBlockStmt::vKind::rExpr, marco, {rExprVal}};
1941 return;
1942 }
1943
1944 if (marco)
1945 finalizeAST(marco);
1946 o = nullptr; // If no statement type matched
1947 }
1948
1949 void parse(innerMethodDecl *&o, lexer &lex) {
1950 lex.saveState();
1951 lexer::token node_start_token = lex.curToken;
1952
1953 o = new innerMethodDecl{node_start_token, {}, nullptr, nullptr, nullptr};
1954
1955 while (lex.curToken.kind >= lexer::token::tokenKind::kNoFFI && lex.curToken.kind <= lexer::token::tokenKind::kAlwaysInline) {
1956 o->attrs.push_back(lex.curToken);
1957 lex.scan();
1958 }
1959
1960 parse(o->name, lex);
1961 if (!o->name) {
1962 lex.returnState();
1963 delete o; // Delete the partially constructed node
1964 o = nullptr;
1965 return;
1966 }
1967 parse(o->args, lex);
1968 if (!o->args) {
1969 finalizeAST(o->name);
1970 lex.returnState();
1971 delete o;
1972 o = nullptr;
1973 return;
1974 }
1975 if (lex.curToken.kind == lexer::token::tokenKind::colon) {
1976 lex.scan();
1977 } else {
1978 finalizeAST(o->name);
1979 finalizeAST(o->args);
1980 lex.returnState();
1981 delete o;
1982 o = nullptr;
1983 return;
1984 }
1985 parse(o->resultType, lex);
1986 if (!o->resultType) {
1987 finalizeAST(o->name);
1988 finalizeAST(o->args);
1989 lex.returnState();
1990 delete o;
1991 o = nullptr;
1992 return;
1993 }
1994 lex.dropState();
1995 }
1996
1997 void parse(innerMethodDef *&o, lexer &lex) {
1998 lex.saveState();
1999 lexer::token node_start_token = lex.curToken;
2000
2001 o = new innerMethodDef{node_start_token, {}, nullptr, nullptr, nullptr, nullptr};
2002
2003 while (lex.curToken.kind >= lexer::token::tokenKind::kNoFFI && lex.curToken.kind <= lexer::token::tokenKind::kAlwaysInline) {
2004 o->attrs.push_back(lex.curToken);
2005 lex.scan();
2006 }
2007
2008 parse(o->name, lex);
2009 if (!o->name) {
2010 lex.returnState();
2011 delete o;
2012 o = nullptr;
2013 return;
2014 }
2015 parse(o->args, lex);
2016 if (!o->args) {
2017 finalizeAST(o->name);
2018 lex.returnState();
2019 delete o;
2020 o = nullptr;
2021 return;
2022 }
2023 if (lex.curToken.kind == lexer::token::tokenKind::colon) {
2024 lex.scan();
2025 } else {
2026 finalizeAST(o->name);
2027 finalizeAST(o->args);
2028 lex.returnState();
2029 delete o;
2030 o = nullptr;
2031 return;
2032 }
2033 parse(o->resultType, lex);
2034 if (!o->resultType) {
2035 finalizeAST(o->name);
2036 finalizeAST(o->args);
2037 lex.returnState();
2038 delete o;
2039 o = nullptr;
2040 return;
2041 }
2042 parse(o->block, lex);
2043 if (!o->block) {
2044 finalizeAST(o->name);
2045 finalizeAST(o->args);
2046 finalizeAST(o->resultType);
2047 lex.returnState();
2048 delete o;
2049 o = nullptr;
2050 return;
2051 }
2052 lex.dropState();
2053 }
2054
2055 void parse(constructorDecl *&o, lexer &lex) {
2056 lexer::token node_start_token;
2057 if (lex.curToken.kind == lexer::token::tokenKind::kConstructor) {
2058 node_start_token = lex.curToken;
2059 lex.scan();
2060 } else {
2061 o = nullptr;
2062 return;
2063 }
2064 defTemplateArg *tempArg = nullptr;
2065 if (lex.curToken.kind == lexer::token::tokenKind::lessThan) {
2066 parse(tempArg, lex);
2067 if (!tempArg) {
2068 panic(lex.line, lex.col, "expected template argument after `<` in constructor declaration");
2069 o = nullptr;
2070 return;
2071 }
2072 }
2073 definitionArguments *args = nullptr;
2074 parse(args, lex);
2075 if (!args) {
2076 panic(lex.line, lex.col, "expected arguments after `constructor`");
2077 o = nullptr;
2078 return;
2079 }
2080 if (lex.curToken.kind == lexer::token::tokenKind::colon) {
2081 finalizeAST(args);
2082 panic(lex.line, lex.col, "constructor declaration cannot have a return type");
2083 o = nullptr;
2084 }
2085 o = new constructorDecl{node_start_token, tempArg, args};
2086 }
2087
2088 void parse(constructorDef *&o, lexer &lex) {
2089 lexer::token node_start_token;
2090 if (lex.curToken.kind == lexer::token::tokenKind::kConstructor) {
2091 node_start_token = lex.curToken;
2092 lex.scan();
2093 } else {
2094 o = nullptr;
2095 return;
2096 }
2097 templateArg *tempArg = nullptr;
2098 definitionArguments *args = nullptr;
2099 codeBlock *block = nullptr;
2100
2101 if (lex.curToken.kind == lexer::token::tokenKind::lessThan) {
2102 parse(tempArg, lex);
2103 if (!tempArg) {
2104 panic(lex.line, lex.col, "expected template argument after `<` in constructor definition");
2105 o = nullptr;
2106 return;
2107 }
2108 }
2109 parse(args, lex);
2110 if (!args) {
2111 panic(lex.line, lex.col, "expected arguments after `constructor`");
2112 o = nullptr;
2113 return;
2114 }
2115 if (lex.curToken.kind == lexer::token::tokenKind::colon) {
2116 finalizeAST(args);
2117 panic(lex.line, lex.col, "constructor declaration cannot have a return type");
2118 o = nullptr;
2119 }
2120 parse(block, lex);
2121 if (!block) {
2122 finalizeAST(args);
2123 panic(lex.line, lex.col, "expected codeBlock after arguments");
2124 o = nullptr;
2125 return;
2126 }
2127 o = new constructorDef{node_start_token, tempArg, args, block};
2128 }
2129
2130 void parse(hoshiModule *&o, lexer &lex) {
2132 globalStmt *a = nullptr; // Initialize a
2133
2134 lexer::token node_start_token = lex.curToken;
2135
2136 while (true) {
2137 if (lex.curToken.kind == lexer::token::tokenKind::eof)
2138 break;
2139 parse(a, lex);
2140 if (!a) { // If parsing a global statement fails, it's an error.
2141 finalizeAST_vec(vecA);
2142 panic(lex.line, lex.col, "expected globalStmt");
2143 o = nullptr;
2144 return;
2145 }
2146 vecA.push_back(a);
2147 a = nullptr; // Reset 'a' for the next parse call
2148 }
2149 o = new hoshiModule{node_start_token, vecA};
2150 }
2151
2152 void parse(importDecl *&o, lexer &lex) {
2153 lexer::token node_start_token;
2154 if (lex.curToken.kind == lexer::token::tokenKind::kImport) {
2155 lexer::token node_start_token = lex.curToken;
2156 lex.scan();
2157 } else {
2158 o = nullptr; // Consistent with other functions
2159 return;
2160 }
2161
2162 innerMethodDecl *a = nullptr;
2163 parse(a, lex);
2164 if (!a) {
2165 panic(lex.line, lex.col, "expected innerMethodDecl after `import`"); // Corrected panic message
2166 o = nullptr;
2167 return;
2168 }
2169
2170 o = new importDecl{node_start_token, a}; // Create the node here, now that 'a' is successfully parsed
2171
2172 if (lex.curToken.kind == lexer::token::tokenKind::kFrom) {
2173 lex.scan(); // Consume 'from'
2174 if (lex.curToken.kind == lexer::token::tokenKind::string) {
2175 o->from_path = lex.curToken;
2176 lex.scan(); // Consume string
2177 } else {
2178 finalizeAST(o);
2179 panic(lex.line, lex.col, "expected string literal after `from` in import declaration");
2180 o = nullptr;
2181 return;
2182 }
2183 } else {
2184 finalizeAST(o);
2185 panic(lex.line, lex.col, "expected `from` after import declaration");
2186 o = nullptr;
2187 return;
2188 }
2189 }
2190
2191 void parse(exportDecl *&o, lexer &lex) {
2192 lexer::token node_start_token;
2193 if (lex.curToken.kind == lexer::token::tokenKind::kExport) {
2194 node_start_token = lex.curToken;
2195 lex.scan();
2196 } else {
2197 o = nullptr; // Consistent
2198 return;
2199 }
2200
2202 while (lex.curToken.kind >= lexer::token::tokenKind::kNoFFI && lex.curToken.kind <= lexer::token::tokenKind::kAlwaysInline) {
2203 attrs.push_back(lex.curToken);
2204 lex.scan();
2205 }
2206
2207 typeSpec *a = nullptr;
2208 parse(a, lex);
2209 if (!a) {
2210 panic(lex.line, lex.col, "expected typeSpec after `export`"); // Corrected panic message
2211 o = nullptr;
2212 return;
2213 }
2214
2215 o = new exportDecl{node_start_token, attrs, a, nullptr}; // Create the node here, now that 'a' is parsed.
2216
2217 if (lex.curToken.kind == lexer::token::tokenKind::kAs) {
2218 lex.scan(); // Consume 'as'
2219 identifier *b = nullptr;
2220 parse(b, lex);
2221 if (!b) {
2222 finalizeAST(o);
2223 panic(lex.line, lex.col, "expected identifier after `as` in export declaration");
2224 o = nullptr;
2225 return;
2226 }
2227 o->as = b;
2228 } else {
2229 finalizeAST(o);
2230 panic(lex.line, lex.col, "expected `as` after export declaration");
2231 o = nullptr;
2232 return;
2233 }
2234 }
2235
2236 void parse(tryCatchStmt *&o, lexer &lex) {
2237 if (lex.curToken.kind != lexer::token::tokenKind::kTry) {
2238 o = nullptr;
2239 return;
2240 }
2241 lexer::token node_start_token = lex.curToken;
2242 lex.scan();
2243 codeBlock *tryBlock = nullptr;
2244 parse(tryBlock, lex);
2245 yoi_assert(tryBlock, lex.line, lex.col, "expected codeBlock after `try`");
2246 yoi::vec<catchParam *> catchParams;
2247 while (lex.curToken.kind == lexer::token::tokenKind::kCatch) {
2248 catchParam *param;
2249 parse(param, lex);
2250 if (!param) {
2251 finalizeAST(tryBlock);
2252 o = nullptr;
2253 panic(lex.line, lex.col, "expected catchParam after `catch`");
2254 }
2255 catchParams.push_back(param);
2256 }
2257 codeBlock *finallyBlock = nullptr;
2258 parse(finallyBlock, lex);
2259 if (!finallyBlock) {
2260 finalizeAST(tryBlock);
2261 for (auto p : catchParams)
2262 finalizeAST(p);
2263 o = nullptr;
2264 panic(lex.line, lex.col, "expected codeBlock after `catch`");
2265 }
2266 o = new tryCatchStmt{node_start_token, tryBlock, catchParams, finallyBlock};
2267 }
2268
2269 void parse(throwStmt *&o, lexer &lex) {
2270 if (lex.curToken.kind != lexer::token::tokenKind::kThrow) {
2271 o = nullptr;
2272 return;
2273 }
2274 lexer::token node_start_token = lex.curToken;
2275 lex.scan();
2276 rExpr *expr = nullptr;
2277 parse(expr, lex);
2278 if (!expr) {
2279 o = nullptr;
2280 panic(lex.line, lex.col, "expected expression after `throw`");
2281 }
2282 o = new throwStmt{node_start_token, expr};
2283 }
2284
2285 void parse(catchParam *&o, lexer &lex) {
2286 if (lex.curToken.kind != lexer::token::tokenKind::kCatch) {
2287 o = nullptr;
2288 return;
2289 }
2290 lexer::token node_start_token = lex.curToken;
2291 lex.scan();
2292 if (lex.curToken.kind != lexer::token::tokenKind::leftParentheses) {
2293 o = nullptr;
2294 panic(lex.line, lex.col, "expected `(` after `catch`");
2295 }
2296 lex.scan();
2297 identifier *name = nullptr;
2298 parse(name, lex);
2299 if (!name) {
2300 o = nullptr;
2301 panic(lex.line, lex.col, "expected identifier after typeSpec in catchParam");
2302 }
2303 if (lex.curToken.kind != lexer::token::tokenKind::colon) {
2304 o = nullptr;
2305 finalizeAST(name);
2306 panic(lex.line, lex.col, "expected `)` after identifier in catchParam");
2307 }
2308 lex.scan();
2309 typeSpec *type = nullptr;
2310 parse(type, lex);
2311 if (!type) {
2312 o = nullptr;
2313 finalizeAST(name);
2314 panic(lex.line, lex.col, "expected typeSpec after `(` in catchParam");
2315 }
2316 if (lex.curToken.kind != lexer::token::tokenKind::rightParentheses) {
2317 o = nullptr;
2318 finalizeAST(name);
2319 finalizeAST(type);
2320 panic(lex.line, lex.col, "expected `)` after typeSpec in catchParam");
2321 }
2322 lex.scan();
2323 codeBlock *block = nullptr;
2324 parse(block, lex);
2325 if (!block) {
2326 o = nullptr;
2327 finalizeAST(type);
2328 finalizeAST(name);
2329 panic(lex.line, lex.col, "expected codeBlock after identifier in catchParam");
2330 }
2331 o = new catchParam{node_start_token, type, name, block};
2332 }
2333
2334 void parse(typeIdExpression *&o, lexer &lex) {
2335 if (lex.curToken.kind != lexer::token::tokenKind::kTypeId) {
2336 o = nullptr;
2337 return;
2338 }
2339 lexer::token node_start_token = lex.curToken;
2340 lex.scan();
2341 if (lex.curToken.kind == lexer::token::tokenKind::leftParentheses) {
2342 lex.scan();
2343 rExpr *expr = nullptr;
2344 parse(expr, lex);
2345 if (!expr) {
2346 o = nullptr;
2347 panic(lex.line, lex.col, "expected expression after `(` in `type_id` expression");
2348 }
2349 if (lex.curToken.kind != lexer::token::tokenKind::rightParentheses) {
2350 o = nullptr;
2351 finalizeAST(expr);
2352 panic(lex.line, lex.col, "expected `)` after expression in `type_id` expression");
2353 }
2354 lex.scan();
2355 o = new typeIdExpression{node_start_token, nullptr, expr};
2356 } else if (lex.curToken.kind == lexer::token::tokenKind::lessThan) {
2357 lex.scan();
2358 typeSpec *type = nullptr;
2359 parse(type, lex);
2360 if (!type) {
2361 o = nullptr;
2362 panic(lex.line, lex.col, "expected typeSpec after `<` in `type_id` expression");
2363 }
2364 if (lex.curToken.kind != lexer::token::tokenKind::greaterThan) {
2365 o = nullptr;
2366 finalizeAST(type);
2367 panic(lex.line, lex.col, "expected `>` after typeSpec in `type_id` expression");
2368 }
2369 lex.scan();
2370 o = new typeIdExpression{node_start_token, type, nullptr};
2371 } else {
2372 o = nullptr;
2373 panic(lex.line, lex.col, "expected `(` or `<` after `type_id` in `type_id` expression");
2374 }
2375 }
2376
2377 void parse(dynCastExpression *&o, lexer &lex) {
2378 if (lex.curToken.kind != lexer::token::tokenKind::kDynCast) {
2379 o = nullptr;
2380 return;
2381 }
2382 lexer::token node_start_token = lex.curToken;
2383 lex.scan();
2384 if (lex.curToken.kind != lexer::token::tokenKind::lessThan) {
2385 o = nullptr;
2386 panic(lex.line, lex.col, "expected `<` after `dyn_cast`");
2387 }
2388 lex.scan();
2389 typeSpec *type = nullptr;
2390 parse(type, lex);
2391 if (!type) {
2392 o = nullptr;
2393 panic(lex.line, lex.col, "expected typeSpec after `<` in `dyn_cast` expression");
2394 }
2395 if (lex.curToken.kind != lexer::token::tokenKind::greaterThan) {
2396 o = nullptr;
2397 finalizeAST(type);
2398 panic(lex.line, lex.col, "expected `>` after typeSpec in `dyn_cast` expression");
2399 }
2400 lex.scan();
2401 if (lex.curToken.kind != lexer::token::tokenKind::leftParentheses) {
2402 o = nullptr;
2403 finalizeAST(type);
2404 panic(lex.line, lex.col, "expected `(` after `>` in `dyn_cast` expression");
2405 }
2406 lex.scan();
2407 rExpr *expr = nullptr;
2408 parse(expr, lex);
2409 if (!expr) {
2410 o = nullptr;
2411 finalizeAST(type);
2412 panic(lex.line, lex.col, "expected expression after `(` in `dyn_cast` expression");
2413 }
2414 if (lex.curToken.kind != lexer::token::tokenKind::rightParentheses) {
2415 o = nullptr;
2416 finalizeAST(type);
2417 finalizeAST(expr);
2418 panic(lex.line, lex.col, "expected `)` after expression in `dyn_cast` expression");
2419 }
2420 lex.scan();
2421 o = new dynCastExpression{node_start_token, type, expr};
2422 }
2423
2424 void parse(abstractExpr *&o, lexer &lex) {
2425 lexer::token node_start_token = lex.curToken;
2426 primary *lhs{};
2427 parse(lhs, lex);
2428 if (!lhs) {
2429 o = nullptr;
2430 return;
2431 }
2432 if (lex.curToken.kind != lexer::token::tokenKind::kInterfaceOf && lex.curToken.kind != lexer::token::tokenKind::kImpl &&
2433 lex.curToken.kind != lexer::token::tokenKind::kAs) {
2434 o = new abstractExpr{node_start_token, lhs, {}, nullptr};
2435 return;
2436 }
2437 o = new abstractExpr{node_start_token, lhs, lex.curToken, nullptr};
2438 lex.scan();
2439
2440 parse(o->rhs, lex);
2441 if (!o->rhs) {
2442 finalizeAST(o);
2443 o = nullptr;
2444 panic(lex.line, lex.col, "expected extern module access expression after `interfaceof` or `impl`");
2445 }
2446 }
2447
2448 void parse(lambdaExpr *&o, lexer &lex) {
2449 lexer::token node_start_token = lex.curToken;
2450 if (lex.curToken.kind != lexer::token::tokenKind::kFunc) {
2451 o = nullptr;
2452 return;
2453 }
2454 lex.saveState();
2455 lex.scan();
2456 if (lex.curToken.kind != lexer::token::tokenKind::leftBracket) {
2457 o = nullptr;
2458 lex.returnState();
2459 return;
2460 }
2461 lex.scan();
2462 vec<yoi::identifier *> captures;
2463 while (lex.curToken.kind == lexer::token::tokenKind::identifier) {
2464 identifier *capture = nullptr;
2465 parse(capture, lex);
2466 captures.push_back(capture);
2467 if (!capture) {
2468 for (auto c : captures)
2469 finalizeAST(c);
2470 o = nullptr;
2471 panic(lex.line, lex.col, "expected identifier in capture list in lambda expression");
2472 }
2473 if (lex.curToken.kind != lexer::token::tokenKind::comma) {
2474 break;
2475 }
2476 lex.scan();
2477 }
2478 if (lex.curToken.kind != lexer::token::tokenKind::rightBracket) {
2479 o = nullptr;
2480 panic(lex.line, lex.col, "expected `]` after capture list in lambda expression");
2481 }
2482 lex.scan();
2483 definitionArguments *args = nullptr;
2484 parse(args, lex);
2485 if (!args) {
2486 o = nullptr;
2487 panic(lex.line, lex.col, "expected arguments after capture list in lambda expression");
2488 }
2489 if (lex.curToken.kind != lexer::token::tokenKind::colon) {
2490 o = nullptr;
2491 finalizeAST(args);
2492 panic(lex.line, lex.col, "expected `:` after arguments in lambda expression");
2493 }
2494 lex.scan();
2495 typeSpec *resultType = nullptr;
2496 parse(resultType, lex);
2497 if (!resultType) {
2498 o = nullptr;
2499 finalizeAST(args);
2500 panic(lex.line, lex.col, "expected typeSpec after `:` in lambda expression");
2501 }
2502 codeBlock *block = nullptr;
2503 parse(block, lex);
2504 if (!block) {
2505 o = nullptr;
2506 finalizeAST(args);
2507 finalizeAST(resultType);
2508 panic(lex.line, lex.col, "expected codeBlock after `:` in lambda expression");
2509 }
2510 lex.dropState();
2511 o = new lambdaExpr{node_start_token, captures, args, resultType, block};
2512 }
2513
2514 void parse(unnamedDefinitionArguments *&o, lexer &lex) {
2515 if (lex.curToken.kind != lexer::token::tokenKind::leftParentheses) {
2516 o = nullptr;
2517 return;
2518 }
2519 lexer::token node_start_token = lex.curToken;
2520 lex.scan();
2521 vec<typeSpec *> types;
2522 while (true) {
2523 typeSpec *type = nullptr;
2524 parse(type, lex);
2525 if (!type) {
2526 o = nullptr;
2527 break;
2528 }
2529 types.push_back(type);
2530 if (lex.curToken.kind != lexer::token::tokenKind::comma) {
2531 break;
2532 }
2533 lex.scan();
2534 }
2535 if (lex.curToken.kind != lexer::token::tokenKind::rightParentheses) {
2536 o = nullptr;
2537 for (auto t : types)
2538 finalizeAST(t);
2539 panic(lex.line, lex.col, "expected `)` after typeSpecs in unnamed definition arguments");
2540 }
2541 lex.scan();
2542 o = new unnamedDefinitionArguments{node_start_token, types};
2543 }
2544
2545 void parse(marcoPair *&o, lexer &lex) {
2546 lexer::token node_start_token = lex.curToken;
2547 lex.saveState();
2548 lexer::token lhs, constraint, rhs;
2549 if (lex.curToken.kind == lexer::token::tokenKind::identifier) {
2550 lhs = lex.curToken;
2551 } else {
2552 lex.returnState();
2553 o = nullptr;
2554 return;
2555 }
2556 lex.scan();
2557 switch (lex.curToken.kind) {
2564 constraint = lex.curToken;
2565 break;
2566 }
2567 default: {
2568 lex.returnState();
2569 o = nullptr;
2570 return;
2571 }
2572 }
2573 lex.scan();
2574 switch (lex.curToken.kind) {
2579 rhs = lex.curToken;
2580 break;
2581 }
2582 default: {
2583 lex.returnState();
2584 o = nullptr;
2585 return;
2586 }
2587 }
2588 lex.scan();
2589 lex.dropState();
2590 o = new marcoPair{node_start_token, lhs, constraint, rhs};
2591 }
2592
2593 void parse(marcoDescriptor *&o, lexer &lex) {
2594 lexer::token current_token = lex.curToken;
2595 lex.saveState();
2596 if (current_token.kind != lexer::token::tokenKind::leftBracket) {
2597 lex.returnState();
2598 o = new marcoDescriptor{current_token, {}};
2599 return;
2600 }
2601 lex.scan();
2602 if (lex.curToken.kind != lexer::token::tokenKind::leftBracket) {
2603 lex.returnState();
2604 o = new marcoDescriptor{current_token, {}};
2605 return;
2606 }
2607 lex.scan();
2608 vec<marcoPair *> pairs;
2609 marcoPair *pair = nullptr;
2610 parse(pair, lex);
2611 while (pair) {
2612 pairs.push_back(pair);
2613 pair = nullptr;
2614 parse(pair, lex);
2615 }
2616 if (lex.curToken.kind != lexer::token::tokenKind::rightBracket) {
2617 o = nullptr;
2618 for (auto p : pairs)
2619 finalizeAST(p);
2620 return;
2621 }
2622 lex.scan();
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 lex.dropState();
2631 o = new marcoDescriptor{current_token, pairs};
2632 }
2633
2634 void parse(typeAliasStmt *&o, lexer &lex) {
2635 lexer::token node_start_token = lex.curToken;
2636 if (lex.curToken.kind != lexer::token::tokenKind::kAlias) {
2637 o = nullptr;
2638 return;
2639 }
2640 lex.scan();
2641 identifierWithDefTemplateArg *lhs;
2642 parse(lhs, lex);
2643 if (!lhs) {
2644 panic(lex.line, lex.col, "expected identifier with definition template arguments in type alias statement");
2645 o = nullptr;
2646 return;
2647 }
2648 if (lex.curToken.kind != lexer::token::tokenKind::assignSign) {
2649 o = nullptr;
2650 finalizeAST(lhs);
2651 panic(lex.line, lex.col, "expected `=` after identifier in type alias statement");
2652 return;
2653 }
2654 lex.scan();
2655 typeSpec *rhs = nullptr;
2656 parse(rhs, lex);
2657 if (!rhs) {
2658 o = nullptr;
2659 finalizeAST(lhs);
2660 panic(lex.line, lex.col, "expected typeSpec after `=` in type alias statement");
2661 return;
2662 }
2663 o = new typeAliasStmt{node_start_token, lhs, rhs};
2664 }
2665
2666 void parse(finalizerDecl *&o, lexer &lex) {
2667 lexer::token node_start_token = lex.curToken;
2668 if (lex.curToken.kind != lexer::token::tokenKind::kFinalizer) {
2669 o = nullptr;
2670 return;
2671 }
2672 lex.scan();
2673 if (lex.curToken.kind != lexer::token::tokenKind::leftParentheses) {
2674 o = nullptr;
2675 panic(lex.line, lex.col, "expected `(` after `finalizer` in finalizer declaration");
2676 }
2677 lex.scan();
2678 if (lex.curToken.kind != lexer::token::tokenKind::rightParentheses) {
2679 o = nullptr;
2680 panic(lex.line, lex.col, "expected `)` after `finalizer` in finalizer declaration");
2681 }
2682 lex.scan();
2683 o = new finalizerDecl{node_start_token};
2684 }
2685
2686 void parse(finalizerDef *&o, lexer &lex) {
2687 lexer::token node_start_token = lex.curToken;
2688 if (lex.curToken.kind != lexer::token::tokenKind::kFinalizer) {
2689 o = nullptr;
2690 return;
2691 }
2692 lex.scan();
2693 if (lex.curToken.kind != lexer::token::tokenKind::leftParentheses) {
2694 o = nullptr;
2695 panic(lex.line, lex.col, "expected `(` after `finalizer` in finalizer definition");
2696 }
2697 lex.scan();
2698 if (lex.curToken.kind != lexer::token::tokenKind::rightParentheses) {
2699 o = nullptr;
2700 panic(lex.line, lex.col, "expected `)` after `finalizer` in finalizer definition");
2701 }
2702 lex.scan();
2703 codeBlock *block = nullptr;
2704 parse(block, lex);
2705 if (!block) {
2706 o = nullptr;
2707 panic(lex.line, lex.col, "expected codeBlock after `finalizer` declaration");
2708 return;
2709 }
2710 o = new finalizerDef{node_start_token, block};
2711 }
2712
2713 void parse(funcExpr *&o, lexer &lex) {
2714 lexer::token node_start_token = lex.curToken;
2715 if (lex.curToken.kind != lexer::token::tokenKind::kFunc) {
2716 o = nullptr;
2717 return;
2718 }
2719 lex.saveState();
2720 lex.scan();
2721 externModuleAccessExpression *name = nullptr;
2722 parse(name, lex);
2723 if (!name) {
2724 o = nullptr;
2725 lex.returnState();
2726 return;
2727 }
2728 lex.dropState();
2729 unnamedDefinitionArguments *args = nullptr;
2730 parse(args, lex);
2731 if (!args) {
2732 o = new funcExpr{node_start_token, name, nullptr};
2733 return;
2734 }
2735 o = new funcExpr{node_start_token, name, args};
2736 }
2737
2738 void parse(enumerationDefinition *&o, lexer &lex) {
2739 lexer::token node_start_token = lex.curToken;
2740 if (lex.curToken.kind != lexer::token::tokenKind::kEnum) {
2741 o = nullptr;
2742 return;
2743 }
2744 lex.scan();
2745 identifier *name = nullptr;
2746 parse(name, lex);
2747 if (!name) {
2748 o = nullptr;
2749 panic(lex.line, lex.col, "expected identifier after `enum` in enumeration definition");
2750 return;
2751 }
2752 if (lex.curToken.kind != lexer::token::tokenKind::leftBraces) {
2753 o = nullptr;
2754 finalizeAST(name);
2755 panic(lex.line, lex.col, "expected `{` after identifier in enumeration definition");
2756 return;
2757 }
2758 lex.scan();
2759 vec<enumerationPair *> enumerators;
2760 enumerationPair *enumerator = nullptr;
2761 parse(enumerator, lex);
2762 while (enumerator) {
2763 enumerators.push_back(enumerator);
2764 if (lex.curToken.kind != lexer::token::tokenKind::comma) {
2765 break;
2766 } else {
2767 enumerator = nullptr;
2768 lex.scan();
2769 parse(enumerator, lex);
2770 }
2771 }
2772 if (lex.curToken.kind != lexer::token::tokenKind::rightBraces) {
2773 o = nullptr;
2774 for (auto e : enumerators)
2775 finalizeAST(e);
2776 finalizeAST(name);
2777 panic(lex.line, lex.col, "expected `}` after enumerators in enumeration definition");
2778 return;
2779 }
2780 lex.scan();
2781 o = new enumerationDefinition{node_start_token, name, enumerators};
2782 }
2783
2784 void parse(enumerationPair *&o, lexer &lex) {
2785 lexer::token node_start_token = lex.curToken;
2786 identifier *name = nullptr;
2787 parse(name, lex);
2788 if (!name) {
2789 o = nullptr;
2790 return;
2791 }
2792 if (lex.curToken.kind != lexer::token::tokenKind::assignSign) {
2793 o = new enumerationPair{node_start_token, name, {}};
2794 return;
2795 }
2796 lex.scan();
2797 lexer::token value = lex.curToken;
2799 o = new enumerationPair{node_start_token, name, value};
2800 lex.scan();
2801 } else if (value.kind == lexer::token::tokenKind::minus) {
2802 lex.scan();
2803 if (lex.curToken.kind != lexer::token::tokenKind::integer) {
2804 o = nullptr;
2805 finalizeAST(name);
2806 panic(lex.line, lex.col, "expected integer literal after `-` in enumeration pair");
2807 return;
2808 }
2809 value = lex.curToken;
2810 value.basicVal.vInt = -value.basicVal.vInt;
2811 o = new enumerationPair{node_start_token, name, value};
2812 lex.scan();
2813 } else {
2814 o = nullptr;
2815 finalizeAST(name);
2816 panic(lex.line, lex.col, "expected integer literal after `=` in enumeration pair");
2817 return;
2818 }
2819 }
2820
2821 void parse(bracedInitalizerList *&o, lexer &lex) {
2822 if (lex.curToken.kind != lexer::token::tokenKind::leftBraces) {
2823 o = nullptr;
2824 return;
2825 }
2826 yoi::lexer::token node_start_token = lex.curToken;
2827 lex.saveState();
2828 lex.scan();
2829 vec<rExpr *> expressions;
2830 rExpr *expression = nullptr;
2831 parse(expression, lex);
2832 while (expression) {
2833 expressions.push_back(expression);
2834 if (lex.curToken.kind != lexer::token::tokenKind::comma) {
2835 break;
2836 } else {
2837 expression = nullptr;
2838 lex.scan();
2839 parse(expression, lex);
2840 }
2841 }
2842 if (lex.curToken.kind != lexer::token::tokenKind::rightBraces) {
2843 o = nullptr;
2844 for (auto e : expressions)
2845 finalizeAST(e);
2846 lex.returnState();
2847 return;
2848 }
2849 lex.scan();
2850 lex.dropState();
2851 o = new bracedInitalizerList{node_start_token, expressions};
2852 }
2853
2854 void parse(yieldStmt *&o, lexer &lex) {
2855 if (lex.curToken.kind != lexer::token::tokenKind::kYield) {
2856 o = nullptr;
2857 return;
2858 }
2859 yoi::lexer::token node_start_token = lex.curToken;
2860 lex.scan();
2861 rExpr *expr = nullptr;
2862 parse(expr, lex);
2863 if (!expr) {
2864 o = nullptr;
2865 panic(lex.line, lex.col, "expected rExpr after `yield` in yieldStmt");
2866 return;
2867 }
2868 o = new yieldStmt{node_start_token, expr};
2869 }
2870
2871 void parse(decltypeExpr *&o, lexer &lex) {
2872 lexer::token node_start_token{lex.curToken};
2873 if (lex.curToken.kind != lexer::token::tokenKind::kDecltype) {
2874 o = nullptr;
2875 return;
2876 }
2877 lex.scan();
2878 yoi_assert(lex.curToken.kind == lexer::token::tokenKind::leftParentheses, lex.curToken.line, lex.curToken.col, "expected `(` after `decltype` keyword");
2879 lex.scan();
2880 rExpr *expr{};
2881 parse(expr, lex);
2882 yoi_assert(expr, lex.line, lex.col, "expected expression after `(` for decltype-expression");
2883 if (lex.curToken.kind != lexer::token::tokenKind::rightParentheses) {
2884 o = nullptr;
2885 finalizeAST(expr);
2886 panic(lex.line, lex.col, "expected `)` after expression");
2887 }
2888 lex.scan();
2889 o = new decltypeExpr{node_start_token, expr};
2890 }
2891
2892 void parse(satisfyStmt *&o, lexer &lex) {
2893 if (lex.curToken.kind != lexer::token::tokenKind::kSatisfy) {
2894 o = nullptr;
2895 return;
2896 }
2897 yoi::lexer::token node_start_token = lex.curToken;
2898 lex.scan();
2899 externModuleAccessExpression *emae = nullptr;
2900 parse(emae, lex);
2901 if (!emae) {
2902 o = nullptr;
2903 panic(lex.line, lex.col, "expected externModuleAccessExpression after `satisfy` in satisfyStmt");
2904 return;
2905 }
2906 o = new satisfyStmt{node_start_token, emae};
2907 }
2908
2909 void parse(conceptStmt *&o, lexer &lex) {
2910 yoi::lexer::token node_start_token = lex.curToken;
2911
2912 satisfyStmt *s{};
2913 parse(s, lex);
2914 if (s) {
2915 o = new conceptStmt{node_start_token, conceptStmt::Kind::SatisfyStmt, s};
2916 return;
2917 }
2918
2919 rExpr *e{};
2920 parse(e, lex);
2921 if (e) {
2922 o = new conceptStmt{node_start_token, conceptStmt::Kind::Expression, e};
2923 return;
2924 }
2925 }
2926
2927 void parse(conceptDefinition *&o, lexer &lex) {
2928 if (lex.curToken.kind != lexer::token::tokenKind::kConcept) {
2929 o = nullptr;
2930 return;
2931 }
2932 yoi::lexer::token node_start_token = lex.curToken;
2933 lex.scan();
2934
2935 lexer::token name{};
2936 yoi::vec<lexer::token> typeParams;
2937 yoi_assert(lex.curToken.kind == lexer::token::tokenKind::identifier, lex.curToken.line, lex.curToken.col, "expected identifier after `concept` in conceptDefinition");
2938 name = lex.curToken;
2939 lex.scan();
2940
2941 yoi_assert(lex.curToken.kind == lexer::token::tokenKind::lessThan, lex.curToken.line, lex.curToken.col, "expected `<` after concept name in conceptDefinition");
2942 lex.scan();
2943
2944 while (lex.curToken.kind == lexer::token::tokenKind::identifier) {
2945 typeParams.push_back(lex.curToken);
2946 lex.scan();
2947 if (lex.curToken.kind == lexer::token::tokenKind::comma) {
2948 lex.scan();
2949 } else {
2950 break;
2951 }
2952 }
2953 yoi_assert(lex.curToken.kind == lexer::token::tokenKind::greaterThan, lex.curToken.line, lex.curToken.col, "expected `>` after type parameters in conceptDefinition");
2954 lex.scan();
2955
2956 yoi_assert(lex.curToken.kind == lexer::token::tokenKind::leftParentheses, lex.curToken.line, lex.curToken.col, "expected `(` after `>`");
2957 lex.scan();
2958
2960 identifierWithTypeSpec *spec{};
2961 parse(spec, lex);
2962 while (spec) {
2963 specs.push_back(spec);
2964 if (lex.curToken.kind == lexer::token::tokenKind::comma) {
2965 lex.scan();
2966 spec = nullptr;
2967 parse(spec, lex);
2968 } else {
2969 break;
2970 }
2971 }
2972 yoi_assert(lex.curToken.kind == lexer::token::tokenKind::rightParentheses, lex.curToken.line, lex.curToken.col, "expected `)` after specs");
2973 lex.scan();
2974
2975 if (lex.curToken.kind != lexer::token::tokenKind::leftBraces) {
2976 o = nullptr;
2977 for (auto s : specs)
2978 finalizeAST(s);
2979 panic(lex.line, lex.col, "expected `{` after `)`");
2980 return;
2981 }
2982 lex.scan();
2983
2984 yoi::vec<conceptStmt *> conceptStmts;
2985 conceptStmt *stmt{};
2986 parse(stmt, lex);
2987 while (stmt) {
2988 conceptStmts.push_back(stmt);
2989 stmt = nullptr;
2990 parse(stmt, lex);
2991 }
2992 yoi_assert(lex.curToken.kind == lexer::token::tokenKind::rightBraces, lex.curToken.line, lex.curToken.col, "expected `}` after satisfyClauses");
2993 lex.scan();
2994
2995 o = new conceptDefinition{node_start_token, name, typeParams, specs, conceptStmts};
2996 }
2997
2998 void parse(satisfyClause *&o, lexer &lex) {
2999 if (lex.curToken.kind != lexer::token::tokenKind::kSatisfy) {
3000 o = nullptr;
3001 return;
3002 }
3003 lexer::token node_start_token = lex.curToken;
3004 lex.scan();
3005 yoi_assert(lex.curToken.kind == lexer::token::tokenKind::leftParentheses, lex.curToken.line, lex.curToken.col, "expected `(` after `satisfy`");
3006 lex.scan();
3007
3009 externModuleAccessExpression *spec{};
3010 parse(spec, lex);
3011 while (spec) {
3012 specs.push_back(spec);
3013 if (lex.curToken.kind == lexer::token::tokenKind::comma) {
3014 lex.scan();
3015 spec = nullptr;
3016 parse(spec, lex);
3017 } else {
3018 break;
3019 }
3020 }
3021 if (lex.curToken.kind != lexer::token::tokenKind::rightParentheses) {
3022 o = nullptr;
3023 for (auto s : specs)
3024 finalizeAST(s);
3025 panic(lex.line, lex.col, "expected `)` after specs");
3026 return;
3027 }
3028 lex.scan();
3029 o = new satisfyClause{node_start_token, specs};
3030 }
3031} // namespace yoi
3032
3033#pragma clang diagnostic pop
bool hasTemplateArg() const
Definition ast.cpp:75
token scan()
Definition lexer.cpp:29
token curToken
Definition lexer.hpp:172
int64_t col
Definition lexer.hpp:175
int64_t line
Definition lexer.hpp:175
void saveState()
Definition lexer.cpp:543
void returnState()
Definition lexer.cpp:547
void dropState()
Definition lexer.cpp:555
subscript * length
Definition ast.hpp:405
invocationArguments * args
Definition ast.hpp:406
externModuleAccessExpression * type
Definition ast.hpp:404
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:53
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:171
void finalizeAST(funcTypeSpec *ptr)
Definition ast.cpp:475
uint64_t indexT
Definition def.hpp:51
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:131
#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