Jump to content


Check out our Community Blogs

DarkLordCthulhu

Member Since 15 Jul 2010
Offline Last Active Dec 22 2015 02:26 PM
-----

Topics I've Started

An RPN calculator in C

08 November 2015 - 08:51 AM

It's been a long time since I posted anything to the code snippets forum.  This is just something I hacked out in C yesterday.  I had started on a similar project for a stack-based RPN calculator months earlier, but the implementation was far more convoluted, and I did it completely wrong.  Originally I had planned to push both the operands and the operators onto the stack.  In reality, it only works if you push the operands onto the stack and the operators are commands to pop the stack and push the result onto the stack.  This calculator only works with integers, because I was interested more in the structure of programming on the stack than in the details of converting between strings and floating point values.  Also, unlike dc, I had it parse its input directly from the command line, because that was just faster.  I haven't tested the program completely, so some parts (particularly subtraction and division) might be a bit wonky.  Feel free to tell me if you find any bugs.  Here's the code:

 

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
 
struct stack_item {
        int value;
        struct stack_item *down;
};
 
struct stack_item *top;
struct stack_item *new; // Used for mallocing new structs for the stack
 
void push( int );
int pop( void );
int add( void );
int sub( void );
int mul( void );
int idiv( void );
 
int main( int argc, char **argv ){
        top = (struct stack_item *) malloc( sizeof( struct stack_item ) );
        for( int i = 0; i < argc; i++ ){
                if( isdigit( argv[i][0] ) ) push( atoi( argv[i] ) );
                else if( argv[i][0] == '+' ) push( add() );
                else if( argv[i][0] == '-' ) push( sub() );
                else if( argv[i][0] == 'x' ) push( mul() ); // I have to use x because * will be interpreted as a wildcard by the shell.
                else if( argv[i][0] == '/' ) push( idiv() );
        }
        printf( "%d\n", top->value );
        return 0;
}
 
void push( int num ){
        new = (struct stack_item *) malloc( sizeof( struct stack_item ) );
        new->value = num;
        new->down = top;
        top = new;
}
 
int pop(){
        struct stack_item *tmp_ptr = top;
        int tmp_val = top->value;
        top = top->down;
        free( tmp_ptr );
        return tmp_val;
}
 
int add(){
        return pop() + pop();
}
 
int sub(){
        return 0 - pop() + pop();
}
 
int mul(){
        return pop() * pop();
}
 
int idiv(){
        return 10000 / pop() * pop() * 10000;
}