* Bug 14606 fixed: now `[names,mem]=who()` returns memory used by variables
[scilab.git] / scilab / modules / ast / includes / types / user.hxx
1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2010-2010 - DIGITEO - Bruno JOFRET
4 *  Copyright (C) 2014 - Scilab Enterprises - Cedric Delamarre
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 #ifndef __USER_HXX__
18 #define __USER_HXX__
19
20 #include "types.hxx"
21 #include "bool.hxx"
22
23 namespace types
24 {
25 class EXTERN_AST UserType : public GenericType
26 {
27 public :
28     UserType() {}
29     virtual ~UserType() {}
30
31     /*** non virtual function to prevent overriding in user derived class ***/
32
33     inline ScilabType       getType(void)
34     {
35         return ScilabUserType;
36     }
37
38     inline ScilabId         getId(void)
39     {
40         return IdUserType;
41     }
42
43     bool                    isUserType(void)
44     {
45         return true;
46     }
47
48     inline bool             isGenericType()
49     {
50         return false;
51     }
52
53 public :
54     /*** User will be asked to implement the following methods      ***/
55     /*** in order Scilab engine to manage correctly this user type  ***/
56
57     virtual std::wstring    getTypeStr() const = 0;
58     virtual std::wstring    getShortTypeStr() const = 0;
59     virtual UserType*       clone() = 0;
60
61 public :
62     /*** User can overload these methods                            ***/
63     /*** all methods not overloaded will call scilab overload       ***/
64
65     virtual bool operator==(const InternalType& /*it*/) override
66     {
67         return false;
68     }
69
70     virtual Bool* equal(UserType*& /*ut*/)
71     {
72         return NULL;
73     }
74
75     // hasToString return false so scilab will call overload %..._p
76     // and toString method is useless
77     // if user overload hasToString for return true, he must overload toString method
78     // bool toString(std::wostringstream& ostr)
79     virtual bool hasToString()
80     {
81         return false;
82     }
83
84     // overload this method if hasToString method return true
85     virtual bool toString(std::wostringstream& /*ostr*/)
86     {
87         return false;
88     }
89
90     // insertion by value
91     // _pArs is a list of scilab types:: of where we want to extract
92     // _pSource is what we wan to insert
93     virtual UserType* insert(typed_list* /*_pArgs*/, InternalType* /*_pSource*/)
94     {
95         return NULL;
96     }
97
98     // this method is called to perform an extraction by field. ie : a = myUserType.myfield
99     // name is the field name
100     // out contain extraction of field
101     virtual bool extract(const std::wstring& /*name*/, InternalType *& /*out*/)
102     {
103         return false;
104     }
105
106     // extraction by value, this method can be only called by "invoke" method below.
107     // _pArs is a list of scilab types:: of where we want to extract
108     // return all element extracted, in case when multiple elements returned
109     // these elements must be stored in a types::List
110     virtual InternalType* extract(typed_list* /*_pArgs*/)
111     {
112         return NULL;
113     }
114
115     // if return false , Scilab will never call "invoke" method
116     virtual bool isInvokable() const
117     {
118         return true;
119     }
120
121     // hasInvokeOption must return true to call the user type with optional argument.
122     // ie : myUserType(a,b, opt=value, opt2=value2,...)
123     // in this case, "types::optional_list& opt" will contain opt and opt2.
124     // by default this method return false, the optional list is empty and the input list contains all arguments.
125     virtual bool hasInvokeOption() const
126     {
127         return false;
128     }
129
130     // invoke method is called when a UserType is called with "(...)" ie : a = myUserType(...)
131     // This implementation allow the use of extract method above, but it can be overloaded.
132     // Inputs :
133     //  in          : contain input arguments myUserType(arg1,arg2,...)
134     //  opt         : contain optional input arguments myUserType(arg1=..., arg2=..., ...)
135     //  _iRetCount  : is the number of output arguments (ie : [a,b] = myUserType(...), _iRetCount = 2)
136     //  out         : after "invoke" execution, will contain results
137     //  execFunc    : is used in case of macro call : Overload::call(L"A_Macro", in, _iRetCount, out, execFunc);
138     //  e           : Generally used to return the Location when thowing an error. ie : throw ast::InternalError(L"error message", 999, e.getLocation());
139     // Outputs :
140     // if false, Scilab will call the macro %UserType_e,where UserType is the string return by the method getShortTypeStr()
141     // if true, Scilab will set each elements of out in Scilab variables
142     virtual bool invoke(types::typed_list & in, types::optional_list & /*opt*/, int /*_iRetCount*/, types::typed_list & out, const ast::Exp & /*e*/) override
143     {
144         InternalType* pIT = extract(&in);
145         if (pIT)
146         {
147             out.push_back(pIT);
148             return true;
149         }
150
151         return false;
152     }
153
154     // used to compute the iterator in scilab loop "for"
155     // when type is a two dimensions array
156     // _iPos is the column position
157     virtual GenericType*  getColumnValues(int /*_iPos*/)
158     {
159         return NULL;
160     }
161
162     //called by save to export your usertype as basic scilab type
163     //if you do not want to overload this function, save will call %yourtype_save overload function
164     virtual InternalType* save()
165     {
166         return nullptr;
167     }
168
169     //load must be done by overload %yourtype_load and must returns a pointer on your UserType
170
171     bool getMemory(int* _piSize, int* _piSizePlusType)
172     {
173         *_piSize = sizeof(UserType);
174         *_piSizePlusType = *_piSize;
175         return true;
176     }
177 };
178 }
179
180 #endif /* !__USER_HXX__ */