1 #include "AST.h" 2 #include "Type.h" 3 4 void 5 WriteModifiers(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 36 void 37 WriteArgumentList(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 48 ClassElement::ClassElement() 49 { 50 } 51 52 ClassElement::~ClassElement() 53 { 54 } 55 56 Field::Field() 57 :ClassElement(), 58 modifiers(0), 59 variable(NULL) 60 { 61 } 62 63 Field::Field(int m, Variable* v) 64 :ClassElement(), 65 modifiers(m), 66 variable(v) 67 { 68 } 69 70 Field::~Field() 71 { 72 } 73 74 void 75 Field::GatherTypes(set<Type*>* types) const 76 { 77 types->insert(this->variable->type); 78 } 79 80 void 81 Field::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 95 Expression::~Expression() 96 { 97 } 98 99 LiteralExpression::LiteralExpression(const string& v) 100 :value(v) 101 { 102 } 103 104 LiteralExpression::~LiteralExpression() 105 { 106 } 107 108 void 109 LiteralExpression::Write(FILE* to) 110 { 111 fprintf(to, "%s", this->value.c_str()); 112 } 113 114 StringLiteralExpression::StringLiteralExpression(const string& v) 115 :value(v) 116 { 117 } 118 119 StringLiteralExpression::~StringLiteralExpression() 120 { 121 } 122 123 void 124 StringLiteralExpression::Write(FILE* to) 125 { 126 fprintf(to, "\"%s\"", this->value.c_str()); 127 } 128 129 Variable::Variable() 130 :type(NULL), 131 name(), 132 dimension(0) 133 { 134 } 135 136 Variable::Variable(Type* t, const string& n) 137 :type(t), 138 name(n), 139 dimension(0) 140 { 141 } 142 143 Variable::Variable(Type* t, const string& n, int d) 144 :type(t), 145 name(n), 146 dimension(d) 147 { 148 } 149 150 Variable::~Variable() 151 { 152 } 153 154 void 155 Variable::GatherTypes(set<Type*>* types) const 156 { 157 types->insert(this->type); 158 } 159 160 void 161 Variable::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 171 void 172 Variable::Write(FILE* to) 173 { 174 fprintf(to, "%s", name.c_str()); 175 } 176 177 FieldVariable::FieldVariable(Expression* o, const string& n) 178 :object(o), 179 clazz(NULL), 180 name(n) 181 { 182 } 183 184 FieldVariable::FieldVariable(Type* c, const string& n) 185 :object(NULL), 186 clazz(c), 187 name(n) 188 { 189 } 190 191 FieldVariable::~FieldVariable() 192 { 193 } 194 195 void 196 FieldVariable::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 208 Statement::~Statement() 209 { 210 } 211 212 StatementBlock::StatementBlock() 213 { 214 } 215 216 StatementBlock::~StatementBlock() 217 { 218 } 219 220 void 221 StatementBlock::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 231 void 232 StatementBlock::Add(Statement* statement) 233 { 234 this->statements.push_back(statement); 235 } 236 237 void 238 StatementBlock::Add(Expression* expression) 239 { 240 this->statements.push_back(new ExpressionStatement(expression)); 241 } 242 243 ExpressionStatement::ExpressionStatement(Expression* e) 244 :expression(e) 245 { 246 } 247 248 ExpressionStatement::~ExpressionStatement() 249 { 250 } 251 252 void 253 ExpressionStatement::Write(FILE* to) 254 { 255 this->expression->Write(to); 256 fprintf(to, ";\n"); 257 } 258 259 Assignment::Assignment(Variable* l, Expression* r) 260 :lvalue(l), 261 rvalue(r), 262 cast(NULL) 263 { 264 } 265 266 Assignment::Assignment(Variable* l, Expression* r, Type* c) 267 :lvalue(l), 268 rvalue(r), 269 cast(c) 270 { 271 } 272 273 Assignment::~Assignment() 274 { 275 } 276 277 void 278 Assignment::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 288 MethodCall::MethodCall(const string& n) 289 :obj(NULL), 290 clazz(NULL), 291 name(n) 292 { 293 } 294 295 MethodCall::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 306 MethodCall::MethodCall(Expression* o, const string& n) 307 :obj(o), 308 clazz(NULL), 309 name(n) 310 { 311 } 312 313 MethodCall::MethodCall(Type* t, const string& n) 314 :obj(NULL), 315 clazz(t), 316 name(n) 317 { 318 } 319 320 MethodCall::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 331 MethodCall::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 342 MethodCall::~MethodCall() 343 { 344 } 345 346 void 347 MethodCall::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 355 void 356 MethodCall::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 370 Comparison::Comparison(Expression* l, const string& o, Expression* r) 371 :lvalue(l), 372 op(o), 373 rvalue(r) 374 { 375 } 376 377 Comparison::~Comparison() 378 { 379 } 380 381 void 382 Comparison::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 391 NewExpression::NewExpression(Type* t) 392 :type(t) 393 { 394 } 395 396 NewExpression::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 405 NewExpression::~NewExpression() 406 { 407 } 408 409 void 410 NewExpression::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 418 void 419 NewExpression::Write(FILE* to) 420 { 421 fprintf(to, "new %s(", this->type->InstantiableName().c_str()); 422 WriteArgumentList(to, this->arguments); 423 fprintf(to, ")"); 424 } 425 426 NewArrayExpression::NewArrayExpression(Type* t, Expression* s) 427 :type(t), 428 size(s) 429 { 430 } 431 432 NewArrayExpression::~NewArrayExpression() 433 { 434 } 435 436 void 437 NewArrayExpression::Write(FILE* to) 438 { 439 fprintf(to, "new %s[", this->type->QualifiedName().c_str()); 440 size->Write(to); 441 fprintf(to, "]"); 442 } 443 444 Ternary::Ternary() 445 :condition(NULL), 446 ifpart(NULL), 447 elsepart(NULL) 448 { 449 } 450 451 Ternary::Ternary(Expression* a, Expression* b, Expression* c) 452 :condition(a), 453 ifpart(b), 454 elsepart(c) 455 { 456 } 457 458 Ternary::~Ternary() 459 { 460 } 461 462 void 463 Ternary::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 474 Cast::Cast() 475 :type(NULL), 476 expression(NULL) 477 { 478 } 479 480 Cast::Cast(Type* t, Expression* e) 481 :type(t), 482 expression(e) 483 { 484 } 485 486 Cast::~Cast() 487 { 488 } 489 490 void 491 Cast::Write(FILE* to) 492 { 493 fprintf(to, "((%s)", this->type->QualifiedName().c_str()); 494 expression->Write(to); 495 fprintf(to, ")"); 496 } 497 498 VariableDeclaration::VariableDeclaration(Variable* l, Expression* r, Type* c) 499 :lvalue(l), 500 cast(c), 501 rvalue(r) 502 { 503 } 504 505 VariableDeclaration::VariableDeclaration(Variable* l) 506 :lvalue(l), 507 cast(NULL), 508 rvalue(NULL) 509 { 510 } 511 512 VariableDeclaration::~VariableDeclaration() 513 { 514 } 515 516 void 517 VariableDeclaration::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 530 IfStatement::IfStatement() 531 :expression(NULL), 532 statements(new StatementBlock), 533 elseif(NULL) 534 { 535 } 536 537 IfStatement::~IfStatement() 538 { 539 } 540 541 void 542 IfStatement::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 556 ReturnStatement::ReturnStatement(Expression* e) 557 :expression(e) 558 { 559 } 560 561 ReturnStatement::~ReturnStatement() 562 { 563 } 564 565 void 566 ReturnStatement::Write(FILE* to) 567 { 568 fprintf(to, "return "); 569 this->expression->Write(to); 570 fprintf(to, ";\n"); 571 } 572 573 TryStatement::TryStatement() 574 :statements(new StatementBlock) 575 { 576 } 577 578 TryStatement::~TryStatement() 579 { 580 } 581 582 void 583 TryStatement::Write(FILE* to) 584 { 585 fprintf(to, "try "); 586 this->statements->Write(to); 587 } 588 589 CatchStatement::CatchStatement(Variable* e) 590 :statements(new StatementBlock), 591 exception(e) 592 { 593 } 594 595 CatchStatement::~CatchStatement() 596 { 597 } 598 599 void 600 CatchStatement::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 611 FinallyStatement::FinallyStatement() 612 :statements(new StatementBlock) 613 { 614 } 615 616 FinallyStatement::~FinallyStatement() 617 { 618 } 619 620 void 621 FinallyStatement::Write(FILE* to) 622 { 623 fprintf(to, "finally "); 624 this->statements->Write(to); 625 } 626 627 Case::Case() 628 :statements(new StatementBlock) 629 { 630 } 631 632 Case::Case(const string& c) 633 :statements(new StatementBlock) 634 { 635 cases.push_back(c); 636 } 637 638 Case::~Case() 639 { 640 } 641 642 void 643 Case::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 661 SwitchStatement::SwitchStatement(Expression* e) 662 :expression(e) 663 { 664 } 665 666 SwitchStatement::~SwitchStatement() 667 { 668 } 669 670 void 671 SwitchStatement::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 683 Break::Break() 684 { 685 } 686 687 Break::~Break() 688 { 689 } 690 691 void 692 Break::Write(FILE* to) 693 { 694 fprintf(to, "break;\n"); 695 } 696 697 Method::Method() 698 :ClassElement(), 699 modifiers(0), 700 returnType(NULL), // (NULL means constructor) 701 returnTypeDimension(0), 702 statements(NULL) 703 { 704 } 705 706 Method::~Method() 707 { 708 } 709 710 void 711 Method::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 730 void 731 Method::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 780 Class::Class() 781 :modifiers(0), 782 what(CLASS), 783 type(NULL), 784 extends(NULL) 785 { 786 } 787 788 Class::~Class() 789 { 790 } 791 792 void 793 Class::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 813 void 814 Class::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 866 Document::Document() 867 { 868 } 869 870 Document::~Document() 871 { 872 } 873 874 static string 875 escape_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 890 void 891 Document::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