def convert_methods(gv, cl, declare): if declare: print >>gv.out, ' PyObject *__to_py__();' else: for n in cl.module.mod_path: print >>gv.out, 'namespace __%s__ { /* XXX */' % n print >>gv.out print >>gv.out, 'PyObject *%s::__to_py__() {' % cpp.nokeywords(cl.ident) print >>gv.out, ' PyObject *p;' print >>gv.out, ' if(__ss_proxy->has_key(this))' print >>gv.out, ' p = (PyObject *)(__ss_proxy->__getitem__(this));' print >>gv.out, ' else {' print >>gv.out, ' %sObject *self = (%sObject *)(%sObjectType.tp_alloc(&%sObjectType, 0));' % (4*(clname(cl),)) print >>gv.out, ' self->__ss_object = this;' print >>gv.out, ' __ss_proxy->__setitem__(self->__ss_object, self);' print >>gv.out, ' p = (PyObject *)self;' print >>gv.out, ' }' print >>gv.out, ' Py_INCREF(p);' print >>gv.out, ' return p;' print >>gv.out, '}\n' for n in cl.module.mod_path: print >>gv.out, '} // module namespace' print >>gv.out print >>gv.out, 'namespace __shedskin__ { /* XXX */\n' print >>gv.out, 'template<> %s::%s *__to_ss(PyObject *p) {' % (cl.module.full_path(), cpp.nokeywords(cl.ident)) print >>gv.out, ' if(p == Py_None) return NULL;' print >>gv.out, ' if(PyObject_IsInstance(p, (PyObject *)&%sObjectType)!=1)' % clname(cl) print >>gv.out, ' throw new TypeError(new str("error in conversion to Shed Skin (%s expected)"));' % cl.ident print >>gv.out, ' return ((%s::%sObject *)p)->__ss_object;' % (cl.module.full_path(), clname(cl)) print >>gv.out, '}\n}'
def convert_methods2(gv): for cl in exported_classes(gv): print >>gv.out, 'extern PyTypeObject %sObjectType;' % clname(cl) print >>gv.out, 'namespace __shedskin__ { /* XXX */\n' for cl in exported_classes(gv): print >>gv.out, 'template<> %s::%s *__to_ss(PyObject *p);' % (cl.module.full_path(), cpp.nokeywords(cl.ident)) print >>gv.out, '}'
def do_extmod_class(gv, cl): for n in cl.module.mod_path: print >>gv.out, 'namespace __%s__ { /* XXX */' % n print >>gv.out # determine methods, vars to expose funcs = supported_funcs(gv, cl.funcs.values()) vars = supported_vars(cl.vars.values()) # python object print >>gv.out, '/* class %s */\n' % cl.ident print >>gv.out, 'typedef struct {' print >>gv.out, ' PyObject_HEAD' print >>gv.out, ' %s::%s *__ss_object;' % (cl.module.full_path(), cpp.nokeywords(cl.ident)) print >>gv.out, '} %sObject;\n' % clname(cl) print >>gv.out, 'static PyMemberDef %sMembers[] = {' % clname(cl) print >>gv.out, ' {NULL}\n};\n' # methods for func in funcs: do_extmod_method(gv, func) do_extmod_methoddef(gv, cl.ident, funcs, cl) # tp_init if hasmethod(cl, '__init__') and cl.funcs['__init__'] in funcs: print >>gv.out, 'int %s___tpinit__(PyObject *self, PyObject *args, PyObject *kwargs) {' % clname(cl) print >>gv.out, ' if(!%s___init__(self, args, kwargs))' % clname(cl) print >>gv.out, ' return -1;' print >>gv.out, ' return 0;' print >>gv.out, '}\n' # tp_new print >>gv.out, 'PyObject *%sNew(PyTypeObject *type, PyObject *args, PyObject *kwargs) {' % clname(cl) print >>gv.out, ' %sObject *self = (%sObject *)type->tp_alloc(type, 0);' % (clname(cl), clname(cl)) print >>gv.out, ' self->__ss_object = new %s::%s();' % (cl.module.full_path(), cpp.nokeywords(cl.ident)) print >>gv.out, ' self->__ss_object->__class__ = %s::cl_%s;' % (cl.module.full_path(), cl.ident) print >>gv.out, ' __ss_proxy->__setitem__(self->__ss_object, self);' print >>gv.out, ' return (PyObject *)self;' print >>gv.out, '}\n' # tp_dealloc print >>gv.out, 'void %sDealloc(%sObject *self) {' % (clname(cl), clname(cl)) print >>gv.out, ' self->ob_type->tp_free((PyObject *)self);' print >>gv.out, ' __ss_proxy->__delitem__(self->__ss_object);' print >>gv.out, '}\n' # getset for var in vars: print >>gv.out, 'PyObject *__ss_get_%s_%s(%sObject *self, void *closure) {' % (clname(cl), var.name, clname(cl)) print >>gv.out, ' return __to_py(self->__ss_object->%s);' % var.cpp_name() print >>gv.out, '}\n' print >>gv.out, 'int __ss_set_%s_%s(%sObject *self, PyObject *value, void *closure) {' % (clname(cl), var.name, clname(cl)) print >>gv.out, ' try {' typ = cpp.nodetypestr(var, var.parent) if typ == 'void *': # XXX investigate print >>gv.out, ' self->__ss_object->%s = NULL;' % var.cpp_name() else: print >>gv.out, ' self->__ss_object->%s = __to_ss<%s>(value);' % (var.cpp_name(), typ) print >>gv.out, ' } catch (Exception *e) {' print >>gv.out, ' PyErr_SetString(__to_py(e), ((e->msg)?(e->msg->unit.c_str()):""));' print >>gv.out, ' return -1;' print >>gv.out, ' }' print >>gv.out, ' return 0;' print >>gv.out, '}\n' print >>gv.out, 'PyGetSetDef %sGetSet[] = {' % clname(cl) for var in vars: print >>gv.out, ' {(char *)"%s", (getter)__ss_get_%s_%s, (setter)__ss_set_%s_%s, (char *)"", NULL},' % (var.name, clname(cl), var.name, clname(cl), var.name) print >>gv.out, ' {NULL}\n};\n' # python type print >>gv.out, 'PyTypeObject %sObjectType = {' % clname(cl) print >>gv.out, ' PyObject_HEAD_INIT(NULL)' print >>gv.out, ' 0, /* ob_size */' print >>gv.out, ' "%s.%s", /* tp_name */' % (cl.module.ident, cl.ident) print >>gv.out, ' sizeof(%sObject), /* tp_basicsize */' % clname(cl) print >>gv.out, ' 0, /* tp_itemsize */' print >>gv.out, ' (destructor)%sDealloc, /* tp_dealloc */' % clname(cl) print >>gv.out, ' 0, /* tp_print */' print >>gv.out, ' 0, /* tp_getattr */' print >>gv.out, ' 0, /* tp_setattr */' print >>gv.out, ' 0, /* tp_compare */' if hasmethod(cl, '__repr__'): print >>gv.out, ' (PyObject *(*)(PyObject *))%s___repr__, /* tp_repr */' % clname(cl) else: print >>gv.out, ' 0, /* tp_repr */' print >>gv.out, ' &%s_as_number, /* tp_as_number */' % clname(cl) print >>gv.out, ' 0, /* tp_as_sequence */' print >>gv.out, ' 0, /* tp_as_mapping */' print >>gv.out, ' 0, /* tp_hash */' print >>gv.out, ' 0, /* tp_call */' if hasmethod(cl, '__str__'): print >>gv.out, ' (PyObject *(*)(PyObject *))%s___str__, /* tp_str */' % clname(cl) else: print >>gv.out, ' 0, /* tp_str */' print >>gv.out, ' 0, /* tp_getattro */' print >>gv.out, ' 0, /* tp_setattro */' print >>gv.out, ' 0, /* tp_as_buffer */' print >>gv.out, ' Py_TPFLAGS_DEFAULT, /* tp_flags */' print >>gv.out, ' 0, /* tp_doc */' print >>gv.out, ' 0, /* tp_traverse */' print >>gv.out, ' 0, /* tp_clear */' print >>gv.out, ' 0, /* tp_richcompare */' print >>gv.out, ' 0, /* tp_weaklistoffset */' print >>gv.out, ' 0, /* tp_iter */' print >>gv.out, ' 0, /* tp_iternext */' print >>gv.out, ' %sMethods, /* tp_methods */' % clname(cl) print >>gv.out, ' %sMembers, /* tp_members */' % clname(cl) print >>gv.out, ' %sGetSet, /* tp_getset */' % clname(cl) if cl.bases and not cl.bases[0].mv.module.builtin: print >>gv.out, ' &%sObjectType, /* tp_base */' % clname(cl.bases[0]) else: print >>gv.out, ' 0, /* tp_base */' print >>gv.out, ' 0, /* tp_dict */' print >>gv.out, ' 0, /* tp_descr_get */' print >>gv.out, ' 0, /* tp_descr_set */' print >>gv.out, ' 0, /* tp_dictoffset */' if hasmethod(cl, '__init__') and cl.funcs['__init__'] in funcs: print >>gv.out, ' %s___tpinit__, /* tp_init */' % clname(cl) else: print >>gv.out, ' 0, /* tp_init */' print >>gv.out, ' 0, /* tp_alloc */' print >>gv.out, ' %sNew, /* tp_new */' % clname(cl) print >>gv.out, '};\n' do_reduce_setstate(gv, cl, vars) for n in cl.module.mod_path: print >>gv.out, '} // namespace __%s__' % n print >>gv.out