1 TITLE PRIMITIVE FUNCTIONS FOR THE MUDDLE SYSTEM
\r
7 .GLOBAL TMA,TFA,CELL,IBLOCK,IBLOK1,ICELL2,VECTOP
\r
8 .GLOBAL NWORDT,CHARGS,CHFRM,CHLOCI,IFALSE,IPUTP,IGETP,BYTDOP
\r
9 .GLOBAL OUTRNG,IGETLO,CHFRAM,ISTRUC,TYPVEC,SAT,CHKAB,VAL,CELL2,MONCH,MONCH0
\r
10 .GLOBAL RMONCH,RMONC0,LOCQ,LOCQQ,SMON,PURERR,APLQ,NAPT,TYPSEG,NXTLM
\r
11 .GLOBAL MAKACT,ILLCHO,COMPER,CEMPTY,CIAT,CIEQUA,CILEGQ,CILNQ,CILNT,CIN,CINTH,CIREST
\r
12 .GLOBAL CISTRU,CSETLO,CIPUT,CIGET,CIGETL,CIMEMQ,CIMEMB,CIMON,CITOP,CIBACK
\r
13 .GLOBAL IGET,IGETL,IPUT,CIGETP,CIGTPR,CINEQU,IEQUAL,TD.LNT,TD.GET,TD.PUT,TD.PTY
\r
14 .GLOBAL TMPLNT,ISTRCM
\r
16 ; BUILD DISPATCH TABLE FOR PRIMITIVE FUNCTIONS USAGE
\r
20 REPEAT NUMSAT,[0] ;INITIALIZE TABLE TO ZEROES
\r
22 IRP A,,[2WORD,2NWORD,NWORD,ARGS,CHSTR,BYTE]
\r
32 ; FUDGE FOR STRUCTURE LOCATIVES
\r
34 IRP A,,[[LOCL,2WORD],[LOCV,2NWORD],[LOCU,NWORD],[LOCS,CHSTR],[LOCA,ARGS]
\r
44 LOC PRMTYP+SSTORE ;SPECIAL HACK FOR AFREE STORAGE
\r
51 ; MACRO TO BUILD PRIMITIVE DISPATCH TABLES
\r
53 DEFINE PRDISP NAME,DEFAULT,LIST
\r
54 TBLDIS NAME,DEFAULT,[LIST]PNUM
\r
58 ; SUBROUTINE TO RETURN PRIMITIVE TYPE AND PRINT ERROR IF ILLEGAL
\r
60 PTYPE: GETYP A,(B) ;CALLE D WITH B POINTING TO PAIR
\r
61 CAIN A,TILLEG ;LOSE IF ILLEGAL
\r
64 PUSHJ P,SAT ;GET STORAGE ALLOC TYPE
\r
66 CAIN A,SARGS ;SPECIAL HAIR FOR ARGS
\r
72 PTYP1: MOVEI 0,(A) ; ALSO RETURN PRIMTYPE
\r
73 CAILE A,NUMSAT ; SKIP IF NOT TEMPLATE
\r
75 MOVE A,PRMTYP(A) ;GET PRIM TYPE,
\r
78 ; COMPILERS CALL TO ABOVE (LESS CHECKING)
\r
88 MFUNCTION SUBSTRUC,SUBR
\r
91 JUMPGE AB,TFA ;need at least one arg
\r
92 CAMGE AB,[-10,,0] ;NO MORE THEN 4
\r
95 PUSHJ P,PTYPE ;get primtype in A
\r
99 RESSUB: CAMLE AB,[-2,,0] ;if only one arg skip rest
\r
101 HLRZ B,(AB)2 ;GET TYPE
\r
102 CAIE B,TFIX ;IF FIX OK
\r
104 MOVE B,(AB)1 ;ptr to object of resting
\r
105 MOVE C,(AB)3 ;# of times to rest
\r
110 PUSH TP,B ;put rested sturc on stack
\r
113 PRDISP TYTBL,IWTYP1,[[P2WORD,RESSUB],[P2NWORD,RESSUB]
\r
114 [PNWORD,RESSUB],[PCHSTR,RESSUB]]
\r
116 PRDISP MRSTBL,IWTYP1,[[P2WORD,LREST],[P2NWORD,VREST]
\r
117 [PNWORD,UREST],[PCHSTR,SREST]]
\r
119 PRDISP COPYTB,IWTYP1,[[P2WORD,CPYLST],[P2NWORD,CPYVEC]
\r
120 [PNWORD,CPYUVC],[PCHSTR,CPYSTR]]
\r
122 PRDISP ALOCTB,IWTYP1,[[P2WORD,ALLIST],[P2NWORD,ALVEC]
\r
123 [PNWORD,ALUVEC],[PCHSTR,ALSTR]]
\r
125 ALOCFX: MOVE B,(TP) ;missing 3rd arg aloc for "rest" of struc
\r
128 PUSH P,[377777,,-1]
\r
129 PUSHJ P,@LENTBL(A) ;get length of rested struc
\r
132 MOVE A,B ;# of elements needed
\r
135 ALOCOK: CAML AB,[-4,,0] ;exactly 3 args
\r
138 CAIE C,TFIX ;OK IF TYPE FIX
\r
140 POP P,C ;C HAS PRIMTYYPE
\r
141 MOVE A,(AB)5 ;# of elements needed
\r
142 JRST @ALOCTB(C) ;DO ALLOCATION
\r
145 CPYVEC: HLRE A,(AB)1 ;USE WHEN ONLY ONE ARG
\r
147 ASH A,-1 ;# OF ELEMENTS FOR ALLOCATION
\r
155 CAIL A,-1 ;CHK FOR OUT OF RANGE
\r
157 CAMGE AB,[-6,,] ; SKIP IF WE GET VECTOR
\r
158 JRST ALVEC2 ; USER SUPPLIED VECTOR
\r
161 ALVEC1: MOVE A,(P) ;# OF WORDS TO ALLOCATE
\r
162 MOVE C,B ; SAVE VECTOR POINTER
\r
165 ADD A,B ;PTING TO FIRST DOPE WORD -ALLOCATED
\r
168 SUBI A,1 ;ptr to last element of the block
\r
169 HRL B,(TP) ;bleft-ptr to source , b right -ptr to allocated space
\r
177 ALVEC2: GETYP 0,6(AB) ; CHECK IT IS A VECTOR
\r
180 HLRE A,7(AB) ; CHECK SIZE
\r
182 ASH A,-1 ; # OF ELEMENTS
\r
183 CAMGE A,(P) ; SKIP IF BIG ENOUGH
\r
185 MOVE B,7(AB) ; WINNER, JOIN COMMON CODE
\r
188 CPYUVC: HLRE A,(AB)1 ;# OF ELEMENTS FOR ALLOCATION
\r
195 ADD A,(TP) ;PTING TO DOPE WORD OF ORIG VEC
\r
198 CAMGE AB,[-6,,] ; SKIP IF WE SUPPLY UVECTOR
\r
202 ALUVE1: MOVE A,(P) ;# of owrds to allocate
\r
204 ADD A,B ;LOCATION O FIRST ALLOCATED DOPE WORD
\r
205 HLR D,(AB)1 ;# OF ELEMENTS IN UVECTOR
\r
207 ADD D,(AB)1 ;LOCATION OF FIRST DOPE WORD FOR SOURCE
\r
208 GETYP E,(D) ;GET UTYPE
\r
209 CAML AB,[-6,,] ; SKIP IF USER SUPPLIED OUTPUT UVECTOR
\r
210 HRLM E,(A) ;DUMP UTYPE INTO DOPE WORD OF ALLOC UVEC
\r
212 CAIN 0,(E) ; 0 HAS USER UVEC UTYPE
\r
217 MOVE C,B ; SAVE POINTER TO FINAL GUY
\r
218 HRL C,(TP) ;Bleft- ptr to source, Bright-ptr to allocated space
\r
224 ALUVE2: GETYP 0,6(AB) ; CHECK IT IS A VECTOR
\r
227 HLRE A,7(AB) ; CHECK SIZE
\r
229 CAMGE A,(P) ; SKIP IF BIG ENOUGH
\r
231 MOVE B,7(AB) ; WINNER, JOIN COMMON CODE
\r
234 GETYP 0,(A) ; GET UTYPE OF USER UVECTOR
\r
237 CPYSTR: HRR A,(AB) ;#OF CHAR TO COPY
\r
238 PUSH TP,(AB) ;ALSTR EXPECTS STRING IN TP
\r
242 HRRZ 0,-1(TP) ;0 IS LENGTH OFF VECTOR
\r
245 CAMGE AB,[-6,,] ; SKIP IF WE SUPPLY STRING
\r
249 PUSHJ P,IBLOCK ;ALLOCATE SPACE
\r
251 MOVE A,(P) ; # OF CHARS TO A
\r
252 ALSTR1: PUSH P,B ;BYTE PTR TO ALOC SPACE
\r
253 POP TP,C ;PTR TO ORIGINAL STR
\r
255 COPYST: ILDB D,C ;GET NEW CHAR
\r
256 IDPB D,B ;DEPOSIT CHAR
\r
257 SOJG A,COPYST ;FINISH TRANSFER?
\r
259 CLOSTR: POP P,B ;BYTE PTR TO COPY
\r
260 POP P,A ;# FO ELEMENTS
\r
264 ALSTR2: GETYP 0,6(AB) ; CHECK IT IS A VECTOR
\r
268 CAMGE A,(P) ; SKIP IF BIG ENOUGH
\r
271 MOVE B,7(AB) ; WINNER, JOIN COMMON CODE
\r
274 CPYLST: SKIPN 1(AB)
\r
278 HRLI C,TLIST ;TP JUNK FOR GAR. COLLECTOR
\r
280 PUSH TP,B ;VALUE -PTR TO NEW LIST
\r
282 MOVE C,1(AB) ;PTR TO FIRST ELEMENT OF ORIG. LIST
\r
284 MOVE E,1(C) ;GET LIST ELEMENT INTO ALOC SPACE
\r
286 MOVEM E,1(B) ;PUT INTO ALLOCATED SPACE
\r
287 HRRZ C,(C) ;UPDATE PTR
\r
288 JUMPE C,CLOSWL ;END OF LIST?
\r
292 HRRM B,(D) ;LINK ALLOCATED LIST CELLS
\r
295 CLOSWL: POP TP,B ;USELESS
\r
296 POP TP,B ;PTR TO NEW LIST
\r
302 ALLIST: CAMGE AB,[-6,,] ; SKIP IF WE BUILD THE LIST
\r
307 POP P,A ;# OF ELEMENTS
\r
308 PUSH P,B ;ptr to allocated list
\r
309 POP TP,C ;ptr to orig list
\r
313 HRRM B,-2(B) ;LINK ALOCATED LIST CELLS
\r
314 ENTCOP: JUMPE C,OUTRNG
\r
316 MOVE E,1(C) ;get list element into D+E
\r
318 MOVEM E,1(B) ;put into allocated space
\r
319 HRRZ C,(C) ;update ptrs
\r
320 SOJG A,COPYL ;finish transfer?
\r
322 CLOSEL: POP P,B ;PTR TO NEW LIST
\r
326 ZEROLT: SUB TP,[1,,1] ;IF RESTED ALL OF LIST
\r
332 CPYLS2: GETYP 0,6(AB)
\r
335 MOVE B,7(AB) ; GET DEST LIST
\r
339 CPYLS4: JUMPE B,OUTRNG
\r
349 CPYLS3: MOVE B,7(AB)
\r
354 ; PROCESS TYPE ILLEGAL
\r
356 ILLCHO: HRRZ B,1(B) ;GET CLOBBERED TYPE
\r
357 CAIN B,TARGS ;WAS IT ARGS?
\r
359 CAIN B,TFRAME ;A FRAME?
\r
361 CAIN B,TLOCD ;A LOCATIVE TO AN ID
\r
364 LSH B,1 ;NONE OF ABOVE LOOK IN TABLE
\r
365 ADDI B,TYPVEC+1(TVP)
\r
367 PUSH TP,EQUOTE ILLEGAL
\r
369 PUSH TP,(B) ;PUSH ATOMIC NAME
\r
371 JRST CALER ;GO TO ERROR REPORTER
\r
373 ; CHECK AN ARGS POINTER
\r
375 CHARGS: PUSHJ P,ICHARG ; INTERNAL CHECK
\r
378 ILLAR1: PUSH TP,$TATOM
\r
379 PUSH TP,EQUOTE ILLEGAL-ARGUMENT-BLOCK
\r
382 ICHARG: PUSH P,A ;SAVE SOME ACS
\r
385 SKIPN C,1(B) ;GET POINTER
\r
386 JRST ILLARG ; ZERO POINTER IS ILLEGAL
\r
387 HLRE A,C ;FIND ASSOCIATED FRAME
\r
388 SUBI C,(A) ;C POINTS TO FRAME OR FRAME POINTER
\r
389 GETYP A,(C) ;GET TYPE OF NEXT GOODIE
\r
392 CAIE A,TENTRY ;MUST BE EITHER ENTRY OR TINFO
\r
394 JRST CHARG1 ;WINNER
\r
397 CHARG1: CAIN A,TINFO ;POINTER TO FRAME?
\r
398 ADD C,1(C) ;YES, GET IT
\r
399 CAIE A,TINFO ;POINTS TO ENTRT?
\r
400 MOVEI C,FRAMLN(C) ;YES POINT TO END OF FRAME
\r
401 HLRZ C,OTBSAV(C) ;GET TIME FROM FRAME
\r
402 HRRZ B,(B) ;AND ARGS TIME
\r
404 ILLARG: SETZM -1(P) ; RETURN ZEROED B
\r
408 POPJ P, ;GO GET PRIM TYPE
\r
412 ; CHECK A FRAME POINTER
\r
414 CHFRM: PUSHJ P,CHFRAM
\r
417 ILFRAM: PUSH TP,$TATOM
\r
418 PUSH TP,EQUOTE ILLEGAL-FRAME
\r
421 CHFRAM: PUSH P,A ;SAVE SOME REGISTERS
\r
424 HRRZ A,(B) ; GE PVP POINTER
\r
425 HLRZ C,(A) ; GET LNTH
\r
426 SUBI A,-1(C) ; POINT TO TOP
\r
427 CAIN A,(PVP) ; SKIP IF NOT THIS PROCESS
\r
428 MOVEM TP,TPSTO+1(A) ; MAKE CURRENT BE STORED
\r
429 HRRZ A,TPSTO+1(A) ; GET TP FOR THIS PROC
\r
430 HRRZ C,1(B) ;GET POINTER PART
\r
431 CAILE C,1(A) ;STILL WITHIN STACK
\r
433 HLRZ A,FSAV(C) ;CHECK STILL AN ENTRY BLOCK
\r
438 HLRZ A,1(B) ;GET TIME FROM POINTER
\r
439 HLRZ C,OTBSAV(C) ;AND FROM FRAME
\r
441 BDFR: SETZM -1(P) ; RETURN 0 IN B
\r
442 JRST POPBCJ ;YES, WIN
\r
444 ; CHECK A LOCATIVE TO AN IDENTIFIER
\r
446 CHLOCI: PUSHJ P,ICHLOC
\r
449 ILLOC1: PUSH TP,$TATOM
\r
450 PUSH TP,EQUOTE ILLEGAL-LOCATIVE
\r
457 HRRZ A,(B) ;GET TIME FROM POINTER
\r
458 JUMPE A,POPBCJ ;ZERO, GLOBAL VARIABLE NO TIME
\r
459 HRRZ C,1(B) ;POINT TO STACK
\r
462 HRRZ C,2(C) ; SHOULD BE DECL,,TIME
\r
464 ILLOC: SETZM -1(P) ; RET 0 IN B
\r
470 ; PREDICATE TO SEE IF AN OBJECT IS STRUCTURED
\r
472 MFUNCTION %STRUC,SUBR,[STRUCTURED?]
\r
476 GETYP A,(AB) ; GET TYPE
\r
477 PUSHJ P,ISTRUC ; INTERNAL
\r
482 ; PREDICATE TO CHECK THE LEGALITY OF A FRAME/ARGS TUPLE/IDENTIFIER LOCATIVE
\r
484 MFUNCTION %LEGAL,SUBR,[LEGAL?]
\r
488 MOVEI B,(AB) ; POINT TO ARG
\r
496 PUSHJ P,SAT ; GET STORG TYPE
\r
497 CAIN A,SFRAME ; FRAME?
\r
499 CAIN A,SARGS ; ARG TUPLE
\r
501 CAIN A,SLOCID ; ID LOCATIVE
\r
529 \f;SUBRS TO DEFINE, GET, AND PUT BIT FIELDS
\r
531 MFUNCTION BITS,SUBR
\r
533 JUMPGE AB,TFA ;AT LEAST ONE ARG ?
\r
537 SKIPLE C,(AB)+1 ;GET FIRST AND CHECK TO SEE IF POSITIVE
\r
538 CAILE C,44 ;CHECK IF FIELD NOT GREATER THAN WORD SIZE
\r
541 CAML AB,[-2,,0] ;ONLY ONE ARG ?
\r
543 CAMGE AB,[-4,,0] ;MORE THAN TWO ARGS ?
\r
544 JRST TMA ;YES, LOSE
\r
548 SKIPGE B,(AB)+3 ;GET SECOND ARG AND CHECK TO SEE IF NON-NEGATIVE
\r
550 ADD C,(AB)+3 ;CALCULATE LEFTMOST EXTENT OF THE FIELD
\r
551 CAILE C,44 ;SHOULD BE LESS THAN WORD SIZE
\r
555 LSH B,30 ;FORM BYTE POINTER'S LEFT HALF
\r
561 MFUNCTION GETBITS,SUBR
\r
572 MOVEI A,(AB)+1 ;GET ADDRESS OF THE WORD
\r
573 HLL A,(AB)+3 ;GET LEFT HALF OF BYTE POINTER
\r
575 MOVSI A,TWORD ; ALWAYS RETURN WORD
\b\b\b\b____
\r
579 MFUNCTION PUTBITS,SUBR
\r
581 CAML AB,[-2,,0] ;AT LEAST TWO ARGS ?
\r
590 MOVEI B,0 ;EMPTY THIRD ARG DEFAULT
\r
591 CAML AB,[-4,,0] ;ONLY TWO ARGS ?
\r
593 CAMGE AB,[-6,,0] ;MORE THAN THREE ARGS ?
\r
594 JRST TMA ;YES, LOSE
\r
600 TWOF: MOVEI A,(AB)+1 ;ADDRESS OF THE TARGET WORD
\r
601 HLL A,(AB)+3 ;GET THE LEFT HALF OF THE BYTE POINTER
\r
604 MOVE A,(AB) ;SAME TYPE AS FIRST ARG'S
\r
608 ; FUNCTION TO GET THE LENGTH OF LISTS,VECTORS AND CHAR STRINGS
\r
610 MFUNCTION LNTHQ,SUBR,[LENGTH?]
\r
620 MFUNCTION LENGTH,SUBR
\r
623 PUSH P,[377777777777]
\r
624 LNTHER: MOVE B,AB ;POINT TO ARGS
\r
625 PUSHJ P,PTYPE ;GET ITS PRIM TYPE
\r
628 PUSHJ P,@LENTBL(A) ; CALL RIGTH ONE
\r
629 JRST LFINIS ;OTHERWISE USE 0
\r
631 PRDISP LENTBL,IWTYP1,[[P2WORD,LNLST],[P2NWORD,LNVEC],[PNWORD,LNUVEC]
\r
632 [PARGS,LNVEC],[PCHSTR,LNCHAR],[PTMPLT,LNTMPL]]
\r
634 LNLST: SKIPN C,B ; EMPTY?
\r
635 JRST LNLST2 ; YUP, LEAVE
\r
636 MOVEI B,1 ; INIT COUNTER
\r
637 MOVSI A,TLIST ;WILL BECOME INTERRUPTABLE
\r
638 HLLM A,CSTO(PVP) ;AND C WILL BE A LIST POINTER
\r
639 LNLST1: INTGO ;IN CASE CIRCULAR LIST
\r
643 JUMPE C,.+2 ;DONE, RETRUN LENGTH
\r
644 AOJA B,LNLST1 ;COUNT AND GO
\r
645 LNLST2: SETZM CSTO(PVP)
\r
651 MOVSI A,TFIX ;LENGTH IS AN INTEGER
\r
654 LNVEC: ASH B,-1 ;GENERAL VECTOR DIVIDE BY 2
\r
655 LNUVEC: HLRES B ;GET LENGTH
\r
659 LNCHAR: HRRZ B,C ; GET COUNT
\r
662 LNTMPL: GETYP A,(B) ; GET REAL SAT
\r
664 HRLS A ; READY TO HIT TABLE
\r
665 ADD A,TD.LNT+1(TVP)
\r
667 MOVE C,B ; DATUM TO C
\r
668 XCT (A) ; GET LENGTH
\r
669 HLRZS C ; REST COUNTER
\r
670 SUBI B,(C) ; FLUSH IT OFF
\r
671 MOVEI B,(B) ; IN CASE FUNNY STUFF
\r
675 ; COMPILERS ENTRIES
\r
678 PUSH P,[377777,,-1]
\r
681 PUSHJ P,CPTYPE ; GET PRIMTYPE
\r
683 PUSHJ P,@LENTBL(A) ; DISPATCH
\r
707 IDNT1: MOVE A,(AB) ;RETURN THE FIRST ARG
\r
711 MFUNCTION QUOTE,FSUBR
\r
716 CAIE A,TLIST ;ARG MUST BE A LIST
\r
718 SKIPN B,1(AB) ;SHOULD HAVE A BODY
\r
721 HLLZ A,(B) ; GET IT
\r
726 MFUNCTION NEQ,SUBR,[N==?]
\r
731 MFUNCTION EQ,SUBR,[==?]
\r
736 GETYP A,(AB) ;GET 1ST TYPE
\r
737 GETYP C,2(AB) ;AND 2D TYPE
\r
739 CAIN A,(C) ;CHECK IT
\r
744 ITRUTH: MOVSI A,TATOM ;RETURN TRUTH
\r
748 IFALSE: MOVSI A,TFALSE ;RETURN FALSE
\r
759 MFUNCTION EMPTY,SUBR,EMPTY?
\r
764 PUSHJ P,PTYPE ;GET PRIMITIVE TYPE
\r
768 SKIPN B,1(AB) ;GET THE ARG
\r
771 CAIN A,PTMPLT ; TEMPLATE?
\r
773 CAIE A,P2WORD ;A LIST?
\r
774 JRST EMPT1 ;NO VECTOR OR CHSTR
\r
775 JUMPE B,ITRUTH ;0 POINTER MEANS EMPTY LIST
\r
779 EMPT1: CAIE A,PCHSTR ;CHAR STRING?
\r
780 JRST EMPT2 ;NO, VECTOR
\r
781 HRRZ B,(AB) ; GET COUNT
\r
782 JUMPE B,ITRUTH ;0 STRING WINS
\r
785 EMPT2: JUMPGE B,ITRUTH
\r
788 EMPTPL: PUSHJ P,LNTMPL ; GET LENGTH
\r
792 ; COMPILER'S ENTRY TO EMPTY
\r
799 JUMPE B,YES ; ALWAYS EMPTY
\r
808 TRNE 0,-1 ; STRING, SKIP ON ZERO LENGTH FIELD
\r
812 CEMPTP: PUSHJ P,LNTMPL
\r
816 MFUNCTION NEQUAL,SUBR,[N=?]
\r
820 MFUNCTION EQUAL,SUBR,[=?]
\r
824 MOVE C,AB ;SET UP TO CALL INTERNAL
\r
826 ADD D,[2,,2] ;C POINTS TO FIRS, D TO SECOND
\r
827 PUSHJ P,IEQUAL ;CALL INTERNAL
\r
828 JRST EQFALS ;NO SKIP MEANS LOSE
\r
836 ; COMPILER'S ENTRY TO =? AND N=?
\r
848 SUBM M,-1(P) ; MAY BECOME INTERRUPTABLE
\r
852 SUB TP,[4,,4] ; FLUSH TEMPS
\r
863 ; INTERNAL EQUAL SUBROUTINE
\r
865 IEQUAL: MOVE B,C ;NOW CHECK THE ARGS
\r
869 GETYP 0,(C) ;NOW CHECK FOR EQ
\r
872 CAIN 0,(B) ;DONT SKIP IF POSSIBLE WINNER
\r
873 CAME E,1(D) ;DEFINITE WINNER, SKIP
\r
875 CPOPJ1: AOS (P) ;EQ, SKIP RETURN
\r
879 IEQ1: CAIE 0,(B) ;SKIP IF POSSIBLE MATCH
\r
880 CPOPJ: POPJ P, ;NOT POSSIBLE WINNERS
\r
881 JRST @EQTBL(A) ;DISPATCH
\r
883 PRDISP EQTBL,CPOPJ,[[P2WORD,EQLIST],[P2NWORD,EQVEC],[PNWORD,EQUVEC]
\r
884 [PARGS,EQVEC],[PCHSTR,EQCHST],[PTMPLT,EQTMPL]]
\r
887 EQLIST: PUSHJ P,PUSHCD ;PUT ARGS ON STACK
\r
889 EQLST1: INTGO ;IN CASE OF CIRCULAR
\r
890 HRRZ C,-2(TP) ;GET FIRST
\r
891 HRRZ D,(TP) ;AND 2D
\r
893 JRST EQLST2 ;YES, LEAVE
\r
894 JUMPE C,EQLST3 ;NIL LOSES
\r
896 GETYP 0,(C) ;CHECK DEFERMENT
\r
898 HRRZ C,1(C) ;PICK UP POINTED TO CROCK
\r
901 HRRZ D,1(D) ;POINT TO REAL GOODIE
\r
902 PUSHJ P,IEQUAL ;CHECK THE CARS
\r
904 HRRZ C,@-2(TP) ;CDR THE LISTS
\r
906 HRRZM C,-2(TP) ;AND STORE
\r
910 EQLST2: AOS (P) ;SKIP RETRUN
\r
911 EQLST3: SUB TP,[4,,4] ;REMOVE CRUFT
\r
914 ; HERE FOR HACKING TEMPLATE STRUCTURES
\r
916 EQTMPL: PUSHJ P,PUSHCD ; SAVE GOODIES
\r
918 MOVE C,1(C) ; CHECK REAL SATS
\r
922 CAIE 0,(C) ; SKIP IF WINNERS
\r
924 PUSH P,0 ; SAVE MAGIC OFFSET
\r
926 PUSHJ P,TM.LN1 ; RET LENGTH IN B
\r
927 MOVEI B,-1(B) ; FLUSH FUNNY
\r
931 MOVE C,(TP) ; POINTER TO OTHER GUY
\r
932 ADD A,TD.LNT+1(TVP)
\r
933 XCT (A) ; OTHER LENGTH TO B
\r
934 HLRZ 0,B ; REST OFFSETTER
\r
944 JRST EQTMP3 ; WIN!!
\r
946 MOVE B,-6(TP) ; POINTER
\r
947 MOVE 0,-2(P) ; GET MAGIC OFFSET
\r
948 PUSHJ P,TM.TOE ; GET OFFSET TO TEMPLATE
\r
949 ADD A,TD.GET+1(TVP)
\r
952 XCT (E) ; VAL TO A AND B
\r
956 MOVE B,-4(TP) ; OTHER GUY
\r
959 ADD A,TD.GET+1(TVP)
\r
962 XCT (E) ; GET OTHER VALUE
\r
967 PUSHJ P,IEQUAL ; RECURSE
\r
968 JRST EQTMP1 ; LOSER
\r
969 JRST EQTMP2 ; WINNER
\r
971 EQTMP3: AOS -3(P) ; WIN RETURN
\r
972 EQTMP1: SUB P,[3,,3] ; FLUSH JUNK
\r
973 EQTMP4: SUB TP,[10,,10]
\r
978 EQVEC: HLRE A,1(C) ;GET LENGTHS
\r
980 CAIE B,(A) ;SKIP IF EQUAL LENGTHS
\r
982 JUMPGE A,CPOPJ1 ;SKIP RETRUN WIN
\r
983 PUSHJ P,PUSHCD ;SAVE ARGS
\r
985 EQVEC1: INTGO ;IN CASE LONG VECTOR
\r
987 MOVE D,-2(TP) ;ARGS TO C AND D
\r
990 MOVE C,[2,,2] ;GET BUMPER
\r
992 ADDB C,-2(TP) ;BUMP BOTH POINTERS
\r
996 EQUVEC: HLRE A,1(C) ;GET LENGTHS
\r
998 CAIE B,(A) ;SKIP IF EQUAL
\r
1001 HRRZ B,1(C) ;START COMPUTING DOPE WORD LOCN
\r
1002 SUB B,A ;B POINTS TO DOPE WORD
\r
1003 GETYP 0,(B) ;GET UNIFORM TYPE
\r
1004 HRRZ B,1(D) ;NOW FIND OTHER DOPE WORD
\r
1006 HLRZ B,(B) ;OTHER UNIFORM TYPE
\r
1007 CAIE 0,(B) ;TYPES THE SAME?
\r
1010 JUMPGE A,CPOPJ1 ;IF ZERO LENGTH ALREADY WON
\r
1012 HRLZI B,(B) ;TYPE TO LH
\r
1013 PUSH P,B ;AND SAVED
\r
1014 PUSHJ P,PUSHCD ;SAVE ARGS
\r
1016 EQUV1: MOVEI C,1(TP) ;POINT TO WHERE WILL GO
\r
1018 MOVE A,-3(TP) ;PUSH ONE OF THE VECTORS
\r
1019 PUSH TP,(A) ; PUSH ELEMENT
\r
1020 MOVEI D,1(TP) ;POINT TO 2D ARG
\r
1022 MOVE A,-3(TP) ;AND PUSH ITS POINTER
\r
1027 SUB TP,[4,,4] ;POP TP
\r
1029 ADDM A,(TP) ;BUMP POINTERS
\r
1031 JUMPL A,EQUV1 ;JUMP IF STILL MORE STUFF
\r
1032 SUB P,[1,,1] ;POP OFF TYPE
\r
1035 UNEQUV: SUB P,[1,,1]
\r
1041 EQCHST: HRRZ B,(C) ; GET LENGTHS
\r
1044 JRST EQCHS3 ;NO, LOSE
\r
1047 JUMPE A,EQCHS4 ;BOTH 0 LENGTH, WINS
\r
1050 ILDB 0,C ;GET NEXT CHARS
\r
1052 CAIE 0,(E) ; SKIP IF STILL WINNING
\r
1053 JRST EQCHS3 ; NOT =
\r
1059 PUSHCD: PUSH TP,(C)
\r
1066 ; REST/NTH/AT/PUT/GET
\r
1070 ARGS1: MOVE E,[JRST WTYP2] ; ERROR CONDITION FOR 2D ARG NOT FIXED
\r
1071 ARGS2: HLRE 0,AB ; CHECK NO. OF ARGS
\r
1072 ASH 0,-1 ; TO - NO. OF ARGS
\r
1073 AOJG 0,TFA ; 0--TOO FEW
\r
1074 AOJL 0,TMA ; MORE THAT 2-- TOO MANY
\r
1075 MOVEI C,1 ; DEFAULT ARG2
\r
1076 JUMPN 0,ARGS4 ; GET STRUCTURED ARG
\r
1077 ARGS3: GETYP A,2(AB)
\r
1078 CAIE A,TFIX ; SHOULD BE FIXED NUMBER
\r
1079 XCT E ; DO ERROR THING
\r
1080 SKIPGE C,3(AB) ; BETTER BE NON-NEGATIVE
\r
1082 ARGS4: MOVEI B,(AB) ; POINT TO STRUCTURED POINTER
\r
1083 PUSHJ P,PTYPE ; GET PRIM TYPE
\r
1084 MOVEI E,(A) ; DISPATCH CODE TO E
\r
1085 MOVE A,(AB) ; GET ARG 1
\r
1091 MFUNCTION REST,SUBR
\r
1094 PUSHJ P,ARGS1 ; GET AND CHECK ARGS
\r
1095 PUSHJ P,@RESTBL(E) ; DO IT BASED ON TYPE
\r
1096 MOVE C,A ; THE FOLLOWING IS TO MAKE STORAGE WORK
\r
1099 CAIN A,SSTORE ; SKIP IF NOT STORAGE
\r
1100 MOVSI C,TSTORA ; USE ITS PRIMTYPE
\r
1104 PRDISP RESTBL,IWTYP1,[[P2WORD,LREST],[PNWORD,UREST],[P2NWOR,VREST],[PARGS,AREST]
\r
1105 [PCHSTR,SREST],[PTMPLT,TMPRST]]
\r
1117 PRDISP ATTBL,IWTYP1,[[P2WORD,LAT],[PNWORD,UAT],[P2NWORD,VAT],[PARGS,AAT]
\r
1118 [PCHSTR,STAT],[PTMPLT,TAT]]
\r
1123 MFUNCTION NTH,SUBR
\r
1129 PUSHJ P,@NTHTBL(E)
\r
1132 PRDISP NTHTBL,IWTYP1,[[P2WORD,LNTH],[PNWORD,UNTH],[P2NWOR,VNTH],[PARGS,ANTH]
\r
1133 [PCHSTR,SNTH],[PTMPLT,TMPLNT]]
\r
1137 MFUNCTION GET,SUBR
\r
1140 MOVE E,IIGETP ; MAKE ARG CHECKER FAIL INTO GETPROP
\r
1141 PUSHJ P,ARGS5 ; CHECK ARGS
\r
1143 SKIPN E,IGETBL(E) ; GET DISPATCH ADR
\r
1144 JRST IGETP ; REALLY PUTPROP
\r
1146 PUSHJ P,(E) ; DISPATCH
\r
1149 PRDISP IGETBL,0,[[P2WORD,LNTH],[PNWORD,UNTH],[P2NWORD,VNTH],[PARGS,ANTH]
\r
1150 [PCHSTR,SNTH],[PTMPLT,TMPLNT]]
\r
1154 MFUNCTION GETL,SUBR
\r
1157 MOVE E,IIGETL ; ERROR HACK
\r
1159 SOJL C,OUTRNG ; LOSER
\r
1161 JRST IGETLO ; REALLY GETPL
\r
1163 PUSHJ P,(E) ; DISPATCH
\r
1166 IIGETL: JRST IGETLO
\r
1168 PRDISP IGTLTB,0,[[P2WORD,LAT],[PNWORD,UAT],[P2NWORD,VAT],[PARGS,AAT]
\r
1172 ; ARG CHECKER FOR PUT/GET/GETL
\r
1174 ARGS5: HLRE 0,AB ; -# OF ARGS
\r
1176 ADDI 0,2 ; 0 OR -1 WIN
\r
1178 AOJL 0,TMA ; MORE THAN 3
\r
1179 JRST ARGS3 ; GET ARGS
\r
1183 MFUNCTION PUT,SUBR
\r
1187 PUSHJ P,ARGS5 ; GET ARGS
\r
1190 CAML AB,[-5,,] ; SKIP IF GOOD ARRGS
\r
1196 MOVE A,(AB) ; RET STRUCTURE
\r
1200 PRDISP IPUTBL,0,[[P2WORD,LPUT],[PNWORD,UPUT],[P2NWORD,VPUT],[PARGS,APUT]
\r
1201 [PCHSTR,SPUT],[PTMPLT,TMPPUT]]
\r
1209 MOVEI B,(AB) ; POINT TO ARG
\r
1211 MOVS E,A ; REAL DISPATCH TO E
\r
1214 GETYP C,A ; IN CASE NEEDED
\r
1218 PRDISP INTBL,OTHIN,[[P2WORD,LNTH1],[PNWORD,UIN],[P2NWORD,VIN],[PARGS,AIN]
\r
1219 [PCHSTR,SIN],[PTMPLT,TIN]]
\r
1221 OTHIN: CAIE C,TLOCN ; ASSOCIATION LOCATIVE
\r
1222 JRST OTHIN1 ; MAYBE LOCD
\r
1229 OTHIN1: CAIE C,TLOCD
\r
1236 MFUNCTION SETLOC,SUBR
\r
1240 MOVEI B,(AB) ; POINT TO ARG
\r
1241 PUSHJ P,PTYPE ; DO TYPE
\r
1242 MOVS E,A ; REAL TYPE
\r
1244 MOVE C,2(AB) ; PASS ARG
\r
1246 MOVE A,(AB) ; IN CASE
\r
1248 PUSHJ P,@SETTBL(E)
\r
1253 PRDISP SETTBL,OTHSET,[[P2WORD,LSTUF],[PNWORD,USTUF],[P2NWORD,VSTUF],[PARGS,ASTUF]
\r
1254 [PCHSTR,SSTUF],[PTMPLT,TSTUF]]
\r
1256 OTHSET: CAIE 0,TLOCN ; ASSOC?
\r
1258 HLLZ 0,VAL(B) ; GET MONITORS
\r
1264 OTHSE1: CAIE 0,TLOCD
\r
1268 ; LREST -- REST A LIST IN B BY AMOUNT IN C
\r
1270 LREST: MOVSI A,TLIST
\r
1274 LREST2: INTGO ;CHECK INTERRUPTS
\r
1275 JUMPE B,OUTRNG ; CANT CDR NIL
\r
1276 HRRZ B,(B) ;CDR THE LIST
\r
1277 SOJG C,LREST2 ;COUNT DOWN
\r
1278 SETZM BSTO(PVP) ;RESET BSTO
\r
1282 ; VREST -- REST A VECTOR, AREST -- REST AN ARG BLOCK
\r
1284 VREST: SKIPA A,$TVEC ; FINAL TYPE
\r
1285 AREST: HRLI A,TARGS
\r
1289 ; UREST -- REST A UVECTOR
\r
1291 STORST: SKIPA A,$TSTORA
\r
1292 UREST: MOVSI A,TUVEC
\r
1293 UREST1: JUMPE C,CPOPJ
\r
1297 CAILE B,-1 ; OUT OF RANGE ?
\r
1302 ; SREST -- REST A STRING
\r
1304 SREST: JUMPE C,SREST1
\r
1305 PUSH P,A ; SAVE TYPE WORD
\r
1306 PUSH P,C ; SAVE AMOUNT
\r
1307 MOVEI D,(A) ; GET LENGTH
\r
1308 CAILE C,(D) ; SKIP IF OK
\r
1310 LDB D,[366000,,B] ;POSITION FIELD OF BYTE POINTER
\r
1311 LDB A,[300600,,B] ;SIZE FIELD
\r
1312 PUSH P,A ;SAVE SIZE
\r
1313 IDIVI D,(A) ;COMPUT BYTES IN 1ST WORD
\r
1314 MOVEI 0,36. ;NOW COMPUTE BYTES PER WORD
\r
1315 IDIVI 0,(A) ;BYTES PER WORD IN 0
\r
1316 MOVE E,0 ;COPY OF BYTES PER WORD TO E
\r
1317 SUBI 0,(D) ;0 # OF UNSUED BYTES IN 1ST WORD
\r
1318 ADDB C,0 ;C AND 0 NO.OF CHARS FROM WORD BOUNDARY
\r
1319 IDIVI C,(E) ;C/ REL WORD D/ CHAR IN LAST
\r
1320 ADDI C,(B) ;POINTO WORD WITH C
\r
1321 POP P,A ;RESTORE BITS PER BYTE
\r
1322 IMULI A,(D) ;A/ BITS USED IN LAST WORD
\r
1324 SUBI 0,(A) ;0 HAS NEW POSITION FIELD
\r
1325 DPB 0,[360600,,B] ;INTO BYTE POINTER
\r
1326 HRRI B,(C) ;POINT TO RIGHT WORD
\r
1327 POP P,C ; RESTORE AMOUNT
\r
1329 SUBI A,(C) ; NEW LENGTH
\r
1330 SREST1: HRLI A,TCHSTR
\r
1333 ; TMPRST -- REST A TEMPLATE DATA STRUCTURE
\r
1335 TMPRST: PUSHJ P,TM.TOE ; CHECK ALL BOUNDS ETC.
\r
1338 MOVE B,C ; RET IN B
\r
1342 ; LAT -- GET A LOCATIVE TO A LIST
\r
1344 LAT: PUSHJ P,LREST ; GET POINTER
\r
1345 JUMPE B,OUTRNG ; YOU LOSE!
\r
1346 MOVSI A,TLOCL ; NEW TYPE
\r
1350 ; UAT -- GET A LOCATIVE TO A UVECTOR
\r
1352 UAT: PUSHJ P,UREST
\r
1356 ; VAT -- GET A LOCATIVE TO A VECTOR
\r
1358 VAT: PUSHJ P,VREST ; REST IT AND TYPE IT
\r
1362 ; AAT -- GET A LOCATIVE TO AN ARGS BLOCK
\r
1364 AAT: PUSHJ P,AREST
\r
1366 POPJL: JUMPGE B,OUTRNG ; LOST
\r
1369 ; STAT -- LOCATIVE TO A STRING
\r
1371 STAT: PUSHJ P,SREST
\r
1372 TRNN A,-1 ; SKIP IF ANY LEFT
\r
1374 HRLI A,TLOCS ; LOCATIVE
\r
1377 ; TAT -- LOCATIVE TO A TEMPLATE
\r
1379 TAT: PUSHJ P,TMPRST
\r
1382 GETYP A,(B) ; GET REAL SAT
\r
1384 HRLS A ; READY TO HIT TABLE
\r
1385 ADD A,TD.LNT+1(TVP)
\r
1387 MOVE C,B ; DATUM TO C
\r
1388 XCT (A) ; GET LENGTH
\r
1389 HLRZS C ; REST COUNTER
\r
1390 SUBI B,(C) ; FLUSH IT OFF
\r
1398 ; LNTH -- NTH OF LIST
\r
1401 LNTH1: PUSHJ P,RMONC0 ; CHECK READ MONITORS
\r
1402 HLLZ A,(B) ; GET GOODIE
\r
1404 JSP E,CHKAB ; HACK DEFER
\r
1407 ; VNTH -- NTH A VECTOR, ANTH -- NTH AN ARGS BLOCK
\r
1414 VIN: PUSHJ P,RMONC0
\r
1419 ; UNTH -- NTH OF UVECTOR
\r
1422 UIN: HLRE C,B ; FIND DW
\r
1424 HLLZ 0,(C) ; GET MONITORS
\r
1428 PUSHJ P,RMONCH ; CHECK EM
\r
1430 MOVE B,(B) ; AND VALUE
\r
1434 ; SNTH -- NTH A STRING
\r
1436 SNTH: PUSHJ P,STAT
\r
1438 PUSH TP,B ; SAVE POINT BYTER
\r
1439 MOVEI C,-1(TP) ; FIND DOPE WORD
\r
1441 HLLZ 0,-1(A) ; GET
\r
1445 ILDB B,B ; GET CHAR
\r
1449 ; TIN -- IN OF A TEMPLATE
\r
1453 ; TMPLNT -- NTH A TEMPLATE DATA STRUCTURE
\r
1456 PUSHJ P,TM.TOE ; GET POINTER TO INS IN E
\r
1457 ADD A,TD.GET+1(TVP) ; POINT TO GETTER
\r
1458 MOVE A,(A) ; GET VECTOR OF INS
\r
1459 ADDI E,-1(A) ; POINT TO INS
\r
1464 ; LPUT -- PUT ON A LIST
\r
1466 LPUT: PUSHJ P,LAT ; POSITION
\r
1470 ; LSTUF -- HERE TO STUFF A LIST ELEMENT
\r
1472 LSTUF: PUSHJ P,MONCH0 ; CHECK OUT MONITOR BITS
\r
1473 GETYP A,C ; ISOLATE TYPE
\r
1474 PUSHJ P,NWORDT ; NEED TO DEFER?
\r
1477 MOVEM D,1(B) ; AND VAL
\r
1480 DEFSTU: PUSH TP,$TLIST
\r
1484 PUSHJ P,CELL2 ; GET WORDS
\r
1490 HLLZ 0,(E) ; GET OLD MONITORS
\r
1491 TLZ 0,TYPMSK ; KILL TYPES
\r
1492 TLO 0,TDEFER ; MAKE DEFERRED
\r
1496 ; VPUT -- PUT ON A VECTOR , APUT -- PUT ON AN RG BLOCK
\r
1501 VPUT: PUSHJ P,VAT ; TREAT LIKE VECTOR
\r
1502 POP TP,D ; GET GOODIE BACK
\r
1505 ; AVSTUF -- CLOBBER ARGS AND VECTORS
\r
1508 VSTUF: PUSHJ P,MONCH0
\r
1516 ; UPUT -- CLOBBER A UVECTOR
\r
1518 UPUT: PUSHJ P,UAT ; GET IT RESTED
\r
1522 ; USTUF -- HERE TO CLOBBER A UVECTOR
\r
1525 SUBM B,E ; C POINTS TO DOPE
\r
1526 GETYP A,(E) ; GET UTYPE
\r
1528 CAIE 0,(A) ; CHECK SAMENESS
\r
1530 HLLZ 0,(E) ; MONITOR BITS IN DOPE WORD
\r
1533 MOVEM D,(B) ; SMASH
\r
1536 ; SPUT -- HERE TO PUT A STRING
\r
1538 SPUT: PUSHJ P,STAT ; REST IT
\r
1542 ; SSTUF -- STUFF A STRING
\r
1544 SSTUF: GETYP 0,C ; BETTER BE CHAR
\r
1549 MOVEI C,-1(TP) ; FIND D.W.
\r
1551 HLLZ 0,(A)-1 ; GET MONITORS
\r
1559 ; TSTUF -- SETLOC A TEMPLATE
\r
1565 ; PUTTMP -- TEMPLATE PUTTER
\r
1568 PUSHJ P,TM.TOE ; GET E POINTING TO SLOT #
\r
1569 ADD A,TD.PUT+1(TVP) ; POINT TO INS
\r
1570 MOVE A,(A) ; GET VECTOR OF INS
\r
1572 POP TP,B ; NEW VAL TO A AND B
\r
1579 TM.LN1: SUBI 0,NUMSAT+1
\r
1580 HRRZ A,0 ; RET FIXED OFFSET
\r
1582 ADD 0,TD.LNT+1(TVP) ; USE LENGTHERS FOR TEST
\r
1586 HRRZS 0 ; POINT TO TABLE ENTRY
\r
1593 TM.TBL: MOVEI E,(D) ; TENTATIVE WINNER IN E
\r
1594 TLNN B,-1 ; SKIP IF REST HAIR EXISTS
\r
1597 PUSH P,A ; SAVE OFFSET
\r
1598 HRLS A ; A IS REL OFFSET TO INS TABLE
\r
1599 ADD A,TD.GET+1(TVP) ; GET ONEOF THE TABLES
\r
1600 MOVE A,(A) ; TABLE POINTER TO A
\r
1601 MOVSI 0,-1(D) ; START SEEING IF PAST TEMP SPEC
\r
1603 JUMPL 0,CPOPJA ; JUMP IF E STILL VALID
\r
1604 HLRZ E,B ; BASIC LENGTH TO E
\r
1605 HLRE 0,A ; LENGTH OF TEMPLATE TO 0
\r
1606 ADDI 0,(E) ; 0 ==> # ELEMENTS IN REPEATING SEQUENCE
\r
1608 SUBM D,E ; E ==> # PAST BASIC WANTED
\r
1610 IDIVI 0,(E) ; A ==> REL REST GUY WANTED
\r
1616 ; TM.TOE -- GET RIGHT TEMPLATE # IN E
\r
1617 ; C/ OBJECT #, B/ OBJECT POINTER
\r
1619 TM.TOE: GETYP 0,(B) ; GET REAL SAT
\r
1620 MOVEI D,(C) ; OBJ # TO D
\r
1621 HLRZ C,B ; REST COUNT
\r
1622 ADDI D,(C) ; FUDGE FOR REST COUNTER
\r
1623 MOVE C,B ; POINTER TO C
\r
1624 PUSHJ P,TM.LN1 ; GET LENGTH IN B (WATCH LH!)
\r
1625 CAILE D,(B) ; CHECK RANGE
\r
1626 JRST OUTRNG ; LOSER, QUIT
\r
1627 JRST TM.TBL ; GO COMPUTE TABLE OFFSET
\r
1629 \f; ROUTINE FOR COMPILER CALLS RETS CODE IN E GOODIE IN A AND B
\r
1640 ; COMPILER CALLS TO MANY OF THESE GUYS
\r
1642 CIREST: PUSHJ P,CPTYEE ; TYPE OF DISP TO E
\r
1646 PUSHJ P,@RESTBL(E)
\r
1649 CIRST1: PUSHJ P,STORST
\r
1652 CINTH: PUSHJ P,CPTYEE
\r
1653 SOJL C,OUTRNG ; CHECK BOUNDS
\r
1654 PUSHJ P,@NTHTBL(E)
\r
1657 CIAT: PUSHJ P,CPTYEE
\r
1662 CSETLO: PUSHJ P,CTYLOC
\r
1663 MOVSS E ; REAL DISPATCH
\r
1664 GETYP 0,A ; INCASE LOCAS OR LOCD
\r
1667 PUSHJ P,@SETTBL(E)
\r
1672 CIN: PUSHJ P,CTYLOC
\r
1673 MOVSS E ; REAL DISPATCH
\r
1685 ; COMPILER'S PUT,GET AND GETL
\r
1690 CIGETL: PUSH P,[1]
\r
1695 JUMPE E,CIGET1 ; REAL GET, NOT NTH
\r
1696 GETYP 0,C ; INDIC FIX?
\r
1699 POP P,E ; GET FLAG
\r
1700 AOS (P) ; ALWAYS SKIP
\r
1701 MOVE C,D ; # TO AN AC
\r
1706 CIGET1: POP P,E ; GET FLAG
\r
1707 JRST @GETTR(E) ; DO A REAL GET
\r
1717 PUSH TP,-1(TP) ; PAIN AND SUFFERING
\r
1723 CAIE 0,TFIX ; YES DO STRUCT
\r
1726 SOJL C,OUTRNG ; CHECK BOUNDS
\r
1727 PUSHJ P,@IPUTBL(E)
\r
1732 CIPUT1: PUSHJ P,IPUT
\r
1735 ; SMON -- SET MONITOR BITS
\r
1736 ; B/ <POINTER TO LOCATIVE>
\r
1737 ; D/ <IORM> OR <ANDCAM>
\r
1741 PUSHJ P,PTYPE ; TO PRIM TYPE
\r
1743 SKIPE A,SMONTB(A) ; DISPATCH?
\r
1746 ; COULD STILL BE LOCN OR LOCD
\r
1748 GETYP A,(B) ; TYPE BACK
\r
1750 JRST SMON2 ; COULD BE LOCD
\r
1751 MOVE C,1(B) ; POINT
\r
1752 HRRI D,VAL(C) ; MAKE INST POINT
\r
1755 SMON2: CAIE A,TLOCD
\r
1759 ; SET LIST/TUPLE/ID LOCATIVE
\r
1761 SMON4: HRR D,1(B) ; POINT TO TYPE WORD
\r
1767 SMON5: HRRZ C,1(B) ; POINT TO TOP OF UV
\r
1769 SUB C,0 ; POINT TO DOPE
\r
1770 HRRI D,(C) ; POINT IN INST
\r
1775 SMON6: MOVEI C,(B) ; FOR BYTDOP
\r
1776 PUSHJ P,BYTDOP ; POINT TO DOPE
\r
1780 PRDISP SMONTB,0,[[P2WORD,SMON4],[P2NWOR,SMON4],[PARGS,SMON4]
\r
1781 [PNWORD,SMON5],[PCHSTR,SMON6]]
\r
1784 ; COMPILER'S MONAD?
\r
1796 ; FUNCTION TO DECIDE IF FURTHER DECOMPOSITION POSSIBLE
\r
1798 MFUNCTION MONAD,SUBR,MONAD?
\r
1802 MOVE B,AB ; CHECK PRIM TYPE
\r
1804 JUMPE A,ITRUTH ;RETURN ARGUMENT
\r
1806 JRST @MONTBL(A) ;DISPATCH ON PTYPE
\r
1809 PRDISP MONTBL,IFALSE,[[P2NWORD,MON1],[PNWORD,MON1],[PARGS,MON1]
\r
1810 [PCHSTR,CHMON],[PTMPLT,TMPMON]]
\r
1812 MON1: JUMPGE B,ITRUTH ;EMPTY VECTOR
\r
1815 CHMON: HRRZ B,(AB)
\r
1819 TMPMON: PUSHJ P,LNTMPL
\r
1823 CISTRU: GETYP A,A ; COMPILER CALL
\r
1828 ISTRUC: PUSHJ P,SAT ; STORAGE TYPE
\r
1830 AOS (P) ; SKIP IF WINS
\r
1833 ; SUBR TO CHECK FOR LOCATIVE
\r
1835 MFUNCTION %LOCA,SUBR,[LOCATIVE?]
\r
1843 ; SKIPS IF TYPE IN A IS A LOCATIVE
\r
1845 LOCQ: GETYP A,(B) ; GET TYPE
\r
1846 LOCQQ: PUSH P,A ; SAVE FOR LOCN/LOCD
\r
1855 LOCQ1: POP P,A ; RESTORE TYPE
\r
1862 ; MUDDLE SORT ROUTINE
\r
1864 ; P-STACK OFFSETS MUDDLE SORT ROUTINE
\r
1866 ; P-STACK OFFSETS FOR THIS PROGRAM
\r
1868 XCHNG==0 ; FLAG SAYING AN EXCHANGE HAS HAPPENED
\r
1869 PLACE==-1 ; WHERE WE ARE NOW
\r
1870 UTYP==-2 ; TYPE OF UNIFORM VECTOR
\r
1871 DELT==-3 ; DIST BETWEEN COMPARERS
\r
1873 MFUNCTION SORT,SUBR
\r
1877 HLRZ 0,AB ; CHECK FOR ENOUGH ARGS
\r
1880 GETYP A,(AB) ; 1ST MUST EITHER BE FALSE OR APPLICABLE
\r
1882 JRST SORT1 ; FALSE, OK
\r
1883 PUSHJ P,APLQ ; IS IT APPLICABLE
\r
1884 JRST NAPT ; NO, LOSER
\r
1887 ADD B,[2,,2] ; BUMP TO POINT TO MAIN ARRAY
\r
1888 SETZB D,E ; 0 # OF STUCS AND LNTH
\r
1890 SORT2: GETYP A,(B) ; GET ITS TYPE
\r
1891 PUSHJ P,PTYPE ; IS IT STRUCTURED?
\r
1892 MOVEI C,1 ; CHECK TYPE OF STRUC
\r
1893 CAIN A,PNWORD ; UVEC?
\r
1896 CAIN A,P2NWORD ; VECTOR
\r
1899 PUSH TP,(B) ; PUSH IT
\r
1901 ADD B,[2,,2] ; GO ON
\r
1902 MOVEI A,1 ; DEFAULT REC SIZE
\r
1903 PUSHJ P,NXFIX ; SIZE OF RECORD?
\r
1904 HLRZ 0,-2(TP) ; -LNTH OF STUC
\r
1905 HRRZ A,(TP) ; LENGTH OF REC
\r
1906 IDIVI 0,(A) ; DIV TO GET - # OF RECS
\r
1907 SKIPN D ; PREV LENGTH EXIST?
\r
1908 MOVE D,0 ; NO USE THIS
\r
1911 MOVEI A,0 ; DEF REC SIZE
\r
1912 PUSHJ P,NXFIX ; AND OFFSET OF KEY
\r
1914 JUMPL B,SORT2 ; GO ON
\r
1915 HRRM E,4(TB) ; SAVE THAT IN APPROPRIATE PLACE
\r
1918 CAMG 0,5(TB) ; CHECK FOR BAD OFFSET
\r
1921 ; NOW CHECK WHATEVER STUCTURE THIS IS IS UNIFORM AND HAS GOOD ELEMENTS
\r
1923 HLRE B,1(TB) ; COMP LENGTH
\r
1925 HRRZ C,2(TB) ; GET VEC/UVEC FLAG
\r
1928 JUMPE C,.+3 ; SKIP FOR UVEC
\r
1929 MOVE 0,[1,,1] ; ELSE FUDGE KEY OFFSET
\r
1931 HRRZ 0,3(TB) ; GET REC LENGTH
\r
1932 IDIV D,0 ; # OF RECS
\r
1934 CAIG D,1 ; MORE THAN 1?
\r
1935 JRST SORTD ; NO, DONE ALREADY
\r
1936 GETYP 0,(AB) ; TYPE OF COMPARER
\r
1937 CAIE 0,TFALSE ; IF FALSE, STRUCT MUST CONTAIN FIX,FLOAT,ATOM OR STRING
\r
1938 JRST SORT3 ; USER SUPPLIED COMPARER, LET HIM WORRY
\r
1940 ; NOW CHECK OUT ELEMENT TYPES
\r
1942 JUMPN C,SORT5 ; JUMP IF GENERAL
\r
1943 MOVEI D,1(B) ; FIND END OF VECTOR
\r
1944 ADD D,1(TB) ; D POINTS TO END
\r
1945 PUSHJ P,TYPCH1 ; GET TYPE AND CHECK IT
\r
1948 SORT5: MOVE D,1(TB) ; POINT TO VEC
\r
1949 ADD D,5(TB) ; INTO REC TO KEY
\r
1952 SAMELP: GETYP C,-1(D) ; GET TYPE
\r
1953 CAIE 0,(C) ; COMPARE TYPE
\r
1955 ADD D,3(TB) ; TO NEXT RECORD
\r
1958 SORT6: CAIE A,S1WORD ; 1 WORDS?
\r
1961 MOVSI A,400000 ; SET UP MASK
\r
1962 SORT9: PUSHJ P,ISORT
\r
1967 SORT7: CAIE A,SATOM ; ATOMS?
\r
1969 MOVE E,[-3,,ATMSRT] ; SET UP FOR ATOMS
\r
1970 MOVE A,[430140,,3(D)] ; BIT POINTER FOR ATOMS
\r
1973 SORT8: MOVE E,[1,,STRSRT] ; MUST BE STRING SORT
\r
1974 MOVE A,[430140,,(D)] ; BYTE POINTER FOR STRINGER
\r
1977 ; TABLES FOR RADIX SORT CHECKERS
\r
1983 TST1: PUSHJ P,I.TST1
\r
1987 TST2: PUSHJ P,I.TST2
\r
2003 ; INTEGER SORT SPECIFIC ROUTINES
\r
2005 I.TST1: JUMPL A,I.TST3
\r
2006 I.TST4: TDNE A,(D)
\r
2010 I.TST2: JUMPL A,I.TST4
\r
2011 I.TST3: TDNN A,(D)
\r
2015 ; ATOM SORT SPECIFIC ROUTINES
\r
2017 A.TST1: MOVE D,(D) ; GET AN ATOM
\r
2018 CAMG E,D ; SKIP IF NOT EXHAUSTED
\r
2020 TLZ A,40 ; TELL A BIT HAS HAPPENED
\r
2021 LDB D,A ; GET THE BIT
\r
2023 AOS (P) ; SKIP IF ON
\r
2026 A.TST2: PUSHJ P,A.TST1 ; USE OTHER ROUTINE
\r
2030 A.NXBI: TLNN A,770000 ; CHECK FOR WORD CHANGE
\r
2031 SUB E,[1,,0] ; FIX WORD CHECKER
\r
2035 A.PREB: ADD A,[10000,,] ; AH FOR A DECR BYTE POINTER
\r
2037 CAMG A,[437777,,-1] ; SKIP IF BACKED OVER WORD
\r
2039 TLZ A,770000 ; CLOBBER POSIT FIELD
\r
2040 SUBI A,1 ; DECR WORD POS FIELD
\r
2041 ADD E,[1,,0] ; AND FIX WORD HACKER
\r
2044 ; STRING SPECIFIC SORT ROUTINES
\r
2046 S.TST1: HRLZ 0,-1(D) ; LENGTH OF STRING
\r
2047 IMULI 0,7 ; IN BITS
\r
2048 HRRI 0,-1 ; MAKE SURE BIGGER RH
\r
2049 CAMG 0,E ; SKIP IF MORE BITS LEFT
\r
2050 POPJ P, ; DON TSKIP
\r
2051 TLZ A,40 ; BIT FOUND
\r
2052 HLRZ 0,(D) ; CHECK FOR SIMPLE CASE
\r
2053 HRRZ D,(D) ; POINT TO STRING
\r
2054 CAIN 0,440700 ; SKIP IF HAIRY
\r
2057 PUSH P,A ; SAVE BYTER
\r
2058 MOVEI A,440700 ; COMPUTE BITS NOT USED 1ST WORD
\r
2060 HLRZ 0,(P) ; GET BIT POINTER
\r
2061 SUBI 0,(A) ; UPDATE POS FIELD
\r
2062 JUMPGE 0,.+2 ; NO NEED FOR NEXT WORD
\r
2065 HRRZ A,(P) ; REBUILD BYTE POINTER
\r
2067 LDB 0,0 ; GET THE DAMN BYTE
\r
2071 S.TST3: LDB 0,A ; GET BYTE FOR EASY CASE
\r
2076 S.TST2: PUSHJ P,S.TST1
\r
2080 S.NXBI: IBP A ; BUMP BYTER
\r
2081 TLNN A,770000 ; SKIP IF NOT END BIT
\r
2082 IBP A ; SKIP END BIT (NOT USED IN ASCII STRINGS)
\r
2083 ADD E,[1,,0] ; COUNT BIT
\r
2086 S.PREB: SUB E,[1,,0] ; DECR CHAR COUNT
\r
2087 ADD A,[10000,,0] ; PLEASE GIVE ME A DECRBYTEPNTR
\r
2089 CAMG A,[437777,,-1]
\r
2091 TLC A,450000 ; POINT TO LAST USED BIT IN WORD
\r
2095 ; SIMPLE RADIX EXCHANGE
\r
2097 ISORT: MOVE B,1(TB) ; START OF VECTOR
\r
2098 HLRE D,B ; COMPUTE POINTER TO END OF IT
\r
2099 SUBM B,D ; FIND END
\r
2102 ISORT1: PUSH TP,(TB)
\r
2104 MOVE 0,C ; SEE IF HAVE MET AT MIDDLE
\r
2108 JRST ISORT7 ; HAVE MET, LEAVE
\r
2109 PUSH TP,(TB) ; SAVE OTHER POINTER
\r
2113 MOVE B,(TP) ; IN CASE MOVED
\r
2116 ISORT3: HRRZ D,5(TB) ; OFFSET TO KEY
\r
2117 ADDI D,(B) ; POINT TO KEY
\r
2118 XCT TST1(E) ; CHECK FOR LOSER
\r
2120 SUB C,3(TB) ; IS THERE ONE TO EXCHANGE WITH
\r
2123 XCT TST2(E) ; SKIP IF A POSSIBLE EXCHANGE
\r
2124 JRST ISORT2 ; NO EXCH, KEEP LOOKING
\r
2126 PUSHJ P,EXCHM ; DO THE EXCHANGE
\r
2128 ISORT4: ADD B,3(TB) ; HAVE EXCHANGED, MOVE ON
\r
2129 ISORT2: CAME B,C ; MET?
\r
2130 JRST ISORT3 ; MORE TO CHECK
\r
2131 XCT NXBIT(E) ; NEXT BIT
\r
2132 MOVE B,(TP) ; RESTORE TOP POINTER
\r
2133 SUB TP,[2,,2] ; FLUSH IT
\r
2136 PUSHJ P,ISORT1 ; SORT SUB AREA
\r
2137 MOVE C,(TP) ; AND OTHER SUB AREA
\r
2139 ISORT6: XCT PREBIT(E)
\r
2140 ISORT7: MOVE B,(TP)
\r
2144 ; SCHELL SORT FOR USER SUPPLIED COMPARER
\r
2147 ASH D,-1 ; COMPUTE INITIAL D
\r
2148 PUSH P,D ; AND SAVE IT
\r
2149 PUSH P,[0] ; MAY HOLD UTYPE OF VECTOR
\r
2150 HRRZ 0,(TB) ; 0 NON ZERO MEANS GEN VECT
\r
2151 JUMPN 0,SSORT1 ; DONT COMPUTE UTYPE
\r
2153 HRRZ D,1(TB) ; FIND TYPE
\r
2156 MOVSM D,(P) ; AND SAVE
\r
2157 SSORT1: PUSH P,[0] ; CURRENT PLACE IN VECTOR
\r
2158 PUSH P,[0] ; EXCHANGE FLAG
\r
2162 ; OUTER LOOP STARTS HERE
\r
2164 OUTRLP: SETZM XCHNG(P) ; NO EXHCANGE YET
\r
2167 INRLP: PUSH TP,(AB) ; PUSH USER COMPARE FCN
\r
2169 MOVE C,PLACE(P) ; GET CURRENT PLACE
\r
2170 ADD C,1(TB) ; ADD POINTER TO VEC IN
\r
2171 ADD C,5(TB) ; OFFSET TO KEY
\r
2174 IMUL D,DELT(P) ; TIMES WORDS PER REC
\r
2177 MCALL 3,APPLY ; APPLY IT
\r
2178 GETYP 0,A ; TYPE OF RETURN
\r
2179 CAIN 0,TFALSE ; SKIP IF MUST CHANGE
\r
2182 MOVE C,1(TB) ; POINT TO START
\r
2187 PUSHJ P,EXCHM ; EXCHANGE THEM
\r
2188 SETOM XCHNG(P) ; SAY AN EXCHANGE TOOK PLACE
\r
2190 INRLP1: MOVE C,3(TB) ; GET OFFSET
\r
2194 ADD C,D ; CHECK FOR OVERFLOW
\r
2197 SKIPE XCHNG(P) ; ANY EXCHANGES?
\r
2198 JRST OUTRLP ; YES, RESET PLACE AND GO
\r
2199 SOSG D,DELT(P) ; SKIP IF DIST WAS 1
\r
2201 ADDI D,2 ; COMPUTE NEW DIST
\r
2206 SORTD: MOVE A,2(AB) ; DONE, RET 1ST STRUC
\r
2210 ; ROUTINE TO GET NEXT ARG IF ITS FIX
\r
2212 NXFIX: JUMPGE B,NXFIX1 ; NONE LEFT, USE DEFAULT
\r
2213 GETYP 0,(B) ; TYPE
\r
2214 CAIE 0,TFIX ; FIXED?
\r
2215 JRST NXFIX1 ; NO, USE DEFAULT
\r
2216 MOVE A,1(B) ; GET THE NUMBER
\r
2217 ADD B,[2,,2] ; BUMP TO NEXT ARG
\r
2218 NXFIX1: HRLI C,TFIX
\r
2219 TRNE C,-1 ; SKIP IF UV
\r
2220 ASH A,1 ; FUDGE FOR VEC/UVEC
\r
2226 GETELM: SKIPN A,UTYP-1(P) ; SKIP IF UVECT
\r
2227 MOVE A,-1(C) ; GGET GEN TYPE
\r
2232 TYPCH1: GETYP A,-1(D) ; GET TYPE
\r
2233 MOVEI 0,(A) ; SAVE IN 0
\r
2234 PUSHJ P,SAT ; AND SAT
\r
2235 CAIE A,SCHSTR ; STRING
\r
2238 CAIN A,S1WORD ; 1-WORD GOODIE
\r
2242 ; HERE TO DO EXCHANGE
\r
2245 PUSH P,A ; SAVE VITAL ACS
\r
2248 SUB B,1(TB) ; COMPUTE RECORD #
\r
2250 HRRZ 0,3(TB) ; GET REC LENGTH
\r
2251 IDIV B,0 ; DIV BY REC LENGTH
\r
2253 SUB C,1(TB) ; SAME FOR C
\r
2255 IDIV C,0 ; NOW HAVE OTHER RECORD
\r
2257 HRRE D,4(TB) ; - # OF STUCS
\r
2258 MOVSI D,(D) ; MAKE AN AOBJN POINTER
\r
2259 HRRI D,(TB) ; TO TEMPPS
\r
2261 RECLP: HRRZ 0,3(D) ; GET REC LENGTH
\r
2262 MOVN E,3(D) ; NOW AOBJN TO REC
\r
2265 MOVEI A,(C) ; COMP START OF REC
\r
2266 IMUL A,0 ; TIMES REC LENGTH
\r
2270 ADD A,1(D) ; POINT TO OTHER RECORD
\r
2272 EXCHLP: EXCH 0,(A)
\r
2278 ADD D,[1,,6] ; TO NEXT STRUC
\r
2279 JUMPL D,RECLP ; IF MORE
\r
2287 ; FUNCTION TO DETERMINE MEMBERSHIP IN LISTS AND VECTORS
\r
2289 MFUNCTION MEMBER,SUBR
\r
2291 MOVE E,[PUSHJ P,EQLTST] ;TEST ROUTINE IN E
\r
2294 MFUNCTION MEMQ,SUBR
\r
2296 MOVE E,[PUSHJ P,EQTST] ;EQ TESTER
\r
2299 MOVE B,AB ;POINT TO FIRST ARG
\r
2300 PUSHJ P,PTYPE ;CHECK PRIM TYPE
\r
2301 ADD B,[2,,2] ;POINT TO 2ND ARG
\r
2303 JUMPE A,WTYP2 ;2ND WRONG TYPE
\r
2306 MOVE C,2(AB) ; FOR TUPLE CASE
\r
2307 SKIPE B,3(AB) ;GOBBLE LIST VECTOR ETC. POINTER
\r
2308 PUSHJ P,@MEMTBL(A) ;DISPATCH
\r
2309 JRST IFALSE ;OR REPORT LOSSAGE
\r
2312 PRDISP MEMTBL,IWTYP2,[[P2WORD,MEMLST],[PNWORD,MUVEC],[P2NWORD,MEMVEC]
\r
2313 [PARGS,MEMTUP],[PCHSTR,MEMCH],[PTMPLT,MEMTMP]]
\r
2317 MEMLST: MOVSI 0,TLIST ;SET B'S TYPE TO LIST
\r
2319 JUMPE B,MEMLS6 ; EMPTY LIST LOSE IMMEDIATE
\r
2321 MEMLS1: INTGO ;CHECK INTERRUPTS
\r
2322 MOVEI C,(B) ;COPY POINTER
\r
2323 GETYP D,(C) ;GET TYPE
\r
2325 CAIE D,TDEFER ;DEFERRED?
\r
2327 MOVE C,1(C) ;GET DEFERRED DATUM
\r
2328 GETYPF A,(C) ;GET FULL TYPE WORD
\r
2329 MEMLS2: MOVE C,1(C) ;GET DATUM
\r
2330 XCT E ;DO THE COMPARISON
\r
2331 JRST MEMLS3 ;NO MATCH
\r
2334 MEMLS6: SETZM BSTO(PVP) ;RESET B'S TYPE
\r
2337 MEMLS3: HRRZ B,(B) ;STEP THROGH
\r
2338 JUMPN B,MEMLS1 ;STILL MORE TO DO
\r
2339 MEMLS4: MOVSI A,TFALSE ;RETURN FALSE
\r
2340 JRST MEMLS6 ;RETURN 0
\r
2344 MEMVEC: MOVSI A,TVEC ;CLOBBER B'S TYPE TO VECTOR
\r
2345 JUMPGE B,MEMLS4 ;EMPTY VECTOR
\r
2348 MEMV1: INTGO ;CHECK FOR INTS
\r
2349 GETYPF A,(B) ;GET FULL TYPE
\r
2350 MOVE C,1(B) ;AND DATA
\r
2351 XCT E ;DO COMPARISON INS
\r
2352 JRST MEMV2 ;NOT EQUAL
\r
2354 JRST MEMLS5 ;RETURN WITH POINTER
\r
2356 MEMV2: ADD B,[2,,2] ;INCREMENT AND GO
\r
2357 JUMPL B,MEMV1 ;STILL WINNING
\r
2359 JRST MEMLS4 ;AND RETURN FALSE
\r
2361 MUVEC: JUMPGE B,MEMLS4
\r
2362 GETYP A,-1(TP) ;GET TYPE OF GODIE
\r
2363 HLRE C,B ;LOOK FOR UNIFORM TYPE
\r
2364 SUBM B,C ;DOPE POINTER TO C
\r
2365 GETYP C,(C) ;GET THE TYPE
\r
2366 CAIE A,(C) ;ARE THEY THE SAME?
\r
2367 JRST MEMLS4 ;NO, LOSE
\r
2373 MOVSI A,(C) ;TYPE TO LH
\r
2374 PUSH P,A ; SAVE FOR EACH TEST
\r
2376 MUVEC1: INTGO ;CHECK OUT INTS
\r
2377 MOVE C,(B) ;GET DATUM
\r
2378 MOVE A,(P) ; GET TYPE
\r
2380 AOBJN B,MUVEC1 ;LOOP TO WINNAGE
\r
2383 JUMPGE B,MEMV3 ;LOSE RETURN
\r
2385 MUVEC2: JRST MEMLS5
\r
2388 MEMCH: GETYP A,-1(TP) ;IS ARG A SINGLE CHAR
\r
2389 CAIE A,TCHRS ;SKIP IF POSSIBLE WINNER
\r
2392 MOVE D,(TP) ; AND CHAR
\r
2394 MEMCH1: SOJL 0,MEMV3
\r
2397 CAIE A,(D) ;CHECK IT
\r
2404 MEMSTR: CAME E,[PUSHJ P,EQLTST]
\r
2407 CAIE A, TCHSTR ; A SHOULD HAVE TCHSTR IN RIGHT HALF
\r
2409 MOVEI 0,(C) ; GET # OF CHAR INTO 0
\r
2411 PUSH P,D ; PUTS 1ST CHAR OF 1ST ARG ONTO STACK
\r
2413 MEMST1: SOJL 0,MEMLS ; HUNTS FOR FIRST MATCHING CHAR
\r
2417 SOJA C,MEMST1 ; MATCH FAILS TRY NEXT
\r
2423 MOVE E,(TP) ; MATCH WINS SAVE OLD VALUES FOR FAILING LOOP
\r
2424 HRRZ C,-1(TP) ; LENGTH OF 1ARG
\r
2425 MEMST2: SOJE C,MEMWN ; WON -RAN OUT OF 1ARG FIRST-
\r
2426 SOJL MEMLSR ; LOST -RAN OUT OF 2ARG-
\r
2429 CAIN A,(D) ; SKP IF POSSIBLY LOST -BACK TO MEMST1-
\r
2438 MEMWN: MOVE B,-2(P) ; SETS UP ARGS LIKE MEMCH2 - HAVE WON
\r
2443 MEMLSR: SUB P,[5,,5]
\r
2446 MEMLS: SUB P,[1,,1]
\r
2449 ; MEMBERSHIP FOR TEMPLATE HACKER
\r
2451 MEMTMP: GETYP 0,(B) ; GET REAL SAT
\r
2455 PUSH TP,B ; SAVE GOOEIE
\r
2456 PUSHJ P,TM.LN1 ; GET LENGTH
\r
2458 HLRZ A,(TP) ; FUDGE FOR REST
\r
2460 PUSH P,B ; SAVE LENGTH
\r
2464 MOVEM A,BSTO+1(PVP)
\r
2466 MEMTM1: SETZM BSTO(PVP)
\r
2471 PUSHJ P,TMPLNT ; GET ITEM
\r
2472 EXCH C,B ; VALUE TO C, POINTER BACK TO B
\r
2479 HRL B,(P) ; DO APPROPRIATE REST
\r
2481 MEMTM2: SUB P,[4,,4]
\r
2488 CAMN C,(TP) ;CHECK VALUE
\r
2489 CAIE 0,(A) ;AND TYPE
\r
2493 EQLTST: PUSH TP,BSTO(PVP)
\r
2498 PUSH P,E ;SAVE INS
\r
2499 MOVEI C,-5(TP) ;SET UP CALL TO IEQUAL
\r
2501 AOS -1(P) ;ASSUME SKIP
\r
2502 PUSHJ P,IEQUAL ;GO INO EQUAL
\r
2503 SOS -1(P) ;UNDO SKIP
\r
2504 SUB TP,[2,,2] ;AND POOP OF CRAP
\r
2510 ; COMPILER MEMQ AND MEMBER
\r
2512 CIMEMB: SKIPA E,[PUSHJ P,EQLTST]
\r
2514 CIMEMQ: MOVE E,[PUSHJ P,EQTST]
\r
2521 MOVE B,D ; STRUCT TO B
\r
2522 PUSHJ P,@MEMTBL(A)
\r
2523 TDZA 0,0 ; FLAG NO SKIP
\r
2524 MOVEI 0,1 ; FLAG SKIP
\r
2527 SOS (P) ; SKIP RETURN
\r
2531 ; FUNCTION TO RETURN THE TOP OF A VECTOR , CSTRING OR UNIFORM VECTOR
\r
2533 MFUNCTION TOP,SUBR
\r
2537 MOVE B,AB ;CHECK ARG
\r
2542 PUSHJ P,@TOPTBL(E) ;DISPATCH
\r
2545 PRDISP TOPTBL,IWTYP1,[[PNWORD,UVTOP],[P2NWORD,VTOP],[PCHSTR,CHTOP],[PARGS,ATOP]
\r
2548 BCKTOP: MOVEI B,(B) ; FIX UP POINTER
\r
2552 UVTOP: SKIPA A,$TUVEC
\r
2553 VTOP: MOVSI A,TVEC
\r
2556 HLRE C,B ;AND -LENGTH
\r
2558 SUB B,C ;POINT TO DOPE WORD
\r
2559 HLRZ D,1(B) ;TOTAL LENGTH
\r
2560 SUBI B,-2(D) ;POINT TO TOP
\r
2561 MOVNI D,-2(D) ;-LENGTH
\r
2562 HRLI B,(D) ;B NOW POINTS TO TOP
\r
2567 LDB 0,[360600,,(TP)] ; POSITION FIELD
\r
2568 LDB E,[300600,,(TP)] ; AND SIZE FILED
\r
2569 IDIVI 0,(E) ; 0/ BYTES IN 1ST WORD
\r
2570 MOVEI C,36. ; BITS PER WORD
\r
2571 IDIVI C,(E) ; BYTES PER WORD
\r
2573 SUBM C,0 ; UNUSED BYTES I 1ST WORD
\r
2574 ADD 0,-1(TP) ; LENGTH OF WORD BOUNDARIED STRING
\r
2575 MOVEI C,-1(TP) ; GET DOPE WORD
\r
2577 HLRZ C,(A) ; GET LENGTH
\r
2578 SUBI A,-1(C) ; START +1
\r
2579 MOVEI B,(A) ; SETUP BYTER
\r
2581 SUB A,(TP) ; WORDS DIFFERENT
\r
2582 IMUL A,(P) ; CHARS EXTRA
\r
2583 SUBM 0,A ; FINAL TOTAL TO A
\r
2594 GETATO: HLRE C,B ;GET -LENGTH
\r
2596 SUB B,C ;POINT PAST
\r
2597 GETYP 0,(B) ;GET NEXT TYPE (ASSURED OF BEING EITHER TINFO OR TENTRY)
\r
2598 CAIN 0,TENTRY ;IF ENTRY
\r
2599 JRST EASYTP ;WANT UNEVALUATED ARGS
\r
2600 HRRE C,(B) ;ELSE-- GET NO. OF ARGS (*-2)
\r
2601 SUBI B,(C) ;GO TO TOP
\r
2602 TLCA B,-1(C) ;STORE NUMBER IN TOP POINTER
\r
2603 EASYTP: MOVE B,FRAMLN+ABSAV(B) ;GET ARG POINTER
\r
2607 ; COMPILERS ENTRY TO TOP
\r
2609 CITOP: PUSHJ P,CPTYEE
\r
2610 CAIN E,P2WORD ; LIST?
\r
2612 PUSHJ P,@TOPTBL(E)
\r
2615 ; FUNCTION TO CLOBBER THE CDR OF A LIST
\r
2617 MFUNCTION PUTREST,SUBR,[PUTREST]
\r
2620 MOVE B,AB ;COPY ARG POINTER
\r
2621 PUSHJ P,PTYPE ;CHECK IT
\r
2622 CAIE A,P2WORD ;LIST?
\r
2623 JRST WTYP1 ;NO, LOSE
\r
2624 ADD B,[2,,2] ;AND NEXT ONE
\r
2627 JRST WTYP2 ;NOT LIST, LOSE
\r
2628 HRRZ B,1(AB) ;GET FIRST
\r
2629 MOVE D,3(AB) ;AND 2D LIST
\r
2632 HRRM D,(B) ;CLOBBER
\r
2633 MOVE A,(AB) ;RETURN CALLED TYPE
\r
2638 ; FUNCTION TO BACK UP A VECTOR, UVECTOR OR CHAR STRING
\r
2640 MFUNCTION BACK,SUBR
\r
2644 MOVEI C,1 ;ASSUME BACKING UP ONE
\r
2645 JUMPGE AB,TFA ;NO ARGS IS TOO FEW
\r
2646 CAML AB,[-2,,0] ;SKIP IF MORE THAN 2 ARGS
\r
2647 JRST BACK1 ;ONLY ONE ARG
\r
2648 GETYP A,2(AB) ;GET TYPE
\r
2649 CAIE A,TFIX ;MUST BE FIXED
\r
2651 SKIPGE C,3(AB) ;GET NUMBER
\r
2653 CAMGE AB,[-4,,0] ;SKIP IF WINNING NUMBER OF ARGS
\r
2655 BACK1: MOVE B,AB ;SET UP TO FIND TYPE
\r
2656 PUSHJ P,PTYPE ;GET PRIM TYPE
\r
2659 MOVE B,1(AB) ;GET DATUM
\r
2660 PUSHJ P,@BCKTBL(E)
\r
2663 PRDISP BCKTBL,IWTYP2,[[PNWORD,BACKU],[P2NWORD,BACKV],[PCHSTR,BACKC],[PARGS,BACKA]
\r
2666 BACKV: LSH C,1 ;GENERAL, DOUBLE AMOUNT
\r
2668 BACKU: MOVSI A,TUVEC
\r
2671 HRLI C,(C) ;TO BOTH HALVES
\r
2672 SUB B,C ;BACK UP VECTOR POINTER
\r
2673 HLRE C,B ;FIND OUT IF OVERFLOW
\r
2674 SUBM B,C ;DOPE POINTER TO C
\r
2675 HLRZ D,1(C) ;GET LENGTH
\r
2676 SUBI C,-2(D) ;POINT TO TOP
\r
2678 CAILE C,(B) ;SKIP IF A WINNER
\r
2679 JRST OUTRNG ;COMPLAIN
\r
2682 BCKTMP: MOVSI C,(C)
\r
2683 SUB B,C ; FIX UP POINTER
\r
2690 ADDI A,(C) ; NEW LENGTH
\r
2692 PUSH P,A ; SAVE COUNT
\r
2693 LDB E,[300600,,B] ;BYTE SIZE
\r
2694 MOVEI 0,36. ;BITS PER WORD
\r
2695 IDIVI 0,(E) ;DIVIDE TO FIND BYTES/WORD
\r
2696 IDIV C,0 ;C/ WORDS BACK, D/BYTES BACK
\r
2697 SUBI B,(C) ;BACK WORDS UP
\r
2698 JUMPE D,CHBOUN ;CHECK BOUNDS
\r
2700 IMULI 0,(E) ;0/ BITS OCCUPIED BY FULL WORD
\r
2701 LDB A,[360600,,B] ;GET POSITION FILED
\r
2702 BACKC2: ADDI A,(E) ;BUMP
\r
2706 SUBI B,1 ;DECREMENT POINTER PART
\r
2707 BACKC1: SOJG D,BACKC2 ;DO FOR ALL BYTES
\r
2711 DPB A,[360600,,B] ;FIX UP POINT BYTER
\r
2712 CHBOUN: MOVEI C,-1(TP)
\r
2713 PUSHJ P,BYTDOP ; FIND DOPE WORD
\r
2715 SUBI A,-1(C) ; POINT TO TOP
\r
2716 MOVE C,B ; COPY BYTER
\r
2718 CAILE A,(C) ; SKIP IF OK
\r
2720 POP P,A ; RESTORE COUNT
\r
2725 BACKA: LSH C,1 ;NUMBER TIMES 2
\r
2726 HRLI C,(C) ;TO BOTH HALVES
\r
2727 SUB B,C ;FIX POINTER
\r
2728 MOVE E,B ;AND SAVE
\r
2729 PUSHJ P,GETATO ;LOOK A T TOP
\r
2730 CAMLE B,E ;COMPARE
\r
2737 CIBACK: PUSHJ P,CPTYEE
\r
2741 PUSHJ P,@BCKTBL(E)
\r
2744 MFUNCTION STRCOMP,SUBR
\r
2757 JRST ATMCMP ; MAYBE ATOMS
\r
2763 MOVEI A,(A) ; ISOLATR LENGHTS
\r
2766 STRCO2: SOJL A,CHOTHE ; ONE STRING EXHAUSTED, CHECK OTHER
\r
2767 SOJL C,1BIG ; 1ST IS BIGGER
\r
2770 CAIN 0,(E) ; SKIP IF DIFFERENT
\r
2772 CAIL 0,(E) ; SKIP IF 2D BIGGER THAN 1ST
\r
2777 CHOTHE: JUMPN C,2BIG ; 2 IS BIGGER
\r
2778 SM.CMP: TDZA B,B ; RETURN 0
\r
2780 RETFIX: MOVSI A,TFIX
\r
2783 ATMCMP: CAIE 0,TATOM ; COULD BE ATOM
\r
2784 JRST WTYP1 ; NO, QUIT
\r
2789 CAMN B,D ; SAME ATOM?
\r
2791 ADD B,[3,,3] ; SKIP VAL CELL ETC.
\r
2794 ATMCM1: MOVE 0,(B) ; GET A WORD OF CHARS
\r
2795 CAME 0,(D) ; SAME?
\r
2796 JRST ATMCM3 ; NO, GET DIF
\r
2798 AOBJN D,ATMCM1 ; MORE TO COMPARE
\r
2799 JRST 1BIG ; 1ST IS BIGGER
\r
2802 ATMCM2: AOBJP D,SM.CMP ; EQUAL
\r
2805 ATMCM3: LSH 0,-1 ; AVOID SIGN LOSSAGE
\r
2812 \f;ERROR COMMENTS FOR SOME PRIMITIVES
\r
2814 OUTRNG: PUSH TP,$TATOM
\r
2815 PUSH TP,EQUOTE OUT-OF-BOUNDS
\r
2818 WRNGUT: PUSH TP,$TATOM
\r
2819 PUSH TP,EQUOTE UNIFORM-VECTORS-TYPE-DIFFERS
\r
2822 SLOSE0: PUSH TP,$TATOM
\r
2823 PUSH TP,EQUOTE VECTOR-LENGTHS-DIFFER
\r
2826 SLOSE1: PUSH TP,$TATOM
\r
2827 PUSH TP,EQUOTE KEYS-WRONG-TYPE
\r
2830 SLOSE2: PUSH TP,$TATOM
\r
2831 PUSH TP,EQUOTE KEY-TYPES-DIFFER
\r
2834 SLOSE3: PUSH TP,$TATOM
\r
2835 PUSH TP,EQUOTE KEY-OFFSET-OUTSIDE-RECORD
\r
2838 SLOSE4: PUSH TP,$TATOM
\r
2839 PUSH TP,EQUOTE NON-INTEGER-NO.-OF-RECORDS
\r
2842 IIGETP: JRST IGETP ;FUDGE FOR MIDAS/STINK LOSSAGE
\r
2843 IIPUTP: JRST IPUTP
\r
2845 \f;SUPER USEFUL ERROR MESSAGES (USED BY WHOLE WORLD)
\r
2847 WNA: PUSH TP,$TATOM
\r
2848 PUSH TP,EQUOTE WRONG-NUMBER-OF-ARGUMENTS
\r
2851 TFA: PUSH TP,$TATOM
\r
2852 PUSH TP,EQUOTE TOO-FEW-ARGUMENTS-SUPPLIED
\r
2855 TMA: PUSH TP,$TATOM
\r
2856 PUSH TP,EQUOTE TOO-MANY-ARGUMENTS-SUPPLIED
\r
2860 WTYP: PUSH TP,$TATOM
\r
2861 PUSH TP,EQUOTE ARG-WRONG-TYPE
\r
2865 WTYP1: PUSH TP,$TATOM
\r
2866 PUSH TP,EQUOTE FIRST-ARG-WRONG-TYPE
\r
2870 WTYP2: PUSH TP,$TATOM
\r
2871 PUSH TP,EQUOTE SECOND-ARG-WRONG-TYPE
\r
2874 BADTPL: PUSH TP,$TATOM
\r
2875 PUSH TP,EQUOTE BAD-TEMPLATE-DATA
\r
2878 BADPUT: PUSH TP,$TATOM
\r
2879 PUSH TP,EQUOTE TEMPLATE-TYPE-VIOLATION
\r
2882 WTYP3: PUSH TP,$TATOM
\r
2883 PUSH TP,EQUOTE THIRD-ARG-WRONG-TYPE
\r
2887 CALER: HRRZ C,FSAV(TB)
\r
2891 SKIPA C,@-1(C) ; SUBRS AND FSUBRS
\r
2892 MOVE C,3(C) ; FOR RSUBRS
\r
2899 GETWNA: HLRZ B,(E)-2 ;GET LOSING COMPARE INSTRUCTION
\r
2900 CAIE B,(CAIE A,) ;AS EXPECTED ?
\r
2902 HRRE B,(E)-2 ;GET DESIRED NUMBER OF ARGS
\r
2903 HLRE A,AB ;GET ACTUAL NUMBER OF ARGS
\r