1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) 2002-2004 - INRIA - Vincent COUVERT
4 // Copyright (C) 2012 - 2016 - Scilab Enterprises
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.
13 function [converted_instr, nblines] = instruction2sci(mtlb_instr,nblines)
15 // Convertion of empty lines
16 if mtlb_instr==list("EOL") then
17 converted_instr=list("EOL")
18 nblines = nblines + 1;
22 if typeof(mtlb_instr)=="equal" then
23 [converted_instr] = equal2sci(mtlb_instr)
25 elseif or(typeof(mtlb_instr)==["ifthenelse","selectcase","for","while","trycatch"]) then
26 [converted_instr, nblines] = clause2sci(mtlb_instr, nblines)
28 elseif or(typeof(mtlb_instr)==["funcall","cste","operation","variable"]) then
29 converted_instr = expression2sci(mtlb_instr)
31 elseif typeof(mtlb_instr)=="comment" then
32 converted_instr = mtlb_instr
35 error(gettext("unknown instruction type %s."),typeof(mtlb_instr))
40 // ---------------------------------------------------------------------------
42 function sci_instr = equal2sci(mtlb_instr)
43 // PRIVATE INTERNAL function called only by instruction2sci()
45 // Conversion of a Matlab instruction or expression to Scilab
47 // - mtlb_instr: Matlab instr or expression to convert
49 // - sci_instr: Scilab equivalent for mtlb_instr
51 // Trees to insert in converted function tree
52 global("m2sci_to_insert_b")
53 m2sci_to_insert_b=list()
54 global("m2sci_to_insert_a")
55 m2sci_to_insert_a=list()
60 // Add inference data to lhs
63 // Inference field added to each lhs argument
64 // Get infos in varslist to init
65 for k=1:size(mtlb_instr.lhs)
66 if typeof(mtlb_instr.lhs(k))=="variable" then
67 [bval,index]=isdefinedvar(mtlb_instr.lhs(k))
69 INFER=varslist(index).infer
73 lhslist($+1)=Variable(mtlb_instr.lhs(k).name,INFER)
74 elseif typeof(mtlb_instr.lhs(k))=="operation" then
75 if mtlb_instr.lhs(k).operator<>"ins" then
76 error(msprintf(gettext("lhs cannot be a %s operation."),mtlb_instr.lhs(k).operator))
79 [bval,index]=isdefinedvar(mtlb_instr.lhs(k).operands(1))
81 INFER=varslist(index).infer
86 lhslist($+1)=Operation(mtlb_instr.lhs(k).operator,..
87 mtlb_instr.lhs(k).operands,..
88 list(Variable(mtlb_instr.lhs(k).operands(1).name,INFER)))
90 error(msprintf(gettext("lhs cannot be a %s."),typeof(mtlb_instr.lhs(k))))
96 [sci_expr]=expression2sci(mtlb_instr.expression,lhslist);
98 if sci_expr==list() then // Conversion made by inserted instructions or 'm2scideclare'
102 sci_instr.expression=sci_expr;
104 // Update lhs of instruction
105 select typeof(sci_instr.expression)
106 case "operation" then
107 sci_instr.lhs=sci_expr.out;
109 sci_instr.lhs=sci_instr.expression.lhs
110 if typeof(mtlb_instr.expression)=="funcall" then
111 sci_instr.lhs=sci_expr.lhs;
114 sci_instr.lhs=lhslist;
115 sci_instr.lhs(1).dims=sci_expr.dims;
116 sci_instr.lhs(1).type=sci_expr.type;
118 sci_instr.lhs=lhslist;
119 sci_instr.lhs(1).dims=sci_expr.dims;
120 sci_instr.lhs(1).type=sci_expr.type;
122 error(msprintf(gettext("%s is not yet implemented."),typeof(sci_instr.expression)));
125 // If lhs are insertion operation, they also have to be converted
126 for k=1:size(sci_instr.lhs)
127 if typeof(sci_instr.lhs(k))=="operation" then
128 sci_instr.lhs(k).operands($+1)=sci_instr.expression
129 // Keep just one inference field in sci_instr.expression (if is a funcall) so that inference can be made in operation2sci()
130 if typeof(sci_instr.lhs(k).operands($))=="funcall" then
131 for l=1:size(sci_instr.lhs(k).operands($).lhs)
133 sci_instr.lhs(k).operands($).lhs(l)=list()
137 while l<=size(sci_instr.lhs(k).operands($).lhs)
138 if sci_instr.lhs(k).operands($).lhs(l)==list() then
139 sci_instr.lhs(k).operands($).lhs(l)=null()
144 // Verify that there is just one lhs kept
145 if size(sci_instr.lhs(k).operands($).lhs)<>1 then pause;end
147 // If insertion made in an unknown variable, I add it to varslist
148 inservar=sci_instr.lhs(k).operands(1)
149 [bval,index]=isdefinedvar(inservar)
151 // Variable added to varslist before insertion
152 if funptr(inservar.name)<>0 then
153 matname="%"+inservar.name
155 matname=inservar.name
157 if sci_instr.expression.vtype==Struct then
158 // Variable is initialized to struct() in converted script is does not already exist
159 varslist($+1)=M2scivar(matname,inservar.name,Infer(list(0,0),Type(Struct,Unknown)))
160 //m2sci_to_insert_b($+1)=Equal(list(inservar),Funcall("struct",1,list(),list()))
161 elseif sci_instr.expression.vtype==Cell then
162 // Variable is initialized to cell() in converted script is does not already exist
163 varslist($+1)=M2scivar(matname,inservar.name,Infer(list(0,0),Type(Cell,Unknown)))
164 //m2sci_to_insert_b($+1)=Equal(list(inservar),Funcall("cell",1,list(),list()))
166 // Variable is initialized to [] in converted script is does not already exist
167 varslist($+1)=M2scivar(matname,inservar.name,Infer(list(0,0),Type(Double,Real)))
168 //m2sci_to_insert_b($+1)=Equal(list(inservar),Cste([]))
170 sci_instr.lhs(k).out(1).infer=varslist($).infer
172 sci_instr.lhs(k).out(1).infer=varslist(index).infer
174 [sci_instr.lhs(k)]=operation2sci(sci_instr.lhs(k))
175 if typeof(sci_instr.lhs(k))=="operation" then
176 if or(sci_instr.lhs(k).operands($)<>sci_instr.expression) then // Update expression if has been modified while converting lhs
177 sci_instr.expression=sci_instr.lhs(k).operands($)
180 sci_instr.lhs(k).operands($)=null()
181 updatevarslist(sci_instr.lhs(k).out)
183 // Insertion done by inserted instruction
190 updatevarslist(sci_instr.lhs);
194 // ---------------------------------------------------------------------------
196 function [sci_clause, nblines] = clause2sci(mtlb_clause, nblines, leveltemp)
199 // Global variables for M2SCI
200 global("m2sci_to_insert_b")
203 // Increment level of clause indentation
206 // Temp variable used to store instructions to insert before clause
208 select typeof(mtlb_clause)
213 // Get instructions to insert if there are
214 if m2sci_to_insert_b<>list() then
215 to_insert=m2sci_to_insert_b
216 m2sci_to_insert_b=list()
222 for k=1:size(mtlb_clause.trystat)
223 if typeof(mtlb_clause.trystat(k))=="sup_equal" then
225 for i=1:size(mtlb_clause.trystat(k).sup_instr)
226 [instr,nblines]=instruction2sci(mtlb_clause.trystat(k).sup_instr(i),nblines)
227 sci_try_temp=update_instr_list(sci_try_temp,instr)
229 sci_try($+1)=tlist(["sup_equal","sup_instr","nb_opr"],sci_try_temp,mtlb_clause.trystat(k).nb_opr)
231 [instr,nblines]=instruction2sci(mtlb_clause.trystat(k),nblines)
232 sci_try=update_instr_list(sci_try,instr)
239 for k=1:size(mtlb_clause.catchstat)
240 if typeof(mtlb_clause.catchstat(k))=="sup_equal" then
241 sci_catch_temp=list()
242 for i=1:size(mtlb_clause.catchstat(k).sup_instr)
243 [instr,nblines]=instruction2sci(mtlb_clause.catchstat(k).sup_instr(i),nblines)
244 sci_catch_temp=update_instr_list(sci_catch_temp,instr)
246 sci_catch($+1)=tlist(["sup_equal","sup_instr","nb_opr"],sci_catch_temp,mtlb_clause.catchstat(k).nb_opr)
248 [instr,nblines]=instruction2sci(mtlb_clause.catchstat(k),nblines)
249 sci_catch=update_instr_list(sci_catch,instr)
253 // Create Scilab trycatch
254 sci_clause=tlist(["trycatch","trystat","catchstat"],sci_try,sci_catch)
256 updatevarslist("END OF CLAUSE")
262 // Convert expression
263 [sci_expr]=expression2sci(mtlb_clause.expression)
265 // Get instructions to insert if there are
266 if m2sci_to_insert_b<>list() then
267 to_insert=m2sci_to_insert_b
268 m2sci_to_insert_b=list()
271 // Convert then statements
274 for k=1:size(mtlb_clause.then)
275 if typeof(mtlb_clause.then(k))=="sup_equal" then
277 for i=1:size(mtlb_clause.then(k).sup_instr)
278 [instr,nblines]=instruction2sci(mtlb_clause.then(k).sup_instr(i),nblines)
279 sci_then_temp=update_instr_list(sci_then_temp,instr)
281 sci_then($+1)=tlist(["sup_equal","sup_instr","nb_opr"],sci_then_temp,mtlb_clause.then(k).nb_opr)
283 [instr,nblines]=instruction2sci(mtlb_clause.then(k),nblines)
284 sci_then=update_instr_list(sci_then,instr)
290 for k=1:size(mtlb_clause.elseifs)
293 // Convert expression
294 [sci_exprn]=expression2sci(mtlb_clause.elseifs(k).expression)
296 // Get instructions to insert if there are
297 if m2sci_to_insert_b<>list() then
298 to_insert=m2sci_to_insert_b
299 m2sci_to_insert_b=list()
302 // Convert statements
304 for l=1:size(mtlb_clause.elseifs(k).then)
305 if typeof(mtlb_clause.elseifs(k).then(l))=="sup_equal" then
307 for i=1:size(mtlb_clause.elseifs(k).then(l).sup_instr)
308 [instr,nblines]=instruction2sci(mtlb_clause.elseifs(k).then(l).sup_instr(i),nblines)
309 sci_stat_temp=update_instr_list(sci_stat_temp,instr)
311 sci_stat($+1)=tlist(["sup_equal","sup_instr","nb_opr"],sci_stat_temp,mtlb_clause.elseifs(k).then(l).nb_opr)
313 [instr,nblines]=instruction2sci(mtlb_clause.elseifs(k).then(l),nblines)
314 sci_stat=update_instr_list(sci_stat,instr)
317 sci_elseifs($+1)=tlist(["elseif","expression","then"],sci_exprn,sci_stat)
322 if size(mtlb_clause.else)<>0 then
325 for k=1:size(mtlb_clause.else)
326 if typeof(mtlb_clause.else(k))=="sup_equal" then
328 for i=1:size(mtlb_clause.else(k).sup_instr)
329 [instr,nblines]=instruction2sci(mtlb_clause.else(k).sup_instr(i),nblines)
330 sci_else_temp=update_instr_list(sci_else_temp,instr)
332 sci_else($+1)=tlist(["sup_equal","sup_instr","nb_opr"],sci_else_temp,mtlb_clause.else(k).nb_opr)
334 [instr,nblines]=instruction2sci(mtlb_clause.else(k),nblines)
335 sci_else=update_instr_list(sci_else,instr)
339 // Create Scilab ifthenelse
340 sci_clause=tlist(["ifthenelse","expression","then","elseifs","else"],sci_expr,sci_then,sci_elseifs,sci_else)
342 updatevarslist("END OF CLAUSE")
347 // Convert expression
349 [sci_expr(1)]=expression2sci(mtlb_clause.expression(1))
350 for i=2:size(mtlb_clause.expression)
351 sci_expr(i)=mtlb_clause.expression(i) // EOL or comment
354 // Get instructions to insert if there are
355 if m2sci_to_insert_b<>list() then
356 to_insert=m2sci_to_insert_b
357 m2sci_to_insert_b=list()
363 while k<size(mtlb_clause.cases)
366 // Convert expression
367 if typeof(mtlb_clause.cases(k).expression)=="funcall" then
368 if mtlb_clause.cases(k).expression.name=="makecell" then
370 for nbcas=size(mtlb_clause.cases):-1:k+1
371 mtlb_clause.cases(nbcas+size(mtlb_clause.cases(k).expression.rhs))=mtlb_clause.cases(nbcas)
373 for nbrhs=1:size(mtlb_clause.cases(k).expression.rhs)
374 mtlb_clause.cases(nbrhs+k)=tlist(["case","expression","then"],mtlb_clause.cases(k).expression.rhs(nbrhs),mtlb_clause.cases(k).then)
376 mtlb_clause.cases(k)=null()
379 [sci_exprn]=expression2sci(mtlb_clause.cases(k).expression)
380 // Get instructions to insert if there are
381 if m2sci_to_insert_b<>list() then
382 to_insert=m2sci_to_insert_b
383 m2sci_to_insert_b=list()
386 // Convert statements
388 for l=1:size(mtlb_clause.cases(k).then)
389 if typeof(mtlb_clause.cases(k).then(l))=="sup_equal" then
391 for i=1:size(mtlb_clause.cases(k).then(l).sup_instr)
392 [instr,nblines]=instruction2sci(mtlb_clause.cases(k).then(l).sup_instr(i),nblines)
393 sci_stat_temp=update_instr_list(sci_stat_temp,instr)
395 sci_stat($+1)=tlist(["sup_equal","sup_instr","nb_opr"],sci_stat_temp,mtlb_clause.cases(k).then(l).nb_opr)
397 [instr,nblines]=instruction2sci(mtlb_clause.cases(k).then(l),nblines)
398 sci_stat=update_instr_list(sci_stat,instr)
401 sci_cases($+1)=tlist(["case","expression","then"],sci_exprn,sci_stat)
406 if size(mtlb_clause.else)<>0 then
409 for k=1:size(mtlb_clause.else)
410 if typeof(mtlb_clause.else(k))=="sup_equal" then
411 sci_else_temp=list();
412 for i=1:size(mtlb_clause.else(k).sup_instr)
413 [instr,nblines]=instruction2sci(mtlb_clause.else(k).sup_instr(i),nblines)
414 sci_else_temp=update_instr_list(sci_else_temp,instr)
416 sci_else($+1)=tlist(["sup_equal","sup_instr","nb_opr"],sci_else_temp,mtlb_clause.else(k).nb_opr)
418 [instr,nblines]=instruction2sci(mtlb_clause.else(k),nblines)
419 sci_else=update_instr_list(sci_else,instr)
422 // Create Scilab selectcase
423 sci_clause=tlist(["selectcase","expression","cases","else"],sci_expr,sci_cases,sci_else)
425 updatevarslist("END OF CLAUSE")
431 // Convert expression
432 [sci_expr]=expression2sci(mtlb_clause.expression)
433 // If there are instructions to insert, while is modified so that inserted instruction is evaluated in each loop
434 if m2sci_to_insert_b<>list() then
435 newif=tlist(["ifthenelse","expression","then","elseifs","else"],sci_expr,list(Funcall("break",1,list(),list())),list(),list())
436 m2sci_to_insert_b($+1)=newif
438 sci_do=m2sci_to_insert_b
439 m2sci_to_insert_b=list()
442 // Convert all do instructions
444 for k=1:size(mtlb_clause.statements)
445 if typeof(mtlb_clause.statements(k))=="sup_equal" then
447 for i=1:size(mtlb_clause.statements(k).sup_instr)
448 [instr,nblines]=instruction2sci(mtlb_clause.statements(k).sup_instr(i),nblines)
449 // If inserted instruction is an initialisation, it has to be done just one time and before loop
451 while l <= size(m2sci_to_insert_b)
452 if typeof(m2sci_to_insert_b(l))=="equal" & ..
453 (and(m2sci_to_insert_b(l).expression==Cste([])) | ..
454 and(m2sci_to_insert_b(l).expression==Funcall("struct",1,list(),list())) | ..
455 and(m2sci_to_insert_b(l).expression==Funcall("cell",1,list(),list())) ) then
456 to_insert($+1)=m2sci_to_insert_b(l)
457 m2sci_to_insert_b(l)=null()
458 if size(m2sci_to_insert_b)>=l & m2sci_to_insert_b(l)==list("EOL") then
459 to_insert($+1)=m2sci_to_insert_b(l)
460 m2sci_to_insert_b(l)=null()
466 sci_do_temp=update_instr_list(sci_do_temp,instr)
468 sci_do($+1)=tlist(["sup_equal","sup_instr","nb_opr"],sci_do_temp,mtlb_clause.statements(k).nb_opr)
470 [instr,nblines]=instruction2sci(mtlb_clause.statements(k),nblines)
471 // If inserted instruction is an initialisation, it has to be done just one time and before loop
473 while l <= size(m2sci_to_insert_b)
474 if typeof(m2sci_to_insert_b(l))=="equal" & ..
475 (and(m2sci_to_insert_b(l).expression==Cste([])) | ..
476 and(m2sci_to_insert_b(l).expression==Funcall("struct",1,list(),list())) | ..
477 and(m2sci_to_insert_b(l).expression==Funcall("cell",1,list(),list())) ) then
478 to_insert($+1)=m2sci_to_insert_b(l)
479 m2sci_to_insert_b(l)=null()
480 if size(m2sci_to_insert_b)>=l & m2sci_to_insert_b(l)==list("EOL") then
481 to_insert($+1)=m2sci_to_insert_b(l)
482 m2sci_to_insert_b(l)=null()
488 sci_do=update_instr_list(sci_do,instr)
492 // Create Scilab while
493 sci_clause=tlist(["while","expression","statements"],sci_expr,sci_do)
495 updatevarslist("END OF CLAUSE")
500 // Convert expression
501 [sci_expr,nblines]=instruction2sci(mtlb_clause.expression,nblines)
502 if typeof(sci_expr)=="equal" then
503 [bval,pos]=isdefinedvar(sci_expr.lhs(1))
505 varslist(pos).infer.dims=list(varslist(pos).infer.dims(1),1)
508 // Get instructions to insert if there are
509 if m2sci_to_insert_b<>list() then
510 to_insert=m2sci_to_insert_b
511 m2sci_to_insert_b=list()
514 // Convert all do instructions
515 for k=1:size(mtlb_clause.statements)
516 if typeof(mtlb_clause.statements(k))=="sup_equal" then
517 sci_instr_temp=list()
518 for i=1:size(mtlb_clause.statements(k).sup_instr)
519 [instr,nblines]=instruction2sci(mtlb_clause.statements(k).sup_instr(i),nblines)
520 // If inserted instruction is an initialisation, it has to be done just one time and before loop
522 while l <= size(m2sci_to_insert_b)
523 if typeof(m2sci_to_insert_b(l))=="equal" & ..
524 (and(m2sci_to_insert_b(l).expression==Cste([])) | ..
525 and(m2sci_to_insert_b(l).expression==Funcall("struct",1,list(),list())) | ..
526 and(m2sci_to_insert_b(l).expression==Funcall("cell",1,list(),list())) ) then
527 to_insert($+1)=m2sci_to_insert_b(l)
528 m2sci_to_insert_b(l)=null()
529 if size(m2sci_to_insert_b)>=l & m2sci_to_insert_b(l)==list("EOL") then
530 to_insert($+1)=m2sci_to_insert_b(l)
531 m2sci_to_insert_b(l)=null()
537 sci_instr_temp=update_instr_list(sci_instr_temp,instr)
539 sci_instr($+1)=tlist(["sup_equal","sup_instr","nb_opr"],sci_instr_temp,mtlb_clause.statements(k).nb_opr)
541 [instr,nblines]=instruction2sci(mtlb_clause.statements(k),nblines)
542 // If inserted instruction is an initialisation, it has to be done just one time and before loop
544 while l <= size(m2sci_to_insert_b)
545 if typeof(m2sci_to_insert_b(l))=="equal" & ..
546 (and(m2sci_to_insert_b(l).expression==Cste([])) | ..
547 and(m2sci_to_insert_b(l).expression==Funcall("struct",1,list(),list())) | ..
548 and(m2sci_to_insert_b(l).expression==Funcall("cell",1,list(),list())) ) then
549 to_insert($+1)=m2sci_to_insert_b(l)
550 m2sci_to_insert_b(l)=null()
551 if size(m2sci_to_insert_b)>=l & m2sci_to_insert_b(l)==list("EOL") then
552 to_insert($+1)=m2sci_to_insert_b(l)
553 m2sci_to_insert_b(l)=null()
559 sci_instr=update_instr_list(sci_instr,instr)
562 // Create Scilab while
563 sci_clause=tlist(["for","expression","statements"],sci_expr,sci_instr)
565 error(msprintf(gettext("unknown clause type: %s."),typeof(mtlb_clause)))
567 m2sci_to_insert_b=to_insert
568 if m2sci_to_insert_b<>list() then
569 m2sci_to_insert_b($+1)=list("EOL");
573 // ---------------------------------------------------------------------------
575 function updatevarslist(instr_lhs)
576 // PRIVATE INTERNAL function called only by equal2sci() and clause2sci()
577 // that are also private to instruction2sci()
579 // (2 functions in this file: merge_vars() at the end)
580 // Update list of M2SCI variables with converted instruction lhs
582 // - instr_lhs: list of lhs of current instruction
583 // - in_a_clause: boolean value
584 // Set to 1 if instruction is in a clause
585 // In this case, type and dimensions are set to unknown if differ from those already stored in varslist
586 // (Default value is %F)
588 // Global variable for M2SCI
593 // level is declared in m2sci.sci and modified in clause2sci.sci
601 // Merge infered data from the last two parts of clause which are above the current part
602 // if we are in the third part of clause (current), then : merge the first and second part of clause
603 // when end of conversion of a clause : merge infered data from the last two parts of clause
604 levelsize=size(level,1)
607 for i=size(varslist):-1:1
608 if size(varslist(i).level,1)==levelsize then
609 varlevel=varslist(i).level
610 if varlevel($)<>level($)
618 if changepartclause | instr_lhs=="END OF CLAUSE" then
619 index=[] // Search variables from two part above current part clause
620 for k=size(varslist):-1:1
621 if size(varslist(k).level,1)==levelsize then
622 varlevel=varslist(k).level
623 if and(varlevel(1:$-1)==level(1:$-1)) & varlevel($)==level($)-2 then
628 if index<>[] then // Found variables from the second part above current part of a clause
629 for k=1:size(index,1)
631 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
632 varlevel=varslist(i).level
633 if varslist(i).matname==varslist(index(k)).matname & and(varlevel(1:$-1)==level(1:$-1)) & varlevel($)==level($)-1 then
634 boolmerge =%T // Found the same variable name from the last two parts above the current part : Merge
635 merge_vars(index(k),varslist(i))
641 varslist(index(k)).level=[level(1:$-1);level($)-1]
647 // Special case when end of conversion of a clause
648 // Merge infered data from clause and those from level-1
649 if instr_lhs=="END OF CLAUSE" then // Search variables in the last part of a clause (above end of conversion of a clause)
651 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
652 varlevel=varslist(k).level
653 if varlevel==[level(1:$-1);level($)-1] then
658 for j=1:size(index,1)
660 for k=size(varslist):-1:1 //
661 varlevel=varslist(k).level
662 if varslist(k).matname==varslist(index(j)).matname & and(varlevel==level(1:$-1)) then
663 boolmerge=%T // Found variables from level-1 which have the same name than variables from the last part of current level : Merge
665 merge_vars(index_lower_level,varslist(index(j)))
666 varslist(k).level=level(1:$-1)
667 varslist(index(j))=null()
671 if boolmerge==%F then
672 varslist(index(j)).level=level(1:$-1)
679 // Expression: lhs name is empty => nothing to do
680 if instr_lhs==list() then
684 // Remove lhs which are not variables
686 while k<=size(instr_lhs)
687 // Insertion operation
688 if typeof(instr_lhs(k))=="operation" then
695 if size(instr_lhs)==0 then
700 for k=1:size(instr_lhs)
701 [bval,index]=isdefinedvar(instr_lhs(k))
702 ierr=execstr("zz=instr_lhs(k).contents.index","errcatch")
703 if ierr<>0 then pause;end
704 // Remove multiple entries from contents
705 for kcont = size(instr_lhs(k).contents.index):-1:1
706 [infertlist,pos]=get_contents_infer(instr_lhs(k),instr_lhs(k).contents.index(kcont))
707 if pos<>0 & pos<>kcont then
708 instr_lhs(k).contents.index(pos)=null()
709 instr_lhs(k).contents.data(pos)=null()
712 // If variable exists for the current level in the same part of clause then update exixting variable
715 for l=1:size(varslist)
716 if varslist(l).matname==instr_lhs(k).name & varslist(l).level==level then
717 varslist(l)=M2scivar(varslist(l).sciname,..
718 varslist(l).matname,..
719 Infer(instr_lhs(k).infer.dims,instr_lhs(k).infer.type,instr_lhs(k).infer.contents),..
725 // If variable exists, but not for the current level or not in the same part of clause then Update variable then create new variable
727 varslist($+1)=M2scivar(varslist(index).sciname,..
728 varslist(index).matname,..
729 instr_lhs(k).infer,..
733 // Variable added to varslist if as a name (not done for expressions
734 if execstr("f=instr_lhs(k).name","errcatch")<>0 then pause;end;errclear();
735 if instr_lhs(k).name<>"ans" then
736 varslist($+1)=M2scivar(instr_lhs(k).name,..
738 instr_lhs(k).infer,..
745 // ---------------------------------------------------------------------------
747 function merge_vars(oldvarindex, newvar)
748 // PRIVATE INTERNAL function called only by updatevarslist() hereabove.
750 // Merge two variables inference properties, if different then set to Unknown
752 // - oldvarindex: index of old variable in varslist
753 // - newvar: new variable to take in account to update oldvar properties
755 // Global variable for M2SCI
757 oldvar=varslist(oldvarindex)
760 oldvtype=oldvar.vtype
761 oldprop=oldvar.property
764 newvtype=newvar.vtype
765 newprop=newvar.property
768 for l=1:min(size(newdims),size(olddims))
769 if newdims(l)<>olddims(l) then
773 if size(newdims)>size(olddims) then
774 for l=size(olddims):size(newdims)
780 if newvtype<>oldvtype then
785 if newprop<>oldprop then
790 for k = 1:size(newvar.contents.index)
791 olddata=get_contents_infer(oldvar,newvar.contents.index(k))
792 newdata=newvar.contents.data(k)
794 if or(olddata<>newdata) then
795 newvar.infer.contents.data(k)=Infer()
799 // Write result in varslist
800 varslist(oldvarindex)=M2scivar(oldvar.sciname,..
802 Infer(newdims,Type(newvtype,newprop),newvar.contents),..