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/03/01 04:03:09 UTC

[01/22] lucy-clownfish git commit: Gen stub Py method wrappers.

Repository: lucy-clownfish
Updated Branches:
  refs/heads/master 43de47bc4 -> 89fc04640


Gen stub Py method wrappers.


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

Branch: refs/heads/master
Commit: cb25fd0bd79dfcd8097db6bf8c0319cb44a07531
Parents: a158003
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Mon Feb 1 19:13:00 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:20:39 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPyClass.c  | 17 +++++++++++++++++
 compiler/src/CFCPyMethod.c | 18 ++++++++++++++++++
 compiler/src/CFCPyMethod.h |  3 +++
 3 files changed, 38 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/cb25fd0b/compiler/src/CFCPyClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyClass.c b/compiler/src/CFCPyClass.c
index 9f46b60..11a4905 100644
--- a/compiler/src/CFCPyClass.c
+++ b/compiler/src/CFCPyClass.c
@@ -145,6 +145,23 @@ CFCPyClass_gen_binding_code(CFCPyClass *self) {
     char *bindings  = CFCUtil_strdup(self->pre_code ? self->pre_code : "");
     char *meth_defs = CFCUtil_strdup(self->meth_defs);
 
+    // Instance methods.
+    CFCMethod **methods = CFCClass_fresh_methods(klass);
+    for (size_t j = 0; methods[j] != NULL; j++) {
+        CFCMethod *meth = methods[j];
+
+        if (CFCMethod_excluded_from_host(meth)
+            || !CFCMethod_can_be_bound(meth)
+           ) {
+            continue;
+        }
+
+        // Add the function wrapper.
+        char *wrapper = CFCPyMethod_wrapper(meth, klass);
+        bindings = CFCUtil_cat(bindings, wrapper, "\n", NULL);
+        FREEMEM(wrapper);
+    }
+
     // Complete the PyMethodDef array.
     const char *struct_sym = CFCClass_get_struct_sym(klass);
     char *meth_defs_pattern =

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/cb25fd0b/compiler/src/CFCPyMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index 983df28..0a5cd27 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -215,3 +215,21 @@ S_maybe_unreachable(CFCType *return_type) {
     return return_statement;
 }
 
+char*
+CFCPyMethod_wrapper(CFCMethod *method, CFCClass *invoker) {
+    char *meth_sym   = CFCMethod_full_method_sym(method, invoker);
+
+    char pattern[] =
+        "static PyObject*\n"
+        "S_%s(PyObject *unused1, PyObject *unused2) {\n"
+        "    CFISH_UNUSED_VAR(unused1);\n"
+        "    CFISH_UNUSED_VAR(unused2);\n"
+        "    Py_RETURN_NONE;\n"
+        "}\n"
+        ;
+    char *wrapper = CFCUtil_sprintf(pattern, meth_sym);
+    FREEMEM(meth_sym);
+
+    return wrapper;
+}
+

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/cb25fd0b/compiler/src/CFCPyMethod.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.h b/compiler/src/CFCPyMethod.h
index 15fa1e6..53768e2 100644
--- a/compiler/src/CFCPyMethod.h
+++ b/compiler/src/CFCPyMethod.h
@@ -31,6 +31,9 @@ struct CFCClass;
 char*
 CFCPyMethod_callback_def(struct CFCMethod *method, struct CFCClass *invoker);
 
+char*
+CFCPyMethod_wrapper(struct CFCMethod *method, struct CFCClass *invoker);
+
 #ifdef __cplusplus
 }
 #endif


[02/22] lucy-clownfish git commit: Build up the ParseTuple format string.

Posted by ma...@apache.org.
Build up the ParseTuple format string.


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

Branch: refs/heads/master
Commit: 4cdfb56b6ed149cfef354720e7514d1d23bd8769
Parents: ba87d53
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Tue Feb 2 13:45:03 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:24:52 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPyMethod.c | 6 ++++++
 1 file changed, 6 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/4cdfb56b/compiler/src/CFCPyMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index c0363a5..8d6adfb 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -201,6 +201,10 @@ S_gen_arg_parsing(CFCParamList *param_list, int first_tick, char **error) {
         CFCVariable *var  = vars[i];
         const char  *val  = vals[i];
 
+        const char *var_name = CFCVariable_get_name(var);
+        keywords = CFCUtil_cat(keywords, "\"", var_name, "\", ", NULL);
+
+        // Build up ParseTuple format string.
         if (val == NULL) {
             if (optional_started) { // problem!
                 *error = "Required after optional param";
@@ -210,8 +214,10 @@ S_gen_arg_parsing(CFCParamList *param_list, int first_tick, char **error) {
         else {
             if (!optional_started) {
                 optional_started = 1;
+                format_str = CFCUtil_cat(format_str, "|", NULL);
             }
         }
+        format_str = CFCUtil_cat(format_str, "O&", NULL);
 
         char *declaration = S_gen_declaration(var, val);
         declarations = CFCUtil_cat(declarations, declaration, NULL);


[13/22] lucy-clownfish git commit: Add helper for generating arg lists.

Posted by ma...@apache.org.
Add helper for generating arg lists.


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

Branch: refs/heads/master
Commit: 71c836a2a2329c3a999ce102a6bd38f1b0f08169
Parents: d88c0bf
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Tue Feb 2 16:08:54 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:36:07 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPyMethod.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/71c836a2/compiler/src/CFCPyMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index 450c26e..4220aea 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -473,6 +473,26 @@ S_gen_decrefs(CFCParamList *param_list, int first_tick) {
     return decrefs;
 }
 
+static char*
+S_gen_arg_list(CFCParamList *param_list, const char *first_arg) {
+    CFCVariable **vars = CFCParamList_get_variables(param_list);
+    int num_vars = CFCParamList_num_vars(param_list);
+    char *arg_list = CFCUtil_strdup("");
+    for (int i = 0; i < num_vars; i++) {
+        if (i > 0) {
+            arg_list = CFCUtil_cat(arg_list, ", ", NULL);
+        }
+        if (i == 0 && first_arg != NULL) {
+            arg_list = CFCUtil_cat(arg_list, first_arg, NULL);
+        }
+        else {
+            arg_list = CFCUtil_cat(arg_list, CFCVariable_get_name(vars[i]),
+                                   "_ARG", NULL);
+        }
+    }
+    return arg_list;
+}
+
 char*
 CFCPyMethod_wrapper(CFCMethod *method, CFCClass *invoker) {
     CFCParamList *param_list  = CFCMethod_get_param_list(method);


[08/22] lucy-clownfish git commit: Detect required arg after optional.

Posted by ma...@apache.org.
Detect required arg after optional.

For now, Clownfish allows required arguments to appear after optional
arguments in a parameter list.  Python does not, so we need to detect
that error case.

Eventually, we'll either fix Clownfish to take on Python's restriction,
or else force the user to create manual glue for problematic methods.


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

Branch: refs/heads/master
Commit: 74878d3ce0be405b575552dfb25caa6a00e46ba9
Parents: 15602e6
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Tue Feb 2 11:09:57 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:24:52 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPyMethod.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/74878d3c/compiler/src/CFCPyMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index c89d12c..fcbeee1 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -71,7 +71,7 @@ S_build_py_args(CFCParamList *param_list) {
  * them to Clownfish-flavored C values.
  */
 static char*
-S_gen_arg_parsing(CFCParamList *param_list) {
+S_gen_arg_parsing(CFCParamList *param_list, int first_tick, char **error) {
     char *content = NULL;
 
     CFCVariable **vars = CFCParamList_get_variables(param_list);
@@ -84,6 +84,21 @@ S_gen_arg_parsing(CFCParamList *param_list) {
     char *targets      = CFCUtil_strdup("");
     int optional_started = 0;
 
+    for (int i = first_tick; i < num_vars; i++) {
+        const char  *val  = vals[i];
+        if (val == NULL) {
+            if (optional_started) { // problem!
+                *error = "Required after optional param";
+                goto CLEAN_UP_AND_RETURN;
+            }
+        }
+        else {
+            if (!optional_started) {
+                optional_started = 1;
+            }
+        }
+    }
+
     char parse_pattern[] =
         "%s"
         "    char *keywords[] = {%sNULL};\n"
@@ -95,6 +110,7 @@ S_gen_arg_parsing(CFCParamList *param_list) {
     content = CFCUtil_sprintf(parse_pattern, declarations, keywords,
                               format_str, targets);
 
+CLEAN_UP_AND_RETURN:
     FREEMEM(declarations);
     FREEMEM(keywords);
     FREEMEM(format_str);
@@ -262,7 +278,14 @@ S_meth_top(CFCMethod *method) {
         return CFCUtil_sprintf(pattern);
     }
     else {
-        char *arg_parsing = S_gen_arg_parsing(param_list);
+        char *error = NULL;
+        char *arg_parsing = S_gen_arg_parsing(param_list, 1, &error);
+        if (error) {
+            CFCUtil_die("%s in %s", error, CFCMethod_get_name(method));
+        }
+        if (!arg_parsing) {
+            return NULL;
+        }
         char pattern[] =
             "(PyObject *self, PyObject *args, PyObject *kwargs) {\n"
             "%s"


[04/22] lucy-clownfish git commit: Prepare to parse Python meth args.

Posted by ma...@apache.org.
Prepare to parse Python meth args.

Stub out data structures into which we will read arguments from 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/15602e67
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/15602e67
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/15602e67

Branch: refs/heads/master
Commit: 15602e67deb05b28329c9eaf0612a739547ddf8b
Parents: 6a50d21
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Tue Feb 2 11:03:02 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:24:52 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPyMethod.c | 40 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/15602e67/compiler/src/CFCPyMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index 863a0cb..c89d12c 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -67,6 +67,41 @@ S_build_py_args(CFCParamList *param_list) {
     return py_args;
 }
 
+/* Generate the code which parses arguments passed from Python and converts
+ * them to Clownfish-flavored C values.
+ */
+static char*
+S_gen_arg_parsing(CFCParamList *param_list) {
+    char *content = NULL;
+
+    CFCVariable **vars = CFCParamList_get_variables(param_list);
+    const char **vals = CFCParamList_get_initial_values(param_list);
+    int num_vars = CFCParamList_num_vars(param_list);
+
+    char *declarations = CFCUtil_strdup("");
+    char *keywords     = CFCUtil_strdup("");
+    char *format_str   = CFCUtil_strdup("");
+    char *targets      = CFCUtil_strdup("");
+    int optional_started = 0;
+
+    char parse_pattern[] =
+        "%s"
+        "    char *keywords[] = {%sNULL};\n"
+        "    char *fmt = \"%s\";\n"
+        "    int ok = PyArg_ParseTupleAndKeywords(args, kwargs, fmt,\n"
+        "        keywords%s);\n"
+        "    if (!ok) { return NULL; }\n"
+        ;
+    content = CFCUtil_sprintf(parse_pattern, declarations, keywords,
+                              format_str, targets);
+
+    FREEMEM(declarations);
+    FREEMEM(keywords);
+    FREEMEM(format_str);
+    FREEMEM(targets);
+    return content;
+}
+
 static char*
 S_build_pymeth_invocation(CFCMethod *method) {
     CFCType *return_type = CFCMethod_get_return_type(method);
@@ -227,10 +262,13 @@ S_meth_top(CFCMethod *method) {
         return CFCUtil_sprintf(pattern);
     }
     else {
+        char *arg_parsing = S_gen_arg_parsing(param_list);
         char pattern[] =
             "(PyObject *self, PyObject *args, PyObject *kwargs) {\n"
+            "%s"
             ;
-        char *result = CFCUtil_sprintf(pattern);
+        char *result = CFCUtil_sprintf(pattern, arg_parsing);
+        FREEMEM(arg_parsing);
         return result;
     }
 }


[14/22] lucy-clownfish git commit: Register PyMethodDefs for glued methods.

Posted by ma...@apache.org.
Register PyMethodDefs for glued methods.

Create PyMethodDef entries for each wrapped Clownfish method.


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

Branch: refs/heads/master
Commit: d8ced59cb135f628c0266e6aff0141152280f603
Parents: 71c836a
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Tue Feb 2 17:13:28 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:36:07 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPyClass.c             |  5 +++++
 compiler/src/CFCPyMethod.c            | 21 +++++++++++++++++++++
 compiler/src/CFCPyMethod.h            |  5 +++++
 runtime/python/test/test_clownfish.py |  2 ++
 4 files changed, 33 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d8ced59c/compiler/src/CFCPyClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyClass.c b/compiler/src/CFCPyClass.c
index 11a4905..529c6cf 100644
--- a/compiler/src/CFCPyClass.c
+++ b/compiler/src/CFCPyClass.c
@@ -160,6 +160,11 @@ CFCPyClass_gen_binding_code(CFCPyClass *self) {
         char *wrapper = CFCPyMethod_wrapper(meth, klass);
         bindings = CFCUtil_cat(bindings, wrapper, "\n", NULL);
         FREEMEM(wrapper);
+
+        // Add PyMethodDef entry.
+        char *meth_def = CFCPyMethod_pymethoddef(meth, klass);
+        meth_defs = CFCUtil_cat(meth_defs, "    ", meth_def, "\n", NULL);
+        FREEMEM(meth_def);
     }
 
     // Complete the PyMethodDef array.

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d8ced59c/compiler/src/CFCPyMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index 4220aea..1291568 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -519,3 +519,24 @@ CFCPyMethod_wrapper(CFCMethod *method, CFCClass *invoker) {
     return wrapper;
 }
 
+char*
+CFCPyMethod_pymethoddef(CFCMethod *method, CFCClass *invoker) {
+    CFCParamList *param_list = CFCMethod_get_param_list(method);
+    const char *flags = CFCParamList_num_vars(param_list) == 1
+                        ? "METH_NOARGS"
+                        : "METH_KEYWORDS|METH_VARARGS";
+    char *meth_sym = CFCMethod_full_method_sym(method, invoker);
+    char *micro_sym = CFCUtil_strdup(CFCSymbol_get_name((CFCSymbol*)method));
+    for (int i = 0; micro_sym[i] != 0; i++) {
+        micro_sym[i] = tolower(micro_sym[i]);
+    }
+
+    char pattern[] =
+        "{\"%s\", (PyCFunction)S_%s, %s, NULL},";
+    char *py_meth_def = CFCUtil_sprintf(pattern, micro_sym, meth_sym, flags);
+
+    FREEMEM(meth_sym);
+    FREEMEM(micro_sym);
+    return py_meth_def;
+}
+

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d8ced59c/compiler/src/CFCPyMethod.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.h b/compiler/src/CFCPyMethod.h
index 53768e2..b3d6808 100644
--- a/compiler/src/CFCPyMethod.h
+++ b/compiler/src/CFCPyMethod.h
@@ -31,6 +31,11 @@ struct CFCClass;
 char*
 CFCPyMethod_callback_def(struct CFCMethod *method, struct CFCClass *invoker);
 
+/** Generate a PyMethodDef entry for an instance method.
+  */
+char*
+CFCPyMethod_pymethoddef(struct CFCMethod *method, struct CFCClass *invoker);
+
 char*
 CFCPyMethod_wrapper(struct CFCMethod *method, struct CFCClass *invoker);
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d8ced59c/runtime/python/test/test_clownfish.py
----------------------------------------------------------------------
diff --git a/runtime/python/test/test_clownfish.py b/runtime/python/test/test_clownfish.py
index d8f2594..f7908ca 100644
--- a/runtime/python/test/test_clownfish.py
+++ b/runtime/python/test/test_clownfish.py
@@ -14,6 +14,7 @@
 # limitations under the License.
 
 import unittest
+import inspect
 import clownfish
 
 class MyTest(unittest.TestCase):
@@ -23,6 +24,7 @@ class MyTest(unittest.TestCase):
 
     def testClassesPresent(self):
         self.assertIsInstance(clownfish.Hash, type)
+        self.assertTrue(inspect.ismethoddescriptor(clownfish.Hash.store))
 
 if __name__ == '__main__':
     unittest.main()


[12/22] lucy-clownfish git commit: Handle default values for primitive types.

Posted by ma...@apache.org.
Handle default values for primitive types.

Set conversion args to default values prior to Python argument parsing.


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

Branch: refs/heads/master
Commit: 73635f233dc3a5b1addf17aacdf5773d8fad1113
Parents: 2e4d3d3
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Fri Feb 5 18:03:01 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:36:07 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPyMethod.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/73635f23/compiler/src/CFCPyMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index ef8b152..d8128c2 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -124,7 +124,10 @@ S_gen_declaration(CFCVariable *var, const char *val) {
         }
     }
     else if (CFCType_is_primitive(type)) {
-        ;
+        if (val) {
+            char pattern[] = "    %s_ARG = %s;\n";
+            result = CFCUtil_sprintf(pattern, var_name, val);
+        }
     }
     else {
         CFCUtil_die("Unexpected type, can't gen declaration: %s", type_str);


[16/22] lucy-clownfish git commit: Add increfs and decrefs to gen ctor glue.

Posted by ma...@apache.org.
Add increfs and decrefs to gen ctor glue.

Incref decremented args. Signal to CFBind_run_trapped when it needs to
decref some args.


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

Branch: refs/heads/master
Commit: 2e4d3d3e6292539af7aab6419286ebe1be90e5ba
Parents: a6068b4
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Tue Feb 2 18:48:50 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:36:07 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPyMethod.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2e4d3d3e/compiler/src/CFCPyMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index 2f6168a..ef8b152 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -523,6 +523,8 @@ char*
 CFCPyMethod_constructor_wrapper(CFCFunction *init_func, CFCClass *invoker) {
     CFCParamList *param_list  = CFCFunction_get_param_list(init_func);
     char *decs       = S_gen_decs(param_list, 1);
+    char *increfs    = S_gen_arg_increfs(param_list, 1);
+    char *decrefs    = S_gen_decrefs(param_list, 1);
     const char *struct_sym = CFCClass_full_struct_sym(invoker);
     char *error = NULL;
     char *arg_parsing = S_gen_arg_parsing(param_list, 1, &error);
@@ -540,12 +542,16 @@ CFCPyMethod_constructor_wrapper(CFCFunction *init_func, CFCClass *invoker) {
         "S_%s_PY_NEW(PyTypeObject *type, PyObject *args, PyObject *kwargs) {\n"
         "%s" // decs
         "%s" // arg_parsing
+        "%s" // increfs
+        "%s" // decrefs
         "    Py_RETURN_NONE;\n"
         "}\n"
         ;
     char *wrapper = CFCUtil_sprintf(pattern, struct_sym, decs,
-                                    arg_parsing);
+                                    arg_parsing, increfs, decrefs);
 
+    FREEMEM(decrefs);
+    FREEMEM(increfs);
     FREEMEM(decs);
     FREEMEM(arg_parsing);
     return wrapper;


[21/22] lucy-clownfish git commit: Add actual method invocation to Py glue.

Posted by ma...@apache.org.
Add actual method invocation to Py glue.


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

Branch: refs/heads/master
Commit: f624495ea3f0e80a6d95fb37d51fdb7a2b5b8124
Parents: 674721c
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Mon Feb 22 19:40:17 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:41:13 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPyMethod.c | 64 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 62 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/f624495e/compiler/src/CFCPyMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index ea97d6a..f83fdc0 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -497,24 +497,84 @@ S_gen_arg_list(CFCParamList *param_list, const char *first_arg) {
     return arg_list;
 }
 
+static char*
+S_gen_meth_invocation(CFCMethod *method, CFCClass *invoker) {
+    CFCParamList *param_list = CFCMethod_get_param_list(method);
+    char *full_meth = CFCMethod_full_method_sym(method, invoker);
+    char *meth_type_c = CFCMethod_full_typedef(method, invoker);
+    const char *class_var = CFCClass_full_class_var(invoker);
+    char *first_arg
+        = CFCUtil_sprintf("(%s*)self", CFCClass_full_struct_sym(invoker));
+    char *arg_list = S_gen_arg_list(param_list, first_arg);
+
+    CFCType *return_type = CFCMethod_get_return_type(method);
+    char *maybe_declare;
+    const char *maybe_assign;
+    if (CFCType_is_void(return_type)) {
+        maybe_declare = CFCUtil_strdup("");
+        maybe_assign = "";
+    }
+    else {
+        maybe_declare = CFCUtil_sprintf("    %s retvalCF;\n",
+                                        CFCType_to_c(return_type));
+        maybe_assign = "retvalCF = ";
+    }
+
+    const char pattern[] =
+        "%s"
+        "    %s method = CFISH_METHOD_PTR(%s, %s);\n"
+        "    CFBIND_TRY(%smethod(%s));\n"
+        ;
+    char *content
+        = CFCUtil_sprintf(pattern, maybe_declare, meth_type_c, class_var,
+                          full_meth, maybe_assign, arg_list);
+
+    FREEMEM(arg_list);
+    FREEMEM(first_arg);
+    FREEMEM(maybe_declare);
+    FREEMEM(full_meth);
+    FREEMEM(meth_type_c);
+    return content;
+}
+
 char*
 CFCPyMethod_wrapper(CFCMethod *method, CFCClass *invoker) {
     CFCParamList *param_list  = CFCMethod_get_param_list(method);
+    CFCType      *return_type = CFCMethod_get_return_type(method);
     char *meth_sym   = CFCMethod_full_method_sym(method, invoker);
     char *meth_top   = S_meth_top(method);
     char *increfs    = S_gen_arg_increfs(param_list, 1);
     char *decrefs    = S_gen_decrefs(param_list, 1);
+    char *invocation = S_gen_meth_invocation(method, invoker);
+    char *ret;
+    if (CFCType_is_void(return_type)) {
+        ret = CFCUtil_strdup("    Py_RETURN_NONE;\n");
+    }
+    else if (CFCType_incremented(return_type)) {
+        ret = CFCUtil_strdup("    return CFBind_cfish_to_py_zeroref((cfish_Obj*)retvalCF);\n");
+    }
+    else {
+        char *conv = CFCPyTypeMap_c_to_py(return_type, "retvalCF");
+        ret = CFCUtil_sprintf("    return %s;\n", conv);
+        FREEMEM(conv);
+    }
 
     char pattern[] =
         "static PyObject*\n"
         "S_%s%s"
         "%s" // increfs
+        "%s" // invocation
         "%s" // decrefs
-        "    Py_RETURN_NONE;\n"
+        "    if (CFBind_migrate_cferr()) {\n"
+        "        return NULL;\n"
+        "    }\n"
+        "%s" // ret
         "}\n"
         ;
     char *wrapper = CFCUtil_sprintf(pattern, meth_sym, meth_top,
-                                    increfs, decrefs);
+                                    increfs, invocation, decrefs, ret);
+    FREEMEM(ret);
+    FREEMEM(invocation);
     FREEMEM(decrefs);
     FREEMEM(increfs);
     FREEMEM(meth_sym);


[19/22] lucy-clownfish git commit: Add actual constructor invocation to Py glue.

Posted by ma...@apache.org.
Add actual constructor invocation to Py glue.


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

Branch: refs/heads/master
Commit: 8b41f26264da06c6b43655a1e939ac1123957d9d
Parents: f624495
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Mon Feb 22 19:40:54 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:41:13 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPyMethod.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8b41f262/compiler/src/CFCPyMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index f83fdc0..3d13665 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -586,9 +586,13 @@ CFCPyMethod_wrapper(CFCMethod *method, CFCClass *invoker) {
 char*
 CFCPyMethod_constructor_wrapper(CFCFunction *init_func, CFCClass *invoker) {
     CFCParamList *param_list  = CFCFunction_get_param_list(init_func);
+    const char *self_type
+        = CFCType_to_c(CFCFunction_get_return_type(init_func));
+    char *func_sym   = CFCFunction_full_func_sym(init_func, invoker);
     char *decs       = S_gen_decs(param_list, 1);
     char *increfs    = S_gen_arg_increfs(param_list, 1);
     char *decrefs    = S_gen_decrefs(param_list, 1);
+    const char *class_var  = CFCClass_full_class_var(invoker);
     const char *struct_sym = CFCClass_full_struct_sym(invoker);
     char *error = NULL;
     char *arg_parsing = S_gen_arg_parsing(param_list, 1, &error);
@@ -600,6 +604,9 @@ CFCPyMethod_constructor_wrapper(CFCFunction *init_func, CFCClass *invoker) {
         CFCUtil_die("Unexpected arg parsing error for %s",
                     CFCClass_get_name(invoker));
     }
+    char *first_arg = CFCUtil_sprintf("(%s)CFISH_Class_Make_Obj(%s)",
+                                      self_type, class_var);
+    char *arg_list = S_gen_arg_list(param_list, first_arg);
 
     char pattern[] =
         "static PyObject*\n"
@@ -607,13 +614,22 @@ CFCPyMethod_constructor_wrapper(CFCFunction *init_func, CFCClass *invoker) {
         "%s" // decs
         "%s" // arg_parsing
         "%s" // increfs
+        "    %s self = NULL;\n"
+        "    CFBIND_TRY(self = %s(%s));\n"
         "%s" // decrefs
-        "    Py_RETURN_NONE;\n"
+        "    if (CFBind_migrate_cferr()) {\n"
+        "        return NULL;\n"
+        "    }\n"
+        "    return (PyObject*)self;\n"
         "}\n"
         ;
     char *wrapper = CFCUtil_sprintf(pattern, struct_sym, decs,
-                                    arg_parsing, increfs, decrefs);
+                                    arg_parsing, increfs, self_type,
+                                    func_sym, arg_list, decrefs);
 
+    FREEMEM(arg_list);
+    FREEMEM(first_arg);
+    FREEMEM(func_sym);
     FREEMEM(decrefs);
     FREEMEM(increfs);
     FREEMEM(decs);


[15/22] lucy-clownfish git commit: Stub out generated Python constructors.

Posted by ma...@apache.org.
Stub out generated Python constructors.


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

Branch: refs/heads/master
Commit: 5443a74386b0bd6217d12c16a5ef9265c99d78c7
Parents: d8ced59
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Tue Feb 2 17:50:12 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:36:07 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPyClass.c  | 23 +++++++++++++++++++++--
 compiler/src/CFCPyMethod.c | 18 ++++++++++++++++++
 compiler/src/CFCPyMethod.h |  7 +++++++
 3 files changed, 46 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5443a743/compiler/src/CFCPyClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyClass.c b/compiler/src/CFCPyClass.c
index 529c6cf..0fe168e 100644
--- a/compiler/src/CFCPyClass.c
+++ b/compiler/src/CFCPyClass.c
@@ -145,6 +145,14 @@ CFCPyClass_gen_binding_code(CFCPyClass *self) {
     char *bindings  = CFCUtil_strdup(self->pre_code ? self->pre_code : "");
     char *meth_defs = CFCUtil_strdup(self->meth_defs);
 
+    // Constructor.
+    CFCFunction *init_func = CFCClass_function(klass, "init");
+    if (init_func && CFCFunction_can_be_bound(init_func)) {
+        char *wrapper = CFCPyMethod_constructor_wrapper(init_func, klass);
+        bindings = CFCUtil_cat(bindings, wrapper, "\n", NULL);
+        FREEMEM(wrapper);
+    }
+
     // Instance methods.
     CFCMethod **methods = CFCClass_fresh_methods(klass);
     for (size_t j = 0; methods[j] != NULL; j++) {
@@ -201,6 +209,16 @@ S_pytype_struct_def(CFCPyClass *self) {
 
     const char *struct_sym = CFCClass_get_struct_sym(klass);
 
+    char *tp_new;
+    CFCFunction *init_func = CFCClass_function(klass, "init");
+    if (init_func && CFCFunction_can_be_bound(init_func)) {
+        tp_new = CFCUtil_sprintf("S_%s_PY_NEW",
+                                 CFCClass_full_struct_sym(klass));
+    }
+    else {
+        tp_new = CFCUtil_strdup("0");
+    }
+
     char pattern[] =
         "static PyTypeObject %s_pytype_struct = {\n"
         "    PyVarObject_HEAD_INIT(NULL, 0)\n"
@@ -240,12 +258,13 @@ S_pytype_struct_def(CFCPyClass *self) {
         "    0,                                  // tp_dictoffset\n"
         "    0,                                  // tp_init\n"
         "    0,                                  // tp_allow\n"
-        "    0,                                  // tp_new\n"
+        "    %s,                                 // tp_new\n"
         "};\n"
         ;
     char *content = CFCUtil_sprintf(pattern, struct_sym, pymod_name,
-                                    struct_sym, struct_sym);
+                                    struct_sym, struct_sym, tp_new);
 
+    FREEMEM(tp_new);
     FREEMEM(pymod_name);
     return content;
 }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5443a743/compiler/src/CFCPyMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index 1291568..c93252e 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -520,6 +520,24 @@ CFCPyMethod_wrapper(CFCMethod *method, CFCClass *invoker) {
 }
 
 char*
+CFCPyMethod_constructor_wrapper(CFCFunction *init_func, CFCClass *invoker) {
+    const char *struct_sym = CFCClass_full_struct_sym(invoker);
+
+    char pattern[] =
+        "static PyObject*\n"
+        "S_%s_PY_NEW(PyTypeObject *type, PyObject *args, PyObject *kwargs) {\n"
+        "    CFISH_UNUSED_VAR(type);\n"
+        "    CFISH_UNUSED_VAR(args);\n"
+        "    CFISH_UNUSED_VAR(kwargs);\n"
+        "    Py_RETURN_NONE;\n"
+        "}\n"
+        ;
+    char *wrapper = CFCUtil_sprintf(pattern, struct_sym);
+
+    return wrapper;
+}
+
+char*
 CFCPyMethod_pymethoddef(CFCMethod *method, CFCClass *invoker) {
     CFCParamList *param_list = CFCMethod_get_param_list(method);
     const char *flags = CFCParamList_num_vars(param_list) == 1

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5443a743/compiler/src/CFCPyMethod.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.h b/compiler/src/CFCPyMethod.h
index b3d6808..f85844f 100644
--- a/compiler/src/CFCPyMethod.h
+++ b/compiler/src/CFCPyMethod.h
@@ -21,6 +21,7 @@
 extern "C" {
 #endif
 
+struct CFCFunction;
 struct CFCMethod;
 struct CFCClass;
 
@@ -39,6 +40,12 @@ CFCPyMethod_pymethoddef(struct CFCMethod *method, struct CFCClass *invoker);
 char*
 CFCPyMethod_wrapper(struct CFCMethod *method, struct CFCClass *invoker);
 
+/** Generate glue code for a constructor.
+  */
+char*
+CFCPyMethod_constructor_wrapper(struct CFCFunction *init_func,
+                                struct CFCClass *invoker);
+
 #ifdef __cplusplus
 }
 #endif


[18/22] lucy-clownfish git commit: Test err handling in Py glue.

Posted by ma...@apache.org.
Test err handling in Py glue.

Check that a Clownfish exception gets transformed into a Python
exception.


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

Branch: refs/heads/master
Commit: 674721cc3e0f7fac030cf75fcdcfc4ee3d2f539f
Parents: b05965c
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Mon Feb 22 18:29:02 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:36:08 2016 -0800

----------------------------------------------------------------------
 runtime/python/test/test_err.py | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/674721cc/runtime/python/test/test_err.py
----------------------------------------------------------------------
diff --git a/runtime/python/test/test_err.py b/runtime/python/test/test_err.py
new file mode 100644
index 0000000..a553d74
--- /dev/null
+++ b/runtime/python/test/test_err.py
@@ -0,0 +1,31 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import unittest
+import clownfish
+import sys
+
+class TestErr(unittest.TestCase):
+
+    def testErrorHandling(self):
+        vec = clownfish.Vector()
+        try:
+            vec.grow(sys.maxsize)
+        except RuntimeError as e:
+            self.assertTrue(str(e).find("overflow") != -1)
+
+if __name__ == '__main__':
+    unittest.main()
+


[22/22] lucy-clownfish git commit: Merge branch 'CLOWNFISH-66-py-glue3'

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

Gen Py glue for methods and constructors.

* Autogenerate CPython glue code for methods and constructors.
* Handle both positional and labeled args.
* Deal with refcounting of args and return values.
* Trap Clownfish exceptions and rethrow as Python exceptions.
* Unit test Py binding of Hash.

This closes #60.


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

Branch: refs/heads/master
Commit: 89fc046405bf5ae9613219ef8af10cea6082a97c
Parents: 43de47b 9d058f4
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Mon Feb 29 18:59:47 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Mon Feb 29 18:59:47 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPyClass.c             |  45 ++-
 compiler/src/CFCPyMethod.c            | 443 +++++++++++++++++++++++++++++
 compiler/src/CFCPyMethod.h            |  15 +
 runtime/python/cfext/CFBind.c         |   7 +-
 runtime/python/test/test_clownfish.py |   2 +
 runtime/python/test/test_err.py       |  31 ++
 runtime/python/test/test_hash.py      | 102 +++++++
 7 files changed, 640 insertions(+), 5 deletions(-)
----------------------------------------------------------------------



[11/22] lucy-clownfish git commit: More liberal Py to Cfish Obj conversion.

Posted by ma...@apache.org.
More liberal Py to Cfish Obj conversion.

When converting a Python argument to Clownfish `Obj*`, allow conversion
from Python dict, list, string, integer, and other types -- instead of
just checking to confirm that the argument is already a Clownfish Obj.


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

Branch: refs/heads/master
Commit: b05965cafb60362badf530872dc81a304b9db761
Parents: 73635f2
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Sat Feb 6 09:41:59 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:36:07 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPyMethod.c    | 3 ++-
 runtime/python/cfext/CFBind.c | 7 ++++---
 2 files changed, 6 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/b05965ca/compiler/src/CFCPyMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index d8128c2..ea97d6a 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -464,7 +464,8 @@ S_gen_decrefs(CFCParamList *param_list, int first_tick) {
         const char *micro_sym = CFCVariable_get_name(var);
         const char *specifier = CFCType_get_specifier(type);
 
-        if (strcmp(specifier, "cfish_String") == 0
+        if (strcmp(specifier, "cfish_Obj") == 0
+             || strcmp(specifier, "cfish_String") == 0
              || strcmp(specifier, "cfish_Vector") == 0
              || strcmp(specifier, "cfish_Hash") == 0
             ) {

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/b05965ca/runtime/python/cfext/CFBind.c
----------------------------------------------------------------------
diff --git a/runtime/python/cfext/CFBind.c b/runtime/python/cfext/CFBind.c
index a1e47eb..cd77078 100644
--- a/runtime/python/cfext/CFBind.c
+++ b/runtime/python/cfext/CFBind.c
@@ -294,12 +294,13 @@ S_convert_obj(PyObject *py_obj, CFBindArg *arg, bool nullable) {
             return 0;
         }
     }
-    PyTypeObject *py_type = S_get_cached_py_type(arg->klass);
-    if (!PyObject_TypeCheck(py_obj, py_type)) {
+
+    bool success = S_maybe_py_to_cfish(py_obj, arg->klass, true, nullable,
+                                       NULL, arg->ptr);
+    if (!success) {
         PyErr_SetString(PyExc_TypeError, "Invalid argument type");
         return 0;
     }
-    *((PyObject**)arg->ptr) = py_obj;
     return 1;
 }
 


[06/22] lucy-clownfish git commit: Gen CFBindArg declarations.

Posted by ma...@apache.org.
Gen CFBindArg declarations.

Generate the declarations for the CFBindArg wrapper structs which are
required by some Python argument conversion routines.


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

Branch: refs/heads/master
Commit: 1853cbfd000430937312142034090de25de8039f
Parents: f11b123
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Tue Feb 2 13:38:19 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:24:52 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPyMethod.c | 58 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/1853cbfd/compiler/src/CFCPyMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index dc98fb4..48ef443 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -81,6 +81,58 @@ S_gen_decs(CFCParamList *param_list, int first_tick) {
     return decs;
 }
 
+/* Some of the ParseTuple conversion routines provided by the Python-flavored
+ * CFBind module accept a CFBindArg instead of just a pointer to the value
+ * itself.  This routine generates the declarations for those CFBindArg
+ * variables, as well as handling some default values.
+ */
+static char*
+S_gen_declaration(CFCVariable *var, const char *val) {
+    CFCType *type = CFCVariable_get_type(var);
+    const char *var_name = CFCVariable_get_name(var);
+    const char *type_str = CFCType_to_c(type);
+    char *result = NULL;
+
+    if (CFCType_is_object(type)) {
+        const char *specifier = CFCType_get_specifier(type);
+        if (strcmp(specifier, "cfish_String") == 0) {
+            if (val && strcmp(val, "NULL") != 0) {
+                const char pattern[] =
+                    "    const char arg_%s_DEFAULT[] = %s;\n"
+                    "    %s_ARG = CFISH_SSTR_WRAP_UTF8(\n"
+                    "        arg_%s_DEFAULT, sizeof(arg_%s_DEFAULT) - 1);\n"
+                    ;
+                result = CFCUtil_sprintf(pattern, var_name, val, var_name,
+                                         var_name, var_name);
+            }
+        }
+        else {
+            if (val && strcmp(val, "NULL") != 0) {
+                CFCUtil_die("Can't assign a default of '%s' to a %s",
+                            val, type_str);
+            }
+            if (strcmp(specifier, "cfish_Hash") != 0
+                && strcmp(specifier, "cfish_Vector") != 0
+                ) {
+                const char *class_var = CFCType_get_class_var(type);
+                char pattern[] =
+                    "    CFBindArg wrap_arg_%s = {%s, &%s_ARG};\n"
+                    ;
+                result = CFCUtil_sprintf(pattern, var_name, class_var,
+                                         var_name);
+            }
+        }
+    }
+    else if (CFCType_is_primitive(type)) {
+        ;
+    }
+    else {
+        CFCUtil_die("Unexpected type, can't gen declaration: %s", type_str);
+    }
+
+    return result;
+}
+
 /* Generate the code which parses arguments passed from Python and converts
  * them to Clownfish-flavored C values.
  */
@@ -99,7 +151,9 @@ S_gen_arg_parsing(CFCParamList *param_list, int first_tick, char **error) {
     int optional_started = 0;
 
     for (int i = first_tick; i < num_vars; i++) {
+        CFCVariable *var  = vars[i];
         const char  *val  = vals[i];
+
         if (val == NULL) {
             if (optional_started) { // problem!
                 *error = "Required after optional param";
@@ -111,6 +165,10 @@ S_gen_arg_parsing(CFCParamList *param_list, int first_tick, char **error) {
                 optional_started = 1;
             }
         }
+
+        char *declaration = S_gen_declaration(var, val);
+        declarations = CFCUtil_cat(declarations, declaration, NULL);
+        FREEMEM(declaration);
     }
 
     char parse_pattern[] =


[05/22] lucy-clownfish git commit: Consider num args in Py binding.

Posted by ma...@apache.org.
Consider num args in Py binding.

For generated CPython method glue code, support keyword args if the
method takes arguments.


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

Branch: refs/heads/master
Commit: 6a50d2179d0464048f54f021eff3e70029b6162d
Parents: cb25fd0
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Tue Feb 2 10:39:32 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:24:52 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPyMethod.c | 28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/6a50d217/compiler/src/CFCPyMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index 0a5cd27..863a0cb 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -215,20 +215,40 @@ S_maybe_unreachable(CFCType *return_type) {
     return return_statement;
 }
 
+static char*
+S_meth_top(CFCMethod *method) {
+    CFCParamList *param_list = CFCMethod_get_param_list(method);
+
+    if (CFCParamList_num_vars(param_list) == 1) {
+        char pattern[] =
+            "(PyObject *self, PyObject *unused) {\n"
+            "    CFISH_UNUSED_VAR(unused);\n"
+            ;
+        return CFCUtil_sprintf(pattern);
+    }
+    else {
+        char pattern[] =
+            "(PyObject *self, PyObject *args, PyObject *kwargs) {\n"
+            ;
+        char *result = CFCUtil_sprintf(pattern);
+        return result;
+    }
+}
+
 char*
 CFCPyMethod_wrapper(CFCMethod *method, CFCClass *invoker) {
     char *meth_sym   = CFCMethod_full_method_sym(method, invoker);
+    char *meth_top   = S_meth_top(method);
 
     char pattern[] =
         "static PyObject*\n"
-        "S_%s(PyObject *unused1, PyObject *unused2) {\n"
-        "    CFISH_UNUSED_VAR(unused1);\n"
-        "    CFISH_UNUSED_VAR(unused2);\n"
+        "S_%s%s"
         "    Py_RETURN_NONE;\n"
         "}\n"
         ;
-    char *wrapper = CFCUtil_sprintf(pattern, meth_sym);
+    char *wrapper = CFCUtil_sprintf(pattern, meth_sym, meth_top);
     FREEMEM(meth_sym);
+    FREEMEM(meth_top);
 
     return wrapper;
 }


[09/22] lucy-clownfish git commit: Incref `decremented` args in Py glue.

Posted by ma...@apache.org.
Incref `decremented` args in Py glue.

For args that are specified as `decremented` in the Clownfish method
signature, add an INCREF in the glue code.


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

Branch: refs/heads/master
Commit: a9daf3cf7bb82ee5c9f51a83b5f3d166fb35de6d
Parents: 4cdfb56
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Tue Feb 2 15:44:10 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:32:30 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPyMethod.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a9daf3cf/compiler/src/CFCPyMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index 8d6adfb..5464dbb 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -427,18 +427,43 @@ S_meth_top(CFCMethod *method) {
     }
 }
 
+static char*
+S_gen_arg_increfs(CFCParamList *param_list, int first_tick) {
+    CFCVariable **vars = CFCParamList_get_variables(param_list);
+    int num_vars = CFCParamList_num_vars(param_list);
+    char *content = CFCUtil_strdup("");
+    for (int i = first_tick;i < num_vars; i++) {
+        CFCType *type = CFCVariable_get_type(vars[i]);
+        if (CFCType_decremented(type)) {
+            const char *name = CFCVariable_get_name(vars[i]);
+            const char *specifier = CFCType_get_specifier(type);
+            char pattern[] =
+                "    %s_ARG = (%s*)CFISH_INCREF(%s_ARG);\n";
+            char *incref = CFCUtil_sprintf(pattern, name, specifier, name);
+            content = CFCUtil_cat(content, incref, NULL);
+            FREEMEM(incref);
+        }
+    }
+    return content;
+}
+
 char*
 CFCPyMethod_wrapper(CFCMethod *method, CFCClass *invoker) {
+    CFCParamList *param_list  = CFCMethod_get_param_list(method);
     char *meth_sym   = CFCMethod_full_method_sym(method, invoker);
     char *meth_top   = S_meth_top(method);
+    char *increfs    = S_gen_arg_increfs(param_list, 1);
 
     char pattern[] =
         "static PyObject*\n"
         "S_%s%s"
+        "%s" // increfs
         "    Py_RETURN_NONE;\n"
         "}\n"
         ;
-    char *wrapper = CFCUtil_sprintf(pattern, meth_sym, meth_top);
+    char *wrapper = CFCUtil_sprintf(pattern, meth_sym, meth_top,
+                                    increfs);
+    FREEMEM(increfs);
     FREEMEM(meth_sym);
     FREEMEM(meth_top);
 


[10/22] lucy-clownfish git commit: Prepare decrefs to run in Py glue.

Posted by ma...@apache.org.
Prepare decrefs to run in Py glue.


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

Branch: refs/heads/master
Commit: d88c0bf5c19a22b655bb5c59a6f2a0d2c366f85c
Parents: a9daf3c
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Tue Feb 2 15:46:23 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:35:27 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPyMethod.c | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d88c0bf5/compiler/src/CFCPyMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index 5464dbb..450c26e 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -447,22 +447,51 @@ S_gen_arg_increfs(CFCParamList *param_list, int first_tick) {
     return content;
 }
 
+// Prep refcount decrement calls to follow the Clownfish subroutine
+// invocation.
+static char*
+S_gen_decrefs(CFCParamList *param_list, int first_tick) {
+    CFCVariable **vars = CFCParamList_get_variables(param_list);
+    int num_vars = CFCParamList_num_vars(param_list);
+    char *decrefs = CFCUtil_strdup("");
+
+    for (int i = first_tick; i < num_vars; i++) {
+        CFCVariable *var = vars[i];
+        CFCType *type = CFCVariable_get_type(var);
+        const char *micro_sym = CFCVariable_get_name(var);
+        const char *specifier = CFCType_get_specifier(type);
+
+        if (strcmp(specifier, "cfish_String") == 0
+             || strcmp(specifier, "cfish_Vector") == 0
+             || strcmp(specifier, "cfish_Hash") == 0
+            ) {
+            decrefs = CFCUtil_cat(decrefs, "    CFISH_DECREF(", micro_sym,
+                                  "_ARG);\n", NULL);
+        }
+    }
+
+    return decrefs;
+}
+
 char*
 CFCPyMethod_wrapper(CFCMethod *method, CFCClass *invoker) {
     CFCParamList *param_list  = CFCMethod_get_param_list(method);
     char *meth_sym   = CFCMethod_full_method_sym(method, invoker);
     char *meth_top   = S_meth_top(method);
     char *increfs    = S_gen_arg_increfs(param_list, 1);
+    char *decrefs    = S_gen_decrefs(param_list, 1);
 
     char pattern[] =
         "static PyObject*\n"
         "S_%s%s"
         "%s" // increfs
+        "%s" // decrefs
         "    Py_RETURN_NONE;\n"
         "}\n"
         ;
     char *wrapper = CFCUtil_sprintf(pattern, meth_sym, meth_top,
-                                    increfs);
+                                    increfs, decrefs);
+    FREEMEM(decrefs);
     FREEMEM(increfs);
     FREEMEM(meth_sym);
     FREEMEM(meth_top);


[17/22] lucy-clownfish git commit: Gen arg parsing for Py constructor glue.

Posted by ma...@apache.org.
Gen arg parsing for Py constructor glue.


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

Branch: refs/heads/master
Commit: a6068b41523b9c216bb63ace4d66f9f5cccf1477
Parents: 5443a74
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Tue Feb 2 18:43:41 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:36:07 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPyMethod.c | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/a6068b41/compiler/src/CFCPyMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index c93252e..2f6168a 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -521,19 +521,33 @@ CFCPyMethod_wrapper(CFCMethod *method, CFCClass *invoker) {
 
 char*
 CFCPyMethod_constructor_wrapper(CFCFunction *init_func, CFCClass *invoker) {
+    CFCParamList *param_list  = CFCFunction_get_param_list(init_func);
+    char *decs       = S_gen_decs(param_list, 1);
     const char *struct_sym = CFCClass_full_struct_sym(invoker);
+    char *error = NULL;
+    char *arg_parsing = S_gen_arg_parsing(param_list, 1, &error);
+    if (error) {
+        CFCUtil_die("%s in constructor for %s", error,
+                    CFCClass_get_name(invoker));
+    }
+    if (!arg_parsing) {
+        CFCUtil_die("Unexpected arg parsing error for %s",
+                    CFCClass_get_name(invoker));
+    }
 
     char pattern[] =
         "static PyObject*\n"
         "S_%s_PY_NEW(PyTypeObject *type, PyObject *args, PyObject *kwargs) {\n"
-        "    CFISH_UNUSED_VAR(type);\n"
-        "    CFISH_UNUSED_VAR(args);\n"
-        "    CFISH_UNUSED_VAR(kwargs);\n"
+        "%s" // decs
+        "%s" // arg_parsing
         "    Py_RETURN_NONE;\n"
         "}\n"
         ;
-    char *wrapper = CFCUtil_sprintf(pattern, struct_sym);
+    char *wrapper = CFCUtil_sprintf(pattern, struct_sym, decs,
+                                    arg_parsing);
 
+    FREEMEM(decs);
+    FREEMEM(arg_parsing);
     return wrapper;
 }
 


[03/22] lucy-clownfish git commit: Gen list of converter/arg-pointer pairs.

Posted by ma...@apache.org.
Gen list of converter/arg-pointer pairs.

Generate the list of function-pointer/arg-pointer pairs passed which get
passed to `PyArg_ParseTupleAndKeywords`.


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

Branch: refs/heads/master
Commit: ba87d53627914d6815122d59e9b0ae5afbcf9e23
Parents: 1853cbf
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Tue Feb 2 13:42:27 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:24:52 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPyMethod.c | 51 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/ba87d536/compiler/src/CFCPyMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index 48ef443..c0363a5 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -133,6 +133,53 @@ S_gen_declaration(CFCVariable *var, const char *val) {
     return result;
 }
 
+static char*
+S_gen_target(CFCVariable *var, const char *value) {
+    CFCType *type = CFCVariable_get_type(var);
+    const char *specifier = CFCType_get_specifier(type);
+    const char *micro_sym = CFCVariable_get_name(var);
+    const char *maybe_maybe = "";
+    const char *dest_name;
+    char *var_name = NULL;
+    if (CFCType_is_primitive(type)) {
+        dest_name = CFCType_get_specifier(type);
+        if (value != NULL) {
+            maybe_maybe = "maybe_";
+        }
+        var_name = CFCUtil_sprintf("%s_ARG", CFCVariable_get_name(var));
+    }
+    else if (CFCType_is_object(type)) {
+        if (CFCType_nullable(type) ||
+            (value && strcmp(value, "NULL") == 0)
+           ) {
+            maybe_maybe = "maybe_";
+        }
+        if (strcmp(specifier, "cfish_String") == 0) {
+            dest_name = "string";
+            var_name = CFCUtil_sprintf("%s_ARG", CFCVariable_get_name(var));
+        }
+        else if (strcmp(specifier, "cfish_Hash") == 0) {
+            dest_name = "hash";
+            var_name = CFCUtil_sprintf("%s_ARG", CFCVariable_get_name(var));
+        }
+        else if (strcmp(specifier, "cfish_Vector") == 0) {
+            dest_name = "vec";
+            var_name = CFCUtil_sprintf("%s_ARG", CFCVariable_get_name(var));
+        }
+        else {
+            dest_name = "obj";
+            var_name = CFCUtil_sprintf("wrap_arg_%s", micro_sym);
+        }
+    }
+    else {
+        dest_name = "INVALID";
+    }
+    char *content = CFCUtil_sprintf(", CFBind_%sconvert_%s, &%s",
+                                    maybe_maybe, dest_name, var_name);
+    FREEMEM(var_name);
+    return content;
+}
+
 /* Generate the code which parses arguments passed from Python and converts
  * them to Clownfish-flavored C values.
  */
@@ -169,6 +216,10 @@ S_gen_arg_parsing(CFCParamList *param_list, int first_tick, char **error) {
         char *declaration = S_gen_declaration(var, val);
         declarations = CFCUtil_cat(declarations, declaration, NULL);
         FREEMEM(declaration);
+
+        char *target = S_gen_target(var, val);
+        targets = CFCUtil_cat(targets, target, NULL);
+        FREEMEM(target);
     }
 
     char parse_pattern[] =


[07/22] lucy-clownfish git commit: Declare C arg vars in Py glue.

Posted by ma...@apache.org.
Declare C arg vars in Py glue.


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

Branch: refs/heads/master
Commit: f11b123c496486c51d3a402e16636fc6430fe379
Parents: 74878d3
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Mon Feb 22 19:34:59 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:24:52 2016 -0800

----------------------------------------------------------------------
 compiler/src/CFCPyMethod.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/f11b123c/compiler/src/CFCPyMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c
index fcbeee1..dc98fb4 100644
--- a/compiler/src/CFCPyMethod.c
+++ b/compiler/src/CFCPyMethod.c
@@ -67,6 +67,20 @@ S_build_py_args(CFCParamList *param_list) {
     return py_args;
 }
 
+static char*
+S_gen_decs(CFCParamList *param_list, int first_tick) {
+    char *decs = CFCUtil_strdup("");
+    int num_vars = CFCParamList_num_vars(param_list);
+    CFCVariable **vars = CFCParamList_get_variables(param_list);
+    for (int i = first_tick; i < num_vars; i++) {
+        CFCType *type = CFCVariable_get_type(vars[i]);
+        const char *name = CFCVariable_get_name(vars[i]);
+        decs = CFCUtil_cat(decs, "    ", CFCType_to_c(type), " ", name,
+                           "_ARG = 0;\n", NULL);
+    }
+    return decs;
+}
+
 /* Generate the code which parses arguments passed from Python and converts
  * them to Clownfish-flavored C values.
  */
@@ -286,11 +300,13 @@ S_meth_top(CFCMethod *method) {
         if (!arg_parsing) {
             return NULL;
         }
+        char *decs = S_gen_decs(param_list, 1);
         char pattern[] =
             "(PyObject *self, PyObject *args, PyObject *kwargs) {\n"
+            "%s" // decs
             "%s"
             ;
-        char *result = CFCUtil_sprintf(pattern, arg_parsing);
+        char *result = CFCUtil_sprintf(pattern, decs, arg_parsing);
         FREEMEM(arg_parsing);
         return result;
     }


[20/22] lucy-clownfish git commit: Add test for the Py binding of Hash.

Posted by ma...@apache.org.
Add test for the Py binding of Hash.


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

Branch: refs/heads/master
Commit: 9d058f4b324dabf4f2cdd2ea88f40c9aabe2d622
Parents: 8b41f26
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Wed Feb 10 18:45:50 2016 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed Feb 24 15:41:13 2016 -0800

----------------------------------------------------------------------
 runtime/python/test/test_hash.py | 102 ++++++++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/9d058f4b/runtime/python/test/test_hash.py
----------------------------------------------------------------------
diff --git a/runtime/python/test/test_hash.py b/runtime/python/test/test_hash.py
new file mode 100644
index 0000000..5bfd034
--- /dev/null
+++ b/runtime/python/test/test_hash.py
@@ -0,0 +1,102 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import unittest
+import inspect
+import clownfish
+
+class TestHash(unittest.TestCase):
+
+    def testStoreFetch(self):
+        h = clownfish.Hash()
+        h.store("foo", "bar")
+        h.store("foo", "bar")
+        self.assertEqual(h.fetch("foo"), "bar")
+        h.store("nada", None)
+        self.assertEqual(h.fetch("nada"), None)
+
+    def testDelete(self):
+        h = clownfish.Hash()
+        h.store("foo", "bar")
+        got = h.delete("foo")
+        self.assertEqual(h.get_size(), 0)
+        self.assertEqual(got, "bar")
+
+    def testClear(self):
+        h = clownfish.Hash()
+        h.store("foo", 1)
+        h.clear()
+        self.assertEqual(h.get_size(), 0)
+
+    def testHasKey(self):
+        h = clownfish.Hash()
+        h.store("foo", 1)
+        h.store("nada", None)
+        self.assertTrue(h.has_key("foo"))
+        self.assertFalse(h.has_key("bar"))
+        self.assertTrue(h.has_key("nada"))
+
+    def testKeys(self):
+        h = clownfish.Hash()
+        h.store("a", 1)
+        h.store("b", 1)
+        keys = sorted(h.keys())
+        self.assertEqual(keys, ["a", "b"])
+
+    def testValues(self):
+        h = clownfish.Hash()
+        h.store("foo", "a")
+        h.store("bar", "b")
+        got = sorted(h.values())
+        self.assertEqual(got, ["a", "b"])
+
+    def testGetCapacity(self):
+        h = clownfish.Hash(capacity=1)
+        self.assertGreater(h.get_capacity(), 0)
+
+    def testGetSize(self):
+        h = clownfish.Hash()
+        self.assertEqual(h.get_size(), 0)
+        h.store("meep", "moop")
+        self.assertEqual(h.get_size(), 1)
+
+    def testEquals(self):
+        h = clownfish.Hash()
+        other = clownfish.Hash()
+        h.store("a", "foo")
+        other.store("a", "foo")
+        self.assertTrue(h.equals(other))
+        other.store("b", "bar")
+        self.assertFalse(h.equals(other))
+        self.assertTrue(h.equals({"a":"foo"}),
+                        "equals() true against a Python dict")
+        vec = clownfish.Vector()
+        self.assertFalse(h.equals(vec),
+                         "equals() false against conflicting Clownfish type")
+        self.assertFalse(h.equals(1),
+                         "equals() false against conflicting Python type")
+
+    def testIterator(self):
+        h = clownfish.Hash()
+        h.store("a", "foo")
+        i = clownfish.HashIterator(h)
+        self.assertTrue(i.next())
+        self.assertEqual(i.get_key(), "a")
+        self.assertEqual(i.get_value(), "foo")
+        self.assertFalse(i.next())
+
+if __name__ == '__main__':
+    unittest.main()
+