main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Stack.h"
#include "conversionController.h"
// Author: Devin Eldreth
/*
This program functions as a Reverse Polish Notation Calculator. It will accept integer input and push the values to the stack. As of now it is
only capable of performing the 4 main arithmetic functions (addition, subtraction, multiplication, and division). It is also capaable of converting between bases 2-16 much like
the *nix dc rpn calculator.
April 27th 2007
*/
void valueAdd(); // Add values from stack
void valueNeg(); // Subtract values from stack
void valuePro(); // Multiply values from stack
void valueDiv(); // Divide values from stack
Stack S;
int main(){
init(&S);
char value[100];
char allowedValues[20] = {'a', 'A', 'b', 'B', 'c', 'C', 'd', 'D', 'e', 'E', 'f', 'F', '+', '-', '*', '/', 'p', 'P', 'i', 'o'};
int basein = 10;
int baseout = 10;
printf("RPN CALCULATOR (type L for command list)\n");
while(1){
fgets(value, 80, stdin);
if(index(allowedValues, value[0]) == value){
printf("Error\n");
}
else{
switch((int)value[0]){
case '+': // dc: + // Add the top most values and push the result to the stack
valueAdd();
break;
case '-': // dc: - // Subtract the top most values and push the result to the stack
valueNeg();
break;
case '*': // dc: * // Multiply the top most values and push the result to the stack
valuePro();
break;
case '/': // dc: / // Divide the top most values and push the result to the stack
valueDiv();
break;
case 'L': // Command: L // Displays a list of all available commands
printf("List of Commands:\n");
printf("+ : Addition (Adds the top two values on the stack and pushes the result)\n");
printf("- : Subtraction (Calculates the difference of the top two values on the stack and pushes the result)\n");
printf("* : Product (Calculates the product of the top two values on the stack and pushes the result)\n");
printf("/ : Quotient (Calculates the quotient of the top two values on the stack and pushes the integer result)\n");
// Stack based commands
printf("p : Peeks at the stack\n");
printf("P : Pops the stack\n");
printf("c : Clears the stack\n");
// Base control commands
printf("i : Uses the top value of the stack as the input of base n\n");
printf("o : Uses the top value of the stack as the output of base n\n");
break;
case 'p': // dc: p // Print top most value without alteration to stack
if(isEmpty(&S)){
printf("Stack is Empty\n");
}
else{
if(baseout != 10)
intToBase(peek(&S), baseout);
else
printf("%d\n", peek(&S));
}
break;
case 'P': // dc: P // Pops the value from the top of the stack
if(isEmpty(&S)){
printf("Stack is Empty\n");
}
else{
if(baseout != 10){
intToBase(pop(&S), baseout);
}
else{
printf("%d\n", pop(&S));
}
}
break;
case 'f': // dc: f // Prints the entire stack without alteration to the stack
displayStack(&S);
break;
case 'i': // dc: i // Sets the base conversion for 2 - 16
if(peek(&S) > 1 && peek(&S) < 17){
basein = pop(&S);
}
else{
printf("Error: The top most value of the stack is not within the range of bases (2 - 16).\n");
}
break;
case 'o': // dc: o // Sets the base output between 2 - 16
if(peek(&S) > 1 && peek(&S) < 17){
baseout = pop(&S);
}
else{
printf("Error: The top most value of the stack is not within the range of bases (2 - 16).\n");
}
break;
default: // For any alphanumberic character not specificed in the range of values, push those values onto the stack
if(basein != 10){
push(&S, baseToInt(value, basein));
}
else{
push(&S, atoi(value));
}
break;
}
}
}
}
void valueAdd(){
int added = pop(&S) + pop(&S);
push(&S, added);
}
void valueNeg(){
int neg = pop(&S) - pop(&S);
push(&S, neg);
}
void valuePro(){
int product = pop(&S) * pop(&S);
push(&S, product);
}
void valueDiv(){
if(topIs(&S) < 2 || isEmpty(&S) == 1){
printf("Div 0\n");
}
else{
int div = pop(&S) / pop(&S);
push(&S, div);
}
}
conversionController.h
/*
Author: Devin Eldreth
Header for conversionController.c
*/
// Convert a string value of a certain base n to a decimal number (base 10)
int baseToInt(char string[64], int base);
// This function accompanies baseToInt by returning values based on ASCII representations of A, B, C, D, E, F
int returnValue(char value);
// This function prints a string based on a passed integer value and a passed base n value
void intToBase(int pass, int base);
Stack.h
/*
Author: Devin Eldreth
April 17th 2007
*/
// Stuct declaration for Stack
// The only thing that really matters in this simple stack is the value, which implemented like this is also the max value
// and the top of the stack. Of course the name of the struct will be Stack.
// The type of the array 'value' will of course correspond to the type of the stack.
typedef struct{
int value[20];
int top;
}Stack;
// Initilize the stack. Just set the top value to 0
void init(Stack *S);
// Pop the last value pushed onto the stack and return it as an integer.
int pop(Stack *S);
// Push a value onto the stack and make sure that it is stored in whatever the top value is.
void push(Stack *S, int value);
// Print the first value of the stack without altering the stack
int peek(Stack *S);
// Display all of the values contained on the stack, top down, and if it is empty let someone know
void displayStack(Stack *S);
void displayStackOffset(Stack *S, int base);
// Check and see if the stack is full (return 1 for full. (i.e., the top is at 20).
int isFull(Stack *S);
// Check and see if the stack is empty
int isEmpty(Stack *S);
// Get the location of the top
int topIs(Stack *S);
conversionController.c
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "conversionController.h"
/*
Author: Devin Eldreth
*/
int baseToInt(char input[64], int base){
int length = strlen(input) - 1; // The length of the input string
int value = 0; // Rolling sum for the values
int count = 0; // Counting variable
while(count < length){
// Sum up the base ^ current offset between the length of the string and the counting variable,
// multiplied by the getIndex return value for the value at count on the input string
value = value + pow(base, length - count - 1) * returnValue(input[count]);
count++;
}
return value;
}
int returnValue(char value){
switch(value){
case 'a':
case 'A':
return 10;
case 'b':
case 'B':
return 11;
case 'c':
case 'C':
return 12;
case 'd':
case 'D':
return 13;
case 'e':
case 'E':
return 14;
case 'f':
case 'F':
return 15;
default:
return (int)value - '0';
}
}
void intToBase(int pass, int passBase){
char basedig[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
int converted[64];
int next, index = 0;
int base = passBase;
long int value = pass;
while(value != 0){
converted[index] = value % base;
value = value / base;
++index;
}
--index;
for(; index >= 0; index--){
printf("%c", basedig[converted[index]]);
}
printf("\n");
}
Stack.c
#include <stdio.h>
#include "Stack.h"
#include "conversionController.h"
void init(Stack *S){
S->top = 0;
}
int pop(Stack *S){
(S->top)--;
return S->value[S->top];
}
void push(Stack *S, int value){
S->value[S->top] = value;
(S->top)++;
}
int peek(Stack *S){
int peeked;
(S->top)--;
peeked = S->value[S->top];
(S->top)++;
return peeked;
}
int isFull(Stack *S){
if(S->top >= 20){
return 1;
}
else{
return 0;
}
}
int isEmpty(Stack *S){
if(S->top == 0){
return 1;
}
else{
return 0;
}
}
void displayStack(Stack *S){
int counter;
if(S->top == 0){
printf("Stack is Empty\n\n");
}
else{
printf("Displaying contents of Stack:\n");
counter = S->top - 1;
while(counter >= 0){
printf("Stack[%d]: %d\n", counter, S->value[counter]);
counter--;
}
printf("\n");
}
}
void displayStackOffset(Stack *S, int base){
int counter;
if(S->top == 0){
printf("Stack is Empty\n\n");
}
else{
printf("Displaying contents of Stack:\n");
counter = S->top - 1;
while(counter >= 0){
printf("Stack[%d]: %s\n", counter, intToBase(S->value[counter], base));
counter--;
}
printf("\n");
}
}
int topIs(Stack *S){
return S->top;
}