Trailing-Edge
-
PDP-10 Archives
-
decus_20tap2_198111
-
decus/20-0057/sddutl.mac
There are 2 other files named sddutl.mac in the archive. Click here to see a list.
TITLE S$$UTL SYSTEM UTILITY ROUTINES
SUBTTL S$$EFI 'ENTRY.FUNCTION' INITIALIZATION ROUTINE
ENTRY S$$EFI
EXTERN S$$MFB,S$$KWD,S$$PBP,S$$FLP,S$$IPR,S$$CPF,S$$FLR
RADIX 10
SEARCH S$$NDF
COMMENT/
XWD STNO,PARBLK ; WHERE STNO IS THE STATEMENT # OF THE
CALL: JSP R11,S$$EFI ; 'ENTRY.FUNCTION' DECLARATION, PARBLK
PROT DESCR ; IS THE PARAMETER BLOCK, AND PROT DESCR AND
LABL DESCR ; LABL DESCR THE PROTOTYPE AND LABEL DESCRIP-
TORS. THE PROGRAM IS INITIALIZED IF NECESSARY, THE FUNCTION DEFINED AND
CALLING SEQUENCE MODIFIED TO APPEAR LIKE A NORMAL FUNCTION DEFINITION,
AND THE FUNCTION IS CALLED USING THE NEW DEFINITION/
S$$EFI: PUSH ES,1(R11) ; SAVE LABEL DESCR ON ES
PUSH ES,(R11) ; SAVE PROTOTYPE DESCR ON ES
PUSH SS,R3 ; SAVE # OF ARGS
PUSH SS,S$$PBP ; SAVE PARBLK+1
PUSH SS,S$$KWD+2 ; SAVE &STNO
PUSH SS,S$$FLP ; SAVE FAILPOINT
PUSH SS,R11 ; SAVE LINK
MOVE R10,-2(R11) ; GET NEW &STNO,PARBLK
HLRZM R10,S$$KWD+2 ; SET &STNO
MOVEI R9,1(R10) ; GET PARBLK+1
MOVEM R9,S$$PBP ; SET
HRLI R9,1B18+4 ; FORM NEW WORD FOR CALLING SEQUENCE
MOVEM R9,-2(R11) ; AND STORE IT THERE
SKIPL (R10) ; HAS PROGRAM BEEN INITIALIZED?
JSP R11,S$$IPR ; NO, INITIALIZE IT
HRROI R10,EFIFAL ; SET UP DUMMY FAILPOINT
MOVEM R10,S$$FLP
SETZ R0, ; MAKE FUNCTION BLOCK, LOCAL VARS POSSIBLE,
JSP R11,S$$MFB ; BUT NO FUNCTION WORD
POP SS,R11 ; RESTORE LINK
MOVEM R10,1(R11) ; SAVE FUNCTION DEFINITION
MOVEM R9,(R11) ; PARAMETERS IN CALLING SEQUENCE
MOVEI R10,S$$CPF ; GET 'CALL PROGRAMMER-DEFINED FUN'
POP SS,S$$FLP ; RESTORE FAILPOINT
POP SS,S$$KWD+2 ; AND &STNO
POP SS,S$$PBP ; AND PARBLK+1
POP SS,R3 ; AND # OF ARGS
HRRM R10,-1(R11) ; CHANGE CALLING SEQUENCE
JRST (R10) ; AND GO THERE
; FAILURE DURING FUNCTION DEFINITION
EFIFAL: SUB SS,[XWD 1,1] ; POP SS
POP SS,S$$FLP ; RESTORE FAILPOINT
POP SS,S$$KWD+2 ; RESTORE &STNO
POP SS,S$$PBP ; RESTORE PARBLK+1
JRST S$$FLR ; AND FAIL
PRGEND
SUBTTL S$$MFB MAKE FUNCTION BLOCK ROUTINE
ENTRY S$$MFB
EXTERN S$$GFP,S$$PGL,S$$LKV,S$$LKL,S$$LKF,S$$GNS,S$$SRT,S$$NRT
EXTERN S$$FRT,S$$MKS
RADIX 10
SEARCH S$$NDF
COMMENT/
CALL: JSP R11,S$$MFB ; WITH LABEL, THEN FUNCTION PROTOTYPE
PUSHED ONTO ES, AND FLAG IN R0 INDICATING FUNCTION TYPE (-1='ENTRY.FOR-
TRAN.FUNCTION',0='ENTRY.FUNCTION',1='DEFINE' FUNCTION). RETURNS XWD
-(NARG+NLV+1),ARGBLK IN R10, XWD STARTL,NLV+1 IN R9, AND, IF REQUIRED,
A FUNCTION WORD POINTER IN R8/
S$$MFB: MOVEM R0,FTPFLG ; SAVE FLAG
JUMPLE R0,.+2 ; IS IT 'DEFINE'?
SETZ R0, ; YES, WANT LOCAL VARS ALSO
HRRM R11,MFBRET ; SAVE LINK
MOVE R1,(ES) ; GET PROTOTYPE
TLNN R1,^O770000 ; IS IT STRING?
JSP R11,S$$GFP ; YES, GET FUNCTION PARAMETERS
CFERR 6,S$$PGL ; NO, BAD PROTOTYPE
MOVEM R9,SAVNLV ; SAVE # OF LOCAL VARS
MOVEI R0,1(R10) ; GET NARG+NLV+2
JSP R6,S$$GNS ; GET ARGUMENT BLOCK
MOVNI R2,(R10) ; GET -(NARG+NLV+1)
HRLI R1,(R2) ; INTO LH OF R1
MOVEM R1,SAVABP ; SAVE XWD -(NARG+NLV+1),ARGBLK
HRLZI R11,-1(R10) ; NARG+NLV,0
ADDI R10,(R1) ; ARGBLK+NARG+NLV+1
HRRM R10,(R1) ; SAVE IN ARGBLK
HRRI R11,(R10) ; AND AS POINTER TO LAST ARG BLOCK ENTRY
VARLOP: POP ES,R1 ; GET NEXT PREVIOUS SYMBOL
JSP R10,S$$LKV ; DO VARIABLE LOOKUP
HRLZI R3,3B23 ; DEDICATED TYPE MASK
AND R3,(R2) ; GET DEDICATED TYPE
LSH R3,-12 ; FORM XWD NAMPTR,DEDTYP
LSHC R2,-18
MOVEM R3,(R11) ; SAVE IN ARG BLOCK
SUB R11,[XWD 1,1] ; DECREMENT POINTER
JUMPGE R11,VARLOP ; LOOP IF ANY SYMBOLS LEFT
ADD ES,[XWD 1,1] ; PRESERVE FUNCTION SYMBOL
MOVE R1,(ES) ; GET IT
SKIPLE FTPFLG ; IS FUNCTION WORD WANTED?
JSP R10,S$$LKF ; YES, DO FUNCTION LOOKUP
HRRM R2,RSTFPT ; SAVE PTR TO FUNCTION WORD
MOVE R1,-2(ES) ; GET LABEL DESCR
SETO R0, ; MUST BE STRING
JSP R7,S$$MKS
CFERR 6,S$$PGL
SETZ R0, ; GET CHAR COUNT OF LABEL
HRRZ R0,(R1)
JUMPN R0,.+2 ; SKIP IF NON-NULL, OR
MOVE R1,(ES) ; USE FUNCTION SYMBOL
JSP R10,S$$LKL ; DO LABEL LOOKUP
MOVE R10,SAVABP ; GET XWD -(NARG+NLV+1),ARGBLK
AOS R9,SAVNLV ; GET XWD STARTL,NLV+1
HRLI R9,(R2)
SUB ES,[XWD 3,3] ; POP FUNC SYM, PROTOTYPE, LABEL OFF ES
RSTFPT: MOVEI R8,.-. ; GET FUNCTION WORD POINTER
MFBRET: JRST .-. ; RETURN
; STORAGE
FTPFLG: S$$SRT ; TO FORCE LOADING OF NON-DUMMY 'RETURN', 'FRETURN',
SAVNLV: S$$FRT ; AND 'NRETURN' IN CASE ONLY INDIRECT REFERENCES TO
SAVABP: S$$NRT ; THEM ARE MADE
PRGEND
SUBTTL S$$CPF CALL PROGRAMMER-DEFINED FUNCTION ROUTINE
ENTRY S$$CPF
EXTERN S$$PGL,S$$STP,S$$STB,S$$TMS,S$$KWD,S$$PBP,S$$FLP,S$$CPS
EXTERN S$$MKS,S$$MKI,S$$MKR,S$$TAC,S$$FLR
RADIX 10
SEARCH S$$NDF
COMMENT/
XWD ,PARBLK+1 ; WHERE PARBLK IS THE PARAMETER BLOCK
CALL: JSP R11,S$$CPF ; NLV IS THE # OF LOCAL VARIABLES, STARTL
XWD STARTL,NLV+1 ; IS THE LOCATION OF THE STARTING LABEL
XWD -(NARG+NLV+1),ARGBLK ; WORD, NARG IS THE # OF FORMAL
ARGUMENTS, AND ARGBLK IS THE ARGUMENT BLOCK POINTER. EXPECTS RETURN
LINK IN S$$PGL, CALL MODE LINK IN R12, AND # OF ARGS IN R3, WITH ARGS
PUSHED ONTO ES/
S$$CPF: HRL R12,S$$PGL ; GET PROGRAM LINK
PUSH SS,R12 ; SAVE , WITH R12, ON SS
MOVN R12,S$$STB ; SAVE CURRENT ES - BASE
ADD R12,ES ; IN CASE STACK OVERFLOWS AND CHANGES BASE
MOVE R10,(R11) ; GET STARTL,NLV+1
HLRM R10,STLABL ; SAVE PTR IN XCT INSTR
MOVEI R10,(R10) ; GET NLV+1
SETZ R0, ; NULL VALUES
PUSH ES,R0 ; PUSH EXTRA VALUES ONTO ES
SOJG R10,.-1 ; LOOP
ADD R12,S$$STB ; ADD BASE AND POINT TO FIRST
MOVEI R12,1(R12) ; VALUE ON ES BY SUTRACTING
SUBI R12,(R3) ; # OF ARGUMENTS
MOVE R8,-2(R11) ; SAVE NEW PARBLK+1
MOVE R11,1(R11) ; GET -(NARG+NLV+1),ARGBLK
PUSH SS,S$$FLP ; SAVE FAILPOINT
PUSH SS,S$$TMS ; SAVE STATEMENT START TIME ON SS
MOVE R1,S$$PBP ; GET OLD PARBLK+1
HRL R1,S$$KWD+2 ; GET OLD &STNO
PUSH SS,R1 ; SAVE THEM ON SS
PUSH SS,S$$STP-1 ; SAVE SS PREVIOUS
PUSH SS,S$$STP ; SAVE ES PREVIOUS
MOVEI R1,CPFRET ; GET FUNCTION CALL RETURN LOC
HRLI R1,(R11) ; AND ARG BLOCK POINTER
PUSH SS,R1 ; SAVE ON SS
SETZ R1, ; NULL VALUE FOR FUNCTION VAR
SAVLOP: MOVE R10,1(R11) ; GET NAMLOC,VARTYP OF NEXT VAR
JRA R10,.+1(R10) ; GET NAME DESCR, GO TO:
JRST SAVUND ; UNDEDICATED VAR
JRST SAVSTR ; DEDICATED STRING
JRST SAVINT ; DEDICATED INTEGER
JRST SAVREL ; OR DEDICATED REAL
SAVUND: SETM R2,(R10) ; GET OLD VALUE, WITHOUT INPUT
MOVEM R1,(R10) ; REPLACE WITH NEW VALUE, POSSIBLE OUTPUT
MOVE R1,R2
SAVCOM: EXCH R1,(R12) ; SAVE OLD VALUE ON ES AND GET NEXT VALUE
AOBJP R11,SAVFIN ; JUMP OUT IF NO MORE VARS
AOJA R12,SAVLOP ; OR BUMP ES POINTER AND LOOP
SAVSTR: MOVE R9,R1 ; SAVE NEW VALUE
MOVE R1,(R10) ; GET OLD VALUE
JSP R7,S$$CPS ; MAKE A COPY
EXCH R1,R9 ; EXCHANGE WITH NEW VALUE
MOVE R2,(R10) ; SET UP FOR STORING NEW VALUE
HLRZ R0,(R2) ; IN DEDICATED STRING, COMPUTE MAX CHARS AVAILA-
SUBI R0,1 ; BLE
IMULI R0,5
JSP R7,S$$MKS ; STORE NEW VALUE
CFERR 1,S$$PGL
HRRM R3,@(R10) ; SAVE CHAR COUNT
MOVE R1,R9 ; GET COPY OF OLD VALUE
JRST SAVCOM ; GO SAVE ON ES
SAVINT: JSP R7,S$$MKI ; MAKE INTEGER FROM NEW VALUE
CFERR 1,S$$PGL
EXCH R1,(R10) ; EXCHANGE WITH OLD VALUE
TLO R1,1B18 ; MAKE DESCRIPTOR FROM OLD VALUE
TLZ R1,1B19
JRST SAVCOM ; GO SAVE ON ES
SAVREL: JSP R7,S$$MKR ; DITTO FOR REALS
CFERR 1,S$$PGL
EXCH R1,(R10)
LSH R1,-2
TLO R1,3B19
JRST SAVCOM
SAVFIN: MOVN R1,S$$STB ; COMPUTE NEW ES PREVIOUS
ADD R1,ES ; FROM CURRENT ES
MOVEM R1,S$$STP ; SAVE
MOVN R1,S$$STB-1 ; DITTO FOR SS
ADD R1,SS
MOVEM R1,S$$STP-1
AOS S$$KWD+3 ; INCREMENT &FNCLEVEL
HRRZM R8,S$$PBP ; SAVE NEW PARBLK+1
SETZM S$$KWD+2 ; ZERO &STNO
STLABL: XCT .-. ; EXECUTE LABEL WORD (JUMP TO STARTING LABEL)
; RETURN, FRETURN, AND NRETURN OF A PROGRAMMER-DEFINED FUNCTION
; EXPECTS 0, -1, OR 1 IN RH(R12) , RESPECTIVELY
CPFRET: HLRZ R11,1(SS) ; GET ARGBLK POINTER
POP SS,S$$STP ; RESTORE ES PREVIOUS
POP SS,S$$STP-1 ; RESTORE SS PREVIOUS
POP SS,R1
HLRZM R1,S$$KWD+2 ; RESTORE OLD &STNO
HRRZM R1,S$$PBP ; RESTORE OLD PARBLK+1
POP SS,S$$TMS ; RESTORE START TIME FOR OLD STNO
POP SS,S$$FLP ; RESTORE FAILPOINT POINTER
POP SS,R1 ; GET OLD LINK,R12
MOVEI R12,(R12) ; CLEAR LH OF RETURN INDEX
ADDI R12,(R1) ; ADD OLD R12
HLRZM R1,S$$PGL ; RESTORE OLD PROGRAM LINK
MOVE R10,1(R11) ; GET NAMPTR,TYPE FOR FUNCTION VARIABLE
JRA R10,.+1(R10) ; GET NAME DESCR, AND SAVE VALUE FOR:
JRST FVLUND ; UNDEDICATED VARIABLE
JRST FVLSTR ; DEDICATED STRING
JRST FVLINT ; DEDICATED INTEGER
JRST FVLREL ; OR DEDICATED REAL
FVLSTR: MOVE R1,(R10) ; GET DESCRIPTOR
JSP R7,S$$CPS ; MAKE A COPY
JRST FVLCOM ; GO SAVE
FVLINT: MOVE R1,(R10) ; GET INTEGER
TLO R1,1B18 ; MAKE DESCRIPTOR
TLZ R1,1B19
JRST FVLCOM ; GO SAVE
FVLREL: MOVE R1,(R10) ; DITTO FOR REAL
LSH R1,-2
TLO R1,3B19
JRST FVLCOM
FVLUND: SETM R1,(R10) ; GET DESCR (WITHOUT INPUT)
FVLCOM: MOVEM R1,S$$TAC ; SAVE IN TEMP AC
HRRZ R9,(R11) ; COMPUTE NARG+NLV+1
SUBI R9,(R11)
MOVE R11,(R11) ; POINTER TO BOTTOM OF ARGBLOCK
RSTLOP: MOVE R10,(R11) ; GET NEXT NAMPTR,TYPE
POP ES,R1 ; POP CORRESPONDING SAVED VALUE OFF ES
JRA R10,.+1(R10) ; GET NAME DESCR AND RESTORE:
JRST RSTUND ; UNDEDICATED VARIABLE
JRST RSTSTR ; DEDICATED STRING
JRST RSTINT ; DEDICATED INTEGER
JRST RSTREL ; OR DEDICATED REAL
RSTSTR: MOVE R2,(R10) ; MOVE OLD STRING COPY INTO DEDICATED
HRRZ R0,(R1) ; STRING LOC
JSP R7,S$$MKS
JFCL
HRRM R3,@(R10) ; SAVE CHAR COUNT
JRST RSTCOM ; GO LOOP
RSTINT: LSH R1,2 ; GET INTEGER FROM DESCR
ASH R1,-2
MOVEM R1,(R10) ; SAVE IN DED LOC
JRST RSTCOM ; GO LOOP
RSTREL: LSH R1,2 ; DITTO FOR REAL
MOVEM R1,(R10)
JRST RSTCOM
RSTUND: SETAM R1,(R10) ; SAVE DESCR IN LOC (BUT NO OUTPUT)
RSTCOM: SOJLE R9,RSTFIN ; JUMP OUT IF NO MORE VARS
SOJA R11,RSTLOP ; OR DECREMENT ARGBLK POINTER AND LOOP
RSTFIN: SETZ R1,
EXCH R1,S$$TAC ; GET FUNCTION VALUE
TLNN R12,-1 ; SKIP IF INDEX WAS -1 (FRETURN)
JRST (R12) ; 'RETURN' OR 'NRETURN'
JRST S$$FLR ; 'FRETURN', FAIL
PRGEND
SUBTTL S$$GFP GET FUNCTION PARAMETERS ROUTINE
ENTRY S$$GFP
EXTERN S$$BKT,S$$GRS
RADIX 10
SEARCH S$$NDF
COMMENT/
CALL: JSP R11,S$$GFP ; WITH PROTOTYPE ON ES, AND LOCAL VAR-
RIABLE FLAG (-1=NONE, 0=POSSIBLY) IN R0. RETURNS TO 0(R11) IF PROTOTYPE
IS BAD, OR TO 1(R11) WITH SYMBOLS PUSHED ONTO ES, SYMBOL COUNT IN R10,
AND, IF REQUIRED, LOCAL VARIABLE COUNT IN R9/
S$$GFP: JRST INIBKT ; INITIALIZE BREAK TABLES, THEN MODIFY THIS LOC
SETZM PROTCT ; INITIALIZE SYMBOL COUNT
MOVE R10,(ES) ; INITIALIZE CURSOR
SETZ R0, ; GET TOTAL CHAR COUNT
HRRZ R9,(R10)
JSP R8,GETSYM ; GET FIRST SYMBOL
JRST (R11) ; ERROR IF NO MORE CHARS
CAIE R7,"(" ; IS NEXT CHAR OPEN PAREN?
JRST (R11) ; NO, ERROR
JSP R8,SPNBLN ; SPAN BLANKS
JRST (R11) ; ERROR IF NO MORE CHARS
CAIN R7,")" ; IS NEXT CHAR CLOSE PAREN?
JRST CLSPRN ; YES
VARLOP: JSP R8,GETSYM ; GET NEXT SYMBOL
JRST (R11) ; ERROR IF NO MORE CHARS
MOVE R8,PROTCT ; GET # OF SYMBOLS
CAILE R8,16 ; < OR = 15 ARGS + FUNCTION?
JRST (R11) ; NO, BAD PROTOTYPE
CAIE R7," " ; IS NEXT CHAR BLANK OR TAB?
CAIN R7,^O11
JSP R8,SPNBLN ; YES, SPAN BLANKS
JUMPL R9,(R11) ; NO, OR IF OUT OF CHARS, ERROR
CAIE R7,"," ; IS NEXT CHAR A COMMA?
JRST CLSCHK ; NO, CHECK FOR CLOSE PAREN
JSP R8,SPNBLN ; YES, SPAN BLANKS
JRST (R11) ; ERROR IF NO MORE CHARS
JRST VARLOP ; LOOP
CLSCHK: CAIE R7,")" ; IS NEXT CHAR CLOSE PAREN?
JRST (R11) ; NO, ERROR
CLSPRN: JSP R8,SPNBLN ; SPAN BLANKS AFTER ")"
JRST GFPEND ; FINISH UP IF NO MORE CHARS
SKIPE PROTFL ; WERE LOCAL VARS EXPECTED?
JRST (R11) ; NO, ERROR
LVRLOP: AOS PROTFL ; ADD 1 TO LOCAL VAR COUNT
JSP R8,GETSYM ; GET NEXT SYMBOL
JRST GFPEND ; FINISH UP IF NO MORE CHARS
CAIE R7," " ; IS NEXT CHAR BLANK OR TAB?
CAIN R7,^O11
JSP R8,SPNBLN ; YES, SPAN BLANKS
JUMPL R9,GFPEND ; NO, OR IF OUT OF CHARS, FINISH UP
CAIE R7,"," ; IS NEXT CHAR A COMMA?
JRST (R11) ; NO, ERROR
JSP R8,SPNBLN ; YES, SPAN BLANKS
JRST (R11) ; ERROR IF NO MORE CHARS
JRST LVRLOP ; LOOP
GFPEND: MOVE R9,PROTFL ; GET LOCAL VAR COUNT
MOVE R10,PROTCT ; GET SYMBOL COUNT
JRST 1(R11) ; RETURN
; INITIALIZE BREAK TABLES
INIBKT: MOVE R1,.+2 ; GET 'MOVEM R0,PROTFL'
PROTFL: MOVEM R1,S$$GFP ; PLUG CALLING SEQUENCE
PROTCT: MOVEM R0,PROTFL ; SAVE R0
FRSTBL: MOVEI R0,1 ; BIT MARK
MOVEI R1,R3 ; PTR TO DUMMY FRSTBL IN R3-R6
MOVE R2,[XWD -26,"A"] ; UPPER CASE LETTERS
SETZB R3,R4 ; CLEAR TABLE
RESTBL: SETZB R5,R6
DPB R0,S$$BKT(R2) ; MARK UPPER CASE BITS
AOBJN R2,.-1
MOVE R2,[XWD -26,^O141] ; LOWER CASE LETTERS
DPB R0,S$$BKT(R2) ; MARK LOWER CASE BITS
AOBJN R2,.-1
MOVEI R1,R7 ; COPY INTO DUMMY RESTBL
MOVE R10,[XWD R3,R7] ; IN R7-R10
BLT R10,R10
MOVE R2,[XWD -10,"0"] ; DIGITS
DPB R0,S$$BKT(R2) ; MARK DIGIT BITS
AOBJN R2,.-1
DPB R0,S$$BKT+"." ; MARK DOT
DPB R0,S$$BKT+"-" ; MARK DASH
MOVE R0,[XWD R3,FRSTBL] ; MOVE TABLES INTO CORE
BLT R0,RESTBL+3
JRST S$$GFP+1 ; CONTINUE
; SPAN BLANKS ROUTINE: JSP R8,SPNBLN ; AUTOMATICALLY SKIPS THE FIRST
; CHARACTER, AND THEN SKIPS OVER SUCCEEDING BLANKS AND TABS. RETURNS
; TO 0(R8) IF IT RUNS OUT OF CHARACTERS, OR TO 1(R8) WITH THE NEXT CHAR
; IN R7, AND THE CURSOR BACKED UP TO JUST IN FRONT OF IT
SPNBLN: IBP R10 ; MOVE CURSOR 1 CHAR
SUBI R9,1 ; FORWARD AUTOMATICALLY
SPNLOP: MOVE R6,R10 ; SAVE CURSOR IN CASE OF BACKUP
SOJL R9,(R8) ; DECREMENT CHAR COUNT, LEAVE IF <0
ILDB R7,R10 ; GET NEXT CHAR
CAIE R7," " ; IS IT BALNK OR TAB?
CAIN R7,^O11
JRST SPNLOP ; YES, LOOP
MOVE R10,R6 ; NO, BACKUP CURSOR
AOJA R9,1(R8) ; AND RETURN
; GET SYMBOL ROUTINE: JSP R8,GETSYM ; PARSES SYMBOL, CREATES NEW STRING
; , PUSHES IT ONTO ES AND INCREMENTS PROTCT, AND RETURNS TO 0(R8) IF
; NO MORE CHARS, OR TO 1(R8) WITH NEXT CHAR IN R7, WITH CURSOR BACKED
; UP TO JUST IN FRONT OF IT. FAILS TO (R11) IF CAN'T FIND SYMBOL
GETSYM: MOVEI R0,1 ; AT LEAST 1 CHAR
MOVEI R1,FRSTBL ; GET BREAK TABLE FOR LETTERS
SOJL R9,(R11) ; FAIL IF NO MORE CHARS
ILDB R7,R10 ; GET CHAR
LDB R2,S$$BKT(R7) ; GET BREAK BIT
JUMPE R2,(R11) ; FAIL IF NOT LETTER
PUSH SS,R7 ; PUSH CHAR ONTO SS
MOVEI R1,RESTBL ; GET BREAK TABLE FOR LETTERS, DIGITS,.,-
SYMLOP: MOVE R6,R10 ; SAVE CURSOR IN CASE OF BACKUP
SOJL R9,SYMEND+2 ; DECREMENT CHAR COUNT, QUIT IF <0
ILDB R7,R10 ; GET CHAR
LDB R2,S$$BKT(R7) ; GET BREAK BIT
JUMPE R2,SYMEND ; QUIT IF NOT ON
PUSH SS,R7 ; PUSH CHAR ONTO SS
AOJA R0,SYMLOP ; INCREMENT SYMBOL CHAR COUNT AND LOOP
SYMEND: ADDI R8,1 ; RETURN TO 1(R8)
MOVE R10,R6 ; BACKUP CURSOR
ADDI R9,1
HRRM R0,SAVCNT ; SAVE SYMBOL CHAR COUNT
MUL R0,[^F0.2B0] ; COMPUTE # WORDS NEEDED
ADDI R0,2
JSP R6,S$$GRS ; GET BLOCK FOR SYMBOL
HRLI R1,^O700 ; FORM STRING DESCR
PUSH ES,R1 ; SAVE ON ES
AOS PROTCT ; INCREMENT SYMBOL COUNT
SAVCNT: MOVEI R2,.-. ; GET SYMBOL CHAR COUNT
HRRM R2,(R1) ; SAVE IN STRING BLOCK
HRLI R2,(R2) ; FORM XWD NCHAR,NCHAR
SUB SS,R2 ; RESTORE SS TO INITIAL VALUE
MOVN R2,R2 ; FORM XWD -NCHAR,FIRST CHAR PTR
HRRI R2,(SS)
AOBJN R2,.+1
SYMCHR: MOVE R0,(R2) ; GET NEXT CHAR OFF SS
IDPB R0,R1 ; PUT IN STRING
AOBJN R2,SYMCHR ; LOOP FOR EACH CHAR
JRST (R8) ; RETURN
PRGEND
SUBTTL S$$NGS,S$$NGF STRING NEGATION ROUTINES
ENTRY S$$NGS,S$$NGF
EXTERN S$$STB,S$$STP,S$$FLR,S$$FLP
RADIX 10
SEARCH S$$NDF
COMMENT/
CALL: JSP R12,S$$NGS ; START NEGATION, FAILPT IS LOC TO GO TO
FAILPT ; IF NEGATION ARG FAILS (AND NEGATION THUS SUCCEEDS)
CALL: JRST S$$NGF ; NEGATION FAILS (BECAUSE ARG SUCCEEDED)/
S$$NGS: PUSH SS,S$$FLP ; SAVE OLD FAILPOINT
PUSH SS,S$$STP-1 ; SAVE SS PREVIOUS
MOVN R1,S$$STB ; COMPUTE NEW ES PREVIOUS
ADD R1,ES
EXCH R1,S$$STP ; EXCHANGE WITH OLD ES PREVIOUS
PUSH SS,R1 ; SAVE OLD ES PREVIOUS
PUSH SS,(R12) ; SAVE FAILPOINT
MOVN R1,S$$STB-1 ; COMPUTE NEW SS PREVIOUS
ADD R1,SS
MOVEM R1,S$$STP-1 ; AND SAVE
HRROI R1,NEGFAL ; COMPUTE NEW FAILPOINT
MOVEM R1,S$$FLP ; SAVE
JRST 1(R12) ; CONTINUE WITH ARGUMENT
NEGFAL: MOVE SS,S$$STB-1 ; RESTORE SS
ADD SS,S$$STP-1
POP SS,R12 ; GET FAILPOINT
POP SS,ES ; GET OLD ES PREVIOUS
EXCH ES,S$$STP ; EXCHANGE WITH CURRENT ES PREVIOUS
ADD ES,S$$STB ; UPDATE ES
POP SS,S$$STP-1 ; RESTORE OLD SS PREVIOUS
POP SS,S$$FLP ; GET OLD FAILPOINT
SETZ R1, ; RESULT IS NULL
JRST (R12) ; SUCCEED TO FAILPOINT
S$$NGF: SUB SS,[XWD 1,1] ; THROW AWAY FAILPOINT
POP SS,S$$STP ; RESTORE ES PREVIOUS
POP SS,S$$STP-1 ; RESTORE SS PREVIOUS
POP SS,S$$FLP ; RESTORE OLD FAILPOINT
JRST S$$FLR ; FAIL
PRGEND
SUBTTL S$$ADD,S$$SUB,S$$MUL,S$$DIV DESCRIPTOR ARITHMETIC ROUTINES
ENTRY S$$ADD,S$$SUB,S$$MUL,S$$DIV
EXTERN S$$PGL,S$$STN,S$$ITR
RADIX 10
SEARCH S$$NDF
COMMENT/
CALL: JSP R12,S$$XXX ; WITH SECOND (RIGHT) ARG IN R1 AND
FIRST (LEFT) ARG ON ES, RETURNS RESULT IN R1 WITH ES POPED/
S$$ADD: JSP R11,ARITH ; ADD, INDEX=0
S$$SUB: JSP R11,ARITH ; SUBTRACT, INDEX=1
S$$MUL: JSP R11,ARITH ; MULTIPLY, INDEX=2
S$$DIV: JSP R11,ARITH ; DIVIDE, INDEX=3
ARITH: SUBI R11,S$$ADD+1
MOVEM R12,S$$PGL ; SAVE LINK
SETZ R2, ; GET DESCR TYPE
ROTC R1,2
JRST .+1(R2) ; CONVERT TO VALUE
JSP R7,S$$STN-1 ; STRING, CONVERT TO INTEGER OR REAL
CFERR 1,S$$PGL ; OTHER, OR FAILED STRING CONVERSION
ASH R1,-2 ; INTEGER, RESTORE VALUE
MOVEI R10,(R2) ; REAL, OR SUCEEDED STRING CONV, SAVE TYPE
MOVE R9,R1 ; SAVE VALUE
POP ES,R1 ; GET LEFT HAND SIDE
SETZ R2, ; SIMILAR CONVERSION
ROTC R1,2
JRST .+1(R2)
JSP R7,S$$STN-1
CFERR 1,S$$PGL
ASH R1,-2
CAIE R2,(R10) ; TYPES THE SAME?
JRST MIXMOD ; NO, MIXED MODE
XCT OPERAT(R11) ; YES, PERFORM OPERATION
MAKDSC: JRST .-1(R2) ; FORM DESCRIPTOR
LSH R1,2 ; FOR INTEGER
ROTC R1,-2 ; AND REAL
JRST (R12) ; RETURN
; OPERATION TABLE
OPERAT: XCT ADDOP-2(R2)
XCT SUBOP-2(R2)
XCT MULOP-2(R2)
XCT DIVOP-2(R2)
; MODE TABLES
ADDOP: ADD R1,R9
FAD R1,R9
SUBOP: SUB R1,R9
FSB R1,R9
MULOP: IMUL R1,R9
FMP R1,R9
DIVOP: JSP R4,[MOVEI R3,(R2)
IDIV R1,R9
MOVEI R2,(R3)
JRST (R4)]
FDV R1,R9
MIXMOD: CAIE R10,3 ; IS RIGHT HAND SIDE REAL?
EXCH R1,R9 ; NO, IS INTEGER, EXCHANGE WITH LHS
JSP R3,S$$ITR ; CONVERT ARG THAT IS INTEGER TO REAL
CAIE R10,3 ; WERE SIDES EXCHANGED?
EXCH R1,R9 ; YES, RE-EXCHANGE
MOVEI R2,3 ; NOW BITH SIDES ARE REAL
XCT OPERAT(R11) ; PERFORM OPERATION
ROTC R1,-2 ; FORM REAL DESCR
JRST (R12) ; RETURN
PRGEND
SUBTTL S$$EXP DESCRIPTOR MODE EXPONENTIATION ROUTINE
ENTRY S$$EXP
EXTERN S$$PGL,S$$STN,S$$ITR,EXP1.0,EXP2.0,EXP3.0
RADIX 10
SEARCH S$$NDF
COMMENT/
CALL: JSP R12,S$$EXP ; WITH SECOND (RIGHT) ARG IN R1 AND
FIRST (LEFT) ARG ON ES, RETURNS RESULT IN R1 WITH ES POPPED/
S$$EXP: MOVEM R12,S$$PGL ; SAVE LINK
SETZ R2, ; GET DESCR TYPE
ROTC R1,2
JRST .+1(R2) ; CONVERT TO INTEGER OR REAL VALUE
JSP R7,S$$STN-1
CFERR 1,S$$PGL
ASH R1,-2
MOVEI R10,(R2) ; SAVE TYPE AND VALUE OF RHS
MOVE R9,R1
POP ES,R1 ; GET LHS
SETZ R2, ; LIKEWISE CONVERT
ROTC R1,2
JRST .+1(R2)
JSP R7,S$$STN-1
CFERR 1,S$$PGL
ASH R1,-2
CAIL R2,(R10) ; IS IT INTEGER ** REAL?
JRST .+3 ; NO
JSP R3,S$$ITR ; YES, MAKE IT REAL ** REAL
MOVEI R2,3
MOVE R0,R1 ; GET ARGS INTO POSITION FOR FORTRAN LIBRARY
MOVE R1,R9 ; CALL
PUSHJ SS,@EXPTBL-2(R2) ; EXECUTE PROPER EXPONENTIATION
IORI R2,(R10) ; FORM DOMINANT TYPE
MOVE R1,R0 ; GET VAL INTO POSITION
JRST .-1(R2) ; AND MAKE DESCR
LSH R1,2 ; INTEGER
ROTC R1,-2 ; REAL
JRST (R12) ; RETURN
EXPTBL: JRST EXP1.0 ; I ** I
JRST @EXPTB1-2(R10) ; R ** ?
EXPTB1: JRST EXP2.0 ; R ** I
JRST EXP3.0 ; R ** R
PRGEND
SUBTTL S$$NEG DESCRIPTOR UNARY - ROUTINE
ENTRY S$$NEG
EXTERN S$$PGL,S$$STN
RADIX 10
SEARCH S$$NDF
COMMENT/
CALL: JSP R12,S$$NEG ; WITH DESCRIPTOR IN R1/
S$$NEG: MOVEM R12,S$$PGL ; SAVE LINK
SETZ R2, ; GET TYPE
ROTC R1,2
JRST .+1(R2) ; CONVERT TO INTEGER OR REAL VALUE
JSP R7,S$$STN-1 ; STRING
CFERR 1,S$$PGL ; OTHER, OR STRING CONV FAILED
ASH R1,-2 ; INTEGER
MOVN R1,R1 ; REAL, AND NEGATE
JRST .-1(R2) ; MAKE DESCR AGAIN
LSH R1,2 ; INTEGER
ROTC R1,-2 ; REAL
JRST (R12) ; RETURN
PRGEND
SUBTTL S$$CNC CONCATENATION ROUTINE
ENTRY S$$CNC
EXTERN S$$PGL,S$$GRS,S$$MKS,S$$TAC,S$$MST,S$$PTS,S$$PTX
RADIX 10
SEARCH S$$NDF
COMMENT/
CALL: JSP R12,S$$CNC ; WHERE NCONC IS THE NUMBER OF ELEMENTS
NCONC ; IN THE CONCATENATION, ALL BUT THE LAST PUSHED ONTO ES
AND THE LAST IN R1. IF ALL BUT ONE ELEMENT IS NULL-VALUED, THE RESULT
IS THAT ELEMENT. IF ALL NON-NULL ELEMENTS ARE EITHER STRINGS, INTEGERS,
OR REALS, THE RESULT IS THEIR CONCATENATED STRING. IF ALL NON-NULL
ELEMENTS ARE EITHER STRINGS, INTEGERS, REALS, OR PATTERNS, THE RESULT IS
THEIR CONCATENATED PATTERN. IF ANY ELEMENT IS NONE OF THESE, AND ANOTHER
NON-NULL ELEMENT EXISTS, IT IS A TYPE ERROR. THE RESULT DESCRIPTOR IS RE-
TURNED IN R1, WITH ES RESTORED TO ITS INITIAL STATE (NCONC-1 ELEMENTS
POPPED OFF)/
S$$CNC: MOVEM R12,S$$PGL ; SAVE PROG LINK
PUSH ES,R1 ; SAVE LAST ELT
MOVN R11,(R12) ; FORM -(NCONC,NCONC)
HRLI R11,-1(R11)
MOVE R10,ES ; FORM RESET ES
ADD R10,R11
MOVEM R10,SAVNES ; AND SAVE
HRRI R11,(R10) ; FORM XWD -NCONC,PTR TO FIRST ELEMENT
AOBJN R11,.+1
MOVEM R11,SAVELP ; AND SAVE
SETZ R10, ; INITIALIZE ELEMENT COUNT=0
SETZB R9,R8 ; INITIALIZE CHAR COUNT, SAVED ELT =0
; SEARCH LOOP, CHECK EACH ELEMENT ON ES
SRCHLP: MOVE R1,(R11) ; GET NEXT ELEMENT
JUMPE R1,GTNXTS ; SKIP OUT IF NULL
JUMPL R1,SRCNUM ; JUMP IF INTEGER OR REAL
TLNE R1,^O770000 ; IS IT STRING?
JRST SRCPAT ; NO, TRY PATTERN
HRRZ R3,(R1) ; GET CHAR COUNT
JUMPN R3,SRCSTR ; JUMP IF NONZERO
SETZM (R11) ; OR MAKE ELEMENT NULL
JRST GTNXTS ; AND SKIP OUT
CNVNUM: SETO R0, ; MAKE STRING FROM INTEGER OR REAL
JSP R7,S$$MKS ; WILL ALLWAYS SKIP OVER NEXT INSTR
SRCSTR: SKIPN R8,R1 ; SAVE DESCR IN R8 AND SKIP
MOVEM R1,(R11) ; SAVE NEW STRING AS ELT
ADDI R9,(R3) ; ADD CHARS TO TOTAL
AOJA R10,GTNXTS ; INCREMENT ELT COUNT AND LOOP
SRCNUM: JUMPN R10,CNVNUM ; IF ELT COUNT > 0, GO CONVERT TO STRING
HRRM R11,SAVNPT ; OR SAVE PTR TO ELT
NUMLOP: AOBJP R11,RETSAV+1 ; POINT TO NEXT ELT OR FINISH
MOVE R8,(R11) ; GET NEXT ELT
JUMPE R8,NUMLOP ; LOOP IF NULL
TLNE R8,^O770000 ; IS IT STRING?
JRST NUMCNV ; NO
HRRZ R3,(R8) ; YES, GET CHAR COUNT
JUMPN R3,NUMCNV ; DON'T JUMP IF 0
SETZM (R11) ; SET ELT TO NULL
JRST NUMLOP ; AND KEEP LOOPING
NUMCNV: SETO R0, ; CONVERT SAVED NUMBER TO STRING
JSP R7,S$$MKS
SAVNES: BLOCK 1 ; NEVER EXECUTED, USE FOR STORAGE
SAVNPT: MOVEM R1,.-. ; SAVE NEW STRING DESCR IN ELT LOC
MOVEI R9,(R3) ; INITIALIZE CHAR COUNT
MOVE R1,R8 ; GET CURRENT DESCR
AOJA R10,SRCHLP+2 ; INCREMENT ELT COUNT AND PROCEED
SRCPAT: TLC R1,1B20 ; IS IT PATTERN?
TLNN R1,3B21
AOBJP R10,SAVELT ; YES, INCREMENT ELT COUNT, MARK AS PAT
JUMPN R10,SPCERR ; NO, ERROR IF ANOTHER NON-NULL ELEMENT
TLC R1,1B20 ; RESTORE DESCR
SPCLOP: AOBJP R11,RETSAV+1 ; POINT TO NEXT ELT OR FINISH
MOVE R8,(R11) ; GET NEXT ELT
JUMPE R8,SPCLOP ; LOOP IF NULL
TLNE R8,^O770000 ; IS IT STRING?
SPCERR: CFERR 1,S$$PGL ; NO, ERROR
HRRZ R3,(R8) ; GET # OF CHARS
JUMPE R3,SPCLOP ; LOOP IF 0
CFERR 1,S$$PGL ; OR ERROR
SAVELT: TLC R1,1B20 ; RESTORE DESCR
MOVE R8,R1 ; SAVE LATEST ELEMENT
GTNXTS: AOBJN R11,SRCHLP ; POINT TO NEXT ELEMENT AND LOOP
; ELEMENT SEARCH IS OVER, FORM NEW STRING OR PATTERN
CAIG R10,1 ; IS # ELTS >1 ?
JRST RETSAV ; NO, FINISH
MOVE R11,SAVELP ; YES, GET FIRST ELT POINTER
CAIL R10,^O777777 ; IS PATTERN FLAG ON?
JRST MAKPAT ; YES, GO MAKE PATTERN
MOVEI R0,(R9) ; NO, STRING, COMPUTE # OF WORDS NEEDED
MUL R0,[^F0.2B0]
ADDI R0,2
JSP R6,S$$GRS ; GET BLOCK
HRLI R1,^O700 ; FORM DESCR
MOVE R8,R1 ; SAVE
HRRM R9,(R1) ; AND SAVE # OF CHARS IN STRING BLOCK
MOVE R7,[XWD STRCHR,CHRLOP] ; MOVE CHAR LOOP INTO R4-R7
BLT R7,CHRBOT
STRLOP: MOVE R2,(R11) ; GET NEXT ELT
JUMPE R2, STRBOT ; SKIP OUT IF NULL
HRRZ R3,(R2) ; GET CHAR COUNT
JRST CHRLOP ; START LOOP
STRCHR: PHASE 4
CHRLOP: ILDB R0,R2 ; R4: GET CHAR FROM ELT
IDPB R0,R1 ; R5: PUT CHAR IN NEW STRING
SOJG R3,CHRLOP ; R6: LOOP
CHRBOT: JRST STRBOT ; R7: OR EXIT
DEPHASE
STRBOT: AOBJN R11,STRLOP ; LOOP FOR EACH ELEMENT
RETSAV: MOVE R1,R8 ; RESTORE RESULT DESCR
MOVE ES,SAVNES ; RESTORE POPPED ES
JRST 1(R12) ; RETURN
; AT LEAST ONE ELEMENT IS A PATTERN, CREATE PATTERN ROUTINE AND DATA BLOCK
MAKPAT: MOVEI R0,1(R10) ; GET # ELTS + 1
CAIG R0,2 ; IS # ELTS > 1?
JRST RETSAV ; NO, FINISH
JSP R6,S$$GRS ; GET DATA BLOCK
HRLI R1,3B20 ; MAKE PATTERN DESCR
MOVE R8,R1 ; SAVE
HRLI R1,^O700 ; FAKE STRING DESCR AND SAVE
MOVEM R1,S$$TAC ; IN CASE OF GARBAGE COLLECTION
LSH R0,1 ; GET 2*(#ELTS+1)
JSP R6,S$$GRS ; GET BLOCK FOR PATTERN ROUTINE
ADDI R1,1 ; PTR TO FIRST INST
HRRM R1,(R8) ; SAVE POINTER TO ROUTINE IN DATA BLOCK
MOVE R9,[MOVE R1,1(DT)] ; INSTR. TO FETCH ELT FROM DATBLK
MOVE R7,[JSP R9,S$$MST] ; INSTR. IF STRING
MOVE R6,[JSP R9,S$$PTX] ; ISTR. IF PATTERN
MOVEI R10,1(R8) ; FIRST ELT PTR IN DATA BLOCK
PATLOP: MOVE R2,(R11) ; GET NEXT ELT
JUMPE R2,PATBOT ; SKIP OUT IF NULL
TLNE R2,^O770000 ; IS IT STRING?
JRST PATELT ; NO, PATTERN
MOVEM R7,1(R1) ; YES, SAVE STRING MATCH INSTR
PATRET: MOVEM R2,(R10) ; SAVE ELT IN DATA BLOCK
MOVEM R9,(R1) ; SAVE ELT FETCH INSTR
ADDI R1,2 ; NEXT INSTR LOC IN PATTERN ROUTINE
ADDI R9,1 ; NEXT ELT FETCH INSTR
ADDI R10,1 ; NEXT DATA BLOCK LOC
PATBOT: AOBJN R11,PATLOP ; LOOP FOR EACH ELT
MOVE R6,[JRST S$$PTS] ; LAST INSTR OF PATTERN ROUTINE
MOVEM R6,(R1)
SETZM S$$TAC ; CLEAR DUMMY STRING DESCR
JRST RETSAV ; FINISH
PATELT: TLNE R2,1B22 ; IS SUBPAT RESTARTEABLE?
TLO R8,1B22 ; YES, SET RESTARTEABLE BIT OF WHOLE PAT
MOVEM R6,1(R1) ; SAVE PAT MATCH INST
JRST PATRET ; REJOIN LOOP
; STORAGE
SAVELP: BLOCK 1
PRGEND
SUBTTL S$$IVN,S$$IVV INDIRECT VARIABLE NAME AND VALUE ROUTINES
ENTRY S$$IVN,S$$IVV
EXTERN S$$PGL,S$$LKV,S$$CPS
RADIX 10
SEARCH S$$NDF
COMMENT/
CALL: JSP R12,S$$IVN ; WITH KEY DESCRIPTOR IN R1, RETURNS
NAME DESCRIPTOR IN R1 (SAME AS KEY IF KEY IS NAME)
CALL: JSP R12,S$$IVV ; WITH KEY DESCRIPTOR IN R1, RETURNS
VALUE DESCRIPTOR IN R1 (DOES NO LOOKUP IF KEY IS NAME)/
S$$IVN: JSP R11,S$$IVV+1 ; NAME, INDEX=0
S$$IVV: JSP R11,S$$IVV+1 ; VALUE, INDEX=1
SUBI R11,S$$IVN+1
SETZ R2, ; GET DESCR TYPE
ROTC R1,4
CAIE R2,4 ; IS IT NAME?
JRST INDLKP ; NO, DO LOOKUP
ROTC R1,-4 ; RESTORE DESCR
INDCOM: XCT [JRST (R12)
MOVE R2,R1](R11) ; RETURN FOR NAME CALL
MOVE R1,(R2) ; GET VALUE
TLNE R2,1B22 ; IS IT DEDICATED INTEGER OR REAL?
JRST DEDVAR ; YES
TLNE R2,1B23 ; IS IT DEDICATED STRING?
JSP R7,S$$CPS ; YES, COPY
JRST (R12) ; RETURN VALUE
DEDVAR: TLNN R2,1B23 ; IS IT DEDICATED REAL?
JRST MKIDSC ; NO, MAKE INT DESCR
LSH R1,-2 ; MAKE REAL DESCR
TLO R1,3B19
JRST (R12) ; RETURN
MKIDSC: TLZ R1,1B19 ; MAKE INTEGER DESCR
TLO R1,1B18
JRST (R12) ; RETURN
INDLKP: MOVEM R12,S$$PGL ; SAVE LINK
ROTC R1,-4 ; RESTORE DESCR
JSP R10,S$$LKV ; DO LOOKUP
MOVE R1,(R2) ; GET NAME
JRST INDCOM ; RETURN OR GET VALUE
PRGEND
SUBTTL S$$ILB INDIRECT LABEL FUNCTION
ENTRY S$$ILB
EXTERN S$$PGL,S$$LKL
RADIX 10
SEARCH S$$NDF
COMMENT/
CALL: JSP R12,S$$ILB ; WITH KEY DESCRIPTOR IN R1, EXECUTES
VALUE LOCATION/
S$$ILB: MOVEM R12,S$$PGL ; SAVE PROG LINK
JSP R10,S$$LKL ; DO LOOKUP
XCT (R2) ; PERFORM GOTO
PRGEND
SUBTTL S$$LKV,S$$LKL,S$$LKF VARIABLE, LABEL, AND FUNCTION LOOKUP
ENTRY S$$LKV,S$$LKL,S$$LKF
EXTERN S$$LKS,S$$PGL,S$$GLP,S$$GNS,S$$UDF
RADIX 10
SEARCH S$$NDF
COMMENT/
CALL: JSP R10,S$$LKV[S$$LKL,S$$LKF] ; WITH KEY DESCRIPTOR IN
R1, RETURNS POINTER TO VALUE LOCATION IN R2/
S$$LKV: JSP R9,S$$LKF+1 ; VARIABLE, INDEX = 0
S$$LKL: JSP R9,S$$LKF+1 ; LABEL, INDEX = 1
S$$LKF: JSP R9,S$$LKF+1 ; FUNCTION, INDEX = 2
SUBI R9,S$$LKL
MOVEI R0,(R9) ; GET TYPE
TLO R0,1B18 ; FORM TYPE*2+1
ROT R0,-4 ; IN BITS 0-4
JSP R8,S$$LKS ; DO LOOKUP
JRST (R10) ; FOUND
XCT NEWLKV(R9) ; NEW ENTRY, GET APPROPRIATE VALUE
NEWLKC: MOVEM R5,(R2) ; SAVE
JRST (R10) ; RETURN
NEWLKV: JRST .+3 ; VARIABLE
MOVE R5,[UFERR 8,S$$PGL] ; LABEL
MOVE R5,[XWD 1B19,S$$UDF] ; FUNCTION
HRRZ R5,S$$GLP+1 ; GET GLOBAL VARIABLE BLOCK
HLRZ R6,(R5) ; GET SIZE
ANDI R6,^O177777
CAMG R6,S$$GLP+2 ; ROOM LEFT?
JRST NEWVBL ; NO, MAKE NEW BLOCK
ADD R5,S$$GLP+2 ; YES, POINT TO NEXT AVAILABLE LOC
AOS S$$GLP+2 ; INCREMENT LOC INDEX
NEWVBC: TLO R5,1B19 ; FORM NAME DESCR
JRST NEWLKC ; GO BACK TO SEQUENCE
NEWVBL: HRRM R2,NEWVR2 ; SAVE VALUE POINTER
MOVEI R0,P$GVXT ; GET GLOBAL VARIABLE BLOCK EXTENSION SIZE
JSP R6,S$$GNS ; GET NONRETURNABLE BLOCK
MOVE R2,S$$GLP+1 ; GET VAR BLOCK LIST
HRRM R1,(R2) ; APPEND NEW BLOCK
HRRI R2,(R1)
MOVEM R2,S$$GLP+1
MOVEI R2,2 ; NEW AVAIL INDEX
MOVEM R2,S$$GLP+2
NEWVR2: MOVEI R2,.-. ; RESTORE VALUE POINTER
MOVEI R5,1(R1) ; FORM POINTER TO VARIABLE LOC
HRLI R1,1(R1) ; SET INITIAL VALUES
MOVEI R3,P$GVXT-1(R1) ; OF VARIABLES IN NEW VAR BLOCK
SETZM 1(R1) ; TO NULL
HRRI R1,2(R1)
BLT R1,(R3)
JRST NEWVBC ; FORM NAME AND GO BACK TO SEQUENCE
PRGEND
SUBTTL S$$LKS INDIRECTION SYMBOL LOOKUP ROUTINE
ENTRY S$$LKS
EXTERN S$$MKS,S$$PGL,S$$PBP,S$$SY1,S$$SY2,S$$GLP,S$$TBM,S$$MNS
RADIX 10
SEARCH S$$NDF
COMMENT"
CALL: JSP R8,S$$LKS ; WITH TYPE/0,0 IN R0, KEY DESCRIPTOR
IN R1. RETURNS TO 0(R8) IF FOUND, WITH POINTER TO VALUE LOC
IN R2. RETURNS TO 1(R8) IF NEW ENTRY, WITH POINTER TO VALUE LOC
IN R2, AND STRING VALUE OF KEY MADE NONRETURNABLE"
S$$LKS: TLNN R1,^O770000 ; IS IT A STRING?
JRST .+5 ; YES
MOVN R0,R0 ; NO, TRY TO CREATE ONE
JSP R7,S$$MKS
CFERR 1,S$$PGL ; NO GO
MOVN R0,R0 ; RESTORE TYPE
CAML R0,[7B4] ; IS IT < TYPE 7?
JRST SPCLKS ; NO, SPECIAL
ADD R0,@S$$PBP ; ADD TABLE NUMBER TO LH
HLRI R0, ; AND ZERO RH
JSP R7,S$$SY1 ; LOOKUP SYMBOL
JRST (R8) ; FOUND
ADD R0,[1B4] ; MAKE TYPE GLOBAL
TLZ R0,^O17777 ; WITH TABLE # = 0
JSP R7,S$$SY2 ; AND RETRY LOOKUP
JRST (R8) ; FOUND
MNELKS: MOVE R4,S$$GLP ; NOT FOUND, GET GLOBAL TABLE DESCR
JSP R7,S$$TBM ; MAKE NEW ENTRY
HRRM R2,RR2LKS ; SAVE VALUE POINTER
JSP R6,S$$MNS ; MAKE STRING BLOCK NONRETURNABLE
RR2LKS: MOVEI R2,.-. ; RESTORE VALUE POINTER
JRST 1(R8) ; RETURN NEW ENTRY
SPCLKS: JSP R7,S$$SY1 ; LOOKUP SYMBOL
JRST (R8) ; FOUND
JRST MNELKS ; NOT FOUND, MAKE NEW ENTRY
PRGEND
SUBTTL S$$TBM NEW TABLE ENTRY FUNCTION
ENTRY S$$TBM
EXTERN S$$GNS,S$$GRS,S$$TA1,S$$GLP
RADIX 10
SEARCH S$$NDF
COMMENT"
CALL: JSP R7,S$$TBM ; WITH TYPE/NO.,MAJORKEY IN R0, KEY
DESCRIPTOR IN R1, NEXT ENTRY POINTER IN R2, AND TABLE DESCRIPTOR
IN R4. RETURNS POINTER TO VALUE LOC OF NEW ENTRY IN R2, WITH
R0 AND R1 UNCHANGED"
S$$TBM: MOVE R3,1(R4) ; GET CURRENT SIZE AND POINTER
CAML R3,-1(R3) ; WITHIN CURRENT BLOCK?
JRST NEWEXT ; NO, GET NEW EXTENSION BLOCK
NEWEXR: HLRZ R5,R3 ; GET CURRENT SIZE
HRLI R3,4(R5) ; ADD 4 LOCS
MOVEM R3,1(R4) ; UPDATE CURRENT SIZE, POINTER
ADDI R3,(R5) ; PTR TO NEW ENTRY
MOVEM R0,1(R3) ; SAVE TYPE/NO.,MAJORKEY
MOVEM R1,2(R3) ; SAVE KEY DESCR
HLL R2,(R2) ; FORM CHAIN WORD
MOVEM R2,(R3) ; AND SAVE
HRLM R3,(R2) ; SPLICE ENTRY INTO CHAIN
MOVS R2,R2
HRRM R3,(R2)
MOVEI R2,3(R3) ; FORM POINTER TO VALUE LOC
JRST (R7) ; AND RETURN
NEWEXT: MOVEM R0,SAVTMP ; SAVE R0,R2,R4, AND KEY DESCR
MOVEM R2,SAVTMP+1
MOVEM R4,SAVTMP+2
MOVEM R1,S$$TA1
HRRZ R0,(R4) ; GET EXTENSION BLOCK SIZE
CAMN R4,S$$GLP ; IS TABLE GLOBAL SYMBOL TABLE?
JRST TBMGNS ; YES, GET NONRETURNABLE BLOCK
JSP R6,S$$GRS ; NO, GET RETURNABLE BLOCK
TBMGNR: MOVE R4,SAVTMP+2 ; RESTORE R4
MOVE R3,1(R4) ; GET LAST EXT POINTER
HRRM R1,-1(R3) ; SAVE EXTENSION POINTER TO NEW ONE
SUBI R0,2 ; EXTENSION SIZE MAX
HRLZM R0,1(R1) ; SAVE IN NEW EXTENSION BLOCK
MOVEI R3,2(R1) ; FORM NEW EXTENSION POINTER
SETZ R1,
EXCH R1,S$$TA1 ; RESTORE KEY DESCR
MOVE R2,SAVTMP+1 ; RESTORE R2 AND R0
MOVE R0,SAVTMP
JRST NEWEXR ; RETURN TO SEQUENCE
TBMGNS: JSP R6,S$$GNS ; GET NONRETURNABLE BLOCK
JRST TBMGNR
; STORAGE
SAVTMP: BLOCK 3
PRGEND
SUBTTL S$$TMR 'TIMER' OPTION ROUTINES
ENTRY S$$STT,S$$TMF,S$$TMX,S$$TMO
EXTERN S$$STE,S$$KWD,S$$PBP,S$$TMS,S$$OUC,S$$OUT,S$$ITS
RADIX 10
SEARCH S$$NDF
COMMENT/
STATEMENT TIMING
CALL: JSP R12,S$$STT ; FINISH TIMING ON LAST STATEMENT, START
XWD STNO,FAILPT ; TIMING ON NEW ONE, AND THEN GO TO
S$$STE. DOES NOTHING IF TIMING IS NOT ACTIVE FOR CURRENT ROUTINE,
OR DOES NOT FINISH TIMING ON LAST STATEMENT IF &STNO IS 0.
FUNCTION RETURN TIMING
CALL: JSP R5,S$$TMF ; SIMILAR TO S$$STT, BUT CALLED FROM
FUNCTION RETURN OR SYSTEM EXIT TO CLOSE OUT TIMING ON LAST &STNO.
TIMER EXIT STATISTICS
CALL: JSP R7,S$$TMX ; WITH PROGRAM LIST IN R6, OUTPUTS TIMING
STATISTICS FOR EACH PROGRAM BEING TIMED.
PROGRAM TIMER STATISTICS
CALL: JSP R7,S$$TMO ; WITH PARBLK POINTER IN R6, TIMING
BLOCK POINTER IN R5, OUTPUTS TIMING STATISTICS FOR PROGRAM
SPECIFIED BY PARBLK POINTER, LEAVES R6 UNCHANGED/
; STATEMENT AND FUNCTION RETURN TIMING
S$$STT: JSP R4,TMRCOM ; STATEMENT TIMING, INDEX = 0
S$$TMF: JSP R4,TMRCOM ; RETURN TIMING, INDEX = 1
TMRCOM: SUBI R4,S$$STT+1
HRRZ R3,@S$$PBP ; GET TIMING BLOCK POINTER
JUMPE R3,TMRFIN(R4) ; SKIP OUT IF NO TIMING
SETZ R0,
RUNTIM R0, ; GET CURRENT RUNTIME
MOVE R1,S$$TMS ; GET PREVIOUS RUNTIME
MOVEM R0,S$$TMS ; SAVE CURRENT RUNTIME
MOVE R2,S$$KWD+2 ; GET &STNO
JUMPE R2,TMRFIN(R4) ; SKIP OUT IF 0 (NO TIMING YET)
SUB R0,R1 ; COMPUTE ELAPSED TIME FOR STATEMENT
ADDM R0,(R3) ; ADD TO TOTAL TIME
HRLI R0,1 ; 1 MORE STATEMENT FOR COUNT
ADDI R3,(R2) ; TIMING BLOCK ENTRY FOR STATEMENT
ADDM R0,(R3) ; ADD 1,TIME TO TOTAL EXECUTION FOR STATEMENT
JRST TMRFIN(R4) ; EXIT
TMRFIN: JRST S$$STE ; STATEMENT TIMING EXIT
JRST (R5) ; RETURN TIMING EXIT
; TIMER EXIT STATISTICS
S$$TMX: HRRM R7,TMXFIN ; SAVE RETURN LINK
HLRZ R6,R6 ; GET FIRST PROGRAM PARBLK
TMXLOP: HRRZ R5,1(R6) ; GET TIMING BLOCK POINTER
JUMPE R5,.+2 ; SKIP IF 0
JSP R7,S$$TMO ; OTHERWISE OUTPUT STATISTICS
HRRZ R6,(R6) ; GET NEXT PARBLK POINTER
JUMPN R6,TMXLOP ; AND LOOP IF NONZERO
TMXFIN: JRST .-. ; OR RETURN
; PROGRAM TIMER STATISTICS
S$$TMO: MOVE R1,MSG1 ; "////TIMING STATISTICS FOR "
MOVEM R1,@S$$OUC ; OUTPUT
MOVE R1,-1(R6) ; GET PROGRAM NAME STRING DESCR
MOVEM R1,@S$$OUT ; OUTPUT
MOVE R1,[POINT 7,MSG2S+5,27] ; INSERT IN TOTAL TIME MESSAGE
HRRZ R2,(R5) ; GET TOTAL TIME
HRRM R2,PERCNT ; SAVE IN PERCENT CALCULATION
SETZM MSG2S+6 ; CLEAR CONVERSION AREA
JSP R4,S$$ITS ; CONVERT TO STRING
MOVE R1,MSG2 ; "// TOTAL TIME FOR PROGRAM = XXX MS."
MOVEM R1,@S$$OUT ; OUTPUT
MOVE R1,MSG3 ; TIMING STATISTICS COLLUMN HEADER
MOVEM R1,@S$$OUT ; OUTPUT
SETZM STSTAT+3 ; INITIALIZE STATEMENT #
HLRZ R1,(R5) ; SET UP LOOP POINTER FOR STATEMENT BLOCK
ANDI R1,^O177777
MOVNI R1,(R1)
HRLI R5,(R1)
AOBJP R5,(R7) ; START AT FIRST STATEMENT ENTRY
HRLI R7,(R6) ; SAVE PARBLK POINTER
TMOLP1: AOS STSTAT+3 ; INCREMENT STATEMENT NUMBER
MOVE R1,(R5) ; GET COUNT,TIME
HLRZM R1,STSTAT+2 ; SAVE COUNT
HRRZM R1,STSTAT+1 ; SAVE TIME
MOVEI R2,100 ; COMPUTE % OF TOTAL
IMULI R2,(R1)
PERCNT: IDIVI R2,.-.
HRRZM R2,STSTAT ; SAVE
MOVE R3,MSG4S ; BLANK OUT NUMERIC FIELDS
MOVEM R3,MSG4S+1
MOVEM R3,MSG4S+4
MOVEM R3,MSG4S+7
MOVEM R3,MSG4S+10
MOVEI R6,3 ; 4 STATISTICS LOOP
TMOLP2: MOVE R1,STPOIN(R6) ; GET BYTE POINTER FOR STATISTIC
MOVE R2,STSTAT(R6) ; GET STATISTIC
JSP R4,S$$ITS ; CONVERT TO STRING IN MESSAGE
SOJGE R6,TMOLP2 ; LOOP FOR EACH STATISTIC
MOVE R1,MSG4 ; GET STATISTICS LINE
MOVEM R1,@S$$OUT ; OUTPUT
AOBJN R5,TMOLP1 ; LOOP FOR EACH STATEMENT
HLRZ R6,R7 ; RESTORE PARBLK POINTER
JRST (R7) ; RETURN
; STORAGE
MSG1: POINT 7,.+1,35
BYTE (2)2(16)7(18)27
BYTE (7)^O12,^O12,^O12,^O12,"*"
ASCII/TIMING STATISTICS FOR /
MSG2: POINT 7,.+1,35
BYTE (2)2(16)9(18)39
MSG2S: BYTE (7)^O12,^O12," "," ","T"
ASCII/OTAL TIME FOR PROGRAM = MS./
MSG3: POINT 7,.+1,35
BYTE (2)2(16)13(18)62
BYTE (7)^O12,^O12," ","S","T"
ASCII/ATEMENT # OF EXECUTIONS TIME IN MS. /
ASCII/ % OF TOTAL TIME/
MSG4: POINT 7,.+1,35
BYTE (2)2(16)12(18)55
MSG4S: REPEAT 11,< ASCII/ />
STPOIN: POINT 7,MSG4S+10
POINT 7,MSG4S+7
POINT 7,MSG4S+4
POINT 7,MSG4S+1
STSTAT: BLOCK 4
PRGEND
SUBTTL S$$STE STATEMENT ENTRY ROUTINE
ENTRY S$$STE
EXTERN S$$KWD,S$$FLP,S$$ITS,S$$SST,S$$PBP,S$$OUT
RADIX 10
SEARCH S$$NDF
COMMENT/
CALL: JSP R12,S$$STE ; WHERE STNO IS THE STATEMENT NUMBER
XWD STNO,FAILPT ; AND FAILPT IS THE STATEMENT FAILPOINT
&LASTNO IS SET TO &STNO,&STNO IS SET TO STNO, &STCOUNT IS INCRE-
MENTED AND TESTED AGAINST &STLIMIT, AND THE FAILPOINT POINTER IS SET.
IF &STNTRACE IS NOT 0, A STATEMENT TRACE MESSAGE IS OUTPUT/
S$$STE: MOVE R1,(R12) ; GET STNO, FAILPT
HRRZM R1,S$$FLP ; SET FAILPOINT
HLRZ R1,R1 ; GET STNO
EXCH R1,S$$KWD+2 ; UPDATE &STNO, GET OLD &STNO
MOVEM R1,S$$KWD+1 ; SAVE AS NEW &LASTNO
AOS R1,S$$KWD+4 ; INCREMENT &STCOUNT
CAML R1,S$$KWD+13 ; IS IT < &STLIMIT
UFERR 6,R12 ; NO, ERROR
SKIPN S$$KWD+11 ; IS &STNTRACE ON?
JRST 1(R12) ; NO, RETURN
SETZM TRCMSG+5 ; INITIALIZE TRACE MESSAGE
SETZM TRCMSG+7
SETZM TRCMSG+8
SETZM TRCMSG+11
SETZM TRCMSG+12
MOVE R1,[POINT 7,TRCMSG+5] ; EDIT IN &STNO
MOVE R2,S$$KWD+2
JSP R4,S$$ITS
MOVE R1,S$$PBP ; EDIT IN PROGRAM NAME
MOVE R1,-2(R1)
HRRZ R2,(R1)
CAILE R2,10
MOVEI R2,10
MOVE R3,[POINT 7,TRCMSG+7]
ILDB R0,R1
IDPB R0,R3
SOJG R2,.-2
MOVE R1,[POINT 7,TRCMSG+11] ; EDIT IN TIME
SETZ R2,
RUNTIM R2,
SUB R2,S$$SST
JSP R4,S$$ITS
MOVE R1,MSGDSC ; OUTPUT TRACE MESSAGE
MOVEM R1,@S$$OUT
JRST 1(R12) ; RETURN
; STORAGE
MSGDSC: POINT 7,.+1,35
BYTE (2)2(16)14(18)65
TRCMSG: ASCII/*STNTRACE* OF STATEMENT /
BLOCK 1
ASCII/ IN /
BLOCK 2
ASCII/ AT TIME= /
BLOCK 2
PRGEND
SUBTTL S$$CPS COPY STRING ROUTINE
ENTRY S$$CPS
EXTERN S$$GRS,S$$TA1
RADIX 10
SEARCH S$$NDF
COMMENT/
CALL: JSP R7,S$$CPS ; WITH STRING DESCRIPTOR IN R1, RETURNS
NEW STRING DESCRIPTOR IN R1/
S$$CPS: JUMPE R1,(R7) ; RETURN IF NULL
HRRZ R2,(R1) ; GET CHAR COUNT
JUMPN R2,.+3 ; IS IT 0?
SETZ R1, ; YES, SET TO NULL VALUE
JRST (R7) ; AND RETURN
MUL R2,[^F0.2B0] ; COMPUTE NUMBER OF WORDS NEEDED
MOVEI R0,2(R2)
MOVEM R1,S$$TA1 ; SAVE OLD DESCR
JSP R6,S$$GRS ; GET BLOCK FOR NEW STRING
HRLI R1,^O700 ; FORM STRING DESCR
MOVE R2,R1 ; FORM BLT WORD
HRL R2,S$$TA1
HRRZ R3,@S$$TA1 ; TRANSFER CHAR COUNT
HRRM R3,(R2)
MOVE R3,R0 ; FORM END ADDR FOR BLT
ADDI R3,-1(R2)
AOBJP R2,.+1 ; START BLT ON SECOND WORD OF BLOCKS
BLT R2,(R3)
SETZM S$$TA1
JRST (R7) ; RETURN
PRGEND
SUBTTL S$$GNP GET NEXT NUMERICAL PARAMETER ROUTINE
ENTRY S$$GNP
RADIX 10
SEARCH S$$NDF
COMMENT/
CALL: JSP R4,S$$GNP ; WITH BYTE POINTER IN R1, BYTE COUNT
IN R3. PROCESSES SIGNED INTEGER INCLUDING DELIMITER AND RETURNS
TO 1(R4) WITH INTEGER VALUE IN R2 AND DELIMITER IN R0, OR RE-
TURNS TO 0(R4) IF DELIMITER IS NOT FOUND, WITH INTEGER IN R2/
S$$GNP: SETZ R2, ; INITIAL INTEGER VALUE
SOJL R3,(R4) ; RETURN IF NO MORE CHARS
HLLI R4, ; INITIAL SIGN IS +
ILDB R0,R1 ; GET FIRST CHAR
CAIE R0,"-" ; IS IT A - SIGN?
JRST TRYPLS ; NO, TRY PLUS
HRLI R4,-1 ; SET SIGN TO -
JRST NXTDIG ; GO INTO LOOP
TRYPLS: CAIN R0,"+" ; IS IT A + SIGN
JRST NXTDIG ; YES, GO INTO LOOP
DIGLOP: CAIL R0,"0" ; IS IT A DIGIT?
CAILE R0,"9"
AOJA R4,GNPFIN ; NO, DELIMITER FOUND
SUBI R0,"0" ; GET INTEGER DIGIT
IMULI R2,10 ; TOT = TOT*10+DIGIT
ADD R2,R0
NXTDIG: SOJL R3,GNPFIN ; QUIT IF NO MORE CHARS
ILDB R0,R1 ; GET NEXT CHAR
JRST DIGLOP ; AND LOOP
GNPFIN: JUMPGE R4,(R4) ; RETURN IF + VALUE
MOVN R2,R2 ; OR NEGATE
JRST (R4) ; AND RETURN
PRGEND
SUBTTL S$$ASG ASSIGNMENT ROUTINE
ENTRY S$$ASG
EXTERN S$$DSG,S$$PGL
RADIX 10
SEARCH S$$NDF
COMMENT/
CALL: JSP R9,S$$ASG ; WITH VALUE IN R1 AND NAME DESCRIPTOR
ON ES, DOES NORMAL OR DEDICATED ASSIGNMENT/
S$$ASG: MOVEM R9,S$$PGL ; SAVE PROGRAM LINK
POP ES,R8 ; GET NAME OFF ES
TLNE R8,3B23 ; ARE DEDICATED BITS ON?
JRST S$$DSG ; YES, DEDICATED ASSIGNMENT
MOVEM R1,(R8) ; NO, NORMAL ASSIGNMENT (POSSIBLE OUTPUT)
JRST (R9) ; RETURN
PRGEND
SUBTTL S$$MVS MOVE STRING ROUTINE
ENTRY S$$MVS
RADIX 10
SEARCH S$$NDF
P$BRKE=8 ; BREAK EVEN POINT OF REGISTER LOOP
COMMENT/
CALL: JSP R7,S$$MVS ; WITH OBJECT BYTE POINTER IN R1, SOURCE
BYTE POINTER IN R2, AND CHARACTER COUNT (>0) IN R3/
S$$MVS: CAIL R3,P$BRKE ; FEWER CHARS THAN BREAK EVEN POINT?
JRST MOVLOP ; NO, MOVE LOOP INTO FAST REGISTERS
CHRLP1: ILDB R0,R2 ; GET CHAR FROM SOURCE
IDPB R0,R1 ; PUT CHAR IN OBJECT
SOJG R3,CHRLP1 ; LOOP
JRST (R7) ; OR RETURN
MOVLOP: HLL R7,S$$MVS+1 ; INSERT JRST IN LH OF R7
MOVE R6,[XWD CHRLOP,CHRLP2] ; MOVE LOOP INTO R4-R6
BLT R6,CHRLPE
JRST CHRLP2 ; START LOOP
CHRLOP: PHASE 4
CHRLP2: ILDB R0,R2 ; R4: GET CHAR
IDPB R0,R1 ; R5: PUT CHAR
CHRLPE: SOJG R3,CHRLP2 ; R6: LOOP
DEPHASE
PRGEND
SUBTTL S$$EQS STRING EQUALITY TEST ROUTINE
ENTRY S$$EQS
RADIX 10
SEARCH S$$NDF
COMMENT/
CALL: JSP R5,S$$EQS ; WITH STRING DESCRIPTORS IN R1 AND R2,
RETURNS TO 0(R5) IF EQUAL AND 1(R5) IF NOT EQUAL/
S$$EQS: CAMN R1,R2 ; ARE DESCRIPTORS EQUAL?
JRST (R5) ; YES, STRINGS MUST BE EQUAL
SETZ R0, ; ZERO R0 INCASE DESCR IS 0 (POINTS TO R0)
HRRZ R3,(R2) ; GET FIRST CHAR COUNT, INCLUDING NULL OR ZERO
HRRZ R0,(R1) ; GET SECOND CHAR COUNT, INCLUDING NULL OR ZERO
CAIE R0,(R3) ; ARE COUNTS EQUAL?
JRST 1(R5) ; NO, STRINGS UNEQUAL
JUMPE R0,(R5) ; STRINGS EQUAL IF 0 CHAR
CAIG R0,5 ; <6 CHARS?
JRST CHRLOP ; YES, DO CHAR LOOP
MUL R3,POINT2 ; NO, COMPUTE # WORDS
ROT R4,4 ; AND # OF REM CHARS
MOVE R4,REMTBL(R4)
HRRM R4,GETREM ; SAVE REM CHARS
TLC R1,^B1001B27 ; SET BYTE PTRS
TLC R2,^B1001B27 ; FOR 35-BIT BYTES
WRDLOP: ILDB R0,R1 ; GET WORD FROM FIRST
ILDB R4,R2 ; GET WORD FROM SECOND
CAME R0,R4 ; EQUAL?
JRST 1(R5) ; NO, STRINGS UNEQUAL
SOJG R3,WRDLOP ; LOOP FOR EACH WORD
TLC R1,^B1001B27 ; SET BYTE PTRS
TLC R2,^B1001B27 ; BACK TO 7-BIT BYTES
GETREM: MOVEI R3,.-. ; GET REM CHARS
CHRLOP: ILDB R0,R1 ; GET CHAR FROM FIRST
ILDB R4,R2 ; GET CHAR FROM SECOND
CAIE R0,(R4) ; EQUAL?
JRST 1(R5) ; NO, STRINGS UNEQUAL
SOJG R3,CHRLOP ; LOOP FOR EACH CHAR
JRST (R5) ; STRINGS EQUAL IF ALL CHARS MATCH
; STORAGE
REMTBL=.-1 ; REM=0, IMPOSSIBLE
1 ; REM=1, 1 CHAR REM
POINT2: ^O63146300000 ; REM=2, IMPOSSIBLE, USE SPACE
2 ; REM=3, 2 CHAR REM
3 ; REM=4, 3 CHAR REM
0 ; REM=5, IMPOSSIBLE
4 ; REM=6, 4 CHAR REM
5 ; REM=7, 5 CHAR REM
PRGEND
SUBTTL S$$SRT,S$$NRT,S$$FRT 'RETURN','NRETURN','FRETURN' LABELS
ENTRY S$$SRT,S$$NRT,S$$FRT
EXTERN S$$KWD,S$$RTP,S$$TMF,S$$PGL
RADIX 10
SEARCH S$$NDF
COMMENT/
CALL: JRST S$$SRT[S$$NRT,S$$FRT] ; RESULT OF JUMP TO 'RETURN',
'NRETURN', OR 'FRETURN' LABELS/
S$$FRT: JSP R12,S$$NRT+1 ; 'FRETURN', INDEX=-1
S$$SRT: JSP R12,S$$NRT+1 ; 'RETURN', INDEX=0
S$$NRT: JSP R12,S$$NRT+1 ; 'NRETURN', INDEX=1
SUBI R12,S$$NRT
SOSGE S$$KWD+3 ; DECREMENT &FNCLEVEL
UFERR 2,S$$PGL ; RETURN FROM 0 LEVEL
MOVE R1,@RTNTYP(R12) ; GET RETURN TYPE
MOVEM R1,S$$KWD+6 ; SAVE IN &RTNTYPE
JSP R5,S$$TMF ; FINISH TIMING ON LAST STATEMENT
POPJ SS, ; GO TO APPROPRIATE FUNCTION RETURN ROUTINE
; STORAGE
S$$RTP+4 ; POINTS TO 'FRETURN' DESCRIPTOR
RTNTYP: S$$RTP ; POINTS TO 'RETURN' DESCRIPTOR
S$$RTP+8 ; POINTS TO 'NRETURN' DESCRIPTOR
PRGEND
SUBTTL S$$BGT BAD GOTO ERROR EXIT
ENTRY S$$BGT
EXTERN S$$PGL
RADIX 10
SEARCH S$$NDF
COMMENT/
CALL: JRST S$$BGT ; CALLED BY FAILPOINT ROUTINE DURING GOTO EVA
LUATION/
S$$BGT: UFERR 3,S$$PGL ; FAILURE DURING GOTO EVALUATION
PRGEND
SUBTTL S$$NFE FAILURE UNDER 'NOFAIL' ERROR EXIT
ENTRY S$$NFE
EXTERN S$$PGL
RADIX 10
SEARCH S$$NDF
COMMENT/
CALL: JRST S$$NFE ; CALLED BY FAILPOINT ROUTINE/
S$$NFE: UFERR 13,S$$PGL ; FAILURE UNDER 'NOFAIL'
PRGEND
SUBTTL S$$UDF UNDEFINED FUNCTION ERROR EXIT
ENTRY S$$UDF
EXTERN S$$PGL
RADIX 10
SEARCH S$$NDF
COMMENT/
CALL: JRST S$$UDF ; CALLED BY FCALV OR FCALN/
S$$UDF: CFERR 5,S$$PGL ; UNDEFINED FUNCTION CALL
PRGEND
SUBTTL S$$CPE COMPILATION ERROR EXIT
ENTRY S$$CPE
RADIX 10
SEARCH S$$NDF
COMMENT/
CALL: JSP R12,S$$CPE ; EXECUTION OF STATEMENT WITH COMPI-
LATION ERROR/
S$$CPE: UFERR 12,R12
END