*** empty log message ***

This commit is contained in:
Joe Shochet 2000-11-08 19:34:34 +00:00
parent 1e61b1190e
commit 76a8f5abac
4 changed files with 73 additions and 86 deletions

View File

@ -13,7 +13,7 @@ import FFISpecs
import FFIRename import FFIRename
import FFIConstants import FFIConstants
import FFIOverload import FFIOverload
from PythonUtil import *
# FFIConstants.notify.setDebug(1) # FFIConstants.notify.setDebug(1)
FFIConstants.notify.info('Importing interrogate library: ' + FFIConstants.InterrogateModuleName) FFIConstants.notify.info('Importing interrogate library: ' + FFIConstants.InterrogateModuleName)
@ -622,35 +622,6 @@ class FFIInterrogateDatabase:
newGlob = self.constructGlobalFunction(funcIndex) newGlob = self.constructGlobalFunction(funcIndex)
if newGlob: if newGlob:
self.environment.addGlobalFunction(newGlob) self.environment.addGlobalFunction(newGlob)
"""
# Take all the global functions that have a Panda Class as their
# first argument and make them class methods on that class
# For example the global function
# get_distance(node1, node2)
# becomes:
# node1.getDistance(node2)
# Functions that do not get moved will be stored here temporarily
tempGlobalFunctions = []
for funcSpec in self.environment.globalFunctions:
# If there are any arguments
if (len(funcSpec.typeDescriptor.argumentTypes) > 0):
# If the first argument is a class type descriptor
methodArgSpec = funcSpec.typeDescriptor.argumentTypes[0]
argBaseType = methodArgSpec.typeDescriptor.recursiveTypeDescriptor()
if isinstance(argBaseType, FFITypes.ClassTypeDescriptor):
# Move this global function into the class
argBaseType.globalMethods.append(funcSpec)
else:
# Copy this function into the temp list
tempGlobalFunctions.append(funcSpec)
else:
# Copy this function into the temp list
tempGlobalFunctions.append(funcSpec)
# Copy the temp list back over the real list
self.environment.globalFunctions = tempGlobalFunctions
"""
def addGlobalValues(self, CModuleName): def addGlobalValues(self, CModuleName):
numGlobals = interrogate_number_of_globals() numGlobals = interrogate_number_of_globals()
@ -660,7 +631,6 @@ class FFIInterrogateDatabase:
if newGlob: if newGlob:
self.environment.addGlobalValue(newGlob) self.environment.addGlobalValue(newGlob)
def constructManifest(self, manifestIndex): def constructManifest(self, manifestIndex):
descriptor = None descriptor = None
intValue = None intValue = None
@ -757,6 +727,18 @@ class FFIInterrogateDatabase:
# Output all the imports based on this list of functions # Output all the imports based on this list of functions
outputGlobalFileImports(globalFile, globalFunctions, CModuleName) outputGlobalFileImports(globalFile, globalFunctions, CModuleName)
# Generate overloading
overloadedGlobalFunctions = {}
for methodSpec in globalFunctions:
methodList = ifAbsentPut(overloadedGlobalFunctions, methodSpec.name, [])
methodList.append(methodSpec)
overloadedGlobalFunctions = FFIOverload.cullOverloadedMethods(overloadedGlobalFunctions)
for methodSpecList in overloadedGlobalFunctions.values():
treeColl = FFIOverload.FFIMethodArgumentTreeCollection(None, methodSpecList)
treeColl.generateCode(globalFile, -1)
FFIConstants.notify.info( 'Generating global value code...') FFIConstants.notify.info( 'Generating global value code...')
for type in self.environment.globalValues: for type in self.environment.globalValues:
type.generateGlobalCode(globalFile) type.generateGlobalCode(globalFile)

View File

@ -21,6 +21,25 @@ AT_char = 5
AT_void = 6 AT_void = 6
AT_string = 7 AT_string = 7
def cullOverloadedMethods(fullMethodDict):
"""
Find all the entries that have multiple indexes for the same method name
Get rid of all others.
"""
tmpDict = {}
# For each class
for methodName in fullMethodDict.keys():
methodList = fullMethodDict[methodName]
# See if this method has more than one function index (overloaded)
if (len(methodList) > 1):
tmpDict[methodName] = methodList
# Mark all the method specifications as overloaded
for methodSpec in methodList:
methodSpec.overloaded = 1
return tmpDict
def getTypeName(classTypeDesc, typeDesc): def getTypeName(classTypeDesc, typeDesc):
""" """
Map the interrogate primitive type names to python type names. Map the interrogate primitive type names to python type names.
@ -161,10 +180,11 @@ class FFIMethodArgumentTreeCollection:
# Constructors are not treated as static. They are special because # Constructors are not treated as static. They are special because
# they are not really constructors, they are instance methods that fill # they are not really constructors, they are instance methods that fill
# in the this pointer. # in the this pointer.
# Global functions do not need static versions
if (self.methodSpecList[0].isStatic() and if (self.methodSpecList[0].isStatic() and
(not self.methodSpecList[0].isConstructor())): (not self.methodSpecList[0].isConstructor())):
indent(file, nesting+1, 'def ' + indent(file, nesting+1, 'def ' +
self.methodSpecList[0].name + '(*_args):\n') self.methodSpecList[0].name + '(*_args):\n')
else: else:
indent(file, nesting+1, 'def ' + indent(file, nesting+1, 'def ' +
self.methodSpecList[0].name + '(self, *_args):\n') self.methodSpecList[0].name + '(self, *_args):\n')
@ -180,7 +200,8 @@ class FFIMethodArgumentTreeCollection:
# in the this pointer. # in the this pointer.
if (self.methodSpecList[0].isStatic() and if (self.methodSpecList[0].isStatic() and
(not self.methodSpecList[0].isConstructor())): (not self.methodSpecList[0].isConstructor()) and
(not isinstance(self.methodSpecList[0], FFISpecs.GlobalFunctionSpecification))):
self.outputOverloadedStaticFooter(file, nesting) self.outputOverloadedStaticFooter(file, nesting)
indent(file, nesting+1, '\n') indent(file, nesting+1, '\n')
@ -216,7 +237,7 @@ class FFIMethodArgumentTreeCollection:
else: else:
indent(file, nesting+2, 'elif (numArgs == ' + `numArgs` + '):\n') indent(file, nesting+2, 'elif (numArgs == ' + `numArgs` + '):\n')
tree.setup() tree.setup()
tree.traverse(file, nesting+1) tree.traverse(file, nesting+1, 0)
# If the overloaded function got all the way through the if statements # If the overloaded function got all the way through the if statements
# it must have had the wrong number or type of arguments # it must have had the wrong number or type of arguments
@ -278,7 +299,7 @@ class FFIMethodArgumentTree:
# This subtree has no method spec # This subtree has no method spec
self.tree[typeDesc] = [subTree, None] self.tree[typeDesc] = [subTree, None]
def traverse(self, file, level=1): def traverse(self, file, nesting, level):
oneTreeHasArgs = 0 oneTreeHasArgs = 0
typeNameList = [] typeNameList = []
# Make a copy of the keys so we can sort them in place # Make a copy of the keys so we can sort them in place
@ -291,7 +312,7 @@ class FFIMethodArgumentTree:
if (typeDesc == 0): if (typeDesc == 0):
# Output the function # Output the function
methodSpec = self.tree[0][1] methodSpec = self.tree[0][1]
indent(file, level+2, 'return ') indent(file, nesting+2, 'return ')
methodSpec.outputOverloadedCall(file, self.classTypeDesc, 0) methodSpec.outputOverloadedCall(file, self.classTypeDesc, 0)
else: else:
# Specify that at least one of these trees had arguments # Specify that at least one of these trees had arguments
@ -300,32 +321,32 @@ class FFIMethodArgumentTree:
typeName = getTypeName(self.classTypeDesc, typeDesc) typeName = getTypeName(self.classTypeDesc, typeDesc)
typeNameList.append(typeName) typeNameList.append(typeName)
if (i == 0): if (i == 0):
indent(file, level+2, 'if (isinstance(_args[' + `level-1` + '], ' indent(file, nesting+2, 'if (isinstance(_args[' + `level` + '], '
+ typeName + typeName
+ '))') + '))')
else: else:
indent(file, level+2, 'elif (isinstance(_args[' + `level-1` + '], ' indent(file, nesting+2, 'elif (isinstance(_args[' + `level` + '], '
+ typeName + typeName
+ '))') + '))')
# If it is looking for a float, make it accept an integer too # If it is looking for a float, make it accept an integer too
if (typeName == 'types.FloatType'): if (typeName == 'types.FloatType'):
file.write(' or (isinstance(_args[' + `level-1` + '], ' file.write(' or (isinstance(_args[' + `level` + '], '
+ 'types.IntType' + 'types.IntType'
+ '))') + '))')
file.write(':\n') file.write(':\n')
# Get to the bottom of this chain # Get to the bottom of this chain
if (self.tree[typeDesc][0] != None): if (self.tree[typeDesc][0] != None):
self.tree[typeDesc][0].traverse(file, level+1) self.tree[typeDesc][0].traverse(file, nesting+1, level+1)
else: else:
# Output the function # Output the function
methodSpec = self.tree[typeDesc][1] methodSpec = self.tree[typeDesc][1]
indent(file, level+3, 'return ') indent(file, nesting+3, 'return ')
numArgs = level numArgs = level+1
methodSpec.outputOverloadedCall(file, self.classTypeDesc, numArgs) methodSpec.outputOverloadedCall(file, self.classTypeDesc, numArgs)
# Output an else clause if one of the trees had arguments # Output an else clause if one of the trees had arguments
if oneTreeHasArgs: if oneTreeHasArgs:
indent(file, level+2, 'else:\n') indent(file, nesting+2, 'else:\n')
indent(file, level+3, "raise TypeError, 'Invalid argument " + `level-1` + ", expected one of: ") indent(file, nesting+3, "raise TypeError, 'Invalid argument " + `level` + ", expected one of: ")
for name in typeNameList: for name in typeNameList:
indent(file, 0, ('<' + name + '> ')) indent(file, 0, ('<' + name + '> '))
indent(file, 0, "'\n") indent(file, 0, "'\n")

View File

@ -99,18 +99,29 @@ class FunctionSpecification:
These do not get indented because they are not the beginning of the line These do not get indented because they are not the beginning of the line
""" If classTypeDesc is None, then this is a global function and should
if (self.isStatic() and not self.isConstructor()): output code as such
indent(file, 0, classTypeDesc.foreignTypeName + '.' + self.getFinalName() + '(')
else:
indent(file, 0, 'self.' + self.getFinalName() + '(')
for i in range(numArgs):
file.write('_args[' + `i` + ']')
if (i != (numArgs - 1)):
file.write(', ')
file.write(')\n')
"""
if classTypeDesc:
if (self.isStatic() and not self.isConstructor()):
indent(file, 0, classTypeDesc.foreignTypeName + '.' + self.getFinalName() + '(')
else:
indent(file, 0, 'self.' + self.getFinalName() + '(')
for i in range(numArgs):
file.write('_args[' + `i` + ']')
if (i != (numArgs - 1)):
file.write(', ')
file.write(')\n')
else:
indent(file, 0, self.getFinalName() + '(')
for i in range(numArgs):
file.write('_args[' + `i` + ']')
if (i != (numArgs - 1)):
file.write(', ')
file.write(')\n')
class GlobalFunctionSpecification(FunctionSpecification): class GlobalFunctionSpecification(FunctionSpecification):
def __init__(self): def __init__(self):

View File

@ -338,37 +338,10 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
def cullOverloadedMethods(self): def cullOverloadedMethods(self):
""" """
Find all the entries that have multiple indexes for the same method name Find all the entries that have multiple indexes for the same method name
Get rid of all others. Get rid of all others. Do this for class methods and instance methods
""" """
tmpDict = {} self.overloadedClassMethods = FFIOverload.cullOverloadedMethods(self.overloadedClassMethods)
# For each class self.overloadedInstanceMethods = FFIOverload.cullOverloadedMethods(self.overloadedInstanceMethods)
for methodName in self.overloadedClassMethods.keys():
methodList = self.overloadedClassMethods[methodName]
# See if this method has more than one function index (overloaded)
if (len(methodList) > 1):
tmpDict[methodName] = methodList
# Mark all the method specifications as overloaded
for methodSpec in methodList:
methodSpec.overloaded = 1
# Now we are done. Jam the tmpDict into the real one
self.overloadedClassMethods = tmpDict
# Now do the same for instance methods
tmpDict = {}
# For each class
for methodName in self.overloadedInstanceMethods.keys():
methodList = self.overloadedInstanceMethods[methodName]
# See if this method has more than one function index (overloaded)
if (len(methodList) > 1):
# Copy over the method list
tmpDict[methodName] = methodList
# Mark all the method specifications as overloaded
for methodSpec in methodList:
methodSpec.overloaded = 1
# Now we are done. Jam the tmpDict into the real one
self.overloadedInstanceMethods = tmpDict
def filterOutStaticMethods(self): def filterOutStaticMethods(self):
""" """