Module Misc = Begin ! miscellaneous routines Require 'bliss.req'; Global Routine strcmp(s : Ref Vector[,Byte],t : Ref Vector[,Byte]) = Begin While .s[0] Eql .t[0] Do Begin If .s[0] Eql 0 Then Return TRUE; s = .s + 1; t = .t + 1 End; Return FALSE End; Global Routine strlen(s : Ref Vector[,Byte]) = Begin Return ch$find_ch(999,.s,0) - .s End; Global Routine FIRSTONE(N : Integer) = Begin If .N Eql 0 Then Return -1; Incr I From 0 To 63 Do If .N<.I,1> Then Return .I; Return -1 End; Global Routine MatchMinorWord(t : Ref Vector) = Begin Local S : Ref GT; If .SYM Eql NIL Then Begin S = .dtpf[.OLDDELI]; If .S Eqla 0 Then Return -1 End Else If .SYM[gt_type] Neq T_NAME Then Return -1 Else S = .SYM; Incr i From 0 To .t[-1] Do If strcmp(.t[.i],s[nt_data]) Then Return -i; Return -1 End; Global Routine Ctce = Begin Local N : Integer, pos : Integer; pos = .pos_sym; EXPRESSION(); SYM = BINDBIND(.SYM); If .SYM[gt_type] Neq T_LITERAL Then Begin WARNEM(.pos,B11$_WANT_CTCE); N = 0 End Else N = .SYM[gt_disp]; FreeSym(); Return .n End; ! SYMPURGE RETURNS TRUE IF THE SYMBOL MAY BE PURGED. IN ! ADDITION IT RELEASES ALL FIELDS (STREAMS AND ! TREES ASSOCIATED WITH THE FIELDS WITHIN THE SYMBOL. Global Routine FreeSymbol(S : Ref ST) : Novalue = Begin Local p : Ref Vector, v : Ref GT; Selectone .S[st_code] Of Set [S_MACRO]: stream_release(.S[st_mac_body]); [S_STRUCTURE]: Begin stream_release(.S[st_str_body]); If .S[st_str_alloc] Neqa 0 Then stream_release(.S[st_str_alloc]) End; [S_FORWARD]: WARNEM(0,B11$_FORWARD_ROUTINE,.S); [S_LOCAL,S_REGISTER,S_FORMAL,S_OWN,S_EXTERNAL,S_GLOBAL]: Begin If .S[st_var_actuals] Neqa 0 And Not .S[st_v_no_acts] And .S[st_v_release_acts] Then Begin p = .S[st_var_actuals]; RELEASESPACE(.p,SZ_STREAM(.p[strm_size])) End; If .S[st_v_init] And .S[st_v_release_init] Then FreeNode(.S[st_var_init]); If .S[st_var_chg_list] Neq 0 Then Begin FreeList(.S[st_var_chg_list]); FreeList(.S[st_var_use_list]) End; While .S[st_var_next] Neqa 0 Do Begin v = .S[st_var_next]; S[st_var_next] = .v[st_var_next]; RELEASESPACE(.v,.STSZ[.v[st_code]]) End End Tes; RELEASESPACE(.S,.STSZ[.S[st_code]]) End; ! release the flow lists for a node Global Routine RELFLOW(NODE : Ref GT) : Novalue = Begin Local LSTPTR : Ref FLOLSTPTR; If .NODE[gt_v_flow] Then Begin LSTPTR = .NODE[gt_flow]; FreeList(.LSTPTR[flow_prolog]); FreeList(.LSTPTR[flow_mu]); FreeList(.LSTPTR[flow_epilog]); FreeList(.LSTPTR[flow_postlog]); RELEASESPACE(.LSTPTR,SZ_FLOLIST); NODE[gt_v_flow] = FALSE End End; ! release a tree Global Routine RSTRTREE(NODE : Ref GT) : Novalue = Begin If .NODE[gt_type] Eql T_NODE Then Begin Incr I From 1 To .NODE[gt_argc] Do RSTRTREE(.NODE[gt_argv(.I)]); RELEASESPACE(.NODE,SZ_NODE(.NODE[gt_argc])) End Else If .NODE[gt_type] Eql T_QUEUE Then Begin FreeList(.NODE[que_head]); RELEASESPACE(.NODE,SZ_QUEUE) End End; ! release a list of symbols Global Routine FreeSymbolList(START : Ref ST) : Novalue = Begin Local SV : Ref ST; If .START Eql 0 Then Return; While .START Neq .LASTPUR Do Begin SV = .START; START = .START[st_next]; FreeSymbol(.sv) End; End; Global Routine FreeNode(p : Ref GT) : Novalue = Begin Case .p[gt_type] From LO_TAG_TYPE To HI_TAG_TYPE Of Set [T_LITERAL]: RELEASESPACE(.p,SZ_NODE(0)); [T_VARIABLE]: RELEASESPACE(.p,SZ_NODE(0)); [T_NODE]: Begin Incr i From 0 To .p[gt_argc]-1 Do FreeNode(.p[gt_argv(.i)]); RELEASESPACE(.p,SZ_NODE(.p[gt_argc])) End; [T_QUEUE]: Begin FreeList(.p[que_head]); RELEASESPACE(.p,SZ_QUEUE) End; [T_NAME]: 0; [T_SYMBOL]: 0; [T_PLIT]: Begin If .p[pl_next] Neqa 0 Then FreeNode(.p[pl_next]); FreeNode(.p[pl_data]); RELEASESPACE(.p,SZ_PLIT) End; [Inrange,Outrange]: Punt(999) Tes End; Global Routine FreeSym : Novalue = Begin FreeNode(.SYM); SYM = NIL End; Global Routine RaiseChild(p : Ref GT,I : Integer) = Begin Local r : Ref GT; r = .p[gt_argv(.i)]; p[gt_argv(.i)] = NIL; FreeNode(.p); Return .r End; End Eludom