CONSTSTRING (9) LADATE="28 NOV 83"; ! LAST ALTERED CONSTINTEGER NO OF SNS=66 CONSTINTEGER LRLPT=X'62' UNLESS HOST=PERQ OR HOST=ACCENT THEN START CONSTINTEGER PTSHIFT=16,FLAGSHIFT=0 FINISH ELSE START CONSTINTEGER PTSHIFT=0,FLAGSHIFT=16 FINISH ! CONSTINTEGER MAXLEVELS=31,CONCOP=13 ! INCLUDE "ERCC07.TRIPCNSTS" INCLUDE "ERCC07.TRIMP_TFORM1S" CONSTINTEGER SNPT=X'1006'; ! SPECIALNAME PTYPE CONSTINTEGER UNASSPAT=X'80808080' CONSTINTEGER LABUSEDBIT=X'01000000' CONSTINTEGER LABSETBIT=X'02000000' CONSTINTEGER MAXDICT=X'100'; ! PARM MAXDICT BIT ! INTEGER I, K, DUMMYFORMAT, P1SIZE, STARSIZE, ASL, ARSIZE, OLDLINE, NEXTP, SNUM, RLEVEL, NMAX, PLABEL, LEVEL, PROFAAD, LAST INST, LINE, BFFLAG, RBASE, N, EXITLAB, CONTLAB, Q, R, FNAME, STMTS, FILE SIZE, BIMSTR, MAX ULAB, SFLABEL, NEXTTRIP INTEGERNAME SSTL,USTPTR STRING (31)MAINEP ! EXTERNALINTEGERARRAY CAS(0:12) EXTERNALRECORD (PARMF) PARM EXTERNAL RECORD (WORKAF)WORKA SYSTEMINTEGERMAPSPEC COMREG(INTEGER N) CONSTINTEGER BYTESPERKFORSOURCE=256;! FRACTION OF KB IN WK FILE ! THATS IS ALLOCATE FOR SOURCE (&LPUT) BEGIN RECORD (EMASFHDRF)NAME SHDR,WHDR WORKA_FILE ADDR=COMREG(46); ! SOURCE FILE IF CLEAN PARM=0 PARM_BITS1=COMREG(27) PARM_BITS2=COMREG(28) WORKA_WKFILEAD=COMREG(14) WHDR==RECORD(WORKA_WKFILEAD) WORKA_WKFILEK=WHDR_FBYTESIZE>>10 IF WORKA_FILE ADDR<=0 THEN START IF WORKA_FILE ADDR<-1 THEN FILESIZE=IMOD(WORKA_FILE ADDR) C ELSE FILESIZE=64000 WORKA_FILE ADDR=0 FINISH ELSE START SHDR==RECORD(WORKA_FILE ADDR) FILE SIZE=SHDR_ENDRA FINISH WORKA_NNAMES=511 IF FILESIZE>32000 THEN WORKA_NNAMES=1023 IF FILESIZE>256*1024 OR PARM_BITS2&MAXDICT#0 OR WORKA_WKFILEK>512 C THEN WORKA_NNAMES=2047 ASL=3*WORKA_NNAMES IF ASL>4095 AND (HOST#EMAS OR PARM_BITS2&MAXDICT=0) THEN ASL=4095 WORKA_ASL MAX=ASL ARSIZE=WORKA_WKFILEK*(1024-BYTESPERKFORSOURCE)-300 END BYTEINTEGERARRAYFORMAT AF(0:ARSIZE) BYTEINTEGERARRAYNAME A RECORD (LISTF)ARRAY ASLIST(0:ASL) INTEGERARRAY TAGS(0:WORKA_NNAMES) INTEGERARRAY WORD(0:WORKA_NNAMES) INTEGERARRAY DVHEADS(0:12) RECORD (LEVELF)ARRAY LEVELINF(0:MAXLEVELS) EXTERNALROUTINESPEC INITASL(RECORD (LISTF)ARRAYNAME A,INTEGERNAME B) EXTERNALINTEGERFNSPEC MORE SPACE !%EXTERNALINTEGERFNSPEC NEWCELL EXTERNALROUTINESPEC INSERTATEND(INTEGERNAME S, INTEGER A, B, C) EXTERNALROUTINESPEC INSERT AFTER(INTEGERNAME S,INTEGER A,B,C) EXTERNALROUTINESPEC POP(INTEGERNAME C, P, Q, R) EXTERNALROUTINESPEC PUSH(INTEGERNAME C, INTEGER S1, S2, S3) EXTERNALINTEGERFNSPEC FIND(INTEGER LAB, LIST) EXTERNALROUTINESPEC BINSERT(INTEGERNAME T,B,INTEGER S1,S2,S3) EXTERNALROUTINESPEC CLEARLIST(INTEGERNAME HEAD) EXTERNALROUTINESPEC FILL DTABREFS(INTEGERNAME HEAD) EXTERNALROUTINESPEC CXREF(STRING (255)NAME,INTEGER MODE,XTRA, INTEGERNAME AT) EXTERNALROUTINESPEC IMPABORT EXTERNALROUTINESPEC PROLOGUE(RECORD (LISTF)ARRAYNAME ALIST) EXTERNALROUTINESPEC EPILOGUE(INTEGER STMTS) EXTERNALROUTINESPEC PDATA(INTEGER AREA,BNDRY,L,AD) EXTERNALROUTINESPEC PRDATA(INTEGER AREA,BNDRY,L,REP,AD) EXTERNALINTEGERFNSPEC PINITOWN(INTEGER PTYPE,ACC,RECORD (RD)NAME INIT, STRINGNAME XNAME) EXTERNALINTEGERFNSPEC POWNARRAYHEAD(INTEGER PTYPE,J,LB,SIZE, AOFFSET,AAREA,DVOFFSET,STRING (31) XNAME) EXTERNALROUTINESPEC FAULT(INTEGER A,B,C) EXTERNALROUTINESPEC WARN(INTEGER N,V) EXTERNALROUTINESPEC TRIP OPT(RECORD (TRIPF)ARRAYNAME T, INTEGERNAME NEXT TRIP) EXTERNALROUTINESPEC MOVE BYTES(INTEGER LENGTH,FBASE,FOFF,TOBASE,TOOFF) EXTERNALROUTINESPEC CTOP(INTEGERNAME OP,MASK,INTEGER XTRA, RECORD (RD)NAME OPND1,OPND2) IF HOST#TARGET START EXTERNALROUTINESPEC REFORMATC(RECORD (RD)NAME OPND) EXTERNALROUTINESPEC CHANGE SEX(INTEGER BASEAD,OFFSET,L) FINISH EXTERNALROUTINESPEC GENERATE(RECORD (TRIPF)ARRAYNAME T, INTEGER CURRLEVEL,ROUTINE GETWSP(INTEGERNAME PL,INTEGER SIZE)) EXTERNALROUTINESPEC PRINTLIST(INTEGER HEAD) ! START OF COMPILATION K=BYTESPERKFORSOURCE//(HOST//10); ! DISTINGUISH BYTE&WORD ADDRESSED HOSTS ! ALLOW FOR BYTE & WORD ADDRESS M-CS A==ARRAY(WORKA_WKFILE AD+K*WORKA_WKFILEK, AF) BEGIN !*********************************************************************** !* THIS BLOCK INITIALISE THE COMPILER SCALARS AND ARRAYS * !* WAS ORIGINALLY ROUTINE 'INITIALISE'. * !* THE INITIALISATION OF THE CONSTANT LISTS WITH THE VALUES * !* IN PERM MAY BE OMITTED IN BATCH OR CUT-DOWN VERSIONS. * !*********************************************************************** EXTERNALINTEGERFNSPEC PASSONE WORKA_CCSIZE=BYTESPERKFORSOURCE*(WORKA_WKFILEK-1);! CCSIZE ALWAYS AS BYTES BYTEINTEGERARRAYFORMAT CCF(0:WORKA_CCSIZE) BYTEINTEGERARRAYNAME CC CC==ARRAY(WORKA_WKFILEAD+32,CCF) WORKA_CC==CC WORKA_A==A WORKA_WORD==WORD WORKA_TAGS==TAGS WORKA_LINE==LINE WORKA_RELEASE=RELEASE WORKA_LADATE=LADATE WORKA_AASL0=ADDR(ASLIST(0)) WORKA_AMAINEP=ADDR(MAINEP) WORKA_LASTTRIP=WORKA_CCSIZE//40 -2; ! 40 IS SIZE OF THE TRIP ARRAY IF WORKA_LASTTRIP>699 THEN WORKA_LASTTRIP=699 PLABEL=24999 N=12; MAX ULAB=WORKA_NNAMES+16384; ! LARGEST VALID USER LABEL LAST INST=0 SFLABEL=20999 EXITLAB=0; CONTLAB=0 RLEVEL=0; NMAX=0; BFFLAG=0 RBASE=1 SSTL==CAS(4); USTPTR==CAS(5) STMTS=1; SNUM=0 BIMSTR=0 WORKA_RTCOUNT=1; ! ROUTINE 0 RESERVED FOR MAIN PROG MAINEP="s#go"; ! DEFAULT MAIN ENTRY INITASL(ASLIST,ASL) CYCLE I=0,1,12 CAS(I)=0; DVHEADS(I)=0 REPEAT ! DUMMY FORMAT=0; ! DUMMY RECORD FORMAT PUSH(DUMMY FORMAT,0,0,0); ! FOR BETTER ERROR RECOVERY P1SIZE=PASSONE R=P1SIZE WORKA_ARTOP=P1SIZE END ; ! OF BLOCK CONTAINING PASS 1 BEGIN !*********************************************************************** !* SECOND OR TRIPLES GENERATING PASS * !*********************************************************************** RECORD (LEVELF)NAME CURRINF INTEGER TWSPHEAD IF HOST=EMAS OR HOST=IBM OR HOST=IBMXA START ; ! LPUT BASED WORKFILE USED FOR OBJECT RECORD (TRIPF)ARRAY TRIPLES(0:WORKA_LASTTRIP) FINISH ELSE START RECORD (TRIPF)ARRAYFORMAT TRIPLESFORM(0:WORKA_LASTTRIP) RECORD (TRIPF)ARRAYNAME TRIPLES TRIPLES==ARRAY(WORKA_WKFILEAD+32,TRIPLESFORM) FINISH INTEGERARRAYFORMAT CF(0:12*WORKA_NNAMES) INTEGERARRAYNAME CTABLE !%ROUTINESPEC NOTE CREF(%INTEGER CA) !%ROUTINESPEC STORE CONST(%INTEGERNAME D,%INTEGER L,AD) !%INTEGERFNSPEC WORD CONST(%INTEGER VALUE) ROUTINESPEC REUSE TEMPS ROUTINESPEC GET WSP(INTEGERNAME PLACE,INTEGER SIZE) ROUTINESPEC RETURN WSP(INTEGER PLACE,SIZE) ROUTINESPEC COMPILE A STMNT INTEGERFNSPEC NEW TRIP INTEGERFNSPEC FROMAR4(INTEGER PTR) INTEGERFNSPEC FROMAR2(INTEGER PTR) INTEGERFNSPEC UCONSTTRIP(INTEGER OPERN,OPTYPE,FLAGS,CONST) INTEGERFNSPEC ULCONSTTRIP(INTEGER OPERN,OPTYPE,FLAGS,CONST1,CONST2) INTEGERFNSPEC UNAMETRIP(INTEGER OPERN,OPTYPE,FLAGS,NAME) INTEGERFNSPEC UTEMPTRIP(INTEGER OPERN,OPTYPE,FLAGS,TEMP) INTEGERFNSPEC BRECTRIP(INTEGER OPERN,OPTYPE,FLAGS, RECORD (RD)NAME OPND1,OPND2) INTEGERFNSPEC URECTRIP(INTEGER OPERN,OPTYPE,FLAG,RECORD (RD)NAME OPND1) ROUTINESPEC KEEPUSECOUNT(RECORD (RD)NAME OPND) ROUTINESPEC CSS(INTEGER P) CYCLE I=0, 1, MAXLEVELS LEVELINF(I)=0 LEVELINF(I)_NAMES=-1 REPEAT CTABLE==ARRAY(ADDR(ASLIST(1)),CF) WORKA_CTABLE==CTABLE WORKA_LEVELINF==LEVELINF CTABLE(0)=M'CTAB' LINE=0 TWSPHEAD=0 PROLOGUE(ASLIST) NEXTTRIP=1 TRIPLES(0)=0 NEXTP=1; LEVEL=1; STMTS=0 CURRINF==LEVELINF(LEVEL) RLEVEL=0; RBASE=0 WHILE A(NEXTP+3)!A(NEXTP+4)#0 CYCLE COMPILE A STMNT REPEAT LINE=99999 EPILOGUE(STMTS) IF HOST=PERQ START *RETURN; ! JUMP WONT REACH! FINISH ELSE ->P2END ROUTINE FORCE TRIPS !*********************************************************************** !* FORCE OUT THE TRIPLES TO CODE. NEEDED IN CEND ETC * !*********************************************************************** RETURN IF NEXT TRIP=1 IF PARM_OPT=0 THEN TRIP OPT(TRIPLES,NEXT TRIP) GENERATE(TRIPLES,LEVEL,GET WSP) TRIPLES(0)=0 NEXTTRIP=1 TRIPLES(0)_FLINK=NEXT TRIP END ROUTINE COMPILE A STMNT INTEGER I FORCE TRIPS IF NEXT TRIP>1 IF TWSPHEAD#0 THEN REUSE TEMPS I=NEXTP STARSIZE=A(NEXTP)<<16+A(NEXTP+1)<<8+A(NEXTP+2) NEXTP=NEXTP+STARSIZE LINE=A(I+3)<<8+A(I+4) STMTS=STMTS+1 CSS(I+5) ! %CYCLE I=0,1,4 ! %REPEAT ! CHECK ASL %IF LINE&7=0 END ROUTINE CSS(INTEGER P) ROUTINESPEC ENTER JUMP(INTEGER MASK,STAD,FLAG) INTEGERFNSPEC ENTER LAB(INTEGER M,FLAG) ROUTINESPEC REMOVE LAB(INTEGER LAB) ROUTINESPEC SAVE STACK PTR ROUTINESPEC CEND(INTEGER KKK) INTEGERFNSPEC CCOND(INTEGER CTO,A,B,JFLAGS) INTEGERFNSPEC REVERSE(INTEGER MASK) ROUTINESPEC SET LINE ROUTINESPEC CUI(INTEGER CODE) ROUTINESPEC ASSIGN(INTEGER A,B) ROUTINESPEC CSTART(INTEGER CCRES,MODE) INTEGERFNSPEC CHECKBLOCK(INTEGER P,PIN) ROUTINESPEC CCYCBODY(INTEGER UA,ELAB,CLAB) ROUTINESPEC CLOOP(INTEGER ALT,MARKC,MARKUI) ROUTINESPEC CIFTHEN(INTEGER MARKIU,MARKC,MARKUI,MARKE,MARKR,SKIP) INTEGERFNSPEC CREATE AH(INTEGER MODE,RECORD (RD)NAME EOPND,NOPND) ROUTINESPEC TORP(INTEGERNAME HEAD,BOT,NOPS) INTEGERFNSPEC INTEXP(INTEGERNAME VALUE,INTEGER PRECTYPE) INTEGERFNSPEC CONSTEXP(INTEGER PRECTYPE) ROUTINESPEC CSEXP(INTEGER MODE) ROUTINESPEC CSTREXP(INTEGER B) ROUTINESPEC CRES(INTEGER LAB) ROUTINESPEC EXPOP(INTEGERNAME A,B,INTEGER C,D) ROUTINESPEC TEST APP(INTEGERNAME NUM) ROUTINESPEC SKIP EXP ROUTINESPEC SKIP APP ROUTINESPEC NO APP INTEGERFNSPEC DOPE VECTOR(INTEGER A,B,MODE,ID,INTEGERNAME C,D) ROUTINESPEC DECLARE ARRAYS(INTEGER A,B) ROUTINESPEC DECLARE SCALARS(INTEGER B) ROUTINESPEC CRSPEC(INTEGER M) INTEGERFNSPEC SET SWITCHLAB(INTEGER HEAD,LAB,FNAME,BIT) ROUTINESPEC CFPLIST(INTEGERNAME A,B) ROUTINESPEC CFPDEL ROUTINESPEC CLT INTEGERFNSPEC ROUNDING LENGTH(INTEGER PTYPE,RULES) ROUTINESPEC CQN(INTEGER P) INTEGERFNSPEC TSEXP(INTEGERNAME VALUE) ROUTINESPEC CRCALL(INTEGER RTNAME) ROUTINESPEC NAMEOP(INTEGER Z,SIZE,NAMEP) ROUTINESPEC CNAME(INTEGER Z) ROUTINESPEC AATORP(INTEGERNAME A,B,C,INTEGER D,E,F) ROUTINESPEC CANAME(INTEGER Z,ARRP,BS,DP) ROUTINESPEC CSNAME(INTEGER Z) ROUTINESPEC COPY TAG(INTEGER KK) ROUTINESPEC REDUCE TAG ROUTINESPEC STORE TAG(INTEGER KK,LEVEL,RBASE,J,SNDISP,ACC,SLINK,KFORM) ROUTINESPEC UNPACK ROUTINESPEC PACK(INTEGERNAME PTYPE) ROUTINESPEC RDISPLAY(INTEGER KK) ROUTINESPEC RHEAD(INTEGER RTNAME,AXNAME) INTEGERFNSPEC CFORMATREF ROUTINESPEC CRFORMAT(INTEGERNAME OPHEAD,OPBOT,NLIST,MRL,INTEGER INIT) INTEGERFNSPEC DISPLACEMENT(INTEGER LINK) INTEGERFNSPEC COPY RECORD TAG(INTEGERNAME SUBS) SWITCH SW(1:24) CONSTBYTEINTEGERARRAY FCOMP(0:14)=0, 8,10,2,7,12,4,7, 8,12,4,7,10,2,7; INTEGER SNDISP,ACC,K,KFORM,STNAME,MIDCELL INTEGER TCELL,JJ,JJJ,KK,QQ,MARKER,REPORTUI,XDISP,MASK, C BASE,AREA,ACCESS,DISP,EXTRN, CURR INST,VALUE,STRINGL, C PTYPE,I,J,OLDI,USEBITS,STRFNRES,BML,DML, C MARKIU,MARKUI,MARKC,MARKE,MARKR,INAFORMAT INTEGER LITL,ROUT,NAM,ARR,PREC,TYPE RECORD (RD) EXPOPND,NAMEOPND; ! RESULT RECORD FOR EXPOP&CNAME CURR INST=0; INAFORMAT=0 ->SW(A(P)) SW(13): ! INCLUDE SOMETHING SW(24): ! REDUNDANT SEP SW(2): ! <CMARK> <COMMENT TEXT> CSSEXIT: LAST INST=CURR INST RETURN SW(1): !(UI)(S) FAULT(57,0,0) UNLESS LEVEL>=2 MARKER=P+1+A(P+1)<<8+A(P+2) P=P+3 ->LABFND IF A(MARKER)=1 IF A(MARKER)=2 THEN SET LINE AND CUI(0) AND ->CSSEXIT MARKE=0; MARKR=0 MARKUI=P; MARKIU=MARKER+1 MARKC=MARKIU+1 IF A(MARKER)=3 THEN CIFTHEN(MARKIU,MARKC,MARKUI,0,0,NO) C AND ->CSSEXIT CLOOP(A(MARKIU),MARKC+2,MARKUI) ->CSSEXIT LABFND: OLDLINE=0 ->SWITCH UNLESS A(P)=1 AND A(P+5)=2; ! 1ST OF UI AND NO APP ->SWITCH UNLESS A(P+6)=2 AND A(P+7)=2;! NO ENAMSE OR ASSNMNT JJ=ENTER LAB(FROM AR2(P+3),0); ->CSSEXIT SW(5): ! %CYCLE FAULT(57,0,0) UNLESS LEVEL>=2 IF A(P+5)=2 THEN START ; ! OPEN CYCLE CLOOP(0,P+1,P+1) FINISH ELSE START SET LINE CLOOP(6,P+6,P+1) FINISH ->CSSEXIT ! SW(6): ! REPEAT ->CSSEXIT SW(22): ! '%CONTROL' (CONST) J=FROM AR4(P+2) PARM_DCOMP=J>>28; ->CSSEXIT ! SW(3): ! (%IU)(COND)%THEN(UI)(ELSE') MARKIU=P+1; MARKC=MARKIU+3 MARKR=P+2+A(P+2)<<8+A(P+3); ! ! FROMAR2(P+2) MARKE=0 IF A(MARKR)=3 THEN START MARKE=MARKR+1+FROMAR2(MARKR+1) MARKUI=MARKR+3 FINISH CIFTHEN(MARKIU,MARKC,MARKUI,MARKE,MARKR,NO) ->CSSEXIT SW(4): ! '%FINISH(ELSE')(S) SW(18): ! '%ELSE' MEANING FINISH ELSE START ->CSSEXIT SWITCH: BEGIN ; ! SWITCH LABEL INTEGER NAPS,FNAME FNAME=FROM AR2(P+3) UNLESS A(P)=1 AND A(P+5)=1 THEN FAULT(5,0,FNAME) AND ->BEND ! 1ST OF UI + APP P=P+3; TEST APP(NAPS) P=P+6 UNLESS INTEXP(JJ,MINAPT)=0 THEN FAULT(41,0,0) AND ->BEND ! UNLESS EXPRESSION EVALUATES AND UNLESS NAPS=1 THEN FAULT(21,NAPS-1,FNAME) AND ->BEND ! NO REST OF APP UNLESS A(P+1)=2=A(P+2) THEN FAULT(5,0,FNAME) AND ->BEND ! NO ENAME OR REST OF ASSIGMENT COPY TAG(FNAME) IF OLDI#LEVEL OR TYPE#6 THEN FAULT(4,0,FNAME) AND ->BEND IF SET SWITCHLAB(K,JJ,FNAME,1)#0 THEN FAULT(6,JJ,FNAME) BEND: END ; ->CSSEXIT SW(23): ! SWITCH(*): BEGIN RECORD (LISTF)NAME LCELL INTEGER FNAME,JJ,RES FNAME=FROM AR2(P+1) COPY TAG (FNAME) IF OLDI=LEVEL AND TYPE=6 START LCELL==ASLIST(K) CYCLE JJ=LCELL_S2,1,LCELL_S3 RES=SET SWITCHLAB(K,JJ,FNAME,0) REPEAT FINISH ELSE FAULT(4,0,FNAME) END ; ->CSSEXIT ! SW(7): ! (%WU)(SC)(COND)(RESTOFWU) FAULT(57,0,0) UNLESS LEVEL>=2 MARKIU=P+1; ! TO WHILE/UNTIL MARKC=MARKIU+3; ! TO (SC)(COND) CLOOP(A(MARKIU)+3,MARKC,MARKIU+1+FROMAR2(MARKIU+1)) ->CSSEXIT ! SW(8): ! SIMPLE DECLN FAULT(57,0,0) UNLESS LEVEL>=2 FAULT(40,0,0) IF CURRINF_NMDECS&1#0 P=P+1 MARKER=P+FROMAR2(P); ! TO ALT OF DECLN P=P+2; ROUT=0; LITL=0 IF A(MARKER)#1 THEN START ; ! ARRAY DECLARATIONS CLT IF TYPE=5 AND (ACC<=0 OR ACC>256) THEN C FAULT(70,ACC-1,0) AND ACC=255 NAM=0 SET LINE QQ=2-A(P+1); P=P+2; ! QQ=1 FOR ARRAYFORMATS DECLARE ARRAYS(QQ,KFORM) FINISH ELSE START CLT CQN(P+1); P=P+2 DECLARE SCALARS(KFORM) FINISH ->CSSEXIT ! SW(9): ! %END BEGIN SWITCH S(1:5) -> S(A(P+1)) S(1): ! ENDOFPROGRAM S(2): ! ENDOFFILE IF PARM_CPRMODE=0 THEN PARM_CPRMODE=2 FAULT(15,LEVEL+PARM_CPRMODE-3,0) UNLESS LEVEL+PARM_CPRMODE=3 CEND(PARM_CPRMODE) ->BEND S(3): ! ENDOFLIST ->BEND S(4): ! END IF PARM_CPRMODE=1 AND LEVEL=2 THEN FAULT(14,0,0) ELSE C CEND(CURRINF_FLAG) BEND: END ->CSSEXIT ! SW(11): BEGIN INTEGER MARKER1,RTNAME,KKK,PTR,PTYPEP,CNT,PP,PCHAIN,AXNAME,PNAME, NPARAMS,SCHAIN,PARMSPACE,D RECORD (LISTF)NAME LCELL,TCELL P=P+1; MARKER1=FROM AR2(P)+P; ! (SEX)(RT)(SPEC')(NAME)(FPP) AGN: Q=P; RTNAME=FROM AR2(MARKER1+1); ! RTNAME ON NAME EXTRN=A(P+2); ! 1=SYSTEM,2=EXTERNAL ! 3=DYNAMIC, 4=INTERNAL LITL=EXTRN&3 IF A(MARKER1)=1 THEN START ; ! P<%SPEC'>='%SPEC' P=P+3; CRSPEC(1-EXTRN>>2); ! 0 FOR ROUTINESPEC ! 1 FOR EXTERNAL (ETC) SPEC ->BEND FINISH COPY TAG(RTNAME) AXNAME=ADDR(WORKA_LETT(WORD(RTNAME))) IF EXTRN=3 THEN EXTRN=2 IF TARGET=EMAS AND EXTRN=1 THEN WARN(11,0) IF A(MARKER1+3)=1 THEN START MOVE BYTES(A(MARKER1+4)+1,ADDR(A(0)),MARKER1+4, ADDR(A(0)),WORKA_ARTOP) AXNAME=ADDR(A(WORKA_ARTOP)) WORKA_ARTOP=(WORKA_ARTOP+3+A(MARKER1+4))&(-4) FINISH IF EXTRN=4 THEN AXNAME=0 IF OLDI#LEVEL THEN START ; ! NAME NOT KNOWN AT THIS LEVEL P=Q+3; CRSPEC(0); P=Q; ->AGN FINISH ELSE START ; ! NAME ALREADY KNOWN AT THIS LEVEL IF PARM_CPRMODE=0 THEN PARM_CPRMODE=2; ! FLAG AS FILE OF ROUTINES FAULT(56,0,RTNAME) UNLESS EXTRN=4 OR C (PARM_CPRMODE=2 AND LEVEL=1) IF A(P+3)=1 THEN KKK=LITL<<14!X'1000' ELSE START ROUT=1; P=P+4; ! FIGURE OUT PTYPE FOR FNS&MAPS CLT; ARR=0; NAM=0 IF A(P)=2 THEN NAM=2; ! SET NAME ARRAY BIT FOR MAPS PACK(KKK); ! AND STORE PTYPE IN KKK FINISH FINISH ! ! UNLESS A MATCH WAS OBTAINED BETWEEN HEADING AND SPEC SOMETHING ! HAS GONE WRONG. COMPILE HEADING AGAIN AS SPEC. THIS WILL ! PREVENT ANY INCONSISTENCIED AND CAUSE A "NAME SET TWICE" ! FOR ANY ERROR ! UNLESS (J=15 OR J=7*EXTRN) AND PTYPE&X'FFFF'=KKK START P=Q+3; CRSPEC(0); P=Q; ->AGN FINISH PTYPE=PTYPE!(EXTRN&3)<<14; ! DEAL WITH %ROUTINESPEC FOLLOWED ! BY %EXTERNALROUTINE ! ! RESET THE TAGS TO BODY GIVEN AND ALLOWING FOR SPEC/EXTERNALROUTINE ! AND EXTERNALSPEC/EXTERNAL ROUTINE COMBINATIONS. RESTORE THE USE ! BITS WHICH WILL SHOW USED AS A RESULT OF THE COPYTAG IN THIS SEQUENCE ! TCELL==ASLIST(TAGS(RTNAME)) TCELL_PTYPE<-PTYPE TCELL_UIOJ<-TCELL_UIOJ&X'3FF0'!USEBITS<<14 ! NEWPTYPE & SET J=0 IF J=14 THEN TCELL_S2=WORKA_RTCOUNT AND C WORKA_RTCOUNT=WORKA_RTCOUNT+1; ! NO RT NO ALLOCATED TO EXTERNAL SPECS PTYPEP=PTYPE PCHAIN=TCELL_SLINK; ! CHAIN OF PARAMETER DESCRIPTUONS RHEAD(RTNAME,AXNAME); ! FIRST PART OF ENTRY SEQUENCE ! ! NOW DECLARE THE FORMAL PARAMETERS. FOLLOW BY CLAIMING DISPLAY ! AND SETTING DIAGNOSTIC PTR IN ROUTINE RDISPLAY ! P=MARKER1+4 IF A(P-1)=1 THEN P=P+A(P)+1; ! SKIP OVER ALIASNAME CNT=0 PTYPE=PTYPEP; UNPACK N=RTPARAM1OFFSET IF TARGET=PERQ OR TARGET=ACCENT START IF TYPE#0 THEN N=(BYTES(PREC)+1)&(-2) IF NAM#0 OR TYPE=5 THEN N=4; ! MAPS CURRINF_RESSIZE=N FINISH NPARAMS=0; PARMSPACE=0 IF PCHAIN#0 THEN NPARAMS=ASLIST(PCHAIN)_S3 IF NPARAMS#0 THEN PARMSPACE=NPARAMS>>16 AND NPARAMS=NPARAMS&X'FFFF' ! ALLOW ACTUAL PARAMETER SPACE WHILE A(P)=1 CYCLE ; ! WHILE SOME (MORE) FP PART PP=P+1+FROMAR2(P+1) P=P+3 CFPDEL PTR=P UNTIL A(PTR-1)=2 CYCLE ; ! CYCLE DOWN NAMELIST IF PARAMS BWARDS=YES START ;! MAP PCHAIN TO REVERSE ORDER LIST PCHAIN=TCELL_SLINK PCHAIN=ASLIST(PCHAIN)_LINK FOR KKK=2,1,NPARAMS-CNT FINISH IF PCHAIN#0 THEN START LCELL==ASLIST(PCHAIN); ! EXTRACT PTYPE XTRA INFO UNLESS LCELL_PTYPE=PTYPE AND LCELL_ACC=ACC C THEN FAULT(9,CNT+1,RTNAME) FINISH PNAME=FROM AR2(PTR); ! NAME FOR PARAM INTERNALLY LCELL_UIOJ=LCELL_UIOJ!PNAME<<4;! SAVED IN LIST D=LCELL_SNDISP+N; ! PARAMETER OFFSET IF ROUT=1 START ; ! PROCEDURE PARAMETERS P=PTR P=P+3 UNTIL A(P-1)=2 CFPLIST(SCHAIN,KKK); ! PARAMETERLIST FOR PASSED PROC PTYPE=LCELL_PTYPE; ! CHANGED BY CFPLIST STORETAG(PNAME,LEVEL,RBASE,13,D,LCELL_ACC,SCHAIN,0) FINISH ELSE START IF TARGET=EMAS AND PTYPE=X'33' C THEN D=D+8; ! FOR HISTORIC PARAMTER COMPATABILITY IF STRVALINWA=YES AND PTYPE=X'35' THEN PTYPE=X'435' STORE TAG(PNAME,LEVEL,RBASE,LCELL_UIOJ&15,0,ACC,D,KFORM) IF STRVALINWA=YES AND PTYPE=X'435' THEN PTYPE=LCELL_PTYPE FINISH PTR=PTR+3 CNT=CNT+1 PCHAIN=LCELL_LINK IF PARAMS BWARDS=NO REPEAT P=PP REPEAT ; ! UNTIL NO MORE FP-PART N=N+PARMSPACE N=(N+MINPARAMSIZE-1)&(-MINPARAMSIZE);! TO WORD BOUNDARY AFTER ALL SYSTEM ! STANDARD PARAMETERS HAVE BEEN DECLARED FAULT(8,0,RTNAME) IF CNT>NPARAMS FAULT(10,0,RTNAME) IF CNT<NPARAMS PTYPE=PTYPEP IF STRRESINWA=YES START ; ! NEEDS FN RESULT DESC UNLESS 3#PTYPE&X'F0F'#5 THEN N=N+PTRSIZE(X'35'); ! STR FNS RESULT PARAM IS STACKED CURRINF_RESSIZE=N FINISH IF TARGET=PNX THEN START N=N+8; ! SPACE FOR PC&OLDLNB IMPABORT IF N&7#0 FINISH ! AS XTRA PARM JUST BEFORE DISPLAY RDISPLAY(RTNAME) BEND: END ; ->CSSEXIT ! SW(14): ! %BEGIN BEGIN PTYPE=0 IF LEVEL=1 AND RLEVEL=0 START IF PARM_CPRMODE=0 THEN START RLEVEL=1; RBASE=1 PARM_CPRMODE=1 RHEAD(-1,ADDR(MAINEP)) N=RTPARAM1OFFSET FINISH ELSE FAULT(58,0,0) FINISH ELSE START SET LINE; ! SO 'ENTERED FROM LINE' IS OK RHEAD(-1,0) FINISH RDISPLAY(-1) END ->CSSEXIT ! SW(15): ! '%ON'(EVENT')(N)(NLIST)'%START' FAULT(57,0,0) UNLESS LEVEL>=2 FAULT(40,0,0) IF CURRINF_NMDECS&1#0 CURRINF_NMDECS=CURRINF_NMDECS!X'11';! NO MORE DECS AND IN ONCOND IF TARGET=EMAS THEN SAVE STACK PTR;! NEEDED WITH AUXSTACKS ONLY JJ=UCONSTTRIP(ONEV1,X'51',DONTOPT,0);! SAVE PROGRAM MASK ETC PLABEL=PLABEL-1 JJJ=PLABEL ENTER JUMP(15,JJJ,B'10'); ! JUMP ROUND ON BODY ! P=P+1; JJ=0; ! SET UP A BITMASK IN JJ UNTIL A(P)=2 CYCLE ; ! UNTIL NO MORE NLIST KK=-1; P=P+4 FAULT(26,KK,0) UNLESS INTEXP(KK,MINAPT)=0 AND 1<=KK<=14 JJ=JJ!1<<(KK-1) REPEAT P=P+1 CURRINF_ONWORD=JJ<<18 LEVELINF(0)_ONWORD=LEVELINF(0)_ONWORD!JJ<<18 CURRINF_ONINF=N; N=N+12 JJ=UCONSTTRIP(ONEV2,X'51',DONTOPT,JJ) OLDLINE=0 CSTART(0,3) CURRINF_NMDECS=CURRINF_NMDECS!!X'10';! NOT IN ONCOND JJ=ENTER LAB(JJJ,B'111'); ! REPLACE ENVIRONMENT ->CSSEXIT SW(16): BEGIN ; ! %SWITCH (SWITCH LIST) INTEGER Q,RANGE,KKK,LB,UB,PP,D0,OPHEAD,V,R RECORD (RD) OPND1,OPND2 FAULT(57,0,0) UNLESS LEVEL>=2 Q=P UNLESS TARGET=EMAS THEN PLABEL=PLABEL-1 AND ENTER JUMP(15,PLABEL,0) UNTIL A(Q)=2 CYCLE ; ! UNTIL NO'REST OF SW LIST' P=P+3 P=P+3 WHILE A(P)=1 P=P+4; ! TO P(+') KKK=INTEXP(LB,MINAPT); ! EXTRACT LOWER BOUND P=P+3 KKK=KKK!INTEXP(UB,MINAPT); ! EXTRACT UPPER BOUND RANGE=(UB-LB+1) IF RANGE<=0 OR KKK#0 START FAULT(38,1-RANGE,FROMAR2(Q+1)) LB=0; UB=10; RANGE=11 FINISH PTYPE=X'56'+1<<8; ! WORD LABEL ARRAY PP=P; P=Q+1 UNTIL A(P-1)=2 CYCLE ; ! DOWN NAMELIST K=FROM AR2(P) P=P+3 OPHEAD=0; R=LB ! ! SET UP A BIT LIST (96 BITS PER CELL) TO CHECK FOR SWITCH LABELS ! SET TWICE ! UNTIL R>UB CYCLE PUSH(OPHEAD,0,0,0) R=R+96 REPEAT OPND1_S1=PTYPE<<PTSHIFT!DNAME<<FLAGSHIFT OPND1_D=K OPND1_XTRA=0 OPND2_S1=X'61'<<PTSHIFT!DNAME<<FLAGSHIFT OPND2_D=LB OPND2_XTRA=UB V=BRECTRIP(DCLSW,PTYPE,0,OPND1,OPND2) PUSH(OPHEAD,0,LB,UB) STORE TAG(K,LEVEL,RBASE,1,0,4,OPHEAD,0) ! !THE TABLE WILL CONSIST OF RELATIVE DISPLACEMENTS FROM EACH ENTRY ! TO THE LABEL POSN. SET ALL TO GO TO PLAB(6) INITIALLY ! REPEAT ; ! FOR ANY MORE NAMES IN NAMELIST Q=PP; P=Q REPEAT ; ! UNTIL A(Q)=2 UNLESS TARGET=EMAS THEN KKK=ENTER LAB(PLABEL,0);! COMPLETE JUMP AROUND TABLE END ;->CSSEXIT ! SW(17): ->CSSEXIT ! SW(12): ! '%OWN' (TYPE)(OWNDEC) BEGIN !*********************************************************************** !* INITIALISED DECLARATION GO INTO THE GLA OR GLA SYMBOL TABLES * !* EXCEPT FOR CONST ARRAYS WHICH GO INTO THE CODE SYMBOL TABLES * !* STRINGS AND ARRAYS HAVE A HEADER IN THE GLA. QPUT ARRANGES * !* FOR THE LOADER TO RELOCATE THE HEADERS. * !* EXTERNALS ARE IDENTICAL WITH OWN BUT ALSO HAVE A DATA EP DEFN * !* IN THE LOAD DATA SO THEY CAN BE FOUND AT LOAD TIME * !* EXTRINSICS HAVE A DATA REFERENCE AND A DUMMY HEADER IN THE GLA* !* THE LOADER USES THE FORMER TO RELOCATE THE LATTER. * !*********************************************************************** ROUTINESPEC CLEAR(INTEGER L) ROUTINESPEC XTRACT CONST(INTEGER CONTYPE, CONPREC) ROUTINESPEC INIT SPACE(INTEGER A, B) INTEGER SLENGTH, PP, SIGN, TAGDISP, DVO, K, STALLOC, SPOINT, CONSTSFOUND, CPREC, EXTRN, NNAMES, C MARK, QPUTP, LB, CTYPE, CONSTP, FORMAT,DPTYPE, C DIMEN, SACC, TYPEP, KK RECORD (RD) COPND,FCOPND OWNLONGREAL ZERO=0 STRING (255) SCONST, NAMTXT RECORD (LISTF)NAME LCELL INTEGERNAME STPTR QPUTP=5; STPTR==USTPTR; ! NORMAL CASE GLA SYMBOLTABLES ! FAULT(40,0,0) %IF NMDECS&1#0 EXTRN=A(P+1) P=P+2 IF EXTRN>=4 THEN EXTRN=0; ! CONST & CONSTANT->0 SNDISP=0 CONSTS FOUND=0 IF EXTRN=0 THEN QPUTP=4 AND STPTR==SSTL CLT ! ! CHECK FOR %SPEC AND CHANGE EXTERNAL SPEC TO EXTRINSIC ! IF A(P+2)=1 START IF EXTRN=2 THEN EXTRN=3 ELSE FAULT(46,0,0) FINISH IF 2<=EXTRN<=3 AND ((A(P)=1 AND A(P+1)#3) OR C (A(P)=2 AND A(P+1)#2)) THEN FAULT(46,0,0) LITL=EXTRN IF LITL<=1 THEN LITL=LITL!!1 IF A(P)=1 THEN CQN(P+1) ELSE ARR=1 AND NAM=0 IF TYPE=5 AND NAM=0 AND (ACC<=0 OR ACC>256) THEN C FAULT(70,ACC-1,0) AND ACC=2 STALLOC=ACC; ! ALLOCATION OF STORE FOR ITEM OR POINTER IF (TARGET=PERQ OR TARGET=ACCENT OR TARGET=PNX) AND TYPE=5 THEN C STALLOC=(STALLOC+1)&X'FFE' ROUT=0; PACK(PTYPE); DPTYPE=PTYPE;! FOR DECLARATION IF NAM#0 START ; ! OWN POINTERS IF ARR#0 THEN STALLOC=8 ELSE STALLOC=4 FINISH ELSE START ; ! OWN VARS & ARRAYS ->NON SCALAR IF ARR#0 FINISH P=P+2 UNTIL A(MARK)=2 CYCLE ; ! UNTIL <RESTOFOWNDEC> NULL MARK=P+1+FROM AR2(P+1) PP=P+3; P=PP+2; ! PP ON FIRST NAME' K=FROM AR2(PP); ! FOR ERROR MESSAGES RE CONST NAMTXT=STRING(ADDR(WORKA_LETT(WORD(K)))) IF A(P)=1 THEN START ; ! ALAIS GIVEN IF LITL=0 THEN WARN(10,0) LENGTH(NAMTXT)=A(P+1) CHARNO(NAMTXT,KK)=A(P+KK+1) FOR KK=1,1,A(P+1) P=P+A(P+1)+1 FINISH P=P+1; ! P ON CONST' ! ! OBTAIN THE INITIAL CONSTANT,ITS TYPE(CTYPE) AND SIGN(SIGN) ! SCONST="" PTYPE=DPTYPE; UNPACK; ! MAY HAVE BEEN CONSTANT EVALUATIONS ! WHICH HAVE CHANGED PTYPE SIGN=3; CTYPE=TYPE; CONSTSFOUND=0; CPREC=PREC IF TYPE=3 THEN CTYPE=1; ! RECS INITTED TO REPEATED BYTE IF NAM#0 THEN CTYPE=1 AND CPREC=5 P=P+1 IF A(P-1)=1 THEN START ; ! CONSTANT GIVEN XTRACT CONST(CTYPE,CPREC) FINISH ELSE START WARN(7,K) IF EXTRN=0; ! %CONST NOT INITIALISED FCOPND=0; COPND=0 FINISH J=0 IF NAM#0 THEN START ; ! OWNNAMES AND ARRAYNAMES IF ARR=0 THEN START TAGDISP=PINITOWN(PTYPE,ACC,FCOPND,NAMTXT) FINISH ELSE START ; ! ARRAYNAMES DVO=DOPE VECTOR(TYPE,ACC,-1,K,QQ,LB) IF PARM_COMPILER#0 AND LB#0 THEN FAULT(99,0,0) IF EXTRN#0 THEN SNDISP=0 AND J=0 ELSE C J=1 AND SNDISP=(SNDISP&X'3FFFF')>>2 TAGDISP=POWNARRAYHEAD(PTYPE,J,LB,X'FFFFFF', FCOPND_D,0,DVO,NAMTXT) FINISH STORE TAG(K,LEVEL,0,J,SNDISP,ACC,TAGDISP,KFORM) P=MARK CONTINUE FINISH IF EXTRN=3 THEN START ; ! EXTRINISIC PTYPE=PTYPE!X'400'; ! FORCE NAM=1 (IE VIA POINTER) FCOPND_D=0 TAGDISP=PINITOWN(PTYPE,ACC,FCOPND,NAMTXT) STORE TAG(K,LEVEL,0,J,SNDISP,ACC,TAGDISP,KFORM) P=MARK CONTINUE FINISH IF TYPE=3 THEN START ; ! RECORDS TAGDISP=PINITOWN(PTYPE,ACC,COPND,NAMTXT) FINISH IF 1<<TYPE&B'100110'#0 START ; ! INTEGER & REAL & STRING IF EXTRN#0 THEN START TAGDISP=PINITOWN(PTYPE,ACC,COPND,NAMTXT) FINISH ELSE TAGDISP=0 FINISH STORE TAG(K,LEVEL,0,J,SNDISP,ACC,TAGDISP,KFORM) IF EXTRN=0=NAM AND 1<<TYPE&B'100110'#0 START ;! CONST = LITERAL LCELL==ASLIST(TAGS(K)) LCELL_S2=COPND_D LCELL_S3=COPND_XTRA IF TYPE=5 THEN START LCELL_S2=WORKA_ARTOP WORKA_ARTOP=(WORKA_ARTOP+COPND_XTRA+4)&(-4) FINISH FINISH P=MARK REPEAT ->BEND NONSCALAR: ! OWN AND OWNRECORD ARRAYS !*********************************************************************** !* OWN ARRAYS CAN BE INITIALISED BUT ONLY ONE ARRAY CAN BE * !* DECLARED IN A STATEMENT.(THANK HEAVENS!) * !* OWN RECORD ARRAYS ARE INITIALISED AS BYTE ARRAYS * !*********************************************************************** P=P+1 FORMAT=2-A(P) IF FORMAT#0 THEN ARR=3 AND PACK(PTYPE) PP=P+2; P=P+4; NNAMES=1 K=FROM AR2(PP) NAMTXT=STRING(ADDR(WORKA_LETT(WORD(K)))) IF A(P)=1 THEN START ; ! ALAIS GIVEN IF LITL=0 THEN WARN(10,0) LENGTH(NAMTXT)=A(P+1) CHARNO(NAMTXT,KK)=A(P+KK+1) FOR KK=1,1,A(P+1) P=P+A(P+1)+1 FINISH P=P+1; ! P ON CONSTLIST SACC=ACC; TYPEP=PTYPE DVO=DOPE VECTOR(TYPE,STALLOC,0,K,QQ,LB) IF SNDISP=-1 THEN SNDISP=0; ! BUM DOPE VECTOR SNDISP=(SNDISP&X'3FFFF')>>2; ! AS WORD DISPLACEMENT DIMEN=J; ! SAVE NO OF DIMENESIONS ACC=SACC; PTYPE=TYPEP; UNPACK IF LB=0 AND FORMAT=0 THEN ARR=2 AND PACK(PTYPE) IF TYPE=3 THEN SLENGTH=QQ ELSE SLENGTH=QQ//STALLOC;! NO OF ELEMENTS SPOINT=STPTR IF FORMAT=0 THEN START IF A(P)=1 THEN P=P+1 AND INIT SPACE(QQ,SLENGTH) FINISH IF CONSTS FOUND=0 THEN START ; ! NO CONSTANTS GIVEN ! SO CLEAR AN AREA TO ZERO CONSTS FOUND=SLENGTH CLEAR(QQ) UNLESS SLENGTH<1 OR EXTRN=3 OR FORMAT#0 FINISH ELSE START FAULT(49,0,K) IF EXTRN=3 OR FORMAT#0 FINISH IF EXTRN=3 THEN SPOINT=0 ! ! OUTPUT AN ARRAYHEAD INTO THE GLA RELATIVE TO THE START OF THE SYMBOL- ! TABLES IN WHICH THE ARRAY RESIDES. ! TAGDISP=POWNARRAYHEAD(PTYPE,J,LB,QQ,SPOINT,QPUTP,DVO,NAMTXT) STORE TAG(K,LEVEL,0,J,SNDISP,ACC,TAGDISP,KFORM) ->BEND ROUTINE INIT SPACE(INTEGER SIZE, NELS) !*********************************************************************** !* P IS TO FIRST ENTRY FOR CONSTLIST * !* MAP SPACE ONTO WORKFILE END TO GIVE SANE ERROR MESSAGE IF * !* THERE WAS NOT ENOUGH SPACE * !*********************************************************************** CONSTINTEGER BUFSIZE=512 INTEGER RF, I, II, ELSIZE, AD, SPP, SLENGTH, WRIT BYTEINTEGERARRAY SP(0:BUFSIZE+256) AD=ADDR(FCOPND_B0) ELSIZE=SIZE//NELS IF ELSIZE=2 AND TARGET#PERQ AND TARGET#ACCENT THEN AD=ADDR(FCOPND_H1) IF TYPE=5 THEN AD=ADDR(SCONST) SPP=0; WRIT=0 UNTIL A(P-1)=2 CYCLE XTRACT CONST(TYPE,PREC) IF A(P)=1 START ; ! REPITITION FACTOR P=P+2 IF A(P-1)=2 THEN RF=NELS-CONSTS FOUND ELSE START P=P+2 IF INTEXP(RF,MINAPT)#0 THEN FAULT(41,0,0) AND RF=1 FINISH P=P+1 FINISH ELSE RF=1 AND P=P+2 FAULT(42,RF,0) IF RF<=0 CYCLE I=RF,-1,1 IF TYPE=1=ACC OR TYPE=3 START CYCLE II=0,1,ELSIZE-1 IF CONSTS FOUND<=NELS THEN SP(SPP)<- C COPND_D AND SPP=SPP+1 REPEAT FINISH ELSE START IF CONSTS FOUND<=NELS THEN C MOVE BYTES(ELSIZE,AD,0,ADDR(SP(0)),SPP) AND SPP=SPP+ELSIZE FINISH CONSTS FOUND=CONSTS FOUND+1 IF SPP>=BUFSIZE START ; ! EMPTY BUFFER IF HOST#TARGET AND (TYPE=5 OR (TYPE=1 AND PREC=3))C THEN CHANGE SEX(ADDR(SP(0)),0,SPP) PDATA(QPUTP,1,SPP,ADDR(SP(0))) WRIT=WRIT+SPP SPP=0 FINISH REPEAT REPEAT ; ! UNTIL P<ROCL>=%NULL IF CONSTS FOUND#NELS THEN FAULT(45,CONSTS FOUND,NELS) SLENGTH=(SIZE+3)&(-4) IF HOST#TARGET AND (TYPE=5 OR (TYPE=1 AND PREC=3)) C THEN CHANGE SEX(ADDR(SP(0)),0,SLENGTH-WRIT) PDATA(QPUTP,1,SLENGTH-WRIT,ADDR(SP(0))) END ROUTINE CLEAR(INTEGER SLENGTH) SLENGTH=(SLENGTH+3)&(-4) PRDATA(QPUTP,4,4,SLENGTH>>2,ADDR(ZERO)) END ROUTINE XTRACT CONST(INTEGER CONTYPE, CONPREC) !*********************************************************************** !* P POINTS TO P<+'> OF <+'><OPERNAD><RESTOFEXPR> AND IS UPDATED* !* THE CONST IS CONVERTED TO REQUIRED FORM AND IF INTEGER * !* IS LEFT IN ICONST, IF REAL IN RCONST AND IF STRING IN SCONST * !*********************************************************************** INTEGER SLENGTH, STYPE, SACC, MODE, CH, WR, I STYPE=PTYPE; SACC=ACC; ! MAY BE CHANGED IF CONST IS EXPR IF CONTYPE=5 THEN START P=P-3; CSTREXP(0) WR=WORKA_ARTOP IF EXPOPND_FLAG=LCONST AND EXPOPND_PTYPE=X'35' START SLENGTH=EXPOPND_XTRA LENGTH(SCONST)=SLENGTH A(WR)=SLENGTH FOR I=1,1,SLENGTH CYCLE CH=A(EXPOPND_D+I) CHARNO(SCONST,I)=CH A(WR+I)=CH REPEAT COPND_PTYPE=X'35'; COPND_FLAG=LCONST COPND_D=EXPOPND_D COPND_XTRA=SLENGTH FINISH ELSE START FAULT(44,CONSTS FOUND,K); SCONST="" SLENGTH=0 FINISH FINISH ELSE START MODE=CONPREC<<4!CONTYPE IF CONPREC<5 THEN MODE=CONTYPE!X'50' CONSTP=CONSTEXP(MODE) IF CONSTP=0 THEN FAULT(41,0,0) ! CANT EVALUATE EXPT COPND=EXPOPND; ! GET RESULT OPND COPND_PTYPE=MODE FINISH PTYPE=STYPE; UNPACK; ACC=SACC ! FAULT ANY OBVIOUS ERRORS IE:- ! CONSTANT FOR EXTRINSIC OR INCOMPATIBLE TYPE OR STRING TOO LONG IF EXTRN=3 THEN FAULT(49,0,K) AND RETURN IF (CONTYPE=5 AND SLENGTH>=ACC) C OR (CONTYPE=1 AND ((CONPREC=3 AND COPND_D>255) C OR (CONPREC=4 AND COPND_D>X'FFFF'))) C THEN FAULT(44,CONSTS FOUND,K) ! ! IF CROSS COMPILING THEN A CONSTANT FORMAT CHANGE IS NEED FROM ! IBM&ICL FORM TO PERQ FORM. IF ON PERQ FORMAT IS CORRECT ! FCOPND=COPND IF HOST#TARGET THEN START REFORMATC(FCOPND) FINISH END BEND: END ; ->CSSEXIT SW(10): BEGIN ; ! %RECORDFORMAT (RDECLN) INTEGER NAME,OPHEAD,OPBOT,NLIST,MRL,CELLREF,FHEAD,SPEC RECORD (LISTF)NAME LCELL,FRCELL SNDISP=0 SPEC=A(P+1); ! 1 FOR SPEC 2 FOR FORMAT NAME=FROM AR2(P+2); P=P+4 COPY TAG(NAME) IF SPEC=1 OR NOT (PTYPE=4 AND J=15 AND OLDI=LEVEL) START KFORM=0 PUSH(KFORM,0,0,0) PTYPE=4 STORE TAG(NAME,LEVEL,RBASE,15,0,X'7FFF',KFORM,KFORM);! IN CASE OF REFS IN FORMAT FINISH IF SPEC=2 START OPHEAD=0; OPBOT=0 NLIST=0; MRL=0 INAFORMAT=1 CRFORMAT(OPHEAD,OPBOT,NLIST,MRL,X'80000000') INAFORMAT=0 CLEAR LIST(NLIST) ! ! IN CASE OF FORWARD REFS COPY TOP CELL OF FORMAT CHAIN INTO DUMMY ! SET UP BEFORE CALL OF CRFORMAT. ALSO RESET J&ACC TO CORRECT VALUE ! LCELL==ASLIST(TAGS(NAME)) KFORM=LCELL_KFORM POP(KFORM,I,I,FHEAD); ! THROW DUMMY CELL ! GET HEAD OF FORWARD REFS WHILE FHEAD>0 CYCLE ; ! THROUGH FORWARD REFS POP(FHEAD,CELLREF,I,I) FRCELL==ASLIST(CELLREF) FRCELL_UIOJ=FRCELL_UIOJ&X'FFFFFFF0';! SET J BACK TO 0 FRCELL_ACC=ACC; ! ACC TO CORRECT VALUE FRCELL_KFORM=OPHEAD; ! CORRECT KFORM REPEAT LCELL_UIOJ=LCELL_UIOJ&X'FFFFFFF0'; ! J BACK TO ZERO LCELL_ACC=ACC LCELL_SLINK=OPHEAD; ! KFORM&SLINK(HISTORIC) TO SIDECHAIN LCELL_KFORM=OPHEAD FINISH END ;->CSSEXIT ! SW(19): ! '*' (UCI) (S) FAULT(57,0,0) UNLESS LEVEL>=2 BEGIN !*********************************************************************** !* COMPILE USERCODE INSTRUCTION. MOST WORK IS DONE BY HAIRY * !* BUILT-IN PHRASE IN COMPARE. SINCE ALMOST ANYTHING IS LEGAL * !* IN USERCODE THIS BLOCK HAS ONLT TO ASSEMBLE AND PLANT THE * !* THE INSTRUCTION. * !*********************************************************************** SWITCH UCITYPE(1:5),QINST(1:7) RECORD (RD) OPND RECORD (TAGF)NAME TCELL INTEGER ALT,AALT,FNAME,OPTINC,OPC,KK,VAL1,VAL2,UCOP,TR,XTRA,H,Q IF TARGET=EMAS OR TARGET=IBM OR TARGET=IBMXA START ROUTINE CUCS !*********************************************************************** !* SETS UP OPND FOR ASSEMBLER NAME(IE LOCAL OR CONST) * !*********************************************************************** INTEGER ALT,FN0,D FN0=FROM AR2(P); P=P+2 COPY TAG(FN0) IF (LITL=1 AND NAM=ARR=0) START TCELL==ASLIST(TAGS(FN0)) OPND_PTYPE=PTYPE&255 OPND_D=TCELL_S2 OPND_XTRA=TCELL_S3 FINISH ELSE START IF TYPE>=6 OR TYPE=4 OR C (ROUT=1 AND NAM=0) THEN FAULT(95,0,FN0) AND RETURN IF ROUT=1 THEN K=SNDISP; ! FORMAL RT DESCPTR OFFSET ALT=A(P); D=FROM AR2(P+1) IF ALT=1 THEN K=K+D IF ALT=2 THEN K=K-D P=P+1; P=P+2 IF ALT<=2 OPND_FLAG=LOCALIR OPND_D=I<<16!K FINISH END FINISH IF TARGET=EMAS START ROUTINE CIND !*********************************************************************** !* COMPILE A SYMBOLIC OPERAND BY SETTING ACCESS,AREA &DISP * !*********************************************************************** INTEGER ALT,FN0,JJ,D,CTYPE,CPREC,AREA SWITCH SW(1:4) ALT=A(P) P=P+1; ->SW(ALT) SW(1): ! (PLUS')(ICONST) D=A(P); CTYPE=A(P+1) OPND_PTYPE=CTYPE CPREC=CTYPE>>4; CTYPE=CTYPE&7 IF CPREC=4 THEN OPND_D=FROM AR2(P+2) ELSE C IF CPREC=7 THEN OPND_D=P+2 ELSE C MOVE BYTES(BYTES(CPREC),ADDR(A(0)),P+2,ADDR(OPND_D),0) P=P+2+BYTES(CPREC) IF D=2 THEN START JJ=11; ! UNARY NEGATE CTOP(JJ,D,0,OPND,OPND); ! NEGATE CONSTANT FINISH FAULT(96,FN0,0) UNLESS 1<=CTYPE<=2 AND 4<=CPREC<=7 RETURN SW(2): ! (NAME)(OPTINC) CUCS RETURN SW(3): ! '('(REG)(OPTINC)')' AREA=A(P)+1; ALT=A(P+1); P=P+2 DISP=0 D=FROM AR2(P) IF ALT=1 THEN DISP=D IF ALT=2 THEN FAULT(96,-D,0) DISP=4*DISP P=P+2 UNLESS ALT=3 OPND_FLAG=10 OPND_XB=AREA<<4 OPND_D=DISP RETURN SW(4): ! '%TOS' OPND_FLAG=10; OPND_XB=X'60' END ROUTINE ULABREF !*********************************************************************** !* COMPILES USERCODE REF TO 2900 LABELS * !* LABELS MAY ONLY BE USED WITH JCC(2),JAT(4),JAF(6),J(1A),JLK(1C) * !* AND ALSO DEBJ(24) * !* FAULTED IN OTHER SITUATIONS.(IE MORE RESTRICTIVE THAN 2900IMP) * !*********************************************************************** INTEGER MASK,LAB IF OPC<=6 THEN MASK=FROMAR2(P)+8*(OPC-2) AND P=P+3 C ELSE IF OPC=X'1A' THEN MASK=15 ELSE C IF OPC=X'1C' THEN MASK=0 ELSE C IF OPC=X'24' THEN MASK=48 ELSE FAULT(97,0,0) LAB=FROMAR2(P) ENTER JUMP(MASK,LAB,0) END FINISH IF TARGET=IBM OR TARGET=IBMXA START ROUTINE DB !*********************************************************************** !* COMPILES AN IBM DB FORMAT SECOND OPERAND REFERENCE * !*********************************************************************** INTEGER ALT ALT=A(P); P=P+1; ! ALT OF DB IF ALT=1 START ; ! NAME LOCAL OR CONST CUCS FINISH ELSE START ; ! EXPLICIT NUMERICAL FORM OPND_D=FROMAR2(P); P=P+2 OPND_FLAG=10 ALT=A(P); P=P+1 IF ALT=1 THEN OPND_XB=A(P) AND P=P+1 FINISH END ROUTINE DXB !*********************************************************************** !* COMPILES AN IBM DXB (AND DLB) FORMAT SECOND OPERAND REFERENCE * !* THE L IN DLB CAN BE UP TO 256 SO NEEDS 2 AR ENTRIES * !*********************************************************************** INTEGER ALT ALT=A(P); P=P+1; ! ALT OF DXB IF ALT=1 START ; ! NAME LOCAL OR CONST CUCS IF A(P)=1 AND OPND_FLAG=7 THEN XTRA=FROMAR2(P+1) AND P=P+2 P=P+1 FINISH ELSE START ; ! EXPLICIT NUMERICAL FORM OPND_D=FROMAR2(P); P=P+2 OPND_FLAG=10 ALT=A(P); P=P+1 IF ALT=1 THEN START XTRA=FROMAR2(P); OPND_XB=A(P+2) P=P+3 FINISH IF ALT=2 THEN OPND_XB=A(P) AND P=P+1 FINISH END FINISH OPC=0; XTRA=0 OPND=0 OPND_PTYPE=X'51' OPND_FLAG=1 ALT=A(P+1); P=P+2 ->UCITYPE(ALT) UCITYPE(1): ! **@'(NAME)(OPTINC) ! INVALID ON IBM ARCHITECTURES ! AS THERE IS NO ACCUMULATOR AALT=A(P); ! ALT OF @' FNAME=A(P+1)<<8!A(P+2) P=P+3; OPTINC=0 IF A(P)#3 START ; ! THERE IS AN OPTINC OPTINC=FROMAR2(P+1) IF A(P)=2 THEN OPTINC=-OPTINC FINISH COPY TAG(FNAME) IF TARGET=IBM OR TARGET=IBMXA OR TYPE>=6 OR ROUT#0 THEN FAULT(97,FNAME,0) UCOP=UCNAM OPND_PTYPE=X'61' OPND_D=AALT<<16!FNAME OPND_XTRA=OPTINC ->OTRIP UCITYPE(2): ! PUT (HEX HALFWORD) TYPE=A(P) PREC=TYPE>>4; TYPE=TYPE&7 FAULT(97,0,0) UNLESS TYPE=1 AND PREC<6 IF PREC=5 THEN P=P+2 OPND_D=FROM AR2(P+1); UCOP=UCB2 ->OTRIP UCITYPE(4): ! CNOP UCOP=UCNOP; OPND_D=FROM AR2(P) ->OTRIP UCITYPE(3): ! ASSEMBLER AALT=A(P); P=P+1 OPC=FROMAR2(P); P=P+2 IF TARGET=PNX OR TARGET=PERQ OR TARGET=ACCENT START P=P+3; ! TO START OF EXPR IF AALT>1 THEN START KK=INTEXP(VAL1,MINAPT) FAULT(96,0,1) UNLESS KK=0 FINISH IF AALT>=5 START P=P+3 KK=INTEXP(VAL2,MINAPT) FAULT(96,0,2) UNLESS KK=0 FINISH FINISH ->QINST(AALT) UCITYPE(5): ! OTHER M-CS ASSEMBLER FAULT(97,0,0) ->BEND QINST(1): ! ONE BYTE INSTRUCTION ! 2900 IS PRIMARY FORMAT INSTRUCTIONS ! IBM ONE REGISTER RR INSTRUCTIONS UCOP=UCB1 IF TARGET=PNX OR TARGET=PERQ OR TARGET=ACCENT THEN OPND_D=OPC ELSE C IF TARGET=EMAS START ALT=A(P); P=P+1 IF ALT=1 THEN ULABREF AND ->BEND IF ALT=2 THEN CIND ELSE C IF ALT=3 THEN CIND AND XTRA=4-A(P) ELSE C IF ALT=4 THEN CIND AND XTRA=1 ELSE C IF ALT=5 THEN OPND_FLAG=10 AND OPND_XB=X'74'-A(P) ELSE C IF ALT=6 THEN OPND_FLAG=10 AND OPND_XB=X'70' FINISH ELSE IF TARGET=IBM OR TARGET=IBMXA START VAL1=A(P); P=P+1 IF OPC#10 AND VAL1>15 THEN FAULT(97,0,0) OPND_D=OPC<<16!VAL1 FINISH ->OTRIP QINST(2): ! UNSIGNED BYTE OPERAND ! EMAS 2NDARY (STORE TO STORE) FORMAT ! IBM RR AND RRE INSTRUCTIONS UCOP=UCB2 IF TARGET=PNX OR TARGET=PERQ OR TARGET=ACCENT START FAULT(96,0,1) UNLESS 0<=VAL1<=255 OPND_D=OPC<<8!VAL1 FINISH ELSE IF TARGET=EMAS START VAL1=0; VAL2=0; Q=0; JJ=0 H=2-A(P) IF H=0 THEN JJ=FROM AR2(P+1)-1 AND P=P+2 FAULT(96,JJ+1,0) UNLESS 0<=JJ<=127 ALT=A(P+1); P=P+2 IF ALT=1 THEN START Q=1 VAL1=FROM AR2(P) VAL2=FROM AR2(P+2) P=P+4 IF VAL1>255 THEN FAULT(96,VAL1,0) IF VAL2>255 THEN FAULT(96,VAL2,0) FINISH OPND_D=H<<31!Q<<30!JJ<<16!VAL1<<8!VAL2 FINISH ELSE IF TARGET=IBM OR TARGET=IBMXA START VAL1=A(P); VAL2=A(P+1); P=P+2 FAULT(97,0,0) IF VAL1>15 OR VAL2>15 OPND_D=OPC<<16!VAL2<<8!VAL1 FINISH ->OTRIP QINST(3): ! PERQ SIGNED BYTE OPERAND ! EMAS TERTIARY (JUMP) FORMAT ! IBM REGISTER STORE RX FORMAT IF TARGET=PNX OR TARGET=PERQ OR TARGET=ACCENT START UCOP=UCB2 FAULT(96,0,1) UNLESS -128<=VAL1<=127 OPND_D=OPC<<8!(VAL1&255) FINISH ELSE IF TARGET=EMAS START UCOP=UCB3; ! DIFFERENT TRIPLE NEEDED FOR EMAS XTRA=FROMAR2(P) ALT=A(P+2) IF ALT=1 THEN ULABREF AND ->BEND P=P+3 IF ALT=2 THEN START CIND FAULT(97,0,0) IF OPND_XB=X'60' FINISH ELSE IF ALT=3 START OPND_FLAG=10 OPND_XB=8-A(P) FINISH ELSE OPND_XB=1 AND OPND_D=FROMAR2(P) FINISH ELSE IF TARGET=IBM OR TARGET=IBMXA START UCOP=UCB3 VAL1=A(P); P=P+1; ! FIRST REGISTER OPERAND DXB FAULT(97,0,0) IF XTRA>15 OR VAL1>15 OR OPND_XB>15 XTRA=XTRA<<8!VAL1 ! OPCODE R1 & INDEX IN _X1 ! DB VARIOUSLY IN OPND FINISH ->OTRIP QINST(4): ! SIGNED WORD OPERAND ! IBM RS (REGISTER TO STORE) FORMAT IF TARGET=PNX OR TARGET=PERQ OR TARGET=ACCENT START FAULT(96,0,1) IF C (TARGET=PERQ OR TARGET=ACCENT) AND IMOD(VAL1)>X'7FFF' UCOP=UCW; OPND_PTYPE=X'61' OPND_D=OPC OPND_XTRA=VAL1 FINISH ELSE IF TARGET=IBM OR TARGET=IBMXA START UCOP=UCB3; ! GENERATORS TREATS AS DXB VAL1=A(P); XTRA=A(P+1) P=P+2; DB FAULT(97,0,0) IF XTRA>15 OR VAL1>15 OR OPND_XB>15 XTRA=XTRA<<8!VAL1 FINISH ->OTRIP QINST(5): ! 2 UNSIGNED BYTE OPERANDS ! IBM STORE IMMEDIATE OR STORE FORMATS IF TARGET=PNX OR TARGET=PERQ OR TARGET=ACCENT START FAULT(96,0,1) UNLESS 0<=VAL1<=255 FAULT(96,0,2) UNLESS 0<=VAL2<=255 UCOP=UCB3; OPND_D=OPC<<16!VAL1<<8!VAL2 FINISH ELSE IF TARGET=IBM OR TARGET=IBMXA START UCOP=UCW; DB ALT=A(P); P=P+1 IF ALT=1 START ; ! IMMEDIATE OPERAND GIVEN P=P+3 KK=INTEXP(XTRA,X'51') FAULT(97,0,0) UNLESS KK=0 AND 0<=XTRA<=255 AND OPC<255 FINISH ; ! NO OPERAND 0 ASSUMED ->OTRIP FINISH ->OTRIP QINST(6): ! BYTE & WORD OPERANDS ! IBM SS AND SSE FORMATS IF TARGET=PNX OR TARGET=PERQ OR TARGET=ACCENT START FAULT(96,0,1) UNLESS 0<=VAL1<=255 FAULT(96,0,2) UNLESS IMOD(VAL2)<=X'7FFFF' I=UCBW; OPND_D=OPC<<24!VAL1<<16!(VAL2&X'FFFF') FINISH ELSE IF TARGET=IBM OR TARGET=IBMXA START DXB TR=URECTRIP(UCNAM,0,DONT OPT!ASSLEVEL,OPND) ! PASS ON OPND FIRST DUE TO ! LIMITATIONS OF PORTABLE ASSEMBLER OPND=0 DB; UCOP=UCBW IF (OPC>255 AND XTRA#0) OR XTRA>256 THEN FAULT(97,0,0) FINISH ->OTRIP OTRIP: TR=URECTRIP(UCOP,0,DONT OPT!ASS LEVEL,OPND) TRIPLES(TR)_X1=OPC<<16!XTRA BEND: END ->CSSEXIT SW(20): ! '%TRUSTEDPROGRAM' PARM_COMPILER=1 IF PARM_ARR=0 AND PARM_CHK=0; ->CSSEXIT SW(21): ! '%MAINEP'(NAME) KK=FROM AR2(P+1) FAULT(97,0,0) UNLESS PARM_CPRMODE=0 MAINEP<-STRING(ADDR(WORKA_LETT(WORD(KK)))) ->CSSEXIT INTEGERFN CFORMATREF !*********************************************************************** !* P IS TO ALT OF FORMAT REF * !* P<FORMTAREF>::=(NAME),(RFDEC)(RESTOFRFDEC)(ALTRFDEC) * !* RETURNS CELL NO OF TOP CELL OF THE FORMATLIST * !*********************************************************************** INTEGER FNAM,OPHEAD,OPBOT,NHEAD,MRL RECORD (LISTF)NAME LCELL IF A(P)=1 START ; ! A RECORD OF RECORDFORMAT NAME FNAM=FROM AR2(P+1) P=P+3 COPY TAG(FNAM) IF 3<=TYPE<=4 THEN RESULT =KFORM IF INAFORMAT#0 AND OLDI#LEVEL START PTYPE=4 PUSH(KFORM,0,0,0) STORE TAG(FNAM,LEVEL,RBASE,15,0,X'7FFF',KFORM,KFORM) RESULT =KFORM FINISH FAULT(62,0,FNAM); ! NOT A RECORD OF FORMAT NAME ACC=8; ! GUESS A RECORD SIZE RESULT =DUMMY FORMAT FINISH ! FORMAT ACTUALLY SPECIFIED P=P+1 OPHEAD=0; OPBOT=0 NHEAD=0; MRL=0 CRFORMAT(OPHEAD,OPBOT,NHEAD,MRL,X'80000000') CLEAR LIST(NHEAD) IF CURRINF_UNATT FORMATS#0 START LCELL==ASLIST(CURRINF_UNATT FORMATS) IF LCELL_S2=0 THEN LCELL_S2=OPHEAD AND RESULT =OPHEAD IF LCELL_S3=0 THEN LCELL_S3=OPHEAD AND RESULT =OPHEAD FINISH PUSH(CURRINF_UNATT FORMATS,OPHEAD,0,0) RESULT =OPHEAD END ROUTINE CRFORMAT(INTEGERNAME OPHEAD, OPBOT, NLIST, MRL, INTEGER INIT) !*********************************************************************** !* CONVERTS A RECORDFORMAT STATEMENT TO A LIST HEADED BY OPHEAD * !* FORMAT OF AN ENTRY. * !* S1=SUBNAME<<20!PTYPE<<4!J * !* S2,S3=4 16 BIT DISPLACEMENTS D2,ACC,D1,KFORM * !* NORMALLY D1=RECORD RELATIVE DISPLACEMENT AND ACC=LMAX(STRINGS)* !* FOR ARRAYS D2=FIRST ELEMENT DISPLACEMENT AND D1=DISPLACEMENT * !* OF RECORD RELATIVE ARRAYHEAD IN THE GLA * !* KFORM IS ONLY USED FOR RECORDS AND POINTS TO THE FORMAT * !* ON EXIT ACC HAS THE RECORD SIZE ROUNDED UP TO THE BOUNDARY * !* REQUIRED BY ITS LARGEST COMPONENT * !*********************************************************************** INTEGER D1, D2, FORM, RL, STALLOC, INC, Q, R, RFD, LB, TYPEP, SACC, DVO ROUTINESPEC SN(INTEGER Q) ROUTINESPEC ROUND FORM=0; ACC=0 INC=INIT&X'FFFF'; ! INC COUNTS DOWN RECORD CYCLE ROUT=0; LITL=0; NAM=0; RFD=A(P) P=P+1 IF RFD=1 THEN START CLT FORM=KFORM STALLOC=ACC P=P+1 IF A(P-1)=1 START ! (TYPE) (QNAME')(NAMELIST) FORM=KFORM CQN(P); P=P+1 IF NAM=1 THEN START STALLOC=PTRSIZE(PREC<<4!TYPE) IF ARR#0 THEN STALLOC=AHEADSIZE FINISH PACK(PTYPE); D2=0 RL=ROUNDING LENGTH(PTYPE,0) ROUND; J=0 UNTIL A(P-1)=2 CYCLE D1=INC; SN(P) P=P+3; INC=INC+STALLOC REPEAT FINISH ELSE START ! (TYPE)%ARRAY(NAMELIST)(BPAIR) Q=P+1; ARR=1; PACK(PTYPE) CYCLE P=Q P=P+3 UNTIL A(P-1)=2 TYPEP=PTYPE; SACC=ACC DVO=DOPE VECTOR(TYPE,ACC,0,FROMAR2(Q)>>1,R,LB) ! DOPE VECTOR INTO SHAREABLE S.T. ACC=SACC; PTYPE=TYPEP; UNPACK RL=ARRAYINREC ROUNDING CYCLE ROUND D1=POWNARRAYHEAD(PTYPE,J,LB,R,INC,0,DVO,"") D2=INC SN(Q); INC=INC+R Q=Q+3 REPEAT UNTIL A(Q-1)=2;! TILL NAMELIST NULL P=P+1; Q=P+1 REPEAT UNTIL A(P-1)=2; ! UNTIL <RESTOFARRAYLIST> NULL FINISH FINISH ELSE START ! (FORMAT) CRFORMAT(OPHEAD,OPBOT,NLIST,MRL,INC) INC=ACC FINISH P=P+1 REPEAT UNTIL A(P-1)=2; ! UNTIL <RESTOFRFDEC> NULL ! FINISH OFF IF A(P)=1 START ; ! WHILE %OR CLAUSES P=P+1 CRFORMAT(OPHEAD,OPBOT,NLIST,MRL,INIT&X'FFFF') IF ACC>INC THEN INC=ACC FINISH ELSE P=P+1 IF INIT<0 THEN RL=MRL AND ROUND ACC=INC; ! SIZE ROUNDED APPROPRIATELY FAULT(63,X'7FFF',0) UNLESS INC<=X'7FFF' RETURN ROUTINE SN(INTEGER Q) !*********************************************************************** !* CHECK THE SUBNAME HAS NOT BEEN USED BEFORE IN THIS FORMAT * !* AND ENTER IT WITH ITS DESCRIPTORS INTO THE LIST. * !* CARE IS NEEDED TO MATCH TAG LAYOUT ON BYTE SWOPPED HOSTS * !*********************************************************************** RECORD (TAGF) CELL FNAME=FROM AR2(Q) FAULT(61,0,FNAME) UNLESS FIND(FNAME,NLIST)=-1 CELL_PTYPE<-PTYPE; CELL_UIOJ<-FNAME<<4!J CELL_ACC=ACC CELL_SNDISP=D2 CELL_SLINK=D1 CELL_KFORM=FORM BINSERT(OPHEAD,OPBOT,CELL_S1,CELL_S2,CELL_S3) PUSH(NLIST,0,FNAME,0) IF PTYPE=X'433' AND ACC=X'7FFF' THEN C PUSH(ASLIST(FORM)_S3,OPBOT,0,0);! NOTE FORWARD REFERENCE END ROUTINE ROUND MRL=RL IF RL>MRL INC=INC+1 WHILE INC&RL#0 END END ; ! OF ROUTINE CRFORMAT INTEGERFN DISPLACEMENT(INTEGER LINK) !*********************************************************************** !* SEARCH A FORMAT LIST FOR A SUBNAME * !* A(P) HAS ENAME--LINK IS HEAD OF RFORMAT LIST. RESULT IS DISP * !* FROM START OF RECORD * !*********************************************************************** RECORD (LISTF)NAME FCELL,PCELL,LCELL INTEGER RR,II,ENAME,CELL ENAME=A(P)<<8+A(P+1); CELL=0 IF LINK#0 THEN START ; ! CHK RECORDSPEC NOT OMITTED FCELL==ASLIST(LINK); ! ONTO FIRST CELL CELL=LINK; II=-1; ACC=-1 WHILE LINK>0 CYCLE LCELL==ASLIST(LINK) IF LCELL_UIOJ<<16>>20=ENAME START ;! RIGHT SUBNAME LOCATED TCELL=LINK SNDISP=LCELL_SNDISP K=LCELL_SLINK J=LCELL_UIOJ&15; PTYPE=LCELL_PTYPE ACC=LCELL_ACC SNDISP=LCELL_SNDISP KFORM=LCELL_KFORM IF LINK#CELL START ; ! NOT TOP CELL OF FORMAT PCELL_LINK=LCELL_LINK LCELL_LINK=FCELL_LINK FCELL_LINK=LINK FINISH ; ! ARRANGING LIST WITH THIS SUBNAME ! NEXT TO THE TOP RESULT =K FINISH PCELL==LCELL LINK=LCELL_LINK REPEAT FINISH FAULT(65,0,ENAME) IF CELL>0 THEN C PUSH(ASLIST(CELL)_LINK,(ENAME<<4)<<FLAGSHIFT!X'57'<<PTSHIFT,0,0) PTYPE=X'57'; TCELL=0 RESULT =-1 END INTEGERFN COPY RECORD TAG(INTEGERNAME SUBS) !*********************************************************************** !* PRODUCE PTYPE ETC FOR A COMPOUND NAME BY CHAINING DOWN ONE * !* ONE OR MORE RECORD FORMAT LISTS. ON EXIT RESULT =0 IF NO * !* SUBNAME FOUND OR SUBNAME IS OF TYPE RECORD WITH NO FURTHER * !* SUBNAME ATTACHED. RESULT#0 IF BONE-FIDE SUBNAME LOCATED * !* ON ENTRY KFORM HAS POINTER TO THE (FIRST ) FORMAT LIST AND * !* P POINTS TO THE A.R. ENTRY FOR (FIRST) ENAME * !*********************************************************************** INTEGER Q,FNAME SUBS=0 UNTIL TYPE#3 CYCLE FNAME=KFORM P=P+2; SKIP APP RESULT =0 IF A(P)=2 OR FNAME<=0;! NO (FURTHER) ENAME SUBS=SUBS+1 P=P+1; Q=DISPLACEMENT (FNAME) UNPACK REPEAT RESULT =Q+1; ! GIVES 0 IF SUBNAME NOT KNOWN END ROUTINE CRNAME(INTEGER Z,MODE,BS,DP,INTEGERNAME NAMEP) !*********************************************************************** !* DEAL WITH RECORD ELEMENT NAMES.Z AS FOR CNAME.CLINK=TAGS(RN) * !* MODE=ACCESS FOR RECORD(NOT THE ELEMENT!) * !* ON EXIT BASE,AREA & DISP POINT TO REQUIRED ELEMENT * !* RECURSIVE CALL IS NEEDED TO DEAL WITH RECORDS IN RECORDS * !* DEPTH SHEWS RECURSIVE LEVELS- NEEDED TO AVOID MIS SETTING * !* REGISTER IN USE IF RECORDNAME IN RECORD HAS THE SAME NAME AS * !* A GENUINE RECORD NAME. * !*********************************************************************** INTEGER DEPTH,FNAME ROUTINESPEC CENAME(INTEGER MODE,FNAME,BS,DP,XD) DEPTH=0 FNAME=KFORM; ! POINTER TO FORMAT IF ARR=0 OR (Z=6 AND A(P+2)=2) START ;! SIMPLE RECORD IF A(P+2)=2 THEN P=P+3 ELSE NO APP CENAME(MODE,FNAME,BS,DP,0) FINISH ELSE START CANAME(Z,ARR,BS,DP) NAMEP=-1 CENAME(ACCESS,FNAME,BASE,DISP,0) FINISH ; RETURN ! ROUTINE CENAME(INTEGER MODE,FNAME,BS,DP,XD) !*********************************************************************** !* FINDS OUT ABOUT SUBNAME AND ACTS ACCORDINGLY.MOSTLY ACTION * !* CONSISTS OF UPPING XD BY OFFSET OF THE SUBNAME BUT IS VERY * !* HAIRY FOR RECORDS IN RECORDS ETC * !* MODE IS ACCESS FOR THE RECORD * !*********************************************************************** ROUTINESPEC FETCH RAD ROUTINESPEC LOCALISE(INTEGER SIZE) INTEGER Q,QQ,D,C,W,TR RECORD (RD) RADOPND,OPND1 RECORD (LISTF)NAME LCELL DEPTH=DEPTH+1 IF A(P)=2 THEN START ; ! ENAME MISSING ACCESS=MODE; XDISP=XD BASE=BS; DISP=DP; ! FOR POINTER IF Z<14 THEN START ; ! NOT A RECORD OPERATION UNLESS 3<=Z<=4 OR Z=6 START ; ! ADDR(RECORD) FAULT(64,0,NAMEP&X'FFFF'); BASE=RBASE DISP=0; ACCESS=0; PTYPE=X'51'; UNPACK FINISH FINISH RETURN FINISH P=P+1; ! FIND OUT ABOUT SUBNAME Q=DISPLACEMENT(FNAME); ! TCELL POINTS TO CELL HOLDING UNPACK; ! INFO ABOUT THE SUBNAME IF Q=-1=ACC OR PTYPE=X'57' START ; ! WRONG SUBNAME(HAS BEEN FAULTED) P=P+2; SKIP APP; P=P-3 ACCESS=0; BASE=RBASE; DISP=0 RETURN FINISH NAMEP=(A(P)<<8!A(P+1))<<16!NAMEP; ! NAMEP=-1 UNALTERED ! ->AE IF ARR=1; ! ARRAYS INCLUDING RECORDARRAYS IF A(P+2)=2 THEN P=P+3 ELSE NO APP IF TYPE<=2 OR TYPE=5 OR C (TYPE=3 AND A(P)=2 AND (3<=Z<=4 OR Z=6)) START ACCESS=MODE+4+4*NAM; BASE=BS; DISP=DP; XDISP=XD+Q RETURN FINISH ! ! NOW CODING BECOMES HAIRY:- STILL LEFT ARE ! A) RECORDS IN RECORDS Q POINTS TO SECONDARY RECORD ! B) RECORDNAMES IN RECORDS Q HAS OFF-SET OF A POINTER ! C) RECORDARRAYNAMES IN RECORDS Q HAS OFF-SET A HEADER IN RECORD ! D) RECORDARRAYS IN RECORDS NOT YET ALLOWED ! Q WOULD HAVE OFF-SET OF A RECORD RELATIVE HEADER IN THE GLA ! XD=XD+Q NAMEP=NAMEP!X'FFFF0000' IF NAM=1 THEN START LOCALISE(1); ! PICK UP RECNAME DESCR &STCK IF NECESSARY DP=DISP; BS=BASE FINISH CENAME(MODE,KFORM,BS,DP,XD) RETURN AE: ! ARRAYS AND ARRAYNAMES AS ELEMEN LCELL==ASLIST(TCELL) ACC=LCELL_ACC; SNDISP=LCELL_SNDISP KFORM=LCELL_KFORM; K=LCELL_SLINK C=ACC; D=SNDISP; Q=K; QQ=KFORM IF (Z=6 OR Z>=11) AND A(P+2)=2 START ;! 'GET ARRAYHEAD' CALL P=P+3 IF NAM=1 THEN START ACCESS=MODE+8; BASE=BS DISP=DP; XDISP=XD+Q PTYPE=AHEADPT NAMEOP(6,8,NAMEP); ! PTR TO HEAD RETURN FINISH ! ! PASSING AN ARRAY IN A RECORD BY NAME MUST CONSTRUCT PROPER ARRAYHEAD ! FROM THE RECORD RELATIVE ONE AT Q(GLA) ! FETCH RAD NAMEP=-1 OPND1_S1=AHEADPT<<PTSHIFT!LOCALIR<<FLAGSHIFT OPND1_D=Q OPND1_XTRA=0 NAMEOPND_D=CREATE AH(1,RADOPND,OPND1) NAMEOPND_PTYPE=AHEADPT; NAMEOPND_FLAG=REFTRIP NAMEOPND_XTRA=0 FINISH ELSE START ; ! ARRAY ELEMENTS IN RECORDS IF NAM=1 THEN START ; ! ARRAYNAMES-FULLHEAD IN RECORD XD=XD+Q LOCALISE(2); ! MOVE HEAD UNDER LNB IF NECESSARY D=DISP CANAME(Z,3,BASE,DISP); ! ARRAY MODE SETS DISP,AREA&BASE BASE=RBASE; DISP=D; ! ONLY NEEDED FOR STRINGARRAYNAMES FINISH ELSE START ; ! ARRAY RELATIVE HEAD IN GLA FETCH RAD; ! 32 BIT ADDR TO ETOS CANAME(Z,3,0,Q); ! RECORD REL ARRAY ACCESS ! CAN RETURN ACCESS=1 OR 3 ONLY TR=BRECTRIP(AAINC,X'51',0,RADOPND,EXPOPND) EXPOPND_FLAG=REFTRIP EXPOPND_D=TR TRIPLES(TR)_X1=PTYPE&255; ! FRIG FOR PERQ&ACCENT 3 WORD BYTE PTRS! FINISH NAMEP=-1 XDISP=XD IF TYPE=3 THEN CENAME(ACCESS,QQ,BASE,DISP,XD) FINISH ACC=C; ! NEEDED FOR STRING ARRAYS RETURN ROUTINE FETCH RAD !*********************************************************************** !* SET ACC TO 32 BIT ADDRESS OF RECORD. * !*********************************************************************** INTEGER PRECP ACCESS=MODE+4 BASE=BS DISP=DP; XDISP=XD PRECP=PREC; PREC=5 NAMEOP(4,4,NAMEP) PREC=PRECP; ! ENSURE 32BIT PICKUP RADOPND=NAMEOPND END ROUTINE LOCALISE(INTEGER LMODE) !*********************************************************************** !* REMOVES A RECORD POINTER OR ARRAYHEAD FROM A RECORD AND STORES* !* IT IN A TEMPORARY UNDER LNB. * !* LMODE=1 NORMAL POINTERS, LMODE=2 ARRAY POINTERS * !*********************************************************************** RECORD (RD)TOPND INTEGER HOLE,PRECP,SIZE,JJ,PTYPEP IF MODE=0 AND TARGET#PNX START ;! MOVE NOT NECESSARY ! BUT ON PNX CANT ADD OFFSETS LIKE THIS BASE=BS; DISP=DP+XD XD=0; MODE=2 RETURN FINISH BASE=BS; DISP=DP XDISP=XD PRECP=PREC; PTYPEP=PTYPE IF LMODE=1 THEN SIZE=4 AND PREC=5 C ELSE SIZE=AHEADSIZE AND PREC=AHEADPT>>4 GET WSP(HOLE,SIZE>>1) TOPND_PTYPE=1!PREC<<4 TOPND_FLAG=LOCALIR TOPND_D=RBASE<<16!HOLE TOPND_XTRA=0 IF LMODE=1 START ACCESS=MODE+4 NAMEOP(4,SIZE,NAMEP) NAMEOPND_PTYPE=TOPND_PTYPE FINISH ELSE START ACCESS=MODE+8 NAMEOP(6,SIZE,NAMEP) NAMEOPND_PTYPE=TOPND_PTYPE JJ=URECTRIP(PRELOAD,NAMEOPND_PTYPE,0,NAMEOPND) NAMEOPND_FLAG=REFTRIP NAMEOPND_D=JJ FINISH JJ=BRECTRIP(LASS,1+16*PREC,0,TOPND,NAMEOPND) PREC=PRECP; PTYPE=PTYPEP MODE=2 BASE=RBASE; DISP=HOLE; XD=0 END ; ! OF ROUTINE LOCALISE END ; ! OF ROUTINE CENAME END ; ! OF ROUTINE CRNAME ROUTINE CSTREXP(INTEGER MODE) !*********************************************************************** !* PLANT IN-LINE CODE FOR CONCATENATION. A WORK AREA IN THE * !* CURRENT STACK FRAME IS USUALLY REQUIRED. * !* ON ENTRY:- * !* MODE=0 NORMAL. WK AREA NOT USED FOR ONE OPERAND EXPSSNS * !* MODE=1 STRING MUST GO TO WORK AREA * !* 2**5 BIT OF MODE SET IF FULL VIRTUAL ADDRESS REQUIRED * !* 2**4 BIT OF MODE IS SET IF WK-AREA NOT TO BE FREED ON EXIT * !* ON EXIT:- * !* VALUE#0 %IF RESULT IN A WORK AREA(CCOND MUST KNOW) * !*********************************************************************** INTEGER PP,WKAREA,DOTS,ERR,KEEPWA,FNAM,I,ENDFLAG RECORD (RD) OPND1,OPND2,OPND3 INTEGERFNSPEC STROP(RECORD (RD) NAME OPND) KEEPWA=MODE&16; MODE=MODE&15 PP=P; STRINGL=0; FNAM=0; WKAREA=0 P=P+3; ! LENGTH OF CONSTANT PART ERR=72; ->ERROR UNLESS A(P)=4 P=P+1 DOTS=0; ! NO OPERATORS YET ENDFLAG=0 STRINGL=0 ERR=STROP(OPND2); ! GET FIRST OPERAND ->ERROR UNLESS ERR=0 NEXT: IF A(P)=2 THEN ENDFLAG=1 ELSESTART IF A(P+1)#CONCOP THEN ERR=72 AND ->ERROR P=P+2 ! ! LEFT TO RIGHT EVALUATION IS DEFINED BUT IF FIRST OPERAND IS ACONST ! WE CAN EVALUATE THE SECOND. THIS ENABLES US TO FOLD "TOSTRING(NL)" ETC ! IF DOTS=0 AND OPND2_FLAG=LCONST THEN START ERR=STROP(OPND3) ->ERROR UNLESS ERR=0 FINISH ELSE OPND3_FLAG=255 FINISH IF ENDFLAG=0 AND OPND2_FLAG=LCONST=OPND3_FLAG START ! ! CAN FOLD OUT A CONCATENATION HERE ! I=CONCAT CTOP(I,ERR,0,OPND2,OPND3) IF I=0 THEN ->NEXT; ! FOLDED OUR FINISH IF DOTS=0 START IF MODE=0 AND ENDFLAG#0 START ; ! NO RUN-TIME OPERATIONS OPND1=OPND2; ->TIDY FINISH GET WSP(WKAREA,X'80000000'!268); ! GET NEXT OPERAND OPND1_PTYPE=X'35' OPND1_FLAG=LOCALIR OPND1_D=RBASE<<16!WKAREA OPND1_XTRA=268; ! THE WORK AREA SIZE NEEDED FOR ! BACKWARD STACKS I=BRECTRIP(PRECC,X'35',0,OPND1,OPND2) OPND1_FLAG=REFTRIP OPND1_D=I; ! CHANGE TO TRIPLES REFERENCE DOTS=1 FINISH IF ENDFLAG=0 THENSTART IF OPND3_FLAG=255 START ; ! 3 NEED EVALUATION ERR=STROP(OPND3) ->ERROR UNLESS ERR=0 FINISH OPND1_D=BRECTRIP(CONCAT,X'35',0,OPND1,OPND3) ->NEXT FINISH TIDY: ! FINISH OFF EXPOPND=OPND1; ! LEAVE REULT IN EXPOPND VALUE=WKAREA P=P+1; ! PAST REST OF EXPRN RETURN WSP(WKAREA,268) IF KEEPWA=0 AND WKAREA>0 STRINGL=0 RETURN ERROR:FAULT(ERR,0,FNAM) BASE=RBASE; DISP=0 VALUE=0; ACCESS=0 P=PP; SKIP EXP RETURN INTEGERFN STROP(RECORD (RD) NAME OPND) !*********************************************************************** !* DEALS WITH OPERAND FOR CONCATENATION. RETURN RESULT=0 FOR * !* VALID OPERAND OTHERWISE AN ERROR NUMBER. * !*********************************************************************** INTEGER CTYPE,MODE,I MODE=A(P); ! ALTERNATIVE OF OPERAND OPND=0 RESULT =75 IF MODE>2 IF MODE#1 THENSTART CTYPE=A(P+1); ! GET CONST TYPE & LOSE AMCK FLAGS IF CTYPE=X'35' THENSTART STRINGL=A(P+2) OPND_PTYPE=CTYPE OPND_FLAG=LCONST OPND_D=P+2 OPND_XTRA=STRINGL P=P+STRINGL+3 FINISHELSERESULT =73 FINISHELSESTART P=P+1; ! MUST CHECK FIRST REDUCE TAG IF 5#TYPE#7 THEN FNAM=FROMAR2(P) ANDRESULT =71 IF PTYPE=X'4035' AND A(P+2)=2=A(P+3) START OPND_FLAG=LCONST; ! CONST STRING OPND_PTYPE=X'35' OPND_D=MIDCELL OPND_XTRA=KFORM STRINGL=OPND_XTRA P=P+4 RESULT =0 FINISH IF PTYPE=X'35' AND A(P+2)=2=A(P+3) START OPND_FLAG=DNAME OPND_XTRA=0 OPND_PTYPE=PTYPE OPND_D=FROMAR2(P) P=P+4 FINISHELSESTART CNAME(2) OPND=NAMEOPND FINISH STRINGL=0 FINISH RESULT =0 END ; ! OF INTEGERFN STROP END ; ! OF ROUTINE CSTREXP ROUTINE CRES (INTEGER LAB) !********************************************************************** !* COMPILES A RESOLUTION E.G A->B.(C).D.(E).F AND JUMPS TO LAB * !* ON FAILURE. (LAB=0 FOR UNCONDITIONAL RESOLUTION TO PERM ON * !* FAILURE ). * !* THE METHOD IS TO CALL A SUBROUTINE PASSING 5 PARAMS:- * !* P1(32BITS) POINTS TO LHS(A) * !* P2(16BITS) ORIGINAL LENGTH OF A * !* P3(32BITS) FULL POINTER TO BYTES USED UP INITIALLY 0 * !* P4(48BITS) STRING TO CONTAIN FRAGMENT * !* (PASSED AS LMAX FOLLOWED BY 32BIT ADDRESS) * !* P5(32BITS) THE EXPRESSION PASSED AS 32 BIT ADDRESS * !* SUBROUTINE TRIES TO PERFORM THE RESOLUTION AND SETS THE * !* RESULT TO TRUE IF IT SUCCEEDS. * !* * !* ON ENTRY LHS IS IN THE ESTACK(32BITS). * !* P POINTS TO P(+') OF RHS DEFINED AS (+')(OPERAND)(RESTOFEXP) * !* * !$ THE ROUTINE IS COMPACT BUT DIFFICULT TO FOLLOW (OR ALTER) * !* THE TIME IN PERM IS LARGE SO IT IS NOT WORTHWHILE TO PERSUE * !* CODE EFFICIENCY TOO INDUSTRIOUSLY . * !********************************************************************** INTEGER P1,P2,SEXPRN,W,LAST,ERR,FNAM,JJ RECORD (RD) OPND1,OPND2 LAST=0; FNAM=0; ! =1 WHEN END OF EXPRNSN FOUND SEXPRN=0; ! RESOLUTION(BRKTD) EXPRESSNS P1=P ERR=43 IF NAMEOPND_PTYPE&X'C300'=X'4000' THEN FNAM=NAMEOPND_D AND ->ERROR ! CANT RESOLVE A CONST STRING ERR=74; ! NORMAL CRES FAULT GET WSP(W,4); ! TO HOLD P1,P2 AND VALUE OF P3 OPND1_PTYPE=X'61' OPND1_FLAG=LOCALIR OPND1_D=RBASE<<16!W JJ=BRECTRIP(PRES1,X'35',DONT OPT,OPND1,NAMEOPND) P=P+3 ->RES IF A(P)=4; ! LHS MUST BE A STRING ! BUT THIS CHECKED BEFORE CALL ERR=72 ERROR:FAULT(ERR,0,FNAM) P=P1; SKIP EXP; RETURN RES: P=P+1; ! TO P(OPERAND) IF A(P)=3 THEN START ; ! B OMITTED OPND2_PTYPE=X'51' OPND2_FLAG=SCONST OPND2_D=0; ! ZERO CONST FOR NO DEST FINISH ELSE START ->ERROR UNLESS A(P)=1; ! P(OPERAND)=NAME P=P+1; P2=P CNAME(3) OPND2=NAMEOPND IF TYPE#5 THEN ERR=71 AND FNAM=FROMAR2(P2) AND ->ERROR IF A(P+1)#CONCOP THEN ERR=72 AND ->ERROR P=P+2 FINISH JJ=BRECTRIP(PRES2,X'35',DONT OPT,OPND1,OPND2) ->ERROR UNLESS A(P)=3; ! P(OPERAND)='('(EXPR)')' SEXPRN=SEXPRN+1; P=P+1 CSTREXP(32); ! FULL 32 BIT ADDRESS OPND2_S1=X'51'<<PTSHIFT!SCONST<<FLAGSHIFT OPND2_D=LAB JJ=BRECTRIP(RESLN,X'35',DONT OPT,EXPOPND,OPND2) IF LAB#0 THEN ENTER JUMP(X'87',LAB,B'11') ! -> END IF A(P)=2 IF A(P+1)#CONCOP THEN ERR=72 AND ->ERROR P2=P+1; P=P2+1 IF A(P)=3 THEN P=P2 AND ->RES ->ERROR UNLESS A(P)=1 P=P+3 AND SKIP APP UNTIL A(P)=2 IF A(P+1)=1 THEN P=P2 AND ->RES P1=P+1 P=P2+2 CNAME(3) JJ=BRECTRIP(RESFN,X'35',DONT OPT,OPND1,NAMEOPND) P=P1 END: P=P+1 END ROUTINE SAVE STACK PTR !*********************************************************************** !* SAVE THE CURRENT STACK TOP AND POSSIBLY A DESCRIPTOR TO IT * !* NEEDED ON AUX STACK IMPLEMENTATIONS AND ALSO IN BEGIN-END BLOCKS * !* SO ARRAYS CAN BE UNDECLARED ON BLOCK EXIT. ONLY ACTS ON THE FIRST* !* CALL IN ANY BLOCK OR ROUITNE * !*********************************************************************** INTEGER JJJ IF CURRINF_AUXSBASE=0 START JJJ=UTEMPTRIP(SSPTR,MINAPT,0,N); ! SAVE THE STACK POINTER CURRINF_AUXSBASE=N IF TARGET=EMAS AND PARM_STACK=0 THEN N=N+16 C ELSE N=N+4 FINISH END ROUTINE CEND (INTEGER KKK) !*********************************************************************** !* DEAL WITH ALL OCCURENCES OF '%END' * !* KKK=PTYPE(>=X'1000') FOR ROUTINES,FNS AND MAPS * !* KKK=0 FOR ENDS OF '%BEGIN' BLOCKS * !* KKK=1 FOR '%ENDOFPROGRAM' * !* %ENDOFPROGRAM IS REALLY TWO ENDS. THE FIRST IS THE USERS * !* AND THE SECOND IS PERMS. KKK=2 FOR A RECURSIVE CALL OF CEND * !* ON END OF PROGRAM TO DEAL WITH THE %END CORRESPONDING TO * !* THE %BEGIN COMPILED IN THE INITIALISATION SEQUENCE * !*********************************************************************** INTEGER KP,JJ,BIT RECORD (TAGF)NAME TCELL,PCELL ROUTINESPEC DTABLE(INTEGER LEVEL) SET LINE UNLESS KKK=2 BIT=1<<LEVEL ! ! NOW PLANT AN ERROR EXIT FOR FNS AND MAPS - CONTROL SHOULD BE RETURNED ! VIA %RESULT= AN SHOULD NEVVER REACH THE %END INSTRUCTION ! IF KKK&X'3FFF'>X'1000' AND PARM_COMPILER=0 C AND LAST INST=0 THEN C JJ=UCONSTTRIP(RTBAD,X'51',0,0); ! RUN FAULT 11 IF KKK=0 THEN START ; ! BEGIN BLOCK EXIT IF PARM_TRACE=1 THEN START ; ! RESTORE DIAGS POINTERS JJ=UCONSTTRIP(RDPTR,X'51',0,LEVEL-1) FINISH JJ=CURRINF_AUXSBASE IF JJ#0 THEN START ; ! ARRAYS TO BE UNDECLARED JJ=UCONSTTRIP(RSPTR,X'51',0,JJ) FINISH FINISH NMAX=N IF N>NMAX; ! WORK SPACE POINTER ! ! CLEAR OUT THE LABEL LIST FAULTING LABELS WITH JUMPS OUTSTANDING ! AS NOT SET AND COMMENTING ON LABELS NOT USED ! WHILE CURRINF_LABEL#0 CYCLE POP(CURRINF_LABEL,I,J,KP) IF J&X'FFFF'#0 THEN START J=J&X'FFFF' IF 0<KP<=MAX ULAB THEN FAULT(11,ASLIST(J)_S3,KP) CLEAR LIST(J) FINISH ELSE START IF I&LABUSEDBIT=0 AND KP<MAX ULAB THEN WARN(3,KP) FINISH REPEAT ! NMAX=(NMAX+7)&(-8) CURRINF_SNMAX=NMAX ! ! FOR ROUITNE CHECK PARAMETER LIST FOR ARRAY PARAMETERS AND PASS ! BACK ANY INFORMATION ON DIMENSIONALAITY GLEANED DURING THE BODY ! JJ=CURRINF_M-1; ! RT NALE IF JJ>=0 START COPYTAG(JJ) WHILE K>0 CYCLE ; ! DOWN PARAM LIST TCELL==ASLIST(K) IF TCELL_PTYPE&X'F00'=X'500' AND TCELL_UIOJ&15=0 START ! TCELL IS ARRAY OF UNKNOWN DIMENSION PCELL==ASLIST(TAGS(TCELL_UIOJ>>4));! ONTO LOCAL TAGS TCELL_UIOJ=TCELL_UIOJ!PCELL_UIOJ&15;! COPY BACK DIMENSIO FINISH K=TCELL_LINK REPEAT FINISH ! ! NOW PLANT THE BLOCK EXIT SEQUENCE ! FORCE TRIPS IF KKK&X'3FFF'>=X'1000' THEN JJ=UCONSTTRIP(RTXIT,X'51',0,KKK) JJ=UCONSTTRIP(XSTOP,X'51',0,KKK) IF KKK=1;! %STOP AT %ENDOFPROGRAM CLEAR LIST(TWSPHEAD); ! CAN NOT CARRY FORWARD CYCLE JJ=0,1,4 CLEAR LIST(CURRINF_AVL WSP(JJ));! RELEASE TEMPORARY LOCATIONS REPEAT FORCE TRIPS; ! PERQ NEED THIS BEFORE DTABLE AS ! DTABLE OFFSET GOES IN RTDICT DTABLE(LEVEL); ! OUTPUT DIAGNOSTIC TABLES WHILE CURRINF_UNATT FORMATS#0 CYCLE POP(CURRINF_UNATT FORMATS,I,J,JJ) CLEAR LIST(I) CLEAR LIST(J) CLEAR LIST(JJ) REPEAT ! ! NOW CLAIM THE STACK FRAME BY FILING THE ASF IN THE BLOCK ENTRY CODING ! IF KKK=2 THEN RETURN ! ! RETURN TO PREVIOUS LEVEL PROVIDED THERE IS A VALID ONE ! ! UNLESS LEVEL>2 OR (LEVEL=2 AND PARM_CPRMODE=2) THEN START IF KKK=1 AND LEVEL=2 THEN KKK=2 ELSE FAULT(109,0,0) ! SHOULD BE CHKD IN PASS1 FINISH LEVEL=LEVEL-1 CURRINF==LEVELINF(LEVEL) IF KKK>=X'1000' THEN START RLEVEL=CURRINF_RBASE RBASE=RLEVEL FINISH ! ! RESTORE INFORMATION ABOUT THE (NEW) CURRENT LEVEL ! NMAX=CURRINF_SNMAX IF KKK>=X'1000' N=CURRINF_SN IF KKK=2 THEN CEND(KKK); ! ROUND AGAIN FOR 'ENDOFPROGRAM' ! ! COMPLETE THE JUMP AROUND ALL NON-EXTERNAL ROUTINES EXCEPT WHEN ! %TRUSTEDPROGRAM IS IN OPERATION. ! IF KKK>=X'1000' AND PARM_COMPILER=0 AND C (RLEVEL>0 OR PARM_CPRMODE#2) THEN START JJ=NEXTP+6 UNLESS A(NEXTP+5)=11 AND A(JJ+FROMAR2(JJ))=2 START JJ=ENTER LAB(CURRINF_JROUND,1) CURRINF_JROUND=0 FINISH FINISH RETURN ! ! LAYOUT OF DIAGNOSIC TABLES ! ****** ** ********* ****** ! ! THE BOUND FIELD OF PLT DESCRIPTOR STORED AT (LNB+3 & LNB+4) IF ! USED TO CONTAIN A DISPLACEMENT RELATIVE TO THE START OF SST OF THE ! DIAGNOSTIC TABLES FOR THE BLOCK OR ROUTINE BEING EXECUTED. ! A ZERO BOUND MEANS NO DIAGNOSTIC REQUESTED.(NB THIS MAY MEAN A DUMMY ! FIRST WORD IN THE SST). ! THE ABSOLUTE ADDRESS OF THE SST FOR THE CURRENT CODE SEGMENT WILL ! ALWAYS BE FOUND IN THE STANDARD 10 WORDS OF THE GLA/PLT ! ! FORM OF THE TABLES:- ! ! WORD 0 = LINE OF RT IN SOURCE PROG <<16 ! LINE NO POSN(FROM LNB) ! WORD 1 = (12 LANG DEPENDENT BITS)<<18 ! ENVIRONMENT ! ( TOP 2 BITS OF LANG DEPENDENT HAS LITL FROM PTYPE) ! ( BOTTOM 4 BITS HAVE TEXTUAL LEVEL) ! WORD 2 = DISPLAY POSN (FROM LNB)<<16 ! RT TYPE INFO ! WORD 3 = ZERO FOR BLKS OR STRING(<=11BYTES) BEING THE ! RT NAME. THIS WILL TAKE WORDS 4 AND 5 IF NEEDED ! WORD 6 = LANGUAGE DEPENDENT INFO . IMP ON CONDITIONS ETC ! ! THE REST IS MADE UP OF VARIABLE ENTRIES AND THE SECTION IS TERMINATED BY ! A WORD OF X'FFFFFFFF' ! ! EACH VARIABLE ENTRY CONSISTS OF THE VARIABLE WORD FOLLOWED BY ! THE VARIABLE NAME AS A STRING. THE WORD CONSISTS OF ! BITS 2**31 TO 2**20 TYPE INFORMATION (MAY BE LANGUAGE DEPENDENT ! BIT 2**19 =0 UNDER LNB =1 IN GLA ! BITS 2**18 TO 2**0 DISPLACEMENT FROM LNB(GLA) IN BYTES ! ! ! THE ENVIRONMENT IS A POINTER (RELATIVE TO SST) OF THE NEXT OUTERMOST ! BLOCK OR A POINTER TO GLOBAL OWNS, EXTERNAL OR COMMON AREAS ! A ZERO MEANS NO ENCLOSING BLOCK. WORD1=WORD3=0 IS AN ! IMP MAIN PROGRAM AND WILL TERMINATE THE DIAGNOSTICS. ! ROUTINE DTABLE(INTEGER LEVEL) !*********************************************************************** !* THIS ROUTINE LOOKS AT THE DECLARATIONS FOR THE CURRENT LEVEL & * !* SETS UP THE SEGMENT OF SHARABLE SYMBOL TABLES TO DESCRIBE THEM.* !* FOR MAIN PROGRAMS OR EXTERNAL ROUTINES THE 'GLOBAL' VARIABLES * !* (IF ANY) ARE ALSO INCLUDED. * !*********************************************************************** STRING (11) RT NAME STRING (11) LOCAL NAME RECORDFORMAT HEADF(HALFINTEGER RTLINE,LINEOFF,OFLAGS,ENV,DISPLAY, RTFLAGS,(INTEGER IDHEAD OR STRING (11)RTNAME)) RECORD (HEADF)NAME DHEAD RECORDFORMAT VARF(HALFINTEGER FLAGS,DISP,STRING (11)VNAME) RECORD (VARF)NAME VAR RECORD (LISTF)NAME LCELL CONSTINTEGER LARRROUT=X'F300' RECORD (TAGF)T INTEGER DPTR,LNUM,ML,KK,JJ,Q,DEND,BIT,S4,LANGD,II CONSTINTEGER DLIMIT=700 INTEGERARRAY DD(0:DLIMIT); ! BUFFER FOR SEGMENT OF SST ! ! FILL ALL OUTSTANDING REFERENCES TO THIS DIAGS BLOCK ! BIT=1<<LEVEL LANGD=KKK>>14<<30!LEVEL<<18; ! GET LITL FROM PTYPE FILL DTABREFS(CURRINF_RAL) PUSH(LEVELINF(LEVEL-1)_RAL,DAREA,CAS(DAREA)+4,LANGD) IF PARM_TRACE#0 DHEAD==RECORD(ADDR(DD(0))) DHEAD_RTLINE=CURRINF_L DHEAD_LINEOFF=CURRINF_DIAGINF IF TARGET=PERQ OR TARGET=ACCENT THEN DHEAD_LINEOFF=DHEAD_LINEOFF+2 DHEAD_OFLAGS<-LANGD>>16 DHEAD_ENV=0 DHEAD_DISPLAY=CURRINF_DISPLAY DHEAD_RTFLAGS=CURRINF_FLAG&X'3FFF' ML=CURRINF_M; ! ROUTINE NAME(=0 FOR %BEGIN) IF ML#0 THEN ML=WORD(ML-1); ! IF NOT BLOCK GET DIRPTR LNUM=WORKA_LETT(ML); ! LENGTH OF THE NAME DPTR=4; DEND=0 IF LNUM=0 THEN DHEAD_IDHEAD=0 ELSE START Q=ADDR(WORKA_LETT(ML)) RT NAME<-STRING(Q); ! FOR RTS MOVE IN 1ST 32 CHARS LNUM=LENGTH(RT NAME) DHEAD_RTNAME=RTNAME; ! AND UPDATE POINTER PAST IF HOST#TARGET AND PARM_TRACE#0 THEN C CHANGE SEX(ADDR(DD(0)),12,LNUM+1) DPTR=DPTR+LNUM>>2; ! ACTUAL NO OF CHARS FINISH DD(DPTR)=CURRINF_ONWORD; ! ON CONDITION WORD DPTR=DPTR+1 JJ=CURRINF_NAMES WHILE 0<=JJ<X'3FFF' CYCLE LCELL==ASLIST(TAGS(JJ)) T=LCELL ! OBTAIN NEXT NAME FORM DECLNS ! ! GET ONLY THE MINIMUM OF DETALS NECESSARY ! S4=LCELL_LINK LCELL_LINK=ASL; ASL=TAGS(JJ) TAGS(JJ)=S4&X'3FFFF' PTYPE=T_PTYPE; TYPE=PTYPE&15 ! ! FAULT ALL UNUSED NAMES EXCEPT CONSTINTEGERS&REALS ! IF (TYPE>2 OR PTYPE&X'FF00'#X'4000') C AND T_UIOJ&X'C000'=0 THEN WARN(2,JJ) I=T_UIOJ>>4&15 J=T_UIOJ&15 K=T_SLINK ! ! ALLOW OWNS (LITL=0) AND EXTERNALS (=2) NOT CONSTS(=1) OR EXTRINSIC(=3) ! IF PARM_DIAG#0 AND PTYPE&X'7300'<=X'200' AND DPTR<DLIMIT-3 C AND (1<=TYPE<=3 OR TYPE=5) START Q=ADDR(WORKA_LETT(WORD(JJ))); ! ADDRESS OF NAME IF I=0 THEN II=1 ELSE II=0; ! GLA OR LNB BIT VAR==RECORD(ADDR(DD(DPTR))) VAR_FLAGS<-PTYPE<<4!II<<2 IF TARGET=PNX AND PTYPE&X'C00'=0 AND II=0 AND C (TYPE=3 OR TYPE=5) START ;! VALUE RECS&STRS K=K+T_ACC FINISH VAR_DISP=K LOCAL NAME<-STRING(Q); ! TEXT OF NAME FROM DICTIONARY LNUM=LENGTH(LOCAL NAME) VAR_VNAME=LOCAL NAME; ! MOVE IN NAME IF HOST#TARGET AND PARM_TRACE#0 THEN C CHANGE SEX(ADDR(DD(0)),4*DPTR+4,LNUM+1) DPTR=DPTR+(LNUM+8)>>2 FINISH IF J=15 AND PTYPE&X'3000'#0 AND T_UIOJ&X'C000'#0 THEN C FAULT(28,0,JJ) ! SPEC&USED BUT NO BODY GIVEN IF J=15 AND TYPE=4 THEN FAULT(62,0,JJ) IF PTYPE&X'3000'#0 OR TYPE=4 OR TYPE=6 THEN C CLEAR LIST(K) ELSE START IF I#0 AND K>4095 AND PTYPE&LARRROUT=0 AND TYPE#7 C THEN WARN(5,JJ) FINISH JJ=S4>>18 REPEAT DD(DPTR)=-1; ! 'END OF SEGMENT' MARK DPTR=DPTR<<2+4 IF PARM_TRACE=1 THEN C PDATA(DAREA,4,DPTR,ADDR(DD(0)));! ADD TO SHARABLE SYM TABS END ; ! OF ROUTINE DTABLE END ROUTINE DECLARE SCALARS(INTEGER XTRA) !*********************************************************************** !* THIS ROUTINE DECLARES A LIST OF SCALARS FROM INFORMATION * !* IN THE GLOBAL VARIABLES ROUT,NAM,ARR,PREC,TYPE & ACC.IT WORKS * !* OUT ROUNDING FACTORS FOR ITSELF. * !* P POINTS TO THE NAMELIST ON ENTRY AND IS UPDATED. * !*********************************************************************** INTEGER INC,SCAL NAME,RL PACK(PTYPE) INC=ACC; SNDISP=0 IF NAM#0 AND ARR=0 AND ROUT=0 THEN INC=PTRSIZE(PTYPE&127) IF NAM>0 AND ARR>0 THEN INC=AHEADSIZE IF PTYPE=X'35' AND (ACC<=0 OR ACC>256) THEN C FAULT(70,ACC-1,0) AND ACC=255 RL=ROUNDING LENGTH(PTYPE,1) UNTIL A(P-1)=2 CYCLE ; ! DOWN THE NAMELIST N=(N+RL+SFRAME MISALIGN)&(¬RL)-SFRAME MISALIGN SCAL NAME=FROM AR2(P) P=P+3 STORE TAG(SCAL NAME,LEVEL,RBASE,0,SNDISP,ACC,N,XTRA) N=N+INC REPEAT N=(N+MIN PARAM SIZE-1)&(-MIN PARAM SIZE); ! THIS IS NECESSARY ! END INTEGERFN DOPE VECTOR(INTEGER TYPEP,ELSIZE,MODE,IDEN, INTEGERNAME ASIZE,LB) !*********************************************************************** !* CONSTRUCTS THE DOPE-VECTOR FOR A CONSTANT ARRAY IN THE * !* SHAREABLE SYMBOL TABLES AND RETURNS ITS DISPLACEMENT AS RESULT* !* P IS TO ALT (MUST BE 1!) OF P<BPAIR> * !* PERQ&ACCENT DOPE VECTOR CONSISTS OF :- * !* @0 DWORD CONTAINING THE BASE OFFSET * !* @4 WORD CONTAINING THE NO OF DIMENSIONS ND * !* @6 WORD HOLDING SIZE (IN BYTES) OF A SINGLE ELEMENT * !* @8 DWORD OF SIZE(IN WORDS OF ENTIRE ARRAY)FOR STACK ADJUSTMENT* !* AND ND DWORD TRIPLES EACH CONSISTING OF:- * !* UBI THE UPPER BOUND OF THE ITH DIMENSION * !* LBI - THE LOWER BOUND OF THE ITH DIMENSION * !* RI - THE STRIDE FOR THE ITH DIMENSION=(UBI-LBI+1) * !* EMAS DOPE VECTOR CONSISTS OF:- * !* @0 BOUNDED WORD DESCRPTOR BOUND=3*ND * !* @8 THE ARRAY SIZE IN BYTES OF ENTIRE ARRAY * !* @12 ND TRIPLES OF LB,MULT AND UPPER CHK AS PER VMY INSTRN * !* NOTE TRIPLES IN REVERSE ORDER FOR HISTORIC COMPATABILITY * !* MODE=0 DV MUST BE CONST, MODE#0 CAN BE DYNAMIC * !* MODE=-1 SPECIAL FOR CONSTARRAYNAMES 1D 0:INFINITY * !*********************************************************************** INTEGER I,JJ,K,ND,D,M0,HEAD,NOPS,TYPEPP,PIN RECORD (LISTF) NAME LCELL INTEGERARRAY LBH,LBB,UBH,UBB(0:12) INTEGERARRAY DV(0:39); ! ENOUGH FOR 12 DIMENSIONS ND = 0; NOPS = 0; TYPEPP = 0; PIN = P M0 = 1 IF (TARGET=PERQ OR TARGET=ACCENT OR TARGET=PNX) AND ELSIZE>1 THEN C ELSIZE=(ELSIZE+1)&(-2) IF MODE=-1 THENSTART ND = 1; LBB(1) = 0 IF TARGET=PERQ OR TARGET=ACCENT THEN ASIZE=X'7FFF' ELSE ASIZE=X'FFFFFF' UBB(1)=ASIZE-1 UBH(1)=ASIZE FINISHELSESTART UNTIL A(P)=2 CYCLE ND = ND+1; P = P+4 FAULT(37,0,IDEN) AND ND = 1 IF ND>12 LBH(ND) = 0; LBB(ND) = 0 UBB(ND) = 0; UBH(ND) = 0 TORP(LBH(ND),LBB(ND),NOPS) P = P+3 TYPEPP = TYPEPP!TYPE TORP(UBH(ND),UBB(ND),NOPS) TYPEPP = TYPEPP!TYPE REPEAT P = P+1 ->NONCONST UNLESS TYPEPP=1 AND NOPS&X'40040000'=0 ! ! NOW ONE CAN WORK OUT AND FILL IN THE TRIPLES ! ASIZE = 1 CYCLE D = 1,1,ND K = 3*D EXPOP(LBH(D),LBB(D),NOPS,X'251') EXPOPND_D = 0 AND FAULT(41,0,0) UNLESS C EXPOPND_FLAG<=1 AND EXPOPND_PTYPE=X'51' LBB(D) = EXPOPND_D EXPOP(UBH(D),UBB(D),NOPS,X'251') EXPOPND_D = 10 AND FAULT(41,0,0) UNLESS C EXPOPND_FLAG<=1 AND EXPOPND_PTYPE=X'51' JJ = EXPOPND_D UBB(D) = JJ UBH(D) = JJ-LBB(D)+1; ! RANGE OF DTH DIMENSION FAULT(38,1-UBH(D),IDEN) UNLESS JJ>=LBB(D) ASIZE = ASIZE*UBH(D) REPEAT ASIZE = ASIZE*ELSIZE FINISH ! ! CALCULATE THE OFF SET OF A(FIRST,..) FROM A(0,..) ! LB = 0; I = ND WHILE I>=2 CYCLE LB = (LB+LBB(I))*UBH(I-1) I = I-1 REPEAT LB = LB+ LBB(1) FAULT(39,0,IDEN) IF ASIZE>X'FFFFFF' ! ! SET UP THE DOPEVECTOR ALLOWING EACH TARGET ITS ODDITIES ! IF TARGET=PERQ OR TARGET=ACCENT OR TARGET=PNX START DV(2) = (ASIZE+1)>>1 DV(0) = -LB DV(1) = ND<<16!ELSIZE FINISH IF TARGET=EMAS START DV(0)=X'28000000'+3*ND DV(1)=12; ! SO LDRL POINTS TO TRIPLES DV(2)=ASIZE; ! FOR ARRAYS BY VALUE IF TYPEP>=3 OR ELSIZE=2 THEN M0=ELSIZE FINISH IF TARGET=IBM OR TARGET=IBMXA START DV(0)=ND DV(1)=(ASIZE+7)&(-8) DV(2)=ELSIZE FINISH CYCLE D=1,1,ND IF TARGET=PERQ OR TARGET=ACCENT OR TARGET=PNX START K=3*D DV(K)=UBB(D) DV(K+1)=LBB(D); ! LOWER BND OVER UPPER M0=M0*UBH(D) DV(K+2)=M0; ! RANGE FINISH IF TARGET=EMAS START K=3*(ND+1-D); ! TRIPLES IN REVERSE ORDER DV(K)=LBB(D) DV(K+1)=M0; ! RUNNING MULTIPLIER M0=M0*UBH(D); ! UPPED BY RANGE DV(K+2)=M0 FINISH IF TARGET=IBM OR TARGET=IBMXA START K=3*D DV(K)=LBB(D) DV(K+1)=UBB(D) DV(K+2)=M0*ELSIZE M0=M0*UBH(D) FINISH REPEAT K = 3*ND+2 J = ND; ! DIMENSIONALITY FOR DECLN HEAD = DVHEADS(ND) WHILE HEAD#0 CYCLE LCELL == ASLIST(HEAD) IF LCELL_S2=ASIZE START CYCLE D = 0,1,K ->ON UNLESS DV(D)=CTABLE(D+LCELL_S1) REPEAT SNDISP = 4*LCELL_S1 RESULT = LCELL_S3 FINISH ON: HEAD = LCELL_LINK REPEAT SNDISP = 4*WORKA_CONST PTR IF TARGET=PERQ OR TARGET=ACCENT THEN SSTL=(SSTL+3)&(-4) AND I = SSTL; ! PERQ DVS IN SST IF TARGET=EMAS OR TARGET=PNX OR TARGET=IBM OR TARGET=IBMXA THEN I=SNDISP PUSH(DVHEADS(ND),WORKA_CONSTPTR,ASIZE,I) CYCLE D = 0,1,K CTABLE(WORKA_CONST PTR) = DV(D) WORKA_CONST PTR = WORKA_CONST PTR+1 IF HOST=EMAS AND (TARGET=PERQ OR TARGET=ACCENT) THEN C DV(D) = DV(D)>>16!DV(D)<<16 REPEAT IF WORKA_CONST PTR>WORKA_CONST LIMIT THEN FAULT(102,WORKA_WKFILEK,0) IF TARGET=PERQ OR TARGET=ACCENT THEN C PDATA(4,4,4*(K+1),ADDR(DV(0))) AND SSTL = SSTL+4*(K+1) WAYOUT: IF MODE=-1 THENRESULT = I; ! NO EXPRESSION CELLS TO RETURN RESULT = I NONCONST: ! NOT A CONST DV J = ND; I = -1; SNDISP = -1 LB = 0; ASIZE = ELSIZE IF MODE=0 THEN FAULT(41,0,0) ELSE P = PIN CYCLE D=1,1,ND CLEAR LIST(LBH(D)) CLEAR LIST(UBH(D)) REPEAT ->WAYOUT END ROUTINE DECLARE ARRAYS(INTEGER FORMAT,FINF) !*********************************************************************** !* FORMAT=1 FOR 'ARRAYFORMAT' =0 OTHERWISE * !* FINF>0 FOR RECORD FORMAT INFORMATION =0 OTHERWISE * !* P IS AT P<ADECLN> IN * !* * !* P<ADECLN>=<NAMELIST> <BPAIR> <RESTOFDECLN> * !* P<BPAIR> = '('<EXPR>':'<EXRR><RESTOFBP>*')' * !* * !* ARRAYS WITH CONSTANT BOUNDS HAVE THEIR D-V IN THE SST * !* ALL OTHER ARRAYS HAVE A DOPE VECTOR AMONG THE LOCALS AND GET * !* THEIR SPACE OFF THE STACK AT RUN TIME * !* BOTH SORTS OF ARRAYS HAVE A FOUR WORD HEAD AND D-V TO EMAS * !* SYSTEM STANDARDS * !*********************************************************************** INTEGER DVDISP,PP,DVF,ELSIZE,TOTSIZE,PTYPEP,ARRP,NN,ND,II,CDV,LWB, PTYPEPP,JJJ,JJ,TRIP1 RECORD (RD) OPND1 SAVE STACK PTR; ! FOR LATER UNDECLARING ARRP=2*FORMAT+1; ARR=ARRP; PACK(PTYPEP) ELSIZE=ACC IF (TARGET=PERQ OR TARGET=ACCENT OR TARGET=PNX) AND ELSIZE>1 THEN C ELSIZE=(ELSIZE+1)&(-2) START:NN=1; P=P+1; ! NO OF NAMES IN NAMELIST PP=P; CDV=0; PTYPEPP=PTYPEP P=P+3 AND NN=NN+1 WHILE A(P+2)=1 P=P+3 DVDISP=DOPE VECTOR(TYPE,ELSIZE,1,FROMAR2(PP),TOTSIZE,LWB) ND=J ->CONSTDV UNLESS DVDISP<0 ! ! NORMAL CASE - PLANT CODE TO SET UP DOPE-VECTOR AT RUN TIME ! DVF=0; TOTSIZE=X'FFFF' N=(N+3)&(-4); ! MAY BE BENEFITS IN WORD ALIGNMENT DVDISP=N; ! DVDISP IS D-V POSITION N=N+12*ND+12; ! CLAIM SPACE FOR THE D-V IF TARGET=PNX THEN DVDISP=N-4 TRIP1=ULCONSTTRIP(DVSTT,X'51',DONT OPT,ND<<16!ELSIZE,PTYPEP<<16!DVDISP); ! ASSN ND&DIMEN->DVDIPS+4 ! CYCLE II=1,1,ND P=P+1 CSEXP(X'51'); ! LOWER BOUND IF EXPOPND_FLAG>0 OR EXPOPND_D#0 THEN DVF=DVF!(1<<II);!NON ZERO ! BASE OFFSET NOT ZERO OPND1=EXPOPND CSEXP(X'51'); ! UPPER BOUND TRIP1=BRECTRIP(DVBPR,X'51',DONT OPT,OPND1,EXPOPND) TRIPLES(TRIP1)_X1=II<<24!ND<<16!DVDISP REPEAT P=P+1 SNDISP=0; ! DV NOT AVAILABLE AT COMPILETIME IF DVF=0 THENSTART LWB=0 IF FORMAT=0 THEN PTYPEPP=PTYPEP+256 FINISH !*********************************************************************** !* FIND THE OFFSET OF A(0...) FROM A(FIRST...) BY COMPUTING * !* THE OFFSET OF A(FIRST...) FROM A(0...) AND NEGATING * !*********************************************************************** JJ=ULCONSTTRIP(DVEND,X'51',DONT OPT,DVF<<16!ELSIZE,PTYPEPP) TRIPLES(JJ)_X1=ND<<16!DVDISP ->DECL CONSTDV: ! ONE DIMENSION - CONSTANT BOUNDS CDV=1 IF LWB=0 AND FORMAT=0 THEN PTYPEPP=PTYPEP+256 SNDISP=SNDISP>>2 ! SET ARR=2 IF LWB=ZERO IF PARM_COMPILER#0 AND LWB#0 THEN FAULT(99,0,0) DECL: ! MAKE DECLN - BOTH WAYS J=ND N=(N+3)&(-4) PTYPE=PTYPEPP; UNPACK CYCLE JJJ=0,1,NN-1; ! DOWN NAMELIST K=FROM AR2(PP+3*JJJ) STORE TAG(K,LEVEL,RBASE,J,SNDISP,ELSIZE,N,FINF) JJ=ULCONSTTRIP(DARRAY,X'61',0, CDV<<31!JJJ<<24!(NN-1)<<16!DVDISP,K) JJ=ULCONSTTRIP(ASPTR,X'61',0, CDV<<31!SNDISP<<16!DVDISP,K) IF FORMAT=0 N=N+AHEADSIZE REPEAT P=P+1; ! PAST REST OF ARRAYLIST IF A(P-1)=1 THEN ->START RETURN END INTEGERFN ROUNDING LENGTH(INTEGER PTYPE,RULES) !*********************************************************************** !* RULES=0 IN RECORDS(BEST DEFINED) * !* RULES=1 IN STACK FRAME(MOST LATITUDE) * !* RULES=2 AS PARAMETERS(FUNNY HARDWARE CONSIDERATIONS) * !*********************************************************************** IF PTYPE&X'1000'#0 THEN RESULT =PTR ROUNDING(128*RULES) ! TREAT RT PARAMS AS %NAME IF PTYPE&X'C00'#0 THEN RESULT =PTR ROUNDING(PTYPE&X'7F'+128*RULES) RESULT =RNDING(PTYPE&X'7F'+128*RULES) END ROUTINE CLT !*********************************************************************** !* DEAL WITH PHRASE TYPE AND SET PREC,TYPE & ACC * !* ONLY PROBLEM ARE STRINGS WHICH HAS OPTIONAL MAX LENGTH ALSO * !* RECORD WHICH HAVE A FORMAT * !* P ON PHRASE TYPE AT ENTRY - TO NEXT PHRASE AT EXIT. * !*********************************************************************** INTEGER ALT,PTYPEP,I,FLAGS,SJ ALT=A(P) FLAGS=TYPEFLAG(ALT) IF FLAGS&X'8000'#0 THEN P=P+1 AND FLAGS=TYPEFLAG(A(P)+FLAGS&15) IF FLAGS&X'4000'#0 THEN P=P+1;! ALLOWS BYTE OR BYTEINTEGER ETC IF FLAGS&X'2000'#0 THEN WARN(8,0);! SUBSTITUTION MADE IF FLAGS&X'1000'#0 THEN FAULT(99,0,0) PREC=FLAGS>>4&15 TYPE=FLAGS&7 P=P+1 ACC=BYTES(PREC) PACK(PTYPEP); ! PRESERVE ALL COMPONENT ! BEFORE CALLINT INTEXP ETC IF TYPE=5 THEN START ; ! P<TYPE>='%STRING' IF A(P)=1 THEN START ; ! MAX LENGTH GIVEN IF A(P+1)=1 START ; ! EXPRESSION NOT STAR P=P+4 IF INTEXP(I,MINAPT)#0 THEN FAULT(41,0,0) ACC=I+1 PTYPE=PTYPEP; UNPACK FINISH ELSE ACC=0 AND P=P+2 FINISH ELSE ACC=0 AND P=P+1 FINISH KFORM=0 IF TYPE=3 THEN START SJ=J KFORM=CFORMATREF PTYPE=PTYPEP UNPACK J=SJ FINISH END ROUTINE CQN(INTEGER P) !*********************************************************************** !* SET NAM & ARR FROM ALTERNATIVE OF PHRASE <QNAME'> * !* P<QNAME'>='%ARRAYNAME','%NAME',<%NULL> * !* P POINTS TO THE ANALYSIS RECORD ENTRY AS IS NOT UPDATED * !*********************************************************************** INTEGER I I=A(P);NAM=0;ARR=0 IF I=1 THEN ARR=1; ! ARRAYNAMES IF I<=2 THEN NAM=1; ! ARRAYNAMES & NAMES END INTEGERFN SET SWITCHLAB(INTEGER HEAD,LAB,FNAME,BIT) !*********************************************************************** !* SET A SWITCH LABEL AND RETURNS RESULT=0 %UNLESS THE LABEL * !* HAS BEEN ALREADY SET WHEN IT RETURNS RESULT#0 * !* HEAD IS HEAD OF THE TAGS SIDECHAIN FOR THE SWITCH * !*********************************************************************** INTEGER Q,QQ,JJJ,LB,UB,BASEPT RECORDFORMAT BITFORM(INTEGERARRAY BITS(0:2),INTEGER LINK) RECORD (RD) OPND1,OPND2 RECORD (BITFORM)NAME BCELL RECORD (LISTF)NAME LCELL OLDLINE=0 LCELL==ASLIST(HEAD) LB=LCELL_S2 UB=LCELL_S3 HEAD=LCELL_LINK BCELL==ASLIST(HEAD) UNLESS LB<=LAB<=UB THEN FAULT(50,LAB,FNAME) AND RESULT =0 Q=LAB-LB WHILE Q>=96 CYCLE HEAD=BCELL_LINK BCELL==ASLIST(HEAD) Q=Q-96 REPEAT ! ! ASLIST(HEAD) IS THE START OF 96 BIT ENTRY IN THE BIT LIST ! CHECK BIT NO Q TO SEE IF LABEL ALREADY SET AND THEN SET BIT Q ! QQ=Q>>5; ! RIGHT WORD Q=Q&31; JJJ=1<<Q; ! BIT IN WORD RESULT =1 UNLESS BCELL_BITS(QQ)&JJJ=0 BCELL_BITS(QQ)=BCELL_BITS(QQ)!BIT<<Q;! DONT SET BIT ON SW(*) ENTRIES OPND1_S1=X'56'<<PTSHIFT!DNAME<<FLAGSHIFT OPND1_D=FNAME OPND1_XTRA=0 OPND2_S1=X'51'<<PTSHIFT!SCONST<<FLAGSHIFT OPND2_D=LAB QQ=BRECTRIP(SETSW,X'56',0,OPND1,OPND2) RESULT =0 END ROUTINE CRSPEC (INTEGER M) !*********************************************************************** !* MODE=0 FOR NORMAL ROUTINE SPEC * !* MODE=1 FOR EXTERNAL(ETC) ROUTINE SPECS XREF NEEDED * !* P ON ENTRY TO P(RT) IN (RT)(MARK)(%SPEC')(NAME)(FPP) * !*********************************************************************** INTEGER KK,JJ,TYPEP,OPHEAD,NPARMS,AXNAME,SACC,SKFORM LITL=EXTRN&3 ACC=0; KFORM=0; ! FOR NORMAL RTS-CLT WILL REVISE IF A(P)=1 THEN START ; ! P<RT>=%ROUTINE TYPEP=LITL<<14!X'1000' P=P+2; ! IGNORING ALT OF P(SPEC') FINISH ELSE START ; ! P<RT>=<TYPE><FNORMAP> ROUT=1; ARR=0; P=P+1 CLT; NAM=0 IF A(P)=2 THEN NAM=2; ! 2 FOR MAP 0 FOR FN PACK(TYPEP) P=P+2; ! AGAIN IGNORING ALT OF P(SPEC') FINISH KK=FROM AR2(P) AXNAME=ADDR(WORKA_LETT(WORD(KK))) JJ=0 P=P+3 SACC=ACC; SKFORM=KFORM; ! FOR RECORD MAPS WITH PARAMS IF A(P-1)=1 THEN START IF LITL=0 THEN WARN(10,0) MOVE BYTES(A(P)+1,ADDR(A(0)),P,ADDR(A(0)),WORKA_ARTOP) AXNAME=ADDR(A(WORKA_ARTOP)) WORKA_ARTOP=(WORKA_ARTOP+4+A(P))&(-4) P=P+A(P)+1 FINISH CFPLIST(OPHEAD,NPARMS) IF M=1 THEN START IF TARGET=EMAS OR TARGET=PNX THEN C CXREF(STRING(AXNAME),3*PARM_DYNAMIC!EXTRN,2,JJ) ! %SYSTEM & %EXTERNAL =STATIC ! UNLESS PARM DYNAMIC SET ! %DYNAMIC = DYNAMIC IF TARGET=PERQ OR TARGET=ACCENT THEN JJ=AXNAME-ADDR(A(WORKA_DICTBASE)) FINISH ELSE START IF TARGET=PERQ OR TARGET=ACCENT THEN JJ=WORKA_RTCOUNT AND WORKA_RTCOUNT=WORKA_RTCOUNT+1 FINISH IF M=0 AND RLEVEL=0 START IF PARM_CPRMODE=0 THEN PARM_CPRMODE=2 IF PARM_CPRMODE#2 THEN FAULT(56,0,KK) FINISH J=15-M; PTYPE=TYPEP STORE TAG(KK,LEVEL,RBASE,15-M,JJ,SACC,OPHEAD,SKFORM) END ROUTINE CFPLIST(INTEGERNAME OPHEAD,NPARMS) !*********************************************************************** !* COMPILE A FORMAL PARAMETER PART INTO A LIST OF PARAMETER TYPES * !* P(FPP)='('{(HOLE)(FPDEL)(NAMELIST)(MARK)}*')',0. * !* * !* THE LIST OF PARAMETER LOOKS LIKE:- * !* S1 = PTYPE FOR PARAM<<16!LNAME<<12!DIMENSION(DIMEN DEDUCED LATER)* !* LNAME IS PARAMS LOCAL NAME * !* S2 = PARAMETER OFFSET(SNDISP) <<16 ! ACC * !* S3 = 0 (RESERVED FOR FPP OF RTS) * !* * !* ON ENTRY P IS AT ALT OF FPP (WHICH MAY BE NULL) * !*********************************************************************** INTEGER OPBOT, PP, INC, RL, RSIZE, CELL RECORD (LISTF)NAME LCELL OPHEAD=0; OPBOT=0 NPARMS=0; ! ZERO PARAMETERS AS YET WHILE A(P)=1 CYCLE ; ! WHILE SOME(MORE) FPS PP=P+1+FROMAR2(P+1); ! TO NEXT FPDEL P=P+3; ! TO ALT OF FPDEL CFPDEL; ! GET TYPE & ACC FOR NEXT GROUP IF ARR=1 THEN START INC=AHEADSIZE; RL=ROUNDING LENGTH(AHEADPT,2) FINISH ELSE IF NAM=1 AND ROUT=0 THEN START INC=PTRSIZE(PTYPE&X'7F') RL=PTRROUNDING(PTYPE&X'7F'+256) FINISH ELSE IF STRVALINWA=YES AND PTYPE=X'35' THEN START INC=PTRSIZE(X'35') RL=PTRROUNDING(256+X'35') FINISH ELSE IF TARGET=EMAS AND PTYPE=X'33' THEN START INC=ACC+8; ! ALLOW FOR DESCRPTR FOR IMP80 COMPATABILITY RL=3; ! STRICTLY ROUNDING LENGTH(X'33',2) FINISH ELSE INC=ACC AND RL=ROUNDING LENGTH(PTYPE,2) UNTIL A(P-1)=2 CYCLE ; ! DOWN <NAMELIST> FOR EACH DEL IF PARAMS BWARDS=YES THEN START PUSH(OPHEAD,0,0,RL) CELL=OPHEAD FINISH ELSE START BINSERT(OPHEAD,OPBOT,0,0,RL) CELL=OPBOT FINISH LCELL==ASLIST(CELL) LCELL_PTYPE=PTYPE; ! DIRECT "PUS" FAILS ON HALF SWOPPED MACHINES LCELL_SNDISP=INC LCELL_ACC=ACC NPARMS=NPARMS+1 P=P+3 REPEAT P=PP REPEAT OPBOT=OPHEAD; INC=0; ! FURTHER PASS TO ALLOCATE SPACE WHILE OPBOT>0 CYCLE LCELL==ASLIST(OPBOT) RL=LCELL_S3; LCELL_S3=0; ! EXTRACT ROUNDIMG LENGTH RSIZE=LCELL_SNDISP; ! INC EXTRACTED INC=(INC+RL+SFRAME MISALIGN)&(¬RL)-SFRAME MISALIGN IF PARAMSBWARDS=NO AND RSIZE<MINPARAMSIZE AND LCELL_PTYPE&7<=2 C THEN INC=INC+MINPARAMSIZE-RSIZE ! MAINTAIN BYTES &SHORTS IN BTM ! OF WORDS FOR 2900&IBM ARCHITECTURE LCELL_SNDISP=INC; ! THE PARAMETER OFFSET INC=INC+RSIZE OPBOT=LCELL_LINK REPEAT INC=(INC+RL+SFRAME MISALIGN)&(¬RL)-SFRAME MISALIGN P=P+1 PRINT LIST(OPHEAD) IF PARM_Z#0 IF TARGET=PNX AND INC&7#0 START ;! FUNNY STACK RULES ON PNX INC=INC+4 OPBOT=OPHEAD WHILE OPBOT#0 CYCLE LCELL==ASLIST(OPBOT) LCELL_SNDISP=LCELL_SNDISP+4 OPBOT=LCELL_LINK REPEAT FINISH IF NPARMS>0 THEN ASLIST(OPHEAD)_S3=INC<<16!NPARMS PRINTLIST(OPHEAD) IF PARM_Z#0 END ROUTINE CFPDEL !*********************************************************************** !* SET UP PTYPE & ACC FOR A FORMAL PARAMETER DEFINITION * !* P<FPDEL>=<TYPE><%QNAME'>, * !* (RT)(%NAME')(NAMELIST)(FPP), * !* '%NAME'. * !*********************************************************************** SWITCH FP(1:3) INTEGER FPALT FPALT=A(P); P=P+1 KFORM=0; LITL=0 ->FP(FPALT) FP(1): ! (TYPE)(%QNAME') ROUT=0; CLT CQN(P) IF TYPE=5 AND NAM=0 AND (ACC<=0 OR ACC>256) THEN C FAULT(70,ACC-1,0) AND ACC=255 P=P+1 ->PK FP(2): ! (RT)(%NAME')(NAMELIST)(FPP) ROUT=1; NAM=1 ARR=0 IF A(P)=1 THEN START ; ! RT=%ROUITNE TYPE=0; PREC=0 P=P+2 FINISH ELSE START P=P+1; CLT; ! RT=(TYPE)(FM) NAM=1 IF A(P)=2 THEN NAM=3; ! 1 FOR FN 3 FOR MAP P=P+2; ! PAST (%NAME') WHICH IS IGNORED FINISH ACC=RT PARAM SIZE ->PK FP(3): ! %NAME ACC=PTRSIZE(0); NAM=1 ROUT=0; TYPE=0 ARR=0; PREC=0 PK: PACK(PTYPE) END ROUTINE RHEAD(INTEGER RTNAME,AXNAME) !*********************************************************************** !* COMPILES CODE FOR BLOCK AND ROUTINE ENTRY * !* RTNAME IS THE RT/FN/MAP NAME (=-1 FOR %BEGIN BLOCKS) * !* XNAME IS THE EXTERNAL NAME (="" FOR INTERNALS&BLOCKS * !* ACTIONS INCLUDE PLANTING JUMPS ROUND RT BODY AND * !* DEFINING EXTERNAL ENTRIES AS WELL AS PLANTING ENTRY CODE * !*********************************************************************** INTEGER W3 RECORD (LISTF)NAME LCELL CURRINF_SNMAX=NMAX; CURRINF_SN=N IF RTNAME>=0 THEN START ; ! SECTION FOR ROUTINES LCELL==ASLIST(TAGS(RTNAME)) ! ! FIRST JUMP ROUND BODY UNLESS AT TOP LEVEL OR IN COMPILER ! OR A JUMP IS ALREADY OUTSTANDING AT THIS LEVEL ! MUST DO THIS HERE BEFORE LEVEL IS CHANGED OR LABEL LIST IS WRONG ! IF PARM_COMPILER=0 AND LEVEL>1 AND CURRINF_JROUND=0 START PLABEL=PLABEL-1 CURRINF_JROUND=PLABEL IF JRNDBODIES=YES THEN ENTER JUMP(15,PLABEL,0) FINISH RLEVEL=RLEVEL+1; RBASE=RLEVEL FINISH LEVEL=LEVEL+1 CURRINF==LEVELINF(LEVEL) CURRINF=0 CURRINF_RBASE=RBASE CURRINF_CLEVEL=LEVEL; ! SELF POINTER IS NEEDED IN GENERATE CURRINF_NAMES=-1 CURRINF_DIAGINF=LEVELINF(LEVEL-1)_DIAGINF CURRINF_DISPLAY=LEVELINF(LEVEL-1)_DISPLAY FAULT(34, 0, 0) IF LEVEL=MAX LEVELS FAULT(105, 0, 0) IF LEVEL>MAX LEVELS ! ! DEAL WITH EXTERNAL ENTRIES SO THAT THEY COME TO THIS POINT ! IN THE CODE. THE DESCRIPTORS SET UP ARE OF NO INTEREST TO THIS MODULE ! ONLY TO OTHER MODULES SO NO DETAILS OF THEN ARE RECORDED IN TAGS ! IF RTNAME<0 THEN W3=0 ELSE W3=RTNAME+1 CURRINF_L=LINE; CURRINF_M=W3 CURRINF_FLAG=PTYPE; ! CURRENT BLOCK TYPE MARKER ! ! TILL LOADER COPIES GLAP TO GLA MUST CALL A FRIG ROUTINE TO DO ! THIS ESSENTIAL AS SOON AS POSSIBLE IN ANYTHING EXTERNAL ! W3=ULCONSTTRIP(RTHD,X'61',0,RTNAME,AXNAME) END ROUTINE RDISPLAY(INTEGER KK) !*********************************************************************** !* SET UP OR COPY THE DISPLAY * !* SINCE THIS IS IN REGISTERS ON 360 IT IS EASY * !* ALSO CLAIM STACK SPACE AND SET DIAGNOSTIC POINTERS * !*********************************************************************** INTEGER TRIPNO IF KK>=0 OR LEVEL=2 START ; ! DISPLAY NEEDED ! DONE BY THE QCODE CALL CURRINF_PSIZE=N; ! REMEMBER PARAMETER SIZE FOR RTDICT IF DISPLAY NEEDED=YES START CURRINF_DISPLAY=N N=N+4*RLEVEL; ! RESERVE DISPLAY SPACE IF TARGET=PNX THEN N=N+4;! GLOBALS ALSO IN PNX DISPLAY FINISH TRIPNO=UCONSTTRIP(RDSPY,X'51',0,N) FINISH ! ! IF IN DIAGNOSTIC MODE PLANT CODE TO SAVE THE LINE & ROUTINE NO OF ! THE CALLING ROUTINE AND SET UP THE NEW BLOCK/ROUTINE IDENT NO. ! IF PARM_TRACE#0 START IF KK>=0 OR LEVEL=2 START ; ! ROUTINE NEW AREA NEEDED TRIPNO=UCONSTTRIP(RDAREA,X'51',0,N) N=N+4 CURRINF_DIAGINF=N N=N+4 FINISH TRIPNO=UCONSTTRIP(RDPTR,X'51',0,LEVEL) FINISH OLDLINE=0 SET LINE ! ! NORMALLY CODE IS PLANTED HERE TO CHECK PARAMETERS BUT I CANNOT ! SEE HOW TO DO THIS ON PERQ ARCHITECTURE. IT MAY BE IN THE QCODE ANYHOW ! ! ! CLAIM (THE REST OF) THE STACK FRAME ! IF KK>=0 OR LEVEL=2 START NMAX=N FINISH END ROUTINE CUI(INTEGER CODE) !*********************************************************************** !* COMPILE AN UNCONDITIONAL INSTRN WHEREEVER IT OCCURS * !* CODE=0 UNCONDITIOALLY,=1 AFTER %THEN, =2 AFTER %ELSE * !*********************************************************************** INTEGER MARKER,J,LNAME,TYPEP,PRECP,ALT,KK RECORD (RD) OPND1 INTEGER HEAD1,BOT1,NOPS RECORD (RD)RPOP SWITCH SW(1:9) REPORTUI=0 ALT=A(P) ->SW(ALT) SW(1): ! (NAME)(APP)(ASSMNT?) P=P+1; MARKER=P+FROMAR2(P) IF A(MARKER)=1 THEN START J=P+2; P=MARKER+2 ASSIGN(A(MARKER+1),J) FINISH ELSE START P=P+2 CNAME(0) P=P+1 FINISH AUI: J=A(P); P=P+1 IF J=1 THEN CUI(CODE) RETURN SW(2): ! -> (NAME)(APP) CURRINF_NMDECS=CURRINF_NMDECS!1 CURR INST=1 IF CODE=0 LNAME=FROM AR2(P+1) J=A(P+3); P=P+4 IF J=2 THEN START ; ! SIMPLE LABEL ENTER JUMP(15,LNAME,0) REPORTUI=1 FINISH ELSE START ; ! SWITCH LABELS COPY TAG(LNAME) UNLESS OLDI=LEVEL AND TYPE=6 START FAULT(4,0,LNAME); P=P-1; SKIP APP RETURN FINISH CSEXP(MINAPT) OPND1_S1=PTYPE<<PTSHIFT!DNAME<<FLAGSHIFT OPND1_D=LNAME OPND1_XTRA=0 KK=BRECTRIP(GOTOSW,PTYPE,0,OPND1,EXPOPND) REPORTUI=1 FINISH RETURN SW(3): ! RETURN FAULT(30,0,0) UNLESS CURRINF_FLAG&X'3FFF'=X'1000' P=P+1 RET: KK=UCONSTTRIP(RTXIT,X'51',0,0) REPORT UI=1 CURR INST=1 IF CODE=0 RETURN SW(4): ! %RESULT(ASSOP)(EXPR) PTYPE=CURRINF_FLAG&X'3FFF'; UNPACK OPND1=0 OPND1_S1=PTYPE<<PTSHIFT!DNAME<<FLAGSHIFT OPND1_D=CURRINF_M-1 IF PTYPE>X'1000' AND A(P+1)#3 THEN START ;! ASSOP #'->' IF A(P+1)=1 AND NAM#0 AND A(P+5)=4 AND A(P+6)=1 START P=P+7; TYPEP=TYPE; PRECP=PREC; J=P CNAME(4) KK=BRECTRIP(MAPRES,PTYPE&255,0,OPND1,NAMEOPND) FAULT(81,0,0) UNLESS A(P)=2; P=P+1 FAULT(83,CURRINF_M-1,FROMAR2(J)) C UNLESS TYPEP=TYPE AND PRECP=PREC ->RET FINISH IF A(P+1)=2 AND NAM=0 THEN START ;! ASSOP='=' P=P+2 IF TYPE=5 THEN START CSTREXP(32); ! FULL VIRTAD FINISH ELSE START IF PREC<4 THEN PREC=4 CSEXP(PREC<<4!TYPE) FINISH KK=BRECTRIP(FNRES,PTYPE&255,0,OPND1,EXPOPND) ->RET FINISH FINISH FAULT(31,0,0) P=P+2; SKIP EXP; ! IGNORE SPURIOUS RESULT RETURN SW(5): ! %MONITOR (AUI) KK=UCONSTTRIP(MNITR,X'51',0,0) P=P+1; ->AUI SW(6): ! %STOP KK=UCONSTTRIP(XSTOP,X'51',0,0) P=P+1 CURR INST=1 IF CODE=0 REPORTUI=1 RETURN SW(7): !'%SIGNAL'(EVENT')(N)(OPEXPR) P=P+5 KK=INTEXP(J,MINAPT); ! EVENT NO TO J FAULT(26,J,0) UNLESS KK=0 AND 1<=J<=15 HEAD1=0; NOPS=0 RPOP=0 RPOP_PTYPE=X'51' RPOP_FLAG=1 RPOP_D=256*J PUSH(HEAD1,RPOP_S1,RPOP_D,0); ! EVENT<<8 AS CONST BOT1=HEAD1 IF A(P)=1 START ; ! SUBEVENT SPECIFIED PUSH(HEAD1,ANDL<<FLAGSHIFT,0,0);! OPERATOR & RPOP_PTYPE=X'51' RPOP_FLAG=1 RPOP_D=255 PUSH(HEAD1,RPOP_S1,RPOP_D,0); ! CONST=F'255' P=P+4; TORP(HEAD1,BOT1,NOPS) BINSERT(HEAD1,BOT1,ORL<<FLAGSHIFT,0,0); ! OPERATOR ! NOPS=NOPS+2 FINISH EXPOP(HEAD1,BOT1,NOPS,X'51') OPND1_PTYPE=X'51'; OPND1_FLAG=SCONST OPND1_D=LEVEL IF CURRINF_NMDECS&16 #0 START ; ! IN AN 'ON' GROUP OPND1_D=LEVEL-1; ! SIGNAL 1 LEVEL UP FINISH KK=BRECTRIP(SIGEV,X'51',DONTOPT,OPND1,EXPOPND) CURR INST=1 IF CODE=0 REPORTUI=1; RETURN SW(8): ! %EXIT SW(9): ! %CONTINUE ALT=ALT&7; ! 0 FOR EXIT 1 FOR CONTINUE IF EXITLAB=0 THEN FAULT(54+ALT,0,0) AND RETURN IF ALT=0 THEN KK=EXITLAB ELSE KK=CONTLAB ENTER JUMP(15,KK&X'FFFFFF',B'10'!KK>>31) REPORTUI=1 CURR INST=1 IF CODE=0 END ROUTINE CIFTHEN(INTEGER MARKIU,MARKC,MARKUI,MARKE,MARKR,SKIP) !*********************************************************************** !* THIS ROUTINE COMPILES CONDITIONAL EXPRESSIONS.IT REQUIRES THE * !* FOLLOWING PARAMETERS TO BE SET TO THEIR A .R. ENTRY. * !* MARKIU TO THE ENTRY FOR P(%IU) * !* MARKC TO THE ENTRY FOR P(COND) * !* MARKUI TO THE ENTRY FOR (FIRST OCCURRENCE OF) P(UI) * !* MARKE TO THE ENTRY FOR P(ELSE') - =0 FOR BACKWARDS CONDITION * !* MARKR TO ENTRY FOR P(RESTOFIU) - =0 FOR BACKWARDS CONDITION * !*********************************************************************** INTEGER ALTUI,CCRES,ELRES,THENLAB,ELSELAB,USERLAB,REPORT,START, C ELSEALT,K,CS CONSTINTEGER NULL ELSE=4 SWITCH ESW(1:NULL ELSE) SET LINE UNLESS SKIP=YES MARKIU=A(MARKIU); ! ALT OF IU 1=%IF,2=%UNLESS PLABEL=PLABEL-1 THENLAB=PLABEL START=0; CS=0; ! NO START IN CONDITION YET CS=1 IF STARSIZE>100; ! LONG JUMPS FOR COMPLEX STMTS ELSELAB=0; ! MEANS NO ELSE CLAUSE P=MARKC IF MARKR>0 AND A(MARKR)<=2 THEN C START=1 AND CS=CHECK BLOCK(MARKR+1,MARKC);! '%START' OR '%THENSTART' IF MARKE#0 AND LEVEL<2 AND START=0 THEN FAULT(57,0,0) USERLAB=-1 IF START#0 THEN ALTUI=0 ELSE ALTUI=A(MARKUI) IF ALTUI=2 AND A(MARKUI+3)=2 THEN C USERLAB=FROM AR2(MARKUI+1); ! UI = SIMPLE LABEL IF 8<=ALTUI<=9 AND EXITLAB#0 START ; ! VALID EXIT IF ALTUI=8 THEN USERLAB=EXITLAB ELSE USERLAB=CONTLAB FINISH ! IF SKIP=YES THEN START ; ! NO CODE NEEDED IF START#0 START P=MARKR+1 CSTART(2,1); ! NO CODE MARKE=P FINISH CCRES=1; ! NO CODE FOR ELSE ->ELSE FINISH ! IF USERLAB>=0 THEN START ; ! FIRST UI IS'->'<LABEL> CURRINF_NMDECS=CURRINF_NMDECS!1 CCRES=CCOND(0,3-MARKIU,USERLAB&X'FFFFFF',USERLAB>>31) IF CCRES#0 THEN CCRES=CCRES!!3;! CONDITION BACKWARDS! THENLAB=0; ! NO THENLAB IN THIS CASE REPORT=1; ! UI TRANSFERED CONTROL FINISH ELSE START CCRES=CCOND(1,MARKIU,THENLAB,B'11'!!START!!CS) IF START#0 THEN START ; ! %THEN %START IF CCRES=0 START ; ! CONDITIONAL FAULT(57,0,0) IF LEVEL<2 CURRINF_NMDECS=CURRINF_NMDECS!1 FINISH P=MARKR+1 CSTART(CCRES,1) IF A(P)<=2 THEN PLABEL=PLABEL-1 AND ELSELAB=PLABEL MARKE=P REPORT=LAST INST FINISH ELSE START IF CCRES#2 START P=MARKUI; CUI(1) REPORT=REPORTUI FINISH ELSE START ; ! FIRST UI NEVER EXECUTED REPORT=1 FINISH FINISH FINISH ELSE: ! ELSE PART IF MARKE=0 THEN ELSEALT=NULL ELSE ELSE ELSEALT=A(MARKE) IF ELSEALT<NULL ELSE THEN PLABEL=PLABEL-1 AND ELSELAB=PLABEL P=MARKE+1 IF REPORT=0=CCRES AND ELSEALT<NULL ELSE THEN START REPORT=1 K=B'10' IF (ELSEALT=3 AND STARSIZE<100) OR C (ELSEALT=1 AND CHECK BLOCK(P,P)#0) THEN K=B'11' ENTER JUMP(15,ELSELAB,K); ! LONG(?) JUMP BUT SAVE ENV FINISH IF THENLAB>0 THEN ELRES=ENTER LAB(THENLAB,B'11'!REPORT<<2) ! CONDITIONAL&MERGE OR REPLACE ->ESW(ELSEALT) ESW(1): ! '%ELSESTART' IF CCRES=0 THEN CURRINF_NMDECS=CURRINF_NMDECS!1 CSTART(CCRES,2) REPORT=LAST INST ->ENTER ELSELAB ESW(2): ! '%ELSE' (%IU) ETC MARKE=0; MARKUI=0 MARKR=P+1+FROMAR2(P+1) IF A(MARKR)=3 THEN START MARKE=MARKR+1+FROM AR2(MARKR+1) MARKUI=MARKR+3 FINISH IF CCRES=1 OR SKIP=YES THEN K=YES ELSE K=NO CIFTHEN(P,P+3,MARKUI,MARKE,MARKR,K) REPORT=0; ! CANT TELL IN GENERAL ->ENTER ELSELAB ESW(3): ! '%ELSE'<UI> IF CCRES#1 THEN START IF START#0 THEN SET LINE; ! FOR CORRECT LINE IF FAILS IN UI IF THENLAB=0 THEN K=0 ELSE K=2 CUI(K) REPORT=REPORTUI FINISH ENTER ELSELAB: IF ELSELAB>0 THEN ELRES=ENTER LAB(ELSELAB,B'11'!REPORT<<2) ! CONDITIONAL MERGE ESW(NULL ELSE): ! NULL ELSE CLAUSE END INTEGERFN CHECKBLOCK(INTEGER P,PIN) !*********************************************************************** !* WORK OUT IF START-FINISH OR CYCLE REPEAT IS SHORT ENOUGH TO * !* MANAGE WITH BYTE JUMP. PIN ALLOWS THE CONDITION TO BE INCLUDED * !* IN THE TEST WHERE RELEVANT. * !*********************************************************************** INTEGER SIZE SIZE=FROMAR4(P)-PIN IF SIZE<64 OR (PARM_OPT=0 AND SIZE<128) THEN RESULT =1 RESULT =0 END ROUTINE CSTART(INTEGER CCRES,CODE) !*********************************************************************** !* COMPILE A COMPLETE START-FINISH BLOCK BY RECURSION * !* IF START NEVER EXECUTED SKIP TO CORRESPONDING FINISH * !* CODE=0 WAS UNCONDITIONAL NOW SHOULD BE UNUSED * !* CODE=1 AFTER THEN * !* CODE=2 AFTER ELSE * !* CODE=3 AFTER ONEVENT * !* P ON ENTRY TO FORWARD POINTER TO THE RIGHT FINISH * !* P ON EXIT TO THE ELSE CLAUSE AFTER THE RIGHT FINISH * !*********************************************************************** INTEGER SKIPCODE,FINISHAR,OLDNEXTP,OLDLINE SKIPCODE=NO IF 1<=CODE<=2 AND CCRES!CODE=3 THEN SKIPCODE=YES;! NEVER EXECUTED FINISHAR=FROMAR4(P); ! TO START OF AR FOR FINISH IF FINISHAR<=P THEN IMPABORT; ! FOR TESTING OLDLINE=LINE; ! FOR ERROR MESSAGES CYCLE ; ! THROUGH INTERVENING STATMNTS OLDNEXTP=NEXTP IF SKIP CODE=NO THEN COMPILE A STMNT ELSE START LINE=A(NEXTP+3)<<8!A(NEXTP+4) STARSIZE=A(NEXTP)<<16+A(NEXTP+1)<<8+A(NEXTP+2) NEXTP=NEXTP+STARSIZE FINISH REPEAT UNTIL OLDNEXTP>=FINISHAR;! HAVING COMPILED FINISH P=FINISHAR+6; ! TO ELSE CLAUSE ! IF A(P)<=3 AND CODE#1 THEN FAULT(45+CODE,OLDLINE,0) IF SKIPCODE=YES THEN LAST INST=1 END ROUTINE CCYCBODY(INTEGER UA,ELAB,CLAB) !*********************************************************************** !* COMPILES A CYCLE REPEAT BODY BY RECURSION * !* ON ENTRY P IS TO FORWARD POINTER. ON EXIT TO ALT OF UNTIL * !* UA = O IF UNTIL NOT ALLOWED * !* ELAB&CLAB ARE LABELS FOR ELSE & CONTINUE * !*********************************************************************** INTEGER FINISHAR,OLDLINE,SAVEE,SAVEC FINISHAR=FROMAR4(P) IF FINISHAR<=P THEN IMPABORT OLDLINE=LINE; SAVEE=EXIT LAB; SAVEC=CONTLAB EXITLAB=ELAB; CONTLAB=CLAB WHILE NEXTP<=FINISHAR CYCLE COMPILE A STMNT REPEAT EXIT LAB=SAVEE; CONTLAB=SAVEC P=FINISHAR+6 IF A(P)=1 AND UA=0 THEN FAULT(12,OLDLINE,0) END ROUTINE CLOOP(INTEGER ALT,MARKC,MARKUI) !*********************************************************************** !* ALT=1 FOR %WHILE, =2 FOR %UNTIL, =3 FOR %FOR * !* MARKC IS TO THE CONDITION OR CONTROL CLAUSE * !* MARKUI IS TO THE UI, SPECIAL FOR %CYCLE * !* FORBITS DEFINES FOR LOOP AS FOLLOWS:- * !* 2**2 TO 2**0 SET FOR CONSTANT INITIAL,INC &FINAL * !* CORRESPONDING UPPER BYTE SET DEFINES CONSTANT FURTHER * !* 2**7 NEGATIVE CONSTANT * !* 2**4 CONSTANT IS 2 * !* 2**3 CONSTANT IS 1 * !* 2**2 CONSTANT IS 0 * !* 2**1 CONSTANT IS -1 * !* 2**0 CONSTANT IS -2 * !* THESE BITS ARE PASSED ON TO GENERATOR FOR SPECIAL CASE * !*********************************************************************** INTEGER L1,L2,L3,L4,CCRES,ELRES,FLINE,TRIP INTEGER FORNAME,INITP,STEPP,REPMASK,FORPT,FORWORDS,FORBITS RECORD (RD) INITOPND,STEPOPND,FINALOPND,DIFFOPND,ZOPND,OPND RECORD (TRIPF) NAME CURRT ROUTINESPEC FOREXP(RECORD (RD) NAME EOPND, INTEGER TT,SH) ROUTINESPEC VALIDATE FOR SWITCH SW(0:6) P=MARKC FORBITS=0 SFLABEL=SFLABEL-2 L1=SFLABEL; L2=L1+1 ! ! SET L3 FOR ALTS 0,5&6 ONLY ! L3=0 IF B'1100001'&1<<ALT#0 THEN L3=SFLABEL-1 AND SFLABEL=L3 ! ! UPDATE THE LINE NUMBER FOR ALTS 1 TO 3 ONLY ! IF 1<=ALT<=3 THEN SET LINE ! ! ENTER THE FIRST LABEL FOR ALL ALTS EXCEPT 3 & 6 ! IF B'0110111'&1<<ALT#0 THEN ELRES=ENTER LAB(L1,0) ->SW(ALT) SW(0): ! %CYCLE C CYC BODY(1,L2,L3) L3=L3*ENTER LAB(L3,B'011'); ! DELETE IF NOT NEEDED IF A(P)=1 START ; ! %REPEAT %UNTIL <COND> SET LINE P=P+1; CCRES=CCOND(0,1,L1,0) FINISHELSE ENTER JUMP(15,L1,0) L2=L2*ENTER LAB(L2,B'011'); ! DELETE IF NOT NEEDED WAYOUT: ! REMOVE LABELS NOT REQUIRED REMOVE LAB(L1) RETURN SW(1): ! UI WHILE COND CCRES=CCOND(0,1,L2,B'11') P=MARKUI CUI(1) ENTER JUMP(15,L1,0); ! UNCONDITIONALLY BACK TO WHILE L2=L2*ENTER LAB(L2,B'111'); ! CONDITIONAL(?) & REPLACE ENV ->WAYOUT SW(2): ! UI %UNTIL COND P=MARKUI CUI(1) P=MARKC CCRES=CCOND(0,1,L1,0) ->WAYOUT SW(6): ! %FOR ... %CYCLE SW(3): ! UI %FOR .... L4=SFLABEL-1; SFLABEL=L4 FORNAME=FROMAR2(P) INITP=P+2 COPY TAG(FORNAME) IF I=-1 THEN CNAME(2); ! DECLARE IF UNKNOWN TO COMPILER FAULT(91,0,FORNAME) UNLESS C (TYPE=7 OR TYPE=1) AND 4<=PREC<=5 AND ROUT=0=ARR AND LITL#1 FORPT=PTYPE&255; ! SAVE TYPE&PREC OF CONTROL FORWORDS=WORDS(FORPT>>4); ! NO OF WORDS FOR TEMPS WARN(4,FORNAME) UNLESS I=RBASE ! P=INITP SKIP EXP; ! P TO STEP EXPRSN STEPP=P; SKIP EXP; ! P TO FINAL FOR EXP(FINALOPND,1,0); ! EVALUATE FINAL ! P=STEPP FOR EXP(STEPOPND,1,1); ! STEP TO REG AND TEMP IF STEPOPND_FLAG=0 START FAULT(92,0,0) IF STEPOPND_D=0; ! ZERO STEP FINISHELSESTART IF PARM_OPT#0 THENSTART TRIP=URECTRIP(STPCK,FORPT,0,STEPOPND); ! VALIDATE STEP FINISH FINISH ! P=INITP FOR EXP(INITOPND,0,2); ! INITIAL VALUE TO ETOS IF PARM_OPT#0 THEN VALIDATE FOR ! DIFFOPND_D=BRECTRIP(SUB,FORPT,0,INITOPND,STEPOPND) DIFFOPND_PTYPE=FORPT; DIFFOPND_FLAG=REFTRIP ! ! HAVE DIFFOPND SET TO INIT-STEP. FOR COMPUTED STEPS NOW MUST CHECK ! FOR NEGATIVE TRAVERSES. FOR FIXED STEPS THIS CAN BE SET ! IN MASK FOR REPEATING ! IF STEPOPND_FLAG>0 THENSTART OPND_D=BRECTRIP(SUB,FORPT,0,FINALOPND,DIFFOPND) OPND_PTYPE=FORPT; OPND_FLAG=REFTRIP OPND_D=BRECTRIP(INTDIV,FORPT,0,OPND,STEPOPND) ZOPND_D=0; ZOPND_PTYPE=FORPT; ZOPND_FLAG=SCONST CURRT==TRIPLES(BRECTRIP(COMP,FORPT,0,OPND,ZOPND)) CURRT_X1=4; ! MASK FOR <0 ENTER JUMP(4,L4,B'10') REPMASK=8 FINISHELSESTART IF STEPOPND_D>0 THEN REPMASK=10 ELSE REPMASK=12 FINISH ! DIFFOPND_D=URECTRIP(FORPRE,FORPT,0,DIFFOPND) TRIPLES(DIFFOPND_D)_X1=FORBITS ! ! MUST PREVENT OPTIMISING OF UNUSED STEP&FINAL TEMPORAIES IN ! REGISTERS ACCROSS THIS LABEL FOR REPEATING. THE OPTIMISING CAN ! BE REINSTATED BY NEXT PASS AFTER CHECKS ! IF STEPOPND_FLAG>1 START ; ! NOT A CONST CURRT==TRIPLES(STEPOPND_D) IF CURRT_PUSE=0 THEN CURRT_FLAGS=CURRT_FLAGS!NOTINREG FINISH IF FINALOPND_FLAG>1 START ; ! NOT A CONST CURRT==TRIPLES(FINALOPND_D) IF CURRT_PUSE=0 THEN CURRT_FLAGS=CURRT_FLAGS!NOTINREG FINISH ELRES=ENTER LAB(L1,0); ! LABEL FOR REPEATING DIFFOPND_D=URECTRIP(FORPR2,FORPT,USE ESTACK,DIFFOPND) TRIPLES(DIFFOPND_D)_X1=FORBITS ! CURRT==TRIPLES(BRECTRIP(COMP,FORPT,0,DIFFOPND,FINALOPND)) CURRT_X1=REPMASK ENTER JUMP(REPMASK,L4,B'10') OPND_D=BRECTRIP(ADD,FORPT,0,DIFFOPND,STEPOPND) OPND_PTYPE=FORPT; OPND_FLAG=REFTRIP ZOPND_PTYPE=FORPT; ZOPND_FLAG=DNAME ZOPND_D=FORNAME ZOPND_XTRA=0 CURRT==TRIPLES(BRECTRIP(VASS,FORPT,0,ZOPND,OPND)) CURRT_X1=FORPT; ! VASS USES THIS FIELD ! P=MARKUI; ! TO UI OR '%CYCLE'(HOLE) IF ALT=3 THENSTART ; ! DEAL WITH CONTROLLED STMNTS CUI(0) FINISHELSESTART CCYCBODY(0,L2,L3) L3=L3*ENTER LAB(L3,B'011'); ! LABEL FOR CONTINUE FINISH TRIP=UNAMETRIP(FOREND,FORPT,0,FORNAME) TRIPLES(TRIP)_X1=FORBITS ENTER JUMP(15,L1,0) ELRES=ENTER LAB(L4,B'10') TRIP=UCONSTTRIP(FORPOST,FORPT,0,0) TRIPLES(TRIP)_X1=FORBITS REMOVE LAB(L4) L2=L2*ENTER LAB(L2,B'111'); ! REPLACE ENV ! WHEN MERGE ENV IF STEPOPND_FLAG>1 THEN RETURN WSP(STEPOPND_XTRA,FORWORDS) IF FINALOPND_FLAG>1 THEN RETURN WSP(FINALOPND_XTRA,FORWORDS) ->WAYOUT SW(4): ! %WHILE COND %CYCLE SET LINE CCRES=CCOND(0,1,L2,0) C CYC BODY(0,L2,L1) ENTER JUMP(15,L1,0) L2=L2*ENTER LAB(L2,B'111'); ! CONDITIONAL & REPLACE ENV ->WAYOUT SW(5): ! %UNTIL ... %CYCLE ! ALSO %CYCLE... %REPEAT %UNTIL ! MARKUI TO %CYCLE P=MARKUI FLINE=LINE C CYC BODY(0,L2,L3) P=MARKC; L3=L3*ENTER LAB(L3,B'011'); ! CONTINUE LABEL IF NEEDED LINE=FLINE; SET LINE CCRES=CCOND(0,1,L1,0) L2=L2*ENTER LAB(L2,B'011') ->WAYOUT ROUTINE FOR EXP(RECORD (RD) NAME EOPND, INTEGER TOTEMP,SHIFT) !*********************************************************************** !* P INDEXES EXPRESSION. IF CONST PUT INTO EVALUE OTHERWISE * !* COMPILE TO ETOS AND STORE IN TEMP IF TOTEMP#0 * !*********************************************************************** INTEGER INP,VAL,SUBBITS INP=P; P=P+3 IF INTEXP(VAL,FORPT)=0 AND X'FFFF8000'<VAL<X'FFFF' START EOPND=EXPOPND; ! EXPRESSION A LITERAL CONST SUBBITS=0 IF VAL<0 THEN SUBBITS=X'80' IF -2<=VAL<=2 THEN SUBBITS=SUBBITS!(1<<(VAL+2)) SUBBITS=SUBBITS<<(8+8*SHIFT) FORBITS=FORBITS!SUBBITS!1<<SHIFT RETURN FINISH EOPND=EXPOPND IF TOTEMP#0 START GET WSP(VAL,FORWORDS!X'80000000') EOPND_PTYPE=FORPT; EOPND_FLAG=LOCALIR EOPND_D=RBASE<<16!VAL; EOPND_XTRA=VAL EOPND_D=BRECTRIP(LASS,FORPT,0,EOPND,EXPOPND) EOPND_FLAG=REFTRIP FINISH END ROUTINE VALIDATE FOR !*********************************************************************** !* INITIAL VALUE IN ETOS * !*********************************************************************** INTEGER J RECORD (RD) OPND IF INITOPND_FLAG!STEPOPND_FLAG!FINALOPND_FLAG=0 START J=FINALOPND_D-INITOPND_D; ! ALL CONSTANT CAN CHECK NOW IF STEPOPND_D=0 OR (J//STEPOPND_D)*STEPOPND_D#J C THEN FAULT(93,0,0) RETURN FINISH IF STEPOPND_FLAG=0 AND IMOD(STEPOPND_D)=1 THENRETURN ! ! CHECK BY PLANTING CODE ! OPND_D=BRECTRIP(SUB,FORPT,0,FINALOPND,INITOPND) OPND_PTYPE=FORPT; OPND_FLAG=REFTRIP J=BRECTRIP(FORCK,FORPT,0,OPND,STEPOPND) END END ROUTINE ASSIGN(INTEGER ASSOP,P1) !*********************************************************************** !* HANDLES ARITHMETIC,STRING & ADDRESS ASSIGNMENTS TO VARIABLES * !* FORMAL PARAMETERS AND DOPEVECTORS * !* ASSOP:- * !* 1 IS FOR '==' * !* 2 IS FOR '=' * !* 3 IS FOR '<-' (JAM TRANSFER) * !* 4 IS FOR '->' (UNCONDITIONAL RESOLUTION) * !* * !* P POINTS TO THE EXPRESSION. P1 TO THE NAME ON LHS * !*********************************************************************** INTEGER Q,KK,TYPEP,PRECP,PTYPEP,JJJ,P2,JJ,B,D,HEAD2,BOT2, C ACCP,II,HEAD1,NOPS,TPCELL,LVL,BOT1,LHNAME,RHNAME RECORD (LISTF)NAME LHCELL RECORD (RD) OPND1,OPND2 SWITCH SW(0:4); ! TO SWITCH ON ASSOP P2=P LHNAME=A(P1)<<8!A(P1+1) LHCELL==ASLIST(TAGS(LHNAME)) P=P1; REDUCE TAG; ! LOOK AT LH SIDE PTYPEP=PTYPE; JJ=J KK=K; II=I; LVL=OLDI TPCELL=TCELL; ACCP=ACC P=P2; TYPEP=TYPE; PRECP=PREC; ! SAVE USEFUL INFO FOR LATER -> SW(ASSOP) SW(2):SW(3): ! ARITHMETIC ASSIGNMENTS IF TYPE=3 THEN ->RECOP TYPE=1 UNLESS TYPE=2 OR TYPE=5; ! IN CASE OF RUBBISHY SUBNAMES ->ST IF TYPE=5; ! LHS IS A STRING BACK: HEAD1=0; BOT1=0; ! CLEAR TEMPORAYRY LIST HEADS HEAD2=0; BOT2=0 TYPE=1 UNLESS TYPE=2; ! DEAL WITH UNSET NAMES TYPEP=TYPE NOPS=1<<18+1 PTYPE=PTYPEP; UNPACK IF LHSADDRFIRST=NO OR (NAM=0=ARR AND A(P1+2)=2=A(P1+3)) START ;! SCALAR BINSERT(HEAD1,BOT1,PTYPE<<PTSHIFT!ARNAME<<FLAGSHIFT,P1,LHNAME) FINISH ELSE START P=P1; CNAME(3); ! 32 BIT ADDR TO STACK BINSERT(HEAD1,BOT1,NAMEOPND_S1,NAMEOPND_D,NAMEOPND_XTRA) FINISH P=P2+3 TORP(HEAD2,BOT2,NOPS); ! RHS TO REVERSE POLISH BINSERT(HEAD2,BOT2,(VASS+ASSOP-2)<<FLAGSHIFT,LHNAME<<16!PTYPEP,0);! = OR <-OPERATOR ASLIST(BOT1)_LINK=HEAD2 HEAD2=0; BOT1=BOT2 EXPOP(HEAD1,BOT1,NOPS,256+PRECP<<4+TYPEP); ! PLANT CODE RETURN ST: ! STRINGS P=P1 REDUCE TAG IF A(P1+2)=2=A(P1+3) AND PTYPE=X'35' AND ASSOP=2 C THEN KK=STRASS2 AND CNAME(2) ELSE KK=STRASS1 AND CNAME(3) OPND1=NAMEOPND P=P2; CSTREXP(32) IF ASSOP=3 THEN KK=STRJT JJ=BRECTRIP(KK,X'35',0,OPND1,EXPOPND) RETURN ! ! THIS SECTION DEALS WITH OPERATIONS ON COMPLETE RECORDS ! RECOP: ! LHS IS RECORD WITHOUT SUBNAME Q=TSEXP(JJJ) IF Q=1 AND JJJ=0 START ; ! CLEAR A RECORD TO ZERO P=P1; CNAME(3) OPND1=NAMEOPND; ACCP=ACC OPND2_S1=X'51'<<PTSHIFT!SCONST<<FLAGSHIFT OPND2_D=0 FINISH ELSE START ->BACK UNLESS TYPE=3 AND A(P2+3)=4 AND A(P2+4)=1 P=P1; CNAME(3) OPND1=NAMEOPND ACCP=ACC P=P2+5; CNAME(3) OPND2=NAMEOPND UNLESS A(P)=2 THEN FAULT(66,0,LHNAME) AND ->F00 IF ASSOP=2 AND ACCP#ACC THEN C FAULT(67,LHNAME,FROMAR2(P2+5)) AND ->F00 IF ACCP>ACC THEN ACCP=ACC FINISH JJ=BRECTRIP(RECASS,X'33',0,OPND1,OPND2) TRIPLES(JJ)_X1=ACCP P=P2; SKIP EXP RETURN SW(4): ! RESOLUTION P=P1; CNAME(2) P=P2; IF TYPE=5 THEN CRES(0) ELSE START SKIP EXP FAULT(71,0,LHNAME) UNLESS TYPE=7 FINISH RETURN SW(1): ! '==' AND %NAME PARAMETERS ->F81 UNLESS A(P2+3)=4 AND A(P2+4)=1 FAULT(82,0,LHNAME) AND ->F00 UNLESS NAM=1 AND LITL#1 ! ONLY NON-CONST POINTERS ON LHS OF== IF ARR=1 THEN START JJ=11; KK=12 II=AHASS; B=AHEADPT FINISH ELSE START JJ=6; KK=3 II=PTRAS; B=X'51' IF PTRSIZE(PTYPE&255)>4 THEN B=X'61' FINISH P=P1; CNAME(JJ) P=P2+5; OPND1=NAMEOPND RHNAME=A(P)<<8!A(P+1) CNAME(KK); ! DESCRPTR FETCHED ->F81 UNLESS A(P)=2; ! NO REST OF EXP ON RHS ->F83 UNLESS TYPE=TYPEP AND PREC=PRECP AND (ARR>0 OR II=PTRAS) ->F86 UNLESS OLDI<=LVL OR BASE=0 OR NAM#0 ! GLOBAL == NONOWN LOCAL JJ=BRECTRIP(II,B,0,OPND1,NAMEOPND) P=P+1 RETURN F83: FAULT(83,LHNAME,RHNAME); ->F00 F86: FAULT(86,LHNAME,RHNAME); ->F00 F81: FAULT(81,0,LHNAME) F00: P=P2; SKIP EXP END ROUTINE CSEXP(INTEGER MODE) !*********************************************************************** !* COMPILE A SIGNED EXPRESSION TO REGISTER 'REG' IN MODE 'MODE' * !* MODE=1 FOR %INTEGER, =2 REAL, =3 LONG,=0 INTEGER %IF POSSIBLE * !* MODE=5 FOR ADDRESS EXPRESSNS(IE LEAVE ANY CONSTANT IN 'ADISP')* !*********************************************************************** INTEGER EXPHEAD,NOPS,EXPBOT EXPHEAD=0; EXPBOT=0 NOPS=0 P=P+3 TORP(EXPHEAD,EXPBOT,NOPS) EXPOP(EXPHEAD,EXPBOT,NOPS,MODE) END INTEGERFN CONSTEXP(INTEGER PRECTYPE) !*********************************************************************** !* COMPILES AN EXPRESSION WHICH SHOULD EVALUATE TO A CONSTANT OF * !* TYPE 'PRECTYPE'. P AS FOR FN INTEXP. * !*********************************************************************** INTEGER EXPHEAD,EXPBOT,NOPS,RES EXPHEAD=0; EXPBOT=0; NOPS=0; RES=0 TORP(EXPHEAD,EXPBOT,NOPS) ->WAYOUT UNLESS NOPS&X'00040000'=0 EXPOP(EXPHEAD,EXPBOT,NOPS,X'200'+PRECTYPE) ->WAYOUT UNLESS EXPOPND_FLAG<=1 RES=ADDR(EXPOPND_D) WAYOUT: RESULT =RES END INTEGERFN INTEXP(INTEGERNAME VALUE,INTEGER PRECTYPE) !*********************************************************************** !* COMPILES AN EXPRESSION WHICH SHOULD EVALUATE TO A CONSTANT * !* VALUE RETURNED IN VALUE. RESULT#0 IF FAILED TO EVALUATE * !* IN THIS CASE RESULT IS IN ETOS. USED FOR BOUND CALCULATIONS * !* P POINTS TO P(+') IN (+')(OPERNAD)(RESTOFEXPR) * !*********************************************************************** INTEGER EXPHEAD,EXPBOT,NOPS,CODE,SPTYPE,SACC EXPHEAD=0; EXPBOT=0; NOPS=0; CODE=0 SPTYPE=PTYPE; SACC=ACC; ! CALLED IN DECLARATIONS TORP(EXPHEAD,EXPBOT,NOPS) EXPOP(EXPHEAD,EXPBOT,NOPS,X'200'+PRECTYPE) CODE=1 UNLESS EXPOPND_FLAG<=1 AND EXPOPND_PTYPE=PRECTYPE VALUE=EXPOPND_D ACC=SACC; PTYPE=SPTYPE UNPACK RESULT =CODE END ROUTINE TORP(INTEGERNAME HEAD,BOT,NOPS) !*********************************************************************** !* CONVERT THE SIGNED EXPRESSION INDEXED BY P INTO REVERSE * !* POLISH NOTATION. THE REVERSE POLISH LIST IS ADDED TO 'HEAD' * !* WHICH MAY CONTAIN ANOTHER EXPRESSION. THE NUMBER OF OPERATORS * !* IS ADDED TO NOPS. * !* N.B. AN INTEGER EXPRESSION IS A SPECIAL CASE OF A REAL EXPRSN * !* THE TOP 20 BITS OF NOPS ARE USED TO RETURN DETAILS OF THE EXPR * !* THESE BITS SIGNIFY AS FOLLOWS:- * !* 1<<17 CONTAINS VARIABLE OF MORE THAN 32 BITS * !* 1<<18 NOT CONSTANT EXPRSSN IE CONTAINS AT LEAST 1 VARIABLE * !* 1<<19 COMPLEX IE CONTAINS FN CALL OR NEEDS DR TO EVALUATE * !*********************************************************************** SWITCH OPERAND(1:3) CONSTBYTEINTEGERARRAY PRECEDENCE(0:20)=0,3,3,4,5,5,4,3,3,4,4,5,5,3,5,5, 0(3),3,5; CONSTBYTEINTEGERARRAY OPVAL(0:20)=0,ADD,SUB,ANDL,IEXP,REXP,MULT,NONEQ, ORL,INTDIV,REALDIV,RSHIFT,LSHIFT,ADD,IEXP,REXP,0(3),LNEG,NOTL; INTEGER RPHEAD,PASSHEAD,SAVEHEAD,REAL,REALOP,OPERATOR,OPPREC,OPND, C,D,E,BDISP,OPNAME,OPMASK,RPBOT,OPSTK,OPPSTK,PASSBOT RECORD (TAGF)NAME LCELL RECORD (RD)RPOP ! PASSHEAD=0; RPHEAD=0; SAVEHEAD=0 REAL=0; REALOP=0; BDISP=0 RPBOT=0; OPSTK=0; OPPSTK=0 ! C=A(P) IF 2<=C<=3 THEN START ; ! INITIAL '-' OR '¬' NOPS=NOPS+1 ! '-' =(11,3) '¬' =(10,5) OPSTK=C+17 OPPSTK=PRECEDENCE(OPSTK) OPMASK=1<<(19+C); ! - %OR !! FINISH ELSE OPMASK=0 NEXTOPND:OPND=A(P+1); P=P+2 RPOP=0 -> OPERAND(OPND); ! SWITCH ON OPERAND OPERAND(1): ! NAME OPNAME=A(P)<<8+A(P+1) LCELL==ASLIST(TAGS(OPNAME)) LCELL_UIOJ<-LCELL_UIOJ!X'8000'; ! SET USED BIT PTYPE=LCELL_PTYPE IF PTYPE=X'FFFF' THEN PTYPE=X'57';! NAME NOT SET TYPE=PTYPE&7; PREC=PTYPE>>4&15 IF PTYPE=SNPT THEN PTYPE=LCELL_ACC AND UNPACK IF PTYPE&X'FF00'=X'4000' AND A(P+2)=2=A(P+3) C AND 1<=TYPE<=2 THEN START ; ! CONST VAR RPOP_D=LCELL_S2; RPOP_XTRA=LCELL_S3 RPOP_FLAG=1; PTYPE=PTYPE&255 IF TYPE=1 AND PREC<=5 AND X'FFFF8000'<RPOP_D<=X'7FFF'C THEN RPOP_FLAG=0 AND PTYPE=MINAPT REAL=1 IF TYPE=2 P=P+2; ->SKNAM FINISH RPOP_XTRA=OPNAME RPOP_FLAG=ARNAME; RPOP_D=P; PTYPE=X'51' IF PTYPE=X'57' IF TYPE=5 THEN FAULT(76,0,OPNAME) AND RPOP_FLAG=0 AND C PTYPE=X'51' IF TYPE=3 THEN START D=P; KFORM=LCELL_KFORM C=COPY RECORD TAG(E); P=D; FINISH ELSE START ! %IF PTYPE&X'300'#0 %START;! ARRAYS ! COPY TAG(OPNAME) ! RPOP_PTYPE=PTYPE ! RPOP_FLAG=DNAME ! BINSERT(RPHEAD,RPBOT,RPOP_S1,OPNAME,RPOP_XTRA) ! AATORP(NOPS,RPHEAD,RPBOT,ARR,I,K) ! P=RPOP_D; RPOP_FLAG=IFETCH ! RPOP_XTRA=0; RPOP_D=0 ! %FINISH FINISH IF PREC>=6 THEN OPMASK=OPMASK!1<<17;! MORE THAN 32 BITS IF TYPE=2 THEN REAL=1 P=P+2 SKNAM: IF A(P)=2 THEN P=P+1 ELSE SKIP APP IF A(P)=1 THEN P=P+3 AND ->SKNAM P=P+2 INS: IF RPOP_FLAG=ARNAME THEN OPMASK=OPMASK!1<<18 IF PTYPE>>4&15>5 THEN OPMASK=OPMASK!1<<17;! CONTINS LONG IF 3<=PTYPE&7<=7 THEN PTYPE=MINAPT;! NOT SET TO MIN INTEGER RPOP_PTYPE=PTYPE BINSERT(RPHEAD,RPBOT,RPOP_S1,RPOP_D,RPOP_XTRA) -> OP OPERAND(2): ! CONSTANT PTYPE=A(P); D=PTYPE>>4 IF D>=6 THEN OPMASK=OPMASK!1<<17;! MORE THAN 32 BIT OPERAND C=PTYPE&7 IF D=4 THEN START RPOP_D=FROM AR2(P+1) PTYPE=X'51' FINISH ELSE RPOP_D=FROM AR4(P+1) REAL=1 IF C=2; RPOP_FLAG=1 IF D=6 THEN RPOP_XTRA=FROM AR4(P+5) IF C=5 THEN START ; ! STRING CONSTANT FAULT(77,0,0); RPOP_D=1; RPOP_FLAG=0 P=P+A(P+1)+3; PTYPE=X'51' FINISH ELSE START IF D=7 THEN RPOP_XTRA=RPOP_D AND RPOP_D=P+1 IF PTYPE=X'51' AND X'FFFF8000'<=RPOP_D<=X'7FFF' THEN C RPOP_FLAG=0 AND PTYPE=MINAPT P=P+2+BYTES(D) FINISH ; -> INS OPERAND(3): ! SUB EXPRESSION PASSHEAD=0; PASSBOT=0 P=P+3 TORP(PASSHEAD,PASSBOT,NOPS) REAL=1 IF TYPE=2 ! CONCAT(RPHEAD,PASSHEAD) IF RPBOT=0 THEN RPHEAD=PASSHEAD ELSE C ASLIST(RPBOT)_LINK=PASSHEAD RPBOT=PASSBOT P=P+1 OP: ! DEAL WITH OPERATOR RPOP=0 -> EOE IF A(P-1)=2; ! EXPR FINISHED OPERATOR=A(P) ! ! THE STRING OPERATOR '.' CAUSES CHAOS IN AN ARITHMETIC EXPRSN ! SO FAULT IT AND CHANGE IT TO THE INNOCUOUS '+' ! IF OPERATOR=CONCOP THEN FAULT(78,0,0) OPPREC=PRECEDENCE(OPERATOR) C=OPVAL(OPERATOR) IF C=REALDIV OR C=REXP THEN REAL=1 NOPS=NOPS+1 ! ! UNLOAD THE OPERATOR STACK OF ALL OPERATORS WHOSE PRECEDENCE IS ! NOT LOWER THAN THE CURRENT OPERATOR. AN EMPTY STACK GIVES'-1' ! AS PRECEDENCE. ! WHILE OPPREC<=OPPSTK&31 CYCLE RPOP_FLAG=OPVAL(OPSTK&31) BINSERT(RPHEAD,RPBOT,RPOP_S1,0,0) OPSTK=OPSTK>>5; OPPSTK=OPPSTK>>5 REPEAT ! ! THE CURRENT OPERATOR CAN NOW BE STORED ! OPSTK=OPSTK<<5!OPERATOR OPPSTK=OPPSTK<<5!OPPREC -> NEXTOPND EOE: ! END OF EXPRESSION ! EMPTY REMAINING OPERATORS WHILE OPSTK#0 CYCLE RPOP_FLAG=OPVAL(OPSTK&31) BINSERT(RPHEAD,RPBOT,RPOP_S1,0,0) OPSTK=OPSTK>>5 REPEAT PTYPE=REAL+1 TYPE=PTYPE ! CONCAT(RPHEAD,HEAD) IF HEAD=0 THEN BOT=RPBOT ELSE C ASLIST(RPBOT)_LINK=HEAD HEAD=RPHEAD; ! HEAD BACK TO TOP OF LIST NOPS=NOPS!OPMASK END ROUTINE EXPOP(INTEGERNAME HEAD,BOT,INTEGER NOPS,MODE) !*********************************************************************** !* EVALUATE A LIST OF OPERAND AND'NOPS' OPERATORS AND LEAVE * !* THE RESULT IN REG * !* INHEAD HOLDS THE LIST THE BOTTOM BYTE OF STREAM 1 DEFINES THE * !* ENTRY AS FOLLOWS:- * !* 0 = SHORT (INTEGER) CONSTANT <18 BITS --S2=CONSTANT * !* 1 = OTHER CONSTANT S2 (+S3 IF NEEDED) = CONSTANT * !* 2 = VARIABLE S2 POINT TO AR ENTRY FOR NAME&SUBSCRIPTS * !* (3 = DOPE VECTOR ITEM IF NEEDED) * !* (4 = CONDITONAL EXPRESSION AS IN ALGOL) * !* 7 = INTERMEDIATE RESULT UNDER LNB S2=DISPLCMNT FROM LNB * !* 8 = INTERMEDIATE RESULT STACKED * !* 9 = INTERMEDIATE RESULT IN A REGISTER S2 = REG * !* * !* 10-19 = UNARY OPERATOR S2=OP S3 =EXTRA * !* 20 UP = BINARY OPERATOR * !* * !* MODE HAS TYPE & PREC REQD +256 BIT IF NO RESULT REQD * !*********************************************************************** ROUTINESPEC PSEVAL ! INTEGERARRAY OPERAND(0:2),STK(0:99) RECORD (LISTF)NAME LIST RECORD (RD)NAME OPND1,OPND2,OPND RECORD (TRIPF)NAME CURRT ! INTEGER C,D,KK,JJ,COMM,XTRA,INHEAD,NDEPTH,CURR TRIP, C STPTR,CONSTFORM,CONDFORM,SAVEP,INITTRIP ! ! CORULES GIVE INFORMATION ON OPERATORS. ! BTM 4 BITS HAVE TYPE CONVERSION RULES(SEE COERCET) ! NEXT 4 BITS HAVE PREC RULES (SEE COERCEP) ! 2**8 SET IF COMMUTATIVE ! 2**9 SET DONT LOAD OPERAND2 ! 2**10 SET DONT LOAD OPERAND1 ! CONSTHALFINTEGERARRAY CORULES(0:20)= C X'1FF'{+},X'FF'{-}, X'1F1'{!!},X'1F1'{!}, X'1FF'{*},X'F1'{//}, X'F2'{/},X'1F1'{&},X'71'{>>}, X'71'{<<},X'243'{**}, X'1FF'{COMP},X'FF'{DCOMP}, X'200'{VMY},X'1F1'{COMB}, X'214'{ASSIGN=}, X'254'{ASSIGN<-},X'241'{****}, X'201'{ARR SCALE}, X'001'{ARR INDEX}, X'500'{INDEXED FETCH}; CONSTINTEGERARRAY PTYPECH(0:19)=0(12),X'11',0,-X'10',X'10',-X'10',0(3); ! STPTR=0; NDEPTH=0; CONSTFORM= MODE&512 INITTRIP=NEXTTRIP CONDFORM=MODE&256 SAVEP=P INHEAD=HEAD PSEVAL NEXT: LIST==ASLIST(INHEAD) XTRA=LIST_S2 JJ=LIST_FLAG; D=INHEAD INHEAD=LIST_LINK -> OPERATOR IF JJ>=10 ! ! ANY OPERAND WHICH MAY NEED DR OR B OR ACC IN THEIR EVALUATION ! EG FUNCTIONS,ARRAY ELEMENTS ETC ARE FETCHED AND STACKKED FIRST ! OPND1==ASLIST(D) STK(STPTR)=D STPTR=STPTR+1 IMPABORT IF STPTR>99 ANYMORE: ->NEXT UNLESS INHEAD=0 OPND1==ASLIST(STK(STPTR-1)) EXPOPND=OPND1 ->FINISH OPERATOR: IF JJ<128 THEN KK=1 ELSE KK=2; ! UNARY OR BINARY CYCLE KK=KK,-1,1 STPTR=STPTR-1 OPERAND(KK)=STK(STPTR) REPEAT COMM=1 OPND1 == ASLIST(OPERAND(1)) IF JJ>=128 THEN START OPND2==ASLIST(OPERAND(2)) FINISH ELSE OPND2==RECORD(0) IF JJ=32 THEN COMM=2; ! DSIDED RESULT=2ND OPERAND ! ALL OTHERS RESULT=1ST OPERAND IF OPND1_FLAG<2 AND (JJ<128 OR OPND2_FLAG<2) THEN C CTOP(JJ,MASK,XTRA,OPND1,OPND2) IF JJ#0 THEN START ; ! CODE REQUIRED OP TRIPLE IF JJ<128 THEN C=0 ELSE C=CORULES(JJ-128) IF JJ=VASS OR JJ=VJASS THEN KK=1 ELSE KK=2;! CNAME FETCH-STORE IF OPND1_FLAG=ARNAME AND C (LHSADDRFIRST=YES OR KK=2) START ! EXPAND UP NAMES BUT NOT LHS ! ASSIGNMENT NAMES P=OPND1_D; CNAME(KK) OPND1=NAMEOPND FINISH IF JJ>=128 AND OPND2_FLAG=ARNAME THEN START P=OPND2_D CNAME(2) OPND2=NAMEOPND FINISH IF OPND1_FLAG=ARNAME THEN START P=OPND1_D CNAME(KK) OPND1=NAMEOPND FINISH CURR TRIP=NEW TRIP CURRT==TRIPLES(CURR TRIP) CURRT_DPTH=NDEPTH CURRT_CNT=0 CURRT_FLAGS=1!(C>>1&128) CURRT_OPERN=JJ CURRT_OPTYPE<-OPND1_PTYPE IF OPND1_PTYPE&7=1 AND OPND1_PTYPE&255<MINAPT THEN C CURRT_OPTYPE=MINAPT IF JJ<128 START ; ! UNARY(TYPECHANGE)OPN CURRT_OPTYPE=CURRT_OPTYPE+PTYPECH(JJ) FINISH ! %IF JJ=COMP %OR JJ=DCOMP %THEN MASK=FCOMP(LIST_S2) ! PREVENT OPTIMISING BYTE ARRAY SCALE ! AS THESE CREATE EXTRA WORD ! WHICH DEFEATS ALGORITHMS IF JJ=39 AND LIST_S2>>20=1 THEN C CURRT_FLAGS<-CURRT_FLAGS! DONT OPT CURRT_X1=LIST_S2 CURRT_OPND1=OPND1 IF 1<<OPND1_FLAG&BTREFMASK#0 THEN KEEP USE COUNT(OPND1) IF JJ>=128 THEN START CURRT_OPND2=OPND2 IF 1<<OPND2_FLAG&BTREFMASK#0 THEN KEEP USE COUNT(OPND2) FINISH OPND1_FLAG=8 OPND1_PTYPE=CURRT_OPTYPE OPND1_D=CURR TRIP ! NDEPTH=NDEPTH+WORDS(CURRT_OPTYPE>>4) FINISH STK(STPTR)=OPERAND(COMM) STPTR=STPTR+1 ->ANYMORE FINISH: IF EXPOPND_FLAG=ARNAME THEN START P=EXPOPND_D CNAME(2) EXPOPND=NAMEOPND FINISH PTYPE=EXPOPND_PTYPE TYPE=PTYPE&7; PREC=PTYPE>>4 P=SAVEP ASLIST(BOT)_LINK=ASL ASL=HEAD HEAD=0; BOT=0 RETURN ROUTINE PSEVAL !*********************************************************************** !* PERFORMS A PSEUDO EVALUATION ON THE EXPRESSION TO DETERMINE * !* THE POSITION OF ANY TYPE CHANGES AND THEN INSERTS * !* THESE UNARY OPERATIONS * !*********************************************************************** ROUTINESPEC AMEND(RECORD (RD)NAME OPND,INTEGER OP) ROUTINESPEC COERCET(INTEGER RULES) ROUTINESPEC COERCEP(INTEGER RULES) INTEGER TMPHEAD,INHEAD,C,JJ,NEXT RECORD (RD)NAME OPND1 RECORD (RD)OPND2,RPOP RECORD (LISTF)NAME CELL PRINT LIST(HEAD) AND IMPABORT UNLESS ASLIST(BOT)_LINK=0 RPOP=0 TMPHEAD=0 INHEAD=HEAD ! WHILE INHEAD#0 CYCLE CELL==ASLIST(INHEAD) NEXT=CELL_LINK RPOP<-CELL; ! COPY BEFOR ADJUSTING PTYPE JJ=RPOP_FLAG; ! FLAG IF JJ<10 START ; ! AN OPERAND ! %IF RPOP_PTYPE>>4&15<MINAPREC %THEN %C RPOP_PTYPE=RPOP_PTYPE&X'FF0F'!(MINAPREC<<4) PUSH(TMPHEAD,RPOP_S1,RPOP_D,INHEAD) FINISH ELSE START ; ! AN OPERATOR IF JJ>=128 START ; ! BINARY OPERATOR POP(TMPHEAD,OPND2_S1,OPND2_D,OPND2_XTRA) OPND1==ASLIST(TMPHEAD); ! MAPPING SAVES POP&PUSH C=CORULES(JJ-128) IF C&15#0 THEN COERCET(C&15) IF C>>4&15#0 THEN COERCEP(C>>4&15) FINISH ELSE OPND1==ASLIST(TMPHEAD) OPND1_XTRA=INHEAD; ! IN CASE(FURTHER)TYPE CHANGE FINISH INHEAD=NEXT REPEAT ! ! FINAL COERCION ON RESULT ! POP(TMPHEAD,OPND2_S1,OPND2_D,OPND2_XTRA) PRINT LIST(HEAD) AND IMPABORT UNLESS TMPHEAD=0 IF CONDFORM=0 START IF MODE&7=1 AND OPND2_PTYPE&7=2 THEN FAULT(25,0,0) IF OPND2_PTYPE&7=1 AND MODE&7=2 THEN AMEND(OPND2,IFLOAT) C=MODE>>4&15; ! TARGET PREC AMEND(OPND2,SHRTN) WHILE C<OPND2_PTYPE>>4&15 AMEND(OPND2,LNGTHN) WHILE C>OPND2_PTYPE>>4&15 FINISH PRINTLIST(HEAD) IF PARM_DCOMP#0 AND PARM_Z#0 BOT=ASLIST(BOT)_LINK WHILE ASLIST(BOT)_LINK#0 RETURN ROUTINE AMEND(RECORD (RD)NAME OPND,INTEGER OP) !*********************************************************************** !* ADDS IN AN OPERATION TO CHANGE THE TYPE OR PREC OF OPND * !*********************************************************************** RECORD (RD) RPOP IF OP=LNGTHN AND OPND_PTYPE&255<MINAPT THEN C OPND_PTYPE=OPND_PTYPE&X'FF00'!MINAPT AND RETURN RPOP=0 RPOP_FLAG=OP INSERT AFTER(OPND_XTRA,RPOP_S1,0,0) NOPS=NOPS+1 IF OP=IFLOAT AND OPND_PTYPE&255<MINAPT THEN C OPND_PTYPE=MINAPT OPND_PTYPE=OPND_PTYPE+PTYPECH(OP) END ROUTINE COERCET(INTEGER RULES) !*********************************************************************** !* RULES=1 BOTH OPERANDS INTEGER ELSE ERROR * !* RULES=2 FORCE BOTH OPERAND TO BE OF TYPE REAL * !* RULES=3 OPND1 ONLY TO BE REAL(FOR **) * !* RULES=4 OPND2 TO BE OPND 1(ASSIGNMENT) * !* RULES=15 BOTH OPERANDS TO BE OF LARGEST TYPE * !*********************************************************************** INTEGER PT1,PT2 RECORD (RD)RPOP RPOP=0; RPOP_FLAG=12; ! FLOAT PT1=OPND1_PTYPE&7 PT2=OPND2_PTYPE&7 IF RULES=4 THEN PT1=CELL_S2&7; ! ORIGINAL PT FOR ARRAYS ETC IF (RULES=1 OR RULES=15 OR RULES=4) AND PT1=1=PT2 C THEN RETURN IF RULES=1 OR (RULES=4 AND PT1=1) C THEN FAULT(24,0,0) AND RETURN IF PT1=1 THEN AMEND(OPND1,IFLOAT) IF PT2=1 AND (RULES=2 OR RULES=4 OR RULES=15) THEN C AMEND(OPND2,IFLOAT) END ROUTINE COERCEP(INTEGER RULES) !*********************************************************************** !* RULES DEFINE COERCION AS FOLLOWS: * !* RULES=1 FORCE OPND2 TO BE OPND1(ASSIGNMENT) * !* RULES=2 OPERAND 1 TO BE 'STANDARD' INTEGER * !* RULES=4 OPERAND 2 TO BE 'STANDARD' INTEGER * !* RULES=5 AS RULES=1 BUT FOR <- ASSIGNMENT * !* RULES=6 BOTH OPERANDS TO BE 'STANDARD' INTEGER * !* RULES=7 OPND1>=32BITS, OPND2 TO BE 'STANDARD' * !* RULES=15 BOTH OPERANDS TO THE LARGEST PRECISION * !*********************************************************************** INTEGER PREC1,PREC2,TPREC,OPER RECORD (RD)NAME OPND RECORD (RD)RPOP RPOP=0 IF RULES=6 THEN COERCEP(4) AND RULES=2 PREC1=OPND1_PTYPE>>4&15 PREC2=OPND2_PTYPE>>4&15 IF RULES=5 OR RULES=1 START ; ! ASSIGN PREC1=CELL_S2>>4&15; ! ORIGINAL PREC FOR ARRAY ASSIGN IF PREC2>PREC1 START CYCLE IF RULES=1 THEN OPER=SHRTN ELSE OPER=JAMSHRTN AMEND(OPND2,OPER) PREC2=PREC2-1 REPEAT UNTIL PREC1=PREC2 RETURN FINISH ELSE RULES=1; ! IN CASE LENGTHEN NEEDED FINISH ! %IF PREC1<MINAPREC %THEN PREC1=MINAPREC %AND %C OPND1_PTYPE=OPND1_PTYPE&X'FF0F'!(MINAPREC<<4) ! %IF PREC2<MINAPREC %THEN PREC2=MINAPREC %AND %C OPND2_PTYPE=OPND2_PTYPE&X'FF0F'!(MINAPREC<<4) IF RULES=7 START ; ! FORCE SHIFT INTO 32 BIT MIN REG RULES=4 IF PREC1=4 THEN AMEND(OPND1,LNGTHN) AND PREC1=5 FINISH IF 2<=RULES<=4 START IF RULES<=2 THEN OPND==OPND1 ELSE OPND==OPND2 IF OPND_PTYPE&X'FF'>MINAPT THEN AMEND(OPND,SHRTN) RETURN FINISH IF PREC1<PREC2 THEN TPREC=PREC2 AND OPND==OPND1 ELSE C TPREC=PREC1 AND OPND==OPND2 OPER=OPND_PTYPE AMEND(OPND,LNGTHN) WHILE OPND_PTYPE>>4&15<TPREC END END END ; ! OF ROUTINE EXPOP INTEGERFN CCOND(INTEGER CTO,IU,FARLAB,JFLAGS) !*********************************************************************** !* COMPILES <IU><SC><RESTOFCOND>%THEN<UI1>%ELSE<UI2> * !* CTO=0 JUMP TO FARLAB MUST BE PLANTED IF COND UNCONDITIONAL * !* CTO#0 JUMP MAY BE OMITTED * !* IU=1 FOR %IF =2 FOR UNLESS. FARLAB TO GO ON UI2 * !* THE ROUTINE MAKES FOUR PASSES THROUGH THE CONDITION * !* PASS 1 ANALYSES THE STRUCTURE AND DECIDES TO BRANCH ON TRUE * !* (TF=2) OR ON FALSE (TF=1) FOR EACH COMPARISON * !* PASS 2 WORKS OUT WHERE THE BRANCHES OF PASS 1 SHOULD GO TO * !* PASS 3 ASSIGNS LABEL NUMBERS * !* PASS 4 EVALUATES COMPARISIONS AND PLANTS THE CODE * !* * !* ON ENTRY P POINTS TO <SC> IN<HOLE><SC><RESTOFCOND> * !* RESULT=0 CONDITION COMPILED * !* RESULT=1 UNCONDITIONALLY TO 1ST ALTERNATIVE * !* RESULT=2 UNCONDITIONALLY TO 2ND ALTERNATIVE(FARLAB) * !*********************************************************************** !%ROUTINESPEC WRITE CONDLIST ROUTINESPEC SKIP SC(INTEGER REVERSED) ROUTINESPEC SKIP COND(INTEGER REVERSED) INTEGERFNSPEC CCOMP ROUTINESPEC JUMP(INTEGER MASK,LAB,FLAGS) ROUTINESPEC NOTE JUMP(INTEGER LAB) ROUTINESPEC LAB UNUSED(INTEGER LAB) ROUTINESPEC OMIT TO(INTEGER LAB) ! ! FCOMP HAS BC MASKS FOR EACH STRING COMPARATOR. ! THE FIRST 7 ARE TO BRANCH IF TRUE WITH NORMAL COMPARISON ! THE SECOND SEVEN ARE TO BRANCH IF TRUE WITH BACKWARDS COMPARISON ! ! INTEGER PIN,PP,II,L,CPTR,CMAX,LL,BITMASK,LLA RECORDFORMAT CF(BYTEINTEGER TF,CMP1,CMP2,LABU,LVL,JMP,REV,JUMPED, C INTEGER LABNO,SP1,SP2) RECORD (CF)ARRAY CLIST(0:30) RECORD (CF)NAME C1,C2 ! ! PASS 1. ANALYSES THE CONDITION ! PIN=P; ! SAVE INITIAL AR POINTER CPTR=1; L=3; ! LEVEL=3 TO ALLOW 2 LOWER C1==CLIST(CPTR); ! SET UP RECORD FOR FIRST CMPARSN C1=0 SKIP SC(0); ! SKIP THE 1ST CMPARSN SKIP COND(0); ! AND ANY %AND/%OR CLAUSES C1_LVL=2; ! LEVEL =-1 FOR %IF/%THEN ENTRY C1_TF=IU CMAX=CPTR+1 C1==CLIST(CMAX); C1=0 C1_LVL=1; ! LEVEL =-2 FOR ELSE ENTRY C1_TF=3-IU; ! C1_REV NEVER SET HERE (PDS HOPES) C1_LABNO=FARLAB PP=P; ! SAVE FINAL AR POINTER FAULT(108,0,0) IF CMAX>29; ! TOO COMPLICATED ! ! PASS 2 WORKS OUT WHERE TO JUMP TO ! THE JUMP IS FORWARD TO THE START OF THE CLAUSE WITH A DIFFERENT ! CONNECTOR (AND/OR) PROVIDED THIS IS AT A LOWER LEVEL THAN THE BRANCH ! AND ALSO AT A LOWER LEVEL THAN THE LOWEST POINT REACHED ENROUTE ! ! ALSO CONTAINS PASS 3 (TRIVIAL) ! ASSIGN LABELS WHERE LABU SHOWS THEY ARE REQUIRED ! CYCLE CPTR=1,1,CMAX-1 C1==CLIST(CPTR) L=C1_LVL; LL=L; ! LL FOR LOWEST LEVEL ENROUTE CYCLE II=CPTR+1,1,CMAX+1 C2==CLIST(II) EXIT IF C1_TF#C2_TF AND C2_LVL<LL IF C2_LVL<LL THEN LL=C2_LVL REPEAT C1_JMP=II; ! CLAUSE TO JUMP TO C2_LABU=C2_LABU+1 IF C1_CMP2#0 OR C1_CMP1=8 START ; ! D-SIDED OR RESLN ! REQIUIRES A LABEL ON THE C1_LABU=C1_LABU+1; ! THE NEXT SIMPLE CONDITION FINISH IF C1_LABU#0 AND C1_LABNO<=0 THEN PLABEL=PLABEL-1 C AND C1_LABNO=PLABEL REPEAT ! ! PASS 4 GENERATE THE CODE ! MAINTAIN BIT MASK TO HELP. 2**0 JUMP TO FAR LAB PLANTED ! 2**1 JUMP TO INTERMEDIATE LAB PLANTED ! ! WRITE CONDLIST %IF PARM_DCOMP=1 BITMASK=0 CPTR=1 CYCLE C1==CLIST(CPTR) LLA=CCOMP IF LLA#0 START OMIT TO(LLA) IF CPTR>=CMAX THEN START IF CTO=0 THEN ENTER JUMP(15,LLA,B'11') RESULT =2 FINISH C1==CLIST(CPTR) FINISH IF C1_LABNO>0 THEN II=ENTER LAB(C1_LABNO,B'11') CPTR=CPTR+1 EXIT IF CPTR>=CMAX REPEAT ! P=PP; RESULT =1 IF BITMASK&1=0 RESULT =0 ROUTINE LAB UNUSED(INTEGER LAB) !*********************************************************************** !* A LABEL IS NOT JUMPED TO AS CONDITION ALWAYS FALSE * !* REMOVE IT FROM LIST * !*********************************************************************** INTEGER I RECORD (CF)NAME C1 CYCLE I=CPTR,1,CMAX-1 C1==CLIST(I) IF C1_LABNO=LAB START C1_LABU=C1_LABU-1; ! COUNT DOWN USE COUNT IF C1_LABU=0 THEN C1_LABNO=0 RETURN FINISH REPEAT END ROUTINE OMIT TO(INTEGER LAB) !*********************************************************************** !* A JUMP TURNS OUT TO BE UNCONDITIONAL. OMIT CODE FOR SKIPPED BIT * !*********************************************************************** RECORD (CF)NAME C1 CYCLE C1==CLIST(CPTR) IF C1_LABNO>0 START IF C1_LABNO=LAB THEN RETURN IF C1_JUMPED>0 THEN JUMP(15,LAB,B'11') AND RETURN FINISH CPTR=CPTR+1 EXIT IF CPTR>=CMAX REPEAT END ROUTINE SKIP SC(INTEGER REVERSED) !*********************************************************************** !* REVERSED=1 FOR RECURSIVE CALL IN %NOT(SC) * !* SKIPS OVER A SIMPLE CONDITION. P ON ALT OF<SC> * !*********************************************************************** SWITCH SCALT(1:3) INTEGER ALT ALT=A(P); P=P+1 ->SCALT(ALT) SCALT(1): ! <EXP><COMP><EXP><SECONDSIDE> C1_SP1=P-PIN SKIP EXP C1_CMP1=A(P) C1_REV=3*REVERSED P=P+1; C1_SP2=P-PIN SKIP EXP IF A(P)=2 THEN P=P+1 ELSE START C1_CMP2=A(P+1); ! DEAL WITH 2ND HALF OF D-SIDED P=P+2; SKIP EXP FINISH RETURN SCALT(2): ! '('<SC><RESTOFCOND>')' L=L+1 SKIP SC(REVERSED) SKIP COND(REVERSED) L=L-1 RETURN SCALT(3): ! %NOT(SC) SKIP SC(REVERSED!!1) END ; ! OF ROUTINE SKIP SC ROUTINE SKIP COND(INTEGER REVERSED) !*********************************************************************** !* SKIPS OVER <RESTOFCOND> * !*********************************************************************** INTEGER ALT,ALTP ALT=A(P); ! 1=%AND<ANDC>,2=%OR<ORC>,3=NULL P=P+1 IF ALT¬=3 THEN START ; ! NULL ALTERNATIVE NOTHING TO DO UNTIL ALTP=2 CYCLE ; ! UNTIL NO MORE <SC>S C1_LVL=L; C1_TF=ALT C1_TF=C1_TF!!(3*REVERSED) CPTR=CPTR+1 C1==CLIST(CPTR); C1=0 SKIP SC(REVERSED) ALTP=A(P); P=P+1 REPEAT FINISH END !%ROUTINE WRITE CONDLIST !%CONSTSTRING(5) %ARRAY CM(0:10)=" "," ="," >="," >", ! " #"," <="," <"," ¬="," ->", ! " =="," ¬==" ! PRINTSTRING(" ! NO TF C1 C2 LABU LVL JMP REV LABNO JUMPED !") ! %CYCLE CPTR=1,1,CMAX ! C1==CLIST(CPTR) ! WRITE(CPTR,2) ! WRITE(C1_TF,4) ! PRINTSTRING(CM(C1_CMP1)) ! PRINTSTRING(CM(C1_CMP2)) ! WRITE(C1_LABU,6) ! WRITE(C1_LVL,5) ! WRITE(C1_JMP,4) ! WRITE(C1_REV,4) ! WRITE(C1_LABNO,7) ! WRITE(C1_JUMPED,6) ! NEWLINE ! %REPEAT !%END INTEGERFN CCOMP !*********************************************************************** !* COMPILES A COMPARISION: THREE DIFFERENT CASES * !* 1) ARITHMETIC EXPRESSIONS EXPOP IS USED * !* 2) STRING EXPRESSION AD-HOC CODE PLANTED BY THIS ROUTINE * !* 3) RESOLUTIONS - CRES CAN BE USED * !* 4) EQUIVALENCES INTEGER COMPARISONS ON ADDRESSES * !* RESULT=0 CODE COMPILED * !* RESULT#0 UNCODITIONAL JUMP TO LAB=RESULT * !*********************************************************************** ROUTINESPEC ACOMP(INTEGER TF,DS) ROUTINESPEC ADCOMP(INTEGER TF) ROUTINESPEC STRCOMP(INTEGER DS,TF,LAB,INTEGERNAME WA) INTEGER HEAD1,HEAD2,NOPS,TE2,TEX2,P1,P2,FEXIT,IEXIT, C CMP,BOT1,BOT2 INTEGERARRAY WA(0:3) ! HEAD1=0; HEAD2=0; NOPS=0 BOT1=0; BOT2=0 FEXIT=CLIST(C1_JMP)_LABNO; ! FINAL EXIT IEXIT=FEXIT; ! INTERMEDIATE EXIT (D-SIDED ETC) IF C1_REV!!C1_TF=2 AND (C1_CMP1=8 OR C1_CMP2#0) THEN C IEXIT=C1_LABNO ! P=PIN+C1_SP2 P2=P; P1=PIN+C1_SP1 IF C1_CMP1=8 THEN START ! CONDITIONAL RESOLUTION ! NB CRES BRANCHES ON FALSE!! P=P1 IF A(P+3)=4 AND A(P+4)=1 START P=P+5; CNAME(2); ! LH STRING TO ANY REG IF A(P)=2 THEN START IF TYPE#5 THEN FAULT(71,0,FROMAR2(P1+5)) C AND RESULT =0 P=P2 CRES(IEXIT); ! FAILURES -> IEXIT NOTE JUMP(IEXIT) IF IEXIT=FARLAB THEN BITMASK=BITMASK!1 ELSE C BITMASK=BITMASK!2 IF C1_REV!!C1_TF=2 THEN JUMP(15,FEXIT,B'11') RESULT =0 FINISH FINISH FAULT(74,0,0) RESULT =0 FINISH IF C1_CMP1>8 THEN ->ADRCOMP MASK=FCOMP(C1_CMP1) TE2=TSEXP(TEX2) ->STR IF TYPE=5 ! ARITHMETIC COMPARISIONS P=P1+3 TORP(HEAD1,BOT1,NOPS); ! FIRST EXPRESSION TO REVERSE POL CMP=C1_CMP1 P=P2+3 IF C1_CMP2#0 THEN START ; ! IF D-SIDED DEAL WITH MIDDLE ACOMP(1,1); ! BRANCH IEXIT %IF FALSE IF MASK=15 THEN RESULT =IEXIT JUMP(MASK,IEXIT,B'11') P=P+5; ! TO THE THIRD EXPRSN CMP=C1_CMP2; ! COMPARATOR NO 2 FINISH ! ACOMP(C1_REV!!C1_TF,0); ! SECOND OR ONLY COMPARISION IF MASK=15 THEN RESULT =FEXIT JUMP(MASK,FEXIT,B'11') RESULT =0 STR: ! STRING COMPARISIONS ! SOME CARE IS NEEDED IN FREEING ! STRING WK-AREAS SET BY CSTREXP P=P1 WA(1)=0; WA(2)=0; WA(3)=0 CSTREXP(48); ! DO NOT FREE WK-AREA WA(1)=VALUE; ! SAVE ADDRESS OF WK-AREA CMP=C1_CMP1 P=P2 ! IF C1_CMP2#0 THEN START ; ! D-SIDED DEAL WITH MIDDLE STRCOMP(1,1,IEXIT,WA(2)) P=P+2; CMP=C1_CMP2 IF WA(1)#0 THEN RETURN WSP(WA(1),268) AND WA(1)=0 FINISH ! STRCOMP(0,C1_REV!!C1_TF,FEXIT,WA(3)) CYCLE CMP=1,1,3 IF WA(CMP)#0 THEN RETURN WSP(WA(CMP),268) REPEAT RESULT =0 ADRCOMP: ! ADRESS COMPARISONS ADCOMP(C1_REV!!C1_TF) JUMP(MASK,FEXIT,B'11') RESULT =0 ROUTINE ADCOMP(INTEGER TF) !*********************************************************************** !* COMPILES AN == OR ADDRESS COMPARISON WHICH CAN NOT BE * !* DOUBLESIDED. BETTER CODE COULD BE GENERATED FOR THE * !* MOST COMMON CASE IE POINTERNAME==VARIABLE * !************************************************************************ INTEGER TYPEP,PRECP,LHNAME,RHNAME,FNAME,CMP RECORD (RD)OPND1 RECORD (TRIPF)NAME CURRT LHNAME=A(P1+5)<<8!A(P1+6) FNAME=RHNAME RHNAME=A(P2+5)<<8!A(P2+6) IF C1_CMP1=10 THEN CMP=7 ELSE CMP=1 MASK=FCOMP(CMP) P=P1+1 ->FLT UNLESS A(P1+3)=4 AND A(P1+4)=1 AND A(P+FROMAR2(P))=2 P=P1+5; CNAME(4) TYPEP=TYPE; PRECP=PREC OPND1=NAMEOPND OPND1_PTYPE=X'51' ! FNAME=LHNAME P=P2+1 ->FLT UNLESS A(P2+3)=4 AND A(P2+4)=1 AND A(P+FROMAR2(P))=2 P=P2+5; CNAME(4) FAULT(83,LHNAME,RHNAME) UNLESS TYPEP=TYPE AND PRECP=PREC CURRT==TRIPLES(BRECTRIP(COMP,X'51',0,OPND1,NAMEOPND)) CURRT_X1=MASK IF TF=1 THEN MASK=REVERSE(MASK) RETURN FLT: FAULT(80,0,FNAME) MASK=7 END ROUTINE ACOMP(INTEGER TF,DS) !*********************************************************************** !* TYPE & PREC DEFINE THE EXPRSN IN REVERSE POLISH IN HEAD1 * !* THIS ROUTINE CONVERTS THE NEXT EXPRSN TO REVERSE POLISH AND * !* ADDS OPERATORS FOR TYPE CHANGING(IF REQ) CMPRSN AND JUMP * !*********************************************************************** INTEGER PRECP,TYPEP PRECP=PTYPE>>4&15; TYPEP=TYPE MASK=FCOMP(CMP) ! ! ADD OPERATOR AT BOTTOM. EITHER COMPARE(COMP) OR DS COMPARE(DCOMP) ! PUSH(HEAD2,(COMP+DS)<<FLAGSHIFT,MASK,0) BOT2=HEAD2 NOPS=NOPS+1; ! FLAG COMPARE ! ! CONVERT NEXT EXPRSN TO REVERSE POLISH AND TO THE SAME TYPE AS THE ! FIRST IF POSSIBLE. MODE=0 INTEGER IF POSSIBLE,=2 REAL, =3 LONGREAL ! TORP(HEAD2,BOT2,NOPS) IF TYPEP>TYPE THEN TYPE=TYPEP ! CONCAT(HEAD1,HEAD2) ASLIST(BOT1)_LINK=HEAD2 BOT1=BOT2; BOT2=0; HEAD2=0 EXPOP(HEAD1,BOT1,NOPS,256+16*PRECP+TYPE); ! PLANT THE CODE IF DS#0 START PUSH(HEAD1,EXPOPND_S1,EXPOPND_D,EXPOPND_XTRA) BOT1=HEAD1 FINISH IF TF=1 THEN MASK=REVERSE(MASK) END ROUTINE STRCOMP(INTEGER DS,TF,LAB,INTEGERNAME WA) !*********************************************************************** !* 1ST STRING IS DEFINED BY (ACCR) * !* THIS ROUTINE EVALUATES THE NEXT STRING EXPRS AND PERFORMS * !* THE COMPARISON & BRANCH. * !* DS=0 UNLESS THIS COMPARISON IS THE FIRST HALF OF A DBLE-SIDED * !*********************************************************************** INTEGER MASK,D RECORD (RD)OPND1 RECORD (TRIPF)NAME CURRT OPND1=EXPOPND CSTREXP(48); ! SAVE WK-AREA WA=VALUE MASK=FCOMP(CMP) CURRT==TRIPLES(BRECTRIP(SCOMP+DS,X'35',0,OPND1,EXPOPND)) CURRT_X1=MASK IF TF=1 THEN MASK=REVERSE(MASK); ! REVERSE MASK TO JMP IF FALS JUMP(MASK,LAB,B'11') END END ROUTINE JUMP(INTEGER MASK,LAB,FLAGS) !*********************************************************************** !* CALLS ENTER JUMP WHILE MAINTAINING BITMASK * !*********************************************************************** IF MASK=0 THEN LAB UNUSED(LAB) AND RETURN IF LAB=FARLAB THEN FLAGS=JFLAGS ENTER JUMP(MASK,LAB,FLAGS) NOTE JUMP(LAB) IF LAB=FARLAB THEN BITMASK=BITMASK!1 ELSE BITMASK=BITMASK!2 END ROUTINE NOTE JUMP(INTEGER LABEL) !*********************************************************************** !* RECORD LABEL JUMPED TO FOR SKIPPING COMPLEX CONDITIONS * !*********************************************************************** INTEGER I RECORD (CF)NAME C CYCLE I=1,1,CMAX C==CLIST(I) IF C_LABNO=LABEL THEN C_JUMPED=C_JUMPED+1 AND EXIT REPEAT END END ; ! OF CCOND INTEGERFN REVERSE(INTEGER MASK) !*********************************************************************** !* REVERSE THE MASK FOR A JCC(MASK<=15),JAT(>15) OR JAF(>31) * !*********************************************************************** IF MASK=0 OR MASK=15 THEN RESULT =MASK!!15 RESULT =MASK!!X'8F' END INTEGERFN ENTER LAB(INTEGER LAB,FLAGS) !*********************************************************************** !* ENTER A NEW LABEL ON THE LABEL LIST FOR THE CURRENT LEVEL * !* 2**0 OF FLAGS = 1 CONDITIONAL ENTRY * !* 2**1 OF FLAGS = 1 UPDATE ENVIRONMENT * !* 2**2 OF FLAGS = 1 REPLACE ENV =0 MERGE ENV * !* THE LABEL LIST * !* S1 = USE BITS<<8 ! LABEL ADDR * !* S2 = UNFILLED JUMPS LIST & ENVIRONMENT LIST * !* S3 = LAB NO - RESET TO FFFF WHEN USED FOR INTERNAL LABELS * !* RESULT = 1 LABEL ENTERED * !* RESULT = 0 CONDITIONAL LABEL NOT REQUIRED * !*********************************************************************** INTEGER CELL,OLDCELL,TRIPNO RECORD (LISTF)NAME LCELL CELL=CURRINF_LABEL; OLDCELL=0 WHILE CELL>0 CYCLE LCELL==ASLIST(CELL) EXIT IF LCELL_S3=LAB OLDCELL=CELL; CELL=LCELL_LINK REPEAT ! IF CELL<=0 THEN START ; ! LABEL NOT KNOWN IF FLAGS&1#0 THEN RESULT =0; ! CONDITIONAL ENTRY PUSH(CURRINF_LABEL,0,0,LAB) CELL=CURRINF_LABEL LCELL==ASLIST(CELL) FINISH ! ! LABEL HAS BEEN REFERENCED - FILL IN ITS ADDRESS ! IF LCELL_S1&LABSETBIT# 0 THEN START FAULT(2,0,LAB); ! LABEL SET TWICE FINISH ELSE START LCELL_S1=LCELL_S1!LABSETBIT; ! FLAG AS SET FINISH ! ! NOW FILL JUMPS TO THIS LABEL - JUMP LIST FORMAT GIVEN IN 'ENTER JMP' ! TRIPNO=ULCONSTTRIP(TLAB,X'61',DONT OPT,FLAGS<<24!LAB,CELL) IF FLAGS&1#0 AND LAB>MAXULAB THEN REMOVELAB(LAB) RESULT =1 END ROUTINE ENTER JUMP(INTEGER TFMASK,LAB,FLAGS) !*********************************************************************** !* IF LAB HAS BEEN ENCOUNTERED THEN PLANT A JCC OTHERWISE ENTER * !* THE LABEL IN THE LABEL LIST AND ATTACH THE JUMP TO IT SO IT * !* CAN BE PLANTED WHEN THE LABEL IS FOUND * !* THE LABEL LIST IS DESCRIBED UNDER 'ENTER LAB' * !* THE JUMP SUB-LIST HAS THE FORM * !* S1= ADDR OF JUMP * !* S2=SHORT OR LONG FLAG * !* S3=LINE NO OF JUMP FOR DIAGNOSTICS * !* * !* FLAGS BITS SIGNIFY AS FOLLOWS * !* 2**0 =1 JUMP IS KNOWN TO BE SHORT * !* 2**1 =1 ENVIRONMENT MERGEING REQUIRED * !* 2**8 =1 ASSEMBLER JUMP TFMASK =RELEVENT ASS INFO * !*********************************************************************** INTEGER CELL,I RECORD (TRIPF)NAME CURRT RECORD (LISTF)NAME LCELL IF LAB<MAX ULAB THEN FLAGS=0;! NO MERGE CELL=CURRINF_LABEL WHILE CELL>0 CYCLE LCELL==ASLIST(CELL) IF LAB=LCELL_S3 THEN EXIT CELL=LCELL_LINK REPEAT -> FIRSTREF IF CELL<=0 -> NOT YET SET IF LCELL_S1&LABSETBIT=0 LCELL_S1=LCELL_S1!X'1000000'; ! FLAG LABEL AS USED CURRT==TRIPLES(UCONSTTRIP(BJUMP,0,DONT OPT,FLAGS<<24!LAB)) CURRT_OPND1_XTRA=CELL; ! LAB CELL FOR BJUMPS CURRT_X1=TFMASK RETURN FIRSTREF: ! FIRST REFERENCE TO A NEW LABEL PUSH(CURRINF_LABEL,LABUSEDBIT,0,LAB) FLAGS=FLAGS!128; ! MARK FIRST USE FOR PASS3 CELL=CURRINF_LABEL LCELL==ASLIST(CELL) NOT YET SET: ! LABEL REFERENCED BEFORE CURRT==TRIPLES(UCONSTTRIP(FJUMP,0,DONT OPT,FLAGS<<24!LAB)) CURRT_X1=TFMASK; ! CONDITIONAL OR NOT ETC I=LCELL_S2&X'FFFF'; ! MAY BE ENVIRONMENT LIST ADDED PUSH(I,0,0,LINE) LCELL_S2=LCELL_S2&X'FFFF0000'!I CURRT_OPND1_XTRA=CELL<<16!LCELL_S2;! LABEL&JUMP CELL FOR FJUMPS END ROUTINE REMOVE LAB(INTEGER LAB) !*********************************************************************** !* REMOVES A ALBEL FROM THE CURRENT LABEL LIST WHEN KNOWN TO * !* BE REDUNDANT. MAINLY USED FOR CYCLE LABELS * !*********************************************************************** INTEGER T T=UCONSTTRIP(REMLB,X'51',DONT OPT,LAB) END INTEGERFN CREATE AH(INTEGER MODE,RECORD (RD)NAME EOPND,NOPND) !*********************************************************************** !* CREATES AN ARRAYHEAD IN THE ESTACK BY MODIFYING THE * !* HEAD ALREADY THERE AS FOLLOWS:- * !* MODE=0 (ARRAYMAPPING) ETOS-4&5 HAS 32BIT ADDR OF FIRST ELEMNT* !* MODE=1 (ARRAYS IN RECORDS)ETOS-4&5 HAS 32BIT RELOCATION FACTOR* !*********************************************************************** INTEGER JJ JJ=BRECTRIP(AHADJ,AHEADPT,0,EOPND,NOPND) TRIPLES(JJ)_X1=PTYPE<<4!MODE RESULT =JJ END ; ! OF ROUTINE CREATE AH ROUTINE CSNAME(INTEGER Z) !*********************************************************************** !* COMPILE A SPECIAL NAME - PTYPE=10006 (=%ROUTINE %LABEL) * !* THEIR TRUE PTYPE IS IN GLOBAL ARRAY TAGS_S2. * !* SNINFO HAS A FOUR BYTE RECORD FOR EACH NAME (%BI FLAG,PTR, * !* %SI XTRA). THE TOP BITS OF FLAG CATEGORISE AS FOLLOWS:- * !* 2**7 SET FOR IMPLICITLY SPECIFIED CONSTRUCT A %SPEC * !* 2**6 SET FOR IOCP CALL * !* 2**5 SET FOR BUILT IN MAPPING FUNCTIONS * !* 2**4 SET IF AD-HOC CODE PLANTED BY THIS ROUTINE * !* 2**3 SET IF FIRST PARAMETER IS OF %NAME TYPE * !* 2**2-2**0 HOLD NUMBER OF PARAMS * !* * !* THE FULL SPECS ARE AS FOLLOWS:- * !* 0=%ROUTINE SELECT INPUT(%INTEGER STREAM) * !* 1=%ROUTINE SELECT OUTPUT(%INTEGER STREAM) * !* 2=%ROUTINE NEWLINE * !* 3=%ROUTINE SPACE * !* 4=%ROUTINE SKIP SYMBOL * !* 5=%ROUTINE READ STRING(%STRINGNAME S) * !* 6=%ROUTINE NEWLINES(%INTEGER N) * !* 7=%ROUTINE SPACES(%INTEGER N) * !* 8=%INTEGERFN NEXT SYMBOL * !* 9=%ROUTINE PRINT SYMBOL(%INTEGER SYMBOL) * !* 10=%ROUTINE READ SYMBOL(%NAME SYMBOL) * !* 11=%ROUTINE READ(%NAME NUMBER) * !* 12=%ROUTINE WRITE(%INTEGER VALUE,PLACES) * !* 13=%ROUTINE NEWPAGE * !* 14=%INTEGERFN ADDR(%NAME VARIABLE) * !* 15=%LONGREALFN ARCSIN(%LONGREAL X) * !* 16=%INTEGERFN INT(%LONGREAL X) * !* 17=%INTEGERFN INTPT(%LONRGREAL X) * !* 18=%LONGREALFN FRACPT(%LONGREAL X) * !* 19=%ROUTINE PRINT(%LONGREAL NUMBER,%INTEGER BEFORE,AFTER) * !* 20=%ROUTINE PRINTFL(%LONGREAL NUMBER,%INTEGER PLACES) * !* 21=%REALMAP REAL(%INTEGER VAR ADDR) * !* 22=%INTEGERMAP INTEGER(%INTEGER VAR ADDR) * !* 23=%LONGREALFN MOD(%LONGREAL X) * !* 24=%LONGREALFN ARCCOS(%LONGREAL X) * !* 25=%LONGREALFN SQRT(%LONGREAL X) * !* 26=%LONGREALFN LOG(%LONGREAL X) * !* 27=%LONGREALFN SIN(%LONGREAL X) * !* 28=%LONGREALFN COS(%LONGREAL X) * !* 29=%LONGREALFN TAN(%LONGREAL X) * !* 30=%LONGREALFN EXP(%LONGREAL X) * !* 31=%ROUTINE CLOSE STREAM(%INTEGER STREAM) * !* 32=%BYTEINTEGERMAP BYTE INTEGER(%INTEGER VAR ADDR) * !* 33=%INTEGERFN EVENTINF * !* 34=%LONGREALFN RADIUS(%LONGREAL X,Y) * !* 35=%LONGREALFN ARCTAN(%LONGREAL X,Y) * !* 36=%BYTEINTEGERMAP LENGTH(%STRINGNAME S) * !* 37=%ROUTINE PRINT STRING(%STRING(255) MESSAGE) * !* 38=%INTEGERFN NL * !* 39=%LONGREALMAP LONG REAL(%INTEGER VAR ADDR) * !* 40=%ROUTINE PRINT CH(%INTEGER CHARACTER) * !* 41=%ROUTINE READ CH(%NAME CHARACTER) * !* 42=%STRINGMAP STRING(%INTEGER VAR ADDR) * !* 43=%ROUTINE READ ITEM(%STRINGNAME ITEM) * !* 44=%STRING(1)%FN NEXT ITEM * !* 45=%BYTEINTEGERMAP CHARNO(%STRINGNAME STR,%INTEGER CHARREQD) * !* 46=%STRING(1)%FN TOSTRING(%INTEGER SYMBOL) * !* 47=%STRING(255)%FN SUBSTRING(%STRINGNAME S,%INTEGER BEG,END) * !* 48=%RECORDMAP RECORD(%INTEGER REC ADDR) * !* 49=%ARRAYMAP ARRAY(%INTEGER A1ADDR,%ARRAYNAME FORMAT) * !* 50=%INTEGERFN SIZEOF(%NAME X) * !* 51=%INTEGERFN IMOD(%INTEGER VALUE) * !* 52=%LONGREALFN PI * !* 53=%INTEGERFN EVENTLINE * !* 54=%LONGINTEGERMAP LONGINTEGER(%INTEGER ADR) * !* 55=%LONGLONGREALMAP LONGLONGREAL(%INTEGER ADR) * !* 56=%LONGINTGEREFN LENGTHENI(%INTEGER VAL) * !* 57=%LONGLONGREALFN LENGTHENR(%LONGREAL VAL) * !* 58=%INTEGERFN SHORTENI(%LONGINTEGER VAL) * !* 59=%LONGREALFN SHORTENR(%LONGLONGREAL VAL) * !* 60=%INTEGERFN NEXTCH * !* 61=%HALFINTEGERMAP HALFINTEGER(%INTEGER ADDR) * !* 62=%ROUTINE PPROFILE * !* 63=%LONGREALFN FLOAT(%INTEGER VALUE) * !* 64=%LONGINTEGERFN LINT(%LONGLONGREAL X) * !* 65=%LONGINTEGERFN LINTPT(%LONGLONGREAL X) * !* 66=%SHORTINTEGERMAP SHORTINTEGER(%INTEGER N) * !*********************************************************************** INTEGERFNSPEC OPTMAP SWITCH ADHOC(1:17) CONSTINTEGERARRAY SNINFO(0:NO OF SNS)=C X'41080001',X'41090001',X'408A0001',X'40A00001', X'40010001',X'800D0000',X'11010001',X'11010001', X'10020024',X'41030001',X'19030001',X'80130001', X'80170014',X'408C0001',X'19050024',X'80010002', X'11040024',X'11040024',X'80010005',X'80090006', X'80060007',X'2100003E',X'2100003E',X'11060024', X'80010008',X'80010009',X'8001000A',X'8001000B', X'8001000C',X'8001000D',X'8001000E',X'8015000F', X'2100003E',X'100D0024',X'80030010',X'80030011', X'1907003E',X'41070001',X'10080024',X'2100003E', X'41050001',X'19030001',X'2100003E',X'19030001', X'10020024',X'1A07003E',X'11090024',X'800F0012', X'110A0018',X'120B1000',X'80130013',X'11060024', X'100C0024',X'100D0024',X'2100003E'(2), X'110E0024'(4), X'10020024',X'2100003E',X'100F0001',X'11100024', X'11110024',X'11110024',X'2100003E'; CONSTSTRING (11)ARRAY SNXREFS(0:20)=C "readstring", "s#read", "s#iarcsin", "s#int", "s#intpt" , "s#fracpt", "s#print" , "s#printfl", "s#iarccos","s#isqrt" , "s#ilog" , "s#isin", "s#icos" , "s#itan" , "s#iexp" , "closestream", "s#iradius","s#iarctan","s#substring","s#sizeof", "s#write" ; ! ! SNPARAMS HOLDS NUMBER AND PTYPE OF FORMAL PARAMETER FOR IMPLICITLY ! SPECIFIED EXTERNAL ROUTINES. A POINTER IN SNINFO MEANS THAT NO ! DUPLICATES NEED TO BE RECORDED. ! IF PARAMS BWARDS=YES THEN START CONSTINTEGERARRAY SNPARAMS(0:25)=0{NO PARAMS}, 1,LRLPT{%LONGREAL X}, 2,8<<16!LRLPT,LRLPT{%LONGREAL X,Y}, 2,12<<16!LRLPT,4<<16!X'51'{%LONGREAL X,%INTEGER I}, 3,8<<16!LRLPT,4<<16!X'51',X'51'{%LONGREAL X,%INTEGER I,J}, 1,X'435'{%STRINGNAME S}, 3,8<<16!X'435',4<<16!X'51',X'51'{%STRINGNAME S,%INTEGER I,J}, 1,X'400'{%NAME X}, 1,4<<16!X'51'{%INTEGER I}, 2,4<<16!X'51',X'51'{%INTEGER I,J}; FINISH ELSE START CONSTINTEGERARRAY SNPARAMS(0:25)=0{NO PARAMS}, 1,LRLPT{%LONGREAL X}, 2,LRLPT,8<<16!LRLPT{%LONGREAL X,Y}, 2,LRLPT,8<<16!X'51'{%LONGREAL X,%INTEGER I}, 3,LRLPT,4<<16!X'51',8<<16!X'51'{%LONGREAL X,%INTEGER I,J}, 1,X'435'{%STRINGNAME S}, 3,X'435',8<<16!X'51',12<<16!X'51'{%STRINGNAME S,%INTEGER I,J}, 1,X'400'{%NAME X}, 1,4<<16!X'51'{%INTEGER I}, 2,X'51',4<<16!X'51'{%INTEGER I,J}; FINISH ! CONSTBYTEINTEGERARRAY WRONGZ(0:15)=27,29,23,29,29,23,82,109(5), 23,27,109(2); ROUTINESPEC RTOS INTEGERFNSPEC CIOCP(INTEGER N,RECORD (RD)NAME PARAM) RECORD (LISTF)NAME LCELL RECORD (LISTF)PCELL RECORD (RD)OPND RECORD (TRIPF)NAME CURRT STRING (11)SNXREF INTEGER ERRNO,FLAG,POINTER,PIN,SNNO,SNNAME,NAPS,SNPTYPE,JJ,C XTRA,IOCPEP,B,D,SNINF,P0,OPHEAD,ERRVAL,EXPHEAD,EXPBOT,NOPS SNNAME=FROM AR2(P) SNNO=K; ! INDEX INTO SNINFO TESTAPP(NAPS); ! COUNT ACTUAL PARAMETERS PIN=P; P=P+2 SNPTYPE=ACC SNINF=SNINFO(SNNO) XTRA=SNINF&X'FFFF' POINTER=(SNINF>>16)&255 FLAG=SNINF>>24 ! ! THE IMPLICITLY SPECIFIED ROUTINE ARE THE EASIEST OF ALL TO DEAL WITH. ! JUST SET UP THE EXTERNAL SPEC & PARAMETERS. THEN A RECURSIVE CALL ! OF CNAME THEN FINDS THE ROUTINE UNDER ITS TRUE COLOURS AND COMPILES ! THE CALL. ALL CALLS EXCEPT THE FIRST ARE DEALT WITH DIRECTLY BY CNAME. ! ALL NONTRIVIAL ROUTINES SHOULD BE DEALT WITH IN THIS MANNER ! XTRA HAS INDEX INTO ARRAY OF EXTERNAL NAMES SO THAT THESE ! CAN EASILY BE CHANGED. ! IF FLAG&X'80'#0 THEN START SNXREF=SNXREFS(XTRA) IF TARGET=EMAS OR TARGET=IBM OR TARGET=IBMXA OR TARGET=PNX THEN C CXREF(SNXREF,3*PARM_DYNAMIC,2,JJ);! JJ SET WITH REF DISPLACEMENT IF TARGET=PERQ OR TARGET=ACCENT THEN START JJ=ADDR(SNXREF) D=LENGTH(SNXREF) MOVE BYTES(D+1,JJ,0,ADDR(A(0)),WORKA_ARTOP) JJ=ADDR(A(WORKA_ARTOP))-ADDR(A(WORKA_DICTBASE)) WORKA_ARTOP=(WORKA_ARTOP+D+4)&(-4) FINISH ! %IF SNNO=26 %THEN LOGEPDISP=JJ ! %IF SNNO=30 %THEN EXPEPDISP=JJ OPHEAD=0; P0=SNPARAMS(POINTER) K=OPHEAD; D=1 WHILE D<=P0 CYCLE B=SNPARAMS(POINTER+D) PTYPE=B&X'FFFF' UNPACK IF NAM=0 THEN ACC=BYTES(PREC) ELSE ACC=8 IF PTYPE=X'35' THEN ACC=256;!STRING BY VALUE PCELL=0; ! SET UP PARAMETER DESC VIA RECORD PCELL_PTYPE=PTYPE; ! FOR CONSISTENCY ON BYTE SWOPPED HOSTS PCELL_SNDISP=B>>16 PCELL_ACC=ACC IF PARAMS BWARDS=YES THEN PUSH(OPHEAD,PCELL_S1,PCELL_S2,0) C ELSE INSERTAT END(OPHEAD,PCELL_S1,PCELL_S2,0) D=D+1 REPEAT IF P0>0 THEN ASLIST(OPHEAD)_S3=P0;! INSERT NO OF PARAMS ! UPPER PART OF P0(TOTAL PARAMSPACE) ! APPARENTLY NOT NEEDED AS NO BODIES ! ARE PROVIDED. FIELD COULD BE ! GIVEN EASILY IN ABOVE TABLES LCELL==ASLIST(TAGS(SNNAME)) LCELL_PTYPE=SNPTYPE LCELL_UIOJ=1<<4!14; ! I=1 & J=14 LCELL_SNDISP=JJ; ! RT ENTRY DISPLACEMENT LCELL_ACC=BYTES(SNPTYPE>>4&15) LCELL_SLINK=OPHEAD LCELL_KFORM=0; ! KFORM(=FORMAT INFO) P=PIN; CNAME(Z); ! RECURSIVE CALL P=P-1; RETURN ; ! DUPLICATES CHECK OF <ENAME> FINISH ! ! ALL ROUTINES EXCEPT THE IMPLICITS REQUIRE A CHECK THAT THE USE OF THE ! NAME IS LEGAL AND THAT THE CORRECT NO OF PARAMETERS(BOTTOM 2 BITS OF ! FLAG) HAS BEEN SUPPLIED. THE CHECK IS TRIVIAL - THE PROBLEM ! IS TO GET THE RIGHT ERROR NUMBER. ! XTRA HAS A BITMASK OF ALLOWED USES(IE ALLOWED Z VALUES) ! ERRVAL=NAPS-FLAG&3 IF ERRVAL>0 THEN ERRNO=19 AND ->ERREXIT IF ERRVAL<0 THEN ERRNO=18 AND ERRVAL=-ERRVAL AND ->ERREXIT JJ=1<<Z IF JJ&XTRA=0 THEN START ; ! ILLEGAL USE ERRNO=WRONGZ(Z) ->ERR EXIT FINISH ! ! A NUMBER OF INPUT-OUTPUT ROUTINES ARE MAPPED ONTO CALLS OF IOCP. ! THIS ARRANGEMENT HAS THE ADVANTAGE OF REQUIRING ONL 1 EXTERNAL REF ! IN THE GLA BUT HAS THE DISADVANTAGE THAT THE I-O ROUTINES CAN NOT ! BE PASSED AS RT-TYPE PARAMETERS AS WELL AS REQUIRING MESSY CODE ! HEREABOUTS. SNINF_PTR HOLD EITHER:- ! 1) THE IOCP ENTRY POINT NO ! OR 2) THE SYMBOL TO BE OUTPUT WITH 2**7 BIT SET ! ! THIS SECTION DEALS WITH SELECT INPUT,SELECT OUTPUT,NEWLINE,NEWPAGE ! SPACE,SKIP SYMBOL,PRINT SYMBOL,PRINT STRING ! AND PRINT CH ! IF FLAG&X'40'#0 THEN START IOCPEP=POINTER IF FLAG&3#0 THEN START ; ! RT HAS PARAMS P=P+1 IF SNNO=37 THEN CSTREXP(32) ELSE CSEXP(X'51') FINISH ELSE EXPOPND=0 AND EXPOPND_PTYPE=X'51' IF IOCPEP>127 THEN START EXPOPND_FLAG=SCONST EXPOPND_D=IOCPEP&127 IOCPEP=5 FINISH JJ=CIOCP(IOCPEP,EXPOPND); ! PLANT CALL OF IOCP P=P+1 ->OKEXIT FINISH ! ! THE BUILT-IN MAPS (INTEGER ETC BUT NOT RECORD OR ARRAY) ! IF FLAG&X'20'#0 THEN START SNPTYPE=X'1C00'+SNPTYPE; ! ADD MAP BITS IF PARM_OPT=0 AND OPTMAP#0 THEN ->OKEXIT IF Z=1 THEN BIMSTR=1; ! SPECIAL FLAG FOR STORE VIA MAP P=P+1 CSEXP(X'51'); P=P+1 IF Z=1 THEN BIMSTR=0 DISP=0; ACCESS=3; BASE=0 OLDI=0; ! FOR CHECK IN == ASSGNMNT ->OKEXIT FINISH ! ! ADHOC CODING IS REQUIRED FOR THE REMAINING ROUTINES APART FROM ! A CHECK FOR NAMETYPE PARAMETERS. THE SWITCH NO IS KEPT IN POINTER ! P=P+1 IF FLAG&8#0 AND C (A(P+3)#4 OR A(P+4)#1 OR A(P+FROM AR2(P+1)+1)#2) THEN C ERRNO=22 AND ERRVAL=1 AND ->ERREXIT ->ADHOC(POINTER) ADHOC(1): ! NEWLINES(=6) & SPACES(=7) IF SNNO=6 THEN JJ=10 ELSE JJ=32 EXPHEAD=0; NOPS=2 PUSH(EXPHEAD,ORL<<FLAGSHIFT,0,0); ! OPERATOR '!' EXPBOT=EXPHEAD PUSH(EXPHEAD,MINAPT<<PTSHIFT,JJ,0);! CONST JJ PUSH(EXPHEAD,LSHIFT<<FLAGSHIFT,0,0);! OPERATOR '<<' PUSH(EXPHEAD,MINAPT<<PTSHIFT,8,0);! CONST 8 P=P+3; TORP(EXPHEAD,EXPBOT,NOPS) EXPOP(EXPHEAD,EXPBOT,NOPS,X'51'); ! EVAL REPTN<<8!SYMBOL IN GR1 JJ=CIOCP(17,EXPOPND) P=P+1 ->OKEXIT ADHOC(2): ! NEXTSYMBOL(=8) & NEXTITEM(=44) ! ALSO NEXTCH(=60) IF SNNO=60 THEN JJ=18 ELSE JJ=2 EXPOPND=0; EXPOPND_PTYPE=X'51' JJ=CIOCP(JJ,EXPOPND); ! LEAVES THE SYMBOL IN GR1 IF SNNO=44 THEN ->TOST; ! TREAT AS TOSTRING NAMEOPND_PTYPE=MINAPT NAMEOPND_FLAG=REFTRIP NAMEOPND_D=JJ ->OKEXIT ADHOC(3): ! READSYMBOL(=10),CH(=41)&ITEM(=43) IF SNNO=41 THEN JJ=4 ELSE JJ=1 EXPOPND=0; EXPOPND_PTYPE=X'51' P=P+5 IF SNNO=43 THEN START EXPOPND_D=CIOCP(JJ,EXPOPND) EXPOPND_PTYPE=X'41'; EXPOPND_FLAG=REFTRIP TYPE=5; RTOS OPND=NAMEOPND CNAME(3) JJ=BRECTRIP(STRASS1,X'35',0,NAMEOPND,OPND) FINISH ELSE START EXPHEAD=0; NOPS=1 FNAME=A(P)<<8!A(P+1) REDUCE TAG FAULT(25,0,0) UNLESS TYPE=1 IF LHSADDRFIRST=NO OR (NAM=ARR=0 AND A(P+2)=2=A(P+3)) THEN C PUSH(EXPHEAD,PTYPE<<PTSHIFT!ARNAME<<FLAGSHIFT,P,FNAME) ELSE C CNAME(3) AND PUSH(EXPHEAD,NAMEOPND_S1,NAMEOPND_D,NAMEOPND_XTRA) EXPBOT=EXPHEAD EXPOPND_PTYPE=X'51'; EXPOPND_FLAG=SCONST EXPOPND_D=0 JJ=CIOCP(JJ,EXPOPND) BINSERT(EXPHEAD,EXPBOT,MINAPT<<PTSHIFT!REFTRIP<<FLAGSHIFT,JJ,0) BINSERT(EXPHEAD,EXPBOT,VASS<<FLAGSHIFT,PTYPE,0) EXPOP(EXPHEAD,EXPBOT,NOPS,PTYPE&255!256) FINISH P=PIN+6+FROM AR2(PIN+4) ->OKEXIT ADHOC(17): ! LINT(=64) AND LINTPT(=65) UNLESS TYPEFLAG(10)&255=X'61' AND TYPEFLAG(12)&255=X'72' C THEN ERRNO=99 AND ->ERREXIT;! NEED LONGINTS&LLREALS CSEXP(X'72'); ! LONGLONGREAL MODE IF SNNO=64 THEN JJ=RTOI1 ELSE JJ=RTOI2 P0=X'61'; ->FIXIT ADHOC(4): ! INT(=16) AND INTPT (=17) CSEXP(LRLPT) IF SNNO=16 THEN JJ=RTOI1 ELSE JJ=RTOI2 P0=X'51'; ! FIXES TO INTEGER FIXIT:JJ=URECTRIP(JJ,P0,0,EXPOPND) P=P+1 NAMEOPND_PTYPE=P0; NAMEOPND_FLAG=REFTRIP NAMEOPND_D=JJ ->OKEXIT ADHOC(5): ! ADDR(=14) P=P+5; CNAME(4); ! FETCH ADDRESS MODE P=P+2; ->OKEXIT ADHOC(6): ! MOD(=23), IMOD(=51) EXPHEAD=0; NOPS=1 PUSH(EXPHEAD,MODULUS<<FLAGSHIFT,0,0) EXPBOT=EXPHEAD P=P+3 TORP(EXPHEAD,EXPBOT,NOPS) EXPOP(EXPHEAD,EXPBOT,NOPS,SNPTYPE) NAMEOPND=EXPOPND P=P+1 ->OKEXIT ADHOC(7): ! CHARNO(=45) & LENGTH(=36) P=P+5 CNAME(4) OPND=NAMEOPND B=BML; D=DML ERRNO=22; ERRVAL=1 ->ERREXIT UNLESS TYPE=5 AND (ROUT=0 OR NAM>=2) IF NAM=0 AND LITL=1 THEN FAULT(43,0,FROMAR2(PIN+8)) P=P+2 IF SNNO#36 THEN START CSEXP(MINAPT) P=P+1 FINISH ELSE EXPOPND=0 AND EXPOPND_PTYPE=X'41' AND EXPOPND_FLAG=SCONST JJ=BRECTRIP(SINDX,X'31',0,OPND,EXPOPND) CURRT==TRIPLES(JJ) CURRT_X1=1<<20; ! ADJUSTMENT BASE ON 1 BYTE ELEMENTS EXPOPND_PTYPE=X'31'; EXPOPND_FLAG=REFTRIP EXPOPND_D=JJ EXPOPND_XTRA=0 DISP=0; ACCESS=3 STNAME=-1 IF Z=1; ! CANT REMEBER NAME SNPTYPE=SNPTYPE+X'1C00' ->OKEXIT ADHOC(12): ! PI(=52) ADHOC(8): ! NL(=38). THIS FN IS PICKED OFF P=P+1 ->OKEXIT; ! ERROR EG NL=A+B ADHOC(9): ! TOSTRING(=46) CSEXP(MINAPT); ! RET EXPSN P=P+1 TOST: RTOS STRFNRES=0 SNPTYPE=X'1035'; ! TYPED AS STRING FN ->OKEXIT ADHOC(10): ! RECORD(=48) CSEXP(X'51') P=P+1 DISP=0; BASE=0; ACCESS=3 OLDI=0; ACC=X'FFFF' SNPTYPE=SNPTYPE+X'1C00'; ! ADD MAP BITS ->OKEXIT ADHOC(11): ! ARRAY(=49) CSEXP(X'51'); ! ADDR(A(0)) TO NEST OPND=EXPOPND ERRNO=22; ERRVAL=2 ->ERREXIT UNLESS A(P+4)=4 AND A(P+5)=1 P=P+6; CNAME(12) ->ERREXIT UNLESS A(P)=2 AND ARR>0 P=P+2 NAMEOPND_D=CREATE AH(0,OPND,NAMEOPND) NAMEOPND_PTYPE=AHEADPT NAMEOPND_FLAG=REFTRIP NAMEOPND_XTRA=0 RETURN ADHOC(13): ! EVENTINF(=33) & EVENTLINE D=CURRINF_ONINF FAULT(16,0,SNNAME) IF D=0 D=D+4 IF SNNO#33 BASE=RBASE; ACCESS=0 DISP=D; SNPTYPE=SNPTYPE+X'1C00';! ADD MAP BITS ->OKEXIT ADHOC(14): ! LENGTHEN AND SHORTEN D=(SNNO&3)*8 CSEXP(X'52415251'>>D&255) P=P+1 NAMEOPND=EXPOPND ->OKEXIT ADHOC(15): ! PPROFILE(IGNORED UNLESS PARM SET) JJ=UCONSTTRIP(PPROF,X'51',0,PROFAAD) UNLESS PARM_PROF=0 ->OKEXIT ADHOC(16): ! FLOAT CSEXP(LRLPT) NAMEOPND=EXPOPND P=P+1 OKEXIT: ! NORMAL EXIT PTYPE=SNPTYPE; UNPACK RETURN ERREXIT: ! ERROR EXIT FAULT(ERRNO,ERRVAL,SNNAME) NAMEOPND=0; NAMEOPND_PTYPE=X'51' BASE=0; DISP=0; ACCESS=0; AREA=0 PTYPE=SNPTYPE; UNPACK P=PIN+2; SKIP APP P=P-1; RETURN INTEGERFN OPTMAP !*********************************************************************** !* LOOK FOR EXPRESSION LIKE INTEGER(ADDR(X)) AND AVOID USING DR * !*********************************************************************** INTEGER VARNAME,REXP,PP,CVAL,OP IF SNNO=42 THEN RESULT =0; ! STRINGMAP STRING PP=P+2; REXP=FROM AR2(PP)+PP; ! TO REST OF EXP VARNAME=FROM AR2(PP+4); ! SHOULD BE ADDR RESULT =0 UNLESS A(PP+2)=4 AND A(PP+3)=1 COPY TAG(VARNAME); ! CHECK IT WAS ADDR ->WASADR IF PTYPE=SNPT AND K=14 AND A(PP+6)=1 RESULT =0 WASADR: PP=PP+10 RESULT =0 UNLESS A(PP)=4 AND A(PP+1)=1 AND C A(PP+4)=2=A(PP+5) AND A(PP+6)=2=A(PP+7) AND A(PP+8)=2 VARNAME=FROM AR2(PP+2); COPY TAG(VARNAME) RESULT =0 UNLESS PTYPE&X'FF0C'=0 IF A(REXP)=2 THEN P=REXP+2 ELSE START OP=A(REXP+1) RESULT =0 UNLESS 1<=OP<=2 AND A(REXP+2)=2 AND C A(REXP+3)=X'41' AND A(REXP+6)=2 CVAL=FROM AR2(REXP+4) IF OP=1 THEN K=K+2*CVAL ELSE K=K-2*CVAL RESULT =0 IF K<0 P=REXP+8 FINISH BASE=I DISP=K; ACCESS=0 RESULT =1 END INTEGERFN CIOCP(INTEGER EP,RECORD (RD)NAME PARAM) !*********************************************************************** !* CALL IOCP PASSING A PARAMETER !* RETURNS THE TRIPLE NO OF THE CALL !*********************************************************************** RECORD (RD) OPND OPND_PTYPE=MINAPT; OPND_FLAG=SCONST OPND_D=EP RESULT =BRECTRIP(IOCPC,MINAPT,0,OPND,PARAM) END ROUTINE RTOS !*********************************************************************** !* PLANTS CODE TO CONVERT A SYMBOL IN EXPOPND TO A ONE * !* CHARACTER STRING IN A TEMPORARARY VARIABLE. * !*********************************************************************** INTEGER KK,JJ IF EXPOPND_FLAG<=1 START KK=ITOS1 CTOP(KK,JJ,0,EXPOPND,NAMEOPND) IF KK=0 THEN NAMEOPND=EXPOPND AND RETURN FINISH JJ=URECTRIP(ITOS1,X'35',0,EXPOPND) NAMEOPND_PTYPE=X'35'; NAMEOPND_FLAG=REFTRIP NAMEOPND_D=JJ END END ; ! OF ROUTINE CSNAME ROUTINE AATORP(INTEGERNAME NOPS,HEAD1,BOT1, INTEGER ARRP,BS,DP) !*********************************************************************** !* DOES THE HARD WORK OF ARRAY ACCESS BY PRODUCING REVERSE POLISH * !* EXPRESSION OF THE INDEX EXPRESSIONS & MULTIPLIERS * !*********************************************************************** RECORD (TAGF) NAME LCELL INTEGER PTYPEP,KK,PP,JJ,SOLDI,TYPEP,ARRNAME,Q,PRECP,ELSIZE, NAMINF,DVD,PRIVOPS INTEGERARRAY HEADS,BOTS(0:12) RECORD (RD) VMYOP,RPOP PP=P; TYPEP=TYPE JJ=J; PTYPEP=PTYPE; PRECP=PREC; SOLDI=OLDI IF TYPE<=2 THEN ELSIZE=BYTES(PRECP) ELSE ELSIZE=ACC IF ELSIZE>4095 OR (TYPE=5 AND NAM#0) THEN ELSIZE=0 DVD=SNDISP; ! LOCATION OF DV IF CONSTANT IF DVD>0 THEN VMYOP_PTYPE=X'51' ELSE VMYOP_PTYPE=X'61' VMYOP_FLAG=0; VMYOP_XB=0 ARRNAME=FROM AR2(P); ! NAME OF ENTITY NAMINF=TAGS(ARRNAME) FAULT(87,0,ARRNAME) IF ARR=3; ! ARRAYFORMAT USED AS ARRAY NAMINF=-2 AND DVD=0 IF ARRP>2; ! ARRAYS IN RECORDS TEST APP(Q); ! COUNT NO OF SUBSCRIPTS ! ! CHECK CORRECT NO OF SUBSCRIPTS PROVIDED. HOWEVER ENTITIES DECLARED ! AS %<TYPE>ARRAYNAME HAVE NO DIMENSION . THIS SECTION SETS THE ! DIMENSION FROM THE FIRST USE OF THE NAME. ! IF JJ=0 THENSTART ; ! 0 DIMENSIONS = NOT KNOWN LCELL==ASLIST(TCELL) LCELL_UIOJ=LCELL_UIOJ!Q; ! DIMSN IS BOTTOM 4 BITS OF TAG JJ=Q FINISH IF JJ=Q#0 THENSTART ; ! IN LINE CODE ! ! FOR IN-LINE CODE WE SET UP A CHAIN OF REVERSE POLISH OPERATIONS TO ! EVALUATE THE VARIOUS SUBSCRIPTS,MULTIPLY BY THE MULTIPLIERS AND ! ADD THEM TOGETHER. ! ! ! NOW PROCESS THE SUBSCRIPTS CALLINR TORP TO CONVERT THE EXPRESSIONS ! TO REVERSE POLISH AND ADDING THE EXTRA OPERATIONS. ! RPOP=0 RPOP_PTYPE=X'51' RPOP_FLAG=7 RPOP_D=BS<<16!DP RPOP_XTRA=M'ARRH' BINSERT(HEAD1,BOT1,RPOP_S1,RPOP_D,RPOP_XTRA) P=PP+3 CYCLE KK=1,1,JJ; ! THROUGH THE SUBSCRIPTS P=P+3 HEADS(KK)=0; BOTS(KK)=0; PRIVOPS=0 TORP(HEADS(KK),BOTS(KK),PRIVOPS); ! SUBSCRIPT TO REVERSE POLISH IF PTYPE=1 AND PRIVOPS&1<<17#0 THEN C WARN(1,0) AND BINSERT(HEADS(KK),BOTS(KK),SHRTN,0,0) P=P+1 NOPS=(NOPS+PRIVOPS&X'FFF')!PRIVOPS&X'FFFF0000' ! ADD OPERATORS AND OR FLAGS ! ! MULTIPLIERS ARE DOPE VECTOR ITEMS (OPTYPE=3) ! ! N SUBSCRIPTS WILL REQUIRE (N-1) MULTIPLICATIONS AND ADDITIONS ! ON EMAS HAVE TO ADD ALL OPERATORS AT END SINCE DV ARE BACKWARDS ! NOPS=NOPS+1 VMYOP_D=KK<<24!JJ<<16!DVD VMYOP_XTRA=BS<<16!DP BINSERT(HEADS(KK),BOTS(KK),VMYOP_S1,VMYOP_D,VMYOP_XTRA);! MULTIPLIER RPOP=0 RPOP_FLAG=VMY RPOP_D=PTYPEP<<16 IF NAMINF>=0 THEN RPOP_D=RPOP_D!ARRNAME BINSERT(HEADS(KK),BOTS(KK),RPOP_S1,RPOP_D,0); ! DOPE VECTOR MULTIPLY IF (TARGET#EMAS AND KK>1) OR (TARGET=EMAS AND KK<JJ) START RPOP=0; RPOP_FLAG=COMB BINSERT(HEADS(KK),BOTS(KK),RPOP_S1,0,0); ! COMBINE WITH PREVIOUS NOPS=NOPS+1 FINISH REPEAT CYCLE KK=1,1,JJ IF TARGET#EMAS START ASLIST(BOT1)_LINK=HEADS(KK) BOT1=BOTS(KK) FINISH ELSE START ASLIST(BOT1)_LINK=HEADS(JJ+1-KK) BOT1=BOTS(JJ+1-KK) FINISH REPEAT UNLESS ARRP=2 OR C ((TARGET=PERQ OR TARGET=ACCENT) AND PARM_COMPILER#0) START ; ! BASE ADJUST VMYOP_D=JJ<<16!DVD BINSERT(HEAD1,BOT1,VMYOP_S1,VMYOP_D,VMYOP_XTRA) RPOP=0 RPOP_FLAG=BADJ; RPOP_D=PTYPE<<16!ARRNAME BINSERT(HEAD1,BOT1,RPOP_S1,RPOP_D,0) FINISH RPOP=0; RPOP_FLAG=AINDX RPOP_D=BS<<16!DP!ELSIZE<<20 BINSERT(HEAD1,BOT1,RPOP_S1,RPOP_D,0); ! SCALE NOPS=NOPS+2 FINISHELSESTART RPOP=0; RPOP_FLAG=SCONST BINSERT(HEAD1,BOT1,RPOP_S1,0,0) IF JJ>Q THEN FAULT(20,JJ-Q,ARRNAME) ELSE FAULT(21,Q-JJ,ARRNAME) P=P+2; SKIP APP FINISH ACC=ELSIZE PTYPE=PTYPEP; J=JJ END ROUTINE CANAME(INTEGER Z,ARRP,BS,DP) !*********************************************************************** !* BS & DP DEFINE THE POSITION OF THE ARRAY HEAD * !* ARRP=1 FOR ARRAYS,2 FOR VECTORS,3 FOR ARRAYS IN RECORDS * !* BASIC DISP = DISPMNT OF A(0) FOR VECTORS OR ARRAYS IN RECORDS * !*********************************************************************** INTEGER HEAD1,BOT1,NOPS,ELSIZE,PTYPEP,JJ,SOLDI NOPS=0; HEAD1=0; BOT1=0 AATORP(NOPS,HEAD1,BOT1,ARRP,BS,DP) SOLDI=OLDI PTYPEP=PTYPE; JJ=J; ELSIZE=ACC EXPOP(HEAD1,BOT1,NOPS,X'51'); ! EVALUATE THE REVERSE POLISH LIST ! CONSTANT ACCEPTABLE AS RESULT BASE=BS; DISP=DP; ACCESS=3 ACC=ELSIZE; PTYPE=PTYPEP; UNPACK; J=JJ IF TYPE=5 AND NAM>0 THEN BML=BS AND DML=DP OLDI=SOLDI; ! FOR NAME==A(EL) VALIDATION END ; ! OF ROUTINE CANAME ROUTINE CNAME(INTEGER Z) !*********************************************************************** !* THIS IS THE MAIN ROUTINE FOR PROCESSING NAMES.CANAME,CSNAME * !* AND CRNAME ARE ONLY CALLED FROM HERE,THE NAME (AND ANY PARAMS * !* OR SUBNAMES) ARE ACCESSED BY P WHICH IS ADVANCED. * !* Z SPECIFIES ACTION AS FOLLOWS:- * !* Z=0 COMPILE A ROUTINE CALL * !* Z=1 ARRANGE A 'STORE' OPERATION FROM ESTACK * !* Z=2 FETCH NAME TO ESTACK * !* Z=3 GET 32 BIT ADDRESS(48BIT FOR BYTES) FOR PASSING BY NAME * !* Z=4 SET 20 BIT ADDRESS(36BIT FOR BYTES) OF NAME IN REG * !* Z=5 AS Z=2 * !* Z=6 STORE ETOS (CONTAINS POINTER) INTO POINTER VARIABLE * !* Z=7->10 NOT NOW USED * !* Z=11 FETCH 32 BIT ADDRESS OF ARRAYHEAD * !* Z=12 FETCH ARRAYHEAD TO ESTACK * !* Z=13 GET 4 WORD ROUTINE DISCRIPTOR * !* (INTERNAL ROUTINES FIRST CREATE THE DISCRIPTOR) * !* * !*********************************************************************** INTEGER JJ, KK, LEVELP, DISPP, NAMEP, PP, SAVESL, FNAME SWITCH S, FUNNY(11:13), SW(0:8) PP=P FNAME=A(P)<<8+A(P+1) IF Z=1 OR Z=6 THEN STNAME=FNAME COPYTAG(FNAME) IF I=-1 THEN START FAULT(16, 0, FNAME) PTYPE=X'57' STORE TAG(FNAME,LEVEL,RBASE,0,0,4,N,0) N=N+4; COPYTAG(FNAME); ! SET USE BITS! FINISH SAVESL=ACC JJ=J; JJ=0 IF JJ=15 NAMEP=FNAME LEVELP=I; DISPP=K FAULT(43, 0, FNAME) IF LITL=1 AND ROUT=0=NAM AND C (Z=1 OR Z=3 OR (Z=4 AND ARR=0)) ->NOT SET IF TYPE=7 IF (Z=0 AND (ROUT#1 OR 0#TYPE#6)) OR (Z=13 AND ROUT=0) C THEN FAULT(27,0,FNAME) AND ->NOT SET ->FUNNY(Z) IF Z>=10 ->RTCALL IF ROUT=1 ->SW(TYPE) SW(6): FAULT(5, 0, FNAME) ->NOT SET SW(4): !RECORD FORMAT NAME FAULT(87,0,FNAME) SW(7): NOT SET: ! NAME NOT SET BASE=I; DISP=K; ACCESS=0 NAMEOPND=0; NAMEOPND_PTYPE=X'51' PTYPE=X'51'; UNPACK IF 1<=Z<=5 THEN NAMEOP(Z,4,NAMEP) P=P+2; SKIP APP; ->CHKEN FUNNY(11): ! SET 32 BIT ADRESS OF ARRAYHEAD FUNNY(12): ! MOVE ARRAYHEAD TO ESTACK ->SW(3) IF TYPE=3 AND (ARR=0 OR A(P+2)=1) IF PTYPE=SNPT THEN CSNAME(12) AND ->CHKEN IF A(P+2)=2 THEN P=P+3 ELSE NO APP NAMEOPND_PTYPE=AHEADPT NAMEOPND_FLAG=DNAME NAMEOPND_D=FNAME NAMEOPND_XTRA=0 ->CHKEN S(12):S(11): ! ARRAYS IN RECORDS BY NAME ->CHKEN FUNNY(13): ! LOAD ADDR FOR RT-TYPE IF PTYPE=SNPT THEN CSNAME(Z) AND P=P+1 AND ->CHKEN JJ=UNAMETRIP(RTFP,RTPARAMPT,0,FNAME) NAMEOPND_PTYPE=RTPARAMPT; NAMEOPND_FLAG=REFTRIP NAMEOPND_D=JJ NAMEOPND_XTRA=0 IF A(P+2)=2 THEN P=P+3 ELSE NO APP ->CHKEN RMAP: ! RECORD MAPS RFUN: ! RECORD FUNCTIONS COPY TAG(NAMEP); ! SET KFORM ETC P=P-3 NAMEP=-1 CRNAME(Z,3,0,0,NAMEP) ->RBACK SW(3): ! RECORD CRNAME(Z, 2*NAM, I, K, NAMEP) RBACK: ->S(Z) IF Z>=10 ->STRINREC IF TYPE=5 AND Z#6 ->NOT SET IF TYPE=7 NAMEOP(Z,BYTES(PREC),NAMEP) STNAME=NAMEP IF Z=1 OR Z=6 ->CHKEN SW(5): ! TYPE =STRING ! ! ALL STRING OPERATIONS ARE ON THE RELEVANT DESCRIPTOR. Z=2 &Z=5 ! REQUIRE A CURRENT LENGTH(IE MODIFIED) DESCRIPTOR. OTHER OPERATIONS ! REQUIRE THE MAX LENGTH DESCRIPTOR (IE UNMODIFIED HEADER) ! IF Z=6 THEN ->SW(1) ->STRARR IF ARR>=1 IF A(P+2)=2 THEN P=P+3 ELSE NO APP BASE=I; ACCESS=2*NAM; DISP=K SMAP: IF NAM#1 THEN BML=-1 AND DML=SAVESL-1 C ELSE BML=I AND DML=K NAMEOP(Z,4,NAMEP) ->CHKEN STRARR: ! STRINGARRAYS & ARRAYNAMES CANAME(Z, ARR, I, K) ->SMAP UNLESS Z=3 AND NAM#0 BML=LEVELP; DML=DISPP NAMEOP(3,4,NAMEP) ->CHKEN STRINREC: ! STRINGS IN RECORDS SAVESL=ACC ->SMAP UNLESS Z=3 AND NAM#0 AND ARR#0 DML=DISP; BML=BASE; ! LEFT SET BY CENAME NAMEOP(3,4,NAMEP) ->CHKEN ! ! SECTION TO DEAL WITH ALL NAMES INVOLVING ROUTINE CALL ! RTCALL: ! FIRST CHECK IF TYPE=0 AND Z#0 THEN FAULT(23, 0, FNAME) AND ->NOT SET ! RT NAME IN EXPRSN IF PTYPE=SNPT THEN START CSNAME(Z); ! SPECIAL NAME ->BIM IF ROUT=1 AND NAM>1 AND Z#0 ->CHKEN FINISH CRCALL(FNAME); P=P+1; ! DEAL WITH PARAMS ->CHKEN IF PTYPE&15=0 ->UDM IF NAM>1; ! MAPS UNLESS Z=2 OR Z=5 THEN START ; ! FUNCTIONS FAULT(29, 0, FNAME); BASE=0 ACCESS=0; DISP=0 FINISH ->RFUN IF TYPE=3 ->CHKEN UDM: ! USER DEFINED MAPS DISP=0 ACCESS=3 BASE=0 EXPOPND=NAMEOPND ->RMAP IF TYPE=3 BIM: ! BUILT IN MAPS NAMEP=-1 STNAME=-1 IF TYPE=5 THEN SAVESL=256 AND ->SMAP KK=Z; KK=2 IF Z=5 NAMEOP(Z,BYTES(PREC),NAMEP) ->CHKEN SW(0): ! %NAME PARAMETERS NO TYPE ! ALLOW FETCH ADDR OPERATIONS ! AND SPECIAL FOR BUILTIN MAPS UNLESS 3<=Z<=4 THEN START FAULT(90,0,FNAME); TYPE=1 FINISH SW(1): ! TYPE =INTEGER SW(2): ! TYPE=REAL IF ARR=0 OR (Z=6 AND A(P+2)=2) THEN START BASE=I; ACCESS=2*NAM DISP=K IF A(P+2)=2 THEN P=P+3 ELSE NO APP FINISH ELSE START CANAME(Z, ARR, I, K) NAM=0 FINISH NAMEOP(Z,BYTES(PREC),NAMEP) ->CHKEN ! CHKEN: WHILE A(P)=1 CYCLE FAULT(69,FROMAR2(P+1),FNAME) P=P+3; SKIP APP REPEAT P=P+1 END ROUTINE NAMEOP(INTEGER Z, SIZE, NAMEP) !*********************************************************************** !* FETCH OR STORE ETOS FROM OR TO VARIABLE DEFINED BY AREA ACCESS * !* BASE AND DISP. * !*********************************************************************** SWITCH BIGACC(0:11) RECORD (RD)POPND INTEGER KK,PPTYPE KK=Z; KK=2 IF Z=5 IF Z=6 THEN START ; ! NAME DEREFENCING FAULT(82,0,NAMEP) UNLESS NAMEP&X'FFFF'=X'FFFF' OR C (NAM!ARR#0 AND ROUT=0 AND (ACCESS>=8 OR ACCESS=2)) Z=1; KK=1; SIZE=4 PPTYPE=X'51' IF PTRSIZE(PTYPE&255)>4 THEN PPTYPE=X'61';! POINTER PTYPE PTYPE=PPTYPE IF ACCESS>=8 THEN ACCESS=ACCESS-4 ELSE ACCESS=0 FINISH KK=KK&3 XDISP=0 IF ACCESS<=3 ->BIGACC(ACCESS) BIGACC(9): ! ALL ACCESS=9 BIGACC(5): BIGACC(1): IMPABORT; ! NO LONGER USED? ! ! ACCESS ! ****** ! THIS VARIABLE DEFINES HOW TO ACCESS ANY IMP VARIABLE:- ! =0 VARIABLE DIRECTLY ADDRESSED IN 'BASE' BY 'DISP' ! =1 NOT USED ! =2 POINTER TO VARIABLE DIRECTLY ADDRESS BY 'BASE' & 'DISP' ! =3 POINTER AS IN =2 COMPUTED IN EXPOPND ! =4 VARIABLE 'XDISP' INTO RECORD AT BY 'BASE' &'DISP' ! =5 NOT USED ! =6 VAR 'XDISP' INTO RECORD ADDRESSED BY POINTER AT 'BASE' & 'DISP' ! =7 AS =6 BUT POINTER COMPUTED IN EXPOPND ! =8-11 AS 4-7 BUT THERE IS A POINTER TO ITEM AT 'XDISP' INTO RECORD ! POINTER HERE MEANS 32 BIT NORMALLY BUT BYTES MUSTBE AND STRING MAY ! HAVE TO BE 48 BIT ! BIGACC(0): ! DIRECTLY ADDRESS IF NAMEP&X'FFFF'#X'FFFF' START NAMEOPND_PTYPE=PTYPE; NAMEOPND_FLAG=DNAME NAMEOPND_D=NAMEP&X'FFFF' FINISH ELSE START NAMEOPND_PTYPE=PTYPE; NAMEOPND_FLAG=LOCALIR NAMEOPND_D=BASE<<16!DISP FINISH NAMEOPND_XTRA=0 ADOP: RETURN IF Z=1 IF Z=3 THEN START POPND_PTYPE=X'61'; POPND_FLAG=SCONST POPND_D=PTYPE<<16!ACC POPND_XTRA=BML<<16!DML PPTYPE=X'51' IF PTRSIZE(PTYPE&255)>4 THEN PPTYPE=X'61' NAMEOPND_D=BRECTRIP(GETPTR,PPTYPE,0,NAMEOPND,POPND) NAMEOPND_PTYPE=PPTYPE IF TARGET=EMAS THEN TRIPLES(NAMEOPND_D)_X1=J ! TO FIND SIZE OF STRINGARRAYNAME ! EMAS NEEDS DIMENSIONALITY FINISH ELSE START IF Z=2 OR Z=5 START ; ! FETCHING RETURN UNLESS NAMEOPND_FLAG=INDIRECT NAMEOPND_D=URECTRIP(PRELOAD,PTYPE,0,NAMEOPND) FINISH ELSE START ; ! Z=4 GET ADDRESS NAMEOPND_D=URECTRIP(GETAD,X'51',0,NAMEOPND) NAMEOPND_PTYPE=X'51'; ! ADDRESS IS 32 BIT INTEGER FINISH FINISH NAMEOPND_FLAG=REFTRIP NAMEOPND_XTRA=0 RETURN BIGACC(2): ! ALL ACCESS=2 IF NAMEP&X'FFFF'#X'FFFF' START NAMEOPND_PTYPE=PTYPE; NAMEOPND_FLAG=INDNAME NAMEOPND_D=NAMEP&X'FFFF' NAMEOPND_XTRA=X'80000000' ->ADOP FINISH EXPOPND_PTYPE=PTYPE; EXPOPND_FLAG=LOCALIR EXPOPND_D=BASE<<16!DISP BIGACC(3): ! ACCESS=3 IF EXPOPND_FLAG#REFTRIP START KK=URECTRIP(PRELOAD,EXPOPND_PTYPE,0,EXPOPND) EXPOPND_PTYPE=PTYPE; EXPOPND_FLAG=REFTRIP EXPOPND_D=KK FINISH NAMEOPND_PTYPE=PTYPE; NAMEOPND_FLAG=INDIRECT NAMEOPND_D=EXPOPND_D NAMEOPND_XTRA=X'80000000'; ! OFFSET NOT RELEVANT PERQ ONLY DISTINCTION ->ADOP BIGACC(4): ! ALL ACCESS=4 IF NAMEP&X'FFFF'#X'FFFF' START NAMEOPND_PTYPE=PTYPE; NAMEOPND_FLAG=DNAME NAMEOPND_D=NAMEP&X'FFFF' NAMEOPND_XTRA=XDISP FINISH ELSE START NAMEOPND_PTYPE=PTYPE; NAMEOPND_FLAG=LOCALIR NAMEOPND_D=DISP+XDISP IMPABORT IF TARGET=PNX; ! ABOVE LINE DOES NOT WORK ON PNX ! BUT PDS CANT FATHOM WHAT SORT ! OF SOURCE CODING CAN EVER REACH HERE NAMEOPND_XTRA=0 FINISH ->ADOP BIGACC(6): ! ALL ACCESS=6 IF NAMEP&X'FFFF'#X'FFFF' START NAMEOPND_PTYPE=PTYPE; NAMEOPND_FLAG=INDNAME NAMEOPND_D=NAMEP&X'FFFF' NAMEOPND_XTRA=XDISP; ->ADOP FINISH NAMEOPND_PTYPE=X'51'; NAMEOPND_FLAG=LOCALIR NAMEOPND_D=BASE<<16!DISP NAMEOPND_XTRA=0 KK=URECTRIP(PRELOAD,X'51',0,NAMEOPND) EXPOPND_PTYPE=PTYPE; EXPOPND_FLAG=REFTRIP EXPOPND_D=KK BIGACC(7): ! ALL ACCESS=7 NAMEOPND_PTYPE=PTYPE; NAMEOPND_FLAG=INDIRECT NAMEOPND_D=EXPOPND_D NAMEOPND_XTRA=XDISP ->ADOP BIGACC(8): ! ALL ACCESS=8 IF NAMEP&X'FFFF'#X'FFFF' START NAMEOPND_PTYPE=X'51'; NAMEOPND_FLAG=DNAME NAMEOPND_D=NAMEP&X'FFFF' NAMEOPND_XTRA=XDISP; XDISP=0 FINISH ELSE START NAMEOPND_PTYPE=X'51'; NAMEOPND_FLAG=LOCALIR NAMEOPND_D=BASE<<16!DISP NAMEOPND_XTRA=0 FINISH KK=URECTRIP(GETAD,X'51',0,NAMEOPND) EXPOPND_PTYPE=X'51'; EXPOPND_FLAG=REFTRIP EXPOPND_D=KK ->BIGACC(11); ! HAS BECOME ACESS=11 BIGACC(10): ! ALL ACCESS=10 IF NAMEP&X'FFFF'#X'FFFF' START NAMEOPND_PTYPE=X'51'; NAMEOPND_FLAG=INDNAME NAMEOPND_D=NAMEP&X'FFFF' NAMEOPND_XTRA=XDISP; XDISP=0 FINISH ELSE START NAMEOPND_PTYPE=X'51'; NAMEOPND_FLAG=LOCALIR NAMEOPND_D=BASE<<16!DISP KK=URECTRIP(GETAD,X'51',0,NAMEOPND) NAMEOPND_FLAG=VIAPTR; NAMEOPND_D=KK NAMEOPND_XTRA=0 FINISH KK=URECTRIP(GETAD,X'51',0,NAMEOPND) EXPOPND_D=KK EXPOPND_FLAG=REFTRIP BIGACC(11): ! ALL ACCESS=11 NAMEOPND_PTYPE=PTYPE; NAMEOPND_FLAG=VIAPTR NAMEOPND_D=EXPOPND_D NAMEOPND_XTRA=XDISP ->ADOP END ROUTINE CRCALL(INTEGER RTNAME) !*********************************************************************** !* COMPILE A ROUTINE OR FN CALL * !* THE PROCEDURE CONSIST OF THREE PARTS:- * !* A) PLANT THE PARAMETER (IF ANY) * !* B) ENTER THE ROUTINE OR FN * !* C) FORGET ANY REGISTERS WHICH HOLD ENTITIES THAT CAN BE * !* ALTERED BY THE CALLED PROCEDURE. * !*********************************************************************** INTEGER II,III,QQQ,JJ,JJJ,NPARMS,PT,LP,PSIZE,TWSP,PARMNO,ERRNO,FPTR,C TYPEP,PRECP,NAMP,TL,CLINK,PSPECED,OUTP RECORD (RD)OPND,OPND2 RECORD (LISTF)NAME LCELL PT=PTYPE; JJJ=J; TL=OLDI TWSP=0; FPTR=0 LP=I; CLINK=K TYPEP=TYPE; PRECP=PREC; NAMP=NAM IF CLINK=0 THEN PSPECED=0 ELSE PSPECED=ASLIST(CLINK)_S3&255 ! BEGIN INTEGERARRAY ARP(0:PSPECED) SWITCH FPD(0:3) ! NOW CHECK THAT THE RIGHT NUMBER OF PARAMETERS HAVE BEEN PROVIDED ! ALSO NOTE THE POINTERS TO ACTUAL PARAMETERS ALLOWING FOC 'C' COMPATABILITY ! P=P+2 NPARMS=0 WHILE A(P)=1 CYCLE P=P+1 IF NPARMS<PSPECED START IF PARAMS BWARDS=YES THEN ARP(PSPECED-NPARMS)=P C ELSE ARP(NPARMS+1)=P FINISH NPARMS=NPARMS+1 SKIP EXP REPEAT OUTP=P IF PSPECED#NPARMS THEN START ! WRONG NO OF PARAMETERS GIVEN IF PSPECED=0 THEN ERRNO=17 ELSE START IF NPARMS<PSPECED THEN ERRNO=18 ELSE ERRNO=19 FINISH FAULT(ERRNO,IMOD(PSPECED-NPARMS),RTNAME) SKIP APP; P=P-1 NAMEOPND=0; NAMEOPND_PTYPE=X'51';! ENSURE SENSIBLE RESULT TRIPLE ->OVER FINISH ! II=UNAMETRIP(PRECL,PT&255,0,RTNAME) PARMNO=0 ->FIRST PARM ! BAD PARM: ! BAD PARAMETER FAULT IT FAULT(22,PARMNO,RTNAME) NEXT PARM:CLINK=LCELL_LINK FIRSTPARM:->ENTRY SEQ IF CLINK=0; ! DEPART AT ONCE IF NO PARAMS LCELL==ASLIST(CLINK) PSIZE=LCELL_ACC PARMNO=PARMNO+1 P=ARP(PARMNO) PTYPE=LCELL_PTYPE UNPACK II=TYPE;III=PREC JJ=(NAM<<1!ARR)&3 ->BAD PARM UNLESS (JJ=0 AND ROUT=0) OR C (A(P+3)=4 AND A(P+4)=1 AND A(P+FROMAR2(P+1)+1)=2) OPND_PTYPE=PTYPE; OPND_FLAG=DNAME OPND_D=RTNAME OPND_XTRA=PARMNO<<24!CLINK ! ! RT TYPE PARAMS, PASS 4 WORDS AS SET UP BY QCODE INSTRN LVRD ! IF ROUT=1 THEN START II=PTYPE; P=P+5 CNAME(13); ! SET UP 4 WDS IN ACC ->BAD PARM IF II&255#PTYPE&255;! PREC&TYPE SIMILAR P=P+1 II=BRECTRIP(PASS4,X'61',0,OPND,NAMEOPND) FPTR=FPTR+RTPARAMSIZE ->NEXT PARM FINISH ->FPD(JJ) FPD(0): ! VALUE PARAMETERS IF TYPE=3 START ; ! RECORDS BY VALUE II=TSEXP(III); ! CHECK FOR ZERO AS RECORD VALUE IF II=1 AND III=0 START EXPOPND_PTYPE=X'51'; EXPOPND_FLAG=SCONST EXPOPND_D=0 FINISH ELSE START P=ARP(PARMNO); ! RESET NEEDED AFTER TSEXP ->BAD PARM UNLESS A(P+3)=4 AND A(P+4)=1 AND C A(P+FROMAR2(P+1)+1)=2 P=P+5 CNAME(3) P=P+1 JJ=1 EXPOPND=NAMEOPND ->BAD PARM UNLESS ACC=PSIZE FINISH FPTR=FPTR+PSIZE IF TARGET=EMAS THEN FPTR=FPTR+8;! TIRESOME BACK COMPATIBILITY ! WITH EMAS IMP ON RECORD VALUES FINISH ELSE IF TYPE=5 THEN START IF STRVALINWA=YES START ; ! USING WORK AREA (2900) CSTREXP(17) PUSH(TWSP,VALUE,0,0); ! REMEBER WA FPTR=FPTR+PTRSIZE(X'35') FINISH ELSE START CSTREXP(0) FPTR=FPTR+ACC FINISH FINISH ELSE START CSEXP(III<<4!II) FPTR=FPTR+BYTES(III) FINISH II=BRECTRIP(PASS1,PTYPE&255,0,OPND,EXPOPND) FPTR=(FPTR+MINPARAMSIZE-1)&(-MINPARAMSIZE) ->NEXT PARM ! FPD(2): ! NAME PARAMETERS P=P+5 IF II#0 START ; ! NOT A GENERAL NAME CNAME(3) ->BAD PARM UNLESS II=TYPE AND III=PREC JJ=PTRSIZE(III<<4!II) II=BRECTRIP(PASS2,PTYPE&255,0,OPND,NAMEOPND) FPTR=FPTR+JJ FINISH ELSE START FNAME=FROM AR2(P) COPY TAG(FNAME) OPND2_PTYPE=X'51'; OPND2_FLAG=SCONST OPND2_D=ACC<<16!PTYPE OPND2_XTRA=0 IF TYPE#0 START ; ! NOT GENERAL NAME PASSED AS NAME CNAME(4) FINISH ELSE START ; ! NAME AS GENERAL NAME NAMEOPND_PTYPE=PTYPE; NAMEOPND_FLAG=DNAME NAMEOPND_D=FNAME NAMEOPND_XTRA=X'80000000' FINISH EXPOPND_D=BRECTRIP(CTGEN,X'61',0,NAMEOPND,OPND2) EXPOPND_PTYPE=X'61'; EXPOPND_FLAG=REFTRIP EXPOPND_XTRA=0 II=BRECTRIP(PASS5,X'61',0,OPND,EXPOPND) FPTR=FPTR+PTRSIZE(0) FINISH P=P+1 ->NEXT PARM FPD(1):FPD(3): ! ARRAY NAME (&VALUE) ! ! FOR ARRAYNAME PARAMETERS THE NO OF DIMENSIONS OF THE ARRAY IS ! DEDUCED FROM THE FIRST CALL AND STORED IN STREAM3 OF THE PARAMETER ! LIST. ON ANY SUBSEQUENT CALL ONLY ARRAYS OF THE SAME DIMENSION CAN ! BE PASSED ! P=P+5 CNAME(12) P=P+1 ->BAD PARM UNLESS 1<=ARR<=2 AND II=TYPE AND III=PREC II=BRECTRIP(PASS3,PTYPE&255,0,OPND,NAMEOPND) QQQ=ASLIST(TCELL)_UIOJ&15; ! DIMENSION OF ACTUAL(IF KNOWN) JJ=LCELL_UIOJ&15; ! DIMENSION OF FORMAL IF JJ=0 THEN JJ=QQQ AND LCELL_UIOJ=LCELL_UIOJ!JJ IF QQQ=0 THEN QQQ=JJ AND ASLIST(TCELL)_UIOJ=ASLIST(TCELL)_UIOJ!JJ ->BAD PARM UNLESS JJ=QQQ FPTR=FPTR+AHEADSIZE ->NEXT PARM ENTRY SEQ: ! CODE FOR RT ENTRY WHILE TWSP>0 CYCLE POP(TWSP,QQQ,JJ,III); ! ONLY IF STR VALS & EMAS RETURN WSP(QQQ,268) REPEAT IF STRRESINWA=YES AND NAMP<=1 AND (TYPEP=3 OR TYPEP=5) START GET WSP(QQQ,268); ! AUTOMATIC RETURN OPND2_PTYPE=PT OPND2_FLAG=LOCALIR OPND2_D=RBASE<<16!QQQ OPND2_XTRA=268 II=BRECTRIP(PASS6,PT,0,OPND,OPND2) FPTR=FPTR+PTRSIZE(X'35') FINISH II=UNAMETRIP(RCALL,PT&255,0,RTNAME) TRIPLES(II)_OPND1_XTRA=FPTR; ! PASS PARAM SIZE TOTAL CURRINF_NMDECS=CURRINF_NMDECS!2 ROUT=1; TYPE=TYPEP; NAM=NAMP PREC=PRECP; PTYPE=PT ! ! RECOVER THE RESULT OF FNS & MAPS. OFTEN NOCODE WILL BE NEEDED ! IF PT&255#0 START IF NAM>=2 THEN II=RCRMR ELSE II=RCRFR II=UNAMETRIP(II,PT&255,0,RTNAME) IF STRRESINWA =YES THEN C TRIPLES(II)_OPND1_XTRA=QQQ; ! WORK AREA OFFSET NAMEOPND_PTYPE=PT&255; NAMEOPND_FLAG=REFTRIP NAMEOPND_D=II NAMEOPND_XTRA=0 FINISH OVER: P=OUTP END ; ! OF INNER BLOCK END INTEGERFN TSEXP(INTEGERNAME VALUE) SWITCH SW(1:3) INTEGER PP,REXP,KK,SIGN,CT TYPE=1; PP=P REXP=2-A(P+1+FROM AR2(P+1)) P=P+3 SIGN=A(P) ->TYPED UNLESS SIGN=4 OR A(P+1)=2 ->SW(A(P+1)) SW(1): ! NAME P=P+2; REDUCE TAG ->TYPED SW(2): ! CONSTANT CT=A(P+2); TYPE=CT&7 ->TYPED UNLESS CT=X'41' AND SIGN#3 KK=FROMAR2(P+3) ->TYPED UNLESS REXP=0 AND 0<=KK<=255 VALUE=KK P=P+6 IF SIGN#2 THEN RESULT =1 VALUE=-VALUE; RESULT =-1 SW(3): ! SUB EXPRN TYPED: P=PP; RESULT =0 END ROUTINE SKIP EXP !*********************************************************************** !* SKIPS OVER THE EXPRESSION POINTED AT BY P. USED FOR ERROR * !* RECOVERY AND TO EXTRACT INFORMATION ABOUT THE EXPRESSION. * !*********************************************************************** INTEGER OPTYPE, PIN, J PIN=P P=P+3; ! TO P<+'> CYCLE ; ! DOWN THE LIST OF OPERATORS OPTYPE=A(P+1); ! ALT OF P<OPERAND> P=P+2 IF OPTYPE=0 OR OPTYPE>3 THEN IMPABORT IF OPTYPE=3 THEN SKIP EXP; ! SUB EXPRESSIONS ! IF OPTYPE=2 THEN START ; ! OPERAND IS A CONSTANT J=A(P)&7; ! CONSTANT TYPE IF J=5 THEN P=P+A(P+1)+2 ELSE P=P+1+BYTES(A(P)>>4) FINISH ! IF OPTYPE=1 THEN START ; ! NAME P=P-1 P=P+3 AND SKIP APP UNTIL A(P)=2 ;! TILL NO ENAME P=P+1 FINISH ! P=P+1 IF A(P-1)=2 THEN EXIT ; ! NO MORE REST OF EXP REPEAT END ; ! OF ROUTINE SKIP EXP ROUTINE SKIP APP !*********************************************************************** !* SKIPS ACTUAL PARAMETER PART * !* P IS ON ALT OF P<APP> AT ENTRY * !*********************************************************************** INTEGER PIN PIN=P P=P+1 AND SKIP EXP WHILE A(P)=1 P=P+1 END ROUTINE NO APP P=P+2 IF A(P)=1 THEN START ; ! <APP> PRESENT FAULT(17,0,FROM AR2(P-2)) SKIP APP FINISH ELSE P=P+1; ! P NOW POINTS TO ENAME END ROUTINE TEST APP(INTEGERNAME NUM) !*********************************************************************** !* THIS ROUTINE COUNTS THE NUMBER OF ACTUAL PARAMETERS * !* WHICH IT RETURNS IN NUM. * !*********************************************************************** INTEGER PP, Q Q=0; PP=P; P=P+2; ! P ON NAME AT ENTRY WHILE A(P)=1 CYCLE ; ! NO (MORE) PARAMETERS P=P+1; Q=Q+1 SKIP EXP REPEAT P=PP; NUM=Q END ROUTINE SET LINE !*********************************************************************** !* UPDATE THE STATEMENT NO * !*********************************************************************** INTEGER I RETURN IF RLEVEL=0; ! AMONG CONDITIONAL GLOBAL DECS I=UCONSTTRIP(SLINE,X'41',0,LINE<<16!CURRINF_DIAGINF+2) IF PARM_PROF#0 THEN START I=PROFAAD+4+4*LINE FINISH END ROUTINE STORE TAG(INTEGER KK, LEVEL,RBASE,J,SNDISP,ACC,SLINK,KFORM) INTEGER Q, I, TCELL RECORD (TAGF)NAME LCELL TCELL=TAGS(KK) Q=LEVEL<<8!RBASE<<4!J IMPABORT UNLESS (KFORM!ACC)>>16=0 LCELL==ASLIST(TCELL) IF LCELL_UIOJ>>8&63=LEVEL THEN START FAULT(7,0,KK) LCELL_UIOJ<-LCELL_UIOJ&X'C000'!Q;! COPY USED BITS ACCROSS FINISH ELSE START I=ASL; IF I=0 THEN I=MORE SPACE LCELL==ASLIST(I) ASL=LCELL_LINK LCELL_LINK=TCELL!CURRINF_NAMES<<18 LCELL_UIOJ=Q TAGS(KK)=I CURRINF_NAMES=KK FINISH LCELL_PTYPE<-PTYPE LCELL_ACC=ACC LCELL_SNDISP=SNDISP LCELL_KFORM=KFORM LCELL_SLINK=SLINK END ROUTINE COPY TAG(INTEGER TNAME) !*********************************************************************** !* A TAG IS A LIST CELL POINTED AT BY TAGS(NAME) * !* S1 HAS PTYPE<<16!USEBITS(2)!TEXT LEVEL(OLDI6)!RTLEVE(4)!DIMEN * !* S2 HAS SECONDARY DISP(SIGNED)<<16! ACC OR ITEM SIZE IN BYTES * !* S3 HAS PRIMARY DISP(K)<<16!KFORM WHICH IS POINTER TO FORMAT * !* SIDE CHAIN FOR ITEMS OF TYPE RECORD * !* LINK HAS PTR TO TAG OF NAME HIDDEN WHEN THIS ONE DECLARED * !*********************************************************************** RECORD (TAGF)NAME LCELL TCELL=TAGS(TNAME) IF TCELL=0 THEN START ; ! NAME NOT SET TYPE=7; PTYPE=X'57'; PREC=5 ROUT=0; NAM=0; ARR=0; LITL=0; ACC=4 I=-1; J=-1; K=-1; OLDI=-1 FINISH ELSE START LCELL==ASLIST(TCELL) LCELL_UIOJ<-LCELL_UIOJ!X'8000' MIDCELL=LCELL_S2 PTYPE=LCELL_PTYPE; USEBITS=LCELL_UIOJ>>14&3 OLDI=LCELL_UIOJ>>8&63; I=LCELL_UIOJ>>4&15; J=LCELL_UIOJ&15 SNDISP=LCELL_SNDISP ACC=LCELL_ACC K=LCELL_SLINK; KFORM=LCELL_KFORM LITL=PTYPE>>14&3; ! SIGNEXTENSION ON 16 BIT MACHINES ROUT=PTYPE>>12&3 NAM=PTYPE>>10&3 ARR=PTYPE>>8&3 PREC=PTYPE>>4&15 TYPE=PTYPE&15 FINISH END ROUTINE REDUCE TAG !*********************************************************************** !* AS COPY TAG FOR NAME AT A(P) EXCEPT:- * !* 1) SPECIAL NAMES HAVE THEIR CORRECT PREC & TYPE SUBSTITUTED * !* 2) RECORD ELEMENTS HAVE THE SUBNAME PARTICULARS RETURNED * !*********************************************************************** INTEGER SUBS,QQ,PP COPY TAG(FROMAR2(P)) IF PTYPE=SNPT THEN START PTYPE=ACC; UNPACK ROUT=1 FINISH ; ! TO AVOID CHECKING PARAMS IF TYPE=3 THEN START PP=P; QQ=COPY RECORD TAG(SUBS); P=PP FINISH END ! LAYOUT OF PTYPE ! ****** ** ***** ! PTYPE REQUIRES 16 BITS TO DEFINE A VARIABLE AND CAN BE REGARDED AS ! AS TWO BYTEINTEGERS:= ! UPPER ONE(UPTYPE):= LITL<<6!ROUT<<4!NAM<<2!ARR ! LOWER ONE(PTYPE) :=PREC<<4!TYPE ! OFTEN (EG IN EXPOP) ONLY THE LOWER PART IS REQUIRED AS FUNCTIONS ! ETC ARE PREFETCHED AND STACKED. ! LITL:= 1=CONST,2=EXTERNAL,3=EXTRINSIC(OR DYNAMIC), 0=NONE OF THESE ! ROUT:= 1 FOR ROUTINE OR FN OR MAP, =0 NONE OF THESE ! NAM := 2 FOR MAPS AND 'REFREFS',=1 FOR NAMES ,=0 DIRECTLY ADDRESSED ! ARR :=1 FOR ARRAYS =0 SCALARS ! PREC IS DESCRIPTOR SIZE CODE FOR EACH PRECISION:- ! :=0 BITS,=3 BYTES, =5 WORDS, =6 D-WRDS, =7,QUAD WRDS ! TYPE:= THE VARIABLE TYPE ! :=0 (TYPE GENERAL),=1 INTEGER, =2 REAL, =3 RECORD ! :=4 (RECORDFORMAT),=5 STRING, =6 LABEL/SWITCH. =7 NOT SET ! ROUTINE UNPACK LITL=PTYPE>>14 ROUT=PTYPE>>12&3 NAM=PTYPE>>10&3 ARR=PTYPE>>8&3 PREC=PTYPE>>4&15 TYPE=PTYPE&15 END ROUTINE PACK(INTEGERNAME PTYPE) PTYPE=(((((LITL&3)<<2!ROUT&3)<<2!NAM&3)<<2!ARR&3)<<4! C PREC&15)<<4!TYPE&15 END END ; ! OF ROUTINE CSS INTEGERFN NEWTRIP !*********************************************************************** !* SETS UP A NEW TRIPLE AND LINKS IT IN !*********************************************************************** RECORD (TRIPF)NAME CURRT INTEGER I CURRT==TRIPLES(NEXT TRIP) I=NEXT TRIP IF I>=WORKA_LAST TRIP THEN FAULT(102,WORKA_WKFILEK,0) NEXT TRIP=NEXT TRIP+1 CURRT=0 CURRT_BLINK=TRIPLES(0)_BLINK TRIPLES(0)_BLINK=I TRIPLES(CURRT_BLINK)_FLINK=I RESULT =I END INTEGERFN UCONSTTRIP(INTEGER OPERN,OPTYPE,FLAGS,CONST) !*********************************************************************** !* SETS UP A UNARY TRIPLE WITH CONSTANT OPERAND * !*********************************************************************** RECORD (TRIPF) NAME CURRT INTEGER CELL CELL = NEW TRIP CURRT == TRIPLES(CELL) CURRT_OPERN = OPERN CURRT_OPTYPE <- OPTYPE CURRT_FLAGS <- FLAGS CURRT_OPND1_S1 = X'00510000' CURRT_OPND1_D = CONST RESULT = CELL END INTEGERFN ULCONSTTRIP(INTEGER OPERN,OPTYPE,FLAGS,CONST1,CONST2) !*********************************************************************** !* SETS UP A UNARY TRIPLE WITH CONSTANT OPERAND * !*********************************************************************** RECORD (TRIPF) NAME CURRT INTEGER CELL CELL = NEW TRIP CURRT == TRIPLES(CELL) CURRT_OPERN = OPERN CURRT_OPTYPE <- OPTYPE CURRT_FLAGS <- FLAGS CURRT_OPND1_S1 = X'00610000' CURRT_OPND1_D = CONST1 CURRT_OPND1_XTRA=CONST2 RESULT = CELL END INTEGERFN UNAMETRIP(INTEGER OPERN,OPTYPE,FLAGS,NAME) !*********************************************************************** !* SETS UP A UNARY TRIPLE WITH ONE NAME OPERAND * !*********************************************************************** RECORD (TAGF) NAME TAGINF RECORD (TRIPF) NAME CURRT INTEGER CELL TAGINF == ASLIST(TAGS(NAME)) CELL = NEW TRIP CURRT == TRIPLES(CELL) CURRT_OPERN = OPERN CURRT_OPTYPE <- OPTYPE CURRT_FLAGS <- FLAGS CURRT_OPND1_PTYPE = TAGINF_PTYPE CURRT_OPND1_FLAG=DNAME CURRT_OPND1_D = NAME CURRT_OPND1_XTRA = 0 RESULT = CELL END INTEGERFN UTEMPTRIP(INTEGER OPERN,OPTYPE,FLAGS,TEMP) !*********************************************************************** !* SETS UP A UNARY TRIPLE WITH LOCAL TEMPORARY OPND * !*********************************************************************** INTEGER CELL RECORD (TRIPF)NAME CURRT CELL=NEWTRIP CURRT==TRIPLES(CELL) CURRT_OPERN=OPERN CURRT_OPTYPE<-OPTYPE CURRT_FLAGS<-FLAGS CURRT_OPND1_PTYPE=OPTYPE; CURRT_OPND1_FLAG=LOCALIR CURRT_OPND1_D=TEMP RESULT =CELL END ROUTINE KEEPUSECOUNT(RECORD (RD)NAME OPND) !*********************************************************************** !* KEEPS PUSE AND CNT UP TO DATE * !*********************************************************************** RECORD (TRIPF)NAME REFT REFT==TRIPLES(OPND_D) IF REFT_CNT=0 THEN REFT_PUSE=TRIPLES(0)_BLINK REFT_CNT=REFT_CNT+1 END INTEGERFN URECTRIP(INTEGER OPERN,OPTYPE,FLAGS,RECORD (RD)NAME OPND1) !*********************************************************************** !* SETS UP A BINARY TRIPLE WITH COMPLETE OPERANDS PROVIDED * !*********************************************************************** INTEGER CELL RECORD (TRIPF) NAME CURRT CELL=NEWTRIP CURRT==TRIPLES(CELL) CURRT_OPERN=OPERN CURRT_OPTYPE<-OPTYPE CURRT_FLAGS<-FLAGS CURRT_OPND1=OPND1 IF 1<<OPND1_FLAG&BTREFMASK#0 THEN KEEPUSECOUNT(OPND1) RESULT =CELL END INTEGERFN BRECTRIP(INTEGER OPERN,OPTYPE,FLAGS,RECORD (RD)NAME OPND1,OPND2) !*********************************************************************** !* SETS UP A BINARY TRIPLE WITH COMPLETE OPERANDS PROVIDED * !*********************************************************************** INTEGER CELL RECORD (TRIPF) NAME CURRT CELL=NEWTRIP CURRT==TRIPLES(CELL) CURRT_OPERN=OPERN CURRT_OPTYPE<-OPTYPE CURRT_FLAGS<-FLAGS CURRT_OPND1=OPND1 CURRT_OPND2=OPND2 IF 1<<OPND1_FLAG&BTREFMASK#0 THEN KEEP USE COUNT(OPND1) IF 1<<OPND2_FLAG&BTREFMASK#0 THEN KEEP USE COUNT(OPND2) RESULT =CELL END ROUTINE GET WSP(INTEGERNAME PLACE,INTEGER SIZE) !*********************************************************************** !* FIND OR CREATE A TEMPORARY VARIABLE OF 'SIZE' WORDS * !*********************************************************************** INTEGER J,K,L,F F=SIZE>>31; ! TOP BIT SET FOR MANUAL RETURN ! OTHERWISE NOTE IN TWSP LIST ! FOR AUTOMATIC RETURN SIZE=SIZE<<1>>1 IF SIZE>4 THEN SIZE=0 POP(CURRINF_AVL WSP(SIZE),J,K,L) IF K<=0 THEN START ; ! MUST CREATE TEMPORARY K=N IF SIZE=0 THEN N=N+268 ELSE N=N+SIZE<<2 FINISH PLACE=K PUSH(TWSPHEAD,K,SIZE,0) UNLESS F#0 END ROUTINE RETURN WSP(INTEGER PLACE,SIZE) !*********************************************************************** !* RETURNS WORKSPACE TO ORDERED FREE LIST. ADDRESSABLE CELLS * !* ARE PUT AT THE TOP. NON-ADDRESSABLE ON THE BACK * !*********************************************************************** INTEGER CELL IMPABORT UNLESS PLACE<=N AND PLACE&1=0 IF SIZE>4 THEN SIZE=0 CELL=CURRINF_AVL WSP(SIZE) WHILE CELL>0 CYCLE IMPABORT IF ASLIST(CELL)_S2=PLACE CELL=ASLIST(CELL)_LINK REPEAT IF PLACE<511 THEN PUSH(CURRINF_AVL WSP(SIZE),0,PLACE,0) C ELSE INSERT AT END(CURRINF_AVL WSP(SIZE),0,PLACE,0) END ROUTINE REUSE TEMPS INTEGER JJ,KK,QQ WHILE TWSPHEAD#0 CYCLE POP(TWSPHEAD,JJ,KK,QQ) RETURN WSP(JJ,KK) REPEAT END INTEGERFN FROMAR2(INTEGER PTR) RESULT =A(PTR)<<8!A(PTR+1) END INTEGERFN FROMAR4(INTEGER PTR) INTEGER I MOVE BYTES(4,ADDR(A(0)),PTR,ADDR(I),0) RESULT =I END P2END: ! EXITS AFTER COMPILATION END ; ! OF SUBBLOCK CONTAINING PASS2 END ENDOFFILE