|
|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: B T
Length: 30572 (0x776c)
Types: TextFile
Names: »B«
└─⟦a7d1ea751⟧ Bits:30000550 8mm tape, Rational 1000, !users!projects 94_04_11
└─⟦129cab021⟧ »DATA«
└─⟦this⟧
└─⟦2f6cfab89⟧ Bits:30000547 8mm tape, Rational 1000, !projects 94-01-04
└─⟦d65440be7⟧ »DATA«
└─⟦this⟧
with Dfa, Ecs, Misc_Defs;
use Misc_Defs;
package body Tblcmp is
-- bldtbl - build table entries for dfa state
--
-- synopsis
-- int state[numecs], statenum, totaltrans, comstate, comfreq;
-- bldtbl( state, statenum, totaltrans, comstate, comfreq );
--
-- State is the statenum'th dfa state. It is indexed by equivalence class and
-- gives the number of the state to enter for a given equivalence class.
-- totaltrans is the total number of transitions out of the state. Comstate
-- is that state which is the destination of the most transitions out of State.
-- Comfreq is how many transitions there are out of State to Comstate.
--
-- A note on terminology:
-- "protos" are transition tables which have a high probability of
-- either being redundant (a state processed later will have an identical
-- transition table) or nearly redundant (a state processed later will have
-- many of the same out-transitions). A "most recently used" queue of
-- protos is kept around with the hope that most states will find a proto
-- which is similar enough to be usable, and therefore compacting the
-- output tables.
-- "templates" are a special type of proto. If a transition table is
-- homogeneous or nearly homogeneous (all transitions go to the same
-- destination) then the odds are good that future states will also go
-- to the same destination state on basically the same character set.
-- These homogeneous states are so common when dealing with large rule
-- sets that they merit special attention. If the transition table were
-- simply made into a proto, then (typically) each subsequent, similar
-- state will differ from the proto for two out-transitions. One of these
-- out-transitions will be that character on which the proto does not go
-- to the common destination, and one will be that character on which the
-- state does not go to the common destination. Templates, on the other
-- hand, go to the common state on EVERY transition character, and therefore
-- cost only one difference.
procedure Bldtbl (State : in Unbounded_Int_Array;
Statenum, Totaltrans, Comstate, Comfreq : in Integer) is
Extptr : Integer;
subtype Carray is Unbounded_Int_Array (0 .. Csize + 1);
Extrct : array (0 .. 1) of Carray;
Mindiff, Minprot, I, D : Integer;
Checkcom : Boolean;
Local_Comstate : Integer;
begin
-- If extptr is 0 then the first array of extrct holds the result of the
-- "best difference" to date, which is those transitions which occur in
-- "state" but not in the proto which, to date, has the fewest differences
-- between itself and "state". If extptr is 1 then the second array of
-- extrct hold the best difference. The two arrays are toggled
-- between so that the best difference to date can be kept around and
-- also a difference just created by checking against a candidate "best"
-- proto.
Local_Comstate := Comstate;
Extptr := 0;
-- if the state has too few out-transitions, don't bother trying to
-- compact its tables
if ((Totaltrans * 100) < (Numecs * Proto_Size_Percentage)) then
Mkentry (State, Numecs, Statenum, Jamstate_Const, Totaltrans);
else
-- checkcom is true if we should only check "state" against
-- protos which have the same "comstate" value
Checkcom := Comfreq * 100 > Totaltrans * Check_Com_Percentage;
Minprot := Firstprot;
Mindiff := Totaltrans;
if (Checkcom) then
-- find first proto which has the same "comstate"
I := Firstprot;
while (I /= Nil) loop
if (Protcomst (I) = Local_Comstate) then
Minprot := I;
Tbldiff (State, Minprot, Extrct (Extptr), Mindiff);
exit;
end if;
I := Protnext (I);
end loop;
else
-- since we've decided that the most common destination out
-- of "state" does not occur with a high enough frequency,
-- we set the "comstate" to zero, assuring that if this state
-- is entered into the proto list, it will not be considered
-- a template.
Local_Comstate := 0;
if (Firstprot /= Nil) then
Minprot := Firstprot;
Tbldiff (State, Minprot, Extrct (Extptr), Mindiff);
end if;
end if;
-- we now have the first interesting proto in "minprot". If
-- it matches within the tolerances set for the first proto,
-- we don't want to bother scanning the rest of the proto list
-- to see if we have any other reasonable matches.
if (Mindiff * 100 > Totaltrans * First_Match_Diff_Percentage) then
-- not a good enough match. Scan the rest of the protos
I := Minprot;
while (I /= Nil) loop
Tbldiff (State, I, Extrct (1 - Extptr), D);
if (D < Mindiff) then
Extptr := 1 - Extptr;
Mindiff := D;
Minprot := I;
end if;
I := Protnext (I);
end loop;
end if;
-- check if the proto we've decided on as our best bet is close
-- enough to the state we want to match to be usable
if (Mindiff * 100 > Totaltrans * Acceptable_Diff_Percentage) then
-- no good. If the state is homogeneous enough, we make a
-- template out of it. Otherwise, we make a proto.
if (Comfreq * 100 >= Totaltrans * Template_Same_Percentage) then
Mktemplate (State, Statenum, Local_Comstate);
else
Mkprot (State, Statenum, Local_Comstate);
Mkentry (State, Numecs, Statenum,
Jamstate_Const, Totaltrans);
end if;
else
-- use the proto
Mkentry (Extrct (Extptr), Numecs, Statenum,
Prottbl (Minprot), Mindiff);
-- if this state was sufficiently different from the proto
-- we built it from, make it, too, a proto
if (Mindiff * 100 >= Totaltrans *
New_Proto_Diff_Percentage) then
Mkprot (State, Statenum, Local_Comstate);
end if;
-- since mkprot added a new proto to the proto queue, it's possible
-- that "minprot" is no longer on the proto queue (if it happened
-- to have been the last entry, it would have been bumped off).
-- If it's not there, then the new proto took its physical place
-- (though logically the new proto is at the beginning of the
-- queue), so in that case the following call will do nothing.
Mv2front (Minprot);
end if;
end if;
end Bldtbl;
-- cmptmps - compress template table entries
--
-- template tables are compressed by using the 'template equivalence
-- classes', which are collections of transition character equivalence
-- classes which always appear together in templates - really meta-equivalence
-- classes. until this point, the tables for templates have been stored
-- up at the top end of the nxt array; they will now be compressed and have
-- table entries made for them.
procedure Cmptmps is
Tmpstorage : C_Size_Array;
Totaltrans, Trans : Integer;
begin
Peakpairs := Numtemps * Numecs + Tblend;
if (Usemecs) then
-- create equivalence classes base on data gathered on template
-- transitions
Ecs.Cre8ecs (Tecfwd, Tecbck, Numecs, Nummecs);
else
Nummecs := Numecs;
end if;
if (Lastdfa + Numtemps + 1 >= Current_Max_Dfas) then
Dfa.Increase_Max_Dfas;
end if;
-- loop through each template
for I in 1 .. Numtemps loop
Totaltrans := 0;
-- number of non-jam transitions out of this template
for J in 1 .. Numecs loop
Trans := Tnxt (Numecs * I + J);
if (Usemecs) then
-- the absolute value of tecbck is the meta-equivalence class
-- of a given equivalence class, as set up by cre8ecs
if (Tecbck (J) > 0) then
Tmpstorage (Tecbck (J)) := Trans;
if (Trans > 0) then
Totaltrans := Totaltrans + 1;
end if;
end if;
else
Tmpstorage (J) := Trans;
if (Trans > 0) then
Totaltrans := Totaltrans + 1;
end if;
end if;
end loop;
-- it is assumed (in a rather subtle way) in the skeleton that
-- if we're using meta-equivalence classes, the def[] entry for
-- all templates is the jam template, i.e., templates never default
-- to other non-jam table entries (e.g., another template)
-- leave room for the jam-state after the last real state
Mkentry (Tmpstorage, Nummecs, Lastdfa + I + 1,
Jamstate_Const, Totaltrans);
end loop;
end Cmptmps;
-- expand_nxt_chk - expand the next check arrays
procedure Expand_Nxt_Chk is
Old_Max : Integer := Current_Max_Xpairs;
begin
Current_Max_Xpairs := Current_Max_Xpairs + Max_Xpairs_Increment;
Num_Reallocs := Num_Reallocs + 1;
Reallocate_Integer_Array (Nxt, Current_Max_Xpairs);
Reallocate_Integer_Array (Chk, Current_Max_Xpairs);
for I in Old_Max .. Current_Max_Xpairs loop
Chk (I) := 0;
end loop;
end Expand_Nxt_Chk;
-- find_table_space - finds a space in the table for a state to be placed
--
-- State is the state to be added to the full speed transition table.
-- Numtrans is the number of out-transitions for the state.
--
-- find_table_space() returns the position of the start of the first block (in
-- chk) able to accommodate the state
--
-- In determining if a state will or will not fit, find_table_space() must take
-- into account the fact that an end-of-buffer state will be added at [0],
-- and an action number will be added in [-1].
function Find_Table_Space
(State : in Unbounded_Int_Array; Numtrans : in Integer)
return Integer is
-- firstfree is the position of the first possible occurrence of two
-- consecutive unused records in the chk and nxt arrays
I : Integer;
State_Ptr, Chk_Ptr, Ptr_To_Last_Entry_In_State : Int_Ptr;
Cnt, Scnt : Integer;
-- if there are too many out-transitions, put the state at the end of
-- nxt and chk
begin
if (Numtrans > Max_Xtions_Full_Interior_Fit) then
-- if table is empty, return the first available spot in chk/nxt,
-- which should be 1
if (Tblend < 2) then
return (1);
end if;
I := Tblend - Numecs;
-- start searching for table space near the
-- end of chk/nxt arrays
else
I := Firstfree;
-- start searching for table space from the
-- beginning (skipping only the elements
-- which will definitely not hold the new
-- state)
end if;
loop
-- loops until a space is found
if (I + Numecs > Current_Max_Xpairs) then
Expand_Nxt_Chk;
end if;
-- loops until space for end-of-buffer and action number are found
loop
if (Chk (I - 1) = 0) then
-- check for action number space
if (Chk (I) = 0) then
-- check for end-of-buffer space
exit;
else
I := I + 2;
-- since i != 0, there is no use checking to
-- see if (++i) - 1 == 0, because that's the
-- same as i == 0, so we skip a space
end if;
else
I := I + 1;
end if;
if (I + Numecs > Current_Max_Xpairs) then
Expand_Nxt_Chk;
end if;
end loop;
-- if we started search from the beginning, store the new firstfree for
-- the next call of find_table_space()
if (Numtrans <= Max_Xtions_Full_Interior_Fit) then
Firstfree := I + 1;
end if;
-- check to see if all elements in chk (and therefore nxt) that are
-- needed for the new state have not yet been taken
Cnt := I + 1;
Scnt := 1;
while (Cnt /= I + Numecs + 1) loop
if ((State (Scnt) /= 0) and (Chk (Cnt) /= 0)) then
exit;
end if;
Scnt := Scnt + 1;
Cnt := Cnt + 1;
end loop;
if (Cnt = I + Numecs + 1) then
return I;
else
I := I + 1;
end if;
end loop;
end Find_Table_Space;
-- inittbl - initialize transition tables
--
-- Initializes "firstfree" to be one beyond the end of the table. Initializes
-- all "chk" entries to be zero. Note that templates are built in their
-- own tbase/tdef tables. They are shifted down to be contiguous
-- with the non-template entries during table generation.
procedure Inittbl is
begin
for I in 0 .. Current_Max_Xpairs loop
Chk (I) := 0;
end loop;
Tblend := 0;
Firstfree := Tblend + 1;
Numtemps := 0;
if (Usemecs) then
-- set up doubly-linked meta-equivalence classes
-- these are sets of equivalence classes which all have identical
-- transitions out of TEMPLATES
Tecbck (1) := Nil;
for I in 2 .. Numecs loop
Tecbck (I) := I - 1;
Tecfwd (I - 1) := I;
end loop;
Tecfwd (Numecs) := Nil;
end if;
end Inittbl;
-- mkdeftbl - make the default, "jam" table entries
procedure Mkdeftbl is
begin
Jamstate := Lastdfa + 1;
Tblend := Tblend + 1;
-- room for transition on end-of-buffer character
if (Tblend + Numecs > Current_Max_Xpairs) then
Expand_Nxt_Chk;
end if;
-- add in default end-of-buffer transition
Nxt (Tblend) := End_Of_Buffer_State;
Chk (Tblend) := Jamstate;
for I in 1 .. Numecs loop
Nxt (Tblend + I) := 0;
Chk (Tblend + I) := Jamstate;
end loop;
Jambase := Tblend;
Base (Jamstate) := Jambase;
Def (Jamstate) := 0;
Tblend := Tblend + Numecs;
Numtemps := Numtemps + 1;
end Mkdeftbl;
-- mkentry - create base/def and nxt/chk entries for transition array
--
-- "state" is a transition array "numchars" characters in size, "statenum"
-- is the offset to be used into the base/def tables, and "deflink" is the
-- entry to put in the "def" table entry. If "deflink" is equal to
-- "JAMSTATE", then no attempt will be made to fit zero entries of "state"
-- (i.e., jam entries) into the table. It is assumed that by linking to
-- "JAMSTATE" they will be taken care of. In any case, entries in "state"
-- marking transitions to "SAME_TRANS" are treated as though they will be
-- taken care of by whereever "deflink" points. "totaltrans" is the total
-- number of transitions out of the state. If it is below a certain threshold,
-- the tables are searched for an interior spot that will accommodate the
-- state array.
procedure Mkentry (State : in Unbounded_Int_Array;
Numchars, Statenum, Deflink, Totaltrans : in Integer) is
I, Minec, Maxec, Baseaddr, Tblbase, Tbllast : Integer;
begin
if (Totaltrans = 0) then
-- there are no out-transitions
if (Deflink = Jamstate_Const) then
Base (Statenum) := Jamstate_Const;
else
Base (Statenum) := 0;
end if;
Def (Statenum) := Deflink;
return;
end if;
Minec := 1;
while (Minec <= Numchars) loop
if (State (Minec) /= Same_Trans) then
if ((State (Minec) /= 0) or (Deflink /= Jamstate_Const)) then
exit;
end if;
end if;
Minec := Minec + 1;
end loop;
if (Totaltrans = 1) then
-- there's only one out-transition. Save it for later to fill
-- in holes in the tables.
Stack1 (Statenum, Minec, State (Minec), Deflink);
return;
end if;
Maxec := Numchars;
while (Maxec >= 1) loop
if (State (Maxec) /= Same_Trans) then
if ((State (Maxec) /= 0) or (Deflink /= Jamstate_Const)) then
exit;
end if;
end if;
Maxec := Maxec - 1;
end loop;
-- Whether we try to fit the state table in the middle of the table
-- entries we have already generated, or if we just take the state
-- table at the end of the nxt/chk tables, we must make sure that we
-- have a valid base address (i.e., non-negative). Note that not only are
-- negative base addresses dangerous at run-time (because indexing the
-- next array with one and a low-valued character might generate an
-- array-out-of-bounds error message), but at compile-time negative
-- base addresses denote TEMPLATES.
-- find the first transition of state that we need to worry about.
if (Totaltrans * 100 <= Numchars * Interior_Fit_Percentage) then
-- attempt to squeeze it into the middle of the tabls
Baseaddr := Firstfree;
while (Baseaddr < Minec) loop
-- using baseaddr would result in a negative base address below
-- find the next free slot
Baseaddr := Baseaddr + 1;
while (Chk (Baseaddr) /= 0) loop
Baseaddr := Baseaddr + 1;
end loop;
end loop;
if (Baseaddr + Maxec - Minec >= Current_Max_Xpairs) then
Expand_Nxt_Chk;
end if;
I := Minec;
while (I <= Maxec) loop
if (State (I) /= Same_Trans) then
if ((State (I) /= 0) or (Deflink /= Jamstate_Const)) then
if (Chk (Baseaddr + I - Minec) /= 0) then
-- baseaddr unsuitable - find another
Baseaddr := Baseaddr + 1;
while ((Baseaddr < Current_Max_Xpairs) and
(Chk (Baseaddr) /= 0)) loop
Baseaddr := Baseaddr + 1;
end loop;
if (Baseaddr + Maxec - Minec >=
Current_Max_Xpairs) then
Expand_Nxt_Chk;
end if;
-- reset the loop counter so we'll start all
-- over again next time it's incremented
I := Minec - 1;
end if;
end if;
end if;
I := I + 1;
end loop;
else
-- ensure that the base address we eventually generate is
-- non-negative
Baseaddr := Max (Tblend + 1, Minec);
end if;
Tblbase := Baseaddr - Minec;
Tbllast := Tblbase + Maxec;
if (Tbllast >= Current_Max_Xpairs) then
Expand_Nxt_Chk;
end if;
Base (Statenum) := Tblbase;
Def (Statenum) := Deflink;
for J in Minec .. Maxec loop
if (State (J) /= Same_Trans) then
if ((State (J) /= 0) or (Deflink /= Jamstate_Const)) then
Nxt (Tblbase + J) := State (J);
Chk (Tblbase + J) := Statenum;
end if;
end if;
end loop;
if (Baseaddr = Firstfree) then
-- find next free slot in tables
Firstfree := Firstfree + 1;
while (Chk (Firstfree) /= 0) loop
Firstfree := Firstfree + 1;
end loop;
end if;
Tblend := Max (Tblend, Tbllast);
end Mkentry;
-- mk1tbl - create table entries for a state (or state fragment) which
-- has only one out-transition
procedure Mk1tbl (State, Sym, Onenxt, Onedef : in Integer) is
begin
if (Firstfree < Sym) then
Firstfree := Sym;
end if;
while (Chk (Firstfree) /= 0) loop
Firstfree := Firstfree + 1;
if (Firstfree >= Current_Max_Xpairs) then
Expand_Nxt_Chk;
end if;
end loop;
Base (State) := Firstfree - Sym;
Def (State) := Onedef;
Chk (Firstfree) := State;
Nxt (Firstfree) := Onenxt;
if (Firstfree > Tblend) then
Tblend := Firstfree;
Firstfree := Firstfree + 1;
if (Firstfree >= Current_Max_Xpairs) then
Expand_Nxt_Chk;
end if;
end if;
end Mk1tbl;
-- mkprot - create new proto entry
procedure Mkprot (State : in Unbounded_Int_Array;
Statenum, Comstate : in Integer) is
Slot, Tblbase : Integer;
begin
Numprots := Numprots + 1;
if ((Numprots >= Msp) or (Numecs * Numprots >= Prot_Save_Size)) then
-- gotta make room for the new proto by dropping last entry in
-- the queue
Slot := Lastprot;
Lastprot := Protprev (Lastprot);
Protnext (Lastprot) := Nil;
else
Slot := Numprots;
end if;
Protnext (Slot) := Firstprot;
if (Firstprot /= Nil) then
Protprev (Firstprot) := Slot;
end if;
Firstprot := Slot;
Prottbl (Slot) := Statenum;
Protcomst (Slot) := Comstate;
-- copy state into save area so it can be compared with rapidly
Tblbase := Numecs * (Slot - 1);
for I in 1 .. Numecs loop
Protsave (Tblbase + I) := State (I + State'First);
end loop;
end Mkprot;
-- mktemplate - create a template entry based on a state, and connect the state
-- to it
procedure Mktemplate (State : in Unbounded_Int_Array;
Statenum, Comstate : in Integer) is
Numdiff, Tmpbase : Integer;
Tmp : C_Size_Array;
subtype Tarray is Char_Array (0 .. Csize);
Transset : Tarray;
Tsptr : Integer;
begin
Numtemps := Numtemps + 1;
Tsptr := 0;
-- calculate where we will temporarily store the transition table
-- of the template in the tnxt[] array. The final transition table
-- gets created by cmptmps()
Tmpbase := Numtemps * Numecs;
if (Tmpbase + Numecs >= Current_Max_Template_Xpairs) then
Current_Max_Template_Xpairs :=
Current_Max_Template_Xpairs + Max_Template_Xpairs_Increment;
Num_Reallocs := Num_Reallocs + 1;
Reallocate_Integer_Array (Tnxt, Current_Max_Template_Xpairs);
end if;
for I in 1 .. Numecs loop
if (State (I) = 0) then
Tnxt (Tmpbase + I) := 0;
else
Transset (Tsptr) := Character'Val (I);
Tsptr := Tsptr + 1;
Tnxt (Tmpbase + I) := Comstate;
end if;
end loop;
if (Usemecs) then
Ecs.Mkeccl (Transset, Tsptr, Tecfwd, Tecbck, Numecs);
end if;
Mkprot (Tnxt (Tmpbase .. Current_Max_Template_Xpairs),
-Numtemps, Comstate);
-- we rely on the fact that mkprot adds things to the beginning
-- of the proto queue
Tbldiff (State, Firstprot, Tmp, Numdiff);
Mkentry (Tmp, Numecs, Statenum, -Numtemps, Numdiff);
end Mktemplate;
-- mv2front - move proto queue element to front of queue
procedure Mv2front (Qelm : in Integer) is
begin
if (Firstprot /= Qelm) then
if (Qelm = Lastprot) then
Lastprot := Protprev (Lastprot);
end if;
Protnext (Protprev (Qelm)) := Protnext (Qelm);
if (Protnext (Qelm) /= Nil) then
Protprev (Protnext (Qelm)) := Protprev (Qelm);
end if;
Protprev (Qelm) := Nil;
Protnext (Qelm) := Firstprot;
Protprev (Firstprot) := Qelm;
Firstprot := Qelm;
end if;
end Mv2front;
-- place_state - place a state into full speed transition table
--
-- State is the statenum'th state. It is indexed by equivalence class and
-- gives the number of the state to enter for a given equivalence class.
-- Transnum is the number of out-transitions for the state.
procedure Place_State (State : in Unbounded_Int_Array;
Statenum, Transnum : in Integer) is
I : Integer;
Position : Integer := Find_Table_Space (State, Transnum);
begin
-- base is the table of start positions
Base (Statenum) := Position;
-- put in action number marker; this non-zero number makes sure that
-- find_table_space() knows that this position in chk/nxt is taken
-- and should not be used for another accepting number in another state
Chk (Position - 1) := 1;
-- put in end-of-buffer marker; this is for the same purposes as above
Chk (Position) := 1;
-- place the state into chk and nxt
I := 1;
while (I <= Numecs) loop
if (State (I) /= 0) then
Chk (Position + I) := I;
Nxt (Position + I) := State (I);
end if;
I := I + 1;
end loop;
if (Position + Numecs > Tblend) then
Tblend := Position + Numecs;
end if;
end Place_State;
-- stack1 - save states with only one out-transition to be processed later
--
-- if there's room for another state one the "one-transition" stack, the
-- state is pushed onto it, to be processed later by mk1tbl. If there's
-- no room, we process the sucker right now.
procedure Stack1 (Statenum, Sym, Nextstate, Deflink : in Integer) is
begin
if (Onesp >= One_Stack_Size - 1) then
Mk1tbl (Statenum, Sym, Nextstate, Deflink);
else
Onesp := Onesp + 1;
Onestate (Onesp) := Statenum;
Onesym (Onesp) := Sym;
Onenext (Onesp) := Nextstate;
Onedef (Onesp) := Deflink;
end if;
end Stack1;
-- tbldiff - compute differences between two state tables
--
-- "state" is the state array which is to be extracted from the pr'th
-- proto. "pr" is both the number of the proto we are extracting from
-- and an index into the save area where we can find the proto's complete
-- state table. Each entry in "state" which differs from the corresponding
-- entry of "pr" will appear in "ext".
-- Entries which are the same in both "state" and "pr" will be marked
-- as transitions to "SAME_TRANS" in "ext". The total number of differences
-- between "state" and "pr" is returned as function value. Note that this
-- number is "numecs" minus the number of "SAME_TRANS" entries in "ext".
procedure Tbldiff (State : in Unbounded_Int_Array;
Pr : in Integer;
Ext : out Unbounded_Int_Array;
Result : out Integer) is
Sp : Integer := 0;
Ep : Integer := 0;
Numdiff : Integer := 0;
Protp : Integer;
begin
Protp := Numecs * (Pr - 1);
for I in reverse 1 .. Numecs loop
Protp := Protp + 1;
Sp := Sp + 1;
if (Protsave (Protp) = State (Sp)) then
Ep := Ep + 1;
Ext (Ep) := Same_Trans;
else
Ep := Ep + 1;
Ext (Ep) := State (Sp);
Numdiff := Numdiff + 1;
end if;
end loop;
Result := Numdiff;
return;
end Tbldiff;
end Tblcmp;
-- Copyright (c) 1990 Regents of the University of California.
-- All rights reserved.
--
-- This software was developed by John Self of the Arcadia project
-- at the University of California, Irvine.
--
-- Redistribution and use in source and binary forms are permitted
-- provided that the above copyright notice and this paragraph are
-- duplicated in all such forms and that any documentation,
-- advertising materials, and other materials related to such
-- distribution and use acknowledge that the software was developed
-- by the University of California, Irvine. The name of the
-- University may not be used to endorse or promote products derived
-- from this software without specific prior written permission.
-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
-- IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
-- WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-- TITLE table compression routines
-- AUTHOR: John Self (UCI)
-- DESCRIPTION used for compressed tables only
-- NOTES somewhat complicated but works fast and generates efficient scanners
-- $Header: /co/ua/self/arcadia/aflex/ada/src/RCS/tblcmpS.a,v 1.3 90/01/12 15:20:47 self Exp Locker: self $