Gen PyTypeObject structs and empty method 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/cd5438b7 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/cd5438b7 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/cd5438b7 Branch: refs/heads/master Commit: cd5438b7e31dab8fdd00cb4da47529fa7e6b3614 Parents: f0048b3 Author: Marvin Humphrey <[email protected]> Authored: Thu Jan 28 18:26:45 2016 -0800 Committer: Marvin Humphrey <[email protected]> Committed: Wed Feb 24 15:20:37 2016 -0800 ---------------------------------------------------------------------- compiler/src/CFCPyClass.c | 94 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/cd5438b7/compiler/src/CFCPyClass.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCPyClass.c b/compiler/src/CFCPyClass.c index e79c2d4..9f46b60 100644 --- a/compiler/src/CFCPyClass.c +++ b/compiler/src/CFCPyClass.c @@ -15,6 +15,7 @@ */ #include <string.h> +#include <ctype.h> #include <stdlib.h> #define CFC_NEED_BASE_STRUCT_DEF 1 @@ -44,6 +45,9 @@ static size_t registry_cap = 0; static void S_CFCPyClass_destroy(CFCPyClass *self); +static char* +S_pytype_struct_def(CFCPyClass *self); + static const CFCMeta CFCPERLCLASS_META = { "Clownfish::CFC::Binding::Python::Class", sizeof(CFCPyClass), @@ -134,5 +138,93 @@ CFCPyClass_clear_registry(void) { char* CFCPyClass_gen_binding_code(CFCPyClass *self) { - return CFCUtil_strdup(""); + if (!self->client) { + CFCUtil_die("No Clownfish class defined for %s", self->class_name); + } + CFCClass *klass = self->client; + char *bindings = CFCUtil_strdup(self->pre_code ? self->pre_code : ""); + char *meth_defs = CFCUtil_strdup(self->meth_defs); + + // Complete the PyMethodDef array. + const char *struct_sym = CFCClass_get_struct_sym(klass); + char *meth_defs_pattern = + "static PyMethodDef %s_pymethods[] = {\n" + "%s" + " {NULL}\n" + "};\n" + ; + char *meth_defs_array = CFCUtil_sprintf(meth_defs_pattern, struct_sym, + meth_defs); + bindings = CFCUtil_cat(bindings, meth_defs_array, NULL); + FREEMEM(meth_defs_array); + FREEMEM(meth_defs); + + // PyTypeObject struct def. + char *struct_def = S_pytype_struct_def(self); + bindings = CFCUtil_cat(bindings, struct_def, NULL); + FREEMEM(struct_def); + + return bindings; +} + +static char* +S_pytype_struct_def(CFCPyClass *self) { + CFCClass *klass = self->client; + const char *parcel_name = CFCParcel_get_name(self->parcel); + char *pymod_name = CFCUtil_strdup(parcel_name); + // TODO: Stop lowercasing when parcels are restricted to lowercase. + for (int i = 0; pymod_name[i] != '\0'; i++) { + pymod_name[i] = tolower(pymod_name[i]); + } + + const char *struct_sym = CFCClass_get_struct_sym(klass); + + char pattern[] = + "static PyTypeObject %s_pytype_struct = {\n" + " PyVarObject_HEAD_INIT(NULL, 0)\n" + " \"%s.%s\", // tp_name\n" + " 0, // tp_basicsize THIS IS A LIE!\n" + " 0, // tp_itemsize\n" + " 0, // tp_dealloc\n" + " 0, // tp_print\n" + " 0, // tp_getattr\n" + " 0, // tp_setattr\n" + " 0, // tp_reserved\n" + " 0, // tp_repr\n" + " 0, // tp_as_number\n" + " 0, // tp_as_sequence\n" + " 0, // tp_as_mapping\n" + " 0, // tp_hash\n" + " 0, // tp_call\n" + " 0, // tp_str\n" + " 0, // tp_getattro\n" + " 0, // tp_setattro\n" + " 0, // tp_as_buffer\n" + " Py_TPFLAGS_DEFAULT, // tp_flags\n" + " 0, // tp_doc\n" + " 0, // tp_traverse\n" + " 0, // tp_clear\n" + " 0, // tp_richcompare\n" + " 0, // tp_weaklistoffset\n" + " 0, // tp_iter\n" + " 0, // tp_iternext\n" + " %s_pymethods, // tp_methods\n" + " 0, // tp_members\n" + " 0, // tp_getset\n" + " 0, // tp_base\n" + " 0, // tp_dict\n" + " 0, // tp_descr_get\n" + " 0, // tp_descr_set\n" + " 0, // tp_dictoffset\n" + " 0, // tp_init\n" + " 0, // tp_allow\n" + " 0, // tp_new\n" + "};\n" + ; + char *content = CFCUtil_sprintf(pattern, struct_sym, pymod_name, + struct_sym, struct_sym); + + FREEMEM(pymod_name); + return content; } +
