Skip to content

Instantly share code, notes, and snippets.

@gonzafernan
Last active April 20, 2022 16:00
Show Gist options
  • Save gonzafernan/c87086f03dfdb8f138638cacd4d9a3d5 to your computer and use it in GitHub Desktop.
Save gonzafernan/c87086f03dfdb8f138638cacd4d9a3d5 to your computer and use it in GitHub Desktop.
Reverse Polish notation (RPN) is a mathematical notation in which operators follow their operands. This is a C implementation with a simple stack.
/*
============================================================================
Name : rpncalc.c
Author : Gonzalo G. Fernandez
Email : ggfernandez@unbosque.edu.co
Institution : Universidad El Bosque
Year : 2022
Version : 1.0
Copyright : License MIT
Description : Reverse Polish notation (RPN) is a mathematical notation in
which operators follow their operands.
This is a C implementation with a simple stack.
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define MAX_STACK_LENGTH 10 /* Max float stack length */
float stack[MAX_STACK_LENGTH]; /* Float stack */
int top = -1; /* Current stack index */
/* Check if stack is empty (1 if true, 0 if false) */
int isEmpty(void){
if (top == -1){
return 1;
} else {
return 0;
}
}
/* Check if stack is full (1 if true, 0 if false) */
int isFull(void){
if (top == MAX_STACK_LENGTH){
return 1;
} else {
return 0;
}
}
/* Get next stack element without pop */
float peek(void){
return stack[top];
}
/* Get next stack element
* If a pop is tried when the stack is empty,
* the program finish execution with error
*/
float pop(void){
float data;
if (!isEmpty()){
data = stack[top];
top--;
return data;
} else {
printf("ERROR: Pop of empty stack.\n");
exit(EXIT_FAILURE);
}
}
/* Put element data in stack
* If a push is tried when the stack is full return 1,
* successful push return 0
*/
int push(float data){
if (!isFull()){
top++;
stack[top] = data;
return 0;
} else {
return 1;
}
}
int main(int argc, char *argv[]) {
char *token;
float tmp_value1, tmp_value2;
// Check for input argument expression
if (argc < 2){
printf("No expression given.\n");
return EXIT_SUCCESS;
}
// Process every expression given
for (int i=1; i<argc; i++){
// Tokenize argument and processing
token = strtok(argv[i], " ");
while (token != NULL){
/* Addition operation */
if (strcmp(token, "+") == 0){
tmp_value2 = pop();
tmp_value1 = pop();
tmp_value1 = tmp_value1 + tmp_value2;
/* Subtraction operation */
} else if (strcmp(token, "-") == 0){
tmp_value1 = pop();
tmp_value2 = pop();
tmp_value1 = tmp_value1 - tmp_value2;
/* Multiplication operation */
} else if (strcmp(token, "*") == 0){
tmp_value1 = pop();
tmp_value2 = pop();
tmp_value1 = tmp_value1 * tmp_value2;
/* Division operation */
} else if (strcmp(token, "/") == 0){
tmp_value1 = pop();
tmp_value2 = pop();
tmp_value1 = tmp_value1 / tmp_value2;
/* Power operation */
} else if (strcmp(token, "pow") == 0){
tmp_value1 = pop();
tmp_value2 = pop();
tmp_value1 = pow(tmp_value1, tmp_value2);
/* Absolute value */
} else if (strcmp(token, "abs") == 0){
tmp_value1 = pop();
tmp_value1 = abs(tmp_value1);
/* Sqruare-root operation */
} else if (strcmp(token, "sqrt") == 0){
tmp_value1 = pop();
tmp_value1 = sqrt(tmp_value1);
/* Input number (always float) */
} else {
tmp_value1 = atof(token);
}
// Push value to stack (operation result or new value)
if (push(tmp_value1)){
printf("ERROR: Push of full stack.\n");
return EXIT_FAILURE;
}
token = strtok(NULL, " "); // Get new token
}
// Check for answer
// If more than one element in stack, invalid expression
if (top > 0){
printf("Invalid expression.");
return EXIT_SUCCESS;
}
printf("%.3f", peek());
}
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment