560abcb19d5f26730128e52015bcd28e1da45a00
[scilab.git] / scilab / modules / m2sci / macros / percent / %i_ce2sci.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) 2002-2004 - INRIA - Vincent COUVERT
3 //
4 // Copyright (C) 2012 - 2016 - Scilab Enterprises
5 //
6 // This file is hereby licensed under the terms of the GNU GPL v2.0,
7 // pursuant to article 5.3.4 of the CeCILL v.2.1.
8 // This file was originally licensed under the terms of the CeCILL v2.1,
9 // and continues to be available under such terms.
10 // For more information, see the COPYING file which you should have received
11 // along with this program.
12
13 function [tree]=%i_ce2sci(tree)
14     // M2SCI function
15     // Conversion function for Matlab insertion in cells
16     // Input: tree = Matlab operation tree
17     // Output: tree = Scilab equivalent for tree
18
19     from=tree.operands($)
20     to=tree.operands(1)
21     // Verify that to is not a struct (cell of struct)
22     inds=tree.operands;inds(1)=null();inds($)=null()
23     if type(inds)<>15 then
24         inds=list(inds)
25     end
26     for kinds=1:lstsize(inds)
27         if typeof(inds(kinds))<>"list" & inds(kinds).vtype==String & typeof(inds(kinds))=="cste" & inds(kinds).value<>":" then
28             tree=%i_st2sci(tree)
29             return
30         end
31     end
32
33     if to.vtype<>Struct then
34         if and(to.vtype<>[Cell,Unknown]) then
35             if to.vtype==Double & and(to.dims==list(0,0)) then
36                 m2sci_insert(Equal(list(to),Funcall("cell",1,list(),list(to))))
37                 // To be sure that variable will now be of type Cell
38                 [bval,index]=isdefinedvar(to)
39                 varslist(index).infer.type.vtype=Cell
40             else
41                 error(msprintf(gettext("destination variable is not a cell: %s is of type %s."),to.name,string(to.vtype)))
42             end
43         elseif to.vtype==Unknown then
44             m2sci_insert(Equal(list(to),Funcall("cell",1,list(),list(to))))
45             // To be sure that variable will now be of type Cell
46             [bval,index]=isdefinedvar(to)
47             varslist(index).infer.type.vtype=Cell
48         end
49     end
50     // Just one index value
51     if rhs==1 then
52         ind=tree.operands(2)
53         if type(ind)<>15 then // One value index A(xx)={...}
54             tree.operands(2)=list(Cste(1),ind)
55             tree.out(1).vtype=Cell
56             if typeof(ind)=="cste" then
57                 if ind.vtype<>String then // Not :
58                     tree.out(1).dims=list(1,ind.value)
59
60                     // Data added so that extraction of a cell element can also be infered
61                     tree.out(1).contents.index($+1)=tree.operands(2)
62                     tree.out(1).contents.data($+1)=Infer(list(1,1),Type(Cell,Unknown),from.contents)
63
64                     if lstsize(from.contents.data)==1 then
65                         tree.out(1).contents.index($+1)=list(tree.operands(2),Cste("entries"))
66                         tree.out(1).contents.data($+1)=from.contents.data(1)
67                     else
68                         error(gettext("Not yet implemented."))
69                     end
70                 else
71                     tree.out(1).infer=from.infer
72                 end
73             else
74                 tree.out(1).dims=list(1,Unknown)
75             end
76         else // --- Insertion with more than one index value (index is a list) ---
77             // Cell array of struct A{p,q,...}.name... or recursive index A{p,q,...}(1,2)...
78             for kind=1:lstsize(tree.operands(2))
79                 if typeof(tree.operands(2)(kind))=="cste" then
80                     if tree.operands(2)(kind).vtype<>String then
81                         tree.operands(2)(kind)=list(Cste(1),tree.operands(2)(kind))
82                     end
83                 end
84             end
85             IND=tree.operands(2)(1)
86             // Update cell dims for inference
87             if typeof(IND)=="list" then
88                 if lstsize(IND)>lstsize(tree.out(1).dims) then
89                     for kd=lstsize(tree.out(1).dims):lstsize(IND)
90                         tree.out(1).dims(kd)=Unknown
91                     end
92                 end
93                 for kd=1:lstsize(tree.out(1).dims)
94                     if typeof(IND(kd))=="cste" & tree.out(1).dims(kd)<>Unknown & tree.out(1).dims(kd)<IND(kd).value then
95                         tree.out(1).dims(kd)=IND(kd).value
96                     end
97                 end
98             else
99                 tree.out(1).dims=list(1,1)
100             end
101             tree.out(1).type=Type(Cell,Unknown)
102
103             ind=tree.operands(2)
104             if typeof(ind($))=="list" | ind($).vtype~=String then // X.p(m,n)=y
105                 tmp=gettempvar()
106                 oplist=list()
107
108                 tmpind=ind
109                 tmpind($)=null()
110                 if or(get_contents_infer(tree.operands(1),tmpind)<>Infer()) then
111                     tmp.infer=get_contents_infer(tree.operands(1),tmpind)
112                 end
113                 oplist(1)=tmp
114
115                 for kind=1:size(ind($))
116                     oplist($+1)=ind($)(kind)
117                 end
118
119                 oplist($+1)=tree.operands($)
120
121                 newop=Operation("ins",oplist,list(tmp))
122                 newop=%i2sci(newop)
123                 tree.out(1).infer.contents.index($+1)=tmpind
124                 tree.out(1).infer.contents.data($+1)=newop.out(1).infer
125             elseif ind($).vtype==String then
126                 tree.out(1).type=Type(Struct,Unknown)
127             end
128
129             // Update cell contents
130             infertree=tree.operands(2)
131             tree.out(1).contents.index($+1)=infertree
132             tree.out(1).contents.data($+1)=from.infer
133         end
134         // Two indexes: to(ind1,ind2,...)=from or more
135     else
136         tree.out(1).dims=list()
137         for k=1:lstsize(tree.operands)-2
138             tree.out(1).dims(k)=Unknown
139         end
140
141         // dim can be infered when index is a constant and when index value is greater than older dim and this dim is not unknown
142         for kdim=1:size(tree.operands)-2
143             if typeof(tree.operands(kdim+1))=="cste" then
144                 if to.dims(kdim)<>Unknown then
145                     if to.dims(kdim)<=tree.operands(kdim+1).value then
146                         tree.out(1).dims(kdim)=tree.operands(kdim+1).value;
147                     else
148                         tree.out(1).dims(kdim)=to.dims(kdim)
149                     end
150                 end
151             end
152         end
153         tree.out(1).type=from.type
154
155         // Update contents...
156         infertree=tree.operands
157         infertree(1)=null()
158         infertree($)=null()
159
160         // Data added so that extraction of a cell element can also be infered
161         tree.out(1).contents.index($+1)=infertree
162         tree.out(1).contents.data($+1)=Infer(list(1,1),Type(Cell,Unknown),Contents())
163
164         infertree=list(infertree,Cste("entries"))
165         if lstsize(from.contents.index)==1 then
166             tree.out(1).contents.index($+1)=infertree
167             tree.out(1).contents.data($+1)=from.contents.data(1);
168         elseif lstsize(from.contents.index)==0 then
169             tree.out(1).contents=Contents()
170         else
171             error(gettext("Not yet implemented."))
172         end
173     end
174 endfunction
175