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