63000 (* COPYRIGHT 1983 C.H.LINDSEY, UNIVERSITY OF MANCHESTER *) 63010 (**) 63020 (*+84() 63030 (**) 63040 (**) 63050 (*MODE HANDLING*) 63060 (***************) 63070 (**) 63080 FUNCTION LENGTHEN(M: MODE; COUNT: INTEGER): MODE; 63090 (*FUNCTION: RETURNS A LONG OR SHORT MODE DERIVED FROM M*) 63100 BEGIN 63110 LENGTHEN := M; (*DEFAULT*) 63120 IF COUNT<0 THEN 63130 SEMERR(ESE+06) (*NO SHORT MODES IMPLEMENTED*) 63140 ELSE BEGIN 63150 (*WHEN LONG MODES ARE IMPLEMENTED, SPECIFIC TESTS MUST BE MADE HERE 63160 FOR MDINT, MDREAL AND MDCOMPL, AND THE APPROPRIATE LONG VERSIONS RETURNED*) 63170 IF COUNT>0 THEN 63180 (*+61() IF (COUNT=1) AND (M=MDREAL) THEN LENGTHEN := MDLREAL 63190 ELSE IF (COUNT=1) AND (M=MDCOMPL) THEN LENGTHEN := MDLCOMPL 63200 ELSE ()+61*) 63210 SEMERR(ESE+19) 63220 END; 63230 END; 63240 (**) 63250 (**) 63260 FUNCTION TX (*-01() (M: MODE): XTYPE ()-01*); 63270 BEGIN 63280 IF M=MDCOMPL THEN TX := 4 63290 (*+61() ELSE IF M=MDLCOMPL THEN TX := 5 ()+61*) 63300 ELSE TX := MODEID[M^.MDV.MDID] 63310 END; 63320 (**) 63330 (**) 63340 PROCEDURE THIPMD(HIP, M: MODE); 63350 (*FUNCTION: ENSURES THAT THE MODE M IS SUITABLE FOR HIPPING LIKE HIP*) 63360 BEGIN WITH HIP^.MDV DO 63370 IF MDID IN [MDIDSKIP,MDIDJUMP,MDIDNIL] THEN 63380 BEGIN 63390 IF MDID=MDIDJUMP THEN 63400 IF M^.MDV.MDID=MDIDPROC THEN SEMERR(ESE+40) ELSE (*NO ACTION*) 63410 ELSE IF MDID=MDIDNIL THEN 63420 IF M^.MDV.MDID<>MDIDREF THEN SEMERR(ESE+21); 63430 IF M^.MDV.MDID IN [MDIDCOVER,MDIDBNDS,MDIDABSENT] THEN SEMERR(ESE+33) 63440 (*TO CATCH NOSEY PARKERS WHO TRY TO MANUFACTURE .FILES*) 63450 END 63460 END; 63470 (**) 63480 (**) 63490 FUNCTION TUNITED(M: MODE): BOOLEAN; 63500 (*FUNCTION: TESTS WHETHER M IS A UNITED MODE*) 63510 BEGIN WITH M^ DO 63520 IF MDV.MDID=MDIDROW THEN 63530 TUNITED := TUNITED(MDPRRMD) 63540 ELSE 63550 TUNITED := (MDV.MDID>=MDIDOUT) AND (MDV.MDID<=MDIDROWS) 63560 END; 63570 (**) 63580 (**) 63590 PROCEDURE TCOLL; 63600 (*FUNCTION: ENSURES THAT NO UNIT ON THE SUBSTACK IS A COLLATERAL*) 63610 VAR SEMP: -1..SRSTKSIZE; 63620 BEGIN 63630 IF BALFLAG THEN SEMP := SRSUBP+1 ELSE SEMP := SRSEMP; 63640 WHILE SEMP<=SRSEMP DO 63650 BEGIN 63660 IF SBCOLL IN SRSTK[SEMP].SB^.SBINF THEN SEMERR(ESE+18); 63670 SEMP := SEMP+1 63680 END 63690 END; 63700 (**) 63710 (**) 63720 FUNCTION DEPASCAL(PASC: MODE): MODE; 63730 VAR TEMPM: MODE; 63740 I: INTEGER; 63750 BEGIN WITH PASC^ DO BEGIN 63760 ENEW(TEMPM, MDV.MDCNT*SZADDR + MODE1SIZE); 63770 FOR I := 1 TO (MDV.MDCNT*SZADDR+MODE1SIZE) DIV SZWORD DO 63780 TEMPM^.MDWORDS[I] := MDWORDS[I]; 63790 WITH TEMPM^ DO 63800 BEGIN 63810 MDV := MDVPROC; 63820 MDV.MDCNT := PASC^.MDV.MDCNT; 63830 MDLINK := PROCL 63840 END; 63850 PROCL := TEMPM; 63860 FIND(PROCL, FALSE, MDV.MDCNT*SZADDR); 63870 DEPASCAL := PROCL; 63880 END 63890 END; 63900 (**) 63910 (**) 63920 PROCEDURE CGCSUPP(SB: PSB; M: MODE; ROWCOUNT: INTEGER); 63930 (*FUNCTION: GENERATES CODE TO COERCE THE UNIT REPRESENTED BY SB TO THE MODE M ROWED ROWCOUNT TIMES.*) 63940 VAR ROWM, NEWM: MODE; 63950 WIDTYP: STATE; 63960 OPCOD : POP; 63970 I, PSPACE: INTEGER; 63980 BEGIN WITH SB^ DO 63990 BEGIN 64000 WHILE SBMODE<>M DO WITH SBMODE^ DO 64010 BEGIN 64020 IF MDV.MDID=MDIDREF THEN 64030 BEGIN 64040 IF SBTYP=SBTVAR THEN SBTYP := SBTID 64050 ELSE IF SBWEAKREF IN SBINF THEN SBINF := SBINF-[SBWEAKREF] 64060 ELSE 64070 BEGIN 64080 GETTOTAL(SB); OPCOD := PDEREF; 64090 GENOP(OPCOD,MDPRRMD,OLIST3,NIL); 64100 IF GENDPOCV=OCVNONE THEN 64110 EMITX2(OPCOD,OCVSB,ORD(SB),OCVRES,ORD(SB)) 64120 ELSE EMITX3(OPCOD,OCVSB,ORD(SB),GENDPOCV,GENDPVAL,OCVRES,ORD(SB)) 64130 END; 64140 SBMODE := MDPRRMD; 64150 END 64160 ELSE IF MDV.MDDEPROC THEN 64170 BEGIN 64180 GETTOTAL(SB); 64190 IF MDV.MDID=MDIDPROC THEN 64200 CGDEPROC(SB) 64210 ELSE (*MDV.MDID=MDIDPASC*) 64220 CGPASC(SB, SB); 64230 SBMODE := MDPRRMD; 64240 END 64250 ELSE BEGIN 64260 GETTOTAL(SB); 64270 IF MDV.MDID<=MDIDSTRNG THEN 64280 BEGIN CASE MDV.MDID OF 64290 MDIDINT : BEGIN WIDTYP := 0; NEWM := MDREAL END; 64300 (*+61() MDIDLINT : BEGIN WIDTYP := 1; NEWM := MDLREAL END; ()+61*) 64310 MDIDREAL : BEGIN WIDTYP := 2; NEWM := MDCOMPL END; 64320 (*+61() MDIDLREAL: BEGIN WIDTYP := 3; NEWM := MDLCOMPL END; ()+61*) 64330 MDIDCHAR : BEGIN WIDTYP := 4; NEWM := MDSTRNG END; 64340 MDIDBITS : BEGIN WIDTYP := 5; NEWM := ROWBOOL END; 64350 MDIDBYTES: BEGIN WIDTYP := 6; NEWM := ROWCHAR END; 64360 MDIDSTRNG: BEGIN WIDTYP := 7; NEWM := ROWCHAR END; 64370 END; 64380 EMITX2(PWIDEN+WIDTYP,OCVSB,ORD(SB),OCVRES,ORD(SB)); 64382 SBMODE := NEWM; 64390 IF (SBMODE^.MDV.MDID=MDIDROW) AND (SBMODE^.MDPRRMD=M) AND (ROWCOUNT>0) THEN 64400 BEGIN ROWCOUNT := ROWCOUNT-1; M := SBMODE END 64410 END 64420 ELSE IF MDV.MDID=MDIDPASC THEN 64430 BEGIN 64432 PSPACE := 0; 64434 FOR I := 0 TO MDV.MDCNT-1 DO WITH MDPRCPRMS[I]^ DO 64436 IF MDV.MDPILE THEN PSPACE := PSPACE+SZADDR ELSE PSPACE := PSPACE+MDV.MDLEN; 64440 EMITX3(PLOADRTP, OCVSB, ORD(SB), OCVIMMED, PSPACE, OCVRES,ORD(SB)); 64450 SBMODE := DEPASCAL(SBMODE) 64460 END 64470 ELSE BEGIN 64480 IF M<>MDERROR THEN MODERR(SBMODE, ESE+33); 64490 SBMODE := M; SBTYP := SBTVOID; 64500 END; 64510 END; 64520 END; 64530 IF ROWCOUNT>0 THEN 64540 BEGIN 64550 GETTOTAL(SB); 64560 IF SBMODE^.MDV.MDID=MDIDROW THEN 64570 BEGIN 64580 WITH SBMODE^ DO ROWM := FINDROW(MDPRRMD, MDV.MDCNT+ROWCOUNT); 64590 EMITX3(PROWMULT, OCVSB, ORD(SB), OCVIMMED, ROWM^.MDV.MDCNT, OCVRES, ORD(SB)) 64600 END 64610 ELSE 64620 BEGIN 64630 ROWM := FINDROW(SBMODE, ROWCOUNT); 64640 GENDP(ROWM); 64650 EMITX4(PROWNONMULT, OCVSB, ORD(SB), OCVIMMED, ROWM^.MDV.MDCNT, GENDPOCV, GENDPVAL, OCVRES, ORD(SB)) 64660 END; 64670 SBMODE := ROWM; 64680 END 64690 END 64700 END; 64710 (**) 64720 (**) 64730 FUNCTION COSOFT(M: MODE): MODE; 64740 (*FUNCTION: FINDS SOFTEST COERCION OF M*) 64750 BEGIN 64760 WHILE M^.MDV.MDDEPROC DO 64770 M := M^.MDPRRMD; 64780 COSOFT := M 64790 END; 64800 (**) 64810 (**) 64820 FUNCTION COMEEK(SRCM: MODE): MODE; 64830 (*FUNCTION: MEEKLY COERCES SRCM AS FAR AS POSSIBLE 64840 YIELDS THE MODE REACHED. 64850 *) 64860 LABEL 9; 64870 BEGIN 64880 LASTPREF := MDVOID; LASTPROC := NIL; COERCLEN := 0; 64890 WHILE SRCM<>NIL DO WITH SRCM^ DO 64900 IF MDV.MDDEPROC THEN 64910 BEGIN LASTPROC := SRCM; LASTPREF := SRCM; COERCLEN := COERCLEN+1; SRCM := MDPRRMD END 64920 ELSE IF MDV.MDID=MDIDREF THEN 64930 BEGIN LASTPREF := SRCM; COERCLEN := COERCLEN+1; SRCM := MDPRRMD END 64940 ELSE GOTO 9; 64950 9:COMEEK := SRCM 64960 END; 64970 (**) 64980 (**) 64990 FUNCTION COFIRM(SRCM, DSTM: MODE): MODE; 65000 (*FUNCTION: FIRMLY COERCES SRCM AS FAR AS POSSIBLE IN THE DIRECTION OF DSTM. 65010 YIELDS THE MODE (POSSIBLY DSTM) REACHED. 65020 *) 65030 LABEL 9; 65040 BEGIN 65050 LASTPREF := MDVOID; LASTPROC := NIL; COERCLEN := 0; 65060 WHILE SRCM<>DSTM DO WITH SRCM^ DO 65070 IF MDV.MDDEPROC THEN 65080 BEGIN LASTPROC := SRCM; LASTPREF := SRCM; COERCLEN := COERCLEN+1; SRCM := MDPRRMD END 65090 ELSE IF MDV.MDID=MDIDREF THEN 65100 BEGIN LASTPREF := SRCM; COERCLEN := COERCLEN+1; SRCM := MDPRRMD END 65110 ELSE IF MDV.MDID=MDIDPASC THEN 65120 SRCM := DEPASCAL(SRCM) 65130 ELSE GOTO 9; 65140 9:COFIRM := SRCM 65150 END; 65160 (**) 65170 (**) 65180 FUNCTION COWEAK(M: MODE): MODE; 65190 (*FUNCTION: FINDS WEAKEST COERCION OF M*) 65200 BEGIN 65210 M := COMEEK(M); 65220 IF LASTPREF^.MDV.MDID=MDIDREF THEN 65230 M := LASTPREF; 65240 COWEAK := M 65250 END; 65260 (**) 65270 (**) 65280 FUNCTION TSTRENGTH(SRCM, DSTM: MODE): STRTYP; 65290 (*FUNCTION: DETERMINES THE STRENGTH OF COERCION NECESSARY TO GET FROM SRCM TO DSTM*) 65300 BEGIN 65310 IF DSTM=SRCM THEN TSTRENGTH := STREMPTY 65320 ELSE IF COSOFT(DSTM)=COSOFT(SRCM) THEN TSTRENGTH := STRSOFT 65330 ELSE IF COWEAK(DSTM)=COWEAK(SRCM) THEN TSTRENGTH := STRWEAK 65340 ELSE IF COMEEK(DSTM)=COMEEK(SRCM) THEN TSTRENGTH := STRMEEK 65350 ELSE TSTRENGTH := STRFIRM 65360 END; 65370 (**) 65380 (**) 65390 FUNCTION BALMOIDS(M1, M2: MODE): MODE; 65400 (*FUNCTION: RETURNS THE PIVOTAL MODE OF THE BALANCE M1/M2. 65410 ON EXIT, M1COERC AND M2COERC CONTAIN THE NECESSARY STRENGTHS. 65420 *) 65430 VAR FIRMM1, FIRMM2: MODE; 65440 LEN1, LEN2, DIFF, I: INTEGER; 65450 BEGIN 65460 M1COERC := STREMPTY; M2COERC := STREMPTY; 65470 IF (M1^.MDV.MDID>=MDIDSKIP) AND (M1^.MDV.MDID<=MDIDNIL) THEN 65480 BEGIN M1COERC := STRSTRONG; BALMOIDS := M2 END; 65490 IF (M2^.MDV.MDID>=MDIDSKIP) AND (M2^.MDV.MDID<=MDIDNIL) THEN 65500 BEGIN M2COERC := STRSTRONG; BALMOIDS := M1 END; 65510 IF (M1COERC=STREMPTY) AND (M2COERC=STREMPTY) THEN 65520 IF M1=M2 THEN BALMOIDS := M1 65530 ELSE BEGIN 65540 FIRMM1 := COFIRM(M1, NIL); LEN1 := COERCLEN; 65550 FIRMM2 := COFIRM(M2, NIL); LEN2 := COERCLEN; 65560 IF FIRMM1=FIRMM2 THEN 65570 BEGIN 65580 DIFF := LEN2-LEN1; 65590 IF DIFF>=0 THEN 65600 BEGIN FIRMM1 := M1; FIRMM2 := M2 END 65610 ELSE 65620 BEGIN FIRMM1 := M2; FIRMM2 := M1; DIFF := -DIFF END; 65630 FOR I := DIFF-1 DOWNTO 0 DO 65640 FIRMM2 := FIRMM2^.MDPRRMD; 65650 WHILE FIRMM1<>FIRMM2 DO 65660 IF FIRMM1^.MDV.MDID=MDIDPASC THEN 65670 BEGIN 65680 FIRMM1 := DEPASCAL(FIRMM1); 65690 FIRMM2 := DEPASCAL(FIRMM2) 65700 END 65710 ELSE 65720 BEGIN 65730 FIRMM1 := FIRMM1^.MDPRRMD; 65740 FIRMM2 := FIRMM2^.MDPRRMD 65750 END; 65760 M1COERC := TSTRENGTH(M1, FIRMM1); 65770 M2COERC := TSTRENGTH(M2, FIRMM1); 65780 BALMOIDS := FIRMM1 65790 END 65800 ELSE BEGIN 65810 WITH FIRMM1^.MDV DO 65820 IF MDID=MDIDROW THEN LEN1 := 100+MDCNT ELSE LEN1 := MODEID[MDID]; 65830 WITH FIRMM2^.MDV DO 65840 IF MDID=MDIDROW THEN LEN2 := 100+MDCNT ELSE LEN2 := MODEID[MDID]; 65850 IF LEN1M THEN 66080 BEGIN 66090 FIRMM := COFIRM(SBMODE,M); 66100 IF M=MDVOID THEN (*VOIDING COERCION NEEDED*) 66110 BEGIN 66120 IF (SBMORF IN SBINF) AND (LASTPROC<>NIL) THEN 66130 CGCSUPP(SB, LASTPROC^.MDPRRMD, 0); 66140 IF SBTYP>SBTDEN THEN (*THE VALUE IS ALREADY STORED SOMEWHERE*) 66150 BEGIN 66160 IF SBNAKED IN SBINF THEN BEGIN EMITX1(PVOIDNAKED,OCVSB,ORD(SB)); STACKSB(SB) END 66180 ELSE IF SBMODE^.MDV.MDPILE THEN BEGIN EMITX1(PVOIDNORMAL,OCVSB,ORD(SB)); STACKSB(SB) END 66182 ELSE IF SBTYP IN [SBTSTK..SBTSTKN] THEN EMITX1(PASP, OCVIMMED, SBMODE^.MDV.MDLEN); 66190 END; 66200 IF (SBVOIDWARN IN SBINF) AND (SBMODE<>MDVOID) THEN 66210 OUTERR(ESE+10, WARNING, NIL); 66220 SBINF := SBINF-[SBNAKED]; FILL(SBTVOID,SB); 66230 END 66240 ELSE IF TUNITED(M) THEN (*TRANSPUT COERCION*) 66250 BEGIN 66260 FIRMM := COMEEK(SBMODE); 66270 IF (FIRMM<>PRCVF) AND (FIRMM<>PASCVF) AND 66280 ((M=MDIN) OR (M=MDINB) OR (M=ROWIN) OR (M=ROWINB) OR (M=MDROWS)) THEN 66290 MM := COWEAK(SBMODE) 66300 ELSE IF FIRMM=MDSKIP THEN 66310 BEGIN MM := MDCHAR; FIRMM := MM END (*TO FORCE A RUN-TIME ERROR*) 66320 ELSE MM := FIRMM; 66330 CGCOERCE(SB, MM); 66340 IF M<>MDROWS THEN 66350 BEGIN 66360 IF FIRMM^.MDV.MDID=MDIDROW THEN 66370 MODENO := TX(FIRMM^.MDPRRMD)+16 66380 ELSE MODENO := TX(FIRMM); 66390 SB1 := PUSHSB(MDINT); SB1^.SBTYP := SBTLIT; SB1^.SBVALUE := MODENO; TWIST; LOADSTK(SB1); 66400 (*-01() IF (M^.MDV.MDID=MDIDNUMBER) AND (MODENO=0(*INT*)) THEN 66410 BEGIN 66420 SB2 := PUSHSB(MDINT); SB2^.SBLEN := SZREAL-SZINT; SB2^.SBINF := SB2^.SBINF+[SBUNION]; SB2^.SBTYP := SBTLIT; SB1^.SBVALUE := 0; TWIST; LOADSTK(SB2); 66430 GETTOTAL(SB); LOADSTK(SB); 66440 COMBINE; SBTYP := SBTSTKN; 66450 END; 66460 ()-01*) 66470 GETTOTAL(SB); 66480 FOR I:= SBDELAYS-1 DOWNTO 0 DO CGRGXB(SB);(*DEAL WITH DELAYS*) 66490 SBDELAYS:=0;LOADSTK(SB); 66500 COMBINE; SBTYP := SBTSTKN; SBINF := SBINF+[SBUNION]; 66530 IF M^.MDV.MDID=MDIDROW THEN (*SINGLE UNIT TO BE ROWED TO A DATA LIST*) 66540 BEGIN 66550 (*+05() IF (RTSTKDEPTH MOD 4)<>0 THEN 66560 BEGIN SB1 := PUSHSB(MDINT); SB1^.SBTYP := SBTLIT; SB1^.SBVALUE := TX(MDVOID); 66570 LOADSTK(SB1); COMBINE; SB^.SBTYP := SBTSTKN END; 66580 ()+05*) 66590 SPACE := SBLEN; 66600 SB1 := PUSHSB(MDVOID); UNSTACKSB; SB1^.SBLEN := SPACE+SZDL; 66610 EMITX3(PDATALIST, OCVSB, ORD(SB), OCVIMMED, SPACE, OCVRES, ORD(SB1)); 66620 SBLEN := SB1^.SBLEN; SBINF := SBINF-[SBUNION]; SBTYP := SB1^.SBTYP; 66630 UNSTACKSB; DISPOSE(SRSTK[SRSEMP].SB); SRSEMP := SRSEMP-1; STACKSB(SB); 66640 END 66650 ELSE M := MM; (*SBMODE WILL BE MM, FOR BENEFIT OF STKMAP*) 66660 END 66670 ELSE GETTOTAL(SB) 66680 END 66690 ELSE WITH SBMODE^ DO 66700 IF (MDV.MDIDMDIDNIL) THEN (*NOT HIP*) 66710 WITH M^ DO 66720 IF MDV.MDID<>MDIDROW THEN 66730 CGCSUPP(SB, M, 0) 66740 ELSE IF COFIRM(SBMODE, MDPRRMD)=MDPRRMD THEN 66750 CGCSUPP(SB, MDPRRMD, MDV.MDCNT) 66760 ELSE IF FIRMM^.MDV.MDID=MDIDROW THEN 66770 CGCSUPP(SB, FIRMM, MDV.MDCNT-FIRMM^.MDV.MDCNT) 66780 ELSE 66790 CGCSUPP(SB, MDPRRMD, MDV.MDCNT) 66800 ELSE CASE MDV.MDID OF 66810 MDIDSKIP: 66820 BEGIN UNSTACKSB; 66830 IF M^.MDV.MDID=MDIDSTRUCT THEN 66840 BEGIN GENDP(M); EMITX2(PSKIPSTRUCT, GENDPOCV, GENDPVAL,OCVRES,ORD(SB)) END 66850 ELSE 66852 BEGIN 66854 IF M^.MDV.MDPILE THEN OPCOD := PSKIP+1 66856 ELSE IF M^.MDV.MDLEN>SZINT THEN OPCOD := PSKIP+2 66857 ELSE OPCOD := PSKIP; 66858 EMITX1(OPCOD, OCVRES, ORD(SB)); 66859 END; 66860 END; 66870 MDIDJUMP: (*NO ACTION*); 66880 MDIDNIL: BEGIN UNSTACKSB; EMITX1(PNIL, OCVRES, ORD(SB)) END 66890 END; 66900 SBMODE := M 66910 END 66920 END; 66930 (**) 66940 (**) 66950 PROCEDURE CGBALB(SB: PSB; M: MODE); 66960 (*EACH UNIT TO BE BALANCED*) 66970 VAR I: INTEGER; 66980 SB1: PSB; 66990 BEGIN WITH SB^ DO 67000 IF SBMODE<>MDJUMP THEN 67010 BEGIN 67012 (*+42() SETTEXTSTATE; ()+42*) 67020 FIXUPF(SBXPTR); (*SBXPTR WAS SET IN CGIBAL*) 67030 STACKSB(SB); 67040 CGCOERCE(SB, M); 67050 FOR I := SBDELAYS-1 DOWNTO 0 DO CGRGXB(SB); 67060 SBDELAYS := 0; 67070 LOADTOTAL(SB); 67080 IF SBUNION IN SBINF THEN 67090 WHILE SBLENSRSTK[SRSEMP].SB THEN 67190 GENFLAD 67200 END 67210 END; 67220 (**) 67230 (**) 67240 FUNCTION COERCE (*-01() (M: MODE): MODE ()-01*); 67250 (*FUNCTION: GENERATE CODE TO PERFORM THE APPROPRIATE COERCIONS FOR THE UNIT ON THE STACK. 67260 REDUCES THE STACK TO CONTAIN A SINGLE BLOCK REPRESENTING THE RESULTING UNIT. 67270 RETURNS M UNALTERED ??? 67280 *) 67290 VAR SEMP: -1..SRSTKSIZE; 67300 NOTJUMP: BOOLEAN; 67310 I: INTEGER; 67320 BEGIN 67330 IF BALFLAG THEN 67340 BEGIN 67350 STARTCHAIN; 67360 SEMP := SRSUBP+1; 67370 WHILE SEMP<=SRSEMP DO WITH SRSTK[SEMP] DO 67380 BEGIN 67390 THIPMD(SB^.SBMODE, M); 67400 CGBALB(SB, M); 67410 IF SEMP<>SRSEMP THEN DISPOSE(SB); 67420 SEMP := SEMP+1 67430 END; 67440 SUBREST; 67450 SRSEMP := SRSEMP+1; SRSTK[SRSEMP] := SRSTK[SEMP-1]; (*AS KEPT*) 67460 STACKSB(SRSTK[SRSEMP].SB); 67470 CGBALC; 67480 BALFLAG := FALSE; 67490 END 67500 ELSE WITH SRSTK[SRSEMP] DO WITH SB^ DO 67510 BEGIN 67520 THIPMD(SBMODE, M); 67530 NOTJUMP := SBMODE<>MDJUMP; 67540 CGCOERCE(SB, M); 67550 IF NOTJUMP THEN WITH SB^ DO 67560 FOR I := SBDELAYS-1 DOWNTO 0 DO CGRGXB(SB); 67570 SBDELAYS := 0 67580 END; 67590 WITH SRSTK[SRSEMP].SB^ DO SBINF := SBINF-[SBMORF]; 67600 COERCE := M 67610 END; 67620 (**) 67630 (**) 67640 FUNCTION BALANCE(STRENGTH: STRTYP): MODE; 67650 (*FUNCTION: DEDUCES THE MODE OF THE BALANCE ON THE SUBSTACK. 67660 COMPLAINS IF STRENGTH IS INSUFFICIENT. 67670 RETURNS THE MODE OF THE BALANCE. 67680 *) 67690 VAR COMM, M: MODE; 67700 SEMP: -1..SRSTKSIZE; 67710 BEGIN 67720 IF BALFLAG THEN SEMP := SRSUBP+1 ELSE SEMP := SRSEMP; 67730 COMM := SRSTK[SEMP].SB^.SBMODE; 67740 WITH COMM^.MDV DO 67750 IF (MDIDMDIDNIL) (*NOT HIPMODE*) THEN BALSTR := STREMPTY 67760 ELSE BALSTR := STRSTRONG; 67770 WHILE SEMPM2COERC THEN BALSTR := M2COERC; 67830 END; 67840 IF BALSTR>STRENGTH THEN 67850 IF (STRENGTH=STRFIRM) AND (COMM^.MDV.MDID=MDIDROW) THEN 67860 COMM := MDROWS 67870 ELSE BEGIN 67880 CASE STRENGTH OF 67890 STRSOFT: SEMERR(ESE+26); 67900 STRWEAK: SEMERR(ESE+27); 67910 STRMEEK: SEMERR(ESE+28); 67920 STRFIRM: SEMERR(ESE+29); 67930 END; 67940 COMM := MDERROR; 67950 END; 67960 BALANCE := COMM 67970 END; 67980 (**) 67990 (**) 68000 FUNCTION SOFT: MODE; 68010 (*FUNCTION: PERFORMS SOFTEST COERCION ON UNIT OR BALANCE ON THE STACK*) 68020 BEGIN 68030 TCOLL; 68040 SOFT := COERCE(COSOFT(BALANCE(STRSOFT))) 68050 END; 68060 (**) 68070 (**) 68080 FUNCTION WEAK: MODE; 68090 (*FUNCTION: PERFORMS WEAKEST COERCION ON UNIT OR BALANCE ON THE STACK*) 68100 BEGIN 68110 TCOLL; 68120 WEAK := COERCE(COWEAK(BALANCE(STRWEAK))) 68130 END; 68140 (**) 68150 (**) 68160 FUNCTION FIRMBAL: MODE; 68170 (*FUNCTION: PERFORMS FIRM BALANCE (BUT DOES NOT COERCE)*) 68180 BEGIN 68190 TCOLL; 68200 FIRMBAL := COFIRM(BALANCE(STRFIRM), NIL); 68210 END; 68220 (**) 68230 (**) 68240 FUNCTION MEEK: MODE; 68250 (*FUNCTION: PERFORMS FIRMEST COERCION ON UNIT OR BALANCE ON THE STACK*) 68260 BEGIN 68270 TCOLL; 68280 MEEK := COERCE(COMEEK(BALANCE(STRMEEK))); 68290 END; 68300 (**) 68310 (**) 68320 FUNCTION UNITESTO(SRCM, DSTM: MODE): BOOLEAN; 68330 (*DSTM MUST BE ONE OF THE TRANSPUT MODES OUT, IN, OUT, INB OR NUMBER. 68340 FUNCTION: DETERMINES WHETHER SRCM CAN BE UNITED TO DSTM. 68350 *) 68360 LABEL 9; 68370 VAR WEAKM, MEEKM: MODE; 68380 BEGIN 68390 IF SRCM=MDERROR THEN 68400 BEGIN UNITESTO := TRUE; GOTO 9 END; 68410 IF DSTM^.MDV.MDID=MDIDROW THEN 68420 IF SRCM=DSTM THEN 68430 BEGIN UNITESTO := TRUE; GOTO 9 END 68440 ELSE DSTM := DSTM^.MDPRRMD; 68450 WEAKM := COWEAK(SRCM); MEEKM := COMEEK(WEAKM); 68460 UNITESTO := FALSE; 68470 WITH DSTM^.MDV DO 68480 IF (MDID>=MDIDOUT) AND (MDID<=MDIDNUMBER) (*A UNITED MODE*) THEN 68490 CASE MDID OF 68500 MDIDOUT: 68510 IF (MEEKM=PRCVF) OR (MEEKM=PASCVF) OR (MEEKM^.MDV.MDIO) THEN UNITESTO := TRUE; 68520 MDIDIN: 68530 IF (MEEKM=PRCVF) OR (MEEKM=PASCVF) THEN UNITESTO := TRUE 68540 ELSE IF WEAKM^.MDV.MDID=MDIDREF THEN 68550 UNITESTO := MEEKM^.MDV.MDIO; 68560 MDIDOUTB: 68570 UNITESTO := MEEKM^.MDV.MDIO; 68580 MDIDINB: 68590 IF WEAKM^.MDV.MDID=MDIDREF THEN 68600 UNITESTO := MEEKM^.MDV.MDIO; 68610 MDIDNUMBER: 68620 IF MEEKM^.MDV.MDID<=MDIDLREAL THEN UNITESTO := TRUE 68630 END; 68640 9: END; 68650 (**) 68660 (**) 68670 FUNCTION UNITEDBAL(M: MODE): BOOLEAN; 68680 (*FUNCTION: DETERMINES WHETHER THE UNIT OR BALANCE ON THE STACK CAN BE 68690 UNITED TO THE TRANSPUT MODE M. 68700 *) 68710 VAR SEMP: -1..SRSTKSIZE; 68720 BALCOUNT: INTEGER; 68730 BEGIN 68740 BALCOUNT := 0; 68750 BALANLEN := 0; 68760 IF BALFLAG THEN SEMP := SRSUBP+1 ELSE SEMP := SRSEMP; 68770 WHILE SEMP<=SRSEMP DO WITH SRSTK[SEMP] DO WITH SB^ DO 68780 BEGIN 68790 IF UNITESTO(SBMODE, M) THEN BALCOUNT := BALCOUNT+1 68800 ELSE IF (SBMODE^.MDV.MDIDMDIDNIL) THEN BALCOUNT := -MAXINT; 68810 IF SBLEN>BALANLEN THEN BALANLEN := SBLEN; 68820 SEMP := SEMP+1 68830 END; 68840 UNITEDBAL := BALCOUNT>0 68850 END; 68860 (**) 68870 (**) 68880 PROCEDURE STRONG; 68890 (*FUNCTION: STRONGLY COERCES THE UNIT OR BALANCE ON THE STACK AS FAR AS THE 68900 MODE ON THE SC CHAIN. 68910 WHEN THE A POSTERIORI MODE IS VOID IT IS POSSIBLE TO GENERATE DIRECTLY THE COERCION CODE 68920 WITHOUT CALLING A BALANCING ROUTINE. THIS IS DUE TO THE FACT THAT ALL MODES CAN BE STRONGLY 68930 COERCED TO VOID. HOWEVER, COLLATERAL-CLAUSES MAY NOT APPEAR IN STRONG VOID CONTEXTS. 68940 *) 68950 VAR M, M1: MODE; 68960 BEGIN 68970 M := SCPOP; 68980 IF M=MDVOID THEN 68990 TCOLL 69000 ELSE WITH M^ DO 69010 BEGIN 69020 IF MDV.MDID=MDIDROW THEN M1 := MDPRRMD ELSE M1 := M; 69030 WITH M1^.MDV DO IF (MDID>=MDIDOUT) AND (MDID<=MDIDNUMBER) (*UNITEDMODE*) THEN 69040 IF NOT UNITEDBAL(M) THEN 69050 BEGIN 69060 SEMERR(ESE+31); 69070 M := MDERROR 69080 END 69090 END; 69100 M := COERCE(M) 69110 END; 69120 (**) 69130 (**) 69140 PROCEDURE SETBALFLAG; 69150 (*FUNCTION: SETS THE BALANCE FLAG (BALFLAG) FOR THE VALUE OF A RANGE. 69160 IF THE RANGE VALUE MAY BE ANY OF A NUMBER (>1) UNITS THEN THE FLAG IS SET AND THE STACK HOLDS 69170 A MARK PLUS THE BLOCKS FOR THE UNITS. F THE RANGE VALUE IS A SINGLE UNIT, 69180 THE FLAG IS CLEARED AND THE STACK HOLDS ONLY THE SINGLE BLOCK. 69190 *) 69200 VAR T: PSB; 69210 BEGIN 69220 IF SRSEMP<>SRSUBP+1 (*NOT ONE UNIT*) THEN 69230 BALFLAG := TRUE 69240 ELSE BEGIN 69250 T := SRSTK[SRSEMP].SB; SRSEMP := SRSEMP-1; 69260 SUBREST; 69270 SRSEMP := SRSEMP+1; SRSTK[SRSEMP].SB := T 69280 END 69290 END; 69300 (**) 69310 (**) 69320 PROCEDURE INNERBAL; 69330 (*FUNCTION: EXECUTED AFTER PROCESSING AN "INNER UNIT" OF A BALANCE. 69340 EVERY BALANCE CONSISTS OF ONE OR MORE UNITS WHICH ARE EVENTUALLY BALANCED. 69350 EACH UNIT EXCEPT THE LAST IS CALLED AN INNER UNIT. NOTE THAT EACH UNIT IN A BALANCE MAY IN FACT 69360 BE A SINGLE BASIC (NON-BALANCE) UNIT OR A SEQUENCE OF BASIC UNITS WHICH RESULTED FROM SOME BALANCE. 69370 *) 69380 VAR I: INTEGER; T: -1..SRSTKSIZE; 69390 BEGIN 69400 IF NOT BALFLAG THEN CGIBAL 69410 ELSE BEGIN 69420 BALFLAG := FALSE; 69430 T := SRSTK[SRSUBP].SUBP; 69440 FOR I := SRSUBP TO SRSEMP-1 DO 69450 SRSTK[I] := SRSTK[I+1]; 69460 SRSEMP := SRSEMP-1; 69470 SRSUBP := T 69480 END 69490 END; 69500 (**) 69510 (**) 69520 PROCEDURE LASTIBAL; 69530 (*FUNCTION: CALLS INNERBAL IF NECESSARY*) 69540 BEGIN 69550 IF (BALFLAG) OR (SRSEMP<>SRSUBP+1) THEN INNERBAL 69560 END; 69570 (**) 69580 (**) 69590 PROCEDURE MEEKLOAD(M: MODE; ERR: INTEGER); 69600 (*EXPECTS THE MAXIMUM COERCION OF THE STACKED UNIT OR BALANCE TO BE M*) 69610 VAR M1: MODE; 69620 BEGIN 69630 M1 := MEEK; 69640 IF M1<>M THEN MODERR(M1, ERR); 69650 CGFIRM 69660 END; 69670 (**) 69680 (**) 69690 PROCEDURE GETOPDM(PROCM: MODE); 69700 (*FUNCTION: PROCM IS THE MODE OF SOME OPERATOR. 69710 SETS LHMODE AND RHMODE.*) 69720 BEGIN WITH PROCM^ DO 69730 IF MDV.MDCNT=1 THEN 69740 BEGIN LHMODE := MDABSENT; RHMODE := MDPRCPRMS[0] END 69750 ELSE 69760 BEGIN LHMODE := MDPRCPRMS[0]; RHMODE := MDPRCPRMS[1] END 69770 END; 69780 (**) 69790 ()+84*)