# Copyright (c) Corporation for National Research Initiatives import operator import org from BaseEvaluator import BaseEvaluator class FlowControlException(Exception): pass class DoBreak(FlowControlException): pass class DoContinue(FlowControlException): pass class DoReturn(FlowControlException): pass class PythonInterpreter(BaseEvaluator): def __init__(self): BaseEvaluator.__init__(self) self.locals = {} self.globals = {} self.builtins = makeBuiltins() #primitive values def int_const(self, value): return PyInteger(value) def float_const(self, value): return PyFloat(value) def string_const(self, value): return PyString(value) # builtin types def list_op(self, values): ret = [] for value in values: ret.append(self.visit(value).value) return PyObject(ret) def tuple_op(self, values): lst = self.list_op(values) return PyObject(tuple(lst.value)) def dictionary_op(self, items): dict = {} for key, value in items: dict[self.visit(key).value] = self.visit(value).value #namespaces def set_name(self, name, value): if self.globalnames.has_key(name): self.globals[name] = value else: #print 'setlocal', name, value self.locals[name] = value def name_const(self, name): #print 'get', self.locals if self.locals.has_key(name): return self.locals[name] elif self.globals.has_key(name): return self.globals[name] else: return self.builtins[name] def get_module(self, name): top = __import__(name[0]) for part in name[1:]: top = getattr(top, part) return PyObject(top) #flow control def pass_stmt(self): pass def continue_stmt(self): raise DoContinue def break_stmt(self): raise DoBreak def return_stmt(self, value): raise DoReturn, self.visit(value) def while_stmt(self, test, body, else_body=None): while self.visit(test).nonzero(): try: self.visit(body) except DoBreak: break except DoContinue: continue else: if else_body is not None: self.visit(else_body) def if_stmt(self, tests, else_body=None): for test, body in tests: if self.visit(test).nonzero(): return self.visit(body) if else_body != None: return self.visit(else_body) def for_stmt(self, index, sequence, body, else_body=None): seq = self.visit(sequence) i = 0 try: while 1: self.set(index, seq.getitem(PyObject(i))) i = i+1 try: self.visit(body) except DoBreak: break except DoContinue: continue except IndexError: if else_body is not None: self.visit(else_body) class PyObject: def print_line(self): print self.value def print_continued(self): print self.value, def __init__(self, value): self.value = value def nonzero(self): return not not self.value def unop(self, op): test = getattr(org.python.core.PyObject, '__'+op+'__')(self.value) return PyObject(test) def compop(self, op, y): #print 'comp', self.value, op, y.value test = getattr(org.python.core.PyObject, '_'+op)(self.value, y.value) return PyObject(test) binop = compop def getitem(self, index): return PyObject(operator.getitem(self.value, index.value)) def setitem(self, index, value): operator.setitem(self.value, index.value, value.value) def getattr(self, name): return PyObject(getattr(self.value, name)) def setattr(self, name, value): setattr(self.value, name, value.value) def call(self, args, kws): newargs = [] for arg in args: newargs.append(arg.value) newkws = {} for name, value in kws.items(): newkws[name] = value.value return PyObject(apply(self.value, tuple(newargs), newkws)) def invoke(self, name, args, kws): return self.getattr(name).call(args, kws) def dir(self): return dir(self.value) class PyInteger(PyObject): pass class PyFloat(PyObject): pass class PyString(PyObject): pass def makeBuiltins(): dict = {} import __builtin__ for name in dir(__builtin__): value = getattr(__builtin__, name) dict[name] = PyObject(value) return dict true = PyObject(1); false = PyObject(0) data = """ print 2, 2+2 print 1<2 print 1<2<3 print 3<2 print 1<3<2 print 2*8-9, 6/3 x = 99 print x y = x+9 print x, y print 'testing 1, 2, 3' if 1: print 'true' else: print 'false' i = 0 while i < 5: print i i = i+1 while i < 10: print i i = i+1 if i == 8: break print len print [1,2,3] print len([1,2,3]) import string print string.join(["a", "b"]) from string import split print split, split("a b c d e") """ pi = PythonInterpreter() pi.execstring(data)