summaryrefslogtreecommitdiff
path: root/modules/m2sci/macros/percent/%i_st2sci.sci
blob: 9ce57cac7a6a0e26037225a81277f1a671631d4f (plain)
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
// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
// Copyright (C) 2002-2004 - INRIA - Vincent COUVERT
//
// This file must be used under the terms of the CeCILL.
// This source file is licensed as described in the file COPYING, which
// you should have received as part of this distribution.  The terms
// are also available at
// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt

function [tree]=%i_st2sci(tree)
    // M2SCI function
    // Conversion function for Matlab insertion in structs
    // Input: tree = Matlab operation tree
    // Output: tree = Scilab equivalent for tree
    // Emulation functions: mtlb_i() and mtlb_is()

    // Global variable for M2SCI
    global("varslist")

    from=tree.operands($)
    to=tree.operands(1)

    // Insertion of a struct in a not-struct array
    if typeof(to)=="variable" & to.vtype<>Struct then
        // To be sure that variable will now be of type Struct
        [bval,index]=isdefinedvar(to)
        varslist(index).infer.type.vtype=Struct
        varslist(index).infer.contents=Contents()
        tree.out(1).infer=Infer(list(0,0),Type(Struct,Unknown),Contents())
    elseif typeof(to)=="operation" & to.vtype<>Struct then
        // To be sure that variable will now be of type Struct
        [bval,index]=isdefinedvar(to.operands(1))
        varslist(index).infer.type.vtype=Struct
        varslist(index).infer.contents=Contents()
        tree.out(1).infer=Infer(list(0,0),Type(Struct,Unknown),Contents())
    end

    // Just one index value
    if rhs==1 then
        ind=tree.operands(2)
        // --- Insertion with just one index ---
        if type(ind)<>15 then
            // --- Insertion in a struct with just one index ---
            if ind.vtype==String then // A.f
                tree.out(1).dims=list(1,1);
                tree.out(1).vtype=Struct
                tree.out(1).contents.index($+1)=list(list(Cste(1),Cste(1)),ind)
                tree.out(1).contents.data($+1)=from.infer
            else
                if from.vtype<>Double then // X(p)=struct(...)
                    tree.operands(2)=list(Cste(1),tree.operands(2))
                    tree.out(1).vtype=Struct
                    if typeof(ind)=="cste" then
                        if ind.vtype<>String then // Not :
                            tree.out(1).dims=list(1,ind.value)

                            tree.out(1).contents.index($+1)=list(Cste(1),ind)

                            // Update contents for an extraction of type: z = X(p)
                            CONT=Contents()
                            for k=1:lstsize(from.infer.contents.index)
                                if type(from.contents.index(k)(1))==15 then
                                    CONT.index($+1)=list(from.contents.index(k)(2))
                                else
                                    CONT.index($+1)=list(from.contents.index(k))
                                end
                                CONT.data($+1)=from.contents.data(k)
                            end
                            tree.out(1).contents.data($+1)=Infer(list(1,1),Type(Struct,Unknown),CONT)

                            // Update contents for extraction of type: z = X(p).f
                            for k=1:lstsize(from.infer.contents.index)
                                if type(from.contents.index(k)(1))==15 then
                                    tree.out(1).contents.index($+1)=list(list(Cste(1),ind),from.contents.index(k)(2))
                                else
                                    tree.out(1).contents.index($+1)=list(list(Cste(1),ind),from.contents.index(k))
                                end
                                tree.out(1).contents.data($+1)=from.contents.data(k)
                            end
                        else
                            tree.out(1).dims=from.dims
                            tree.out(1).contents=from.contents
                        end
                    end
                else
                    if is_empty(from) then // Clear element: A(p)=[]
                        // Nothing done
                    else // Change type of variable
                        error(gettext("Not yet implemented."))
                    end
                end
            end
            // --- Insertion with more than one index value (index is a recursive index list) ---
        else

            // Change index value if just one double
            for k=1:lstsize(ind)
                //ind(k+1) <-> tree.operands(2)(k+1)
                if typeof(ind(k))=="cste" | (typeof(ind(k))<>"list" & is_a_scalar(ind(k))) then
                    if ind(k).vtype<>String then
                        tree.operands(2)(k)=list(Cste(1),tree.operands(2)(k))
                    end
                end
            end
            ind=tree.operands(2);

            if typeof(ind($))=="list" | ind($).vtype~=String then // X.p(m,n)=y
                tmp=gettempvar()
                oplist=list()

                tmpind=ind
                tmpind($)=null()
                if or(get_contents_infer(tree.operands(1),tmpind)<>Infer()) then
                    tmp.infer=get_contents_infer(tree.operands(1),tmpind)
                end
                oplist(1)=tmp

                for kind=1:size(ind($))
                    oplist($+1)=ind($)(kind)
                end

                oplist($+1)=tree.operands($)

                newop=Operation("ins",oplist,list(tmp))
                newop=%i2sci(newop)
                tree.out(1).infer.contents.index($+1)=tmpind
                tree.out(1).infer.contents.data($+1)=newop.out(1).infer
            end

            infertree=tree.operands(2)

            // A(x,y,...).f
            if typeof(infertree(1))=="list" then
                possible_dims=infertree(1)
                infdims=tree.out(1).dims
                if lstsize(infdims)<lstsize(possible_dims) then
                    for k=lstsize(infdims)+1:lstsize(possible_dims)
                        infdims(k)=Unknown
                    end
                end
                for k=1:lstsize(possible_dims)
                    if typeof(possible_dims(k))<>"cste" then
                        infdims(k)=Unknown
                    elseif infdims(k)<>Unknown & infdims(k)<possible_dims(k).value then
                        infdims(k)=possible_dims(k).value
                    end
                end
                tree.out(1).infer.contents.index($+1)=ind
                tree.out(1).infer.contents.data($+1)=from.infer
                tree.out(1).dims=infdims
                tree.out(1).type=Type(Struct,Unknown)
                // A.b.f
            else
                tree.out(1).dims=list(1,1)
                tree.out(1).type=Type(Struct,Unknown)
                tree.out(1).infer.contents.index($+1)=ind
                tree.out(1).infer.contents.data($+1)=from.infer
            end

        end
        // Two indexes: to(ind1,ind2,...)=from or more
    else
        tree.out(1).dims=list()
        for k=1:lstsize(tree.operands)-2
            tree.out(1).dims(k)=Unknown
        end

        // dim can be infered when index is a constant and when index value is greater than older dim and this dim is not unknown
        for kdim=1:size(tree.operands)-2
            if typeof(tree.operands(kdim+1))=="cste" then
                if to.dims(kdim)<>Unknown then
                    if to.dims(kdim)<=tree.operands(kdim+1).value then
                        tree.out(1).dims(kdim)=tree.operands(kdim+1).value;
                    else
                        tree.out(1).dims(kdim)=to.dims(kdim)
                    end
                end
            end
        end
        tree.out(1).type=from.type

        // Update contents
        ind=tree.operands
        ind(1)=null()
        ind($)=null()
        tree.out(1).infer.contents.index($+1)=ind
        tree.out(1).infer.contents.data($+1)=from.infer

    end
endfunction