bbed83d8079a000a034c3b189aecaf7217cbf4da
[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 (pIL->isList() && pIR->isList())
558     {
559         List* pLL = pIL->getAs<List>();
560         List* pLR = pIR->getAs<List>();
561
562         // check if an overload exists
563         if (TypeL == GenericType::ScilabMList ||
564                 TypeL == GenericType::ScilabTList ||
565                 TypeR == GenericType::ScilabMList ||
566                 TypeR == GenericType::ScilabTList)
567         {
568             std::wstring function_name;
569             function_name = L"%" + pLL->getShortTypeStr() + L"_o_" + pLR->getShortTypeStr();
570             InternalType* pFunc = symbol::Context::getInstance()->get(symbol::Symbol(function_name));
571
572             if (pFunc)
573             {
574                 //call overload
575                 return NULL;
576             }
577         }
578
579         if (pLL->getSize() != pLR->getSize())
580         {
581             clearAlloc(bAllocL, pIL, bAllocR, pIR);
582             return new Bool(false);
583         }
584
585         if (pLL->getSize() == 0 && pLR->getSize() == 0)
586         {
587             //list() == list() -> return true
588             clearAlloc(bAllocL, pIL, bAllocR, pIR);
589             return new Bool(true);
590         }
591
592         Bool* pB = new Bool(1, pLL->getSize());
593         for (int i = 0 ; i < pLL->getSize() ; i++)
594         {
595             pB->set(i, ((*pLL->get(i) == *pLR->get(i)) && (pLL->get(i)->getType() != types::InternalType::ScilabVoid)));
596         }
597
598         clearAlloc(bAllocL, pIL, bAllocR, pIR);
599         return pB;
600     }
601
602     /*
603     ** CELL == CELL
604     */
605     if (TypeL == GenericType::ScilabCell && TypeR == GenericType::ScilabCell)
606     {
607         Cell* pCL = pIL->getAs<Cell>();
608         Cell* pCR = pIR->getAs<Cell>();
609
610         /* check dimension*/
611         if (pCL->getDims() != pCR->getDims())
612         {
613             clearAlloc(bAllocL, pIL, bAllocR, pIR);
614             return new Bool(false);
615         }
616
617         int* piDimsL = pCL->getDimsArray();
618         int* piDimsR = pCR->getDimsArray();
619
620         for (int i = 0 ; i < pCL->getDims() ; i++)
621         {
622             if (piDimsL[i] != piDimsR[i])
623             {
624                 clearAlloc(bAllocL, pIL, bAllocR, pIR);
625                 return new Bool(false);
626             }
627         }
628
629         if (pCL->getSize() == 0)
630         {
631             //{} == {} -> return true
632             clearAlloc(bAllocL, pIL, bAllocR, pIR);
633             return new Bool(true);
634         }
635
636         Bool *pB = new Bool(pCL->getDims(), piDimsL);
637         for (int i = 0 ; i < pCL->getSize() ; i++)
638         {
639             pB->set(i, *pCL->get(i) == *pCR->get(i));
640         }
641
642         clearAlloc(bAllocL, pIL, bAllocR, pIR);
643         return pB;
644     }
645
646     /*
647     ** STRUCT == STRUCT
648     */
649     if (TypeL == GenericType::ScilabStruct && TypeR == GenericType::ScilabStruct)
650     {
651         Struct* pStL = pIL->getAs<Struct>();
652         Struct* pStR = pIR->getAs<Struct>();
653
654         /* check dimension*/
655         if (pStL->getDims() != pStR->getDims())
656         {
657             clearAlloc(bAllocL, pIL, bAllocR, pIR);
658             return new Bool(false);
659         }
660
661         int* piDimsL = pStL->getDimsArray();
662         int* piDimsR = pStR->getDimsArray();
663
664         for (int i = 0 ; i < pStL->getDims() ; i++)
665         {
666             if (piDimsL[i] != piDimsR[i])
667             {
668                 clearAlloc(bAllocL, pIL, bAllocR, pIR);
669                 return new Bool(false);
670             }
671         }
672
673         if (pStL->getSize() == 0)
674         {
675             clearAlloc(bAllocL, pIL, bAllocR, pIR);
676             return new Bool(true);
677         }
678
679         Bool *pB = new Bool(pStL->getDims(), piDimsL);
680         for (int i = 0 ; i < pStL->getSize() ; i++)
681         {
682             pB->set(i, *pStL->get(i) == *pStR->get(i));
683         }
684
685         clearAlloc(bAllocL, pIL, bAllocR, pIR);
686         return pB;
687     }
688
689     /*
690     ** DOUBLE == STRING
691     */
692     if (TypeL == GenericType::ScilabDouble && TypeR == GenericType::ScilabString)
693     {
694         clearAlloc(bAllocL, pIL, bAllocR, pIR);
695         return new Bool(0);
696     }
697
698     /*
699     ** STRING == DOUBLE
700     */
701     if (TypeL == GenericType::ScilabString && TypeR == GenericType::ScilabDouble)
702     {
703         clearAlloc(bAllocL, pIL, bAllocR, pIR);
704         return new Bool(0);
705     }
706
707     /*
708     ** SPARSE == SPARSE
709     */
710     if (TypeL == GenericType::ScilabSparse && TypeR == GenericType::ScilabSparse)
711     {
712         Sparse* pL = pIL->getAs<Sparse>();
713         Sparse* pR = pIR->getAs<Sparse>();
714
715         int iResult = EqualToSparseAndSparse(pL, pR, (GenericType**)&pResult);
716         if (iResult)
717         {
718             clearAlloc(bAllocL, pIL, bAllocR, pIR);
719             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
720         }
721
722         clearAlloc(bAllocL, pIL, bAllocR, pIR);
723         return pResult;
724     }
725
726     /*
727     ** SPARSE == DOUBLE
728     */
729     if (TypeL == GenericType::ScilabSparse && TypeR == GenericType::ScilabDouble)
730     {
731         Sparse* pL = pIL->getAs<Sparse>();
732         Double* pR = pIR->getAs<Double>();
733
734         int iResult = EqualToSparseAndDouble(pL, pR, (GenericType**)&pResult);
735         if (iResult)
736         {
737             clearAlloc(bAllocL, pIL, bAllocR, pIR);
738             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
739         }
740
741         clearAlloc(bAllocL, pIL, bAllocR, pIR);
742         return pResult;
743     }
744
745     /*
746     ** DOUBLE == SPARSE
747     */
748     if (TypeL == GenericType::ScilabDouble && TypeR == GenericType::ScilabSparse)
749     {
750         Double* pL = pIL->getAs<Double>();
751         Sparse* pR = pIR->getAs<Sparse>();
752
753         int iResult = EqualToDoubleAndSparse(pL, pR, (GenericType**)&pResult);
754         if (iResult)
755         {
756             clearAlloc(bAllocL, pIL, bAllocR, pIR);
757             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
758         }
759
760         clearAlloc(bAllocL, pIL, bAllocR, pIR);
761         return pResult;
762     }
763
764     /*
765     ** SPARSE BOOL == SPARSE BOOL
766     */
767     if (TypeL == GenericType::ScilabSparseBool && TypeR == GenericType::ScilabSparseBool)
768     {
769         SparseBool* pL = pIL->getAs<SparseBool>();
770         SparseBool* pR = pIR->getAs<SparseBool>();
771
772         int iResult = EqualToSparseBoolAndSparseBool(pL, pR, (GenericType**)&pResult);
773         if (iResult)
774         {
775             clearAlloc(bAllocL, pIL, bAllocR, pIR);
776             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
777         }
778
779         clearAlloc(bAllocL, pIL, bAllocR, pIR);
780         return pResult;
781     }
782
783     /*
784     ** SPARSE BOOL == BOOL
785     */
786     if (TypeL == GenericType::ScilabSparseBool && TypeR == GenericType::ScilabBool)
787     {
788         SparseBool* pL = pIL->getAs<SparseBool>();
789         Bool* pR = pIR->getAs<Bool>();
790
791         int iResult = EqualToSparseBoolAndBool(pL, pR, (GenericType**)&pResult);
792         if (iResult)
793         {
794             clearAlloc(bAllocL, pIL, bAllocR, pIR);
795             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
796         }
797
798         clearAlloc(bAllocL, pIL, bAllocR, pIR);
799         return pResult;
800     }
801
802     /*
803     ** BOOL == SPARSE BOOL
804     */
805     if (TypeL == GenericType::ScilabBool && TypeR == GenericType::ScilabSparseBool)
806     {
807         Bool* pL = pIL->getAs<Bool>();
808         SparseBool* pR = pIR->getAs<SparseBool>();
809
810         int iResult = EqualToBoolAndSparseBool(pL, pR, (GenericType**)&pResult);
811         if (iResult)
812         {
813             clearAlloc(bAllocL, pIL, bAllocR, pIR);
814             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
815         }
816
817         clearAlloc(bAllocL, pIL, bAllocR, pIR);
818         return pResult;
819     }
820
821     /*
822     ** INT == INT
823     */
824
825     if (pIL->isInt() && pIR->isInt())
826     {
827         if (pIL->getType() != pIR->getType())
828         {
829             //call overload function to convert left or right or both to have comparable type
830             clearAlloc(bAllocL, pIL, bAllocR, pIR);
831             return NULL;
832         }
833
834         int iResult = EqualToIntAndInt(pIL, pIR, (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     ** HANDLE == HANDLE
847     */
848
849     if (pIL->isHandle() && pIR->isHandle())
850     {
851         int iResult = EqualToArrayAndArray(pIL->getAs<GraphicHandle>(), pIR->getAs<GraphicHandle>(), (GenericType**)&pResult);
852         if (iResult)
853         {
854             clearAlloc(bAllocL, pIL, bAllocR, pIR);
855             throw ast::ScilabError(_W("Inconsistent row/column dimensions.\n"));
856         }
857
858         clearAlloc(bAllocL, pIL, bAllocR, pIR);
859         return pResult;
860     }
861
862     /*
863     ** MACRO == MACROFILE
864     */
865
866     if (TypeL == GenericType::ScilabMacro || TypeL == GenericType::ScilabMacroFile)
867     {
868         bool ret = false;
869         if (TypeL == GenericType::ScilabMacroFile)
870         {
871             types::MacroFile* pL = _pLeftOperand->getAs<types::MacroFile>();
872             ret = *pL == *_pRightOperand;
873         }
874         else if (TypeL == GenericType::ScilabMacro)
875         {
876             types::Macro* pL = _pLeftOperand->getAs<types::Macro>();
877             if (TypeR == GenericType::ScilabMacroFile)
878             {
879                 types::MacroFile* pR = _pRightOperand->getAs<types::MacroFile>();
880                 ret = *pR == *pL;
881             }
882             else
883             {
884                 ret = *pL == *_pRightOperand;
885             }
886         }
887
888         return new Bool(ret == true ? 1 : 0);
889     }
890
891     /*
892     ** Default case : Return NULL will Call Overloading.
893     */
894     clearAlloc(bAllocL, pIL, bAllocR, pIR);
895     return NULL;
896 }
897
898 int EqualToDoubleAndDouble(types::Double* _pDouble1, types::Double* _pDouble2, types::GenericType** _pOut)
899 {
900     int iFree = 0;
901
902     if (_pDouble1->isEmpty() && _pDouble2->isEmpty())
903     {
904         *_pOut = new Bool(true);
905         return 0;
906     }
907
908     if (_pDouble1->isEmpty() || _pDouble2->isEmpty())
909     {
910         *_pOut = new Bool(false);
911         return 0;
912     }
913
914     if (_pDouble2->isComplex() && _pDouble1->isComplex() == false)
915     {
916         _pDouble1 = _pDouble1->clone()->getAs<Double>();
917         _pDouble1->setComplex(true);
918         iFree = 1;
919     }
920
921     if (_pDouble2->isComplex() == false && _pDouble1->isComplex())
922     {
923         _pDouble2 = _pDouble2->clone()->getAs<Double>();
924         _pDouble2->setComplex(true);
925         iFree = 2;
926     }
927
928     if (_pDouble2->isScalar())
929     {
930         Bool* pB = new Bool(_pDouble1->getDims(), _pDouble1->getDimsArray());
931         double dblRefR = _pDouble2->get(0);
932
933         if (_pDouble1->isComplex())
934         {
935             double dblRefI = _pDouble2->getImg(0);
936             for (int i = 0 ; i < _pDouble1->getSize() ; i++)
937             {
938                 pB->set(i, (_pDouble1->get(i) == dblRefR) && (_pDouble1->getImg(i) == dblRefI));
939             }
940         }
941         else
942         {
943             for (int i = 0 ; i < _pDouble1->getSize() ; i++)
944             {
945                 pB->set(i, _pDouble1->get(i) == dblRefR);
946             }
947         }
948
949         *_pOut = pB;
950         return 0;
951     }
952
953     if (_pDouble1->isScalar())
954     {
955         Bool* pB = new Bool(_pDouble2->getDims(), _pDouble2->getDimsArray());
956         double dblRefR = _pDouble1->get(0);
957
958         if (_pDouble2->isComplex())
959         {
960             double dblRefI = _pDouble1->getImg(0);
961             for (int i = 0 ; i < _pDouble2->getSize() ; i++)
962             {
963                 pB->set(i, (dblRefR == _pDouble2->get(i)) && (dblRefI == _pDouble2->getImg(i)));
964             }
965         }
966         else
967         {
968             for (int i = 0 ; i < _pDouble2->getSize() ; i++)
969             {
970                 pB->set(i, dblRefR == _pDouble2->get(i));
971             }
972         }
973
974         *_pOut = pB;
975         return 0;
976     }
977
978
979     if (_pDouble1->getDims() != _pDouble2->getDims())
980     {
981         *_pOut = new Bool(false);
982         return 0;
983     }
984
985     int* piDimsL = _pDouble1->getDimsArray();
986     int* piDimsR = _pDouble2->getDimsArray();
987
988     for (int i = 0 ; i < _pDouble1->getDims() ; i++)
989     {
990         if (piDimsL[i] != piDimsR[i])
991         {
992             *_pOut = new Bool(false);
993             return 0;
994         }
995     }
996
997     Bool* pB = new Bool(_pDouble2->getDims(), _pDouble2->getDimsArray());
998     if (_pDouble1->isComplex())
999     {
1000         for (int i = 0 ; i < _pDouble1->getSize() ; i++)
1001         {
1002             pB->set(i, (_pDouble1->get(i) == _pDouble2->get(i)) && (_pDouble1->getImg(i) == _pDouble2->getImg(i)));
1003         }
1004     }
1005     else
1006     {
1007         for (int i = 0 ; i < _pDouble1->getSize() ; i++)
1008         {
1009             pB->set(i, _pDouble1->get(i) == _pDouble2->get(i));
1010         }
1011     }
1012
1013     if (iFree == 1)
1014     {
1015         delete _pDouble1;
1016     }
1017     else if (iFree == 2)
1018     {
1019         delete _pDouble2;
1020     }
1021
1022     *_pOut = pB;
1023     return 0;
1024 }
1025
1026 int EqualToSparseBoolAndSparseBool(SparseBool* _pSB1, SparseBool* _pSB2, GenericType** _pOut)
1027 {
1028     SparseBool* pOut = NULL;
1029     if (_pSB1->isScalar())
1030     {
1031         pOut = new SparseBool(_pSB2->getRows(), _pSB2->getCols());
1032         bool bVal = _pSB1->get(0, 0);
1033
1034         for (int i = 0 ; i < pOut->getRows() ; i++)
1035         {
1036             for (int j = 0 ; j < pOut->getCols() ; j++)
1037             {
1038                 pOut->set(i, j, bVal == _pSB2->get(i, j));
1039             }
1040         }
1041
1042         pOut->finalize();
1043         *_pOut = pOut;
1044         return 0;
1045     }
1046
1047     if (_pSB2->isScalar())
1048     {
1049         pOut = new SparseBool(_pSB1->getRows(), _pSB1->getCols());
1050         bool bVal = _pSB2->get(0, 0);
1051
1052         for (int i = 0 ; i < pOut->getRows() ; i++)
1053         {
1054             for (int j = 0 ; j < pOut->getCols() ; j++)
1055             {
1056                 pOut->set(i, j, _pSB1->get(i, j) == bVal);
1057             }
1058         }
1059
1060         *_pOut = pOut;
1061         pOut->finalize();
1062         return 0;
1063     }
1064
1065     if (_pSB1->getRows() != _pSB2->getRows() || _pSB1->getCols() != _pSB2->getCols())
1066     {
1067         *_pOut = new Bool(false);
1068         return 0;
1069     }
1070
1071     pOut = new SparseBool(_pSB1->getRows(), _pSB1->getCols());
1072
1073     for (int i = 0 ; i < pOut->getRows() ; i++)
1074     {
1075         for (int j = 0 ; j < pOut->getCols() ; j++)
1076         {
1077             pOut->set(i, j, _pSB1->get(i, j) == _pSB2->get(i, j));
1078         }
1079     }
1080
1081     pOut->finalize();
1082     *_pOut = pOut;
1083     return 0;
1084 }
1085
1086 int EqualToSparseAndSparse(Sparse* _pSparse1, Sparse* _pSparse2, GenericType** _pOut)
1087 {
1088     if ((_pSparse1->getRows() == _pSparse2->getRows() && _pSparse1->getCols() == _pSparse2->getCols()) //matrix case
1089             || _pSparse1->isScalar() || _pSparse2->isScalar()) //scalar cases
1090     {
1091         *_pOut = _pSparse1->newEqualTo(*_pSparse2);
1092     }
1093     else
1094     {
1095         *_pOut = new Bool(false);
1096     }
1097     return 0;
1098 }
1099
1100 int EqualToDoubleAndSparse(Double* _pDouble, Sparse* _pSparse, GenericType** _pOut)
1101 {
1102     Sparse* pSparse = NULL;
1103     if (_pDouble->isScalar())
1104     {
1105         pSparse = new Sparse(_pSparse->getRows(), _pSparse->getCols(), _pDouble->isComplex());
1106         if (pSparse->isComplex())
1107         {
1108             std::complex<double> dbl(_pDouble->get(0), _pDouble->getImg(0));
1109             for (int i = 0 ; i < pSparse->getRows() ; i++)
1110             {
1111                 for (int j = 0 ; j < pSparse->getCols() ; j++)
1112                 {
1113                     pSparse->set(i, j, dbl);
1114                 }
1115             }
1116         }
1117         else
1118         {
1119             double dbl = _pDouble->get(0);
1120             for (int i = 0 ; i < pSparse->getRows() ; i++)
1121             {
1122                 for (int j = 0 ; j < pSparse->getCols() ; j++)
1123                 {
1124                     pSparse->set(i, j, dbl);
1125                 }
1126             }
1127         }
1128     }
1129     else
1130     {
1131         pSparse = new Sparse(*_pDouble);
1132     }
1133
1134     int iRet = EqualToSparseAndSparse(pSparse, _pSparse, _pOut);
1135     delete pSparse;
1136     return iRet;
1137 }
1138
1139 int EqualToSparseAndDouble(Sparse* _pSparse, Double* _pDouble, GenericType** _pOut)
1140 {
1141     return EqualToDoubleAndSparse(_pDouble, _pSparse, _pOut);
1142 }
1143
1144 int EqualToSparseBoolAndBool(SparseBool* _pSB1, Bool* _pB2, GenericType** _pOut)
1145 {
1146     SparseBool* pSB = new SparseBool(*_pB2);
1147     int iRet = EqualToSparseBoolAndSparseBool(_pSB1, pSB, _pOut);
1148     delete pSB;
1149     return iRet;
1150 }
1151
1152 int EqualToBoolAndSparseBool(Bool* _pB1, SparseBool* _pSB2, GenericType** _pOut)
1153 {
1154     SparseBool* pSB = new SparseBool(*_pB1);
1155     int iRet = EqualToSparseBoolAndSparseBool(pSB, _pSB2, _pOut);
1156     delete pSB;
1157     return iRet;
1158 }
1159
1160 template <class T>
1161 static int EqualToArrayAndArray(T* _pL, T* _pR, GenericType** _pOut)
1162 {
1163     if (_pL->isScalar())
1164     {
1165         Bool *pB = new Bool(_pR->getDims(), _pR->getDimsArray());
1166
1167         int* pb = pB->get();
1168         const typename T::type x = _pL->get(0);
1169
1170         for (int i = 0 ; i < pB->getSize() ; i++)
1171         {
1172             pb[i] = x == _pR->get(i);
1173         }
1174
1175         *_pOut = pB;
1176         return 0;
1177     }
1178
1179     if (_pR->isScalar())
1180     {
1181         Bool *pB = new Bool(_pL->getDims(), _pL->getDimsArray());
1182
1183         int* pb = pB->get();
1184         const typename T::type x = _pL->get(0);
1185
1186         for (int i = 0 ; i < pB->getSize() ; i++)
1187         {
1188             pb[i] = x == _pL->get(i);
1189         }
1190
1191         *_pOut = pB;
1192         return 0;
1193     }
1194
1195     if (_pL->getDims() != _pR->getDims())
1196     {
1197         *_pOut = new Bool(false);
1198         return 0;
1199     }
1200
1201     int* piDimsL = _pL->getDimsArray();
1202     int* piDimsR = _pR->getDimsArray();
1203
1204     for (int i = 0 ; i < _pL->getDims() ; i++)
1205     {
1206         if (piDimsL[i] != piDimsR[i])
1207         {
1208             *_pOut = new Bool(false);
1209             return 0;
1210         }
1211     }
1212
1213     Bool* pB = new Bool(_pR->getDims(), _pR->getDimsArray());
1214     for (int i = 0 ; i < _pL->getSize() ; i++)
1215     {
1216         pB->set(i, _pL->get(i) == _pR->get(i));
1217     }
1218
1219     *_pOut = pB;
1220     return 0;
1221 }
1222
1223 int EqualToIntAndInt(InternalType* _pL, InternalType*  _pR, GenericType** _pOut)
1224 {
1225     switch (_pL->getType())
1226     {
1227         case InternalType::ScilabInt8 :
1228         {
1229             return EqualToArrayAndArray(_pL->getAs<Int8>(), _pR->getAs<Int8>(), _pOut);
1230         }
1231         case InternalType::ScilabUInt8 :
1232         {
1233             return EqualToArrayAndArray(_pL->getAs<UInt8>(), _pR->getAs<UInt8>(), _pOut);
1234         }
1235         case InternalType::ScilabInt16 :
1236         {
1237             return EqualToArrayAndArray(_pL->getAs<Int16>(), _pR->getAs<Int16>(), _pOut);
1238         }
1239         case InternalType::ScilabUInt16 :
1240         {
1241             return EqualToArrayAndArray(_pL->getAs<UInt16>(), _pR->getAs<UInt16>(), _pOut);
1242         }
1243         case InternalType::ScilabInt32 :
1244         {
1245             return EqualToArrayAndArray(_pL->getAs<Int32>(), _pR->getAs<Int32>(), _pOut);
1246         }
1247         case InternalType::ScilabUInt32 :
1248         {
1249             return EqualToArrayAndArray(_pL->getAs<UInt32>(), _pR->getAs<UInt32>(), _pOut);
1250         }
1251         case InternalType::ScilabInt64 :
1252         {
1253             return EqualToArrayAndArray(_pL->getAs<Int64>(), _pR->getAs<Int64>(), _pOut);
1254         }
1255         case InternalType::ScilabUInt64 :
1256         {
1257             return EqualToArrayAndArray(_pL->getAs<UInt64>(), _pR->getAs<UInt64>(), _pOut);
1258         }
1259         default:
1260         {
1261             return 3;
1262         }
1263     }
1264 }
1265
1266 static void clearAlloc(bool _bAllocL, InternalType* _pIL, bool _bAllocR, InternalType* _pIR)
1267 {
1268     if (_bAllocL)
1269     {
1270         delete _pIL;
1271     }
1272
1273     if (_bAllocR)
1274     {
1275         delete _pIR;
1276     }
1277 }