* Bug 15599 fixed: now degree of zero polynomial is -Inf
[scilab.git] / scilab / modules / ast / includes / types / internal.hxx
1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2008-2008 - DIGITEO - Antoine ELIAS
4 *  Copyright (C) 2010-2010 - DIGITEO - Bruno JOFRET
5 *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14 *
15 */
16
17
18 #ifndef __INTERNAL_HXX__
19 #define __INTERNAL_HXX__
20
21 #include <vector>
22 #include <unordered_map>
23 #include <iostream>
24 #include <algorithm>
25 #include <string>
26
27 extern "C"
28 {
29 #include "dynlib_ast.h"
30 #include "configvariable_interface.h"
31 }
32
33 #include "localization.hxx"
34 #ifndef NDEBUG
35 #include "inspector.hxx"
36 #endif
37
38 #define bsiz 4096
39
40 //#define _SCILAB_DEBUGREF_
41 #ifdef _SCILAB_DEBUGREF_
42 //#define _SCILAB_DEBUGREF_WITHOUT_START_END
43 #define DecreaseRef() _decreaseref(__FILE__, __LINE__)
44 #define IncreaseRef() _increaseref(__FILE__, __LINE__)
45 #define killMe() _killme(__FILE__, __LINE__)
46 #endif
47
48 #include "visitor.hxx"
49
50 class Location;
51
52 namespace types
53 {
54
55 /*
56 ** List of types
57 */
58 class InternalType;
59 typedef std::vector<InternalType *> typed_list;
60 typedef std::unordered_map<std::wstring, InternalType *> optional_list;
61
62 class EXTERN_AST InternalType
63 {
64 public :
65     enum ScilabType
66     {
67         ScilabNull = 0, //no type, no data, nothing !
68         /* Internal Type */
69         ScilabInternal,
70         /* Generic Types */
71         ScilabGeneric,
72         ScilabInt8,
73         ScilabUInt8,
74         ScilabInt16,
75         ScilabUInt16,
76         ScilabInt32,
77         ScilabUInt32,
78         ScilabInt64,
79         ScilabUInt64,
80         ScilabString,
81         ScilabDouble,
82         ScilabBool,
83         ScilabFloat,
84         ScilabPolynom,
85         ScilabSinglePolynom,
86         /* Callable */
87         ScilabFunction,
88         ScilabMacro,
89         ScilabMacroFile,
90         /* Implicit List */
91         ScilabImplicitList,
92         /* Container */
93         ScilabContainer,
94         ScilabList,
95         ScilabTList,
96         ScilabMList,
97         ScilabSingleStruct,
98         ScilabStruct,
99         ScilabCell,
100         /* User */
101         ScilabUserType,
102         /*For list operation*/
103         ScilabListOperation, //parent type
104         ScilabListInsertOperation,
105         ScilabListDeleteOperation,
106         ScilabListUndefinedOperation,
107         ScilabFile,
108         ScilabColon,
109         ScilabThreadId,
110         ScilabSparse,
111         ScilabSparseBool,
112         ScilabHandle,
113         ScilabVoid,
114         ScilabLibrary
115     };
116
117     enum ScilabId
118     {
119         IdNull, //no type, no data, nothing !
120         /* Internal Type */
121         IdInternal,
122         /* Generic Types */
123         IdGeneric,
124         IdEmpty,
125         IdIdentity,
126         IdIdentityComplex,
127         IdInt8,
128         IdScalarInt8,
129         IdUInt8,
130         IdScalarUInt8,
131         IdInt16,
132         IdScalarInt16,
133         IdUInt16,
134         IdScalarUInt16,
135         IdInt32,
136         IdScalarInt32,
137         IdUInt32,
138         IdScalarUInt32,
139         IdInt64,
140         IdScalarInt64,
141         IdUInt64,
142         IdScalarUInt64,
143         IdString,
144         IdScalarString,
145         IdDouble,
146         IdDoubleComplex,
147         IdScalarDouble,
148         IdScalarDoubleComplex,
149         IdBool,
150         IdScalarBool,
151         IdPolynom,
152         IdScalarPolynomComplex,
153         IdScalarPolynom,
154         IdPolynomComplex,
155         IdSinglePolynom,
156         /* Callable */
157         IdFunction,
158         IdMacro,
159         IdMacroFile,
160         /* Implicit List */
161         IdImplicitList,
162         /* Container */
163         IdContainer,
164         IdList,
165         IdTList,
166         IdMList,
167         IdSingleStruct,
168         IdStruct,
169         IdCell,
170         /* User */
171         IdUserType,
172         /*For list operation*/
173         IdListOperation, //parent type
174         IdListInsertOperation,
175         IdListDeleteOperation,
176         IdListUndefinedOperation,
177         IdFile,
178         IdColon,
179         IdThreadId,
180         IdSparse,
181         IdSparseComplex,
182         IdSparseBool,
183         IdHandle,
184         IdScalarHandle,
185         IdVoid,
186         IdLibrary,
187         IdLast //msut always be the last value
188     };
189
190 protected :
191     InternalType() : m_iRef(0), m_bAllowDelete(true), m_bPrintFromStart(true), m_iSavePrintState(0), m_iRows1PrintState(0), m_iCols1PrintState(0), m_iRows2PrintState(0), m_iCols2PrintState(0), bKillMe(false)
192     {
193 #ifdef _SCILAB_DEBUGREF_
194 #if defined(_SCILAB_DEBUGREF_WITHOUT_START_END)
195         if (getStartProcessing() == 0 && getEndProcessing() == 0)
196 #endif
197         {
198             std::cout << "new_IT " << m_iRef << " " << (void*)this << std::endl;
199         }
200 #endif
201     }
202
203 public :
204
205     virtual                         ~InternalType()
206     {
207 #ifdef _SCILAB_DEBUGREF_
208 #if defined(_SCILAB_DEBUGREF_WITHOUT_START_END)
209         if (getStartProcessing() == 0 && getEndProcessing() == 0 && bKillMe == false)
210 #endif
211         {
212             std::cout << "delete_IT " << m_iRef << " " << (void*)this << std::endl;
213         }
214 #endif
215     }
216
217     virtual void                    whoAmI(void);
218     virtual bool                    isAssignable(void);
219     virtual ScilabType              getType(void) = 0 ; //{ return ScilabInternal; }
220     virtual ScilabId                getId(void) = 0 ; //{ return ScilabInternal; }
221     virtual bool                    hasToString();
222     virtual bool                    toString(std::wostringstream& ostr) = 0;
223     virtual std::wstring            toStringInLine();
224     virtual InternalType*           clone(void) = 0;
225     virtual ast::Exp*               getExp(const Location& /*loc*/);
226
227     template <typename T, typename F, typename ... A>
228     T* checkRef(T* _pIT, F f, A ... a)
229     {
230         if (getRef() > 1)
231         {
232             // A types:: content in more than one Scilab variable
233             // must be cloned before being modified.
234             T* pClone = _pIT->clone()->template getAs<T>();
235             T* pIT = (pClone->*f)(a...);
236             if (pIT == NULL)
237             {
238                 pClone->killMe();
239             }
240
241             return pIT;
242         }
243
244         return _pIT;
245     }
246
247
248
249 #ifdef _SCILAB_DEBUGREF_
250     inline void _killme(const char * f, int l)
251     {
252 #if defined(_SCILAB_DEBUGREF_WITHOUT_START_END)
253         if (getStartProcessing() == 0 && getEndProcessing() == 0)
254 #endif
255         {
256             std::cout << "killme " << m_iRef << " " << (void*)this << " in " << f << " at line " << l << std::endl;
257         }
258
259         if (isDeletable())
260         {
261             bKillMe = true;
262             delete this;
263         }
264     }
265
266     inline void _increaseref(const char * f, int l)
267     {
268         m_iRef++;
269 #if defined(_SCILAB_DEBUGREF_WITHOUT_START_END)
270         if (getStartProcessing() == 0 && getEndProcessing() == 0)
271 #endif
272         {
273             std::cout << "incref " << m_iRef << " " << (void*)this << " in " << f << " at line " << l << std::endl;
274         }
275     }
276
277     inline void _decreaseref(const char * f, int l)
278     {
279         if (m_iRef > 0)
280         {
281             m_iRef--;
282         }
283
284 #if defined(_SCILAB_DEBUGREF_WITHOUT_START_END)
285         if (getStartProcessing() == 0 && getEndProcessing() == 0)
286 #endif
287         {
288             std::cout << "decref " << m_iRef << " " << (void*)this << " in " << f << " at line " << l << std::endl;
289         }
290     }
291 #else
292
293     inline void killMe()
294     {
295         if (isDeletable())
296         {
297             delete this;
298         }
299     }
300
301     inline void IncreaseRef()
302     {
303         m_iRef++;
304     }
305
306     inline void DecreaseRef()
307     {
308         if (m_iRef > 0)
309         {
310             m_iRef--;
311         }
312     }
313 #endif
314
315     inline bool isDeletable()
316     {
317         return m_iRef == 0;
318     }
319
320     inline bool isRef(int _iRef = 0)
321     {
322         return m_iRef > _iRef;
323     }
324
325     inline int getRef() const
326     {
327         return m_iRef;
328     }
329
330     virtual bool isTrue();
331     virtual bool neg(InternalType *& /*out*/);
332     virtual bool transpose(InternalType *& /*out*/);
333     virtual bool adjoint(InternalType *& out);
334     virtual bool isFieldExtractionOverloadable() const;
335     virtual bool invoke(typed_list & /*in*/, optional_list & /*opt*/, int /*_iRetCount*/, typed_list & /*out*/, const ast::Exp & /*e*/);
336     virtual bool isInvokable() const;
337     virtual bool hasInvokeOption() const;
338     virtual int getInvokeNbIn();
339     virtual int getInvokeNbOut();
340     /* return type as string ( double, int, cell, list, ... )*/
341     virtual std::wstring            getTypeStr() const = 0;
342     /* return type as short string ( s, i, ce, l, ... )*/
343     virtual std::wstring            getShortTypeStr() const = 0;
344     virtual bool                    operator==(const InternalType& it);
345     virtual bool                    operator!=(const InternalType& it);
346
347     /**
348     ** GenericType
349     ** \{
350     */
351
352     template <class T>
353     inline T*                              getAs(void)
354     {
355         return static_cast<T*>(this);
356     }
357
358     virtual bool isGenericType(void);
359     virtual bool isArrayOf(void);
360     virtual bool isString(void);
361     virtual bool isDouble(void);
362     virtual bool isSparse(void);
363     virtual bool isSparseBool(void);
364     virtual bool isFloat(void);
365     virtual bool isInt(void);
366     virtual bool isInt8(void);
367     virtual bool isUInt8(void);
368     virtual bool isInt16(void);
369     virtual bool isUInt16(void);
370     virtual bool isInt32(void);
371     virtual bool isUInt32(void);
372     virtual bool isInt64(void);
373     virtual bool isUInt64(void);
374     virtual bool isBool(void);
375     virtual bool isPoly(void);
376     virtual bool isSinglePoly(void);
377     virtual bool isCallable(void);
378     virtual bool isFunction(void);
379     virtual bool isMacro(void);
380     virtual bool isMacroFile(void);
381     virtual bool isContainer(void);
382     virtual bool isList(void);
383     virtual bool isStruct(void);
384     virtual bool isSingleStruct(void);
385     virtual bool isCell(void);
386     virtual bool isTList(void);
387     virtual bool isMList(void);
388     virtual bool isImplicitList(void);
389     virtual bool isColon(void);
390     virtual bool isDollar(void);
391     virtual bool isFile(void);
392     virtual bool isHandle(void);
393     virtual bool isSingleHandle(void);
394     virtual bool isThreadId(void);
395     virtual bool isListOperation(void);
396     virtual bool isListDelete(void);
397     virtual bool isListInsert(void);
398     virtual bool isListUndefined(void);
399     virtual bool isPointer(void);
400     virtual bool isLibrary(void);
401     virtual bool isUserType(void);
402
403     void clearPrintState();
404
405 protected :
406     int          m_iRef;
407     //use to know if we can delete this variables or if it's link to a scilab variable.
408     bool         m_bAllowDelete;
409
410     /*variables to manage print taking care of lines*/
411     bool m_bPrintFromStart;
412     int  m_iSavePrintState;
413     int  m_iRows1PrintState;
414     int  m_iCols1PrintState;
415     int  m_iRows2PrintState;
416     int  m_iCols2PrintState;
417
418     bool bKillMe;
419
420 };
421
422 }
423
424 #ifdef _SCILAB_DEBUGREF_
425 #undef _SCILAB_DEBUGREF_
426 #endif
427
428 #endif /* !__INTERNAL_HXX__ */