{ History ------- 13/02/86 - Add call to EpDiscard to dispose address descriptor in Closewtih. New include file impint.pf } { MODULE 21 With Statements The set of records addressed by currently open with-statements is held as a 'with-stack', pointed to by the variable TopWithEntry, and maintained by the procedures OpenWith and CloseWith. OpenWith creates an extended reference to the record variable, generates code if necessary to save its address in temporary storage, and pushes a new entry onto the with-stack holding the variable reference and a unique 'with-base' key generated by the analyser. Subsequent calls to WithReference use the key value supplied by the analyser to locate the corresponding reference in the with- stack, and re-create it on the operand/reference stack for use by the subsequent call to FieldReference. At the end of a with-statement the procedure CloseWith releases any locks set by the extended reference and pops the with-stack. } program WithStatements; #include "globals.x" #include "varref.pf" #include "codeutils.pf" #include "impint.pf" procedure OpenWith(WithBase: DispRange); visible; var LocalBase: StackEntry; ThisEntry: WithEntry; begin if CodeIsToBeGenerated then begin new(ThisEntry); with ThisEntry^ do begin BaseNum := WithBase; Pop(LocalBase); SaveAddress(LocalBase); Entry := LocalBase; Next := TopWithEntry end; TopWithEntry := ThisEntry end end { openwith }; procedure WithReference(WithBase: DispRange); visible; var BaseEntry: WithEntry; NewBase: StackEntry; begin if CodeIsToBeGenerated then begin BaseEntry := TopWithEntry; while BaseEntry^.BaseNum <> WithBase do BaseEntry := BaseEntry^.Next; GetEntry(NewBase); NewBase^ := BaseEntry^.Entry^; Push(NewBase) end end { withreference }; procedure CloseWith; visible; var ThisEntry: WithEntry; begin if CodeIsToBeGenerated then begin ThisEntry := TopWithEntry; with ThisEntry^ do begin with Entry^ do if Kind = Address then if not Loaded then EpDiscard(Descriptor); FreeEntry(Entry); TopWithEntry := Next end; dispose(ThisEntry) end end { closewith }; procedure InitWith; visible; begin TopWithEntry := nil end; begin { end of module } end.