Analysis: add info about $ and fix bug 83/17283/3
Calixte DENIZET [Mon, 5 Oct 2015 18:43:09 +0000 (20:43 +0200)]
Change-Id: I5e0b9daac5e90a4795604d1b31a61d8a085eccfa

17 files changed:
scilab/modules/api_scilab/src/cpp/api_boolean_sparse.cpp
scilab/modules/api_scilab/src/cpp/api_sparse.cpp
scilab/modules/ast/ast.vcxproj
scilab/modules/ast/ast.vcxproj.filters
scilab/modules/ast/includes/analysis/AnalysisVisitor.hxx
scilab/modules/ast/includes/analysis/Decorator.hxx
scilab/modules/ast/includes/analysis/DollarInfo.hxx [new file with mode: 0644]
scilab/modules/ast/includes/analysis/OptionalDecoration.hxx
scilab/modules/ast/includes/analysis/data/LoopAnalyzer.hxx
scilab/modules/ast/includes/exps/opexp.hxx
scilab/modules/ast/src/cpp/analysis/AnalysisVisitor.cpp
scilab/modules/ast/src/cpp/analysis/CompleteMacroSignature.cpp
scilab/modules/ast/src/cpp/analysis/IndexAnalyzer.cpp
scilab/modules/ast/src/cpp/analysis/VisitAssignExp.cpp
scilab/modules/ast/src/cpp/analysis/VisitDollarVar.cpp
scilab/modules/ast/src/cpp/analysis/VisitMatrixExp.cpp
scilab/modules/ast/src/cpp/ast/prettyprintvisitor.cpp

index 5001a90..872da51 100644 (file)
@@ -80,7 +80,7 @@ SciErr getBooleanSparseMatrix(void* _pvCtx, int* _piAddress, int* _piRows, int*
 SciErr allocBooleanSparseMatrix(void* _pvCtx, int _iVar, int _iRows, int _iCols, int _iNbItem, int** _piNbItemRow, int** _piColPos)
 {
     SciErr sciErr = sciErrInit();
-    // We cant rewrite this function in YaSp
+    // We cant rewrite this function in Scilab 6
     // because sparses are not stored like scilab 5.
     // We cant return pointer to _piNbItemRow and
     // _piColPos and let user fill it.
index 7626bf7..1cc0c4a 100644 (file)
@@ -141,7 +141,7 @@ SciErr allocComplexSparseMatrix(void* _pvCtx, int _iVar, int _iRows, int _iCols,
 SciErr allocCommonSparseMatrix(void* _pvCtx, int _iVar, int _iComplex, int _iRows, int _iCols, int _iNbItem, int** _piNbItemRow, int** _piColPos, double** _pdblReal, double** _pdblImg)
 {
     SciErr sciErr = sciErrInit();
-    // We cant rewrite this function in YaSp
+    // We cant rewrite this function in Scilab 6
     // because sparses are not stored like scilab 5.
     // We cant return pointer to _piNbItemRow and
     // _piColPos and let user fill it.
index 2edd0b9..8bf84ff 100644 (file)
@@ -293,7 +293,6 @@ lib /DEF:"$(ProjectDir)string_import.def" /SUBSYSTEM:WINDOWS /MACHINE:$(Platform
     <ClInclude Include="includes\analysis\data\LoopAnalyzer.hxx" />
     <ClInclude Include="includes\analysis\data\LoopBlock.hxx" />
     <ClInclude Include="includes\analysis\data\MacroDef.hxx" />
-    <ClInclude Include="includes\analysis\data\MacroInfo.hxx" />
     <ClInclude Include="includes\analysis\data\MacroSignature.hxx" />
     <ClInclude Include="includes\analysis\data\PolymorphicMacroCache.hxx" />
     <ClInclude Include="includes\analysis\data\TemporaryManager.hxx" />
@@ -302,6 +301,7 @@ lib /DEF:"$(ProjectDir)string_import.def" /SUBSYSTEM:WINDOWS /MACHINE:$(Platform
     <ClInclude Include="includes\analysis\data\TypeLocal.hxx" />
     <ClInclude Include="includes\analysis\data\XBlock.hxx" />
     <ClInclude Include="includes\analysis\Decorator.hxx" />
+    <ClInclude Include="includes\analysis\DollarInfo.hxx" />
     <ClInclude Include="includes\analysis\FBlockEmittedListener.hxx" />
     <ClInclude Include="includes\analysis\ForList.hxx" />
     <ClInclude Include="includes\analysis\gvn\ConstraintManager.hxx" />
index e781c1f..421f664 100644 (file)
     <ClInclude Include="includes\analysis\data\MacroDef.hxx">
       <Filter>Header Files\analysis\data</Filter>
     </ClInclude>
-    <ClInclude Include="includes\analysis\data\MacroInfo.hxx">
-      <Filter>Header Files\analysis\data</Filter>
-    </ClInclude>
     <ClInclude Include="includes\analysis\data\MacroSignature.hxx">
       <Filter>Header Files\analysis\data</Filter>
     </ClInclude>
     <ClInclude Include="includes\ast\prettyprintvisitor.hxx">
       <Filter>Header Files\ast</Filter>
     </ClInclude>
+    <ClInclude Include="includes\analysis\DollarInfo.hxx">
+      <Filter>Header Files\analysis</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="src\cpp\ast\expHistory.cpp">
index 20b3ec8..234cd06 100644 (file)
@@ -29,6 +29,7 @@
 #include "analyzers/CallAnalyzer.hxx"
 #include "checkers/Checkers.hxx"
 #include "Chrono.hxx"
+#include "DollarInfo.hxx"
 #include "ForList.hxx"
 #include "Result.hxx"
 #include "TIType.hxx"
@@ -64,6 +65,7 @@ private:
     logging::Logger logger;
     std::vector<FBlockEmittedListener *> fblockListeners;
     std::stack<ast::Exp *> loops;
+    std::stack<DollarInfo> argIndices;
 
     static MapSymCall symscall;
     static MapSymCall initCalls();
@@ -206,7 +208,7 @@ public:
     // Only for debug use
     void print_info();
     logging::Logger & getLogger();
-    
+
 private:
 
     bool getDimension(SymbolicDimension & dim, ast::Exp & arg, bool & safe, SymbolicDimension & out);
@@ -317,6 +319,7 @@ private:
 
         if (resT.isscalar())
         {
+            // TODO
         }
 
         return resT;
index 021d5a2..4bc9d54 100644 (file)
@@ -92,6 +92,18 @@ struct Decorator
         return *clone;
     }
 
+    inline DollarInfo & setDollarInfo(const DollarInfo & di)
+    {
+        DollarInfo * _di = new DollarInfo(di);
+        opt.set(_di);
+        return *_di;
+    }
+
+    inline DollarInfo * getDollarInfo() const
+    {
+        return opt.get<DollarInfo>();
+    }
+
     inline Result & setResult(Result && _res)
     {
         res = _res;
diff --git a/scilab/modules/ast/includes/analysis/DollarInfo.hxx b/scilab/modules/ast/includes/analysis/DollarInfo.hxx
new file mode 100644 (file)
index 0000000..02cfef3
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2015 - Scilab Enterprises - Calixte DENIZET
+ *
+ *  This file must be used under the terms of the CeCILL.
+ *  This source file is licensed as described in the file COPYING, which
+ *  you should have received as part of this distribution.  The terms
+ *  are also available at
+ *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ */
+
+#ifndef __DOLLAR_INFO_HXX__
+#define __DOLLAR_INFO_HXX__
+
+#include <iostream>
+#include "symbol.hxx"
+#include <cstdint>
+
+namespace analysis
+{
+
+class DollarInfo
+{
+
+    const symbol::Symbol sym;
+    uint32_t index;
+
+public:
+
+    DollarInfo(const symbol::Symbol _sym, const uint32_t _index) : sym(_sym), index(_index) { }
+
+    inline symbol::Symbol getSymbol() const
+    {
+        return sym;
+    }
+
+    inline uint32_t getIndex() const
+    {
+        return index;
+    }
+
+    inline uint32_t & getIndex()
+    {
+        return index;
+    }
+
+    friend std::wostream & operator<<(std::wostream & out, const DollarInfo & di)
+    {
+        out << L"$ in " << di.sym << L" at index " << di.index;
+        return out;
+    }
+
+};
+
+} // namespace analysis
+
+#endif // __DOLLAR_INFO_HXX__
index 6879692..0cf8069 100644 (file)
 
 #include "call/Call.hxx"
 #include "data/Clone.hxx"
+#include "DollarInfo.hxx"
 
 namespace analysis
 {
 
 class OptionalDecoration
 {
-    enum Type { NONE, CALL, CLONE };
+    enum Type { NONE, CALL, CLONE, DOLLAR };
 
     Type ty;
     void * ptr;
@@ -33,6 +34,7 @@ public:
     OptionalDecoration() : ty(NONE), ptr(nullptr) { }
     OptionalDecoration(Call * _ptr) : ty(CALL), ptr(_ptr) { }
     OptionalDecoration(Clone * _ptr) : ty(CLONE), ptr(_ptr) { }
+    OptionalDecoration(DollarInfo * _ptr) : ty(DOLLAR), ptr(_ptr) { }
     OptionalDecoration(OptionalDecoration && od) : ty(od.ty), ptr(od.ptr)
     {
         od.ty = NONE;
@@ -71,6 +73,13 @@ public:
         ptr = _ptr;
     }
 
+    inline void set(DollarInfo * _ptr)
+    {
+        clean();
+        ty = DOLLAR;
+        ptr = _ptr;
+    }
+
     friend std::wostream & operator<<(std::wostream & out, const OptionalDecoration & od)
     {
         switch (od.ty)
@@ -81,6 +90,9 @@ public:
             case CLONE:
                 out << *od.get<Clone>();
                 break;
+            case DOLLAR:
+                out << *od.get<DollarInfo>();
+                break;
             default:
                 break;
         }
@@ -100,6 +112,9 @@ private:
             case CLONE:
                 delete get<Clone>();
                 break;
+            case DOLLAR:
+                delete get<DollarInfo>();
+                break;
             default:
                 break;
         }
@@ -109,5 +124,4 @@ private:
 
 } // namespace analysis
 
-
 #endif // __OPTIONAL_DECORATION_HXX__
index 59378cd..1d2ba51 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
- *  Copyright (C) 2014 - Scilab Enterprises - Calixte DENIZET
+ *  Copyright (C) 2015 - Scilab Enterprises - Calixte DENIZET
  *
  *  This file must be used under the terms of the CeCILL.
  *  This source file is licensed as described in the file COPYING, which
@@ -31,10 +31,20 @@ namespace analysis
 
 class LoopAnalyzer : public ast::Visitor, public Chrono
 {
-    std::unordered_map<ast::Exp *, tools::SymbolSet> assigned;
-    std::unordered_map<ast::Exp *, tools::SymbolSet> inserted;
-    std::unordered_map<ast::Exp *, tools::SymbolSet> shared;
-    std::stack<ast::Exp *> loops;
+
+    struct __Info
+    {
+        tools::SymbolSet assigned;
+        tools::SymbolSet inserted;
+        tools::SymbolSet shared;
+        tools::SymbolSet used;
+
+        __Info() { }
+    };
+
+    std::unordered_map<ast::Exp *, __Info> info;
+
+    std::stack<std::pair<ast::Exp *, __Info *>> loops;
     ast::Exp * seq;
 
 public:
@@ -60,10 +70,10 @@ public:
     {
         if (e)
         {
-            const auto i = assigned.find(e);
-            if (i != assigned.end())
+            const auto i = info.find(e);
+            if (i != info.end())
             {
-                return i->second.find(sym) != i->second.end();
+                return i->second.assigned.find(sym) != i->second.assigned.end();
             }
         }
         return false;
@@ -73,10 +83,10 @@ public:
     {
         if (e)
         {
-            const auto i = inserted.find(e);
-            if (i != inserted.end())
+            const auto i = info.find(e);
+            if (i != info.end())
             {
-                return &i->second;
+                return &i->second.inserted;
             }
         }
         return nullptr;
@@ -86,10 +96,10 @@ public:
     {
         if (e)
         {
-            const auto i = shared.find(e);
-            if (i != shared.end())
+            const auto i = info.find(e);
+            if (i != info.end())
             {
-                return &i->second;
+                return &i->second.shared;
             }
         }
         return nullptr;
@@ -97,36 +107,51 @@ public:
 
     friend std::wostream & operator<<(std::wostream & out, const LoopAnalyzer & la)
     {
-        if (!la.assigned.empty())
+        if (!la.info.empty())
         {
-            out << L" Assigned:\n";
-            for (const auto & p : la.assigned)
+            std::wostringstream wos_ass, wos_ins, wos_sh, wos_used;
+            for (const auto & p : la.info)
             {
-                out << L"  -Loop at " << p.first->getLocation().getLocationString() << L": ";
-                tools::printSet(p.second, out);
-                out << L"\n";
+                wos_ass << L"  -Loop at " << p.first->getLocation().getLocationString() << L": ";
+                tools::printSet(p.second.assigned, wos_ass);
+                wos_ass << L"\n";
+
+                wos_ins << L"  -Loop at " << p.first->getLocation().getLocationString() << L": ";
+                tools::printSet(p.second.inserted, wos_ins);
+                wos_ins << L"\n";
+
+                wos_sh << L"  -Loop at " << p.first->getLocation().getLocationString() << L": ";
+                tools::printSet(p.second.inserted, wos_sh);
+                wos_sh << L"\n";
+
+                wos_used << L"  -Loop at " << p.first->getLocation().getLocationString() << L": ";
+                tools::printSet(p.second.inserted, wos_used);
+                wos_used << L"\n";
             }
-        }
 
-        if (!la.inserted.empty())
-        {
-            out << L" Inserted:\n";
-            for (const auto & p : la.inserted)
+            std::wstring str = wos_ass.str();
+            if (!str.empty())
             {
-                out << L"  -Loop at " << p.first->getLocation().getLocationString() << L": ";
-                tools::printSet(p.second, out);
-                out << L"\n";
+                out << L" Assigned:\n";
+                out << str;
             }
-        }
-
-        if (!la.shared.empty())
-        {
-            out << L" Shared:\n";
-            for (const auto & p : la.shared)
+            str = wos_ins.str();
+            if (!str.empty())
+            {
+                out << L" Inserted:\n";
+                out << str;
+            }
+            str = wos_sh.str();
+            if (!str.empty())
             {
-                out << L"  -Loop at " << p.first->getLocation().getLocationString() << L": ";
-                tools::printSet(p.second, out);
-                out << L"\n";
+                out << L" Shared:\n";
+                out << str;
+            }
+            str = wos_used.str();
+            if (!str.empty())
+            {
+                out << L" Used:\n";
+                out << str;
             }
         }
 
@@ -141,38 +166,41 @@ public:
 
 private:
 
-    inline void emplace(std::unordered_map<ast::Exp *, tools::SymbolSet> & map, const symbol::Symbol & sym)
+    inline void emplaceAssigned(const symbol::Symbol & sym)
     {
-        ast::Exp * loop = loops.top();
-        auto i = map.find(loop);
-        if (i == map.end())
-        {
-            i = map.emplace(loop, tools::SymbolSet()).first;
-        }
-        i->second.emplace(sym);
+        loops.top().second->assigned.emplace(sym);
+    }
+
+    inline void emplaceInserted(const symbol::Symbol & sym)
+    {
+        loops.top().second->inserted.emplace(sym);
+    }
+
+    inline void emplaceShared(const symbol::Symbol & sym)
+    {
+        loops.top().second->shared.emplace(sym);
+    }
+
+    inline void emplaceUsed(const symbol::Symbol & sym)
+    {
+        loops.top().second->used.emplace(sym);
+    }
+
+    inline void push(ast::Exp & e)
+    {
+        __Info * i = &(info.emplace(&e, __Info()).first->second);
+        loops.push({ &e, i });
     }
 
     inline void pushAssigned()
     {
-        ast::Exp * last = loops.top();
+        std::pair<ast::Exp *, __Info *> last = loops.top();
         loops.pop();
 
-        if (!loops.empty())
+        if (!loops.empty() && !last.second->assigned.empty())
         {
-            ast::Exp * penult = loops.top();
-            const auto i = assigned.find(last);
-            if (i != assigned.end())
-            {
-                const auto j = assigned.find(penult);
-                if (j == assigned.end())
-                {
-                    assigned.emplace(penult, i->second);
-                }
-                else
-                {
-                    j->second.insert(i->second.begin(), i->second.end());
-                }
-            }
+            std::pair<ast::Exp *, __Info *> & penult = loops.top();
+            penult.second->assigned.insert(last.second->assigned.begin(), last.second->assigned.end());
         }
     }
 
@@ -234,12 +262,13 @@ private:
         {
             // A = ....
             const symbol::Symbol & Lsym = static_cast<ast::SimpleVar &>(e.getLeftExp()).getSymbol();
-            emplace(assigned, Lsym);
+            emplaceAssigned(Lsym);
             if (e.getRightExp().isSimpleVar())
             {
                 const symbol::Symbol & Rsym = static_cast<ast::SimpleVar &>(e.getRightExp()).getSymbol();
-                emplace(shared, Lsym);
-                emplace(shared, Rsym);
+                emplaceShared(Lsym);
+                emplaceShared(Rsym);
+                emplaceUsed(Rsym);
             }
         }
         else if (e.getLeftExp().isCallExp())
@@ -249,8 +278,8 @@ private:
             if (ce.getName().isSimpleVar())
             {
                 const symbol::Symbol & Lsym = static_cast<ast::SimpleVar &>(ce.getName()).getSymbol();
-                emplace(inserted, Lsym);
-                emplace(assigned, Lsym);
+                emplaceInserted(Lsym);
+                emplaceAssigned(Lsym);
             }
         }
         else if (e.getLeftExp().isAssignListExp())
@@ -262,7 +291,7 @@ private:
                 if (re->isSimpleVar())
                 {
                     const symbol::Symbol & Lsym = static_cast<const ast::SimpleVar *>(re)->getSymbol();
-                    emplace(assigned, Lsym);
+                    emplaceAssigned(Lsym);
                 }
             }
         }
@@ -279,7 +308,7 @@ private:
 
     void visit(ast::WhileExp & e)
     {
-        loops.push(&e);
+        push(e);
         e.getBody().accept(*this);
 
         // pushAssigned pops loops
@@ -288,7 +317,7 @@ private:
 
     void visit(ast::ForExp & e)
     {
-        loops.push(&e);
+        push(e);
         e.getVardec().accept(*this);
         e.getBody().accept(*this);
         pushAssigned();
@@ -385,7 +414,7 @@ private:
 
     void visit(ast::VarDec & e)
     {
-        emplace(assigned, e.getSymbol());
+        emplaceAssigned(e.getSymbol());
     }
 
     void visit(ast::FunctionDec & e)
index f517518..d7a57c1 100644 (file)
@@ -185,9 +185,71 @@ public:
 
     inline bool isBooleanOp() const
     {
-       return _oper == eq || _oper == ne || _oper == lt || _oper == le || _oper == gt || _oper == ge || _oper == logicalAnd || _oper == logicalOr || _oper == logicalShortCutAnd || _oper == logicalShortCutOr; 
+        return _oper == eq || _oper == ne || _oper == lt || _oper == le || _oper == gt || _oper == ge || _oper == logicalAnd || _oper == logicalOr || _oper == logicalShortCutAnd || _oper == logicalShortCutOr;
     }
 
+    inline std::wstring getString() const
+    {
+        switch (_oper)
+        {
+            case plus:
+                return L"+";
+            case minus:
+                return L"-";
+            case times:
+                return L"*";
+            case rdivide:
+                return L"/";
+            case ldivide:
+                return L"\\";
+            case power:
+                return L"^";
+            case dottimes:
+                return L".*";
+            case dotrdivide:
+                return L"./";
+            case dotldivide:
+                return L".\\";
+            case dotpower:
+                return L".^";
+            case krontimes:
+                return L".*.";
+            case kronrdivide:
+                return L"./.";
+            case kronldivide:
+                return L".\\.";
+            case controltimes:
+                return L"*.";
+            case controlrdivide:
+                return L"/.";
+            case controlldivide:
+                return L"\\.";
+            case eq:
+                return L"==";
+            case ne:
+                return L"~=";
+            case lt:
+                return L"<";
+            case le:
+                return L"<=";
+            case gt:
+                return L">";
+            case ge:
+                return L">=";
+            case logicalAnd:
+                return L"&";
+            case logicalOr:
+                return L"|";
+            case logicalShortCutAnd:
+                return L"&&";
+            case logicalShortCutOr:
+                return L"||";
+            case unaryMinus:
+                return L"-";
+        }
+    }
+
+
 protected:
     /** \brief Operator. */
     Oper _oper;
index 8665212..e8411b7 100644 (file)
 
 namespace analysis
 {
-    AnalysisVisitor::MapSymCall AnalysisVisitor::symscall = AnalysisVisitor::initCalls();//a=1:3;b=2;c=3;testAnalysis("repmat","a","b","c")
+AnalysisVisitor::MapSymCall AnalysisVisitor::symscall = AnalysisVisitor::initCalls();//a=1:3;b=2;c=3;testAnalysis("repmat","a","b","c")
 
-    AnalysisVisitor::MapSymCall AnalysisVisitor::initCalls()
-    {
-        MapSymCall msc;
-
-        msc.emplace(L"zeros", std::shared_ptr<CallAnalyzer>(new ZerosAnalyzer()));
-        msc.emplace(L"ones", std::shared_ptr<CallAnalyzer>(new OnesAnalyzer()));
-        msc.emplace(L"rand", std::shared_ptr<CallAnalyzer>(new RandAnalyzer()));
-        msc.emplace(L"matrix", std::shared_ptr<CallAnalyzer>(new MatrixAnalyzer()));
-        msc.emplace(L"eye", std::shared_ptr<CallAnalyzer>(new EyeAnalyzer()));
-
-        std::shared_ptr<CallAnalyzer> ca(new CeilAnalyzer());
-        msc.emplace(L"ceil", ca);
-        msc.emplace(L"floor", ca);
-        msc.emplace(L"round", ca);
-        msc.emplace(L"fix", ca);
-        msc.emplace(L"int", ca);
-
-        //msc.emplace(L"sqrt", std::shared_ptr<CallAnalyzer>(new SqrtAnalyzer()));
-        msc.emplace(L"argn", std::shared_ptr<CallAnalyzer>(new ArgnAnalyzer()));
-        msc.emplace(L"size", std::shared_ptr<CallAnalyzer>(new SizeAnalyzer()));
-        msc.emplace(L"length", std::shared_ptr<CallAnalyzer>(new LengthAnalyzer()));
-        msc.emplace(L"diag", std::shared_ptr<CallAnalyzer>(new DiagAnalyzer()));
-        msc.emplace(L"type", std::shared_ptr<CallAnalyzer>(new TypeAnalyzer()));
-        msc.emplace(L"typeof", std::shared_ptr<CallAnalyzer>(new TypeofAnalyzer()));
-        msc.emplace(L"inttype", std::shared_ptr<CallAnalyzer>(new InttypeAnalyzer()));
-        msc.emplace(L"iconvert", std::shared_ptr<CallAnalyzer>(new IconvertAnalyzer()));
-        msc.emplace(L"isreal", std::shared_ptr<CallAnalyzer>(new IsrealAnalyzer()));
-        msc.emplace(L"isscalar", std::shared_ptr<CallAnalyzer>(new IsscalarAnalyzer()));
-        msc.emplace(L"find", std::shared_ptr<CallAnalyzer>(new FindAnalyzer()));
-
-        return msc;
-    }
+AnalysisVisitor::MapSymCall AnalysisVisitor::initCalls()
+{
+    MapSymCall msc;
+
+    msc.emplace(L"zeros", std::shared_ptr<CallAnalyzer>(new ZerosAnalyzer()));
+    msc.emplace(L"ones", std::shared_ptr<CallAnalyzer>(new OnesAnalyzer()));
+    msc.emplace(L"rand", std::shared_ptr<CallAnalyzer>(new RandAnalyzer()));
+    msc.emplace(L"matrix", std::shared_ptr<CallAnalyzer>(new MatrixAnalyzer()));
+    msc.emplace(L"eye", std::shared_ptr<CallAnalyzer>(new EyeAnalyzer()));
+
+    std::shared_ptr<CallAnalyzer> ca(new CeilAnalyzer());
+    msc.emplace(L"ceil", ca);
+    msc.emplace(L"floor", ca);
+    msc.emplace(L"round", ca);
+    msc.emplace(L"fix", ca);
+    msc.emplace(L"int", ca);
+
+    //msc.emplace(L"sqrt", std::shared_ptr<CallAnalyzer>(new SqrtAnalyzer()));
+    msc.emplace(L"argn", std::shared_ptr<CallAnalyzer>(new ArgnAnalyzer()));
+    msc.emplace(L"size", std::shared_ptr<CallAnalyzer>(new SizeAnalyzer()));
+    msc.emplace(L"length", std::shared_ptr<CallAnalyzer>(new LengthAnalyzer()));
+    msc.emplace(L"diag", std::shared_ptr<CallAnalyzer>(new DiagAnalyzer()));
+    msc.emplace(L"type", std::shared_ptr<CallAnalyzer>(new TypeAnalyzer()));
+    msc.emplace(L"typeof", std::shared_ptr<CallAnalyzer>(new TypeofAnalyzer()));
+    msc.emplace(L"inttype", std::shared_ptr<CallAnalyzer>(new InttypeAnalyzer()));
+    msc.emplace(L"iconvert", std::shared_ptr<CallAnalyzer>(new IconvertAnalyzer()));
+    msc.emplace(L"isreal", std::shared_ptr<CallAnalyzer>(new IsrealAnalyzer()));
+    msc.emplace(L"isscalar", std::shared_ptr<CallAnalyzer>(new IsscalarAnalyzer()));
+    msc.emplace(L"find", std::shared_ptr<CallAnalyzer>(new FindAnalyzer()));
+
+    return msc;
+}
 
 
-    AnalysisVisitor::AnalysisVisitor() : cv(*this), pv(std::wcerr, true, false), logger("/tmp/analysis.log")
-    {
-        start_chrono();
-    }
+AnalysisVisitor::AnalysisVisitor() : cv(*this), pv(std::wcerr, true, false), logger("/tmp/analysis.log")
+{
+    start_chrono();
+}
 
-    AnalysisVisitor::~AnalysisVisitor() { }
+AnalysisVisitor::~AnalysisVisitor() { }
 
-    void AnalysisVisitor::reset()
+void AnalysisVisitor::reset()
+{
+    _result = Result();
+    dm.reset();
+    multipleLHS.clear();
+    while (!loops.empty())
     {
-       _result = Result();
-       dm.reset();
-       multipleLHS.clear();
-       while (!loops.empty())
-       {
-           loops.pop();
-       }
-       start_chrono();
+        loops.pop();
     }
+    start_chrono();
+}
 
-    void AnalysisVisitor::print_info()
-    {
-        stop_chrono();
+void AnalysisVisitor::print_info()
+{
+    stop_chrono();
 
-        //std::wcout << getGVN() << std::endl << std::endl; function z=foo(x,y);z=argn(2);endfunction;jit("x=123;y=456;t=foo(x,y)")
-        std::wcerr << L"Analysis: " << *static_cast<Chrono *>(this) << std::endl;
-        //std::wcout << temp << std::endl;
+    //std::wcout << getGVN() << std::endl << std::endl; function z=foo(x,y);z=argn(2);endfunction;jit("x=123;y=456;t=foo(x,y)")
+    std::wcerr << L"Analysis: " << *static_cast<Chrono *>(this) << std::endl;
+    //std::wcout << temp << std::endl;
 
-        std::wcerr << dm << std::endl;
-       std::wcerr << pmc << std::endl;
+    std::wcerr << dm << std::endl;
+    std::wcerr << pmc << std::endl;
 
-        std::wcerr << std::endl;
-    }
+    std::wcerr << std::endl;
+}
 
-    logging::Logger & AnalysisVisitor::getLogger()
-    {
-        return logger;
-    }
+logging::Logger & AnalysisVisitor::getLogger()
+{
+    return logger;
+}
 
-    bool AnalysisVisitor::asDouble(types::InternalType * pIT, double & out)
+bool AnalysisVisitor::asDouble(types::InternalType * pIT, double & out)
+{
+    if (pIT && pIT->isDouble())
     {
-        if (pIT && pIT->isDouble())
+        types::Double * pDbl = static_cast<types::Double *>(pIT);
+        if (!pDbl->isComplex() && pDbl->getSize() == 1)
         {
-            types::Double * pDbl = static_cast<types::Double *>(pIT);
-            if (!pDbl->isComplex() && pDbl->getSize() == 1)
-            {
-                out = pDbl->get()[0];
-                return true;
-            }
+            out = pDbl->get()[0];
+            return true;
         }
-
-        return false;
     }
 
-    bool AnalysisVisitor::asDouble(ast::Exp & e, double & out)
+    return false;
+}
+
+bool AnalysisVisitor::asDouble(ast::Exp & e, double & out)
+{
+    if (e.isDoubleExp())
     {
-        if (e.isDoubleExp())
-        {
-            out = static_cast<ast::DoubleExp &>(e).getValue();
-            return true;
-        }
-        else if (e.isOpExp())
+        out = static_cast<ast::DoubleExp &>(e).getValue();
+        return true;
+    }
+    else if (e.isOpExp())
+    {
+        ast::OpExp & op = static_cast<ast::OpExp &>(e);
+        if (op.getOper() == ast::OpExp::unaryMinus)
         {
-            ast::OpExp & op = static_cast<ast::OpExp &>(e);
-            if (op.getOper() == ast::OpExp::unaryMinus)
+            if (op.getRight().isDoubleExp())
             {
-                if (op.getRight().isDoubleExp())
-                {
-                    out = -static_cast<ast::DoubleExp &>(op.getRight()).getValue();
-                    return true;
-                }
+                out = -static_cast<ast::DoubleExp &>(op.getRight()).getValue();
+                return true;
             }
-            else if (op.getLeft().isDoubleExp() && op.getRight().isDoubleExp())
-            {
-                const double L = static_cast<ast::DoubleExp &>(op.getLeft()).getValue();
-                const double R = static_cast<ast::DoubleExp &>(op.getRight()).getValue();
+        }
+        else if (op.getLeft().isDoubleExp() && op.getRight().isDoubleExp())
+        {
+            const double L = static_cast<ast::DoubleExp &>(op.getLeft()).getValue();
+            const double R = static_cast<ast::DoubleExp &>(op.getRight()).getValue();
 
-                switch (op.getOper())
-                {
+            switch (op.getOper())
+            {
                 case ast::OpExp::minus:
                     out = L - R;
                     return true;
@@ -173,70 +173,70 @@ namespace analysis
                     return true;
                 default:
                     return false;
-                }
             }
         }
-
-        return false;
     }
 
-    bool AnalysisVisitor::isDoubleConstant(const ast::Exp & e)
+    return false;
+}
+
+bool AnalysisVisitor::isDoubleConstant(const ast::Exp & e)
+{
+    if (e.isDoubleExp())
     {
-        if (e.isDoubleExp())
-        {
-            return true;
-        }
-        else if (e.isOpExp())
+        return true;
+    }
+    else if (e.isOpExp())
+    {
+        const ast::OpExp & oe = static_cast<const ast::OpExp &>(e);
+        if (!oe.isBooleanOp())
         {
-            const ast::OpExp & oe = static_cast<const ast::OpExp &>(e);
-            if (!oe.isBooleanOp())
-            {
-                return isDoubleConstant(oe.getLeft()) && isDoubleConstant(oe.getRight());
-            }
-            return false;
+            return isDoubleConstant(oe.getLeft()) && isDoubleConstant(oe.getRight());
         }
-        else if (e.isMatrixExp())
+        return false;
+    }
+    else if (e.isMatrixExp())
+    {
+        const ast::MatrixExp & me = static_cast<const ast::MatrixExp &>(e);
+        const ast::exps_t & lines = me.getLines();
+        for (const auto line : lines)
         {
-            const ast::MatrixExp & me = static_cast<const ast::MatrixExp &>(e);
-            const ast::exps_t & lines = me.getLines();
-            for (const auto line : lines)
+            const ast::exps_t & columns = static_cast<ast::MatrixLineExp *>(line)->getColumns();
+            for (const auto column : columns)
             {
-                const ast::exps_t & columns = static_cast<ast::MatrixLineExp *>(line)->getColumns();
-                for (const auto column : columns)
+                if (column && !isDoubleConstant(*column))
                 {
-                    if (column && !isDoubleConstant(*column))
-                    {
-                        return false;
-                    }
+                    return false;
                 }
             }
-            return true;
-        }
-        else if (e.isListExp())
-        {
-            const ast::ListExp & le = static_cast<const ast::ListExp &>(e);
-            return isDoubleConstant(le.getStart()) && isDoubleConstant(le.getStep()) && isDoubleConstant(le.getEnd());
         }
-        else if (e.isSimpleVar())
-        {
-            const ast::SimpleVar & var = static_cast<const ast::SimpleVar &>(e);
-            const symbol::Symbol & sym = var.getSymbol();
-            const std::wstring & name = sym.getName();
-            return name == L"%i" || name == L"%inf" || name == L"%nan" || name == L"%eps" || name == L"%pi" || name == L"%e";
-        }
-        else if (e.isCallExp())
-        {
-            const ast::CallExp & ce = static_cast<const ast::CallExp &>(e);
-            const ast::SimpleVar & var = static_cast<const ast::SimpleVar &>(ce.getName());
-            const std::wstring & name = var.getSymbol().getName();
+        return true;
+    }
+    else if (e.isListExp())
+    {
+        const ast::ListExp & le = static_cast<const ast::ListExp &>(e);
+        return isDoubleConstant(le.getStart()) && isDoubleConstant(le.getStep()) && isDoubleConstant(le.getEnd());
+    }
+    else if (e.isSimpleVar())
+    {
+        const ast::SimpleVar & var = static_cast<const ast::SimpleVar &>(e);
+        const symbol::Symbol & sym = var.getSymbol();
+        const std::wstring & name = sym.getName();
+        return name == L"%i" || name == L"%inf" || name == L"%nan" || name == L"%eps" || name == L"%pi" || name == L"%e";
+    }
+    else if (e.isCallExp())
+    {
+        const ast::CallExp & ce = static_cast<const ast::CallExp &>(e);
+        const ast::SimpleVar & var = static_cast<const ast::SimpleVar &>(ce.getName());
+        const std::wstring & name = var.getSymbol().getName();
 
-            // TODO: check if 'ones' and 'zeros' are the expected functions
-            // ie: ones="abc"; ones(1) !!!
-            if (name == L"ones" || name == L"zeros")
+        // TODO: check if 'ones' and 'zeros' are the expected functions
+        // ie: ones="abc"; ones(1) !!!
+        if (name == L"ones" || name == L"zeros")
+        {
+            const ast::exps_t args = ce.getArgs();
+            switch (args.size())
             {
-                const ast::exps_t args = ce.getArgs();
-                switch (args.size())
-                {
                 case 0:
                     return true;
                 case 1:
@@ -245,34 +245,55 @@ namespace analysis
                     return isDoubleConstant(*args.front()) && isDoubleConstant(**std::next(args.cbegin()));
                 default:
                     return false;
-                }
             }
         }
-
-        return false;
     }
 
-    bool AnalysisVisitor::asDoubleMatrix(ast::Exp & e, types::Double *& data)
+    return false;
+}
+
+bool AnalysisVisitor::asDoubleMatrix(ast::Exp & e, types::Double *& data)
+{
+    if (isDoubleConstant(e))
     {
-        if (isDoubleConstant(e))
+        ast::ExecVisitor exec;
+        e.accept(exec);
+        types::InternalType * pIT = exec.getResult();
+        // TODO : handle complex case
+        if (pIT && pIT->isDouble() && !pIT->getAs<types::Double>()->isComplex())
         {
-            ast::ExecVisitor exec;
-            e.accept(exec);
-            types::InternalType * pIT = exec.getResult();
-            // TODO : handle complex case
-            if (pIT && pIT->isDouble() && !pIT->getAs<types::Double>()->isComplex())
-            {
-                pIT->IncreaseRef();
-                data = static_cast<types::Double *>(pIT);
+            pIT->IncreaseRef();
+            data = static_cast<types::Double *>(pIT);
 
-                return true;
-            }
+            return true;
         }
+    }
 
-        return false;
+    return false;
+}
+
+void AnalysisVisitor::visitArguments(const std::wstring & name, const unsigned int lhs, const TIType & calltype, ast::CallExp & e, const ast::exps_t & args)
+{
+    std::vector<Result> resargs;
+    std::vector<TIType> vargs;
+    vargs.reserve(args.size());
+    resargs.reserve(args.size());
+
+    const symbol::Symbol & sym = static_cast<ast::SimpleVar &>(e.getName()).getSymbol();
+    argIndices.emplace(sym, 0);
+
+    for (auto arg : args)
+    {
+        argIndices.top().getIndex() += 1;
+        arg->accept(*this);
+        resargs.push_back(getResult());
+        vargs.push_back(getResult().getType());
     }
 
-    void AnalysisVisitor::visitArguments(const std::wstring & name, const unsigned int lhs, const TIType & calltype, ast::CallExp & e, const ast::exps_t & args)
+    argIndices.pop();
+    uint64_t functionId = 0;
+    std::vector<TIType> out = getDM().call(*this, lhs, sym, vargs, &e, functionId);
+    if (lhs > 1)
     {
         std::vector<Result> resargs;
         std::vector<TIType> vargs;
@@ -287,7 +308,7 @@ namespace analysis
         }
 
         const symbol::Symbol & sym = static_cast<ast::SimpleVar &>(e.getName()).getSymbol();
-       uint64_t functionId = 0;
+        uint64_t functionId = 0;
         std::vector<TIType> out = getDM().call(*this, lhs, sym, vargs, &e, functionId);
         if (lhs > 1)
         {
@@ -333,148 +354,149 @@ namespace analysis
             setResult(e.getDecorator().res);
         }
     }
+}
 
-    int AnalysisVisitor::getTmpIdForEWOp(const TIType & resT, const Result & LR, const Result & RR, ast::Exp * Lexp, ast::Exp * Rexp)
+int AnalysisVisitor::getTmpIdForEWOp(const TIType & resT, const Result & LR, const Result & RR, ast::Exp * Lexp, ast::Exp * Rexp)
+{
+    int tempId = -1;
+    if (resT.isknown() && resT.ismatrix())
     {
-        int tempId = -1;
-        if (resT.isknown() && resT.ismatrix())
+        if (LR.isTemp() || RR.isTemp())
         {
-            if (LR.isTemp() || RR.isTemp())
-            {
-                const int Lid = LR.getTempId();
-                const int Rid = RR.getTempId();
-                const TIType & LT = LR.getType();
-                const TIType & RT = RR.getType();
+            const int Lid = LR.getTempId();
+            const int Rid = RR.getTempId();
+            const TIType & LT = LR.getType();
+            const TIType & RT = RR.getType();
 
-                if (LT.isscalar())
+            if (LT.isscalar())
+            {
+                if (RT.isscalar())
                 {
-                    if (RT.isscalar())
+                    if (Lid == -1)
                     {
-                        if (Lid == -1)
+                        if (resT == LT)
                         {
-                            if (resT == LT)
-                            {
-                                tempId = Rid;
-                            }
-                            else
-                            {
-                                tempId = getDM().getTmpId(resT, false);
-                                getDM().releaseTmp(Rid, Rexp);
-                            }
+                            tempId = Rid;
                         }
                         else
                         {
-                            if (resT == LT)
-                            {
-                                tempId = Lid;
-                                getDM().releaseTmp(Rid, Rexp);
-                            }
-                            else if (Rid != -1 && resT == RT)
-                            {
-                                tempId = Rid;
-                                getDM().releaseTmp(Lid, Lexp);
-                            }
-                            else
-                            {
-                                tempId = getDM().getTmpId(resT, false);
-                                getDM().releaseTmp(Lid, Lexp);
-                            }
+                            tempId = getDM().getTmpId(resT, false);
+                            getDM().releaseTmp(Rid, Rexp);
                         }
                     }
                     else
                     {
-                        if (Rid == -1)
+                        if (resT == LT)
                         {
-                            tempId = getDM().getTmpId(resT, false);
+                            tempId = Lid;
+                            getDM().releaseTmp(Rid, Rexp);
+                        }
+                        else if (Rid != -1 && resT == RT)
+                        {
+                            tempId = Rid;
+                            getDM().releaseTmp(Lid, Lexp);
                         }
                         else
                         {
-                            if (resT == RT)
-                            {
-                                tempId = Rid;
-                            }
-                            else if (Lid != -1 && resT == LT)
-                            {
-                                tempId = Lid;
-                                getDM().releaseTmp(Rid, Rexp);
-                            }
-                            else
-                            {
-                                tempId = getDM().getTmpId(resT, false);
-                                getDM().releaseTmp(Rid, Rexp);
-                            }
+                            tempId = getDM().getTmpId(resT, false);
+                            getDM().releaseTmp(Lid, Lexp);
                         }
-                        getDM().releaseTmp(Lid, Lexp);
                     }
                 }
                 else
                 {
-                    if (RT.isscalar())
+                    if (Rid == -1)
+                    {
+                        tempId = getDM().getTmpId(resT, false);
+                    }
+                    else
                     {
-                        if (Lid == -1)
+                        if (resT == RT)
                         {
-                            tempId = getDM().getTmpId(resT, false);
+                            tempId = Rid;
+                        }
+                        else if (Lid != -1 && resT == LT)
+                        {
+                            tempId = Lid;
+                            getDM().releaseTmp(Rid, Rexp);
                         }
                         else
                         {
-                            if (resT == LT)
-                            {
-                                tempId = Lid;
-                            }
-                            else if (Rid != -1 && resT == RT)
-                            {
-                                tempId = Rid;
-                                getDM().releaseTmp(Lid, Lexp);
-                            }
-                            else
-                            {
-                                tempId = getDM().getTmpId(resT, false);
-                                getDM().releaseTmp(Lid, Lexp);
-                            }
+                            tempId = getDM().getTmpId(resT, false);
+                            getDM().releaseTmp(Rid, Rexp);
                         }
-                        getDM().releaseTmp(Rid, Rexp);
+                    }
+                    getDM().releaseTmp(Lid, Lexp);
+                }
+            }
+            else
+            {
+                if (RT.isscalar())
+                {
+                    if (Lid == -1)
+                    {
+                        tempId = getDM().getTmpId(resT, false);
                     }
                     else
                     {
-                        if (Rid == -1)
+                        if (resT == LT)
                         {
-                            if (resT == LT)
-                            {
-                                tempId = Lid;
-                            }
-                            else
-                            {
-                                tempId = getDM().getTmpId(resT, false);
-                                getDM().releaseTmp(Lid, Lexp);
-                            }
+                            tempId = Lid;
+                        }
+                        else if (Rid != -1 && resT == RT)
+                        {
+                            tempId = Rid;
+                            getDM().releaseTmp(Lid, Lexp);
                         }
                         else
                         {
-                            if (resT == RT)
-                            {
-                                tempId = Rid;
-                            }
-                            else if (Lid != -1 && resT == LT)
-                            {
-                                tempId = Lid;
-                                getDM().releaseTmp(Rid, Rexp);
-                            }
-                            else
-                            {
-                                tempId = getDM().getTmpId(resT, false);
-                                getDM().releaseTmp(Rid, Rexp);
-                            }
+                            tempId = getDM().getTmpId(resT, false);
                             getDM().releaseTmp(Lid, Lexp);
                         }
                     }
+                    getDM().releaseTmp(Rid, Rexp);
+                }
+                else
+                {
+                    if (Rid == -1)
+                    {
+                        if (resT == LT)
+                        {
+                            tempId = Lid;
+                        }
+                        else
+                        {
+                            tempId = getDM().getTmpId(resT, false);
+                            getDM().releaseTmp(Lid, Lexp);
+                        }
+                    }
+                    else
+                    {
+                        if (resT == RT)
+                        {
+                            tempId = Rid;
+                        }
+                        else if (Lid != -1 && resT == LT)
+                        {
+                            tempId = Lid;
+                            getDM().releaseTmp(Rid, Rexp);
+                        }
+                        else
+                        {
+                            tempId = getDM().getTmpId(resT, false);
+                            getDM().releaseTmp(Rid, Rexp);
+                        }
+                        getDM().releaseTmp(Lid, Lexp);
+                    }
                 }
-            }
-            else
-            {
-                tempId = getDM().getTmpId(resT, false);
             }
         }
-
-        return tempId;
+        else
+        {
+            tempId = getDM().getTmpId(resT, false);
+        }
     }
+
+    return tempId;
+}
 }
index 7fa1e53..3cc7890 100644 (file)
 
 namespace analysis
 {
-    const MacroOut * CompleteMacroSignature::getOutTypes(AnalysisVisitor & visitor, const MacroSignature & signature, MacroDef * macrodef, DataManager & dm, const unsigned int rhs, std::vector<TIType> & in, const std::vector<GVN::Value *> values, uint64_t & functionId)
+const MacroOut * CompleteMacroSignature::getOutTypes(AnalysisVisitor & visitor, const MacroSignature & signature, MacroDef * macrodef, DataManager & dm, const unsigned int rhs, std::vector<TIType> & in, const std::vector<GVN::Value *> values, uint64_t & functionId)
 {
     for (const auto & mpcmo : outMap)
     {
         if (mpcmo.verified.check(visitor.getGVN(), values) == InferenceConstraint::RESULT_TRUE && ConstraintManager::checkGlobalConstants(mpcmo.globalConstants))
         {
-           for (const auto & set : mpcmo.unverified)
-           {
-               if (set.check(visitor.getGVN(), values) != InferenceConstraint::RESULT_FALSE)
-               {
-                   return analyze(visitor, signature, macrodef, dm, rhs, in, values, functionId);
-               }
-           }
-           functionId = mpcmo.id;
+            for (const auto & set : mpcmo.unverified)
+            {
+                if (set.check(visitor.getGVN(), values) != InferenceConstraint::RESULT_FALSE)
+                {
+                    return analyze(visitor, signature, macrodef, dm, rhs, in, values, functionId);
+                }
+            }
+            functionId = mpcmo.id;
             return &mpcmo.out;
         }
     }
@@ -59,34 +59,34 @@ const MacroOut * CompleteMacroSignature::analyze(AnalysisVisitor & visitor, cons
         fblock.getExp()->accept(visitor);
         dm.finalizeBlock();
         //std::wcerr << fblock << std::endl;
-        visitor.emitFunctionBlock(fblock);
         const auto p = outMap.emplace(id++, fblock.getVerifiedConstraints(), fblock.getUnverifiedConstraints(), fblock.getGlobalConstants(), fblock.getOuts(*this));
-       fblock.setFunctionId(p.first->id);
-       functionId = p.first->id;
+        fblock.setFunctionId(p.first->id);
+        functionId = p.first->id;
+        visitor.emitFunctionBlock(fblock);
+
+        //std::wcerr << *this << std::endl;
 
-       //std::wcerr << *this << std::endl;
-       
         return &p.first->out;
     }
 
     return nullptr;
 }
 
-    std::wostream & operator<<(std::wostream & out, const CompleteMacroSignature & cms)
+std::wostream & operator<<(std::wostream & out, const CompleteMacroSignature & cms)
+{
+    out << L"Complete Macro Cache:\n";
+    for (const auto & mpcmo : cms.outMap)
     {
-       out << L"Complete Macro Cache:\n";
-       for (const auto & mpcmo : cms.outMap)
-       {
-           out << L" * Verified constraints: " << mpcmo.verified << L"\n"
-               << L" * Unverified constraints: ";
-           tools::printSet(mpcmo.unverified, out);
-           out << L"\n"
-               << L" * Globals: ";
-           tools::printSet(mpcmo.globalConstants, out);
-           out << L"\n"
-               << L"   => " << mpcmo.out.tuple << L"\n";
-       }
-       return out;
+        out << L" * Verified constraints: " << mpcmo.verified << L"\n"
+            << L" * Unverified constraints: ";
+        tools::printSet(mpcmo.unverified, out);
+        out << L"\n"
+            << L" * Globals: ";
+        tools::printSet(mpcmo.globalConstants, out);
+        out << L"\n"
+            << L"   => " << mpcmo.out.tuple << L"\n";
     }
+    return out;
+}
 
 } // namespace analysis
index 7707eb3..601bd02 100644 (file)
@@ -37,6 +37,7 @@ bool AnalysisVisitor::analyzeIndices(TIType & type, ast::CallExp & ce)
     SymbolicDimension first, second;
     bool safe, ret;
 
+    argIndices.emplace(static_cast<ast::SimpleVar &>(ce.getName()).getSymbol(), 1);
     if (size == 1)
     {
         // when there is one argument, a(?) is equivalent to A(?,1)
@@ -57,6 +58,7 @@ bool AnalysisVisitor::analyzeIndices(TIType & type, ast::CallExp & ce)
         ret = getDimension(type.rows, *args.front(), _safe, first);
         if (ret)
         {
+            argIndices.top().getIndex() = 2;
             ret = getDimension(type.cols, *args.back(), safe, second);
             safe = safe && _safe;
         }
@@ -65,6 +67,7 @@ bool AnalysisVisitor::analyzeIndices(TIType & type, ast::CallExp & ce)
             safe = _safe;
         }
     }
+    argIndices.pop();
 
     if (ret)
     {
@@ -86,12 +89,14 @@ bool AnalysisVisitor::getDimension(SymbolicDimension & dim, ast::Exp & arg, bool
         {
             out = dim;
             safe = true;
+            arg.getDecorator().setDollarInfo(argIndices.top());
             return true;
         }
         case ast::Exp::DOLLARVAR : // a($)
         {
             out = SymbolicDimension(getGVN(), 1.);
             safe = true;
+            arg.getDecorator().setDollarInfo(argIndices.top());
             return true;
         }
         case ast::Exp::DOUBLEEXP : // a(12) or a([1 2])
@@ -313,23 +318,25 @@ bool AnalysisVisitor::getDimension(SymbolicDimension & dim, ast::Exp & arg, bool
 
             if (GVN::Value * const v = _res.getConstant().getGVNValue())
             {
+                GVN::Value * w = v;
                 if (GVN::Value * const dollar = getGVN().getExistingValue(symbol::Symbol(L"$")))
                 {
-                    if (GVN::Value * const w = SymbolicList::evalDollar(getGVN(), v, dollar, dim.getValue()))
+                    if (GVN::Value * const x = SymbolicList::evalDollar(getGVN(), v, dollar, dim.getValue()))
                     {
-                        bool b = getCM().check(ConstraintManager::GREATER, dim.getValue(), w);
-                        if (b)
-                        {
-                            safe = getCM().check(ConstraintManager::STRICT_POSITIVE, w);
-                        }
-                        else
-                        {
-                            safe = false;
-                        }
-                        out = SymbolicDimension(getGVN(), 1);
-                        return true;
+                        w = x;
                     }
                 }
+                bool b = getCM().check(ConstraintManager::GREATER, dim.getValue(), w);
+                if (b)
+                {
+                    safe = getCM().check(ConstraintManager::STRICT_POSITIVE, w);
+                }
+                else
+                {
+                    safe = false;
+                }
+                out = SymbolicDimension(getGVN(), 1);
+                return true;
             }
 
             // To use with find
index 8d5cdd3..bc9d7c7 100644 (file)
@@ -55,13 +55,13 @@ void AnalysisVisitor::visit(ast::AssignExp & e)
             }
 
             Result & RR = getResult();
-            // Don't remove tmp... temp.remove(RR); WHY THIS COMMENT ?????
-
             var.getDecorator().res = RR;
             Info & info = getDM().define(sym, RR.getType(), RR.isAnInt(), &e);
             info.getConstant() = RR.getConstant();
             e.getDecorator().safe = true;
-            getDM().releaseTmp(RR.getTempId(), &e.getRightExp());
+
+            // Don't remove temp: because the value is transfered to LHS
+            //getDM().releaseTmp(RR.getTempId(), &e.getRightExp());
         }
     }
     else if (e.getLeftExp().isCallExp()) // A(12) = ...
index 6ecb646..b06cbf8 100644 (file)
@@ -20,6 +20,13 @@ void AnalysisVisitor::visit(ast::DollarVar & e)
     logger.log(L"DollarVar", e.getLocation());
     Result & res = e.getDecorator().setResult(TIType(dm.getGVN(), TIType::POLYNOMIAL, 1, 1));
     res.getConstant() = getGVN().getValue(symbol::Symbol(L"$"));
+
+    if (!argIndices.empty())
+    {
+        // we have something like A(1, $ - 1)
+        e.getDecorator().setDollarInfo(argIndices.top());
+    }
+
     setResult(res);
 }
 
index 6b1e353..748096f 100644 (file)
@@ -28,6 +28,7 @@ void AnalysisVisitor::visit(ast::MatrixExp & e)
         return;
     }
 
+    std::vector<std::pair<int, ast::Exp *>> tempIds;
     GVN::Value * totalColsRef = nullptr;
     GVN::Value * totalRows = getGVN().getValue(0.);
     TIType::Type baseType = TIType::UNKNOWN;
@@ -46,6 +47,11 @@ void AnalysisVisitor::visit(ast::MatrixExp & e)
                 e->accept(*this);
                 Result & res = getResult();
                 TIType & type = res.getType();
+                const int tempId = res.getTempId();
+                if (tempId != -1)
+                {
+                    tempIds.emplace_back(tempId, e);
+                }
                 if (type.type != TIType::EMPTY && type.rows != 0 && type.cols != 0)
                 {
                     if (!baseTypeSet)
@@ -149,6 +155,11 @@ void AnalysisVisitor::visit(ast::MatrixExp & e)
         }
     }
 
+    for (const auto & p : tempIds)
+    {
+        getDM().releaseTmp(p.first, p.second);
+    }
+
     if (checkDims)
     {
         if (!totalRows || !totalColsRef || totalRows->poly->isConstant(0) || totalColsRef->poly->isConstant(0))
index 1ee70d8..e6148b2 100644 (file)
@@ -424,7 +424,7 @@ void PrettyPrintVisitor::visit(const FieldExp & e)
 void PrettyPrintVisitor::visit(const OpExp & e)
 {
     START_NODE(e);
-    print(e);
+    print(RED, e.getString(), e);
     e.getLeft().accept(*this);
     e.getRight().accept(*this);
     END_NODE();