Kaydet (Commit) f8de0685 authored tarafından Guido van Rossum's avatar Guido van Rossum

Lots of changes.

Renamed some things.
Added support for methods directly to bgenGenerator.py.
Completely reworked buffer, string and and structure types.
üst 7cbf4803
......@@ -11,20 +11,28 @@ OUT = "out"
INOUT = IN_OUT = "in-out"
class Generator:
class FunctionGenerator:
# XXX There are some funny things with the argument list.
# XXX It would be better to get rid of this and require
# XXX each argument to be a type object or a tuple of the form
# XXX (inoutmode, typeobject, argumentname)
# XXX or possibly even a Variable() instance...
def __init__(self, *argumentList):
apply(self.parseArguments, argumentList)
def __init__(self, returntype, name, *argumentList):
self.returntype = returntype
self.name = name
self.argumentList = []
self.setreturnvar()
self.parseArgumentList(argumentList)
self.prefix = "XXX" # Will be changed by setprefix() call
self.objecttype = "PyObject" # Type of _self argument to function
self.itselftype = None # Type of _self->ob_itself, if defined
def setreturnvar(self):
if self.returntype:
self.rv = self.makereturnvar()
self.argumentList.append(self.rv)
else:
self.rv = None
def makereturnvar(self):
return Variable(self.returntype, "_rv", OutMode)
def setprefix(self, prefix):
self.prefix = prefix
......@@ -32,32 +40,12 @@ class Generator:
self.objecttype = selftype
self.itselftype = itselftype
def parseArguments(self, returnType, name, *argumentList):
if returnType:
self.rv = Variable(returnType, "_rv", OutMode)
else:
self.rv = None
self.name = name
self.argumentList = []
if self.rv:
self.argumentList.append(rv)
self.parseArgumentList(argumentList)
def parseArgumentList(self, argumentList):
from types import *
iarg = 0
for arg in argumentList:
# Arguments can either be:
# - a type
# - a tuple (type, [name, [mode]])
# - a variable
for type, name, mode in argumentList:
iarg = iarg + 1
if hasattr(arg, 'typeName'):
arg = Variable(arg)
elif type(arg) == TupleType:
arg = apply(Variable, arg)
if arg.name is None:
arg.name = "_arg%d" % iarg
if name is None: name = "_arg%d" % iarg
arg = Variable(type, name, mode)
self.argumentList.append(arg)
def reference(self, name = None):
......@@ -67,6 +55,7 @@ class Generator:
name, self.prefix, self.name)
def generate(self):
print "-->", self.name
self.functionheader()
self.declarations()
self.getargs()
......@@ -84,6 +73,7 @@ class Generator:
Output("PyObject *_args;")
DedentLevel()
OutLbrace()
Output("PyObject *_res = NULL;")
def declarations(self):
for arg in self.argumentList:
......@@ -98,7 +88,9 @@ class Generator:
continue
if arg.mode in (InMode, InOutMode):
fmt = fmt + arg.getargsFormat()
lst = lst + sep + arg.getargsArgs()
args = arg.getargsArgs()
if args:
lst = lst + sep + args
Output("if (!PyArg_ParseTuple(_args, \"%s\"%s))", fmt, lst)
IndentLevel()
Output("return NULL;")
......@@ -111,7 +103,11 @@ class Generator:
def callit(self):
args = ""
sep = ",\n" + ' '*len("%s = %s(" % (self.rv.name, self.name))
if self.rv:
s = "%s = %s(" % (self.rv.name, self.name)
else:
s = "%s(" % self.name
sep = ",\n" + ' '*len(s)
for arg in self.argumentList:
if arg is self.rv:
continue
......@@ -140,15 +136,34 @@ class Generator:
lst = lst + sep + arg.mkvalueArgs()
if fmt == "":
Output("Py_INCREF(Py_None);")
Output("return Py_None;");
Output("_res = Py_None;");
else:
Output("return Py_BuildValue(\"%s\"%s);", fmt, lst)
Output("_res = Py_BuildValue(\"%s\"%s);", fmt, lst)
tmp = self.argumentList[:]
tmp.reverse()
for arg in tmp:
if not arg: continue
if arg.flags == ErrorMode: continue
if arg.mode in (OutMode, InOutMode):
arg.mkvalueCleanup()
Output("return _res;")
def functiontrailer(self):
OutRbrace()
class ManualGenerator(Generator):
class MethodGenerator(FunctionGenerator):
def parseArgumentList(self, args):
a0, args = args[0], args[1:]
t0, n0, m0 = a0
if m0 != InMode:
raise ValueError, "method's 'self' must be 'InMode'"
self.itself = Variable(t0, "_self->ob_itself", SelfMode)
self.argumentList.append(self.itself)
FunctionGenerator.parseArgumentList(self, args)
class ManualGenerator(FunctionGenerator):
def __init__(self, name, body):
self.name = name
......
......@@ -13,7 +13,6 @@ class GeneratorGroup:
def generate(self):
for g in self.generators:
g.generate()
Output()
Output("static PyMethodDef %s_methods[] = {", self.prefix)
IndentLevel()
for g in self.generators:
......@@ -21,6 +20,7 @@ class GeneratorGroup:
Output("{NULL, NULL, 0}")
DedentLevel()
Output("};")
Output()
def _test():
......
......@@ -57,18 +57,22 @@ class ObjectDefinition(GeneratorGroup):
OutHeader2("End object type " + self.name)
def outputNew(self):
Output("static %s *%s_New(itself)", self.objecttype, self.prefix)
Output("static PyObject *%s_New(itself)", self.prefix)
IndentLevel()
Output("const %s %sitself;", self.itselftype, self.argref)
DedentLevel()
OutLbrace()
Output("%s *it;", self.objecttype)
self.outputCheckNewArg()
Output("it = PyObject_NEW(%s, &%s);", self.objecttype, self.typename)
Output("if (it == NULL) return NULL;")
Output("it->ob_itself = %sitself;", self.argref)
Output("return it;")
Output("return (PyObject *)it;")
OutRbrace()
Output()
def outputCheckNewArg(self):
pass
def outputConvert(self):
Output("""\
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment