Blame


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