Google
 

Trailing-Edge - PDP-10 Archives - ALGOL-20_1-29-82 - algol-sources/algcon.mac
Click algol-sources/algcon.mac to see without markup as text/plain
There are 5 other files named algcon.mac in the archive. Click here to see a list.
;
;
;COPYRIGHT (C) 1975,1981,1982 BY
;DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;
;
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY  OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF THE  SOFTWARE  IS  HEREBY
;TRANSFERRED.
;
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT  NOTICE
;AND  SHOULD  NOT  BE  CONSTRUED  AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY  OF  ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
;
;

; WRITTEN BY K. NIST, C.M.U./ EDITED BY R. M. DE MORGAN

	SEARCH ALGPRM		; MAIN PARAMETER FILE

	SALL

%TITLE(ALGCON,ALGOL COMPILER CONTROL MODULE)

	TWOSEG

	LOC	.JBVER		;[171]
	VERNO			;[171]

	RELOC 400000

	MLON
;   THIS MODULE CONTAINS THE FOLLOWING ROUTINES:
;
;
;   .RINIT	".RINIT" WILL INITIALIZE THE READ MODULE AND WRITE MODULE.
;		".RINIT" WILL SCAN THE COMMAND STRING AND OPEN FILES,
;		INITIALIZE VARIABLES, AND ACQUIRE AND ALLOCATE SPACE
;		FOR TABLES.
;
;   .PINIT	".PINIT" IS CALLED BEFORE EACH ENTRY PROCEDURE TO
;		REINITIALIZE VARIABLES AND REALLOCATE TABLES.  ".PINIT"
;		IS AUTOMATICALLY DONE AS PART OF ".RINIT".
;
;   .RUND	".RUND" PERFORM LEXICAL SCANNING.  ".RUND" WILL "READ UNTIL
;		NEXT DELIMITER" AND THEN SHIFT THE WINDOW.  ".RUND" WILL
;		COMPUTE "LEXEX" AND "COMPNAME".
;
;   .SEARCH	".SEARCH" WILL SEARCH THE SYMBOL TABLE FOR AN IDENTIFIER
;		AND, OPTIONALLY, IF NOT FOUND WILL ENTER THE IDENTIFIER
;		INTO THE TABLE.
;
;   .STADD	".STADD" WILL ADD TO THE SYMBOL TABLE AN ENTRY FOR AN
;		IDENTIFIER WHOSE NAME DUPLICATES THE NAME OF AN EXISTING
;		IDENTIFIER.
;
;   .XTNDLB	".XTNDLB" WILL MAKE THE LAST ENTRY IN THE SYMBOL TABLE AN
;		EXTENDED ENTRY.
;
;   .TOFIX	".TOFIX" WILL ENTER A TYPE-15 FIXUP INTO THE FIXUP TABLE.
;
;   .CON1	".CON1" WILL ENTER A 1-WORD CONSTANT INTO THE CONSTANTS
;		TABLE.
;
;   .CON2	".CON2" WILL ENTER A 2-WORD CONSTANT INTO THE CONSTANTS
;		TABLE.
;
;   .FAILED	".FAILED" WILL ENTER AN ERROR MESSAGE INTO THE MESSAGE TABLE
;		TO BE INCLUDED IN THE LISTING.
;   .BLK1	".BLK1" IS CALLED AT THE BEGINNING OF A BLOCK TO ENTER INTO
;		THE LISTING THE MESSAGE "START OF BLOCK N".
;
;   .BLK2	".BLK2" IS CALLED AT THE END OF A BLOCK TO ENTER INTO THE
;		LISTING THE MESSAGE "END BLOCK N, CONT M".
;
;   .SCRUND	".SCRUND" WILL COMPUTE "LEXEX" AND "COMPNAME".
;
;   GETCS	"GETCS" WILL READ AND INTERPRET A COMMAND STRING.
;
;   LMSGZ	"LMSGZ" IS CALLED AT THE END OF A COMPILATION TO PRINT
;		THE REMAINING CONTENTS OF THE MESSAGE TABLE.
;
;   .STOVER	".STOVER" WILL HANDLE STACK OVERFLOWS.
;
;   INS		"INS" AND "TCHECK" ARE USED TO INSERT MESSAGES INTO
;   TCHECK	THE LISTING.
;
;   GETSPC	"GETSPC" IS USED TO ACQUIRE SPACE IN THE SYMBOL TABLE.
;
;   HAL		"HAL" WILL COMPUTE THE HASH VALUE AND NAME LENGTH FOR A
;		SYMBOL TABLE ENTRY.
;   TABLE ALLOCATION:

;
; TEMP   SYMBOL            FIXUP CONSTANTS    STACK
; CODE   TABLE             TABLE TABLE
;!      !                       !            !                       !
;!  \   !           \     /     !     \      !                 \     !
;!--->  !------------>   <------!------>     !------------------>    !
;!  /   !           /     \     !     /      !                 /     !
;!      !                       !            !                       !
; T      ST           N N        FC     N     CS                    C
; C      YC           A A        IO     A     OT                    O
; B      MM           S F        XN     C     NA                    R
; A      BA           T T        UT     T     EC                    E
; S      OX           E E        PA     E     NK                    N
; E      L                        B           DB                    D
;
;
;
;
;	TEMPCODE IS A BUFFER THAT RECEIVES PARTIALLY GENERATED CODE FOR
;	EXPRESSIONS. TEMPCODE CAN OVERFLOW IF THE COMPILER ENCOUNTERS
;	A SUPER-LARGE EXPRESSION.  WHEN THIS HAPPENS THE COMPILATION
;	ABORTS.   THE DEFAULT LENGTH OF TEMPCODE IS "TEMPL".  THE ALGOL
;	USER CAN OVER-RIDE THIS WITH THE /T SWITCH.
;
		IFNDEF	TEMPL,<
		TEMPL==400>
;
;
;	THE SYMBOL TABLE HAS ENTRIES FOR ALL IDENTIFIERS ACTIVE IN THE
;	USER'S PROGRAM.  THE FIXUP TABLE CONTAINS THE ACCUMULATED TYPE-15
;	LOADER BLOCK FIX-UPS.  THE SYMBOL TABLE AND FIXUP TABLE GROW
;	TOWARD EACH OTHER. IF THEY SHOULD MEET, CORE WILL BE EXPANDED
;	BY AN AMOUNT "DELTA", THE FIXUP TABLE, CONSTANTS TABLE, AND STACK
;	WILL BE MOVED UPWARD IN CORE BY AN AMOUNT "DELTA", AND THE COMPILATION
;	WILL CONTINUE.  THE COMBINED INITIAL LENGTH OF THE SYMBOL TABLE
;	AND FIXUP TABLE IS "TABLES".
;
		IFNDEF	TABLES,<
		TABLES==400>
;	THE CONSTANTS TABLE CONTAINS WHATEVER SINGLE AND DOUBLE PRECISION
;	FIXED AND FLOATING POINT CONSTANTS THAT CANNOT BE EXPRESSED AS
;	IMMEDIATES, AND ALSO STRINGS.  IF THE CONSTANTS TABLE SHOULD
;	OVERFLOW, CORE WILL BE EXPANDED BY AN AMOUNT "DELTA", THE STACK
;	WILL BE MOVED UPWARD IN CORE BY AN AMOUNT "DELTA", AND THE
;	COMPILATION WILL CONTINUE.  THE INITIAL LENGTH OF THE CONSTANTS
;	TABLE IS "CONL".
;
		IFNDEF	CONL,<
		CONL==30>
;
;
;
;	THE STACK CONTAINS "PUSH" AND "PUSHJ" DATA, AND OTHER BLOCKS OF
;	DATA.  WHEN THE STACK OVERFLOWS, CORE IS EXPANDED BY AN AMOUNT
;	"DELTA".  THE INITIAL LENGTH OF THE STACK IS "STACKL".
;
		IFNDEF	STACKL,<
		STACKL==100>
;
;
;
;	THE UPPER BOUND OF THE STACK IS "COREND". PLEASE NOTE THAT NOTHING
;	CAN GO INTO THE LOW SEGMENT ABOVE "COREND".
;
;
		IFNDEF	DELTA,<
		DELTA==100>
;
;
;
;	ALL BUFFER RINGS ARE COMPOSED OF BUFFERS OF STANDARD SIZE
;	FOR THE PARTICULAR DEVICE.  THE ALGOL USER CAN SELECT THE NUMBER
;	OF BUFFERS IN EACH RING WITH THE /B SWITCH.  THE DEFAULT NUMBER
;	OF BUFFERS IN EACH BUFFER RING IS:
;
		IFNDEF	SBUF,<		; SOURCE
		SBUF==2>

		IFNDEF	LBUF,<		; LISTING
		LBUF==2>

		IFNDEF	OBUF,<		; OBJECT CODE
		OBUF==2>
; 	REGISTER ASSIGNMENTS:

	FL==A0			; FLAGS REGISTER
;	A10-A13			; SAFE OVER READ MODDULE
	A14==14			; SAFE OVER READ MODULE
	DEL==15
	SYM==16
	SP==17			; STACK POINTER (SAFE OVER READ MODULE)

	STOPS==A7
	DBASE==A10


; 	READ MODULE FLAGS -- BIT ASSIGNMENTS (RFLAGS)

	EXISTS==400000		; LISTING FILE EXISTS
	LTTY==200000		; LISTING DEVICE IS A TTY
	CSDONE==100000		; COMMAND STRING SCANNED, COMPILATION STARTED
	SPAREN==40000		; PARENTHETICAL COMMAND STRING SWITCH
	TTY==20000		; SOURCE DEVICE IS A TTY
	ESWIT==10000		; LINE NUMBERS IN COLS 73-80
	NSWIT==4000		; NO ERROR PRINTOUTS ON TTY
	COMPLETE==2000		; 1 = LISTING COMPLETE AND CLOSED
	TMG==1000		; TERMINATION MESSAGE GIVEN
	ELINE==400		; EDITORS LINE NUMBER SCANNED
	BLANKL==200		; BLANK LINE BEING SCANNED
	WITHIN==100		; WITHIN NEWLINE ROUTINE
	ONECHS==40		; 1 CHARACTER SWITCH SCANNED
	STATS==20		;  STATS REQUESTED.
; 	ACCUMULATOR ZERO -- BIT ASSIGNMENTS

; **************************************************
; *                                                *
; *     W A R N I N G    ! ! ! ! ! ! ! ! ! ! !     *
; *                                                *
; *  THIS  M U S T  AGREE WITH GB DEFINITIONS      *
; *           IN FILE ALGMAC !!!                   *
; *                                                *
; **************************************************


	TRLOFF==20000		; DON'T PLANT TRACE INFO ( IMPLIES TRPOFF)
	TRPOFF==10000		; DON'T MAKE SYMBOL BLOCKS
	CREF==4000		; /CREF - PRODUCE O/P FOR CROSS-REF PROGRAM
	ACOFF==2000		; /CHECKOFF - FORCE NO ARRAY-BOUND CHECKS
	ACON==1000		; /CHECKON - FORCE ARRAY-BOUND CHECKS
	OBOO==400		; OBJECT CODE LISTING ON/OFF FLAG
	NOENTR==200		; 1 => MAKE NO NEW ENTRIES IN SYMBOL TABLE
	ACOO==100		; ARRAY-BOUND CHECKING IN FORCE
	LNOO==40		; LINE-NUMBERS ON/OFF FLAG
	LISTOO==20		; LISTON/LISTOFF SWITCH
	DECLAR==10		; DECLARATION MODE
	BPAIR==4		; SCANNING A BOUND PAIR
	ERRF==2			; FATAL ERROR FOUND. NO CODE GENERATED
	ERRL==1			; SCANNING IN ERROR-LABEL


;	OTHER RANDOM BITS

	USE==400000		; BUFFER USE BIT
	EXACT==400000		; USE EXACT POINTER FOR ERROR MSG UP-ARROW
	DEVTTY==10		; DEVCHR TTY BIT


	RWTRT==-1
	RWTLNK==0
	RWTLEN==0
	RWTLEX==1
	RWTNAM==2
	SYMBLK==0
	SYMLNK==0
	SYMTYP==1
	SYMNAM==2
	.FAILE=FAILED
	INTERN	.PINIT
	INTERN	.BLK1
	INTERN	.BLK2
	INTERN	.FAILE
	.LSCAN=LSCAN
	INTERN	.LSCAN
	.RINIT=RINIT
	INTERN	.RINIT
	.SEARCH=SEARCH
	INTERN	.SEARCH
	.STADD=STADD
	INTERN	.STADD
	.GETSPC=GETSPC
	INTERN	.GETSPC
	.RUND=RUND
	INTERN	.RUND
	.XTNDL=XTNDLB
	INTERN	.XTNDL
	.HAL=HAL
	INTERN	.HAL
	.CON1=CON1
	INTERN	.CON1
	.CON2=CON2
	INTERN	.CON2
	INTERN	.SCRUND
	INTERN	.TOFIX
	INTERN	.STOVE
	INTERN	COREB
	INTERN	CSBLK
	INTERN	CHKSUM
	INTERN	CCLSW
	INTERN	PRNAME
	INTERN	OFILE

	EXTERN	.JBERR
	EXTERN	.HELPR
	EXTERN	.JBREL
	EXTERN	.FAIL
	EXTERN	.JBAPR
	EXTERN	.JBTPC
	EXTERN	.JBFF
	EXTERN	.JBDDT
	BLKLEV=BLOCKL
	..HARD==60
	..SOFT==0
	..FRIED==1040
	..IUO==1140
	..FATAL==200
	..FVARY==400
	..SYM==10
	..DEL==4
	..NSYM==2
	..NDEL==1
	..IMM==20000
	..IUO2==100
	SUSPCO==40



	RELOC 0

	DEFINE	FAIL(NNN,ARG1,ARG2,TEXT)
	<
	PUSHJ	SP,FAILX
	XWD	<<..'ARG1+..'ARG2>&<777777>>,^D'NNN
	>




FAILX:	BLOCK	5		; INITIALISED FROM HISEG AT START1.

;	PUSH	SP,A1		; SAVE A1
;	PUSH	SP,A2		; SAVE A2
;	MOVE	A1,@-2(SP)	; GET PARAM
;	MOVEM	A1,FAILX1	; SAVE IT
;	PUSHJ	SP,.FAIL	; CALL FAIL ROUTINE

FAILX1:	BLOCK	5
;	XWD	0,0		; PARAM WILL BE PUT HERE
;	POP	SP,A2		; RESTORE A2
;	POP	SP,A1		; RESTORE A1
;	AOS	(SP)		; SKIP RETURN
;	POPJ	SP,		; EXIT FAILX

	RELOC


	$IMM==1			; CONSTANT, SIMPLE
	$CT==3			; CONSTANT, REGULAR
	$ST==7			; VARIABLE, SIMPLE
	$SYMB==4		; THIS BIT ON IMPLIES A SIMPLE VARIABLE
;    FORMAT OF A RESERVED WORD TABLE ENTRY
;
;	EACH ENTRY IN THIS TABLE IS LINKED INTO ONE OF 26 SUB-LISTS (ONE
;	FOR EACH LETTER OF THE ALPHABET) WHOSE HEADS CAN BE FOUND USING
;	THE "RESERVED WORD HASH TABLE".  WHICH SUB-LIST THAT AN ENTRY IS LOCATED
;	ON DEPENDS UPON THE FIRST LETTER OF THE NAME OF THE DELIMITER WORD.
;
;	ALL ENTRIES IN THE TABLE THAT ARE LOCATED BEFORE THE ADDRESS "FRW"
;	ARE CONSIDERED FLAGGED, AND THE WORD PRECEDING THESE ENTRIES MUST
;	CONTAIN THE ADDRESS OF A ROUTINE THAT WILL PERFORM THE SPECIAL
;	PROCESSING FOR THAT DELIMITER WORD.  OTHER THAN THIS, NEITHER THE
;	POSITION OF A DELIMITER WORD IN THE TABLE NOR ITS POSITION ON A
;	DELIMITERS ON A SUB-LIST SHOULD BE ARRANGED IN ORDER OF FREQUENCY
;	OF USAGE.
;
;	THE RIGHT HALF OF THE FIRST WORD OF AN ENTRY CONTAINS THE SUB-LIST
;	LINK.  THE LEFT HALF CONTAINS EITHER A 0 OR A -1, DEPENDING ON WHETHER
;	THE DELIMITER NAME WILL TAKE UP 1 WORD OR 2, RESPECTIVELY.  THE SECOND
;	WORD OF THE ENTRY CONTAINS THE COMPLETE LEXEME FOR THE DELIMITER.
;	THE THIRD AND FOURTH WORDS OF THE ENTRY CONTAIN THE NAME OF THE
;	DELIMITER.  THERE IS NO FOURTH WORD IF THE NAME IS ONLY 1 WORD LONG
;	(5 CHARACTERS OR LESS).


	DEFINE	N1(NAM,LN)
	<
					<373737373737>&<LN-1+SIXBIT/NAM/>
	>

	DEFINE	N2(NAM)
	<
					<373737373737>&<SIXBIT/NAM/>
	>
	DEFINE LEX(ROOT)
	<
	INTERN	Z'ROOT
	EXTERN	L$'ROOT,R$'ROOT
Z'ROOT:	XWD	L$'ROOT,R$'ROOT>

;	***  RESERVED WORD TABLE  ***

	FBEGIN
FB:	FB1		; BEGIN
	LEX(BEGIN)
	N1(NIGEB,5)

	FEND
FE:	FE1		; END
	LEX(END)
	N1(DNE,3)

	FFALSE
FF1:	FF2		; FALSE
	0
	N1(ESLAF,5)

	FGO
FG1:	0		; GO
	LEX(GOTO)
	N1(OG,2)

	COMNT2
FC:	XWD	-1,FC1	; COMMENT
	0
	N1(EMMOC,7)
	N2(TN)

	FTRUE
FT1:	0		; TRUE
	0
	N1(EURT,4)
FRW:	;  ALL PRECEDING RESERVED WORDS ARE FLAGGED.

FA:
	.+3		; ARRAY
	LEX(ARRAY)
	N1(YARRA,5)

	0		; AND
	LEX(AND)
	N1(DNA,3)

FB1:
	XWD	-1,0	; BOOLEAN
	LEX(BOOLEAN)
	N1(ELOOB,7)
	N2(NA)


FC1:
	XWD	-1,.+4	; COMPLEX
	LEX(COMPLEX)
	N1(LPMOC,7)
	N2(XE)


	XWD	-1,.+4	; CHECKON
	LEX(CON)
	N1(KCEHC,7)
	N2(NO)

	XWD	-1,0	; CHECKOFF
	LEX(COFF)
	N1(KCEHC,8)
	N2(FFO)

FD:
	.+3		; DO
	LEX(DO)
	N1(OD,2)

	0		; DIV
	LEX(DIV)
	N1(VID,3)
FE1:
	.+3		; ELSE
	LEX(ELSE)
	N1(ESLE,4)

	XWD	-1,.+4	; EXTERNAL
	LEX(EXTERNAL)
	N1(RETXE,8)
	N2(LAN)

	0		; EQV
	LEX(EQV)
	N1(VQE,3)

FF:
	FF1		; FOR
	LEX(FOR)
	N1(ROF,3)

FF2:
	XWD	-1,0	; FORWARD
	LEX(FORWARD)
	N1(AWROF,7)
	N2(DR)

FG:
	FG1		; GOTO
	XWD	L$GOTO,R$GOTO
	N1(OTOG,4)

FI:
	.+3		; IF
	LEX(IF)
	N1(FI,2)

	XWD	-1,.+4	; INTEGER
	LEX(INTEGER)
	N1(GETNI,7)
	N2(RE)

	0		; IMP
	LEX(IMP)
	N1(PMI,3)
FLL:
	.+3		; LABEL
	LEX(LABEL)
	N1(LEBAL,5)

	.+3		; LONG
	LEX(LONG)
	N1(GNOL,4)


	XWD	-1,.+4	; LISTON
	LEX(LON)
	N1(OTSIL,6)
	N2(N)

	XWD	-1,.+4	; LISTOFF
	LEX(LOFF)
	N1(OTSIL,7)
	N2(FF)

	0		; LINE
	LEX(LINE)
	N1(ENIL,4)

FN:
	0		; NOT
	LEX(NOT)
	N1(TON,3)

FO:
	.+3		; OWN
	LEX(OWN)
	N1(NWO,3)

	0		; OR
	LEX(OR)
	N1(RO,2)

FP:
	XWD	-1,0	; PROCEDURE
	LEX(PROCEDURE)
	N1(ECORP,9)
	N2(ERUD)
FR:
	.+3		; REAL
	LEX(REAL)
	N1(LAER,4)

	0		; REM
	LEX(REM)
	N1(MER,3)


FS:
	.+3		; STEP
	LEX(STEP)
	N1(PETS,4)

	XWD	-1,.+4	; STRING
	LEX(STRING)
	N1(NIRTS,6)
	N2(G)

	XWD	-1,0	; SWITCH
	LEX(SWITCH)
	N1(CTIWS,6)
	N2(H)

FT:
	FT1		; THEN
	LEX(THEN)
	N1(NEHT,4)

FU:
	0		; UNTIL
	LEX(UNTIL)
	N1(LITNU,5)

FV:
	0		; VALUE
	LEX(VALUE)
	N1(EULAV,5)

FW:
	0		; WHILE
	LEX(WHILE)
	N1(ELIHW,5)
;	** RESERVED WORD HASH TABLE **

RESWRD:	FA
	FB
	FC
	FD
	FE
	FF
	FG
	0
	FI
	0
	0
	FLL
	0
	FN
	FO
	FP
	0
	FR
	FS
	FT
	FU
	FV
	FW
	0
	0
	0
;   SPECIAL CHARACTERS

	.TAB==11
	.LF==12
	.VT==13
	.FF==14
	.CR==15
	.CZ==32
	.ALT1==33
	.CLEFT==37
	.SPACE==" "
	.EXCL=="!"
	.DQUOT==""""
	.$=="$"
	.%=="%"
	.AMPER=="&"
	.LPAREN=="("
	.RPAREN==")"
	.STAR=="*"
	.PLUS=="+"
	.COMMA==","
	.MINUS=="-"
	.DOT=="."
	.SLASH=="/"
	.N0=="0"
	.N7=="7"
	.N9=="9"
	.COLON==":"
	.SEMI==";"
	.EQUAL=="="
	.QUESTION=="?"
	.AAAAA=="@"
	.A=="A"
	.B=="B"
	.E=="E"
	.I=="I"
	.O=="O"
	.T=="T"
	.Z=="Z"
	.LBRAC=="["
	.RBRAC=="]"
	.UP=="^"
	.LEFT=="_"
	.ALT2==175
	.ALT3==176

	.CRF==SIXBIT/   CRF/
	.LST==SIXBIT/   LST/
	.REL==SIXBIT/   REL/
	.ALG==SIXBIT/   ALG/
	.DSK==SIXBIT/   DSK/
	.TMP==SIXBIT/   TMP/
SUBTTL ** RINIT **

;	READ MODULE INITIALIZATION ROUTINE

RINIT:	MOVEM	A1,LINK		; SAVE RETURN LINK
	CLOSE	3,0		; CLOSE SOURCE FILE, IF OPEN
	CLOSE 	5,0		; CLOSE COMMAND STRING FILE, IF OPEN
	MOVE	SP,[		; LOAD A STACK POINTER
	XWD	-46,TMPBUF]	; TEMPORARILY USE TMPBUF AS A STACK

; IF THIS IS NOT THE 1ST CALL TO ".RINIT" THEN THE LISTING FROM
; THE PREVIOUS COMPILATION MIGHT NOT YET BE COMPLETE, AND ALSO
; THE REL-FILE MIGHT NOT YET BE CLOSED NOR DELETED IF IT IS TO
; BE DELETED.

	MOVE	A7,RFLAGS	; GET OLD READ MODULE FLAGS
	MOVE	A4,COREB	; GET OLD VALUE OF CORE
	XORI	A4,RANDOM	; CODE IT
	CAME	A4,CHKSUM	; IF VALUE OF CORE NOT VALID
	JRST	START1		; THEN SKIP THIS PART
	SKIPL	WFLAG		; UNLESS REL-FILE IS TO BE DELETED
	JRST	START0		; SKIP OVER THIS PART

	; DELETE REL-FILE

	SKIPE	OFILE		; IF THERE IS NO REL FILE
	CLOSE	1,40		; DON'T SUPERSEDE
	SETZM	WFLAG		; CLEAR THE WRITE MODULE FLAG

	; COMPLETE THE LISTING

START0:;	TLNE	A7,COMPLETE	; IF PREVIOUS RUN'S LISTING IS COMPLETE
	;	JRST	START		; THEN SKIP THIS PART
	PUSHJ	SP,CREFNL	; CLOSE OFF ANY CREF INFO
	MOVEI	A1,NLCHRS	; PUT A BLANK LINE IN LISTING
	PUSHJ	SP,INSERT
	SKIPN	A1,.JBERR	; IF THERE ARE NO ERRORS
	SKIPA	A1,[[ASCIZ/No/]]; THEN SAY SO
	PUSHJ	SP,LPRINT	; CONVERT TO DECIMAL ASCII
	PUSHJ	SP,DONE1	; INCLUDE IT IN LISTING
	MOVE	A1,.JBERR
	CAIN	A1,1		; DON'T USE SOJG - DONE1 NEEDS .JBERR
	SKIPA	A1,[[ASCIZ/ error
/]]
	MOVEI	A1,ERRORM	; " ERRORS"
	PUSHJ	SP,DONE1	; INCLUDE IN LISTING
	SKIPN	A1,WRNCNT	;[171] IF THERE ARE NO WARNINGS,
	 SKIPA	A1,[[ASCIZ /No/]] ;[171] THEN SAY SO
	  PUSHJ	SP,LPRINT	;[171] OR ELSE CONVERT NUMBER TO DECIMAL ASCII
	PUSHJ	SP,DONE1	;[171] AND INCLUDE IT IN LISTING
	MOVE	A1,WRNCNT	;[171] GET WARNING COUNT
	CAIN	A1,1		;[171] IF IT IS 1, USE THE SINGULAR
	 SKIPA	A1,[[ASCIZ / warning
/]]				;[171] ...
	  MOVEI	A1,[ASCIZ / warnings
/]				;[171] IF NOT, USE THE PLURAL
	PUSHJ	SP,DONE1	;[171] AND INCLUDE IT IN LISTING
	IFN FTSTATS,<
	TLNN	A7,STATS	;  STATS ?
	JRST	START3		;  NO
	MOVEI	A1,[ASCIZ/
Number of identifiers = /]	; 
	PUSHJ	SP,DONE2	; 
	MOVE	A1,DEFCNT	; 
	PUSHJ	SP,LPRINT	; 
	PUSHJ	SP,DONE2	; 
	MOVEI	A1,[ASCIZ/
Average characters in each = /]	; 
	PUSHJ	SP,DONE2	; 
	MOVE	A1,IDCHRS	; 
	IDIV	A1,DEFCNT	; 
	ADDI	A1,1		; 
	PUSHJ	SP,LPRINT	; 
	PUSHJ	SP,DONE2	; 
	MOVEI	A1,[ASCIZ/
Number of identifier references = /] ; 
	PUSHJ	SP,DONE2	; 
	MOVE	A1,REFCNT	; 
	PUSHJ	SP,LPRINT	; 
	PUSHJ	SP,DONE2	; 
	MOVEI	A1,NLCHRS	; 
	PUSHJ	SP,DONE2	; 

START3:	>
	MOVEI	A1,LINES3	; PUT 3 BLANK LINES
	PUSHJ	SP,INSERT	; IN LISTING
	TLNE	A7,EXISTS	; IF LISTING EXISTS,
	PUSHJ	SP,WRITEL	; WRITE OUT THIS BUFFER
START:	CLOSE	1,0		; CLOSE REL-FILE
	CLOSE	2,0		; CLOSE LISTING
	JRST	START1+1	; SKIP NEXT INSTRUCTION

START1:	SETOM	CSCOMP		; MARK COMMAND STRING TO BE READ
	SKIPN	.JBDDT		; UNLESS DDT IS LOADED...
	RESET			; RESET IO
	MOVE	A4,.JBFF	; ADD ADDRESS OF FREE CORE
	XORI	A4,RANDOM	; HASH IT
	MOVEM	A4,CHKSUM	; SET CHECK SUM
	HRRZ	A5,.JBFF	; GET START OF FREE CORE
	MOVEM	A5,COREB	; SET BASE OF CORE

	; ***  BEGIN THE CURRENT COMPILATION  ***

	IFE	FTSYM,<
	MOVEI	FL,TRPOFF	; DEFAULT TO NO SYMBOLS (TYPE 1044 BLOCKS)
	>
	IFN	FTSYM,<
	SETZ	FL,		; CLEAR FLAG REGISTER>
	MOVE	A7,IFLAGS	; GET A NEW SET OF FLAGS
	SETZB	A5,DYNOWN	; CLEAR OUR PROCESSOR TO KA, AND INITIAL HEAP SIZE
	MOVEI	A4,TEMPL	; DEFAULT LENGTH OF TEMPCODE
	MOVEM	A4,LTCODE	; SET LENGTH OF TEMPCODE
	MOVEI	A1,RLIST	; READ MODULE INIT LIST
	PUSHJ	SP,BMOVE	; INITIALIZE READ MODULE FROM HIGH SEG
	MOVEI	A4,600000	; SET PROCESSOR TO TRAP ON
	APRENB	A4,		; A PUSHDOWN OVERFLOW
	SKIPA	A4,.+1		; SET THE RESERVED WORD TABLE POINTER
	XWD	A1,RESWRD-.A	; TO THE ACTUAL RESERVED WORD TABLE
	MOVEM	A4,RWS		; SET IT
	SKIPE	.JBDDT		; SPECIAL MESSAGE IF
	SKIPE	CCLSW		; NOT CCL-MODE AND
	JRST	START2
	OUTSTR	DDTMSG	; DDT HAS BEEN LOADED

	; PROCESS COMMAND STRING

START2:	MOVEI	A4,OBUF		; DEFAULT NUMBER OF OBJECT BUFFERS
	MOVEM	A4,OLIST+7	; SET IT
	MOVEI	A4,LBUF		; DEFAULT NUMBER OF LISTING BUFFERS
	MOVEM	A4,LLIST+7	; SET IT
	MOVEI	A4,SBUF		; DEFAULT NUMBER OF SOURCE BUFFERS
	MOVEM	A4,SLIST+7	; SET IT
	SKIPN	CSCOMP		; IF PREVIOUS COMMAND STRING NOT EMPTY
	JRST	.+4		; THEN DONT READ ANOTHER
	SKIPGE	CCLSW		; IF CCLSW = -1
	JRST	QUIT		; THEN NOTHING MORE TO COMPILE
	PUSHJ	SP,GETCS	; READ IN THE COMMAND STRING
	; SCAN OBJECT CODE FILE NAME

	MOVEI	A4,.REL		; EXTENSION NAME DEFAULT
	MOVSM	A4,OFILE+1	; SET DEFAULT
	MOVEI	A1,OLIST	; OBJECT CODE PARAM LIST
	PUSHJ	SP,SCAN2	; SCAN NAME

	; SCAN LISTING FILE NAME

	MOVEI	A4,.DSK		; LISTING DEVICE DEFAULT
	MOVSM	A4,LLIST+1	; SET IT
EDIT(042); DONT USE OLD LISTING FILE NAME AGAIN
	SETZM	LFILE		; [E042] CLEAR LISTING FILE NAME
	CAIE	A6,.LEFT	; _?
	CAIN	A6,.EQUAL	; OR =?
	JRST	CS1		; -YES, NEXT SCAN SOURCE FILES
	CAIE	A6,.COMMA	; IF TERMINATING CHAR NOT A COMMA
	JRST	CSER		; THEN COMMAND STRING ERROR
	MOVEI	A4,777777	; EXTENSION NAME DEFAULT - GARBAGE
	MOVSM	A4,LFILE+1	; SET DEFAULT VALUE
	MOVEI	A1,LLIST	; LISTING PARAM LIST
	PUSHJ	SP,SCAN2	; SCAN NAME
	CAIN	A6,.LEFT	; _?
	JRST	CS1		; YES
	CAIE	A6,.EQUAL	; =?
	JRST	CSER		; NO - COMMAND STRING ERROR

	; SCAN SOURCE FILE NAME

CS1:	TRO	FL,LISTOO	; TURN LISTING ON
	PUSHJ	SP,SCAN3	; SCAN 1ST SOURCE FILE AND OPEN IT	
	JRST	CS5		; CONTINUE
	; SCAN SOURCE FILE NAME AND OPEN IT. DEV:FILE.EXT[123,456]/A/B

SCAN3:	MOVEI	A4,.ALG		; EXTENSION NAME DEFAULT
	MOVSM	A4,SFILE+1	; SET DEFAULT
	MOVEI	A1,SLIST	; SOURCE PARAM LIST
	PUSHJ	SP,SCAN2	; SCAN NAME
	CAIE	A6,.COMMA	; IF THE LAST CHAR IS NOT A COMMA
	JRST	CS12		; THEN SKIP THIS PART
	AOS	CSCOMP		; MARK: LINE NOT COMPLETELY SCANNED
	JRST	CS14		; CONTINUE

CS12:	CAIE	A6,.CR		; IF IT IS NOT A CR
	JRST	CS13		; THEN SKIP THIS PART
	PUSHJ	SP,SCANCH	; STEP OVER THE LINE FEED
	PUSHJ	SP,SCANCH	; READ THE NEXT CHAR
	JRST	CS12		; TRY AGAIN


CS13:	CAIG	A6,0		; IF IT IS A NULL OR OTHER TERMINATOR
	SETOM	CSCOMP		; THEN MARK: END OF COMMAND STRING
	HRLZI	A4,070000	; BYTE POINTER BACK-UP CONSTANT
	ADDM	A4,CSP		; BACK UP THE COMMAND STRING POINTER

CS14:	TLZ	A7,TTY		; CLEAR TTY FLAG
	MOVE	A5,SLIST+1	; GET SOURCE DEVICE NAME
	DEVCHR	A5,		; WHAT IS DEVICE?
	TLNE	A5,DEVTTY	; IS IT A TTY?
	TLO	A7,TTY		; YES - SET FLAG BIT

	; OPEN SOURCE DEVICE

	OPEN	3,SLIST		; OPEN SOURCE DEVICE
	JRST	DSERR1		; -SOMETHING WRONG
	TLNE	A7,CSDONE	; UNLESS THIS IS THE 1ST SOURCE FILE IN
	JRST	CS11		; THE COMMAND STRING, SKIP THIS PART
	; ESTABLISH SOURCE BUFFER RING

	MOVE	A5,SLIST+7	; GET NUMBER OF BUFFERS
	MOVEI	A1,(A5)		; COPY TO A1
	IMULI	A1,204		; EACH BUFFER TAKES UP 204 WORDS
	PUSHJ	SP,ALLOCATE	; GET SPACE FOR THESE BUFFERS
	ADD	A1,[		; SET REGISTER A1 TO LOOK LIKE
	XWD	202,1]		; A BUFFER LINK WORD
	HRRZM	A1,OLDSBR	; SAVE ADDRESS OF SOURCE BUFFER RING
	JRST	.+3		; JUMP INTO LOOP

	MOVEM	A1,204(A1)	; SET NEXT BUFFER TO POINT TO THIS BUFFER
	ADDI	A1,204		; STEP TO NEXT BUFFER
	SOJG	A5,.-2		; LOOP
	MOVEM	A1,@OLDSBR	; SET LINK WORD OF 1ST BUFFER


CS11:	MOVE	A4,OLDSBR	; GET OLD SOURCE BUFFER RING
	HRLI	A4,400000	; TURN ON USE BIT
	MOVEM	A4,BHEAD3	; USE FOR THE CURRENT FILE ALSO
	HRLI	A4,000700	; S-P BITS
	MOVEM	A4,BHEAD3+1	; SET UP BYTE POINTER

	; FIND SOURCE FILE

CS9:	LOOKUP	3,SFILE		; SELECT SOURCE FILE
	JRST	DSERR2		; FILE DOESNT EXIST
	POPJ	SP,		; EXIT SCAN3
SUBTTL	**  COMMAND STRING ROUTINES  **

	; SCAN A FILE NAME ELEMENT (DEV, FILE, OR EXT)

SCAN1:	SETZ	A3,0		; CLEAR A3
	SKIPA	A2,.+1
	POINT	6,A3		; SET UP OUTPUT POINTER

CS8:	PUSHJ	SP,SCANCH	; GET NEXT CHAR
	SKIPL	CTABLE(A6)	; IF NOT LETTER OR DIGIT
	POPJ	SP,		; THEN EXIT
	SUBI	A6,40		; ELSE CONVERT TO SIXBIT
	TLNE	A2,770000	; MORE THAN SIX CHARS?
	IDPB	A6,A2		; DEPOSIT CHAR
	JRST	CS8		; YES - IGNORE
	; SCAN A FILE NAME OF THE FORM  DEV:FILE.EXT[123,456]/A/B

SCAN2:	MOVEI	A4,.DSK		; "DSK"
	MOVSM	A4,1(A1)	; SET DEFAULT VALUE
	SETZM	5(A1)		; CLEAR TIME/DATE
	SETZM	6(A1)		; CLEAR PPN
	PUSHJ	SP,SCAN1	; SCAN 1ST STRING
	CAIE	A6,.COLON	; ENDS IN COLON?
	JRST	CS2		; -NO, MUST BE A FILE NAME
	MOVEM	A3,1(A1)	; SET DEVICE NAME
	PUSHJ	SP,SCAN1	; SCAN NEXT STRING

CS2:	MOVEM	A3,3(A1)	; SET FILENAME
	CAIE	A6,.DOT		; ENDS IN DOT?
	JRST	CS10		; -NO
	PUSHJ	SP,SCAN1	; -YES, SCAN EXTENSION NAME
	HLLZM	A3,4(A1)	; SAVE EXTENSION NAME

CS10:	CAIN	A6,.EXCL	; IF EXCLAMATION MARK FOUND
	JRST	RUNUUO		; THEN TRANSFER TO NEXT CUSP
	CAIE	A6,.LBRAC	; IF IT IS NOT A "["
	JRST	SWITCH		; EXIT VIA SWITCH

	; SCAN PROJECT/PROGRAMMER NUMBERS

	PUSHJ	SP,SCAN4	; SCAN 1ST NUMBER
	CAIE	A6,.COMMA	; IT IS AN ERROR IF THIS
	JRST	CSER		; CHAR IS NOT A COMMA
	HRLZM	A5,6(A1)	; SAVE PROJECT NUMBER
	PUSHJ	SP,SCAN4	; SCAN 2ND NUMBER
	CAIE	A6,.RBRAC	; IF IT'S A ]
	CAIN	A6,.CR		;
	SKIPA			;
	JRST	CSER		;
	HRRM	A5,6(A1)	; SAVE PROGRAMMER NUMBER
EDIT(022); MAKE SWITCHES AFTER PPN'S WORK.
	PUSHJ	SP,SCANCH	; [E022] READ NEXT CHAR.
	JRST	SWITCH		; [E022] PROCESS SWITCHES, EXIT SCAN2.




	; SUBROUTINE TO SCAN PROJECT NUMBER OR PROGRAMMER NUMBER

SCAN4:	MOVEI	A5,0		; CLEAR A5
	PUSHJ	SP,SCANCH	; GET NEXT CHAR
	CAIL	A6,.N0		; IF IT IS BELOW "0"
	CAILE	A6,.N7		; OR ABOVE "7"
	POPJ	SP,		; THEN EXIT SCAN4
	LSH	A5,3		; MULTIPLY BY 8
	ADDI	A5,-.N0(A6)	; AND ADD IN CURRENT DIGIT
	JRST	SCAN4+1		; LOOP
	; CHECK FOR, AND PROCESS, A COMMAND SWITCH

SWITCH:	CAIN	A6,.SLASH	; SWITCH ?
	JRST	SW13		; YES
	CAIE	A6,.LPAREN	; START OF COMPIL SWITCH-STRING ?
	POPJ	SP,		;  NO.
	TLO	A7,SPAREN	; YES - REMEMBER
SW13:	MOVEI	A4,6
	SETZM	SWIT
	SKIPA	A5,.+1		;
	POINT	6,SWIT		;

SW1:	PUSHJ	SP,SCANCH	; GET A CHARACTER
	SKIPL	CTABLE(A6)	; LETTER ?
	JRST	SW2		; NO
	ADDI	A6,40		; YES - TO SIXBIT
	IDPB	A6,A5
	SOJG	A4,SW1		; GET UP TO 6
	MOVE	A5,SWIT		; GET SWITCH
	CAMN	A5,[SIXBIT/CHECKO/]  ; /CHECKON OR /CHECKOFF !
	JRST	SW3		; YES
	PUSHJ	SP,SCANCH
	SKIPGE	CTABLE(A6)	; SKIP REMAINING
	JRST	.-2		;  LETTERS

SW2:	MOVEM	A6,SWDEL	; SAVE DELIMITER CHARACTER
	CAIN	A4,6
	JRST	SE1		; ERROR - NOTHING THERE !
	CAIN	A4,5		; 1 CHAR SW ?
	TLOA	A7,ONECHS	; YES - REMEMBER
	TLZ	A7,ONECHS	; ELSE REMEMBER NOT
	IMULI	A4,6
	SETO	A6,
	LSH	A6,-^D36(A4)	; MAKE MASK
	MOVEM	A6,SWMASK
	HRLZI	A6,-SWTABN
	SETZ	A4,

SW4:	MOVE	A5,SWTAB(A6)	; GET AN ENTRY FROM SWITCH-TABLE
	ANDCM	A5,SWMASK	; MASK IT
	CAMN	A5,SWIT		; WHAT HE TYPED ?
	JRST	SW5		; YES

SW9:	AOBJN	A6,SW4		; NO - GET NEXT ENTRY
	JUMPE	A4,SE2		; RECOGNIZED - ERROR IF NOT

SW11:	SETZ	A5,
	MOVE	A6,SWDEL	; RESTORE DELIMITER
	TLNE	A4,SWNYET	; "NOT IMPLEMENTED YET" ?
	JRST	NOTIMP		; YES - TELL HIM
	TLNN	A4,VALSW	; VALUE WANTED ?
	JRST	SW12		; NO
	CAIN	A6,.COLON	; YES - DELIMITER = COLON ?
	JRST	SW14		; YES - OK
	TLNN	A4,SWVOPT-VALSW	; NO - OPTIONAL ?
	JRST	SE3		; NO - COMPLAIN
	JRST	SW6		; YES - OK (VALUE = 0)
SW14:	JFCL	17,.+1		; CLEAR OVERFLOW FLAG

SW7:	PUSHJ	SP,SCANCH	; GET DIGIT
	CAIL	A6,.N0		; IS
	CAILE	A6,.N9		;  IT ?
	JRST	SW6A		; NO - END OF VALUE
	IMULI	A5,^D10		; YES - ADD IT IN
	ADDI	A5,-.N0(A6)
	JOV	SE4		; TOO BIG !
	JRST	SW7

SW12:	CAIN	A6,.COLON	; NO VALUE WANTED - DID HE GIVE ONE ?
	JRST	SE6		; YES - COMPLAIN
	JRST	SW6		; NO - GOOD.

SW6A:	CAIN	A6,"K"		; nK OR
	IMULI	A5,^D1024
	CAIN	A6,"P"		;  nP ?
	IMULI	A5,^D512
	JOV	SE4		; TOO BIG.
	CAIE	A6,"K"
	CAIN	A6,"P"	;  & GET NEXT CHAR
	PUSHJ	SP,SCANCH

SW6:	; HERE, A5 = VALUE, OR 0
	;	A6 = DELIMITER (OF SWITCH OR VALUE)
	;       A4 = DISPATCH TABLE ENTRY
	TLNN	A4,SETVAL	; SET VALUE TYPE ?
	JRST	SW10		; NO
	MOVEM	A5,@A4		; YES - SET IT !!MUST BE @, NOT ()!!
	JRST	SWEND		; GET NEXT SWITCH

SW10:	TLNE	A4,XCTSW	; EXCECUTE INSTRUCTION TYPE ?
	XCT	@A4		; YES - DO IT
	TLNN	A4,XCTSW	; ELSE
	PUSHJ	SP,@A4		;  JUMP TO ROUTINE
	JRST	SWEND		; DONE - GET NEXT SWITCH

SW3:	; CHECKO SCANNED - IS IT -N OR -FF ?
	PUSHJ	SP,SCANCH	; GET 7TH CHARACTER
	CAIN	A6,"N"		; CHECKON ?
	TRO	FL,ACON!ACOO	; YES - REMEMBER
	CAIN	A6,"F"		; CHECKOFF ?
	TRO	FL,ACOFF
	TRNN	FL,ACON!ACOFF	; IF NEITHER FLAG WAS SET
	JRST	SE2		;  IT'S UNRECOGNIZED
	PUSHJ	SP,SCANCH	; GOBBLE
	SKIPGE	CTABLE(A6)	;  REMAINING
	JRST	.-2		;   LETTERS
	JRST	SWEND		; DO NEXT SWITCH

SW5:	SKIPGE	SWDTAB(A6)	; 1 CHAR FLAG ?
	TLNN	A7,ONECHS	; YES - ONLY 1 CHAR TYPED ?
	JRST	SW8		; NO
	MOVE	A4,SWDTAB(A6)	; YES - GET ENTRY
	JRST	SW11		; AND DISPATCH

SW8:	JUMPN	A4,SE5		; UNIQUE ? - ERROR IF NOT
	MOVE	A4,SWDTAB(A6)	; YES - GET ENTRY
	JRST	SW9		; AND GO ON LOOKING
SE1:	OUTSTR	[ASCIZ/
? Non-alpha switch
/]
	JRST	CSER+1

SE2:	OUTSTR	[ASCIZ/
? Unrecognized/]
	JRST	SE9

SE3:	OUTSTR	[ASCIZ/
? No value for/]
	JRST	SE9

SE4:	OUTSTR	[ASCIZ/
? Value too large for/]
	JRST	SE9

SE5:	OUTSTR	[ASCIZ/
? Non-unique/]
	JRST	SE9

SE6:	OUTSTR	[ASCIZ/
? No value allowed for/]
	JRST	SE9

NOTIMP:	OUTSTR	[ASCIZ/
? Unimplemented/]

SE9:	SKIPA	A5,.+1		;
	POINT	6,SWIT		;
	SKIPA	A6,.+1		;
	POINT	7,SWERR+2	;
	ILDB	A4,A5		; MOVE SWITCH TO TYPE-BUFFER
	JUMPE	A4,.+4		; NULL - END ?
	ADDI	A4,40		; TO ASCII
	IDPB	A4,A6
	JRST	.-4		; GO ON
	IDPB	A4,A6		; DEPOSIT THE NULL (AS ASCIZ TERMINATOR)
	OUTSTR	SWERR
	OUTSTR	[ASCIZ/
/]
	SETZM	SWERR+2		; CLEAR BUFFER
	SETZM	SWERR+3
	JRST	CSER+1

SWEND:	TLNN	A7,SPAREN	; IN A COMPIL SWITCH-STRING ?
	JRST	SWITCH		; NO
	CAIN	A6,.RPAREN	; CORRECT TERMINATOR ?
	PUSHJ	SP,SCANCH	; YES - GOBBLE IT
	JRST	SWITCH
;	SWITCH TABLES
;
; EACH SWITCH HAS A V-MACRO IN THE DEFINITION OF THE SWS-MACRO.
;
; FORMAT OF THE V-MACRO ENTRY:
;
;	V	NAME,*,ACTIONS,ADDRESS-OR-INSTRUCTION
;
; WHERE:
;
;	NAME	IS THE SWITCH-NAME (ALPHA) - ONLY
;		THE FIRST 6 ARE USED.
;
;	*	MEANS THIS SWITCH WILL BE RECOGNIZED IN PREFERENCE TO OTHERS
;		BEGINNING WITH THE SAME LETTER, IF ONLY 1 CHARACTER IS
;		TYPED (E.G. /H MEANS /HELP, NOT /HEAP)
;
;	ACTIONS	IS A BIT-MASK, AS FOLLOWS:
;
;		VALSW	A VALUE (/SW:VALUE) IS EXPECTED
;		SETVAL	A VALUE IS TO BE SET INTO THE ADDRESS SPECIFIED BY
;			THE FOURTH PARAMETER (0 IF NOT VALSW)
;		XCTSW	AN INSTRUCTION, SUPPLIED AS THE FOURTH PARAMETER, IS
;			TO BE OBEYED.
;		SWVOPT	THE VALUE IS OPTIONAL (IMPLIES VALSW)
;		SWNYET	NOT-YET-IMPLEMENTED: TYPE MESSAGE & GO TO ERROR
;
;	ADDRESS-OR-INSTRUCTION
;		IS THE ADDRESS OF THE ROUTINE TO OBEY, OR
;		IS THE ADDRESS TO SET A VALUE TO (SETVAL), OR
;		IS THE INSTRUCTION TO OBEY (XCTSW).
;
;

	DEFINE	SWS,<
;;	V	NAME,*,ACTIONS,ADDRESS
	V	SYMBOLS,,XCTSW,<TRZ FL,TRPOFF>	; PRODUCE DEBUGGER SYMBOLS (TYPE 1044 BLOCKS)
	V	NOSYMBOLS,,XCTSW,<TRO FL,TRPOFF>; NO SYMBOL BLOCKS
	V	NOERRORS,,XCTSW,<TLO A7,NSWIT>	; SUPPRESS ERRORS ON TTY
	V	NOLIST,,XCTSW,<TRZ FL,LISTOO!CREF>	; TURN OFF LISTING
	IFN	FTSTATS,<
	V	STATS,,XCTSW,<TLO A7,STATS> ;  STATISTICS
	>
	IFE	FTSTATS,<
	V	STATS,,SWNYET
	>
	V	LIST,*,XCTSW,<TRO FL,LISTOO>	; TURN ON LISTING
	V	QUOTED,*,SETVAL,RWS		; QUOTED STROP-WORDS
	V	NOQUOTES,,,SWNOQT		; UNQUOTED STROP-WORDS
	V	HEAP,,SETVAL!VALSW,DYNOWN	; CHANGE INITIAL HEAP-SIZE
	V	HELP,*,XCTSW,<JRST HELPER>	; TELL HIM WHAT TO DO
	V	TEMPCODE,,SETVAL!VALSW,LTCODE	; TEMPCODE BUFFER SIZE
	V	NUMBERS,,XCTSW,<TLO A7,ESWIT>	; SEQUENCE NUMBERS
	V	NONUMBERS,,XCTSW,<TLZ A7,ESWIT>	; NO SEQUENCE NUMBERS
	V	BUFFERS,,SETVAL!VALSW,<7(A1)>	; # I/O BUFFERS
	V	TRACE,*,SWVOPT,SWTRAC		; TRACE-BUFFER LENGTH
	V	PRODUCTION,*,XCTSW,<TRO FL,TRLOFF!TRPOFF> 
						; SUPPRESS DIAGNOSTIC INFO
	V	CREF,,XCTSW,<TRO FL,CREF!LISTOO> ; CROSS-REFERENCE LISTING
	V	NOCREF,,XCTSW,<TRZ FL,CREF>	; NO CREF LISTING
	>

	SETVAL==200000
	VALSW==100000
	XCTSW==40000
	SWNYET==20000
	SWVOPT==10000!VALSW
	DEFINE	V(A,B,C,D),<
	<SIXBIT/A/>>

SWTAB:	SWS					; GENERATE SWITCH NAME TABLE

SWTABN==.-SWTAB					; GET # SWITCHES

	DEFINE	V(A,B,C,D),<
	.ZZZ==0
	IFIDN	<B><*>,<
	.ZZZ==400000>
	IFNB	<C>,<
	.ZZZ==.ZZZ!C>
	IFN	.ZZZ&XCTSW,<			;; GENERATE INSTR, & POINTER
	.ZZZ,,[D]>
	IFE	.ZZZ&XCTSW,<			;; ELSE JUST ENTER VALUE GIVEN
	<.ZZZ_^D18>+<D>>	>

SWDTAB:	SWS					; GENERATE SWITCH DISPATCH TABLE

	PURGE	SWS
	PURGE	.ZZZ
	PURGE	V
XALL
SWNOQT:	SKIPA	A4,.+1		;
	XWD	A1,RESWRD-.A		; SET UP RESERVED-WORD-TABLE
	MOVEM	A4,RWS			;  POINTER
	POPJ	SP,

SWTRAC:	SKIPN	A5		; VALUE GIVEN ?
	MOVEI	A5,^D100	; NO - GIVE DEFAULT
	MOVEM	A5,TRACLN
	TRZ	FL,TRLOFF!TRPOFF ; & ENSURE TRACING ON
	POPJ	SP,

HELPER:	MOVE	A1,[SIXBIT/ALGOL/]
	PUSHJ	SP,.HELPR
	JRST	CSER+1		; TREAT AS SWITCH-ERROR (GET NEXT LINE)



;
;	SWITCH SCANNER DATA
;
	RELOC

SWIT:	BLOCK	2			; BUFFER FOR SWITCH
SWDEL:	BLOCK	1			; SWITCH DELIMITER SAVE
SWMASK:	BLOCK	1			; SAVE FOR UNIQUENESS-TEST MASK
SWERR:	BLOCK	3			; INITIALISED FROM HISEG.
;	ASCIZ/ switch:       /		; END OF ERROR-MESSAGE

	RELOC
	; INPUT THE COMMAND STRING

GETCS:	SETZM	CSFILE		; CLEAR COMMAND STRING FILE NAME
	SETZM	CSFILE+1	; CLEAR COMMAND STRING EXTENSION NAME
	SETZM	CSFILE+3	; CLEAR PROJECT/PROGRAMMER NUMBER
	SKIPN	CCLSW		; IF ENTRY WAS NOT FROM CCL
	JRST	GETCS2		; THEN SKIP THIS PART

	; READ CCL COMMAND STRING WITH TMPCOR UUO

	SETOM	CCLSW		; MARK: CCL COMMAND STRING HAS BEEN READ
	SKIPA	A4,.+1		; GET TMPCOR PARAMETER
	XWD	2,TEMPC1	; READ JUST FOR LENGTH OF FILE
	TMPCOR	A4,		; READ TEMPORARY CORE FILE
	SKIPA	A3,[440600,,A1]	; READ ERROR, SEE IF THERE IS A DISK FILE
	JRST	GETCS3		; CONTINUE

	; READ CCL COMMAND STRING FROM DISK

	PJOB	A4,		; GET JOB NUMBER
	IDIVI	A4,^D100	; GET 1ST DIGIT
	ADDI	A4,20		; CONVERT TO SIXBIT
	IDPB	A4,A3		; PUT IN A1
	IDIVI	A5,^D10		; GET 2ND AND 3RD DIGITS
	ADDI	A5,20		; CONVERT 2ND DIGIT TO SIXBIT
	IDPB	A5,A3		; PUT IN A1
	ADDI	A6,20		; CONVERT THIRD DIGIT TO SIXBIT
	IDPB	A6,A3		; PUT IT IN A1
	HRRI	A1,.ALG		; A1 NOW CONTAINS XXXALG
	MOVEM	A1,CSFILE	; SET FILE NAME
	MOVEI	A1,.TMP		; THE EXTENSION NAME IS TMP
	MOVSM	A1,CSFILE+1	; SET EXTENSION NAME
	MOVEI	A1,.DSK		; DEVICE IS DSK
	MOVSM	A1,CSLIST+1	; SET DEVICE NAME
	; OPEN COMMAND STRING FILE, WRITE A "*"

GETCS2:	OPEN	5,CSLIST	; OPEN COM STRING DEVICE
	JRST	TERMIN		; CANT OPEN, QUIT
	LOOKUP	5,CSFILE	; FIND THE FILE IF THERE IS ONE
	JRST	TERMIN		; FILE CANNOT BE READ
	SKIPE	CCLSW		; IF CALLED FROM CCL
	JRST	GETCS4		; THEN DONT PRINT COMMAND STRING STAR
	OUTBUF	5,1		; GET A BUFFER RING
	OUTPUT	5,0		; GET AN OUTPUT BUFFER
	MOVEI	A4,.STAR	; "*"
	IDPB	A4,STHEAD+1	; PUT IN OUTPUT BUFFER
	OUTPUT	5,0		; WRITE IT TO THE TTY

	; READ IN COMMAND STRING

GETCS4:	INBUF	5,1		; GET AN INPUT BUFFER RING
	AOS	A4,CSBLK	; POINT AT DESIRED BLOCK OF CMD STRING
	USETI	5,(A4)		; AND TELL MONITOR TO READ IT
	INPUT	5,0		; READ THE COMMAND STRING
	STATO	5,20000		; DID WE REACH END OF THE COMMAND FILE ?
	JRST	GETCS5		; NOT YET
	SETZM	CSBLK		; YES, MARK END-OF-COMMAND-FILE REACHED
	SETZM	CSTRIN		; AND ENSURE NULL TERMINATOR IN C.S.
	JRST	GETCS3		; NOW PROCEED TO FETCH THE NULL TERMINATOR

GETCS5:	MOVE	A4,CSHEAD	; BUFFER ADDRESS
	HRLZI	A4,2(A4)	; WHERE COMMAND STRING SITS NOW
	HRRI	A4,CSTRIN	; WHERE TO MOVE IT TO
	MOVE	A5,CSHEAD+2	; GET LENGTH OF BUFFER
	IDIVI	A5,5		; IN WORDS
	BLT	A4,CSTRIN-1(A5)	; AND SAVE THE COMMAND STRING
	SETZM	CSTRIN(A5)	; CLOBBER OLD GARBAGE


EDIT(117); CORRECT COMMAND SCANNER TO IGNORE LEADING SPACES

GETCS3:	MOVE	A5,[POINT 7,CSTRIN]; [E117] GET BYTE POINTER TO A5
	MOVEM	A5,CSP		; [E117] SAVE IT
	SKIPL	CSCOMP		; IF CURRENT CMD FILE NOT FINISHED
	POPJ	SP,		; THEN RETURN NOW
	ILDB	A6,A5		; [E117] GET NEXT CHAR
	CAIE	A6,.SPACE	; [E117] IF CHAR IS SPACE
	CAIN	A6,.TAB		; [E117]  OR TAB,
	JRST	.-3		; [E117] SKIP OVER IT
	CAIN	A6,.CR		; IF THE 1ST CHARACTER IS A CR
	JRST	GETCS		; THEN READ ANOTHER COMMAND STRING
	CAIN	A6,.CZ		; CONTROL-Z ?
	EXIT			; YES - ALL DONE
	JUMPL	A6,GETCS	; DITTO FOR OTHER TERMINATOR
	SETZM	CSCOMP		; MARK: COMMAND STRING YET TO BE SCANNED
	POPJ	SP,		; RETURN
SCANCH:	ILDB	A6,CSP		; FETCH NEXT CHAR
	CAIG	A6,172		; LOWER CASE ?
	CAIGE	A6,141
	JRST	SCANC1
	SUBI	A6,40		; CONVERT IT TO UPPER CASE
	POPJ	SP,

SCANC1:	CAIE	A6,.SPACE	; IGNORE SPACES AND TABS
	CAIN	A6,.TAB
	JRST	SCANCH
	CAIE	A6,.LF
	CAIN	A6,.VT
	JRST	SCANC2
	CAIE	A6,.FF
	CAIN	A6,.ALT1
	JRST	SCANC2
	CAIE	A6,.ALT2
	CAIN	A6,.ALT3

SCANC2:	MOVNI	A6,1
	CAIE	A6,0
	POPJ	SP,
	SKIPE	CSFILE		; ARE WE READING A DISK CMD FILE ?
	SKIPN	CSBLK		; YES, ANY MORE TO COME ?
	POPJ	SP,		; NO, RETURN NULL TERMINATOR NOW
	SETZM	CSFILE+3	; CLEAR CMD FILE PPN
	MOVEI	A6,.DSK		; DEVICE MUST BE RESET TO DSK
	MOVSM	A6,CSLIST+1	; AFTER CALL TO BMOVE AT START1+14
	PUSH	SP,A4		; SAVE A4 AND A5 OVER
	PUSH	SP,A5		; CALL TO GETCS2
	PUSHJ	SP,GETCS2	; TO READ NEXT CMD FILE BLOCK
	POP	SP,A5		; RESTORE A5,A4
	POP	SP,A4
	JRST	SCANCH
	RELOC

;----------------------------------------------------------
OLIST:	BLOCK	3		; "B" DATA MODE (14)
				; SIXBIT DEVICE
;	XWD	BHEAD1,0	; BUFFER HEADER
OFILE:	BLOCK	1		; SIXBIT FILENAME
	BLOCK	1		; SIXBIT EXTENSION
	BLOCK	1		; TIME/DATE
	BLOCK	1		; PROJECT/PROGRAMMER
	BLOCK	1		; NUMBER OF RING BUFFERS

BHEAD1:	BLOCK	1		; OBJECT BUFFER HEADER BLOCK
	BLOCK	1		; WRITE POINTER
	BLOCK	1		; COUNT

;----------------------------------------------------------
LLIST:	BLOCK	1		; "A" DATA MODE
	BLOCK	2		; SIXBIT DEVICE
;	XWD	BHEAD2,0	; BUFFER HEADER
LFILE:	BLOCK	1		; SIXBIT FILENAME
	BLOCK	1		; SIXBIT EXTENSION
	BLOCK	1		; TIME/DATE
	BLOCK	1		; PROJECT/PROGRAMMER 
	BLOCK	1		; NUMBER OF BUFFERS

BHEAD2:	BLOCK	1		; LISTING BUFFER HEADER BLOCK
W:	BLOCK	1		; LISTING POINTER
	BLOCK	1		; COUNT

;----------------------------------------------------------
SLIST:	BLOCK	1		; "A" DATA MODE
	BLOCK	2		; SIXBIT DEVICE
;	XWD	0,BHEAD3	; BUFFER HEADER
SFILE:	BLOCK	1		; SIXBIT FILENAME
	BLOCK	1		; SIXBIT EXTENSION
	BLOCK	1		; TIME/DATE
	BLOCK	1		; PROJECT/PROGRAMMER
	BLOCK	1		; NUMBER OF BUFFERS

BHEAD3:	BLOCK	1		; SOURCE BUFFER HEADER BLOCK
P:	BLOCK	1		; READ POINTER
	BLOCK	1		; COUNT
;----------------------------------------------------------
CSLIST:	BLOCK	3
;	1			; "AL" DATA MODE
;	SIXBIT	/TTY/		; DEVICE
;	XWD	STHEAD,CSHEAD	; BUFFER HEADS

CSFILE:	BLOCK	1		; SIXBIT FILE NAME
	BLOCK	1		; SIXBIT EXTENSION
	BLOCK	1		; TIME/DATE
	BLOCK	1		; PROJECT/PROGRAMMER NUMBER

CSHEAD:	BLOCK	1		; BUFFER
CSP:	BLOCK	1		; POINTER
	BLOCK	1		; COUNT

;--------------------------------------------------------
STHEAD:	BLOCK	3		; BUFFER HEADER FOR COMMAND STRING STAR

	CSLEN==201		; LENGTH OF COMMAND STRING BUFFER

CSTRIN:	BLOCK	CSLEN		; COMMAND STRING BUFFER

CCLSW:	BLOCK	1		; CCL SWITCH. 1=ENTERED FROM CCL
RFLAGS:	BLOCK	1		; READ-MODULE FLAGS
BLOCK1:	BLOCK	1		; BEGINNING OF SYMBOL TABLE BLOCK 1
STACKB:	BLOCK	1		; BEGINNING OF STACK
COREB:	BLOCK	1		; BEGINNING OF CORE ACQUIRED WITH CORE UUO
COREND:	BLOCK	1		; END OF LOW SEGMENT
LTCODE:	BLOCK	1		; LENGTH OF TEMPCODE
CSCOMP:	BLOCK	1		; -1 = COMMAND STRING COMPLETELY SCANNED
				; 0 = COMMAND STRING CONTAINS YET ANOTHER COMP.
				; 1 = CURRENT LINE OF COM.STRING NOT COMPLETELY SCAND.
CSBLK:	BLOCK	1		; POINTER TO WHICH CMD FILE BLK WE'RE AT
CHKSUM:	BLOCK	1		; CHECK SUM
PNBUF:	BLOCK	2		; PREPARED NAME BUFFER

	RELOC

TEMPC1:	XWD	.ALG,0		; TMPCOR READ BLOCK
	IOWD	CSLEN,CSTRIN
SUBTTL	** A RANDOM COLLECTION OF RANDOM ROUTINES **

	; TERMINATE COMPILATION DUE TO ABNORMAL CONDITION

TERMIN:	OUTSTR	TERMSG	; WRITE TERMINATE MSG
EDIT(001); DON'T DELETE OLD .REL-FILE IF DISASTERS STRIKE.
QUIT:	CLOSE	1,40		; [E001] CLOSE OBJECT FILE
	CLOSE	2,0		; CLOSE LISTING FILE
	CLOSE	3,0		; CLOSE SOURCE FILE
	SKIPN	CSFILE		; HAVE WE A DSK CMD FILE ?
	JRST	QUIT1		; NO SO NO NEED TO DELETE IT !
	PUSHJ	SP,GETCS	; YES, OPEN IT
	SETZM	CSFILE		; CLEAR ITS NAME
	RENAME	5,CSFILE	; AND DELETE IT
	JFCL			; IGNORE ERRORS
	CLOSE	5,0		; CLOSE THE DEVICE
	SETZM	CSBLK		; MARK IT ABSENT

QUIT1:	MOVE	A4,COREB	; GET ORIGINAL VALUE OF JOBFF
	HRRZM	A4,.JBFF	; RETURN CORE USED DURING COMPILATION
	SETZM	COREB		; MARK: RETURNED
	EXIT			; RETURN TO MONITOR

	; COMMAND STRING ERROR

CSER:	OUTSTR	CSERM		; WRITE MSG
	SETOM	CSCOMP		; MARK: COMMAND STRING FULLY SCANNED
	SKIPN	CCLSW		; TERMINATE IF CALLED FROM CCL
	TLNE	A7,CSDONE	; IF COMMAND STRING ONLY PART SCANNED
	JRST	TERMIN		; THEN TERMINATE
	JRST	START2		; ELSE GET ANOTHER COMMAND STRING

	; WRITE TO LISTING, GET NEXT OUTPUT BUFFER

WRITEL:	HLLZ	A3,W		; GET S-P BITS
	ROT	A3,4		; PUT 1ST 4 BITS IN RIGHT HALF
	SETCM	A3,MSKTBL(A3)	; GET A MASK FROM TABLE
	ANDM	A3,@W		; DELETE TRAILING EXTRA CHARS
	OUT	2,0		; GET NEXT OUTPUT BUFFER
	JRST	.+3		; -OK, SKIP
	OUTSTR	LISTER	; -OUTPUT ERROR
	JRST	TERMIN		; TERMINATE COMP

	; WRITTEN OK, MARK END OF NEW BUFFER

	MOVE	A6,BHEAD2	; ADDR OF CURRENT BUFFER
	HLRZ	A3,(A6)		; LENGTH OF BUFFER
	TLZ	A6,USE		; ZERO USE BIT
	ADDI	A6,(A3)		; ADD LENGTH TO ADDRESS
	MOVEM	A6,OBEND	; SAVE ADDR OF END OF BUFFER DATA
	POPJ	SP,		; EXIT
	; ALLOCATE BUFFER SPACE

ALLOCATE:
	PUSH	SP,.JBFF	; SAVE ADDRESS OF BUFFER
	ADDB	A1,.JBFF	; SET NEW VALUE OF FREE SPACE POINTER
	CAMGE	A1,.JBREL	; IF NOT BEYOND END OF LOW SEGMENT
	JRST	.+3		; THEN SKIP THIS
	CORE	A1,		; MOVE UP THE TOP OF THE LOW SEG
	JRST	TERMIN		; -CANNOT ACQUIRE MORE CORE
	POP	SP,A1		; GET ADDRESS OF BUFFER
	POPJ	SP,		; EXIT ALLOCATE



	; CANNOT OPEN SOURCE DEVICE

DSERR1:	SKIPA	A1,[		; INCLUDE DEVICE IN MSG
	POINT	6,SLIST+1]	; POINTER TO DEVICE NAME

	; CANNOT OPEN LISTING FILE

DSERR3:	MOVE	A4,[POINT 6,LLIST+1]	; LOAD POINTER TO LISTING DEVICE NAME

DSERR0:	MOVEI	A6,6		; 6 CHARS LONG
	PUSHJ	SP,PRENAM	; WRITE TO TTY
	OUTSTR	ILLDEV	; WRITE REST OF MSG
	JRST	CSER+1		; TERMINATE COMP



	; WRITE DEVICE NAME ON TTY

PRENAM:	MOVE	A5,[		; POINTER TO WHERE
	POINT	7,PNBUF]	; PREPARED NAME WILL GO
	MOVEI	A3,.QUESTION
	IDPB	A3,A5		; OUTPUT A "?"

PNL:	ILDB	A3,A4		; GET A CHAR
	MOVEI	A3,40(A3)	; CONV TO ASCII
	IDPB	A3,A5		; PUT IN BUFFER
	SOJG	A6,PNL		; LOOP
	IDPB	A6,A5		; END BUFFER WITH A NULL
	OUTSTR	PNBUF		; WRITE BUFFER TO TTY
	POPJ	SP,		; EXIT
	; CANNOT READ FROM INDICATED SOURCE FILE

DSERR2:	HLRZ	A4,SFILE+1	; IF EXTENSION NAME IS NULL
	JUMPE	A4,.+3		; THEN THE ERROR IS REAL
	SETZM	SFILE+1		; OTHERWISE CHANGE FROM .ALG TO .
	JRST	CS9		; AND TRY AGAIN
	MOVE	A4,[		; PUT FILENAME IN MSG
	POINT	6,SFILE]	; POINTER TO FILENAME
	MOVEI	A6,6		; 6 CHARS LONG
	PUSHJ	SP,PRENAM	; WRITE FILENAME TO TTY
	OUTSTR	..DOT		; WRITE DOT TO TTY
	MOVEI	A6,3		; 3 CHAR EXTENSION LENGTH
	MOVE	A5,[POINT 7,PNBUF]
	PUSHJ	SP,PNL		; WRITE FILENAME EXT TO TTY
	MOVE	A6,SFILE+1
	ANDI	A6,7		; GET LOOKUP RETURN CODE
	CAIN	A6,2		; IF RC=2,
	JRST	READPR		; THEN FILE READ PROTECTED
	OUTSTR	NOFILE	; ELSE FILE DOESNT EXIST
	JRST	CSER+1		; TERMINATE COMP

READPR:	OUTSTR	READPM	; WRITE MSG
	JRST	CSER+1		; TERMINATE COMP



..DOT:	ASCIZ	/./		; DOT

IFLAGS:	XWD	<WITHIN+COMPLETE>&777777,NORMAL ; INITIAL READ MODULE FLAGS

	; UNABLE TO CREATE LISTING FILE

DSERR4:	OUTSTR	UNLIST	; UNABLE TO CREATE LISTING
	JRST	CSER+1		; TERMINATE COMP
	; PUT 2-DIGIT DECIMAL NUMBER IN LISTING

DEC2:	IDIVI	A4,^D10		; A4=TENS, A5=ONES
	MOVEI	A4,.N0(A4)	; CONV TO ASCII
	IDPB	A4,A3		; MOVE TO LISTING
	MOVEI	A5,.N0(A5)	; CONV TO ASCII
	IDPB	A5,A3		; MOVE TO LISTING
	IDPB	A14,A3		; MOVE : OR - TO LISTING
	POPJ	SP,		; EXIT

	; RUN THE NEXT CUSP

RUNUUO:	SKIPE	.JBERR		; IF THERE WERE ERRORS
	JRST	QUIT		; THEN ABORT LOADING
	MOVSI	A3,(SIXBIT /SYS/)
	MOVEM	A3,LB		; SEARCH DEVICE
	MOVE	A3,OFILE	; GET NAME OF PROGRAM TO BE CALLED
	MOVEM	A3,LB+1		; PUT IN PARAMETER BLOCK
	SETZM	LB+2
	SETZM	LB+3
	SETZM	LB+4
	SETZM	LB+5		; CLEAR OUT THE REST
	HRLZI	A4,1		; ENTER IT AT ITS CCL ENTRY POINT
	HRRI	A4,LB		; ADDRESS OF PARAMETER BLOCK
	RUN	A4,		; LOAD AND RUN NEXT CUSP
	JRST	TERMIN		; CUSP NOT FOUND, STOP
	; PUT CURRENT DATE AND TIME IN LISTING

DATIME:	MOVE	A3,LBP		; GET BUFFER POINTER
	DATE	A4,		; GET DATE
	IDIVI	A4,^D372	; DIVIDE BY 372 DAYS/YEAR
	IDIVI	A5,^D31		; DIVIDE BY 31 DAYS PER MONTH
	MOVE	A1,A5		; SAVE ACC A5
	MOVE	A2,A4		; SAVE ACC A4
	MOVEI	A14,.MINUS	; -
	MOVEI	A4,1(A6)	; DAY
	PUSHJ	SP,DEC2		; WRITE 2 DIGITS
	ROT	A1,-1
	MOVEI	A4,[SIXBIT /JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC/](A1)
	JUMPGE	A1,.+2
	TLOA	A4,(POINT 6,0,17)
	TLO	A4,(POINT 6,0,)	; GET MONTH
	MOVEI	A5,3
	ILDB	A6,A4
	ADDI	A6,40
	IDPB	A6,A3
	SOJG	A5,.-3		; AND WRITE IT
	IDPB	A14,A3
	MOVEI	A4,100(A2)	; YEAR
	PUSHJ	SP,DEC2		; WRITE 2 DIGITS
	MOVEI	A1,.SPACE	; BLANK
	DPB	A1,A3		; INCLUDE
	MOVEI	A5,3		; FOUR
	IDPB	A1,A3		; BLANKS.
	SOJG	A5,.-1		; PUT A BLANK IN LISTING
	MSTIME	A4,		; GET TIME OF DAY
	IDIVI	A4,^D1000	; CONVERT TO SECONDS
	IDIVI	A4,^D3600	; DIVIDE BY 3600 SEC/HOUR
	IDIVI	A5,^D60		; DIVIDE BY 60 SEC/MIN
	MOVE	A2,A5		; SAVE ACC A5
	MOVEI	A14,.COLON	; :
	PUSHJ	SP,DEC2		; WRITE HOUR AS 2 DIGITS
	MOVE	A4,A2		; MINUTE
	PUSHJ	SP,DEC2		; WRITE 2 DIGITS
	MOVE	A4,A6		; SECOND
	PUSHJ	SP,DEC2		; WRITE 2 DIGITS
	MOVEI	A1,0		; ASCII NULL
	DPB	A1,A3		; PUT NULL AT END OF MESSAGE
	MOVEI	A1,LB		; ADDR OF BUFFER
	PUSHJ	SP,INSERT	; INSERT LINE IN LISTING
	TLNE	A7,LTTY		; IF LISTING IS TO TTY:
	JRST	DATIM1		;  THEN DON'T DO IT
	MOVEI	A1,COMSTR
	PUSHJ	SP,INSERT
	MOVEI	A1,CSTRIN
	PUSHJ	SP,INSERT
DATIM1:	MOVEI	A1,LINES3	; 3 BLANK LINES
	PUSHJ	SP,INSERT	; INSERT IN LISTING
	JRST	ICHECK		; ALIGN TO A FULLWORD, EXIT DATIME
	RELOC

LINK:	BLOCK	1		; RETURN LINK
LINK1:	BLOCK	1		; RETURN LINK .PINIT
OLDSBR:	BLOCK	1		; OLD SOURCE BUFFER RING

	RELOC


;	"DEC" WILL CONVERT THE NUMBER IN A4 TO DECIMAL ASCII CHARACTERS,
;	AND PLACE THE RESULT DIRECTLY INTO THE LISTING.  "DEC" WILL PRINT
;	THE NUMBER RIGHT-JUSTIFIED IN A FIELD WHOSE SIZE IS SPECIFIED IN
;	A3.  "DEC" WILL PRECEDE THE FIRST PRINTABLE CHARACTER OF THE NUMBER
;	WITH THE CHARACTER THAT IS SPECIFIED IN RH A2.
;	"CRFDEC" WILL FILL THE FIELD WITH THE CHARACTER IN LH A2,
;	INSTEAD OF BLANKS

DEC:	HRLI	A2," "		; BLANK-FILL

CRFDEC:	MOVE	A1,A3		; COPY NUMBER OF CHARS
	IDIVI	A4,^D10		; DIVIDE BY 10
	LSHC	A5,-4		; MOVE REMAINDER TO ACC A3
	SOJG	A1,.-2		; LOOP TILL END OF NUMBER
	HLRZ	A1,A2		; PUT FILLER IN ACC A1

DEC1:	LSHC	A5,4		; GET NEXT CHAR FROM A6
	JUMPN	A5,DEC3		; JUMP IF NON ZERO
EDIT (203);			;[203]
	CAIN	A3,1		;[203] LAST CHARACTER AND STILL A ZERO?
	 JRST	DEC3		;[203] GO PRINT IT THEN
	IDPB	A1,W		; INCLUDE A LEADING BLANK
	SOJG	A3,DEC1		; LOOP TILL END OF NUMBER

DEC3:	DPB	A2,W		; INCLUDE SPECIAL CHARACTER
	MOVEI	A5,.N0(A5)	; CONVERT TO ASCII
	IDPB	A5,W		; PUT NUMBER IN LISTING
	MOVEI	A5,0		; CLEAR A5
	LSHC	A5,4		; GET NEXT CHAR FROM A6
	SOJG	A3,DEC3+1	; LOOP TILL END OF NUMBER
	POPJ	SP,		; EXIT DEC - A3=0 IS RELIED ON!

	; DETERMINE WHETHER NL CHAR IS FOR END OF LINE OR END OF BUFFER

NCHECK:	MOVE	A1,P		; GET READ POINTER
	CAMN	A1,IBEND	; IF AT END OF BUFFER
	JRST	INEND1		; THEN GET ANOTHER BUFFER
	JRST	SKRET		; EXIT NCHECK

	; COMPUTE LENGTH OF TAB

TAB:	MOVE	A2,CC		; GET CHAR COUNT
	SUB	A2,LP1		; COMPUTE POSITION ON CURRENT LINE
	ADDI	A2,^D8		; TAB TO THE NEW POSITION
	ANDCMI	A2,7		; BACK UP TO 8-CHAR MULTIPLE
	SUBI	A2,1		; BACK UP 1 MORE CHAR
	ADD	A2,LP1		; COMPUTE NEW CHARACTER COUNT
	MOVEM	A2,CC		; SE IT
	MOVE	A2,CTABLE(A1)	; RELOAD THE TABLE ENTRY VALUE
	POPJ	SP,		; EXIT TAB
CSERM:	ASCIZ	/?INVALID COMMAND STRING
/
TERMSG:	ASCIZ	/?COMPILATION TERMINATED
/
LISTER:	ASCIZ	/?OUTPUT ERROR ON LISTING
/
ILLDEV:	ASCIZ	/ DEVICE NOT AVAILABLE
/
NOFILE:	ASCIZ	/ FILE DOES NOT EXIST
/
DDTMSG:	ASCIZ	/ DDT is loaded
/
HEADIN:	ASCIZ	/DECSYSTEM-20 ALGOL-60, Version /  ; [274]
READPM:	ASCIZ	/ FILE READ PROTECTED
/
UNLIST:	ASCIZ	/?CANNOT CREATE LISTING FILE
/
LINES3:	ASCIZ	/


/
FORM:	XWD	060000,0

ERRORM:	ASCIZ	/ errors
/
QUERY:	ASCIZ	/?/
ALGOL:	ASCIZ	/ALGOL:  /	;[251]
ALGDDT:	ASCIZ/ALGDDT: /
COMSTR:	ASCIZ/
Command string: /
SUBTTL	**  RINIT  **

	; CREATE OBJECT FILE

CS5:	SKIPE	OFILE		; IF FILE NAME NOT NULL
	JRST	NOOBJ-1		; THEN CREATE THE OBJECT FILE
	MOVS	A5,OLIST+1	; GET DEVICE NAME
	CAIE	A5,.DSK		; UNLESS DEVICE NAME IS DSK
	PUSHJ	SP,WRITE1	; CREATE OBJECT FILE

	; WRITE "ALGOL: NAME "

NOOBJ:	PUSHJ	SP,WRITE0	; ELSE CALL WRITE0
	TLO	A7,CSDONE	; 1ST PART OF CS DONE
	SKIPN	CCLSW		; IF THIS IS NOT A CCL RUN
	JRST	LST1		; THEN SKIP THIS
	SKIPN	.JBDDT		; IF NO DDT ..
	OUTSTR	ALGOL		; WRITE "ALGOL: "
	SKIPE	.JBDDT		; ELSE..
	OUTSTR	ALGDDT	; ..WRITE "ALGDDT: "
	MOVEI	A4,6		; WRITE 6 CHARACTERS OF FILE NAME
	MOVE	A5,[		; LOAD A POINTER TO
	XWD	440600,SFILE]	; THE NAME OF THE SOURCE FILE
	ILDB	A6,A5		; GET NEXT SIXBIT CHARACTER
	ADDI	A6,40		; CONVERT IT TO ASCII
	TTCALL	1,A6		; WRITE IT TO TERMINAL
	SOJG	A4,.-3		; LOOP
	OUTSTR	NLCHRS	; WRITE A CR/LF

	; CREATE LISTING

LST1:	SETZM	W		; ZERO W
	SKIPE	LFILE		; IS THERE A LISTING?
	JRST	LST		; -YES
	MOVS	A5,LLIST+1	; -MAYBE, CHECK DEVICE
	CAIN	A5,.DSK		; DSK?
	JRST	NOLST		; -YES, NO LISTING
	
LST:	MOVE	A5,LLIST+1	; GET DEVICE NAME
	DEVCHR	A5,		; GET DEVICE CHARACTERISTICS WITH DEVCHR
	TLNE	A5,DEVTTY	; IF LISTING DEVICE IS A TTY
	TLO	A7,LTTY!NSWIT	; THEN SET INDICATOR
	TLNE	A5,DEVTTY	;  AND
	TRZ	FL,CREF		;   TURN OFF CREF'ING.
	OPEN	2,LLIST		; OPEN LISTING
	JRST	DSERR3		; -SOMETHING WRONG
	OUTBUF	2,@LLIST+7	; GET A BUFFER RING
	HLRZ	A3,LFILE+1	; GET EXT
	CAIE	A3,777777	; STILL GARBAGE ?
	JRST	LST2		; NO - USE HIS
	MOVEI	A3,.LST		; YES USE .LST
	TRNE	FL,CREF		;  UNLESS WE'RE CREF'ING
	MOVEI	A3,.CRF		;   IN WHICH CASE USE .CRF
	MOVSM	A3,LFILE+1
LST2:	ENTER	2,LFILE		; CREATE FILE
	JRST	DSERR4		; -CANNOT CREATE
	TLO	A7,EXISTS	; SET FLAG: FILE EXISTS
	SETZM	FIVEC		; INIT FIVE CHAR COUNT

	; PUT HEADING IN LISTING

	PUSHJ	SP,WRITEL	; GET THE 1ST LISTING BUFFER
	MOVEI	A1,FORM		; ADDRESS OF A FORM FEED
	TLNE	A7,LTTY		; IF LISTING IS SENT TO TTY
	PUSHJ	SP,INSERT	; THEN SEND A FORM-FEED THERE
	MOVEI	A1,HEADIN	; ADDR OF HEADING
	PUSHJ	SP,INSERT	; PUT IN LISTING
	MOVE	A6,LBP		; PREPARE TO PRINT VERSION NUMBER
	LDB	A1,[POINT 9,.JBVER,11]

EDIT(111); INSERT VERSION NUMBER IN OCTAL

	PUSHJ	SP,LST4		; [E111] INSERT OCTAL VALUE
	LDB	A1,[POINT 6,.JBVER,17]
	JUMPE	A1,LST3
	IDIVI	A1,^D26
	JUMPE	A1,.+3		; FIRST LETTER OF..
	ADDI	A1,.A-1
	IDPB	A1,A6		; ..MINOR VERSION NUMBER
	ADDI	A2,.A-1
	IDPB	A2,A6		; ..AND ITS SECOND LETTER

LST3:	MOVEI	A1,.LPAREN
	IDPB	A1,A6
	HRRZ	A1,.JBVER	; [E111] GET EDIT NUMBER
	PUSHJ	SP,LST4		; [E111] INSERT IT IN OCTAL
	MOVEI	A1,.RPAREN
	IDPB	A1,A6
	MOVEI	A1,.SPACE
	MOVEI	A4,3
	IDPB	A1,A6		; INSERT THREE SPACES
	SOJG	A4,.-1
	MOVEI	A1,0
	IDPB	A1,A6
	MOVEI	A1,LB
	PUSHJ	SP,INSERT
	PUSHJ	SP,DATIME	; PUT DATE, TIME AND COMMAND-STRING IN LISTING
	TLNE	A7,LTTY		; IF LISTING IS TO TTY
	PUSHJ	SP,WRITEL	; THEN CLEAR THE BUFFER
	JRST	NOLST1		; CONTINUE


LST4:	IDIVI	A1,10		; [E111] SPLIT OFF OCTAL DIGIT
	JUMPE	A1,LST5		; [E111] JUMP IF ALL DONE
	HRLM	A2,(SP)		; [E111] OTHERWISE SAVE DIGIT
	PUSHJ	SP,LST4		; [E111] AND INSERT EARLIER
	HLRZ	A2,(SP)		; [E111] DIGITS FIRST.
LST5:	ADDI	A2,.N0		; [E111] CONVERT TO ASCII
	IDPB	A2,A6		; [E111] INSERT IN TEXT
	POPJ	SP,		; [E111] AND RETURN

NOLST:	HRRI	A7,NLIST1	; SET FLAGS ADDR
	; INITIALIZE VARIABLES AND TABLES

NOLST1:	SETZM	CC		; INIT CHARACTER COUNT
	IFN	FTSTATS,<
	SETZM	DEFCNT		; INIT 
	SETZM	IDCHRS		;  STATS 
	SETZM	REFCNT		;   COUNTERS.
	>
	SETZM	OLDNO		; INIT OLD LINE NUMBER
	SETZM	LINE5		; INIT 5-CHAR LINE NUMBER
	SETZM	LSBUFP		; INIT NAME BUF LIST POINTER
	SETZM	BNUM		; INIT BEGIN NUMBER
	SETZM	LBNUM		; INIT LAST BEGIN NUMBER
	SETZM	ENUM		; INIT END NUMBER
	SETZM	LENUM		; INIT LAST END NUMBER
	SETZM	NSYM		; INIT NSYM
	SETZM	PLIST+4		; INIT PLIST+4
	SETZM	NDEL		; INIT NDEL
	SETZM	DUBBLE		; INIT DUBBLE
	SETZM	BLEX		; INIT BUFFERED LEXEME
	SETZM	.JBERR		; INIT ERROR COUNT
	SETZM	WRNCNT		;[171] INIT WARNING COUNT
	SETZM	TBLEN		; INIT TMPBUF DATA LENGTH WORD
	SETZM	SSTART		; INIT SEGMENT START
	SETZM	LINENO		; INIT LINENO
	SETZM	NXTSLN		; CLEAR NEXT STATEMENT NUMBER FOR SYM
	SETZM	NXTDLN		; AND DEL (WILL BE COPIED BY RUND)
	SETOM	LSTSLN		; MAKE LAST AN IMPOSSIBLE VALUE
	SETOM	LASTRA		; MAKE SURE FIRST STN IS SENT
	SETZM	SENDSN		; MARK NOT SET UP YET
	SETZM	STCFL		; INIT STRING CHARACTERS FLAG
	MOVEI	A4,50		; SET THE BEGIN TABLE INDEX
	MOVEM	A4,BTI		; TO 50
	MOVEI	A4,MTABLE	; ADDRESS OF MTABLE
	MOVEM	A4,NAMTE	; INIT MESSAGE TABLE POINTER
	MOVEI	A4,PLIST+3	; ADDR OF POINTER TABLE
	MOVEM	A4,PLIST	; INIT UP-ARROW LIST
	MOVEM	A7,RFLAGS	; SAVE THE FLAGS
	HRRZ	A4,.JBFF	; GET ADDRESS OF FREE SPACE
	MOVEM	A4,TCBASE	; USE AS BASE FOR ALLOCATION
	JSP	A1,.PINIT	; ALLOCATE TABLES
	MOVEM	A7,A7SAV	; SAVE A7
	MOVE	A7,RFLAGS	; GET FLAGS AGAIN
	PUSHJ	SP,READ		; READ IN FIRST LINE OF SOURCE

EMPTY:	TLZ	A7,WITHIN	; MARK: WITHIN NEWLINE
	MOVE	A2,P		; GET READ POINTER
	MOVEM	A2,LSTART	; SAVE POINTER TO LINE START
	PUSHJ	SP,NL11		; CHECK FOR LINE NUMBERS, ETC
	HALT	.		; CANT POSSIBLY RETURN HERE

EMPTY1:	SETOM	NDEL		; MAKE IT LOOK LIKE SOMTHING IS IN NDEL
	PUSHJ	SP,RUND		; DO AN INITIAL RUND
	AOJA	DEL,@LINK	; CLEAR DEL AND EXIT
SUBTTL	**  PINIT  **

.PINIT:	MOVEM	A1,LINK1	; SAVE RETURN LINK

	; INITIALIZE VARIABLES

	SETZM	TOFIXI		; INIT FIXUP TABLE HALFWORD INDEX
	SETZM	RA		; INIT PROGRAM COUNTER
	SETZM	FNLEVEL		; INIT FUNCTION LEVEL
	SETZM	BLOCKL		; INIT BLOCK LEVEL
	SETZM	LEXBLOCK	; INIT LEXICAL BLOCK LEVEL
	SETZM	CURBLOCK	; INIT CURRENT BLOCK LEVEL
	SETZM	THUNK		; INIT THUNK
	SETOM	CAX		; INIT CAX
	SETOM	PROSKIP		; INIT PROCEDURE SKIP
	HRLZI	DBASE,400000	; INIT DISPLAY POINTER
	HRLZI	DBASE+1,400000	; INIT DISPLAY POINTER
	MOVEI	A4,A13+1	; INIT
	MOVEM	A4,LAC		; LAC
	HRLZI	STOPS,160000	; INIT STOPS

	; ACQUIRE SPACE FOR TABLES

	MOVE	A5,TCBASE	; BASE OF AVAILABLE CORE
	ADD	A5,LTCODE	; THE LENGTH OF TEMPCODE
	ADDI	A5,TABLES+CONL+STACKL+1
				; PLUS THE LENGTH OF SYMBOL AND FIXUP TABLES
				; PLUS LENGTH OF CONSTANT TABLE
				; PLUS LENGTH OF STACK
	MOVEM	A5,COREND	; SAVE THE CALLI PARAMETER
	HRRZM	A5,.JBFF	; SET NEW VALUE OF JOBFF
	CORE	A5,		; GET CORE FOR ALL OF THAT
	JRST	TERMIN		; CORE NOT AVAILABLE, TERMINATE
	; ALLOCATE TABLES

	MOVE	SP,TCBASE	; BASE OF TEMPCODE
	MOVEM	SP,INDEX	; SET THE TEMPCODE INDEX
	ADD	SP,LTCODE	; ADD LENGTH OF TEMPCODE
	MOVEM	SP,TCMAX	; SET END OF TEMPCODE
	ADDI	SP,1		; LEAVE 1 WORD BETWEEN SYMBOL TABLE AND TEMPCODE
	MOVEM	SP,BLOCK1	; WHICH IS ALSO THE START OF THE SYMBOL TABLE
	MOVEM	SP,STBB		; START OF CURRENT BLOCK IN SYMBOL TABLE
	MOVEM	SP,NASTE	; 1ST AVAILABLE ENTRY IN SYMBOL TABLE
	ADDI	SP,TABLES	; ADD LENGTH OF TABLES
	MOVEM	SP,CONTAB	; SET BASE OF CONSTANT TABLE
	MOVEM	SP,FIXUP	; WHICH IS ALSO THE BASE OF THE FIXUP TABLE
	MOVEM	SP,LASTST	; END OF STRING CHAIN
	MOVEI	A5,1(SP)	; STEP OVER 1ST WORD OF CONSTANTS TABLE
	MOVEM	A5,NACTE	; SET NEXT AVAILABLE CONSTANT TABLE ENTRY
	MOVEI	A5,-1(SP)	; BACK UP 1
	MOVEM	A5,NAFTE	; SET NEXT AVAILABLE FIX-UP TABLE ENTRY
	MOVEM	A5,LASTC1	; SET CONSTANT TABLE POINTER
	MOVEI	A5,-2(SP)	; BACK UP 1 MORE
	MOVEM	A5,LASTC2	; SET CONSTANT TABLE POINTER
	ADDI	SP,CONL		; ADD LENGTH OF CONSTANT TABLE
	MOVEM	SP,CONEND	; SET END OF CONSTANT TABLE
	MOVEM	SP,STACKB	; SAVE BEGINNING ADDR OF STACK
	HRLI	SP,-STACKL	; SET UP STACK POINTER
	MOVE	A4,INDEX	; TEMPCODE POINTER
	HRLI	A4,770000	; INIT
	MOVEM	A4,HANDLE	; HANDLE
	HRREI	A4,-1		; THE 1ST ENTRY IN THE CONSTANTS TABLE MUST
	PUSHJ	SP,CON1		; BE A CONSTANT OF -1
	MOVEI	A1,B0LIST##	; INIT LIST
	PUSHJ	SP,BMOVE	; INITIALIZE BLOCK-0 FROM HIGH SEGMENT
	JRST	@LINK1		; EXIT .PINIT
SUBTTL	**  TABLE OVERFLOW ROUTINES  **

	; SYMBOL TABLE OR FIXUP TABLE OVERFLOW

OVFL1:	PUSHJ	SP,OVFLS	; SAVE SOME REGISTERS
	MOVE	A4,NAFTE	; BASE OF CORE TO MOVE
	PUSHJ	SP,OVFL		; MOVE IT
	ADDM	A4,CONTAB	; UPDATE BASE OF CONSTANT TABLE
	ADDM	A4,FIXUP	; UPDATE BASE OF FIXUP TABLE
	ADDM	A4,LASTST	; UPDATE STRING CHAIN
	ADDM	A4,NACTE	; UPDATE CONSTANT TABLE POINTER
	ADDM	A4,NAFTE	; UPDATE FIXUP TABLE POINTER
	ADDM	A4,LASTC1	; UPDATE 1-WORD CONSTANT CHAIN
	ADDM	A4,LASTC2	; UPDATE 2-WORD CONSTANT CHAIN

OVFL3:	ADDM	A4,CONEND	; UPDATE POINTER TO END OF CONSTANT TABLE
	ADDM	A4,STACKB	; UPDATE BASE OF STACK
	MOVE	A4,OVA		; RESTORE A4
	MOVE	A5,OVB		; RESTORE A5
	MOVE	A6,OVC		; RESTORE A6
	MOVE	A3,OVD		; RESTORE A3
	POPJ	SP,		; EXIT OVFL1 OR OVFL2


	; CONSTANTS TABLE OVERFLOW

OVFL2:	PUSHJ	SP,OVFLS	; SAVE SOME REGISTERS
	MOVE	A4,CONEND	; BASE OF CORE TO MOVE
	PUSHJ	SP,OVFL		; MOVE IT
	JRST	OVFL3		; CONTINUE


OVFL:	MOVEI	A5,DELTA	; LENGTH OF CORE TO ACQUIRE
	ADDB	A5,COREND	; NEW END OF LOW SEGMENT
	HRRZM	A5,.JBFF	; SET JOBFF
	CORE	A5,		; GET SOME MORE CORE
	JRST	OVFLX		; -CANT GET IT
	MOVE	A5,COREND	; GET NEW END OF CORE
	ADDI	A5,1-DELTA	; BLT "TO" ADDRESS
	HRLI	A5,-DELTA(A5)	; BLT "FROM" ADDRESS
	JRST	OVFLL1		; JUMP INTO MOVE LOOP
OVFLL:	MOVE	A3,A5		; COPY BLT PARAM TO A3
	BLT	A3,DELTA-1(A5)	; MOVE A DELTA OF CORE
	SUB	A5,[		; COMPUTE THE NEXT BLT CONSTANT
	XWD	DELTA,DELTA]	; BACK UP TO NEXT DELTA

OVFLL1:	HLRZ	A6,A5		; GET THE "FROM" ADDRESS
	CAILE	A6,(A4)		; IF ABOVE THE BASE OF CORE TO MOVE
	JRST	OVFLL		; THEN CONTINUE LOOPING
	HRL	A4,A4		; FORM A NEW BLT POINTER FOR
	ADDI	A4,DELTA	; CORE OF SIZE LESS THAN DELTA
	MOVE	A3,A4		; COPY BLT CONSTANT TO A3
	BLT	A3,DELTA-1(A5)	; MOVE THE LESS THAN DELTA CORE
	MOVE	A4,[		; CORRECTION FACTOR FOR DISPLAY POINTERS
	XWD	DELTA,DELTA]	; VALUE
	MOVEI	A5,DBASE	; HEAD OF CHAIN
	ADDM	A4,(A5)		; UPDATE THE POINTER
	HLRE	A5,(A5)		; LOCATE NEXT DISPLAY POINTER IN CHAIN
	JUMPG	A5,.-2		; LOOP UNLESS END OF LIST
	MOVEI	A5,DBASE+1	; HEAD OF CHAIN
	ADDM	A4,(A5)		; UPDATE THE POINTER
	HLRE	A5,(A5)		; LOCATE NEXT DISPLAY POINTER IN CHAIN
	JUMPG	A5,.-2		; LOOP UNLESS END OF LIST
	MOVEI	A4,DELTA	; UPDATE FACTOR
	ADD	SP,A4		; SET POINTER TO NEW LOCATION OF STACK
	POPJ	SP,		; EXIT OVFL


OVFLX:	OUTSTR	OVFLXM	; SEND MSG TO TTY
	JRST	TERMIN		; TERMINATE COMPILATION

OVFLXM:	ASCIZ	/?MORE CORE REQUIRED
/
OVFLS:	MOVEM	A4,OVA		; SAVE A4
	MOVEM	A5,OVB		; SAVE A5
	MOVEM	A6,OVC		; SAVE A6
	MOVEM	A3,OVD		; SAVE A3
	POPJ	SP,		; EXIT OVFLS

	; STACK OVERFLOW ALLOCATING STACK LOCALS

OVFL5:	MOVEM	A4,OVA		; SAVE ACC A4
	MOVE	A4,.STOVE	; GET RETURN LINK
	MOVEM	A4,.JBTPC	; SAVE IN JOBTPC
	JRST	.+2		; SKIP

	; STACK OVERFLOW BY PUSH OR PUSHJ

OVFL4:	MOVEM	A4,OVA		; SAVE IN ACC A4
	MOVEI	A4,DELTA	; CORE INCREMENT
	ADDB	A4,COREND	; NEW END OF LOW SEGMENT
	HRRZM	A4,.JBFF	; SET JOBFF
	CORE	A4,		; GET MORE CORE
	JRST	OVFLX		; -NOT AVAILABLE, TERMINATE
	HRLZI	A4,-DELTA	; CORRECTION CONSTANT
	ADD	SP,A4		; FIX UP STACK POINTER
	MOVE	A4,OVA		; RESTORE ACC A4
	JRST	2,@.JBTPC	; RETURN TO COMPILATION



	RELOC

OVA:	BLOCK	1
OVB:	BLOCK	1
OVC:	BLOCK	1
OVD:	BLOCK	1
.STOVE:	BLOCK	2		; RETURN LINK
;	JRST	OVFL5		; JUMP INTO HIGH SEGMENT

	RELOC
SUBTTL  ** NEW-LINE **

;	*** NEW-LINE ROUTINE ***
;
;	THIS ROUTINE IS CALLED WHENEVER A CARRIAGE-RETURN, LINE-FEED,
;	OR OTHER SUCH CHARACTER IS SCANNED.  NEWLINE PERFORMS ALL I/O
; 	PROCESSING ASSOCIATED WITH THE SOURCE AND LISTING FILES.
;	NEWLINE RETURNS IN REGISTER A1 THE 1ST CHAR OF THE NEXT
;	LINE.  REGISTERS A1 - A6 ARE NOT SAFE OVER NEWLINE.
;
;
;	THROUGHOUT THE COMPILER, CHARACTERS ARE SCANNED WHERE THEY SIT
;	IN THE SOURCE BUFFER RING.  CHARACTERS ARE READ WITH AN "ILDB".
;	THE LISTING IS FORMED BY TRANSFERING CHARACTERS FROM THE SOURCE
;	BUFFER RING TO THE LISTING BUFFER RING WITH A "BLT" INSTRUCTION.
;	A "BLT" IS 20 TIMES FASTER PER CHARACTER THAN AN "IDPB", ALTHOUGH
;	THERE IS A GREATER OVERHEAD INVOLVED AT THE BEGINNING OF EACH LINE.
;
;	THE FOLLOWING ARE SOME OF THE CHARACTERISTICS OF THE "NEWLINE" ROUTINE:
;
;	1.)  THE POSITIONS OF THE CHARACTERS IN THE WORDS MUST BE THE SAME
;	IN THE SOURCE AND LISTING BUFFERS.  THEREFORE, ANYTHING ELSE THAT APPEARS
;	IN THE LISTING MUST BE ARRANGED IN STRINGS THAT ARE A MULTIPLE OF
;	5 CHARACTERS AND WHICH ARE MOVED TO THE LISTING WITH IDPB'S.
;	THIS INCLUDES THE LINE PREFIX (ON THE FRONT OF EACH LINE OF ALGOL
;	TEXT IN THE LISTING), WHICH ALSO MUST BE A MULTIPLE OF 8 PRINTABLE
;	CHARACTERS SO THAT TABS ALIGN CORRECTLY.
;
;	2.)  THE LINE IS MOVED FROM THE SOURCE BUFFER RING TO THE LISTING BUFFER
;	RING AFTER THE LINE HAS BEEN SCANNED, SINCE UNTIL THEN THE EXTENT
;	OF THE LINE IS NOT KNOWN.  WHENEVER A NEW SOURCE BUFFER IS OBTAINED
;	FROM THE SOURCE DEVICE, A WORD CONTAINING A CR/LF IS INSERTED AFTER
;	THE DATA IN THE BUFFER TO MARK ITS END.  THUS, WHENEVER A CR IS SCANNED
;	A CHECK MUST BE MADE TO SEE IF  IT IS THE END OF THE BUFFER.

;	3.)  A CONSIDERABLE AMOUNT OF CODE IS DEDICATED TO HANDLING THE
;	FOLLOWING EXCEPTIONAL CASES:  WHEN THE LINE WONT FIT IN WHAT IS LEFT
;	OF THE OUTPUT BUFFER ("SHOB1" AND "SHOB2"),  AND WHEN THE SOURCE
;	LINE IS SPLIT OVER TWO INPUT BUFFERS ("INEND" AND "SHIB").
;	WHEN THE INPUT LINE IS SPLIT OVER TWO INPUT BUFFERS, THE 1ST PART
;	MUST BE SAVED (IN "TMPBUF") WHILE THE 2ND PART IS BEING SCANNED,
;	SINCE ONCE THE NEW INPUT BUFFER IS OBTAINED, THE OLD INPUT BUFFER IS
;	NO LONGER RELIABLE.
				; THE RIGHT HALF OF RFLAGS CONTAINS
				; THE ADDRESS OF ONE OF THE FOLLOWING:
				;    NORMAL:
				;    NOLIST:
				;    NLIST1:
				;    ENDPRG:

NEWLINE: MOVEM	A7,A7SAV	; SAVE A7
	MOVE	A7,RFLAGS	; GET READ MODULE FLAGS
	JRST	(A7)		; GO TO APPROPRIATE ROUTINE


	; LISTING EXISTS AND WAS ON

NORMAL:	SETCM	A2,A7		; IF SOURCE
	TLNN	A2,TTY!LTTY	; AND LISTING ARE TTY
	JRST	NLIST1		; THEN SUPRESS LISTING
	TRNN	FL,LISTOO	; DID HE TURN LISTING OFF?
	JRST	TURNOF		; -YES

	; LISTING EXISTS AND IS ON

TURNON:	MOVE	A2,P		; PUT READ POINTER IN A2
	TLNE	A7,ESWIT	; IF LINE NUMBERS IN 73-80
	MOVE	A2,LINEND	; THEN GET TRUE READ POINTER
	MOVEM	A2,P		; SAVE TRUE READ POINTER
	CAMN	A2,IBEND	; AT END OF INPUT BUFFER?
	JRST	INEND		; -YES, GET ANOTHER
	TLO	A7,WITHIN	; WE ARE WITHIN THE NEWLINE ROUTINE

	; PRINT THE 1ST BATCH OF MESSAGES

	MOVEI	A5,MTABLE	; ADDR OF MESSAGE TABLE
	CAML	A5,NAMTE	; IF END OF TABLE
	JRST	NL2		; THEN NO MESSAGES TO PRINT
	SETZM	LMSGS		; SET LMSG SWITCH TO "1ST PASS"
	PUSHJ	SP,LMSG		; PRINT 1ST GROUP OF MESSAGES

NL2:	SKIPLE	FFCNT2		; IF THERE ARE FORM-FEEDS THAT HAVE NOT
	PUSHJ	SP,INSFF	; YET BEEN PUT IN LISTING, PUT THEM THERE
	PUSHJ	SP,CREFNL	; IF CREF, DO CREF STUFF

	; MAKE SURE THAT THERE IS ROOM IN OUTPUT BUFFER FOR 1ST PART OF LINE

	MOVEI	A1,.SPACE	; PUT A BLANK IN ACC A1
	MOVE	A4,W		; GET WRITE POINTER
	TLNE	A7,LTTY		; IF THE LISTING IS TO THE TTY
	JRST	NL15		; THEN PRODUCE A DIFFERENT LISTING
	MOVEI	A4,5(A4)	; GO AHEAD 5 WORDS
	CAML	A4,OBEND	; AT END OF BUFFER?
	PUSHJ	SP,SHOB1	; -YES, GET ANOTHER
	; PRINT PROGRAM COUNTER

	SETZM	(A4)		; CLEAR 1ST CHARS OF TEXT
	MOVEI	A5,6		; PRINT 6 CHARS
	TLNE	A7,TMG		; IF NO REL FILE
	JRST	NL18		; THEN DONT PRINT PC
	MOVE	A4,[		; LOAD A POINTER TO
	POINT	3,RA,17]	; PROGRAM COUNTER

NL1:	ILDB	A6,A4		; GET 3 BITS
	MOVEI	A6,.N0(A6)	; CONV TO ASCII
	IDPB	A6,W		; PUT IN LISTING
	SOJG	A5,NL1		; LOOP

NL19:	IDPB	A5,W		; INCLUDE A NULL

	; PRINT BEGIN NUMBER

	MOVE	A4,BNUM		; LOAD BEGIN NUMBER
	CAMN	A4,LBNUM	; COMPARE TO LAST BEGIN NUMBER
	JSP	A3,NL3		; -SAME, PRINT SOME BLANKS
	MOVEM	A4,LBNUM	; SAVE AS LAST BEGIN NUMBER
	MOVEI	A2,.B		; WRITE A "B"
	MOVEI	A3,5		; WRITE 5 CHARS
	PUSHJ	SP,DEC		; WRITE IT

	; PRINT END NUMBER

	MOVE	A4,ENUM		; LOAD END NUMBER
	CAMN	A4,LENUM	; COMPARE TO LST END NUMBER
	JSP	A3,NL3		; -SAME, PRINT SOME BLANKS
	MOVEM	A4,LENUM	; SAVE AS LAST END NUMBER
	MOVEI	A2,.E		; WRITE AN "E"
	MOVEI	A3,5		; WRITE 5 CHARS
	PUSHJ	SP,DEC		; CONVERT TO DECIMAL
	JRST	NL6		; CONTINUE


	; SUBROUTINE FOR PUTTING 5 BLANKS IN LISTING INSTEAD OF BEGIN/END NUMBER

NL3:	MOVEI	A5,5		; WRITE 5 BLANKS
	IDPB	A1,W		; INCLUDE A BLANK
	SOJG	A5,.-1		; LOOP
	JRST	4(A3)		; EXIT
	; PUT 6 BLANKS IN LISTING INSTEAD OF PC

NL18:	IDPB	A1,W		; PUT BLANK IN LISTING
	SOJG	A5,NL18		; LOOP 5 MORE TIMES
	JRST	NL19		; CONTINUE



	; PUT LINE NUMBER IN LISTING

NL6:	TLZN	A7,ELINE	; IF TEXT HAS A LINE NUMBER
	TLNE	A7,ESWIT	; OR NUMBERS IN 73-80
	JRST	NL5		; THEN DONT GENERATE A LINE NUMBER
	MOVE	A4,LINENO	; GET LINE NUMBER
	MOVEI	A2,.SPACE	; ACC A2 = BLANK
	MOVEI	A3,7		; PRINT 7 CHARS LONG
	PUSHJ	SP,DEC		; CONVERT TO DECIMAL
	JRST	NL7		; CONTINUE

NL5:	MOVEI	A3,0
	IDPB	A3,W		; INSERT A NULL
	IDPB	A1,W		; INCLUDE ANOTHER SPACE
	TLNN	A7,ESWIT	; IF NOT NUMBERS IN 73-80
	JRST	NL7		; THEN SKIP THIS PART
	MOVE	A2,CHAR		; GET THE SAVED CHARACTER
	DPB	A2,CHARP	; REINSERT IT INTO ITS PLACE IN THE LINE

	; READ THE LF THAT FOLLOWS THE CR

NL7:	IDPB	A1,W		; PUT BLANK IN LISTING
	MOVE	A2,P		; LOAD READ POINTER
	PUSHJ	SP,GETNL	; READ NEXT CHAR
	MOVE	A3,CTABLE(A1)	; GET TABLE ENTRY
	CAIN	A3,4		; IF IT IS A LF
	MOVEM	A1,CHAR2	; THEN SAVE THIS CHAR
	CAIE	A3,4		; IS IT A LF?
	ADD	A2,[		; BACK UP POINTER
	XWD	070000,0]	; POINTER DECREMENT CONSTANT
	; PUT 1ST WORD OF LINE TEXT IN OUTPUT BUFFER

	MOVE	A6,LSTART	; POINTER TO BEGINNING OF LAST LINE
	MOVEM	A2,LSTART	; SET NEXT LINE START
	HLLZ	A4,W		; GET WRITE POINTER S-P BITS
	ROT	A4,4		; PUT 1ST 4 BITS IN RIGHT HALF
	MOVE	A4,MSKTBL(A4)	; GET A MASK
	AND	A4,@A6		; MASK OFF EXTRANEOUS CHARS
	IORM	A4,@W		; PUT REMAINING CHARS IN LISTING

	; MOVE REMAINDER OF ALGOL TEXT TO OUTPUT BUFFER WITH A BLT

	AOS	A5,W		; STEP WRITE POINTER AND LOAD IT
	HRLI	A5,1(A6)	; STEP OLD READ POINTER
	SKIPE	TBLEN		; IS INPUT LINE SPLIT OVER 2 BUFFERS?
	JRST	SHIB		; -YES, TREAT SEPARATELY
	MOVEI	A4,(A2)		; CURRENT READ POINTER ADDRESS
	SUBI	A4,1(A6)	; CURRENT LINE LENGTH
	ADDI	A4,@W		; END OF LINE IN WRITE BUFFER

	;
	; Edit(1005)  Deal with very long source lines correctly
	;
NL14:	CAMGE	A4,OBEND	; [E1005] WILL LINE OVERFLOW OUTPUT BUFFER?
	JRST	.+3		; [E1005] - NO, SO OK
	PUSHJ	SP,SHOB2	; [E1005] - YES, HANDLE WITH CARE
	JRST	NL14		; [E1005] TRY AGAIN
	CAIL	A4,(A5)		; NEGATIVE LENGTH?

NL13:	BLT	A5,(A4)		; MOVE THE LINE
	HLL	A4,A2		; FORM NEW WRITE POINTER
	MOVEM	A4,W		; SAVE IT

	; PRINT 2ND BATCH OF MESSAGES

NL10:	PUSHJ	SP,GETNL	; STEP TO NEXT CHAR
	MOVEI	A5,MTABLE	; ADDR OF MESSAGE TABLE
	CAML	A5,NAMTE	; IF NO MESSAGES IN TABLE
	JRST	NL9		; THEN SKIP THIS PART
	SETOM	LMSGS		; SET LMSG SWITCH TO 2ND PASS
	PUSHJ	SP,LMSG		; PRINT REST OF MSGS
	MOVEI	A1,MTABLE	; START OF MESSAGE TABLE
	MOVEM	A1,NAMTE	; SET POINTER TO START OF TABLE

	; PROCESS ANY FORM FEEDS

NL9:	LDB	A1,A2		; GET THE NEXT CHAR
	JUMPN	A1,.+3		; SKIP THIS IF NOT A NULL
	PUSHJ	SP,GETNL	; READ THE NEXT CHAR
	JUMPE	A1,.-1		; READ ANOTHER IF IT IS A NULL
	TLZ	A7,WITHIN	; WE ARE ABOUT TO EXIT THE NEWLINE ROUTINE
	CAIE	A1,.FF		; IF IT IS NOT A FORM-FEED
	JRST	NL11+1		; THEN SKIP THIS PART
	PUSHJ	SP,FFOUND	; PROCESS THE FORM-FEED
	JRST	NL9+2		; LOOK FOR ANOTHER FORM-FEED
	; SKIP OVER ANY NULLS AT BEGINNING OF NEXT LINE

NL11:	PUSHJ	SP,GETNL	; READ NEXT CHAR
	JUMPE	A1,NL11		; READ AGAIN IF A NULL

	; PROCESS LINE NUMBER IF ANY

	TLNE	A7,ESWIT	; IF NUMBERS IN 73-80
	JRST	COL73		; THEN SCAN THE LINE NUMBER
	MOVE	A4,LINENO	; GET OLD LINE NUMBER
	MOVE	A5,(A2)		; PICK UP FIRST WORD
	TRNN	A5,1		; IS IT A LINE NUMBER?
	AOJA	A4,NL8		; -NO, INCREMENT LINE NO. AND SKIP
	CAIN	A1,.SPACE	; IF LINE NUMBER IS BLANK
	JRST	BLN		; THEN JUMP
	MOVEI	A5,4		; SCAN NEXT 4 CHARS
	MOVEI	A4,-.N0(A1)	; CONVERT 1ST CHAR TO DECIMAL
	PUSHJ	SP,GETNL	; GET NEXT CHAR
	IMULI	A4,^D10		; MULTIPLY PREVIOUS RESULT BY 10
	ADDI	A4,-.N0(A1)	; ADD IN CURRENT CHAR
	SOJG	A5,.-3		; LOOP
	PUSHJ	SP,GETNL	; SKIP OVER TAB
	SOS	CC		; DONT COUNT THIS AS A POSITION
	CAIN	A1,.FF		; IF IT IS A FORM-FEED
	PUSHJ	SP,FFOUND	; THEN PROCESS IT
	CAIE	A1,.TAB		; IF IT IS NOT A TAB
	JRST	NOTAB		; THEN TREAT SEPARATELY

NL16:	PUSHJ	SP,GETNL	; GET NEXT CHAR
	CAIE	A1,.FF		; IF IT IS NOT A FORM-FEED
	JRST	.+3		; THEN SKIP THIS PART
	PUSHJ	SP,FFOUND	; PROCESS IT
	JRST	NL16		; READ ANOTHER CHAR
	TLO	A7,ELINE	; MARK: EDITOR LINE NUMBER SCANNED
	; SAVE ALL LINE POINTERS

NL8:	MOVE	A5,CC		; GET POSITION COUNT
	EXCH	A4,LINENO	; SET NEW LINE NUMBER
	EXCH	A5,LP1		; SET START OF CURRENT LINE
	TLZE	A7,BLANKL	; IF THIS WAS A BLANK LINE
	JRST	.+3		; THEN SKIP
	MOVEM	A4,OLDNO	; SET OLD LINE NUMBER
	MOVEM	A5,LP2		; SET START OF PRECEDING LINE

	; CHECK FOR A BLANK LINE

	MOVE	A5,CTABLE(A1)	; GET CHARS TABLE ENTRY
	CAIN	A5,4		; IF IT IS A NEW LINE CHAR
	TLO	A7,BLANKL	; THEN MARK THIS A BLANK LINE

	; EXIT FROM NEWLINE

	MOVEM	A2,P		; SAVE READ POINTER
	PUSHJ	SP,CREFST	; O/P CREF START DATA, IF WE'RE CREF'ING
	MOVEM	A7,RFLAGS	; STORE READ-MODULE FLAGS
	MOVE	A7,A7SAV	; RESTORE A7
	JRST	SKRET		; EXIT NEWLINE
SUBTTL	** SUBROUTINES OF NEWLINE  **

	; ROUTINES FOR CROSS-REFERENCING.

CREFIT:	; ENTER WITH LEXEME OF IDENTIFIER IN A1. CALLED FROM SEARCH.
	MOVE	A2,SYMNAM(A1)	; GET FIRST WORD OF NAME
	ANDI	A2,77		; GET # CHARS - 1
	ADDI	A2,1
	DPB	A2,[POINT 7,CREFRF,13]	; PUT INTO CREF DATA
	ADDI	A2,3		; ALLOW FOR ^A^? AND POSSIBLE ^B
	ADDM	A2,CRFCNT	; UPDATE CHAR-COUNTER
	PUSHJ	SP,NAME		; GET NAME IN ASCIZ
	MOVEI	A1,CREFRF
	EXCH	A7,RFLAGS	; GET READ-MODULE FLAGS
	PUSHJ	SP,INSERT	; OUTPUT (<DEL> B) ^A^?
	MOVEI	A1,LB		; WHERE NAME ROUTINE LEFT IT
	PUSHJ	SP,INSERT	; SYMBOL NAME
	MOVEI	A1,CREFDF	; DEFINITION FLAG
	HRRZ	A2,NDEL		; GET TERMINATING DELIMITER,
	CAIN	A2,15		; AND IF IT IS A COLON THEN
	JRST	CREFLB		; THIS IS A LABEL DEFINITION
	TRNN	FL,DECLAR	; DECLARATION ?
	SOSA	CRFCNT		; NO - DON'T ALLOW FOR ^B IN COUNT OF CHARS
CREFLB:	PUSHJ	SP,INSERT	; YES - TELL CREF
	EXCH	A7,RFLAGS	; PUT READ-MODULE FLAGS AWAY.
	POPJ	SP,		; BACK TO SEARCH

CREFNL:	; CALLED BY NEWLINE JUST BEFORE PRINTING SOURCE-LINE
	MOVEI	A1,CREFND	; END CREF DATA
	JRST	CRFNL3

CRFNL2:	MOVEI	A1,[BYTE(7)177,"D"]  ; <DEL>D - END CREF DATA - NO LINE #

CRFNL3:	SKIPE	CRFCNT		; ANY CREF'ING DONE ON THIS LINE ?
	TRNN	FL,CREF		; ANY CREF'ING AT ALL ?
	POPJ	SP,		; NO
	PUSHJ	SP,INSERT	; <DEL> A
	AOS	CRFCNT		; ALLOW FOR <DEL>A
	AOS	A1,CRFCNT	; # OF CHARACTERS OUTPUT BY CREF
	IDIVI	A1,5		; 
	JUMPE	A2,CRFNL1	; WHOLE # OF WORDS ?
	SUBI	A2,5
	MOVEM	A2,CRFCNT	; NO - MUST MAKE IT SO
	PUSHJ	SP,INSNUL	; BY PUTTING IN NULLS
	AOSE	CRFCNT		; ENOUGH ?
	JRST	.-2		; NO

CRFNL1:	SETZM	CRFCNT		; CLEAR COUNT
	POPJ	SP,
CREFST:	; OUTPUT START-OF-CREF DATA, IF REQUIRED.
	SKIPN	CRFCNT		; NOT ALREADY STARTED, AND...
	TRNN	FL,CREF		; CREF ?
	POPJ	SP,		; NO
	PUSH	SP,A1		; YES - SAVE A1 (USED IN NEWLINE)
	MOVEI	A1,[BYTE(7)177,"B"]  ;<DEL>B - START CREF DATA
	PUSHJ	SP,INSERT	; OUTPUT IT
	MOVEI	A1,2		; UPDATE
	ADDM	A1,CRFCNT	;  CREF COUNTER
	POP	SP,A1
	POPJ	SP,

CREFDF:	BYTE(7)2,0,0,0,0	; ^B (DEFINITION FLAG)
CREFND:	BYTE(7)177,"A",0,0,0	; <DEL> A (END OF CREF DATA)

	RELOC

CREFRF:	BLOCK	1
;	BYTE(7)1,0,0,0,0	; ^A (SYMBOL REF. 2ND BYTE PLUGGED WITH LENGTH)
CRFCNT:	BLOCK	1		; # OF CHARS O/P BY CREF

	RELOC
	; BRIEF FORM OF LISTING FOR WHEN SENT TO TTY

NL15:	TLNN	A7,ELINE	; IF THERE IS AN EDITOR'S LINE NUMBER
	TLNE	A7,ESWIT	; OR NUMBERS IN 73 - 80
	JRST	NL7+1		; THEN DONT GENERATE ANOTHER ONE
	MOVEI	A4,2(A4)	; END OF WHERE LINE PREFIX WILL GO
	CAML	A4,OBEND	; IF PAST END OF BUFFER
	PUSHJ	SP,SHOB1	; THEN GET ANOTHER OUTPUT BUFFER
	MOVE	A4,LINENO	; GET THE CURRENT LINE NUMBER
	MOVEI	A2,.SPACE	; PRECEDE WITH A SPACE
	MOVEI	A3,7		; FIELD IS 7 CHARS WIDE
	PUSHJ	SP,DEC		; PUT LINE NUMBER IN LISTING
	IDPB	A3,W		; PUT AN ASCII NULL IN LISTING
	IDPB	A3,W		; PUT IN ANOTHER ONE
	JRST	NL7		; CONTINUE



	; LISTING EXISTS BUT WAS OFF

NOLIST:	TRNN	FL,LISTOO	; IF SO, IS IT CURRENTLY ON?
	JRST	NLIST1		; -NO, CONTINUE WITH NO LISTING
	HRRI	A7,NORMAL	; TIME TO TURN LISTING BACK ON
;[223] LSTART AND W MUST BE THE SAME BYTE OFFSET WHEN THE LISTING RESUMES.
	HLRZ	A1,LSTART	;[223] GET THE SOURCE'S OFFSET
	SETZ	A4,		;[223] CREATE A NULL BYTE
NLIST3:	HLRZ	A2,W		;[223] GET W'S OFFSET (LISTING'S OFFSET)
	CAMN	A2,A1		;[223] ARE THEY THE SAME?
	 JRST	TURNON		;[223] YES, EVERYTHING IS OK
	IDPB	A4,W		;[223] NO, WRITE A NULL BYTE
	JRST	NLIST3		;[223] AND LOOP

	; TURN LISTING OFF

TURNOF:	HRRI	A7,NOLIST	; TURN LISTING OFF

	; LISTING IS OFF

NLIST1:	MOVE	A2,P		; LOAD READ POINTER
	TLNE	A7,ESWIT	; IF NUMBERS IN 73-80
	MOVE	A2,LINEND	; GET TRUE READ POINTER
	MOVEM	A2,P		; SAVE TRUE VALUE
	CAMN	A2,IBEND	; AT END OF INPUT BUFFER?
	JRST	INEND		; -YES, GET A NEW INPUT BUFFER
	TLO	A7,WITHIN	; WE ARE WITHIN THE NEWLINE ROUTINE
	MOVEM	A2,LSTART	; SAVE POINTER FOR LATER
	SETZM	SSTART		; CLEAR SEGMENT START MARKER
	SETZM	TBLEN		; EMPTY OUT TMPBUF

	; PRINT 1ST BATCH OF MESSAGES

	MOVEI	A5,MTABLE	; ADDR OF MESSAGE TABLE
	CAML	A5,NAMTE	; IF NO MESSAGES IN TABLE
	JRST	NLIST2		; THEN SKIP THIS PART
	SETZM	LMSGS		; SET LMSG SWITCH TO 1ST PASS
	PUSHJ	SP,LMSG		; PRINT MESSAGES
	; READ THE LF THAT FOLLOWS THE CR

NLIST2:	PUSHJ	SP,GETNL	; GET NEXT CHAR
	MOVE	A4,CTABLE(A1)	; GET TABLE ENTRY
	CAIE	A4,4		; IT IS NORMALLY A LF
	JRST	NL10+1		; -NO, CONTINUE WITHOUT STEPPING READ POINTER
	MOVEM	A2,LSTART	; SAVE READ POINTER
	MOVEM	A1,CHAR2	; SAVE THIS CHAR
	JRST	NL10		; CONTINUE

;	"GETNL" WILL READ THE NEXT CHARACTER OF THE SOURCE TEXT.  "GETNL" 
;	MUST BE USED WHENEVER A CHARACTER IS TO BE READ WITHIN "NEWLINE".
;	"GETNL" WILL CALL "INEND" IF AN END OF BUFFER OCCURRS.


GETNL:	ILDB	A1,A2		; GET NEXT CHAR
	AOS	CC		; STEP POSITION COUNT
	CAME	A2,IBEND	; UNLESS AT END OF INPUT BUFFER
	POPJ	SP,		; EXIT GETNL
	MOVEM	A2,P		; INEND WANTS POINTER SET
	PUSHJ	SP,INEND	; READ NEXT INPUT BUFFER
	MOVE	A7,RFLAGS	; RELOAD READ MODULE FLAGS
	MOVE	A2,P		; RELOAD READ POINTER
	JRST	GETNL+2		; TEST AGAIN
;	"INEND" IS CALLED WHENEVER THE END OF AN INPUT BUFFER IS REACHED.
;	"INEND" WILL MOVE THE 1ST PART OF THE SPLIT INPUT LINE TO "TMPBUF"
;	AND THEN CALL "READ" TO OBTAIN THE NEXT INPUT BUFFER.

INEND1:	MOVEM	A2,NLR+4	; SAVE A2
	MOVE	A2,A1		; MOVE READ POINTER TO A2
	MOVEM	A7,A7SAV	; SAVE A7
	MOVE	A7,RFLAGS	; GET READ MODULE FLAGS

INEND:	MOVEM	A4,NLR		; SAVE A4
	MOVEM	A5,NLR+1	; SAVE A5
	MOVEM	A6,NLR+2	; SAVE A6
	MOVEM	A3,NLR+3	; SAVE A3
	HRRZ	A6,A2		; GET READ POINTER
	SKIPN	A5,SSTART	; UNLESS LINE ALREADY BROKEN ONCE
	MOVE	A5,LSTART	; GET START OF LINE SEGMENT
	SUBI	A6,(A5)		; LENGTH OF DATA TO MOVE
	MOVEI	A4,TMPBUF-1(A6)	; END OF LINE IN TEMPBUF
	HRLZI	A5,(A5)		; MOVE SEGMENT FROM RING BUFFER
	HRRI	A5,TMPBUF	; TO TEMP BUFFER
	HRRM	A5,LSTART	; SET NEW VALUE FOR LSTART
	ADD	A4,TBLEN	; ADD TO WHAT IS IN TMPBUF
EDIT(025); BE MORE INFORMATIVE IF WE ARE GIVING UP
	CAIGE	A4,BUF0		; [E025] WILL IT ALL FIT IN TMPBUF ?
	 JRST	INEND2		; [E025] YES - CARRY ON
	OUTSTR	[ASCIZ	/
? SOURCE STATEMENT TOO LONG /]	; [E025] NO  - TELL USER
	JRST	TERMIN		; THEN GIVE UP
INEND2:	ADD	A5,TBLEN	; [E025] ADD TO WHAT IS IN TMPBUF
	ADDM	A6,TBLEN	; ADDITIONAL LENGTH OF TMPBUF
	BLT	A5,(A4)		; MOVE LINE
	PUSHJ	SP,READ		; READ NEXT BUFFER

INEND5:	MOVE	A5,P		; GET NEW POINTER
	MOVEI	A5,1(A5)	; ADD 1
	MOVEM	A5,SSTART	; SAVE THIS ADDR
	ILDB	A1,P		; READ 1ST CHAR
	CAIN	A1,.CZ		; IF THIS IS A CONTROL-Z
	JRST	INEND4		; THEN READ AGAIN
	MOVEM	A7,RFLAGS	; SAVE READ-MODULE FLAGS
	MOVE	A7,A7SAV	; RESTORE A7
	MOVE	A4,NLR		; RESTORE A4
	MOVE	A5,NLR+1	; RESTORE A5
	MOVE	A6,NLR+2	; RESTORE A6
	MOVE	A3,NLR+3	; RESTORE A3
	MOVE	A2,NLR+4	; RESTORE A2
	POPJ	SP,		; EXIT NEWLINE

INEND4:	PUSHJ	SP,READ1	; CALL INEND BUT DONT PRINT A LINE NUMBER ON TTY
	JRST	INEND5		; CONTINUE
;	IF THE SOURCE DEVICE IS A TTY, "READ" WILL SEND THE NEXT LINE NUMBER
;	TO THE TTY.  THEN "READ" WILL OBTAIN THE NEXT BUFFER FROM THE SOURCE
;	DEVICE, AND MARK THE END OF DATA IN IT WITH A WORD CONTAINING A
;	CR/LF.

READ:	TLNN	A7,TTY		; IS SOURCE DEVICE A TTY?
	JRST	READ1		; -NO, SKIP WRITING A LINE NUMBER
	TLNN	A7,WITHIN	; IF WITHIN THE NEWLINE ROUTINE
	JRST	READ1		; THEN PRINT NUMBER ELSE SKIP THIS PART
	PUSH	SP,W		; SAVE W
	MOVEI	A5,BUF0
	HRLI	A5,440700
	MOVEM	A5,W		; SET UP BYTE POINTER
	MOVE	A4,LINENO	; GET CURRENT LINE NUMBER
	ADDI	A4,1		; INCREMENT IT
	MOVEI	A2,.SPACE
	MOVEI	A3,7
	PUSHJ	SP,DEC		; PRINT LINE NO.
	MOVEI	A4,.SPACE	; LOAD A BLANK
	IDPB	A4,W		; PUT THE BLANK IN BUFFER
	MOVEI	A4,0
	IDPB	A4,W		; AND FINISH WITH A NULL
	POP	SP,W		; RESTORE W
	OUTSTR	BUF0		; OUTPUT LINE NUMBER

READ1:	IN	3,0		; INPUT NEXT BUFFER
	JRST	INOKA		; -SUCCESSFUL READ
	STATO	3,710000	; WAS IT A READ ERROR?
	JRST	EOF		; -NO, JUST END OF FILE
	OUTSTR	INERRM	; WRITE ERROR MSG
	JRST	TERMIN		; TERMINATE COMP


INERRM:	ASCIZ	/?INPUT ERROR
/


	; INPUT BUFFER READ SUCCESSFULLY

INOKA:	MOVE	A6,BHEAD3	; ADDR OF CURRENT BUFFER
	HRRZ	A5,1(A6)	; LENGTH OF BUFFER IN WORDS
	JUMPE	A5,READ		; IF EMPTY GET ANOTHER BUFFER
	ADD	A5,P		; ADDR OF END OF BUFFER
	SKIPN	(A5)		; BACKUP OVER NULLS
	SOJA	A5,.-1
	MOVE	A4,NLCHRS	; LOAD A CR/LF
	MOVEM	A4,1(A5)	; PUT IT AT END OF BUFFER
	ADD	A5,[		; HOW POINTER WILL LOOK AT
	XWD	350000,1]	; END OF BUFFER
	MOVEM	A5,IBEND	; STORE FOR LATER COMPARISON
	POPJ	SP,		; EXIT INEND
	; END-OF-FILE ENCOUNTERED

EOF:	MOVE	A4,BHEAD3	; LOCATE CURRENT BUFFER RING
	MOVEM	A4,OLDSBR	; SAVE ITS ADDRESS
	CLOSE	3,0		; CLOSE SOURCE FILE
	SKIPG	CSCOMP		; IF NO MORE SOURCE FILES
	JRST	ENDPRG		; THEN RETURN EOF LEXEME
	TLZ	A7,ESWIT	; TURN OFF 73-80 INDICATOR
	SETZM	CSCOMP		; CLEAR SWITCH
	PUSHJ	SP,SCAN3	; SCAN NEXT SOURCE FILE AND OPEN IT
	JRST	READ		; READ 1ST BUFFER

	; END OF SOURCE DATA (NO MORE SOURCE FILES)

ENDPRG:	HRRI	A7,ENDPRG	; LSCAN WILL READ NO MORE
	MOVEM	A7,RFLAGS	; SAVE READ-MODULE FLAGS
	MOVE	A7,A7SAV	; RESTORE A7
	MOVE	A2,[		; SET UP A POINTER TO
	POINT	7,NLCHRS]	; A NEW-LINE CHAR
	MOVEM	A2,P		; PUT IN READ POINTER
	MOVE	A3,ZEOF		; OUTPUT END-OF-FILE LEXEME

	; RETURN TO CALLER OF LSCAN

EOF5:	POP	SP,A4		; GET RETURN LINK
	MOVEI	A4,(A4)		; CLEAR LEFT HALF
	CAIN	A4,EMPTY
	JRST	EMPTY1		; NULL FILE
	CAIE	A4,RUND0
	CAIN	A4,RUND5	; IF IT IS ONE OF THESE
	JRST	(A4)		; THEN GO THERE
	JRST	EOF5		; ELSE ASCEND ANOTHER LEVEL

NLCHRS:	ASCIZ	/
/
	; NO ROOM IN OUTPUT BUFFER FOR LINE PREFIX

SHOB1:	HLRZ	A5,W		; GET OLD S-P BITS
	PUSHJ	SP,WRITEL	; GET NEXT BUFFER
	AOS	A4,W		; STEP WRITE POINTER, LOAD IT
	SETZM	(A4)		; ZERO 1ST WORD OF LINE IN BUFFER
	SETZM	5(A4)		; ZERO 6TH WORD OF LINE IN BUFFER
	HRLM	A5,W		; SET NEW WRITE POINTER
	POPJ	SP,		; CONTINUE



	; NO ROOM IN OUTPUT BUFFER FOR THE ALGOL TEXT

SHOB2:	SOS	A6,OBEND	; LAST WORD IN BUFFER
	CAIGE	A6,(A5)		; IF FULL UP
	JRST	SHOB3		; THEN SKIP THIS
	MOVE	A3,A5		; SAVE A5
	BLT	A5,(A6)		; AND FILL UP BUFFER
	MOVE	A5,A3		; RESTORE A5

SHOB3:	HRLI	A6,010700
	MOVEM	A6,W		; SET UP W
	SUBI	A4,(A6)		; REMAINDER
	SUBI	A6,-1(A5)	; AMOUNT TRANSFERRED
	HRLZI	A6,(A6)
	ADD	A5,A6		; MOVE UP INPUT POINTER
	PUSHJ	SP,WRITEL	; GET NEW OUTPUT BUFFER
	ADDI	A4,@W		; STOP ADDRESS FOR BLT
	AOS	W		; STEP WRITE POINTER
	HRR	A5,W		; SET UP OUTPUT POINTER
	POPJ	SP,		; [E1005] AND TRY AGAIN

	; INPUT LINE WAS SPLIT OVER 2 INPUT BUFFERS

SHIB:	SOS	A4,TBLEN	; A4=LENGTH OF FIRST PART
	ADDI	A4,@W		; STOP ADDR FOR BLT
	CAMGE	A4,OBEND	; WILL THIS OVERFLOW BUFFER?
	JRST	SHIB1		; -NO, SKIP

	; 1ST PART OF INPUT LINE WILL NOT FIT IN OUTPUT BUFFER

	PUSH	SP,A6		; [E1005] SAVE A6
	PUSHJ	SP,SHOB2	; [E1005] SEND WHAT WE CAN
	POP	SP,A6		; [E1005] RESTORE A6
	JRST	SHIB+2		; [E1005] AND TRY AGAIN
SHIB1:	CAIG	A4,(A5)		; SKIP BLT IF LENGTH NEGATIVE
	JRST	.+3		; -YES, SKIP
	MOVE	A3,A5		; MOVE TO ACC A3
	BLT	A3,-1(A4)	; MOVE 1ST PART OF LINE
	MOVEM	A4,W		; SET W JUST IN CASE SHOB2 IS CALLED
	MOVEI	A5,(A4)		; WHERE 2ND PART WILL START
	HRL	A5,SSTART	; WHERE 2ND PART NOW SITS
	ADDI	A4,(A2)		; ADD CURRENT POINTER ADDR
	SUB	A4,SSTART	; STOP ADDR FOR BLT
	SETZM	TBLEN		; ZERO TBLEN
	SETZM	SSTART		; CLEAR SSTART
	JRST	NL14		; CONTINUE

FFOUND:	MOVEI	A1,0		; ASCII NULL
	DPB	A1,A2		; DELETE FORM FEED FROM INPUT BUFFER
	AOS	FFCNT		; STEP FORM FEED COUNNT
	AOS	FFCNT2		; STEP OTHER FORM FEED COUNT
	POPJ	SP,		; EXIT FFOUND



	; PUT FORM-FEED IN FRONT OF LINE
	;
	Edit(165);  If CREFing include FF characters in cref count
	;

INSFF:	PUSH	SP,FFCNT2	; [E162] Save number of FFs sent
	MOVEI	A1,[BYTE(7)177,"F",14]  ; PUT IN "END-OF-CREF",F.F
	TRNN	FL,CREF		; IF CREF, OTHERWISE

INSFF1:	MOVEI	A1,FORM		; ADDRESS OF A FORM-FEED
	PUSHJ	SP,INSERT	; PUT IT IN LISTING
	SOSLE	FFCNT2		; IF MORE FORM-FEEDS TO INSERT, THEN
	JRST	INSFF1		; LOOP
	POP	SP,A1		; [E165] Get saved FF count
	TRNN	FL,CREF		; IF NOT CREF
	JRST	[		; [E165]
	  PUSHJ	SP,IC2		; [E165] then tidy up
	  POPJ	SP,]		; [E165]  and exit
	IMULI	A1,3		; [E165] Get actual count of chars sent
	ADDI	A1,2		; [E162]  and include end of cref chars
	ADDM	A1,CRFCNT	;
	MOVEI	A1,[BYTE(7)177,"B"]  ; ELSE START CREF DATA FOR NEW LINE
	JRST	INSERT		; EXIT VIA INSERT
	; LINE NUMBER NOT FOLLOWED BY A TAB

NOTAB:	CAIN	A1,.CR		; IF IT IS A CARRIAGE RETURN
	JRST	.+4		; THEN SKIP THIS PART
	MOVEI	A1,.TAB		; AN ASCII TAB CHARACTER
	DPB	A1,A2		; REPLACE THE CHARACTER WITH A TAB
	JRST	NL16		; CONTINUE
	PUSHJ	SP,GETNL	; READ THE NEXT CHARACTER
	CAIN	A1,.CR		; IF IT IS A CARRIAGE RETURN
	JRST	NL8-1		; THEN IT IS PROBABLY THE SEQUENCE: CR CR LF
	MOVEI	A1,.LF		; LINE-FEED
	PUSHJ	SP,FFOUND+1	; REPLACE CR BY LF ETC.
	JRST	NL8-1		; CONTINUE



	; BLANK LINE NUMBER ENCOUNTERED

BLN:	MOVEI	A5,7		; SKIP OVER 7 CHARACTERS
	MOVEI	A6,0		; ASCII NULL
	DPB	A6,A2		; REPLACE CHARACTER WITH A NULL
	PUSHJ	SP,GETNL	; READ A CHARACTER
	SOJG	A5,.-2		; LOOP
	PUSHJ	SP,FFOUND	; NULL OUT THE FORM-FEED
	JRST	NL11		; CONTINUE
	RELOC

IBEND:	BLOCK	1		; END OF INPUT BUFFER
OBEND:	BLOCK	1		; END OF OUTPUT BUFFER
BNUM:	BLOCK	1		; BEGIN NUMBER
LBNUM:	BLOCK	1		; LAST BEGIN NUMBER
ENUM:	BLOCK	1		; END NUMBER
LENUM:	BLOCK	1		; LAST END NUMBER
LINEND:	BLOCK	1		; READ POINTER AT END OF CURRENT LINE
LINE5:	BLOCK	1		; 5 -CHAR DATASET LINE NUMBER
LSTART:	BLOCK	1		; START OF CURRENT LINE
SSTART:	BLOCK	1		; START OF CURRENT LINE SEGMENT
CHAR:	BLOCK	1		; SAVE CHAR FROM 80-COLUMN LINE
CHARP:	BLOCK	1		; SAVED CHARACTER'S RESTORATION POINTER
TBLEN:	BLOCK	1		; LENGTH OF DATA IN TMPBUF
A7SAV:	BLOCK	1		; SAVE AREA FOR A7
NLR:	BLOCK	5		; SAVE AREA FOR REGISTERS OVER NEWLINE
EDIT(025); INCREASE SIZE OF TMPBUF
TMPBUF:	BLOCK	200		; SAVED 1ST PART OF SPLIT SOURCE LINE

BUF0:	BLOCK	5

	RELOC
;	THE "COL73" ROUTINE WAS CONTRIVED AFTER THE REST OF "NEWLINE" WAS
;	WRITTEN.  "NEWLINE" HAS THE CONVENTION THAT THE LINE NUMBER MUST BE
;	KNOWN BEFORE THE LINE IS SCANNED.  "COL73" WILL CAUSE THE WHOLE
;	LINE TO BE "UNOFFICIALLY" MOVED INTO "TMPBUF" BEFORE SCANNING ANY OF
;	IT SO THAT THE LINE NUMBER CAN FIRST BE SCANNED.  HOWEVER, IF PART
;	OF THE LINE WAS MOVED THERE BY "INEND", ONLY THE LAST PART OF THE LINE
;	IS "UNOFFICIAL".  BY "UNOFFICIAL" IT IS MEANT THAT THE TEXT IS
;	NOT REALLY THERE (NOT INCLUDED IN "TBLEN", WHICH IS THE COUNT
;	OF DATA WORDS IN "TMPBUF"), AND THE LISTING WILL BE TAKEN FROM
;	TEXT IN THE SOURCE BUFFER RATHER THAN FROM "TMPBUF".  HOWEVER
;	THE SOURCE BYTE POINTER WILL POINT INTO "TMPBUF".  THE 1ST CHARACTER
;	OF THE LINE NUMBER IS EXTRACTED AND REPLACED WITH A CR SO THAT
;	THE SCANNER WILL NOT RUN INTO THE LINE NUMBER.


	; FORM READ POINTER TO TMPBUF

COL73:	MOVE	A3,A2		; COPY READ POINTER
	HRRI	A3,TMPBUF	; POINT IT TO TMPBUF
	ADD	A3,TBLEN	; IN CASE SOMETHING ALREADY IN TMPBUF
	MOVEI	A5,^D16		; PUT NEXT 17 WORDS IN TMPBUF

COL73A:	ADDI	A5,(A2)		; END OF SOURCE IN RING BUFFER
	MOVE	A6,IBEND	; END OF RING BUFFER
	CAIGE	A5,(A6)		; IF THE LINE IS ENTIRELY WITHIN RING BUFFER
	JRST	COL73B		; THEN SKIP THIS PART

	; USE INEND TO PUT PART OF LINE IN TMPBUF

	MOVE	A2,LSTART	; GET LINE START
	SKIPN	SSTART		; SKIP IF TMPBUF NOT EMPTY
	TLNE	A2,760000	; IF BYTE POINTER NOT AT END OF WORD
	JRST	.+2		; THEN SKIP THIS PART
	ADDI	A3,1		; THEN IGNORE 1ST WORD OF TMPBUF
	SUBI	A5,(A6)		; EXCESS LENGTH - 1
	MOVEM	A6,P		; SET P
	MOVE	A2,A6		; COPY TO A2
	PUSHJ	SP,INEND	; GET NEXT INPUT BUFFER
	MOVE	A7,RFLAGS	; RE-FETCH READ MODULE FLAGS
	MOVE	A2,P		; RELOAD POINTER
	JRST	COL73A		; MOVE REMAINDER TO TMPBUF
	; MOVE REMAINDER OF LINE TO TMPBUF "UNOFFICIALLY"

COL73B:	MOVEM	A5,LINEND	; SAVE END OF TEXT IN RING BUFFER
	HRLZ	A6,A2		; "FROM" ADDRESS
	HRRI	A6,TMPBUF	; "TO" ADDRESS
	ADD	A6,TBLEN	; IN CASE TMPBUF NOT EMPTY
	SUBI	A5,(A2)		; LENGTH OF MOVE - 1
	JUMPL	A5,.+3		; SKIP IF NOTHING TO MOVE
	ADDI	A5,(A6)		; "STOP" ADDRESS
	BLT	A6,(A5)		; MOVE TEXT TO TMPBUF

	; REPLACE 1ST DIGIT OF LINE NUMBER WITH A CR

	MOVE	A2,A3		; A2 = NEW READ POINTER
	IBP	A3		; STEP TO COLUMN 2
	IBP	A3		; STEP TO COLUMN 3
	ADDI	A3,^D14		; STEP TO COLUMN 73
	LDB	A4,A3		; GET THE CHARACTER THAT IS THERE
	MOVEM	A4,CHAR		; SAVE IT FOR LATER
	MOVEI	A6,.CR		; ASCII CARRIAGE RETURN CHARACTER
	DPB	A6,A3		; PUT IN PLACE OF OTHER CHARACTER
	MOVEM	A3,CHARP	; SAVE POINTER TO THIS CHARACTER
	SUBI	A4,.N0		; CONVERT FROM ASCII TO BINARY
	MOVEI	A6,7		; READ 7 MORE CHARACTERS

	; SCAN LINE NUMBER

COL73C:	ILDB	A5,A3		; READ NEXT CHAR
	CAIN	A5,.SPACE	; IF IT IS A BLANK
	JRST	.+3		; THEN IGNORE IT
	IMULI	A4,^D10		; MULT PREVIOUS RESULT BY 10
	ADDI	A4,-.N0(A5)	; ADD IN CURRENT DIGIT
	SOJG	A6,COL73C	; LOOP

	; FROM TRUE LINE POINTER TO SOURCE BUFFER RING

	HRR	A3,LINEND	; GET POINTER TO TEXT IN RING BUFFER
	TLNN	A3,760000	; STEP POINTER, BUT NOT TO NEXT WORD
	SUBI	A3,1		; TRUE POINTER
	IBP	A3		; THE NEXT CHARACTER TO BE READ FROM THE RING BUFFER
	MOVEM	A3,LINEND	; SAVE THIS POINTER
	LDB	A1,A2		; READ THE NEXT CHARACTER
	JRST	NL8		; CONTINUE
SUBTTL	**  ERROR HANDLING ROUTINES  **

;   ERROR MESSAGES
;
;	ERROR MESSAGES ARE NOT PRINTED IMMEDIATELY AS THE ERRORS ARE
;	DETECTED.  IF THEY WERE THEN, SINCE THE ALGOL TEXT IS NOT MOVED TO
;	THE LISTING UNTIL AFTER THE LINE HAS BEEN SCANNED (FOR EFFICIENCY)
;	USUALLY THE ERROR CODE WOULD APPEAR BELOW THE ERROR MESSAGE, AND
;	OTHER TIMES THE ERROR CODE WOULD APPEAR ABOVE THE ERROR MESSAGE
;	BECAUSE THE SCANNER IS USUALLY PROCESSING AHEAD OF THE SYNTAX
;	ANALYZERS.  TO COMBAT THIS,  MESSAGES ARE BUFFERED IN A MESSAGE TABLE.
;	THEN, WHEN THE SCANNER REACHES THE END OF A LINE, "NEWLINE" WILL
;	1.) PRINT ALL MESSAGES THAT PERTAIN TO THE PRECEDING LINE OF
;	TEXT, 2.) PRINT THE CURRENT LINE OF TEXT, AND 3.) PRINT ALL MESSAGES
;	THAT PERTAIN TO THE CURRENT LINE OF TEXT.
;
;	EACH TIME THE SCANNER READ A CHARACTER WITH AN "ILDB" IT STEPS
;	"CC" WITH AN "AOS".  FOR EACH ITEM SCANNED "RUND" WILL STORE "CC"
;	IN THE CORRECT WORD OF "PLIST".  "PLIST" HAS 4 WORDS, ONE FOR EACH
;	PORT OF THE WINDOW.  "LP1" AND "LP2" CONTAIN THE CHARACTER NUMBERS
;	THAT BEGAN THE CURRENT AND PREVIOUS LINES OF TEXT, RESPECTIVELY.
;	USING ALL OF THE ABOVE, THE MESSAGE ROUTINE CAN TELL EXACTLY
;	WHERE TO PRINT THE UP-ARROW.
;
;	THE MESSAGE ROUTINE USUALLY PRINTS THE UP ARROW 1 POSITION
;	TO THE LEFT OF WHERE IT HAS CALCULATED THAT THE UP-ARROW SHOULD GO.
;	(THIS IS USUALLY A MORE CORRECT PLACE TO PUT IT.)  BUT THIS CAN
;	BE PREVENTED BY STORING THE CHARACTER COUNT WORD WITH BIT ZERO
;	SET TO ONE.
;	".FAILED" IS CALLED BY THE ".FAIL" ROUTINE WITH A1 CONTAINING
;	THE FOLLOWING PARAMETER:
;
;
;
;   +----------------------------------------------------------------+
;   !      ! !    !                 !                                !
;   !      !F!    !      FLAGS      !        MESSAGE NUMBER          !
;   !      ! !    !                 !                                !
;   +----------------------------------------------------------------+
;           4      8              17 18                            35
;
;   BIT 4:	UP-ARROW GOES UNDER READ BYTE POINTER, DONT SHIFT LEFT 1
;   BITS 8-9:	(OF NO CONCERN TO THIS MODULE)
;   BIT 10:	FATAL ERROR. HALT IMMEDIATELY
;   BIT 11:	"ILLEGAL USE OF" TYPE MESSAGE
;   BIT 12:	DELETE REL-FILE
;   BIT 13:	(OF NO CONCERN TO THIS MODULE)
;   BIT 14:	UP-ARROW GOES UNDER SYM
;   BIT 15:	UP-ARROW GOES UNDER DEL
;   BIT 16:	UP-ARROW GOES UNDER NSYM
;   BIT 17:	UP-ARROW GOES UNDER NDEL
;   BITS 18-35:	MESSAGE NUMBER
;	FROM THE ABOVE PARAMETER ".FAILED" WILL COMPUTE A MESSAGE TABLE
;	ENTRY AND INSERT IT INTO THE MESSAGE TABLE.  THE FORMAT OF A MESSAGE
;	TABLE ENTRY IS:
;
;
;
;   +-----------------------------------------------------------------+
;   !               !      !         !                                !
;   !  BYTE COUNT   !FLAGS !KIND/TYPE!       MESSAGE NUMBER           !
;   !               !      !         !                                !
;   +-----------------------------------------------------------------+
;    0             7 8   11 12     17 18                            35
;
;   BITS 0-7:	POSITION OF ARROW ON PRINT PAGE
;   BIT 8:	ERROR ON THE PRECEDING LINE
;   BIT 9:	ERROR ON SOME PREVIOUS LINE
;   BIT 10:	"ILLEGAL USE OF" TYPE MESSAGE
;   BIT 11:	DELETE REL-FILE
;   BITS 12-17:	KIND AND TYPE EXTRACTED FROM LEXEME IN SYM
;   BITS 18-35:	MESSAGE NUMBER
;	THE MESSAGES "START OF BLOCK N" AND "END BLOCK N, CONT M" ARE
;	ALSO BUFFERED IN THE MESSAGE TABLE.  ENTRIES FOR THESE HAVE THE
;	FOLLOWING FORMAT, WHICH IS DISTINGUISHED FROM THE OTHERS BY HAVING
;	A POSITION COUNT OF 377.
;
;
;
;   +-----------------------------------------------------------------+
;   !               !   !                      !                      !
;   !      377      !   !       VALUE 1        !       VALUE 2        !
;   !               !   !                      !                      !
;   +-----------------------------------------------------------------+
;    0             7 8 9 10                  22 23                  35
;
;
;   BITS 0-7:	377
;   BIT 8:	MESSAGE ON THE PRECEDING OR SOME PREVIOUS LINE
;   BIT 9:	MUST BE ZERO
;   BITS 10-22:	VALUE 1
;   BITS 23-35:	VALUE 2
;
;	IF VALUE2 = 0 THEN PRINT "START OF BLOCK (VALUE1)"
;	ELSE PRINT "END BLOCK (VALUE2), CONT (VALUE1)";
	..PREC==1000		; ERROR ON PRECEDING LINE
	..PREV==400		; ERROR ON SOME PREVIOUS LINE
	..IUO1==200		; "ILLEGAL USE OF" FORM
	..TERM==100		; "REL FILE DELETED"



;	".FAIL", ".BLK1", AND ".BLK2" PUT ENTRIES IN THE MESSAGE TABLE,
;	"LMSG" TAKES THEM OUT AND PRINTS THEM.
;	LMSGS = 0 FOR PASS1, -1 FOR PASS2


	; EDIT (1002)	Include bad identifiers in error messages.
	;
	Edit(166); Correct Edit 1002 for errors at block level 1
	;

LMSG1:	MOVE	A1,(A5)		; [E166] Get message entry.
	TLC	A1,776000	; [E166] Is this a block begin or end ?
	TLCN	A1,776000	; [E166]	...
	AOJA	A5,LMSG5	; [E166] Yes - step to next entry
	TLNE	A1,..IUO1	; [E166] If IUO or undeclared identifier
	JRST	LMSG6		; [E166] 	...
	HRRZ	A1,A1		; [E166]	...
	CAIE	A1,1		; [E166]	...
	CAIN	A1,^D62		; [266] CHECK FOR SPECIFIC ERROR MESSAGE #
	SKIPA			; [266] MESSAGE HAS MORE TO TYPE, SKIP
	AOJA	A5,LMSG5	; [E166]	...
LMSG6:	PUSHJ	SP,IUOLN	; [E166] then get entry length in A1
	ADDM	A1,A5		; [E166] and step extra length.
	AOJA	A5,LMSG5	; STEP TO NEXT TABLE ENTRY

LMSG:	PUSH	SP,A2		; SAVE A2
LMSG5:	CAML	A5,NAMTE	; [E166] END OF MESSAGES?
	JRST	LMSGE		; -YES, DONE
	MOVE	A2,(A5)		; GET ENTRY CONTENTS
	MOVE	A4,LMSGS	; LOAD THE SWITCH
	TLNN	A2,..PREC+..PREV; IF EITHER BIT IS SET
	SETCM	A4,A4		; THEN THIS MESSAGE SHOULD BE PRINTED
	JUMPN	A4,LMSG1	; ONLY ON THE 1ST PASS THROUGH LMSG

	; CHECK FOR "START BLOCK" AND "END BLOCK" ENTRIES


	LSH	A2,-^D28	; COLUMN POINTER
	CAIN	A2,377		; IF BYTES=255 THEN IT IS
	JRST	BLK1A		; A BLOCK BEGIN OR END LINE

	PUSHJ	SP,CRFNL2	; TERMINATE CREF DATA, IF ANY.
	; WRITE: "******   ^"

	MOVEI	A1,STAR3	; "*******"
	PUSHJ	SP,INSERT	; SEND TO LISTING
	MOVE	A2,(A5)		; GET MESSAGE TABLE ENTRY
	TLNE	A2,..PREV	; IF ERROR OCCURRED ON A PREVIOUS LINE
	JRST	LMSG3		; THEN HANDLE SEPARATELY
	LSH	A2,-^D28	; GET ARROW POSITION
	JUMPE	A2,LMSG2	; NO ^ IF ZERO
	TLNN	A7,LTTY		; UNLESS THE LISTING IS GOING TO THE TTY
	ADDI	A2,^D16		; PUT 16 MORE BLANKS AT START OF LINE
	TLNN	A7,EXISTS	; [E134] ARE WE LISTING
	 JRST	LMSG2		; [E134] NO - DON'T BOTHER
	MOVEI	A1,(A2)		; [E134] GET THE COUNT
	MOVEI	A2,.SPACE	; [E134] SPACE CHARACTER
	PUSHJ	SP,INS7		; [E134] PUT CHAR IN BUFFER
	SOJG	A1,.-1		; [E134]
	MOVEI	A2,.UP		; [E134]
	PUSHJ	SP,INS7		; [E134] OUTPUT ^
	SETZ	A2,		; [E134]
	PUSHJ	SP,INS7		; [E134] AND A NULL
	JRST	LMSG2		; [E134]

LMSG4:	PUSHJ	SP,INSERT	; INSERT LINE IN LISTING

LMSG2:	PUSHJ	SP,ICHECK	; INCLUDE CR/LF
	PUSHJ	SP,NPRINT	; PUT ERROR LINE NUMBER IN LISTING

	; WRITE ERROR MESSAGE TO LISTING

	JSP	A6,LMSG0	; GET ERROR MESSAGE
	HLL	A1,(A5)		; GET FLAGS
	TRNN	A1,777777	; IF NO ENTRY THEN
	MOVEI	A1,[		; USE A
	ASCIZ	//]		; LITERAL NULL STRING
	TLNE	A1,..IUO1	; IF "ILLEGAL USE OF"
	PUSHJ	SP,IUO		; THEN HANDLE SEPARATELY
	PUSHJ	SP,INSE		; PUT MESSAGE IN LISTING
	HRRZ	A1,(A5)		; [E1002] If undeclared identifier
	CAIE	A1,^D62		; [266] IF MISSING FORWARD, LIST LABEL NAME
	CAIN	A1,1		; [E1002] 	...
	PUSHJ	SP,OUTSYM	; [E1002] then list spelling.
	PUSHJ	SP,KCHECK	; PUT CR/LF IN MESSAGE

	; CHECK FOR FATAL ERROR

	MOVE	A4,(A5)		; GET MESSAGE TABLE ENTRY
	TLNN	A4,..TERM	; IF OBJECT CODE NOT TERMINATED
	JRST	[AOS	WRNCNT	;[171] THEN INCREMENT WARNING COUNT
		 JRST	LMSG1]	;[171] AND LOOP
	AOS	.JBERR		; ELSE INCREMENT ERROR COUNT
	TLOE	A7,TMG		; IF TERM MSG PREV GIVEN 
	JRST	LMSG1		; THEN LOOP
	SETOM	WFLAG		; MARK REL FILE TO BE ERASED
	EDIT	(247)		; [247] FIX COMPILER LOOPING WITH BAD PROG.
	MOVEI	A1,TERMC	; ADDR OF TERMINATION MESSAGE
	PUSHJ	SP,INS		; "REL-FILE DELETED"
	PUSHJ	SP,TCHECK	; CR/LF
	JRST	LMSG1		; LOOP


TERMC:	ASCIZ	/?ALGNRF No .REL file created/
STAR3:	ASCIZ	/*******/
SPACE2:	ASCIZ	/  /
	; "NPRINT" WILL PRINT THE LINE NUMBER OF THE ERROR

NPRINT:	MOVEI	A1,[ASCIZ/%/]	; [300] DEFAULT TO WARNING
	MOVE	A4,(A5)		; [300] GET MESSAGE TABLE ENTRY
	TLNE	A4,..TERM	; [300] IF THIS WAS A FATAL ERROR
	MOVEI	A1,[ASCIZ/?/]	; [300] THEN USE A QUESTION MARK
	PUSHJ	SP,INSE		; [300] PUT CORRECT ONE IN LISTING
	SKIPN	LMSGS		; IF MESSAGE FOR PREVIOUS LINE
	SKIPA	A1,OLDNO	; THEN GET OLD LINE NUMBER
	MOVE	A1,LINENO	; ELSE GET LINE NUMBER
	PUSHJ	SP,LPRINT	; CONVERT IT TO ASCII
	PUSHJ	SP,INSE		; WRITE LINE NUMBER TO LISTING AND TTY
	MOVEI	A1,SPACE2	; WRITE 2 SPACES
	JRST	INSE		; SEND TO LISTING AND TTY, EXIT NPRINT




	; ERROR IS NEITHER ON CURRENT NOR PRECEDING LINE

LMSG3:	MOVEI	A1,Y19		; "ERROR ON A PREVIOUS LINE"
	JRST	LMSG4		; CONTINUE

	; EXIT LMSG

LMSGE:	PUSHJ	SP,CREFST	; OUTPUT CREF START DATA, IF REQUIRED.
	POP	SP,A2		; RESTORE A2
	POPJ	SP,		; EXIT LMSG


;	AN "IUO" MESSAGE IS A MESSAGE OF THE FORM "XXX YYY FOUND WHERE A 
;	ZZZ WAS EXPECTED".  THE ERROR MESSAGE NUMBER SPECIFIES ONLY THE
;	TEXT OF ZZZ.  XXX AND YYY ARE THE TYPE AND KIND OF WHAT WAS
;	FOUND, AND THE TEXT OF THESE MUST BE DETERMINED BY DECODING THE
;	LEXEME IN SYM.

IUO:	LDB	A1,[		; GET "TYPE" OF ITEM
	POINT	3,(A5),14]	; POINTER TO TYPE FIELD IN ENTRY
	CAIN	A1,4		; IF IT IS A LABEL
	JRST	IUOLAB		; THEN HANDLE SEPARATELY
	MOVE	A1,IUOMT1(A1)	; GET NAME
	PUSHJ	SP,INS		; PUT IN LISTING
	LDB	A1,[		; GET "KIND" OF ITEM
	POINT	3,(A5),17]	; POINTER TO KIND FIELD IN ENTRY
	MOVE	A1,IUOMT2(A1)	; GET NAME
IUO1:	PUSHJ	SP,INS		; PUT IN LISTING
	PUSHJ	SP,OUTSYM	; [E1002] Put spelling in listing.
	MOVEI	A1,Y2		; " WHERE A "
	PUSHJ	SP,INS		; PUT IN LISTING
	JSP	A6,LMSG0	; GET MESSAGE
	PUSHJ	SP,INS		; PUT IN LISTING
	MOVEI	A1,Y3		; " WAS EXPECTED"
	POPJ	SP,		; EXIT IUO

IUOLAB:	LDB	A1,[		; GET "KIND" OF ITEM
	POINT	3,(A5),17]	; POINTER TO KIND FIELD
	MOVE	A1,IUOMT3(A1)	; GET PROPER NAME
	JRST	IUO1		; CONTINUE

LMSG0:	HRRZ	A1,(A5)		; GET MESSAGE #
	ROT	A1,-1
	JUMPL	A1,.+3
	HLRZ	A1,TTABLE(A1)
	JRST	(A6)
	HRRZ	A1,TTABLE(A1)
	JRST	(A6)
	; BLOCK START OR END

BLK1A:	TLNE	A7,LTTY		; IF LISTING IS ON TTY
	JRST	LMSG1		; THEN DONT WRITE BLOCK BEGIN OR END MSG
	MOVE	A4,(A5)		; RELOAD PARAM WORD
	TRNE	A4,017777	; IF RIGHT-MOST 13 BITS NOT ZERO
	JRST	BLK2A		; THEN THIS IS AN END MESSAGE

	; "START OF BLOCK N"

	TRNN	FL,CREF		; CREF ?
	JRST	BLK2B		; NO
	PUSH	SP,A5		; DEC CLOBBERS THIS
	PUSHJ	SP,CREFST	; OUTPUT CREF START-DATA, IF NEEDED.
	MOVEI	A1,BLK2M3	; START-BLOCK
	PUSHJ	SP,INSERT
	MOVEI	A3,5		; FOR DEC
	MOVE	A2,["-",,"-"]	; FILLER-CHAR,,RIGHT-MOST FILLER
	LDB	A4,[POINT 13,(A5),22]	; BLOCK-NUMBER
	PUSHJ	SP,CRFDEC	; TO DECIMAL TO LISTING
	MOVEI	A5,^D8		; UPDATE 
	ADDM	A5,CRFCNT	;  CHARACTER-COUNT
	POP	SP,A5
	JRST	LMSG1		; DON'T PRINT 'START OF BLOCK'

BLK2B:	MOVEI	A1,BLK1M	; "START OF BLOCK "

BLKC:	PUSHJ	SP,INSERT	; PUT IN LISTING
	LDB	A1,[		; GET THE NUMBER STORED IN
	POINT	13,(A5),22]	; BITS 10-22
	PUSHJ	SP,LPRINT	; CONVERT TO DECIMAL ASCII
	PUSHJ	SP,INSERT	; PUT NUMBER IN LISTING
	PUSHJ	SP,ICHECK	; CR/LF
	JRST	LMSG1		; LOOP


	; "END OF BLOCK N, CONT M"

BLK2A:	TRNN	FL,CREF		; CREF ?
	JRST	BLK2C		; NO
	PUSH	SP,A5
	PUSHJ	SP,CREFST	; OUTPUT CREF START DATA, IF NEEDED.
	MOVEI	A1,BLK2M4	; END BLOCK
	PUSHJ	SP,INSERT
	MOVEI	A3,5
	MOVE	A2,["-",,"-"]	; FILLER-CHAR,,RIGHT-MOST-FILLER
	LDB	A4,[POINT 13,(A5),35]	; BLOCK-NUMBER
	PUSHJ	SP,CRFDEC	; TO LISTING IN DECIMAL
	MOVEI	A5,^D8		; UPDATE
	ADDM	A5,CRFCNT	;  CHAR-COUNT
	POP	SP,A5
	JRST	LMSG1		; DON'T PRINT 'END OF BLOCK'

BLK2C:	MOVEI	A1,BLK2M1	; "END BLOCK "
	PUSHJ	SP,INSERT	; PUT IN LISTING
	LDB	A1,[		; GET THE NUMBER STORED IN
	POINT	13,(A5),35]	; BITS 23-35
	PUSHJ	SP,LPRINT	; CONVERT TO DECIMAL ASCII
	PUSHJ	SP,INSERT	; PUT NUMBER IN LISTING
	MOVEI	A1,BLK2M2	; ", CONT "
	JRST	BLKC		; CONTINUE
BLK1M:	ASCIZ	/START OF BLOCK /
BLK2M1:	ASCIZ	/END BLOCK /
BLK2M2:	ASCIZ	/, CONT /
BLK2M3:	BYTE(7)015,6,"B",0	; CREF START-BLOCK:  T15 6CH B
BLK2M4:	BYTE(7)016,6,"E",0	; CREF END BLOCK: T16 6CH E
;	"LMSGZ" IS CALLED AT THE END OF THE COMPILATION BY ".ZZEND".  "LMSGZ"
;	WILL PRINT ALL MESSAGES THAT REMAIN IN THE MESSAGE TABLE THAT
;	HAVE NOT YET BEEN PRINTED.

LMSGZ:	MOVEM	A7,A7SAV	; SAVE A7
	MOVE	A7,RFLAGS	; FETCH THE READ MODULE FLAGS
	MOVEI	A5,MTABLE	; ADDR OF MESSAGE TABLE
	CAML	A5,NAMTE	; IF NO MESSAGES IN MESSAGE TABLE
	POPJ	SP,		; THEN EXIT LMSGZ
	SKIPE	LMSGS		; [273] DUMP 1ST GROUP OF MESSAGES, UNLESS DONE
	JRST	LMSGZ2
	PUSHJ	SP,LMSG		; PRINT MESSAGES

LMSGZ2:	MOVEI	A5,MTABLE	; ADDR OF MESSAGE TABLE
	SETOM	LMSGS		; DUMP 2ND GROUP OF MESSSAGES
	PUSHJ	SP,LMSG		; PUT THEM IN LISTING
	PUSHJ	SP,CRFNL2	; OUTPUT CREF END, & ANY NECESSARY NULLS
	MOVEI	A1,LINES3	; PUT 3 BLANK LINES
	PUSHJ	SP,INSERT	; IN LISTING
	JRST	ICHECK		; INSERT A CR/LF, EXIT LMSGZ

LBP:	POINT	7,LB		; [273] LISTING BUFFER POINTER

	RELOC

MTABLE:	BLOCK	50		; MESSAGE TABLE
NAMTE:	BLOCK	1
;	MTABLE			; NEXT AVAIL MESSAGE TABLE ENTRY
LMSGS:	BLOCK	1		; LMSG SWITCH: 0 FOR PASS1, -1 FOR PASS2
LB:	BLOCK	40		; LISTING BUFFER FOR MESSAGES
OLDNO:	BLOCK	1		; OLD LINE NUMBER
WRNCNT:	BLOCK	1		;[171] WARNING COUNT
	RELOC

Y2:	ASCIZ	/ FOUND WHERE A/
Y3:	ASCIZ	/ WAS EXPECTED/
Y4:	ASCIZ	/STRING/
Y5:	ASCIZ	/COMPLEX/
Y6:	ASCIZ	/TYPELESS/
Y7:	ASCIZ	/BOOLEAN/
Y8:	ASCIZ	/LONG REAL/
Y9:	ASCIZ	/REAL/
Y10:	ASCIZ	/INTEGER/
Y11:	ASCIZ	/ VARIABLE/
Y12:	ASCIZ	/ EXPRESSION/
Y13:	ASCIZ	/ ARRAY IDENTIFIER/
Y14:	ASCIZ	/ PROCEDURE/
Y15:	ASCIZ	/ CONSTANT/
Y16:	ASCIZ	/LABEL/
Y17:	ASCIZ	/DESIGNATIONAL EXPRESSION/
Y18:	ASCIZ	/SWITCH/
IUOMT1:	Y4
	Y5
	Y6
	Y7
	0
	Y8
	Y9
	Y10

IUOMT2:	Y11
	Y12
	Y13
	Y14
	Y15

IUOMT3:	Y16
	Y17
	0
	Y18
	Y19			;[252] MAKE ENTRY FOR Y19 TOO

Y19:	ASCIZ	/ ERROR ON A PREVIOUS LINE:/
;	THE INSERT ROUTINES ("INSERT", "INS", AND "INSE") ARE USED TO INSERT
;	MESSAGES INTO THE LISTING.  THE CHECK ROUTINES ("ICHECK", "TCHECK",
;	AND "KCHECK") WILL INSERT A CR/LF INTO THE LISTING, AND THEN
;	INSERT NULLS INTO THE LISTING SO THAT THE TOTAL NUMBER OF CHARACTERS
;	INSERTED SINCE THE LAST CHECK ROUTINE WAS CALLED IS A MULTIPLE OF 5.
;	WHENEVER AN INSERT ROUTINE IS USED, A CHECK ROUTINE MUST BE CALLED
;	BEFORE THE NEXT CALL TO NEWLINE.
;
;	"INSERT" AND "ICHECK" WRITE MESSAGES IN THE LISTING.  "INS" AND
;	"TCHECK" ALSO WRITE THE MESSAGE TO THE TTY.  "INSE" AND "KCHECK"
;	ARE USED TO WRITE MESSAGES WHEN MESSAGE 98 MIGHT BE ENCOUNTERED.


INSE:	HRRZ	A3,(A5)		; GET MESSAGE NUMBER
	CAIN	A3,^D98		; IF THIS IS MESSAGE 98
	JRST	INSERT		; THEN DONT WRITE TO TTY


	; INSERT LINE IN LISTING, AND ALSO WRITE IT TO TTY

INS:	TLNN	A7,NSWIT	; IF NO N-SWITCH
	OUTSTR	(A1)		; THEN WRITE IT TO TTY
	JRST	INSERT		; INSERT LINE IN LISTING


	; PUT DECIMAL NUMBER IN LISTING

LPRINT:	MOVE	A6,LBP		; GET BUFFER BYTE POINTER
	PUSHJ	SP,LPR1		; CONVERT IT TO CHARACTERS
	MOVEI	A1,0		; ASCII NULL
	IDPB	A1,A6		; END STRING WITH AN ASCII NULL
	MOVEI	A1,LB		; OUTPUT ADDRESS OF BUFFER
	POPJ	SP,		; EXIT LPRINT


	; CONVERT IT TO DECIMAL

LPR1:	IDIVI	A1,12		; DIVIDE BY TEN
	PUSH	SP,A2		; PUT DIGIT ON STACK
	SKIPE	A1		; SKIP IF END OF NUMBER
	PUSHJ	SP,LPR1		; RECURSIVE CALL TO LPR1
	POP	SP,A1		; FETCH DIGIT FROM STACK
	ADDI	A1,.N0		; CONV TO ASCII
	IDPB	A1,A6		; PUT IN BUFFER
	POPJ	SP,		; ASCEND FROM LPR1
	; Write msg to listing, and to TTY if CCL and there were errors,
	;  or if not CCL (DONE1).
	; DONE2 writes msg to listing, and to TTY if not CCL.
	; Both used at end, called from START0, to do N Errors, stats, etc.

DONE1:	SKIPE	WRNCNT		; [300] ANY WARNINGS?
	JRST	INS		; [300] YES, SEND TO TTY
	SKIPN	.JBERR

DONE2:	SKIPN	CCLSW
	JRST	INS		; TO TTY AS WELL, IF REQUD.

	; Insert a message in listing. The address of the message in ASCIZ
	; format should be in A1

INSERT:	TROA	A2,777777	; SET SWITCH TO SAY INSERT, NOT INSNUL

INSNUL:	SETZ	A2,		; INSERT ONE NULL
	TLNN	A7,EXISTS	; IF LISTING DOES NOT EXIST

INS2:	POPJ	SP,		; THEN DONT SEND MESSAGE THERE
	JUMPE	A2,INS7		; IF NOT NULL...
	HRLI	A1,440700	; SET UP BYTE POINTER

	; CHARACTER TRANSFER LOOP

INS6:	ILDB	A2,A1		; GET A CHAR
	JUMPE	A2,INS2		; IF NULL, THE END

	PUSHJ	SP,INS7		; [E134] OUTPUT THE CHARACTER
	JRST	INS6		; [E134] AND LOOP UNTIL DONE
INS7:	SOSGE	FIVEC		; DECR NO OF REMAINING CHARS
	JRST	INS3		; -END OF 5-CHAR GROUP

INS1:	IDPB	A2,W		; PUT CHAR IN LISTING
	POPJ	SP,		; DONE

	; AT END OF WORD, CHECK FOR END OF LISTING BUFFER

INS3:	HRRZ	A6,W		; GET LISTING POINTER
	ADDI	A6,2		; STEP TO NEXT WORD
	CAML	A6,OBEND	; IF IT IS NOT WITHIN BUFFER
	JRST	INS5		; THEN GET A NEW BUFFER

INS4:	MOVEI	A6,4		; 4 CHARS LEFT AFTER THIS ONE
	MOVEM	A6,FIVEC	; SET 5-CHAR GROUP COUNT
	JRST	INS1		; CONTINUE

	; END OF BUFFER, GET ANOTHER

INS5:	HLRZ	A4,W		; SAVE S-P BITS OF LISTING POINTER
	PUSHJ	SP,WRITEL	; GET A NEW BUFFER
	AOS	A6,W		; STEP LISTING POINTER
	SETZM	(A6)		; ZERO 1ST WORD OF BUFFER
	HRLM	A4,W		; SET S-P BITS
	JRST	INS4		; CONTINUE



KCHECK:	HRRZ	A3,(A5)		; GET MESSAGE NUMBER
	CAIN	A3,^D98		; IF IT IS MESSAGE 98
	JRST	ICHECK		; THEN DONT WRITE CR/LF TO TTY
	; WRITE CR/LF TO TTY, THEN CALL "ICHECK"

TCHECK:	MOVEI	A1,NLCHRS	; PUT A CR/LF
	PUSHJ	SP,INS		; INTO LISTING
	JRST	IC2		; CONTINUE

	; "ICHECK MUST BE CALLED AFTER USING "INSERT" TO WRITE THE CR/LF TO
	; THE LISTING, AND TO MAKE SURE THAT THE TOTAL INSERTED MESSAGE
	; IS A MULTIPLE OF 5 CHARACTERS LONG.

ICHECK:	MOVEI	A1,NLCHRS	; PUT A CR/LF
	PUSHJ	SP,INSERT	; INTO LISTING

IC2:	TLNN	A7,EXISTS	; IF LISTING DOESNT EXIST
	POPJ	SP,		; THEN SKIP THIS
	MOVEI	A1,0		; NULL CHARACTER

IC1:	SOSGE	FIVEC		; DECR NO OF REMAINING CHARS
	POPJ	SP,		; EXIT ICHECK IF NONE LEFT
	IDPB	A1,W		; PUT NULL INTO LISTTIG
	JRST	IC1		; LOOP


	RELOC

FIVEC:	BLOCK	1		; FIVE CHARACTER COUNT

	RELOC
	; PUT ENTRY IN MESSAGE TABLE

FAILED:	MOVEM	A6,REG3+5	; SAVE A6
	MOVE	A6,[		; LOAD BLT WORD
	XWD	A1,REG3]	; BLT WORD
	BLT	A6,REG3+4	; SAVE REGS

	; FIND THE BYTE POINTER TO THE ERROR

	SETOM	BYTES		; ZERO ^ POSITION
	SETZB	A4,FAILF	; CLEAR FLAGS
	TLNN	A1,..IMM+17	; IF THERE IS TO BE NO ^
	JRST	FAILA		; THEN SKIP THIS PART
	TLNN	A1,..IMM	; IF NOT ^ WHERE POINTER IS NOW
	JRST	.+3		; THEN SKIP
	AOS	BYTES		; USE EXACT POINTER
	MOVE	A4,CC		; THEN USE CURRENT READ POINTER
	MOVE	A5,PLIST	; GET POINTER  LIST POINTER
	XORI	A5,2		; FLIP IT
	TLNE	A1,..SYM	; IF ^ UNDER SYM
	MOVE	A4,(A5)		; THEN GET SYM POINTER
	TLNE	A1,..DEL	; IF ^ UNDER DEL
	MOVE	A4,1(A5)	; THEN GET DEL POINTER
	XORI	A5,2		; FLIP POINTER SWITCH
	TLNE	A1,..NSYM	; IF ^ UNDER NSYM
	MOVE	A4,(A5)		; THEN GET NSYM POINTER
	TLNE	A1,..NDEL	; IF ^ UNDER NDEL
	MOVE	A4,1(A5)	; THEN GET NDEL POINTER
	JUMPE	A4,FAILB	; IF POINTER ZERO, ERROR ON A PREVIOUS LINE
	TLZE	A4,EXACT	; IF FLAG BIT IS ON
	AOS	BYTES		; THEN USE EXACT POINTER

	; DETERMINE WHAT LINE THE ERROR IS ON

	CAMGE	A4,LP1		; IF ERROR NOT ON CURRENT LINE
	JRST	FAILC		; THEN CHECK PRECEDING LINE
	SUB	A4,LP1		; COMPUTE POSITION ON LINE
	ADDM	A4,BYTES	; SAVE IT
	JRST	FAILA		; CONTINUE

FAILC:	CAMGE	A4,LP2		; IF ERROR NOT ON PRECEDING LINE
	JRST	FAILB		; THEN DONT PRINT AN ^
	SUB	A4,LP2		; COMPUTE POSITION ON LINE
	ADDM	A4,BYTES	; SAVE IT
	AOSA	FAILF		; SET FLAG +
FAILB:	SETOM	FAILF		; SET FLAG -

	; CREATE MESSAGE TABLE ENTRY

FAILA:	AOS	A4,BYTES	; GET UP ARROW POSITION
	LDB	A5,[		; GET TYPE FIELD OF SYM
	POINT	6,SYM,8]	; POINTER TO TYPE FIELD
	CAIN	A5,<$L>B44	; IF TYPE = LABEL
	MOVEI	A5,4		; THEN CHANGE TO 04
	ANDI	A5,7		; USE ONLY 3 BITS OF TYPE FIELD
	LSH	A4,7		; SHIFT 7
	ADD	A4,A5		; INCLUDE TYPE FIELD
	LSH	A4,3		; SHIFT 3
	LDB	A5,[		; GET KIND FIELD OF SYM
	POINT	2,SYM,2]	; POINTER TO KIND FIELD
	TLNN	SYM,$SYMB	; IF SYM IS A CONSTANT
	MOVEI	A5,4		; THEN USE AN 04
	ADD	A4,A5		; INCLUDE KIND
	MOVS	A4,A4		; MOVE IMFO TO FINAL POSITION
	MOVE	A5,REG3		; GET PARAMETER TO "FAILED"
	HRR	A4,A5		; INCLUDE MESSAGE NUMBER
	SKIPLE	A6,FAILF	; IF ERROR ON PRECEDING LINE
	TLO	A4,..PREC	; THEN SET FLAG
	SKIPGE	A6		; IF ERROR ON SOME PREVIOUS LINE
	TLO	A4,..PREV	; THEN SET FLAG
	TLNE	A5,SUSPCO	; IF TERMINATION BIT ON
	TLO	A4,..TERM	; THEN TURN ON CORRESPONDING BIT

BLK0:	MOVE	A6,NAMTE	; NEXT AVAILABLE MSG TABLE ENTRY SPACE
	CAIL	A6,MTABLE+50	; IF PAST END OF TABLE
	JRST	BLK2		; [E1002] then don't put in table
	HRRZ	A3,A5		; [E1002] If undeclared identifier
	CAIE	A3,^D62		; [266] CHECK FOR MISSING FORWARD LABEL TOO
	CAIN	A3,1		; [E1002] 	...
	JRST	.+4		; [E1002]	...
	TLNN	A5,..IUO2	; [E1002] or IUO
	JRST	BLK1		; [E1002]	...
	TLO	A4,..IUO1	; [E1002] then enter symbol spelling.
	HRRZ	A3,SYM		; [E1002] Address of symbol in A3
	CAIL	A3,MTABLE	; [E1002] In symbol table (best to make sure)?
	CAML	A3,NASTE	; [E1002]	...
	JRST	BLK3		; [E1002] No - enter a null.
	HLRZ	A1,A4		; [E1002] Get lexeme kind in A1
	ANDI	A1,7		; [E1002] 	...
	CAIE	A1,1		; [E1002] If kind = expression or constant
	CAIN	A1,4		; [E1002] 	...
	JRST	BLK3		; [E1002] then make a null entry.
	MOVEI	A3,SYMNAM(A3)	; [E1002] Start of spelling in ST.
	HRRZ	A1,@A3		; [E1002]	...
	PUSHJ	SP,IUOLN1	; [E1002] Get entry length in A1.
	JRST	BLK4
BLK3:	MOVEI	A1,1		; [E1002] Null entry of length 1.
	MOVEI	A3,[EXP 0]	; [E1002] and zero value.
BLK4:	ADDM	A1,A6		; [E1002] Room for spelling in table ?
	CAIL	A6,MTABLE+50	; [E1002]	...
	JRST	BLK2		; [E1002] No - don't enter it.
	MOVE	A6,NAMTE	; [E1002] Save current next entry free.
	ADDM	A1,NAMTE	; [E1002] Add in spelling entry length.
	HRL	A2,A3		; [E1002] Set up BLT word.
	HRR	A2,A6		; [E1002]	...
	AOJ	A2,		; [E1002] 	...
	BLT	A2,@NAMTE	; [E1002] Move spelling into message table.
BLK1:	MOVEM	A4,(A6)		; [E1002] Put entry into table.
	AOS	NAMTE		; [E1002] Step table index.
BLK2:	TLNE	A5,..FATAL	; [E1002] If termination bit is on
	JRST	FAILT		; THEN STOP COMPILATION
	MOVS	A6,[		; GET POINTERS FOR
	XWD	A1,REG3]	; BLT
	BLT	A6,A6		; RESTORE REGISTERS
	POPJ	SP,		; EXIT FAILED
	; FATAL ERROR. STOP COMPILATION IMMEDIATELY.

	ILDB	A1,P		; READ NEXT CHAR

FAILT:	LDB	A1,P		; RESD CHAR (FIRST TIME)
	MOVE	A2,CTABLE(A1)	; GET ITS ENTRY
	CAIN	A2,4		; IF IT A NEW-LINE CHAR
	PUSHJ	SP,NEWLINE	; THEN PRINT LINE AND MESSAGES
	JRST	FAILT-1		; ELSE READ ANOTHER CHAR
	MOVEI	A1,TERMSG	; TERMINATION MESSAGE
	PUSHJ	SP,INS		; INSERT IT IN LISTING
	PUSHJ	SP,TCHECK	; CR/LF
	JRST	RINIT+1		; GET ANOTHER COMMAND STRING

	RELOC

REG3:	BLOCK	6		; REGISTER SAVE AREA
BYTES:	BLOCK	1		; BYTE COUNT FOR ^
FAILF:	BLOCK	1		; FLAG USED BY FAILED
LP1:	BLOCK	1		; POINTER TO START OF CURRENT LINE
LP2:	BLOCK	1		; POINTER TO START OF PRECEDING LINE
BLKF:	BLOCK	1		; .BLK1 .BLK2 FLAG

	RELOC
	; [E1002] IUOLN - Finds the word length of a spelling in the ST.

IUOLN:	HRRZ	A1,1(A5)	; [E1002] Get entry length in A1.
IUOLN1:	ANDI	A1,77		; [E1002]	...
	ADDI	A1,2		; [E1002]	...
	IDIVI	A1,6		; [E1002]	...
	SKIPE	,A2		; [E1002]	...
	AOJ	A1,		; [E1002]	...
	POPJ	SP,		; [E1002] Return.

	; [E1002] OUTSYM - Inserts a spelling from the message table
	;		   into the listing.

OUTSYM:	MOVE	A1,A5		; [E1002] Adress of spelling - 1.
	SKIPN	,1(A5)		; [E1002] If null entry
	POPJ	SP,		; [E1002] then don't bother.
	PUSH	SP,A5		; [E1002] Convert to ASCIZ in LB.
	SOJ	A1,		; [E1002]	...
	PUSHJ	SP,NAME		; [E1002]	...
	POP	SP,A5		; [E1002]	...
	MOVEI	A1,[ASCIZ/ </]	; [E1002] List a '<'.
	PUSHJ	SP,INS		; [E1002]	...
	MOVEI	A1,LB		; [E1002] List spelling.
	PUSHJ	SP,INS		; [E1002]	...
	MOVEI	A1,[ASCIZ/>/]	; [E1002] List a '>'.
	PUSHJ	SP,INS		; [E1002]	...
	POPJ	SP,		; [E1002] Return.

	; START OF BLOCK

.BLK1:	SETZM	BLKF		; ZERO THE FLAG
	JRST	.+2		; SKIP

	; END OF BLOCK

.BLK2:	SETOM	BLKF		; SET FLAG NON-ZERO
	MOVEM	A6,REG3+5	; SAVE WORD
	MOVE	A6,[		; LOAD BLT WORD
	XWD	A1,REG3]	; BLT WORD
	BLT	A6,REG3+4	; SAVE ALL 6 REGS
	MOVE	A2,CURBLOCK	; GET CURRENT BLOCK NUMBER
	SKIPN	BLKF		; IF .BLK1 THEN
	LSHC	A1,^D36		; MOVE TO A1, CLEAR 2ND PARAM
	LSH	A2,^D23		; COMBINE THE PARAM IN A1
	LSHC	A1,-^D23	; WITH THE PARAM IN A2
	MOVE	A5,PLIST	; POINTER BUFFER
	XORI	A5,2		; FLIP IT TO SYM AND DEL
	MOVE	A4,1(A5)	; GET POINTER TO DEL
	SKIPN	BLKF		; IF .BLK1 THEN
	MOVE	A4,(A5)		; USE POINTER TO SYM INSTEAD
	TLZE	A4,EXACT	; IF FLAG BIT IS ON
	ADDI	A4,1		; THEN USE EXACT POINTER
	CAMG	A4,LP1		; DETERMINE WHICH LINE IT IS ON
	TLO	A2,..PREC	; MARK: ON PRECEDING LINE
	TLO	A2,776000	; SET BYTES=255
	MOVE	A4,A2		; MOVE TO A4
	MOVEI	A5,0		; CLEAR A5
	JRST	BLK0		; CONTINUE
SCDLT=.-43

	LEX(NE)			; "#"

	BLOCK	4

	LEX(LPAR)		; "("
	LEX(RPAR)		; ")"
	LEX(TIMES)		; "*"
	LEX(PLUS)		; "+"
	LEX(COM)		; ","
	LEX(MINUS)		; "-"
	LEX(DOT)		; "."
	LEX(SLASH)		; "/"

TCDLT:	XWD	L$ASS,R$ASS	; ":="
	0
	LEX(LEQ)		; "<="
	0
	LEX(GTE)		; ">="
	0
	LEX(UPLUS)
	LEX(UMINUS)
	LEX(PHID)
	0
	LEX(COLON)		; ":"
	LEX(SC)			; ";"
	LEX(LSS)		; "<"
	LEX(EQ)			; "="
	LEX(GTR)		; ">"
	BLOCK	^D28

	LEX(LBRA)		; "["
	LEX(EOF)		; END-OF-FILE
	LEX(RBRA)		; "]"
	LEX(POW)		; "^"
	LEX(ASS)		; "_"
SUBTTL	** LSCAN **

; 	*****  L S C A N  *****
; 
; 		"LSCAN" READS ALGOL TEXT FROM A FILE AND
; 	CONVERTS IT TO AN INTERNAL CODE.  EACH CALL TO
; 	LSCAN PRODUCES THE NEXT ITEM FROM THE ALGOL
; 	PROGRAM.  ITEMS ARE OF THREE TYPES:
; 
; 		1.  IF THE ITEM IS A DELIMITER (EITHER
; 	SINGLE CHARACTER OR RESERVED WORD) LSCAN SETS
;	A3 EQUAL TO THE LEXEME OF THAT DELIMITER.
; 
; 		2.  IF THE ITEM IS A LITERAL CONSTANT
; 	LSCAN SETS A3 EQUAL THE LEXEME FOR THAT
; 	CONSTANT (PUTTING THE CONSTANT IN THE OBJECT
; 	MODULE'S CONSTANT TABLE IF NECESSARY), AND
; 	SKIP-RETURNS.
; 
; 		3.  IF THE ITEM IS AN IDENTIFIER NAME
; 	LSCAN PLACES IN A3 A POSITIVE NUMBER (A
; 	BUFFER ADDRESS), AND SKIP-RETURNS.  THIS NUMBER
; 	IS THE INPUT PARAMETER TO THE ROUTINE "SEARCH"
; 	WHICH IS USED TO PRODUCE THE LEXEME FOR THE
; 	IDENTIFIER.


LSCAN:	SKIPE	A3,BLEX		; IF THERE IS A BUFFERED LEXEME
	JRST	BLEXR		; THEN TREAT SEPARATELY
	LDB	A1,P		; PICK UP 1ST CHAR
	SKIPE	A2,CTABLE(A1)	; LOAD TABLE ENTRY, SKIP IF DELIM
	JRST	@TABLE1(A2)	; JUMP TO APPROPRIATE ROUTINE
	JRST	DELIM
	DIGITS			; NUMBERS
	LETTER			; LETTERS
TABLE1:	DELIM			; DELIMITERS
	FLAGD			; DELIMITERS (FLAGGED)
	SPACE			; IGNORABLES
	SPACE			; SPACE & TAB
	NEW1			; NEW-LINE
	LOWER			; LOWER CASE
	OTHER			; OTHER CHARS
	SQUOTE			; SINGLE QUOTE


	; SPACE OR TAB

SPACE:	CAIN	A1,.TAB		; IF IT IS A TAB
	PUSHJ	SP,TAB		; COMPUTE ITS LENGTH
	ILDB	A1,P		; GET ANOTHER CHAR
	AOSA	CC		; STEP POSITION COUNT

	; END OF LINE - WATCH THE SPACING HERE !

NEW1:	PUSHJ	SP,NEWLINE	; PROCESS LISTING, GET NEXT CHAR
	JFCL			; NO-OP

NEW3:	MOVE	A2,CTABLE(A1)	; LOAD TABLE ENTRY
	JRST	@TABLE1(A2)	; JUMP TO APPROPRIATE ROUTINE

	; FLAGGED CHAR:   : < > !

FLAGD:	CAIN	A1,.EXCL	; IF CHAR IS A "!"
	JRST	COMNT0		; THEN PROCESS COMMENT
	MOVE	A4,A1		; COPY CHARACTER TO A4
	JSP	A6,IGST		; READ THE NEXT CHARACTER
	CAIN	A1,.EQUAL	; IS IT AN "=" ??
	JRST	FLAGD1		; -YES, ITS A 2-CHAR DELIM
	MOVE	A3,SCDLT(A4)	; PICK UP LEXEME FOR DELIM
	POPJ	SP,		; EXIT LSCAN
	; :=, <=, OR >=

FLAGD1:	MOVE	A3,TCDLT-.COLON(A4); GET DELIMETER LEXEME
	JRST	SQOK2		; EXIT LSCAN

	; A SPECIAL CHARACTER WAS SCANNED

OTHER:	HLRZ	A2,CTABLE(A1)	; GET LEFT HALF OF CHARS TABLE ENTRY
	JRST	@TABLE3(A2)	; JUMP THROUGH TABLE 3


TABLE3:	ILLEGAL			; ILLEGAL CHARACTER
	POWER			; @ &
	SCON			; " $ %
	DOT			; .


	; SPECIAL CONSTANT

SCON:	CAIN	A1,.%		; A "%" INDICATES
	JRST	OCTAL		; AN OCTAL CONSTANT
	CAIN	A1,.$		; A "$" INDICATES
	JRST	DOLLAR		; A SYMBOL CONSTANT
	JRST	STRING		; OTHERWISE, MUST BE A STRING



	; A CONSTANTLESS EXPONENT

POWER:	SETZB	A4,MARKER	; MARK: NO DECIMAL POINT
	MOVEI	A5,1		; SET DOUBLE-LENGTH CONSTANT = 1
	SETZM	FORMAT		; [E044] ASSUME SINGLE PRECISION
	JRST	C22		; [E044] AND JUMP INTO DIGITS
	; A DOT HAS BEEN SCANNED

DOT:	JSP	A6,IGST		; GET THE NEXT CHAR
	MOVE	A3,CTABLE(A1)
	AOJGE	A3,DOT1		; IF NOT DIGIT, DELIMITER
	MOVEI	A3,^D9		; SET LOOP INDEX
	MOVEM	A3,MARKER	; SET DECIMAL POINT MARKER
	SETZB	A4,FORMAT	; [E044] CLEAR HI WORD OF DOUBLE
	MOVEI	A5,-.N0(A1)	; CONVERT 1ST CHAR TO BINARY
	SOJA	A3,LLOOP1	; JUMP INTO "NUMBER"


	; THE DOT IS A DELIMITER

DOT1:	SKIPA	A3,ZDOT		; LOAD ITS LEXEME

BLEXR:	SETZM	BLEX		; CLEAR INDICATOR
	POPJ	SP,		; EXIT LSCAN

	; AN ILLEGAL CHAR HAS BEEN SCANNED

ILLEGAL: FAIL	(93,SOFT,IMM,ILLEGAL CHARACTER)

ILL1:	ILDB	A1,P		; GET NEXT CHAR
	AOS	CC		; STEP POSITION COUNT
	MOVE	A2,CTABLE(A1)	; GET ITS TABLE ENTRY
	CAIN	A2,6		; IF IT TOO IS AN ILLEGAL CHARACTER
	JRST	ILL1		; THEN LOOP WITHOUT PRINTING ANOTHER MSG
	JRST	@TABLE1(A2)	; OTHERWISE JUMP THROUGH TABLE 1
; 	**** CHARACTER TABLE ****
; 
; 	THIS TABLE IS USED TO CLASSIFY EACH OF
; 	THE ASCII CHARACTERS ACCORDING TO THE
; 	FOLLOWING TYPES:
; 
; 	-2	DIGIT
; 	-1	LETTER
; 	0	SINGLE-CHARACTER DELIMITERS
; 	1	FLAGGED DELIMITERS
; 	2	SHOULD BE IGNORED ON INPUT
; 	3	SPACE CHARS (SPACE & TAB)
; 	4	NEW-LINE CHARS (CR, LF, )
; 	5	LOWER CASE LETTERS
; 	6	OTHER CHARS.  
; 		   LEFT HALF:
; 			0 ILLEGAL CHAR
; 			1 @ &
; 			2 " $ %
; 			3 .
; 	7	SINGLE QUOTE
	0	;   -1 PSEUDO ALTMODE (SCANCH)
CTABLE:	2	;   0 NULL
	6	;   1 ^A
	6	;   2 ^B
	6	;   3 ^C
	6	;   4 ^D  (EOT)
	6	;   5 ^E  (WRU)
	6	;   6 ^F
	6	;   7 ^G  (BELL)
	6	;  10 ^H  (BACKSPACE)
	3	;  11 ^I  (TAB)
	4	;  12 ^J  (LINE FEED)
	6	;  13 ^K  (VERT TAB)
	3	;  14 ^L  (FORM)
	4	;  15 ^M  (RETURN)
	6	;  16 ^N
	6	;  17 ^O
	6	;  20 ^P
	2	;  21 ^Q  (XON)
	2	;  22 ^R  (TAPE)
	2	;  23 ^S  (XOFF)
	2	;  24 ^T  (NOTAPE)
	6	;  25 ^U
	6	;  26 ^V
	6	;  27 ^W
	6	;  30 ^X
	6	;  31 ^Y
	4	;  32 ^Z
	6	;  33 ^LBRAC  (ESC)
	6	;  34 ^\
	6	;  35 ^RBRAC
	6	;  36 ^^
	6	;  37 ^_
	3	;  40 SPACE
  XWD  1,1	;  41 !
  XWD  2,6	;  42 "
	0	;  43 #
  XWD  2,6	;  44 $
  XWD  2,6	;  45 %
  XWD  1,6	;  46 &
	7	;  47 '
	0	;  50 (
	0	;  51 )
	0	;  52 *
	0	;  53 +
	0	;  54 ,
	0	;  55 -
  XWD  3,6	;  56 .
	0	;  57 /
	-2	;  60 0
	-2	;  61 1
	-2	;  62 2
	-2	;  63 3
	-2	;  64 4
	-2	;  65 5
	-2	;  66 6
	-2	;  67 7
	-2	;  70 8
	-2	;  71 9
	1	;  72 :
	0	;  73 ; 
	1	;  74 LESS THAN
	0	;  75 =
	1	;  76 GRTR THAN
	6	;  77 ?
  XWD  1,6	; 100 @
	-1	; 101 A
	-1	; 102 B
	-1	; 103 C
	-1	; 104 D
	-1	; 105 E
	-1	; 106 F
	-1	; 107 G
	-1	; 110 H
	-1	; 111 I
	-1	; 112 J
	-1	; 113 K
	-1	; 114 L
	-1	; 115 M
	-1	; 116 N
	-1	; 117 O
	-1	; 120 P
	-1	; 121 Q
	-1	; 122 R
	-1	; 123 S
	-1	; 124 T
	-1	; 125 U
	-1	; 126 V
	-1	; 127 W
	-1	; 130 X
	-1	; 131 Y
	-1	; 132 Z
	0	; 133 LBRAC
	6	; 134 \
	0	; 135 RBRAC
	0	; 136 ^
	0	; 137 _
	6	; 140 LEFT SINGLE QUOTE
	5	; 141 LA
	5	; 142 LB
	5	; 143 LC
	5	; 144 LD
	5	; 145 LE
	5	; 146 LF
	5	; 147 LG
	5	; 150 LH
	5	; 151 LI
	5	; 152 LJ
	5	; 153 LK
	5	; 154 LL
	5	; 155 LM
	5	; 156 LN
	5	; 157 LO
	5	; 160 LP
	5	; 161 LQ
	5	; 162 LR
	5	; 163 LS
	5	; 164 LT
	5	; 165 LU
	5	; 166 LV
	5	; 167 LW
	5	; 170 LX
	5	; 171 LY
	5	; 172 LZ
	6	; 173 LEFT BRACE
	6	; 174 VERTICAL BAR
	3	; 175 RIGHT BRACE (ALTMODE)
	6	; 176 NOT
	2	; 177 DELETE
;	*****  L E T T E R  *****
;
;	"LETTER" SCANS IDENTIFIER NAMES AND RESERVED WORDS,
;	UNLESS RESERVED WORDS ARE QUOTED.  "LETTER" WILL OUTPUT 
;	THE LEXEME OF A RESERVED WORD OR THE BUFFER ADDRESS OF AN
;	IDENTIFIER.
;
;	"LETTER" READS CHARACTERS 6 AT A TIME.  THE 7-BIT 
;	CHARACTERS ARE READ INTO REGISTER A1 WITH AN ILDB AND
;	THEN 6 OF THESE BITS ARE SHIFTED INTO REGISTER A2 WITH
;	A "LSHC A1,-6" .  WHEN REGISTER A2 IS FULL IT IS DUMPED
;	INTO THE NEXT WORD OF A NAME BUFFER.  THUS THE NAME IS 
;	STORED IN A NAME BUFFER, 6 CHARACTERS PER WORD (NOT
;	THE SAME AS "SIXBIT" CHARACTERS), WITH THE CHARACTERS IN
;	REVERSE ORDER, AND WITH BLANKS ON THE RIGHT.  THE RIGHT-MOST
;	6 BITS OF THE 1ST WORD OF THE NAME IN THE NAME BUFFER 
;	CONTAIN THE LENGTH OF THE NAME IN CHARACTERS MINUS 1.  
;	THE WORD IMMEDIATELY PRECEDING THE NAME BUFFER CONTAINS
;	THE LENGTH OF THE NAME IN WORDS MINUS 1.  
;
;	UNLESS RESERVED WORDS ARE QUOTED, THE NAME IS THEN LOOKED
;	UP IN THE RESERVED WORD TABLE TO FIND OUT IF IT IS A RESERVED
;	WORD.  IF IT IS FOUND, THE LEXEME IS OUTPUT, AND THE NAME
;	BUFFER WILL BE USED AGAIN AT THE NEXT CALL TO "LETTER".
;	IF IT IS NOT FOUND, THE NAME BUFFER ADDRESS IS OUTPUT.  
;	THIS ADDRESS IS USED BY "SEARCH" TO LOCATE THE IDENTIFIER
;	IN THE SYMBOL TABLE.  THE NEXT CALL TO "LETTER" WILL NOT
;	USE THE SAME NAME BUFFER, THUS "SEARCH" DOES NOT HAVE TO
;	BE CALLED IMMEDIATELY.  "LETTER" CURRENTLY ROTATES AMONGST
;	THREE NAME BUFFERS.
;


LOWER:	MOVEI	A1,-40(A1)	; CONVERT TO UPPER CASE

LETTER:	SKIPE	A5,RWS		; IF RESERVED MODE
	MOVE	A5,@A5		; LOCATE RESERVED WORD SUBLIST
	MOVEM	A5,RWSL		; SAVE IT FOR LATER
	AOSA	A3,LSBUFP	; GET LIST INDEX AND SKIP
	SETZM	LSBUFP		; ZERO INDEX
	SKIPN	A3,LSBUFT(A3)	; LOCATE A NAME BUFFER
	JRST	.-2		; -RECYCLE
	SETZ	A2,		; CLEAR A2
	HRLZI	A5,-5		; SCAN 1ST 5 CHARS
	HRLZI	A6,-13		; BUT NO MORE THAN 65 CHARS
	; CHARACTER-READING LOOP

LET1:	LSHC	A1,-6		; MOVE CHAR TO ACC A1
	ILDB	A1,P		; GET NEXT CHAR
	AOS	CC		; STEP POSITION COUNT
	SKIPL	A4,CTABLE(A1)	; CHECK IF LETTER OR NUMBER
	JRST	@TABLE2(A4)	; -NO, GOTO A ROUTINE

LET2:	AOBJN	A5,LET1		; LOOP

	; END OF 6-CHAR GROUP

	MOVEM	A2,@A3		; SAVE CHARS IN NAME BUFFER
	SETZ	A2, 		; CLEAR A2
	HRLI	A5,-6		; READ NEXT 6 CHARS
	AOBJN	A6,LET1		; BUT NOT PAST 65 CHARS


	; LINE EXCEEDS 64 CHARS

LET3:	MOVEI	A6,-1(A6)	; BACK UP COUNTER
	FAIL	(91,SOFT,IMM,NAME EXCEEDS 64 CHARACTERS)
	PUSHJ	SP,ATNAC	; ADVANCE TO NEXT ALPHAMERIC CHARACTER
	MOVEI	A5,77		; MAKE NAME 63 CHARACTERS LONG
	MOVEI	A6,12		; MAKE NAME 11 WORDS LONG
	JRST	LET4+3		; CONTINUE


TABLE2:	LET4			; DELIMITERS
	LET4			; DELIMITERS (FLAGGED)
	LET1+1			; IGNORABLES
	LET12			; SPACE & TAB
	LET13			; NEW-LINE
	LET11			; LOWER CASE
	LET14			; OTHER
	LET4			; SINGLE QUOTE

LET12:	SKIPN	RWS		; RESERVED WORD MODE?
	JRST	LET1+1		; NO - IGNORE
	; END OF NAME, CHECK IF RESERVED WORD

LET4:	MOVEM	A2,@A3		; SAVE LAST GROUP OF CHARS
	TRNE	A5,100		; IF NAME IS 65 CHARACTERS LONG
	JRST	LET3		; THEN GIVE ERROR
	HRRZM	A6,-1(A3)	; PUT LENGTH-IN-WORDS IN BUFFER
	MOVEI	A6,(A5)		; PUT LENGTH-IN-CHARS IN A6
	IORB	A6,(A3)		; PUT LENGTH IN BUFFER, PICK UP 1ST WORD

SQ3:	SKIPN	A5,RWSL		; IS THERE A SUBLIST?
	JRST	LET9		; -NO, SKIP EVERY THING

LET7:	CAME	A6,RWTNAM(A5)	; DO 1ST WORDS MATCH?
	JRST	LET8		; -NO, CONTINUE SEARCH

LET5:	SKIPL	A4,RWTLEN(A5)	; IS NAME 1 WORD LONG?
	JRST	LET6		; -NO, 2 WORDS LONG

LET10:	MOVE	A4,1(A3)	; GET 2ND WORD OF NAME BUFFER
	CAME	A4,RWTNAM+1(A5)	; DO 2ND WORDS MATCH
	JRST	LET8		; -NO, CONTINUE

	; NAME FOUND IN RESERVED-WORD TABLE

LET6:	MOVE	A3,RWTLEX(A5)	; LOAD LEXEME
	SKIPE	RWS		; IF RESERVED WORD MODE
	SOS	LSBUFP		; RELEASE BUFFER
	CAIGE	A5,FRW		; IS RESERVED WORD FLAGGED?
	JRST	@RWTRT(A5)	; -YES, GOTO ROUTINE
	POPJ	SP,		; -NO, LSCAN



LET8:	HRRZ	A5,RWTLNK(A5)	; LOCATE ENTRY ON SUBLIST
	JUMPN	A5,LET7		; LOOP UNLESS LINK=0

	;;; GENERAL SKIP RETURN POINT

	; NAME IS NOT A RESERVED WORD - IS AN IDENTIFIER

LET9:	POP	SP,A4		; GET RETURN LINK
	JRST	1(A4)		; SKIP RETURN

	; LOWER-CASE LETTER SCANNED

LET11:	MOVEI	A1,-40(A1)	; CONVERT TO UPPER CASE
	JRST	LET2		; CONTINUE
LET13:	PUSHJ	SP,NCHECK	; INPUT NEXT LINE
	JRST	LET1+3		; -END OF BUFFER IN MID LINE, CONTINUE
	JRST	LET4		; END OF NAME


LET14:	CAIE	A1,.DOT		; IF THIS IS A DOT
	JRST	LET4		; ELSE END OF NAME
	PUSH	SP,A6		; SAVE A6
	PUSH	SP,A2		; SAVE A2
	JSP	A6,GETCHR	; READ NEXT CHARACTER
	POP	SP,A2		; RESTORE A2
	POP	SP,A6		; RESTORE A6
	SKIPGE	CTABLE(A1)	; IF IT IS A LETTER OR A NUMBER
	JRST	LET2		; THEN CONTINUE WITH IDENTIFIER NAME
	MOVE	A4,ZDOT		; ELSE BUFFER THE LEXEME FOR
	MOVEM	A4,BLEX		; THE DELIMITER "DOT"
	JRST	LET4		; END OF IDENTIFIER NAME
	; THE FOLLOWING ROUTINES PROCESS THE FLAGGED RESERVED WORDS

FBEGIN:	SOSGE	A5,BTI		; DECREMENT BEGIN TABLE INDEX
	POPJ	SP,		; EXIT LSCAN IF TABLE IS FULL
	AOS	A4,BNUM		; ADD 1 TO BEGIN NUMBER
	MOVEM	A4,BTAB(A5)	; STORE NUMBER IN TABLE
	POPJ	SP,		; EXIT LSCAN



FEND:	AOSG	A4,BTI		; STEP BEGIN TABLE INDEX
	POPJ	SP,		; EXIT LSCAN IF TABLE STILL FULL
	SKIPE	A4,BTAB-1(A4)	; LOAD BEGIN NUMBER (DON'T PRINT E0)
	MOVEM	A4,ENUM		; SAVE FOR PRINTING
	POPJ	SP,		; EXIT LSCAN

	; A "GO" HAS BEEN SCANNED, NOW SEARCH FOR THE "TO"

FGO:	LDB	A1,P		; GET LAST CHAR
	MOVE	A2,CTABLE(A1)	; GET ITS TABLE ENTRY

FGO1:	CAIE	A2,3		; IF IT  IS NOT A SPACE OR A TAB
	JRST	GOERR2		; THEN HE BLEW IT
	JSP	A6,GETCHR	; GET ANOTHER CHAR
	CAIE	A1,.T		; IF IT IS NOT A "T"
	JRST	FGO1		; THEN SEARCH NEXT CHAR
	JSP	A6,GETCHR	; GET ANOTHER CHAR
	CAIE	A1,.O		; IF IT IS NOT A "O"
	JRST	GOERR1		; THEN IT IS WRONG
	JSP	A6,GETCHR	; GET ANOTHER CHAR
	CAIE	A2,-1		; THIS CHARACTER MUST NOT BE AN UPPER
	CAIN	A2,5		; OR LOWER CASE LETTER
	JRST	GOERR1		; OR IT IS AN ERROR

FGO2:	MOVE	A3,ZGOTO	; LOAD LEXEME
	POPJ	SP,		; EXIT LSCAN

GOERR1:	PUSHJ	SP,ATNAC		; ADVANCE TO NON-ALPHAMERIC CHAR

GOERR2:	FAIL	(99,SOFT,IMM,DID NOT FIND 'TO' IN 'GOTO' STATEMENT) ; [273]
	JRST	FGO2
COMNT2:	SKIPN	RWS		; 'COMMENT': IF QUOTED MODE
	JRST	[POP	SP,A1		; [273] THEN LOSE LINK FROM SQUOTE
		JRST	COMNT1]		; [273] AND PARSE COMMENT
	TDZA	A1,A1		; AND CLEAR A1

COMNT0:	MOVEI	A1,-1		; "!": FLAG A1
	CAME	DEL,ZEND	; IF DEL#END
EDIT(104); Allow comment to go over newlines without error.
	JRST	COMNT4		; [E104] THEN PROCEED
	;
	Edit(161); Accept COMMENT after END without error.
	;
	SKIPE	A1		; [E161] ELSE if "!" then 
	JSP	A6,GETCHR	; [E161]  get next character
	JRST	LSCAN		; [E161] and let SBEGIN process comment.
COMNT4:	PUSHJ	SP,COMNT3(A1)	; [E104] DISPATCH TO IGNORE COMMENT
	IBP	P		; [E104] THEN STEP BYTE POINTER
	AOS	CC		; [E104] AND CHARACTER COUNT
	JRST	LSCAN		; [E104] TO IGNORE SEMICOLON

NEW2:	PUSHJ	SP,NEWLINE	; CALL NEWLINE (SKIP RETURN!)
COMNT1:	JSP	A6,GETCHR	; GET NEXT CHAR
COMNT3:	LDB	A1,P		; GET THE CHARACTER
	MOVE	A2,CTABLE(A1)	; GET ITS TABLE ENTRY
	CAIN	A2,4		; IF IT IS A NEW-LINE CHAR
	JRST	NEW2		; THEN HANDLE SPECIALLY
	CAIN	A1,.SEMI	; [273] IF IT'S A SEMI-COLON
	POPJ	SP,		; [273][E104] THEN RETURN
	SKIPE	RWS		; [273] ELSE, RESERVED WORD MODE?
	JRST	COMNT1		; [273] NO, JUST LOOP UNTIL SEMICOLON FOUND
	CAIE	A2,7		; [273] YES, IS CHR. A SINGLE-QUOTE?
	JRST	COMNT1		; [273] NO, CONTINUE LOOPING
	FAIL	(92,SOFT,IMM,RESERVED WORD DELIMITER NOT ALLOWED HERE) ; [273]
	JRST	COMNT1		; [273] YES, ERROR AND CONTINUE SCANNING COMMENT
44;	*****  D I G I T S  *****
;
;	"DIGITS" IS USED TO SCAN DECIMAL CONSTANTS.  "DIGITS"
;	WILL COMPUTE THE VALUE, PUT IT INTO THE CONSTANTS TABLE
;	IF NECESSARY, AND PRODUCE THE LEXEME.
;
;	"DIGITS" WORKS BY READING THE 1ST 10 DIGITS WITH A
;	QUICK 7-INSTRUCTION LOOP (LLOOP1) THAT ALWAYS PRODUCES AN INTEGER.
;	IF A DECIMAL POINT IS ENCOUNTERED, THE LOOP INDEX IS SAVED
;	IN "MARKER" AND USED LATER TO DETERMINE THE POWER OF TEN, 
;	THEN CONTROL RETURNS TO THE LOOP.  IF THERE ARE MORE THAN
;	TEN DIGITS, CONTROL PASSES TO A SECOND LOOP (LLOOP2) THAT
;	READS DIGITS INTO THE DOUBLE AC 4-5 ABSORBING A DECIMAL
;	POINT IF NECESSARY.   FINALLY
;	THE CONSTANT IS CONVERTED TO THE INDICATED TYPE.
;	SINGLE-PRECISION FLOATING POINT IS FIRST CONVERTED TO
;	DOUBLE-PRECISION FLOATING POINT, THEN THE POWER OF TEN
;	IS INCLUDED.  THIS IS DONE SO THAT ALL 27 BITS OF THE
;	FRACTION ARE ACCURATE.
;	ROUNDING TO SINGLE-PRECISION IS DONE LATER, IF NECESSARY, BY
;	CONVERT.
;

DIGITS:
	; SET UP FOR READING DIGITS

	MOVEI	A3,^D9		; READ 1ST 9 DIGITS OF NUMBER
	SETZB	A4,MARKER	; CLEAR DECIMAL POINT MARKER
	SETZM	EXTRA		; AND EXTRA DIGIT COUNT
EDIT(044); Dont force constants to D.P. unnecessarily
	SETZM	FORMAT		; [E044] ASSUME IT WILL BE SINGLE PRECISION
	MOVEI	A5,-.N0(A1)	; CONVERT 1ST CHAR TO BINARY

	; MAIN LOOP FOR SCANNING NUMBER

LLOOP1:	ILDB	A1,P		; READ NEXT CHAR
	AOS	CC		; STEP POSITION COUNT

C1:	MOVE	A2,CTABLE(A1)	; GET CHAR'S TABLE ENTRY
	JRST	@TABLE4(A2)	; JUMP THROUGH TABLE 4

C2:	IMULI	A5,^D10		; MULT PREVIOUS RESULT BY TEN
	ADDI	A5,-.N0(A1)	; ADD IN NEW DIGIT
	SOJG	A3,LLOOP1	; LOOP

	; NUMBER IS LONGER THAN 10 CHARS

	MOVEI	A3,30000	; SET A NEW INDEX
	SKIPE	MARKER		; IF A DECIMAL POINT HAS OCCURRED
	ADDM	A3,MARKER	; THEN ADD NEW INDEX TO MARKER
	; LOOP THAT READS UNTIL OVERFLOW

LLOOP2:	JSP	A6,IGST		; READ NEXT CHAR
	CAIN	A1,.DOT		; IF IT IS A DOT
	JRST	C3		; THEN EXIT THIS LOOP
	MOVE	A2,CTABLE(A1)	; IF CHAR IS NOT NUMERIC
	AOJGE	A2,@TABLE4(A2)	; GO ELSEWHERE
	EXCH	A4,A5		; SWAP TO LONG MULTIPLY
	MULI	A4,^D10		; MULTIPLY SUM SO FAR
	ADDI	A5,-.N0(A1)	; AND ADD THE NUMBER
	TLZE	A5,(1B0)	; [E044] OVERFLOW INTO TOP BIT ?
	AOJA	A4,C6D		; [E044] YES - ADD IT IN TO A4
	JUMPN	A4,C6D		; IF A4 NON-ZERO SUM V. LARGE
	SOJA	A3,LLOOP2	; KEEP GOING

C3:	MOVEM	A3,MARKER	; STORE DECIMAL POINT MARKER
	
;	MAIN LOOP FOR SCANNING LONG NUMBERS

LLOOP3:	ILDB	A1,P		; GET NEXT CHAR
	AOS	CC		; STEP POSITION COUNT

C5:	MOVE	A2,CTABLE(A1)	; GET(TABLE ENTRY
	JRST	@TABLE5(A2)	; AND USE TABLE5
C6:	MOVEM	A5,COPY		; LONG INTEGER MULTIPLY
	MULI	A4,^D10		; MULTIPLY HIGH-ORDER WORD
	JUMPN	A4,C6A		; TOO BIG IF NON-ZERO
	MOVE	A4,COPY		; NOW THE LOW-ORDER
	MOVEM	A5,COPY		; INTO THE CORRECT HALF
	MULI	A4,^D10		; MULTIPLY LOW-ORDER WORD
	ADDI	A5,-.N0(A1)	; ADD IN THE NEW NUMBER
	ADD	A4,COPY		; ADD BACK THE HIGH ORDER WORD
	TLZE	A5,(1B0)	; [E044] CARRY INTO TOP BIT OF LOW WORD ?
	ADDI	A4,1		; [E044] YES - ADD IN TO HIGH WORD
C6D:	SOJA	A3,LLOOP3	; AND KEEP GOING

C6A:	DIVI	A4,^D10		; RESTORE THE ORIGINAL NUMBER
	MOVE	A5,COPY		; RESTORE LOW-ORDER WORD
	SKIPE	MARKER		; IF DECIMAL POINT EVER SCANNED
	JRST	C6C		; DON'T WORRY
;
; OTHERWISE NUMBER IS TOO LARGE - SAY SO
;
	CAIL	A1,"5"		;
	ADDI	A5,1		; ROUND IN IGNORED DIGIT
	MOVE	A1,[..IMM,,^D98]
	PUSHJ	SP,.FAILED
	AOS	EXTRA		; ALLOW FOR DIGIT JUST IGNORED
C6C:	AOS	CC
	ILDB	A1,P		; NEXT CHAR
	MOVE	A2,CTABLE(A1)	; GET ITS TABLE ENTRY
	AOJGE	A2,@TABLE5(A2)
	SKIPN	MARKER		; IF NO DECIMAL POINT SEEN,
	AOS	EXTRA		; COUNT IGNORED DIGITS
	JRST	C6C		; AND KEEP IGNORING
	C2			; NUMBER
	C8			; LETTER
TABLE4:	C8			; DELIMITER
	C8			; DELIMITER (FLAGGED)
	LLOOP1			; IGNORABLE CHARACTER
	LLOOP1			; SPACE & TAB
	C8B			; NEW-LINE
	C8			; LOWER CASE LETTER
	C10			; OTHER (E.G. PERIOD, &, @)
	C8			; SINGLE QUOTE



C8B:	PUSHJ	SP,NCHECK	; INPUT NEXT LINE
	JRST	C1		; -END OF BUFFER IN MID LINE, CONTINUE

	; NORMAL END OF NUMBER

C8:	SKIPE	MARKER		; IF A DECIMAL POINT WAS EVER SCANNED
	JRST	C18		; THEN THE NUMBER IS DOUBLE-FLOATING

C8A:	TLNE	A5,777777	; IF LEFT HALF OF VALUE IS NON ZERO
	JRST	C9		; THEN NUMBER IS NOT INTEGER-IMMEDIATE

	; THE CONSTANT IS AN INTEGER-IMMEDIATE

	MOVE	A3,A5		; MOVE CONSTANT TO A3 FOR OUTPUT
	HRLI	A3,$EXP+$I+$SIM+$DEC+$IMM; LEXEME TYPE FIELDS
	JRST	LET9		; EXIT LSCAN

	; THE CONSTANT IS AN INTEGER FULLWORD

C9:	PUSHJ	SP,CON1Z		; SEARCH CONSTANTS TABLE
	HRLI	A3,$EXP+$I+$SIM+$DEC+$CT; LEXEME LEFT HALF
	JRST	LET9		; EXIT LSCAN
	; A SPECIAL CHARACTER WAS SCANNED

C10:	HLRZ	A2,CTABLE(A1)	; GET LEFT HALF OF CHAR'S TABLE ENTRY
	JRST	@TABLE6(A2)	; JUMP THROUGH TABLE 6

TABLE6:	C19			; ILLEGAL CHARACTER
	C22			; [E044] @ &
	C20			; " $ %
	C16			; .

	; A DOT WAS SCANNED

C16:	SKIPE	MARKER		; IF MARKER NOT ZERO THEN THERE ARE
	JRST	C17		; TWO DECIMAL POINTS IN THIS CONSTANT
	MOVEM	A3,MARKER	; SET DECIMAL POINT MARKER
	JRST	LLOOP1		; RETURN TO LOOP
	; CONSTANT CONTAINS TWO DECIMAL POINTS

C17:	PUSHJ	SP,BADNAC	; PRINT ERROR MSG, USE ATNAC

	; CONVERT CONSTANT TO DOUBLE-FLOATING

C18:	SUB	A3,MARKER	; FIX SCALING CONSTANT
	JRST	C13		; HALVES AND CONTINUE



	; AN ILLEGAL CHARACTER WAS SCANNED

C19:	PUSHJ	SP,BADNAC	; PRINT ERROR MESSAGE, USE ATNAC
	JRST	C8		; CONTINUE

C20:	PUSHJ	SP,BADCON	; PRINT ERROR MSG
	JRST	C8		; CONTINUE

	C6			; NUMBER
	C30			; LETTER
TABLE5:	C28			; DELIMITER
	C28			; DELIMITER (FLAGGED)
	LLOOP3			; IGNORABLE
EDIT (215);	CHANGE AT TABLE5 + 3	CLRH	17-JULY-79
	LLOOP3			;[215] SPACE AND TAB
;[215]	C28			; SPACE & TAB
	C36			; NEW-LINE
	C30			; LOWER CASE LETTER
	C21			; OTHER
	C28			; SINGLE QUOTE
	; A SPECIAL CHAR WAS SCANNED

C21:	HLRZ	A2,CTABLE(A1)	; GET LEFT HALF OF CHAR'S TABLE ENTRY
	JRST	@TABLE7(A2)	; JUMP THROUGH TABLE 7

TABLE7:	C27			; ILLEGAL CHARACTER
	C22			; @ &
	C30			; " $ %
	C25			; .

	; A @ OR & WAS SCANNED

C22:	JSP	A6,IGST		; GET NEXT CHAR
	CAIE	A1,.AAAAA	; IF IT IS A @
	CAIN	A1,.AMPER	; OR A &
	AOSA	FORMAT		; [E044] THEN REMEMBER IT WAS
	JRST	C24		; [E044] ELSE CARRY ON
	JSP	A6,IGST		;[215] IGNORE IT
;[215]	JSP	A6,GETCHR	; [E044] IGNORE IT
;****	JRST	C24		; [E044] FALL THROUGH TO GET EXPONENT

	; PRODUCE LEXEME FOR DOUBLE PRECISION CONSTANT

C24:	PUSHJ	SP,EXPONT	; SCAN THE EXPONENT

C13:	PUSHJ	SP,FCMML	; INCLUDE CORRECT POWER OF TEN
	SKIPE	FORMAT		; [E044] IS THIS EXPLICIT DOUBLE PRECISION ?
	JRST	C13A		; [E044] YES - MUST MAKE DOUBLE-WORD CONSTANT
	JUMPE	A5,C13B		; [E044] NO  - CAN WE USE A SINGLE WORD ?
	TLO	A5,(1B0)	; [E044] NO  - SET SIGN BIT OF SECOND WORD TO 1
C13A:	PUSHJ	SP,CON2		; PUT CONSTANT IN CONSTANT TABLE
	HRLI	A3,$EXP+$LR+$SIM+$DEC+$CT; LEXEME LEFT HALF
	JRST	LET9		; EXIT LSCAN
C13B:	TRNN	A4,-1		; [E044] CAN THIS BE AN IMMEDIATE CONSTANT ?
	JRST	C13C		; [E044] YES - GO FORM THE LEXEME
	PUSHJ	SP,CON1		; [E044] NO  - ENTER IT IN THE TABLE
	HRLI	A3,$EXP+$R+$SIM+$DEC+$CT; [E044] FORM LEXEME
	JRST	LET9		; [E044] EXIT FROM LSCAN
C13C:	HLRZ	A3,A4		; [E044] IMMEDIATE REAL CONSTANT - GET VALUE
	HRLI	A3,$EXP+$R+$SIM+$DEC+$IMM; [E044] SET LEXEME BITS IN L.H.
	JRST	LET9		; [E044] AND EXIT FROM LSCAN


	; A DOT WAS SCANNED

C25:	SKIPE	MARKER		; IF MARKER NOT ZERO THEN THERE ARE
	JRST	C26		; TWO DECIMAL POINTS IN THIS CONSTANT
	MOVEM	A3,MARKER	; SET DECIMAL POINT MARKER
	JRST	LLOOP3		; RETURN TO LOOP
	; EITHER A LETTER OR TWO DECIMAL POINTS APPEARED IN CONSTANT

C26:	PUSHJ	SP,BADNAC	; PRINT ERROR MSG, USE ATNAC
	JSP	A6,IGST		; GET NEXT CHAR
	CAME	A1,.AAAAA	; IF IT IS A @
	CAMN	A1,.AMPER	; OR A &
	JRST	C22		; THEN CONTINUE AS DOUBLE-PRECISION
	JRST	C28		; ELSE CONVERT TO SINGLE-PRECISION



	; A STRANGE CHAR APPEARED IN CONSTANT

C27:	PUSHJ	SP,BADNAC	; PRINT ERROR MSG, USE ATNAC
	JRST	C28		; CONTINUE

C30:	PUSHJ	SP,BADCON	; PRINT ERROR MESSAGE

C28:	SKIPE	MARKER		; IF A DECIMAL POINT WAS EVER SCANNED
	JRST	C29		; THEN JUMP OVER THIS PART

	; INTEGER TOO LARGE FOR INTEGER

	MOVE	A1,[		; LOAD PARAMETER FOR MESSAGE
	XWD	..IMM,^D98