hoshi-lang dev
Yet another programming language
Loading...
Searching...
No Matches
formatter.cpp
Go to the documentation of this file.
1//
2// Created by XIaokang00010 on 2025/2/16.
3//
4
5#include "formatter.hpp"
8#include "share/def.hpp"
9#include <ostream>
10
11yoi::FormatOption::FormatOption(IndentType indentType, size_t indentSize, BraceType braceType, size_t maxWidth)
12 : indentType(indentType), indentSize(indentSize), braceType(braceType), maxWidth(maxWidth) {}
13
14void yoi::formatToken(std::wostream &os, FormatOption option, const lexer::token &token) {
15 switch (token.kind) {
17 break;
19 os << token.strVal;
20 break;
22 os << '\'' << yoi::escapeString(token.strVal) << '\'';
23 break;
25 os << '\"' << yoi::escapeString(token.strVal) << '\"';
26 break;
28 os << token.basicVal.vInt;
29 break;
31 os << token.basicVal.vUint << "u";
32 break;
34 os << token.basicVal.vShort << "s";
35 break;
37 os << token.basicVal.vDeci;
38 break;
40 os << (token.basicVal.vBool ? L"true" : L"false");
41 break;
43 os << L"->";
44 break;
46 os << L"+";
47 break;
49 os << L"-";
50 break;
52 os << L"*";
53 break;
55 os << L"/";
56 break;
58 os << L"%";
59 break;
61 os << L"^";
62 break;
64 os << L"|";
65 break;
67 os << L"&";
68 break;
70 os << L"~";
71 break;
73 os << L"!";
74 break;
76 os << L"++";
77 break;
79 os << L"--";
80 break;
82 os << L"<<";
83 break;
85 os << L">>";
86 break;
88 os << L"+=";
89 break;
91 os << L"-=";
92 break;
94 os << L"*=";
95 break;
97 os << L"/=";
98 break;
100 os << L"%=";
101 break;
103 os << L">";
104 break;
106 os << L"<";
107 break;
109 os << L">=";
110 break;
112 os << L"<=";
113 break;
115 os << L"==";
116 break;
118 os << L"!=";
119 break;
121 os << L"&&";
122 break;
124 os << L"||";
125 break;
127 os << L"=";
128 break;
130 os << L":=";
131 break;
133 os << L"(";
134 break;
136 os << L")";
137 break;
139 os << L"[";
140 break;
142 os << L"]";
143 break;
145 os << L"{";
146 break;
148 os << L"}";
149 break;
151 os << L";";
152 break;
154 os << L":";
155 break;
157 os << L",";
158 break;
160 os << L".";
161 break;
163 os << L"#";
164 break;
166 os << L"yield";
167 break;
169 os << L"use";
170 break;
172 os << L"func";
173 break;
175 os << L"interface";
176 break;
178 os << L"constructor";
179 break;
181 os << L"finalizer";
182 break;
184 os << L"struct";
185 break;
187 os << L"impl";
188 break;
190 os << L"let";
191 break;
193 os << L"in";
194 break;
196 os << L"for";
197 break;
199 os << L"forEach";
200 break;
202 os << L"while";
203 break;
205 os << L"if";
206 break;
208 os << L"elif";
209 break;
211 os << L"else";
212 break;
214 os << L"return";
215 break;
217 os << L"continue";
218 break;
220 os << L"break";
221 break;
223 os << L"cast";
224 break;
226 os << L"null";
227 break;
229 os << L"import";
230 break;
232 os << L"export";
233 break;
235 os << L"as";
236 break;
238 os << L"from";
239 break;
241 os << L"try";
242 break;
244 os << L"catch";
245 break;
247 os << L"finally";
248 break;
250 os << L"throw";
251 break;
253 os << L"type_id";
254 break;
256 os << L"dyn_cast";
257 break;
259 os << L"noffi";
260 break;
262 os << L"static";
263 break;
265 os << L"intrinsic";
266 break;
268 os << L"always_inline";
269 break;
271 os << L"new";
272 break;
274 os << L"callable";
275 break;
277 os << L"...";
278 break;
280 os << L"interfaceof";
281 break;
283 os << L"alias";
284 break;
286 os << L"enum";
287 break;
289 os << L"datastruct";
290 break;
292 os << L"datafield";
293 break;
295 os << L"generator";
296 break;
298 os << "decltype";
299 break;
301 os << "concept";
302 break;
304 os << "satisfy";
305 break;
307 break;
308 }
309}
310
311yoi::Formatter::Formatter(std::wostream &os, FormatOption option) : os(os), option(option), lastLine(-1) {}
312
314 : os(os), option(option), comments(std::move(comments)), lastLine(-1) {}
315
317 for (size_t i = 0; i < indentLevel * option.indentSize; ++i) {
318 yoi::wstr s = (option.indentType == FormatOption::IndentType::Space ? L" " : L"\t");
319 os << s;
320 currentColumn += (option.indentType == FormatOption::IndentType::Space ? 1 : option.indentSize);
321 }
322}
323
325 os << L"\n";
326 currentColumn = 0;
327 indent();
328}
329
331 os << s;
332 currentColumn += s.length();
333}
334
336 if (!node) return false;
337 return printComments(node->getLine(), node->getColumn());
338}
339
340bool yoi::Formatter::printComments(uint64_t line, uint64_t col) {
341 bool printedStandalone = false;
342 while (lastCommentIdx < comments.size() &&
343 (comments[lastCommentIdx].line < line ||
344 (comments[lastCommentIdx].line == line && comments[lastCommentIdx].col < col))) {
345
346 const auto &comment = comments[lastCommentIdx++];
347 if (lastLine != (uint64_t)-1) {
348 if (comment.line > lastLine) {
349 newLine();
350 } else {
351 write(L" ");
352 }
353 }
354 write(trim(comment.text));
355 lastLine = comment.line;
356 if (comment.line < line) {
357 printedStandalone = true;
358 }
359 }
360 if (printedStandalone) {
361 newLine();
362 return true;
363 }
364 return false;
365}
366
368 std::wstringstream ss;
369 yoi::formatToken(ss, option, token);
370 write(ss.str());
371}
372
374 if (!node || option.maxWidth == (size_t)-1) return true;
375 std::wstringstream ss;
376 FormatOption tempOpt = option;
377 tempOpt.maxWidth = (size_t)-1;
378 Formatter temp(ss, tempOpt);
379 temp.format(node);
380 return currentColumn + ss.str().length() <= option.maxWidth;
381}
382
384 if (!node) return;
385 format(node->node);
386}
387
389 if (!node) return;
390 format(node->node);
391}
392
394 if (!node) return;
395 format(node->id);
396 write(L": ");
397 format(node->spec);
398}
399
401 if (!node) return;
402 format(node->id);
403 if (node->satisfyCondition) {
404 os << " ";
405 format(node->satisfyCondition);
406 }
407}
408
410 if (!node || node->spec.empty()) return;
411 write(L"<");
412 for (size_t i = 0; i < node->spec.size(); ++i) {
413 format(node->spec[i]);
414 if (i < node->spec.size() - 1) write(L", ");
415 }
416 write(L">");
417}
418
420 if (!node) return;
421 format(node->spec);
422}
423
425 if (!node || node->spec.empty()) return;
426 write(L"<");
427 for (size_t i = 0; i < node->spec.size(); ++i) {
428 format(node->spec[i]);
429 if (i < node->spec.size() - 1) write(L", ");
430 }
431 write(L">");
432}
433
435 if (!node) return;
436 if (willFit(node)) {
437 write(L"(");
438 for (size_t i = 0; i < node->arg.size(); ++i) {
439 format(node->arg[i]);
440 if (i < node->arg.size() - 1) write(L", ");
441 }
442 write(L")");
443 } else {
444 write(L"(");
445 indentLevel++;
446 for (size_t i = 0; i < node->arg.size(); ++i) {
447 newLine();
448 format(node->arg[i]);
449 if (i < node->arg.size() - 1) write(L",");
450 }
451 indentLevel--;
452 newLine();
453 write(L")");
454 }
455}
456
458 if (!node) return;
459 // For simplicity, we use the same willFit logic (invocationArguments is used for measurement)
460 // but in a real implementation we'd have a more generic measure function.
461 write(L"(");
462 for (size_t i = 0; i < node->spec.size(); ++i) {
463 format(node->spec[i]);
464 if (i < node->spec.size() - 1) write(L", ");
465 }
466 write(L")");
467}
468
470 if (!node) return;
471 write(L"func");
472 format(node->args);
473 write(L" : ");
474 format(node->resultType);
475}
476
478 if (!node) return;
480 write(L"...");
481 format(node->elipsis);
482 } else if (node->isNull) {
483 write(L"null");
484 } else if (node->kind == typeSpec::typeSpecKind::Member) {
485 format(node->member);
486 } else if (node->kind == typeSpec::typeSpecKind::Func) {
487 format(node->func);
488 } else if (node->kind == typeSpec::typeSpecKind::DecltypeExpr) {
489 format(node->decltypeExpression);
490 }
491
492 if (node->arraySubscript) {
493 for (auto val : *node->arraySubscript) {
494 write(L"[");
495 if (val != (uint64_t)-1) write(yoi::string2wstring(std::to_string(val)));
496 write(L"]");
497 }
498 }
499}
500
502 if (!node) return;
503 if (node->isInvocation()) {
504 format(node->args);
505 } else {
506 write(L"[");
507 format(node->expr);
508 write(L"]");
509 }
510}
511
513 if (!node) return;
514 format(node->id);
515 if (node->hasTemplateArg()) {
516 format(node->arg);
517 }
518}
519
521 if (!node) return;
522 format(node->id);
523 if (node->hasDefTemplateArg()) {
524 format(node->arg);
525 }
526}
527
529 if (!node) return;
530 format(node->id);
531 for (auto s : node->subscriptVal) {
532 format(s);
533 }
534}
535
537 if (!node) return;
538 for (size_t i = 0; i < node->terms.size(); ++i) {
539 format(node->terms[i]);
540 if (i < node->terms.size() - 1) write(L".");
541 }
542}
543
545 if (!node) return;
546 switch (node->kind) {
547 case primary::primaryKind::memberExpr: format(node->member); break;
548 case primary::primaryKind::basicLiterals: format(node->literals); break;
550 write(L"(");
551 format(node->expr);
552 write(L")");
553 break;
554 case primary::primaryKind::typeIdExpression: format(node->typeId); break;
555 case primary::primaryKind::dynCastExpression: format(node->dynCast); break;
556 case primary::primaryKind::newExpression: format(node->newExpr); break;
557 case primary::primaryKind::lambdaExpr: format(node->lambda); break;
558 case primary::primaryKind::funcExpr: format(node->func); break;
560 }
561}
562
564 if (!node) return;
565 format(node->lhs);
567 write(L" ");
568 format(node->op);
569 write(L" ");
570 format(node->rhs);
571 }
572}
573
575 if (!node) return;
577 format(node->op);
578 }
579 format(node->lhs);
580}
581
583 if (!node) return;
584 format(node->lhs);
585 if (node->hasRhs()) {
586 write(L" ");
587 format(node->op);
588 write(L" ");
589 format(node->rhs);
590 }
591}
592
593#define FORMAT_BINARY_EXPR(NODE_TYPE) \
594void yoi::Formatter::format(NODE_TYPE *node) { \
595 if (!node) return; \
596 for (size_t i = 0; i < node->terms.size(); ++i) { \
597 format(node->terms[i]); \
598 if (i < node->ops.size()) { \
599 write(L" "); \
600 format(node->ops[i]); \
601 write(L" "); \
602 } \
603 } \
604}
605
606FORMAT_BINARY_EXPR(mulExpr)
607FORMAT_BINARY_EXPR(addExpr)
608FORMAT_BINARY_EXPR(shiftExpr)
609FORMAT_BINARY_EXPR(relationalExpr)
610FORMAT_BINARY_EXPR(equalityExpr)
611FORMAT_BINARY_EXPR(andExpr)
612FORMAT_BINARY_EXPR(exclusiveExpr)
613FORMAT_BINARY_EXPR(inclusiveExpr)
614FORMAT_BINARY_EXPR(logicalAndExpr)
615FORMAT_BINARY_EXPR(logicalOrExpr)
616
617void yoi::Formatter::format(rExpr *node) {
618 if (!node) return;
619 format(node->expr);
620}
621
623 if (!node) return;
624 for (size_t i = 0; i < node->terms.size(); ++i) {
625 format(node->terms[i]);
626 if (i < node->terms.size() - 1) write(L".");
627 }
628}
629
631 if (!node) return;
632 if (option.braceType == FormatOption::BraceType::NewLine) {
633 newLine();
634 } else {
635 os << L" ";
636 }
637 os << L"{";
638 indentLevel++;
639 for (auto stmt : node->stmts) {
640 if (!printComments(stmt)) {
641 newLine();
642 }
643 format(stmt);
644 lastLine = std::max(lastLine, stmt->getLine());
645 printComments(stmt->getLine(), -1);
646 }
647 indentLevel--;
648 newLine();
649 os << L"}";
650}
651
653 if (!node) return;
654 write(L"if (");
655 format(node->ifB.cond);
656 write(L")");
657 format(node->ifB.block);
658 for (auto &elif : node->elifB) {
659 write(L" elif (");
660 format(elif.cond);
661 write(L")");
662 format(elif.block);
663 }
664 if (node->hasElseBlock()) {
665 write(L" else");
666 format(node->elseB);
667 }
668}
669
671 if (!node) return;
672 os << L"while (";
673 format(node->cond);
674 os << L")";
675 format(node->block);
676}
677
679 if (!node) return;
680 os << L"for (";
681 format(node->initStmt);
682 os << L"; ";
683 format(node->cond);
684 os << L"; ";
685 format(node->afterStmt);
686 os << L")";
687 format(node->block);
688}
689
691 if (!node) return;
692 os << L"forEach (";
693 format(node->var);
694 os << L" : ";
695 format(node->container);
696 os << L")";
697 format(node->block);
698}
699
701 if (!node) return;
702 os << L"return";
703 if (node->hasValue()) {
704 os << L" ";
705 format(node->value);
706 }
707}
708
710 if (!node) return;
711 os << L"continue";
712}
713
715 if (!node) return;
716 os << L"break";
717}
718
720 if (!node) return;
721 if (node->marco) {
722 format(node->marco);
723 }
724 switch (node->kind) {
725 case inCodeBlockStmt::vKind::ifStmt: format(node->value.ifStmtVal); break;
726 case inCodeBlockStmt::vKind::whileStmt: format(node->value.whileStmtVal); break;
727 case inCodeBlockStmt::vKind::forStmt: format(node->value.forStmtVal); break;
729 case inCodeBlockStmt::vKind::returnStmt: format(node->value.returnStmtVal); break;
731 case inCodeBlockStmt::vKind::breakStmt: format(node->value.breakStmtVal); break;
732 case inCodeBlockStmt::vKind::letStmt: format(node->value.letStmtVal); break;
733 case inCodeBlockStmt::vKind::codeBlock: format(node->value.codeBlockVal); break;
734 case inCodeBlockStmt::vKind::tryCatchStmt: format((tryCatchStmt *)node->value.ptr); break;
735 case inCodeBlockStmt::vKind::throwStmt: format((throwStmt *)node->value.ptr); break;
736 case inCodeBlockStmt::vKind::rExpr: format(node->value.rExprVal); break;
737 case inCodeBlockStmt::vKind::yieldStmt: format(node->value.yieldStmtVal); break;
738 }
739}
740
742 if (!node) return;
743 os << L"use ";
744 format(node->name);
745 os << L" \"";
746 os << yoi::escapeString(node->path.strVal);
747 os << L"\"";
748}
749
751 if (!node) return;
752 os << L"func ";
753 for (auto &attr : node->attrs) {
754 formatToken(os, option, attr);
755 os << L" ";
756 }
757 format(node->id);
758 format(node->args);
759 os << L" : ";
760 format(node->resultType);
761 format(node->block);
762}
763
765 if (!node) return;
766 if (node->isMethod()) {
767 format(node->method);
768 } else {
769 format(node->var);
770 }
771}
772
774 if (!node) return;
775 if (option.braceType == FormatOption::BraceType::NewLine) {
776 newLine();
777 } else {
778 os << L" ";
779 }
780 os << L"{";
781 indentLevel++;
782 for (auto pair : node->inner) {
783 if (!printComments(pair)) {
784 newLine();
785 }
786 format(pair);
787 lastLine = std::max(lastLine, pair->getLine());
788 printComments(pair->getLine(), -1);
789 }
790 indentLevel--;
791 newLine();
792 os << L"}";
793}
794
796 if (!node) return;
797 write(L"interface ");
798 format(node->id);
799 format(node->inner);
800}
801
803 if (!node) return;
804 switch (node->kind) {
805 case 0:
806 if (node->modifier == structDefInnerPair::Modifier::DataField) write(L"datafield ");
807 format(node->var);
808 break;
809 case 1: format(node->con); break;
810 case 2: format(node->method); break;
811 case 3: format(node->finalizer); break;
812 }
813}
814
816 if (!node) return;
817 if (option.braceType == FormatOption::BraceType::NewLine) {
818 newLine();
819 } else {
820 os << L" ";
821 }
822 os << L"{";
823 indentLevel++;
824 for (auto it = node->inner.begin(); it != node->inner.end(); it++) {
825 auto pair = *it;
826 if (!printComments(pair)) {
827 newLine();
828 }
829 format(pair);
830 if (it + 1 != node->inner.end()) {
831 write(L",");
832 }
833 lastLine = std::max(lastLine, pair->getLine());
834 printComments(pair->getLine(), -1);
835 }
836 indentLevel--;
837 newLine();
838 os << L"}";
839}
840
842 if (!node) return;
843 write(L"struct ");
844 format(node->id);
845 format(node->inner);
846}
847
849 if (!node) return;
850 write(L"datastruct ");
851 format(node->id);
852 format(node->inner);
853}
854
856 if (!node) return;
857 if (node->isConstructor()) format(node->con);
858 else if (node->isMethod()) format(node->met);
859 else if (node->isFinalizer()) format(node->finalizer);
860}
861
863 if (!node) return;
864 if (option.braceType == FormatOption::BraceType::NewLine) {
865 newLine();
866 } else {
867 os << L" ";
868 }
869 os << L"{";
870 indentLevel++;
871 for (auto pair : node->inner) {
872 if (!printComments(pair)) {
873 newLine();
874 }
875 format(pair);
876 lastLine = std::max(lastLine, pair->getLine());
877 printComments(pair->getLine(), -1);
878 }
879 indentLevel--;
880 newLine();
881 os << L"}";
882}
883
885 if (!node) return;
886 write(L"impl ");
887 if (node->interfaceName) {
888 format(node->structName);
889 write(L" : ");
890 format(node->interfaceName);
891 } else {
892 format(node->structName);
893 }
894 format(node->inner);
895}
896
898 if (!node) return;
899 format(node->lhs);
900 if (node->type) {
901 os << L" : ";
902 format(node->type);
903 }
904 if (node->rhs) {
905 os << L" = ";
906 format(node->rhs);
907 }
908}
909
911 if (!node) return;
912 os << L"let ";
913 for (size_t i = 0; i < node->terms.size(); ++i) {
914 format(node->terms[i]);
915 if (i < node->terms.size() - 1) os << L", ";
916 }
917}
918
920 if (!node) return;
921 if (node->marco) format(node->marco);
922 switch (node->kind) {
923 case globalStmt::vKind::useStmt: format(node->value.useStmtVal); break;
924 case globalStmt::vKind::funcDefStmt: format(node->value.funcDefStmtVal); break;
928 case globalStmt::vKind::implStmt: format(node->value.implStmtVal); break;
929 case globalStmt::vKind::letStmt: format(node->value.letStmtVal); break;
930 case globalStmt::vKind::importDecl: format(node->value.importDeclVal); break;
931 case globalStmt::vKind::exportDecl: format(node->value.exportDeclVal); break;
934 case globalStmt::vKind::conceptDef: format(node->value.conceptDefVal); break;
935 }
936}
937
939 if (!node) return;
940 for (auto &attr : node->attrs) {
941 formatToken(os, option, attr);
942 os << L" ";
943 }
944 os << L"export ";
945 format(node->from);
946 if (node->as) {
947 os << L" as ";
948 format(node->as);
949 }
950}
951
953 if (!node) return;
954 os << L"import ";
955 format(node->inner);
956 os << L" from \"";
957 os << node->from_path.strVal;
958 os << L"\"";
959}
960
961void yoi::Formatter::format(importInner *node) {
962}
963
965 if (!node) return;
966 os << L"throw ";
967 format(node->expr);
968}
969
971 if (!node) return;
972 os << L"catch (";
973 format(node->name);
974 os << L": ";
975 format(node->type);
976 os << L")";
977 format(node->block);
978}
979
981 if (!node) return;
982 os << L"try";
983 format(node->tryBlock);
984 for (auto cp : node->catchParams) {
985 os << L" ";
986 format(cp);
987 }
988 if (node->finallyBlock) {
989 os << L" finally";
990 format(node->finallyBlock);
991 }
992}
993
995 if (!node) return;
996 os << L"dyn_cast<";
997 format(node->type);
998 os << L">(";
999 format(node->expr);
1000 os << L")";
1001}
1002
1004 if (!node) return;
1005 os << L"type_id";
1006 if (node->type) {
1007 os << L"<";
1008 format(node->type);
1009 os << L">";
1010 }
1011 if (node->expr) {
1012 os << L"(";
1013 format(node->expr);
1014 os << L")";
1015 }
1016}
1017
1019 if (!node) return;
1020 os << L"new ";
1021 format(node->type);
1022 if (node->length) format(node->length);
1023 if (node->args) format(node->args);
1024}
1025
1027 if (!node) return;
1028 os << L"func[";
1029 for (size_t i = 0; i < node->captures.size(); ++i) {
1030 format(node->captures[i]);
1031 if (i < node->captures.size() - 1) os << L", ";
1032 }
1033 os << L"] ";
1034 format(node->args);
1035 os << L" : ";
1036 format(node->resultType);
1037 format(node->block);
1038}
1039
1041 if (!node) return;
1042 write(L" (");
1043 for (size_t i = 0; i < node->types.size(); ++i) {
1044 format(node->types[i]);
1045 if (i < node->types.size() - 1) write(L", ");
1046 }
1047 write(L")");
1048}
1049
1051 if (!node) return;
1052 os << node->identifier.strVal;
1054 os << L": " << node->constraint.strVal;
1055 }
1056 os << L" = " << node->rhs.strVal;
1057}
1058
1060 if (!node || node->pairs.empty()) return;
1061 os << L"#(";
1062 for (size_t i = 0; i < node->pairs.size(); ++i) {
1063 format(node->pairs[i]);
1064 if (i < node->pairs.size() - 1) os << L", ";
1065 }
1066 os << L") ";
1067}
1068
1070 if (!node) return;
1071 os << L"alias ";
1072 format(node->lhs);
1073 os << L" = ";
1074 format(node->rhs);
1075}
1076
1078 if (!node) return;
1079 os << L"finalizer";
1080 format(node->block);
1081}
1082
1084 if (!node) return;
1085 os << L"finalizer";
1086}
1087
1089 if (!node) return;
1090 os << L"func ";
1091 format(node->name);
1092 format(node->args);
1093}
1094
1096 if (!node) return;
1098 format(node->id);
1099 } else {
1100 os << L"[";
1101 for (size_t i = 0; i < node->list.size(); ++i) {
1102 formatToken(os, option, node->list[i]);
1103 if (i < node->list.size() - 1) os << L", ";
1104 }
1105 os << L"]";
1106 }
1107}
1108
1110 if (!node) return;
1111 os << L"enum ";
1112 format(node->name);
1113 os << L" {";
1114 indentLevel++;
1115 for (size_t i = 0; i < node->values.size(); ++i) {
1116 if (!printComments(node->values[i])) {
1117 newLine();
1118 }
1119 format(node->values[i]);
1120 if (i < node->values.size() - 1) os << L",";
1121 lastLine = std::max(lastLine, node->values[i]->getLine());
1122 printComments(node->values[i]->getLine(), -1);
1123 }
1124 indentLevel--;
1125 newLine();
1126 os << L"}";
1127}
1128
1130 if (!node) return;
1131 format(node->name);
1133 os << L" = ";
1134 formatToken(os, option, node->value);
1135 }
1136}
1137
1139 if (!node) return;
1140 os << L"{";
1141 for (size_t i = 0; i < node->exprs.size(); ++i) {
1142 format(node->exprs[i]);
1143 if (i < node->exprs.size() - 1) os << L", ";
1144 }
1145 os << L"}";
1146}
1147
1149 if (!node) return;
1150 for (auto it = node->stmts.begin(); it != node->stmts.end(); ++it) {
1151 if (it != node->stmts.begin()) {
1152 auto prev = std::prev(it);
1153 if (((*prev)->kind == globalStmt::vKind::useStmt || (*prev)->kind == globalStmt::vKind::importDecl) &&
1154 ((*it)->kind == globalStmt::vKind::useStmt || (*it)->kind == globalStmt::vKind::importDecl)) {
1155 os << L"\n";
1156 // indent();
1157 } else {
1158 os << L"\n\n";
1159 // indent();
1160 }
1161 }
1162
1163 bool printedStandalone = printComments(*it);
1164 format(*it);
1165 lastLine = std::max(lastLine, (*it)->getLine());
1166 printComments((*it)->getLine(), -1);
1167 }
1168 printComments(-1, -1);
1169}
1170
1172 if (!node) return;
1173 for (auto &attr : node->attrs) {
1174 formatToken(os, option, attr);
1175 os << L" ";
1176 }
1177 format(node->name);
1178 format(node->args);
1179 if (node->resultType) {
1180 os << L" : ";
1181 format(node->resultType);
1182 }
1183}
1184
1186 if (!node) return;
1187 for (auto &attr : node->attrs) {
1188 formatToken(os, option, attr);
1189 os << L" ";
1190 }
1191 format(node->name);
1192 format(node->args);
1193 if (node->resultType) {
1194 os << L" : ";
1195 format(node->resultType);
1196 }
1197 format(node->block);
1198}
1199
1201 if (!node) return;
1202 os << L"constructor";
1203 if (node->tempArgs) format(node->tempArgs);
1204 format(node->args);
1205}
1206
1208 if (!node) return;
1209 os << L"constructor";
1210 if (node->tempArgs) format(node->tempArgs);
1211 format(node->args);
1212 format(node->block);
1213}
1214
1216 if (!node) return;
1217 os << L"yield ";
1218 format(node->expr);
1219}
1220
1222 os << "decltype(";
1223 format(node->expr);
1224 os << ")";
1225}
1226
1228 if (!node) return;
1229 os << L"concept " << node->name.strVal << L"<";
1230 for (auto it = node->typeParams.begin(); it != node->typeParams.end(); it++) {
1231 if (it != node->typeParams.begin()) {
1232 os << ", ";
1233 }
1234 os << it->strVal;
1235 }
1236 os << ">(";
1237 for (auto it = node->algebraParams.begin(); it != node->algebraParams.end(); it++) {
1238 if (it != node->algebraParams.begin()) {
1239 os << ", ";
1240 }
1241 format(*it);
1242 }
1243 os << ") {";
1244 indentLevel++;
1245 for (auto it = node->conceptBlock.begin(); it != node->conceptBlock.end(); it++) {
1246 newLine();
1247 format(*it);
1248 }
1249 indentLevel--;
1250 newLine();
1251 os << "}";
1252}
1253
1255 if (!node) return;
1256 switch (node->kind) {
1258 format(node->value.expression);
1259 break;
1260 }
1262 format(node->value.satisfyStmt);
1263 break;
1264 }
1265 default:
1266 break;
1267 }
1268}
1269
1271 os << L"satisfy ";
1272 format(node->emae);
1273}
1274
1276 os << L"satisfy(";
1277 for (auto it = node->emaes.begin(); it != node->emaes.end(); it++) {
1278 if (it != node->emaes.begin()) {
1279 os << ", ";
1280 }
1281 format(*it);
1282 }
1283 os << ")";
1284}
yoi::indexT getColumn()
Definition ast.cpp:1037
yoi::indexT getLine()
Definition ast.cpp:1041
void format(const lexer::token &token)
bool willFit(invocationArguments *node)
void write(const yoi::wstr &s)
Formatter(std::wostream &os, FormatOption option)
bool printComments(AST *node)
externModuleAccessExpression * rhs
Definition ast.hpp:446
primary * lhs
Definition ast.hpp:444
lexer::token op
Definition ast.hpp:445
lexer::token node
Definition ast.hpp:253
yoi::vec< yoi::rExpr * > exprs
Definition ast.hpp:216
codeBlock * block
Definition ast.hpp:1058
identifier * name
Definition ast.hpp:1057
typeSpec * type
Definition ast.hpp:1056
vec< inCodeBlockStmt * > stmts
Definition ast.hpp:1015
yoi::vec< identifierWithTypeSpec * > algebraParams
Definition ast.hpp:1106
yoi::vec< lexer::token > typeParams
Definition ast.hpp:1105
yoi::vec< conceptStmt * > conceptBlock
Definition ast.hpp:1108
lexer::token name
Definition ast.hpp:1104
union yoi::conceptStmt::ConceptStmtValue value
enum yoi::conceptStmt::Kind kind
defTemplateArg * tempArgs
Definition ast.hpp:985
definitionArguments * args
Definition ast.hpp:986
codeBlock * block
Definition ast.hpp:999
templateArg * tempArgs
Definition ast.hpp:997
definitionArguments * args
Definition ast.hpp:998
structDefInner * inner
Definition ast.hpp:716
identifier * id
Definition ast.hpp:715
rExpr * expr
Definition ast.hpp:621
satisfyClause * satisfyCondition
Definition ast.hpp:278
identifier * id
Definition ast.hpp:277
vec< defTemplateArgSpec * > spec
Definition ast.hpp:285
vec< identifierWithTypeSpec * > spec
Definition ast.hpp:313
vec< enumerationPair * > values
Definition ast.hpp:1088
lexer::token value
Definition ast.hpp:1094
identifier * name
Definition ast.hpp:1093
typeSpec * from
Definition ast.hpp:1039
identifier * as
Definition ast.hpp:1040
yoi::vec< lexer::token > attrs
Definition ast.hpp:1038
vec< identifierWithTemplateArg * > terms
Definition ast.hpp:1029
codeBlock * block
Definition ast.hpp:1008
codeBlock * block
Definition ast.hpp:888
rExpr * container
Definition ast.hpp:887
identifier * var
Definition ast.hpp:886
codeBlock * block
Definition ast.hpp:873
inCodeBlockStmt * afterStmt
Definition ast.hpp:872
inCodeBlockStmt * initStmt
Definition ast.hpp:870
rExpr * cond
Definition ast.hpp:871
codeBlock * block
Definition ast.hpp:630
identifierWithDefTemplateArg * id
Definition ast.hpp:627
typeSpec * resultType
Definition ast.hpp:629
yoi::vec< lexer::token > attrs
Definition ast.hpp:626
definitionArguments * args
Definition ast.hpp:628
externModuleAccessExpression * name
Definition ast.hpp:247
unnamedDefinitionArguments * args
Definition ast.hpp:248
typeSpec * resultType
Definition ast.hpp:321
unnamedDefinitionArguments * args
Definition ast.hpp:320
union yoi::globalStmt::vValue value
enum yoi::globalStmt::vKind kind
marcoDescriptor * marco
Definition ast.hpp:809
vec< globalStmt * > stmts
Definition ast.hpp:1022
bool hasTemplateArg() const
Definition ast.cpp:75
lexer::token node
Definition ast.hpp:260
vec< ifBlock > elifB
Definition ast.hpp:846
codeBlock * elseB
Definition ast.hpp:847
ifBlock ifB
Definition ast.hpp:845
bool hasElseBlock() const
Definition ast.cpp:415
bool isFinalizer() const
Definition ast.cpp:1201
bool isMethod() const
Definition ast.cpp:1197
innerMethodDef * met
Definition ast.hpp:728
finalizerDef * finalizer
Definition ast.hpp:730
constructorDef * con
Definition ast.hpp:726
bool isConstructor() const
Definition ast.cpp:351
vec< implInnerPair * > inner
Definition ast.hpp:747
implInner * inner
Definition ast.hpp:756
externModuleAccessExpression * structName
Definition ast.hpp:755
externModuleAccessExpression * interfaceName
Definition ast.hpp:754
lexer::token from_path
Definition ast.hpp:1046
innerMethodDecl * inner
Definition ast.hpp:1045
union yoi::inCodeBlockStmt::vValue value
enum yoi::inCodeBlockStmt::vKind kind
marcoDescriptor * marco
Definition ast.hpp:928
typeSpec * resultType
Definition ast.hpp:957
yoi::vec< lexer::token > attrs
Definition ast.hpp:954
identifierWithDefTemplateArg * name
Definition ast.hpp:955
definitionArguments * args
Definition ast.hpp:956
codeBlock * block
Definition ast.hpp:972
typeSpec * resultType
Definition ast.hpp:971
yoi::vec< lexer::token > attrs
Definition ast.hpp:968
definitionArguments * args
Definition ast.hpp:970
identifierWithTemplateArg * name
Definition ast.hpp:969
innerMethodDecl * method
Definition ast.hpp:649
identifierWithTypeSpec * var
Definition ast.hpp:644
vec< interfaceDefInnerPair * > inner
Definition ast.hpp:658
identifierWithDefTemplateArg * id
Definition ast.hpp:665
interfaceDefInner * inner
Definition ast.hpp:666
vec< rExpr * > arg
Definition ast.hpp:306
codeBlock * block
Definition ast.hpp:242
typeSpec * resultType
Definition ast.hpp:241
vec< yoi::identifier * > captures
Definition ast.hpp:239
definitionArguments * args
Definition ast.hpp:240
rExpr * rhs
Definition ast.hpp:471
lexer::token op
Definition ast.hpp:469
uniqueExpr * lhs
Definition ast.hpp:470
bool hasRhs() const
Definition ast.cpp:135
vec< lexer::token > list
Definition ast.hpp:771
enum yoi::letAssignmentPairLHS::vKind kind
letAssignmentPairLHS * lhs
Definition ast.hpp:776
typeSpec * type
Definition ast.hpp:777
vec< letAssignmentPair * > terms
Definition ast.hpp:787
yoi::vec< marcoPair * > pairs
Definition ast.hpp:234
lexer::token identifier
Definition ast.hpp:227
lexer::token rhs
Definition ast.hpp:229
lexer::token constraint
Definition ast.hpp:228
vec< subscriptExpr * > terms
Definition ast.hpp:397
subscript * length
Definition ast.hpp:405
invocationArguments * args
Definition ast.hpp:406
externModuleAccessExpression * type
Definition ast.hpp:404
lambdaExpr * lambda
Definition ast.hpp:430
enum yoi::primary::primaryKind kind
funcExpr * func
Definition ast.hpp:431
memberExpr * member
Definition ast.hpp:424
rExpr * expr
Definition ast.hpp:426
basicLiterals * literals
Definition ast.hpp:425
newExpression * newExpr
Definition ast.hpp:429
bracedInitalizerList * bracedInitalizer
Definition ast.hpp:432
typeIdExpression * typeId
Definition ast.hpp:427
dynCastExpression * dynCast
Definition ast.hpp:428
rExpr * value
Definition ast.hpp:899
bool hasValue() const
Definition ast.cpp:459
yoi::vec< externModuleAccessExpression * > emaes
Definition ast.hpp:1134
externModuleAccessExpression * emae
Definition ast.hpp:1129
innerMethodDecl * method
Definition ast.hpp:683
enum yoi::structDefInnerPair::Modifier modifier
constructorDecl * con
Definition ast.hpp:681
finalizerDecl * finalizer
Definition ast.hpp:685
identifierWithTypeSpec * var
Definition ast.hpp:679
vec< structDefInnerPair * > inner
Definition ast.hpp:698
structDefInner * inner
Definition ast.hpp:706
identifierWithDefTemplateArg * id
Definition ast.hpp:705
vec< subscript * > subscriptVal
Definition ast.hpp:388
identifierWithTemplateArg * id
Definition ast.hpp:387
bool isInvocation() const
Definition ast.cpp:1075
rExpr * expr
Definition ast.hpp:351
invocationArguments * args
Definition ast.hpp:352
typeSpec * spec
Definition ast.hpp:292
vec< templateArgSpec * > spec
Definition ast.hpp:299
rExpr * expr
Definition ast.hpp:1051
vec< catchParam * > catchParams
Definition ast.hpp:1064
codeBlock * tryBlock
Definition ast.hpp:1063
codeBlock * finallyBlock
Definition ast.hpp:1065
yoi::identifierWithDefTemplateArg * lhs
Definition ast.hpp:221
yoi::typeSpec * rhs
Definition ast.hpp:222
typeSpec * type
Definition ast.hpp:1070
decltypeExpr * decltypeExpression
Definition ast.hpp:340
yoi::vec< uint64_t > * arraySubscript
Definition ast.hpp:342
externModuleAccessExpression * member
Definition ast.hpp:337
funcTypeSpec * func
Definition ast.hpp:338
enum yoi::typeSpec::typeSpecKind kind
typeSpec * elipsis
Definition ast.hpp:339
bool isNull
Definition ast.hpp:341
lexer::token op
Definition ast.hpp:457
abstractExpr * lhs
Definition ast.hpp:458
vec< typeSpec * > types
Definition ast.hpp:1082
identifier * name
Definition ast.hpp:611
lexer::token path
Definition ast.hpp:612
codeBlock * block
Definition ast.hpp:861
rExpr * cond
Definition ast.hpp:860
rExpr * expr
Definition ast.hpp:1099
#define FORMAT_BINARY_EXPR(NODE_TYPE)
std::vector< t > vec
Definition def.hpp:53
std::wstring string2wstring(const std::string &v)
Definition def.cpp:178
void formatToken(std::wostream &os, FormatOption option, const lexer::token &token)
Definition formatter.cpp:14
wstr escapeString(const wstr &value)
Definition def.cpp:84
std::wstring wstr
Definition def.hpp:48
std::basic_string< T > trim(const std::basic_string< T > &str)
Definition def.hpp:70
FormatOption()=default
codeBlock * block
Definition ast.hpp:838
enum yoi::lexer::token::tokenKind kind
union yoi::lexer::token::vBasicValue basicVal
dataStructDefStmt * dataStructDefStmtVal
Definition ast.hpp:815
enumerationDefinition * enumerationDefVal
Definition ast.hpp:822
useStmt * useStmtVal
Definition ast.hpp:812
implStmt * implStmtVal
Definition ast.hpp:816
interfaceDefStmt * interfaceDefStmtVal
Definition ast.hpp:813
letStmt * letStmtVal
Definition ast.hpp:817
conceptDefinition * conceptDefVal
Definition ast.hpp:823
funcDefStmt * funcDefStmtVal
Definition ast.hpp:818
typeAliasStmt * typeAliasStmtVal
Definition ast.hpp:821
exportDecl * exportDeclVal
Definition ast.hpp:820
structDefStmt * structDefStmtVal
Definition ast.hpp:814
importDecl * importDeclVal
Definition ast.hpp:819
forEachStmt * forEachStmtVal
Definition ast.hpp:933
returnStmt * returnStmtVal
Definition ast.hpp:934
continueStmt * continueStmtVal
Definition ast.hpp:935