Trailing-Edge
-
PDP-10 Archives
-
bb-d868e-bm_tops20_v41_2020_dist_1of2
-
language-sources/ma0n.bli
There are 18 other files named ma0n.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,1973,1974,1977,1978 DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. 01754
!FILENAME: LOMACR.BLI
!DATE: 19 JULY 73 MGM/FLD
%3.13% GLOBAL BIND LOMAV=3; !MODULE VERSION NUMBER
! REVISION HISTORY::
!
% MCSAV---
COLLECT A STRING OF CHARACTERS INTO CHUNCKS IN CORE.
A BLOCK OF 'NOBLKS' CELLS IS ACQUIRED. IT HOLDS ALL CHARS IN
NORMAL FORMAT. THE LAST TWO CHAR POSITIONS + EXTRA BIT
GIVE THE INDEX OF THE NEXT CELL OF CHARS.
%
%3.1% GLOBAL ROUTINE MCSAV (A) =
BEGIN
LOCAL T;
REGISTER R;
MACHOP IDPB=#136;
IF .POSITC GEQ TOOBIG THEN
(POSITC_1;
T_(@BODYMC)<NEXTF> _ GETSPACE(NOBLKS);
BODYMC _ (ST[.T,0]-1)<1,7>;
);
R_.A;
IDPB(R,BODYMC);
POSITC_.POSITC+1;
END;
! ***** SECTION TWO *****
! MACRO EXPANSION
!
GLOBAL ROUTINE EXPMCR (STI) =
% CALLED ONLY FROM IDFIXER WHICH, HAVING
SEEN A MACRO NAME, WISHES TO REPLACE IT
WITH ITS EXPANSION. (LOLEXA). %
%WINDOW IN: ( XXX , XXX , XXX , <NAME> )
SETUP AN EXPANSION OF THE MACRO GIVEN AS PARAMETER.
FIRST CHECK IF THIS MACRO IS ALREADY IN USE AS SHOWN
BY <INUSEBIT> IN STENTRY. IF SO THEN TRACE BACK THE
MACRO EXPANSION CHAIN AS A DIAGNOSTIC AND DON'T EXPAND
THE MACRO. THE IDENTIFIER ITSELF IS DELETED.
OTHERWISE CALLECT ACTUAL PARAMETERS IF REQUIRED AND SAVE
AS STRINGS JUST LIKE THE BODY WITH RESPECTIVE STIS IN THE
FORMAL BLOCK OF THE MACRO. NULL PARAMETERS, AND TOO FEW
PARAMETERS ARE OKAY. EXTRA PARAMETERS ARE SCANNER FOR
BALANCE JUST LIKE THE OTHERS, THEN IGNORED.
%
BEGIN
LOCAL S,T,ST1,NFORMALS,I;
ST1_ST[.STI,1]<0,0>;
IF .(.ST1)<INUSEBIT> THEN
(WARNEM(.NFUTDEL,#175);
S_T_MCBUFF<0,0>; !GIVE TRACEBACK OF MACRO NESTING
OUTSTR("MACRO",5);OCHAR(" ");
OUTSTN(.STI);
UNTIL .S EQL 0 DO
(OUTSTR(" CALL",5);OUTSTR("ED FR",5);OUTSTR("OM ",3);
IF @.T EQL 0 THEN
(OUTSTR("SOURC",5);OCHAR("E"))
ELSE IF .(.T+1)<ACTUALF> EQL 0 THEN
OUTSTN(.(.T+1)<NAMEF>)
ELSE
(OUTSTR("PARAM",5);OUTSTR(" #",2);
OUTMOC(.(.T+1)<ACTUALF>)
)
;
T_ST[S_.(.T+1)<NEXTF>,0]<0,0>
);
OCHAR(".");
NEWLINE();
RETURN
)
ELSE (.ST1)<INUSEBIT>_1;
FBLKMC_ST[.(.ST1)<NEXTF>,0]<0,0>; !THIS IS AN ADDRESS - NOT AN INDEX!
NFORMALS_.(.FBLKMC)<LEFTF>; !NUMBER OF FORMAL PARAMETERS
IF .NFORMALS NEQ 0 THEN
%2.20% (INCR J FROM .FBLKMC<RIGHTF>+1 TO .FBLKMC<RIGHTF>+.NFORMALS DO (.J)<0,36>_0;
SKAN(#2);
IF .CHAR NEQ "(" THEN WARNEM(.NFUTSYM,#177)
ELSE ( SCANNER();
I_1;
DO(
T_GETACTUAL(S_.I LEQ .NFORMALS);
IF .S THEN (.FBLKMC+.I)<WORDF>_.T;
I_.I+1
)
UNTIL (T_.CHAR EQL ")";SCANNER();.T);
));
PUSHEXP( .FBLKMC,TOOBIG,.STI,0,.CHAR,.FBLKMC) ;
SCANNER();
END;
% GETACTUAL---
SETUP TO COLLECT A STRING.
COUNT LEFT AND RIGHT PARENS TO ENFORCE BALANCE.
%
%3.1% GLOBAL ROUTINE GETACTUAL(KEEP) =
% COLLECT UP TO THE NEXT COMMA OR RIGHT DELIMITER IN
THE CONTEXT OF MATCHED LEFT AND RIGHT BRACKETS: "()",
"[]", OR "<>". %
% FIXED (5.200.5) TO ERASE COMMENTS APPEARING IN ACTUALS%
BEGIN
LOCAL STKP,STACK[30],STACKP[30];
MACRO BALANCED=(.STKP EQL 0)$,
PUSHSTK(CODE,POS)=(STKP_.STKP+1; STACKP[.STKP]_POS;
STACK[.STKP]_CODE)$,
POPSTK=(STKP_.STKP-1)$,
TOPCODE=.STACK[.STKP]$,
TOPPOS=.STACKP[.STKP]$;
LOCAL WHICH, TRUE;
IF .KEEP THEN
(BODYMC_STEMC<0,0>; ! USED ONLY AS A TEMPORARY
POSITC_TOOBIG);
STKP_0;
TRUE_1;
WHILE .TRUE DO
(CASE (WHICH_SELECT .CHAR OF
NSET
"," : 0;
"(" : 1^18+0;
"[" : 1^18+1;
"<" : 1^18+2;
")" : 2^18+0;
"]" : 2^18+1;
">" : 2^18+2;
%3.13% "'" : 3^18+0;
%3.13% %DBL QUOTE% #42 : 3^18+0;
%5.200.5% "%" : 4^18+0;
%5.200.5% "!" : 5^18+0
TESN)^(-18)
OF
SET
! COMMA FOUND--IF BALANCED, EXIT WITH STE INDEX OF STRING
IF BALANCED THEN EXITLOOP;
! LEFT DELIMITER FOUND--STACK IT
PUSHSTK(.WHICH<RIGHTHALF>,.NCBUFF);
! RIGHT DELIMITER FOUND--IF BALANCED EXIT, OTHERWISE CHECK
! THE MATCHING LEFT AT TOP OF STACK.
(IF BALANCED THEN EXITLOOP;
IF .WHICH<RIGHTHALF> EQL TOPCODE
THEN POPSTK
ELSE (ERROR(TOPPOS,ERSYUNMTCH); ERROR(.NCBUFF,ERSYUNMTCH); EXITLOOP));
%3.13% ! SOME FORM OF QUOTE SEEN -- COPY UNTIL CLOSING QUOTE SEEN
%3.13% (WHICH_.CHAR;
%3.13% DO (IF .KEEP THEN MCSAV(.CHAR)) UNTIL (SCANNER(); .CHAR EQL .WHICH));
%5.200.5% ! ERASE COMMENT BEGINNING WITH "%"
(IF .KEEP THEN MCSAV(.CHAR);
DO 0 UNTIL ( SCANNER(); .CHAR EQL "%"));
%5.200.5% ! ERASE COMMENT BEGINNING WITH "!"
DO 0 UNTIL ( SCANNER(); .CHAR EQL EOL);
TES;
IF .KEEP THEN MCSAV(.CHAR);
SCANNER()); % END OF DO %
IF .KEEP THEN MCSAV(TERMINATOR);
.STEMC
END;
% PUSHEXP---
PUSH A NEW MACRO ON THE EXPANSION STACK.
PARAMETERS ARE:
PTR - STINDEX FOR NEW CHAR STRING FOR EXPANSION
(MAY BE BODY OR ACTUAL)
COUNT - INITIAL COUNT IN ABOVE STRING (NOW ALWAYS "TOOBIG")
NAME - STINDEX OF THE NAME OF THIS MACRO
NPAR - ACTUAL PARAMETER NUMBER (0 IMPLIES THE BODY ITSELF)
CCHAR - NEXT CHAR VALUE FROM CURRENT EXPANSION TO BE SAVED
FBLK - ADDRESS OF THE FORMAL BLOCK OF THIS MACRO EXPANSION
%
%3.1% GLOBAL ROUTINE PUSHEXP(PTR,COUNT,NAME,NPAR,CCHAR,FBLK) =
BEGIN
REGISTER T,S;
IF .EMFLG THEN
(FORCELINE(0);
NEWLINE();
IF .NPAR EQL 0 THEN
(OUTSTR("CALL ",5);OUTSTN(.NAME);OCHAR(":"))
ELSE
(OUTSTR("ACTUA",5);OUTSTR("L #",3);OUTMOC(.NPAR);OCHAR(":")
);
);
T_ST[S_GETSPACE(2),0]<0,0>;
(.T)<0,36>_.MCBUFF;
(@T+1)<WORDF>_.(MCBUFF+1);
(@T+2)<POSITF>_.POSIT;
(@T+2)<CHARF>_.CCHAR;
(@T+3)<WORDF>_.(MCBUFF+2);
MCBUFF_.PTR;
(MCBUFF+1)<NEXTF>_@S;
(MCBUFF+1)<NAMEF>_.NAME;
(MCBUFF+1)<ACTUALF>_.NPAR;
(MCBUFF+2)<WORDF>_.FBLK;
POSIT_.COUNT;
IF .PTR EQL 0 THEN POPEXP(); !TEST FOR NULL ACTUAL PARAMETER
END;
% POPEXP---
%
%3.1% GLOBAL ROUTINE POPEXP =
BEGIN
LOCAL T,S,U;
T_ST[S_.(MCBUFF+1)<NEXTF>,0];
IF .(MCBUFF+1)<ACTUALF> EQL 0 THEN
(%WE HAVE FINISHED A MACRO EXPANSION - TIME
TO RELEASE THE ACTUAL PARAMETER STRINGS
%
IF (U_.(.(MCBUFF+2))<LEFTF>) GEQ 1 THEN
INCR J FROM .(MCBUFF+2)<0,36>+1 TO .(MCBUFF+2)<0,36>+.U DO
PRGSTR(@.J);
%RECORD THAT THIS STENTRY IS TO BE UNMARKED INUSE%
U_ST[.(MCBUFF+1)<NAMEF>,1]<0,0>;
IF .FORGET<LEFTF> NEQ 0 THEN (.U)<LEFTF>_.FORGET<LEFTF>;
FORGET<LEFTF>_.U;
% FORGETTING MEANS THAT ALTHOUGH ALL OF THE CHARACTERS
FROM THE MACRO BODY, OR SPRINGING FROM IT VIA ITS
ACTUALS OR FROM EXPANSIONS OF MACROS APPEARING IN
ITS BODY OR ITS ACTUALS, ETC., HAVE BEEN SCANNED,
IT IS NOT SAFE TO TURN OFF THE INUSEBIT, THE FEAR
BEING THAT THE MACRO NAME ITSELF MAY HAVE BEEN SCANNED
FROM WITHIN ITSELF.
WHEN MAY INUSEBIT BE TURNED OFF SAFELY? THE CHANGE OF
5.200.7 ASSERTS THAT IT IS AS SOON AS A CHARACTER HAS
BEEN SCANNED AND PLACED IN ACCUM IN THE ACCUMULATION OF
AN IDENTIFIER; FOR SUCH A CHARACTER MUST HAVE COME FROM
"BELOW" ANY MACRO WHICH IS IN THE FORGET LIST. %
);
MCBUFF_@@T;
(MCBUFF+1)<WORDF>_@(@T+1);
POSIT_.(@T+2)<POSITF>;
CHAR_.(@T+2)<CHARF>;
(MCBUFF+2)<WORDF>_@(.T+3);
RELEASESPACE(.S,2);
IF .EMFLG THEN
(NEWLINE();
OUTSTR("RETUR",5);OUTSTR("N TO ",5);
IF (T_.(MCBUFF+1)<NAMEF>) EQL 0
THEN (OUTSTR("SOURC",5);OUTSTR("E.",2);NEWLINE())
ELSE (OUTSTN(.T);OCHAR(":"));
);
END;
% PRGSTR---
RELEASE A BODY TYPE STRING FROM CORE.
USED WITH BOTH THE BODY AND THE ACTUAL PARAMETERS
OF A MACRO CALL.
%
GLOBAL ROUTINE PRGSTR(T) =
BEGIN
LOCAL S;
UNTIL .T EQL 0 DO
(S_.ST[.T,2*NOBLKS-1]<NEXTF>;
RELEASESPACE(.T,NOBLKS);
T_.S
);
END;
% DUMPMACRO---
ROUTINE TO DELETE THE DEFINITION OF A MACRO.
CALLED ONLY BY BLOCKPURGE.
NOTE: IF MACRO IS CURRENTLY EXPANDING THIS
DEFINITION THEN IT IS NOT PURGED BUT SIMPLY ALLOWED
TO BE DISCONNECTED FROM THE SYMBOL TABLE. IT TERMINATES
EXPANSION NORMALLY AND THEN IS EFFECTIVELY GONE.
THE SPACE IS NEVER RECOVERD.
%
GLOBAL ROUTINE DUMPMACRO (STI) =
BEGIN
LOCAL FORMAL,NAME,T;
%CHECK THAT NAME NOT ON MACRO EXPANSION LIST%
T_ST[.STI,1];
IF .(.T)<INUSEBIT> THEN
(WARNEM(.NDEL,#176);
OUTSTR("MACRO",5);OUTSTR(": ",2);
OUTSTN(.STI);
NEWLINE();
RETURN
);
%GOT HERE THEN DELETE DEFINITION%
FORMAL_.ST[.STI,1]<NEXTF>;
PRGSTR(.(T_ST[.FORMAL,0])<NEXTF>); !DELETE THE BODY
RELEASESPACE(.STI,2); !NOW THE STENTRY ITSELF
RELEASESPACE(.FORMAL,.(.T)<LEFTF>/2+1); !AND THE FORMAL BLOCK
END;
!**********************SECTION 3****************************
% SCANNER---
%
FORWARD SCAN2;
GLOBAL ROUTINE SCANNER =
BEGIN
REGISTER R;
MACHOP ILDB=#134;
IF .MCBUFF NEQ 0 THEN %READING FROM MACRO TEXT%
(SCAN2();
IF .EMFLG AND (.MCBUFF NEQ 0) THEN
IF .CHAR EQL EOL THEN NEWLINE() ELSE OCHAR(.CHAR)
)
ELSE %READING FROM SOURCE%
(IF .CHAR EQL EOL THEN READALINE();
CHAR _ ILDB(R,PBUFF);
NCBUFF _ .NCBUFF + (IF .CHAR EQL #11 %TAB% THEN 8 ELSE 1);
);
TYPE _ .TYPETAB[.CHAR]
END;
ROUTINE SCAN2 =
%DO THE ACTUAL PROCESSING OF MACRO TEXT%
BEGIN
REGISTER R;
MACHOP ILDB=#134;
IF .POSIT GEQ TOOBIG THEN
(POSIT _ 1;
MCBUFF _ (ST[.(.MCBUFF)<NEXTF>,0]-1)<1,7>
);
POSIT _ .POSIT + 1;
CHAR _ ILDB(R,MCBUFF);
WHILE .CHAR EQL TERMINATOR DO POPEXP();
IF .CHAR EQL #176 THEN !INVOKE ACTUAL ACTUAL PARAMETER
%2.20% BEGIN
%2.20% !IF WE HAVE A NULL PARAMETER, IGNORE IT
%2.20% !BY SUBSTITUTING THE NULL STRING IN THE MACRO WHERE
%2.20% !THE ACTUAL PARAMETER WOULD HAVE GONE.
%2.20% SCAN2(); !TO GET THE PARAMETER NUMBER
%2.20% IF @(.(MCBUFF + 2) +.CHAR) EQL 0 !WE HAVE A NULL ACTUAL
%2.20% THEN SCAN2() !SIMPLY RETURN NEXT CHAR OF MACRO BODY
%2.20% ELSE !PROCESS THE NON-NULL ACTUAL PARAMETER STRING
%2.20% (PUSHEXP(.(MCBUFF+2)+.CHAR,
TOOBIG,
.(MCBUFF+1)<NAMEF>,
.CHAR,
0,
.(MCBUFF+2)
);
SCAN2()
);
%2.25% END;
IF .CHAR EQL 0 THEN SCAN2();
END;
!END OF LOMACR.BLI