Skip to content

Instantly share code, notes, and snippets.

@wd5gnr
Last active June 19, 2023 20:47
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 wd5gnr/68d067c3c42a2e0e9a27b083e01f7080 to your computer and use it in GitHub Desktop.
Save wd5gnr/68d067c3c42a2e0e9a27b083e01f7080 to your computer and use it in GitHub Desktop.
RPN in Python or C
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
float stack[32];
unsigned sp=0;
void rpn(int argc, char **argv)
{
while (argc--)
{
char *token=*argv++;
if (isdigit(*token) || strlen(token)>1) stack[sp++]=atof(token);
else
{
switch (*token)
{
case '+':
stack[sp-2]=stack[sp-1]+stack[sp-2];
sp--;
break;
case '-':
stack[sp-2]=stack[sp-2]-stack[sp-1];
sp--;
break;
case '*':
stack[sp-2]=stack[sp-2]*stack[sp-1];
sp--;
break;
case '/':
stack[sp-2]=stack[sp-2]/stack[sp-1];
sp--;
break;
default:
printf("Error\n");
}
}
}
}
// Note: no error checking for stack over/under flow -- should fix
int main(int argc, char *argv[])
{
int i;
rpn(argc-1,argv+1);
for (i=sp-1;i>=0;i--)
printf("%f\n",stack[i]);
return 0;
}
# Do RPN in Python
class RPN:
def __init__(self):
self.stack=[] # each instance has its own stack which is really a list
self.vars={} # variables
# push on the stack
def push(cls,v):
cls.stack.append(v)
# pop off the stack
def pop(self):
return self.stack.pop()
# basic math (should add more)
def add(self):
t=self.stack.pop()+self.stack.pop()
self.push(t)
def sub(self):
t=self.stack.pop()
t=self.stack.pop()-t
self.push(t)
def mul(self):
self.push(self.pop()*self.pop())
def div(self):
t=self.pop()
t=self.pop()/t
self.push(t)
# Look at the top of the stack with no change
def peek(self):
return self.stack[-1]
# dump the stack with not change
def dump(self):
print(self.stack)
def clear(self): # clear stack
self.stack=[]
def wipe(self): # reset everthing
self.clear()
self.vars=[]
def exchange(self):
t=self.pop()
t1=self.pop()
self.push(t)
self.push(t1)
# parse an RPN string and execute it
def parse(self,s):
tokens=s.split()
for token in tokens:
try:
num=float(token)
rpn.push(num)
except ValueError:
if token=="x" or token=="X": # exchange top of stack
exchange()
elif token=="?": # dump stack
self.dump()
elif token=="+":
rpn.add()
elif token=='-':
rpn.sub()
elif token=="*":
rpn.mul()
elif token=="/":
rpn.div()
elif token[0]=="!":
self.vars[token[1:]]=self.peek() # store tos in var
elif token[0]=="@":
self.push(self.vars[token[1:]]) # push var to tos
else:
raise Exception("Unknown operator or number "+token)
rpn=RPN()
# we could parse a string
rpn.parse("5 2 + -3 - 10 +") # equiv y=5+2-(-3)+10 = 20
rpn.dump()
# or do it all manaully
rpn.push(10)
print(rpn.peek())
rpn.push(99)
print(rpn.peek())
rpn.add();
print(rpn.pop())
rpn.pop() # get rid of that old 20.0 from before
# test variables
rpn.parse("50 20 + !temp")
rpn.pop()
rpn.parse("2 @temp * ?")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment