fix axes.y_ticks.location
[scilab.git] / scilab / modules / ast / src / cpp / ast / runvisitor.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2014 - 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 <string>
14
15 #include "runvisitor.hxx"
16 #include "execvisitor.hxx"
17 #include "stepvisitor.hxx"
18 #include "timedvisitor.hxx"
19 #include "shortcutvisitor.hxx"
20 #include "printvisitor.hxx"
21 #include "mutevisitor.hxx"
22
23 #include "visitor_common.hxx"
24
25 #include "context.hxx"
26 #include "generic_operations.hxx"
27 #include "types_or.hxx"
28 #include "types_and.hxx"
29 #include "localization.hxx"
30
31 #include "macrofile.hxx"
32 #include "macro.hxx"
33
34 extern "C"
35 {
36 #include "sciprint.h"
37 #include "os_swprintf.h"
38 #include "elem_common.h"
39 }
40
41
42
43 namespace ast
44 {
45 template <class T>
46 void RunVisitorT<T>::visitprivate(const CellExp &e)
47 {
48     exps_t::const_iterator row;
49     exps_t::const_iterator col;
50     int iColMax = 0;
51
52     exps_t lines = e.getLines();
53     //check dimmension
54     for (row = lines.begin() ; row != lines.end() ; ++row )
55     {
56         exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
57         if (iColMax == 0)
58         {
59             iColMax = static_cast<int>(cols.size());
60         }
61
62         if (iColMax != static_cast<int>(cols.size()))
63         {
64             std::wostringstream os;
65             os << _W("inconsistent row/column dimensions\n");
66             //os << ((Location)(*row)->getLocation()).getLocationString() << std::endl;
67             throw ScilabError(os.str(), 999, (*row)->getLocation());
68         }
69     }
70
71     //alloc result cell
72     types::Cell *pC = new types::Cell(static_cast<int>(lines.size()), iColMax);
73
74     int i = 0;
75     int j = 0;
76
77     //insert items in cell
78     for (i = 0, row = lines.begin() ; row != lines.end() ; ++row, ++i)
79     {
80         exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
81         for (j = 0, col = cols.begin() ; col != cols.end() ; ++col, ++j)
82         {
83             (*col)->accept(*this);
84             InternalType *pIT = getResult();
85             if (pIT->isImplicitList())
86             {
87                 InternalType * _pIT = pIT->getAs<ImplicitList>()->extractFullMatrix();
88                 pC->set(i, j, _pIT);
89                 _pIT->killMe();
90             }
91             else
92             {
93                 pC->set(i, j, pIT);
94             }
95             clearResult();
96         }
97     }
98
99     //return new cell
100     setResult(pC);
101 }
102
103 template <class T>
104 void RunVisitorT<T>::visitprivate(const FieldExp &e)
105 {
106     /*
107       a.b
108     */
109
110     if (!e.getTail()->isSimpleVar())
111     {
112         wchar_t szError[bsiz];
113         os_swprintf(szError, bsiz, _W("/!\\ Unmanaged FieldExp.\n").c_str());
114         throw ScilabError(szError, 999, e.getLocation());
115     }
116
117     try
118     {
119         e.getHead()->accept(*this);
120     }
121     catch (const ScilabError& error)
122     {
123         throw error;
124     }
125
126     if (getResult() == NULL)
127     {
128         wchar_t szError[bsiz];
129         os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
130         throw ScilabError(szError, 999, e.getLocation());
131     }
132
133     // TODO: handle case where getSize() > 1
134     // l=list(struct("toto","coucou"),struct("toto","hello"),1,2);[a,b]=l(1:2).toto
135     //
136     if (getResultSize() > 1)
137     {
138         clearResult();
139         wchar_t szError[bsiz];
140         os_swprintf(szError, bsiz, _W("Not yet implemented in Scilab.\n").c_str());
141         throw ScilabError(szError, 999, e.getLocation());
142     }
143
144     SimpleVar * psvRightMember = static_cast<SimpleVar *>(const_cast<Exp *>(e.getTail()));
145     std::wstring wstField = psvRightMember->getSymbol().getName();
146     InternalType * pValue = getResult();
147     InternalType * pReturn = NULL;
148     bool ok = false;
149
150     try
151     {
152         if (pValue->isGenericType())
153         {
154             ok = pValue->getAs<GenericType>()->extract(wstField, pReturn);
155         }
156     }
157     catch (std::wstring & err)
158     {
159         pValue->killMe();
160         throw ScilabError(err.c_str(), 999, e.getTail()->getLocation());
161     }
162
163     if (ok)
164     {
165         if (pReturn == NULL)
166         {
167             std::wostringstream os;
168             os << _W("Invalid index.\n");
169             throw ScilabError(os.str(), 999, e.getLocation());
170         }
171
172         setResult(pReturn);
173         if (pValue->isDeletable())
174         {
175             if (pValue->isContainer())
176             {
177                 // prevent delete of pReturn in case where
178                 // extract not return a clone
179                 pReturn->IncreaseRef();
180                 pValue->killMe();
181                 pReturn->DecreaseRef();
182             }
183             else
184             {
185                 pValue->killMe();
186             }
187         }
188     }
189     else if (pValue->isFieldExtractionOverloadable())
190     {
191         types::typed_list in;
192         types::typed_list out;
193
194         String* pS = new String(wstField.c_str());
195
196         //TODO: in the case where overload is a macro there is no need to incref in
197         // because args will be put in context, removed and killed if required.
198         // But if the overload is a function... it is another story...
199
200         pS->IncreaseRef();
201         pValue->IncreaseRef();
202
203         in.push_back(pS);
204         in.push_back(pValue);
205         Callable::ReturnValue Ret = Callable::Error;
206
207         try
208         {
209             Ret = Overload::call(L"%" + pValue->getShortTypeStr() + L"_e", in, 1, out, this);
210         }
211         catch (ast::ScilabError & se)
212         {
213             // TList or Mlist
214             if (pValue->isList())
215             {
216                 Ret = Overload::call(L"%l_e", in, 1, out, this);
217             }
218             else
219             {
220                 throw se;
221             }
222         }
223
224         if (Ret != Callable::OK)
225         {
226             cleanInOut(in, out);
227             throw ScilabError();
228         }
229
230         setResult(out);
231         cleanIn(in, out);
232     }
233     else
234     {
235         pValue->killMe();
236         wchar_t szError[bsiz];
237         os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
238         throw ScilabError(szError, 999, e.getLocation());
239     }
240 }
241
242 template <class T>
243 void RunVisitorT<T>::visitprivate(const IfExp  &e)
244 {
245     //Create local exec visitor
246     ShortCutVisitor SCTest;
247     bool bTestStatus = false;
248
249     //condition
250     e.getTest().accept(SCTest);
251     e.getTest().accept(*this);
252
253     bTestStatus = getResult()->isTrue();
254     clearResult();
255     if (bTestStatus == true)
256     {
257         //condition == true
258         if (e.isBreakable())
259         {
260             const_cast<IfExp*>(&e)->resetBreak();
261             const_cast<Exp*>(&e.getThen())->setBreakable();
262         }
263
264         if (e.isContinuable())
265         {
266             const_cast<IfExp*>(&e)->resetContinue();
267             const_cast<Exp*>(&e.getThen())->setContinuable();
268         }
269
270         if (e.isReturnable())
271         {
272             const_cast<IfExp*>(&e)->resetReturn();
273             const_cast<Exp*>(&e.getThen())->setReturnable();
274         }
275
276         e.getThen().accept(*this);
277     }
278     else
279     {
280         //condition == false
281
282         if (e.hasElse())
283         {
284             if (e.isBreakable())
285             {
286                 const_cast<Exp*>(&e.getElse())->setBreakable();
287             }
288
289             if (e.isContinuable())
290             {
291                 const_cast<IfExp*>(&e)->resetContinue();
292                 const_cast<Exp*>(&e.getElse())->setContinuable();
293             }
294
295             if (e.isReturnable())
296             {
297                 const_cast<Exp*>(&e.getElse())->setReturnable();
298             }
299
300             e.getElse().accept(*this);
301         }
302     }
303
304     if (e.isBreakable()
305             && ( (&e.getElse())->isBreak()
306                  || (&e.getThen())->isBreak() ))
307     {
308         const_cast<IfExp*>(&e)->setBreak();
309         const_cast<Exp*>(&e.getElse())->resetBreak();
310         const_cast<Exp*>(&e.getThen())->resetBreak();
311     }
312
313     if (e.isContinuable()
314             && ( (&e.getElse())->isContinue()
315                  || (&e.getThen())->isContinue() ))
316     {
317         const_cast<IfExp*>(&e)->setContinue();
318         const_cast<Exp*>(&e.getElse())->resetContinue();
319         const_cast<Exp*>(&e.getThen())->resetContinue();
320     }
321
322     if (e.isReturnable()
323             && ( (&e.getElse())->isReturn()
324                  || (&e.getThen())->isReturn() ))
325     {
326         const_cast<IfExp*>(&e)->setReturn();
327         const_cast<Exp*>(&e.getElse())->resetReturn();
328         const_cast<Exp*>(&e.getThen())->resetReturn();
329     }
330 }
331
332 template <class T>
333 void RunVisitorT<T>::visitprivate(const WhileExp  &e)
334 {
335     //allow break and continue operations
336     const_cast<Exp*>(&e.getBody())->setBreakable();
337     const_cast<Exp*>(&e.getBody())->setContinuable();
338     //allow return operation
339     if (e.isReturnable())
340     {
341         const_cast<Exp*>(&(e.getBody()))->setReturnable();
342     }
343
344     //condition
345     e.getTest().accept(*this);
346     while (getResult()->isTrue())
347     {
348         e.getBody().accept(*this);
349         if (e.getBody().isBreak())
350         {
351             const_cast<Exp*>(&(e.getBody()))->resetBreak();
352             break;
353         }
354
355         if (e.getBody().isReturn())
356         {
357             const_cast<WhileExp*>(&e)->setReturn();
358             const_cast<Exp*>(&(e.getBody()))->resetReturn();
359             break;
360         }
361
362         if (e.getBody().isContinue())
363         {
364             const_cast<WhileExp*>(&e)->setContinue();
365             const_cast<Exp*>(&(e.getBody()))->resetContinue();
366             e.getTest().accept(*this);
367             continue;
368         }
369
370         //clear old result value before evaluate new one
371         if (getResult() != NULL)
372         {
373             getResult()->killMe();
374         }
375
376         e.getTest().accept(*this);
377     }
378
379     //clear result of condition or result of body
380     clearResult();
381 }
382
383 template <class T>
384 void RunVisitorT<T>::visitprivate(const ForExp  &e)
385 {
386     e.getVardec().accept(*this);
387     InternalType* pIT = getResult();
388     //allow break and continue operations
389     const_cast<Exp&>(e.getBody()).setBreakable();
390     const_cast<Exp&>(e.getBody()).setContinuable();
391
392     //allow return operation
393     if (e.isReturnable())
394     {
395         const_cast<Exp&>(e.getBody()).setReturnable();
396     }
397
398     if (pIT->isImplicitList())
399     {
400         ImplicitList* pVar = pIT->getAs<ImplicitList>();
401         for (int i = 0; i < pVar->getSize(); ++i)
402         {
403             //TODO : maybe it would be interesting here to reuse the same InternalType (to avoid delete/new)
404             InternalType * pIL = pVar->extractValue(i);
405             symbol::Context::getInstance()->put(e.getVardec().getAs<VarDec>()->getStack(), pIL);
406
407             e.getBody().accept(*this);
408             if (e.getBody().isBreak())
409             {
410                 const_cast<Exp&>(e.getBody()).resetBreak();
411                 break;
412             }
413
414             if (e.getBody().isContinue())
415             {
416                 const_cast<Exp&>(e.getBody()).resetContinue();
417                 continue;
418             }
419
420             if (e.getBody().isReturn())
421             {
422                 const_cast<ForExp&>(e).setReturn();
423                 break;
424             }
425         }
426     }
427     else if (pIT->isList())
428     {
429         List* pL = pIT->getAs<List>();
430         const int size = pL->getSize();
431         for (int i = 0; i < size; ++i)
432         {
433             InternalType* pNew = pL->get(i);
434             symbol::Context::getInstance()->put(e.getVardec().getAs<VarDec>()->getStack(), pNew);
435
436             e.getBody().accept(*this);
437             if (e.getBody().isBreak())
438             {
439                 const_cast<Exp*>(&(e.getBody()))->resetBreak();
440                 break;
441             }
442
443             if (e.getBody().isContinue())
444             {
445                 const_cast<Exp*>(&(e.getBody()))->resetContinue();
446                 continue;
447             }
448
449             if (e.getBody().isReturn())
450             {
451                 const_cast<ForExp*>(&e)->setReturn();
452                 break;
453             }
454         }
455     }
456     else if (pIT->isGenericType())
457     {
458         //Matrix i = [1,3,2,6] or other type
459         GenericType* pVar = pIT->getAs<GenericType>();
460         if (pVar->getDims() > 2)
461         {
462             pIT->DecreaseRef();
463             pIT->killMe();
464             throw ScilabError(_W("for expression can only manage 1 or 2 dimensions variables\n"), 999, e.getVardec().getLocation());
465         }
466
467         for (int i = 0; i < pVar->getCols(); i++)
468         {
469             GenericType* pNew = pVar->getColumnValues(i);
470             if (pNew == NULL)
471             {
472                 pIT->DecreaseRef();
473                 pIT->killMe();
474                 throw ScilabError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
475             }
476
477             symbol::Context::getInstance()->put(e.getVardec().getAs<VarDec>()->getStack(), pNew);
478
479             e.getBody().accept(*this);
480             if (e.getBody().isBreak())
481             {
482                 const_cast<Exp*>(&(e.getBody()))->resetBreak();
483                 break;
484             }
485
486             if (e.getBody().isContinue())
487             {
488                 const_cast<Exp*>(&(e.getBody()))->resetContinue();
489                 continue;
490             }
491
492             if (e.getBody().isReturn())
493             {
494                 const_cast<ForExp*>(&e)->setReturn();
495                 break;
496             }
497         }
498     }
499     else
500     {
501         pIT->DecreaseRef();
502         pIT->killMe();
503         throw ScilabError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
504     }
505
506     pIT->DecreaseRef();
507     pIT->killMe();
508
509     setResult(NULL);
510 }
511
512 template <class T>
513 void RunVisitorT<T>::visitprivate(const ReturnExp &e)
514 {
515     if (e.isGlobal())
516     {
517         if (ConfigVariable::getPauseLevel() != 0 && symbol::Context::getInstance()->getScopeLevel() == ConfigVariable::getActivePauseLevel())
518         {
519             //return or resume
520             ThreadId* pThreadId = ConfigVariable::getLastPausedThread();
521             if (pThreadId == NULL)
522             {
523                 //no paused thread, so just go leave
524                 return;
525             }
526
527             //force exit without prompt of current thread ( via Aborted status )
528             ThreadId* pMe = ConfigVariable::getThread(__GetCurrentThreadKey());
529             pMe->setStatus(ThreadId::Aborted);
530
531             //resume previous execution thread
532             pThreadId->resume();
533
534             return;
535         }
536         else
537         {
538             const_cast<ReturnExp*>(&e)->setReturn();
539         }
540     }
541     else
542     {
543         //return(x)
544
545         //in case of CallExp, we can return only one values
546         int iSaveExpectedSize = getExpectedSize();
547         setExpectedSize(1);
548         e.getExp().accept(*this);
549         setExpectedSize(iSaveExpectedSize);
550         const_cast<ReturnExp*>(&e)->setReturn();
551     }
552 }
553
554 template <class T>
555 void RunVisitorT<T>::visitprivate(const SelectExp &e)
556 {
557     // FIXME : exec select ... case ... else ... end
558     e.getSelect()->accept(*this);
559     bool bCase = false;
560
561
562     InternalType* pIT = getResult();
563     setResult(NULL);
564     if (pIT)
565     {
566         //find good case
567         exps_t::iterator it;
568         exps_t* cases = e.getCases();
569         for (it = cases->begin(); it != cases->end() ; it++)
570         {
571             CaseExp* pCase = (*it)->getAs<CaseExp>();
572             pCase->getTest()->accept(*this);
573             InternalType *pITCase = getResult();
574             setResult(NULL);
575             if (pITCase)
576             {
577                 if (pITCase->isContainer()) //WARNING ONLY FOR CELL
578                 {
579                     //check each item
580                 }
581                 else if (*pITCase == *pIT)
582                 {
583                     if (e.isBreakable())
584                     {
585                         const_cast<SelectExp*>(&e)->resetBreak();
586                         pCase->getBody()->setBreakable();
587                     }
588
589                     if (e.isContinuable())
590                     {
591                         const_cast<SelectExp*>(&e)->resetContinue();
592                         pCase->getBody()->setContinuable();
593                     }
594
595                     if (e.isReturnable())
596                     {
597                         const_cast<SelectExp*>(&e)->resetReturn();
598                         pCase->getBody()->setReturnable();
599                     }
600
601                     //the good one
602                     pCase->getBody()->accept(*this);
603
604                     if (e.isBreakable() && pCase->getBody()->isBreak())
605                     {
606                         const_cast<SelectExp*>(&e)->setBreak();
607                         pCase->getBody()->resetBreak();
608                     }
609
610                     if (e.isContinuable() && pCase->getBody()->isContinue())
611                     {
612                         const_cast<SelectExp*>(&e)->setContinue();
613                         pCase->getBody()->resetContinue();
614                     }
615
616                     if (e.isReturnable() && pCase->getBody()->isReturn())
617                     {
618                         const_cast<SelectExp*>(&e)->setReturn();
619                         pCase->getBody()->resetReturn();
620                     }
621
622                     bCase = true;
623                     break;
624                 }
625             }
626         }
627
628         delete cases;
629     }
630
631     if (bCase == false && e.getDefaultCase() != NULL)
632     {
633         if (e.isBreakable())
634         {
635             const_cast<SelectExp*>(&e)->resetBreak();
636             e.getDefaultCase()->setBreakable();
637         }
638
639         if (e.isContinuable())
640         {
641             const_cast<SelectExp*>(&e)->resetContinue();
642             e.getDefaultCase()->setContinuable();
643         }
644
645         if (e.isReturnable())
646         {
647             const_cast<SelectExp*>(&e)->resetReturn();
648             e.getDefaultCase()->setReturnable();
649         }
650
651         //default case
652         e.getDefaultCase()->accept(*this);
653
654         if (e.isBreakable() && e.getDefaultCase()->isBreak())
655         {
656             const_cast<SelectExp*>(&e)->setBreak();
657             e.getDefaultCase()->resetBreak();
658         }
659
660         if (e.isContinuable() && e.getDefaultCase()->isContinue())
661         {
662             const_cast<SelectExp*>(&e)->setContinue();
663             e.getDefaultCase()->resetContinue();
664         }
665
666         if (e.isReturnable() && e.getDefaultCase()->isReturn())
667         {
668             const_cast<SelectExp*>(&e)->setReturn();
669             e.getDefaultCase()->resetReturn();
670         }
671     }
672
673     clearResult();
674 }
675
676 template <class T>
677 void RunVisitorT<T>::visitprivate(const SeqExp  &e)
678 {
679     //T execMe;
680     exps_t::const_iterator itExp;
681     exps_t exps = e.getExps();
682
683     for (itExp = exps.begin (); itExp != exps.end (); ++itExp)
684     {
685         if (e.isBreakable())
686         {
687             (*itExp)->resetBreak();
688             (*itExp)->setBreakable();
689         }
690
691         if (e.isContinuable())
692         {
693             (*itExp)->resetContinue();
694             (*itExp)->setContinuable();
695         }
696
697         if (e.isReturnable())
698         {
699             (*itExp)->setReturnable();
700         }
701
702         try
703         {
704             //reset default values
705             setResult(NULL);
706             setExpectedSize(-1);
707             (*itExp)->accept(*this);
708             InternalType * pIT = getResult();
709
710             if (pIT != NULL)
711             {
712                 bool bImplicitCall = false;
713                 if (pIT->isCallable()) //to manage call without ()
714                 {
715                     Callable *pCall = pIT->getAs<Callable>();
716                     typed_list out;
717                     typed_list in;
718                     optional_list opt;
719
720                     try
721                     {
722                         //in this case of calling, we can return only one values
723                         int iSaveExpectedSize = getExpectedSize();
724                         setExpectedSize(1);
725                         Function::ReturnValue Ret = pCall->call(in, opt, getExpectedSize(), out, this);
726                         setExpectedSize(iSaveExpectedSize);
727
728                         if (Ret == Callable::OK)
729                         {
730                             if (out.size() == 0)
731                             {
732                                 setResult(NULL);
733                             }
734                             else
735                             {
736                                 setResult(out[0]);
737                             }
738                             bImplicitCall = true;
739                         }
740                         else if (Ret == Callable::Error)
741                         {
742                             if (ConfigVariable::getLastErrorFunction() == L"")
743                             {
744                                 ConfigVariable::setLastErrorFunction(pCall->getName());
745                                 ConfigVariable::setLastErrorLine(e.getLocation().first_line);
746                                 throw ScilabError();
747                             }
748
749                             if (pCall->isMacro() || pCall->isMacroFile())
750                             {
751                                 wchar_t szError[bsiz];
752                                 os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), (*itExp)->getLocation().first_line, pCall->getName().c_str());
753                                 throw ScilabMessage(szError);
754                             }
755                             else
756                             {
757                                 throw ScilabMessage();
758                             }
759                         }
760                     }
761                     catch (ScilabMessage sm)
762                     {
763                         wostringstream os;
764                         PrintVisitor printMe(os);
765                         (*itExp)->accept(printMe);
766                         //os << std::endl << std::endl;
767                         if (ConfigVariable::getLastErrorFunction() == L"")
768                         {
769                             ConfigVariable::setLastErrorFunction(pCall->getName());
770                         }
771
772                         if (pCall->isMacro() || pCall->isMacroFile())
773                         {
774                             wchar_t szError[bsiz];
775                             os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), sm.GetErrorLocation().first_line, pCall->getName().c_str());
776                             throw ScilabMessage(szError + os.str());
777                         }
778                         else
779                         {
780                             sm.SetErrorMessage(sm.GetErrorMessage() + os.str());
781                             throw sm;
782                         }
783                     }
784                 }
785
786                 //don't output Simplevar and empty result
787                 if (getResult() != NULL && (!(*itExp)->isSimpleVar() || bImplicitCall))
788                 {
789                     //symbol::Context::getInstance()->put(symbol::Symbol(L"ans"), *execMe.getResult());
790                     InternalType* pITAns = getResult();
791                     symbol::Context::getInstance()->put(m_pAns, pITAns);
792                     if ((*itExp)->isVerbose() && ConfigVariable::isPromptShow())
793                     {
794                         //TODO manage multiple returns
795                         scilabWriteW(L" ans  =\n\n");
796                         std::wostringstream ostrName;
797                         ostrName << L"ans";
798                         VariableToString(pITAns, ostrName.str().c_str());
799                     }
800                 }
801
802                 pIT->killMe();
803             }
804
805             if ((&e)->isBreakable() && (*itExp)->isBreak())
806             {
807                 const_cast<SeqExp *>(&e)->setBreak();
808                 break;
809             }
810
811             if ((&e)->isContinuable() && (*itExp)->isContinue())
812             {
813                 const_cast<SeqExp *>(&e)->setContinue();
814                 break;
815             }
816
817             if ((&e)->isReturnable() && (*itExp)->isReturn())
818             {
819                 const_cast<SeqExp *>(&e)->setReturn();
820                 (*itExp)->resetReturn();
821                 break;
822             }
823         }
824         catch (const ScilabMessage& sm)
825         {
826             scilabErrorW(sm.GetErrorMessage().c_str());
827
828             CallExp* pCall = dynamic_cast<CallExp*>(*itExp);
829             if (pCall != NULL)
830             {
831                 //to print call expression only of it is a macro
832                 pCall->getName().accept(*this);
833
834                 if (getResult() != NULL && (getResult()->isMacro() || getResult()->isMacroFile()))
835                 {
836                     wostringstream os;
837                     PrintVisitor printMe(os);
838                     pCall->accept(printMe);
839                     //os << std::endl << std::endl;
840                     if (ConfigVariable::getLastErrorFunction() == L"")
841                     {
842                         ConfigVariable::setLastErrorFunction(((InternalType*)getResult())->getAs<Callable>()->getName());
843                     }
844                     throw ScilabMessage(os.str(), 0, (*itExp)->getLocation());
845                 }
846             }
847
848             throw ScilabMessage((*itExp)->getLocation());
849         }
850         catch (const ScilabError& se)
851         {
852             // check on error number because error message can be empty.
853             if (ConfigVariable::getLastErrorNumber() == 0)
854             {
855                 ConfigVariable::setLastErrorMessage(se.GetErrorMessage());
856                 ConfigVariable::setLastErrorNumber(se.GetErrorNumber());
857                 ConfigVariable::setLastErrorLine(se.GetErrorLocation().first_line);
858                 ConfigVariable::setLastErrorFunction(wstring(L""));
859             }
860
861             CallExp* pCall = dynamic_cast<CallExp*>(*itExp);
862             if (pCall != NULL)
863             {
864                 //to print call expression only of it is a macro
865                 try
866                 {
867                     pCall->getName().accept(*this);
868                     if (getResult() != NULL && (getResult()->isMacro() || getResult()->isMacroFile()))
869                     {
870                         wostringstream os;
871                         PrintVisitor printMe(os);
872                         pCall->accept(printMe);
873                         //os << std::endl << std::endl;
874                         ConfigVariable::setLastErrorFunction(((InternalType*)getResult())->getAs<Callable>()->getName());
875                         scilabErrorW(se.GetErrorMessage().c_str());
876                         throw ScilabMessage(os.str(), 999, (*itExp)->getLocation());
877                     }
878                 }
879                 catch (ScilabError se2)
880                 {
881                     //just to catch exception, do nothing
882                 }
883             }
884
885             scilabErrorW(se.GetErrorMessage().c_str());
886             scilabErrorW(L"\n");
887             throw ScilabMessage((*itExp)->getLocation());
888         }
889
890         // If something other than NULL is given to setResult, then that would imply
891         // to make a cleanup in visit(ForExp) for example (e.getBody().accept(*this);)
892         setResult(NULL);
893     }
894 }
895
896 template <class T>
897 void RunVisitorT<T>::visitprivate(const NotExp &e)
898 {
899     /*
900       @ or ~ !
901     */
902     e.getExp().accept(*this);
903
904     InternalType * pValue = getResult();
905     InternalType * pReturn = NULL;
906     if (pValue->neg(pReturn))
907     {
908         if (pValue != pReturn)
909         {
910             pValue->killMe();
911         }
912
913         setResult(pReturn);
914     }
915     else
916     {
917         // neg returned false so the negation is not possible so we call the overload (%foo_5)
918         types::typed_list in;
919         types::typed_list out;
920
921         pValue->IncreaseRef();
922         in.push_back(pValue);
923
924         Callable::ReturnValue Ret = Overload::call(L"%" + pValue->getShortTypeStr() + L"_5", in, 1, out, this);
925
926         if (Ret != Callable::OK)
927         {
928             cleanInOut(in, out);
929             throw ScilabError();
930         }
931
932         setResult(out);
933         cleanIn(in, out);
934     }
935 }
936
937 template <class T>
938 void RunVisitorT<T>::visitprivate(const TransposeExp &e)
939 {
940     e.getExp().accept(*this);
941
942     if (getResultSize() != 1)
943     {
944         clearResult();
945         wchar_t szError[bsiz];
946         os_swprintf(szError, bsiz, _W("%ls: Can not transpose multiple elements.\n").c_str(), L"Transpose");
947         throw ScilabError(szError, 999, e.getLocation());
948     }
949
950     InternalType * pValue = getResult();
951     InternalType * pReturn = NULL;
952     const bool bConjug = e.getConjugate() == TransposeExp::_Conjugate_;
953
954     if ((bConjug && pValue->adjoint(pReturn)) || (!bConjug && pValue->transpose(pReturn)))
955     {
956         if (pValue != pReturn)
957         {
958             pValue->killMe();
959         }
960
961         setResult(pReturn);
962
963         return;
964     }
965     else
966     {
967         // transpose returned false so the negation is not possible so we call the overload (%foo_t or %foo_0)
968         types::typed_list in;
969         types::typed_list out;
970
971         pValue->IncreaseRef();
972         in.push_back(pValue);
973
974         Callable::ReturnValue Ret;
975         if (bConjug)
976         {
977             Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_t", in, 1, out, this);
978         }
979         else
980         {
981             Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_0", in, 1, out, this);
982         }
983
984         if (Ret != Callable::OK)
985         {
986             cleanInOut(in, out);
987             throw ScilabError();
988         }
989
990         setResult(out);
991         cleanIn(in, out);
992     }
993 }
994
995 template <class T>
996 void RunVisitorT<T>::visitprivate(const FunctionDec & e)
997 {
998     /*
999       function foo
1000       endfunction
1001     */
1002
1003     // funcprot(0) : do nothing
1004     // funcprot(1) && warning(on) : warning
1005     //get input parameters list
1006     std::list<symbol::Variable*> *pVarList = new std::list<symbol::Variable*>();
1007     const ArrayListVar* pListVar = e.getArgs().getAs<ArrayListVar>();
1008     exps_t vars = pListVar->getVars();
1009     for (exps_t::const_iterator it = vars.begin(), end = vars.end(); it != end; ++it)
1010     {
1011         pVarList->push_back((*it)->getAs<SimpleVar>()->getStack());
1012     }
1013
1014     //get output parameters list
1015     std::list<symbol::Variable*> *pRetList = new std::list<symbol::Variable*>();
1016     const ArrayListVar *pListRet = e.getReturns().getAs<ArrayListVar>();
1017     exps_t rets = pListRet->getVars();
1018     for (exps_t::const_iterator it = rets.begin(), end = rets.end(); it != end; ++it)
1019     {
1020         pRetList->push_back((*it)->getAs<SimpleVar>()->getStack());
1021     }
1022
1023     types::Macro *pMacro = new types::Macro(e.getSymbol().getName(), *pVarList, *pRetList,
1024                                             *const_cast<SeqExp&>(static_cast<const SeqExp&>(e.getBody())).clone(), L"script");
1025     pMacro->setFirstLine(e.getLocation().first_line);
1026
1027     bool bEquals = false;
1028     int iFuncProt = ConfigVariable::getFuncprot();
1029     if (iFuncProt != 0)
1030     {
1031         types::InternalType* pITFunc = symbol::Context::getInstance()->get(((FunctionDec&)e).getStack());
1032         if (pITFunc && pITFunc->isCallable())
1033         {
1034             if (pITFunc->isMacroFile())
1035             {
1036                 types::MacroFile* pMF = pITFunc->getAs<types::MacroFile>();
1037                 bEquals = *pMF->getMacro() == *pMacro;
1038             }
1039             else if (pITFunc->isMacro())
1040             {
1041                 types::Macro* pM = pITFunc->getAs<types::Macro>();
1042                 bEquals = *pM == *pMacro;
1043             }
1044         }
1045         else
1046         {
1047             bEquals = true; //avoid msg but keep assignation
1048         }
1049     }
1050
1051     if (bEquals == false && iFuncProt == 1 && ConfigVariable::getWarningMode())
1052     {
1053         wchar_t pwstFuncName[1024];
1054         os_swprintf(pwstFuncName, 1024, L"%-24ls", e.getSymbol().getName().c_str());
1055         char* pstFuncName = wide_string_to_UTF8(pwstFuncName);
1056
1057         sciprint(_("Warning : redefining function: %s. Use funcprot(0) to avoid this message"), pstFuncName);
1058         sciprint("\n");
1059         FREE(pstFuncName);
1060     }
1061     else if (bEquals == false && iFuncProt == 2)
1062     {
1063         char pstError[1024];
1064         char* pstFuncName = wide_string_to_UTF8(e.getSymbol().getName().c_str());
1065         sprintf(pstError, _("It is not possible to redefine the %s primitive this way (see clearfun).\n"), pstFuncName);
1066         wchar_t* pwstError = to_wide_string(pstError);
1067         std::wstring wstError(pwstError);
1068         FREE(pstFuncName);
1069         FREE(pwstError);
1070         throw ScilabError(wstError, 999, e.getLocation());
1071     }
1072
1073     symbol::Context::getInstance()->addMacro(pMacro);
1074
1075 }
1076
1077 template <class T>
1078 void RunVisitorT<T>::visitprivate(const ListExp &e)
1079 {
1080     e.getStart().accept(*this);
1081     GenericType* pITStart = static_cast<GenericType*>(getResult());
1082     if ((pITStart->getSize() != 1 || (pITStart->isDouble() && pITStart->getAs<Double>()->isComplex())) &&
1083             pITStart->isList() == false) // list case => call overload
1084     {
1085         pITStart->killMe();
1086         wchar_t szError[bsiz];
1087         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 1);
1088         throw ScilabError(szError, 999, e.getLocation());
1089     }
1090     InternalType * piStart = pITStart;
1091
1092     e.getStep().accept(*this);
1093     GenericType* pITStep = static_cast<GenericType*>(getResult());
1094     if ((pITStep->getSize() != 1 || (pITStep->isDouble() && pITStep->getAs<Double>()->isComplex())) &&
1095             pITStep->isList() == false) // list case => call overload
1096     {
1097         pITStart->killMe();
1098         pITStep->killMe();
1099         wchar_t szError[bsiz];
1100         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 2);
1101         throw ScilabError(szError, 999, e.getLocation());
1102     }
1103     InternalType* piStep = pITStep;
1104
1105     e.getEnd().accept(*this);
1106     GenericType* pITEnd = static_cast<GenericType*>(getResult());
1107     if ((pITEnd->getSize() != 1 || (pITEnd->isDouble() && pITEnd->getAs<Double>()->isComplex())) &&
1108             pITEnd->isList() == false) // list case => call overload
1109     {
1110         pITStart->killMe();
1111         pITStep->killMe();
1112         pITEnd->killMe();
1113         wchar_t szError[bsiz];
1114         os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 3);
1115         throw ScilabError(szError, 999, e.getLocation());
1116     }
1117     InternalType* piEnd = pITEnd;
1118
1119     //check compatibility
1120     // double : double : double or poly : poly : poly and mix like double : double : poly
1121     if ((piStart->isPoly() || piStart->isDouble()) &&
1122             (piStep->isPoly()  || piStep->isDouble())  &&
1123             (piEnd->isPoly()   || piEnd->isDouble()))
1124     {
1125         // No need to kill piStart, ... because Implicit list ctor will incref them
1126         setResult(new ImplicitList(piStart, piStep, piEnd));
1127         return;
1128     }
1129
1130     // int : double or int : int
1131     if ( piStart->isInt()   &&
1132             (piStep->isDouble() || piStep->isInt()) &&
1133             piEnd->isInt())
1134     {
1135         // check for same int type int8, int 16 ...
1136         if (piStart->getType() == piEnd->getType()  &&
1137                 (piStart->getType() == piStep->getType() ||
1138                  piStep->isDouble()))
1139         {
1140             // No need to kill piStart, ... because Implicit list ctor will incref them
1141             setResult(new ImplicitList(piStart, piStep, piEnd));
1142             return;
1143         }
1144     }
1145
1146     // Call Overload
1147     Callable::ReturnValue Ret;
1148     types::typed_list in;
1149     types::typed_list out;
1150
1151     piStart->IncreaseRef();
1152     piStep->IncreaseRef();
1153     piEnd->IncreaseRef();
1154
1155     in.push_back(piStart);
1156     if (e.hasExplicitStep())
1157     {
1158         // 1:2:4
1159         //call overload %typeStart_b_typeEnd
1160         in.push_back(piStep);
1161         in.push_back(piEnd);
1162         Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piStep->getShortTypeStr(), in, 1, out, this, true);
1163     }
1164     else
1165     {
1166         // 1:2
1167         //call overload %typeStart_b_typeStep
1168         in.push_back(piEnd);
1169         Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piEnd->getShortTypeStr(), in, 1, out, this, true);
1170     }
1171
1172     if (Ret != Callable::OK)
1173     {
1174         cleanInOut(in, out);
1175         throw ScilabError();
1176     }
1177
1178     setResult(out);
1179     cleanIn(in, out);
1180 }
1181
1182 template <class T>
1183 void RunVisitorT<T>::visitprivate(const OptimizedExp &e)
1184 {
1185 }
1186
1187 template <class T>
1188 void RunVisitorT<T>::visitprivate(const DAXPYExp &e)
1189 {
1190     InternalType* pIT = NULL;
1191     Double* ad = NULL;
1192     int ar = 0;
1193     int ac = 0;
1194
1195     Double* xd = NULL;
1196     int xr = 0;
1197     int xc = 0;
1198
1199     Double* yd = NULL;
1200     int yr = 0;
1201     int yc = 0;
1202
1203     //check types and dimensions
1204
1205     //y must be double
1206     const Exp &ye = e.getY();
1207     ye.accept(*this);
1208     pIT = getResult();
1209     if (pIT->isDouble())
1210     {
1211         yd = pIT->getAs<Double>();
1212         if (yd->getDims() == 2 && yd->isComplex() == false)
1213         {
1214             yr = yd->getRows();
1215             yc = yd->getCols();
1216         }
1217         else
1218         {
1219             yd->killMe();
1220             e.getOriginal()->accept(*this);
1221             return;
1222         }
1223     }
1224     else
1225     {
1226         pIT->killMe();
1227         e.getOriginal()->accept(*this);
1228         return;
1229     }
1230
1231     //x
1232     const Exp &xe = e.getX();
1233     xe.accept(*this);
1234     pIT = getResult();
1235
1236     if (pIT->isDouble())
1237     {
1238         xd = pIT->getAs<Double>();
1239         if (xd->isScalar() && xd->isComplex() == false)
1240         {
1241             // x become a
1242             ad = xd;
1243             ar = 1;
1244             ac = 1;
1245         }
1246         else if (xd->getDims() == 2 && xd->isComplex() == false)
1247         {
1248             xr = xd->getRows();
1249             xc = xd->getCols();
1250         }
1251         else
1252         {
1253             yd->killMe();
1254             xd->killMe();
1255             e.getOriginal()->accept(*this);
1256             return;
1257         }
1258     }
1259     else
1260     {
1261         pIT->killMe();
1262         yd->killMe();
1263         e.getOriginal()->accept(*this);
1264         return;
1265     }
1266
1267     const Exp &ae = e.getA();
1268     ae.accept(*this);
1269     pIT = getResult();
1270
1271     if (pIT->isDouble())
1272     {
1273         if (ad)
1274         {
1275             xd = pIT->getAs<Double>();
1276             //X is scalar it become A
1277             //now use A as X
1278             if (xd->getDims() == 2 && xd->isComplex() == false)
1279             {
1280                 xr = xd->getRows();
1281                 xc = xd->getCols();
1282             }
1283             else
1284             {
1285                 yd->killMe();
1286                 xd->killMe();
1287                 ad->killMe();
1288                 e.getOriginal()->accept(*this);
1289                 return;
1290             }
1291         }
1292         else
1293         {
1294             //a is a and it must be scalar
1295             ad = pIT->getAs<Double>();
1296             if (ad->isScalar() && ad->isComplex() == false)
1297             {
1298                 ar = 1;
1299                 ac = 1;
1300             }
1301             else
1302             {
1303                 yd->killMe();
1304                 xd->killMe();
1305                 ad->killMe();
1306                 e.getOriginal()->accept(*this);
1307                 return;
1308             }
1309         }
1310     }
1311     else
1312     {
1313         pIT->killMe();
1314         yd->killMe();
1315         xd->killMe();
1316         e.getOriginal()->accept(*this);
1317         return;
1318     }
1319
1320     if (ad && xd && yd)
1321     {
1322         if ( ac == 1 &&
1323                 ar == 1 &&
1324                 xr == yr &&
1325                 xc == yc)
1326         {
1327             //go !
1328             int one = 1;
1329             int size = xc * xr;
1330             Double* od = (Double*)yd->clone();
1331             C2F(daxpy)(&size, ad->get(), xd->get(), &one, od->get(), &one);
1332             setResult(od);
1333             yd->killMe();
1334             xd->killMe();
1335             ad->killMe();
1336             return;
1337         }
1338     }
1339
1340     if (yd)
1341     {
1342         yd->killMe();
1343     }
1344
1345     if (xd)
1346     {
1347         xd->killMe();
1348     }
1349
1350     if (ad)
1351     {
1352         ad->killMe();
1353     }
1354
1355     e.getOriginal()->accept(*this);
1356     return;
1357 }
1358
1359 #include "run_CallExp.cpp"
1360 #include "run_MatrixExp.cpp"
1361 #include "run_OpExp.cpp"
1362 #include "run_AssignExp.cpp"
1363 }
1364
1365 template EXTERN_AST class ast::RunVisitorT<ast::ExecVisitor>;
1366 template EXTERN_AST class ast::RunVisitorT<ast::StepVisitor>;
1367 template EXTERN_AST class ast::RunVisitorT<ast::TimedVisitor>;