1#include "AST.h" 2#include "Type.h" 3 4void 5WriteModifiers(FILE* to, int mod, int mask) 6{ 7 int m = mod & mask; 8 9 if (m & OVERRIDE) { 10 fprintf(to, "@Override "); 11 } 12 13 if ((m & SCOPE_MASK) == PUBLIC) { 14 fprintf(to, "public "); 15 } 16 else if ((m & SCOPE_MASK) == PRIVATE) { 17 fprintf(to, "private "); 18 } 19 else if ((m & SCOPE_MASK) == PROTECTED) { 20 fprintf(to, "protected "); 21 } 22 23 if (m & STATIC) { 24 fprintf(to, "static "); 25 } 26 27 if (m & FINAL) { 28 fprintf(to, "final "); 29 } 30 31 if (m & ABSTRACT) { 32 fprintf(to, "abstract "); 33 } 34} 35 36void 37WriteArgumentList(FILE* to, const vector<Expression*>& arguments) 38{ 39 size_t N = arguments.size(); 40 for (size_t i=0; i<N; i++) { 41 arguments[i]->Write(to); 42 if (i != N-1) { 43 fprintf(to, ", "); 44 } 45 } 46} 47 48ClassElement::ClassElement() 49{ 50} 51 52ClassElement::~ClassElement() 53{ 54} 55 56Field::Field() 57 :ClassElement(), 58 modifiers(0), 59 variable(NULL) 60{ 61} 62 63Field::Field(int m, Variable* v) 64 :ClassElement(), 65 modifiers(m), 66 variable(v) 67{ 68} 69 70Field::~Field() 71{ 72} 73 74void 75Field::GatherTypes(set<Type*>* types) const 76{ 77 types->insert(this->variable->type); 78} 79 80void 81Field::Write(FILE* to) 82{ 83 if (this->comment.length() != 0) { 84 fprintf(to, "%s\n", this->comment.c_str()); 85 } 86 WriteModifiers(to, this->modifiers, SCOPE_MASK | STATIC | FINAL | OVERRIDE); 87 fprintf(to, "%s %s", this->variable->type->QualifiedName().c_str(), 88 this->variable->name.c_str()); 89 if (this->value.length() != 0) { 90 fprintf(to, " = %s", this->value.c_str()); 91 } 92 fprintf(to, ";\n"); 93} 94 95Expression::~Expression() 96{ 97} 98 99LiteralExpression::LiteralExpression(const string& v) 100 :value(v) 101{ 102} 103 104LiteralExpression::~LiteralExpression() 105{ 106} 107 108void 109LiteralExpression::Write(FILE* to) 110{ 111 fprintf(to, "%s", this->value.c_str()); 112} 113 114StringLiteralExpression::StringLiteralExpression(const string& v) 115 :value(v) 116{ 117} 118 119StringLiteralExpression::~StringLiteralExpression() 120{ 121} 122 123void 124StringLiteralExpression::Write(FILE* to) 125{ 126 fprintf(to, "\"%s\"", this->value.c_str()); 127} 128 129Variable::Variable() 130 :type(NULL), 131 name(), 132 dimension(0) 133{ 134} 135 136Variable::Variable(Type* t, const string& n) 137 :type(t), 138 name(n), 139 dimension(0) 140{ 141} 142 143Variable::Variable(Type* t, const string& n, int d) 144 :type(t), 145 name(n), 146 dimension(d) 147{ 148} 149 150Variable::~Variable() 151{ 152} 153 154void 155Variable::GatherTypes(set<Type*>* types) const 156{ 157 types->insert(this->type); 158} 159 160void 161Variable::WriteDeclaration(FILE* to) 162{ 163 string dim; 164 for (int i=0; i<this->dimension; i++) { 165 dim += "[]"; 166 } 167 fprintf(to, "%s%s %s", this->type->QualifiedName().c_str(), dim.c_str(), 168 this->name.c_str()); 169} 170 171void 172Variable::Write(FILE* to) 173{ 174 fprintf(to, "%s", name.c_str()); 175} 176 177FieldVariable::FieldVariable(Expression* o, const string& n) 178 :object(o), 179 clazz(NULL), 180 name(n) 181{ 182} 183 184FieldVariable::FieldVariable(Type* c, const string& n) 185 :object(NULL), 186 clazz(c), 187 name(n) 188{ 189} 190 191FieldVariable::~FieldVariable() 192{ 193} 194 195void 196FieldVariable::Write(FILE* to) 197{ 198 if (this->object != NULL) { 199 this->object->Write(to); 200 } 201 else if (this->clazz != NULL) { 202 fprintf(to, "%s", this->clazz->QualifiedName().c_str()); 203 } 204 fprintf(to, ".%s", name.c_str()); 205} 206 207 208Statement::~Statement() 209{ 210} 211 212StatementBlock::StatementBlock() 213{ 214} 215 216StatementBlock::~StatementBlock() 217{ 218} 219 220void 221StatementBlock::Write(FILE* to) 222{ 223 fprintf(to, "{\n"); 224 int N = this->statements.size(); 225 for (int i=0; i<N; i++) { 226 this->statements[i]->Write(to); 227 } 228 fprintf(to, "}\n"); 229} 230 231void 232StatementBlock::Add(Statement* statement) 233{ 234 this->statements.push_back(statement); 235} 236 237void 238StatementBlock::Add(Expression* expression) 239{ 240 this->statements.push_back(new ExpressionStatement(expression)); 241} 242 243ExpressionStatement::ExpressionStatement(Expression* e) 244 :expression(e) 245{ 246} 247 248ExpressionStatement::~ExpressionStatement() 249{ 250} 251 252void 253ExpressionStatement::Write(FILE* to) 254{ 255 this->expression->Write(to); 256 fprintf(to, ";\n"); 257} 258 259Assignment::Assignment(Variable* l, Expression* r) 260 :lvalue(l), 261 rvalue(r), 262 cast(NULL) 263{ 264} 265 266Assignment::Assignment(Variable* l, Expression* r, Type* c) 267 :lvalue(l), 268 rvalue(r), 269 cast(c) 270{ 271} 272 273Assignment::~Assignment() 274{ 275} 276 277void 278Assignment::Write(FILE* to) 279{ 280 this->lvalue->Write(to); 281 fprintf(to, " = "); 282 if (this->cast != NULL) { 283 fprintf(to, "(%s)", this->cast->QualifiedName().c_str()); 284 } 285 this->rvalue->Write(to); 286} 287 288MethodCall::MethodCall(const string& n) 289 :obj(NULL), 290 clazz(NULL), 291 name(n) 292{ 293} 294 295MethodCall::MethodCall(const string& n, int argc = 0, ...) 296 :obj(NULL), 297 clazz(NULL), 298 name(n) 299{ 300 va_list args; 301 va_start(args, argc); 302 init(argc, args); 303 va_end(args); 304} 305 306MethodCall::MethodCall(Expression* o, const string& n) 307 :obj(o), 308 clazz(NULL), 309 name(n) 310{ 311} 312 313MethodCall::MethodCall(Type* t, const string& n) 314 :obj(NULL), 315 clazz(t), 316 name(n) 317{ 318} 319 320MethodCall::MethodCall(Expression* o, const string& n, int argc = 0, ...) 321 :obj(o), 322 clazz(NULL), 323 name(n) 324{ 325 va_list args; 326 va_start(args, argc); 327 init(argc, args); 328 va_end(args); 329} 330 331MethodCall::MethodCall(Type* t, const string& n, int argc = 0, ...) 332 :obj(NULL), 333 clazz(t), 334 name(n) 335{ 336 va_list args; 337 va_start(args, argc); 338 init(argc, args); 339 va_end(args); 340} 341 342MethodCall::~MethodCall() 343{ 344} 345 346void 347MethodCall::init(int n, va_list args) 348{ 349 for (int i=0; i<n; i++) { 350 Expression* expression = (Expression*)va_arg(args, void*); 351 this->arguments.push_back(expression); 352 } 353} 354 355void 356MethodCall::Write(FILE* to) 357{ 358 if (this->obj != NULL) { 359 this->obj->Write(to); 360 fprintf(to, "."); 361 } 362 else if (this->clazz != NULL) { 363 fprintf(to, "%s.", this->clazz->QualifiedName().c_str()); 364 } 365 fprintf(to, "%s(", this->name.c_str()); 366 WriteArgumentList(to, this->arguments); 367 fprintf(to, ")"); 368} 369 370Comparison::Comparison(Expression* l, const string& o, Expression* r) 371 :lvalue(l), 372 op(o), 373 rvalue(r) 374{ 375} 376 377Comparison::~Comparison() 378{ 379} 380 381void 382Comparison::Write(FILE* to) 383{ 384 fprintf(to, "("); 385 this->lvalue->Write(to); 386 fprintf(to, "%s", this->op.c_str()); 387 this->rvalue->Write(to); 388 fprintf(to, ")"); 389} 390 391NewExpression::NewExpression(Type* t) 392 :type(t) 393{ 394} 395 396NewExpression::NewExpression(Type* t, int argc = 0, ...) 397 :type(t) 398{ 399 va_list args; 400 va_start(args, argc); 401 init(argc, args); 402 va_end(args); 403} 404 405NewExpression::~NewExpression() 406{ 407} 408 409void 410NewExpression::init(int n, va_list args) 411{ 412 for (int i=0; i<n; i++) { 413 Expression* expression = (Expression*)va_arg(args, void*); 414 this->arguments.push_back(expression); 415 } 416} 417 418void 419NewExpression::Write(FILE* to) 420{ 421 fprintf(to, "new %s(", this->type->InstantiableName().c_str()); 422 WriteArgumentList(to, this->arguments); 423 fprintf(to, ")"); 424} 425 426NewArrayExpression::NewArrayExpression(Type* t, Expression* s) 427 :type(t), 428 size(s) 429{ 430} 431 432NewArrayExpression::~NewArrayExpression() 433{ 434} 435 436void 437NewArrayExpression::Write(FILE* to) 438{ 439 fprintf(to, "new %s[", this->type->QualifiedName().c_str()); 440 size->Write(to); 441 fprintf(to, "]"); 442} 443 444Ternary::Ternary() 445 :condition(NULL), 446 ifpart(NULL), 447 elsepart(NULL) 448{ 449} 450 451Ternary::Ternary(Expression* a, Expression* b, Expression* c) 452 :condition(a), 453 ifpart(b), 454 elsepart(c) 455{ 456} 457 458Ternary::~Ternary() 459{ 460} 461 462void 463Ternary::Write(FILE* to) 464{ 465 fprintf(to, "(("); 466 this->condition->Write(to); 467 fprintf(to, ")?("); 468 this->ifpart->Write(to); 469 fprintf(to, "):("); 470 this->elsepart->Write(to); 471 fprintf(to, "))"); 472} 473 474Cast::Cast() 475 :type(NULL), 476 expression(NULL) 477{ 478} 479 480Cast::Cast(Type* t, Expression* e) 481 :type(t), 482 expression(e) 483{ 484} 485 486Cast::~Cast() 487{ 488} 489 490void 491Cast::Write(FILE* to) 492{ 493 fprintf(to, "((%s)", this->type->QualifiedName().c_str()); 494 expression->Write(to); 495 fprintf(to, ")"); 496} 497 498VariableDeclaration::VariableDeclaration(Variable* l, Expression* r, Type* c) 499 :lvalue(l), 500 cast(c), 501 rvalue(r) 502{ 503} 504 505VariableDeclaration::VariableDeclaration(Variable* l) 506 :lvalue(l), 507 cast(NULL), 508 rvalue(NULL) 509{ 510} 511 512VariableDeclaration::~VariableDeclaration() 513{ 514} 515 516void 517VariableDeclaration::Write(FILE* to) 518{ 519 this->lvalue->WriteDeclaration(to); 520 if (this->rvalue != NULL) { 521 fprintf(to, " = "); 522 if (this->cast != NULL) { 523 fprintf(to, "(%s)", this->cast->QualifiedName().c_str()); 524 } 525 this->rvalue->Write(to); 526 } 527 fprintf(to, ";\n"); 528} 529 530IfStatement::IfStatement() 531 :expression(NULL), 532 statements(new StatementBlock), 533 elseif(NULL) 534{ 535} 536 537IfStatement::~IfStatement() 538{ 539} 540 541void 542IfStatement::Write(FILE* to) 543{ 544 if (this->expression != NULL) { 545 fprintf(to, "if ("); 546 this->expression->Write(to); 547 fprintf(to, ") "); 548 } 549 this->statements->Write(to); 550 if (this->elseif != NULL) { 551 fprintf(to, "else "); 552 this->elseif->Write(to); 553 } 554} 555 556ReturnStatement::ReturnStatement(Expression* e) 557 :expression(e) 558{ 559} 560 561ReturnStatement::~ReturnStatement() 562{ 563} 564 565void 566ReturnStatement::Write(FILE* to) 567{ 568 fprintf(to, "return "); 569 this->expression->Write(to); 570 fprintf(to, ";\n"); 571} 572 573TryStatement::TryStatement() 574 :statements(new StatementBlock) 575{ 576} 577 578TryStatement::~TryStatement() 579{ 580} 581 582void 583TryStatement::Write(FILE* to) 584{ 585 fprintf(to, "try "); 586 this->statements->Write(to); 587} 588 589CatchStatement::CatchStatement(Variable* e) 590 :statements(new StatementBlock), 591 exception(e) 592{ 593} 594 595CatchStatement::~CatchStatement() 596{ 597} 598 599void 600CatchStatement::Write(FILE* to) 601{ 602 fprintf(to, "catch "); 603 if (this->exception != NULL) { 604 fprintf(to, "("); 605 this->exception->WriteDeclaration(to); 606 fprintf(to, ") "); 607 } 608 this->statements->Write(to); 609} 610 611FinallyStatement::FinallyStatement() 612 :statements(new StatementBlock) 613{ 614} 615 616FinallyStatement::~FinallyStatement() 617{ 618} 619 620void 621FinallyStatement::Write(FILE* to) 622{ 623 fprintf(to, "finally "); 624 this->statements->Write(to); 625} 626 627Case::Case() 628 :statements(new StatementBlock) 629{ 630} 631 632Case::Case(const string& c) 633 :statements(new StatementBlock) 634{ 635 cases.push_back(c); 636} 637 638Case::~Case() 639{ 640} 641 642void 643Case::Write(FILE* to) 644{ 645 int N = this->cases.size(); 646 if (N > 0) { 647 for (int i=0; i<N; i++) { 648 string s = this->cases[i]; 649 if (s.length() != 0) { 650 fprintf(to, "case %s:\n", s.c_str()); 651 } else { 652 fprintf(to, "default:\n"); 653 } 654 } 655 } else { 656 fprintf(to, "default:\n"); 657 } 658 statements->Write(to); 659} 660 661SwitchStatement::SwitchStatement(Expression* e) 662 :expression(e) 663{ 664} 665 666SwitchStatement::~SwitchStatement() 667{ 668} 669 670void 671SwitchStatement::Write(FILE* to) 672{ 673 fprintf(to, "switch ("); 674 this->expression->Write(to); 675 fprintf(to, ")\n{\n"); 676 int N = this->cases.size(); 677 for (int i=0; i<N; i++) { 678 this->cases[i]->Write(to); 679 } 680 fprintf(to, "}\n"); 681} 682 683Break::Break() 684{ 685} 686 687Break::~Break() 688{ 689} 690 691void 692Break::Write(FILE* to) 693{ 694 fprintf(to, "break;\n"); 695} 696 697Method::Method() 698 :ClassElement(), 699 modifiers(0), 700 returnType(NULL), // (NULL means constructor) 701 returnTypeDimension(0), 702 statements(NULL) 703{ 704} 705 706Method::~Method() 707{ 708} 709 710void 711Method::GatherTypes(set<Type*>* types) const 712{ 713 size_t N, i; 714 715 if (this->returnType) { 716 types->insert(this->returnType); 717 } 718 719 N = this->parameters.size(); 720 for (i=0; i<N; i++) { 721 this->parameters[i]->GatherTypes(types); 722 } 723 724 N = this->exceptions.size(); 725 for (i=0; i<N; i++) { 726 types->insert(this->exceptions[i]); 727 } 728} 729 730void 731Method::Write(FILE* to) 732{ 733 size_t N, i; 734 735 if (this->comment.length() != 0) { 736 fprintf(to, "%s\n", this->comment.c_str()); 737 } 738 739 WriteModifiers(to, this->modifiers, SCOPE_MASK | STATIC | ABSTRACT | FINAL | OVERRIDE); 740 741 if (this->returnType != NULL) { 742 string dim; 743 for (i=0; i<this->returnTypeDimension; i++) { 744 dim += "[]"; 745 } 746 fprintf(to, "%s%s ", this->returnType->QualifiedName().c_str(), 747 dim.c_str()); 748 } 749 750 fprintf(to, "%s(", this->name.c_str()); 751 752 N = this->parameters.size(); 753 for (i=0; i<N; i++) { 754 this->parameters[i]->WriteDeclaration(to); 755 if (i != N-1) { 756 fprintf(to, ", "); 757 } 758 } 759 760 fprintf(to, ")"); 761 762 N = this->exceptions.size(); 763 for (i=0; i<N; i++) { 764 if (i == 0) { 765 fprintf(to, " throws "); 766 } else { 767 fprintf(to, ", "); 768 } 769 fprintf(to, "%s", this->exceptions[i]->QualifiedName().c_str()); 770 } 771 772 if (this->statements == NULL) { 773 fprintf(to, ";\n"); 774 } else { 775 fprintf(to, "\n"); 776 this->statements->Write(to); 777 } 778} 779 780Class::Class() 781 :modifiers(0), 782 what(CLASS), 783 type(NULL), 784 extends(NULL) 785{ 786} 787 788Class::~Class() 789{ 790} 791 792void 793Class::GatherTypes(set<Type*>* types) const 794{ 795 int N, i; 796 797 types->insert(this->type); 798 if (this->extends != NULL) { 799 types->insert(this->extends); 800 } 801 802 N = this->interfaces.size(); 803 for (i=0; i<N; i++) { 804 types->insert(this->interfaces[i]); 805 } 806 807 N = this->elements.size(); 808 for (i=0; i<N; i++) { 809 this->elements[i]->GatherTypes(types); 810 } 811} 812 813void 814Class::Write(FILE* to) 815{ 816 size_t N, i; 817 818 if (this->comment.length() != 0) { 819 fprintf(to, "%s\n", this->comment.c_str()); 820 } 821 822 WriteModifiers(to, this->modifiers, ALL_MODIFIERS); 823 824 if (this->what == Class::CLASS) { 825 fprintf(to, "class "); 826 } else { 827 fprintf(to, "interface "); 828 } 829 830 string name = this->type->Name(); 831 size_t pos = name.rfind('.'); 832 if (pos != string::npos) { 833 name = name.c_str() + pos + 1; 834 } 835 836 fprintf(to, "%s", name.c_str()); 837 838 if (this->extends != NULL) { 839 fprintf(to, " extends %s", this->extends->QualifiedName().c_str()); 840 } 841 842 N = this->interfaces.size(); 843 if (N != 0) { 844 if (this->what == Class::CLASS) { 845 fprintf(to, " implements"); 846 } else { 847 fprintf(to, " extends"); 848 } 849 for (i=0; i<N; i++) { 850 fprintf(to, " %s", this->interfaces[i]->QualifiedName().c_str()); 851 } 852 } 853 854 fprintf(to, "\n"); 855 fprintf(to, "{\n"); 856 857 N = this->elements.size(); 858 for (i=0; i<N; i++) { 859 this->elements[i]->Write(to); 860 } 861 862 fprintf(to, "}\n"); 863 864} 865 866Document::Document() 867{ 868} 869 870Document::~Document() 871{ 872} 873 874static string 875escape_backslashes(const string& str) 876{ 877 string result; 878 const size_t I=str.length(); 879 for (size_t i=0; i<I; i++) { 880 char c = str[i]; 881 if (c == '\\') { 882 result += "\\\\"; 883 } else { 884 result += c; 885 } 886 } 887 return result; 888} 889 890void 891Document::Write(FILE* to) 892{ 893 size_t N, i; 894 895 if (this->comment.length() != 0) { 896 fprintf(to, "%s\n", this->comment.c_str()); 897 } 898 fprintf(to, "/*\n" 899 " * This file is auto-generated. DO NOT MODIFY.\n" 900 " * Original file: %s\n" 901 " */\n", escape_backslashes(this->originalSrc).c_str()); 902 if (this->package.length() != 0) { 903 fprintf(to, "package %s;\n", this->package.c_str()); 904 } 905 906 N = this->classes.size(); 907 for (i=0; i<N; i++) { 908 Class* c = this->classes[i]; 909 c->Write(to); 910 } 911} 912 913