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