a673b2b2185edd51f487ead23b28c83f96bc8f35
[scilab.git] / scilab / modules / core / src / cpp / tasks.cpp
1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2009-2009 - DIGITEO - Bruno JOFRET
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 "AnalysisVisitor.hxx"
17 #include "FBlockListener.hxx"
18 #include "tasks.hxx"
19 #include "timer.hxx"
20 #include "context.hxx"
21 #include "visitor.hxx"
22 #include "printvisitor.hxx"
23 #include "execvisitor.hxx"
24 #include "timedvisitor.hxx"
25 #include "prettyprintvisitor.hxx"
26 #include "debuggervisitor.hxx"
27 #include "stepvisitor.hxx"
28 #include "visitor_common.hxx"
29 #include "threadmanagement.hxx"
30
31 #include "scilabWrite.hxx"
32 #include "runner.hxx"
33
34 #define SCILAB_START    L"/etc/scilab.start"
35 #define SCILAB_QUIT     L"/etc/scilab.quit"
36
37 Timer _timer;
38
39 //#define DEBUG
40
41 /*
42 ** Parse
43 **
44 ** Parse the given file and create the AST.
45 */
46 void parseFileTask(Parser *parser, bool timed, const wchar_t* file_name, const wchar_t* prog_name)
47 {
48 #ifdef DEBUG
49     std::cerr << "*** Processing " << file_name << " file..." << std::endl;
50 #endif
51
52     if (timed)
53     {
54         _timer.start();
55     }
56
57     parser->parseFile(file_name, prog_name);
58
59     if (timed)
60     {
61         _timer.check(L"Parsing");
62     }
63 }
64
65 /*
66 ** Parse
67 **
68 ** Parse the given command and create the AST.
69 */
70 void parseCommandTask(Parser *parser, bool timed, char *command)
71 {
72 #ifdef DEBUG
73     std::cerr << "*** Processing [" <<  command << "]..." << std::endl;
74 #endif
75
76     if (timed)
77     {
78         _timer.start();
79     }
80
81     parser->parse(command);
82
83     if (timed && parser->getControlStatus() == Parser::AllControlClosed)
84     {
85         _timer.check(L"Parsing");
86     }
87 }
88
89 /*
90 ** Dump AST
91 **
92 ** Display the AST in human readable format.
93 */
94 void dumpAstTask(ast::Exp *tree, bool timed)
95 {
96     if (timed)
97     {
98         _timer.start();
99     }
100
101     ast::PrettyPrintVisitor debugMe;
102     if (tree)
103     {
104         tree->accept(debugMe);
105     }
106
107     if (timed)
108     {
109         _timer.check(L"AST Dump");
110     }
111 }
112
113 /*
114 ** Pretty Print
115 **
116 ** Pretty print the Stored AST.
117 */
118 void printAstTask(ast::Exp *tree, bool timed)
119 {
120     if (timed)
121     {
122         _timer.start();
123     }
124
125     if (tree)
126     {
127         ast::PrintVisitor printMe (std::wcout);
128         tree->accept(printMe);
129     }
130
131     if (timed)
132     {
133         _timer.check(L"Pretty Print");
134     }
135 }
136
137
138 /*
139 ** Exec Tree
140 **
141 ** Execute the stored AST.
142 */
143 void execAstTask(ast::Exp* tree, bool serialize, bool timed, bool ASTtimed, bool execVerbose,
144                  bool isInterruptibleThread, bool isPrioritaryThread, command_origin_t iCommandOrigin)
145 {
146     if (tree == NULL)
147     {
148         return;
149     }
150
151     ast::Exp* newTree = NULL;
152     if (serialize)
153     {
154         if (timed)
155         {
156             newTree = callTyper(tree, L"tasks");
157         }
158         else
159         {
160             newTree = callTyper(tree);
161         }
162
163         delete tree;
164     }
165     else
166     {
167         newTree = tree;
168     }
169
170     ast::RunVisitor *exec;
171     if (timed)
172     {
173         _timer.start();
174     }
175
176     if (ASTtimed)
177     {
178         exec = new ast::TimedVisitor();
179     }
180     else if (execVerbose)
181     {
182         exec = new ast::StepVisitor();
183     }
184     else
185     {
186         //call analyzer visitor before exec visitor
187         if (ConfigVariable::getAnalyzerOptions() == 1)
188         {
189             FBlockListener listener;
190             analysis::AnalysisVisitor& analysis = analysis::AnalysisVisitor::getInstance();
191             analysis.reset();
192             analysis.registerFBlockEmittedListener(&listener);
193             newTree->accept(analysis);
194         }
195
196         exec = (ast::RunVisitor*)ConfigVariable::getDefaultVisitor();
197     }
198
199     StaticRunner::execAndWait(newTree, exec, isInterruptibleThread, isPrioritaryThread, iCommandOrigin);
200     //DO NOT DELETE tree or newTree, they was deleted by Runner or previously;
201
202     if (timed)
203     {
204         _timer.check(L"Execute AST");
205     }
206 }
207
208 /*
209 ** Dump Stack Trace
210 **
211 ** Display what is stored in scilab.
212 */
213 void dumpStackTask(bool timed)
214 {
215     if (timed)
216     {
217         _timer.start();
218     }
219
220     symbol::Context::getInstance()->print(std::wcout);
221
222     if (timed)
223     {
224         _timer.check(L"Dumping Stack");
225     }
226 }
227
228 /*
229 ** Execute scilab.start
230 **
231 */
232 int execScilabStartTask(bool _bSerialize)
233 {
234     Parser parse;
235     std::wstring stSCI = ConfigVariable::getSCIPath();
236     stSCI += SCILAB_START;
237
238     ThreadManagement::LockParser();
239     try
240     {
241         parse.parseFile(stSCI, L"");
242     }
243     catch (const ast::InternalError& ie)
244     {
245         scilabWrite(ie.what());
246         ThreadManagement::UnlockParser();
247         return 1;
248     }
249
250     if (parse.getExitStatus() != Parser::Succeded)
251     {
252         scilabWriteW(parse.getErrorMessage());
253         scilabWriteW(L"Failed to parse scilab.start");
254         ThreadManagement::UnlockParser();
255         return 1;
256     }
257     ThreadManagement::UnlockParser();
258
259     ast::Exp* newTree = parse.getTree();
260     if (_bSerialize)
261     {
262         newTree = callTyper(parse.getTree());
263     }
264
265     return StaticRunner::exec(newTree, new ast::ExecVisitor()) ? 0 : 1;
266 }
267
268 /*
269 ** Execute scilab.quit
270 **
271 */
272 int execScilabQuitTask(bool _bSerialize)
273 {
274     Parser parse;
275     std::wstring stSCI = ConfigVariable::getSCIPath();
276     stSCI += SCILAB_QUIT;
277
278     //delete analysisVisitor
279     analysis::AnalysisVisitor::deleteInstance();
280
281     ThreadManagement::LockParser();
282     try
283     {
284         parse.parseFile(stSCI, L"");
285     }
286     catch (const ast::InternalError& ie)
287     {
288         scilabWrite(ie.what());
289         ThreadManagement::UnlockParser();
290         return 1;
291     }
292
293     if (parse.getExitStatus() != Parser::Succeded)
294     {
295         scilabWriteW(parse.getErrorMessage());
296         scilabWriteW(L"Failed to parse scilab.quit");
297         ThreadManagement::UnlockParser();
298         return 1;
299     }
300     ThreadManagement::UnlockParser();
301
302     ast::Exp* newTree = parse.getTree();
303     if (_bSerialize)
304     {
305         newTree = callTyper(parse.getTree());
306     }
307
308     return StaticRunner::exec(newTree, new ast::ExecVisitor()) ? 0 : 1;
309 }
310
311
312 ast::Exp* parseCommand(std::wstring _command)
313 {
314     if (_command.empty())
315     {
316         return NULL;
317     }
318
319     Parser parse;
320     parse.parse((wchar_t*)_command.c_str());
321     if (parse.getExitStatus() != Parser::Succeded)
322     {
323         return NULL;
324     }
325
326     return parse.getTree();
327 }