* Bugs 16567 16586 fixed: mfile2sci() supports block %{..%}. Appended comments improved"
[scilab.git] / scilab / modules / m2sci / macros / kernel / clause2sci.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 [sci_clause,nblines]=clause2sci(mtlb_clause,nblines,leveltemp)
14     // M2SCI function
15
16     // Global variables for M2SCI
17     global("m2sci_to_insert_b")
18     global("varslist")
19
20     // Increment level of clause indentation
21     level
22
23     // Temp variable used to store instructions to insert before clause
24     to_insert=list()
25     select typeof(mtlb_clause)
26         // --- TRYCATCH ---
27     case "trycatch"
28         level=[level;0]
29
30         // Get instructions to insert if there are
31         if m2sci_to_insert_b<>list() then
32             to_insert=m2sci_to_insert_b
33             m2sci_to_insert_b=list()
34         end
35
36         // Convert try
37         sci_try=list()
38         level($)=level($)+1
39         for k=1:size(mtlb_clause.trystat)
40             if typeof(mtlb_clause.trystat(k))=="sup_equal" then
41                 sci_try_temp=list()
42                 for i=1:size(mtlb_clause.trystat(k).sup_instr)
43                     [instr,nblines]=instruction2sci(mtlb_clause.trystat(k).sup_instr(i),nblines)
44                     sci_try_temp=update_instr_list(sci_try_temp,instr)
45                 end
46                 sci_try($+1)=tlist(["sup_equal","sup_instr","nb_opr"],sci_try_temp,mtlb_clause.trystat(k).nb_opr)
47             else
48                 [instr,nblines]=instruction2sci(mtlb_clause.trystat(k),nblines)
49                 sci_try=update_instr_list(sci_try,instr)
50             end
51         end
52
53         // Convert catch
54         sci_catch=list()
55         level($)=level($)+1
56         for k=1:size(mtlb_clause.catchstat)
57             if typeof(mtlb_clause.catchstat(k))=="sup_equal" then
58                 sci_catch_temp=list()
59                 for i=1:size(mtlb_clause.catchstat(k).sup_instr)
60                     [instr,nblines]=instruction2sci(mtlb_clause.catchstat(k).sup_instr(i),nblines)
61                     sci_catch_temp=update_instr_list(sci_catch_temp,instr)
62                 end
63                 sci_catch($+1)=tlist(["sup_equal","sup_instr","nb_opr"],sci_catch_temp,mtlb_clause.catchstat(k).nb_opr)
64             else
65                 [instr,nblines]=instruction2sci(mtlb_clause.catchstat(k),nblines)
66                 sci_catch=update_instr_list(sci_catch,instr)
67             end
68         end
69
70         // Create Scilab trycatch
71         sci_clause=tlist(["trycatch","trystat","catchstat"],sci_try,sci_catch)
72         level($)=level($)+1
73         updatevarslist("END OF CLAUSE")
74
75         // --- IF ---
76     case "ifthenelse"
77         level=[level;0]
78
79         // Convert expression
80         [sci_expr]=expression2sci(mtlb_clause.expression)
81
82         // Get instructions to insert if there are
83         if m2sci_to_insert_b<>list() then
84             to_insert=m2sci_to_insert_b
85             m2sci_to_insert_b=list()
86         end
87
88         // Convert then statements
89         sci_then=list()
90         level($)=level($)+1
91         for k=1:size(mtlb_clause.then)
92             if typeof(mtlb_clause.then(k))=="sup_equal" then
93                 sci_then_temp=list()
94                 for i=1:size(mtlb_clause.then(k).sup_instr)
95                     [instr,nblines]=instruction2sci(mtlb_clause.then(k).sup_instr(i),nblines)
96                     sci_then_temp=update_instr_list(sci_then_temp,instr)
97                 end
98                 sci_then($+1)=tlist(["sup_equal","sup_instr","nb_opr"],sci_then_temp,mtlb_clause.then(k).nb_opr)
99             else
100                 [instr,nblines]=instruction2sci(mtlb_clause.then(k),nblines)
101                 sci_then=update_instr_list(sci_then,instr)
102             end
103         end
104
105         // Convert elseifs
106         sci_elseifs=list()
107         for k=1:size(mtlb_clause.elseifs)
108             level($)=level($)+1
109
110             // Convert expression
111             [sci_exprn]=expression2sci(mtlb_clause.elseifs(k).expression)
112
113             // Get instructions to insert if there are
114             if m2sci_to_insert_b<>list() then
115                 to_insert=m2sci_to_insert_b
116                 m2sci_to_insert_b=list()
117             end
118
119             // Convert statements
120             sci_stat=list()
121             for l=1:size(mtlb_clause.elseifs(k).then)
122                 if typeof(mtlb_clause.elseifs(k).then(l))=="sup_equal" then
123                     sci_stat_temp=list()
124                     for i=1:size(mtlb_clause.elseifs(k).then(l).sup_instr)
125                         [instr,nblines]=instruction2sci(mtlb_clause.elseifs(k).then(l).sup_instr(i),nblines)
126                         sci_stat_temp=update_instr_list(sci_stat_temp,instr)
127                     end
128                     sci_stat($+1)=tlist(["sup_equal","sup_instr","nb_opr"],sci_stat_temp,mtlb_clause.elseifs(k).then(l).nb_opr)
129                 else
130                     [instr,nblines]=instruction2sci(mtlb_clause.elseifs(k).then(l),nblines)
131                     sci_stat=update_instr_list(sci_stat,instr)
132                 end
133             end
134             sci_elseifs($+1)=tlist(["elseif","expression","then"],sci_exprn,sci_stat)
135         end
136
137         // Convert else
138         sci_else=list()
139         if size(mtlb_clause.else)<>0 then
140             level($)=level($)+1
141         end
142         for k=1:size(mtlb_clause.else)
143             if typeof(mtlb_clause.else(k))=="sup_equal" then
144                 sci_else_temp=list()
145                 for i=1:size(mtlb_clause.else(k).sup_instr)
146                 [instr,nblines]=instruction2sci(mtlb_clause.else(k).sup_instr(i),nblines)
147                     sci_else_temp=update_instr_list(sci_else_temp,instr)
148                 end
149             sci_else($+1)=tlist(["sup_equal","sup_instr","nb_opr"],sci_else_temp,mtlb_clause.else(k).nb_opr)
150             else
151             [instr,nblines]=instruction2sci(mtlb_clause.else(k),nblines)
152                 sci_else=update_instr_list(sci_else,instr)
153             end
154         end
155
156         // Create Scilab ifthenelse
157         sci_clause=tlist(["ifthenelse","expression","then","elseifs","else"],sci_expr,sci_then,sci_elseifs,sci_else)
158         level($)=level($)+1
159         updatevarslist("END OF CLAUSE")
160
161         // --- SELECT ---
162     case "selectcase"
163         level=[level;0]
164         // Convert expression
165         sci_expr=list()
166         [sci_expr(1)]=expression2sci(mtlb_clause.expression(1))
167         for i=2:size(mtlb_clause.expression)
168             sci_expr(i)=mtlb_clause.expression(i) // EOL or comment
169         end
170
171         // Get instructions to insert if there are
172         if m2sci_to_insert_b<>list() then
173             to_insert=m2sci_to_insert_b
174             m2sci_to_insert_b=list()
175         end
176
177         // Convert cases
178         sci_cases=list()
179         k=0
180         while k<size(mtlb_clause.cases)
181             k=k+1
182             level($)=level($)+1
183             // Convert expression
184             if typeof(mtlb_clause.cases(k).expression)=="funcall" then
185                 if mtlb_clause.cases(k).expression.name=="makecell" then
186                     // Insert new cases
187                     for nbcas=size(mtlb_clause.cases):-1:k+1
188                         mtlb_clause.cases(nbcas+size(mtlb_clause.cases(k).expression.rhs))=mtlb_clause.cases(nbcas)
189                     end
190                     for nbrhs=1:size(mtlb_clause.cases(k).expression.rhs)
191                         mtlb_clause.cases(nbrhs+k)=tlist(["case","expression","then"],mtlb_clause.cases(k).expression.rhs(nbrhs),mtlb_clause.cases(k).then)
192                     end
193                     mtlb_clause.cases(k)=null()
194                 end
195             end
196             [sci_exprn]=expression2sci(mtlb_clause.cases(k).expression)
197             // Get instructions to insert if there are
198             if m2sci_to_insert_b<>list() then
199                 to_insert=m2sci_to_insert_b
200                 m2sci_to_insert_b=list()
201             end
202
203             // Convert statements
204             sci_stat=list()
205             for l=1:size(mtlb_clause.cases(k).then)
206                 if typeof(mtlb_clause.cases(k).then(l))=="sup_equal" then
207                     sci_stat_temp=list()
208                     for i=1:size(mtlb_clause.cases(k).then(l).sup_instr)
209                         [instr,nblines]=instruction2sci(mtlb_clause.cases(k).then(l).sup_instr(i),nblines)
210                         sci_stat_temp=update_instr_list(sci_stat_temp,instr)
211                     end
212                     sci_stat($+1)=tlist(["sup_equal","sup_instr","nb_opr"],sci_stat_temp,mtlb_clause.cases(k).then(l).nb_opr)
213                 else
214                     [instr,nblines]=instruction2sci(mtlb_clause.cases(k).then(l),nblines)
215                     sci_stat=update_instr_list(sci_stat,instr)
216                 end
217             end
218             sci_cases($+1)=tlist(["case","expression","then"],sci_exprn,sci_stat)
219         end
220
221         // Convert else
222         sci_else=list()
223         if size(mtlb_clause.else)<>0 then
224             level($)=level($)+1
225         end
226         for k=1:size(mtlb_clause.else)
227             if typeof(mtlb_clause.else(k))=="sup_equal" then
228                 sci_else_temp=list();
229                 for i=1:size(mtlb_clause.else(k).sup_instr)
230                 [instr,nblines]=instruction2sci(mtlb_clause.else(k).sup_instr(i),nblines)
231                     sci_else_temp=update_instr_list(sci_else_temp,instr)
232                 end
233             sci_else($+1)=tlist(["sup_equal","sup_instr","nb_opr"],sci_else_temp,mtlb_clause.else(k).nb_opr)
234             else
235             [instr,nblines]=instruction2sci(mtlb_clause.else(k),nblines)
236                 sci_else=update_instr_list(sci_else,instr)
237             end
238         end
239         // Create Scilab selectcase
240         sci_clause=tlist(["selectcase","expression","cases","else"],sci_expr,sci_cases,sci_else)
241         level($)=level($)+1
242         updatevarslist("END OF CLAUSE")
243
244         // --- WHILE ---
245     case "while"
246         level=[level;0]
247         sci_do=list()
248         // Convert expression
249         [sci_expr]=expression2sci(mtlb_clause.expression)
250         // If there are instructions to insert, while is modified so that inserted instruction is evaluated in each loop
251         if m2sci_to_insert_b<>list() then
252             newif=tlist(["ifthenelse","expression","then","elseifs","else"],sci_expr,list(Funcall("break",1,list(),list())),list(),list())
253             m2sci_to_insert_b($+1)=newif
254             sci_expr=Cste(%T)
255             sci_do=m2sci_to_insert_b
256             m2sci_to_insert_b=list()
257         end
258
259         // Convert all do instructions
260         level($)=level($)+1
261         for k=1:size(mtlb_clause.statements)
262             if typeof(mtlb_clause.statements(k))=="sup_equal" then
263                 sci_do_temp=list()
264                 for i=1:size(mtlb_clause.statements(k).sup_instr)
265                     [instr,nblines]=instruction2sci(mtlb_clause.statements(k).sup_instr(i),nblines)
266                     // If inserted instruction is an initialisation, it has to be done just one time and before loop
267                     l=1;
268                     while l <= size(m2sci_to_insert_b)
269                         if typeof(m2sci_to_insert_b(l))=="equal" & ..
270                             (and(m2sci_to_insert_b(l).expression==Cste([])) | ..
271                             and(m2sci_to_insert_b(l).expression==Funcall("struct",1,list(),list())) | ..
272                             and(m2sci_to_insert_b(l).expression==Funcall("cell",1,list(),list())) ) then
273                             to_insert($+1)=m2sci_to_insert_b(l)
274                             m2sci_to_insert_b(l)=null()
275                             if size(m2sci_to_insert_b)>=l & m2sci_to_insert_b(l)==list("EOL") then
276                                 to_insert($+1)=m2sci_to_insert_b(l)
277                                 m2sci_to_insert_b(l)=null()
278                             end
279                         else
280                             l=l+1;
281                         end
282                     end
283                     sci_do_temp=update_instr_list(sci_do_temp,instr)
284                 end
285                 sci_do($+1)=tlist(["sup_equal","sup_instr","nb_opr"],sci_do_temp,mtlb_clause.statements(k).nb_opr)
286             else
287                 [instr,nblines]=instruction2sci(mtlb_clause.statements(k),nblines)
288                 // If inserted instruction is an initialisation, it has to be done just one time and before loop
289                 l=1;
290                 while l <= size(m2sci_to_insert_b)
291                     if typeof(m2sci_to_insert_b(l))=="equal" & ..
292                         (and(m2sci_to_insert_b(l).expression==Cste([])) | ..
293                         and(m2sci_to_insert_b(l).expression==Funcall("struct",1,list(),list())) | ..
294                         and(m2sci_to_insert_b(l).expression==Funcall("cell",1,list(),list())) ) then
295                         to_insert($+1)=m2sci_to_insert_b(l)
296                         m2sci_to_insert_b(l)=null()
297                         if size(m2sci_to_insert_b)>=l & m2sci_to_insert_b(l)==list("EOL") then
298                             to_insert($+1)=m2sci_to_insert_b(l)
299                             m2sci_to_insert_b(l)=null()
300                         end
301                     else
302                         l=l+1;
303                     end
304                 end
305                 sci_do=update_instr_list(sci_do,instr)
306             end
307         end
308
309         // Create Scilab while
310         sci_clause=tlist(["while","expression","statements"],sci_expr,sci_do)
311         level($)=level($)+1
312         updatevarslist("END OF CLAUSE")
313
314         // --- FOR ---
315     case "for"
316         //level=[level;1]
317         // Convert expression
318         [sci_expr,nblines]=instruction2sci(mtlb_clause.expression,nblines)
319         if typeof(sci_expr)=="equal" then
320             [bval,pos]=isdefinedvar(sci_expr.lhs(1))
321             if bval then
322                 varslist(pos).infer.dims=list(varslist(pos).infer.dims(1),1)
323             end
324         end
325         // Get instructions to insert if there are
326         if m2sci_to_insert_b<>list() then
327             to_insert=m2sci_to_insert_b
328             m2sci_to_insert_b=list()
329         end
330         sci_instr=list()
331         // Convert all do instructions
332         for k=1:size(mtlb_clause.statements)
333             if typeof(mtlb_clause.statements(k))=="sup_equal" then
334                 sci_instr_temp=list()
335                 for i=1:size(mtlb_clause.statements(k).sup_instr)
336                     [instr,nblines]=instruction2sci(mtlb_clause.statements(k).sup_instr(i),nblines)
337                     // If inserted instruction is an initialisation, it has to be done just one time and before loop
338                     l=1;
339                     while l <= size(m2sci_to_insert_b)
340                         if typeof(m2sci_to_insert_b(l))=="equal" & ..
341                             (and(m2sci_to_insert_b(l).expression==Cste([])) | ..
342                             and(m2sci_to_insert_b(l).expression==Funcall("struct",1,list(),list())) | ..
343                             and(m2sci_to_insert_b(l).expression==Funcall("cell",1,list(),list())) ) then
344                             to_insert($+1)=m2sci_to_insert_b(l)
345                             m2sci_to_insert_b(l)=null()
346                             if size(m2sci_to_insert_b)>=l & m2sci_to_insert_b(l)==list("EOL") then
347                                 to_insert($+1)=m2sci_to_insert_b(l)
348                                 m2sci_to_insert_b(l)=null()
349                             end
350                         else
351                             l=l+1;
352                         end
353                     end
354                     sci_instr_temp=update_instr_list(sci_instr_temp,instr)
355                 end
356                 sci_instr($+1)=tlist(["sup_equal","sup_instr","nb_opr"],sci_instr_temp,mtlb_clause.statements(k).nb_opr)
357             else
358                 [instr,nblines]=instruction2sci(mtlb_clause.statements(k),nblines)
359                 // If inserted instruction is an initialisation, it has to be done just one time and before loop
360                 l=1;
361                 while l <= size(m2sci_to_insert_b)
362                     if typeof(m2sci_to_insert_b(l))=="equal" & ..
363                         (and(m2sci_to_insert_b(l).expression==Cste([])) | ..
364                         and(m2sci_to_insert_b(l).expression==Funcall("struct",1,list(),list())) | ..
365                         and(m2sci_to_insert_b(l).expression==Funcall("cell",1,list(),list())) ) then
366                         to_insert($+1)=m2sci_to_insert_b(l)
367                         m2sci_to_insert_b(l)=null()
368                         if size(m2sci_to_insert_b)>=l & m2sci_to_insert_b(l)==list("EOL") then
369                             to_insert($+1)=m2sci_to_insert_b(l)
370                             m2sci_to_insert_b(l)=null()
371                         end
372                     else
373                         l=l+1;
374                     end
375                 end
376                 sci_instr=update_instr_list(sci_instr,instr)
377             end
378         end
379         // Create Scilab while
380         sci_clause=tlist(["for","expression","statements"],sci_expr,sci_instr)
381     else
382         error(msprintf(gettext("unknown clause type: %s."),typeof(mtlb_clause)))
383     end
384     m2sci_to_insert_b=to_insert
385     if m2sci_to_insert_b<>list() then
386         m2sci_to_insert_b($+1)=list("EOL");
387     end
388 endfunction