Use idiomatic Go argument names when possible.

*   Single-letter method receievers.
*   lowerCamelCase for parameters.


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

Branch: refs/heads/master
Commit: 2bf2a05cac2e7eb86ed98dc9c0c359ed4246307c
Parents: 6002adc
Author: Marvin Humphrey <[email protected]>
Authored: Wed Apr 8 15:03:41 2015 -0700
Committer: Marvin Humphrey <[email protected]>
Committed: Wed May 6 14:28:15 2015 -0700

----------------------------------------------------------------------
 compiler/src/CFCGoFunc.c    | 14 +++++--
 compiler/src/CFCGoMethod.c  | 23 +++++++++---
 compiler/src/CFCGoTypeMap.c | 81 ++++++++++++++++++++++++++++++++++++++++
 compiler/src/CFCGoTypeMap.h | 19 ++++++++++
 4 files changed, 127 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2bf2a05c/compiler/src/CFCGoFunc.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCGoFunc.c b/compiler/src/CFCGoFunc.c
index 88a887e..59ac1ed 100644
--- a/compiler/src/CFCGoFunc.c
+++ b/compiler/src/CFCGoFunc.c
@@ -33,6 +33,8 @@
     #define false 0
 #endif
 
+#define GO_NAME_BUF_SIZE 128
+
 char*
 CFCGoFunc_go_meth_name(const char *orig) {
     char *go_name = CFCUtil_strdup(orig);
@@ -50,9 +52,13 @@ CFCGoFunc_func_start(CFCParcel *parcel, const char *name, 
CFCClass *invoker,
                      int is_method) {
     CFCVariable **param_vars = CFCParamList_get_variables(param_list);
     char *invocant;
+    char go_name[GO_NAME_BUF_SIZE];
+
     if (is_method) {
-        invocant = CFCUtil_sprintf("(self *%sIMP) ",
-                                   CFCClass_get_struct_sym(invoker));
+        const char *struct_sym = CFCClass_get_struct_sym(invoker);
+        CFCGoTypeMap_go_meth_receiever(struct_sym, param_list, go_name,
+                                       GO_NAME_BUF_SIZE);
+        invocant = CFCUtil_sprintf("(%s *%sIMP) ", go_name, struct_sym);
     }
     else {
         invocant = CFCUtil_strdup("");
@@ -64,11 +70,11 @@ CFCGoFunc_func_start(CFCParcel *parcel, const char *name, 
CFCClass *invoker,
         CFCVariable *var = param_vars[i];
         CFCType *type = CFCVariable_get_type(var);
         char *go_type_name = CFCGoTypeMap_go_type_name(type, parcel);
+        CFCGoTypeMap_go_arg_name(param_list, i, go_name, GO_NAME_BUF_SIZE);
         if (i > start) {
             params = CFCUtil_cat(params, ", ", NULL);
         }
-        params = CFCUtil_cat(params, CFCVariable_micro_sym(var), " ",
-                             go_type_name, NULL);
+        params = CFCUtil_cat(params, go_name, " ", go_type_name, NULL);
         FREEMEM(go_type_name);
     }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2bf2a05c/compiler/src/CFCGoMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCGoMethod.c b/compiler/src/CFCGoMethod.c
index 05ac230..b15243f 100644
--- a/compiler/src/CFCGoMethod.c
+++ b/compiler/src/CFCGoMethod.c
@@ -104,22 +104,33 @@ CFCGoMethod_iface_sig(CFCGoMethod *self) {
     return sig;
 }
 
+#define GO_NAME_BUF_SIZE 128
+
 static char*
-S_prep_cfargs(CFCParamList *param_list) {
+S_prep_cfargs(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);
-        const char *name = CFCVariable_micro_sym(var);
-        if (i > 0) {
+        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),
-                                 "(", name, ")", NULL);
+                                 "(", go_name, ")", NULL);
         }
         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()))))";
@@ -128,7 +139,7 @@ S_prep_cfargs(CFCParamList *param_list) {
                 obj_pattern = "(*C.%s)(unsafe.Pointer(%s.TOPTR()))";
             }
             char *temp = CFCUtil_sprintf(obj_pattern,
-                                         CFCType_get_specifier(type), name);
+                                         CFCType_get_specifier(type), go_name);
             cfargs = CFCUtil_cat(cfargs, temp, NULL);
             FREEMEM(temp);
         }
@@ -147,7 +158,7 @@ CFCGoMethod_func_def(CFCGoMethod *self, CFCClass *invoker) {
                                             param_list, ret_type, true);
     char *full_meth_sym = CFCMethod_full_method_sym(novel_method, NULL);
 
-    char *cfargs = S_prep_cfargs(param_list);
+    char *cfargs = S_prep_cfargs(invoker, param_list);
 
     char *ret_type_str;
     char *maybe_retval;

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2bf2a05c/compiler/src/CFCGoTypeMap.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCGoTypeMap.c b/compiler/src/CFCGoTypeMap.c
index 516f42b..50aaa32 100644
--- a/compiler/src/CFCGoTypeMap.c
+++ b/compiler/src/CFCGoTypeMap.c
@@ -20,9 +20,16 @@
 
 #include "CFCGoTypeMap.h"
 #include "CFCParcel.h"
+#include "CFCParamList.h"
+#include "CFCVariable.h"
 #include "CFCType.h"
 #include "CFCUtil.h"
 
+#ifndef true
+    #define true 1
+    #define false 0
+#endif
+
 /* Integer types with implementation-specific widths are tricky to convert.
  * If a C `int` and a Go `int` are not the same width, it is potentially
  * dangerous to map between them.  For example, if a function takes a 32-bit C
@@ -144,3 +151,77 @@ CFCGoTypeMap_go_short_package(CFCParcel *parcel) {
     return go_short_package;
 }
 
+
+void
+CFCGoTypeMap_go_meth_receiever(const char *struct_name,
+                               CFCParamList *param_list,
+                               char *buf, size_t buf_len) {
+    size_t max_required = 2;
+    if (param_list != NULL && CFCParamList_num_vars(param_list) > 0) {
+        CFCVariable **vars = CFCParamList_get_variables(param_list);
+        const char *orig = CFCVariable_micro_sym(vars[0]);
+        max_required = strlen(orig) + 1;
+    }
+    if (buf_len < max_required) {
+        CFCUtil_die("Buffer length too short: %d", buf_len);
+    }
+
+    // Find the first letter of the type and lowercase it.
+    for (size_t i = 0, max = strlen(struct_name); i < max; i++) {
+        if (isupper(struct_name[i])) {
+            buf[0] = tolower(struct_name[i]);
+            buf[1] = '\0';
+            break;
+        }
+    }
+
+    // Check for another argument with the same name.
+    if (param_list != NULL) {
+        CFCVariable **vars = CFCParamList_get_variables(param_list);
+        size_t num_vars = CFCParamList_num_vars(param_list);
+        for (int i = 1; i < num_vars; i++) {
+            const char *name = CFCVariable_micro_sym(vars[i]);
+            if (strcmp(name, buf) == 0) {
+                // Bah, a clash.  Use the original name, even though it's
+                // probably "self" which isn't good Go style.
+                CFCGoTypeMap_go_arg_name(param_list, 0, buf, buf_len);
+                break;
+            }
+        }
+    }
+}
+
+void
+CFCGoTypeMap_go_arg_name(CFCParamList *param_list, size_t tick, char *buf,
+                         size_t buf_len) {
+    size_t num_vars = CFCParamList_num_vars(param_list);
+    if (tick >= num_vars) {
+        CFCUtil_die("Index out of range: %d >= %d", (int)tick, (int)num_vars);
+    }
+    CFCVariable **vars = CFCParamList_get_variables(param_list);
+    const char *orig = CFCVariable_micro_sym(vars[tick]);
+    size_t max_required = strlen(orig) + 2;
+    if (buf_len < max_required || buf_len < 5) {
+        CFCUtil_die("Buffer length too short: %d", buf_len);
+    }
+    size_t dest_tick = 0;
+    int last_was_underscore = 0;
+    for (size_t i = 0; i <= strlen(orig); i++) {
+        if (i > buf_len) {
+            CFCUtil_die("Name too long for buffer of size %d: '%s'", buf_len,
+                        orig);
+        }
+        if (orig[i] == '_') {
+            last_was_underscore = 1;
+            continue;
+        }
+        else if (last_was_underscore) {
+            buf[dest_tick] = toupper(orig[i]);
+        }
+        else {
+            buf[dest_tick] = orig[i];
+        }
+        last_was_underscore = 0;
+        dest_tick++;
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2bf2a05c/compiler/src/CFCGoTypeMap.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCGoTypeMap.h b/compiler/src/CFCGoTypeMap.h
index f0b3929..da20c26 100644
--- a/compiler/src/CFCGoTypeMap.h
+++ b/compiler/src/CFCGoTypeMap.h
@@ -23,6 +23,7 @@ extern "C" {
 
 struct CFCType;
 struct CFCParcel;
+struct CFCParamList;
 
 char*
 CFCGoTypeMap_go_type_name(struct CFCType *type,
@@ -33,6 +34,24 @@ CFCGoTypeMap_go_type_name(struct CFCType *type,
 char*
 CFCGoTypeMap_go_short_package(struct CFCParcel *parcel);
 
+/** Convert param names to lowerCamelCase, storing the result in `buf`.
+ */
+void
+CFCGoTypeMap_go_arg_name(struct CFCParamList *param_list, size_t tick,
+                         char *buf, size_t buf_len);
+
+/** For the name of the method receiver, default to lower case letter derived
+ * from type, e.g. `f` for `Foo`.
+ *
+ * `param_list` may be NULL.  If it is not, check to see whether the
+ * single-letter name is already taken by another parameter.  In the event of
+ * a clash, use the result of `CFCGoTypeMap_go_arg_name` instead.
+ */
+void
+CFCGoTypeMap_go_meth_receiever(const char *struct_name,
+                               struct CFCParamList *param_list,
+                               char *buf, size_t buf_len);
+
 #ifdef __cplusplus
 }
 #endif

Reply via email to