definition module type_io_read

//1.3
from StdString import String
//3.1
import BitSet
//1.3
from NamesTable import NamesTable, NamesTableElement
from general import Optional;
from StdFile import Files
from SymbolTable import LibraryList;
//3.1
/*2.0
from NamesTable import ::NamesTable, ::NamesTableElement, ::SNamesTable
from general import ::Optional;
from StdFile import ::Files
from SymbolTable import ::LibraryList;
0.2*/ 

import StdDynamicDefaultElem
import StdMaybe;

// Hashtable
NAME_TABLE_SIZE			:== 4096;
NAME_TABLE_SIZE_MASK 	:== 4095;

:: HashTableElement
	= {
		hte_name					:: !String
	,	hte_index					:: !Int
	,	hte_type_refs				:: !TypeName			// references types with same names
	,	hte_module_ref				:: !ModuleName
	}
	
:: TypeName
	= NoTypeName
	| TypeName [TIO_TypeReference]			// references to possibly different but equally named types
	;
	
isNoTypeName :: TypeName -> !Bool
	
:: ModuleName
	= NoModuleName
	| ModuleName Int						// module index in {TIO_CommonDefs}-array
	;
get_type_name :: !TIO_TypeReference !String !*{#TIO_CommonDefs} -> (!String,!*{#TIO_CommonDefs});

name_hash :: !String -> Int;

type_io_find_name :: !String !*TypeIOState -> *(!Bool,!HashTableElement,!*TypeIOState);	

insert_name :: !(Optional !Int) (Optional (!Int,!Int)) !.{#Char} !*TypeIOState -> *(!Int,!*TypeIOState);			


// Defaults
/*
class DefaultElem a
where
	default_elem :: a
*/
// 
:: *TypeIOState = {
	// String index table; used during read_type_info
		tis_current_string_index	:: !Int
	
	// String hash table
	,	tis_string_hash_table		:: !*{[HashTableElement]}
	,	tis_string_table			:: !String						// * dynamic rts
	
	// Used by TypeDef
	,	tis_current_module_i		:: !Int
	,	tis_current_def_i			:: !Int							// type or cons def
	
	// Used when filling in TIO_TypeReference
	,	tis_current_icl_module			:: !Int
	,	tis_is_module_already_in_scope	:: !*BitSet
	
	// ?	
	,	tis_max_types_per_module		:: !{#Int}					// index in bitset column
	,	tis_is_type_already_checked		:: !*BitSet
	
	, 	tis_n_common_defs				:: !Int						
	,	tis_max_types					:: !Int
	
	// used during equal_types
	,	tis_left_module_index			:: !Int
	,	tis_right_module_index			:: !Int
	
	// used after equivalent types have been determined
	,	tis_equivalent_type_definitions	:: !{#EquivalentTypeDef}	// * dynamic rts
	
	// used to reuse the read_type_info
	,	tis_reading_typ_file			:: !Bool					// .typ file
	};
	
select_bitset :: !Int !*TypeIOState -> (!Int,!*TypeIOState)
update_bitset :: !Int !Int !*TypeIOState -> !*TypeIOState

	
	
//:: EquivalentTypeDef
//:: HashTableElement

default_type_io_state :: !*TypeIOState
	// read
class ReadTypeInfo a
where
	read_type_info :: !*File !*TypeIOState -> (!Bool,a,!*File,!*TypeIOState)
	
instance ReadTypeInfo TIO_CommonDefs

instance DefaultElem TIO_CommonDefs

// Type IO
::	TIO_CommonDefs =
	{	tio_com_type_defs 				:: !.{# TIO_CheckedTypeDef}
	,   tio_com_cons_defs				:: !.{# TIO_ConsDef}
	,	tio_com_selector_defs			:: !.{# TIO_SelectorDef}
	,	tio_imported_modules			:: !.{#Int}						// offsets in string table; becomes index in {#TIO_CommonDefs}
	,	tio_n_exported_com_type_defs	:: !Int
	,	tio_n_exported_com_cons_defs	:: !Int
	,	tio_module						:: !Int							// offset in string table
	}
	
::	TIO_CheckedTypeDef	:== TIO_TypeDef TIO_TypeRhs
	
::	TIO_TypeDef type_rhs =
	{
		tio_td_name							:: !Int
	,	tio_td_arity						:: !Int
	,	tio_td_args							:: ![TIO_ATypeVar]		// - normalized so not necessary
	,	tio_td_rhs							:: !type_rhs
	
	// only used by after reading a TIO
	,	tio_type_equivalence_table_index	:: !Optional !Int
	};
	
::	TIO_TypeRhs	= TIO_AlgType ![TIO_DefinedSymbol]
				| TIO_SynType !TIO_AType
				| TIO_RecordType !TIO_RecordType
				| TIO_AbstractType !TIO_BITVECT
				| TIO_UnknownType
				
::	TIO_DefinedSymbol = 
	{	tio_ds_ident			:: !Int
 	,	tio_ds_arity			:: !Int
	,	tio_ds_index			:: !TIO_Index					// waar wijst dit veld na? index in tio_com_cons_defs
	}
		
::	TIO_RecordType =
	{
		tio_rt_fields			:: !{# TIO_FieldSymbol}
	}
	
::	TIO_ConsDef =
	{
		tio_cons_symb			:: !Int	
	,	tio_cons_type			:: !TIO_SymbolType
	,	tio_cons_arg_vars		:: ![[TIO_ATypeVar]]	// remove?
//	,	tio_cons_priority		:: !TIO_Priority		// REMOVE

	,	tio_cons_index			:: !TIO_Index			// remove?
	,	tio_cons_type_index		:: !TIO_Index			// remove?
	,	tio_cons_exi_vars		:: ![TIO_ATypeVar]
	}
	
:: TIO_SelectorDef = 
	{ 
		tio_sd_type				:: !TIO_SymbolType
	}
	
::	TIO_ATypeVar =
	{
		tio_atv_annotation		:: !TIO_Annotation
	,	tio_atv_variable		:: !TIO_TypeVar
	}
	
::	TIO_Annotation = TIO_AN_Strict | TIO_AN_None 

::	TIO_AType =
	{
		tio_at_annotation		:: !TIO_Annotation
	,	tio_at_type				:: !TIO_Type
	}
	
	
::	TIO_Type	=	TIO_TA !TIO_TypeSymbIdent ![TIO_AType]
			|	(---->) infixr 9 !TIO_AType !TIO_AType
			|	(:@@:) infixl 9 !TIO_ConsVariable ![TIO_AType]
			|	TIO_TB !TIO_BasicType

			| 	TIO_GTV !TIO_TypeVar
			| 	TIO_TV !TIO_TypeVar

			
			|	TIO_TQV	TIO_TypeVar

			|	TIO_TE
			
::	TIO_SymbolType =
	{	tio_st_vars			:: ![TIO_TypeVar]
	,	tio_st_args			:: ![TIO_AType]
	,	tio_st_arity		:: !Int
	,	tio_st_result		:: !TIO_AType
	}
	
::	TIO_BasicType	= TIO_BT_Int | TIO_BT_Char | TIO_BT_Real | TIO_BT_Bool | TIO_BT_Dynamic
					| TIO_BT_File | TIO_BT_World
					| TIO_BT_String !TIO_Type /* the internal string type synonym only used to type string denotations */
					
instance toString TIO_BasicType
	
::	TIO_TypeVar =
	{	
		tio_tv_name			:: !Int
	}

::	TIO_ConsVariable = TIO_CV 		!TIO_TypeVar
					 | TIO_TempCV 	!TIO_TempVarId
					 | TIO_TempQCV 	!TIO_TempVarId
					 
::	TIO_TempVarId		:== Int

::	TIO_TypeSymbIdent =
	{	tio_type_name_ref	:: !TIO_TypeReference
	,	tio_type_arity		:: !Int
	}
	
/*
:: TIO_TypeReference
	= TypeWithoutDefinition !String					// see TypeSymbIdentWithoutDefinition, string = name of type
	| TypeWithDefinition !TIO_new_TypeReference		// see TypeSymbIdentWithDefinition
	
instance == TIO_TypeReference

::	TIO_new_TypeReference
	= {
		tio_tr_module_n		:: !Int
	,	tio_tr_type_def_n	:: !Int
	}

instance == TIO_new_TypeReference;
*/

::  TIO_TypeReference
	= {
		tio_type_without_definition  :: !Maybe !String
	,   tio_tr_module_n    			 :: !Int
	,   tio_tr_type_def_n  			 :: !Int
	}
	
instance DefaultElem TIO_TypeReference;

class isTypeWithoutDefinition a :: !a -> !Bool

instance isTypeWithoutDefinition TIO_TypeReference

makeTypeWithoutDefinition :: !String -> !TIO_TypeReference
/*
// created in type_io_static.icl (static linker) and used by dynamic linker.	
makeBuiltinTypeReference :: !Int -> !TIO_TypeReference;
isBuiltinTypeReference :: !TIO_TypeReference -> !Bool;
*/
	
	
/*
:: RTTypeReference 
	= PredefinedType !Int !String					// fst Int is index in cs_type_tables
	| TypeReference !Int !TIO_TypeReference			// fst Int is index in cs_type_tables
	
	
instance == RTTypeReference;
*/

:: TypeTableTypeReference
	= TypeTableTypeReference !Int !TIO_TypeReference
	
instance == TypeTableTypeReference

instance isTypeWithoutDefinition TypeTableTypeReference

:: LibraryInstanceTypeReference 
//	= LIT_PredefinedType !Int !String				// fst Int is index in cs_library_instances
	= LIT_TypeReference !Int !TIO_TypeReference		// fst Int is index in cs_library_instances

instance == LibraryInstanceTypeReference;

instance isTypeWithoutDefinition LibraryInstanceTypeReference

/*
:: TypeLibraryReferenceType
	= {
		tlr_library_instance_i	:: !Int
	,	tlr_type_table_i		:: !Int
	,	tlr_tio_type_reference	:: !TIO_TypeReference
	};
	
instance isTypeWithoutDefinition TypeLibraryReferenceType
*/
		
	/*
// SUPERFLUOUS ...
::	TIO_Priority = TIO_Prio TIO_Assoc Int | TIO_NoPrio

::	TIO_Assoc	= TIO_LeftAssoc | TIO_RightAssoc | TIO_NoAssoc
// ... SUPERFLUOUS
*/

:: 	TIO_Index	:== Int

::	TIO_BITVECT :== Int

::	TIO_FieldSymbol =
	{	tio_fs_name			:: !Int
	,	tio_fs_var			:: !Int				// ?
	,	tio_fs_index		:: !TIO_Index
	}
// FieldSymbol

//collect_type_info :: [String] !Int !*Files -> (!Bool,!*{#TIO_CommonDefs},!*TypeIOState,!*Files)

empty_tio_common_def :: TIO_CommonDefs


:: EquivalentTypeDef
	= { 
		type_name	:: Int							// name of type
	,	partitions	:: !{#{# TIO_TypeReference}}		// grouped definitions by equality of a type with the above name 
	};


//instance DefaultElem {#a}	| ArrayElem, DefaultElem a
instance DefaultElem TIO_SelectorDef
instance DefaultElem TIO_ConsDef
//1.3
instance DefaultElem (TIO_TypeDef TIO_TypeRhs)
//3.1
/*2.0
instance DefaultElem (TIO_TypeDef a) | DefaultElem a
instance DefaultElem TIO_TypeRhs
0.2*/

//read_type_information :: !String !*Files -> (!Bool,!*{#TIO_CommonDefs},!*TypeIOState,!*Files)
:: RTI
	= { 
		rti_n_libraries			:: !Int
	,	rti_library_list		:: !LibraryList
	,	rti_n_library_symbols	:: !Int
	};
default_RTI :: RTI;
	
//read_type_information :: !String !*NamesTable !*Files -> (!Bool,!RTI,!*{#TIO_CommonDefs},!*TypeIOState,!*NamesTable,!*Files)
read_type_information typ_file_name names_table files :== read_type_information_new True typ_file_name names_table files;

read_type_information_new :: !Bool !String !*NamesTable !*Files -> (!Bool,!RTI,!*{#TIO_CommonDefs},!*TypeIOState,!*NamesTable,!*Files)

initialize_type_io_state :: !*{#TIO_CommonDefs} !*TypeIOState -> (!*{#TIO_CommonDefs},!*TypeIOState)

get_name_from_string_table :: !Int !String -> !String

instance DefaultElem (Maybe a)

