Twenex Muddle.
[pdp10-muddle.git] / <mdl.int> / maps.mid.29
diff --git a/<mdl.int>/maps.mid.29 b/<mdl.int>/maps.mid.29
new file mode 100644 (file)
index 0000000..4c0cbf2
--- /dev/null
@@ -0,0 +1,247 @@
+
+TITLE MAPS -- MAP FUNCTIONS FOR MUDDLE
+
+RELOCATABLE
+
+.INSRT MUDDLE >
+
+.GLOBAL TYPSEG,NXTLM,NAPT,APLQ,INCR1,SPECBI,FRMSTK,MAPPLY
+.GLOBAL CHFSWP,SSPEC1,ILVAL,CHUNW,DSTORE,PVSTOR,TVSTOR
+
+; 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
+
+IMFUNCTION MAPF,SUBR
+
+       PUSH    P,.             ; PUSH NON-ZERO
+       JRST    MAP1
+
+; MAP THE "CDR" OF EACH LIST
+
+IMFUNCTION MAPR,SUBR
+
+       PUSH    P,[0]
+
+MAP1:  ENTRY
+       HLRE    C,AB            ; HOW MANY ARGS
+       ASH     C,-1            ; TO # OF PAIRS
+       ADDI    C,2             ; 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)
+       PUSH    P,C             ; SAVE IT
+       PUSH    TP,[TATOM,,-1]  ; ALL **GFP** INSTRUCTIONS ARE TO DO WITH MAPRET
+       PUSH    TP,IMQUOTE 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
+       MOVE    PVP,PVSTOR+1
+       MOVEM   0,ASTO(PVP)
+       JUMPE   C,ARGSDN                ; NOA ARGS?
+
+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
+
+ARGSDN:        PUSH    TP,(AB)         ; CONSTRUCTOR
+       PUSH    TP,1(AB)
+       MOVE    PVP,PVSTOR+1
+       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
+       SOSGE   INCNT(P)
+       JRST    INRLP2
+       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.
+       MOVE    E,LISTNO(P)
+       ADDI    E,4(TB)
+       SKIPL   ARGCNT(P)       ; DONT INCR THE 1ST TIME
+       XCT     INCR1(C)        ; INCREMENT THE LOSER
+       MOVE    0,DSTORE        ; UPDATE THE LIST
+       MOVEM   0,(E)
+       MOVEM   D,1(E)          ; CLOBBER AWAY
+       PUSH    TP,DSTORE       ; FOR REST CASE
+       PUSH    TP,D
+       PUSHJ   P,NXTLM         ; SKIP IF GOT ONE, ELSE DONT
+       JRST    DONEIT          ; FINISHED
+       SETZM   DSTORE
+       SKIPN   NTHRST(P)       ; SKIP IF MAP REST
+       JRST    INRLP1
+       MOVEM   A,-1(TP)        ; IUSE AS ARG
+       MOVEM   B,(TP)
+INRLP1:        JRST    INRLP           ; MORE, GO DO THEM
+
+
+; ALL ARGS PUSHED, APPLY USER FCN
+
+INRLP2:        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   DSTORE          ; 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,IMQUOTE 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,IMQUOTE 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,IMQUOTE 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:  ERRUUO  EQUOTE NOT-IN-MAP-FUNCTION
+
+END
+\f\ 3\f
\ No newline at end of file