Exercise 4-8

Suppose that there will never be more than one character of pushback. Modify getch and ungetch accordingly.

For this exercise, we cannot build upon the previous ones as this would break functionality that the program depends on, so we will build on from our code from exercise 4-3, which is the calculator at its most basic state while still remaining usable with support for negative numbers.

The first thing we do is replace the character array buf with a single character. We can also get rid of bufp and instead create the boolean variable state that can be set to FULL or EMPTY to represent whether the buffer is free. Inside ungetch, we assign the argument to buf only if state is not FULL, and then update state to FULL. For getch, we normally run getchar except for when state is FULL, in which case we return buf and change state to EMPTY.

    #define MAXOP   100 /* max size of operand or operator */
    #define NUMBER  '0' /* signal that a number was found */
    #define MAXVAL  100 /* maximum depth of val stack */
    #define BUFSIZE 100

    enum boolean { EMPTY, FULL };
    
    int getop(char []);
    void push(double);
    double pop(void);
    int getch(void);
    void ungetch(int);
    
    int sp = 0;         /* next free stack position */
    double val[MAXVAL]; /* value stack */
    char buf[BUFSIZE];  /* buffer for ungetch */
    int bufp = 0;       /* next free position in buf */
    char buf;           /* buffer for ungetch */
    int state = EMPTY;  /* whether buffer is full or empty */
    ...
    int getch(void) /* get a (possibly pushed back) character */
    {
        return (bufp > 0) ? buf[--bufp] : getchar();
        if (state == FULL) {
            state = EMPTY;
            return buf;
        }
        return getchar();
    }
    
    void ungetch(int c) /* push character back on input */
    {
        if (bufp >= BUFSIZE)
            printf("ungetch: too many characters\n");
        else
            buf[bufp++] = c;
        if (state == FULL)
            printf("ungetch: buffer is full\n");
        else {
            buf = c;
            state = FULL;
        }
    }