Also update the URL to the CeCILL license. Thanks to Paul for noticing that
[scilab.git] / scilab / modules / m2sci / macros / kernel / updatevarslist.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) 2002-2004 - INRIA - Vincent COUVERT
3 //
4 // This file must be used under the terms of the CeCILL.
5 // This source file is licensed as described in the file COPYING, which
6 // you should have received as part of this distribution.  The terms
7 // are also available at
8 // http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
9
10 function []=updatevarslist(instr_lhs)
11     // (2 functions in this file: merge_vars() at the end)
12     // Update list of M2SCI variables with converted instruction lhs
13     // Input:
14     // - instr_lhs: list of lhs of current instruction
15     // - in_a_clause: boolean value
16     //   Set to 1 if instruction is in a clause
17     //   In this case, type and dimensions are set to unknown if differ from those already stored in varslist
18     //   (Default value is %F)
19
20     // Global variable for M2SCI
21     global("varslist")
22     // level is declared in m2sci.sci and modified in clause2sci.sci
23     level;
24
25     rhs=argn(2)
26     if rhs==2 then
27         in_a_clause=%F
28     end
29
30     // Merge infered data from the last two parts of clause which are above the current part
31     // if we are in the third part of clause (current), then : merge the first and second part of clause
32     // when end of conversion of a clause : merge infered data from the last two parts of clause
33     levelsize=size(level,1)
34     changepartclause=%F
35     for i=size(varslist):-1:1
36         if size(varslist(i).level,1)==levelsize then
37             varlevel=varslist(i).level
38             if varlevel($)<>level($)
39                 changepartclause=%T
40             else
41                 changepartclause=%F
42                 break
43             end
44         end
45     end
46     if changepartclause | instr_lhs=="END OF CLAUSE" then
47         index=[] // Search variables from two part above current part clause
48         for k=size(varslist):-1:1
49             if size(varslist(k).level,1)==levelsize then
50                 varlevel=varslist(k).level
51                 if and(varlevel(1:$-1)==level(1:$-1)) & varlevel($)==level($)-2 then
52                     index=[index;k]
53                 end
54             end
55         end
56         if index<>[] then  // Found variables from the second part above current part of a clause
57             for k=1:size(index,1)
58                 boolmerge =%F
59                 for i=size(varslist):-1:1 // Search variables from the first part above current part of a clause, and which have the same name than variables from the second part above current part of a clause
60                     varlevel=varslist(i).level
61                     if varslist(i).matname==varslist(index(k)).matname & and(varlevel(1:$-1)==level(1:$-1)) &  varlevel($)==level($)-1 then
62                         boolmerge =%T // Found the same variable name from the last two parts above the current part : Merge
63                         merge_vars(index(k),varslist(i))
64                         varslist(i)=null()
65                         break
66                     end
67                 end
68                 if ~boolmerge then
69                     varslist(index(k)).level=[level(1:$-1);level($)-1]
70                 end
71             end
72         end
73     end
74
75     // Special case when end of conversion of a clause
76     // Merge infered data from clause and those from level-1
77     if instr_lhs=="END OF CLAUSE" then // Search variables in the last part of a clause (above end of conversion of a clause)
78         index=[] //
79         for k=size(varslist):-1:1 // Search variables from level-1 which have the same name than variables from the last part of current level
80             varlevel=varslist(k).level
81             if varlevel==[level(1:$-1);level($)-1] then
82                 index=[index;k]
83             end
84         end
85         if index<>[] then
86             for j=1:size(index,1)
87                 boolmerge=%F
88                 for k=size(varslist):-1:1 //
89                     varlevel=varslist(k).level
90                     if varslist(k).matname==varslist(index(j)).matname  & and(varlevel==level(1:$-1)) then
91                         boolmerge=%T // Found variables from level-1 which have the same name than variables from the last part of current level : Merge
92                         index_lower_level=k
93                         merge_vars(index_lower_level,varslist(index(j)))
94                         varslist(k).level=level(1:$-1)
95                         varslist(index(j))=null()
96                         break
97                     end
98                 end
99                 if boolmerge==%F then
100                     varslist(index(j)).level=level(1:$-1)
101                 end
102             end
103         end
104         return
105     end
106
107     // Expression: lhs name is empty => nothing to do
108     if instr_lhs==list() then
109         return
110     end
111
112     // Remove lhs which are not variables
113     k=1
114     while k<=size(instr_lhs)
115         // Insertion operation
116         if typeof(instr_lhs(k))=="operation" then
117             instr_lhs(k)=null()
118         else
119             k=k+1
120         end
121     end
122
123     if size(instr_lhs)==0 then
124         return
125     end
126
127     // Update varslist
128     for k=1:size(instr_lhs)
129         [bval,index]=isdefinedvar(instr_lhs(k))
130         ierr=execstr("zz=instr_lhs(k).contents.index","errcatch")
131         if ierr<>0 then pause;end
132         // Remove multiple entries from contents
133         for kcont=lstsize(instr_lhs(k).contents.index):-1:1
134             [infertlist,pos]=get_contents_infer(instr_lhs(k),instr_lhs(k).contents.index(kcont))
135             if pos<>0 & pos<>kcont then
136                 instr_lhs(k).contents.index(pos)=null()
137                 instr_lhs(k).contents.data(pos)=null()
138             end
139         end
140         // If variable exists for the current level in the same part of clause then update exixting variable
141         if bval
142             boolupdate=%F
143             for l=1:size(varslist)
144                 if varslist(l).matname==instr_lhs(k).name & varslist(l).level==level then
145                     varslist(l)=M2scivar(varslist(l).sciname,..
146                     varslist(l).matname,..
147                     Infer(instr_lhs(k).infer.dims,instr_lhs(k).infer.type,instr_lhs(k).infer.contents),..
148                     varslist(l).level)
149                     boolupdate=%T
150                     break
151                 end
152             end
153             // If variable exists, but not for the current level or not in the same part of clause then Update variable then create new variable
154             if ~boolupdate then
155                 varslist($+1)=M2scivar(varslist(index).sciname,..
156                 varslist(index).matname,..
157                 instr_lhs(k).infer,..
158                 level)
159             end
160         else
161             // Variable added to varslist if as a name (not done for expressions
162             if execstr("f=instr_lhs(k).name","errcatch")<>0 then pause;end;errclear();
163             if instr_lhs(k).name<>"ans" then
164                 varslist($+1)=M2scivar(instr_lhs(k).name,..
165                 instr_lhs(k).name,..
166                 instr_lhs(k).infer,..
167                 level)
168             end
169         end
170     end
171 endfunction
172
173 function []=merge_vars(oldvarindex,newvar)
174     // M2SCI function
175     // Merge two variables inference properties, if different then set to Unknown
176     // Input:
177     // - oldvarindex: index of old variable in varslist
178     // - newvar: new variable to take in account to update oldvar properties
179
180     // Global variable for M2SCI
181     global("varslist")
182     oldvar=varslist(oldvarindex)
183
184     olddims=oldvar.dims
185     oldvtype=oldvar.vtype
186     oldprop=oldvar.property
187
188     newdims=newvar.dims
189     newvtype=newvar.vtype
190     newprop=newvar.property
191
192     // Verify dims
193     for l=1:min(size(newdims),size(olddims))
194         if newdims(l)<>olddims(l) then
195             newdims(l)=Unknown
196         end
197     end
198     if size(newdims)>size(olddims) then
199         for l=size(olddims):size(newdims)
200             newdims(l)=null()
201         end
202     end
203
204     // Verify vtype
205     if newvtype<>oldvtype then
206         newvtype=Unknown
207     end
208
209     // Verify property
210     if newprop<>oldprop then
211         newprop=Unknown
212     end
213
214     // Verify contents
215     for k=1:lstsize(newvar.contents.index)
216         olddata=get_contents_infer(oldvar,newvar.contents.index(k))
217         newdata=newvar.contents.data(k)
218
219         if or(olddata<>newdata) then
220             newvar.infer.contents.data(k)=Infer()
221         end
222     end
223
224     // Write result in varslist
225     varslist(oldvarindex)=M2scivar(oldvar.sciname,..
226     oldvar.matname,..
227     Infer(newdims,Type(newvtype,newprop),newvar.contents),..
228     newvar.level)
229 endfunction