Implement StaticMultiMethod

This commit is contained in:
Siu Kwan Lam 2013-01-22 15:33:23 -06:00
commit bd550e3c0e
3 changed files with 59 additions and 2 deletions

View file

@ -314,6 +314,11 @@ class Class(Binding):
mm = MultiMethod(self, signatures)
self.methods.append(mm)
return mm
def staticmultimethod(self, *signatures):
smm = StaticMultiMethod(self, signatures)
self.methods.append(smm)
return smm
def compile(self, name, println):
# set name
@ -518,6 +523,53 @@ class StaticMethod(Method):
println('%s;' % call)
return_none(println)
class StaticMultiMethod(Binding):
'''Can only differs by the number of arguments.
'''
def __init__(self, cls, signatures):
super(StaticMultiMethod, self).__init__()
nargs = set()
for sig in signatures:
n = len(sig)
if n in nargs:
raise TypeError("StaticMultiMethod only supports overloaded "
"version with different number of arguments")
nargs.add(n)
self.cls = cls
self.signatures = signatures
self.name = None
def compile(self, name, println):
# set name
self.name = self.name or name
# generate wrapper
println('static')
println('PyObject*')
mangled = self.mangled_name
println('%(mangled)s(PyObject* self, PyObject* args)' % locals())
println('{')
println2 = indent_println(println)
nargs = declare(println2, 'Py_ssize_t', 'PyTuple_Size(args)')
for sig in self.signatures:
expect = len(sig) - 1
println2('if (%(nargs)s == %(expect)d) {' % locals())
method = StaticMethod(self.cls, sig[0], *sig[1:])
method.name = self.name
method.compile_body(indent_println(println2))
println2('}')
println2('PyErr_SetString(PyExc_TypeError, "Wrong # of args");')
println2('return NULL;')
println('}')
@property
def fullname(self):
return '::'.join([self.cls.fullname, self.name])
@property
def mangled_name(self):
return mangle(self.fullname)
class Constructor(StaticMethod):
def compile_body(self, println):
args = parse_arguments(println, 'args', *self.args)

View file

@ -128,7 +128,8 @@ class Context(object):
# generate class methods
for method in cls.methods:
name = method.name
if isinstance(method, StaticMethod):
if(isinstance(method, StaticMethod) or
isinstance(method, StaticMultiMethod)):
println('@staticmethod')
println('def %(name)s(*args):' % locals())
println2 = indent_println(println)

View file

@ -6,7 +6,11 @@ from Type import Type
FunctionType = Type.Subclass()
FunctionType.include.add('llvm/DerivedTypes.h')
get = FunctionType.staticmethod(FunctionType.Pointer, Type.Pointer, Bool.From(bool))
get = FunctionType.staticmultimethod([FunctionType.Pointer,
Type.Pointer, Bool.From(bool)],)
# (FunctionType.Pointer,
# Type.Pointer, )])
isVarArg = FunctionType.method(Bool.To(bool))
getReturnType = FunctionType.method(Type.Pointer)
getParamType = FunctionType.method(Type.Pointer, Unsigned.From(int))