Skip to content

Instantly share code, notes, and snippets.

@spitemim
Created April 12, 2022 15:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spitemim/e9b6c5442936c49e246bf0d77c1856e5 to your computer and use it in GitHub Desktop.
Save spitemim/e9b6c5442936c49e246bf0d77c1856e5 to your computer and use it in GitHub Desktop.
Simple Reverse Polish Notation calculator in C
/*
RPN Calcuator in C
by Spitemim, 2022/04/12
To compile:
$ cc rpn.c -lreadline -o rpn
*, +, /, and - are operators and work as expected
Use ~ for negative numbers (~500, ~5.5, etc.)
Use @ to clear the stack
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <readline/readline.h>
#include <readline/history.h>
#define STACK_MAX 1024
double stack[STACK_MAX] = {0.0};
int top = -1;
void
push(double d) {
if (top + 1 == STACK_MAX) {
puts("\tStack overflow!");
return;
}
stack[++top] = d;
}
double
pop(void)
{
if (top < 0) {
puts("\tStack underflow!");
return 0.0;
}
return stack[top--];
}
void
showstack(void)
{
int i;
printf("\t[ ");
for (i = 0; i <= top; ++i) {
printf("%g ", stack[i]);
}
/*printf("] - TOP: %d\n", top);*/
printf("]\n");
}
void
interpret(char *buf)
{
int nc;
double d;
do {
if (isdigit(*buf)) {
/* read one float into d */
sscanf(buf, "%lf%n", &d, &nc);
buf += nc;
push(d);
} else if (*buf == '~') {
/* if a number doesn't immediately follow the ~, ignore */
++buf;
if (isdigit(*buf)) {
sscanf(buf, "%lf%n", &d, &nc);
buf += nc;
push(-d);
}
} else {
/* operators */
switch (*buf) {
case '+':
push(pop() + pop());
break;
case '*':
push(pop() * pop());
break;
case '-':
d = pop();
push(pop() - d);
break;
case '/':
d = pop();
push(pop() / d);
break;
case '@':
top = -1;
break;
}
}
} while (*buf++);
}
int
main(void)
{
char *buf;
puts("Reverse Polish Notation Calculator");
puts(" +, -, *, / work as expected");
puts(" ~ for negative numbers, @ to clear stack\n");
for (;;) {
buf = readline("> ");
add_history(buf);
if (strlen(buf) != 0) {
interpret(buf);
showstack();
}
free(buf);
}
free(buf);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment