TITLE MAPS -- MAP FUNCTIONS FOR MUDDLE RELOCATABLE .INSRT MUDDLE > .GLOBAL TYPSEG,NXTLM,NAPT,APLQ,INCR1,SPECBI,FRMSTK,MAPPLY .GLOBAL CHFSWP,SSPEC1,ILVAL,CHUNW ; PSTACK OFFSETS INCNT==0 ; INNER LOOP COUNT LISTNO==-1 ; ARG NUMBER BEING HACKED ARGCNT==-2 ; FINAL ARG COUNTER NARGS==-3 ; NUMBER OF STRUCTURES NTHRST==-4 ; 0=> MAP REST, OTHERWISE MAP FIRST ; MAP THE "CAR" OF EACH LIST MFUNCTION MAPF,SUBR PUSH P,. ; PUSH NON-ZERO JRST MAP1 ; MAP THE "CDR" OF EACH LIST MFUNCTION MAPR,SUBR PUSH P,[0] MAP1: ENTRY HLRE C,AB ; HOW MANY ARGS ASH C,-1 ; TO # OF PAIRS ADDI C,3 ; AT LEAST 3 JUMPG C,TFA ; NOT ENOUGH GETYP A,(AB) ; TYPE OF CONSTRUCTOR CAIN A,TFALSE ; ANY CONSING NEEDE? JRST MAP2 ; NO, SKIP CHECK PUSHJ P,APLQ ; CHECK IF APPLICABLE JRST NAPT ; NO, ERROR MAP2: MOVNS C ; POS NO. OF ARGS (-3) ADDI C,1 ; C/ NOW # OF LISTS... PUSH P,C ; SAVE IT PUSH TP,[TATOM,,-1] ; ALL **GFP** INSTRUCTIONS ARE TO DO WITH MAPRET PUSH TP,MQUOTE LMAP,[LMAP ]INTRUP PUSHJ P,FRMSTK ; **GFP** PUSH TP,[0] ; **GFP** PUSH TP,[0] ; **GFP** PUSHJ P,SPECBIND ; **GFP** MOVE C,(P) ; RESTORE COUNT OF ARGS MOVE A,AB ; COPY ARG POINTER MOVSI 0,TAB ; CLOBBER A'S TYPE MOVEM 0,ASTO(PVP) ARGLP: INTGO ; STACK MAY OVERFLOW PUSH TP,4(A) ; SKIP FCNS PUSH TP,5(A) ADD A,[2,,2] SOJG C,ARGLP ; ALL UP ON STACK ; ALL STRUCTURES ARE ON THE STACK, NOW PUSH THE CONSTRUCTOR PUSH TP,(AB) ; CONSTRUCTOR PUSH TP,1(AB) SETZM ASTO(PVP) PUSH P,[-1] ; FUNNY TEMPS PUSH P,[0] PUSH P,[0] ; OUTER LOOP CDRING EACH STRUCTURE OUTRLP: SETZM LISTNO(P) ; START AT 0TH LIST MOVE 0,NARGS(P) ; TOTAL # OF STRUCS MOVEM 0,INCNT(P) ; AS COUNTER IN INNER LOOP PUSH TP,2(AB) ; PUSH THE APPLIER PUSH TP,3(AB) ; INNER LOOP, CONS UP EACH APPLICATION INRLP: INTGO MOVEI E,2 ; READY TO BUMP LISTNO ADDB E,LISTNO(P) ; CURRENT STORED AND IN C ADDI E,(TB)4 ; POINT TO A STRUCTURE MOVE A,(E) ; PICK IT UP MOVE B,1(E) ; AND VAL PUSHJ P,TYPSEG ; SETUP TO REST IT ETC. SKIPL ARGCNT(P) ; DONT INCR THE 1ST TIME XCT INCR1(C) ; INCREMENT THE LOSER MOVE 0,DSTO(PVP) ; UPDATE THE LIST MOVEM 0,(E) MOVEM D,1(E) ; CLOBBER AWAY PUSH TP,DSTO(PVP) ; FOR REST CASE PUSH TP,D PUSHJ P,NXTLM ; SKIP IF GOT ONE, ELSE DONT JRST DONEIT ; FINISHED SETZM DSTO(PVP) SKIPN NTHRST(P) ; SKIP IF MAP REST JRST INRLP1 MOVEM A,-1(TP) ; IUSE AS ARG MOVEM B,(TP) INRLP1: SOSE INCNT(P) ; COUNT ARGS JRST INRLP ; MORE, GO DO THEM ; ALL ARGS PUSHED, APPLY USER FCN SKIPGE ARGCNT(P) ; UN NEGATE ARGCNT SETZM ARGCNT(P) MOVE A,NARGS(P) ; GET # OF ARGS ADDI A,1 ACALL A,MAPPLY ; APPLY THE BAG BITER GETYP 0,(AB) ; GET TYPE OF CONSTRUCTOR CAIN 0,TFALSE ; SKIP IF ONE IS THERE JRST OUTRL1 PUSH TP,A PUSH TP,B AOS ARGCNT(P) JRST OUTRLP OUTRL1: MOVEM A,-1(TP) ; SAVE PARTIAL VALUE MOVEM B,(TP) JRST OUTRLP ; HERE IF ALL FINISHED DONEIT: HRLS C,LISTNO(P) ; HOW MANY DONE SUB TP,[2,,2] ; FLUSH SAVED VAL SUB TP,C ; FLUSH TUPLE OF CRUFT DONEI1: SKIPGE ARGCNT(P) SETZM ARGCNT(P) ; IN CASE STILL NEGATIVE SETZM DSTO(PVP) ; UNSCREW GETYP 0,(AB) ; ANY CONSTRUCTOR CAIN 0,TFALSE JRST MFINIS ; NO, LEAVE AOS D,ARGCNT(P) ; IF NO ARGS ACALL D,APPLY ; APPLY IT JRST FINIS ; HERE TO FINISH IF CONSTRUCTOR WAS #FALSE () MFINIS: POP TP,B POP TP,A JRST FINIS ; **GFP** FROM HERE TO THE END MFUNCTION MAPLEAVE,SUBR ENTRY CAMGE AB,[-3,,0] JRST TMA MOVE B,MQUOTE LMAP,[LMAP ]INTRUP PUSHJ P,ILVAL GETYP 0,A CAIE 0,TFRAME ; MAKE SURE WINNER JRST NOTM PUSH TP,A PUSH TP,B MOVEI B,-1(TP) ; POINT TO FRAME POINTER PUSHJ P,CHFSWP PUSHJ P,CHUNW JUMPL C,MAPL1 ; RET VAL SUPPLIED MOVSI A,TATOM MOVE B,MQUOTE T JRST FINIS MAPL1: MOVE A,(C) MOVE B,1(C) JRST FINIS MFUNCTION MAPSTOP,SUBR ENTRY PUSH P,[1] JRST MAPREC MFUNCTION MAPRET,SUBR ENTRY PUSH P,[0] MAPREC: MOVE B,MQUOTE LMAP,[LMAP ]INTRUP PUSHJ P,ILVAL ; GET VALUE GETYP 0,A ; FRAME? CAIE 0,TFRAME JRST NOTM PUSH TP,A PUSH TP,B MOVEI B,-1(TP) POP P,0 ; RET/STOP SWITCH JUMPN 0,MAPRC1 ; JUMP IF STOP PUSHJ P,CHFSWP ; CHECK IT OUT (AND MAYBE SWAP) PUSH P,[NLOCR] JRST MAPRC2 MAPRC1: PUSHJ P,CHFSWP PUSH P,[NLOCR1] MAPRC2: HRRZ E,SPSAV(B) ; UNBIND BEFORE RETURN PUSH TP,$TAB PUSH TP,C ADDI E,1 ; FUDGE FOR UNBINDER PUSHJ P,SSPEC1 ; UNBINDER HLRE D,(TP) ; FIND NUMBER JUMPE D,MAPRE1 ; SKIP IF NONE TO MOVE MOVNS E,D ; AND PLUS IT HRLI E,(E) ; COMPUTE NEW TP ADD E,TPSAV(B) ; NEW TP HRRZ C,TPSAV(B) ; GET OLD TOP MOVEM E,TPSAV(B) HRL C,(TP) ; AND NEW BOT ADDI C,1 BLT C,(E) ; BRING IT ALL DOWN MAPRE1: ASH D,-1 ; NO OF ARGS HRRI TB,(B) ; PREPARE TO FINIS MOVSI A,TFIX MOVEI B,(D) POP P,0 ; GET PC TO GO TO MOVEM 0,PCSAV(TB) JRST CONTIN ; BACK TO MAPPER NLOCR1: TDZA A,A ; ZER SW NLOCR: MOVEI A,1 GETYP 0,(AB) ; CHECK IF BUILDING CAIN 0,TFALSE JRST FLUSHM ; REMOVE GOODIES ADDM B,ARGCNT(P) ; BUMP ARG COUNTER NLOCR2: JUMPE A,DONEI1 JRST OUTRLP FLUSHM: ASH B,1 ; FLUSH GOODIES DROPPED HRLI B,(B) SUB TP,B JRST NLOCR2 NOTM: PUSH TP,$TATOM PUSH TP,EQUOTE NOT-IN-MAP-FUNCTION JRST CALER1 END