#!/bin/sh # This is a shar archive. # The rest of this file is a shell script which will extract: # # 5_5A.h 5_5B.h 5_5E.h 5_5a.c 5_5a.cmp 5_5a0.c 5_5a1.c 5_5a2.c 5_5a3.c 5_5a4.c 5_5a5.c 5_5a_all.c 5_5a_pr.c 5_5b.c 5_5b.cmp 5_5b1.c 5_5b2.c 5_5b_pr.c 5_5c.cmp 5_5c1.c 5_5c2.c 5_5c3.c 5_5c3_6.c 5_5c3_W.c 5_5c3a.h 5_5c3b.h 5_5c3i.c 5_5c3iac.c 5_5c3iah.h 5_5c3sth.h 5_5c3sth6.h 5_5cO1.c 5_5cO2.c 5_5cO3.c 5_5cO4.c 5_5cOa.c 5_5cOb.c 5_5c_pr.c 5_5d.cmp 5_5d.h 5_5d1.c 5_5d2.c 5_5d3.c 5_5d_pr.c 5_5e.cmp 5_5e1.c 5_5e3.c 5_5e4.c 5_5e5.c 5_5e_all.c 5_5f1.c 5_5f2.c 5_5x1.c 5_5x2.c 5_5x3.c 5_5x4.c 5_5x5.c 5_5x6.c intalloc.c intalloc.h intset.c intset.h intset2.c junk.c main.c makefile stackalloc.h # # To extract the files from this shell archive file simply # create a directory for this file, move the archive file # to it and enter the command # # sh filename # # The files will be extracted automatically. # Note: Do not use csh. # # Archive created: Mon Jul 30 23:03:33 EDT 1990 # echo x - 5_5A.h sed 's/^X//' > 5_5A.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // expression evaluator enum exprtype { NUMBER, END, PLUS='+', MINUS='-', MUL='*', DIV='/', LP='(', RP=')' }; !EOF! ls -l 5_5A.h echo x - 5_5B.h sed 's/^X//' > 5_5B.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ struct tree { tree *left, *right; exprtype type; int value; tree() { left = right = 0; } ~tree() { delete left; delete right; } void print(int level); // DELETE }; class expr { tree *head; int evaluated, value; public: expr(char*); ~expr() { delete head; } int eval(); void print(); void eprint(); // DELETE }; struct token { exprtype type; int value; }; !EOF! ls -l 5_5B.h echo x - 5_5E.h sed 's/^X//' > 5_5E.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ struct tree { tree() { } virtual ~tree() { } virtual int eval() { return 0; } virtual void print() { } }; struct unary_op : tree { tree *left; unary_op() { left = 0; } ~unary_op() { delete left; } }; struct binary_op : unary_op { tree *right; binary_op() { right = 0; } ~binary_op() { delete right; } }; struct number_leaf : tree { int value; number_leaf(int v) { value = v; } int eval() { return value; } void print() { cout << "( " << value << " ) "; } }; struct plus_op : binary_op { int eval() { return left->eval() + right->eval(); } void print() { cout << "( "; left->print(); cout << "+ "; right->print(); cout << ") "; } }; struct unary_minus_op : unary_op { int eval() { return - left->eval(); } void print() { cout << "( - "; left->print(); } }; struct binary_minus_op : binary_op { int eval() { return left->eval() - right->eval(); } void print() { cout << "( "; left->print(); cout << "- "; right->print(); cout << ") "; } }; struct mult_op : binary_op { int eval() { return left->eval() * right->eval(); } void print() { cout << "( "; left->print(); cout << "* "; right->print(); cout << ") "; } }; struct div_op : binary_op { int eval() { int l = left->eval(); int r = right->eval(); return (r != 0) ? (l / r) : error("division by 0"); } void print() { cout << "( "; left->print(); cout << "/ "; right->print(); cout << ") "; } }; struct lparen_op : unary_op { int eval() { return left->eval(); } void print() { cout << "( "; left->print(); cout << ") "; } }; class expr { tree *head; int evaluated, value; public: expr(char*); ~expr() { delete head; } int eval(); void print(); }; struct token { exprtype type; int value; }; !EOF! ls -l 5_5E.h echo x - 5_5a.c sed 's/^X//' > 5_5a.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include <5.5A.h> static void treeprint(tree* head) { if (head) switch (head->type) { case PLUS: case MINUS: case DIV: case MULT: cout << "("; treeprint(head->left); cout << chr(head->type); treeprint(head->right); cout << ")"; break; case NEG: cout << "-("; treeprint(head->left); cout << ")"; break; case NUMBER: cout << head->value; break; default: error("unknown type within tree"); break; } else error("null node found"); } void expr:: print() { treeprint(head); } !EOF! ls -l 5_5a.c echo x - 5_5a.cmp sed 's/^X//' > 5_5a.cmp << '!EOF!' x = '' x = ( 0 ) x = 0 x = '1 ' x = ( 1 ) x = 1 x = '2*3 ' x = ( ( 2 ) * ( 3 ) ) x = 6 x = '2-3 ' x = ( ( 2 ) - ( 3 ) ) x = -1 x = '5/2' x = ( ( 5 ) / ( 2 ) ) x = 2 x = '123/4+123*4-3' x = ( ( ( ( 123 ) / ( 4 ) ) + ( ( 123 ) * ( 4 ) ) ) - ( 3 ) ) x = 519 !EOF! ls -l 5_5a.cmp echo x - 5_5a0.c sed 's/^X//' > 5_5a0.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ static token curr_tok; static void get_token(istream&); static tree* get_expr(istream&); static tree* term(istream&); static tree* prim(istream&); !EOF! ls -l 5_5a0.c echo x - 5_5a1.c sed 's/^X//' > 5_5a1.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ tree *expandtree(istream &input) { if (curr_tok.type == END) { if (debug) cout << "expandtree() sees END\n"; // DELETE tree *ret = new tree; ret->type = NUMBER; ret->value = 0; return ret; } else return get_expr(input); } expr:: expr(char* s) { istream input(strlen(s), s); evaluated = 0; get_token(input); head = expandtree(input); if (debug) head->print(0); // DELETE } !EOF! ls -l 5_5a1.c echo x - 5_5a2.c sed 's/^X//' > 5_5a2.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ static void get_token(istream &input) { char ch; do { // skip whitespace if (!input.get(ch)) { curr_tok.type = END; return; } } while (isspace(ch)); switch (ch) { case '*': case '/': case '+': case '-': case '(': case ')': curr_tok.type = ch; if (debug) cout << "get_token() returns '" << chr(ch) << "'\n"; // DELETE return; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': input.putback(ch); input >> curr_tok.value; curr_tok.type = NUMBER; if (debug) cout << "get_token() returns NUMBER='" << curr_tok.value << "'\n"; // DELETE return; default: error("bad token"); curr_tok.type = END; return; } } !EOF! ls -l 5_5a2.c echo x - 5_5a3.c sed 's/^X//' > 5_5a3.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ static tree* get_expr(istream& input) { tree* left = term(input); for (;;) switch (curr_tok.type) { case PLUS: case MINUS: if (debug) cout << "get_expr() sees +/-\n"; // DELETE if (debug) { cout << "get_expr():left:\n"; left->print(0); } // DELETE tree* head = new tree; head->type = curr_tok.type; head->left = left; get_token(input); // eat '+','-' head->right = term(input); left = head; if (debug) { cout << "get_expr():new left:\n"; left->print(0); } // DELETE break; default: // collapse node if (debug) cout << "get_expr() sees other\n"; // DELETE if (debug) { cout << "left:\n"; left->print(0); } // DELETE return left; } } !EOF! ls -l 5_5a3.c echo x - 5_5a4.c sed 's/^X//' > 5_5a4.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ static tree* term(istream& input) { tree* left = prim(input); for (;;) switch (curr_tok.type) { case MUL: case DIV: if (debug) cout << "term() sees +/-\n"; // DELETE if (debug) { cout << "term():left:\n"; left->print(0); } // DELETE tree* head = new tree; head->type = curr_tok.type; head->left = left; get_token(input); // eat '*','/' head->right = prim(input); left = head; if (debug) { cout << "term():new left:\n"; left->print(0); } // DELETE break; default: // collapse node if (debug) cout << "term() sees other\n"; // DELETE if (debug) { cout << "left:\n"; left->print(0); } // DELETE return left; } } !EOF! ls -l 5_5a4.c echo x - 5_5a5.c sed 's/^X//' > 5_5a5.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ static tree* prim(istream& input) { tree* ret = new tree; switch (curr_tok.type) { case NUMBER: if (debug) cout << "prim() sees NUMBER " << curr_tok.value << "\n"; // DELETE ret->type = NUMBER; ret->value = curr_tok.value; get_token(input); // skip number if (debug) { cout << "prim():ret:\n"; ret->print(0); } // DELETE return ret; case MINUS: if (debug) cout << "prim() sees -\n"; // DELETE ret->type = MINUS; get_token(input); // skip '-' ret->left = prim(input); ret->right = 0; if (debug) { cout << "prim():ret:\n"; ret->print(0); } // DELETE return ret; case LP: if (debug) cout << "prim() sees (\n"; // DELETE ret->type = LP; get_token(input); // skip '(' ret->left = get_expr(input); if (curr_tok.type != RP) { error(") expected"); break; } get_token(input); // skip ')' if (debug) { cout << "prim():ret:\n"; ret->print(0); } // DELETE return ret; case END: if (debug) cout << "prim() sees END\n"; // DELETE error("end of expression unexpected"); break; default: if (debug) cout << "prim() sees UNKNOWN\n"; // DELETE error("unknown type within tree"); break; } // error case ret->value = 0; ret->type = NUMBER; return ret; } !EOF! ls -l 5_5a5.c echo x - 5_5a_all.c sed 's/^X//' > 5_5a_all.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include #include #include #include int error(const char *fmt ...); char prefix[512] = "....", *endprefix = &prefix[1]; char *incr() { *endprefix++ = '.'; *endprefix = '\0'; return prefix+1; } char *decr() { *--endprefix = '\0'; return prefix; } char *unctrl(unsigned int c) { static char x[5]; char *p = x; if (c > 0177) *p++ = 'M', *p++ = '-', c -= 0200; if ((c < 040) || (c == 0177)) *p++ = '^', *p++ = c ^ 0100; else *p++ = c; *p = '\0'; return x; } #include "5_5A.h" /* enum exprtype */ #include "5_5B.h" /* class tree, expr, token */ #include "5_5a0.c" /* forward declarations */ #include "5_5a5.c" /* prim() */ #include "5_5a4.c" /* term() */ #include "5_5a3.c" /* get_expr() */ #include "5_5a2.c" /* gettoken() */ #include "5_5a1.c" /* expandtree, expr::expr() */ #include "5_5b2.c" /* treeval() */ #include "5_5b1.c" /* expr::eval() */ #include "main.c" // print the expression tree static char *spaces(int num) { return form("%.*s", num * 3, " "); } void tree::print(int level) { if (this) switch (this->type) { case PLUS: case DIV: case MUL: cout << spaces(level) << chr(this->type) << "\n"; this->left->print(level + 1); this->right->print(level + 1); return; case MINUS: cout << spaces(level) << chr(this->type) << "\n"; if (this->right) { this->left->print(level + 1); this->right->print(level + 1); } else this->left->print(level + 1); return; case NUMBER: cout << spaces(level) << "# " << this->value << "\n"; return; case LP: cout << spaces(level) << chr(this->type) << "\n"; this->left->print(level + 1); return; case RP: case END: default: cout << spaces(level) << chr(this->type) << "\n"; error("invalid type within tree"); break; } else error("NULL node found"); return; } void expr::eprint() { if (debug) head->print(0); } !EOF! ls -l 5_5a_all.c echo x - 5_5a_pr.c sed 's/^X//' > 5_5a_pr.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include #include #include int error(const char *fmt ...); #include "5_5A.h" #include "5_5B.h" #include "5_5c1.c" !EOF! ls -l 5_5a_pr.c echo x - 5_5b.c sed 's/^X//' > 5_5b.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include <5.5A.h> static void treeval(tree* head) { if (head) { switch (head->type) { case PLUS: return treeval(head->left) + treeval(head->right); case MINUS: return treeval(head->left) - treeval(head->right); case DIV: return treeval(head->left) / treeval(head->right); case MULT: return treeval(head->left) * treeval(head->right); case NEG: return -treeval(head->left); case NUMBER: return head->value; default: error("unknown type within tree"); break; } else error("null node found"); return 0; } int expr:: eval() { if (evaluated) return value; value = treeval(head); evaluated++; } !EOF! ls -l 5_5b.c echo x - 5_5b.cmp sed 's/^X//' > 5_5b.cmp << '!EOF!' x = '' x = 0 x = 0 x = '1 ' x = 1 x = 1 x = '2*3 ' x = 2 3 * x = 6 x = '2-3 ' x = 2 3 - x = -1 x = '5/2' x = 5 2 / x = 2 x = '123/4+123*4-3' x = 123 4 / 123 4 * + 3 - x = 519 !EOF! ls -l 5_5b.cmp echo x - 5_5b1.c sed 's/^X//' > 5_5b1.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Evaluate the expression int expr:: eval() { if (!evaluated) { value = treeval(head); evaluated++; } return value; } !EOF! ls -l 5_5b1.c echo x - 5_5b2.c sed 's/^X//' > 5_5b2.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Evaluate the given expression tree static int treeval(tree* head) { if (head) switch (head->type) { case PLUS: return treeval(head->left) + treeval(head->right); case MINUS: if (head->right) return treeval(head->left) - treeval(head->right); else return -treeval(head->left); case DIV: int l = treeval(head->left); int r = treeval(head->right); if (r != 0) return l / r; else return error("division by 0"); case MUL: return treeval(head->left) * treeval(head->right); case NUMBER: return head->value; case LP: return treeval(head->left); case RP: case END: default: error("invalid type within tree"); break; } else error("NULL node found"); return 0; } !EOF! ls -l 5_5b2.c echo x - 5_5b_pr.c sed 's/^X//' > 5_5b_pr.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include #include #include int error(const char *fmt ...); #include "5_5A.h" #include "5_5B.h" #include "5_5c2.c" !EOF! ls -l 5_5b_pr.c echo x - 5_5c.cmp sed 's/^X//' > 5_5c.cmp << '!EOF!' x = '' x = MOVW &0, 0(%sp) MOVW 0(%sp), result x = 0 x = '1 ' x = MOVW &1, 0(%sp) MOVW 0(%sp), result x = 1 x = '2*3 ' x = MOVW &2, 0(%sp) MOVW &3, 4(%sp) MULW2 4(%sp), 0(%sp) MOVW 0(%sp), result x = 6 x = '2-3 ' x = MOVW &2, 0(%sp) MOVW &3, 4(%sp) SUBW2 4(%sp), 0(%sp) MOVW 0(%sp), result x = -1 x = '5/2' x = MOVW &5, 0(%sp) MOVW &2, 4(%sp) DIVW2 4(%sp), 0(%sp) MOVW 0(%sp), result x = 2 x = '123/4+123*4-3' x = MOVW &123, 0(%sp) MOVW &4, 4(%sp) DIVW2 4(%sp), 0(%sp) MOVW &123, 4(%sp) MOVW &4, 8(%sp) MULW2 8(%sp), 4(%sp) ADDW2 4(%sp), 0(%sp) MOVW &3, 4(%sp) SUBW2 4(%sp), 0(%sp) MOVW 0(%sp), result x = 519 !EOF! ls -l 5_5c.cmp echo x - 5_5c1.c sed 's/^X//' > 5_5c1.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // print out the tree in infix format static void infixprint(tree* head) { cout << "( "; if (head) switch (head->type) { case PLUS: case DIV: case MUL: infixprint (head->left); cout << chr (head->type) << " "; infixprint (head->right); break; case MINUS: if (head->right) { infixprint (head->left); cout << "- "; infixprint (head->right); } else { cout << "- "; infixprint (head->left); } break; case NUMBER: cout << head->value; break; case LP: infixprint (head->left); break; case RP: case END: default: error ("invalid type within tree"); break; } else error ("NULL node found"); cout << " ) "; } void expr:: print() { infixprint(head); } !EOF! ls -l 5_5c1.c echo x - 5_5c2.c sed 's/^X//' > 5_5c2.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // print out the tree in postfix format static void postfixprint(tree* head) { if (head) switch (head->type) { case PLUS: case DIV: case MUL: postfixprint(head->left); postfixprint(head->right); cout << chr(head->type); break; case MINUS: postfixprint(head->left); if (head->right) { postfixprint(head->right); cout << "-"; } else cout << "chg"; break; case NUMBER: cout << head->value; break; case LP: postfixprint(head->left); break; case RP: case END: default: error("invalid type within tree"); break; } else error("NULL node found"); cout << " "; } void expr:: print() { postfixprint(head); } !EOF! ls -l 5_5c2.c echo x - 5_5c3.c sed 's/^X//' > 5_5c3.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // print out the tree in assembly format // WE32100 version #ifdef NONLOCAL /* DELETE */ #include #include #else /* DELETE */ #include "intalloc.h" /* DELETE */ #include "stackalloc.h" /* DELETE */ #endif /* DELETE */ // forward declaration of // assemblyprint() for binop() static void assemblyprint(tree* head, stackalloc &curloc, const intalloc *cursp); #ifdef USE8086 /* DELETE */ #include "5_5c3_6.c" /* DELETE */ #else /* DELETE */ #include "5_5c3_W.c" /* EXPAND */ #endif /* DELETE */ // print out the appropriate assembly // language instructions static void assemblyprint(tree* head, stackalloc &curloc, const intalloc *cursp) { if (head) { switch (head->type) { case PLUS: case MUL: case DIV: binop(head, curloc, cursp); break; case MINUS: if (head->right) binop(head, curloc, cursp); else negop(head, curloc, cursp); break; case NUMBER: svnumber(head, curloc); break; case LP: assemblyprint(head->left, curloc, cursp); break; case RP: case END: default: error("invalid type within tree"); break; } } else error("NULL node found"); } void expr:: print() { setup(); intalloc cursp(15, 15); stackalloc stacktop(&cursp); assemblyprint(head, stacktop, &cursp); finishup(stacktop); } !EOF! ls -l 5_5c3.c echo x - 5_5c3_6.c sed 's/^X//' > 5_5c3_6.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // print out the tree in assembly format // 8086 version // initialize for the 8086 // set up register bp for the stack void setup() { cout << "\tpush bp\n" << "\tmov bp, sp\n"; } // finish things up void finishup(stackalloc &stacktop) { cout << "\tmov ax, "; stacktop.print(cout) << "\n"; cout << "\tmov result, ax\n"; cout << "\tpop bp\n"; } // print out a binary operator followed by the // source and destination static void binop(const tree *head, stackalloc &curloc, const intalloc *cursp) { assemblyprint(head->left, curloc, cursp); stackalloc newloc(cursp); assemblyprint(head->right, newloc, cursp); cout << "\tmov ax,"; curloc.print(cout) << "\n"; cout << "\tmov bx,"; newloc.print(cout) << "\n"; switch (head->type) { case PLUS: cout << "\tadd ax, bx\n"; break; case MUL: cout << "\tmul bx\n"; break; case DIV: cout << "\tmov dx, 0\n" << "\tdiv bx\n"; break; case MINUS: cout << "\tsub ax, bx\n"; break; } cout << "\tmov "; curloc.print(cout) << ", ax\n"; } // print out a unary operator followed // by the destination static void negop(const tree *head, stackalloc &curloc, const intalloc *cursp) { stackalloc newloc(cursp); assemblyprint(head->left, newloc, cursp); cout << "\tmov ax, "; newloc.print(cout) << "\n"; cout << "\tneg ax"; cout << "\tmov "; curloc.print(cout) << ", ax\n"; } // store a number node at the current location static void svnumber(tree* head, stackalloc &curloc) { cout << "\tmov "; curloc.print(cout) << ", " << head->value << "\n"; } !EOF! ls -l 5_5c3_6.c echo x - 5_5c3_W.c sed 's/^X//' > 5_5c3_W.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // initialize for the WE32100 // (nothing to do) void setup() { } // finish things up void finishup(stackalloc &stacktop) { cout << "\tMOVW "; stacktop.print(cout) << ", result\n"; } // print out a binary operator followed by the // source and destination static void binop(const tree *head, stackalloc &curloc, const intalloc *cursp) { assemblyprint(head->left, curloc, cursp); stackalloc newloc(cursp); assemblyprint(head->right, newloc, cursp); switch (head->type) { case PLUS: cout << "\tADDW2 "; break; case MUL: cout << "\tMULW2 "; break; case DIV: cout << "\tDIVW2 "; break; case MINUS: cout << "\tSUBW2 "; break; } newloc.print(cout) << ", "; curloc.print(cout) << "\n"; } // print out a negate operator followed // by the destination static void negop(const tree *head, stackalloc &curloc, const intalloc *cursp) { stackalloc newloc(cursp); assemblyprint(head->left, newloc, cursp); cout << "\tMNEGW2 "; newloc.print(cout) << ", "; curloc.print(cout) << "\n"; } // store a number node at the current location static void svnumber(tree* head, stackalloc &curloc) { cout << "\tMOVW &" << head->value << ", "; curloc.print(cout) << "\n"; } !EOF! ls -l 5_5c3_W.c echo x - 5_5c3a.h sed 's/^X//' > 5_5c3a.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // intalloc.h // allocate and deallocate a number // from an integer set #ifndef INTALLOC_H # define INTALLOC_H #ifdef NONLOCAL /* DELETE */ #include #else /* DELETE */ #include "intset.h" /* DELETE */ #endif /* DELETE */ class intalloc { intset *a; public: intalloc(int m, int n) { a = new intset(m, n); } ~intalloc() { delete a; } int get(); void free(int i) { a->remove(i); } }; #endif /* INTALLOC_H */ !EOF! ls -l 5_5c3a.h echo x - 5_5c3b.h sed 's/^X//' > 5_5c3b.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // stackalloc.h // Manage a location on the stack. // WE32100 version. // Uses class intalloc to find // the location. #ifndef STACKALLOC_H # define STACKALLOC_H #ifdef NONLOCAL /* DELETE */ #include #else /* DELETE */ #include "intalloc.h" /* DELETE */ #endif /* DELETE */ #include class stackalloc { int loc; const intalloc *ia; public: stackalloc(const intalloc *a) : ia(a) { loc = a->get(); } ~stackalloc() { ia->free(loc); } #ifdef USE8086 /* DELETE */ #include "5_5c3sth6.h" /* DELETE */ #else /* DELETE */ ostream &print(ostream &out) { out << (loc * 4) << "(%sp)"; return out; } #endif /* DELETE */ }; #endif /* STACKALLOC_H */ !EOF! ls -l 5_5c3b.h echo x - 5_5c3i.c sed 's/^X//' > 5_5c3i.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #ifdef NONLOCAL /* DELETE */ #include #else /* DELETE */ #include "intset.h" /* DELETE */ #endif /* DELETE */ // remove a member from an intset void intset::remove(int t) { // look for the member // using a binary search, // just as was done in // intset::member() int l = 0; int u = cursize - 1; while (l <= u) { int m = (l+u) / 2; if (t < x[m]) u = m - 1; else if (t > x[m]) l = m + 1; else // found it, shift the remaining { // elements to the left for (int n = m + 1; n < cursize; n++, m++) x[m] = x[n]; cursize--; return; } } // not found, do nothing } !EOF! ls -l 5_5c3i.c echo x - 5_5c3iac.c sed 's/^X//' > 5_5c3iac.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #ifdef NONLOCAL /* DELETE */ #include #else /* DELETE */ #include "intalloc.h" /* DELETE */ #endif /* DELETE */ int intalloc::get() { for (int i = 0; a->member(i); i++) ; a->insert(i); return i; } !EOF! ls -l 5_5c3iac.c echo x - 5_5c3iah.h sed 's/^X//' > 5_5c3iah.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // intalloc.h // allocate and deallocate a number // from an integer set #ifndef INTALLOC_H # define INTALLOC_H #ifdef NONLOCAL /* DELETE */ #include #else /* DELETE */ #include "intset.h" /* DELETE */ #endif /* DELETE */ class intalloc { intset *a; public: intalloc(int m, int n) { a = new intset(m, n); } ~intalloc() { delete a; } int get(); void free(int i) { a->remove(i); } }; #endif /* INTALLOC_H */ !EOF! ls -l 5_5c3iah.h echo x - 5_5c3sth.h sed 's/^X//' > 5_5c3sth.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // stackalloc.h // Manage a location on the stack. // WE32100 version. // Uses class intalloc to find // the location. #ifndef STACKALLOC_H # define STACKALLOC_H #ifdef NONLOCAL /* DELETE */ #include #else /* DELETE */ #include "intalloc.h" /* DELETE */ #endif /* DELETE */ #include class stackalloc { int loc; const intalloc *ia; public: stackalloc(const intalloc *a) : ia(a) { loc = a->get(); } ~stackalloc() { ia->free(loc); } #ifdef USE8086 /* DELETE */ #include "5_5c3sth6.h" /* DELETE */ #else /* DELETE */ ostream &print(ostream &out) { out << (loc * 4) << "(%sp)"; return out; } #endif /* DELETE */ }; #endif /* STACKALLOC_H */ !EOF! ls -l 5_5c3sth.h echo x - 5_5c3sth6.h sed 's/^X//' > 5_5c3sth6.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // 8086 version of printing a // location on the stack. ostream &print(ostream &out) { out << "[bp-" << ((loc * 2) + 2) << "]"; return out; } !EOF! ls -l 5_5c3sth6.h echo x - 5_5cO1.c sed 's/^X//' > 5_5cO1.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include "5.5dir/5_5cOa.c" #include "5.5dir/5_5c1.c" /* expr::print() */ #include "5.5dir/5_5cOb.c" !EOF! ls -l 5_5cO1.c echo x - 5_5cO2.c sed 's/^X//' > 5_5cO2.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include "5.5dir/5_5cOa.c" #include "5.5dir/5_5c2.c" /* expr::print() */ #include "5.5dir/5_5cOb.c" !EOF! ls -l 5_5cO2.c echo x - 5_5cO3.c sed 's/^X//' > 5_5cO3.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include "5.5dir/5_5cOa.c" #include "5.5dir/5_5c3.c" /* expr::print() */ #include "5.5dir/5_5cOb.c" #include "5.5dir/5_5c3iac.c" #include "5.5dir/5_5c3i.c" #include "5.5dir/intset.c" !EOF! ls -l 5_5cO3.c echo x - 5_5cO4.c sed 's/^X//' > 5_5cO4.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #define USE8086 #include "5.5dir/5_5cOa.c" #include "5.5dir/5_5c3.c" /* expr::print() */ #include "5.5dir/5_5cOb.c" #include "5.5dir/5_5c3iac.c" #include "5.5dir/5_5c3i.c" #include "5.5dir/intset.c" !EOF! ls -l 5_5cO4.c echo x - 5_5cOa.c sed 's/^X//' > 5_5cOa.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include #include #include int error(const char *fmt ...); char prefix[512] = "....", *endprefix = &prefix[1]; char *incr() { *endprefix++ = '.'; *endprefix = '\0'; return prefix+1; } char *decr() { *--endprefix = '\0'; return prefix; } char *unctrl(unsigned int c) { static char x[5]; char *p = x; if (c > 0177) *p++ = 'M', *p++ = '-', c -= 0200; if ((c < 040) || (c == 0177)) *p++ = '^', *p++ = c ^ 0100; else *p++ = c; *p = '\0'; return x; } #include "5_5A.h" /* enum exprtype */ #include "5_5B.h" /* class tree, expr, token */ #include "5_5a0.c" /* forward declarations */ #include "5_5a5.c" /* prim() */ #include "5_5a4.c" /* term() */ #include "5_5a3.c" /* get_expr() */ #include "5_5a2.c" /* gettoken() */ #include "5_5a1.c" /* expandtree, expr::expr() */ #include "5_5b2.c" /* treeval() */ #include "5_5b1.c" /* expr::eval() */ !EOF! ls -l 5_5cOa.c echo x - 5_5cOb.c sed 's/^X//' > 5_5cOb.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ main(int, char) { char *s = "123/4+123*4-3"; expr x(s); x.print(); cout << "\n"; return 0; } // print the expression tree static char *spaces(int num) { return form("%.*s", num * 3, " "); } void tree::print(int level) { if (this) switch (this->type) { case PLUS: case DIV: case MUL: cout << spaces(level) << chr(this->type) << "\n"; this->left->print(level + 1); this->right->print(level + 1); return; case MINUS: cout << spaces(level) << chr(this->type) << "\n"; if (this->right) { this->left->print(level + 1); this->right->print(level + 1); } else this->left->print(level + 1); return; case NUMBER: cout << spaces(level) << "# " << this->value << "\n"; return; case LP: cout << spaces(level) << chr(this->type) << "\n"; this->left->print(level + 1); return; case RP: case END: default: cout << spaces(level) << chr(this->type) << "\n"; error("invalid type within tree"); break; } else error("NULL node found"); return; } void expr::eprint() { head->print(0); } !EOF! ls -l 5_5cOb.c echo x - 5_5c_pr.c sed 's/^X//' > 5_5c_pr.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include #include #include int error(const char *fmt ...); #include "5_5A.h" #include "5_5B.h" #include "5_5c3.c" !EOF! ls -l 5_5c_pr.c echo x - 5_5d.cmp sed 's/^X//' > 5_5d.cmp << '!EOF!' x = '' x = push bp mov bp, sp mov [bp-2], 0 mov ax, [bp-2] mov result, ax pop bp x = 0 x = '1 ' x = push bp mov bp, sp mov [bp-2], 1 mov ax, [bp-2] mov result, ax pop bp x = 1 x = '2*3 ' x = push bp mov bp, sp mov [bp-2], 2 mov [bp-4], 3 mov ax,[bp-2] mov bx,[bp-4] mul bx mov [bp-2], ax mov ax, [bp-2] mov result, ax pop bp x = 6 x = '2-3 ' x = push bp mov bp, sp mov [bp-2], 2 mov [bp-4], 3 mov ax,[bp-2] mov bx,[bp-4] sub ax, bx mov [bp-2], ax mov ax, [bp-2] mov result, ax pop bp x = -1 x = '5/2' x = push bp mov bp, sp mov [bp-2], 5 mov [bp-4], 2 mov ax,[bp-2] mov bx,[bp-4] mov dx, 0 div bx mov [bp-2], ax mov ax, [bp-2] mov result, ax pop bp x = 2 x = '123/4+123*4-3' x = push bp mov bp, sp mov [bp-2], 123 mov [bp-4], 4 mov ax,[bp-2] mov bx,[bp-4] mov dx, 0 div bx mov [bp-2], ax mov [bp-4], 123 mov [bp-6], 4 mov ax,[bp-4] mov bx,[bp-6] mul bx mov [bp-4], ax mov ax,[bp-2] mov bx,[bp-4] add ax, bx mov [bp-2], ax mov [bp-4], 3 mov ax,[bp-2] mov bx,[bp-4] sub ax, bx mov [bp-2], ax mov ax, [bp-2] mov result, ax pop bp x = 519 !EOF! ls -l 5_5d.cmp echo x - 5_5d.h sed 's/^X//' > 5_5d.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ struct tree { tree *left, *right; exprtype type; int value; }; class expr { char *str; int evaluated, value; public: expr(char*); ~expr() { delete str; } int eval(); void print(); }; struct token { exprtype type; int value; }; !EOF! ls -l 5_5d.h echo x - 5_5d1.c sed 's/^X//' > 5_5d1.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include expr:: expr(char* s) { str = new char[strlen(s) + 1]; strcpy(str, s); evaluated = 0; } !EOF! ls -l 5_5d1.c echo x - 5_5d2.c sed 's/^X//' > 5_5d2.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ int expr::eval() { if (!evaluated) { istream input(strlen(s), s); get_token(input); tree *head = expandtree(input); value = treeval(head); delete head; evaluated++; } return value; } !EOF! ls -l 5_5d2.c echo x - 5_5d3.c sed 's/^X//' > 5_5d3.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ void expr:: print() { tree *head = expandtree(input); infixprint(head); delete head; } !EOF! ls -l 5_5d3.c echo x - 5_5d_pr.c sed 's/^X//' > 5_5d_pr.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include #include #include int error(const char *fmt ...); #include "5_5A.h" #include "5_5B.h" #include "5_5c3.c" !EOF! ls -l 5_5d_pr.c echo x - 5_5e.cmp sed 's/^X//' > 5_5e.cmp << '!EOF!' x = '' x = ( 0 ) x = 0 x = '1 ' x = ( 1 ) x = 1 x = '2*3 ' x = ( ( 2 ) * ( 3 ) ) x = 6 x = '2-3 ' x = ( ( 2 ) - ( 3 ) ) x = -1 x = '5/2' x = ( ( 5 ) / ( 2 ) ) x = 2 x = '123/4+123*4-3' x = ( ( ( ( 123 ) / ( 4 ) ) + ( ( 123 ) * ( 4 ) ) ) - ( 3 ) ) x = 519 !EOF! ls -l 5_5e.cmp echo x - 5_5e1.c sed 's/^X//' > 5_5e1.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ tree *expandtree(istream &input) { if (curr_tok.type == END) return new number_leaf(0); else return get_expr(input); } expr:: expr(char* s) { istream input(strlen(s), s); evaluated = 0; get_token(input); head = expandtree(input); } !EOF! ls -l 5_5e1.c echo x - 5_5e3.c sed 's/^X//' > 5_5e3.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ static tree* get_expr(istream& input) { tree* left = term(input); for (;;) switch (curr_tok.type) { case PLUS: plus_op *headp = new plus_op; headp->left = left; get_token(input); // eat '+' headp->right = term(input); left = headp; break; case MINUS: binary_minus_op* headm = new binary_minus_op; headm->left = left; get_token(input); // eat '-' headm->right = term(input); left = headm; break; default: // collapse node return left; } } !EOF! ls -l 5_5e3.c echo x - 5_5e4.c sed 's/^X//' > 5_5e4.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ static tree* term(istream& input) { tree* left = prim(input); for (;;) switch (curr_tok.type) { case MUL: mult_op *headm = new mult_op; headm->left = left; get_token(input); // eat '*' headm->right = prim(input); left = headm; break; case DIV: div_op *headd = new div_op; headd->left = left; get_token(input); // eat '/' headd->right = prim(input); left = headd; break; default: // collapse node return left; } } !EOF! ls -l 5_5e4.c echo x - 5_5e5.c sed 's/^X//' > 5_5e5.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ static tree* prim(istream& input) { switch (curr_tok.type) { case NUMBER: number_leaf* retn = new number_leaf(curr_tok.value); get_token(input); // skip number return retn; case MINUS: unary_minus_op *retm = new unary_minus_op; get_token(input); // skip '-' retm->left = prim(input); return retm; case LP: lparen_op *retlp = new lparen_op; get_token(input); // skip '(' retlp->left = get_expr(input); if (curr_tok.type != RP) { error(") expected"); break; } get_token(input); // skip ')' return retlp; case END: error("end of expression unexpected"); break; default: error("unknown type within tree"); break; } // error case number_leaf *ret = new number_leaf(0); return ret; } !EOF! ls -l 5_5e5.c echo x - 5_5e_all.c sed 's/^X//' > 5_5e_all.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include #include #include #include int error(const char *fmt ...); char prefix[512] = "....", *endprefix = &prefix[1]; char *incr() { *endprefix++ = '.'; *endprefix = '\0'; return prefix+1; } char *decr() { *--endprefix = '\0'; return prefix; } char *unctrl(unsigned int c) { static char x[5]; char *p = x; if (c > 0177) *p++ = 'M', *p++ = '-', c -= 0200; if ((c < 040) || (c == 0177)) *p++ = '^', *p++ = c ^ 0100; else *p++ = c; *p = '\0'; return x; } #include "5_5A.h" /* enum exprtype */ #include "5_5E.h" /* class tree, expr, token */ #include "5_5a0.c" /* forward declarations */ #include "5_5e5.c" /* prim() */ #include "5_5e4.c" /* term() */ #include "5_5e3.c" /* get_expr() */ #include "5_5a2.c" /* gettoken() */ #include "5_5e1.c" /* expandtree, expr::expr() */ #include "5_5f2.c" /* treeval() */ #include "5_5f1.c" /* expr::eval() */ #include "main.c" !EOF! ls -l 5_5e_all.c echo x - 5_5f1.c sed 's/^X//' > 5_5f1.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Evaluate the expression int expr:: eval() { if (!evaluated) { value = head->eval(); evaluated++; } return value; } !EOF! ls -l 5_5f1.c echo x - 5_5f2.c sed 's/^X//' > 5_5f2.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ void expr:: print() { head->print(); } !EOF! ls -l 5_5f2.c echo x - 5_5x1.c sed 's/^X//' > 5_5x1.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ class expr { // ... public: expr(char*); int eval(); void print(); }; !EOF! ls -l 5_5x1.c echo x - 5_5x2.c sed 's/^X//' > 5_5x2.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ expr x("123/4+123*4-3"); cout << "x = " << x.eval() << "\n"; x.print(); !EOF! ls -l 5_5x2.c echo x - 5_5x3.c sed 's/^X//' > 5_5x3.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ infixprint(head->left); cout << " + "; infixprint(head->right); !EOF! ls -l 5_5x3.c echo x - 5_5x4.c sed 's/^X//' > 5_5x4.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ cout << " ( "; infixprint(head->left); cout << " + "; infixprint(head->right); cout << " ) "; !EOF! ls -l 5_5x4.c echo x - 5_5x5.c sed 's/^X//' > 5_5x5.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ postfixprint(head->left); postfixprint(head->right); cout << " + "; !EOF! ls -l 5_5x5.c echo x - 5_5x6.c sed 's/^X//' > 5_5x6.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ return treeval(head->left) + treeval(head->right); !EOF! ls -l 5_5x6.c echo x - intalloc.c sed 's/^X//' > intalloc.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #ifdef NONLOCAL /* DELETE */ #include #else /* DELETE */ #include "intalloc.h" /* DELETE */ #endif /* DELETE */ int intalloc::get() { for (int i = 0; a->member(i); i++) ; a->insert(i); return i; } !EOF! ls -l intalloc.c echo x - intalloc.h sed 's/^X//' > intalloc.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // intalloc.h // allocate and deallocate a number // from an integer set #ifndef INTALLOC_H # define INTALLOC_H #ifdef NONLOCAL /* DELETE */ #include #else /* DELETE */ #include "intset.h" /* DELETE */ #endif /* DELETE */ class intalloc { intset *a; public: intalloc(int m, int n) { a = new intset(m, n); } ~intalloc() { delete a; } int get(); void free(int i) { a->remove(i); } }; #endif /* INTALLOC_H */ !EOF! ls -l intalloc.h echo x - intset.c sed 's/^X//' > intset.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ extern int error(const char * ...); #ifdef NONLOCAL /* DELETE */ #include #else /* DELETE */ #include "intset.h" /* DELETE */ #endif /* DELETE */ intset::intset(int m, int n) { if (m < 1 || n < m) error("illegal intset size"); cursize = 0; maxsize = m; x = new int[maxsize]; } intset:: ~intset() { delete x; } void intset::insert(int t) { if (++cursize > maxsize) error("too many elements in intset"); int i = cursize - 1; x[i] = t; while (i > 0 && x[i-1] > x[i]) { int t = x[i]; x[i] = x[i-1]; x[i-1] = t; i--; } } int intset::member(int t) { int l = 0; int u = cursize - 1; while (l <= u) { int m = (l+u) / 2; if (t < x[m]) u = m - 1; else if (t > x[m]) l = m + 1; else return 1; } return 0; } !EOF! ls -l intset.c echo x - intset.h sed 's/^X//' > intset.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #ifndef INTSET_H # define INTSET_H class intset { int cursize, maxsize; int *x; public: intset(int m, int n); ~intset(); int member(int t); void insert(int t); void remove(int i); void iterate(int &i) { i = 0; } int ok(int& i) { return i < cursize; } int next(int& i) { return x[i++]; } }; #endif /* INTSET_H */ !EOF! ls -l intset.h echo x - intset2.c sed 's/^X//' > intset2.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #ifdef NONLOCAL /* DELETE */ #include #else /* DELETE */ #include "intset.h" /* DELETE */ #endif /* DELETE */ // remove a member from an intset void intset::remove(int t) { // look for the member // using a binary search, // just as was done in // intset::member() int l = 0; int u = cursize - 1; while (l <= u) { int m = (l+u) / 2; if (t < x[m]) u = m - 1; else if (t > x[m]) l = m + 1; else // found it, shift the remaining { // elements to the left for (int n = m + 1; n < cursize; n++, m++) x[m] = x[n]; cursize--; return; } } // not found, do nothing } !EOF! ls -l intset2.c echo x - junk.c sed 's/^X//' > junk.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ foo() { int a = 1, b = 2, c = 3, d; d = a + b * c; } !EOF! ls -l junk.c echo x - main.c sed 's/^X//' > main.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ char *strs[] = { "", "1 ", "2*3 ", "2-3 ", "5/2", "123/4+123*4-3", 0 }; void lookat(char *s) { cout << "x = '" << s << "'\n"; expr x(s); cout << "x = "; x.print(); cout << "\n"; cout << "x = " << x.eval() << "\n"; cout << "\n"; } main(int argc, char **argv) { if (argc > 1) while (*++argv) lookat(*argv); else for (int i = 0; strs[i]; i++) lookat(strs[i]); return 0; } !EOF! ls -l main.c echo x - makefile sed 's/^X//' > makefile << '!EOF!' CC= CC -I. -I../../CC ERROR= ../../error.a CFLAGS= -I. ALLSRC = 5_5A.h 5_5B.h 5_5a0.c 5_5a1.c 5_5a2.c 5_5a3.c 5_5a4.c 5_5a5.c 5_5b1.c 5_5b2.c all: 5_5a_all 5_5b_all 5_5c_all 5_5d_all 5_5e_all 5_5a_all.o: $(ALLSRC) 5_5a_all.c main.c $(CC) -c $(CFLAGS) 5_5a_all.c 5_5a_pr.o: 5_5a_pr.c 5_5A.h 5_5B.h 5_5c1.c $(CC) -c $(CFLAGS) 5_5a_pr.c 5_5b_pr.o: 5_5b_pr.c 5_5A.h 5_5B.h 5_5c2.c $(CC) -c $(CFLAGS) 5_5b_pr.c 5_5c_pr.o: 5_5c_pr.c 5_5A.h 5_5B.h 5_5c3.c \ 5_5c3_W.c \ intalloc.h stackalloc.h intset.h $(CC) -c $(CFLAGS) 5_5c_pr.c 5_5d_pr.o: 5_5c_pr.c 5_5A.h 5_5B.h 5_5c3.c \ 5_5c3_6.c \ intalloc.h stackalloc.h intset.h -ln -f 5_5c_pr.c 5_5d_pr.c $(CC) $(CFLAGS) -DUSE8086 -c 5_5d_pr.c 5_5a_all: 5_5a_all.o 5_5a_pr.o $(CC) $(CFLAGS) 5_5a_all.o 5_5a_pr.o -o 5_5a_all $(ERROR) 5_5b_all: 5_5a_all.o 5_5b_pr.o $(CC) $(CFLAGS) 5_5a_all.o 5_5b_pr.o -o 5_5b_all $(ERROR) 5_5c_all: 5_5a_all.o 5_5c_pr.o intset.o intset2.o intalloc.o $(CC) $(CFLAGS) 5_5a_all.o 5_5c_pr.o intset.o intset2.o intalloc.o -o 5_5c_all $(ERROR) 5_5d_all: 5_5a_all.o 5_5d_pr.o intset.o intset2.o intalloc.o $(CC) $(CFLAGS) 5_5a_all.o 5_5d_pr.o intset.o intset2.o intalloc.o -o 5_5d_all $(ERROR) 5_5e_all.o: 5_5A.h 5_5E.h 5_5a0.c 5_5e5.c 5_5e4.c 5_5e3.c 5_5a2.c 5_5e1.c 5_5f2.c 5_5f1.c main.c $(CC) -c $(CFLAGS) 5_5e_all.c 5_5e_all: 5_5e_all.o $(CC) $(CFLAGS) 5_5e_all.o -o 5_5e_all $(ERROR) intset.o: intset.c intset.h $(CC) -c $(CFLAGS) intset.c intset2.o: intset2.c intset.h $(CC) -c $(CFLAGS) intset2.c intalloc.o: intalloc.c intalloc.h $(CC) -c $(CFLAGS) intalloc.c CMP= 5_5a.cmp 5_5b.cmp 5_5c.cmp 5_5d.cmp 5_5e.cmp OUT= 5_5a.out 5_5b.out 5_5c.out 5_5d.out 5_5e.out 5_5a.out: 5_5a_all ; 5_5a_all > 5_5a.out 5_5b.out: 5_5b_all ; 5_5b_all > 5_5b.out 5_5c.out: 5_5c_all ; 5_5c_all > 5_5c.out 5_5d.out: 5_5d_all ; 5_5d_all > 5_5d.out 5_5e.out: 5_5e_all ; 5_5e_all > 5_5e.out test: all $(OUT) $(CMP) cmp 5_5a.out 5_5a.cmp cmp 5_5b.out 5_5b.cmp cmp 5_5c.out 5_5c.cmp cmp 5_5d.out 5_5d.cmp cmp 5_5e.out 5_5e.cmp echo tests done !EOF! ls -l makefile echo x - stackalloc.h sed 's/^X//' > stackalloc.h << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // stackalloc.h // Manage a location on the stack. // WE32100 version. // Uses class intalloc to find // the location. #ifndef STACKALLOC_H # define STACKALLOC_H #ifdef NONLOCAL /* DELETE */ #include #else /* DELETE */ #include "intalloc.h" /* DELETE */ #endif /* DELETE */ #include class stackalloc { int loc; const intalloc *ia; public: stackalloc(const intalloc *a) : ia(a) { loc = a->get(); } ~stackalloc() { ia->free(loc); } #ifdef USE8086 /* DELETE */ #include "5_5c3sth6.h" /* DELETE */ #else /* DELETE */ ostream &print(ostream &out) { out << (loc * 4) << "(%sp)"; return out; } #endif /* DELETE */ }; #endif /* STACKALLOC_H */ !EOF! ls -l stackalloc.h # The following exit is to ensure that extra garbage # after the end of the shar file will be ignored. exit 0