1*74a4d8c2SCharles.Forsyth #include "rc.h"
2*74a4d8c2SCharles.Forsyth #include "y.tab.h"
3*74a4d8c2SCharles.Forsyth
4*74a4d8c2SCharles.Forsyth #define c0 t->child[0]
5*74a4d8c2SCharles.Forsyth #define c1 t->child[1]
6*74a4d8c2SCharles.Forsyth #define c2 t->child[2]
7*74a4d8c2SCharles.Forsyth #define emitf(x) ((codep!=ncode || morecode()), codebuf[codep].f=(x), codep++)
8*74a4d8c2SCharles.Forsyth #define emiti(x) ((codep!=ncode || morecode()), codebuf[codep].i=(x), codep++)
9*74a4d8c2SCharles.Forsyth #define emits(x) ((codep!=ncode || morecode()), codebuf[codep].s=(x), codep++)
10*74a4d8c2SCharles.Forsyth
11*74a4d8c2SCharles.Forsyth void stuffdot(int);
12*74a4d8c2SCharles.Forsyth char *fnstr(Tree*);
13*74a4d8c2SCharles.Forsyth void outcode(Tree*, int);
14*74a4d8c2SCharles.Forsyth void codeswitch(Tree*, int);
15*74a4d8c2SCharles.Forsyth int iscase(Tree*);
16*74a4d8c2SCharles.Forsyth Code *codecopy(Code*);
17*74a4d8c2SCharles.Forsyth void codefree(Code*);
18*74a4d8c2SCharles.Forsyth
19*74a4d8c2SCharles.Forsyth int codep, ncode;
20*74a4d8c2SCharles.Forsyth Code *codebuf;
21*74a4d8c2SCharles.Forsyth
22*74a4d8c2SCharles.Forsyth int
morecode(void)23*74a4d8c2SCharles.Forsyth morecode(void)
24*74a4d8c2SCharles.Forsyth {
25*74a4d8c2SCharles.Forsyth ncode+=100;
26*74a4d8c2SCharles.Forsyth codebuf=realloc(codebuf, ncode*sizeof codebuf[0]);
27*74a4d8c2SCharles.Forsyth if(codebuf==0)
28*74a4d8c2SCharles.Forsyth panic("Can't realloc %d bytes in morecode!",
29*74a4d8c2SCharles.Forsyth ncode*sizeof codebuf[0]);
30*74a4d8c2SCharles.Forsyth return 0; /* not used */
31*74a4d8c2SCharles.Forsyth }
32*74a4d8c2SCharles.Forsyth
33*74a4d8c2SCharles.Forsyth void
stuffdot(int a)34*74a4d8c2SCharles.Forsyth stuffdot(int a)
35*74a4d8c2SCharles.Forsyth {
36*74a4d8c2SCharles.Forsyth if(a<0 || codep<=a) panic("Bad address %d in stuffdot", a);
37*74a4d8c2SCharles.Forsyth codebuf[a].i=codep;
38*74a4d8c2SCharles.Forsyth }
39*74a4d8c2SCharles.Forsyth
40*74a4d8c2SCharles.Forsyth int
compile(Tree * t)41*74a4d8c2SCharles.Forsyth compile(Tree *t)
42*74a4d8c2SCharles.Forsyth {
43*74a4d8c2SCharles.Forsyth ncode=100;
44*74a4d8c2SCharles.Forsyth codebuf=malloc(ncode*sizeof codebuf[0]);
45*74a4d8c2SCharles.Forsyth codep=0;
46*74a4d8c2SCharles.Forsyth emiti(0); /* reference count */
47*74a4d8c2SCharles.Forsyth outcode(t, flag['e']?1:0);
48*74a4d8c2SCharles.Forsyth if(nerror){
49*74a4d8c2SCharles.Forsyth free(codebuf);
50*74a4d8c2SCharles.Forsyth return 0;
51*74a4d8c2SCharles.Forsyth }
52*74a4d8c2SCharles.Forsyth /* readhere(); */
53*74a4d8c2SCharles.Forsyth emitf(Xreturn);
54*74a4d8c2SCharles.Forsyth emitf(0);
55*74a4d8c2SCharles.Forsyth return 1;
56*74a4d8c2SCharles.Forsyth }
57*74a4d8c2SCharles.Forsyth
58*74a4d8c2SCharles.Forsyth void
cleanhere(char * f)59*74a4d8c2SCharles.Forsyth cleanhere(char *f)
60*74a4d8c2SCharles.Forsyth {
61*74a4d8c2SCharles.Forsyth emitf(Xdelhere);
62*74a4d8c2SCharles.Forsyth emits(strdup(f));
63*74a4d8c2SCharles.Forsyth }
64*74a4d8c2SCharles.Forsyth
65*74a4d8c2SCharles.Forsyth char *
fnstr(Tree * t)66*74a4d8c2SCharles.Forsyth fnstr(Tree *t)
67*74a4d8c2SCharles.Forsyth {
68*74a4d8c2SCharles.Forsyth Io *f=openstr();
69*74a4d8c2SCharles.Forsyth char *v;
70*74a4d8c2SCharles.Forsyth extern char nl;
71*74a4d8c2SCharles.Forsyth char svnl=nl;
72*74a4d8c2SCharles.Forsyth
73*74a4d8c2SCharles.Forsyth nl=';';
74*74a4d8c2SCharles.Forsyth pfmt(f, "%t", t);
75*74a4d8c2SCharles.Forsyth nl=svnl;
76*74a4d8c2SCharles.Forsyth v=f->strp;
77*74a4d8c2SCharles.Forsyth f->strp=0;
78*74a4d8c2SCharles.Forsyth closeio(f);
79*74a4d8c2SCharles.Forsyth return v;
80*74a4d8c2SCharles.Forsyth }
81*74a4d8c2SCharles.Forsyth
82*74a4d8c2SCharles.Forsyth void
outcode(Tree * t,int eflag)83*74a4d8c2SCharles.Forsyth outcode(Tree *t, int eflag)
84*74a4d8c2SCharles.Forsyth {
85*74a4d8c2SCharles.Forsyth int p, q;
86*74a4d8c2SCharles.Forsyth Tree *tt;
87*74a4d8c2SCharles.Forsyth
88*74a4d8c2SCharles.Forsyth if(t==0)
89*74a4d8c2SCharles.Forsyth return;
90*74a4d8c2SCharles.Forsyth if(t->type != NOT && t->type != ';')
91*74a4d8c2SCharles.Forsyth runq->iflast=0;
92*74a4d8c2SCharles.Forsyth switch(t->type){
93*74a4d8c2SCharles.Forsyth default:
94*74a4d8c2SCharles.Forsyth pfmt(err, "bad type %d in outcode\n", t->type);
95*74a4d8c2SCharles.Forsyth break;
96*74a4d8c2SCharles.Forsyth case '$':
97*74a4d8c2SCharles.Forsyth emitf(Xmark);
98*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
99*74a4d8c2SCharles.Forsyth emitf(Xdol);
100*74a4d8c2SCharles.Forsyth break;
101*74a4d8c2SCharles.Forsyth case '"':
102*74a4d8c2SCharles.Forsyth emitf(Xmark);
103*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
104*74a4d8c2SCharles.Forsyth emitf(Xqdol);
105*74a4d8c2SCharles.Forsyth break;
106*74a4d8c2SCharles.Forsyth case SUB:
107*74a4d8c2SCharles.Forsyth emitf(Xmark);
108*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
109*74a4d8c2SCharles.Forsyth emitf(Xmark);
110*74a4d8c2SCharles.Forsyth outcode(c1, eflag);
111*74a4d8c2SCharles.Forsyth emitf(Xsub);
112*74a4d8c2SCharles.Forsyth break;
113*74a4d8c2SCharles.Forsyth case '&':
114*74a4d8c2SCharles.Forsyth emitf(Xasync);
115*74a4d8c2SCharles.Forsyth emits(fnstr(c0));
116*74a4d8c2SCharles.Forsyth /*
117*74a4d8c2SCharles.Forsyth p=emiti(0);
118*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
119*74a4d8c2SCharles.Forsyth emitf(Xexit);
120*74a4d8c2SCharles.Forsyth stuffdot(p);
121*74a4d8c2SCharles.Forsyth */
122*74a4d8c2SCharles.Forsyth break;
123*74a4d8c2SCharles.Forsyth case ';':
124*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
125*74a4d8c2SCharles.Forsyth outcode(c1, eflag);
126*74a4d8c2SCharles.Forsyth break;
127*74a4d8c2SCharles.Forsyth case '^':
128*74a4d8c2SCharles.Forsyth emitf(Xmark);
129*74a4d8c2SCharles.Forsyth outcode(c1, eflag);
130*74a4d8c2SCharles.Forsyth emitf(Xmark);
131*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
132*74a4d8c2SCharles.Forsyth emitf(Xconc);
133*74a4d8c2SCharles.Forsyth break;
134*74a4d8c2SCharles.Forsyth case '`':
135*74a4d8c2SCharles.Forsyth emitf(Xbackq);
136*74a4d8c2SCharles.Forsyth emits(fnstr(c0));
137*74a4d8c2SCharles.Forsyth /*
138*74a4d8c2SCharles.Forsyth p=emiti(0);
139*74a4d8c2SCharles.Forsyth outcode(c0, 0);
140*74a4d8c2SCharles.Forsyth emitf(Xexit);
141*74a4d8c2SCharles.Forsyth stuffdot(p);
142*74a4d8c2SCharles.Forsyth */
143*74a4d8c2SCharles.Forsyth break;
144*74a4d8c2SCharles.Forsyth case ANDAND:
145*74a4d8c2SCharles.Forsyth outcode(c0, 0);
146*74a4d8c2SCharles.Forsyth emitf(Xtrue);
147*74a4d8c2SCharles.Forsyth p=emiti(0);
148*74a4d8c2SCharles.Forsyth outcode(c1, eflag);
149*74a4d8c2SCharles.Forsyth stuffdot(p);
150*74a4d8c2SCharles.Forsyth break;
151*74a4d8c2SCharles.Forsyth case ARGLIST:
152*74a4d8c2SCharles.Forsyth outcode(c1, eflag);
153*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
154*74a4d8c2SCharles.Forsyth break;
155*74a4d8c2SCharles.Forsyth case BANG:
156*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
157*74a4d8c2SCharles.Forsyth emitf(Xbang);
158*74a4d8c2SCharles.Forsyth break;
159*74a4d8c2SCharles.Forsyth case PCMD:
160*74a4d8c2SCharles.Forsyth case BRACE:
161*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
162*74a4d8c2SCharles.Forsyth break;
163*74a4d8c2SCharles.Forsyth case COUNT:
164*74a4d8c2SCharles.Forsyth emitf(Xmark);
165*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
166*74a4d8c2SCharles.Forsyth emitf(Xcount);
167*74a4d8c2SCharles.Forsyth break;
168*74a4d8c2SCharles.Forsyth case FN:
169*74a4d8c2SCharles.Forsyth emitf(Xmark);
170*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
171*74a4d8c2SCharles.Forsyth if(c1){
172*74a4d8c2SCharles.Forsyth emitf(Xfn);
173*74a4d8c2SCharles.Forsyth p=emiti(0);
174*74a4d8c2SCharles.Forsyth emits(fnstr(c1));
175*74a4d8c2SCharles.Forsyth outcode(c1, eflag);
176*74a4d8c2SCharles.Forsyth emitf(Xunlocal); /* get rid of $* */
177*74a4d8c2SCharles.Forsyth emitf(Xreturn);
178*74a4d8c2SCharles.Forsyth stuffdot(p);
179*74a4d8c2SCharles.Forsyth }
180*74a4d8c2SCharles.Forsyth else
181*74a4d8c2SCharles.Forsyth emitf(Xdelfn);
182*74a4d8c2SCharles.Forsyth break;
183*74a4d8c2SCharles.Forsyth case IF:
184*74a4d8c2SCharles.Forsyth outcode(c0, 0);
185*74a4d8c2SCharles.Forsyth emitf(Xif);
186*74a4d8c2SCharles.Forsyth p=emiti(0);
187*74a4d8c2SCharles.Forsyth outcode(c1, eflag);
188*74a4d8c2SCharles.Forsyth emitf(Xwastrue);
189*74a4d8c2SCharles.Forsyth stuffdot(p);
190*74a4d8c2SCharles.Forsyth break;
191*74a4d8c2SCharles.Forsyth case NOT:
192*74a4d8c2SCharles.Forsyth if(!runq->iflast) yyerror("`if not' does not follow `if(...)'");
193*74a4d8c2SCharles.Forsyth emitf(Xifnot);
194*74a4d8c2SCharles.Forsyth p=emiti(0);
195*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
196*74a4d8c2SCharles.Forsyth stuffdot(p);
197*74a4d8c2SCharles.Forsyth break;
198*74a4d8c2SCharles.Forsyth case OROR:
199*74a4d8c2SCharles.Forsyth outcode(c0, 0);
200*74a4d8c2SCharles.Forsyth emitf(Xfalse);
201*74a4d8c2SCharles.Forsyth p=emiti(0);
202*74a4d8c2SCharles.Forsyth outcode(c1, eflag);
203*74a4d8c2SCharles.Forsyth stuffdot(p);
204*74a4d8c2SCharles.Forsyth break;
205*74a4d8c2SCharles.Forsyth case PAREN:
206*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
207*74a4d8c2SCharles.Forsyth break;
208*74a4d8c2SCharles.Forsyth case SIMPLE:
209*74a4d8c2SCharles.Forsyth emitf(Xmark);
210*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
211*74a4d8c2SCharles.Forsyth emitf(Xsimple);
212*74a4d8c2SCharles.Forsyth if(eflag) emitf(Xeflag);
213*74a4d8c2SCharles.Forsyth break;
214*74a4d8c2SCharles.Forsyth case SUBSHELL:
215*74a4d8c2SCharles.Forsyth emitf(Xsubshell);
216*74a4d8c2SCharles.Forsyth emits(fnstr(c0));
217*74a4d8c2SCharles.Forsyth /*
218*74a4d8c2SCharles.Forsyth p=emiti(0);
219*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
220*74a4d8c2SCharles.Forsyth emitf(Xexit);
221*74a4d8c2SCharles.Forsyth stuffdot(p);
222*74a4d8c2SCharles.Forsyth */
223*74a4d8c2SCharles.Forsyth if(eflag) emitf(Xeflag);
224*74a4d8c2SCharles.Forsyth break;
225*74a4d8c2SCharles.Forsyth case SWITCH:
226*74a4d8c2SCharles.Forsyth codeswitch(t, eflag);
227*74a4d8c2SCharles.Forsyth break;
228*74a4d8c2SCharles.Forsyth case TWIDDLE:
229*74a4d8c2SCharles.Forsyth emitf(Xmark);
230*74a4d8c2SCharles.Forsyth outcode(c1, eflag);
231*74a4d8c2SCharles.Forsyth emitf(Xmark);
232*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
233*74a4d8c2SCharles.Forsyth emitf(Xmatch);
234*74a4d8c2SCharles.Forsyth if(eflag) emitf(Xeflag);
235*74a4d8c2SCharles.Forsyth break;
236*74a4d8c2SCharles.Forsyth case WHILE:
237*74a4d8c2SCharles.Forsyth q=codep;
238*74a4d8c2SCharles.Forsyth emitf(Xsettrue);
239*74a4d8c2SCharles.Forsyth outcode(c0, 0);
240*74a4d8c2SCharles.Forsyth emitf(Xtrue);
241*74a4d8c2SCharles.Forsyth p=emiti(0);
242*74a4d8c2SCharles.Forsyth outcode(c1, eflag);
243*74a4d8c2SCharles.Forsyth emitf(Xjump);
244*74a4d8c2SCharles.Forsyth emiti(q);
245*74a4d8c2SCharles.Forsyth stuffdot(p);
246*74a4d8c2SCharles.Forsyth break;
247*74a4d8c2SCharles.Forsyth case WORDS:
248*74a4d8c2SCharles.Forsyth outcode(c1, eflag);
249*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
250*74a4d8c2SCharles.Forsyth break;
251*74a4d8c2SCharles.Forsyth case FOR:
252*74a4d8c2SCharles.Forsyth emitf(Xmark);
253*74a4d8c2SCharles.Forsyth if(c1){
254*74a4d8c2SCharles.Forsyth outcode(c1, eflag);
255*74a4d8c2SCharles.Forsyth emitf(Xglob);
256*74a4d8c2SCharles.Forsyth }
257*74a4d8c2SCharles.Forsyth else{
258*74a4d8c2SCharles.Forsyth emitf(Xmark);
259*74a4d8c2SCharles.Forsyth emitf(Xword);
260*74a4d8c2SCharles.Forsyth emits(strdup("*"));
261*74a4d8c2SCharles.Forsyth emitf(Xdol);
262*74a4d8c2SCharles.Forsyth }
263*74a4d8c2SCharles.Forsyth emitf(Xmark); /* dummy value for Xlocal */
264*74a4d8c2SCharles.Forsyth emitf(Xmark);
265*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
266*74a4d8c2SCharles.Forsyth emitf(Xlocal);
267*74a4d8c2SCharles.Forsyth p=emitf(Xfor);
268*74a4d8c2SCharles.Forsyth q=emiti(0);
269*74a4d8c2SCharles.Forsyth outcode(c2, eflag);
270*74a4d8c2SCharles.Forsyth emitf(Xjump);
271*74a4d8c2SCharles.Forsyth emiti(p);
272*74a4d8c2SCharles.Forsyth stuffdot(q);
273*74a4d8c2SCharles.Forsyth emitf(Xunlocal);
274*74a4d8c2SCharles.Forsyth break;
275*74a4d8c2SCharles.Forsyth case WORD:
276*74a4d8c2SCharles.Forsyth emitf(Xword);
277*74a4d8c2SCharles.Forsyth emits(strdup(t->str));
278*74a4d8c2SCharles.Forsyth break;
279*74a4d8c2SCharles.Forsyth case DUP:
280*74a4d8c2SCharles.Forsyth if(t->rtype==DUPFD) {
281*74a4d8c2SCharles.Forsyth emitf(Xdup);
282*74a4d8c2SCharles.Forsyth emiti(t->fd0);
283*74a4d8c2SCharles.Forsyth emiti(t->fd1);
284*74a4d8c2SCharles.Forsyth } else { /* t->rtype == CLOSE */
285*74a4d8c2SCharles.Forsyth emitf(Xclose);
286*74a4d8c2SCharles.Forsyth emiti(t->fd0);
287*74a4d8c2SCharles.Forsyth }
288*74a4d8c2SCharles.Forsyth outcode(c1, eflag);
289*74a4d8c2SCharles.Forsyth emitf(Xpopredir);
290*74a4d8c2SCharles.Forsyth break;
291*74a4d8c2SCharles.Forsyth /*
292*74a4d8c2SCharles.Forsyth case PIPEFD:
293*74a4d8c2SCharles.Forsyth emitf(Xpipefd);
294*74a4d8c2SCharles.Forsyth emiti(t->rtype);
295*74a4d8c2SCharles.Forsyth p=emiti(0);
296*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
297*74a4d8c2SCharles.Forsyth emitf(Xexit);
298*74a4d8c2SCharles.Forsyth stuffdot(p);
299*74a4d8c2SCharles.Forsyth break;
300*74a4d8c2SCharles.Forsyth */
301*74a4d8c2SCharles.Forsyth case REDIR:
302*74a4d8c2SCharles.Forsyth emitf(Xmark);
303*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
304*74a4d8c2SCharles.Forsyth emitf(Xglob);
305*74a4d8c2SCharles.Forsyth switch(t->rtype){
306*74a4d8c2SCharles.Forsyth case APPEND:
307*74a4d8c2SCharles.Forsyth emitf(Xappend);
308*74a4d8c2SCharles.Forsyth break;
309*74a4d8c2SCharles.Forsyth case WRITE:
310*74a4d8c2SCharles.Forsyth emitf(Xwrite);
311*74a4d8c2SCharles.Forsyth break;
312*74a4d8c2SCharles.Forsyth case READ:
313*74a4d8c2SCharles.Forsyth case HERE:
314*74a4d8c2SCharles.Forsyth emitf(Xread);
315*74a4d8c2SCharles.Forsyth break;
316*74a4d8c2SCharles.Forsyth }
317*74a4d8c2SCharles.Forsyth emiti(t->fd0);
318*74a4d8c2SCharles.Forsyth outcode(c1, eflag);
319*74a4d8c2SCharles.Forsyth emitf(Xpopredir);
320*74a4d8c2SCharles.Forsyth break;
321*74a4d8c2SCharles.Forsyth case '=':
322*74a4d8c2SCharles.Forsyth tt=t;
323*74a4d8c2SCharles.Forsyth for(;t && t->type=='=';t=c2)
324*74a4d8c2SCharles.Forsyth ;
325*74a4d8c2SCharles.Forsyth if(t){
326*74a4d8c2SCharles.Forsyth for(t=tt;t->type=='=';t=c2){
327*74a4d8c2SCharles.Forsyth emitf(Xmark);
328*74a4d8c2SCharles.Forsyth outcode(c1, eflag);
329*74a4d8c2SCharles.Forsyth emitf(Xmark);
330*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
331*74a4d8c2SCharles.Forsyth emitf(Xlocal);
332*74a4d8c2SCharles.Forsyth }
333*74a4d8c2SCharles.Forsyth t=tt;
334*74a4d8c2SCharles.Forsyth outcode(c2, eflag);
335*74a4d8c2SCharles.Forsyth for(;t->type=='=';t=c2)
336*74a4d8c2SCharles.Forsyth emitf(Xunlocal);
337*74a4d8c2SCharles.Forsyth }
338*74a4d8c2SCharles.Forsyth else{
339*74a4d8c2SCharles.Forsyth for(t=tt;t;t=c2){
340*74a4d8c2SCharles.Forsyth emitf(Xmark);
341*74a4d8c2SCharles.Forsyth outcode(c1, eflag);
342*74a4d8c2SCharles.Forsyth emitf(Xmark);
343*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
344*74a4d8c2SCharles.Forsyth emitf(Xassign);
345*74a4d8c2SCharles.Forsyth }
346*74a4d8c2SCharles.Forsyth }
347*74a4d8c2SCharles.Forsyth t=tt; /* so tests below will work */
348*74a4d8c2SCharles.Forsyth break;
349*74a4d8c2SCharles.Forsyth case PIPE:
350*74a4d8c2SCharles.Forsyth emitf(Xpipe);
351*74a4d8c2SCharles.Forsyth emiti(t->fd0);
352*74a4d8c2SCharles.Forsyth emiti(t->fd1);
353*74a4d8c2SCharles.Forsyth emits(fnstr(c0));
354*74a4d8c2SCharles.Forsyth q=emiti(0);
355*74a4d8c2SCharles.Forsyth /*
356*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
357*74a4d8c2SCharles.Forsyth emitf(Xexit);
358*74a4d8c2SCharles.Forsyth stuffdot(p);
359*74a4d8c2SCharles.Forsyth */
360*74a4d8c2SCharles.Forsyth outcode(c1, eflag);
361*74a4d8c2SCharles.Forsyth emitf(Xreturn);
362*74a4d8c2SCharles.Forsyth stuffdot(q);
363*74a4d8c2SCharles.Forsyth emitf(Xpipewait);
364*74a4d8c2SCharles.Forsyth break;
365*74a4d8c2SCharles.Forsyth }
366*74a4d8c2SCharles.Forsyth if(t->type!=NOT && t->type!=';')
367*74a4d8c2SCharles.Forsyth runq->iflast=t->type==IF;
368*74a4d8c2SCharles.Forsyth else if(c0) runq->iflast=c0->type==IF;
369*74a4d8c2SCharles.Forsyth }
370*74a4d8c2SCharles.Forsyth
371*74a4d8c2SCharles.Forsyth /*
372*74a4d8c2SCharles.Forsyth * switch code looks like this:
373*74a4d8c2SCharles.Forsyth * Xmark
374*74a4d8c2SCharles.Forsyth * (get switch value)
375*74a4d8c2SCharles.Forsyth * Xjump 1f
376*74a4d8c2SCharles.Forsyth * out: Xjump leave
377*74a4d8c2SCharles.Forsyth * 1: Xmark
378*74a4d8c2SCharles.Forsyth * (get case values)
379*74a4d8c2SCharles.Forsyth * Xcase 1f
380*74a4d8c2SCharles.Forsyth * (commands)
381*74a4d8c2SCharles.Forsyth * Xjump out
382*74a4d8c2SCharles.Forsyth * 1: Xmark
383*74a4d8c2SCharles.Forsyth * (get case values)
384*74a4d8c2SCharles.Forsyth * Xcase 1f
385*74a4d8c2SCharles.Forsyth * (commands)
386*74a4d8c2SCharles.Forsyth * Xjump out
387*74a4d8c2SCharles.Forsyth * 1:
388*74a4d8c2SCharles.Forsyth * leave:
389*74a4d8c2SCharles.Forsyth * Xpopm
390*74a4d8c2SCharles.Forsyth */
391*74a4d8c2SCharles.Forsyth void
codeswitch(Tree * t,int eflag)392*74a4d8c2SCharles.Forsyth codeswitch(Tree *t, int eflag)
393*74a4d8c2SCharles.Forsyth {
394*74a4d8c2SCharles.Forsyth int leave; /* patch jump address to leave switch */
395*74a4d8c2SCharles.Forsyth int out; /* jump here to leave switch */
396*74a4d8c2SCharles.Forsyth int nextcase; /* patch jump address to next case */
397*74a4d8c2SCharles.Forsyth Tree *tt;
398*74a4d8c2SCharles.Forsyth if(c1->child[0]->type!=';'
399*74a4d8c2SCharles.Forsyth || !iscase(c1->child[0]->child[0])){
400*74a4d8c2SCharles.Forsyth yyerror("case missing in switch");
401*74a4d8c2SCharles.Forsyth return;
402*74a4d8c2SCharles.Forsyth }
403*74a4d8c2SCharles.Forsyth emitf(Xmark);
404*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
405*74a4d8c2SCharles.Forsyth emitf(Xjump);
406*74a4d8c2SCharles.Forsyth nextcase=emiti(0);
407*74a4d8c2SCharles.Forsyth out=emitf(Xjump);
408*74a4d8c2SCharles.Forsyth leave=emiti(0);
409*74a4d8c2SCharles.Forsyth stuffdot(nextcase);
410*74a4d8c2SCharles.Forsyth t=c1->child[0];
411*74a4d8c2SCharles.Forsyth while(t->type==';'){
412*74a4d8c2SCharles.Forsyth tt=c1;
413*74a4d8c2SCharles.Forsyth emitf(Xmark);
414*74a4d8c2SCharles.Forsyth for(t=c0->child[0];t->type==ARGLIST;t=c0) outcode(c1, eflag);
415*74a4d8c2SCharles.Forsyth emitf(Xcase);
416*74a4d8c2SCharles.Forsyth nextcase=emiti(0);
417*74a4d8c2SCharles.Forsyth t=tt;
418*74a4d8c2SCharles.Forsyth for(;;){
419*74a4d8c2SCharles.Forsyth if(t->type==';'){
420*74a4d8c2SCharles.Forsyth if(iscase(c0)) break;
421*74a4d8c2SCharles.Forsyth outcode(c0, eflag);
422*74a4d8c2SCharles.Forsyth t=c1;
423*74a4d8c2SCharles.Forsyth }
424*74a4d8c2SCharles.Forsyth else{
425*74a4d8c2SCharles.Forsyth outcode(t, eflag);
426*74a4d8c2SCharles.Forsyth break;
427*74a4d8c2SCharles.Forsyth }
428*74a4d8c2SCharles.Forsyth }
429*74a4d8c2SCharles.Forsyth emitf(Xjump);
430*74a4d8c2SCharles.Forsyth emiti(out);
431*74a4d8c2SCharles.Forsyth stuffdot(nextcase);
432*74a4d8c2SCharles.Forsyth }
433*74a4d8c2SCharles.Forsyth stuffdot(leave);
434*74a4d8c2SCharles.Forsyth emitf(Xpopm);
435*74a4d8c2SCharles.Forsyth }
436*74a4d8c2SCharles.Forsyth
437*74a4d8c2SCharles.Forsyth int
iscase(Tree * t)438*74a4d8c2SCharles.Forsyth iscase(Tree *t)
439*74a4d8c2SCharles.Forsyth {
440*74a4d8c2SCharles.Forsyth if(t->type!=SIMPLE)
441*74a4d8c2SCharles.Forsyth return 0;
442*74a4d8c2SCharles.Forsyth do
443*74a4d8c2SCharles.Forsyth t=c0;
444*74a4d8c2SCharles.Forsyth while(t->type==ARGLIST);
445*74a4d8c2SCharles.Forsyth
446*74a4d8c2SCharles.Forsyth return t->type==WORD && !t->quoted && strcmp(t->str, "case")==0;
447*74a4d8c2SCharles.Forsyth }
448*74a4d8c2SCharles.Forsyth
449*74a4d8c2SCharles.Forsyth Code *
codecopy(Code * cp)450*74a4d8c2SCharles.Forsyth codecopy(Code *cp)
451*74a4d8c2SCharles.Forsyth {
452*74a4d8c2SCharles.Forsyth cp[0].i++;
453*74a4d8c2SCharles.Forsyth return cp;
454*74a4d8c2SCharles.Forsyth }
455*74a4d8c2SCharles.Forsyth
456*74a4d8c2SCharles.Forsyth void
codefree(Code * cp)457*74a4d8c2SCharles.Forsyth codefree(Code *cp)
458*74a4d8c2SCharles.Forsyth {
459*74a4d8c2SCharles.Forsyth Code *p;
460*74a4d8c2SCharles.Forsyth
461*74a4d8c2SCharles.Forsyth if(--cp[0].i!=0)
462*74a4d8c2SCharles.Forsyth return;
463*74a4d8c2SCharles.Forsyth
464*74a4d8c2SCharles.Forsyth for(p=cp+1;p->f;){
465*74a4d8c2SCharles.Forsyth if(p->f==Xappend || p->f==Xclose || p->f==Xread || p->f==Xwrite
466*74a4d8c2SCharles.Forsyth || p->f==Xasync || p->f==Xcase || p->f==Xfalse
467*74a4d8c2SCharles.Forsyth || p->f==Xfor || p->f==Xjump
468*74a4d8c2SCharles.Forsyth || p->f==Xsubshell || p->f==Xtrue)
469*74a4d8c2SCharles.Forsyth p+=2;
470*74a4d8c2SCharles.Forsyth else if(p->f==Xdup || p->f==Xpipefd)
471*74a4d8c2SCharles.Forsyth p+=3;
472*74a4d8c2SCharles.Forsyth else if(p->f==Xpipe) {
473*74a4d8c2SCharles.Forsyth free(p[3].s);
474*74a4d8c2SCharles.Forsyth p+=5;
475*74a4d8c2SCharles.Forsyth } else if(p->f==Xword || p->f==Xdelhere || p->f==Xbackq) {
476*74a4d8c2SCharles.Forsyth free(p[1].s);
477*74a4d8c2SCharles.Forsyth p+=2;
478*74a4d8c2SCharles.Forsyth } else if(p->f==Xfn){
479*74a4d8c2SCharles.Forsyth free(p[2].s);
480*74a4d8c2SCharles.Forsyth p+=3;
481*74a4d8c2SCharles.Forsyth } else
482*74a4d8c2SCharles.Forsyth p++;
483*74a4d8c2SCharles.Forsyth }
484*74a4d8c2SCharles.Forsyth
485*74a4d8c2SCharles.Forsyth free(cp);
486*74a4d8c2SCharles.Forsyth }
487