1 // =================================
   2 // Copyright (c) 2021 Seppo Laakko
   3 // Distributed under the MIT license
   4 // =================================
   5 
   6 #include <sngcm/ast/SourceWriter.hpp>
   7 #include <sngcm/ast/Literal.hpp>
   8 #include <sngcm/ast/CompileUnit.hpp>
   9 #include <sngcm/ast/Namespace.hpp>
  10 #include <sngcm/ast/Identifier.hpp>
  11 #include <sngcm/ast/Template.hpp>
  12 #include <sngcm/ast/Attribute.hpp>
  13 #include <sngcm/ast/Function.hpp>
  14 #include <sngcm/ast/Class.hpp>
  15 #include <sngcm/ast/Interface.hpp>
  16 #include <sngcm/ast/Delegate.hpp>
  17 #include <sngcm/ast/Concept.hpp>
  18 #include <sngcm/ast/Typedef.hpp>
  19 #include <sngcm/ast/Constant.hpp>
  20 #include <sngcm/ast/Enumeration.hpp>
  21 #include <sngcm/ast/TypeExpr.hpp>
  22 #include <sngcm/ast/Expression.hpp>
  23 #include <sngcm/ast/GlobalVariable.hpp>
  24 #include <sngcm/ast/Comment.hpp>
  25 #include <soulng/util/TextUtils.hpp>
  26 #include <soulng/util/Unicode.hpp>
  27 #include <iostream>
  28 
  29 namespace sngcm { namespace ast {
  30 
  31 SourceWriter::SourceWriter(soulng::util::CodeFormatter& formatter_) : formatter(formatter_)omitNewLine(false)omitSemicolon(false)emptyLine(false)
  32 {
  33 }
  34 
  35 void SourceWriter::Visit(BoolNode& boolNode)
  36 {
  37     formatter.Write("bool");
  38 }
  39 
  40 void SourceWriter::Visit(SByteNode& sbyteNode)
  41 {
  42     formatter.Write("sbyte");
  43 }
  44 
  45 void SourceWriter::Visit(ByteNode& byteNode)
  46 {
  47     formatter.Write("byte");
  48 }
  49 
  50 void SourceWriter::Visit(ShortNode& shortNode)
  51 {
  52     formatter.Write("short");
  53 }
  54 
  55 void SourceWriter::Visit(UShortNode& ushortNode)
  56 {
  57     formatter.Write("ushort");
  58 }
  59 
  60 void SourceWriter::Visit(IntNode& intNode)
  61 {
  62     formatter.Write("int");
  63 }
  64 
  65 void SourceWriter::Visit(UIntNode& uintNode)
  66 {
  67     formatter.Write("uint");
  68 }
  69 
  70 void SourceWriter::Visit(LongNode& longNode)
  71 {
  72     formatter.Write("long");
  73 }
  74 
  75 void SourceWriter::Visit(ULongNode& ulongNode)
  76 {
  77     formatter.Write("ulong");
  78 }
  79 
  80 void SourceWriter::Visit(FloatNode& floatNode)
  81 {
  82     formatter.Write("float");
  83 }
  84 
  85 void SourceWriter::Visit(DoubleNode& doubleNode)
  86 {
  87     formatter.Write("double");
  88 }
  89 
  90 void SourceWriter::Visit(CharNode& charNode)
  91 {
  92     formatter.Write("char");
  93 }
  94 
  95 void SourceWriter::Visit(WCharNode& wcharNode)
  96 {
  97     formatter.Write("wchar");
  98 }
  99 
 100 void SourceWriter::Visit(UCharNode& ucharNode)
 101 {
 102     formatter.Write("uchar");
 103 }
 104 
 105 void SourceWriter::Visit(VoidNode& voidNode)
 106 {
 107     formatter.Write("void");
 108 }
 109 
 110 void SourceWriter::Visit(BooleanLiteralNode& booleanLiteralNode)
 111 {
 112     if (booleanLiteralNode.Value())
 113     {
 114         formatter.Write("true");
 115     }
 116     else
 117     {
 118         formatter.Write("false");
 119     }
 120 }
 121 
 122 void SourceWriter::Visit(SByteLiteralNode& sbyteLiteralNode)
 123 {
 124     formatter.Write(std::to_string(sbyteLiteralNode.Value()));
 125 }
 126 
 127 void SourceWriter::Visit(ByteLiteralNode& byteLiteralNode)
 128 {
 129     formatter.Write(std::to_string(byteLiteralNode.Value()) + "u");
 130 }
 131 
 132 void SourceWriter::Visit(ShortLiteralNode& shortLiteralNode)
 133 {
 134     formatter.Write(std::to_string(shortLiteralNode.Value()));
 135 }
 136 
 137 void SourceWriter::Visit(UShortLiteralNode& ushortLiteralNode)
 138 {
 139     formatter.Write(std::to_string(ushortLiteralNode.Value()) + "u");
 140 }
 141 
 142 void SourceWriter::Visit(IntLiteralNode& intLiteralNode)
 143 {
 144     formatter.Write(std::to_string(intLiteralNode.Value()));
 145 }
 146 
 147 void SourceWriter::Visit(UIntLiteralNode& uintLiteralNode)
 148 {
 149     formatter.Write(std::to_string(uintLiteralNode.Value()) + "u");
 150 }
 151 
 152 void SourceWriter::Visit(LongLiteralNode& longLiteralNode)
 153 {
 154     formatter.Write(std::to_string(longLiteralNode.Value()));
 155 }
 156 
 157 void SourceWriter::Visit(ULongLiteralNode& ulongLiteralNode)
 158 {
 159     formatter.Write(std::to_string(ulongLiteralNode.Value()) + "u");
 160 }
 161 
 162 void SourceWriter::Visit(FloatLiteralNode& floatLiteralNode)
 163 {
 164     formatter.Write(std::to_string(floatLiteralNode.Value()) + "f");
 165 }
 166 
 167 void SourceWriter::Visit(DoubleLiteralNode& doubleLiteralNode)
 168 {
 169     formatter.Write(std::to_string(doubleLiteralNode.Value()));
 170 }
 171 
 172 void SourceWriter::Visit(CharLiteralNode& charLiteralNode)
 173 {
 174     formatter.Write("'");
 175     formatter.Write(soulng::util::CharStr(charLiteralNode.Value()));
 176     formatter.Write("'");
 177 }
 178 
 179 void SourceWriter::Visit(WCharLiteralNode& wcharLiteralNode)
 180 {
 181     formatter.Write("w'");
 182     formatter.Write(soulng::unicode::ToUtf8(soulng::util::CharStr(char32_t(wcharLiteralNode.Value()))));
 183     formatter.Write("'");
 184 }
 185 
 186 void SourceWriter::Visit(UCharLiteralNode& ucharLiteralNode)
 187 {
 188     formatter.Write("u'");
 189     formatter.Write(soulng::unicode::ToUtf8(soulng::util::CharStr(ucharLiteralNode.Value())));
 190     formatter.Write("'");
 191 }
 192 
 193 void SourceWriter::Visit(StringLiteralNode& stringLiteralNode)
 194 {
 195     formatter.Write("\"");
 196     formatter.Write(soulng::util::StringStr(stringLiteralNode.Value()));
 197 formatter.Write("\"");
 198 }
 199 
 200 void SourceWriter::Visit(WStringLiteralNode& wstringLiteralNode)
 201 {
 202     formatter.Write("w\"");
 203     formatter.Write(soulng::util::StringStr(soulng::unicode::ToUtf8(wstringLiteralNode.Value())));
 204     formatter.Write("\"");
 205 }
 206 
 207 void SourceWriter::Visit(UStringLiteralNode& ustringLiteralNode)
 208 {
 209     formatter.Write("u\"");
 210     formatter.Write(soulng::util::StringStr(soulng::unicode::ToUtf8(ustringLiteralNode.Value())));
 211     formatter.Write("\"");
 212 }
 213 
 214 void SourceWriter::Visit(NullLiteralNode& nullLiteralNode)
 215 {
 216     formatter.Write("null");
 217 }
 218 
 219 void SourceWriter::Visit(ArrayLiteralNode& arrayLiteralNode)
 220 {
 221     formatter.Write("[");
 222     int n = arrayLiteralNode.Values().Count();
 223     for (int i = 0; i < n; ++i)
 224     {
 225         if (i > 0)
 226         {
 227             formatter.Write(", ");
 228         }
 229         arrayLiteralNode.Values()[i]->Accept(*this);
 230     }
 231     formatter.Write("]");
 232 }
 233 
 234 void SourceWriter::Visit(StructuredLiteralNode& structuredLiteralNode)
 235 {
 236     formatter.Write("{");
 237     int n = structuredLiteralNode.Members().Count();
 238     for (int i = 0; i < n; ++i)
 239     {
 240         if (i > 0)
 241         {
 242             formatter.Write(", ");
 243         }
 244         structuredLiteralNode.Members()[i]->Accept(*this);
 245     }
 246     formatter.Write("}");
 247 }
 248 
 249 void SourceWriter::Visit(UuidLiteralNode& uuidLiteralNode)
 250 {
 251     WriteWarning("sngcm::writer::SourceWriter: uuid literals not supported");
 252 }
 253 
 254 void SourceWriter::Visit(CompileUnitNode& compileUnitNode)
 255 {
 256     compileUnitNode.GlobalNs()->Accept(*this);
 257 }
 258 
 259 void SourceWriter::Visit(NamespaceNode& namespaceNode)
 260 {
 261     WriteEmptyLine();
 262     if (!namespaceNode.Id()->Str().empty())
 263     {
 264         if (namespaceNode.IsUnnamedNs())
 265         {
 266             formatter.Write("namespace");
 267         }
 268         else
 269         {
 270             formatter.Write("namespace ");
 271             namespaceNode.Id()->Accept(*this);
 272         }
 273         formatter.WriteLine();
 274         formatter.WriteLine("{");
 275         formatter.IncIndent();
 276     }
 277     int n = namespaceNode.Members().Count();
 278     for (int i = 0; i < n; ++i)
 279     {
 280         namespaceNode.Members()[i]->Accept(*this);
 281         if (i < n - 1)
 282         {
 283             NodeType nodeType = namespaceNode.Members()[i]->GetNodeType();
 284             if (nodeType == NodeType::aliasNode || nodeType == NodeType::namespaceImportNode)
 285             {
 286                 NodeType nextNodeType = namespaceNode.Members()[i + 1]->GetNodeType();
 287                 if (nextNodeType != NodeType::aliasNode && nextNodeType != NodeType::namespaceImportNode)
 288                 {
 289                     formatter.WriteLine();
 290                 }
 291             }
 292         }
 293     }
 294     if (!namespaceNode.Id()->Str().empty())
 295     {
 296         formatter.DecIndent();
 297         if (namespaceNode.IsUnnamedNs())
 298         {
 299             formatter.WriteLine("} // namespace");
 300         }
 301         else
 302         {
 303             formatter.WriteLine("} // namespace " + soulng::unicode::ToUtf8(namespaceNode.Id()->Str()));
 304         }
 305     }
 306     emptyLine = true;
 307 }
 308 
 309 void SourceWriter::Visit(AliasNode& aliasNode)
 310 {
 311     formatter.Write("using ");
 312     aliasNode.Id()->Accept(*this);
 313     formatter.Write(" = ");
 314     aliasNode.Qid()->Accept(*this);
 315     formatter.WriteLine(";");
 316 }
 317 
 318 void SourceWriter::Visit(NamespaceImportNode& namespaceImportNode)
 319 {
 320     formatter.Write("using ");
 321     namespaceImportNode.Ns()->Accept(*this);
 322     formatter.WriteLine(";");
 323 }
 324 
 325 void SourceWriter::Visit(IdentifierNode& identifierNode)
 326 {
 327     formatter.Write(soulng::unicode::ToUtf8(identifierNode.Str()));
 328 }
 329 
 330 void SourceWriter::Visit(CursorIdNode& cursorIdNode)
 331 {
 332     WriteWarning("sngcm::writer::SourceWriter: cursor id nodes not supported");
 333 }
 334 
 335 void SourceWriter::Visit(TemplateIdNode& templateIdNode)
 336 {
 337     templateIdNode.Primary()->Accept(*this);
 338     formatter.Write("<");
 339     int n = templateIdNode.TemplateArguments().Count();
 340     for (int i = 0; i < n; ++i)
 341     {
 342         if (i > 0)
 343         {
 344             formatter.Write(", ");
 345         }
 346         templateIdNode.TemplateArguments()[i]->Accept(*this);
 347     }
 348     formatter.Write(">");
 349 }
 350 
 351 void SourceWriter::Visit(FunctionNode& functionNode)
 352 {
 353     WriteEmptyLine();
 354     AttributesNode* attributes = functionNode.GetAttributes();
 355     if (attributes)
 356     {
 357         attributes->Accept(*this);
 358         formatter.WriteLine();
 359     }
 360     if (functionNode.GetSpecifiers() != Specifiers::none)
 361     {
 362         formatter.Write(SpecifierStr(functionNode.GetSpecifiers()));
 363         formatter.Write(" ");
 364     }
 365     functionNode.ReturnTypeExpr()->Accept(*this);
 366     formatter.Write(" ");
 367     formatter.Write(soulng::unicode::ToUtf8(functionNode.GroupId()));
 368     int nt = functionNode.TemplateParameters().Count();
 369     if (nt > 0)
 370     {
 371         formatter.Write("<");
 372         for (int i = 0; i < nt; ++i)
 373         {
 374             if (i > 0)
 375             {
 376                 formatter.Write(", ");
 377             }
 378             functionNode.TemplateParameters()[i]->Accept(*this);
 379         }
 380         formatter.Write(">");
 381     }
 382     formatter.Write("(");
 383     int np = functionNode.Parameters().Count();
 384     for (int i = 0; i < np; ++i)
 385     {
 386         if (i > 0)
 387         {
 388             formatter.Write(", ");
 389         }
 390         functionNode.Parameters()[i]->Accept(*this);
 391     }
 392     formatter.Write(")");
 393     if (functionNode.WhereConstraint())
 394     {
 395         formatter.Write(" ");
 396         functionNode.WhereConstraint()->Accept(*this);
 397     }
 398     if (functionNode.Body())
 399     {
 400         formatter.WriteLine();
 401         functionNode.Body()->Accept(*this);
 402     }
 403     else
 404     {
 405         formatter.WriteLine(";");
 406     }
 407     emptyLine = true;
 408 }
 409 
 410 void SourceWriter::Visit(ClassNode& classNode)
 411 {
 412     WriteEmptyLine();
 413     AttributesNode* attributes = classNode.GetAttributes();
 414     if (attributes)
 415     {
 416         attributes->Accept(*this);
 417         formatter.WriteLine();
 418     }
 419     if (classNode.GetSpecifiers() != Specifiers::none)
 420     {
 421         formatter.Write(SpecifierStr(classNode.GetSpecifiers()));
 422         formatter.Write(" ");
 423     }
 424     formatter.Write("class ");
 425     classNode.Id()->Accept(*this);
 426     int nt = classNode.TemplateParameters().Count();
 427     if (nt > 0)
 428     {
 429         formatter.Write("<");
 430         for (int i = 0; i < nt; ++i)
 431         {
 432             if (i > 0)
 433             {
 434                 formatter.Write(", ");
 435             }
 436             classNode.TemplateParameters()[i]->Accept(*this);
 437         }
 438         formatter.Write(">");
 439     }
 440     int nb = classNode.BaseClassOrInterfaces().Count();
 441     if (nb > 0)
 442     {
 443         formatter.Write(" : ");
 444         for (int i = 0; i < nb; ++i)
 445         {
 446             if (i > 0)
 447             {
 448                 formatter.Write(", ");
 449             }
 450             classNode.BaseClassOrInterfaces()[i]->Accept(*this);
 451         }
 452     }
 453     if (classNode.WhereConstraint())
 454     {
 455         formatter.Write(" ");
 456         classNode.WhereConstraint()->Accept(*this);
 457     }
 458     formatter.WriteLine();
 459     formatter.WriteLine("{");
 460     formatter.IncIndent();
 461     int n = classNode.Members().Count();
 462     for (int i = 0; i < n; ++i)
 463     {
 464         classNode.Members()[i]->Accept(*this);
 465     }
 466     formatter.DecIndent();
 467     formatter.WriteLine("}");
 468     emptyLine = true;
 469 }
 470 
 471 void SourceWriter::Visit(ThisInitializerNode& thisInitializerNode)
 472 {
 473     formatter.Write("this(");
 474     int n = thisInitializerNode.Arguments().Count();
 475     for (int i = 0; i < n; ++i)
 476     {
 477         if (i > 0)
 478         {
 479             formatter.Write(", ");
 480         }
 481         thisInitializerNode.Arguments()[i]->Accept(*this);
 482     }
 483     formatter.Write(")");
 484 }
 485 
 486 void SourceWriter::Visit(BaseInitializerNode& baseInitializerNode)
 487 {
 488     formatter.Write("base(");
 489     int n = baseInitializerNode.Arguments().Count();
 490     for (int i = 0; i < n; ++i)
 491     {
 492         if (i > 0)
 493         {
 494             formatter.Write(", ");
 495         }
 496         baseInitializerNode.Arguments()[i]->Accept(*this);
 497     }
 498     formatter.Write(")");
 499 }
 500 
 501 void SourceWriter::Visit(MemberInitializerNode& memberInitializerNode)
 502 {
 503     memberInitializerNode.MemberId()->Accept(*this);
 504     formatter.Write("(");
 505     int n = memberInitializerNode.Arguments().Count();
 506     for (int i = 0; i < n; ++i)
 507     {
 508         if (i > 0)
 509         {
 510             formatter.Write(", ");
 511         }
 512         memberInitializerNode.Arguments()[i]->Accept(*this);
 513     }
 514     formatter.Write(")");
 515 }
 516 
 517 void SourceWriter::Visit(StaticConstructorNode& staticConstructorNode)
 518 {
 519     AttributesNode* attributes = staticConstructorNode.GetAttributes();
 520     if (attributes)
 521     {
 522         attributes->Accept(*this);
 523         formatter.WriteLine();
 524     }
 525     if (staticConstructorNode.GetSpecifiers() != Specifiers::none)
 526     {
 527         formatter.Write(SpecifierStr(staticConstructorNode.GetSpecifiers()));
 528         formatter.Write(" ");
 529     }
 530     staticConstructorNode.ClassId()->Accept(*this);
 531     formatter.Write("()");
 532     int ni = staticConstructorNode.Initializers().Count();
 533     if (ni > 0)
 534     {
 535         formatter.WriteLine(" :");
 536         formatter.IncIndent();
 537         for (int i = 0; i < ni; ++i)
 538         {
 539             if (i > 0)
 540             {
 541                 formatter.Write(", ");
 542             }
 543             staticConstructorNode.Initializers()[i]->Accept(*this);
 544         }
 545         formatter.DecIndent();
 546     }
 547     if (staticConstructorNode.WhereConstraint())
 548     {
 549         formatter.WriteLine();
 550         formatter.IncIndent();
 551         staticConstructorNode.WhereConstraint()->Accept(*this);
 552         formatter.DecIndent();
 553     }
 554     if (staticConstructorNode.Body())
 555     {
 556         formatter.WriteLine();
 557         staticConstructorNode.Body()->Accept(*this);
 558     }
 559     else
 560     {
 561         formatter.WriteLine(";");
 562     }
 563 }
 564 
 565 void SourceWriter::Visit(ConstructorNode& constructorNode)
 566 {
 567     AttributesNode* attributes = constructorNode.GetAttributes();
 568     if (attributes)
 569     {
 570         attributes->Accept(*this);
 571         formatter.WriteLine();
 572     }
 573     if (constructorNode.GetSpecifiers() != Specifiers::none)
 574     {
 575         formatter.Write(SpecifierStr(constructorNode.GetSpecifiers()));
 576         formatter.Write(" ");
 577     }
 578     constructorNode.ClassId()->Accept(*this);
 579     formatter.Write("(");
 580     int np = constructorNode.Parameters().Count();
 581     for (int i = 0; i < np; ++i)
 582     {
 583         if (i > 0)
 584         {
 585             formatter.Write(", ");
 586         }
 587         constructorNode.Parameters()[i]->Accept(*this);
 588     }
 589     formatter.Write(")");
 590     int ni = constructorNode.Initializers().Count();
 591     if (ni > 0)
 592     {
 593         formatter.WriteLine(" :");
 594         formatter.IncIndent();
 595         for (int i = 0; i < ni; ++i)
 596         {
 597             if (i > 0)
 598             {
 599                 formatter.Write(", ");
 600             }
 601             constructorNode.Initializers()[i]->Accept(*this);
 602         }
 603         formatter.DecIndent();
 604     }
 605     if (constructorNode.WhereConstraint())
 606     {
 607         formatter.WriteLine();
 608         formatter.IncIndent();
 609         constructorNode.WhereConstraint()->Accept(*this);
 610         formatter.DecIndent();
 611     }
 612     if (constructorNode.Body())
 613     {
 614         formatter.WriteLine();
 615         constructorNode.Body()->Accept(*this);
 616     }
 617     else
 618     {
 619         formatter.WriteLine(";");
 620     }
 621 }
 622 
 623 void SourceWriter::Visit(DestructorNode& destructorNode)
 624 {
 625     AttributesNode* attributes = destructorNode.GetAttributes();
 626     if (attributes)
 627     {
 628         attributes->Accept(*this);
 629         formatter.WriteLine();
 630     }
 631     if (destructorNode.GetSpecifiers() != Specifiers::none)
 632     {
 633         formatter.Write(SpecifierStr(destructorNode.GetSpecifiers()));
 634         formatter.Write(" ");
 635     }
 636     formatter.Write("~");
 637     destructorNode.ClassId()->Accept(*this);
 638     formatter.Write("()");
 639     if (destructorNode.WhereConstraint())
 640     {
 641         formatter.WriteLine();
 642         formatter.IncIndent();
 643         destructorNode.WhereConstraint()->Accept(*this);
 644         formatter.DecIndent();
 645     }
 646     if (destructorNode.Body())
 647     {
 648         formatter.WriteLine();
 649         destructorNode.Body()->Accept(*this);
 650     }
 651     else
 652     {
 653         formatter.WriteLine(";");
 654     }
 655 }
 656 
 657 void SourceWriter::Visit(MemberFunctionNode& memberFunctionNode)
 658 {
 659     AttributesNode* attributes = memberFunctionNode.GetAttributes();
 660     if (attributes)
 661     {
 662         attributes->Accept(*this);
 663         formatter.WriteLine();
 664     }
 665     if (memberFunctionNode.GetSpecifiers() != Specifiers::none)
 666     {
 667         formatter.Write(SpecifierStr(memberFunctionNode.GetSpecifiers()));
 668         formatter.Write(" ");
 669     }
 670     memberFunctionNode.ReturnTypeExpr()->Accept(*this);
 671     formatter.Write(" ");
 672     formatter.Write(soulng::unicode::ToUtf8(memberFunctionNode.GroupId()));
 673     formatter.Write("(");
 674     int np = memberFunctionNode.Parameters().Count();
 675     for (int i = 0; i < np; ++i)
 676     {
 677         if (i > 0)
 678         {
 679             formatter.Write(", ");
 680         }
 681         memberFunctionNode.Parameters()[i]->Accept(*this);
 682     }
 683     formatter.Write(")");
 684     if (memberFunctionNode.IsConst())
 685     {
 686         formatter.Write(" const");
 687     }
 688     if (memberFunctionNode.WhereConstraint())
 689     {
 690         formatter.WriteLine();
 691         formatter.IncIndent();
 692         memberFunctionNode.WhereConstraint()->Accept(*this);
 693         formatter.DecIndent();
 694     }
 695     if (memberFunctionNode.Body())
 696     {
 697         formatter.WriteLine();
 698         memberFunctionNode.Body()->Accept(*this);
 699     }
 700     else
 701     {
 702         formatter.WriteLine(";");
 703     }
 704 }
 705 
 706 void SourceWriter::Visit(ConversionFunctionNode& conversionFunctionNode)
 707 {
 708     AttributesNode* attributes = conversionFunctionNode.GetAttributes();
 709     if (attributes)
 710     {
 711         attributes->Accept(*this);
 712         formatter.WriteLine();
 713     }
 714     if (conversionFunctionNode.GetSpecifiers() != Specifiers::none)
 715     {
 716         formatter.Write(SpecifierStr(conversionFunctionNode.GetSpecifiers()));
 717         formatter.Write(" ");
 718     }
 719     formatter.Write("operator ");
 720     conversionFunctionNode.ReturnTypeExpr()->Accept(*this);
 721     formatter.Write("()");
 722     if (conversionFunctionNode.IsConst())
 723     {
 724         formatter.Write(" const");
 725     }
 726     if (conversionFunctionNode.WhereConstraint())
 727     {
 728         formatter.WriteLine();
 729         formatter.IncIndent();
 730         conversionFunctionNode.WhereConstraint()->Accept(*this);
 731         formatter.DecIndent();
 732     }
 733     if (conversionFunctionNode.Body())
 734     {
 735         formatter.WriteLine();
 736         conversionFunctionNode.Body()->Accept(*this);
 737     }
 738     else
 739     {
 740         formatter.WriteLine(";");
 741     }
 742 }
 743 
 744 void SourceWriter::Visit(MemberVariableNode& memberVariableNode)
 745 {
 746     AttributesNode* attributes = memberVariableNode.GetAttributes();
 747     if (attributes)
 748     {
 749         attributes->Accept(*this);
 750         formatter.WriteLine();
 751     }
 752     if (memberVariableNode.GetSpecifiers() != Specifiers::none)
 753     {
 754         formatter.Write(SpecifierStr(memberVariableNode.GetSpecifiers()));
 755         formatter.Write(" ");
 756     }
 757     memberVariableNode.TypeExpr()->Accept(*this);
 758     formatter.Write(" ");
 759     memberVariableNode.Id()->Accept(*this);
 760     formatter.WriteLine(";");
 761 }
 762 
 763 void SourceWriter::Visit(InterfaceNode& interfaceNode)
 764 {
 765     WriteEmptyLine();
 766     AttributesNode* attributes = interfaceNode.GetAttributes();
 767     if (attributes)
 768     {
 769         attributes->Accept(*this);
 770         formatter.WriteLine();
 771     }
 772     if (interfaceNode.GetSpecifiers() != Specifiers::none)
 773     {
 774         formatter.Write(SpecifierStr(interfaceNode.GetSpecifiers()));
 775         formatter.Write(" ");
 776     }
 777     formatter.Write("interface ");
 778     interfaceNode.Id()->Accept(*this);
 779     formatter.WriteLine();
 780     formatter.WriteLine("{");
 781     formatter.IncIndent();
 782     int n = interfaceNode.Members().Count();
 783     for (int i = 0; i < n; ++i)
 784     {
 785         interfaceNode.Members()[i]->Accept(*this);
 786     }
 787     formatter.DecIndent();
 788     formatter.WriteLine("}");
 789     emptyLine = true;
 790 }
 791 
 792 void SourceWriter::Visit(DelegateNode& delegateNode)
 793 {
 794     WriteEmptyLine();
 795     if (delegateNode.GetSpecifiers() != Specifiers::none)
 796     {
 797         formatter.Write(SpecifierStr(delegateNode.GetSpecifiers()));
 798         formatter.Write(" ");
 799     }
 800     formatter.Write("delegate ");
 801     delegateNode.ReturnTypeExpr()->Accept(*this);
 802     formatter.Write(" ");
 803     delegateNode.Id()->Accept(*this);
 804     formatter.Write("(");
 805     int np = delegateNode.Parameters().Count();
 806     for (int i = 0; i < np; ++i)
 807     {
 808         if (i > 0)
 809         {
 810             formatter.Write(", ");
 811         }
 812         delegateNode.Parameters()[i]->Accept(*this);
 813     }
 814     formatter.WriteLine(");");
 815     emptyLine = true;
 816 }
 817 
 818 void SourceWriter::Visit(ClassDelegateNode& classDelegateNode)
 819 {
 820     WriteEmptyLine();
 821     if (classDelegateNode.GetSpecifiers() != Specifiers::none)
 822     {
 823         formatter.Write(SpecifierStr(classDelegateNode.GetSpecifiers()));
 824         formatter.Write(" ");
 825     }
 826     formatter.Write("class delegate ");
 827     classDelegateNode.ReturnTypeExpr()->Accept(*this);
 828     formatter.Write(" ");
 829     classDelegateNode.Id()->Accept(*this);
 830     formatter.Write("(");
 831     int np = classDelegateNode.Parameters().Count();
 832     for (int i = 0; i < np; ++i)
 833     {
 834         if (i > 0)
 835         {
 836             formatter.Write(", ");
 837         }
 838         classDelegateNode.Parameters()[i]->Accept(*this);
 839     }
 840     formatter.WriteLine(");");
 841     emptyLine = true;
 842 }
 843 
 844 void SourceWriter::Visit(ParenthesizedConstraintNode& parenthesizedConstraintNode)
 845 {
 846     formatter.Write("(");
 847     parenthesizedConstraintNode.Constraint()->Accept(*this);
 848     formatter.Write(")");
 849 }
 850 
 851 void SourceWriter::Visit(DisjunctiveConstraintNode& disjunctiveConstraintNode)
 852 {
 853     disjunctiveConstraintNode.Left()->Accept(*this);
 854     formatter.Write(" or ");
 855     disjunctiveConstraintNode.Right()->Accept(*this);
 856 }
 857 
 858 void SourceWriter::Visit(ConjunctiveConstraintNode& conjunctiveConstraintNode)
 859 {
 860     conjunctiveConstraintNode.Left()->Accept(*this);
 861     formatter.Write(" and ");
 862     conjunctiveConstraintNode.Right()->Accept(*this);
 863 }
 864 
 865 void SourceWriter::Visit(WhereConstraintNode& whereConstraintNode)
 866 {
 867     formatter.Write("where ");
 868     whereConstraintNode.Constraint()->Accept(*this);
 869     if (whereConstraintNode.Semicolon())
 870     {
 871         formatter.WriteLine(";");
 872     }
 873 }
 874 
 875 void SourceWriter::Visit(PredicateConstraintNode& predicateConstraintNode)
 876 {
 877     predicateConstraintNode.InvokeExpr()->Accept(*this);
 878 }
 879 
 880 void SourceWriter::Visit(IsConstraintNode& isConstraintNode)
 881 {
 882     isConstraintNode.TypeExpr()->Accept(*this);
 883     formatter.Write(" is ");
 884     isConstraintNode.ConceptOrTypeName()->Accept(*this);
 885 }
 886 
 887 void SourceWriter::Visit(MultiParamConstraintNode& multiParamConstraintNode)
 888 {
 889     multiParamConstraintNode.ConceptId()->Accept(*this);
 890     formatter.Write("<");
 891     int n = multiParamConstraintNode.TypeExprs().Count();
 892     for (int i = 0; i < n; ++i)
 893     {
 894         if (i > 0)
 895         {
 896             formatter.Write(", ");
 897         }
 898         multiParamConstraintNode.TypeExprs()[i]->Accept(*this);
 899     }
 900     formatter.Write(">");
 901 }
 902 
 903 void SourceWriter::Visit(TypeNameConstraintNode& typeNameConstraintNode)
 904 {
 905     formatter.Write("typename ");
 906     typeNameConstraintNode.TypeId()->Accept(*this);
 907     formatter.WriteLine(";");
 908 }
 909 
 910 void SourceWriter::Visit(ConstructorConstraintNode& constructorConstraintNode)
 911 {
 912     constructorConstraintNode.TypeParamId()->Accept(*this);
 913     formatter.Write("(");
 914     int np = constructorConstraintNode.Parameters().Count();
 915     for (int i = 0; i < np; ++i)
 916     {
 917         if (i > 0)
 918         {
 919             formatter.Write(", ");
 920         }
 921         constructorConstraintNode.Parameters()[i]->Accept(*this);
 922     }
 923     formatter.WriteLine(");");
 924 }
 925 
 926 void SourceWriter::Visit(DestructorConstraintNode& destructorConstraintNode)
 927 {
 928     formatter.Write("~");
 929     destructorConstraintNode.TypeParamId()->Accept(*this);
 930     formatter.WriteLine("();");
 931 }
 932 
 933 void SourceWriter::Visit(MemberFunctionConstraintNode& memberFunctionConstraintNode)
 934 {
 935     memberFunctionConstraintNode.ReturnTypeExpr()->Accept(*this);
 936     formatter.Write(" ");
 937     memberFunctionConstraintNode.TypeParamId()->Accept(*this);
 938     formatter.Write(".");
 939     formatter.Write(soulng::unicode::ToUtf8(memberFunctionConstraintNode.GroupId()));
 940     formatter.Write("(");
 941     int np = memberFunctionConstraintNode.Parameters().Count();
 942     for (int i = 0; i < np; ++i)
 943     {
 944         if (i > 0)
 945         {
 946             formatter.Write(", ");
 947         }
 948         memberFunctionConstraintNode.Parameters()[i]->Accept(*this);
 949     }
 950     formatter.WriteLine(");");
 951 }
 952 
 953 void SourceWriter::Visit(FunctionConstraintNode& functionConstraintNode)
 954 {
 955     functionConstraintNode.ReturnTypeExpr()->Accept(*this);
 956     formatter.Write(" ");
 957     formatter.Write(soulng::unicode::ToUtf8(functionConstraintNode.GroupId()));
 958     formatter.Write("(");
 959     int np = functionConstraintNode.Parameters().Count();
 960     for (int i = 0; i < np; ++i)
 961     {
 962         if (i > 0)
 963         {
 964             formatter.Write(", ");
 965         }
 966         functionConstraintNode.Parameters()[i]->Accept(*this);
 967     }
 968     formatter.WriteLine(");");
 969 }
 970 
 971 void SourceWriter::Visit(AxiomStatementNode& axiomStatementNode)
 972 {
 973     axiomStatementNode.Expression()->Accept(*this);
 974     formatter.WriteLine(";");
 975 }
 976 
 977 void SourceWriter::Visit(AxiomNode& axiomNode)
 978 {
 979     formatter.Write("axiom ");
 980     axiomNode.Id()->Accept(*this);
 981     int np = axiomNode.Parameters().Count();
 982     if (np > 0)
 983     {
 984         formatter.Write("(");
 985         for (int i = 0; i < np; ++i)
 986         {
 987             if (i > 0)
 988             {
 989                 formatter.Write(", ");
 990             }
 991             axiomNode.Parameters()[i]->Accept(*this);
 992         }
 993         formatter.Write(")");
 994     }
 995     formatter.WriteLine();
 996     formatter.WriteLine("{");
 997     formatter.IncIndent();
 998     int n = axiomNode.Statements().Count();
 999     for (int i = 0; i < n; ++i)
1000     {
1001         axiomNode.Statements()[i]->Accept(*this);
1002     }
1003     formatter.DecIndent();
1004     formatter.WriteLine("}");
1005 }
1006 
1007 void SourceWriter::Visit(ConceptIdNode& conceptIdNode)
1008 {
1009     formatter.Write(" : ");
1010     conceptIdNode.Id()->Accept(*this);
1011     formatter.Write("<");
1012     int n = conceptIdNode.TypeParameters().Count();
1013     for (int i = 0; i < n; ++i)
1014     {
1015         if (i > 0)
1016         {
1017             formatter.Write(", ");
1018         }
1019         conceptIdNode.TypeParameters()[i]->Accept(*this);
1020     }
1021     formatter.Write(">");
1022 }
1023 
1024 void SourceWriter::Visit(ConceptNode& conceptNode)
1025 {
1026     WriteEmptyLine();
1027     if (conceptNode.GetSpecifiers() != Specifiers::none)
1028     {
1029         formatter.Write(SpecifierStr(conceptNode.GetSpecifiers()));
1030         formatter.Write(" ");
1031     }
1032     formatter.Write("concept ");
1033     conceptNode.Id()->Accept(*this);
1034     formatter.Write("<");
1035     int n = conceptNode.TypeParameters().Count();
1036     for (int i = 0; i < n; ++i)
1037     {
1038         if (i > 0)
1039         {
1040             formatter.Write(", ");
1041         }
1042         conceptNode.TypeParameters()[i]->Accept(*this);
1043     }
1044     formatter.Write(">");
1045     if (conceptNode.Refinement())
1046     {
1047         conceptNode.Refinement()->Accept(*this);
1048     }
1049     formatter.WriteLine();
1050     int nc = conceptNode.Constraints().Count();
1051     for (int i = 0; i < nc; ++i)
1052     {
1053         ConstraintNode* constraintNode = conceptNode.Constraints()[i];
1054         if (constraintNode->IsHeaderConstraint())
1055         {
1056             formatter.IncIndent();
1057             constraintNode->Accept(*this);
1058             formatter.DecIndent();
1059             formatter.WriteLine();
1060         }
1061     }
1062     formatter.WriteLine("{");
1063     formatter.IncIndent();
1064     for (int i = 0; i < nc; ++i)
1065     {
1066         ConstraintNode* constraintNode = conceptNode.Constraints()[i];
1067         if (constraintNode->IsHeaderConstraint()) continue;
1068         constraintNode->Accept(*this);
1069     }
1070     int na = conceptNode.Axioms().Count();
1071     for (int i = 0; i < na; ++i)
1072     {
1073         conceptNode.Axioms()[i]->Accept(*this);
1074     }
1075     formatter.DecIndent();
1076     formatter.WriteLine("}");
1077     emptyLine = true;
1078 }
1079 
1080 void SourceWriter::Visit(LabelNode& labelNode)
1081 {
1082     formatter.Write(soulng::unicode::ToUtf8(labelNode.Label()));
1083     formatter.Write(": ");
1084 }
1085 
1086 void SourceWriter::Visit(LabeledStatementNode& labeledStatementNode)
1087 {
1088     labeledStatementNode.Label()->Accept(*this);
1089     labeledStatementNode.Stmt()->Accept(*this);
1090 }
1091 
1092 void SourceWriter::Visit(CompoundStatementNode& compoundStatementNode)
1093 {
1094     formatter.WriteLine("{");
1095     formatter.IncIndent();
1096     int n = compoundStatementNode.Statements().Count();
1097     for (int i = 0; i < n; ++i)
1098     {
1099         compoundStatementNode.Statements()[i]->Accept(*this);
1100     }
1101     formatter.DecIndent();
1102     formatter.WriteLine("}");
1103 }
1104 
1105 void SourceWriter::Visit(ReturnStatementNode& returnStatementNode)
1106 {
1107     formatter.Write("return");
1108     if (returnStatementNode.Expression())
1109     {
1110         formatter.Write(" ");
1111         returnStatementNode.Expression()->Accept(*this);
1112     }
1113     formatter.WriteLine(";");
1114 }
1115 
1116 void SourceWriter::Visit(IfStatementNode& ifStatementNode)
1117 {
1118     formatter.Write("if (");
1119     ifStatementNode.Condition()->Accept(*this);
1120     if (ifStatementNode.ThenS()->GetNodeType() == NodeType::compoundStatementNode)
1121     {
1122         formatter.WriteLine(")");
1123     }
1124     else
1125     {
1126         formatter.Write(") ");
1127     }
1128     ifStatementNode.ThenS()->Accept(*this);
1129     if (ifStatementNode.ElseS())
1130     {
1131         if (ifStatementNode.ElseS()->GetNodeType() == NodeType::compoundStatementNode)
1132         {
1133             formatter.WriteLine("else");
1134         }
1135         else
1136         {
1137             formatter.Write("else ");
1138         }
1139         ifStatementNode.ElseS()->Accept(*this);
1140     }
1141 }
1142 
1143 void SourceWriter::Visit(WhileStatementNode& whileStatementNode)
1144 {
1145     formatter.Write("while (");
1146     whileStatementNode.Condition()->Accept(*this);
1147     if (whileStatementNode.Statement()->GetNodeType() == NodeType::compoundStatementNode)
1148     {
1149         formatter.WriteLine(")");
1150     }
1151     else
1152     {
1153         formatter.Write(") ");
1154     }
1155     whileStatementNode.Statement()->Accept(*this);
1156 }
1157 
1158 void SourceWriter::Visit(DoStatementNode& doStatementNode)
1159 {
1160     formatter.Write("do");
1161     if (doStatementNode.Statement()->GetNodeType() == NodeType::compoundStatementNode)
1162     {
1163         formatter.WriteLine();
1164     }
1165     else
1166     {
1167         formatter.Write(" ");
1168     }
1169     doStatementNode.Statement()->Accept(*this);
1170     formatter.Write("while (");
1171     doStatementNode.Condition()->Accept(*this);
1172     formatter.WriteLine(");");
1173 }
1174 
1175 void SourceWriter::Visit(ForStatementNode& forStatementNode)
1176 {
1177     formatter.Write("for (");
1178     omitNewLine = true;
1179     forStatementNode.InitS()->Accept(*this);
1180     formatter.Write(" ");
1181     omitNewLine = false;
1182     if (forStatementNode.Condition())
1183     {
1184         forStatementNode.Condition()->Accept(*this);
1185         formatter.Write("; ");
1186     }
1187     else
1188     {
1189         formatter.Write("; ");
1190     }
1191     omitSemicolon = true;
1192     omitNewLine = true;
1193     forStatementNode.LoopS()->Accept(*this);
1194     omitSemicolon = false;
1195     omitNewLine = false;
1196     if (forStatementNode.ActionS()->GetNodeType() == NodeType::compoundStatementNode)
1197     {
1198         formatter.WriteLine(")");
1199     }
1200     else
1201     {
1202         formatter.Write(") ");
1203     }
1204     forStatementNode.ActionS()->Accept(*this);
1205 }
1206 
1207 void SourceWriter::Visit(BreakStatementNode& breakStatementNode)
1208 {
1209     formatter.WriteLine("break;");
1210 }
1211 
1212 void SourceWriter::Visit(ContinueStatementNode& continueStatementNode)
1213 {
1214     formatter.WriteLine("continue;");
1215 }
1216 
1217 void SourceWriter::Visit(GotoStatementNode& gotoStatementNode)
1218 {
1219     formatter.Write("goto ");
1220     formatter.Write(soulng::unicode::ToUtf8(gotoStatementNode.Target()));
1221     formatter.WriteLine(";");
1222 }
1223 
1224 void SourceWriter::Visit(ConstructionStatementNode& constructionStatementNode)
1225 {
1226     constructionStatementNode.TypeExpr()->Accept(*this);
1227     formatter.Write(" ");
1228     constructionStatementNode.Id()->Accept(*this);
1229     if (constructionStatementNode.Empty())
1230     {
1231         formatter.Write(";");
1232     }
1233     else if (constructionStatementNode.Assignment())
1234     {
1235         formatter.Write(" = ");
1236         constructionStatementNode.Arguments()[0]->Accept(*this);
1237         formatter.Write(";");
1238     }
1239     else
1240     {
1241         formatter.Write("(");
1242         int n = constructionStatementNode.Arguments().Count();
1243         for (int i = 0; i < n; ++i)
1244         {
1245             if (i > 0)
1246             {
1247                 formatter.Write(", ");
1248             }
1249             constructionStatementNode.Arguments()[i]->Accept(*this);
1250         }
1251         formatter.Write(");");
1252     }
1253     if (!omitNewLine)
1254     {
1255         formatter.WriteLine();
1256     }
1257 }
1258 
1259 void SourceWriter::Visit(DeleteStatementNode& deleteStatementNode)
1260 {
1261     formatter.Write("delete ");
1262     deleteStatementNode.Expression()->Accept(*this);
1263     formatter.WriteLine(";");
1264 }
1265 
1266 void SourceWriter::Visit(DestroyStatementNode& destroyStatementNode)
1267 {
1268     formatter.Write("destroy ");
1269     destroyStatementNode.Expression()->Accept(*this);
1270     formatter.WriteLine(";");
1271 }
1272 
1273 void SourceWriter::Visit(AssignmentStatementNode& assignmentStatementNode)
1274 {
1275     assignmentStatementNode.TargetExpr()->Accept(*this);
1276     formatter.Write(" = ");
1277     assignmentStatementNode.SourceExpr()->Accept(*this);
1278     if (!omitSemicolon)
1279     {
1280         formatter.Write(";");
1281     }
1282     if (!omitNewLine)
1283     {
1284         formatter.WriteLine();
1285     }
1286 }
1287 
1288 void SourceWriter::Visit(ExpressionStatementNode& expressionStatementNode)
1289 {
1290     expressionStatementNode.Expression()->Accept(*this);
1291     if (!omitSemicolon)
1292     {
1293         formatter.Write(";");
1294     }
1295     if (!omitNewLine)
1296     {
1297         formatter.WriteLine();
1298     }
1299 }
1300 
1301 void SourceWriter::Visit(EmptyStatementNode& emptyStatementNode)
1302 {
1303     if (!omitSemicolon)
1304     {
1305         formatter.Write(";");
1306     }
1307     if (!omitNewLine)
1308     {
1309         formatter.WriteLine();
1310     }
1311 }
1312 
1313 void SourceWriter::Visit(RangeForStatementNode& rangeForStatementNode)
1314 {
1315     formatter.Write("for (");
1316     rangeForStatementNode.TypeExpr()->Accept(*this);
1317     formatter.Write(" ");
1318     rangeForStatementNode.Id()->Accept(*this);
1319     formatter.Write(" : ");
1320     rangeForStatementNode.Container()->Accept(*this);
1321     if (rangeForStatementNode.Action()->GetNodeType() == NodeType::compoundStatementNode)
1322     {
1323         formatter.WriteLine(")");
1324     }
1325     else
1326     {
1327         formatter.Write(") ");
1328     }
1329     rangeForStatementNode.Action()->Accept(*this);
1330 }
1331 
1332 void SourceWriter::Visit(SwitchStatementNode& switchStatementNode)
1333 {
1334     formatter.Write("switch (");
1335     switchStatementNode.Condition()->Accept(*this);
1336     formatter.WriteLine(")");
1337     formatter.WriteLine("{");
1338     formatter.IncIndent();
1339     int n = switchStatementNode.Cases().Count();
1340     for (int i = 0; i < n; ++i)
1341     {
1342         switchStatementNode.Cases()[i]->Accept(*this);
1343     }
1344     if (switchStatementNode.Default())
1345     {
1346         switchStatementNode.Default()->Accept(*this);
1347     }
1348     formatter.DecIndent();
1349     formatter.WriteLine("}");
1350 }
1351 
1352 void SourceWriter::Visit(CaseStatementNode& caseStatementNode)
1353 {
1354     int n = caseStatementNode.CaseExprs().Count();
1355     for (int i = 0; i < n; ++i)
1356     {
1357         formatter.Write("case ");
1358         caseStatementNode.CaseExprs()[i]->Accept(*this);
1359         formatter.Write(": ");
1360     }
1361     int ns = caseStatementNode.Statements().Count();
1362     for (int i = 0; i < ns; ++i)
1363     {
1364         if (i == 0 && caseStatementNode.Statements()[i]->GetNodeType() == NodeType::compoundStatementNode)
1365         {
1366             formatter.WriteLine();
1367         }
1368         caseStatementNode.Statements()[i]->Accept(*this);
1369     }
1370 }
1371 
1372 void SourceWriter::Visit(DefaultStatementNode& defaultStatementNode)
1373 {
1374     formatter.Write("default: ");
1375     int ns = defaultStatementNode.Statements().Count();
1376     for (int i = 0; i < ns; ++i)
1377     {
1378         if (i == 0 && defaultStatementNode.Statements()[i]->GetNodeType() == NodeType::compoundStatementNode)
1379         {
1380             formatter.WriteLine();
1381         }
1382         defaultStatementNode.Statements()[i]->Accept(*this);
1383     }
1384 }
1385 
1386 void SourceWriter::Visit(GotoCaseStatementNode& gotoCaseStatementNode)
1387 {
1388     formatter.Write("goto case ");
1389     gotoCaseStatementNode.CaseExpr()->Accept(*this);
1390     formatter.WriteLine(";");
1391 }
1392 
1393 void SourceWriter::Visit(GotoDefaultStatementNode& gotoDefaultStatementNode)
1394 {
1395     formatter.WriteLine("goto default;");
1396 }
1397 
1398 void SourceWriter::Visit(ThrowStatementNode& throwStatementNode)
1399 {
1400     formatter.Write("throw");
1401     if (throwStatementNode.Expression())
1402     {
1403         formatter.Write(" ");
1404         throwStatementNode.Expression()->Accept(*this);
1405     }
1406     formatter.WriteLine(";");
1407 }
1408 
1409 void SourceWriter::Visit(TryStatementNode& tryStatementNode)
1410 {
1411     formatter.WriteLine("try");
1412     tryStatementNode.TryBlock()->Accept(*this);
1413     int n = tryStatementNode.Catches().Count();
1414     for (int i = 0; i < n; ++i)
1415     {
1416         tryStatementNode.Catches()[i]->Accept(*this);
1417     }
1418 }
1419 
1420 void SourceWriter::Visit(CatchNode& catchNode)
1421 {
1422     formatter.Write("catch (");
1423     catchNode.TypeExpr()->Accept(*this);
1424     if (catchNode.Id())
1425     {
1426         formatter.Write(" ");
1427         catchNode.Id()->Accept(*this);
1428     }
1429     formatter.WriteLine(")");
1430     catchNode.CatchBlock()->Accept(*this);
1431 }
1432 
1433 void SourceWriter::Visit(AssertStatementNode& assertStatementNode)
1434 {
1435     formatter.Write("#assert ");
1436     assertStatementNode.AssertExpr()->Accept(*this);
1437     formatter.WriteLine(";");
1438 }
1439 
1440 void SourceWriter::Visit(ConditionalCompilationPartNode& conditionalCompilationPartNode)
1441 {
1442     int n = conditionalCompilationPartNode.Statements().Count();
1443     for (int i = 0; i < n; ++i)
1444     {
1445         conditionalCompilationPartNode.Statements()[i]->Accept(*this);
1446     }
1447 }
1448 
1449 void SourceWriter::Visit(ConditionalCompilationDisjunctionNode& conditionalCompilationDisjunctionNode)
1450 {
1451     conditionalCompilationDisjunctionNode.Left()->Accept(*this);
1452     formatter.Write(" || ");
1453     conditionalCompilationDisjunctionNode.Right()->Accept(*this);
1454 }
1455 
1456 void SourceWriter::Visit(ConditionalCompilationConjunctionNode& conditionalCompilationConjunctionNode)
1457 {
1458     conditionalCompilationConjunctionNode.Left()->Accept(*this);
1459     formatter.Write(" && ");
1460     conditionalCompilationConjunctionNode.Right()->Accept(*this);
1461 }
1462 
1463 void SourceWriter::Visit(ConditionalCompilationNotNode& conditionalCompilationNotNode)
1464 {
1465     formatter.Write("!");
1466     conditionalCompilationNotNode.Expr()->Accept(*this);
1467 }
1468 
1469 void SourceWriter::Visit(ConditionalCompilationPrimaryNode& conditionalCompilationPrimaryNode)
1470 {
1471     formatter.Write(soulng::unicode::ToUtf8(conditionalCompilationPrimaryNode.Symbol()));
1472 }
1473 
1474 void SourceWriter::Visit(ParenthesizedConditionalCompilationExpressionNode& parenthesizeCondCompExprNode)
1475 {
1476     formatter.Write("(");
1477     parenthesizeCondCompExprNode.Expr()->Accept(*this);
1478     formatter.Write(")");
1479 }
1480 
1481 void SourceWriter::Visit(ConditionalCompilationStatementNode& conditionalCompilationStatementNode)
1482 {
1483     formatter.Write("#");
1484     formatter.Write("if (");
1485     conditionalCompilationStatementNode.IfPart()->Expr()->Accept(*this);
1486     formatter.WriteLine(")");
1487     formatter.IncIndent();
1488     conditionalCompilationStatementNode.IfPart()->Accept(*this);
1489     formatter.DecIndent();
1490     int ne = conditionalCompilationStatementNode.ElifParts().Count();
1491     for (int i = 0; i < ne; ++i)
1492     {
1493         formatter.Write("#");
1494         formatter.Write("elif (");
1495         conditionalCompilationStatementNode.ElifParts()[i]->Expr()->Accept(*this);
1496         formatter.WriteLine(")");
1497         formatter.IncIndent();
1498         conditionalCompilationStatementNode.ElifParts()[i]->Accept(*this);
1499         formatter.DecIndent();
1500     }
1501     if (conditionalCompilationStatementNode.ElsePart())
1502     {
1503         formatter.Write("#");
1504         formatter.WriteLine("else");
1505         formatter.IncIndent();
1506         conditionalCompilationStatementNode.ElsePart()->Accept(*this);
1507         formatter.DecIndent();
1508     }
1509     formatter.WriteLine("#endif");
1510 }
1511 
1512 void SourceWriter::Visit(TypedefNode& typedefNode)
1513 {
1514     if (typedefNode.Parent()->GetNodeType() != NodeType::classNode)
1515     {
1516         WriteEmptyLine();
1517     }
1518     if (typedefNode.GetSpecifiers() != Specifiers::none)
1519     {
1520         formatter.Write(SpecifierStr(typedefNode.GetSpecifiers()));
1521         formatter.Write(" ");
1522     }
1523     formatter.Write("typedef ");
1524     typedefNode.TypeExpr()->Accept(*this);
1525     formatter.Write(" ");
1526     typedefNode.Id()->Accept(*this);
1527     formatter.WriteLine(";");
1528     if (typedefNode.Parent()->GetNodeType() != NodeType::classNode)
1529     {
1530         emptyLine = true;
1531     }
1532 }
1533 
1534 void SourceWriter::Visit(ConstantNode& constantNode)
1535 {
1536     if (constantNode.Parent()->GetNodeType() != NodeType::classNode)
1537     {
1538         WriteEmptyLine();
1539     }
1540     if (constantNode.GetSpecifiers() != Specifiers::none)
1541     {
1542         formatter.Write(SpecifierStr(constantNode.GetSpecifiers()));
1543         formatter.Write(" ");
1544     }
1545     formatter.Write("const ");
1546     constantNode.TypeExpr()->Accept(*this);
1547     formatter.Write(" ");
1548     constantNode.Id()->Accept(*this);
1549     formatter.Write(" = ");
1550     constantNode.Value()->Accept(*this);
1551     formatter.WriteLine(";");
1552     if (constantNode.Parent()->GetNodeType() != NodeType::classNode)
1553     {
1554         emptyLine = true;
1555     }
1556 }
1557 
1558 void SourceWriter::Visit(EnumTypeNode& enumTypeNode)
1559 {
1560     if (enumTypeNode.Parent()->GetNodeType() != NodeType::classNode)
1561     {
1562         WriteEmptyLine();
1563     }
1564     if (enumTypeNode.GetSpecifiers() != Specifiers::none)
1565     {
1566         formatter.Write(SpecifierStr(enumTypeNode.GetSpecifiers()));
1567         formatter.Write(" ");
1568     }
1569     formatter.Write("enum ");
1570     enumTypeNode.Id()->Accept(*this);
1571     if (enumTypeNode.GetUnderlyingType())
1572     {
1573         formatter.Write(" : ");
1574         enumTypeNode.GetUnderlyingType()->Accept(*this);
1575     }
1576     formatter.WriteLine();
1577     formatter.WriteLine("{");
1578     formatter.IncIndent();
1579     int n = enumTypeNode.Constants().Count();
1580     for (int i = 0; i < n; ++i)
1581     {
1582         if (i > 0)
1583         {
1584             formatter.Write(", ");
1585         }
1586         enumTypeNode.Constants()[i]->Accept(*this);
1587     }
1588     formatter.WriteLine();
1589     formatter.DecIndent();
1590     formatter.WriteLine("}");
1591     if (enumTypeNode.Parent()->GetNodeType() != NodeType::classNode)
1592     {
1593         emptyLine = true;
1594     }
1595 }
1596 
1597 void SourceWriter::Visit(EnumConstantNode& enumConstantNode)
1598 {
1599     enumConstantNode.Id()->Accept(*this);
1600     if (enumConstantNode.HasValue())
1601     {
1602         formatter.Write(" = ");
1603         enumConstantNode.GetValue()->Accept(*this);
1604     }
1605 }
1606 
1607 void SourceWriter::Visit(ParameterNode& parameterNode)
1608 {
1609     parameterNode.TypeExpr()->Accept(*this);
1610     if (parameterNode.Id())
1611     {
1612         formatter.Write(" ");
1613         parameterNode.Id()->Accept(*this);
1614     }
1615 }
1616 
1617 void SourceWriter::Visit(TemplateParameterNode& templateParameterNode)
1618 {
1619     templateParameterNode.Id()->Accept(*this);
1620     if (templateParameterNode.DefaultTemplateArgument())
1621     {
1622         formatter.Write(" = ");
1623         templateParameterNode.DefaultTemplateArgument()->Accept(*this);
1624     }
1625 }
1626 
1627 void SourceWriter::Visit(ConstNode& constNode)
1628 {
1629     formatter.Write("const ");
1630     constNode.Subject()->Accept(*this);
1631 }
1632 
1633 void SourceWriter::Visit(LValueRefNode& lvalueRefNode)
1634 {
1635     lvalueRefNode.Subject()->Accept(*this);
1636     formatter.Write("&");
1637 }
1638 
1639 void SourceWriter::Visit(RValueRefNode& rvalueRefNode)
1640 {
1641     rvalueRefNode.Subject()->Accept(*this);
1642     formatter.Write("&&");
1643 }
1644 
1645 void SourceWriter::Visit(PointerNode& pointerNode)
1646 {
1647     pointerNode.Subject()->Accept(*this);
1648     formatter.Write("*");
1649 }
1650 
1651 void SourceWriter::Visit(ArrayNode& arrayNode)
1652 {
1653     arrayNode.Subject()->Accept(*this);
1654     formatter.Write("[");
1655     if (arrayNode.Size())
1656     {
1657         arrayNode.Size()->Accept(*this);
1658     }
1659     formatter.Write("]");
1660 }
1661 
1662 void SourceWriter::Visit(DotNode& dotNode)
1663 {
1664     dotNode.Subject()->Accept(*this);
1665     formatter.Write(".");
1666     dotNode.MemberId()->Accept(*this);
1667 }
1668 
1669 void SourceWriter::Visit(ArrowNode& arrowNode)
1670 {
1671     arrowNode.Subject()->Accept(*this);
1672     formatter.Write("->");
1673     arrowNode.MemberId()->Accept(*this);
1674 }
1675 
1676 void SourceWriter::Visit(EquivalenceNode& equivalenceNode)
1677 {
1678     equivalenceNode.Left()->Accept(*this);
1679     formatter.Write(" <=> ");
1680     equivalenceNode.Right()->Accept(*this);
1681 }
1682 
1683 void SourceWriter::Visit(ImplicationNode& implicationNode)
1684 {
1685     implicationNode.Left()->Accept(*this);
1686     formatter.Write(" => ");
1687     implicationNode.Right()->Accept(*this);
1688 }
1689 
1690 void SourceWriter::Visit(DisjunctionNode& disjunctionNode)
1691 {
1692     disjunctionNode.Left()->Accept(*this);
1693     formatter.Write(" || ");
1694     disjunctionNode.Right()->Accept(*this);
1695 }
1696 
1697 void SourceWriter::Visit(ConjunctionNode& conjunctionNode)
1698 {
1699     conjunctionNode.Left()->Accept(*this);
1700     formatter.Write(" && ");
1701     conjunctionNode.Right()->Accept(*this);
1702 }
1703 
1704 void SourceWriter::Visit(BitOrNode& bitOrNode)
1705 {
1706     bitOrNode.Left()->Accept(*this);
1707     formatter.Write(" | ");
1708     bitOrNode.Right()->Accept(*this);
1709 }
1710 
1711 void SourceWriter::Visit(BitXorNode& bitXorNode)
1712 {
1713     bitXorNode.Left()->Accept(*this);
1714     formatter.Write(" ^ ");
1715     bitXorNode.Right()->Accept(*this);
1716 }
1717 
1718 void SourceWriter::Visit(BitAndNode& bitAndNode)
1719 {
1720     bitAndNode.Left()->Accept(*this);
1721     formatter.Write(" & ");
1722     bitAndNode.Right()->Accept(*this);
1723 }
1724 
1725 void SourceWriter::Visit(EqualNode& equalNode)
1726 {
1727     equalNode.Left()->Accept(*this);
1728     formatter.Write(" == ");
1729     equalNode.Right()->Accept(*this);
1730 }
1731 
1732 void SourceWriter::Visit(NotEqualNode& notEqualNode)
1733 {
1734     notEqualNode.Left()->Accept(*this);
1735     formatter.Write(" != ");
1736     notEqualNode.Right()->Accept(*this);
1737 }
1738 
1739 void SourceWriter::Visit(LessNode& lessNode)
1740 {
1741     lessNode.Left()->Accept(*this);
1742     formatter.Write(" < ");
1743     lessNode.Right()->Accept(*this);
1744 }
1745 
1746 void SourceWriter::Visit(GreaterNode& greaterNode)
1747 {
1748     greaterNode.Left()->Accept(*this);
1749     formatter.Write(" > ");
1750     greaterNode.Right()->Accept(*this);
1751 }
1752 
1753 void SourceWriter::Visit(LessOrEqualNode& lessOrEqualNode)
1754 {
1755     lessOrEqualNode.Left()->Accept(*this);
1756     formatter.Write(" <= ");
1757     lessOrEqualNode.Right()->Accept(*this);
1758 }
1759 
1760 void SourceWriter::Visit(GreaterOrEqualNode& greaterOrEqualNode)
1761 {
1762     greaterOrEqualNode.Left()->Accept(*this);
1763     formatter.Write(" >= ");
1764     greaterOrEqualNode.Right()->Accept(*this);
1765 }
1766 
1767 void SourceWriter::Visit(ShiftLeftNode& shiftLeftNode)
1768 {
1769     shiftLeftNode.Left()->Accept(*this);
1770     formatter.Write(" << ");
1771     shiftLeftNode.Right()->Accept(*this);
1772 }
1773 
1774 void SourceWriter::Visit(ShiftRightNode& shiftRightNode)
1775 {
1776     shiftRightNode.Left()->Accept(*this);
1777     formatter.Write(" >> ");
1778     shiftRightNode.Right()->Accept(*this);
1779 }
1780 
1781 void SourceWriter::Visit(AddNode& addNode)
1782 {
1783     addNode.Left()->Accept(*this);
1784     formatter.Write(" + ");
1785     addNode.Right()->Accept(*this);
1786 }
1787 
1788 void SourceWriter::Visit(SubNode& subNode)
1789 {
1790     subNode.Left()->Accept(*this);
1791     formatter.Write(" - ");
1792     subNode.Right()->Accept(*this);
1793 }
1794 
1795 void SourceWriter::Visit(MulNode& mulNode)
1796 {
1797     mulNode.Left()->Accept(*this);
1798     formatter.Write(" * ");
1799     mulNode.Right()->Accept(*this);
1800 }
1801 
1802 void SourceWriter::Visit(DivNode& divNode)
1803 {
1804     divNode.Left()->Accept(*this);
1805     formatter.Write(" / ");
1806     divNode.Right()->Accept(*this);
1807 }
1808 
1809 void SourceWriter::Visit(RemNode& remNode)
1810 {
1811     remNode.Left()->Accept(*this);
1812     formatter.Write(" % ");
1813     remNode.Right()->Accept(*this);
1814 }
1815 
1816 void SourceWriter::Visit(NotNode& notNode)
1817 {
1818     formatter.Write("!");
1819     notNode.Subject()->Accept(*this);
1820 }
1821 
1822 void SourceWriter::Visit(UnaryPlusNode& unaryPlusNode)
1823 {
1824     formatter.Write("+");
1825     unaryPlusNode.Subject()->Accept(*this);
1826 }
1827 
1828 void SourceWriter::Visit(UnaryMinusNode& unaryMinusNode)
1829 {
1830     formatter.Write("-");
1831     unaryMinusNode.Subject()->Accept(*this);
1832 }
1833 
1834 void SourceWriter::Visit(PrefixIncrementNode& prefixIncrementNode)
1835 {
1836     formatter.Write("++");
1837     prefixIncrementNode.Subject()->Accept(*this);
1838 }
1839 
1840 void SourceWriter::Visit(PrefixDecrementNode& prefixDecrementNode)
1841 {
1842     formatter.Write("--");
1843     prefixDecrementNode.Subject()->Accept(*this);
1844 }
1845 
1846 void SourceWriter::Visit(DerefNode& derefNode)
1847 {
1848     formatter.Write("*");
1849     derefNode.Subject()->Accept(*this);
1850 }
1851 
1852 void SourceWriter::Visit(AddrOfNode& addrOfNode)
1853 {
1854     formatter.Write("&");
1855     addrOfNode.Subject()->Accept(*this);
1856 }
1857 
1858 void SourceWriter::Visit(ComplementNode& complementNode)
1859 {
1860     formatter.Write("~");
1861     complementNode.Subject()->Accept(*this);
1862 }
1863 
1864 void SourceWriter::Visit(IsNode& isNode)
1865 {
1866     isNode.Expr()->Accept(*this);
1867     formatter.Write(" is ");
1868     isNode.TargetTypeExpr()->Accept(*this);
1869 }
1870 
1871 void SourceWriter::Visit(AsNode& asNode)
1872 {
1873     asNode.Expr()->Accept(*this);
1874     formatter.Write(" as ");
1875     asNode.TargetTypeExpr()->Accept(*this);
1876 }
1877 
1878 void SourceWriter::Visit(IndexingNode& indexingNode)
1879 {
1880     indexingNode.Subject()->Accept(*this);
1881     formatter.Write("[");
1882     indexingNode.Index()->Accept(*this);
1883     formatter.Write("]");
1884 }
1885 
1886 void SourceWriter::Visit(InvokeNode& invokeNode)
1887 {
1888     invokeNode.Subject()->Accept(*this);
1889     formatter.Write("(");
1890     int n = invokeNode.Arguments().Count();
1891     for (int i = 0; i < n; ++i)
1892     {
1893         if (i > 0)
1894         {
1895             formatter.Write(", ");
1896         }
1897         invokeNode.Arguments()[i]->Accept(*this);
1898     }
1899     formatter.Write(")");
1900 }
1901 
1902 void SourceWriter::Visit(PostfixIncrementNode& postfixIncrementNode)
1903 {
1904     postfixIncrementNode.Subject()->Accept(*this);
1905     formatter.Write("++");
1906 }
1907 
1908 void SourceWriter::Visit(PostfixDecrementNode& postfixDecrementNode)
1909 {
1910     postfixDecrementNode.Subject()->Accept(*this);
1911     formatter.Write("--");
1912 }
1913 
1914 void SourceWriter::Visit(SizeOfNode& sizeOfNode)
1915 {
1916     formatter.Write("sizeof(");
1917     sizeOfNode.Expression()->Accept(*this);
1918     formatter.Write(")");
1919 }
1920 
1921 void SourceWriter::Visit(TypeNameNode& typeNameNode)
1922 {
1923     formatter.Write("typename(");
1924     typeNameNode.Expression()->Accept(*this);
1925     formatter.Write(")");
1926 }
1927 
1928 void SourceWriter::Visit(TypeIdNode& typeIdNode)
1929 {
1930     formatter.Write("typeid(");
1931     typeIdNode.Expression()->Accept(*this);
1932     formatter.Write(")");
1933 }
1934 
1935 void SourceWriter::Visit(CastNode& castNode)
1936 {
1937     formatter.Write("cast<");
1938     castNode.TargetTypeExpr()->Accept(*this);
1939     formatter.Write(">(");
1940     castNode.SourceExpr()->Accept(*this);
1941     formatter.Write(")");
1942 }
1943 
1944 void SourceWriter::Visit(ConstructNode& constructNode)
1945 {
1946     formatter.Write("construct<");
1947     constructNode.TypeExpr()->Accept(*this);
1948     formatter.Write(">(");
1949     int n = constructNode.Arguments().Count();
1950     for (int i = 0; i < n; ++i)
1951     {
1952         if (i > 0)
1953         {
1954             formatter.Write(", ");
1955         }
1956         constructNode.Arguments()[i]->Accept(*this);
1957     }
1958     formatter.Write(")");
1959 }
1960 
1961 void SourceWriter::Visit(NewNode& newNode)
1962 {
1963     formatter.Write("new ");
1964     newNode.TypeExpr()->Accept(*this);
1965     formatter.Write("(");
1966     int n = newNode.Arguments().Count();
1967     for (int i = 0; i < n; ++i)
1968     {
1969         if (i > 0)
1970         {
1971             formatter.Write(", ");
1972         }
1973         newNode.Arguments()[i]->Accept(*this);
1974     }
1975     formatter.Write(")");
1976 }
1977 
1978 void SourceWriter::Visit(ThisNode& thisNode)
1979 {
1980     formatter.Write("this");
1981 }
1982 
1983 void SourceWriter::Visit(BaseNode& baseNode)
1984 {
1985     formatter.Write("base");
1986 }
1987 
1988 void SourceWriter::Visit(ParenthesizedExpressionNode& parenthesizedExpressionNode)
1989 {
1990     formatter.Write("(");
1991     parenthesizedExpressionNode.Subject()->Accept(*this);
1992     formatter.Write(")");
1993 }
1994 
1995 void SourceWriter::Visit(GlobalVariableNode& globalVariableNode)
1996 {
1997     WriteEmptyLine();
1998     if (globalVariableNode.GetSpecifiers() != Specifiers::none)
1999     {
2000         formatter.Write(SpecifierStr(globalVariableNode.GetSpecifiers()));
2001         formatter.Write(" ");
2002     }
2003     globalVariableNode.TypeExpr()->Accept(*this);
2004     formatter.Write(" ");
2005     globalVariableNode.Id()->Accept(*this);
2006     if (globalVariableNode.Initializer())
2007     {
2008         formatter.Write(" = ");
2009         globalVariableNode.Initializer()->Accept(*this);
2010     }
2011     formatter.WriteLine(";");
2012     emptyLine = true;
2013 }
2014 
2015 void SourceWriter::Visit(AttributeNode& attribute)
2016 {
2017     formatter.Write(soulng::unicode::ToUtf8(attribute.Name()));
2018     if (!attribute.Value().empty())
2019     {
2020         formatter.Write("=");
2021         formatter.Write("\"" + soulng::util::StringStr(soulng::unicode::ToUtf8(attribute.Value())) + "\"");
2022     }
2023 }
2024 
2025 void SourceWriter::Visit(AttributesNode& attributes)
2026 {
2027     formatter.Write("[");
2028     int n = static_cast<int>(attributes.GetAttributes().size());
2029     for (int i = 0; i < n; ++i)
2030     {
2031         if (i > 0)
2032         {
2033             formatter.Write(", ");
2034         }
2035         attributes.GetAttributes()[i]->Accept(*this);
2036     }
2037     formatter.Write("]");
2038 }
2039 
2040 void SourceWriter::Visit(CommentNode& comment)
2041 {
2042     formatter.WriteLine("// " + soulng::unicode::ToUtf8(comment.Comment()));
2043     formatter.WriteLine();
2044 }
2045 
2046 void SourceWriter::WriteWarning(const std::string& message)
2047 {
2048     std::cerr << message << std::endl;
2049 }
2050 
2051 void SourceWriter::WriteEmptyLine()
2052 {
2053     if (emptyLine)
2054     {
2055         formatter.WriteLine();
2056         emptyLine = false;
2057     }
2058 }
2059 
2060 } } // sngcm::ast