Merge remote-tracking branch 'origin/master' into jit
[scilab.git] / scilab / modules / ast / src / cpp / ast / macrovarvisitor.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2013 - 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 "macrovarvisitor.hxx"
14 #include "context.hxx"
15
16 namespace ast
17 {
18
19 void MacrovarVisitor::visit (const MatrixLineExp &e)
20 {
21     exps_t columns = e.getColumns();
22     for (exps_t::const_iterator it = columns.begin(), itEnd = columns.end(); it != itEnd ; ++it)
23     {
24         (*it)->accept (*this);
25         add();
26     }
27 }
28
29 void MacrovarVisitor::visit (const SimpleVar &e)
30 {
31     m_current = e.getSymbol().getName();
32 }
33
34 void MacrovarVisitor::visit(const OpExp &e)
35 {
36     e.getLeft().accept(*this);
37     add();
38     e.getRight().accept(*this);
39     add();
40 }
41
42 void MacrovarVisitor::visit(const CallExp &e)
43 {
44     e.getName().accept (*this);
45     if (isAssignExpLeftExp)
46     {
47         add(m_local);
48     }
49     else
50     {
51         add();
52     }
53
54     exps_t args = e.getArgs();
55     for (auto arg : args)
56     {
57         arg->getOriginal()->accept(*this);
58         add();
59     }
60 }
61
62 void MacrovarVisitor::visit (const ForExp  &e)
63 {
64     e.getVardec().accept(*this);
65     add(m_local);
66     e.getBody().accept (*this);
67 }
68
69 void MacrovarVisitor::visit (const FieldExp &e)
70 {
71     e.getHead()->accept(*this);
72     add(m_local);
73 }
74
75 void MacrovarVisitor::visit(const AssignExp &e)
76 {
77     isAssignExpLeftExp = true;
78     e.getLeftExp().getOriginal()->accept (*this);
79     isAssignExpLeftExp = false;
80     if (e.getLeftExp().isSimpleVar())
81     {
82         add(m_local);
83     }
84     else
85     {
86         add();
87     }
88
89     e.getRightExp().getOriginal()->accept (*this);
90     add();
91 }
92
93 void MacrovarVisitor::visit (const AssignListExp  &e)
94 {
95     isAssignExpLeftExp = true;
96     for (exps_t::const_iterator it = e.getExps().begin (), itEnd = e.getExps().end(); it != itEnd; ++it)
97     {
98         (*it)->accept (*this);
99         if ((*it)->isSimpleVar())
100         {
101             add(m_local);
102         }
103         else
104         {
105             add();
106         }
107     }
108     isAssignExpLeftExp = false;
109 }
110
111 void MacrovarVisitor::visit (const VarDec  &e)
112 {
113     m_current = e.getSymbol().getName();
114     add(m_local);
115     e.getInit().getOriginal()->accept(*this);
116     add();
117 }
118
119 void MacrovarVisitor::visit (const FunctionDec  &e)
120 {
121     // Function declared locally but never called
122     // If called then the CallExp visitor does the job
123     m_current = e.getSymbol().getName();
124     add(m_local);
125 }
126
127 std::list<std::wstring>& MacrovarVisitor::getIn()
128 {
129     return m_in;
130 }
131
132 std::list<std::wstring>& MacrovarVisitor::getOut()
133 {
134     return m_out;
135 }
136
137 std::list<std::wstring>& MacrovarVisitor::getExternal()
138 {
139     return m_external;
140 }
141
142 std::list<std::wstring>& MacrovarVisitor::getCalled()
143 {
144     return m_called;
145 }
146
147 std::list<std::wstring>& MacrovarVisitor::getLocal()
148 {
149     return m_local;
150 }
151
152 void MacrovarVisitor::add(std::list<std::wstring>& lst)
153 {
154     if (m_current == L"")
155     {
156         return;
157     }
158
159     if (isAlreadyUsed() == false)
160     {
161         lst.push_back(m_current);
162     }
163
164     m_current = L"";
165 }
166
167 void MacrovarVisitor::add()
168 {
169     types::InternalType* pVar = symbol::Context::getInstance()->get(symbol::Symbol(m_current));
170     if (pVar)
171     {
172         if (pVar->isCallable())
173         {
174             //symbol already exists and callable
175             add(m_called);
176             return;
177         }
178     }
179
180     add(m_external);
181 }
182
183 bool MacrovarVisitor::isAlreadyIn(std::list<std::wstring>& lst)
184 {
185     for (auto l : lst)
186     {
187         if (l == m_current)
188         {
189             return true;
190         }
191     }
192
193     return false;
194 }
195
196 bool MacrovarVisitor::isAlreadyUsed()
197 {
198     if (isAlreadyIn(m_in))
199     {
200         return true;
201     }
202
203     if (isAlreadyIn(m_out))
204     {
205         return true;
206     }
207
208     if (isAlreadyIn(m_external))
209     {
210         return true;
211     }
212
213     if (isAlreadyIn(m_called))
214     {
215         return true;
216     }
217
218     if (isAlreadyIn(m_local))
219     {
220         return true;
221     }
222
223     return false;
224 }
225 }