summaryrefslogtreecommitdiff
path: root/forop
blob: d741d7af0a41c7b4eae59cebcf7793e58b316890 (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
OP *
newFOROP(label,forline,scalar,expr,block,cont)
char *label;
line_t forline;
OP *scalar;
OP *expr
OP *block
OP *cont;
{
    OP *newop;

    copline = forline;

    /*
     * The following gobbledygook catches EXPRs that
     * aren't explicit array refs and translates
     *		foreach VAR (EXPR)
     * into
     *		@ary = EXPR;
     *		foreach VAR (@ary)
     * where @ary is a hidden array made by newGVgen().
     * (Note that @ary may become a local array if
     * it is determined that it might be called
     * recursively.  See cmd_tosave().)
     */
    if (expr->op_type != OP_ARRAY) {
	scrstab = gv_AVadd(newGVgen());
	newop = append_elem(OP_LINESEQ,
	    newSTATEOP(label,
	      newBINOP(OP_ASSIGN,
		listref(newUNOP(OP_ARRAY,
		  gv_to_op(A_STAB,scrstab))),
		forcelist(expr))),
	    loopscope(over(scalar,newSTATEOP(label,
	      newLOOPOP( 0,
		newUNOP(OP_ARRAY,
		  gv_to_op(A_STAB,scrstab)),
		block,cont)))));
	newop->cop_line = forline;
	newop->cop_head->cop_line = forline;
    }
    else {
	newop = loopscope(over(scalar,newSTATEOP(label,
	newLOOPOP(1,expr,block,cont) )));
    }
    return newop;
}