예제 #1
0
    def convertClassInstanceDescription(self, objectId, classInstanceDescription, convertedValues):
        classMemberNameToImplVal = {
            classMemberName: convertedValues[memberId]
            for classMemberName, memberId in
            classInstanceDescription.classMemberNameToClassMemberId.iteritems()
            }
        classImplVal = convertedValues[classInstanceDescription.classId]

        if classImplVal.isSymbol():
            convertedValues[objectId] = classImplVal
            return

        memberNames = tuple(sorted(name for name in classMemberNameToImplVal.iterkeys()))
        memberValues = tuple(classMemberNameToImplVal[name] for name in memberNames)
        convertedValueOrNone = ForaNative.simulateApply(
            ForaNative.ImplValContainer(
                (classImplVal,
                 Symbol_CreateInstance,
                 ForaNative.CreateNamedTuple(memberValues, memberNames))
                )
            )

        if convertedValueOrNone is None:
            raise pyfora.PythonToForaConversionError(
                ("An internal error occurred: " +
                 "function stage 1 simulation unexpectedly returned None")
                )

        convertedValues[objectId] = convertedValueOrNone
예제 #2
0
    def _specializeFreeVariablesAndEvaluate(
            self,
            foraExpression,
            renamedVariableMapping
            ):
        allAreIVC = True
        for _, v in renamedVariableMapping.iteritems():
            if not isinstance(v, ForaNative.ImplValContainer):
                allAreIVC = False

        if allAreIVC:
            missingVariableDefinitions = [
                x for x in foraExpression.freeVariables if x not in renamedVariableMapping
                ]

            if missingVariableDefinitions:
                raise pyfora.PythonToForaConversionError(
                    ("An internal error occurred: we didn't provide a " +
                     "definition for the following variables: %s" % missingVariableDefinitions +
                     ". Most likely, there is a mismatch between our analysis of the "
                     "python code and the generated FORA code underneath. Please file a bug report."
                    ))

            #we need to determine whether we should bind the free variables in this expression as constants
            #inline in the code, or as class members. Binding them as constants speeds up the compiler,
            #but if we have the same function bound repeatedly with many constants, we'll end up
            #producing far too much code. This algorithm binds as constants the _First_ time we bind
            #a given expression with given arguments, and as members any future set of times. This
            #should cause it to bind modules and classes that don't have any data flowing through them
            #as constants, and closures and functions we're calling repeatedly using class members.
            shouldMapArgsAsConstants = True

            boundValues = tuple(renamedVariableMapping[k].hash for k in sorted(renamedVariableMapping))
            if foraExpression.hash() not in self.boundExpressions:
                self.boundExpressions[foraExpression.hash()] = boundValues
            else:
                bound = self.boundExpressions[foraExpression.hash()]
                if boundValues != bound:
                    shouldMapArgsAsConstants = False

            return ForaNative.evaluateRootLevelCreateObjectExpression(
                foraExpression,
                renamedVariableMapping,
                shouldMapArgsAsConstants
                )
        else:
            #function that evaluates the CreateObject.
            #Args are the free variables, in lexical order
            expressionAsIVC = foraExpression.toFunctionImplval(False)

            args = []
            for f in foraExpression.freeVariables:
                args.append(renamedVariableMapping[f])

            res = ComputedValue.ComputedValue(
                args=(expressionAsIVC, Symbol_Call) + tuple(args)
                )

            return res
예제 #3
0
def convertNativePythonToForaConversionError(err, path):
    """Convert a ForaNative.PythonToForaConversionError to a python version of the exception"""
    return pyfora.PythonToForaConversionError(err.error,
                                              trace=[{
                                                  'path':
                                                  path,
                                                  'line':
                                                  err.range.start.line
                                              }])
예제 #4
0
    def registerObjectMembers(self, objectImplVal, renamedObjectMapping):
        for objectId, memberName in renamedObjectMapping.iteritems():
            memberImplValOrNone = objectImplVal.getObjectMember(memberName)

            if memberImplValOrNone is None:
                raise pyfora.PythonToForaConversionError(
                    ("An internal error occurred: " +
                     "getObjectMember unexpectedly returned None"))

            self.convertedValues[objectId] = memberImplValOrNone
예제 #5
0
    def _assertContainerDoesNotReferenceItself(self, containerId,
                                               dependencyGraph,
                                               stronglyConnectedComponents):
        assert containerId in stronglyConnectedComponents[-1]

        if len(stronglyConnectedComponents[-1]) > 1 or \
           containerId in dependencyGraph[containerId]:
            raise pyfora.PythonToForaConversionError(
                "don't know how to convert lists or tuples which reference themselves"
            )
예제 #6
0
    def _getCreateObjectExpressionAndMemberToObjectIdMap(self,
                                                        objectIdToObjectDefinition,
                                                        stronglyConnectedComponent):
        naiveConvertedFunctions = dict()
        for objectId in stronglyConnectedComponent:
            objectDefinition = objectIdToObjectDefinition[objectId]

            if isinstance(objectDefinition, TypeDescription.ClassInstanceDescription):
                classDesc = objectIdToObjectDefinition[objectDefinition.classId]
                sourceFile = objectIdToObjectDefinition[classDesc.sourceFileId]
                lineNumber = classDesc.lineNumber
                raise pyfora.PythonToForaConversionError(
                    "Classes and instances cannot be mutually recursive",
                    trace=[{'path': sourceFile.path, 'line': lineNumber}]
                    )

            assert isinstance(
                objectDefinition,
                (TypeDescription.FunctionDefinition,
                 TypeDescription.ClassDefinition)), type(objectDefinition)

            naiveConvertedFunctions[objectId] = \
                self._convertPyClassOrFunctionDefinitionToForaFunctionExpression(
                    objectDefinition,
                    objectIdToObjectDefinition
                    )
        # at this point, naiveConvertedFunctions is a map: objectId -> functionExpr

        # renamedObjectMapping is a map: objectId -> varname,
        # where varname is (essentially) just the hash of the corresponding functionExpr
        renamedObjectMapping = self._computeRenamedObjectMapping(
            naiveConvertedFunctions
            )

        # replace the known free var chains in the strongly connected component
        # with the varnames coming from the renamedObjectMapping
        convertedFunctions = self._replaceKnownMemberChainsWithRenamedVariables(
            naiveConvertedFunctions,
            renamedObjectMapping,
            objectIdToObjectDefinition,
            stronglyConnectedComponent
            )

        createObjectExpression = empytObjectExpression

        for objectId, varname in sorted(renamedObjectMapping.items(), key=lambda p: p[1]):
            createObjectExpression = ForaNative.prependMemberToCreateObjectExpression(
                createObjectExpression,
                varname,
                convertedFunctions[objectId]
                )

        return createObjectExpression, renamedObjectMapping
예제 #7
0
    def convertNamedSingleton(self, objectDefinition):
        if self.singletonAndExceptionConverter is None:
            logging.error("Can't convert %s without a converter",
                          objectDefinition.singletonName)

        singleton = self.singletonAndExceptionConverter.convertSingletonByName(
            objectDefinition.singletonName)

        if singleton is None:
            raise pyfora.PythonToForaConversionError(
                "No singleton named %s" % objectDefinition.singletonName)

        return singleton
예제 #8
0
    def getCreateObjectExpressionAndMemberToObjectIdMap(
            self, objectIdToObjectDefinition, stronglyConnectedComponent):
        naiveConvertedFunctions = dict()
        for objectId in stronglyConnectedComponent:
            objectDefinition = objectIdToObjectDefinition[objectId]

            if isinstance(objectDefinition,
                          TypeDescription.ClassInstanceDescription):
                classDesc = objectIdToObjectDefinition[
                    objectDefinition.classId]
                sourceFile = objectIdToObjectDefinition[classDesc.sourceFileId]
                lineNumber = classDesc.lineNumber
                raise pyfora.PythonToForaConversionError(
                    "Classes and instances cannot be mutually recursive",
                    trace=[{
                        'path': sourceFile.path,
                        'line': lineNumber
                    }])

            assert isinstance(
                objectDefinition,
                (TypeDescription.FunctionDefinition,
                 TypeDescription.ClassDefinition)), type(objectDefinition)

            naiveConvertedFunctions[objectId] = \
                self.convertPyClassOrFunctionDefinitionToForaFunctionExpression(
                    objectDefinition,
                    objectIdToObjectDefinition
                    )

        renamedObjectMapping = self.computeRenamedObjectMapping(
            naiveConvertedFunctions)

        convertedFunctions = self.transformFunctions(
            naiveConvertedFunctions, renamedObjectMapping,
            objectIdToObjectDefinition, stronglyConnectedComponent)

        createObjectExpression = empytObjectExpression

        for objectId, functionExpression in convertedFunctions.iteritems():
            createObjectExpression = ForaNative.prependMemberToCreateObjectExpression(
                createObjectExpression, renamedObjectMapping[objectId],
                functionExpression)

        return createObjectExpression, renamedObjectMapping
예제 #9
0
    def _convert(self, objectId, dependencyGraph, objectIdToObjectDefinition):
        objectDefinition = objectIdToObjectDefinition[objectId]
        logging.info("ObjectDefinition: %s", objectDefinition)

        if TypeDescription.isPrimitive(objectDefinition) or isinstance(
                objectDefinition, list):
            return self.convertPrimitive(objectDefinition)
        elif isinstance(objectDefinition, TypeDescription.RemotePythonObject):
            return self.convertRemotePythonObject(objectDefinition)
        elif isinstance(objectDefinition, TypeDescription.NamedSingleton):
            return self.convertNamedSingleton(objectDefinition)
        elif isinstance(objectDefinition,
                        TypeDescription.BuiltinExceptionInstance):
            return self.convertBuiltinExceptionInstance(objectDefinition)
        elif isinstance(objectDefinition,
                        (TypeDescription.FunctionDefinition,
                         TypeDescription.ClassDefinition,
                         TypeDescription.ClassInstanceDescription,
                         TypeDescription.InstanceMethod)):
            return (self.convertObjectWithDependencies(
                objectId, dependencyGraph, objectIdToObjectDefinition))
        elif isinstance(objectDefinition, TypeDescription.List):
            return (self.convertList(objectId, dependencyGraph,
                                     objectIdToObjectDefinition))
        elif isinstance(objectDefinition, TypeDescription.Tuple):
            return (self.convertTuple(objectId, dependencyGraph,
                                      objectIdToObjectDefinition))
        elif isinstance(objectDefinition, TypeDescription.Dict):
            return (self.convertDict(objectId, objectDefinition,
                                     dependencyGraph,
                                     objectIdToObjectDefinition))
        elif isinstance(objectDefinition,
                        TypeDescription.WithBlockDescription):
            return (self.convertObjectWithDependencies(
                objectId, dependencyGraph, objectIdToObjectDefinition))
        else:
            raise pyfora.PythonToForaConversionError(
                "don't know how to convert %s of type %s" %
                (objectDefinition, type(objectDefinition)))
예제 #10
0
    def convertClassInstanceDescription(self, objectId,
                                        classInstanceDescription):
        classMemberNameToImplVal = {
            classMemberName: self.convertedValues[memberId]
            for classMemberName, memberId in classInstanceDescription.
            classMemberNameToClassMemberId.iteritems()
        }
        classImplVal = self.convertedValues[classInstanceDescription.classId]

        #note that we need to strip off the first character of membernames defined in the
        #class implval because the object holds 'x' as '@x' so that it doesn't capture
        #all references to 'x'
        classMembersInForaDeclarationOrder = \
            [str(val)[1:] for val in classImplVal.getDataMembers]

        assert set(classMembersInForaDeclarationOrder) == \
            set(classMemberNameToImplVal.keys()), "%s vs %s" % (
                set(classMembersInForaDeclarationOrder),
                set(classMemberNameToImplVal.keys())
                )

        classMemberImplVals = []
        for classMemberName in classMembersInForaDeclarationOrder:
            ivc = classMemberNameToImplVal[classMemberName]
            classMemberImplVals.append(ivc)

        applyArgs = [classImplVal, Symbol_CreateInstance] + classMemberImplVals

        convertedValueOrNone = ForaNative.simulateApply(
            ForaNative.ImplValContainer(tuple(applyArgs)))

        if convertedValueOrNone is None:
            raise pyfora.PythonToForaConversionError(
                ("An internal error occurred: " +
                 "function stage 1 simulation unexpectedly returned None"))

        self.convertedValues[objectId] = convertedValueOrNone
예제 #11
0
파일: Converter.py 프로젝트: ufora/ufora
 def _convert(self, objectId, dependencyGraph, objectIdToObjectDefinition):
     objectDefinition = objectIdToObjectDefinition[objectId]
     if TypeDescription.isPrimitive(objectDefinition) or isinstance(objectDefinition, list):
         return self.convertPrimitive(objectDefinition)
     elif isinstance(objectDefinition, TypeDescription.RemotePythonObject):
         return self.convertRemotePythonObject(objectDefinition)
     elif isinstance(objectDefinition, TypeDescription.NamedSingleton):
         return self.convertNamedSingleton(objectDefinition)
     elif isinstance(objectDefinition, TypeDescription.BuiltinExceptionInstance):
         return self.convertBuiltinExceptionInstance(
             objectDefinition
             )
     elif isinstance(objectDefinition,
                     (TypeDescription.FunctionDefinition,
                      TypeDescription.ClassDefinition,
                      TypeDescription.ClassInstanceDescription,
                      TypeDescription.InstanceMethod)
                    ):
         return (
             self.convertObjectWithDependencies(
                 objectId,
                 dependencyGraph,
                 objectIdToObjectDefinition
                 )
             )
     elif isinstance(objectDefinition, TypeDescription.List):
         return (
             self.convertList(
                 objectId,
                 dependencyGraph,
                 objectIdToObjectDefinition
                 )
             )
     elif isinstance(objectDefinition, TypeDescription.PackedHomogenousData):
         return (
             self.convertPackedHomogenousDataAsList(
                 objectId,
                 objectIdToObjectDefinition
                 )
             )
     elif isinstance(objectDefinition, TypeDescription.Tuple):
         return (
             self.convertTuple(
                 objectId,
                 dependencyGraph,
                 objectIdToObjectDefinition
                 )
             )
     elif isinstance(objectDefinition, TypeDescription.Dict):
         return (
             self.convertDict(
                 objectId,
                 objectDefinition,
                 dependencyGraph,
                 objectIdToObjectDefinition
                 )
             )
     elif isinstance(objectDefinition, TypeDescription.WithBlockDescription):
         return (
             self.convertObjectWithDependencies(
                 objectId,
                 dependencyGraph,
                 objectIdToObjectDefinition
                 )
             )
     elif isinstance(objectDefinition, TypeDescription.Unconvertible):
         return self.convertUnconvertibleValue(objectId, objectDefinition.module_path)
     elif isinstance(objectDefinition, TypeDescription.UnresolvedVarWithPosition):
         return self.convertUnresolvedVarWithPosition(objectId, objectDefinition)
     else:
         raise pyfora.PythonToForaConversionError(
             "don't know how to convert %s of type %s" % (
                 objectDefinition, type(objectDefinition)
                 )
             )