00100	COMMENT    VALID 00037 PAGES
   00200	C REC  PAGE   DESCRIPTION
  00300	C00001 00001
00400	C00004 00002	HISTORY
  00500	C00012 00003	SCAN
00600	C00015 00004	BITDATA (SCNWRD -- LISTING CONTROL, ETC.)
   00700	C00021 00005	DATA (SCANNER PARSE TOKENS)
  00800	C00033 00006	DSCR main SCANNER Dispatch loop
   00900	C00046 00007	 ID -- RESET FOR SCAN
   01000	C00054 00008	  COMMENT -- throw out everything to next semicolon
   01100	C00056 00009	DSCR -- USID
  01200	C00063 00010	DSCR -- SCNACT
01300	C00073 00011		PUSH	PNT,PNEXTC-1	STRING NUMBER
  01400	C00077 00012	DSCR STRNG, etc.
   01500	C00081 00013	 
   01600	C00084 00014	DEFCHK:
  01700	C00096 00015	DSCR SCNUMB -- number scanner
01800	C00109 00016	
    01900	C00114 00017	 Print the last character, then stack the result
 02000	C00118 00018	DSCR CSPEC, SEOL, SEOM, SEOB -- Special handling routines
  02100	C00122 00019	Cspec, Seol
   02200	C00123 00020	 CALL SPECIAL ROUTINE, BUT FIRST MAKE SURE CHARACTER COUNT IS
   02300	C00130 00021
02400	C00138 00022	 END OF BUFFER CODE.
    02500	C00140 00023	 Parameter delimiter or end of message 
02600	C00148 00024	DSCR ADVBUF -- new input buffer routine
02700	C00160 00025	BAIL <
   02800	C00163 00026	DSCR --HERE IS THE CREFFINF STUFF (STRANGE PLACE N'EST CE PAS?)
 02900	C00170 00027	DSCR HDR, HDROV 
   03000	C00181 00028	DSCR ENTERS -- make new symbol entry
   03100	C00185 00029	^ENTERS:	
03200	C00191 00030	 
   03300	C00196 00031
03400	C00197 00032	DSCR ADCINS, CREINT, CONINS
  03500	C00201 00033	DSCR SHASH, NHASH -- look up symbol entries in hashed buckets.
  03600	C00207 00034	SEMBLK Allocation Routines
   03700	C00214 00035	RNGVRB, RNGSTR, etc. -- `Ring' Linkage Routines
  03800	C00217 00036
03900	C00220 00037	 Mark insertion routine for counter routines
04000	C00223 ENDMK
04100	C;
            00100	COMMENT HISTORY
 00200	AUTHOR,REASON
    00300	021  102100000046  ;
 00400	
  00500	
  00600	COMMENT 
   00700	VERSION 17-1(38) 4-14-75 BY JFR ANOTHER PASS AT BAIL COORDINATE FIXES P.6
    00800	VERSION 17-1(37) 3-1-75 BY RLS CHECK FOR END OF BUFFER IN TENEX ADVBUF (PROB. SHOULD BE ADDED TO DEC ALSO)
 00900	VERSION 17-1(36) 2-8-75 BY JFR BAIL SOURCE POINTERS P.6
  01000	VERSION 17-1(35) 11-17-74 BY JFR BAIL SOURCE FILE POINTER BUGS P. 6,21
  01100	VERSION 17-1(34) 10-16-74 BY JFR FIX BAIL SOURCE FILE COUNTING
01200	VERSION 17-1(33) 10-10-74 BY JFR REVISE WAY BAIL PUTS OUT TEXT FILE POINTERS
 01300	VERSION 17-1(32) 9-26-74 BY JFR BAIL INSTALLED 9-19-74.  FIX VERSION, AUTHOR, REASON STUFF
  01400	VERSION 17-1(31) 9-15-74 BY HJS BUG #TG# PREVENT PARSE STACK OVERFLOW WHEN SCANNING ACTUAL PARAMETERS TO MACROS 
01500	VERSION 17-1(30) 5-30-74 BY RLS TENEX FIX #SI# BETTER LISTING FORMAT
    01600	VERSION 17-1(29) 5-30-74 
  01700	VERSION 17-1(28) 5-28-74 BY RHT BUG #SD# NEEDED A FLAG TO DETECT EXTERNAL-INTERNAL CHANGES
  01800	VERSION 17-1(27) 4-12-74 BY RHT %BI% ASS RECORD STUFF TO ENTID
01900	VERSION 17-1(26) 3-17-74 BY RLS INSTALL TENEX
  02000	VERSION 17-1(25) 3-17-74 
  02100	VERSION 17-1(24) 2-5-74 BY HJS BUG #RA# ALLOW TEXT PAST FINAL END OF PROGRAM 
02200	VERSION 17-1(23) 1-29-74 BY HJS BUG #QV# ASSIGNC PROBLEMS
02300	VERSION 17-1(22) 1-25-74 BY RHT BUG #QO# PNAME MAY BE SPLIT BY STRING SPACE EXPANSION
  02400	VERSION 17-1(21) 1-11-74 BY JRL CHANGE MACRO EXPANSION LIST CHARACTER
   02500	VERSION 17-1(20) 12-14-73 BY RHT BUG #PZ# A KLUGE THAT NO LONGER WORKED FIXED BY NEW DCS KLUGE
   02600	VERSION 17-1(19) 12-14-73 
 02700	VERSION 17-1(18) 12-7-73 BY JRL REMOVE SPECIAL STANFORD CHARACTERS
 02800	VERSION 17-1(17) 11-27-73 BY RLS BUG #PF# AVOID DYING IF SOURCE FILE ENDS IN FF
   02900	VERSION 17-1(16) 11-27-73 
 03000	VERSION 17-1(15) 11-25-73 BY JRL FEAT %AN% HAVE SOURCE!FILE SWITCHING CHECK ARG AS STRING CONSTANT
    03100	VERSION 17-1(14) 11-16-73 BY HJS BUG #PC# OVERWRITNG FIRST LINE IN CREF 
03200	VERSION 17-1(13) 11-10-73 BY KVL MERGE:CORERR
  03300	VERSION 17-1(12) 9-24-73 BY HJS BUG #OH# NO CREFFING OF MACRO FORMALS ALLOWED
03400	VERSION 17-1(11) 9-24-73 
  03500	VERSION 17-1(10) 9-21-73 BY HJS INHIBIT LISTING IN FALSE PART OF CONDITIONAL COMPILATION 
   03600	VERSION 17-1(9) 9-21-73 BY RHT PATCH UP VERSION STUFF
    03700	VERSION 17-1(7) 9-21-73 BY HJS MAKE BUG OG FIX RIGHT
03800	VERSION 17-1(6) 9-19-73 BY HJS BUG #OG# SAVE PNAME COUNT BEFORE SGCOL
   03900	VERSION 17-1(5) 9-19-73 
   04000	VERSION 17-1(4) 9-17-73 BY HJS BUG #OF# MAKE SURE PARSE TOKEN IN AC A WHEN GOING TO STACK
   04100	VERSION 17-1(3) 9-17-73 
   04200	VERSION 17-1(2) 9-17-73 
   04300	VERSION 17-1(1) 8-14-73 BY RHT TURN JRST .CORERR AT GETTOP BACK TO JRST CORERR
    04400	VERSION 16-2(48) 7-12-73 BY HJS SAVE CHARACTER COUNT IN CASE GARBAGE COLLECTION HAPPENS DURING MACRO ACTUAL SCANNING
 04500	VERSION 16-2(47) 6-20-73 BY HJS IFCR, REDEFINE, EVALDEFINE, AND ASSIGNC IMPLEMENTATION 
04600	VERSION 16-2(46) 6-10-73 BY JRL BUG #MQ# LPNT NOT PROPERLY SAVED FOR BACKUP WHEN SAVCHR=0
   04700	VERSION 16-2(45) 6-1-73 BY DCS BUG #MP# KEEP REMCHR HONEST (STRNGC BUG)
 04800	VERSION 16-2(44) 3-19-73 BY HJS ALLOW TEMPORARY OVERRIDING OF NULL DELIMITERS MODE
04900	VERSION 16-2(43) 3-13-73 BY JRL REMOVE REFERENCES TO WOM,SLS,GAG,NODIS
  05000	VERSION 16-2(42) 3-12-73 BY RHT BUG #LS# OWN THINGS GETTING THE WRONG LEVEL INFO
  05100	VERSION 16-2(41) 1-31-73 BY HJS ADD NOEMIT, ACKSAV, AND SBSAV FOR EXPR!TYPE
  05200	VERSION 16-2(40) 1-17-73 BY HJS BUG #LC# MACRO FORMALS ARE NOT MACRO REDEFINTION
  05300	VERSION 16-2(39) 1-17-73 
  05400	VERSION 16-2(38) 12-11-72 BY HJS DISABLE ENDC PARSER SWITCH TRIGGER IN WHILEC, CASEC, FORC, AND FORLC BODIES
    05500	VERSION 16-2(37) 12-2-72 BY HJS SAVE BITS DURING CONDITIONAL COMPILATION AND MACRO DEFINITIONS (CBTSTK AND DBTSTK)
   05600	VERSION 16-2(36) 11-20-72 BY JRL FIX SUGG BY R. SMITH AT CHKPRC
    05700	VERSION 16-2(35) 11-19-72 BY HJS BUG #JZ# CORRECTION - MACRO REDEFINITION AND RESERVED WORD REDEFINITION IN ENTERS
   05800	VERSION 16-2(34) 11-15-72 BY HJS INSERT DEFDLM QSTACK FOR DEFLUK BIT OF FF FOR COMPILE-TIME MACROS WITHIN MACROS
05900	VERSION 16-2(33) 11-5-72 BY DCS BUG #JZ# CHANGE MACRO SCOPE RULES
  06000	VERSION 16-2(32) 11-3-72 BY DCS SIMILARLY, ALLOW ALL EXTERNALS TO OVERRIDE
   06100	VERSION 16-2(31) 11-2-72 BY DCS BUG #JX# ALLOW INTRNL PROC TO OVERRIDE EXTRNL ONE.
06200	VERSION 16-2(30) 10-24-72 BY HJS EMIT ERR MSG FOR UNINIT MACRO VAR USE
  06300	VERSION 16-2(29) 7-5-72 BY DCS BUG #IF# FIX SOME GOERGE BUGS
  06400	VERSION 15-6(18-28) 7-5-72 
06500	VERSION 15-6(17) 3-10-72 BY DCS REPLACE RING,ULINK MACRO WITH VARIOUS ROUTINES
    06600	VERSION 15-6(8-16) 3-9-72 
 06700	VERSION 15-6(7) 2-21-72 BY HJS THE BRAVE NEW PARSER WORLD
06800	VERSION 15-2(6) 2-18-72 BY DCS BUG #GP# CHECK OLD FORMALS AGAINST NEW FORMALS
06900	VERSION 15-2(5) 2-5-72 BY DCS BUG #GJ# ADD LSTON LIST-CONTROL STUFF
07000	VERSION 15-2(4) 2-5-72 BY DCS BUG #GI# REMOVE TOPSTR
07100	VERSION 15-2(3) 2-1-72 BY DCS BUG #GE# LPSBOT FROM USER TABLE TO COMPILER DATA
    07200	VERSION 15-2(2) 12-22-71 BY DCS BUG #FT# PROVIDE LINE NUMBER IF NOT SOS FILE
 07300	VERSION 15-2(1) 12-2-71 BY DCS INSTALL VERSION NUMBER
    07400	
  07500	;
07600	
          00100	SUBTTL	SCAN
 00200		LSTON	(SYM)
00300	BEGIN SYM
   00400	
  00500	DSCR SCANNER -- get next "ATOM" from source file
    00600	CAL PUSHJ from PARSE (or recursively)
00700	PAR PNEXTC is bp to next input char (from file or macro)
 00800	 SAVCHR, if non-zero, is a scan-ahead char which should
  00900	  be considered first.
01000	 File variables, Listing variables used by I/O part.
01100	 Define stack, variables, macro semantics used when
 01200	  recurring into macros
    01300	
  01400	RES The ATOM will be either:
    01500	
  01600	1. An operator or other character atom, in which case
    01700		the Parse token representing it will be placed in the
   01800		parse stack, a 0 in the generator stack (null entry).
   01900	
  02000	2. A reserved word, in which case the Parse token will be 
    02100		placed on the parse stack from the word's symbol 
  02200		entry, and again a null semantic entry will be stacked.
 02300	
  02400	3. An IDENTIFIER, in which case the Parse token for the appro-
02500		iate class of IDs will appear on the parse stack, the
   02600		Semantics for the symbol on the generator stack. If the
 02700		symbol is undefined, a 0 is represents null Semantics.
  02800	
  02900	4. A STRING or numeric constant. These entities are ENTERed 
  03000		in their respective symbol tables if previously 
   03100		undefined, and the stacks are set up as above.
03200	
  03300	
  03400	 In all cases, the semantic entry will be repeated in the cell
03500		NEWSYM. In those cases where a hash was made, the
  03600		MOVE or MOVS instr to fetch the list on which the symbol
03700		appears (or will appear after ENTERy) is located in
03800		the cell HPNT. For string constants or identifiers, the
 03900		string	identifier is left in PNAME, PNAME+1. For numeric
04000		arguments, the value is left in SCNVAL. DBLVAL is zeroed
04100		in these cases.
 04200	
  04300	SID SCANNER uses temporary ACs indiscriminately, so look out for it.
    04400	 Many variables are changed as a result of calling SCANNER.
   04500	
 04600	
          00100	BITDATA (SCNWRD -- LISTING CONTROL, ETC.)
 00200	
  00300	Comment  SCAN table -- good bits that make the whole thing work 
 00400	
  00500	^^LSTEXP__400000		;ON IF "<"-">" PAIRS TO BE PRINTED
00600	^^MACEXP__200000		;EXPAND MACRO TEXTS
00700	^^MACLST__100000		;LIST MACRO NAMES BEFORE EXPANSION
00800	^^LINESO__ 40000		;ON IF LINE NUMBERS SHOULD BE PRINTED
  00900	^^PCOUT __ 20000		;ON IF PCNT SHOULD BE PRINTED
01000	^^CREFIT__ 10000		;ON IF A CREF S HAPPENING
    01100	^^MACIN __  4000		;ON IF IN A MACRO EXPANSION
  01200	^^EOFOK __  2000		;ON IF CAN GET EOF WITHOUT FATALITY
    01300	^^BACKON__  1000		;ON IF LISTING BACK ON AFTER PARAM RESCAN
   01400	^^LOKPRM__  400			;ON IF LOOKING FOR POSSIBLE MACRO PARAM
01500	^^RDYPRM__  200			;GETTING READY FOR MACRO PARAM (RANSCN)
01600	^^INLIN __  100			;TREAT @ AS DELIMITER IN IN-LINE CODE
  01700	^^INSWT __   40			;WE'RE SCANNING A SWITCHED-TO SOURCE FILE
   01800	 ^^NOLIST__     1		;ON IN RH IF NO LISTING HAPPENING NOW
 01900	
  02000	BITDATA (SCANNER TABLE)
    02100	
  02200	SPCL  __400000		;NOT A LETTER OR DIGIT
    02300	ATSIGN__ 20000		;@ -- REAL EXPONENT COMING
02400	AOSSOS__ 20000		;BIT DIFFERENTIATING BETWEEN AOS AND SOS FOR NESTING
    02500				;   DELIMITERS COUNT
    02600	DOT   __ 10000		;. -- DECIMAL POINT
  02700	NUMB  __  4000		;NUMBER OR NUMBER PART (ONE OF ABOVE TWO)
02800	DIG   __  2000		;0 THRU 9
  02900	LETDG __  1000		;REQUIRES SPECIAL TREATMENT
    03000	QUOTE __   400		;" -- STRING CONSTANT DELIMITER
03100	^NEST  __   200		; NESTABLE CHARACTER
03200	^LNEST __   100		; LEFT NESTED CHARACTER
  03300	QUOCTE__    40		;' -- OCTAL NUMBER COMING
 03400	
  03500	; BITS FOR NUMBER SCANNER
  03600	
  03700	INTOV __200000		;INTEGER OVERFLOW
    03800	REALOV__100000		;REAL OVERFLOW
  03900	EXPNEG__ 40000		;NEGATIVE EXPONENT
   04000	NUMNST __3		; NUMBER OF NESTABLE CHARACTERS
    04100	RPAROF __2		; RIGHT PAREN OFFSET FOR LOCNST ENSTRY
  04200	^NUMCHA __200		; NUMBER OF CHARACTERS
04300	^DELNUM __4		; NUMBER OF DELIMITERS AS INPUT TO REQ. DEL.
04400	
  04500	
  04600	TABCONDATA (SCANNER CHARACTER TABLE)
 04700	
  04800	DEFINE IGL <XWD SPCL,IGLCHR>
    04900	DEFINE OPER <.-SCNTBL>
05000	DEFINE LTR <XWD LETDG,.-SCNTBL>
 05100	DEFINE NESTED <<XWD NEST,0>>
    05200	DEFINE LNESTD <<XWD NEST+LNEST,0>>
   05300	
  05400	^SCNTBL:
    05500		XWD	SPCL,SEOB		;0 -- END OF BUFFER
  05600		LTR 				;DWNARROW
    05700		LTR 				;ALPHA
  05800		LTR 				;BETA
   05900		RAND				;AND
    06000		RNOT				;NOT
    06100		RIN				;ELEMENTOF
    06200		REPEAT 2,<LTR >			;PI, LAMBDA
  06300		0				;TAB
  06400		XWD SPCL,SEOL		;LF -- END OF LINE
   06500		0				;VTAB
 06600		XWD SPCL,SEOP			;FF -- END OF PAGE
  06700		0				;CARRIAGE RETURN
06800		RINF				;INFINITY.
   06900		LTR 				;PARTIAL, LEFTHORSESHOE,RGHTHORSESHOE
 07000		REPEAT 2,<LTR >
 07100		RINTER				;INTERSECT
 07200		RUNION				;UNION
07300		LTR 				;FOREACH
07400		LTR 				;EXISTS
 07500		RXOR
  07600		RSWAP				;BOTHWAYSARROW
   07700		LTR 				;UNDERLINE ?
 07800		LTR				;RGT ARRW
07900		RAND				;STANFORD TILDE (AND)
  08000		RNEQ 				;NTEQUAL
    08100		RLEQ				;LTEQUAL
08200		RGEQ				;GTEQUAL
08300		REQV				;EQUIVALENCE
 08400		ROR				;OR
 08500		0				;SPACE
08600	 	XWD LETDG,30			;! -- SAME AS UNDERLINE.
 08700		XWD	QUOTE,.-SCNTBL		;   "
 08800		LTR				;#
  08900		LTR				;$ 
 09000		TPRC				; %
09100		TANDD				;&
09200		XWD	LETDG+NUMB+QUOCTE,.-SCNTBL	;   '
09300		LNESTD+TLPRN			; (
   09400		NESTED+TRPRN			; )
   09500		TTIMS				;*
09600		TPLUS 				;+
    09700		TCOMA				;,
09800		TMINUS				;-
    09900		XWD	LETDG+NUMB+DOT,.-SCNTBL		; .
    10000		TSLSH					;  /
  10100		REPEAT 12,<XWD LETDG+NUMB+DIG,.-SCNTBL>	;DIGITS
    10200		TCOL				; :
10300		TSEMI	 			;  ;
  10400		TLES				; <
10500		TEQU       			; =
    10600		TGRE				; >
10700		TQUES				;?
10800		XWD	LETDG+NUMB+ATSIGN,.-SCNTBL	;  @
 10900		REPEAT =26,<LTR>			;UPPER CASE LETTERS
   11000		LNESTD+TLBR			; [
    11100		LTR  				; TILDE
11200		NESTED+TRBR			; ]
    11300		TUPRW				;^
11400		TLARW				;_
11500		RASSOC				;`
    11600		REPEAT =26,<LTR-40>			;LOWER CASE LETTERS
11700		LNESTD+RSETO			; {
   11800		TVERT				; |
    11900		NESTED+RSETC			; RIGHT CURLY BRACKET
12000		NESTED+RSETC			; RIGHT CURLY BRACKET
12100	; 175 AND 176 WILL BOTH BE CURLY BRACKETS FOR A WHILE.
   12200		XWD	SPCL,EOM			;177 -- END MACRO OR PARAM
12300	ENDSCN_.
    12400	
          00100	DATA (SCANNER PARSE TOKENS)
00200	
  00300	COMMENT 
   00400	  These variables provide symbolic access to the PARSE token
  00500	 numbers for several delimiter characters -- they are used in
 00600	 those cases where the SCANNER or some EXEC needs to examine
  00700	 a value directly
00800	
 00900	%ATS:	TINDR		;BITS FOR @ DELIMITER IN INLINE(SEE SCNUMB)
 01000	%COMMENT: RCOMME+1B0
  01100	^^%ID:	TI
   01200	%NUMCON: TICN		;ARITHMETIC CONSTANT.
 01300	%SEMICOL: TSEMI
  01400	^^%STCON:TSTC		;STRING CONSTANT.
01500	
  01600	ZERODATA (SCANNER VARIABLES)
    01700	
  01800	BAIL<
  01900	^^BCORDN: 0	;DEBUGGER COORDINATE NUMBER.  RIGHT HALF CONTAINS CURRENT
   02000			;COORDINATE, LEFT HALF IS ZERO IF WE ARE NOT NOW PUTTING OUT
02100			;COORDINATES TO THE .SM1 FILE, AND NON-ZERO IF WE ARE.
 02200	BCRDW1:	0	;SPACE TO SAVE COORD INFO TO BE WRITTEN TO .SM1 FILE, SINCE
   02300	BCRDW2:	0	;  LOCATION MUST BE MARKED AT BEGINNING OF STATEMENT, BUT
02400			;  WE DONT KNOW IF WE WANT A COORD UNTIL THE END OF STATEMENT
    02500	>;BAIL
 02600	
  02700	^^DEFRN2: 0	;TEMP RING-VARIABLE WHILE SCANNING MACRO ACTUAL PARAMS
 02800	
  02900	;FLTVAL -- collect floating point equiv while scanning number
 03000	?FLTVAL: 0
  03100	
  03200	COMMENT 
   03300	HPNT, HSPNT -- When the hashing routines (SHASH, NHASH) locate the
 03400	  right bucket pointer in the appropriate bucket Semblk, they create
    03500	  a [HRR LPSA,addr] or [HLR LPSA,addr] instruction which will fetch
03600	  this pointer, and put it into HPNT -- also leaving it in LPSA. They
   03700	  then execute the instruction to begin their lookup phases.  ENTERS
    03800	  again uses this pointer when adding a new Semblk to a bucket -- first
 03900	  as is, to fetch the old pointer, then modified to HRRM or HRLM, to 
   04000	  update the bucket.
  04100	  HSPNT is the saved HPNT value for the last string constant scanned.
   04200	  The "string constant as comment" EXEC uses it to remove the constant
  04300	  from the bucket (provided, of course, that it hasn't also been used
   04400	  as a string constant).
   04500	
 04600	^HPNT: 0
    04700	
  04800	^HSPNT: 0
   04900	
  05000	^^LOCMBD:  BLOCK 2		; MACRO BODY DELIMITERS BLOCK
   05100	^^LOCMPR:  BLOCK 2		; MACRO PARAMETER DELIMITERS BLOCK
   05200	BAKDLM:	   0			; A FLAG WHICH IS SET TO -1 IF DLMSTG IS ON
    05300					;  (I.E. ONE WANTS A DELIMITED MACRO BODY)
 05400					;  AND QUOTES ARE USED INSTEAD BECAUSE A 
  05500					;  REQUIRE NULL DELIMITERS STATEMENT WAS NOT
    05600					;  USED.
05700	^^CURMBG:  0			; CURRENT MACRO BODY BEGIN DELIMITER
 05800	^^CURMED:  0			; CURRENT MACRO BODY END DELIMITER 
  05900	^^CURPBG:  0			; CURRENT PARAMETER BEGIN DELIMITER
  06000	^^CURPED:  0			; CURRENT PARAMETER END DELIMITER
    06100	^^DELSTK:  0			; DELIMITER "BLOCK-STRUCTURE" STACK
  06200	^^LOKDLM:  0			; DLMSTG (LOOKING FOR DELIMITERS FLAG) QSTACK
  06300	^^DEFDLM:  0			; DEFLUK (SCANNING A MACRO BODY OR LOOKING FOR
 06400					;  ACTUAL PARAMETERS) QSTACK
06500	^^CBTSTK:  0			; POINTER TO QSTACK FOR SAVING BITS WHILE SCANNING 
 06600					;  CONDITIONAL COMPILATION EXPRESSIONS
06700	^^DBTSTK:  0			; POINTER TO QSTACK FOR SAVING BITS WHILE SCANNING 
 06800					;  MACRO DEFINITIONS
   06900	^^ENDCTR:  0			; POINTER TO QSTACK INDICATING WHETHER OR NOT ENDC 
 07000					;  SHOULD TRIGGER A PARSER SWITCH (NO IF ONE IS 
07100					;  SCANNING A WHILEC, CASEC, FORC, OR FORLC BODY)
    07200	^^REQDLM:  0			; REQUIRE DELIMITER STATEMENT SEEN FLAG
   07300	^^SWBODY:  0			; SPECIAL DELIMITER DEFINITION SEEN
  07400	^^BNSTCN:  0			; NESTED DELIMITER COUNT
   07500	^^LOCNST:  BLOCK NUMNST  	; NESTABLE CHARACTERS BLOCK
    07600	^^NSTABL:  BLOCK NUMCHA		; NESTABLE CHARACTERS ADDRESS INDEX BLOCK
 07700	
  07800	^^NOEMIT:  0			; DON'T EMIT CODE FLAG FOR THE EMITTER
    07900	^^ACKSAV:  BLOCK 13		; SAVE ACKTAB HERE WHILE EVALUATING EXPR!TYPE
 08000	^^SBSAV:   BLOCK 13		; SAVE $SBITS CORRESPONDING TO ACKSAV VALUES WHILE 
08100					;  EVALUATING EXPR!TYPE (AVOIDS HARMFUL SIDE 
   08200					;  EFFECTS OF CODE GENERATORS)
   08300	^^ADPTSV:  0			; ADEPTH VALUE BEFORE EXPR!TYPE PROCESSING
08400	^^PCNTSV:  0			; PCNT VALUE BEFORE EXPR!TYPE PROCESSING
  08500	^^SDPTSV:  0			; SDEPTH VALUE BEFORE EXPR!TYPE PROCESSING
08600	^^RSTDLM:  0			; TEMPORARY OVERRIDING OF NULL DELIMITERS MODE FLAG
 08700	^^RECSTK:  0			; POINTER TO QSTACK INDICATING WHETHER MACROS SHOULD 
    08800					;  BE EXPANDED IN THE FALSE PART OF CONDITIONAL 
08900					;  COMPILATION 
   09000	^^IFCREC:  0			; FLAG INDICATING WHETHER MACROS SHOULD BE EXPANDED IN 
  09100					;  THE FALSE PART OF CONDITIONAL COMPILATION 
   09200	NULCNT:	   0			; COUNTER INDICATING THE NUMBER OF ACTUAL PARAMETERS 
    09300					;  THAT HAVE NOT BEEN SPECIFIED AT THE END OF THE LIST OF 
09400					;  ACTUALS IN A MACRO CALL.  THEY ARE TREATED AS IF THEY 
 09500					;  HAD BEEN THE NULL STRING (AS DONE AT CMU) 
   09600	LPTRSV:	   0			; SAVE WORD FOR LISTING BUFFER POINTER SO THAT 
09700					;  FALSE PART OF CONDITIONAL COMPILATION DOES NOT 
   09800					;  GET LISTED 
    09900	^^LSTSTK:  0			; POINTER TO QSTACK INDICATING WHETHER OR NOT ONE 
  10000					;  IS IN THE FALSE PART OF CONDITIONAL COMPILATION 
  10100	^^CNDLST:  0			; FLAG INDICATING IF ONE IS IN THE FALSE PART OF 
   10200					;  CONDITIONAL COMPILATION 
 10300	;;%CI% (1/5) JFR 7-18-75
   10400	TRKMCR:	0		;ADDR OF $PNAME+1 OF CURRENT MACRO NAME
  10500	TRKMCS:	0		;SAME FOR LAST MACRO IN SOURCE FILE
 10600	TRKM.P:	0		;PAGE # OF LAST MACRO IN SOURCE FILE
10700	TRKM.L:	0		;ASCLIN # OF LAST MACRO IN SOURCE FILE
   10800	^^TRKBEG:	0	;PTR TO SECOND BLOCK SEMBLK OF CURRENT BLOCK
 10900			;FOR INFORMATIVE ERROR MESSAGES, "FATAL EOF"
 11000	;;%CI% ^
    11100	;; #RA#	(1 OF 2) ! 
   11200	^^EOFCEL:  0			; FLAG INDICATING FINAL END OF PROGRAM SEEN 
   11300	
  11400	BAIL <
 11500	^^BSRCFC: 0			; BUFFER ADDR,,BLOCK COUNT  FOR SOURCE FILE
11600	^^BNSRC:  0			; NUMBER OF SOURCE FILES SEEN
    11700	^^BSRCFN: 0			; CURRENT SOURCE FILE NUMBER
11800	^^BSRCFQ: 0			; QSTACK FOR  REQUIRE  SAVING
    11900	^^BLSTFC: 0			; WORD COUNT FOR LISTING FILE
    12000	^^BPPCNT: 0			; PREVIOUS PROGRAM COUNTER
  12100	>;BAIL
 12200	 
 12300	IFN FTL$DBG,<
    12400	^^L$CNT:	0		;#CHARS LEFT IN LSTBUF
   12500	>;IFN FTL$DBG
    12600	
  12700	ENDDATA
12800	
  12900	DSCR  LSTDPB
13000	
 13100	
  13200	DEFINE LSTDPB	<		;OUTPUT CHAR TO LISTING FILE IF REQD
    13300		TRNN	TBITS2,NOLIST	;IS LISTING HAPPENING, BABY?
    13400		ML$CHR			;YES, DO THE REQUIRED THING
13500	>
 13600	
  13700	IFE FTL$DBG,<
    13800		DEFINE ML$CHR <IDPB B,LPNT>
    13900		DEFINE ML$BAK <MOVEM SBITS2,LPNT>
   14000	>;IFE FTL$DBG
    14100	IFN FTL$DBG,<
    14200		DEFINE ML$CHR <PUSHJ P,L$CHR>
  14300		DEFINE ML$BAK <PUSHJ P,L$BAK>
  14400	
  14500	L$CHR:	SOSGE	L$CNT		;ADD CHAR IN B TO LSTBUF, CHECKING OVERFLOW
    14600		 ERR	<LSTBUF OVERFLOW>,1
  14700		IDPB	B,LPNT
14800		POPJ	P,
    14900	
  15000		5*<POINT 7,0,-1>-5  0  0  0  0
  15100	L$TAB:	5*<POINT 7,0,34>-4
  15200		5*<POINT 7,0,27>-3
   15300		5*<POINT 7,0,20>-2
   15400		5*<POINT 7,0,13>-1
   15500		5*<POINT 7,0,06>-0
   15600	
  15700	L$BAK:				;BACK UP LPNT TO SBITS2, CHECKING AND COUNTING
 15800		CAMN	SBITS2,LPNT
15900		 POPJ	P,		;FREQUENT SPECIAL CASE
    16000		PUSH	P,LPSA
16100		PUSH	P,LPSA+1
   16200		MOVE	LPSA,SBITS2	;SUPPOSED BACK BP
  16300		MULI	LPSA,5		;HAKMEM STRIKES AGAIN (PROG. HAX,ITEM 165-FREIBERG)
  16400		SUB	LPSA+1,L$TAB(LPSA)	;LPSA+1 IS NOW CHAR ADDR
    16500		PUSH	P,LPSA+1
   16600		MOVE	LPSA,LPNT	;CURRENT BP
16700		MULI	LPSA,5
16800		SUB	LPSA+1,L$TAB(LPSA)
    16900		CAML	LPSA+1,(P)	;CURRENT CHR ADDR MUST BE  BACKUP
 17000		 JRST	L$BAK1
    17100		ERR	<LPNT FORWARD "BACKUP">,1
  17200		JRST	L$BAK2
17300	L$BAK1:	MOVEM	SBITS2,LPNT	;BACKUP BP
 17400		SUB	LPSA+1,(P)
  17500		ADDM	LPSA+1,L$CNT	;AND CNT
17600	L$BAK2:	SUB	P,X11
17700		POP	P,LPSA+1
    17800		POP	P,LPSA
 17900		POPJ	P,
    18000	>;IFN FTL$DBG
    18100	
  18200	;;#YV# JFR 2-4-77 SET 'NOLIST' FROM ABSOLUTE BEARINGS
    18300	^^L$SET:TLNE	FF,LISTNG	;.LST FILE EXIST?
  18400		SKIPE	CNDLST		;CHECK FOR EXPLICIT NO LIST OF COND. COMP.
18500		 JRST	L$NO
 18600		MOVE	TEMP,FMTWRD
18700		TLNE	FF,PRMSCN
  18800		TLNE	TBITS2,MACLST	;SCANNING PRMS, NOT LISTING MACRO NAMES, DONT LIST ARGS EITHER
18900		TRNE	TEMP,40		;USER MIGHT HAVE EXPLICITLY TURNED IT OFF
 19000		 JRST	L$NO
 19100		TLNE	TBITS2,MACIN
    19200		TLNE	TBITS2,MACEXP	;IN A MACRO, NOT LISTING EXPANDED TEXTS
   19300		TLNE	TBITS2,LOKPRM
   19400	L$NO:	 TROA	TBITS2,NOLIST	;HUNTING PRM, OR IN MACRO AND NOT LISTING EXPANSIONS
    19500		TRZ	TBITS2,NOLIST	;YES LIST
    19600		POPJ	P,
            00100	DSCR main SCANNER Dispatch loop
 00200	RES gets first char from SAVCHR or PNEXTC, dispatches to
 00300	 routine to handle what it found (IDENT, STRING, DELIM, etc.)
 00400	
 00500	^SCANNER:	
  00600		MOVE	TBITS2,SCNWRD	; SET UP SCANNER PARAMS
    00700	;; #RA# (2 OF 2) 
00800		SKIPE	EOFCEL		; FINAL END OF PROGRAM SEEN? 
   00900		JRST	[TLO TBITS2,EOFOK ; 
 01000			 MOVEM TBITS2,SCNWRD ; 
  01100			 JRST .+1]; 
   01200	;; #RA# 
    01300		TLZE	FF,BAKSCN	;IS SCANNER BACK ONE CHARACTER ??
   01400		 JRST	 GOAGAIN	; DO IT.
   01500		MOVE	USER,GOGTAB	;USER DATA TABLE ADDR FOR STRING STUFF
 01600		TLNE	TBITS2,INLIN	;SPECIAL START!CODE FEATURE?
01700		SETZM	PNAME		;YES, ASSURE NO PNAME USED
  01800	;;#MQ# SET UP SBITS2 FOR BACKING UP LPNT EVEN IF HAVE SAVCHR0
01900		MOVE	SBITS2,LPNT
02000		MOVEM	SBITS2,LPTRSV	; SAVE IN CASE IN FALSE PART OF COND. COMP. 
  02100	
  02200		MOVEI	C,0		;WILL COUNT CHARS FOR IDENTS
  02300		SKIPE	B,SAVCHR	;IS ANYTHING LEFT OVER?
   02400		 JRST	 SPCHAR		;YES, DISPATCH AS FIRST CHAR
   02500	
  02600		TLNN	FF,PRMSCN	;SCANNING MACRO PARAMETERS?
    02700		 JRST	 DISPT		; NO
   02800		 TRNA			;SKIP IDPB
   02900	
  03000		ML$CHR			;TO LISTING FILE
 03100	DSPRM:	ILDB	B,PNEXTC	;SKIP IGNORABLE CHARACTERS
03200		SKIPGE	A,SCNTBL(B)	;ANYTHING SPECIAL REQUIRED?
03300		PUSHJ	P,(A)		;YES, DO IT
  03400		JUMPE	A,DSPRM-1(TBITS2) ;MAYBE LIST, GET NEXT IGNORABLE
 03500	
  03600	DSPR1:	TLO	FF,PRMXXX	;SET SPECIAL PARAM SCANNING BIT
03700		TLNE	A,QUOTE		;DOES HE WANT COMPLETE FREEDOM?
 03800		 JRST	 STRLST		; YES, GIVE IT TO HIM (FIRST LIST `"')
   03900		PUSHJ	P,INSET		;NO, SPECIAL MODE -- "," OR ")" WILL BREAK
    04000		JRST	BAKSTR		;AROUND QUOTE DELETION
 04100	
  04200		ML$CHR			;TO LIST FILE
    04300	DISPT:	ILDB	B,PNEXTC	;GET FIRST CHAR
 04400		SKIPGE	A,SCNTBL(B)	;GET GOOD BITS, CHECK SPECIAL
   04500		PUSHJ	P,(A)		;SPECIAL, HANDLE IT
    04600		 JUMPE	 A,DISPT-1(TBITS2) ;BLANKS AND OTHER IGNORABLES
  04700		MOVE	SBITS2,LPNT	;SAVE IN CASE BACKUP MUST HAPPEN
  04800		MOVEM	SBITS2,LPTRSV	; SAVE IN CASE IN FALSE PART OF COND. COMP. 
  04900	STRLST:	LSTDPB			;TO LISTING FILE IF REQD
 05000	
  05100	SPCHAR:	SETZM	SAVCHR		;NOTHING LEFT OVER YET
   05200		SETZM	LSTCHR
    05300		JUMPL	B,[TLZN	TBITS2,EOFOK	;OK FOR EOF HERE?
  05400			   ERR  <Fatal end of source file>	;NO
  05500			   MOVE	A,%EOFILE	;YES, RETURN `EOF'
    05600			   JRST	CHAROUT]	;NULL SEMANTICS
   05700		SKIPN	A,SCNTBL(B)	;GET GOOD BITS (DON'T DISPATCH AGAIN!)
05800		JRST	DISPT		; IGNORABLE, FIND ONE THAT ISN'T
  05900		SKIPE	DLMSTG		; LOOKING FOR SPECIALLY DELIMITED STRING?
 06000		CAME	B,CURMBG	; POSSIBLY, MACRO BODY BEGIN DELIMITER?
   06100		JRST CONCHK		; GO DO A NORMAL SCAN
  06200		SETZM	BNSTCN		; SET DELIMITER NEST COUNT TO ZERO
   06300		JRST	STRNG		; GET MACRO BODY
   06400	
  06500	BAIL<
  06600	^^BMKSRC:
   06700		MOVE	TEMP,BAILON
06800		TRNN	TEMP,BBCRD	;SKIP IF WE WANT COORDS
  06900		 POPJ	P,
   07000		PUSH	P,A
   07100		PUSH	P,B
   07200		PUSH	P,C		;WE ARE IN THE HEART OF THE SCANNER, SO BEWARE
07300	;;%##% 1! JFR 4-18-76
 07400		PUSH	P,D
   07500	
  07600		MOVE	TBITS2,SCNWRD		;PICK UP SCANNER FLAGS
    07700		TRNN	TBITS2,NOLIST		;LISTING IN PROGRESS?
07800		 JRST	BCRDLS			;YES
  07900	;;#%%# JFR 2-8-75 FIX THIS CRUFFT FOR MACROS AND CONDITIONAL COMPILATION
08000		TLNE	TBITS2,MACIN		;IN A MACRO?
08100		 JRST	BCRDN2			;YES, UPDATE COUNTERS ONLY, NOT POINTERS
 08200		HRRZ	TEMP,PNEXTC
08300		HRRZ	SBITS,SRCPNT
    08400		SUBI	TEMP,(SBITS)
    08500		CAIL	TEMP,1
08600		CAILE	TEMP,200		;SRCPNT IS A WORD EARLY
  08700		 JRST	BCRDN2			;PNEXTC IS OUT IN THE BOONIES
  08800	;;#%%# ^
    08900		MOVE	TEMP,PNEXTC
09000		MOVEM	TEMP,BPNXTC		;SAVE BYTE POINTER
    09100	
  09200		HRR	SBITS,BSRCFC		;BLOCK COUNT FOR SOURCE FILE
09300		HRRZ	A,BPNXTC		;ADDR OF CURRENT WORD IN BUFFER
09400	;;#%%# BY JFR 11-17-74  CORRECT COMPUTATION OF WORD OFFSETS
   09500		HRRZ	B,SRCPNT		;WORD EARLY POINTER
  09600		ADDI	B,1			;CORRECT
  09700	;;#%%# ^
    09800		LDB	C,[POINT 5,BSRCFN,35-0]	;FILE NUMBER
 09900		LDB	D,[POINT 6,BPNXTC,35-30]	;"P" PORTION OF BYTE POINTER
    10000		JRST	BCRDN1
10100	BCRDLS:
10200	NOTENX<
10300		LDB	SBITS,[POINT 18,BLSTFC,35-7]	;BLOCK COUNT FOR LIST FILE
  10400		ADDI	SBITS,1			;FIRST BLOCK IS 1, NOT 0
  10500		HRRZ	A,LPNT			;ADDR OF CURRENT WORD IN BUFFER
 10600		HRRZ	B,LSTBUF		;ADDR OF FIRST WORD
  10700		LDB	D,[POINT 6,LPNT,35-30]	;"P" PORTION OF BYTE POINTER
 10800	>;NOTENX
    10900	TENX<
  11000		MOVE	A,BLSTFC		; CHAR COUNT FOR LIST FILE
11100		IDIVI	A,5			;WORD COUNT IN A, REMAINDER IN B
  11200		SUBI	B,5			;BEGIN CONSTRUCTION OF "P" OF BYTE POINTER
   11300		MOVM	D,B
   11400		IMULI	D,7
  11500		ADDI	D,1			;FINISHED
 11600		LDB	SBITS,[POINT 18,A,35-7]	;BLOCK COUNT FOR FILE
  11700		ADDI	SBITS,1
    11800		ANDI	A,177			;WORD OFFSET IN A
 11900		SETZ	B,			; FAKE IT FOR BCRND1
 12000	>;TENX	
12100		SETZ	C,			;LIST FILE IS NUMBER 0
    12200	BCRDN1:	SUBI	A,(B)			;WORD OFFSET IN BUFFER
    12300	;;
12400		TLCE	TBITS2,PCOUT!LINESO
  12500		 ADDI	A,2			;PC OR SOS LINE NUMBER GIVES 2 EXTRA WDS
    12600		TLCN	TBITS2,PCOUT!LINESO
  12700		 ADDI	A,1			;BOTH GIVE 3
  12800	;;
12900		DPB	A,[POINT 7,SBITS,35-18]	;INSERT WORD OFFSET
    13000		DPB	C,[POINT 5,SBITS,35-25]	;INSERT FILE NU	DP
13100		DPB	D,[POINT 6,SBITS,35-30]	;INSERT "P" POINTER
    13200		MOVEM	SBITS,BCRDW1		;SAVE
 13300	BCRDN2:	HRL	SBITS,BCORDN		;COORD NUMBER
   13400					;SEE IF ANYTHING IS IN THE ACS
   13500		MOVSI	TEMP,-20		;LENGTH OF ACKTAB
   13600		MOVE	A,ACKTAB(TEMP)
  13700		JUMPE	A,.+3			;JUMP IF VACANT
  13800		ADDI	A,1
   13900		JUMPN	A,.+3			;JUMP IF NOT PROTECTED, I.E. BUSY
    14000		AOBJN	TEMP,.-4		;LOOP
14100		TLO	SBITS,400000		;MARK AS ALLSTO
   14200	
  14300		HRR	SBITS,PCNT
  14400		MOVEM	SBITS,BCRDW2		;SAVE
 14500	
  14600	BXCRD:
 14700	;;%##% 1! JFR 4-18-76
 14800		POP	P,D
    14900		POP	P,C
    15000		POP	P,B
    15100		POP	P,A
    15200		POPJ	P,
    15300	
  15400	^^BCROUT:			;PUT COORD OUT TO .SM1 FILE IF NECESSARY
15500	;;%##% 1! JFR 4-18-76
 15600		SKIPE	TEMP,BPNXTC	;DONT PUT ONE OUT IF TEXT NOT MARKED YET
   15700		SKIPLE	TEMP,BAILON	;SKIP IF BAIL OFF
15800		TRNN	TEMP,BBCRD	;SKIP IF WE WANT COORDS
  15900		 POPJ	P,
   16000		MOVE	TEMP,PCNT
  16100		SKIPN	NOEMIT		;NO COORDS FOR EXPR TYPE
   16200		CAMN	TEMP,BPPCNT	;NO SKIP IF PCNT SAME AS BEFORE
   16300	BCRPJ:	 POPJ	P,
  16400		SETZM	BPNXTC		;REMEMBER TO MARK SOURCE AT NEXT TOKEN
    16500		EXCH	TEMP,BPPCNT	;UPDATE, KEEP OLD VALUE
 16600		JUMPE	TEMP,BCRPJ	;FIRST TIME THROUGH IS JUST SETUP
 16700		PUSH	P,A
   16800		PUSH	P,B
   16900		PUSH	P,C		;TAKE CARE IN SCANNER
17000	;;%##% 1! JFR 4-18-76
 17100		PUSH	P,D
   17200		AOS	A,BCORDN	;INCREMENT COORD COUNT
 17300		TLOE	A,1		;IS CURRENT TABLE OF .SM1 FILE A COORD TABLE?
 17400		 JRST	BCROU1		;YES
   17500		MOVEM	A,BCORDN	;UPDATE
    17600		SETZ	SBITS,
17700		PUSHJ	P,VALOUT	;END PREVIOUS TABLE OF .SM1 FILE
    17800		MOVEI	SBITS,BAICRD
   17900		PUSHJ	P,VALOUT	;START COORD TABLE
   18000	BCROU1:	MOVE	SBITS,BCRDW1
  18100		PUSHJ	P,VALOUT	;FIRST WORD
18200		MOVE	SBITS,BCRDW2
    18300		PUSHJ	P,VALOUT	;SECOND WORD
    18400		JRST	BXCRD
 18500	>;BAIL
 18600		
 18700	CONCHK:
18800	;;%DI% 3! JFR 12-2-75 CLEAN UP BEGINNING OF COORDINATE, ESP. FOR "CASE"
 18900	BAIL<	SKIPN	BPNXTC		;IF SOURCE NOT MARKED
 19000		 PUSHJ	P,BMKSRC	; THEN DO SO
   19100	>;BAIL
 19200		TLNE	A,LETDG		; LETTER OR NUMBER?
   19300		JRST	CHKNUM		; YES, GO SEE WHICH
    19400	BAIL<
  19500		CAIN	B,";"		;TEST FOR END OF STATEMENT
   19600		 PUSHJ	P,BCROUT	;YES. PUT OUT COORDINATE
 19700	>;BAIL
 19800	;;\UR#4\ ALLOW := FOR _, >= FOR GEQ, <= FOR LEQ , ** FOR ^
    19900	        CAIN    B,":"
 20000		 JRST    [PUSHJ P,[SNEAKC:
20100				ILDB B,PNEXTC	; PICK UP NEXT CHARACTER
 20200				SKIPGE A,SCNTBL(B); MAKE SURE NOT END OF BUFFER ETC.
  20300				PUSHJ P,(A)	; IF IS. HANDLE IT.
   20400				TRNN TBITS2,-1	; LISTING?
    20500				ML$CHR		; YEP.
20600				POP P,TEMP	;RETRIEVE PTR TO ARGS
  20700				MOVE A,@(TEMP)	;ASSUME THIS
  20800				CAMN B,1(TEMP)	;DOES 2ND CHAR MATCH?
   20900				JRST CHAROUT	;YES, ASSUMPTION CORRECT
  21000				MOVEM B,SAVCHR	;ASSUMPTION WRONG. SAVE 2ND CHAR
  21100				MOVEM B,LSTCHR 
    21200				MOVE A,@2(TEMP)	;GET ORIGINAL SEMANTICS
21300				JRST   CHAROUT]	;AND LEAVE
   21400			SCNTBL+"_"	;ASSUME SEMANTICS OF _
  21500			0,,"="		;2ND CHAR OF := IS "="
21600			SCNTBL+":"	;SEMANTICS IN CASE ASSUMPTION OF _ FAILS
    21700	                ]
21800	        CAIN    B,76		;a  GREATER THAN CHAR
    21900		 JRST    [PUSHJ P,SNEAKC
  22000			SCNTBL+""	;ASSUME WE REALLY HAVE GEQ
   22100			0,,"="		;2ND CHAR IS "="
 22200			SCNTBL+76]	;ASSUMPTION FAILS, WE HAVE GTR
    22300	        CAIN    B,74
  22400		 JRST    [PUSHJ P,SNEAKC
  22500			SCNTBL+""
22600			0,,"="
    22700			SCNTBL+74]
22800	        CAIN	B,"*"
    22900		 JRST    [PUSHJ P,SNEAKC
  23000			SCNTBL+"^"
23100			0,,"*"
    23200			SCNTBL+"*"]
    23300	;;\UR#4\
    23400		TLNN	A,QUOTE		;STRING CONSTANT?
23500		 JRST	CHAROUT		; NO, OPERATOR, OUTPUT ID, NULL SEMANTICS
23600	;;#XO# ! JFR 10-14-76
 23700		TLZ	TBITS2,EOFOK	;saw a " char, must see another
   23800					; (particularly after final END "FOO )
23900		SKIPN	DLMSTG		; HAS A QUOTE BEEN USED TO DELIMIT A MACRO
24000					;  BODY WHILE IN REQUIRE DELIMITERS MODE?
  24100		JRST	STRNG		; NO, SCAN A STRING CONSTANT IN NORMAL MODE.
24200		SETZM	DLMSTG		; YES, TURN OFF DLMSTG FLAG AND TURN ON 
  24300		SETOM	BAKDLM		;  BAKDLM FLAG SO THAT WHEN SCANNING THE 
 24400		JRST	STRNG		;  MACRO BODY A QUOTE WILL BREAK THE SCAN.
  24500	
  24600	CHKNUM:	TLNE	A,NUMB		;NUMBER PART?
   24700		 JRST	 SCNUMB		; YES, SCAN NUMBER
   24800	
  24900	
          00100	; ID -- RESET FOR SCAN
00200	
  00300	DSCAN:	PUSHJ	P,INSET		;CLEAR PNAMES, COUNT, ALIGN TO FW
  00400	BAIL<
  00500		SKIPN	BPNXTC		;DOES DEBUGGER KNOW WHERE WE ARE?
    00600		 PUSHJ	P,BMKSRC	;NO -- GO MARK PLACE
00700	>;BAIL
 00800		MOVE	TBITS2,SCNWRD	;MAKE SURE THE BITS ARE RIGHT
   00900		TLO	TBITS2,EOFOK	;EOF CAN END THE WORLD WITHOUT KILLING IT
   01000		MOVEI	C,1		;ACCOUNT FOR FIRST CHARACTER
  01100		TRNA
  01200		ML$CHR			;TO LISTING FILE
 01300	IDSCAN:	IDPB	A,TOPBYTE(USER)	;STORE CONVERTED CHAR
  01400		ILDB	B,PNEXTC	; GET NEXT CHARACTER
  01500		SKIPGE	A,SCNTBL(B)	;GET GOOD BITS, CHECK SPECIAL
   01600		PUSHJ	P,CSPEC		;SPECIAL, DO SOMETHING
    01700		TLNE	A,LETDG		;DONE WITH ID?
   01800		 AOJA	 C,IDSCAN-1(TBITS2) ;NO, GO GET MORE.
   01900	
  02000	Comment  Now the symbol is in string space, pointed to
  02100		by the string descriptor in PNAME, etc. Store the
  02200		count, make the lookup, set up the results 
  02300	
  02400		CAIE	B,12		;IF LF, ALREADY HANDLED, LEAVE SAVCHR 0
 02500		MOVEM	B,SAVCHR	;SAVE THE BREAK BITS (0 IF BLANK OR CR BROKE)
 02600		MOVEM	B,LSTCHR	;ALSO HERE ANY TIME
  02700		TLZ	TBITS2,EOFOK	;DONE WITH THIS MODE
    02800	
  02900		PUSHJ	P,UPDCNT	;UPDATE PNAME CNT, REMCHR CNT, COLLECT IF NECC.
    03000		MOVE	LPSA,SYMTAB	;TRY TO FIND IT
    03100		PUSH	P,B		;SAVE FOR LATER
 03200		PUSHJ	P,SHASH		;LIKE SO
   03300		POP	P,B		;GET IT BACK
03400		MOVEM	TBITS2,SCNWRD	;SAVE ANY CHANGES
    03500		TLNE	TBITS2,LOKPRM	;STACK IT?
  03600		 POPJ	 P,		; NO, IN STRING CONSTANT MODE
 03700	
  03800	;  GET RELEVANT DATA TO STACKS
  03900	
  04000		MOVE	A,%ID		;IT IS AN IDENTIFIER
    04100		SKIPG	LPSA,NEWSYM	;IF IT IS UNDEFINED,
   04200		 JRST	 LSTACK		;   PUSH TO STACKS
   04300	
  04400		MOVE	TBITS,$TBITS(LPSA)
   04500	;IF CREFFING, DO IT NOW...
 04600		TLNE	FF,CREFSW	;
04700		PUSHJ	P,LCREFIT
 04800	
  04900		 JUMPGE	 TBITS,USID	; NO, USER ID
   05000		LSTDPB
05100		MOVE	A,TBITS		;RESULTANT PL-ID
 05200	;;%CI% ! JFR 7-26-75
  05300		MOVEI	TEMP,$PNAME+1(LPSA)	;ADDR OF B.P. TO RES WORD
05400		MOVEI	LPSA,0		;MAKE NULL SEMANTICS
  05500		CAMN	A,%COMMENT	; COMMENT?
05600		 JRST	 CHKSAV		; YES, GO PROCESS IT
 05700		TLNN	TBITS,CONRES	; PARSER SWITCHING RESERVED WORD?
05800		JRST	STACK		; NO, RETURN RESERVED WORD
   05900	;;%CI%
 06000		MOVEM	TEMP,TRKMCR	;CURRENT "MACRO"
  06100		SKIPN	SWCPRS		; YES, NEED TO SWITCH PARSERS?
  06200		 JRST	STACK		; NO, RETURN RESERVED WORD
  06300		TLNE	TBITS2,MACIN	;IN A MACRO??
06400		 JRST	.+5		;YES, DON'T RECORD
  06500		MOVEM	TEMP,TRKMCS	;	SOURCE-FILE TOKEN
    06600		MOVEI	TEMP,TRKM.P-1
  06700		PUSH	TEMP,FPAGNO	;	PAGE #
 06800		PUSH	TEMP,ASCLIN	;	LINE #
 06900	;;%CI% ^
    07000		TLNE	TBITS,DEFINT	; PARSER INTERRUPT (I.E. NO SWITCHING)?
    07100		JRST[SKIPE NODFSW	; DEFER DEFINE HANDLING FOR BLOCK EXECUTION?
    07200		JRST	STACK		; YES, RETURN RESERVED WORD
  07300		MOVE 	TEMP,SCNNO	; YES, SAVE NUMBER OF SCANS REMAINING IN LEFT HALF 
   07400		MOVE	B,PCSAV		;  OF TOP OF PRODUCTION STACK, UNPACK $TBITS ENTRY 
 07500		HRLM	TEMP,(B)	;  OF THE RESERVED WORD TO GET AN INDEX OF ADDRESS 
 07600		JRST	CONDAD]		;  TO PUSHJ TO, AND SET SCNNO TO ONE.
07700		TLNE	TBITS,CONDIN	; CHECK IF ENDC HAS OCCURRED AS THE END OF A WHILEC,
 07800		JRST	ENDCOK		;  CASEC, FORC, OR FORLC BODY AND IF SO, THEN DO NOT
 07900		HLRZ	TEMP,ENDCTR	;  SWITCH PARSERS.  ENDCTR IS A POINTER TO A QSTACK 
  08000		SKIPE	(TEMP)		;  INDICATING SUCH INFORMATION.  
    08100		JRST	STACK		;
   08200	ENDCOK:	MOVEI	TEMP,CGPSAV-1		; DETERMINE WHICH PARSER ONE IS CURRENTLY IN AND 
    08300		SKIPN	PRSCON		;  GET THE ADDRESS TO SAVE ITS PARSER DESCRIPTOR.
   08400		MOVEI	TEMP,SGPSAV-1	;  SAVE SEMANTIC STACK POINTER, PARSE STACK POINTER,
    08500		PUSH	TEMP,GPSAV	;  NUMBER OF SCANS REMAINING IN LEFT HALF OF TOP OF 
   08600		PUSH	TEMP,PPSAV	;  PRODUCTION STACK, PRODUCTION STACK POINTER, 
   08700		MOVE	SP,SCNNO	;  CURRENT SCNWRD, AND A POINTER TO THE SCNWRD 
08800		MOVE	B,PCSAV		;
 08900		HRLM	SP,(B)		;  STACK.
    09000		PUSH	TEMP,PCSAV	;
    09100		MOVE	B,SCWSV		;
 09200		MOVEM	TBITS2,(B)	; SAVE SCNWRD
 09300		PUSH	TEMP,SCWSV	;
    09400		HRROI	TEMP,SSCWSV ; DETERMINE WHICH PARSER IS TO BE RESUMED AND GET 
   09500		SKIPN	PRSCON		;  THE ADDRESS OF ITS PARSER DESCRIPTOR.
  09600		HRROI	TEMP,CSCWSV	;
  09700		POP	TEMP,B		; RESTORE SCNWRD STACK POINTER
    09800		TLNE	TBITS,CONDIN	; IF ONE IS SWITCHING PARSERS VIA A PUSHJ INSTEAD OF
 09900		JRST[TLZ TBITS2,INLIN	;  PROPER SCANNING OF INLINE STARTCODE.  COMPENSATE
   10000		TRO	TBITS2,NOLIST	;  FOR NOT POPPING TEMP.
    10100		PUSH	B,TBITS2	;
 10200		JRST	.+2]		;
    10300		MOVE	TBITS2,(B)	; RESTORE SCNWRD AND TBITS2
   10400		MOVEM	B,SCWSV		;
10500		MOVEM	TBITS2,SCNWRD	;
10600		ML$BAK			; DON'T LIST PARSER SWITCH TRIGGERING RESERVED WORDS
10700		POP	TEMP,B		; RESTORE CONTROL STACK POINTER
   10800		POP	TEMP,SP		; RESTORE PARSE STACK POINTER.  MUST BE IN AC AS 
    10900		MOVEM	SP,PPSAV	;  WELL AS IN MEMORY.
11000		POP	TEMP,GPSAV	; RESTORE SEMANTIC STACK POINTER
    11100		SETCMM	PRSCON		; COMPLEMENT PARSER IN CONTROL FLAG
 11200		MOVEI	C,1001		; ASSUME A RESUME TYPE SWITCH
   11300		TLNN	TBITS,CONDIN	; RESUME TYPE SWITCH?
  11400		JRST	SWTPRE		; YES
   11500	CONDAD:	HLRZ	C,TBITS		; CONDAD IS CALLED WITH THE $TBITS ENTRY 
    11600		TRZ	C,RES+CONBTS	;  OF A PARSER INTERRUPT RESERVED WORD IN 
  11700		LSH	C,-IF0SHF	;  TBITS.  IT INSERTS THE ADDRESS OF THE 
 11800		MOVEI	C,PRODGO(C)	;  PRODUCTION WHICH ONE IS TO EXECUTE NEXT
 11900		PUSH	B,C		;  IN THE PRODUCTION CONTROL STACK.  TBITS
    12000		MOVEI	C,4001		;  IS UNPACKED TO GET AN INDEX TO A TABLE
 12100					;  STARTING AT PRODG0 (BITS 6-8).  SET 
    12200					;  REMAINING NUMBER OF CALLS TO SCANNER TO 
12300					;  ONE SO THAT THE PARSER WILL NOT SCAN 
   12400					;  AGAIN AND SET A BIT TO DO A PUSHJ.
 12500	SWTPRE:	MOVEM	B,PCSAV		; RESTORE CONTROL STACK POINTER IN CORE
12600		MOVEM	C,SCNNO		; SET REMAINING NUMBER OF CALLS TO SCANNER
    12700		JRST	STACK		; GO STACK
    12800	
  12900	
          00100	Comment   COMMENT -- throw out everything to next semicolon
  00200	
 00300	
  00400	CHKSAV:	MOVE	B,SAVCHR	;BE SURE SAVCHR IS NOT ";"
    00500		SETZM	SAVCHR
    00600		SETZM	LSTCHR
    00700	;; #PC#! OVERWRITING FIRST LINE IN CREF 
  00800		JUMPE	B,COMLUP	; NULL HAS ALREADY BEEN HANDLED 
    00900		SKIPGE	A,SCNTBL(B)	;GET BITS, CHECK SPECIAL
   01000		PUSHJ	P,(A)		;SPECIAL, GET PAST PROBLEM
  01100		JRST	COMLUP		;GET THEM ALL
01200	
  01300		ML$CHR			;TO LISTING FILE
 01400	NOBAIL<
01500	COMLUP:	CAIN	B,";"		;DONE?
 01600		 JRST	 SCANNER		; YES
01700	>;NOBAIL
    01800	BAIL<
  01900	COMLUP:	CAIE	B,";"		;DONE?
 02000		 JRST	COMILD		; NO
   02100		SETZM	BPNXTC		;YES. MARK SOURCE AT NEXT TOKEN
 02200		JRST	SCANNER
    02300	>;BAIL
 02400	COMILD:	ILDB	B,PNEXTC	;GET NEXT CHAR
 02500		SKIPGE	A,SCNTBL(B)	;USUAL
 02600		PUSHJ	P,(A)
02700		 JRST	 COMLUP-1(TBITS2) ;GO PUT AWAY, GET ANOTHER
  02800	
          00100	DSCR -- USID
00200	DES An identifier has been found.  If it is a macro name, go
  00300	  expand it.  Otherwise call TYPDEC routine to provide the
    00400	  proper parse token for this identifier (differentiates 
00500	  ARRAYS from PROCEDURES from STRINGS from ....
00600	SEE TYPDEC in GEN, for providing correct parse token.
    00700	
 00800	
  00900	USID:	SKIPN	SWCPRS		; IN FALSE PART OF CONDITIONAL COMPILATION? 
   01000		SKIPN	IFCREC		; YES, SHOULD MACROS BE EXPANDED? 
   01100		JRST	TSTDEF		; YES, GO EXPAND MACROS 
    01200	;; #OF# ! MAKE SURE A IS VALID BEFORE GOING OFF TO STACK
 01300		MOVE	A,%ID		
    01400		JRST	STACK		; NO, DON'T EXPAND MACROS OR CHECK TYPES AND RETURN
   01500	TSTDEF:	TLNE	TBITS,DEFINE	;NEED TO EXPAND MACRTO?
   01600		JRST	DEFRG		;YES
01700	GOHEQ:	LSTDPB
    01800		PUSHJ	P,TYPDEC
  01900		JRST	STACK
 02000	
  02100	DSCR DEFRG -- prepare to expand a macro
   02200	DES The Ident is a DEFINE Ident.  The steps are
02300	1.	Save current Parse and Semantic Stack state,
02400		 other state which will be destroyed.
    02500	2.	If no parameters to get, go to step 5.
 02600	3.	Get a parameter (special form string constant,
   02700		 see manual), via SCANNER (recursive call, also
    02800		 ENTERS); place on special VARB-RING whose ring
    02900		 variable is VARB, and whose starting element is
   03000		 in DEFRN2.
03100	4.	If comma, go to step 3 for more, else check for 
 03200		 right paren.
   03300	5.	Save previous SCANNER information on DEFPDP stack,
    03400		 set up DEFRNG for actuals, put macro body descrip-
03500		 tor in PNEXTC, restore stacks and VARB, etc.
 03600	6.	Handle macro expansions in listing.
    03700	7.	JRST to SCANNER for another try with the new PNEXTC
   03800	
 03900	
  04000	DEFRG:	HLRZ	A,%TLINK(LPSA)	; CHECK IF MACRO HAS BEEN INITIALIZED.
  04100		JUMPN	A,DEFRG1	;
04200		ERR <MACRO WAS NOT INITIALIZED - INITIALIZE TO ZERO AND CONTINUE>,1; 
  04300		SETZM	A		; SOLVES PROBLEMS SUCH AS:
 04400		PUSHJ	P,CREINT	;  DEFINE NAME=NAME+1 WITHOUT A DEFINE NAME=0 
04500		MOVE	LPSA,PNT	;  OR ANOTHER INITIAL VALUE.
    04600		MOVE	A,%NUMCON	;
04700		JRST	STACK		;
   04800	DEFRG1:				;CREATE A NEW DEFINE ELEMENT
   04900		TLNE	FF,NOMACR	;EXPAND MACROS??
05000		JRST	[LSTDPB
    05100			 MOVE A,%ID
    05200			 JRST STACK];NO -- USER ID.
   05300	
  05400	; IF WE DON'T WANT TO SEE MACRO NAMES IN OUTPUT LISTING, BACK UP OUTPUT PTR.
 05500	; ALSO TURN OFF LISTING FOR PARAMS
   05600	
  05700		TLNN	TBITS2,MACLST	;LIST MACRO NAMES?
    05800		 JRST	 [ML$BAK	;NO, NULLIFY ALL TO DATE
  05900			  TRO	TBITS2,NOLIST ;LIST NO MORE FOR A WHILE
06000			  JRST	.+1]
    06100	
  06200		PUSHJ	P,SCNACT	; GET ACTUAL PARAMETER LIST
    06300		PUSHJ	P,ACPMED	; FINISH OFF THE MACRO CALL PREPARATION
  06400		JRST	SCANNER		; TRY AGAIN (SCAN THE MACRO BODY!)
   06500	
  06600	; SPECIAL DELIMITER MODE ACTUAL PARAMETER SCANNING ROUTINE
    06700	
  06800	SCNPMR:	PUSHJ	P,INSET		; SET UP STRING SPACE ENTRY
  06900		TRNA			; SKIP
   07000		ML$CHR			; LIST MAYBE
07100	DSPRMS:	ILDB	B,PNEXTC	; GET NEXT CHAR.
    07200		SKIPGE	A,SCNTBL(B)	; SPECIAL?
  07300		PUSHJ	P,CSPEC		; DO IT
    07400		JUMPE	A,DSPRMS-1(TBITS2) ; AGAIN IF IGNORABLE
 07500		CAME	B,CURPBG	; PARAMETER BEGIN DELIMITER?
    07600		JRST	BALCHK		; NO, NESTED-BALANCED COMMA OR RPAR WILL BREAK
  07700		LSTDPB			; LIST IT?
  07800		SETZM 	BNSTCN		; SET NEST COUNT TO ZERO
  07900		JRST	PSCAN+3		; CONTINUE SCAN
  08000	PSCAN:	LSTDPB			; LIST IT?
 08100		IDPB	B,TOPBYTE(USER)	; DEPOSIT
 08200		ILDB	B,PNEXTC	; GET NEXT CHAR.
 08300		SKIPGE	A,SCNTBL(B)	; SPECIAL?
  08400		PUSHJ	P,CSPEC		; DO IT
    08500		CAMN	B,CURPED	; PARAMETER END DELIMITER?
 08600		JRST    SPMEND		; YES, CHECK IF DONE
08700		CAMN	B,CURPBG	; PARAMETER BEGIN DELIMITER?
    08800		AOS	BNSTCN		; INCREMENT NEST COUNT
  08900		AOJA	C,PSCAN		; SCAN AGAIN
09000	SPMEND: SOSL	BNSTCN		; DECREMENT NEST COUNT AND CHECK IF DONE
 09100		AOJA	C,PSCAN		; NO, SCAN AGAIN
 09200		ILDB	B,PNEXTC	; ADVANCE CHAR. TO KEEP IN SYNCH.
    09300		SKIPGE	A,SCNTBL(B)	; SPECIAL?
  09400		PUSHJ	P,CSPEC		; DO IT
    09500		JRST 	ENDSTR		; GO TO END
 09600	DEPOSB:	CAIN	B,")"		; RIGHT PAREN WITH NONZERO NEST COUNT?
    09700		SOS	LOCNST+RPAROF	; DECREMENT NEST COUNT
 09800	DEPOSA:	LSTDPB			; LIST IT?
09900		IDPB	B,TOPBYTE(USER)	; DEPOSIT
 10000		AOJ	C,		; INCREMENT CHARACTER COUNT
 10100		ILDB	B,PNEXTC	; GET NEXT CHAR.
 10200		SKIPGE	A,SCNTBL(B)	; SPECIAL?
  10300		PUSHJ	P,CSPEC		; DO IT
    10400	BALCHK:	CAIE	B,","		; END OF PARAMETER?
   10500		CAIN	B,")"		; 
  10600		JRST	ENDCHK		; POSSIBLY, GO CHECK
   10700		TLNN 	A,NEST		; NESTED CHARACTER?
   10800		JRST 	DEPOSA		; NO, GO DEPOSIT
 10900		MOVE 	TEMP,[AOS LOCNST-1(LPSA)] ; SET UP INSTRUCTION TO UPDATE APPROP. NEST COUNT
11000		TLNN	A,LNEST		; LEFT NESTED?
   11100		TLO	TEMP,AOSSOS	; NO, CHANGE INSTRUCTION TO SUBTRACT
    11200		HRRZ	LPSA,NSTABL(B)	; LOAD CHAR'S NESTED COUNT INDEX
    11300		XCT	TEMP		; MODIFY COUNT
  11400		JRST 	DEPOSA		; GO DEPOSIT
11500	ENDCHK:	MOVEI	TEMP,NUMNST-1	; SET UP COUNT
11600	EDLOOP:	SKIPN	LOCNST(TEMP)	; NEST COUNTEQUAL ZERO?
  11700		SOJGE	TEMP, EDLOOP	; YES, AND TRY NEXT IF NOT DONE
 11800		JUMPGE	TEMP,DEPOSB	; GO DEPOSIT IF NOT ALL NEST COUNTS EQUAL ZERO
 11900		JRST 	ENDSTR		; GO TO END
 12000	
  12100	
          00100	DSCR -- SCNACT
   00200	DES This procedure is used to scan a list of actual parmeters for a macro
    00300	  or a conditional compilation FORLC statement.  When the latter happens
00400	  SCNACT is called from the EXEC routine GETACT which appears in GEN. 
  00500	  FORLC statements have a body which is scanned as many times as one has
00600	  parameters in the actual list; in each case a different actual is used
00700	  as the parameter.
   00800	PAR LPSA contains the semantics of the macro name or macro pseudonym in
 00900	  case a FORLC list is being scanned (address of semblk of name).
  01000	RES DEFRN2 contains the address of the first actual parameter in the list.
   01100	
 01200	
  01300	^SCNACT: PUSH	P,LPSA		;SAVE SEMANTICS OF DEFINE SYMBOL
   01400		PUSH	P,VARB		;WILL MAKE NEW ONE FOR MACRO ARGUMENTS
01500		PUSH	P,PPSAV	;SAVE THE STACKS
  01600		PUSH	P,GPSAV
    01700		SETZM	DEFRN2		;INITIALIZE FOR NEW MACRO
  01800		SETZM	VARB
 01900	;;%CI% (2,3/5) JFR 7-25-75
 02000		MOVEI	TEMP,$PNAME+1(LPSA)	;ADDR OF B.P. TO MACRO NAME
   02100		MOVEM	TEMP,TRKMCR	;CURRENT MACRO
    02200		TLNE	TBITS2,MACIN	;IN A MACRO??
02300		 JRST	.+5		;YES, DON'T RECORD SOURCE-FILE INFO
02400		MOVEM	TEMP,TRKMCS
    02500		MOVEI	TEMP,TRKM.P-1
  02600		PUSH	TEMP,FPAGNO
02700		PUSH	TEMP,ASCLIN
02800	;;%CI% ^
    02900		HLRZ	TEMP,$VAL(LPSA)	;ANY PARAMETERS NEEDED?
  03000		JUMPE	TEMP,NOPRMS	 	; NO
  03100		MOVEM	TBITS2,SCNWRD	;NOTE CHANGES
   03200	SCNAGN:	PUSHJ	P,SCANNER	;LOOKING FOR "("
  03300		MOVE	TEMP,(SP)	;SYNTAX OF SCANNED ELEMENT
03400		POP	P,GPSAV		;KEEP STACKS IN SYNCH
  03500		POP	P,PPSAV
03600		ADD	P,X22
  03700		CAMN	TEMP,%STCON	; A SPECIAL DELIMITER DECLARATION?
03800		SKIPE 	SWBODY		; YES, COULD WE POSSIBLY HAVE SEEN A SPEC DEL DECL.
03900					;  I.E. DID WE SEE ONE ALREADY?
  04000		JRST	TSLPRN		; NO, GET LEFT PAREN.
  04100		SKIPN	REQDLM		; TRYING TO OVERRIDE NULL DELIMITERS MODE?
04200		SETOM	RSTDLM		; YES, SET APPROPRIATE FLAGS
    04300		SETOM	REQDLM		;
 04400		SETOM 	SWBODY		; SET SWITCH DELIMITER DECLARATION FLAG
  04500		MOVE	TEMP,[XWD -2,2]	; SET UP A COUNT
    04600		MOVE	PNT,$PNAME+1(LPSA) ; PNT HAS BYTE POINTER TO DELIM. STRING
   04700		HRRZ	LPSA,$PNAME(LPSA) ; LPSA HAS DELIMITER STRING LENGTH
    04800		PUSHJ	P,GETDL2	; GET SPECIAL DELIMITER DECLARATION
 04900		JRST 	SCNAGN		; GO BACK AND GET LEFT PAREN.
   05000	TSLPRN:	CAME	TEMP,[TLPRN&17777777]	;PARAMS? 
   05100	;;%CU% (1/2) JFR 8-16-75 make this error continuable
05200		 JRST	[ERR	 <MISSING "(" IN MACRO CALL>,1
05300			MOVEI TEMP,SCANNER
  05400			MOVEM TEMP,-4(P)
    05500			JRST CONACT+2] ; NO
 05600	;;%CU% ^
    05700		MOVEI	B,"("
05800		LSTDPB
05900		TLO	FF,PRMSCN 	; PRIME THE SCANNER FOR PARAMETER
   06000		PUSHJ	P,FFPUSH	; SAVE OLD DEFLUK BIT OF FF AND TURN IT ON IN FF
   06100	;;#TG#	9-15-74 HJS RESTORE PARSE STACK POINTER 
06200	PRMLUP:	MOVE	SP,PPSAV	; RESTORE SP SINCE IT POINTS TO THE PARSE STACK 
  06300					;  SINCE OTHERWISE MAY GET OVERFLOW SINCE STACK 
06400					;  IS CALLED AT THE END OF EACH PARAMETER SCAN 
 06500	;;#TG# 
06600		SKIPN 	REQDLM		; IN SPECIAL DELIMITER MODE? 
  06700	 	JRST	PRMOLD		; NO	
  06800		PUSHJ	P,SCNPMR	; YES, GET THE PARAMETERS
 06900		TRNA
  07000	PRMOLD:	PUSHJ	P,SCANNER	;GET A PARAMETER
  07100		POP	P,GPSAV		;SYNCH STACK
 07200		POP	P,PPSAV
07300		ADD	P,X22
  07400	
  07500	; WE KNOW RESULT IS STRING CONSTANT, SCANNER WILL RETURN NO OTHER
  07600	
  07700		SKIPN	TEMP,DEFRN2	;PUT PTR TO FIRST ARG IN DEFRN2
  07800		 MOVE	 TEMP,NEWSYM
   07900		MOVEM	TEMP,DEFRN2
    08000	
  08100		PUSHJ 	P,SCANNER	;GET NEXT PUNCTUATION
   08200		MOVE	TEMP,(SP)
  08300		POP	P,GPSAV
08400		POP	P,PPSAV
08500		ADD	P,X22		;SYNCH STACKS
  08600		CAMN	TEMP,[TCOMA&17777777]	;LOOPING?	
    08700		 JRST	 PRMLUP		;YES
  08800		CAME	TEMP,[TRPRN&17777777]	;DONE?  
 08900	;;%CU% (2/2) JFR 8-16-75 make this error continuable; even recoverable
  09000	;;	 JRST	[ERR	 <MISSING "," OR ")" IN MACRO CALL>,1
 09100	;;		MOVEI TEMP,SCANNER
09200	;;		MOVEM TEMP,-4(P)
  09300	;;		JRST CONACT]
 09400		 PUSHJ	P,[PUSHJ  P,ER40	;inserted missing )
   09500			   JRST	SCNBAK]		;scanner is ahead
 09600	;;%CU% ^
    09700		MOVE	LPSA,DEFRN2	; DETERMINE IF ALL PARAMETERS HAVE BEEN 
    09800		MOVEI	TEMP,0		;  SPECIFIED AND IF NOT FORM NULL'S FOR 
  09900	DEFLNK:	HRRZ	LPSA,%RVARB(LPSA);  ALL THOSE LEFT OUT SO THAT ASSIGNC 
    10000		ADDI	TEMP,1		;  WILL WORK PROPERLY 
 10100		JUMPN	LPSA,DEFLNK	;
  10200		MOVE	LPSA,-3(P)	; 
   10300		HLRZ	LPSA,$VAL(LPSA)
 10400		SUB	TEMP,LPSA	; NUMBER OF UNSPECIFIED PARAMETERS
   10500		MOVEM	TEMP,NULCNT	; 
 10600	TSTDON:	AOSLE	NULCNT		; ALL PARAMETERS SPECIFIED? 
  10700		JRST	CONACT		; YES, 
 10800		PUSHJ	P,INSET		; SET UP STRING SPACE ENTRY 
   10900		ADDI	C,2		; APPEND 1770 TO NULL STRING AND LINK 
  11000		MOVEI	TEMP,177	;  ON VARB AND STRING RINGS 
   11100		IDPB	TEMP,TOPBYTE(USER) ; 
11200		MOVEI	TEMP,0		; 
11300		IDPB	TEMP,TOPBYTE(USER) ; 
11400		PUSHJ	P,UPDCNT	; 
    11500		GETBLK	NEWSYM		; 
    11600		HRROI	TEMP,PNAME+1	; 
11700		POP	TEMP,$PNAME+1(LPSA) ; 
11800		POP	TEMP,$PNAME(LPSA) ; 
  11900		MOVE	TEMP,[XWD CNST,STRING] ; 
 12000		MOVEM	TEMP,$TBITS(LPSA) ; 
12100		PUSHJ	P,RNGSTR	; 
    12200		PUSHJ	P,RNGVRB	; 
    12300		JRST	TSTDON		; 
 12400	CONACT:	TLZ	FF,PRMSCN 	; DONE WITH THESE
  12500		PUSHJ	P,FFPOP		; RESTORE DEFLUK BIT OF FF
12600		SKIPE 	REQDLM		; IN SPECIAL DELIMITER MODE?
   12700		SKIPN	SWBODY		; YES, HAVE TO REVERT TO OLD DELS?
   12800		JRST	NOPRMS		; NO
    12900		SETZM	SWBODY		; RESET SWITCH DELIMITER DECLARATION FLAG
 13000		SKIPN	RSTDLM		; RESTORING NULL DELIMITERS MODE?
    13100		JRST	.+4		; NO
  13200		SETZM	RSTDLM		; YES, RESTORE APPROPRIATE FLAGS
13300		SETZM	REQDLM		;
 13400		JRST	NOPRMS		;
  13500		HRROI	TEMP,LOCMPR+1	; GET RESTORING ADDRESS
   13600		POP	TEMP,CURPED	; RESTORE START DEL.
13700		POP	TEMP,CURPBG	; RESTORE END DEL.
  13800	NOPRMS: POP	P,GPSAV		; GET SEMANTIC STACK BACK
 13900		POP	P,PPSAV		; GET PARSE STACK BACK
 14000		POP	P,VARB		; GET OLD VARB BACK
14100		POP	P,LPSA		; SEMANTICS FOR DEFINE
  14200		MOVE	SP,PPSAV	; RESTORE SP IN CASE IT GOT FOULED UP IN
  14300					;   SCANNER CALLS
 14400		POPJ	P,		; RETURN
    14500	
  14600	
  14700	
  14800	DSCR -- ACPMED
   14900	DES ACPMED prepares for a macro call once the actual parameters have been
    15000	  scanned.  It is also used to prepare for the first instantiation of the
    15100	  body of a conditional compilation WHILEC, CASEC, FORC, or FORLC statement.
 15200	PAR LPSA contains the semantics of the macro name or macro pseudonym in
 15300	  case a conditional compilation WHILEC, CASEC, FORC, or FORLC body is
  15400	  being scanned for the first time.  DEFRN2 contains the address of the
 15500	  actual parameter list in case of a FORLC statement, the address of the
15600	  loop variable semblk in case of a FORC statement, and zero in the case
15700	  of a WHILEC or CASEC statement.
    15800	RES At the end of this procedure one has effectively switched PNEXTC and
15900	  PNEXTC-1 to scan the macro body or the conditional compilation body.
  16000	  Relevant information is saved on the DEFPDP stack.
16100	
 16200	
  16300	
  16400	
  16500	^ACPMED: MOVE	PNT,DEFPDP	;RESTORE NOW
16600		PUSH	PNT,DEFRNG	;SAVE OLD RING OF PARAMETERS
  16700	
          00100		PUSH	PNT,PNEXTC-1	;STRING NUMBER
    00200		PUSH	PNT,PNEXTC	;INSTEAD SAVE THOSE WHICH
00300		PUSH	PNT,SAVCHR	; PARAMETERS
   00400		MOVEM	PNT,DEFPDP
00500		MOVE	PNT,PLINE	;WILL SAVE IN IPLINE IF LEAVING INPUT LEVEL
   00600	
  00700		HLRZ	LPSA,%TLINK(LPSA) ; STORE THE LENGTH OF THE MACRO BODY IN THE LEFT 
    00800		HRLZ	TEMP,$PNAME(LPSA) ;  HALF OF DEFRNG SO THAT WHEN FINISH SCANNING AN
    00900		HRR	TEMP,DEFRN2	;  ACTUAL PARAMETER THERE WILL BE SOME INDICATION OF 
  01000		MOVEM	TEMP,DEFRNG	;  THE MINIMUM AMOUNT OF STRING SPACE NECESSARY FOR
  01100		PUSHJ	P,CONTX2	;  THE SCANNING OF THE REMAINDER OF THE MACRO
 01200	
  01300	; DECIDE WHETHER MACRO EXPANSION SHOULD BE LISTED.
  01400	
  01500		MOVEI	B,"<"		;MARK EXPANSION IF MACRO NAME
    01600	;;#YV# JFR 2-4-77
01700		TLNN	TBITS2,LSTEXP	; IS ALSO BEING LISTED
01800		 JRST	ACPM.1
    01900		LSTDPB			;LISTING MIGHT BE OFF FOR OTHER REASONS
   02000	ACPM.1:
02100		TLON	TBITS2,MACIN	;IN A MACRO NOW
   02200		MOVEM	PNT,IPLINE	;CAN GET CURRENT LINE LOC FROM HERE
    02300	;;#ZH# JFR 9-17-77
    02400	;;	TLNN	TBITS2,MACEXP	;IF MACRO EXPANSION SHOULD NOT BE LISTED,
    02500	;;	 TRO	TBITS2,NOLIST	; INDICATE IT
  02600		PUSHJ	P,L$SET		;SET COURSE FROM ABSOLUTE BEARINGS
  02700	;;#ZH# ^
    02800	;;#YV# ^
    02900		MOVEM	TBITS2,SCNWRD	;UPDATE IN CORE
 03000		POPJ	P,		; RETURN
    03100	
  03200	
  03300	
  03400	DSCR -- CONTXT
   03500	DES CONTXT is used to switch the input pointers before a macro call or
  03600	  prior to each invocation of the body of conditional compilation WHILEC,
    03700	  CASEC, FORC, or FORLC statement.  If conditional compilation is the case
   03800	  then this is virtually all that need be done for the reinvocation of the
   03900	  body and thus it is clearly cheaper than calling the macro in the old
 04000	  sense several times with different variables (this statement is only true
  04100	  for the WHILEC, FORC, and  FORLC statement since the body of a CASEC
  04200	  statement is only scanned once).
   04300	PAR LPSA contains the semantics of the macro name or macro pseudonym in the
  04400	  case of a conditional compilation WHILEC, CASEC, FORC, or FORLC statement.
 04500	RES PNEXTC, PNEXTC-1, PLINE, and PLINE-1 are set.
   04600	
 04700	
  04800	
  04900	
  05000	^CONTXT: HLRZ	LPSA,%TLINK(LPSA)	;SEMANTICS FOR MACRO BODY
05100	CONTX2:	PUSHJ	P,SGCOL1	  ;MAKE SURE THERE'S ENOUGH ROOM
  05200		HLLZ	TEMP,$PNAME(LPSA) ;STRING NUMBER -- NULL STRING
    05300		MOVEM	TEMP,PNEXTC-1
  05400		MOVEM	TEMP,PLINE-1
   05500		MOVEW	PNEXTC,$PNAME+1(LPSA) ;SET UP NEW INPUT POINTER
   05600		MOVEM	TEMP,PLINE
05700		SETZM	SAVCHR		; NOTHING SCANNED AHEAD AT THIS LEVEL
05800		SETZM	LSTCHR		; NOTHING SCANNED AHEAD AT THIS LEVEL
05900		POPJ	P,		; RETURN
    06000	
          00100	DSCR STRNG, etc.
 00200	DES Input a string constant. Check all identifiers to see if
  00300	  they are formal parameters to a DEFINE (macro). If so,
 00400	  replace them by their internal identifiers (delete <177>
    00500	  followed by unique code). Store string constant in string
   00600	  space, place entry in table, results to HPNT and NEWSYM. 
   00700	SEE Comments on following page for details of actual param thing.
  00800	
 00900	
  01000	STRNG:
 01010		PUSHJ	P,INSET		;CLEAR AND RESET AS ABOVE
 01050	
  01110	;[05] Ensure that there is room in string space for a large string,
01115	;[05] thereby making it less likely that a large string constant or
01117	;[05] macro will cause TOPBYTE out of range at STRNGC error
   01120		EXTERNAL STRGC		;[05] Need this for patch
01150		MOVEI	A,^D5000	;[05] We want at least 5000 chars
   01155		MOVE	B,REMCHR(USER)	;[05] Neg. Number chars left
   01160		ADD	B,A		;[05] 
 01165		SKIPG	B		;[05] More than 5000 chars left?
01167		 JRST	STRNG1		;[05] Yes, we are safe
01168		PUSH	P,A		;[05] No, so get some space
    01170		PUSHJ	P,STRGC		;[05]
 01175		PUSHJ	P,INSET		;[05] Need to do this again
    01185	
  01190	STRNG1:	
    01200		TLZ	FF,PRMXXX	;IF " WAS FIRST CHAR, NOT IN SPECIAL MODE
 01300	STSCAN:
01400		ILDB	B,PNEXTC	;PRESERVE NEXT CHARACTER
   01500	BAKSTR:	SKIPGE	A,SCNTBL(B)	;DO SPECIAL THINGS
  01600		PUSHJ	P,CSPEC		;IF REQUIRED
    01700	BAKST1:	TLNN	A,LETDG		;THINK HARD ONLY ON QUOTE, LETTDIG
 01800		JRST 	MORSTR		; NOT LETTER OR DIGIT
 01900		TLNE	FF,DEFLUK	; SCANNING A MACRO BODY?
  02000		TLNE	FF,PRMSCN	; YES, SCANNING MACRO PARAMETERS
    02100		JRST 	MORSTR		; YES, CHECK DELIMITERS
    02200		SKIPN 	REQDLM		; SPECIAL DELIMITER MODE?
 02300		JRST	DEFCHK 		; NO, THINK HARD
 02400		CAMN 	B,CURMED	; MACRO BODY END DELIMITER?
    02500		JRST	LTDEND		; YES, CHECK IF DONE
   02600		CAMN	B,CURMBG	; MACRO BODY BEGIN DELIMITER?
   02700		AOS	BNSTCN		; YES, INCREMENT NEST COUNT
  02800		JRST	DEFCHK		; THINK HARD
 02900	LTDEND:	SOSL	BNSTCN		; DECREMENT NEST COUNT AND CHECK IF DONE
 03000		JRST	DEFCHK		; THINK HARD
 03100		JRST 	LTDCON		; TERMINATE MACRO BODY SCAN
03200	
  03300	MORSTR:	TLNN	FF,PRMXXX	;IN SPECIAL PARAMETER-SCANNING MODE?
   03400		 JRST	 MORST1		; NO, CONTINUE
  03500	
  03600		CAIE	B,","		;END OF PARAMETER?
 03700		CAIN	B,")"
 03800		 JRST	 ENDSTR		; YES
 03900		JRST	DEPOSIT		;LET SINGLE QUOTES THRU IN THIS MODE
 04000	MORST1:	SKIPN	DLMSTG		; A SPECIALLY DELIMITED STRING?
    04100		JRST 	MORST2		; NO, GO CHECK FOR QUOTES
  04200		CAMN	B,CURMED	; MACRO BODY END DELIMITER?
04300		JRST	MBDEND		; YES
   04400		CAMN	B,CURMBG	; MACRO BEGIN DELIMITER?
   04500		AOS	BNSTCN		; YES, INCREMENT NEST COUNT
  04600		JRST 	DEPOSIT		; DEPOSIT
  04700	MBDEND:	SOSL	BNSTCN		; DECREMENT NEST COUNT AND CHECK IF DONE
 04800		JRST 	DEPOSIT		; DEPOSIT
  04900	LTDCON:	LSTDPB			; PUT IT AWAY
  05000		ILDB	B,PNEXTC 	; GET NEXT CHAR. TO KEEP IN SYNCH.
  05100		SKIPGE	A,SCNTBL(B)	; SPECIAL?
  05200		PUSHJ	P,CSPEC		;DO IT
05300		JRST	ENDSTR		; GO TO END
  05400	MORST2:	TLNN	A,QUOTE		;END OR DOUBLE-QUOTE ?
   05500		 JRST	 DEPOSIT	; NO, PUT IT AWAY
    05600	
  05700		LSTDPB			;PUT IT AWAY
05800		ILDB	B,PNEXTC	;TRY NEXT
   05900		SKIPGE	A,SCNTBL(B)	; DO THE USUAL IF SPCL
06000		PUSHJ	P,CSPEC
   06100		TLNN	A,QUOTE		;IS IT ONE?
 06200		JRST[SKIPE BAKDLM	; YES, CHECK IF NEED TO RESTORE DLMSTG
06300		SETOM	DLMSTG		; YES
  06400		SETZM	BAKDLM		; TURN OFF BAKDLM
06500		 JRST	 ENDSTR]	; DONE
06600	
  06700	DEPOSIT:
    06800		LSTDPB			;TO LISTING FILE IF REQD
   06900	DEPO1:	IDPB	B,TOPBYTE(USER)	;STORE CHARACTER AS IS
  07000		AOJA	C,STSCAN	;LOOP ON RANDOM CHARACTERS
 07100	
  07200	
          00100	COMMENT  
  00200	We come here if a letter or number has been seen.  If we are not
   00300	 scanning a macro body, we simply scan the rest of the characters
  00400	 which could be an identifier into the string constant, and return
 00500	 to the main string constant scanning loop.
    00600	
  00700	If we are scanning a macro body, this may be a parameter name.
00800	 The following algorithm is used:
    00900	   1. If not a letter, continue as if were not scanning macro body.
01000	   2. Save the length of the string up to the start of the ident.
  01100	   3. Scan this (possible) param into the constant, no case conversion.
 01200	   4. Save the length of the string up to the end of the ident.
    01300	   5. Save state of scanner (char, bits), then return PNEXTC to the
01400	      ident within the string const.  Call DSCAN (ident scanner) to con-
01500	      vert and lookup this identifier (some special bits set to avoid
   01600	      stacking results, etc.)
   01700	   6. If not a DEFINE parameter, reset TOPBYTE and PNAME pointers to
    01800	      their state at the end of step 3, clear space used during DSCAN,
  01900	      and return to main string constant loop.
 02000	   7. Back TOPBYTE pointer up to the length of step 2, insert '177
 02100	      (param marker), followed by param number into string, clear space
 02200	      used during steps 3 and 4, update PNAME count properly, and return
02300	      to main loop.
   02400	
  02500	 Substring operations are used to retrieve the relevant byte
  02600	 pointers from the saved lengths, and only when they are really
    02700	 needed, to avoid the garbage collect problems with multiple
  02800	 saved pointers which plagued past implementations, and made
  02900	 the multiple string space implementation impossible.
    03000	
  03100	Be warned (again) that the current setup is the result of several
  03200	 (+1) killed bugs  --  each  thought to  be the  last.  No
    03300	 guarantees are proferred that no more exist, but chances are
 03400	 (even) better than ever.
  03500	
 03600	
          00100	DEFCHK:
00200		TLNE	A,NUMB		;MUST BE A LETTER
 00300		 JRST	 DEPOSIT	; DIGIT OR OTHER NUMBER PART, GO ON
 00400		PUSH	P,C	;save length just before scanning ident
   00500	RANSCN:	ADDI	C,1		;COUNT FIRST CHAR
  00600		LSTDPB			;LIST IF NECESSARY
    00700	RANSC1:	IDPB	B,TOPBYTE(USER)	;KNOW FIRST ONE IS OK
  00800		ILDB	B,PNEXTC
   00900		SKIPGE	A,SCNTBL(B)	;USUAL TEST
 01000		 PUSHJ	 P,CSPEC
 01100		TLNN	A,LETDG
    01200		JRST	SEEPRM		; NOT A LETTER OR DIGIT
01300		SKIPN	REQDLM		; SPECIAL DELIMITER MODE
   01400		JRST 	CHKCON		; NO
   01500		CAMN	B,CURMED	; MACRO BODY END DELIMITER
 01600		JRST	MBEDCK		; YES
   01700		CAMN	B,CURMBG	; MACRO BODY BEGIN DELIMITER
    01800		AOS	BNSTCN		; YES, INCREMENT NEST COUNT
  01900		JRST	CHKCON		; CONTINUE ID SCAN
02000	MBEDCK:	SOSL 	BNSTCN		; DONE WITH MACRO BODY
   02100	CHKCON:	 AOJA	 C,RANSC1-1(TBITS2) ; COUNT AND LOOP
  02200	
  02300	; NOW CONVERT IDENT TO UPPER CASE, ALIGN, CALL SCANNER TO LOOK IT UP
    02400	
  02500	SEEPRM:	
    02600		PUSH	P,A		;SAVE BITS,
02700		PUSH	P,B		; CHARACTER, AND CURRENT TOTAL
 02800		PUSH	P,C		; MACRO BODY STRING COUNT
 02900		HRRM	C,PNAME		; END POINTER OVER GC
 03000	; P stack is:
    03100	;  -3 -- length before ident scanned into string const
   03200	;  -2 -- bits for char after ident.
  03300	;  -1 -- char after ident.
 03400	;   0 -- length after ident scanned into string const
    03500		HRRZ	TBITS,-3(P);use length(id)+5 for string space need
 03600		SUBM	C,TBITS	
   03700		PUSH	P,TBITS	;save id length for remchr update
03800		ADDI	TBITS,5		;WILL MOVE OUT TO AVOID A PROBLEM
    03900	COLNEC:	PUSHJ	P,SGCOL2	;COLLECT IF NECESSARY
   04000	; Developing string constant is now at the end of the current
 04100	;  string space, with room beyond for the identifier scan.
    04200	; P Stack as before, with ident length added to top
 04300		AOS	TOPBYTE(USER)	;IDPB-ILDB GETS INTO LOOP IN DSCAN IF NOT
  04400	;;#WN# JFR 3-24-76 THERE ONCE WAS A BIG HAIRY MACRO THAT NEEDED THIS PATCH.
  04500	;		SEEMS GENERALLY RIGHT, TOO, IN LIGHT OF ABOVE  AOS.  ONLY POSSIBLE
   04600	;		SIDE EFFECT IS STRING GARBAGE COLLECTION MORE OFTEN, BUT WATCHING
    04700	;		CONSOLE LIGHTS INDICATED THAT THIS DID NOT HAPPEN.
    04800		MOVEI	TEMP,5
    04900		ADDM	TEMP,REMCHR(USER)	;KEEP COUNT MORE HONEST
05000	;;#WN# ^
    05100		EXCH	SP,STPSAV	;save string constant state in preparation for
05200		MOVSS	POVTAB+6	; identifier rescan (as identifier)
 05300		PUSH	SP,PNEXTC-1	;Save Scanner input state, and PNAME
   05400		PUSH	SP,PNEXTC	; (string constant) state.
05500		PUSH	SP,PNAME
   05600		PUSH	SP,PNAME+1
 05700		PUSH	SP,PNAME	;Now retrieve (possibly moved) bp to beginning
 05800		PUSH	SP,PNAME+1	; of potential formal name in constant
  05900		PUSH	P,[1]	;PNAME[<before id length> for 1]
   06000		PUSH	P,-5(P)
    06100		JSP	B,SBSTR
06200		POP	SP,TEMP	;resultant bp
 06300		SUB	SP,X11
 06400		MOVSS	POVTAB+6
  06500		EXCH	SP,STPSAV
  06600		ILDB	B,TEMP		;SET UP FOR SCANNER
    06700		MOVEM	TEMP,PNEXTC	;SCAN FROM HERE FOR A WHILE
 06800		MOVE	A,SCNTBL(B)	;GET THE BITS BACK
 06900		TLO	TBITS2,LOKPRM
    07000		TRON	TBITS2,NOLIST	;TURN OFF LISTING FOR RESCAN
    07100		TLO	TBITS2,BACKON	;SAY YOU'VE DONE IT IF STATE CHANGED
  07200		MOVEM	TBITS2,SCNWRD	;UPDATE
    07300	SCNPRM:	PUSHJ	P,DSCAN		;ID SCANNER -- SCAN AND LOOK IT UP
07400		POP	P,TEMP	;fix up REMCHR using saved ident length
 07500		MOVNS	TEMP
 07600		ADDM	TEMP,REMCHR(USER)
    07700		EXCH	SP,STPSAV	;PUT THE SCANNER LOCATION BACK
 07800		POP	SP,PNAME+1	;Restore string constant descriptor
 07900		POP	SP,PNAME
    08000		ADD	SP,X22	;Then use to get one or other pointer back (below)
08100		PUSH	P,[1]	;Whichever SUBSR is called, it will be [x for 1]
  08200	TSTPRM:	SKIPG	LPSA,NEWSYM	;THESE TESTS DETERMINE IF 
08300		 JRST	 NOPAR		; (1) THERE IS A SYMBOL OF THIS NAME
 08400		SKIPGE	TBITS,$TBITS(LPSA)
 08500		 JRST	 NOPAR		; (2) IT IS NOT A RESERVED WORD
 08600		TLNE	TBITS,FORMAL
    08700		TLNN	TBITS,DEFINE
    08800		 JRST	 NOPAR		; (3) IT IS A MACRO PARAMETER NAME
   08900	
  09000		PUSH	P,-4(P)	;We found a param -- retrieve bp to beginning of
09100		JSP	B,SBSTR	; original param name, clear string space to end
 09200		MOVE	TEMP,(SP)	; of space which DSCAN used
    09300		PUSHJ	P,CLREST
  09400		POP	SP,C		;Now replace param name with 177, param #
09500		MOVEI	TEMP,177	;(other word of SUBSR result removed at DN below)
  09600		IDPB	TEMP,C
09700		HRRZ	TEMP,$VAL(LPSA) ;PARAM NUMBER 
 09800		IDPB	TEMP,C
09900		MOVEM	C,TOPBYTE(USER)	;update end of space
    10000		AOS	C,-3(P)	;length before id scan, +2 for param spec,
  10100		AOJA	C,DN		; yields proper current string const. length
 10200	
  10300	NOPAR:
 10400		PUSH	P,-1(P)	;Was not param, retain (apparent) ident in string,
   10500		JSP	B,SBSTR	; by retrieving bp to end of original scan,
 10600		MOVE	TEMP,(SP)	; clearing space to end of DSCAN scan,
   10700		PUSHJ	P,CLREST	; then restoring TOPBYTE to continue macro body
    10800		POP	SP,TOPBYTE(USER)	; scan
    10900		HRRZ	C,(P)	;Restore length after ident scan
   11000	DN:
    11100		TLZE	TBITS2,BACKON	;TURN LISTING BACK ON
 11200		TRZ	TBITS2,NOLIST	;YES
    11300		SUB	P,X11	;Toss end of ident length
 11400		POP	P,B	;ident terminator
 11500		POP	P,A	;bits for that terminator
   11600		SUB	P,X11	;Beginning of ident length
11700		SUB	SP,X11	;count word from whichever subsr was done
    11800		POP	SP,PNEXTC	;Finally, restore Scanner input
 11900		POP	SP,PNEXTC-1
 12000		EXCH	SP,STPSAV	;ONE MORE TIME
  12100		HRRM	C,PNAME		;MAKE SURE COUNT IS REALLY HONEST
    12200	;A AND B ARE THE APPROPRIATE VALUES FOR THE ORIGINAL BREAK CHAR
    12300		TLZ	TBITS2,LOKPRM	;LOOK NO MORE
12400		JRST	MORSTR		;CONTINUE THE SCAN
12500	
  12600	CLREST:
12700	;;#WM# JFR 3-22-76 440700 BYTE POINTERS (STRNGC) CAUSE PROBLEMS
    12800		SKIPLE	C,TOPBYTE(USER)	;BAD GUY?
    12900		 JRST	CLRES1		;NO
    13000		MOVEI	C,-1(C)		;MAKE HIM A GOOD GUY
 13100		HRLI	C,010700
   13200		MOVEM	C,TOPBYTE(USER)
13300	CLRES1:
13400	;;#WM# ^
    13500		MOVEI	C,0		; BP OF START OF ID IN TEMP
   13600	LINLUP:	CAMN	TEMP,TOPBYTE(USER) ;clear space from temp's bp to
13700		POPJ	P,		;current top
13800		IDPB	C,TEMP
13900		JRST	LINLUP
14000	
  14100	
  14200	SBSTR:	AOS	(P)		;ADAPT TO SAIL CONVENTIONS
14300		MOVE	C,LPSA		;SAVE
   14400	EXTERN	SUBSR
14500		PUSHJ	P,SUBSR
   14600		MOVE	LPSA,C		;RESTORE
14700		MOVE	USER,GOGTAB
14800		JRST	(B)
   14900	
  15000	Comment 
   15100	End of string constant -- set up results for stacking,
   15200		go do it   
    15300	
  15400	ENDSTR:
15500		MOVEM	TBITS2,SCNWRD	;PUT ALL THE BITS AWAY
    15600		LSTDPB			;PUT "," OR ")" AWAY
  15700		TLZ	FF,PRMXXX
   15800		CAIE	B,12		;LF IS SPECIAL PROBLEM!
  15900		MOVEM	B,SAVCHR	;SAVE BITS FOR NEXT TIME
  16000		MOVEM	B,LSTCHR	;ALSO HERE ANY TIME
  16100		SKIPN	SWCPRS		; SWITCHING PARSERS OK?  
  16200		JRST	NOSWCH		; NO, 
  16300	;; #QV (1 OF 2) WILL NOW USE ENDMAC TO ADD 177-0 TO ASSIGNC BODIES
 16400		TLNE	FF,PRMSCN	; SCANNING ACTUALS? 
 16500		JRST	ENDACT		; YES, APPEND 1770 TO MACRO ACTUALS 
 16600		JRST	NOMACW		; NO, 
  16700	;; #QV#
16800	NOSWCH:	SKIPN	IFCREC		; EXPAND MACROS IN FALSE PART OF COND COMP? 
 16900		TLNN	FF,PRMSCN	; YES, SCANNING MACRO ACTUALS? 
17000		JRST	[PUSHJ P,UPDCNT	; KEEP REMCHR HONEST 
    17100			 JRST	STCTYP]	; DON'T ENTER STRING 
17200	ENDACT: ADDI	C,2		; FOR ACTUAL PARAMETERS APPEND 177-0 TO END OF 
  17300		MOVEI	TEMP,177	;  STRING, GET A SEMBLK AND PLACE IT ONLY ON 
 17400		IDPB	TEMP,TOPBYTE(USER) ;  THE STRING RING.  ALL ACTUAL PARAMETERS TO 
 17500		MOVEI	TEMP,0		;  A MACRO ARE LINKED ON THE VARB RING.  THUS WHEN 
 17600		IDPB	TEMP,TOPBYTE(USER) ;  A MACRO CALL IS FINISHED ALL THAT REMAINS TO 
    17700		PUSHJ	P,UPDCNT	;  DO IS TO KILLST ALONG THE VARB RING WHOSE HEAD 
 17800		GETBLK	NEWSYM		;  IS POINTED TO BY DEFRNG.  
  17900		HRROI	TEMP,PNAME+1	;
 18000		POP	TEMP,$PNAME+1(LPSA) ;
 18100		POP	TEMP,$PNAME(LPSA) ;
   18200		MOVE	TEMP,[XWD CNST,STRING] ; MAKE SEMBLK OF ACTUAL PARAMETER LOOK LIKE 
    18300		MOVEM	TEMP,$TBITS(LPSA) ;  A STRING CONSTANT SEMBLK EXCEPT FOR THE FACT 
    18400		PUSHJ	P,RNGSTR	;  THAT IT IS NOT LINKED ON THE STRING CONSTANT RING
    18500	;; #QV (2 OF 2) ! REMOVED TEST ON ASGFLG HERE
  18600		PUSHJ	P,RNGVRB	;
18700		MOVE	LPSA,NEWSYM	;
   18800		MOVE	A,%STCON	;
 18900		JRST	STACK		;
   19000	NOMACW:	PUSHJ	P,UPDCNT	; UPDATE PNAME CNT, REMCHR, COLLECT IF NECESSARY
 19100		PUSH	P,BITS		;
  19200		PUSHJ	P,STRINS	; CHECK IF STRING HAS ALREADY BEEN ENTERED IN THE 
 19300		POP	P,BITS		;  SYMBOL TABLE AND IF NOT THEN ENTER IT
    19400		MOVE	LPSA,PNT	;
 19500		MOVEM	LPSA,NEWSYM	;
  19600	STCTYP:	MOVE	A,%STCON	;
    19700		JRST	STACK		;
   19800	
          00100	DSCR SCNUMB -- number scanner
   00200	DES Scan a number -- keep both REAL (floating) and fixed
 00300	  representations around, use the appropriate one at the end.
 00400	 A number is composed of integers and various special characters.
  00500	 See the syntax for a better definition, but here is a summary:
    00600	
  00700			<int><.<int>><@<+|->int>
 00800	
  00900	 Common sense should indicate that some of these things must
  01000	  be present to constitute a legal number. The results
   01100	  are returned as described on the opening page of SCAN.
 01200	
 01300	
  01400	SCNUMB:
01500	
  01600	; @ CHARACTER TO BE TREATED AS DELIMITER IF INSIDE START!CODE
 01700	;  BLOCK
    01800	
  01900		TLNN	A,ATSIGN	; AT SIGN? 
 02000	;;#YA# ! (1/2) JFR 1-3-77 CLEAR FLAGS FOR SAFETY
    02100		JRST	2,@[SCNM1]	; NO, GET REST OF NUMBER 
02200		SKIPN	SWCPRS		; YES, IN FALSE PART OF CONDITIONAL COMPILATION? 
   02300		JRST	ATOUT		; YES, TREAT AT SIGN AS A PARSE TOKEN 
 02400		TLNN	TBITS2,INLIN	; NO, IN-LINE CODE? 
   02500	;;#YA# ! (2/2)
   02600		JRST	2,@[SCNM1]	; NO, GET REST OF NUMBER 
02700	
  02800	ATOUT:	MOVE	A,%ATS		;GET BITS FOR AT SIGN DELIMITER
 02900		JRST	CHAROUT		;HANDLE AS DELIMITER
  03000	
  03100	SCNM1:
 03200		SETZB	C,SCNVAL	;DIGITS CTR, VALUE
   03300		SETZB	SBITS2,DBLVAL	;FLAGS, LOW HALF OF LONG VALUE
 03400		TLNN	A,QUOCTE	;OCTAL QUOTE MARK (') ?
    03500		 JRST	 DECIM		;NO, DECIMAL NUMBER
   03600	
  03700		SETZB	LPSA,LPSA+1	;ACCUMULATE HERE
  03800	OCTL:	ILDB	B,PNEXTC	;GET BACK IN SYNCH
    03900		SKIPGE	A,SCNTBL(B)
   04000		PUSHJ	P,(A)		;USUAL SPECIAL TREATMENT
    04100		LSTDPB
04200		MOVE	LPSA,SCNVAL
04300		MOVE	LPSA+1,DBLVAL
   04400		TLNE	A,DIG
 04500		 JRST	OCTL1
04600		JUMPE	LPSA,ENDNUM	;SINGLE PRECISION INTEGER
   04700		IORI	SBITS2,DBLPRC	;LONG INTEGER
    04800		JRST	ENDNUM
04900	OCTL1:	LSHC	LPSA,3
    05000		ADDI	LPSA+1,-"0"(A)
  05100		JOV	[ADDI	LPSA,1	;IN CASE SOME JOKER SAYS '777777777778
 05200			JOV	.+1	;TOP PART COULD OVERFLOW, TOO
   05300			JRST	.+1]
 05400		MOVEM	LPSA,SCNVAL
    05500		MOVEM	LPSA+1,DBLVAL
  05600		AOJA	C,OCTL		;COUNT DIGITS TO DETECT LONE '
   05700	
  05800	DECIM:
 05900		PUSHJ	P,GETINT	;CLEAR COUNT, GET INTEGER
 06000		TLNN	A,LETDG		;PART OF NUMBER?
 06100		 JRST	ENDNMZ		;NO
    06200	;;#XZ# JFR 1-3-77 GET EXPONENT/TERMINATION CONDITIONS STRAIGHT
06300		IORI	SBITS2,FLOTNG	;MUST BE REAL
    06400	;;#ZD# MWK 4-13-77 FIX TO PREVENT C CLOBBERAGE
 06500	;	TLNN	A,DOT		;DECIMAL POINT?
   06600	;	 SETZ	C,		;NO. NO DIGITS AFTER DECIMAL PT.
   06700	;;#ZD#
 06800		PUSH	P,C		;SAVE DIGIT COUNTS
   06900		TLNE	A,DOT
 07000		 PUSHJ	P,TZ		;TRY FOR MORE INTEGER
  07100		HLRZ	D,C		;# TRAILING ZEROES
   07200		SUBI	D,(C)		;-(# DIGITS WHICH ARE NOT TRAILING ZEROES)
  07300		ADDM	D,(P)		;RH (P) = AMOUNT TO ADD TO EXPONENT
    07400		PUSH	P,SCNVAL	;SAVE FRACTION VALUE
  07500		PUSH	P,DBLVAL
   07600		SETZM	SCNVAL		;INITIAL EXPONENT VALUE
    07700		SETZB	C,DBLVAL
  07800		TLNN	A,LETDG
    07900		 JRST	FIXAT1		;END OF REAL NUMBER
   08000		TLNN	A,DOT		;MUST BE "." OR "@"
08100		TLNE	A,ATSIGN
   08200		 JRST	.+2
  08300		ERR	<ILLEGAL REAL CONSTANT>,1
  08400	;;#XZ# ^
    08500	NODOT1:	ILDB	B,PNEXTC
 08600		SKIPGE	A,SCNTBL(B)
   08700		PUSHJ	P,(A)
08800		LSTDPB
08900		TLNN	A,ATSIGN	;SECOND "@"
 09000		 JRST	NODOT2		;NO
    09100		IORI	SBITS2,DBLPRC	;YES, LONG PRECISION
  09200		JRST	NODOT1
09300	NODOT2:	PUSH	P,[FIXAT]
09400		CAIN	B,"-"		;MINUS?
  09500		 TLOA	 SBITS2,EXPNEG	; YES, EXPONENT NEGATIVE
 09600		CAIN	B,"+"		;NO, PLUS?
    09700		 JRST	 LGETINT	; PLUS OR MINUS, GET DIGIT
09800		 JRST	 GETINT		; HAVE DIGIT, GO GET NUMBER
    09900	FIXAT:	PUSHJ	P,TZMUL
  10000	FIXAT1:	SKIPN	(P)		;IS RESULT ZERO?
  10100		SKIPE	-1(P)
10200		 JRST	.+3		;NO
  10300		SUB	P,X33		;YES, REMOVE 2 VALUE WORDS AND DIGIT CTR WORD
10400		JRST	RETZER		;AND MAKE LIFE SIMPLE
  10500		SKIPE	SCNVAL		;IF THIS IS NOT ZERO
  10600		 JRST	EXPER3		;THEN WE HAVE A WHOPPING BIG EXPONENT
10700		TLZN	SBITS2,EXPNEG	;NEGATIVE EXPONENT?
   10800		SKIPA	D,DBLVAL	;NO
   10900		MOVN	D,DBLVAL	;YES
   11000		POP	P,DBLVAL	;RETRIEVE MANTISSA
11100		POP	P,SCNVAL
    11200		ADD	D,(P)
  11300		HRREI	D,(D)		;EXPONENT OF 10
   11400		SUB	P,X11		;DONE WITH FORMER DIGIT CTR WORD
   11500		MOVE	LPSA,SCNVAL	;BEGIN CONVERTING MANTISSA TO PURE FRACTION
 11600		JFFO	LPSA,DFSC
  11700		MOVE	LPSA,DBLVAL	;HIGH ORDER WORD WAS ALL ZERO
11800		JFFO	LPSA,.+1
   11900		ADDI	LPSA+1,=35	;HIGH WORD WAS ALL ZERO
  12000	DFSC:	MOVEI	C,-1(LPSA+1)	;# OF PLACES TO SHIFT (REMEMBER SIGN BIT)
 12100		MOVE	LPSA,SCNVAL	;GET MANTISSA
 12200		MOVE	LPSA+1,DBLVAL
   12300		ASHC	LPSA,(C)	;MAKE MANTISSA INTO PURE FRACTION
    12400		SUBI	C,=70
 12500		MOVN	C,C		;C=EXPONENT OF 2 OF MANTISSA
   12600		JUMPE	D,DFSC2		;EXPONENT OF 10 WAS ZERO
  12700		PUSH	P,A		;SAVE BITS
 12800		MOVE	A,[EXP.P1,,FR.P1]	;ASSUME EXPONENT OF 10 IS POSITIVE
    12900		JUMPG	D,DFSCA
   13000		TLO	SBITS2,EXPNEG	;EXPONENT WAS NEG
 13100		MOVN	D,D
   13200		MOVE	A,[EXP.M1,,FR.M1]	;MULT BY NEG PWRS OF 10
13300	DFSCA:	MOVEM	LPSA,SCNVAL
   13400		MOVEM	LPSA+1,DBLVAL
  13500		TRNE	D,777700	;CHECK MAGNITUDE OF EXP OF 10
   13600		 JRST	EXPERR		;EXPONENT IS TOO BIG
  13700		TRNE	D,40		;E+-32 INVOLVED?
    13800		TLNE	SBITS2,EXPNEG	;EXPONENT NEGATIVE?
   13900		JRST	MULOOP		;NO
14000		TRNE	D,20		;OUT OF RANGE IF E-48
    14100		 JRST	EXPERR		;BAD
   14200	MULOOP:	TRZE	D,1		;SHOULD WE MULTIPLY?
    14300		 PUSHJ	P,DMUL..		;YES
14400		JUMPE	D,DFSC1		;QUIT IF EXPONENT NOW ZERO
14500		ASH	D,-1		;NEXT BIT INTO POSITION
   14600		AOBJN	A,.+1		;ADD 1 TO LH
 14700		AOJA	A,MULOOP	;AND 2 TO RH
14800	
  14900	;MULTIPLY TWO DOUBLE-LENGTH PURE FRACTIONS. ONE IS (A), OTHER IS SCNVAL, DBLVAL PAIR
   15000	;RETURN DOUBLE-LENGTH RESULT IN SCNVAL, DBLVAL
 15100	;SCALE FACTOR KEPT IN C
    15200	DMUL..:
15300	NOKL10<	PUSH	P,SCNVAL	;SAVE HIGH
15400		SETZM	SCNVAL		;1ST WORD, FINAL PRODUCT
   15500		MOVE	LPSA,(A)	;HIGH
  15600		MULM	LPSA,DBLVAL	;* LOW
   15700					;IGNORING 3RD WORDS: 8 EXPONENT BITS TO BURN
    15800		MOVE	LPSA,1(A)	;LOW
  15900		MUL	LPSA,(P)	;* HIGH
 16000		TLO	LPSA,400000	;PREVENT OVERFLOWS
  16100		ADD	LPSA,DBLVAL	;ADD 2ND WORDS
 16200		TLZN	LPSA,400000	;WOULD THERE HAVE BEEN AN OVERFLOW?
    16300		 AOS	SCNVAL		;YES, DO CARRY (SETS SCNVAL TO 1)
16400		MOVEM	LPSA,DBLVAL	;STORE LOW RESULT
 16500		POP	P,LPSA		;HIGH
    16600		MUL	LPSA,(A)	;* HIGH
 16700		TLO	LPSA+1,400000	;PREVENT OVERFLOW
 16800		ADD	LPSA+1,DBLVAL	;COLLECT 2ND WORD
 16900		TLZN	LPSA+1,400000	;WOULD THERE HAVE BEEN AN OVERFLOW?
  17000		 ADDI	LPSA,1		;YES
   17100		ADD	LPSA,SCNVAL	;COLLECT 1ST WORD (THIS CAN'T OVERFLOW)
 17200	>;NOKL10
    17300	KL10<
  17400		DMOVE	LPSA,SCNVAL
    17500		DMOVEM	LPSA+2,SCNVAL
 17600		DMUL	LPSA,(A)
   17700		JOV	[TLO	SBITS2,INTOV
17800			JRST	.+1]
 17900		DMOVE	LPSA+2,SCNVAL
  18000	>;KL10
 18100		TLNE	LPSA,(1B1)	;NORMALIZED FRACTION?
    18200		 JRST	.+3		;YES
 18300		ASHC	LPSA,1		;NO, SHIFT OVER
   18400		SUBI	C,1		;AND ADJUST EXPONENT
 18500		MOVS	A,A		;COLLECT EXPONENT CHANGES
 18600		ADD	C,(A)
  18700		MOVS	A,A
   18800		MOVEM	LPSA,SCNVAL	;STORE RESULT SO FAR
   18900		MOVEM	LPSA+1,DBLVAL
  19000		POPJ	P,
    19100	
  19200	DFSC1:	POP	P,A		;GET BITS BACK
  19300		MOVE	LPSA,SCNVAL	;GET VALUE
    19400		MOVE	LPSA+1,DBLVAL
   19500		TRNN	LPSA+1,400	;ROUND?
   19600		 JRST	DFSC2		;NO
19700		TLO	LPSA,400000	;PREVENT
  19800		TLO	LPSA+1,400000	; OVERFLOWS
  19900		ADDI	LPSA+1,400	;YES
 20000		TLZN	LPSA+1,400000	;WOULD THERE HAVE BEEN AN OVERFLOW?
  20100		 ADDI	LPSA,1		;YES
   20200		TLZE	LPSA,400000
20300		 JRST	DFSC2		;NO OVERFLOW
 20400		MOVSI	LPSA,200000	;HIGH WD EXACTLY .1 (BASE 2)
20500		ADDI	C,1		;EXPONENT HAS INCREASED
   20600		LSH	LPSA+1,-1	;KEEP LOW WD ALIGNED PROPERLY
   20700	DFSC2:	ASHC	LPSA,-8		;MAKE ROOM FOR EXPONENT
   20800		FSC	LPSA,200(C)	;AND INSERT IT
 20900		JFOV	EXPERR
21000		JRST	ENDNUM		;FINALLY DONE (EXCEPT TEST OVERFLOW FLAGS)
 21100	
  21200	EXPER3:	SUB	P,X33
21300	EXPERR:	ERR	<EXPONENT RANGE EXCEEDED>,1
   21400		HRLOI	LPSA,377777	;SET UP AN INFINITY
    21500		MOVE	LPSA+1,LPSA
21600		TLNE	SBITS2,EXPNEG
   21700	RETZER:	 SETZB	LPSA,LPSA+1	;BUT USE ZERO IF EXPONENT WAS NEG
  21800		JRST	ENDNUM
21900	
  22000	ENDNMZ:	PUSHJ	P,TZMUL		;TRAILING ZEROES NOW SIGNIF.
 22100		MOVE	LPSA,SCNVAL
22200		MOVE	LPSA+1,DBLVAL
   22300	ENDNUM:	CAIE	B,12		;EXCEPT FOR LINE FEED,
 22400		MOVEM	B,SAVCHR	;SAVE FOR NEXT SCAN
  22500		MOVEM	B,LSTCHR	;ALSO HERE ANY TIME
  22600		TLNE	A,LETDG 	;MUST NOT BE LEETTER OR DIG OR
  22700		 ERR	 <ILLEGAL CONSTANT>,1
22800		TRNN	SBITS2,FLOTNG	;REAL OR INTEGER?
22900		 JRST	 INTEG
    23000		TRNN	SBITS2,DBLPRC
   23100		 SNGL	LPSA,LPSA	;ONLY SINGLE ASKED FOR
   23200		JRST	NUMRET
23300		
 23400	INTEG:	SKIPN	C		;MAKE SURE THERE WAS SOMETHING
 23500		 ERR	 <ILLEGAL INTEGER CONSTANT>,1
  23600		TLNE	SBITS2,INTOV	;INTEGER OVERFLOW?
23700		 ERR	 <INTEGER CONSTANT TOO LARGE>,1
23800		TRO	SBITS2,INTEGR	;MARK TYPE
   23900	NUMRET:	SKIPN	SWCPRS		; INSIDE FALSE PART OF CONDITIONAL COMPILATION? 
  24000		JRST	NUMTYP		; YES, DON'T ENTER THE NUMBER 
   24100		HRLI	SBITS2,CNST	; MAKE INTO TBITS WORD
  24200		PUSH	P,BITS		;DON'T EFFECT OUTSIDE WORLD
 24300		MOVEM	SBITS2,BITS		;SET UP FOR ENTER
24400		JUMPN	LPSA,.+2
  24500		EXCH	LPSA,LPSA+1	;SINGLE PRECISION INTEGER ONLY
    24600		MOVEM	LPSA,SCNVAL
    24700		MOVEM	LPSA+1,DBLVAL
  24800		PUSHJ	P,NHASH		;LOOK UP THE NUMBER
  24900		SKIPG	NEWSYM		;WAS IT THERE ALREADY?
25000		PUSHJ	 P,ENTERS	; NO, BUT IT IS NOW
 25100		POP	P,BITS		;GET OLD BITS BACK
 25200		MOVE	LPSA,NEWSYM	;SET UP FOR STACKING
    25300	NUMTYP:	MOVE	A,%NUMCON
25400		JRST	STACK		;GO DO IT
25500	
          00100	Comment 
   00200	Get an integer (base 10 only for the present).
 00300	C has	# trailing zeroes ,, # digits
  00400	
 00500	LGETINT:		;GET A CHARACTER FIRST
00600		ILDB	B,PNEXTC
   00700	MGETINT:		;GET BITS FIRST
  00800		SKIPGE	A,SCNTBL(B)
   00900		PUSHJ	P,(A)	;SIGH!
   01000		LSTDPB
01100	
  01200	GETINT:	JOV	.+1	;GET AN INTEGER
 01300		TDZA	C,C		;SET # DECIMAL PLACES TO 0
01400	
  01500		ML$CHR			;PUT AWAY
   01600	GETLUP:	TLNN	A,DIG		;IS IT A DIG?
    01700		 POPJ	  P,		; NO, RETURN
  01800		CAIN	B,"0"
 01900		AOBJP	C,TZ		;A TRAILING ZERO
   02000		TLNN	C,-1		;HAVE DIGIT. WERE THERE TRAILING ZEROES BEFORE IT?
02100		 AOJA	C,NOTZ		;NO. COUNT DIGIT AND LEAVE
 02200		ADDI	C,1		;YES. COUNT DIGIT ANYWAY
  02300		PUSHJ	P,TZMUL		;TRAILING ZEROES NOW SIGNIF.
   02400	NOTZ:	PUSHJ	P,M10ADA	;MULTIPLY BY 10 AND ADD A
 02500	TZ:	ILDB	B,PNEXTC	; GET ANOTHER
 02600		SKIPGE	A,SCNTBL(B)	;COULD IT STILL BE A DIGIT?
02700		PUSHJ	P,(A)
02800		JRST	GETLUP-1(TBITS2);LOOP
02900	
  03000	TZMUL:	HLRZ	D,C		;# TRAILING ZEROES
  03100		JUMPE	D,TZMUL1	;QUIT IF NONE
   03200		CAIN	D,(C)
 03300		 JRST	TZMUL1		;TRAILERS WERE ALSO LEADERS!
    03400		PUSH	P,A
   03500		MOVEI	A,"0"
03600		PUSHJ	P,M10ADA	;ADJUST VALUE TO ACCOUNT FOR TRAILING ZEROES
  03700		SOJG	D,.-1
 03800		POP	P,A
    03900	TZMUL1:	TLZ	C,-1		;NO TRAILING ZEROES NOW
 04000		POPJ	P,
    04100	
  04200	M10ADA:
04300	NOKL10<	SKIPN	LPSA,SCNVAL	;ANY HIGH ORDER PART?
04400		 JRST	M10A.1		;NO
    04500		IMULI	LPSA,=10	;YES
  04600		JOV	[TLO	SBITS2,INTOV
04700			JRST	.+1]
 04800		MOVEM	LPSA,SCNVAL
    04900	M10A.1:	MOVE	LPSA,DBLVAL	;LOW HALF
   05000		MULI	LPSA,=10
   05100		TLO	LPSA+1,400000	;PREVENT OVERFLOW
 05200		ADDI	LPSA+1,-"0"(A)	;ADD THE NEW DIGIT
   05300		TLZN	LPSA+1,400000	;WOULD THERE HAVE BEEN AN OVERFLOW?
  05400		 ADDI	LPSA,1		;YES. (THIS CAN'T OVERFLOW; LPSA WAS AT MOST =9)
    05500		MOVEM	LPSA+1,DBLVAL	;SAVE LOW HALF
  05600		TLO	LPSA,400000
 05700		ADD	LPSA,SCNVAL	;TAKE CARE OF HIGH HALF
  05800		TLZN	LPSA,400000
05900		 TLO	SBITS2,INTOV
    06000		MOVEM	LPSA,SCNVAL	;SAVE HIGH HALF
   06100	>;NOKL10
    06200	KL10<
  06300		DMOVE	LPSA,SCNVAL	;FETCH ONE VALUE
  06400		DMOVEM	LPSA+2,SCNVAL	;SAVE 2 REGS CLOBBERED BY DMUL
06500		DMUL	LPSA,[0  =10]	;RESULT SHOULD BE IN LPSA+3,+4
 06600		JOV	[TLO	SBITS2,INTOV
06700			JRST	.+1]
 06800		JUMPN	LPSA,.+2
  06900		JUMPE	LPSA+1,.+2
07000		TLO	SBITS2,INTOV	;BUT IT MIGHT HAVE OVERFLOWED
07100		MOVEI	LPSA+1,-"0"(A)	;CONSTRUCT VALUE TO ADD. LPSA HAS 0 ALREADY
  07200		DADD	LPSA,LPSA+2	;ADD
07300		JOV	[TLO	SBITS2,INTOV
07400			JRST	.+1]
 07500		DMOVE	LPSA+2,SCNVAL	;RESTORE 2 REGS
 07600		DMOVEM	LPSA,SCNVAL
   07700	>;KL10
 07800		POPJ	P,
    07900	
  08000	FR.P1:	240000,,0	;10^1		PURE FRACTION PART
08100		0
08200		310000,,0	;10^2
 08300		0
08400		234200,,0	;10^4
 08500		0
08600		276570,,200000	;10^8
 08700		0
08800		216067,,446770	;10^16
08900		040000,,0
  09000		235613,,266501	;10^32
09100		133413,,263574
  09200	EXP.P1:	4				;POWER OF 2 EXPONENT PART
    09300		7
09400		16
    09500		33
    09600		66
    09700		153
   09800	
  09900	FR.M1:	314631,,463146	;10^-1
    10000		146314,,631463
  10100		243656,,050753	;10^-2
10200		205075,,314217
  10300		321556,,135307	;10^-4
10400		020626,,245364
  10500		253630,,734214	;10^-8
10600		043034,,737425
  10700		346453,,122766	;10^-16
    10800		042336,,053314
  10900		317542,,172552	;10^-32
    11000		051631,,227215
  11100	EXP.M1:	-3
  11200		-6
    11300		-15
   11400		-32
   11500		-65
   11600		-152
          00100	Comment  Print the last character, then stack the result
00200	
 00300	
  00400	LSTACK:	LSTDPB
   00500		JRST	STACK
 00600	
  00700	Comment  We have been backed up by the wonderful error routines
   00800	in the parser.  So now we return things to their normal states:
    00900	
 01000	
  01100	GOAGAIN: MOVE	LPSA,SAVSEM
  01200		SKIPA	A,SAVPAR
  01300	
  01400	DSCR CHAROUT -- returns value for single char operator.
  01500	DES No Semantic stack entry is necessary (a null pointer
 01600	  is stacked). The indirect, address, and index fields
   01700	  of the character comprise its PL-ID. 
   01800	
 01900	
  02000	CHAROUT:
    02100		MOVEI	LPSA,0		;SEMANTICS RETURNED ARE NULL
    02200	
  02300	DSCR STACK  
02400	DES All SCANNER sub-sections return here to place Parse
  02500	  token on parse stack (PPDL) and Semantics on EXEC stack
02600	  (GPDL). STACK is bypassed only by the string constant
  02700	  scanner when calling SCANNER recursively to modify for-
02800	  mal parameters.
02900	
 03000	STACK:	HRRZS	LPSA		;MAKE SURE ONLY RH
03100		TLZ	A,777740	;CLEAR SCANNER BITS
    03200		PUSH	SP,A		;PL ENTRY
 03300		EXCH	SP,GPSAV	;GET GP POINTER
  03400		PUSH	SP,LPSA		;SEMANTIC ENTRY
  03500		EXCH	SP,GPSAV	;PUT AWAY SEMANTIC POINTER
 03600		MOVEM	SP,PPSAV	;PUT AWAY PARSE POINTER
   03700		SKIPN	CNDLST		; IN FALSE PART OF COND. COMP.? 
03800		POPJ	P,		; NO, RETURN 
    03900		MOVE	SBITS2,LPTRSV	; YES, DO NOT LIST - I.E. RESTORE LPNT 
   04000		ML$BAK
04100		POPJ	P,
    04200	
  04300	DSCR INSET
  04400	DES prepare for ID or STRING constant scan
04500	RES sets up TOPBYTE, REMCHR, PNAME, TOPSTR, C (char count)
    04600	SID Uses TEMP
    04700	
 04800	^^INSET: MOVEI	C,0		;CLEAR CHARACTER COUNT
04900	;;#GI# DCS 2-5-72 REMOVE TOPSTR
 05000		MOVSI	TEMP,40		; MOST HARMLESS CONST BIT
05100	;;#GI
  05200		MOVEM	TEMP,PNAME	;FIRST PNAME DESCRIPTOR WORD
 05300		HLL	TEMP,TOPBYTE(USER)	;ADJUST REMCHR FOR
05400		HRRI	TEMP,[BYTE (7) 0,4,3,2,1,0] ;CHARACTERS SKIPPED
    05500		ILDB	TEMP,TEMP
  05600		ADDM	TEMP,REMCHR(USER)	;UPDATE REMCHR
    05700	
  05800		SKIPL	TEMP,TOPBYTE(USER)	;ADJUST TOPBYTE TO
   05900		ADDI	TEMP,1		; WORD BDRY (440700 OK ALREADY)
  06000		HRLI	TEMP,440700	;[POINT 7,WORD]
    06100		MOVEM	TEMP,PNAME+1	;BP FOR THIS STRING
   06200		MOVEM	TEMP,TOPBYTE(USER)	;ADJUSTED TOPBYTE
    06300			;NOW GC CAN GO AHEAD AND HAPPEN
    06400		POPJ	P,		;ALL SET
    06500	SUBTTL	SCANNER I/O, MACRO EXPANSION
  06600	
          00100	DSCR CSPEC, SEOL, SEOM, SEOB -- Special handling routines
00200	PAR A contains address of appropriate routine.  Many SCANNER
  00300	  state variables are perused and changed.
00400	RES PNEXTC, SAVCHR, and friends are set to proper values after
00500	  more file has been read, macro has been returned from, etc.
 00600	DES Called by SCANNER routines when an input char is detected
 00700	  whose SCNTBL entry indicates special conditions.  The routine
    00800	  address is in the right half of this SCNTBL word.
 00900	 CSPEC is sometimes called to save the char count (C) before dis-
  01000	  patching to the special routine (for STRINGC integrity)
01100	 SEOL is called when the SCANNER is reading from the input file
    01200	   or a macro and an end of of line condition is detected.  A
 01300	   new line is found and the PNEXTC pointer is reinitialized.
 01400	 EOM is called when the SCANNER is reading a DEFINE body, and end
  01500	   of text (177 char) is seen. If the character following the EOT
  01600	   is non-zero, it indicates the right actual parameter to expand
  01700	   here.  If it is 0, it signals end of macro. Old input values are
01800	   restored, things like PNEXTC and SAVCHR.
    01900	 SEOB is called when a 0 is detected while scanning. This can mean
 02000	  two things -- a TECO-type file is being read, and a buffer has
   02100	  ended in the middle of a line, or the string scanner has called
  02200	  SCANNER recursively to pick up a possible formal param.  In either
    02300	  case the right thing happens.
 02400	SEE ADVBUF routine, which these call for for file input
  02500	
 02600	ZERODATA (SCANNER INPUT/OUTPUT VARIABLES)
 02700	;LINNUM -- physical line number of this output line.  Used
    02800	;    to force page ejects and new sub-numbering when too
 02900	;    many have gone out since last logical page encountered
   03000	?LINNUM: 0
  03100	
  03200	?LNCREF: 0	;IF ON, CREF INFO HAS GONE OUT FOR THIS LINE
  03300	
  03400	COMMENT 
   03500	LPNT -- byte pointer used to deposit characters in output
03600	    buffer (LSTBUF) -- SEOL code transfers this data, along
   03700	    with CREF data, to the output file buffers.  IDPB B,LPNT
  03800	    instructions are scattered throughout the SCANNER to build
03900	    this output file
  04000	
 04100	^^LPNT: 0
   04200	
  04300	^^LSTBUF: 0	;ADDRESS OF LISTING BUFFER
    04400	
  04500	;LSTCHR -- saved scan-ahead character -- sometimes slightly different
   04600	;   from SAVCHR -- used for error message (the arrow) output
  04700	^^LSTCHR: 0
 04800	ENDDATA
04900	
          00100	SUBTTL	Cspec, Seol
    00200	
  00300	
          00100	; CALL SPECIAL ROUTINE, BUT FIRST MAKE SURE CHARACTER COUNT IS
00200	;  CORRECT IN "PNAME" (THE DESCRIPTOR FOR THE CURRENTLY DEVELOPING
 00300	;  IDENTIFIER OR STRING)
   00400	
  00500	CSPEC:	HRRM	C,PNAME		;UPDATE CHAR COUNT
   00600		JRST	(A)		;DISPATCH TO SPECIFIED ROUTINE
 00700	
  00800	SEOL:	
 00900		PUSH	P,C		;SAVE CHARACTER COUNT (CLOBBERED BY HDROV)
    01000		TRNE	TBITS2,NOLIST	;ARE WE LISTING NOW?
  01100		 JRST	 NOLST		; NO
   01200	
  01300	ifn 0,<;;JFR 12-11-76 causes Address check for device DSK on PASS1.SAI[PUB,SYS]
   01400	;; \UR#5\ BETTER LISTING FOR CONDITIONAL COMPILATION
01500		SKIPE	CNDLST			;SUPPRESSING LISTING?
01600		JRST	[ MOVE SBITS2,LPTRSV
 01700			  ML$BAK
  01800			 JRST  NOLST ]
 01900	;; \UR#5\
   02000	>;ifn 0,
    02100	
  02200	; TIME TO DO A LISTING
02300	
  02400		MOVE	TBITS,LPNT	;PUT THE LINE FEED IN LIST BUFFER
  02500	LLL2:	IDPB	B,TBITS
    02600		MOVEI	B,0		;ZERO REMAINING CHARS OF CURRENT WORD
   02700		TLNE	TBITS,760000	;ALL DONE?
   02800		JRST	LLL2		;NO, PUT OUT ZERO
   02900		MOVEM	TBITS,LPNT	;SAVE AGAIN FOR A WHILE
 03000	
  03100	;IF CREFING WAS DONE ON THIS LINE, TERMINATE THE CREF STUFF
   03200		SKIPN	LNCREF		;CREF GONE OUT?
  03300		 JRST	 NOLNX		;NOPE
  03400		SETZM	LNCREF		;RESET.
03500		MOVEI	TBITS,177	;DELETE
   03600		PUSHJ	P,CHROUT
  03700		MOVEI	TBITS,"A"	;AND AN A
 03800		PUSHJ	P,CHROUT
  03900	NOLNX:
 04000	
  04100	; IF PCNT OUTPUT DESIRED, DO THAT FIRST
   04200	
  04300		TLNN	TBITS2,PCOUT	;WANT TO PRINT PC?
04400		 JRST	 NOPC		; NO
    04500	
  04600		MOVE	TBITS,PCNT	;YET ANOTHER FRNP
   04700		ADD	TBITS,LSTSTRT	;OFFSET BY USER-PROVIDED LOC
04800		MOVEI	B,CHROUT	;ROUTINE TO USE
 04900		MOVEI	PNT2,6		;ALWAYS DO 6 CHARS
    05000	BAIL<
  05100		SKIPN	BAILON
    05200		 JRST	.+4		;NO BAIL
  05300		HRRZ	TBITS,BCORDN	;IF DEBUGGER IN USE, PRINT COORDINATE INSTEAD
   05400		PUSHJ	P,FRNPD		;IN DECIMAL
05500		JRST	.+2		;AND SKIP OVER PC PRINTER
 05600	>;BAIL
 05700		PUSHJ	P,[
  05800	^FRNP1:	SKIPA	TEMP,[10]
    05900	^FRNPD:	MOVEI	TEMP,=10
06000	FRNP3:	IDIV	TBITS,TEMP
06100		IORI	SBITS,"0"
  06200		HRLM	SBITS,(P)
  06300		SOJE	PNT2,FRNP2
 06400		PUSHJ	P,FRNP3
   06500	FRNP2:	HLRZ	TBITS,(P)
 06600		JRST	(B)		;CHARACTER TO OUTPUT
 06700	]
 06800		MOVE	SBITS,[POINT 7,[ASCII /   /]]
  06900		PUSHJ	P,LL1+1		;SEE BELOW
 07000	
  07100	; IF LINE NUMBER OUTPUT DESIRED, DO IT NEXT.
   07200	
  07300	NOPC:	MOVE	SBITS,[POINT 7,ASCLIN] ;ASSUME WANT LINE NUMBER
    07400		TLNE	TBITS2,LINESO	;IS IT THE CASE
  07500		PUSHJ	P,[LL1: PUSHJ P,CHROUT ;CHARACTER TO OUTPUT
  07600			      ILDB  TBITS,SBITS ;NEXT CHAR
 07700			      JUMPN TBITS,LL1
    07800			      POPJ   P,]+1	;KLUDGE........
 07900	
  08000	; NEXT LINE UP THE BP FOR SOME RAPID-FIRE STUFF
08100	
  08200	NOTENX <
    08300	NLNO:	MOVE	TBITS,LSTPNT	;LST OUTPUT  BYTE POINTER
   08400		MOVE	SBITS,LSTCNT	;IF ALREADY LINED UP....
    08500	HARRY:	TLNN	TBITS,760000	;LINED UP WHEN PTR PART IS 01
   08600		JRST	LNDUP
 08700		SOS	SBITS,LSTCNT	;DENOTE CHANGE
08800		IBP	TBITS		;MAINLY WANT TO ADJUST COUNT
  08900		JRST	HARRY		;COULD PROBABLY DO CALCULATION
    09000	
  09100	LNDUP:	MOVEM	TBITS,LSTPNT	;UPDATE
    09200		IDIVI	SBITS,5		;#WORDS LEFT, NO REMAINDER GUARANTEED
    09300		AOS	PNT2,LPNT	;WE GOT THIS FAR
 09400		HRRZS	PNT2
 09500		SUB	PNT2,LSTBUF	;HOW MANY WORDS?
    09600		CAMGE	SBITS,PNT2	;IS THERE ROOM?
    09700		 PUSHJ	 P,LSTDO	; NOW THERE IS
 09800	BAIL<
  09900		ADDM	PNT2,BLSTFC	;WORD COUNT FOR LIST FILE
    10000	>;BAIL
 10100		MOVNI	SBITS,5		;UPDATE CHAR COUNT
   10200		IMUL	SBITS,PNT2
 10300		ADDM	SBITS,LSTCNT
    10400		EXCH	PNT2,LSTPNT	;AND LSTPNT
   10500		ADDM	PNT2,LSTPNT	;PREV VERSION IN PNT2
   10600		ADDI	PNT2,1
10700		HRL	PNT2,LSTBUF	;BLT WORD (LSTBUF,,OUTBUF)
    10800		BLT	PNT2,@LSTPNT	;WRITE THE LINE!
   10900	>;NOTENX
    11000	TENX<
  11100		PUSH	P,C
   11200		PUSH	P,B
   11300		HRRZ	2,LPNT
11400		HRRZ	3,LSTBUF
   11500		SUBI	3,1(2)		;-#WRDS, INCLUDING CURRENT WORD
  11600		IMULI	3,5		;-#CHRS, INCL. EXTRAS IN CURRENT WRD
    11700		SKIPA	2,LPNT
    11800		IBP	2
 11900		TLNE	2,760000	;LAST CHAR IN WORD COUNTED?
12000		 AOJA	3,.-2		;UN-COUNT AN EXTRA CHAR
12100	BAIL<
  12200		ADDM	3,BLSTFC	; UPDATE COUNT
   12300	>;BAIL
 12400		EXCH	1,LISJFN
   12500		HRRO	2,LSTBUF
   12600		JSYS	SOUT
  12700		EXCH	1,LISJFN
   12800		HRRZ	3,LSTBUF	;NOW ZERO LSTBUF, JUST IN CASE.
 12900		SETZM	(3)
  13000		HRLI	3,(3)
 13100		ADDI	3,1
   13200		BLT	3,(2)
  13300		POP	P,B
    13400		POP	P,C
    13500	>;TENX
 13600		HRRO	TEMP,LSTBUF	;ADDR OF FIRST WORD OF BUFFER
13700		SUB	TEMP,[XWD 677077,1] ;POINT 5,@LSTBUF,29
   13800		MOVEM	TEMP,LPNT	;NEW LIST POINTER
   13900	IFN FTL$DBG,<
    14000		MOVEI	TEMP,5*=50
14100		MOVEM	TEMP,L$CNT
14200	>;IFN FTL$DBG
    14300		MOVE	TEMP,[ASCID /     /] ;BLANKS IN CASE
14400		MOVEM	TEMP,ASCLIN	;IN MACRO AND MORE LINES TO COME
 14500		AOS	TBITS,LINNUM	;CHECK LINE OVERFLOW
    14600		IDIVI	TBITS,PGSIZ
    14700		SKIPN	SBITS
14800		PUSHJ	P,HDROV		;PRINT FF
  14900	
          00100	
  00200	; ENOUGH OUTPUT, NOW FOR SOME INPUT
  00300	
  00400	NOLST:
 00500		SKIPE	SRCDLY			;SWITCHING SOURCE INPUT?
  00600		 JRST	 NXTSRC			; YES
00700	
  00800		MOVE	PNT,PNEXTC
 00900		IBP	PNT
    01000		MOVEM	PNT,PLINE	;UPDATE IF MACRO
    01100		TLNE	TBITS2,MACIN	;DONE IF MACRO
    01200		 JRST	 LDO1		;DONE
   01300	
  01400	; MAKE A LINE NUMBER IN CASE FILE HAS NONE
01500		AOS	TBITS,BINLIN	;SEQUENTIAL WITHIN PAGE
 01600	;;%DM% CMU =F4= LDE 14-JUN-76	GENERATE MORE LIKELY SOS LINE NUMBERS.
    01700	EXPO <
 01800		CAIG	TBITS,=999	;HIGHEST LEGAL LINE NUMBER
    01900		 IMULI	TBITS,=100
    02000	>;EXPO	=F4=
 02100	;;%DM% ^
    02200		MOVEI	B,[IDPB TBITS,A ;ROUTINE TO DISPENSE CHARS
   02300			   POPJ P,]
    02400		MOVEI	PNT2,5		;5 CHARS ALWAYS
  02500		MOVE	A,[POINT 7,ASCLIN] ;PUT IT HERE
02600		PUSHJ	P,FRNPD		;GET ASCII VERSION
   02700		MOVEI	TEMP,1
    02800		ORM	TEMP,ASCLIN	;MAKE ASCID
    02900	; ACTUAL LINE NUMBER WILL OVERRIDE THIS IF THERE
    03000	
  03100		LDB TEMP,PNT		;NEXT CHAR.
 03200		JUMPE TEMP,NULCHR	;GO FIND NON-NULL
 03300	LINCHA:	MOVE TEMP,(PNT)
    03400	LINCHK:	TRNN TEMP,1		;ARE WE IN LINE NUMBER?
   03500		JRST LDUNA		;NO THIS IS THE NEXT CHAR.
   03600	BAIL<	;JFR 4-18-76 AT COMPLAINT OF REM
    03700		PUSH	P,TEMP
03800		SKIPN	BPNXTC		;IF SOURCE NOT MARKED
 03900		 PUSHJ 	P,BMKSRC	;THEN MARK IT BEGINNING AT LINE NUMBER
 04000		POP	P,TEMP
 04100	>;BAIL
 04200		CAME TEMP,[ASCID/     /];IS IT A PAGE MARK PERHAPS
 04300		AOJA PNT,LDUN		;NO JUST SKIP LINE NUM AND TAB
 04400		MOVEM PNT,PNEXTC	;HDR CLOBBERS THIS
 04500		PUSHJ P,HDR		;WRITE PAGE MARK, NEW TITLE LINE
 04600		MOVE PNT,PNEXTC		;GET HIM BACK
 04700		SKIPN 1(PNT)		;END OF BUFFER?
  04800		PUSHJ P,ADVBUF		;YES, GET NEXT.
04900		ADDI PNT,1		;POINT BEHIND NEXT LINE NUMBER
    05000		SKIPN TEMP,1(PNT)	;IS IT IN THIS BUFFER?
 05100		PUSHJ P,LINADV		;[clh] NO.
05200		HRLI PNT,350700		;POINT TO FIRST CHAR. OF LINE NUMBER
   05300		AOJA PNT,LINCHA		;AND DO IT AGAIN (IN CASE 2 PAGE MARKS).
    05400	
  05500	LINADV:	MOVEM PNT,PNEXTC	;[clh] advbuf needs this
   05600		JRST ADVBUF		;[clh] get to new buffer
    05700	
  05800	NULCHR:	ILDB B,PNT		;MOVE ON UP
 05900		MOVE	TEMP,(PNT)	;GET COMPLETE WORD
  06000		JUMPN B,LINCHK		;FINALLY WE GOT SOMETHING
06100		IBP	PNEXTC		;KEEP IN STEP
 06200		JUMPN	TEMP,NULCHR	;END OF BUFFER?
   06300		PUSHJ P,ADVBUF		;YES.
06400		JRST NULCHR		;HERE WE GO LOOP-D-LOOP
06500	
  06600	LDUN:	SKIPE (PNT)		;IS TAB IN THIS BUFFER
 06700		JRST LDUN1		;YES
06800		PUSHJ P,LINADV		;[CLH] NO
 06900		IBP PNT			;MAKE IT CURRENT
07000	LDUN1:	MOVEM TEMP,ASCLIN	;CURRENT LINE#
   07100		MOVEM PNT,PNEXTC	;THIS GUY POINTS TO TAB
 07200	LDUNA:	MOVE TEMP,PNEXTC	;MAY NOT USE PNT
  07300		MOVEM TEMP,PLINE	;BEGINNING OF LINE
 07400	IFN FTDEBUG,<
    07500		AOS	LINCNT		;COUNT NUMBER OF LINES SEEN
  07600		SKIPL STPAGE		;ARE WE LOOKING FOR A PAGE/LINE?
07700		PUSHJ P,STPLIN		;LINE BREAK IF NECESSARY.
07800	>
 07900	LDO1:	MOVEI B,12		;GET LINE FEED BACK.
    08000		MOVEI A,0		;HARMLESS LF
   08100		MOVE USER,GOGTAB
08200		POP	P,C		;RESTORE CHARACTER COUNT.
  08300		POPJ P,			;WASN'T THAT WONDERFUL
    08400	
  08500	
  08600	; HERE WE SAVE INFO ABOUT SOURCE FILE, AND PREPARE TO GET INFO
08700	; ABOUT NEW ONE.
 08800	
  08900	NXTSRC:
09000	NOTENX <
    09100		MOVE	A,AVLSRC		;BITS TELLING FREE CHANNELS
    09200		JFFO	A,GOTNEW		;FOUND A FREE ONE
    09300		 ERR	 <NO MORE AVAILABLE SOURCE CHANNELS>
09400	GOTNEW:
09500		PUSH	P,B			;SAVE NEW CHANNEL #
 09600		MOVEI	C,ENDSRC-SRCCDB+1	;SIZE OF SAVE AREA
    09700	>;NOTENX
    09800	TENX <
 09900		MOVEI 	C,ENDSRC-BGNSWA+1	;SIZE OF SAVE AREA
   10000	>;TENX
 10100		PUSHJ	P,CORGET		;GET ONE
  10200		 ERR	 <NO CORE AVAILABLE FOR FILE SWITCH>
10300		HRR	TEMP,B			;BLT WORD
    10400	NOTENX <
    10500		HRLI	TEMP,SRCCDB
10600		BLT	TEMP,ENDSRC-SRCCDB(B)
 10700	>;NOTENX
    10800	TENX <
 10900		HRLI	TEMP,BGNSWA
11000		BLT	TEMP,ENDSRC-BGNSWA(B)
 11100	>;TENX
 11200		HRRZM	B,SWTLNK		;SAVE PTR TO SAVE AREA
   11300		TLO	TBITS2,INSWT		;WE'RE SCANNING SWITCHED-TO FILE
 11400		MOVEM	TBITS2,SCNWRD
  11500		SETZM	LSTCHR			;ALWAYS DO IT
   11600		SETZM	SAVCHR
    11700	NOTENX <
    11800		SETZM	SAVTYI
    11900		SETZM	EOF
  12000		SETZM	EOL
  12100		POP	P,A			;CHANNEL NUMBER
 12200	FOR II_0,1 <
12300		DPB	A,[POINT 4,SRCOP+II,12]
    12400	>
 12500	FOR II_0,3 <
12600		DPB	A,[POINT 4,INSRC+II,12]
    12700	>
 12800	NOEXPO <
    12900		DPB	A,[POINT 4,SRCOP+2,12]	;PUSHJ IF EXPO
13000	>;NOEXPO
    13100		MOVN	TEMP,A			;-CHANNEL NUMBER
 13200		MOVSI	LPSA,400000		;BIT
   13300		LSH	LPSA,(TEMP)
 13400		ANDCAM	LPSA,AVLSRC		;THIS CHANNEL UNAVAILABLE
 13500	>;NOTENX
    13600	;;%CF% JFR 7-8-75
13700	IFN 0,<
13800		AOS	TEMP,LININD		;HOW FAR IN TO SPACE ON TTY
  13900		CAILE	TEMP,MAXIND		;TOO FAR?
   14000		SOS	LININD			;NOT REALLY
  14100	>;IFN 0
14200		MOVEI	TEMP,2		;INDENT ON TTY
   14300		ADDM	TEMP,LININD
14400	;;%CF% ^
    14500	NOTENX <
    14600		SETOM	TYICORE			;WILL SCAN FROM STRING
   14700	>;NOTENX
    14800		MOVE	TEMP,GENLEF+2
   14900	;; %AN% CHECK TO BE SURE STRING CONSTANT, SINCE PRODUCTIONS NO LONGER CHECK
  15000		MOVE	TEMP,$TBITS(TEMP)
    15100		TRNN	TEMP,STRING	
    15200		ERR	<SOURCE!FILE NAME MUST BE STRING>
    15300		MOVE	TEMP,GENLEF+2
   15400	;; %AN%
15500		HRROI	TEMP,$PNAME+1(TEMP)	;GET STRING TO BE SCANNED
15600		POP	TEMP,PNAME+1
15700		POP	TEMP,PNAME		;PUT ER THERE
  15800	BAIL<
  15900		SKIPN	SRCDLY			;SWITCHING SOURCE INPUT?
  16000		JRST	BNSRCD			;NO
    16100		QPUSH	BSRCFQ,BSRCFC		;YES. SAVE BUFF. ADDR,,BLOCK COUNT
 16200		QPUSH	BSRCFQ,BSRCFN		;SAVE FILE NUMBER
   16300	;;#%%# ! BY JFR 11-17-74  ZERO THE BLOCK COUNT FOR THE NEW FILE
    16400		SETZM	BSRCFC
    16500	BNSRCD:
16600	>;BAIL
 16700		PUSHJ	P,ENDSWT		;USE EOF CODE TO GET NEW FILE
 16800						;SRCDLY WILL BE TURNED OFF HERE
 16900		JRST	NOLST			;AND GO BACK TO END OF LINE CODE
 17000	
          00100	; END OF BUFFER CODE.
 00200	
  00300	SEOB:	TLNE	TBITS2,LOKPRM	;END OF POSSIBLE MACRO PARAM SCAN?
   00400		POPJ	P,		;YES, IGNORE THE WHOLE THING
    00500		MOVE	PNT,PNEXTC	;CURRENT BP
    00600		JUMPE	PNT,ADVIT	;INITIALIZATION TIME
00700		SKIPE	TEMP,(PNT)	;REAL END OF BUFFER?
    00800		 JRST	 SEOBAK		; NO, WILL COME BACK UNTIL NOT NULL
 00900	ADVIT:	
01000	;; #PF# SUPPLY CORRECT NUMBER OF THINGS ON STACK IN CASE ADVBUG DOESN'T RETURN
    01100		PUSH	P,C
   01200		PUSHJ	P,ADVBUF
  01300		POP	P,C
    01400	;; #PF#
01500		TRNN	TEMP,1		;LINE NUMBER? (INIT SCAN FOR SOS FILES)
    01600		 JRST	 SEOBAK		;NO, FIND NEXT CHAR
  01700		MOVEM	TEMP,ASCLIN	;SAVE LINE NUMBER
 01800		IBP	PNT		;OVER TAB
   01900		ADDI	PNT,1		;BACK IN BUSINESS
  02000	SEOBAK:	MOVEM	PNT,PLINE	;BEGINNING OF LINE
02100		ILDB	B,PNT		;GET CHAR
02200		MOVEM	PNT,PNEXTC	;UPDATE
  02300		SKIPGE	A,SCNTBL(B)	;SPECIAL?
   02400		JRST	(A)		;YES, HANDLE
    02500		POPJ	P,		;NO, DONE
   02600	
  02700	; END OF PAGE (TECO FILES ONLY)
 02800	
  02900	SEOP:	PUSHJ	P,HDR		;PRINT FF, TITLE LINE
  03000	;; #PC#! OVERWRITING FIRST LINE OF CREF 
  03100		MOVEI	B,0		;PRETEND A NULL CHARACTER 
    03200		MOVEI	A,0		;BITS FOR CR
   03300		POPJ	P,
    03400	
          00100	Comment  Parameter delimiter or end of message 
   00200	
  00300	EOM:	ILDB	B,PNEXTC	;CHECK WHICH
 00400		SKIPN	ASGFLG		;ASSIGNC PARAMETER NUMBER? 
00500		JRST	CONEOM		;NO, 
   00600		MOVE	LPSA,B		;RETURN THE PARAMETER NUMBER IN THE 
  00700		MOVE	A,%NUMCON	; SEMANTIC STACK 
    00800		SUB	P,X11		; TO OVERRIDE THE PUSHJ HERE 
 00900		JRST	STACK		;
   01000	CONEOM:	JUMPE	B,RESTOR	;ZERO, END OF MACRO (OR PARAM) TEXT
    01100		
 01200	; PARAMETER NEEDED
    01300	
  01400		SETZM	SAVCHR
    01500		SETZM	LSTCHR
    01600		MOVE	LPSA,DEFRNG
01700	GETIT:	SOJE	B,GOTIT		;LOOK FOR THE PARAMETER OF PROPER NUMBER
 01800		RIGHT	,%RVARB,<[ERR <NOT ENOUGH ARGUMENTS SUPPLIED TO MACRO>]>
    01900		JRST	GETIT		;KEEP LOOKING
 02000	
  02100	GOTIT:
 02200	DFNEST:	MOVE	PNT,DEFPDP	;NOW SAVE STATE OF SCANNER AND RECUR
  02300		PUSH	PNT,DEFRNG	; SAVE DEFRNG WHICH CONTAINS THE LENGTH OF THE 
   02400		PUSH	PNT,PNEXTC-1	;  ACTUAL PARAMETER TO BE  EXPANDED.  THIS WILL
 02500					;  ENSURE THAT WHEN A RETURN IS MADE FROM
  02600					;  EXPANDING THE ACTUAL THERE WILL BE ENOUGH
    02700					;  STRING SPACE FOR THE REST OF THE MACRO.  
    02800		PUSH	PNT,PNEXTC	;INPUT POINTER
 02900		PUSH	PNT,SAVCHR	;SCANNED AHEAD
 03000		MOVEM	PNT,DEFPDP	;SAVE POINTER
 03100		PUSHJ	P,SGCOL1		;MAKE SURE ENOUGH ROOM
   03200		HLLZ	TEMP,$PNAME(LPSA) ;STRING NUMBER
    03300		MOVEM	TEMP,PNEXTC-1
  03400		MOVEM	TEMP,PLINE-1
   03500		MOVEW	PNEXTC,$PNAME+1(LPSA) ;NEW INPUT POINTER
03600		MOVEM	TEMP,PLINE
03700		MOVEI	B,"<"		;MARKER FOR MACRO EXP
  03800	;;#YV# JFR 2-4-77
03900		TLNN	TBITS2,LSTEXP	;WANT IT?
   04000		 JRST	DFNE.1		;SURELY NOT
 04100		LSTDPB			;MAYBE
 04200	DFNE.1:	TLO	TBITS2,MACIN	;MARK IN MACRO
   04300		TLNN	TBITS2,MACEXP	;EXPANDING?
 04400		 TRO	TBITS2,NOLIST	;NO
    04500	;;#YV# ^
    04600		MOVEM	TBITS2,SCNWRD	;UPDATE
    04700		TLNE	FF,PRMSCN	; SCANNING PARAMETERS?
    04800		SKIPN	REQDLM		; YES, IN SPECAIL DELIMITER MODE?
    04900		JRST	NEWCHR		;GO GET FIRST NEW CHAR, RET
 05000		CAIN	P,DSPRMS+3	; IS 177-# FIRST ITEM IN ACTUAL PARAMETER
    05100		HRRI	P,BALCHK	; YES, CHANGE RETURN ADDRESS TO REFLECT 
  05200					; THAT UNTESTED COMMAS AND RIGHT PARS. WILL
05300					; BREAK SCAN
 05400	DLMPRM:	ILDB	B,PNEXTC	; SCAN REST OF CHARS. INTO STRING CONSTANT
   05500		SKIPGE	A,SCNTBL(B)	; SPECIAL?
  05600	;; #OG# ! MAKE SURE PNAME COUNT VALID IN CASE OF REAL GARBAGE COLLECT
   05700		PUSHJ	P,CSPEC		; DO IT
    05800		LSTDPB			; PUT IT AWAY
    05900		IDPB	B,TOPBYTE(USER)	; DEPOSIT IT
   06000		AOJA	C,DLMPRM	; INCREMENT COUNT AND CONTINUE SCAN
  06100	
  06200	RESTOR:	MOVE	PNT,DEFPDP
    06300		POP	PNT,SAVCHR	;CHAR SCANNED AHEAD
  06400		POP	PNT,PNEXTC	;OLD INPUT POINTER
   06500		POP	PNT,PNEXTC-1	;STRING NUMBER
06600		ADD	PNT,X22			;START PLINE HERE
06700		POP	PNT,PLINE
   06800		POP	PNT,PLINE-1
 06900		POP	PNT,LPSA	;PERHAPS OLD DEFRNG
    07000		MOVEM	PNT,DEFPDP
07100		HLRZ	TBITS,LPSA	; GET LENGTH OF MACRO TO WHICH ONE IS RETURNING AND
    07200		PUSHJ	P,SGCOL2	;  INSURE ENOUGH ROOM IN STRING SPACE FOR IT 
 07300		EXCH	LPSA,DEFRNG	; GET OLD DEFRNG VALUE AND IF DIFFERENT FROM CURRENT
  07400		CAMN	LPSA,DEFRNG	;  VALUE THEN ONE IS DONE WITH THE MACRO AND THUS 
    07500		JRST	DDUN		;  RING OF ACTUAL PARAMETERS (POINTED TO BY DEFRNG) 
   07600		HRRZS	LPSA		;  IS REMOVED FROM THE STRING RING.  NOTE THAT 
  07700		PUSHJ	P,KILLST	;  KILLST EXPECTS LPSA WITH ZERO IN THE LEFT HALF.  	
   07800	
  07900	DDUN:	MOVEI	B,">"		;END OF EXPANSION MARKER
    08000	;;#YV# JFR 2-4-77
08100		TLNN	TBITS2,LSTEXP
   08200		 JRST	DDUN.1
    08300		LSTDPB
08400	DDUN.1:
08500		SKIPN	PNEXTC-1	;OUT OF MACROS?
 08600		TLZA	TBITS2,MACIN	;YES
    08700		JRST	DUNRST		;NO
08800		PUSHJ	P,L$SET		;GET 'NOLIST' FROM ABSOLUTE BEARINGS
08900	;;#YV# ^
    09000		MOVE	TEMP,IPLINE	;PLINE TO OUTER LEVEL VALUE
  09100		MOVEM	TEMP,PLINE
09200		SETZM	PLINE-1
   09300	
  09400	DUNRST:	MOVEM	TBITS2,SCNWRD	;SAFETY FIRST
 09500	
  09600	; NOW GET A CHARACTER FOR THE SCANNER
09700	
  09800		TLNE	FF,PRMSCN	; SCANNING PARAMETERS?
    09900		SKIPN	REQDLM		; YES, IN SPECIAL DELIMITER MODE?
    10000		TRNA			; SKIP
   10100		SUB	P,X11		; POP RETURN ADDRESS, AND NOW WILL RETURN 
   10200					; TO CHECK NESTING INSTEAD OF CONTINUING 
  10300					; FORMAL PARAMETER SCAN
10400		SKIPN	B,SAVCHR	;HAVE IT ALREADY?
    10500		JRST	NEWCHR		;NO
10600		SETZM	SAVCHR		;NO LONGER AHEAD (DCS 5-27-71)******
 10700		MOVE	A,SCNTBL(B)	;YES, DON'T DISPATCH AGAIN
   10800		POPJ	P,
    10900	
  11000	NEWCHR:	ILDB	B,PNEXTC	;GET FROM INPUT
11100		SKIPGE	A,SCNTBL(B)	;SPECIAL?
   11200		JRST	(A)		;YES, DISPATCH
  11300		POPJ	P,		;NO, DONE
   11400	
  11500	DSCR KILLST
 11600	CAL PUSHJ
   11700	PAR LPSA ptr to first Semblk to be released
    11800	RES Unlinks Semblk from %RSTR, releases it to free
  11900	  storage, then continues right down %RVARB until
   12000	  all Semblks on this VARB-Ring are released.
  12100	DES THIS ROUTINE IS IN THE WRONG PLACE!
   12200	SEE FREBLK, ULINK
12300	
 12400	
  12500	^KILLST:  
  12600		PUSH	P,LPSA
12700		JUMPE	LPSA,KLPDUN
    12800	
  12900	KLLUP:	
13000	
  13100		PUSHJ	P,URGSTR	;UNLINK FROM STRING RING
  13200		FREBLK
13300		RIGHT	,%RVARB,<[KLPDUN: POP P,LPSA
  13400					  POPJ P,]>
  13500		JRST	KLLUP
 13600	SUBTTL	SCANNER INPUT AND LISTING ROUTINES
 13700	
          00100	DSCR ADVBUF -- new input buffer routine
   00200	DES Reads a new input buffer, gets a new source file
00300	  if this one is exhausted or if file switching is
  00400	  happening (prints loser message if no files remain),
   00500	  and assures that the buffer ends in zero for EOB
  00600	  detection by SEOL. The buffers were made long enough
   00700	  to allow the inclusion of an extra word of zero.
  00800	SID Saves USER, C -- reinits A,B -- all others vulnerable
00900	SEE SEOL, SEOB, routines which detect EOB and call ADVBUF.
    01000	
 01100	NOTENX <
    01200	ADVBUF:	
    01300		XCT	INSRC		;ADVANCE BUFFER
01400		XCT	TSTSRC		;ANY ERRORS?
  01500		 ERR	 <I-O ERROR ON SOURCE DEVICE>,1
01600		XCT	EOFSRC		;TO ENDFL ON EOF
   01700		JRST	ENDFL
 01800	BAIL <
 01900		AOS	BSRCFC		; ADD ONE TO SOURCE FILE BLOCK COUNT
   02000	>;BAIL
 02100		PUSHJ	P,SGCHK		;STRING GC, IF NECESSARY, TBITS_SRCCNT
   02200		ADDI	TBITS,4		;(CHAR CT+4)/5 IS WORD COUNT
    02300		IDIVI	TBITS,5
   02400		ADD	TBITS,SRCPNT	;ADD BASE ADDRESS
  02500		IBP	TBITS		;PTR TO LAST WORD+1, MAKE 0 TO
02600		SETZM	(TBITS)		; DENOTE EOB
    02700		MOVE	PNT,SRCPNT	;RESET PNT TO CURRENT BP,
02800		MOVEM	PNT,PNEXTC	;FIX THIS GUY TOO.
 02900		MOVE	TEMP,1(PNT)	; TEMP TO WORD NEXT REFERENCED
    03000		POPJ	P,
    03100	
  03200	; CHECK FOR STRING SPACE FULL, GC IF SO
   03300	
  03400	SGCHK:
 03500		HRRZ	TBITS,SRCCNT	;GET # OF CHARACTERS
   03600		MOVE	TEMP,REMCHR(USER) ;TEST ENOUGH ROOM
 03700		ADD	TEMP,TBITS
  03800		SKIPL	TEMP		;IS THERE ENOUGH?
  03900		 JRST	 SGCOL		;NO, COLLECT SPACE
    04000		POPJ	P,		;NOT NECESSARY
   04100	
  04200	ENDFL:	XCT	RELSRC		;RELEASE OLD FILE,
04300	>;NOTENX
    04400	TENX <
 04500	ADVBUF:	PUSH	P,1
 04600		PUSH	P,2
   04700		PUSH	P,3
   04800		SKIPE	TTYSRC		;CONTROLLING TERMINAL SOURCE DEVICE?
 04900		  JRST	ADVTTY		;YES
  05000		SKIPN	TNXBND		;ANYTHING IN THE BUFFER?
   05100		  JRST	ADVBF1		;NO DONT CHECK
  05200		HRRZ	1,PNEXTC 	;LOOK AT ADDR
   05300	ADVBF2:	CAML	1,TNXBND	;BEYOND BUFFER?
05400		  JRST	ADVBF1		;YES, CHECK EOF, GET MORE IF THERE
  05500		SKIPN	1(1)		;0 WORD?
 05600		  AOJA	1,ADVBF2	;YES KEEP LOOKING FOR INFO IN THE BUFFER
05700		HRLI	1,010700
   05800		PUSH	P,1		;SAVE NEW BP
    05900		PUSHJ	P,SGCHK		;CHECK GARBAGE COLLECTION
 06000		POP	P,PNT		;BP TO PNT
06100		POP	P,3		;RESTORE
    06200		POP	P,2
    06300		POP	P,1
    06400		MOVEM	PNT,PNEXTC
06500		MOVE	TEMP,1(PNT)	;WHICH IS NON-ZERO BECAUSE WE JUST CHECKED
  06600		POPJ	P,
    06700	
  06800	ADVBF1:	HRRZ	1,SRCJFN
 06900		JSYS	GTSTS
 07000		TLNE	2,1000		;EOF?
   07100		 JRST	ENDFL		;YES
    07200	BAIL <
 07300		AOS	BSRCFC		;ADD ONE TO SOURCE FILE BLOCK COUNT
    07400	>;BAIL
 07500		HRR	2,SRCPNT
    07600		ADDI	2,1		;SRCPNT IS A 7-BIT POINTER THAT IS A WORD EARLY
    07700		HRLI	2,444400	;36-BIT POINTER.
 07800		MOVNI	3,SRCBSZ	;SIZE OF SRC BUF IN WRDS, MINUS EOB NULL
 07900		JSYS	SIN		;SRCJFN OPEN FOR 36BIT INPUT
   08000		HRRZM	2,TNXBND	;SAVE END OF BUFFER ADDRESS FOR CHECKS ABOVE
  08100		SETZM	1(2)		;EOB NULL.
    08200	ADVDUN:	PUSHJ	P,SGCHK
 08300		POP	P,3
    08400		POP	P,2
    08500		POP	P,1
    08600		MOVE	PNT,SRCPNT	;RESET PNT TO CURRENT BP,
08700		MOVEM	PNT,PNEXTC	;FIX THIS GUY TOO.
 08800		MOVE	TEMP,1(PNT)	;GET THE FIRST WORD IN TEMP
  08900		POPJ	P,
    09000	
  09100	; CHECK FOR STRING SPACE FULL, GC IF SO
   09200	
  09300	SGCHK:
 09400		MOVEI	TBITS,SRCBSZ*5	;TENEX BUFFER SIZE
  09500		MOVE	TEMP,REMCHR(USER)	;REMAINING CHARS
  09600		ADD 	TEMP,TBITS
 09700		SKIPL	TEMP			;ENOUGH?
09800		   JRST	SGCOL		;NOT ENUF STRNG SPACE FOR A FULL BUFFER
  09900		POPJ	P,		;NOW THERE IS
    10000	
  10100	DSCR ADVTTY
 10200		Since the boys at BBN have seen fit to not provide a standard
10300	line editor into their system, we must resort to using some runtimes
    10400	to handle input in the case that the source is a TTY.  We confine the
   10500	problem to the case that the source is the controlling teletype, as
10600	indicated by the SRCTTY (set in CC), and use INTTY.  INTTY at IMSSS
10700	uses the IMSSS PSTIN jsys, otherwise a simulation of same.
    10800	;
10900	
  11000	ADVTTY:
11100	EXTERNAL .SKIP.
  11200	EXTERNAL INTTY
   11300		EXCH	SP,STPSAV
  11400		PUSHJ	P,INTTY		;GET A STRING USING THE PSTIN JSYS
  11500		POP	SP,A		;BYTE POINTER
   11600		POP	SP,C		;XWD -1, LENGTH -- STACKS ARE NOW OK
11700		EXCH	SP,STPSAV
  11800		MOVE	B,.SKIP.
   11900		CAIN	B,32		;CONTROL-Z TO INDIATE EOF
12000		  JRST	ENDFL		;YES END OF FILE
 12100		MOVE	B,SRCPNT
   12200		HRRZ	C,C	
  12300		MOVNS	C		;NUMBER OF CHARS TO TRANSFER
    12400		JSYS	SIN		;USE SIN TO TRANSFER STRING
    12500		MOVEI	C,15
 12600		IDPB	C,B
   12700		MOVEI	C,12
 12800		IDPB	C,B
   12900		SETZ	C,
    13000		REPEAT 5, <IDPB	C,B>	;PUT NULLS THERE
    13100		SETZM	(B)		;BE SURE TO INDICATE EOF
 13200		SETZM	1(B)		
    13300		JRST	ADVDUN		;AND FINISH UP, ABOVE
  13400	
  13500	ENDFL:
 13600		HRRZ	A,SRCJFN
   13700		JSYS	CLOSF
 13800		  JFCL
13900		HRRZ	A,SRCJFN
   14000		JSYS	RLJFN
 14100		  JFCL
14200		POP	P,3
    14300		POP	P,2
    14400		POP	P,1
    14500	
  14600	>;TENX
 14700	ENDSWT:	MOVEM	TBITS2,SCNWRD	;UPDATE IN CORE VERSION
 14800		PUSHJ	P,FILEIN	;FIND AND INIT NEW ONE
    14900		JRST	[TLNN	TBITS2,EOFOK
   15000	;;%CI% ! (4/5)
   15100			 JRST	ENDSW1
   15200			 MOVNI	B,1	;MARK END OF FILE NEXT TIME
  15300			 MOVEI	A,1	;HARMLESS, BUT BREAKS IGNORABLE
   15400			 SUB	P,X11	;RETURN EARLY
 15500			 POP	P,C	;CHAR COUNT BACK
15600			 POPJ	P,]
 15700	ENDSW3:
15800	;;%DE% ! JFR 10-25-75	PUSHJ	P,MAKT		;PREPARE NEW TITLE LINE
   15900		SKIPE	SRCDLY		;COMING BACK FROM SWTCHED-TO FILE?
   16000		 JRST	 SWTBKP		; YES, DO MORE BOOKKEEPING
16100		SETZM	FPAGNO		;FIRST PAGE IN NEW FILE
    16200		PUSHJ	P,HDR		; , DENOTE IT
16300		JRST	ADVBUF		; OR PRINT LOSING MESSAGE, TRY AGAIN
  16400	
  16500	^^XTCONT:MOVSI	16,INIACS	;RESTORE
    16600		BLT	16,16
  16700		JRST	ENDSW3
16800	
  16900	;;%CI% (5/5) JFR 7-18-75
   17000	ENDSW1:
17100		MOVEI	TEMP,LININD+1	;MAKE SURE TRKMCS AND TRKMCR POINT A LEGIT STRING
  17200		SKIPN	TRKMCS
    17300		 MOVEM	TEMP,TRKMCS
   17400		SKIPN	TRKMCR
    17500		 MOVEM	TEMP,TRKMCR
   17600		MOVEI	TEMP,0		;ASSUME FILE JUST RAN OUT
  17700		TLNE	FF,PRMSCN	;SCANNING MACRO ACTUALS?
  17800		 MOVEI	TEMP,[ASCIZ/macro parameters/]
    17900		SKIPE	CNDLST
    18000		 MOVEI	TEMP,[ASCIZ/false conditional compilation/]
 18100		JUMPN	TEMP,.+4	;IF ALREADY SOME BAD REASON
    18200		SKIPE	XTFLAG		;ELSE TEST FOR EXTENDED COMPILATION
  18300		 JRST	XTCOMP
    18400		MOVEI	TEMP,[ASCIZ/file/]
  18500		HRLI	TEMP,(<POINT 7,0>)	;MAKE BYTE POINTER
    18600	;;%DH%
 18700		MOVE	SBITS,TRKBEG	;SECOND SEMBLK OF CURRENT BEGIN
  18800		HLRZ	TBITS,(SBITS)	;FIRST SEMBLK OF BEGIN
18900		ERRSPL	[[ASCIZ\
 19000	Fatal end of source file, scanning @A.
    19100	BEGIN @I  @E/@D
  19200	Last source-file macro: @I  @E/@D
    19300	Current macro: @I
19400	\]
19500			PWORD	TEMP		;MORE EXPLICIT REASON
  19600			PWORD	$PNAME+1(TBITS)	;BLOCK NAME
  19700			PWORD	$PNAME+1(SBITS)	;LINE #
 19800			PWORD	$PNAME(SBITS)	;PAGE #
   19900			PWORD	@TRKMCS		;MACRO NAME
    20000			PWORD	TRKM.L		;LINE #
    20100			PWORD	TRKM.P		;PAGE #
    20200			PWORD	@TRKMCR]	;MACRO NAME
    20300		JRST	ENDSW3
20400	
  20500	XTCOMP:
20600	NOTENX<
20700	;;%DL% JFR 4-30-76 prevent enclobberment if /X and /B
    20800	IFN 0,<	;some problems remain
   20900		SKIPE	BAILON
    21000		SKIPN	XTFLAG
    21100		 JRST	XTC.NR		;MISSING ONE OR BOTH OF /X, /B
  21200		MOVE	TEMP,SM1FIL
21300		MOVEM	TEMP,NAME
 21400		MOVSI	TEMP,'SM0'	;NEW EXTENSION
21500		MOVEM	TEMP,EXTEN
21600		MOVEM	TEMP,SM1EXT
    21700		SETZM	WORD3
21800		MOVE	TEMP,SM1PPN
21900		MOVEM	TEMP,PPN
  22000		RENAME	SM1,NAME
 22100		 ERR	<RENAME error .SM1>,1
22200	XTC.NR:
22300	>;IFN 0,
    22400	;;%DL% ^
    22500		PUSH	P,SM1DEV	;SAVE NAME OF .SM1 FILE
    22600		PUSH	P,SM1FIL
   22700		PUSH	P,SM1EXT
   22800		PUSH	P,SM1PPN
   22900		PUSH	P,BINDEV	;AND .REL FILE
   23000		PUSH	P,BINFIL
   23100		PUSH	P,BINEXT
   23200		PUSH	P,BINPPN
   23300	>;NOTENX
    23400		MOVEI	TEMP,INIACS	;SAVE OUR ACS HERE
23500		BLT	TEMP,INIACS+17
   23600	TENX<
  23700		HRROI	1,XTSFIL
  23800		SETZ	3,
    23900		SKIPN	2,SM1JFN
  24000		 JRST	.+2
  24100		JSYS	JFNS
  24200		HRROI	1,XTBFIL
  24300		SETZ	3,
    24400		SKIPN	2,BINJFN
  24500		 JRST	.+2
  24600		JSYS	JFNS
  24700		SETZM	TMPCNT		;[clh]
 24800		MOVE	TEMP,[ASCII /XSAIL/] ;[clh]
    24900		MOVEM	TEMP,CMPMT	;[clh] <
 25000		MOVE	TEMP,[ASCIZ />/] ;[clh]
   25100		MOVEM	TEMP,CMPMT+1
   25200	>;TENX
 25300		HRLZS	XTFLAG		;WHEN WE START AGAIN, WE ARE XTENDED!!!!!
 25400		HRROS	JOBHRL		;GET RID OF SECOND SEGMENT??
    25500		HRRZ	TEMP,JOBREL	;HIGHEST LEGAL ADDR IN LOW SEG
    25600		MOVSI	TEMP,1(TEMP)	;FIRST FREE LOC,,0
    25700		HRRI	TEMP,XSTART	;NEW START ADDR
    25800		MOVEM	TEMP,JOBSA	;NOW .SAVE HAD BETTER DO THE RIGHT THING
    25900		PUUO	3,[ASCIZ/
  26000	SAVE ME FOR USE AS XSAIL./]
26100		JRST	RELSE
 26200	
  26300	; WE HAVE OLD SOURCE FILE BACK, FAKE ADVBUF
    26400	SWTBKP:
26500	BAIL <
 26600		QPOP	BSRCFQ,BSRCFN	;RETRIEVE PREVIOUS FILE NUMBER
  26700		QPOP	BSRCFQ,BSRCFC	;RETRIEVE BUFF.ADDR,,BLOCK COUNT
26800	>;BAIL
 26900		PUSHJ	P,HDROV		;CONTINUE PAGE NUMBERING FOR FILE
   27000		SETZM	SRCDLY
    27100		PUSHJ	P,SGCHK		;CHECK (LIBERALLY) FOR STRING SPACE FULL
 27200		MOVE	TEMP,PNEXTC	;NOW SET UP PNT, PNEXTC, AND TEMP AS
   27300	SWTLUP:	SKIPN	(TEMP)		; THEY WOULD BE COMING OUT OF ADVBUF
    27400		 JRST	 ADVBUF		;WE WERE AT END OF BUFFER ANYWAY
    27500		MOVE	PNT,TEMP	;WE'RE GOING TO GET AHEAD OF SELVES
  27600		ILDB	TBITS,TEMP	;CHECK NULLS
   27700		JUMPE	TBITS,SWTLUP	;ALL THIS UNECESSARY IF SOS FILES, BUT...
 27800		MOVEM	PNT,PNEXTC	;FAKE ADVBUF
  27900		MOVE	TEMP,(TEMP)	;WORD WITH NON-NULL CHAR
28000		POPJ	P,
    28100	;;%CI% ^
    28200	
          00100	BAIL <
 00200	^^UPDCNT:	HRRM	C,PNAME			;UPDATE PNAME
    00300	>;BAIL
 00400	NOBAIL<
00500	UPDCNT:	HRRM	C,PNAME			;UPDATE PNAME
 00600	>;NOBAIL
    00700		ADDB	C,REMCHR(USER)		;AND REMCHR
    00800		CAMGE	C,[-=50]		;ARE WE NEARING CATASTROPHE?
  00900		 POPJ	 P,			; NO
01000	;EVEN THIS CANNOT PREVENT OCCASIONAL DEATH
01100		MOVEI	TBITS,=50		;REQUIRE AT LEAST THIS MANY
  01200		JRST	SGCOL			;GO COLLECT
  01300	
  01400	SGCOL1:	HRRZ	TBITS,$PNAME(LPSA)	;CHAR COUNT
    01500	SGCOL2:	MOVE	USER,GOGTAB
   01600		MOVE	TEMP,REMCHR(USER)		;REMAINING CHARS
 01700		ADD	TEMP,TBITS
  01800		SKIPGE	TEMP				;NOT ENOUGH?
    01900		 POPJ	 P,				;NO, OK
 02000	
  02100	SGCOL:	EXCH	SP,STPSAV	;GET STRING STACK
   02200		MOVSS	POVTAB+6	;calling seq. to .SONTP may oflow
   02300		PUSH	P,TBITS		;PASS TO STRGC THIS WAY
    02400		PUSHJ	P,STRGC	;COLLECT STRING SPACE
 02500	;;#QO# -- BE SURE PNAME STAYS TOGETHER 1-25-74 RHT
  02600		EXTERN 	.SONTP
  02700		PUSH	SP,PNAME
   02800		PUSH	SP,PNAME+1
 02900		PUSH	P,[0]
 03000		PUSHJ	P,.SONTP
  03100		POP	SP,PNAME+1
  03200		POP	SP,PNAME
    03300	;;#QO#
 03400		EXCH	SP,STPSAV	;GET IT BACK
    03500		MOVSS	POVTAB+6
  03600		POPJ	P,		; NO, GO AHEAD
   03700	NOTENX <
    03800	
  03900	?CHROUT: SOSG	LSTCNT		;ONE CHAR OUTPUT ROUTINE
 04000		PUSHJ	P,LSTDO		;DO AN OUTPUT
   04100		IDPB	TBITS,LSTPNT	;DO THE OUTPUT
    04200		POPJ	P,
    04300	
  04400	?LSTDO:	OUT	LST,
 04500		POPJ	P,
    04600		ERR	<I-O ERROR ON LISTING DEVICE>,1
 04700		POPJ	P,
    04800	>;NOTENX
    04900	TENX <
 05000	?CHROUT: EXCH	TBITS,2
 05100		EXCH	1,LISJFN
   05200		JSYS	BOUT
  05300		EXCH	1,LISJFN
   05400		EXCH	TBITS,2
    05500		POPJ	P,
    05600	>;TENX
 05700	
          00100	DSCR --HERE IS THE CREFFINF STUFF (STRANGE PLACE N'EST CE PAS?)
    00200	DES We'll leave it at these comments for the nonce:
 00300	 For those of you who are interested in what cref output looks like, allow
   00400	 me to discourse for a while on it.  Basically, the output line is
 00500	 preceeded by a whole mess of garbage. (In the following discussion,
    00600	 let # stand for delete -- octal 177).
    00700	
  00800	1. The first thing in a line with cref information in it must be
   00900		#B    .  This is handled in crefout.
01000	
  01100	2. There are two types of symbols:
   01200		a. NUMSYM's, which are represented by a six-digit number(decimal)
 01300			which is unique to that occurrance of the symbol.
 01400			The number is represented by an octal 6 (length of symbol)
  01500			followed by the number in ASCII.
   01600		b. SYMSYM's, which are the real symbolic symbols.  These consist
  01700			of one byte of length, followed by the symbol in ASCII
 01800	
  01900	3. When an identifier is seen in the source text, you do one of
    02000		several things:
 02100		1  followed by the NUMSYM -- a regular identifer seen.
  02200		3  followed by the SYMSYM -- a reserved word.
 02300		5  followed by the NUMSYM -- a macro use.
02400	  -- it is occasionally to flush the last type 1 instance.  This is done
02500	 	by following it immediately with a 7.
   02600	
  02700	4. When defining things, we put out:
 02800		1 followed by the NUMSYM followed by 2 -- ordinary identifier
02900		6 followed by NUMSYM -- macro.
 03000	
  03100	5. When beginning a block, we put out a 15 followed by the SYMSYM.
 03200	6. When ending a block, we put out a 16 followed by the SYMSYM.
    03300		Then come the equivalences of numbers and symbolic names.
    03400	7. To equivalence an ordinary symbol, we put out 11 followed by
    03500		the NUMSYM followed by the SYMSYM.
  03600	
  03700	8. When all done with the cref information for a line, we put out
  03800		#A    .
    03900	
 04000	
  04100	BEGIN CREF
  04200	
  04300	^LCREFIT: 
  04400		TDZA	C,C
   04500	^ECREFIT: MOVNI C,1		;CREF FOR ENTER.
04600		SKIPE	CNDLST		; IN FALSE PART OF CONDITIONAL COMPILATION? 
   04700		POPJ	P,		; YES, DO NOT CREF 
   04800		TLNN	TBITS,CNST	;IF A CONSTANT, FORGET IT.
    04900		TLNE	FF,NOCRFW	;AN EXTERNAL PROCEDURE -- DO NOT CREF;
   05000		POPJ	P,
    05100		MOVE	A,X11		;ORDINARY IDENTIFIER.
   05200		TLNE	TBITS,DEFINE	;IF THIS IS A MACRO.
   05300		MOVE	A,[XWD 6,5]
05400		TLNE	TBITS,400000	;RESERVED WORD?
   05500		MOVE	A,X33
 05600		TLNE	C,-1		;ENTER OR LOOKUP?
   05700		MOVSS	A
    05800		PUSHJ	P,CREFOUT	;AND PUT OUT THE CHARACTER.
   05900		PUSHJ	P,CREFSYM	;CREF THE SYMBOL IN LPSA,TBITS.
    06000		TLNN	A,-2		;IF REGULAR SYMBOL,
 06100		SKIPL	C		;BEING DEFINED,
  06200		POPJ	P,
    06300		MOVEI	A,2		;THEN PUT OUT EXTRA THING.
    06400		JRST	CREFOUT		;....
  06500	
  06600	
  06700	CREFSYM: PUSH	P,TBITS
 06800		JUMPL	TBITS,ASC1	;A RESERVED WORD ----
   06900		MOVEI	TBITS,6
   07000		PUSHJ	P,CHROUT	;NUMBER OF CHARACTERS.
    07100		MOVEI	TBITS,(LPSA)
   07200		MOVEI	PNT2,6		;FOR THE RECURSIVE NUMBER PRINTER IN SEOL.
07300	;;#MF#! 5-1-73 DCS (1 OF 2) AC B NEEDED IN CALLER OF LCREFIT
  07400		PUSH	P,B
   07500		MOVEI	B,CHROUT	;OUTPUT ROUTINE FOR SAME --
    07600		PUSHJ	P,FRNP1		;  FRNP1 IS IN SEOL ABOVE.
07700	;;#MF#! (2 OF 2) SAVE, RESTORE B
07800		POP	P,B
    07900		POP	P,TBITS
08000		POPJ	P,		;GO AWAY.
   08100	ASC1:	PUSH	P,A
   08200		PUSHJ	P,CREFASC	;ASCII CREF.....
    08300		POP	P,A
    08400		POP	P,TBITS
08500		POPJ	P,
    08600	
  08700	
  08800	CREFCHR: CAIN	A,30		;UNDERLINE
  08900		MOVEI	A,"."		;CHANGE UNDERLINE TO .
 09000	^^CREFOUT: SKIPE  LNCREF	;CREF GONE FOR THIS LINE?
  09100		JRST	GONEF		;YES
09200		SETOM	LNCREF
    09300		PUSH	P,A
   09400		MOVEI	A,177
09500		PUSHJ	P,CREFOUT
 09600		MOVEI	A,"B"
09700		PUSHJ	P,CREFOUT
 09800		POP	P,A
    09900	NOTENX <
    10000	GONEF:	SOSG	LSTCNT
    10100		PUSHJ	P,LSTDO
   10200		IDPB	A,LSTPNT
   10300		POPJ	P,
    10400	>;NOTENX
    10500	TENX <
 10600	GONEF:	EXCH	1,2
  10700		EXCH	1,LISJFN
   10800		JSYS	BOUT
  10900		EXCH	1,LISJFN
   11000		EXCH	1,2
   11100		POPJ	P,
    11200	>;TENX
 11300	
  11400	^^CREFASC:			;CREF THE ASCII FOR A SYMBOL.
11500		HRRZ	A,$PNAME(LPSA)	;COUNT.
    11600		PUSHJ	P,CREFOUT	;AND CREF...
   11700		MOVE	TEMP,A
11800		MOVE	C,$PNAME+1(LPSA)	;BYTE POINTER.
11900		ILDB	A,C
   12000		PUSHJ	P,CREFCHR
 12100		SOJG	TEMP,.-2
   12200	GPOPJ:	POPJ	P,
   12300	
  12400	^^CREFDEF:			;PUT OUT SYMBOL DEFINTION.
   12500		MOVEI	A,11		;ORDINARY SYMBOL
   12600		MOVE	TEMP,$TBITS(LPSA)
    12700		TLNE	TEMP,DEFINE
12800		MOVEI	A,13		;FOR MACRO
    12900		PUSHJ	P,CREFOUT
 13000		PUSHJ	P,CREFSYM
 13100		JRST	CREFASC		;CODE,SYMBOL,PRINT-NAME.
   13200	
  13300	^^CREFBLOCK:			;END OF A BLOCK.
 13400		MOVEI	A,16
 13500		PUSHJ	P,CREFOUT
 13600		JRST	CREFASC		;AND THE NAME.
   13700	
  13800	
  13900	BEND
   14000	
          00100	DSCR HDR, HDROV 
 00200	DES List routines for top of (physical page). Reset page,
00300	  line counters.  Print a page header if listing.
   00400	 HDR is called when new page (logical) is sensed.
   00500	 HDROV is called when PGSIZ lines have been printed
 00600	  since last time a header was printed.
   00700	SID Uses D, TEMP,USER -- saves USER, C, others vulnerable.
    00800	
 00900	
  01000	^HDR:	
 01100		AOS	PAGENO		;NEXT PAGE, PLEASE
 01200		AOS	FPAGNO		;NEXT IN THIS FILE
 01300		SETZM	PAGINC		;FIRST PHYSICAL PAGE NO
    01400		SETZM	BINLIN		;SEQUENTIAL LINE #
    01500		AOS	BINLIN		;ALWAYS STARTS AT 1
01600		MOVE	TEMP,[ASCII /00001/]
 01700		MOVEM	TEMP,ASCLIN	;SO DOES THE SUFF WHICH APPEARS ON LISTING
 01800	;;#HU# 6-20-72 DCS BETTER TTY LISTING
01900		SKIPN	CRIND		;NEED CRLF/INDENT?
02000		 JRST	 NCRIND		;NO
   02100		SETZM	CRIND
02200		TERPRI
02300	;;%CF% JFR 7-8-75
02400		SKIPA	TEMP,LININD	;HOW MANY
    02500		PUUO	1,[" "]
    02600		SOJGE	TEMP,.-1
  02700	;;%CF% ^
    02800	NCRIND:	PRINT	< >
02900		DECPNT	FPAGNO		;JUST KEEP TRACK
03000	;;%CT% warnings if in macro or false conditional scan
    03100		MOVEI	TEMP,LININD+1	;TRKMCR AND TRKMCS MUST POINT TO A STRING
03200		SKIPN	TRKMCR
    03300		 MOVEM	TEMP,TRKMCR
   03400		SKIPN	TRKMCS
    03500		 MOVEM	TEMP,TRKMCS
   03600		MOVEI	TEMP,0
    03700		TLNE	FF,PRMSCN	;SCANNING MACRO PARAMS?
   03800		 MOVEI	TEMP,[ASCIZ/macro parameters/]
    03900		SKIPE	CNDLST		;OR FALSE CONDIITIONAL?
    04000		 MOVEI	TEMP,[ASCIZ/false conditional compilation/]
 04100		JUMPE	TEMP,SEOP1	;IF OK
   04200		HRLI	TEMP,440700	;COMPLETE BYTE POINTER
  04300		MOVEI	A,[ASCIZ\
 04400	WARNING: Form-feed while scanning @A.
04500	Last source-file macro: @I  @E/@D
    04600	Current macro: @I
04700	\]
04800		MOVEI	B,-1+[	PWORD	TEMP
   04900				PWORD	@TRKMCS
 05000				PWORD	TRKM.L
  05100				PWORD	TRKM.P
  05200				PWORD	@TRKMCR]
05300		PUSH	P,C		;SAVE THIS
 05400		PUSHJ	P,SPLPRT
  05500		POP	P,C
    05600	SEOP1:
 05700	;;%CT% ^
    05800	
  05900	
  06000	NOTENX<
06100	;;%DE% JFR 10-25-75
   06200	^HDROV:	SETZM	LINNUM
  06300		AOS	PAGINC		;HERE WHEN LINES OVERFLOW PAGE
    06400		MOVE	TEMP,TTOP	;CUR BLOCK SEMBLK
    06500		MOVEI	A,TITPAT
  06600		MOVEI	B,-1+[
    06700			PWORD	IPROC+$PNAME+1	;OUTER BLOCK NAME B.P.
  06800			PWORD	SRCDEV
   06900			PWORD	SRCFIL
   07000			PLEFT	SRCEXT
   07100			PWORD	SRCPPN
   07200			PWORD	FPAGNO
   07300			PWORD	PAGINC
   07400			PWORD	$PNAME+1(TEMP)	;CURRENT BLOCK NAME B.P.
07500			PWORD	ASWITCH	;/A
   07600			PWORD	BAILON	;/B
    07700			POINT	1,SCNWRD,5;/C
 07800			PRIGHT	DFMAX	;/D
    07900			PWORD	FMTWRD	;/F
    08000			PWORD	HISW	;/H
 08100			PWORD	KOUNT	;/K
08200			PWORD	LSTSTRT	;/L
   08300			PRIGHT	PDLMAX	;/P
   08400			PRIGHT	SPMAX	;/Q
    08500			PRIGHT	PPMAX	;/R
    08600			PRIGHT	STMAXX	;/S
   08700			PWORD	OVRSAI	;/V
    08800			PWORD	WHERSW	;/W
    08900			PWORD	XTFLAG	;/X
    09000			]
    09100		PUSH	P,C
   09200		PUSH	P,D
   09300		MOVSI	C,-5*=28
  09400		MOVE	D,[IPCHAR TITLIN]
    09500	EXTERNAL SPLICE
  09600		PUSHJ	P,SPLICE
  09700		HRRZM	C,BANMAC+$PNAME	;CHAR COUNT
   09800		POP	P,D
    09900		POP	P,C
    10000	;;%DF% RHT 10-25-75
   10100		MOVE	TEMP,FMTWRD	;CHECK FORMAT BITS
 10200		TRNN	TEMP,140	; USER REQUESTED LIST OFF (40) OR NO HEADING (100)
  10300	;;%DF% ^
    10400		TLNN	FF,LISTNG	;LISTING FILE OPEN?
  10500		 POPJ	 P,		; NO
 10600		MOVE	TEMP,SCNWRD
10700		TRNE	TEMP,NOLIST	;DID SCANNER TURN LISTING OFF?
    10800		 POPJ	P,		; YES
 10900	;;%XM% ! JFR 8-22-76 WAS =5*28+4	28 IS A FUNNY OCTAL CONSTANT!
11000		MOVEI	TEMP,5*=28+4	;MAKE SURE ENOUGH ROOM REMAINS
  11100		CAMLE	TEMP,LSTCNT	;IS THERE
    11200		PUSHJ	P,LSTDO		;NOW THERE IS
   11300		MOVE	TEMP,BANMAC+$PNAME+1	;B.P.
11400		IBP	TEMP		;SKIP OPENING QUOTE
  11500		MOVEI	D,14
 11600		PUSHJ	P,HDROV1
  11700		MOVEI	D,15		;CR
 11800		MOVE	TEMP,[POINT 7,[BYTE (7) 12,15,12,42],-1]	;LF CR LF "
    11900	HDROV1:	IDPB	D,LSTPNT
 12000		SOS	LSTCNT
 12100		ILDB	D,TEMP	;CHAR FROM BANNER
  12200		CAIE	D,042
 12300		 JRST	.-4	;CONTINUE UNTIL 042 CLOSE QUOTE
12400		POPJ	P,
    12500	;;%DE% ^
    12600	>;NOTENX
    12700	
  12800	TENX<
  12900	^HDROV:	
    13000		SETZM	LINNUM
    13100		AOS	PAGINC		;HERE WHEN LINES OVERFLOW PAGE
    13200		PUSH	P,A
   13300		PUSH	P,B
   13400		PUSH	P,C
   13500		PUSH	P,D
   13600		HRROI	2,TITLIN	;DESTINATION
    13700		HRROI	1,TITTIM	;SAIL time date
 13800		SETZ	3,
    13900		JSYS	SIN		;COPY INTO MACRO BODY STRING
   14000		MOVE	1,2		;UPDATED DESTINATION
 14100		HRRZ	2,SRCJFN
   14200		SETZ	3,		
  14300		JSYS	JFNS		;FILE NAME
14400		MOVE	D,1		;UPDATED DESTINATION BYTE POINTER
   14500		MOVE	TEMP,TTOP	;CUR BLOCK SEMBLK
    14600		MOVEI	A,TITPAT	;PATTERN FOR REST OF STUFF
14700		MOVEI	B,-1+[
    14800			PWORD	FPAGNO
   14900			PWORD	PAGINC
   15000			PWORD	IPROC+$PNAME+1	;OUTER BLOCK NAME B.P.
  15100			PWORD	$PNAME+1(TEMP)	;CURRENT BLOCK NAME B.P.
15200			PWORD	ASWITCH	;/A
   15300			PWORD	BAILON	;/B
    15400			POINT	1,SCNWRD,5;/C
 15500			PRIGHT	DFMAX	;/D
    15600			PWORD	FMTWRD	;/F
    15700			PWORD	LODMOD	;/G
    15800			PWORD	HISW	;/H
 15900			PWORD	KOUNT	;/K
16000			PWORD	LSTSTRT	;/L
   16100			PRIGHT	PDLMAX	;/P
   16200			PRIGHT	SPMAX	;/Q
    16300			PRIGHT	PPMAX	;/R
    16400			PRIGHT	STMAXX	;/S
   16500			PWORD	LODDDT	;/T
    16600			PWORD	LODSDT	;/U
    16700			PWORD	OVRSAI	;/V
    16800			PWORD	WHERSW	;/W
    16900			PWORD	XTFLAG	;/X
    17000			]
    17100		MOVSI	C,-5*=28
  17200	EXTERNAL SPLICE
  17300		PUSHJ	P,SPLICE
  17400		MOVE	C,D		;UPDATED B.P.
   17500		SUBI	C,TITLIN	;rh(C) has # words
    17600		MULI	C,5		;C_4,3,2,1 or 0, rh(D)_5*#words
17700		SUBI	D,-4(C)		;rh(D)_# chars
   17800		HRRZM	D,BANMAC+$PNAME
17900	;;%DF% RHT 10-25-75
   18000		MOVE	TEMP,FMTWRD	;CHECK FORMAT BITS
 18100		TRNN	TEMP,140	; USER REQUESTED LIST OFF (40) OR NO HEADING (100)
  18200	;;%DF% ^
    18300		SKIPG	A,LISJFN	;LISTING FILE OPEN?
  18400		 JRST	NOHDR		; NO
    18500		MOVE	TEMP,SCNWRD
18600		TRNE	TEMP,NOLIST	;SCANNER TURNED LISTING OFF?
 18700		 JRST	NOHDR		;YES
    18800		HRRZI	B,14
 18900		JSYS	BOUT
  19000		MOVE	B,BANMAC+$PNAME+1	;B.P.
   19100		IBP	B		;SKIP OPENNING QUOTE
    19200		HRRZ	C,BANMAC+$PNAME	;COUNT
    19300		SUBI	C,4		;OMIT QUOTES AND 177&0
    19400		JSYS	SOUT		;DISPOSE OF IT
 19500		MOVE	B,[POINT 7,[BYTE (7) 15,12,15,12],-1]	;CRLF CRLF
   19600		MOVEI	C,4
  19700		JSYS	SOUT
  19800	NOHDR:	POP	P,D
   19900		POP	P,C
    20000		POP	P,B
    20100		POP	P,A
    20200		POPJ	P,
    20300	
  20400	;;%DE% JFR 10-25-75
   20500	DATA(TITLE LINE)
 20600	^BANMAC:0		;FAKE SEMBLK FOR BODY OF MACRO
 20700		0
20800		POINT	7,TITLIN
  20900		CNST,,STRING
    21000		0
21100	TITLIN:	BLOCK =60
21200	TITTIM:	BLOCK =10	;SAIL day time
21300	TITPAT:	ASCII  /  @D-@D   @I
    21400	@I  @BA @BB @DC @DD @BF @DG @DH @DK @BL @DP @DQ @DR @DS @DT @DU @DV @DW @DX"/
21500		BYTE (7) 177,"@",0		; 177&0=END OF MACRO
 21600	>;TENX
 21700	
  21800	
  21900	NOTENX<
22000	;;%DE% JFR 10-25-75
   22100	DATA(TITLE LINE)
 22200	^BANMAC:0		;FAKE SEMBLK FOR BODY OF MACRO
 22300		0
22400		POINT	7,TITLIN
  22500		CNST,,STRING
    22600		0
22700	TITLIN:	BLOCK =28
22800	
  22900	TITPAT:	ASCII	/"@I		/
 23000	NOTYMSHR <ASCII	/SAIL />
   23100	TYMSHR <ASCII /SAIL-TYMSHARE  />
23200		ASCII	/   dd/
   23300		ASCII	/-mon-/
   23400		ASCII	/yr   /
   23500		ASCII	/hr:mn/
   23600		ASCII	/ @F:@F.@F@G	@D-@D   /
   23700		ASCII	/
    23800	@I		@BA @BB @DC @DD @BF @DH @DK @BL @DP @DQ @DR @DS @DV @DW @DX/
   23900		BYTE (7) 042,177,"@",0	;" 177&0=END OF MACRO
  24000		0
24100	ENDDATA
24200	
  24300	;  MAKT -- PREPARE A TITLE LINE
 24400	
  24500	^MAKT: NOTYMSHR <MOVE	TEMP,[POINT 7,TITPAT+2,20]	;IDPB POINTER TO DAY OF MONTH>
   24600	TYMSHR <MOVE TEMP,[POINT 7,TITPAT+4,20]>
  24700		CALL6	C,DATE
    24800		IDIVI	C,=31		;DAY IN D
    24900		ADDI	D,1		;DAY - 1 THAT IS
25000		PUSHJ	P,MAKT.1
  25100		IDIVI	C,=12		;MONTH - 1 IN D
   25200		MOVE	D,[ASCII /-JAN--FEB--MAR--APR--MAY--JUN--JUL-/
25300			   ASCII /-AUG--SEP--OCT--NOV--DEC-/](D)
25400		AOJ	TEMP,
  25500		MOVEM	D,(TEMP)	;-mon-
25600		MOVEI	D,=64(C)	;YEAR
 25700		PUSHJ	P,MAKT.1
  25800	NOTYMSHR <MOVE	TEMP,[POINT 7,TITPAT+5]>
   25900	TYMSHR <MOVE TEMP,[POINT 7,TITPAT+7]>
26000		CALL6	C,MSTIME	;TIME IN MS
26100		IDIVI	C,=60000
  26200		IDIVI	C,=60		;MINUTES IN D
26300		EXCH	D,C		;HOURS IN D
26400		PUSHJ	P,MAKT.1
  26500		IBP	TEMP		;COLON
26600		MOVE	D,C		;MINUTES
   26700	MAKT.1:	IDIVI	D,=10
   26800		ADDI	D,"0"
 26900		IDPB	D,TEMP
27000		ADDI	D+1,"0"
    27100		IDPB	D+1,TEMP
   27200		POPJ	P,
    27300	;;%DE% ^
    27400	>;NOTENX
    27500	
  27600	
  27700	TENX <
 27800	^MAKT:
 27900		HRROI	2,TITTIM	;DEST. DESIGN. FOR ALL THAT FOLLOWS
 28000		HRROI	1,[ASCIZ /"SAIL  /]
 28100		SETZ	3,
    28200		JSYS	SIN		;MERELY COPY
    28300		MOVE	1,2		;UPDATED DEST
   28400		SETO	2,		;CURRENT TIME
    28500		SETZ	3,		;KEEP IT SIMPLE
  28600		JSYS	ODTIM		;APPEND DATE AND TIME
   28700		SETZ	2,
    28800		IDPB	2,1		;MAKE SURE ITS ASCIZ
 28900		POPJ	P,
    29000	>;TENX
 29100	
  29200	SUBTTL	ENTERS -- ENTER A SYMBOL
 29300	
          00100	DSCR ENTERS -- make new symbol entry
 00200	DES Will use existing comments, not use standard form
    00300	 ENTERS creates a block of proper type for this "ATOM", and
   00400	  installs the proper links to assure this thing can be found
 00500	  again. ENTERS can handle the following kinds of things:
00600			1. Variables -- numeric, STRING, ITEM, etc.
  00700			2. Labels
 00800			3. Procedure identifiers
 00900			4. Numeric constants
01000			5. String constants
 01100	 STEPS:
01200	 1-3: Create a block for ID. Check that level is greater
 01300	  for new symbol if old one was present (FORWARD Procedures
   01400	  are a special case). Install level, $TBITS, $PNAME; link
    01500	  to SYMTAB hash table (ptr to instr to fetch right bucket in HPNT).
    01600	  Link to current VARB structure via %RVARB, to STRRNG via
    01700	  %RSTR for STRINGC collector. Return ptr to Semantics in  NEWSYM
  01800	  (replaces ptr to found block if redefinition).
    01900	 4: Insert numeric value entry in CONST bucket. No checking
   02000	  (level, etc.) is necessary because ENTERS is called for
02100	  constants only when the lookup fails. Bucket fetching instr
 02200	  found in HPNT, new Semantics to NEWSYM.
 02300	 5: Insert new string constant entry in STRCON bucket. #4 
    02400	  arguments also apply here.
    02500	
  02600	PAR "BITS" -- the TBITS flags for the ATOM. These will be
02700	  installed in the entry. They also guide the entry process.
  02800	
  02900	"PNAME" -- String descriptor for $PNAME or String constant.
   03000	
  03100	"SCNVAL" -- value of (1st word of) numeric constant. Second
   03200	  word, if any, is the adjacent word DBLVAL.
   03300	
  03400	"HPNT"  -- The instr which when executed will load LPSA with
  03500	  the correct bucket in the right half. SHASH, NHASH set up.
  03600	
  03700	"NEWSYM" -- if 0, ptr to block matching PNAME or SCNVAL. This ptr
 03800	  is set by SCAN, STRINS, etc., using SHASH, NHASH. If -0,
    03900	  this is the first occurrence of the symbol.
  04000	
  04100	"QRCTYP" -- Record class id. ... if  not zero, put into lhs of $acno
    04200	
  04300	Also, the prodef bit in ff is used to tell if the symbol is a formal param
   04400	
  04500	RES "NEWSYM"_pointer to new block.
   04600	
  04700	SID Uses A,C, TBITS, LPSA, TEMP; alters symbol table structure
04800	
 04900	
          00100	^ENTERS:	
   00200		MOVE	TBITS,BITS	;TYPE BITS
00300		TLNE	TBITS,CNST	;CONSTANT?
00400		 JRST	 ENCNST		; YES
 00500	
  00600	; ENTER AN IDENTIFIER -- CHECK FOR RESERVED (ERROR), FORWARD
  00700	;  PROCEDURE BEING DEFINED. CHECK LEVEL VALIDITY FOR REDEFINED
00800	;  SYMBOLS
  00900	
  01000	ENIDNT:
01100		MOVE	C,LEVEL		;CURRENT LEVEL OF DEFINITION
    01200		SKIPG	LPSA,NEWSYM	;IS THIS THE FIRST OCCURRENCE?
   01300		 JRST	 BRANEW		; YES
 01400	
  01500	;;#JZ# 11-4-72 HJS (1-2) CHANGE MACRO SCOPE
    01600	;;#JZ# THIS GROUP AND THE NEXT WERE INTERCHANGED
    01700		SETCM	TEMP,$TBITS(LPSA);PREVIOUS TYPE BITS, COMPLEMENTED
01800		SKIPL	$TBITS(LPSA)	; CHECK FOR REDEFINITION OF A RESERVED WORD AS
 01900					;  AS A MACRO (HJS 11-19-72)
02000		TLNN	TBITS,DEFINE	;SPECIAL TREATMENT FOR REDEFINITION
   02100		 JRST	 NODEFN		; IT ISN'T ONE (HJS 11-19-72)
  02200	;; #LC# (1-17-73) HJS MACRO FORMAL,NOT MACRO REDEFINITION
02300		TLNE	TBITS,FORMAL	;
  02400		JRST	NODEFN		;MACRO FORMAL, NOT MACRO REDEFINTION
  02500	;; #LC#
02600		TLNN	TEMP,DEFINE	; WAS PREVIOUS DEFINITION ALSO A MACRO? 
    02700		SKIPN	REDEFN		; YES, MACRO REDEFINITION? 
02800		JRST	NODEFN		; NO, GO CHECK LEVELS 
 02900		 JRST	DFEN1		; IT IS ONE
  03000	;;#JZ# (1-2)
03100	
  03200	;;#JZ# 11-4-72 HJS (2-2) WAS INTERCHANGED WITH ABOVE
03300	NODEFN:	LDB	A,PLEVEL	;OLD LEVEL OF DEFINITION (HJS 11-19-72)
  03400		SKIPL	$TBITS(LPSA)	;IF OLD WAS RESERVED WORD, THEN OK.
  03500		CAMLE	C,A		;C=CURRENT -- MUST BE GREATER
 03600		 JRST	 OKOLD		; AND IS
    03700		CAME	C,A		;IF =, MAY BE FORWARD COMING
   03800		 ERR	 <SAIL IN LEVEL TROUBLE>,1
03900	;;#JZ# 2-2
  04000	
  04100	CHKPRC:	SETCM	A,TBITS		;NEW BITS
04200	;; SUGG BY R. SMITH LOAD A BEFORE TRNN
    04300		TRNN	TEMP,PROCED!FORWRD; MUST BE FORWARD PROCEDURE
 04400		 JRST	 ISPRC
    04500		TLO	A,OWN		;THIS IS SORT OF IRRELEVANT
   04600		TLO	TEMP,OWN
    04700		TLOE	TEMP,EXTRNL
04800		 ERR	 <DUPLICATE IDENTIFIER DECLARATION>,1,BRANEW ; ISN'T ANY GOOD!
    04900		TLC	A,INTRNL	;SHOULD BE ON (=0), TURN OFF (=1) OR ON (ERROR)
 05000		CAME	A,TEMP
05100		 ERR	 <DUPLICATE IDENTIFIER DECLARATION>,1,BRANEW ; ISN'T ANY GOOD!
    05200		MOVEM	TBITS,$TBITS(LPSA)
  05300	REC <
  05400		SKIPE	C,QRCTYP	;RECORD CLASS ID SPECIFIED
05500		HRLM	C,$ACNO(LPSA)
   05600	>;REC
  05700		PUSHJ	P,URGVRB
  05800		PUSHJ	P,RNGVRB
  05900		POPJ	P,
    06000	
  06100	ISPRC:	TRNN	TBITS,PROCED	 ;THIS SHOULD ALSO BE A PROCEDURE
    06200		 ERR	 <DUPLICATE IDENTIFIER DECLARATION FOR >,3,BRANEW
  06300	
  06400	; FORWARD PROCEDURE BEING DEFINED NOW, CHECK VALIDITY, CHANGE BITS
 06500	
  06600		TRZE	A,FORWRD 	;TO MATCH OLD(COMPLEMENTED)
    06700		TLNN	A,EXTRNL	;MAKE SURE NOT DUPLICATE EXTERNAL
    06800		 ERR	 <DUPLICATE FORWARD/EXTERNAL DECLARATION FOR >,3,NOPROG
 06900	;;#JX#2! 11-2-72 DCS ALLOW INTERNAL PROC TO OVERRIDE EXTERNAL PROC.
07000		TLON	TEMP,EXTRNL	;Turn off EXTRNL in old, but if it was on, flip
  07100		 TLC	 A,INTRNL	; INTRNL in new (will turn it off was on -- correct)
    07200	;;#JX#
 07300		CAME	A,TEMP		;CHECK MATCHING TYPES
  07400		 ERR	 <FORWARD TYPE DISAGREES>,1
    07500		TRO	TBITS,INPROG	;MARK PROCEDURE UNDER DEFINITION
  07600	;;#SD#	ADD A FLAG IF OLD IS EXTERNAL & NEW IS INTERNAL
   07700		MOVE	C,$TBITS(LPSA)	; COULD HAVE USED THE HAIR ABOVE, BUT ...
07800		SETOM	IEFLAG		;SET THE FLAG
    07900		TLNE	C,EXTRNL	;RESET IT IF OLD NOT EXTERNAL
   08000		TLNN	TBITS,INTRNL	;OR NEW NOT INTERNAL
   08100		SETZM	IEFLAG		;
 08200	;;#SD#
 08300	
  08400		MOVEM	TBITS,$TBITS(LPSA) ;STORE NEW
 08500	REC <
  08600		SKIPE	C,QRCTYP	;RECORD CLASS ID SPECIFIED
08700		HRLM	C,$ACNO(LPSA)
   08800	>;REC
  08900	NOPROG:	PUSHJ	P,URGVRB	;REMOVE FROM VARB RING
  09000		PUSHJ	P,RNGVRB	;PUT BACK ON THE END
 09100		LEFT	,%TLINK,LPSERR	;PTR TO SECOND BLOCK
 09200		LEFT	(,%TLINK)
  09300	;;#GP# DCS 2-6-72 (2-4) CHECK OLD FORMALS AGAINST ACTUAL ONES
 09400		HRRZM	LPSA,OLDPRM	;SAVE OLD FORMALS -- USED TO KILLST HERE
   09500		POPJ	P,		;FOR A BIT LATER
 09600	;;#GP# (2)
  09700	
  09800	; REDEFINITION IF NOT A PARAMETER TO A MACRO
   09900	
  10000	DFEN1:	TLNN	TEMP,FORMAL	;BITS ARE COMPLEMENTED HERE, CAN'T BE FORMAL
    10100		ERR	<DUPLICATE IDENTIFIER DECLARATION>,1
 10200		POPJ	P,		; GET OUT IF MACRO REDEFINITION AT THE SAME
    10300					;   LEVEL.  BODY IS DELETED IN DFENT IF
    10400					;   %TLINK IS NON-ZERO
 10500	
  10600	
          00100	 
 00200	; NOW CREATE A NEW BLOCK, PUT STUFF IN IT
 00300	
  00400	BRANEW:	;NO CHECKING WAS DONE
   00500	OKOLD:	;IT'S ALL OK
   00600	
  00700		GETBLK	NEWSYM		;GET A NEW BLOCK
00800	
  00900	; INSERT PNAME, BITS -- LINK TO BUCKET, STRING RING,(VARB IF ID)
   01000	
  01100		MOVE	LPSA,NEWSYM	;POINTER TO NEW BLOCK
   01200		HRROI	TEMP,PNAME+1	;GET PDP FOR POPPING DATA
  01300	
  01400		POP	TEMP,$PNAME+1(LPSA) ;STORE STUFF
01500		POP	TEMP,$PNAME(LPSA)
01600	
  01700	;CREFFING FOR THE WORLD.
   01800		TLNE	FF,CREFSW
  01900	;;#OH# -- HJS 9-24-73 DO NOT CREF MACRO FORMALS 
    02000		PUSHJ	P,[ TLNE TBITS,DEFINE ; DO NOT CREF MACRO FORMALS
 02100			    TLNN TBITS,FORMAL
    02200			    JRST ECREFIT
    02300			    POPJ P,] 
  02400	;;#OH#
 02500	
  02600		TRNN	TBITS,PROCED	;PROCEDURE?
  02700		JRST	NOPROC		;NO
02800		MOVE	PNT,LPSA
   02900		GETBLK			;SECOND PROCEDURE BLOCK
    03000		HRLM	LPSA,%TLINK(PNT) ;%TLINK PNTS TO 2D BLOCK
03100		MOVE	LPSA,PNT
   03200		TRNN	TBITS,FORTRAN	;A FORTRAN CALL?
 03300		TLNE	TBITS,EXTRNL	;OR EXTERNAL
 03400		TRO	TBITS,FORWRD	;TURN ON FORWARD.
  03500		TRNN	TBITS,FORWRD	;A FORWARD PROCEDURE?
  03600		TRO	TBITS,INPROG	;NO -- TURN ON IN PROGRESS.
  03700	NOPROC:	MOVEM	TBITS,$TBITS(LPSA) ;TYPE BITS
    03800	REC <
  03900		SKIPE	C,QRCTYP	;RECORD CLASS ID SPECIFIED
04000		HRLM	C,$ACNO(LPSA)
   04100	>;REC
  04200		SKIPE	C,SIMPSW	;IF SIMPLE
 04300		AOJA	C,FILLEV	;CLEVER TRICK TO LOAD C 0 & GO PUT IN LL
  04400		TRNN	TBITS,LABEL	;OR NOT A LABEL, DONT CARE
   04500		JRST	DOLL		;GO DO LEVELS
  04600		MOVE	C,TPROC		;PICK UP CURRENT PROCEDURE
 04700		HRRZ	C,$VAL(C)	;PICK UP PD SEMBLK
   04800		HRLM	C,$ACNO(LPSA)	;PUT AWAY FOR LABEL SEMBLK
 04900	;#HY# RHT 6-26-72 OWN WAS BEING TESTED AS A RIGHT HALF BIT
    05000	DOLL:	SKIPE	C,CDLEV		;PICK UP DISPLY LEVEL
05100	;;#IU# 8-12-72 ! RHT PREVENT EXTERNALS FROM BEING REFD (RF)
   05200		TLNE	TBITS,OWN!EXTRNL;IF NON-ZERO DISPLY LEV, BUT OWN, OK
    05300	;;#LS# RHT 2! 3-12-73 WAS GETTING TO FILLEV WITH NOD ZERO C FOR OWN&EXTERNAL
 05400		JRST	[SETZM C	;NO WORRY, ID IS AT LEVEL 0
05500			JRST FILLEV]
   05600		SKIPE	RECSW		;IF  CURRENT PROC IS RECURSVE
    05700	;#HY# RHT  HERE IS WHERE OWN WAS BEING TESTED
  05800		TRNE	TBITS,ITEM!LABEL!PROCED; YES, IF NOT ITEM,LABEL, OR PROC THEN USE
 05900					;STACK
  06000		TLNE	FF,PRODEF	;IF FORMAL USE STACK -- PRODEF SAYS WAS AN ARG LST
 06100		LSH	C,LLFLDL	;SHIFT LEVEL  T RIGHT SPOT
  06200		TRZ	C,LLFLDM
    06300		;MASK OUT LEX LEV FLD AREA
06400	FILLEV:	TDO	C,LEVEL		;PUT IN THE LEX LEVEL
06500		HRRZM	C,$SBITS(LPSA)	;LEVEL OF DEFINITION
06600	
  06700	; LINK TO BUCKET, STRING RING
   06800	
  06900		MOVEI	A,LNKRET+1	;IN-LINE "CALL"
    07000	LNK:	MOVE	B,HPNT		;WORD SET UP BY HASH
    07100		XCT	B		;THIS PICKS UP THE TIE INTO LPSA
  07200		MOVE	TEMP,NEWSYM	;POINTER TO NEW ONE
07300		HRRM	LPSA,%TBUCK(TEMP)	;LINK DOWN NEW BLOCK
   07400		HRR	LPSA,TEMP	;GET LPSA READY TO PUT BACK
07500		TLO	B,2000		;TURN ON "MOVE TO MEMORY" BIT
07600		XCT	B
 07700	LNKRET:	JRST	(A)		;ALL DONE
07800	
  07900		MOVE	LPSA,NEWSYM
08000		PUSHJ	P,RNGSTR	;PUT ON STRING RING
  08100	
  08200	
  08300	; IF NOT A CONSTANT, LINK TO VARB LIST -- RETURN
    08400	
  08500		TLNE	TBITS,CNST	;NOT ON VARB IF CONST
    08600		 POPJ	 P,		; DONE
    08700	
  08800		MOVE	LPSA,NEWSYM
08900		JRST	RNGVRB		;PUT ON VARB RING
 09000	
          00100	
  00200	Comment  Constants, String or Numeric 
  00300	
  00400	ENCNST:	TRNN	TBITS,STRING	;STRING CONSTANT?
    00500		 JRST	 ENNUMB		; NO, NUMERIC
   00600	
  00700	ENSTRNG:
    00800		MOVEI	C,0		;STRCONS ARE AT LEVEL 0
  00900		PUSHJ	P,BRANEW	;USE VARIABLE STUFF TO PERFORM THE ENTER.
01000		MOVE	LPSA,NEWSYM	;SEMANTICS OF RESULT
    01100		HLLZS	$SBITS(LPSA)	;NO LEVELS FOR STRING CONSTANTS
 01200		JRST	RNGCST		;PUT ON CONSTANT RING.
 01300	
  01400	
  01500	; NUMERIC CONSTANT
    01600	
  01700	ENNUMB:
01800		GETBLK	NEWSYM
   01900		HRROI	TEMP,DBLVAL	;STORE STUFF
 02000		POP	TEMP,$VAL+1(LPSA)
02100		POP	TEMP,$VAL(LPSA)
  02200		POP	TEMP,$TBITS(LPSA)
02300		JSP	A,LNK		;LINK TO BUCKET LIST
02400		PUSHJ	P,RNGCNM	;PUT ON CONSTANT RING
02500		POPJ	P,
    02600	
          00100	DSCR ADCINS, CREINT, CONINS
00200	CAL PUSHJ from EXECS which create constants for runtime.
 00300	PAR A contains value for CREINT, ADCINS
   00400	 SCNVAL contains value for CONINS (numeric)
    00500	 BITS contains type bits for CONINS
  00600	 PNAME string is value for CONINS (String)
00700	RES Semantics for constant (new or used) in rh of PNT
    00800	DES These routines are used to create constants, for
00900	  adjusting the stack, doing compile-time computation
    01000	  of constant expressions, providing address constants, etc.
  01100	 CONINS uses SCNVAL and BITS to make a constant of the
   01200	  proper flavor (PNAME string for String constants).
01300	 CREINT makes an Integer constant.
   01400	 ADCINS is CONINS, except it forces a new constant to be
 01500	  made (code in SCANNER does it).  It is used to provide
 01600	  unique addresses for REFERENCE calls, which might wipe
 01700	  the values out.
01800	SID All AC's except PNT preserved; lh PNT preserved.
01900	
 02000	
  02100	^ADCINS:
    02200		MOVEM	A,SCNVAL	;SPECIAL UNIQUE CONSTANT FOR
   02300		MOVE	TBITS,[XWD CNST+RECURS,0] ;ADCON MAKER
   02400		ORM	TBITS,BITS		;(CONSTANT BY REFERENCE)
 02500		JRST	CONINS		;CONTINUE
    02600	
  02700	^CREINT: MOVEM	A,SCNVAL	;CREATE AN INTEGER
02800		SKIPA	TBITS,[XWD CNST,INTEGR]
  02900	
  03000	^CONINS: MOVE	TBITS,BITS
   03100	;;#  # DCS 3-1-72
03200		TRNE	TBITS,STRING	;INSERT A STRING IF REQUESTED
    03300		 JRST	 STRINS
   03400	;;#  #
 03500		PUSH	P,NUM1		;FLAGS
  03600		PUSH	P,NUM2
03700	CINS:	MOVE	TEMP,[XWD A,CONACS] ; SAVE REGISTERS 1-12
03800		BLT	TEMP,CONACS+SBITS2-A
  03900		MOVE	LPSA,STRCON	;STRING CONSTANT BUCKET.
04000		MOVEM	TBITS,BITS
04100		XCT	-1(P)		;HASH AND LOOKUP
    04200		MOVE	TBITS,TBITS+CONACS-A
 04300		MOVEM	TBITS,BITS
04400		SKIPN	NEWSYM		;WAS IT FOUND?
   04500		XCT	(P)		;NO -- ENTERS
    04600		MOVE	TEMP,[XWD CONACS,A] ; RESTORE REGISTERS 1-12
  04700		BLT	TEMP,SBITS2
 04800		SUB	P,X22		; ADJUST STACK POINTER TO GET RID OF ROUTINE NAMES 
    04900		HRR	PNT,NEWSYM	;DO NOT CLOBBER LEFT HALF INCASE
    05000					; ADCONS ARE BEING MADE.
    05100		JRST	GETAD		; LOAD SBITS AND TBITS
  05200	
  05300	^STRINS: PUSHJ	P,STRNS1	; 
 05400		AOS	$VAL2(PNT)	; INCREMENT REFERENCE COUNT 
   05500		POPJ	P,		; 
05600	
  05700	STRNS1:	PUSH	P,STR1		;FOR STRINGS
    05800		PUSH	P,STR2
05900		MOVE	TBITS,[XWD CNST,STRING]
   06000		JRST	CINS		;GO DO IT.
06100	
  06200	NUM1:	PUSHJ	P,NHASH
   06300	NUM2:	PUSHJ	P,ENNUMB
  06400	STR1:	PUSHJ	P,SHASH
   06500	STR2:	PUSHJ	P,ENSTRNG
 06600	
  06700	ZERODATA (AC SAVE AREA FOR CONSTANT-MAKERS)
    06800	CONACS:	BLOCK SBITS2-A+1
   06900	ENDDATA
07000	
  07100	SUBTTL	HASH ROUTINES
  07200	
          00100	DSCR SHASH, NHASH -- look up symbol entries in hashed buckets.
00200	
  00300	PAR LPSA -- ptr to bucket Semblk for SHASH (since there are two).
  00400	  NHASH supplies its own.
  00500	 PNAME -- String search argument for SHASH
00600	 SCNVAL -- Numeric search argument for NHASH
   00700	
  00800	RES HPNT -- [HRRZ LPSA, bucketaddr] or [HLRZ LPSA, bucketaddr]
00900	  as explained in HPNT declaration.
  01000	 NEWSYM -- 0 if not found, else Semantics of found entity.
    01100	
  01200	SID Uses TEMP, TBITS, A, B, C, D, PNT -- Results in LPSA
 01300	SEE HPNT, NEWSYM, Bucket descriptions in main SAIL DATA area
  01400	
 01500	
  01600	^SHASH:
01700		MOVE	A,PNAME+1	;BYTE POINTER
   01800		MOVE	A,(A)		;1ST STRING WORD
   01900		HRRZ	TEMP,PNAME	;#CHARACTERS
   02000		XOR	A,TEMP		;MIX IT UP A BIT
   02100		PUSHJ	P,HASH		;COMPUTE HASH, GET POINTER, STORE IN HPNT
 02200	
  02300	Comment  Search for symbol identical to string in pname.
02400		Put pointer to it in NEWSYM if found.
    02500		Computed hash pointer is in HPNT on entry 
   02600	
  02700	SFIND:	SETZM	NEWSYM		;ASSUME NOT FOUND
    02800		HRRZ	A,PNAME		;LENGTH
02900		JUMPE	A,BUKS		;ZERO LENGTH PNAME TEST
    03000		MOVEI	B,4(A)
    03100		IDIVI	B,5		;# WORDS IN B
  03200		HRLI	PNT,D		;SET UP INDICES
    03300		HRR	PNT,PNAME+1	;BYTE POINTER TO NEW NAME
03400		HRLI	C,D
   03500		MOVE	TBITS,(PNT)	;FIRST WORD OF NEW NAME
 03600	
  03700		JRST	BUKS		;START AT THIS ONE
  03800	BUKLS:	RIGHT	,%TBUCK,,	;GO DOWN BUCKET
    03900	BUKS:		JUMPE	LPSA,NOFND		;IN CASE BUCKET WAS EMPTY
  04000			JUMPE	A,LCOMP			;ZERO LENGTH PNAME TEST
 04100			CAME	TBITS,@$PNAME+1(LPSA)	;SAME FIRST WORD?
 04200			 JRST	BUKLS		;NO , FAIL
  04300		LCOMP:	HRR	TEMP,$PNAME(LPSA)	;LENGTH OF OBJECT STRING
   04400			CAIE	A,(TEMP)	;SAME LENGTH?
   04500			 JRST	BUKLS		;NO -- FAILURE
   04600			JUMPE	A,FND		;IF BOTH LENGTH(0), ASSUME IDENTICAL
 04700			HRREI	D,-1(B)		;# WORDS-1
04800			JUMPLE	D,FND		;SAME SYMBOL, ONE WORD LONG
    04900			HRR	C,$PNAME+1(LPSA);BYTE POINTER ADDR -- INDEX
   05000	
  05100		SFNLUP:	MOVE	TEMP,@PNT
    05200			CAME	TEMP,@C		;SAME WORD?
05300			 JRST	BUKLS		;FAILURE
    05400			SOJG	D,SFNLUP	;KEEP AT IT!
    05500	
  05600	
  05700	FND:	MOVEM	LPSA,NEWSYM
05800	NOFND:	POPJ	P,
   05900	
  06000	
  06100	
  06200	; USES A,B  only -- results in LPSA
  06300	
  06400	^NHASH:	SETZM	NEWSYM		;ASSUME FAILURE
06500		MOVE	A,SCNVAL	;HASH ON 1ST WORD OF VALUE
 06600		MOVE	LPSA,CONST	; HASH TO CONST BUCKET
   06700		PUSHJ	P,HASH
    06800		MOVE	A,SCNVAL	;GET VALUES FOR COMPARISON
 06900		MOVE	B,DBLVAL
   07000	
  07100		MOVE	TEMP,BITS
  07200		TLNE	TEMP,RECURS	;WANT UNIQUE CONSTANT?
  07300		 JRST	 NOFND		; YES, SAME AS FAILURE
07400	
  07500		JRST	BUK		;START HERE
07600	BUKL:	RIGHT	,%TBUCK		;DOWN BUCKET LIST
    07700	BUK:		JUMPE	LPSA,NOFND	;BE SURE TO CHECK THE FIRST ONE
   07800			CAME	A,$VAL(LPSA)	;FIRST VALUE EQUAL?
   07900			 JRST	BUKL		;NO -- FAILURE
    08000			CAME	B,$VAL2(LPSA)	;SECOND VALUE EQUAL?
 08100			 JRST	BUKL		;NO -- FAILURE
    08200			MOVE	TEMP,BITS	;MAKE SURE TYPE IS SAME
  08300			CAME	TEMP,$TBITS(LPSA)
   08400			 JRST	 BUKL		;STILL CAN'T USE IT
   08500			JRST	FND		;OK, USE IT
    08600	
  08700		JRST	FND		;FINISH OUT
08800	
  08900	Comment  HASH routine itself --
09000	
  09100	IN:  A -- number to be hashed
   09200	     LPSA -- bucket pointer
09300	
  09400	OUT: HPNT contains an instruction which, when executed
   09500		will load LPSA with the bucket word in the RH.
09600		See LNK above for the cute way of entering
    09700		the new symbol.
 09800	
  09900	ACS: uses A, B -- results in LPSA
    10000	
  10100	
 10200	
  10300	HASH:	IDIVI	A,BUKLEN	;GET  (A mod BUKLEN)
 10400		MOVMS	B		;USE MAGNITUDE
   10500		ROT	B,-1		;DIVIDE BY TWO
  10600		ADD	LPSA,B		;ADD TO THE BUCKET POINTER
   10700		HRLI	LPSA,(<MOVE LPSA,0>)
 10800		SKIPL	B
    10900		HRLI	LPSA,(<MOVS LPSA,0>)
 11000		MOVEM	LPSA,HPNT	;AND STORE AWAY
11100		XCT	LPSA
   11200		HRRZS	LPSA		;SO THE JUMPE WILL WORK.
11300		POPJ	P,
    11400	
          00100	SUBTTL	SEMBLK Allocation Routines
    00200	DSCR BLKGET, BLKFRE -- Semblk Allocators
  00300	CAL PUSHJ via GETBLK, FREBLK macros.
 00400	
  00500	DES Routines to perform the following:
    00600	 BLKGET allocates a new 11-word Semblk.
   00700	 BLKFRE restores such a Semblk to the BLFREE storage list
00800	 SETBLK Initializes BLFREE with blocks as determined by
  00900	  determined by the area allocated in lpsbot, lpstop.
    01000	 NEEBLK	Gets more blocks when you need them
    01100	 BLKZER	Zeroes the block pointed to by LPSA
    01200	
  01300	PAR LPSA is Semblk address for BLKFRE
01400	
  01500	RES LPSA contains Semblk address from BLKGET
   01600	
  01700	SID USER used for GOGTAB by SET-&NEE- blk
 01800	 TEMP  destroyed by same
   01900	 LPSA changed by SETBLK and BLKZER, set to good thing by NEEBLK
    02000	
 02100	
  02200	ZERODATA (BLOCK-GETTER VARIABLES)
    02300	COMMENT 
   02400	BLFREE -- Semblk Free Storage List pointer.  Points to first Semblk
02500	   on list, whose first word points to next, etc. -- 0 terminates.
 02600	   Semblks are put on the list by BLKZER when allocating more, and
 02700	   by the BLKFRE (via FREBLK macro) routine.  They are removed by
  02800	   the BLKGET (via GETBLK macro) routine.
 02900	
 03000	^^BLFREE: 0
 03100	
  03200	;FRECNT -- # free blocks when enabled by FTCOUNT switch
  03300	IFN FTDEBUG, <
   03400	^^FRECNT: 0
 03500	>
 03600	
  03700	TSTALO__0		;SPECIAL TEST MODE FOR BLOCK ALLOCATOR
   03800	IFNDEF TSTALO, <TSTALO__0>
 03900	IFE TSTALO,<BLLEN__BLKLEN; ELSE>BLLEN__BLKLEN+2 ;SET TOTAL BLOCK SIZE
   04000	IFN TSTALO, <BLKUSE: 0>
    04100	ENDDATA
04200	
  04300	^SETBLK:
    04400	IFN TSTALO ,<
    04500		MOVEI	TEMP,BLKUSE-BLKLEN-1 ;initialize pointer to
  04600		HRLS	TEMP		     ;doubly-linked list of IN USE
 04700		MOVEM	TEMP,BLKUSE	     ; blocks for finding lacking FREBLKs
  04800	>;TSTALO
    04900	
  05000		MOVE	TEMP,LPSBOT
05100	SETBL1:	MOVEM	TEMP,BLFREE		;STARTING ADDRESS
   05200	GOK:	MOVEI	LPSA,BLLEN(TEMP)	;NEXT AREA
    05300		CAML	LPSA,LPSTOP		;TOO FAR?
    05400		JRST	SETD
  05500		MOVEM	LPSA,(TEMP)		;STORE THE POINTER
    05600		MOVE	TEMP,LPSA
  05700		JRST	GOK
   05800	
  05900	SETD:	SUBI	TEMP,BLLEN		;GO BACK AND
  06000		SETZM	(TEMP)			;TERMINATE LIST
 06100		POPJ	P,
    06200	
  06300	^NEEBLK:
    06400		PUSH	P,B			;NEEDED FOR CORE GETTERS
 06500		PUSH	P,C
   06600		MOVE	B,LPSBOT		;TRY TO INCREMENT THIS BLOCK
   06700		MOVEI	C,=100*BLLEN		;TRY TO INCREMENT THIS BLOCK
   06800		PUSHJ	P,CANINC		;IS IT POSSIBLE?
    06900		 JRST	 NOINC			;NO
   07000	
  07100		JRST	INCR3			;YES, GO DO IT
    07200	
  07300	NOINC:	
07400		CAIGE	C,=20*BLLEN		;WILL SETTLE FOR THIS
 07500		 JRST	 GETTOP			;NO, GET NEW BLOCK
  07600	
  07700	INCR3:	PUSHJ	P,CORINC		;EXPAND BY ALLOWABLE AMOUNT
  07800		 ERR	 <DRYROT>		;CAN'T HAPPEN
  07900		EXCH	C,LPSTOP		;OLD TOP IS NEW FREE AREA
 08000		ADDM	C,LPSTOP		;NEW UPPER LIMIT
08100		MOVE	TEMP,C			;SO LEAVE IT WHERE IT WILL BE NOTICED
08200		JRST	NEERT1			;NOW GO AND RELINK
    08300	
  08400	
  08500	GETTOP:	MOVEI	C,=100*BLLEN		;GET NEW BLOCK THIS SIZE
08600		PUSHJ	P,CORGET
  08700		 CORERR <RAN OUT OF CORE AT GETTOP>
 08800		MOVEM	B,LPSBOT		;SET LIMITS ANEW
    08900		MOVEM	B,LPSTOP
  09000		ADDM	C,LPSTOP
   09100	
  09200	NEERET:	
    09300		MOVE	TEMP,B			;PTR TO BOTTOM OF NEW
 09400	NEERT1:	POP	P,C
  09500		POP	P,B
    09600		PUSHJ	P,SETBL1		;LINK THEM UP
  09700		MOVE	LPSA,BLFREE		;SO THAT WE CAN CONTINUE
    09800		POPJ	P,
    09900	
  10000	^BLKGET: 
   10100	IFN FTDEBUG,<AOS FRECNT>
   10200		SKIPN	LPSA,BLFREE
    10300		PUSHJ	P,NEEBLK	;GET A WHOLE NOTHER SET.
  10400		MOVE	TEMP,(LPSA)
10500		MOVEM	TEMP,BLFREE	;UPDATE FREE STORAGE.
  10600	^BLKZER: SETZM	(LPSA)		;FIRST WORD
   10700		MOVSI	TEMP,(LPSA)		;ZERO THE BLOCK
  10800		HRRI	TEMP,1(LPSA)
    10900		BLT	TEMP,BLLEN-1(LPSA)
    11000	IFN TSTALO,<
11100	; ADD BLOCK TO DOUBLY-LINKED RING OF IN USE BLOCKS
  11200		POP	P,BLKLEN(LPSA) ;SAVE RET ADDR FOR HISTORY OF CALL TO BLKGET
   11300		HLRZ	TEMP,BLKUSE	;GET POINTER TO LAST BLOCK IN RING
11400		HRLM	LPSA,BLKUSE	;UPDATE SAID POINTER
    11500		HRRM	LPSA,BLKLEN+1(TEMP) ;UPDATE FOR'RD PNTR IN OLD LAST BLOCK
    11600		HRLM	TEMP,BLKLEN+1(LPSA) ;UPDATE BCK'RD PNTR IN NEW (LAST) BLOCK
  11700		MOVEI	TEMP,BLKUSE-BLKLEN-1 ;UPDATE FOR'RD PNTR IN NEW BLOCK
  11800		HRRM	TEMP,BLKLEN+1(LPSA)
  11900		JRST	@BLKLEN(LPSA)	    ;RETURN DEVIOUSLY
 12000	; ELSE >POPJ	P,
  12100	
  12200	^BLKFRE:
    12300	IFN FTDEBUG,<SOS FRECNT>
   12400		EXCH	LPSA,-1(P)		;GET ARG, SAVE LPSA
12500		MOVE	TEMP,BLFREE
12600		HRRZM	TEMP,(LPSA)		;STRINGOUT FREE STORAGE
    12700		HRRM	LPSA,BLFREE
12800	IFN TSTALO, <
    12900	; REMOVE FROM IN USE RING
  13000		MOVE	TEMP,BLKLEN+1(LPSA)	;BCK'RD,,FOR'RD
 13100		HLLM	TEMP,BLKLEN+1(TEMP)	;UPDATE BCK'RD IN NEXT TO PNT TO  PREV
   13200		MOVSS	TEMP
 13300		HLRM	TEMP,BLKLEN+1(TEMP)	;UPDATE FOR'RD IN LAST TO PNT TO NEXT
    13400	>
 13500		MOVE	LPSA,-1(P)		;GET OLD VALUE BACK
13600		SUB	P,X22
  13700		JRST	@2(P)
 13800	
          00100	SUBTTL	RNGVRB, RNGSTR, etc. -- `Ring' Linkage Routines
   00200	
  00300	
  00400	DSCR RNGSTR, RNGGEN, RNGTMP, RNGCST, RNGVRB, RNGADR, RNGCNM
   00500	PAR (Sometimes) LPSA is Semblk address
    00600	RES The Semblk is linked onto a `ring' based on a variable
    00700	 implied by the routine name.  RNGSTR uses %RSTR -- all others
00800	 use %RVARB.  The ring header variables are STRRNG, VARB, TTEMP,
   00900	 CONINT, CONSTR, ADRTAB.
   01000	DES These routines replace the RING macro -- for space efficiency.
 01100	
 01200	
  01300	^RNGDIS:MOVEI	TEMP,DISLST	;DISPLAY TEMPS
  01400		JRST	RNGGEN
01500	^RNGADR:SKIPA	TEMP,[ADRTAB]	;ADDRESS CONSTANTS
 01600	^RNGTMP:MOVEI	TEMP,TTEMP	;CORE TEMPS
 01700		JRST	RNGGEN
01800	^RNGCNM:SKIPA	TEMP,[CONINT]	;NUMERICAL CONSTANTS -- ASSUMES NEWSYM
 01900	^RNGCST:MOVEI	TEMP,CONSTR	;STRING CONSTANTS    -- ASSUMES NEWSYM
   02000		SKIPA	LPSA,NEWSYM	;GET SEMBLK FROM HERE
  02100	^RNGVRB:MOVEI	TEMP,VARB	;VARB RING
   02200	RNGGEN:	PUSH	P,A
 02300		SKIPN	A,(TEMP)	;The left half of %RVARB(Semblk) is
 02400		 JRST	 .+3		; made to point to the previous `newest'
    02500		HRRM	LPSA,%RVARB(A)	; Semblk, if one exists -- the right
02600		HRLZM	A,%RVARB(LPSA)	; half of %RVARB(Previous) points to
    02700		MOVEM	LPSA,(TEMP)	; this one -- the vase vbl (TEMP) always
   02800		POP	P,A		; indicates the new (right-hand) end
 02900		POPJ	P,		; of the list -- the oldest lh is always 0
03000	
  03100	
  03200	^RNGSTR:SKIPN	TEMP,STRRNG	;String ring linkage -- same business
    03300		 JRST	 .+3
 03400		HRRM	LPSA,%RSTR(TEMP)
03500		HRLZM	TEMP,%RSTR(LPSA)
    03600		MOVEM	LPSA,STRRNG
    03700		POPJ	P,
    03800	
          00100	
  00200	DSCR URGVRB, URGADR, URGTMP, URGCST, URGSTR
    00300	PAR LPSA is a Semblk Address
    00400	 The Header vbl is set up by calling the right routine
   00500	DES Undoes the damage done by RING
   00600	
 00700	
  00800	^URGDIS:SKIPA	TEMP,[DISLST]
00900	^URGCNM:MOVEI	TEMP,CONINT
  01000		JRST	URGGEN
01100	^URGVRB:SKIPA	TEMP,[VARB]
  01200	^URGTMP:MOVEI	TEMP,TTEMP
   01300		JRST	URGGEN
01400	^URGADR:SKIPA	TEMP,[ADRTAB]
01500	^URGCST:MOVEI	TEMP,CONSTR
  01600	URGGEN:	PUSH	P,A		;If there are no pointers in %RVARB, then
   01700		SKIPN	A,%RVARB(LPSA)	;1) The Semblk is not on the ring, or:
  01800		CAMN	LPSA,(TEMP)	;2) It is the only member, in which case its
01900		 JRST	 DOU		;   address is that of the header vbl (TEMP)
02000	ENDU:	POP	P,A		;So you get here immediately in CASE 1 above,
  02100		POPJ	P,		;   and after you've unlinked in other cases.
  02200	DOU:	TRNE	A,-1		;If there is a younger neighbor, tell him
02300		 HLLM	 A,%RVARB(A)	;   you're gone.
 02400		TRNN	A,-1		;If there is not a younger neighbor, update
  02500		 HLRZM	 A,(TEMP)	;   the header, because you were youngest.
  02600		MOVSS	A
    02700		TRNE	A,-1		;If there is an older neigbor, tell him
 02800		 HLRM	 A,%RVARB(A)	;   you're gone.
 02900		JRST	ENDU
  03000	
  03100	^URGSTR:SKIPN	TEMP,%RSTR(LPSA);Same stuff for string ring.
    03200		CAMN	LPSA,STRRNG
03300		 JRST	 DOST
03400		 POPJ	 P,
  03500	DOST:	TRNE	TEMP,-1
    03600		 HLLM	 TEMP,%RSTR(TEMP)
   03700		TRNN	TEMP,-1
    03800		 HLRZM	 TEMP,STRRNG
  03900		MOVSS	TEMP
 04000		TRNE	TEMP,-1
    04100		 HLRM	 TEMP,%RSTR(TEMP)
   04200		POPJ	P,
    04300	
          00100	SUBTTL  Mark insertion routine for counter routines
 00200	DSCR LSTOUT -- write to list file
    00300	CAL PUSHJ P,LSTOUT
    00400	PAR Reg A contains character to be listed
 00500	RES The character right justified in A is placed in the output
00600	 line of the list file.  If the last character was a CR, the character 
 00700	 is inserted before the CR.  This routine is called by the exec
    00800	 routines KOUNT1, KOUNT2, etc. to put markers in the list file
00900	 indicating where counters were placed into the object code.
  01000	SID the contents of A may be changed.
01100	
 01200	
  01300	^LSTOUT: PUSH	P,B		;SAVE B
 01400		LDB	B,LPNT		;GET PREV LAST CHAR
01500		CAIE	B,15		;IS IT A CR
    01600		JRST	.+3		;NO
   01700		DPB	A,LPNT		;YES, WIPE IT OUT
  01800		MOVEI	A,15		;AND PUT CR AFTER IT
    01900		MOVEI	B,(A)
02000		ML$CHR
02100		POP	P,B		;RESTORE B
  02200		POPJ	P,		;RETURN
02300	
  02400	
  02500	
  02600	DSCR LSTOU1 -- Write to list file
    02700	CAL PUSHJ P,LSTOU1
    02800	PAR Reg A contains character to be listed
 02900	 Reg C contains character that the char in A should follow
    03000	RES If the last character in the line matches the one in
 03100	 C, the character in A is put at the end of the line.  If
03200	 not, the char in A is placed before the last character.
 03300	 The necessity for doing this comes from the fact that some
   03400	 single character tokens are placed in the listing file before
03500	 they are parsed.
03600	SID Register A may be changed
   03700	
 03800	^LSTOU1:  PUSH	P,B		;SAVE B
03900		LDB	B,LPNT		;GET THE LAST CHAR
 04000		CAMN	B,C		;IS IT THE ONE WE WANT...
 04100		JRST	.+8		;YES, GO STORE CHARACTER
  04200		CAIGE	C,"A"		;IS THE COMPARE CHAR A LETTER
    04300		JRST	.+4		;NO
   04400		ADDI	C,"a"-"A"	;CONVERT TO LOWERCASE
04500		CAMN	B,C		;IS IT THE RIGHT THING?
   04600		JRST	.+3		;YES, GO STORE CHARACTER AND RETURN
 04700		DPB	A,LPNT		;NO, STORE NEW CHAR
04800		MOVEI	A,(B)		;THEN OLD CHARACTER
    04900		MOVEI	B,(A)
05000		ML$CHR
05100		POP	P,B		;RESTORE B
  05200		POPJ	P,		;RETURN
05300	
  05400	BEND SYM
    05500	^KILLST_KILLST
   05600	
  05700	SUBTTL	Generator Data
 05800	
  05900	
  06000	
  
