1 //**************************************************************************
2 //**
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
9 //**
10 //** $Id: vc_expr_unary_binary.cpp 4297 2010-06-03 22:49:00Z firebrand_kh $
11 //**
12 //** Copyright (C) 1999-2006 Jānis Legzdiņš
13 //**
14 //** This program is free software; you can redistribute it and/or
15 //** modify it under the terms of the GNU General Public License
16 //** as published by the Free Software Foundation; either version 2
17 //** of the License, or (at your option) any later version.
18 //**
19 //** This program is distributed in the hope that it will be useful,
20 //** but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 //** GNU General Public License for more details.
23 //**
24 //**************************************************************************
25
26 // HEADER FILES ------------------------------------------------------------
27
28 #include "vc_local.h"
29
30 // MACROS ------------------------------------------------------------------
31
32 // TYPES -------------------------------------------------------------------
33
34 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
35
36 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
37
38 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
39
40 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
41
42 // PUBLIC DATA DEFINITIONS -------------------------------------------------
43
44 // PRIVATE DATA DEFINITIONS ------------------------------------------------
45
46 // CODE --------------------------------------------------------------------
47
48 //==========================================================================
49 //
50 // VUnary::VUnary
51 //
52 //==========================================================================
53
VUnary(VUnary::EUnaryOp AOper,VExpression * AOp,const TLocation & ALoc)54 VUnary::VUnary(VUnary::EUnaryOp AOper, VExpression* AOp, const TLocation& ALoc)
55 : VExpression(ALoc)
56 , Oper(AOper)
57 , op(AOp)
58 {
59 if (!op)
60 {
61 ParseError(Loc, "Expression expected");
62 return;
63 }
64 }
65
66 //==========================================================================
67 //
68 // VUnary::~VUnary
69 //
70 //==========================================================================
71
~VUnary()72 VUnary::~VUnary()
73 {
74 if (op)
75 {
76 delete op;
77 op = NULL;
78 }
79 }
80
81 //==========================================================================
82 //
83 // VUnary::DoResolve
84 //
85 //==========================================================================
86
DoResolve(VEmitContext & ec)87 VExpression* VUnary::DoResolve(VEmitContext& ec)
88 {
89 if (op)
90 {
91 if (Oper == Not)
92 op = op->ResolveBoolean(ec);
93 else
94 op = op->Resolve(ec);
95 }
96 if (!op)
97 {
98 delete this;
99 return NULL;
100 }
101
102 switch (Oper)
103 {
104 case Plus:
105 Type = op->Type;
106 if (op->Type.Type != TYPE_Int && op->Type.Type != TYPE_Float)
107 {
108 ParseError(Loc, "Expression type mistmatch");
109 delete this;
110 return NULL;
111 }
112 else
113 {
114 VExpression* e = op;
115 op = NULL;
116 delete this;
117 return e;
118 }
119
120 case Minus:
121 if (op->Type.Type == TYPE_Int)
122 {
123 Type = TYPE_Int;
124 }
125 else if (op->Type.Type == TYPE_Float)
126 {
127 Type = TYPE_Float;
128 }
129 else if (op->Type.Type == TYPE_Vector)
130 {
131 Type = op->Type;
132 }
133 else
134 {
135 ParseError(Loc, "Expression type mistmatch");
136 delete this;
137 return NULL;
138 }
139 break;
140
141 case Not:
142 Type = TYPE_Int;
143 break;
144
145 case BitInvert:
146 if (op->Type.Type != TYPE_Int)
147 {
148 ParseError(Loc, "Expression type mistmatch");
149 delete this;
150 return NULL;
151 }
152 Type = TYPE_Int;
153 break;
154
155 case TakeAddress:
156 if (op->Type.Type == TYPE_Reference)
157 {
158 ParseError(Loc, "Tried to take address of reference");
159 delete this;
160 return NULL;
161 }
162 else
163 {
164 op->RequestAddressOf();
165 Type = op->RealType.MakePointerType();
166 }
167 break;
168 }
169
170 // Optimise integer constants.
171 if (op->IsIntConst())
172 {
173 vint32 Value = op->GetIntConst();
174 VExpression* e = NULL;
175 switch (Oper)
176 {
177 case Minus:
178 e = new VIntLiteral(-Value, Loc);
179 break;
180
181 case Not:
182 e = new VIntLiteral(!Value, Loc);
183 break;
184
185 case BitInvert:
186 e = new VIntLiteral(~Value, Loc);
187 break;
188
189 default:
190 break;
191 }
192 if (e)
193 {
194 delete this;
195 return e;
196 }
197 }
198
199 // Optimise float constants.
200 if (op->IsFloatConst() && Oper == Minus)
201 {
202 float Value = op->GetFloatConst();
203 VExpression* e = new VFloatLiteral(-Value, Loc);
204 delete this;
205 return e;
206 }
207
208 return this;
209 }
210
211 //==========================================================================
212 //
213 // VUnary::Emit
214 //
215 //==========================================================================
216
Emit(VEmitContext & ec)217 void VUnary::Emit(VEmitContext& ec)
218 {
219 op->Emit(ec);
220
221 switch (Oper)
222 {
223 case Plus:
224 break;
225
226 case Minus:
227 if (op->Type.Type == TYPE_Int)
228 {
229 ec.AddStatement(OPC_UnaryMinus);
230 }
231 else if (op->Type.Type == TYPE_Float)
232 {
233 ec.AddStatement(OPC_FUnaryMinus);
234 }
235 else if (op->Type.Type == TYPE_Vector)
236 {
237 ec.AddStatement(OPC_VUnaryMinus);
238 }
239 break;
240
241 case Not:
242 ec.AddStatement(OPC_NegateLogical);
243 break;
244
245 case BitInvert:
246 ec.AddStatement(OPC_BitInverse);
247 break;
248
249 case TakeAddress:
250 break;
251 }
252 }
253
254 //==========================================================================
255 //
256 // VUnary::EmitBranchable
257 //
258 //==========================================================================
259
EmitBranchable(VEmitContext & ec,VLabel Lbl,bool OnTrue)260 void VUnary::EmitBranchable(VEmitContext& ec, VLabel Lbl, bool OnTrue)
261 {
262 if (Oper == Not)
263 {
264 op->EmitBranchable(ec, Lbl, !OnTrue);
265 }
266 else
267 {
268 VExpression::EmitBranchable(ec, Lbl, OnTrue);
269 }
270 }
271
272 //==========================================================================
273 //
274 // VUnaryMutator::VUnaryMutator
275 //
276 //==========================================================================
277
VUnaryMutator(EIncDec AOper,VExpression * AOp,const TLocation & ALoc)278 VUnaryMutator::VUnaryMutator(EIncDec AOper, VExpression* AOp, const TLocation& ALoc)
279 : VExpression(ALoc)
280 , Oper(AOper)
281 , op(AOp)
282 {
283 if (!op)
284 {
285 ParseError(Loc, "Expression expected");
286 return;
287 }
288 }
289
290 //==========================================================================
291 //
292 // VUnaryMutator::~VUnaryMutator
293 //
294 //==========================================================================
295
~VUnaryMutator()296 VUnaryMutator::~VUnaryMutator()
297 {
298 if (op)
299 {
300 delete op;
301 op = NULL;
302 }
303 }
304
305 //==========================================================================
306 //
307 // VUnaryMutator::DoResolve
308 //
309 //==========================================================================
310
DoResolve(VEmitContext & ec)311 VExpression* VUnaryMutator::DoResolve(VEmitContext& ec)
312 {
313 if (op)
314 op = op->Resolve(ec);
315 if (!op)
316 {
317 delete this;
318 return NULL;
319 }
320
321 if (op->Type.Type != TYPE_Int)
322 {
323 ParseError(Loc, "Expression type mistmatch");
324 delete this;
325 return NULL;
326 }
327 Type = TYPE_Int;
328 op->RequestAddressOf();
329 return this;
330 }
331
332 //==========================================================================
333 //
334 // VUnaryMutator::Emit
335 //
336 //==========================================================================
337
Emit(VEmitContext & ec)338 void VUnaryMutator::Emit(VEmitContext& ec)
339 {
340 op->Emit(ec);
341 switch (Oper)
342 {
343 case PreInc:
344 ec.AddStatement(OPC_PreInc);
345 break;
346
347 case PreDec:
348 ec.AddStatement(OPC_PreDec);
349 break;
350
351 case PostInc:
352 ec.AddStatement(OPC_PostInc);
353 break;
354
355 case PostDec:
356 ec.AddStatement(OPC_PostDec);
357 break;
358
359 case Inc:
360 ec.AddStatement(OPC_IncDrop);
361 break;
362
363 case Dec:
364 ec.AddStatement(OPC_DecDrop);
365 break;
366 }
367 }
368
369 //==========================================================================
370 //
371 // VUnaryMutator::AddDropResult
372 //
373 //==========================================================================
374
AddDropResult()375 bool VUnaryMutator::AddDropResult()
376 {
377 switch (Oper)
378 {
379 case PreInc:
380 case PostInc:
381 Oper = Inc;
382 break;
383
384 case PreDec:
385 case PostDec:
386 Oper = Dec;
387 break;
388
389 case Inc:
390 case Dec:
391 FatalError("Should not happen");
392 }
393 Type = TYPE_Void;
394 return true;
395 }
396
397 //==========================================================================
398 //
399 // VBinary::VBinary
400 //
401 //==========================================================================
402
VBinary(EBinOp AOper,VExpression * AOp1,VExpression * AOp2,const TLocation & ALoc)403 VBinary::VBinary(EBinOp AOper, VExpression* AOp1, VExpression* AOp2, const TLocation& ALoc)
404 : VExpression(ALoc)
405 , Oper(AOper)
406 , op1(AOp1)
407 , op2(AOp2)
408 {
409 if (!op2)
410 {
411 ParseError(Loc, "Expression expected");
412 return;
413 }
414 }
415
416 //==========================================================================
417 //
418 // VBinary::~VBinary
419 //
420 //==========================================================================
421
~VBinary()422 VBinary::~VBinary()
423 {
424 if (op1)
425 {
426 delete op1;
427 op1 = NULL;
428 }
429 if (op2)
430 {
431 delete op2;
432 op2 = NULL;
433 }
434 }
435
436 //==========================================================================
437 //
438 // VBinary::DoResolve
439 //
440 //==========================================================================
441
DoResolve(VEmitContext & ec)442 VExpression* VBinary::DoResolve(VEmitContext& ec)
443 {
444 if (op1)
445 op1 = op1->Resolve(ec);
446 if (op2)
447 op2 = op2->Resolve(ec);
448 if (!op1 || !op2)
449 {
450 delete this;
451 return NULL;
452 }
453
454 if (ec.Package->Name == NAME_decorate)
455 {
456 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Float)
457 {
458 VExpression* TmpArgs[1];
459 TmpArgs[0] = op1;
460 op1 = new VInvocation(NULL, ec.SelfClass->FindMethodChecked(
461 "itof"), NULL, false, false, op1->Loc, 1, TmpArgs);
462 op1 = op1->Resolve(ec);
463 }
464 else if (op1->Type.Type == TYPE_Float && op2->Type.Type == TYPE_Int)
465 {
466 VExpression* TmpArgs[1];
467 TmpArgs[0] = op2;
468 op2 = new VInvocation(NULL, ec.SelfClass->FindMethodChecked(
469 "itof"), NULL, false, false, op2->Loc, 1, TmpArgs);
470 op2 = op2->Resolve(ec);
471 }
472 }
473
474 switch (Oper)
475 {
476 case Add:
477 case Subtract:
478 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int)
479 {
480 Type = TYPE_Int;
481 }
482 else if (op1->Type.Type == TYPE_Float && op2->Type.Type == TYPE_Float)
483 {
484 Type = TYPE_Float;
485 }
486 else if (op1->Type.Type == TYPE_Vector && op2->Type.Type == TYPE_Vector)
487 {
488 Type = TYPE_Vector;
489 }
490 else
491 {
492 ParseError(Loc, "Expression type mistmatch");
493 delete this;
494 return NULL;
495 }
496 break;
497 case Multiply:
498 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int)
499 {
500 Type = TYPE_Int;
501 }
502 else if (op1->Type.Type == TYPE_Float && op2->Type.Type == TYPE_Float)
503 {
504 Type = TYPE_Float;
505 }
506 else if (op1->Type.Type == TYPE_Vector && op2->Type.Type == TYPE_Float)
507 {
508 Type = TYPE_Vector;
509 }
510 else if (op1->Type.Type == TYPE_Float && op2->Type.Type == TYPE_Vector)
511 {
512 Type = TYPE_Vector;
513 }
514 else
515 {
516 ParseError(Loc, "Expression type mistmatch");
517 delete this;
518 return NULL;
519 }
520 break;
521 case Divide:
522 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int)
523 {
524 Type = TYPE_Int;
525 }
526 else if (op1->Type.Type == TYPE_Float && op2->Type.Type == TYPE_Float)
527 {
528 Type = TYPE_Float;
529 }
530 else if (op1->Type.Type == TYPE_Vector && op2->Type.Type == TYPE_Float)
531 {
532 Type = TYPE_Vector;
533 }
534 else
535 {
536 ParseError(Loc, "Expression type mistmatch");
537 delete this;
538 return NULL;
539 }
540 break;
541 case Modulus:
542 case LShift:
543 case RShift:
544 case And:
545 case XOr:
546 case Or:
547 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int)
548 {
549 Type = TYPE_Int;
550 }
551 else
552 {
553 ParseError(Loc, "Expression type mistmatch");
554 delete this;
555 return NULL;
556 }
557 break;
558 case Less:
559 case LessEquals:
560 case Greater:
561 case GreaterEquals:
562 if (!(op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int) &&
563 !(op1->Type.Type == TYPE_Float && op2->Type.Type == TYPE_Float))
564 {
565 ParseError(Loc, "Expression type mistmatch");
566 delete this;
567 return NULL;
568 }
569 Type = TYPE_Int;
570 break;
571 case Equals:
572 case NotEquals:
573 if (!(op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int) &&
574 !(op1->Type.Type == TYPE_Float && op2->Type.Type == TYPE_Float) &&
575 !(op1->Type.Type == TYPE_Name && op2->Type.Type == TYPE_Name) &&
576 !(op1->Type.Type == TYPE_Pointer && op2->Type.Type == TYPE_Pointer) &&
577 !(op1->Type.Type == TYPE_Vector && op2->Type.Type == TYPE_Vector) &&
578 !(op1->Type.Type == TYPE_Class && op2->Type.Type == TYPE_Class) &&
579 !(op1->Type.Type == TYPE_State && op2->Type.Type == TYPE_State) &&
580 !(op1->Type.Type == TYPE_Reference && op2->Type.Type == TYPE_Reference))
581 {
582 ParseError(Loc, "Expression type mistmatch");
583 delete this;
584 return NULL;
585 }
586 Type = TYPE_Int;
587 break;
588 }
589
590 // Optimise integer constants
591 if (op1->IsIntConst() && op2->IsIntConst())
592 {
593 vint32 Value1 = op1->GetIntConst();
594 vint32 Value2 = op2->GetIntConst();
595 VExpression* e = NULL;
596 switch (Oper)
597 {
598 case Add:
599 e = new VIntLiteral(Value1 + Value2, Loc);
600 break;
601
602 case Subtract:
603 e = new VIntLiteral(Value1 - Value2, Loc);
604 break;
605
606 case Multiply:
607 e = new VIntLiteral(Value1 * Value2, Loc);
608 break;
609
610 case Divide:
611 if (!Value2)
612 {
613 ParseError(Loc, "Division by 0");
614 delete this;
615 return NULL;
616 }
617 e = new VIntLiteral(Value1 / Value2, Loc);
618 break;
619
620 case Modulus:
621 if (!Value2)
622 {
623 ParseError(Loc, "Division by 0");
624 delete this;
625 return NULL;
626 }
627 e = new VIntLiteral(Value1 % Value2, Loc);
628 break;
629
630 case LShift:
631 e = new VIntLiteral(Value1 << Value2, Loc);
632 break;
633
634 case RShift:
635 e = new VIntLiteral(Value1 >> Value2, Loc);
636 break;
637
638 case Less:
639 e = new VIntLiteral(Value1 < Value2, Loc);
640 break;
641
642 case LessEquals:
643 e = new VIntLiteral(Value1 <= Value2, Loc);
644 break;
645
646 case Greater:
647 e = new VIntLiteral(Value1 > Value2, Loc);
648 break;
649
650 case GreaterEquals:
651 e = new VIntLiteral(Value1 >= Value2, Loc);
652 break;
653
654 case Equals:
655 e = new VIntLiteral(Value1 == Value2, Loc);
656 break;
657
658 case NotEquals:
659 e = new VIntLiteral(Value1 != Value2, Loc);
660 break;
661
662 case And:
663 e = new VIntLiteral(Value1 & Value2, Loc);
664 break;
665
666 case XOr:
667 e = new VIntLiteral(Value1 ^ Value2, Loc);
668 break;
669
670 case Or:
671 e = new VIntLiteral(Value1 | Value2, Loc);
672 break;
673
674 default:
675 break;
676 }
677 if (e)
678 {
679 delete this;
680 return e;
681 }
682 }
683
684 // Optimise float constants.
685 if (op1->IsFloatConst() && op2->IsFloatConst())
686 {
687 float Value1 = op1->GetFloatConst();
688 float Value2 = op2->GetFloatConst();
689 VExpression* e = NULL;
690 switch (Oper)
691 {
692 case Add:
693 e = new VFloatLiteral(Value1 + Value2, Loc);
694 break;
695
696 case Subtract:
697 e = new VFloatLiteral(Value1 - Value2, Loc);
698 break;
699
700 case Multiply:
701 e = new VFloatLiteral(Value1 * Value2, Loc);
702 break;
703
704 case Divide:
705 if (!Value2)
706 {
707 ParseError(Loc, "Division by 0");
708 delete this;
709 return NULL;
710 }
711 e = new VFloatLiteral(Value1 / Value2, Loc);
712 break;
713
714 default:
715 break;
716 }
717 if (e)
718 {
719 delete this;
720 return e;
721 }
722 }
723
724 return this;
725 }
726
727 //==========================================================================
728 //
729 // VBinary::Emit
730 //
731 //==========================================================================
732
Emit(VEmitContext & ec)733 void VBinary::Emit(VEmitContext& ec)
734 {
735 op1->Emit(ec);
736 op2->Emit(ec);
737
738 switch (Oper)
739 {
740 case Add:
741 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int)
742 {
743 ec.AddStatement(OPC_Add);
744 }
745 else if (op1->Type.Type == TYPE_Float && op2->Type.Type == TYPE_Float)
746 {
747 ec.AddStatement(OPC_FAdd);
748 }
749 else if (op1->Type.Type == TYPE_Vector && op2->Type.Type == TYPE_Vector)
750 {
751 ec.AddStatement(OPC_VAdd);
752 }
753 break;
754
755 case Subtract:
756 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int)
757 {
758 ec.AddStatement(OPC_Subtract);
759 }
760 else if (op1->Type.Type == TYPE_Float && op2->Type.Type == TYPE_Float)
761 {
762 ec.AddStatement(OPC_FSubtract);
763 }
764 else if (op1->Type.Type == TYPE_Vector && op2->Type.Type == TYPE_Vector)
765 {
766 ec.AddStatement(OPC_VSubtract);
767 }
768 break;
769
770 case Multiply:
771 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int)
772 {
773 ec.AddStatement(OPC_Multiply);
774 }
775 else if (op1->Type.Type == TYPE_Float && op2->Type.Type == TYPE_Float)
776 {
777 ec.AddStatement(OPC_FMultiply);
778 }
779 else if (op1->Type.Type == TYPE_Vector && op2->Type.Type == TYPE_Float)
780 {
781 ec.AddStatement(OPC_VPostScale);
782 }
783 else if (op1->Type.Type == TYPE_Float && op2->Type.Type == TYPE_Vector)
784 {
785 ec.AddStatement(OPC_VPreScale);
786 }
787 break;
788
789 case Divide:
790 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int)
791 {
792 ec.AddStatement(OPC_Divide);
793 }
794 else if (op1->Type.Type == TYPE_Float && op2->Type.Type == TYPE_Float)
795 {
796 ec.AddStatement(OPC_FDivide);
797 }
798 else if (op1->Type.Type == TYPE_Vector && op2->Type.Type == TYPE_Float)
799 {
800 ec.AddStatement(OPC_VIScale);
801 }
802 break;
803
804 case Modulus:
805 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int)
806 {
807 ec.AddStatement(OPC_Modulus);
808 }
809 break;
810
811 case LShift:
812 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int)
813 {
814 ec.AddStatement(OPC_LShift);
815 }
816 break;
817
818 case RShift:
819 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int)
820 {
821 ec.AddStatement(OPC_RShift);
822 }
823 break;
824
825 case Less:
826 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int)
827 {
828 ec.AddStatement(OPC_Less);
829 }
830 else if (op1->Type.Type == TYPE_Float && op2->Type.Type == TYPE_Float)
831 {
832 ec.AddStatement(OPC_FLess);
833 }
834 break;
835
836 case LessEquals:
837 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int)
838 {
839 ec.AddStatement(OPC_LessEquals);
840 }
841 else if (op1->Type.Type == TYPE_Float && op2->Type.Type == TYPE_Float)
842 {
843 ec.AddStatement(OPC_FLessEquals);
844 }
845 break;
846
847 case Greater:
848 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int)
849 {
850 ec.AddStatement(OPC_Greater);
851 }
852 else if (op1->Type.Type == TYPE_Float && op2->Type.Type == TYPE_Float)
853 {
854 ec.AddStatement(OPC_FGreater);
855 }
856 break;
857
858 case GreaterEquals:
859 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int)
860 {
861 ec.AddStatement(OPC_GreaterEquals);
862 }
863 else if (op1->Type.Type == TYPE_Float && op2->Type.Type == TYPE_Float)
864 {
865 ec.AddStatement(OPC_FGreaterEquals);
866 }
867 break;
868
869 case Equals:
870 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int)
871 {
872 ec.AddStatement(OPC_Equals);
873 }
874 else if (op1->Type.Type == TYPE_Float && op2->Type.Type == TYPE_Float)
875 {
876 ec.AddStatement(OPC_FEquals);
877 }
878 else if (op1->Type.Type == TYPE_Name && op2->Type.Type == TYPE_Name)
879 {
880 ec.AddStatement(OPC_Equals);
881 }
882 else if (op1->Type.Type == TYPE_Pointer && op2->Type.Type == TYPE_Pointer)
883 {
884 ec.AddStatement(OPC_PtrEquals);
885 }
886 else if (op1->Type.Type == TYPE_Vector && op2->Type.Type == TYPE_Vector)
887 {
888 ec.AddStatement(OPC_VEquals);
889 }
890 else if (op1->Type.Type == TYPE_Class && op2->Type.Type == TYPE_Class)
891 {
892 ec.AddStatement(OPC_PtrEquals);
893 }
894 else if (op1->Type.Type == TYPE_State && op2->Type.Type == TYPE_State)
895 {
896 ec.AddStatement(OPC_PtrEquals);
897 }
898 else if (op1->Type.Type == TYPE_Reference && op2->Type.Type == TYPE_Reference)
899 {
900 ec.AddStatement(OPC_PtrEquals);
901 }
902 break;
903
904 case NotEquals:
905 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int)
906 {
907 ec.AddStatement(OPC_NotEquals);
908 }
909 else if (op1->Type.Type == TYPE_Float && op2->Type.Type == TYPE_Float)
910 {
911 ec.AddStatement(OPC_FNotEquals);
912 }
913 else if (op1->Type.Type == TYPE_Name && op2->Type.Type == TYPE_Name)
914 {
915 ec.AddStatement(OPC_NotEquals);
916 }
917 else if (op1->Type.Type == TYPE_Pointer && op2->Type.Type == TYPE_Pointer)
918 {
919 ec.AddStatement(OPC_PtrNotEquals);
920 }
921 else if (op1->Type.Type == TYPE_Vector && op2->Type.Type == TYPE_Vector)
922 {
923 ec.AddStatement(OPC_VNotEquals);
924 }
925 else if (op1->Type.Type == TYPE_Class && op2->Type.Type == TYPE_Class)
926 {
927 ec.AddStatement(OPC_PtrNotEquals);
928 }
929 else if (op1->Type.Type == TYPE_State && op2->Type.Type == TYPE_State)
930 {
931 ec.AddStatement(OPC_PtrNotEquals);
932 }
933 else if (op1->Type.Type == TYPE_Reference && op2->Type.Type == TYPE_Reference)
934 {
935 ec.AddStatement(OPC_PtrNotEquals);
936 }
937 break;
938
939 case And:
940 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int)
941 {
942 ec.AddStatement(OPC_AndBitwise);
943 }
944 break;
945
946 case XOr:
947 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int)
948 {
949 ec.AddStatement(OPC_XOrBitwise);
950 }
951 break;
952
953 case Or:
954 if (op1->Type.Type == TYPE_Int && op2->Type.Type == TYPE_Int)
955 {
956 ec.AddStatement(OPC_OrBitwise);
957 }
958 break;
959 }
960 }
961
962 //==========================================================================
963 //
964 // VBinaryLogical::VBinaryLogical
965 //
966 //==========================================================================
967
VBinaryLogical(ELogOp AOper,VExpression * AOp1,VExpression * AOp2,const TLocation & ALoc)968 VBinaryLogical::VBinaryLogical(ELogOp AOper, VExpression* AOp1,
969 VExpression* AOp2, const TLocation& ALoc)
970 : VExpression(ALoc)
971 , Oper(AOper)
972 , op1(AOp1)
973 , op2(AOp2)
974 {
975 if (!op2)
976 {
977 ParseError(Loc, "Expression expected");
978 return;
979 }
980 }
981
982 //==========================================================================
983 //
984 // VBinaryLogical::~VBinaryLogical
985 //
986 //==========================================================================
987
~VBinaryLogical()988 VBinaryLogical::~VBinaryLogical()
989 {
990 if (op1)
991 {
992 delete op1;
993 op1 = NULL;
994 }
995 if (op2)
996 {
997 delete op2;
998 op2 = NULL;
999 }
1000 }
1001
1002 //==========================================================================
1003 //
1004 // VBinaryLogical::DoResolve
1005 //
1006 //==========================================================================
1007
DoResolve(VEmitContext & ec)1008 VExpression* VBinaryLogical::DoResolve(VEmitContext& ec)
1009 {
1010 if (op1)
1011 op1 = op1->ResolveBoolean(ec);
1012 if (op2)
1013 op2 = op2->ResolveBoolean(ec);
1014 if (!op1 || !op2)
1015 {
1016 delete this;
1017 return NULL;
1018 }
1019
1020 Type = TYPE_Int;
1021
1022 // Optimise constant cases.
1023 if (op1->IsIntConst() && op2->IsIntConst())
1024 {
1025 vint32 Value1 = op1->GetIntConst();
1026 vint32 Value2 = op2->GetIntConst();
1027 VExpression* e = NULL;
1028 switch (Oper)
1029 {
1030 case And:
1031 e = new VIntLiteral(Value1 && Value2, Loc);
1032 break;
1033
1034 case Or:
1035 e = new VIntLiteral(Value1 || Value2, Loc);
1036 break;
1037 }
1038 if (e)
1039 {
1040 delete this;
1041 return e;
1042 }
1043 }
1044
1045 return this;
1046 }
1047
1048 //==========================================================================
1049 //
1050 // VBinaryLogical::Emit
1051 //
1052 //==========================================================================
1053
Emit(VEmitContext & ec)1054 void VBinaryLogical::Emit(VEmitContext& ec)
1055 {
1056 VLabel Push01 = ec.DefineLabel();
1057 VLabel End = ec.DefineLabel();
1058
1059 op1->EmitBranchable(ec, Push01, Oper == Or);
1060
1061 op2->Emit(ec);
1062 ec.AddStatement(OPC_Goto, End);
1063
1064 ec.MarkLabel(Push01);
1065 ec.AddStatement(Oper == And ? OPC_PushNumber0 : OPC_PushNumber1);
1066
1067 ec.MarkLabel(End);
1068 }
1069
1070 //==========================================================================
1071 //
1072 // VBinaryLogical::EmitBranchable
1073 //
1074 //==========================================================================
1075
EmitBranchable(VEmitContext & ec,VLabel Lbl,bool OnTrue)1076 void VBinaryLogical::EmitBranchable(VEmitContext& ec, VLabel Lbl, bool OnTrue)
1077 {
1078 switch (Oper)
1079 {
1080 case And:
1081 if (OnTrue)
1082 {
1083 VLabel End = ec.DefineLabel();
1084 op1->EmitBranchable(ec, End, false);
1085 op2->EmitBranchable(ec, Lbl, true);
1086 ec.MarkLabel(End);
1087 }
1088 else
1089 {
1090 op1->EmitBranchable(ec, Lbl, false);
1091 op2->EmitBranchable(ec, Lbl, false);
1092 }
1093 break;
1094
1095 case Or:
1096 if (OnTrue)
1097 {
1098 op1->EmitBranchable(ec, Lbl, true);
1099 op2->EmitBranchable(ec, Lbl, true);
1100 }
1101 else
1102 {
1103 VLabel End = ec.DefineLabel();
1104 op1->EmitBranchable(ec, End, true);
1105 op2->EmitBranchable(ec, Lbl, false);
1106 ec.MarkLabel(End);
1107 }
1108 break;
1109 }
1110 }
1111