1af4664a7f9f016839bf45f1613b51e7938add63
[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     for (; it != itEnd; ++it)
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             StaticRunner_launch();
69             StaticRunner_setInterruptibleCommand(1);
70         }
71
72         //printf input expression line following mode configuration
73         if (file && ConfigVariable::isPrintInput())
74         {
75             Location loc = (*it)->getLocation();
76             if (iCurrentLine + 1 < loc.first_line)
77             {
78                 //get prompt
79                 std::string stPrompt = GetCurrentPrompt();
80                 if (ConfigVariable::isPrintInteractive())
81                 {
82                     stPrompt = SCIPROMPT_PAUSE;
83                 }
84
85                 ast::exps_t::const_iterator k = it;
86                 int iLastLine = loc.last_line;
87                 int iCurrentCol = 0; //no data in str
88                 do
89                 {
90                     str = printExp(*file, *k, stPrompt, &iCurrentLine, &iCurrentCol, str);
91                     iLastLine = (*k)->getLocation().last_line;
92                     k++;
93                 } while (k != exps.end() && (*k)->getLocation().first_line == iLastLine);
94             }
95         }
96
97         if ((*it)->isCommentExp())
98         {
99             continue;
100         }
101
102         try
103         {
104             //reset default values
105             setResult(NULL);
106             int iExpectedSize = getExpectedSize();
107             setExpectedSize(-1);
108             (*it)->accept(*this);
109             setExpectedSize(iExpectedSize);
110             types::InternalType * pIT = getResult();
111
112             // In case of exec file, set the file name in the Macro to store where it is defined.
113             int iFileID = ConfigVariable::getExecutedFileID();
114             if (iFileID && (*it)->isFunctionDec())
115             {
116                 types::InternalType* pITMacro = symbol::Context::getInstance()->get((*it)->getAs<FunctionDec>()->getSymbol());
117                 if (pITMacro)
118                 {
119                     types::Macro* pMacro = pITMacro->getAs<types::Macro>();
120                     const wchar_t* filename = getfile_filename(iFileID);
121                     // scilab.quit is not open with mopen
122                     // in this case filename is NULL because FileManager have not been filled.
123                     if (filename)
124                     {
125                         pMacro->setFileName(filename);
126                     }
127                 }
128             }
129
130             if (pIT != NULL)
131             {
132                 bool bImplicitCall = false;
133                 if (pIT->isCallable()) //to manage call without ()
134                 {
135                     types::Callable *pCall = pIT->getAs<types::Callable>();
136                     types::typed_list out;
137                     types::typed_list in;
138                     types::optional_list opt;
139
140                     try
141                     {
142                         //in this case of calling, we can return only one value
143                         int iSaveExpectedSize = getExpectedSize();
144                         setExpectedSize(1);
145
146                         pCall->invoke(in, opt, getExpectedSize(), out, **it);
147                         setExpectedSize(iSaveExpectedSize);
148
149                         if (out.size() == 0)
150                         {
151                             setResult(NULL);
152                         }
153                         else
154                         {
155                             setResult(out[0]);
156                         }
157
158                         bImplicitCall = true;
159                     }
160                     catch (const InternalError& ie)
161                     {
162                         if (ConfigVariable::getLastErrorFunction() == L"")
163                         {
164                             ConfigVariable::setLastErrorFunction(pCall->getName());
165                             ConfigVariable::setLastErrorLine(e.getLocation().first_line);
166                         }
167                         CoverageInstance::stopChrono((void*)&e);
168                         throw ie;
169                     }
170                 }
171                 else if (pIT->isImplicitList())
172                 {
173                     //expand implicit when possible
174                     types::ImplicitList* pIL = pIT->getAs<types::ImplicitList>();
175                     if (pIL->isComputable())
176                     {
177                         types::InternalType* p = pIL->extractFullMatrix();
178                         if (p)
179                         {
180                             setResult(p);
181                         }
182                     }
183                 }
184
185                 //don't output Simplevar and empty result
186                 if (getResult() != NULL && (!(*it)->isSimpleVar() || bImplicitCall))
187                 {
188                     //symbol::Context::getInstance()->put(symbol::Symbol(L"ans"), *execMe.getResult());
189                     types::InternalType* pITAns = getResult();
190                     symbol::Context::getInstance()->put(m_pAns, pITAns);
191                     if ((*it)->isVerbose() && ConfigVariable::isPrintOutput())
192                     {
193                         //TODO manage multiple returns
194                         scilabWriteW(L" ans  =\n\n");
195                         std::wostringstream ostrName;
196                         ostrName << L"ans";
197                         VariableToString(pITAns, ostrName.str().c_str());
198                     }
199                 }
200
201                 pIT->killMe();
202             }
203
204             if (ConfigVariable::isPrintInteractive())
205             {
206                 Location loc = (*it)->getLocation();
207                 if (lastLine < loc.first_line)
208                 {
209                     //break execution
210                     SetTemporaryPrompt(SCIPROMPT_PAUSE);
211
212                     // The console thread must not parse the next console input.
213                     ConfigVariable::setScilabCommand(0);
214
215                     // Get the console input filled by the console thread.
216                     char* pcConsoleReadStr = ConfigVariable::getConsoleReadStr();
217                     ThreadManagement::SendConsoleExecDoneSignal();
218                     while (pcConsoleReadStr == NULL)
219                     {
220                         pcConsoleReadStr = ConfigVariable::getConsoleReadStr();
221                         ThreadManagement::SendConsoleExecDoneSignal();
222                     }
223
224                     // reset flag to default value
225                     ConfigVariable::setScilabCommand(1);
226
227                     if (pcConsoleReadStr && pcConsoleReadStr[0] == 'p' && pcConsoleReadStr[1] == '\0')
228                     {
229                         //mode pause
230                         ConfigVariable::setExecutionBreak();
231                     }
232                 }
233
234                 lastLine = loc.last_line;
235             }
236
237             if ((&e)->isBreakable() && (*it)->isBreak())
238             {
239                 const_cast<SeqExp *>(&e)->setBreak();
240                 (*it)->resetBreak();
241                 break;
242             }
243
244             if ((&e)->isContinuable() && (*it)->isContinue())
245             {
246                 const_cast<SeqExp *>(&e)->setContinue();
247                 (*it)->resetContinue();
248                 break;
249             }
250
251             if ((&e)->isReturnable() && (*it)->isReturn())
252             {
253                 const_cast<SeqExp *>(&e)->setReturn();
254                 (*it)->resetReturn();
255                 break;
256             }
257         }
258         catch (const InternalError& ie)
259         {
260             ConfigVariable::fillWhereError(ie.GetErrorLocation().first_line);
261             CoverageInstance::stopChrono((void*)&e);
262             if (file)
263             {
264                 file->close();
265                 delete file;
266             }
267
268             throw ie;
269         }
270         catch (const InternalAbort& ia)
271         {
272             if (file)
273             {
274                 file->close();
275                 delete file;
276             }
277             throw ia;
278         }
279         // If something other than NULL is given to setResult, then that would imply
280         // to make a cleanup in visit(ForExp) for example (e.getBody().accept(*this);)
281         setResult(NULL);
282     }
283
284     if (file)
285     {
286         file->close();
287         delete file;
288     }
289     CoverageInstance::stopChrono((void*)&e);
290 }
291
292
293 } /* namespace ast */