home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
SIMTEL
/
CPMUG
/
CPMUG030.ARK
/
BASSYN.PLM
< prev
next >
Wrap
Text File
|
1984-04-29
|
55KB
|
1,640 lines
BASSYN:
DO;
/* SYMBOL TABLE AND CODE SYNTHESIS MODULE */
$INCLUDE (:F1:BASCOM.LIT)
/* EXTERNAL PROCEDURES (DEFINED IN BASIC.PLM) */
MON3: PROCEDURE EXTERNAL;
END MON3;
MOVE: PROCEDURE(S,D,C) EXTERNAL;
DECLARE (S,D) ADDRESS, C BYTE;
END MOVE;
FILL: PROCEDURE(D,CH,CNT) EXTERNAL;
DECLARE D ADDRESS, (CH, CNT) BYTE;
END FILL;
EMIT: PROCEDURE(C) EXTERNAL;
DECLARE C BYTE;
END EMIT;
SETFLAGS: PROCEDURE EXTERNAL;
END SETFLAGS;
SETUP$INT$FILE: PROCEDURE EXTERNAL;
END SETUP$INT$FILE;
ERROR: PROCEDURE(ERR) EXTERNAL;
DECLARE ERR ADDRESS;
END ERROR;
SCANNER: PROCEDURE EXTERNAL;
END SCANNER;
PRINT: PROCEDURE(A) EXTERNAL;
DECLARE A ADDRESS;
END PRINT;
PRINT$DEC: PROCEDURE(VAL) EXTERNAL;
DECLARE VAL ADDRESS;
END PRINT$DEC;
CRLF: PROCEDURE EXTERNAL;
END CRLF;
REWIND$SOURCE$FILE: PROCEDURE EXTERNAL;
END REWIND$SOURCE$FILE;
GETCHAR: PROCEDURE BYTE EXTERNAL;
END GETCHAR;
WRITE$INT$FILE: PROCEDURE EXTERNAL;
END WRITE$INT$FILE;
CLOSE$INT$FILE: PROCEDURE EXTERNAL;
END CLOSE$INT$FILE;
/*
*********************************************************
* *
* SYMBOL TABLE PROCEDURES *
* *
* THE SYMBOL TABLE IS BUILT FROM .MEMORY TOWARD *
* THE LARGEST USABLE ADDRESS WHICH IS STORED IN MAX. *
* INFORMATION REQUIRED DURING FOR STATEMENT CODE *
* GENERATION IS MAINTAINED STARTING AT MAX AND *
* WORKING DOWN TOWARD THE TOP OF THE SYMBOL TABLE *
* THE FOLLOWING ARE MAJOR GLOBAL VARIABLES USED *
* BY THE SYMBOL TABLE AND THEIR MEANING: *
* SBTBLTOP - CURRENT POSITION OF FOR/NEXT *
* STACK. *
* SBTBL - CURRENT "TOP" OF SYMBOL TABLE *
* BASE - ADDRESS OF BEGINNING OF ENTRY. THIS *
* MUST BE SET BEFORE AN ENTRY MAY BE *
* ACCESSED. *
* PRINTNAME - ADDRESS OF PRINTNAME OF AN ENTRY *
* TO BE USED IN REFERENCE TO THE *
* SYMBOL TABLE. *
* SYMHASH - HASH OF TOKEN REFERENCE BY *
* PRINTNAME *
* *
* THE FOLLOWING IS THE STRUCTURE OF A SYMBOL *
* TABLE ENTRY: *
* LENGTH OF PRINTNAME - 1 BYTE *
* COLLISION FIELD - 2 BYTES *
* PRINTNAME - VARIABLE LENGTH *
* TYPE - 1 BYTE *
* LEFTMOST BIT OF THIS BYTE IS A FLAG *
* TO INDICATE IF THE ADDRESS HAS BEEN *
* SET. *
* LOCATION - 2 BYTES *
* SUBTYPE - 1 BYTES *
* *
* THE FOLLOWING GLOBAL ROUTINES ARE PROVIDED *
* FOR SYMBOL TABLE MANIPULATION: *
* LOOKUP ENTER GETLEN GETYPE *
* SETYPE GETRES GETADDR SETADDR *
* SETSUBTYPE GETSUBTYPE UNLINK RELINK *
* *
*********************************************************
*/
/* GLOBAL VARIABLES (DEFINED IN BASIC.PLM) */
DECLARE
BEXT LITERALLY 'BYTE EXTERNAL',
AEXT LITERALLY 'ADDRESS EXTERNAL',
/* LITERAL DECLARATIONS FOR PARSE TABLE ENTRIES */
FLOATPT LITERALLY '49',
STRING LITERALLY '50',
PASS1 BEXT,
PASS2 BEXT,
LISTPROD BEXT,
ERRORCOUNT AEXT,
DEBUGLN BEXT,
COMPILING BEXT,
DATACT AEXT, /* COUNTS SIZE OF DATA AREA */
FORSTMT BEXT,
RANDOMFILE BEXT,
FILEIO BEXT,
INPUTSTMT BEXT,
GOSUBSTMT BEXT,
NEXTCHAR BEXT,
FUNCOP BEXT,
ACCLEN BEXT,
ACCUM(IDENTSIZE) BEXT,
CONT BEXT,
LINENO BEXT,
SEPARATOR BEXT;
DECLARE /* LOCAL VARIABLES */
MAX ADDRESS AT (6H), /* DOS ADDRESS */
ULERRORFLAG BYTE INITIAL(FALSE),
CODESIZE ADDRESS, /* COUNTS SIZE OF CODE AREA */
PRTCT ADDRESS, /* COUNTS PRT ENTRIES */
FDACT ADDRESS, /* COUNTS FDA ENTRIES */
NEXTSTMTPTR ADDRESS,
NEXTADDRESS BASED NEXTSTMTPTR (4) ADDRESS,
NEXTBYTEV BASED NEXTSTMTPTR(2) BYTE,
NEXTBYTE BASED NEXTSTMTPTR BYTE, /* SIMPLE VERSION OF 'V' */
FORCOUNT BYTE INITIAL(0),
BASE ADDRESS, /* BASE OF CURRENT ENTRY IN SYMBOL */
HASHTABLE(HASHTBLSIZE) ADDRESS,
SBTBLTOP ADDRESS, /* CURRENT TOP OF SYMBOL TABLE */
FORADDRESS BASED SBTBLTOP (4) ADDRESS, /* FOR STMT INFO */
SBTBL ADDRESS,
PTRV BASED BASE (2) BYTE, /* FIRST BYTE OF ENTRY */
PTR BASED BASE BYTE, /* SIMPLE PTRV */
APTRADDR ADDRESS, /* UTILITY VARIABLE TO ACCESS TABLE */
BYTEPTRV BASED APTRADDR (2) BYTE,
BYTEPTR BASED APTRADDR BYTE, /* SIMPLE BYTEPTRV */
ADDRPTR BASED APTRADDR ADDRESS,
PRINTNAME ADDRESS, /* SET PRIOR TO LOOKUP OR ENTER */
SYMHASH BYTE; /* ALSO SET PRIOR TO LOOKUP OR ENTER */
IN$SYMTBL: PROCEDURE PUBLIC;
/* FILL HASHTABLE WITH 0'S */
IF PASS1 THEN
DO;
CALL FILL(.HASHTABLE,0,SHL(HASHTBLSIZE,1));
SBTBL = .MEMORY;
END;
/* INITIALIZE POINTER TO TOP OF SYMBOL TABLE */
SBTBLTOP, NEXTSTMTPTR = MAX - 2;
NEXTBYTEV(1) =0;
RETURN;
END IN$SYMTBL;
SETADDRPTR: PROCEDURE(OFFSET); /* SET PTR FOR ADDR REFERENCE */
DECLARE
OFFSET BYTE;
APTRADDR = BASE + PTR + OFFSET; /* POSITION FOR ADDR REFERENCE */
RETURN;
END SETADDRPTR;
GETHASH: PROCEDURE BYTE;
DECLARE HASH BYTE,
I BYTE;
HASH = 0;
APTRADDR = BASE + 2;
DO I = 1 TO PTR;
HASH = (HASH + BYTEPTRV(I)) AND HASHMASK;
END;
RETURN HASH;
END GETHASH;
NEXTENTRY: PROCEDURE;
BASE = BASE + PTR + 7;
RETURN;
END NEXTENTRY;
SETLINK: PROCEDURE;
APTRADDR = BASE + 1;
RETURN;
END SETLINK;
HASHTBL$OF$SYMHASH: PROCEDURE ADDRESS;
RETURN HASHTABLE(SYMHASH);
END HASHTBL$OF$SYMHASH;
LIMITS: PROCEDURE(COUNT);
/*
CHECK TO SEE IF ADDITIONAL SBTBL WILL OVERFLOW LIMITS OF
MEMORY. IF SO THEN PUNT ELSE RETURN
*/
DECLARE COUNT BYTE; /*SIZE BEING ADDED IS COUNT */
IF SBTBLTOP <= (SBTBL + COUNT) THEN
DO;
PASS2 = TRUE; /* TO PRINT ERROR MSG */
CALL ERROR('TO');
CALL MON3;
END;
RETURN;
END LIMITS;
SETADDR: PROCEDURE(LOC);
/*SET THE ADDRESS FIELD AND RESOLVED BIT*/
DECLARE LOC ADDRESS;
CALL SETADDRPTR (4);
ADDRPTR=LOC;
APTRADDR = APTRADDR - 1;
BYTEPTR=BYTEPTR OR 80H;
RETURN;
END SETADDR;
LOOKUP: PROCEDURE BYTE;
/*
CHECK TO SEE IF P/N LOCATED AT ADDR IN PRINTNAME IS IN SBTBL
RETURN TRUE IF IN SBTBL
RETURN FALSE IF NOT IN SBTBL.
BASE=ADDRESS IF IN SBTBL
*/
DECLARE
LEN BYTE,
N BASED PRINTNAME (2) BYTE; /* N IS LENGTH OF P/N */
BASE = HASHTBL$OF$SYMHASH;
DO WHILE BASE <> 0;
IF(LEN := PTR) = N(0) THEN
DO WHILE (PTRV(LEN + 2) = N(LEN));
IF (LEN := LEN - 1) = 0 THEN
RETURN TRUE;
END;
CALL SETLINK;
BASE = ADDRPTR;
END;
RETURN FALSE;
END LOOKUP;
ENTER: PROCEDURE;
/*
ENTER TOKEN REFERENCE BY PRINTNAME AND SYMHASH
INTO NEXT AVAILABLE LOCATION IN THE SYMBOL TABLE.
SET BASE TO BEGINNING OF THIS ENTRY AND INCREMENT
SBTBL. ALSO CHECK FOR SYMBOL TABLE FULL.
*/
DECLARE
I BYTE,
N BASED PRINTNAME BYTE;
CALL LIMITS(I:=N+7);
BASE = SBTBL; /* BASE FOR NEW ENTRY */
CALL MOVE(PRINTNAME + 1,SBTBL + 3,(PTR := N));
CALL SETADDRPTR(3);/* SET RESOLVE BIT TO 0 */
BYTEPTR = 0;
CALL SETLINK;
ADDRPTR = HASHTBL$OF$SYMHASH;
HASHTABLE(SYMHASH) = BASE;
SBTBL = SBTBL + I;
RETURN;
END ENTER;
GETLEN: PROCEDURE BYTE; /*RETURN LENGTH OF THE P/N */
RETURN PTR;
END GETLEN;
GETYPE: PROCEDURE BYTE; /*RETURNS TYPE OF VARIABLE */
CALL SETADDRPTR (3);
RETURN (BYTEPTR AND 7FH);
END GETYPE;
SETYPE: PROCEDURE (TYPE); /*SET TYPEFIELD = TYPE */
DECLARE TYPE BYTE;
CALL SETADDRPTR (3);
BYTEPTR = BYTEPTR OR TYPE;
/*THIS SETS THE TYPE AND PRESERVES RESOLVED BIT */
RETURN;
END SETYPE;
GETRES: PROCEDURE BYTE;
/*
RETURN TRUE IF RESOLVED BIT = 1,
RETURN FALSE IF RESOLVED BIT = 0
*/
CALL SETADDRPTR(3);
RETURN ROL(BYTEPTR,1);
END GETRES;
GETADDR: PROCEDURE ADDRESS;
/*RETURN THE ADDRESS OF THE P/N LOCATION */
CALL SETADDRPTR(4);
RETURN ADDRPTR;
END GETADDR;
SETSUBTYPE: PROCEDURE(STYPE); /*INSERT THE SUBTYPE IN SBTBL */
DECLARE STYPE BYTE;
CALL SETADDRPTR (6);
BYTEPTR=STYPE;
RETURN;
END SETSUBTYPE;
GETSUBTYPE: PROCEDURE BYTE; /*RETURN THE SUB TYPE */
CALL SETADDRPTR (6);
RETURN BYTEPTR;
END GETSUBTYPE;
UNLINK: PROCEDURE;
DECLARE NEXTA ADDRESS,
NUMPARM BYTE,
I BYTE,
ENTRYPT BASED NEXTA ADDRESS;
NUMPARM = GETYPE;
DO I = 1 TO NUMPARM;
CALL NEXTENTRY;
NEXTA = SHL(GETHASH,1) + .HASHTABLE; /* ITS ON THIS CHAIN */
DO WHILE ENTRYPT <> BASE;
NEXTA = ENTRYPT + 1;
END;
CALL SETLINK;
ENTRYPT = ADDRPTR;
END;
RETURN;
END UNLINK;
RELINK: PROCEDURE;
DECLARE
TEMPA ADDRESS,
I BYTE,
NUMPARM BYTE,
LOC BASED TEMPA ADDRESS;
NUMPARM = GETYPE;
DO I = 1 TO NUMPARM;
CALL NEXTENTRY;
TEMPA = BASE + 1;
LOC = HASHTABLE(GETHASH);
HASHTABLE(GETHASH) = BASE;
END;
RETURN;
END RELINK;
/*
*********************************************************
* *
* **** PARSER AND CODE GENERATION SECTION **** *
* *
*********************************************************
*/
/*
MNEMMONICS FOR BASIC-E MACHINE
*/
DECLARE
FAD LIT '0', DUP LIT '18', WST LIT '36',
FMI LIT '1', XCH LIT '19', RDF LIT '37',
FMU LIT '2', STD LIT '20', RDB LIT '38',
FDI LIT '3', SLT LIT '21', ECR LIT '39',
EXP LIT '4', SGT LIT '22', WRB LIT '40',
LSS LIT '5', SEQ LIT '23', RDN LIT '41',
GTR LIT '6', SNE LIT '24', RDS LIT '42',
EQU LIT '7', SGE LIT '25', WRN LIT '43',
NEQ LIT '8', SLE LIT '26', WRS LIT '44',
GEQ LIT '9', STS LIT '27', OPN LIT '45',
LEQ LIT '10', ILS LIT '28', CON LIT '46',
NOTO LIT '11', CAT LIT '29', RST LIT '47',
ANDO LIT '12', PRO LIT '30', NEG LIT '48',
BOR LIT '13', RTN LIT '31', RES LIT '49',
LOD LIT '14', ROW LIT '32', NOP LIT '50',
STO LIT '15', SUBO LIT '33', DAT LIT '51',
XIT LIT '16', RDV LIT '34', DBF LIT '52',
DEL LIT '17', WRV LIT '35', NSP LIT '53',
BRS LIT '54', BRC LIT '55', BFC LIT '56',
BFN LIT '57', CVB LIT '58', RCN LIT '59',
DRS LIT '60', DRF LIT '61', EDR LIT '62',
EDW LIT '63', CLS LIT '64', RON LIT '91',
CKO LIT '92', EXR LIT '93', DEF LIT '94',
BOL LIT '95', ADJ LIT '96', POT LIT '40',
IRN LIT '77';
DECLARE
STATE STATESIZE PUBLIC,
/*
THE FOLLOWING VECTORS ARE USED AS PARSE STACKS
SYNTHESIZE AND THE PARSER ACCESS THESE ARRAYS
*/
STATESTACK(PSTACKSIZE) STATESIZE PUBLIC,
HASH(PSTACKSIZE) BYTE PUBLIC,
SYMLOC(PSTACKSIZE) ADDRESS PUBLIC,
SRLOC(PSTACKSIZE) ADDRESS PUBLIC,
VAR(PSTACKSIZE) BYTE PUBLIC,
TYPE(PSTACKSIZE) BYTE PUBLIC,
STYPE(PSTACKSIZE) BYTE PUBLIC,
VARC(VARCSIZE) BYTE PUBLIC,
ONSTACK(MAXONCOUNT) BYTE,
ONSP BYTE AT (.ONSTACK(0)),
VARINDEX BYTE PUBLIC, /* INDEX INTO VAR */
SP BYTE PUBLIC,
MP BYTE PUBLIC,
MPP1 BYTE PUBLIC,
NOLOOK BYTE PUBLIC,
IFLABLNG BYTE INITIAL(2),
/*
THE FOLLOWING VARABLES ARE USED TO GENERATE
COMPILER LABELS.
*/
IFLAB2 BYTE INITIAL(23),
IFLABLE BYTE;
EMITCON: PROCEDURE(CHAR);
/*
WRITES NUMERIC CONSTANTS DURING PASS1
*/
DECLARE CHAR BYTE;
IF PASS1 THEN
CALL EMIT(CHAR);
RETURN;
END EMITCON;
IN$SYN: PROCEDURE PUBLIC;
DECLARE CONZERO(*) BYTE DATA(01H,30H);
DECLARE CONONE(*) BYTE DATA(01H,31H);
CODESIZE,DATACT,ONSP,IFLABLE = 0;
FDACT = 1;
PRTCT = 0FFFFH;
CALL SET$FLAGS;
IF PASS1 THEN
DO;
CALL SETUP$INT$FILE;
PRINTNAME = .CONONE(0);
SYMHASH = 31H;
CALL ENTER;
CALL EMITCON(31H);
CALL EMITCON('$');
CALL SETADDR(0); /* CONSTANT 1 IS AT FDA POS 0 */
CALL SETYPE(4); /* TYPE CONST */
PRINTNAME = .CONZERO(0);
SYMHASH = 30H;
CALL ENTER;
CALL EMITCON(30H);
CALL EMITCON('$');
CALL SETADDR(1);
CALL SETYPE(4);
END;
RETURN;
END IN$SYN;
SYNTHESIZE: PROCEDURE(PRODUCTION) PUBLIC;
DECLARE
PRODUCTION BYTE;
DECLARE
/*
THESE LITERALS DEFINE DIFFERENT "TYPES" WHICH
MAY BE PLACED IN THE TYPE FIELD OF THE SYMBOL
TABLE BY ROUTINES IN SYNTHESIZE
*/
SIMVAR LIT '00H',
SUBVAR LIT '02',
CONST LIT '04',
LABLE LIT '08',
UNFUNC LIT '0AH';
DECLARE
/*
THE FOLLOWING VARIABLES ARE USED TO HOLD THE
CONTENTS OF THE PARSE STACKS DURING EXECUTION
OF SYNTHESIZE. THE PROCEDURE COPY IS CALLED
TO UPDATE EACH OF THESE VARIABLES ON EACH CALL
TO SYNTHESIZE. THIS REDUCES THE NUMBER OF
SUBSCRIPT REFERENCES REQUIRED
*/
(TYPESP,TYPEMP,TYPEMP1) BYTE,
(STYPESP,STYPEMP,STYPEMP1) BYTE,
(HASHSP,HASHMP,HASHMP1) BYTE,
(SYMLOCSP,SYMLOCMP, SYMLOCMP1) ADDRESS,
(SRLOCSP,SRLOCMP) ADDRESS;
/*
*********************************************************
* *
* THE FOLLOWING PROCEDURES ARE USED BY SYTHESIZE *
* TO GENERATE CODE REQUIRED BY THE PRODUCTIONS *
* *
* THE FIRST GROUP OF PROCEDURES CONSISTING OF *
* COPY AND THE SET-------- PROCEDURES ARE USED *
* TO PREVENT THE LARGE AMOUNT OF SUBSCRIPTING *
* THAT WOULD BE REQUIRED TO ACCESS THE PARSE *
* STACKS DURING CODE GENERATION. *
* *
* THE REMAINING PROCEDURES DIRECTLY SUPPORT CODE *
* GENERATION AND ARE ARRANGED IN LOGICAL GROUPS *
* SUCH AS THOSE WHICH ASSIST IN ACCESSING THE *
* SYMBOL TABLE OR THOSE USED TO GENERATE INTERNAL *
* COMPILER LABLES. *
* *
*********************************************************
*/
COPY: PROCEDURE;
TYPESP = TYPE(SP);
TYPEMP1 = TYPE(MPP1);
TYPEMP = TYPE(MP);
STYPESP = STYPE(SP);
STYPEMP1 = STYPE(MPP1);
STYPEMP = STYPE(MP);
SYMLOCSP = SYMLOC(SP);
SYMLOCMP1 = SYMLOC(MPP1);
SYMLOCMP = SYMLOC(MP);
HASHMP = HASH(MP);
HASHMP1 = HASH(MPP1);
HASHSP = HASH(SP);
SRLOCSP = SRLOC(SP);
SRLOCMP = SRLOC(MP);
RETURN;
END COPY;
SETSYMLOCSP: PROCEDURE(A);
DECLARE A ADDRESS;
SYMLOC(SP) = A;
RETURN;
END SETSYMLOCSP;
SETSYMLOCMP: PROCEDURE(A);
DECLARE A ADDRESS;
SYMLOC(MP) = A;
RETURN;
END SETSYMLOCMP;
SETTYPESP: PROCEDURE(B);
DECLARE B BYTE;
TYPE(SP) = B;
RETURN;
END SETTYPESP;
SETSTYPESP: PROCEDURE(B);
DECLARE B BYTE;
STYPE(SP) = B;
RETURN;
END SETSTYPESP;
SETSTYPEMP: PROCEDURE(B);
DECLARE B BYTE;
STYPE(MP) = B;
RETURN;
END SETSTYPEMP;
SETTYPEMP: PROCEDURE(B);
DECLARE B BYTE;
TYPE(MP) = B;
RETURN;
END SETTYPEMP;
SETHASHMP: PROCEDURE(B);
DECLARE B BYTE;
HASH(MP) = B;
RETURN;
END SETHASHMP;
SETHASHSP: PROCEDURE(B);
DECLARE B BYTE;
HASH(SP) = B;
RETURN;
END SETHASHSP;
SETSRLOCSP: PROCEDURE(A);
DECLARE A ADDRESS;
SRLOC(SP) = A;
RETURN;
END SETSRLOCSP;
GENERATE: PROCEDURE(OBJCODE);
/*
WRITES GENERATED CODE AND COUNTS SIZE
OF CODE AREA.
*/
DECLARE OBJCODE BYTE;
CODESIZE = CODESIZE + 1;
IF NOT PASS1 THEN
CALL EMIT(OBJCODE);
RETURN;
END GENERATE;
CALC$VARC: PROCEDURE(B) ADDRESS;
DECLARE B BYTE;
RETURN VAR(B) + .VARC;
END CALC$VARC;
SETLOOKUP: PROCEDURE(A);
DECLARE A BYTE;
PRINTNAME = CALC$VARC(A);
SYMHASH = HASH(A);
RETURN;
END SETLOOKUP;
LOOKUP$ONLY: PROCEDURE(A) BYTE;
DECLARE A BYTE;
CALL SETLOOKUP(A);
IF LOOKUP THEN
RETURN TRUE;
RETURN FALSE;
END LOOKUP$ONLY;
NORMAL$LOOKUP: PROCEDURE(A) BYTE;
DECLARE A BYTE;
IF LOOKUP$ONLY(A) THEN
RETURN TRUE;
CALL ENTER;
RETURN FALSE;
END NORMAL$LOOKUP;
COUNTPRT: PROCEDURE ADDRESS;
/* COUNTS THE SIZE OF THE PRT */
RETURN (PRTCT := PRTCT + 1);
END COUNTPRT;
GENTWO: PROCEDURE(A);
/* WRITES TWO BYTES OF OBJECT CODE ON DISK FOR LITERALS */
DECLARE A ADDRESS;
CALL GENERATE(HIGH(A));
CALL GENERATE(LOW(A));
RETURN;
END GENTWO;
LITERAL: PROCEDURE(A);
DECLARE A ADDRESS;
CALL GENTWO(A OR 8000H);
RETURN;
END LITERAL;
LITLOAD: PROCEDURE(A);
DECLARE A ADDRESS;
CALL GENTWO(A OR 0C000H);
RETURN;
END LITLOAD;
LINE$NUMBER: PROCEDURE;
IF DEBUGLN THEN
DO;
CALL LITERAL(LINENO);
CALL GENERATE(BOL);
END;
RETURN;
END LINE$NUMBER;
SETIFNAME: PROCEDURE;
PRINTNAME = .IFLABLNG;
SYMHASH = IFLABLE AND HASHMASK;
RETURN;
END SETIFNAME;
ENTER$COMPILER$LABEL: PROCEDURE(B);
DECLARE B BYTE;
IF PASS1 THEN
DO;
CALL SETIFNAME;
CALL ENTER;
CALL SETADDR(CODESIZE + B);
END;
RETURN;
END ENTER$COMPILER$LABEL;
SET$COMPILER$LABEL: PROCEDURE;
DECLARE X BYTE;
IFLABLE = IFLABLE + 1;
CALL SETIFNAME;
X = LOOKUP;
RETURN;
END SET$COMPILER$LABEL;
COMPILER$LABEL: PROCEDURE;
CALL SET$COMPILER$LABEL;
CALL GEN$TWO(GETADDR);
RETURN;
END COMPILER$LABEL;
CHKTYP1: PROCEDURE BYTE; /* CHECK MP,SP BOTH FLOATING PT */
IF((STYPEMP <> FLOATPT) OR (STYPESP <> FLOATPT)) THEN
DO;
CALL ERROR('MF');
RETURN FALSE;
END;
RETURN TRUE;
END CHKTYP1;
CHKTYP2: PROCEDURE BYTE; /* CHECK MP,SP BOTH SAME TYPE */
IF STYPESP <> STYPEMP THEN
DO;
CALL ERROR('MM');
RETURN FALSE;
END;
RETURN TRUE;
END CHKTYP2;
CHKTYP3: PROCEDURE BYTE;
CALL SETSTYPEMP(STYPESP);
IF STYPESP = FLOATPT THEN
RETURN TRUE;
CALL ERROR('MF');
RETURN FALSE;
END CHKTYP3;
CHKTYP4: PROCEDURE;
IF STYPEMP1 = STRING THEN
CALL ERROR('MF');
CALL GENERATE(RON);
END CHKTYP4;
CHKTYP5: PROCEDURE;
CALL CHKTYP4;
CALL SETTYPEMP(TYPEMP := TYPEMP + 1);
END CHKTYP5;
SUBCALC: PROCEDURE;
CALL SETSUBTYPE(TYPESP);
CALL GENERATE(ROW);
CALL GENERATE(TYPESP);
CALL GENERATE(STD);
RETURN;
END SUBCALC;
GEN$STORE: PROCEDURE;
IF STYPEMP1 = FLOATPT THEN
CALL GENERATE(STD);
ELSE
CALL GENERATE(STS);
RETURN;
END GEN$STORE;
SETUP$INPUT: PROCEDURE;
CALL GENERATE(DBF);
INPUTSTMT = TRUE;
CALL GENERATE(RCN);
END SETUP$INPUT;
GET$FIELD: PROCEDURE;
GEN$READ: PROCEDURE(I,J);
DECLARE (I,J) BYTE;
IF STYPESP = STRING THEN
DO;
CALL GENERATE(I);
CALL GENERATE(STS);
END;
ELSE
DO;
CALL GENERATE(J);
CALL GENERATE(STD);
END;
RETURN;
END GEN$READ;
IF(TYPESP = SIMVAR) THEN
CALL LITERAL(SYMLOCSP);
IF INPUTSTMT THEN
CALL GEN$READ(RES,RDV);
ELSE
IF FILEIO THEN
CALL GEN$READ(RDS,RDN);
ELSE
CALL GEN$READ(DRS,DRF);
RETURN;
END GET$FIELD;
GEN$ON: PROCEDURE;
CALL GENERATE(RON);
CALL LITERAL(ONSTACK(ONSP := ONSP + 1));
CALL GENERATE(CKO);
CALL GENERATE(BFN);
RETURN;
END GEN$ON;
GEN$ON$2: PROCEDURE;
ONSTACK(ONSP) = TYPESP;
RETURN;
END GEN$ON$2;
GENNEXT: PROCEDURE;
IF(FORCOUNT := FORCOUNT - 1) = 255 THEN
DO;
FORCOUNT = 0;
CALL ERROR('NU');
END;
ELSE
DO;
CALL GENERATE(BRS);
CALL GEN$TWO(NEXTADDRESS(2));
NEXTADDRESS(0) = CODESIZE OR 8000H;
DO WHILE NEXTBYTEV(1) > 127;
NEXTSTMTPTR = NEXTSTMTPTR + 8;
END;
END;
RETURN;
END GENNEXT;
GEN$NEXT$WITH$IDENT: PROCEDURE;
IF LOOKUP$ONLY(MPP1) AND (BASE = NEXTADDRESS(3)) THEN
CALL GENNEXT;
ELSE
CALL ERROR('NI');
RETURN;
END GEN$NEXT$WITH$IDENT;
CHECK$UL$ERROR: PROCEDURE;
IF ULERRORFLAG THEN
CALL ERROR('UL');
ULERRORFLAG = FALSE;
END CHECK$UL$ERROR;
FINDLABEL: PROCEDURE;
IF NORMAL$LOOKUP(SP) THEN
DO;
IF PASS2 AND (NOT GETRES) THEN
ULERRORFLAG = TRUE;
END;
RETURN;
END FINDLABEL;
RESOLVE$LABEL: PROCEDURE;
CALL FINDLABEL;
IF GOSUBSTMT THEN
CALL GENERATE(PRO);
ELSE
CALL GENERATE(BRS);
CALL GEN$TWO(GETADDR);
RETURN;
END RESOLVE$LABEL;
PROCESS$SIMPLE$VARIABLE: PROCEDURE(LOC);
DECLARE LOC BYTE;
IF NORMALLOOKUP(LOC) THEN
DO;
IF GETYPE <> SIMVAR THEN
CALL ERROR('IU');
END;
ELSE
DO;
CALL SETADDR(COUNTPRT);
CALL SETYPE(SIMVAR);
END;
CALL SETSYMLOCSP(SYMLOCSP:=GETADDR);
CALL SETTYPESP(SIMVAR);
IF FORSTMT THEN
DO;
FORSTMT = FALSE;
FORADDRESS(3) = BASE;
END;
END PROCESS$SIMPLE$VARIABLE;
GEN$ILS: PROCEDURE(WHERE);
DECLARE STRPTR BYTE,
WHERE ADDRESS,
STRINGTOSPOOL BASED WHERE (2) BYTE;
CALL SETSTYPESP(STRING);
CALL GENERATE(ILS);
DO FOREVER;
DO STRPTR = 1 TO STRINGTOSPOOL(0);
CALL GENERATE(STRINGTOSPOOL(STRPTR));
END;
IF CONT THEN
CALL SCANNER;
ELSE
DO;
CALL GENERATE(0);
RETURN;
END;
END; /* OF DO FOREVER */
END GEN$ILS;
GENCON: PROCEDURE;
DECLARE I BYTE;
CALL GENERATE(CON);
CALL SETTYPESP(CONST);
CALL SETSTYPESP(FLOATPT);
IF LOOKUP$ONLY(SP) AND (GETYPE = CONST) THEN
CALL GEN$TWO(GETADDR);
ELSE
DO;
DO I = 1 TO ACCLEN;
CALL EMITCON(ACCUM(I));
END;
CALL EMITCON('$');
CALL GEN$TWO(FDACT := FDACT + 1);
END;
RETURN;
END GENCON;
PUT$FIELD: PROCEDURE;
IF FILEIO THEN
DO;
IF STYPESP = FLOATPT THEN
CALL GENERATE(WRN);
ELSE
CALL GENERATE(WRS);
END;
ELSE
IF STYPESP = FLOATPT THEN
DO;
IF TYPESP <> 74 THEN /* IS IT A TAB */
CALL GENERATE(WRV);
END;
ELSE
CALL GENERATE(WST);
RETURN;
END PUT$FIELD;
GEN$PARM: PROCEDURE;
IF TYPEMP = UNFUNC THEN
DO;
BASE = SYMLOCMP;
CALL NEXTENTRY;
CALL SETSYMLOCMP(BASE);
CALL SETHASHMP(HASHMP := HASHMP - 1);
CALL LITERAL(GETADDR);
END;
RETURN;
END GEN$PARM;
CHECKPARM: PROCEDURE;
IF TYPEMP = UNFUNC THEN
DO;
BASE = SYMLOCMP;
IF(GETSUBTYPE <> STYPEMP1) THEN
CALL ERROR('FP');
CALL GEN$STORE;
RETURN;
END;
IF(HASHMP XOR (STYPEMP1 <> FLOATPT)) THEN
CALL ERROR('FP');
CALL SETHASHMP(SHR(HASHMP,1));
CALL SETSTYPEMP(STYPEMP := STYPEMP -1);
RETURN;
END CHECKPARM;
FUNCGEN: PROCEDURE;
IF TYPEMP = UNFUNC THEN
DO;
IF HASHMP <> 0 THEN
CALL ERROR('FN');
CALL GENERATE(PRO);
BASE = SRLOCSP;
CALL GEN$TWO(GETADDR);
RETURN;
END;
IF((STYPEMP AND 03H) <>0) THEN
CALL ERROR('FN');
CALL GENERATE(TYPEMP);
IF ROL(STYPEMP,2) THEN
CALL SETSTYPEMP(STRING);
ELSE
CALL SETSTYPEMP(FLOATPT);
RETURN;
END FUNCGEN;
ENTER$PARM: PROCEDURE;
IF PASS1 THEN
DO;
CALL SETLOOKUP(MPP1);
CALL ENTER;
CALL SETADDR(COUNTPRT);
CALL SETSUBTYPE(STYPEMP1);
CALL SETYPE(SIMVAR);
CALL SETTYPEMP(TYPEMP + 1);
END;
RETURN;
END ENTER$PARM;
/*
**********************************************************
* *
* EXECUTION OF SYNTHESIS BEGINS HERE..... *
* *
**********************************************************
*/
IF LISTPROD AND PASS2 THEN
DO; /* IF LISTPROD SET PRINT OUT PRODUCTIONS */
CALL PRINT(.('PROD $'));
CALL PRINTDEC(PRODUCTION);
CALL CRLF;
END;
CALL COPY; /* SETUP FOR ACCESSING PARSE TABLES */
DO CASE PRODUCTION; /* CALL TO SYNTHESIS HANDLES ONE PROD */
/* CASE 0 NOT USED */ ;
/* 1 <PROGRAM> ::= <LINE NUMBER> <STATEMENT> _|_ */
;
/* 2 <LINE NUMBER> ::= <NUMBER> */
DO;
IF LOOKUP$ONLY(SP) THEN
DO;
IF GETRES THEN
DO;
IF CODESIZE <> GETADDR THEN
CALL ERROR('DL');
END;
ELSE
DO;
CALL SETADDR(CODESIZE);
CALL SETYPE(LABLE);
END;
END;
ELSE
SEPARATOR = ASTRICK;
CALL LINE$NUMBER;
END;
/* 3 | */
CALL LINE$NUMBER;
/* 4 <STATEMENT> ::= <STATEMENT LIST> */
CALL CHECK$UL$ERROR;
/* 5 | <IF STATEMENT> */
;
/* 6 | <END STATEMENT> */
;
/* 7 | <DIMENSION STATEMENT> */
;
/* 8 | <DEFINE STATEMENT> */
;
/* 9 <STATEMENT LIST> ::= <SIMPLE STATEMENT> */
;
/* 10 | <STATEMENT LIST> : */
/* 10 <SIMPLE STATEMENT> */
;
/* 11 <SIMPLE STATEMENT> ::= <LET STATEMENT> */
;
/* 12 | <ASSIGNMENT> */
;
/* 13 | <FOR STATEMENT> */
;
/* 14 | <NEXT STATEMENT> */
;
/* 15 | <FILE STATEMENT> */
;
/* 16 | <CLOSE STATEMENT> */
;
/* 18 | <PRINT STATEMENT> */
/* 17 | <READ STATEMENT> */
;
;
/* 19 | <GOTO STATEMENT> */
;
/* 20 | <GOSUB STATEMENT> */
;
/* 21 | <INPUT STATEMENT> */
;
/* 22 | <STOP STATEMENT> */
;
/* 23 | <RETURN STATEMENT> */
;
/* 24 | <ON STATEMENT> */
;
/* 25 | <RESTORE STATEMENT> */
;
/* 26 | <RANDOMIZE STATEMENT> */
;
/* 27 | <OUT STATEMENT> */
;
/* 28 | */
;
/* 29 <LET STATEMENT> ::= LET <ASSIGNMENT> */
;
/* 30 <ASSIGNMENT> ::= <ASSIGN HEAD> <EXPRESSION> */
IF CHKTYP2 THEN
CALL GEN$STORE;
/* 31 <ASSIGN HEAD> ::= <VARIABLE> = */
IF TYPEMP = SIMVAR THEN
CALL LITERAL(SYMLOCMP);
/* 32 <EXPRESSION> ::= <LOGICAL FACTOR> */
;
/* 33 | <EXPRESSION> <OR> <LOGICAL FACTOR> */
IF CHKTYP1 THEN
CALL GENERATE(TYPEMP1);
/* 34 <OR> ::= OR */
CALL SETTYPESP(BOR);
/* 35 | XOR */
CALL SETTYPESP(EXR);
/* 36 <LOGICAL FACTOR> ::= <LOGICAL SECONDARY> */
;
/* 37 | <LOGICAL FACTOR> AND */
/* 37 <LOGICAL SECONDARY> */
IF CHKTYP1 THEN
CALL GENERATE(ANDO);
/* 38 <LOGICAL SECONDARY> ::= <LOGICAL PRIMARY> */
;
/* 39 | NOT <LOGICAL PRIMARY> */
IF CHKTYP3 THEN
CALL GENERATE(NOTO);
/* 40 <LOGICAL PRIMARY> ::= <ARITHMETIC EXPRESSION> */
;
/* 41 | <ARITHMETIC EXPRESSION> */
/* 41 <RELATION> */
/* 41 <ARITHMETIC EXPRESSION> */
IF CHKTYP2 THEN
DO;
IF STYPESP = FLOATPT THEN
CALL GENERATE(TYPEMP1);
ELSE
DO;
CALL GENERATE(TYPEMP1 + 16);
CALL SETSTYPEMP(FLOATPT);
END;
END;
/* 42 <ARITHMETIC EXPRESSION> ::= <TERM> */
;
/* 43 | <ARITHMETIC EXPRESSION> + */
/* 43 <TERM> */
IF CHKTYP2 THEN
DO;
IF STYPESP = FLOATPT THEN
CALL GENERATE(FAD);
ELSE
CALL GENERATE(CAT);
END;
/* 44 | <ARITHMETIC EXPRESSION> - */
/* 44 <TERM> */
IF CHKTYP1 THEN
CALL GENERATE(FMI);
/* 45 | + <TERM> */
IF CHKTYP3 THEN ; /* NO ACTION REQUIRED */
/* 46 | - <TERM> */
IF CHKTYP3 THEN
CALL GENERATE(NEG);
/* 47 <TERM> ::= <PRIMARY> */
;
/* 48 | <TERM> * <PRIMARY> */
IF CHKTYP1 THEN
CALL GENERATE(FMU);
/* 49 | <TERM> / <PRIMARY> */
IF CHKTYP1 THEN
CALL GENERATE(FDI);
/* 50 <PRIMARY> ::= <ELEMENT> */
;
/* 51 | <PRIMARY> ** <ELEMENT> */
IF CHKTYP1 THEN
CALL GENERATE(EXP);
/* 52 <ELEMENT> ::= <VARIABLE> */
IF TYPESP = SIMVAR THEN
CALL LITLOAD(SYMLOCSP);
ELSE
CALL GENERATE(LOD);
/* 53 | <CONSTANT> */
;
/* 54 | <FUNCTION CALL> */
;
/* 55 | ( <EXPRESSION> ) */
CALL SETSTYPEMP(STYPEMP1);
/* 56 <VARIABLE> ::= <IDENTIFIER> */
CALL PROCESS$SIMPLE$VARIABLE(SP);
/* 57 | <SUBSCRIPT HEAD> <EXPRESSION> ) */
DO;
IF FORSTMT THEN
CALL ERROR('FI');
CALL CHKTYP5;
BASE = SYMLOCMP;
IF GETSUBTYPE <> TYPEMP THEN
CALL ERROR('SN');
CALL LITLOAD(GETADDR);
CALL GENERATE(SUBO);
CALL SETTYPEMP(SUBVAR);
END;
/* 58 <SUBSCRIPT HEAD> ::= <IDENTIFIER> ( */
DO;
IF((NOT LOOKUP$ONLY(MP)) OR (GETYPE <> SUBVAR)) THEN
CALL ERROR('IS');
CALL SETTYPEMP(0);
CALL SETSYMLOCMP(BASE);
END;
/* 59 | <SUBSCRIPT HEAD> <EXPRESSION> , */
CALL CHKTYP5;
/* 60 <FUNCTION CALL> ::= <FUNCTION HEADING> <EXPRESSION> ) */
DO;
CALL CHECKPARM;
SRLOCSP = SRLOCMP;
CALL FUNCGEN;
END;
/* 61 | <FUNCTION NAME> */
CALL FUNCGEN;
/* 62 <FUNCTION HEADING> ::= <FUNCTION NAME> ( */
CALL GEN$PARM;
/* 63 | <FUNCTION HEADING> <EXPRESSION> */
/* 63 , */
DO;
CALL CHECK$PARM;
CALL GEN$PARM;
END;
/* 64 <FUNCTION NAME> ::= <USERDEFINED NAME> */
IF LOOKUP$ONLY(SP) THEN
DO;
CALL SETSRLOCSP(BASE);
CALL SETSYMLOCSP(BASE);
CALL SETTYPESP(UNFUNC);
CALL SETHASHSP(GETYPE);
END;
ELSE
CALL ERROR('FU');
/* 65 | <PREDEFINED NAME> */
DO;
CALL SETTYPESP(FUNCOP);
CALL SETHASHSP(SHR(STYPESP,2) AND 07H);
END;
/* 66 <CONSTANT> ::= <NUMBER> */
CALL GENCON;
/* 67 | <STRING> */
CALL GEN$ILS(.ACCUM);
/* 68 <RELATION> ::= = */
CALL SETTYPESP(7);
/* 69 | > = */
CALL SETTYPEMP(9);
/* 70 | GE */
CALL SETTYPEMP(9);
/* 71 | < = */
CALL SETTYPEMP(10);
/* 72 | LE */
CALL SETTYPEMP(10);
/* 73 | > */
CALL SETTYPESP(6);
/* 74 | < */
CALL SETTYPESP(5);
/* 75 | < > */
CALL SETTYPEMP(8);
/* 76 | NE */
CALL SETTYPEMP(8);
/* 77 <FOR STATEMENT> ::= <FOR HEAD> TO <EXPRESSION> */
/* 77 <STEP CLAUSE> */
DO;
BASE = FORADDRESS(3);
IF TYPESP THEN
CALL GENERATE(DUP);
CALL LITLOAD(GETADDR);
CALL GENERATE(FAD);
IF TYPESP THEN
DO;
CALL LITERAL(GETADDR);
CALL GENERATE(XCH);
END;
CALL GENERATE(STO);
IF TYPESP THEN
DO;
CALL GENERATE(XCH);
CALL LITERAL(0);
CALL GENERATE(LSS);
CALL LITERAL(5);
CALL GENERATE(BFC);
CALL GENERATE(LEQ);
CALL LITERAL(2);
CALL GENERATE(BFN);
END;
CALL GENERATE(GEQ);
CALL GENERATE(BRC);
CALL GEN$TWO(FORADDRESS(0));
FORADDRESS(1) = CODESIZE;
END;
/* 78 <FOR HEAD> ::= <FOR> <ASSIGNMENT> */
DO;
CALL GENERATE(BRS);
CALL GEN$TWO(FORADDRESS(1));
FORADDRESS(2) = CODESIZE;
END;
/* 79 <FOR> ::= FOR */
DO;
FORSTMT = TRUE;
SBTBLTOP,NEXTSTMTPTR = SBTBLTOP - 8;
NEXTBYTEV(1) = NEXTBYTEV(1) AND 7FH;
CALL LIMITS(0);
FORCOUNT = FORCOUNT + 1;
END;
/* 80 <STEP CLAUSE> ::= STEP <EXPRESSION> */
CALL SETTYPEMP(TRUE);
/* 81 | */
DO;
BASE = FORADDRESS(3);
CALL LITERAL(GETADDR);
CALL SETTYPESP(FALSE);
CALL GENERATE(CON);
CALL GEN$TWO(0);
END;
/* 82 <IF STATEMENT> ::= <IF GROUP> */
CALL ENTER$COMPILER$LABEL(0);
/* 83 | <IF ELSE GROUP> <STATEMENT LIST> */
CALL ENTER$COMPILER$LABEL(0);
/* 84 | IF END # <EXPRESSION> THEN <NUMBER> */
DO;
CALL GENERATE(RON);
CALL GENERATE(DEF);
CALL FINDLABEL;
CALL GEN$TWO(GETADDR);
END;
/* 85 <IF GROUP> ::= <IF HEAD> <STATEMENT LIST> */
;
/* 86 | <IF HEAD> <NUMBER> */
CALL RESOLVE$LABEL;
/* 87 <IF ELSE GROUP> ::= <IF HEAD> <STATEMENT LIST> ELSE */
DO;
CALL ENTER$COMPILER$LABEL(3);
CALL GENERATE(BRS);
CALL COMPILER$LABEL;
END;
/* 88 <IF HEAD> ::= IF <EXPRESSION> THEN */
DO;
IF STYPEMP1 = STRING THEN
CALL ERROR('IE');
CALL GENERATE(BRC);
CALL COMPILER$LABEL;
END;
/* 89 <DEFINE STATEMENT> ::= <UD FUNCTION NAME> */
/* 89 <DUMMY ARG LIST> = <EXPRESSION> */
IF CHKTYP2 THEN
DO;
BASE = SYMLOCMP;
CALL SETYPE(TYPEMP1);
CALL UNLINK;
CALL GENERATE(XCH);
CALL GENERATE(RTN);
CALL ENTER$COMPILER$LABEL(0);
END;
/* 90 <UD FUNCTION NAME> ::= DEF <USERDEFINED NAME> */
DO;
DECLARE FLAG BYTE;
CALL GENERATE(BRS);
CALL COMPILER$LABEL;
FLAG = NORMAL$LOOKUP(SP);
CALL SETSTYPEMP(STYPESP);
CALL SETSYMLOCMP(BASE);
IF PASS1 THEN
DO;
IF FLAG THEN
CALL ERROR('FD');
CALL SETADDR(CODESIZE);
END;
ELSE
CALL RELINK;
END;
/* 91 <DUMMY ARG LIST> ::= <DUMMY ARG HEAD> <IDENTIFIER> ) */
CALL ENTER$PARM;
/* 92 | */
CALL SETTYPEMP(0);
/* 93 <DUMMY ARG HEAD> ::= ( */
CALL SETTYPEMP(0);
/* 94 | <DUMMY ARG HEAD> <IDENTIFIER> , */
CALL ENTER$PARM;
/* 95 <FILE STATEMENT> ::= <FILE HEAD> <FILE DECLERATION> */
;
/* 96 <FILE HEAD> ::= FILE */
;
/* 97 | <FILE HEAD> <FILE DECLERATION> , */
;
/* 98 <FILE DECLERATION> ::= <IDENTIFIER> <FILE REC SIZE> */
DO;
CALL PROCESS$SIMPLE$VARIABLE(MP);
IF STYPEMP = FLOATPT THEN
CALL ERROR('IF');
CALL LITLOAD(SYMLOCSP);
CALL GENERATE(OPN);
END;
/* 99 <FILE REC SIZE> ::= ( <EXPRESSION> ) */
CALL CHKTYP4;
/* 100 | */
CALL LITERAL(0);
/* 101 <DIMENSION STATEMENT> ::= DIM */
/* 101 <DIMENSION VARIABLE LIST> */
;
/* 102 <DIMENSION VARIABLE LIST> ::= <DIMENSION VARIABLE> */
CALL SUBCALC;
/* 103 | */
/* 103 <DIMENSION VARIABLE LIST> */
/* 103 , <DIMENSION VARIABLE> */
CALL SUBCALC;
/* 104 <DIMENSION VARIABLE> ::= <DIM VAR HEAD> <EXPRESSION> ) */
DO;
CALL CHKTYP5;
BASE = SYMLOCMP;
END;
/* 105 <DIM VAR HEAD> ::= <IDENTIFIER> ( */
DO;
IF NORMAL$LOOKUP(MP) AND PASS1 THEN
CALL ERROR('DP');
CALL SETYPE(SUBVAR);
IF PASS1 THEN
CALL SETADDR(COUNTPRT);
CALL LITERAL(GETADDR);
CALL SETTYPEMP(0);
CALL SETSYMLOCMP(BASE);
END;
/* 106 | <DIM VAR HEAD> <EXPRESSION> , */
CALL CHKTYP5;
/* 107 <CLOSE STATEMENT> ::= CLOSE <CLOSE LIST> */
;
/* 108 <CLOSE LIST> ::= <EXPRESSION> */
DO;
IF STYPESP = STRING THEN
CALL ERROR('MF');
CALL GENERATE(RON);
CALL GENERATE(CLS);
END;
/* 109 | <CLOSE LIST> , <EXPRESSION> */
DO;
IF STYPESP = STRING THEN
CALL ERROR('MF');
CALL GENERATE(RON);
CALL GENERATE(CLS);
END;
/* 110 <READ STATEMENT> ::= READ <FILE OPTION> <READ LIST> */
IF FILEIO THEN
DO;
CALL GENERATE(EDR);
FILEIO = FALSE;
END;
/* 111 | READ <READ LIST> */
;
/* 112 <INPUT STATEMENT> ::= INPUT <PROMPT OPTION> */
/* 112 <READ LIST> */
DO;
CALL GENERATE(ECR);
INPUTSTMT = FALSE;
END;
/* 113 <PROMPT OPTION> ::= <CONSTANT> ; */
DO;
CALL PUT$FIELD;
CALL SETUP$INPUT;
END;
/* 114 | */
CALL SETUP$INPUT;
/* 115 <READ LIST> ::= <VARIABLE> */
CALL GET$FIELD;
/* 116 | <READ LIST> , <VARIABLE> */
CALL GET$FIELD;
/* 117 | */
FILEIO = FALSE;
/* 118 <PRINT STATEMENT> ::= PRINT <PRINT LIST> <PRINT END> */
;
/* 119 | PRINT <FILE OPTION> <FILE LIST> */
DO;
CALL GENERATE(EDW);
FILEIO = FALSE;
END;
/* 120 <PRINT LIST> ::= <EXPRESSION> */
CALL PUT$FIELD;
/* 121 | <PRINT LIST> <PRINT DELIM> */
/* 121 <EXPRESSION> */
CALL PUT$FIELD;
/* 122 | */
;
/* 123 <FILE LIST> ::= <EXPRESSION> */
CALL PUT$FIELD;
/* 124 | <EXPRESSION> , <EXPRESSION> */
CALL PUT$FIELD;
/* 125 <PRINT END> ::= <PRINT DELIM> */
;
/* 126 | */
CALL GENERATE(DBF);
/* 127 <FILE OPTION> ::= # <EXPRESSION> ; */
DO;
FILEIO = TRUE;
CALL GENERATE(RON);
CALL GENERATE(RDB);
END;
/* 128 | # <EXPRESSION> , <EXPRESSION> ; */
DO;
FILEIO = TRUE;
CALL GENERATE(RON);
CALL GENERATE(XCH);
CALL GENERATE(RON);
CALL GENERATE(RDF);
END;
/* 129 <PRINT DELIM> ::= ; */
;
/* 130 | , */
IF NOT FILEIO THEN
CALL GENERATE(NSP);
/* 131 <GOTO STATEMENT> ::= <GOTO> <NUMBER> */
CALL RESOLVE$LABEL;
/* 132 <ON STATEMENT> ::= <ON GOTO> <LABEL LIST> */
CALL GEN$ON$2;
/* 133 | <ON GOSUB> <LABEL LIST> */
DO;
CALL GEN$ON$2;
CALL ENTER$COMPILER$LABEL(0);
END;
/* 134 <ON GOTO> ::= ON <EXPRESSION> <GOTO> */
CALL GEN$ON;
/* 135 <ON GOSUB> ::= ON <EXPRESSION> <GOSUB> */
DO;
CALL SET$COMPILER$LABEL;
CALL LITERAL(GETADDR);
CALL GENERATE(ADJ);
CALL GENERATE(XCH);
CALL GEN$ON;
END;
/* 136 <LABEL LIST> ::= <NUMBER> */
DO;
CALL RESOLVE$LABEL;
CALL SETTYPESP(1);
END;
/* 137 | <LABEL LIST> , <NUMBER> */
DO;
CALL RESOLVE$LABEL;
CALL SETTYPEMP(TYPEMP + 1);
END;
/* 138 <GOSUB STATEMENT> ::= <GOSUB> <NUMBER> */
DO;
GOSUBSTMT = TRUE;
CALL RESOLVE$LABEL;
GOSUBSTMT = FALSE;
END;
/* 139 <GOTO> ::= GOTO */
;
/* 140 | GO TO */
;
/* 141 <GOSUB> ::= GOSUB */
;
/* 142 | GO SUB */
;
/* 143 <NEXT STATEMENT> ::= <NEXT HEAD> <IDENTIFIER> */
CALL GEN$NEXT$WITH$IDENT;
/* 144 | NEXT */
CALL GENNEXT;
/* 145 <NEXT HEAD> ::= NEXT */
;
/* 146 | <NEXT HEAD> <IDENTIFIER> , */
CALL GEN$NEXT$WITH$IDENT;
/* 147 <OUT STATEMENT> ::= OUT <EXPRESSION> , <EXPRESSION> */
IF STYPEMP1 <> FLOATPT OR STYPESP <> FLOATPT THEN
CALL ERROR('MF');
ELSE
DO;
CALL GENERATE(RON);
CALL GENERATE(XCH);
CALL GENERATE(RON);
CALL GENERATE(POT);
END;
/* 148 <RETURN STATEMENT> ::= RETURN */
CALL GENERATE(RTN);
/* 149 <STOP STATEMENT> ::= STOP */
CALL GENERATE(XIT);
/* 150 <END STATEMENT> ::= END */
IF PASS1 THEN
DO;
PASS1 = FALSE;
CALL REWIND$SOURCE$FILE;
IF FORCOUNT <> 0 THEN
DO;
CALL ERROR('FU');
FORCOUNT = 0;
END;
CALL GENERATE('*');
CALL GENTWO((CODESIZE + 3) AND 0FFFCH);
CALL GENTWO(DATACT);
CALL GENTWO(COUNTPRT);
END;
ELSE
DO;
DO WHILE NEXTCHAR <> EOLCHAR;
NEXTCHAR = GETCHAR;
END;
CALL GENERATE(XIT);
CALL GENERATE(7FH);
CALL WRITE$INT$FILE;
CALL CLOSE$INT$FILE;
CALL PRINTDEC(ERRORCOUNT);
CALL PRINT(.(' ERRORS DETECTED$'));
CALL CRLF;
CALL MON3;
END;
/* 151 <RESTORE STATEMENT> ::= RESTORE */
CALL GENERATE(RST);
/* 152 <RANDOMIZE STATEMENT> ::= RANDOMIZE */
CALL GENERATE(IRN);
END /* OF CASES */;
END SYNTHESIZE;
END;