CeCILL license headers
[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-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