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