! File: TRY.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 TRY= Begin Require 'Bliss'; ! 2. - FITTING ! ! THESE ROUTINES DETERMINE WHETHER IT IS POSSIBLE ! TO PLACE A PARTICULAR TN INTO A PARTICULAR ! LOCATION (REGISTER OR WHATEVER). THE TN'S ALREADY ! ASSIGNED TO A LOCATION ARE REPRESENTED BY A TN-REP ! LIST ASSOCIATED WITH THAT LOCATION. THE 'LIFE SPAN' ! INFO DETERMINED BY THE TL ROUTINES IS USED TO ! DETERMINE THE POSSIBILITY OF FITTING THE TN INTO ! THE LOCATION. ! ! try to fit 'TN' onto list 'LST' Global Routine TRYFIT(TN : Ref GT,LST : Ref TNREPR) = Begin Macro OVERLAPFON= (((.T[tn_fon_fu]-.TN[tn_fon_lu])*(.TN[tn_fon_fu]-.T[tn_fon_lu])) Geq 0) %; Local TR : Ref TNREPR, T : Ref GT, Q : Ref TNREPR; ! loop for each TNREP on the list TR = .LST; Until (TR = .TR[itm_rlink]) Eqla .LST Do Begin T = .TR[tnr_ptr]; ! if 'T' comes completely before 'TN' If .T[tn_lon_lu] Lssu .TN[tn_lon_fu] Then Q = .TR ! if 'T' comes completely after 'TN' Else If .T[tn_lon_fu] Gtru .TN[tn_lon_lu] Then Begin LINK(TNREP(.TN),.Q); TN[tn_bind_list] = .LST; SUCCESS End ! if LON's overlap. check if the FON's overlap also Else If OVERLAPFON Then Begin ! they overlap which is only ok if one permits the other to overlap. If .T[tn_permit] Neqa .TN And .T Neqa .TN[tn_permit] Then FAIL End Else If .T[tn_lon_fu] Lssu .TN[tn_lon_fu] Then Q = .TR End; ! how can we ever get here? FAIL End; ! 3. - OPENING ! ! THESE ROUTINES ALLOW 'OPENING' AND CLOSING ! LOCATIONS. NOTE THAT CLOSING IS ACCOMPLISHED ! BY MAKING IT APPEAR THAT THE LOCATION IS 'IN-USE' ! OVER AN INFINITE LIFE SPAN. ! Global Routine OPENLIST(L : Ref TNREPR) : Novalue = Begin Local BF : Ref GT, BT : Ref GT; BF = GETTN(); BT = GETTN(); ! head of list marker BF[tn_request] = IGREQDB; ! this is a dummy TN BF[tn_lon_fu] = GENESIS; BF[tn_lon_lu] = GENESIS; BF[tn_fon_fu] = GENESIS; BF[tn_fon_lu] = ETERNITY; ! end of list marker BT[tn_request] = IGREQDB; BT[tn_fon_fu] = GENESIS; BT[tn_lon_lu] = ETERNITY; BT[tn_lon_fu] = ETERNITY; BT[tn_fon_lu] = ETERNITY; LINK(TNREP(.BF),.L[itm_llink]); LINK(TNREP(.BT),.L[itm_llink]) End; Global Routine CLOSELIST(LST : Ref TNREPR,WHEN) : Novalue = Begin Local L : Ref GT; ! adjust the LON of the tail LST = .LST[itm_llink]; L = .LST[tnr_ptr]; If .L[tn_lon_fu] Gtr .WHEN Then L[tn_lon_fu] = .WHEN; End; Global Routine REOPEN(LST : Ref TNREPR,ATLON,ATFON) : Novalue = Begin Local L : Ref GT; If Not ISOPEN(.LST) Then Begin OPENLIST(.LST); CLOSELIST(.LST,1) End; ! adjust the old tail marker LST = .LST[itm_llink]; L = .LST[tnr_ptr]; L[tn_lon_lu] = (If .L[tn_lon_fu] Lssu .ATLON Then .ATLON-1 Else .L[tn_lon_fu]); ! create a new tail marker L = GETTN(); L[tn_request] = IGREQDB; ! DUMMY TN L[tn_lon_lu] = ETERNITY; L[tn_fon_lu] = ETERNITY; L[tn_lon_fu] = ETERNITY; L[tn_fon_fu] = GENESIS; LINK(TNREP(.L),.LST) End; ! ! THE FOLLOWING SECTIONS, B-D, DEFINE THE PRIMITIVES ! FOR VARIOUS TYPES OF LOCATIONS WHICH MAY BE USED TO ! HOLD TEMP RESULTS. ! ! ! B. - REGISTERS ! ------------------------------------------------ ! true if 'LST' is one of the register lists Global Routine ISREGLST(LST : Ref TNREPR) = Begin LST = .LST; If .LST Geqa REGS[0] And .LST Leqa REGS[5] Then Return TRUE; Return FALSE End; ! ASSIGN T TO THE SPECIFIC REGISTER R. Global Routine TRYSPREG(T : Ref GT,R : Integer) : Novalue = Begin ! open as necessary If Not ISOPEN(REGS[.R]) Then OPENREG(.R); ! this should work. if not, it was not due to a problem caused by us ! but by the user. If Not TRYFIT(.T,REGS[.R]) Then Begin ERRINFO[0] = .R; WARNEM(0,REGTOOCROWD); T[tn_bind_list] = REGS[.R]; T[tn_type] = BNDREG; T[gt_reg] = .R End End; ! TRY THE OPEN REGISTERS Global Routine TRYOPREG(T : Ref GT) = Begin ! try each register, only considering ones which are open and not reserved. Decr I From 5 To 0 Do If ISOPEN(REGS[.I]) Then If Not .RESERVED<.I,1,0> Then If TRYFIT(.T,REGS[.I]) Then SUCCESS; FAIL End; ! TRY TO OPEN A REGISTER Global Routine TRYCLREG(T : Ref GT) = Begin ! try each register, only considering ones which are closed and not reserved. Incr I From 0 To 5 Do If Not ISOPEN(REGS[.I]) Then If Not .RESERVED<.I,1,0> Then Begin OPENREG(.I); ! how can TRYFIT fail? If TRYFIT(.T,REGS[.I]) Then SUCCESS End; FAIL End; ! C. - STATIC TEMPS ! ------------------------------------------------ ! TRY THE OPEN STATIC TEMPS Global Routine TRYOPSTEMPS(T : Ref GT) = Begin ! loop for each static temporary, looking for one in which it can fit Incr I From 0 To .STEMPS[stk_idx] Do If TRYFIT(.T,STEMPS[stk_item(.I)]) Then SUCCESS; FAIL End; ! OPEN A NEW STATIC TEMP Global Routine TRYCLSTEMPS(T : Ref GT) = Begin Local R : Ref Item; ! create a new static temporary PUSHSTK(STEMPS); R = STEMPS[stk_item(.STEMPS[stk_idx])]; OPENLIST(.R); Return TRYFIT(.T,.R) ! NOTE THIS WILL (SHOULD) ALWAYS WORK End; ! D. - DYNAMIC TEMPS ! ------------------------------------------------ Global Routine TRYSPDYTEMP(T : Ref GT,N : Integer) = Begin If .N Lss 0 Or .N Gtr .DTEMPS[stk_idx] Then FAIL; Return TRYFIT(.T,DTEMPS[stk_item(.N)]) End; Global Routine OPENDYTEMP(T : Ref GT,OLON : Integer,OFON : Integer) : Novalue = Begin Local R : Ref ITEM; ! allocate a new dynamic temporary DTEMPS[stk_idx] = .DTEMPS[stk_idx] + 1; ! if above the highwater mark, null out the list and note the highwater R = DTEMPS[stk_item(.DTEMPS[stk_idx])]; If .DTEMPS[stk_idx] Gtr .DTEMPS[stk_max] Then Begin DTEMPS[stk_max] = .DTEMPS[stk_idx]; NULLLST(.R) End; ! open/reopen this temporary REOPEN(.R,.OLON,.OFON); ! this should work, should it not? TRYFIT(.T,.R); ! dynamics are push types T[tn_type] = BNDPUSH End; Global Routine CLOSEDYTEMPS(TOO : Integer) : Novalue = Begin If .TOO Geq .DTEMPS[stk_idx] Then Return; Decr I From .DTEMPS[stk_idx] To .TOO+1 Do CLOSELIST(DTEMPS[stk_item(.I)],.LON); DTEMPS[stk_idx] = .TOO End; ! TRY THE DYNAMIC TEMPS OPENED BY TLA Global Routine TRYDYTEMPS(T : Ref GT) = Begin Decr I From .DTEMPS[stk_max] To 0 Do If TRYFIT(.T,DTEMPS[stk_item(.I)]) Then SUCCESS; FAIL End; ! ! PREDICATE WHICH DETERMINES WHETHER, IF TEMP-NAME 'TN' ! WERE ALLOCATED TO DYTEMP-LIST 'LST', IT WOULD ALWAYS ! BE ADDRESSED AS '@SP' (RATHER THAN 'N(SP)', WITH N NON-ZERO). ! ! there are three possibilities: ! ! LST is not a dynamic temporary - FALSE ! ! LST is the dynamic temporary highwater mark - TRUE ! ! LST is a dynamic temporary somewhere in the middle - ? Global Routine MUSTBETOP(TN : Ref GT,LST : LSTHDR) = Begin Local MARK, TR : Ref TNREPR, L : Ref LSTHDR, T : Ref GT; ! if 'LST' is at the highwater mark then it always will be If .LST Eql DTEMPS[stk_item(.DTEMPS[stk_max])] Then Return TRUE; ! search for the list and get the next highest list. wouldn't it be ! easier to simply range test 'LST' against 'DTEMPS'? L = 0; Incr I From 1 To .DTEMPS[stk_max] Do If .LST Eql DTEMPS[stk_item(.I-1)] Then Begin L = DTEMPS[stk_item(.I)]; Exitloop End; ! if not a dynamic temp If .L Eqla 0 Then Return FALSE; ! see if the list above 'LST' contains any overlapping TN's MARK = .TN[tn_lon_fu]; TR = .L; Until (TR = .TR[itm_rlink]) Eqla .L Do Begin T = .TR[tnr_ptr]; ! if 'T' comes after or overlaps 'TN' If .T[tn_lon_lu] Gequ .TN[tn_lon_fu] Then Begin ! if 'T' comes after 'TN' then why are we returning FALSE? does this ! not mean that no TN's were found below 'LST' and so it must be a ! highwater mark at the time? If .T[tn_lon_fu] Gtru .TN[tn_lon_lu] Then Return FALSE; ! if an overlap of LON's then fail. ! won't this be true the second time round? If .T[tn_lon_fu] Gtru .MARK Then Return FALSE; ! anything other than an ignore request is bad If .T[tn_request] Neq IGREQDB Then Return FALSE; MARK = .T[tn_lon_lu]; If .MARK Gequ .TN[tn_lon_lu] Then Return TRUE End End; Return FALSE End; End Eludom