reforge "|" operator
[scilab.git] / scilab / modules / ast / src / cpp / operations / types_comparison_eq.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2012 - Scilab Enterprises - Antoine ELIAS
4  *
5  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #include "types_comparison_eq.hxx"
14 #include "bool.hxx"
15 #include "double.hxx"
16 #include "string.hxx"
17 #include "polynom.hxx"
18 #include "cell.hxx"
19 #include "struct.hxx"
20 #include "sparse.hxx"
21 #include "int.hxx"
22 #include "graphichandle.hxx"
23 #include "mlist.hxx"
24 #include "macro.hxx"
25 #include "macrofile.hxx"
26
27 using namespace types;
28
29 static void clearAlloc(bool _bAllocL, InternalType* _pIL, bool _bAllocR, InternalType* _pIR);
30 template <class T> static int EqualToArrayAndArray(T* _pL, T* _pR, GenericType** _pOut);
31
32 InternalType *GenericComparisonEqual(InternalType *_pLeftOperand, InternalType *_pRightOperand)
33 {
34     GenericType::ScilabType TypeL = _pLeftOperand->getType();
35     GenericType::ScilabType TypeR = _pRightOperand->getType();
36
37     InternalType* pIL = _pLeftOperand;
38     InternalType* pIR = _pRightOperand;
39     bool bAllocL = false;
40     bool bAllocR = false;
41
42     InternalType *pResult = NULL;
43
44     /*
45     ** [] == ??
46     */
47     if (TypeL == GenericType::ScilabDouble && pIL->getAs<Double>()->getSize() == 0)
48     {
49         if (TypeR != InternalType::ScilabDouble)
50         {
51             return new Bool(false);
52         }
53     }
54
55     /*
56     ** ?? == []
57     */
58     if (TypeR == GenericType::ScilabDouble && pIR->getAs<Double>()->getSize() == 0)
59     {
60         if (TypeL != InternalType::ScilabDouble)
61         {
62             return new Bool(false);
63         }
64     }
65
66     if (TypeL == GenericType::ScilabColon && TypeR == GenericType::ScilabColon)
67     {
68         //: == :
69         return new Bool(true);
70     }
71
72     if (TypeL == GenericType::ScilabColon)
73     {
74         // : == x
75         if (pIR->isGenericType())
76         {
77             //transform left operand in a identity matrix with same dimension of right operand
78             GenericType* pGT = pIR->getAs<GenericType>();
79             pIL = Double::Identity(pGT->getDims(), pGT->getDimsArray());;
80             TypeL = GenericType::ScilabDouble;
81             bAllocL = true;
82         }
83         else
84         {
85             return new Bool(false);
86         }
87     }
88
89     if (TypeR == GenericType::ScilabColon)
90     {
91         // x == :
92         if (pIL->isGenericType())
93         {
94             //transform right operand in a identity matrix with same dimensions of left operand
95             GenericType* pGT = pIL->getAs<GenericType>();
96             pIR = Double::Identity(pGT->getDims(), pGT->getDimsArray());;
97             TypeR = GenericType::ScilabDouble;
98             bAllocR = true;
99         }
100         else
101         {
102             return new Bool(false);
103         }
104     }
105
106     /*
107     ** DOUBLE == DOUBLE
108     */
109     if (TypeL == GenericType::ScilabDouble && TypeR == GenericType::ScilabDouble)
110     {
111         Double *pL   = pIL->getAs<Double>();
112         Double *pR   = pIR->getAs<Double>();
113
114         int iResult = EqualToDoubleAndDouble(pL, pR, (GenericType**)&pResult);
115         clearAlloc(bAllocL, pIL, bAllocR, pIR);
116         if (iResult)
117         {
118
119             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
120         }
121
122         return pResult;
123     }
124
125     /*
126     ** STRING == STRING
127     */
128     if (TypeL == GenericType::ScilabString && TypeR == GenericType::ScilabString)
129     {
130         String *pL   = pIL->getAs<String>();
131         String *pR   = pIR->getAs<String>();
132
133         if (pL->isScalar())
134         {
135             pResult = new Bool(pR->getDims(), pR->getDimsArray());
136
137             wchar_t* pstL = pL->get(0);
138             for (int i = 0 ; i < pR->getSize() ; i++)
139             {
140                 pResult->getAs<Bool>()->set(i, wcscmp(pstL, pR->get(i)) == 0);
141             }
142
143             clearAlloc(bAllocL, pIL, bAllocR, pIR);
144             return pResult;
145         }
146
147         if (pR->isScalar())
148         {
149             pResult = new Bool(pL->getDims(), pL->getDimsArray());
150
151             wchar_t* pstR = pR->get(0);
152             for (int i = 0 ; i < pL->getSize() ; i++)
153             {
154                 pResult->getAs<Bool>()->set(i, wcscmp(pL->get(i), pstR) == 0);
155             }
156
157             clearAlloc(bAllocL, pIL, bAllocR, pIR);
158             return pResult;
159         }
160
161         int iDims1 = pL->getDims();
162         int iDims2 = pR->getDims();
163
164         if (iDims1 != iDims2)
165         {
166             clearAlloc(bAllocL, pIL, bAllocR, pIR);
167             return new Bool(false);
168         }
169
170         int* piDims1 = pL->getDimsArray();
171         int* piDims2 = pR->getDimsArray();
172
173         for (int i = 0 ; i < iDims1 ; i++)
174         {
175             if (piDims1[i] != piDims2[i])
176             {
177                 clearAlloc(bAllocL, pIL, bAllocR, pIR);
178                 return new Bool(false);
179             }
180         }
181
182         pResult = new Bool(pL->getDims(), pL->getDimsArray());
183
184         for (int i = 0 ; i < pL->getSize() ; i++)
185         {
186             pResult->getAs<Bool>()->set(i, wcscmp(pL->get(i), pR->get(i)) == 0);
187         }
188
189         clearAlloc(bAllocL, pIL, bAllocR, pIR);
190         return pResult;
191     }
192
193     /*
194     ** BOOL == BOOL
195     */
196     if (TypeL == GenericType::ScilabBool && TypeR == GenericType::ScilabBool)
197     {
198         Bool *pL   = pIL->getAs<Bool>();
199         Bool *pR   = pIR->getAs<Bool>();
200
201         if (pL->isScalar())
202         {
203             pResult = new Bool(pR->getDims(), pR->getDimsArray());
204
205             int iL = pL->get(0);
206             for (int i = 0 ; i < pR->getSize() ; i++)
207             {
208                 pResult->getAs<Bool>()->set(i, iL == pR->get(i));
209             }
210
211             clearAlloc(bAllocL, pIL, bAllocR, pIR);
212             return pResult;
213         }
214
215         if (pR->isScalar())
216         {
217             pResult = new Bool(pL->getDims(), pL->getDimsArray());
218
219             int iR = pR->get(0);
220             for (int i = 0 ; i < pL->getSize() ; i++)
221             {
222                 pResult->getAs<Bool>()->set(i, iR == pL->get(i));
223             }
224
225             clearAlloc(bAllocL, pIL, bAllocR, pIR);
226             return pResult;
227         }
228
229
230         int iDims1 = pL->getDims();
231         int iDims2 = pR->getDims();
232
233         if (iDims1 != iDims2)
234         {
235             clearAlloc(bAllocL, pIL, bAllocR, pIR);
236             return new Bool(false);
237         }
238
239         int* piDims1 = pL->getDimsArray();
240         int* piDims2 = pR->getDimsArray();
241
242         for (int i = 0 ; i < iDims1 ; i++)
243         {
244             if (piDims1[i] != piDims2[i])
245             {
246                 clearAlloc(bAllocL, pIL, bAllocR, pIR);
247                 return new Bool(false);
248             }
249         }
250
251         pResult = new Bool(pL->getDims(), pL->getDimsArray());
252
253         for (int i = 0 ; i < pL->getSize() ; i++)
254         {
255             pResult->getAs<Bool>()->set(i, pL->get(i) == pR->get(i));
256         }
257
258         clearAlloc(bAllocL, pIL, bAllocR, pIR);
259         return pResult;
260     }
261
262     /*
263     ** POLY == POLY
264     */
265     if (TypeL == GenericType::ScilabPolynom && TypeR == GenericType::ScilabPolynom)
266     {
267         Polynom *pL   = pIL->getAs<Polynom>();
268         Polynom *pR   = pIR->getAs<Polynom>();
269
270         if (pL->isScalar())
271         {
272             pResult = new Bool(pR->getDims(), pR->getDimsArray());
273
274             SinglePoly* pSL = pL->get(0);
275             for (int i = 0 ; i < pR->getSize() ; i++)
276             {
277                 pResult->getAs<Bool>()->set(i, *pSL == *pR->get(i));
278             }
279
280             clearAlloc(bAllocL, pIL, bAllocR, pIR);
281             return pResult;
282         }
283
284         if (pR->isScalar())
285         {
286             pResult = new Bool(pL->getDims(), pL->getDimsArray());
287
288             SinglePoly* pSR = pR->get(0);
289             for (int i = 0 ; i < pL->getSize() ; i++)
290             {
291                 pResult->getAs<Bool>()->set(i, *pSR == *pL->get(i));
292             }
293
294             clearAlloc(bAllocL, pIL, bAllocR, pIR);
295             return pResult;
296         }
297
298         if (pL->getDims() != pR->getDims())
299         {
300             clearAlloc(bAllocL, pIL, bAllocR, pIR);
301             return new Bool(false);
302         }
303
304         int* piDims1 = pL->getDimsArray();
305         int* piDims2 = pR->getDimsArray();
306
307         for (int i = 0 ; i < pL->getDims() ; i++)
308         {
309             if (piDims1[i] != piDims2[i])
310             {
311                 clearAlloc(bAllocL, pIL, bAllocR, pIR);
312                 return new Bool(false);
313             }
314         }
315
316         pResult = new Bool(pL->getDims(), pL->getDimsArray());
317
318         for (int i = 0 ; i < pL->getSize() ; i++)
319         {
320             pResult->getAs<Bool>()->set(i, *pL->get(i) == *pR->get(i));
321         }
322
323         clearAlloc(bAllocL, pIL, bAllocR, pIR);
324         return pResult;
325     }
326
327     /*
328     ** DOUBLE == POLY
329     */
330     if (TypeL == GenericType::ScilabDouble && TypeR == GenericType::ScilabPolynom)
331     {
332         Double *pL  = pIL->getAs<Double>();
333         Polynom *pR = pIR->getAs<Polynom>();
334
335         if (pR->isScalar())
336         {
337             pResult         = new Bool(pL->getDims(), pL->getDimsArray());
338             int* piResult   = pResult->getAs<Bool>()->get();
339             int iSize       = pL->getSize();
340             int iRank       = 0;
341
342             pR->getRank(&iRank);
343             if (iRank != 0) // check rank
344             {
345                 memset(piResult, 0x00, iSize * sizeof(int));
346             }
347             else
348             {
349                 // check values
350                 double dR       = pR->get(0)->get(0);
351                 double* pdblL   = pL->get();
352                 if (pL->isComplex() && pR->isComplex())
353                 {
354                     double dRImg    = pR->get(0)->getImg(0);
355                     double* pdblLImg = pL->getImg();
356                     for (int i = 0 ; i < iSize; i++)
357                     {
358                         piResult[i] = (int)((dR == pdblL[i]) && (dRImg == pdblLImg[i]));
359                     }
360                 }
361                 else if (pL->isComplex())
362                 {
363                     double* pdblLImg = pL->getImg();
364                     for (int i = 0 ; i < iSize; i++)
365                     {
366                         piResult[i] = (int)((dR == pdblL[i]) && (pdblLImg[i] == 0));
367                     }
368                 }
369                 else if (pR->isComplex())
370                 {
371                     double dRImg    = pR->get(0)->getImg(0);
372                     for (int i = 0 ; i < iSize; i++)
373                     {
374                         piResult[i] = (int)((dR == pdblL[i]) && (dRImg == 0));
375                     }
376                 }
377                 else
378                 {
379                     for (int i = 0 ; i < iSize; i++)
380                     {
381                         piResult[i] = (int)(dR == pdblL[i]);
382                     }
383                 }
384             }
385
386             clearAlloc(bAllocL, pIL, bAllocR, pIR);
387             return pResult;
388         }
389
390         if (pL->isScalar())
391         {
392             pResult         = new Bool(pR->getDims(), pR->getDimsArray());
393             int* piResult   = pResult->getAs<Bool>()->get();
394             int iSize       = pR->getSize();
395             int* piRank     = new int[iSize];
396             double dL       = pL->get(0);
397
398             pR->getRank(piRank);
399
400             if (pL->isComplex() && pR->isComplex())
401             {
402                 double dLImg = pL->getImg(0);
403                 for (int i = 0 ; i < iSize; i++)
404                 {
405                     if (piRank[i] == 0)
406                     {
407                         piResult[i] = (int)(dL == pR->get(i)->get(0) &&
408                                             dLImg == pR->get(i)->getImg(0));
409                     }
410                     else
411                     {
412                         piResult[i] = 0;
413                     }
414                 }
415             }
416             else if (pL->isComplex())
417             {
418                 double dLImg = pL->getImg(0);
419                 for (int i = 0 ; i < iSize; i++)
420                 {
421                     if (piRank[i] == 0)
422                     {
423                         piResult[i] = (int)(dL == pR->get(i)->get(0) &&
424                                             dLImg == 0);
425                     }
426                     else
427                     {
428                         piResult[i] = 0;
429                     }
430                 }
431             }
432             else if (pR->isComplex())
433             {
434                 for (int i = 0 ; i < iSize; i++)
435                 {
436                     if (piRank[i] == 0)
437                     {
438                         piResult[i] = (int)(dL == pR->get(i)->get(0) &&
439                                             pR->get(i)->getImg(0) == 0);
440                     }
441                     else
442                     {
443                         piResult[i] = 0;
444                     }
445                 }
446             }
447             else
448             {
449                 for (int i = 0 ; i < iSize; i++)
450                 {
451                     piResult[i] = piRank[i] ? 0 : (int)(dL == pR->get(i)->get(0));
452                 }
453             }
454
455             clearAlloc(bAllocL, pIL, bAllocR, pIR);
456             delete[] piRank;
457             return pResult;
458         }
459
460         if (pL->getDims() != pR->getDims())
461         {
462             clearAlloc(bAllocL, pIL, bAllocR, pIR);
463             return new Bool(false);
464         }
465
466         int* piDims1 = pL->getDimsArray();
467         int* piDims2 = pR->getDimsArray();
468
469         for (int i = 0 ; i < pL->getDims() ; i++)
470         {
471             if (piDims1[i] != piDims2[i])
472             {
473                 clearAlloc(bAllocL, pIL, bAllocR, pIR);
474                 return new Bool(false);
475             }
476         }
477
478         pResult         = new Bool(pL->getDims(), pL->getDimsArray());
479         int* piResult   = pResult->getAs<Bool>()->get();
480         int iSize       = pL->getSize();
481         int* piRank     = new int[iSize];
482         double* pdblL   = pL->get();
483
484         pR->getRank(piRank);
485
486         if (pL->isComplex() && pR->isComplex())
487         {
488             double* pdblLImg = pL->getImg();
489             for (int i = 0 ; i < iSize; i++)
490             {
491                 if (piRank[i] == 0)
492                 {
493                     piResult[i] = (int)(pdblL[i] == pR->get(i)->get(0) &&
494                                         pdblLImg[i] == pR->get(i)->getImg(0));
495                 }
496                 else
497                 {
498                     piResult[i] = 0;
499                 }
500             }
501         }
502         else if (pL->isComplex())
503         {
504             double* pdblLImg = pL->getImg();
505             for (int i = 0 ; i < iSize; i++)
506             {
507                 if (piRank[i] == 0)
508                 {
509                     piResult[i] = (int)(pdblL[i] == pR->get(i)->get(0) &&
510                                         pdblLImg[i] == 0);
511                 }
512                 else
513                 {
514                     piResult[i] = 0;
515                 }
516             }
517         }
518         else if (pR->isComplex())
519         {
520             for (int i = 0 ; i < iSize; i++)
521             {
522                 if (piRank[i] == 0)
523                 {
524                     piResult[i] = (int)(pdblL[i] == pR->get(i)->get(0) &&
525                                         pR->get(i)->getImg(0) == 0);
526                 }
527                 else
528                 {
529                     piResult[i] = 0;
530                 }
531             }
532         }
533         else
534         {
535             for (int i = 0 ; i < iSize; i++)
536             {
537                 piResult[i] = piRank[i] ? 0 : (int)(pdblL[i] == pR->get(i)->get(0));
538             }
539         }
540
541         clearAlloc(bAllocL, pIL, bAllocR, pIR);
542         delete[] piRank;
543         return pResult;
544     }
545
546     /*
547     ** POLY == DOUBLE
548     */
549     if (TypeL == GenericType::ScilabPolynom && TypeR == GenericType::ScilabDouble)
550     {
551         return GenericComparisonEqual(_pRightOperand, _pLeftOperand);
552     }
553
554     /*
555     ** LIST == LIST
556     */
557     if (TypeL == GenericType::ScilabList && TypeR == GenericType::ScilabList)
558     {
559         List* pLL = pIL->getAs<List>();
560         List* pLR = pIR->getAs<List>();
561
562         if (pLL->getSize() != pLR->getSize())
563         {
564             clearAlloc(bAllocL, pIL, bAllocR, pIR);
565             return new Bool(false);
566         }
567
568         if (pLL->getSize() == 0 && pLR->getSize() == 0)
569         {
570             //list() == list() -> return true
571             clearAlloc(bAllocL, pIL, bAllocR, pIR);
572             return new Bool(true);
573         }
574
575         Bool* pB = new Bool(1, pLL->getSize());
576         for (int i = 0 ; i < pLL->getSize() ; i++)
577         {
578             pB->set(i, *pLL->get(i) == *pLR->get(i));
579         }
580
581         clearAlloc(bAllocL, pIL, bAllocR, pIR);
582         return pB;
583     }
584
585     /*
586     ** CELL == CELL
587     */
588     if (TypeL == GenericType::ScilabCell && TypeR == GenericType::ScilabCell)
589     {
590         Cell* pCL = pIL->getAs<Cell>();
591         Cell* pCR = pIR->getAs<Cell>();
592
593         /* check dimension*/
594         if (pCL->getDims() != pCR->getDims())
595         {
596             clearAlloc(bAllocL, pIL, bAllocR, pIR);
597             return new Bool(false);
598         }
599
600         int* piDimsL = pCL->getDimsArray();
601         int* piDimsR = pCR->getDimsArray();
602
603         for (int i = 0 ; i < pCL->getDims() ; i++)
604         {
605             if (piDimsL[i] != piDimsR[i])
606             {
607                 clearAlloc(bAllocL, pIL, bAllocR, pIR);
608                 return new Bool(false);
609             }
610         }
611
612         if (pCL->getSize() == 0)
613         {
614             //{} == {} -> return true
615             clearAlloc(bAllocL, pIL, bAllocR, pIR);
616             return new Bool(true);
617         }
618
619         Bool *pB = new Bool(pCL->getDims(), piDimsL);
620         for (int i = 0 ; i < pCL->getSize() ; i++)
621         {
622             pB->set(i, *pCL->get(i) == *pCR->get(i));
623         }
624
625         clearAlloc(bAllocL, pIL, bAllocR, pIR);
626         return pB;
627     }
628
629     /*
630     ** STRUCT == STRUCT
631     */
632     if (TypeL == GenericType::ScilabStruct && TypeR == GenericType::ScilabStruct)
633     {
634         Struct* pStL = pIL->getAs<Struct>();
635         Struct* pStR = pIR->getAs<Struct>();
636
637         /* check dimension*/
638         if (pStL->getDims() != pStR->getDims())
639         {
640             clearAlloc(bAllocL, pIL, bAllocR, pIR);
641             return new Bool(false);
642         }
643
644         int* piDimsL = pStL->getDimsArray();
645         int* piDimsR = pStR->getDimsArray();
646
647         for (int i = 0 ; i < pStL->getDims() ; i++)
648         {
649             if (piDimsL[i] != piDimsR[i])
650             {
651                 clearAlloc(bAllocL, pIL, bAllocR, pIR);
652                 return new Bool(false);
653             }
654         }
655
656         if (pStL->getSize() == 0)
657         {
658             clearAlloc(bAllocL, pIL, bAllocR, pIR);
659             return new Bool(true);
660         }
661
662         Bool *pB = new Bool(pStL->getDims(), piDimsL);
663         for (int i = 0 ; i < pStL->getSize() ; i++)
664         {
665             pB->set(i, *pStL->get(i) == *pStR->get(i));
666         }
667
668         clearAlloc(bAllocL, pIL, bAllocR, pIR);
669         return pB;
670     }
671
672     /*
673     ** DOUBLE == STRING
674     */
675     if (TypeL == GenericType::ScilabDouble && TypeR == GenericType::ScilabString)
676     {
677         clearAlloc(bAllocL, pIL, bAllocR, pIR);
678         return new Bool(0);
679     }
680
681     /*
682     ** STRING == DOUBLE
683     */
684     if (TypeL == GenericType::ScilabString && TypeR == GenericType::ScilabDouble)
685     {
686         clearAlloc(bAllocL, pIL, bAllocR, pIR);
687         return new Bool(0);
688     }
689
690     /*
691     ** SPARSE == SPARSE
692     */
693     if (TypeL == GenericType::ScilabSparse && TypeR == GenericType::ScilabSparse)
694     {
695         Sparse* pL = pIL->getAs<Sparse>();
696         Sparse* pR = pIR->getAs<Sparse>();
697
698         int iResult = EqualToSparseAndSparse(pL, pR, (GenericType**)&pResult);
699         if (iResult)
700         {
701             clearAlloc(bAllocL, pIL, bAllocR, pIR);
702             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
703         }
704
705         clearAlloc(bAllocL, pIL, bAllocR, pIR);
706         return pResult;
707     }
708
709     /*
710     ** SPARSE == DOUBLE
711     */
712     if (TypeL == GenericType::ScilabSparse && TypeR == GenericType::ScilabDouble)
713     {
714         Sparse* pL = pIL->getAs<Sparse>();
715         Double* pR = pIR->getAs<Double>();
716
717         int iResult = EqualToSparseAndDouble(pL, pR, (GenericType**)&pResult);
718         if (iResult)
719         {
720             clearAlloc(bAllocL, pIL, bAllocR, pIR);
721             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
722         }
723
724         clearAlloc(bAllocL, pIL, bAllocR, pIR);
725         return pResult;
726     }
727
728     /*
729     ** DOUBLE == SPARSE
730     */
731     if (TypeL == GenericType::ScilabDouble && TypeR == GenericType::ScilabSparse)
732     {
733         Double* pL = pIL->getAs<Double>();
734         Sparse* pR = pIR->getAs<Sparse>();
735
736         int iResult = EqualToDoubleAndSparse(pL, pR, (GenericType**)&pResult);
737         if (iResult)
738         {
739             clearAlloc(bAllocL, pIL, bAllocR, pIR);
740             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
741         }
742
743         clearAlloc(bAllocL, pIL, bAllocR, pIR);
744         return pResult;
745     }
746
747     /*
748     ** SPARSE BOOL == SPARSE BOOL
749     */
750     if (TypeL == GenericType::ScilabSparseBool && TypeR == GenericType::ScilabSparseBool)
751     {
752         SparseBool* pL = pIL->getAs<SparseBool>();
753         SparseBool* pR = pIR->getAs<SparseBool>();
754
755         int iResult = EqualToSparseBoolAndSparseBool(pL, pR, (GenericType**)&pResult);
756         if (iResult)
757         {
758             clearAlloc(bAllocL, pIL, bAllocR, pIR);
759             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
760         }
761
762         clearAlloc(bAllocL, pIL, bAllocR, pIR);
763         return pResult;
764     }
765
766     /*
767     ** SPARSE BOOL == BOOL
768     */
769     if (TypeL == GenericType::ScilabSparseBool && TypeR == GenericType::ScilabBool)
770     {
771         SparseBool* pL = pIL->getAs<SparseBool>();
772         Bool* pR = pIR->getAs<Bool>();
773
774         int iResult = EqualToSparseBoolAndBool(pL, pR, (GenericType**)&pResult);
775         if (iResult)
776         {
777             clearAlloc(bAllocL, pIL, bAllocR, pIR);
778             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
779         }
780
781         clearAlloc(bAllocL, pIL, bAllocR, pIR);
782         return pResult;
783     }
784
785     /*
786     ** BOOL == SPARSE BOOL
787     */
788     if (TypeL == GenericType::ScilabBool && TypeR == GenericType::ScilabSparseBool)
789     {
790         Bool* pL = pIL->getAs<Bool>();
791         SparseBool* pR = pIR->getAs<SparseBool>();
792
793         int iResult = EqualToBoolAndSparseBool(pL, pR, (GenericType**)&pResult);
794         if (iResult)
795         {
796             clearAlloc(bAllocL, pIL, bAllocR, pIR);
797             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
798         }
799
800         clearAlloc(bAllocL, pIL, bAllocR, pIR);
801         return pResult;
802     }
803
804     /*
805     ** INT == INT
806     */
807
808     if (pIL->isInt() && pIR->isInt())
809     {
810         if (pIL->getType() != pIR->getType())
811         {
812             //call overload function to convert left or right or both to have comparable type
813             clearAlloc(bAllocL, pIL, bAllocR, pIR);
814             return NULL;
815         }
816
817         int iResult = EqualToIntAndInt(pIL, pIR, (GenericType**)&pResult);
818         if (iResult)
819         {
820             clearAlloc(bAllocL, pIL, bAllocR, pIR);
821             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
822         }
823
824         clearAlloc(bAllocL, pIL, bAllocR, pIR);
825         return pResult;
826     }
827
828     /*
829     ** HANDLE == HANDLE
830     */
831
832     if (pIL->isHandle() && pIR->isHandle())
833     {
834         int iResult = EqualToArrayAndArray(pIL->getAs<GraphicHandle>(), pIR->getAs<GraphicHandle>(), (GenericType**)&pResult);
835         if (iResult)
836         {
837             clearAlloc(bAllocL, pIL, bAllocR, pIR);
838             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
839         }
840
841         clearAlloc(bAllocL, pIL, bAllocR, pIR);
842         return pResult;
843     }
844
845     /*
846     ** TList == TList
847     */
848     if (TypeL == GenericType::ScilabTList && TypeR == GenericType::ScilabTList)
849     {
850         TList* pLL = pIL->getAs<TList>();
851         TList* pLR = pIR->getAs<TList>();
852
853         // check if an overload exists
854         std::wstring function_name;
855         function_name = L"%" + pLL->getShortTypeStr() + L"_o_" + pLR->getShortTypeStr();
856         InternalType* pFunc = symbol::Context::getInstance()->get(symbol::Symbol(function_name));
857
858         if (pFunc)
859         {
860             //call overload
861             return NULL;
862         }
863
864         if (pLL->getSize() != pLR->getSize())
865         {
866             clearAlloc(bAllocL, pIL, bAllocR, pIR);
867             return new Bool(false);
868         }
869
870         if (pLL->getSize() == 0 && pLR->getSize() == 0)
871         {
872             //list() == list() -> return true
873             clearAlloc(bAllocL, pIL, bAllocR, pIR);
874             return new Bool(true);
875         }
876
877         Bool* pB = new Bool(1, pLL->getSize());
878         for (int i = 0 ; i < pLL->getSize() ; i++)
879         {
880             pB->set(i, *pLL->get(i) == *pLR->get(i));
881         }
882
883         clearAlloc(bAllocL, pIL, bAllocR, pIR);
884         return pB;
885     }
886
887
888     /*
889     ** MList == MList
890     */
891     if (TypeL == GenericType::ScilabMList && TypeR == GenericType::ScilabMList)
892     {
893         MList* pLL = pIL->getAs<MList>();
894         MList* pLR = pIR->getAs<MList>();
895
896         // check if an overload exists
897         std::wstring function_name;
898         function_name = L"%" + pLL->getShortTypeStr() + L"_o_" + pLR->getShortTypeStr();
899         InternalType* pFunc = symbol::Context::getInstance()->get(symbol::Symbol(function_name));
900
901         if (pFunc)
902         {
903             //call overload
904             return NULL;
905         }
906
907         if (pLL->getSize() != pLR->getSize())
908         {
909             clearAlloc(bAllocL, pIL, bAllocR, pIR);
910             return new Bool(false);
911         }
912
913         if (pLL->getSize() == 0 && pLR->getSize() == 0)
914         {
915             //list() == list() -> return true
916             clearAlloc(bAllocL, pIL, bAllocR, pIR);
917             return new Bool(true);
918         }
919
920         Bool* pB = new Bool(1, pLL->getSize());
921         for (int i = 0 ; i < pLL->getSize() ; i++)
922         {
923             pB->set(i, *pLL->get(i) == *pLR->get(i));
924         }
925
926         clearAlloc(bAllocL, pIL, bAllocR, pIR);
927         return pB;
928     }
929
930     /*
931     ** MACRO == MACROFILE
932     */
933
934     if (TypeL == GenericType::ScilabMacro || TypeL == GenericType::ScilabMacroFile)
935     {
936         bool ret = false;
937         if (TypeL == GenericType::ScilabMacroFile)
938         {
939             types::MacroFile* pL = _pLeftOperand->getAs<types::MacroFile>();
940             ret = *pL == *_pRightOperand;
941         }
942         else if (TypeL == GenericType::ScilabMacro)
943         {
944             types::Macro* pL = _pLeftOperand->getAs<types::Macro>();
945             if (TypeR == GenericType::ScilabMacroFile)
946             {
947                 types::MacroFile* pR = _pRightOperand->getAs<types::MacroFile>();
948                 ret = *pR == *pL;
949             }
950             else
951             {
952                 ret = *pL == *_pRightOperand;
953             }
954         }
955
956         return new Bool(ret == true ? 1 : 0);
957     }
958
959     /*
960     ** Default case : Return NULL will Call Overloading.
961     */
962     clearAlloc(bAllocL, pIL, bAllocR, pIR);
963     return NULL;
964 }
965
966 int EqualToDoubleAndDouble(types::Double* _pDouble1, types::Double* _pDouble2, types::GenericType** _pOut)
967 {
968     int iFree = 0;
969
970     if (_pDouble1->isEmpty() && _pDouble2->isEmpty())
971     {
972         *_pOut = new Bool(true);
973         return 0;
974     }
975
976     if (_pDouble1->isEmpty() || _pDouble2->isEmpty())
977     {
978         *_pOut = new Bool(false);
979         return 0;
980     }
981
982     if (_pDouble2->isComplex() && _pDouble1->isComplex() == false)
983     {
984         _pDouble1 = _pDouble1->clone()->getAs<Double>();
985         _pDouble1->setComplex(true);
986         iFree = 1;
987     }
988
989     if (_pDouble2->isComplex() == false && _pDouble1->isComplex())
990     {
991         _pDouble2 = _pDouble2->clone()->getAs<Double>();
992         _pDouble2->setComplex(true);
993         iFree = 2;
994     }
995
996     if (_pDouble2->isScalar())
997     {
998         Bool* pB = new Bool(_pDouble1->getDims(), _pDouble1->getDimsArray());
999         double dblRefR = _pDouble2->get(0);
1000
1001         if (_pDouble1->isComplex())
1002         {
1003             double dblRefI = _pDouble2->getImg(0);
1004             for (int i = 0 ; i < _pDouble1->getSize() ; i++)
1005             {
1006                 pB->set(i, (_pDouble1->get(i) == dblRefR) && (_pDouble1->getImg(i) == dblRefI));
1007             }
1008         }
1009         else
1010         {
1011             for (int i = 0 ; i < _pDouble1->getSize() ; i++)
1012             {
1013                 pB->set(i, _pDouble1->get(i) == dblRefR);
1014             }
1015         }
1016
1017         *_pOut = pB;
1018         return 0;
1019     }
1020
1021     if (_pDouble1->isScalar())
1022     {
1023         Bool* pB = new Bool(_pDouble2->getDims(), _pDouble2->getDimsArray());
1024         double dblRefR = _pDouble1->get(0);
1025
1026         if (_pDouble2->isComplex())
1027         {
1028             double dblRefI = _pDouble1->getImg(0);
1029             for (int i = 0 ; i < _pDouble2->getSize() ; i++)
1030             {
1031                 pB->set(i, (dblRefR == _pDouble2->get(i)) && (dblRefI == _pDouble2->getImg(i)));
1032             }
1033         }
1034         else
1035         {
1036             for (int i = 0 ; i < _pDouble2->getSize() ; i++)
1037             {
1038                 pB->set(i, dblRefR == _pDouble2->get(i));
1039             }
1040         }
1041
1042         *_pOut = pB;
1043         return 0;
1044     }
1045
1046
1047     if (_pDouble1->getDims() != _pDouble2->getDims())
1048     {
1049         *_pOut = new Bool(false);
1050         return 0;
1051     }
1052
1053     int* piDimsL = _pDouble1->getDimsArray();
1054     int* piDimsR = _pDouble2->getDimsArray();
1055
1056     for (int i = 0 ; i < _pDouble1->getDims() ; i++)
1057     {
1058         if (piDimsL[i] != piDimsR[i])
1059         {
1060             *_pOut = new Bool(false);
1061             return 0;
1062         }
1063     }
1064
1065     Bool* pB = new Bool(_pDouble2->getDims(), _pDouble2->getDimsArray());
1066     if (_pDouble1->isComplex())
1067     {
1068         for (int i = 0 ; i < _pDouble1->getSize() ; i++)
1069         {
1070             pB->set(i, (_pDouble1->get(i) == _pDouble2->get(i)) && (_pDouble1->getImg(i) == _pDouble2->getImg(i)));
1071         }
1072     }
1073     else
1074     {
1075         for (int i = 0 ; i < _pDouble1->getSize() ; i++)
1076         {
1077             pB->set(i, _pDouble1->get(i) == _pDouble2->get(i));
1078         }
1079     }
1080
1081     if (iFree == 1)
1082     {
1083         delete _pDouble1;
1084     }
1085     else if (iFree == 2)
1086     {
1087         delete _pDouble2;
1088     }
1089
1090     *_pOut = pB;
1091     return 0;
1092 }
1093
1094 int EqualToSparseBoolAndSparseBool(SparseBool* _pSB1, SparseBool* _pSB2, GenericType** _pOut)
1095 {
1096     SparseBool* pOut = NULL;
1097     if (_pSB1->isScalar())
1098     {
1099         pOut = new SparseBool(_pSB2->getRows(), _pSB2->getCols());
1100         bool bVal = _pSB1->get(0, 0);
1101
1102         for (int i = 0 ; i < pOut->getRows() ; i++)
1103         {
1104             for (int j = 0 ; j < pOut->getCols() ; j++)
1105             {
1106                 pOut->set(i, j, bVal == _pSB2->get(i, j));
1107             }
1108         }
1109
1110         pOut->finalize();
1111         *_pOut = pOut;
1112         return 0;
1113     }
1114
1115     if (_pSB2->isScalar())
1116     {
1117         pOut = new SparseBool(_pSB1->getRows(), _pSB1->getCols());
1118         bool bVal = _pSB2->get(0, 0);
1119
1120         for (int i = 0 ; i < pOut->getRows() ; i++)
1121         {
1122             for (int j = 0 ; j < pOut->getCols() ; j++)
1123             {
1124                 pOut->set(i, j, _pSB1->get(i, j) == bVal);
1125             }
1126         }
1127
1128         *_pOut = pOut;
1129         pOut->finalize();
1130         return 0;
1131     }
1132
1133     if (_pSB1->getRows() != _pSB2->getRows() || _pSB1->getCols() != _pSB2->getCols())
1134     {
1135         *_pOut = new Bool(false);
1136         return 0;
1137     }
1138
1139     pOut = new SparseBool(_pSB1->getRows(), _pSB1->getCols());
1140
1141     for (int i = 0 ; i < pOut->getRows() ; i++)
1142     {
1143         for (int j = 0 ; j < pOut->getCols() ; j++)
1144         {
1145             pOut->set(i, j, _pSB1->get(i, j) == _pSB2->get(i, j));
1146         }
1147     }
1148
1149     pOut->finalize();
1150     *_pOut = pOut;
1151     return 0;
1152 }
1153
1154 int EqualToSparseAndSparse(Sparse* _pSparse1, Sparse* _pSparse2, GenericType** _pOut)
1155 {
1156     if ((_pSparse1->getRows() == _pSparse2->getRows() && _pSparse1->getCols() == _pSparse2->getCols()) //matrix case
1157             || _pSparse1->isScalar() || _pSparse2->isScalar()) //scalar cases
1158     {
1159         *_pOut = _pSparse1->newEqualTo(*_pSparse2);
1160     }
1161     else
1162     {
1163         *_pOut = new Bool(false);
1164     }
1165     return 0;
1166 }
1167
1168 int EqualToDoubleAndSparse(Double* _pDouble, Sparse* _pSparse, GenericType** _pOut)
1169 {
1170     Sparse* pSparse = NULL;
1171     if (_pDouble->isScalar())
1172     {
1173         pSparse = new Sparse(_pSparse->getRows(), _pSparse->getCols(), _pDouble->isComplex());
1174         if (pSparse->isComplex())
1175         {
1176             std::complex<double> dbl(_pDouble->get(0), _pDouble->getImg(0));
1177             for (int i = 0 ; i < pSparse->getRows() ; i++)
1178             {
1179                 for (int j = 0 ; j < pSparse->getCols() ; j++)
1180                 {
1181                     pSparse->set(i, j, dbl);
1182                 }
1183             }
1184         }
1185         else
1186         {
1187             double dbl = _pDouble->get(0);
1188             for (int i = 0 ; i < pSparse->getRows() ; i++)
1189             {
1190                 for (int j = 0 ; j < pSparse->getCols() ; j++)
1191                 {
1192                     pSparse->set(i, j, dbl);
1193                 }
1194             }
1195         }
1196     }
1197     else
1198     {
1199         pSparse = new Sparse(*_pDouble);
1200     }
1201
1202     int iRet = EqualToSparseAndSparse(pSparse, _pSparse, _pOut);
1203     delete pSparse;
1204     return iRet;
1205 }
1206
1207 int EqualToSparseAndDouble(Sparse* _pSparse, Double* _pDouble, GenericType** _pOut)
1208 {
1209     return EqualToDoubleAndSparse(_pDouble, _pSparse, _pOut);
1210 }
1211
1212 int EqualToSparseBoolAndBool(SparseBool* _pSB1, Bool* _pB2, GenericType** _pOut)
1213 {
1214     SparseBool* pSB = new SparseBool(*_pB2);
1215     int iRet = EqualToSparseBoolAndSparseBool(_pSB1, pSB, _pOut);
1216     delete pSB;
1217     return iRet;
1218 }
1219
1220 int EqualToBoolAndSparseBool(Bool* _pB1, SparseBool* _pSB2, GenericType** _pOut)
1221 {
1222     SparseBool* pSB = new SparseBool(*_pB1);
1223     int iRet = EqualToSparseBoolAndSparseBool(pSB, _pSB2, _pOut);
1224     delete pSB;
1225     return iRet;
1226 }
1227
1228 template <class T>
1229 static int EqualToArrayAndArray(T* _pL, T* _pR, GenericType** _pOut)
1230 {
1231     if (_pL->isScalar())
1232     {
1233         Bool *pB = new Bool(_pR->getDims(), _pR->getDimsArray());
1234
1235         int* pb = pB->get();
1236         const typename T::type x = _pL->get(0);
1237
1238         for (int i = 0 ; i < pB->getSize() ; i++)
1239         {
1240             pb[i] = x == _pR->get(i);
1241         }
1242
1243         *_pOut = pB;
1244         return 0;
1245     }
1246
1247     if (_pR->isScalar())
1248     {
1249         Bool *pB = new Bool(_pL->getDims(), _pL->getDimsArray());
1250
1251         int* pb = pB->get();
1252         const typename T::type x = _pL->get(0);
1253
1254         for (int i = 0 ; i < pB->getSize() ; i++)
1255         {
1256             pb[i] = x == _pL->get(i);
1257         }
1258
1259         *_pOut = pB;
1260         return 0;
1261     }
1262
1263     if (_pL->getDims() != _pR->getDims())
1264     {
1265         *_pOut = new Bool(false);
1266         return 0;
1267     }
1268
1269     int* piDimsL = _pL->getDimsArray();
1270     int* piDimsR = _pR->getDimsArray();
1271
1272     for (int i = 0 ; i < _pL->getDims() ; i++)
1273     {
1274         if (piDimsL[i] != piDimsR[i])
1275         {
1276             *_pOut = new Bool(false);
1277             return 0;
1278         }
1279     }
1280
1281     Bool* pB = new Bool(_pR->getDims(), _pR->getDimsArray());
1282     for (int i = 0 ; i < _pL->getSize() ; i++)
1283     {
1284         pB->set(i, _pL->get(i) == _pR->get(i));
1285     }
1286
1287     *_pOut = pB;
1288     return 0;
1289 }
1290
1291 int EqualToIntAndInt(InternalType* _pL, InternalType*  _pR, GenericType** _pOut)
1292 {
1293     switch (_pL->getType())
1294     {
1295         case InternalType::ScilabInt8 :
1296         {
1297             return EqualToArrayAndArray(_pL->getAs<Int8>(), _pR->getAs<Int8>(), _pOut);
1298         }
1299         case InternalType::ScilabUInt8 :
1300         {
1301             return EqualToArrayAndArray(_pL->getAs<UInt8>(), _pR->getAs<UInt8>(), _pOut);
1302         }
1303         case InternalType::ScilabInt16 :
1304         {
1305             return EqualToArrayAndArray(_pL->getAs<Int16>(), _pR->getAs<Int16>(), _pOut);
1306         }
1307         case InternalType::ScilabUInt16 :
1308         {
1309             return EqualToArrayAndArray(_pL->getAs<UInt16>(), _pR->getAs<UInt16>(), _pOut);
1310         }
1311         case InternalType::ScilabInt32 :
1312         {
1313             return EqualToArrayAndArray(_pL->getAs<Int32>(), _pR->getAs<Int32>(), _pOut);
1314         }
1315         case InternalType::ScilabUInt32 :
1316         {
1317             return EqualToArrayAndArray(_pL->getAs<UInt32>(), _pR->getAs<UInt32>(), _pOut);
1318         }
1319         case InternalType::ScilabInt64 :
1320         {
1321             return EqualToArrayAndArray(_pL->getAs<Int64>(), _pR->getAs<Int64>(), _pOut);
1322         }
1323         case InternalType::ScilabUInt64 :
1324         {
1325             return EqualToArrayAndArray(_pL->getAs<UInt64>(), _pR->getAs<UInt64>(), _pOut);
1326         }
1327         default:
1328         {
1329             return 3;
1330         }
1331     }
1332 }
1333
1334 static void clearAlloc(bool _bAllocL, InternalType* _pIL, bool _bAllocR, InternalType* _pIR)
1335 {
1336     if (_bAllocL)
1337     {
1338         delete _pIL;
1339     }
1340
1341     if (_bAllocR)
1342     {
1343         delete _pIR;
1344     }
1345 }