Exemplo n.º 1
0
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}'
Exemplo n.º 2
0
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, '}'
Exemplo n.º 3
0
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