perm filename STATS[S,AIL]47 blob sn#235154 filedate 1976-09-08 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00050 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00005 00002	
C00006 00003	
C00007 00004	HISTORY
C00019 00005	For-Loop, Case Statement Variables
C00021 00006	  Descriptions of For Loop Constructs, Bit Definitions
C00026 00007	  FOR, DO, WHILE, NEEDNEXT Generators
C00030 00008
C00036 00009
C00039 00010	    (continued),  NEXT, DONE, CONTINUE
C00044 00011		
C00048 00012
C00052 00013
C00059 00014
C00061 00015	ENTLAB, TRA -- generators for label placement, Go To statements
C00064 00016	  TRAGO -- go-to-solver -- used also by RETURN code
C00067 00017
C00071 00018	CASSTR, CASEMT, CASEND, CASE1, ... -- Case Statement Generators
C00074 00019
C00078 00020
C00079 00021	↑CASE3:	SOSL	B,THISE		THE TYPE OF EXPRESSION.
C00082 00022	PROCEDURE Structure Descriptions, Data Declarations
C00086 00023	  PRDEC -- When Name is Seen
C00097 00024	  ENDPR -- when params have been seen
C00106 00025	 ENDRC -- MAIN RECORD CLASS EXEC
C00120 00026	  PRUP -- When Procedure Body's Finished -- Entry, Exit, Fixups, etc.
C00124 00027
C00126 00028
C00134 00029
C00138 00030	    RESTOR, SAVIT,MKESMT,SETF -- Subroutines for Above
C00145 00031		NOW THAT AC IS STATIC LINK, MIGHT AS WELL REMEMBER THAT FACT
C00147 00032	  TWPR1, TWPR2 -- Procedure Syntax  Twiddlers
C00148 00033	RDYCAL -- Prepare to Call Procedure
C00153 00034	  Describe CALARG
C00155 00035	  CALARG -- Pass a Parameter
C00164 00036
C00166 00037	MPPARM:				BINDING ITEMVAR PARAMETER
C00174 00038
C00179 00039	    ADRINS -- Subrt for Above -- Prepare an Address Constant (Semblk)
C00183 00040
C00186 00041
C00189 00042	  ISUCAL -- Call the Procedure, Mark Resultant Type, etc.
C00198 00043
C00203 00044	ARGFIX:
C00208 00045	RESULT -- Return (with or without value) from Procedure
C00213 00046
C00215 00047	DFVPV -- exec for default param values 
C00216 00048	 CLNSET
C00217 00049	DSCR	Execs for PRINT and CPRINT statements.
C00223 00050		BEND	PROCED
C00224 ENDMK
C⊗;
COMMENT ⊗HISTORY
AUTHOR,REASON
021  102100000046  ⊗;


COMMENT ⊗
VERSION 17-1(38) 9-20-75 BY JFR #VD P.6  STR[1 STEP 1 UNTIL N] GAVE ILL MEM REF
VERSION 17-1(37) 2-1-75 BY JFR BAIL INTERFERRENCE WITH RECORDS, P.20
VERSION 17-1(36) 1-22-75 BY RHT BUG #TV# MAKE CLASS OF PNTVAR ARGS TO BUILTINS ANYCLASS
VERSION 17-1(35) 10-26-74 BY RHT BUG #TO# FUNNY TYPED BILTIN PROCEDURES
VERSION 17-1(34) 9-26-74 BY JFR INSERT TWO  JSFIX'S  WHICH WERE OMITTED ON P. 27
VERSION 17-1(33) 9-19-74 BY JFR INSTALL BAIL
VERSION 17-1(32) 8-3-74 BY RHT FEAT BN RECORD CLASSID IN ASCIZ
VERSION 17-1(31) 7-7-74 BY RHT MANY EDITS FOR RECGC
VERSION 17-1(30) 7-7-74 
VERSION 17-1(29) 7-7-74 
VERSION 17-1(28) 6-2-74 BY RHT MAKE EXTERNAL RECORD CLASSES WORK BETTER
VERSION 17-1(27) 5-29-74 BY RHT BUG #SH# NEEDED NOUSAC WHEN PUT OUT PDA WORD
VERSION 17-1(26) 5-28-74 BY RHT BUG #SD# NEEDED MUCH HAIR WHEN EXTERNAL PROC REDECLARED AS INT
VERSION 17-1(25) 4-12-74 BY RHT ADD RECORD CRUFT
VERSION 17-1(24) 4-12-74 
VERSION 17-1(23) 4-12-74 
VERSION 17-1(22) 4-12-74 
VERSION 17-1(21) 4-12-74 
VERSION 17-1(20) 1-31-74 BY RHT BUG #QX# MUST KEEP ADEPTH HONEST IN BUG FIX JK
VERSION 17-1(19) 1-11-74 BY JRL CMU CHANGE DON'T BARF AT EXTERNAL PROC DECS INSIDE SIMPLE PROC
VERSION 17-1(18) 1-11-74 
VERSION 17-1(17) 1-11-74 
VERSION 17-1(16) 1-8-74 BY RHT BUG #QH# FIX NEEDNEXT FOREACH PROBLEM
VERSION 17-1(15) 1-8-74 
VERSION 17-1(14) 1-8-74 
VERSION 17-1(13) 1-7-74 BY JRL BUG #QG# ALLOW MATCHING PROCEDURES WITH NO PARAMETERS
VERSION 17-1(12) 12-8-73 BY JRL REMOVE SPECIAL STANFORD CHARACTERS(WHERE POSSIBLE)
VERSION 17-1(11) 10-18-73 BY RHT FEAT %AE% PASSING TYPED ITEMVARS TO UNTYPED ONES
VERSION 17-1(10) 8-19-73 BY RHT BUG #NU# TRAGO NEEDED SPECIAL TEST FOR KILL SETS
VERSION 17-1(9) 8-19-73 BY RHT BUG #NT# NEED AN ALLSTO SOONER IN PRDEC
VERSION 17-1(8) 8-16-73 BY JRL REMOVE REFERENCES TO LEAPSW
VERSION 17-1(7) 8-14-73 BY JRL FIX BAD FIX TO BUG NP
VERSION 17-1(6) 8-14-73 
VERSION 17-1(5) 8-13-73 BY RHT ARRANGE FOR ITEMVAR PARAMS TO DEFAULT PROPERLY
VERSION 17-1(4) 8-12-73 BY JRL BUG #NP# DRYROT IN MATCHING PROCEDURE WITHOUT ? PARAMETERS
VERSION 17-1(3) 7-30-73 BY RHT BUG #NI# FIXUP FOR CONTINUE IN A DO... UNTIL...
VERSION 17-1(2) 7-27-73 BY RHT BUG #NH# ADEPTH PROBLEM FOR DEFAULTS
VERSION 17-1(1) 7-27-73 
VERSION 17-1(0) 7-26-73 BY RHT **** VERSION 17 ****
VERSION 16-2(63) 7-9-73 BY JRL REMOVE ALL REFERENCES TO PATSW
VERSION 16-2(62) 6-29-73 BY RHT BUG #MY# FIX A TYPO
VERSION 16-2(61) 6-28-73 BY RHT BUGS #MX# & #MY#
VERSION 16-2(60) 6-28-73 
VERSION 16-2(59) 6-28-73 
VERSION 16-2(58) 6-28-73 
VERSION 16-2(57) 6-28-73 BY JRL BUG #MA# CONCHK SHOULD SAVE FF OVER ITS CALL
VERSION 16-2(56) 6-27-73 BY RHT BUG #MV# NEEDED AN ACCESS BEFORE A PUT
VERSION 16-2(55) 5-15-73 BY JRL BUG #MJ# FOR CODE REMOPING WRONG SEMBLK
VERSION 16-2(54) 5-12-73 BY RHT BUG #MH# DRYROT IN EPNT FROM LOOP CODE
VERSION 16-2(53) 4-25-73 BY JRL BUG #ME# DRYROT IN ENDPR FOR FORWARD MATCHING PROCEDURE
VERSION 16-2(52) 4-25-73 
VERSION 16-2(51) 3-22-73 BY RHT ADD DEFAULT PARAM VALUES
VERSION 16-2(50) 3-20-73 BY RHT ADD CODE FOR DEFAULT PARAM VALUES (ISUCAL)
VERSION 16-2(49) 3-13-73 BY RHT BUG #LQ# FWRD PROC PD SHOULD BE USED WHEN DECLARE THE PROC
VERSION 16-2(48) 3-13-73 BY JRL REMOVE REFERENCES TO WOM,SLS,GAG,NODIS
VERSION 16-2(47) 2-26-73 
VERSION 16-2(46) 2-14-73 BY JRL BUG #LL# PROTECTION OF AC CONTAINING UNBOUND IN MATCH PROC
VERSION 16-2(45) 2-12-73 BY JRL RETURN VAL OF MP NOW SAVED IN XX AREA
VERSION 16-2(44) 2-12-73 BY JRL BUG #LK# GET RID OF DRYROT AT BPOP AT END OF MATCH PROC
VERSION 16-2(43) 2-9-73 BY JRL MAKE AN ITEM PROCEDURE 
VERSION 16-2(42) 2-9-73 BY JRL BUG #LJ# LEAP SHOULD STACK EVERYTHING BEFORE PROCEDURE CALL
VERSION 16-2(41) 2-9-73 
VERSION 16-2(40) 2-9-73 
VERSION 16-2(39) 2-7-73 
VERSION 16-2(38) 2-5-73 BY JRL MOD MP'S FOR SPROUT
VERSION 16-2(37) 1-28-73 BY JRL ALLOW ?,BIND TO MPPARS OUTSIDE OF FOREACH
VERSION 16-2(36) 1-23-73 BY JRL REMOVE RESTRICTION ABOUT MP WITH SAME ACTUAL ? PAR TWICE
VERSION 16-2(35) 11-30-72 BY RHT MODIFY LOPSS TO CALL EPOLL
VERSION 16-2(34) 11-28-72 BY RHT INSERT EXEC FOR CLEANUP
VERSION 16-2(33) 11-13-72 BY RHT BUG #KD# RECURSIVE CORTMP IN ADRINS
VERSION 16-2(32) 11-11-72 BY RHT BUG #KB# BAD LPSA ENCLOBERMENT IN SYNTUP
VERSION 16-2(31) 10-21-72 BY JRL CHANGE FIX TO BUG JT
VERSION 16-2(30) 10-20-72 BY JRL BUG #JT# DON'T RELEASE SETS TO BE RETURNED BY FUNCTION
VERSION 16-2(29) 10-13-72 BY JRL SAV MP RETURN VAL OVER CALL TO STKUWD
VERSION 16-2(28) 10-3-72 BY JRL BUG #JK# SAVE AC 1 OVER CALLS TO RECLAIM VALUE SET
VERSION 16-2(27) 10-3-72 BY JRL MOVE DEF OF MPFLAG TO STATS
VERSION 16-2(26) 9-21-72 BY JRL MAKE SURE PROC FORMALS CAN BE ACCESSED
VERSION 16-2(25) 9-18-72 BY KVL TO ADD SPECIAL CHECK: REF PARAMS TO PROC ARGS OF PROCS.
VERSION 16-2(23) 9-8-72 BY JRL HANDLE ? LOCAL ITEMVARS AS PARAMETERS TO PROCS
VERSION 16-2(22) 8-23-72 BY RHT ONLY ALLOCATE PD SEMBLK IF NOT SIMPLE
VERSION 16-2(21) 8-19-72 BY JRL HANDLE ? PARAMS TO FOREACH
VERSION 16-2(20) 8-17-72 BY JRL ALTER ISUCAL TO HANDLE MATCHING PROCEDURES
VERSION 16-2(19) 7-26-72 BY RHT BUG #IS# NEEDNEXT WHILE LOOPS
VERSION 16-2(18) 7-18-72 BY RHT BUG #IP# SET VALUE PARAMS RELEASING
VERSION 16-2(17) 7-6-72 BY RHT BUG ##I#K#  FIX DL LOADING BUG IN ISSUE
VERSION 16-2(16) 7-4-72 BY RHT MAKE DONE & CONTINUE STORE TEMPS BEFORE JUMPING
VERSION 16-2(15) 7-4-72 BY RHT DONE, NEXT, &CONTINUE
VERSION 16-2(14) 6-27-72 BY JRL BUG #HZ# ARRTRAN UPSET BY LSTBIT
VERSION 16-2(13) 6-23-72 BY RHT FIX NEEDNEXT BUG
VERSION 16-2(12) 6-23-72 BY RHT FIX NEEDNEXT BUG
VERSION 16-2(11) 6-14-72 BY JRL BUGS #HR#,#HS# STRING ITEMVAR PARAMS, AND PROCS.
VERSION 16-2(10) 6-14-72 BY DCS BUG #HT# SAVE REGS, RF, RESTORE RF ON F4 SUBROUTINE CALL
VERSION 16-2(9) 6-14-72 BY RHT PUT IN DONE OUT OF FOREACH IN SIMP PROC
VERSION 16-2(8) 6-13-72 BY DCS BUG #HQ# ALLOW RETURN OF STRING ITEMVARS
VERSION 16-2(7) 6-9-72 BY RHT MAKE DONE IN FOREACH CALL ON BEXIT
VERSION 16-2(6) 5-31-72 BY JRL FIX BUG #HM# DRYROT STRING PARAMS TO MESSAGE PROCEDURES
VERSION 16-2(5) 5-24-72 BY RHT MORE GO TO SOLVING
VERSION 16-2(4) 5-24-72 BY rht  make trago look at pda of label
VERSION 16-2(3) 5-14-72 BY DCS BUG #HG# CONSTANT BOOLEANS DIDN'T WORK WITH /H
VERSION 16-2(2) 5-11-72 BY DCS BUG #GW# DON'T CALL AT COMPTIME IF WRONG #PARAMS
VERSION 16-2(1) 5-11-72 BY DCS BUG #GU# NEGAT PROBLEM WITH LIMIT OF FOR ... UNTIL
VERSION 15-6(10) 3-15-72 BY RHT FIX SIMPSW BUGS
VERSION 15-6(9) 3-10-72 BY RHT TO FIX NNEDNEXT WHILE LOOPS
VERSION 15-6(8) 3-6-72 BY RHT FIX SIMPLE BUG
VERSION 15-6(7) 3-6-72 BY RHT FIX SIMPLE PROC DECL BUG
VERSION 15-6(6) 3-6-72 BY RHT fix trago bug
VERSION 15-6(5) 3-1-72 BY DCS CALL RUNTIME FUNCS (CONST ARGS) AT COMPTIME
VERSION 15-2(4) 2-6-72 BY DCS BUG #GP# CHECK FORWARD FORMALS AGAINST THE REAL ONES
VERSION 15-2(3) 2-6-72 BY DCS BUG #FV# CASE N ... ["A"] BLEW
VERSION 15-2(2) 2-5-72 BY DCS BUG #GJ# ADD LSTON LISTING CONTROL STUFF
VERSION 15-2(1) 12-2-71 BY DCS INSTALL VERSION NUMBER

⊗;

COMMENT ⊗For-Loop, Case Statement Variables⊗
	LSTON	(STATS)
ZERODATA (LOOP/CASE STATEMENT VARIABLES)

;CASTAK -- PCNT values for each statement of a Case Statement or
;    Expression are stored here via QPUSH (CASTAK is a Q-Descriptor).
;    These are used for setting up the Case dispatch table for 
;    the statement
?CASTAK: 0

;FORLIS -- QSTACK Descriptor -- each entry is a saved FRBLK, 
;   put here when an inner Loop statement is started.  See
;   FRBLK for contents
?FORLIS: 0

;FRBLK -- Semantics of current FOR-type loop. See LOOP DSCRs
;   for details of its contents
?FRBLK: 0

;FRDO -- class index from PARSER (via AC B), telling what kind of loop
?FRDO: 0

?FRTYPE: 0	;LOOP TEMP VARIABLE

;NETTMP -- set if this is a NEEDNEXT loop -- coroutine-like code
;    must be generated
?NETTMP: 0
ENDDATA

COMMENT ⊗  Descriptions of For Loop Constructs, Bit Definitions⊗

BEGIN	LOOP
DSCR FORBG, WAIT, FRSTE, FRLOP, WHIL, DOLOOP, etc.
PRO FORBG WAIT FRSTE FRWHIL FRSTO FRLIST FRLOP WHIL DOLOOP
PRO LOPPS DOUNT DNEXT DDONE
DES These are the generators for any of the looping constructs.
  When the construct is recognized at statement level, a block
  is created and attached to the Semblk for the loop descriptor
  (FORC, WHILC, FOREACH).
 Appropriate routines are called to generate the loop header code.
 The Single routine LOPPS is called at the end of the loop range.
  It generates the return jump (and the ADD to the index variable,
  if a FOR loop) and deletes the Semblk squandered for the interim
  purposes of holding AC numbers, fixups, and the like.

 The syntactic contexts of the calls to these routines are:
   FOR IVB ←			FORBG
   SG E STEP			WAIT
   SG E UNTIL/WHILE		WAIT
   FORC LHS E STEP E UNTIL E SG	FRSTE
   FORC LHS E STEP E WHILE E SG FRWHIL
   FORC LHS E SG		FRSTO
   				FRLIST a for list seen
   				FRLOP a DO seen

   WHILE BE DO			WHIL
   DO				DOLOOP (at statement level)
   DOL S UNTIL BE DO		DOUNT

   @LOOP S END			LOPPS

   NEXT				DNEXT
   DONE				DDONE
⊗
DSCR -- Loop statement Semblk Format
RES The block that is appropriated for use holding things has the 
  following format:

  $DATA		xwd fixup to jump out,,address to jump back to.
  $DATA2	good bits word for this looping statement.
  $DATA3	fixup for any DONE's done.
  $ACNO		ac number for the FOR index
  $DATA4	xwd pointer to step,, pointer to index.
  $ADR		fixup to start of statement (after that, the actual address)
  $VAL		level of forloop start,,0
  $VAL2		pcnt for start of whole thing (used for coroutines).

 Following are good bits stored in $DATA2 for my use in sorting out
  the 10↑6 cases for FOR loops and friends:
⊗
BITDATA (FOR-LOOP SEMBLKS)
↑JSPDON←←	1	;There was a push done at some point (corout or flist)
INCNST←←	2	;Step element is constant.
INPOS ←←	4	;Step element is positive.
INONE ←←       10	;Step element is +- 1

DOUNB ←←       20	;DO <s> UNTIL <be> ;
FSTAT ←←       40	;FOR <id> ← <e> STEP <e> UNTIL <e>
LWHIL ←←      100	;WHILE <be> DO
↑FRCHS ←←      200	;FOREACH x,y ....

↑FLIST ←←      400	;For lists in progress.
↑COROUT←←     1000	;The guy is going to try to use the NEXT thing.
NOJMPS←←     2000	;There are no jumps out or back!
NOJRST←←     4000	;This is a thing without a jump out (i.e. ID←E,E do)
NOMARK←←    10000	;Do not mark index for storing on exit  -
			; either an itemvar  or it was a for step while 
			;which may clobber the index
			;  but will store it at any rate!
↑TMPUS←←    20000	;A temp was used in a for statement.  Do not allow
			;loser to jump into the for loop.
IXVAR  ←←   40000	;INDEXED VAR FOR CONTROL VAR.
DONDON  ←← 200000	;A "DONE" WAS EXECUTED IN THIS LOOP, THE CONTROL
			;VARIABLE MUST NOT BE ASSUMED CORRECT IN THE AC
			; AT LOOP END (SEE MARKIT -- DCS -- 8/2/70)

ENDDATA

COMMENT ⊗  FOR, DO, WHILE, NEEDNEXT Generators⊗

↑FRCHT:	SKIPA	TBITS,[FRCHS]	;FOREACH LIST STARTER.
↑DOLOOP:			;HERE ON START OF "DO"
	MOVEI	TBITS,DOUNB
	JRST	RECORDIT	;GO MAKE A BLOCK.

↑WHIL1:				;START OF "WHILE"
	SKIPA	TBITS,[XWD 0,LWHIL]
	
↑FORBG:				;START OF "FOR"
	MOVEI	TBITS,FSTAT
RECORDIT: PUSHJ	P,ALLSTO 	;CLEAR THE BOARDS
	HRRO	A,FRBLK		;LEFT HALF NEGATIVE.
	QPUSH	(FORLIS)	;PUSH ON THE OLD FRBLK VALUE.
	GETBLK			;AND GET A NEW ONE.
	MOVE	A,LEVEL		;RECORD THE CURRENT LEVEL.
	HRLM	A,$VAL(LPSA)	;AND SAVE.
	AOS	LEVEL		;SO THAT TRAGO WILL SEE US.
	SKIPN	NETTMP		;COROUTINE FEATURE ASKED FOR ?
	JRST	NOCORT		;NO COROUTINES TODAY.
	TRO	TBITS,COROUT!JSPDON	;MARK IT AS SO.
	TRNE	TBITS,LWHIL
	JRST	[
		MOVE	SP,LPSA		;FOR THE ROUTINE TO FOLLOW
		PUSH	P,TBITS
		PUSH 	P,LPSA
		PUSHJ	P,GTJSPR	;KNOW WE HAVE TO GET A JSP REG
		POP	P,LPSA		;RESTORE LPSA
		POP	P,TBITS
		JRST  	.+1]
	MOVE	A,PCNT		;CURRENT PC.
	HRRM	A,$VAL2(LPSA)	;AND FIXUP FOR THE JSP
	TRNE	TBITS,DOUNB	;COROUTINE DISALLOWED FORTHIS
	ERR	<NO COROUTINES HERE, PLEASE>,1
	SETZM	NETTMP		;FOR NEXT TIME. (PUN, PUN)


NOCORT:	MOVE	A,PCNT
	MOVEM	A,$DATA(LPSA)	;SAVE FOR START OF WHILE.
	MOVEM	TBITS,$DATA2(LPSA)	;STORE BITS.
	MOVEM	LPSA,FRBLK	;SAVE FOR INTERESTED PARTIES.
	MOVEM	LPSA,GENRIG	;FOR THE DOLOOP.
	TRNE	TBITS,FRCHS
	TRNN	TBITS,COROUT
	POPJ	P,
	MOVE	SP,LPSA
	PUSHJ   P,GTJSPR		;IF FOREACH COROUTINE, DO MOVEI NOW
	MOVE	LPSA,SP
	POPJ	P,

↑NEXTR:				;HE IS GOING TO ASK FOR NEXT.
	SETOM	NETTMP
	POPJ	P,

↑ENDFOR: PUSHJ	P,INIT		;FINISH OUT FOREACH CODE.
	JRST	DOL1		;NO JUMP BACK, PLEASE.


;;#NI# RHT 30-JULY-73 NEED A FIXUP FOR CONTINUES
↑CNFXP:	MOVE	SP,FRBLK	;
	HLLZ	B,$ACNO(SP)	;FIXUP TO THE TEST
	JUMPE	B,.+4		;NO FIXUP
	PUSHJ	P,ALLSTO	;
	HRR	B,PCNT		;YES FIXUP
	PUSHJ	P,FBOUT		;
	POPJ	P,
;;#NI#
↑DOUNT:				;HERE ON DO S UNTIL....
	PUSHJ	P,STIF		;GO EVALUATE BOOLEAN.
;	MOVE	B,GENRIG	;RESULTANT FIXUP.
	MOVE	SP,FRBLK
	HRR	B,$DATA(SP)
;;#HG#2! 5-14-72 DCS (3-4) TEST ENTIRE LEFT HALF OR /H WON'T WORK
	HLRE	TEMP,B		;IF LH IS -1, WE HAVE
	 AOJE	 TEMP,DONON	;   `DO S UNTIL TRUE', DO ONLY ONCE
	PUSHJ	P,FBOUT		;PUT OUT FIXUP.
	JRST	DONON		;FREE THE BLOCK, ETC.



↑WHIL:				;ALL DONE WITH A WHILE STATEMENT.
	SETZM	FRDO
	PUSHJ	P,STIF		;GO EVALUATE THE BOOLEAN EXPRESSION.
	PUSHJ	P,INIT		;GET GOOD BITS.
;	MOVE	B,GENRIG	;THE HORRID TRUTH.
	HLLM	B,$DATA(SP)	;FIXUP FOR JUMP OUT, LH -1 IF TRUE
	JRST	DOL		;GO MAKE CALLS IF NECESSARY.

↑LFOR:				;HERE FROM LEAP STUFF.
	PUSHJ	P,INIT		;GET SET UP, AND FILL UP "C";
	HRRM	PNT,$DATA4(SP)	;INDEX ... FOR WHAT IT IS WORTH.
	PUSHJ	P,ALLSTO	;STORE EVERYONE.
	TRO	C,NOMARK	;WE DO NOT MARK THE INDEX ON EXIT.
	JRST	FRS1		;GO SEE ABOUT CALLS.

↑FRSTO:				;WE HAVE SEEN A <ID> ← E , OR <ID> ← <E> DO.
	MOVEM	B,FRDO		;B HAS INDEX FROM PARSER.
	SOSL	B,THISE		;SEE WHAT KIND OF EXPRESSION
	JRST	[JUMPN B,LPFRSTO	;LEAP
		 PUSHJ	P,LEVBOL	;BOOLEAN
		 JRST .+1]
	PUSHJ	P,GETINDX	;PICK UP THE INDEX, START VALUE AND SAVE.
	PUSHJ	P,FORST		;GO DO THE STORE.
FRS1:	TRNN	C,FLIST		;IF LIST NOT GOING, THEN
	SKIPE	FRDO		;IF THIS IS THE LAST
	JRST	DOL1
	TRO	C,NOJMPS	;DO NOT EMIT ANY JUMPS.
	JRST	DOL1		;GENERATE CALLS IF NECESSARY.

↑WAIT:				;HERE ON "STEP" OR "UNTIL/WHILE"
;;#VD# JFR 9-20-75
	CAIGE	B,4		;4→TO, 5→FOR
	SKIPN	LENCNT		;NEQ 0 IMPLIES SUBSTRINGING
	JRST	.+2
	ERR	<Substringing uses TO or FOR.>,1,CPOPJ
;;#VD# ↑
	JUMPE	B,GETINDX	;FOR "STEP", JUST RECORD THE INDEX INFO.
	JUMPL	B,CPOPJ		;NOTHING DOING !
	
	CAILE	B,2		;IF NOT UNTIL/WHILE
	POPJ	P,		;GO AWAY.

				;DCS 8/16/70 CONVERT TYPE OF INCR
	MOVE	TEMP,FRBLK	;ALL INFO WE HAVE ABOUT LOOP SO FAR
	HRRZ	TEMP,$DATA4(TEMP) ;SEMANTICS OF INDEX VARIABLE
	HRR	B,$TBITS(TEMP)	;TYPE
	MOVE	PNT,GENLEF+1	;INCREMENT SEMANTICS
	GENMOV	(CONV,INSIST!GETD) ;MAKE SURE THEY MATCH
	MOVEM	PNT,GENLEF+1	;FIXUP
				;DCS 8/17/70
	PUSHJ	P,FORST		;GO HANDLE THE STORE. 
	MOVE	PNT,GENLEF+1	;INCREMENT.
	PUSHJ	P,CLEAR		;MAKE SURE OUT OF AC.
	PUSHJ	P,GETAD		;NOW GET SEMANTICS
	TLNE	SBITS,CORTMP	;IF A TEMP, THOUGH, BE SURE
	 TRO	 C,TMPUS	; NOT TO LET JUMPS COME INTO THE LOOP.
	GENMOV	(CONV,INSIST)	;B STILL LEFT OVER FROM FRSTO.
	QPUSH	(FORLIS,PNT)
	TRZ	C,INONE!INCNST!INPOS	;IN CASE WE COME THROUGH HERE THE SECOND
				;TIME WHEN PUTTING OUT FOR LISTS.
	TLNN	TBITS,CNST	;IF STEP IS CONSTANT, THEN COMPUTE SOME THINGS.
	JRST	NOCVN
	TRO	C,INCNST	;ASSERT CONSTANT.
	SKIPL	$VAL(PNT)	;SEE ABOUT VALUE.
	TRO	C,INPOS		;ASSERT POSITIVE.
	MOVM	TEMP,$VAL(PNT)	;SEE ABOUT VALUE EQUAL TO 1.
	CAIN	TEMP,1
	TRO	C,INONE		;IT IS ONE!
NOCVN:				;PLACE TO JUMP BACK TO IN ORDER TO 
				;COMPUTE LIMIT.
	HRRM	TBITS2,$DATA(SP) ;SINCE STOREB WAS DONE, NOW AC INFO IS ASSUMED
	HRLM	PNT,$DATA4(SP)	;SAVE INCREMENT.

	JRST	FINOUT		;SAVE C AND EXIT.


STJSPR:	PUSHJ	P,INIT
	TRNN	C,COROUT	;IS IT A COROUTINE ????
	POPJ	P,		;NO !!!!!!!
	HLRZ	D,$ADR(SP)	;PICK UP AC NO
	JUMPN	D,HAVAC		;IF NOT FIRST TIME, THEN GET THE AC NO NOW
GTJSPR:	PUSHJ	P,GETAN0	;GET THEE AC
	PUSHJ	P,MARKINT	;MAKE IT AN INTEGER TEMP
	HRLM	PNT,$VAL2(SP)	;SAVE THE TEMP
	HRLM	D,$ADR(SP)	;REMEMBER AC NUMBER
	HRRZ	PNT,SP		;
	EMIT	<MOVEI	JSFIX>	;
	POPJ	P,		;
HAVAC:	HLRZ	PNT,$VAL2(SP)	;PICK UP THE TEMP
	CAIN	PNT,0		;IS IT THERE
	ERR	<DRYROT AT WAIT>;NO
	GENMOV	(GET,GETD!SPAC!MRK)
	HRLM	PNT,$VAL2(SP)	;PUT IT AWAY -- NOW KNOW AC IS LOADED FOR 
				;COROUTINE CALL
	POPJ	P,


FORST:				;ROUTINE TO HANDLE THE STORES.
;;#IS# ! RHT 7-26-72 NEEDED TO BE SURE MOVEI AC,START IS DONE
	PUSHJ	P,STJSPR	;INIT, SET UP TEMP IF COROUT
	HLRZ	PNT,$DATA4(SP)	;EXPRESSION FOR START 
	HRRZ	PNT2,$DATA4(SP)	;AND INDEX.
	HLRZ	D,$ADR(SP)	;PICK UP AC FOR COROUT OR JSP
	TRNE	C,COROUT!JSPDON	;IF WE HAVE ONE
	HRROS	ACKTAB(D)	;PROTECT IT
	PUSHJ	P,FORSTO	;SPECIAL GOSTO LIKE (A LA BOLSTO)
				;THE POINT OF ALL THIS IS TO STORE ANY INCREMENT
				;CALCULATIONS DONE. (I.E. TEMPS).
				;BUT WE TRY TO KEEP START EXPR IN AC.
	CAIE	D,0		;DID WE PROTECT SOMEONE?
	HRRZS	ACKTAB(D)	;YES -- WITHDRAW PROTECTION
	PUSHJ	P,GETAD2	;GET SEMANTICS. OF INDEX
;	TLNE	SBITS2,INDXED!FIXARR
;	 TRO	 C,IXVAR	;INDEXED.
	TLNN	SBITS2,PTRAC	;IS IS INDXED (SHUDDER) ?
	JRST	.+3
	HRRZ	D,$ACNO(PNT2)
	PUSHJ	P,STORA		;GO STORE IT.
;	HLRZ	PNT,$DATA4(SP)	;STARTER VALUE IN PNT.
	PUSHJ	P,GETAD
	HRRI	FF,INSIST!INDX!POSIT!REM ;ALL THESE THINGS.
	SKIPE	D,$ACNO(SP)	;OLD DUSTY AC ?
	TRO	FF,SPAC		;YES -- AND MORE.
	HRRZ	B,TBITS2	;TO FORCE TYPE CONVERSION TO INDEX TYPE.
	GENMOV	(GET)		;MAGIC
	MOVE	TBITS,PCNT	;REMEMBER PROGRAM COUNTER.
				;(NOTE EXCHOP IN NEXT INSTR)
;;#MV# RHT USE TO BE A GENMOV PUT ONLY
	GENMOV	(ACCESS,EXCHIN)	;MARK FOR STORE -- ACTUALLY STORE IF THE
				;THING WAS INDXED.
	GENMOV	(PUT,0)		;
;;#MV#
	MOVEM	D,$ACNO(SP)	;NEW AC# IF ANY.
	MOVEM	B,FRTYPE	;SAVE TYPE FOR THIS LIST.
	POPJ	P,

GETINDX:			;PICK UP INDEX AND STARTERD....
	MOVE	SP,FRBLK	;GET CURRENT BLOCK.
	MOVE	A,GENLEF+2	;INDEX
	HRL	A,GENLEF+1	;STARTER
	MOVEM	A,$DATA4(SP)
	POPJ	P,		;DONE

COMMENT ⊗    (continued),  NEXT, DONE, CONTINUE⊗

↑FRWHILE:			;HERE ON FOR-STEP-WHILE
	MOVEM	B,FRDO		;INDEX FROM PARSER.
	PUSHJ	P,STIF		;EVALUATE THE BOOLEAN
;	MOVE	B,GENRIG	;FALSE FIXUP
	PUSHJ	P,INIT
	HLLM	B,$DATA(SP)	;FIXUP FOR JUMP OUT.
	TRNE	C,FLIST!COROUT	;ONLY IF STATEMENT BEING PUSHJ'ED TO, DO WE
	PUSHJ	P,INDXGET	;GET THE INDEX BACK IN THE RIGHT AC.
	TRO	C,NOMARK	;DO NOT MARK INDEX AC ON EXIT -- STIF STORED IT.
	JRST	DOL		;SEE ABOUT CALLING THE STATEMENT.
	
↑FRSTE:				;HERE ON FOR-STEP-UNTIL
	MOVEM	B,FRDO		;INDEX FROM PARSER.
	PUSHJ	P,INDXGET	;GET INDEX BACK IN THE AC.
	MOVE	B,FRTYPE
;;#GU# 5-11-72 DCS NEGAT BUG FIX
	GETSEM	(1)		;LIMIT
	TLNN	SBITS,NEGAT	;DO WE HAVE TO DO IT?
	 JRST	 LIMOK		; NO, GOOD
	PUSH	P,D
	GENMOV	(GET,PROTECT!INSIST!POSIT!UNPROTECT) ;GET RIGHT GUY
	POP	P,D
	JRST	NOWOK		;NOW IT'S OK
LIMOK:	GENMOV	(ACCESS,PROTECT!INSIST!UNPROTECT)    ;BLESS IT
;;#MJ SAVE CONVERTED SEMBLK FOR LATER REMOP
	MOVEM	PNT,GENLEF+1
;;#GU#
NOWOK:	TRNE	C,INCNST	;IS INCREMENT CONSTANT ?
	JRST	FRCNST		;YES -- DO OTHER THINGS.

	HRL	C,D
	PUSHJ	P,GETAN0	;WE WOULD OTHERWISE CLOBBER PROTECTED AC.
	EMIT	(MOVE USADDR!NORLC)
	MOVSI	A,(<SUB>)	;SUBTRACT INDEX-LIMIT
	TRNN	TBITS,INTEGR	;CORRECT ?
	MOVSI	A,(<FSB>)
	PUSHJ	P,EMITER	;AC NOW HAS INDEX - LIMIT.
	MOVS	PNT,$DATA4(SP)	;INCREMENT.
	EMIT	(SKIPL NOUSAC)	;SKIPL INCREMENT
	HRL	C,D		;GET AC #
	EMIT	(MOVNS NOUSAC!USADDR!NORLC)
	MOVE	A,[JUMPL NOADDR];THE JUMP OUT.
	JRST	REMTMP

FRCNST:	MOVSS	C		;BECAUSE WE NEED CONDITION BITS.
	HRRI	C,3		;CODE FOR LEQ
	TLNN	C,INPOS		;ASSUMPTION CORRECT?
	HRRI	C,5		;CODE FOR GEQ
	MOVE	A,[CAM USCOND]	;THE SUPER COMPARE INSTRUCTION.
	PUSHJ	P,EMITER
	MOVSS	C
	MOVE	A,[JRST NOUSAC!NOADDR]

REMTMP:	MOVE	TEMP,PCNT	;PROGRAM COUNTER OF THE JRST.
	HRLM	TEMP,$DATA(SP)	;SAVE IT.
	PUSHJ	P,EMITER
	MOVE	D,$ACNO(SP)	;GET BACK AC NUMBER
	MOVE	LPSA,GENLEF+1	;LIMIT
	PUSHJ	P,REMOPL	;ALL DONE WITH IT.
DOL:	TRZA	C,NOJRST	;INDICATE THAT ADD'S ARE TO BE DONE.
DOL1:	TRO	C,NOJRST	;INDICATE NOT AN ADDITIVE FOR STATEMENT.

				;NOW GENERATE CALLS TO STATEMENT IF NECESSARY.
	TRNN	C,COROUT!FLIST	;THESE ARE THE INTERESTING CASES.
	JRST	FINTO
	TRNE	C,COROUT	;COROUTINE ?
;;#QH# HACK TO FIX NEEDNEXT FOREACHES
	PUSHJ 	P, [
		TRNN	C,FRCHS		;KLUGE SINCE FOREACH IS SPECIAL
		JRST	CRCAL		;NOT FOREACH, JUST COROUTINE CALL
		PUSHJ	P,CRCAL		;CALL IT.
		HLRZ	PNT,$VAL2(SP)	;
		JUMPE	PNT,CPOPJ	;NO TEMP CELL
		HLRZ	D,$ADR(SP)
		MOVE	A,[ MOVEM ]
		JRST	EMITER ]
;;#QH#
	TRNN	C,COROUT	;IF ONLY A FOR LIST, THEN
	PUSHJ	P,FLSCAL	;CALL IT.
ENDIT:
	TRNE	C,FRCHS		;FOREACH ?
	JRST	[PUSH	P,C
		 LPCALL (FRLOOP)
		 POP	P,C
		 JRST LSTTST]
	TRNE	C,NOJRST!NOJMPS	;IF NOT ADDING LOOPING STATEMENT,
	JRST	LSTTST		;GO SEE ABOUT FIXUPS AND THINGS.
	TRNN	C,FSTAT		;IF NOT FOR STATEMENT, THEN EMIT THE JRST
	JRST	[		;BACK TO THE BEGINNING.
		 HRL	C,$DATA(SP)
		 EMIT	(JRST NOUSAC!USADDR)
		 JRST	LSTTST]

	
ADDIT:	HRRZ	D,$ACNO(SP)	;MAY HAVE BEEN MANGLED BY COROUT STUFF
				;NOW IS THE TIME TO PUT OUT THE ADDS AND THINGS.
	TRNE	C,INONE		;IS INCREMENT CONSTANT AND ONE ?
	JRST	ACCDOM		;YES
	HLRZ	PNT,$DATA4(SP)	;INCREMENT.
;;#MH# ! RHT 5-12-73 WAS GETAD BUT REALLY NEED ACCESS
	GENMOV	(ACCESS,GETD)
	MOVSI	A,(<ADD>)
	TRNN	TBITS,INTEGR	;IS THIS CORRECT ?
	MOVSI	A,(<FADR>)
	PUSHJ	P,EMITER
	MOVE	A,[JRST NOUSAC!USADDR]
	JRST	EJRT		;TO EMIT IT.

ACCDOM:	MOVE	A,[AOJA USADDR]
	TRNN	C,INPOS
	HRLI	A,(<SOJA>)
EJRT:	HRL	C,$DATA(SP)	;JUMP BACK.
	PUSHJ	P,EMITER	;EMIT IT.

LSTTST:	
	SKIPN	FRDO		;WAS THIS THE LAST ?
	JRST	FLTEST		;YES -- GO SEE ABOUT FOR LISTS.
	TRNE	C,NOJRST	;JUMPS BACK?
	JRST	FINTO
	HLLZ	B,$DATA(SP)	;FIXUP FOR JUMP OUT.
	HRRZS	$DATA(SP)	;RESTART IT.
	HRR	B,PCNT
	PUSHJ	P,FBOUT
	JRST	FINTO		;FIXUP DONE -- GO AWAY.

FLTEST: TRNE	C,NOJRST!COROUT	;IF ALREADY A JUMP OUT OR
	TRNN	C,FLIST!COROUT	;NO FOR LIST GOING AND NO COROUTINE
	JRST	STAT		; -- RECORD START OF STATEMENT.
	HRRZ	B,PCNT		;NONE -- NEED TO PUT IN JRST
	TRNE	C,COROUT	;COROUTINE??
	JRST	[ 
		HLL	B,$DATA(SP)	;FIXUP FOR THE JUMPS TO EXIT
		TLNE	B,-1		;IF ANY
		PUSHJ	P,FBOUT		;
		HRRZS	$DATA(SP)	;START OVER
		HLRZ D,$ADR(SP) ;JSP REGISTER
		GENMOVE(GET,GETD!SPAC!POSIT);
		HRLZ	D,D
		HRLI	C,1
		EMIT	<JRST NOUSAC!NORLC!USX!USADDR>
		JRST	STAT
		]
	HRLM	B,$DATA(SP)	;MAKE A FIXUP FOR JUMP OUT.
	EMIT	<JRST NOUSAC!NOADDR>
STAT:	TRNN	C,COROUT!JSPDON	;COROUTINE OR FOR LIST -- IE A JSP THING
	JRST	STAT.1		;NO
	HRLZ	B,PCNT		;PICK UP PCNT
	HLRM	B,$DATA3(SP)	;REMEMBER WHERE
	HLRZ	PNT,$VAL2(SP)	;THIS TEMP
	PUSHJ	P,REMOP		;IS NOW KAPUT
	HLRZ	D,$ADR(SP)	;PICK UP THE AC
	PUSHJ	P,MARKINT	;NEW TEMP
	HRLM	PNT,$VAL2(SP)	;SAVE IT
	TRNE	C,COROUT	;IF COROUTINE
	JRST	FINTO		;THE "START" IS AT THE END (SO SKIP RETURN WORKS)

STAT.1:	HRLZ	B,$ADR(SP)	;SAY THAT THIS IS THE START 
	HRR	B,PCNT		;THIS IS THE START OF STATEMENT.
	TLNE	B,-1
	PUSHJ	P,FBOUT
FINTO:	SKIPE	FRDO		;IF NOT LAST, THEN DON'T RECORD.
	JRST	FINOUT
	MOVEM	SP,GENRIG	;RECORD BEFORE GOING AWAY.
	MOVEM	SP,GENRIG+2	;.....
	


FINOUT:	MOVEM	C,$DATA2(SP)	;SAVE C
	POPJ	P,		;AND EXIT.

FLSCAL:	MOVE	PNT,SP		;FOR LIST CALL.
	TRO	C,JSPDON
	PUSH	P,D		;DO I REALLY NEED TO?????????
	HLRZ	D,$ADR(PNT)	;
	JUMPN	D,EMTIT
	PUSH	P,PNT
	PUSHJ	P,GETAN0	;
	PUSHJ	P,MARKINT
	HRLM	D,$ADR(SP);
	HRLM	PNT,$VAL2(SP);
	POP	P,PNT
EMTIT:
	EMIT	<JSP  JSFIX>
	POP	P,D

	POPJ	P,

CRCAL:	
	HLRZ	PNT,$VAL2(SP)	;TEMP SEMBLK
	HLRZ	D,$ADR(SP)	;AC NO
	SKIPE	TEMP,ACKTAB(D)	;WHAT IT THINKS IS THERE
	CAIN	PNT,(TEMP)	;IF NOTHING OR SAME THING
	JRST	TRISOK		;THEN DONT NEED TO 
	GENMOV	(GET,GETD!SPAC!POSIT);GET IT THERE
TRISOK:	EMIT	<JSP INDRCT>	;CALL IT 
	POPJ	P,


INIT:	MOVE	SP,FRBLK
	SKIPE	BNFG		;WANT A NAMED BLOCK??
	PUSHJ	P,FNLBK		;YES
	MOVE	C,$DATA2(SP)	;GOOD BITS WORD.
	SKIPE	FRDO		;FOR LIST (I.E. A COMMA)?
	TRO	C,FLIST		;RECORD THIS FOR ALL TIME.
	MOVE	D,$ACNO(SP)	;SET UP PRIVILEGED AC NUMBER.
	POPJ	P,

↑LOPPS:				;HERE AT END OF STATEMENT.
	PUSHJ	P,INIT
	HLLZ	B,$ACNO(SP)	;ANY "CONTINUE" FIXUPS DONE HERE
	JUMPE	B,DSTQQ
	MOVE	PNT,ACKTAB(D)	;IF (D) STILL HOLDS THE INDEX, THEN PROTECT
	HRRZ	PNT2,$DATA4(SP)	; WHAT I THINK INDEX IS
	CAIN	PNT2,(PNT)
	HRROS	ACKTAB(D)
	PUSHJ	P,ALLSTO
	HRRZS	ACKTAB(D)
	HRR	B,PCNT		;DO THE CONTINUE FIXUP NOW
	PUSHJ	P,FBOUT
DSTQQ:	PUSHJ	P,STORQQ	;STORE EVERYONET RELEVANT.
				;BUT PERHAPS NOT THE INDEX.
	SKIPLE	POLINT		;DO WE WANT POLLS INSERTED?
	PUSHJ	P,EPOLL		;YES -- CALL TO SAVE ALL REGS
	TRNE	C,FLIST!COROUT	;ANY OF THESE THINGS ?
	JRST	HARDER		;YES -- ADDS ALREADY DONE.
	PUSHJ	P,ENDIT		;SEE ABOVE -- EMIT THE ADDS.
	JRST	MARKIT		;GO MARK THE AC, EMIT JUMP FIXUPS.

HARDER:	TRNN	C,COROUT	;COROUTINE??
	JRST	[HLRZ	PNT,$VAL2(SP)
		EMIT	<JRST	NOUSAC!INDRCT>  ;NO
		PUSHJ	P,REMOP		;FLUSH IT
		JRST	MARKIT
		]
	PUSHJ	P,CRCAL		;COROUTINE CALL
	HRLZ	B,$ADR(SP)	;THE "START" IS HERE
	HRR	B,PCNT
	PUSHJ	P,FBOUT		
	HRL	C,$DATA3(SP)	;REAL START OF LOOP ADDRS
	EMIT	<JRST NOUSAC!USADDR>
	HLRZ	PNT,$VAL2(SP)	;WE DONT NEED HIM ANY MORE
	PUSHJ	P,REMOP





MARKIT:	
JUMPOUT:
;	TRNN	C,IXVAR		;IF INDEXED VAR.
;	JRST	.+3
;	PUSHJ	P,REMOPA	;CLEAR OUT AC TABLE ENTRY.
;	SETZM	ACKTAB(D)
	TRNE	C,NOMARK	;IF HE REALLY DIDN'T WANT THE THING MARKED
	PUSHJ	P,CLEARA	;WIPE OUT THE AC.
	TRNE	C,DONDON	;DID SOMEBODY JUMP OUT VIA "DONE"?
	PUSHJ	P,CLEARA	;YES, WIPE OUT AC (DCS -- 8/2/70)
JMGO:	TRNE	C,NOJMPS	;IF NO JUMPS WERE DONE,
	 JRST	 ALDON		;THEN ALL DONE
	HLL	B,$DATA(SP)	;PLACE TO JUMP OUT.
	HRR	B,PCNT		;
;;#HG#2! 5-14-72 DCS (4-4) TEST ENTIRE LEFT HALF, OR /H WON'T WORK
	HLRE	TEMP,B		;If left half is -1, 
	 AOJE	 TEMP,DONON	;   there was no JRST FALSE (BE was TRUE)
	PUSHJ	P,FBOUT		;FIXUP TO JUMP OUT.
DONON:	HLLZ	B,$DATA3(SP)	;"DONE" FIXUP
	JUMPE	B,ALDON		;THESE HAVE FINISHED.
;;#TD# ! be sure dont do a done & leave loop with stuff inac
;;	PUSHJ	P,ALLSTO
;;NOTE: COULDN'T GET THE BUG TO HAPPEN
	HRR	B,PCNT
	PUSHJ	P,FBOUT
ALDON:	FREBLK	<SP>		;GOING,
	SOS	LEVEL
POPER:	QPOP	(FORLIS)	; GOING,
	JUMPL	A,DONER		;REMOPS DONE.
	MOVE	PNT,A
	PUSHJ	P,REMOP
	JRST	POPER
DONER:	
	HRRZM	A,FRBLK		;  GOING,
	POPJ	P,		;    GONE.

↑DDONE:				;HERE ON "DONE" CONSTRUCT
	SKIPN	SP,FRBLK
	 ERR	 <"DONE" ILLEGAL OUTSIDE LOOP>,1,DDPOPJ
DONEXX:	PUSHJ	P,GOSTO		;IT IS SAME AS A GO TO
	MOVE	B,LEVEL
	HLRZ	SBITS,$VAL(SP)	;LOOP LEVEL
	MOVE	C,$DATA2(SP)	;IF FOREACH STATEMENT, GO ONE MORE TO
	TRNE	C,FRCHS		;GET OUT OF THE FAKE BLOCK
	SUBI	SBITS,1
	PUSHJ	P,TRAGO
	HRRZ	C,$DATA3(SP)	;PROTECT RH FROM EXCH
	HRL	C,PCNT
	EXCH	C,$DATA3(SP)	;CHAIN FIXUPS FOR DONE.
	MOVE	TEMP,$DATA2(SP)
	TRO	TEMP,DONDON
	TRZ	TEMP,NOJMPS
	MOVEM	TEMP,$DATA2(SP)
	EMIT	(JRST NOUSAC!USADDR)
DDPOPJ:	POPJ	P,

↑DNEXT:				;HERE ON "NEXT" CONSTRUCT
	PUSHJ	P,STORQQ
NEXTXX:	TRZ	C,NOJMPS
	HRRM	C,$DATA2(SP)

	TRNE	C,COROUT	;ONLY ALLOW IF COROUTINE
	JRST	CTCOR		;GO CALL THE COROUTINE

	ERR	<USED NEXT WITHOUT PREPARATION>,1
	POPJ	P,

CTCOR:	PUSHJ	P,CRCAL			;CALL THE COROUTINE
	PUSH	P,PCNT
	EMIT	<JRST NOUSAC!NOADDR>
	MOVE	B,LEVEL
	HLRZ	SBITS,$VAL(SP)
	MOVE	C,$DATA2(SP)	;IF FOREACH STATEMENT, GO ONE MORE TO
	TRNE	C,FRCHS		;GET OUT OF THE FAKE BLOCK
	SUBI	SBITS,1
	PUSHJ	P,TRAGO			;SOLVE THE GO TO
	HLLZ	C,$DATA(SP)		;JUMP OUT 
	HRR	C,PCNT			;FIXUP
	HRLM	C,$DATA(SP)		;
	EMIT	<JRST NOUSAC!USADDR>
	POP	P,B
	HRLZ	B,B
	HRR	B,PCNT
	PUSHJ	P,FBOUT
	HLRZ	PNT,$VAL2(SP)		;TEMP FOR COROUT VAR
	HRLZI	SBITS,INAC		;MARK IT INAC
	ORM	SBITS,$SBITS(PNT)
	HLRZ	D,$ADR(SP)		;THE ACNO
	HRRZM	D,$ACNO(PNT)
	HRRZM	PNT,ACKTAB(D)		;SAY AC IS FULL OF IT
	POPJ	P,

STORQQ:	PUSHJ	P,QQW
	SKIPA	PNT,[0]
	HRRZ	PNT,ACKTAB(D)
	HLRZ	PNT2,$VAL2(SP)	;DONT WIPE THESE OUT -- JSP TEMP
	JRST	BOLSTO

↑CNTNUE:
	SKIPN	SP,FRBLK		;FETCH FOREACH BLOCK
	ERR	<"CONTINUE" ILLEGAL OUTSIDE LOOP">,1,CCPOPJ
CONTXX:	PUSHJ 	P,GOSTO			;SAME AS A GO TO
	MOVE	B,LEVEL
	HLRZ	SBITS,$VAL(SP)		;LOOP LEVEL
	PUSHJ	P,TRAGO			;SOLVE IT
	HRL	C,PCNT			;FIXUP
	HRR	C,$ACNO(SP)		;
	EXCH	C,$ACNO(SP)		;
	EMIT	<JRST NOUSAC!USADDR>	;JUMP TO LOOP END
CCPOPJ:	POPJ	P,

↑NEXTBN:	;NEXT -- WITH BLOCK NAME
	SETOM	BNFG			;SET A FLAG FOR INIT
	PUSHJ	P,STORQQ		;
	SETZM	BNFG			;

	JRST	NEXTXX			;

ZERODATA ()
BNFG:	0				;FLAG TO TELL INIT TO FIND BLOCK NAME
ENDDATA

↑CONTBN:	;CONTINUE WITH BLOCK NAME
	PUSHJ	P,FNLBK
	JRST	CONTXX

↑DONEBN:	;DONE WITH BLOCK NAME
	PUSHJ	P,FNLBK
	JRST	DONEXX

FNLBK:	;FINDS THE NAMED LOOP BLOCK

;FIRST SEARCH FOR THE NAMED BLOCK

	MOVE	A,GENLEF
	MOVE	LPSA,$PNAME+1(A)	;THE REQUESTED NAME
	MOVE	TBITS2,PPSAV		;STACK POINTERS
	MOVE	SBITS2,GPSAV	
LKNPE:	HRRZ	C,(TBITS2)		;PARSE ENTRY
	CAME	C,%NBEG			;A BEGIN???
	JRST	CHKILL			;NO
	MOVE	TEMP,(SBITS2)		;SEM ENTRY
	CAME	LPSA,$PNAME+1(TEMP)	;SAME???
	JRST	NXTBK			;NO

;HERE CHECK NEXT THING BACK TO SEE IF A LOOP
	HRRZ	C,-1(TBITS2)		;PICK UP
	CAME	C,%DOL			;
	CAMN	C,%WHILC
	JRST	OKBNM
	CAME	C,%ASSDO
	CAMN	C,%NFORC
	JRST	OKBNM
	ERR	<"DONE", "NEXT", OR "CONTINUE" TO A BLOCK NOT THE
		BODY OF A LOOP >,1
EREXT:	SKIPE	BNFG			;FROM NEXT?
	JRST	[ POP	P,(P)		;YES, TWO MORE LEVELS IN
		POP	P,(P)
		JRST	.+1 ]
	POP	P,(P)
	POPJ	P,

OKBNM:	MOVE	SP,-1(SBITS2)		;GET THE SEMANTICS INTO SP
	POPJ	P,

CHKILL:	CAMN	C,%NPDEC		;PROCEDURE DECL
	JRST	[ ERR <ATTEMPT TO "DONE", "NEXT", OR "CONTINUE" OUT OF PROCEDURE>,1
		JRST	EREXT ]
	CAMN	C,%NBLAT
	JRST	[ ERR <ATTEMPT TO "DONE", "NEXT", OR "CONTINUE" A BLOCK
THAT I CANT FIND>,1
		JRST	EREXT]
NXTBK:	SOS	TBITS2
	SOJA	SBITS2,LKNPE



STOREB: PUSHJ P,QQW	;DO IT.
	JRST	ALLSTO	;IF NOT FOR LOOP,STORE.
	HRROS	ACKTAB(D)	;PREPARE FOR STORES.
	PUSHJ	P,ALLSTO
	HRRZS	ACKTAB(D)
	POPJ	P,

INDXGET: TLOA	FF,FFTEMP
QQW:	TLZ	FF,FFTEMP
	PUSHJ	P,INIT
	TRNN	C,FSTAT		;FOR STATEMENT?
	POPJ	P,		;NO GETTING TO BE DONE.

	MOVE	PNT,$DATA4(SP)	;INDEX.
	PUSHJ	P,GETAD
	TRNE	TBITS,STRING	;IF STRING,
	POPJ	P,		;ALL DONE.
	PUSH	P,SBITS		;SAVE.
	GENMOV	(GET,SPAC!POSIT) ;GET INDEX ......
	POP	P,TEMP		;RESTORE SBITS.
	TLNN	TEMP,INDXED!FIXARR	;IF THESE,
	 JRST	 NOIXX
	TLZ	TEMP,PTRAC!INAC	;....
	MOVEM	TEMP,$SBITS(PNT)	;RESTORE IT.
	SETZM	ACKTAB(D)		;AND....
NOIXX:	TLNN	FF,FFTEMP	;NOT IF JUST INDXGET.
	AOS	(P)		;SKIP RETURN.
	POPJ	P,

BEND	LOOP

SUBTTL Land of Labels.

COMMENT ⊗ENTLAB, TRA -- generators for label placement, Go To statements⊗

BEGIN	LABEL
DSCR ENTLAB, TRA
DES Execs for handling labels
 For now, we are dealing with labels in the obvious way.
  When in doubt, the poor loser cannot do the transfer he
  requests.  When we get more smarts, we can provide more features
  (bugs?).

 Semantic contexts:
  ILB :			ENTLAB
  GOTO ILB		TRA
SEE TRAGO DSCR, for the routine which does most of the work
 (it is also used by RETURN, LOOP code)
⊗

↑ENTLAB: PUSHJ	P,ALLSTO	;CLEAR THE BOARDS.
	GETSEM	(1)
	MOVE	LPSA,PNT
	TRZN	TBITS,FORWRD	;IT IS NO LONGER FORWARD.
	ERR	<LABEL ALREADY DEFINED:>,3
	MOVEM	TBITS,$TBITS(PNT)
	HRLZ	B,$ADR(PNT)	;FIXUP
	JUMPE	B,ENT1		;HAS NOT BEEN USED YET.
	HRR	B,PCNT
	PUSHJ	P,FBOUT		;EMIT THE FIXUP.
ENT1:	MOVE	B,PCNT
	HRRZM	B,$ADR(PNT)	;THIS IS THE ADDRESS.
	MOVE	B,LEVEL		;THE LEVEL CURRENTLY AT.
	PUSHJ	P,TRAG1		;SPECIAL -- TO GUARANTEE ACCESS.
	TLNN	FF,FFTEMP	;SUCCESSFUL ?
	ERR	<LABEL DEFINED AT LOWER LEVEL>,1
	POPJ	P,		;YES




↑TRA:	PUSHJ	P,GOSTO		;STORE EVERYONE -- HE MAY BE NEEDED
	GETSEM	(0)		;THE TARGET
	MOVE	B,LEVEL		;CURRENT LEVEL
	HLRZ	PNT2,$ACNO(PNT)	;PICK UP PDA SEMBK (MAY JUMP OUT OF PROC)
	PUSHJ	P,TRAGO		;DO THE WORK.
EMJRST:	GETSEM	(0)		;AGAIN
	MOVE	A,[JRST NOUSAC]
	JRST	EMITER		;ALL THROUGH.

COMMENT ⊗  TRAGO -- go-to-solver -- used also by RETURN code⊗

DSCR TRAGO, TRAG1 -- general complicated-jump solver
CAL PUSHJ from points within Label, Loop, RETURN code.
PAR AC B contains the LEVEL we are at.
 AC SBITS contains the level we are trying to reach.
 AC PNT2 POINTS AT TARGET PDA IF JUMP OUT OF PROC
DES TRAGO and TRAG1 search up the stack looking for syntactic
  things that may need attention. If the level comparison indicates
  putting out <ARRAY RELEASE> instructions, this is done. Note
  that we disallow jumping out of a Procedure.  Stack adjustment
  many levels deep in recursion could be messy.
 TRAG1 is called when a Label is finally defined to make sure of free
  access from the level at which the label was "declared" to the level
  at which it is finally defined.  This prohibits jumping into certain
  kinds of For Loops (those with stack problems), jumping into
  Foreach statements, jumping into Blocks with Arrays dynamically
  declared, etc.
⊗
ZERODATA(LOCAL  NAMES FOR GO TO SOLVER)
BK:	0	;SET TO SEMBLK FOR FIRST BLOCK OUT TO NEED EXITING
BL:	0	;SET TO COUNT OF BLOCKS OUT TO GO
ENDDATA

BIT2DATA (BIT DEFS FOR GOOD GO TO SOLVING BITS)
ENDDATA



TRAG1:	TLOA	FF,FFTEMP
↑TRAGO:	TLZ	FF,FFTEMP	;B HAS LEVEL OF JUMP
	LDB	C,[POINT LLFLDL,SBITS,=35]	;C HAS LEVEL OF LABEL
	SUB	B,C		;B HAS NUMBER OF BLOCKS WE MUST GO UP.
	JUMPE	B,CPOPJ		;NO BLOCKS TO GO THROUGH.
	SETZM	BK		;ZERO PLACE KEEPERS
	SETZM	BL;
	MOVE	TBITS2,PPSAV
	MOVE	SBITS2,GPSAV	;PICK UP STACK POINTESS
TOK:	HRRZ	C,(TBITS2)	;PARSE ENTRY.
	CAME	C,%DOL		;DO S UNTIL BE.
	CAMN	C,%WHILC	;WHILE BE DO...
	JRST	.+3
	CAME	C,%ASSDO	;A FOREACH LOOP ?
	CAMN	C,%NFORC	;A FOR LOOP ????



	JRST	[
		MOVE	TEMP,(SBITS2)	;SEMANTICS
		MOVE	TEMP,$DATA2(TEMP); GOOD BITS
		TRNN	TEMP,COROUT!FLIST!FRCHS
	   	JRST	LGOUP 			;NOTHING EXCITING

		TLZE	FF,FFTEMP		;LOSE IF COMING IN
		POPJ	P,
		JRST	LGOUP
		]
TRYAL:	CAMN	C,%NBEG				;MIGHT IT BE A BLOCK
	JRST	DOBLK				;TREAT IT AS A BLOCK
	CAME	C,%BLKFRC			;FOREACH THING
	JRST	TRYUP				;NO
	SKIPL	PNT,(SBITS2)			;GET SEMANTICS FOR THIS
	ERR	<DRYROT AT TRAGO -- MISSING SEM FOR FOREACH>
	SKIPN	SIMPSW
	JRST	TGI				;GO SET UP FOR BEXIT
	TLZE	FF,FFTEMP			;SIMPLE PROC, CHECK GOING IN
	POPJ	P,
	LPCALL	(FRELS)				;RELEASE THE SO AND SO
	JRST	LGOUP				;GO ON UP
DOBLK:
	SKIPL	PNT,(SBITS2)			;GET SEM
	JRST	NXPRSU				;NONE
;;#NU# RHT 8-19-73 NEEDED BETTER CHECK FOR KILL SET
	HRRZ	TBITS,$ACNO(PNT)		;CHECK SPECIAL FOR KILL SET
	JUMPN	TBITS,TGI			;IF SO, MUST BEXIT
;;#NU#
	MOVE	TBITS,$VAL(PNT)
;;#SW#
NOREC <
	TDNN	TBITS,[XWD SBSCRP,SET]		;ALLOCATIONS?
>;NOREC
REC <
	TDNN	TBITS,[XWD SBSCRP,SET!PNTVAR]	;ALLOCATIONS??
						;ALSO CHECK FOR RECORDS
>;REC
	JRST	LGOUP				;NO
TGI:	TLZE	FF,FFTEMP			;GOING IN?
	POPJ	P,				;LOSE
 MRKUP:	SKIPN	BK			;IF FIRST BACK,SAY SO
	MOVEM	PNT,BK			;THIS IS THE FIRST
	AOS	BL			;INCR COUNT
LGOUP:	SOJE	B,XBKS				;IF UP, GO PUT OUT BEXIT
TRYUP:	CAMN	C,%NPDEC			;PROC?
	JRST	JOOPR				;YES, GO JUMP OUT
NXPRSU:	SOS	SBITS2
	SOJA	TBITS2,TOK
JOOPR:	TLZE	FF,FFTEMP			;
	POPJ	P,				;OK
	PUSHJ	P,XBKS				;GET OUT OF CURRENT BLOCKS
;; #MY# (1 OF 2) RHT BE SURE PD SEMBLK WILL APPLY
	SKIPN	PNT,PNT2			;PICK UP PDA SEMBK
	ERR	<YOU CANNOT DO THIS GO TO>,1	;
;; #MY# (1 OF 2) -- USED TO BE A SIMPLE MOVE PNT,PNT2
	EMIT	(<HRRZI LPSA,NOUSAC!JSFIX>)	;HRRZI LPSA,PDAOFLABEL
;;#MY# ! (2 OOF 2) RHT ALSO FIX A TYPO IN NEXT LINE
	LDB	C,[POINT LLFLDL,SBITS,=35]	;PICK UP LEX LEV OF LABEL
	MOVSS	C				;FOR EMITER
	EMIT	<HRLI LPSA,NOUSAC!USADDR!NORLC>	;HRLI LPSA,LL
	XCALL	<STKUWD>			;CALL THE STACK UNWINDER
	POPJ	P,				;ALL DONE
XBKS:	SKIPN	B,BK				;ANY TO EXIT
	POPJ	P,				;NO
	HLLZ	C,$SBITS(B)
	HRR	C,PCNT
	HRLM	C,$SBITS(B)
	EMIT	<HRRZI LPSA,NOUSAC!USADDR>
	SOSG	B,BL
	JRST	BEXCL
	HRLZI	C,(B)
	EMIT	<HRLI	LPSA,NOUSAC!NORLC!USADDR>	; IF NEED, LOAD A COUNT
BEXCL:	XCALL	<BEXIT>				;EXIT THE BLOCK
	POPJ	P,







BEND	LABEL

SUBTTL	Case Statement Generators.

COMMENT ⊗CASSTR, CASEMT, CASEND, CASE1, ... -- Case Statement Generators⊗

BEGIN	CASE
DSCR CASSTR, CASEMT, CASEND, CASE1, etc.
PRO CASSTR CASEM1 CASEMT CASEN1 CASEND CASE1 CASE2 CASE3
DES EXECS for generating case statement code.  The expression
  generated is compared to the numcode. The generated code:
 1. compares index into the statements to number of statements.
 2. calls an error routine (run-time) if something is fishy.
 3. does an indexed jrst to dispatch to the right statement.

The syntactic contexts are:
CASE E OF drarrow  CASEX		CASSTR
CASEX S drarrow  CASEX		CASEMT
CASEX [ E ] S ; drarrow  CASEX		CASEM1
CASEX S END drarrow  S			CASEMT CASEND
CASEX [ E ] S END drarrow  S		CASEM1 CASEN1
CASEX ( drarrow CASEE			CASE1	;EXPRESSION CASE STATEMENT
CASEE E , drarrow  CASEE		CASE2	; "
CASEE E ) drarrow  E			CASE2, CASE3
⊗

COMMENT ⊗ The CASE SEMBLK has the following form:
%TLINK -- saved version of CASTAK (from prev level)
$PNAME,+1 -- standard
$TBITS -- standard in CASE expression
$SBITS -- level as usual
$ADR (both halves), $ACNO (lh)  used for fixups
$VAL -- lowest case # seen,,highest seen
$VAL2 -- 0 if no S's seen, >0 if old style, <0 if new style
⊗

↑CASSTR: 			;START OF CASE CONDITIONS
	GETSEM	(1)		;SEMANTICS OF THE EXPRESSION.
	MOVE	PNT2,PNT	;MAKE SURE BOTH ARE VALID
	PUSHJ	P,BOLSTO	;STORE ALL BUT INDEX
	GENMOV	(GET,INSIST!INDX!POSIT,INTEGR)
	MOVE	A,[SKIPL NOUSAC]
	PUSHJ	P,EMITER
	PUSHJ	P,REMOP		;ALL DONE.
	GETBLK	<GENRIG>	;FOR CASE STATEMENT TEMPORARIES.
	MOVEW	(<%TLINK(LPSA)>,CASTAK);SAVE OLD CASTAK
	SETZM	CASTAK		;AND START A NEW ONE
	MOVE	A,PCNT
	HRLM	A,$ADR(LPSA)	;FIXUP FOR THE COMPARE, WHICH FOLLOWS.
	MOVE	A,[CAIL NOADDR]
	PUSHJ	P,EMITER
	XCALL	<CSERR>
	MOVE	A,[JRST @USX+NOADDR+NOUSAC]
	MOVSS	D
	PUSHJ	P,EMITER
	QPUSH	(CASTAK,PCNT)	;SAVE ON GENERALIZED STACK THE STATEMENT
	POPJ	P,



↑CASE1:	GETSEM	(1)		;CASEX SEMANTICS.
	PUSHJ	P,GETAC		;RESERVE AN ACCUMULATOR.
	MOVEM	D,$ACNO(PNT)	;REMEMBER IT.
	MOVEM	PNT,GENRIG
	POPJ	P,


↑CASE2:	MOVEM	B,THISE
	SOJL	B,.+3
	JUMPN	B,LPCS2		;..LEAP..
	PUSHJ	P,LEVBOL	;.....
	MOVE	SP,GENLEF+2	;CASEE SEMANTICS.
	MOVE	D,$ACNO(SP)	;RESERVED AC.
	GETSEM	(1)		;THE EXPRESSION.
	SKIPN	B,$TBITS(SP)	;TYPE FOR THE EXPRESSION.
	HRRZ	B,TBITS
	MOVEM	B,$TBITS(SP)	;NOW IT HAS SOME IF NOT BEFORE.
	HRRI	FF,INSIST!REM	;FOR GENMOV -- REMOP SO ALLSTO WON'T SEE IT.
	TRNE	B,STRING	;SPECIAL FOR A STRING.
	JRST	[GENMOV (STACK)
 		 MOVNI	A,2
		 ADDM	A,SDEPTH  ;FIX UP THE STACK
		 JRST CAS22]
	TRO	FF,SPAC!POSIT
	GENMOV	(GET)

CAS22:
	JRST	CASEMT
				;EMIT JRST TO END OF CASE STATEMENT

; CASE N OF BEGIN [E]S; [E]S; ... [E] S END;

↑CASEM1: GETSEM	(5)		;SEMANTICS OF CASEX
	SKIPLE	TEMP,$VAL2(PNT);LEGAL TO EXPLICITLY NUMBER?
	 ERR	 <TOO LATE TO START NUMBERING CASES>,1 ;NO
	JUMPL	TEMP,NOTFST	;NOT FIRST
	HRROS	$VAL(PNT)	;SMALLEST SEEN IS VERY LARGE
	SETOM	$VAL2(PNT)	;LEGAL TO EXPLICITLY NUMBER
NOTFST:	GETSM2	(3)		;SEMANTICS OF `E'
	TLNN	TBITS2,CNST	;MUST BE CONSTANT
	 ERR	 <CASE NUMBER MUST BE NON-NEGATIVE INTEGER CONSTANT>,1
;;#FV# DCS 2-6-72 (1-1) CASE N OF BEGIN ["A"] DIDN'T WORK
	GENMOV	(CONV,EXCHIN!INSIST!EXCHOUT,INTEGR);A REASONABLE CONST.
;;#FV# (1-1)
	SKIPGE	TBITS2,$VAL(PNT2);NON-NEGATIVE?
	 ERR	 <CASE NUMBER MUST BE NON-NEGATIVE INTEGER CONSTANT>,1
	QPOP	(CASTAK)	;GET PTR 1ST WD PREV STATEMENT
	HRL	A,TBITS2	;CASE # 
	QPUSH	(CASTAK)	;NOW CORRECT ENTRY
	JRST	CASSDO		;CONTINUE

;CASE N OF BEGIN S; S; S; S; ... S END;

↑CASEMT:GETSEM	(2)
	SKIPGE	$VAL2(PNT)	;LEGAL TO IMPLICITLY NUMBER?
	 ERR	 <EXPLICIT CASE NUMBER REQUIRED>,1
	HRRZM	PNT,$VAL2(PNT) ;GT 0 MEANS IMPLICIT NUMBERING
	AOS	TBITS2,$VAL(PNT);NUMBER SEEN
CASSDO:	PUSHJ	P,ALLSTO	;STORE ALL
	MOVE	A,[JRST NOUSAC+JSFIX]
	PUSHJ	P,EMITER
	HRL	A,TBITS2	;GET CURRENT NUMBER
	HRR	A,PCNT		;AND PC
	QPUSH	(CASTAK)	;SAVE
CASDO2:	HLRZ	TEMP,$VAL(PNT);LOWEST SEEN YET
	CAMGE	TBITS2,TEMP	;THIS ONE LOWER?
	HRLM	TBITS2,$VAL(PNT);YES, THEN NO
	HRRZ	TEMP,$VAL(PNT)
	CAMLE	TBITS2,TEMP	;SAME FOR UPPER
	HRRM	TBITS2,$VAL(PNT)
	POPJ	P,




↑CASEMM:GETSEM (4)	;SEMANTICS OF CASEX
	SKIPLE TEMP,$VAL2(PNT)
	 ERR <TOO LATE TO START NUMBERING CASES>,1	;ERR
	JUMPL TEMP,NOTFS2
	HRROS $VAL(PNT)	;SEE CASEM1
	SETOM $VAL2(PNT)
NOTFS2:	GETSM2 (2)
	TLNN TBITS2,CNST
	 ERR <CASE NUMBER MUST BE NON-NEGATIVE INTEGER CONSTANT>,1
	GENMOV(CONV,EXCHIN!INSIST!EXCHOUT,INTEGR)
	SKIPGE TBITS2,$VAL(PNT2)
	 ERR <CASE NUMBER MUST BE NON-NEGATIVE INTEGER CONSTANT>,1
	QPOP (CASTAK)
	HRL A,TBITS2
	QPUSH (CASTAK)
	QPUSH (CASTAK)
	JRST CASDO2

     
↑CASE3:	SOSL	B,THISE		;THE TYPE OF EXPRESSION.
	JRST	[JUMPN B,LPCS3
		 PUSHJ	P,LEVBOL
		 JRST .+1]
	MOVE	PNT,GENLEF+2	;CASEE
	MOVE	D,$ACNO(PNT)	;RESERVED AC.
	GENMOV	(MARK,GETD)	;MAKE A TEMP (TBITS IS MAGICALLY SET UP
	MOVEM	PNT,GENRIG  	;MARK THE EXPRESSION.
	MOVEI	A,2
	TRNE	TBITS,STRING
	ADDM	A,SDEPTH	;UNDO THE DAMAGE
				;FALL THROUGH TO EMIT JRSTS.

↑CASEND:GETSEM	(2)		;CASEX SEMANTICS
	JRST	CASENS
↑CASEN1: GETSEM	(5)		;CASEX SEMANTICS.
CASENS:	HRRZ	B,$VAL(PNT)	;COUNT OF STATEMENTS.
	SKIPG	$VAL2(PNT)	;RANDOM NUMBERING?
	ADDI	B,1		;YES, BE COMPATIBLE (CAIL)
	MOVE	TBITS2,PCNT	;CURRENT PC
	ADDI	TBITS2,(B)	; + # STATEMENTS IS OUT ADDR
	HLL	B,$ADR(PNT)	;FIXUP FOR THE CAIL
	PUSHJ	P,FIXOUT	;DO NOT RELOCATE THE FIXUP.
	ADD	B,[XWD 2,0]
	HRR	B,PCNT
	PUSHJ	P,FBOUT		;FIXUP FOR INDEXED JRST.
	HRRZS	$VAL(PNT)	;XWD 0,LAST STMT
	SKIPL	$VAL2(PNT)	;RANDOM NUMBERING?
	 SOS	 $VAL(PNT)	; NO, ONE TOO BIG
	MOVEI	LPSA,CASTAK	;SET FOR QSTACK OPS
	TDZA	C,C		;C←0, ALWAYS QBEG ONCE
CELUP:	SKIPGE	$VAL2(PNT)	;EXPLICIT NUMBERING
	PUSHJ	P,BBEG		; YES, ALWAYS START AT HEAD
	JUMPE	B,CLD		;NO QSTACK
	CAMLE	C,$VAL(PNT)	;DONE?
	 JRST	 CLD		; YES
CEILUP:	HRRZ	A,TBITS2	;IN CASE NO SUCH ENTRY
	PUSHJ	P,QTAK		;GET NEXT
	 JRST	 RNDM		; NO SUCH NUMBER, USE OUT ADDR
	HLRZ	TEMP,A		;CASE # THIS STATEMENT
	CAME	C,TEMP		;THERE YET?
	 JRST	 CEILUP		; NOPE
	HRRZS	A		;YEP, THIS ADDR
RNDM:	TLO	FF,RELOC
	PUSHJ	P,CODOUT	;WRITE DISPATCH ADDR
	AOJA	C,CELUP		;GET NEXT
CLD:	QFLUSH	(CASTAK)	;DELETE STACK
	MOVEW	(CASTAK,<%TLINK(PNT)>);RESTORE OLD ONE
	HRR	B,PCNT		;FIXUP OUT JUMPS
	HRL	B,$ADR(PNT)
	MOVE	LPSA,PNT
	PUSHJ	P,URGSTR	;IF CASE STATEMENT, NAMED
	FREBLK	(PNT)
	JRST	FBOUT		;AND RELEASE CASEX SEMBLK
BEND CASE

SUBTTL	Procedure Declarations.
BEGIN PROCED

COMMENT ⊗PROCEDURE Structure Descriptions, Data Declarations⊗

DSCR PRDEC -- name and type known, prepare for proc
PRO PRDEC
DES
  PD0:	PDEC @I (  drarrow   PDEC   EXEC  PRDEC CLRSET  SCAN  ¬DS1
	PDEC @I ;  drarrow   PDEC   EXEC  PRDEC ENDDEC  SCAN  ¬DS1

Procedure declaration.  This routine has three parts:
1.  Save status -- Temp ring, TTOP, TPROC
2.  Initialize status -- VARB, ADEPTH, SDEPTH, FORMFX stack, TPROC, TTOP.
	Down a text level, set FF bits for parameter scan
3.  Output necessary code for beginning of procedure (if not FORWRD).
    An ENTER has already been done for the symbol (semantics in NEWSYM). 

SEMBLK descriptions for procedure Semantics
%TLINK pnts to 2d Semblk for proc	,,%TBUCK standard
$PNAME standard
$TBITS standard
$SBITS standard -- RTNDON on means a RETURN was seen in this proc
$ADR   <note1>			,,<note2>
$ACNO  <note3>			,,<note4>
%RVARB, %RSTR standard

 2d Semblk
%TLINK -- pnts to 1st formal Semblk	,,%STEMP pnts to saved TTEMP list (%TBUCK)
%SAVET  ptr to  old TTOP	,, ptr old TPROC    ($PNAME)
$NPRMS  # arith params+1	,, # string params * 2 ($PNAME+1)
$BLKLP  BLKLIM qstack dscriptr saved at PRDEC ($TBITS)
$SBITS	<note5>
$VAL	-1 if TOPLEV on at PRDEC
$VAL2	DDT level of this procedure

<note1>	fixup chain of jumps past SUB/PUSH code in string exit sequences
	(for non-recursive RETURNs which return non-temp Strings).
<note2> fixup until entry addr known (delayed to PRUP for recursive procs),
	then addr of procedure entry sequence
<note3> address of first word of proecedure text (for finding text, adjusting AOS)
<note4>	fixup chain of jumps to procedure exit sequence (incl SUB/PUSH for Str)
<note5> address of JRST around 1st procedure in nest
⊗

ZERODATA (PROCEDURE CODE VARIABLES)
;FTRPRM -- QSTACK Descriptor -- holds Semantics of actual 
;    parameters as they are developed for FORTRAN calls.
;    These are QTAKed back off after the JSA is generated
?FTRPRM: 0

;FORMFX -- formal fixups QSTACK Descriptor -- see TOTAL for
;    definition, description

;MESFLG -- on in Procedure call code if call is a MESSAGE
;    call
?MESFLG: 0
;TBSAVE -- Temp cell used to save tbits during call to DYNAMAK(ADRINS);
;
?TBSAVE: 0
;MPFLAG -- Flag to FTRADR to tell that we really want the type bits
;in the left half of the adcon
↑↑MPFLAG:0

;MPQCNT - number of matching procedure params seen so far
?MPQCNT: 0
;MPVARS - qstack of ? params seen thus far
?MPVARS:	0

ENDDATA

COMMENT ⊗  PRDEC -- When Name is Seen⊗

; 1  -- SAVE STATUS

;;#GP# DCS 2-6-72 (3-4) CHECK FORWARD FORMALS AGAINST REAL ONES
↑PRDEC:	SETOM	OLDPRM			;NO SAVED FORMAL DECLS YET
;;#NT#	! RHT 8-19-73 REALLY NEED AN ALLSTO HERE, WHILE STILL HAVE OLD TEMPS
	PUSHJ	P,ALLSTO
	MOVEI	A,PROCED		;BITS FOR PROCEDURE
	IOR	A,BITS
	TRNE	A,ITEM
	TRC	A,ITEM!ITMVAR		;ITEM PROCEDURES REALLY ITEMVAR PROCS
	MOVEM	A,BITS
	PUSHJ	P,ENTID			;ENTER THE SYMBOL
;;#GP# (3) ALSO SET UP OLDPRM IN ENTERS
	MOVE	PNT,TPROC		;PNT  CURRENT PROC SEMANTICS.
	LEFT	PNT,%TLINK,LPSERR	;LPSA to pnt to 2D TPROC BLOCK
RGC <
	HRR	TEMP,RCTEMP
	HRLM	TEMP,%RVARB(LPSA)	;SAVE RCTEMP LIST
>;RGC
	HRR	TEMP,TTEMP
	HRRM	TEMP,%STEMP(LPSA)	;SAVE CURRENT TEMP RING.
	PUSH	P,LPSA			;SAVE ptr to 2D BLOCK OF SURROUNDING PROC
	MOVE	PNT2,NEWSYM		;NEW SYMBOL (PROCEDURE NAME)
	LEFT	PNT2,%TLINK,LPSERR	;LPSA ptr to 2D BLOCK
	HRL	PNT,TTOP		;TTOP,TPROC SAVED HERE
	MOVEM	PNT,%SAVET(LPSA)
	TLZE	FF,TOPLEV	;NO LONGER AT TOP LEVEL,
	SETOM	$VAL(LPSA)	; BUT SAVE PREVIOUS STATUS
	MOVEW	(<$BLKLP(LPSA)>,BLKIDX) ;SAVE CURRENT BLKIDX
	SETZM	BLKIDX			;CLEAR NEW ONE

	AOS	TEMP,NMLVL	;UPDATE DDT LEVEL
	SETZM	$SBITS(LPSA)		;JRST AROUND PROCS ADDR
	HRRZM	TEMP,$VAL2(LPSA)


;  2 -- INITIALIZE STATUS FOR THIS PROCEDURE

; ***** BUG TRAP
	SKIPN	ADEPTH		;THESE SHOULD BE ZERO HERE
	SKIPE	SDEPTH
	 ERR	 <DRYROT -- ADEPTH OR SDEPTH >,1

	FOR	II IN (VARB,APARNO,SPARNO,ADEPTH,SDEPTH,TTEMP) <
		SETZM	II>
RGC <
	SETZM	RCTEMP
>;RGC
COMMENT ⊗
	AT THIS POINT YOU MAY WANT TO SAVE OLD DISPLAY LIST
	⊗
	MOVE 	A,$SBITS(PNT2)	;NEED TO ZERO OUT THE DL FLD
	TRZ	A,DLFLDM	;ZERO IT
	MOVEM	A,$SBITS(PNT2)	;PUT IT BACK
	SETOM	RECSW		;ASSUME RECURSIVE -- IF WRONG WILL FIX BELOW
	MOVE	TBITS2,$TBITS(PNT2)	;BITS FOR THIS PROCEDURE
	MOVEI	A,0		;ASSUME A RECURSIVE PROCEDURE
	TLNN	TBITS2,RECURS
	MOVNI	A,1		;NON-RECURSIVE -- INDICATE NO FORMAL FIXUPS
	XORM	A,RECSW		;THIS WILL SET RECSW TO ALL 0 IF NOT RECSV
;; #MX# (1 OF 1) RHT CHECK FOR NON SIMP INSIDE SIMP
;;%##% ALSO DO NOT BARF AT EXTERNAL OR FORTRAN
	TDNN	TBITS2,[ XWD SIMPLE+EXTRNL,FORTRAN]
	SKIPN	SIMPSW	
	JRST	.+2		
	ERR	<YOU HAVE DECLARED A NON-SIMPLE PROCEDURE INSIDE
A SIMPLE PROCEDURE.  WE MAKE NO PROMISSES... >,1
;; #MX#

	SETOM	SIMPSW		;ASSUME SIMPLE
NOBAIL<
	TLNE	TBITS2,SIMPLE	;IS IT REALLY
	JRST	GOTPD		;YES
	SETZM	SIMPSW		;NOT SIMPLE
>;NOBAIL
BAIL<
	TLNN	TBITS2,SIMPLE	;IS IT REALLY
	 SETZM	SIMPSW		;NO
	MOVE	TEMP,BAILON
	TLNE	TBITS2,SIMPLE	;SKIP IF NOT SIMPLE
	TRNE	TEMP,BBPDSM	;SKIP IF SIMPLE PROCS DONT GET PDS
	 JRST	.+2		;PROC WILL GET A PD
	JRST	GOTPD		;SIMPLE PROC AND NO PD
>;BAIL
;;#LQ# 2! RHT IF FWRD PROC HAD A PD, THEN KEEP IT
	HRRZ	LPSA,$VAL(PNT2)	;HAD A PD?
	JUMPN	LPSA,GOTPD	;DONT GET ANOTHER
;;#LQ#
	GETBLK			;FOR PROC DESC STUFF
	HRRM	LPSA,$VAL(PNT2)	;RECORD IT
GOTPD:
BAIL<
	MOVE	TEMP,BCORDN	;COORDINATE NUMBER AT PRDEC
	HRLM	TEMP,$VAL(LPSA)	;PLACE INTO PD SEMBLK
>;BAIL
	QPUSH	(FORMFX)	;SAVE MARKER
	MOVEM	PNT2,TPROC	;LET EVERYONE KNOW
	MOVEM	PNT2,TTOP	; WHO HAS A RIGHT TO KNOW WHERE
	MOVEM	PNT2,GENRIG	;  THIS PROCEDURE IS
;5-12-72
;	MOVEM	PNT2,GENRIG+1	;  (COULD GO ONE OF TWO PLACES) NO MORE -- DCS

	AOS	LEVEL
	PUSHJ	P,MAKBUK	;DOWN A LEVEL
	SKIPN	SIMPSW		;IF NOT SIMPLE PROC
	AOS 	CDLEV		;DOWN HERE TOO
	TLO	FF,NOCRFW!PRODEF	;SET DECLARATION BIT

; 3 -- ISSUE CODE

Comment ⊗ consider: ... X ← A+1;
			   BEGIN INTEGER PROCEDURE ... ⊗

	TRNE	TBITS2,FORWRD	;IF FORWARD DEC, IGNORE THE REST
	 JRST	 TMPOPJ		; (SOME OF ABOVE IS IRRELEVANT ALSO)
	PUSHJ	P,ZOTDIS
	PUSHJ	P,ALLSTO	;BECAUSE OF ABOVE CONSIDERATION
	MOVE	TEMP,CDLEV	;BUMP DISPLY LEVEL
	MOVEI	LPSA,RF
	MOVEM	LPSA,DISTAB(TEMP)	;F IS THE TOP DISPLAY
COMMENT ⊗ AT A LATER DATE MAY  WANT TOO DO MORE --
	I.E. BEFORE ALLSTO -- GO THRU ZZ CLEAR DISTAB SO
	RECORD OF DISPLAYS GETS KEPT OVER PROC DECL;
	⊗
;CREF THE NEW BLOCK NAME.
	TLZ	FF,NOCRFW
	TLNN	FF,CREFSW
	JRST	NOCRW		;NO
	MOVEI	A,15
	PUSHJ	P,CREFOUT
	MOVE	LPSA,PNT2
	PUSHJ	P,CREFASC
NOCRW:
	HRRZ	TEMP,PCNT	;ADDR OF JRST TO COME (IF ANY)
	POP	P,LPSA		;PTR TO 2D SEMBLK FOR SURROUNDING PROCEDURE
	SKIPE	$SBITS(LPSA)	;HAS SOMEBODY ALREADY DONE THE JUMP?
	 JRST	 NOROUND	; YES, ONLY ONE JUMP AROUND PROCEDURES
				; (SEE ENDDEC, ENDJMP, BUILT-IN ARRAY CODE)
	HRRZM	TEMP,$SBITS(LPSA);DENOTE JRST FROM HERE
	EMIT	(<JRST NOUSAC+NOADDR>) ;JRST AROUND PROC(S)
	HRRZ	TEMP,PCNT	;NOW NEW PCNT
;;%BI% ! CHANGED THIS FROM HRLZM TEMP,$ACNO(PNT2)
NOROUND:HRLM	TEMP,$VAL2(PNT2);IDENTIFIES START OF PROCEDURE
	HLLZS	$ACNO(PNT2)	;WAS PARANOID ABOUT THE ZEROING USED TO GET
;;%BI%
	TLNE	TBITS2,RECURS
	 JRST	 RCSV		;RECURSIVE, CAN'T PLACE PROC YET
	TLNN	TBITS2,SIMPLE	;IS THIS NON-SIMPLE AND
	TLNN	TBITS2,INTRNL	;IS THIS AN INTERNAL PROCEDURE??
	JRST	NTINT		;NO
;;#SD#
	MOVEI	A,1		;FLAG THAT SAYS ALWAYS PUT OUT PDA WORD
	PUSHJ	P,PDAWRD	;YES, NEED A PDA WORD
;;#SD#
NTINT:
NRC <
	SKIPE	RCDFLG		;IF DECLARING A RECORD CLASS
	JRST	WAITAS		;THEN WAIT TO ASSIGN ADDRESS
>;NRC
	HRL	B,$ADR(PNT2)	;CAN NOW GIVE PROCEDURE A HOME
	HRR	B,PCNT		;AT PCNT NO LESS!
	HRRM	B,$ADR(PNT2)
	TLNE	B,-1		;IF IT WAS FORWARD, AND SOMEONE
	PUSHJ	P,FBOUT		;HAD THE FORSIGHT TO USE IT.
	TRZ	TBITS2,INPROG
WAITAS:	MOVEM	TBITS2,$TBITS(PNT2); NO LONGER FORWARD
BAIL<
	MOVE	TEMP,BAILON
	SKIPE	SIMPSW		;SKIP IF NOT SIMPLE
	TRNN	TEMP,BBPDSM	;SKIP IF SIMPLE PROCS GET PD
	 JRST	NTINT1		;SAME AS USUAL
;;#%%# 2! JFR 2-1-75	RECORDS ARE SIMPLE PROCS IN DISGUISE, THE JFCL WAS KILLING THEM
	SKIPE	RCDFLG		;RECORD CLASS DECL IN PROGRESS?
	 JRST	NTINT1		;YES
	EMIT	(<JFCL NOUSAC+NOADDR>)	;GIVE BREAKPOINTS SOME BREATHING ROOM
	HRRZ	PNT,$VAL(PNT2)	;MY PD SEMBLK
	HRRZ	B,PCNT
	HRLM	B,$ACNO(PNT)	;PCNT AFTER "MKSEMT"
	POPJ	P,
NTINT1:
>;BAIL
	SKIPE	SIMPSW		;IF SIMPLE THEN ALL DONE
	POPJ	P,
	PUSHJ	P,MKSEMT	;PUT OUT MSCP
	PUSHJ	P,SETF		;MAKE IT ALL OFFICIAL
	POPJ	P,

↑↑TMPOPJ:POP	P,TEMP
	POPJ	P,

PDAWRD:	HRRZ	PNT,$VAL(PNT2)	;LOOK AT PROCEDURE DESCRIPTOR
	CAIN	PNT,0		;BETTER BE HERE
	ERR	<DRYROT -- DONT HAVE PD SEMBLK YET>
;;#SD# IF USED TO BE EXTERNAL WE NEED TO BE FANCY HERE (PERHAPS)
	SKIPN	IEFLAG		;INTERNAL TO EXTERNAL??
	JRST	PDAW.1		;
	HRLZ	B,$ADR(PNT)	;PDA FIXUP CHAIN
	JUMPE	B,PDAW.1	;
	HRR	B,PCNT		;
	PUSHJ	P,FBOUT		;FIX ALL THESE UP TO HERE
	HLLZS	$ADR(PNT)	;MAKE A FRESH START
	PUSHJ	P,FRBT		;LIKE SO
	JRST	.+2		;WE REALLY NEED A PDA WORD
PDAW.1: JUMPE	A,CPOPJ
;;#SH# ! ADDED A NOUSAC
	EMIT	<NOUSAC!JSFIX>		;PUT OUT PDA
	HRRZ	TEMP,PCNT	;AND YET ANOTHER VALUE FOR
	HRLM	TEMP,$VAL2(PNT2);PCNT AT PRDEC
	POPJ	P,

RCSV:	SKIPN	IEFLAG		;
	POPJ	P,
	MOVEI	A,0		;ONLY PUT OUT PDA WORD IF NEED TO
	JRST	PDAWRD

;;#SD#


COMMENT ⊗  ENDPR -- when params have been seen⊗

DSCR ENDPR
PRO ENDPR
DES
PD1:	PDEC ;  drarrow  PDEC   EXEC ENDPR  SCAN   ¬S1
	PDNO ;  drarrow  NIL	  EXEC ENDPR  SCAN   ¬DS0

1. Turn off formal-scanning bit
2. Save parameter counts, insert stack displacements
	for parameters
⊗
; 1

↑ENDPR:	TLZ	FF,NOCRFW!PRODEF

;  2

	HRRZ	PNT2,GENLEF+1		;THIS PROCEDURE
	MOVE	TEMP,$TBITS(PNT2)	;GET TYPE BITS
	TLNN	TEMP,MPBIND		;A MATCHING PROCEDURE?
	JRST	MATNOT			;NO
	TLNE	TEMP,SIMPLE		;BETTER NOT BE SIMPLE.
	ERR	<MATCHING PROCEDURES MAY NOT BE SIMPLE>,1
	QPUSH	(MPSTAK,PNT2)		;SEMANTICS OF MATCHING PROCEDURE
MATNOT:
	HLRZ	PNT2,%TLINK(PNT2)	;PTR TO SECOND BLOCK FOR THIS PROC
	JUMPE	PNT2,LPSERR		;HAS TO BE THERE
	AOS	A,APARNO	;SAVE COUNTS
	HRLM	A,$NPRMS(PNT2)	;SAVE COUNTS
	MOVE	A,SPARNO
	LSH	A,1		; * 2 FOR STRINGS
	HRRM	A,$NPRMS(PNT2)	;AND SET UP A AND B WITH THEM

	MOVEI	A,1		;LEAVE ROOM FOR RETURN ADDR
	MOVEI	B,1		;LEAVE ROOM FOR SECOND STRING WORD

; NUMBER THE PARAMETERS, FIND BEGINNING OF THEIR LIST, REZERO VARB

	SKIPN	PNT,VARB	;ARE THERE ANY?
	 JRST	 PUTIN		; NO, MARK ZERO
PARD:	PUSHJ	P,GETAD		;FIND OUT ABOUT THIS FORMAL
	TRNE	TBITS,PROCED	;IF IT IS A PROCEDURE CALLED BY
	TLNN	TBITS,VALUE	; VALUE, COMPLAIN
	SKIPA
	 ERR	 <DON'T PASS PROCEDURES BY VALUE>,1
	TRNE	TBITS,STRING	;STRING VALUE PARAMS ARE INDEXED
	TLNN	TBITS,VALUE	;FROM THE RSP STACK
	 JRST	 PST		;ALL OTHERS OFF OF RP
;;#HR# ALLOW STRING ITEMVAR PARAMETERS
	TDNE	TBITS,[XWD SBSCRP,ITEM!ITMVAR]
;;#HR# 
	 JRST	 PST
	HRRM	B,$ADR(PNT)	;DISPLACEMENT FROM TOP OF STACK
	ADDI	B,2		;SIZE OF EACH PARAM
	JRST	PRLUP

PST:	HRRM	A,$ADR(PNT)
	ADDI	A,1
	TRNE	TBITS,SET
	TDNE	TBITS,[XWD REFRNC!SBSCRP,LPARRAY!ITEM!ITMVAR]
	JRST	NOSET		;EXCEPT THESE.
	TRNE	TBITS,FLOTNG	;DON'T LET CONTEXTS THROUGH
	ERR	<CONTEXTS MAY NOT BE PASSED BY VALUE>,1

; IF EXTERNAL (OR FORWARD) PROCEDURE, NO CODE GOES OUT  (DCS -- 9/11/70)
; MORE FIXES 6-11-71
	MOVE	TEMP,GENLEF+1	;PROC SEMANTICS
	MOVE	TEMP,$TBITS(TEMP)
	TDNE	TEMP,[XWD EXTRNL,FORWRD] ;SPECIAL DECLARATION?
	 JRST	 NOSET
; END BUG FIX (DCS -- 9/11/70) (6-11-71)


	PUSH	P,A
	EMIT	(<HRROI TAC1,NOUSAC>);CALL IT.
	LPCALL	(SETCOP)	;AND COPY IT.
	POP	P,A
NOSET:
	TLNN	TBITS,MPBIND	;A ?ITEMVAR
	JRST	NOMPRS		;NO.
	MOVE 	TEMP,GENLEF+1	;GET PROC'S SEMANTICS
	MOVE	TEMP,$TBITS(TEMP);
	TDNE	TEMP,[XWD EXTRNL,FORWRD]
	JRST	NOMPRS		;NO CODE FOR EXTERNS OF FORWARDS
	TLNN	TEMP,MPBIND	;THIS REALLY A MATCHING PROC.
	ERR	<? PARAMS ONLY LEGAL FOR MATCHING PROCEDURES>,1
	PUSH	P,A		;SAVE DISPLACEMENT
	PUSH	P,PNT		;SAVE
	AOS	MPQCNT		;WE HAVE ANOTHER ? PARAM
	QPUSH	(MPVARS,PNT)	;SAVE ? PARS SEMANTICS
;INITIALIZE ? PARAMS TO UNBOUND IF NECESSARY
	MOVEI	A,UNBND		;THE "UNBOUND" ITEM
	PUSHJ	P,CREINT	;GET CONSTANT SEMBLK
	GENMOV  (GET,0)		;
	HRROS	ACKTAB(D)	;PROTECT THAT AC
	EXCH	D,(P)		;SAVE AC # ITS IN
	MOVE	PNT,D		;THE PARAM SEMBLK
	GENMOV	(ACCESS,GETD)	;PROBABLY NOT NECESSARY
	PUSHJ	P,GETAN0	;GET AN AC TO PLAY WITH
	EMIT	<MOVE ,0>	;LOAD PARAM
				;NOTE GENMOV WILL NOT WORK HERE
				;AS IT WOULD GENERATE MOVEI @
	HRLM	D,(P)		;TO USE AS INDX FOR MOVEM BELOW
	HRLI	C,20		;THE INDIRECT BIT
	EMIT	<TLNE ,USADDR!NORLC> ;TEST FOR INDIRECT BIT
	POP	P,D		;AC CONTAINING "UNBOUND"
	EMIT	<MOVEM ,USX!NOADDR>
;; #LL# WAS UNPROTECTING WRONG AC
;;	MOVSS	D
	HRRZS	ACKTAB(D)	;"FREE" INDEX AC
	POP	P,A		;RESTORE DISPLACEMENT
NOMPRS:
	

PRLUP:	LEFT	PNT,%RVARB,PUTIN;NEXT ONE OR ZERO
	MOVE	PNT,LPSA	;PNT TO NEXT ONE
	JRST	PARD

PUTIN:
	MOVE	TEMP,GENLEF+1	;GET PROC'S SEMANTICS
	MOVE	TEMP,$TBITS(TEMP)
;; #ME# FOLLOWING ONLY TESTED EXTRNL
	TDNN	TEMP,[EXTRNL,,FORWRD] ;IF EXTERNAL OR FORWARD DO NOTHING HERE
	TLNN	TEMP,MPBIND	;OR NOT MATCHING PROCEDURE 
	JRST	PUTIN2		;IGNORE
	PUSH	P,PNT
	HRR	C,PCNT
	MOVE 	B,MPQCNT	; THE COUNT OF NUMBER OF ? PARAMETERS
	ADDI	C,2(B)		;
	HRLI	C,(C)
	EMIT	<JRST	,NOUSAC!USADDR> ;JRST AROUND ?TABLE
	HRL	PNT,PCNT	;SAVE ADDR OF TABLE
	HRR	PNT,LEVEL	;SAVE LEVEL FOR STKUWD
	QPUSH	(MPVSTK,PNT)
	HRLI	C,(B)		;NUMBER OF MP PARS
	EMIT	<,NOUSAC!USADDR!NORLC>;COUNT OF
;; #NP# CAN'T QPOP AN EMPTY STACK(MPVARS)
	JUMPE	B,NOQPARS	;IF NO PARAMS DO NOTHING
LBPUTL:
	QPOP	(MPVARS,PNT)
	HRRZ	C,$ADR(PNT)	;THE STACK DISPLACEMENT
	MOVNS	C
	SUBI	C,1		;FOR RETURN ADDRESS
	HRL	C,C
	EMIT	<,USADDR!NOUSAC!NORLC>
	SOJG	B,LBPUTL
NOQPARS:
	POP	P,PNT
	SETZM	MPQCNT		;FOR NEXT TIME
PUTIN2:
	HRLM	PNT,%TLINK(PNT2) ;PNT2 pnts to 2D PROC BLOCK
	SETZM	VARB		;BRAND NEW PROC DECL COMING
;;#GP# DCS 2-6-72 (4-4) CHECK FORWARDS AGAINS NEW FORMALS
	SKIPN	LPSA,OLDPRM	;DID ANY FORWARD HAVE DECLRARATIONS?
	 JUMPE	 PNT,OKFORM	; NO, AND ALSO NO NEW DECLARATIONS
	JUMPL	LPSA,OKFORM	;NO PREVIOUS FORMALS, QUIT
	SETOM	OLDPRM		;CLEAR OUT, JUST FOR SAFETY
CKPRM:	JUMPE	LPSA,CHKRDN	;CHECK REAL DONE TOO
	JUMPE	PNT,TOOMF	;TOO MANY FORWARDS
	PUSHJ	P,URGSTR	;RELEASE FROM STRING RING
	FREBLK	()		;RELEASE STORAGE
	MOVE	TBITS,$TBITS(PNT)
	CAME	TBITS,$TBITS(LPSA);MUST BE SAME TYPE
	ERR	 <FORMALS DON'T ALL AGREE WITH FORWARD DECLARATIONS>,1
	HRRZ	LPSA,%RVARB(LPSA);MOVE ON DOWN
	HRRZ	PNT,%RVARB(PNT)
	JRST	CKPRM

CHKRDN:	JUMPE	PNT,OKFORM	;MUST BOTH BE EMPTY
	ERR	 <MORE FORMALS DECLARED THAN IN FORWARD DECLARATION>,1
OKFORM:	POPJ	P,

TOOMF:	ERR	 <FEWER FORMALS DECLARED THAN IN FORWARD DECLARATION>,1
	JRST	 KILLST		;REMOVE THE REST
;;#GP# (4)

;; ENDRC -- MAIN RECORD CLASS EXEC

REC <

; Any resemblence between this routine & ENDPR or PRUP is strictly
; intentional

ZERODATA(SOME VARIABLES FOR RCLASS EMISSION)
TARAPC:	0			;PROGRAM COUNTER AT START OF TYPE ARRAY
IDRAPC:	0			;PC AT START OF ID ARRAY
PNSTPC:	0			;PC AT START OF PNAME STRING
CLSBTS:	0			;HOLDS TYPE BITS
NOFLID:	0			;IF NON-ZERO, NO FIELD PNAMES GO OUT
ENDDATA


↑ENDRC:	TLZ	FF,NOCRFW!PRODEF	;MAKE THE SCANNER HAPPY
	SETZM	CURRCC			;DONE WITH THIS NOW
	HRRZ	PNT2,GENLEF+1		;THE "PROCEDURE"
	PUSHJ	P,GETAD2		;IF EXTERNAL OR FORWARD, DO NOTHING
	HLRZ	PNT2,%TLINK(PNT2)	;GET THE SECOND BLOCK
NONRC<
	SKIPE	A,SPARNO		;PARAMETER COUNT
	ERR	<STRING SUBFIELDS FOR RECORDS NOT YET IMPLEMENTED>,1
>;NONRC
NRC<
	MOVE	A,SPARNO
>;NRC
	ADD	A,APARNO		;NUMBER OF PARAMETERS
	MOVEM	A,$NPRMS(PNT2)		;

NONRC <
	TDNE	TBITS2,[XWD EXTRNL,FORWRD] ;CHECK TO SEE IF SHOULD PUT OUT
	JRST	FLDCHK			;NOTHING GOES OUT

	LSH	A,=23			;TURN THE WORD COUNT INTO "OPCODE"
	SKIPE	PNT,URCIPR		;DID THE USER SPECIFY A HANDLER
	JRST	[ PUSHJ	P,GETAD
		  HRL	C,$ADR(PNT)	;
		  TRNE	TBITS,FORWRD!INPROG	;WELL??
		  TROA	A,NOUSAC!JSFIX	;YES, LET EMITER DO FIXUP
		  TRO	A,NOUSAC!USADDR	;
		  JRST  HLRWRD
		]
	HRLZ	C,PCNT			;USE THE STANDARD ROUTINE $REC$
	EXCH	C,LIBTAB+R$REC$		;DO FIXUP MYSELF
	HRRI	A,NOUSAC!USADDR		;& PUT OUT THE INSTRUCTION
HLRWRD:	PUSHJ	P,EMITER		;PUT OUT THE HANDLER WORD
>;NONRC

FLDCHK:	
NRC <
	MOVEI	B,CMPLDC		;NO DELETE & COMPILED-IN
>;NRC
	SKIPN	LPSA,VARB		;ARE THERE ANY FIELDS
	JRST	NOFLDS			;NOPE
	HRRZ	A,$NPRMS(PNT2)		;HOW MANY THERE ARE
	HRLZI	TBITS,FORMAL		;TURN OFF THE FORMALNESS
ZRTB:	ANDCAM	TBITS,$TBITS(LPSA)	;OF THIS PARAMETER
NRC <
	MOVE	C,$TBITS(LPSA)		;GET TBITS
	TRNE	C,ITMVAR!ITEM		;AN ITEMISH THING?
	JRST	FPISIV			;YES
	TRNE	C,STRING		;A STRING?
	TRO	B,HASSTR		;HAVE SOME SORT OF STRING PARAM
	TRNE	C,PNTVAR		;PERCHANCE A RECORD CLASS
	TRO	B,HASRPS		;YES
FPISIV:
>;NRC
	MOVEM	A,$ADR(LPSA)		;INDEX
	SOJLE	A,RMFP			;REMEMBER THIS ONE 
;;#VB# (1 OF 3) MISPLACED CODE USED TO BE HERE RHT
	HLRZ	LPSA,%RVARB(LPSA)	;GO LEFT,YOUNG MAN
	JUMPN	LPSA,ZRTB		;
	ERR	<DRYROT: INDEX COUNT & PARAM RING DISAGREE>,1
;;#VB# (2 OF 3) ! PUT NOFLDS IN RIGHT PLACE
NRC <
NOFLDS:
>;NRC
RMFP:	HRLM	LPSA,%TLINK(PNT2)	;NOW LPSA HOLDS PTR TO FIRST
;;#VB# (3 OF 3) RHT
NRC <
	MOVEM	B,CLSBTS		;REMEMBER CLASS BITS
>;NRC
;;#VB#
	TDNE	TBITS2,[XWD EXTRNL,FORWRD] ;IF ONE OF THESE, NO CODE
	JRST	RCBDON
NRC <	
REN <
	PUSHJ	P,HISET			;FORCE INTO HIGH SEGMENT
>;REN
	PUSH	P,FF			;PARANOIA
	TLO	FF,RELOC		;
	MOVE	A,PCNT			;
	MOVEM	A,TARAPC		;TYPE ARRAY PC
	ADDI	A,5			;POINT AT FIRST WORD OF ARRAY
	PUSHJ	P,CODOUT
	PUSHJ	P,[ARBNDP: TLZ	FF,RELOC	;PUT OUT BOUNDS PAIRS
			MOVEI	A,0
			PUSHJ	P,CODOUT	;LOWER BND
			HRRZ	A,$NPRMS(PNT2)	;
			PUSHJ	P,CODOUT	;UPPER BND
			MOVEI	A,1		;MULT
			PUSHJ	P,CODOUT
			POPJ	P, ]
	HRRZ	A,$NPRMS(PNT2)
	ADD	A,X11			; NDIMS,,LEN
	PUSHJ	P,CODOUT		; PUT OUT THAT WORD
	MOVE	A,CLSBTS		; *** HERE IS WHERE TYPE BITS GO ***
	PUSHJ	P,CODOUT		; PUT OUT TYPE BITS
	HLRZ	LPSA,%TLINK(PNT2)	;IN CASE WAS MUNCHED (MOST LIKELY WAS OK)
	PUSHJ	P,TBCOUT		;
	MOVE	PNT,GENLEF+1		;PICK UP THE CLASS DESCRIPTOR
	EXCH	SP,STPSAV		;SINCE WILL CALL CAT
	PUSHJ	P,INSET			;WE WILL ALWAYS PUT OUT CLASSID CHARS
	PUSH	SP,$PNAME(PNT)		;CLASSID
	PUSH	SP,$PNAME+1(PNT)
	PUSH	P,[0]
EXTERN	CATCHR
	PUSHJ	P,CATCHR		;NOW ASCII WITH A ZERO
	SKIPE	NOFLID			;WANT IDS
	JRST	CHRSDO			;NO, JUST PUT OUT WHAT YOU HAVE
	HLRZ	B,%TLINK(PNT2)		;FIRST FIELD
	JUMPE	B,CHRSDO		;NO FIELDS
FIDSLP:	PUSH	SP,$PNAME(B)		;PNAME OF PARAMETER
	PUSH	SP,$PNAME+1(B)
	PUSHJ	P,CAT			;CONCATENATE IT ON
	HRRZ	B,%RVARB(B)		;GET THE NEXT ONE
	JUMPN	B,FIDSLP		;CONTINUE ON
CHRSDO: 
	POP	SP,B			;POINT AT TEXT
	POP	SP,C			;CHARACTER COUNT
	EXCH	SP,STPSAV		;PUT SP BACK TOGETHER
	HRRZ	C,C			;WANT THE BYTE COUNT
	MOVE	A,PCNT			;REMEMBER HERE
	MOVEM 	A,PNSTPC		;SO CAN BUILD DESCRIPTORS
CHRSD1:	MOVE	A,(B)			;A WORD OF TEXT
	PUSHJ	P,CODOUT		;PUT IT OUT
	SUBI	C,5			;5 CHARS WENT OUT
	CAILE	C,0			;DONE 
	AOJA	B,CHRSD1		;DO, GO DO SOME MORE
	SETZM	IDRAPC			;
	SKIPE	NOFLID			;WANT ID FIELDS TO GO OUT
	JRST	FIDSDN			;NO, THEN WE ARE DONE WITH IDS
	MOVE	A,PCNT			;REMEMBER WHERE STRING ARRAY STARTS
	MOVEM	A,IDRAPC		;
;;#XK# ! JFR 7-30-76 STRING ARRAYS HAVE -1 IN LEFT HALF OF WORD CONTAINING 000 ADDR
	HRROI	A,6(A)			;FIRST DATA ENTRY
	TLO	FF,RELOC
	PUSHJ	P,CODOUT
	PUSHJ	P,ARBNDP		;PUT OUT ARRAY BOUNDS PAIR
	HRRZ	A,$NPRMS(PNT2)		;COUNT WORD
	LSH	A,1
	HRROI	A,2(A)			;-1,,2(N+1)
	PUSHJ	P,CODOUT		;

	MOVE	D,PNSTPC		;PC AT START OF PNAME STRING
	HRLI	D,(<POINT 7,0>)		;MAKE IT A BYTE POINTER
	HRRZ	C,$PNAME(PNT)		;BYTE CNT OF ID
	PUSHJ	P,[BPEMT:  TLZ FF,RELOC
			MOVE	A,C	;PUT OUT COUNT
			PUSHJ	P,CODOUT;
			TLO	FF,RELOC;
			MOVE	A,D	;PUT OUT BPTR
			PUSHJ	P,CODOUT
			JUMPE	C,CPOPJ	;
		   BPEMT0: IBP	D	;INCREMENT POINTER
			SOJG	C,BPEMT0;THAT MANY TIMES
			POPJ	P,]
	IBP	D			;FOR THE 0 BYTE
	HLRZ	B,%TLINK(PNT2)		;PUT OUT STRINGS FOR FIELDS
	JUMPE	B,FIDSDN		;DONE
FID1DO:	HRRZ	C,$PNAME(B)		;LENGHT OF THIS ONE
	PUSHJ	P,BPEMT			;PUT OUT
	HRRZ	B,%RVARB(B)		;NEXT
	JUMPN	B,FID1DO
;; HERE PUT OUT THE ACTUAL DESCRIPTOR
FIDSDN:
REN <
	PUSHJ	P,LOSET			;THIS GOES INTO THE LOW SEGMENT
>;REN
	TLZ	FF,RELOC
	MOVEI	A,0			;RECORD CLASS LINK WORD
	PUSHJ	P,CODOUT		;
	MOVEI	B,%RCLNK		;LINK ONTO THE RECORD CLASS LIST
	PUSHJ	P,LNKOUT		;PUT IT OUT
	MOVEI	A,0			;THE RING WORD
	PUSHJ	P,CODOUT
;; NOW GIVE RECORD CLASS AN ADDRESS
	MOVE	PNT,GENLEF+1
	HRL	B,$ADR(PNT)	;PICK UP ADDRESS
	HRR	B,PCNT		;AT PCNT NO LESS!
	HRRM	B,$ADR(PNT)
	TLNE	B,-1		;IF IT WAS FORWARD, AND SOMEONE
	PUSHJ	P,FBOUT		;HAD THE FORSIGHT TO USE IT.
	MOVEI	TBITS2,INPROG	;TURN OFF INPROG
	ANDCAM	TBITS2,$TBITS(PNT)
;; NOW PUT OUT THE FIRST "REAL" WORD OF THE DESCRIPTOR
	HRLZ	C,PCNT			;
	EXCH	C,LIBTAB+R$CLASS	;DO FIXUP MYSELF
	HRRI	A,NOUSAC!USADDR		;& PUT OUT THE INSTRUCTION
	PUSHJ	P,EMITER		;PUT OUT THE CLASSID WORD
	TLZ	FF,RELOC
	MOVEI	A,0			;THE RECRNG WORD
	PUSHJ	P,CODOUT
	SKIPE	PNT,URCIPR		;DID THE USER SPECIFY A HANDLER
	JRST	[ PUSHJ	P,GETAD
		  HRL	C,$ADR(PNT)	;
		  TRNE	TBITS,FORWRD!INPROG	;WELL??
		  TROA	A,NOUSAC!JSFIX	;YES, LET EMITER DO FIXUP
		  TRO	A,NOUSAC!USADDR	;
		  JRST  HLRWRD
		]
	HRLZ	C,PCNT			;USE THE STANDARD ROUTINE $REC$
	EXCH	C,LIBTAB+R$REC$		;DO FIXUP MYSELF
	MOVEI	A,NOUSAC!USADDR		;& PUT OUT THE INSTRUCTION
HLRWRD:	PUSHJ	P,EMITER		;PUT OUT THE HANDLER WORD
;;#UG# ! REMEMBER NOT TO RELOCATE THE COUNT
	TLZ	FF,RELOC		;GOES OUT UNRELOCATED
	MOVE	A,$NPRMS(PNT2)		;WORD COUNT
	PUSHJ	P,CODOUT
	MOVE	A,TARAPC		;PC OF TYPE ARRAY
	ADDI	A,5			;FOR ARRAY HEAD
	TLO	FF,RELOC
	PUSHJ	P,CODOUT		;PUT IT OUT
	SKIPN	A,IDRAPC		;ID ARRAY
	TLZA	FF,RELOC		;A ZERO
	ADDI	A,6			;TO RIGHT PLACE
	PUSHJ	P,CODOUT		;PUT OUT
	POP	P,FF			;GET FF BACK
REN <
	PUSHJ	P,HISET			;BACK TO HIGH SEGMENT
>;REN


>;NRC
NONRC <

	PUSHJ	P,TBCOUT		;PUT OUT THE CODES FOR THESE
NOFLDS:	MOVEI	A,0			;
	PUSHJ	P,CODOUT		;A ZERO TO SAY DONE
;;%BN% PUT OUT ASCIZ/CLASSID/ & A SAIL STRING POINTER THERETO
	MOVE	PNT,GENLEF+1
	PUSH	P,FF			;SUPER PARANOID
	TLZ	FF,RELOC
	HRRZ	A,$PNAME(PNT);
	PUSHJ	P,CODOUT
	HRRZ	B,A
	HRRZ	A,PCNT
	ADD	A,[POINT 7,1]
	TLO	FF,RELOC
	PUSHJ	P,CODOUT		;PUT OUT THE BYTE PTR
	MOVE	D,$PNAME+1(PNT)		;THE BYTE POINTER WORD OF ID
	IDIVI	B,5			;NUMBER OF WORDS
	CAIE	C,0			;IF NO REMAINDER
	ADDI	B,1			;THEN WE WILL EVENTUALLY PUT OUT A 
	TLZ	FF,RELOC		;WHOLE WORD OF 0
CIDLP:	MOVE	A,(D)			;A WORD FULL OF TEXT
	PUSHJ	P,CODOUT
	ADDI	D,1
	SOJG	B,CIDLP
	JUMPN	C,.+3
	MOVEI	A,0
	PUSHJ	P,CODOUT
	POP	P,FF
;;%BN%
>;NONRC
	
RCBDON:	;WELL, THE BODY IS OUT NOW
	HLRZ	PNT,%TLINK(PNT2)	;PRE-CONDITION FOR PUTIN2
	PUSHJ	P,PUTIN2		;CHECK AGAINST POSSIBLE FORWARDS
					;(PRETENDING TO BE ENDPR, REMEMBER)

RPRUP:	SETZM	BITS			;NOW DO THE PRUPISH THINGS
	SETZM	ALOCALS			;MOST LIKELY MOOT, BUT DOESN'T HURT
	SETZM	SLOCALS
	QPOP	(FORMFX)		;THIS ARCHAIC THING SHOULD BE FLUSHED
	JUMPGE	A,FFXERR		;THE "MARK" WAS NEGATIVE

	MOVE	PNT,GENLEF+1		;JUST TO KEEP MY HEAD STRAIGHT
	PUSHJ	P,GETAD			;PROC SEMANTICS 

	PUSHJ	P,SYNTUP		;NOTE STILL PRETENDING TO BE SIMPLE PROC
	MOVE	PNT,GENLEF+1		;FOR SAFETY
	MOVE	TBITS,[XWD SIMPLE,PROCED!PNTVAR!SHORT]
	XORM	TBITS,$TBITS(PNT)	;TELL THE TRUTH ABOUT WHAT IT IS
	POPJ	P,			;HOPE IT WORKS

>;REC


COMMENT ⊗  PRUP -- When Procedure Body's Finished -- Entry, Exit, Fixups, etc.⊗

DSCR PRUP
PRO PRUP
RES 
at S8:	PDEC S ;  drarrow  NIL   EXEC PRUP  SCAN   ¬DS
1. Issues fixups for any jumps to procedure exit, and
	for the jump around the procedure.
2. Issues procedure exit code, including stack adjusts
3. Issues procedure entry code if the procedure is recursive,
	including a JRST to the procedure text.
4. Goes up a text level, restores VARB-type pointers
5. Allocates storage for locals to procedure (ALOT).
BITS used as special flag during PRUP (see NONULL+1)
⊗

↑PRUP:	PUSHJ	P,ALLSTO	;STORE ALLES NOT YET STORED
	SETZM	BITS		;NOT SPECIAL YET (BITS USED AS FLAG)
	GETSM2	(2)		;PROCEDURE SEMANTICS
;;#HS# STRING ITEMVAR PROC TO BE TREATED AS ITEMVAR PROC. NOT STRING
	TRNE	TBITS2,ITEM!ITMVAR
	TRZ	TBITS2,STRING
;;#HS#

;⊗⊗ PNT2 set will almost continuously have Proc Semantics in the sequel

	HRRZ	PNT,$VAL(PNT2)	;PICK UP PD SEMBLK
	MOVE	TEMP,PCNT	;PICK UP PCNT
	HRRM	TEMP,$ACNO(PNT)	;
	TLNN	TBITS2,MPBIND	;THIS A MATCHING PROC
	JRST	MPNO		;NO
	QPOP	(MPSTAK)
	CAIE	PNT2,(A)	;THE SAME?
	ERR	<DRYROT-PRUP MATCHING PROC>
	EMIT	<HRRZI LPSA,NOUSAC> ;ADDRESS OF PDA
;; #LK# BY JRL FOLLOWING WAS QPOP
	QPOP	(MPVSTK,C)	;THIS IS QPOP AGAIN, SINCE PEXIT NO LONGER
				;REFERS TO IT
;; #LK# 
	EMIT	<HRLI LPSA,NOUSAC!USADDR>;ADDRESS OF ?TAB
	HRLI	C,LPSA
	EMIT	<PUSH RP,NOUSAC!USADDR!NORLC> ;STACK PDA ADDRESS
	XCALL	(.FAIL)		;REPORT FAILURE
	EMIT	<SETZ 1,NOUSAC!NOADDR> ;FALLING THROUGH IS FALSE
	PUSHJ	P,EMITER	;BOTH NORMAL RETURN AND SKIP RETURN
MPNO:

	PUSH	P,TBITS2	;REST WILL BE RECONSTRUCTED LATER
	TRNE	TBITS2,STRING	;IF NO RETURN MADE FROM STRING
	TLNE	SBITS2,RTNDON	; PROC, RETURN NULL HERE
	 JRST	 NONULL
	SETZM	PNAME
	PUSHJ	P,STRINS
	GENMOV	(STACK,REM)	;STACK IT AND FORGET IT
	SETZM	SDEPTH		;WE KNOW ABOUT STACK HERE
	JRST	NOEXIT		;BYPASS SPECIAL TEST (MUST HAVE SUB/PUSH CODE)
NONULL:	HRLZ	B,$ACNO(PNT2)
	JUMPE	B,[SETOM BITS	;NOBODY JUMPED TO SUB/PUSH CODE, BUT SOMEBODY
		   TLNE SBITS2,RTNDON ;RETURNED, SO SET SPEC (DON'T GENERATE
		   TRNN TBITS2,STRING ; SUB/PUSH) -- ONLY IF STRING PROC AND
		   SETZM BITS	; SOMEBODY RETURNED (TO EXIT2, ACTUALLY)
		   JRST  NOEXIT]; NO FIXUP, IN ANY CASE
	HRR	B,PCNT		;EXIT TO HERE
	PUSHJ	P,FBOUT		; IF YOU CAN



Comment ⊗ Now call routine which obtains the necessary
	counts and such (if the procedure is recursive).  ⊗

NOEXIT:
	TLZ	FF,ALLOCT	; GET SIZES
	PUSHJ	P,ALOT
	POP	P,TBITS2	;GET PROC TYPES BACK
	TLNN	TBITS2,RECURS	;RECURSIVE PROCEDURE?
	 JRST	 NOREC1		; NO

; FIX UP ANY REFERENCES TO THE FORMALS OF THIS PROCEDURE

FFXLUP:	QPOP	(FORMFX)	;A pnts to [DISPL REL 0,ADDR OF INSTR]
	JUMPL	A,FFXERR	;MUST NOT BE NEGATIVE
	JUMPLE	A,PEXIT		;GO GENERATE EXIT CODE WHEN DONE
FFXERR:	ERR	<DRYROT -- FFXLUP>

NOREC1:	SETZM	ALOCALS		;DON'T INCLUDE IN STACK COUNTS
	SETZM	SLOCALS
	QPOP	(FORMFX)	;GET STACK POINTER OFF
	JUMPGE	A,FFXERR	;MUST BE NEGATIVE -- NO RECURSION


Comment ⊗ Generate procedure exit code -- local restore, subs, push str results ⊗

PEXIT:	GETSM2	(2)		;PROCEDURE SEMANTICS AGAIN
;;#HS# IGNORE STRING BIT FOR STRING ITEMVAR PROC.
	TRNE	TBITS2,ITEM!ITMVAR
	TRZ	TBITS2,STRING
;;#HS#
	LEFT	PNT2,%TLINK,LPSERR;LPSA pnts to SECOND BLOCK
	PUSH	P,$NPRMS(LPSA)	;NUMBERS OF PARAMS
;;#IP# RHT 7-18-72 RELEASE ANY VALUE SETS

;;#JK# RHT 10-3-72 (1 OF 3) !
	TLZ	FF,FFTEMP	;HAVENT RELEASED SETS YET
	HLRZ	PNT,%TBUCK(LPSA);POINT AT FIRST FORMAL
FRSV:	JUMPE	PNT,PEX2	;ANY LEFT TO LOOK AT??
	MOVE	TBITS,$TBITS(PNT)
	TRNE	TBITS,ITEM!ITMVAR
	JRST	NXF
REC <
NORGC <
	TLNN	TBITS,VALUE	;IF NOT VALUE
	JRST	NXF		;NO WORRY AT ALL
	TRNE	TBITS,PNTVAR	;A RECORD POINTR
	TRNE	TBITS,777777-(PNTVAR!GLOBL)
	JRST	SETCHK		;NOPE
	MOVNI	C,1		;GO DEREFERENCE THIS FELLOW
	PUSHJ	P,RFCADJ
	JRST	NXF		;GO LOOK AT NEXT FORMAL PARAMETER
SETCHK:
>;NORGC
RGC <
	TLNE	TBITS,VALUE
>;RGC
>;REC
NOREC <
	TLNE	TBITS,VALUE	;IF NOT VALUE
>;NOREC
	TRNN	TBITS,SET	;OR NOT SET THEN 
	JRST	NXF		;GO ON TO NEXT
	EMIT	<HRROI TEMP,NOUSAC>	;CODE TO RELEASE THE SET
;; #JK# BY JRL 10-3-72 SAVE AC 1 OVER LEAP CALL
	TRNE	TBITS2,ALTYPS≠<PROCED+FORTRAN+STRING>	;WAS THIS A TYPED PROCEDURE
	TLOE	FF,FFTEMP	;DO WE HAVE TO SAVE AC1??
	JRST	STRCLX		;ALREADY DONE IT
	HRLI	C,A		;WILL SAVE AC 1 OVER LPCALL
	EMIT	<PUSH RP,NOUSAC!USADDR!NORLC>
;;#QX# RHT ! NEED TO BOOKKEEP (1 OF 2) 1-31-74
	AOS	ADEPTH
STRCLX:	LPCALL	(SETRCL)	;

;; #JK#
NXF:	HRRZ	PNT,%RVARB(PNT)	;ON TO NEXT
	JRST	FRSV	
PEX2:
;;#JK# RHT 13-3-72 3 OF 3
	HRLI	C,A		;RESTORE AC1 IF NEED
	MOVE	A,[POP RP,NOUSAC!USADDR!NORLC] ;
	TLNE	FF,FFTEMP	;DID WE SAVE IT
;;#QX# RHT ! FOR 2 (2 OF 2) 
	PUSHJ	P,[ SOS ADEPTH	;PUT IT BACK
		JRST	EMITER ]
;;#JK#
;;#IP#
	SKIPGE	BITS		;SPECIAL?
	 JRST	 DNTPSH		; YES, NO NEED SUBS OR PUSHES (DONE BFORE RETURN)
	MOVE	PNT,SLIMS	;VBL DESCRIPTOR BOUNDARIES
	MOVE 	A,SSDIS		;STRING STACK DISPL
	MOVEI	D,RSP		;INDICATE USE OF SP STACK
;⊗ PNT is Sem of last,,Sem of 1st; A is # str locs, RH(P) is #str params
	PUSHJ	P,RESTOR	;ADJUST THE STACK, RESTORE LOCALS

; NOW PUSH RESULT INTO CORRECT STACK LOC IF NECESSARY
	TRNE	TBITS2,STRING	;STRING PROCEDURE WHICH REQUIRED A SUB?
	CAIG	B,2		; (SET BY RESTOR, NUMBER SUBTRACTED)
	 JRST	 DNTPSH		; NO, NOT STRING OR RESULT IN RIGHT PLACE
	HRLI	C,-1(B)		;RELATIVE LOCATION OF RESULT TO CURRENT SP
	EMIT	<PUSH RSP,USADDR!NOUSAC!NORLC(RSP)>;#SUB'ED -1(SP)
	EMIT	<PUSH RSP,USADDR!NOUSAC!NORLC(RSP)>;#SUB'ED -1(SP)

; NOW ISSUE FIXUP FOR JUMPS AROUND ABOVE SUB/PUSH CODE

DNTPSH:	SETZM	BITS		;DON'T LEAVE BITS SCREWED UP
	HLLZ	B,$ADR(PNT2)	;THAT SPECIAL FIXUP
	JUMPE	B,NO2XIT	;NOBODY RETURNED NON-TEMP RESULT
	HRR	B,PCNT		;ISSUE FIXUP
	PUSHJ	P,FBOUT		;DOESN'T HAPPEN IN RECURSIVE PROCEDURES

NO2XIT:
	SKIPE	SIMPSW		;IF SIMPLE
	JRST	DOOUT		;NO NEED TO MANGLE F
	MOVEI	C,0		;
	EMIT	(<MOVE RF,USADDR!NOUSAC!NORLC(RF)>); RESET RF
DOOUT:  MOVSS	(P)		;WANT NO ARITH PARAMS
	MOVEI	D,RP		;WANT RP
	MOVE	A,ASDIS		;ARTIH STACK DISPL
	SKIPN	SIMPSW		;ONLY HAVE FOR NON SIMPLE
	ADDI	A,1		;SINCE (F) TAKES UP A WORD
	HRRZ	TEMP,(P)	;NOW CONSIDER THE CASE WHERE THERE
	ADDI	TEMP,-1(A)	; ARE NO LOCALS OR PARAMETERS
	TRNN	TEMP,-1		;
	JRST	[EMIT (<POPJ RP,NOUSAC+NOADDR>) ;(ONLY A RETURN
				 JRST	PENTRY]		;ADDRESS) -- DO POPJ

	MOVE	PNT,ALIMS	;PNT, A, D, (P) SET UP ANALAGOUS TO ABOVE CALL
	PUSHJ	P,RESTOR	;RESTORE THE P SIDE
	HRLZ	C,(P)		;NUMBER OF ARITH PARAMS.
	HRLI	D,RP		;USE THIS STACK AS INDEX
	EMIT	(<JRST USADDR+INDRCT+NORLC+USX+NOUSAC+JSFIX>);JRST @PARAMS(RP)
	
; NOW PRODUCE PROCEDURE ENTRY CODE IF RECURSIVE PROCEDURE

PENTRY:	POP	P,TEMP		;THROW THE #PARAMS PAIR AWAY
	TLNN	TBITS2,RECURS	;
	 JRST	 PRUPYU		;NOT RECURSIVE
	TRZN	TBITS2,INPROG	;NO LONGER FORWARD
; ***** BUG TRAP
	 ERR	 <DRYROT -- PENTRY>
	HRRM	TBITS2,$TBITS(PNT2) ;OFF IN MEMORY
;NOW, IF INTERNAL, PUT OUT PDA WORD
	TLNN	TBITS2,INTRNL	;IS THIS AN INTERNAL PROCEDURE??
	JRST	NOIN.1		;NO
	HRRZ	PNT,$VAL(PNT2)	;LOOK AT PROCEDURE DESCRIPTOR
	CAIN	PNT,0		;BETTER BE HERE
	ERR	<DRYROT -- DONT HAVE PD SEMBLK YET>
;;#SH# ! ADDED NOUSAC
	EMIT	<NOUSAC!JSFIX>		;PUT OUT PDA
;NOW THE PDA WORD IS OUT, IF NEED BE
NOIN.1:	HRLZ	B,$ADR(PNT2)	;FIXUP FOR EARLY JUMPS
	HRR	B,PCNT
	HRRM	B,$ADR(PNT2)	;THIS IS PROCEDURE ADDRESS
	TLNE	B,-1		;DID ANYONE CALL EARLY?
	PUSHJ	P,FBOUT		;ADDR,,FIXUP FOR EARLY CALLS

	PUSHJ	P,MKSEMT	;MARK THE STACK
	MOVEI	D,RP		;DO ARITH SAVES
	MOVE	A,ASDIS		;STACK DISPL
	SUBI	A,2		;FOR MSCP
	CAILE	A,0		;IF ANY ARITH LOCALS
	PUSHJ	P,SAVIT		;ZERO THE APPROPRIATE STUFF
	MOVEI	D,RSP		;STRING STACK
	SKIPE	A,SSDIS		;IF STRING LOCALS, BLT THEM TOO
	PUSHJ	P,SAVIT
	PUSHJ	P,SETF		;MAKE IT OFFICIAL
;; ! %BI% USED TO BE $ACNO
	HLL	C,$VAL2(PNT2)	;TEXT ADDR (OF AOS IF THERE IS ONE)
	EMIT	(<JRST NOUSAC+USADDR>)


PRUPYU:
BAIL<
	MOVE	TEMP,PCNT
	HRRZ	LPSA,$VAL(PNT2)	;PD SEMBLK
	SKIPE	LPSA
	 HRLM	TEMP,$VAL2(LPSA);ADDR OF LAST WORD OF CODE TO PD SEMBLK
>;BAIL
	TLO	FF,ALLOCT	;***** ASSUME SAVES ACS
	PUSHJ	P,ALOT		;ALLOCATE THE STORAGE
	GETSEM	(2)		;PROC SEMANTICS BACK
	PUSHJ	P,LNKMAK	;PUT OUT STRING LINK BLOCK IF NECESSARY

Comment ⊗ Now fix some syntactic things (restore counts,
	pointers, etc.), go up a level, and quit  .  ⊗

SYNTUP:	LEFT	PNT,%TLINK,LPSERR
	HRRZM	PNT,VARB	;CAN ADD ON FROM HERE
	SKIPE	$VAL(LPSA)	;RETURNING TO TOP LEVEL?
	 TLO	 FF,TOPLEV	; YES, RESET BIT
	MOVEW	(BLKIDX,<$BLKLP(LPSA)>) ;RESTORE OLD BLKIDX
	MOVE	TEMP,%SAVET(LPSA)
	HRRZM	TEMP,TPROC	;RESTORE VARB STRUCTURE POINTERS
	HLRZM	TEMP,TTOP
	MOVE	A,$TBITS(TEMP)	;PICK UP TYPE BITS OF PROC
;;#KB# RHT ! 1 OF 2 (11-11-72) MUST SAVE LPSA
	PUSH	P,LPSA		;SAVE THE LIFE OF MY AC
	PUSHJ	P,ZOTDIS
;;#KB# 2 OF 2 !
	POP	P,LPSA		;CRIED THHE DESPARATE PROGRAMMER
	SKIPE	SIMPSW		;
	SKIPA	TEMP,CDLEV
	SOS	TEMP,CDLEV	;
	HRLI	TEMP,RF		;PUT RF BACK RIGHT
	HLRZM	TEMP,DISTAB(TEMP);
	SETZM	RECSW		;ASSUME DADDY NOT RECURSIVE
	TLNE	A,RECURS	;UNLESS HE WAS
	SETOM	RECSW		;THEN SAY SO
	SETZM	SIMPSW		;RESTORE SIMPLE PROCEDURE FLAG
	TLNE	A,SIMPLE
	SETOM	SIMPSW		;SAY IT IS SIMPLE
	HRRZ	TEMP,TPROC	;GET IT BACK FOR THE NEXT LOAD
	HLRZ	A,%TLINK(TEMP) ;RIGHT TEMP,%TLINK,
	JUMPE	A,LPSERR	;   LPSERR
RGC <
	HLRZ	TEMP,%RVARB(A)	;RCTEMP LIST
	MOVEM	TEMP,RCTEMP
>;RGC
	MOVE	TEMP,%STEMP(A) ;GET PARTIAL CORE TEMP LIST BACK
	HRRZM	TEMP,TTEMP	;RESTORE TO RIGHTFUL POSITION
	SOS	NMLVL		;REDUCE DDT LEVEL
	SOS	LEVEL		;UP A LEVEL
	PUSHJ	P,CLRSET	;CLEAR OUT BITS
	TLNN	FF,CREFSW	;IF CREFFING, PUT OUT SYMBOLS FOR FORMALS.
	JRST	FREBUK		;RELEASE OLD BUCKET, RETURN
	HLRZ	LPSA,%TBUCK(LPSA)	; TO FIRST FORMAL.
CRFNO:	JUMPE	LPSA,FREBUK		;ALL DONE.
	PUSHJ	P,CREFDEF		;SYMBOL DEFINITION.
	HRRZ	LPSA,%RVARB(LPSA)
	JRST	CRFNO

Comment ⊗ FORWRD declarations come here to undo damage

at PD1:	PDNO ;   drarrow  NIL   EXEC FWUNDO  SCAN  ¬DS0
⊗

↑FWUNDO:
	QPOP	(FORMFX)	;GET STACK MARKER OFF
; ***** BUG TRAP
	SKIPLE	A		;MUST NOT HAVE PUT ANYTHING ON
	 ERR	 <DRYROT -- FWUNDO>
	GETSEM	(1)
	JRST	SYNTUP		;UP A LEVEL, RESET LIST POINTERS, ETC.


COMMENT ⊗    RESTOR, SAVIT,MKESMT,SETF -- Subroutines for Above

PAR (P)rh = #PARAMS (size of params)
 A     = #LOCALS (size of)
 PNT   = SEMANTICS OF LAST,,SEMANTICS OF FIRST TO BE RESTORED
RES B=# words subtracted
DES Sub sum of both from stack ref'ed in D if there are any (incl Str res in SUB)
 BLT from 1+paramsize(stack) to first local, ending at last local, if recursive ⊗

RESTOR:	PUSH	P,PNT		;SAVE POINTERS
	PUSH	P,A		;SAVE # LOCALS
	MOVEI	B,0		;IN CASE NONE SUBTRACTED
	ADD	A,-3(P)		;TOTAL TO SUBTRACT
	HRLS	A		;XWD
	JUMPE	A,RESDUN	;NOTHING TO DO AT ALL
	ADD	A,X22		;IF STRING PROCEDURE WITH ANY LOCALS OR PARAMS,
	CAIN	D,RSP		; AND ADJUSTING STRING STACK, SUBTRACT AN EXTRA
	TRNN	TBITS2,STRING
	 SUB	 A,X22		; TWO WORDS TO ACCOUNT FOR STRING RESULT
;;%DN% JFR 7-4-76
	MOVEI	B,(A)		;LIKE WE PROMISED
	MOVNI	TEMP,(A)	;NEGATE FOR ADJSP
	HRLI	C,(TEMP)	;INTO DISPL. FIELD
	PUSHJ	P,EADJSP
;;	PUSHJ	P,CREINT	
;;	HRRZ	B,$VAL(PNT)	;TOTAL NUMBER SUBTRACTED
;;	MOVE	A,[SUB]		;RESULTS TO PNT -- SOME OF THESE
;;	PUSHJ	P,EMITER	;EMITS SHOULD EVENTUALLY BE COMBINED
;;%DN% ↑
RESDUN:	POP	P,A			;REMOVE #PARAMS WORD
	POP	P,PNT			;SAVED PNT
	POPJ	P,


Comment  ⊗
IN:	A -- #locals
	D -- stack #
	PNT -- end,start semantics
⊗


SAVIT:
	PUSH	P,PNT
	PUSH	P,A
	MOVEI	A,0		;CREATE A ZERO
	PUSHJ	P,CREINT	;GET A ZERO
	EMIT	(<PUSH >)	; PUSH IT ONTO STACK
	SOSG	A,(P)		;ONE LESS ZERO TO BLT
	JRST	PSH1.1		;NOTHING LEFT TO DO
	CAILE	A,4		;BLT CHEAPER ONLY IF >4 MORE
	JRST	BLTIT		;
PSH1:	EMIT	(<PUSH >)	;PUSH A ZIP ON
	SOSLE	(P)		;COUNT DOWN
	JRST	PSH1		;GO PUSH ANOTHER
PSH1.1:	POP	P,A		;GET A BACK
	POP	P,PNT		;GET IT BACK
	POPJ	P,		;THATS ALL
BLTIT:  ;WE WILL DO A BLT
	HRL	D,D		;NEED STACK NO AS INX
	MOVEI	C,0		;ZERO DISPL
	EMIT(<HRLI RTEMP,NOUSAC!NORLC!USADDR!USX>) ;FROM HERE
	HRLI	C,1		;DISPL OF ONE
	EMIT(<HRRI RTEMP,NOUSAC!NORLC!USADDR!USX>) ;TO THERE
	;NOW FOR THE ADD
;;%DN%
	HRL	C,(P)		;COUNT
	PUSHJ	P,EADJSP	;ADJUST THE STACK
	MOVE	TEMP,ASWITCH
	TRNE	TEMP,AADJSP
	 JRST	BLTADN		;WE DID ADJSP, NO NEED FOR SKIPL AND PUSHJ $PDLOV
;;	MOVE	A,(P)		;GET THE COUNT INTO A
;;	HRLS	A		;XWD
;;	PUSHJ	P,CREINT
;;	EMIT	(ADD)		;ADD STK,[XWD SIZ,SIZ]
	HRL	C,D		;USE STACK # AS DISPL
	EMIT	(<SKIPL USADDR+NORLC+NOUSAC>) ;SKIPL STK
	HRL	C,PCNT		;EMIT INSTR TO CAUSE PDLOV.
	EXCH	C,LIBTAB+R$PDLOV ;FIXUP
	EMIT	(<JSP USER,NOUSAC!USADDR>)
BLTADN:	POP	P,A		;RESTORE STACK
	POP	P,PNT		;GET THIS BACK -- NOT IMPORTANT
	MOVEI	C,0		;ZERO	DISPL
	EMIT	(<BLT	RTEMP,NOUSAC!USADDR!NORLC!USX>);BLT RTEMP,(STK)
	POPJ	P,

;;%DN% ↑

COMMENT⊗
DSCR MKSEMT
DES	EMITS CODE TO BUILD ONE FHQ MSCP
PARM	PNT2 POINTS AT FIRST PROC SEMBLK
SID	MANGLES A,B,C,D,PNT,LPSA,TEMP
⊗

MKSEMT:	PUSH	P,FF			;SAVE IT
	HRLI	C,RF
	EMIT	(<PUSH RP,NOUSAC!USADDR!NORLC>); PUSH P,F
	MOVE	B,CDLEV			;IF PARENT IS GLOBAL, NO LOOP
	SOJG	B,SLNKIT
	HRRZ	A,$VAL(PNT2)		;A pnts to PD SEMBLK
	HLRZ	PNT,%TLINK(A)		;PNT ptr to PDA SEMBLK
	CAIE	PNT,0			;HAVE WE ONE?
	JRST	PPDAW			;YES
	GETBLK				;NO--GET ONE
	MOVE	PNT,LPSA		;SET PNT TO THIS ONE
	HRLM	A,%TLINK(PNT)		;LNK BACK
	HRLM	PNT,%TLINK(A)		;AND FWD
;;#  # (1 OF 2) BY JFR  THE JSFIX WAS MISSING
PPDAW:	EMIT	(<PUSH	RP,NOUSAC!JSFIX>)	;PUSH	P,[PDA,0]
;;#  #
	JRST	MKSSS			;GO DO STRING STUFF
SLNKIT:	PUSHJ	P,GETAN0		;GET AC FOR LOOP
	HRLI	C,RF
	EMIT	(<SKIPA, USADDR!NORLC>);SKIPA AC,F
	HRL	D,D			;USE AS INDEX
	HRLI	C,1
	EMIT	(<MOVE	USX!USADDR!NORLC>)	;MOVE AC,1(AC)
	HRLI	C,1
	EMIT    (<HLRZ RTEMP,NOUSAC!USX!USADDR!NORLC>);  HRLZ TEMP,1(AC)
	HLRZ	PNT,%TLINK(PNT2)	;2ND PROC SEMBLK
	HRRZ	PNT,%SAVET(PNT)		;PARENT PROC
	HRRZ	PNT,$VAL(PNT)		;POINT AT PARENTS PD SEMBLK
        EMIT	(<CAIE  RTEMP,NOUSAC!JSFIX>);
	HRLZ	C,PCNT	
	SUB	C,[XWD 3,0]
	EMIT	(<JRST 0,NOUSAC!USADDR>);JRST .-3
	HRRZ	PNT,$VAL(PNT2)	;PNT2 ptr to PD SEMBLK
;;#  # (2 OF 2) BY JFR  THE JSFIX WAS MISSING
	EMIT	(<HRLI JSFIX>)	;HRL AC,PDA
;;#  #
	HRL	C,D
	EMIT	(<PUSH RP,USADDR!NOUSAC!NORLC>);PUSH	 P,AC
COMMENT⊗

	NOW THAT AC IS STATIC LINK, MIGHT AS WELL REMEMBER THAT FACT
⊗
;;#VU# JFR 11-21-75 CANT USE THIS INFO BECAUSE APPLY MIGHT JUMP INTO MIDDLE
;;	AND THE REGISTER WOULD BE INVALID
;;	MOVE	B,CDLEV			;INTERNAL LEVEL
;;	SUBI	B,1			;DADDY
;;	PUSHJ	P,DISBLK		;LPSA ptr to DISPLAY SEMBLK
;;	HRRM	D,DISTAB(B)		;UPDATE DISTAB
;;#VU# ↑
MKSSS:	HRLI	C,RSP
	EMIT	(<PUSH RP,USADDR!NORLC!NOUSAC>)	;PUSH	P,SP
	HRRZ	PNT,$VAL(PNT2)		;MY PD SEMBLK
	HRRZ	A,PCNT			;PCNT AFTER MKSEMT
	HRLM	A,$ACNO(PNT)		;SAVED IN PD SEMBLK
	POP	P,FF
	POPJ	P,

COMMENT ⊗ 
DSCR	SETF
DIS	EMITS CODE TO SET UP NEW RF
PARM	SAME AS MKSEMT
SID	DITTO
⊗

SETF:	PUSH	P,FF
	HRRI	C,-2			;WILL BE -2(P) FOR E PART
	SKIPE   RECSW			;UNLESS IT WAS RECURSIVE
	MOVN	C,ASDIS
	HRLZ	C,C			;FOR ADDRESS PART
	EMIT    (<HRRZI RF,NOUSAC!NORLC!USADDR(RP)>); HRRZI RF,-2(P)
	POP	P,FF
	POPJ	P,
 

COMMENT ⊗  TWPR1, TWPR2 -- Procedure Syntax  Twiddlers⊗

DSCR TWPR1, TWPR2
PRO TWPR1, TWPR2
DES 
at IDL:	PDEC @IDL @I )  drarrow  PDEC   EXEC INTID ENDDEC TWPR2  SCAN
					   ¬PD1  # Q0
at PD0:	PDEC @I ;  drarrow  PDEC ;  EXEC PRDEC TWPR1    ¬PD1  #Q0
⊗

↑TWPR2:	MOVE	PNT,GENRIG
	MOVEI	A,0		;RESULTS TO PARRIG
	JRST	TWPR
↑TWPR1:	MOVE	PNT,GENRIG+1
	MOVEI	A,1
TWPR:	PUSHJ	P,GETAD
	MOVE	TEMP,%PDNO	;IF FORWARD, PARSER WILL LOOK FOR NO
	TRNE	TBITS,FORWRD	; PROCEDURE BODY
	MOVEM	TEMP,PARRIG(A)	;MODIFIED SYNTACTIC ENTRY
	POPJ	P,

SUBTTL	Procedure Calls

COMMENT ⊗RDYCAL -- Prepare to Call Procedure⊗

DSCR RDYCAL
PRO RDYCAL
DES 
	@CALL SG  drarrow  @CALL SG   EXEC RDYCAL  ¬

Prepare for a procedure call.
A block needs to be prepared to hold information about the
	call, because  PROC(a,PROC(b)) would otherwise
	cause awful confusion.  The block contains:

    1. In  %TLINK, ptr to procedure semantics
    2. In  %TBUCK, ptr to next formal parameter definition
    3. In  $ADR, initial Qstack pointer for FTRPRM. 
    4. In  $VAL, SDEPTH,,0. These (the stack counts) will be restored after the call.
	The reason that ADEPTH cannot be saved has to do with the way LEAP
	stacks things one too late.  In other words, when a fucntion call is
	seen, the ADEPTH count is really one too low, and all hell will break
	loose if the procedure caller merely restores things.  So it must keep
	explicit count of what has happened.

The preparation of this block constitutes preparation for
	the procedure call.
⊗

↑RDYCAL: 
	GETBLK	(GENRIG)
	JRST	RDYCL

↑RDYCL1: 
	GETBLK	(GENRIG+1)	;LPSA pnts to NEW BLOCK
RDYCL:
;; #LJ# ALL LEAP ARGS MUST REALLY BE STACKED BEFORE PROCEDURE CALL
	PUSH	P,LPSA		;SAVE LPSA OVER OKSTACK
	PUSHJ	P,OKSTAC	;MAKE SURE EVERYTHING IS STACKED THAT SHOULD BE
	POP	P,LPSA		;RESTORE LPSA

	GETSEM	(1)		;PNT ptr to  SEMANTICS OF PROCEDURE
	TLNE	FF,LPPROG	;FOREACH IN PROGRESS?
	TLNN	TBITS,MPBIND	;AND THIS A MATCHING PROCEDURE?
	JRST	NOMPRO
	PUSH	P,PNT		;SAVE IT
	PUSH	P,LPSA		;IT ALSO
	PUSHJ   P,CHKSAT	;POP SATISFIERS INTO CORE IF NECESSARY
	MOVEI	A,0
	PUSHJ	P,CREINT
	GENMOV	(STACK,0)	;RESERVE A PLACE FOR ITEM PARAM TO SPROUT
	POP	P,LPSA
	POP	P,PNT
NOMPRO:
GLOC <
	SKIPN	MESFLG		;IS THIS A MESSAGE PROCEDURE ?
	 JRST	 NOMESQ		;NOPE
	SETZM	MESFLG		;RESET THE FLAG.
	TLO	SBITS,LPFREE	;THIS IS HOW WE TELL EVERYONE.
	TLNN	TBITS,MESSAGE
	ERR	<MESSAGE: REQUIRES MESSAGE PROCEDURE>,1
	MOVEM	SBITS,$SBITS(PNT);
NOMESQ:
>;GLOC
	MOVEM	TBITS,$TBITS(LPSA)
	MOVEM	SBITS,$SBITS(LPSA) ;COPY THESE
	HRLM	PNT,%TLINK(LPSA)
	EXCH	PNT,LPSA
	TLNE	TBITS,OWN	;BUILT-IN FUNCTION?
	JRST	BLTN		; YES, GO SET UP BYTE POINTER
	LEFT	,%TLINK,LPSERR	;SECOND BLOCK OF PROC
	LEFT	(,%TLINK)		;ptr to FIRST PARAM OR NIL
	HRRM	LPSA,%TBUCK(PNT)
QCAL:	QPUSH	(FTRPRM)		;MAKE SURE STACK IS
	QPOP	(FTRPRM)		;INITIALIZED
	MOVE	TEMP,FTRPRM
	MOVEM	TEMP,$ADR(PNT)	;SAVE QSTACK POINTER
; lh of $VAL used to collect the number of string elements to be removed
; after the call -- rh is used for non-string elements.
;*-*	HRLZ	TEMP,SDEPTH
;*-*	MOVEM	TEMP,$VAL(PNT)	;SAVE SDEPTH,,0
GLOC <
	TLNN	SBITS,LPFREE	;IF A MESSAGE PROCEDURE, THEN
	POPJ	P,		;
	XCALL	<.MES1>		;PREPARE FOR THE CALLS.
>;GLOC
	POPJ	P,

BLTN:	MOVEI	TEMP,$SBITS+2(LPSA)
	HRLI	TEMP,440600	;POINT 6,FIRST PARAM WORD
	MOVEM	TEMP,$VAL2(PNT)	;STORE FOR PARAM DESCRIPTOR RETRIEVAL
	JRST	QCAL		;FINISH UP

;MESSAGE PROCEDURE STARTER.

↑MESCL:
GLOC <
	SETOM	MESFLG		;NEXT FCALL IS A MESSAGE.
>;GLOC
NOGLOC <
	ERR	<This compiler will not handle MESSAGE PROCEDURES>,1
>;NOGLOC
	POPJ	P,

COMMENT ⊗  Describe CALARG⊗

DSCR CALARG
PRO CALARG
DES
at SID:	IPR SG  drarrow  S SG   EXEC ISUCL1	¬S9

at EE2:	PCALL @E )  drarrow  S   EXEC CALARG ISUCAL  SCAN  ¬S9
	FCALL @E )  drarrow  P  EXEC CALARG ISUCAL TYPPRO  SCAN  ¬XID
	@CALL @E ,  drarrow  @CALL  EXEC CALARG   ¬EX0
	IPR SG   drarrow  P SG   EXEC ISUCL1  TYPR1   ¬XID

Generate parameter calls, issue procedure calls

A. Parameter calls
  Several things have to happen here:
  1. REFERENCE or VALUE determines whether an address or a 
	value will be "PUSH"ed. For reference parameters,
	certain things are illegal (i.e. expressions, procedure
 	executions) unless we are issuing a FORTRAN call. Procedures
	with no parameters must be called unless the formal is a
	(reference, non-FORTRAN) procedure. The address word (with
	types) is created (if possible) for reference 
	parameters.  A reference parameter called by reference is a special
	case.

  2. A destination must be determined. For FORTRAN calls, the
	semantics of the created (address) word is pushed into
	a compile time "buffer" Qstack. For others, the
	thing is stacked appropriately on the P or SP stack
	(code is issued).
⊗

COMMENT ⊗  CALARG -- Pass a Parameter⊗

TOOMNY:	ERR	<TOO MANY ARGUMENTS SPECIFIED TO PROCEDURE>,1
;;#GW# 5-11-72 DCS (1-4) AVOID CALLING AT RUNTIME WITH TOO MANY PARAMS
	TLNN	TBITS,CONOK	;TRYING TO CALL AT COMPILE TIME?
	 JRST	 SAMADR		;NO
	TLO	TBITS,400000	;SOMETHING SILLY -- DON'T DO IT.
	MOVEM	TBITS,(SP)	;UPDATE
	JRST	SAMADR
;;#GW# (1-4)
↑CALARG: PUSH	P,SP		;GOOD SAFE AC
	PUSH	P,ADEPTH	;THIS IS FOR COMPARING PURPOSES.... SEE BELOW
	GETSEM	(2)		;SEMANTICS OF PROCEDURE CALL BLOCK
	MOVE	SP,PNT		;SAVE HERE
	TLNE	TBITS,ANYTYP	;IF ON, ASSUME REFERENCE, TYPE OK
	 JRST	 SAMADR
	TLNE	TBITS,OWN	;BUILT-IN PROCEDURE?
	 JRST	 [ILDB	TBITS2,$VAL2(PNT) ; YES, GET FORMAL DESCRIPTION
		 JUMPE	TBITS2,TOOMNY	; TOO MANY ARGUMENTS SUPPLIED
		TRZ	TBITS2,40	; TURN OFF DEFAULTABLE BIT
		 MOVE	TBITS2,BLTTBL(TBITS2)
		 JRST	BLTBAK		;CONTINUE AFTER SIMILAR BRANCH
]

	HRRZ	PNT2,%TLINK(SP)	;PNT2 pnts to  NEXT FORMAL PARAM DESCR
	JUMPE	PNT2,[TRNN	TBITS,FORTRAN	;FORTRAN CALL?
		      JRST	TOOMNY		;NO -- TO MANY ARGS CITED.
		      SETOM	TBITS2		;FLAG AS DON'T CONVERT
		      JRST	FTRARG]		;ELSE GO AWAY.
	HRRZ	LPSA,%RVARB(PNT2) ;ptr to NEXT FORMAL PARAM AFTER THIS
	HRRM	LPSA,%TBUCK(SP)	;STORE POINTER TO NEXT IN CALL BLOCK
	MOVE	TBITS2,$TBITS(PNT2) ;ALL THAT'S IMPORTANT
BLTBAK:	TRNE	TBITS,FORTRAN	;FORTRAN CALL?
	 JRST	 FTRARG		; YES
	GETSEM	(1)		;SEMANTICS OF ACTUAL TO PNT GROUP
REC <
	TRNE	TBITS2,PNTVAR	;CHECK RECORD CLASSES HERE
	TDNE	TBITS2,[XWD SBSCRP,ITEM!ITMVAR!SHORT]
				;DONT CHECK ARRAYS AND
				;NEVER CHECK ITEMISH STUFF(UNLESS CHECKED?)
	JRST	BLTB.1
	PUSH	P,LPSA		;PARANOIA
	PUSH	P,PNT2		;
;;#TV# RHT 1-22-75 DON'T CHECK IF RUNTIME ROUTINE
	MOVE	LPSA,$TBITS(SP)	;CHECK PROCEDURE SEMANTICS
	TLNE	LPSA,OWN	;IF RUNTIME ROUT, CLASS IS ANY
	JRST	BLTB.Z		;IT IS
;;#TV# ↑
	HLRZ	PNT2,$ACNO(PNT2);CLASS OF FORMAL
BLTB.X:	HLRZ	LPSA,$ACNO(PNT)	;CLASS OF ACTUAL
BLTB.Y:	PUSHJ	P,SUBFOK
	ERR	<CLASS DISAGREEMENT IN ACTUAL-FORMAL RECORD PAIR>,1
BLTB.Z:	POP	P,PNT2
	POP	P,LPSA
BLTB.1:
>;REC
	TLNE	TBITS2,REFRNC	;BY REFERENCE?
	 JRST	 REFARG		; YOU BETCHUM

	TLNE	TBITS2,MPBIND	;A FORMAL ? ITEMVAR
	JRST	MPPARM		;YES
; ***** BUG TRAP
	TLNN	TBITS2,VALUE	;TEST UNLIKELY CASE
	 ERR	 <DRYROT -- CALARG>,1

; VALUE PARAMETER
	TLNN	SBITS,LPFRCH!FREEBD
	JRST	VALPAR
	TLNE	SBITS,LPFREE
	ERR	<UNBOUND LOCAL AS PARAMETER TO PROCEDURE>,1
	PUSHJ   P,CHKSAT	;POP SATISFIERS INTO CORE IF NECESARY

VALPAR:	TLNE	TBITS,SBSCRP	;MAKE A TEST
	 ERR	 <ARRAYS BY VALUE NOT IN>,1
	PUSH	P,TBITS2	;SAVE FORMAL TYPE BITS
	TRNE	TBITS,PROCED	;IF VALUE PROCEDURE, NO PARAMS,
	 PUSHJ	 P,CALNPR	; CALL IT NOW
OKPRM:	POP	P,B		;TYPE OF FORMAL
	TLNN	TBITS,FORMAL!SBSCRP	;FOR LEAPISH CONSTRUCTS.
	TRNN	TBITS,ITEM
	JRST	GMV
	TRNN	B,ITEM!ITMVAR		;TARGET TYPE
	ERR	<ITEM TYPE MISMATCH>,1	;BLOW
	SKIPE	PNT,$VAL2(PNT)		;PLACE WHERE ITEM NUMBER IS STORED.
	PUSHJ	P,GETAD			;AND GET HIS BITS.
	HRRI	FF,POSIT
	JRST	GMV2+1
GMV:	TRNE	TBITS,ITEM!ITMVAR
	JRST	GMV2
	TRNE	TBITS,LSTBIT
	JRST	[TRNN	B,LSTBIT	;BOTH LISTS, NO WORRY
		 ERR <WARNING-LIST EXPR. COERCED TO SET EXPR>,1
		 JRST	.+1]
GMV2:
	HRRI	FF,INSIST!POSIT
;;#  # DCS 2-29-72 CALL F(CONST,...) AT COMPILE TIME
	MOVE	TBITS2,$TBITS(SP)	;PROC CALL BLOCK BITS
	TLNE	TBITS2,CONOK		;STILL OK?
	TLNN	TBITS,CNST		; ALSO NO USE IF THIS NOT CONST
	 JRST	 STRET			;NO
	GENMOV	(CONV)			;MAKE SURE CONVERTED
	HRRI	FF,0			;IN CASE NOT CONST
	TLNN	TBITS,CNST		;CONST OF RIGHT TYPE?
	 JRST	 STRET			;NO
; STILL CONOK, SAVE CONST
	QPUSH	(FTRPRM,PNT)		;SAVE THE SEMBLK
	POP	P,ADEPTH		;NO CHANGE TODAY
	POP	P,SP			;GET STACK BACK
	POPJ	P,			;DONE RIGHT NOW
;;#  #

STRET:	PUSHJ	P,CONCHK		;STACK PREV CONSTS
REC <
	TRNE	TBITS,PNTVAR		;A RECORD POINTER??
	TRNE	TBITS,777777-(PNTVAR!GLOBL)
	JRST	NOTRCD			;NOPE
NORGC <
	GENMOV	(GET,MRK!INDX)		;YEP,HAVE TO BUMP REF CNT. GET WILL DO IT
					;NOTE: IF THIS ALREADY WAS A REGULAR TEMP
					;THEN THE GET WILL NOT BUMP THE COUNT AGAIN
>;NORGC
RGC <
	TLNE	SBITS,INAC		;IS THE THING INAC
	JRST	STRT.1			;YES
	EMIT	<MOVE TEMP,NOUSAC>	;NO, GET IT THERE IN A HIGHLY MARGINAL WAY
	SKIPA	D,[TEMP]		;
STRT.1:	HRRZ	D,$ACNO(PNT)		;FIND OUT WHAT AC ITS IN
	PUSHJ	P,GETRCT		;GET US AN AVAILABLE RECORD CORTMP
	HRRZ	TEMP,$ACNO(SP)		;SP POINTS AT PROC CALL SEM. (UGH!!)
	HRRM	TEMP,%TLINK(LPSA)	;LINK ONTO CHAIN
	HRRM	LPSA,$ACNO(SP)		;LIKE SO
	PUSH	P,PNT			;SAVE THE THING WE ARE GOING TO PUSH
	MOVE	PNT,LPSA		;NOW MOVEM INTO THIS TEMP
	EMIT	(<MOVEM>)		;
	POP	P,PNT			;SO THAT THE PUSH EVENTUALLY WINS
>;RGC
NOTRCD:
>;REC
	GENMOV	(STACK)			;DO THE PUSH.
	MOVEI	PNT,0			;SO WON'T REMOP TWICE
	MOVSI	TEMP,2			;Keep track of the number of string
;;#HM# JRL 5-31-72 AVOID DRYROT BY STRING ARGS TO MESSAGE PROCEDURE
	MOVE	SBITS,$SBITS(SP)		;WILL TELL IF A MESSAGE PROC. CALL
;;#HR# JRL 6-14-72 A STRING ITEM IS NOT A STRING
	TRNE	TBITS,ITEM!ITMVAR	;TURN OFF STRING BIT FOR ITEMS
	TRZ	TBITS,STRING
;;#HR#
	TRNE	TBITS,STRING		; words which will adjust SDEPTH
	TLNE	SBITS,LPFREE		;A MESSAGE PROCEDURE
	JRST	CALRET			;If message pro, or not string no sdepth change
	ADDM	TEMP,$VAL(SP)		; when call is finished.
;; #HM#
	JRST	CALRET			;DONE ALREADY


CONCHK:	PUSH	P,B
;; #MA (1 OF 4) ! SAVE FF OVER CALL
	PUSH	P,FF
	MOVE	TEMP,$TBITS(SP)		;CONOK bit on in this Semblk (PCALL
	TLZN	TEMP,CONOK		; block) if calling runtime which can
;; #MA (2 OF 4) !
	 JRST	FBPOPJ			; be evaled at comp. time, and all prev
	MOVEM	TEMP,$TBITS(SP)		; args were const -- but this arg is
	MOVE	B,$ADR(SP)		; non-const, so must recover.
	CAMN	B,FTRPRM		;If there were no previous constant
;; #MA (3 OF 4) !
	 JRST	 FBPOPJ			; args, there is nothing left to do.
	PUSH	P,PNT			;Now issue stack code for each arg
CONCAL:	QTAKE	(FTRPRM)		; previously saved (types already
	 JRST	 CONDUN			; matched up before saving).
	MOVE	PNT,A
	GENMOV	(STACK,GETD!REM)
	MOVSI	TEMP,2			;Update the ADEPTH or SDEPTH count in
	TRNN	TBITS,STRING		; Pcall Semblk -- will be used to readjust
	 AOSA	 $VAL(SP)		; these variables when call finished.
	 ADDM	 TEMP,$VAL(SP)
	JRST	CONCAL
CONDUN:	MOVE	TEMP,$ADR(SP)		;No REF args were handled, our part of
	MOVEM	TEMP,FTRPRM		; this stack had only consts, can remove.
	POP	P,PNT			;Now the state of things is as if the
	PUSHJ	P,GETAD			; stack code had gone out the first time.
;; #MA (4 OF 4) ! RESTORE FF
FBPOPJ:	POP	P,FF
BPOPJ:	POP	P,B
	POPJ	P,

MPPARM:				;BINDING ITEMVAR PARAMETER
	TRNN	TBITS,ITEM!ITMVAR	;BETTER BE ITEM TYPE
	ERR	<PARM TO  ? ITEMVAR NOT ITEM EXPRESSION>,1
	TLNE	PNT,FBIND!QBIND		;IS IT BIND ITEMVAR?
	JRST	PASREF			;WILL PASS BY REFERENCE
	TLNE	SBITS,LPFRCH!FREEBD
	TLNN	SBITS,LPFREE		;STILL FREE WITHIN FOREACH?
	JRST	VALPAR			;NO TREAT AS VALUE PARAMETER
NTPARM: QPUSH	(MPQSTK,PNT)		;PUT THIS ON PARM LIST
; AT THIS POINT GENERATE APPROPRIATE LPCALL FOR POTUNB IF NECESSARY.
;;#TJ# ! USED TO BE TBITS
	TLNE	SBITS,FREEBD
	JRST	[MOVE PNT,$VAL2(PNT)	;GET LOCAL NUMBER
		 GENMOV (STACK,0)
		 LPCALL (STKQPR)	;INTERPRETIVE CALL TO SEE IF BOUND
		 JRST CALRET]
PASREF:	PUSH	P,PNT			;SAV LH ACTUALLY
	GENMOV  (INCOR,0)		;MAKE SURE NOT IN AC
	HRLI	PNT,20			;WANT INDIRECT BIT
	SETOM	MPFLAG			;TO TELL THAT WE WANT TYPE BITS
	PUSHJ	P,FTRADR		;GET ADCON
	GENMOV	(STACK,0)		;STACK IT
	SETZM	MPFLAG
	POP	P,PNT
	TLNN	PNT,QBIND
	JRST	CALRET
	HRLZI	D,RP			;WILL NOW LOAD VAL FROM STACK
	EMIT	<MOVEI TAC1,INDRCT!NOUSAC!NOADDR!USX> ; GEN MOVEI TAC1,@(P)
	HRLI	C,UNBND			;FOR COMPARE WITH UNBOUND
	EMIT	<CAIE TAC1,NOUSAC!USADDR!NORLC>
	EMIT	<MOVEM TAC1,NOUSAC!NOADDR!USX>
	JRST	CALRET

; FORTRAN ARGUMENT -- ASSURE VALID TYPE

FTRARG:
	GETSEM	(1)
	TLNE	TBITS,SBSCRP
	 ERR	 <DON'T PASS ARRAYS TO FORTRAN (YET)>,1
	TRNE	TBITS,PROCED	;PROCEDURES MUST BE EVALUATED
	 PUSHJ	 P,CALNPR	; CALL WITH NO PARAMS
	HRRI	FF,INSIST!POSIT
	SKIPG	B,TBITS2	;THIS IS THE TYPE WE HOPE FOR
	TRC	FF,INSIST!ARITH	;NO TYPE SPECIFIED -- JUST GET ARITH.
	TLNE	TBITS,CNST	;PROTECT CONSTANTS BY MOVING THEM.
	 JRST	 CNGET
	GENMOV	(CONV)
	JRST	 MAKADR		;GO MAKE ADDRESS CONSTANT
CNGET:	TRO	FF,MRK
	GENMOV	(GET)
	JRST	MAKADR

REFARG:	PUSHJ	P,CONCHK	;STACK PREV CONSTANTS
	TRNE	TBITS2,PROCED	;IF FORMAL ¬ PROCEDURE,
	 JRST	 CHKEXP
	TRNE	TBITS,PROCED	;AND ACTUAL IS ONE, ERROR
	PUSHJ	P,CALNPR	;MAKE IT AN EXPRESSION TO PASS BY REFERENCE
CHKEXP:
; #HZ# JRL 6-27-72 TEST SBSCRP BIT BEFORE ALL OTHERS
	TLNE	TBITS,SBSCRP
	JRST	CKTYP
	TRNE	TBITS,ITEM
	ERR	<DO NOT PASS ITEMS BY REFERENCE>,1
	TRNE	TBITS2,LSTBIT	;LIST FORMAL?
	JRST	[TRNE	TBITS,LSTBIT;	AN ACTUAL LIST?
		 JRST .+1	;YES
		 MOVE B,SET!LSTBIT
		 JRST	RTYPER]
	TLNE	SBITS,LPFRCH!FREEBD
	ERR	<FOREACH LOCAL AS REFERENCE PARAMETER>,1
; #HZ#
	TLNN	SBITS,ARTEMP!STTEMP ;EXPRESSION?
	 JRST	 CKTYP		;NO
	TLNE	SBITS,FIXARR	;FIXED CALCULATED ARRAY THING?
	 JRST	 CKTYP		; YES, DON'T WORRY
	TLNN	SBITS,INDXED	;OK IF CALCULATED SUBSCRIPT

	JRST	[TRNN	TBITS2,STRING ;DON'T ALLOW STRING EXP BY REF
		 ERR	<WARNING: EXPRESSION BY REFERENCE;
WILL WORK BUT INACCESSABLE AFTER CALL>,1
		STREXP: TRNE TBITS2,STRING
		ERR	<NO STRING EXPRESSIONS BY REFERENCE>,1
		GENMOV	(INCOR)
		QPUSH	(FTRPRM,PNT)	;SAVE FOR LATER REMOPING
		JRST	.+1]		;GO CHECK TYPES

CKTYP:	
;;%AE% RHT ALLOW TYPED ITEMVARS THROUGH TO ITEMVAR FORMALS
	TRNE	TBITS2,ITMVAR		;ITEMVAR FORMAL
	TRNE	TBITS2,¬<ITMVAR+PROCED>	;ANYTHING ELSE TOO
	JRST	.+2			;NO CHANGE
	TRZ	TBITS,¬<ITMVAR+PROCED>	;TURN OFF THE BAD GUYS
;;%AE%
	TRNA	TBITS,PROCED		;SPECIAL CHECK
	JRST	[PUSH	P,TBITS2
		HRRZ	TEMP,GENLEF+1	;GET THE ARGUMENT PROCEDURE
		TLNE	TBITS,OWN	
		JRST	CKTYPO		;EVEN SPECIALER
CKTYP0:		HRRZ	TEMP,%RVARB(TEMP)	;GET PARMS TO PARM PROC
		JUMPE	TEMP,CKTYP2		;DONE
		HRRZ	TBITS2,$TBITS(TEMP)	;GET BITS
		TLNN	TBITS2,REFRNC		;PARMS OF PRAM PROC MUST BE REF.
		ERR	<PARAMETERS TO A PROCEDURE ARGUMENT TO A PROCEDURE MUST BE REFERENCE>,1
		JRST	CKTYP0
CKTYPO:		MOVEI	TEMP,$ACNO(TEMP)	;MAKING  BYTE POINTER
		HRLI	TEMP,440600		;POINT 6,FIRST PARM WORD
CKTYP1:		ILDB	TBITS2,TEMP		;GET BITS
;;#??# RHT WHAT IS GOING ON HERE?????
		JUMPE	TBITS,CKTYP2		;DONE
		TLNN	TBITS,REFRNC		;
		ERR	<PARAMETERS TO A PROCEDURE ARGUMENT TO A PROCEDURE MUST BE REFERENCE>,1
		JRST	CKTYP1
CKTYP2:		POP	P,TBITS2
		JRST	.+1    ]


	MOVE	B,TBITS		;ALGORITHM IS TO MAKE SURE THAT ALL BITS
	AND	B,[XWD SBSCRP,ALTYPS]	;ON IN ACTUAL ARE ON IN FORMAL.
	SETCM	TEMP,TBITS2	;THIS ALLOWS ARRINFO AND FRIENDS TO HAVE
	TLNE	TBITS2,SBSCRP	;IF FORMAL REQUIRES ARRAY, THEN MAKE SURE IT IS
	TLNE	TBITS,SBSCRP
	TDNE	B,TEMP		;ANY TYPE ARRAYS PASSED TO THEM.

RTYPER:	JRST	[TERPRI <WARNING: TYPE MISMATCH FOR REFERENCE CALL>
		 TERPRI <CONVERTED EXPRESSION WILL BE PASSED BY REFERENCE>
		 ERR	<ORIGINAL VARIABLE WILL NOT BE ALTERED BY PROCEDURE>,1
		 MOVE   B,TBITS2
		 GENMOV	(CONV,INSIST)	;MAKE TYPE CONVERSION
		 MOVE	TBITS2,TBITS	;DON'T LET IT HAPPEN AGAIN!
		 JRST	STREXP]

	JRST	MAKADR		;FINISH UP


; CREATE FORTRAN-LIKE TYPE BITS FOR AC FIELD

SAMADR:	GETSEM	(1)		;NOBODY ELSE GOT ACTUAL'S SEMANTICS
MAKADR:	MOVE	TBITS2,$TBITS(SP)	;GET PROC BITS BACK
	TLNE	SBITS,INDXED	;NO NEED TO STORE INDXED THINGS
	 JRST	 LATER		; BECAUSE DYNAMAK AND FRIENDS WILL
	GENMOV	(INCOR)		;MAKE SURE ARG IS IN CORE.

LATER:	
	TRNE	TBITS2,FORTRAN	;IF HERE AND FORTRAN, WE DEFINITELY
	 JRST	 .+3		;WANT TO STAY HERE DAMMMMMIT
	TLNE	TBITS,REFRNC
	 JRST	 REFREF		;REF CALLED BY REF (SPCL CASE)
;;%DT% FORTRAN-10 WANTS 2 FOR INTEGR, 4 FOR FLOTNG
	TRNN	TBITS2,FORTRAN
	 JRST	.+3		;NOT FORTRAN
	SKIPE	TEMP,ASWITCH
	TRNN	TEMP,ASWF10
	 TDZA	TEMP,TEMP	;NOT FORTRAN-10, START AT ZERO
	MOVEI	TEMP,2		;FORTRAN-10, ADD 2
;;%DT% ↑
	TRNE	TBITS,FLOTNG	;0 FOR INTEGR, 2 FOR FLOATING,
	ADDI	TEMP,2
	TLNE	TBITS,SBSCRP	;8 + OTHERS FOR ARRAYS
	ADDI	TEMP,=8
	LSH	TEMP,5		;TO AC POSITION
	HRL	PNT,TEMP	;TO AC AREA

; PNT NOW CONTAINS SEMANTICS OF REF VBL IN LH, TYPES IN RH

	TRNE	TBITS2,FORTRAN	;CALLING FORTRAN?
	 JRST	 FTRSAV		;YES, JUST SAVE ADCON SEMANTICS
	TLNN	TBITS,SBSCRP	;STACK VBL ITSELF IF SBSCRP
	PUSHJ	P,ADRINS	;GET ptr to  ADCON IN PNT, ETC.
	GENMOV	(STACK,0)		;STACK IT
	JRST	 CALRET

FTRSAV:	PUSHJ	P,FTRADR	;GET (UNIQUE) ADCON SEMANTICS
	QPUSH	(FTRPRM,PNT) ;SAVE SEMANTICS TILL LATER
	JUMPL	PNT,[POP P,A
		     POP P,SP
		     POPJ P,]
	JRST	CALRET

REFREF:	GENMOV	(STACK,ADDR)	;JUST STACK IT AGAIN (REF BY REF)
CALRET:	
	MOVE	SP,GENLEF+2		;SINCE TOTAL USES THE DAMNED THING.
	POP	P,A			;OLD ADEPTH.
GLOC <
	MOVE	SBITS,$SBITS(SP)	;SBITS FOR PROCEDURE.
	TLNN	SBITS,LPFREE		;IF A MESSAGE PROCEDURE IS BEING ISSUED.
	JRST	CAL00			;NO
	MOVE	TBITS2,$TBITS(PNT2)	;DESTROYED IF A REFERENCE.
	TRNE	TBITS2,PROCED!LABEL	;THESE NOT ALLOWED.
	 ERR	 <MESSAGE: INVALID PARAMETER LIST MEMBER>,1
	TRNE	TBITS2,STRING		;GODDAMN
	TLNE	TBITS2,REFRNC
	JRST	.+3			;FIGURE OUT WHICH STACK TO SUBTRACT
	SOS	SDEPTH
	SOSA	SDEPTH
	SOS	ADEPTH			;ALL OVER.
	HRL	C,TBITS2		;GET THE TBITS WORD IN TAC1
	EMIT	(<MOVEI TAC1,USADDR!NOUSAC!NORLC>)
	HLL	C,TBITS2
	EMIT	(<HRLI TAC1,USADDR!NOUSAC!NORLC>)
	XCALL	<.MES2>			;AND PROCESS THE PARAM.
	JRST	NOADJ		;DO NOT INDEX COUNTS. -- OTHERWISE DOOM.
CAL00:
>;GLOC
	CAME	A,ADEPTH		;SAME AS NOW (WAS THERE A PUSH DONE??)
	AOS	$VAL(SP)		;NO -- UPDATE COUNTS.
NOADJ:	POP	P,SP		;RESTORE STACK
	JRST	REMOP		;REMOVE TEMP ARGS,RETURN

↑CALNPR: PUSH	P,GENRIG	;SINCE ISUCL1 DESTROYS IT.
	MOVEM	PNT,GENLEF+1	;SIMULATE A CALL TO RDYCAL
	PUSHJ	P,RDYCL1	;AS THE PARSER WOULD DO IT
	MOVEW	GENLEF+1,GENRIG+1 ;RESULTS BACK TO LEFT SIDE
	PUSHJ	P,ISUCL1	;CALL THE PROCEDURE
	MOVE	PNT,GENRIG+1
	POP	P,GENRIG	;RESTORE THE BLESSED CELL (IT ONLY POINTS TO PROC).
	JRST	GETAD		;LEAVE ITS SEMANTICS IN PNT, ETC.

COMMENT ⊗    ADRINS -- Subrt for Above -- Prepare an Address Constant (Semblk)

Address constant blocks have fixup information for
	address constants necessary for procedure calls. The
	constants are of the form:

	TYP(fortran),,address, where TYP is:

  0  for integer
  2  for floating
  8 + others for arrays

An ADCON block uses %RVARB to link to the ADRTAB ring.
	The %TLINK field indicates the intity whose AD
	is being CONned. The type is inserted in the left
	half of $ADR -- fixups for the ADCON go in $ADR(rh).
	These constants will be output after space is 
	allocated for the associated variables, or at the
	time of a FORTRAN call. For temps and those
	blocks involved in a FORTRAN call, unique ADCON
	blocks are assigned for each eventual word of code. For 
	others, fixups are chained via a search of the 
	ADCON list.

IN:	PNT -- TYPE,,semantics of entry
OUT:	PNT,TBITS,SBITS -- semantics of result
	C(lh) -- old fixup
Call ADRINS for normal insertion, FTRADR for unicke ones
If FTRADR is called with MPFLAG non-zero the type bits,
in left half PNT will be inserted but otherwise FORTRAN-like
things won't happen (see DYNAMAK)
If MPFLAG is set the address of the array is considered to be
the address of the cell containing the descriptor. I don't
believe ADRINS is every called with an array except if MPFLAG
is set.
⊗

↑ADRINS: TLOA	FF,FFTEMP	;CONDUCT A SEARCH
↑FTRADR: TLZ	FF,FFTEMP	;DON'T
	PUSHJ	P,GETAD		;GET SEMANTICS OF AD TO BE CONNED
	TRNE	SBITS,DLFLDM	;IF A DISPLAY REG IS NEEDED
	JRST	DYNAMAK		;MUST DO DYNAMAK
;; #KD# ! RHT 11-13-72 FOLLOWING INSTR HAD SBITS MISSING
	TLNE	SBITS,CORTMP	;ALSO CHECK THE CASE OF TEMPS IN REC PRO
	SKIPN	RECSW		;
	JRST	.+2		;
	JRST	DYNAMAK		;
NOREC <
	TRNE	TBITS,PNTVAR	;DON'T REALLY UNDERSTAND THESE YET
	 ERR	 <POINTER VARS MAY NOT BE CALLED BY REFERENCE>,1
>;NOREC
	TLNE	SBITS,FIXARR	;IF HAVE CALCULATED WHOLE INDEX THING,
	 JRST	 DYNAMAK	; GET IT WITH A MOVEI
	TLNN	TBITS,FORMAL	;IF ARG IS NOT IN FIXED LOC,
	TLNE	SBITS,INDXED
	 JRST	 DYNAMAK	;  CREATE ADCON AT RUN TIME

	TLNN	FF,FFTEMP	;ALSO IF FORTRAN TYPE ADCON
	 JRST	 INSNEW		;JUST INSERT A NEW ONE
	TLNE	SBITS,ARTEMP	;DON'T SEARCH FOR TEMP MATCHES
	 JRST	 TEMLUK		; IN THE SAME WAY

	TLNE	TBITS,CNST	;ALSO CONSTANTS DONE DIFFERENTLY
	JRST	CONADD



SRCH:	MOVE	LPSA,ADRTAB	;ADDRESS CONSTANT "RING"
	JUMPE	LPSA,INSNEW	;NOTHING YET, MAKE SOMETHING
SRCLUP:	HLRZ	TEMP,%TLINK(LPSA) ;ptr to SEMANTICS OF THING
	CAIN	TEMP,(PNT)	;SAME STUFF?
	 JRST	 FOUND1		;YES, FOUND ONE
	LEFT	,%RVARB,INSNEW	;KEEP LOOKING
	 JRST	 SRCLUP

TEMLUK:	TLNN	SBITS,CORTMP	;MUST BE A CORTMP
	ERR	<DRYROT -- TEMLUK>
	MOVE	LPSA,ADRTAB	;SEARCH ADCON TABLE FOR SAME ID NO
	JUMPE	LPSA,INSNEW	;NONE FOR THIS TEMP YET
	MOVE	A,$PNAME(PNT)	;TEMP ID NO FOR THIS TEMP

TMLUUP:	MOVE	TEMP,$SBITS(LPSA)
	TLNN	TEMP,ARTEMP	;MUST BE TEMP OR DON'T LOOK
	JRST	LEFLUK
	CAMN	A,$PNAME(LPSA)	;SAME TEMP?
	 JRST	 GETADL		;YES, THIS IS THE RESULT
LEFLUK:	LEFT	,%RVARB,INSNEW	;LOOP UNLESS YOU RUN OUT
	JRST	TMLUUP


FOUND1:	HLLZ	TEMP,$ADR(LPSA) ;MAKE SURE TYPE HASN'T CHANGED
	HLR	TEMP,PNT
	TSC	TEMP,TEMP	;SEE IF TYPE FROM ADCON IS SAME
	SKIPN	TEMP		; AS THAT COMING IN
	JRST	GETADL		;IT IS,DONE

INSNEW:	GETBLK
				;GET ANOTHER ONE
	PUSHJ	P,RNGADR	;ADD THIS ADCON TO ADRTAB
	HLLM	PNT,$ADR(LPSA)	;STORE TYPE
	HRLM	PNT,%TLINK(LPSA) ;AND SEMANTICS OF THING BEING ADCONNED

	MOVEW	(<$PNAME(LPSA)>,<$PNAME(PNT)>) ;TRANSFER ID NO IF ANY
	MOVEI	TEMP,INTEGR	;TYPE FOR ADCON ITSELF, IF NEEDED
	MOVEM	TEMP,$TBITS(LPSA)
	MOVEM	SBITS,$SBITS(LPSA)	;SAVE SBITS FOR ADCON TYPE DETERMINATION



	HRR	PNT,LPSA		;DO NOT CLOBBER LEFT HALF OF PNT.
	JRST	GETAD			;THAT'S IT.




CONADD:	TRNE	TBITS,STRING	;WILLING TO PASS ALL BUT STRING CONST
	ERR	(<NO STRING CONSTANTS BY REFERENCE>,1) ;BY REFERENCE
	PUSH	P,$VAL(PNT)	;SAVE FOR A MOMENT
	PUSH	P,$TBITS(PNT)
	PUSHJ	P,REMOP		;IN CASE IN AC
	POP	P,BITS
	POP	P,A
	PUSHJ	P,ADCINS	;SPECIAL ENTRY (UNIQUE)
	JRST	INSNEW		;MAKE ADCON FOR THIS UNIQUE CONSTANT
DYNAMAK: 
	MOVEM	TBITS,TBSAVE	;SAVE SBITS
	TLNE	TBITS,SBSCRP	;AN ARRAY
	TLZN	TBITS,REFRNC	;TURN OFF REFERENCE BIT
	CAIA
	TLO	TBITS,VALUE	;TURN ON VALUE BIT IF WAS REFRNC
	MOVEM	TBITS,$TBITS(PNT); 
	GENMOV	(GET,ADDR!REM)	;WILL GET ADDRESS OF THING WITH A MOVEI
				;IT ALL HAPPENS MAGICALLY
	MOVE	TBITS,TBSAVE
	MOVEM	TBITS,$TBITS(PNT)
	HLLZ	C,PNT		;TYPE BITS, USE AS ADDR FLD OF HRLI
	PUSHJ	P,MARKINT	;MARK AN INTEGER FOR KICKS.
	TLNE	FF,FFTEMP	;FORTRAN CALL REQUIRE THIS ADCON?
	 POPJ	 P,		;NO, LEAVE SEMANTICS FOR PUSH
	JUMPN	C,NDBITS	;ARE THERE NON-ZERO TYPE BITS
	SKIPE	MPFLAG		;IF NO BITS AND NOT FORTRAN
	POPJ	P,		;RETURN
NDBITS:
;;%DT%
	SKIPN	TEMP,MPFLAG	;DON'T CHANGE INSTR IF LEAP CALL: MPFLAG IS SETZM/SETOM
	SKIPE	TEMP,ASWITCH	;FORTRAN CALL, WHICH KIND?
	TRNN	TEMP,ASWF10	;ALWAYS SKIPS IF LEAP
	 TLO	C,(<JUMP>)	;F40 CALL PUTS NOOP HERE
	EMIT	(<HRLI  USADDR+NORLC>) ;HRLI AC,TYPE*2↑5
	SKIPE	MPFLAG
	POPJ	P,		;IF REMEMBER OF MP RETURN NOW.
	PUSHJ	P,REMOP		;DON'T NEED SEMANTICS ANYMORE
	PUSH	P,TBITS		;JUST IN CASE
	PUSH	P,SBITS
	MOVEI	TBITS,INTEGR
	PUSHJ	P,GETCRTMP	;A CORETEMP FOR THE COMPUTED ADDRESS
	MOVEI	PNT,(LPSA)
	EMIT	(<MOVEM>)	;STORE THE ADDRESS
	POP	P,SBITS
	POP	P,TBITS
	IOR	PNT,C		;COPY BITS
	TLO	PNT,400000	;AND MARK LH NEG
;;%DT% ↑
	POPJ	P,


COMMENT ⊗  ISUCAL -- Call the Procedure, Mark Resultant Type, etc.⊗

DSCR ISUCAL, ISUCL1
PRO ISUCAL ISUCL1
RES
	PCALL @E )   drarrow   S	EXEC CALARG ISUCAL  SCAN  GO S9
	FCALL @E )   drarrow   P	EXEC CALARG ISUCAL  TYPPRO  SCAN  GO XID
	IPR SG       drarrow   P SG	EXEC ISUCL1 TYPR1  GO XID
⊗

↑ISUCAL:
	SKIPA	PNT,GENLEF+2	;GET PROCEDURE

↑ISUCL1:
	MOVE	PNT,GENRIG+1	;   CALL BLOCK SEMANTICS
				; (PLACED BY RDYCAL FOR ISUCL1)

ISSUE:	PUSH	P,$ADR(PNT)	;CONTAINS SAVED FTRPRM PTR.
	PUSH	P,$VAL(PNT)	;RESTORE DEPTHS
				;BUT AFTER CALLING ALLSTO, ETC.

BICHK:	MOVE	TBITS2,$TBITS(PNT) ;NEED TO CHECK BUILT-IN
	MOVE	C,TBITS2	;FOR CONST EVAL DON'T DO IT FLAG
	TLNE	TBITS2,OWN	; IS IT?
	 JRST	[MOVE	B,$VAL2(PNT) ;YES, GET NEXT PARAM DSCRPTR
		ILDB	TEMP,$VAL2(PNT)	; SO CAN RESTORE
		 JUMPE	TEMP,OKCAL	;SHOULD BE 0 (NONE LEFT)
		TRZN	TEMP,40		;DEFAULTABLE?
		JRST	ERCAL		;NO
		MOVE	TBITS,BLTTBL(TEMP);TBITS OF THIS ARG
		TLNN	TBITS,VALUE	;REF NEVER DEFAULTED
		JRST	ERCAL
		PUSH	P,PNT		;SAVE PNT
		MOVEI	A,0		;COMMON NULL VALUE
		MOVE	PNT,UBSBLK	;
		TRNE	TBITS,ITMVAR	;ITEMVARS ARE SET TO NEC
		JRST	SFFPRM
		TRNE	TBITS,STRING	; A STRING GETS A NULL STRING
		JRST	NSTVP		;
		PUSHJ	P,CREINT	;
	SFFPRM:	MOVE	TEMP,PNT	;
		MOVE	PNT,(P)		;THE PROCID
		MOVEM	B,$VAL2(PNT)
		JRST	PCA1		;GO PUSH THE CONST ARG
	NSTVP:	PUSH	P,BITS		;SAVE SOME CRUFT
		PUSH	SP,PNAME	;
		PUSH	SP,PNAME+1	;
		SETZM	PNAME		;NULL
		PUSHJ	P,STRINS	;MAKE ONE
		POP	SP,PNAME+1	;
		POP	SP,PNAME	;PUT EM BACK
		POP	P,BITS		;
		JRST	SFFPRM		;GO STACK IT
]

	RIGHT	PNT,%TBUCK,OKCAL ;MAKE SURE FORMAL LIST IS EMPTY
	HRRZ	TEMP,$VAL2(LPSA)	;GET DEFAULT VALUE , IF ANY
	JUMPE	TEMP,ERCAL		;YOU LOSE
PCA:	PUSH	P,PNT			;SAVE
PCA1:	PUSH	P,GENLEF+1		;
	PUSH	P,GENLEF+2		;
	MOVEM	TEMP,GENLEF+1		;
	MOVEM	PNT,GENLEF+2		;
;;#WL# JFR 3-16-76 BUMP REF CNT OF STRING DEFAULT PARAM SO REMOP WONT DRYROT
	MOVEI	PNT,(TEMP)
	PUSHJ	P,GETAD
	TRNN	TBITS,ITEM!ITMVAR
	TRNN	TBITS,STRING
	 JRST	.+2
	AOS	$VAL2(PNT)
;;#WL# ↑
	PUSHJ	P,CALARG		;OH, WHAT A DREADFUL THING TO DO
	POP	P,GENLEF+2		;
	POP	P,GENLEF+1		;
	POP	P,PNT			;PUT EM BACK THE WAY THEY WAS
;;#NH# RHT 7-25-73 1 OF 1 THE THINGS ON THE STACK WERE CHANGED BY CALARG
	SUB	P,X22
	JRST	ISSUE			;TRY AGAIN
;;#NH#

ERCAL:	 ERR	 <NOT ENOUGH PARAMETERS SUPPLIED TO PROCEDURE>,1
;;#GW#! 5-11-72 DCS (2-4) DON'T CALL AT COMPTIME IF WRONG NUMB. OF PARAMS
	 TLO	 C,400000	;FLAG ERROR -- DON'T EVAL AT COMPILE TIME
NORGC <
OKCAL:	HRRZ	LPSA,PNT	;RELEASE CALL BLOCK,
	HLRZ	PNT,%TLINK(PNT)	;  GET SEMANTICS OF PROC
>;NORGC
RGC <
OKCAL:	PUSH	P,PNT	
	HRRZ	PNT,$ACNO(PNT)		;FETCH THE THINGS TO REMOP
	JUMPE	PNT,OKCA.1		;NONE LEFT
OKCA.0:	EMIT	<SETZM NOUSAC>		;ZERO IT OUT
	MOVE	LPSA,PNT		;
	HRRZ	PNT,%TLINK(PNT)		;GET NEXT
	PUSHJ	P,REMOPL		;
	JUMPN	PNT,OKCA.0		;LIKE SO
OKCA.1:	POP	P,LPSA			;FOR THE FREBLK
	HLRZ	PNT,%TLINK(LPSA)	;PROC CALL SEMANTICS
>;RGC
	FREBLK
	PUSHJ	P,GETAD		; PNT, ETC. DESCRIBE PROC SEMANTICS
;;#  # DCS 2-29-72 COMPILE-TIME CALL OF PROCEDURE
	TLNN	TBITS2,CONOK	;If CONOK on, all args were const, we call
	 JRST	 NC		; the procedure now, recording approp. const.
	POP	P,TEMP		;Any saved Depths are irrelevant now
	EXCH	SP,STPSAV	;Prepare stacks and pdlov-message information
	MOVSS	POVTAB+6	; for the impending call.
	MOVE	B,(P)		;Fetch start of our part of stack, verify that
	CAMN	B,FTRPRM	; there were args, or quit.
	 JRST	 NA
NOWLUP:	QTAKE	(FTRPRM)	;Actually stack each constant value, then REMOP
	 JRST	 NA		; its representation.  Choose the right stack.
	MOVE	PNT2,A
	PUSHJ	P,REMOP2
	MOVE	TBITS2,$TBITS(PNT2)
;;#GW#! 5-11-72 DCS (3-4) SEE JUST ABOVE
	JUMPL	C,NOWLUP	;DON'T DO IT IF MARKED
	TRNE	TBITS2,STRING
	 JRST	 NOWSTR
	PUSH	P,$VAL(PNT2)
	JRST	NOWLUP
NOWSTR:	PUSH	SP,$PNAME(PNT2)
	PUSH	SP,$PNAME+1(PNT2)
	JRST	NOWLUP
NA:	HLRZ	TEMP,$ADR(PNT)	;Get the address of the procedure from its
;;#GW#2! 5-11-72 DCS (4-4) SEE JUST ABOVE
	JUMPL	C,NS
	PUSHJ	P,(TEMP)	; Semblk, and call it for its value
;;#GW#! SEE JUST ABOVE
	MOVEM	1,SCNVAL	;Store resultant value where CONINS will expect
	TRNN	TBITS,STRING	; it, along with the desired type bits from
	 JRST	 NS		; the procedure's type.
	HRRZ	TEMP,-1(SP)	;Align Strings to full-word boundary by
	JUMPE	TEMP,NLS	; concatenating 0 (if non-null)
	PUSH	SP,[1]
	PUSH	SP,[POINT 7,[0]]
	PUSHJ	P,CAT
	SOS	-1(SP)		; then remove the extra character from the end
NLS:	POP	SP,PNAME+1
	POP	SP,PNAME
NS:	EXCH	SP,STPSAV	;PUT OLD STACKS BACK
	MOVSS	POVTAB+6
	ANDI	TBITS,-1≠<PROCED!FORWRD!INPROG>
	TLO	TBITS,CNST
	MOVEM	TBITS,BITS
	PUSHJ	P,CONINS
	POP	P,FTRPRM	;Back the Qstack up to value at start of call
	JRST	MRKDN		;This just records the result
;;#  #
	
NC:
GLOC <
	TLZN	SBITS,LPFREE	;A MESSAGE PROCEDURE ??
	JRST	CAL01		;NO
	MOVEM	SBITS,$SBITS(PNT)
	HRROI	B,$PNAME+1(PNT)	;PRINT NAME.
	POP	B,PNAME+1
	POP	B,PNAME		;AND READY TO
	PUSHJ	P,STRINS	;MAKE A CONSTANT.
	PUSHJ	P,GETAD		;GET BITS.
	GENMOV	(STACK,0)	;PISS ON IT.
	SOS 	SDEPTH
	SOS	SDEPTH		;SINCE TYPPRO WILL ADD 2 TO SDEPTH
	MOVEI	TBITS2,STRING	;CROCK -- THIS IS THE TYPE OF MESS.
;#IK#! 7-5-72 RHT PREVENT DL FLD OF SBITS FROM CAUSING MUCH BAD DISPLAY LOADING
	MOVEI	SBITS2,0	;RENDER SBITS2 HARMLESS (FOR FUTURE EXCHIN &STACK)
	JRST	MRKCAL		;AND FINISH OUT
CAL01:
>;GLOC

	PUSHJ	P,STORIX	;INTERNALS.AND EXTERNALS ARE NOW STORED.
	TRNE	TBITS,FORTRAN	;IF FORTRAN CALL
	 JRST	 FTRCAL		;GO ISSUE IT.
	MOVEI	D,1		;PREPARE TO STORE R1
;;#TO# ! (2-2) RHT 10-27-74 (USED TO BE INTEGR+FLOTNG)
	TRNE	TBITS,SNGTYP	;DEFINED IN SAIL/13
	 PUSHJ	 P,STORZ	;DO IT IF TYPED ARITH PROC.
	TLNN	TBITS,BILTIN	;UNLESS BUILTIN PROC.
	 PUSHJ	 P,ALLSTO	;STORE THE REST.


DPUSHJ:

;;  BY JRL 9-20-72  MAKE SURE PROCEDURE FORMALS CAN BE ACCESSED
	GENMOV	(ACCESS,0)		;MAKE SURE WE HAVE ACCESS
;;  BY JRL 
	MOVE	A,[PUSHJ RP,NOUSAC]	;PUSHJ PDP,ROUTINE.
	TLNE	FF,LPPROG		;A FOREACH IN PROGRESS AND
	TLNN	TBITS,MPBIND		;A MATCHING PROCEDURE?
	PUSHJ	P,EMITER
MVCAL:	MOVOPS			;PROC SEMANTICS TO SECOND GROUP.
;BUG TRAP
	SKIPN	B,-1(P)		;SAVED FRTPRM POINTER.
	ERR	<DRYROT AT DPUSHJ>

QQQLRX: QTAKE	(FTRPRM)	;POP OFF A GOODY
	 JRST	 LLQRLX
	PUSH	P,B
	MOVE	PNT,A
	PUSHJ	P,REMOP		;REMOP IT
	POP	P,B
	JRST	QQQLRX		;GET ALL OF THEM
LLQRLX:
	MOVEI	D,1		;IF ARITH TYPE, RESULTS IN R1
	JRST	MRKCAL		;FINISH OUT, MARK RESULT

;;#HT# 6-14-72 DCS (1-2) SAVE ALL ACS, ALSO RF, WHEN FORTRAN SUBROUTINE
FTRCAL:	TRNN	TBITS2,ALTYPS≠(FORTRAN!PROCED);TYPED PROCEDURE?
	 JRST	 [PUSHJ	P,ALLSTO
		  HRLI	C,RF	;NO, STORE ALL ACS, SAVE F
		  EMIT (<PUSH RP,NOUSAC!USADDR!NORLC>)
		  JRST  CALFTR]
;;RW#HT# (1-2)
	MOVEI	D,0		;ASSURE R0 FREE
	PUSHJ	P,STORZ
	MOVEI	D,1		;AND R1
	PUSHJ	P,STORZ
CALFTR:
;;%DT% JFR 8-22-76
	SKIPE	TEMP,ASWITCH
	TRNN	TEMP,ASWF10
	 JRST	CALF.1		;NOT FORTRAN-10
	SKIPN	B,-1(P)		;FTRPRM PTR
	 ERR	<DRYROT -- FTRCAL>;NOT THERE
	MOVEI	C,0		;COUNT PARAMS
CALF.2:	QTAKE	(FTRPRM)
	 JRST	.+2
	AOJA	C,CALF.2
	PUSH	P,C		;SAVE # PARAMS
	HRLI	C,RSP
	EMIT	(<PUSH RP,NOUSAC!USADDR!NORLC>)	;NEED TO SAVE SP
	AOS	ADEPTH
	MOVE	C,PCNT
	ADDI	C,4
	MOVSI	C,(C)
	EMIT	(<MOVEI RSP,NOUSAC!USADDR>)	;MOVEI 16,.+4
	EMIT	(<PUSHJ RP,NOUSAC>)	;PUSHJ P,ROUTINE
	MOVE	C,(P)		;# PARAMS
	ADD	C,PCNT
	ADDI	C,2
	MOVSI	C,(C)
	EMIT	(<JRST NOUSAC!USADDR>)	;JRST AROUND ADDRESS BLOCK
	POP	P,A		;# PARAMS
	MOVNI	A,(A)
	MOVSI	A,(A)
	PUSHJ	P,CODOUT	;-N,,0
	JRST	CALF.3
CALF.1:	EMIT	(<JSA 16,NOUSAC>) ;JSA 16,ROUTINE
CALF.3:
;;%DT% ↑
	MOVOPS			;SEMANTICS OF PROC TO 2D GROUP
; ***** BUG TRAP
	SKIPN	B,-1(P)		;FTRPRM POINTER
	 ERR	 <DRYROT -- FTRCAL> ;WASN'T A POINTER
ARGLUP:	QTAKE	(FTRPRM)	;GET NEXT ADCON DESCRIPTOR
	 JRST	 LLLQRX		; DONE WITH ADCONS
	PUSH	P,B		;SAVE UPDATED POINTER
	JUMPL	A,ARGFIX	;MOVEI,HRLI,MOVEM WAS DONE, FIX IT UP
	PUSH	P,A		;SAVE ADCON POINTER
	HLRZ	PNT,%TLINK(A)	;SEMANTICS OF AD BEING CONNED
	HLLZ	A,$ADR(A)	;TYPE BITS, ALREADY IN AC FIELD POS
	PUSHJ	P,GETAD	;GET DESCRIPTION
;;%DT%
	SKIPE	TEMP,ASWITCH
	TRNN	TEMP,ASWF10
	TLO	A,(<JUMP>)	;F40 ONLY
	TRO	A,NOUSAC	;BOTH
;;%DT% ↑
	PUSHJ	P,EMITER	;JUMP TYP,ADDR
	PUSHJ	P,REMOP		;GET RID OF IT
	POP	P,A		;GET POINTER BACK
	HRRZ	LPSA,A		;ptr to SEMANTICS OF ADCON
	PUSHJ	P,URGADR	;REMOVE FROM ADRTAB
	FREBLK			;RETURN ADCON BLOCK TO FREE STORAGE

	POP	P,B		;UPDATED STACK PTR
	JRST	ARGLUP		;GET ALL OF THEM

ARGFIX:
;;%DT%
	MOVEI	PNT,(A)		;ADDR OF SEMBLK OF CORE TEMP FOR ADDRESS
	TLC	A,400020	;REMOVE FLAG, INSERT @
	HRRI	A,NOUSAC
	PUSHJ	P,EMITER	;BITS,@TEMP
	PUSHJ	P,REMOP		;NO LONGER NEED TEMP
	POP	P,B		;UPDATED QSTACK PTR
;;%DT% ↑
	JRST	ARGLUP		;RETURN

LLLQRX:	MOVEI	D,0		;IF TYPED, RESULT IN 0
MRKCAL: 
	HLRZ	TEMP,(P)	;NUMBER OF SDEPTH ADJUST WORDS
	SUB	TEMP,SDEPTH	;ADJUST
	MOVNM	TEMP,SDEPTH
	HRRZ	TEMP,(P)	;SIMILAR ADEPTH STUFF
	SUB	TEMP,ADEPTH
	MOVNM	TEMP,ADEPTH
	POP	P,TEMP		;TOSS OUT
	POP	P,FTRPRM	;RESTORE OLD QSTACK PTR
	SETZM	PNT
	TLNE	FF,LPPROG	;A FOREACH IN PROGRESS?
	TLNN	TBITS2,MPBIND	;THIS A MATCHING PROCEDURE CALL?
	JRST	ISTYPD		;NO

	MOVE	TEMP,%MPRO	;MESSAGE PROCEDURE TOKEN
;; #QG# TOKEN BEING PLACED IN WRONG LOC WHEN NO PARAMS
	MOVE	PNT,PNT2	;TO BE REPLACED IN PARSE STACK
	HLRZ	PNT2,%TLINK(PNT) ;SECOND PROCEDURE BLOCK
	MOVE	PNT2,$NPRMS(PNT2)	;ANY PARAMETERS
	CAMN	PNT2,[XWD 1,0]
	JRST	[MOVEM TEMP,PARRIG+1 ;NO PARAMETERS WAS AN ISUCL1
		 JRST  MRKDN]
;; #QG#
	MOVEM	TEMP,PARRIG	;TELL THE PARSER
	JRST	MRKDN		;FINI
ISTYPD:
REC <
	TRNE	TBITS2,PNTVAR			;A POINTER PROCEDURE
	TRNE	TBITS2,ITEM!ITMVAR		;THESE ARE DIFFERENT
	JRST	NOTPPP				;NOPE
	HLRZ	TEMP,$ACNO(PNT2)		;REMEMBER CLASS ID FOR MARK
	MOVEM	TEMP,RCLASS			;NEXT MARK WILL DO THIS
NOTPPP:
>;REC
;;%DT%
	SKIPE	TEMP,ASWITCH
	TRNN	TEMP,ASWF10
	 JRST	NF10.1
	MOVSI	C,RSP
	EMIT	(<POP RP,NOUSAC!USADDR!NORLC>)
	SOS	ADEPTH
NF10.1:
;;%DT% ↑
;;#HT# 6-14-72 DCS (2-2) RESTORE SAVED RF REGISTER
	TRNE	TBITS2,ALTYPS≠(FORTRAN!PROCED)	;TYPED PROC?
	 JRST	 TYPRC		;YES
	TRNN	TBITS2,FORTRAN	;NO, FORTRAN PROCEDURE?
	 JRST	 MRKDN		;NO, QUIT
	HRLI	C,RF		;YES, UNTYPED F4, RESTORE RF
	EMIT	(<POP RP,NOUSAC!USADDR!NORLC>)
	JRST 	MRKDN
;;#HT# (2-2)
TYPRC:	GENMOV	(MARK,EXCHIN)	;TEMP INDICATES TYPE OF PROCEDURE
	MOVEI	TEMP,2		;IF A STRING PROC, INCREASE
;;#HS# JRL 6-14-72 STRING ITEMVAR PROC. IS NOT A STRING PROC.
	TRNE	TBITS,ITMVAR!ITEM;STRING ITEMVAR PROC. NOT REALLY STRING
	JRST	MRKDN
;;#HS#
	TRNE	TBITS,STRING	; STRING STACK DEPTH
	ADDM	TEMP,SDEPTH
MRKDN:	MOVEM	PNT,GENRIG	;ONE OF THESE
	MOVEM	PNT,GENRIG+1	;WILL COVER IT
	POPJ	P,


SUBTTL	Return Statement

COMMENT ⊗RESULT -- Return (with or without value) from Procedure⊗

DSCR RESULTS, RESLT1
PRO RESULT RESLT1
DES 
at RT0:	  SG ;  drarrow  S ;		EXEC RESLT1      ¬S9
   EE2:	RETURN ( @E )  drarrow  S	EXEC RESULTS SCAN  ¬S9
⊗

;  SETUP PROCEDURE FOR BOTH KINDS OF RETURNS
RETSET:	MOVE	PNT2,TPROC		;CAN ONLY RETURN FROM INNERMOST PROC
	PUSHJ	P,GETAD2		;SEMANTICS OF IT
	TLNE	TBITS2,MPBIND		;MATCHING PROCS ARE NO-NO'S
	ERR	<RETURN NOT VALID WITHIN MATCHING PROC.>,1
	MOVSI	TEMP,RTNDON		;MARK RETURN DONE THIS PROC
	IORM	TEMP,$SBITS(PNT2)	;IN SEMBLK
	EXCH	TEMP,(P)		;GEQ 0 IN TOP OF STACK, RETN TO TEMP
	JRST	(TEMP)			;RETURN

↑RESLT1: PUSHJ	P,RETSET		;GET SEMANTICS OF THIS PROC TO 2D GROUP
	TRNE	TBITS2,ALTYPS≠PROCED	;CANNOT BE TYPED
	 ERR	 <TYPED PROCEDURE MUST RETURN A VALUE>
	JRST	JMPOU1			;GENERATE THE ARRAY RELEASES AND EXIT JUMP

↑RESULTS:PUSHJ	P,RETSET
	TRNN	TBITS2,ALTYPS≠PROCED	;THIS MUST BE TYPED
	 ERR	 <UNTYPED PROCEDURE MUST NOT RETURN A VALUE>,1
;;#HQ#! 6-13-72 DCS ITEMVARS ARE ITEMVARS, NOT THEIR DATUMS!!!!!!!
	TRNN	TBITS2,ITEM!ITMVAR	;PRECLUDE DATUMS
	TRNN	TBITS2,STRING		;STRING VALUE RETURNED?
	 JRST	 ARRET			; NO, ARITHMETIC VALUE

STRRET:	LEFT	PNT2,%TLINK,LPSERR 	; LPSA ptr to  2D PROCEDURE BLOCK
	HRRZ	A,$NPRMS(LPSA)		;#PARAMS(STRING)
	GETSEM	(1)			;GET SEMANTICS OF RESULT
	TLNN	TBITS2,RECURS		;IF NOT RECURSIVE PROCEDURE
	TLNE	SBITS,STTEMP		; AND NOT A TEMP RESULT, THEN CAN
	 JRST	 RTSTR1			; DO THE SUB HERE, ELSE JUST STACK
	TRNE	TBITS,STRING		;IF RESULT IS STRING VALUE FORMAL,
	TLNN	TBITS,VALUE		; AND IS FIRST STRING PARAM,
	 JRST	 NOTEZY			; CAN REPLACE SUB/PUSH BY DIFFERENT SUB
	HRRZ	TEMP,$NPRMS(LPSA)	;# STRING WORDS
	SUBI	TEMP,1			;-1 TO MATCH HOPEFUL CANDIDATE
	CAME	TEMP,$ADR(PNT)		;THIS THE FIRST STRING PARAM?
	 JRST	 NOTEZY			; NO
	SUBI	A,2			;REMOVE ONE FEWER STRINGS (LEAVE ANSWER)
	PUSHJ	P,MARKME		;NOW A TEMP STRING-TYPE RESULT
	MOVEM	PNT,GENLEF+1		;WILL BE PICKED UP LATER
NOTEZY:	JUMPE	A,RTSET			;IF NOTHING TO SUBTRACT, DON'T DO IT

	MOVN	TEMP,A			;UPDATE SDEPTH TO REFLECT THE COMING SUB
	ADDM	TEMP,SDEPTH		; SO THAT REFERENCES TO PARAMS ARE RIGHT
;;%DN% JFR 7-2-76
	HRLI	C,(TEMP)
	PUSHJ	P,ESPADJ
;;	HRLS	A			; IN SUBSEQUENT STACKING OPERATION
;;	PUSHJ	P,CREINT		;FOR SUB
;;	EMIT	<SUB RSP,NOUSAC> 	;SUB RSP,[XWD #,#]
;;	PUSHJ	P,REMOP			;REMOVE CONSTANT FROM USE
;;%DN% ↑
RTSET:	SETOM	(P)			;<0 IN TOP OF STACK, MARK THIS CASE

RTSTRG:	GETSEM	(1)			;SEMANTICS OF RESULT
RTSTR1:	MOVEI	B,STRING
	GENMOV	(STACK,INSIST)		;MAKE SURE RESULT IS STACKED
	SETZM	SDEPTH			;DON'T RECORD EFFECTS OF THIS PUSH
	JRST	JMPOU1			;RETURN


ARRET:	GETSEM  (1)			;ARG.
	MOVEI	D,1			;RESULTS TO AC 1
	HRRZ	B,TBITS2		;TYPE CONVERSION IF NECESSARY
;; #JT# BY JRL 10-21-72 COPY SET TO BE RETURNED
	TRNN	TBITS,ITMVAR
	TRNN	TBITS,SET
	JRST	ARRET2
	PUSH	P,PNT
	GENMOV	(STACK,INSIST)
	MOVEI	A,0
	PUSHJ	P,CREINT
	GENMOV	(STACK,GETD)
	LPCALL  (CATLST)
	MOVNI	A,2
	ADDM	A,ADEPTH
	HRLI	C,1
	EMIT	<POP RP,NOUSAC!USADDR!NORLC>
	POP	P,PNT
	PUSHJ	P,GETAD
	JRST	ARRET3
;; #JT#
ARRET2:	GENMOV	(GET,INSIST!SPAC!POSIT) ;LOAD THE AC
ARRET3:	PUSHJ	P,REMOP

JMPOUT:	PUSHJ	P,CLEARA		;FORGET ABOUT  AC  1
JMPOU1:	EXCHOP				;GET PROC SEMANTICS BACK FROM HIDING
RETJMP:	PUSHJ	P,GOSTO			;DUMP EVERYTHING, BUT REMEMBER WHERE
	MOVE	B,LEVEL			;CURRENT LEVEL
	SUBI 	B,1			;DO NOT ENCOUNTER PROCEDURE
	PUSH	P,PNT
	PUSHJ	P,TRAGO			;GUARANTEE ACCESS
	POP	P,PNT			;THE WORK IS DONE.
	MOVE	A,[JRST NOUSAC+USADDR]	;THE JUMP OUT
	HRR	C,PCNT			;PUT CURRENT IN CHAIN
	POP	P,TEMP			;IF <0, NON-REC, NON-TEMP STRING RESULT
	JUMPL	TEMP,OTHJMP		; JUMP PAST SUB/PUSH PAIR IN EXIT CODE
	HRL	C,$ACNO(PNT)		;THIS IS WHERE PROC. RET. FIXUP IS STORED.
	HRRM	C,$ACNO(PNT)		;CHAIN THE FIXUP.
	JRST	EMITER			;EMIT JUMP
OTHJMP:	HLL	C,$ADR(PNT)		;OTHER JUMP ADDR
	HRLM	C,$ADR(PNT)		;CHAIN
	JRST	EMITER			;DO IT


COMMENT ⊗DFVPV -- exec for default param values ⊗

ZERODATA();
PBITTS:	0			;SAVE PARAM BITS HERE
ENDDATA

↑DFVPV0:	MOVE	A,BITS			;
	MOVEM	A,PBITTS		;SAVE THE BITS
	POPJ	P,

↑DFVPV:	MOVE	PNT,VARB		;THE MOST RECENT FORMAL ON VARB 
DFV.01:	PUSHJ	P,GETAD			;RING
	TLNE	TBITS,FORMAL		;
	JRST	GOTVCT
	HRRZ	PNT,%RVARB(PNT)		;
	JUMPN	PNT,DFV.01		;
	ERR	<DRYROT IN DFVPV, CAN CONTINUE>,1;
	JRST	DFV.2			;
GOTVCT:	TLNE	TBITS,REFRNC		;
	ERR	<DEFAULT VALUES FOR REF PARAMS IS A VERY BAD IDEA>,1
	MOVE	PNT2,GENLEF+1		;THE VALUE
	HRRM	PNT2,$VAL2(PNT)		;
DFV.2:	MOVE	A,PBITTS		;PUT BITS BACK
	MOVEM	A,BITS
	POPJ	P,

; CLNSET

↑CLNSET:
	MOVE	PNT,TTOP	;CURRENT BLOCK
	HLRZ	PNT2,%TLINK(PNT)	;SECOND SEMBLK
	JUMPN	PNT2,CLNS.1		;HAVE ONE
	GETBLK				;GET ONE
	HRLM	LPSA,%TLINK(PNT)	;SAVE IT
	HRRZ	PNT2,LPSA		;
CLNS.1:	MOVE	A,GENLEF+1		;PROC SEMBLK
	HLRZ	B,%TLINK(A)		;SECOND BLOCK
	MOVSI	C,1			;STACK DISPLS FOR 0 PARS
	CAME	C,$NPRMS(B)		;BETTER HAVE NO PARAMS
	ERR	<CANNOT USE A PROC WITH PARAMS FOR CLEANUP>,1
	QPUSH	(<$ACNO(PNT2)>)		;REMEMBER
	MOVEI	A,SET			;SO GO TO SOLVER WORKS
	ORM	A,$VAL(PNT)		;
	POPJ	P,

DSCR	Execs for PRINT and CPRINT statements.


	The PRINT and CPRINT statements allow an arbitrary number
of expressions to be formatting according to expression and printed
out to the teletype or other device.  Each expression is converted
to a string by a formatting function (either the standard one or one
supplied by the user) then is printed out to the teletype, file, both,
or to a user-specified function which can do anything.
	The expected syntax is either

	PRINT(e1,e2, ... , en)

or

	CPRINT(chan,e1,e2, ... , en)

The PRINT statement prints out to the Teletype or whatever is specified
by the SETPRINT statement.  The CPRINT statement goes to the channel
specified by the first integer argument.  Both of these constructions
occur as statements, and both are parsed.
	The EXEC functions here (1) initialize the printing by pushing
the channel number for CPRINT or -1 for PRINT onto the stack, done
by STRTPT for PRINT or STCTPT for CPRINT; (2) printing out each argument
by a call on the appropriate runtime, using the syntactic type of
the expression as a key to which function is used; (3) closing off
the PRINT or CPRINT statement by removing the channel argument, which
remains on the stack during the entire operation.  Note that the
calling sequence is therefore divergent from the classical SAIL sequence.
	Currently, only scalars of each type (INTEGER, REAL, RECORD!POINTER)
are allowed.  Adding arrays is a possible extension.
⊗

;start the PRINT statement
↑STRTPT:	
	SETO	A,			;USE -1
	PUSHJ	P,CREINT		;AS A CHANNEL TO INDICATE TELETYPE
STRTP1:	SETZB	C,D
	EMIT	(<PUSH RP,NOUSAC>)
;;#VW#  (1 OF 2)  STACK NOT ADJUSTED FOR PRINT RLS 12-6-75
	AOS	ADEPTH			;RECORD CHANGE OF STACK
	POPJ	P,

;start the CPRINT statement
↑STCPRT:
	GETSEM	(1)			;CHANNEL ARGUMENT
	GENMOV	(CONV,INSIST,INTEGR)	;MAKE IT INTEGER
	JRST	STRTP1			;AND USE THIS AS THE CHANNEL

;make subroutine call to appropriate function
↑DOPRT:
	GETSEM	(1)
	TLNE	TBITS,SBSCRP		;ARRAY?
	  ERR	<PRINT not defined for arrays>,1
	SETZ	TEMP,			;ASSUME ERROR
	TRNN	TBITS,ITEM!ITMVAR	;SOME ITEM EXPRESSION
	  JRST	NOTITM
	MOVEI	TEMP,.$PITM
	JRST	DOPRT1
NOTITM:
	TRNE	TBITS,SET
	TRNN	TBITS,LSTBIT		;IS IT A LIST SOMEHOW?
	  JRST	NOTLST			;NO
	MOVEI	TEMP,.$PLST		;YES
	JRST	DOPRT1
NOTLST:
	TRNE	TBITS,INTEGR		;USE CVS(X) FOR INTEGER
	  MOVEI	TEMP,.$PINT
	TRNE	TBITS,PNTVAR
	  MOVEI	TEMP,.$PREC
	TRNE	TBITS,STRING		;JUST PRINT A STRING
	  MOVEI	TEMP,.$PSTR
	TRNE	TBITS,FLOTNG		;CVG(X) FOR REAL ARGUMENT
	  MOVEI	TEMP,.$PREL
	TRNE	TBITS,SET		;SETS GET PRINTED {IT, ...}
	  MOVEI	TEMP,.$PSET

DOPRT1:	SKIPN	TEMP			;A LEGAL PRINT ARGUMENT?
	  ERR	<Can't PRINT this syntactic type>,1

;HERE TO SIMULATE PARSING OF A PROCEDURE CALL FOR PRINT,
;PROCEDURE DESCRIPTOR IS IN TEMP

PRTCAL:	PUSH	P,GENLEF+1		;SAVE ARGUMENT
	MOVEM	TEMP,GENLEF+1		;PROCEDURE TO CALL
	PUSHJ	P,RDYCL1		;PREPARE
	MOVEW	<GENLEF+2>,<GENRIG+1>	
	POP	P,GENLEF+1
	PUSHJ	P,CALARG		;NOW SEND ARGUMENT
	JRST	ISUCAL			;AND FINALLY THE CALL


;finish up a PRINT or CPRINT sequence
↑ENDPRT:
;;%DN% JFR 8-17-76 POSSIBLY USE ADJSP
	SOS	ADEPTH
	HRLI	C,-1		;REMOVE 1 EL
	JRST	EPADJ		;FROM P STACK
;;	MOVE	A,X11
;;	PUSHJ	P,CREINT		;CREATE AN INTEGER XWD 1,1
;;	SETZB	C,D
;;	EMIT	(<SUB RP,NOUSAC>)	;NOW ADJUST USER'S STACK AFTER PRINT
;;#VX# STACK NOT ADJUSTED FOR PRINT  RLS 12-6-75
;;	SOS	ADEPTH			;AND MARK THAT STACK RESET
;;	POPJ	P,
;;%DN% ↑

	BEND	PROCED