	.TITLE	COMND
	.IDENT	/M04.0/

;
; DEC ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
; SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DEC.
;
; VERSION 02
;
; AUTHOR: L. WADE 1-JUN-72
;
; MODIFIED BY:
;
;	E. POLLACK U. OF W. 19-DEC-73
;
;	D. N. CUTLER 27-JUL-75
;
;	J. CLEMENT AUGUST 82
;
;MODIFACATIONS BY J. CLEMENT
;	PARSING FOR ANY VARIANT OF COMMAND
;		1. MUTIPLE TABS, SPACES ALLOWED
;		2. RUNON SYNTAX ALLOWED
;		3. fast parsing (alphabetical table)
;		4. Locked command parsing
;		5. Shortened table
;		6. Defined commands added
;
; COMMAND SCANNER
;
; READ AND DISPATCH ON COMMAND
;
;INPUT:	file is set to beginning of command
;OUTPUT:	(R2) = flags byte
;		(R3) = dispatch address
;		All other regs are destroyed
;
;	IMPURE STORAGE
;
	.vars
COMBUF:	.BLKB	1
TBUFF:	.BLKB	COMSIZ			; Contains the command
	.even
SADD:	.BLKA	1			; Address of string
TADD:	.BLKA	1			; ADDRESS OF BUFFER LOCATION
	.code
;
;	Move command to input buffer
;
COMND::	CALL	LSINSV		; Save current input position
	MOV	#COMBUF,R2	; COMMAND SAVE BUFFER
	CLRB	(R2)+		; Leading char
	CALL	CMCIN		; GET FIRST CHARACTER OF COMMAND
	BCS	30$
	CMPEQB	#excl,R1,5$	; An exclamation point
	CMPNE	#SEMI,R1,7$	; NOT A COMMENT?
5$:	JMP	COMNT		; PROCESS COMMENT
7$:	CMPEQ	#undsc,R1,8$	; underscore ?
	CMPNE	#dolar,R1,10$	; not dollar sign ?
8$:	MOVB	R1,COMBUF	; Save it
	CALL	LSINSV		; Save current position
	BR	21$
10$:	CMPEQ	R1,#SPC,20$	; SPACE?
	MOV	R1,R0
	ADD	#GCTABL,R0
	CMPB	(R0),#GC.LC	; ALPHABETIC?
	BHI	30$		; NO, DONE
20$:	MOVB	R1,(R2)+	; SAVE IT
21$:	CALL	CMCIN		; NEXT INPUT CHAR
	BCS	30$
	CMP	R2,#TBUFF+COMSIZ ; at end of buffer?
	BLO	10$		; No ?
30$:	CLRB	(R2)+		; Chock input string
	MOV	BUFAD,R0	; Current input
	MOV	BF.FUL(R0),BF.HED(R0)	; Save index for traceback
	CALL	LSINRS		; Restore input status
	CMPEQB	COMBUF,#undsc,33$	; Search user first ?
	CMPEQB	COMBUF,#dolar,34$	; System first ?
	BITNE	#LITFG!IFFLG,F.1,34$ ; literal or if processing active?
	TSTEQB	$USRCM,34$	; System first ?
33$:	JMP	101$		; Default is user first
34$:	MOV	#TBUFF,R2	; Current buffer pointer
	MOVB	(R2)+,R3	; First char in buffer
	MOV	R2,TADD		; Starting point
	SUB	#A,R3	; Convert to index
	BGE	37$		; not too small index ?
	JMP	100$		; bad index?
37$:	CMP	R3,#26.		; too big?
	BLE	38$		; No ?
	JMP	100$		; yes
38$:	INDXA	R3		; now table pointer
	ADD	#DSPAT,R3
	MOV	(R3),R3		; starting point
	MOV	(R3)+,R2	; String offset
	ADD	#COMTAB,R2	; Add on base
40$:	MOV	R2,SADD		; Save String address
;
;	Start comparing strings to command
;
50$:	MOV	TADD,R4		; Buffer data
	MOV	SADD,R2		; String address
	MOVB	(R2)+,R0	; Get byte offset
	BGT	55$		; Positive ?
	BIC	#^C<^o177>,R0	; Strip extra
	BNE	54$		; Not done ?
	JMP	100$		; Done ?
54$:	TST	-(r3)		; It is synonym so reset R3
55$:	TSTNE	(R3),56$	; Not done
	JMP	100$		; No more entries this letter ?
56$:	ADD	R0,SADD		; next string pointer
60$:	MOVB	(R2)+,R1	; TABLE CHAR TO TEST
	BGE	70$		; Not end of table entry ?
	JMP	110$		; END OF TABLE ENTRY
70$:	MOVB	(R4)+,R0	; INPUT STRING CHAR TO TEST
71$:	CMPNE	R0,#SPC,80$	; NOT SPACE?
	CMPEQB	(R4),R0,70$	; AND NEXT SPACE ALSO?
80$:	CMPEQB	R0,R1,60$	; Match?
	BITEQB	#^o100,R1,85$	; Not lower or upper case
	BITEQB	#^o40,R1,85$	; Uppercase ?
	BICB	#^o40,R1	; Make it upper
	CMPEQB	R0,R1,60$	; Match ?
81$:	MOVB	(R2)+,R1	; Next table char
	BGT	84$		; Not end of entry ?
	JMP	106$		; End of entry ?
84$:	CMPEQB	R1,#SPC,71$	; Space ?
	BLT	90$		; Done ?
	BITEQB	#^o40,R1,71$	; Uppercase ?
	BR	81$		; Skip another
82$:	MOVB	(R2)+,R1	; Table char next
	BGE	83$		; Not end of entry ?
	JMP	106$		; End of entry
83$:	CMP	R1,#SPC		; Compare with space
	BGE	82$		; Printable char ?
85$:	CMPNE	R1,#SPC,90$	; WAS TABLE CHAR SPACE?
	MOVB	(R2)+,R1	; YES, TRY THE NEXT
	BR	80$		; TO ACCEPT RUN ON SYNTAX
90$:	CMPNE	R1,#^o37,95$	; Not continuation char ?
	MOV	(R3),R3		; Get subtable
	MOV	(R3)+,R0	; Get string offset
	ADD	#COMTAB,R0	; Add on base
	MOV	R0,SADD		; Now save string address
	DEC	R4		; Char address to test
	MOV	R4,TADD		; Save char address
	BR	50$		; Start subtable
95$:	TST	(R3)+		; NEXT COMMAND
	BR	50$		; Continue with next entry
;
;	Command not recognized here
;
100$:	BITNE	#LITFG!IFFLG,F.1,120$ ; literal or if processing active?
	TSTNEB	$USRCM,105$	; User command first ?
101$:	MOV	#COMBUF,R0	; Table
	CMPEQB	(R0)+,#dolar,105$	; Default table only?
	BISB	#^o200,(R0)	; Set it as command
	CALL	FNDSB		; Search for substitution
	BCS	104$
	JMP	COMND		; Try again
104$:	CMPEQB	COMBUF,#undsc,105$	; User specified ?
	TSTEQB	$USRCM,105$	; Default is system first?
	BICB	#^o200,TBUFF	; Clear extra bits
	JMP	34$
105$:	MOV	#52.,R0		; Message to output
	JMP	ILCMA		; Output illegal command message + kill
;
;	All chars matched up to this point
;
106$:	DEC	R4
110$:	TSTB	-(R2)		; POINT TO TERMINAL BYTE
	MOVB	(R4),R0		; CHAR AT END OF STRING
	BITEQB	#^o100,R0,113$	; Not alpha ?
	JMP	90$		; end, do special processing
113$:	BITEQ	#LITFG!IFFLG,F.1,130$ ; LITERAL PROCESSING NOT ACTIVE?
	MOV	#CMADR,R0	; Check legal table
115$:	CMPEQ	(R3),@(R0)+,130$; COMMAND ADDRESS MATCH?
	TSTNE	(R0),115$	; more in table ??
120$:	BITNE	#LITFG,F.1,125$	; Literal ??
	JMP	COMNT		; Skip this line
125$:	CALL	BKSPI		; And restore .
	JMP	TEXT		; DO LITERAL
130$:	BITEQB	(R2),F.1,150$	; Command legal in current context?
	MOV	#21.,R0		; Illegal command during footnote
	BITNE	#FOTF,F.1,140$	; Footnote in progress ?
	MOV	#22.,R0		; Illegal during note
	BITNE	#NOTF,F.1,140$	; Note in progress ?
	MOV	#23.,R0		; Illegal during lock
	BITNE	#LCKF,F.1,140$	; Lock on ?
	MOV	#24.,R0		; Illegal during text section
140$:	JMP	ILCMA
150$:	SUB	#TBUFF,R4	; number of char to consume
160$:	CALL	CMCIN		; Consume 1 char
	SOB	R4,160$		; Till all consumed
	RETURN
;
;	Get uppercase chars/convert tabs to spaces
; 
CMCIN:	CALL	CCINP		; Get params
	BCS	20$		; End of input
	BITEQB	#^o100,R1,10$	; Control or number ?
	BICB	#^o40,R1	; SET TO UPPER CASE
10$:	CMPNEB	R1,#TAB,20$	; NOT TAB?
	MOV	#SPC,R1		; CONVERT TABS TO SPACES
20$:	RETURN
	.END
