Advertisement
zenware

RPN Interpreter

Feb 10th, 2012
398
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.74 KB | None | 0 0
  1. """RPN language interpreter"""
  2.  
  3. # Built-in words
  4. # math words
  5.  
  6. def plus(i): i.stack.append(i.stack.pop()+i.stack.pop())
  7. def minus(i): i.stack[-2:] = [i.stack[-2] - i.stack[-1]]
  8. def mul(i): i.stack.append(i.stack.pop()*i.stack.pop())
  9. def div(i): i.stack[-2:] = [i.stack[-2] / i.stack[-1]]
  10.  
  11. #comparison words
  12.  
  13. def lt(i): i.stack[-2:] = [int(i.stack[-2] < i.stack[-1])]
  14. def gt(i): i.stack[-2:] = [i.stack[-2] > i.stack[-1]]
  15. def lte(i): i.stack[-2:] = [i.stack[-2] <= i.stack[-1]]
  16. def gte(i): i.stack[-2:] = [i.stack[-2] >= i.stack[-1]]
  17. def eq(i): i.stack[-2:] = [i.stack[-2] == i.stack[-1]]
  18. def neq(i): i.stack[-2:] = [i.stack[-2] != i.stack[-1]]
  19.  
  20. # stack manipulation words
  21.  
  22. def dup(i): i.stack.append(i.stack[-1])
  23. def swap(i): i.stack[-2:] = [i.stack[-1], i.stack[-2]]
  24. def pop(i): i.stack.pop()
  25.  
  26. # i/o words
  27.  
  28. def echo(i): print i.stack.pop(),
  29. def echo_nl(i): print i.stack.pop()
  30. def read_int(i): i.stack.append(int(raw_input()))
  31. def read_string(i): i.stack.append(raw_input())
  32. def dot(i): print i.stack
  33.  
  34. # other
  35.  
  36. def ifthen(i): expr = i.stack.pop() bool = i.stack.pop()
  37.      if bool: i.run(expr) i.stack.append(1)
  38.          else: i.stack.append(0)
  39. def ifelse(i):
  40.              """If the second from the top item on the
  41. stack is false, run the top item on the stack. otherwise
  42. don't. This can be used as the else portion of an
  43. if-else statement. """
  44. def add_word(i): expr = i.stack.pop() name = i.stack.pop() i.words[name] = lambda i: i.run(expr) builtins = { '+': plus, '-': minus, '*': mul, '/': div, 'dup': dup, 'swap': swap, 'echo': echo, 'echo_nl': echo_nl, 'pop': pop, '<': lt, '>': gt, '<=': lte, '>=': gte, '=': eq, '!=': neq, 'read_int': read_int, 'read_string': read_string, '.': dot, 'add_word': add_word, 'if': ifthen, 'else': ifelse } class Interpreter: def __init__(self): self.stack = [] self.words = builtins def eval(self, expr_str): parser = Parser(expr_str) expr = parser.parse() self.run(expr) def run(self, expr): for i in expr: if isinstance(i, Word): self.words[i](self) else: self.stack.append(i) class Word (str): pass
  45.  
  46. # a class to differentiate words from strings
  47. class Parser:
  48.     whitespace = set(" \t\n")
  49.     string_delimiters = set('\'"')
  50.     numerals = set('0123456789')
  51.     white_and_sub = whitespace | set('}')
  52.     qdef __init__(self, to_parse=''):
  53.         self.in_str = to_parse self.pos = 0
  54.         # current parsing position
  55.         self.len = len(to_parse) def skip_whitespace(self):
  56.         while self.pos < self.len and self.in_str[self.pos] in self.whitespace: self.pos += 1 def read_to(self, delim, escape=False):
  57.             start = self.pos while self.pos < self.len and self.in_str[self.pos] not in delim:
  58.                 if escape and self.in_str[self.pos] == '\\' and self.in_str[self.pos+1] == delim: self.pos += 2 else: self.pos += 1 return self.in_str[start:self.pos] def parse(self):
  59. """ Reads an expression made up of space separated numbers, strings, "words", and sub-expressions """
  60.     expr = [[]] while self.pos < self.len: self.skip_whitespace() #print 'expr:', expr, ', current:', "'"+self.in_str[self.pos]+"'", ', rest:', self.in_str[self.pos:]
  61. char = self.in_str[self.pos] if char in self.string_delimiters:
  62.     self.pos += 1 expr[-1].append(self.read_to(char, escape=True)) self.pos += 1 elif char in self.numerals:
  63.     expr[-1].append(eval(self.read_to(self.white_and_sub))) elif char == '{':
  64. # start a new sub_expression
  65.         self.pos += 1 expr.append([]) elif char == '}':
  66. # append the sub_expression to the expression above it
  67.             self.pos +=1 sub_expr = expr.pop() expr[-1].append(sub_expr)
  68.     else:
  69.         word = self.read_to(self.white_and_sub) expr[-1].append(Word(word)) return expr[0] if __name__ == "__main__":
  70.      i = Interpreter() while True: try: input = raw_input('> ') except EOFError: break if input == 'quit': break else: i.eval(input)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement