Merge remote-tracking branch 'origin/master' into jit
[scilab.git] / scilab / modules / ast / src / cpp / ast / printvisitor.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2008-2008 - DIGITEO - Bruno JOFRET
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 <cmath>
14
15 #include "string.hxx"
16 #include "printvisitor.hxx"
17
18 namespace ast
19 {
20
21 /** \name Visit Matrix Expressions nodes.
22  ** \{ */
23 void PrintVisitor::visit (const MatrixExp &e)
24 {
25     ast::exps_t::const_iterator i, j;
26     *ostr << SCI_OPEN_MATRIX;
27     ++indent;
28     this->is_last_matrix_line = false;
29     ast::exps_t lines = e.getLines();
30     for (i = lines.begin() ; i != lines.end() ; )
31     {
32         bool addIndent = false;
33         j = i;
34         if (++j == lines.end())
35         {
36             this->is_last_matrix_line = true;
37         }
38         else
39         {
40             if ((*i)->getLocation().last_line != (*j)->getLocation().first_line)
41             {
42                 addIndent = true;
43             }
44         }
45
46         if (displayOriginal)
47         {
48             (*i)->getOriginal()->accept(*this);
49         }
50         else
51         {
52             (*i)->accept(*this);
53         }
54
55         //if (lines.size() > 1 || this->is_last_column_comment)
56         if (addIndent)
57         {
58             *ostr << std::endl;
59             this->apply_indent();
60         }
61
62         ++i;
63     }
64     *ostr << SCI_CLOSE_MATRIX;
65     --indent;
66 }
67
68 void PrintVisitor::visit (const MatrixLineExp &e)
69 {
70     ast::exps_t::const_iterator i, j;
71     this->is_last_column_comment = false;
72
73     ast::exps_t cols = e.getColumns();
74     for (i = cols.begin() ; i != cols.end() ; )
75     {
76         if (displayOriginal)
77         {
78             (*i)->getOriginal()->accept(*this);
79         }
80         else
81         {
82             (*i)->accept(*this);
83         }
84
85         if ((*i)->isCommentExp())
86         {
87             this->is_last_column_comment = true;
88         }
89         if (++i != cols.end())
90         {
91             if ((*i)->isCommentExp() == false)
92             {
93                 *ostr << SCI_COLUMN_SEPARATOR;
94             }
95             *ostr << " ";
96         }
97     }
98
99     if (!this->is_last_column_comment && this->is_last_matrix_line == false)
100     {
101         *ostr << SCI_LINE_SEPARATOR;
102     }
103 }
104 /** \} */
105
106 /** \name Visit Cell Expressions nodes.
107  ** \{ */
108 void PrintVisitor::visit (const CellExp &e)
109 {
110     ast::exps_t::const_iterator i, j;
111
112     *ostr << SCI_OPEN_CELL;
113     ++indent;
114     ast::exps_t lines = e.getLines();
115     for (i = lines.begin() ; i != lines.end() ; )
116     {
117         if (displayOriginal)
118         {
119             (*i)->getOriginal()->accept(*this);
120         }
121         else
122         {
123             (*i)->accept(*this);
124         }
125         if (++i != lines.end())
126         {
127             *ostr << SCI_LINE_SEPARATOR << std::endl;
128             this->apply_indent();
129         }
130     }
131     *ostr << SCI_CLOSE_CELL;
132     --indent;
133 }
134 /** \} */
135
136 /** \name Visit Constant Expressions nodes.
137  ** \{ */
138 void PrintVisitor::visit (const StringExp &e)
139 {
140     if (types::InternalType * pIT = e.getConstant())
141     {
142         types::String * pStr = static_cast<types::String *>(pIT);
143         if (pStr->getSize() == 0)
144         {
145             *ostr << L"[]";
146         }
147         if (pStr->getSize() == 1)
148         {
149             std::wstring wstr(pStr->get(0, 0));
150             printString(wstr);
151         }
152         else
153         {
154             *ostr << L"[";
155             const int r = pStr->getRows();
156             const int c = pStr->getCols();
157             for (int i = 0; i < r; ++i)
158             {
159                 for (int j = 0; j < c - 1; ++j)
160                 {
161                     std::wstring wstr(pStr->get(i, j));
162                     printString(wstr);
163                     *ostr << L" ";
164                 }
165                 std::wstring wstr(pStr->get(i, c - 1));
166                 printString(wstr);
167                 *ostr << L";";
168             }
169             *ostr << L"]";
170         }
171     }
172     else
173     {
174         printString(e.getValue());
175     }
176 }
177
178 void PrintVisitor::visit (const CommentExp &e)
179 {
180     *ostr << SCI_OPEN_COMMENT;
181     *ostr << e.getComment();
182 }
183
184 void PrintVisitor::visit (const DoubleExp  &e)
185 {
186     if (types::InternalType * pIT = e.getConstant())
187     {
188         if (pIT->isDouble())
189         {
190             types::Double * pDbl = static_cast<types::Double *>(pIT);
191             if (pDbl->getSize() == 0)
192             {
193                 *ostr << L"[]";
194             }
195             else if (pDbl->getSize() == 1)
196             {
197                 if (pDbl->isComplex())
198                 {
199                     const double imag = pDbl->getImg()[0];
200                     if (imag != 0)
201                     {
202                         *ostr << pDbl->getReal()[0] << (imag > 0 ? L"+%i*" : L"-%i*") << std::abs(imag);
203                     }
204                     else
205                     {
206                         *ostr << pDbl->getReal()[0];
207                     }
208                 }
209                 else
210                 {
211                     *ostr << pDbl->getReal()[0];
212                 }
213             }
214             else
215             {
216                 *ostr << L"[";
217                 const int r = pDbl->getRows();
218                 const int c = pDbl->getCols();
219                 if (pDbl->isComplex())
220                 {
221                     for (int i = 0; i < r; ++i)
222                     {
223                         for (int j = 0; j < c - 1; ++j)
224                         {
225                             const double imag = pDbl->getImg(i, j);
226                             if (imag != 0)
227                             {
228                                 *ostr << pDbl->getReal(i, j) << (imag > 0 ? L"+%i*" : L"-%i*") << std::abs(imag) << L" ";
229                             }
230                             else
231                             {
232                                 *ostr << pDbl->get(i, j) << L" ";
233                             }
234                         }
235                         *ostr << pDbl->get(i, c - 1) << L";";
236                     }
237                 }
238                 else
239                 {
240                     for (int i = 0; i < r; ++i)
241                     {
242                         for (int j = 0; j < c - 1; ++j)
243                         {
244                             *ostr << pDbl->get(i, j) << L" ";
245                         }
246                         *ostr << pDbl->get(i, c - 1) << L";";
247                     }
248                 }
249                 *ostr << L"]";
250             }
251         }
252     }
253     else
254     {
255         *ostr << e.getValue();
256     }
257 }
258
259 void PrintVisitor::visit (const BoolExp  &e)
260 {
261     if (types::InternalType * pIT = e.getConstant())
262     {
263         if (pIT->isBool())
264         {
265             types::Bool * pBool = static_cast<types::Bool *>(pIT);
266             if (pBool->getSize() == 0)
267             {
268                 *ostr << L"[]";
269             }
270             if (pBool->getSize() == 1)
271             {
272                 *ostr << (pBool->get(0, 0) ? SCI_TRUE : SCI_FALSE);
273             }
274             else
275             {
276                 *ostr << L"[";
277                 const int r = pBool->getRows();
278                 const int c = pBool->getCols();
279                 for (int i = 0; i < r; ++i)
280                 {
281                     for (int j = 0; j < c - 1; ++j)
282                     {
283                         *ostr << (pBool->get(i, j) ? SCI_TRUE : SCI_FALSE) << L" ";
284                     }
285                     *ostr << (pBool->get(i, c - 1) ? SCI_TRUE : SCI_FALSE) << L";";
286                 }
287                 *ostr << L"]";
288             }
289         }
290     }
291     else
292     {
293         if (e.getValue() == true)
294         {
295             *ostr << SCI_TRUE;
296         }
297         else
298         {
299             *ostr << SCI_FALSE;
300         }
301     }
302 }
303
304 void PrintVisitor::visit (const NilExp &/*e*/)
305 {
306     /* Do Nothing */
307 }
308 /** \} */
309
310 /** \name Visit Variable related nodes.
311  ** \{ */
312 void PrintVisitor::visit (const SimpleVar &e)
313 {
314     *ostr << e.getSymbol().getName();
315 }
316
317 void PrintVisitor::visit (const ColonVar &/*e*/)
318 {
319     *ostr << SCI_COLON;
320 }
321
322 void PrintVisitor::visit (const DollarVar &/*e*/)
323 {
324     *ostr << SCI_DOLLAR;
325 }
326
327 void PrintVisitor::visit (const ArrayListVar &e)
328 {
329     exps_t vars = e.getVars();
330     for (exps_t::const_iterator it = vars.begin (), itEnd = vars.end(); it != itEnd; /**/)
331     {
332         if (displayOriginal)
333         {
334             (*it)->getOriginal()->accept(*this);
335         }
336         else
337         {
338             (*it)->accept(*this);
339         }
340         if (++it != itEnd)
341         {
342             *ostr << ", ";
343         }
344     }
345 }
346 /** \} */
347
348 /** \name Visit Control Expressions or Instructions nodes.
349  ** \{ */
350
351 void PrintVisitor::visit (const FieldExp &e)
352 {
353     if (displayOriginal)
354     {
355         e.getHead()->getOriginal()->accept(*this);
356     }
357     else
358     {
359         e.getHead()->accept(*this);
360     }
361     *ostr << SCI_FVAR_SEPARATOR;
362     if (displayOriginal)
363     {
364         e.getTail()->getOriginal()->accept(*this);
365     }
366     else
367     {
368         e.getTail()->accept(*this);
369     }
370 }
371
372 void PrintVisitor::visit(const OpExp &e)
373 {
374     bool old_force_parenthesis = force_parenthesis;
375
376     if (force_parenthesis)
377     {
378         *ostr << SCI_LPAREN;
379     }
380
381     if (e.getOper() != OpExp::unaryMinus)
382     {
383         // Getting Left Operand
384         this->enable_force_parenthesis();
385         if (displayOriginal)
386         {
387             e.getLeft().getOriginal()->accept(*this);
388         }
389         else
390         {
391             e.getLeft().accept(*this);
392         }
393         this->set_force_parenthesis(old_force_parenthesis);
394         *ostr << " ";
395     }
396
397     switch (e.getOper())
398     {
399         // Arithmetics.
400         case OpExp::plus:
401             *ostr << SCI_PLUS;
402             break;
403         case OpExp::unaryMinus:
404         case OpExp::minus:
405             *ostr << SCI_MINUS;
406             break;
407         case OpExp::times:
408             *ostr << SCI_TIMES;
409             break;
410         case OpExp::rdivide:
411             *ostr << SCI_RDIVIDE;
412             break;
413         case OpExp::ldivide:
414             *ostr << SCI_LDIVIDE;
415             break;
416         case OpExp::power:
417             *ostr << SCI_POWER;
418             break;
419         // Element Ways.
420         case OpExp::dottimes:
421             *ostr << SCI_DOTTIMES;
422             break;
423         case OpExp::dotrdivide:
424             *ostr << SCI_DOTRDIVIDE;
425             break;
426         case OpExp::dotldivide:
427             *ostr << SCI_DOTLDIVIDE;
428             break;
429         case OpExp::dotpower:
430             *ostr << SCI_DOTPOWER;
431             break;
432         // Kroneckers
433         case OpExp::krontimes:
434             *ostr << SCI_KRONTIMES;
435             break;
436         case OpExp::kronrdivide:
437             *ostr << SCI_KRONRDIVIDE;
438             break;
439         case OpExp::kronldivide:
440             *ostr << SCI_KRONLDIVIDE;
441             break;
442         // Control
443         case OpExp::controltimes:
444             *ostr << SCI_CONTROLTIMES;
445             break;
446         case OpExp::controlrdivide:
447             *ostr << SCI_CONTROLRDIVIDE;
448             break;
449         case OpExp::controlldivide:
450             *ostr << SCI_CONTROLLDIVIDE;
451             break;
452         // Comparisons
453         case OpExp::eq:
454             *ostr << SCI_EQ;
455             break;
456         case OpExp::ne:
457             *ostr << SCI_NE;
458             break;
459         case OpExp::lt:
460             *ostr << SCI_LT;
461             break;
462         case OpExp::le:
463             *ostr << SCI_LE;
464             break;
465         case OpExp::gt:
466             *ostr << SCI_GT;
467             break;
468         case OpExp::ge:
469             *ostr << SCI_GE;
470             break;
471         default :
472             // FIXME : This case should never happend.
473             break;
474     }
475     *ostr << " ";
476
477     // Now getting right operand
478     this->enable_force_parenthesis();
479     if (displayOriginal)
480     {
481         e.getRight().getOriginal()->accept(*this);
482     }
483     else
484     {
485         e.getRight().accept(*this);
486     }
487     this->set_force_parenthesis(old_force_parenthesis);
488
489     if (force_parenthesis)
490     {
491         *ostr << SCI_RPAREN;
492     }
493 }
494
495 void PrintVisitor::visit(const LogicalOpExp &e)
496 {
497     bool old_force_parenthesis = force_parenthesis;
498
499     if (force_parenthesis)
500     {
501         *ostr << SCI_LPAREN;
502     }
503
504     // Getting Left Operand
505     this->enable_force_parenthesis();
506     if (displayOriginal)
507     {
508         e.getLeft().getOriginal()->accept(*this);
509     }
510     else
511     {
512         e.getLeft().accept(*this);
513     }
514     this->set_force_parenthesis(old_force_parenthesis);
515
516     *ostr << " ";
517     switch (e.getOper())
518     {
519         // Binary Operators
520         case LogicalOpExp::logicalAnd:
521             *ostr << SCI_AND;
522             break;
523         case LogicalOpExp::logicalOr:
524             *ostr << SCI_OR;
525             break;
526         case LogicalOpExp::logicalShortCutAnd:
527             *ostr << SCI_ANDAND;
528             break;
529         case LogicalOpExp::logicalShortCutOr:
530             *ostr << SCI_OROR;
531             break;
532         default :
533             // FIXME : This case should never happend.
534             break;
535     }
536     *ostr << " ";
537
538     // Now getting right operand
539     this->enable_force_parenthesis();
540     if (displayOriginal)
541     {
542         e.getRight().getOriginal()->accept(*this);
543     }
544     else
545     {
546         e.getRight().accept(*this);
547     }
548     this->set_force_parenthesis(old_force_parenthesis);
549
550     if (force_parenthesis)
551     {
552         *ostr << SCI_RPAREN;
553     }
554 }
555
556 void PrintVisitor::visit (const AssignExp  &e)
557 {
558     if (displayOriginal)
559     {
560         e.getLeftExp().getOriginal()->accept(*this);
561         *ostr << " " << SCI_ASSIGN << " ";
562         e.getRightExp().getOriginal()->accept(*this);
563     }
564     else
565     {
566         e.getLeftExp().accept(*this);
567         *ostr << " " << SCI_ASSIGN << " ";
568         e.getRightExp().accept(*this);
569     }
570 }
571
572 void PrintVisitor::visit(const CellCallExp &e)
573 {
574     if (displayOriginal)
575     {
576         e.getName().getOriginal()->accept(*this);
577     }
578     else
579     {
580         e.getName().accept(*this);
581     }
582     *ostr << SCI_OPEN_CELL;
583     exps_t args = e.getArgs();
584     for (exps_t::const_iterator it = args.begin(), itEnd = args.end(); it != itEnd; /**/)
585     {
586         if (displayOriginal)
587         {
588             (*it)->getOriginal()->accept(*this);
589         }
590         else
591         {
592             (*it)->accept(*this);
593         }
594         if (++it != itEnd)
595         {
596             *ostr << SCI_COMMA << " ";
597         }
598     }
599     *ostr << SCI_CLOSE_CELL;
600 }
601
602 void PrintVisitor::visit(const CallExp &e)
603 {
604     if (displayOriginal)
605     {
606         e.getName().getOriginal()->accept(*this);
607     }
608     else
609     {
610         e.getName().accept(*this);
611     }
612     *ostr << SCI_OPEN_CALL;
613
614     exps_t args = e.getArgs();
615     for (exps_t::const_iterator it = args.begin(), itEnd = args.end(); it != itEnd; /**/)
616     {
617         if (displayOriginal)
618         {
619             (*it)->getOriginal()->accept(*this);
620         }
621         else
622         {
623             (*it)->accept(*this);
624         }
625         if (++it != itEnd)
626         {
627             *ostr << SCI_COMMA << " ";
628         }
629     }
630     *ostr << SCI_CLOSE_CALL;
631 }
632
633 void PrintVisitor::visit (const IfExp  &e)
634 {
635     *ostr << SCI_IF;
636     *ostr << " " << SCI_OPEN_TEST;
637     if (displayOriginal)
638     {
639         e.getTest().getOriginal()->accept(*this);
640     }
641     else
642     {
643         e.getTest().accept(*this);
644     }
645     *ostr << SCI_CLOSE_TEST << " ";
646     *ostr << SCI_THEN << std::endl;
647
648     if (headerOnly)
649     {
650         return;
651     }
652
653     ++indent;
654     if (displayOriginal)
655     {
656         e.getThen().getOriginal()->accept(*this);
657     }
658     else
659     {
660         e.getThen().accept(*this);
661     }
662     --indent;
663     if (e.hasElse())
664     {
665         this->apply_indent();
666         *ostr << SCI_ELSE << std::endl;
667         ++indent;
668         if (displayOriginal)
669         {
670             e.getElse().getOriginal()->accept(*this);
671         }
672         else
673         {
674             e.getElse().accept(*this);
675         }
676         --indent;
677     }
678     this->apply_indent();
679     *ostr << SCI_ENDIF;
680 }
681
682 void PrintVisitor::visit (const TryCatchExp  &e)
683 {
684     *ostr << SCI_TRY << std::endl;
685
686     if (headerOnly)
687     {
688         return;
689     }
690
691     ++indent;
692     if (displayOriginal)
693     {
694         e.getTry().getOriginal()->accept(*this);
695     }
696     else
697     {
698         e.getTry().accept(*this);
699     }
700     --indent;
701     this->apply_indent();
702     *ostr << SCI_CATCH << std::endl;
703     ++indent;
704     if (displayOriginal)
705     {
706         e.getCatch().getOriginal()->accept(*this);
707     }
708     else
709     {
710         e.getCatch().accept(*this);
711     }
712     --indent;
713     this->apply_indent();
714     *ostr << SCI_ENDTRY;
715 }
716
717 void PrintVisitor::visit (const WhileExp  &e)
718 {
719     *ostr << SCI_WHILE;
720     *ostr << " " << SCI_OPEN_TEST;
721     if (displayOriginal)
722     {
723         e.getTest().getOriginal()->accept(*this);
724     }
725     else
726     {
727         e.getTest().accept(*this);
728     }
729     *ostr << SCI_CLOSE_TEST << " " << SCI_DO << std::endl;
730
731     if (headerOnly)
732     {
733         return;
734     }
735
736     ++indent;
737     if (displayOriginal)
738     {
739         e.getBody().getOriginal()->accept(*this);
740     }
741     else
742     {
743         e.getBody().accept(*this);
744     }
745     --indent;
746     this->apply_indent();
747     *ostr << SCI_ENDWHILE;
748 }
749
750 void PrintVisitor::visit (const ForExp  &e)
751 {
752     *ostr << SCI_FOR;
753     *ostr << " " << SCI_OPEN_TEST;
754     if (displayOriginal)
755     {
756         e.getVardec().getOriginal()->accept(*this);
757     }
758     else
759     {
760         e.getVardec().accept(*this);
761     }
762     *ostr << SCI_CLOSE_TEST << " ";
763     *ostr << SCI_DO << std::endl;
764
765     if (headerOnly)
766     {
767         return;
768     }
769
770     ++indent;
771     if (displayOriginal)
772     {
773         e.getBody().getOriginal()->accept(*this);
774     }
775     else
776     {
777         e.getBody().accept(*this);
778     }
779     --indent;
780     this->apply_indent();
781     *ostr << SCI_ENDFOR;
782 }
783
784 void PrintVisitor::visit (const BreakExp &/*e*/)
785 {
786     *ostr << SCI_BREAK;
787 }
788
789 void PrintVisitor::visit (const ContinueExp &/*e*/)
790 {
791     *ostr << SCI_CONTINUE;
792 }
793
794 void PrintVisitor::visit (const ReturnExp &e)
795 {
796     *ostr << SCI_RETURN;
797     if (!e.isGlobal())
798     {
799         *ostr << " " ;
800         if (displayOriginal)
801         {
802             e.getExp().getOriginal()->accept(*this);
803         }
804         else
805         {
806             e.getExp().accept(*this);
807         }
808     }
809 }
810
811 void PrintVisitor::visit (const SelectExp &e)
812 {
813     *ostr << SCI_SELECT;
814     *ostr << " " << SCI_OPEN_TEST;
815     if (displayOriginal)
816     {
817         e.getSelect()->getOriginal()->accept(*this);
818     }
819     else
820     {
821         e.getSelect()->accept(*this);
822     }
823     *ostr << SCI_CLOSE_TEST << std::endl;
824     ++indent;
825     exps_t cases = e.getCases();
826     for (auto exp : cases)
827     {
828         if (displayOriginal)
829         {
830             exp->getOriginal()->accept(*this);
831         }
832         else
833         {
834             exp->accept(*this);
835         }
836     }
837
838     if (e.hasDefault())
839     {
840         this->apply_indent();
841         *ostr << SCI_DEFAULT_CASE << std::endl;
842         ++indent;
843         if (displayOriginal)
844         {
845             e.getDefaultCase()->getOriginal()->accept(*this);
846         }
847         else
848         {
849             e.getDefaultCase()->accept(*this);
850         }
851         --indent;
852     }
853     --indent;
854     this->apply_indent();
855     *ostr << SCI_ENDSELECT;
856 }
857
858 void PrintVisitor::visit (const CaseExp &e)
859 {
860     this->apply_indent();
861     *ostr << SCI_CASE;
862     *ostr << " " << SCI_OPEN_TEST;
863     if (displayOriginal)
864     {
865         e.getTest()->getOriginal()->accept(*this);
866     }
867     else
868     {
869         e.getTest()->accept(*this);
870     }
871     *ostr << SCI_CLOSE_TEST << std::endl;
872     indent++;
873     if (displayOriginal)
874     {
875         e.getBody()->getOriginal()->accept(*this);
876     }
877     else
878     {
879         e.getBody()->accept(*this);
880     }
881     indent--;
882 }
883
884 void PrintVisitor::visit (const SeqExp  &e)
885 {
886     int previousLine = -1;
887     bool bPreviousVerbose = false;
888     for (exps_t::const_iterator it = e.getExps().begin (), itEnd = e.getExps().end(); it != itEnd; ++it)
889     {
890         if (previousLine == -1)
891         {
892             this->apply_indent();
893         }
894
895         if (previousLine != -1 && (*it)->getLocation().first_line != previousLine)
896         {
897             *ostr << std::endl;
898             this->apply_indent();
899         }
900
901         if ((*it)->getLocation().first_line == previousLine && bPreviousVerbose)
902         {
903             *ostr << ",";
904         }
905
906         if (displayOriginal)
907         {
908             (*it)->getOriginal()->accept(*this);
909         }
910         else
911         {
912             (*it)->accept(*this);
913         }
914         bPreviousVerbose = (*it)->isVerbose();
915         if (!(*it)->isVerbose())
916         {
917             *ostr << ";";
918         }
919
920         previousLine = (*it)->getLocation().last_line;
921     }
922
923     *ostr << std::endl;
924 }
925
926 void PrintVisitor::visit (const ArrayListExp  &e)
927 {
928     *ostr << SCI_LPAREN;
929     for (exps_t::const_iterator it = e.getExps().begin (), itEnd = e.getExps().end(); it != itEnd; /**/)
930     {
931         if (displayOriginal)
932         {
933             (*it)->getOriginal()->accept(*this);
934         }
935         else
936         {
937             (*it)->accept(*this);
938         }
939         if (++it != itEnd)
940         {
941             *ostr << SCI_COMMA << " ";
942         }
943     }
944     *ostr << SCI_RPAREN;
945 }
946
947 void PrintVisitor::visit (const AssignListExp  &e)
948 {
949     *ostr << SCI_LBRACK;
950     ast::exps_t exps = e.getExps();
951     for (exps_t::const_iterator it = exps.begin (), itEnd = exps.end(); it != itEnd; /**/)
952     {
953         if (displayOriginal)
954         {
955             (*it)->getOriginal()->accept(*this);
956         }
957         else
958         {
959             (*it)->accept(*this);
960         }
961         if (++it != itEnd)
962         {
963             *ostr << SCI_COMMA << " ";
964         }
965     }
966     *ostr << SCI_RBRACK;
967 }
968 /** \} */
969
970 /** \name Visit Single Operation nodes.
971  ** \{ */
972 void PrintVisitor::visit (const NotExp &e)
973 {
974     *ostr << SCI_NOT;
975     *ostr << SCI_LPAREN;
976     if (displayOriginal)
977     {
978         e.getExp().getOriginal()->accept(*this);
979     }
980     else
981     {
982         e.getExp().accept(*this);
983     }
984     *ostr << SCI_RPAREN;
985 }
986
987 void PrintVisitor::visit (const TransposeExp &e)
988 {
989     *ostr << SCI_LPAREN;
990     if (displayOriginal)
991     {
992         e.getExp().getOriginal()->accept(*this);
993     }
994     else
995     {
996         e.getExp().accept(*this);
997     }
998     *ostr << SCI_RPAREN;
999     if (e.getConjugate() == TransposeExp::_Conjugate_)
1000     {
1001         *ostr << SCI_CONJUGATE_TRANSPOSE;
1002     }
1003     if (e.getConjugate() == TransposeExp::_NonConjugate_)
1004     {
1005         *ostr << SCI_TRANSPOSE;
1006     }
1007 }
1008 /** \} */
1009
1010 /** \name Visit Declaration nodes.
1011  ** \{ */
1012 /** \brief Visit Var declarations. */
1013 void PrintVisitor::visit (const VarDec  &e)
1014 {
1015     *ostr << e.getSymbol().getName();
1016     *ostr << SCI_ASSIGN;
1017     if (displayOriginal)
1018     {
1019         e.getInit().getOriginal()->accept(*this);
1020     }
1021     else
1022     {
1023         e.getInit().accept(*this);
1024     }
1025 }
1026
1027 void PrintVisitor::visit (const FunctionDec  &e)
1028 {
1029     *ostr << SCI_FUNCTION << " ";
1030
1031     // First ask if there are some return values.
1032     if (e.getReturns().getAs<ArrayListVar>()->getVars().size() > 1)
1033     {
1034         *ostr << SCI_OPEN_RETURNS;
1035     }
1036
1037     if (displayOriginal)
1038     {
1039         e.getReturns().getOriginal()->accept(*this);
1040     }
1041     else
1042     {
1043         e.getReturns().accept(*this);
1044     }
1045
1046     if (e.getReturns().getAs<ArrayListVar>()->getVars().size() > 1)
1047     {
1048         *ostr << SCI_CLOSE_RETURNS;
1049     }
1050
1051     *ostr << " ";
1052     if (e.getReturns().getAs<ArrayListVar>()->getVars().size() > 0)
1053     {
1054         *ostr << SCI_ASSIGN << " ";
1055     }
1056
1057     // Then get the function name
1058     *ostr << e.getSymbol().getName();
1059
1060     // Then get function args
1061     *ostr << SCI_OPEN_ARGS;
1062     if (displayOriginal)
1063     {
1064         e.getArgs().getOriginal()->accept(*this);
1065     }
1066     else
1067     {
1068         e.getArgs().accept(*this);
1069     }
1070     *ostr << SCI_CLOSE_ARGS << std::endl;
1071
1072     // Now print function body
1073     ++indent;
1074     if (displayOriginal)
1075     {
1076         e.getBody().getOriginal()->accept(*this);
1077     }
1078     else
1079     {
1080         e.getBody().accept(*this);
1081     }
1082     --indent;
1083     this->apply_indent();
1084
1085     // Close function declaration
1086     *ostr << SCI_ENDFUNCTION;
1087 }
1088 /** \} */
1089
1090 /** \name Visit Type dedicated Expressions related node.
1091  ** \{ */
1092 void PrintVisitor::visit(const ListExp &e)
1093 {
1094     *ostr << SCI_LPAREN;
1095     if (displayOriginal)
1096     {
1097         e.getStart().getOriginal()->accept(*this);
1098     }
1099     else
1100     {
1101         e.getStart().accept(*this);
1102     }
1103     if (e.hasExplicitStep())
1104     {
1105         *ostr << SCI_IMPLICIT_LIST;
1106         if (displayOriginal)
1107         {
1108             e.getStep().getOriginal()->accept(*this);
1109         }
1110         else
1111         {
1112             e.getStep().accept(*this);
1113         }
1114     }
1115     *ostr << SCI_IMPLICIT_LIST;
1116     if (displayOriginal)
1117     {
1118         e.getEnd().getOriginal()->accept(*this);
1119     }
1120     else
1121     {
1122         e.getEnd().accept(*this);
1123     }
1124     *ostr << SCI_RPAREN;
1125 }
1126 /** \} */
1127
1128
1129 void PrintVisitor::visit(const OptimizedExp &e)
1130 {
1131     e.getOriginal()->accept(*this);
1132 }
1133
1134 void PrintVisitor::visit(const MemfillExp &e)
1135 {
1136     e.getOriginal()->accept(*this);
1137 }
1138
1139 void PrintVisitor::visit(const DAXPYExp &e)
1140 {
1141     e.getOriginal()->accept(*this);
1142 }
1143
1144 void PrintVisitor::visit(const IntSelectExp &e)
1145 {
1146     e.getOriginal()->accept(*this);
1147 }
1148
1149 void PrintVisitor::visit(const StringSelectExp &e)
1150 {
1151     e.getOriginal()->accept(*this);
1152 }
1153
1154 void PrintVisitor::apply_indent()
1155 {
1156     int i;
1157     for (i = 0; i < indent; ++i)
1158     {
1159         *ostr << "    ";
1160     }
1161 }
1162
1163 void PrintVisitor::enable_force_parenthesis()
1164 {
1165     force_parenthesis = true;
1166 }
1167
1168 void PrintVisitor::set_force_parenthesis(bool new_state)
1169 {
1170     force_parenthesis = new_state;
1171 }
1172
1173 }