blob: bfa67656b32329e956014a26babf87a9e9e32ec7 [file] [log] [blame]
Adam Lesinski282e1812014-01-23 18:17:42 -08001#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