|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 177920 (0x2b700) Types: TextFile Names: »D98«
└─⟦5dbd6b396⟧ Bits:30005867/disk12.imd Dokumenter (RCSL m.m.) └─⟦this⟧ »D98«
T_I_M_E_F_O_R_B_R_U_G_ SB 80.05.30 4.30 timer på rettelser. SB 80.06.02 5.30 timer på rettelser. SB 80.06.04 5.00 timer på rettelser. SB 80.06.05 4.00 timer på rettelser. SB 80.06.09 4.30 timer på rettelser. SB 80.06.10 4.30 timer på rettelser. SB 80.06.11 4.00 timer på rettelser. SB 80.06.13 5.00 timer på rettelser. SB 80.06.16 3.00 timer på rettelser. SB 80.06.17 0.30 timer på rettelser. SB 80.06.18 1.30 timer på rettelser. SB 80.06.23 6.00 timer på rettelser. SB 80.06.24 5.30 timer på rettelser. SB 80.07.14 4.00 timer på rettelser. SB 80.07.15 5.30 timer på rettelser. SB 80.07.16 5.30 timer på rettelser. SB 80.07.17 4.30 timer på rettelser. SB 80.07.18 3.00 timer på udskrift. SB 80.07.24 2.30 timer på rettelser og udskrift. SB 80.09.29 6.00 timer på rettelser SB 80.09.30 5.00 timer på rettelser. SB 80.09.01 7.50 timer på rettelser og udskrift. SB 80.10.06 5.30 timer på rettelser og udskrift. SB 80.10.09 3.30 timer på rettelser og udskrift. SB 80.10.14 4.00 timer på contents, rettelser og udskrift. SB 80.10.15 1.00 timer på udskrift. \f i F_O_R_E_W_O_R_D_ This manual contains the description of standard procedures, standard identifiers, operators, and delimiters in ALGOL8. The manual thus replaces the procedure descriptions in the fol- lowing manuals: RCSL No 31-D 322 ALGOL6 User>s Manual, section 9 55-D 66 Sorting in ALGOL5 31-D 393 Startsort6, Changekey6 31-D 72 Outdate, Movestring, Outchar, etc. 31-D 387 Write/writeint 31-D 408 Fpmode 31-D 581 ALGOL8 The manuals >Sorting in ALGOL5> and >ALGOL8>, however, still contain information which is not covered by any other manual. Edith Rosenberg A/S Regnecentralen af 1979, October 1980 \f ii \f iii T_A_B_L_E_ _O_F_ _C_O_N_T_E_N_T_S_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _P_A_G_E_ _ 1. INTRODUCTION .......................................... 1 2. PROCEDURE DESCRIPTIONS ................................ 3 2.1 abs ............................................. 3 2.2 activate ........................................ 4 2.3 activity ........................................ 7 2.4 add ............................................. 19 2.5 alarmcause ...................................... 21 2.6 algol ........................................... 22 2.7 and (and &) ..................................... 24 2.8 arcsin .......................................... 25 2.9 arctan .......................................... 26 2.10 arg ............................................. 27 2.11 array ........................................... 28 2.12 blockproc ....................................... 29 2.13 blocksout ....................................... 30 2.14 blocksread ...................................... 31 2.15 boolean ......................................... 33 2.16 bracket ......................................... 34 2.17 case ............................................ 36 2.18 changekey6 ...................................... 38 2.19 changerec ....................................... 39 2.20 changerec6 ...................................... 40 2.21 changevar ....................................... 43 2.22 character constant .............................. 49 2.23 check ........................................... 50 2.24 checkvar ........................................ 51 2.25 close ........................................... 53 2.26 closetrans ...................................... 55 2.27 comment ......................................... 56 2.28 comment string .................................. 57 2.29 context ......................................... 58 2.30 continue ........................................ 59 2.31 cos ............................................. 60 \f iv T_A_B_L_E_ _O_F_ _C_O_N_T_E_N_T_S_ _(_c_o_n_t_i_n_u_e_d_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _P_A_G_E_ _ 2.32 deadsort ........................................ 61 2.33 decimal point ................................... 63 2.34 disable ......................................... 64 2.35 divide (/) ...................................... 65 2.36 endaction ....................................... 66 2.37 entier .......................................... 67 2.38 equal (=) ....................................... 68 2.39 equivalent (==) ................................. 69 2.40 errorbits ....................................... 70 2.41 exit ............................................ 71 2.42 exor ............................................ 72 2.43 exp ............................................. 74 2.44 exponentiation (**) ............................. 75 2.45 extend .......................................... 77 2.46 external ........................................ 78 2.47 extract ......................................... 80 2.48 f8000table ...................................... 83 2.49 field ........................................... 84 2.50 fpmode .......................................... 85 2.51 getalarm ........................................ 86 2.52 getf8000tab ..................................... 88 2.53 getposition ..................................... 89 2.54 getshare ........................................ 91 2.55 getshare6 ....................................... 92 2.56 getstate ........................................ 95 2.57 getzone ......................................... 96 2.58 getzone6 ........................................ 97 2.59 goto ............................................ 105 2.60 greater than (') ................................ 106 2.61 greater than or equal ('=) ...................... 107 2.62 implication (=') ................................ 108 2.63 in .............................................. 109 \f v T_A_B_L_E_ _O_F_ _C_O_N_T_E_N_T_S_ _(_c_o_n_t_i_n_u_e_d_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _P_A_G_E_ _ 2.64 increase ........................................ 110 2.65 initkey ......................................... 111 2.66 initsort ........................................ 114 2.67 initzones ....................................... 115 2.68 inrec ........................................... 117 2.69 inrec6 .......................................... 119 2.70 intable ......................................... 123 2.71 integer ......................................... 127 2.72 integer divide (//) ............................. 128 2.73 invar ........................................... 129 2.74 isotable ........................................ 136 2.75 less than (<) ................................... 137 2.76 less than or equal (<=) ......................... 138 2.77 lifesort ........................................ 139 2.78 ln .............................................. 140 2.79 lock ............................................ 141 2.80 locked .......................................... 143 2.81 logand .......................................... 144 2.82 logor ........................................... 146 2.83 long (declarator) ............................... 147 2.84 long (operator) ................................. 148 2.85 message ......................................... 149 2.86 minus (-) ....................................... 150 2.87 mod ............................................. 152 2.88 monitor ......................................... 153 2.89 movestring ...................................... 186 2.90 multiply (*) .................................... 187 2.91 newactivity ..................................... 188 2.92 newsort ......................................... 194 2.93 not (-,) ........................................ 198 2.94 not equal (<') .................................. 199 \f vi T_A_B_L_E_ _O_F_ _C_O_N_T_E_N_T_S_ _(_c_o_n_t_i_n_u_e_d_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _P_A_G_E_ _ 2.95 open ............................................ 200 2.96 opentrans ....................................... 207 2.97 openvirtual ..................................... 209 2.98 or (and !) ...................................... 210 2.99 out ............................................. 211 2.100 outchar ......................................... 212 2.101 outdate ......................................... 213 2.102 outindex ........................................ 214 2.103 outinteger ...................................... 215 2.104 outrec .......................................... 217 2.105 outrec6 ......................................... 219 2.106 outsort ......................................... 221 2.107 outtable ........................................ 224 2.108 outtext ......................................... 225 2.109 outvar .......................................... 227 2.110 overflows ....................................... 229 2.111 own ............................................. 230 2.112 passivate ....................................... 232 2.113 plus (+) ........................................ 233 2.114 priority ........................................ 235 2.115 progmode ........................................ 236 2.116 random .......................................... 237 2.117 rc8000 .......................................... 238 2.118 read ............................................ 239 2.119 readall ......................................... 242 2.120 readchar ........................................ 249 2.121 readfield ....................................... 254 2.122 readstring ...................................... 256 2.123 real (declarator) ............................... 258 2.124 real (operator) ................................. 259 2.125 repeatchar ...................................... 261 2.126 replacechar ..................................... 262 2.127 resume .......................................... 264 2.128 round ........................................... 265 \f vii T_A_B_L_E_ _O_F_ _C_O_N_T_E_N_T_S_ _(_c_o_n_t_i_n_u_e_d_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _P_A_G_E_ _ 2.129 setfpmode ....................................... 266 2.130 setposition ..................................... 267 2.131 setshare ........................................ 272 2.132 setshare6 ....................................... 273 2.133 setstate ........................................ 275 2.134 setzone ......................................... 276 2.135 setzone6 ........................................ 277 2.136 sgn ............................................. 279 2.137 shift ........................................... 280 2.138 sign ............................................ 281 2.139 sin ............................................. 282 2.140 sinh ............................................ 283 2.141 sortcomp ........................................ 284 2.142 sqrt ............................................ 285 2.143 startsort6 ...................................... 286 2.144 stderror ........................................ 290 2.145 string (specificator) ........................... 291 2.146 string (operator) ............................... 292 2.147 swoprec ......................................... 294 2.148 swoprec6 ........................................ 295 2.149 system .......................................... 298 2.150 systime ......................................... 312 2.151 tableindex ...................................... 317 2.152 tofrom .......................................... 318 2.153 trap ............................................ 320 2.154 trapmode ........................................ 325 2.155 underflows ...................................... 326 2.156 value ........................................... 327 2.157 virtual ......................................... 328 \f viii T_A_B_L_E_ _O_F_ _C_O_N_T_E_N_T_S_ _(_c_o_n_t_i_n_u_e_d_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _P_A_G_E_ _ 2.158 w _activity ...................................... 329 2.159 waittrans ....................................... 332 2.160 write ........................................... 336 2.161 writefield ...................................... 346 2.162 writeint ........................................ 349 2.163 zone ............................................ 352 A_P_P_E_N_D_I_C_E_S_: A. REFERENCES ............................................. 355 B. SURVEY OF FORMAT8000 TRANSACTIONS ...................... 357 C. INDEX .................................................. 360 \f F_1_._ _ _ _ _ _ _ _ _I_N_T_R_O_D_U_C_T_I_O_N_ 1. This manual gives a detailed description of all the standard identifiers, standard procedures, operators, and a few other things supplied as a part of the compiler, and all the delimiters found in ALGOL8. The syntax of the operators and other delimiters is described rather informally. Take the description of >divide> as an example. Syntax : <operand1'/<operand2' Priority : 3 Operand types : integer, long, or real Result type : always real This shows that >divide> has two operands with type <' boolean. The result of applying >divide> to these two operands is always of type real. The priority of operators is listed in the descrip- tion of priority in this manual. The priority with value 1 is the highest. The description of procedures follows a different scheme. C_a_l_l_: inrec6(z,length) inrec6 (return value,integer). The ... z (call and return value,zone). The ... length (call value, integer, long, or real). The ... This shows that inrec6 is called with two parameters. The first, z, must be a zone. The contents of the zone at call time is sig- nificant and it is changed at return from the procedure. The se- cond, length, must be an integer, a long, or a real. The value of length at call time is significant. It is not changed at return. Finally, inrec6 is shown to have an integer value at return. \f The parameters may actually be expressions, of course. Unless something else is mentioned, it is a tacit assumption that all the parameters are evaluated once, but not necessarily in sequen- ce from left to right. Especially, if something is assigned to a parameter, the assign- ment may or may not be delayed until all the parameters have been evaluated (see for instance read). Note, that the evaluation of a string parameter will access the actual parameter repeatedly un- til the string end is supplied (cf. ref. 15). \f F_ 2_._ _ _ _ _ _ _ _ _P_R_O_C_E_D_U_R_E_ _D_E_S_C_R_I_P_T_I_O_N_S_ 2. 2_._1_ _ _ _ _ _ _ _a_b_s_ 2.1 abs This delimiter, which is a monadic arithmetic operator, yields the absolute value of the operand. S_y_n_t_a_x_: abs <operand' P_r_i_o_r_i_t_y_: 1 O_p_e_r_a_n_d_ _t_y_p_e_: integer, long, or real R_e_s_u_l_t_ _t_y_p_e_: The result is of the same type as <operand' S_e_m_a_n_t_i_c_: The absolute value of the argument is evaluated. E_x_a_m_p_l_e_ _1_: abs n if abs sin(x) <= 0.5 then ... j:= abs (0.5 + s/q) \f F_ 2_._2_ _ _ _ _ _ _ _a_c_t_i_v_a_t_e_ 2.2 activate This long standard procedure activates (restarts) a non-empty ac- tivity at its restart point. C_a_l_l_: activate (actno) activate (return value, long). The value is composed by two integers activityno shift 24 add cause describing the way in which activate returns (see below). actno (call value, integer). The identification of the activity to be activated. This activity must be n_o_n_-_e_m_p_t_y_. The value may be negative, in which case the activity identified by abs(actno) is "killed" rather than restarted (see 6, below). F_u_n_c_t_i_o_n_: The call: result:= activate (actno) proceeds as follows: 1) If the program is not in monitor mode or is not in activity mode the run is terminated with an alarm. 2) If actno = 0 or abs(actno) ' max _no _of _activities the run is terminated with an alarm. 3) If the program is in monitor mode and actno desig- nates an empty activity, the call returns with the result = actno shift 24 add (-1). If the program is in activity mode and actno designates an empty activity, the run is terminated with an alarm. \f 4) If the activity is virtual (see newactivity),activate and a shared virtual activity occupies the common stack area, waiting for an i/o trans- fer to be completed, the call returns with the result = shared _virtual shift 24 add (-2). 5) If the activity is virtual, and a shared vir- tual activity occupies the common stack area, n_o_t_ waiting for completion of an i/o trans- fer, the used part of the stack area is transferred to virtual store to stack area (swop). 6) If actno ' 0, the designated activity is ac- tivated (restarted) at its restart point. If the program is in activity mode (i.e. acti- vate is called from an activity), the acti- vate call at the same time defines a restart point for the calling activity, and when the calling activity later on is activated, the cause in result is defined to 3. If actno < 0, the absolute value of actno de- signates the activity; in this case the re- start is just the execution of an implicit run time alarm statement, with the text: "killed", and alarm _cause = extend 0 add (-15); the alarm statement is executed, as if it was the first statement a_t_ the restart point. R_e_s_u_l_t_ _v_a_l_u_e_s_: The return values activityno and cause have the following meaning: activityno: The identification of the activi- ty causing the return. In case of cause = -2, the activity waiting for an i/o operation to complete.\f cause indicates the return cause: activate -3: activate returned because of an alarm in a started activity, which is now empty. -2: activate returns, because the designated activity is virtual and shares storage with another activity waiting for an i/o operation to complete. -1: activate returns because the designated acti- vity is empty. 0: activate returns because a started activity terminated via its final end. This activitity is now empty. 1: activate returns because a started activity is passivated by a programmed passivate statement. 2: activate returns because a started activity is passivated by an implicit passivate statement in the zone i/o system. 3: activate is called in activity mode, defining a restart point - and calling activity is resumed. E_x_a_m_p_l_e_ _1_: see example 1 of activity. E_x_a_m_p_l_e_ _2_: see example 2 of newactivity. \f 2_._3_ _ _ _ _ _ _ _a_c_t_i_v_i_t_y_ 2.3 activity This standard procedure creates a number of activity descriptors defining empty activities. C_a_l_l_: activity (max _actno) max _actno (call value, integer). The number of activity descriptors to be created. The program must be in neutral mode, which is the de- fault mode of programs. The lexicographical enclosing block is now defined as the monitor block. When the program leaves this block, either by a goto statement or through its terminating end, the activity descrip- tors (and thereby the activities) are removed (includ- ing stop of pending zones), and the program mode re- turns to neutral mode. An activity is an entity, which permits procedures to act as coroutines, and is identified by a positive integer. Activities are operated by the following five procedures: - activity (n); creates n activity descriptors, defining n empty activities, now identified: 1, 2,...,n The mode is transferred from neutral mode to monitor mode. - newactivity (actno, virt, p,...); initializes the empty activi- ty actno, with the procedure p. The mode is transferred from mo- nitor mode to activity mode. - activate (actno); resumes the activity actno, at its restart point. The mode is transferred from monitor mode to activity mode, or is left unchanged in activity mode. \f - passivate; deactivates executing activity, establishing itsactivity restart point. The mode is transferred back to monitor mode. - w _activity (buf); waits for an event (message or answer) in the event queue (similar to call: monitor (24,...)), supplying the identification of the responsible activity. The mode is left un- changed in monitor mode. E_x_a_m_p_l_e_ _1_: A_ _c_o_r_o_u_t_i_n_e_ _s_y_s_t_e_m_. The following coroutine system runs controlled by the coroutine monitor described in ref. 21. The system reads input data from a number of format 8000 terminals (see ref. 17 and 18), and spools the data on current output. The system contains the following coroutines: P_r_o_c_e_d_u_r_e_ _i_n_p_u_t_l_i_n_k_: This coroutine has one semaphore (see ref. 21) >transinput> from which the next free buffer is waited for. Into this buffer is read the transaction head of the next format 8000 transaction from the zone >input> (by waittrans). The contents of the buffer is signalled to a semaphore >screen> depending on cu/dev (destination), the number of screen semaphores being the same as the number of screens. P_r_o_c_e_d_u_r_e_ _r_e_c_e_i_v_e_r_: This coroutine runs in one incarnation per screen, each having its own screen semaphore. Each incarnation of the procedure - receives a buffer from this screen semaphore, - copies it to a buffer from the semaphore >spool _pool>, - reads the rest of the input transaction to this buffer, and - signals it to the semaphore >spool>. When a receiver coroutine is started a screen mask is initialized (as shown in example 3 of writefield). P_r_o_c_e_d_u_r_e_ _s_p_o_o_l_e_r_: This coroutine has one semaphore >spool>, from which buffers are received. The contents of the buffer are printed on current output as an exact copy of the screen picture (incl. the mask). \f The system can be outlined in the following figure: activity 1 : transinput semaphore 2 : screen semaphores 3 : spool semaphore 4 : spool _pool semaphore. The coroutine monitor is described in details in ref. 21, here it is only sketched: begin <*coroutine monitor*' integer array sem (1:no _of _sem), buf (2:buf _arr _length), corout (2:4*maxactivity + 2); integer array field ready _q _first, ready _q _last, c _corout, data; integer field next, home _pool, operation, length, corout _no, incarn, bf; integer buf _base, buffer _addr, i, global _count, c _corout _no, sems _pr _incarn, buffer _head _length; real cputime, realtime; boolean finished; zone input (128,1, sense), output (128,1, stderror); \f <*the contents of the following procedures are listed inactivity ref.21*' integer procedure sem _to _field (semno, incarnation); integer procedure get _buf (bsize); procedure init _buffer _pool (semno, incarnation, nb, bsize); procedure init _corout _descr (actno, incarnation); procedure empty _sem(s); procedure signal (s,b); integer procedure wait (s); integer field s; begin <*passivates the coroutine until something arrives on the semaphore >s>*' integer array field i; if sem.s ' 0 then begin <*the semaphore is open, i.e. a buffer is ready*' corout.c _corout.bf:= sem.s; i:= sem.s; sem.s:= buf.i.next; end open else begin <*the semaphore is neutral or closed - hang the coroutine on the semaphore*' corout.c _corout.next:= 0; if sem.s = 0 then sem.s:= -c _corout <*neutral*' else begin <*closed*' i:= -sem.s; while corout.i.next <' 0 do i:= corout.i.next; corout.i.next:= c _corout; end closed; passivate; <*wait here*' end neutral or closed; wait:= corout.c _corout.bf; end wait; \f procedure sense _ready (z); activity zone z; begin getshare6 (z,ia1); ia(4):= 2;<*sense*' setshare6 (z,ia,1); repeat monitor (16<*send mess*', z, 1, ia) until monitor (18<*wait answ*', z, 1, ia) = 1 and ia(1) shift(-21)<*timer*' extract 1 = 0; end sense _ready; procedure sense (z,s,b); <***block proc for input***' zone z; integer s,b; begin if s extract 1 = 1 then stderror (z,s,b); if b = 0 then begin sense _ready (z); getshare6 (z, ia, 1); ia(4):= 3; <*input*' setshare6 (z, ia, 1); monitor (16<*send mess*', z, 1, ia); monitor (18<*wait answ*', z, 1, ia); b:= ia (2); end; end sense; procedure claim(i); integer i; begin integer array ii(1:i); end; <*coroutine and variable declarations*' algol copy.coroutdecl; <*initialize coroutine monitor*' . . . <*init field variables and clear arrays*' open (input,8,input _name, 1 shift 9 + 1 shift 1); monitor (8<*reserve process*',z,0,ia); open (output,14,output _name,0); \f activity (max _activity); activity <*initialize coroutines and semaphores*' algol copy.initcor; <*central logic of coroutine monitor*' finished:= false; repeat c _corout _no:= 0; if ready _q _first <' 0 then begin <*start the first coroutine in the ready queue*' - - - end else begin <*ready queue is empty, wait for an external event*' for i:= w _activity (buffer _addr) while i<0 do; if i=0 then begin <*message received, decode message*' - - - end else begin <*answer to a coroutine received*' c _corout _no:= i; c _corout := 8*c _corout _no - 8 + 2; end answer; end ready queue empty; if c _corout _no ' 0 then begin <*start the selected coroutine*' activate (c _corout _no); buffer _addr:= 0; end start coroutine; until finished; end program; \f F_ The coroutine declarations (in the file coroutdecl) look asactivity follows: integer array screen _semaphore (1:max _incarn+1); <******* coroutine *******' procedure spooler (spool, spool _pool); value spool, spool _pool; integer spool, spool _pool; <*semaphores*' begin integer array field bf; long array field text; integer field line; claim (400); <*reserve stack space for the activity, see newactivity*' repeat bf:= wait (spool); write (out, _ <:<10'<10' format::',buf.bf.data(1), _ <: dest::', buf.bf.data(2) shift(-12), _ buf.bf.data(2) extract 12, _ <: aid::', buf.bf.data(3), _ <: cursor::', buf.bf.data(4)); line:= text:= data + 10; while buf.bf.line '= 0 do begin write (out,<:<10'line:', <<dd', buf.bf.line, _ <: :', buf.bf.text); end lines; signal (spool _pool, bf); setposition (out,0,0); until false; end spooler; \f <******* coroutine *******' activity procedure receiver (transinput, screen, spool, spool _pool); value transinput, screen, spool, spool _pool); integer transinput, screen, spool, spool _pool); begin integer array field trans, bf; integer i, aid, dest; claim(400); trans:= wait (screen); dest:= buf.trans.data(2); set _mask (dest); <*set up a screen mask, see ex. 3 of writefield*' signal (transinput, trans); repeat bf := wait (spool _pool); trans:= wait (screen); aid := buf.trans.data(3); for i:= 1 step 1 until 4 do buf.bf.data(i):= buf.trans.data(i); if aid = 1 <*send*' then get _input _data (buf.bf.data); opentrans (output, 3, dest, 63 <*erase unprotected*', 3); closetrans (output); signal (transinput, trans); signal (spool, bf); until aid = 17 <*clear*'; finished:= true; end receiver; \f <******* coroutine *******' activity procedure input _link (transinput, screen); value transinput; integer transinput; integer array screen; begin integer array field trans; integer screen _no; claim (300); sense _ready (input); repeat trans:= wait (transinput); waittrans (input, _ buf.trans.data(1), <*format*' _ buf.trans.data(2), <*dest *' _ buf.trans.data(3), <*aid *' _ buf.trans.data(4)); <*cursor*' screen _no:= buf.trans.data(2) extract 12 + 1; signal (screen(screen _no), trans); until false; end input _link; procedure set _mask (dest); <*see ex. 3 of writefield*' value dest; integer dest; begin integer line; opentrans (output,3,dest, 49, 3); for line:= 0 step 1 until 23 do begin writefield (output, 1, line*80); writefield (output, 2, 1 shift 5); write (output, <:line:', <<dd', line); writefield (output, 2, 0); if line=0 then writefield (output, 3, 0); writefield (output, 6, >sp> shift 12 + line*80 + 79); end; closetrans (output); end setmask; \f procedure get _input _data (datapart); activity integer array datapart); begin integer field line; array field text; integer type, addr; line:= text:= 10; while read _field (input, type, addr) = 8 do begin datapart.line:= addr//80; readstring (input, datapart.text, 1); line:= text:= line+50; end; datapart.line:= -1; end get _input _data; \f The initialization of coroutines and semaphores (in the fileactivity initcor) is: sems _pr _incarn:= 1; for inc:= 0 step 1 until max _incarn do init _buffer _pool (1, <*screen semaphore*' inc, <*incarnation*' 0,0); <*no.of buffers, buf.size*' inc:= max _incarn + 1; init _buffer _pool (1, <*transinput semaphore*' inc, <*incarnation*' 1,4); <*no.of buffers, buf.size*' init _buffer _pool (2, <*spool semaphore*', inc, <*incarnation*' 0,0); <*no.of buffers ,bufzise*' init _buffer _pool (3, <*spool pool semaphore*' inc, <*incarnation*' 4,800); <*no.of buffers, bufsize*' \f <*start the activities*' activity for inc:= 0 step 1 until max _incarn do begin init _corout _descr (inc+1, inc); new _activity (inc+1, 0, receiver, _ sem _to _field (1, max _incarn+1), _ sem _to _field (1, inc ), _ sem _to _field (2, max _incarn+1), _ sem _to _field (3, max _incarn+1)); end; inc:= max _incarn+1; init _corout _descr (max _incarn+2, 0); new _activity (max _incarn+2, 0, spooler, _ sem _to _field (2, inc), _ sem _to _field (3, inc)); for inc:= 0 step 1 until max _incarn do screen _semaphore (inc+1):= sem _to _field (1,inc); inc:= max _incarn+1; init _corout _descr (max _incarn+3,0); new _activity (max _incarn+3, 0, input _link, _ sem _to _field (1, inc), _ screen _semaphore); \f F_ 2_._4_ _ _ _ _ _ _ _a_d_d_ 2.4 add This delimiter, which is a pattern operator, is used for packing of integer values into a real, long, integer, boolean, or string value. S_y_n_t_a_x_: <operand1' add <operand2' P_r_i_o_r_i_t_y_: 2 O_p_e_r_a_n_d_ _t_y_p_e_s_: <operand1': boolean, integer, long, real, or string. <operand2': integer, long, or real. R_e_s_u_l_t_ _t_y_p_e_: The result is of the same type as <operand1'. S_e_m_a_n_t_i_c_: If <operand2' is real or long it is rounded to an integer. Now both operands are treated as binary patterns and the right hand integer is added to <operand1' to obtain the binary pattern of the result. If the result is a boolean, it is cut to 12 bits. The addition is binary addition in 24 bits with rightmost bit added to rightmost bit. E_x_a_m_p_l_e_ _1_: Let i and j be integers between 0 and 63. They may be packed into one boolean variable in this way: b:= false add i shift 6 add j; if j were negative, the statement would not work as intended. E_x_a_m_p_l_e_ _2_: Two signed integers may be packed into one real in this way: r:= 0.0 shift 24 add i1 shift 24 add i2; or: r:= real (extend i1 shift 24 add i2); \f Note that the binary pattern of a negative numberadd has zeroes in front of the 24 ordinary bits. E_x_a_m_p_l_e_ _3_: The last bit of an integer >j> may be tested in this way: if false add j then ... \f F_ 2_._5_ _ _ _ _ _ _ _a_l_a_r_m_c_a_u_s_e_ 2.5 alarmcause This long standard identifier contains the cause of a suppressed program break down. The value of alarmcause is interpreted as two integers: param:= alarmcause shift (-24) cause:= alarmcause extract 24 where param is the integer output by the normal error message (see ref. 15) and cause is the errortype (e.g. the error message index 100 corresponds to param = 100 and cause = -2). The value of cause means: -15 killed activity -14 goto alarm -13 trap alarm -12 field alarm -11 give up from stderror (algol check) -10 end program (normal program termination) -9 break -8 param error -7 real overflow -6 integer overflow -5 syntax error -4 case alarm -3 zone index error -2 index alarm -1 stack alarm '=0 other alarms (e.g. sqrt, ln etc.) E_x_a_m_p_l_e_ _1_: Alarmcause can be used to check why a traproutine is called (see example 2 in trap). E_x_a_m_p_l_e_ _2_: See example 1 of getalarm. \f F_ 2_._6_ _ _ _ _ _ _ _a_l_g_o_l_ 2.6 algol This delimiter, which is a compiler directive, is used to call specific actions of the compiler. M_ 1 1 S_y_n_t_a_x_: algol <modifier' copy.<source' ; P_ 0 0 M_ list.on <modifier'::= P_ list.off M_ <name' <source'::= P_ <integer' Only allowed after the delimiters begin or ; (semicolon) S_e_m_a_n_t_i_c_: The modifiers list.on and list.off may be used to di- rect whether or not subsequent parts of the program should be listed during compilation. The effect of the list-modifier may be overruled by use of the list-modi- fiers of the FP-command calling the compiler (cf. ref 15). The modifier copy.<source' make it possible to copy the specified <source' into the main source text. The co- pying will take place when the delimiter is met. E_x_a_m_p_l_e_ _1_: algol list.on; <*change to listing.yes*' E_x_a_m_p_l_e_ _2_: algol list.off; <*change to listing.no*' E_x_a_m_p_l_e_ _3_: algol list.off copy.text; <*copy text with listing.no. The listing modifier is only valid for text*' \f E_x_a_m_p_l_e_ _4_: algol copy.t;<*copy t, listing as stated in thealgol call of the compiler*' E_x_a_m_p_l_e_ _5_: algol copy.2;<*in case the call of the compiler specifies the parameter: copy.text2.text3 as the first >copy> parameters, text3 is copied. A possible listing modifier in front of copy.2 will be blind (is overruled by the listmodifiers in the call of the compiler*' E_x_a_m_p_l_e_ _6_: See example 1 of activity. \f F_ 2_._7_ _ _ _ _ _ _ _a_n_d_ _(_a_n_d_ _&_)_ 2.7 and This delimiter, which is a logical operator, yields the logical and (logical product) of the two operands. M_ and S_y_n_t_a_x_: <operand1' <operand2' P_ & P_r_i_o_r_i_t_y_: 7 O_p_e_r_a_n_d_ _t_y_p_e_s_: boolean. R_e_s_u_l_t_ _t_y_p_e_: boolean. S_e_m_a_n_t_i_c_: The logical product of the operands is evaluated. This logical product is performed bit by bit in parallel on the twelve bits of the two operands. The truth value of the result pattern, when used in repetitive or conditional statements, is deter- mined by the last (rightmost) bit in the pattern (0 = false, 1 = true). E_x_a_m_p_l_e_ _1_: Set the last 3 bits of a boolean. a:= b and (false add 7); E_x_a_m_p_l_e_ _2_: if a and b then .... else .... \f F_2_._8_ _ _ _ _ _ _ _a_r_c_s_i_n_ 2.8 arcsin This real standard procedure performs the mathematical function arcsine (i.e. the inverse of the trigonometric function sine). C_a_l_l_: arcsin (r) arcsin (return value, real). Is the mathematical function arcsine of the argument r, in radians with - /2 <= arcsin <= /2 = 3.14159 26536. r (call value, real, long, or integer) Must be in the interval: -1 <= r <= 1. A_c_c_u_r_a_c_y_: r = 1, -1 gives an absolute error of 3>-12 r = 0 gives arcsin= 0 0 < abs r <0.5 gives a relative error below 1.1>-10 0.5 <= abs r < 1 gives a relative error below 1.6>-10 E_x_a_m_p_l_e_ _1_: The sides of a triangle are a, b, c. The angle A (opposite a) can be calculated by: pi := 2*arcsin(1); s := (a+b+c)/2; A := 2*arcsin(sqrt((s-b)*(s-c)/(b*c))); if A <0 then A := A + pi; If A is wanted in degrees then A := A*180/pi; \f F_ 2_._9_ _ _ _ _ _ _ _a_r_c_t_a_n_ 2.9 arctan This real standard procedure performs the mathematical function arctangent (i.e. the inverse of the trigonometric function tangent). C_a_l_l_: arctan (r) arctan (return value, real). Is the mathematical function arctangent of the argument r in radians with - /2 <= arctan <= /2. r (call value, real, long, or integer) in radians. A_c_c_u_r_a_c_y_: r = 0 gives arctan = 0 r <' 0 gives a relative error below 1.5>-10 When inserting into formulae containing a term like arctan (b/a) where a may be zero, the function arg (a,b) may be a better choice as it behaves sensible for a=0. \f F_ 2_._1_0_ _ _ _ _ _ _a_r_g_ 2.10 arg This real standard procedure performs the mathematical function of calculating the argument (also called angle) of a complex num- ber from its cartesian coordinates. C_a_l_l_: arg (u, v) arg (return value, real). Is the argu- ment in radians of the complex num- ber u+i*v with - < arg < . If u < 0 and v = 0, arg is positive. u (call value, real, long, or integer). v (call value, real, long, or integer). A_c_c_u_r_a_c_y_: v=0 and u '= 0 gives arg = 0. v<'0 or u < 0 gives a relative error below 1.8>-10. E_x_a_m_p_l_e_ _1_: The coordinates of the complex number a + i*b can be transformed from cartesian format (a,b) to polar format (modulus r, argument q) by: r:= sqrt (a*a + b*b); q:= arg (a,b); E_x_a_m_p_l_e_ _2_: Let a and b be the lengths of two sides of a tri- angle, and let C be the angle between them (in radians). The angle B, opposite to b, is then com- puted by: B:= arg(a-b*cos(C),b*sin(C)); \f F_ 2_._1_1_ _ _ _ _ _ _a_r_r_a_y_ 2.11 array This delimiter, which is a declarator, is used to declare arrays and to specify the kinds and types of formal parameters in procedures. S_y_n_t_a_x_: <type' array <array list' <type' array <identifier list' S_e_m_a_n_t_i_c_: In the first description one or more array segments of the appropriate type (i.e. real, long, integer, or boolean) is declared. The next description speci- fies that the formal parameters mentioned in the identifier list are arrays of the appropriate type. <type' may be omitted, then real arrays are declared or specified. If more than one array identifier appears in an array segment, the compiler will describe the loca- tions (the base words) for the different arrays separately, but the description of the bounds (the dope vector) is shared by all the arrays of the ar- ray segment. The elements of an array are stored densely in lexicographical order. A multidimensional array may be used as actual parameter where the corresponding formal is used as one dimensional. In this case the mapping used is given by the lexicographical ordering of the elements. E_x_a_m_p_l_e_ _1_: Declaration: integer array A, B(1:100),x(0:2); array C(1:10), D(-15:17, 1:10); Specification: real array K,L,M; \f F_ 2_._1_2_ _ _ _ _ _ _b_l_o_c_k_p_r_o_c_ 2.12 blockproc This standard procedure performs the call of a blockprocedure associated with a given zone. Blockproc makes it possible in pure algol to obtain an effect like check (used by inrec, read, write, etc.), which only knows the zone, but still manages to call the block procedure (cf. ref. 15). C_a_l_l_: blockproc (z, s, b) z (call and return value, zone). Specifies the procedure to be called. The proce- dure to be called is the blockprocedure connected to the zone z. s (call and return value, integer). The value of s is supposed to be a logical status word. b (call and return value, integer). The value of b is supposed to be the number of halfwords in a block transfer. Let pr be the block procedure of z. Then the fol- lowing call will be executed: pr(z,s,b) E_x_a_m_p_l_e_ _1_: See example 2 of swoprec6. \f F_ 2_._1_3_ _ _ _ _ _ _b_l_o_c_k_s_o_u_t_ 2.13 blocksout This integer standard identifier is increased by one each time a segment of the virtual storage (context data) is transferred to the backing storage. The initial setting is zero. \f F_ 2_._1_4_ _ _ _ _ _ _b_l_o_c_k_s_r_e_a_d_ 2.14 blocksread This integer standard identifier is increased by one each time a segment of the algol program is transferred from the backing sto- rage. This enables you to estimate the length of the program loops and balance the use of the core store. The value of blocks- read is printed at program end (cf. ref 15). E_x_a_m_p_l_e_ _1_: If you feel that your program is running very slowly, the first thing to do is to insert a piece of code around the inner loop: blocksread:= 0; The inner loop; write(out,blocksread//55); The number printed is then the number of seconds spent in transferring program segments from disc to the core store. If this explains the trouble, you could e.g.: 1) change the program so that fewer variables are declared, or 2) run the job in a greater core area, or 3) lock the segments of the inner loop in the core. In this example the integer printed after the end message is not the total number of segment trans- fers during the run, but it shows the number of transfers since the latest time blocksread was set to 0. E_x_a_m_p_l_e_ _2_: In many cases a program can run with an array of varying length. One example is the first phase of a magnetic tape sorting. Here you save tape passes in the second phase by increasing the array avail- able for the first phase. But if you increase too much, the first phase will become very slow because of frequent program transfers. \f The following program shows how this can beblocksread balanced by the algorithm itself. The idea is to reserve an array of maximum size (see system) and then decrease the length of the array whenever segments are transferred in the inner loop. n:= max; repeat begin array ra (1:n); s:= blocksread; The inner loop; if blocksread ' s then n:= n-128; <*make room for one more program segment*' end; until sorted; It is more difficult to do the same thing starting by a short array. \f F_ 2_._1_5_ _ _ _ _ _ _b_o_o_l_e_a_n_ 2.15 boolean This delimiter, which is a declarator, is used in declarations and specifications of variables of type boolean. S_y_n_t_a_x_: boolean <namelist' S_e_m_a_n_t_i_c_: The variables in namelist will all be of type boolean and comprises 12 bits in the storage area. E_x_a_m_p_l_e_ _1_: boolean b1; boolean yes, no, r; procedure truth (c); boolean c; \f F_2_._1_6_ _ _ _ _ _ _b_r_a_c_k_e_t_ 2.16 bracket These delimiters, which are brackets, are used to separate special items. S_y_n_t_a_x_: ( <expression ' ) is an expression or a subscript ( <parameter list ' ) is a parameter part ( <expression list ' ) is an expression or subscript begin <statements' end is a statement <: <text not containing "<:" or ":'"' :' is a string ><character name'> is an integer character constant "<character name'" is a boolean character constant < <unsigned integer or integer character constant' ' is a character << <layout' ' is a layout string <* <text not containing "<*" or "*'*"' *' is a comment string \f E_x_a_m_p_l_e_s_: (a + c/(a+b)) bracket (a,b, v+3) (a+b, c, n+k/l) begin a:= a+b; i:= i+1 end <:bsarea:' <:<10' data error:' "nl" >em> <<-ddd.dd' \f F_ 2_._1_7_ _ _ _ _ _ _c_a_s_e_ 2.17 case This delimiter, which is a sequential operator, occurs in case- expressions and case-statements, which are generalisations of if-expressions and if-statements. The case-constructions use an integer to select among several expressions or statements. S_y_n_t_a_x_: case <operand' of begin <statement list' end is a case-statement case <operand' of ( <expression list' ) is a case-expression A case-statement or a case-expression has the same syntactical position as an if-statement or an if- expression. O_p_e_r_a_n_d_ _t_y_p_e_s_: <operand' must be of type integer, long, or real. The elements of a statement list are separated by semicolons and numbered 1, 2, 3,... The elements of an expression list must either be all arithmetic, all boolean, all string, or all designational. The expressions are separated by commas and numbered 1, 2, 3, ... R_e_s_u_l_t_ _t_y_p_e_: If the elements in an expression list are arithme- tic, the type of the resulting value will be: integer if all elements are integer long if one or more elements are long, but none real real if one or more elements are real. When the elements of the expression list are of type boolean, string, or designational the result- ing value will be of the same type. \f S_e_m_a_n_t_i_c_: A case-construction is executed as follows: First,case evaluate the arithmetic expression and if necess- ary round it to an integer. Next, select the list element corresponding to the result. If no such list element exists, the run is terminated. If the selected element is a statement, execute it and continue the execution after the complete case- statement (provided that a goto was not executed). If the selected element is an expression, evaluate it and take the result as the value of the case- expression. E_x_a_m_p_l_e_ _1_: Initializing a table. An array may be initialized with the values 3, 5, 0, 1, 1, 2 in this way: for i:= 1 step 1 until 6 do ia(i):= case i of (3,5,0,1,1,2); E_x_a_m_p_l_e_ _2_: The logical status word occuring as a parameter to block procedures may be displayed in this way: for i:= 0 step 1 until 23 do if logical _status shift (-i) extract 1 = 1 then write(out,case 24-i of (<:local:',<:parity:',<:timer:', ...)); E_x_a_m_p_l_e_ _3_: See example 2 of readchar. \f F_ 2_._1_8_ _ _ _ _ _ _c_h_a_n_g_e_k_e_y_6_ 2.18 changekey6 This integer standard procedure makes it possible to change the key code generated by startsort6. The new generated key code must not be longer than the key code in the initial call of startsort6. C_a_l_l_: changekey6 (z, keydescr, noofkeys) changekey6 (return value, integer). The number of records which reasonably may be placed in the zone. keydescr (call value, integer array). Holds in- formation about types and relative lo- cations of the key fields as described for startsort6. noofkeys (call value, integer). The number of significant rows in keydescr. The note on the value of startsort6 is also valid for changekey6. Z_o_n_e_ _s_t_a_t_e_: The zone must be initiated by startsort6 (state 9, in sort), and all records in the zone must be inactive. The procedure must not be called in connection with initsort and initkey. \f F_ 2_._1_9_ _ _ _ _ _ _c_h_a_n_g_e_r_e_c_ 2.19 changerec This integer standard procedure regrets the latest call of inrec, outrec, or swoprec and makes a record of a new size available. The procedure is the A_L_G_O_L_5_ version of changerec6. C_a_l_l_: changerec (z, length) changerec (return value, integer). The number of elements of 4 halfwords each left in the present block for further calls of inrec, outrec or swoprec. z (call and return value, zone). The name of the record. length (call value, integer, long or real). The number of elements of 4 halfwords each in the new record. Length must be '= 0. For further details see changerec6. \f F_ 2_._2_0_ _ _ _ _ _ _c_h_a_n_g_e_r_e_c_6_ 2.20 changerec6 This integer standard procedure regrets the latest call of inrec6, outrec6, or swoprec6 and makes a record of a new size available. C_a_l_l_: changerec6 (z, length) changerec6 (return value, integer). The number of halfwords left in the present block for further calls of inrec6, outrec6 or swoprec6. z (call and return value, zone). The name of the record. length (call value, integer, long or real). The number of halfwords in the new record. Length must be '= 0. If length is odd, one is added. Z_o_n_e_ _s_t_a_t_e_: The zone must be in one of the states 5, 6 or 7, i.e. after record input, after record output, or after record swop (see getzone6), and it is left in the same state. B_l_o_c_k_i_n_g_: Changerec6 can be used to regret a former call of the procedures for record handling. This happens in the following way: 1) Check that 5 <= zone state <= 7. Set the record length to 0 (zero) and the logical position just before the record base. 2) Start the record procedure indicated by the zone state with the same parameters as changerec6. I.e. if zonestate = after record input then inrec6 (z,length) else if zone state = after record output then outrec6(z,length) else swoprec6(z,length). \f The terms zone state, record length, and recordchangerec6 base are explained in getzone6. If there is room in the current block for the new record size, a call of changerec6 will not change block. In this case data in elements available both before and after the call are unchanged. If you are not aware of the rest length in the used share, you must be prepared for a block change if the length in the call of changerec6 is greater than that of the previous call of a record procedure. The blocking is explained in more detail in inrec6, outrec6, and swoprec6. E_x_a_m_p_l_e_ _1_: Output of records with variable length. Records with variable length, where the length is stored in the first word (2 halfwords), may be output like this: repeat outrec6(z,maxlength); ....; Fill the buffer and compute the actual length. z.firstword:= actuallength; changerec6(z,actuallength); until...; Compare this with example 1 of outrec6, where the actual length is known before the call of outrec6. E_x_a_m_p_l_e_ _2_: See example 2 of invar. E_x_a_m_p_l_e_ _3_: In a zone with one share the last of a series of output records may be forced onto the document without using setposition or close: \f begin zone z (buflength, 1, stderror); changerec6 open (z, ...); ... repeat produce records be means of outrec6 ... outrec6 (z, buflength * 4); <*this big dummy record will force the last record onto the document*' changerec6 (z,0); <*regret the dummy record*' getposition (z, file, block); <*file and block must be saved in some status area*' until ... This can be useful in an online program for making an easy restart after a possible program break down. \f F_ 2_._2_1_ _ _ _ _ _ _c_h_a_n_g_e_v_a_r_ 2.21 changevar This integer standard procedure is used in connection with outvar, as it replaces a record placed in the zone z by means of outvar with another, maybe of a new length. The call changevar(z,z) always works so that indices available both before and after the call refer to the same piece of data - even though a block change may have happened. C_a_l_l_: changevar (z, a) changevar (return value, integer). The number of halfwords available for further calls of outvar before change in block takes place exactly as for outrec6. z (call and return value, zone). The zone used for output. a (call value, real array). An array con- taining the record to replace the cur- rent zone record. The first word of the element with lexicographical index 1 must contain the new record length in halfwords. If it is odd, 1 is added. Z_o_n_e_ _s_t_a_t_e_: The zone state must be after record output (state 6, see getzone6), and the latest record may have been placed by means of outrec6, outvar or the like. B_l_o_c_k_i_n_g_: Changevar tests whether the next record may reside within the current block, and changes the block if this is not the case. The old record is not out- put. The call changevar(z,z) gets a special treat- ment, as the second parameter will be saved if it cannot reside in the zone buffer while the block is changed. The blocking and the function is ex- plained in more detail in outvar. \f R_e_c_o_r_d_ _F_o_r_m_a_t_,_ _c_o_u_n_t_i_n_g_ _o_f_ _r_e_c_o_r_d_s_: changevar The record format is explained in outvar. The free zone parameter (see getzone6) is decreased by one if the new length is 0 (zero). Otherwise it is not changed. E_x_a_m_p_l_e_ _1_: S_e_q_u_e_n_t_i_a_l_ _f_i_l_e_ _u_p_d_a_t_i_n_g_ _b_y_ _m_e_r_g_i_n_g_ Certain systems maintain their master files by merging an old master file with a transaction file giving a new master file. We assume that the files are sorted in ascending order with respect to a key field, that the files end with an end-record with the key equal to the maximum value for longs, and that the records are var-records. The following algorithm allows several transac- tions to the same master record. It also allows transactions to a new master record, supposed that the new record precedes the transaction record. Old record with same key as the previous is treated as a serious error. The algorithm can easily be extended to more than 3 files. begin comment merging algorithm; zone old, trans, new(..., ..., stderror); integer action, creation, removal, changes, guessed _len; long first, infinity; integer field length, type; long field key; length:=2; ... infinity:= extend(-1) shift (-1); ... <* The initialization of the type identifications \f >creation>, >removal>, and >changes> as well aschangevar the field variables >key> and >type> depend on the record format. The initialization of >infinity> assumes that the key is ' 0. The value of >guessed _len> may lie between the minimum length and the maximum length of the record. If it is the minimum length, blockchanges are postponed as long as possible, and if it is the maximum length, intermediate savings during changevar are avoided*' open (old, ..... ); open (trans, ..... ); open (new, ..... ); <*maybe also setposition on the documents*' invar (old); invar (trans); outrec6 (new, guessed _len); new.length:= guessed _len; new.key:= inifinity; <*The following code determines an action number which may be thought of as a binary number 1 <= action <= 7, where 1 means new contains the lowest key, 2 means trans contains the lowest key, 4 means old contains the lowest key. More than one key can be lowest, e.g. 6 means trans and old lowest*' action:= 0; while action <' 7 do begin <*old trans new*' action:= 7; <* 1 1 1 *' if old.key ' trans.key or old.key ' new.key then action:= action - 4; <* 0 1 1 *' if trans.key ' old.key or trans.key ' new.key then action:= action - 2; <* . 0 . *' if new.key ' old.key or new.key ' trans.key then action:= action - 1; <* . . 0 *' \f case action of changevar begin <*1. (001) new.key smallest, output the ready record*' begin outrec6 (new, quessed _len); new.key:= infinity; new.length:= guessed _len; end 1; <*2. (010) trans.key smallest, the transaction should be a creation*' begin if trans.type <' creation then error (1) else begin trans.type:= ...; <*perform necessary changes in trans*' changevar (new, trans); end; invar (trans); end 2; <*3. (011) trans.key and new.key smallest, the transaction must be a removal or change*' begin if trans.type = creation then error (2) else if trans.type = removal then new.key:= infinity else begin <*change*' ... <*perform changes in new, perhaps make: new.length:= new _len; changevar (new,new);*' ... checkvar (new); end; invar (trans); end 3; \f <*4. (100) old.key smallest, changevar no transaction to this record*' begin changevar (new, old); invar (old); end 4; <*5. (101) old.key and new.key smallest, two old records with the same key This is a serious error*' begin alarm (1); end 5; <*6. (110) old.key and trans.key smallest, let the transaction wait until we have been through the logic once more*' begin changevar (new, old); invar (old); end 6; <*7. (111) all keys are >smallest>, if all three keys are equal to infinity, we have finished, else serious error: two records with same key*' begin if old.key <' infinity then begin error(3); invar (old); action:= 0; <*avoid leaving the loop*' end; end 7; end case action; end merge loop, while action <' 7; \f <*At merge end put a correct end record into new, maybechangevar check the end records of old trans, close the zones properly*' If the number of transactions is not small compared with the number of records in old, the checkvar-call concluding action 3 should be moved so that it is per- formed just prior to the outrec-call in action 1. Note that in this algorithm the number of new records is not counted in the free zone parameter (see getzone6), as outvar is never called. \f F_ 2_._2_2_ _ _ _ _ _ _c_h_a_r_a_c_t_e_r_ _c_o_n_s_t_a_n_t_ 2.22 char This string may be used instead of an integer constant or a boolean constant. S_y_n_t_a_x_: ><character name'> is an integer constant "<character name'" is a boolean constant S_e_m_a_n_t_i_c_: All ISO character values, listed in the character set table in ref. 14, may be written directly in the program text. <character name' is the mne- monics shown in column G in the character table; the mnemonics corresponding to the ISO values 0:32 and 127 must be written with small letters. The mnemonics are translated to the corresponding ISO values, as if these constants were written directly: ><mnemonic'> <=' <digits in ISO value' "<mnemonic'" <=' false add <digits in ISO value' E_x_a_m_p_l_e_ _1_: The following statements and expressions are identical two by two: if char = >ext> then ... if char = 3 then ... write (out, "sp", 3); write (out, false add 32, 3); <:a>y>x"nl"<>p>':' <:a>y>x"nl"<112':' alpha (>x>):= >x> + 6 shift 12; alpha (120):= 120 + 6 shift 12; \f 2_._2_3_ _ _ _ _ _ _c_h_e_c_k_ 2.23 check This standard procedure waits for and checks an answer from a transfer in exactly the same way as high level zone procedures check their transfers. C_a_l_l_: check (z) z (call and return value, zone). The ope- ration given in used share of z (see getzone6) is waited for and checked. The algorithm is given in ref 15, 2.4.4 wait transfer. Ref. 15 also describes the standard error reactions. \f F_ 2_._2_4_ _ _ _ _ _ _c_h_e_c_k_v_a_r_ 2.24 checkvar This integer standard procedure calculates the record checksum of a record with the format of a variable length record as generated by outvar. The checksum is stored in the second word of the record. The procedure is intended for use in the very special cases where the checksum is destroyed or becomes invalid or where a checksum is needed later on. C_a_l_l_: checkvar (z) checkvar (return value, integer). The checksum which was stored in the record before the call of checkvar. z (call and return value, zone). Specifies the record for which the checksum must be calculated, and where it is stored. Z_o_n_e_ _s_t_a_t_e_: The record length given in the first word of the record must be greater than or equal to 4 and equal to the record length of the zone descriptor (see getzone6). The zone state is irrelevant and unchanged. No transfer is initiated by checkvar. E_x_a_m_p_l_e_ _1_: Simulating an end-record. An end record may be generated in the block procedure when tapemark is sensed. procedure endfile(z,s,b); zone z ; integer s,b ; if s extract 1 = 1 then stderror(z,s,b) else if b ' 0 then begin integer array descr(1:20); integer field reclen,firstword; reclen:= 32; firstword:= 2; \f getzone6(z,descr); checkvar b:= descr.reclen:= z.firstword:= length; ..... set other parameters in the record; setzone6(z,descr); checkvar(z); end; The zone should be opened with giveup mask 1 shift 16. E_x_a_m_p_l_e_ _2_: See example 2 of invar. E_x_a_m_p_l_e_ _3_: See example 2 of swoprec6. \f F_2_._2_5_ _ _ _ _ _ _c_l_o_s_e_ 2.25 close This standard procedure terminates the current use of a zone and makes the zone ready for a new call of open. Close may also release a device so that it becomes available for other processes in the computer. C_a_l_l_: close (z, rel) z (call and return value, zone). Specifies the document, the position of the docu- ment, and the latest operation on z. rel (call value, boolean). True if you want the document to be released, false otherwise. Close terminates the current use of the zone as described for setposition. If the document is a magnetic tape which latest has been used for out- put (state 3 and 6, see getzone6), a tape mark is written. Finally, close releases the document if rel is true. Releasing means for a backing storage area that the reservation of the area process descrip- tion inside the monitor is released for use by other zones of yours (remove process). The area itself is not removed and you may later open it again. End medium is not set on the document. In case of a magnetic tape, two kinds of release exist: If rel is true and the binary pattern is false add 1, the tape will be released, which means that the tape is not needed later in the run. Release of a work tape means that the tape is made available to other users (see ref. 7). If rel is true with another binary pattern, the tape may be unmounted now (for instance if tape stations are sparse), but it will be needed later in the run. In both cases a message is sent to the parent asking for release or suspension of the tape. \f Releasing means for other documents, that theclose corresponding peripheral device is made available for other processes. Z_o_n_e_ _s_t_a_t_e_: The zone may be in any state when close is called. After the call the zone is in state 4, after de- claration, meaning that it must be opened before it can be used for input/output again. E_x_a_m_p_l_e_ _1_: A backing storage area which you want to open more times should not be released, because that may allow other processes to remove it or output to it. Avoid it in this way: open(master,4,<:bs52:',0); for ... do outrec6(master, ... close(master,false); open(trans,4,<:bs52:',0); ... E_x_a_m_p_l_e_ _2_: Let z1 and z2 be two zones which describe magnetic tapes. If you want to close them and rewind them, proceed in this way: setposition(z1,0,0); setposition(z2,0,0); close(z1,false); close(z2,false); The rewindings are then performed in parallel and completed when close is called. \f F_2_._2_6_ _ _ _ _ _ _c_l_o_s_e_t_r_a_n_s_ 2.26 closetrans This standard procedure terminates the current format 8000 output transaction, i.e. writes an ETX character and outputs the current buffer to the device (see ref. 19). C_a_l_l_: closetrans (z) z (call and return value, zone). Specifies the document to which the transaction is transferred. Z_o_n_e_ _s_t_a_t_e_: The zone must be in state 3 (after character writing). After the call the zone is in state 13 (ready for opentrans). E_x_a_m_p_l_e_ _1_: See example 1 of opentrans, and example 3 of writefield. \f F_2_._2_7_ _ _ _ _ _ _c_o_m_m_e_n_t_ 2.27 comment This delimiter, which is a separator, is used to insert comments in the program text in order to increase the readability of the program. Comments may appear in 2 different forms: S_y_n_t_a_x_: ; comment <text not containing ";"' ; may replace any ; (semicolon) begin comment <text not containing ";"' ; may be replace any begin E_x_a_m_p_l_e_ _1_: ... begin comment h=height, l=length, w=width, v=volume; integer h, l, w, v; read (in, h, l, w); comment calculate the volume; v:= h*l*w; ... \f F_2_._2_8_ _ _ _ _ _ _c_o_m_m_e_n_t_ _s_t_r_i_n_g_ 2.28 comment string This delimiter, which is a bracket, can be used everywhere a com- ment is needed. S_y_n_t_a_x_: <* <text not containing "<*" or "*'" ' *' S_e_m_a_n_t_i_c_: This comment string can replace a space everywhere in the program. The comment string is blind to the program. E_x_a_m_p_l_e_ _1_: procedure A (<*price*' p, <*item no*' item); case i of (<*i=1*' a+b, <*i=2*' c/q+1) \f F_2_._2_9_ _ _ _ _ _ _c_o_n_t_e_x_t_ 2.29 context This delimiter, which is a declarator, is used in the declaration of a context block. S_y_n_t_a_x_: context (incarnations, no _of _incarnations, context _mode) incarnation (integer expression). Specifies the actual incarnation of the context block. no _of _incarnations (integer expression). Specifies the total number of incarnations. context _mode (integer expression). Specifies a bit pattern, which defines the action at entry to and exit from a context block. The bits are used as follows: 1 shift 0: read bit 1 shift 1: write bit 1 shift 2: save bit 1 shift 3: new block bit 1 shift 4: new incarnation bit This declaration follows immediately the block begin, and must only appear once in the head of the block. S_e_m_a_n_t_i_c_: See the description in ref. 15, section 4. E_x_a_m_p_l_e_ _1_: See the examples in ref. 15. \f F_2_._3_0_ _ _ _ _ _ _c_o_n_t_i_n_u_e_ 2.30 continue This delimiter, which is a context operator, is used in a context block to control special jumps out of a context block. S_y_n_t_a_x_: continue S_e_m_a_n_t_i_c_: See the description in ref. 15. E_x_a_m_p_l_e_ _1_: See the examples in ref. 15. N_o_t_e_: continue is only a delimiter in programs where context is used. \f F_2_._3_1_ _ _ _ _ _ _c_o_s_ 2.31 cos This real standard procedure performs the trigonometric function cosine. C_a_l_l_: cos (r) cos (return value, real). Is the trigonome- trical function cosine of the argument r, in radians with -1 <= cos <= 1 r (call value, real, long, or integer). The argument in radians. A_c_c_u_r_a_c_y_: abs(r) < /2 gives a relative error below 1.2>-10 abs(r) '= /2 To the relative error of 1.2>-10 must be added the absolute error of the argument, r*3>-11. This means that cos is completely undefined for abs(r) ' 3>10, and then the result is always 0. E_x_a_m_p_l_e_ _1_: Let d be an angle in degrees. pi:= 3.14159 26536; cad:= cos (pi/180 * d); Now cad contains cos of d. \f F_2_._3_2_ _ _ _ _ _ _d_e_a_d_s_o_r_t_ 2.32 deadsort This standard procedure creates a zone record in core store which at a later stage is to take part in a sorting process. The con- tents of the record are initially undefined, but the user is supposed to assign values to the record variables before next call of any sorting procedure. The so defined record becomes an inactive record in the sorting process, i.e. it is not partici- pating in the selection process of procedure outsort. C_a_l_l_: deadsort (z); z (call and return value, zone). The name of the record created. Z_o_n_e_ _s_t_a_t_e_: As for newsort. E_x_a_m_p_l_e_ _1_: String generation by replacement - selection. A large file on magnetic tape is read, and a string of sorted records as long as possible is generated from this input stream. The input takes place via zone x, and output is written via zone y. Record length is one double word, and the output string is sequenced on ascending value of this real. The internal store is supposed to be able to hold about 1000 records. begin zone z(2018, 1, sorterror); integer array key(1:1, 1:2); integer i, n; key(1,1):= 4; key(1,2):= 4; n:= 1000; startsort6(z,key, 1,4); for i:= 1 step 1 until 1000 do begin inrec(x,1); newsort(z); z(1):= x(1) end; \f outsort(z); deadsort while true do begin outrec(y,1); y(1):= z(1); inrec(x,1); if sortcomp(z, x, y) < 0 then begin deadsort(z); n:= n -1 end else newsort(z); z(1):= x(1); if n ' 0 then outsort(z) else begin <*at this stage the zone z is filled up with inactive records which can be activated to form a new string*' lifesort(z); n:= 999; end; end while; comment an end of file situation is not handled by this algorithm, i.e. the input file is assumed to be infinitely large; \f F_2_._3_3_ _ _ _ _ _ _d_e_c_i_m_a_l_ _p_o_i_n_t_ _(_._)_ 2.33 decimal This delimiter, which is a separator, is a part of a real number. M_m_m_S_y_n_t_a_x_: 1 1 + <unsigned integer' .<unsigned integer' - P_p_p_ 0 0 S_e_m_a_n_t_i_c_: The decimal point has the conventional meaning. E_x_a_m_p_l_e_ _1_: 0.7300 +0.7614 -200.084 -.083 5.17 .1 \f F_ 2_._3_4_ _ _ _ _ _ _d_i_s_a_b_l_e_ 2.34 disable This delimiter, which is a declarator, is used in connection with activities in order to let the following statement allocate stack space in the "open ended" stack of the monitor block (see ref. 19 and activity). It can also be used to prevent an implicit passi- vate. S_y_n_t_a_x_: disable <statement' S_e_m_a_n_t_i_c_: During execution of a disable statement all stacking/unstacking is done in the "open ended" stack of the monitor block, and the program is in d_i_s_a_b_l_e_ _m_o_d_e_. This means that a possible implicit passivate is not performed. A disable statement must not be the body of a procedure declaration. Execution of activity procedures (activate, passivate) is not allowed in disable mode. E_x_a_m_p_l_e_s_: disable a:= proc (a, b, x); disable begin a:= a+1; ... end; \f F_2_._3_5_ _ _ _ _ _ _d_i_v_i_d_e_ _(_/_)_ 2.35 divide This delimiter, which is an arithmetic operator, yields the quotient of the two operands. S_y_n_t_a_x_: <operand1' / <operand2' P_r_i_o_r_i_t_y_: 3 O_p_e_r_a_n_d_ _t_y_p_e_s_: integer, long, or real. R_e_s_u_l_t_ _t_y_p_e_: always real. S_e_m_a_n_t_i_c_: The operation may include a type conversion. Real values are represented with a relative pre- cision of about 3>-11 (cf. ref. 15). This means that a real variable holding an integral value is represented exact in the interval -2**35 <= real <= 2**35-1. As division of long values includes call of sub- routines, and cannot be performed by built-in operations, a representation of certain long vari- ables in real variables may be advantageous (cf. ref. 15). E_x_a_m_p_l_e_ _1_: r:= a/b; b:= a/b/c/d; \f F_ 2_._3_6_ _ _ _ _ _ _e_n_d_a_c_t_i_o_n_ 2.36 endaction This integer standard identifier controls the way in which, the program will terminate: endaction = 0: At program termination, the FP end program will be called. endaction = 1: At program termination, a "finis job message" will be sent to the parent process. endaction '1 or <0: At program termination, the FP break action will be called. Default value is 0. \f F_2_._3_7_ _ _ _ _ _ _e_n_t_i_e_r_ 2.37 entier This delimiter, which is a monadic arithmetic operator, transfers an arithmetic expression of type real to the largest integer not greater than the real expression. S_y_n_t_a_x_: entier <operand' P_r_i_o_r_i_t_y_: 1 O_p_e_r_a_n_d_ _t_y_p_e_: always real. R_e_s_u_l_t_ _t_y_p_e_: always integer. S_e_m_a_n_t_i_c_: The largest integer not greater than the real arithmetic expression is evaluated. The operation may cause integer overflow. E_x_a_m_p_l_e_ _1_: a:= 5.85; b:= entier a; <* now b has the value 5 *' a:= -a; c:= entier a; <* now c has the value -6 *' \f F_ 2_._3_8_ _ _ _ _ _ _e_q_u_a_l_ _(_=_)_ 2.38 equal This delimiter, which is a relational operator, gives the value true or false. S_y_n_t_a_x_: <operand1' = <operand2' P_r_i_o_r_i_t_y_: 5 O_p_e_r_a_n_d_ _t_y_p_e_s_: integer, long, or real. R_e_s_u_l_t_ _t_y_p_e_: always boolean. S_e_m_a_n_t_i_c_: The relation takes on the value true whenever the bitpattern of the two operands are equal, otherwise false. The relation is performed as a bit by bit compari- son of the two operands (after a possible type conversion whenever the operands are of different types). E_x_a_m_p_l_e_ _1_: b:= 5=6; <*false*' if a=c then .... k:= 5=15/3; <*true*' \f F_2_._3_9_ _ _ _ _ _ _e_q_u_i_v_a_l_e_n_t_ _(_=_=_)_ 2.39 equivalent This delimiter, which is a logical operator, yields the logi- cal equivalence of the two operands. S_y_n_t_a_x_: <operand1' == <operand2' P_r_i_o_r_i_t_y_: 10 O_p_e_r_a_n_d_ _t_y_p_e_s_: boolean. R_e_s_u_l_t_ _t_y_p_e_: boolean. S_e_m_a_n_t_i_c_: The truth value is evaluated according to the following rule: right left true false true true false false false true E_x_a_m_p_l_e_ _1_: if a == b then ....; <*is the same as if a and b or (-,a and -,b) then ...*' \f F_2_._4_0_ _ _ _ _ _ _e_r_r_o_r_b_i_t_s_ 2.40 errorbits This integer standard identifier is used when returning to the File Processor. The value of the errorbits defines the "end program condition". Only the bits: errorbits extract 2 are used by the system. The two bits are interpreted as follows: 1 shift 0 : ok.no 0 shift 0 : ok.yes 1 shift 1 : warning.yes 0 shift 1 : warning.no The default value of errorbits is 0. E_x_a_m_p_l_e_ _1_: If you in an algol program count the number of errors recognized during the run, you may let the program decide whether to continue or stop the job by assigning errorbits before leaving the program: if errors ' maxerrors then errorbits:= 1 else if errors ' 0 then errorbits:= 1 shift 1; end program The job may contain the following FP commands: p ; run the program if ok.no (c = message too many errors. stop run finis) if warning.yes c = message some errors.run continues ; execute the next program in the jobfile ... \f F_2_._4_1_ _ _ _ _ _ _e_x_i_t_ 2.41 exit This delimiter, which is a context operator, is used in a context block to control special jumps out of a context block. S_y_n_t_a_x_: exit (<designational expression') S_e_m_a_n_t_i_c_: See description in ref. 15. N_o_t_e_: exit is only a delimiter in programs where context is used. E_x_a_m_p_l_e_ _1_: See the example in ref. 15. \f F_2_._4_2_ _ _ _ _ _ _e_x_o_r_ 2.42 exor This long standard procedure performs the logical function ex- clusive or on two 48 bit entities a and b. If the type length of a and/or b is shorter than 48 bits, they are extended by repeti- tion of the sign bit. C_a_l_l_: exor (a, b) exor (return value, long). Bit pattern equal to -, (a==b) performed bit by bit after possible extension of the parameters a and b. a,b (call value, short string (text portion), real, long, integer or boolean). The two parameters do not have to be of the same kind. They are - if necessary - extended and they are handled as described below. H_a_n_d_l_i_n_g_ _o_f_ _a_ _a_n_d_ _b_ _a_c_c_o_r_d_i_n_g_ _t_o_ _k_i_n_d_: String: It is tested that a string parameter des- cribes a text portion or a short string (ref. 14). This is a 48 bit entity. Real: A real is represented by 48 bits, no conversion. Long: A long is represented by 48 bits, no conversion. Integer: An integer is extended to a long as if the operator extend had been applied. Boolean: A boolean is considered as a short integer. The 12 bit boolean pattern is extended to a 48 bit long according to the algorithm int:= boo extract 12; if int ' 2047 then int := int - 4096; param:= extend int; \f The rules for extension imply that actual para-exor meters with values true, -1, and extend (-1) are equivalent. Note that the rules also imply that the effect of an integer with value 2048 differs from the effect of a boolean with the value false add 2048. E_x_a_m_p_l_e_ _1_: In certain data transmission problems, a check character, which is a longitudinal parity check of a data block is needed. If the block is of more than 6 characters, the algorithm for finding the check character may look somewhat like this: longfield:= firstword + 2; checkword:= z.longfield; for longfield:= longfield + 4 step 4 until lastword do checkword := exor(checkword,z.longfield); if longfield - 4 <' lastword then checkword:= exor(checkword,z.lastword); checkword:= exor(checkword,checkword shift (-24)); checkword:= exor(checkword extract 8, checkword shift (-8)); checkchar:= exor(checkword,checkword shift (-8)) extract 8; z.checkfield:= checkchar; The data block inclusive the checkcharacter will now be of even longitudinal parity. \f F_2_._4_3_ _ _ _ _ _ _e_x_p_ 2.43 exp This real standard procedure performs the exponential function. C_a_l_l_: exp (r) exp (return value, real). The exponential function of the argument r, e**r. (e = 2.71828 18285). r (call value, real, long, or integer). r < 1000. A_c_c_u_r_a_c_y_: r = 0 gives exp = 1. r < -1000 gives exp = 0. abs(r) < ln(2)/2 gives a relative error below 8.5>-11. (n-0,5)*ln(2) <= abs(r) <= (n+0.5)*ln(2) gives a relative error below 1.2>-10 + n*2>-11. A value of r greater than 1000 will terminate the run. E_x_a_m_p_l_e_ _1_: e:= exp (1); \f F_2_._4_4_ _ _ _ _ _ _e_x_p_o_n_e_n_t_i_a_t_i_o_n_ _(_*_*_)_ 2.44 exponentiation This delimiter, which is an arithmetic operator, yields the involution of the left hand operand to the power indicated by the right hand operand. S_y_n_t_a_x_: <operand1' ** <operand2' P_r_i_o_r_i_t_y_: 2 O_p_e_r_a_n_d_ _t_y_p_e_s_: integer, long, or real. When <operand2' is real, <operand1' must be positive (see below). R_e_s_u_l_t_ _t_y_p_e_: always real. S_e_m_a_n_t_i_c_: The operation denotes exponentiation, where <operand1' is the base, and <operand2' is the exponent. Thus for example DDDDkUUU M_M_m_ n P_P_p_ 2**n**k means (2 ) while DDDDkUUU M_M_m_ (n ) P_P_p_ 2**(n**k) means 2 Writing i for a number of type integer or long, r for a number of type real, and a for a number of type either integer, long, or real, the result is given by the following rules: a_*_*_i_: i ' 0: a*a*...*a (i times) i < 0: 1/(a*a*...*a) (abs(i) times), a must be <' 0 i = 0: 1 \f a_*_*_r_: exponentiation a ' 0 exp (r * ln(a)) a < 0: runtime alarm a = 0: runtime alarm (except when a is of type integer or long and r ' 0, in which case the result becomes 0.0). E_x_a_m_p_l_e_ _1_: r:= b * 10**a; \f F_2_._4_5_ _ _ _ _ _ _e_x_t_e_n_d_ 2.45 extend This delimiter, which is a monadic arithmetic operator, converts an integer expression to a long. S_y_n_t_a_x_: extend <operand' P_r_i_o_r_i_t_y_: 1 O_p_e_r_a_n_d_ _t_y_p_e_: integer. R_e_s_u_l_t_ _t_y_p_e_: long. S_e_m_a_n_t_i_c_: The value of <operand' is converted to a 48 bits long by extension of the sign bit. E_x_a_m_p_l_e_ _1_: As operations on integers give integer values, an unwanted integer overflow may occur when two integers are multiplied. This may be avoided if the operator extend is applied on o_n_e_ of the operands: totals:= extend pieces * price (whereas the expression: totals:= extend (pieces * price) will not work). This is of course only relevant if totals reason- ably can exceed 8 000 000 and is a long. E_x_a_m_p_l_e_ _2_: Two integers may be packed into one long variable in this way: l:= extend i1 shift 24 add i2; E_x_a_m_p_l_e_ _3_: See example 2 of long. \f F_2_._4_6_ _ _ _ _ _ _e_x_t_e_r_n_a_l_ 2.46 external This delimiter, which is a compiler directive, replaces the first begin of the program when an algol procedure is translated alone. S_y_n_t_a_x_: external <procedure declaration'; end is a program. A maximum of 7 parameters is allowed. S_e_m_a_n_t_i_c_: A procedure translated in this way becomes a standard procedure, which means that other algol programs may call the procedure without having to declare it. The name of the procedure is the name of the backing storage area in which it was trans- lated. All standard identifiers used from the pro- cedure must be present in the catalog when the procedure is translated, but the actual code de- termining these standard identifiers is not copied until the procedure itself is copied into an ordi- nary algol program. The name of a translated external procedure must not contain capital letters, because they are for- bidden in names of backing storage areas. E_x_a_m_p_l_e_ _1_: A standard function >tg> may be compiled in this way: tg=algol; File processor commands, see ref. 6. external real procedure p(r); value r; real r; begin real v; v:= cos(r); p:= if v <' 0 then sin(r)/v else >600 end; end scope user tg; File processor command. From another program it may be used like this: write(out,(1+tg(B/2))/(1-tg(B/2))); \f Assume that the procedures cos and sin are re-external placed with better versions. These new versions will automatically be used whenever tg is used during the translation of an algol program. \f F_2_._4_7_ _ _ _ _ _ _e_x_t_r_a_c_t_ 2.47 extract This delimiter, which is a pattern operator, is used for unpack- ing of integer values from a real, long, integer, boolean, or string value. S_y_n_t_a_x_: <operand1' extract <operand2' P_r_i_o_r_i_t_y_: 2 O_p_e_r_a_n_d_ _t_y_p_e_s_: <operand1': boolean, integer, long, real, or string. <operand2': integer, long, or real. R_e_s_u_l_t_ _t_y_p_e_: always integer. S_e_m_a_t_i_c_: Extract treats <operand1' as a binary pattern (see ref. 14), and <operand2' is rounded to an integer if it is of type long or real. Now a number of the rightmost bits are extracted from <operand1' as indicated by the value of <operand2'. These bits are extended with zeroes in front if necessary. The resulting value is the integer with these bits as its binary pattern. The result is undefined if the, possibly rounded, <operand2' has a value below 0 or above 24. E_x_a_m_p_l_e_ _1_: S_i_m_p_l_e_ _s_p_l_i_t_t_i_n_g_. A boolean may be split into two integers in this way: i1:= b shift (-6) extract 6 i2:= b extract 6; Both integers will be in the range 0 to 63. \f E_x_a_m_p_l_e_ _2_: S_p_l_i_t_t_i_n_g_ _w_i_t_h_ _s_i_g_n_. extract A real may be split into two signed integers in this way: i1:= r shift (-24) extract 24; i2:= r extract 24; Usually a signed integer is packed and split in this way: comment -32 <= i <= 31; i.e. 0 <= i+32 <= 63; r:= r shift 6 add (i+32); ... i:= r extract 6 - 32; E_x_a_m_p_l_e_ _3_: A text string stored in the integer array ia may be split into a sequence of characters stored as integers in the array char in the following way: comment c is the current index within char, s counts positions within ia(i); s:= i:= 0; for c:= 1,c+1 while ch <' 0 do begin if s <' 0 then s:= s + 8 else begin s:= -16; i:= i + 1; t:= ia(i) end; char(c):= ch:= t shift s extract 8; end; A faster version, which always splits ia(i) into 3 characters even if one of them is the stop character (0), works like this: \f comment c is current index within char, extract t contains ia(i); t:= c:= -2; i:= 0; for c:= c + 3 while t extract 8 <' 0 do begin i:= i + 1; t:= ia(i); char(c):= t shift (-16); char(c+1):= t shift (-8) extract 8; char(c+2):= t extract 8; end; E_x_a_m_p_l_e_ _4_: S_c_a_l_e_ _o_f_ _r_e_a_l_s_. An array of reals may be scaled so that all ele- ments are in the range -1 < r < 1 in the following way. The mantissas are not touched so that full accuracy is maintained. The main problem in the algorithm is the handling of the sign of the ex- ponent. max:= -2048; for i:= 1 step 1 until n do begin e:= ra(i) extract 12; if e '= 2048 then e:= e - 4096; if e ' max then max:= e; end; comment max is now the maximal two>s exponent; for rf:= 4*n step -4 until 4 do if ra.rf <' 0 then begin bf:= rf; e:= ra.bf extract 12; if e '= 2048 then e:= e - 4096; e:= e - max; if e < -2048 then ra.rf:= 0 else ra.bf:= false add e; end; \f F_ 2_._4_8_ _ _ _ _ _ _f_8_0_0_0_t_a_b_l_e_ 2.48 f8000table This standard procedure changes the input character alphabet (like the standard procedure intable) to the format 8000 input table. C_a_l_l_: f8000table The format 8000 table consists of 256 entries and is stored in own core. N_o_t_e_: The procedure waittrans and readfield call this procedure, so it not necessary for the program to call f8000table when using the format 8000 procedures. \f F_2_._4_9_ _ _ _ _ _ _f_i_e_l_d_ 2.49 field This delimiter, which is a declarator, is used in declarations and specifications of field variables. S_y_n_t_a_x_: <type' field <field list' <type' array field <field list' array field <field list' S_e_m_a_n_t_i_c_: Field variables are used in field references or they may be used as integer variables. For a complete description see ref. 15. E_x_a_m_p_l_e_ _1_: See ref. 15. E_x_a_m_p_l_e_ _2_: See example 1 of activity. \f F_2_._5_0_ _ _ _ _ _ _f_p_m_o_d_e_ 2.50 fpmode This boolean standard procedure tests a bit in the FP-modeword. C_a_l_l_: fpmode (modebit) fpmode (return value, boolean). True if the bit was set, otherwise false. modebit (call value, integer). 0 <= modebit <= 23 E_x_a_m_p_l_e_ _1_: The printing of testoutput from your program can be controlled by modebits in the following way: begin boolean testa, testb; ..... testa:= fpmode(0); testb:= fpmode(1); ..... if testa then write (out, .....); ..... if testb then write (out, .....); The job mode 0.yes 1.no ; set testa p ; execute program will produce the testoutput controlled by testa, but not the testoutput controlled by testb. \f F_ 2_._5_1_ _ _ _ _ _ _g_e_t_a_l_a_r_m_ 2.51 getalarm This integer standard procedure can be used when runtime alarms are trapped, to supply the information which would have been printed by the File Processor if the run was terminated. C_a_l_l_: getalarm (arr) getalarm (return value, integer). If the latest runtime alarm was: give up (i.e. alarmcause extract 24 = -11), the value is the logical status word from the zone in question - otherwise it is undefined. arr (return value, array of any type). Must be declared to hold at least 8 words, the first word being at halfword index =1. Assume the declaration long array arr (1:4); then the contents of arr will be: arr (1:2) The alarmtext printed on current output. arr (3:4) If alarm _cause extract 24 = -11 (give up), the contents will be the document name of the zone in question - other- wise the empty string. E_x_a_m_p_l_e_ _1_: The following procedure should be called when an alarm has been trapped. procedure writealarm (out); zone out ; begin long array text (1:4); long array field docname; integer status, cause, param, bit; real comma; \f docname:= 8; getalarm status := getalarm (text); cause := alarmcause extract 24; param := alarmcause shift (-24); write (out, text, param); if cause = -11 <*give up*' then begin <*output device information*' write (out, "sp", 1, text.docname); comma:= real <:: :'; for bit:= 1 step 1 until 24 do if status shift (bit-1) < 0 then begin write (out, string comma, case bit of ( <*1*' <:intervention:', <:parity error:', <:timer:', <:data overrun:', <*5*' <:block length:', <:end document:', <:load point:', <:att or tapemark:', <:write enable:', <*10*' <:mode error:', <:read error:', <:card reject:', <:checksum:', <:bit 15:', <*15*' <:passivate:', <:stopped:', <:word defect:', <:position error:', <:non exist:', <*20*' <:disconnected:', <:unintelligible:', <:rejected:', <:normal:', <:hard error:')); comma:= real <:, :'; end for, if; end device information; end write alarm; \f F_ 2_._5_2_ _ _ _ _ _ _g_e_t_f_8_0_0_0_t_a_b_ 2.52 getf8000tab This standard procedure opens access to the format 8000 character input table. C_a_l_l_: getf8000tab (a, low, up) a (call and return value, integer array). The dope vector of the array is changed, so as to point directly to the format 8000 table. The array may be declared: integer array a(1:1) and must be a single declaration. Field arrays are not allowed. low, up (call values, integer). Define the wanted lower and upper limits for the array: a (low:up). On exit there is direct access to the format 8000 table, and care must be shown, to avoid destruction of table values (0:31) and (127:255), wich are used for special purposes by the format 8000 procedures. E_x_a_m_p_l_e_ _1_: The following program part will make the user part of the character input table available for changes, but will prevent the special part of the table from being destroyed: begin integer array table (1:1); getf8000tab (table, 32, 126); table (32):= ...; <*define space and other characters*' <*but a reference: table(31):= ... will give an index alarm*' \f F_ 2_._5_3_ _ _ _ _ _ _g_e_t_p_o_s_i_t_i_o_n_ 2.53 getposition This standard procedure gets the block and file number corresponding to the current logical position of a document. C_a_l_l_: getposition (z, file, block) z (call value, zone). Specifies the document, the position of the document, and the latest operation on z. file (return value, integer). Irrelevant for docu- ments other than magnetic tape. Specifies the file number of the current logical position (see ref. 15). Files are counted 0, 1, 2,... block (return value, integer). Irrelevant for docu- ments other than magnetic tape and backing storage. Specifies the block number of the current logical position (see ref. 15). Blocks are counted 0, 1, 2, ... Getposition does not change the zone state and it may be called in all states of the zone. If the zone is not opened, the position got will be undefined, however. The position is also undefined after a call of close. When the document is a backing storage area, the con- tents of the parameter block is the segment number within the area. If the share length of the zone is greater then one segment, the position will be the segment number of the first segment within the block. E_x_a_m_p_l_e_ _1_: During the generation of a magnetic tape, you may note the position of a particular record and later return to that block: outrec6(z,10); getposition(z,f,b); outrec6(z,10); setposition(z,f,b); inrec6(z,10); \f If you want to get the same record again, you may usegetposition getzone6 to get the position within the block, or you may use the value of inrec6 or outrec6 to denote the position within the block (see example 3 of getzone6). \f F_2_._5_4_ _ _ _ _ _ _g_e_t_s_h_a_r_e_ 2.54 getshare This standard procedure moves the contents of a s_h_a_r_e_ _d_e_s_c_r_i_p_t_o_r_ into an integer array for further inspection. The procedure is the A_L_G_O_L_5_ version of getshare6. C_a_l_l_: getshare (z, ia, sh) z (call value, zone). Specifies the share together with sh. ia (return value,integer array,length '= 12). sh (call value, integer). The number of a share within z. The contents of the share descrip- tor are moved to the first element of ia and on. Works as getshare6 except that getshare computes first shared and last shared as a buffer index instead of as a halfword index. The buffer index is equal to (halfword index+3)//4. \f F_ 2_._5_5_ _ _ _ _ _ _g_e_t_s_h_a_r_e_6_ 2.55 getshare6 This standard procedure moves the contents of a s_h_a_r_e_ _d_e_s_c_r_i_p_t_o_r_ into an integer array for further inspection. The procedure is designed for the primitive level of input-output, where you im- plement your own blocking strategy for the peripheral devices, and for use in the block procedures where you want to interfere with the standard handling of devices. Skip it if you are satis- fied with the high level zone procedures. A share descriptor consists of 12 pieces of information, most of them with names originating from their use in high level zone procedures. The explanation below requires some knowledge of handling of peripheral devices (see ref. 3). The share descriptor contains certain absolute addresses of half- words within the zone buffer. The reason for this and the rela- tion between the absolute address and the usual index are given for the procedure getzone6. C_a_l_l_: getshare6 (z, ia, sh) z (call value, zone). Specifies the share to- gether with sh. ia (return value, integer array, length '= 12). The following list assumes that >ia> has been declared as ia(1:12). sh (call value, integer). The number of a share within z. The contents of the share descrip- tor are moved to the first element of ia and on. \f ia(1) S_h_a_r_e_ _s_t_a_t_e_. Describes what the share is used for: getshare6 = message buffer address for an uncompleted transfer or a stopping child process. = -process description address for a running child process. = 0 for a free share. See below. = 1 for a ready share. See below. ia(2) F_i_r_s_t_ _s_h_a_r_e_d_. Halfword index for the first element available for a block transfer which uses this share and was started by a high level zone procedure. ia(3) L_a_s_t_ _s_h_a_r_e_d_. Halfword index for the last element available for a block transfer which uses this share and was started by a high level zone procedure. ia(4) to ia(11) M_e_s_s_a_g_e_. A high level zone procedure leaves the latest message sent by means of this share in the message part of the share descriptor. A message describing a block transfer is composed like this: ia(4) operation shift 12 + mode operation examples cf. ref. 3 0 sense 3 read 5 write ia(5) first absolute address of block ia(6) last absolute address of block ia(7) segment number (only significant for backing storage) ia(12) T_o_p_ _t_r_a_n_s_f_e_r_r_e_d_. The absolute address of the halfword just after the latest block transferred by means of this share. Top transferred may differ from ia(6)+1 after an input operation, for instance. N_o_t_e_ ! Fielding has no influence on the addressing of ia, as the procedure always use the 12 first elements of the array. \f F_r_e_e_ _a_n_d_ _r_e_a_d_y_ _s_h_a_r_e_ getshare6 The output procedures do not distinguish between a free and a ready share, but whenever an input procedure tries to get a new block of information, it assumes that a ready share contains a block of information already whereas a free share must be filled with a block from the device. E_x_a_m_p_l_e_ _1_: Let z be declared as z(300,3,stderror) with base buffer area = 29 999, (see definition in getzone6) and assume that you have opened the zone. The calls getshare6(z,ia,1), getshare6(z,ia,2), and getshare6(z,ia,3) will now yield the following results in typical situations (X designates an undefined value): ia(1) ia(2) ia(3) ia(4) ia(5) ia(6)... ia(12) state f.sh. l.sh. opt. f.adr. l.adr. top.tr. When the first block of input is being processed: used share 0 1 400 input 30 000 30 398 30 276 share2 '0 401 800 input 30 400 30 798 X share3 '0 801 1200 input 30 800 31 198 X When the first block of output has been produced: share1 '0 1 400 output 30 000 30 350 X used share 0 401 800 X 30 400 30 798 X share3 0 801 1200 X 30 800 31 198 X Just after setposition for a magnetic tape: used share '0 1 400 move position 30 398 X share2 0 401 800 X 30 400 30 798 X share3 0 801 1200 X 30 800 31 198 X \f F_ 2_._5_6_ _ _ _ _ _ _g_e_t_s_t_a_t_e_ 2.56 getstate This standard procedure assigns the zonestate to an integer parameter. C_a_l_l_: getstate (z, state) z (call value, zone). The zone state of z is assigned to state. state (return value, integer). E_x_a_m_p_l_e_ _1_: See example 1 of opentrans. \f F_ 2_._5_7_ _ _ _ _ _ _g_e_t_z_o_n_e_ 2.57 getzone This standard procedure moves the contents of a z_o_n_e_ _d_e_s_c_r_i_p_t_o_r_ into an integer array for further inspection. The procedure is the A_L_G_O_L_5_ version of getzone6 and works as getzone6 except that the record length is given in buffer elements instead of halfwords. A buffer element consists of 4 halfwords. Last halfword of a buffer element, the reference halfword, has the absolute address: base buffer area + 4 * buffer index. C_a_l_l_: getzone (z, ia) z (call value, zone). The contents of the zone descriptor are moved to the first element of ia and on. ia (return value, integer array, length '= 20). Getzone should only be used if the zone has only been used for inrec, outrec or swoprec. As it cuts the record length to an integral number of elements, it may give misleading results if some of the procedures inrec6, outrec6, swoprec6, changerec6, invar, outvar, or changevar have been used. For further description see getzone6. \f F_ 2_._5_8_ _ _ _ _ _ _g_e_t_z_o_n_e_6_ 2.58 getzone6 This standard procedure moves the contents of a z_o_n_e_ _d_e_s_c_r_i_p_t_o_r_ into an integer array for further inspection. The procedure is designed for the primitive level of input-output, where you implement your own blocking strategy for the peripheral devices, and for use in the block procedures where you want to interfere with the standard handling of the devices. Skip it if you are satisfied with the high level zone procedures. A zone descriptor consists of 20 pieces of information, most of them with names originating from their use in high level zone procedures. The z_o_n_e_ _b_u_f_f_e_r_ is just a sequence of real variables - from the point of view of the algol program - but other processes (periphe- ral devices, etc.) regard it rather as a sequence of halfwords, each being identified by its a_b_s_o_l_u_t_e_ _a_d_d_r_e_s_s_. If you want to communicate with other processes on the very pri- mitive level (procedure monitor), you cannot avoid the absolute addresses. They are related to the usual halfword index in this way: The reference halfword of a field in the zone has the absolute address: base buffer area + halfword index. This expression also defines the quantity >base buffer area> as the absolute address of the halfword preceding the zone buffer area. The value of >base buffer area> and certain other halfword addresses are available by means of getzone6. \f C_a_l_l_: getzone6 (z, ia) getzone6 z (call value, zone). The contents of the zone descriptor are moved to the first element of ia and on. ia (return value, integer array, length '= 20). The following list assumes that ia has been declared as ia(1:20). ia(1) M_o_d_e_ shift 12 + k_i_n_d_. Values and significance are explained under the procedure open. ia(2) to ia(5) P_r_o_c_e_s_s_ _n_a_m_e_. The name of the process (document) with which the zone communicates for the moment. The name is extended to 12 characters using null characters for fill. ia(6) N_a_m_e_ _t_a_b_l_e_ _a_d_d_r_e_s_s_. The corresponding variable in the zone descriptor is used by the monitor to speed up the search for the process given by the process name. ia(7) F_i_l_e_ _c_o_u_n_t_. Only significant for magnetic tape handling. See explanation below. ia(8) B_l_o_c_k_ _c_o_u_n_t_. Only significant for magnetic tape handling. See explanation below. ia(9) S_e_g_m_e_n_t_ _c_o_u_n_t_. Only significant for handling of backing storage areas. See explanation below. ia(10) G_i_v_e_ _u_p_ _m_a_s_k_. See ref. 15. ia(11) F_r_e_e_ _p_a_r_a_m_e_t_e_r_. Is used by the Fortran read/write system and by the var-procedures. See explanation below. ia(12) P_a_r_t_i_a_l_ _w_o_r_d_. Used by the procedures for input- output on character level to unpack or pack cha- racters. See explanation below. ia(13) Z_o_n_e_ _s_t_a_t_e_. Used by high level zone procedures to keep track of the latest operation on the zone. See below. ia(14) R_e_c_o_r_d_ _b_a_s_e_. The absolute address of the halfword preceding the first halfword of the present record. During character input or output the record may be regarded as the word in the zone buffer in which the partial word will end or from which it came. \f ia(15) L_a_s_t_ _h_a_l_f_w_o_r_d_. Absolute address of the last half- getzone6 word of current block. During output the block matches the shared area used for the moment, du- ring input the block matches the block transferred from the device. ia(16) R_e_c_o_r_d_ _l_e_n_g_t_h_. Number of halfwords in the present record. Notice that the record length is 0 during character input or output. ia(17) U_s_e_d_ _s_h_a_r_e_. Number of a share within z. Used share will in high level zone procedures be the share in which items are stored for the moment or from which they are fetched. ia(18) N_u_m_b_e_r_ _o_f_ _s_h_a_r_e_s_. The value given in the zone declaration. ia(19) B_a_s_e_ _b_u_f_f_e_r_ _a_r_e_a_. See above. ia(20) B_u_f_f_e_r_ _l_e_n_g_t_h_. The value given in the zone decla- ration, i.e. measured in double words. N_o_t_e_ ! Fielding has no influence on the addressing of ia, as the procedure always use the 20 first elements of the array. F_i_l_e_ _c_o_u_n_t_,_ _b_l_o_c_k_ _c_o_u_n_t_ In the high level zone procedures of algol the two variables, file count and block count, are used in two ways: When a ta- pe positioning is initiated, file and block count denote the wanted final position. When a block transfer has been check- ed, file and block count denote the physical position corre- sponding to the end of that block. S_e_g_m_e_n_t_ _c_o_u_n_t_ The current value of segment count is used as the 4th word of every message sent to a device by the high level zone procedures. It will only have significance when the message is sent to a backing storage process, however. As soon as the message is sent, segment count is updated to correspond to a transfer of the next block of the backing storage area, (i.e. the segement number of the first segment in this block). \f F_r_e_e_ _p_a_r_a_m_e_t_e_r_ getzone6 The so called free parameter may contain anything if the zone is not used by the Fortran read/write system or by the procedures changevar, invar and outvar. It is set to zero when the zone is declared. The var-procedures (changevar, invar, and outvar) use the free parameter as a counter of the logical records generated or read by the procedures, and as an indication of whether or not the record checksum should be checked by invar. The fortran read/ write system uses the last bit of this parameter to signal if the latest call of read or write have used format or formato. A one in the last bit means that formato was used and a zero means that format was used. See ref. 9 for further details. P_a_r_t_i_a_l_ _w_o_r_d_ One element of the zone buffer consists of two words. Each of the words contains 3 characters like this: ch1 shift 16 + ch2 shift 8 + ch3. Partial word may after the call of a procedure on the character level contain this: After input:After output: ch2 shift 16 + ch3 shift 8 + 11 ch3 shift 16 + 1 shift 8 1 shift 8 + ch1 1 shift 16 1 shift 16 + ch1 shift 8 + ch2 Z_o_n_e_ _s_t_a_t_e_ The action of a high level zone procedure will in general depend on the latest operation upon the same zone. The following zone states are used: zone state: 0 positioned after open. 1 after character reading. 2 after repeatchar. 3 after character writing. 4 after declaration or after close. 5 after record input. 6 after record output. \f 7 after record swop. getzone6 8 after open on magnetic tape. 9 in sort. 10 format8000: after waittrans. 11 format8000: after waittrans. 12 as 14 13 format8000: ready for opentrans. '= 14 after some procedures not described in this manual. The high level zone procedures described in this manual use the zone state as shown in the following scheme: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ procedure zonestate zonestate _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _b_e_f_o_r_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _a_f_t_e_r_ _ _ _ _ _ _ _ _s_e_t_p_o_s_i_t_i_o_n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _0_,_1_,_2_,_3_,_5_,_6_,_7_,_8_ _ _ _ _ _ _ _ _ _ _0_ _ _ _ _ _ _ _ _ _ _o_p_e_n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _4_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _0_,_8_ _ _ _ _ _ _ read, readall, readchar, 0,1,2 1 _ _ _r_e_a_d_s_t_r_i_n_g_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ repeatchar 1,2 2 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _a_n_y_ _o_t_h_e_r_ _ _ _ _ _ _ _ _ _u_n_c_h_a_n_g_e_d_ _ _ _ outchar, outdate, outinteger, outtext, 0,3 3 _ _ _w_r_i_t_e_,_ _w_r_i_t_e_i_n_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _c_l_o_s_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _a_n_y_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _4_ _ _ _ _ _ _ _ _ _ _i_n_r_e_c_,_ _i_n_r_e_c_6_,_ _i_n_v_a_r_ _ _ _ _ _ _ _ _ _ _ _ _ _0_,_5_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _5_ _ _ _ _ _ _ _ _ _ _o_u_t_r_e_c_,_ _o_u_t_r_e_c_6_,_ _o_u_t_v_a_r_ _ _ _ _ _ _ _ _ _ _0_,_6_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _6_ _ _ _ _ _ _ _ _ _ _s_w_o_p_r_e_c_,_ _s_w_o_p_r_e_c_6_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _0_,_7_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _7_ _ _ _ _ _ _ _ _ _ _c_h_a_n_g_e_r_e_c_,_ _c_h_a_n_g_e_r_e_c_6_ _ _ _ _ _ _ _ _ _ _ _5_,_6_,_7_ _ _ _ _ _ _ _ _ _ _ _u_n_c_h_a_n_g_e_d_ _ _ _ _ _ _c_h_a_n_g_e_v_a_r_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _6_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _6_ _ _ _ _ _ _ _ _ _ _i_n_i_t_s_o_r_t_,_ _s_t_a_r_t_s_o_r_t_6_ _ _ _ _ _ _ _ _ _ _ _ _ _ _4_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _9_ _ _ _ _ _ _ _ changekey6, deadsort, initkey, liftsort, 9 9 _ _ _n_e_w_s_o_r_t_,_ _o_u_t_s_o_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _o_p_e_n_t_r_a_n_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _0_,_1_3_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _3_ _ _ _ _ _ _ _ _ _ _r_e_a_d_f_i_e_l_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _1_,_2_,_1_0_,_1_1_ _ _ _ _ _ _ _ _ _ _ _ _ _1_,_2_ _ _ _ _ _ _ _ _ _w_a_i_t_t_r_a_n_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _0_,_1_,_2_,_1_0_,_1_1_ _ _ _ _ _ _ _ _ _ _1_0_,_1_1_ _ _ _ _ _ _ _ _c_l_o_s_e_t_r_a_n_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _3_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _1_3_ _ _ _ _ _ _ \f E_x_a_m_p_l_e_ _1_: Let z be declared as z(2*128,2,stderror) andgetzone6 opened as the backing storage area <:sldata15:'. After 130 calls of >outrec6(z,4)> the call getzone6(z,ia) will yield something which only depends on the value of base buffer area: variable contains ia(1),modekind 4 ia(2)-ia(5), process name <:sldata15:',0 ia(6),name table address Some address ia(7),filecount 0 ia(8),block count 0 ia(9),segment count 1 (prepared for output of the next segment) ia(10),give up mask As defined by open ia(11),free parameter 0 ia(12),partial word 1 ia(13),zone state 6 (after outrec6) ia(14),record base 30 515 (base buffer + 4*128 + 4) ia(15),last halfword 31 023 (base buffer + 4*256) ia(16),record length 4 ia(17),used share 2 (one block output already) ia(18),number of shares 2 ia(19),base buffer area 29 999 ia(20),buffer length 256 E_x_a_m_p_l_e_ _2_: character output to primary store: Numbers may be transformed to character form by means of write. The only problem is that you do not want to output the characters on a device, but rather keep them in long variables as text portions. This is possible by means of getzone6,setzone6. \f \f «eof»