Commits

Anonymous committed 89ef2c8

add method call

Comments (0)

Files changed (10)

+^build$
+^build/
+^build/*
+^build/*/*
+^docs/_build
+^(build|dist|perlpy\.egg-info)/
+\.py[co]$
+^env/
+from paver.easy import *
+import paver.doctools
+from paver.setuputils import setup, find_packages
+from setuptools import Extension
+
+import os
+
+perl_path = sh("perl -MConfig -e 'print $Config{archlib}' ", capture=True)
+perl_path = os.path.join(perl_path, 'CORE')
+
+setup(name='perlpy',
+    version='0.0',
+    description='',
+    url='',
+    license='MIT License',
+    packages=find_packages(exclude=['tests']),
+    py_modules=['perlpy'],
+    ext_modules=[
+        Extension(
+            name='_perl', 
+            sources = ['src/_interp.c', 'src/object.c', 'src/convert.c'],
+            include_dirs = [perl_path],
+            #library_dirs = [perl_path],
+            libraries = ['perl', 'm'],
+
+            )
+    ]
+)
+
 from _perl import *
 
+def _set_perl_getter(clz, perl):
+    def get_perl(self):
+        return perl
+    clz._get_perl = get_perl
+
+def pyclass_name(name):
+    return name.replace("::", "_")
+
 class Perl(Interpreter):
     
 
     def perlclass(self, name):
         self.require(name)
-        return PerlClass(self, name)
+        pyname = pyclass_name(name)
+        templ = """
+class %(type_name)s(object):
+            
+    def __init__(self, ctor='new', *args):
+        self._perl = self._get_perl()
+        self.perl_name = '%(perl_name)s'
+        call_arg = (ctor, self.perl_name) 
+        self.ref = self._perl.call_method(*call_arg)
+    
+
+""" % dict(type_name=pyname, perl_name=name)
+        exec templ in globals()
+        clz = globals()[pyname]
+        _set_perl_getter(clz, self)
+        return clz
+
 
 class PerlClass(object):
 
     ext_modules=[
         Extension(
             name='_perl', 
-            sources = ['src/_interp.c', 'src/object.c', 'src/convert.c'],
+            sources = ['src/_interp.c', 'src/svrv.c', 'src/convert.c'],
             include_dirs = [perl_path],
             #library_dirs = [perl_path],
             libraries = ['perl', 'm'],
 #include "Python.h"
 #include "_interp.h"
 #include "convert.h"
+#include "svrv.h"
 
 
 static PyTypeObject Perl_Type;
 {
     PyObject *res, *name;
     int i, retcnt, arglen, errsv;
-
+    int firstarg = 0;
+    
     arglen = PyTuple_Size(args);
 
     dPCTX;
     SAVETMPS;
     PUSHMARK(SP);
 
-    for (i = 1; i < arglen; i++) {
-	    XPUSHs(sv_2mortal(py2sv(self, PyTuple_GET_ITEM(args, i))));
+    if(method){
+        PyObject *fo = PyTuple_GET_ITEM(args, 0);
+        if(PyString_Check(fo)){
+            //ctor classname
+            name = fo;
+            firstarg = 1;
+        }else if(PySvRV_Check(fo)){
+            //ref methodname args
+            name = PyTuple_GET_ITEM(args, 1);
+            // stack -> ref 
+            XPUSHs(sv_2mortal(py2sv(self, fo)));
+            firstarg = 2;
+        }else{
+            //ERR
+        }
+    }else{
+        firstarg = 1;
     }
+    
+    for (i = firstarg; i < arglen; i++) {
+        XPUSHs(sv_2mortal(py2sv(self, PyTuple_GET_ITEM(args, i))));
+    }
+
     PUTBACK; 
     if(method){
-        char *methodname;
+	    char *methodname = PyString_AS_STRING(name);
+        //printf("call method :%s\n", methodname);
         retcnt = call_method(methodname, gimme|G_EVAL);
     }else{
         name  = PyTuple_GetItem(args, 0);
         SV *sv = py2sv(self, name);
         retcnt = call_sv(sv, gimme|G_EVAL);
     }
+
     errsv = SvTRUE(ERRSV);
-
+    if(errsv){
+        printf("err! %d\n", errsv);
+    }
     SPAGAIN;
     
 	if (gimme == G_ARRAY || retcnt > 1) {
 static PyMethodDef perl_methods[] = {
     {"eval", (PyCFunction)perl_eval, METH_VARARGS, perl_eval_doc},
     {"call", (PyCFunction)perl_call, METH_VARARGS, perl_call_doc},
-    {"callmethod", (PyCFunction)perl_callm, METH_VARARGS, perl_callm_doc},
+    {"call_method", (PyCFunction)perl_callm, METH_VARARGS, perl_callm_doc},
     {"require", (PyCFunction)perl_require, METH_VARARGS, perl_require_doc},
     {NULL, NULL},
 
 #include "Python.h"
 #include "_interp.h"
 #include "convert.h"
-#include "object.h"
+#include "svrv.h"
 
 PyObject *
 sv2py(Perl_Object *self, SV *sv)
 {
     PyObject *o;
-    dP;
+    dPCTX;
 
     if(SvPOK(sv)){
         //string
 
     }else if(SvROK(sv)){
         // ref
+        //printf("is sv ref \n");
 	    o = newSvRV_Object(my_perl, sv);
 
     }else{
         //other
+        //printf("is sv other \n");
 	    o = Py_BuildValue("");
 
     }
     dP;
 
     if (o == Py_None) {
+        //printf("is py None \n");
 	    return newSV(0);
     }else if (PyString_Check(o)) {
+	    //printf("is py string %s \n" ,PyString_AS_STRING(o));
 	    return newSVpvn(PyString_AS_STRING(o), PyString_GET_SIZE(o));
     }else if (PyInt_Check(o)) {
+        //printf("is py int \n");
 	    return newSViv(PyInt_AsLong(o));
     }else if (PyLong_Check(o)) {
+        //printf("is py long \n");
 	    unsigned long tmp = PyLong_AsUnsignedLong(o);
 	    return newSVuv(tmp);
     }else if (PyFloat_Check(o)) {
+        //printf("is py float \n");
 	    return newSVnv(PyFloat_AsDouble(o));
     }else if (PySvRV_Check(o)){
+        //printf("is py svrv \n");
 	    return PySvRV_AsSV(o);
     }else {
+        //printf("is py other \n");
 	    return newSV(0);
     }
+    //printf("wrong value \n");
     return NULL;
 
 }
 SV* py2sv(Perl_Object *self, PyObject *o);
 
 
-#define PySvRV_AsSV(v)     (((SvRV_Object*)(v))->sv)
+#define PySvRV_AsSV(v)     (((PySvRV_Object*)(v))->sv)
 
+#include <EXTERN.h>
+#include <perl.h>
+
+#include "Python.h"
+#include "svrv.h"
+//
+//PyTypeObject PySvRV_Type;
+
+PyObject * 
+newSvRV_Object(PerlInterpreter *my_perl, SV *sv)
+{
+    PERL_SET_CONTEXT(my_perl);
+    PySvRV_Object *self;
+    self = PyObject_NEW(PySvRV_Object, &PySvRV_Type);
+    if (self == NULL)
+	   return NULL;
+    self->sv = SvREFCNT_inc(sv);
+    self->perl = my_perl;
+    return (PyObject *)self;
+}
+
+static void
+svrv_dealloc(PySvRV_Object *self)
+{
+    PerlInterpreter *my_perl;
+    my_perl = self->perl;
+    PERL_SET_CONTEXT(my_perl);
+    SvREFCNT_dec(self->sv);
+	Py_TYPE(self)->tp_free(self);
+}
+
+
+PyTypeObject PySvRV_Type = {
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
+	"ref",					/* tp_name */
+	sizeof(PySvRV_Object),				/* tp_basicsize */
+	0,						/* tp_itemsize */
+	0, /*(destructor)svrv_dealloc,*/			/* tp_dealloc */
+	0,						/* tp_print */
+	0,						/* tp_getattr */
+	0,						/* tp_setattr */
+	0,						/* tp_compare */
+	0,						/* tp_repr */
+	0,						/* tp_as_number */
+	0,						/* tp_as_sequence */
+	0,						/* tp_as_mapping */
+	0,						/* tp_hash */
+	0,              				/* tp_call */
+	0,						/* tp_str */
+	PyObject_GenericGetAttr,			/* tp_getattro */
+	0,						/* tp_setattro */
+	0,						/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,				/* tp_flags */
+	0,					/* tp_doc */
+	0,						/* tp_traverse */
+	0,						/* tp_clear */
+	0,						/* tp_richcompare */
+	0,						/* tp_weaklistoffset */
+	0,						/* tp_iter */
+	0,						/* tp_iternext */
+    /*svrv_method*/0,  				/* tp_methods */
+	0,						/* tp_members */
+	0,				/* tp_getset */
+	0,						/* tp_base */
+	0,						/* tp_dict */
+	0,						/* tp_descr_get */
+	0,						/* tp_descr_set */
+	0,						/* tp_dictoffset */
+	0,						/* tp_init */
+	0,						/* tp_alloc */
+	0,					/* tp_new */
+	0,						/* tp_free */
+};
+
+
+typedef struct {
+    PyObject_HEAD
+    SV *sv;
+    PerlInterpreter *perl;
+} PySvRV_Object;
+
+
+extern PyTypeObject PySvRV_Type;
+
+
+#define PySvRV_Check(v)  ((v)->ob_type == &PySvRV_Type)
+//#define SVRV_RV(v)     (((PySVRV*)(v))->rv)
+
+PyObject *newSvRV_Object(PerlInterpreter *my_perl, SV *sv);
+
+

tests/test_perl.py

     p = Perl()
     assert p != None
 
-
 def test_eval():
     p = Perl()
     ret = p.eval("$a = 1")
 
 def test_evalcall():
     p = Perl()
-    p.eval("""
+    p.eval('''
     sub add{
       my ($a, $b) = @_;
       $a + $b;
     }
-    """)
+    ''')
     ret = p.call("add", 1, 2)
     assert ret == 3
 
+
 def test_call():
     p = Perl("tests/power.pl")
     ret = p.call("expo", 2,2)
 def test_require():
     p = Perl()
     ret = p.require("HTTP::Request")
-    print ret
+    assert ret == 1
+
 
 def test_class():
     p = Perl()
-    pclass = p.perlclass("HTTP::Request")
-    assert pclass != None
+    clz = p.perlclass("LWP::UserAgent")
+    assert clz.__name__ == "LWP_UserAgent"
 
-"""
-def test_class_ins():
-    p = Perl()
-    LWP_UserAgent = p.perlclass("LWP::UseAgent")
-    HTTP_Request = p.perlclass("HTTP::Request")
-    ua = LWP_UserAgent()
-    res = ua.request(HTTP_Request("GET", "http://google.com"))
-    if res.issuccess:
-        print res.content()
-    assert res != None
-"""
 
-"""def test_class():
-    p = Perl()
-    cls = p.perlclass("HTTP::Request")
-"""
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.