예제 #1
0
파일: interpreter.py 프로젝트: radix/subol
 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
예제 #2
0
파일: interpreter.py 프로젝트: radix/subol
    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))