8429c397d5d41799e3619b9ad84a5ea3221e08ab
[scilab.git] / scilab / modules / ast / src / cpp / ast / run_SeqExp.hpp
1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2015 - Scilab Enterprises - Antoine ELIAS
4 *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13 *
14 */
15
16 #include <fstream>
17 //file included in runvisitor.cpp
18 namespace ast {
19
20 template <class T>
21 void RunVisitorT<T>::visitprivate(const SeqExp  &e)
22 {
23     CoverageInstance::invokeAndStartChrono((void*)&e);
24     int lastLine = 0;
25     ast::exps_t exps = e.getExps();
26     ast::exps_t::const_iterator it = exps.begin();
27     ast::exps_t::const_iterator itEnd = exps.end();
28
29
30     /*stuff of printf input during execution*/
31     std::string str;
32     int iCurrentLine = -1; //no data in str
33
34     std::ifstream* file = nullptr;
35     if (e.getExecFrom() == SeqExp::EXEC)
36     {
37         //open input file to print exp from it
38         int iFileID = ConfigVariable::getExecutedFileID();
39         if (iFileID)
40         {
41             const wchar_t* filename = getfile_filename(iFileID);
42             if (filename)
43             {
44                 char* cfilename = wide_string_to_UTF8(filename);
45                 file = new std::ifstream(cfilename);
46                 FREE(cfilename);
47             }
48         }
49     }
50
51     if (exps.size() == 0)
52     {
53         if (ConfigVariable::isExecutionBreak())
54         {
55             ConfigVariable::resetExecutionBreak();
56             if (ConfigVariable::isPrintInteractive())
57             {
58                 ClearTemporaryPrompt();
59             }
60
61             StorePrioritaryCommand("pause");
62             ThreadManagement::WaitForRunMeSignal();
63         }
64
65         // interrupt me to execute a prioritary command
66         while (StaticRunner_isInterruptibleCommand() == 1 && StaticRunner_isRunnerAvailable() == 1)
67         {
68             // save the origin of the actual running command
69             command_origin_t origin = StaticRunner_getCurrentCommandOrigin();
70             StaticRunner_launch();
71             StaticRunner_setInterruptibleCommand(1);
72             // restore the origin of the actual running command
73             StaticRunner_setCurrentCommandOrigin(origin);
74         }
75
76         if (file)
77         {
78             file->close();
79             delete file;
80         }
81
82         CoverageInstance::stopChrono((void*)&e);
83         return;
84     }
85
86     for (; it != itEnd; ++it)
87     {
88         if (ConfigVariable::isExecutionBreak())
89         {
90             ConfigVariable::resetExecutionBreak();
91             if (ConfigVariable::isPrintInteractive())
92             {
93                 ClearTemporaryPrompt();
94             }
95
96             StorePrioritaryCommand("pause");
97             ThreadManagement::WaitForRunMeSignal();
98         }
99
100         // interrupt me to execute a prioritary command
101         while (StaticRunner_isInterruptibleCommand() == 1 && StaticRunner_isRunnerAvailable() == 1)
102         {
103             StaticRunner_launch();
104             StaticRunner_setInterruptibleCommand(1);
105         }
106
107         //printf input expression line following mode configuration
108         if (file && ConfigVariable::isPrintInput())
109         {
110             Location loc = (*it)->getLocation();
111             if (iCurrentLine + 1 < loc.first_line)
112             {
113                 //get prompt
114                 std::string stPrompt = GetCurrentPrompt();
115                 if (ConfigVariable::isPrintInteractive())
116                 {
117                     stPrompt = SCIPROMPT_PAUSE;
118                 }
119
120                 ast::exps_t::const_iterator k = it;
121                 int iLastLine = loc.last_line;
122                 int iCurrentCol = 0; //no data in str
123                 do
124                 {
125                     str = printExp(*file, *k, stPrompt, &iCurrentLine, &iCurrentCol, str);
126                     iLastLine = (*k)->getLocation().last_line;
127                     k++;
128                 } while (k != exps.end() && (*k)->getLocation().first_line == iLastLine);
129             }
130         }
131
132         if ((*it)->isCommentExp())
133         {
134             continue;
135         }
136
137         try
138         {
139             //reset default values
140             setResult(NULL);
141             int iExpectedSize = getExpectedSize();
142             setExpectedSize(-1);
143             (*it)->accept(*this);
144             setExpectedSize(iExpectedSize);
145             types::InternalType * pIT = getResult();
146
147             // In case of exec file, set the file name in the Macro to store where it is defined.
148             int iFileID = ConfigVariable::getExecutedFileID();
149             if (iFileID && (*it)->isFunctionDec())
150             {
151                 types::InternalType* pITMacro = symbol::Context::getInstance()->get((*it)->getAs<FunctionDec>()->getSymbol());
152                 if (pITMacro)
153                 {
154                     types::Macro* pMacro = pITMacro->getAs<types::Macro>();
155                     const wchar_t* filename = getfile_filename(iFileID);
156                     // scilab.quit is not open with mopen
157                     // in this case filename is NULL because FileManager have not been filled.
158                     if (filename)
159                     {
160                         pMacro->setFileName(filename);
161                     }
162                 }
163             }
164
165             if (pIT != NULL)
166             {
167                 bool bImplicitCall = false;
168                 if (pIT->isCallable()) //to manage call without ()
169                 {
170                     types::Callable *pCall = pIT->getAs<types::Callable>();
171                     types::typed_list out;
172                     types::typed_list in;
173                     types::optional_list opt;
174
175                     try
176                     {
177                         //in this case of calling, we can return at most one value
178                         int iSaveExpectedSize = getExpectedSize();
179                         setExpectedSize(0);
180
181                         pCall->invoke(in, opt, getExpectedSize(), out, **it);
182                         setExpectedSize(iSaveExpectedSize);
183
184                         if (out.size() == 0)
185                         {
186                             setResult(NULL);
187                         }
188                         else
189                         {
190                             setResult(out[0]);
191                         }
192
193                         bImplicitCall = true;
194                     }
195                     catch (const InternalError& ie)
196                     {
197                         if (ConfigVariable::getLastErrorFunction() == L"")
198                         {
199                             ConfigVariable::setLastErrorFunction(pCall->getName());
200                             ConfigVariable::setLastErrorLine(e.getLocation().first_line);
201                         }
202                         CoverageInstance::stopChrono((void*)&e);
203                         throw ie;
204                     }
205                 }
206                 else if (pIT->isImplicitList())
207                 {
208                     //expand implicit when possible
209                     types::ImplicitList* pIL = pIT->getAs<types::ImplicitList>();
210                     if (pIL->isComputable())
211                     {
212                         types::InternalType* p = pIL->extractFullMatrix();
213                         if (p)
214                         {
215                             setResult(p);
216                         }
217                     }
218                 }
219
220                 //don't output Simplevar and empty result
221                 if (getResult() != NULL && (!(*it)->isSimpleVar() || bImplicitCall))
222                 {
223                     //symbol::Context::getInstance()->put(symbol::Symbol(L"ans"), *execMe.getResult());
224                     types::InternalType* pITAns = getResult();
225                     symbol::Context::getInstance()->put(m_pAns, pITAns);
226                     if ((*it)->isVerbose() && ConfigVariable::isPrintOutput())
227                     {
228                         //TODO manage multiple returns
229                         scilabWriteW(L" ans  =\n");
230                         if (ConfigVariable::isPrintCompact() == false)
231                         {
232                             scilabWriteW(L"\n");
233                         }
234                         std::wostringstream ostrName;
235                         ostrName << L"ans";
236                         VariableToString(pITAns, ostrName.str().c_str());
237                     }
238                 }
239
240                 pIT->killMe();
241             }
242
243             if (ConfigVariable::isPrintInteractive())
244             {
245                 Location loc = (*it)->getLocation();
246                 if (lastLine < loc.first_line)
247                 {
248                     //break execution
249                     SetTemporaryPrompt(SCIPROMPT_PAUSE);
250
251                     // The console thread must not parse the next console input.
252                     ConfigVariable::setScilabCommand(0);
253
254                     // Get the console input filled by the console thread.
255                     char* pcConsoleReadStr = ConfigVariable::getConsoleReadStr();
256                     ThreadManagement::SendConsoleExecDoneSignal();
257                     while (pcConsoleReadStr == NULL)
258                     {
259                         pcConsoleReadStr = ConfigVariable::getConsoleReadStr();
260                         ThreadManagement::SendConsoleExecDoneSignal();
261                     }
262
263                     // reset flag to default value
264                     ConfigVariable::setScilabCommand(1);
265
266                     if (pcConsoleReadStr && pcConsoleReadStr[0] == 'p' && pcConsoleReadStr[1] == '\0')
267                     {
268                         //mode pause
269                         ConfigVariable::setExecutionBreak();
270                     }
271                 }
272
273                 lastLine = loc.last_line;
274             }
275
276             if ((&e)->isBreakable() && (*it)->isBreak())
277             {
278                 const_cast<SeqExp *>(&e)->setBreak();
279                 (*it)->resetBreak();
280                 break;
281             }
282
283             if ((&e)->isContinuable() && (*it)->isContinue())
284             {
285                 const_cast<SeqExp *>(&e)->setContinue();
286                 (*it)->resetContinue();
287                 break;
288             }
289
290             if ((&e)->isReturnable() && (*it)->isReturn())
291             {
292                 const_cast<SeqExp *>(&e)->setReturn();
293                 (*it)->resetReturn();
294                 break;
295             }
296         }
297         catch (const InternalError& ie)
298         {
299             ConfigVariable::fillWhereError(ie.GetErrorLocation().first_line);
300             CoverageInstance::stopChrono((void*)&e);
301             if (file)
302             {
303                 file->close();
304                 delete file;
305             }
306
307             throw ie;
308         }
309         catch (const InternalAbort& ia)
310         {
311             if (file)
312             {
313                 file->close();
314                 delete file;
315             }
316             throw ia;
317         }
318         // If something other than NULL is given to setResult, then that would imply
319         // to make a cleanup in visit(ForExp) for example (e.getBody().accept(*this);)
320         setResult(NULL);
321     }
322
323     if (file)
324     {
325         file->close();
326         delete file;
327     }
328     CoverageInstance::stopChrono((void*)&e);
329 }
330
331
332 } /* namespace ast */