690 lines
		
	
	
	
		
			26 KiB
		
	
	
	
		
			OpenEdge ABL
		
	
	
	
	
	
			
		
		
	
	
			690 lines
		
	
	
	
		
			26 KiB
		
	
	
	
		
			OpenEdge ABL
		
	
	
	
	
	
| 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 LEN1<LEN2 THEN (*STRONG COERCION, IF ANY, IS FROM M1 TO FIRMM2*)
 | |
| 65860           BEGIN
 | |
| 65870           M1COERC := STRSTRONG; M2COERC := TSTRENGTH(M2, FIRMM2);
 | |
| 65880           BALMOIDS := FIRMM2;
 | |
| 65890           END
 | |
| 65900         ELSE
 | |
| 65910           BEGIN
 | |
| 65920           M1COERC := TSTRENGTH(M1, FIRMM1); M2COERC := STRSTRONG;
 | |
| 65930           BALMOIDS := FIRMM1;
 | |
| 65940           END;
 | |
| 65950         END;
 | |
| 65960       END
 | |
| 65970     END;
 | |
| 65980 (**)
 | |
| 65990 (**)
 | |
| 66000 PROCEDURE CGCOERCE(SB: PSB (*CONTAINING SOURCE MODE*); M: MODE (*DESTINATION MODE*));
 | |
| 66010   VAR FIRMM, MM: MODE;
 | |
| 66020       SB1, SB2: PSB;
 | |
| 66030       MODENO: -1..31;
 | |
| 66040       SPACE: 0..MAXSIZE;
 | |
| 66050       I:0..MAXINT;
 | |
| 66052       OPCOD: POP;
 | |
| 66060     BEGIN WITH SB^ DO
 | |
| 66070       IF SBMODE<>M 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.MDID<MDIDSKIP) OR (MDV.MDID>MDIDNIL) 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 SBLEN<BALANLEN+SZWORD DO (*TO MAKE STKMAP HAPPY*)
 | |
| 67100             BEGIN SB1 := PUSHSB(MDVOID); CGCOERCE(RTSTACK, M); COMBINE END;
 | |
| 67110         IF (SBTYP=SBTDL) AND (SBLEN<BALANLEN) THEN
 | |
| 67120           BEGIN
 | |
| 67130           EMITX1(PHOIST, OCVIMMED, BALANLEN-SBLEN);
 | |
| 67140           RTSTKDEPTH := RTSTKDEPTH+BALANLEN-SBLEN;
 | |
| 67150           SBLEN := BALANLEN;
 | |
| 67160           END;
 | |
| 67170         UNSTACKSB;
 | |
| 67180         IF SB<>SRSTK[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 (MDID<MDIDSKIP) OR (MDID>MDIDNIL) (*NOT HIPMODE*) THEN BALSTR := STREMPTY
 | |
| 67760       ELSE BALSTR := STRSTRONG;
 | |
| 67770     WHILE SEMP<SRSEMP DO
 | |
| 67780       BEGIN
 | |
| 67790       SEMP := SEMP+1;
 | |
| 67800       COMM := BALMOIDS(COMM, SRSTK[SEMP].SB^.SBMODE);
 | |
| 67810       IF BALSTR<M1COERC THEN BALSTR := M1COERC;
 | |
| 67820       IF BALSTR>M2COERC 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.MDID<MDIDSKIP) OR (SBMODE^.MDV.MDID>MDIDNIL) 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*)
 |