Thursday, March 13, 2008

RPN Calculator in C (R1 Command Line)

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;
}

Objective-C Stack & Node Implementation


After creating a Struct oriented Stack in C I decided it might not be a bad idea to work on a similar implementation in Objective-C. This simple program actually tries to mimic the function of the java.util.Stack data collection. It, however, does not inherit any of the class definitions that java.util.Stack does.
 
This Objective-C implementation of a Stack utilizes a class called Node. Node functionally serves as an object which only has three basic things. A next, previous and value. The Node class contains methods which are used to access each Node’s next, previous, and value. But functionally the Node has nothing to do with the algorithm of the Stack, other than through the use of its previous node.
 
In a Stack, or in my implementation of a Stack, the Node only needs to reference its previous node. A stack does not ever need to know of its next node. If it did it wouldn’t be a Stack! Data structures such as a doubly linked list, which contain elements (in this case Node’s) that have knowledge of both their next and previous elements can benefit from this setup. My Node class simply is ready to be used in the cases of other data structures such as Queues.
 
Here are the snippets of source code from my Objective-C implementation of a Stack.
 
Code:
main.m

#import "Stack.h"

#import "Node.h"

#import


main (void){

id S = [Stack new]; // Create a new Stack

char value[80];

while(1){

fgets(value, 80, stdin);

switch(value[0]){

case 'P': // Big P pops the top value off the stack

if([S empty] != 1){

printf("Pop: %d\n", [[S pop] getValue]);

}

else{

printf("Empty Stack\n");

}

break;

case 'p': // Lowercase p peeks the top of the stack

if([S empty] != 1){

printf("Peek: %d\n", [[S peek] getValue]);

}

else{

printf("Empty Stack\n");

}

break;

case 'f': // Display all values in the stack

[S displayStack];

break;

default: // Add the integer value of whatever the input was to the stack (push)

[S push: atoi(value)];

break;

}

}

}


Node.h

#import


/**

Author: Devin Eldreth

Node Header Information

*/


@interface Node: Object{

int value; // The integer value of the node

id previous, next; // Previous and next Nodes relative to this node

}


- (id) getPrevious; // Returns a pointer to the previous node

- (id) getNext; // Returns a pointer to the next node


- (void) setPrevious: (id) pass; // Sets the pointer to this Node's previous node to a node 'pass'

- (void) setNext: (id) pass; // Sets the pointer to this Node's next node to a node 'pass'


- (int) getValue; // Gets the value of the node

- (void) setValue: (int) pass; // Sets the value of the node to an integer value 'pass'

@end


Node.m

#import

#import "Node.h"

#import


/**

Author: Devin Eldreth

Implementation of the Node interface.

*/


@implementation Node{

}


- (id) getPrevious{

return previous;

}


- (id) getNext{

return next;

}


- (void) setPrevious: (id) pass{

previous = pass;

}


- (void) setNext: (id) pass{

next = pass;

}


- (int) getValue{

return value;

}


- (void) setValue: (int) pass{

value = pass;

}

@end


Stack.h

#import


/**

Author: Devin Eldreth

Header information for an Objective-C Stack

*/


@interface Stack: Object{

id top; // Point to the top of the stack

int size; // Store the size of the stack

}


- (id) pop; // Get the top most value of the stack, removing it

- (void) push: (int) value; // Put the value parameter onto the stack

- (id) peek; // Get the top most element on the stack, but don't remove it.

- (void) displayStack; // Display all of the values on the stack


- (int) empty; // Check to see if Stack is empty

@end


Stack.m

#import "Stack.h"

#import "Node.h"

#import


/**

Author: Devin Eldreth

Implementation of a Stack in Objective-C

This simple Stack uses elements referred to as Nodes (objects with a knowledge of value of previous for a Stack). In the case of a Queue these nodes would have knowledge of 

next. In a doubly linked list both previous and next.

*/


@implementation Stack{

}


// Pop the top most Node from the stack, removing it, and decrementing the size of the stack.

- (id) pop{

if(size > 0){

id ret = top;

top = [top getPrevious];

size--;

return ret;

}

else{

return NULL;

}

}


// Return the top most Node on the Stack, do not remove it, and do not decrement the size of the Stack.

- (id) peek{

if(size > 0){

return top;

}

else{

return NULL;

}

}


// Push an integer value onto the top of the Stack. If the stack is new create a new Node to be the top.

- (void) push: (int) passed{

if(size == 0){

top = [Node new];

[top setValue: passed];

[top setPrevious: NULL];

}

else{

id newNode = [Node new];

id previous = top;

[newNode setValue: passed];

top = newNode;

[top setPrevious: previous];

}

size++;

}


// Return 1 if the Stack is empty and 0 if it is not empty

- (int) empty{

if(size == 0){

return 1;

}

else{

return 0;

}

}


// Display all of the values held inside of the Stack.

- (void) displayStack{

id counter;

int position = size;

if(size == 0){

printf("Empty Stack\n");

}

else{

counter = top;

while(counter != NULL){

printf("Stack[%d]: %d\n", position, [counter getValue]);

counter = [counter getPrevious];

position--;

}

printf("\n");

}

}


@end