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