{ CHAPTER 2 Global Definitions and Declarations Because of the rigid order of definitions and declarations imposed by Pascal, this chapter contains all of the global definitions and declarations on which the procedures in the subsequent chapters depend. In this chapter, only a brief indication of the overall nature of the constants, types and variables introduced is given, together with a reference to the chapter in which they are used. A more detailed explanation of the nature and purpose of each is given in the referenced chapter itself. } label { The source-handler procedure ReadNextLine uses this global } { label to recover from an unexpected end of program file. The } { compiler reports error:- } { } { 421 : fatal error: unexpected end of program file. } { Compilation aborted. } { } { and control is transferred to procedure EndListing where } { the listing file is concluded in the usual way. } 13 ; const {*************************************************************************} {*************************************************************************} {****** ******} {****** ******} {****** Host Installation ******} {****** ----------------- ******} {****** ******} {****** ******} {****** 1. Investigate how your host Pascal processor implements ******} {****** the packed-variable:- ******} {****** ******} {****** HostWord : packed array[HostWordSize] of HostBit ******} {****** ******} {****** If HostWord[0] is mapped onto the most significant bit ******} {****** position, then set the constant IndexedFromLeft to the ******} {****** value true. Otherwise, set it to false. ******} {****** ******} {****** 2. Redefine the constants prefixed 'MC' for the host ******} {****** machine. ******} {****** ******} {****** ******} {*************************************************************************} {*************************************************************************} IndexedFromLeft = false ; { for host Pascal compiler } {*************************************************************************} {****** constants used by the source program analyser ******} {*************************************************************************} { constants used by the option-handler, chapter 3 } Level0 = 0 ; { conform to ISO 7185, level 0 } Level1 = 1 ; { conform to ISO 7185, level 1 } OptionFlag = '$' ; { introduce option-list } OptionSize = 12 ; { size of string below } UnknownOption = ' ' ; { denotes unknown option } FileWarning = '*Option error: error file not available.' ; { constants used by the source handler, chapter 4 } BannerTitleSize = 40 ; { length of banner titles below } SiteName = ' your site name ' ; ProgName = 'Model Pascal Compiler - UMIST/BSI Vv.r ' ; VerNumPos = 36 ; { position of ^ this 'v' } RelNumPos = 38 ; { position of ^ this 'r' } VerNum = 4 ; { model pascal compiler version } RelNum = 0 ; { model pascal compiler release } LineMax = 121 ; { maximum source line } StartCode = 0 ; { analysis error code base } MaxCode = 499 ; { total error range: 0..499 } AnalysisBase = StartCode ; { analysis errors: 1..300 } PredictedBase = 300 ; { runtime errors: 301..400 } SystemBase = 400 ; { system limit errors: 401..420 } FatalBase = 420 ; { fatal errors: 421..450 } OptionBase = 450 ; { option errors: 451..460 } LinesPerText = 2 ; { lines per error text } { constant used by the diagnostics handler, chapter 6 } NilSerial = 0 ; { unallocated serial number } { constants used by the lexical analyser, chapter 7 } NoWords = 47 ; { upper bound of word symbol table } AlfaSize = 12 ; { size of alfa header string } ChunkLength = 4 ; { size of trailing alfa chunks } DefaultSpelling = '????????????' ; { default alfa header } { constants used in semantic analysis, chapter 9 } DispLimit = 20 ; { upper bound of display } GlobalLevel = 1 ; { scope level of program block } {*************************************************************************} {****** constants used by the object program generator ******} {*************************************************************************} { constants describing the model P-machine } MCBitsPerWord = 32 ; { bits per memory-word } MCWordSetBits = 31 ; { bits per set-word } MCBitsPerByte = 8 ; { bits per memory-byte } MCBytesPerWord = 4 ; { mcbitsperword div mcbitsperbyte } MCMaxBitNum = 31 ; { mcbitsperword-1 } MCMaxSetBit = 30 ; { mcwordsetbits-1 } MCMaxByteNum = 3 ; { mcbytesperword-1 } MCMaxint = 2147483647 ; { max mc-integer value } MCMaxDigits = 10 ; { digits in mcmaxint } MCMaxintDiv10 = 214748364 ; { mcmaxint div 10 } MCMaxintMod10 = 7 ; { mcmaxint mod 10 } MCRealSize = 1 ; { real size in words } MCMaxHalfWord = 65535 ; { max unsigned half word value } MCMaxByte = 255 ; { max mc-byte value } MCUndefinedChar= 255 ; { 'undefined' character value } MCMaxChar = 255 ; { max mc-char value } MCMaxSet = 256 ; { maximum members per set } MCMaxMemWord = 16383 ; { max memory-word address } {*************************************************************************} {****** P-machine instruction set ******} {*************************************************************************} {*************************************************************************} {****** group 1 - constant instructions. ******} {*************************************************************************} { inline constants } ConstShort = 0 ; ConstWord = 32 ; ConstMultiple = 34 ; ConstRefMultiple = 36 ; ConstSet = 38 ; {*************************************************************************} {****** group 2 - word acessing instructions. ******} {*************************************************************************} { local block } { global block } { enclosing block } LoadShort = 40 ; LoadGlobal = 70 ; LoadEnclosing = 76 ; LoadLocal = 48 ; LoadRefGlobal = 72 ; LoadRefEnclosing = 78 ; LoadRShort = 50 ; StoreGlobal = 74 ; StoreEnclosing = 80 ; LoadRefLocal = 58 ; StoreShort = 60 ; StoreLocal = 68 ; { intermediate block } { indirect access } { packed field access } LoadIntermediate = 82 ; LoadIndirect = 88 ; LoadBit = 109 ; LoadRefIntermediate=84 ; IndexShort = 89 ; LoadPacked = 110 ; StoreIntermediate =86 ; Index = 96 ; StoreBit = 111 ; IndexRef = 98 ; StorePacked = 112 ; IndexCAP = 100 ; IndexPackedRef = 113 ; StoreIndirect = 101 ; IndexPackdCAP = 114 ; AdjustPlus = 102 ; IndexSubWord = 115 ; AdjustP1 = 104 ; AdjustPackedRef = 116 ; AdjustMinus = 105 ; AdjustM1 = 107 ; AddAddress = 108 ; { byte access } { multiple word access} LoadByte = 117 ; LoadMultiple = 121 ; StoreByte = 118 ; StoreMultiple = 123 ; LoadByteRef = 119 ; StoreRepeated = 125 ; IndexByteRef = 120 ; Move = 127 ; SizeCAP = 129 ; MoveCAP = 130 ; DuplicateCAP = 131 ; ReleaseCAP = 132 ; {*************************************************************************} {****** group 3 - top of stack operations. ******} {*************************************************************************} { logical operations } { scalar operations } { integer comparisons } AndOperation = 133 ; Increment = 135 ; TestIEqual = 150 ; NotOperation = 134 ; Inc1 = 137 ; TestIUnequal = 151 ; Decrement = 138 ; TestILess = 152 ; Dec1 = 140 ; TestILtOrEqual = 153 ; AbsInteger = 141 ; NegateInteger = 142 ; SquareInteger = 143 ; AddInteger = 144 ; SubInteger = 145 ; MultInteger = 146 ; DivInteger = 147 ; ModInteger = 148 ; OddInteger = 149 ; { value checks } { scalar range checks } { real operations } CheckTopValue = 154 ; CheckLimits = 156 ; Float = 160 ; CheckTopDefined = 155 ; CheckLower = 157 ; AbsReal = 161 ; CheckUpper = 158 ; NegateReal = 162 ; CheckCAP = 159 ; SquareReal = 163 ; AddReal = 164 ; SubtractReal = 165 ; MultiplyReal = 166 ; DivideReal = 167 ; { transfer functions } { real comparisons } { pointer operations } TruncateReal = 168 ; TestREqual = 170 ; LoadPointer = 174 ; RoundReal = 169 ; TestRUnequal = 171 ; TestPEqual = 175 ; TestRLess = 172 ; TestPUnequal = 176 ; TestRLtOrEqual = 173 ; { string operations } { set operations } { set comparisons } TestSEqual = 177 ; LoadSet = 181 ; TestSetEqual = 189 ; TestSUnequal = 178 ; StoreSet = 182 ; TestSetUnequal = 190 ; TestSLess = 179 ; MakeSingletonSet = 183 ; TestSubset = 191 ; TestSLtOrEqual = 180 ; MakeRangeSet = 184 ; InSet = 192 ; SetUnion = 185 ; CheckSetLimits = 193 ; SetIntersection = 186 ; CheckSetUpper = 194 ; SetDifference = 187 ; SetExpand = 188 ; {*************************************************************************} {****** group 4 - jumps. ******} {*************************************************************************} { simple jumps } { false jumps } { special jumps } JumpForward = 195 ; FJumpForward = 199 ; FJumpConditional = 202 ; JumpBack = 196 ; FJumpBack = 200 ; TJumpConditional = 203 ; JumpVia = 197 ; FJumpVia = 201 ; CaseJump = 204 ; JumpOut = 198 ; {*************************************************************************} {****** group 5 - block calls. ******} {*************************************************************************} { block entry } { block exit } MarkStack = 205 ; EndProcedure = 211 ; CallGlobal = 206 ; EndFunction = 212 ; CallLocal = 207 ; EndMultiFunction = 213 ; Callevel = 208 ; CallOuter = 209 ; CallForml = 210 ; {*************************************************************************} {****** group 6 - store management. ******} {*************************************************************************} { dynamic allocation } New1 = 214 ; Dispose1 = 216 ; CheckNew1 = 218 ; CheckDsp1 = 219 ; CheckDsp2 = 220 ; {*************************************************************************} {****** group 7 - specials. ******} {*************************************************************************} { special operations } NoOperation = 221 ; PresetWord = 222 ; PresetRepeated = 223 ; LoadStack = 225 ; DuplicateStack = 226 ; PopStack = 227 ; CheckWord = 228 ; CheckRepeated = 229 ; CheckVntField = 230 ; TrapError = 231 ; TrapIfTrue = 232 ; TrapIfFalse = 233 ; SetLock = 234 ; DiscardLocks = 235 ; PurgeLocks = 236 ; SampleAndPurge = 237 ; HaltProgram = 238 ; JumpDest = 239 ; LoadFmlP = 240; CaseStart = 241 ; CaseLab = 242 ; TraceLine = 254 ; Escape = 255 ; {*************************************************************************} {****** group 8 - class 2 (escaped) operations. ******} {*************************************************************************} { input-output } { transfer procedures } { arithmetic functions} CheckReadMode = 256 ; Pack = 276 ; Sine = 280 ; CheckWriteMode = 257 ; Packc = 277 ; Cosine = 281 ; RewriteFile = 258 ; Unpack = 278 ; NaturalExp = 282 ; ResetFile = 259 ; Unpackc = 279 ; NaturalLog = 283 ; EndOfLine = 260 ; SquareRoot = 284 ; EndOfFile = 261 ; ArcTangent = 285 ; GetFile = 262 ; ReadInteger = 263 ; ReadReal = 264 ; ReadLine = 265 ; PutFile = 266 ; WriteCharacter = 267 ; WriteBoolean = 268 ; WriteCString = 269 ; WriteInteger = 270 ; WriteFloatedReal = 271 ; WriteFixedReal = 272 ; WriteLine = 273 ; PageFile = 274 ; CloseFile = 275 ; { program parameters } MapProgParam = 286 ; MaxPcode = 286 ; {*************************************************************************} {****** end of instruction set ******} {*************************************************************************} { constants used by the code-file emitter, chapter 15 } MaxPcodeByte = 255 ; { logical byte capacity - 1 } DataWordLimit = 1023 ; { control data buffer upper bound } CodeWordLimit = 2047 ; { code buffer upper bound } CodeByteLimit = 8191 ; { codewordlimit*mcbytesperword + } { mcbytesperword - 1 } { control data table header layout } ParamsOffset = 0 ; { [codebase-1] = parameter size } LocalsOffset = 1 ; { [codebase-2] = stack size } LocksOffset = 2 ; { [codebase-3] = lock stack size } SerialOffset = 3 ; { [codebase-4] = 0/pmd block serial } HeaderSize = 4 ; { control data header size } { stack frame layout } FirstOffset = 0 ; { first available frame offset } FrameSize = 6 ; { stack-frame header size } { constants used by the object-program generator, chapters 12-28 } FileSize = 5 ; { file-variable size } CAPBpSize = 3 ; { conformant array parameter } { bound pair block size } DefaultBufferSize = 64 ; { default file-buffer word size } BufferVarOffset = 2 ; { buffer-variable offset in text } { file variable } MaxLevels = 9 ; { max variant nesting level } MaxCaseGap =256 ; { max permissable discontinuity } { in case label values } LockSize = 3 ; { size of lock-stack entry } FileLockOffset = 1 ; { file lock word offset } FileLockBit = 0 ; { file lock bit posititon } HeapLockOffset = -2 ; { heap lock word offset } HeapLockBit = MCMaxBitNum ; { heap lock bit position } type {*************************************************************************} {****** types used by the source program analyser ******} {*************************************************************************} { types applied globally } HostWord = integer ; Scalar = 0..maxint ; DeclKind = ( Predefined,Declared ) ; StdProcFuncs = (Getp,Putp,Resetp,Rewritep, Readp,Writep,Readlnp,Writelnp,Pagep, Newp,Disposep,Packp,Unpackp, Absf,Sqrf,Oddf,Succf,Predf,Ordf,Chrf,Truncf,Roundf, Sinf,Cosf,Expf,Lnf,Sqrtf,Arctanf, Eoff,Eolnf) ; TypeForm = (Scalars,SubRanges,Pointers,Arrays,CAPSchema, Records,Sets,Files,VariantPart,Variant) ; SetForms = ( Unpacked,IsPacked,Constructed ) ; IdClass = ( Domain,Types,Consts,Vars,Bound,Field,Proc,Func,Prog ) ; { types describing the model P-machine } MCBit = 0..1 ; MCByte = 0..MCMaxByte ; MCHalfWord = 0..MCmaxHalfWord ; MCWord = HostWord ; { target=host } MCScalar = 0..MCMaxint ; MCIntegerForm = HostWord ; { MC-integer-space: target=host } MCRealForm = real ; { MC-real-space: target=host } MCCharSet = 0..MCMaxChar ; MCBitRange = 0..MCBitsPerWord ; MCBitIndex = 0..MCMaxBitNum ; MCSetBits = 0..MCMaxSetBit ; MCBitArray = packed array[MCBitIndex] of MCBit ; MCByteIndex = 0..MCMaxByteNum ; MCByteArray = packed array[MCByteIndex] of MCByte ; MCWordSet = set of MCSetBits ; WordCast = ( AsSet,AsBits,AsBytes,AsReal,AsValue,AsLabel ) ; MCWordForm = packed record case WordCast of AsSet : ( WSet : MCWordSet ) ; AsBits : ( WBits : MCBitArray ) ; AsBytes : ( WBytes : MCByteArray ) ; AsReal : ( WReal : MCRealForm ) ; AsValue : ( WValue : MCWord ) ; AsLabel : ( Linked : Boolean ; Address : MCScalar ) end ; WordRange = 0..MCMaxMemWord ; DataRange = 0..DataWordLimit ; CodeRange = 0..CodeWordLimit ; CodeByteRange = 0..CodeByteLimit ; WordEntry = ^ ListWord ; ListWord = record Word : MCWordForm ; Next : WordEntry end ; { types used by the option-handler, chapter 3 } OptionContext = ( Locally,Globally ) ; OptionClass = ( BoolClass,IntClass ) ; OptionType = ( Listing,CodeDump,Checks,PMDump, Level,Programs,Margin,Other ) ; BoolOptions = Listing..PMDump ; IntOptions = Level..Margin ; OptionIndex = 1..OptionSize ; OptionString = packed array[OptionIndex] of char ; SetOfOptions = set of OptionType ; { types used by the source-handler, chapter 4 } BannerPositions = 1..BannerTitleSize ; BannerString = packed array[BannerPositions] of char ; AlfaIndex = 1..AlfaSize ; ErrorSpan = 0..MaxCode ; LinePosition = 1..LineMax ; TextPosition = record LineNumber : Scalar ; CharNumber : LinePosition end ; ErrorEntry = ^ErrorRec ; ErrorRec = record ErrorCode : ErrorSpan ; ErrorPosition : TextPosition ; Next : ErrorEntry end ; ErrorList = record First,Last : ErrorEntry end ; SourceLine = record Line : array [LinePosition] of char ; FirstLine,BlankLine : Boolean ; FirstRead,FirstNonBlank,LastNonBlank, LastSignificant : LinePosition ; Position : TextPosition ; ListingInProgress : Boolean ; ErrorsToReport,ErrorStarted : Boolean ; ErrorsOnThisLine,EarlierErrors : ErrorList end ; CodeAddress = Scalar ; { types used by the object-program generator interface, chapter 5 } ValueKind = ( OrdValue,IntValue,BoolValue,CharValue,RealValue, SetValue,StringValue,PntrValue ) ; ObjectValue = record WordSize : WordRange ; case Kind : ValueKind of OrdValue, IntValue, BoolValue, CharValue : ( Ival : MCIntegerForm ) ; RealValue : ( Rval : MCRealForm ) ; SetValue : ( Setval : WordEntry ) ; StringValue : ( Length : MCScalar ; Stringval : WordEntry ) ; PntrValue : ( Pval : WordEntry ) end ; ValueDetails = record Velue : ObjectValue ; case Kind : ValueKind of OrdValue : ( Ival : integer ) ; IntValue, BoolValue, CharValue, RealValue, SetValue, StringValue: ( Length : 0..LineMax ; String : packed array [1..LineMax] of char) ; PntrValue : ( ) end ; AddressLevel = 0..DispLimit ; RuntimeAddress = packed record BlockLevel : AddressLevel ; WordOffset : WordRange end ; FieldLevel = Scalar ; FieldOffset = packed record WordOffset : WordRange ; Level : FieldLevel ; case PartWord : Boolean of false : ( WordSize : WordRange ) ; true : ( BitSize : MCBitRange ; BitOffset : MCBitIndex ) end ; BlockLabel = packed record BlockLevel : AddressLevel ; EntryOffset : MCHalfWord end ; StatementLabel = BlockLabel ; RepKind = ( ForScalar,ForSet,ForArray,ForARecord,ForVntRecord, ForFile,ForPnter,ForVariant,ForSelector,ForCAP,ForReal, ForString,ForOther ); MachineValue = packed record Multiple : Scalar ; case Defined : Boolean of false : ( ) ; true : ( Magnitude : MCIntegerForm ) end ; TypeRepresentation = packed record WordSize : WordRange ; BitSize : MCBitRange ; Kind : RepKind ; CheckValue : MachineValue ; Min,Max : MCIntegerForm ; PresetCode,PostsetCode,CheckCode : BlockLabel ; Selector : FieldOffset end ; JumpType = ( IfFalse,IfTrue,IfFalseConditional,IfTrueConditional, Absolute ); FixUpEntry = ^ FixUpRecord ; FixUpRecord = record JumpKind : JumpType ; JumpAddress : CodeByteRange ; Next : FixUpEntry end ; CodeLabel = record Linked : Boolean ; LinkIndex : MCHalfWord ; case Expected : Boolean of false : ( Address : CodeByteRange ) ; true : ( LastReference : FixUpEntry ) end ; StackTop = (TopOfStack,NextToTop) ; FileModes = ( Inspection,Generation ) ; OutputKind = (IntKind,RealKind,CharKind,BoolKind, StringKind,DefaultKind ) ; InputKind = IntKind..CharKind ; FormatKind = (Default,Floating,Fixed) ; { types used by the diagnostics handler, chapter 6 } SerialRange = Scalar ; { types used by the lexical analyser, chapter 7 } SymbolType = (Ident,IntConst,RealConst,CharConst,StringConst,NilSy, NotSy,MulOp,AddOp,RelOp, LeftParent,RightParent,LeftBracket,RightBracket, Comma,Semicolon,Period,Arrow,Colon,Becomes,Thru, LabelSy,ConstSy,TypeSy,VarSy,FuncSy,ProcSy, PackedSy,ArraySy,RecordSy,SetSy,FileSy, BeginSy,IfSy,CaseSy,RepeatSy,WhileSy,ForSy,WithSy,GotoSy, EndSy,ThenSy,ElseSy,UntilSy,OfSy,DoSy,ToSy, ProgramSy,OtherSy) ; OpType = ( Mul,Rdiv,AndOp,Idiv,Imod,Plus,Minus,OrOp, LtOp,LeOp,GeOp,GtOp,NeOp,EqOp,InOp,NotOp, SingleOp,RangeOp ) ; AlfaHead = packed array[AlfaIndex] of char ; AlfaEntry = ^AlfaRecord ; AlfaRecord = record Chunk : packed array[1..ChunkLength] of char ; NextChunk : AlfaEntry end ; Alfa = record Head : AlfaHead ; Tail : AlfaEntry end ; { type used by syntax analysis and recovery, chapter 8 } SetOfSymbols = set of SymbolType ; { types used in static semantic analysis, chapters 9,10 } TypEntry = ^ TypeRecord ; IdEntry = ^ IdRecord ; FormalEntry = ^ FormalRecord ; LabelEntry = ^ LabelRecord ; ScopeCopy = ^ ScopeRecord ; ListEntry = ^ListRecord ; ListRecord = record Id : IdEntry ; Next : ListEntry end ; IdList = record FirstEntry,LastEntry : ListEntry end ; IdSet = IdList ; TypeRecord = packed record Serial : SerialRange ; Next : TypEntry ; Representation : TypeRepresentation ; case Form : TypeForm of Scalars : (case ScalarKind : DeclKind of Predefined : ( ) ; Declared : (FirstConst : IdEntry)) ; SubRanges : (RangeType : TypEntry ; Min,Max : ObjectValue) ; Pointers : (DomainType : TypEntry) ; Sets : (FormOfSet : SetForms ; BaseType : TypEntry ) ; Arrays : (PackedArray,StringConstant : Boolean ; AelType,InxType : TypEntry) ; CAPSchema : (PackedSchema,ValueSchema, FirstIndex : Boolean ; CompType,InxSpec : TypEntry ; LowBdAddress,HighBdAddress : RuntimeAddress ) ; Records : (FileFree,PackedRecord : Boolean ; FieldScope : IdEntry ; FixedPart : IdEntry ; VarPart : TypEntry) ; Files : (PackedFile,TextFile : Boolean ; FelType : TypEntry) ; VariantPart : (TagType : TypEntry ; TagField,SelectorField : IdEntry ; FirstVariant : TypEntry) ; Variant : (VarFileFree,Distinct : Boolean ; SubFixedPart : IdEntry ; NextVariant,SubVarPart : TypEntry ; VariantValue : ObjectValue) end ; SetOfIdClass = set of IdClass ; IdKind = (Actual,Formal) ; KindOfVar = (ValueParam,VarParam,LocalVar) ; ScopeNumber = integer ; IdRecord = packed record Serial : SerialRange ; Name : Alfa ; LastUse : ScopeNumber ; LeftLink,RightLink : IdEntry ; IdType : TypEntry ; case Klass : IdClass of Domain, Types : ( ) ; Consts: ( Values : ObjectValue ; SuccId : IdEntry ) ; Vars: ( VarKind : KindOfVar ; VarAddress : RuntimeAddress ) ; Field: ( Offset : FieldOffset ; Tag : Boolean ; NextField : IdEntry ) ; Bound : ( BdAddress : RuntimeAddress ; NextBound : IdEntry ) ; Proc, Func: ( case PfDecKind : DeclKind of Predefined: ( PfIndex : StdProcFuncs ) ; Declared: ( Formals : FormalEntry ; case PfKind : IdKind of Actual: ( CodeBody : BlockLabel ; Assignable : Boolean ; Assigned : Boolean ; case Forwrd : Boolean of false: ( Result : RuntimeAddress ) ; true : ( Declaration : TextPosition ; FormalScope : ScopeCopy )) ; Formal: ( FAddress : RuntimeAddress ))) ; Prog: ( ProgBody : BlockLabel ) ; end ; ParmKind = (BoundParm,ValueParm,VarParm,ProcParm,FuncParm) ; FormalRecord = packed record Next : FormalEntry ; Section : Scalar ; FormalType : TypEntry ; case Parm : ParmKind of BoundParm, ValueParm, VarParm : ( ) ; ProcParm, FuncParm : ( ItsFormals : FormalEntry ) end ; LabelDepth = 1..maxint ; LabelRecord = record LabelValue : ObjectValue ; NextLabel : LabelEntry ; LabelledCode : StatementLabel ; case Defined : Boolean of false : (Declaration : TextPosition ; MaxDepth : LabelDepth ) ; true : (case Accessible : Boolean of false : ( ) ; true : (DefinedDepth : LabelDepth ) ) end ; ProgPmEntry = ^ ProgPmRecord ; ProgPmRecord = record Name : Alfa ; Declaration : TextPosition ; ParamId : IdEntry ; NextParam : ProgPmEntry end ; FrameEntry = ^ FrameRecord ; ScopeKind = ( ActualBlock,FormalBlock,RecordScope ) ; ScopeRecord = record ScopeNo : ScopeNumber ; Locals : IdEntry ; case Scope : ScopeKind of ActualBlock, FormalBlock : ( Threatened : IdSet ; TypeChain : TypEntry ; LabelChain : LabelEntry ; SavedFrame : FrameEntry ) ; RecordScope : ( RecordType : TypEntry ; FieldsPacked : Boolean ) end ; DispRange = 0..DispLimit ; RefSecurity = ( Secure,MayBeInsecure ) ; {*************************************************************************} {****** types used by the object program generator ******} {*************************************************************************} { types used by the storage allocator, chapter 13 } Shapes = ( Word,WordStructure,PartWrd,PartWrdStructure ) ; TypeCode = ( None,Indirect,Inline ) ; TypeActions = ( Presets,Postsets,ValueChecks ) ; ManualEntry = ^ ManualItem ; ManualItem = record ItsShape : Shapes ; ItsRepresentation : TypeRepresentation ; ItsCode : TypeCode ; ItsOffset: FieldOffset ; Repeated : Scalar ; NextItem : ManualEntry end ; ManualList = record FirstEntry,LastEntry : ManualEntry end ; FrameRecord = record NextOffset, LockDepth,MaxDepth : WordRange ; PresetList,PostsetList : ManualList ; CAPList : IdList ; Next : FrameEntry end ; { types used by the code-file emitter, chapter 15 } Pcodes = 0..MaxPcode ; PcodeByte = 0..MaxPcodeByte ; BlockPtr = ^ BlockRecord ; BlockRecord = record DataBase : DataRange ; EntryLabel : BlockLabel ; Next : BlockPtr end ; { types used by the object-program generator, chapters 16-26 } StackEntry = ^ StackNode ; Accesses = ( Local,Enclosing,Intermediate,Global ) ; AccessOps = ( LoadOp,StoreOp,LoadRefOp ) ; BpEntry = ^ BpRecord ; RangeEntry = BpEntry ; BpRecord = record Size : WordRange ; Lower,Upper : MCIntegerForm ; Next : BpEntry ; case CAPBounds : Boolean of false : ( ) ; true : ( BpAddress : RuntimeAddress ) end ; ActualKind = ( IsValue,IsVar,IsBlock,IsBounds,IsRef ) ; ActualEntry = ^ ActualRecord ; ActualRecord = record Next : ActualEntry ; case Kind : ActualKind of IsValue, IsRef, IsVar, IsBlock : ( ActualParam : StackEntry ; FormalRep : TypeRepresentation ) ; IsBounds : ( BpList : BpEntry ) end ; IndexEntry = ^ IndexRecord ; IndexRecord = record TheIndex : StackEntry ; Factor : MCIntegerForm ; Next : IndexEntry ; case CAPIndex : Boolean of false : ( Lower,Upper : MCIntegerForm ) ; true : ( BpAddress : RuntimeAddress ) end ; RefClasses = ( VarRef,TagRef,PnterRef,FileRef ) ; OperatorKind = ( Unary,Binary,Standard,Condition,BlockCall,CAPLoad, RangeChk,ReadOp ) ; Unaries = ( NegateOp,FloatOp ) ; OperandKind = ( AnInteger,AReal,ABoolean,ASet,AString,APointer,AFile ) ; NodeKind = ( Reference,BlockRef,Result,Address,AConstant,Operation ) ; KindOfRangeCheck = ( SubrangeChecks,TransferChecks,MemberChecks ) ; Offsets = -MCMaxMemWord..+MCMaxMemWord ; AnOperator = ( CheckSelector,SetSelector,CheckIfActive, CheckIfNew,SetALock ) ; AncillaryEntry = ^ AncillaryRecord ; AncillaryRecord = record Next : AncillaryEntry ; case WhichOp : AnOperator of CheckSelector : ( SelectorField : FieldOffset ; SelectorValue : MCIntegerForm ) ; SetSelector : ( Selector : BlockLabel ; TagValue : MCIntegerForm ) ; CheckIfActive : ( SelectorLevel : FieldLevel ) ; SetALock : ( LockWord : Offsets ; LockBit : MCBitIndex ) ; CheckIfNew : ( ) ; end ; AncillaryList = record FirstEntry,LastEntry : AncillaryEntry end ; IOFileEntry = ^ IOFileRecord ; StackNode = record NextNode : StackEntry ; DataRep : TypeRepresentation ; DataBytes : MCScalar ; Vulnerable,MayHaveOverflowed : Boolean ; RunError : Scalar ; CheckList : AncillaryList ; case Kind : NodeKind of Reference : ( BaseAddress : RuntimeAddress ; Adjustment : Offsets ; Level : Scalar ; Indirect : Boolean ; AccessList : StackEntry ; Class : RefClasses ; case PartOfWord : Boolean of false : ( case Indexed : Boolean of false:( ) ; true :(Indices : IndexEntry)) ; true : ( BitSize : MCBitRange ; BitOffset : MCBitRange ; OnByteBoundary : Boolean ; case IndexedPartWord : Boolean of false : ( ) ; true : (Index:IndexEntry) ) ) ; BlockRef : ( CallToBeGenerated : Boolean ; First,Last : ActualEntry ; OldDepth : Scalar ; case BlockKind : IdKind of Actual : ( BlockBase : BlockLabel ) ; Formal : (FormalAddress : RuntimeAddress)) ; Result : ( ) ; Address : ( case Loaded : Boolean of false : ( APartWord : Boolean ; TempAddress : RuntimeAddress ) ; true : ( ) ) ; AConstant : ( TheConst : ObjectValue ) ; Operation : ( OpGroup : OperandKind ; case OpForm : OperatorKind of Unary : ( UnaryEntry : StackEntry ; UnaryOp : Unaries ) ; Binary : ( LeftEntry,RightEntry : StackEntry ; BinaryOp : OpType ) ; Condition : ( Jump : JumpType ; OpList : StackEntry ) ; BlockCall : ( FnBlockEntry : StackEntry ) ; RangeChk : ( CheckKind : KindOfRangeCheck ; RequiredRange,TransferRange : RangeEntry; EntryToCheck : StackEntry ) ; ReadOp : ( Mode : IntKind..RealKind ) ; CAPLoad : ( CAPEntry : StackEntry ; CAPPacked : Boolean ; BpAddress : RuntimeAddress ) ; Standard : ( StdOp : StdProcFuncs ; case Boolean of false : ( StdEntry : StackEntry ) ; true : ( IOEntry : IOFileEntry ))) ; end ; { types used by the with-statement controller, chapter 20 } WithEntry = ^ WithRecord ; WithRecord = record BaseNum : DispRange ; Entry : StackEntry ; OldDepth : Scalar ; Next : WithEntry end ; { types used by the standard procedures generator, chapter 21 } IOFileRecord = record FileType : TypEntry ; FileEntry : StackEntry ; Next : IOFileEntry end ; RequestEntry = ^ RequestRecord ; RequestRecord = record Next : RequestEntry ; Request : TypeRepresentation ; ReqLevel : FieldLevel ; SelectorField : FieldOffset ; SelectorValue : MCIntegerForm end ; { types used by the case and for-statement controllers, chapter 22 } CaseLabelEntry = ^ CaseLabelRecord ; CaseLabelRecord = record LabelValue : MCIntegerForm ; LimbAddress : CodeByteRange ; NextLabel : CaseLabelEntry end ; CaseEntry = ^ CaseRecord ; CaseRecord = record Selector : StackEntry ; CaseCode : CodeLabel ; MinLabel,MaxLabel : CaseLabelEntry ; Next : CaseEntry end ; ForEntry = ^ ForRecord ; ForRecord = record Incrementing : Boolean ; ControlVar,FinalEntry : StackEntry ; StartOfLoop,EndOfLoop : CodeLabel ; Next : ForEntry end ; { types used by the type-specific envelope generator, chapters 25-26 } TypeSpecificAction = record Request : TypeActions ; Representation : TypeRepresentation ; Invoked : ( WithValue,WithRefrnce ) ; Multiple : Scalar end ; LocalEntry = ^ LocalRecord ; LocalRecord = record LKind : KindOfVar ; LAddress : RuntimeAddress end ; { types used by the data-map and code-map emitters, chapter 27 } DataName = Scalar ; MapIndex = Scalar ; DataObject = packed record ObjSerial: SerialRange; case ObjClass: IdClass of Domain: ( ) ; Types: (ObjRepresentation: TypeRepresentation; case ObjForm: TypeForm of Scalars: (case ObjScalarKind: DeclKind of Declared: (ObjFirstConst: SerialRange) ; Predefined: (StdType: (IntStd,RealStd,CharStd))) ; SubRanges: (ObjRangeType: SerialRange; ObjMin, ObjMax: ObjectValue); Sets: (SetIsPacked: Boolean; ObjBaseType: SerialRange); Pointers: ( ObjDomain : SerialRange ) ; Arrays: (ArrayIsPacked: Boolean; ObjLowBound,ObjHighBound : ObjectValue ; ObjAelType, ObjInxType: SerialRange); CAPSchema: (SchemaIsPacked: Boolean ; ObjCompType,ObjInxSpec: SerialRange ; ObjLowAddr,ObjHighAddr: WordRange) ; Records: (RecordIsPacked: Boolean; ObjFixedPart, ObjVarPart: SerialRange); Files: (FileIsPacked, FileIsText: Boolean; ObjFelType: SerialRange); VariantPart: (ObjTagField,ObjTagType, ObjFstVariant: SerialRange; ObjSelector : FieldOffset); Variant: (VariantIsDistinct : Boolean ; ObjSubFixedPart, ObjSubVarPart, ObjNextVariant: SerialRange; ObjVariantValue: ObjectValue)); Consts : (ConstName: DataName; ConstValue: ObjectValue ; NextConst: SerialRange); Vars, Bound: (VarName: DataName; VarType: SerialRange; IsVarParam: Boolean; LocalAddress: WordRange; NextLocalVar: SerialRange); Field: (FieldName : DataName ; FieldType: SerialRange; ObjOffset: FieldOffset; NextField: SerialRange); Prog,Proc,Func: { The serial no. of this object-table entry } { serves to identify the corresponding block } { in the object program. } (BlockName: DataName ; BlockBody: MapIndex ; FirstLocalVar: SerialRange) end; TokenKinds = ( StartBody,FlowToken,EndBody ) ; MapToken = packed record case Kind : TokenKinds of StartBody : ( BlockSerial : SerialRange ; StartLine : Scalar ) ; FlowToken : ( CodeOffset,FlowLine : Scalar ) ; EndBody : ( JumpTableSize,CodeTableSize : Scalar ) end ; NameByte = 0..MCMaxChar ; var { The compiler will generate object-code subject to the } { condition that the Boolean variable CodeIsToBeGenerated } { has the value true. On the first occurrence of any } { error (be it syntactic, semantic, or predicted), the } { source-handler procedure Error resets this value to } { false, thereby suppressing the generation of any } { further executable code. Program analysis continues } { however, and the compiler will check the syntax and } { static semantics of the remaining program text. } CodeIsToBeGenerated : Boolean ; {*************************************************************************} {****** variables used by the source program analyser ******} {*************************************************************************} { global variables used by the option-handler, chapter 3 } OptionCh : char ; Requested,LocallyRequested : SetOfOptions ; OptionF : text ; WarningsToReport : Boolean ; Warning : BannerString ; OptionValue : array[IntOptions] of integer ; OptionMap : array[OptionType] of record Name : OptionString ; Option : OptionType ; Class : OptionClass end ; { global variables used by the source handler, chapter 4 } Banner : record Title,SubTitle,BoolOps,IntOps : BannerString ; PageNum : Scalar ; end ; Ch: char ; Source : SourceLine ; ErrorCount : Scalar ; Reported : packed array[ErrorSpan] of Boolean ; SourceF, ListFile, ErrFile : text ; { global variables provided for use with the object } { code generation interface, chapter 5 } EmptyRepresentation, RealRepresentation,BooleanRepresentation, CharRepresentation,IntegerRepresentation, PointerRepresentation,DefaultRepresentation : TypeRepresentation ; UndefinedValue : MachineValue ; NilValue,EmptyValue, FalseValue,TrueValue, ZeroValue,ZeroReal,OneValue,MaxintValue, MinLabValue,MaxLabValue, MinCharValue,MaxCharValue, LineFeed,PageThrow, DefaultLayout,DefaultValue : ObjectValue ; DefaultAddress : RuntimeAddress ; DefaultOffset : FieldOffset ; DefaultLabel : BlockLabel ; { global variable used by the diagnostics handler, chapter 6 } NextSerial : SerialRange; { global variables used by the lexical analyser, chapter 7 } Symbol : SymbolType ; Operator : OpType ; Constant : ValueDetails ; Spelling : Alfa ; StartOfSymbol : TextPosition ; SymbolStarters,Letters,Digits, LettersAndDigits,LowerCaseLetters : set of char ; PrecedingPeriod, TailToBeDisposed : Boolean ; { tables used by the lexical analyser, chapter 7 } WordSymbol : array[1..NoWords] of record Spelling : AlfaHead ; SymbolValue : SymbolType ; OpValue : OpType end ; LastOfLength : array[0..AlfaSize] of 0..NoWords ; { global variables used in syntax analysis, chapters 8,10 } SymbolsSkipped,Recovering,ErrorReported : Boolean ; BlockBegSys,TypeBegSys,ConstBegSys,SimpTypeBegSys,TypeDels, StatBegSys,FacBegSys,SelectSymbols,ParamBegSys, KonformantParamBegSys : SetOfSymbols ; { global variables used by semantic analysis, chapters 9,10 } IntType,RealType,BoolType,CharType, TextType,NilType,EmptyType,Unknown : TypEntry ; ExpType,VarType : TypEntry ; VntSelector : TypEntry ; PackedVar,SimpleVar,TagVar,NewRecVar : Boolean ; InputFile,OutputFile : IdEntry ; DummyVarId : IdEntry ; ControlVars : IdSet ; ScopeLevel,BlockLevel,LevelFound : DispRange ; Display : array [DispRange] of ScopeRecord ; NextScopeNo : ScopeNumber ; Depth : LabelDepth ; {*************************************************************************} {****** variables used by the object program generator ******} {*************************************************************************} { variable used by the storage allocator, chapter 13 } FrameLevel : AddressLevel ; ItemShapes : array[Boolean,Boolean] of Shapes ; PresetBuffer : record Shift,BitsFree : MCBitRange ; Buffer : MCWordForm end ; { variables used by the code-file emitter, chapter 15 } CodeFileSize : CodeAddress ; CodeFile : file of MCWord ; CodeCounter : CodeByteRange ; CodeBuffer : packed array[CodeByteRange] of MCByte ; DataCounter : DataRange ; DataStack : array[DataRange] of MCWordForm ; CurrentBlock : BlockPtr ; BlockIndex : MapIndex ; { variables used by the object program generator, chapters 16-26 } SelectedFile : IOFileEntry ; HpRequests : record FirstReq,LastReq : RequestEntry ; PointerEntry : StackEntry end ; ZeroEntry,DefaultWidth, TopStackEntry : StackEntry ; TopFrameEntry : FrameEntry ; TopWithEntry : WithEntry ; TopCaseEntry : CaseEntry ; TopForEntry : ForEntry ; BufferOffset : FieldOffset ; Overflow : record Occurred,Positive : Boolean end ; IntCodes,RealCodes,PtrCodes,SetCodes,StringCodes : array[OpType] of Pcodes ; AccessCodes : array[AccessOps,Accesses] of Pcodes ; ContextOfCheck : ( IsSucc,IsPred,IsUnknown ) ; TransferCodes,CheckCodes : array[Boolean,Boolean] of Pcodes ; ProgPmCount : Scalar ; { variables used by the code-map and data-map emitters, chapter 27 } LastFlowLine : Scalar ; CodeMapIndex : MapIndex ; CodeMap : packed file of MapToken ; DataMapIndex : SerialRange ; DataMap : packed file of DataObject ; NameFileIndex : SerialRange ; NameFile : packed file of NameByte ;