(* COPYRIGHT (C) 1978, REGENTS OF THE *) (* UNIVERSITY OF CALIFORNIA, SAN DIEGO *) SEGMENT PROCEDURE BODYPART(FSYS: SETOFSYS; FPROCP: CTP); PROCEDURE LINKERREF(KLASS: IDCLASS; ID,ADDR: INTEGER); BEGIN IF NREFS > REFSPERBLK THEN (*WRITE BUFFER*) BEGIN IF BLOCKWRITE(REFFILE,REFLIST^,1,REFBLK) <> 1 THEN ERROR(402); REFBLK := REFBLK + 1; NREFS := 1 END; WITH REFLIST^[NREFS] DO BEGIN IF KLASS IN VARS THEN KEY := ID + 32 ELSE (*PROC*) KEY := ID; OFFSET := SEGINX + ADDR END; NREFS := NREFS + 1 END (*LINKERREF*) ; PROCEDURE GENLDC(IVAL: INTEGER); BEGIN IF (IVAL >= 0) AND (IVAL <= 127) THEN GENBYTE(IVAL) ELSE BEGIN GENBYTE(51(*LDC*)+148); MOVELEFT(IVAL,CODEP^[IC],2); IC := IC+2 END END (*GENLDC*) ; PROCEDURE GENBIG(IVAL: INTEGER); VAR LOWORDER: CHAR; BEGIN IF IVAL <= 127 THEN GENBYTE(IVAL) ELSE BEGIN MOVELEFT(IVAL,CODEP^[IC],2); LOWORDER := CODEP^[IC]; CODEP^[IC] := CHR(ORD(CODEP^[IC+1])+128); CODEP^[IC+1] := LOWORDER; IC := IC+2 END END (*GENBIG*) ; PROCEDURE GEN0(FOP: OPRANGE); VAR I: INTEGER; BEGIN GENBYTE(FOP+128); IF FOP = 38(*LCA*) THEN WITH GATTR.CVAL.VALP^ DO BEGIN GENBYTE(SLGTH); FOR I := 1 TO SLGTH DO GENBYTE(ORD(SVAL[I])) END END (*GEN0*) ; PROCEDURE GEN1(FOP: OPRANGE; FP2: INTEGER); LABEL 1; VAR I,J: INTEGER; BEGIN GENBYTE(FOP+128); IF FOP = 51(*LDC*) THEN BEGIN IF FP2 = 2 THEN I := REALSIZE ELSE BEGIN I := 8; WHILE I > 0 DO IF GATTR.CVAL.VALP^.CSTVAL[I] <> 0 THEN GOTO 1 ELSE I := I - 1; 1: END; GATTR.TYPTR^.SIZE := I; IF I > 1 THEN BEGIN GENBYTE(I); FOR J := I DOWNTO 1 DO GENWORD(GATTR.CVAL.VALP^.CSTVAL[J]) END ELSE BEGIN IC := IC - 1; IF I = 1 THEN GENLDC(GATTR.CVAL.VALP^.CSTVAL[1]) END END ELSE IF FOP IN [30(*CSP*),32(*ADJ*),45(*RNP*), 46(*CIP*),60(*LDM*),61(*STM*), 65(*RBP*),66(*CBP*),78(*CLP*), 42(*SAS*),79(*CGP*)] THEN GENBYTE(FP2) ELSE IF INMODULE AND (FOP IN [37(*LAO*),39(*LDO*),43(*SRO*)]) THEN BEGIN LINKERREF(ACTUALVARS,FP2,IC); GENBYTE(128); GENBYTE(0) END ELSE IF ((FOP = 74(*LDL*)) OR (FOP = 39(*LDO*))) AND (FP2 <= 16) THEN BEGIN IC := IC-1; IF FOP = 39(*LDO*) THEN GENBYTE(231+FP2) ELSE GENBYTE(215+FP2) END ELSE IF (FOP = 35(*IND*)) AND (FP2 <= 7) THEN BEGIN IC := IC-1; GENBYTE(248+FP2) END ELSE GENBIG(FP2) END (*GEN1*) ; PROCEDURE GEN2(FOP: OPRANGE; FP1,FP2: INTEGER); BEGIN IF (FOP = 64(*IXP*)) OR (FOP = 77(*CXP*)) THEN BEGIN GENBYTE(FOP+128); GENBYTE(FP1); GENBYTE(FP2); END ELSE IF FOP IN [47(*EQU*),48(*GEQ*),49(*GRT*), 52(*LEQ*),53(*LES*),55(*NEQ*)] THEN IF FP1 = 0 THEN GEN0(FOP+20) ELSE BEGIN GEN1(FOP,FP1+FP1); IF FP1 > 4 THEN GENBIG(FP2) END ELSE BEGIN (*LDA,LOD,STR*) IF FP1 = 0 THEN GEN1(FOP+20,FP2) ELSE BEGIN GENBYTE(FOP+128); GENBYTE(FP1); GENBIG(FP2) END END; END (*GEN2*) ; PROCEDURE GENNR(EXTPROC: NONRESIDENT); PROCEDURE ASSIGN(EXTPROC: NONRESIDENT); BEGIN PROCTABLE[NEXTPROC] := 0; PFNUMOF[EXTPROC] := NEXTPROC; NEXTPROC := NEXTPROC + 1; IF NEXTPROC > MAXPROCNUM THEN ERROR(193);(*NOT ENOUGH ROOM FOR THIS*) CLINKERINFO := TRUE (*OPERATION*) END (*ASSIGN*) ; BEGIN (*GENNR*) IF PFNUMOF[EXTPROC] = 0 THEN ASSIGN(EXTPROC); IF SEPPROC THEN BEGIN GEN1(79(*CGP*),0); LINKERREF(PROC,-PFNUMOF[EXTPROC],IC-1) END ELSE GEN1(79(*CGP*),PFNUMOF[EXTPROC]); END (*GENNR*) ; PROCEDURE GENJMP(FOP: OPRANGE; FLBP: LBP); VAR DISP: INTEGER; BEGIN WITH FLBP^ DO IF DEFINED THEN BEGIN GENBYTE(FOP+128); DISP := OCCURIC-IC-1; IF (DISP >= 0) AND (DISP <= 127) THEN GENBYTE(DISP) ELSE BEGIN IF JTABINX = 0 THEN BEGIN JTABINX := NEXTJTAB; IF NEXTJTAB = MAXJTAB THEN ERROR(253) ELSE NEXTJTAB := NEXTJTAB + 1; JTAB[JTABINX] := OCCURIC END; DISP := -JTABINX; GENBYTE(248-JTABINX-JTABINX) END; END ELSE BEGIN MOVELEFT(REFLIST,CODEP^[IC],2); IF FOP = 57(*UJP*) THEN DISP := IC + 4096 ELSE DISP := IC; REFLIST := DISP; IC := IC+2 END; END (*GENJMP*) ; PROCEDURE LOAD; FORWARD; PROCEDURE GENFJP(FLBP: LBP); BEGIN LOAD; IF GATTR.TYPTR <> BOOLPTR THEN ERROR(135); GENJMP(33(*FJP*),FLBP) END (*GENFJP*) ; PROCEDURE GENLABEL(VAR FLBP: LBP); BEGIN NEW(FLBP); WITH FLBP^ DO BEGIN DEFINED := FALSE; REFLIST := MAXADDR END END (*GENLABEL*) ; PROCEDURE PUTLABEL(FLBP: LBP); VAR LREF: INTEGER; LOP: OPRANGE; BEGIN WITH FLBP^ DO BEGIN LREF := REFLIST; DEFINED := TRUE; OCCURIC := IC; JTABINX := 0; WHILE LREF < MAXADDR DO BEGIN IF LREF >= 4096 THEN BEGIN LREF := LREF - 4096; LOP := 57(*UJP*) END ELSE LOP := 33(*FJP*); IC := LREF; MOVELEFT(CODEP^[IC],LREF,2); GENJMP(LOP,FLBP) END; IC := OCCURIC END END (*PUTLABEL*) ; PROCEDURE LOAD; VAR J,M: INTEGER; BEGIN WITH GATTR DO IF TYPTR <> NIL THEN BEGIN CASE KIND OF CST: IF TYPTR^.FORM = LONGINT THEN WITH GATTR.CVAL.VALP^ DO BEGIN M := 10000; GENLDC(LONGVAL[1]); GENLDC(1); FOR J := 2 TO LLENG DO BEGIN IF J = LLENG THEN M := TRUNC(PWROFTEN(LLAST)); GENLDC(M); GENLDC(1); GENLDC(8(*DMP*)); GENNR(DECOPS); GENLDC(LONGVAL[J]); GENLDC(1); GENLDC(2(*DAD*)); GENNR(DECOPS) END END ELSE IF (TYPTR^.FORM = SCALAR) AND (TYPTR <> REALPTR) THEN GENLDC(CVAL.IVAL) ELSE IF TYPTR = NILPTR THEN GEN0(31(*LDCN*)) ELSE IF TYPTR = REALPTR THEN GEN1(51(*LDC*),2) ELSE GEN1(51(*LDC*),5); VARBL: CASE ACCESS OF DRCT: IF VLEVEL = 1 THEN GEN1(39(*LDO*),DPLMT) ELSE GEN2(54(*LOD*),LEVEL-VLEVEL,DPLMT); INDRCT: GEN1(35(*IND*),IDPLMT); PACKD: GEN0(58(*LDP*)); MULTI: GEN1(60(*LDM*),TYPTR^.SIZE); BYTE: GEN0(62(*LDB*)) END; EXPR: END; WITH TYPTR^ DO IF ((FORM = POWER) OR (FORM = LONGINT) AND (KIND <> CST)) AND (KIND <> EXPR) THEN GENLDC(TYPTR^.SIZE); KIND := EXPR END END (*LOAD*) ; PROCEDURE STORE(VAR FATTR: ATTR); BEGIN WITH FATTR DO IF TYPTR <> NIL THEN CASE ACCESS OF DRCT: IF VLEVEL = 1 THEN GEN1(43(*SRO*),DPLMT) ELSE GEN2(56(*STR*),LEVEL-VLEVEL,DPLMT); INDRCT: IF IDPLMT <> 0 THEN ERROR(400) ELSE GEN0(26(*STO*)); PACKD: GEN0(59(*STP*)); MULTI: GEN1(61(*STM*),TYPTR^.SIZE); BYTE: GEN0(63(*STB*)) END END (*STORE*) ; PROCEDURE LOADADDRESS; BEGIN WITH GATTR DO IF TYPTR <> NIL THEN BEGIN CASE KIND OF CST: IF STRGTYPE(TYPTR) THEN GEN0(38(*LCA*)) ELSE ERROR(400); VARBL: CASE ACCESS OF DRCT: IF VLEVEL = 1 THEN GEN1(37(*LAO*),DPLMT) ELSE GEN2(50(*LDA*),LEVEL-VLEVEL,DPLMT); INDRCT: IF IDPLMT <> 0 THEN GEN1(34(*INC*),IDPLMT+IDPLMT); PACKD: ERROR(103) END END; KIND := VARBL; ACCESS := INDRCT; IDPLMT := 0 END END (*LOADADDRESS*) ; PROCEDURE EXPRESSION(FSYS: SETOFSYS); FORWARD; PROCEDURE SELECTOR(FSYS: SETOFSYS; FCP: CTP); VAR LATTR: ATTR; LCP: CTP; LMIN,LMAX: INTEGER; BEGIN WITH FCP^, GATTR DO BEGIN TYPTR := IDTYPE; KIND := VARBL; CASE KLASS OF ACTUALVARS: BEGIN VLEVEL := VLEV; DPLMT := VADDR; ACCESS := DRCT; IF INMODULE THEN IF TYPTR <> NIL THEN IF (VLEV = 1) AND (TYPTR^.FORM = RECORDS) THEN LOADADDRESS END; FORMALVARS: BEGIN IF VLEV = 1 THEN GEN1(39(*LDO*),VADDR) ELSE GEN2(54(*LOD*),LEVEL-VLEV,VADDR); ACCESS := INDRCT; IDPLMT := 0 END; FIELD: WITH DISPLAY[DISX] DO BEGIN IF OCCUR = CREC THEN BEGIN ACCESS := DRCT; VLEVEL := CLEV; DPLMT := CDSPL + FLDADDR END ELSE BEGIN IF LEVEL = 1 THEN GEN1(39(*LDO*),VDSPL) ELSE GEN2(54(*LOD*),0,VDSPL); ACCESS := INDRCT; IDPLMT := FLDADDR END; IF FISPACKD THEN BEGIN LOADADDRESS; IF ((FLDRBIT = 0) OR (FLDRBIT = 8)) AND (FLDWIDTH = 8) THEN BEGIN ACCESS := BYTE; IF FLDRBIT = 8 THEN GEN1(34(*INC*),1) END ELSE BEGIN ACCESS := PACKD; GENLDC(FLDWIDTH); GENLDC(FLDRBIT) END END END; FUNC: IF PFDECKIND <> DECLARED THEN ERROR(150) ELSE IF NOT INSCOPE THEN ERROR(103) ELSE BEGIN ACCESS := DRCT; VLEVEL := PFLEV + 1; DPLMT := LCAFTERMARKSTACK END END (*CASE*); IF TYPTR <> NIL THEN IF (TYPTR^.FORM <= POWER) AND (TYPTR^.SIZE > PTRSIZE) THEN BEGIN LOADADDRESS; ACCESS := MULTI END END (*WITH*); IF NOT (SY IN SELECTSYS + FSYS) THEN BEGIN ERROR(59); SKIP(SELECTSYS + FSYS) END; WHILE SY IN SELECTSYS DO BEGIN (*[*) IF SY = LBRACK THEN BEGIN REPEAT LATTR := GATTR; WITH LATTR DO IF TYPTR <> NIL THEN IF TYPTR^.FORM <> ARRAYS THEN BEGIN ERROR(138); TYPTR := NIL END; LOADADDRESS; INSYMBOL; EXPRESSION(FSYS + [COMMA,RBRACK]); LOAD; IF GATTR.TYPTR <> NIL THEN IF GATTR.TYPTR^.FORM <> SCALAR THEN ERROR(113); IF LATTR.TYPTR <> NIL THEN WITH LATTR.TYPTR^ DO BEGIN IF COMPTYPES(INXTYPE,GATTR.TYPTR) THEN BEGIN IF (INXTYPE <> NIL) AND NOT STRGTYPE(LATTR.TYPTR) THEN BEGIN GETBOUNDS(INXTYPE,LMIN,LMAX); IF RANGECHECK THEN BEGIN GENLDC(LMIN); GENLDC(LMAX); GEN0(8(*CHK*)) END; IF LMIN <> 0 THEN BEGIN GENLDC(ABS(LMIN)); IF LMIN > 0 THEN GEN0(21(*SBI*)) ELSE GEN0(2(*ADI*)) END END END ELSE ERROR(139); WITH GATTR DO BEGIN TYPTR := AELTYPE; KIND := VARBL; ACCESS := INDRCT; IDPLMT := 0; IF TYPTR <> NIL THEN IF AISPACKD THEN IF ELWIDTH = 8 THEN BEGIN ACCESS := BYTE; IF STRGTYPE(LATTR.TYPTR) AND RANGECHECK THEN GEN0(27(*IXS*)) ELSE GEN0(2(*ADI*)) END ELSE BEGIN ACCESS := PACKD; GEN2(64(*IXP*),ELSPERWD,ELWIDTH) END ELSE BEGIN GEN1(36(*IXA*),TYPTR^.SIZE); IF (TYPTR^.FORM <= POWER) AND (TYPTR^.SIZE > PTRSIZE) THEN ACCESS := MULTI END END END UNTIL SY <> COMMA; IF SY = RBRACK THEN INSYMBOL ELSE ERROR(12) END (*IF SY = LBRACK*) ELSE (*.*) IF SY = PERIOD THEN BEGIN WITH GATTR DO BEGIN IF TYPTR <> NIL THEN IF TYPTR^.FORM <> RECORDS THEN BEGIN ERROR(140); TYPTR := NIL END; INSYMBOL; IF SY = IDENT THEN BEGIN IF TYPTR <> NIL THEN BEGIN SEARCHSECTION(TYPTR^.FSTFLD,LCP); IF LCP = NIL THEN BEGIN ERROR(152); TYPTR := NIL END ELSE WITH LCP^ DO BEGIN TYPTR := IDTYPE; CASE ACCESS OF DRCT: DPLMT := DPLMT + FLDADDR; INDRCT: IDPLMT := IDPLMT + FLDADDR; MULTI,BYTE, PACKD: ERROR(400) END (*CASE ACCESS*); IF FISPACKD THEN BEGIN LOADADDRESS; IF ((FLDRBIT = 0) OR (FLDRBIT = 8)) AND (FLDWIDTH = 8) THEN BEGIN ACCESS := BYTE; IF FLDRBIT = 8 THEN GEN1(34(*INC*),1) END ELSE BEGIN ACCESS := PACKD; GENLDC(FLDWIDTH); GENLDC(FLDRBIT) END END; IF TYPTR <> NIL THEN IF (TYPTR^.FORM <= POWER) AND (TYPTR^.SIZE > PTRSIZE) THEN BEGIN LOADADDRESS; ACCESS := MULTI END END END; INSYMBOL END (*SY = IDENT*) ELSE ERROR(2) END (*WITH GATTR*) END (*IF SY = PERIOD*) ELSE (*^*) BEGIN IF GATTR.TYPTR <> NIL THEN WITH GATTR,TYPTR^ DO IF (FORM = POINTER) OR (FORM = FILES) THEN BEGIN LOAD; KIND := VARBL; ACCESS := INDRCT; IDPLMT := 0; IF FORM = POINTER THEN TYPTR := ELTYPE ELSE BEGIN TYPTR := FILTYPE; IF TYPTR = NIL THEN ERROR(399) END; IF TYPTR <> NIL THEN IF (TYPTR^.FORM <= POWER) AND (TYPTR^.SIZE > PTRSIZE) THEN ACCESS := MULTI END ELSE ERROR(141); INSYMBOL END; IF NOT (SY IN FSYS + SELECTSYS) THEN BEGIN ERROR(6); SKIP(FSYS + SELECTSYS) END END (*WHILE*) END (*SELECTOR*) ;