	.TITLE	RECUR
	.LIBRARY	"CLD"
	.PSECT	RECUR
	$ENTDEF
	$CHGDEF
	.ENTRY	RECUR,^M<R6,R7,R8,R9,R10,R11>
;
; RECURSIVE ROUTINE TO PROCESS KEYWORD LISTS
	MOVL	4(AP),R7
	MOVZWL	ENT_W_KEYWORDS(R7),R9			;ANY KEYWORDS?
	BNEQ	ADDLST
	BRW	FINI					;  RETURN IF NOT
;
;   A TABLE OF KEYWORD LISTS IS MAINTAINED TO AVOID DUPLICATON OF
;	THE SAME LIST AND TO AVOID DUPLICATION OF THE LIST NAMES
;	RECUR LOOKS FOR THE KEYWORD LIST IN THE TABLE.  IF IT IS
;	NOT THERE, IT IS ADDED.  IF ANOTHER LIST IS THERE WITH
;	THE SAME NAME, THE NEW LIST IS GIVEN A KLUGE BYTE BUMPED
;	BY ONE.
;	   KEYWORD TABLE FORMAT:
;		LONGWORD 1	KEYWORD LIST ADDRESS
;		LONGWORD 2	ADDRESS OF COUNTED ASCII QUAL/PARM NAME STRING
;		LONGWORD 3	KLUGE CHARACTER ADDED TO THE END OF THE
;				KEYWORD NAME STRING FOR CASES OF THE SAME
;				NAMED QUALIFIER/PARAM HAVING DIFFERENT KEYWORD
;				LISTS
;
ADDLST:	CVTWL	R9,R9
	ADDL	R7,R9
	MOVL	R7,R4
	MOVZWL	ENT_W_NAME(R7),R6
	CMPL	#9,R6			;<= 9 IS A PARAMETER
	BLEQ	10$
	DECL	R6
	MULL2	#3,R6
	MOVAL	P1,R4
;
10$:	ADDL3	R6,R4,R11		;R11 = ADDRESS OF ENTITY NAME
	MOVZBL	#^X30,SAVE		;KLUGE CHARACTER IS DEFAULTED TO 0
	PUSHL	R8
	MOVAL	TABKEY,R8		;R8=CURRENT KEYWORD TABLE POSITION
	MOVL	KEYNUM,-(SP)		;NUMBER OF KEYWORD LISTS DEFINED
	BEQL	50$			;BRANCH IF THIS IS THE FIRST ENTRY
;
20$:	CMPL	R9,(R8)+		;COMPARE KEYWORD LIST ADDRESSES
	BEQL	60$			;BRANCH IF LIST FOUND
	MOVL	(R8)+,R10
	CMPB	(R10)+,(R11)		;COMPARE NAME LENGTHS
	BNEQ	30$
	CMPC3	CLEN,(R10),1(R11)	;COMPARE NAMES
	BNEQ	30$
	ADDL3	#1,(R8),SAVE		;SAME NAME SO BUMP THE KLUGE CHARACTER
30$:	TSTL	(R8)+
	SOBGTR	(SP),20$		;LOOP THROUGH TABLE
;
; ADD THE ENTRY TO THE KEYWORD LIST TABLE
;
50$:	MOVL	R9,(R8)+
	MOVL	R11,(R8)+
	MOVL	SAVE,(R8)
	INCL	KEYNUM
	TSTL	(SP)+
	POPL	R8
	CLRL	-(SP)			;SET ENTRY FLAG TO KEYWORD
	BRB	CHKKEY
;
; KEYWORD LIST IS ALREADY IN THE TABLE.  DON'T PROCESS THIS DUPLICATE
;
60$:	TSTL	(SP)+
	POPL	R8
	BRW	FINI
;
;
	.ENTRY	RECUR1,^M<R6,R7,R8,R9,R10,R11>
;
; ENTRY POINT FOR RECURSIVE SYNTAX STATEMENT PROCESSING
;
	MOVL	4(AP),R9
	MOVL	#1,-(SP)
	MOVZWL	ENT_W_SYNTAX(R9),R10
	BNEQ	CHKKE2
	BRW	FINI
;
; SYNTAX STATEMENTS?
;
CHKKEY:	MOVZWL	ENT_W_SYNTAX(R9),R10
	BNEQ	CHKKE2
	BRW	NEXTKEY
CHKKE2:	CVTWL	R10,R10
	ADDL	R9,R10
;
;   A TABLE OF SYNTAX LISTS IS MAINTAINED IN THE SAME FORMAT AS THE
;	KEYWORD LIST TABLE.  THE LIST IS PROCESSED HERE JUST AS THE
; 	KEYWORD LIST IS PROCESSED AT ADDLST:
;
	MOVL	R9,R4
	MOVZWL	ENT_W_NAME(R9),R6
	CMPL	#9,R6
	BLEQ	10$
	DECL	R6
	MULL2	#3,R6
	MOVAL	P1,R4
10$:	ADDL3	R6,R4,R11		;R11 = ENTITY NAME ADDRESS
	MOVZBL	#^X30,SAVE		;DEFAULT KLUGE CHARACTER IS 0
	PUSHL	R8
	MOVAL	TABSYN,R8		;R8 = CURRENT LOCATION IN SYNTAX TABLE
	MOVL	SYNNUM,-(SP)		;NUMBER OF ENTRIES IN SYNTAX TABLE
	BEQL	50$			;BRANCH IF THIS IS THE FIRST ENTRY
;
20$:	CMPL	R10,(R8)+		;COMPARE SYNTAX LIST ADDRESSES
	BEQL	60$			;BRANCH IF LIST IS FOUND
	MOVL	(R8)+,R4
	CMPB	(R4)+,(R11)		;COMPARE ENTITY NAME LENGTHS
	BNEQ	30$
	MOVZBL	(R11),CLEN
	CMPC3	CLEN,(R4),1(R11)	;COMPARE ENTITY NAME STRINGS
	BNEQ	30$
	ADDL3	#1,(R8),SAVE
30$:	TSTL	(R8)+
	SOBGTR	(SP),20$		;LOOP THROUGH TABLE
;
; ADD AN ENTRY TO THE SYNTAX LIST TABLE
;
50$:	MOVL	R10,(R8)+
	MOVL	R11,(R8)+
	MOVL	SAVE,(R8)
	INCL	SYNNUM
	TSTL	(SP)+
	POPL	R8
	BRB	CPARMS
;
; SYNTAX LIST IS ALREADY IN THE TABLE.  IF CALLED AT RECUR1, QUIT. IF CALLED
;	AT RECUR, GO ON TO NEXT KEYWORD.
;
60$:	TSTL	(SP)+
	POPL	R8
	TSTL	(SP)			;TEST ENTRY FLAG
	BEQL	70$
	BRW	FINI
70$:	BRW	NEXTKEY
;
; EACH PARAMETER MUST BE CHECKED FOR KEYWORD LIST AND SYNTAX REFERENCES
;
CPARMS:	BITB	#CHG_M_PARMS,CHG_B_FLAGS(R10)
	BEQL	ANYQUA
	MOVZWL	CHG_W_PARMS(R10),R11
	BEQL	ANYQUA
	CVTWL	R11,R11
	ADDL	R10,R11
CHKPRM:
	PUSHL	R11
	CALLS	#1,RECUR		;FIRST DO KEYWORDS
	PUSHL	R11
	CALLS	#1,RECUR1		;THEN DO SYNTAX STATEMENTS
	MOVZBL	ENT_B_NEXT(R11),R6
	BEQL	ANYQUA
	ADDL	R6,R11
	BRB	CHKPRM
;
; EACH QUALIFIER MUST BE CHECKED FOR KEYWORD AND SYNTAX REFERENCES
;
ANYQUA:
	BITB	#CHG_M_QUALS,CHG_B_FLAGS(R10)
	BEQL	DOSYNT
	MOVZWL	CHG_W_QUALS(R10),R11
	BEQL	DOSYNT
	CVTWL	R11,R11
	ADDL	R10,R11
CHKQUA:
	PUSHL	R11
	CALLS	#1,RECUR		;FIRST THE KEYWORD LISTS
	PUSHL	R11
	CALLS	#1,RECUR1		;THEN THE SYNTAX LISTS
	MOVZBL	ENT_B_NEXT(R11),R6
	BEQL	DOSYNT
	ADDL	R6,R11
	BRB	CHKQUA
;
; RECURSIVE CHECKING OF THIS SYNTAX LIST IS FINISHED. WRITE OUT THE DEFINITION
;    RECORDS.
;
DOSYNT:
	PUSHL	#1
	PUSHL	R9
	CALLS	#2,SYNTAX		;WRITE OUT THE DEFINE SYNTAX RECORD
;
; IMAGE/ROUTINE RECORD
;
	BITB	#CHG_M_IMAGE,CHG_B_FLAGS(R10)
	BEQL	20$
	MOVZWL	CHG_W_IMAGE(R10),R11
	CVTWL	R11,R11
	BGTR	10$
	PUSHL	R11
	CALLS	#1,ROUTINE		;INTERNAL ROUTINE NAME 
	BRB	20$
10$:	ADDL	R10,R11
	MOVB	(R11)+,R6
	MOVC3	R6,(R11),IMGNAM
	ADDL	#13,R6
	$RAB_STORE	RAB=OUTRAB,RBF=IMGREC,RSZ=R6
	$PUT	RAB=OUTRAB
;
; PARAMETERS
;
20$:	BITB	#CHG_M_PARMS,CHG_B_FLAGS(R10)
	BEQL	40$
	MOVZWL	CHG_W_PARMS(R10),R11
	BNEQ	30$
;
	$RAB_STORE	RAB=OUTRAB,RBF=NOPAR,RSZ=#19
	$PUT	RAB=OUTRAB
	BRB	40$
;
30$:	ADDL	R10,R11
	PUSHL	R11
	CALLS	#1,DOPARMS
;
; QUALIFIERS
;
40$:	BITB	#CHG_M_QUALS,CHG_B_FLAGS(R10)
	BEQL	60$
	MOVZWL	CHG_W_QUALS(R10),R11
	BNEQ	50$
;
	$RAB_STORE	RAB=OUTRAB,RBF=NOQUA,RSZ=#19
	$PUT	RAB=OUTRAB
	BRB	60$
;
50$:	ADDL	R10,R11
	PUSHL	R11
	CALLS	#1,DOQUALS
60$:	TSTL	(SP)		;TEST ENTRY FLAG
	BEQL	NEXTKEY
	BRW	FINI		;EXIT IF CALLED AT RECUR1
;
; MORE KEYWORDS?
;
NEXTKEY:
	MOVZBL	ENT_B_NEXT(R9),R6
	BEQL	DOKEYS
	ADDL	R6,R9
	BRW	CHKKEY
;
; RECURSIVE CHECKING OF THIS KEYWORD LIST IS FINISHED.  WRITE ALL THE
;    RECORDS FOR THE KEYWORD LIST DEFINITION
;
DOKEYS:
	PUSHL	#1
	PUSHL	R7
	CALLS	#2,KEYWORD		;DEFINE TYPE RECORD
;
; NOW DO EACH KEYWORD IN THE LIST
;
	MOVZWL	ENT_W_KEYWORDS(R7),R9
	CVTWL	R9,R9
	ADDL	R7,R9
;
30$:	MOVZWL	ENT_W_NAME(R9),R10
	CVTWL	R10,R10
	ADDL	R9,R10
	MOVZBL	(R10)+,R6
	MOVC3	R6,(R10),KEYNAM
	ADDL	#17,R6
	$RAB_STORE	RAB=OUTRAB,RBF=KEYREC,RSZ=R6	
	$PUT	RAB=OUTRAB			;KEYWORD RECORD
;
	PUSHL	R7
	PUSHL	R9
	MOVL	R9,R7
	MOVL	#1,R10
	JSB	VALUE				;VALUE LIST
	POPL	R9
	POPL	R7
;
	BITL	#ENT_M_DEFTRUE,ENT_L_FLAGS(R9)
	BEQL	40$
	$RAB_STORE	RAB=OUTRAB,RBF=DEFREC,RSZ=#24
	$PUT	RAB=OUTRAB
40$:	BITL	#ENT_M_NEG,ENT_L_FLAGS(R9)
	BEQL	50$
	$RAB_STORE	RAB=OUTRAB,RBF=NEGREC,RSZ=#26
	$PUT	RAB=OUTRAB
;
50$:	PUSHL	#0
	PUSHL	R9
	CALLS	#2,SYNTAX		;SYNTAX RECORD
;
	MOVZBL	ENT_B_NEXT(R9),R10
	BEQL	FINI
	ADDL	R10,R9
	BRW	30$
;
FINI:	TSTL	(SP)+
	RET
;
;  LOCAL DATA
;
DEFSYN:	.ASCII	/define syntax /
SYNAM:	.BLKB	80.
UNDER:	.ASCII	/_/
KEYREC:	.ASCII	/       keyword   /
KEYNAM:	.BLKB	30.
NOPAR:	.ASCII	/       noparameters/
NOQUA:	.ASCII	/       noqualifiers/
IMGREC:	.ASCII	/       image /
IMGNAM:	.BLKB	80.
NEGREC:	.ASCII	/                 negatable/
SAVE:	.LONG	0
CLEN:	.LONG	0
SYNNUM::	.LONG	0
TABSYN::	.BLKL	300.
KEYNUM::	.LONG	0
TABKEY::	.BLKL	300.
	.END
