Repository: lucy-clownfish
Updated Branches:
  refs/heads/master f26da1edf -> dbb139416


Autogenerate Go type statements for classes.

All non-inert classes get both a public interface type and a public
struct type.


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

Branch: refs/heads/master
Commit: 17dc892b48130001f21f8827aff19f5d97c65abc
Parents: 6ab3378
Author: Marvin Humphrey <[email protected]>
Authored: Sun Mar 29 15:04:53 2015 -0700
Committer: Marvin Humphrey <[email protected]>
Committed: Wed May 6 14:25:26 2015 -0700

----------------------------------------------------------------------
 compiler/src/CFCGo.c              | 52 ++++++++++++++++++++++++-
 compiler/src/CFCGoClass.c         | 69 ++++++++++++++++++++++++++++++++++
 compiler/src/CFCGoClass.h         |  5 +++
 runtime/go/clownfish/clownfish.go | 45 ----------------------
 4 files changed, 124 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/17dc892b/compiler/src/CFCGo.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCGo.c b/compiler/src/CFCGo.c
index fee057f..13ceb63 100644
--- a/compiler/src/CFCGo.c
+++ b/compiler/src/CFCGo.c
@@ -29,6 +29,7 @@
 #include "CFCMethod.h"
 #include "CFCHierarchy.h"
 #include "CFCUtil.h"
+#include "CFCGoClass.h"
 #include "CFCGoTypeMap.h"
 
 static void
@@ -135,6 +136,24 @@ S_gen_h_includes(CFCGo *self) {
     return h_includes;
 }
 
+static void
+S_register_classes(CFCGo *self, CFCParcel *parcel) {
+    CFCClass **ordered = CFCHierarchy_ordered_classes(self->hierarchy);
+    for (size_t i = 0; ordered[i] != NULL; i++) {
+        CFCClass *klass = ordered[i];
+        if (CFCClass_included(klass)
+            || CFCClass_get_parcel(klass) != parcel
+           ) {
+            continue;
+        }
+        const char *class_name = CFCClass_get_class_name(klass);
+        if (!CFCGoClass_singleton(class_name)) {
+            CFCGoClass *binding = CFCGoClass_new(parcel, class_name);
+            CFCGoClass_register(binding);
+        }
+    }
+}
+
 static char*
 S_gen_cgo_comment(CFCGo *self, CFCParcel *parcel, const char *h_includes) {
     const char *prefix = CFCParcel_get_prefix(parcel);
@@ -167,6 +186,30 @@ S_gen_init_code(CFCParcel *parcel) {
     return CFCUtil_sprintf(pattern, prefix);
 }
 
+static char*
+S_gen_autogen_go(CFCGo *self, CFCParcel *parcel) {
+    CFCGoClass **registry = CFCGoClass_registry();
+    char *type_decs = CFCUtil_strdup("");
+
+    for (int i = 0; registry[i] != NULL; i++) {
+        CFCGoClass *class_binding = registry[i];
+
+        char *type_dec = CFCGoClass_go_typing(class_binding);
+        type_decs = CFCUtil_cat(type_decs, type_dec, "\n", NULL);
+        FREEMEM(type_dec);
+    }
+
+    char pattern[] =
+        "// Type declarations.\n"
+        "%s\n"
+        "\n"
+        ;
+    char *content = CFCUtil_sprintf(pattern, type_decs);
+
+    FREEMEM(type_decs);
+    return content;
+}
+
 static void
 S_write_cfbind_go(CFCGo *self, CFCParcel *parcel, const char *dest,
                   const char *h_includes) {
@@ -174,6 +217,7 @@ S_write_cfbind_go(CFCGo *self, CFCParcel *parcel, const 
char *dest,
     char *go_short_package = CFCGoTypeMap_go_short_package(parcel);
     char *cgo_comment   = S_gen_cgo_comment(self, parcel, h_includes);
     char *init_code     = S_gen_init_code(parcel);
+    char *autogen_go    = S_gen_autogen_go(self, parcel);
     const char pattern[] =
         "%s"
         "\n"
@@ -186,6 +230,8 @@ S_write_cfbind_go(CFCGo *self, CFCParcel *parcel, const 
char *dest,
         "\n"
         "%s\n"
         "\n"
+        "%s\n"
+        "\n"
         "//export %sDummyExport\n"
         "func %sDummyExport() int {\n"
         "\treturn 1\n"
@@ -193,14 +239,15 @@ S_write_cfbind_go(CFCGo *self, CFCParcel *parcel, const 
char *dest,
         "%s";
     char *content
         = CFCUtil_sprintf(pattern, self->c_header, go_short_package,
-                          cgo_comment, init_code, PREFIX, PREFIX,
-                          self->c_footer);
+                          cgo_comment, init_code, autogen_go,
+                          PREFIX, PREFIX, self->c_footer);
 
     char *filepath = CFCUtil_sprintf("%s" CHY_DIR_SEP "cfbind.go", dest);
     CFCUtil_write_if_changed(filepath, content, strlen(content));
 
     FREEMEM(filepath);
     FREEMEM(content);
+    FREEMEM(autogen_go);
     FREEMEM(init_code);
     FREEMEM(cgo_comment);
     FREEMEM(go_short_package);
@@ -210,6 +257,7 @@ void
 CFCGo_write_bindings(CFCGo *self, CFCParcel *parcel, const char *dest) {
     char *h_includes = S_gen_h_includes(self);
 
+    S_register_classes(self, parcel);
     S_write_hostdefs(self);
     S_write_cfbind_go(self, parcel, dest, h_includes);
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/17dc892b/compiler/src/CFCGoClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCGoClass.c b/compiler/src/CFCGoClass.c
index e766f3f..7793959 100644
--- a/compiler/src/CFCGoClass.c
+++ b/compiler/src/CFCGoClass.c
@@ -131,3 +131,72 @@ CFCGoClass_clear_registry(void) {
     registry      = NULL;
 }
 
+char*
+CFCGoClass_go_typing(CFCGoClass *self) {
+    char *content = NULL;
+    if (!self->client) {
+        CFCUtil_die("Can't find class for %s", self->class_name);
+    }
+    else if (CFCClass_inert(self->client)) {
+        content = CFCUtil_strdup("");
+    } else {
+        const char *short_struct = CFCClass_get_struct_sym(self->client);
+        const char *full_struct  = CFCClass_full_struct_sym(self->client);
+
+        CFCClass *parent = CFCClass_get_parent(self->client);
+        char *parent_iface;
+        char *go_struct_def;
+        if (parent) {
+            const char *parent_struct = CFCClass_get_struct_sym(parent);
+            CFCParcel *parent_parcel = CFCClass_get_parcel(parent);
+            char *parent_type_str;
+            if (parent_parcel == self->parcel) {
+                parent_type_str = CFCUtil_strdup(parent_struct);
+            }
+            else {
+                char *parent_package
+                    = CFCGoTypeMap_go_short_package(parent_parcel);
+                parent_type_str = CFCUtil_sprintf("%s.%s", parent_package,
+                                                  parent_struct);
+                FREEMEM(parent_package);
+            }
+            parent_iface = CFCUtil_sprintf("\t%s\n", parent_type_str);
+            go_struct_def
+                = CFCUtil_sprintf("type %sIMP struct {\n\t%sIMP\n}\n",
+                                  short_struct, parent_type_str);
+            FREEMEM(parent_type_str);
+        }
+        else {
+            parent_iface = CFCUtil_strdup("");
+            go_struct_def = CFCUtil_strdup("");
+        }
+
+        // Temporary hack until it's possible to customize interfaces.
+        char *temp_hack_iface_methods;
+        if (strcmp(self->class_name, "Clownfish::Obj") == 0) {
+            temp_hack_iface_methods = CFCUtil_strdup("\tTOPTR() uintptr\n");
+        }
+        else if (strcmp(self->class_name, "Clownfish::Err") == 0) {
+            temp_hack_iface_methods = CFCUtil_strdup("\tError() string\n");
+        }
+        else {
+            temp_hack_iface_methods = CFCUtil_strdup("");
+        }
+
+        char pattern[] =
+            "type %s interface {\n"
+            "%s"
+            "%s"
+            "}\n"
+            "\n"
+            "%s"
+            ;
+        content = CFCUtil_sprintf(pattern, short_struct, parent_iface,
+                                  temp_hack_iface_methods, go_struct_def);
+        FREEMEM(temp_hack_iface_methods);
+        FREEMEM(go_struct_def);
+        FREEMEM(parent_iface);
+    }
+    return content;
+}
+

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/17dc892b/compiler/src/CFCGoClass.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCGoClass.h b/compiler/src/CFCGoClass.h
index d381b62..6693091 100644
--- a/compiler/src/CFCGoClass.h
+++ b/compiler/src/CFCGoClass.h
@@ -57,6 +57,11 @@ CFCGoClass_registry();
 void
 CFCGoClass_clear_registry(void);
 
+/** Return any Go type statements describing the Clownfish class.
+ */
+char*
+CFCGoClass_go_typing(CFCGoClass *self);
+
 #ifdef __cplusplus
 }
 #endif

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/17dc892b/runtime/go/clownfish/clownfish.go
----------------------------------------------------------------------
diff --git a/runtime/go/clownfish/clownfish.go 
b/runtime/go/clownfish/clownfish.go
index d4b61e7..12e625a 100644
--- a/runtime/go/clownfish/clownfish.go
+++ b/runtime/go/clownfish/clownfish.go
@@ -68,55 +68,10 @@ func init() {
        C.cfish_bootstrap_parcel()
 }
 
-type Obj interface {
-       TOPTR() uintptr
-}
-
 type ObjIMP struct {
        ref uintptr
 }
 
-type Err interface {
-       Obj
-       Error() string
-}
-
-type ErrIMP struct {
-       ObjIMP
-}
-
-type String interface {
-       Obj
-}
-
-type StringIMP struct {
-       ObjIMP
-}
-
-type ByteBufIMP struct {
-       ObjIMP
-}
-
-type HashIMP struct {
-       ObjIMP
-}
-
-type VectorIMP struct {
-       ObjIMP
-}
-
-type ClassIMP struct {
-       ObjIMP
-}
-
-type MethodIMP struct {
-       ObjIMP
-}
-
-type LockFreeRegistryIMP struct {
-       ObjIMP
-}
-
 func NewString(goString string) String {
        str := C.CString(goString)
        len := C.size_t(len(goString))

Reply via email to