* Bug 7657: lstsize() is set obsolete, replaced with size()
[scilab.git] / scilab / modules / m2sci / macros / kernel / sci_m2scideclare.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) ???? - INRIA - Scilab
3 // Copyright (C) 2002-2004 - INRIA - Vincent COUVERT
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 function []=sci_m2scideclare(def)
15     // This function translate calls to m2scideclare
16     // which can be used by the user to influence translation
17     // by adding a comment which begins by m2scideclare
18
19     // Global variable for M2SCI
20     global("varslist")
21
22     //variable_name|dimensions|datatype|property
23
24     //dimensions: variable dimensions separated by blanks (Unknown dimension is ?)
25
26     //datatype:
27     // - double: scalar/vector/matrix/hypermatrix containing double values
28     // - string: scalar/vector/matrix/hypermatrix containing character strings
29     // - boolean: scalar/vector/matrix/hypermatrix containing boolean values
30     // - int: scalar/vector/matrix/hypermatrix containing integer values
31     // - handle: matrix of graphics handles or graphics handle
32     // - sparse: sparse scalar/vector/matrix/hypermatrix
33     // - cell: cell array
34     // - struct: struct array
35     // - ? if unknown
36
37     //property:
38     // - real/complex/? for double and int datatype
39     // - real for string and boolean datatype (ignored if not)
40     // - NOT USED for struct/cell/handle datatype
41
42     // def is the comment added by the user
43     userdata=def.rhs(1).value
44     // Remove all multiple blanks
45     while strindex(userdata,"  ")<>[]
46         userdata=strsubst(userdat,"  "," ")
47     end
48
49     seppos=strindex(userdata,"|")
50
51     seppos=[seppos,length(userdata)+1]
52
53     nbsep=size(seppos,"*")
54
55     if nbsep<3 then
56         error(gettext("not enough data, you should give at least variable_name|dimensions|datatype."));
57     elseif nbsep>4 then
58         error(gettext("too much data."));
59     end
60
61     name=stripblanks(part(userdata,1:seppos(1)-1))
62
63     dimstxt=part(userdata,seppos(1)+1:seppos(2)-1)
64
65     datatypetxt=part(userdata,seppos(2)+1:seppos(3)-1)
66
67     if nbsep==4 then
68         proptxt=part(userdata,seppos(3)+1:seppos(4)-1)
69     else
70         proptxt="?"
71     end
72
73     // Dimensions
74     dimstxt=strsubst(dimstxt,"?","-1")
75     dimstxt=strsubst(dimstxt,"*","-2")
76     dimstxt=strsubst(dimstxt,"#","-3")
77     blpos=strindex(dimstxt," ")
78     nbblanks=size(blpos)
79     blpos=[1,blpos,length(dimstxt)+1]
80     fmt="%d"
81     dims=list()
82     for kbl=1:size(blpos,"*")-1
83         dims($+1)=evstr(part(dimstxt,blpos(kbl):blpos(kbl+1)))
84     end
85
86     // Datatype
87     datatypetxt=strsubst(datatypetxt,"?","Unknown")
88     datatype=convstr(datatypetxt,"l")
89     if or(datatype==["double","boolean","string","int","handle","sparse","cell","struct","unknown"]) then
90         datatype=convstr(part(datatype,1),"u")+convstr(part(datatype,2:length(datatype)),"l")
91         vtype=evstr(datatype)
92     else
93         error(msprintf(gettext("Unknown datatype %s."),datatypetxt));
94     end
95
96     // Property
97     proptxt=strsubst(proptxt,"?","Unknown")
98     prop=convstr(proptxt,"l")
99     if or(prop==["real","complex","homogen","unknown"]) then
100         prop=convstr(part(prop,1),"u")+part(prop,2:length(prop))
101         property=evstr(prop)
102     else
103         error(msprintf(gettext("Unknown property %s."),proptxt));
104     end
105     // Property correction
106     if or(vtype==[Boolean,String]) then
107         property=Real
108     end
109
110     if strindex(name,".")<>[] then // Cell or Struct m2scideclare
111         // Get varname
112         endofname=min([strindex(name,[".","("])])-1
113         varname=part(name,1:endofname)
114
115         // First field name (if is 'entries' then a cell else a struct)
116         firstpoint=min(strindex(name,"."))
117         secpoint=min(strindex(part(name,firstpoint+1:length(name)),"."))
118         par=min(strindex(part(name,firstpoint+1:length(name)),"("))
119         if isempty(secpoint) & isempty(par) then //x.fieldname
120             firstfield=part(name,firstpoint:length(name))
121         elseif isempty(secpoint) then //x.fieldname(p...)
122             firstfield=part(name,firstpoint:par-1)
123         elseif isempty(par) then //x.fieldname.fieldname2
124             firstfield=part(name,firstpoint:secpoint-1)
125         else //x.fieldname(p...).fieldname2
126             firstfield=part(name,firstpoint:min([secpoint par])-1)
127         end
128         if firstfield==".entries" then // Cell
129             vartype=Cell
130         else // Struct
131             vartype=Struct
132         end
133
134         // Indexes for varname ? myvar(1,2).field....
135         if or(strindex(name,"(")<strindex(name,".")) | (~isempty(strindex(name,"("))&isempty(strindex(name,"."))) then
136             ierr=execstr("vardims=list"+part(name,min(strindex(name,"(")):min(strindex(name,")"))),"errcatch")
137             if ierr then
138                 if ~isempty(strindex(part(name,min(strindex(name,"(")):min(strindex(name,")"))),"*")) then // Generic command *
139                     vardims="generic"
140                 else
141                     error(gettext("Wrong dimensions user data."));
142                 end
143             end
144         else
145             vardims=list(1,1)
146         end
147
148         [isvar,index]=isdefinedvar(Variable(varname,Infer()))
149
150         if ~isvar then // If variable does not exist it is added to varslist
151             if vardims=="generic" then
152                 vardims=list(Unknown,Unknown)
153             end
154             contents=Contents()
155             name=strsubst(name,"*","%genericm2sciindex")
156             deff("m2scitmp",name)
157             t=macr2tree(m2scitmp);
158             if isempty(firstpoint) then
159                 contents.index($+1)=t.statements(2).expression.rhs;
160             else
161                 contents.index($+1)=t.statements(2).expression.rhs(1);
162             end
163             clear m2scitmp
164             for k = 1:size(contents.index($))
165                 if typeof(contents.index($)(k))=="variable" & contents.index($)(k).name=="%genericm2sciindex" then
166                     contents.index($)(k)=Cste("*")
167                 elseif typeof(contents.index($)(k))=="cste" then
168                     contents.index($)(k)=Cste(contents.index($)(k).value)
169                 elseif typeof(contents.index($)(k))=="list" then
170                     for kk = 1:size(contents.index($)(k))
171                         if typeof(contents.index($)(k)(kk))=="variable" & contents.index($)(k)(kk).name=="%genericm2sciindex" then
172                             contents.index($)(k)(kk)=Cste("*")
173                         elseif typeof(contents.index($)(k)(kk))=="cste" then
174                             contents.index($)(k)(kk)=Cste(contents.index($)(k)(kk).value)
175                         end
176                     end
177                 end
178             end
179             contents.data($+1)=Infer(dims,Type(vtype,property))
180             varslist($+1)=M2scivar(varname,varname,Infer(vardims,Type(vartype,Unknown),contents))
181         else
182             if vardims=="generic" then
183                 vardims=varslist(index).dims
184             else
185                 vardims=dims
186             end
187
188             infereddims=varslist(index).dims
189
190             err=%F
191             for kd=1:min([size(vardims) size(infereddims)])
192                 if infereddims(kd)~=vardims(kd) & infereddims(kd)<>Unknown then
193                     err=%T
194                     break
195                 end
196             end
197
198             // Update dimensions
199             if err then
200                 set_infos(msprintf(gettext("Dimensions current value and m2scideclare statements conflict for: %s\n   m2scideclare given dimension: %s\n   Current dimension: %s\n   m2scideclare IGNORED"),varname,dims2str(vardims),dims2str(infereddims)),2)
201             else
202                 varslist(index)=M2scivar(varslist(index).matname,varslist(index).matname,Infer(vardims,Type(varslist(index).type.vtype,property)))
203             end
204
205             // Update vtype
206             if varslist(index).type.vtype==Unknown then
207                 varslist(index)=M2scivar(varslist(index).matname,varslist(index).matname,Infer(vardims,Type(vartype,varslist(index).property)))
208             elseif varslist(index).type.vtype~=vartype then
209                 set_infos(msprintf(gettext("Type current value and m2scideclare statements conflict for: %s\n   m2scideclare given type: %s\n   current type: %s\n   m2scideclare IGNORED"),varname,tp2str(vartype),tp2str(varslist(index).type.vtype)),2)
210             end
211
212             // Update property
213             if varslist(index).property==Unknown then
214                 varslist(index).infer.type.property=property
215             elseif property==Unknown then
216                 varslist(index).type.property=Unknown
217             elseif varslist(index).type.property~=property then
218                 set_infos(msprintf(gettext("Property current value and m2scideclare statements conflict for: %s\n   m2scideclare given type: %s\n   current type: %s\n   m2scideclare IGNORED"),name,prop2str(Unknown),prop2str(varslist(index).type.property)),2)
219             end
220
221             // Update contents (no verification made...too complex)
222             contents=varslist(index).contents
223             name=strsubst(name,"*","%genericm2sciindex")
224             deff("m2scitmp",name)
225             t=macr2tree(m2scitmp);
226             if isempty(firstpoint) then
227                 contents.index($+1)=t.statements(2).expression.rhs;
228             else
229                 contents.index($+1)=t.statements(2).expression.rhs(1);
230             end
231             clear m2scitmp
232             for k=1:size(contents.index($))
233                 if typeof(contents.index($)(k))=="variable" & contents.index($)(k).name=="%genericm2sciindex" then
234                     contents.index($)(k)=Cste("*")
235                 elseif typeof(contents.index($)(k))=="cste" then
236                     contents.index($)(k)=Cste(contents.index($)(k).value)
237                 elseif typeof(contents.index($)(k))=="list" then
238                     for kk=1:size(contents.index($)(k))
239                         if typeof(contents.index($)(k)(kk))=="variable" & contents.index($)(k)(kk).name=="%genericm2sciindex" then
240                             contents.index($)(k)(kk)=Cste("*")
241                         elseif typeof(contents.index($)(k)(kk))=="cste" then
242                             contents.index($)(k)(kk)=Cste(contents.index($)(k)(kk).value)
243                         end
244                     end
245                 end
246             end
247             contents.data($+1)=Infer(dims,Type(vtype,property))
248             varslist(index)=M2scivar(varname,varname,Infer(vardims,Type(vartype,Unknown),contents))
249
250         end
251     else // Variable m2scideclare
252
253         // Special part for %graphicswindow
254         if name=="%graphicswindow" then
255             global %graphicswindow
256             if and(vtype<>[Handle,Double]) then
257                 set_infos(gettext("%graphicswindow set to default value Handle."),2);
258             else
259                 %graphicswindow=vtype
260             end
261             return
262         end
263
264         [isvar,index]=isdefinedvar(Variable(name,Infer()))
265
266         if ~isvar then // If variable does not exist it is added to varslist
267             varslist($+1)=M2scivar(name,name,Infer(dims,Type(vtype,property)))
268         else // Try to compare with already infered data
269             // Update dims
270             infereddims=varslist(index).dims
271
272             err=%F
273             for kd=1:min([size(dims) size(infereddims)])
274                 if infereddims(kd)~=dims(kd) & infereddims(kd)<>Unknown then
275                     err=%T
276                     break
277                 end
278             end
279
280             if err then
281                 set_infos(msprintf(gettext("Dimensions current value and m2scideclare statements conflict for: %s\n   m2scideclare given dimension: %s\n   Current dimension: %s\n   m2scideclare IGNORED"),name,dims2str(dims),dims2str(infereddims)),2)
282             else
283                 varslist(index)=M2scivar(varslist(index).matname,varslist(index).sciname,Infer(dims,varslist(index).type))
284             end
285
286             // Update vtype
287             if varslist(index).type.vtype==Unknown then
288                 varslist(index)=M2scivar(varslist(index).matname,varslist(index).sciname,Infer(varslist(index).dims,Type(vtype,varslist(index).type.property)))
289             elseif varslist(index).type.vtype~=vtype then
290                 set_infos(msprintf(gettext("Type current value and m2scideclare statements conflict for: %s\n   m2scideclare given type: %s\n   current type: %s\n   m2scideclare IGNORED"),name,tp2str(vtype),tp2str(varslist(index).type.vtype)),2)
291             end
292
293             // Update property
294             if varslist(index).type.property==Unknown then
295                 varslist(index)=M2scivar(varslist(index).matname,varslist(index).sciname,Infer(varslist(index).dims,Type(varslist(index).type.vtype,property)))
296             elseif varslist(index).type.property~=property then
297                 set_infos(msprintf(gettext("Property current value and m2scideclare statements conflict for: %s\n   m2scideclare given type: %s\n   current type: %s\n   m2scideclare IGNORED"),name,prop2str(property),prop2str(varslist(index).type.property)),2)
298             end
299         end
300     end
301 endfunction
302
303
304 function str=tp2str(tp)
305     // Returns equivalent of typeof() from data coming from type()
306
307     if tp==1 then
308         str="Double"
309     elseif tp==4 then
310         str="Boolean"
311     elseif tp==6 then
312         str="Sparse"
313     elseif tp==8 then
314         str="Int"
315     elseif tp==9 then
316         str="Handle"
317     elseif tp==10 then
318         str="String"
319     elseif tp==16 then
320         str="Struct"
321     elseif tp==17 then
322         str="Cell"
323     elseif tp==-1 then
324         str="Unknown"
325     else
326         error(msprintf(gettext("type %d is not implemented."),tp))
327     end
328 endfunction
329
330 function str=prop2str(prop)
331     if type(prop)==10 then
332         str=prop
333     elseif prop==-1 then
334         str="Unknown"
335     else
336         error(msprintf(gettext("type %d is not implemented."),prop))
337     end
338 endfunction
339
340 function str=dims2str(dims)
341     str=""
342     for kd=1:size(dims)
343         str=str+string(dims(kd))+" "
344     end
345 endfunction