[SCM] Lisaac compiler branch, master+stable, updated. lisaac-0.12-606-gf445725

Mildred Ki'Lya silkensedai at online.fr
Mon Mar 1 00:36:00 UTC 2010


The following commit has been merged in the master+stable branch:
commit 5bbefca1d558f6272bdd33ebde4e2883723c9710
Author: Mildred Ki'Lya <silkensedai at online.fr>
Date:   Fri Oct 9 19:35:25 2009 +0200

    Choose intelligently the prototype name to avoid conflicts
    
    Because of the DIR.PROTO notation, it is possible to have two prototypes
    with the same shortname while their longname are different. This patch
    makes PROTOTYPE.name intelligent to be unique among all prototypes. The
    drawback is that the prototype name can change to include directories if
    another PROTOTYPE is added and have a conflicting name.
    
    But the error mesages will show exactly which prototype is concerned
    (provided the conflicting prototypes are all used).

diff --git a/src/any.li b/src/any.li
index 8200398..8454b40 100644
--- a/src/any.li
+++ b/src/any.li
@@ -465,3 +465,11 @@ Section Public
     LIP_CODE.put_string path_lisaac to (ALIAS_STR.variable_lisaac);
   );
 
+  //
+  // Activate debug
+  //
+
+  - debug_proto_bestname :BOOLEAN <- FALSE;
+  // Debug the name of the prototypes choosen to avoid conflicts
+  // See PROTOTYPE.insert_prototype
+
diff --git a/src/type/prototype.li b/src/type/prototype.li
index 2a870fe..b321348 100644
--- a/src/type/prototype.li
+++ b/src/type/prototype.li
@@ -40,6 +40,10 @@ Section Public
 
   - prototype_dico:HASHED_DICTIONARY(PROTOTYPE,STRING_CONSTANT) :=
   HASHED_DICTIONARY(PROTOTYPE,STRING_CONSTANT).create;
+  // Index by filename
+
+  - prototype_canonical_name:HASHED_DICTIONARY(PROTOTYPE,STRING_CONSTANT) :=
+  HASHED_DICTIONARY(PROTOTYPE,STRING_CONSTANT).create;
 
 Section Public
 
@@ -47,6 +51,10 @@ Section Public
 
   + shortname:STRING_CONSTANT;
 
+  + longname:STRING_CONSTANT;
+
+  - is_lip :BOOLEAN <- (filename.last = 'p');
+
   //
   // Slots
   //
@@ -209,14 +217,17 @@ Section Public
   );
 
   - make f:STRING_CONSTANT name n:STRING_CONSTANT generic_count c:INTEGER <-
+  [
+    -? {! prototype_dico.fast_has f};
+    -? {n != NULL};
+  ]
   ( //+ file:FILE;
     //+ entry:ENTRY;
     + file:POINTER;
     + sz,idx:INTEGER;
-    ? {! prototype_dico.fast_has n};
-    ? {n != NULL};
 
     filename := f;
+    longname := protopath_from_path filename;
     name     := n;
     idx := n.fast_last_index_of '.';
     (idx != 0).if {
@@ -229,6 +240,10 @@ Section Public
     generic_count := c;
     idf_generic_list := FAST_ARRAY(ITM_TYPE_PARAMETER).create_with_capacity c;
 
+    is_lip.if_false {
+      insert_prototype;
+    };
+
     // Collection.
     index := prototype_list.count;
     prototype_list.add_last Self;
@@ -800,4 +815,124 @@ Section PROTOTYPE
         put str_tmp to buf like code_balise;
       };
     };
-  );
\ No newline at end of file
+  );
+
+Section Private
+
+  - protopath_from_path filename:ABSTRACT_STRING :STRING_CONSTANT <-
+  ( + strip_end :INTEGER;
+    is_lip.if {
+      // *.lip
+      strip_end := 4;
+    } else {
+      // *.li
+      strip_end := 3;
+    };
+
+    string_tmp.clear;
+    (filename.lower).to (filename.count - strip_end) do { i:INTEGER;
+      + c:CHARACTER;
+      c := filename.item i.to_upper;
+      c.is_upper.if {
+        string_tmp.add_last c;
+      }.elseif {c.is_digit} then {
+        string_tmp.add_last c;
+      }.elseif {c = '/'} then {
+        ((string_tmp.count >= 1) && {string_tmp.last != '.'}).if {
+          string_tmp.add_last '.';
+        };
+      } else {
+        ((string_tmp.count >= 1) && {string_tmp.last != '_'} && {string_tmp.last != '.'}).if {
+          string_tmp.add_last '_';
+        };
+      };
+    };
+    ALIAS_STR.get string_tmp
+  );
+
+  - name_last n:INTEGER :STRING_CONSTANT <-
+  [
+    -? { n > 0 };
+  ]
+  ( + j, idx :INTEGER;
+    j := 0;
+
+    idx := longname.upper;
+    {(idx >= longname.lower) && {j < n}}.while_do {
+      (longname.item idx = '.').if {
+        j := j + 1;
+      };
+      idx := idx - 1;
+    };
+    // idx contains the position of the n-th '.' from the right
+    idx := idx + 1;
+    (longname.item idx = '.').if {
+      idx := idx + 1;
+    };
+    // idx contains the position of first desired character
+
+    // Copy last n members to string_tmp
+    string_tmp.clear;
+    idx.to (longname.upper) do { k:INTEGER;
+      string_tmp.add_last (longname.item k);
+    };
+    ALIAS_STR.get string_tmp
+  )
+  [
+    +? { Result != NULL };
+    +? { (n != 1) | (Result = shortname) };
+  ];
+
+  - insert_prototype <- insert_prototype_start 1;
+
+  - insert_prototype_start start:INTEGER <-
+  ( + i:INTEGER;
+    + proto:PROTOTYPE;
+
+    // Find canonical name
+    // If we find PROTOTYPE in the dictionary, it's a marker to notify that more
+    // than one prototype matches the name. We can't take the slot and we must
+    // add more members to `name'
+    i := start;
+    (i = 1).if {
+      name := shortname;
+    } else {
+      name := name_last i;
+    };
+    proto := prototype_canonical_name.fast_reference_at name;
+    { proto = PROTOTYPE }.while_do {
+      i := i + 1;
+      name  := name_last i;
+      proto := prototype_canonical_name.fast_reference_at name;
+    };
+
+    // We find either an empty slot or a conflicting prototype
+
+    (proto = NULL).if {
+
+      ((debug_proto_bestname) && {i > 1}).if {
+        "Prototype: ".print; name.println;
+        "       is: ".print; longname.println;
+      };
+
+      prototype_canonical_name.fast_put Self to name;
+
+    } else {
+
+      // We find a conflicting prototype.
+      ? { proto != Self };
+
+      (debug_proto_bestname).if {
+        "Conflict: ".print; name.println;
+        "          ".print; longname.println;
+        "          ".print; proto.longname.println;
+      };
+
+      // Add PROTOTYPE marker and add more members to `name' of both prototypes
+      prototype_canonical_name.fast_put PROTOTYPE to name;
+      // Insert both prototypes again with another member to the name
+      i := i + 1;
+      proto.insert_prototype_start i;
+      insert_prototype_start i;
+    };
+  );
diff --git a/tests/ambiguous_protoname/main.li b/tests/ambiguous_protoname/main.li
index 4d7edd3..9157014 100644
--- a/tests/ambiguous_protoname/main.li
+++ b/tests/ambiguous_protoname/main.li
@@ -6,10 +6,12 @@ Section Public
 
   - main <-
   ( + a0 :PROTO;
+    + a0b:AMBIGUOUS_PROTONAME.PROTO;
     + a1 :DIR1.PROTO;
     + a2 :DIR2.PROTO;
     a1.println;
     a2.println;
     "Hello".println;
     a0.toto;
+    a0b.toto;
   );

-- 
Lisaac compiler



More information about the Lisaac-commits mailing list