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