	.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
;
; INPUTS:
;
;
;	IMPURE STORAGE
;
BUFSIZ=40.				; Maximum number of chars in command
	.PSECT	$TEMP,D,RW,GBL,OVR
	.BLKB	1
TBUFF:	.BLKB	BUFSIZ
.EVEN
SADD:	.WORD	0			; Address of string
TADD:	.WORD	0			; ADDRESS OF BUFFER LOCATION
	.BLKB	2


	.PSECT	$CODE	LCL,I,RO,CON
;
;	Move command to input buffer
;
CMN::	CALL	LSINSV		; Save current input position
	MOV	#TBUFF-1,R2	; COMMAND SAVE BUFFER
	MOVB	$NFLSW,(R2)+	; Insert control flag
	MOVB	SUBSTK,R3	; Get substitute stack
	MOV	BUFADD(R3),R3	; Now have input buffer header
	CALL	CMCIN		; GET FIRST CHARACTER OF COMMAND
	CMPNE	#SEMI,R1,10$	; NOT A COMMENT?
	JMP	COMNT		; PROCESS COMMENT
10$:	MOVB	R1,(R2)+	; SAVE IT
	CMP	R2,#TBUFF+BUFSIZ ; at end of buffer?
	BHIS	30$		; yes
	CMPEQ	R1,#SPC,20$	; SPACE?
	CMPB	GCTABL(R1),#GC.LC ; ALPHABETIC?
	BHI	30$		; NO, DONE
20$:	CALL	CMCIN		; NEXT INPUT CHAR
	BR	10$
30$:	CLRB	(R2)+		; Chock input string
	CALL	LSINRS		; Restore input status
	MOVB	TBUFF,R3	; First char in buffer
	SUB	#'A,R3		; Convert it to table index
	BLT	100$		; bad index?
	CMP	R3,#26.		; too big?
	BGE	100$		; yes
	ASL	R3		; now byte pointer
	MOV	COMTAB(R3),R3	; starting point
	MOV	(R3)+,SADD	; String address
	MOV	#TBUFF+1,TADD	; Initial address
;
;	Start comparing strings to command
;
50$:	TSTEQ	(R3),100$	; No more entries this letter ?
	MOV	TADD,R4		; Buffer data
	MOV	SADD,R2		; String address
	MOVB	(R2)+,R0	; Get byte offset
	BGT	55$		; Positive ?
	TST	-(r3)		; It is synonym
	BIC	#^C<177>,R0	; Strip off hi bits
	BEQ	100$		; End of table ?
55$:	ADD	R0,SADD		; next string pointer
60$:	MOVB	(R2)+,R1	; TABLE CHAR TO TEST
	BMI	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?
	CMPNEB	GCTABL(R1),#GC.LC,85$ ; Table char not lowercase ?
	SUB	#40,R1		; Make it upper
	CMPEQB	R0,R1,60$	; Match ?
81$:	MOVB	(R2)+,R1	; Next table char
	BMI	106$		; End of entry ?
	CMPEQB	R1,#SPC,71$	; Space ?
	BLT	90$		; Done ?
	BR	81$		; Skip another
82$:	MOVB	(R2)+,R1	; Table char next
	BMI	106$		; End of entry
	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,#37,95$	; Not continuation char ?
	MOV	(R3),R3		; Get subtable
	MOV	(R3)+,SADD	; Now get 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?
	BISB	#200,TBUFF	; Set it as command
	CALL	FNDSB		; Search for substitution
	BCS	1$
	JMP	CMN		; Try again
1$:	JMP	KILCM		; Kill this command
;
;	All chars matched up to this point
;
106$:	DEC	R4
110$:	TSTB	-(R2)		; POINT TO TERMINAL BYTE
	MOVB	(R4),R1		; CHAR AT END OF STRING
	CMPB	GCTABL(R1),#GC.LC ; alphabetic?
	BLOS	90$		; no, do special processing
	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	CCIN		; Consume 1 char
	SOB	R4,160$		; Till all consumed
	RETURN
;
;	Get uppercase chars/convert tabs to spaces
; 
CMCIN:	CALL	GBYT		; GET 1 CHAR
	CMPNEB	GCTABL(R1),#GC.LC,10$ ; not lower case?
	SUB	#40,R1		; SET TO UPPER CASE
10$:	CMPNE	R1,#TAB,20$	; NOT TAB?
	MOV	#SPC,R1		; CONVERT TABS TO SPACES
20$:	RETURN
	.END
