implementation module NamesTable; import StdArray, StdEnum; //1.3 from StdString import String; from StdInt import ==,<<,>>,bitxor,bitand; from StdClass import inc,+,one; //3.1 from StdMisc import abort; /*2.0 import StdEnv; 0.2*/ from ExtString import BYTE; :: *NamesTable :== SNamesTable; :: SNamesTable :== {!NamesTableElement}; :: NamesTableElement = NamesTableElement !String !Int !Int !NamesTableElement // symbol_name symbol_n file_n symbol_list | EmptyNamesTableElement; isEmptyNamesTableElement :: !.NamesTableElement -> !Bool; isEmptyNamesTableElement EmptyNamesTableElement = True; isEmptyNamesTableElement _ = False; SYMBOL_TABLE_SIZE:==4096; SYMBOL_TABLE_SIZE_MASK:==4095; //import DebugUtilities; create_names_table :: NamesTable; create_names_table = createArray SYMBOL_TABLE_SIZE EmptyNamesTableElement; //import DebugUtilities; FB a b c :== c; insert_symbol_in_symbol_table :: !String Int Int !NamesTable -> NamesTable; insert_symbol_in_symbol_table symbol_name symbol_n file_n names_table // =:{[symbol_hash]=symbol_list} #! symbol_hash=symbol_name_hash symbol_name; #! (symbol_list,names_table) = names_table![symbol_hash]; | FB (symbol_name == "qd") ("insert_symbol_in_symbol_table: " +++ symbol_name +++ " - " +++ toString symbol_n +++ " - " +++ toString file_n) True // | symbol_name == "qd" // = abort ("insert_symbol_in_symbol_table" +++ toString file_n +++ " - " +++ toString symbol_n); | /* F (symbol_name +++ " - " +++ toString symbol_n +++ " - " +++ toString file_n)*/ symbol_n == (-1) = abort "insert_symbol_in_symbol_table"; | symbol_in_symbol_table_list symbol_list = names_table; = {names_table & [symbol_hash] = NamesTableElement symbol_name symbol_n file_n symbol_list}; where { symbol_in_symbol_table_list EmptyNamesTableElement = False; symbol_in_symbol_table_list (NamesTableElement string _ _ symbol_table_list) | string==symbol_name = True; = symbol_in_symbol_table_list symbol_table_list; } import RWSDebugChoice; find_symbol_in_symbol_table :: !String !NamesTable -> (!NamesTableElement,!NamesTable); find_symbol_in_symbol_table symbol_name names_table //=:{[symbol_hash]=symbol_list} // # (s_names_table,names_table) // = usize names_table; // | True <<- ("find_symbol_in_symbol_table", symbol_name, s_names_table) // # (s_names_table,names_table) // = usize names_table; // # names_table // = names_table <<- ("find_symbol_in_symbol_table",symbol_name,symbol_name_hash symbol_name,s_names_table) # (symbol_list,names_table) = names_table![symbol_hash]; = (symbol_in_symbol_table_list symbol_list,names_table); { symbol_hash=symbol_name_hash symbol_name; symbol_in_symbol_table_list EmptyNamesTableElement = EmptyNamesTableElement; symbol_in_symbol_table_list names_table_element=:(NamesTableElement string _ _ symbol_table_list) | string==symbol_name = names_table_element; = symbol_in_symbol_table_list symbol_table_list; } symbol_name_hash symbol_name = (simple_hash symbol_name 0 0) bitand SYMBOL_TABLE_SIZE_MASK; { simple_hash string index value | index== size string = value; = simple_hash string (inc index) (((value<<2) bitxor (value>>10)) bitxor (string BYTE index)); } //find_symbol_in_symbol_table_new :: !String !*s -> (!NamesTableElement,!*s); find_symbol_in_symbol_table_new :: .{#Char} .(Int -> .(.a -> (NamesTableElement,.a))) .a -> (NamesTableElement,.a); find_symbol_in_symbol_table_new symbol_name select1 s //=:{[symbol_hash]=} # (symbol_list,s) = select1 symbol_hash s; = (symbol_in_symbol_table_list symbol_list,s); { symbol_hash=symbol_name_hash symbol_name; symbol_in_symbol_table_list EmptyNamesTableElement = EmptyNamesTableElement; symbol_in_symbol_table_list names_table_element=:(NamesTableElement string _ _ symbol_table_list) | string==symbol_name = names_table_element; = symbol_in_symbol_table_list symbol_table_list; } split_symbol_list_in_symbol_table :: .{#Char} .(Int -> .(.a -> (u:NamesTableElement,.b))) .a -> ((Int,Int,Int,v:NamesTableElement),.b), [u <= v]; split_symbol_list_in_symbol_table symbol_name select1 s # (symbol_list,s) = select1 symbol_hash s; = (symbol_in_symbol_table_list EmptyNamesTableElement symbol_list,s); { symbol_hash=symbol_name_hash symbol_name; symbol_in_symbol_table_list left EmptyNamesTableElement = abort ("split_symbol_list_in_symbol_table; internal error; symbol '" +++ symbol_name +++ "' not found"); symbol_in_symbol_table_list left names_table_element=:(NamesTableElement string symbol_n file_n right) | string==symbol_name = (symbol_hash,file_n,symbol_n,concat left right); //names_table_element; #! new_left = NamesTableElement string symbol_n file_n left; = symbol_in_symbol_table_list new_left right; concat EmptyNamesTableElement accu = accu; concat (NamesTableElement s i1 i2 rest) accu = concat rest (NamesTableElement s i1 i2 accu); /* :: NamesTableElement = NamesTableElement !String !Int !Int !NamesTableElement // symbol_name symbol_n file_n symbol_list | EmptyNamesTableElement; */ } MergeNamesTables :: !NamesTable !NamesTable -> !NamesTable; MergeNamesTables names_table1 names_table2 = { (merge names_table_element1 names_table_element2) \\ names_table_element1 <-: names_table1 & names_table_element2 <-: names_table2 }; where { merge :: !NamesTableElement !NamesTableElement -> !NamesTableElement; merge names_table_element1 EmptyNamesTableElement = names_table_element1; merge names_table_element1 (NamesTableElement symbol_name symbol_n file_n more_names_table_elements) | name_in_names_table_list names_table_element1 = abort ("MergeNamesTables: double defined symbols" +++ symbol_name); = merge (NamesTableElement symbol_name symbol_n file_n names_table_element1) more_names_table_elements; where { name_in_names_table_list EmptyNamesTableElement = False; name_in_names_table_list (NamesTableElement string _ _ names_table_list) | string == symbol_name = True; = name_in_names_table_list names_table_list } }