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"weak";
296 break;
298 os << L"generator";
299 break;
301 os << "decltype";
302 break;
304 os << "concept";
305 break;
307 os << "satisfy";
308 break;
310 break;
311 }
312}
313
314yoi::Formatter::Formatter(std::wostream &os, FormatOption option) : os(os), option(option), lastLine(-1) {}
315
317 : os(os), option(option), comments(std::move(comments)), lastLine(-1) {}
318
320 for (size_t i = 0; i < indentLevel * option.indentSize; ++i) {
321 yoi::wstr s = (option.indentType == FormatOption::IndentType::Space ? L" " : L"\t");
322 os << s;
323 currentColumn += (option.indentType == FormatOption::IndentType::Space ? 1 : option.indentSize);
324 }
325}
326
328 os << L"\n";
329 currentColumn = 0;
330 indent();
331}
332
334 os << s;
335 currentColumn += s.length();
336}
337
339 if (!node) return false;
340 return printComments(node->getLine(), node->getColumn());
341}
342
343bool yoi::Formatter::printComments(uint64_t line, uint64_t col) {
344 bool printedStandalone = false;
345 while (lastCommentIdx < comments.size() &&
346 (comments[lastCommentIdx].line < line ||
347 (comments[lastCommentIdx].line == line && comments[lastCommentIdx].col < col))) {
348
349 const auto &comment = comments[lastCommentIdx++];
350 if (lastLine != (uint64_t)-1) {
351 if (comment.line > lastLine) {
352 newLine();
353 } else {
354 write(L" ");
355 }
356 }
357 write(trim(comment.text));
358 lastLine = comment.line;
359 if (comment.line < line) {
360 printedStandalone = true;
361 }
362 }
363 if (printedStandalone) {
364 newLine();
365 return true;
366 }
367 return false;
368}
369
371 std::wstringstream ss;
372 yoi::formatToken(ss, option, token);
373 write(ss.str());
374}
375
377 if (!node || option.maxWidth == (size_t)-1) return true;
378 std::wstringstream ss;
379 FormatOption tempOpt = option;
380 tempOpt.maxWidth = (size_t)-1;
381 Formatter temp(ss, tempOpt);
382 temp.format(node);
383 return currentColumn + ss.str().length() <= option.maxWidth;
384}
385
387 if (!node) return;
388 format(node->node);
389}
390
392 if (!node) return;
393 format(node->node);
394}
395
397 if (!node) return;
398 format(node->id);
399 write(L": ");
400 format(node->spec);
401}
402
404 if (!node) return;
405 format(node->id);
406 if (node->satisfyCondition) {
407 os << " ";
408 format(node->satisfyCondition);
409 }
410}
411
413 if (!node || node->spec.empty()) return;
414 write(L"<");
415 for (size_t i = 0; i < node->spec.size(); ++i) {
416 format(node->spec[i]);
417 if (i < node->spec.size() - 1) write(L", ");
418 }
419 write(L">");
420}
421
423 if (!node) return;
424 format(node->spec);
425}
426
428 if (!node || node->spec.empty()) return;
429 write(L"<");
430 for (size_t i = 0; i < node->spec.size(); ++i) {
431 format(node->spec[i]);
432 if (i < node->spec.size() - 1) write(L", ");
433 }
434 write(L">");
435}
436
438 if (!node) return;
439 if (willFit(node)) {
440 write(L"(");
441 for (size_t i = 0; i < node->arg.size(); ++i) {
442 format(node->arg[i]);
443 if (i < node->arg.size() - 1) write(L", ");
444 }
445 write(L")");
446 } else {
447 write(L"(");
448 indentLevel++;
449 for (size_t i = 0; i < node->arg.size(); ++i) {
450 newLine();
451 format(node->arg[i]);
452 if (i < node->arg.size() - 1) write(L",");
453 }
454 indentLevel--;
455 newLine();
456 write(L")");
457 }
458}
459
461 if (!node) return;
462 // For simplicity, we use the same willFit logic (invocationArguments is used for measurement)
463 // but in a real implementation we'd have a more generic measure function.
464 write(L"(");
465 for (size_t i = 0; i < node->spec.size(); ++i) {
466 format(node->spec[i]);
467 if (i < node->spec.size() - 1) write(L", ");
468 }
469 write(L")");
470}
471
473 if (!node) return;
474 write(L"func");
475 format(node->args);
476 write(L" : ");
477 format(node->resultType);
478}
479
481 if (!node) return;
483 write(L"...");
484 format(node->elipsis);
485 } else if (node->isNull) {
486 write(L"null");
487 } else if (node->kind == typeSpec::typeSpecKind::Member) {
488 format(node->member);
489 } else if (node->kind == typeSpec::typeSpecKind::Func) {
490 format(node->func);
491 } else if (node->kind == typeSpec::typeSpecKind::DecltypeExpr) {
492 format(node->decltypeExpression);
493 }
494
495 if (node->arraySubscript) {
496 for (auto val : *node->arraySubscript) {
497 write(L"[");
498 if (val != (uint64_t)-1) write(yoi::string2wstring(std::to_string(val)));
499 write(L"]");
500 }
501 }
502}
503
505 if (!node) return;
506 if (node->isInvocation()) {
507 format(node->args);
508 } else {
509 write(L"[");
510 format(node->expr);
511 write(L"]");
512 }
513}
514
516 if (!node) return;
517 format(node->id);
518 if (node->hasTemplateArg()) {
519 format(node->arg);
520 }
521}
522
524 if (!node) return;
525 format(node->id);
526 if (node->hasDefTemplateArg()) {
527 format(node->arg);
528 }
529}
530
532 if (!node) return;
533 format(node->id);
534 for (auto s : node->subscriptVal) {
535 format(s);
536 }
537}
538
540 if (!node) return;
541 for (size_t i = 0; i < node->terms.size(); ++i) {
542 format(node->terms[i]);
543 if (i < node->terms.size() - 1) write(L".");
544 }
545}
546
548 if (!node) return;
549 switch (node->kind) {
550 case primary::primaryKind::memberExpr: format(node->member); break;
551 case primary::primaryKind::basicLiterals: format(node->literals); break;
553 write(L"(");
554 format(node->expr);
555 write(L")");
556 break;
557 case primary::primaryKind::typeIdExpression: format(node->typeId); break;
558 case primary::primaryKind::dynCastExpression: format(node->dynCast); break;
559 case primary::primaryKind::newExpression: format(node->newExpr); break;
560 case primary::primaryKind::lambdaExpr: format(node->lambda); break;
561 case primary::primaryKind::funcExpr: format(node->func); break;
563 }
564}
565
567 if (!node) return;
568 format(node->lhs);
570 write(L" ");
571 format(node->op);
572 write(L" ");
573 format(node->rhs);
574 }
575}
576
578 if (!node) return;
580 format(node->op);
581 }
582 format(node->lhs);
583}
584
586 if (!node) return;
587 format(node->lhs);
588 if (node->hasRhs()) {
589 write(L" ");
590 format(node->op);
591 write(L" ");
592 format(node->rhs);
593 }
594}
595
596#define FORMAT_BINARY_EXPR(NODE_TYPE) \
597void yoi::Formatter::format(NODE_TYPE *node) { \
598 if (!node) return; \
599 for (size_t i = 0; i < node->terms.size(); ++i) { \
600 format(node->terms[i]); \
601 if (i < node->ops.size()) { \
602 write(L" "); \
603 format(node->ops[i]); \
604 write(L" "); \
605 } \
606 } \
607}
608
609FORMAT_BINARY_EXPR(mulExpr)
610FORMAT_BINARY_EXPR(addExpr)
611FORMAT_BINARY_EXPR(shiftExpr)
612FORMAT_BINARY_EXPR(relationalExpr)
613FORMAT_BINARY_EXPR(equalityExpr)
614FORMAT_BINARY_EXPR(andExpr)
615FORMAT_BINARY_EXPR(exclusiveExpr)
616FORMAT_BINARY_EXPR(inclusiveExpr)
617FORMAT_BINARY_EXPR(logicalAndExpr)
618FORMAT_BINARY_EXPR(logicalOrExpr)
619
620void yoi::Formatter::format(rExpr *node) {
621 if (!node) return;
622 format(node->expr);
623}
624
626 if (!node) return;
627 for (size_t i = 0; i < node->terms.size(); ++i) {
628 format(node->terms[i]);
629 if (i < node->terms.size() - 1) write(L".");
630 }
631}
632
634 if (!node) return;
635 if (option.braceType == FormatOption::BraceType::NewLine) {
636 newLine();
637 } else {
638 os << L" ";
639 }
640 os << L"{";
641 indentLevel++;
642 for (auto stmt : node->stmts) {
643 if (!printComments(stmt)) {
644 newLine();
645 }
646 format(stmt);
647 lastLine = std::max(lastLine, stmt->getLine());
648 printComments(stmt->getLine(), -1);
649 }
650 indentLevel--;
651 newLine();
652 os << L"}";
653}
654
656 if (!node) return;
657 write(L"if (");
658 format(node->ifB.cond);
659 write(L")");
660 format(node->ifB.block);
661 for (auto &elif : node->elifB) {
662 write(L" elif (");
663 format(elif.cond);
664 write(L")");
665 format(elif.block);
666 }
667 if (node->hasElseBlock()) {
668 write(L" else");
669 format(node->elseB);
670 }
671}
672
674 if (!node) return;
675 os << L"while (";
676 format(node->cond);
677 os << L")";
678 format(node->block);
679}
680
682 if (!node) return;
683 os << L"for (";
684 format(node->initStmt);
685 os << L"; ";
686 format(node->cond);
687 os << L"; ";
688 format(node->afterStmt);
689 os << L")";
690 format(node->block);
691}
692
694 if (!node) return;
695 os << L"forEach (";
696 format(node->var);
697 os << L" : ";
698 format(node->container);
699 os << L")";
700 format(node->block);
701}
702
704 if (!node) return;
705 os << L"return";
706 if (node->hasValue()) {
707 os << L" ";
708 format(node->value);
709 }
710}
711
713 if (!node) return;
714 os << L"continue";
715}
716
718 if (!node) return;
719 os << L"break";
720}
721
723 if (!node) return;
724 if (node->marco) {
725 format(node->marco);
726 }
727 switch (node->kind) {
728 case inCodeBlockStmt::vKind::ifStmt: format(node->value.ifStmtVal); break;
729 case inCodeBlockStmt::vKind::whileStmt: format(node->value.whileStmtVal); break;
730 case inCodeBlockStmt::vKind::forStmt: format(node->value.forStmtVal); break;
732 case inCodeBlockStmt::vKind::returnStmt: format(node->value.returnStmtVal); break;
734 case inCodeBlockStmt::vKind::breakStmt: format(node->value.breakStmtVal); break;
735 case inCodeBlockStmt::vKind::letStmt: format(node->value.letStmtVal); break;
736 case inCodeBlockStmt::vKind::codeBlock: format(node->value.codeBlockVal); break;
737 case inCodeBlockStmt::vKind::tryCatchStmt: format((tryCatchStmt *)node->value.ptr); break;
738 case inCodeBlockStmt::vKind::throwStmt: format((throwStmt *)node->value.ptr); break;
739 case inCodeBlockStmt::vKind::rExpr: format(node->value.rExprVal); break;
740 case inCodeBlockStmt::vKind::yieldStmt: format(node->value.yieldStmtVal); break;
741 }
742}
743
745 if (!node) return;
746 os << L"use ";
747 format(node->name);
748 os << L" \"";
749 os << yoi::escapeString(node->path.strVal);
750 os << L"\"";
751}
752
754 if (!node) return;
755 os << L"func ";
756 for (auto &attr : node->attrs) {
757 formatToken(os, option, attr);
758 os << L" ";
759 }
760 format(node->id);
761 format(node->args);
762 os << L" : ";
763 format(node->resultType);
764 format(node->block);
765}
766
768 if (!node) return;
769 if (node->isMethod()) {
770 format(node->method);
771 } else {
772 format(node->var);
773 }
774}
775
777 if (!node) return;
778 if (option.braceType == FormatOption::BraceType::NewLine) {
779 newLine();
780 } else {
781 os << L" ";
782 }
783 os << L"{";
784 indentLevel++;
785 for (auto pair : node->inner) {
786 if (!printComments(pair)) {
787 newLine();
788 }
789 format(pair);
790 lastLine = std::max(lastLine, pair->getLine());
791 printComments(pair->getLine(), -1);
792 }
793 indentLevel--;
794 newLine();
795 os << L"}";
796}
797
799 if (!node) return;
800 write(L"interface ");
801 format(node->id);
802 format(node->inner);
803}
804
806 if (!node) return;
807 switch (node->kind) {
808 case 0:
809 if (node->modifier == structDefInnerPair::Modifier::DataField) write(L"datafield ");
810 if (node->modifier == structDefInnerPair::Modifier::Weak) write(L"weak ");
811 format(node->var);
812 break;
813 case 1: format(node->con); break;
814 case 2: format(node->method); break;
815 case 3: format(node->finalizer); break;
816 }
817}
818
820 if (!node) return;
821 if (option.braceType == FormatOption::BraceType::NewLine) {
822 newLine();
823 } else {
824 os << L" ";
825 }
826 os << L"{";
827 indentLevel++;
828 for (auto it = node->inner.begin(); it != node->inner.end(); it++) {
829 auto pair = *it;
830 if (!printComments(pair)) {
831 newLine();
832 }
833 format(pair);
834 if (it + 1 != node->inner.end()) {
835 write(L",");
836 }
837 lastLine = std::max(lastLine, pair->getLine());
838 printComments(pair->getLine(), -1);
839 }
840 indentLevel--;
841 newLine();
842 os << L"}";
843}
844
846 if (!node) return;
847 write(L"struct ");
848 format(node->id);
849 format(node->inner);
850}
851
853 if (!node) return;
854 write(L"datastruct ");
855 format(node->id);
856 format(node->inner);
857}
858
860 if (!node) return;
861 if (node->isConstructor()) format(node->con);
862 else if (node->isMethod()) format(node->met);
863 else if (node->isFinalizer()) format(node->finalizer);
864}
865
867 if (!node) return;
868 if (option.braceType == FormatOption::BraceType::NewLine) {
869 newLine();
870 } else {
871 os << L" ";
872 }
873 os << L"{";
874 indentLevel++;
875 for (auto it = node->inner.begin(); it != node->inner.end(); it++) {
876 auto pair = *it;
877 if (!printComments(pair)) {
878 newLine();
879 }
880 format(pair);
881 if (it + 1 != node->inner.end()) {
882 os << L",";
883 }
884 lastLine = std::max(lastLine, pair->getLine());
885 printComments(pair->getLine(), -1);
886 }
887 indentLevel--;
888 newLine();
889 os << L"}";
890}
891
893 if (!node) return;
894 write(L"impl ");
895 if (node->interfaceName) {
896 format(node->structName);
897 write(L" : ");
898 format(node->interfaceName);
899 } else {
900 format(node->structName);
901 }
902 format(node->inner);
903}
904
906 if (!node) return;
907 format(node->lhs);
908 if (node->type) {
909 os << L" : ";
910 format(node->type);
911 }
912 if (node->rhs) {
913 os << L" = ";
914 format(node->rhs);
915 }
916}
917
919 if (!node) return;
920 os << L"let ";
921 for (size_t i = 0; i < node->terms.size(); ++i) {
922 format(node->terms[i]);
923 if (i < node->terms.size() - 1) os << L", ";
924 }
925}
926
928 if (!node) return;
929 if (node->marco) format(node->marco);
930 switch (node->kind) {
931 case globalStmt::vKind::useStmt: format(node->value.useStmtVal); break;
932 case globalStmt::vKind::funcDefStmt: format(node->value.funcDefStmtVal); break;
936 case globalStmt::vKind::implStmt: format(node->value.implStmtVal); break;
937 case globalStmt::vKind::letStmt: format(node->value.letStmtVal); break;
938 case globalStmt::vKind::importDecl: format(node->value.importDeclVal); break;
939 case globalStmt::vKind::exportDecl: format(node->value.exportDeclVal); break;
942 case globalStmt::vKind::conceptDef: format(node->value.conceptDefVal); break;
943 }
944}
945
947 if (!node) return;
948 for (auto &attr : node->attrs) {
949 formatToken(os, option, attr);
950 os << L" ";
951 }
952 os << L"export ";
953 format(node->from);
954 if (node->as) {
955 os << L" as ";
956 format(node->as);
957 }
958}
959
961 if (!node) return;
962 os << L"import ";
963 format(node->inner);
964 os << L" from \"";
965 os << node->from_path.strVal;
966 os << L"\"";
967}
968
969void yoi::Formatter::format(importInner *node) {
970}
971
973 if (!node) return;
974 os << L"throw ";
975 format(node->expr);
976}
977
979 if (!node) return;
980 os << L"catch (";
981 format(node->name);
982 os << L": ";
983 format(node->type);
984 os << L")";
985 format(node->block);
986}
987
989 if (!node) return;
990 os << L"try";
991 format(node->tryBlock);
992 for (auto cp : node->catchParams) {
993 os << L" ";
994 format(cp);
995 }
996 if (node->finallyBlock) {
997 os << L" finally";
998 format(node->finallyBlock);
999 }
1000}
1001
1003 if (!node) return;
1004 os << L"dyn_cast<";
1005 format(node->type);
1006 os << L">(";
1007 format(node->expr);
1008 os << L")";
1009}
1010
1012 if (!node) return;
1013 os << L"type_id";
1014 if (node->type) {
1015 os << L"<";
1016 format(node->type);
1017 os << L">";
1018 }
1019 if (node->expr) {
1020 os << L"(";
1021 format(node->expr);
1022 os << L")";
1023 }
1024}
1025
1027 if (!node) return;
1028 os << L"new ";
1029 format(node->type);
1030 if (node->length) format(node->length);
1031 if (node->args) format(node->args);
1032}
1033
1035 if (!node) return;
1036 os << L"func[";
1037 for (size_t i = 0; i < node->captures.size(); ++i) {
1038 format(node->captures[i]);
1039 if (i < node->captures.size() - 1) os << L", ";
1040 }
1041 os << L"] ";
1042 format(node->args);
1043 os << L" : ";
1044 format(node->resultType);
1045 format(node->block);
1046}
1047
1049 if (!node) return;
1050 write(L" (");
1051 for (size_t i = 0; i < node->types.size(); ++i) {
1052 format(node->types[i]);
1053 if (i < node->types.size() - 1) write(L", ");
1054 }
1055 write(L")");
1056}
1057
1059 if (!node) return;
1060 os << node->identifier.strVal;
1062 os << L": " << node->constraint.strVal;
1063 }
1064 os << L" = " << node->rhs.strVal;
1065}
1066
1068 if (!node || node->pairs.empty()) return;
1069 os << L"#(";
1070 for (size_t i = 0; i < node->pairs.size(); ++i) {
1071 format(node->pairs[i]);
1072 if (i < node->pairs.size() - 1) os << L", ";
1073 }
1074 os << L") ";
1075}
1076
1078 if (!node) return;
1079 os << L"alias ";
1080 format(node->lhs);
1081 os << L" = ";
1082 format(node->rhs);
1083}
1084
1086 if (!node) return;
1087 os << L"finalizer";
1088 format(node->block);
1089}
1090
1092 if (!node) return;
1093 os << L"finalizer";
1094}
1095
1097 if (!node) return;
1098 os << L"func ";
1099 format(node->name);
1100 format(node->args);
1101}
1102
1104 if (!node) return;
1106 format(node->id);
1107 } else {
1108 os << L"[";
1109 for (size_t i = 0; i < node->list.size(); ++i) {
1110 formatToken(os, option, node->list[i]);
1111 if (i < node->list.size() - 1) os << L", ";
1112 }
1113 os << L"]";
1114 }
1115}
1116
1118 if (!node) return;
1119 os << L"enum ";
1120 format(node->name);
1121 os << L" {";
1122 indentLevel++;
1123 for (size_t i = 0; i < node->values.size(); ++i) {
1124 if (!printComments(node->values[i])) {
1125 newLine();
1126 }
1127 format(node->values[i]);
1128 if (i < node->values.size() - 1) os << L",";
1129 lastLine = std::max(lastLine, node->values[i]->getLine());
1130 printComments(node->values[i]->getLine(), -1);
1131 }
1132 indentLevel--;
1133 newLine();
1134 os << L"}";
1135}
1136
1138 if (!node) return;
1139 format(node->name);
1141 os << L" = ";
1142 formatToken(os, option, node->value);
1143 }
1144}
1145
1147 if (!node) return;
1148 os << L"{";
1149 for (size_t i = 0; i < node->exprs.size(); ++i) {
1150 format(node->exprs[i]);
1151 if (i < node->exprs.size() - 1) os << L", ";
1152 }
1153 os << L"}";
1154}
1155
1157 if (!node) return;
1158 for (auto it = node->stmts.begin(); it != node->stmts.end(); ++it) {
1159 if (it != node->stmts.begin()) {
1160 auto prev = std::prev(it);
1161 if (((*prev)->kind == globalStmt::vKind::useStmt || (*prev)->kind == globalStmt::vKind::importDecl) &&
1162 ((*it)->kind == globalStmt::vKind::useStmt || (*it)->kind == globalStmt::vKind::importDecl)) {
1163 os << L"\n";
1164 // indent();
1165 } else {
1166 os << L"\n\n";
1167 // indent();
1168 }
1169 }
1170
1171 bool printedStandalone = printComments(*it);
1172 format(*it);
1173 lastLine = std::max(lastLine, (*it)->getLine());
1174 printComments((*it)->getLine(), -1);
1175 }
1176 printComments(-1, -1);
1177}
1178
1180 if (!node) return;
1181 for (auto &attr : node->attrs) {
1182 formatToken(os, option, attr);
1183 os << L" ";
1184 }
1185 format(node->name);
1186 format(node->args);
1187 if (node->resultType) {
1188 os << L" : ";
1189 format(node->resultType);
1190 }
1191}
1192
1194 if (!node) return;
1195 for (auto &attr : node->attrs) {
1196 formatToken(os, option, attr);
1197 os << L" ";
1198 }
1199 format(node->name);
1200 format(node->args);
1201 if (node->resultType) {
1202 os << L" : ";
1203 format(node->resultType);
1204 }
1205 format(node->block);
1206}
1207
1209 if (!node) return;
1210 os << L"constructor";
1211 if (node->tempArgs) format(node->tempArgs);
1212 format(node->args);
1213}
1214
1216 if (!node) return;
1217 os << L"constructor";
1218 if (node->tempArgs) format(node->tempArgs);
1219 format(node->args);
1220 format(node->block);
1221}
1222
1224 if (!node) return;
1225 os << L"yield ";
1226 format(node->expr);
1227}
1228
1230 os << "decltype(";
1231 format(node->expr);
1232 os << ")";
1233}
1234
1236 if (!node) return;
1237 os << L"concept " << node->name.strVal << L"<";
1238 for (auto it = node->typeParams.begin(); it != node->typeParams.end(); it++) {
1239 if (it != node->typeParams.begin()) {
1240 os << ", ";
1241 }
1242 os << it->strVal;
1243 }
1244 os << ">(";
1245 for (auto it = node->algebraParams.begin(); it != node->algebraParams.end(); it++) {
1246 if (it != node->algebraParams.begin()) {
1247 os << ", ";
1248 }
1249 format(*it);
1250 }
1251 os << ") {";
1252 indentLevel++;
1253 for (auto it = node->conceptBlock.begin(); it != node->conceptBlock.end(); it++) {
1254 newLine();
1255 format(*it);
1256 }
1257 indentLevel--;
1258 newLine();
1259 os << "}";
1260}
1261
1263 if (!node) return;
1264 switch (node->kind) {
1266 format(node->value.expression);
1267 break;
1268 }
1270 format(node->value.satisfyStmt);
1271 break;
1272 }
1273 default:
1274 break;
1275 }
1276}
1277
1279 os << L"satisfy ";
1280 format(node->emae);
1281}
1282
1284 os << L"satisfy(";
1285 for (auto it = node->emaes.begin(); it != node->emaes.end(); it++) {
1286 if (it != node->emaes.begin()) {
1287 os << ", ";
1288 }
1289 format(*it);
1290 }
1291 os << ")";
1292}
1293
1295 switch (node->attr) {
1297 os << L"weak ";
1298 break;
1300 os << L"datafield ";
1301 break;
1302 default:
1303 break;
1304 }
1305 format(node->identifier);
1306}
yoi::indexT getColumn()
Definition ast.cpp:1042
yoi::indexT getLine()
Definition ast.cpp:1046
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:440
primary * lhs
Definition ast.hpp:438
lexer::token op
Definition ast.hpp:439
lexer::token node
Definition ast.hpp:247
yoi::vec< yoi::rExpr * > exprs
Definition ast.hpp:218
codeBlock * block
Definition ast.hpp:1069
identifier * name
Definition ast.hpp:1068
typeSpec * type
Definition ast.hpp:1067
vec< inCodeBlockStmt * > stmts
Definition ast.hpp:1023
yoi::vec< identifierWithTypeSpec * > algebraParams
Definition ast.hpp:1117
yoi::vec< lexer::token > typeParams
Definition ast.hpp:1116
yoi::vec< conceptStmt * > conceptBlock
Definition ast.hpp:1119
lexer::token name
Definition ast.hpp:1115
union yoi::conceptStmt::ConceptStmtValue value
enum yoi::conceptStmt::Kind kind
defTemplateArg * tempArgs
Definition ast.hpp:993
definitionArguments * args
Definition ast.hpp:994
codeBlock * block
Definition ast.hpp:1007
templateArg * tempArgs
Definition ast.hpp:1005
definitionArguments * args
Definition ast.hpp:1006
structDefInner * inner
Definition ast.hpp:724
identifier * id
Definition ast.hpp:723
rExpr * expr
Definition ast.hpp:615
satisfyClause * satisfyCondition
Definition ast.hpp:272
identifier * id
Definition ast.hpp:271
vec< defTemplateArgSpec * > spec
Definition ast.hpp:279
vec< identifierWithTypeSpec * > spec
Definition ast.hpp:307
vec< enumerationPair * > values
Definition ast.hpp:1099
lexer::token value
Definition ast.hpp:1105
identifier * name
Definition ast.hpp:1104
typeSpec * from
Definition ast.hpp:1050
identifier * as
Definition ast.hpp:1051
yoi::vec< lexer::token > attrs
Definition ast.hpp:1049
vec< identifierWithTemplateArg * > terms
Definition ast.hpp:1040
codeBlock * block
Definition ast.hpp:1016
codeBlock * block
Definition ast.hpp:896
rExpr * container
Definition ast.hpp:895
identifier * var
Definition ast.hpp:894
codeBlock * block
Definition ast.hpp:881
inCodeBlockStmt * afterStmt
Definition ast.hpp:880
inCodeBlockStmt * initStmt
Definition ast.hpp:878
rExpr * cond
Definition ast.hpp:879
codeBlock * block
Definition ast.hpp:624
identifierWithDefTemplateArg * id
Definition ast.hpp:621
typeSpec * resultType
Definition ast.hpp:623
yoi::vec< lexer::token > attrs
Definition ast.hpp:620
definitionArguments * args
Definition ast.hpp:622
externModuleAccessExpression * name
Definition ast.hpp:241
unnamedDefinitionArguments * args
Definition ast.hpp:242
typeSpec * resultType
Definition ast.hpp:315
unnamedDefinitionArguments * args
Definition ast.hpp:314
union yoi::globalStmt::vValue value
enum yoi::globalStmt::vKind kind
marcoDescriptor * marco
Definition ast.hpp:817
vec< globalStmt * > stmts
Definition ast.hpp:1033
bool hasTemplateArg() const
Definition ast.cpp:75
lexer::token node
Definition ast.hpp:254
vec< ifBlock > elifB
Definition ast.hpp:854
codeBlock * elseB
Definition ast.hpp:855
ifBlock ifB
Definition ast.hpp:853
bool hasElseBlock() const
Definition ast.cpp:415
bool isFinalizer() const
Definition ast.cpp:1206
bool isMethod() const
Definition ast.cpp:1202
innerMethodDef * met
Definition ast.hpp:736
finalizerDef * finalizer
Definition ast.hpp:738
constructorDef * con
Definition ast.hpp:734
bool isConstructor() const
Definition ast.cpp:351
vec< implInnerPair * > inner
Definition ast.hpp:755
implInner * inner
Definition ast.hpp:764
externModuleAccessExpression * structName
Definition ast.hpp:763
externModuleAccessExpression * interfaceName
Definition ast.hpp:762
lexer::token from_path
Definition ast.hpp:1057
innerMethodDecl * inner
Definition ast.hpp:1056
union yoi::inCodeBlockStmt::vValue value
enum yoi::inCodeBlockStmt::vKind kind
marcoDescriptor * marco
Definition ast.hpp:936
typeSpec * resultType
Definition ast.hpp:965
yoi::vec< lexer::token > attrs
Definition ast.hpp:962
identifierWithDefTemplateArg * name
Definition ast.hpp:963
definitionArguments * args
Definition ast.hpp:964
codeBlock * block
Definition ast.hpp:980
typeSpec * resultType
Definition ast.hpp:979
yoi::vec< lexer::token > attrs
Definition ast.hpp:976
definitionArguments * args
Definition ast.hpp:978
identifierWithTemplateArg * name
Definition ast.hpp:977
innerMethodDecl * method
Definition ast.hpp:643
identifierWithTypeSpec * var
Definition ast.hpp:638
vec< interfaceDefInnerPair * > inner
Definition ast.hpp:652
identifierWithDefTemplateArg * id
Definition ast.hpp:659
interfaceDefInner * inner
Definition ast.hpp:660
vec< rExpr * > arg
Definition ast.hpp:300
structDefInnerPair::Modifier attr
Definition ast.hpp:692
yoi::identifier * identifier
Definition ast.hpp:693
codeBlock * block
Definition ast.hpp:701
vec< yoi::lambdaCapture * > captures
Definition ast.hpp:698
typeSpec * resultType
Definition ast.hpp:700
definitionArguments * args
Definition ast.hpp:699
rExpr * rhs
Definition ast.hpp:465
lexer::token op
Definition ast.hpp:463
uniqueExpr * lhs
Definition ast.hpp:464
bool hasRhs() const
Definition ast.cpp:135
vec< lexer::token > list
Definition ast.hpp:779
enum yoi::letAssignmentPairLHS::vKind kind
letAssignmentPairLHS * lhs
Definition ast.hpp:784
typeSpec * type
Definition ast.hpp:785
vec< letAssignmentPair * > terms
Definition ast.hpp:795
yoi::vec< marcoPair * > pairs
Definition ast.hpp:236
lexer::token identifier
Definition ast.hpp:229
lexer::token rhs
Definition ast.hpp:231
lexer::token constraint
Definition ast.hpp:230
vec< subscriptExpr * > terms
Definition ast.hpp:391
subscript * length
Definition ast.hpp:399
invocationArguments * args
Definition ast.hpp:400
externModuleAccessExpression * type
Definition ast.hpp:398
lambdaExpr * lambda
Definition ast.hpp:424
enum yoi::primary::primaryKind kind
funcExpr * func
Definition ast.hpp:425
memberExpr * member
Definition ast.hpp:418
rExpr * expr
Definition ast.hpp:420
basicLiterals * literals
Definition ast.hpp:419
newExpression * newExpr
Definition ast.hpp:423
bracedInitalizerList * bracedInitalizer
Definition ast.hpp:426
typeIdExpression * typeId
Definition ast.hpp:421
dynCastExpression * dynCast
Definition ast.hpp:422
rExpr * value
Definition ast.hpp:907
bool hasValue() const
Definition ast.cpp:459
yoi::vec< externModuleAccessExpression * > emaes
Definition ast.hpp:1145
externModuleAccessExpression * emae
Definition ast.hpp:1140
innerMethodDecl * method
Definition ast.hpp:677
enum yoi::structDefInnerPair::Modifier modifier
constructorDecl * con
Definition ast.hpp:675
finalizerDecl * finalizer
Definition ast.hpp:679
identifierWithTypeSpec * var
Definition ast.hpp:673
vec< structDefInnerPair * > inner
Definition ast.hpp:706
structDefInner * inner
Definition ast.hpp:714
identifierWithDefTemplateArg * id
Definition ast.hpp:713
vec< subscript * > subscriptVal
Definition ast.hpp:382
identifierWithTemplateArg * id
Definition ast.hpp:381
bool isInvocation() const
Definition ast.cpp:1080
rExpr * expr
Definition ast.hpp:345
invocationArguments * args
Definition ast.hpp:346
typeSpec * spec
Definition ast.hpp:286
vec< templateArgSpec * > spec
Definition ast.hpp:293
rExpr * expr
Definition ast.hpp:1062
vec< catchParam * > catchParams
Definition ast.hpp:1075
codeBlock * tryBlock
Definition ast.hpp:1074
codeBlock * finallyBlock
Definition ast.hpp:1076
yoi::identifierWithDefTemplateArg * lhs
Definition ast.hpp:223
yoi::typeSpec * rhs
Definition ast.hpp:224
typeSpec * type
Definition ast.hpp:1081
decltypeExpr * decltypeExpression
Definition ast.hpp:334
yoi::vec< uint64_t > * arraySubscript
Definition ast.hpp:336
externModuleAccessExpression * member
Definition ast.hpp:331
funcTypeSpec * func
Definition ast.hpp:332
enum yoi::typeSpec::typeSpecKind kind
typeSpec * elipsis
Definition ast.hpp:333
bool isNull
Definition ast.hpp:335
lexer::token op
Definition ast.hpp:451
abstractExpr * lhs
Definition ast.hpp:452
vec< typeSpec * > types
Definition ast.hpp:1093
identifier * name
Definition ast.hpp:605
lexer::token path
Definition ast.hpp:606
codeBlock * block
Definition ast.hpp:869
rExpr * cond
Definition ast.hpp:868
rExpr * expr
Definition ast.hpp:1110
#define FORMAT_BINARY_EXPR(NODE_TYPE)
Definition json.hpp:5639
std::vector< t > vec
Definition def.hpp:56
std::wstring string2wstring(const std::string &v)
Definition def.cpp:224
void formatToken(std::wostream &os, FormatOption option, const lexer::token &token)
Definition formatter.cpp:14
wstr escapeString(const wstr &value)
Definition def.cpp:94
std::wstring wstr
Definition def.hpp:51
std::basic_string< T > trim(const std::basic_string< T > &str)
Definition def.hpp:81
FormatOption()=default
codeBlock * block
Definition ast.hpp:846
enum yoi::lexer::token::tokenKind kind
union yoi::lexer::token::vBasicValue basicVal
dataStructDefStmt * dataStructDefStmtVal
Definition ast.hpp:823
enumerationDefinition * enumerationDefVal
Definition ast.hpp:830
useStmt * useStmtVal
Definition ast.hpp:820
implStmt * implStmtVal
Definition ast.hpp:824
interfaceDefStmt * interfaceDefStmtVal
Definition ast.hpp:821
letStmt * letStmtVal
Definition ast.hpp:825
conceptDefinition * conceptDefVal
Definition ast.hpp:831
funcDefStmt * funcDefStmtVal
Definition ast.hpp:826
typeAliasStmt * typeAliasStmtVal
Definition ast.hpp:829
exportDecl * exportDeclVal
Definition ast.hpp:828
structDefStmt * structDefStmtVal
Definition ast.hpp:822
importDecl * importDeclVal
Definition ast.hpp:827
forEachStmt * forEachStmtVal
Definition ast.hpp:941
returnStmt * returnStmtVal
Definition ast.hpp:942
continueStmt * continueStmtVal
Definition ast.hpp:943