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