{ > PasComp } {----------------------------------------------------------------------------- Author ----------------------------- L Haines. Released --------------------------- 07/08/84. Date of last compiler mod ---------- 11/02/86. Details of mods since release 1.00 - Bugs 6 to 9 fixed (See Buglist). Tutu 11 feb 86 - added manifest totaldescsize for array accesses Tutu 30 jan 85 mods for ARM version - manifest changes etc. Tutu 04 sep 85 mods to 1.01 -> 1.02 Disc version. Fixed WITH clause bug (Bug 13); Optimised GENUW/GENSI/GENSTR too Also use inkey for stopping exec files on error The compiler's header is created by the basic program which creates and links the machine code stuff and includes a chain to this file of definitions -----------------------------------------------------------------------------} MAXSET = 32; { Number of bytes in a set } MAXLEV = 8; { Maximum procedure / record nesting } MAXFNAME = 60; { Maximum size of a file name } MAXUW = 65535; { Maximum value to be PACKED into 2 bytes 0..MAXUW } MAXERRS = 5; { Maximum number of errors on a line } MAXPROC = 127; { Maximum number of procedures in a program } TERMCH = 13; { Carriage return } EOFCH = 4; { End of file character } { The following are values assigned to the BL codes } PUSH = 9; LOCILD = 7; LOCATE = 16; IPUSH = 24; IDENTIFY = 31; POP = 17; USEOP = 41; IPOP = 33; EQOP = 0; NEOP = 1; LEOP = 2; GEOP = 3; LTOP = 4; GTOP = 5; AACESOP = 66; JMPNOW = 68; JMPFALS = 69; ADDOP = 106; SUBOP = 107; IMULOP = 116; IDIVOP = 117; MODOP = 118; FLTROP = 119; RMULOP = 122; RDIVOP = 123; CALLS = 124; RETURNS = 125; SMULOP = 128; BINOP = 129; FLTLOP = 130; IINOP = 131; ANDOP = 132; OROP = 133; NOTOP = 134; REEDLN = 135; REED = 136; PAIG = 137; RNONTXT = 140; GETT = 141; PUTT = 143; WRITLN = 148; WRIT = 149; WPLAOP = 154; WWIDOP = 155; WSTR = 156; WNONTXT = 157; RSET = 166; RWRIT = 170; EOFFN = 174; INITS = 175; EXITS = 176; MARKS = 177; NU = 178; DISPOZ = 180; FRETRNS = 181; ORDFN = 192; INEGOP = 197; ABSFN = 198; RNEGOP = 200; SINFN = 203; ENTERL = 221; hkfsize = &18; { Tutu - link/disp/retCP/namptr/level/FCBref - all *4 } fcbref = &14; { Tutu - offset of FCB reference in the hkf } fcbsize = 16; { Tutu - size of an FCB without the file buffer } ptrsize = 4; { Tutu - size of pointers on the target machine } twiceptrsize = 8; { Tutu - twice the above } reasize = 8; { Tutu - size of real numbers on the target machine } dspsize = &20; { Tutu - (maxlevel+1)*ptrsize } dspNprocsize = &24; { Tutu - (maxlevel+1)*ptrsize + intsize } totaldescsize = 12; { Tutu - single descriptor elememt - size/low/high } TYPE UB = 0..255; { Unsigned byte } UW = 0..MAXUW; { 2 byte unsigned word } SI = -MAXINT..MAXINT; { 4 byte signed integer } SYMBOLS = (NULL,TWIDLE,COMMA,DOT,COLON,SEMICOLON,AT,LPAREN,RPAREN,LBRAK, RBRAK,MULT,PLUS,MINUS,SLASH,EQUALS,NE,LE,GE,LT,GT,ASSIGN,DDOT, ANDSY,DIVSY,INSY,MODSY,ORSY,ARRAYSY,BEGINSY,CASEY,CONSTSY, DOSY,DOWNTOSY,ELSESY,ENDSY,FILESY,FORSY,FUNCSY,GOTOSY,IFSY, LABELSY,NILSY,NOTSY,OFSY,PACKSY,PROCSY,PROGSY,RECORDSY, REPEATSY,SETSY,THENSY,TOSY,TYPESY,UNTILSY,VARSY,WHILESY,WITHSY, EOFILE,FORWAD,OTHER,UNDEFID,NEWID,KONST,VARID,FIELD,TAG, BOUNDID,TIPE,EPROC,SPROC,PROC,EFUNC,SFUNC,FUNC,PROG,BADUN); TYPES = (NOTYP,BOOL,CHARR,INT,REEL,SUBR,ENUM,PNTR,SETT, STRNG,CARAY,ARAY,REKORD,FYLE,TXT,BLOC); IDSYMS = OTHER..BADUN; { Used only as tag type in SYMREC declaration } VARIANTP = ^VARIANT; STP = ^TYPREC; SYMP = ^SYMREC; PATCHP = ^PATCHREC; CONSTSP = ^CONSTS; LABP = ^LAB; PFNAMP = ^PFNAM; ADRSP = ^ADRS; WITHLISTP = ^WITHLIST; PARAMP = ^PARAM; VARIANT = PACKED RECORD { Info needed to handle variant records } CONSTLIST : CONSTSP; { Pntr to list of tag consts for this variant } MAXSIZE : UW; { Max size of this record } NESTEDV, { Pntr to list of variants nested in this one } LASTV : VARIANTP { Pntr to last variant of variant-part } END; CONSTS = RECORD { Element of a linked list of constants } NEXTC : CONSTSP; { Pntr to next constant in list } CONS : SYMP { Pntr to constant descriptor } END; TYPREC = PACKED RECORD { Type descriptor for an identifier. See sheet 1 in maintenance folder for record's memory map } TYP : TYPES; CASE TYPES OF REEL : (); FYLE,TXT : ( { file type symbol table size = 6 (8) bytes } FILEPAC : BOOLEAN; { TRUE if component of file is packed } FILEREF : STP; { Pntr to descriptor for file's component type } FILESIZ : UW { Size of a component of the file, in bytes }); NOTYP,PNTR : ( { Pointer type symbol table size = 7 (8) bytes } PNTRREF : STP; { Pntr to pointer's base type } PSZ : UW; { Size of pointer's base type } NEXTREF : STP { Pntr to list of pntr records to be resolved }); SUBR,SETT,BOOL,CHARR,INT,ENUM : ( { Subrange type symbol table size = 12 bytes } LOW, { Lower limit of a subrange } HIGH : SI; { UPPER limit of a subrange } SUBRREF : STP; { If enumerated then pntr to enum type else NIL } SUBRSIZ : UB { Bytes needed to hold values of this subrange}); ARAY,CARAY,STRNG,REKORD,BLOC : ( VARSIZ : UW; { Size of variable or PARAMSIZ+local vars } CASE TYPES OF NOTYP,BOOL,CHARR,INT,REEL,SUBR,ENUM,PNTR,SETT,FYLE,TXT : (); ARAY,CARAY,STRNG : ( { Array and string symbol table size = 12 bytes } ELREF, { Pntr to descriptor for array's component type } IREF : STP; { Pntr to descriptor for array's index type } ALEV : UB; { Level at which array is declared. If > 127 then array element is packed } ADESCOFF : UW; { Position of array descriptor in activation rec} ELSIZE : UW; { Size of array's component } CASE TYPES OF CARAY : ( { Conformant array symbol table size = 16 bytes } LOWB, { Pntr to cnformnt array low bound id descriptor} HIGHB : SYMP); { Pntr to cnformnt array high " " " } NOTYP,BOOL,CHARR,INT,REEL,SUBR,ENUM,PNTR,SETT,STRNG,ARAY,FYLE,REKORD, TXT,BLOC : ()); REKORD,BLOC : ( LASTSYM : SYMP; { Pntr to id descriptor of last id in a record or block ( = start of linked list of ids) } CASE TYPES OF NOTYP,BOOL,CHARR,INT,REEL,SUBR,ENUM,PNTR,SETT,STRNG,CARAY,ARAY,FYLE, TXT : (); REKORD : ( { REKORD symbol table size = 7 (8) bytes} VARIANTS : VARIANTP{ Pointer to list of variants, if any }); BLOC : ( { Bloc (proc/func) symbol table size = 16 bytes } LASTPARAM : SYMP; { Pntr to id descriptor of last id in a formal param section (start of linked list of params)} FUNCREF : STP; { Pntr to descriptor for function's result type } FUNCVAR, { Adr of func return value in activation record } PARAMSIZ : UW; { Size of activation record info(9 bytes)+params} RESSIZ : UB; { Size of the function return value } PLIST : PARAMP ))) { List of No. variables in a param list section } END; SYMREC = PACKED RECORD { Descriptor record for an identifier. See sheet 2 in maintenance folder for record's memory map } { This record makes great use of variants to enable standard ids to be described in as small an amount of bytes as possible } IDTYP : TYPES; { Basic type of the identifier } NAMLINK : UW; { Absolute address in memory of the character before the start of the id's name string } LINK : SYMP; { Pntr to id declared previous to this one } OBJ : SYMBOLS; { What the id represents, eg VARID,KONST,PROC etc} USED_LEV : UB; { The level that the id was last used at } USED_PROC: UB; { Procedure number to go with USED_LEV } CASE IDSYMS OF OTHER,UNDEFID,NEWID,KONST,FIELD,TAG,BOUNDID,TIPE,EPROC,PROC,EFUNC, SFUNC,FUNC,PROG,BADUN : (); SPROC : (PROCNO : UB); { Standard procedure identification number } VARID : ( REF : STP ; { Pntr to id type descriptor } CASE IDSYMS OF OTHER,UNDEFID,NEWID,KONST,FIELD,TAG,BOUNDID,TIPE,SPROC, PROC,EFUNC,FUNC,PROG,BADUN : (); SFUNC,EPROC : ( FUNCNO : UB; { Standard func or extension proc id number } CASE IDSYMS OF OTHER,UNDEFID,NEWID,KONST,VARID,FIELD,TAG,BOUNDID,TIPE,SPROC, PROC,EFUNC,SFUNC,FUNC,PROG,BADUN : (); EPROC : (NPARAMS : UB) { No. params for extension proc } ); VARID : ( PAK : BOOLEAN; { True if variable/type is packed } CASE IDSYMS OF OTHER,UNDEFID,NEWID,FIELD,TAG,BOUNDID,TIPE,EPROC,SPROC,PROC, EFUNC,SFUNC,FUNC,PROG,BADUN : (); VARID : ( PERM, {true if is a file declared in prog header} NRM : BOOLEAN;{true if var is a value parameter} LEV : UB; {level at which the id was declared} CASE IDSYMS OF OTHER,UNDEFID,NEWID,KONST,FIELD,TAG,TIPE,EPROC,SPROC, PROC,EFUNC,SFUNC,FUNC,PROG,BADUN : (); BOUNDID : ( OFSET : UW; { Offset from start of array desc where the value of boundid will be found } ADESC : UW { Offset in procedure's activation record that holds adr of the array descriptor } ); VARID : ( ADR : SI; { size of type/adr of variable/proc } FUNCASS, { TRUE if id is function and has been assigned to } THREAT : BOOLEAN) { TRUE if variable has been assigned to in a nested proc/func or has been passed as a var param. Used in checks on control variable of a FOR loop } ); KONST : ( CASE TYPES OF NOTYP,SUBR,SETT,CARAY,ARAY,REKORD,FYLE,TXT,BLOC : (); INT,BOOL,CHARR,ENUM,PNTR : ( VAL : SI; RV : UW ); REEL : ( REELVAL : REAL ); STRNG : ( STRLEN : UW; { Length of string } STRPTR : UW { As for NAMLINK above } ) ) ) ) END; UBSET = PACKED SET OF UB; ADRS = PACKED RECORD { Linked list of references to an undefined label. Used for forward referencing GOTOs } CA : UW; { Code address of part of goto BL-code which needs patching with CA and SPO (see LAB declaration) when the label is defined } LEV : UW; { Procedure nesting level of this reference } NEXT : ADRSP; { Next reference in linked list } ACCSET : UBSET { Set of stmt sequences which are active at this reference. When the label is found (in the same procedure as the reference), it must be in one of the stmt seqs in this set. SEQNO in LAB type and OKGOTOS (global set) are used in the reverse way (ie backward referencing GOTO) } END; LAB = PACKED RECORD { Symbol table record for a label } NEXT : LABP; { Link to next label descriptor in list } VAL, { Numeric value of label's digits } SEQNO, { Stmt sequence No. in which the label is defined } CA, { Code address of the statement following label } SPO, { Stack pointer offset at start of label's stmt } LEV : UW; { Statement level at which label is defined. (1 = outer most level of stmt nesting in a block)} PREFIX, { If TRUE then stmt is prefixed by this label or is nested in a stmt which is prefixed by this label } USED, { TRUE if label is defined } OKGOTO : BOOLEAN; { TRUE if label prefixes a stmt in the stmt sequence of a compound stmt } USER : ADRSP { Pntr to list of GOTOs which reference the label } END; WITHLIST = PACKED RECORD { Holds info on active WITH statements, first in list is most recently activated WITH record } NEXT : WITHLISTP; { Pntr to next active WITH record descriptor } FIELDS : STP; { Pntr to linked list of record's field ids } WITHADR : UW { Address on stack of record's base address } END; PATCHREC = PACKED RECORD { Linked list of patches to patch code file with at end of compilation } NEXT : PATCHP; { Pntr to next in list } ADDR : UW; { Code address to patch } VALUE : UW { Value to patch file with } END; PFNAM = PACKED RECORD { Linked list of user procedure/function entry points. First in the list is a dummy, the second is the address of the 'here is program name' BL-code } NEXT : PFNAMP; { Next in linked list } ADR : UW { Address of proc start } END; PARAM = PACKED RECORD { Linked list of the No. params in each of the parameter-list-sections of a proc/func header} No : UB; { No. params in this parameter-list-section } NEXTNo : PARAMP { Next parameter-list-section in list } END; FNAMETYP = PACKED ARRAY[1..MAXFNAME] OF CHAR; { File names & number conversion string type } VAR { *** to *** MUST be declared first and MUST be in this order } { All adrs are indexd on interpreter's Stack_start } {***} THISSYMP : SYMP; { Last id/constant parsed NEXTSYM. adr = &20} NEXTSYMP : SYMP; { Pntr to id after THISSYMP in id list. Set up by m/c routine EQID in LOOKUPID, used in FUJENT. adr=&22 } Y : PACKED RECORD LASTNAME : UW { Last char in names table. adr = &24 } END; SYM, { Symbol returned by NEXTSYM. adr = &26 } D : SYMBOLS;{ adr = &27 Dummy variable for machine code } BOOLDESC, { Pntr to BOOLEAN type descriptor. adr = &28 } CHARDESC, { Pntr to CHAR type descriptor. adr = &2A } INTDESC : STP; { Pntr to INTEGER type descriptor. adr = &2C } LASTSYMP : SYMP; { Last entry in symbol table at current lev. adr=&2E} { Compiler options } ASSCHK, { TRUE if unassigned checking required. adr=&30} WAIT, { TRUE if compiler is to wait for to be pressed after an error is detected. adr = &31} FULL, { TRUE if full error messages are required. adr=&32} TAIL, { TRUE if the command line tail is to be passed into the program being compiled. adr = &33} EXT, { TRUE if Acorn extensions are allowed. adr = &34} DEBUG, { TRUE if debug code to be planted in code. adr=&35} RNGCHK, { TRUE if range checking code to be planted. adr=&36} GENCODE, { TRUE if object code is to be produced. adr=&37 } LISTING: BOOLEAN; { TRUE if compilation listing to be produced.adr=&38} { End of compiler options } ISDEC, { TRUE if next id to be put in symbol table. adr=&39} RETKONST, { TRUE if code is not to be generated to push a constant onto the stack. adr = &3A} VARP, { True if actual parameter corresponds to var formal parameter. (Used in file buffer access). adr=&3B} FUCKUP, { TRUE if error recovery invoked. adr = &3C } CHANGE, { TRUE if allowed to alter C/D comp options. adr=&3D} NOTOPEN, { TRUE if temp code file has not been opened.adr=&3E} NOTAB, { TRUE if no id table been claimed from heap.adr=&3F} CLO, { TRUE if command line comp options present. adr=&40} {***} ISSEMI, { TRUE if symbol returned by NEXTSYM is ';' } ISCOMA, { TRUE if symbol returned by NEXTSYM is ',' } NEGSIGN, { TRUE if symbol before a constant is a '-' } PHEAD, { TRUE if parsing a procedure heading } SIGNED, { TRUE if variable or constant is signed } MIXED, { TRUE if left & right operands are mixed type } NEWLINE, { Toggle on EOLN(SOURCE) to delay read of next line. TRUE if EOLN(SOURCE) is TRUE } ISTYPDECS, { If FALSE, does not allow ^new_pntr_type } SIMPLE, { TRUE if variable is a simple variable } LHS, { TRUE if parsing LHS of assignment stmt } NOCODE, { TRUE if no code has been generated by a var access} OPTION : BOOLEAN;{ TRUE if compiler option = '+' or '*' } CH, { Current character being used by lexical analyser } NXTCH : CHAR; { Next character to be used by lexical analyser } SAVESYM : SYMBOLS;{ Used to save SYM in FIELDLIST when parsing variant-selector } ACTIVELIST, { List of active WITH records } NEWACTIVE, { Used to create a new entry in ACTIVELIST } THISACTIVE: WITHLISTP;{ In LOOKUPID, ACTIVELIST is searched first to try and match the id being parsed with one in a WITH record, if a match is found then THISACTIVE points to the relevant entry in ACTIVELIST linked list } PROCTAB, { Pntr to start of linked list of procedure/function entries. See PFNAM type declaration for more info } PFNAMES : PFNAMP; { Used to point to the last entry in linked list of procedure/function entries } ADESCREF, { Used to hold the type descriptor of the first dimension of a multidimensional array so as not to lose the ADESCOFF and ALEV values. } SUBRP, { Used in ORDTYP as a copy of a pointer to ordinal's type descriptor } LHSPTR : STP; { Used in TYPDECS, if LHS is referenced on the RHS of a type declaration then this points to the list of pntr records to be resolved } INPTSYMP, { Pntr to id descriptor for INPUT } OTPTSYMP, { Pntr to id descriptor for OUTPUT } TYPID, { Pntr to the type-identifer of a type declaration } BASESYMP : SYMP; { Pntr to id descriptor for any constants } PATCH1 : PATCHP; { Pntr to start of linked list of code patches } GLOBSIZ, { Size of global variables+9(for activation record) } LLIM : SI; { Lower lim of SUBR,STRING,ARRAY (set up by LIMITS) } X : PACKED RECORD { There be dragons in these parts } CADR, { Offset from codebase to put code byte } PROCLEV, { Saves current level inside a proc. Used to set level of any types or enumerated constants declared inside a record to that of the procedure } STMTLEV, { Current level of statement nesting } ACTIVLEV, { Since variable access at program run time only specifies an offset into the currently selected actiavtion record, there exist BL_codes to specify the activation record of the variable currently being accessed (more compact code if you do not intermix variable accesses at different levels too much). ACTIVLEV is used in code generation to remember the last level at which a var was accessed (always set to current level after any BL-jump_or_branch-code has been executed or where the level could be undefined). } INDEX, { Lots of things this be used for } STKINC, { Keeps track of current stk size for this procedure } MAXSTK, { This procedures maximum stack usage } SEQNO, { Each statement_sequence has a number assigned to it for use in GOTO checking, this is the current stmt_sequence number} ERRORS, { Total No. errors detected } ERRNO, { No. errors detected on the current line } CHRNO, { Postion of CH on current line (max 255) } LINENO, { Compilation listing line number } SRCLINE, { Source file line number } LASTADR, { Code address of the 2 bytes following the BL-code byte after proc GENOPWTB (gen operation with two bytes) is called. } MAXNAME, { Before the memory for the id names table is allocated this holds the size of the table. After allocation, it holds the adr in memory of the end of the table. } DBUGTAB, { Address of the word near the start of a BL-code program which specifies the address of the procedure address table at the end of the program. } DEPTH, { Used when searching the symbol table for an identifier, it holds the current declaration level being searched. BEWARE!! since this is an unsigned word, when level drops below 0 DEPTH does not hold -1 (&FFFFFFFF) but 65535 (&FFFF) } LEVEL, { Current declaration level } PROCNO, { Last declared procedure number } THISPROCNO, { Current procedure number } WORDLEN, { Length of the string/id read by NEXTSYM } NAMESZ, { Length of the source file-name } GARECADR : UW; { Address in the generated BL-code to patch with the global activation record size (after program ENTER_level0 BL-code). } USED_AT_LEV, { Level at which the current identifier was last used (scope checking). } USED_IN_PROC: UB{ Procedure number of procedure in which the current identifier was last used. } END; ADESC : UW; { Offset from start of main array descriptor where the sub array descriptor will be found} CBUFF : PACKED RECORD BASICOP, { Basic operation ie locate, push etc } LEV, { Variable's declaration level (see ACTIVLEV) } OPCODE : UW; { final opcode ie push current level integer } VARADR : UW { address of variable or use-offset's offset } END; NAMES : PACKED RECORD CASE BOOLEAN OF TRUE : (TADR : UW); {Set TADR to adr of byte in memory} FALSE : (TPTR : ^CHAR) {then output value using pointer} END; PFILE, { Temporary code file } CODEF : PACKED FILE OF UB; { Final code file } ERRFILE, { File containing error messages } SOURCE : TEXT; { File to be compiled } ERRARAY : PACKED ARRAY[1..MAXERRS] OF UB; { Holds error numbers found on current line } DISPLAY : PACKED ARRAY[0..MAXLEV] OF STP; { pointer to a record of type 'TYPREC' for each level } ACCEPT : SET OF SYMBOLS; { Holds set of symbols to re-align on in the event of a syntactical compilation error. adr = &F6 (9 bytes spare) } LABS : PACKED ARRAY[0..MAXLEV] OF LABP; { labels display } OKGOTOS : UBSET; { Set of statement sequences that are accessible from the current statment using a GOTO } ERRSET : UBSET; { Set to hold the character position on current line of any errors. Used to output a error pointer '^' } SOURCEFILE, { Holds name of source file } CODEFILE : FNAMETYP; { Holds name of code file } SINGLEOPS : PACKED ARRAY[1..22] OF CHAR; { String containing all single character operators } stack_size : integer; { Tutu - Stack size to use on target machine Default 0 -> use default system stack } {$S'PasCgen'}