lucy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nwelln...@apache.org
Subject [lucy-commits] [07/10] git commit: Only search prerequisites for unqualified type specifiers
Date Mon, 17 Mar 2014 17:27:54 GMT
Only search prerequisites for unqualified type specifiers

Don't search all classes for unqualified type specifiers. This should
allow to have classes with the same struct_sym in different parcels.


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

Branch: refs/heads/explicit-dependencies-wip2
Commit: 5bdf3139d5249eeff4c21bd729d487eabebab76e
Parents: 170f5f9
Author: Nick Wellnhofer <wellnhofer@aevum.de>
Authored: Wed Mar 12 15:54:56 2014 +0100
Committer: Nick Wellnhofer <wellnhofer@aevum.de>
Committed: Mon Mar 17 18:25:30 2014 +0100

----------------------------------------------------------------------
 compiler/src/CFCClass.c      |  2 ++
 compiler/src/CFCParcel.c     | 51 +++++++++++++++++++++++++++++++++++++++
 compiler/src/CFCParcel.h     |  9 +++++++
 compiler/src/CFCTestClass.c  |  1 +
 compiler/src/CFCTestParcel.c | 13 +++++++++-
 compiler/src/CFCType.c       | 20 +++------------
 6 files changed, 79 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5bdf3139/compiler/src/CFCClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCClass.c b/compiler/src/CFCClass.c
index 61a9d42..38d1c28 100644
--- a/compiler/src/CFCClass.c
+++ b/compiler/src/CFCClass.c
@@ -202,6 +202,8 @@ CFCClass_do_create(CFCClass *self, struct CFCParcel *parcel,
     // Store in registry.
     S_register(self);
 
+    CFCParcel_add_struct_sym(parcel, self->struct_sym);
+
     return self;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5bdf3139/compiler/src/CFCParcel.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCParcel.c b/compiler/src/CFCParcel.c
index e53ff01..84b95a8 100644
--- a/compiler/src/CFCParcel.c
+++ b/compiler/src/CFCParcel.c
@@ -42,6 +42,8 @@ struct CFCParcel {
     int is_required;
     char **inherited_parcels;
     size_t num_inherited_parcels;
+    char **struct_syms;
+    size_t num_struct_syms;
     CFCPrereq **prereqs;
     size_t num_prereqs;
 };
@@ -253,6 +255,8 @@ CFCParcel_init(CFCParcel *self, const char *name, const char *cnick,
     // Initialize arrays.
     self->inherited_parcels = (char**)CALLOCATE(1, sizeof(char*));
     self->num_inherited_parcels = 0;
+    self->struct_syms = (char**)CALLOCATE(1, sizeof(char*));
+    self->num_struct_syms = 0;
     self->prereqs = (CFCPrereq**)CALLOCATE(1, sizeof(CFCPrereq*));
     self->num_prereqs = 0;
 
@@ -391,6 +395,10 @@ CFCParcel_destroy(CFCParcel *self) {
         CFCBase_decref((CFCBase*)self->prereqs[i]);
     }
     FREEMEM(self->prereqs);
+    for (size_t i = 0; self->struct_syms[i]; ++i) {
+        FREEMEM(self->struct_syms[i]);
+    }
+    FREEMEM(self->struct_syms);
     CFCBase_destroy((CFCBase*)self);
 }
 
@@ -562,6 +570,49 @@ CFCParcel_has_prereq(CFCParcel *self, CFCParcel *parcel) {
     return false;
 }
 
+void
+CFCParcel_add_struct_sym(CFCParcel *self, const char *struct_sym) {
+    size_t num_struct_syms = self->num_struct_syms + 1;
+    size_t size = (num_struct_syms + 1) * sizeof(char*);
+    char **struct_syms = (char**)REALLOCATE(self->struct_syms, size);
+    struct_syms[num_struct_syms-1] = CFCUtil_strdup(struct_sym);
+    struct_syms[num_struct_syms]   = NULL;
+    self->struct_syms     = struct_syms;
+    self->num_struct_syms = num_struct_syms;
+}
+
+static CFCParcel*
+S_lookup_struct_sym(CFCParcel *self, const char *struct_sym) {
+    for (size_t i = 0; self->struct_syms[i]; ++i) {
+        if (strcmp(self->struct_syms[i], struct_sym) == 0) {
+            return self;
+        }
+    }
+
+    return NULL;
+}
+
+CFCParcel*
+CFCParcel_lookup_struct_sym(CFCParcel *self, const char *struct_sym) {
+    CFCParcel *parcel = S_lookup_struct_sym(self, struct_sym);
+
+    for (size_t i = 0; self->prereqs[i]; ++i) {
+        const char *prereq_name   = CFCPrereq_get_name(self->prereqs[i]);
+        CFCParcel  *prereq_parcel = CFCParcel_fetch(prereq_name);
+        CFCParcel *maybe_parcel
+            = S_lookup_struct_sym(prereq_parcel, struct_sym);
+
+        if (maybe_parcel) {
+            if (parcel) {
+                CFCUtil_die("Type '%s' is ambigious", struct_sym);
+            }
+            parcel = maybe_parcel;
+        }
+    }
+
+    return parcel;
+}
+
 /**************************************************************************/
 
 struct CFCPrereq {

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5bdf3139/compiler/src/CFCParcel.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCParcel.h b/compiler/src/CFCParcel.h
index 4efbdd9..4bd822d 100644
--- a/compiler/src/CFCParcel.h
+++ b/compiler/src/CFCParcel.h
@@ -161,6 +161,15 @@ CFCParcel_check_prereqs(CFCParcel *self);
 int
 CFCParcel_has_prereq(CFCParcel *self, CFCParcel *parcel);
 
+void
+CFCParcel_add_struct_sym(CFCParcel *self, const char *struct_sym);
+
+/** Search the parcel and all direct prerequisites for a class with
+ * struct_sym. Return the parcel in which the class was found or NULL.
+ */
+CFCParcel*
+CFCParcel_lookup_struct_sym(CFCParcel *self, const char *struct_sym);
+
 /**************************************************************************/
 
 CFCPrereq*

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5bdf3139/compiler/src/CFCTestClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCTestClass.c b/compiler/src/CFCTestClass.c
index e33d454..36bd4ee 100644
--- a/compiler/src/CFCTestClass.c
+++ b/compiler/src/CFCTestClass.c
@@ -120,6 +120,7 @@ S_run_tests(CFCTest *test) {
         CFCBase_decref((CFCBase*)parsed_neato);
     }
 
+    CFCParser_set_parcel(parser, neato);
     CFCParser_set_class_name(parser, "Foo");
     CFCMethod *do_stuff
         = CFCTest_parse_method(test, parser, "void Do_Stuff(Foo *self);");

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5bdf3139/compiler/src/CFCTestParcel.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCTestParcel.c b/compiler/src/CFCTestParcel.c
index c8fb528..504f2a7 100644
--- a/compiler/src/CFCTestParcel.c
+++ b/compiler/src/CFCTestParcel.c
@@ -40,7 +40,7 @@ S_run_parcel_tests(CFCTest *test);
 
 const CFCTestBatch CFCTEST_BATCH_PARCEL = {
     "Clownfish::CFC::Model::Parcel",
-    32,
+    35,
     S_run_tests
 };
 
@@ -215,6 +215,17 @@ S_run_parcel_tests(CFCTest *test) {
         OK(test, CFCParcel_has_prereq(crust, crust), "has_prereq self");
         OK(test, !CFCParcel_has_prereq(crust, foo), "has_prereq false");
 
+        CFCParcel_add_struct_sym(cfish, "Swim");
+        CFCParcel_add_struct_sym(crust, "Pinch");
+        CFCParcel_add_struct_sym(foo, "Bar");
+        CFCParcel *found;
+        found = CFCParcel_lookup_struct_sym(crust, "Swim");
+        OK(test, found == cfish, "lookup_struct_sym prereq");
+        found = CFCParcel_lookup_struct_sym(crust, "Pinch");
+        OK(test, found == crust, "lookup_struct_sym self");
+        found = CFCParcel_lookup_struct_sym(crust, "Bar");
+        OK(test, found == NULL, "lookup_struct_sym other");
+
         FREEMEM(prereq_parcels);
         CFCBase_decref((CFCBase*)crust);
         CFCBase_decref((CFCBase*)cfish_version);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5bdf3139/compiler/src/CFCType.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCType.c b/compiler/src/CFCType.c
index 3ff7db7..974f33a 100644
--- a/compiler/src/CFCType.c
+++ b/compiler/src/CFCType.c
@@ -273,26 +273,14 @@ CFCType_resolve(CFCType *self, CFCClass **classes) {
 
     char *specifier = self->specifier;
     if (isupper(specifier[0])) {
-        // Try to find class from class list.
-        CFCClass *klass = NULL;
-        for (size_t i = 0; classes[i]; ++i) {
-            CFCClass   *maybe_class = classes[i];
-            const char *struct_sym  = CFCClass_get_struct_sym(maybe_class);
-
-            if (strcmp(specifier, struct_sym) == 0) {
-                if (klass) {
-                    CFCUtil_die("Type '%s' is ambigious", specifier);
-                }
-                klass = maybe_class;
-            }
-        }
-
-        if (!klass) {
+        CFCParcel *parcel
+            = CFCParcel_lookup_struct_sym(self->parcel, specifier);
+        if (!parcel) {
             CFCUtil_die("No class found for type '%s'", specifier);
         }
 
         // Create actual specifier with prefix.
-        const char *prefix = CFCClass_get_prefix(klass);
+        const char *prefix = CFCParcel_get_prefix(parcel);
         self->specifier = CFCUtil_sprintf("%s%s", prefix, specifier);
         FREEMEM(specifier);
     }


Mime
View raw message