Browse Source

+ Tdictionary object: Tsymtable will become object(TTdictionary) in the
future
+ Tnamed_item object: Tsym will become object(Tnamed_item) in the future

daniel 27 years ago
parent
commit
48ebf8cd94
1 changed files with 270 additions and 1 deletions
  1. 270 1
      compiler/cobjects.pas

+ 270 - 1
compiler/cobjects.pas

@@ -40,6 +40,10 @@ unit cobjects;
 {$endif}
 {$endif}
       ;
       ;
 
 
+    const   hasharraysize = 253; {The size of a hasharray should be a prime
+                                  number for better spreading of nodes in
+                                  the array!! (DM)}
+
     type
     type
        pstring = ^string;
        pstring = ^string;
 
 
@@ -148,6 +152,35 @@ unit cobjects;
           procedure clear;
           procedure clear;
        end;
        end;
 
 
+        Pnamed_object=^Tnamed_object;
+        Pdictionary=^Tdictionary;
+        Pdictionaryhasharray=^Tdictionaryhasharray;
+
+        Tdictionaryhasharray=array[0..hasharraysize-1] of Pnamed_object;
+
+        Tcallback = procedure(p:Pnamed_object);
+
+        Tdictionary=object
+            root:Pnamed_object;
+            hasharray:Pdictionaryhasharray;
+            constructor init(usehash:boolean);
+            procedure clear;virtual;
+            procedure foreach(proc2call:Tcallback);
+            function insert(obj:Pnamed_object):Pnamed_object;virtual;
+            function search(const s:string):Pnamed_object;
+            function speedsearch(const s:string;
+             speedvalue:longint):Pnamed_object;virtual;
+            destructor done;virtual;
+        end;
+
+        Tnamed_object=object
+            name:Pstring;
+            left,right:Pnamed_object;
+            speedvalue:longint;
+            owner:Pdictionary;
+            constructor init(const n:string);
+            destructor done;virtual;
+        end;
 
 
 {$ifdef BUFFEREDFILE}
 {$ifdef BUFFEREDFILE}
        { this is implemented to allow buffered binary I/O }
        { this is implemented to allow buffered binary I/O }
@@ -269,6 +302,44 @@ unit cobjects;
 
 
   implementation
   implementation
 
 
+{$ifdef FPC}
+    function getspeedvalue(const s : string) : longint;
+      var
+        p1,p2:^byte;
+      begin
+        p1:=@s;
+        longint(p2):=longint(p1)+p1^+1;
+        inc(longint(p1));
+        getspeedvalue:=0;
+        while p1<>p2 do
+         begin
+           inc(getspeedvalue,p1^);
+           inc(longint(p1));
+         end;
+      end;
+{$else}
+    function getspeedvalue(const s : string) : longint;
+      type
+        ptrrec=record
+          ofs,seg:word;
+        end;
+      var
+        l,w   : longint;
+        p1,p2 : ^byte;
+      begin
+        p1:=@s;
+        ptrrec(p2).seg:=ptrrec(p1).seg;
+        ptrrec(p2).ofs:=ptrrec(p1).ofs+p1^+1;
+        inc(p1);
+        l:=0;
+        while p1<>p2 do
+         begin
+           l:=l+p1^;
+           inc(p1);
+         end;
+        getspeedvalue:=l;
+      end;
+{$endif}
 
 
     function pchar2pstring(p : pchar) : pstring;
     function pchar2pstring(p : pchar) : pstring;
       var
       var
@@ -755,6 +826,199 @@ end;
         empty:=(first=nil);
         empty:=(first=nil);
       end;
       end;
 
 
+{****************************************************************************
+                               TNAMED_OBJECT
+ ****************************************************************************}
+
+constructor Tnamed_object.init(const n:string);
+
+begin
+    left:=nil;
+    right:=nil;
+    name:=stringdup(n);
+    speedvalue:=getspeedvalue(n);
+end;
+
+destructor Tnamed_object.done;
+
+begin
+    stringdispose(name);
+end;
+
+{****************************************************************************
+                               TDICTIONARY
+ ****************************************************************************}
+
+constructor Tdictionary.init(usehash:boolean);
+
+begin
+    root:=nil;
+    hasharray:=nil;
+    if usehash then
+        begin
+            new(hasharray);
+            fillchar(hasharray^,sizeof(hasharray^),0);
+        end;
+end;
+
+procedure Tdictionary.clear;
+
+var w:longint;
+
+begin
+    {remove no entry from a withsymtable as it is only a pointer to the
+     recorddef  or objectdef symtable }
+    { remove all entry from a symbol table }
+    if assigned(root) then
+        dispose(root,done);
+    if assigned(hasharray) then
+        for w:=0 to hasharraysize-1 do
+            if assigned(hasharray^[w]) then
+                begin
+                    dispose(hasharray^[w],done);
+                    hasharray^[w]:=nil;
+                end;
+end;
+
+procedure Tdictionary.foreach(proc2call:Tcallback);
+
+    procedure a(p:Pnamed_object);
+
+    { must be preorder, because it's used by reading in }
+    { a PPU file                                        }
+
+    begin
+        proc2call(p);
+        if assigned(p^.left) then
+            a(p^.left);
+        if assigned(p^.right) then
+            a(p^.right);
+    end;
+
+var i:longint;
+
+begin
+    if assigned(hasharray) then
+        begin
+            for i:=0 to hasharraysize-1 do
+                if assigned(hasharray^[i]) then
+                    a(hasharray^[i]);
+        end
+    else
+        if assigned(root) then
+            a(root);
+end;
+
+
+function Tdictionary.insert(obj:Pnamed_object):Pnamed_object;
+
+    function _insert(var osym:Pnamed_object):Pnamed_object;
+
+    {To prevent TP from allocating temp space for temp strings, we allocate
+     some temp strings manually. We can use two temp strings, plus a third
+     one that TP adds, where TP alone needs five temp strings!. Storing
+     these on the heap saves even more, totally 1016 bytes per recursion!}
+
+    var s1,s2:^string;
+
+    begin
+        if osym=nil then
+            begin
+                osym:=obj;
+                _insert:=osym;
+            end
+        { first check speedvalue, to allow a fast insert }
+        else
+            if osym^.speedvalue>obj^.speedvalue then
+                _insert:=_insert(osym^.right)
+            else
+                if osym^.speedvalue<obj^.speedvalue then
+                    _insert:=_insert(osym^.left)
+                else
+                    begin
+                        new(s1);
+                        new(s2);
+                        s1^:=osym^.name^;
+                        s2^:=obj^.name^;
+                        if s1^>s2^ then
+                            begin
+                                dispose(s2);
+                                dispose(s1);
+                                _insert:=_insert(osym^.right);
+                            end
+                        else
+                            if s1^<s2^ then
+                                begin
+                                    dispose(s2);
+                                    dispose(s1);
+                                    _insert:=_insert(osym^.left);
+                                end
+                            else
+                                begin
+                                    dispose(s2);
+                                    dispose(s1);
+                                    _insert:=osym;
+                                end;
+                    end;
+    end;
+
+begin
+    obj^.owner:=@self;
+    obj^.speedvalue:=getspeedvalue(obj^.name^);
+    if assigned(hasharray) then
+        insert:=_insert(hasharray^[obj^.speedvalue mod hasharraysize])
+    else
+        insert:=_insert(root);
+end;
+
+
+function Tdictionary.search(const s:string):Pnamed_object;
+
+begin
+    search:=speedsearch(s,getspeedvalue(s));
+end;
+
+function Tdictionary.speedsearch(const s:string;
+                                 speedvalue:longint):Pnamed_object;
+
+var hp:Pnamed_object;
+
+begin
+    if assigned(hasharray) then
+        hp:=hasharray^[speedvalue mod hasharraysize]
+    else
+        hp:=root;
+        while assigned(hp) do
+            begin
+                if speedvalue>hp^.speedvalue then
+                    hp:=hp^.left
+                else
+                    if speedvalue<hp^.speedvalue then
+                        hp:=hp^.right
+                    else
+                        begin
+                            if (hp^.name^=s) then
+                                begin
+                                    speedsearch:=hp;
+                                    exit;
+                                end
+                            else
+                                if s>hp^.name^ then
+                                    hp:=hp^.left
+                                else
+                                    hp:=hp^.right;
+                        end;
+            end;
+        speedsearch:=nil;
+end;
+
+destructor Tdictionary.done;
+
+begin
+    clear;
+    if assigned(hasharray) then
+        dispose(hasharray);
+end;
 
 
 {$ifdef BUFFEREDFILE}
 {$ifdef BUFFEREDFILE}
 
 
@@ -1144,7 +1408,12 @@ end;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.16  1998-11-04 10:11:37  peter
+  Revision 1.17  1999-01-19 11:00:33  daniel
+  + Tdictionary object:  Tsymtable will become object(TTdictionary) in the
+    future
+  + Tnamed_item object:  Tsym will become object(Tnamed_item) in the future
+
+  Revision 1.16  1998/11/04 10:11:37  peter
     * ansistring fixes
     * ansistring fixes
 
 
   Revision 1.15  1998/10/19 18:04:40  peter
   Revision 1.15  1998/10/19 18:04:40  peter