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 114Variable::Variable() 115 :type(NULL), 116 name(), 117 dimension(0) 118{ 119} 120 121Variable::Variable(Type* t, const string& n) 122 :type(t), 123 name(n), 124 dimension(0) 125{ 126} 127 128Variable::Variable(Type* t, const string& n, int d) 129 :type(t), 130 name(n), 131 dimension(d) 132{ 133} 134 135Variable::~Variable() 136{ 137} 138 139void 140Variable::GatherTypes(set<Type*>* types) const 141{ 142 types->insert(this->type); 143} 144 145void 146Variable::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 156void 157Variable::Write(FILE* to) 158{ 159 fprintf(to, "%s", name.c_str()); 160} 161 162FieldVariable::FieldVariable(Expression* o, const string& n) 163 :object(o), 164 clazz(NULL), 165 name(n) 166{ 167} 168 169FieldVariable::FieldVariable(Type* c, const string& n) 170 :object(NULL), 171 clazz(c), 172 name(n) 173{ 174} 175 176FieldVariable::~FieldVariable() 177{ 178} 179 180void 181FieldVariable::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 193Statement::~Statement() 194{ 195} 196 197StatementBlock::StatementBlock() 198{ 199} 200 201StatementBlock::~StatementBlock() 202{ 203} 204 205void 206StatementBlock::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 216void 217StatementBlock::Add(Statement* statement) 218{ 219 this->statements.push_back(statement); 220} 221 222void 223StatementBlock::Add(Expression* expression) 224{ 225 this->statements.push_back(new ExpressionStatement(expression)); 226} 227 228ExpressionStatement::ExpressionStatement(Expression* e) 229 :expression(e) 230{ 231} 232 233ExpressionStatement::~ExpressionStatement() 234{ 235} 236 237void 238ExpressionStatement::Write(FILE* to) 239{ 240 this->expression->Write(to); 241 fprintf(to, ";\n"); 242} 243 244Assignment::Assignment(Variable* l, Expression* r) 245 :lvalue(l), 246 rvalue(r), 247 cast(NULL) 248{ 249} 250 251Assignment::Assignment(Variable* l, Expression* r, Type* c) 252 :lvalue(l), 253 rvalue(r), 254 cast(c) 255{ 256} 257 258Assignment::~Assignment() 259{ 260} 261 262void 263Assignment::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 273MethodCall::MethodCall(const string& n) 274 :obj(NULL), 275 clazz(NULL), 276 name(n) 277{ 278} 279 280MethodCall::MethodCall(Expression* o, const string& n) 281 :obj(o), 282 clazz(NULL), 283 name(n) 284{ 285} 286 287MethodCall::MethodCall(Type* t, const string& n) 288 :obj(NULL), 289 clazz(t), 290 name(n) 291{ 292} 293 294MethodCall::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 305MethodCall::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 316MethodCall::~MethodCall() 317{ 318} 319 320void 321MethodCall::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 329void 330MethodCall::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 344Comparison::Comparison(Expression* l, const string& o, Expression* r) 345 :lvalue(l), 346 op(o), 347 rvalue(r) 348{ 349} 350 351Comparison::~Comparison() 352{ 353} 354 355void 356Comparison::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 365NewExpression::NewExpression(Type* t) 366 :type(t) 367{ 368} 369 370NewExpression::~NewExpression() 371{ 372} 373 374void 375NewExpression::Write(FILE* to) 376{ 377 fprintf(to, "new %s(", this->type->InstantiableName().c_str()); 378 WriteArgumentList(to, this->arguments); 379 fprintf(to, ")"); 380} 381 382NewArrayExpression::NewArrayExpression(Type* t, Expression* s) 383 :type(t), 384 size(s) 385{ 386} 387 388NewArrayExpression::~NewArrayExpression() 389{ 390} 391 392void 393NewArrayExpression::Write(FILE* to) 394{ 395 fprintf(to, "new %s[", this->type->QualifiedName().c_str()); 396 size->Write(to); 397 fprintf(to, "]"); 398} 399 400Ternary::Ternary() 401 :condition(NULL), 402 ifpart(NULL), 403 elsepart(NULL) 404{ 405} 406 407Ternary::Ternary(Expression* a, Expression* b, Expression* c) 408 :condition(a), 409 ifpart(b), 410 elsepart(c) 411{ 412} 413 414Ternary::~Ternary() 415{ 416} 417 418void 419Ternary::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 430Cast::Cast() 431 :type(NULL), 432 expression(NULL) 433{ 434} 435 436Cast::Cast(Type* t, Expression* e) 437 :type(t), 438 expression(e) 439{ 440} 441 442Cast::~Cast() 443{ 444} 445 446void 447Cast::Write(FILE* to) 448{ 449 fprintf(to, "((%s)", this->type->QualifiedName().c_str()); 450 expression->Write(to); 451 fprintf(to, ")"); 452} 453 454VariableDeclaration::VariableDeclaration(Variable* l, Expression* r, Type* c) 455 :lvalue(l), 456 cast(c), 457 rvalue(r) 458{ 459} 460 461VariableDeclaration::VariableDeclaration(Variable* l) 462 :lvalue(l), 463 cast(NULL), 464 rvalue(NULL) 465{ 466} 467 468VariableDeclaration::~VariableDeclaration() 469{ 470} 471 472void 473VariableDeclaration::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 486IfStatement::IfStatement() 487 :expression(NULL), 488 statements(new StatementBlock), 489 elseif(NULL) 490{ 491} 492 493IfStatement::~IfStatement() 494{ 495} 496 497void 498IfStatement::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 512ReturnStatement::ReturnStatement(Expression* e) 513 :expression(e) 514{ 515} 516 517ReturnStatement::~ReturnStatement() 518{ 519} 520 521void 522ReturnStatement::Write(FILE* to) 523{ 524 fprintf(to, "return "); 525 this->expression->Write(to); 526 fprintf(to, ";\n"); 527} 528 529TryStatement::TryStatement() 530 :statements(new StatementBlock) 531{ 532} 533 534TryStatement::~TryStatement() 535{ 536} 537 538void 539TryStatement::Write(FILE* to) 540{ 541 fprintf(to, "try "); 542 this->statements->Write(to); 543} 544 545CatchStatement::CatchStatement(Variable* e) 546 :statements(new StatementBlock), 547 exception(e) 548{ 549} 550 551CatchStatement::~CatchStatement() 552{ 553} 554 555void 556CatchStatement::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 567FinallyStatement::FinallyStatement() 568 :statements(new StatementBlock) 569{ 570} 571 572FinallyStatement::~FinallyStatement() 573{ 574} 575 576void 577FinallyStatement::Write(FILE* to) 578{ 579 fprintf(to, "finally "); 580 this->statements->Write(to); 581} 582 583Case::Case() 584 :statements(new StatementBlock) 585{ 586} 587 588Case::Case(const string& c) 589 :statements(new StatementBlock) 590{ 591 cases.push_back(c); 592} 593 594Case::~Case() 595{ 596} 597 598void 599Case::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 617SwitchStatement::SwitchStatement(Expression* e) 618 :expression(e) 619{ 620} 621 622SwitchStatement::~SwitchStatement() 623{ 624} 625 626void 627SwitchStatement::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 639Method::Method() 640 :ClassElement(), 641 modifiers(0), 642 returnType(NULL), // (NULL means constructor) 643 returnTypeDimension(0), 644 statements(NULL) 645{ 646} 647 648Method::~Method() 649{ 650} 651 652void 653Method::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 672void 673Method::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 722Class::Class() 723 :modifiers(0), 724 what(CLASS), 725 type(NULL), 726 extends(NULL) 727{ 728} 729 730Class::~Class() 731{ 732} 733 734void 735Class::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 755void 756Class::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 808Document::Document() 809{ 810} 811 812Document::~Document() 813{ 814} 815 816static string 817escape_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 832void 833Document::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