Tree asgntree(int op, Tree l, Tree r) { Type aty, ty; r = pointer(r); ty = assign(l->type, r); if (ty) r = cast(r, ty); else { typeerror(ASGN, l, r); if (r->type == voidtype) r = retype(r, inttype); ty = r->type; } if (l->op != FIELD) l = lvalue(l); aty = l->type; if (isptr(aty)) aty = unqual(aty)->type; if (isconst(aty) || (isstruct(aty) && unqual(aty)->u.sym->u.s.cfields)) { if (isaddrop(l->op) && !l->u.sym->computed && !l->u.sym->generated) error("assignment to const identifier `%s'\n", l->u.sym->name); else error("assignment to const location\n"); } if (l->op == FIELD) { long n = 8 * l->u.field->type->size - fieldsize(l->u.field); if (n > 0 && isunsigned(l->u.field->type)) r = bittree(BAND, r, cnsttree(r->type, (unsigned long)fieldmask(l->u.field))); else if (n > 0) { if (r->op == CNST + I) { n = r->u.v.i; if (n & (1 << (fieldsize(l->u.field) - 1))) n |= ~0UL << fieldsize(l->u.field); r = cnsttree(r->type, n); } else r = shtree(RSH, shtree(LSH, r, cnsttree(inttype, n)), cnsttree(inttype, n)); } } if (isstruct(ty) && isaddrop(l->op) && iscallb(r)) return tree(RIGHT, ty, tree(CALL + B, ty, r->kids[0]->kids[0], l), idtree(l->u.sym)); return tree(mkop(op, ty), ty, l, r); }
static void shtree(union node *n, int ind, char *pfx, FILE *fp) { struct nodelist *lp; char *s; if (n == NULL) return; indent(ind, pfx, fp); switch(n->type) { case NSEMI: s = "; "; goto binop; case NAND: s = " && "; goto binop; case NOR: s = " || "; binop: shtree(n->nbinary.ch1, ind, NULL, fp); /* if (ind < 0) */ fputs(s, fp); shtree(n->nbinary.ch2, ind, NULL, fp); break; case NCMD: shcmd(n, fp); if (ind >= 0) putc('\n', fp); break; case NPIPE: for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { shcmd(lp->n, fp); if (lp->next) fputs(" | ", fp); } if (n->npipe.backgnd) fputs(" &", fp); if (ind >= 0) putc('\n', fp); break; default: fprintf(fp, "<node type %d>", n->type); if (ind >= 0) putc('\n', fp); break; } }
void showtree(union node *n) { trputs("showtree called\n"); shtree(n, 1, NULL, stdout); }
static void sharg(union node *arg, FILE *fp) { char *p; struct nodelist *bqlist; int subtype; if (arg->type != NARG) { printf("<node type %d>\n", arg->type); fflush(stdout); abort(); } bqlist = arg->narg.backquote; for (p = arg->narg.text ; *p ; p++) { switch (*p) { case CTLESC: putc(*++p, fp); break; case CTLVAR: putc('$', fp); putc('{', fp); subtype = *++p; if (subtype == VSLENGTH) putc('#', fp); while (*p != '=') putc(*p++, fp); if (subtype & VSNUL) putc(':', fp); switch (subtype & VSTYPE) { case VSNORMAL: putc('}', fp); break; case VSMINUS: putc('-', fp); break; case VSPLUS: putc('+', fp); break; case VSQUESTION: putc('?', fp); break; case VSASSIGN: putc('=', fp); break; case VSTRIMLEFT: putc('#', fp); break; case VSTRIMLEFTMAX: putc('#', fp); putc('#', fp); break; case VSTRIMRIGHT: putc('%', fp); break; case VSTRIMRIGHTMAX: putc('%', fp); putc('%', fp); break; case VSLENGTH: break; default: printf("<subtype %d>", subtype); } break; case CTLENDVAR: putc('}', fp); break; case CTLBACKQ: case CTLBACKQ|CTLQUOTE: putc('$', fp); putc('(', fp); shtree(bqlist->n, -1, NULL, fp); putc(')', fp); break; default: putc(*p, fp); break; } } }