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