Reverse Polish Notation shell interpreter with one variable in C
Here are some ideas for improving your program.

Use the correct prototype for main

Many compilers will default to an int return type when the function return type is undeclared, but it's not a good idea to omit it, especially with main.  Instead of this:

main () {


write this:

int main() {


Eliminate global variables where practical

The code declares and uses 5 global variables.  Global variables obfuscate the actual dependencies within code and make maintainance and understanding of the code that much more difficult.  It also makes the code harder to reuse.  For all of these reasons, it's generally far preferable to eliminate global variables and to instead pass pointers to them.  That way the linkage is explicit and may be altered more easily if needed.  In this case, I'd suggest gathering everything together into a structure within main's scope and then passing that structure to each of the functions.  For example, it might be defined like this:

typedef struct stack_s {
    int sp;
    int bufp;
    double x;
    double stack[MAXSTACK];
    char buf[BUFSIZE];
} StackMachine;


And then within main it could be defined like this:

StackMachine sm = { .sp = 0, .bufp = 0 };


Then push could be reimplemented like this:

void push(StackMachine *sm, double f) {
    if (sm-&gt;sp &lt; MAXSTACK)
        sm-&gt;stack[sm-&gt;sp++] = f;
    else
        printf(CRED "ERROR: Stack is full, cannot push %g\n" CRESET, f);
}


Be consistent with the user interface

When the user uses an empty line to see the top of the stack, it reports 0 instead of STACK EMPTY when the stack is empty.  This is inconsistent with the other operations.