1 package net.sourceforge.jenesis4java.impl;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 import net.sourceforge.jenesis4java.*;
41 import net.sourceforge.jenesis4java.impl.util.ListTypeSelector;
42 import net.sourceforge.jenesis4java.impl.util.VisitorUtils;
43
44 import java.util.ArrayList;
45 import java.util.Comparator;
46 import java.util.List;
47
48 import static net.sourceforge.jenesis4java.Style.METHOD_INVOCATION_ON_NEW_LINE;
49
50
51
52
53 public abstract class MExpression extends MVM.MCodeable implements Expression {
54
55 private boolean forcedNewlineAfterExpression = false;
56
57
58
59
60 static class MAccessor extends MExpression implements Accessor {
61
62 String name;
63
64 String qual;
65
66 Expression qualExpression;
67
68 Expression nameExpression;
69
70 public MAccessor(MVM vm, String qual, String name) {
71 super(vm);
72 this.qual = qual;
73 qualExpression = null;
74 this.name = name;
75 nameExpression = null;
76 }
77
78 MAccessor(MVM vm) {
79 super(vm);
80 }
81
82 MAccessor(MVM vm, Expression qual, String name) {
83 super(vm);
84 this.qual = null;
85 qualExpression = qual;
86 this.name = name;
87 }
88
89 MAccessor(MVM vm, Expression qual, Expression name) {
90 super(vm);
91 this.qual = null;
92 qualExpression = qual;
93 nameExpression = name;
94 }
95
96 @Override
97 public String getName() {
98 return name;
99 }
100
101 @Override
102 public Expression getQualExpression() {
103 return qualExpression;
104 }
105
106 @Override
107 public String getQualifier() {
108 return qual;
109 }
110
111 @Override
112 public Type getType() {
113 return null;
114 }
115
116 @Override
117 public MAccessor setName(String name) {
118 this.name = name;
119 return this;
120 }
121
122 @Override
123 public MAccessor setQualifier(String qual) {
124 this.qual = qual;
125 return this;
126 }
127
128 @Override
129 public CodeWriter toCode2(CodeWriter out) {
130 super.toCode2(out);
131 if (qual != null) {
132 out.write(qual).write('.');
133 } else if (qualExpression != null) {
134 out.write(qualExpression).write('.');
135 }
136 if (name != null) {
137 out.write(name);
138 } else if (nameExpression != null) {
139 out.write(nameExpression).write('.');
140 }
141 return out;
142 }
143
144 @Override
145 public void visit(ReplacingVisitor visitor) {
146 super.visit(visitor);
147 qualExpression = VisitorUtils.visit(qualExpression, this, visitor);
148 nameExpression = VisitorUtils.visit(nameExpression, this, visitor);
149 }
150 }
151
152
153
154
155 static class MArrayAccess extends MAccessor implements ArrayAccess {
156
157 List<Expression> dimensions = new ArrayList<>();
158
159 MArrayAccess(MVM vm, Expression qual, String name) {
160 super(vm, qual, name);
161 }
162
163 MArrayAccess(MVM vm, String qual, String name) {
164 super(vm, qual, name);
165 }
166
167 @Override
168 public ArrayAccess addDim(Expression expr) {
169 dimensions.add(expr);
170 return this;
171 }
172
173 @Override
174 public List<Expression> getDims() {
175 return ListTypeSelector.select(dimensions);
176 }
177
178 @Override
179 public CodeWriter toCode2(CodeWriter out) {
180 super.toCode2(out);
181
182 for (Expression dimension : dimensions) {
183 out.write('[').write(dimension).write(']');
184 }
185
186 return out;
187 }
188
189 @Override
190 public void visit(ReplacingVisitor visitor) {
191 super.visit(visitor);
192 VisitorUtils.visit(dimensions, this, visitor);
193 }
194 }
195
196
197
198
199 static class MArrayInitializer extends MExpression implements ArrayInitializer {
200
201 Object o;
202
203 MArrayInitializer(MVM vm, Object o) {
204 super(vm);
205 this.o = o;
206 }
207
208 @Override
209 public Object getArgs() {
210 return o;
211 }
212
213 @Override
214 public Type getType() {
215 return null;
216 }
217
218 @Override
219 public MArrayInitializer setArgs(Object o) {
220 this.o = o;
221 return this;
222 }
223
224 @Override
225 public CodeWriter toCode2(CodeWriter out) {
226 super.toCode2(out);
227
228
229 if (o == null) {
230 out.write("{}");
231 } else if (o instanceof Object[]) {
232 Object[] ao = (Object[]) o;
233 if (ao.length == 0) {
234 out.write("{}");
235 } else {
236 writeElements(ao, out);
237 }
238
239
240
241
242 } else if (o instanceof Expression) {
243 out.write("{ ").write(o).write(" }");
244 }
245
246 return out;
247 }
248
249 @Override
250 public void visit(ReplacingVisitor visitor) {
251 super.visit(visitor);
252 o = VisitorUtils.visit(o, this, visitor);
253 }
254
255 void writeElement(Object o, CodeWriter out, boolean isNotFirst) {
256 if (o instanceof Object[]) {
257 if (isNotFirst) {
258 out.write(", ");
259 }
260 writeElements((Object[]) o, out);
261 } else if (o instanceof Expression) {
262 if (isNotFirst) {
263 out.write(", ");
264 }
265 out.write(o);
266 }
267 }
268
269 void writeElements(Object[] ao, CodeWriter out) {
270 out.write('{');
271
272
273
274 for (int i = 0; i < ao.length; i++) {
275 writeElement(ao[i], out, i > 0);
276 }
277
278 out.write('}');
279 }
280 }
281
282
283
284
285 static class MAssign extends MBinary implements Assign {
286
287 MAssign(MVM vm, int type, Variable l, Expression r) {
288 super(vm, type, l, r);
289 }
290
291 @Override
292 public Variable getVariable() {
293 return (Variable) super.getLValue();
294 }
295
296 @Override
297 public MAssign setVariable(Variable v) {
298 super.setLValue(v);
299 return this;
300 }
301
302 @Override
303 public CodeWriter toCode2(CodeWriter out) {
304 switch (type) {
305 case Assign.S:
306 out.write(l).write(" = ").write(r);
307 break;
308 case Binary.BINARY_AND:
309 out.write(l).write(" &= ").write(r);
310 break;
311 case Binary.BINARY_OR:
312 out.write(l).write(" |= ").write(r);
313 break;
314 case Binary.XOR:
315 out.write(l).write(" ^= ").write(r);
316 break;
317 case Binary.LEFT:
318 out.write(l).write(" <<= ").write(r);
319 break;
320 case Binary.RIGHT:
321 out.write(l).write(" >>= ").write(r);
322 break;
323 case Binary.UNSIGNED:
324 out.write(l).write(" >>>= ").write(r);
325 break;
326 case Binary.SUB:
327 out.write(l).write(" -= ").write(r);
328 break;
329 case Binary.MUL:
330 out.write(l).write(" *= ").write(r);
331 break;
332 case Binary.DIV:
333 out.write(l).write(" /= ").write(r);
334 break;
335 case Binary.MOD:
336 out.write(l).write(" %= ").write(r);
337 break;
338 case Binary.ADD:
339 case Binary.CAT:
340 out.write(l).write(" += ").write(r);
341 break;
342 default:
343 throw new RuntimeException("Please use a constant from the Assign interface when making new Assignment expressions.");
344 }
345 return out;
346 }
347
348 @Override
349 public int type() {
350 return type;
351 }
352 }
353
354
355
356
357 static class MBinary extends MExpression implements Binary {
358
359 final int type;
360
361 Expression l;
362
363 Expression r;
364
365 MBinary(MVM vm, int type, Expression l, Expression r) {
366 super(vm);
367 this.type = type;
368 this.l = l;
369 this.r = r;
370 }
371
372 @Override
373 public Expression getLValue() {
374 return l;
375 }
376
377 @Override
378 public Expression getRValue() {
379 return r;
380 }
381
382 @Override
383 public Type getType() {
384 return l.getType();
385 }
386
387 @Override
388 public MBinary setLValue(Expression l) {
389 this.l = l;
390 return this;
391 }
392
393 @Override
394 public MBinary setRValue(Expression r) {
395 this.r = r;
396 return this;
397 }
398
399 @Override
400 public CodeWriter toCode2(CodeWriter out) {
401 super.toCode2(out);
402
403 switch (type) {
404 case Binary.AND:
405 out.write(l).write(" && ").write(r);
406 break;
407 case Binary.OR:
408 out.write(l).write(" || ").write(r);
409 break;
410 case Binary.BINARY_AND:
411 out.write(l).write(" & ").write(r);
412 break;
413 case Binary.BINARY_OR:
414 out.write(l).write(" | ").write(r);
415 break;
416 case Binary.XOR:
417 out.write(l).write(" ^ ").write(r);
418 break;
419 case Binary.LEFT:
420 out.write(l).write(" << ").write(r);
421 break;
422 case Binary.RIGHT:
423 out.write(l).write(" >> ").write(r);
424 break;
425 case Binary.UNSIGNED:
426 out.write(l).write(" >>> ").write(r);
427 break;
428 case Binary.SUB:
429 out.write(l).write(" - ").write(r);
430 break;
431 case Binary.MUL:
432 out.write(l).write(" * ").write(r);
433 break;
434 case Binary.DIV:
435 out.write(l).write(" / ").write(r);
436 break;
437 case Binary.MOD:
438 out.write(l).write(" % ").write(r);
439 break;
440 case Binary.EQUAL_TO:
441 out.write(l).write(" == ").write(r);
442 break;
443 case Binary.NOT_EQUAL:
444 out.write(l).write(" != ").write(r);
445 break;
446 case Binary.GREATER:
447 out.write(l).write(" > ").write(r);
448 break;
449 case Binary.GREATER_EQUAL:
450 out.write(l).write(" >= ").write(r);
451 break;
452 case Binary.LESS:
453 out.write(l).write(" < ").write(r);
454 break;
455 case Binary.LESS_EQUAL:
456 out.write(l).write(" <= ").write(r);
457 break;
458 case Binary.INSTANCE_OF:
459 out.write(l).write(" instanceof ").write(r);
460 break;
461 case Binary.ASSIGN:
462 out.write(l).write(" = ").write(r);
463 break;
464 case Binary.ADD:
465 case Binary.CAT:
466 out.write(l).write(" + ").write(r);
467 break;
468 default:
469 throw new RuntimeException("Please use a constant from the Binary interface when making new binary expressions.");
470 }
471 return out;
472 }
473
474 @Override
475 public int type() {
476 return type;
477 }
478
479 @Override
480 public void visit(ReplacingVisitor visitor) {
481 super.visit(visitor);
482 l = VisitorUtils.visit(l, this, visitor);
483 r = VisitorUtils.visit(r, this, visitor);
484 }
485 }
486
487
488
489
490 static class MBlank extends MExpression implements Blank {
491
492 MBlank(MVM vm) {
493 super(vm);
494 }
495
496 @Override
497 public Type getType() {
498 return null;
499 }
500
501 @Override
502 public CodeWriter toCode2(CodeWriter out) {
503 return out;
504 }
505 }
506
507
508
509
510 static class MCast extends MExpression implements Cast {
511
512 Type type;
513
514 Expression val;
515
516 MCast(MVM vm, Type type, Expression val) {
517 super(vm);
518 this.type = type;
519 this.val = val;
520 }
521
522 @Override
523 public Expression getExpression() {
524 return val;
525 }
526
527 @Override
528 public Type getType() {
529 return type;
530 }
531
532 @Override
533 public MCast setExpression(Expression val) {
534 this.val = val;
535 return this;
536 }
537
538 @Override
539 public CodeWriter toCode2(CodeWriter out) {
540 super.toCode2(out);
541 if (type == null) {
542 out.write('(').write(val).write(')');
543 } else {
544 out.write('(').write('(').write(type).write(')').write(val).write(')');
545 }
546 return out;
547 }
548
549 @Override
550 public void visit(ReplacingVisitor visitor) {
551 super.visit(visitor);
552 type = VisitorUtils.visit(type, this, visitor);
553 val = VisitorUtils.visit(val, this, visitor);
554 }
555 }
556
557
558
559
560 static class MFieldAccess extends MAccessor implements FieldAccess {
561
562 MFieldAccess(MVM vm, Expression qual, String name) {
563 super(vm, qual, name);
564 }
565
566 MFieldAccess(MVM vm, String qual, String name) {
567 super(vm, qual, name);
568 }
569 }
570
571
572
573
574 static class MFreeform extends MExpression implements Freeform {
575
576
577 java.io.StringWriter buf;
578
579 java.io.PrintWriter out;
580
581 int colNo;
582
583 int lineNo;
584
585 int indentNo;
586
587 boolean isLineNew;
588
589 MFreeform(MVM vm) {
590 super(vm);
591 init();
592 }
593
594 MFreeform(MVM vm, String code) {
595 this(vm);
596 write(code);
597 }
598
599 @Override
600 public Freeform dedentLine() {
601 indentNo--;
602 newLine();
603 return this;
604 }
605
606 @Override
607 public String getCode() {
608 return buf.toString();
609 }
610
611 public int getColumnNumber() {
612 return colNo;
613 }
614
615 @Override
616 public int getIndentNumber() {
617 return indentNo;
618 }
619
620 public int getLineNumber() {
621 return lineNo;
622 }
623
624 @Override
625 public Type getType() {
626 return null;
627 }
628
629 @Override
630 public Freeform indentLine() {
631 indentNo++;
632 newLine();
633 return this;
634 }
635
636 @Override
637 public boolean isLineNew() {
638 return isLineNew;
639 }
640
641 @Override
642 public Freeform newLine() {
643 out.println();
644 writeIndent();
645 colNo = 0;
646 lineNo++;
647 isLineNew = true;
648 return this;
649 }
650
651 @Override
652 public Freeform resetLine() {
653 indentNo = 0;
654 newLine();
655 return this;
656 }
657
658 @Override
659 public MFreeform setCode(String code) {
660 init();
661 buf.write(code);
662 return this;
663 }
664
665 @Override
666 public Freeform space() {
667 out.print(' ');
668 colNo++;
669 isLineNew = false;
670 return this;
671 }
672
673 @Override
674 public CodeWriter toCode2(CodeWriter out) {
675 super.toCode2(out);
676 out.write(buf.toString());
677 return out;
678 }
679
680 @Override
681 public Freeform write(boolean b) {
682
683 out.print(b);
684
685 colNo += b ? 4 : 5;
686 isLineNew = false;
687 return this;
688 }
689
690 @Override
691 public Freeform write(char c) {
692
693 out.print(c);
694
695 colNo++;
696 isLineNew = false;
697 return this;
698 }
699
700 @Override
701 public Freeform write(char[] chars) {
702
703 if (chars != null) {
704 out.print(chars);
705
706 colNo += chars.length;
707 isLineNew = false;
708 }
709 return this;
710 }
711
712 @Override
713 public Freeform write(double d) {
714 out.print(d);
715 colNo += Double.toString(d).length();
716 isLineNew = false;
717 return this;
718 }
719
720 @Override
721 public Freeform write(float f) {
722 out.print(f);
723 colNo += Float.toString(f).length();
724 isLineNew = false;
725 return this;
726 }
727
728 @Override
729 public Freeform write(int i) {
730 out.print(i);
731 colNo += Integer.toString(i).length();
732 isLineNew = false;
733 return this;
734 }
735
736 @Override
737 public Freeform write(Object o) {
738 if (o != null) {
739 out.print(o);
740 colNo += o.toString().length();
741 isLineNew = false;
742 }
743 return this;
744 }
745
746 @Override
747 public Freeform write(Object[] ao) {
748 if (ao != null) {
749 for (Object element : ao) {
750 write(element);
751 }
752 }
753 return this;
754 }
755
756 @Override
757 public Freeform write(String s) {
758 if (s != null) {
759 out.print(s);
760 colNo += s.length();
761 isLineNew = false;
762 }
763
764 return this;
765 }
766
767 private void writeIndent() {
768 int n = indentNo;
769 while (n-- > 0) {
770 out.print('\t');
771 }
772 }
773
774 void init() {
775 buf = new java.io.StringWriter();
776 out = new java.io.PrintWriter(buf);
777 }
778 }
779
780
781
782
783 static class MInvoke extends MNary implements Invoke {
784
785 MInvoke(MVM vm, Expression qual, String name) {
786 super(vm);
787 this.qual = null;
788 qualExpression = qual;
789 this.name = name;
790 }
791
792 MInvoke(MVM vm, String qual, String name) {
793 super(vm);
794 this.qual = qual;
795 qualExpression = null;
796 this.name = name;
797 }
798
799 @Override
800 public Invoke addArg(boolean value) {
801 return addArg(value ? vm.newTrue() : vm.newFalse());
802 }
803
804 @Override
805 public Invoke addArg(double value) {
806 return addArg(vm.newDouble(value));
807 }
808
809 @Override
810 public Invoke addArg(Expression arg) {
811 ve.add(arg);
812 return this;
813 }
814
815 @Override
816 public Invoke addArg(float value) {
817 return addArg(vm.newFloat(value));
818 }
819
820 @Override
821 public Invoke addArg(int value) {
822 return addArg(vm.newInt(value));
823 }
824
825 @Override
826 public Invoke addArg(long value) {
827 return addArg(vm.newLong(value));
828 }
829
830 @Override
831 public Invoke addArg(String value) {
832 return addArg(vm.newString(value));
833 }
834
835 @Override
836 public Invoke addVariableArg(String variableName) {
837 return addArg(vm.newVar(variableName));
838 }
839
840 @Override
841 public void removeArg(int index) {
842 if (index < 0 || index >= ve.size()) {
843 throw new IllegalArgumentException("Cannot remove argument with index " + index);
844 }
845
846 ve.remove(index);
847 }
848
849 @Override
850 public CodeWriter toCode2(CodeWriter out) {
851 if (isActive(METHOD_INVOCATION_ON_NEW_LINE) && qualExpression instanceof MExpression) {
852
853
854 ((MExpression) qualExpression).forceNewLineAfterExpression();
855 }
856
857 super.toCode2(out);
858 out.write('(');
859 for (int i = 0; i < ve.size(); i++) {
860 if (i > 0) {
861 out.write(", ");
862 }
863 out.write(ve.get(i));
864 }
865 out.write(')');
866
867 return out;
868 }
869
870 @Override
871 public boolean isActive(Style style) {
872 if (style == METHOD_INVOCATION_ON_NEW_LINE) {
873
874 return super.isActive(style)
875 || qualExpression != null && qualExpression.isActive(style);
876 } else {
877 return super.isActive(style);
878 }
879 }
880
881 @Override
882 public Invoke applyStyle(Style style) {
883 if (qualExpression instanceof MInvoke) {
884
885 qualExpression.applyStyle(style);
886
887 } else {
888 super.applyStyle(style);
889 }
890 return this;
891 }
892 }
893
894
895
896
897 abstract static class MNary extends MAccessor {
898
899 List<Expression> ve = new ArrayList<>();
900
901 MNary(MVM vm) {
902 super(vm);
903 }
904
905 public List<Expression> getArgs() {
906 return ListTypeSelector.select(ve, Expression.class);
907 }
908
909 @Override
910 public void visit(ReplacingVisitor visitor) {
911 super.visit(visitor);
912 VisitorUtils.visit(ve, this, visitor);
913 }
914 }
915
916
917
918
919 static class MNewAnonymousClass extends MDeclaration.MClassDeclaration implements NewAnonymousClass {
920
921 Type type;
922
923 List<Expression> ve = new ArrayList<>();
924
925 String qual;
926
927 MNewAnonymousClass(MVM vm, Type type, Comparator comparator) {
928 super(vm, null);
929 this.type = type;
930 setComparator(comparator);
931 }
932
933 @Override
934 public NewClass addArg(Expression arg) {
935 ve.add(arg);
936 return this;
937 }
938
939 @Override
940 public List<Expression> getArgs() {
941 return ListTypeSelector.select(ve, Expression.class);
942 }
943
944 @Override
945 public String getQualifier() {
946 return qual;
947 }
948
949 @Override
950 public Type getType() {
951 return type;
952 }
953
954 @Override
955 public MNewAnonymousClass setQualifier(String qual) {
956 this.qual = qual;
957 return this;
958 }
959
960 @Override
961 public MNewAnonymousClass setType(Type type) {
962 this.type = type;
963 return this;
964 }
965
966 @Override
967 public CodeWriter toCode(CodeWriter out) {
968 out.write("new ").write(type).write('(');
969
970 for (int i = 0; i < ve.size(); i++) {
971 if (i > 0) {
972 out.write(", ");
973 }
974 out.write(ve.get(i));
975 }
976 out.write(')');
977
978 writeBlock(out, vm.getStyle("anonymous-class"));
979
980 return out;
981 }
982
983 @Override
984 public void visit(ReplacingVisitor visitor) {
985 super.visit(visitor);
986 type = VisitorUtils.visit(type, this, visitor);
987 VisitorUtils.visit(ve, this, visitor);
988 }
989 }
990
991
992
993
994 static class MNewArray extends MNary implements NewArray {
995
996 Type type;
997
998 List<Expression> dimensions;
999
1000 ArrayInitializer ai;
1001
1002 MNewArray(MVM vm, Type type) {
1003 super(vm);
1004 this.type = type;
1005 dimensions = new ArrayList<>();
1006 }
1007
1008 @Override
1009 public NewArray addDim() {
1010 dimensions.add(new MBlank(vm));
1011 return this;
1012 }
1013
1014 @Override
1015 public NewArray addDim(Expression e) {
1016 dimensions.add(e);
1017 return this;
1018 }
1019
1020 @Override
1021 public List<Expression> getDims() {
1022 return ListTypeSelector.select(dimensions, Expression.class);
1023 }
1024
1025 @Override
1026 public ArrayInitializer getInitializer() {
1027 return ai;
1028 }
1029
1030 @Override
1031 public Type getType() {
1032 return type;
1033 }
1034
1035 @Override
1036 public MNewArray setInitializer(ArrayInitializer ai) {
1037 this.ai = ai;
1038 return this;
1039 }
1040
1041 @Override
1042 public MNewArray setType(Type type) {
1043 this.type = type;
1044 return this;
1045 }
1046
1047 @Override
1048 public CodeWriter toCode2(CodeWriter out) {
1049 out.write("new ").write(type);
1050 for (Expression dim : dimensions) {
1051 out.write('[').write(dim).write(']');
1052 }
1053 out.write(ai);
1054 return out;
1055 }
1056
1057 @Override
1058 public void visit(ReplacingVisitor visitor) {
1059 super.visit(visitor);
1060 type = VisitorUtils.visit(type, this, visitor);
1061 VisitorUtils.visit(dimensions, this, visitor);
1062 ai = VisitorUtils.visit(ai, this, visitor);
1063 }
1064 }
1065
1066
1067
1068
1069 static class MNewClass extends MNary implements NewClass {
1070
1071 Type type;
1072
1073 MNewClass(MVM vm, Type type) {
1074 super(vm);
1075 this.type = type;
1076 }
1077
1078 @Override
1079 public NewClass addArg(Expression arg) {
1080 ve.add(arg);
1081 return this;
1082 }
1083
1084 @Override
1085 public Type getType() {
1086 return type;
1087 }
1088
1089 @Override
1090 public MNewClass setQualifier(String qual) {
1091 super.setQualifier(qual);
1092 return this;
1093 }
1094
1095 @Override
1096 public MNewClass setType(Type type) {
1097 this.type = type;
1098 return this;
1099 }
1100
1101 @Override
1102 public CodeWriter toCode2(CodeWriter out) {
1103 super.toCode2(out);
1104
1105 out.write("new ").write(type).write('(');
1106 for (int i = 0; i < ve.size(); i++) {
1107 if (i > 0) {
1108 out.write(", ");
1109 }
1110 out.write(ve.get(i));
1111 }
1112 out.write(')');
1113
1114 return out;
1115 }
1116
1117 @Override
1118 public void visit(ReplacingVisitor visitor) {
1119 super.visit(visitor);
1120 type = VisitorUtils.visit(type, this, visitor);
1121 }
1122 }
1123
1124
1125
1126
1127 static class MTernary extends MExpression implements Ternary {
1128
1129 final int type;
1130
1131 Expression one;
1132
1133 Expression two;
1134
1135 Expression three;
1136
1137 MTernary(MVM vm, int type, Expression one, Expression two, Expression three) {
1138 super(vm);
1139 this.type = type;
1140 this.one = one;
1141 this.two = two;
1142 this.three = three;
1143 }
1144
1145 @Override
1146 public Type getType() {
1147 return two.getType();
1148 }
1149
1150 @Override
1151 public Expression getValue1() {
1152 return one;
1153 }
1154
1155 @Override
1156 public Expression getValue2() {
1157 return two;
1158 }
1159
1160 @Override
1161 public Expression getValue3() {
1162 return three;
1163 }
1164
1165 @Override
1166 public MTernary setValue1(Expression one) {
1167 this.one = one;
1168 return this;
1169 }
1170
1171 @Override
1172 public MTernary setValue2(Expression two) {
1173 this.two = two;
1174 return this;
1175 }
1176
1177 @Override
1178 public MTernary setValue3(Expression three) {
1179 this.three = three;
1180 return this;
1181 }
1182
1183 @Override
1184 public CodeWriter toCode2(CodeWriter out) {
1185 super.toCode2(out);
1186 out.write(one).write(" ? ").write(two).write(" : ").write(three);
1187 return out;
1188 }
1189
1190 @Override
1191 public int type() {
1192 return type;
1193 }
1194
1195 @Override
1196 public void visit(ReplacingVisitor visitor) {
1197 super.visit(visitor);
1198 one = VisitorUtils.visit(one, this, visitor);
1199 two = VisitorUtils.visit(two, this, visitor);
1200 three = VisitorUtils.visit(three, this, visitor);
1201 }
1202 }
1203
1204
1205
1206
1207 static class MTypeVariable extends MExpression implements Variable {
1208
1209 Type type;
1210
1211 MTypeVariable(MVM vm) {
1212 super(vm);
1213 }
1214
1215 MTypeVariable(MVM vm, Type type) {
1216 super(vm);
1217 this.type = type;
1218 }
1219
1220 @Override
1221 public String getName() {
1222 return type.toString();
1223 }
1224
1225 @Override
1226 public Type getType() {
1227 return type;
1228 }
1229
1230 @Override
1231 public Variable setName(String typeName) {
1232 type = vm.newType(typeName);
1233 return this;
1234 }
1235
1236 public MTypeVariable setName(Type type) {
1237 this.type = type;
1238 return this;
1239 }
1240
1241 @Override
1242 public CodeWriter toCode2(CodeWriter out) {
1243 super.toCode2(out);
1244 out.write(type);
1245 return out;
1246 }
1247
1248 @Override
1249 public void visit(ReplacingVisitor visitor) {
1250 super.visit(visitor);
1251 type = VisitorUtils.visit(type, this, visitor);
1252 }
1253 }
1254
1255
1256
1257
1258 static class MUnary extends MExpression implements Unary {
1259
1260 final int type;
1261
1262 Expression val;
1263
1264 MUnary(MVM vm, int type, Expression val) {
1265 super(vm);
1266 this.type = type;
1267 this.val = val;
1268 }
1269
1270 @Override
1271 public Type getType() {
1272 return val.getType();
1273 }
1274
1275 @Override
1276 public Expression getValue() {
1277 return val;
1278 }
1279
1280 @Override
1281 public MUnary setValue(Expression val) {
1282 this.val = val;
1283 return this;
1284 }
1285
1286 @Override
1287 public CodeWriter toCode2(CodeWriter out) {
1288 super.toCode2(out);
1289
1290 switch (type) {
1291 case Unary.GROUP:
1292 out.write('(').write(val).write(')');
1293 break;
1294 case Unary.NOT:
1295 out.write('!').write(val);
1296 break;
1297 case Unary.BITWISE_NOT:
1298 out.write('~').write(val);
1299 break;
1300 case Unary.POS:
1301 out.write('+').write(val);
1302 break;
1303 case Unary.NEG:
1304 out.write('-').write(val);
1305 break;
1306 case Unary.PREFIX_INCREMENT:
1307 out.write("++").write(val);
1308 break;
1309 case Unary.POST_INCREMENT:
1310 out.write(val).write("++");
1311 break;
1312 case Unary.PREFIX_DECREMENT:
1313 out.write("--").write(val);
1314 break;
1315 case Unary.POST_DECREMENT:
1316 out.write(val).write("--");
1317 break;
1318 default:
1319 throw new RuntimeException("Please use a constant from the Unary interface when making new unary expressions.");
1320 }
1321
1322 return out;
1323 }
1324
1325 @Override
1326 public int type() {
1327 return type;
1328 }
1329
1330 @Override
1331 public void visit(ReplacingVisitor visitor) {
1332 super.visit(visitor);
1333 val = VisitorUtils.visit(val, this, visitor);
1334 }
1335 }
1336
1337
1338
1339
1340 static class MVariable extends MExpression implements Variable {
1341
1342 String name;
1343
1344 MVariable(MVM vm, String name) {
1345 super(vm);
1346 this.name = name;
1347 }
1348
1349 @Override
1350 public String getName() {
1351 return name;
1352 }
1353
1354 @Override
1355 public Type getType() {
1356 return null;
1357 }
1358
1359 @Override
1360 public MVariable setName(String name) {
1361 this.name = name;
1362 return this;
1363 }
1364
1365 @Override
1366 public CodeWriter toCode2(CodeWriter out) {
1367 super.toCode2(out);
1368 out.write(name);
1369 return out;
1370 }
1371 }
1372
1373 static class MThis extends MVariable implements This {
1374
1375 MThis(MVM vm) {
1376 super(vm, "this");
1377 }
1378
1379 public MThis(MVM mvm, ClassType typeOfOuterClass) {
1380 super(mvm, typeOfOuterClass.getName() + ".this");
1381 }
1382
1383 @Override
1384 public MVariable setName(String ignored) {
1385 throw new UnsupportedOperationException("Not allowed for this.");
1386 }
1387 }
1388
1389 static class MSuper extends MVariable implements Super {
1390
1391 MSuper(MVM vm) {
1392 super(vm, "super");
1393 }
1394
1395 @Override
1396 public MVariable setName(String ignored) {
1397 throw new UnsupportedOperationException("Not allowed for super.");
1398 }
1399 }
1400
1401 MExpression(MVM vm) {
1402 super(vm);
1403 }
1404
1405 public CodeWriter toCode2(CodeWriter out) {
1406 return out;
1407 }
1408
1409 @Override
1410 public final CodeWriter toCode(CodeWriter out) {
1411 toCode2(out);
1412 if (forcedNewlineAfterExpression) {
1413 out.write(" //").newLine();
1414 }
1415 return out;
1416 }
1417
1418 private void forceNewLineAfterExpression() {
1419 this.forcedNewlineAfterExpression = true;
1420 }
1421 }