! File: TABLES.BLI ! Module TABLES = Begin Require 'Bliss'; Own UNAMNO : Integer; ! DYNAMIC STORAGE MANAGEMENT ! -------------------------- !--------------------------------------------------------------- !I. GENERAL: ! ! 1. THIS ROUTINE CREATES A SYMBOL TABLE ENTRY AT THE ! CURRENT BLOCK AND FUNCTION LEVELS. ! ! 2. THE NAME TABLE ENTRY IS ALWAYS MADE BY THIS POINT, ! AND WE WILL HANG THIS NEW SYMBOL TABLE ENTRY ! OFF THE NAME TABLE ENTRY CORRESPONDING TO IT. ! ! 3. PARAMETERS: ! ! A. NTI - NAME TABLE INDEX OF SYMBOL. ! ! B. TYPE - TYPE OF THE SYMBOL ! ! C. ADDINFO - CONTENTS TO BE ADDED TO THE ! ADDITIONAL INFORMATION FIELD OF ! THE ENTRY WHEN CREATED. ! ! 5. LOCALS: ! ! A. STE - INDEX OF THE SPACE FOR THE SYMBOL TABLE ! ENTRY BEING CREATED. ! ! B. STSIZE - SIZE IN WORDS OF THE SYMBOL TABLE ENTRY ! !II. SPECIFIC: ! ! 1. * ! ! A. GET THE HASH VALUE FOR THE SYMBOL. ! ! B. GET SPACE FOR THE ENTRY TO BE CREATED. ! ! C. MAKE THE LINK OF THE SYMBOL TABLE ENTRY ! POINT TO THE CLOSEST ENTRY HANGING OFF THE ! NAME TABLE. ! ! D. IN TURN, MAKE THE NAME TABLE ENTRY LINK ! FIELD NOW POINT TO THIS NEW ENTRY. ! ! E. GO DOWN THE HASH TABLE ENTRY THREAD AND FIND ! THE POINT AFTER WHICH THIS SYMBOL SHOULD BE ! ENTERED. ! ! F. MAKE THAT THREAD FIELD POINT TO THIS SYMBOL ! TABLE ENTRY, AND MAKE THIS ENTRY'S THREAD FIELD ! EQUAL TO THE OLD VALUE OF THAT THREAD FIELD. ! ! G. MAKE THE NAME POINTER FIELD OF THE SYMBOL ! TABLE ENTRY POINT TO THE NAME TABLE ENTRY ! WHICH IT HANGS OFF. ! ! H. GIVE THE BLOCK LEVEL FIELD ! OF THE SYMBOL TABLE ENTRY THE CORRECT ! VALUE. ! ! I. ADD THE CORRECT TYPE TO THE TYPE FIELD. ! ! J. ADD THE CORRECT ADDITIONAL INFORMATION WORD. ! ! K. SET LINKAGE NAME TO THE DEFAULT NAME. !--------------------------------------------------------------- Global Routine STINSERT(NTI : Ref GT,TYPE,ADDINFO)= Begin Macro NEWUNAME = (UNAMNO = .UNAMNO+1) %; Local S : Ref ST, L : Ref ST, N : Integer, M : Ref ST, STSIZE : Integer; STSIZE = .STSZ[.TYPE]; S = GETSPACE(.STSIZE); S[st_prev] = .NTI[nt_symb]; NTI[nt_symb] = .S; M = 0; L = .HT_THREAD[.NTI[nt_hash]]; Until .L Eqla 0 Or .L[st_scope] Leq .level_block Do Begin M = .L; L = .L[st_next] End; If .M Eql 0 Then HT_THREAD[.NTI[nt_hash]] = .S Else M[st_next] = .S; S[st_next] = .L; S[st_name] = .NTI; S[st_scope] = .level_block; S[st_code] = .TYPE; S[st_type] = T_SYMBOL; ! this must be a hack If .STSIZE Geq 6 Then Begin S[st_v_unique] = .swit_unames; S[st_unique] = NEWUNAME; S[st_v_debug] = .swit_debug End; If .TYPE Neq S_UNDECLARE Then S[st_which] = .ADDINFO; Return .S End; !--------------------------------------------------------------- !I. GENERAL: ! ! 1. THIS ROUTINE SEARCHES FOR THE SYMBOL IN "ACCUM", AND ! INSERTS IT IF NECESSARY. ! !II. SPECIFIC: ! ! 1. * ! ! A. HASH THE SYMBOL, AND PICK UP THE HASH TABLE ! LINK INTO THE LIST OF NAME TABLE ENTRIES ! HANGING OFF IT. ! ! B. LOOK DOWN THE LIST OF NAME TABLE ENTRIES ! UNTIL: ! ! 1. WE FIND THE SYMBOL. THEN RETURN THE ! VALUE OF ITS INDEX. ! ! 2. WE COME TO THE END OF THE NAME ! TABLE LIST. ! ! C. IF WE EXIT ABOVE BY COMMING TO THE ! END OF A NAME TABLE LIST, THEN CALL ! "NTINSERT" TO INSERT THE NAME INTO THE ! NAME TABLE. THEN WE INSERT THIS ! INTO THE SYMBOL TABLE WITH THE ! REQUESTED TYPE FIELD. ! ! D. FINALLY, RETURN WITH THE INDEX ! INTO THE NAME TABLE. !--------------------------------------------------------------- Global Routine SEARCH(NAME : Ref Vector[,Byte]) = Begin Local N : Integer, NTE : Ref GT, HSH : Integer; ! get the length of the name N = ch$find_ch(999,.NAME,0) - .NAME; ! compute the hash index HSH = 0; Incr I From 1 To .N Do HSH = .HSH * 2 + .NAME[.I-1]; HSH = .HSH Mod HTSIZE; ! search for an existing matching name NTE = .HT_NAME[.HSH]; While .NTE Neqa 0 Do Begin If CH$EQL(.N+1,.NAME,.N+1,NTE[nt_data]) Then Exitloop; NTE = .NTE[nt_next] End; ! if not found, enter a new name If .NTE Eqla 0 Then Begin NTE = GETSPACE(SZ_NAME(.N)); NTE[nt_type] = T_NAME; NTE[nt_next] = .HT_NAME[.HSH]; HT_NAME[.HSH] = .NTE; NTE[nt_hash] = .HSH; NTE[nt_symb] = 0; ch$move(.N+1,.NAME,NTE[nt_data]) End; Return .NTE End; End Eludom