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))
