1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2007-2008 - DIGITEO - Bruno JOFRET
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 #ifndef AST_OPEXP_HXX
17 #define AST_OPEXP_HXX
18 
19 #include <assert.h>
20 #include "mathexp.hxx"
21 
22 namespace ast
23 {
24 
25 /** \brief Abstract an Operation Expression node.
26  **
27  ** \b Example: 77 * 27 */
28 class OpExp : public MathExp
29 {
30 public:
31     /** \brief Operator qualifier */
32     enum Oper
33     {
34         // Arithmetics.
35         /** \brief "+" */			plus,
36         /** \brief "-" */			minus,
37         /** \brief "*" */			times,
38         /** \brief "/" */			rdivide,
39         /** \brief "\" */			ldivide,
40         /** \brief "**" or "^" */		power,
41 
42         // Element Ways.
43         /** \brief ".*" */		dottimes,
44         /** \brief "./" */		dotrdivide,
45         /** \brief ".\" */		dotldivide,
46         /** \brief ".^" */		dotpower,
47 
48         // Kroneckers
49         /** \brief ".*." */		krontimes,
50         /** \brief "./." */		kronrdivide,
51         /** \brief ".\." */		kronldivide,
52 
53         // Control
54         // FIXME : What the hell is this ???
55         /** \brief "*." */		controltimes,
56         /** \brief "/." */		controlrdivide,
57         /** \brief "\." */		controlldivide,
58 
59         // Comparison.
60         /** \brief "==" */		eq,
61         /** \brief "<>" or "~=" */	ne,
62         /** \brief "<" */			lt,
63         /** \brief "<=" */		le,
64         /** \brief "<" */			gt,
65         /** \brief ">=" */		ge,
66 
67         // Logical operators
68         /** \brief "&" */		logicalAnd,
69         /** \brief "|" */		logicalOr,
70         /** \brief "&&" */	logicalShortCutAnd,
71         /** \brief "||" */	logicalShortCutOr,
72 
73         // Unary minus
74         /** \brief "-" */ unaryMinus,
75 
76         // Unary plus
77         /** \brief "+" */ unaryPlus,
78 
79         /** unknow operator*/ unknown
80     };
81 
82     /** \name Ctor & dtor.
83     ** \{ */
84 public:
85     /** \brief Construct an Operation Expression node.
86     ** \param location scanner position informations
87     ** \param left left expression of the operator
88     ** \param oper operator description
89     ** \param right right expression of the operator
90     **
91     ** \b Example: 77 * 27
92     ** \li "77" is the left expression
93     ** \li "*" is the operator
94     ** \li "27" is the right expression
95     */
OpExp(const Location & location,Exp & left,Oper oper,Exp & right)96     OpExp (const Location& location,
97            Exp& left, Oper oper, Exp& right)
98         : MathExp (location),
99           _oper (oper)
100     {
101         left.setParent(this);
102         right.setParent(this);
103         _exps.push_back(&left);
104         _exps.push_back(&right);
105     }
106 
107     /** \brief Destroy a Operation Expression node.
108     **
109     ** Delete left and right, see constructor. */
~OpExp()110     virtual ~OpExp ()
111     {
112     }
113     /** \} */
114 
clone()115     virtual OpExp* clone()
116     {
117         OpExp* cloned = new OpExp(getLocation(), *getLeft().clone(), getOper(), *getRight().clone());
118         cloned->setVerbose(isVerbose());
119         return cloned;
120     }
121 
122     /** \name Visitors entry point.
123     ** \{ */
124 public:
125     /** \brief Accept a const visitor \a v. */
accept(Visitor & v)126     virtual void accept (Visitor& v)
127     {
128         v.visit (*this);
129     }
130     /** \brief Accept a non-const visitor \a v. */
accept(ConstVisitor & v) const131     virtual void accept (ConstVisitor& v) const
132     {
133         v.visit (*this);
134     }
135     /** \} */
136 
137 
138     /** \name Setters. */
139 public :
setLeft(Exp & left)140     virtual void setLeft(Exp& left)
141     {
142         _exps[0] = &left;
143         left.setParent(this);
144     }
145 
setRight(Exp & right)146     virtual void setRight(Exp& right)
147     {
148         _exps[1] = &right;
149         right.setParent(this);
150     }
151     /** \} */
152 
153 
154     /** \name Accessors.
155     ** \{ */
156 public:
157     /** \brief Return the left expression of the operation (read only) */
getLeft() const158     const Exp& getLeft() const
159     {
160         return *_exps[0];
161     }
162     /** \brief Return the left expression of the operation (read and write) */
getLeft()163     Exp& getLeft()
164     {
165         return *_exps[0];
166     }
167 
168     /** \brief Return the operator description (read only) */
getOper() const169     Oper getOper() const
170     {
171         return _oper;
172     }
173 
174     /** \brief Return the right expression of the operation (read only) */
getRight() const175     const Exp& getRight() const
176     {
177         return *_exps[1];
178     }
179     /** \brief Return the right expression of the operation (read and write) */
getRight()180     Exp& getRight()
181     {
182         return *_exps[1];
183     }
184 
getType() const185     virtual ExpType getType() const
186     {
187         return OPEXP;
188     }
isOpExp() const189     inline bool isOpExp() const
190     {
191         return true;
192     }
193 
isBooleanOp() const194     inline bool isBooleanOp() const
195     {
196         return _oper == eq || _oper == ne || _oper == lt || _oper == le || _oper == gt || _oper == ge || _oper == logicalAnd || _oper == logicalOr || _oper == logicalShortCutAnd || _oper == logicalShortCutOr;
197     }
198 
getString() const199     inline std::wstring getString() const
200     {
201         switch (_oper)
202         {
203             case plus:
204                 return L"+";
205             case minus:
206                 return L"-";
207             case times:
208                 return L"*";
209             case rdivide:
210                 return L"/";
211             case ldivide:
212                 return L"\\";
213             case power:
214                 return L"^";
215             case dottimes:
216                 return L".*";
217             case dotrdivide:
218                 return L"./";
219             case dotldivide:
220                 return L".\\";
221             case dotpower:
222                 return L".^";
223             case krontimes:
224                 return L".*.";
225             case kronrdivide:
226                 return L"./.";
227             case kronldivide:
228                 return L".\\.";
229             case controltimes:
230                 return L"*.";
231             case controlrdivide:
232                 return L"/.";
233             case controlldivide:
234                 return L"\\.";
235             case eq:
236                 return L"==";
237             case ne:
238                 return L"~=";
239             case lt:
240                 return L"<";
241             case le:
242                 return L"<=";
243             case gt:
244                 return L">";
245             case ge:
246                 return L">=";
247             case logicalAnd:
248                 return L"&";
249             case logicalOr:
250                 return L"|";
251             case logicalShortCutAnd:
252                 return L"&&";
253             case logicalShortCutOr:
254                 return L"||";
255             case unaryMinus:
256                 return L"-";
257             case unaryPlus:
258                 return L"+";
259             case unknown:
260                 return L"unknown";
261             default:
262                 return L"unknown";
263         }
264     }
265 
266 
267 protected:
268     /** \brief Operator. */
269     Oper _oper;
270 };
271 
272 } // namespace ast
273 
274 #endif // !AST_OPEXP_HXX
275