Analysis: fix bugs
[scilab.git] / scilab / modules / ast / includes / analysis / gvn / SymbolicList.hxx
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2015 - Scilab Enterprises - Calixte DENIZET
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 #ifndef __SYMBOLIC_LIST_HXX__
14 #define __SYMBOLIC_LIST_HXX__
15
16 #include <iostream>
17
18 #include "GVN.hxx"
19 #include "TIType.hxx"
20
21 namespace analysis
22 {
23
24 /**
25  * \class SymbolicList
26  * \brief Manage a symbolic list
27  */
28 class SymbolicList
29 {
30
31     union Value
32     {
33         GVN::Value * gvnVal;
34         double dval;
35
36         Value() { }
37         Value(GVN::Value * val) : gvnVal(val) { }
38         Value(double val) : dval(val) { }
39     };
40
41     Value start;
42     Value step;
43     Value end;
44
45     bool symbolic;
46
47 public:
48
49     /**
50      * \brief default constructor
51      */
52     SymbolicList() : symbolic(false), start(0.), step(0.), end(0.) { }
53
54     /**
55      * \brief constructor
56      * \param _gvn the GVN to use
57      * \param _start the starting value
58      * \param _end the ending value
59      */
60     SymbolicList(GVN::Value * _start, GVN::Value * _step, GVN::Value * _end) : symbolic(true), start(_start), step(_step), end(_end) { }
61
62     /**
63      * \brief constructor
64      * \param _gvn the GVN to use
65      * \param _start the starting value
66      * \param _end the ending value
67      */
68     SymbolicList(double _start, double _step, double _end) : symbolic(false), start(_start), step(_step), end(_end) { }
69
70     /**
71      * \brief constructor
72      */
73     SymbolicList(SymbolicList && sl) : symbolic(sl.symbolic), start(sl.start), step(sl.step), end(sl.end) { }
74
75     inline SymbolicList & operator=(SymbolicList && sl)
76     {
77         symbolic = sl.symbolic;
78         start = sl.start;
79         step = sl.step;
80         end = sl.end;
81
82         return *this;
83     }
84
85     inline bool isSymbolic() const
86     {
87         return symbolic;
88     }
89
90     inline void setStart(GVN::Value * val)
91     {
92         start.gvnVal = val;
93     }
94
95     inline void setStep(GVN::Value * val)
96     {
97         step.gvnVal = val;
98     }
99
100     inline void setEnd(GVN::Value * val)
101     {
102         end.gvnVal = val;
103     }
104
105     inline GVN::Value * getStart() const
106     {
107         return start.gvnVal;
108     }
109
110     inline GVN::Value * getStep() const
111     {
112         return step.gvnVal;
113     }
114
115     inline GVN::Value * getEnd() const
116     {
117         return end.gvnVal;
118     }
119
120     inline double getStart(double) const
121     {
122         return start.dval;
123     }
124
125     inline double getStep(double) const
126     {
127         return step.dval;
128     }
129
130     inline double getEnd(double) const
131     {
132         return end.dval;
133     }
134
135     bool getType(GVN & gvn, TIType & type) const;
136     void evalDollar(GVN & gvn, const GVN::Value * dollarVal);
137     bool checkAsIndex(const GVN::Value * dim);
138
139     static bool get(AnalysisVisitor & visitor, ast::ListExp & le, SymbolicList & sl);
140
141     /**
142      * \brief Overload of the << operator
143      */
144     friend inline std::wostream & operator<<(std::wostream & out, const SymbolicList & sl)
145     {
146         if (sl.symbolic)
147         {
148             out << *sl.start.gvnVal->poly << L" : " << *sl.step.gvnVal->poly << L" : " << *sl.end.gvnVal->poly;
149         }
150         else
151         {
152             out << sl.start.dval << L" : " << sl.step.dval << L" : " << sl.end.dval;
153         }
154         return out;
155     }
156
157     inline static GVN::Value * evalDollar(GVN & gvn, const GVN::Value * value, const GVN::Value * dollar, const GVN::Value * dollarVal)
158     {
159         if (value->poly->contains(dollar->value))
160         {
161             const MultivariatePolynomial & mp = value->poly->eval(std::pair<unsigned long long, const MultivariatePolynomial *>(dollar->value, dollarVal->poly));
162             return gvn.getValue(mp);
163         }
164
165         return nullptr;
166     }
167 };
168
169 } // namespace analysis
170
171 #endif // __SYMBOLIC_LIST_HXX__