@X @~
~L3 COUK1247
80
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H             BSC221
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL
~
~
                                                            ISSUE 11~
~V9 -1
~P
~V9 1
~YBSC221
~S~M~OBASIC IMPLEMENTATION MANUAL
~S~M~OSection 22
~S~OSection 22 Input Routines
~S~O1. General Description
~BThis section provides for the run-time support of input
statements of BASIC programs.
~BThe data contained within all the DATA statements of a program
unit is held as a vector of bytes embedded within the code, and the
READ statements access data from this vector.
~BThe INPUT statements access data via channels which have a mapping
onto MUSS streams.
~S~O2. Interfaces
~S~O2.1 Section Interfaces Used
~
   Section 20   (Run-time configuration)~
   Section 21   (Program control)~
   Section 27   (File control)~
~S~O2.2 Section Interface
~
Exported Procedures:~
   BIO.READ~
   BIO.END.READ~
   BIO.INPUT~
   BIO.END.INPUT~
   BIO.SET.REF~
   BIO.IN.I8~
   BIO.IN.I16~
   BIO.IN.I32~
   BIO.IN.R32~
   BIO.IN.R64~
   BIO.IN.STRING~
   BIO.LINE.IN.STRING~
   BIO.MAT.IN.I8~
   BIO.MAT.IN.I16~
   BIO.MAT.IN.I32~
   BIO.MAT.IN.R32~
   BIO.MAT.IN.R64~
   BIO.MAT.IN.STRING~
   BIO.ELAPSED~
   BIO.REDIM1~
   BIO.REDIM2~
~
Configuration Parameters:~
   IN.BUF.Z~
   CHAN.TAB.Z~
   MAX.STR.Z~
   MAX.I16.DIGS~
   MAX.I32.DIGS~
   MAX.R.EXP~
   MIN.R.EXP~
   MAX.R.MANT~
   MIN.R.MANT~
~S11) BIO.READ(PTR.TO.DATA,BUFFER.POSITION<LO16>,STATUS<IN16>)
~BThis procedure is called at the start of a BASIC READ statement.
P1 is a bounded pointer to a byte vector containing the data from
all the DATA statements within the current program unit.  P2 indexes
the next available byte.  P3 is encoded as follows:~
~T# 13
~
   Bit 0 = 1~I'Missing' recovery label specified.~
~S12) BIO.END.READ()POSITION
~BThis procedure is called at the end of a BASIC READ statement and
returns as its result the position of the next available byte within
the current DATA.BUFFER.
~S13) BIO.INPUT(CHANNEL<IN16>,STATUS<IN16>,PROMPT,TIME<IN32>)
~BThis procedure is called at the start of each BASIC INPUT
statement.  P1 specifies the channel number from which input
is to be taken.  P2 is bit encoded as follows:~
~T# 13
~
   Bit 0 = 1~IMissing recovery specified in BIO.SET.REC.~
   Bit 1 = 1~IElapsed time required.~
   Bit 3 = 1~IBEGIN record setter specified.~
   Bit 4 = 1~IEND record setter specified.~
   Bit 5 = 1~ITIMEOUT specified in P4.~
   Bit 6 = 1~IStatement is LINE INPUT.~
   Bit 7 = 1~INEXT record setter specified.~
   Bit 8 = 1~ISAME record setter specified.~
   Bit 9 = 1~IREAD from channel.~
~
P3 specifies the prompt string to be issued when requesting
input.  If P3 is a nil pointer the default "->" prompt is assumed.  P4 specifies
a TIMEOUT value in seconds.
~S14) BIO.END.INPUT()
~BThis procedure is called at the end of a BASIC INPUT statement,
and checks that the input-reply ends correctly.  If not, an
exception is generated, and a request is issued to resupply the
input-reply.
~S15) BIO.SET.REC(REC.LABEL)
~BThis procedure is called to set the recovery label, specified by P1,
to which control is transferred when a
'missing' condition is specified in a call to BIO.READ.
~S1 6) BIO.IN.I18()VALUE
 ~G7) BIO.IN.I16()VALUE~G~
 ~G8) BIO.IN.I32()VALUE~G~
 ~G9) BIO.IN.R32()VALUE~G~
~G10) BIO.IN.R64()VALUE~G~
~G11) BIO.IN.STR(PTR.TO.STRING)~G~
~G12) BIO.LINE.IN.STR(PTR.TO.STRING)~G~
~BThe above seven procedures each read an item of the specified type
from the current input channel or data buffer,
in a manner as specified by the
BASIC STANDARD.  The type of the item read is checked for
consistency, and if correct the numeric input procedures
return the value while the string input procedures
assign the string value to the string variable pointed at by P1.
~S113) BIO.MAT.IN.I8(MATRIX.PTR,^MATRIX.DESC,STATUS<IN16>)
~BThis procedure reads an array of INTEGER 8 type from the
current input channel or data buffer.  P1
is a bounded pointer to the array into
which the values are input.  P2 gives the total number of elements
in the array, and P3 specifies the sort of array, as follows:~
~3
~
   Bits 0 and 1 encoded as~
            = 1 vector~
            = 2 matrix~
   Bit  2   = 1 variable length vector~
~0
~
For a variable length vector the the upper bound
of the array descriptor is updated.
The procedure checks that the size of the array does not exceed
the storage allocated for it.
~S114) BIO.MAT.IN.I16
~G15) BIO.MAT.IN.I32~
~G16) BIO.MAT.IN.R32~G~
~G17) BIO.MAT.IN.R64~G~
~G18) BIO.MAT.IN.STR~G~
~BThe above five procedures have the same parameter specification
and operate in an analogous manner to the BIO.MAT.IN.I8 procedure,
except that the type of the array element is different.
~S119) BIO.ELAPSED()TIME<IN32>
~BThis procedures returns the elapsed time in seconds between the
initial input request (BIO.INPUT) and the current time.
~S120) BIO.SKIP.REST()
~BThis procedure causes the remainder of the record from which the
last item was taken to be ignored.  Its use is only valid for
non-stream files.
~S121) BIO.REDIM1(^MATRIX.DESC,ARRAY.SIZE,LBOUND1,UBOUND1)
~BThis procedure updates P1 according to the requested dimensions
specified by P3 and P4.  An exception is generated if the size of
the redimensioned array exceeds the storage allocated as specified
by P2.
~S122) BIO.REDIM2(^MATRIX.DESC,ARRAY.SIZE,LBOUND1,UBOUND1,~
               ~GLBOUND2,UBOUND2)~G~
~BAs above but for 2-dimensional arrays.
~S~O3. Implementation
~S~O3.1 Outline of Operation
~BAll numeric input is performed by the internal procedure GET.NUM,
which reads in a number in any format, placing characters in a
buffer, until a valid 'separator' is encountered.  Input procedures
such as BIO.IN.I16 then obtain a corresponding numeric value from
the buffer.
~S~O3.2 Data Structures
~BTo allow for nested input statements, a stack of status information
is maintained.  At the beginning of an input statement, BIO.INPUT
is called, and the next free location on the stack is selected.  At
the end of an input statement, BIO.END.INPUT is called which reselects
the input stream that was current when BIO.INPUT was last called,
and resets the input stack.  The input stack is a vector of type I.BLK,
with the following fields:~
~T# 4 20
~
#: I.STAT~IA status variable, bit encoded as follows:~
~3
#~IBits 0-9 as in BIO.INPUT~
#~IBit 10=0 READ statement~
#~I      =1 INPUT statement~
#~IBit 11=0 separator not required~
#~I      =1 separator required~
#~IBit 12=0 Input from channel 0~
#~I      =1 Input from file~
#~IBit 13=1 MAT statement~
~0
~
#: TIME.LIMIT~IThe currently specified time-limit, -1 if none.~
~
#: WCHAN~IThe MUSS channel number on which the user process is
accepting input.  Used to implement the "time-limit" option.~
~
#: I.STREAM~IThe number of the MUSS stream that was current when
BIO.INPUT was called.~
~
#: READING~IA variable indicating whether a READ operation is in progress.~
~3
#~I0 = Not in progress.~
#~I1 = In progress.~
~0
~
#: CUR.CHAR~IThe character most recently accessed, either from
an INPUT channel or a DATA-statement buffer.~
~
#: REC.LAB~IA label variable holding the current label to be used
to recover from non-fatal input exceptions.~
~
#: MISSING.LAB~IA label variable holding the recovery address for
a "missing" condition.~
~
#: T.START~IThe value returned by TIME.AND.DATE when BIO.INPUT was
called.~
~
#: C.CHAN.I~IIndex into CHAN.TAB [BSC27] of the currently selected
input channel.~
~

#: PROMPT.PTR~IA bounded pointer to the current prompt string.  If no
prompt is specified, the pointer is "->".~
~
#: GET.IN.PROC~IA procedure variable holding the address of the procedure
to be used for getting characters in response to a READ or INPUT
statement.~
~
#: SEP.PROC~IThe address of the procedure to be used for
processing separators.~
~T# 20
~
I.STK~IThe input stack of size I.STK.Z.~
~
LAST.I~IIndex into I.STK.~
~
IN.BUF~IA vector of bytes into which input items are placed (either
from READ or INPUT statements) prior to further processing to
yield numeric or string values.~
~
IB.I~IIndex into IN.BUF.~
~
IN.EXP~IHolds the value of the exponent of a numeric item in the
character buffer IN.BUFF.~
~
IN.DIG.CNT~IHolds the number of digits in the integer mantissa
in IN.BUFF.~
~
IN.SIGN~IHolds the sign of the mantissa of the integer mantissa in
IN.BUFF.~
~
DATA.PTR~IA bounded pointer to the current DATA-STATEMENT buffer.~
~
DATA.POS~IThe position in the current DATA-STATEMENT buffer at the
start of the most recent READ statement.~
~
DI~IIndex into the current DATA-STATEMENT buffer.~
~
BUFF.Z~IThe size in bytes of the current DATA-statement byte vector.~
~Y
~V9 -1
~P
~D15
~HFLOWCHARTS
~
~
~H                BSC221
~V9 -1
~F
///16
@TITLE BSC22(1,11)
@COL 1S-2R-3R-4R-5R-6R-7F
@FLOW 1-2-3-4-5-6-7
@BOX 1.0
INPUT ROUTINES
@BOX 2.0
IMPORTS
@BOX 3.0
TYPE DECLARATIONS
@BOX 4.0
LITERAL DECLARATIONS
@BOX 5.0
GLOBAL VARIABLE DECLARATIONS
@BOX 6.0
PROCEDURES IN MODULE
   LIBRARY PROCS
   BIO.READ[22.1]
   BIO.END.READ[22.2]
   BIO.INPUT[22.3]
   BIO.END.INPUT[22.4]
   BIO.SET.REC[22.5]
   BIO.ELAPSED[22.6]
   BIO.IN.I16[22.7]
   BIO.IN.I32[22.8]
   BIO.IN.R32[22.9]
   BIO.IN.R64[22.10]
   BIO.IN.STR[22.11]
   BIO.LINE.IN.STR[22.12]
   BIO.MAT.IN.I16[22.13]
   BIO.MAT.IN.I32[22.14]
   BIO.MAT.IN.R32[22.15]
   BIO.MAT.IN.R64[22.16]
   BIO.MAT.IN.STR[22.17]
   BIO.SKIP.REST[22.18]
   BIO.MAT.IN.I8[22.19]
  BIO.REDIM.1[22.32]
   BIO.REDIM.2[22.33]

   INTERNAL PROCS
   GET.NUM[22.20]
   GET.I16[22.21]
   GET.I32[22.22]
   GET.R64[22.23]
   MAT.IN[22.24]
   PROCESS.READ.SEP[22.25]
   PROCESS.INP.SEP[22.26]
   READ.CH[22.27]
   INPUT.CH[22.28]
   INPUT.EXCEPTION[22.29]
   BIO.IN.I8[22.30]
   IN.WAIT[22.31]
@BOX 7.0
END
@BOX 1.1
::INPUT ROUTINES
@BOX 2.1
#BSC22/1
MODULE(BIO.READ, BIO.END.READ, BIO.INPUT, BIO.END.INPUT, BIO.SET.REC,
        BIO.ELAPSED, BIO.IN.I16, BIO.IN.I32, BIO.IN.R32, BIO.IN.R64,
        BIO.IN.STR, BIO.LINE.IN.STR, BIO.MAT.IN.I16, BIO.MAT.IN.I32,
        BIO.MAT.IN.R32, BIO.MAT.IN.R64, BIO.MAT.IN.STR, BIO.SKIP.REST,
        BIO.MAT.IN.I8, BIO.IN.I8,BIO.REDIM.1,BIO.REDIM.2,LAST.I,G.LAB);
@BOX 3.1
*GLOBAL 2;
PSPEC PROC.TYP1()/$LO8;
PSPEC PROC.TYP2();
PROC PROC.TYP1;
END
PROC PROC.TYP2;
END
TYPE I.BLK IS
   $IN16 I.STAT
   $IN TIME.LIMIT,W.CHAN,I.STREAM
   $LO8 READING,CUR.CHAR
   $LA REC.LAB,MISSING.LAB
   $IN32 T.START,C.CHAN.I
   ADDR[$LO8] PROMPT.PTR
   ADDR PROC.TYP1 GET.IN.PROC
   ADDR PROC.TYP2 SEP.PROC;
TYPE MAT.TYP IS ADDR [$IN16] MATI16
             OR ADDR [$IN32] MATI32
             OR ADDR [$RE32] MATR32
             OR ADDR [$RE64] MATR64
             OR ADDR [$LO8] MATL8
             OR ADDR [$IN8] MATI8;

@BOX 4.1
@BOX 5.1
*GLOBAL 2;
LITERAL / ADDR[$LO8] NIL.L8 =;
ADDR [$LO8] DATA.PTR;
$IN  DI, IB.I, IN.EXP, IN.DIG.CNT,
     BUFF.Z,IN.SIGN;
I.BLK[I.STK.Z] I.STK;
$LA G.LAB;
$IN16 LAST.I;
$LO8 [IN.BUF.Z] IN.BUF;
*GLOBAL 7;
DATAVEC SYS.PROMPT($LO8)
"->"
END
DATAVEC I8.CHECK ($IN16)
3  1  27  10
END
DATAVEC I16.CHECK ($IN16)
5  3  2767 1000
END
*GLOBAL 0;
@BOX 6.1
LSPEC BIO.SKIP.REST ();
LSPEC BIO.ELAPSED () / $IN32;
LSPEC BIO.READ (ADDR [$LO8], $LO16, $IN16);
LSPEC BIO.END.READ () / $LO16;
LSPEC BIO.INPUT ($IN16, $IN16, ADDR [$LO8], $IN32);
LSPEC BIO.END.INPUT ();
LSPEC BIO.SET.REC ($LA);
LSPEC BIO.IN.I8 () / $IN8;
LSPEC BIO.IN.I16 () / $IN16;
LSPEC BIO.IN.I32 () / $IN32;
LSPEC BIO.IN.R32 () / $RE32;
LSPEC BIO.IN.R64 () / $RE64;
LSPEC BIO.IN.STR (ADDR [$LO8]);
LSPEC BIO.LINE.IN.STR (ADDR [$LO8]);
LSPEC BIO.MAT.IN.I16 (ADDR [$IN16], ADDR[ADDR], $IN16);
LSPEC BIO.MAT.IN.I32 (ADDR [$IN32], ADDR[ADDR], $IN16);
LSPEC BIO.MAT.IN.R32 (ADDR [$RE32], ADDR[ADDR], $IN16);
LSPEC BIO.MAT.IN.R64 (ADDR [$RE64], ADDR[ADDR], $IN16);
LSPEC BIO.MAT.IN.STR (ADDR [$LO8], ADDR[ADDR],$IN16, $IN16);
LSPEC BIO.MAT.IN.I8 (ADDR [$LO8], ADDR[ADDR], $IN16);
LSPEC BIO.REDIM.1(ADDR[ADDR],ADDR,ADDR,ADDR);
LSPEC BIO.REDIM.2(ADDR[ADDR],ADDR,ADDR,ADDR,ADDR,ADDR);
PSPEC GET.NUM ();
PSPEC GET.I16 ($IN) / $IN16;
PSPEC GET.I32 () / $IN32;
PSPEC GET.R64 () / $RE64;
PSPEC MAT.IN (MAT.TYP, $IN, ADDR[ADDR],$IN, $IN);
PSPEC PROCESS.READ.SEP ();
PSPEC PROCESS.INP.SEP ();
PSPEC READ.CH () / $LO8;
PSPEC INPUT.CH () / $LO8;
PSPEC INPUT.EXCEPTION ($IN,ADDR[$LO8],$IN,$IN);
PSPEC IN.WAIT();
#BSC22.1
#BSC22.2
#BSC22.3
#BSC22.4
#BSC22.5
#BSC22.6
#BSC22.7
#BSC22.8
#BSC22.9
#BSC22.10
#BSC22.11
#BSC22.12
#BSC22.13
#BSC22.14
#BSC22.15
#BSC22.16
#BSC22.17
#BSC22.18
#BSC22.19
#BSC22.20
#BSC22.21
#BSC22.22
#BSC22.23
#BSC22.24
#BSC22.25
#BSC22.26
#BSC22.27
#BSC22.28
#BSC22.29
#BSC22.30
#BSC22.31
#BSC22.32
#BSC22.33
@BOX 7.1
*END
@END
//17
@TITLE BSC22/1(1,11)
@COL 1S-2R
@FLOW 1-2
@BOX 1.0
IMPORTS
@BOX 2.0
@BOX 1.1
::IMPORTS
@BOX 2.1
$AD PW0, PW1, PW2, PW3, PW4, PW5, PW6;
$LO64 PWW1, PWW2;
IMPORT LITERAL IN.BUF.Z, I.STK.Z, CHAN.TAB.Z;
$IN C.OUT.STR;
LSPEC CURRENT.INPUT()/$IN;
LSPEC CURRENT.OUTPUT()/$IN;
LSPEC SELECT.INPUT($IN);
LSPEC SELECT.OUTPUT($IN);
LSPEC I.ENQ()/$IN;
LSPEC NEWLINES($IN);
LSPEC CAPTION(ADDR[$LO8]);
LSPEC IMODE()/$IN32;
LSPEC INCH()/$IN;
LSPEC TIMEANDDATE();
LSPEC IN.BIN($IN)/$LO32;
LSPEC PROMPT(ADDR[$LO8]);
LSPEC IN.BACKSPACE($IN);
LSPEC IPOS()/$IN32;
LSPEC BREAKOUTPUT($IN);
LSPEC WAIT($LO,$IN);
PSPEC PROCESS.REC.SETTER($IN16,$IN16)/$LO8;
PSPEC CHAN.EXCEPTION($IN,$IN);
PSPEC BIO.EXCEPTION($IN16);
PSPEC EXCEPTION ($IN,ADDR[$LO8],$IN);
PSPEC BIO.SELECT.CHANNEL ($IN, $IN) / $IN;
IMPORT LITERAL SP, NL, MAX.I16.DIGS, MAX.I32.DIGS,BYTES.PER.SL;
TYPE CHAN.DATA IS
   $IN32 S.POS,S.REC,R.POS,R.REC
   $IN CHAN.NO, STREAM, STATUS
   $IN REC.SZ, POINTER, REC.NO, MARGIN, ZONE.W, COL.POS
   $IN16 PU.ID;
CHAN.DATA [CHAN.TAB.Z] CHAN.TAB;
$LO8 VAL.FN;
IMPORT LITERAL MAX.R.EXP, MIN.R.EXP;
IMPORT LITERAL $RE64 MAX.R.MANT,MIN.R.MANT;
@END
///16
@TITLE BSC22.1(1,11)
@COL 1S-2R-3R-5R-6R-4T-8R-10R-7F
@FLOW 1-2-3-5-6-4N-8-10-7
@FLOW 4Y-10
@BOX 1.0
BIO.READ(PTR.TO.DATA,BUFFER.POS, STATUS)
@BOX 2.0
STORE POINTER TO DATA BUFFER
@BOX 3.0
INITIALISE CURRENT
CHAR TO SPACE
@BOX 4.0
MISSING RECOVERY NOT SPECIFIED?
@BOX 5.0
NOTE SEPARATOR NOT REQUIRED
@BOX 6.0
SET UP GLOBAL PROCEDURE VARIABLES
FOR READ STATEMENT
@BOX 7.0
END
@BOX 8.0
NOTE RECOVERY LABEL
@BOX 10.0
NOTE KIND OF INPUT
STATEMENT IN GLOBAL
@BOX 1.1
PROC BIO.READ(PTR.TO.DATA,BUF.POS, STATUS);
@BOX 2.1
SELECT I.STK[1+>LAST.I];
STATUS => I.STAT;
SIZE (PTR.TO.DATA) => BUFF.Z;
PTR.TO.DATA => DATA.PTR;
@BOX 3.1
SP => CUR.CHAR;
@BOX 4.1
IF STATUS & %1 = 0
@BOX 5.1
%F7FF &> I.STAT;
BUF.POS - 1 => DI;
@BOX 6.1
^READ.CH => GET.IN.PROC;
^PROCESS.READ.SEP => SEP.PROC;
@BOX 7.1
END
@BOX 8.1
G.LAB => MISSING.LAB;
@BOX 10.1
%FBFF &> I.STAT;
@END
//16
@TITLE BSC22.2(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
END.READ() POSITION
@BOX 2.0
RETURN NEXT AVAILABLE
BYTE POSITION FOR CURRENT
DATA BUFFER
@BOX 3.0
END
@BOX 1.1
PROC BIO.END.READ;
@BOX 2.1
1 +> DI => BIO.END.READ;
1 -> LAST.I;
@BOX 3.1
END
@END
///17 27-JULY
@TITLE BSC22.3(1,11)
@COL 1S-7R-2T-8R-17R-18R-14T-3T-4R-5T-6R-10R-13R-11F
@COL 16C
@ROW 3-16
@FLOW 1-7-2N-8-17-18-14N-3N-4-5N-6-10-13-11
@FLOW 2Y-16
@FLOW 14Y-13
@FLOW 3Y-5
@FLOW 5Y-10
@BOX 1.0
BIO.INPUT(CHANNEL,STATUS,PROMPT,TIME)
@BOX 2.0
SELECT CHANNEL
[BSC27.17]
INCORRECT RECORD TYPE?
@BOX 3.0
ELAPSED TIME NOT REQUIRED
AND TIME-OUT NOT SPECIFIED
@BOX 4.0
READ CLOCK AND NOTE TIME
@BOX 5.0
NOT ONLINE (INTERACTIVE) INPUT?
@BOX 6.0
NOTE IF PROMPT STRING
SPECIFIED
@BOX 7.0
NOTE CURRENT INPUT STREAM
@BOX 8.0
SELECT INPUT STACK
@BOX 10.0
NOTE SEPARATOR NOT REQUIRED
@BOX 11.0
END
@BOX 13.0
NOTE KIND OF
STATEMENT IN GLOBAL
AND SET UP GLOBAL PROCEDURE VARIABLES
@BOX 14.0
READ FROM INTERNAL FILE?
@BOX 16.0
EXCEPTION
@BOX 17.0
PROCESS RECORD SETTER
@BOX 18.0
PROCESS MISSING RECOVERY
@BOX 1.1
PROC BIO.INPUT(CHAN,STAT,PROM,TIME);
$IN P,S,R.TYP;
$LO8 DATA.FND;
@BOX 2.1
BIO.SELECT.CHANNEL (CHAN, %1) => P;
SELECT CHAN.TAB[P];
STATUS & %60 => R.TYP;
IF STAT & %200 = 0 AND
   R.TYP /= %20
@BOX 3.1
IF STAT & %22 = 0
@BOX 4.1
TIME.AND.DATE();
PWW1 => T.START;
IF STAT & %20 /= 0 THEN
   IF TIME >= 0 THEN
   TIME => TIME.LIMIT
ELSE
    EXCEPTION(%14E,NIL.L8,TIME);
FI
FI;
1 <<- STREAM OF CHAN.TAB[C.CHAN.I]=>W.CHAN;
@BOX 5.1
NIL.L8 => PROMPT.PTR;
IF I.MODE() & %80 = 0
@BOX 6.1
IF PROM /= NIL.L8 THEN
   PART(PROM,1,PROM^[0]) => PROMPT.PTR;
ELSE
   ^SYS.PROMPT=>PROMPT.PTR;
FI
@BOX 7.1
CURRENT.INPUT() => S;
@BOX 8.1
SELECT I.STK[1+>LAST.I];
S => I.STREAM;
P => C.CHAN.I;
STAT => I.STAT;
@BOX 10.1
%F7FF &> I.STAT;
@BOX 13.1
IF CHAN/= 0 THEN
   %1000 !> I.STAT;
FI
%5000 !> STATUS;
%400 !> I.STAT;
^INPUT.CH => GET.IN.PROC;
^PROCESS.INP.SEP => SEP.PROC;
@BOX 11.1
END
@BOX 14.1
-1 => TIME.LIMIT;
IF STATUS & %60 = %40
@BOX 16.1
EXCEPTION(%15A,%"INPUT",0);
@BOX 17.1
$IN T;
0 => T;
IF STAT & %8 /= 0 THEN 1 => T
ELSE IF STAT & %10 /= 0 THEN 2 => T
ELSE IF STAT & %80 /= 0 THEN 3 => T
ELSE IF STAT & %100 /= 0 THEN 4 => T
FI FI FI FI;
PROCESS.REC.SETTER(C.CHAN.I,T) => DATA.FND;
@BOX 18.1
IF DATA.FND = 0 THEN
   IF STAT & %1 /= 0 THEN
      ;-> G.LAB;
   ELSE
      BIO.EXCEPTION(%1C);
   FI
FI
@END
///17
@TITLE BSC22.4(1,11)
@COL 1S-7T-9T-8R-2R-3T-4R-5R-6F
@COL 10T
@ROW 8-10
@FLOW 1-7N-9N-8-2-3N-4-5-6
@FLOW 9Y-10N-5
@FLOW 10Y-4
@FLOW 7Y-5
@FLOW 3Y-5
@BOX 1.0
BIO.END.INPUT()
@BOX 2.0
SKIP SPACES
@BOX 3.0
CURRENT CHAR NEWLINE?
@BOX 4.0
INPUT EXCEPTION(8003)
@BOX 5.0
RESELECT OLD INPUT STREAM
AND RESET INPUT STACK
@BOX 6.0
END
@BOX 7.0
READ FROM STREAM INTERNAL FILE?
@BOX 8.0
SET INPUT EXCEPTION
RECOVERY LABEL
@BOX 9.0
READ FROM SEQ INTERNAL FILE?
@BOX 10.0
GET BYTE
NOT END OF RECORD?
@BOX 1.1
PROC BIO.END.INPUT;
SELECT I.STK[LAST.I];
SELECT CHAN.TAB[C.CHAN.I];
@BOX 2.1
WHILE CUR.CHAR = SP DO
      GET.IN.PROC^() => CUR.CHAR
OD;
@BOX 3.1
IF CUR.CHAR = NL
@BOX 4.1
SP => CUR.CHAR;
IF I.STAT & %1000 = 0 THEN
   INPUT.EXCEPTION(%1B,NIL.L8,0,1);
ELSE
   CHAN.EXCEPTION(%59,C.CHAN.I);
FI
@BOX 5.1
SELECT.INPUT(I.STREAM);
1 -> LAST.I;
@BOX 6.1
END
@BOX 7.1
IF STATUS & %7C = %48
@BOX 8.1
L:
L => REC.LAB;
@BOX 9.1
IF STATUS & %7C = %44
@BOX 10.1
SELECT.INPUT(STREAM);
IF IN.CH() /= %FF
@END
///16
@TITLE BSC22.5(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
BIO.SET.REC(REC.LABEL)
@BOX 2.0
SAVE MISSING RECOVERY
LABEL IN GLOBAL
@BOX 3.0
END
@BOX 1.1
PROC BIO.SET.REC(LAB);
@BOX 2.1
LAB => G.LAB;
@BOX 3.1
END
@END
//16
@TITLE BSC22.6(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
BIO.ELAPSED()TIME
@BOX 2.0
COMPUTE TIME ELAPSED
SINCE CALL OF BIO.INPUT
@BOX 3.0
END
@BOX 1.1
PROC BIO.ELAPSED;
$IN32 T.NOW;
@BOX 2.1
SELECT I.STK[LAST.I];
TIME.AND.DATE();
PWW1 => T.NOW;
T.NOW - T.START => BIO.ELAPSED;
@BOX 3.1
END
@END
///17
@TITLE BSC22.7(1,11)
@COL 7T-8C-9R
@COL 1S-6T-2R-3R-4R-5F
@ROW 7-2
@FLOW 1-6N-2-3-4-5
@FLOW 6Y-7Y-9-5
@FLOW 7N-8
@BOX 1.0
BIO.IN.I16()VALUE
@BOX 2.0
SET INPUT EXCEPTION
RECOVERY LABEL
@BOX 3.0
READ NUMERIC ITEM FROM
DATA BUFFER/INPUT CHANNEL
INTO INPUT BUFFER
[BSC22.20]
@BOX 4.0
GET I16 VALUE
FROM INPUT BUFFER
[BSC22.21]
@BOX 5.0
END
@BOX 6.0
READ FROM INTERNAL FILE?
@BOX 7.0
GET HEADER BYTE FOR
NEXT DATUM
CORRECT TYPE?
@BOX 8.0
EXCEPTION
@BOX 9.0
READ DATUM
@BOX 1.1
PROC BIO.IN.I16;
SELECT I.STK[LAST.I];
SELECT CHAN.TAB[C.CHAN.I];
@BOX 2.1
L:
L => REC.LAB;
@BOX 3.1
GET.NUM();
@BOX 4.1
GET.I16(1) => BIO.IN.I16;
@BOX 5.1
END
@BOX 6.1
IF STATUS & %60 = %40
@BOX 7.1
$LO8 BYT;
IF IN.CH()=>BYT = %2
@BOX 8.1
IF BYT = %FF THEN
   CHAN.EXCEPTION(%1C,C.CHAN.I);
ELSE
   CHAN.EXCEPTION(%54,C.CHAN.I);
FI
@BOX 9.1
IN.BIN(2) => BIO.IN.I16;
@END
///17
@TITLE BSC22.8(1,11)
@COL 7T-8C-9R
@COL 1S-6T-2R-3R-4R-5F
@ROW 7-2
@FLOW 1-6N-2-3-4-5
@FLOW 6Y-7Y-9-5
@FLOW 7N-8
@BOX 1.0
BIO.IN.I32()VALUE
@BOX 2.0
SET INPUT EXCEPTION
RETURN LABEL
@BOX 3.0
READ NUMERIC ITEM FROM
DATA BUFFER/INPUT CHANNEL
INTO INPUT BUFFER
[BSC22.20]
@BOX 4.0
GET I32 VALUE FROM
INPUT BUFFER
[BSC22.22]
@BOX 5.0
END
@BOX 6.0
READ FROM INTERNAL FILE?
@BOX 7.0
GET HEADER BYTE
FOR NEXT DATUM
CORRECT TYPE?
@BOX 8.0
EXCEPTION
@BOX 9.0
READ DATUM
@BOX 1.1
PROC BIO.IN.I32;
SELECT I.STK[LAST.I];
SELECT CHAN.TAB[C.CHAN.I];
@BOX 2.1
L:
L => REC.LAB;
@BOX 3.1
GET.NUM();
@BOX 4.1
GET.I32() => BIO.IN.I32;
@BOX 5.1
END
@BOX 6.1
IF STATUS & %60 = %40
@BOX 7.1
$LO8 BYT;
IF IN.CH()=>BYT = %4
@BOX 8.1
IF BYT = %FF THEN
   CHAN.EXCEPTION(%1C,C.CHAN.I);
ELSE
   CHAN.EXCEPTION(%54,C.CHAN.I);
FI
@BOX 9.1
IN.BIN(4) => BIO.IN.I32;
@END
///17
@TITLE BSC22.9(1,11)
@COL 7T-8C-9R
@COL 1S-6T-2R-3R-4F
@ROW 7-2
@FLOW 1-6N-2-3-4
@FLOW 6Y-7Y-9-4
@FLOW 7N-8
@BOX 1.0
BIO.IN.R32()VALUE
@BOX 2.0
SET INPUT EXCEPTION RETURN LABEL
@BOX 3.0
GET R64 VALUE
[BSC22.10]
AND CONVERT TO R32
@BOX 4.0
END
@BOX 6.0
READ FROM STREAM FILE?
@BOX 7.0
GET HEADER BYTE FOR
NEXT DATUM
CORRECT TYPE?
@BOX 8.0
EXCEPTION
@BOX 9.0
READ DATUM
@BOX 1.1
PROC BIO.IN.R32;
SELECT I.STK[LAST.I];
SELECT CHAN.TAB[C.CHAN.I];
@BOX 2.1
L:
L => REC.LAB;
@BOX 3.1
BIO.IN.R64() => BIO.IN.R32;
@BOX 4.1
END
@BOX 6.1
IF STATUS & %60 = %40
@BOX 7.1
$LO8 BYT;
IF IN.CH()=>BYT = %8
@BOX 8.1
IF BYT = %FF THEN
   CHAN.EXCEPTION(%1C,C.CHAN.I);
ELSE
   CHAN.EXCEPTION(%54,C.CHAN.I);
FI
@BOX 9.1
IN.BIN(4) => BIO.IN.R32;
@END
///17
@TITLE BSC22.10(1,11)
@COL 7T-8C-9R
@COL 1S-6T-2R-3R-4R-5F
@ROW 7-2
@FLOW 1-6N-2-3-4-5
@FLOW 6Y-7Y-9-5
@FLOW 7N-8
@BOX 1.0
BIO.IN.R64()VALUE
@BOX 2.0
SET INPUT EXCEPTION RETURN LABEL
@BOX 3.0
READ NUMERIC ITEM FROM
DATA BUFFER/INPUT CHANNEL
INTO INPUT BUFFER
[BSC22.20]
@BOX 4.0
GET R64 VALUE FROM
DATA BUFFER
[BSC22.23]
@BOX 5.0
END
@BOX 6.0
READ FROM INTERNAL FILE?
@BOX 7.0
GET HEADER FOR
NEXT DATUM
CORRECT TYPE?
@BOX 8.0
EXCEPTION
@BOX 9.0
READ DATUM
@BOX 1.1
PROC BIO.IN.R64;
SELECT I.STK[LAST.I];
SELECT CHAN.TAB[C.CHAN.I];
@BOX 2.1
L:
L => REC.LAB;
@BOX 3.1
GET.NUM();
@BOX 4.1
GET.R64() => BIO.IN.R64;
@BOX 5.1
END
@BOX 6.1
IF STATUS & %60 = %40
@BOX 7.1
$LO8 BYT;
IF IN.CH()=>BYT = %10
@BOX 8.1
IF BYT = %FF THEN
   CHAN.EXCEPTION(%1C,C.CHAN.I);
ELSE
   CHAN.EXCEPTION(%54,C.CHAN.I);
FI
@BOX 9.1
$LO64 R;
IN.BIN(4) <<- 32 ! IN.BIN(4) => R => BIO.IN.R64;
@END
///17
@TITLE BSC22.11(1,11)
@COL 26T-27C-28R-11T
@COL 1S-25T-3R-4R-5T-6R-7T-8T-20C-9R-10F
@COL 12T-13T-21C-14R-15R-16T-17T-18R-19C
@ROW 26-3
@ROW 6-12
@ROW 11-14
@ROW 10-19
@FLOW 1-25N-3-4-5N-6-7N-8Y-9-6
@FLOW 25Y-26Y-28
@FLOW 26N-27
@FLOW 8N-20
@FLOW 5Y-12N-13Y-14-15-16N-17N-13
@FLOW 13N-21
@FLOW 7Y-11N-10
@FLOW 11Y-8
@FLOW 12Y-19
@FLOW 16Y-18-10
@FLOW 17Y-19
@BOX 1.0
BIO.IN.STR (RESULT.STR.PTR)
@BOX 3.0
SET INPUT EXCEPTION
RETURN LABEL AND
GET MAX SIZE OF RESULT
@BOX 4.0
PROCESS SEPARATOR
[BSC22.25/26]
@BOX 5.0
CHAR NOT "?
@BOX 6.0
GET NEXT CHAR
@BOX 7.0
IS CHAR "?
@BOX 8.0
NOT STRING OVERFLOW ?
@BOX 9.0
STORE CHAR TO RESULT &

INCREMENT CHAR COUNT
@BOX 10.0
END
@BOX 11.0
GET NEXT CHAR
IS IT "?
@BOX 12.0
NOT A PLAIN STRING CHAR?
@BOX 13.0
NOT STRING OVERFLOW ?
@BOX 14.0
STORE CHAR TO RESULT &
INCREMENT CHAR COUNT
@BOX 15.0
GET NEXT CHAR
@BOX 17.0
NOT AN UNQUOTED
STRING CHAR?
@BOX 16.0
 SEPARATOR?
[IE COMMA OR NL]
@BOX 18.0
BACKTRACK DOWN BUFFER
UNTIL CHAR /= SPACE
@BOX 19.0
INPUT.EXCEPTION
@BOX 20.0
INPUT EXCEPTION
@BOX 21.0
INPUT EXCEPTION
@BOX 25.0
READ FROM INTERNAL FILE?
@BOX 26.0
GET HEADER FOR DATUM
CORRECT TYPE?
@BOX 27.0
EXCEPTION
@BOX 28.0
READ STRING DATUM
@BOX 1.1
PROC BIO.IN.STR (RES);
DATAVEC CHAR.TYP ($LO8)
%0[43] %80 %0 %80[2] %0 %80[10] %0[7]
%80[26] %0[6] %80[26] %0[5]
END
$IN CNT, SZ;
$LO8[1]CAP.CH;
SELECT I.STK[LAST.I];
SELECT CHAN.TAB[C.CHAN.I];
@BOX 3.1
L:
L => REC.LAB;
0 => IB.I;
0 => CNT;
1 => READING;
SIZE (RES) => SZ;
@BOX 4.1
SEP.PROC^();
@BOX 5.1
IF CUR.CHAR /= '"
@BOX 6.1
GET.IN.PROC^() => CUR.CHAR;
@BOX 7.1
IF CUR.CHAR = '"
@BOX 8.1
IF CNT < SZ
@BOX 9.1
CUR.CHAR => RES ^[1+>IB.I];
1 +> CNT;
@BOX 10.1
CNT => RES ^[0];
0 => READING;
END
@BOX 11.1
IF GET.IN.PROC^() => CUR.CHAR = '"
@BOX 12.1
IF CHAR.TYP[CUR.CHAR] & %80 = 0
@BOX 13.1
IF CNT < SZ
@BOX 14.1
CUR.CHAR => RES^[1+>IB.I];
1+>CNT;
@BOX 15.1
GET.IN.PROC^() => CUR.CHAR;
@BOX 17.1
IF [CHAR.TYP[CUR.CHAR] & %80 = 0] AND [CUR.CHAR /= SP]
@BOX 16.1
IF CUR.CHAR = %2C OR CUR.CHAR =  %0A
@BOX 18.1
1+>IB.I;
WHILE RES ^[1->IB.I] = SP DO 1->CNT OD;
@BOX 19.1
CUR.CHAR => CAP.CH [0];
IF I.STAT & %1000 = 0 THEN
   INPUT.EXCEPTION(%1E,^CAP.CH,0,0);
ELSE
   CHAN.EXCEPTION(%56,C.CHAN.I);
FI
@BOX 20.1
IF I.STAT & %1000 = 0 THEN
IF I.STAT & %2000 /= 0 THEN
   INPUT.EXCEPTION (%13C,NIL.L8,0,0)
ELSE
   INPUT.EXCEPTION (%13B,NIL.L8,0,0)
FI
ELSE CHAN.EXCEPTION(%55,C.CHAN.I);
FI
@BOX 21.1
IF I.STAT & %1000 = 0 THEN
IF I.STAT & %2000 /= 0 THEN
   INPUT.EXCEPTION (%13C,NIL.L8,0,0)
ELSE
   INPUT.EXCEPTION (%13B,NIL.L8,0,0)
FI
ELSE CHAN.EXCEPTION(%55,C.CHAN.I);
FI
@BOX 25.1
IF STATUS & %60 = %40
@BOX 26.1
$LO8 BYT;
IF IN.CH()=>BYT = %1
@BOX 27.1
IF BYT = %FF THEN
   CHAN.EXCEPTION(%1C,C.CHAN.I);
ELSE
  CHAN.EXCEPTION(%54,C.CHAN.I);
FI
@BOX 28.1
IF IN.CH()=>SZ < SIZE(RES) THEN
   0 => CNT;
   FOR SZ DO
      IN.CH() => RES^[1+>CNT]
   OD
   CNT => RES^[0];
ELSE
   CHAN.EXCEPTION(%55,C.CHAN.I);
FI
EXIT;
@END
///17 17-JULY
@TITLE BSC22.12(1,11)
@COL 1S-11R-2R-3R-4T-9T-10C-5R-7R-8F
@FLOW 1-11-2-3-4N-9Y-5-3
@FLOW 9N-10
@FLOW 4Y-7-8
@BOX 1.0
BIO.LINE.IN.STR (RESULT.STR.PTR)
@BOX 2.0
INITIALISE CHAR COUNT
AND GET MAX SIZE OF RESULT
@BOX 3.0
GET NEXT CHAR
@BOX 4.0
CHAR END-OF-LINE?
@BOX 5.0
STORE CHAR IN INPUT
BUFFER
@BOX 7.0
SET UP BYTE COUNT IN RESULT
@BOX 8.0
END
@BOX 9.0
NOT STRING OVERFLOW ?
@BOX 10.0
INPUT EXCEPTION
@BOX 11.0
SET INPUT EXCEPTION RETURN LABEL
@BOX 1.1
PROC BIO.LINE.IN.STR (RES);
$IN SZ,CNT;
SELECT I.STK[LAST.I];
SELECT CHAN.TAB[C.CHAN.I];
@BOX 2.1
0 => IB.I;
SIZE (RES) => SZ;
@BOX 3.1
INPUT.CH() => CUR.CHAR;
@BOX 4.1
IF CUR.CHAR = NL
@BOX 5.1
CUR.CHAR => RES ^[1+>IB.I];
@BOX 7.1
IB.I => RES ^[0];
@BOX 8.1
END
@BOX 9.1
IF IB.I < SZ
@BOX 10.1
IF I.STAT & %1000 = 0 THEN
IF I.STAT & %2000 /= 0 THEN
   INPUT.EXCEPTION (%13E,NIL.L8,0,0)
ELSE
   INPUT.EXCEPTION (%13D,NIL.L8,0,0)
FI
ELSE
   CHAN.EXCEPTION(%55,C.CHAN.I);
FI
@BOX 11.1
L:
L => REC.LAB;
@END
///15
@TITLE BSC22.13(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
BIO.MAT.IN.I16(MATRIX.PTR,MAT.DESC,STATUS)
@BOX 2.0
CALL MAT.IN FOR I16 TYPE
@BOX 3.0
END
@BOX 1.1
PROC BIO.MAT.IN.I16(MAT.PTR,MD,STATUS);
MAT.TYP M;
@BOX 2.1
MAT.PTR => MAT.I16 OF M;
MAT.IN(M,STATUS,MD,1,0) ;
@BOX 3.1
END
@END
///15
@TITLE BSC22.14(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
BIO.MAT.IN.I32 (MAT.PTR, MAT.DESC, STATUS)
@BOX 2.0
CALL MAT.IN FOR I32 TYPE
[BSC22.24]
@BOX 3.0
END
@BOX 1.1
PROC BIO.MAT.IN.I32 (MAT.PTR, MD, STATUS);
MAT.TYP M;
@BOX 2.1
MAT.PTR => MAT.I32 OF M;
MAT.IN (M, STATUS, MD,1, 1) ;
@BOX 3.1
END
@END
///15
@TITLE BSC22.15(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
BIO.MAT.IN.R32 (MAT.PTR, MD, STATUS)
@BOX 2.0
CALL MAT.IN FOR R32 TYPE
[BSC22.24]
@BOX 3.0
END
@BOX 1.1
PROC BIO.MAT.IN.R32 (MAT.PTR, MD, STATUS);
MAT.TYP M;
@BOX 2.1
MAT.PTR => MAT.R32 OF M;
MAT.IN (M, STATUS, MD,1, 2) ;
@BOX 3.1
END
@END
///15
@TITLE BSC22.16(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
BIO.MAT.IN.R64 (MAT.PTR, MAT.DESC, STATUS)
@BOX 2.0
CALL MAT.IN FOR R64 TYPE
[BSC22.24]
@BOX 3.0
END
@BOX 1.1
PROC BIO.MAT.IN.R64 (MAT.PTR, MD, STATUS);
MAT.TYP M;
@BOX 2.1
MAT.PTR => MAT.R64 OF M;
MAT.IN(M, STATUS, MD,1, 3);
@BOX 3.1
END
@END
///15
@TITLE BSC22.17(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
BIO.MAT.IN.STR (MAT.PTR, MAT.DESC,EL.SIZE, STATUS)
@BOX 2.0
CALL MAT.IN FOR STRING TYPE
@BOX 3.0
END
@BOX 1.1
PROC BIO.MAT.IN.STR (MAT.PTR, MD,EL.SZ, STATUS);
MAT.TYP M;
@BOX 2.1
MAT.PTR => MAT.L8 OF M;
MAT.IN (M, STATUS, MD,EL.SZ, 4) ;
@BOX 3.1
END
@END
///4
@TITLE BSC22.18(1,11)
@COL 5C
@COL 1S-2T-3R-4F
@ROW 5-3
@FLOW 1-2N-3-4
@FLOW 2Y-5
@BOX 1.0
BIO.SKIP.REST ()
@BOX 2.0
FILE ON CURRENT CHANNEL WITH
STREAM ORGANISATION ?
@BOX 3.0
SKIP REMAINDER OF CURRENT RECORD
@BOX 4.0
END
@BOX 5.0
EXCEPTION 7321
@BOX 1.1
PROC BIO.SKIP.REST;
SELECT I.STK[LAST.I];
@BOX 2.1
SELECT CHAN.TAB [C.CHAN.I];
IF STATUS & %1C ->> 2 = 2
@BOX 3.1
::TBC
@BOX 4.1
END
@BOX 5.1
EXCEPTION (%12E, NIL.L8, 0);
@END
///15
@TITLE BSC22.19(1,11)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
BIO.MAT.IN.I8 (MAT.PTR, MAT.DESC, STATUS);
@BOX 2.0
CALL MAT.IN FOR I8 TYPE
[BSC22.24]
@BOX 3.0
END
@BOX 1.1
PROC BIO.MAT.IN.I8 (MAT.PTR, MD, STATUS);
MAT.TYP M;
@BOX 2.1
MAT.PTR => MAT.L8 OF M;
MAT.IN (M, STATUS, MD,1, 5);
@BOX 3.1
END
@END
///18
@TITLE BSC22.20(1,11)
@COL 17C
@COL 1S-2R-3R-4T-5T-6T-7T-8T-9R-10R-11T-12T-13T-14T-15R-28R-16F
@COL 19R-20R-21R-22R-27T-23T-24R-25R-26R
@ROW 4-19
@ROW 17-9
@FLOW 1-2-3-4N-5N-6N-7N-8N-9-10-11N-12N-13N-14N-15-28-16
@FLOW 4Y-19-20-6
@FLOW 5Y-20
@FLOW 6Y-21-22-27N-23N-24-10
@FLOW 27Y-11
@FLOW 7Y-17
@FLOW 8Y-17
@FLOW 11Y-28
@FLOW 12Y-25-26-14Y-17
@FLOW 13Y-26-14
@FLOW 23Y-8
@BOX 1.0
GET.NUM()
SETS IN.EXP TO EXPONENT
     IN.DIG.CNT TO NO. OF
     DIGITS OF INTEGER
     MANTISSA IN IN.BUF
     IN.SIGN TO SIGN OF
     MANTISSA.
@BOX 2.0
INITIALISE GLOBALS
@BOX 3.0
PROCESS SEPARATOR
[22.25/26]
@BOX 4.0
IS CUR.CHAR '-'?
@BOX 5.0
IS CUR.CHAR '+'?
@BOX 6.0
IS CUR.CHAR A DIGIT?
@BOX 7.0
CUR.CHAR NOT '.'?
@BOX 8.0
NEXT CHAR NOT DIGIT?
@BOX 9.0
SKIP LEADING ZEROS
AND SET EXPONENT
@BOX 10.0
COPY DIGITS TO BUFFER
AND DECREMENT EXPONENT
ACCORDINGLY
@BOX 11.0
CAUSE EXCEPTION IF CHAR IS NOT
"E", "e", COMMA, SPACE OR NL
NEXT CHAR NOT 'E'?
@BOX 12.0
NEXT CHAR  '-'?
@BOX 13.0
NEXT CHAR  '+'?
@BOX 14.0
CHAR NOT A DIGIT?
@BOX 15.0
READ IN EXPONENT
@BOX 16.0
END
@BOX 17.0
INPUT EXCEPTION
@BOX 19.0
NOTE NEGATIVE
@BOX 20.0
GET NEXT CHAR
@BOX 21.0
SKIP LEADING ZEROS
@BOX 22.0
COPY SIGNIFICANT
DIGITS TO BUFFER
@BOX 23.0
INTEGER PART ZERO?
@BOX 24.0
SET EXP TO ZERO
@BOX 25.0
NOTE NEGATIVE EXPONENT
@BOX 26.0
GET NEXT CHAR
@BOX 27.0
CHAR NOT '.'
@BOX 28.0
ADD EXPLICIT EXPONENT
TO EXPONENT TO GIVE
TRUE EXPONENT RESULT
@BOX 1.1
PROC GET.NUM;
$IN EXP,EXP.SIGN,E.EXP,JUMP;
$LO8[1]CAP.CH;
SELECT I.STK[LAST.I];
@BOX 2.1
0 => EXP => IN.SIGN => E.EXP => IN.DIG.CNT;
-1 => IB.I; 1 => READING;
@BOX 3.1
SEP.PROC^();
@BOX 4.1
IF CUR.CHAR = '-
@BOX 5.1
IF CUR.CHAR = '+
@BOX 6.1
IF CUR.CHAR >= '0 =< '9
@BOX 7.1
IF CUR.CHAR /= '.
@BOX 8.1
GET.IN.PROC^() => CUR.CHAR;
IF CUR.CHAR < '0 OR CUR.CHAR > '9
@BOX 9.1
WHILE CUR.CHAR = '0 DO
   GET.IN.PROC^() => CUR.CHAR;
   1 -> EXP;
OD;
@BOX 10.1
WHILE CUR.CHAR >= '0 =< '9 DO
      CUR.CHAR => IN.BUF[1+>IB.I];
      1  -> EXP;
      1 +> IN.DIG.CNT;
      GET.IN.PROC^() => CUR.CHAR;
OD;
@BOX 11.1
0 => JUMP;
IF CUR.CHAR /= 'E /= 'e THEN
   1 => JUMP;
    IF CUR.CHAR /= ', /= %0A /= %20 THEN
      CUR.CHAR => CAP.CH[0];
      INPUT.EXCEPTION(%20,^CAP.CH,0,0);
   FI
FI
IF JUMP = 1
@BOX 12.1
IF GET.IN.PROC^() => CUR.CHAR = '-
@BOX 13.1
IF CUR.CHAR = '+
@BOX 14.1
IF CUR.CHAR < '0 OR
   CUR.CHAR > '9
@BOX 15.1
WHILE CUR.CHAR >= '0 =< '9 DO
   E.EXP * 10 + CUR.CHAR - '0 => E.EXP;
   GET.IN.PROC^() => CUR.CHAR;
OD;
@BOX 16.1
0 => READING;
END
@BOX 17.1
CUR.CHAR => CAP.CH [0];
IF VAL.FN=1 THEN
   EXCEPTION(%144,NIL.L8,0);
ELSE
IF I.STAT & %1000 = 0 THEN
   INPUT.EXCEPTION(%20,^CAP.CH,0,0);
ELSE
   CHAN.EXCEPTION(%56,C.CHAN.I);
FI
FI;
@BOX 19.1
-1 => IN.SIGN;
@BOX 20.1
GET.IN.PROC^() => CUR.CHAR;
@BOX 21.1
WHILE CUR.CHAR = '0 DO
   GET.IN.PROC^() => CUR.CHAR;
OD;
@BOX 22.1
WHILE CUR.CHAR >= '0 =< '9 DO
      CUR.CHAR => IN.BUF[1+>IB.I];
      1 +> IN.DIG.CNT;
      GET.IN.PROC^() => CUR.CHAR;
OD;
@BOX 23.1
IF IN.DIG.CNT = 0
@BOX 24.1
0 => EXP;
GET.IN.PROC^() => CUR.CHAR;
@BOX 25.1
-1 => EXP.SIGN;
@BOX 26.1
GET.IN.PROC^() => CUR.CHAR;
@BOX 27.1
IF CUR.CHAR /= '.
@BOX 28.1
IF EXP.SIGN = -1 THEN
   0 - E.EXP => E.EXP
FI
EXP+E.EXP => IN.EXP;
@END
//17
@TITLE BSC22.21(1,11)
@COL 1S-2R-3T-4R-5R-6T-7T-8T-9T-10C-11R-12T-13R-14F
@FLOW 1-2-3N-4-5-6N-7N-8N-9N-10
@FLOW 3Y-10
@FLOW 6Y-12N-13-14
@FLOW 7Y-11-6
@FLOW 8Y-11
@FLOW 9Y-11
@FLOW 12Y-14
@BOX 1.0
GET.I16 (TYP) VALUE
TYP = 0 GET I8 VALUE
    = 1 GET I16 VALUE
@BOX 2.0
CALCULATE TOTAL NO. OF
DIGITS IN REQUIRED INTEGER
@BOX 3.0
IS INTEGER SIZE TOO LARGE
@BOX 4.0
SET M TO 10**EXP-1
@BOX 5.0
SET VALUE TO ZERO
@BOX 6.0
NO MORE DIGITS IN BUFFER?
@BOX 7.0
NOT LAST DIGIT?
@BOX 8.0
NO OF DIGITS < MAX ALLOWED?
@BOX 9.0
INTEGER IN RANGE?
@BOX 10.0
INPUT CHAN.EXCEPTION 8001
@BOX 11.0
SET VALUE = DIGIT * M+VALUE
MULTIPLY M BY 10
@BOX 12.0
POSITIVE NUMBER?
@BOX 13.0
NEGATE RESULT
@BOX 14.0
END
@BOX 1.1
PROC GET.I16 (TYP);
DATAVEC POWERS ($IN16)
1 10 100 1000 10000
END
ADDR[$LO8]MESS;
DATAVEC M1($LO8)
"I16"
END
DATAVEC M2($LO8)
"I8"
END
ADDR [$IN16] CHECK;
$IN16 DIG.CNT,M, DIG, ANS, FAULT, EX;
SELECT I.STK[LAST.I];
@BOX 2.1
IF TYP = 0 THEN
   ^I8.CHECK => CHECK
ELSE
   ^I16.CHECK => CHECK
FI;
0 => FAULT;
IN.DIG.CNT - 1 => IB.I;
IF IN.EXP < 0 THEN
   IN.EXP +> IB.I
FI
IN.DIG.CNT + IN.EXP => DIG.CNT;
@BOX 3.1
IF DIG.CNT > CHECK ^[0]
@BOX 4.1
IF IN.EXP < 0 THEN
   POWERS [0] => M
ELSE
   POWERS [IN.EXP] => M;
FI;
@BOX 5.1
0 => ANS;
@BOX 6.1
IF IB.I < 0
@BOX 7.1
IF IB.I /= 0
@BOX 8.1
IF DIG.CNT < CHECK ^[0]
@BOX 9.1
IN.BUF[IB.I] - '0 => DIG;
IF DIG = CHECK ^[1] AND ANS > CHECK ^[2] THEN
   1 => FAULT
ELSE
   IF DIG > CHECK ^[1] AND M > CHECK ^[3] THEN
      1 => FAULT
   FI
FI
IF FAULT = 0
@BOX 10.1
IF TYP = 0 THEN
   ^M2 => MESS;
ELSE
   ^M1 => MESS;
FI;
IF I.STAT & %000 = 0 THEN
   INPUT.EXCEPTION(%21,MESS,0,0);
ELSE
   CHAN.EXCEPTION(%57,C.CHAN.I);
FI
@BOX 11.1
IN.BUF[IB.I] - '0 => DIG;
DIG*M +> ANS;
1 -> IB.I;
10*>M;
@BOX 12.1
IF IN.SIGN  /= -1
@BOX 13.1
0 - ANS => ANS;
@BOX 14.1
ANS => GET.I16;
END
@END
//17
@TITLE BSC22.22(1,11)
@COL 1S-2R-3T-4R-5R-6T-7T-8T-9T-10C-11R-12T-13R-14F
@FLOW 1-2-3N-4-5-6N-7N-8N-9N-10
@FLOW 3Y-10
@FLOW 6Y-12N-13-14
@FLOW 7Y-11-6
@FLOW 8Y-11
@FLOW 9Y-11
@FLOW 12Y-14
@BOX 1.0
GET.I32()VALUE
@BOX 2.0
CALCULATE TOTAL NO. OF
DIGITS IN REQUIRED INTEGER
@BOX 3.0
IS INTEGER SIZE TOO LARGE
@BOX 4.0
SET M TO 10**EXP-1
@BOX 5.0
SET VALUE TO ZERO
@BOX 6.0
NO MORE DIGITS IN BUFFER?
@BOX 7.0
NOT LAST DIGIT?
@BOX 8.0
NO OF DIGITS < MAX ALLOWED?
@BOX 9.0
INTEGER IN RANGE?
@BOX 10.0
INPUT EXCEPTION 8001
@BOX 11.0
SET VALUE = DIGIT * M+VALUE
MULTIPLY M BY 10
@BOX 12.0
POSITIVE NUMBER?
@BOX 13.0
NEGATE RESULT
@BOX 14.0
END
@BOX 1.1
PROC GET.I32;
DATAVEC POWERS ($IN32)
1 10 100 1000 10000 100000 1000000
10000000 100000000 1000000000
END
$IN32 DIG.CNT,M, DIG, FAULT, ANS;
SELECT I.STK[LAST.I];
@BOX 2.1
0 => FAULT;
IN.DIG.CNT -1 => IB.I;
IF IN.EXP < 0 THEN
   IN.EXP +> IB.I
FI
IN.DIG.CNT + IN.EXP => DIG.CNT;
@BOX 3.1
IF DIG.CNT > MAX.I32.DIGS
@BOX 4.1
IF IN.EXP < 0 THEN
   POWERS [0] => M
ELSE
   POWERS [IN.EXP] => M;
FI
@BOX 5.1
0 => ANS;
@BOX 6.1
IF IB.I < 0
@BOX 7.1
IF IB.I /= 0
@BOX 8.1
IF DIG.CNT < MAX.I32.DIGS
@BOX 9.1
IN.BUF [IB.I] - '0 => DIG;
IF DIG = 2 AND ANS > 147483647 THEN
   1 => FAULT
ELSE
   IF DIG > 2 AND M > 100000000 THEN
      1 => FAULT
   FI
FI
IF FAULT = 0
@BOX 10.1
IF I.STAT & %1000 = 0 THEN
   INPUT.EXCEPTION(%21,%"I32",0,0);
ELSE
   CHAN.EXCEPTION(%57,C.CHAN.I);
FI
@BOX 11.1
IN.BUF[IB.I] - '0 => DIG;
DIG*M +> ANS;
1 -> IB.I;
10 *> M;
@BOX 12.1
IF IN.SIGN/= -1
@BOX 13.1
0 - ANS => ANS;
@BOX 14.1
ANS => GET.I32;
END
@END
//17
@TITLE BSC22.23(1,11)
@COL 13C
@COL 1S-2R-10T-12T-3R-4T-5R-6R-7T-8R-9F
@COL 11R
@ROW 13-3-11
@FLOW 1-2-10N-12N-3-4N-5-6-7N-8-9
@FLOW 12Y-13
@FLOW 10Y-11-9
@FLOW 4Y-6
@FLOW 7Y-9
@BOX 1.0
GET.REAL64 () VALUE
@BOX 2.0
GET MANTISSA FROM BUFFER AND
ACCUMULATE INTEGER VALUE IN
REAL64 VARIABLE
@BOX 3.0
GET SCALE FACTOR
@BOX 4.0
POSITIVE SCALE FACTOR ?
@BOX 5.0
COMPUTE RECIPROCAL OF
SCALE FACTOR
@BOX 6.0
SCALE MANTISSA
@BOX 7.0
POSITIVE MANTISSA ?
@BOX 8.0
NEGATE RESULT
@BOX 9.0
END
@BOX 10.0
TEMPORARILY PUT MANTISSA IN
RANGE 0.1 =< M < 1.0 AND ADJUST EXP
UNDERFLOW ?
@BOX 11.0
REPLACE VALUE WITH 0.0
@BOX 12.0
OVERFLOW ?
@BOX 13.0
INPUT EXCEPTION
@BOX 1.1
PROC GET.R64;
DATAVEC SCALE ($RE64)
1.0  1.0@1  1.0@2  1.0@3  1.0@4  1.0@5  1.0@6
1.0@7  1.0@8  1.0@9  1.0@10  1.0@11  1.0@12  1.0@13
1.0@14 1.0@15 1.0@16
END
$RE64 SC, RES, M, M.TST;
$IN I, S,CH, E.TST;
SELECT I.STK[LAST.I];
@BOX 2.1
0.0 => RES; 0=>E.TST;
IN.DIG.CNT => I;
1.0 => M;
WHILE 1 -> I >= 0 DO
   IN.BUF [I] - '0 => CH * M => SC;
   1 +> E.TST;
   SC  +> RES;
   10.0 *> M;
OD
RES/M => M.TST; IN.EXP +> E.TST;
@BOX 3.1
IF IN.EXP < 1 THEN
   0 - IN.EXP => I
ELSE
   IN.EXP => I
FI
IF I =< 16 THEN
   SCALE [I] => SC;
ELSE
   SCALE[16] => SC;
   16 -> I;
   I <<- 1 => I;
   1 => S;
   WHILE I > 0 DO
      IF I ->> 1 => I & %1 /= 0 THEN
        SCALE[S] *> SC;
      FI
      S <<- 1 => S;
   OD;
FI
@BOX 4.1
IF IN.EXP >= 0
@BOX 5.1
1.0 / SC => SC;
@BOX 6.1
SC *> RES;
@BOX 7.1
IF IN.SIGN >= 0
@BOX 8.1
0.0 - RES => RES;
@BOX 9.1
RES => GET.R64;
END
@BOX 10.1
IF E.TST =< MIN.R.EXP
@BOX 11.1
0.0 => RES;
@BOX 12.1
IF [E.TST > MAX.R.EXP] OR
   [E.TST = MAX.R.EXP AND M.TST > MAX.R.MANT]
@BOX 13.1
IF I.STAT & %1000 = 0 THEN
IF VAL.FN = 1 THEN
   EXCEPTION(%146,NIL.L8,0);
ELSE
   INPUT.EXCEPTION(%46,NIL.L8,0,0);
FI;
ELSE
   CHAN.EXCEPTION(%57,C.CHAN.I);
FI
@END
///17
@TITLE BSC22.24(1,11)
@COL 13R
@COL 1S-2R-3T-4R-5R-6T-7R-9T-17R-10T-11R-12F
@COL 15T-16C
@ROW 13-4
@ROW 7-15
@FLOW 1-2-3N-4-5-6N-7-9N-17-10N-11-12
@FLOW 3Y-13-4
@FLOW 6Y-15N-16
@FLOW 9Y-6
@FLOW 10Y-6
@FLOW 15Y-12
@BOX 1.0
MAT.IN(MATRIX.PTR,STATUS,MAT.DESC,EL.SIZE,KIND)
@BOX 2.0
DETERMINE NUMBER OF
ELEMENTS REQUIRED
@BOX 3.0
VARIABLE LENGTH VECTOR?
@BOX 5.0
SET INDEX TO START
OF ARRAY
@BOX 4.0
SET INPUT EXCEPTION
RECOVERY LABEL
@BOX 6.0
END OF ARRAY?
@BOX 7.0
INPUT AND STORE A VALUE OF APPROPRIATE TYPE
@BOX 9.0
NOT VAR LENGTH VECTOR
OR INTERNAL FILE
@BOX 10.0
CUR.CHAR NOT NEWLINE?
@BOX 11.0
UPDATE VECTOR DESCRIPTOR
@BOX 12.0
END
@BOX 13.0
SET SIZE TO MAXIMUM
@BOX 15.0
NOT VAR LENGTH VECTOR?
@BOX 16.0
EXCEPTION 5001
@BOX 17.0
SKIP SPACES
@BOX 1.1
PROC MAT.IN(MAT.PTR,STATUS,MD,EL.SZ,KIND);
ADDR PROC.TYP1 GET.CH;
$IN VAR.VEC,I, SZ,J,ARRAY.Z;
SELECT MAT.PTR;
@BOX 2.1
%2000 !> I.STAT OF I.STK[LAST.I];
0 => VAR.VEC;
ALTERNATIVE KIND FROM
   SIZE(MATI16) =>SZ;
   SIZE(MATI32) =>SZ;
   SIZE(MATR32) =>SZ;
   SIZE(MATR64) =>SZ;
   SIZE(MATL8 ) =>SZ;
   SIZE (MATI8) => SZ;
END
$IN D1,D2;
MD^[1] => D1;
IF STATUS & %3 = 2 THEN
   MD^[3] => D2;
ELSE
   1 => D2;
FI
D1 * D2 => ARRAY.Z;
@BOX 3.1
IF STATUS & %4 => VAR.VEC /= 0
@BOX 5.1
-1 => I;
0 => J;
@BOX 4.1
L:
L => REC.LAB OF ISTK[LASTI];
@BOX 6.1
IF  1+>I = ARRAY.Z
@BOX 7.1
ALTERNATIVE KIND FROM
   BIO.IN.I16() => MATI16^ [I];
   BIO.IN.I32() =>MATI32^ [I];
   BIO.IN.R32() => MATR32^ [I];
   BIO.IN.R64() => MATR64^ [I];
   BEGIN
   IF I.STAT OF ISTK[LASTI] & %40 /= 0 THEN
   BIO.LINE.IN.STR (PART(MATL8,J,J+EL.SZ-1));
   ELSE
   BIO.IN.STR (PART(MATL8,J,J+EL.SZ-1));
   FI;
   EL.SZ  +> J;
   END
   BIO.IN.I8 () => MAT.I8 ^[I];
END
@BOX 9.1
IF VAR.VEC = 0 OR
STATUS OF CHAN.TAB[C.CHAN.I OF ISTK[LASTI]] & %60 = %40
@BOX 10.1
IF CUR.CHAR OF I.STK[LASTI] /= NL
@BOX 11.1
I+1 => MD^[1];
@BOX 12.1
END
@BOX 13.1
SZ => ARRAY.Z;
@BOX 14.1
EXCEPTION (%107,NIL.L8,0);
@BOX 15.1
IF VAR.VEC = 0
@BOX 16.1
EXCEPTION(%107,NIL.L8,0);
@BOX 17.1
GET.IN.PROC OF ISTK[LASTI] => GET.CH;
WHILE CUR.CHAR OF ISTK[LASTI] = SP DO
   GET.CH^() => CUR.CHAR OF ISTK[LASTI]
OD;
@END
//16
@TITLE BSC22.25(1,11)
@COL 7T-8C
@COL 1S-2R-3T-4T-5R-6F
@COL 9R
@ROW 4-9
@ROW 7-5
@FLOW 1-2-3N-4N-5-6
@FLOW 3Y-9-6
@FLOW 4Y-7N-8
@FLOW 7Y-5
@BOX 1.0
PROCESS.READ.SEP()
@BOX 2.0
SKIP SPACES
@BOX 3.0
SEPARATOR NOT REQUIRED
@BOX 4.0
CURRENT CHAR /= ',
@BOX 5.0
SKIP SPACES
@BOX 6.0
END
@BOX 7.0
NEWLINE?
@BOX 8.0
EXCEPTION
"invalid data statement"
@BOX 9.0
NOTE SEPARATOR REQUIRED
@BOX 1.1
PROC PROCESS.READ.SEP;
SELECT I.STK[LAST.I];
@BOX 2.1
WHILE CUR.CHAR = SP DO
   READ.CH () => CUR.CHAR;
OD;
@BOX 3.1
IF I.STAT & %800 = 0
@BOX 4.1
IF CUR.CHAR /= ',
@BOX 5.1
WHILE READ.CH() =>  CUR.CHAR = SP DO OD;
@BOX 6.1
END
@BOX 7.1
IF CUR.CHAR = NL
@BOX 8.1
EXCEPTION(%123,NIL.L8,0);
@BOX 9.1
%800 !> I.STAT;
@END
///18
@TITLE BSC22.26(1,11)
@COL 7R-8R
@COL 1S-2T-3T-4T-5C-6F
@COL 9R-10T-11R
@ROW 7-3
@ROW 4-9
@FLOW 1-2N-3N-4N-5
@FLOW 2Y-7-8-6
@FLOW 3Y-9-10N-11-6
@FLOW 4Y-6
@FLOW 10Y-6
@BOX 1.0
PROCESS INPUT SEPARATOR
@BOX 2.0
SEPARATOR NOT
REQUIRED ?
@BOX 3.0
SKIP UNTIL CUR CHAR NOT SPACE
CURRENT CHAR "," ?
@BOX 4.0
CURRENT CHAR NOT NL ?
@BOX 5.0
EXCEPTION
@BOX 6.0
END
@BOX 7.0
GET NEXT CHAR
AND SKIP SPACES
AND NEWLINES
@BOX 8.0
NOTE SEP REQUIRED
IF ONLINE INPUT
@BOX 9.0
SKIP UNTIL NEXT
CHAR NOT SPACE
@BOX 10.0
CURRENT CHAR NOT NL ?
@BOX 11.0
ISSUE DEFAULT PROMPT AND
SKIP UNTIL NEXT
CHAR NOT SPACE
@BOX 1.1
PROC PROCESS.INP.SEP;
SELECT I.STK[LAST.I];
@BOX 2.1
IF I.STAT & %800 = 0
@BOX 3.1
WHILE CUR.CHAR = SP DO
   INPUT.CH() => CUR.CHAR;
OD
IF CUR.CHAR = ',
@BOX 4.1
IF CUR.CHAR /= NL
@BOX 5.1
IF I.STAT & %1000 = 0 THEN
   INPUT.EXCEPTION (%1A,NIL.L8,0,0);
ELSE
   CHAN.EXCEPTION(%58,C.CHAN.I);
FI
@BOX 6.1
END
@BOX 7.1
WHILE INPUT.CH () => CUR.CHAR = SP
      OR CUR.CHAR = NL
   DO OD;
@BOX 8.1
IF I.STAT & %1000 = 0 THEN
   %800 !> I.STAT;
FI
@BOX 9.1
WHILE INPUT.CH () => CUR.CHAR = SP
   DO OD;
@BOX 10.1
IF CUR.CHAR /= NL
@BOX 11.1
^SYS.PROMPT=> PROMPT.PTR;
WHILE INPUT.CH () => CUR.CHAR = SP
   DO OD;
@END
//16
@TITLE BSC22.27(1,11)
@COL 1S-2T-10N-3R-4F
@COL 9R
@COL 8T-5T-6C-7C
@ROW 10-8
@ROW 3-9
@FLOW 1-2N-10-3-4
@FLOW 2Y-8N-5N-6
@FLOW 8Y-9-4
@FLOW 5Y-7
@BOX 1.0
READ.CHAR()VALUE
@BOX 2.0
DATA BUFFER EMPTY?
@BOX 3.0
GET NEXT CHAR
FROM DATA BUFF
@BOX 4.0
END
@BOX 5.0
'MISSING' RECOVERY SPECIFIED?
@BOX 6.0
EXCEPTION 8001
@BOX 7.0
JUMP TO MISSING
RECOVERY LABEL
@BOX 8.0
CURRENTLY READING AN ITEM ?
@BOX 9.0
RETURN NEWLINE RESULT
@BOX 1.1
PROC READ.CH;
$LA T;
SELECT I.STK[LAST.I];
@BOX 2.1
IF DI >= BUFF.Z - 2
@BOX 3.1
DATA.PTR^[1+>DI] => READ.CH;
@BOX 4.1
END
@BOX 5.1
IF I.STAT & %1 /= 0
@BOX 6.1
EXCEPTION(%124,NIL.L8,0);
@BOX 7.1
MISSING.LAB => T;
-> T;
@BOX 8.1
IF READING = 1 AND
   DI = BUFF.Z - 2
@BOX 9.1
NL => READ.CH;
0 => READING;
1 +> DI;
@END
//17
@TITLE BSC22.28(1,11)
@COL 1S-6R-7T-8R-2T-3R-4F
@COL 5C
@ROW 3-5
@FLOW 1-6-7N-8-2N-3-4
@FLOW 2Y-5
@FLOW 7Y-2
@BOX 1.0
INPUT.CH()VALUE
@BOX 2.0
END OF INPUT STREAM?
@BOX 3.0
READ NEXT CHAR FROM
CURRENT INPUT STREAM
@BOX 4.0
END
@BOX 5.0
EXCEPTION(4001);
@BOX 6.0
SET PROMPT STRING
@BOX 7.0
TIMEOUT NOT SPECIFIED OR
FIRST CHAR ALREADY OBTAINED?
@BOX 8.0
CALL IN.WAIT WITH
SPECIFIED TIMEOUT
[BSC22.31]
@BOX 1.1
PROC INPUT.CH;
SELECT I.STK[LAST.I];
@BOX 2.1
IF I.ENQ() & %8 /= 0
@BOX 3.1
IN.CH () => INPUT.CH;
@BOX 4.1
END
@BOX 5.1
CHAN.EXCEPTION (%1C,C.CHAN.I);
@BOX 6.1
PROMPT(PROMPT.PTR);
@BOX 7.1
IF TIME.LIMIT = -1
@BOX 8.1
IN.WAIT();
@END
//16
@TITLE BSC22.29(1,11)
@COL 8C
@COL 1S-2T-3T-4R-5R-6R-7F
@ROW 8-4
@FLOW 1-2N-3N-4-5-6-7
@FLOW 2Y-8
@FLOW 3Y-8
@BOX 1.0
INPUT EXCEPTION(EXC.NO,CAPTION,VALUE,TYP)
@BOX 2.0
READ STATEMENT?
@BOX 3.0
NOT ONLINE (INTERACTIVE) INPUT?
@BOX 4.0
PRINT EXCEPTION MESSAGE
[BSC21.3]
@BOX 5.0
ECHO INPUT LINE ON
MONITORING STREAM
AND REQUEST RESUPPLY INPUT
@BOX 6.0
NOTE SEPARATOR
NOT REQUIRED
@BOX 7.0
JUMP TO EXCEPTION
RECOVERY LABEL
@BOX 8.0
FATAL EXCEPTION
[BSC21.3]
@BOX 1.1
PROC INPUT.EXCEPTION(EXC.NO,CAP,VAL,TYP);
DATAVEC M1($LO8)
"value(s)"
END
DATAVEC M2($LO8)
"separator"
END
DATAVEC MESS(ADDR[$LO8])
M1 M2
END
$LA T;
$IN STR;
$IN32 ERR.POS, ST;
SELECT I.STK[LAST.I];
@BOX 2.1
IF I.STAT & %400 = 0
@BOX 3.1
IF I.MODE() & %80 = 0
@BOX 4.1
EXCEPTION(EXC.NO,CAP,VAL);
@BOX 5.1
CURRENT.OUTPUT () => STR;
SELECT.OUTPUT (C.OUT.STR);
I.POS () => ERR.POS;
IN.BACKSPACE (-1);
I.POS () => ST;
WHILE I.ENQ() & %2 = 0 DO
   OUT.CH (IN.CH());
OD;
NEWLINES (0);
SPACES (ERR.POS-ST-1);
CAPTION (%"^$LResupply ");
CAPTION (MESS [TYP]);
SELECT.OUTPUT (STR);
@BOX 6.1
%F7FF &> I.STAT;
@BOX 7.1
REC.LAB => T;
-> T;
END
@BOX 8.1
EXCEPTION(EXC.NO ! %100,CAP,VAL);
@END
///16
@TITLE BSC22.30(1,11)
@COL 1S-2R-3R-4R-5F
@FLOW 1-2-3-4-5
@BOX 1.0
BIO.IN.I8 () VALUE
@BOX 2.0
SET INPUT EXCEPTION
RECOVERY LABEL
@BOX 3.0
READ NUMERIC ITEM FROM
DATA BUFFER/INPUT CHANNEL
INTO INPUT BUFFER
[BSC22.20]
@BOX 4.0
GET I8 VALUE FROM
INPUT BUFFER
[BSC22.21]
@BOX 5.0
END
@BOX 1.1
PROC BIO.IN.I8;
SELECT I.STK[LAST.I];
@BOX 2.1
L:
L => REC.LAB;
@BOX 3.1
GET.NUM();
@BOX 4.1
GET.I16 (0) => BIO.IN.I8;
@BOX 5.1
END
@END
//16
@TITLE BSC22.31(1,11)
@COL 1S-2T-3R-4T-5R-6F
@COL 7C
@ROW 5-7
@FLOW 1-2N-3-4N-5-6
@FLOW 2Y-5
@FLOW 4Y-7
@BOX 1.0
IN.WAIT()
@BOX 2.0
MESSAGE AVAILABLE ?
@BOX 3.0
WAIT ON CHANNEL WITH
SPECIFIED TIMEOUT
@BOX 4.0
NO MESSAGES AVAILABLE?
@BOX 5.0
NOTE FIRST CHAR OBTAINED
@BOX 6.0
END
@BOX 7.0
EXCEPTION
@BOX 1.1
PROC IN.WAIT;
SELECT I.STK[LAST.I];
@BOX 2.1
IF I.ENQ() & %4 = 0
@BOX 3.1
CAPTION(PROMPT.PTR);
BREAKOUTPUT(-1);
WAIT(W.CHAN,TIME.LIMIT);
@BOX 4.1
IF PW1 = 0
@BOX 5.1
-1 => TIME.LIMIT;
@BOX 6.1
END
@BOX 7.1
EXCEPTION(%12D,NIL.L8,0);
@END
///15
@TITLE BSC22.32(1,11)
@COL 1S-2T-3R-4F
@COL 5R
@ROW 3-5
@FLOW 1-2N-3-4
@FLOW 2Y-5-4
@BOX 1.0
BIO.REDIM.1(MAT.DESC,ARRAY.Z,LB1,UB1)
@BOX 2.0
REQUESTED SIZE EXCEEDS
STORAGE ALLOCATED ?
@BOX 3.0
UPDATE MATRIX DESCRIPTOR
@BOX 4.0
END
@BOX 5.0
EXCEPTION
@BOX 1.1
PROC BIO.REDIM.1(MD,SZ,L1,U1);
$IN Z1;
@BOX 2.1
IF U1-L1 + 1 => Z1 > SZ
@BOX 3.1
L1 => MD^[0];
Z1 => MD^[1];
@BOX 4.1
END
@BOX 5.1
EXCEPTION(%7,NIL.L8,0);
@END
///15
@TITLE BSC22.33(1,11)
@COL 1S-2T-3R-4F
@COL 5R
@ROW 3-5
@FLOW 1-2N-3-4
@FLOW 2Y-5-4
@BOX 1.0
BIO.REDIM.2(MAT.DESC,ARRAY.SZ,L1,U1,L2,U2)
@BOX 2.0
REQUESTED SIZE EXCEEDS
ALLOCATED STORAGE ?
@BOX 3.0
UPDATE MATRIX DESCRIPTOR
@BOX 4.0
END
@BOX 5.0
EXCEPTION
@BOX 1.1
PROC BIO.REDIM.2(MD,SZ,L1,U1,L2,U2);
$IN Z1,Z2;
@BOX 2.1
IF (U1-L1+1=> Z1) * (U2-L2+1=> Z2) > SZ
@BOX 3.1
L1 => MD^[0]; Z1 => MD^[1];
L2 => MD^[2]; Z2 => MD^[3];
@BOX 4.1
END
@BOX 5.1
EXCEPTION(%7,NIL.L8,0);
@END
