@X @~
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H            BSC101
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL~
~
~
                                                              ISSUE 11~
~V9 -1
~P
~V9 1
~YBSC101
~S~M~OBASIC COMPILER IMPLEMENTATION DESCRIPTION
~S~M~OSection 10 Version 1
~S1~OSection 10 Delimeter Preprocessor
~S1~O1. General Description
~BThis section contains preprocessors for generating
the delimeter tables and the tables concerned with basic supplied functions for
the compiler.
~BThe job to compile the preprocessor as a private library is
contained in paragraph four of this section.
After opening this library the delimeter preprocessor is invoked by the command
KEYWORDS.  The delimeter input is contained in level 0 chart of
BSC03/2.  The delimeter datavecs, etc., are left in the current
file and these need to be manually edited into level 1 of chart BSC03/2.
Similarly the preprocessor of basic supplied functions is invoked by
the command FUNCTIONS, input is contained in the level 0 chart of
BSC08/2.  The basic supplied function datavecs are left in
the current file and these need to be manually edited into
level 1 of chart BSC08/2.
~S1~O2.1 Interfaces
~
Library Procedures:~
   KEYWORDS~
   FUNCTIONS~
~S1~O3. Implementation
~BOperation of the preprocessor is straightforward.
~S1~O4. Compile Jobs
~S1~O4.1 Preprocessor Compile Job
~BThis job compiles and runs the preprocessor program.
~
~
::BEGIN CPREBSC~
FLIP MU6C:BSC101 1  0 ;LB: ;->LB!0A! !2C!->LB;~
BSC10~
DI 5~
MUSL 0 PREBSC 5~
**TLSEG 0 0 %200000 -1~
**SI 5~
EI 5~
STOP~
::END CPREBSC~
~Y
~V9 -1
~P
~D15
~HFLOWCHARTS
~
~
~H               BSC101
~V9 -1
~F
@TITLE BSC10(1,11)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
PREPROCESSOR FOR HANDLING KEYWORDS
@BOX 2.0
MODULE HEADING
@BOX 3.0
KEYWORD PREPROCESSOR[10.1]
BASIC SUPPLIED FN PREPROCESSOR[10.2]
@BOX 4.0
END
@BOX 1.1
::BSC10
@BOX 2.1
MODULE(KEYWORDS,FUNCTIONS);
@BOX 3.1
LSPEC KEYWORDS();
LSPEC FUNCTIONS();
#BSC10.1
#BSC10.2
@BOX 4.1
*END
@END
///7
@TITLE BSC10.1(1,11)
@COL 1S-2R-3R-4T-5R-6T-7R-8R
@COL 9R-10R-11R-12R-18R-13R-14R-15R-16R-17F
@FLOW 1-2-3-4N-5-6N-7-8-4Y-9-10-11-12-18-13-14-15-16-17
@FLOW 6Y-8
@BOX 1.0
KEYWORD PREPROCESSOR
@BOX 2.0
NOTE CURRENT I/O STREAMS
DEFINE AND SELECT I/O STREAMS
TO AND FROM CURRENT FILE
@BOX 3.0
INITIALISE TABLE INVOICES ETC
@BOX 4.0
GET NEXT NON-SEPARATOR CHAR
IS IT '%'
@BOX 5.0
READ OPTIONAL DELIMITER REQUEST CHARACTER(\)
READ DELIMITER, ITS TAG, IND VALUE
AND ITS ST VALUE
@BOX 6.0
STARTS WITH SAME LETTER AS
PREVIOUS DELIMITER
@BOX 7.0
ADD ENTRY TO STARTS TABLES
@BOX 8.0
CALCULATE HASH AND ADD
ENTRIES TO TABLES
@BOX 9.0
OUTPUT DELIMITER CHAR TABLE
@BOX 10.0
OUTPUT HASH TABLE
@BOX 11.0
OUTPUT CHAR INDEX TABLE
@BOX 12.0
OUTPUT DELIMETER TAG TABLE
@BOX 13.0
OUTPUT DELIMETER IND TABLE
@BOX 14.0
OUTPUT START TABLE
@BOX 15.0
OUTPUT REQUESTED DELIMITER LITERALS
@BOX 16.0
SELECT ORIGINAL I/O STREAMS
END I/O STREAMS
@BOX 17.0
END
@BOX 18.0
OUTPUT DELIMITER ST TABLE
@BOX 1.1
PROC KEYWORDS;
PSPEC CH.HDR($LO8);
PROC CH.HDR(CH);
CAPTION(%"@TITLE BSC03/2.");
OUT.CH(CH);
DATAVEC CHT($LO8)
"(1,11)$L"
"@COL 1S $L"
"@BOX 1.0$L"
"DELIMETER DATAVECS$L"
"@BOX 1.1$L"
END
CAPTION(^CHT);
END
LITERAL/ADDR[$LO8] NIL=;
DATAVEC M.END.CHT($LO8)
"$L@END$L$P"
END;
DATAVEC MEND($LO8)
"$LEND$L$L"
END;
$IN INP,OUTP;
$LO8[3000] D.CH;
$LO8[27] D.STARTS;
TYPE DELIM.E IS
   $LO16 HASH,CH.IND
   $LO8 TAG,IND,FL,ST;
DELIM.E[256] DELIM;
$IN D.NO,C.INP,C.OUTP,I,CH.I;
$LO8 F.CH,CH;
ADDR [$LO8] PTR;
$IN N,J,F,K;
$LO16 H;
@BOX 2.1
CURRENT.INPUT() => C.INP;
CURRENT.OUTPUT() => C.OUTP;
SELECT.INPUT(DEFINE.INPUT(-1,NIL,0,0) => INP);
SELECT.OUTPUT(DEFINE.OUTPUT(-1,NIL,%200,0,100,0) => OUTP);
@BOX 3.1
FOR I < 26 DO 0 => D.STARTS[I] OD;
-1 => D.NO; 0 => CH.I;
0 => F.CH;
@BOX 4.1
WHILE INCH() => CH = " " OR CH = '$L DO OD
IF CH = "%"
@BOX 5.1
SELECT DELIM[1+>D.NO];
IF CH = "\" THEN
   1 => FL;
ELSE
   0 => FL;
   INBACKSPACE(-1);
FI
PART(^D.CH,CH.I,CH.I+32)=>PTR;
IN.STR(PTR)=>N;
IN.HEX() => TAG;
IN.HEX() => IND;
IN.HEX() => ST;
CH.I => CH.IND;
@BOX 6.1
IF D.CH[CH.I] = F.CH
@BOX 7.1
D.NO => D.STARTS[D.CH[CH.I] => F.CH-'A];
@BOX 8.1
0 => H;
FOR I < N DO
   D.CH[CH.I+I] & %1F + H & %7FF <<- 1=> H;
OD
H <<- 4 +N => HASH;
N +> CH.I;
@BOX 9.1
CH.HDR("1");
CAPTION(%"DATAVEC D.CH($$LO8)$L");
32 => J
FOR I < CH.I DO
   IF 1+>J >= 32 THEN OUT.CH('"); 0 => J FI
   OUTCH(D.CH[I]);
   IF J=31 THEN OUT.CH('");NEWLINES(1); FI
OD
IF J/=31 THEN OUT.CH('"); NEWLINES(1); FI
CAPTION(^M.END);
@BOX 10.1
CAPTION(%"DATAVEC D.HASH($$LO16)$L");
FOR I< D.NO + 1 DO
   OUT.CH('%);
   OUT.HEX(HASH OF DELIM[I],4);
   IF I & 7 = 7 THEN NEWLINES(1)
   ELSE SPACES(2) FI
OD
CAPTION(^M.END);
@BOX 11.1
CAPTION(%"DATAVEC D.CH.IND($$LO16)$L");
FOR I < D.NO + 1 DO
   OUT.CH('%);
   OUT.HEX(CH.IND OF DELIM[I],4);
   IF I & 7 = 7 THEN NEWLINES(1)
   ELSE SPACES(2) FI
OD
CAPTION(^M.END);
CAPTION(^M.END.CHT);
@BOX 12.1
CH.HDR("2");
CAPTION(%"DATAVEC D.TAG($$LO8)$L")
FOR I < D.NO + 1 DO
   OUT.CH('%);
   OUT.HEX(TAG OF DELIM[I],2);
   IF I & 7 = 7 THEN NEWLINES(1)
   ELSE SPACES(2) FI
OD
CAPTION(^M.END);
@BOX 13.1
CAPTION(%"DATAVEC D.IND($$LO8)$L");
FOR I < D.NO + 1 DO
   OUT.CH('%);
   OUT.HEX(IND OF DELIM[I],2);
   IF I & 7 = 7 THEN NEWLINES(1)
   ELSE SPACES(2) FI
OD
CAPTION(^M.END);
@BOX 14.1
1 +> D.NO => D.STARTS[26];
CAPTION(%"DATAVEC D.STARTS($$LO8)$L");
FOR I < 26 DO
   IF D.STARTS[26 - I] = 0 THEN
      D.STARTS[27 - I] => D.STARTS[26 - I];
   FI
OD
FOR I < 27 DO
   OUT.CH('%);
   OUT.HEX(D.STARTS[I],2);
   IF I & 7 = 7 THEN NEWLINES(1)
   ELSE SPACES(2) FI
OD
CAPTION(^M.END);
CAPTION(^M.END.CHT);
@BOX 15.1
CH.HDR("3");
CAPTION(%"LITERAL/ITYPE$L");
0 => J; 0 => F;
FOR I < D.NO + 1 DO
   IF FL OF DELIM[I] /= 0 THEN
      IF F = 0 THEN 1 => F ELSE OUT.CH(',) FI
      IF 1+>J = 5 THEN NEWLINES(1); 1 => J FI
      HASH OF DELIM[I] & %1F => N;
      CH.IND OF DELIM[I] -1 => K;
      OUT.CH('D);
      OUT.CH('.);
      FOR N DO
         OUT.CH(D.CH[1+>K]);
      OD
      OUT.CH('=);
      OUT.I(TAG OF DELIM[I],0);
      OUT.CH('\);
      OUT.CH('%);
      OUT.HEX(ST OF DELIM[I],2);
      OUT.CH('\);
      OUT.CH ('%);
      OUT.HEX(I<<-8 ! IND OF DELIM[I],4);
   FI
OD
OUT.CH(';);
CAPTION(^M.END.CHT);
@BOX 16.1
SELECT.INPUT(C.INP);
SELECT.OUTPUT(C.OUTP);
END.INPUT(INP,0);
END.OUTPUT(OUTP,0);
@BOX 17.1
END
@BOX 18.1
CAPTION(%"DATAVEC D.ST($$LO8)$L");
FOR I < D.NO + 1 DO
   OUT.CH('%);
   OUT.HEX(ST OF DELIM[I],2);
   IF I & 7 = 7 THEN NEWLINES(1)
   ELSE SPACES(2) FI
OD
CAPTION(^M.END);
@END
///7
@TITLE BSC10.2(1,11)
@COL 1S-2R-3R-4T-5R-6T-7R-8R
@COL 9R-10R-11R-14R-16R-17F
@ROW 2-9
@FLOW 1-2-3-4N-5-6N-7-8-4Y-9-10-11-14-16-17
@FLOW 6Y-8
@BOX 1.0
BASIC SUPPLIED FUNCTIONS
PREPROCESSOR
@BOX 2.0
NOTE CURRENT I/O STREAMS
DEFINE AND SELECT I/O STREAMS
TO AND FROM CURRENT FILE
@BOX 3.0
INITIALISE TABLES
@BOX 4.0
GET NEXT NON-SEPARATOR CHAR
IS IT '%'
@BOX 5.0
READ FUNCTION NAME
@BOX 6.0
STARTS WITH SAME CHARACTER
AS PREVIOUS LETTER
@BOX 7.0
ADD ENTRY TO STARTS TABLE
@BOX 8.0
CALCULATE HASH
@BOX 9.0
OUTPUT FUNCTION CHAR TABLE
@BOX 10.0
OUTPUT HASH TABLE
@BOX 11.0
OUTPUT CHAR INDEX TABLE
@BOX 14.0
OUTPUT START TABLE
@BOX 16.0
SELECT ORIGINAL I/O STREAMS
END I/O STREAMS
@BOX 17.0
END
@BOX 1.1
PROC FUNCTIONS;
LITERAL/ADDR [$LO8] NIL =;
$IN C.INP,C.OUTP,INP,OUT.P,I,F.NO,CH.I,N;
$LO8[3000] F.CH;
$IN C.CH,CH;
$LO8[27] F.STARTS;
TYPE FN.E IS
   $LO16 HASH, CH.IND;
FN.E[256] FN;
ADDR [$LO8] PTR;
$LO16 H;
$IN J;
DATAVEC MEND($LO8)
"$LEND$L$L"
END;
@BOX 2.1
CURRENT.INPUT()=>C.INP;
CURRENT.OUTPUT()=>C.OUTP;
SELECT.INPUT(DEFINE.INPUT(-1,NIL,0,0)=>INP);
SELECT.OUTPUT(DEFINE.OUTPUT(-1,NIL,%200,0,100,0)=>OUTP);
@BOX 3.1
FOR I < 26 DO 0 => F.STARTS[I] OD
-1 => F.NO; 0 => CH.I; 0 => C.CH
@BOX 4.1
WHILE INCH() => CH = " " OR CH = '$L DO OD
IF CH = "%"
@BOX 5.1
INBACKSPACE(1);
SELECT FN[1+>F.NO];
PART(^F.CH, CH.I, CH.I+32) => PTR;
IN.STR(PTR) => N;
IF NEXT.CH() = '$$ THEN
   IN.CH();
   '$$ => F.CH[N];
   1 +> N;
FI
::CAPTION(%" N, CHI "); OUTHEX(N,8);OUTHEX(CHI,8);CAPTION(PTR);NEWLINES(1);
CHI => CH.IND;
@BOX 6.1
IF F.CH[CH.I] = C.CH
@BOX 7.1
F.NO => F.STARTS[F.CH[CH.I] => C.CH - 'A];
@BOX 8.1
0 => H;
FOR I < N DO
   F.CH[CH.I+I] & %1F +H & %7FF <<- 1 => H;
OD
H <<- 4 + N => HASH;
N +> CH.I;
@BOX 9.1
CAPTION(%"DATAVEC FN.CH($$LO8)$L");
32 => J;
FOR I < CH.I DO
   IF 1+>J >= 32 THEN OUT.CH('"); 0 => J FI
   OUTCH(F.CH[I]);
  IF F.CH[I] = '$$ THEN
     OUT.CH('$$);
  FI
   IF J=31 THEN OUT.CH('");NEWLINES(1); FI
OD
IF J/=31 THEN OUT.CH('"); NEWLINES(1); FI
CAPTION(^M.END);
@BOX 10.1
CAPTION(%"DATAVEC FN.HASH($$LO16)$L");
FOR I< F.NO + 1 DO
   OUT.CH('%);
   OUT.HEX(HASH OF FN[I],4);
   IF I & 7 = 7 THEN NEWLINES(1)
   ELSE SPACES(2) FI
OD
CAPTION(^M.END);
@BOX 11.1
CAPTION(%"DATAVEC FN.CH.IND($$LO16)$L");
FOR I < F.NO + 1 DO
   OUT.CH('%);
   OUT.HEX(CH.IND OF FN[I],4);
   IF I & 7 = 7 THEN NEWLINES(1)
   ELSE SPACES(2) FI
OD
CAPTION(^M.END);
@BOX 14.1
1 + F.NO => F.STARTS[26];
CAPTION(%"DATAVEC FN.STARTS($$LO8)$L");
FOR I < 26 DO
   IF F.STARTS[26 - I] = 0 THEN
      F.STARTS[27 - I] => F.STARTS[26 - I];
   FI
OD
FOR I < 27 DO
   OUT.CH('%);
   OUT.HEX(F.STARTS[I],2);
   IF I & 7 = 7 THEN NEWLINES(1)
   ELSE SPACES(2) FI
OD
CAPTION(^M.END);
@BOX 16.1
SELECT.INPUT(C.INP);
SELECT.OUTPUT(C.OUTP);
END.INPUT(INP,0);
END.OUTPUT(OUTP,0);
@BOX 17.1
END
@END

