lucy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mar...@apache.org
Subject [3/9] lucy-clownfish git commit: Add CFC module for Go/C type mapping.
Date Tue, 07 Apr 2015 00:03:48 GMT
Add CFC module for Go/C type mapping.


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

Branch: refs/heads/master
Commit: fcf9dcfb0c746262c0e62e9d0e47a862d1268d74
Parents: cbd99b0
Author: Marvin Humphrey <marvin@rectangular.com>
Authored: Wed Dec 3 20:56:52 2014 -0800
Committer: Marvin Humphrey <marvin@rectangular.com>
Committed: Mon Apr 6 09:08:19 2015 -0700

----------------------------------------------------------------------
 compiler/src/CFCGoTypeMap.c | 126 +++++++++++++++++++++++++++++++++++++++
 compiler/src/CFCGoTypeMap.h |  36 +++++++++++
 2 files changed, 162 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/fcf9dcfb/compiler/src/CFCGoTypeMap.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCGoTypeMap.c b/compiler/src/CFCGoTypeMap.c
new file mode 100644
index 0000000..f5b689f
--- /dev/null
+++ b/compiler/src/CFCGoTypeMap.c
@@ -0,0 +1,126 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#include "CFCGoTypeMap.h"
+#include "CFCParcel.h"
+#include "CFCType.h"
+#include "CFCUtil.h"
+
+/* 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
+ * `int` and we wrap that in a Go function which takes a 64-bit Go `int`, a
+ * user who sees the Go function signature will being misled about the range
+ * of valid input.
+ *
+ * Therefore, we take a mostly conservative approach and err on the side of
+ * artificially limiting the range.
+ */
+static struct {
+    const char *c;
+    const char *go;
+} conversions[] = {
+    {"bool",     "bool"},
+    {"char",     "int8"},
+    {"short",    "int16"},
+    {"int",      "int32"},
+    {"long",     "int32"},
+    {"size_t",   "uintptr"},
+    {"int8_t",   "int8"},
+    {"int16_t",  "int16"},
+    {"int32_t",  "int32"},
+    {"int64_t",  "int64"},
+    {"uint8_t",  "uint8"},
+    {"uint16_t", "uint16"},
+    {"uint32_t", "uint32"},
+    {"uint64_t", "uint64"},
+    {"float",    "float32"},
+    {"double",   "float64"},
+};
+
+static int num_conversions = sizeof(conversions) / sizeof(conversions[0]);
+
+/* TODO: Optimize local conversions by creating a static wrapper function
+ * which takes a buffer and allocates memory only if the buffer isn't big
+ * enough. */
+
+char*
+CFCGoTypeMap_go_type_name(CFCType *type, CFCParcel *current_parcel) {
+    if (CFCType_is_object(type)) {
+        // Divide the specifier into prefix and struct name.
+        const char *specifier  = CFCType_get_specifier(type);
+        size_t      prefix_len = 0;
+        for (size_t max = strlen(specifier); prefix_len < max; prefix_len++) {
+            if (isupper(specifier[prefix_len])) {
+                break;
+            }
+        }
+        if (!prefix_len) {
+            CFCUtil_die("Can't convert object type name '%s'", specifier);
+        }
+        const char *struct_sym = specifier + prefix_len;
+
+        // Find the parcel that the type lives in.
+        CFCParcel** all_parcels = CFCParcel_all_parcels();
+        CFCParcel *parcel = NULL;
+        for (int i = 0; all_parcels[i] != NULL; i++) {
+            const char *candidate = CFCParcel_get_prefix(all_parcels[i]);
+            if (strncmp(candidate, specifier, prefix_len) == 0
+                && strlen(candidate) == prefix_len
+               ) {
+                parcel = all_parcels[i];
+                break;
+            }
+        }
+        if (!parcel) {
+            CFCUtil_die("Can't find parcel for type '%s'", specifier);
+        }
+
+        // If the type lives in this parcel, return only the struct sym
+        // without a go package prefix.
+        if (parcel == current_parcel) {
+            return CFCUtil_strdup(struct_sym);
+        }
+
+        // The type lives in another parcel, so prefix its Go package name.
+        // TODO: Stop downcasing once Clownfish parcel names are constrained
+        // to lower case.
+        const char *package_name = CFCParcel_get_name(parcel);
+        if (strrchr(package_name, '.')) {
+            package_name = strrchr(package_name, '.') + 1;
+        }
+        char *result = CFCUtil_sprintf("%s.%s", package_name, struct_sym);
+        for (int i = 0; result[i] != '.'; i++) {
+            result[i] = tolower(result[i]);
+        }
+        return result;
+    }
+    else if (CFCType_is_primitive(type)) {
+        const char *specifier = CFCType_get_specifier(type);
+        for (int i = 0; i < num_conversions; i++) {
+            if (strcmp(specifier, conversions[i].c) == 0) {
+                return CFCUtil_strdup(conversions[i].go);
+            }
+        }
+    }
+
+    return NULL;
+}
+

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/fcf9dcfb/compiler/src/CFCGoTypeMap.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCGoTypeMap.h b/compiler/src/CFCGoTypeMap.h
new file mode 100644
index 0000000..3af6137
--- /dev/null
+++ b/compiler/src/CFCGoTypeMap.h
@@ -0,0 +1,36 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef H_CFCGOTYPEMAP
+#define H_CFCGOTYPEMAP
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct CFCType;
+struct CFCParcel;
+
+char*
+CFCGoTypeMap_go_type_name(struct CFCType *type,
+                          struct CFCParcel *current_parcel);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* H_CFCGOTYPEMAP */
+


Mime
View raw message