Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """RPN language interpreter"""
- # Built-in words
- # math words
- def plus(i): i.stack.append(i.stack.pop()+i.stack.pop())
- def minus(i): i.stack[-2:] = [i.stack[-2] - i.stack[-1]]
- def mul(i): i.stack.append(i.stack.pop()*i.stack.pop())
- def div(i): i.stack[-2:] = [i.stack[-2] / i.stack[-1]]
- #comparison words
- def lt(i): i.stack[-2:] = [int(i.stack[-2] < i.stack[-1])]
- def gt(i): i.stack[-2:] = [i.stack[-2] > i.stack[-1]]
- def lte(i): i.stack[-2:] = [i.stack[-2] <= i.stack[-1]]
- def gte(i): i.stack[-2:] = [i.stack[-2] >= i.stack[-1]]
- def eq(i): i.stack[-2:] = [i.stack[-2] == i.stack[-1]]
- def neq(i): i.stack[-2:] = [i.stack[-2] != i.stack[-1]]
- # stack manipulation words
- def dup(i): i.stack.append(i.stack[-1])
- def swap(i): i.stack[-2:] = [i.stack[-1], i.stack[-2]]
- def pop(i): i.stack.pop()
- # i/o words
- def echo(i): print i.stack.pop(),
- def echo_nl(i): print i.stack.pop()
- def read_int(i): i.stack.append(int(raw_input()))
- def read_string(i): i.stack.append(raw_input())
- def dot(i): print i.stack
- # other
- def ifthen(i): expr = i.stack.pop() bool = i.stack.pop()
- if bool: i.run(expr) i.stack.append(1)
- else: i.stack.append(0)
- def ifelse(i):
- """If the second from the top item on the
- stack is false, run the top item on the stack. otherwise
- don't. This can be used as the else portion of an
- if-else statement. """
- 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
- # a class to differentiate words from strings
- class Parser:
- whitespace = set(" \t\n")
- string_delimiters = set('\'"')
- numerals = set('0123456789')
- white_and_sub = whitespace | set('}')
- qdef __init__(self, to_parse=''):
- self.in_str = to_parse self.pos = 0
- # current parsing position
- self.len = len(to_parse) def skip_whitespace(self):
- while self.pos < self.len and self.in_str[self.pos] in self.whitespace: self.pos += 1 def read_to(self, delim, escape=False):
- start = self.pos while self.pos < self.len and self.in_str[self.pos] not in delim:
- 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):
- """ Reads an expression made up of space separated numbers, strings, "words", and sub-expressions """
- expr = [[]] while self.pos < self.len: self.skip_whitespace() #print 'expr:', expr, ', current:', "'"+self.in_str[self.pos]+"'", ', rest:', self.in_str[self.pos:]
- char = self.in_str[self.pos] if char in self.string_delimiters:
- self.pos += 1 expr[-1].append(self.read_to(char, escape=True)) self.pos += 1 elif char in self.numerals:
- expr[-1].append(eval(self.read_to(self.white_and_sub))) elif char == '{':
- # start a new sub_expression
- self.pos += 1 expr.append([]) elif char == '}':
- # append the sub_expression to the expression above it
- self.pos +=1 sub_expr = expr.pop() expr[-1].append(sub_expr)
- else:
- word = self.read_to(self.white_and_sub) expr[-1].append(Word(word)) return expr[0] if __name__ == "__main__":
- 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