definition module Redirections;

import UtilStrictLists;
import BitSet;
import StdMaybe;

// -----------------------------------------------------------------------------------------
// Label name table
LABEL_NAME_TABLE_SIZE			:== 4096;
LABEL_NAME_TABLE_SIZE_MASK 		:== 4095;

:: *LabelNameTable
	:== *{List LabelName};
	
:: LabelName
	= {
		ln_label_name 		 :: !String
	,	ln_redirection_index :: !Int			// index in RedirectionTable
	,	ln_constructor_index :: !Int			// index in ri_constructor_infos
	};

insert_label_name :: LabelName !LabelNameTable -> !LabelNameTable;

class lookup_label_name a :: !String !*a -> (Maybe LabelName,!*a);

// instance lookup_label_name {List LabelName};	// LabelNameTable
instance lookup_label_name RedirectionState;

//insert_label_name ln=:{ln_label_name,ln_redirection_index} label_name_table;

// -----------------------------------------------------------------------------------------
// Module Names Table
:: ModuleNameTable = {
		module_names		:: {#String}
	,	contains_dynamics	:: .BitSet
	};
	
// -----------------------------------------------------------------------------------------
// Redirection Table
:: RedirectionTable
	:== {#.RedirectionInfo};
	
:: RedirectionInfo = {
		ri_module_names			:: !.BitSet
	,	ri_constructor_infos	:: .{#ConstructorInfo}
	,	ri_s_constructor_infos	:: !Int
	};
	
default_redirection_info :: .RedirectionInfo;

:: ConstructorInfo = {
		ci_name					:: !String
	,	ci_prefix_set			:: !PrefixSet
	};

default_constructor_info :: !.ConstructorInfo;

:: PrefixSet =
		NonStrictRecord !NonStrictRecord
	|	StrictRecord !StrictRecord
	|	NonStrictConstructor !NonStrictConstructor
	|	StrictConstructor !StrictConstructor
	|	NoPrefixSet
	;	
	
:: NonStrictRecord = {
		nsr_r_prefix				:: Maybe !String
	};
	
:: StrictRecord = {
		sr_r_prefix					:: Maybe !String
	,	sr_t_prefix					:: Maybe !String
	,	sr_c_prefix					:: Maybe !String
	};
	
:: NonStrictConstructor = {
		nsc_d_prefix				:: Maybe !String
	};
	
default_non_strict_constructor :: !.NonStrictConstructor;
	
:: StrictConstructor = {
		sc_k_prefix					:: Maybe !String
	,	sc_d_prefix					:: Maybe !String
	,	sc_n_prefix					:: Maybe !String
	,	sc_l_prefix					:: Maybe !String
	};
	
default_strict_constructor :: !.StrictConstructor;

get_prefix :: !Char !LabelName !*RedirectionState -> (Maybe !String,!*RedirectionState);
put_prefix :: !Char !LabelName !*RedirectionState -> !*RedirectionState;
	
/*
:: LabelPrefixes = {
		lp_n_prefix	:: Maybe !String
	,	lp_d_prefix :: Maybe !String
	,	lp_k_prefix	:: Maybe !String
	,	lp_c_prefix	:: Maybe !String
	,	lp_t_prefix	:: Maybe !String
	,	lp_r_prefix	:: Maybe !String
	,	lp_l_prefix	:: Maybe !String
	};
	
default_label_prefixes :: .LabelPrefixes;
*/
import NamesTable;

// -----------------------------------------------------------------------------------------
// Redirection State
:: *RedirectionState = {
		rs_use_redirections		:: !Bool
	,	rs_label_name_table		:: !*LabelNameTable
	,	rs_module_name_table	:: !ModuleNameTable
	,	rs_redirection_table	:: !*RedirectionTable
	,	rs_messages				:: [String]					// string are in reverse order
	
	// new .. (used to redirect rts labels to the rts labels of the main library)
	,	rs_main_names_table		:: !*NamesTable	
	,	rs_rts_modules			:: [String]
	,	rs_change_rts_label		:: !Bool
	// ... new 
	};
	
default_redirection_state :: !*RedirectionState;

class GetPutRedirectionState s 
where {
	get_redirection_state :: !*s -> (!*RedirectionState,!*s);
	put_redirection_state :: !*RedirectionState !*s -> !*s
};

// -----------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------
