{ MODULE 20 Assignment Code Generation Assignment code is generated by the procedures Assign and AssignTag. For normal assignments the procedure Assign distin- guishes the following cases: (a) assignment of entire conformant arrays is carried out by the special P-code MoveCAP, using the conformant array value representation generated by the LoadCAP operation within the expression tree; (b) assignment of addressable multiword values is carried out by the store-to-store P-code, Move; (c) assignment of evaluated sets or multiword values is carried out by the P-codes StoreSet or StoreMultiple; (d) assignment of word or part-word variables is carried out by loading and storing the value concerned, using the most effi- cient storage P-codes available. Tagfield assignment is different in that, if checks have been requested or the variant part involved contains an embedded file, a call must be generated to the selector-updating procedure within the augmented representation. Otherwise normal assignment code is used. } program AssignCode; #include "globals.x" #include "varref.pf" #include "codeutils.pf" #include "pfcalls.pf" procedure Assign ( VarRep: TypeRepresentation ); visible; var Expression, Variable: StackEntry; SetVariable, CheckNeeded: Boolean; function AString(Entry: StackEntry): Boolean; begin with Entry^ do if Kind <> AConstant then AString := false else AString := TheConst.Kind = StringValue end { astring }; begin if CodeIsToBeGenerated then begin Pop(Expression); Pop(Variable); if VarRep.Kind = ForCAP then begin Load(Expression); LoadAddress(Variable); {Pcode0(MoveCAP)} end else if (VarRep.WordSize > 1) or (VarRep.Kind = ForSet) then with Expression^ do if (Kind in [Reference, Address]) or AString(Expression) then begin if Kind = Reference then CheckNeeded := (Expression^.RunError <> 0) else CheckNeeded := false; LoadAddress(Expression); {if CheckNeeded then CheckLoadedValue(Expression);} LoadAddress(Variable); {with VarRep do if (Kind = ForVntRecord) and (Checks in Requested) then begin Pcode0(SampleAndPurge); Pcode1(Move, WordSize - 1) end else Pcode1(Move, WordSize)} end else begin Load(Expression); LoadAddress(Variable); {if VarRep.Kind = ForSet then Pcode1(StoreSet, VarRep.WordSize) else Pcode1(StoreMultiple, VarRep.WordSize)} end else begin Load(Expression); with Variable^ do if PartOfWord then begin LoadAddress(Variable); {if OnByteBoundary then Pcode0(StoreByte) else Pcode0(StorePacked)} end else if Indexed or Indirect or (AccessList <> nil) then begin LoadAddress(Variable); {Pcode0(StoreIndirect)} end else with BaseAddress do AccessWord (BlockLevel, WordOffset + Adjustment, StoreOp) end; FreeEntry(Expression); FreeEntry(Variable) end end { assign }; procedure AssignTag ( SelectorRep: TypeRepresentation ); var RecordEntry, TagEntry, Expression: StackEntry; CodeOfBody: BlockLabel; begin if CodeIsToBeGenerated then if SelectorRep.CheckCode.EntryOffset <> 0 then begin Pop(Expression); Pop(TagEntry); RecordEntry := TagEntry^.AccessList; CodeOfBody := SelectorRep.CheckCode; StackActualBlock(CodeOfBody); OpenParameterList(Proc); Push(RecordEntry); PassReference(Secure); Push(Expression); PassValue(Expression^.DataRep); CloseParameterList; CallBlock; FreeEntry(TagEntry) end else Assign(SelectorRep) end { assigntag }; begin { end of module } end.