Google
 

Trailing-Edge - PDP-10 Archives - decuslib10-05 - 43,50337/10/lc.mac
There are 2 other files named lc.mac in the archive. Click here to see a list.
	SEARCH	SIMMAC,SIMMC1
	SALL
	CTITLE	LC
	SUBTTL	WRITTEN BY OLOF BJ@RNER/ENEA JUN-73

COMMENT ;
AUTHOR:		OLOF BJ@RNER
		EDITED JULY 1974

VERSION:	4 [6,14,46,144,171,202,262]

PURPOSES:	1. TO FETCH THE NEXT LINE FROM THE SOURCE CODE TO THE INTERNAL
		   LINE BUFFER, YLCLB
		2. TO UPDATE THE INTERNAL LINE COUNTER, YLSNLIN
		3. TO OUTPUT THE INTERMEDIATE SOURCE FILE nnnLS1.TMP.

CONTENTS:	THE FOLLOWING SUBROUTINES:
		- LCEOF FOR HANDLING EOT WORD IN YLCLB
		- LCLINE FOR UPDATING OF YLSNLIN
		- LCLS1 FOR OUTPUT OF RECORDS TO nnnLS1.TMP
		- LCMORE/LCNEXT FOR READING NEXT SOURCE CODE BUFFER
		- LCPLIN FOR OUTPUT OF LS1 CONTROL RECORDS TYPE 4
		- LC FOR RETRIEVING NEXT SOURCE CODE LINE
;

	TWOSEG
	RELOC	400000

	INTERN	LCEOF,LC,LCLS1

	EXTERN	I1OPAB	;OPEN FAILURE ROUTINE
	EXTERN	I1SC	;SUBROUTINE FOR SCANNING OF NEXT INPUT FILE NAME
	EXTERN	I1SWIT	;SUBROUTINE FOR PROCESSING OF COMMAND SWITCHES
	EXTERN	O1SCOP	;SUBROUTINE FOR OPENING OF NEXT SOURCE FILE
	EXTERN	O1SC	;SUBROUTINE FOR INPUT OF SOURCE CODE
	EXTERN	O1LS1	;SUBROUTINE FOR OUTPUT OF nnnLS1.TMP
	EXTERN	T1AB	;PASS 1 TERMINATION ROUTINE
	EXTERN	YBEGNO	;TOTAL NO OF BEGINS IN THIS COMPILATION
	EXTERN	YENDNO	;TOTAL NO OF ENDS IN THIS COMPILATION
	EXTERN	YELIN1	;FIRST LINE NUMBER IN ERROR MESSAGE
	EXTERN	YELIN2	;LAST  LINE NUMBER IN ERROR MESSAGE
	EXTERN	Y11BUF	;SOURCE CODE BUFFER
	EXTERN	YI1P1	;SAVE AREA FOR POINTER TO SWITCHES AFTER SOURCE
	EXTERN	YI1SWF	;SWITCH SET BY I1, IF 0 THEN FIRST
			;LC CALL FOR THIS COMPILATION
	EXTERN	YLCRT4	;BUFFER FOR RECORD TYPE 4
	EXTERN	YLCLBS	;CONTAINS BYTE POINTER TO FIRST
			;BYTE IN CURRENT LINE
	EXTERN	YLCLN	;CONTAINS SWITCH YLCLNS
	EXTERN	YLCLNO	;HOLDS LINE NUMBER FROM SOURCE LINE
	EXTERN	YLCBEG	;NUMBER OF BEGINS
	EXTERN	YLCEND	;NUMBER OF ENDS
	EXTERN	YLCADR	;CONTAINS RELATIVE ADDRESS TO CARRIAGE RETURN
	EXTERN	YLCLB	;LINE BUFFER
	EXTERN	YLCLBE	;LAST WORD IN YLCLB, CONTAINS CARRIAGE RETURNS
	EXTERN	YBHLS1	;BUFFER RING HEADER FOR LS1
	EXTERN	YBHSRC	;BUFFER RING HEADER FOR SOURCE INPUT
	EXTERN	YELSRC	;LOOKUP BLOCK FOR SOURCE CODE FILE
	EXTERN	YLTIND	;PONTER TO LOOKUP-TABLE
	EXTERN	YLTAB	;LOOKUP-TABLE
	EXTERN	YI1FN	;FILE SPEC RECORD
	EXTERN	ZLEREC	;PROTOTYPE FOR TYPE 4 RECORD
	SUBTTL	DESCRIPTION OF LC MAIN FUNCTION

COMMENT ;
The following technique is utilized for moving lines:
Data is moved from the source code buffer to the source code line 
buffer, YLCBUF. This is done with two or more block transfers for
effiency reasons. The line buffer is 135 characters long and succeeded
by an extra word, YLCLBE, containing two carriage returns to pick up
too long lines. When LC first is called from the SP module the line
buffer is empty and will be filled by LC. At exit the register
XLCLBP, which must be preserved through pass 1 execution, contains
the byte pointer to the first character in YLCBUF. The Line Scanner
(LS) then starts to scan the buffer. When a break character is
found (line feed, vertical tab or form feed),
LC is called to move next line to the beginning of YLCBUF.
The word YLCLBS contains the byte pointer to the start of the
previous line. XLCLBP points to the character following the break
character at LC entry.

YLCBUF before first move:

	I-----I-----I-----I---------- ... ----------I-----I
YLCLB	I     I     I     I                         I     I  YLCLBE
	I-----I-----I-----I---------- ... ----------I-----I
	   ^			^
	   I			I
	YLCLB		     XLCLBP

	<---- previous line ---->


LC starts to check if XLCLBP points behind the line buffer. The error
message TOO LONG LINE is generated in this case and the first move
is skipped. Then LC determines the break character combination, which
may be either of:
	<LF> (line feed)
	<VT> (vertical tab)
	<FF> (form feed)
	<LF>+<VT>
	<LF>+<FF>.
During this scan nulls are ignored which means that nulls between
lines are scanned by LC and that the too long line message will not
appear when there are many nulls between lines, e.g. after a file
concatenation. If the end of the line buffer is reached during this
scan, LCMORE is called to fill the line buffer with data from the source
buffer. This is repeated until a break character combination is found.
Note that nulls in the middle of lines are scanned by LS and may
cause a too long line error message. When the break character combination
is determined LCPLIN is called to output record types 2,3 and 4 to
the LS1 file.
Then the first move takes place, which means that the remaining
data are shifted left in the line buffer.




	First move:

	<------- --------------><--------- --------->
		^			  I
		I-------------------------I
	I-----I-----I-----I---------- ... ----------I-----I
YLCLB	I     I     I     I                         I     I  YLCLBE
	I-----I-----I-----I---------- ... ----------I-----I
	   ^			^
	   I			I
	YLCLB		     XLCLBP


The second move is done from the source buffer to the part of the
line buffer which is now "empty":

	I-----------------------------...-----------I-----I
YLCLB	I					    I     I  YLCLBE
	I-----------------------------...-----------I-----I
	<-------  next line  -----><-----  -------->
					 ^
					 I
					 I	       buffer:
					 I	    I-------------I
					 I	    I   header	  I
					 I	    I-------------I
					 I	    .		  .
					 I	    .		  .
					 I	    .		  .
					 I	    I-------------I
					 I	    I		  I
					 I----------I		  I
						    I		  I
						    I-------------I
						    .		  .
						    .		  .
						    I-------------I


This second move may have to be split into two moves if the
remaining data in the source buffer is not enough to fill the rest
of the line buffer. O1SC is used to read next source buffer. If end
of file occurs an EOT word in inserted in YLCLB. If it was the last
source code YLCEOF is set to true else the first buffer from the
next source is read and moved to YLCLB. When LS scans the EOT word,
LCEOF is called to update YLTAB. The second move is performed by the
LCMORE subroutine.

When LC has filled YLCLB the first word is checked for external line
number. If a line number is found (bit 35=1) then the line number is
moved to the word YLCLNO and the line number in YLCLB is reset and
the ZLESRC flag in ZLEREC is set to true. This flag is later used
by LCLINE when the line number sequence is checked. Finally
YLCLBS and XLCLBP are adjusted to point to the first byte in next
line and LCLINE is called.

;
	SUBTTL	DESCRIPTION OF YLTAB

COMMENT ;

This table is used to store information about the next source file
to be read. The information is transmitted to pass 3 in the
LS1 file. Since the scanner is normally processing the previous
file when the next source is opened and read, information to pass 3
must be delayed until the scanner has processed the last line of
the previous source. When end of file occurs a special EOT word is
stored in the source line buffer YLCLB. This word is recognized
by the scanner (LS module) and the subroutine LCEOF is called.
LCEOF determines which type of EOT word is encountered and outputs
relevant information from YLTAB to LS1 as described below.

EOT word format:

	0      6      13     18               35
	I------I------I------I----------------I
	I  EOT I  IND I      I       FLAG     I
	I------I------I------I----------------I

IND  =	 index to YLTAB
FLAG =	-1 if end of file on last source
	-3 otherwise


YLTAB contains six entries, each having the following format:

word
  	I----------------------------------I
  1	I            file name             I
	I-----------------I----------------I
  2	I  extension	  I		   I
	I-----------------I----------------I
  3	I		 ppn		   I
	I----------------------------------I
  4	I	       device		   I
	I----------------------------------I
  5	I     byte pointer to switches	   I
	I----------------------------------I
  6	I        switch delimiter	   I
	I----------------------------------I


The first four words are transmitted to LS1. The two last words are
used by LCEOF as input arguments to the I1SWIT subroutine
if there were switches after this file specification (word 5 is
non-zero).

YLCTAB is updated by the LCMORE subroutine at end of file.
The table is used cyclically, which means that overflow may occur.
Word 1 is reset after use by LCEOF. If the table overflows,
i.e. next word 1 is non-zero when LCMORE tries to update YLTAB,
a compile time error occurs and the compilation is prematurely
aborted.


;
	SUBTTL	LOCAL DECLARATIONS


;	REGISTER ASSIGNMENTS
;	====================

	XLC=X1
	XLCLBP=X1LBP

;	THESE ARE USED DURING SHUFFLING OF SOURCE LINE

	XLCSAV=X1SR0
	XLCADR=X1SR1
	XLCLEN=X1SR2
	XLCEND=X1SR3


;	LOCAL ASSEMBLY-TIME CONSTANTS
;	=============================

	QLCRT4="I"B24
	QLCRT9="S"B24
	

	DSW	(YLCEOF,YLCLN,34)	;SET ON WHEN END OF FILE OCCURS
	DSW	(YLCNOL,YLCLN,33)	;SET ON IF NO LINE NO POSSIBLE
	DSW	(YLCOVF,YLCLN,35)	;SET ON WHEN LONG LINE IS DISCOVERED
					;SET OFF WHEN REAL END OF LINE DISCOVERED
	MACINIT			;INITIATE CONDITIONAL STATEMENTS
	LS1INIT

	edit(14)
	SCALAR	(<QLDEL,QVDEL,QFDEL,QLVDEL,QLFDEL,QEFDEL>)	;[14]
					;SYMBOLIC NAMES ON ZLEIND VALUES

	SUBTTL	LCEOF

COMMENT ;
PURPOSE:		THIS SUBROUTINE IS CALLED FROM LS WHEN AN EOT
			IS SCANNED. LCEOF DETERMINES
			WHETHER THIS EOT WAS GENERATED BY LC OR IF IT
			WAS PART OF THE INPUT STREAM. IF IT WAS GENERATED
			BY LC THEN THE RIGHT HALFWORD OF THE SAME
			WORD AS THE EOT CONTAINS EITHER -1 OR -3.
			IF IT IS A FALSE END OF FILE THEN THE EOT WORD CONTAINS
			INDEX TO YLTAB AND LCEOF FETCHES THE LOOKUP INFORMATION
			AND PASSES IT TO THE LS1 FILE THROUGH THE LCLS1
			SUBROUTINE. IF THE SOURCE FILE SPECIFICATION
			INCLUDED SWITCHES YLTAB HAS INFORMATION ABOUT
			DELIMITER AND BYTE POINTER TO THE SWITCH LIST.
			LCEOF LOADS THESE AND CALLS I1SWIT TO PROCESS THEM.
ENTRY:			LCEOF
INPUT ARGUMENT:		ADDRESS TO WORD WITH EOT IN XLCLBP
OUTPUT ARGUMENT:	CONTROL RECORDS ON LS1 IF MORE SOURCES
NORMAL EXIT:		RETURN
ERROR EXIT:		-
CALL FORMAT:		EXEC LCEOF
			 - RETURN HERE IF UNKNOWN EOF
			 - RETURN HERE IF TRUE EOF (-1)
			 - RETURN HERE IF FALSE EOF (-3)
USED SUBROUTINES:	LCLS1,LCLS1T,I1SWIT
USED REGISTERS:
			X0	SCRATCH
			X1	(USED BY LCLS1)
			X1BYTE	ARGUMENT TO I1SWIT
			X11	ARGUMENT TO I1SWIT
			X12	INDEX TO YLTAB
ERROR MESSAGES:		LINE NUMBER EXCEEDS 65535.
;

LCEOF:	PROC
	SAVE	<X11,X12>
	n==2	;Number of quantities on the stack
	HRRZ	X0,(XLCLBP)		;GET RIGHT HALF OF EOF WORD
	IF	CAIN	X0,-1
		GOTO	FALSE		;LAST FILE PROCESSED!
	THEN	CAIE	X0,-3
		GOTO	L9		;UNKNOWN EOF IF NOT -3!!
		;FALSE EOF!
		;ONE MORE SOURCE
		ILDB	X12,XLCLBP
		IF	;SWITCHES
			SKIPN	X11,YLTAB+4(X12)
			GOTO	FALSE
		THEN	;PROCESS THEM NOW
			L	X1BYTE,YLTAB+5(X12)
			EXEC	I1SWIT
		FI
		HRLI	XLCLBP,440700	;ADJUST POINTER TO NEXT WORD
		ADDI 	XLCLBP,1
		HRLZI	QLCRT9		;NOW CREATE RECORD TYPE 9 ON LS1
		EXEC	LCLS1		;and output lookup info
		L	YLTAB+3(X12)	;DEVICE
		PUTLS1
		L	YLTAB(X12)	;File name
		SETZM	YLTAB(X12)	;Clear entry to show it is free
		PUTLS1
		L	YLTAB+1(X12)	;extension
		PUTLS1
					edit(144)
		L	YLTAB+2(X12)	;[144] PPN or SFD pointer
		IF	;[144] SFD pointer
			JUMPE	FALSE
			TLNE	-1
			GOTO	FALSE
		THEN	;Output neg count [-n,,0] of SFD names+1, SFD name list
			ST	X1
			SKIPE	2(X1)
			AOJA	X1,.-1
			SUB	X1,YLTAB+2(X12)
			MOVNI	(X1)
			HRLZ
			PUTLS1
			L	X1,YLTAB+2(X12)
			LOOP
				L	2(X1)
				JUMPE	FALSE
				PUTLS1
			AS
				AOJA	X1,TRUE
			SA
		ELSE
			PUTLS1
		FI	;[144]
		SETOM	YLCADR
		AOS	-n(XPDP)
		GOTO	L8
	FI
	LOOP	;AND SCAN NULLS
		ILDB	X0,YLCLBS
	AS	JUMPE	X0,TRUE
	SA
	IF	;NO CARRIAGE RETURN ON THE LAST LINE
		CAIN	X0,QEOT
		GOTO	FALSE
	THEN	;OUTPUT SPECIAL LINE MARK RECORD TO LS1
		;SO THAT PASS 3 CAN EDIT THE SOURCE CORRECTLY
					edit(14)
		LI	X0,QEFDEL	;[14]
		SF	X0,ZLEIND
		EXEC	LCPLIN
	FI
	LF	X0,YLSNLIN
	IF	;LINE NUMBER EXCEEDS 65534
		CAIG	X0,^D65534	;[1C]
		GOTO	FALSE
	THEN	;ISSUE A WARNING
		ST	X0,YELIN1
		ST	X0,YELIN2
		ERR	QW,Q1LC.W+1
	FI
L8():!
	AOS	-n(XPDP)
L9():!
	RETURN
	EPROC

	SUBTTL	LCLINE SUBROUTINE

COMMENT /
PURPOSE:		TO UPDATE THE INTERNAL LINE NUMBER IN YLSNLIN
			ALGORITHM:
			IF EXTERNAL LINE NUMBER THEN
			   BEGIN CONVERT EXTERNAL TO BINARY;
				 IF LINE NUMBER > PREVIOUS LINE NUMBER THEN
				 BEGIN UPDATE PREVIOUS WITH CURRENT;
				       EXIT
				 END;
				 ERROR:ILL LINE NUMBER
			   END;
			ADD 1 TO PREVIOUS LINE NUMBER;
			EXIT;
ENTRY:			LCLINE
INPUT ARGUMENT:		CONTENT IN YLSNLIN AND EXTERNAL LINE NUMBER
			(IF ANY), ALSO THE SWITCH ZLESRC, WHICH IS ON IF
			THERE ARE EXTERNAL LINE NUMBERS
OUTPUT ARGUMENT:	UPDATED YLSNLIN
NORMAL EXIT:		RETURN
ERROR EXIT:		-
CALL FORMAT:		EXEC LCLINE
USED SUBROUTINE:	ERRT
USED REGISTERS:		XLC	SCRATCH
			X2	SCRATCH
			X1R3	PREVIOUS LINE NUMBER.
ERROR MESSAGES:		ILL LINE NUMBER (Q1LC.W)
/

LCLINE:	PROC
	SAVE	<X1,X2,X3>
	IF	LF	X1R3,YLSNLIN
		IFOFF	ZLESRC
		GOTO	FALSE
	THEN	;THERE WAS AN EXTERNAL LINE NUMBER!
		;CONVERT IT TO BINARY
		LI	XLC,0		;RESET RESULT
		L	X3,YLCLNO	;GET LINE NUMBER
		IF	;NON-BLANK LINE NUMBER
			CAMN	X3,[BYTE (35)"     "(1)1]
			GOTO	FALSE
		THEN	LOOP	;UNTIL END OF LINE NUMBER
				LI	X2,0
				LSHC	X2,7		;NEXT DIGIT TO X2
				IMULI	XLC,^D10	;PREVIOUS RESULT
				ADDI	XLC,-60(X2)	;ADD CURRENT
			AS	TLNN	X3,400000	;MORE DIGITS?
				GOTO	TRUE		;YES!
			SA
		FI
		IF	;EXTERNAL > PREVIOUS
			CAMG	XLC,X1R3
			GOTO	FALSE
		THEN	;UPDATE LINE NUMBER WITH EXTERNAL
			SF	XLC,YLSNLIN
			SETON	ZLEOK
			GOTO	L9
		FI
		SETOFF	ZLEOK
		JUMPE	XLC,FALSE
		LI	X1,1(X1R3)		;PREVIOUS LINE NUMBER+1
		ST	X1,YELIN1
		ST	X1,YELIN2
		L	X1,YLCLNO		;LOAD ILL LINE NUMBER
		ERRT	2,Q1LC.W
	FI
	ADDI	X1R3,1		;INCREASE LINE NUMBER
	SF	X1R3,YLSNLIN
L9():!	RETURN
	EPROC
	SUBTTL	LCLS1 SUBROUTINE

COMMENT ;
PURPOSE:		TO CREATE A RECORD IN THE nnnLS1.TMP FILE
			RECORDS OF TYPE 4 ARE PACKED TOGETHER IF POSSIBLE.
ENTRIES:		LCLS1 FOR CONTROL RECORDS
			LCLS1T FOR TEXT RECORDS
INPUT ARGUMENT:		RECORD IN X0
			CURRENT TYPE 4 IN ZLEREC
			PREVIOUS TYPE 4 IN YLCRT4
OUTPUT ARGUMENT:	-
NORMAL EXIT:		RETURN
ERROR EXIT:		-
CALL FORMAT:		EXEC LCLS1 (OR LCLS1T)
USED SUBROUTINE:	O1LS
USED REGISTERS:		X0	INPUT RECORD
			X1	SCRATCH
ERROR MESSAGE:		NONE
;
LCLS1:
	HLRZ	X1,X0		;RECORD IDENTIFIER TO X1
	IF	;RECORD TYPE IS 4
		CAIE	X1,QLCRT4
		GOTO	FALSE
	THEN	IF	;NOT TYPE 4 RECORD BEFORE
			SKIPE	YLCRT4
			GOTO	FALSE
		THEN	;UPDATE YLCRT4
			HLL	X0,ZLEREC
			HLLM	X0,YLCRT4
			RETURN
		FI
		HLL	YLCRT4		;GET OLD RECORD
		HLR	ZLEREC		;AND CURRENT
		SETZM	YLCRT4		;AND RESET OLD
	ELSE
		IF	;OLD RECORD 4
			SKIPN	X1,YLCRT4
			GOTO	FALSE
		THEN	;OUTPUT IT WITH RH = 1
			IORI	X1,1
			SETZM	YLCRT4
			PUTLS1	X1
		FI
		IORI	X0,1
	FI
	PUTLS1	X0
	RETURN
	SUBTTL	LCMORE/LSNEXT SUBROUTINE

COMMENT ;

PURPOSE:		THIS SUBROUTINE FILLS THE YLCLB BUFFER FROM
			THE INPUT BUFFER. IF NECESSARY THE NEXT BUFFER IS
			READ AND IF END OF FILE OCCURS AN APPROPRIATE
			END OF FILE RECORD IS STORED IN THE BUFFER.
			IF THERE ARE MORE SOURCES I1SC IS CALLED AND
			YLTAB IS UPDATED WITH LOOKUP AND
			SWITCH INFORMATION.
INPUT ARGUMENTS:
			XLCLEN SHOULD CONTAIN LENGTH OF NEXT MOVE
			XLCADR SHOULD CONTAIN ADRESS TO LAST MOVED WORD.
OUTPUT ARGUMENTS:	-
NORMAL EXIT:		IMMEDIATE RETURN IF END OF FILE ON LAST SOURCE
			ELSE SKIP RETURN.
ERROR EXIT:		GOTO T1AB IF YLTAB OVERFLOWS.
CALL FORMAT:		EXEC LCMORE OR EXEC LCNEXT
USED ROUTINES:		O1SC	READ NEXT SOURCE BUFFER
			I1SC	PROCESS NEXT SOURCE SPECIFICATION
			O1SCOP	LOOKUP NEXT SOURCE
USED REGISTERS:		SEE DESCRIPTION OF THE LC ROUTINE
ERROR MESSAGE:		?TOO MANY SOURCES
;

LCMORE:	PROC
	IFON	YLCEOF		;SKIP BUFFER MOVE IF END OF FILE HAS OCCURRED
	RETURN
	LI	XLCADR,1(XLCEND);NEW TO ADDRESS
	HRL	XLCADR,YBHSRC+1 ;FROM ADDRESS
	IF	CAMG	XLCLEN,YBHSRC+2 ;ENOUGH DATA IN BUFFER?
		GOTO	FALSE		;YES!
	THEN	IF	SKIPN	YBHSRC+2
			GOTO	FALSE		;JUMP IF NOTHING LEFT
		THEN	;MOVE WHAT'S LEFT IN I/O BUFFER
			SUB	XLCLEN,YBHSRC+2
			HRRZ	XLCEND,XLCADR
			ADD	XLCEND,YBHSRC+2
			SUBI	XLCEND,1
			BLT	XLCADR,(XLCEND)
		FI
LCNEXT:
		EXEC	O1SC		;READ NEXT BUFFER
		GOTO	LCMORE
	
		;O1SC SKIPS TO THIS POINT IF END-OF-FILE OCCURRED
		LI	<QEOT>B24
		LI	XLCADR,YLCLBE	;COMPUTE ADDRESS TO LAST WORD
		SUB	XLCADR,XLCLEN
		HRLOM	(XLCADR)	;STORE <QEOT><-1> IN BUFFER
		ADDI	XLCEND,1	;UPDATE END ADDRESS
		SUBI	XLCLEN,1	;AND LENGTH
		IF	IFOFFA	YI1MS
			GOTO	FALSE
		THEN	;MORE SOURCES!
			SOS	(XLCADR)
			SOS	(XLCADR)	;CHANGE <-1> TO <-3>
			EXEC	I1SC		;SET UP NEW LOOKUP-BLOCK
			LI	X0,14
			L	X1,YI1FN	;DEVICE
			L	X2,[XWD YBHSRC,YBHSRC]
			OPEN	QCHSRC,X0
			GOTO	I1OPAB		;OPEN FAILURE!
			L	[400K,,Y11BUF+1]
			ST	YBHSRC		;RESTORE FIRST WORD
			EXEC	O1SCOP
			L	X1,YLTIND	;POINTER TO LOOKUP TABLE
			IF	;NEXT ELEMENT IN YLTAB IS OCCUPIED
				SKIPN	X0,YLTAB(X1)
				GOTO	FALSE
			THEN	;ERROR!
				LF	X0,YLSNLIN
				ST	X0,YELIN1
				ST	X0,YELIN2
				ERR	QT,252
				GOTO	T1AB
			FI
			L	YELSRC
			ST	YLTAB(X1)	;MOVE LOOKUP BLOCK TO LOOKUP TABLE
			L	YELSRC+1
			ST	YLTAB+1(X1)
			L	YI1FN+4
			ST	YLTAB+2(X1)
			L	YI1FN		;MOVE DEVICE
			ST	YLTAB+3(X1)
			LD	X2,YI1P1	;MOVE SWITCH INFORMATION
			STD	X2,YLTAB+4(X1)
			LSH	X1,^D22		;STORE POINTER IN EOT-WORD
			IORM	X1,(XLCADR)
			L	X1,YLTIND	;UPDATE POINTER
			ADDI	X1,6
			CAIN	X1,^D36
			LI	X1,0
			ST	X1,YLTIND
			JUMPG	XLCLEN,LCMORE
					edit(6)
			RETURN		;[6] RETURN IF XLCLEN=0 AFTER THE
					; EOT WORD IS PLACED IN THE LINE BUFFER
		FI
		;ELSE TRUE END OF FILE
		SETON	YLCEOF		;FLAG LAST SOURCE PROCESSED
		RETURN
	FI
	;THIS POINT IS REACHED IF THERE WAS ENOUGH DATA IN THE BUFFER
	BLT	XLCADR,YLCLBE-1	;FILL REST OF BUFFER
	;NOW THE BUFFER POINTER AND REMAINING NUMBER OF WORDS ARE UPDATED
	ADDM	XLCLEN,YBHSRC+1	;UPDATE BUFFER ADDRESS
	SUB	XLCLEN,YBHSRC+2
	MOVNM	XLCLEN,YBHSRC+2	;DECREASE REMAINING NUMBER OF WORDS
	RETURN
	EPROC
	SUBTTL	LCPLIN SUBROUTINE

COMMENT ;
PURPOSE:		TO OUTPUT CONTROL RECORDS FOR PREVIOUS SOURCE CODE LINE
			IF NECESSARY BEGIN AND END RECORDS ARE
			OUTPUT FIRST, THEN A TYPE 4 RECORD.
ENTRY:			LCPLIN
INPUT ARGUMENTS:	SWITCH YI1SWF
			YBEGNO CONTAINS TOTAL NO OF BEGINS SO FAR
			YENDNO CONTAINS TOTAL NO OF ENDS SO FAR
			YLCBEG CONTAINS TOTAL NO OF BEGINS BEFORE PREVIOUS LINE
			YLCEND CONTAINS TOTAL NO OF ENDS BEFORE PREVIOUS LINE
OUTPUT ARGUMENTS:	YLCBEG AND YLCEND ARE UPDATED
NORMAL EXIT:		RETURN
ERROR EXIT:		-
CALL FORMAT:		EXEC LCPLIN
USED SUBROUTINES:	LCLS1,LCLS1T
USED REGISTERS:		X0 AND XLC AS SCRATCH
ERROR MESSAGE:		NONE
;

LCPLIN:	PROC
	IF	;FIRST CALL TO LCPLIN
		IFONA	YI1SWF
		GOTO	FALSE
	THEN	;NO PREVIOUS LINE!
		SETOFF	YLCEOF
		RETURN
	FI
	HRLI	QLCRT4		;CREATE RECORD TYPE 4
	EXEC	LCLS1
	RETURN
	EPROC
	SUBTTL	MAIN SUBROUTINE LC

COMMENT ;

PURPOSES:		TO OUTPUT PREVIOUS LINE AND INPUT NEXT
ENTRY:			LC
INPUT ARGUMENT:		YLCLBS AND XLCLBP
OUTPUT ARGUMENTS:	YLCLBS AND XLCLBP
NORMAL EXIT:		RETURN
ERROR EXIT:		-
CALL FORMAT:		EXEC LC
USED ROUTINES:		LCPLIN
			LCLINE
			LCLS1
			I1SC
USED REGISTERS:		XLCSAV	BREAK CHARACTER COMBINATION CODE
			XLCADR	USED IN BLT'S
			XLCLEN	LENGTH OF MOVE
			XLCEND	END ADDRESS OF MOVE
			X0	SCRATCH
			XLC	SCRATCH
ERROR MESSAGE:		TOO LONG LINE
;

LC:	PROC
			edit(202)
	XLCSA==XLCSAV	;[202]
	XLCAD==XLCADR	;[202]
	XLCLE==XLCLEN	;[202]
	XLCEN==XLCEND	;[202]
	SAVE	<XLCSA,XLCAD,XLCLE,XLCEN> ;[202]
	HRRE	YLCLBS
	IF	;NO SOURCE YET
		JUMPGE	X0,FALSE
	THEN	;SET UP POINTERS AND GET FIRST BUFFER
		LI	XLCLEN,YLCLBE
		SUBI	XLCLEN,YLCLB
		LI	XLCEND,YLCLB-1
		EXEC	LCNEXT
		GOTO	L9
	FI
	LI	YLCLBE
	HRRZ	XLC,XLCLBP
	STACK	XLC		;SAVE END OF PREVIOUS LINE
	IF	;TOO LONG LINE
		SUB	XLC
		GOTOLE	TRUE		;TOO LONG IF POINTER IS BEHIND END OF BUFFER
		CAIE	1
		GOTO	FALSE
		HLRZ	YLCLBS		;POINTER POINTS TO LAST WORD IN BUFFER,
		CAIN	10700
		LI	440700
		HLRZ	XLC,XLCLBP
		CAMGE	XLC,X0		;COMPARE WITH START OF LINE
		GOTO	FALSE
	THEN
		UNSTK	X0
		LI	X0,440700
		HRLM	X0,YLCLBS	;ADJUST YLCLBS TO POINT TO THE START OF YLCLB
		IFON	YLCOVF
		GOTO	L3		;IF TOO LONG LINE ON PREVIOUS LC CALL!
		LF	X0,YLSNLIN
		ST	YELIN1
		ST	YELIN2
		ERR	0,Q1LC.E
		SETON	YLCOVF		;FLAG TOO LONG LINE
		GOTO	L3
	FI
	;NOW DETERMINE LINE BREAK CHARACTER COMBINATION AND
	;CREATE APPROPRIATE LS1-RECORD(S)
	HRROI	XLCSAV,-1	;NO COMBINATION
	SETOFF	YLCOVF		;FLAG LINE LENGTH OK
	SETOFF	YLCNOL
L1():!
	HLLM	XLCLBP,YLCLBS	;SAVE CURRENT LH
	SKIPL	X0,XLCSAV
L5():!
	ILDB	X1BYTE,XLCLBP	;GET NEXT BYTE
	HRRM	XLCLBP,YLCLBS	;SAVE RH OF BYTE POINTER
	HRRZ	XLCLEN,XLCLBP	;UPDATE XLCLEN FOR LATER MOVE
	IF	;NULL
		JUMPN	X1BYTE,FALSE
	THEN	;IGNORE IT!
		HLLM	XLCLBP,YLCLBS
		GOTO	L5
	FI

	edit(14)
	;[14]  ALL TESTS ON CARRIAGE RETURN REMOVED

	IF	;LINE FEED
		CAIE	X1BYTE,QLF
		GOTO	FALSE
	THEN
		HRRZ	X0,XLCLBP
		SUBI	YLCLBE
		IF	;END OF BUFFER
			JUMPL	X0,FALSE
		THEN	;MUST READ NEXT BUFFER
			LI	XLCLEN,YLCLBE
			SUBI	XLCLEN,YLCLB
			LI	XLCEND,YLCLB-1
			L	XLCLBP,[POINT 7,YLCLB]
			ST	XLCLBP,YLCLBS
			EXEC	LCMORE
			GOTO	L5	;CONTINUE
		FI
		JUMPGE	XLCSAV,L2
		LI	XLCSAV,QLDEL
		GOTO	L1
	FI
	IF	;VERTICAL TAB
		CAIE	X1BYTE,QVT
		GOTO	FALSE
	THEN
		IF	;PRECEDING LF
			CAIE	XLCSAV,QLDEL
			GOTO	FALSE
		THEN	LI	XLCSAV,QLVDEL
			GOTO	L1
		FI
		JUMPGE	XLCSAV,L2
		LI	XLCSAV,QVDEL
		GOTO	L1
	FI
	CAIE	X1BYTE,QFF	;FORM FEED?
				edit(171)
	 GOTO	L2		;[171] NO BREAK CHARACTER
	IF	;PRECEDING LF
		CAIE	XLCSAV,QLDEL
		GOTO	FALSE
	THEN	LI	XLCSAV,QLFDEL
	ELSE
		JUMPGE	XLCSAV,L2
		LI	XLCSAV,QFDEL
	FI
	GOTO	L1

L2():!
	UNSTK	XLC
	HRRZ	X0,XLCLBP
	SUB	X0,XLC
	IF	;END OF PREVIOUS LINE AND START OF NEXT
		;IS IN SAME WORD
		JUMPN	X0,FALSE
	THEN	;NO LINE NUMBER POSSIBLE!
		SETON	YLCNOL
	FI
	edit(171)
	;[171] 3 lines removed
	IF	JUMPL	XLCSAV,FALSE
	THEN	SF	XLCSAV,ZLEIND
		EXEC	LCPLIN		;LINE NO RECORD FOR PREVIOUS LINE
	FI
	SKIPA	X0		;SKIP NEXT STATEMENT

	;NOW MAKE FIRST SHUFFLE WITHIN BUFFER
	;XLCLEN POINTS AT THE FIRST WORD IN THE NEXT LINE.
L3():!
	HRRZ	XLCLEN,XLCLBP
	HRL	XLCADR,YLCLBS	;FROM ADDRESS
	HRRI	XLCADR,YLCLB	;TO ADDRESS
	SUBI	XLCLEN,YLCLB	;LENGTH OF MOVE
	IF	;NO MOVE NECESSARY
		JUMPG	XLCLEN,FALSE
	THEN	;ADJUST POINTER IF NECESSARY
		HLRZ	X0,YLCLBS
		CAIE	X0,10700
		GOTO	L9
		HRRI	XLCLBP,YLCLB+1
		GOTO	L8
	FI
	LI	XLCEND,YLCLBE	;COMPUTE END ADDRESS OF FIRST MOVE
	SUBI	XLCEND,1(XLCLEN)
	BLT	XLCADR,(XLCEND)
	EXEC	LCMORE		;FILL REST OF LINE BUFFER
L9():!
	HRRI	XLCLBP,YLCLB
L8():!
	HLL	XLCLBP,YLCLBS
	;CHECK INPUT FILE FOR PRESENCE OF LINE NUMBERS.
	;IF THERE IS A LINE NUMBER WORD THE SWITCH ZLESRC IS SET ON.
	;The line number and the following tab are reset in the buffer.
	SETOFF	ZLESRC
	IF	;LINE NUMBER POSSIBLE
		IFON	YLCNOL
		GOTO	FALSE
	THEN	HRRZ	X1,XLCLBP	;COMPUTE ADDRESS TO POSSIBLE LINE NUMBER WORD
		edit(262)	;[262] begins here
		;[1C] FIX FOR CONCATENATED LINE NUMBERED FILES
		TLNE	XLCLBP,(30B5)	;Byte pointer internal to word?
		 ADDI	 X1,1		;Yes, line no in next word
		LOOP
			HRRZ	(X1)
			TRNE	1	;No line no
			 CAIN	 -1	;Or last source
			  GOTO	  LCEND	; then finished here
		AS	;More source files are scanned
			CAIN	-3
			 AOJA	 X1,TRUE
		SA
		SETON	ZLESRC	;Line no found
		SETZ
		DPB	[POINT 7,1(X1),6]	;Clear tab after line no
		EXCH	(X1)			;Line no word
		ST	YLCLNO			;Save it
	FI	;[262]
LCEND:
	HLRZ	YLCLBS
	CAIN	10700
	 SUBI	XLCLBP,1	;ADJUST BYTE POINTER
	HRRM	XLCLBP,YLCLBS	;UPDATE START POINTER
	IFOFF	YLCOVF		;IF NOT LONG LINE WHEN LC WAS CALLED
	EXEC	LCLINE		;CHECK AND UPDATE LINE NUMBER
	RETURN
	EPROC
	SUBTTL	LITERALS


IFN QDEBUG,<
LCPA:	BLOCK	50	;PATCH AREA
>
	LIT
	END