-- (C) Copyright International Business Machines Corporation 23 January 
-- 1990.  All Rights Reserved. 
--  
-- See the file USERAGREEMENT distributed with this software for full 
-- terms and conditions of use. 
-- File: newtableinfo.pp
-- Author: Andy Lowry
-- SCCS Info: @(#)newtableinfo.pp	1.9 3/13/90

-- This process selects one or more data representations for a given
-- table type descriptor.  So far the selection is not very
-- sophisticated....

#include "typemark.h"
#include "codegen.h"

newTableInfo: using (interpform, cginternal)

process (Q: newTableInfoQ)

declare
  args: newTableInfo;
  tdef: type_definition;
  empty: empty;
begin
  receive args from Q;

  -- allocate the result and get the element type
  new args.datarep;
  tdef <- type_definition#(args.typeDef(args.info.element_type));

  -- Decide on the primary representation first...

  -- ordered tables get vector-like representations
  if (args.info.ordered_table) then
    block declare
      ip: integer_pair;		-- vector allocation parameters
    begin
      new ip;

      -- if the element type is an enumeration with no more enumerators
      -- than char, then we use a charstring as the primary
      -- representation 
      if B(primitive_types#(case of tdef.specification) 
	   = primitive_types#'enumerationtype') then
	reveal tdef.specification.enumeration;
	if B(I(size of tdef.specification.enumeration.values)
	     <= I(SIZE_OF_CHARS)) then
	  ip.int_one <- I(INITSIZE_CHAR);
	  ip.int_two <- I(GROWTH_CHAR);
	  unite args.datarep.nonlookup.chs from ip;
	else
	  exit vector;		-- enumeration too big for charstring
	end if;
      else
	exit vector;		-- non-enumeration element type
      end if;
  
    on exit(vector)
      -- here when a non-charstring vector type is needed
      ip.int_one <- I(INITSIZE_VEC);
      ip.int_two <- I(GROWTH_VEC);
      unite args.datarep.nonlookup.vec from ip;

    end block;

  else
    -- unordered table... no primary representation if there are keys,
    -- else use a linked list
    if B(I(size of args.info.keys) = ZERO) then
      unite args.datarep.nonlookup.linklist from empty;
    else
      unite args.datarep.nonlookup.none from empty;
    end if;

  end if;

  -- Now allocate a representation for each key (NYI: and index)
  block declare
    li: lookup_info;
    rep: table_rep;
    liKey: interpform!operand_list; -- compononent offsets for one key/index
  begin
    new li;
    new li.reps;		-- no alternate reps yet
    new li.keys;
    new li.indices;

    for key in args.info.keys[] inspect
      unite rep.keyavl from empty;-- each rep is of type 'keyavl'
      insert rep into li.reps;

      -- accumulate offset lists for the key components
      new liKey;
      for components in key[] inspect
	block declare
	  type: typename;
	begin
	  type := args.info.element_type;
	  insert interpform!operand#(args.compOffsets(type,components)) 
	      into liKey;
	end block;
      end for;

      -- Add this key set to our list
      insert liKey into li.keys;

    end for;

    -- Code to generate datareps for indices should go here...


    -- If any key/index reps were generated, install them in the
    -- qualifier
    if B(I(size of li.reps) <> ZERO) then
      unite args.datarep.opt_reps.info from li;
    else
      unite args.datarep.opt_reps.empty from empty;
    end if;

  end block;

  -- All done...
  return args;

end process
