! File: TABLES.BLI ! ! This work was supported by the Advanced Research ! Projects Agency of the Office of the Secretary of ! Defense (F44620-73-C-0074) and is monitored by the ! Air Force Office of Scientific Research. ! Module TABLES= Begin Require 'Bliss'; Own UNAMNO : Integer; ! DYNAMIC STORAGE MANAGEMENT ! -------------------------- Global Routine RELFLOW(NODE : Ref GT) : Novalue = Begin Local LSTPTR : Ref FLOLSTPTR; If .NODE[gt_v_flow] Then Begin LSTPTR = .NODE[gt_flow]; RELLST(.LSTPTR[flow_prolog]); RELLST(.LSTPTR[flow_mu]); RELLST(.LSTPTR[flow_epilog]); RELLST(.LSTPTR[flow_postlog]); RELEASESPACE(.LSTPTR,SZ_FLOLIST); NODE[gt_v_flow] = FALSE End End; Global Routine RSTRTREE(NODE : Ref GT) : Novalue = Begin If .NODE Eql T_NODE Then Begin Incr I From 1 To .NODE[gt_argc] Do RSTRTREE(.NODE[gt_argv(.I)]); RELEASESPACE(.NODE,.NODE[gt_argc]+SZ_NODE) End Else If .NODE Geq LOWFLOLSTTYPE Then RELLST(.NODE) End; Global Routine RSTRTHREAD(START : Ref ST) : Novalue = Begin Local SV : Ref ST, NX : Ref ST, LNX; If .START Eql 0 Then Return; While .START Neq .LASTPUR Do Begin SV = .START; START = .START[st_next]; Case SYMPURGE(.SV) From 0 To 2 Of Set [0]: 0; ! DONT RELEASE ANYTHING [1]: RELEASESPACE(.SV,.STSZ[.SV[gt_type]]); [2]: Begin ! ALSO RETURN THREADS & NX LIST If .SV[st_var_chg_list] Neq 0 Then Begin RELLST(.SV[st_var_chg_list]); RELLST(.SV[st_var_use_list]) End; NX = .SV[st_var_next]; If .NX Neq 0 Then Do Begin LNX = .NX[st_var_next]; RELEASESPACE(.NX,.STSZ[.NX[gt_type]]) End Until (NX = .LNX) Eql 0; RELEASESPACE(.SV,.STSZ[.SV[gt_type]]) End Tes End End; !--------------------------------------------------------------- !I. GENERAL: ! ! 1. COMPUTE THE HASH FUNCTION OF THE SET OF CHARACTERS IN "ACCUM". !--------------------------------------------------------------- Routine HASH(S : Ref Vector[,Byte],LEN) = Begin Local N; N = 0; Incr I From 1 To .LEN Do N = .N * 2 + .S[.I-1]; Return .N Mod HTSIZE End; !--------------------------------------------------------------- !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 NT,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 .BLOCKLEVEL 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] = .BLOCKLEVEL; S[gt_type] = .TYPE; 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 INSERTS AN IDENTIFIER INTO THE NAME ! TABLE. ! !II. SPECIFIC: ! ! 1. * ! ! A. HASH THE NAME FOUND IN "ACCUM[0]", AND SAVE ! THE HASH VALUE IN "HSH". ! ! B. GET SPACE FOR A NAME TABLE ENTRY WITH ! "GETSPACE", AND SAVE THE INDEX OF THE ! ENTRY IN "NTE". ! ! C. MAKE THE LINK OF THE NAME TABLE ENTRY ! POINT TO THE FIRST ENTRY HANGING OFF THE ! HASH TABLE. ! ! D. MAKE THE HASH TABLE ENTRY POINT TO THIS NEW ! NAME ENTRY. ! ! E. SAVE THE HASH VALUE IN A NAME ! TABLE ENTRY FIELD. ! ! F. PUT THE NAME IN THE NAME TABLE ENTRY. ! ! G. ZERO THE NAME TABLE ENTRY LINK FIELD, ! WHICH WILL LATER HAVE A GROUP ! OF SYMBOL TABLE ENTRIES HANGING ! OFF IT. ! ! H. RETURN THE INDEX OF THE NAME TABLE ENTRY. !--------------------------------------------------------------- Global Routine NTINSERT(NAME : Ref Vector[,Byte]) = Begin Local N : Integer, HSH : Integer, NTE : Ref NT; N = ch$find_ch(999,.NAME,0) - .NAME; HSH = HASH(.NAME,.N); NTE = GETSPACE(SZ_NAME); NTE[nt_next] = .HT_NAME[.HSH]; HT_NAME[.HSH] = .NTE; NTE[nt_hash] = .HSH; ch$move(.N+1,.NAME,NTE[nt_data]); NTE[nt_symb] = 0; Return .NTE 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],TYPE) = Begin Local N : Integer, NTE : Ref NT; N = ch$find_ch(999,.NAME,0) - .NAME; NTE = .HT_NAME[HASH(.NAME,.N)]; 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 .NTE Eqla 0 Then NTE = NTINSERT(.NAME); If .NTE[nt_symb] Eqla 0 Then STINSERT(.NTE,.TYPE,0); Return .NTE End; End Eludom