#include "c.h" static int getrule(Node p, int nt) { int rulenum; assert(p); rulenum = (*IR->x._rule)(p->x.state, nt); if (!rulenum) { fprint(stderr, "(%x->op=%s at %w is corrupt.)\n", p, opname(p->op), &src); prettytree(p); assert(0); } return rulenum; } void emitTree(Node p, int nt, int force) { int rulenum; short *nts; char *fmt; int i; Node kids[6]; rulenum = getrule(p, nt); if (!(IR->x._isinstruction[rulenum] || force)) { return; } nts = IR->x._nts[rulenum]; fmt = IR->x._templates[rulenum]; assert(fmt); // if (p->x.emitted) { // prettytree(p); // assert(0); // } for (i = 0; i < 6; i++) { kids[i] = NULL; } (*IR->x._kids)(p, rulenum, kids); for (i = 0; kids[i]; i++) { emitTree(kids[i], nts[i], 0); } if (*fmt == '#') (*IR->x.emit2)(p); else if (fmt[0] == '\n' && fmt[1] == '\0') /* Emit nothing */; else { for (; *fmt; fmt++) if (*fmt != '%') (void)putchar(*fmt); else if (*++fmt == 'F') print("%d", framesize); else if (*fmt >= '0' && *fmt <= '9') emitTree(kids[*fmt - '0'], nts[*fmt - '0'], 1); else if (*fmt >= 'a' && *fmt < 'a' + NELEMS(p->syms)) if (p->syms[*fmt - 'a']) fputs(p->syms[*fmt - 'a']->x.name, stdout); else fputs("No symbol", stdout); else (void)putchar(*fmt); } return; } void stackemit(Node forest) { Node p; for (p = forest; p; p = p->link) { if (generic(p->op) != NOOP) { assert(!p->x.emitted); (*IR->x._label)(p); emitTree(p, 1, 0); p->x.emitted = 1; } } }