DataMuseum.dk

Presents historical artifacts from the history of:

RC4000/8000/9000

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about RC4000/8000/9000

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download

⟦5b3ab1fe4⟧ TextFile

    Length: 185088 (0x2d300)
    Types: TextFile
    Names: »ftnpass73tx «

Derivation

└─⟦01e83a425⟧ Bits:30008166 Bånd med SW8010 og SW8500 source code
    └─⟦75ff9bef3⟧ 
        └─⟦this⟧ »ftnpass73tx « 

TextFile

;/




; alan wessel
; rc finsensvej 9

;  pass 7,  
;  aw   85  

s.  a1200, b0, c0  ; slang names, a-names for symslang
k = e0             ; e-names in file processor

; introduction.

; pass 7 of the rc4000 fortran compiler is written in symbolic
; slang which allows proper names and discriminates these on
; the first 8 characters. the code must therefore be transformed
; into slang code by the symslang program.

; the use of slang and the 12-bit address part in rc4000 restricts
; the order of code parts and definitions. to find a particular
; code, help may be found in the index of contents, and also in
; the alphabetically ordered action address table, where the
; corresponding code is referenced.

; the arrangement of the process area at translation is:
;  1.  file processor
;  2.  pass 0, resident part 
;  3.  pass 7, resident part, see contents
;  4a. pass 7, initiation
;  4b. action stack and operand stack
;  5.  *** used operands in forward stack
;  6.  *** performed actions in backward stack.
; the  *** indicates that this is a test facility.

\f


;/  contents


; contents.


; introduction                                              1
; contents                                                  2
; purpose and funtioning of pass 7                          3
; structure of pass 7 output                                4
; definition of names                                       5
;   directing bytes for pass 8                              5
;   running system entries                                  9
;   general pass or pass 0                                 10
;   types, kinds, and registers                            11
; pass 7 start of instructions                             12
;   words for test printing                                12
; error messages                                           13
; testing, and end statement                               14
; actions for initiation and termination                   16
;   pass end, unit initiation and end line                 16
;   declarations for arrays and zones                      18
;   data initiation                                        19
; operand stack                                            20
;   definition of names in operand stack                   20
;   description of contents of the operand stack           22
; operand actions                                          24
;   register operations                                    24
;   operand descriptor actions                             26
;   operand exchanging                                     27
;   load and release operands                              28
;   operand address handling                               30
; working variables                                        32
; input, output, and copying                               35
;   transmission of lists, copying of single bytes         35
;   input of operands                                      36
;   output of operands                                     38
; internal variables for pass 7                            41
; stepping stones and pass 7 pointers                      42
; main control on directing bytes from pass 6              43
;   standard actions                                       44
;   action stack actions                                   46
; interrupt handling in pass 7                             47
; actions on executable statements                         48
;   arithmetic                                             48
;   description of results                                 50
;   array and zone variables                               51
;   relations                                              52
;   masking and shift                                      54
;   storing                                                55
;   constant operand test, and conversions in pass 7       56
;   if statements                                          57
;   do statements                                          58
; actions for procedure calls                              59
;   call of procedures                                     59
;   parameter transmission                                 60
;   return from program units                              62
; test initiation                                          63
; action address table, alphabetic list of actions         64
; auxiliary action table, alphabetically ordered           67
; special action table                                     69
; main action table                                        70
; initiation of pass 7                                     74

\f


;/purpose and function

; purpose and functioning of pass 7.

; the purpose of pass 7 is to transform the byte string from pass 6
; into a string for pass 8 suited for generation of machine code.
; pass 7 disposes the use of registers and of working variables by
; keeping track of the operands.

; pass 6 delivers a sequence of bytes which is an inverse polish 
; representation of the fortran program. the structure of the byte 
; string is divided into elements of the classes: operators, operands,
; and lists, when these classes are taken in their widest sense.
; 1.  operators:  a. the operator directing byte
;                 b. sometimes followed by one or more parameter bytes
; 2.  operands :  a. the operand directing byte
;                 b. a number of bytes describing the operand
; 3.  lists    :  a. the list directing byte
;                 b. a byte giving the number of bytes in the list
;                 c. the list consisting of a number of bytes, see 3b
; a detailed description of pass 6 output is given in pass 6, chapter 3.

; pass 7 will act on the directing bytes from pass 6 by fetching the
; corresponding action entry from the action table (see at the end
; of pass 7) and put it into the action stack. then the first action
; of this entry is performed.
; each action entry consists of actlng (at present 4) actions, each
; action consists  of a standard action and a parameter for this
; packed into one byte as: parameter < b0 + standard action.

; the standard actions are:
; 
; name  parameter                    function
; doo   reference to code            some pass 7 code is activated
; out   directing byte for pass 8    the byte is output
; aux   auxiliary action entry       new actions are put into stack
; con   auxiliary action entry       current actions are overwritten
; nex   -                            next directing byte from pass 6
; err   -                            error in action table

; operators from pass 6 generally activates code and will often
; operate on the operand stack.
; operands are entered into an operand stack. the structure of
; this is described in the operand stack section.
; lists are usually just copied to pass 8.

\f


;/structure of output

; structure of pass 7 output.

; the output from pass 7 is made to suit the backwards working pass 8.
; the structure of the output may be described in syntactic form in
; which  :a:b: means that the prestanding element may occur from a to
; b times, and a * for b indicates an unlimited number of times.

; <pass 7 output> ::=  ( <operator>  ( <operand> ):0:*:  )
;                      ( <label directing byte>          )
;                      ( <list>                          ) :1:*:

; <operator>      ::=  ( <parameter byte> ):0:*:  <operator dir.byte>

; <operand>       ::=  ( <parameter byte> ):1:*:  <operand dir.byte>

; <label dir.byte>::=  <integer label number>

; <list>          ::=  (<byte>):n:n: <integer byte n> <list dir.byte>

; the directing bytes are defined in the section directing bytes.

; the structure of the operands are:
; <operand> ::= (  (<integer>     )  ( opx0  )    )
;               (  (-s:variable>  )  ( opx1  )    )
;               (                    ( opx2  )    )
;               (                    ( opx3  )    )
;               (                    ( opx0i )    )
;               (                    ( opx2i )    )
;               (                    ( opx3i )    )
;               (  <comno><c:variable> opcommon   )
;               (  <external number>   opext      )
;               (  < 2 bytes >         literal2   )
;               (  < 4 bytes >         literal4   )
;               (  < 8 bytes >         literal8   )

; the transformation of pass 7 output into generated code is described
; somewhere 

; special nomenclature.

; in the description and comments to the code the following symbols
; are used
;
; symbol   meaning
;   a:     absolute address of
;   c:     relative within common
;   d:     relative within description
;   g:     relative within global segment
;   r:     relative on present segment
;   s:     relative to stack pointer, x2-relative
;  -s:       indicating negative sign of s:
;   t:     relative to stack pointer 2, i.e. in array/zone area

\f


;/directing bytes



;  directing bytes for pass 8.
;  ---------------------------

; the definition of the directing bytes for pass 8 are placed
; as the first symslang names. in this way the a-names of the
; symslang translation includes the value of the directing byte.
; the symslang identifier listing will then hold:
;   a <directing byte value>   <directing byte name>
; when directing bytes are used as parameters to the standard
; action out only, the definition includes the b0-shift.


b0=3 ; structure of action:  action parameter < b0 + main action
     ; for output dir.byte:  dirbyte value    < b0 + out


;count ,   name            ;
c0=0   ;                   ; units, lists, entries.
c0=c0+1,   end7      =c0   ; end pass 7
c0=c0+1,   pass7     =c0<b0; pass 7 start for pass 8
c0=c0+1,   unit7     =c0<b0; begin program unit
c0=c0+1,   funit7    =c0<b0; end   program unit
c0=c0+1,   newline   =c0<b0; new line
c0=c0+1,   glolist   =c0<b0; list of global entries
c0=c0+1,   comlist   =c0<b0; list of commons
c0=c0+1,   comzones  =c0<b0; list of zones in commons
c0=c0+1,   extlist   =c0<b0; list of externals
c0=c0+1,   entryvalue=c0<b0; list of local entry points
c0=c0+1,   labvarinit=c0<b0; list of label variables
c0=c0+1,   entrypoint=c0<b0; main entry point
c0=c0+1,   dataentry =c0<b0; data entry point
c0=c0+1,   dataexist =c0   ; data in program unit
c0=c0+1,   suite     =c0<b0; reserve suite on segment

;                          ; declarations.
c0=c0+1,   entry     =c0<b0; entry declaration
c0=c0+1,   label     =c0<b0; label declaration
c0=c0+1,   locinit   =c0<b0; initiate local array/zone
c0=c0+1,   rlw1      =c0   ; register load w1
c0=c0+1,   cominit   =c0<b0; initiate common array/zone
c0=c0+1,   zoninit   =c0<b0; initiate local zone
c0=c0+1,   starray   =c0<b0; initiate parameter array
c0=c0+1,   extzone   =c0<b0; external zone

;                          ; operands.
c0=c0+1,   opx0      =c0   ; direct indexing
c0=c0+1,   opx1      =c0   ;
c0=c0+1,   opx2      =c0   ;
c0=c0+1,   opx3      =c0   ;
c0=c0+1,   opx0i     =c0   ; indirect indexing
c0=c0+1,   opx2i     =c0   ;
c0=c0+1,   opx3i     =c0   ;
c0=c0+1,   opcommon  =c0   ; common operand
c0=c0+1,   opext     =c0   ; external operand (standard variable)
c0=c0+1,   literal2  =c0   ; 2 byte operand
c0=c0+1,   literal4  =c0   ; 4 byte operand
c0=c0+1,   literal8  =c0   ; 8 byte operand
\f


;/directing bytes 2


;                          ; register w1, arithmetic, masking.
c0=c0+1,   hlw1      =c0   ; logical arithmetic
c0=c0+1,   hsw1      =c0   ;
c0=c0+1,   rsw1      =c0   ; register store w1
c0=c0+1,   loadw1    =c0   ; register load  w1, address of value
c0=c0+1,   addw1     =c0   ; integer or address arithmetic
c0=c0+1,   subw1     =c0   ;
c0=c0+1,   dosub     =c0<b0;   subtract and complement
c0=c0+1,   mulw1     =c0   ;
c0=c0+1,   divw1     =c0   ;
c0=c0+1,   alw1      =c0<b0; load address
c0=c0+1,   acw1      =c0<b0; complement
c0=c0+1,   lsw1      =c0   ; shift single
c0=c0+1,   ldw1      =c0   ; shift double
c0=c0+1,   notw1     =c0   ; not   single
c0=c0+1,   notw01    =c0   ; not   double
c0=c0+1,   law1      =c0   ; and   single
c0=c0+1,   law01     =c0   ; and   double
c0=c0+1,   low1      =c0   ; or    single
c0=c0+1,   low01     =c0   ; or    double
c0=c0+1,   dlw1      =c0   ; double register
c0=c0+1,   dsw1      =c0   ;
c0=c0+1,   faw1      =c0   ; real arithmetic
c0=c0+1,   fsw1      =c0   ;
c0=c0+1,   fmw1      =c0   ;
c0=c0+1,   fdw1      =c0   ;
c0=c0+1,   aaw1      =c0   ; long arithmetic
c0=c0+1,   ssw1      =c0   ;
c0=c0+1,   signlong  =c0   ; w0 := sign(long)
c0=c0+1,   signdoub  =c0   ; w0 := sign(double)

;                          ; registers w0, w2, w3, uv, dr.
c0=c0+1,   loadw0    =c0   ; w0
c0=c0+1,   rlw3      =c0<b0; w3
c0=c0+1,   rsw3      =c0<b0;
c0=c0+1,   addw3     =c0<b0;
c0=c0+1,   regtouv   =c0<b0; uv register
c0=c0+1,   reguv0    =c0<b0;
c0=c0+1,   uvtow01   =c0   ;
c0=c0+1,   drload    =c0   ; dr register
c0=c0+1,   drstore   =c0   ;
c0=c0+1,   draddr    =c0<b0;

;                          ; conversion.
c0=c0+1,   iconvl    =c0<b0; integer to long
c0=c0+1,   lconvi    =c0<b0; long    to integer
c0=c0+1,   ifloatr   =c0<b0; integer to real
c0=c0+1,   rtrunci   =c0<b0; real    to integer
c0=c0+1,   rconvc    =c0<b0; real    to complex
c0=c0+1,   ctruncr   =c0<b0; complex to real
\f


;/directing bytes 3




;                          ; skip, relation, check.
c0=c0+1,   shw0      =c0   ; sh w0
c0=c0+1,   shw1      =c0   ; sh w1
c0=c0+1,   slw1      =c0   ; sl w1
c0=c0+1,                   ; (not used)
c0=c0+1,   relation  =c0<b0; relation skip
c0=c0+1,   amodify   =c0   ; am instruction
c0=c0+1,   chlower   =c0<b0; check lower index
c0=c0+1,   zindex    =c0<b0; check zone index
c0=c0+1,   zrechk    =c0<b0; check zone record length
c0=c0+1,   chzono    =c0<b0; check number of zones

;                          ; jumps, points.
c0=c0+1,   xxforw    =c0<b0; bypass label forwards
c0=c0+1,   goforw    =c0   ; goto bypass label forwards
c0=c0+1,   xxback    =c0<b0; bypass label backwards (data statement, optimised)
c0=c0+1,   gosimpl   =c0<b0; goto label
c0=c0+1,   goif      =c0<b0; goto arithmetical
c0=c0+1,   goiforw   =c0<b0; goto conditional
c0=c0+1,   prepjump  =c0<b0; prepare jump
c0=c0+1,   xxbackw   =c0<b0; bypass label backwards (general form)
c0=c0+1,   gobackw   =c0<b0; goto bypass label backwards
c0=c0+1,   goexternal=c0   ; goto external procedure
c0=c0+1,   goformal  =c0   ; goto formal   procedure

;                          ; statements.
c0=c0+1,   complist  =c0<b0; computed goto list
c0=c0+1,   rsw2      =c0<b0; first do-loop := false
c0=c0+1,   domul     =c0<b0; test sign of do
c0=c0+1,   doclear   =c0<b0; w0w1 := 0
c0=c0+1,   dogofor   =c0<b0; conditional goto after-do-loop
c0=c0+1,   xxchang   =c0<b0; exchange the top two xx-labels
c0=c0+1,                   ; (not used)
c0=c0+1,                   ; (not used)
c0=c0+1,                   ; (not used)
c0=c0+1,                   ; (not used)
c0=c0+1,                   ; (not used)
c0=c0+1,                   ; (not used)
c0=c0+1,                   ; (not used)
c0=c0+1,                   ; (not used)
c0=c0+1,   parproc   =c0   ; parameter procedure
c0=c0+1,   lastused  =c0   ; set parameter formals
c0=c0+1,   point01   =c0<b0; call
c0=c0+1,   return    =c0<b0; return from program unit
\f


;/directing bytes 4



;                          ; formats.
c0=c0+1,   begfor    =c0<b0; format begin
c0=c0+1,   contfor   =c0<b0; format continue
c0=c0+1,   openfor   =c0<b0; format open
c0=c0+1,   closfor   =c0<b0; format closed


;                          ; call running system.
c0=c0+1,   gors      =c0<b0; jump to running system, 

;                          ; trouble.
c0=c0+1,   trouble   =c0   ; trouble
c0=c0+1,   troublop  =c0   ; trouble operand



; directing bytes also used in out actions


opx0a    = opx0   <b0
opx1a    = opx1   <b0
opx2a    = opx2   <b0
opx3a    = opx3   <b0
opx2ia   = opx2i  <b0
rlw1a    = rlw1   <b0
rsw1a    = rsw1   <b0
loadw1a  = loadw1 <b0
addw1a   = addw1  <b0
subw1a   = subw1  <b0
mulw1a   = mulw1  <b0
lsw1a    = lsw1   <b0
loadw0a  = loadw0 <b0
dlw1a    = dlw1   <b0
dsw1a    = dsw1   <b0
drloada  = drload <b0
shw0a    = shw0   <b0
chupper  = shw1   <b0
amodifa  = amodify<b0
goforwa  = goforw <b0
troubla  = trouble<b0
\f


;/running system entries


;  running system entries
;  ----------------------
; entry to running system is described to pass 8 as:
;   <running system number>  gors

frsno    =    150              ; base number for fortran running
;                            ; system entries (see also pass8, pass9)

coxadd   =  (:frsno+14:)     ; complex arithmetic
coxsub   =  (:frsno+15:)     ;
coxmul   =  (:frsno+16:)     ;
coxdiv   =  (:frsno+17:)     ;
dbladd   =  (:frsno+10:)     ; double arithmetic
dblsub   =  (:frsno+11:)     ;
dblmul   =  (:frsno+12:)     ;
dbldiv   =  (:frsno+13:)     ;
longmul  =  (:frsno+ 0:)     ; long arithmetic
longdiv  =  (:frsno+ 1:)     ;
iexpoi   =  (:frsno+ 2:)<b0  ; exponentiation
lexpoi   =  (:frsno+ 3:)<b0  ;
rexpoi   =           2  <b0  ;
rexpor   =           1  <b0  ;
dexpod   =  (:frsno+ 4:)<b0  ;
lfloatr  =          46  <b0  ; conversions
lfloatd  =  (:frsno+ 5:)<b0  ;
rtruncl  =          47  <b0  ;
rconvl   =          43       ; (rounding real to long)
rconvd   =  (:frsno+ 6:)<b0  ;
dtruncl  =  (:frsno+ 7:)<b0  ;
dtruncr  =  (:frsno+ 8:)<b0  ;

readinit =  (:frsno+18:)<b0  ; read
readcall =  (:frsno+20:)<b0  ;
writeinit=  (:frsno+19:)<b0  ; write
writecall=  (:frsno+21:)<b0  ;
gopoint  =          53  <b0  ; goto point
endreg   =           6  <b0  ; end register expression
endaddr  =           8  <b0  ; end address  expression
initzone =           9  <b0  ; zone initiation
zonerel  =          10  <b0  ; zone release
noroom   =          17  <b0  ; array index error
stop     =          45  <b0  ; stop fortran run
\f


;/general pass names



; gpa: general pass entries.
; --------------------------
; obs may be substituted by stepping stones

; name           function of jl.w3 name.               unchanged reg
take     =  e2 ; w2 := next input byte                   0 1
give     =  e3 ; output byte (w0)                        0 1 2
ees0     = e87+1000 ; warning.yes
message0 =  e4 ; message(w1=a:text)                      0   2
alarm    =  e5 ; alarm  (w1=a:text)                      0   2
intpass0 = e36 ; interrupt(w2=a:dump words), terminate
carret   =  e1 ; count in gpa:lineno                     0 1 2
printbyte= e16 ; print byte (w0)                         0 1 2
endpass  =  e7 ; terminate pass
writechar= e12 ; writechar(w0=char)                       0 1 2
writetext= e13 ; writetext(w1=a:text)                     0   2
writeint = e14 ; write integer(w0=integer)                0 1 2

; name           variable holding
lineno   =  e6 ; actual line number
stackover= e10 ; text: process too small
modebits = e17 ; mode of translation
modebit2 = e29 ; (more modebits)

chindex  = 1<3 ; bit when index check
spillbit = 1<6 ; bit when interrupt on integer overflow
truncbit = 1<0 ; bit when truncation instead of rounding
loadmap  = 1<3 ; bit when loadmap wanted

lastword = e9+4; a:last word for use by pass 7
\f


;/definitions

; definition of types and kinds
; ----------------------------



notype  =  0
logical =  1
integer =  2
real    =  3
long    =  4
double  =  5
complex =  6
undefin =  7 ; undefined used when trouble


; kinds for parameter transmission etc

pproc   =  0 ; procedure
parray  = 16 ; zone array and array-type
pzone   = 23 ; zone
psimple = 24 ; simple-type
plabel  = 31 ; label
procval = -3 ; a:value of procedure is stored in x2+procval
parbytes=  4 ; number of return description bytes in calls


; names on registers and register parts
; -------------------------------------
reg0     = 0   ,  reg0last = 1  ,  byte0 = 0
reg1     = 2
reg2     = 4   ,  reg2last = 5
reg3     = 6   ,  reg3last = 7


; sizes of common descriptions, as transmitted between
;   pass 6 and pass 8

comsize = 12 ; size of common description
entrsize= 12 ; size of entry description
extsize = 12 ; size of external description
zcomsize= 17 ; size of zone-common description
\f


;/pass 7 start


;  pass 7 start of instructions
;  ----------------------------
w.


start7:    length7 ; length of pass 7 in bytes
h.
           entry7  ; pass 7 entry relative to start7
           7<1 +0  ; pass number<1 + no change of direction
w.
entry7   = k - start7

          jl.      init7.        ; goto initialise via stepping stone



; words for print addresses for test output

; the following words are placed at the start of pass 7 to be used when
; calling the file processor utility program: print  when testing the
; performance of pass 7

; with the present file processor (system 1) and pass 0 (1.7.70)
; the first word of pass 7 is in byte 2658 of the process area.
; when the etest is included a nice printing of the core area 
; dumped to the area pass7dump is given by:
; head 1
; u = set bs pass7dump 0 0 0 7.0
; print u 2658.2688 2664.2666.i integer 2668.2670.i
; head 1
; message pass7 operand stack and used operands
; print u byte words.5 2672.2674.i 2676.2678.i
; head 1
; message pass7 performed actions backwards stack
; print u byte words.4 2680.2682.i

ppp1: 
      0 ; a:pointer and stepping stone area
ppp2: 
      0 ;
pwk1: 
      0 ; a:work pointers
pwk2: 
      0 ;
pop1: 
      0 ; a:operand stack area
pop2: 
      0 ;
pup1: 
      0 ; a:used operands area
pup2: 
      0 ;
pac1: 
      0 ; a:actions performed area
pac2: 
      0 ;

opprint =  200
popinit =  100
pupinit = opprint+800
pacinit =-2000

\f


;/error messages

conindex: <:constant index<0>:>  ; constant index error checked in pass 7
overflow: <:overflow<0>:>        ; overflow in constant arithmetic
notdone:  <:not implemented<0>:> ; unknown byte from pass 6
stacktxt: <:run stack full<0>:>  ; running stack will exceed 2048 bytes
;        <:operand stack<0>:>    ; operand stack not empty
;        <:more actions<0>:>     ; action stack not empty
;        <:stack pointer<0>:>    ; w1 <> opandtop
;       <:wrong standard action:>; error in action tables
;       <:process too small:>    ; too many operands in stack


; other messages are given when tests are included


runstack: al.w1    stacktxt.     ; running stack overflow.
          jl.      alarm.        ; gpa:alarm

notimplx:                           ; directing byte not implemented.
          am       notdone -overflow; 
overmess:                           ; overflow in constant arithmetic.
          am       overflow-conindex;
errconix:                           ; error in constant index.
          al.w1    conindex.        ; w1 := a:text


errmess:
;                                ; error message during pass 7.
;                                ; call: w1 := a:text
;                                ;       jl.w3 errmess.
;                                ; exit: w1 := a:top operand descriptor
;                                ;       w0,w2 unchanged
;                                ; output
;                                ;
;                                ;   line xxx  error message
          ds.w0    save30.       ; save w3 and w0
          jl.w3    message.      ; gpa:message(error text)
          al w0    trouble       ;
          jl.w3    outbyte.      ; gpa:outbyte(trouble)
          rl.w0    save30.       ; restore w0
          rl.w1    opandtop.     ; w1 := a:top operand descriptor
          jl.     (savew3.)      ; return
\f


;/testing


; pass 7 includes test facilities for running in of the code:

atest= 1 ; counting the number of inbytes to and outbytes from
;          pass 7, the result is given as the 4.th and 5.th values
;          in pass information.
;          storage requirement: 18 words
;          time requirement   :  9 milliseconds per segment(512 bytes)

btest= 1 ; testing of stacks empty at statement end
;          error messages:  opstack error  operand stack not empty
;                                          or under limit
;                           more actions   last actions not performed
;          storage requirement: 34 words

ctest= 1 ; testing that the w1-register holds the address of the
;          top operand descriptor
;          error message:  top not in w1
;          storage requirement: 29 words

dtest= 1 ; testing wrong entries to tables and stacks
;          error message:  action stack error  actions in operand stack
;          storage requirement: 17 words

etest=-1 ; comprising the thorough test output in the process area
;          should only be used for reasonably small test programs
;          1. zeroing of non-resident part of pass 7 and rest of
;             process area at initiation
;          2. zeroing of operand entries at time of release
;             this spoils the use of multiple assignment in programs
;          3. preparation of the printing of test output stored in
;             the process area:
;             a. operand descriptions at time of release
;             b. performed actions as 2 bytes: standard action, parameter
;          storage requirement: 70 words

; the xtest is included in the slang translation when the value >= 0
; while it is excluded by giving xtest a negative value.

; the tests are placed in such a way that no definition of names
; are included, thus all symslang or slang names are defined and
; an automatic generation of the compressed byte value - symslang
; name table is possible.


\f


;/testing 2

endstatx:                        ; end statement.
          al w2    0             ; set working variable pointers
          rs.w2    workrel.      ; workrel = 0
          rs.w2    worklev.      ; worklevel = 0
          rl.w2    workinit.     ; present bottom of working variables
          rs.w2    workfree.     ; workfree = workinit
c. btest
          rl.w1    opandtop. ;***
          sn.w1   (opandbot.);*** if operandstack empty
          jl.      actest.   ;***    then goto test action stack
          sh.w1   (opandbot.);***  if w1 < opandbot
          rl.w1    opandbot. ;***    then w1 := opandbot
          rs.w1    opandtop. ;*** set opandtop
          al.w3    0         ;*** return to here if not empty
          al w2    opfault   ;*** set error check
          hs w2 x1+opcheck   ;***
          se.w1   (opandbot.);*** if opstack not empty
          jl.      topdownx. ;***   then reduce opstack
          al.w1    optext.   ;***  error message(opstack not empty)
          jl.w3    errmess.  ;***
z.
actest:
c. btest
          rl.w1    acstabot. ;***  a:action stack
          al w1 x1+actlng    ;***        ;
          rl w2 x1           ;***  last actions
          se w2    0         ;***  if more proper actions
          jl.      acterror. ;***    then goto error in action stack
          sn.w1   (acstatop.);*** if action stack pointer at bottom
z.
          jl.      curract.      ;    then goto current actions
acterror:
c. btest
          al.w3    curract.      ; set return
          rs.w1    acstatop. ;***  acstatop := acstabot + action length
          al.w1    actext.   ;***
          jl.w3    errmess.  ;***  error message(more actions)
z.
          jl.      curract.      ; goto current actions
optext:
c. btest, <:operand stack<0>:> z. ;***
actext:
c. btest, <:more actions<0>:>  z. ;***

; *** test facility for operand stack
; a message is given when  w1 <> opandtop
; call   jl.w3  topinw1.   , see stepping stones
; exit   w1 := opandtop ,  w0,w2 unchanged
topinw1x:
c. ctest
          sn.w1   (opandtop.)    ; if w1 = opandtop
          jl    x3               ;  then return
          ds.w0    topin0.       ; save w30
          al.w1    topmess.      ; w1 := a:text
          jl.w3    message.      ; gpa:message
          ac.w0    start7.       ; - a:pass7 start
          wa.w0    topin3.       ; program relative of call point
          jl.w3    printbyte.    ; gpa:printbyte
          rl.w0    topin0.       ; restore w0
          rl.w1    opandtop.     ; w1 := a:opandtop
          jl.     (topin3.)      ; return
z.
topin3:   0                      ; return address
topin0:   0                      ; save w0
topmess:  <:stack pointer:>      ; error message

\f


;/ pass end and unit initiation

passendx:                        ; end of pass 7.
c. etest
          rl.w1    opandmax. ;***  set test print pointers correct
          sn w1    0         ;***
          rl.w1    opandtop. ;***
          rs.w1    pop2.     ;***
          rl.w1    opused.   ;***
          al w1 x1+oplength  ;***
          rs.w1    pup2.     ;***
          rl.w1    watch.    ;***
          wa.w1    opandlim. ;***
          rs.w1    pac1.     ;***
z.
c. atest
          rl.w1    passin.   ;***
          rs.w1    e9.       ;***  pass information 1 = no.of inbytes 
          rl.w1    passout.  ;***
          rs.w1    e9.+2     ;***  pass information 2 = no.of outbytes
z.
          jl.      endpass.      ; gpa:end pass
\f


;/pass end and unit initiation 2


areasx:                          ; output pass information.
          jl.w3    inbyte.       ; gpa:inbyte(first  byte of buf.inf)
          hs.w2    savebyte.     ;
          jl.w3    inbyte.       ; gpa:inbyte(second byte of buf.inf)
          hs.w2    savelast.     ; savebyte := buffer length
          jl.w3    inbyte.       ; w2 := maximal parameter number
          ls w2    2             ; 4 bytes for each parameter(formal)
          al w2 x2+parbytes      ; + bytes for parameter information
          rs.w2    savew2.       ; savew2 := size of parameter area
          al w0 x2               ; for use by initiation of in-output
          jl.w3    outbyte.      ; outbyte(parameter area - 2)
          rl.w2    workmax.      ; w2 := -s:free stack variable
          ws.w2    savebyte.     ;       -size of array and zone area
          ws.w2    savew2.       ;       -size of parameter area

          rl.w0    modebit2.     ; w0 := modebit2;
          so w0    loadmap       ; if loadmap not wanted then
          jl.      outlit2.      ;   output(-stacksize) as two byte literal;

          al.w1    localtxt.     ;
          jl.w3    writetext.    ; writetext (<:local variables:>);

          ac w0 x2               ; w0 := stacksize;
          sz w0    1             ; if stacksize odd then
          ba.w0    1             ;   make stacksize even;
          jl.w3    writeint.     ; write integer (stacksize);
            32<12+8              ;

          jl.      outlit2.      ; output(-stacksize) as two byte literal;

localtxt: <:<10>local variables: <0>:>

spacetxt: <:   :>
h.                               ;
listelem: 0, r. zcomsize         ;
w.                               ;

txtcommon: 8<12 + comsize  , <:<10>common list:<0>:>
txtextern:        extsize  , <:<10>external list:<0>:>
txtzcomm:  8<12 + zcomsize , <:<10>zone common list:<0>:>

outextx:  am   txtextern-txtcommon;
outcomx:  am   txtcommon-txtzcomm;
outzcomx: al.w2    txtzcomm.+2   ; w2 := start of heading text;
          rs.w2    savew2.       ; save heading address;

          bz w0 x2-2             ; get index for size-word;
          hs.w0    sizendx.      ;

          bz w1 x2-1             ; param := size of descriptor;

          rs.w1    savew1.       ; common-descr size := param;
          rs.w1    savew0.       ; printed := descr size;

nxtentry:                        ; next entry:
          rl.w1    savebyte.     ;
          ws.w1    savew0.       ;
          sh w1   -1             ; if no.list size < printed then
          jl.      restlist.     ;   goto copy rest of list;

          al w1    0             ; count := 0;
copylist:                        ;
          jl.w3    inbyte.       ; w2 := gpa:inbyte;
          hs.w2 x1+listelem.     ; listelem(count) := byte;
          al w0 x2               ; w0 := inbyte;
          jl.w3    outbyte.      ; gpa:outbyte(inbyte);
          al w1 x1+1             ; increase(count);
          se.w1   (savew1.)      ; if count <> descr size then
          jl.      copylist.     ;   goto copylist;

          wa.w1    savew0.       ; printed := printed
          rs.w1    savew0.       ;          + descr size;

          rl.w0    modebit2.     ; if loadmap not wanted then
          so w0    loadmap       ;
          jl.      nxtentry.     ;   goto next entry;

          al w1    0             ;
          rx.w1    savew2.       ; heading := false;
          se w1    0             ; if old heading <> 0 then
          jl.w3    writetext.    ;   writetext (heading);

          al w0    10            ;
          jl.w3    writechar.    ; writechar (newline);

          al w2   ; size index   ; w2 := index;
sizendx = k-1
          sn w2    0             ; if index <> 0 then
          jl.      entrname.     ;
          rl.w0 x2+listelem.     ;
          jl.w3    writeint.     ;   write integer (listelem.index);
            32<12+11             ;

entrname: al.w1    spacetxt.     ;
          jl.w3    writetext.    ; writetext(name of common);

          jl.      nxtentry.     ; goto next entry;

restlist:                        ; copy rest of list:
          wa.w1    savew1.       ; w1 := number of rest bytes;
          jl.w3    inoutn.       ;   copy n bytes;
          jl.      saveoutx.     ; goto outbyte(no.list size);


getentrx:                        ; copy whole entry-list to stack:
          rl.w2    opandlim.     ;
          ws.w2    savebyte.     ; reserve room for entry-list;
          rs.w2    opandlim.     ;
          al.w1    stackover.    ;
          sh.w2   (opandbot.)    ; if no room for list then
          jl.w3    alarm.        ;   alarm (<:stack overflow:>);

          al w1    0             ; count := 0;
readlist:                        ;
          jl.w3    inbyte.       ; w2 := gpa:inbyte;
          am.     (opandlim.)    ;
          hs w2 x1+oplength      ; entry-list(count) := byte;
          al w0 x2               ; w0 := inbyte;
          jl.w3    outbyte.      ; gpa:outbyte(inbyte);
          al w1 x1+1             ; increase(count);
          se.w1   (savebyte.)    ; if count <> savebyte then
          jl.      readlist.     ;   goto readlist;

          jl.      saveoutx.     ; goto outbyte (no.list size);

newltxt:  <:<10>   <0>:>
entrytxt: <:<10><10><10>entry list:<0>:>

outentrx:                        ; output part of entry point list:
          jl.w3    inbyte.       ; w2 := number of local entries := inbyte;

          rl.w0    modebit2.     ;
          so w0    loadmap       ; if loadmap not wanted then
          jl.      curract.      ;   goto current actions;

          al.w1    entrytxt.     ;
          jl.w3    writetext.    ; writetext (<:entry list:>);

;         al w2    1             ; **** preliminary ****
;         jl.w3    inbyte.       ; w2 := number of local entries := inbyte;

entrnxt:                         ; next entry:
          al.w1    newltxt.      ;
          jl.w3    writetext.    ; writetext (newline + spaces);
          rl.w1    opandlim.     ;
          al w0 x1+entrsize      ; release part of stack;
          rs.w0    opandlim.     ;
          al w1 x1+oplength      ;
          jl.w3    writetext.    ; writetext (name of entry);

          al w2 x2-1             ; decrease (number of entries);
          se w2    0             ; if number of entries <> 0 then
          jl.      entrnxt.      ;   goto next entry;

          jl.      curract.      ; goto current actions;

uninitx:                         ; initialise for program unit.
          al w0    0             ;
          hs.w0    datatrue.     ; datatrue := 0
c. etest
          rl.w2    opandbot. ;*** initiate print words for testing
          rs.w2    pop1.
          al w2 x2+opprint
          rs.w2    pup1.
          rl.w2    opandbot.
          al w2 x2+popinit
          rs.w2    pop2.
          al w2 x2+pupinit
          rs.w2    pup2.
          rl.w2    opandlim.
          rs.w2    pac2.
          al w2 x2+pacinit
          rs.w2    pac1.
          al.w2    init7.
          rs.w2    ppp1.
          al.w2    opused.
          rs.w2    ppp2.
          al.w2    workfree.
          rs.w2    pwk1.
          al.w2    workrel.
          rs.w2    pwk2.     ;*** end initiate print words
z.
          jl.      curract.      ; goto current actions

endlinex:                        ; count line number.
          al.w3    curract.      ; set return do current actions
          jl.      carret.       ; goto gpa:car return
\f


;/ declarations



declbegx:                        ; begin declare array or zone.
          jl.w3    inbyte.       ; gpa:inbyte
          rs.w2    savebyte.     ; savebyte := inbyte
          al w1    2             ;
          jl.w3    inoutn.       ; copy 2 bytes
          al w0    literal2      ;
          jl.      outcurr.      ; outbyte(literal2); goto current act

loczonex:                        ; local zone information.
          al w1    5             ;
          al.w3    curract.      ; set return
          jl.      inoutn.       ; copy 5 bytes

paramarx:                        ; parameter array declaration.
c. ctest, jl.w3    topinw1.   z. ; ***  *** test w1 = opandtop
          rl.w2    type.         ;
          rs.w2    savetype.     ; savetype := type of array
          jl.w3    inbyte.       ; w2 := -s:a:array0
          hs w2 x1+opcopy        ; opcopy := w2
          jl.      arrayopx.     ; get rest of array descriptor
                                 ;  6 bytes is read into operand stack

initarrx:                        ; initiate parameter array.
;                                ; entry: savetype := type of array
          rl.w2    savetype.     ; w2 := type of array
          al w0    2.10011       ; w0 := real type mask
          se w2    real          ; if type <> real
          al w0    2.10111       ;   then  w0 := not real type mask
          jl.w3    outbyte.      ; gpa:outbyte(type mask)
          al w0    2.10000       ; w0 := compare base mask
          wa.w0    savetype.     ; w0 := compare type mask (:=w0+type)
          jl.w3    outbyte.      ; gpa:outbyte(compare mask)
          bl.w2 x2+sort.         ; w2 := sort(type)
          bl.w0 x2+length.       ; w0 := length(sort)
          jl.      outcurr.      ; outbyte(length); goto current action

fixarrx:                         ; calculate test for fix array.
c. ctest, jl.w3    topinw1.   z. ; ***  *** test w1 = opandtop
          rl w2 x1+opupper       ;
          ws w2 x1+oplower       ;
          am.     (type.)        ;
          bl.w3    sort.         ; w3 := length(sort);
          ac w3 x3               ;
          ls w2 x3               ; test := (upper-lower) shift (-length);
          jl.      outlit2.      ; output test as 2 byte literal

pzarrayx:                        ; zone/zone array as parameter.
          bl.w0    savelast.     ; w0 := savebyte (no.zones descr)
          al.w3    nextact.      ; parameter kind decides return :=
          se w0    0             ;   if    zone  then  next actions
          al.w3    curract.      ;   else (zone array) current actions
          sl w0    0             ; if not adjustable zone array
          jl.      inbyte.       ;   then dummy gpa:inbyte ; return
          al w2    zparact       ;
          jl.      newspact.     ; goto enter adj.zone array actions

\f


;/ declarations



ixformlx:                        ; check size of formal array:
                                 ;   resulting sequence:
                                 ;     ls w1 length  (or rl w3 length)
                                 ;     ; w0 = size of actual array
                                 ;     ; w1 = size of formal array
                                 ;     sh w1 (0)
                                 ;     sh w1 0
                                 ;     jl.    indexalarm.

          al w0    0             ;
          jl.w3    outbyte.      ; outbyte(0);
          al w0    opx0i         ;
          jl.w3    outbyte.      ; outbyte(opx0i);
          al w0    chlower>b0    ;
          jl.w3    outbyte.      ; outbyte(chlower);
          al w2    0             ;
          jl.w3    outconst.     ; outconst(0);
          jl.      curract.      ; goto current action;
\f


;/ data initiation


dataexix:                        ; if data statement in program unit
datatrue= k+1                    ; then outbyte(dataexist).
          al w0    0             ; w0 := datatrue (initial value = 0)
          sn w0    dataexist     ; if datatrue = dataexist
          jl.w3    outbyte.      ;  then gpa:outbyte(dataexist)
          jl.      curract.      ; goto current actions

datax:                           ; set data exists.
          al w0    dataexist     ;
          hs.w0    datatrue.     ; datatrue := dataexist
          jl.      curract.      ; goto current actions


datasetx:                        ; make pointers to data array.
c. ctest, jl.w3    topinw1.   z. ; ***  *** test w1 = opandtop
          rl.w2    type.         ;
          bl.w2 x2+sort.         ; w2 := sort(type of data array)
          rs.w2    savesort.     ; savesort := sort
          jl.w3    datalast.     ; save data last in work
          rs.w2    workrel.      ; workrel := -s:work(data last)
          rl.w3    worklev.      ; worklev = worklev + 1
          al w3 x3+1                  ;
          rs.w3    worklev.      ;
          al.w3    curract.      ; set return to current actions
          jl.      towork2x.     ; save data pointer in work

databytx:                        ; byte length of data array to set.
          rl w2 x1+opcon         ; w2 := constant before data star
          am.     (savesort.)    ;
          ls w2    0             ; w2 := constant shift sort(datarray)
          jl.      outlit2.      ; goto output bytelength as literal2

datavalx:                        ; update data pointer, store value.
          am.     (savesort.)    ;
          bl.w2    length.       ; w2 := length(savesort)
          jl.w3    outconst.     ; outbyte(length); outbyte(opx0)
          am.     (savesort.)    ;
          bl.w0    regstore.     ; w0 := regstore(savesort)
          jl.      outcurr.      ; outbyte(regstore); goto current act

datasuix:                        ; send sort of data.
          rl.w0    savesort.     ; w0 := sort of data to initiate
          jl.      outcurr.      ; outbyte(sort); goto current actions
\f


;/operand stack


; operand stack, definition of elements and variables
; ---------------------------------------------------
; obs if the organisation of the operand stack layout is changed
;     the action opexch may have to be revised

opcopy   = 0 , opcomno  = 0 , oplabel  = 0
opplace  = 1 , opcomrel = 1 
opzoneno = 2
opbytix  = 3
opupper  = 5
oplower  = 7 , oprange  = 7 , opcon    = 7
opcheck  = 8 ,
opdescr  = opcheck+1 ; opcheck,opdescr must be in common word
oplength = 10 ; length of operand stack entry

;  operand kinds
;  -------------    ; obs  change of the numeration of kinds must
;                          be accompanied by changes in tables:
;                          toparts, addrset, workbyte

c0 = 0   ; kind:           operand:
c0 = c0+1, labelk   = c0 ; label
c0 = c0+1, labvark  = c0 ; label variable
c0 = c0+1, simlock  = c0 ; simple local variable
c0 = c0+1, simcomk  = c0 ; simple common variable
c0 = c0+1, simformk = c0 ; simple formal variable
c0 = c0+1, arrayk   = c0 ; array
c0 = c0+1, rangek   = c0 ; range
c0 = c0+1, subconk  = c0 ; subscripted with constant subscript
c0 = c0+1, subscrk  = c0 ; subscripted with variable subscript
;c0 = c0+1, suboptk  = c0 ; subscripted optimised --- not implemented
c0 = c0+1, zonek    = c0 ; zone
c0 = c0+1, arreqzk  = c0 ; array  equivalenced to zone
c0 = c0+1, externk  = c0 ; external
c0 = c0+1, extformk = c0 ; formal external
c0 = c0+1, constk   = c0 ; constant or literal

;  operand description checkbits.
w.;------------------------------

inw01    =  1<0    ; in w01 register
inuv     =  1<1    ; in  uv register
indr     =  1<2    ; in  dr register
addr     =  1<3    ; address
inwork   =  1<4    ; in working storage
opfault  =  1<10   ; error operand
\f


;/operand stack 2

;  operand description masks and operands.
w.;---------------------------------------

sortmask :  2.111  ; sort mask
nopsort  :  8.7770 ; 1-complement of sort mask
getkind  = -3      ; remove sort by shift
logsort  =  0
intsort  =  1
realsort =  2
longsort =  2
drsort   =  3

subconm  =  subconk>getkind ;
subscrm  =  subscrk>getkind ;
simlocm  =  simlock>getkind ;
constint =  constk >getkind + intsort ; constant integer check bits

\f


;/operand stack 3


; structure of the operand stack.

; the special nomenclature and the names used in the description
; of the operand stack is described above.

; the operand stack holds entries of oplength bytes.
; the opdescr  byte holds:  operand kind < -getkind + sort of operand
; the opcheck  byte holds:  checkbits telling the whereabouts of operands
; the rest of each operand stack entry is used to describe the operand
; in different ways for each kind, only the bytes used are described:

; kind             byte                 content

; label            oplabel              label number
; label variable   opplace              -s:label variable
; simple local     opplace              -s:variable
;                                       -s:work(expression)
; simple common    opcomno              common number
;                  opcomrel             c:common variable
; simple formal    opplace              +s:a:actual variable
; array            opcopy               -s:a:array element 0
;                  opplace              -s:a:array element 0
;                                       -s:work(dope vector)
;                  opupper   (word)     upper limit constant
;                                       -s:upper limit adjustable
;                  oplower   (word)     lower limit constant
;                                       -s:lower limit adjustable
; range            opplace              -s:work(range in dope vector)
;                  oprange   (word)     range constant
;                                       -s:range variable
; subscr constant  as array except:
;                  opplace              -s:a:array element 0
;                                       -s:work(a:element)
;                  opbytix   (word)     constant byte index
; subscripted      as array except:
;                  opplace              -s:a:array element 0
;                                       -s:work(a:element)
; zone             opcopy               -s:work(zone array index i)
;                  opplace              -s:a:zone 0 descriptor
;                                       -s:work(a:zone i descriptor)
;                  opzoneno             number of zones, 0 simple zone
;                                       -s:adjustable number of zones
; array eq zone    opcopy               zone descriptor displacement
;                  opplace              -s:a:zone 0 descriptor
;                                       -s:work(dope vector)
;                  opbytix   (word)     array to record base displacement
;                  opupper              as array
;                  oplower              as array
; external         opplace              external number
; formal external  opplace              +s:formal

\f


;/operand stack 4


; constants:
;                  opplace              -s:work(constant)
; literal1         opcon-1              0
;                  opcon                byte1 of logical constant
; literal2         opcon-1              byte1
;                  opcon                byte2 of integer constant
; literal4         opcon-3              byte1
;                  opcon                byte4 of real/long constant
; literal8         opcon-7              byte1
;                  opcon                byte8 of double/complex constant

; the array kind includes both local and common arrays.
; the zone kind comprises all zone variants: zone z, zone array zz,
; zone array element zz(i), zone record z(r), and zone array record
; zz(i,r)

; whenever an operand has entered calculations the resulting expression
; is described as a simple local entity.

\f


;/operand actions

occuvx:                          ; set register uv occupied.
;                                ; call and exit as occ01x
          rs.w1    useuv.        ; useuv := a:operand descriptor
          al w0    inuv          ; w0    := in uv mask bit
          jl.      setcheck.     ; goto set checkbits

occdrx:                          ; set register dr occupied.
;                                ; call and exit as occ01x
          rs.w1    usedr.        ; usedr := a:operand descriptor
          al w0    indr          ; w0    := in dr mask bit
          jl.      setcheck.     ; goto set checkbits

occ01x:                          ; set register w01 occupied.
;                                ; call: w1 := a:operand descriptor
;                                ;       jl.w3 reg01set.
;                                ; exit: w1,w2 unchanged
;                                ;
          rs.w1    use01.        ; use01 := a:operand descriptor
          al w0    inw01         ; w0 := in w01 mask bit
          jl.      setcheck.     ; goto set checkbits

setaddrx: al w0    addr          ; set address operand.

setcheck:                        ; set checkbit in operand check.
;                                ; entry: w0 := bit to set
;                                ;        w1 := a:operand descriptor
          rs.w2    savew2.       ; save register 2
          bz w2 x1+opcheck       ; get checkbits
          so w2   (reg0)         ; if bit not set
          ba w2    reg0last      ;   then add bit
          hs w2 x1+opcheck       ; save checkbits
          rl.w2    savew2.       ; restore register 2
          jl    x3               ; return

addrof:                          ; cancel address checkbit.
;                                ; call: w1 := a:operand descriptor
;                                ;       jl.w3 addrof.
          al w2    zerorel       ; w2 := dummy zero to use regoff
          al w0    addr          ; w0 := checkbit describing address
          jl.      regoff.       ; goto cancel bit (reg not used)

regdrofx:                        ; set dr register not used.
;                                ; call: w1 := a:operand descriptor
;                                ;       jl.w3 regdroff.
;                                ; exit: w1 unchanged
          al w2    usedrrel      ; w2 := register relative to use01
          al w0    indr          ; w0 := bit describing dr register
          jl.      regoff.       ; goto set register not used

reguvofx:                        ; set uv register not used.
;                                ; call: w1 := a:operand descriptor
;                                ;       jl.w3 reguvoff.
;                                ; exit: w1 unchanged
          al w2    useuvrel      ; w2 := register relative to use01
          al w0    inuv          ; w0 := bit describing uv register
          jl.      regoff.       ; goto set register not used

reg01ofx:                        ; set register w01 not used.
;                                ; call: w1 := a:operand descriptor
;                                ;       jl.w3 reg01off.
;                                ; exit: w1 unchanged
;                                ;
          al w2    0             ; w2 := use01 - use01
          al w0    inw01         ; remove reg01
\f


;/operand actions 2



regoff:                          ; set register not used.
;                                ; entry: w1 := a:operand descriptor
;                                ;        w2 := usereg - use01
;                                ;        w0 := bit to be removed
          ls w0    12            ; shift to first byte of register 0
          lx.w0    allones.      ; w0 := ones except bit to be removed
          la w0 x1+opdescr       ; w0 := operand descriptor without bit
          rs w0 x1+opdescr       ; set operand descriptor
          al w0    0             ;
          rs.w0 x2+use01.        ; usereg := 0
          jl    x3               ; return

rescuuvx:                        ; rescue uv register if used.
;                                ; call: jl.w3 rescuuvx.
;                                ; exit: w1 := a:operand in uv
          rl.w1    useuv.        ; w1 := a:operand using uv
          sn w1    0             ; if uv not used
          jl    x3               ;   then return
uvover01: rs.w3    over3.        ; save w3
          jl.w3    rescu01x.     ; rescue register 01 if used
          al w0    uvtow01       ;
          jl.w3    outbyte.      ; gpa:outbyte(uv to w01)
          rl.w1    useuv.        ; w1 := a:operand in uv register
          jl.w3    reguvofx.     ; set uv register not used
          rl.w3    over3.        ; set return
          jl.      occ01x.       ; operand is now in register 01

rescudrx:                        ; rescue dr register if used.
;                                ; call: jl.w3 rescudrx.
;                                ; exit: w1 := a:operand in dr register
          rl.w2    usedr.        ; w2 := a:operand in dr register
          sn w2    0             ; if dr register not used
          jl    x3               ;   then return
draway:   rl.w1    usedr.        ; w1 := a:operand using dr
          rs.w3    over3.        ; save return
          jl.w3    rescu01x.     ; rescue register 01 if used
          rl.w1    usedr.        ; w1 := a:operand using dr register
          jl.w3    towork8x.     ; move dr register to work area
          jl.w3    regdrofx.     ; set dr register not used
          jl.     (over3.)       ; return
over3:             0             ; for saving of return address

rescu01x:                        ; rescue 01 register if used.
;                                ; call: jl.w3 rescu01x.
;                                ; exit: w1 := a:operand in 01
          rl.w2    use01.        ; w2 := a:operand using 01 
          sn w2    0             ; if register 01 not used
          jl    x3               ;   then return
ww01away: rl.w1    use01.        ; w1 : a:operand using 01
          rs.w3    resc3.        ; save return from rescue 01
          al.w3    regsaved.     ; set return to register saved
          bz w2 x1+opcheck       ; 
          sz w2    addr          ; if register holds address
          jl.      towork2x.     ;   then save in 2 bytes
          rl.w2    sortmask.     ;
          la w2 x1+opdescr       ; w2 := sort(operand in w01)
          jl.w3    toworkp.      ; move operand in w01 to work area
regsaved: jl.w3    reg01ofx.     ; set 01 register not used
          jl.     (resc3.)       ; return
resc3:             0             ; for saving return address
\f


;/operand actions 3

resinuvx:                        ; result in uv.
          jl.w3    addrof.       ; remove address checkbit
          jl.w3    reg01ofx.     ; remove in register 01
          jl.w3    regdrofx.     ; remove in dr register
          jl.w3    occuvx.       ; set in uv register
          jl.      curract.      ; goto current actions

typ8x:    am       double-real   ; set double/complex type.
typ4x:    am       real-integer  ; set real  /long    type.
typintx:  al w2    integer       ; set integer        type.
          rs.w2    type.         ; type := w2
          jl.      curract.      ; goto current actions
 
;                                ; set operand sort in descriptor.
;                                ; call: w1 := a:operand descriptor
;                                ;       jl.w3 setqqq.
set8x:    am       double-real   ; w2 := double or complex type
set4x:    am       real-integer  ; w2 := long   or real    type
setintx:  al w2    integer       ; w2 := integer type
          rs.w2    type.         ; type := chosen type
          al.w3    curract.      ; set return

toptype:                         ; insert operand sort in descriptor.
;                                ; call: w1 := a:operand descriptor
          rl.w2    type.         ;       jl.w3 toptype.
topsort:                         ; call: w1 := a:operand ; w2 := type
;                                ;       jl.w3 topsort.
;                                ; exit: w1 unchanged    ; w2 := type
;                                ;
          rl w0 x1+opdescr       ; get operand descriptor
          la.w0    nopsort.      ; w0 := operand descriptor & nopsort
topdescr:                        ;
          ba.w0 x2+sort.         ;       + operand sort
          hs w0 x1+opdescr       ; set operand descriptor with sort
          jl    x3               ; return

topoldx:                         ; old operand description to top.
;                                ; used with multiple assignment
;                                ; only part of the description moved
;                                ; entry: w1 := a:operand to be set
          jl.w3    topfreex.       ;  release operand top
          jl.w3    topupx.         ;  but point at same entry
          rl w0 x1+opdescr+oplength;
          rs w0 x1+opdescr         ;  operand descriptor := old ditto
          rl w0 x1+opplace+oplength;
          rs w0 x1+opplace         ;  operand place word := old ditto
          al.w3    curract.        ;  set return to current actions
          bz w0 x1+opcheck       ; w0 := checkbits
          so w0    indr          ; if operand in 01 register
          jl.      occ01x.       ;   then occupy 01 register
          jl.      occdrx.       ;   else occupy dr register


topkind:                         ; get kind of top operand.
          rl.w1    opandtop.     ; w1 := a:top operand descriptor
opkind:   bz w2 x1+opdescr       ;
          ls w2    getkind       ; w2 := kind(top operand)
          jl    x3               ; return

\f


;/operand actions 4



topnextx:                        ; exchange top and next operand.
          rl.w1    opandtop.     ; w1 := a: top operand
          al w2 x1-oplength      ; w2 := a:next operand
exchcurr:
          al.w3    curract.      ; set return

opexchx:                         ; exchange 2 operand stack elements.
;                                ; call: w1 := a:element a (10 bytes)
;                                ;       w2 := a:element b (10 bytes)
;                                ;       jl.w3 opexchx.
;                                ; exit: w0,w1,w2 unchanged
          ds.w0    save30.       ; save w0 and return
          rl.w0    use01.        ; w0 := a:element in w01
          sn w0 x1               ; if element a  in w01
          rs.w2    use01.        ;   then  use01 := w2
          sn w0 x2               ; if element b  in w01
          rs.w1    use01.        ;   then  use01 := w1
          rl.w0    useuv.        ; w0 := a:element in uv
          sn w0 x1               ; if element a in uv
          rs.w2    useuv.        ;   then  useuv := w2
          sn w0 x2               ; if element b in uv
          rs.w1    useuv.        ;   then  useuv := w1
          rl.w0    usedr.        ; w0 := element in dr register
          sn w0 x1               ; if element a in dr
          rs.w2    usedr.        ;   then  usedr := w2
          sn w0 x2               ; if element b in dr
          rs.w1    usedr.        ;   then  usedr := w1
          dl w0 x2+2             ; exchange a(0:3) and b(0:3)
          rx w3 x1               ; ...
          rx w0 x1+2             ; ...
          ds w0 x2+2             ; ...
          dl w0 x2+6             ; exchange a(4:7) and b(4:7)
          rx w3 x1+4             ; ...
          rx w0 x1+6             ; ...
          ds w0 x2+6             ; ...
          rl w0 x2+8             ; exchange a(8:9) and b(8:9)
          rx w0 x1+8             ; ...
          rs w0 x2+8             ; ...
          dl.w0    save30.       ; restore w30
          jl    x3               ; return

;                                ; top operand to register.
toplogx:  al w2    logical       ; logical
          jl.      topset.       ;
top01x:   al w2    real          ; real or long
          jl.      topset.       ;
top1x:    al w2    integer       ; integer or address
topset:   rl.w1    opandtop.     ; w1 := a:top operand descriptor
          jl.w3    topsort.      ; set sort in operand descriptor
          jl.      topget.       ; w2 := type ; goto get top
topregx:  rl.w1    opandtop.     ; w1 := a:top operand descriptor
          rl.w2    type.         ; w2 := type
\f


;/ operand actions 5


topget:                          ; get top operand.
;                                ; entry: w1 := a:operand descriptor
;                                ;        w2 := type
          bz.w2 x2+sort.         ; w2 := sort of top operand
          rs.w2    savesort.     ; save sort
          sn w2    drsort        ; if sort = drsort
          jl.      gettodr.      ;   then goto get to dr register

          rl.w0    use01.        ; top operand to register 01.
          sn w0    0             ; if register 01 not used
          jl.      free01.       ;   then goto register 01 free
          se w0 x1               ; if top operand not in reg 01
          jl.      getaway.      ;   then goto get away to work
          bz w0 x1+opcheck       ; w0 := top operand checkbits
          so w0    addr          ; if top operand already in register
          jl.      curract.      ;   then goto current actions
          bl.w0 x2+regload.      ; w0 := regload(sort)
          jl.w3    outbyte.      ; outbyte(register load)
          jl.w3    addrof.       ; cancel address checkbit
          al w0    0             ;
          al.w3    addrinw1.     ; set return from outbyte
          jl.      outbyte.      ; outbyte(0); goto address in reg 1
getaway:  jl.w3    ww01away.     ; move operand in w01 to work area
          rl.w1    opandtop.     ; w1 := a:top operand descriptor
free01:   bz w2 x1+opcheck       ; w2 := checkbits for top operand
          so w2    inuv          ; if not in uv register
          jl.      load01.       ;   then goto load 01 register
          al.w3    curract.      ; set return to current actions
          jl.      uvover01.     ; move uv register to w01

gettodr:  jl.w3    rescu01x.     ; save w01 if used
          rl.w1    opandtop.     ; w1 := a: top operand descriptor
          rl.w0    usedr.        ; top operand to dr register.
          sn w0    0             ; if dr register not used
          jl.      loaddr.       ;   then goto load dr register
          sn w0 x1               ; if dr register used for top operand
          jl.      curract.      ;   then goto current actions
          jl.w3    draway.       ; move dr register to work area
          rl.w1    opandtop.     ; w1 := a:top operand descriptor
loaddr:   bz w2 x1+opcheck       ; w2 := checkbits for top operand
          am       occdrx-occ01x ; w3 := a:occupy dr register action
load01:   al.w3    occ01x.       ; w3 := a:occupy 01 register action
          rs.w3    savew3.       ; savew3 := a:occupy action
          am.     (savesort.)    ;
          bz.w0    regload.      ;
          jl.w3    outbyte.      ; outbyte(register load(sort of top))
          al.w3    outopx.       ; set return
          so w2    addr+inwork   ; if not operand address in work
          jl.     (savew3.)      ;   then occupy register; out operand
          jl.w3    addrof.       ;   else cancel address checkbit
          jl.w3   (savew3.)      ;        occupy register
          rl.w3    addrwork.     ;        w3 := indirect addressing work
          jl.      outopy.       ;        goto output operand
;                                ;  continue current actions

h.                               ; register load byte table.
regload:  hlw1                   ; logical
          loadw1                 ; integer or address
          dlw1                   ; long or real
          drload                 ; double or complex
w.
\f


;/operand actions 6


topfreex:                        ; release top operand.
          rl.w1    opandtop.     ; w1 := old opandtop
          bz w2 x1+opcheck       ; w2 := operand opcheck
          sn w2    0             ; if no checkbits
          jl.      topdownx.     ;   then goto reduce operand stack
          ds.w3    savew3.       ; save return and checkbits
          sz w2    inwork        ; if operand in work
          jl.w3    downwork.     ;   then release work
          dl.w3    savew3.       ; restore return and checkbits
          al w0    0             ; w0 := 0 (register not used)
          sz w2    inw01         ; if operand in register 01
          rs.w0    use01.        ;   then reg01 not used
          sz w2    inuv          ; if operand in uv
          rs.w0    useuv.        ;   then uv not used
          sz w2    indr          ; if operand in dr
          rs.w0    usedr.        ;   then dr not used

topdownx:                        ; reduce operand stack.
                                 ; call:  w1 := a:operand top descr
                                 ;        jl.w3 topdownx.
                                 ; exit   w1 := a:new operand top d
                                 ;        w0,w2 unchanged
c. etest, ds.w0    topd30.   ; ***  test
c. ctest, jl.w3    topinw1.   z. ; ***  test w1 = a:top operand descriptor
          rs.w2    topdw2.   ;***
          rl.w2    opused.   ;***
          al w2 x2+oplength  ;***  operand to used operand area
          rs.w2    opused.   ;***
          dl w0 x1+2         ;***  move operand
          ds w0 x2+2         ;***
          dl w0 x1+6         ;***
          ds w0 x2+6         ;***
          rl w0 x1+8         ;***
          rs w0 x2+8         ;***
          rl.w2    topdw2.   ;***
          ld w0    65        ;*** set
          ds w0 x1+2         ;*** operand
          ds w0 x1+6         ;*** descriptor
          rs w0 x1+8         ;*** := 0
          dl.w0    topd30.   ;***
z.

toplowx:                         ;entry for next
          rl.w1    opandtop.     ;
          sl.w1    (opandbot.)     ; allow only 1 record underflow
          al w1 x1-oplength      ; w1 := a:new operand top descriptor
          rs.w1    opandtop.     ; opandtop := w1
          jl    x3               ; return
topdw2:  0    ;***
topdw3:  0    ;***
topd30:  0    ;***
\f


;/ operand actions 7

getaddrx: rl.w1    opandtop.     ; get address of top operand.
;                                ; call: jl.   getaddrx.
;                                ;       w1 := a:operand descriptor
          rl.w2    use01.        ; w2 := a:operand in 01 register
          rs.w1    savew1.       ; save a:operand descriptor
          se.w2   (savew1.)      ; if other operand in 01 register
          jl.w3    rescu01x.     ;   then rescue 01 register
          rl.w1    savew1.       ; restore a:operand descriptor
          jl.w3    opkind.       ; w2 := kind(operand)
          al w3    2.1111        ; mask index
          la w2    reg3          ;
          bl.w2 x2+addrset.      ; w2 := address set action
          al w2 x2+aux           ; make auxiliary action
          jl.      singlact.     ; goto perform single action

addrset = k-3      ; table of address set actions.
h.                 ; index is kind(operand)  
          addrsim  ; simple local
          addrget  ; simple common
          addrget  ; simple formal
          addrget  ; array
          0        ; range
          addrget  ; subscripted constant
          addrsim  ; subscripted variable
          addrop   ; zone
          addrget  ; array equivalenced zone
          addrget  ; external
          0        ; formal external
          addrcon  ; constant
w.


h.                 ; sort of operand, table.
                   ; index is type
sort:   intsort    ;   0   no type
        logsort    ;   1   logical
        intsort    ;   2   integer
        realsort   ;   3   real
        longsort   ;   4   long
        drsort     ;   5   double
        drsort     ;   6   complex
        intsort    ;   7   undefined, treated as integer


h.                 ; length of operand, table.
                   ; index is sort of operand
length:       1    ;   0   type is logical
              2    ;   1           integer
              4    ;   2           real, long
              8    ;   3           double, complex
w.
\f


;/operand actions 8



; the following decision table explains the addrout action

; operand checkbits            
; addr in01 inuv indr (work)        actions taken
;  y    y    -    -     -      a1.  continue
;  y    n    y    -     -      a2.  rescuuv
;  y    n    n    -     -      a3.  outbyte(al w1); out top operand
;  n    y    -    -     -      a4.  rescu01; goto a3
;  n    n    y    -     -      a5.  rescuuv; goto a4
;  n    n    n    y     -      a6.  rescudr; goto a3
;  n    n    n    n     -      a3.  outbyte(al w1); out top operand


addroutx:                        ; make address in register 1.
          bz w2 x1+opcheck       ; w2 := operand checkbits
          sz w2    inwork        ; if inwork checkbit
          al w2 x2-inwork        ;   then remove inwork
          al w3    2.1111        ; mask checkbits
          la w2    reg3          ;
          bl.w2 x2+detab.        ; take action from decision table
detabase: jl.   x2               ; goto chosen action

deta6:    jl.w3    rescudrx.     ; call rescue dr register to work
          jl.      deta3.        ; goto decision action 3
deta5:    jl.w3    rescuuvx.     ; call rescue uv register to w01
deta4:    jl.w3    rescu01x.     ; call rescue 01 register to work
deta3:    al w2    addrget       ; auxiliary al w1 address
          al w2 x2+con           ; make continuation action
          jl.      singlact.     ; goto perform single action
deta2:    jl.w3    rescuuvx.     ; call rescue uv register to w01
          jl.      curract.      ; goto current actions

detab:             ; decision table for addrout action.
;                  ; the table must be changed if checkbits alters
h.                 ; addr indr inuv in01
deta3  -detabase   ;  n    n    n    n
deta4  -detabase   ;  n    n    n    y
deta5  -detabase   ;  n    n    y    n
deta4  -detabase   ;  n    n    y    y
deta6  -detabase   ;  n    y    n    n
deta4  -detabase   ;  n    y    n    y
deta5  -detabase   ;  n    y    y    n
deta4  -detabase   ;  n    y    y    y
deta3  -detabase   ;  y    n    n    n
curractd           ;  y    n    n    y
deta2  -detabase   ;  y    n    y    n
curractd           ;  y    n    y    y
deta3  -detabase   ;  y    y    n    n
curractd           ;  y    y    n    y
deta2  -detabase   ;  y    y    y    n
curractd           ;  y    y    y    y
w.

\f


;/working variables

;  working variables
w.;-----------------

; working variables are disposed during pass 7 and will be placed
; between the simple local variables + descriptor words and the
; array buffers + zone areas.
; in the running program the working variables are referred to rela-
; tively to x2, the addresses being described  -s:work
; the following variables appears in the working variable procedures

workinit:    0     ; holding the initial -s:worknext - one word
;                  ; for each general do-loop in program unit
workfree:    0     ; holding  -s:worknext, i.e. the address part of
;                  ; the next working variable.
;                  ; the initial value  -s: first free stackword
;                  ; is deduced from pass information <no.bytes for
;                  ; simple variables etc.>
workmax:     0     ; holding the maximal absolute value of workfree
;                  ; during the passing of the present program unit.
;                  ; the terminal value is pass 8 information
worklev:     0     ; counter for work group releasing
workrel:     0     ; variable for releasing of groups of works
;                  ; used in connection with workdown.

worksetx:                        ; initialise work.
          al w2    0             ;
          rs.w2    worklev.      ; work level counter := 0
          rs.w2    workrel.      ; work release := 0
          jl.w3    inbyte.       ; w2 := gpa:inbyte( -s:free )
          bl w2    reg2last      ; extend sign of w2
          rs.w2    workinit.     ; workinit = -s:free
          rs.w2    workfree.     ; workfree := -s:free
          rs.w2    workmax.      ; workmax  := -s:free
          jl.      curract.      ; goto current actions

datalast:                        ; data last pointer to work.

zinworkx:                        ; zone index to work.
          al w0    opcopy        ; w0 := op.index for work information
c. ctest
          rs.w3    savew3.   ;***
          jl.w3    topinw1.  ;***  *** test w1 = opandtop
          rl.w3    savew3.   ;***
z.
          al w2    intsort       ; w2 := sort integer
          jl.      towork.       ; goto register to work
\f


;/working variables 2



;                                ; save register in work.

                                 ; work address to opplace.
towork8x: am       1             ; 8 byte operands, drstore
towork4x: am       1             ; 4 byte operands, dsw1
towork2x: am       1             ; 2 byte operands, rsw1
towork1x: al w2    0             ; 1 byte operands, hsw1
toworkp:  al w0    opplace       ; w0 := operand index

towork:                          ; register to work.
;                                ; work address to operand descriptor.
;                                ; call: w0 := op.index for -s:work
;                                ;       w1 := a:operand descriptor
;                                ;       w2 := sort
;                                ; exit: w2 := -s:work
          rs.w3    savew3.       ; save return
          hs.w0    workopix.     ; save operand index for -s:work
          bl.w0 x2+regstore.     ; w0 := regstore directing byte
          jl.w3    outbyte.      ; gpa:outbyte(regstore)
          sn w2    logsort       ; if sort = logical sort
workint:  al w2    intsort       ;   then sort = integer sort
          bl.w2 x2+length.       ;
          ac w2   (reg2)         ; w2 :=-length(sort),i.e.work bytes
          bz w3 x1+opdescr       ; if kind = array eq zone
          ls w3    getkind       ;
          sn w3    arreqzk       ; then
          am       2             ; save opplace
          al.w3    workop.       ; set continue

;                                ; reserve work.
workres:                         ; call: w2 := - no.bytes to reserve
;                                ;       jl.w3 workres.
;                                ; exit: w2 := -s:work (stack relative)
          wa.w2    workfree.     ; w2 := workfree - no.bytes
          sh w2    -2048         ; if local stack overflow
          jl.      runstack.     ;   then goto run stack exceeded
          sh.w2   (workmax.)     ; if new workfree < workmax
          rs.w2    workmax.      ;   then workmax := new workfree(w2)
          rx.w2    workfree.     ; w2 := -s:work ; workfree := w2
          jl    x3               ; return

workopix  =        k+1           ; set index of work information
workop:   hs w2 x1               ; operand(index  ) := -s:work
          al w0 x2               ; w0 := -s:work
          jl.w3    outbyte.      ; gpa:outbyte(-s:work)
          al w0    opx2          ;
          jl.w3    outbyte.      ; gpa:outbyte(opx2)
          al w0    inwork        ; set in work
          jl.w3    setcheck.     ; operand(descriptor) with inwork
          bz w0 x1+opcheck       ; get checkbits
          sz w0   addr         ; if address saved in work
          jl.     (savew3.)      ;   then return
          bz w3 x1+opdescr       ; if kind = array eq zone
          ls w3    getkind       ;
          se w3    zonek         ; or kind = zone then
          sn w3    arreqzk       ;  save kind
          jl.     (savew3.)      ;
          la.w3    sortmask.     ; w3 := operand sort
          al w3 x3+simlocm       ;       + simple local kind
          hs w3 x1+opdescr       ; value in work is simple local
          jl.     (savew3.)      ; return for towork
h.
regstore: hsw1                   ; store logical
          rsw1                   ; store integer, address
          dsw1                   ; store long   , real
          drstore                ; store double , complex
w.
\f


;/working variables 3

worknotx:                        ; set do not release work.
          rl.w0    workfree.     ;
          rl.w2    worklev.      ;
          al w2 x2+1             ;
          rs.w2    worklev.      ; work level := work level + 1
          sn w2    1             ; if first work level then
          rs.w0    workrel.      ; workrel := -s:first free work
          jl    x3               ; return


downwork:                        ; release work holding operand.
;                                ; call: w1 := a:operand
;                                ;       jl.w3 downwork
;                                ; exit: w2 := -s:work
          bz w2 x1+opdescr       ; w2 := operand descriptor
          ls w2    getkind       ; w2 := kind(operand)
          bl.w2 x2+workbyte.     ; w2 := workbyte(kind)
          am    x1               ;
          bl w2 x2               ; w2 := operand(-s:work)
          sh.w2   (workfree.)    ; if -s:work < workfree
          jl    x3               ;   then return
          rl.w0    workrel.      ; <>0 means wait to release work
          sn w0    0             ; if immediate work release
          jl.      workback.     ;   then goto work release
          sl.w2   (workrel.)     ; if -s:work > workrel
          rs.w2    workrel.      ;   then workrel := -s:work
          jl    x3               ; return

workdwnx:                        ; release group of working storage.
          rl.w2    worklev.      ;
          al w2 x2-1             ;
          rs.w2    worklev.      ; work level := work level - 1
          se w2    0             ; if not last work level
          jl    x3               ;   then return
          rx.w2    workrel.      ; w2 := workrel; workrel := 0

workback:                        ; release working variable(s).
          rs.w2    workfree.     ; release, i.e. set workfree back
          jl    x3               ; return

h.

workbyte:            ; table holding index in operand description
;                    ; for byte giving stack address of work.
;                    ; obs: content depending of enumeration of kinds
opplace  ; not used
opplace  ; label
opplace  ; label variable
opplace  ; simple local, expression
opplace  ; simple common
opplace  ; simple formal
opplace  ; array
opplace  ; range
opplace  ; subscripted constant
opplace  ; subscripted variable
;-1      ; subscripted optimised
opcopy   ; zone
opplace  ; array  eq zone
opplace  ; external
opplace  ; formal external
opplace  ; constant

w.
\f


;/copy




 
outlistx:                        ; transmit list.
          jl.w3    inbyte.       ; w2 := gpa:inbyte
          rs.w2    savebyte.     ; savebyte := no.list bytes
          al w1 x2               ; w1 := no.list bytes
          jl.w3    inoutn.       ; call copy w1 bytes
          jl.      saveoutx.     ; outbyte(no.); goto current actions

copy1x:
inout1:                          ; copy 1 byte. call: jl.w3 inout1.
          al w0 x3               ; w0 := return address
          jl.w3    inbyte.       ; w2 := gpa:inbyte
          rl w3    reg0          ; w3 := return address from outbyte
          al w0 x2               ; w0 := inbyte
          jl.      outbyte.      ; gpa:outbyte(inbyte)

inoutn:                          ; copy n bytes.
                                 ; call: w1:=n ; jl.w3 inoutn.
          rs.w3    savew3.       ; save return
          al.w3    0             ; for
          al w1 x1-1             ;    n := n - 1
          sl w1    0             ;    while n >= 0
          jl.      inout1.       ;     do inout1 (return to for)
          jl.     (savew3.)      ; return from inoutn

copy3x:   al w1    3             ; copy 3 bytes.
          al.w3    curract.      ; set return to current actions
          jl.      inoutn.       ; goto copy n=3 bytes

\f


;/input operands

saveinx:                         ; save inbyte in savebyte.
          jl.w3    inbyte.       ; w2 := gpa:inbyte
          rs.w2    savebyte.     ; savebyte := 0, inbyte
          jl.      curract.      ; goto current actions

opsetx:                          ; set operand description in stack.
          dl.w3   (acstatop.)    ; operand description kind
          bz w0    reg3last      ;  = next action used as parameter
          ls w0   -getkind       ; move kind
          ld w3   -12            ; remove description kind
          ds.w3   (acstatop.)    ; save rest of actions
          jl.w3    topupx.       ; w1 := operand stack pointer
          rs w0 x1+opdescr       ; set operand description
          jl.      curract.      ; goto current actions

arrayopx:                        ; array operand to stack.
          jl.w3    inbyte.       ; w2 := gpa:inbyte
          hs w2 x1+opplace       ; operand(top,opplace) := inbyte
          al w0 x1+oplower       ; w0 := a:last byte to set
          al w1 x1+opupper-2     ; w1 :: a=first byte before upper
          jl.      opbytes.      ; goto input operand bytes to stack

zoneopx:                         ; zone operand to stack.
          al w0 x1+opzoneno      ; w0 := a:last byte to set
          jl.      atplace.      ; goto set first at opplace

subcnopx:                        ; constant subscripted operand.
          al w0 x1+opbytix       ; w0 := a:last byte to set
atplace:  al w1 x1+opplace-1     ; w1 := a:first byte is before opplace
          jl.      opbytes.      ; goto input operand bytes to stack

arrqzx:                          ; array equivalenced to zone.
          al w0 x1+oplower       ; w0 := a:last byte to set
          jl.      atcopy.       ; goto set first at opcopy

simqzx:                          ; simple equivalenced to zone.
          al w0 x1+opbytix       ; w0 := a:last byte to set
atcopy:   al w1 x1+opcopy-1      ; w1 := a:first byte is before opcopy
          jl.      opbytes.      ; goto input operand bytes to stack

constopx:                        ; constant operand to stack.
c. ctest, jl.w3    topinw1.   z. ; ***  *** test w1 = opandtop
          ld w0    65            ; for the sake of constant arithmetic
          ds w0 x1+opcon         ; zero in last 4 bytes of constant
          al w0    constk<b0     ;
          rs w0 x1+opdescr       ; operand desriptor := constant val
          jl.w3    toptype.      ; insert operand sort ; w2 := type
          al w0 x1+opcon         ; w0 := a:last byte of constant
          rl w1    reg0          ;
          bl.w2 x2+sort.         ; w1 := w0 - length(sort(type))
          bs.w1 x2+length.       ; w1 := a:first byte of constant - 1
\f


;/input operands 2


opbytes:  al w1 x1+1             ; w1 := a:byte to be set
          jl.w3    inbyte.       ; w2 := gpa:inbyte
          hs w2 x1               ; opstack(top,byte) := inbyte
          se w0 x1               ; if more bytes to set
          jl.      opbytes.      ;  then goto input operand bytes
          rl.w1    opandtop.     ;  else w1 := a:top operand
          jl.      curract.      ;       goto current actions

copyopx:                         ; copy of operand place.
          rl.w1    opandtop.     ; x1 := operand stack pointcr
          bl w0 x1+opplace       ;
          hs w0 x1+opcopy        ; opcopy := opplace
          jl.      curract.      ; goto current actions

topupx:                          ; increase operand stack pointer.
          rl.w1    opandtop.     ; x1 := operand stack pointer
          al w1 x1+oplength      ;       + oplength
          rs.w1    opandtop.     ; a:next operand stack entry
c. etest, sl.w1   (opandmax.)    ; ***  *** test max opandstack
          rs.w1    opandmax.  z. ; ***
          sh.w1   (opandlim.)    ; if not over operand stack limit
          jl    x3               ;  then return
          al.w1    stackover.    ;  else stack overflow alarm
          jl.w3    alarm.        ; gpa:alarm

simcopx:                         ; simple common operand.
c. ctest, jl.w3    topinw1.   z. ; ***  *** test w1 =  opandtop
          jl.w3    inbyte.       ; w2 := gpa:inbyte
          hs w2 x1+opcomno       ; opstack(top,comno) := inbyte

placeopx:                        ; operand addressing information.
c. ctest, jl.w3    topinw1.   z. ; ***  *** test w1 =  opandtop
          jl.w3    inbyte.       ; w2 := gpa:inbyte
setplace: hs w2 x1+opplace       ; opstack(top,opplace) := inbyte
          jl.      curract.      ; goto current actions

labelopx:                        ; label operand.
c. ctest, jl.w3    topinw1.   z. ; ***  *** test w1 = opandtop
          rl.w2    labelno.      ;
          hs w2 x1+oplabel       ; opstack(top,oplabel) := labelno
          jl.      curract.      ; goto current actions

rangeopx:                        ; put ranges into operand stack.
          jl.w3    inbyte.       ; w2 := no.indices
morange:  al w2 x2-1             ; w2 := no.ranges
          sh w2    0             ; if no.ranges = 0
          jl.      curract.      ;  then goto current actions
          hs.w2    rangeno.      ; rangeno := no.ranges
          jl.w3    topupx.       ; call increase operandstack pointer
          al w2    rangek>getkind;
          rs w2 x1+opdescr       ; opstack(top,opdescr) := range kind
          jl.w3    inbyte.       ; gpa:inbyte
          hs w2 x1+oprange-1     ; opstack(top,rangebyte1) := inbyte
          jl.w3    inbyte.       ; gpa:inbyte
          hs w2 x1+oprange       ; opstack(top,rangebyte2) := inbyte
rangeno   =        k+1
          al w2    0             ; w2 := no.ranges
          jl.      morange.      ; goto more ranges
\f


;/output operands

saveoutx:                        ; output savebyte.
          rl.w0    savebyte.     ; w0 := savebyte
          jl.      outcurr.      ; outbyte; goto current actions

outlit2:                         ; output 2 byte literal.
          bl w0    reg2          ; entry: w2 := 2 byte literal
          jl.w3    outbyte.      ; gpa:outbyte(first byte)
          bl w0    reg2last      ;
          jl.w3    outbyte.      ; gpa:outbyte(last byte)
          al w0    literal2      ;
          jl.      outcurr.      ; outbyte(literal2); goto current act

zonedisx:                        ; out zone descriptor displacement.
          bz w2 x1+opcopy        ; w2 := zone descr displ
          jl.      outconst.     ; goto output constant

zonenox:                         ; output zone number operand.
          bl w2 x1+opzoneno      ; w2 := zone number operand
zonout:   sl w2    0             ; if zone number = constant
          jl.      outconst.     ;   then goto output constant byte
          al w0 x2               ;   else
          jl.w3    outbyte.      ;     outbyte(-s:zoneno)
          al w0    opx2          ;
          jl.      outcurr.      ;     outbyte(opx2 indirect); goto current act

znosavex:                        ; output zone number from savebyte.
          bl.w2    savelast.     ; w2 := zone number operand
          jl.      zonout.       ; goto output zone number

zonerecx:                        ; get zone record base address.
          rl.w3    addrwork.     ; indirect addressing to get base addr
          jl.      outopy.       ; output operand
outarrbx:                        ; output array base addr. of param.
          jl.w3    topkindy.     ; getkind
          se w2    arreqzk       ; if kind=arrey eq zone
          jl.      outbasex.     ;
          bl w0 x1+opplace       ;   then get base
          jl.      outbyx2.      ;     of zone



outcopyx:                        ; output data last pointer.
outzinx:                         ; output zone array index.
outbasex:                        ; output array base address.
                                 ; operand(opcopy) := -s:a:array0
c. ctest, jl.w3    topinw1.   z. ; ***  *** test w1 = opandtop
          bl w0 x1+opcopy        ; w0 := -s:a:array0
outbyx2:  jl.w3    outbyte.      ; gpa:outbyte
          al w0    opx2          ; w0 := operand x2 marked
          jl.      outcurr.      ; outbyte(opx2); goto current actions

;                                ; output 2 byte operand parts.
;                                ; array to rec.base displacement
zrbytix:  am     opbytix-oprange ; zone byteindex rel. rec.base
rangex:   am     oprange-oplower ; range
lowerx:   am     oplower-opupper ; lower limit
upperx:   al w3  opupper         ; upper limit
          am    x3               ;
          rl w0 x1               ; w0 := operand descriptor part
          rl.w2    varx2.        ; w2 := variable in stack
          sh w0   -1             ; if not sign bit of operand part
          sn w3    opbytix       ; or byteindex
          rl.w2    lit2.         ;   then w2 := 2 byte literal
setopy:   ls w3    12            ; w3 := operand index to first byte
          wa w3    reg2          ; w3 := w3 + w2
          jl.      outopy.       ; goto outopy
\f


;/output operands 2

outbytop: jl.w3    outbyte.      ; gpa:outbyte

outopx:                          ; output operand.
          rl.w1    opandtop.     ; w1 := a:top operand descriptor
          bz w2 x1+opdescr       ; w2 := operand descriptor
          rl.w0    sortmask.     ;
          la w0    reg2          ; w0 := sort of operand
          ls w2    getkind       ; w2 := kind of operand
          sn w2    constk        ; if kind = constant kind
          wa w2    reg0          ;   then w2 := w2 + sort
          am    x2               ; make byteindex to toparts table
          rl.w3 x2+toparts.      ; get output description
          se w3    0             ; if outop operation
          jl.      outopy.       ;  then goto out top operand
          al.w3    outopx.       ;  else set return to top op
          jl.      topdownx.     ;       reduce operand stack
outopy:                          ; entry: w1 := a:operand descriptor
;                                ;        w3 := word as in toparts
;                                ; number of bytes         <18 +
;                                ; operand index           <12 +
;                                ; operand byte descriptor
          hs.w3    outopz.       ; save operand byte descriptor
          ls w3   -6             ; split w3:in components:
          bz w2    reg3          ; w2     := number of bytes
          bz w3    reg3last      ;
          ls w3   -6             ; w3 := index of last output byte
          wa w1    reg3          ; w1 := a:last output byte
          ac w2 x2               ; w2 := - number of bytes to output
          wa w2    reg1          ; w2 := a:first output byte  -  1
outbytes: al w2 x2+1             ; w2 := a:output byte
          bl w0 x2               ; w0 := output byte
          jl.w3    outbyte.      ; gpa:outbyte
          se w1 x2               ; if not last byte
          jl.      outbytes.     ;   then goto output bytes
outopz    =        k+1           ;
          al w0                  ; operand descriptor byte
          rl.w1    opandtop.     ; w1 := a:top operand descriptor
          sh w0    0             ; if not operand directing byte
          jl.      outspec.      ;   then goto special output
          bz w2 x1+opcheck       ; w2 := operand checkbits
          so w2    addr          ; if value operand
          jl.      outcurr.      ;   then outbyte; goto current acti
          al w0    opx2i         ; w0 := x2 indirect addressing
          sn w2    inw01         ; if address in register w1
addrinw1: al w0    opx1          ;   then w0 := x1 addressing
          jl.      outcurr.      ; outbyte; goto current actions
outspec:  sn w0    0             ; if no output
          jl.      curract.      ;   then goto current actions
          ac w0   (reg0)         ; w0 := - special operand
          jl.w3    outbyte.      ; gpa:outbyte
          rl.w3    modif2.       ; w3 := modification entry
          jl.      outopy.       ; goto output operand

sortconx:                        ; output sort constant operand.
;                                ; call: savetype := type
;                                ;       jl.w3 sortcon.
          am.     (savetype.)    ;
          bl.w2    sort.         ; w2 := sort(savetype)
          jl.      concurr.      ; output sort constant
                                 ; goto current actions

out12x:   am       10            ; output constant 12 operand.
out2x:    am       1             ; output constant 2 operand.
out1x:    al w2    1             ; output constant 1 operand.
concurr:  al.w3    curract.      ; set return
\f


;/output operands 3


outconst:                        ; output constant operand.
;                                ; call: w2 := constant
;                                ;       jl.w3 outconst.
;                                ; exit: w1,w2 unchanged
          rs.w3    savew3.       ; save w3 return address
          al w0 x2               ;
          jl.w3    outbyte.      ; gpa:outbyte(constant)
          al w0    opx0          ;
          jl.w3    outbyte.      ; gpa:outbyte(opx0)
          jl.     (savew3.)      ; return

h.
toparts:                         ; table for output of operands.
;                                ; the value describes the operand
;                                ; to be output from the operand
;                                ; stack
;                                ; a:   number of bytes to output<18
;                                ; b: + index of last operandbyte<12
;                                ; c: + operand directing byte
;                                ; if c < 0 special actions are taken

;a       b       c               ; kind of operand
 1 <6+ opplace , troublop        ;  0 not used
 1 <6+ oplabel , 0               ;  1 label
 1 <6+ opplace , opx2            ;  2 label variable
 1 <6+ opplace , opx2            ;  3 simple local variable
 2 <6+ opcomrel, opcommon        ;  4 simple common variable
addrwork:                        ;    address in work, treated as
 1 <6+ opplace , opx2i           ;  5 simple formal variable
 1 <6+ opplace , opx2            ;  6 array
 0             , 0               ;  7 range
 1 <6+ opplace , -opx2i          ;  8 subscripted, constant subscript
 1 <6+ opplace , opx2            ;  9 subscripted, variable subscript
 ;0            , 0               ; -- subscripted, optimise subscript
 1 <6+ opplace , opx2            ; 10 zone
 1 <6+ opplace , opx2            ; 11 array  equivalenced to zone
 1 <6+ opplace , opext           ; 12 external
 1 <6+ opplace , opx2            ; 13 formal external
 1 <6+ opcon   , opx0            ; 14 constant, sort 0: logical
 2 <6+ opcon   , literal2        ; 15 constant, sort 1: integer
 4 <6+ opcon   , literal4        ; 16 constant, sort 2: real, long
 8 <6+ opcon   , literal8        ; 17 constant, sort 3: double, compl

lit2:   2<6    , literal2        ; 2 byte literal without index
varx2:  1<6    , opx2            ; stack variable without index
modif2:
 2 <6+ opbytix , amodify         ; 2 byte modifier

w.

\f


;/ internal variables


; variables for saving
w.;-------------------

savew0:    0       ;  save register w0
savew1:    0       ;  save register w1
savew2:    0       ;  save register w2
savew3:    0       ;  save register w3
save30:    0       ;  for double store w0 (w30)
savetype:  0       ;  save type of directing byte
savesort:  0       ;  save sort of directing byte, i.e. of operand
savelast = k + 1   ;  address of last byte in savebyte
savebyte:  0       ;  save input byte

; internal variables
type:      0       ;  type of typedependant directing bytes
labelno:   0       ;  label number, internal representation

; use of registers.
; ----------------
; the planned use of the registers during execution of the program
; is mirrored in the variables:

use01:       0     ;  the content of these pointers will be
usedr:       0     ;  a:operandstack(element) in case the register
useuv:       0     ;     is used
use3 :       0     ;     otherwise zero.
zero :       0     ;  for use in cancelling address checkbit

use01rel = use01 - use01 
usedrrel = usedr - use01
useuvrel = useuv - use01
use3rel  = use3  - use01
zerorel  = zero  - use01


; mask constants
w.;-------------

actmask:
askmask:
typemask:     2.111              ; 3 bit masks
allones:      8.77777777         ; 24 1-bits

; action parameters
ask0w1 = (: 1<3 + 0 :)<b0        ; for logical and, see relations
ask7w1 = (: 1<3 + 7 :)<b0        ; for logical or , see relations

; action table + auxiliary action table
; acttab             ; first action table entry
; acttabhi           ; last  action table entry
actlng =  4          ; 4 bytes in action entry
; auxtab             ; first auxiliary table entry
; auxtabhi           ; last  auxiliary table entry
; maxact = (:acttabhi - acttab:)/actlng
\f


;/stepping stones and pointers


;  stepping stones
addrofy:  jl.      addrof.       ; goto cancel address bit
topdowny: jl.      topdownx.     ; goto reduce operand stack
topsorty: jl.      topsort.      ; goto insert sort in description
topkindy: jl.      topkind.      ; goto insert kind in top operand
toptypey: jl.      toptype.      ; goto inset sort in top operand
rescu01y: jl.      rescu01x.     ; goto rescue 01 register
errindex: jl.      errconix.     ; goto error in constant index
errover:  jl.      overmess.     ; goto error in constant arithmetic
message:  rs.w0    svw0.         ; save w0     ; goto gpa:message
          rs.w1    svw1.         ; save w1
          al w1    -1000         ;   
          al w0     2            ; set
          rs.w0    x1+ees0.      ; warning.yes
          rl.w0    svw0.         ; get saved w0
          rl.w1    svw1.         ; get saved w1
          am      -2048          ;
          jl.      message0.+2048; goto gpa:message
svw0: 0
svw1: 0
intpass:  jl.      intpass0.     ; goto gpa:interrupt handling
topinw1:  jl.      topinw1x.     ; goto test top operand descriptor
opexchy:  jl.      opexchx.     ; goto operand exchange

init7:    jl.      init7y.       ; goto initialise

inbyte:                          ; stepping stone inbyte.
c. atest
          rs.w1    keep.     ;***
          rl.w1    passin.   ;***
          al w1 x1+1         ;***  count input bytes
          rs.w1    passin.   ;***
          rl.w1    keep.     ;***
z.
          am      -2048          ;
          jl.      take.+2048    ; gpa:inbyte

outbyte:                         ; stepping stone outbyte.
c.atest
          rs.w1    keep.     ;***
          rl.w1    passout.  ;***
          al w1 x1+1         ;***  count output bytes
          rs.w1    passout.  ;***
          rl.w1    keep.     ;***
z.
          am      -2048          ;
          jl.      give.+2048    ; gpa:outbyte
watch:             0         ;*** counter for actions
keep:              0         ;***   save register 1
passin:            0         ;***   count pass input
passout:           0         ;***   count pass output

; addresses and pointers
w.;----------------------

; action stack

acstabot:    0     ; bottom , init = a:action stack
acstalim:    0     ; limit  , init = a:operand stack
acstatop:    0     ; pointer, init = a:action stack

; operand stack

opandbot:    0     ; bottom , init = a:operand stack - oplength
opandlim:    0     ; limit  , init = a:lastword      - oplength
opandtop:    0     ; pointer, init = a:operand 0     - oplength
opandmax:    0 ;***  for testing of pass 7
opused:      0 ;***  operand counter



\f


;/main control

;  main administration on pass 6 directing bytes.
;  ----------------------------------------------

; the directing bytes for pass 7 are divided into 3 groups:
;
; 0                     ,typedep              ,dirmax
; ----------------------,---------------------,---------------->
;   type independant        type dependant        labels
;
; the value of the directing byte is related to the main action
; table or to the label number
;
;
; type independant : (index to) main action
; type dependant   :  typedep + (main action - typedep)<b0 + type
;
; typedep          ;  value of first type dependant directing byte
; dirmax           :  maximal value of directing byte from pass 6

dirbyte:  jl.w3    inbyte.       ; directing byte. w2:=gpa:inbyte
          sl w2    dirmax        ; if dirbyte >= first label byte
          jl.      labelset.     ;   then goto get label action
          sl w2    typedep       ; if dirbyte is type dependant
          jl.      typebyte.     ;   then goto extract type
          ls w2    2             ; action table index := 4*dirbyte
          jl.      actload.      ; goto load action

typebyte: al w2 x2+typedepn      ; w2 := (actno - typedep)<3 + type
          al w3    2.111         ; typemask
          la w3    reg2          ; w3   := extracted type
          rs.w3    type.         ; type := extracted type
          ws.w2    type.         ; (actno - typedep)<3
          ls w2   -1             ; 4*actno - 4*typedep
          al w2 x2+typedep4      ; index:= 4*actno
actload:  dl.w0 x2+acttab.       ; w30 := action entry
          jl.      getact.       ; goto get next action

labelset:                        ; label operand.
          rs.w2    labelno.      ; labelno := dirbyte 
          al w2    labelact      ; label action entry
          jl.      getspact.     ; goto get special action

\f


;/main control 2


; get action entry
w.;---------------

nextact:  al w3   -actlng        ; next action entry.
          wa.w3    acstatop.     ; w3 := action stack top - 1
          sn.w3   (acstabot.)    ; if action stack empty
          jl.      dirbyte.      ;   then goto take directing byte
setatop:  rs.w3    acstatop.     ; set action stack top
curract:  dl.w0   (acstatop.)    ; w30 := current actions
getact:   bz w2    reg0last      ; w2  := next action
removact: ld w0   -12            ; remove action
          ds.w0   (acstatop.)    ; current actions := rest actions
singlact:                        ; treat and split action
          rl.w3    actmask.      ; action kind mask
          la w3    reg2          ; w3 := action kind
          ls w2   -b0            ; w2 := action parameter
c. etest
          ds.w1    savew1.   ;***  test: action and parameter in print area
          ds.w3    savew3.   ;***  save registers
          sn w3    nex       ;***  if take next action
          jl.      watchend. ;***    then goto do not save action
          se w3    out       ;***  if not action outbyte
          ls w2    b0        ;***    then w2last := slang byte value
          hs w3    reg2      ;***  w2first := standard action
          rl.w1    watch.    ;***
          al w1 x1-2         ;***  watch := watch - 2
          rs.w1    watch.    ;***
          wa.w1    opandlim. ;***
          rs w2 x1           ;***  save action taken in watch area
          dl.w1    savew1.   ;***  restore registers
          dl.w3    savew3.   ;***
z.
watchend:
          bl.w3 x3+standact.     ; standard action address
acbranch: jl.w3 x3               ; call standard action
          jl.      curract.      ; continue current actions

; set auxiliary actions in action stack:  aux
w.;------------------------------------------
; auxact is a standard action that takes an action entry from the
; auxiliary action entry table, increases the action stack pointer,
; and starts these new actions
; w2 := byte index of auxiliary action table

auxact:                          ; get auxiliary actions.
                                 ; w2 := byteindex to auxact table
          dl.w0 x2+auxtab.       ; w30 := auxiliary actions

newact:                          ; enter new actions.
                                 ; entry: w30 := action entry
          al w2    actlng        ; each action entry of actlng bytes
          wa.w2    acstatop.     ; action stack pointer increased
c. dtest
          sh.w2   (acstalim.);***  if trying to spoil operand stack
          jl.      acstaok.  ;***  then
          al.w1    actover.  ;***
          jl.w3    message.  ;***  gpa:message
          rl.w1    opandtop. ;***
z.
acstaok:                         ;
          rs.w2    acstatop.     ; action stack pointer
          jl.      getact.       ; goto get next action
actover:  <:action stack error<0>:>
\f


;/main control 3



;  get continuation actions to action stack: con
w.;---------------------------------------------
; contact is a standard action used only when an action entry
; must be continued with further actions
; contact is used instead of auxact to avoid having finished (empty)
; actions in the action stack as the continuation actions overwrites
; the current actions. (the action stack pointer is not increased.)
; w2 := byte index of auxiliary action table

contact:                         ; get continuation (aux)actions.
;                                ; w2 :=byteindex to auxact table
          dl.w0 x2+auxtab.       ; w30 := auxiliary continuation acts
          jl.      getact.       ; goto get next action

;  perform general action:  doo
w.;----------------------------
; perform is a standard action that transfers control to a general
; action code of pass 7
; w2 := byteindex to the action address table
; the action address table contains the addresses of the general
; actions relative to the action base address: base

perform:
          bl.w3 x2+aat.          ; w3 := actbase: pass 7 action code

base:     jl.w3 x3               ; goto chosen action
          jl.      curract.      ; return to current action

;  output byte:  out
w.;------------------
; byteout is a standard action that outputs one byte to pass 8
; w2 := value of output byte

byteout:  al w0 x2               ; w0 := output byte
outcurr:  al.w3    curract.      ; set return to current actions
          jl.      outbyte.      ; gpa:outbyte

;  error in action table
w.;---------------------
; message on error in action table

erract:   al.w1    actmess.      ; w1 := a:text
          al.w3    curract.      ; set return
          jl.      message.      ; gpa:message
actmess:  <: wrong standard action :>

standact:                  ; standard action table
h.                         ; ---------------------
;name    standact          ; function
nex = 0, nextact-acbranch  ; next action from action stack
aux = 1, auxact -acbranch  ; auxiliary actions (w2) to action stack
con = 2, contact-acbranch  ; continue  actions (w2) to action stack
doo = 3, perform-acbranch  ; perform jump to named action of pass 7
out = 4, byteout-acbranch  ; outbyte (w2) by call of general pass
err = 5, erract -acbranch  ;
err = 6, erract -acbranch  ;
err = 7, erract -acbranch  ;
w.
\f


;/action stack actions


leavex:                          ; leave action in action stack.
;                                ; this naughty action will leave
;                                ; the rest of the current actions
;                                ; in the action stack
          al w3    actlng        ; each action entry holds actlng bytes
          wa.w3    acstatop.     ; increase action stack pointer
          rs.w3    acstatop.     ;
          jl.      dirbyte.      ; goto read next directing byte

changex:                         ; change of action suite.
;                                ; the following action is taken instead
;                                ; of the first action in the previous
;                                ; entry
          rl.w3    acstatop.     ;
          bz w2 x3+1             ; w2 := following action
          al w3 x3-actlng        ;
          rs.w3    acstatop.     ; reduce action stack
          dl.w0   (acstatop.)    ; w30 := previous action entry
          jl.      removact.     ; goto remove action


newspact:                        ; enter special actions.
          dl.w0 x2+spact.        ; w30 := special actions
          jl.      newact.       ; goto enter new actions

getspact:                        ; get special actions.
          dl.w0 x2+spact.        ; w30 := special actions
          jl.      getact.       ; goto insert these actions

curractd = curract - detabase


\f


;/interrupt in pass 7


intrupt:                         ; interrupt handling in pass 7.
                   0             ; working register 0
                   0             ; working register 1
                   0             ; working register 2
                   0             ; working register 3
                   0             ; exception register
intretur:          0             ; instruction counter
intcause:          0             ; cause of interrupt 
          jl. 2,r.(:intrupt.+e100+2:)>1
          al.w2    intrupt.      ; w2 := a:interrupt dump words
          rl.w0    intcause.     ; w0 := cause of interrupt value
          se w0    0             ; if cause =  protection violation or
          sl w0    5             ;    cause <> arithmetic overflow
          jl.      intpass.      ;   then transfer interrupt to gpa
mulflow:  jl.w3    errover.      ; error message:overflow, trouble
;                                ; w1 := a:top operand description
;                                ; w2 is unimportant, not restored
          ld w0    65            ; w30 := zeroed dummy constant
          jl.     (intretur.)    ; return


intflow:                         ; integer overflow in multiplication.
;                                ; software interrupt (hand made)
          rs.w3    intretur.     ; save return
          wm w0 x1+opcon         ; multiply constants
          sh w0   -1             ; make the test on w3
          am      -1             ;   all bits of w3 equal sign of w0
          se w3    0             ; if overflow in multiplication
          jl.      mulflow.      ;   then goto interrupt action
          jl.     (intretur.)    ;   else return


intdiv:                          ; integer division:
                                 ;   (extend sign)
          rs.w3    intretur.     ; save(return);
          bl w3    reg0          ;
          bl w3    reg3          ; w3 := sign(w0);
          wd w0 x1+opcon         ; w3w0 := result of division;
          jl.     (intretur.)    ; return;
\f



;/arithmetic

multx:    am       2             ; multiply.  arith number := 2
plusx:    al w2    0             ; add.       arith number := 0
          hs.w2    arithno.      ; save arithmetical operator number
          rl.w1    opandtop.     ; 
          al w1 x1-oplength      ; w1 := a:next operand descriptor
          rl.w2    type.         ; w2 := type(operator)
          bz.w0 x2+sort.         ; w0 := sort(operator)
          sn w0    drsort        ; if sort = drsort
          am       usedr-use01   ;   then test dr register
          sn.w1   (use01.)       ; if next operand in register(sort)
          jl.      exchange.     ;   then goto exchange top and next
          jl.      aritype.      ;   else goto choose operation

dividex:  am       2             ; divide.    arith number := 3
minusx :  al w2    1             ; subtract.  arith number := 1
          hs.w2    arithno.      ; save arithmetical number
exchange: rl.w1    opandtop.     ; w1 := a:top operand descriptor
          al w2 x1-oplength      ; w2 := a:next operand descriptor
          jl.w3    opexchx.      ; exchange top and next operand
aritype:  rl.w2    type.         ;
          ls w2    2             ; w2 := 4*type
arithno   =        k+1           ;
          al w2 x2               ; + arithmetical operator number
          hs.w2    arisult.      ; save table index
          bl.w0 x2+operator.     ; w0 := operator(type,arith.no.)
          hs.w0    aribyte.      ; save operator information
          rl.w1    opandtop.     ; w1:= a:top operand descriptor
          sh w0    0             ; if running system arithmetic
          jl.      addruv.       ;   then goto next opand addr to uv
          bz w0 x1+opdescr       ; make description(top) .and.
          la w0 x1+opdescr-oplength;    description(next)
          ls w0    getkind       ; w0 := kind(top .and. next)
          sn w0    constk        ; if two constant operands
          jl.      arithin7.     ;   then perform arithmetic now
          jl.      curract.      ;   else goto current actions
addruv:
          jl.w3    worknotx.     ; set release work after rs call
          rl.w2    type.         ;
          sh w2    long          ; if type < double
          am       addr2uv       ;   then 2 addresses to uv register
          al w2    addrnext      ; next address to uv actions
          jl.      newspact.     ; goto enter special action

h.
operator = k - 8   ; table of operator bytes.
;                  ; minus indicates running system arithmetic
;                  ; the definition of operator is k-8 as
;                  ; no type and logical type will not occur

;    +   ,    -    ,     *    ,     /    ,  type

   addw1 ,   subw1 ,    mulw1 ,    divw1 ;  integer
    faw1 ,    fsw1 ,     fmw1 ,     fdw1 ;  real
    aaw1 ,    ssw1 , -longmul , -longdiv ;  long
 -dbladd , -dblsub ,  -dblmul ,  -dbldiv ;  double
 -coxadd , -coxsub ,  -coxmul ,  -coxdiv ;  complex
 trouble , trouble ,  trouble ,  trouble ;  error

w.
\f


;/ arithmetic 2


arithin7:                        ; constant arithmetic in pass 7.
;                                ; w2 := 4*type + arith.operator number
;                                ; w1 := a:top operand descriptor
          am    x2               ; 2*w2 is byte index to table
          rl.w0 x2+arinstr.      ; load slang instruction(operator) 
          rs.w0    aricode.      ; insert slang instruction
          jl.w3    toplowx.      ; reduce operand stack
          dl w0 x1+opcon+oplength; take 4 byte of constant operand 1
aricode:           0             ; arithmetical instruction inserted
          ds w0 x1+opcon         ; save result as constant top operand
conbase:  jl.      nextact.      ; goto next action entry

arinstr   = k - 16 ; table of slang instructions for arithmetic in 7.
;                  ; the definition of arinstr can be k-16 as
;                  ; no type and logical type will not occur

          wa w0 x1+opcon         ; integer +
          ws w0 x1+opcon         ; integer -
mulset:   wm w0 x1+opcon         ; integer *, spill.no
          jl.w3    intdiv-aricode; integer /
          fa w0 x1+opcon         ; real    +
          fs w0 x1+opcon         ; real    -
          fm w0 x1+opcon         ; real    *
          fd w0 x1+opcon         ; real    /
          aa w0 x1+opcon         ; long    +
          ss w0 x1+opcon         ; long    -
mulspill: jl.w3   intflow-aricode; integer * , spill.yes

aribyte   =        k+1           ; generate code for arithmetic.
arithopx: al w0                  ; w0 := operator(type,arith.no.)
          sl w0    0             ; if not running system arithmetic
          jl.      outbytop.     ;   then goto outbyte and outop
          ac w0   (0)            ; w0 := -(-running system number)
          jl.w3    outbyte.      ; outbyte(running system number)
          al w0    gors>b0       ;
          jl.      outcurr.      ; outbyte(go running system)

squarex:                         ; multiply if operand ** 2.
          jl.w3    topkind.      ; w1 := a:top operand descriptor
;                                ; w2 := kind(top operand)
          se w2    constk        ; if kind <> constant
          jl.      curract.      ;   then goto current actions
          rl w2 x1+opcon         ; w2 := constant exponent
          se w2    2             ; if not squaring
          jl.      curract.      ;   then goto current actions
          jl.w3    topdownx.     ; reduce operand stack
          jl.w3    toptype.      ; insert sort in operand descriptor
          jl.w3    rescu01x.     ; rescue 01 register if used
          jl.w3    topupx.       ; increase operand stack
          al w2 x1-oplength      ; w2 := a:radicand descriptor
          dl w0 x2+2             ;
          ds w0 x1+2             ;
          dl w0 x2+6             ; make copy of radicand descriptor
          ds w0 x1+6             ;
          rl w0 x2+8             ; nb: change code if oplength changes
          rs w0 x1+8             ;
          al w2    squaract      ; get multiplication action
          jl.      getspact.     ; goto insert special actions

\f


;/describe result

getuv:    rs.w3    pickw3.       ; uv to 01 register.
          jl.w3    occuvx.       ; occupy uv register
          jl.w3    rescuuvx.     ; rescue uv register
          jl.     (pickw3.)      ; return

getdr:    rs.w3    pickw3.       ; dr register to work.
          jl.w3    occdrx.       ; occupy dr register
          jl.w3    rescudrx.     ; rescue dr register
          jl.     (pickw3.)      ; return
pickw3:            0             ; for return

conresx:                         ; send constant to work.
          rl.w2    sortmask.     ;
          la w2 x1+opdescr       ; w2 := sort(constant)
          al w0 x2+simlocm       ; w0 := simpel local description with sort
          rs w0 x1+opdescr       ; set description
          hs.w2    consort.      ; save constant sort
          sn w2    drsort        ; if sort = drsort
          am    regdrofx-reg01ofx;   then release dr register
          jl.w3    reg01ofx.     ;   else release 01 register
          al.w3    curract.      ; set return
consort   =        k+1           ;
          al w2                  ; w2 := sort of constant
          jl.      toworkp.      ; send constant to work area

simresx:                         ; describe simple result.
          rl.w2    type.         ; w2 := type
          ls w2    2             ; w2 := 4*type
setres:   hs.w2    arisult.      ; set table index

descresx:                        ; set descriptor of arithmetic result.
          rs.w3    savew3.       ; save return
c. ctest, jl.w3    topinw1.   z. ; ***
          bz w2 x1+opcheck       ; w2 := operand checkbits
          sz w2    inwork        ; if operand in work
          sz w2    indr          ; if operand in drreg
          jl.      4             ;  then dont release
          jl.w3    downwork.     ;   then goto release work
          jl.w3    addrof.       ; (remove addrbit, in case of long etc)
          al w0    simlocm       ; 
          rs w0 x1+opdescr       ; set description simpel local
          jl.w3    toptype.      ; insert sort in descriptor; w2:=type
          rl.w3    savew3.       ; set return 
arisult   =        k+1           ;
          al w2                  ; w2 := table index
          bl.w2 x2+arireg.       ; w2 := occupyx - occ01x
          jl.   x2+occ01x.       ; goto occupy action

arireg    =        k-8           ; table of resulting register.
h.;                              ; no type and logical type do not occur
occ01x-occ01x,occ01x-occ01x,occ01x-occ01x,occ01x-occ01x; integer
occ01x-occ01x,occ01x-occ01x,occ01x-occ01x,occ01x-occ01x; real
occ01x-occ01x,occ01x-occ01x,getuv -occ01x,getuv -occ01x; long
occdrx-occ01x,occdrx-occ01x,occdrx-occ01x,occdrx-occ01x; double
occdrx-occ01x,occdrx-occ01x,occdrx-occ01x,occdrx-occ01x; complex
occ01x-occ01x,occ01x-occ01x,occ01x-occ01x,occ01x-occ01x; trouble

uvres = k-arireg, getuv -occ01x  ; result in uv register
drres = k-arireg, occdrx-occ01x  ; result in dr register

w.
powresx:                         ; describe result of exponentiation.
          rl.w2    type.         ; w2 := type of exponentiation result
          sn w2    double        ; if type is double
          am       drres-uvres   ;   then result in dr register
          al w2    uvres         ;   else result in uv register
          jl.      setres.       ; goto set result of calculation

\f


;/array and zone variables

indicx:                          ; array indexing.
c. ctest, jl.w3    topinw1.   z. ; ***  *** test w1 = opandtop
          am.     (type.)        ; type of array to be subscripted
          bl.w2    sort.         ; w2 := sort(type)
          bl w0 x1+opdescr       ; w0 := operand description
          se w0    constint      ; if operand not constant integer
          jl.      varindex.     ;   then goto variable index
          rl w0 x1+opupper-oplength; w0 := next(upper)
          sh w0    0             ; if next opand adjustable array
          jl.      varindex.     ;   then goto variable index

;                                ; constant subscript variable.
          rl w0 x1+opcon         ; w0 := constant integer index
          jl.w3    topdownx.     ; call reduce operand stack
          ls w0 x2               ; w0 := byteindex for array
          sh w0(x1+opupper)      ; if byteindex >  upper
          sh w0(x1+oplower)      ; or byteindex <= lower
          jl.w3    errindex.     ;   then goto error in const index
          rs w0 x1+opbytix       ; operand byteindex := byteindex
          al w2 x2+subconm       ; w2 := subscript constant + sort
          rs w2 x1+opdescr       ; operand description := w2
          jl.      nextact.      ; goto next action (skip indic act)

zqindexx:                        ; zone equivalenced to array.
          am.     (type.)        ;
          bl.w2    sort.         ; w2 := sort(type)

varindex:                        ; variable array subscript.
          hs.w2    shindex1.     ; save sort of array
          al w2    indexact      ; index operand action
          jl.      newspact.     ; goto enter special actions

shindex1  =        k+1
shindexx:                        ; shift index to byteindex.
          al w2                  ; w2 := sort of array
          al w0    lsw1          ;
          jl.w3    outbyte.      ; gpa:outbyte(lsw1)
          jl.w3    outconst.     ; call outconst(sort)

checkix:                         ; check index.
          jl.                    ; switch set at initiation
;(1)      jl.      curract.      ;   if index.no then goto current act
;(2)      jl.      swindex.      ;   if index.yes then
swindex:  al w2    checkact      ; check index action
          jl.      newspact.     ; goto enter special actions

zelemx:                          ; zone element as simple local addr.
          al w0    simlocm       ; w0 := simple local descriptor
          al w2    real          ; w2 := type real
          jl.      setdescr.     ; goto set operand descriptor

asubscrx:                        ; set subscripted operand address.
          al w0    subscrm       ; w0 := subscripted descriptor
          rl.w2    type.         ; w2 := type

setdescr:                        ; set operand descriptor.
;                                ; entry: w0 := description (-sort)
;                                ;        w2 := type
c. ctest, jl.w3    topinw1.   z. ; ***  *** test w1 = opandtop
          jl.w3    topdescr.     ; insert sort in description
addrin1x:                       ; set address bit and occupy w01:
          jl.w3    setaddrx.     ; set address in checkbits
          al.w3    curract.      ; set return to current actions
          jl.      occ01x.       ; call set w01 used
\f


;/relations



; relation.
; relations appear in logical expressions. a special case of these
; are single relations in logical if statements which are given a
; special treatment.  x  relationoperator   y  will come to pass 7
; in the form     x  y  relation  relask+(= 0<10+ ask<3 + type)
; or in logif     x  y  relation   ifask+(= 1<10+ ask<3 + type)
; the parameter for relation being described in the parenthesis.

; if either x og y is evaluated in a register the generated code is
; optimised. if y is in register or neither x nor y is evaluated
; test1 is used on register ww decided by the operands type.
; if x is in register the top and next operands are exchanged and
; test2 is used

; program  operator    test 1    test 2    ,    ask     code
;   .and.                                  ,     0    so ww  1
;   .lt.      <        1 (001)   4 (100)   ,     1    sh ww  0
;   .le.      <=       3 (011)   6 (110)   ,     2    se ww  0
;   .eq.      =        2 (010)   2 (010)   ,     3    sh ww -1
;   .ge.      >=       6 (110)   3 (011)   ,     4    sl ww  0
;   .gt.      >        4 (100)   1 (001)   ,     5    sn ww  0
;   .ne.      <>       5 (101)   5 (101)   ,     6    sl ww  1
;   .or.                                   ,     7    sz ww  1

ifrelask:          0             ; byte1 = ifrel, byte2 = ask

relx:     jl.w3    inbyte.       ; w2 := gpa:inbyte := parameter
          al w0    2.111         ; typemask
          la w0    reg2          ;
          rs.w0    type.         ; type := parameter & typemask
          ls w2    2             ; ifrel to last bit of first byte
          rs.w2    ifrelask.     ; save ifrel
          ls w2   -5             ; ask in unit position
          la.w2    askmask.      ; w2 := ask
          hs.w2    ifrelask.+1   ; ask := ask from parameter
          al w0    1             ; arith.number for minus := 1
          hs.w0    arithno.      ; set arithmetical operator number
          al w0 x1-oplength      ; w0 := a:operand next
          se.w0   (use01.)       ; if opnext not in register
          jl.      aritype.      ;   then goto minus exchanged
          bz.w2 x2+askturn.      ;
          hs.w2    ifrelask.+1   ; ask := inverse relation
          jl.      exchange.     ; call minus
   
askturn   =        k-1           ; relation turn table.
;         1, 2, 3, 4, 5, 6       ; ask of given relation
h.        4, 2, 6, 1, 5, 3       ; ask of turned relation
w.

\f


;/ relations 2



relsignx:                        ; make test on sign
;                                ; top operand must be in register
          rl.w2    type.         ; w2 := type (not logical or complex)
;                                ; a fast test for integer and real
;                                ; the code depends on real < long
          sh w2    real          ; if integer or real
          jl.      relww.        ;   then goto relww
          al w0    signlong      ; w0 :=
          se w2    long          ;       if long then signlong
          al w0    signdoub      ;               else signdoub
;                                ; register 01 is unused at call
;                                ; of double minus
          jl.w3    outbyte.      ; gpa:outbyte(w0)

relww:    al w0    0             ; ww := 0
          sn w2    integer       ; if type = integer
          al w0    1<3           ;   then  ww := 1
          ba.w0    ifrelask.+1   ; + ask
          jl.w3    outbyte.      ; gpa:outbyte( ww<3 + ask )
          bl.w0    ifrelask.     ; w0 := logical if  or  relation
          se w0    0             ; if logical if
          jl.      logifrel.     ;   then goto logical if
          jl.w3    occ01x.       ;   else relation in w1
          al.w2    logical       ; w2 := logical
          al.w3    curract.      ; set return
          jl.      toplogx.      ; top operand is logical
logifrel: al w0    goiforw>b0    ;
          jl.w3    outbyte.      ; gpa:outbyte(goiforw)
          al.w3    nextact.      ; set return, cancel normal actions
          jl.      topfreex.     ; goto release top operand
\f


;/masking and shift



notx:                            ; not.
          rl.w2    type.         ; w2 := type
          al w0    notw1         ; w0 := notw1
          sl w2    real          ; if type real or long
          al w0    notw01        ;   then w0 := notw01
          jl.      outcurr.      ; outbyte(notww) ; goto current actions

orsplitx: am       actlng        ; or. modifier of or-entry

andx:     al w3    0             ; and. split depending on type
          rl.w2    type.         ;
          se w2    logical       ; if type = not logical
          jl.      maskexpr.     ;   then goto mask expression
          al w2 x3+andlogact     ; get and/or logical actions
          jl.      getspact.     ; goto get special actions
maskexpr:
          se w3    0             ; w3 := if andmask then 0
          al w3    low1-law1     ;       else orbyte - andbyte
          hs.w3    maskmod.      ; save maskmod
          rl.w1    opandtop.     ; w1 := a:top operand descriptor
          al w2 x1-oplength      ; w2 := a:next operand
          se.w2   (use01.)       ; if next operand in register
          jl.w3    opexchx.      ;   then exchange top and next
          jl.      curract.      ; goto current actions

maskx:                           ; masking.
          rl.w2    type.         ; w2 := masking type
          al w3    0             ;
          se w2    integer       ; w3 := if type integer then 0
          al w3    law01-law1    ;       else andlong - andinteger
maskmod   =        k+1
          al w3 x3               ; w3 := w3 + maskmod
          al w0 x3+law1          ; w0 := law1,low1,law01,low01
          jl.      outbytop.     ; goto outbyte and top operand

shiftx:                          ; shift.
          rl.w2    type.         ; w2 := shifting type
          al w0    lsw1          ;
          se w2    integer       ; w0 := if integer then lsw1
          al w0    ldw1          ;                  else ldw1
          jl.      outbytop.     ; outbyte and out operand

\f


;/storing

storex:                          ; outbyte (register store(type)).
                                 ; entry: type := type of operand
          am.     (type.)        ;
          bz.w2    sort.         ; w2 := sort(type)
          bl.w0 x2+regstore.     ; w0 := register store(sort)
          jl.      outbytop.     ; goto outbyte and output top operand
\f


;/constant test and conversion




monoconx:                        ; test constant operand.
;                                ; entry: w1 := a:operand descriptor
;                                ; exit:  w1 is unchanged
;                                ; if operand is a constant
;                                ;   then next action is performed
;                                ;   else next action is skipped

          bz w2 x1+opdescr       ; w2 := operand descriptor byte
          ls w2    getkind       ; w2 := kind of operand
          dl.w0   (acstatop.)    ; w30 := current actions
          se w2    constk        ; if kind <> constant
          ld w0   -12            ;   then skip next action
          jl.      getact.       ; goto get next action

;  conversion of constant operands performed during translation
;  to save run time conversions

conrtoix:                        ; convert real constant to integer.
                                 ; entry: w1 := a:operand descriptor

          dl w0 x1+opcon         ; w30 := real constant
truncmod: jl.       truncate.     ; *** modified if trunc.no ***
;         cf w0    0             ; w0  := integer(real)
          rs w0 x1+opcon         ; set integer constant in stack
          jl.      setintx.      ; goto set integer operand in stack

truncate:                        ; truncate real constant to integer:
          al w2 x3               ; w2 := sign(operand);
          sh w2   -1             ;
          fm.w0    neg1point.    ; w3w0 := abs (operand)
          fs.w0    point5.       ;       - 0.5;
          cf w0    0             ; w0 := entier (abs(operand));
          sh w2   -1             ;
          ac w0   (0)            ; w0 := ifix(operand);
          rs w0 x1+opcon         ; set integer constant in stack;
          jl.      setintx.      ; goto set integer operand in stack;

f.
neg1point:    -1.0               ; floating negate sign
point5:        0.5               ; floating half
w.

conitorx:                        ; convert integer constant to real.
                                 ; entry: w1 := a:operand descriptor

          rl w0 x1+opcon         ; w0 := integer constant
          ci w0    0             ; w30 := real(integer)
          jl.      con4.         ; goto stack 4 byte constant operand

conitolx:                        ; convert integer constant to long.
                                 ; entry: w1 := a:operand descriptor
          rl w0 x1+opcon         ; w0 := integer constant
          bl w3    reg0          ; w3 := first byte of w0, sign extend
          bl w3    reg3          ; w3 := extended sign of w0
con4:     ds w0 x1+opcon         ; set 4 byte constant in stack
          jl.      set4x.        ; goto set 4 byte

conltoix:                        ; convert long constant to integer.
;                                ; entry: w1 := a:operand descriptor
          dl w0 x1+opcon         ; w30 := long constant
          ad w0    24            ; shift error will produce interrupt
          jl.      curract.      ; constant is still in operand stack

\f


;/if statements


ifsplitx:                        ; if. split depending on type
          rl.w2    type.         ;
          se w2    logical       ; if type = not logical
          jl.      curract.      ; goto current actions
          al w2    iflogact      ; replace actions by iflog actions
          jl.      getspact.     ; goto get special action

ifarithx:                        ; arithmetical if.
          rl.w2    type.         ;
          al w0    0             ; w0 := choose(w0)
          sn w2    integer       ; if type = integer
          al w0    1<3           ;   then w0 := choose(w1)
          rs.w0    savebyte.     ; if integer then w1 else w0
          sh w2    real          ; if type = integer or real
          jl.      curract.      ;    then goto current actions
          bl.w0 x2+signtow0.     ; w0 := byte to get sign to w0
          jl.      outcurr.      ; outbyte ; goto current actions

signtow0  =        k-long        ; table of directing bytes to make
h.
          signlong               ; w0 := sign of long in w01
          signdoub               ; w0 := sign of double in dr
          ctruncr                ; w0 := real part of complex in dr
          trouble                ; not used

w.
arifposx: am       2             ; output parameter for goif.
arif0x:   al w0    4             ; ask := if pos then 6 else 4
          ba.w0    savelast.     ; param := ww + ask
          jl.      outcurr.      ; outbyte ; goto current actions

compgox:                         ; computed goto action.
          jl.w3    inbyte.       ; w2 := gpa:inbyte(no.labels)
          rs.w2    savebyte.     ; savebyte := no.labels
          rs.w1    savew1.       ; savew1 := a:last label operand
          al w0    oplength      ;
          wm.w0    savebyte.     ; w0 := oplength * no.labels
          ws w1    reg0          ; w1 := a:operand before labels
          rs.w1    opandtop.     ; release all labels from opandstack
labloop:  al w1 x1+oplength      ; for w1 := a:next label operand
          bl w0 x1+oplabel       ;     do
          jl.w3    outbyte.      ;           gpa:outbyte(label)
          al w0    0             ;
          hs w0 x1+oplabel       ; cancel label
          se.w1   (savew1.)      ; while w1 <> a:last label operand
          jl.      labloop.      ;
          rl.w1    opandtop.     ; effectuate label release
          jl.      saveoutx.     ; outbyte(no.labels);goto current act
\f


;/do statements

c. -1 ; the following optimization has not been adopted by the
      ;   new implementation


dospactx:                        ; do special action on sign of step.
          rl w0 x1+opcon         ; w0 := step
          al w2   -1             ; w2 := -1
          sh w0   -1             ; if step < 0
          al w2    1             ;   then w2 :=1
          hs.w2    signstep.     ; w2 := -sign(step)
          jl.w3    topfreex.     ; reduce operand top
signstep  =        k+1           ;
          al w2                  ; w2 = -sign(step)
          bz w0 x1+opdescr       ;
          ls w0    getkind       ; w0 := kind(operandtop)
          se w0    constk        ; if kind <> constant
          jl.      dospvar.      ;   then goto variable until
          ac w0 x2               ;        w0 :=   sign(step)
          wa w0 x1+opcon         ;              + untilconstant
          rs w0 x1+opcon         ;        operandtop := skipconstant
          jl.      dospskip.     ;   else
dospvar:  al w0    addw1         ;
          jl.w3    outbyte.      ;        gpa:outbyte(addw1)
          jl.w3    outconst.     ;        outconstant(-sign(step))
dospskip: al w0    slw1          ;
          sl w2    0             ; w0 := if step > 0 then slw1
          al w0    shw1          ;                   else shw1
          al.w3    curract.      ; set return
          jl.      outcurr.      ; outbyte(skip) ; goto current act

z.    ;

doexchx:                         ; alter operand stack:
          rl.w1    opandtop.     ;
          al w2 x1-3*oplength    ;   exchange (top, next3);
          jl.w3    opexchy.      ;     (i.e. step, boolean first)

          al w1 x1-oplength      ;
          al w2 x1-oplength      ;   exchange (next1, next2);
          jl.w3    opexchy.      ;     (i.e. until, control)

          jl.      curract.      ;   goto current actions;
\f


;/call of procedures


callx:                           ; call.
          rl.w1    opandtop.     ; w1 := a:operand descriptor
          bl w2 x1+opdescr       ; w2 := operand description
          ls w2    getkind       ; w2 := kind of called procedure
          al w0    goexternal    ; if external call
          hs.w0    callsave.     ;   callsave := goexternal
          sn w2    externk       ;
          jl.      outopx.       ;   goto output top operand
          al w0    goformal      ; else (formal call)
          hs.w0    callsave.     ;   callsave := goformal
          jl.w3    outbyte.      ;   outbyte(goformal)
          jl.      outopx.       ; goto output top operand

callresx:                        ; make result of call.
callsave  =        k+1
          al w0                  ; w0 := goformal or goexternal
          sn w0    goexternal    ; if w0 = goexternal
          jl.w3    outbyte.      ;   then outbyte(goexternal)
          rl.w2    type.         ; w2 := type of called program unit
          al.w3    curract.      ; set return to current actions
          se w2    undefin       ; if type = undefined
          sn w2    notype        ; or type = notype
          jl.      topdowny.     ;   then goto reduce operand stack
          al w0    simlocm       ; simple local description
          rs w0 x1+opdescr       ; operand description is simple local
          jl.w3    topsorty.     ; set sort of result
          al w0    xxforw>b0     ;
          jl.w3    outbyte.      ; gpa:outbyte(xxforw)
          al.w3    nextact.      ; set return to next action
          sh w2    long          ; if logical,integer,real, or long
          jl.      getuv.        ;   then result in uv register
          jl.      getdr.        ;   else result in double register

parcount:          0             ; parameter counter.
parpoint:          0             ; parameter pointer.

parnox:                          ; parameter number initiation.
          al w2    lastused      ;
          hs.w2    lastout.      ; lastout := lastused
          jl.w3    inbyte.       ; w2 := gpa:inbyte
          rs.w2    parcount.     ; parcount := total parameter number
          rs.w2    parpoint.     ; parpoint:= total no. of parameters
          rl.w3    opandtop.     ; w3:=address of top operand (last param)
   loopx: rl.w2    parpoint.     ; for i:=parpoint-1 step -1 until 1 do
          al w2 x2-1             ; begin
          sh w2    0             ;   w3:=address of next parameter
          jl.      afloopx.      ;   if w3.checkbits=inwork+addr+inw01
          rs.w2    parpoint.     ;             then clear inw01
          al w3 x3-oplength      ; end
          bz w2 x3+opcheck       ;
          sn w2 inwork+addr+inw01;
          al w2 inwork+addr      ;
          hs w2 x3+opcheck       ;
          jl.      loopx.        ;
 afloopx: rl.w2    parcount.     ; w2:=total number of parameters
          ls w2    2             ; 4*parameter number
          al w2 x2+parbytes      ; +bytes reserved for return info
          rs.w2    parpoint.     ; parpoint := s:last parameter byte
          jl.w3    worknotx.     ; set release work after call
          jl.      curract.      ; goto current actions

parnoutx:                        ; outbyte(no.of parameters).
          al w0    0             ;
          jl.w3    outbyte.      ; gpa:outbyte(0) easier for pass 8
          rl.w0    parcount.     ; 
          jl.      outcurr.      ; outbyte(no.of parameters)

parlow4x: am      -2             ; parameter pointer back 2 formals.
parlow2x: al w0   -2             ; parameter pointer back 1 formal.
          wa.w0    parpoint.     ; next parpoint := parpoint - 4 bytes
          rx.w0    parpoint.     ; w0 := parpoint; parpoint := next do.
          jl.      outcurr.      ; outbyte(+s:formal); goto current actions
\f


;/ parameter transmission


setlastx:                        ; set lastused for parameter formals.
lastout   =        k+1           ;
          al w0                  ; lastused(at first call) or zero
          sn w0    0             ; if lastused has been output
          jl.      curract.      ;   then goto current actions
          al w2    0             ;
          hs.w2    lastout.      ; lastout := 0
          jl.      outcurr.      ; outbyte(lastused); goto current act

arrzonex:                        ; parameter can be array equival zone.
          jl.w3    topkindy.     ; w2 := kind(top operand)
          se w2    arreqzk       ; if kind <> array equival. zone
          jl.      curract.      ;   then goto current actions
          al w2    arrezact      ;  actions for array eq zone
          am       -1000         ; setpping stone
          rl.w3    sortmask.+1000; lapperi: set kind to simpel local
          la w3 x1+opdescr       ; w3=operand sort+
          al w3 x3+simlocm       ;    simple local kind
          hs w3 x1+opdescr       ;
          jl.      newspact.     ; goto enter special actions

rangoutx:                        ; send ranges to dope vector in work.
          jl.w3    rescu01y.     ; save register 01 if used
          jl.w3    topkindy.     ; w2 := kind(top operand)
          se w2    rangek        ; if kind <> range
          jl.      nextact.      ;   then goto previous action entry
          jl.      curract.      ;   else goto current actions

psubarrx:                        ; choose array or zone subscripted.
          jl.w3    topkindy.     ; w2 := kind(top operand)
          se w2    simlock       ; if kind <> zone(element)
          am       arrspact      ;   then subscripted array action
          al w2    subzone       ;   else subscripted zone action
          jl.      newspact.     ; goto enter special actions

psubadrx:                        ; remove address checkbit.
          jl.w3    addrofy.      ; cancel address checkbit
          jl.      outbasex.     ; goto output top operand

neglngx:                         ; output negative length of element.
          rl.w2    type.         ; w2 := type
          am       sort-base     ;
          bl.w2 x2+base.         ; w2 := sort(type);
          am       length-base   ;
          bl.w2 x2+base.         ; w2 := length(sort(type));
          ac w0 x2               ; w0 := - length;
          jl.      outcurr.      ; outbyte(-length); goto current act

simspltx:                        ; split on simpel label parameter.
          jl.w3    rescu01y.     ; save register 01 if used
          rl.w2    type.         ; w2 := type(simpel parameter)
          sn w2    notype        ; if type = label
          jl.      curract.      ;   then goto current actions
          al w2    parsimct      ;  simpel parameter action
          jl.      getspact.     ; goto get special actions

parextx:                         ; set external in formal.
          al w2                  ; w2 := kind(procedure parameter)
          al w0    parproc       ; (prepare external procedure)
          sn w2    externk       ; if kind = external then
          jl.      outcurr.      ;   outbyte(parproc)
          al w2    parform       ; else
          ls w2   -b0            ;
          jl.      contact.      ;   continue actions(parform);

prcspltx:                        ; set formal external in formal.
          jl.w3    rescu01y.     ; save register 01 if used
          jl.w3    topkindy.     ; w2 := kind(top operand)
          hs.w2    parextx.+1    ; parext := kind(procedure parameter)
          sn w2    externk       ; if kind = external
          jl.      curract.      ;   then goto current actions
          al w0    dlw1          ;
          jl.      outcurr.      ; outbyte(dlw1); goto current actions
\f


;/ parameter transmission 2




;                                ; make formal 1 of parameter words.

kindprcx: am  -1<5+pproc -plabel ; kind procedure
kindlabx: am       plabel-psimple; kind label    (type := 0)
kindsimx: al w2    psimple       ; kind simple
          wa.w2    type.         ; + type
          jl.      outconst.     ; goto output constant byte

arrforml:          4<12 + parray ; doperel<12 + kind array-type
kindarrx: rl.w2    arrforml.     ; formal 1 for parameter array
          wa.w2    type.         ; + type
          jl.      outlit2.      ; goto output literal 2 constant

zonforml:          6<12 + pzone  ; doperel<12 + kind zone
kindzonx: rl.w2    zonforml.     ; formal 1 for zone
          jl.      outlit2.      ; goto output literal 2 constant

kindzarx: al w2    0             ;
          jl.      addzar.       ; goto add zone array kind

zarspltx:                        ; split on adjustable zone.
          bl w2 x1+opzoneno      ; w2 := number of zones
          sl w2    0             ; if not adjustable zone  array
          jl.      zarload.      ;   then goto zone array param
          al w2    adjzarct      ; adjustable zone array action
          jl.      getspact.     ; goto get special actions
zarload:  al w0    loadw0        ;
          jl.w3    outbyte.      ; gpa:outbyte(loadw0)
          ls w2    12            ; number of zones < 12
addzar:   al w2 x2+parray        ; + kind zone array
          jl.      outlit2.      ; goto output literal 2 constant
\f


;/return from program unit


retexitx:                        ; return, release zones.
          jl.w3    inbyte.       ; w2 := release zones<2 + sort of unit
          hs.w2    returno.      ; save sort of unit
          so w2    1<2           ; if no release zones
          jl.      curract.      ;   then goto current actions
          al w2 x2-1<2           ; remove release zone bit
          hs.w2    returno.      ; save sort of unit
          al w2    auxrelz       ; special action aux+relzone
          jl.      newspact.     ; goto enter special action

returno   =        k+1           ; choose return from sort of unit.
retwayx:  al w2                  ; w2 := sort of unit
          ls w2    2             ; byteindex for return action
          al w2 x2+subrout       ; load special action
          jl.      newspact.     ; goto enter return actions

loadresx:                        ; load function result.
          al w0    procval       ; value in x2+procval at run time
          jl.      outcurr.      ; outbyte ; goto current actions
\f


;/test initiation


w.
testinit:
          ld w0    65        ;***  initiate test.
c. atest
          ds.w0    passout.  ;*** in and out counters = 0
z.
zerofill:
c. etest
          ds w0 x2           ;***
          al w2 x2-4         ;***  fill action and opstack with
          sl w2   (reg1)     ;***  zeroes.
          jl.      zerofill. ;***
z.
c. dtest
          al.w1    opstack.  ;***
          rs.w1    acstalim. ;***
          rs.w1    opandbot. ;***  leave oplength for extra actions
          rs.w1    opandtop. ;***
;  initialize bottom- and next lower operand to reasonable values
          al w0    3<3              ; kind:=simloc
          rs w0 x1+opdescr          ;
          rs w0 x1+opdescr-oplength  ;
          al w0    -7              ; addr. in stack
          hs w0 x1+opplace           ;
          hs w0 x1+opplace-oplength  ;
z.
c. etest
          al w1 x1+opprint   ;***
          rs.w1    opused.   ;***
z.
          rl.w1    opandtop.     ; w1 := a:top operand descriptor
          jl.      dirbyte.      ; goto get first directing byte

init7y:   jl.      init7x.       ; go on to initiation


\f


;/action address table




aat: ; action address table
h.   ; --------------------

;action name definition                page

addrin1  =(:k-aat:)<b0, addrin1x-base;  51  set address bit and occupy w01
addrout  =(:k-aat:)<b0, addroutx-base;  31  make address in register 1
and      =(:k-aat:)<b0, andx    -base;  54  and,split on type
areas    =(:k-aat:)<b0, areasx  -base;  17  area pass information
arifpos  =(:k-aat:)<b0, arifposx-base;  57  output parameter for goif
arif0    =(:k-aat:)<b0, arif0x  -base;  57  output parameter for goif
arithop  =(:k-aat:)<b0, arithopx-base;  49  arithmetical operations
arrayop  =(:k-aat:)<b0, arrayopx-base;  36  array operand to stack
arrqz    =(:k-aat:)<b0, arrqzx  -base;  36  array equivalenced zone
arrzone  =(:k-aat:)<b0, arrzonex-base;  60  split if array equival zone
asubscr  =(:k-aat:)<b0, asubscrx-base;  51  set element address
call     =(:k-aat:)<b0, callx   -base;  59  call program unit
callres  =(:k-aat:)<b0, callresx-base;  59  make result of call
change   =(:k-aat:)<b0, changex -base;  46  change of action suite
compgo   =(:k-aat:)<b0, compgox -base;  57  computed goto
conitol  =(:k-aat:)<b0, conitolx-base;  56  integer to long constant
conitor  =(:k-aat:)<b0, conitorx-base;  56  integer to real constant
conltoi  =(:k-aat:)<b0, conltoix-base;  56  long to integer constant
conres   =(:k-aat:)<b0, conresx -base;  50  send constant to work area
conrtoi  =(:k-aat:)<b0, conrtoix-base;  56  real to integer constant
constop  =(:k-aat:)<b0, constopx-base;  36  constant operand
copyop   =(:k-aat:)<b0, copyopx -base;  37  copy of operand place
copy1    =(:k-aat:)<b0, copy1x  -base;  35  copy one byte
copy3    =(:k-aat:)<b0, copy3x  -base;  35  copy three bytes
data     =(:k-aat:)<b0, datax   -base;  19  set dataexist
databyt  =(:k-aat:)<b0, databytx-base;  19  make length of data array
dataexi  =(:k-aat:)<b0, dataexix-base;  19  if data output dataexist
dataset  =(:k-aat:)<b0, datasetx-base;  19  make data array pointers
datasui  =(:k-aat:)<b0, datasuix-base;  19  send sort of data
dataval  =(:k-aat:)<b0, datavalx-base;  19  update data pointer
declbeg  =(:k-aat:)<b0, declbegx-base;  18  declare array or zone
descres  =(:k-aat:)<b0, descresx-base;  50  set description of result
divide   =(:k-aat:)<b0, dividex -base;  48  division
doexch   =(:k-aat:)<b0, doexchx -base;  58  alter operand stack
endline  =(:k-aat:)<b0, endlinex-base;  16  end of program line
endstat  =(:k-aat:)<b0, endstatx-base;  15  end of program statement
fixarr   =(:k-aat:)<b0, fixarrx -base;  18  make test for fix array
getaddr  =(:k-aat:)<b0, getaddrx-base;  30  get address of operand
getentr  =(:k-aat:)<b0, getentrx-base;  17  get entry point list
ifarith  =(:k-aat:)<b0, ifarithx-base;  57  arithmetical if
ifsplit  =(:k-aat:)<b0, ifsplitx-base;  57  if,split on type
indic    =(:k-aat:)<b0, indicx  -base;  51  array indexing
initarr  =(:k-aat:)<b0, initarrx-base;  18  initiate param array
ixforml  =(:k-aat:)<b0, ixformlx-base;  18  check size of formal array
kindarr  =(:k-aat:)<b0, kindarrx-base;  61  set kind array
kindlab  =(:k-aat:)<b0, kindlabx-base;  61  set kind label
kindprc  =(:k-aat:)<b0, kindprcx-base;  61  set kind procedure
kindsim  =(:k-aat:)<b0, kindsimx-base;  61  set kind simple
kindzar  =(:k-aat:)<b0, kindzarx-base;  61  set kind zone (array adj)
kindzon  =(:k-aat:)<b0, kindzonx-base;  61  set kind zone(zone array)
labelop  =(:k-aat:)<b0, labelopx-base;  37  label operand
leave    =(:k-aat:)<b0, leavex  -base;  46  leave action in stack
loadres  =(:k-aat:)<b0, loadresx-base;  62  load function result
loczone  =(:k-aat:)<b0, loczonex-base;  18  copy local zone info
lower    =(:k-aat:)<b0, lowerx  -base;  38  output array lower limit
\f


;/action address table 2


mask     =(:k-aat:)<b0, maskx   -base;  54  masking
minus    =(:k-aat:)<b0, minusx  -base;  48  subtraction
monocon  =(:k-aat:)<b0, monoconx-base;  56  next action if const opand
mult     =(:k-aat:)<b0, multx   -base;  48  multiplication
neglng   =(:k-aat:)<b0, neglngx -base;  60  negative length of element
not      =(:k-aat:)<b0, notx    -base;  54  not
notimpl  =(:k-aat:)<b0, notimplx-base;  13  not implemented  
occdr    =(:k-aat:)<b0, occdrx  -base;  24  dr register occupied
occuv    =(:k-aat:)<b0, occuvx  -base;  24  register uv occupied
occ01    =(:k-aat:)<b0, occ01x  -base;  24  register 01 occupied
opset    =(:k-aat:)<b0, opsetx  -base;  36  set operand description
orsplit  =(:k-aat:)<b0, orsplitx-base;  54  or,split on type
outarrb  =(:k-aat:)<b0, outarrbx-base;  38  output array base for param
outbase  =(:k-aat:)<b0, outbasex-base;  38  output array base
outcom   =(:k-aat:)<b0, outcomx -base;  17  copy common list
outcopy  =(:k-aat:)<b0, outcopyx-base;  38  output operand copy
outentr  =(:k-aat:)<b0, outentrx-base;  17  output entry list
outext   =(:k-aat:)<b0, outextx -base;  17  output external list
outlist  =(:k-aat:)<b0, outlistx-base;  35  copying of lists
outop    =(:k-aat:)<b0, outopx  -base;  39  output operand (general)
outzin   =(:k-aat:)<b0, outzinx -base;  38  output zone array index
out1     =(:k-aat:)<b0, out1x   -base;  39  output the constant 1
out2     =(:k-aat:)<b0, out2x   -base;  39  output the constant 2
out12    =(:k-aat:)<b0, out12x  -base;  39  output the constant 12
paramar  =(:k-aat:)<b0, paramarx-base;  18  parameter array declare
parext   =(:k-aat:)<b0, parextx -base;  60  set external in formal
parlow2  =(:k-aat:)<b0, parlow2x-base;  59  parameter pointer back 1 formal
parlow4  =(:k-aat:)<b0, parlow4x-base;  59  parameter pointer back 2
parno    =(:k-aat:)<b0, parnox  -base;  59  initiate param.pointer
parnout  =(:k-aat:)<b0, parnoutx-base;  59  output no.of parameters
passend  =(:k-aat:)<b0, passendx-base;  16  end pass7, call pass8
placeop  =(:k-aat:)<b0, placeopx-base;  37  operand addressing info
plus     =(:k-aat:)<b0, plusx   -base;  48  addition
powres   =(:k-aat:)<b0, powresx -base;  50  set exponentiation result
prcsplt  =(:k-aat:)<b0, prcspltx-base;  60  set formal external in formal
psubadr  =(:k-aat:)<b0, psubadrx-base;  60  no address in param array
psubarr  =(:k-aat:)<b0, psubarrx-base;  60  array or zone subscripted
pzarray  =(:k-aat:)<b0, pzarrayx-base;  18  zone(array) as parameter
range    =(:k-aat:)<b0, rangex  -base;  38  output range
rangeop  =(:k-aat:)<b0, rangeopx-base;  37  range operands to stack
rangout  =(:k-aat:)<b0, rangoutx-base;  60  ranges to dope vector in work
regdrof  =(:k-aat:)<b0, regdrofx-base;  24  dr register free
reg01of  =(:k-aat:)<b0, reg01ofx-base;  24  01 register free
rel      =(:k-aat:)<b0, relx    -base;  52  relation,may be optimised
relsign  =(:k-aat:)<b0, relsignx-base;  53  test sign of relation
rescudr  =(:k-aat:)<b0, rescudrx-base;  25  rescue dr register
rescuuv  =(:k-aat:)<b0, rescuuvx-base;  25  rescue uv register
rescu01  =(:k-aat:)<b0, rescu01x-base;  25  rescue 01 register
resinuv  =(:k-aat:)<b0, resinuvx-base;  26  result in uv register
retexit  =(:k-aat:)<b0, retexitx-base;  62  return release zones
retway   =(:k-aat:)<b0, retwayx -base;  62  choose sort of return
savein   =(:k-aat:)<b0, saveinx -base;  36  save inbyte
saveout  =(:k-aat:)<b0, saveoutx-base;  38  output saved byte
setint   =(:k-aat:)<b0, setintx -base;  26  set operand sort in descr
setlast  =(:k-aat:)<b0, setlastx-base;  60  lastused for parameter set up
set4     =(:k-aat:)<b0, set4x   -base;  26  set operand sort in descr
set8     =(:k-aat:)<b0, set8x   -base;  26  set operand sort in sescr
\f


;/ action address table 3


shift    =(:k-aat:)<b0, shiftx  -base;  54  shift
shindex  =(:k-aat:)<b0, shindexx-base;  51  shift integer index
simcop   =(:k-aat:)<b0, simcopx -base;  37  simple common operand
simqz    =(:k-aat:)<b0, simqzx  -base;  36  simple equivalenced zone
simres   =(:k-aat:)<b0, simresx -base;  50  set simple result
simsplt  =(:k-aat:)<b0, simspltx-base;  60  split on label parameter
sortcon  =(:k-aat:)<b0, sortconx-base;  39  output sort constant
square   =(:k-aat:)<b0, squarex -base;  49  multiply if **2
store    =(:k-aat:)<b0, storex  -base;  55  outbyte regstore
subcnop  =(:k-aat:)<b0, subcnopx-base;  36  constant subscripted op
topdown  =(:k-aat:)<b0, topdownx-base;  29  reduce operand stack
topfree  =(:k-aat:)<b0, topfreex-base;  29  release top operand
toplog   =(:k-aat:)<b0, toplogx -base;  27  top logical to register
toplow   =(:k-aat:)<b0, toplowx -base;  29  topdown in next action
topnext  =(:k-aat:)<b0, topnextx-base;  27  exchange top and next
topold   =(:k-aat:)<b0, topoldx -base;  26  save part of old descr
topreg   =(:k-aat:)<b0, topregx -base;  27  top to register
topup    =(:k-aat:)<b0, topupx  -base;  37  increase operand stack
top1     =(:k-aat:)<b0, top1x   -base;  27  top to register w1
typint   =(:k-aat:)<b0, typintx -base;  26  set integer type
typ4     =(:k-aat:)<b0, typ4x   -base;  26  set real or long type
typ8     =(:k-aat:)<b0, typ8x   -base;  26  set double or complex
towork2  =(:k-aat:)<b0, towork2x-base;  33  save register in work
uninit   =(:k-aat:)<b0, uninitx -base;  17  initiate new program unit
upper    =(:k-aat:)<b0, upperx  -base;  38  output array upper limit
workdwn  =(:k-aat:)<b0, workdwnx-base;  34  reduce workpointer
worknot  =(:k-aat:)<b0, worknotx-base;  34  protect work
workset  =(:k-aat:)<b0, worksetx-base;  32  initiate workpointers
zarsplt  =(:k-aat:)<b0, zarspltx-base;  61  pslit on adjustable zone
outzcom  =(:k-aat:)<b0, outzcomx-base;  17  output zone common list
zelem    =(:k-aat:)<b0, zelemx  -base;  51  zone element as simple
zinwork  =(:k-aat:)<b0, zinworkx-base;  32  zone index to work
znosave  =(:k-aat:)<b0, znosavex-base;  38  output zone no. saved
zonedis  =(:k-aat:)<b0, zonedisx-base;  38  output zone descr displ
zoneno   =(:k-aat:)<b0, zonenox -base;  38  output zone no. operand
zoneop   =(:k-aat:)<b0, zoneopx -base;  36  zone operand to stack
zonerec  =(:k-aat:)<b0, zonerecx-base;  38  get zone record base address
zrbyti   =(:k-aat:)<b0, zrbytix -base;  38  output zone rec byteindex
zqindex  =(:k-aat:)<b0, zqindexx-base;  51  zone equivalenced array
\f


;/ auxiliary action table
w.

aut: ; auxiliary action entry table.
h.   ; -----------------------------
auxtab = k + 3                   ; auxtab is used for addressing
;                                ; of an auxiliary table entry
; the auxiliary table entries consist each of 4 bytes describing
; an action.
; the name of the auxiliary action is defined relatively to the
; out name of the auxiliary action entry table.
; care must be taken that names are defined when used in expressions
; therefore the auxiliary table is divided into 2 alfabetically ordered
; parts. both must be placed before the general action entry table.
; (these restrictions are caused by slang.)
; the action table can have a maximum of 2**7=128 entries at present

; part 1 of auxiliary action table

; auxiliary name   ,   action4  ,  action3  ,  action2  ,  action1

chforml=(:k-aut:)<b0,  0        ,doo+topfree,doo+ixforml,out+chupper
free2  =(:k-aut:)<b0,  0        ,  0        ,doo+topfree,doo+topfree
gocond =(:k-aut:)<b0,  0        ,doo+topdown,doo+outop  ,out+goif
outopf =(:k-aut:)<b0,  0        ,  0        ,doo+topfree,doo+outop
pardow2=(:k-aut:)<b0,out+opx3a  ,doo+parlow2,out+rsw1a  ,doo+setlast
pardow4=(:k-aut:)<b0,out+opx3a  ,doo+parlow4,out+dsw1a  ,doo+setlast
parform=(:k-aut:)<b0,  0        ,  0        ,doo+topfree,aux+pardow4
parfor1=(:k-aut:)<b0,  0        ,  0        ,doo+topfree,aux+pardow2
power  =(:k-aut:)<b0,  0        ,  0        ,doo+powres ,out+gors
reg01uv=(:k-aut:)<b0,  0        ,  0        ,doo+reg01of,out+regtouv
topint =(:k-aut:)<b0,  0        ,  0        ,doo+setint ,doo+topreg
topregf=(:k-aut:)<b0,  0        ,  0        ,doo+topfree,doo+topreg
top1f  =(:k-aut:)<b0,  0        ,  0        ,doo+topfree,doo+top1
top4   =(:k-aut:)<b0,doo+set4   ,doo+occ01  ,doo+topreg ,doo+rescu01
top8   =(:k-aut:)<b0,doo+set8   ,doo+occdr  ,doo+topreg ,doo+rescudr
zoneq2 =(:k-aut:)<b0,doo+zelem  ,out+zrechk ,doo+zonedis,out+addw3
zoneq1 =(:k-aut:)<b0,con+zoneq2 ,doo+outop  ,out+rlw3   ,doo+zrbyti
c. (:(:k-aut:) a. 2.11:) - 1
m.*** formaterror of auxiliary action table part 1
z.

; part 2 of auxiliary action table

addrcon=(:k-aut:)<b0,  0        ,doo+addrout,doo+conres ,doo+topreg
addrget=(:k-aut:)<b0,  0        ,  0        ,doo+outop  ,out+alw1
addrop =(:k-aut:)<b0,  0        ,  0        ,doo+outop  ,out+rlw1a
addrsim=(:k-aut:)<b0,  0        ,  0        ,  0        ,doo+addrout
adjarr1=(:k-aut:)<b0,con+chforml,doo+sortcon,out+rlw3   ,doo+lower
arifneg=(:k-aut:)<b0,doo+topdown,doo+outop  ,out+gosimpl,aux+gocond
arrbase=(:k-aut:)<b0,doo+outbase,out+rsw1a  ,doo+lower  ,out+subw1a
arrezp =(:k-aut:)<b0,doo+zrbyti ,out+addw1a ,out+opx1a  ,out+0
arrfor1=(:k-aut:)<b0,  0        ,  0        ,doo+kindarr,out+loadw0a
arrinit=(:k-aut:)<b0,out+starray,doo+initarr,doo+outop  ,out+dlw1a
asslab =(:k-aut:)<b0,doo+topdown,doo+outop  ,out+rsw1a  ,doo+topdown
byteix =(:k-aut:)<b0,  0        ,  0        ,doo+sortcon,out+lsw1a
callout=(:k-aut:)<b0,doo+workdwn,out+point01,doo+parnout,doo+setlast
ctor   =(:k-aut:)<b0,  0        ,out+ctruncr,doo+regdrof,aux+top4
datacon=(:k-aut:)<b0,out+opx3a  ,out+0      ,doo+dataval,out+addw3
datafin=(:k-aut:)<b0,doo+outcopy,out+rsw1a  ,doo+outcopy,out+addw1a
datanew=(:k-aut:)<b0,  0        ,  0        ,doo+dataset,doo+lower
dataux2=(:k-aut:)<b0,out+suite  ,doo+datasui,doo+outop  ,out+rsw3
dataux1=(:k-aut:)<b0,con+datacon,doo+outop  ,out+rlw3   ,aux+topregf
declare=(:k-aut:)<b0,out+opx2a  ,doo+saveout,out+rsw1a  ,doo+declbeg
doass  =(:k-aut:)<b0,  0        ,doo+store  ,aux+topregf,doo+setint
dofirst=(:k-aut:)<b0,doo+topup  ,doo+outop  ,out+dogofor,doo+toplow
doinit2=(:k-aut:)<b0,out+xxchang,out+xxbackw,out+goforwa,doo+towork2
doinit1=(:k-aut:)<b0,con+doinit2,out+opx0a  ,out+0<b0   ,out+alw1
doinit =(:k-aut:)<b0,  0        ,con+doinit1, simlock   ,doo+opset
doloop =(:k-aut:)<b0,  0        ,out+xxforw ,doo+outop  ,out+rsw2
domult1=(:k-aut:)<b0,  0        ,  0        ,con+outopf ,out+domul
domult =(:k-aut:)<b0,con+domult1,out+opx1a  ,out+0<b0   ,out+acw1
doparr =(:k-aut:)<b0,con+parform,aux+arrfor1,doo+getaddr,doo+towork2
doplow =(:k-aut:)<b0,  0        ,doo+towork2,doo+lower  ,out+loadw1a
doprang=(:k-aut:)<b0,doo+topfree,doo+towork2,doo+range  ,out+loadw1a
dopupp =(:k-aut:)<b0,  0        ,doo+towork2,doo+upper  ,out+loadw1a
\f


;/auxiliary action table 2
dostep3=(:k-aut:)<b0,  0        ,con+free2  ,doo+arithop,doo+minus
dostep2=(:k-aut:)<b0,con+dostep3,doo+store  ,doo+arithop,doo+plus
dostep1=(:k-aut:)<b0,con+dostep2,aux+outopf ,out+doclear,doo+doexch
dostep =(:k-aut:)<b0,  0        ,con+dostep1,doo+rescu01,doo+topreg
dotest =(:k-aut:)<b0,  0        ,  0        ,out+goiforw,out+3<b0
dtol   =(:k-aut:)<b0,out+gors   ,out+dtruncl,doo+resinuv,aux+top4
dtor   =(:k-aut:)<b0,out+gors   ,out+dtruncr,doo+resinuv,aux+top4
formal =(:k-aut:)<b0,  0        ,out+opx2a  ,doo+copy1  ,out+dlw1a
funcval=(:k-aut:)<b0,  0        ,  0        ,out+opx2ia ,doo+loadres
goaddr =(:k-aut:)<b0,  0        ,  0        ,out+gors   ,out+endaddr
;gocond              see auxiliary table start
itol   =(:k-aut:)<b0,  0        ,  0        ,out+iconvl ,aux+top4
itolin7=(:k-aut:)<b0,  0        ,  0        ,doo+set4   ,doo+conitol
itorin7=(:k-aut:)<b0,  0        ,  0        ,doo+set4   ,doo+conitor
itor   =(:k-aut:)<b0,out+ifloatr,aux+top4   ,con+itorin7,doo+monocon
lowerix=(:k-aut:)<b0,  0        ,con+byteix ,doo+out1   ,out+subw1a
ltod   =(:k-aut:)<b0,con+power  ,out+lfloatd,aux+reg01uv,aux+top8
ltoi   =(:k-aut:)<b0,  0        ,  0        ,out+lconvi ,aux+topint
ltor   =(:k-aut:)<b0,  0        ,out+gors   ,out+lfloatr,aux+loadres
ltoiin7=(:k-aut:)<b0,  0        ,  0        ,doo+setint ,doo+conltoi
nexaddr=(:k-aut:)<b0,  0        ,doo+topup  ,doo+getaddr,doo+toplow
;outopf - parfor2    see auxiliary table start
pararr =(:k-aut:)<b0,con+doparr ,doo+arrzone,doo+outarrb,out+loadw1a
parlab =(:k-aut:)<b0,  0        ,con+parform,doo+kindlab,out+loadw0a
parzone=(:k-aut:)<b0,doo+znosave,out+chzono ,doo+pzarray,doo+savein
procfor=(:k-aut:)<b0,  0        ,con+parform,doo+kindprc,out+loadw0a
rangpar=(:k-aut:)<b0,  0        ,con+rangpar,aux+doprang,doo+rangout
relasub=(:k-aut:)<b0,doo+descres,doo+arithop,aux+topregf,doo+rel
relzone=(:k-aut:)<b0,  0        ,  0        ,out+gors   ,out+zonerel
rpowi  =(:k-aut:)<b0,  0        ,con+power  ,out+rexpoi ,doo+typ4
rsuv0  =(:k-aut:)<b0,  0        ,out+reguv0 ,aux+nexaddr,aux+reg01uv
rsuv01 =(:k-aut:)<b0,con+rsuv0  ,doo+getaddr,doo+rescu01,doo+rescuuv
rtoc   =(:k-aut:)<b0,doo+powres ,out+rconvc ,doo+reg01of,aux+top8
rtod   =(:k-aut:)<b0,con+power  ,out+rconvd ,aux+reg01uv,aux+top8
rtoiin7=(:k-aut:)<b0,  0        ,  0        ,doo+setint ,doo+conrtoi
rtoi   =(:k-aut:)<b0,out+rtrunci,aux+topint ,con+rtoiin7,doo+monocon
rtol   =(:k-aut:)<b0,  0        ,out+gors   ,out+rtruncl,doo+topreg
saveset=(:k-aut:)<b0,  0        ,out+opx2a  ,doo+saveout,out+rsw1a
shift12=(:k-aut:)<b0,  0        ,  0        ,doo+out12  ,out+lsw1a
simeqz =(:k-aut:)<b0,  0        ,aux+zoneq1 ,out+loadw1a,doo+rescu01
sspower=(:k-aut:)<b0,doo+topfree,aux+rsuv01 ,doo+worknot,doo+rescu01
subform=(:k-aut:)<b0,  0        ,con+parfor1,doo+kindsim,out+addw1a
submove=(:k-aut:)<b0,con+subform,out+opx0a  ,out+5<b0   ,out+lsw1a
subrest=(:k-aut:)<b0,con+submove,out+opx1a  ,doo+neglng ,out+acw1
subz1  =(:k-aut:)<b0,con+subrest,out+amodifa,out+4<b0   ,out+0
;topint,top8,top4     see auxiliary table start
xdexpod=(:k-aut:)<b0,con+power  ,out+dexpod ,aux+sspower,doo+typ8
xipow  =(:k-aut:)<b0,  0        ,con+rtoi   ,aux+rpowi  ,aux+sspower
xitor  =(:k-aut:)<b0,con+xipow  ,doo+typ4   ,doo+topup  ,aux+itor
zarform=(:k-aut:)<b0,  0        ,doo+zoneno ,out+loadw1a,aux+pardow2
zarset =(:k-aut:)<b0,con+parfor1,doo+kindzar,out+addw1a ,aux+shift12
zcomma =(:k-aut:)<b0,doo+outop  ,out+addw1a ,out+zindex ,doo+zoneno
zinzar =(:k-aut:)<b0,con+zarset ,doo+out1   ,out+addw1a ,doo+outzin
;zoneq2,zoneq1       see auxiliary table start
zrbase =(:k-aut:)<b0,doo+out2   ,out+lsw1a  ,doo+outop  ,out+rlw3
c. (:(:k-aut:) a. 2.11:) - 1
m.*** formaterror of auxiliary action table part 2
z.


\f


;/special action table
w.


sat: ;  special action entry table
h.   ;----------------------------
spact = k + 3
; the following action entries are used when in an action a different
; suite of actions should be taken.

; action name      ,  action4  ,  action3  ,  action2  ,  action1

iflogact = k-sat   ; same as andlogact. obs orlogact must follow
andlogact= k-sat   ,  0        ,out+goiforw,out+ask0w1 ,aux+topregf
orlogact = k-sat   ,  0        ,out+goiforw,out+ask7w1 ,aux+topregf
addrnext = k-sat   ,con+reg01uv,aux+nexaddr,doo+rescu01,doo+rescuuv
addr2uva = k-sat   ,  0        ,doo+topfree,doo+change ,aux+rsuv01
adjzarct = k-sat   ,  0        ,  0        ,con+zarset ,aux+zarform
auxrelz  = k-sat   ,  0        ,  0        ,  0        ,con+relzone
arrezact = k-sat   ,con+arrezp ,out+rlw1a  ,doo+zonedis,out+addw1a
checkact = k-sat   ,doo+lower  ,out+chlower,doo+upper  ,out+chupper
indexact = k-sat   ,  0        ,doo+shindex,doo+topfree,doo+top1
labelact = k-sat   ,  0        ,doo+labelop,  labelk   ,doo+opset
parsimct = k-sat   ,con+parform,doo+kindsim,out+loadw0a,doo+getaddr
squaract = k-sat   ,doo+descres,doo+arithop,aux+topregf,doo+mult
subarr   = k-sat   ,con+subrest,doo+upper  ,out+subw1a ,doo+psubadr
subzone  = k-sat   ,con+subz1  ,doo+zonerec,out+subw1a ,doo+zonerec
zparact  = k-sat   ,con+saveset,out+opx2ia ,doo+copy1  ,out+loadw1a

subrout  = k-sat   ,  0        ,  0        ,  0        ,con+goaddr
uvfunct  = k-sat   ,out+gors   ,out+endreg ,aux+funcval,out+dlw1a
drfunct  = k-sat   ,con+goaddr ,out+draddr ,aux+funcval,out+drloada
; the subrout, uvfunct, and drfunct actions must be in sequence
; see retway action

addr2uv  = addr2uva - addrnext
arrspact = subarr - subzone

c. (:(:k-sat:) a. 2.11:) - 1
m.*** formaterror special action table
z.




\f


;/ main action table



;  action table.
h.;-------------
acttab = k-1

; the order of the action table corresponds to the values of the
; directing bytes from pass 6. the action entry is put into the action
; stack.
; each action table entry consists of a double word holding 4
; actions of 1 byte each and action 1 in the last byte.
; the structure of an action is:  action name<b0 + standard action

; the standard actions are:
;  0 : next action entry from action stack, if empty new dir.byte
; aux: place auxiliary actions in action stack
; con: continuation actions to action stack
; doo: perform named instructions of pass 7 code
; out: output (directing) byte for pass 8

; action4  ,  action3  ,  action2  ,  action1  ; byte from pass 6

;                                              ; h0+  unit separator.
  0         ,  0       ,doo+uninit ,out+unit7  ;  0   begin unit
  0         ,  0       ,  0        ,out+funit7 ;  1   end unit
 0        ,doo+passend,out+pass7  ,doo+copy1  ;  2   end pass
;                                              ; h1+  lists.     
  0        ,out+glolist,doo+getentr,doo+savein ;  0   global entries
  0        ,out+comlist,doo+outcom ,doo+savein ;  1   common list
  0       ,out+comzones,doo+outzcom,doo+savein ;  2   zones in common
  0        ,out+extlist,doo+outext ,doo+savein ;  3   external list
  0  ,  doo+dataexi ,out+entryvalue,doo+outlist;  4   local entries
  0  ,  0           ,out+labvarinit,doo+outlist;  5   label var.list
;                                              ; h2+  declarations.
con+parzone,aux+saveset,aux+formal ,doo+savein ;  0   parameter zone
  0        ,  0        ,con+declare,out+locinit;  1   local  array
out+zoninit,doo+loczone,aux+declare,out+locinit;  2   local  zone
  0        ,  0        ,con+declare,out+cominit;  3   common array
  0        ,  0        ,con+declare,out+cominit;  4   common zone
  0        ,out+extzone,doo+copy1  ,doo+copy1  ;  5   external zone
;                                              ; h3+  parameter array.
doo+lower  ,out+rsw1a  ,aux+lowerix,aux+top1f  ;  0   adjustable lower
doo+upper  ,out+rsw1a  ,aux+byteix ,aux+top1f  ;  1   adjustable upper
  0        ,  0        ,con+arrbase,aux+arrinit;  2   initiate array
con+chforml,aux+byteix  ,doo+fixarr ,out+loadw1a;  3   fixedlimit array
                                   ixcheck1=k-1;         (the action is blind if index.no)
con+adjarr1,out+subw1a ,doo+upper  ,out+rlw1a  ;  4   adjustable array
                                   ixcheck2=k-1;         (the action is blind if index.no)
;                                              ; h4+  data.      
con+datafin,doo+topfree,doo+databyt,out+loadw1a;  0   data star
con+dataux2,doo+outcopy,out+rsw3   ,aux+dataux1;  1   data single
con+dataux2,doo+outcopy,out+xxback ,aux+dataux1;  2   data multiple
  0        ,  0        ,doo+topdown,doo+workdwn;  3   data array end

\f

;/action table 2



; action4  ,  action3  ,   kind    ,  action1  ;
;                                              ; h5+  operands.  
  0        ,doo+placeop, simlock   ,doo+opset  ;  0   local simple
  0        ,doo+simcop , simcomk   ,doo+opset  ;  1   common simple
  0        ,doo+placeop, simformk  ,doo+opset  ;  2   formal simple
doo+copyop ,doo+subcnop, subconk   ,doo+opset  ;  3   simple eq array
con+simeqz ,doo+simqz  , simlock   ,doo+opset  ;  4   simple eq zone
  0        ,doo+placeop, labvark   ,doo+opset  ;  5   label variable
  0        ,doo+placeop, simlock   ,doo+opset  ;  6   procedure name
doo+copyop ,doo+arrayop, arrayk    ,doo+opset  ;  7   array
  0        ,doo+arrqz  , arreqzk   ,doo+opset  ;  8   array eq zone
  0        ,doo+zoneop , zonek     ,doo+opset  ;  9   zone
  0        ,doo+placeop, externk   ,doo+opset  ; 10   external
  0        ,doo+placeop, extformk  ,doo+opset  ; 11   formal external
; 0        ,doo+statfop, statfunk  ,doo+opset  ;  -    statem.func
; 0        ,doo+statfop, simlock   ,doo+opset  ;  -    stat.func.form

;                      ,  action2  ,           ; h7+  end bytes. 
  0        ,  0        ,  0        ,doo+endstat;  0   end statement
  0        ,  0        ,out+newline,doo+endline;  1   end line
  0        ,  0        ,  0        ,doo+notimpl;  2   
  0        ,  0        ,  0        ,out+xxforw ;  3   end logical if
con+arifneg,doo+arif0  ,aux+gocond ,doo+arifpos;  4   end arith. if
  0        ,out+openfor,doo+copy1  ,doo+copy1  ;  5   open format
  0        ,out+closfor,doo+copy1  ,doo+copy1  ;  6   closed format
  0        ,  0        ,  0     ,out+entrypoint;  7   main entry
  0        ,  0        ,doo+data,out+dataentry ;  8   data entry
  0        ,  0        ,  0        ,out+xxforw ;  9   end formal decl
;                                              ; h8+  format.    
  0        ,out+begfor ,doo+copy1  ,doo+copy1  ;  0   format begin
  0        ,out+contfor,doo+copy1  ,doo+copy1  ;  1   format continue
;                                              ; h9+  parameters.
con+parform,doo+kindzon,out+loadw0a,doo+getaddr;  0   par zone
  0        ,con+parform,doo+zarsplt,doo+getaddr;  1   par zone array
;con+zinzar ,out+subw1a ,aux+zarform,doo+getaddr;  2   par zone indic (not used)
  0        ,  0        ,  0        ,doo+notimpl; (2   par zone indic not impl)
;                                              ; h10+ zone commas.
doo+towork2,aux+zcomma ,out+chupper,aux+top1f  ;  0   zone indic comma
out+zrechk ,doo+zelem  ,aux+zrbase ,aux+top1f  ;  1   zone subscript
;                                              ; h11+ parameterno.
doo+parno  ,doo+rescu01,doo+rescuuv,doo+rescudr;  0   parameter count
;                                              ; h12+ array range.
  0        ,  0        ,  0        ,doo+rangeop;  0   ranges
;                                              ; h13+ enter + exit.
  0        ,  0        ,doo+topdown,out+entry  ;  0   entry
  0        ,doo+retway ,doo+retexit,out+return ;  1   return
  0        ,out+gors   ,out+stop   ,aux+top1f  ;  2   stop
;                                              ; h14+ goto + labels.
con+asslab ,doo+outop ,out+prepjump,doo+topnext;  0   assign label
  0        ,  0        ,out+label  ,doo+copy1  ;  1   declare label
  0        ,doo+topdown,doo+outop  ,out+gosimpl;  2   goto label
  0        ,out+gors   ,out+gopoint,aux+top1f  ;  3   goto assigned
  0       ,out+complist,doo+compgo ,aux+top1f  ;  4   goto computed
;                                              ; h15+ logical ops.
out+relation,doo+relsign,doo+topreg,aux+relasub;  0   relation
  0        ,  0        ,out+xxforw ,doo+toplog ;  1   logpoint
\f


;/action table 3

; action4  ,  action3  ,  action2  ,  action1  ;
;                                              ; h16+ do.        
  0        ,  0        ,con+doloop ,aux+doinit ;  0   do general
  0        ,  0        ,  0        ,  0        ;  1   do special
  0        ,  0        ,con+dofirst,doo+rescu01;  2   do equal general
  0        ,  0        ,  0        ,  0        ;  3   do equal special
  0        ,  0        ,out+xxforw ,aux+doass  ;  4   do init general
doo+topnext,aux+doloop ,aux+doinit ,aux+doass  ;  5   do init special
  0        ,  0        ,  0        ,  0        ;  6   do until
con+dotest ,aux+domult ,aux+dostep ,doo+setint ;  7   do step
  0        ,out+xxforw ,out+gobackw,out+xxchang;  8   do terminate
;                                              ; h17+ read-write.
out+xxforw ,out+gors ,out+readinit ,aux+callout;  0   read  initiate
out+xxforw ,out+gors ,out+writeinit,aux+callout;  1   write initiate
out+xxforw ,out+gors ,out+readcall ,aux+callout;  2   read  call
out+xxforw ,out+gors ,out+writecall,aux+callout;  3   write call
;                                              ; h18+ implied do.
  0        ,  0        ,  0        ,con+doinit ;  0   implied begin
  0        ,  0        ,  0        ,con+doloop ;  1   implied do
;                                              ; h19+ trouble.   
  0        ,  0        ,  0        ,out+troubla;  0   trouble
  0        , simlock   ,doo+opset  ,out+troubla;  1   trouble operand
;                                              ; h20+ conversion.
con+itol   ,con+itolin7,doo+monocon,doo+typint ;  0   i conv  l
  0        ,  0        ,con+itor   ,doo+typint ;  1   i float r
  0        ,con+rtod   ,aux+itor   ,doo+typint ;  2   i float d
  0        ,con+rtoc   ,aux+itor   ,doo+typint ;  3   i float c
con+ltoi   ,con+ltoiin7,doo+monocon,doo+typ4   ;  4   l conv i
  0        ,  0        ,con+ltor   ,doo+typ4   ;  5   l float r
  0        ,  0        ,con+ltod   ,doo+typ4   ;  6   l float d
  0        ,con+rtoc   ,aux+ltor   ,doo+typ4   ;  7   l float c
  0        ,  0        ,con+rtoi   ,doo+typ4   ;  8   r trunc i
  0        ,  0        ,con+rtol   ,doo+typ4   ;  9   r trunc l
  0        ,  0        ,con+rtod   ,doo+typ4   ; 10   r conv  d
  0        ,  0        ,con+rtoc   ,doo+typ4   ; 11   r conv  c
  0        ,con+rtoi   ,aux+dtor   ,doo+typ8   ; 12   d trunc i
  0        ,  0        ,con+dtol   ,doo+typ8   ; 13   d trunc l
  0        ,  0        ,con+dtor   ,doo+typ8   ; 14   d trunc r
  0        ,con+rtoc   ,aux+dtor   ,doo+typ8   ; 15   d conv  c
  0        ,con+rtoi   ,aux+ctor   ,doo+typ8   ; 16   c trunc i
  0        ,con+rtol   ,aux+ctor   ,doo+typ8   ; 17   c trunc l
  0        ,  0        ,con+ctor   ,doo+typ8   ; 18   c conv  r
  0        ,con+rtod   ,aux+ctor   ,doo+typ8   ; 19   c conv  d
  0        ,doo+topup  ,doo+leave  ,doo+toplow ; 20   next
;                                              ; h29+ exponents.
con+xitor  ,doo+toplow ,doo+square ,doo+typint ;  0   integer**integer
con+rpowi  ,aux+sspower,doo+square ,doo+typ4   ;  1   real   **integer
con+power  ,out+lexpoi ,aux+sspower,doo+typ4   ;  2   long   **integer
con+xdexpod,aux+rtod   ,aux+itor   ,doo+typint ;  3   double **integer
con+power  ,out+rexpor ,aux+sspower,doo+typ4   ;  4   real   **real
  0        ,  0        ,con+xdexpod,doo+rescudr;  5   double **double
  0        ,con+xdexpod,aux+rtod   ,doo+typ4   ;  6   double **real
;                                              ; h30+ pass info. 
  0        ,  0        ,doo+outentr,doo+workset;  0   area simple
  0        ,  0        ,doo+copy3  ,doo+areas  ;  1   area

c. (:(:k-1-acttab:) a. 2.11:) - 1
m.*** formaterror main action table
z.

\f

;/ action table 4


typedep4 = k + 3 - acttab        ; byteindex of first type action
typedep  =  typedep4 > 2
typedepn = -(:(:typedep+7:)>3:)<3


; action4  ,  action3  ,  action2  ,  action1  ;  typedependant bytes.
;                                              ; h21+ data init. 
con+datanew,out+addw1a ,doo+outop  ,out+loadw1a;  0   data initiate
;                                              ; h22+ arithmetic.
  0        ,  0        ,  0        ,doo+notimpl;  0   monadic minus
doo+descres,doo+arithop,aux+topregf,doo+minus  ;  1   dyadic minus
doo+descres,doo+arithop,aux+topregf,doo+plus   ;  2   plus
doo+descres,doo+arithop,aux+topregf,doo+mult   ;  3   multiply
doo+descres,doo+arithop,aux+topregf,doo+divide ;  4   divide
;                                              ; h23+ logicals.  
  0        ,  0        ,doo+not    ,doo+topreg ;  0   not
doo+simres ,doo+mask   ,aux+topregf,doo+and    ;  1   and
doo+simres ,doo+mask   ,aux+topregf,doo+orsplit;  2   or
doo+simres ,doo+shift  ,aux+topregf,doo+topnext;  3   shift
;                                              ; h24+ assignments.
  0        ,doo+topfree,doo+store  ,aux+topregf;  0   assignment
  0        ,doo+topold ,doo+store  ,aux+topregf;  1   multiple assign
;                                              ; h25+ subscript. 
doo+asubscr,doo+outop  ,out+addw1a ,doo+indic  ;  0   indic
  0        ,con+zoneq1 ,out+addw1a ,doo+zqindex;  1   zone eq array
;                                              ; h26+
out+xxforw ,doo+callres,doo+call   ,aux+callout;  0   call
;                                              ; h27+ parameters.
con+parlab ,doo+outop ,out+prepjump,doo+simsplt;  0   par simple
doo+psubarr,out+subw1a ,aux+pardow2,doo+getaddr;  1   par subscr array
con+pararr ,aux+dopupp ,aux+doplow ,aux+rangpar;  2   par array
con+procfor,doo+parext ,doo+outop  ,doo+prcsplt;  3   par procedure
;                                              ; h28+ if.        
doo+ifarith,doo+topfree,doo+topreg ,doo+ifsplit;  0   if
;                                              ; h6+  constant.  
  0        ,doo+constop,  constk   ,doo+opset  ;  0
;                                              ; h31+ pararameter array. 
  0        ,doo+paramar,  arrayk   ,doo+opset  ;  0

dirmax = (:k+3 - acttab - typedep4:)<1 - typedepn
; maximal value for pass 6 directing bytes

c. (:(:k+3-acttab-typedep4:) a. 2.11:) - 1
m.*** formaterror typedependant action table
z.
\f


;/initiation of pass 7
w.
actstack = k + actlng - 2        ; action stack.
;                                ; 5 double word entries are;
;                                ; reserved for the action stack

opstack  = actstack + 5*actlng +2; operand stack.
;                                ; entries of oplength are placed in
;                                ; the operand stack

init7x:                          ; initiate pass 7.
;                                ; the code is overwritten by the
;                                ; action and operand stacks
          al w0    end7          ;
          am.     (endbyte.)     ;
          jl.w3    endbyte.      ; gpa:outbyte(end of pass 7)

          am.     (mode2.)       ;
          rl.w2    mode2.        ; w2 := gpa:more modebits for compilation
          rl.w0    cfw00.        ; w0 := simple convert real to integer;
          so w2    truncbit      ; if trunc.no then
          am.     (trcinit.)     ;
          rs.w0    trcinit.      ;   modify code;

          am.     (mode.)         ; set index check switch.
          rl.w2    mode.          ; w2 := gpa:modebits for compilation
          al w0    swindex-checkix; w0 := set switch to take index act
          so w2    chindex        ; if index.no
          al w0    curract-checkix;   then w0 := switch to current act
          am.     (ixcheck.)     ;
          hs.w0    ixcheck.       ; set index check switch

          al w0    doo+topfree   ; w0 := dummy action
          so w2    chindex       ; if index.no then
          rs.w0    ixcheck1.     ;   make no indexcheck with
          so w2    chindex       ;     formal- or actual arrays;
          rs.w0    ixcheck2.     ;

;                                ; prepare arithmetic interrupt.
          al w0   -1             ; interrupt bit1 := bit2 := 1
          so w2    spillbit      ; if spill.no
          ls w0   -2             ;   then bit1 := 0 ; bit2 := 1
          am.     (intinit.)     ;
          al.w3    intinit.      ; w3 := a:interrupt sequence
          jd       1<11 + 0      ; call monitor: set interrupt
;                                ;   only bit1 and bit2 of w0 is used
;                                ;   high precision set in pass 2
          am.     (mulinit.)     ;
          rl.w1    mulinit.      ; constant integer arithmetic instruction
          sh w0    0             ; if spill.yes
          am.     (mulsoft.)     ;
          rs.w1    mulsoft.      ;  then set software interrupt in mult
\f


;/initiation 2


;                                ; initiate pointers.
          al.w1    actstack.     ; w1 := a:action stack
          am.     (aastatop.)    ;
          rs.w1    aastatop.     ; action table top pointer
          al w1 x1-actlng        ; 
          am.     (aastabot.)    ;
          rs.w1    aastabot.     ; initiate action stack bottom
          al.w1    opstack.-oplength ; w1 := a:operand stack - oplength
          am.     (ooandbot.)    ;
          rs.w1    ooandbot.     ; operand stack bottom
          am.     (ooandtop.)    ;
          rs.w1    ooandtop.     ; operand stack top pointer
          am.     (last.)        ; lastword defined at end
          rl.w2    last.         ; w1 := a:last word to use
          al w2 x2-oplength      ;       - oplength
          am.     (ooandlim.)    ;
          rs.w2    ooandlim.     ; operand stack limit
          jl.      testinit.     ; goto get directing byte


endbyte:           outbyte.      ; distances used for far reaching
mode:              modebits.     ;
mode2:             modebit2.     ;
trcinit:           truncmod.     ;
cfw00:    cf w0    0             ; (simple conversion)
ixcheck:           checkix.+1    ;
intinit:           intrupt.      ;
mulinit:           mulspill.     ;
mulsoft:           mulset.       ;
aastabot:          acstabot.     ;
aastatop:          acstatop.     ;
ooandbot:          opandbot.     ;
ooandtop:          opandtop.     ;
ooandlim:          opandlim.     ;

last:              lastword.     ; distance to pass 0 lastword

length7 = k - start7             ; length of pass in bytes

e30 = e30 + length7 ; length := length + length pass 7;


; end of pass 7 instructions

i.
m. rc 83.08.29 fortran, pass 7
e.
▶EOF◀