* Bug 16552 [m2sci]: cd, dir, dos, exist, ferror, +ismac, ispc, isunix, return
[scilab.git] / scilab / modules / functions / macros / instruction2code.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) 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
14 function  C=instruction2code(I, bprettyprintformat)
15     // Translate an instruction tlist to Scilab code (called by tree2code)
16     // Input:
17     // - I: instruction 'tree'
18     // - bprettyprintformat: boolean value, if FALSE (default value), generated code is not formatted else it is
19     // Output:
20     // - C: Scilab code corresponding to I
21
22     // Default value
23     rhs=argn(2)
24     if rhs==1 then
25         bprettyprintformat=%F
26     end
27
28     C=[]
29
30     // -----------
31     // Empty lines
32     // -----------
33     if I==list("EOL") then
34         C=""
35         return
36     end
37
38     // ---------------------------------------------
39     // Generate code corresponding to a TRY-CATCH
40     // ---------------------------------------------
41     if typeof(I)=="trycatch" then
42
43         //TRYCATCH
44         C="try "
45         [C,indent_space] = format_txt(C,I.trystat(1),bprettyprintformat); // Add EOL after while if needed and returns indent_space
46         for k=1:size(I.trystat)
47             C=cat_code(C,indent_space+instruction2code(I.trystat(k)))
48             if k<size(I.trystat) then // Add EOL between statements if needed
49                 C = format_txt(C,I.trystat(k),bprettyprintformat,I.trystat(k+1));
50             end
51         end
52         C = format_txt(C,I.trystat($),bprettyprintformat); // Add EOL after last statement if needed
53         C=cat_code(C,"catch ")
54         for k=1:size(I.catchstat)
55             C=cat_code(C,indent_space+instruction2code(I.catchstat(k)))
56             if k<size(I.catchstat) then // Add EOL between statements if needed
57                 C = format_txt(C,I.catchstat(k),bprettyprintformat,I.catchstat(k+1));
58             end
59         end
60         C = format_txt(C,I.catchstat($),bprettyprintformat); // Add EOL after last statement if needed
61         C=cat_code(C,"end")
62         C($)=C($)+";"
63         return
64     end
65
66     // ---------------------------------------------
67     // Generate code corresponding to a IF-THEN-ELSE
68     // ---------------------------------------------
69     if typeof(I)=="ifthenelse" then
70
71         // IF
72         C="if "+expression2code(I.expression)+" then"
73         [C,indent_space] = format_txt(C,I.then(1),bprettyprintformat); // Add EOL after then if needed and returns indent_space
74         for k=1:size(I.then)
75             C=cat_code(C,indent_space+instruction2code(I.then(k)))
76             if k<size(I.then) then // Add EOL between then statements if needed
77                 C = format_txt(C,I.then(k),bprettyprintformat,I.then(k+1));
78             end
79         end
80         C = format_txt(C,I.then($),bprettyprintformat); // Add EOL after last then statement if needed
81
82         // ELSEIF
83         if size(I.elseifs)<>0 then
84             for k=1:size(I.elseifs)
85                 C=cat_code(C,"elseif "+expression2code(I.elseifs(k).expression)+" then")
86                 [C,indent_space] = format_txt(C,I.elseifs(k).then(1),bprettyprintformat); // Add EOL after then if needed and returns indent_space
87                 for l=1:size(I.elseifs(k).then)
88                     C=cat_code(C,indent_space+instruction2code(I.elseifs(k).then(l)))
89                     if l<size(I.elseifs(k).then) then // Add EOL between then statements
90                         C = format_txt(C,I.elseifs(k).then(l),bprettyprintformat,I.elseifs(k).then(l+1));
91                     end
92                 end
93                 C = format_txt(C,I.elseifs(k).then($),bprettyprintformat); // Add EOL after last then statement if needed
94             end
95         end
96
97         // ELSE
98         if size(I.else)<>0 then
99             C=cat_code(C,"else")
100         [C,indent_space] = format_txt(C,I.else(1),bprettyprintformat); // Add EOL after else if needed and returns indent_space
101             for k=1:size(I.else)
102             C=cat_code(C,indent_space+instruction2code(I.else(k)))
103                 if k<size(I.else) then // Add EOL between else statements if needed
104                 C = format_txt(C,I.else(k),bprettyprintformat,I.else(k+1));
105                 end
106             end
107         C = format_txt(C,I.else($),bprettyprintformat); // Add EOL after last else statement if needed
108         end
109         C=cat_code(C,"end")
110         C($)=C($)+";"
111         return
112     end
113
114     // --------------------------------------------
115     // Generate code corresponding to a SELECT-CASE
116     // --------------------------------------------
117     if typeof(I)=="selectcase" then
118
119         // SELECT
120         C="select "+expression2code(I.expression(1))
121
122         if size(I.expression)==1 // Not EOL and not comment after the expression
123             if bprettyprintformat then
124                 C = cat_code(C,"") // Add EOL after expression
125             end
126         else
127             for i=2:size(I.expression)
128                 C=cat_code(C," "+ instruction2code(I.expression(i)))
129             end
130         end
131
132         // CASES
133         if size(I.cases)<>0 then
134             for k=1:size(I.cases)
135                 C=cat_code(C,"  case "+expression2code(I.cases(k).expression)+" then")
136                 [C,indent_space] = format_txt(C,I.cases(k).then(1),bprettyprintformat); // Add EOL after then if needed and returns indent_space
137                 if indent_space=="  " then // indent_space is modified because indentation differs from others control instructions
138                     indent_space="    "
139                 end
140                 for l=1:size(I.cases(k).then)
141                     C=cat_code(C,indent_space+instruction2code(I.cases(k).then(l)))
142                     if l<size(I.cases(k).then) then // Add EOL between then statements if needed
143                         C = format_txt(C,I.cases(k).then(l),bprettyprintformat,I.cases(k).then(l+1));
144                     end
145                 end
146                 C = format_txt(C,I.cases(k).then($),bprettyprintformat); // Add EOL after last then statement if needed
147             end
148         end
149         // ELSE
150         if size(I.else)<>0 then
151             C=cat_code(C,"  else")
152         [C,indent_space] = format_txt(C,I.else(1),bprettyprintformat); // Add EOL after else if needed and returns indent_space
153             if indent_space=="  " then // indent_space is modified because indentation differs from others control instructions
154                 indent_space="    "
155             end
156             for k=1:size(I.else)
157             C=cat_code(C,indent_space+instruction2code(I.else(k)))
158                 if k<size(I.else) then // Add EOL between else statements if needed
159                 C = format_txt(C,I.else(k),bprettyprintformat,I.else(k+1));
160                 end
161             end
162         C = format_txt(C,I.else($),bprettyprintformat); // Add EOL after last else statement if needed
163         end
164         C=cat_code(C,"end")
165         C($)=C($)+";"
166         return
167     end
168
169     // --------------------------------------
170     // Generate code corresponding to a WHILE
171     // --------------------------------------
172     if typeof(I)=="while" then
173
174         C="while "+expression2code(I.expression)
175         [C,indent_space] = format_txt(C,I.statements(1),bprettyprintformat); // Add EOL after while if needed and returns indent_space
176         for k=1:size(I.statements)
177             C=cat_code(C,indent_space+instruction2code(I.statements(k)))
178             if k<size(I.statements) then // Add EOL between statements if needed
179                 C = format_txt(C,I.statements(k),bprettyprintformat,I.statements(k+1));
180             end
181         end
182         C = format_txt(C,I.statements($),bprettyprintformat); // Add EOL after last statement if needed
183         C=cat_code(C,"end")
184         C($)=C($)+";"
185         return
186
187     end
188
189     // ------------------------------------
190     // Generate code corresponding to a FOR
191     // ------------------------------------
192     if typeof(I)=="for" then
193
194         C="for "+instruction2code(I.expression)
195         [C,indent_space] = format_txt(C,I.statements(1),bprettyprintformat); // Add EOL after while if needed and returns indent_space
196         for k=1:size(I.statements)
197             C=cat_code(C,indent_space+instruction2code(I.statements(k)))
198             if k<size(I.statements) then // Add EOL between statements if needed
199                 C = format_txt(C,I.statements(k),bprettyprintformat,I.statements(k+1));
200             end
201         end
202         C = format_txt(C,I.statements($),bprettyprintformat); // Add EOL after last statement if needed
203         C=cat_code(C,"end")
204         C($)=C($)+";"
205         return
206     end
207
208     // --------------------------------------
209     // Generate code corresponding to a EQUAL
210     // --------------------------------------
211     if typeof(I)=="equal" then
212
213         // Comments
214         if typeof(I.expression)=="funcall" then
215             if I.expression.name=="%comment" then
216                 I.expression.rhs(1).value=strsubst(I.expression.rhs(1).value,"""""","""")
217                 I.expression.rhs(1).value=strsubst(I.expression.rhs(1).value,"''''","''")
218                 C="//"+I.expression.rhs(1).value
219                 //C($)=C($)+";"
220                 return
221             end
222         end
223
224         // Other EQUAL instruction
225         if size(I.lhs)==1 then
226             if typeof(I.lhs(1))=="variable" then
227                 if I.lhs(1).name=="ans" then // expression
228                     C=rhs2code(I.expression)
229                 else
230                     RHS=rhs2code(I.expression)
231                     if size(RHS,"*")==1 then
232                         C=I.lhs(1).name+" = "+rhs2code(I.expression)
233                     else // Multi-line definition
234                         C=[I.lhs(1).name+" = "+RHS(1);"     "+RHS(2:$)]
235                     end
236                 end
237             else // Insertion...
238                 C=expression2code(I.lhs(1))+" = "+rhs2code(I.expression)
239             end
240         else
241             lhsnames=[]
242             for lhsind=1:size(I.lhs)
243                 lhsnames=[lhsnames,expression2code(I.lhs(lhsind))]
244             end
245             if lhsnames<>[] & strcat(lhsnames,",")<>"" then
246                 C="["+strcat(lhsnames,",")+"] = "+rhs2code(I.expression)
247             else
248                 C=rhs2code(I.expression)
249             end
250         end
251         C($)=C($)+I.endsymbol
252         //C($)=C($)+";";
253         return
254     end
255
256     // --------------------------------------
257     // Generate code corresponding to a comment
258     // --------------------------------------
259     if typeof(I)=="comment" then
260         C="//"+I.text
261         //C = cat_code(C,"//"+I.text)
262         return
263     end
264
265     // ---------------------------------------
266     // Generate code corresponding to sup_equal
267     // ---------------------------------------
268     if typeof(I)=="sup_equal" then
269         while typeof(I.sup_instr(1))=="equal" | I.sup_instr(1)==list("EOL")
270             if I.sup_instr(1)==list("EOL") then //Instruction is an EOL
271                 I.sup_instr(1)=null()
272             elseif typeof(I.sup_instr(1))=="equal" then //Instruction is acomment
273                 if typeof(I.sup_instr(1).expression)=="funcall" then
274                     break
275                 end
276             end
277         end
278         //Optimize the code if all sup_intr are equal tlists and expression of this equal tlists are temporaries variables (not a function)
279         if size(I.sup_instr)==I.nb_opr+1 then
280             for i=size(I.sup_instr):-1:2
281                 optim_instr=%f
282                 if typeof(I.sup_instr(i))=="equal" then
283                     if typeof(I.sup_instr(i).expression)=="variable" then
284                         j=0
285                         while ~optim_instr & j<=size(I.sup_instr(1).lhs)
286                             j=j+1
287                             optim_instr=I.sup_instr(i).expression.name==I.sup_instr(1).lhs(j).name
288                         end
289                     end
290                 end
291                 if optim_instr then
292                     I.sup_instr(1).lhs(j)=I.sup_instr(i).lhs(1)
293                     I.sup_instr(i)=null()
294                 end
295             end
296         end
297         for i=1:size(I.sup_instr)
298             C($+1)=instruction2code(I.sup_instr(i))
299         end
300         return
301     end
302
303     // ----------------------------------------------------
304     // Generate code corresponding to a function definition
305     // ----------------------------------------------------
306     if typeof(I)=="inline" then
307         C = "function "+I.prototype;
308         C = cat_code(C,I.definition)
309         C($+1) = "endfunction";
310         return
311     end
312
313     // -------
314     // Command
315     // -------
316     if and(typeof(I)<>["funcall" "variable", "comment"]) then
317         disp("instruction2code: bug in macr2tree() !");
318         pause
319     end
320     C=expression2code(I);
321     C($)=C($)+";"
322 endfunction
323