Generalize Go-to-cfish arg list prep. Make the functionality which converts Go argument lists to Clownfish-flavored-C argument lists more widely available.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/d09f15a3 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/d09f15a3 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/d09f15a3 Branch: refs/heads/master Commit: d09f15a3ca5547726f0c242d9f5c6a8e73e88b61 Parents: 024c815 Author: Marvin Humphrey <[email protected]> Authored: Mon Jul 13 17:21:14 2015 -0700 Committer: Marvin Humphrey <[email protected]> Committed: Mon Jul 20 13:40:36 2015 -0700 ---------------------------------------------------------------------- compiler/src/CFCGoFunc.c | 72 +++++++++++++++++++++++++++++++++++++++++ compiler/src/CFCGoFunc.h | 7 ++++ compiler/src/CFCGoMethod.c | 59 +-------------------------------- 3 files changed, 80 insertions(+), 58 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d09f15a3/compiler/src/CFCGoFunc.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCGoFunc.c b/compiler/src/CFCGoFunc.c index 3138605..ad74bde 100644 --- a/compiler/src/CFCGoFunc.c +++ b/compiler/src/CFCGoFunc.c @@ -35,6 +35,12 @@ #define GO_NAME_BUF_SIZE 128 +enum { + IS_METHOD = 1, + IS_FUNC = 2, + IS_CTOR = 3 +}; + char* CFCGoFunc_go_meth_name(const char *orig) { char *go_name = CFCUtil_strdup(orig); @@ -101,6 +107,72 @@ CFCGoFunc_func_start(CFCParcel *parcel, const char *name, CFCClass *invoker, return content; } +static char* +S_prep_cfargs(CFCParcel *parcel, CFCClass *invoker, + CFCParamList *param_list, int targ) { + CFCVariable **vars = CFCParamList_get_variables(param_list); + char go_name[GO_NAME_BUF_SIZE]; + char *cfargs = CFCUtil_strdup(""); + + for (int i = 0; vars[i] != NULL; i++) { + CFCVariable *var = vars[i]; + CFCType *type = CFCVariable_get_type(var); + if (targ == IS_METHOD && i == 0) { + CFCGoTypeMap_go_meth_receiever(CFCClass_get_struct_sym(invoker), + param_list, go_name, + GO_NAME_BUF_SIZE); + } + else { + CFCGoTypeMap_go_arg_name(param_list, i, go_name, GO_NAME_BUF_SIZE); + } + + if (i > 0) { + cfargs = CFCUtil_cat(cfargs, ", ", NULL); + } + + if (CFCType_is_primitive(type)) { + cfargs = CFCUtil_cat(cfargs, "C.", CFCType_get_specifier(type), + "(", go_name, ")", NULL); + } + else if (CFCType_is_string_type(type) + // Don't convert a clownfish.String invocant. + && (targ != IS_METHOD || i != 0) + ) { + const char *format; + if (CFCParcel_is_cfish(parcel)) { + format = "%s((*C.cfish_String)(unsafe.Pointer(NewString(%s).TOPTR())))"; + } + else { + format = "%s((*C.cfish_String)(unsafe.Pointer(clownfish.NewString(%s).TOPTR())))"; + } + char *temp = CFCUtil_sprintf(format, cfargs, go_name); + FREEMEM(cfargs); + cfargs = temp; + } + else if (CFCType_is_object(type)) { + + char *obj_pattern; + if (CFCType_decremented(type)) { + obj_pattern = "(*C.%s)(unsafe.Pointer(C.cfish_inc_refcount(unsafe.Pointer(%s.TOPTR()))))"; + } + else { + obj_pattern = "(*C.%s)(unsafe.Pointer(%s.TOPTR()))"; + } + char *temp = CFCUtil_sprintf(obj_pattern, + CFCType_get_specifier(type), go_name); + cfargs = CFCUtil_cat(cfargs, temp, NULL); + FREEMEM(temp); + } + } + return cfargs; +} + +char* +CFCGoFunc_meth_cfargs(CFCParcel *parcel, CFCClass *invoker, + CFCParamList *param_list) { + return S_prep_cfargs(parcel, invoker, param_list, IS_METHOD); +} + char* CFCGoFunc_return_statement(CFCParcel *parcel, CFCType *return_type, const char *cf_retval) { http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d09f15a3/compiler/src/CFCGoFunc.h ---------------------------------------------------------------------- diff --git a/compiler/src/CFCGoFunc.h b/compiler/src/CFCGoFunc.h index 213b550..e11fa0d 100644 --- a/compiler/src/CFCGoFunc.h +++ b/compiler/src/CFCGoFunc.h @@ -37,6 +37,13 @@ CFCGoFunc_func_start(struct CFCParcel *parcel, const char *name, struct CFCParamList *param_list, struct CFCType *return_type, int is_method); +/** Convert Go method arguments to comma-separated Clownfish-flavored C + * arguments, to be passed to a Clownfish method. + */ +char* +CFCGoFunc_meth_cfargs(struct CFCParcel *parcel, struct CFCClass *invoker, + struct CFCParamList *param_list); + /** Generate a Go return statement which maps from a CGO Clownfish type to a * Go type. * http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d09f15a3/compiler/src/CFCGoMethod.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCGoMethod.c b/compiler/src/CFCGoMethod.c index b095347..f5b7cb4 100644 --- a/compiler/src/CFCGoMethod.c +++ b/compiler/src/CFCGoMethod.c @@ -133,63 +133,6 @@ CFCGoMethod_get_sig(CFCGoMethod *self, CFCClass *invoker) { } } -#define GO_NAME_BUF_SIZE 128 - -static char* -S_prep_cfargs(CFCParcel *parcel, CFCClass *invoker, - CFCParamList *param_list) { - CFCVariable **vars = CFCParamList_get_variables(param_list); - char go_name[GO_NAME_BUF_SIZE]; - char *cfargs = CFCUtil_strdup(""); - - for (int i = 0; vars[i] != NULL; i++) { - CFCVariable *var = vars[i]; - CFCType *type = CFCVariable_get_type(var); - if (i == 0) { - CFCGoTypeMap_go_meth_receiever(CFCClass_get_struct_sym(invoker), - param_list, go_name, - GO_NAME_BUF_SIZE); - } - else { - cfargs = CFCUtil_cat(cfargs, ", ", NULL); - CFCGoTypeMap_go_arg_name(param_list, i, go_name, GO_NAME_BUF_SIZE); - } - - if (CFCType_is_primitive(type)) { - cfargs = CFCUtil_cat(cfargs, "C.", CFCType_get_specifier(type), - "(", go_name, ")", NULL); - } - else if (CFCType_is_string_type(type) - && i != 0) { // Don't convert a clownfish.String invocant. - const char *format; - if (CFCParcel_is_cfish(parcel)) { - format = "%s((*C.cfish_String)(unsafe.Pointer(NewString(%s).TOPTR())))"; - } - else { - format = "%s((*C.cfish_String)(unsafe.Pointer(clownfish.NewString(%s).TOPTR())))"; - } - char *temp = CFCUtil_sprintf(format, cfargs, go_name); - FREEMEM(cfargs); - cfargs = temp; - } - else if (CFCType_is_object(type)) { - - char *obj_pattern; - if (CFCType_decremented(type)) { - obj_pattern = "(*C.%s)(unsafe.Pointer(C.cfish_inc_refcount(unsafe.Pointer(%s.TOPTR()))))"; - } - else { - obj_pattern = "(*C.%s)(unsafe.Pointer(%s.TOPTR()))"; - } - char *temp = CFCUtil_sprintf(obj_pattern, - CFCType_get_specifier(type), go_name); - cfargs = CFCUtil_cat(cfargs, temp, NULL); - FREEMEM(temp); - } - } - return cfargs; -} - char* CFCGoMethod_func_def(CFCGoMethod *self, CFCClass *invoker) { if (!self->method || CFCMethod_excluded_from_host(self->method)) { @@ -211,7 +154,7 @@ CFCGoMethod_func_def(CFCGoMethod *self, CFCClass *invoker) { cfunc = CFCMethod_full_method_sym(novel_method, invoker); } - char *cfargs = S_prep_cfargs(parcel, invoker, param_list); + char *cfargs = CFCGoFunc_meth_cfargs(parcel, invoker, param_list); char *maybe_retval; char *maybe_return;
