ImplicitList creation corrected. 10/15010/4
Cedric Delamarre [Thu, 7 Aug 2014 16:10:03 +0000 (18:10 +0200)]
test_run ast implicitlist

Change-Id: Ia97e43e8708a4010ad54aa8af5f3d5d37656202f

scilab/modules/ast/src/cpp/ast/runvisitor.cpp
scilab/modules/ast/tests/unit_tests/implicitlist.dia.ref
scilab/modules/ast/tests/unit_tests/implicitlist.tst

index 38fe3f3..2f0f076 100644 (file)
@@ -1032,7 +1032,8 @@ void RunVisitorT<T>::visitprivate(const ListExp &e)
 {
     e.start_get().accept(*this);
     GenericType* pITStart = static_cast<GenericType*>(result_get());
-    if (pITStart->getRows() != 1 || pITStart->getCols() != 1 || (pITStart->isDouble() && pITStart->getAs<Double>()->isComplex()))
+    if ((pITStart->getSize() != 1 || (pITStart->isDouble() && pITStart->getAs<Double>()->isComplex())) &&
+            pITStart->isList() == false) // list case => call overload
     {
         pITStart->killMe();
         wchar_t szError[bsiz];
@@ -1043,7 +1044,8 @@ void RunVisitorT<T>::visitprivate(const ListExp &e)
 
     e.step_get().accept(*this);
     GenericType* pITStep = static_cast<GenericType*>(result_get());
-    if (pITStep->getRows() != 1 || pITStep->getCols() != 1 || (pITStep->isDouble() && pITStep->getAs<Double>()->isComplex()))
+    if ((pITStep->getSize() != 1 || (pITStep->isDouble() && pITStep->getAs<Double>()->isComplex())) &&
+            pITStep->isList() == false) // list case => call overload
     {
         pITStart->killMe();
         pITStep->killMe();
@@ -1055,7 +1057,8 @@ void RunVisitorT<T>::visitprivate(const ListExp &e)
 
     e.end_get().accept(*this);
     GenericType* pITEnd = static_cast<GenericType*>(result_get());
-    if (pITEnd->getRows() != 1 || pITEnd->getCols() != 1 || (pITEnd->isDouble() && pITEnd->getAs<Double>()->isComplex()))
+    if ((pITEnd->getSize() != 1 || (pITEnd->isDouble() && pITEnd->getAs<Double>()->isComplex())) &&
+            pITEnd->isList() == false) // list case => call overload
     {
         pITStart->killMe();
         pITStep->killMe();
@@ -1067,93 +1070,66 @@ void RunVisitorT<T>::visitprivate(const ListExp &e)
     InternalType* piEnd = pITEnd;
 
     //check compatibility
+    // double : double : double or poly : poly : poly and mix like double : double : poly
+    if ((piStart->isPoly() || piStart->isDouble()) &&
+            (piStep->isPoly()  || piStep->isDouble())  &&
+            (piEnd->isPoly()   || piEnd->isDouble()))
+    {
+        // No need to kill piStart, ... because Implicit list ctor will incref them
+        result_set(new ImplicitList(piStart, piStep, piEnd));
+        return;
+    }
 
-    //TODO: refactor these if...else..if...
-    if (piStart->isInt())
+    // int : double or int : int
+    if ( piStart->isInt()   &&
+            (piStep->isDouble() || piStep->isInt()) &&
+            piEnd->isInt())
     {
-        //if Step or End are Int too, they must have the same precision
-        if (piStep->isInt())
-        {
-            if (piStep->getType() != piStart->getType())
-            {
-                pITStart->killMe();
-                pITStep->killMe();
-                pITEnd->killMe();
-                throw ScilabError(_W("Undefined operation for the given operands.\n"), 999, e.step_get().location_get());
-            }
-        }
-        else if (piStep->isPoly())
+        // check for same int type int8, int 16 ...
+        if (piStart->getType() == piEnd->getType()  &&
+                (piStart->getType() == piStep->getType() ||
+                 piStep->isDouble()))
         {
-            pITStart->killMe();
-            pITStep->killMe();
-            pITEnd->killMe();
-            throw ScilabError(_W("Undefined operation for the given operands.\n"), 999, e.step_get().location_get());
+            // No need to kill piStart, ... because Implicit list ctor will incref them
+            result_set(new ImplicitList(piStart, piStep, piEnd));
+            return;
         }
+    }
 
+    // Call Overload
+    Callable::ReturnValue Ret;
+    types::typed_list in;
+    types::typed_list out;
 
-        if (piEnd->isInt())
-        {
-            if (piEnd->getType() != piStart->getType())
-            {
-                pITStart->killMe();
-                pITStep->killMe();
-                pITEnd->killMe();
-                throw ScilabError(_W("Undefined operation for the given operands.\n"), 999, e.end_get().location_get());
-            }
-        }
-        else if (piEnd->isPoly())
-        {
-            pITStart->killMe();
-            pITStep->killMe();
-            pITEnd->killMe();
-            throw ScilabError(_W("Undefined operation for the given operands.\n"), 999, e.end_get().location_get());
-        }
-    }
-    else if (piStart->isPoly())
-    {
-        if (piStep->isInt())
-        {
-            pITStart->killMe();
-            pITStep->killMe();
-            pITEnd->killMe();
-            throw ScilabError(_W("Undefined operation for the given operands.\n"), 999, e.step_get().location_get());
-        }
+    piStart->IncreaseRef();
+    piStep->IncreaseRef();
+    piEnd->IncreaseRef();
 
-        if (piEnd->isInt())
-        {
-            pITStart->killMe();
-            pITStep->killMe();
-            pITEnd->killMe();
-            throw ScilabError(_W("Undefined operation for the given operands.\n"), 999, e.end_get().location_get());
-        }
+    in.push_back(piStart);
+    if (e.hasExplicitStep())
+    {
+        // 1:2:4
+        //call overload %typeStart_b_typeEnd
+        in.push_back(piStep);
+        in.push_back(piEnd);
+        Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piStep->getShortTypeStr(), in, 1, out, this, true);
     }
-    else if (piStep->isInt())
+    else
     {
-        //if End is Int too, they must have the same precision
-        if (piEnd->isInt())
-        {
-            if (piEnd->getType() != piStep->getType())
-            {
-                pITStart->killMe();
-                pITStep->killMe();
-                pITEnd->killMe();
-                throw ScilabError(_W("Undefined operation for the given operands.\n"), 999, e.end_get().location_get());
-            }
-        }
+        // 1:2
+        //call overload %typeStart_b_typeStep
+        in.push_back(piEnd);
+        Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piEnd->getShortTypeStr(), in, 1, out, this, true);
     }
-    else if (piStep->isPoly())
+
+    if (Ret != Callable::OK)
     {
-        if (piEnd->isInt())
-        {
-            pITStart->killMe();
-            pITStep->killMe();
-            pITEnd->killMe();
-            throw ScilabError(_W("Undefined operation for the given operands.\n"), 999, e.step_get().location_get());
-        }
+        clean_in_out(in, out);
+        throw ScilabError();
     }
 
-    // No need to kill piStart, ... because Implicit list ctor will incref them
-    result_set(new ImplicitList(piStart, piStep, piEnd));
+    result_set(out);
+    clean_in(in, out);
 }
 
 #include "run_CallExp.cpp"
index 0764bb5..e8996ad 100644 (file)
@@ -9,6 +9,9 @@
 //
 //
 // <-- JVM NOT MANDATORY -->
+function checkCallOverload(mat)
+    assert_checkerror(mat, [], 144);
+endfunction
 // normal cases
 assert_checkequal(1:3, [1 2 3]);
 assert_checkequal(1:1:3, [1 2 3]);
@@ -31,3 +34,70 @@ assert_checkequal(-%inf:1, %nan);
 assert_checkequal(10:%inf:1, []);
 assert_checkequal(10:%nan:1, %nan);
 assert_checkequal(10:-%inf:1, %nan);
+// int
+i1 = int8(1);
+i2 = int8(2);
+i8 = int8(8);
+assert_checkequal(i1:i2:i8, int8([1,3,5,7]));
+checkCallOverload("i1:i2:8");
+assert_checkequal(i1:2:i8,  int8([1,3,5,7]));
+assert_checkequal(i1:2:8,   int8([1,3,5,7]));
+assert_checkequal(1:i2:i8,  int8([1,3,5,7]));
+assert_checkequal(1:i2:8,   int8([1,3,5,7]));
+assert_checkequal(1:2:i8,   int8([1,3,5,7]));
+assert_checkequal(1:2:8,    [1,3,5,7]);
+assert_checkequal(i1:i8, int8(1:8));
+assert_checkequal(i1:8,  int8(1:8));
+assert_checkequal(1:i8,  int8(1:8));
+assert_checkequal(1:8,   [1 2 3 4 5 6 7 8]);
+ii1 = int16(1);
+ii2 = int16(2);
+ii8 = int16(8);
+assert_checkequal(i1:i2:i8, int8([1,3,5,7]));
+checkCallOverload("i1:i2:ii8");
+checkCallOverload("i1:ii2:i8");
+checkCallOverload("i1:ii2:ii8");
+checkCallOverload("ii1:i2:i8");
+checkCallOverload("ii1:i2:ii8");
+checkCallOverload("ii1:ii2:i8");
+assert_checkequal(ii1:ii2:ii8, int16([1,3,5,7]));
+// bool
+t = %t;
+checkCallOverload("t:t:t");
+checkCallOverload("t:t:8");
+checkCallOverload("t:2:%t");
+checkCallOverload("t:2:8");
+checkCallOverload("1:t:%t");
+checkCallOverload("1:t:8");
+assert_checkerror("1:2:t", [], 10000);
+// poly
+assert_checktrue(execstr("$:$:$", "errcatch") == 0);
+assert_checktrue(execstr("$:$:8", "errcatch") == 0);
+assert_checktrue(execstr("$:2:$", "errcatch") == 0);
+assert_checktrue(execstr("$:2:8", "errcatch") == 0);
+assert_checktrue(execstr("1:$:$", "errcatch") == 0);
+assert_checktrue(execstr("1:$:8", "errcatch") == 0);
+assert_checktrue(execstr("1:2:$", "errcatch") == 0);
+assert_checktrue(execstr("1:2:8", "errcatch") == 0);
+assert_checktrue(execstr("$:$", "errcatch") == 0);
+assert_checktrue(execstr("$:8", "errcatch") == 0);
+assert_checktrue(execstr("2:$", "errcatch") == 0);
+assert_checktrue(execstr("2:8", "errcatch") == 0);
+// rational
+t = 1/%s;
+checkCallOverload("t:t:t");
+checkCallOverload("t:t:8");
+checkCallOverload("t:2:%t");
+checkCallOverload("t:2:8");
+checkCallOverload("1:t:%t");
+checkCallOverload("1:t:8");
+assert_checkerror("1:2:t", [], 10000);
+// rational
+t = list();
+checkCallOverload("t:t:t");
+checkCallOverload("t:t:8");
+checkCallOverload("t:2:%t");
+checkCallOverload("t:2:8");
+checkCallOverload("1:t:%t");
+checkCallOverload("1:t:8");
+assert_checkerror("1:2:t", [], 10000);
index 21bf234..e3a5e20 100644 (file)
 
 // <-- JVM NOT MANDATORY -->
 
+function checkCallOverload(mat)
+    assert_checkerror(mat, [], 144);
+endfunction
+
 // normal cases
 assert_checkequal(1:3, [1 2 3]);
 assert_checkequal(1:1:3, [1 2 3]);
@@ -37,3 +41,85 @@ assert_checkequal(-%inf:1, %nan);
 assert_checkequal(10:%inf:1, []);
 assert_checkequal(10:%nan:1, %nan);
 assert_checkequal(10:-%inf:1, %nan);
+
+// int
+i1 = int8(1);
+i2 = int8(2);
+i8 = int8(8);
+
+assert_checkequal(i1:i2:i8, int8([1,3,5,7]));
+checkCallOverload("i1:i2:8");
+assert_checkequal(i1:2:i8,  int8([1,3,5,7]));
+assert_checkequal(i1:2:8,   int8([1,3,5,7]));
+assert_checkequal(1:i2:i8,  int8([1,3,5,7]));
+assert_checkequal(1:i2:8,   int8([1,3,5,7]));
+assert_checkequal(1:2:i8,   int8([1,3,5,7]));
+assert_checkequal(1:2:8,    [1,3,5,7]);
+
+assert_checkequal(i1:i8, int8(1:8));
+assert_checkequal(i1:8,  int8(1:8));
+assert_checkequal(1:i8,  int8(1:8));
+assert_checkequal(1:8,   [1 2 3 4 5 6 7 8]);
+
+ii1 = int16(1);
+ii2 = int16(2);
+ii8 = int16(8);
+
+assert_checkequal(i1:i2:i8, int8([1,3,5,7]));
+checkCallOverload("i1:i2:ii8");
+checkCallOverload("i1:ii2:i8");
+checkCallOverload("i1:ii2:ii8");
+checkCallOverload("ii1:i2:i8");
+checkCallOverload("ii1:i2:ii8");
+checkCallOverload("ii1:ii2:i8");
+assert_checkequal(ii1:ii2:ii8, int16([1,3,5,7]));
+
+// bool
+t = %t;
+checkCallOverload("t:t:t");
+checkCallOverload("t:t:8");
+checkCallOverload("t:2:%t");
+checkCallOverload("t:2:8");
+checkCallOverload("1:t:%t");
+checkCallOverload("1:t:8");
+assert_checkerror("1:2:t", [], 10000);
+
+// poly
+assert_checktrue(execstr("$:$:$", "errcatch") == 0);
+assert_checktrue(execstr("$:$:8", "errcatch") == 0);
+assert_checktrue(execstr("$:2:$", "errcatch") == 0);
+assert_checktrue(execstr("$:2:8", "errcatch") == 0);
+assert_checktrue(execstr("1:$:$", "errcatch") == 0);
+assert_checktrue(execstr("1:$:8", "errcatch") == 0);
+assert_checktrue(execstr("1:2:$", "errcatch") == 0);
+assert_checktrue(execstr("1:2:8", "errcatch") == 0);
+
+assert_checktrue(execstr("$:$", "errcatch") == 0);
+assert_checktrue(execstr("$:8", "errcatch") == 0);
+assert_checktrue(execstr("2:$", "errcatch") == 0);
+assert_checktrue(execstr("2:8", "errcatch") == 0);
+
+// rational
+t = 1/%s;
+checkCallOverload("t:t:t");
+checkCallOverload("t:t:8");
+checkCallOverload("t:2:%t");
+checkCallOverload("t:2:8");
+checkCallOverload("1:t:%t");
+checkCallOverload("1:t:8");
+assert_checkerror("1:2:t", [], 10000);
+
+// rational
+t = list();
+checkCallOverload("t:t:t");
+checkCallOverload("t:t:8");
+checkCallOverload("t:2:%t");
+checkCallOverload("t:2:8");
+checkCallOverload("1:t:%t");
+checkCallOverload("1:t:8");
+assert_checkerror("1:2:t", [], 10000);
+
+
+
+
+