def eval(self, form, env, maxInstructions=None): self.maxInstructions = maxInstructions self.instructions = 0 try: try: return context.call({'SL-interp': self}, self.evalForm, form, env) except: # XXX This is _really_ not how it should be. # Firstly, the thing that handles Python exceptions # should be separate from the thing that handles # Safelisp exceptions. Of course, that implies that # Safelisp has its _own_ exception system. Then, of # course, the arguments to *exc-handler* should be a # Safelisp-representation of the exception and # traceback objects. exch = E.lookup(env, '*exc-handler*') if exch: if isinstance(exch, O.Function): stuff = sys.exc_info() errorclass = stuff[0].__name__ errormessage = str(stuff[1]) frames = self.frames[:] context.call({'SL-interp': self}, exch.callFunc, self, O.List([errorclass, errormessage, frames])) else: exch(self) self.frames = [] else: self.frames = [] raise finally: self.maxInstructions = None
def evalForm(self, form, env): """ Evaluate a form in an environment """ assert context.get('SL-interp', None) is not None, "Only call evalForm from within eval!" if self.maxInstructions: self.instructions += 1 if self.instructions > self.maxInstructions: raise TooManyInstructions("Your limit is %s, buddy." % self.maxInstructions) # XXX This code is *riddled* with isinstance. What's a better solution? if not isinstance(form, O.SLObject): raise UnevaluableError("I cannot evaluate %s." % form) if isinstance(form, O.Identifier): return E.lookup(env, form.name) if not isinstance(form, O.List): return form if isinstance(form, O.List): value = form.pyvalue if not value: raise SyntaxError("Empty call.") if isinstance(value[0], O.Identifier): name = value[0].name func = self.specials.get(name, None) if func: return func(self, form, env) func = self.evalForm(value[0], env) #print "GOT THE FUNC", func, "FROM", value if isinstance(func, O.Macro): return func.callMacro(self, env, value[1:]) # Must be a function call: LispEvaluate the # elements of the list args = [self.evalForm(x, env) for x in value[1:]] if isinstance(func, O.Function): return func.callFunc(self, O.List(args)) # must be a python extension... r = context.call({'SL-env': env}, func, *args) return r raise RuntimeError("This is a bug. What the heck is %s?" % repr(form))