22f73b45e56a3edb6a4310ff9f3875db67d2a804
[scilab.git] / scilab / modules / ast / src / cpp / ast / treevisitor.cpp
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 "treevisitor.hxx"
17 #include "printvisitor.hxx"
18 #include "execvisitor.hxx"
19 #include "token.hxx"
20
21 extern "C"
22 {
23 #include "os_string.h"
24 #include "os_wcstok.h"
25 }
26
27 namespace ast
28 {
29 void TreeVisitor::visit(const SeqExp  &e)
30 {
31     types::List* lst = new types::List();
32     lst->append(getEOL());
33
34     int last_line = -1;
35     for (auto it : e.getExps())
36     {
37         int first = it->getLocation().first_line;
38         while (last_line != -1 && last_line < first)
39         {
40             lst->append(getEOL());
41             ++last_line;
42         }
43
44         last_line = it->getLocation().last_line;
45
46         it->accept(*this);
47         if (it->isAssignExp() ||
48                 it->isCommentExp() ||
49                 it->isForExp() ||
50                 it->isWhileExp() ||
51                 it->isTryCatchExp() ||
52                 it->isSelectExp() ||
53                 it->isFunctionDec() ||
54                 it->isIfExp())
55         {
56             types::InternalType* tmp = getList();
57             lst->append(tmp);
58             tmp->killMe();
59         }
60         else
61         {
62             //add ans = before expression
63             types::TList* tl = new types::TList();
64             types::String* s = new types::String(1, 4);
65             s->set(0, L"equal");
66             s->set(1, L"expression");
67             s->set(2, L"lhs");
68             s->set(3, L"endsymbol");
69             //header
70             tl->append(s);
71             s->killMe();
72             //expression
73             types::InternalType* tmp = getList();
74             tl->append(tmp);
75             tmp->killMe();
76             //lhs
77             types::List* lhs = new types::List();
78             tmp = createVar(L"ans");
79             lhs->append(tmp);
80             tmp->killMe();
81             tl->append(lhs);
82             lhs->killMe();
83             //endsymbol
84             tl->append(getVerbose(*it));
85             lst->append(tl);
86             tl->killMe();
87         }
88     }
89
90     lst->append(getEOL());
91     l = lst;
92 }
93
94 void TreeVisitor::visit(const CommentExp  &e)
95 {
96     types::TList* tl = new types::TList();
97     types::String* s = new types::String(1, 2);
98     s->set(0, L"comment");
99     s->set(1, L"text");
100     tl->append(s);
101     tl->append(new types::String(e.getComment().c_str()));
102     l = tl;
103 }
104
105 void TreeVisitor::visit(const SimpleVar &e)
106 {
107     l = createVar(e.getSymbol().getName());
108 }
109
110 void TreeVisitor::visit(const DoubleExp &e)
111 {
112     ExecVisitor exec;
113     e.accept(exec);
114     l = createConst(exec.getResult());
115 }
116
117 void TreeVisitor::visit(const StringExp &e)
118 {
119     ExecVisitor exec;
120     e.accept(exec);
121     l = createConst(exec.getResult());
122 }
123
124 void TreeVisitor::visit(const BoolExp &e)
125 {
126     ExecVisitor exec;
127     e.accept(exec);
128     l = createConst(exec.getResult());
129 }
130
131 void TreeVisitor::visit(const DollarVar &/*e*/)
132 {
133     l = createVar(L"$");
134 }
135
136 void TreeVisitor::visit(const ColonVar &/*e*/)
137 {
138     l = createVar(L":");
139 }
140
141 void TreeVisitor::visit(const MatrixExp &e)
142 {
143     exps_t lines = e.getLines();
144
145     if (lines.size() == 0)
146     {
147         l = createConst(types::Double::Empty());
148         return;
149     }
150
151     if (lines.size() == 1)
152     {
153         lines.front()->accept(*this);
154         return;
155     }
156
157     types::List* sub = createOperation();
158     types::List* ope = new types::List();
159
160     int idx = 0;
161     for (auto it : lines)
162     {
163         it->accept(*this);
164
165         if (idx >= 2)
166         {
167             sub->append(ope);
168             ope->killMe();
169             sub->append(new types::String(L"cc"));
170
171             //create a new operation
172             //put previous stage in lhs and
173             //result in rhs
174             types::List* subcolcatOperation = createOperation();
175             types::List* subcolcatOperands = new types::List();
176             subcolcatOperands->append(sub);
177             sub->killMe();
178             //add EOL
179             //subcolcatOperands->append(getEOL());
180             types::InternalType* tmp = getList();
181             subcolcatOperands->append(tmp);
182             tmp->killMe();
183
184             ope = subcolcatOperands;
185             sub = subcolcatOperation;
186         }
187         else
188         {
189             types::InternalType* tmp = getList();
190             ope->append(tmp);
191             tmp->killMe();
192         }
193
194         ++idx;
195     }
196     sub->append(ope);
197     ope->killMe();
198     sub->append(new types::String(L"cc"));
199     l = sub;
200 }
201
202 void TreeVisitor::visit(const MatrixLineExp &e)
203 {
204     exps_t columns = e.getColumns();
205     if (columns.size() == 1)
206     {
207         columns.front()->accept(*this);
208         return;
209     }
210
211     types::List* sub = createOperation();
212     types::List* ope = new types::List();
213
214     int idx = 0;
215     for (auto it : columns)
216     {
217         it->accept(*this);
218
219         if (idx >= 2)
220         {
221             sub->append(ope);
222             ope->killMe();
223             sub->append(new types::String(L"rc"));
224             //create a new operation
225             //put previous stage in lhs and
226             //result in rhs
227             types::List* lst = createOperation();
228             types::List* l2 = new types::List();
229             l2->append(sub);
230             sub->killMe();
231             types::InternalType* tmp = getList();
232             l2->append(tmp);
233             tmp->killMe();
234
235             //lst->append(tmp);
236             ope = l2;
237             sub = lst;
238         }
239         else
240         {
241             types::InternalType* tmp = getList();
242             ope->append(tmp);
243             tmp->killMe();
244         }
245
246         ++idx;
247     }
248
249     sub->append(ope);
250     ope->killMe();
251     sub->append(new types::String(L"rc"));
252     l = sub;
253 }
254
255 void TreeVisitor::visit(const OpExp &e)
256 {
257     types::List* ope = createOperation();
258     types::List* sub = new types::List();
259
260     if (e.getOper() != OpExp::unaryMinus)
261     {
262         e.getLeft().accept(*this);
263         types::InternalType* tmp = getList();
264         sub->append(tmp);
265         tmp->killMe();
266     }
267     e.getRight().accept(*this);
268     types::InternalType* tmp = getList();
269     sub->append(tmp);
270     tmp->killMe();
271     ope->append(sub);
272     sub->killMe();
273
274     switch (e.getOper())
275     {
276         // Arithmetics.
277         case OpExp::plus:
278             tmp = new types::String(SCI_PLUS);
279             break;
280         case OpExp::unaryMinus:
281         case OpExp::minus:
282             tmp = new types::String(SCI_MINUS);
283             break;
284         case OpExp::times:
285             tmp = new types::String(SCI_TIMES);
286             break;
287         case OpExp::rdivide:
288             tmp = new types::String(SCI_RDIVIDE);
289             break;
290         case OpExp::ldivide:
291             tmp = new types::String(SCI_LDIVIDE);
292             break;
293         case OpExp::power:
294             tmp = new types::String(SCI_POWER);
295             break;
296         // Element wise.
297         case OpExp::dottimes:
298             tmp = new types::String(SCI_DOTTIMES);
299             break;
300         case OpExp::dotrdivide:
301             tmp = new types::String(SCI_DOTRDIVIDE);
302             break;
303         case OpExp::dotldivide:
304             tmp = new types::String(SCI_DOTLDIVIDE);
305             break;
306         case OpExp::dotpower:
307             tmp = new types::String(SCI_DOTPOWER);
308             break;
309         // Kroneckers
310         case OpExp::krontimes:
311             tmp = new types::String(SCI_KRONTIMES);
312             break;
313         case OpExp::kronrdivide:
314             tmp = new types::String(SCI_KRONRDIVIDE);
315             break;
316         case OpExp::kronldivide:
317             tmp = new types::String(SCI_KRONLDIVIDE);
318             break;
319         // Control
320         case OpExp::controltimes:
321             tmp = new types::String(SCI_CONTROLTIMES);
322             break;
323         case OpExp::controlrdivide:
324             tmp = new types::String(SCI_CONTROLRDIVIDE);
325             break;
326         case OpExp::controlldivide:
327             tmp = new types::String(SCI_CONTROLLDIVIDE);
328             break;
329         // Comparisons
330         case OpExp::eq:
331             tmp = new types::String(SCI_EQ);
332             break;
333         case OpExp::ne:
334             tmp = new types::String(SCI_NE);
335             break;
336         case OpExp::lt:
337             tmp = new types::String(SCI_LT);
338             break;
339         case OpExp::le:
340             tmp = new types::String(SCI_LE);
341             break;
342         case OpExp::gt:
343             tmp = new types::String(SCI_GT);
344             break;
345         case OpExp::ge:
346             tmp = new types::String(SCI_GE);
347             break;
348         default:
349             tmp = new types::String(L"BAD OPERATOR");
350             break;
351     }
352
353     ope->append(tmp);
354     l = ope;
355 }
356
357 void TreeVisitor::visit(const LogicalOpExp &e)
358 {
359     types::List* ope = createOperation();
360     types::List* sub = new types::List();
361     types::List* tmplst = nullptr;
362
363     if (e.getOper() != OpExp::unaryMinus)
364     {
365         e.getLeft().accept(*this);
366         tmplst = getList();
367         sub->append(tmplst);
368         tmplst->killMe();
369     }
370     e.getRight().accept(*this);
371     tmplst = getList();
372     sub->append(tmplst);
373     tmplst->killMe();
374     ope->append(sub);
375     sub->killMe();
376
377     types::InternalType* tmp = nullptr;
378     switch (e.getOper())
379     {
380         case LogicalOpExp::logicalAnd:
381             tmp = new types::String(SCI_AND);
382             break;
383         case LogicalOpExp::logicalOr:
384             tmp = new types::String(SCI_OR);
385             break;
386         case LogicalOpExp::logicalShortCutAnd:
387             tmp = new types::String(SCI_ANDAND);
388             break;
389         case LogicalOpExp::logicalShortCutOr:
390             tmp = new types::String(SCI_OROR);
391             break;
392         default:
393             tmp = new types::String(L"BAD LOGICAL OPERATOR");
394             break;
395     }
396
397     ope->append(tmp);
398     l = ope;
399 }
400
401 void TreeVisitor::visit(const IfExp  &e)
402 {
403     types::TList* tl = new types::TList();
404     bool hasElse = e.hasElse() && e.getElse().isCommentExp() == false;
405     //header
406     types::String* s = new types::String(1, 5);
407     s->set(0, L"ifthenelse");
408     s->set(1, L"expression");
409     s->set(2, L"then");
410     s->set(3, L"elseifs"); //always empty
411     s->set(4, L"else");
412     tl->append(s);
413
414     //expression -> condition
415     e.getTest().accept(*this);
416     types::InternalType* tmp = getList();
417     tl->append(tmp);
418     tmp->killMe();
419
420     //then
421     e.getThen().accept(*this);
422     tmp = getList();
423     tl->append(tmp);
424     tmp->killMe();
425
426     //elseif
427     tmp = new types::List();
428     tl->append(tmp);
429     tmp->killMe();
430
431     //else
432     if (hasElse)
433     {
434         e.getElse().accept(*this);
435         tmp = getList();
436         tl->append(tmp);
437         tmp->killMe();
438     }
439     else
440     {
441         tmp = new types::List();
442         tl->append(tmp);
443         tmp->killMe();
444     }
445     l = tl;
446 }
447
448 void TreeVisitor::visit(const ListExp  &e)
449 {
450     types::List* ope = createOperation();
451     types::List* sub = new types::List();
452
453     e.getStart().accept(*this);
454     types::InternalType* tmp = getList();
455     sub->append(tmp);
456     tmp->killMe();
457
458     if (e.hasExplicitStep())
459     {
460         e.getStep().accept(*this);
461         tmp = getList();
462         sub->append(tmp);
463         tmp->killMe();
464     }
465
466     e.getEnd().accept(*this);
467     tmp = getList();
468     sub->append(tmp);
469     tmp->killMe();
470
471     ope->append(sub);
472     sub->killMe();
473     tmp = new types::String(L":");
474     ope->append(tmp);
475     tmp->killMe();
476     l = ope;
477 }
478
479 void TreeVisitor::visit(const AssignExp &e)
480 {
481     types::List* assign = createAssign();
482
483     //expression : what to assign
484     e.getRightExp().accept(*this);
485     types::List* tmp = getList();
486     assign->append(tmp);
487
488     double* dlhs = NULL;
489     if (e.getRightExp().isCallExp())
490     {
491         types::TList* tl = getList()->getAs<types::TList>();
492         types::Double* lhsnb = tl->get(tl->getSize() - 1)->getAs<types::Double>();
493         dlhs = lhsnb->get();
494     }
495
496     tmp->killMe();
497
498     //lhs : who to assign
499     Exp& left = e.getLeftExp();
500     if (left.isSimpleVar())
501     {
502         left.accept(*this);
503         types::List* lhs = new types::List();
504         tmp = getList();
505         lhs->append(tmp);
506         tmp->killMe();
507         assign->append(lhs);
508         lhs->killMe();
509         if (dlhs)
510         {
511             dlhs[0] = 1;//lhs = 1
512         }
513     }
514
515     if (left.isCellCallExp())
516     {
517         //not yet manage
518     }
519
520     if (left.isCallExp())
521     {
522         CallExp* call = left.getAs<CallExp>();
523         types::List* ins = createOperation();
524         types::List* lhs = new types::List();
525         //varname
526         call->getName().accept(*this);
527         tmp = getList();
528         lhs->append(tmp);
529         tmp->killMe();
530
531         //indexes
532         ast::exps_t args = call->getArgs();
533         for (auto arg : args)
534         {
535             arg->accept(*this);
536             tmp = getList();
537             lhs->append(tmp);
538             tmp->killMe();
539         }
540
541         if (dlhs)
542         {
543             dlhs[0] = 1;//lhs = 1
544         }
545         ins->append(lhs);
546         lhs->killMe();
547
548         //operator
549         ins->append(new types::String(L"ins"));
550         types::List* lst = new types::List();
551         lst->append(ins);
552         ins->killMe();
553         assign->append(lst);
554         lst->killMe();
555     }
556
557     if (left.isAssignListExp())
558     {
559         AssignListExp* lst = left.getAs<AssignListExp>();
560         types::List* lhs = new types::List();
561         for (auto exp : lst->getExps())
562         {
563             exp->accept(*this);
564             tmp = getList();
565             lhs->append(tmp);
566             tmp->killMe();
567         }
568         if (dlhs)
569         {
570             dlhs[0] = static_cast<double>(lst->getExps().size());
571         }
572
573         assign->append(lhs);
574         lhs->killMe();
575     }
576
577     if (left.isFieldExp())
578     {
579         FieldExp* field = left.getAs<FieldExp>();
580         types::List* ins = createOperation();
581         types::List* lhs = new types::List();
582
583         field->getHead()->accept(*this);
584         tmp = getList();
585         lhs->append(tmp);
586         tmp->killMe();
587
588         if (field->getTail()->isSimpleVar())
589         {
590             SimpleVar* pVar = field->getTail()->getAs<SimpleVar>();
591             tmp = createConst(new types::String(pVar->getSymbol().getName().c_str()));
592             lhs->append(tmp);
593             tmp->killMe();
594         }
595         else
596         {
597             //never occur ?
598             field->accept(*this);
599             tmp = getList();
600             lhs->append(tmp);
601             tmp->killMe();
602         }
603
604         ins->append(lhs);
605         lhs->killMe();
606         //operator
607         ins->append(new types::String(L"ins"));
608         tmp = new types::List();
609         tmp->append(ins);
610         ins->killMe();
611         assign->append(tmp);
612         tmp->killMe();
613     }
614
615     //verbose ?
616     assign->append(getVerbose(e));
617     l = assign;
618 }
619
620 void TreeVisitor::visit(const CallExp &e)
621 {
622     types::TList* call = new types::TList();
623
624     //header
625     types::String* varstr = new types::String(1, 4);
626     varstr->set(0, L"funcall");
627     varstr->set(1, L"rhs");
628     varstr->set(2, L"name");
629     varstr->set(3, L"lhsnb");
630     call->append(varstr);
631
632     //rhs
633     types::List* rhs = new types::List();
634     ast::exps_t args = e.getArgs();
635     for (auto arg : args)
636     {
637         arg->accept(*this);
638         types::List* tmp = getList();
639         rhs->append(tmp);
640         tmp->killMe();
641     }
642
643     call->append(rhs);
644     rhs->killMe();
645
646     //name
647     call->append(new types::String(e.getName().getAs<SimpleVar>()->getSymbol().getName().c_str()));
648
649     //lhsnb
650     //use default value 1
651     //parent exp like assign can adapt it.
652     call->append(new types::Double(1));
653
654     l = call;
655 }
656
657 void TreeVisitor::visit(const ForExp &e)
658 {
659     types::TList* f = new types::TList();
660
661     //header
662     types::String* varstr = new types::String(1, 3);
663     varstr->set(0, L"for");
664     varstr->set(1, L"expression");
665     varstr->set(2, L"statements");
666     f->append(varstr);
667
668     //expression
669     //create a AssignExp to call visitor it
670     VarDec* vardec = e.getVardec().getAs<VarDec>();
671     SimpleVar* var = new SimpleVar(vardec->getLocation(), vardec->getSymbol());
672     Exp* init = vardec->getInit().clone();
673     AssignExp* assign = new AssignExp(vardec->getLocation(), *var, *init);
674     assign->setVerbose(true);
675
676     assign->accept(*this);
677     types::List* tmp = getList();
678     f->append(tmp);
679     tmp->killMe();
680     delete assign;
681
682     //statements
683     e.getBody().accept(*this);
684     tmp = getList();
685     f->append(tmp);
686     tmp->killMe();
687     l = f;
688 }
689
690 void TreeVisitor::visit(const FieldExp &e)
691 {
692     types::List* ext = createOperation();
693     types::List* ope = new types::List();
694
695     //function or varname
696     e.getHead()->accept(*this);
697     types::List* tmp = getList();
698     ope->append(tmp);
699     tmp->killMe();
700
701     //arguments
702     if (e.getTail()->isSimpleVar())
703     {
704         const SimpleVar* pVar = e.getTail()->getAs<SimpleVar>();
705         tmp = createConst(new types::String(pVar->getSymbol().getName().c_str()));
706         ope->append(tmp);
707         tmp->killMe();
708     }
709     else
710     {
711         tmp = getList();
712         ope->append(tmp);
713         tmp->killMe();
714     }
715
716     //operator
717     ext->append(ope);
718     ope->killMe();
719     ext->append(new types::String(L"ext"));
720     l = ext;
721 }
722
723 void TreeVisitor::visit(const TryCatchExp &e)
724 {
725     types::TList* tc = new types::TList();
726
727     //header
728     types::String* varstr = new types::String(1, 3);
729     varstr->set(0, L"trycatch");
730     varstr->set(1, L"trystat");
731     varstr->set(2, L"catchstat");
732     tc->append(varstr);
733
734     //trystat
735     e.getTry().accept(*this);
736     types::List* tmp = getList();
737     tc->append(tmp);
738     tmp->killMe();
739
740     //catchstat
741     e.getCatch().accept(*this);
742     tmp = getList();
743     tc->append(tmp);
744     tmp->killMe();
745
746     l = tc;
747 }
748
749 void TreeVisitor::visit(const WhileExp &e)
750 {
751     types::TList* w = new types::TList();
752
753     //header
754     types::String* varstr = new types::String(1, 3);
755     varstr->set(0, L"while");
756     varstr->set(1, L"expression");
757     varstr->set(2, L"statements");
758     w->append(varstr);
759
760     //expression
761     e.getTest().accept(*this);
762     types::List* tmp = getList();
763     w->append(tmp);
764     tmp->killMe();
765
766     //statements
767     e.getBody().accept(*this);
768     tmp = getList();
769     w->append(tmp);
770     tmp->killMe();
771     l = w;
772 }
773
774 void TreeVisitor::visit(const ContinueExp &/*e*/)
775 {
776     l = createVar(L"continue");
777 }
778
779 void TreeVisitor::visit(const BreakExp &/*e*/)
780 {
781     l = createVar(L"break");
782 }
783
784 void TreeVisitor::visit(const ReturnExp &e)
785 {
786     if (e.isGlobal())
787     {
788         l = createVar(L"resume");
789     }
790     else
791     {
792         types::List* ext = createOperation();
793         types::List* ope = new types::List();
794
795         //function or varname
796         ope->append(new types::String(L"return"));
797
798         //arguments
799         for (auto arg : e.getExp().getAs<ArrayListExp>()->getExps())
800         {
801             arg->accept(*this);
802             types::List* tmp = getList();
803             ope->append(tmp);
804             tmp->killMe();
805         }
806
807         //operator
808         ext->append(ope);
809         ope->killMe();
810         ext->append(new types::String(L"ext"));
811         l = ext;
812     }
813 }
814
815 void TreeVisitor::visit(const SelectExp &e)
816 {
817     types::TList* select = new types::TList();
818
819     //header
820     types::String* varstr = new types::String(1, 4);
821     varstr->set(0, L"selectcase");
822     varstr->set(1, L"expression");
823     varstr->set(2, L"cases");
824     varstr->set(3, L"else");
825     select->append(varstr);
826
827     //expression
828     types::List* cond = new types::List();
829     e.getSelect()->accept(*this);
830     types::List* tmp = getList();
831     cond->append(tmp);
832     tmp->killMe();
833     cond->append(getEOL());
834     select->append(cond);
835     cond->killMe();
836
837     //cases
838     types::List* lcases = new types::List();
839     ast::exps_t cases = e.getCases();
840     for (auto c : cases)
841     {
842         c->accept(*this);
843         tmp = getList();
844         lcases->append(tmp);
845         tmp->killMe();
846     }
847
848     select->append(lcases);
849     lcases->killMe();
850
851     //default
852     if (e.hasDefault())
853     {
854         e.getDefaultCase()->accept(*this);
855         tmp = getList();
856         select->append(tmp);
857         tmp->killMe();
858     }
859     else
860     {
861         select->append(new types::List());
862
863     }
864     l = select;
865 }
866
867 void TreeVisitor::visit(const CaseExp &e)
868 {
869     types::TList* c = new types::TList();
870
871     //header
872     types::String* varstr = new types::String(1, 3);
873     varstr->set(0, L"case");
874     varstr->set(1, L"expression");
875     varstr->set(2, L"then");
876     c->append(varstr);
877
878     //expression
879     e.getTest()->accept(*this);
880     types::List* tmp = getList();
881     c->append(tmp);
882     tmp->killMe();
883
884     //then
885     e.getBody()->accept(*this);
886     tmp = getList();
887     c->append(tmp);
888     tmp->killMe();
889
890     l = c;
891 }
892
893 void TreeVisitor::visit(const ArrayListExp  &e)
894 {
895     types::List* ext = createOperation();
896     types::List* ope = new types::List();
897
898     //function or varname
899     ope->append(new types::String(L""));
900
901     //arguments
902     for (auto arg : e.getExps())
903     {
904         arg->accept(*this);
905         types::List* tmp = getList();
906         ope->append(tmp);
907         tmp->killMe();
908     }
909
910     //operator
911     ext->append(ope);
912     ope->killMe();
913     ext->append(new types::String(L"ext"));
914     l = ext;
915 }
916
917 void TreeVisitor::visit(const NotExp  &e)
918 {
919     types::List* ext = createOperation();
920     types::List* ope = new types::List();
921
922     //function or varname
923     e.getExp().accept(*this);
924     types::List* tmp = getList();
925     ope->append(tmp);
926     tmp->killMe();
927
928     //operator
929     ext->append(ope);
930     ope->killMe();
931     ext->append(new types::String(L"~"));
932     l = ext;
933 }
934
935 void TreeVisitor::visit(const TransposeExp  &e)
936 {
937     types::List* ext = createOperation();
938     types::List* ope = new types::List();
939
940     //function or varname
941     e.getExp().accept(*this);
942     types::List* tmp = getList();
943     ope->append(tmp);
944     tmp->killMe();
945
946     //operator
947     ext->append(ope);
948     ope->killMe();
949     ext->append(new types::String(L"'"));
950     l = ext;
951 }
952
953 void TreeVisitor::visit(const FunctionDec  &e)
954 {
955     wchar_t* pwstState;
956     std::wostringstream wostr;
957     PrintVisitor pv(wostr, false, false);
958
959     types::TList* function = new types::TList();
960
961     //header
962     types::String* varstr = new types::String(1, 3);
963     varstr->set(0, L"inline");
964     varstr->set(1, L"prototype");
965     varstr->set(2, L"definition");
966     function->append(varstr);
967     size_t returnSize = e.getReturns().getOriginal()->getAs<ArrayListVar>()->getVars().size();
968     // First ask if there are some return values.
969     if (returnSize > 1)
970     {
971         wostr << SCI_OPEN_RETURNS;
972     }
973
974     e.getReturns().getOriginal()->accept(pv);
975
976     if (returnSize > 1)
977     {
978         wostr << SCI_CLOSE_RETURNS;
979     }
980
981     if (returnSize > 0)
982     {
983         wostr << L" " << SCI_ASSIGN << L" ";
984     }
985
986     // Then get the function name
987     wostr << e.getSymbol().getName();
988
989     // Then get function args
990     wostr << SCI_OPEN_ARGS;
991     e.getArgs().getOriginal()->accept(pv);
992     wostr << SCI_CLOSE_ARGS << std::endl;
993     wchar_t* pwstFun = os_wcsdup(wostr.str().data());
994     function->append(new types::String(os_wcstok(pwstFun, L"\n", &pwstState)));
995     FREE(pwstFun);
996
997     // Now print function body
998     std::wostringstream wostrBody;
999     PrintVisitor pvBody(wostrBody, false, true);
1000     std::vector<wchar_t*> allTokens;
1001     e.getBody().getOriginal()->accept(pvBody);
1002     wchar_t* pwstBody = os_wcsdup(wostrBody.str().data());
1003     wchar_t* pwstToken = os_wcstok(pwstBody, L"\n", &pwstState);
1004     while (pwstToken != NULL)
1005     {
1006         allTokens.push_back(pwstToken);
1007         pwstToken = os_wcstok(NULL, L"\n", &pwstState);
1008     }
1009
1010     if (allTokens.size() > 0)
1011     {
1012         types::String* stringMatrix = new types::String(static_cast<int>(allTokens.size()), 1);
1013         stringMatrix->set(allTokens.data());
1014         function->append(stringMatrix);
1015     }
1016     else
1017     {
1018         function->append(types::Double::Empty());
1019     }
1020     FREE(pwstBody);
1021
1022     l = function;
1023 }
1024
1025 types::InternalType* TreeVisitor::getEOL()
1026 {
1027     if (eol)
1028     {
1029         return eol;
1030     }
1031
1032     eol = new types::List();
1033     eol->append(new types::String(L"EOL"));
1034     return eol;
1035 }
1036
1037 types::List* TreeVisitor::createVar(const std::wstring& str)
1038 {
1039     types::TList* var = new types::TList();
1040     types::String* varstr = new types::String(1, 2);
1041     varstr->set(0, L"variable");
1042     varstr->set(1, L"name");
1043     var->append(varstr);
1044     var->append(new types::String(str.c_str()));
1045     return var;
1046 }
1047
1048 types::List* TreeVisitor::createConst(types::InternalType* pIT)
1049 {
1050     types::TList* var = new types::TList();
1051     types::String* varstr = new types::String(1, 2);
1052     varstr->set(0, L"cste");
1053     varstr->set(1, L"value");
1054     var->append(varstr);
1055     var->append(pIT);
1056     return var;
1057 }
1058
1059 types::List* TreeVisitor::createOperation()
1060 {
1061     types::TList* var = new types::TList();
1062     types::String* varstr = new types::String(1, 3);
1063     varstr->set(0, L"operation");
1064     varstr->set(1, L"operands");
1065     varstr->set(2, L"operator");
1066     var->append(varstr);
1067     return var;
1068 }
1069
1070 types::List* TreeVisitor::createAssign()
1071 {
1072     types::TList* var = new types::TList();
1073     types::String* varstr = new types::String(1, 4);
1074     varstr->set(0, L"equal");
1075     varstr->set(1, L"expression");
1076     varstr->set(2, L"lhs");
1077     varstr->set(3, L"endsymbol");
1078     var->append(varstr);
1079     return var;
1080 }
1081
1082 types::InternalType* TreeVisitor::getVerbose(const Exp& e)
1083 {
1084     if (e.isVerbose())
1085     {
1086         return new types::String(L"");
1087     }
1088     else
1089     {
1090         return new types::String(L";");
1091     }
1092 }
1093 }