* Bug #14455 - macr2tree crashed when passing a FieldExp
[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* operation = 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         operation->append(lhs);
546         lhs->killMe();
547
548         //operator
549         operation->append(new types::String(L"ins"));
550         types::List* lst = new types::List();
551         lst->append(operation);
552         operation->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     if (e.getName().isSimpleVar())
623     {
624         const ast::SimpleVar & var = static_cast<const ast::SimpleVar &>(e.getName());
625
626         types::TList* call = new types::TList();
627
628         //header
629         types::String* varstr = new types::String(1, 4);
630         varstr->set(0, L"funcall");
631         varstr->set(1, L"rhs");
632         varstr->set(2, L"name");
633         varstr->set(3, L"lhsnb");
634         call->append(varstr);
635
636         //rhs
637         types::List* rhs = new types::List();
638         ast::exps_t args = e.getArgs();
639         for (auto arg : args)
640         {
641             arg->accept(*this);
642             types::List* tmp = getList();
643             rhs->append(tmp);
644             tmp->killMe();
645         }
646
647         call->append(rhs);
648         rhs->killMe();
649
650         //name
651         const std::wstring & name = var.getSymbol().getName();
652         call->append(new types::String(name.c_str()));
653
654         //lhsnb
655         //use default value 1
656         //parent exp like assign can adapt it.
657         call->append(new types::Double(1));
658
659         l = call;
660     }
661     else
662     {
663         //not yet managed
664     }
665 }
666
667 void TreeVisitor::visit(const ForExp &e)
668 {
669     types::TList* f = new types::TList();
670
671     //header
672     types::String* varstr = new types::String(1, 3);
673     varstr->set(0, L"for");
674     varstr->set(1, L"expression");
675     varstr->set(2, L"statements");
676     f->append(varstr);
677
678     //expression
679     //create a AssignExp to call visitor it
680     VarDec* vardec = e.getVardec().getAs<VarDec>();
681     SimpleVar* var = new SimpleVar(vardec->getLocation(), vardec->getSymbol());
682     Exp* init = vardec->getInit().clone();
683     AssignExp* assign = new AssignExp(vardec->getLocation(), *var, *init);
684     assign->setVerbose(true);
685
686     assign->accept(*this);
687     types::List* tmp = getList();
688     f->append(tmp);
689     tmp->killMe();
690     delete assign;
691
692     //statements
693     e.getBody().accept(*this);
694     tmp = getList();
695     f->append(tmp);
696     tmp->killMe();
697     l = f;
698 }
699
700 void TreeVisitor::visit(const FieldExp &e)
701 {
702     types::List* ext = createOperation();
703     types::List* ope = new types::List();
704
705     //function or varname
706     e.getHead()->accept(*this);
707     types::List* tmp = getList();
708     ope->append(tmp);
709     tmp->killMe();
710
711     //arguments
712     if (e.getTail()->isSimpleVar())
713     {
714         const SimpleVar* pVar = e.getTail()->getAs<SimpleVar>();
715         tmp = createConst(new types::String(pVar->getSymbol().getName().c_str()));
716         ope->append(tmp);
717         tmp->killMe();
718     }
719     else
720     {
721         tmp = getList();
722         ope->append(tmp);
723         tmp->killMe();
724     }
725
726     //operator
727     ext->append(ope);
728     ope->killMe();
729     ext->append(new types::String(L"ext"));
730     l = ext;
731 }
732
733 void TreeVisitor::visit(const TryCatchExp &e)
734 {
735     types::TList* tc = new types::TList();
736
737     //header
738     types::String* varstr = new types::String(1, 3);
739     varstr->set(0, L"trycatch");
740     varstr->set(1, L"trystat");
741     varstr->set(2, L"catchstat");
742     tc->append(varstr);
743
744     //trystat
745     e.getTry().accept(*this);
746     types::List* tmp = getList();
747     tc->append(tmp);
748     tmp->killMe();
749
750     //catchstat
751     e.getCatch().accept(*this);
752     tmp = getList();
753     tc->append(tmp);
754     tmp->killMe();
755
756     l = tc;
757 }
758
759 void TreeVisitor::visit(const WhileExp &e)
760 {
761     types::TList* w = new types::TList();
762
763     //header
764     types::String* varstr = new types::String(1, 3);
765     varstr->set(0, L"while");
766     varstr->set(1, L"expression");
767     varstr->set(2, L"statements");
768     w->append(varstr);
769
770     //expression
771     e.getTest().accept(*this);
772     types::List* tmp = getList();
773     w->append(tmp);
774     tmp->killMe();
775
776     //statements
777     e.getBody().accept(*this);
778     tmp = getList();
779     w->append(tmp);
780     tmp->killMe();
781     l = w;
782 }
783
784 void TreeVisitor::visit(const ContinueExp &/*e*/)
785 {
786     l = createVar(L"continue");
787 }
788
789 void TreeVisitor::visit(const BreakExp &/*e*/)
790 {
791     l = createVar(L"break");
792 }
793
794 void TreeVisitor::visit(const ReturnExp &e)
795 {
796     if (e.isGlobal())
797     {
798         l = createVar(L"resume");
799     }
800     else
801     {
802         types::List* ext = createOperation();
803         types::List* ope = new types::List();
804
805         //function or varname
806         ope->append(new types::String(L"return"));
807
808         //arguments
809         for (auto arg : e.getExp().getAs<ArrayListExp>()->getExps())
810         {
811             arg->accept(*this);
812             types::List* tmp = getList();
813             ope->append(tmp);
814             tmp->killMe();
815         }
816
817         //operator
818         ext->append(ope);
819         ope->killMe();
820         ext->append(new types::String(L"ext"));
821         l = ext;
822     }
823 }
824
825 void TreeVisitor::visit(const SelectExp &e)
826 {
827     types::TList* select = new types::TList();
828
829     //header
830     types::String* varstr = new types::String(1, 4);
831     varstr->set(0, L"selectcase");
832     varstr->set(1, L"expression");
833     varstr->set(2, L"cases");
834     varstr->set(3, L"else");
835     select->append(varstr);
836
837     //expression
838     types::List* cond = new types::List();
839     e.getSelect()->accept(*this);
840     types::List* tmp = getList();
841     cond->append(tmp);
842     tmp->killMe();
843     cond->append(getEOL());
844     select->append(cond);
845     cond->killMe();
846
847     //cases
848     types::List* lcases = new types::List();
849     ast::exps_t cases = e.getCases();
850     for (auto c : cases)
851     {
852         c->accept(*this);
853         tmp = getList();
854         lcases->append(tmp);
855         tmp->killMe();
856     }
857
858     select->append(lcases);
859     lcases->killMe();
860
861     //default
862     if (e.hasDefault())
863     {
864         e.getDefaultCase()->accept(*this);
865         tmp = getList();
866         select->append(tmp);
867         tmp->killMe();
868     }
869     else
870     {
871         select->append(new types::List());
872
873     }
874     l = select;
875 }
876
877 void TreeVisitor::visit(const CaseExp &e)
878 {
879     types::TList* c = new types::TList();
880
881     //header
882     types::String* varstr = new types::String(1, 3);
883     varstr->set(0, L"case");
884     varstr->set(1, L"expression");
885     varstr->set(2, L"then");
886     c->append(varstr);
887
888     //expression
889     e.getTest()->accept(*this);
890     types::List* tmp = getList();
891     c->append(tmp);
892     tmp->killMe();
893
894     //then
895     e.getBody()->accept(*this);
896     tmp = getList();
897     c->append(tmp);
898     tmp->killMe();
899
900     l = c;
901 }
902
903 void TreeVisitor::visit(const ArrayListExp  &e)
904 {
905     types::List* ext = createOperation();
906     types::List* ope = new types::List();
907
908     //function or varname
909     ope->append(new types::String(L""));
910
911     //arguments
912     for (auto arg : e.getExps())
913     {
914         arg->accept(*this);
915         types::List* tmp = getList();
916         ope->append(tmp);
917         tmp->killMe();
918     }
919
920     //operator
921     ext->append(ope);
922     ope->killMe();
923     ext->append(new types::String(L"ext"));
924     l = ext;
925 }
926
927 void TreeVisitor::visit(const NotExp  &e)
928 {
929     types::List* ext = createOperation();
930     types::List* ope = new types::List();
931
932     //function or varname
933     e.getExp().accept(*this);
934     types::List* tmp = getList();
935     ope->append(tmp);
936     tmp->killMe();
937
938     //operator
939     ext->append(ope);
940     ope->killMe();
941     ext->append(new types::String(L"~"));
942     l = ext;
943 }
944
945 void TreeVisitor::visit(const TransposeExp  &e)
946 {
947     types::List* ext = createOperation();
948     types::List* ope = new types::List();
949
950     //function or varname
951     e.getExp().accept(*this);
952     types::List* tmp = getList();
953     ope->append(tmp);
954     tmp->killMe();
955
956     //operator
957     ext->append(ope);
958     ope->killMe();
959     ext->append(new types::String(L"'"));
960     l = ext;
961 }
962
963 void TreeVisitor::visit(const FunctionDec  &e)
964 {
965     wchar_t* pwstState;
966     std::wostringstream wostr;
967     PrintVisitor pv(wostr, false, false);
968
969     types::TList* function = new types::TList();
970
971     //header
972     types::String* varstr = new types::String(1, 3);
973     varstr->set(0, L"inline");
974     varstr->set(1, L"prototype");
975     varstr->set(2, L"definition");
976     function->append(varstr);
977     size_t returnSize = e.getReturns().getOriginal()->getAs<ArrayListVar>()->getVars().size();
978     // First ask if there are some return values.
979     if (returnSize > 1)
980     {
981         wostr << SCI_OPEN_RETURNS;
982     }
983
984     e.getReturns().getOriginal()->accept(pv);
985
986     if (returnSize > 1)
987     {
988         wostr << SCI_CLOSE_RETURNS;
989     }
990
991     if (returnSize > 0)
992     {
993         wostr << L" " << SCI_ASSIGN << L" ";
994     }
995
996     // Then get the function name
997     wostr << e.getSymbol().getName();
998
999     // Then get function args
1000     wostr << SCI_OPEN_ARGS;
1001     e.getArgs().getOriginal()->accept(pv);
1002     wostr << SCI_CLOSE_ARGS << std::endl;
1003     wchar_t* pwstFun = os_wcsdup(wostr.str().data());
1004     function->append(new types::String(os_wcstok(pwstFun, L"\n", &pwstState)));
1005     FREE(pwstFun);
1006
1007     // Now print function body
1008     std::wostringstream wostrBody;
1009     PrintVisitor pvBody(wostrBody, false, true);
1010     std::vector<wchar_t*> allTokens;
1011     e.getBody().getOriginal()->accept(pvBody);
1012     wchar_t* pwstBody = os_wcsdup(wostrBody.str().data());
1013     wchar_t* pwstToken = os_wcstok(pwstBody, L"\n", &pwstState);
1014     while (pwstToken != NULL)
1015     {
1016         allTokens.push_back(pwstToken);
1017         pwstToken = os_wcstok(NULL, L"\n", &pwstState);
1018     }
1019
1020     if (allTokens.size() > 0)
1021     {
1022         types::String* stringMatrix = new types::String(static_cast<int>(allTokens.size()), 1);
1023         stringMatrix->set(allTokens.data());
1024         function->append(stringMatrix);
1025     }
1026     else
1027     {
1028         function->append(types::Double::Empty());
1029     }
1030     FREE(pwstBody);
1031
1032     l = function;
1033 }
1034
1035 types::InternalType* TreeVisitor::getEOL()
1036 {
1037     if (eol)
1038     {
1039         return eol;
1040     }
1041
1042     eol = new types::List();
1043     eol->append(new types::String(L"EOL"));
1044     return eol;
1045 }
1046
1047 types::List* TreeVisitor::createVar(const std::wstring& str)
1048 {
1049     types::TList* var = new types::TList();
1050     types::String* varstr = new types::String(1, 2);
1051     varstr->set(0, L"variable");
1052     varstr->set(1, L"name");
1053     var->append(varstr);
1054     var->append(new types::String(str.c_str()));
1055     return var;
1056 }
1057
1058 types::List* TreeVisitor::createConst(types::InternalType* pIT)
1059 {
1060     types::TList* var = new types::TList();
1061     types::String* varstr = new types::String(1, 2);
1062     varstr->set(0, L"cste");
1063     varstr->set(1, L"value");
1064     var->append(varstr);
1065     var->append(pIT);
1066     return var;
1067 }
1068
1069 types::List* TreeVisitor::createOperation()
1070 {
1071     types::TList* var = new types::TList();
1072     types::String* varstr = new types::String(1, 3);
1073     varstr->set(0, L"operation");
1074     varstr->set(1, L"operands");
1075     varstr->set(2, L"operator");
1076     var->append(varstr);
1077     return var;
1078 }
1079
1080 types::List* TreeVisitor::createAssign()
1081 {
1082     types::TList* var = new types::TList();
1083     types::String* varstr = new types::String(1, 4);
1084     varstr->set(0, L"equal");
1085     varstr->set(1, L"expression");
1086     varstr->set(2, L"lhs");
1087     varstr->set(3, L"endsymbol");
1088     var->append(varstr);
1089     return var;
1090 }
1091
1092 types::InternalType* TreeVisitor::getVerbose(const Exp& e)
1093 {
1094     if (e.isVerbose())
1095     {
1096         return new types::String(L"");
1097     }
1098     else
1099     {
1100         return new types::String(L";");
1101     }
1102 }
1103 }