You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2016/01/15 02:54:49 UTC

[1/8] lucy-clownfish git commit: Refactor compiler setup.py for static archive.

Repository: lucy-clownfish
Updated Branches:
  refs/heads/master 105f76c1e -> 9dc3a0e60


Refactor compiler setup.py for static archive.

Use the Charmonizer-based build setup which creates a static archive,
then link that archive into the python bindings.  By using the
Charmonizer-generated Makefile, we can avoid having to do a lot of
custom compilation and cleanup in setup.py.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/4ff87561
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/4ff87561
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/4ff87561

Branch: refs/heads/master
Commit: 4ff87561435f283dda5002d4c5873e63b1de0361
Parents: 22246a3
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Sun Dec 14 10:41:39 2014 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Jan 6 17:41:07 2016 -0800

----------------------------------------------------------------------
 compiler/python/setup.py | 83 +++++++++++--------------------------------
 1 file changed, 20 insertions(+), 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/4ff87561/compiler/python/setup.py
----------------------------------------------------------------------
diff --git a/compiler/python/setup.py b/compiler/python/setup.py
index b5d5c10..072c337 100644
--- a/compiler/python/setup.py
+++ b/compiler/python/setup.py
@@ -37,8 +37,9 @@ compiler_type = distutils.ccompiler.get_default_compiler()
 # out of distutils, but the member variable has been in the same place for a
 # long time, so violating encapsulation may be ok.
 compiler_name = " ".join(compiler.compiler)
+make_command = "make" # TODO portability
 
-BASE_DIR = os.path.abspath(os.path.join(os.pardir, os.pardir, os.pardir))
+BASE_DIR        = os.path.abspath(os.path.join(os.pardir, os.pardir))
 PARENT_DIR      = os.path.abspath(os.pardir)
 CFC_SOURCE_DIR  = os.path.join(PARENT_DIR, 'src')
 CFC_INCLUDE_DIR = os.path.join(PARENT_DIR, 'include')
@@ -47,57 +48,21 @@ CHARMONIZER_C        = os.path.join(COMMON_SOURCE_DIR, 'charmonizer.c')
 CHARMONIZER_EXE_NAME = compiler.executable_filename('charmonizer')
 CHARMONIZER_EXE_PATH = os.path.join(os.curdir, CHARMONIZER_EXE_NAME)
 CHARMONY_H_PATH      = 'charmony.h'
-LEMON_DIR = os.path.join(BASE_DIR, 'lemon')
-LEMON_EXE_NAME = compiler.executable_filename('lemon')
-LEMON_EXE_PATH = os.path.join(LEMON_DIR, LEMON_EXE_NAME)
+LIBCFC_NAME          = 'libcfc.a' # TODO portability
+LIBCFC_PATH          = os.path.abspath(os.path.join(os.curdir, LIBCFC_NAME))
 
-# Accumulate lists of source files and target files.
-c_filepaths = []
-y_filepaths = []
+c_filepaths = [os.path.join('clownfish', '_cfc.c')]
 paths_to_clean = [
     CHARMONIZER_EXE_PATH,
     CHARMONY_H_PATH,
     '_charm*',
 ]
-c_filepaths.append(os.path.join('clownfish', '_cfc.c'))
-for (dirpath, dirnames, files) in os.walk(CFC_SOURCE_DIR):
-    for filename in files:
-        if filename.endswith('.y'):
-            path = os.path.join(dirpath, filename)
-            y_filepaths.append(path)
-            path = re.sub(r'y$', 'h', path)
-            paths_to_clean.append(path)
-            path = re.sub(r'h$', 'c', path)
-            paths_to_clean.append(path)
-            c_filepaths.append(path)
-            path = compiler.object_filenames([path])[0]
-            paths_to_clean.append(path)
-        if filename.endswith('.c'):
-            path = os.path.join(dirpath, filename)
-            c_filepaths.append(path)
-            path = compiler.object_filenames([path])[0]
-            paths_to_clean.append(path)
 
 def _quotify(text):
     text = text.replace('\\', '\\\\')
     text = text.replace('"', '\\"')
     return '"' + text + '"'
 
-def _run_make(command=[], directory=None):
-    current_directory = os.getcwd();
-    if (directory != None):
-        os.chdir(directory)
-    if (compiler_type == 'msvc'):
-        command.insert(0, 'Makefile.MSVC')
-        command.insert(0, '-f')
-    elif (platform.system() == 'Windows'):
-        command.insert(0, 'Makefile.MinGW')
-        command.insert(0, '-f')
-    command.insert(0, "make")
-    subprocess.check_call(command)
-    if (directory != None):
-        os.chdir(current_directory)
-
 class charmony(_Command):
     description = "Build and run charmonizer"
     user_options = []
@@ -123,6 +88,8 @@ class charmony(_Command):
                 CHARMONIZER_EXE_PATH,
                 '--cc=' + _quotify(compiler_name),
                 '--enable-c',
+                '--host=python',
+                '--enable-makefile',
                 '--',
                 cflags
             ]
@@ -131,35 +98,26 @@ class charmony(_Command):
             print(" ".join(command))
             subprocess.check_call(command)
 
-class lemon(_Command):
-    description = "Compile the Lemon parser generator"
+class libcfc(_Command):
+    description = "Build CFC as a static archive."
     user_options = []
     def initialize_options(self):
         pass
     def finalize_options(self):
         pass
     def run(self):
-        if not os.path.exists(LEMON_EXE_PATH):
-            _run_make(['CC=' + _quotify(compiler_name)], directory=LEMON_DIR)
-
-class parsers(_Command):
-    description = "Run .y files through lemon"
-    user_options = []
-    def initialize_options(self):
-        pass
-    def finalize_options(self):
-        pass
-    def run(self):
-        for y_path in y_filepaths:
-            target = re.sub(r'y$', 'c', y_path)
-            if newer_group([y_path], target):
-                command = [LEMON_EXE_PATH, '-c', y_path]
-                subprocess.check_call(command)
+        self.run_command('charmony')
+        subprocess.check_call([make_command, '-j', 'static'])
+        # Touch Python binding file if the library has changed.
+        cfc_c = os.path.join('clownfish', '_cfc.c')
+        if newer_group(['libcfc.a'], cfc_c):
+            os.utime(cfc_c, None)
 
 class my_clean(_clean):
     def run(self):
         _clean.run(self)
-        _run_make(command=['clean'], directory=LEMON_DIR)
+        if os.path.isfile("Makefile"):
+            subprocess.check_call([make_command, 'distclean'])
         for elem in paths_to_clean:
             for path in glob.glob(elem):
                 print("removing " + path)
@@ -171,8 +129,7 @@ class my_clean(_clean):
 class my_build(_build):
     def run(self):
         self.run_command('charmony')
-        self.run_command('lemon')
-        self.run_command('parsers')
+        self.run_command('libcfc')
         _build.run(self)
 
 cfc_extension = Extension('clownfish._cfc',
@@ -182,6 +139,7 @@ cfc_extension = Extension('clownfish._cfc',
                               CFC_SOURCE_DIR,
                               os.curdir,
                           ],
+                          extra_link_args = [LIBCFC_PATH],
                           sources = c_filepaths)
 
 setup(name = 'clownfish-cfc',
@@ -195,9 +153,8 @@ setup(name = 'clownfish-cfc',
       cmdclass = {
           'build': my_build,
           'clean': my_clean,
-          'lemon': lemon,
           'charmony': charmony,
-          'parsers': parsers,
+          'libcfc': libcfc,
       },
       ext_modules = [cfc_extension])
 


[6/8] lucy-clownfish git commit: Start Python bindings for CFCParcel.

Posted by ma...@apache.org.
Start Python bindings for CFCParcel.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/8723a18b
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/8723a18b
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/8723a18b

Branch: refs/heads/master
Commit: 8723a18bd3fa49929c0a3e8d63e058c382c2eb36
Parents: 5f53f5a
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Wed Dec 17 18:39:01 2014 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Jan 6 20:45:31 2016 -0800

----------------------------------------------------------------------
 compiler/python/clownfish/_cfc.c | 93 +++++++++++++++++++++++++++++++++--
 1 file changed, 90 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8723a18b/compiler/python/clownfish/_cfc.c
----------------------------------------------------------------------
diff --git a/compiler/python/clownfish/_cfc.c b/compiler/python/clownfish/_cfc.c
index 209f174..407c82e 100644
--- a/compiler/python/clownfish/_cfc.c
+++ b/compiler/python/clownfish/_cfc.c
@@ -63,12 +63,33 @@ S_CFCBase_dealloc(CFCPyWrapper *wrapper) {
     Py_TYPE(wrapper)->tp_free(wrapper);
 }
 
+void*
+S_to_cfc_something(PyObject *wrapper, const char *class_name) {
+    if (wrapper == NULL || wrapper == Py_None) {
+        return NULL;
+    }
+    CFCBase *obj = (CFCBase*)((CFCPyWrapper*)wrapper)->cfc_obj;
+    if (strcmp(CFCBase_get_cfc_class(obj), class_name) != 0) {
+        CFCUtil_die("Object is not a %s, it's a %s", class_name,
+                    CFCBase_get_cfc_class(obj));
+    }
+    return obj;
+}
+
 static CFCHierarchy*
 S_to_Hierarchy(PyObject *wrapper) {
-    return (CFCHierarchy*)((CFCPyWrapper*)wrapper)->cfc_obj;
+    return (CFCHierarchy*)S_to_cfc_something(wrapper,
+        "Clownfish::CFC::Model::Hierarchy");
+}
+
+static CFCParcel*
+S_to_Parcel(PyObject *wrapper) {
+    return (CFCParcel*)S_to_cfc_something(wrapper,
+        "Clownfish::CFC::Model::Parcel");
 }
 
 static PyTypeObject *Hierarchy_pytype;
+static PyTypeObject *Parcel_pytype;
 
 /***************************** CFCHierarchy *****************************/
 
@@ -191,20 +212,86 @@ static PyTypeObject Hierarchy_pytype_struct = {
     (newfunc)S_CFCHierarchy_new         // tp_new
 };
 
+/***************************** CFCParcel *****************************/
+
+PyObject*
+S_CFCParcel_fetch(PyObject *ignored, PyObject *name) {
+    CFCParcel *parcel = CFCParcel_fetch(PyUnicode_AsUTF8(name));
+    return S_wrap_cfcbase(Parcel_pytype, parcel);
+}
+
+static PyMethodDef parcel_methods[] = {
+    {"fetch", (PyCFunction)S_CFCParcel_fetch, METH_STATIC, NULL},
+    {NULL}
+};
+
+static PyTypeObject Parcel_pytype_struct = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "clownfish.cfc.model.Parcel",       // tp_name
+    sizeof(CFCPyWrapper),               // tp_basicsize
+    0,                                  // tp_itemsize
+    (destructor)S_CFCBase_dealloc,      // tp_dealloc
+    0,                                  // tp_print
+    0,                                  // tp_getattr
+    0,                                  // tp_setattr
+    0,                                  // tp_reserved
+    0,                                  // tp_repr
+    0,                                  // tp_as_number
+    0,                                  // tp_as_sequence
+    0,                                  // tp_as_mapping
+    0,                                  // tp_hash
+    0,                                  // tp_call
+    0,                                  // tp_str
+    0,                                  // tp_getattro
+    0,                                  // tp_setattro
+    0,                                  // tp_as_buffer
+    Py_TPFLAGS_DEFAULT,                 // tp_flags
+    "CFCParcel",                        // tp_doc
+    0,                                  // tp_traverse
+    0,                                  // tp_clear
+    0,                                  // tp_richcompare
+    0,                                  // tp_weaklistoffset
+    0,                                  // tp_iter
+    0,                                  // tp_iternext
+    parcel_methods,                     // 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_allow
+    0                                   // tp_new
+};
+
+/******************************* common ******************************/
+
 PyMODINIT_FUNC
 PyInit__cfc(void) {
-    // Initialize type object pointers.
+    // Initialize Python type objects.
     Hierarchy_pytype = &Hierarchy_pytype_struct;
-
+    Parcel_pytype    = &Parcel_pytype_struct;
     if (PyType_Ready(Hierarchy_pytype) < 0) {
         return NULL;
     }
+    if (PyType_Ready(Parcel_pytype) < 0) {
+        return NULL;
+    }
+
+    // Initialize modules.
     cfc_module = PyModule_Create(&cfc_module_def);
     cfc_model_module = PyModule_Create(&cfc_model_module_def);
     PyModule_AddObject(cfc_module, "model", (PyObject*)cfc_model_module);
+
+    // Add type objects to modules.
     Py_INCREF(Hierarchy_pytype);
     PyModule_AddObject(cfc_model_module, "Hierarchy",
                        (PyObject*)Hierarchy_pytype);
+    Py_INCREF(Parcel_pytype);
+    PyModule_AddObject(cfc_model_module, "Parcel",
+                       (PyObject*)Parcel_pytype);
 
     return cfc_module;
 }


[3/8] lucy-clownfish git commit: Bind more CFCHierarchy methods to Python.

Posted by ma...@apache.org.
Bind more CFCHierarchy methods to Python.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/39fb007f
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/39fb007f
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/39fb007f

Branch: refs/heads/master
Commit: 39fb007f9c2c9ee42b75386728a0f9819c3084b7
Parents: cd9eec3
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Mon Dec 15 20:57:03 2014 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Jan 6 18:43:27 2016 -0800

----------------------------------------------------------------------
 compiler/python/clownfish/_cfc.c | 34 +++++++++++++++++++++++++++++-----
 1 file changed, 29 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/39fb007f/compiler/python/clownfish/_cfc.c
----------------------------------------------------------------------
diff --git a/compiler/python/clownfish/_cfc.c b/compiler/python/clownfish/_cfc.c
index 253f23c..f1486ef 100644
--- a/compiler/python/clownfish/_cfc.c
+++ b/compiler/python/clownfish/_cfc.c
@@ -22,8 +22,10 @@ typedef struct {
     void *cfc_obj;
 } CFCPyWrapper;
 
+/***************************** CFCHierarchy *****************************/
+
 static CFCHierarchy*
-S_extract_hierarchy(PyObject *wrapper) {
+S_to_Hierarchy(PyObject *wrapper) {
     return (CFCHierarchy*)((CFCPyWrapper*)wrapper)->cfc_obj;
 }
 
@@ -55,13 +57,33 @@ S_CFCHierarchy_dealloc(CFCPyWrapper *wrapper) {
 }
 
 static PyObject*
+S_CFCHierarchy_build(PyObject *wrapper, PyObject *unused) {
+    CHY_UNUSED_VAR(unused);
+    CFCHierarchy_build(S_to_Hierarchy(wrapper));
+    Py_RETURN_NONE;
+}
+
+static PyObject*
 S_CFCHierarchy_add_include_dir(PyObject *wrapper, PyObject *dir) {
-    CFCHierarchy *wrapped  = S_extract_hierarchy(wrapper);
-    CFCHierarchy_add_include_dir(S_extract_hierarchy(wrapper),
+    CFCHierarchy_add_include_dir(S_to_Hierarchy(wrapper),
                                  PyUnicode_AsUTF8(dir));
     Py_RETURN_NONE;
 }
 
+static PyObject*
+S_CFCHierarchy_add_source_dir(PyObject *wrapper, PyObject *dir) {
+    CFCHierarchy_add_source_dir(S_to_Hierarchy(wrapper),
+                                PyUnicode_AsUTF8(dir));
+    Py_RETURN_NONE;
+}
+
+static PyObject*
+S_CFCHierarchy_write_log(PyObject *wrapper, PyObject *unused) {
+    CHY_UNUSED_VAR(unused);
+    CFCHierarchy_write_log(S_to_Hierarchy(wrapper));
+    Py_RETURN_NONE;
+}
+
 static PyModuleDef cfc_module_def = {
     PyModuleDef_HEAD_INIT,
     "clownfish.cfc",
@@ -79,8 +101,10 @@ static PyModuleDef cfc_model_module_def = {
 };
 
 static PyMethodDef hierarchy_methods[] = {
-    {"add_include_dir", (PyCFunction)S_CFCHierarchy_add_include_dir, METH_O,
-     NULL},
+    {"add_include_dir", (PyCFunction)S_CFCHierarchy_add_include_dir, METH_O,      NULL},
+    {"add_source_dir",  (PyCFunction)S_CFCHierarchy_add_source_dir,  METH_O,      NULL},
+    {"build",           (PyCFunction)S_CFCHierarchy_build,           METH_NOARGS, NULL},
+    {"write_log",       (PyCFunction)S_CFCHierarchy_write_log,       METH_NOARGS, NULL},
     {NULL}
 };
 


[7/8] lucy-clownfish git commit: Start Python bindings for CFCBindCore.

Posted by ma...@apache.org.
Start Python bindings for CFCBindCore.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/29a2584a
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/29a2584a
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/29a2584a

Branch: refs/heads/master
Commit: 29a2584a083db29baa3b955be7fecadf5f20ba9c
Parents: 8723a18
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Wed Dec 17 19:17:08 2014 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Jan 6 20:46:54 2016 -0800

----------------------------------------------------------------------
 compiler/python/clownfish/_cfc.c | 103 +++++++++++++++++++++++++++++++++-
 1 file changed, 102 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/29a2584a/compiler/python/clownfish/_cfc.c
----------------------------------------------------------------------
diff --git a/compiler/python/clownfish/_cfc.c b/compiler/python/clownfish/_cfc.c
index 407c82e..706943f 100644
--- a/compiler/python/clownfish/_cfc.c
+++ b/compiler/python/clownfish/_cfc.c
@@ -38,8 +38,17 @@ static PyModuleDef cfc_model_module_def = {
     NULL, NULL, NULL, NULL, NULL
 };
 
+static PyModuleDef cfc_binding_module_def = {
+    PyModuleDef_HEAD_INIT,
+    "clownfish.cfc.binding",
+    "CFC components which generate bindings",
+    -1,
+    NULL, NULL, NULL, NULL, NULL
+};
+
 static PyObject *cfc_module;
 static PyObject *cfc_model_module;
+static PyObject *cfc_binding_module;
 
 static PyObject*
 S_wrap_cfcbase(PyTypeObject *type, void *cfc_obj) {
@@ -88,8 +97,15 @@ S_to_Parcel(PyObject *wrapper) {
         "Clownfish::CFC::Model::Parcel");
 }
 
+static CFCBindCore*
+S_to_BindCore(PyObject *wrapper) {
+    return (CFCBindCore*)S_to_cfc_something(wrapper,
+        "Clownfish::CFC::Binding::Core");
+}
+
 static PyTypeObject *Hierarchy_pytype;
 static PyTypeObject *Parcel_pytype;
+static PyTypeObject *BindCore_pytype;
 
 /***************************** CFCHierarchy *****************************/
 
@@ -266,6 +282,80 @@ static PyTypeObject Parcel_pytype_struct = {
     0                                   // tp_new
 };
 
+/***************************** CFCBindCore *****************************/
+
+static PyObject*
+S_CFCBindCore_new(PyTypeObject *type, PyObject *args,
+                   PyObject *keyword_args) {
+    PyObject *hierarchy_wrapped;
+    char *header = "";
+    char *footer = "";
+    char *keywords[] = {"hierarchy", "header", "footer", NULL};
+    int result = PyArg_ParseTupleAndKeywords(args, keyword_args, "O!|ss",
+                                             keywords, Hierarchy_pytype,
+                                             &hierarchy_wrapped, &header,
+                                             &footer);
+    if (!result) { return NULL; }
+    CFCHierarchy *hierarchy = S_to_Hierarchy(hierarchy_wrapped);
+    CFCBindCore *obj = CFCBindCore_new(hierarchy, header, footer);
+    return S_wrap_cfcbase(BindCore_pytype, obj);
+}
+
+static PyObject*
+S_CFCBindCore_write_all_modified(PyObject *wrapper, PyObject *args) {
+    int modified = 0;
+    int result = PyArg_ParseTuple(args, "|p", &modified);
+    if (!result) { return NULL; }
+    CFCBindCore_write_all_modified(S_to_BindCore(wrapper), modified);
+    Py_RETURN_NONE;
+}
+
+static PyMethodDef bindcore_methods[] = {
+    {"write_all_modified", (PyCFunction)S_CFCBindCore_write_all_modified, METH_VARARGS, NULL},
+    {NULL}
+};
+
+static PyTypeObject BindCore_pytype_struct = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "clownfish.cfc.binding.BindCore",   // tp_name
+    sizeof(CFCPyWrapper),               // tp_basicsize
+    0,                                  // tp_itemsize
+    (destructor)S_CFCBase_dealloc,      // tp_dealloc
+    0,                                  // tp_print
+    0,                                  // tp_getattr
+    0,                                  // tp_setattr
+    0,                                  // tp_reserved
+    0,                                  // tp_repr
+    0,                                  // tp_as_number
+    0,                                  // tp_as_sequence
+    0,                                  // tp_as_mapping
+    0,                                  // tp_hash
+    0,                                  // tp_call
+    0,                                  // tp_str
+    0,                                  // tp_getattro
+    0,                                  // tp_setattro
+    0,                                  // tp_as_buffer
+    Py_TPFLAGS_DEFAULT,                 // tp_flags
+    "CFCBindCore",                      // tp_doc
+    0,                                  // tp_traverse
+    0,                                  // tp_clear
+    0,                                  // tp_richcompare
+    0,                                  // tp_weaklistoffset
+    0,                                  // tp_iter
+    0,                                  // tp_iternext
+    bindcore_methods,                   // 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_allow
+    (newfunc)S_CFCBindCore_new          // tp_new
+};
+
 /******************************* common ******************************/
 
 PyMODINIT_FUNC
@@ -273,19 +363,25 @@ PyInit__cfc(void) {
     // Initialize Python type objects.
     Hierarchy_pytype = &Hierarchy_pytype_struct;
     Parcel_pytype    = &Parcel_pytype_struct;
+    BindCore_pytype  = &BindCore_pytype_struct;
     if (PyType_Ready(Hierarchy_pytype) < 0) {
         return NULL;
     }
     if (PyType_Ready(Parcel_pytype) < 0) {
         return NULL;
     }
+    if (PyType_Ready(BindCore_pytype) < 0) {
+        return NULL;
+    }
 
     // Initialize modules.
     cfc_module = PyModule_Create(&cfc_module_def);
     cfc_model_module = PyModule_Create(&cfc_model_module_def);
+    cfc_binding_module = PyModule_Create(&cfc_binding_module_def);
     PyModule_AddObject(cfc_module, "model", (PyObject*)cfc_model_module);
+    PyModule_AddObject(cfc_module, "binding", (PyObject*)cfc_binding_module);
 
-    // Add type objects to modules.
+    // Add type objects to "model" module.
     Py_INCREF(Hierarchy_pytype);
     PyModule_AddObject(cfc_model_module, "Hierarchy",
                        (PyObject*)Hierarchy_pytype);
@@ -293,6 +389,11 @@ PyInit__cfc(void) {
     PyModule_AddObject(cfc_model_module, "Parcel",
                        (PyObject*)Parcel_pytype);
 
+    // Add type objects to "binding" module.
+    Py_INCREF(BindCore_pytype);
+    PyModule_AddObject(cfc_binding_module, "BindCore",
+                       (PyObject*)BindCore_pytype);
+
     return cfc_module;
 }
 


[5/8] lucy-clownfish git commit: Add Python site-packages dirs to CF include.

Posted by ma...@apache.org.
Add Python site-packages dirs to CF include.

In CFCHierarchy's constructor, always add include dirs for each
site-packages dir.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/5f53f5a4
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/5f53f5a4
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/5f53f5a4

Branch: refs/heads/master
Commit: 5f53f5a4c0856c272abc5a202d392a7dd647d69c
Parents: a677d8c
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Wed Dec 17 15:49:23 2014 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Jan 6 20:22:53 2016 -0800

----------------------------------------------------------------------
 compiler/python/clownfish/_cfc.c          | 25 +++++++++++++++++++++++++
 compiler/python/clownfish/cfc/__init__.py | 12 ++++++++++++
 2 files changed, 37 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5f53f5a4/compiler/python/clownfish/_cfc.c
----------------------------------------------------------------------
diff --git a/compiler/python/clownfish/_cfc.c b/compiler/python/clownfish/_cfc.c
index 204ee3e..209f174 100644
--- a/compiler/python/clownfish/_cfc.c
+++ b/compiler/python/clownfish/_cfc.c
@@ -84,7 +84,32 @@ S_CFCHierarchy_new(PyTypeObject *type, PyObject *args,
         PyErr_SetString(PyExc_TypeError, "Missing required arg 'dest'");
         return NULL;
     }
+    PyObject *inc_func = PyObject_GetAttrString(cfc_module, "_get_inc_dirs");
+    PyObject *dirs = NULL;
+    if (PyCallable_Check(inc_func)) {
+        dirs = PyObject_CallObject(inc_func, NULL);
+    }
+    if (dirs == NULL || !PyList_Check(dirs)) {
+        Py_XDECREF(inc_func);
+        Py_XDECREF(dirs);
+        PyErr_SetString(PyExc_RuntimeError, "_get_inc_dirs failed");
+        return NULL;
+    }
     CFCHierarchy *hierarchy = CFCHierarchy_new(dest);
+    for (Py_ssize_t i = 0, max = PyList_Size(dirs); i < max; i++) {
+        PyObject *dir = PyList_GetItem(dirs, i);
+        if (PyUnicode_Check(dir)) {
+            char *dir_utf8 = PyUnicode_AsUTF8(dir);
+            CFCHierarchy_add_include_dir(hierarchy, dir_utf8);
+        }
+        else {
+            PyErr_SetString(PyExc_RuntimeError, "not a string");
+            return NULL;
+        }
+    }
+
+    Py_XDECREF(inc_func);
+    Py_XDECREF(dirs);
 
     return S_wrap_cfcbase(Hierarchy_pytype, hierarchy);
 }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5f53f5a4/compiler/python/clownfish/cfc/__init__.py
----------------------------------------------------------------------
diff --git a/compiler/python/clownfish/cfc/__init__.py b/compiler/python/clownfish/cfc/__init__.py
index 8ab5aaf..f7f3e0b 100644
--- a/compiler/python/clownfish/cfc/__init__.py
+++ b/compiler/python/clownfish/cfc/__init__.py
@@ -13,5 +13,17 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import clownfish._cfc
 from clownfish._cfc import *
+import site
+import os.path
+
+def _get_inc_dirs():
+    dirs = []
+    for path in site.getsitepackages():
+        path = os.path.join(path, "clownfish/_include")
+        dirs.append(path)
+    return dirs
+
+clownfish._cfc._get_inc_dirs = _get_inc_dirs
 


[8/8] lucy-clownfish git commit: Merge branch 'CLOWNFISH-66-py-cfc-core'

Posted by ma...@apache.org.
Merge branch 'CLOWNFISH-66-py-cfc-core'

Improve basic CFC Python bindings.

*   Migrate to Charmonizer-generated Makefile build.
*   Add a "test" target to setup.py.
*   Add bindings for a few more parts of the CFC core.

This fixes #53.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/9dc3a0e6
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/9dc3a0e6
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/9dc3a0e6

Branch: refs/heads/master
Commit: 9dc3a0e60d19c44de0e6ec32ed74265aa31fe89f
Parents: 105f76c 29a2584
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Thu Jan 14 17:53:00 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Thu Jan 14 17:53:00 2016 -0800

----------------------------------------------------------------------
 compiler/python/clownfish/_cfc.c          | 333 ++++++++++++++++++++++---
 compiler/python/clownfish/cfc/__init__.py |  12 +
 compiler/python/setup.py                  | 113 ++++-----
 compiler/python/test/test_cfc.py          |  12 +
 4 files changed, 369 insertions(+), 101 deletions(-)
----------------------------------------------------------------------



[2/8] lucy-clownfish git commit: Add "test" target for setup.py.

Posted by ma...@apache.org.
Add "test" target for setup.py.

Run tests with `python3 setup.py test`.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/cd9eec3c
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/cd9eec3c
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/cd9eec3c

Branch: refs/heads/master
Commit: cd9eec3c29c15c93532547fe92ffe1f48b1864fc
Parents: 4ff8756
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Tue Dec 16 16:37:54 2014 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Jan 6 18:32:52 2016 -0800

----------------------------------------------------------------------
 compiler/python/setup.py         | 30 ++++++++++++++++++++++++++++++
 compiler/python/test/test_cfc.py | 12 ++++++++++++
 2 files changed, 42 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/cd9eec3c/compiler/python/setup.py
----------------------------------------------------------------------
diff --git a/compiler/python/setup.py b/compiler/python/setup.py
index 072c337..ccfba55 100644
--- a/compiler/python/setup.py
+++ b/compiler/python/setup.py
@@ -26,6 +26,8 @@ import re
 import shutil
 import subprocess
 import sysconfig
+import sys
+import unittest
 
 # Get a compiler object and and strings representing the compiler type and
 # CFLAGS.
@@ -132,6 +134,33 @@ class my_build(_build):
         self.run_command('libcfc')
         _build.run(self)
 
+class test(_Command):
+    description = "Run unit tests."
+    user_options = []
+    def initialize_options(self):
+        pass
+    def finalize_options(self):
+        pass
+    def ext_build_dir(self):
+        """Returns the build directory for compiled extensions"""
+        pattern = "lib.{platform}-{version[0]}.{version[1]}"
+        dirname = pattern.format(platform=sysconfig.get_platform(),
+                                 version=sys.version_info)
+        return os.path.join('build', dirname)
+
+    def run(self):
+        self.run_command('build')
+        orig_sys_path = sys.path[:]
+        sys.path.append(self.ext_build_dir())
+
+        loader = unittest.TestLoader()
+        tests = loader.discover("test")
+        test_runner = unittest.runner.TextTestRunner()
+        test_runner.run(tests)
+
+        # restore sys.path
+        sys.path = orig_sys_path
+
 cfc_extension = Extension('clownfish._cfc',
                           define_macros = [('CFCPYTHON', None)],
                           include_dirs = [
@@ -155,6 +184,7 @@ setup(name = 'clownfish-cfc',
           'clean': my_clean,
           'charmony': charmony,
           'libcfc': libcfc,
+          'test': test,
       },
       ext_modules = [cfc_extension])
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/cd9eec3c/compiler/python/test/test_cfc.py
----------------------------------------------------------------------
diff --git a/compiler/python/test/test_cfc.py b/compiler/python/test/test_cfc.py
new file mode 100644
index 0000000..c4091d8
--- /dev/null
+++ b/compiler/python/test/test_cfc.py
@@ -0,0 +1,12 @@
+import unittest
+import clownfish.cfc
+
+class MyTest(unittest.TestCase):
+
+    def testTrue(self):
+        self.assertTrue(True, "True should be true")
+
+
+if __name__ == '__main__':
+    unittest.main()
+


[4/8] lucy-clownfish git commit: Refactor Python C module code for CFC.

Posted by ma...@apache.org.
Refactor Python C module code for CFC.

Move some stuff around to make it easier to add new functions which
access existing data structures.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/a677d8c6
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/a677d8c6
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/a677d8c6

Branch: refs/heads/master
Commit: a677d8c6616139f0d64ec28ee62928cd2b15326d
Parents: 39fb007
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Wed Dec 17 15:49:23 2014 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Jan 6 20:22:23 2016 -0800

----------------------------------------------------------------------
 compiler/python/clownfish/_cfc.c | 94 +++++++++++++++++++++--------------
 1 file changed, 57 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a677d8c6/compiler/python/clownfish/_cfc.c
----------------------------------------------------------------------
diff --git a/compiler/python/clownfish/_cfc.c b/compiler/python/clownfish/_cfc.c
index f1486ef..204ee3e 100644
--- a/compiler/python/clownfish/_cfc.c
+++ b/compiler/python/clownfish/_cfc.c
@@ -22,14 +22,57 @@ typedef struct {
     void *cfc_obj;
 } CFCPyWrapper;
 
-/***************************** CFCHierarchy *****************************/
+static PyModuleDef cfc_module_def = {
+    PyModuleDef_HEAD_INIT,
+    "clownfish._cfc",
+    "CFC: Clownfish compiler",
+    -1,
+    NULL, NULL, NULL, NULL, NULL
+};
+
+static PyModuleDef cfc_model_module_def = {
+    PyModuleDef_HEAD_INIT,
+    "clownfish.cfc.model",
+    "CFC classes which model language constructs",
+    -1,
+    NULL, NULL, NULL, NULL, NULL
+};
+
+static PyObject *cfc_module;
+static PyObject *cfc_model_module;
+
+static PyObject*
+S_wrap_cfcbase(PyTypeObject *type, void *cfc_obj) {
+    if (cfc_obj == NULL) {
+        Py_RETURN_NONE;
+    }
+    CFCPyWrapper *wrapper = (CFCPyWrapper*)type->tp_alloc(type, 0);
+    if (wrapper == NULL) {
+        PyErr_SetString(PyExc_RuntimeError, "Failed to allocate object");
+        return NULL;
+    }
+    wrapper->cfc_obj = cfc_obj;
+    return (PyObject*)wrapper;
+}
+
+static void
+S_CFCBase_dealloc(CFCPyWrapper *wrapper) {
+    CFCBase *temp = (CFCBase*)wrapper->cfc_obj;
+    wrapper->cfc_obj = NULL;
+    CFCBase_decref(temp);
+    Py_TYPE(wrapper)->tp_free(wrapper);
+}
 
 static CFCHierarchy*
 S_to_Hierarchy(PyObject *wrapper) {
     return (CFCHierarchy*)((CFCPyWrapper*)wrapper)->cfc_obj;
 }
 
-static CFCPyWrapper*
+static PyTypeObject *Hierarchy_pytype;
+
+/***************************** CFCHierarchy *****************************/
+
+static PyObject*
 S_CFCHierarchy_new(PyTypeObject *type, PyObject *args,
                    PyObject *keyword_args) {
     char *dest = NULL;
@@ -41,19 +84,9 @@ S_CFCHierarchy_new(PyTypeObject *type, PyObject *args,
         PyErr_SetString(PyExc_TypeError, "Missing required arg 'dest'");
         return NULL;
     }
-    CFCPyWrapper *wrapper = (CFCPyWrapper*)type->tp_alloc(type, 0);
-    if (wrapper) {
-        wrapper->cfc_obj = CFCHierarchy_new(dest);
-    }
-    return wrapper;
-}
+    CFCHierarchy *hierarchy = CFCHierarchy_new(dest);
 
-static void
-S_CFCHierarchy_dealloc(CFCPyWrapper *wrapper) {
-    CFCBase *temp = (CFCBase*)wrapper->cfc_obj;
-    wrapper->cfc_obj = NULL;
-    CFCBase_decref(temp);
-    Py_TYPE(wrapper)->tp_free(wrapper);
+    return S_wrap_cfcbase(Hierarchy_pytype, hierarchy);
 }
 
 static PyObject*
@@ -84,22 +117,6 @@ S_CFCHierarchy_write_log(PyObject *wrapper, PyObject *unused) {
     Py_RETURN_NONE;
 }
 
-static PyModuleDef cfc_module_def = {
-    PyModuleDef_HEAD_INIT,
-    "clownfish.cfc",
-    "CFC: Clownfish compiler",
-    -1,
-    NULL, NULL, NULL, NULL, NULL
-};
-
-static PyModuleDef cfc_model_module_def = {
-    PyModuleDef_HEAD_INIT,
-    "clownfish.cfc.model",
-    "CFC classes which model language constructs",
-    -1,
-    NULL, NULL, NULL, NULL, NULL
-};
-
 static PyMethodDef hierarchy_methods[] = {
     {"add_include_dir", (PyCFunction)S_CFCHierarchy_add_include_dir, METH_O,      NULL},
     {"add_source_dir",  (PyCFunction)S_CFCHierarchy_add_source_dir,  METH_O,      NULL},
@@ -108,12 +125,12 @@ static PyMethodDef hierarchy_methods[] = {
     {NULL}
 };
 
-static PyTypeObject CFCHierarchy_pytype = {
+static PyTypeObject Hierarchy_pytype_struct = {
     PyVarObject_HEAD_INIT(NULL, 0)
     "clownfish.cfc.model.Hierarchy",    // tp_name
     sizeof(CFCPyWrapper),               // tp_basicsize
     0,                                  // tp_itemsize
-    (destructor)S_CFCHierarchy_dealloc, // tp_dealloc
+    (destructor)S_CFCBase_dealloc,      // tp_dealloc
     0,                                  // tp_print
     0,                                  // tp_getattr
     0,                                  // tp_setattr
@@ -151,15 +168,18 @@ static PyTypeObject CFCHierarchy_pytype = {
 
 PyMODINIT_FUNC
 PyInit__cfc(void) {
-    if (PyType_Ready(&CFCHierarchy_pytype) < 0) {
+    // Initialize type object pointers.
+    Hierarchy_pytype = &Hierarchy_pytype_struct;
+
+    if (PyType_Ready(Hierarchy_pytype) < 0) {
         return NULL;
     }
-    PyObject *cfc_module = PyModule_Create(&cfc_module_def);
-    PyObject *cfc_model_module = PyModule_Create(&cfc_model_module_def);
+    cfc_module = PyModule_Create(&cfc_module_def);
+    cfc_model_module = PyModule_Create(&cfc_model_module_def);
     PyModule_AddObject(cfc_module, "model", (PyObject*)cfc_model_module);
-    Py_INCREF(&CFCHierarchy_pytype);
+    Py_INCREF(Hierarchy_pytype);
     PyModule_AddObject(cfc_model_module, "Hierarchy",
-                       (PyObject*)&CFCHierarchy_pytype);
+                       (PyObject*)Hierarchy_pytype);
 
     return cfc_module;
 }