/* 1991 ACM Finals, Problem G, Code Generation Ed Karrels, Oct. 1996 */ #include #include typedef enum { VAR, BINOP, UNIOP, TEMP } Types; struct { Types type; int val; } stack[1000]; int tos = 1; int tmp_no = 1; int accum = 0; void Store() { printf("ST $%d\n", tmp_no); stack[accum].val = tmp_no; tmp_no++; accum = 0; } int Push(Types type, int val) { stack[tos].type = type; stack[tos].val = val; return tos++; } void Pop() { tos--; if (stack[tos].type == TEMP && stack[tos].val != 0) tmp_no--; } char *StackVal(int stack_pos) { static char str[3]; if (stack[stack_pos].type == TEMP) { sprintf(str, "$%d", stack[stack_pos].val); } else { sprintf(str, "%c", stack[stack_pos].val); } return str; } int Token(Types *type) { int c = getchar(); if (c == '\n' || c == EOF) return c; if (isalpha(c)) { *type = VAR; return toupper(c); } if (c == '@') { *type = UNIOP; return 'N'; } else { *type = BINOP; return (c=='+') ? 'A' : (c=='-') ? 'S' : (c=='*') ? 'M' : 'D'; } } int main() { Types type; int tok; tok = Token(&type); while (tok != EOF) { while (tok != '\n') { switch (type) { case VAR: Push(VAR, tok); break; case UNIOP: if (accum && accum != tos-1) Store(); if (accum) { printf("N\n"); } else { printf("L %s\n", StackVal(tos-1)); printf("N\n"); } Pop(); accum = Push(TEMP, 0); break; case BINOP: if (accum && accum != tos-1 && accum != tos-2) Store(); if (accum == tos-2) { printf("%c %s\n", tok, StackVal(tos-1)); } else if (accum == tos-1) { if (tok == 'A' || tok == 'M') { printf("%c %s\n", tok, StackVal(tos-2)); } else { if (tok == 'S') { printf("N\n"); printf("A %s\n", StackVal(tos-2)); } else { Store(); printf("L %s\n", StackVal(tos-2)); printf("D %s\n", StackVal(tos-1)); } } } else { printf("L %s\n", StackVal(tos-2)); printf("%c %s\n", tok, StackVal(tos-1)); } Pop(); Pop(); accum = Push(TEMP, 0); break; } tok = Token(&type); } putchar('\n'); tos = 1; accum = 0; tmp_no = 1; tok = Token(&type); } return 0; }