<> <> <> DIRECTORY AMModel USING [CharIndex], AMModelPrivate USING [EPI, FGIndex, FGNull, NullPCOffset, PCOffset], BrandXSymbolDefs USING [SymbolTableBase, BodyTableEntry, FineGrainTableEntry, rootBodyIndex, BodyIndex, nullBodyIndex], BrandYSymbolDefs USING [SymbolTableBase, BodyTableEntry, FineGrainTableEntry, rootBodyIndex, BodyIndex, nullBodyIndex], RTSymbolDefs USING [SymbolTableBase]; <> AMModelPrivateImpl: PROGRAM EXPORTS AMModelPrivate = BEGIN OPEN AMModel, AMModelPrivate, bx: BrandXSymbolDefs, by: BrandYSymbolDefs, RTSymbolDefs; <> XBodyPtr: TYPE = LONG POINTER TO bx.BodyTableEntry; YBodyPtr: TYPE = LONG POINTER TO by.BodyTableEntry; EPIndex: TYPE = AMModelPrivate.EPI; FGCard: TYPE = CARDINAL; XFGPtr: TYPE = LONG POINTER TO bx.FineGrainTableEntry; YFGPtr: TYPE = LONG POINTER TO by.FineGrainTableEntry; <> fudge: INT _ 8; -- number of characters to assume beyond the last fgi in a procedure <> FGIToEPI: PUBLIC PROC [stb: SymbolTableBase, fgi: FGIndex] RETURNS [EPIndex] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[FGIToEPIX[t.e, fgi]]; t: SymbolTableBase.y => RETURN[FGIToEPIY[t.e, fgi]]; ENDCASE => ERROR; }; FGIToEPIX: PROC [stb: bx.SymbolTableBase, fgi: FGIndex] RETURNS [epi: EPIndex _ 0] = { <> <<(0 for start proc OR invalid fgi)>> IF fgi # FGNull THEN { bti: bx.BodyIndex = FGItoBTIX[stb, fgi]; IF bti # bx.nullBodyIndex THEN { body: XBodyPtr _ @stb.bb[bti]; WITH ext: body^ SELECT FROM Callable => epi _ ext.entryIndex; ENDCASE => RETURN; }; }; }; FGIToEPIY: PROC [stb: by.SymbolTableBase, fgi: FGIndex] RETURNS [epi: EPIndex _ 0] = { <> <<(0 for start proc OR invalid fgi)>> IF fgi # FGNull THEN { bti: by.BodyIndex = FGItoBTIY[stb, fgi]; IF bti # by.nullBodyIndex THEN { body: YBodyPtr _ @stb.bb[bti]; WITH ext: body^ SELECT FROM Callable => epi _ ext.entryIndex; ENDCASE => RETURN; }; }; }; EPIToFirstFGI: PUBLIC PROC [stb: SymbolTableBase, epi: EPIndex, skipArgs: BOOL] RETURNS [FGIndex] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[EPIToFirstFGIX[t.e, epi, skipArgs]]; t: SymbolTableBase.y => RETURN[EPIToFirstFGIY[t.e, epi, skipArgs]]; ENDCASE => ERROR; }; EPIToFirstFGIX: PROC [stb: bx.SymbolTableBase, epi: EPIndex, skipArgs: BOOL] RETURNS [fgi: FGIndex _ FGNull] = { <> bti: bx.BodyIndex _ EPItoBTIX[stb, epi]; IF bti = bx.nullBodyIndex THEN RETURN; WITH info: stb.bb[bti].info SELECT FROM External => { body: XBodyPtr _ @stb.bb[bti]; fgi _ [fgCard: info.startIndex, fudge: FALSE]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; tpc: PCOffset _ 0; FOR tfgi: FGCard IN [firstFGI..lastFGI] DO fp: XFGPtr _ @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => { fgi.fgCard _ tfgi; IF NOT skipArgs THEN RETURN; skipArgs _ FALSE; }; ENDCASE; ENDLOOP; fgi.fudge _ TRUE; }; ENDCASE; }; ENDCASE; }; EPIToFirstFGIY: PROC [stb: by.SymbolTableBase, epi: EPIndex, skipArgs: BOOL] RETURNS [fgi: FGIndex _ FGNull] = { <> bti: by.BodyIndex _ EPItoBTIY[stb, epi]; IF bti = by.nullBodyIndex THEN RETURN; WITH info: stb.bb[bti].info SELECT FROM External => { body: XBodyPtr _ @stb.bb[bti]; fgi _ [fgCard: info.startIndex, fudge: FALSE]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; tpc: PCOffset _ 0; FOR tfgi: FGCard IN [firstFGI..lastFGI] DO fp: YFGPtr _ @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => { fgi.fgCard _ tfgi; IF NOT skipArgs THEN RETURN; skipArgs _ FALSE; }; ENDCASE; ENDLOOP; fgi.fudge _ TRUE; }; ENDCASE; }; ENDCASE; }; EPIToLastFGI: PUBLIC PROC [stb: SymbolTableBase, epi: EPIndex] RETURNS [FGIndex] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[EPIToLastFGIX[t.e, epi]]; t: SymbolTableBase.y => RETURN[EPIToLastFGIY[t.e, epi]]; ENDCASE => ERROR; }; EPIToLastFGIX: PROC [stb: bx.SymbolTableBase, epi: EPIndex] RETURNS [fgi: FGIndex _ FGNull] = { <> <<(FGNull for invalid epi)>> bti: bx.BodyIndex _ EPItoBTIX[stb, epi]; IF bti = bx.nullBodyIndex THEN RETURN; WITH info: stb.bb[bti].info SELECT FROM External => fgi _ [fgCard: info.startIndex + MAX[info.indexLength, 1] - 1, fudge: TRUE]; ENDCASE; }; EPIToLastFGIY: PROC [stb: by.SymbolTableBase, epi: EPIndex] RETURNS [fgi: FGIndex _ FGNull] = { <> <<(FGNull for invalid epi)>> bti: by.BodyIndex _ EPItoBTIY[stb, epi]; IF bti = by.nullBodyIndex THEN RETURN; WITH info: stb.bb[bti].info SELECT FROM External => fgi _ [fgCard: info.startIndex + MAX[info.indexLength, 1] - 1, fudge: TRUE]; ENDCASE; }; EPIToFirstPC: PUBLIC PROC [stb: SymbolTableBase, epi: EPIndex, skipArgs: BOOL] RETURNS [PCOffset] = { fgi: FGIndex _ EPIToFirstFGI[stb, epi, skipArgs]; IF fgi = FGNull THEN RETURN [NullPCOffset]; RETURN [FGIToFirstPC[stb, fgi]]; }; EPIToLastPC: PUBLIC PROC [stb: SymbolTableBase, epi: EPIndex] RETURNS [PCOffset] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[EPIToLastPCX[t.e, epi]]; t: SymbolTableBase.y => RETURN[EPIToLastPCY[t.e, epi]]; ENDCASE => ERROR; }; EPIToLastPCX: PROC [stb: bx.SymbolTableBase, epi: EPIndex] RETURNS [pc: PCOffset _ NullPCOffset] = { <> bti: bx.BodyIndex _ EPItoBTIX[stb, epi]; IF bti = bx.nullBodyIndex THEN RETURN; WITH info: stb.bb[bti].info SELECT FROM External => {pc _ info.bytes; pc _ pc - 1}; ENDCASE; }; EPIToLastPCY: PROC [stb: by.SymbolTableBase, epi: EPIndex] RETURNS [pc: PCOffset _ NullPCOffset] = { <> bti: by.BodyIndex _ EPItoBTIY[stb, epi]; IF bti = by.nullBodyIndex THEN RETURN; WITH info: stb.bb[bti].info SELECT FROM External => {pc _ info.bytes; pc _ pc - 1}; ENDCASE; }; CharIndexToFGI: PUBLIC PROC [stb: SymbolTableBase, ci: CharIndex] RETURNS [FGIndex] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[CharIndexToFGIX[t.e, ci]]; t: SymbolTableBase.y => RETURN[CharIndexToFGIY[t.e, ci]]; ENDCASE => ERROR; }; CharIndexToFGIX: PROC [stb: bx.SymbolTableBase, ci: CharIndex] RETURNS [fgi: FGIndex _ FGNull] = { <> bti: bx.BodyIndex _ CItoBTIX[stb, ci]; IF bti # bx.nullBodyIndex THEN { body: XBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; thisCI: CharIndex _ body.sourceIndex; adjust: CharIndex _ 0; fgi _ [fgCard: firstFGI, fudge: FALSE]; FOR tfgi: FGCard IN [firstFGI..lastFGI] DO fp: XFGPtr _ @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => { adjust _ adjust + deltaSource; IF adjust # 0 THEN { fgi.fgCard _ tfgi; thisCI _ thisCI+adjust; IF thisCI > ci THEN RETURN; adjust _ 0; }; }; step => IF which = source THEN adjust _ adjust + delta; ENDCASE; ENDLOOP; fgi.fudge _ TRUE; }; ENDCASE; }; }; CharIndexToFGIY: PROC [stb: by.SymbolTableBase, ci: CharIndex] RETURNS [fgi: FGIndex _ FGNull] = { <> bti: by.BodyIndex _ CItoBTIY[stb, ci]; IF bti # by.nullBodyIndex THEN { body: YBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; thisCI: CharIndex _ body.sourceIndex; adjust: CharIndex _ 0; fgi _ [fgCard: firstFGI, fudge: FALSE]; FOR tfgi: FGCard IN [firstFGI..lastFGI] DO fp: YFGPtr _ @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => { adjust _ adjust + deltaSource; IF adjust # 0 THEN { fgi.fgCard _ tfgi; thisCI _ thisCI+adjust; IF thisCI > ci THEN RETURN; adjust _ 0; }; }; step => IF which = source THEN adjust _ adjust + delta; ENDCASE; ENDLOOP; fgi.fudge _ TRUE; }; ENDCASE; }; }; PCToFGI: PUBLIC PROC [stb: SymbolTableBase, epi: EPIndex, pc: PCOffset] RETURNS [FGIndex] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[PCToFGIX[t.e, epi, pc]]; t: SymbolTableBase.y => RETURN[PCToFGIY[t.e, epi, pc]]; ENDCASE => ERROR; }; PCToFGIX: PROC [stb: bx.SymbolTableBase, epi: EPIndex, pc: PCOffset] RETURNS [fgi: FGIndex _ FGNull] = { <> <<(FGNull for invalid epi or invalid pc)>> bti: bx.BodyIndex _ EPItoBTIX[stb, epi]; IF bti # bx.nullBodyIndex THEN { body: XBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; rem: INT _ pc; IF pc >= info.bytes THEN RETURN [FGNull]; fgi _ [fgCard: firstFGI, fudge: FALSE]; FOR tfgi: FGCard IN [firstFGI..lastFGI] DO fp: XFGPtr _ @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => { rem _ rem - deltaObject; fgi.fgCard _ tfgi; IF rem < 0 THEN RETURN; }; step => IF which = object THEN rem _ rem - delta; ENDCASE; ENDLOOP; fgi.fudge _ TRUE; }; ENDCASE; }; }; PCToFGIY: PROC [stb: by.SymbolTableBase, epi: EPIndex, pc: PCOffset] RETURNS [fgi: FGIndex _ FGNull] = { <> <<(FGNull for invalid epi or invalid pc)>> bti: by.BodyIndex _ EPItoBTIY[stb, epi]; IF bti # by.nullBodyIndex THEN { body: YBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; rem: INT _ pc; IF pc >= info.bytes THEN RETURN [FGNull]; fgi _ [fgCard: firstFGI, fudge: FALSE]; FOR tfgi: FGCard IN [firstFGI..lastFGI] DO fp: YFGPtr _ @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => { rem _ rem - deltaObject; fgi.fgCard _ tfgi; IF rem < 0 THEN RETURN; }; step => IF which = object THEN rem _ rem - delta; ENDCASE; ENDLOOP; fgi.fudge _ TRUE; }; ENDCASE; }; }; NextFGI: PUBLIC PROC [stb: SymbolTableBase, fgi: FGIndex, epi: EPIndex] RETURNS [FGIndex] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[NextFGIX[t.e, fgi, epi]]; t: SymbolTableBase.y => RETURN[NextFGIY[t.e, fgi, epi]]; ENDCASE => ERROR; }; NextFGIX: PROC [stb: bx.SymbolTableBase, fgi: FGIndex, epi: EPIndex] RETURNS [nfgi: FGIndex _ FGNull] = { <> <> <> bti: bx.BodyIndex; IF fgi = FGNull OR fgi.fudge THEN RETURN; bti _ EPItoBTIX[stb, epi]; IF bti # bx.nullBodyIndex THEN WITH info: stb.bb[bti].info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; IF fgi.fudge OR fgi.fgCard NOT IN [firstFGI..lastFGI] THEN RETURN; IF fgi.fgCard = lastFGI THEN fgi.fudge _ TRUE ELSE fgi.fgCard _ fgi.fgCard + 1; nfgi _ fgi; }; ENDCASE; }; NextFGIY: PROC [stb: by.SymbolTableBase, fgi: FGIndex, epi: EPIndex] RETURNS [nfgi: FGIndex _ FGNull] = { <> <> <> bti: by.BodyIndex; IF fgi = FGNull OR fgi.fudge THEN RETURN; bti _ EPItoBTIY[stb, epi]; IF bti # by.nullBodyIndex THEN WITH info: stb.bb[bti].info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; IF fgi.fgCard NOT IN [firstFGI..lastFGI] THEN RETURN; IF fgi.fgCard = lastFGI THEN fgi.fudge _ TRUE ELSE fgi.fgCard _ fgi.fgCard + 1; nfgi _ fgi; }; ENDCASE; }; FGIToFirstChar: PUBLIC PROC [stb: SymbolTableBase, fgi: FGIndex] RETURNS [CharIndex] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[FGIToFirstCharX[t.e, fgi]]; t: SymbolTableBase.y => RETURN[FGIToFirstCharY[t.e, fgi]]; ENDCASE => ERROR; }; FGIToFirstCharX: PROC [stb: bx.SymbolTableBase, fgi: FGIndex] RETURNS [ci: CharIndex _ -1] = { <> <<-1 for invalid fgi>> bti: bx.BodyIndex _ FGItoBTIX[stb, fgi]; IF bti # bx.nullBodyIndex THEN { body: XBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { stop: FGCard = IF fgi.fudge THEN fgi.fgCard + 1 ELSE fgi.fgCard; tci: CharIndex _ ci _ body.sourceIndex; FOR tfgi: FGCard _ info.startIndex, tfgi + 1 DO IF tfgi >= stop THEN EXIT ELSE { fp: XFGPtr _ @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => ci _ tci _ tci + deltaSource; step => IF which = source THEN tci _ tci + delta; ENDCASE; }; ENDLOOP; }; ENDCASE; }; }; FGIToFirstCharY: PROC [stb: by.SymbolTableBase, fgi: FGIndex] RETURNS [ci: CharIndex _ -1] = { <> <<-1 for invalid fgi>> bti: by.BodyIndex _ FGItoBTIY[stb, fgi]; IF bti # by.nullBodyIndex THEN { body: YBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { stop: FGCard = IF fgi.fudge THEN fgi.fgCard + 1 ELSE fgi.fgCard; tci: CharIndex _ ci _ body.sourceIndex; FOR tfgi: FGCard _ info.startIndex, tfgi + 1 DO IF tfgi >= stop THEN EXIT ELSE { fp: YFGPtr _ @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => ci _ tci _ tci + deltaSource; step => IF which = source THEN tci _ tci + delta; ENDCASE; }; ENDLOOP; }; ENDCASE; }; }; FGIToLastChar: PUBLIC PROC [stb: SymbolTableBase, fgi: FGIndex] RETURNS [CharIndex] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[FGIToLastCharX[t.e, fgi]]; t: SymbolTableBase.y => RETURN[FGIToLastCharY[t.e, fgi]]; ENDCASE => ERROR; }; FGIToLastCharX: PROC [stb: bx.SymbolTableBase, fgi: FGIndex] RETURNS [ci: CharIndex _ -1] = { <> <<-1 for invalid fgi>> bti: bx.BodyIndex _ FGItoBTIX[stb, fgi]; IF bti # bx.nullBodyIndex THEN { body: XBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; ci _ body.sourceIndex; FOR tfgi: FGCard IN [firstFGI..fgi.fgCard] DO fp: XFGPtr _ @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => ci _ ci + deltaSource; step => IF which = source THEN ci _ ci + delta; ENDCASE; ENDLOOP; IF fgi.fudge THEN ci _ ci + fudge --XXX ELSE ci _ ci - 1; }; ENDCASE; }; }; FGIToLastCharY: PROC [stb: by.SymbolTableBase, fgi: FGIndex] RETURNS [ci: CharIndex _ -1] = { <> <<-1 for invalid fgi>> bti: by.BodyIndex _ FGItoBTIY[stb, fgi]; IF bti # by.nullBodyIndex THEN { body: YBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; ci _ body.sourceIndex; FOR tfgi: FGCard IN [firstFGI..fgi.fgCard] DO fp: YFGPtr _ @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => ci _ ci + deltaSource; step => IF which = source THEN ci _ ci + delta; ENDCASE; ENDLOOP; IF fgi.fudge THEN ci _ ci + fudge --XXX ELSE ci _ ci - 1; }; ENDCASE; }; }; FGIToFirstPC: PUBLIC PROC [stb: SymbolTableBase, fgi: FGIndex] RETURNS [PCOffset] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[FGIToFirstPCX[t.e, fgi]]; t: SymbolTableBase.y => RETURN[FGIToFirstPCY[t.e, fgi]]; ENDCASE => ERROR; }; FGIToFirstPCX: PROC [stb: bx.SymbolTableBase, fgi: FGIndex] RETURNS [pc: PCOffset _ NullPCOffset] = { <> bti: bx.BodyIndex _ FGItoBTIX[stb, fgi]; IF bti # bx.nullBodyIndex THEN { body: XBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { stop: FGCard = IF fgi.fudge THEN fgi.fgCard+1 ELSE fgi.fgCard; tpc: PCOffset _ pc _ 0; pending: BOOL _ TRUE; FOR tfgi: FGCard _ info.startIndex, tfgi + 1 DO IF tfgi >= stop THEN EXIT ELSE { fp: XFGPtr = @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => { tpc _ tpc + deltaObject; IF pending OR deltaSource # 0 THEN {pc _ tpc; pending _ FALSE}; }; step => IF which = object THEN tpc _ tpc + delta ELSE pending _ TRUE; ENDCASE; }; ENDLOOP; }; ENDCASE; }; }; FGIToFirstPCY: PROC [stb: by.SymbolTableBase, fgi: FGIndex] RETURNS [pc: PCOffset _ NullPCOffset] = { <> bti: by.BodyIndex _ FGItoBTIY[stb, fgi]; IF bti # by.nullBodyIndex THEN { body: YBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { stop: FGCard = IF fgi.fudge THEN fgi.fgCard+1 ELSE fgi.fgCard; tpc: PCOffset _ pc _ 0; pending: BOOL _ TRUE; FOR tfgi: FGCard _ info.startIndex, tfgi + 1 DO IF tfgi >= stop THEN EXIT ELSE { fp: YFGPtr = @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => { tpc _ tpc + deltaObject; IF pending OR deltaSource # 0 THEN {pc _ tpc; pending _ FALSE}; }; step => IF which = object THEN tpc _ tpc + delta ELSE pending _ TRUE; ENDCASE; }; ENDLOOP; }; ENDCASE; }; }; FGIToLastPC: PUBLIC PROC [stb: SymbolTableBase, fgi: FGIndex] RETURNS [PCOffset] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[FGIToLastPCX[t.e, fgi]]; t: SymbolTableBase.y => RETURN[FGIToLastPCY[t.e, fgi]]; ENDCASE => ERROR; }; FGIToLastPCX: PROC [stb: bx.SymbolTableBase, fgi: FGIndex] RETURNS [pc: PCOffset _ NullPCOffset] = { <> <<(NullPCOffset for invalid fgi)>> bti: bx.BodyIndex _ FGItoBTIX[stb, fgi]; IF bti # bx.nullBodyIndex THEN { body: XBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; IF fgi.fudge THEN {pc _ INT[info.bytes] - 1; RETURN}; pc _ 0; FOR tfgi: FGCard IN [firstFGI..fgi.fgCard] DO fp: XFGPtr _ @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => pc _ pc + deltaObject; step => IF which = object THEN pc _ pc + delta; ENDCASE; ENDLOOP; pc _ pc - 1; }; ENDCASE; }; }; FGIToLastPCY: PROC [stb: by.SymbolTableBase, fgi: FGIndex] RETURNS [pc: PCOffset _ NullPCOffset] = { <> <<(NullPCOffset for invalid fgi)>> bti: by.BodyIndex _ FGItoBTIY[stb, fgi]; IF bti # by.nullBodyIndex THEN { body: YBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; IF fgi.fudge THEN {pc _ INT[info.bytes] - 1; RETURN}; pc _ 0; FOR tfgi: FGCard IN [firstFGI..fgi.fgCard] DO fp: YFGPtr _ @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => pc _ pc + deltaObject; step => IF which = object THEN pc _ pc + delta; ENDCASE; ENDLOOP; pc _ pc - 1; }; ENDCASE; }; }; <> EPItoBTIX: PROC[stb: bx.SymbolTableBase, epi: EPIndex] RETURNS [outerBti: bx.BodyIndex _ bx.nullBodyIndex] = { <> <> <> innerEPItoBTI: PROC [bti: bx.BodyIndex] RETURNS [stop: BOOL _ FALSE] = { body: XBodyPtr _ @stb.bb[bti]; thisEPI: EPIndex _ 0; WITH ext: body^ SELECT FROM Callable => thisEPI _ ext.entryIndex; ENDCASE => RETURN; WITH info: body.info SELECT FROM External => IF epi = thisEPI THEN {outerBti _ bti; stop _ TRUE}; ENDCASE; }; [] _ stb.EnumerateBodies[bx.rootBodyIndex, innerEPItoBTI]; }; EPItoBTIY: PROC[stb: by.SymbolTableBase, epi: EPIndex] RETURNS [outerBti: by.BodyIndex _ by.nullBodyIndex] = { <> <> <> innerEPItoBTI: PROC [bti: by.BodyIndex] RETURNS [stop: BOOL _ FALSE] = { body: YBodyPtr _ @stb.bb[bti]; thisEPI: EPIndex _ 0; WITH ext: body^ SELECT FROM Callable => thisEPI _ ext.entryIndex; ENDCASE => RETURN; WITH info: body.info SELECT FROM External => IF epi = thisEPI THEN {outerBti _ bti; stop _ TRUE}; ENDCASE; }; [] _ stb.EnumerateBodies[by.rootBodyIndex, innerEPItoBTI]; }; FGItoBTIX: PROC [stb: bx.SymbolTableBase, fgi: FGIndex] RETURNS [outerBti: bx.BodyIndex _ bx.nullBodyIndex] = { <> <> <> innerFGItoBTI: PROC [bti: bx.BodyIndex] RETURNS [stop: BOOL _ FALSE] = { body: XBodyPtr _ @stb.bb[bti]; thisEPI: EPIndex _ 0; WITH ext: body^ SELECT FROM Callable => thisEPI _ ext.entryIndex; ENDCASE => RETURN; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; IF fgi.fgCard IN [firstFGI..lastFGI] THEN { outerBti _ bti; stop _ TRUE}; }; ENDCASE; }; [] _ stb.EnumerateBodies[bx.rootBodyIndex, innerFGItoBTI]; }; FGItoBTIY: PROC [stb: by.SymbolTableBase, fgi: FGIndex] RETURNS [outerBti: by.BodyIndex _ by.nullBodyIndex] = { <> <> <> innerFGItoBTI: PROC [bti: by.BodyIndex] RETURNS [stop: BOOL _ FALSE] = { body: YBodyPtr _ @stb.bb[bti]; thisEPI: EPIndex _ 0; WITH ext: body^ SELECT FROM Callable => thisEPI _ ext.entryIndex; ENDCASE => RETURN; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; IF fgi.fgCard IN [firstFGI..lastFGI] THEN { outerBti _ bti; stop _ TRUE}; }; ENDCASE; }; [] _ stb.EnumerateBodies[by.rootBodyIndex, innerFGItoBTI]; }; CItoBTIX: PROC [stb: bx.SymbolTableBase, ci: CharIndex] RETURNS [bestBTI: bx.BodyIndex _ bx.nullBodyIndex] = { <> <> bestCI: CharIndex _ 0; <> <> bti1: bx.BodyIndex _ bx.nullBodyIndex; fgi1: FGCard _ 0; ci1: CharIndex _ 0; <= ci. Note that ci2 is the character index before fgi2 has been applied.>> bti2: bx.BodyIndex _ bx.nullBodyIndex; fgi2: FGCard _ 0; ci2: CharIndex _ 0; innerCItoBTI: PROC [bti: bx.BodyIndex] RETURNS [stop: BOOL _ FALSE] = { body: XBodyPtr _ @stb.bb[bti]; WITH ext: body^ SELECT FROM Callable => NULL; ENDCASE => RETURN; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; thisCI: CharIndex _ body.sourceIndex; -- the first sourceIndex of this Callable body lastCI: CharIndex _ thisCI; -- the first sourceIndex of the current statement FOR tfgi: FGCard IN [firstFGI..lastFGI] DO fp: XFGPtr _ @stb.fgTable[tfgi]; <<>> <= ci>> IF (lastCI < ci2 OR bti2 = bx.nullBodyIndex) AND lastCI >= ci THEN { bti2 _ bti; fgi2 _ tfgi; ci2 _ lastCI; }; WITH fp^ SELECT FROM normal => lastCI _ lastCI + deltaSource; step => IF which = source THEN lastCI _ lastCI + delta; ENDCASE; <> IF (lastCI >= ci1 OR bti1 = bx.nullBodyIndex) AND lastCI < ci THEN {bti1 _ bti; fgi1 _ tfgi; ci1 _ lastCI}; ENDLOOP; }; ENDCASE; }; [] _ stb.EnumerateBodies[bx.rootBodyIndex, innerCItoBTI]; bestBTI _ bti1; IF bti1 # bti2 THEN { IF ci = ci2 OR bti1 = bx.nullBodyIndex THEN bestBTI _ bti2; }; }; CItoBTIY: PROC [stb: by.SymbolTableBase, ci: CharIndex] RETURNS [bestBTI: by.BodyIndex _ by.nullBodyIndex] = { <> <> bestCI: CharIndex _ 0; <> <> bti1: by.BodyIndex _ by.nullBodyIndex; fgi1: FGCard _ 0; ci1: CharIndex _ 0; <= ci. Note that ci2 is the character index before fgi2 has been applied.>> bti2: by.BodyIndex _ by.nullBodyIndex; fgi2: FGCard _ 0; ci2: CharIndex _ 0; innerCItoBTI: PROC [bti: by.BodyIndex] RETURNS [stop: BOOL _ FALSE] = { body: YBodyPtr _ @stb.bb[bti]; WITH ext: body^ SELECT FROM Callable => NULL; ENDCASE => RETURN; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; thisCI: CharIndex _ body.sourceIndex; -- the first sourceIndex of this Callable body lastCI: CharIndex _ thisCI; -- the first sourceIndex of the current statement FOR tfgi: FGCard IN [firstFGI..lastFGI] DO fp: YFGPtr _ @stb.fgTable[tfgi]; <<>> <= ci>> IF (lastCI < ci2 OR bti2 = by.nullBodyIndex) AND lastCI >= ci THEN { bti2 _ bti; fgi2 _ tfgi; ci2 _ lastCI; }; WITH fp^ SELECT FROM normal => lastCI _ lastCI + deltaSource; step => IF which = source THEN lastCI _ lastCI + delta; ENDCASE; <> IF (lastCI >= ci1 OR bti1 = by.nullBodyIndex) AND lastCI < ci THEN {bti1 _ bti; fgi1 _ tfgi; ci1 _ lastCI}; ENDLOOP; }; ENDCASE; }; <<>> [] _ stb.EnumerateBodies[by.rootBodyIndex, innerCItoBTI]; bestBTI _ bti1; IF bti1 # bti2 THEN { IF ci = ci2 OR bti1 = by.nullBodyIndex THEN bestBTI _ bti2; }; }; END.