macr2tree, tree2code: matrix cell exp. 06/21606/3
Cedric Delamarre [Fri, 23 Oct 2020 09:25:11 +0000 (11:25 +0200)]
  https://bugzilla.scilab.org/show_bug.cgi?id=16297
  https://bugzilla.scilab.org/show_bug.cgi?id=16557

  test_run functions bug_16397  // for both

  this commit manage only cell creation using {}.

Change-Id: If7577584e60855267834fe1e75a701a7bbaf61ad

scilab/CHANGES.md
scilab/modules/ast/includes/ast/treevisitor.hxx
scilab/modules/ast/src/cpp/ast/treevisitor.cpp
scilab/modules/functions/macros/expression2code.sci
scilab/modules/functions/tests/nonreg_tests/bug_16297.tst [new file with mode: 0644]

index cf3ce0a..34e4bd7 100644 (file)
@@ -304,6 +304,7 @@ Bug Fixes
 * [#16193](https://bugzilla.scilab.org/16193): `covStart()` clear previous coverage information. `profileEnable()` could be use to append a macro later on.
 * [#16196](https://bugzilla.scilab.org/16196): `covStart()` help page was incomplete about the API usage.
 * [#16274](https://bugzilla.scilab.org/16274): assert_checkequal() did not considered equal matching Nan or void elements in (nested) containers.
+* [#16297](https://bugzilla.scilab.org/16297): After function test(), e={}, endfunction; macr2tree(test)  crashes Scilab.
 * [#16337](https://bugzilla.scilab.org/16337): The 3rd output of `[U,km,ku] = unique(..)` was not implemented.
 * [#16342](https://bugzilla.scilab.org/16342): `strcat()` was much slower in Scilab 6.0.2.
 * [#16350](https://bugzilla.scilab.org/16350): in if/while conditions, the empty sparse boolean was considered as TRUE.
@@ -340,6 +341,7 @@ Bug Fixes
 * [#16549](https://bugzilla.scilab.org/16549): simple script crashed Scilab in GUI mode.
 * [#16551](https://bugzilla.scilab.org/16551): `num2cell` returned {} for any input array of empty strings.
 * [#16553](https://bugzilla.scilab.org/16553): `unique(["" ""])` returned `["" ""]`.
+* [#16557](https://bugzilla.scilab.org/16557): `macr2tree` + `tree2code` translated `e={2}` into `"e=1"` and `e={2,"ab"}` into `"e=[2,"ab"]"`.
 
 
 ### Bugs fixed in 6.1.0:
index e206f6b..b6e432b 100644 (file)
@@ -62,6 +62,7 @@ public:
     virtual void visit(const NotExp &e);
     virtual void visit(const TransposeExp &e);
     virtual void visit(const FunctionDec &e);
+    virtual void visit(const CellExp &e);
 
     inline types::List* getList()
     {
@@ -73,6 +74,7 @@ public:
     static types::List* createOperation();
     static types::List* createAssign();
     static types::InternalType* getVerbose(const Exp& e);
+    static types::List* matrixOrCellExp(const exps_t& lines, TreeVisitor& me, const std::wstring& what);
 
     types::InternalType* getEOL();
 private:
index c8bb815..9e5bffa 100644 (file)
@@ -17,6 +17,7 @@
 #include "printvisitor.hxx"
 #include "execvisitor.hxx"
 #include "token.hxx"
+#include "cell.hxx"
 
 extern "C"
 {
@@ -154,49 +155,28 @@ void TreeVisitor::visit(const MatrixExp &e)
         return;
     }
 
-    types::List* sub = createOperation();
-    types::List* ope = new types::List();
-
-    int idx = 0;
-    for (auto it : lines)
-    {
-        it->accept(*this);
-
-        if (idx >= 2)
-        {
-            sub->append(ope);
-            ope->killMe();
-            sub->append(new types::String(L"cc"));
+    l = matrixOrCellExp(lines, *this, L"cc");
+}
 
-            //create a new operation
-            //put previous stage in lhs and
-            //result in rhs
-            types::List* subcolcatOperation = createOperation();
-            types::List* subcolcatOperands = new types::List();
-            subcolcatOperands->append(sub);
-            sub->killMe();
-            //add EOL
-            //subcolcatOperands->append(getEOL());
-            types::InternalType* tmp = getList();
-            subcolcatOperands->append(tmp);
-            tmp->killMe();
+void TreeVisitor::visit(const CellExp &e)
+{
+    exps_t lines = e.getLines();
 
-            ope = subcolcatOperands;
-            sub = subcolcatOperation;
-        }
-        else
-        {
-            types::InternalType* tmp = getList();
-            ope->append(tmp);
-            tmp->killMe();
-        }
+    if (lines.size() == 0)
+    {
+        l = createConst(new types::Cell());
+        return;
+    }
 
-        ++idx;
+    if (lines.size() == 1)
+    {
+        lines.front()->accept(*this);
+        types::List* pL = getList();
+        pL->get(pL->getSize() - 1)->getAs<types::String>()->set(0, L"crc");
+        return;
     }
-    sub->append(ope);
-    ope->killMe();
-    sub->append(new types::String(L"cc"));
-    l = sub;
+
+    l = matrixOrCellExp(lines, *this, L"ccc");
 }
 
 void TreeVisitor::visit(const MatrixLineExp &e)
@@ -1102,4 +1082,51 @@ types::InternalType* TreeVisitor::getVerbose(const Exp& e)
         return new types::String(L";");
     }
 }
+
+types::List* TreeVisitor::matrixOrCellExp(const exps_t& lines, TreeVisitor& me, const std::wstring& what)
+{
+    types::List* sub = createOperation();
+    types::List* ope = new types::List();
+
+    int idx = 0;
+    for (auto it : lines)
+    {
+        it->accept(me);
+
+        if (idx >= 2)
+        {
+            sub->append(ope);
+            ope->killMe();
+            sub->append(new types::String(what.data()));
+
+            //create a new operation
+            //put previous stage in lhs and
+            //result in rhs
+            types::List* subcolcatOperation = createOperation();
+            types::List* subcolcatOperands = new types::List();
+            subcolcatOperands->append(sub);
+            sub->killMe();
+            //add EOL
+            //subcolcatOperands->append(getEOL());
+            types::InternalType* tmp = me.getList();
+            subcolcatOperands->append(tmp);
+            tmp->killMe();
+
+            ope = subcolcatOperands;
+            sub = subcolcatOperation;
+        }
+        else
+        {
+            types::InternalType* tmp = me.getList();
+            ope->append(tmp);
+            tmp->killMe();
+        }
+
+        ++idx;
+    }
+    sub->append(ope);
+    ope->killMe();
+    sub->append(new types::String(what.data()));
+    return sub;
+}
 }
index 4b7713e..e634565 100644 (file)
@@ -35,6 +35,13 @@ function C=expression2code(e)
         // ---------
     case "operation" then
         operator=e.operator
+        bracket = ["[", "]"];
+        // if Cell Exp {}
+        if or(operator == ["ccc", "crc"]) then
+            operator = part(operator, 2:$);
+            bracket = ["{", "}"];
+        end
+
         operands=[]
         nb_op=size(e.operands)
         if and(operator<>["cc","cceol"]) then
@@ -62,7 +69,7 @@ function C=expression2code(e)
                     end
                 end
             end
-            C="["+strcat(operands,",")+"]"
+            C=bracket(1)+strcat(operands,",")+bracket(2);
             // Multi-line column concatenation
         elseif operator=="cceol" then
             for i=1:nb_op
@@ -77,7 +84,7 @@ function C=expression2code(e)
                 end
 
                 if i==1 then
-                    C="["
+                    C=bracket(1)
                     if size(opi,"*")>1 then
                         C = [C+opi(1);opi(2:$)]
                     else
@@ -91,12 +98,12 @@ function C=expression2code(e)
                     else
                         C = [C(1:$-1);C($)+opi]
                     end
-                    C($)=C($)+"]"
+                    C($)=C($)+bracket(2)
                 end
             end
             // Column concatenation
         elseif operator=="cc" then
-            C="["
+            C=bracket(1)
             for i=1:nb_op
                 opi=expression2code(e.operands(i))
                 // Delete [ and ] if there are...
@@ -127,7 +134,7 @@ function C=expression2code(e)
                     end
                 end
             end
-            C($)=C($)+"]"
+            C($)=C($)+bracket(2)
             // Extraction
         elseif operator=="ext" then
             if size(e.operands)==1 then
diff --git a/scilab/modules/functions/tests/nonreg_tests/bug_16297.tst b/scilab/modules/functions/tests/nonreg_tests/bug_16297.tst
new file mode 100644 (file)
index 0000000..4bb759b
--- /dev/null
@@ -0,0 +1,32 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2020 - ESI Group - Cedric Delamarre
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+// <-- Non-regression test for bug 16297 -->
+//
+// <-- Bugzilla URL -->
+// https://bugzilla.scilab.org/show_bug.cgi?id=16297
+//
+// <-- Short Description -->
+// After function test(), e={}, endfunction; macr2tree(test)  crashes Scilab
+
+function test()
+    e = {};
+    e = {1,2};
+    e = {1,2;3,4};
+endfunction
+t=macr2tree(test);
+
+result = ["function test()"; ...
+  "e = {};"; ...
+  "e = {1,2};"; ...
+  "e = {1,2;3,4};"; ...
+  "endfunction"; ...
+  "" ];
+
+assert_checkequal(tree2code(t), result);
\ No newline at end of file