Trailing-Edge
-
PDP-10 Archives
-
BB-D480C-SB_1981
-
sta3.bli
There are 12 other files named sta3.bli in the archive. Click here to see a list.
!THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
! OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
!COPYRIGHT (C) 1972,1981 BY DIGITAL EQUIPMENT CORPORATION
!AUTHOR: F.J. INFANTE, D. B. TOLMAN/MD/DCE/EGM
MODULE STA3(RESERVE(0,1,2,3),SREG=#17,FREG=#16,VREG=#15,DREGS=4)=
BEGIN
SWITCHES NOLIST;
REQUIRE LEXNAM.BLI;
REQUIRE FIRST.BLI;
REQUIRE TABLES.BLI;
REQUIRE META72.BLI;
REQUIRE ASHELP.BLI;
SWITCHES LIST;
GLOBAL BIND STA3V = 6^24 + 0^18 + 63; ! Version Date: 17-Jul-81
%(
***** Begin Revision History *****
43 ----- ----- IN "EQUISTA", WITHIN THE LOCAL ROUTINE
"GEQITEM", BEFORE CALLING "BLDVAR" FOR AN
ARRAY REF IN AN EQUIVALENCE STMNT, TEMPORARILY TURN OFF THE "BOUNDS"
FLAG, SO WONT TRY TO DO SS CHECKING
46 ----- ----- HAVE STATEMENT FUNCTIONS RESTORE THE SYMBOL
TABLE WHICH WAS MESSED UP TO CREATE THE TEMPROARY
DUMMIES
47 ----- ----- MAKE THE SFNEXPR FIELD OF THE STATEMENT
FUNCTION NODE POINT TO AN ASSIGNMENT OF THE
FUNCTION NAME TO THE EXPRESSION RATHER THAN JUST
POINTING TO THE EXPRESSION
48 ----- ----- FIX EXTESTA SO IT DOESN'T SAVSPAC THE SAME THING TWICE
49 ----- ----- FENTRYNAME IS NO LONGER SET ON STATEMENT FUNCTION
NAMES
50 ----- ----- EQUIVALENCE - PUT THE VARIABLE WHICH IS IN
COMMON AT THE TOP OF THE LIST SO THAT IF THE
CALCULATION OF ITS DISPLACEMENT IS DELAYED UNTIL
OUTMOD, ITS DISPLACEMENT WILL BE CALCULATED BEFORE
THE OTHER VARIABLES WHICH REFERENCE ITS DISPLACEMENT
ARE SHOVED INTO COMMON. WHAT FUN
51 ----- ----- CHECK BOTH NEGATIVE AND POSITIVE LIMITS OF
EQUIVALENCE SUBSCRIPTS
52 ----- ----- FIX DUMYIDMOD SO THAT IT DOES NOT CHANGE THE
TYPE OF FUNCTION NAMES EXPLICITLY TYPED IN
THE FUNCTION STATEMENT
HAVE THE IMPLICIT STATEMENT SET VALTYPE FOR
SUBROUTINE AND PROGRAM NAMES ALSO
JUST IN CASE THE ARE USED FOR SOMETHING ELSE
LATER
53 ----- ----- DOLOOP - WHEN ALREADY DEFINED TERMINAL IS DETECTED
PROCESS THE STATEMENT ANYWAY SO THE UNDEFINED
DO TERMINAL LISTING WON'T GET MESSED UP
54 ----- ----- FIX UP ACTIVE DO INDEX CHECKING SO THAT IT CHECKS
ALL ACTIVE INDICES NOT JUST THE LAST
NAMSET WILL NOW MAKE A CHECK FOR INDEX MODIFICATION
55 ----- ----- IN LOGICALIF - RESTORE LABLOFSTATEMENT AND
STMNDESC ON ANY ERROR RETURNS SO THAT IF THIS
STATEMENT TERMINATES A DO LOOP THE DOCHECK
CALL AFTER SEMANTICS WILL HAVE THE RIGHT INFO
***** Begin Version 4A *****
56 235 ----- IN NAMESTA , DEFINE ITEM AS NAMELIST ITEM, (DT/MD)
57 255 15432 IN DOLOOP, CHECK IF CURRENT STATEMENT # IS SAME AS
ENDING STATEMENT #., (JNT)
***** Begin Version 4B *****
57 324 16750 IF PROCESSING OF STATEMENT FUNCTION FAILS,
SYMBOL TABLE NEEDED FIXING UP BEFORE CONTINUING.
58 417 QAR WITH 57 IN, A(1)=1 WILL DIE IF NOT DIMENSIONED
MUST CHECK FOR CONSTANTS AS PARAMS ON LEFT, (DCE)
59 420 QAR AFTER BOGUS STATEMENT FN SEEN, REMOVE
THE INFO THAT IT WAS A ST FN. THIS PREVENTS
LATER STATEMENTS FROM RELYING ON THIS INFO., (DCE)
***** Begin Version 5A *****
60 534 QAR/21817 VARIOUS PROBLEMS WITH EDIT 59, ESPECIALLY
WITH QUOTED STRINGS IN VARIABLE LIST (BAD
FORMAT STATEMENT, ETC.), (DCE)
61 570 22703 FN(2,3) CAUSES ILL MEM REF UNDER SOME CIRCUMSTANCES,
(DCE)
***** Begin Version 5B *****
62 727 13247 TWO-WAY LOGICAL IF STMNT NEEDS TO KEEP LABEL
COUNT CORRECT FOR SECOND LABEL, (DCE)
***** Begin version 6 *****
63 771 EGM 29-May-80 14108
Make STK validity checks implemented by edit 534 more reliable.
***** End Revision History *****
)%
!THE NUMBER IN COMMENT'S IS THE STATEMENTS LOCATION
!IN THE HASH TABLE .
FORWARD
% 30% IMPLSTA, !IMPLICIT
% 65% EQUISTA, !EQUIVALENCE
% 71% NAMESTA, !NAMELIST
% 79% UNLOSTA, !UNLOAD
% 88% SKIPSTA, !SKIPRECORD OR SKIPFILE
% 91% EXTESTA, !EXTERNAL
DOLOOP, !DO LOOP
LOGICALIF, !"LOGICAL" IF
ARITHIF, !"ARITHMETIC" IF
STATEFUNC; !STATEMENT FUNCTION
ROUTINE GEQITEM(PTR)= !GENERATE AN EQUIVALENCE ITEM ENTRY
BEGIN
EXTERNAL BLDVAR,SETUSE,NAMSET;
MACRO ERR52 = ( FATLEX(E52<0,0>))$,
ERR53 = ( FATLEX(E53<0,0>))$;
LOCAL BASE T1;
REGISTER BASE T2:R1:R2;
LOCAL BASE EPTR ; MAP BASE PTR ;
NAME _ EQLTAB; EPTR _ NEWENTRY(); !MAKE AN EQUIV ITEM NODE
EPTR[EQLID] _ R1 _ .PTR[ELMNT]; !PTR TO SYMBOL IN EQUIVALENCE
R1[IDATTRIBUT(INEQV)] _ 1;
IF .R1[IDATTRIBUT(DUMMY)] THEN ERR52; !IF DUMMY SYMBOL THEN ERROR
IF .PTR[ELMNT1] NEQ 0
THEN !ITEM IS SUBSCRIPTED
BEGIN
IF .R1[IDDIM] NEQ 0 AND .R1[IDATTRIBUT(INTYPE)] NEQ 0
%DELAY PROCESSING IF NOT DIMENSIONED OR TYPED %
THEN !ITEM ALSO DIMENSIONED
IF (T2 _ .PTR[ELMNT2]; .T2[ELMNT]<LEFT>) EQL 0
THEN
BEGIN !A SINGLE SUBSCRIPT
NAMSET ( ARRAYNM1, .R1 ); !DEFINE NAME
T1 _ @.T2[ELMNT]; !PTR TO SUBSCRIPT
SAVSPACE(0,.T2); SAVSPACE(.PTR<LEFT>,.PTR);
IF .T1[OPR1] NEQ CONSTFL OR .T1[VALTYPE] NEQ INTEGER
THEN RETURN ERR53;
!NOW GEN THE OFFSET
EPTR[EQLDISPL] _ - .T1[CONST2] !THE SUBSCRIPT VALUE
+( T2 _ .R1[IDDIM]; T2 _ .T2[DIMENL(0)]; .T2[CONST2]);
IF .EPTR[EQLDISPL] LEQ -(2^18) OR .EPTR[EQLDISPL] GEQ (2^18)
THEN RETURN FATLEX(E103<0,0>);
IF .R1[DBLFLG] THEN EPTR[EQLDISPL] _ .EPTR[EQLDISPL] * 2;
EPTR[EQLLIST] _ 0;
END
ELSE
BEGIN
LOCAL SAVEBOUNDSFLG; !TO SAVE THE VAL OF THE "BOUNDS" SWITCH
SAVEBOUNDSFLG_.FLGREG<BOUNDS>; !SAVE THE VAL OF THE BOUNDS SWITCH
FLGREG<BOUNDS>_0; !TURN OFF THE BOUNDS-CHECK FLAG
! WHILE EXPANDING THE ADDR CALC FOR AN ARRAY
! REFERENCE UNDER AN EQUIVALENCE STMNT
SETUSE _ SETT; !BLDVAR FLAG
T1 _ BLDVAR(.PTR); !RETURNS PTR TO ARRAY REF EXPRESSION NODE
FLGREG<BOUNDS>_.SAVEBOUNDSFLG; !RESTORE THE BOUNDS SWITCH
IF .T1 LSS 0 THEN RETURN .VREG; !BLDVAR ERROR
!MUST DELETE THIS NODE AFTER USE
!T1[ARG2PTR] MUST BE ZERO OTHERWISE
!ERROR DUE TO NON-CONSTANT SUBSCRIPT
IF .T1[ARG2PTR] NEQ 0 THEN ERR53;
EPTR[EQLDISPL] _-(EXTSIGN(.T1[TARGET])); !HALF WORD VALUE MUST BE EXTENDED
EPTR[EQLLIST] _ 0; !SO THAT WE KNOW DISPL IS COMPUTED
END
ELSE !SET EQLLIST PTR TO POINT TO LIST OF SUBSCRIPTS
!FOR USE IN LATER CALCULATION WHEN DIMENSIONS ARE KNOWN
BEGIN
R2 _ .PTR[ELMNT2]; T1 _ .R2[ELMNT]; SAVSPACE(0,.R2);
NAMSET(VARYREF,.R1);
EPTR[EQLINDIC]_ 1; !FLAG FOR NOT YET DIMENSIONED OR TYPED
EPTR[EQLLIST] _ .T1; !PTR TO SUBSCRIPT LIST
END;
END !OF ITEM IS SUBSCRIPTED
ELSE !ITEM NOT SUBSCRIPTED
BEGIN
IF NAMSET(VARYREF,.R1) LSS 0 THEN RETURN .VREG; !NAME CONFLICT
EPTR[EQLDISPL] _ 0;
END;
RETURN .EPTR
END; !OF ROUTINE GEQITEM
GLOBAL ROUTINE EQUISTA=
BEGIN
LOCAL BASE T1;
REGISTER BASE R1 :R2;
EXTERNAL EQVPTR,CORMAN,NAME,NEWENTRY,BLDVAR,STK,SAVSPACE;
MACRO ERR52 = ( FATLEX(E52<0,0>))$,
ERR53 = ( FATLEX(E53<0,0>))$;
!MACRO GENERATES AN EQUIVALENCE GROUP ENTRY
!ENTRIES ARE LINKED BY NEWENTRY()
!
MACRO GEQGROUP(EPTR)=
BEGIN
NAME _ EQVTAB; ENTRY _ R1 _ EPTR;
R2 _ NEWENTRY();
R1 _ EPTR[EQLID];
IF .R1[IDATTRIBUT(INCOM)] THEN (R2[EQVINCOM]_1;
R2[EQVHEAD] _ EPTR;
);
R2[EQVISN] _ .ISN; !LINE NUMBER FOR POSSIBLE ERROR MESSAGES
.R2
END$;
!
LOCAL BASE GRUPHD;
LOCAL BASE ELISTPTR :EGROUP; !PTR TO LAST EQUIV ITEM ENTRY
!SEMANTIC ANALYSIS BEGINS
T1 _ @.STK[0]; !LIST PTR TO LIST OF EQV GROUPS
INCR GROUP FROM .T1 TO .T1+.T1<LEFT> DO
BEGIN MAP BASE GROUP;
!EACH EQUIV GROUP IS COMPOSED OF 2 PARTS:
!1. APTR TO THE FIRST EQUIV ITEM AND A LIST PTR TO A LIST
! OF EQUIV ITEM PTRS
!EACH EQUIV ITEM IS A PTR TO A 3 OR 4 PART LIST
! .IDENTIFIER
! .OPTION (0 OR 1)
! .PTR TO SUBSCRIPT EXPRESSION LISTS PTR (IF OPTION 1)
!
GRUPHD _ .GROUP[ELMNT];
IF (ELISTPTR _ GEQITEM(.GRUPHD[ELMNT])) LSS 0 THEN RETURN -1; !GENERATE AN EQUIVALENCE ITEM NODE
EGROUP _ GEQGROUP(.ELISTPTR); !MACRO GENERATES AN EQUIVALENCE GROUP ENTRY
R1 _ .GRUPHD[ELMNT1]; !PTR TO LIST EQUIVALENCED TO "GRUPHD"
INCR LST FROM .R1 TO .R1+.R1<LEFT> DO
BEGIN !PROCESS LIST OF ITEMS EQUIVALENCE TO GROUP HEAD
MAP BASE LST;
ELISTPTR _ .EGROUP[EQVLAST]; !PTR TO LAST ITEM IN GROUP
IF (R2 _ GEQITEM(.LST[ELMNT])) LSS 0 THEN RETURN -1;
R1 _ .R2[EQLID]; !PTR TO SYMBOL NODE
IF .R1[IDATTRIBUT(INCOM)]
THEN IF .EGROUP[EQVINCOM] THEN FATLEX(E48<0,0>) !TWO ITEMS IN COMMON
ELSE (EGROUP[EQVINCOM] _ 1;
% MOVE THE ONE IN COMMON TO THE HEAD OF THE LIST
SO THAT THE CALCULATION OF ITS DISPLACEMENT WILL
BE ASSURED WHEN THINGS ARE MOVED INTO COMMON %
R2[EQLLINK] _ .EGROUP[EQVFIRST];
EGROUP[EQVFIRST] _ EGROUP[EQVHEAD] _ .R2
)
ELSE
BEGIN
% LINK IT TO THE END OF THE LIST%
ELISTPTR[EQLLINK] _ EGROUP[EQVLAST] _ .R2
END;
END; !END OF INCR LST...
END; !END OF INCR GROUP
[email protected][0];
SAVSPACE(.T1<LEFT>,.T1); SAVSPACE(0,.STK[0]);
.VREG
END;
GLOBAL ROUTINE EXTESTA=
BEGIN
EXTERNAL TYPE,STK,SAVSPACE %(SIZE,LOC)%,BLDARRAY %(ONEARRAY LIST)%,NAMDEF;
REGISTER BASE T1:T2;
!SEMANTIC ANALYSIS BEGINS
%PROCESS LIST OF EXTERNALS %
INCR EXLST FROM .(@STK[0])<RIGHT> TO ( .(@STK[0])<RIGHT>+.(@STK[0])<LEFT> ) DO
BEGIN
MAP BASE EXLST;
T1 _ .EXLST[ELMNT]; !POINTER TO OPTION - ID BLOCK
IF .T1[ELMNT] EQL 0
THEN
BEGIN %NO PRECEEDING CHARACTER SO NOT LIBRARY FUNCTION %
T2 _ .T1[ELMNT1];
IF NAMDEF(EXTDEF,.T2) LSS 0 THEN RETURN .VREG;
T2[IDATTRIBUT(INEXTERN)] _ 1;
END
ELSE
BEGIN %LIBRARY FUNCTION%
IF .T1[ELMNT] EQL 2
THEN %ASTERISK% T2 _ .T1[ELMNT2] !SKIP *
ELSE %ANDSIGN% T2 _ .T1[ELMNT1];
%ANY CONFLICTS%
IF NAMDEF( EXTDEFS, .T2 ) LSS 0 THEN RETURN .VREG;
%OK%
T2[IDATTRIBUT(INEXTSGN)] _ 1;
END;
T2[OPERSP] _ IF .T2[IDATTRIBUT(DUMMY)] THEN FORMLFN ELSE FNNAME;
SAVSPACE(.T1<LEFT>,@T1<RIGHT>)
END;
SAVSPACE( .(@STK[0])<LEFT>, .(@STK[0])<RIGHT> );
SAVSPACE( 0, .STK[0]<RIGHT> )
END;
GLOBAL ROUTINE DUMYIDMOD=
BEGIN
!FIXES UP THE VALTYPE OF DUMMY VARIABLES AFTER AN IMPLICIT
!STATEMENT WAS PROCESSED
EXTERNAL SORCPTR,TYPTAB;
REGISTER BASE R1:R2:T2; LOCAL BASE T1;
!
!DO THE FUNCTION NAME IF PRESENT
!
R1 _ .SORCPTR<RIGHT>;
R2 _ .R1[ENTSYM];
IF NOT .R2[IDATTRIBUT(INTYPE)]
THEN
BEGIN
T2 _ .R2[IDSYMBOL]<30,6>; !FIRST CHARACTER
R2[VALTYPE] _ .TYPTAB[.T2-SIXBIT"A"]<RIGHT>
END;
!NOW REST OF DUMMYS
!
IF (T1 _ .R1[ENTLIST]) NEQ 0 !T1 POINTS TO ARGLIST
THEN
DECR I FROM .(.T1+1)<RIGHT>-1 TO 0 DO
BEGIN
R2 _ .(.T1+2)[.I]<RIGHT>; !PTR TO ARG
T2 _ .R2[IDSYMBOL]<30,6>;
R2[VALTYPE] _ .TYPTAB[.T2-SIXBIT"A"]<RIGHT>;
END
END; !OF DUMTIDMOD
GLOBAL ROUTINE IMPLSTA=
BEGIN
EXTERNAL DUMYIDMOD,SORCPTR;
REGISTER BASE R1;
!SEMANTIC ANALYSIS BEGINS
IF (R1 _ .SORCPTR<RIGHT>) NEQ 0
THEN ( IF .R1[SRCID] EQL ENTRID
THEN DUMYIDMOD(); )
ELSE ( %SET TYPE OF PROGRAM OR BLOCK DATA NAMES JUST INCASE %
EXTERNAL PROGNAME,TBLSEARCH,NAME,ENTRY,TYPTAB;
REGISTER BASE T2;
IF .PROGNAME NEQ SIXBIT'MAIN.' AND
.PROGNAME NEQ SIXBIT'.BLOCK'
THEN
BEGIN
ENTRY _ .PROGNAME;
NAME _ IDTAB;
R1 _ TBLSEARCH();
T2 _ .R1[IDSYMBOL]<30,6>; !FIRST CHARACTER
R1[VALTYPE] _ .TYPTAB[.T2-SIXBIT"A"]<RIGHT>
END
);
.VREG
END;
!GLOBAL ROUTINE GLOBSTA=
!BEGIN
!!
!! ROUTINE COMMENTED IN 1(41)-116
!!
!! EXTERNAL STK,BLDARRAY %(ONEARRAY LIST)%,SAVSPACE %(SIZE,LOC)%,TYPE;
!! MAP BASE T1;MACRO ELMNT=0,0,FULL$;
! BIND GLOBPLIT= PLIT'GLOBAL';
!%1(41)-117% ENTRY[1]_GLOBPLIT;
!%1(41)-117% ERROUT(73);!STATEMENT NOT YET SUPPORTED
!!
!! COMMENT REST OF ROUTINE IN EDIT 1(41)-114
!!
!! IF SCAN(PLIT'AL') LSS 0 THEN (ENTRY[1]_GLOBPLIT;ERROUT(E12));
!! IF SYNTAX(GLOBALSPEC) LSS 0 THEN RETURN -1;
!!SEMANTIC ANALYSIS BEGINS
!! IDTYPE_-1;TYPE_1;T1_.STK[0];
!! BLDARRAY(.T1[ELMNT]);SAVSPACE(0,@STK[0]);
!! .VREG
!%1(41)-117% RETURN -1
!END;
GLOBAL ROUTINE NAMESTA=
BEGIN
%
ROUTINE EXPECTS STK[0] TO CONTAIN A POINTER TO ALIST POINTER
OF THE FORM (COUNT,,PTR). THE LIST PTR POINTS TO A LIST OF
COUNT+1 POINTERS THAT EACH POINT TO A 4 WORD BLOCK OF THE FORM:
0. /
1. NAMELIST NAME PTR
2. /
3. LIST POINTER (COUNT,,LISTPTR)
WHERE THE LIST POINTER IN 3. POINTS TO ALIST OF IDENTIFIER PTRS
THAT ARE THE ITEMS IN THE NAMELIST
%
MACRO ERR58(X)=FATLEX(X,E58<0,0>)$;
EXTERNAL SAVSPACE,NAME,NEWENTRY,STK,CORMAN,ENTRY;
EXTERNAL NAMDEF,NAMREF;
REGISTER BASE R1:R2;
LOCAL BASE T1:T2;
!SEMANTIC ANALYSIS BEGINS
T1 _ @.STK[0]; !GET PTR TO NAMELIST BLOCK
INCR NLST FROM .T1 TO .T1+.T1<LEFT> DO
BEGIN
MAP BASE NLST;
T1 _ .NLST[ELMNT]; !PTR TO BLOCKLIST NAME
R1 _ .T1[ELMNT1]; !PTR TO NAMELIST NAME
IF NAMDEF(NMLSTDEF, .R1) LSS 0 THEN RETURN .VREG;
R1[IDATTRIBUT(NAMNAM)] _ 1;
R2 _ .T1[ELMNT3]; !PTR TO LIST OF NAMELST ANME PTRS
SAVSPACE(.T1<LEFT>,.T1);
INCR ILST FROM .R2 TO .R2+.R2<LEFT> DO
BEGIN
MAP BASE ILST;
T2 _ .ILST[ELMNT]; !GET PTR TO NAMELIST ITEM
!CHECK FOR ILLEGAL NAMES
IF NAMDEF(NMLSTITM,.T2) GTR 0 !CHECK FOR NAMELIST ITEM
THEN ILST[ELMNT]<LEFT> _ 0;
END; !END OF INCR ILST
NAME _ NAMTAB; T2 _ NEWENTRY();
T2[NAMLIST] _ .R2<RIGHT>;
T2[NAMCNT] _ .R2<LEFT>+1;
T2[NAMLID] _ .R1; !NAMLIST NAME
R1[IDCOLINK]_.T2; !SET POINTER IN NAMELIST NAME ENTRY
END; !OF INCR NLST
T1 _ @.STK[0]; SAVSPACE(.T1<LEFT>,.T1); SAVSPACE(0,.STK[0]);
.VREG
END;
GLOBAL ROUTINE SKIPSTA=
BEGIN
EXTERNAL BLDUTILITY;
REGISTER R;
BIND DUM = PLIT( REC NAMES 'RECORD?0', FIL NAMES 'FILE?0' );
R _ SKIPDATA;
LOOK4CHAR _ REC<36,7>;
DECR I FROM 1 TO 0
DO
BEGIN
IF LEXICAL(.GSTSSCAN) NEQ 0
THEN
BEGIN % GOT ONE %
IF SYNTAX(UTILSPEC) LSS 0 THEN RETURN .VREG;
RETURN BLDUTILITY(.R)
END;
R _ SKIPFDATA; ! TRY FILE
LOOK4CHAR _ FIL<36,7>
END;
RETURN FATLEX(E12<0,0>); !MISSPELLED
END;
GLOBAL ROUTINE UNLOSTA=
BEGIN
EXTERNAL BLDUTILITY;
!SEMANTIC ANALYSIS BEGINS
BLDUTILITY(UNLODATA);
.VREG
END;
GLOBAL ROUTINE DOLOOP =
BEGIN
REGISTER BASE T1:T2;REGISTER BASE R1:R2;
EXTERNAL STK,SP,NEWENTRY %()%,SAVSPACE %(SIZE,LOC)%,ONEPLIT,TBLSEARCH %()%,CORMAN %()%;
EXTERNAL DONESTLEVEL, !CURRENT LEVEL OF DO NESTING
LASDOLABEL, !LABEL PTR TO LAST LABEL SEEN IN DO STATEMENT
STALABL, !CURRENT STATEMENT LABEL
ISN, !CURRENT ISN
DOXPN, !MAKES DO INITIALIZATION TREE
CURDOINDEX, !PTR TO CURRENT DO INDEX VARIABLE
ADDLOOP; !MAKES DO TREE STRUCTURE FOR OPTIMIZER
EXTERNAL NAMSET,CKDOINDEX;
LOCAL BEFOREDO; !HOLDS DO PREDECESSOR
MACRO ADDOLAB(X,Y)= NAME<LEFT> _ 2; !LINK IN NEW LABEL
T2 _ CORMAN();
T2[ELMNT] _ .LASDOLABEL; !SAVE LAST
T2[ELMNT1] _ .CURDOINDEX; !SAVE INDEX
LASDOLABEL<LEFT> _ .T2;
LASDOLABEL<RIGHT> _ X;
CURDOINDEX _ Y; !INDEX POINTER
$;
!
MACRO
LBL=0,0,RIGHT$,INDX=0,1,FULL$,INITIAL=0,2,FULL$,FINAL=0,3,FULL$,
INCROPT=0,4,FULL$,INCREMENT=0,5,FULL$;
!------------------------------------------------------------------------------------------------------------------
! THE SYNTAX ROUTINE RETURNS A POINTER IN STK[0] WHICH POINTS TO THE LIST:
!
! LABEL(21^18+LOC) - LABEL OF DO TERMINAL STATEMENT
! IDENTIFIER(20^18+LOC) - DO INDEX
! EXPRESSION(1^18+LOC) - POINTER TO POINTER TO INITIAL VALUE OF DO INDEX
! EXPRESSION(1^18+LOC) - POINTER TO POINTER TO FINAL VALUE OF DO INDEX
! OPTION 0 - INCREMENT OF DO INDEX IS ONE
! OPTION 1 - INCREMENT OF DO INDEX IS EXPRESSION FOLLOWING
! LIST(1^18+LOC) - POINTER TO POINTER TO POINTER TO INCREMENT OF DO INDEX
!------------------------------------------------------------------------------------------------------------------
T1_.STK[0]; !T1_LOC(LIST)
R1_.T1[LBL];R2_.T1[INDX];
IF (T2_.R1[SNHDR]) NEQ 0 THEN !ERROR DO TERMINAL ALREADY SEEN
FATLEX(.T2[SRCISN],.R1[SNUMBER],E20<0,0>); !DON'T RETURN
IF .R1[SNUMBER] EQL .STALABL THEN !IF IT'S THE NUMBER ON THIS STATEMENT
FATLEX(.ISN,.R1[SNUMBER],E20<0,0>); !FATAL ERROR
IF CKDOINDEX(.R2<RIGHT>)
THEN RETURN FATLEX( R2[IDSYMBOL], E21<0,0>); !DO INDEX ALREADY ACTIVE
IF NAMSET(VARIABL1, .R2) LSS 0 THEN RETURN .VREG;
ADDOLAB(.R1,.R2); !LINK IN NEW LOOP LABEL TO PREVIOUS ONES
BEFOREDO _ .SORCPTR<RIGHT>; !PTR TO STATEMENT NODE PRECEDING DO
NAME_IDOFSTATEMENT_DODATA;NAME<RIGHT>_SORTAB;
T2_NEWENTRY();
T2[DOPRED] _ IF .BEFOREDO EQL 0 THEN .SORCPTR<LEFT> ELSE .BEFOREDO; !LINK IN PREVIOUS STATEMENT NODE
DONESTLEVEL _ .DONESTLEVEL+1;
T2[DOSYM]_.R2;T2[DOLBL]_.R1;
R2_.R1[SNDOLNK];R1[SNDOLVL]_.R1[SNDOLVL]+1;NAME<LEFT>_1;R1[SNDOLNK]_CORMAN();
(@VREG)<LEFT>_@T2;(@VREG)<RIGHT>_@R2;
R1_.T1[INITIAL];R2_.T1[FINAL];T2[DOM1]_.R1%[ELMNT]%;T2[DOM2]_.R2%[ELMNT]%;
! SAVSPACE(.R1<LEFT>,@R1);SAVSPACE(.R2<LEFT>,@R2);
IF .T1[INCROPT] NEQ 0 THEN
BEGIN
R1_.T1[INCREMENT];T2[DOM3]_.R1[ELMNT];
SAVSPACE(.R1<LEFT>,.R1);
END ELSE T2[DOM3]_.ONEPLIT;
SAVSPACE(.T1<LEFT>,.T1);
ADDLOOP(.DONESTLEVEL); !FOR OPTIMIZER
DOXPN(.T2<RIGHT>); !CREATE THE NODE FOR THE DO INITIALIZATION CODE
.VREG
END;
GLOBAL ROUTINE LOGICALIF=
BEGIN
LOCAL BASE IFEXPR,LASTTRUESRC,SAVLABEL,SAVDESC;
REGISTER BASE T1:T2;
EXTERNAL SAVSPACE, %SAVSPACE(SIZE,PNTR)%
LABLOFSTATEMENT, %LABEL ON IF STATEMENT%
STALABL, % ALSO CONTAINS THE LABEL %
GSTIFCLASIF, %CLASSIFIER()%
ENDOFILE, ! RETURN FROM LEXICAL
STMNDESC, ! STATEMENT DESCRIPTION BLOCK
STK,SP,LOOK4LABEL,
NEWENTRY; %NEWENTRY()%
IFEXPR _ .STK[0]; !SAVING PTR TO EXPR PTR
!SEMANTIC ANALYSIS BEGINS
SAVDESC _ @STMNDESC; ! SAVE THE STATMENT DESCRIPTION POINTER
IF LEXICAL( .GSTIFCLASIF ) EQL ENDOFILE<0,0> THEN ( STMNDESC _ .SAVDESC; RETURN -1); ! UNRECOGNIZED STATEMENT
IF .BADIFOBJ ( @STMNDESC ) THEN ( STMNDESC_.SAVDESC; RETURN FATLEX(E23<0,0>)); ! ILLEGAL LOGICAL IF OBJECT
!
!STK[0] CONTAINS A PTR TO PTR TO PTR TO EXPRESSION NODE
!
STK[0] _ .IFEXPR; !RESTORING THE PTR
T2_.STK[0];IFEXPR_.T2[ELMNT];SAVSPACE(.T2<LEFT>,.T2);LASTTRUESRC_.LASTSRC;
LOOK4LABEL _ 0; !CLEAR LABEL FLAG
SP_-1; !RESET STK PTR FOR PARSE
SAVLABEL _ .LABLOFSTATEMENT; LABLOFSTATEMENT _ STALABL _ 0;
%EXECUTE THE SYNTAX IF NECESSARY %
IF( T1 _ .SYNOW(@STMNDESC)) NEQ 0
THEN IF SYNTAX(.T1) LSS 0
THEN (STMNDESC_.SAVDESC;LABLOFSTATEMENT_.SAVLABEL; RETURN -1);
IF (.STMNROUTINE(@STMNDESC))() LSS 0
THEN (LABLOFSTATEMENT_.SAVLABEL;STMNDESC_.SAVDESC; RETURN -1); !STATEMENT HAD AN ERROR
!------------------------------------------------------------------------------------------------------------------
! REMOVE THE FALSE SOURCE NODE FROM THE LINKED LIST OF SOURCE STATEMENTS
!------------------------------------------------------------------------------------------------------------------
STMNDESC _ .SAVDESC; ! RESTORE THE STATEMENT DESCRIPTION POINTER
T1_.LASTSRC; IF .LASTTRUESRC EQL 0 THEN LASTSRC _ .SORCPTR<LEFT> ELSE LASTSRC_.LASTTRUESRC;
IF .T1[SRCID] EQL SFNID %STATEMENT FUNCTION% THEN FATLEX(E23<0,0>);
LABLOFSTATEMENT _ .SAVLABEL;
NAME_IDOFSTATEMENT_IFLDATA; NAME<RIGHT> _ SORTAB;T2_NEWENTRY();
T2[LIFEXPR]_.IFEXPR;T2[LIFSTATE]_.T1;
IF .IFEXPR[OPRCLS]NEQ DATAOPR
THEN IFEXPR[PARENT] _ .T2; !EXPR NODE POINTS TO SRC NODE
T1[SRCLBL] _ 0; ! REMOVING ANY LABEL THE STATEMENT HAD FROM THE STATEMENT PART
END;
GLOBAL ROUTINE ARITHIF=
BEGIN
EXTERNAL STK,WARNOUT,SP,NEWENTRY %()%,SAVSPACE %(SIZE,LOC)%,TBLSEARCH %()%;
REGISTER BASE T1:T2;REGISTER BASE R1:R2;
MACRO IFEXPR=0,0,FULL$,LTLABEL=0,1,FULL$,EQLABEL=0,2,FULL$,
GTOPT=0,3,FULL$,GTLABEL=0,4,FULL$;
!SEMANTIC ANALYSIS BEGINS
T1_.STK[0]; !T1_LOC(LIST)
R1_.T1[LTLABEL];R2_.T1[EQLABEL];
IF .T1[GTOPT] NEQ 0 THEN
BEGIN
T2_.T1[GTLABEL];T1_.T2[ELMNT];SAVSPACE(.T2<LEFT>,@T2);
![727] IF WE ARE MANUFACTURING A THIRD LABEL (ONLY TWO REAL
![727] LABELS WERE PRESENT), THEN INCREMENT THE LABEL COUNT TOO.
%[727]% END ELSE (T1_@R2; T1[SNREFNO]_.T1[SNREFNO]+1);
NAME_IDOFSTATEMENT_IFADATA;NAME<RIGHT>_SORTAB;T2_NEWENTRY();
T2[AIFLESS]_.R1<RIGHT>;
T2[AIFEQL]_.R2<RIGHT>;
T2[AIFGTR]_.T1<RIGHT>;
T1_.STK[0]; R1 _ T2[AIFEXPR]_.T1[ELMNT];
!
!CHECK TO POINT BACK TO SRC NODE
!
IF .R1[OPRCLS] NEQ DATAOPR
THEN R1[PARENT] _ .T2; !EXPR POINTS BACK TO SRC NODE
%(**CHECK FOR COMPLEX EXPRESSION - THIS IS ILLEGAL**)%
IF .R1[VALTYPE] EQL COMPLEX THEN WARNLEX(E99<0,0>);
SAVSPACE(.T1<LEFT>,@T1);
END;
ROUTINE BLDSFN= !BUILDS A STATEMENT FUNCTION SOURCE TREE NODE
BEGIN
EXTERNAL STK,NEWENTRY,CORMAN,NAME,ASTATFUN,IDOFSTATMENT,SAVSPACE,ASGNTYPER;
LOCAL BASE T1; REGISTER BASE R1:R2:T2;
!
!STK[0] CONTAINS APTR TO THE OUTPUT FROM A STATEFUNCTION PARSE
!
!BUILD THE NODE
!
NAME _ IDOFSTATEMENT _ SFNDATA; NAME<RIGHT> _ SORTAB;
R1 _ NEWENTRY();
T1 _ .STK[0];
R1[SFNNAME] _ .ASTATFUN; !PTR PUT IN ASTATFUN BY STATEFUNC ROUTINE
R1[SFNEXPR] _ R2 _ .T1[ELMNT1]; !PTR TO EXPRESSION
ASGNTYPER(.R1); !CHECK FOR TYPE CONVERSION
R2 _ .R1[SFNEXPR]; !RESTORE EXPRESSION PTR
! MAKE SFNEXPR POINT TO AN ASSIGNMENT NODE
NAME<LEFT> _ ASGNSIZ+SRCSIZ;
T2 _ CORMAN();
T2[OPRCLS] _ STATEMENT;
T2[OPERSP] _ ASGNID;
T2[LHEXP] _ .ASTATFUN;
T2[A1VALFLG] _ 1;
T2[RHEXP] _ .R2;
R1[SFNEXPR] _ .T2;
IF .R2[OPRCLS] NEQ DATAOPR THEN R2[PARENT] _ .R1; !PTR TO STATEMENT FUNCTION AS PARENT
!BUILD THE NEW ARGLIST BLOCK 2 WORDS LONGER THAN NUM OF ARGS
NAME<LEFT> _ .T1[ELMNT]<LEFT>+1+2;
T2 _ CORMAN();
R2 _ .T1[ELMNT];
T2[ELMNT1] _ .T1[ELMNT]<LEFT>+1; !NUMBER OF ARGS
T2 _ .T2+2;
DECR I FROM .T1[ELMNT]<LEFT> TO 0 DO
BEGIN
%RESTORE THE SYMBOL TABLE%
LOCAL BASE ID:TMP:SAV;
ID _ @(.R2)[.I];
SAV _ .ID[IDSYMBOL];
TMP _ .ID[CLINK];
ID[IDSYMBOL] _ .TMP[IDSYMBOL];
TMP[IDSYMBOL] _ .SAV;
(.T2)[.I] _ .TMP; !TRANSFERING ARGLIST TO NEW BLOCK
%CHECK FOR DUPLICATE DUMMIES%
SAV _ .I-1;
UNTIL .SAV LSS 0
DO
BEGIN
TMP _ @@(@R2)[.SAV]; !NEXT PARAMETER
IF .ID[IDSYMBOL] EQL .TMP[IDSYMBOL]
THEN FATLEX(.ID[IDSYMBOL],E87<0,0>);
SAV _ .SAV-1
END;
END;
R1[SFNLIST] _ T2 _ .T2-2; !PUT THE POINTER VALUE BACK TO BEGINNNING OF BLOCK
SAVSPACE(.R2<LEFT>,.R2); SAVSPACE(.STK[0]<LEFT>,.STK[0]);
RETURN .R1
END;
GLOBAL ROUTINE STATEFUNC=
BEGIN
REGISTER BASE R1:T1:T2;
EXTERNAL
NAMDEF,NAMSET,
STMNDESC,
ARRXPND, %ARRXPND(ARRAYNAME, SUBSCRIPTLIST)
SUBSCRIPTLIST= LOC(COUNT,SUBSCRIPT#1,...,SUBSCRIPT#COUNT-1)%
SAVSPACE, %SAVSPACE(SIZE,LOCATION)%
NEWENTRY, %NEWENTRY()%
MULTIASGN, %MULTIASGN()%
ASTATFUN, !FLAG PTR WHEN PARSING A STATEMENT FUNCTION
STK,SP;
EXTERNAL PSTATE,PSTEXECU,STALABL,DSCSTFN,LABDEF,DSCASGNMT;
MACRO
CNT= 0,0,LEFT$;
LOCAL LNAME;
T2_LEXEMEGEN();
IF .T2<LEFT> NEQ IDENTIFIER THEN RETURN FATLEX(.ISN,E10<0,0>); !UNRECOGNIZED STATEMENT
LNAME _ .T2; !SAVING THE ARRAY OR FUNCTION NAME PTR
IF .T2[OPRSP1] NEQ ARRAYNM1 THEN
BEGIN
%STATEMENT FUNCTION%
STMNDESC _ DSCSTFN<0,0>; ! UPDATE THE STATEMENT DESCRIPTION
% CHECK STATEMENT ORDERING %
IF .PSTATE EQL PSTEXECU<0,0>
THEN % OUT OF ORDER OR UNDEMENSIONED ARRAY %
WARNLEX(KEYWRD(@STMNDESC)<0,0>,E107<0,0>);
% CHECK LABEL%
IF .STALABL NEQ 0
THEN % NO LABELED STATEMENT FUNCTIONS %
FATLEX(KEYWRD(@STMNDESC)<0,0>,E110<0,0>);
%RECORD THEN DEFINITON%
IF NAMDEF( STFNDEF, .T2 ) LSS 0 THEN RETURN .VREG;
T2[IDATTRIBUT(SFN)]_1;T2[OPERSP]_FNNAME;
ASTATFUN _ .T2<RIGHT>; !FLAG PTR USED IN MULTIA ASGN
IF SYNTAX(STATEFUNCSPEC) LSS 0 THEN
BEGIN
ASTATFUN _ 0;
!REMOVE BOGUS STATEMENT FUNCTION DEFINITION
! TO PREVENT LATER CONFUSION, E. G.
! A(1)=1; A(1)=1 WITHOUT DIM ST GIVES UGLY ERRORS!
T1_.LNAME;
T1[OPRSP1]_VARIABL1;
T1[IDATTRIBUTE(SFN)]_0;
![771] CHECK FOR BOTH AN INVALID SYNTAX STACK POINTER AND
![771] THE ABSENCE OF THE EXPECTED LIST OF IDENTIFIERS
%[771]% IF (R1_.STK<RIGHT>) EQL 0 THEN RETURN -1;
%[771]% IF .R1[0]<LEFT> NEQ IDENTIFIER THEN RETURN -1;
![771] THE STACK APPEARS INTACT. STEP THRU THE LIST OF IDENTIFIER
![771] POINTERS AND REPLACE THE FUNCTION FORMALS WITH THE ACTUAL
![771] IDENTIFIERS
INCR I FROM 0 TO .STK<LEFT> DO
BEGIN
LOCAL BASE SAV;
T2_ @(.R1)[.I];
!BE SURE THAT WE ARE NOT INADVERTENTLY IN THE CONSTANT
! TABLE RATHER THAN THE SYMBOL TABLE, E.G. FN(3,2)
IF .T2[OPERSP] EQL CONSTANT
THEN RETURN -1;
SAV_ .T2[IDSYMBOL];
T1_ .T2[CLINK];
!MAKE SURE THAT IT IS A VARIABLE (NOT CONSTANT)
IF .T2 NEQ 0 THEN
(T2[IDSYMBOL]_.T1[IDSYMBOL];
T1[IDSYMBOL]_.SAV)
END;
RETURN -1
END;
BLDSFN(); !BUILD ASTATEFUNCTION NODE
ASTATFUN _ 0; !RESET SINCE PARSE IS FINISHED
RETURN
END;
!------------------------------------------------------------------------------------------------------------------
! AN ARRAY ASSIGNMENT WITH POSSIBLE MULTIPLE ASSIGNMENTS
!------------------------------------------------------------------------------------------------------------------
STMNDESC _ DSCASGNMT<0,0>; ! UPDATE THE STATEMENT DESCRIPTION
% SET ORDERING%
PSTATE _ PSTEXECU<0,0>;
IF .STALABL NEQ 0
THEN LABDEF(); ! ENTER THE LABEL IN THE LABEL TABLE
NAMSET(ARRAYNM1, .T2);
IF SYNTAX(ARRAYASSIGNSPEC) LSS 0 THEN RETURN -1;
T1_.STK[0];T2_.T1[ELMNT]; !T1_LIST BASE
INCR SCR FROM @T2 TO @T2+.T2<LEFT> DO
BEGIN
MAP BASE SCR;
MACRO SCRFLAGS=0,0,LEFT$,SCRCNT=0,0,LEFT$,SCRLOC=0,0,RIGHT$;
R1_.SCR[ELMNT];
SCR[SCRFLAGS]_0;SCR[SCRLOC]_.R1;!PTR TO SUBSCRIPT EXPRESSION
IF .R1[OPRCLS] EQL DATAOPR THEN SCR[P1AVALFLG]_1
ELSE
IF .R1[OPRCLS] EQL ARRAYREF THEN SCR[P1AVALFLG]_1;
END;
IF (T2_ARRXPND(@LNAME,@T2))LSS 0 THEN RETURN -1;
RETURN MULTIASGN(.T2) ! GIVE IT THE LEFT HAND SIDE
END;
END
ELUDOM