%$L+,C-,R-,T+\ PROGRAM CROSS ( TTY, INPUT, OUTPUT ); (*PROGRAMM ZUR ERSTELLUNG EINER CROSSREFERENZLISTE MIT GLEICHZEITIGEM FORMATIEREN EINES PASCALPROGRAMMS. GESCHRIEBEN VON MANUEL MALL.*) LABEL 99; CONST VERSION = 'CROSS VERSION OF JUN 20,75'; %DATUM DER LETZTEN AENDERUNG\ FEED = 2; %ZEICHENVORSCHUB BEI PROZEDUREN UND BLOECKEN\ MAXCH = 72; %MAXIMALE ZAHL VON ZEICHEN PRO DRUCKZEILE\ BACKFEED = 1; %ZEICHENVORRUECKUNG BEI 'PROCEDURE','BEGIN' ETC.\ MAXLINE = 40; %MAXIMALE ZAHL VON ZEILEN PRO DRUCKSEITE\ HT = 11B; %ASCII HORIZONTAL TAB\ LF = 12B; %ASCII LINE FEED\ FF = 14B; %ASCII FORM FEED\ CR = 15B; %ASCII CARIAGE RETURN\ TYPE LINEPTRTY = ^LINE; LISTPTRTY = ^LIST; PROCCALLTY = ^PROCCALL; PROCSTRUCTY = ^PROCSTRUC; LINENRTY = 0..7777B; PAGENRTY = 0..77B; STR5 = PACKED ARRAY [1..5] OF CHAR; WORD = PACKED ARRAY [1..10] OF CHAR; SYMBOL = (LABELSY,CONSTSY,TYPESY,VARSY, %DECSYM\ FUNCTIONSY,PROCEDURESY,INITPROCSY, %PROSYM\ ENDSY,UNTILSY,ELSESY,THENSY,EXITSY,OFSY,DOSY,EOBSY, %ENDSYMBOLS\ BEGINSY,CASESY,LOOPSY,REPEATSY,IFSY, %BEGSYM\ RECORDSY,FORWARDSY,OTHERSY,INTCONST,IDENT,STRGCONST,EXTERNSY, RPARENT,SEMICOLON,POINT,LPARENT,COLON,LBRACK,OTHERSSY%DELIMITER\); LINE = PACKED RECORD %BESCHREIBUNG DER ZEILENNUMMERN\ LINENR : LINENRTY; %ZEILENNUMMER\ PAGENR : PAGENRTY; %SEITENNUMMER\ CONTLINK : LINEPTRTY %NAECHSTER ZEILENNUMMERNRECORD\ END; LIST = PACKED RECORD %BESCHREIBUNG VON IDENTIFIERN\ NAME : WORD; %NAME DES IDENTIFIERS\ LLINK , %LINKER NACHFOLGER IN BAUM\ RLINK : LISTPTRTY; %RECHTER NACHFOLGER IM BAUM\ FIRST , %ZEIGER AUF ERSTEN ZEILENNUMMERNRECORD\ LAST : LINEPTRTY; %ZEIGER AUF LETZTEN ZEILENNUMMERNRECORD\ PROCVAR : 0..2; %0=KEINE PROZEDUR/ 1=PROZEDUR/ 2=FUNKTION\ CALLED, %ZEIGER AUF DIE ERSTE PROZEDUR DIE VON DIESER GERUFEN WIRD\ CALLEDBY : PROCCALLTY %ZEIGER AUF ERSTE RUFENDE PROZEDUR\ END; PROCCALL = PACKED RECORD %BESCHREIBUNG VON PROZEDURAUFRUFEN\ PROCNAME : LISTPTRTY; %ZEIGER AUF DEN ZUGEHOERIGEN IDENTIFIERRECORD\ NEXTPROC : PROCCALLTY; %ZEIGER AUF DIE NAECHSTE PROZEDUR\ FIRST, %ZEILENNUMMERNRECORD FUER DEN ERSTEN AUFRUF\ LAST : LINEPTRTY %ZEILENNUMMERNRECORD FUER DEN LETZTEN AUFRUF\ END; DOUBLEDEC = PACKED RECORD %PROZEDUREN DIE AUCH ALS NORMALE ID. DEFINIERT WURDEN\ PROCORT : LISTPTRTY; %ZEIGER AUF DIE PROZEDUR\ NEXTPROC: ^DOUBLEDEC %NAECHSTE DOPPELT DEKLARIERTE PROZEDUR\ END; PROCSTRUC = PACKED RECORD %BESCHREIBUNG DER PROZEDURVERSCHACHTELUNG\ PROCNAME : LISTPTRTY; %ZEIGER AUF DEN ZUGERHOERIGEN IDENTIFIER\ NEXTPROC : PROCSTRUCTY; %ZEIGER AUF DIE NAECHSTD DEKLARIERTE PROZEDUR\ LINENR : LINENRTY; %ZEILENNUMMER DER PROZEDURDEFINITION\ PAGENR , %SEITENNUMMER DER PROZEDURDEFINITION\ PROCLEVEL: PAGENRTY %VERSCHACHTELUNGSTIEFE DER PROZEDUR\ END; VAR PIX, I, %SCHLEIFENVARIABLE\ BUFFLEN, %LAENGE DES BESCHRIEBENEN TEILS DES EINGABEPUFFERS\ BUFFMARK, %LAENGE DES SCHON GEDRUCKTEN TEIL DES PUFFERS\ BUFFERPTR, %ZEIGER AUF DAS NAECHSTE ZU LESENDE ZEICHEN IM PUFFER\ BUFFINDEX, %ZEIGER IM ARRAY VON BUFF\ BMARKNR, %ZU DRUCKENDE NUMMER FUER MARKIERUNG VON 'BEGIN', 'LOOP' ETC.\ EMARKNR, %ZU DRUCKENDE NUMMER FUER MARKIERUNG VON 'END', 'UNTIL' ETC.\ SPACES, %ZEICHENVORSCHUB FUER DIE FORMATIERUNG\ LASTSPACES, %LETZTER BENUTZTER ZEICHENVORSCHUB\ SYLENG, %LAENGE DES LETZTEN GELESENEN BEZEICHNERS\ CHCNT, %ANZAHL DER RELEVANTEN ZEICHEN IM LETZTEN BEZEICHNER\ LEVEL, %VERSCHACHTELUNGSTIEFE DER AKTUELLEN PROZEDUR\ BLOCKNR, %ZAEHLT DIE GEKENNZEICHNETEN STATEMENTS\ PROCDEC, %GESETZT BEI PROZEDUR DEKLARATION 1=PROCEDURE 2=FUNCTION\ PAGECNT, %ZAEHLT DIE SOS-SEITEN\ PAGECNT2, %ZAEHLT DIE DRUCKSEITEN PRO SOS-SEITE\ INCREMENT, %PARAMETER FUER DIE ERHOEHUNG DER ZEILENNUMMERN\ MAXINC, %GROESSTE ERLAUBTE ZEILENNUMMER\ REALLINCNT, %ZAEHLT DIE ZEILEN PRO DRUCKSEITE\ LINECNT : INTEGER; %ZAEHLT DIE ZEILEN PRO SOS-SEITE\ INPUTFILE, %BESCHREIBUNG DES EINGABEFILES\ OUTPUTFILE : RECORD %BESCHREIBUNG DES AUSGABEFILES\ FILENAME : PACKED ARRAY [1..12] OF CHAR END; PAS,NUE,CRL: PACKED ARRAY [0..3] OF CHAR; BUFFER : ARRAY [1..147] OF CHAR; %EINGABEPUFFER (147 ZEICHEN = MAX. LAENGE SOS-ZEILE)\ LINENB : PACKED ARRAY [1..5] OF CHAR; %SOS-ZEILENNUMMER\ TIMEANDDAY : PACKED ARRAY [1..24] OF CHAR; %DATUM UND UHRZEIT FUER DRUCKSEITENKOPF\ SY : WORD; %LETZTER GELESENER BEZEICHNER\ SYTY : SYMBOL; %TYP DES LETZTEN GELESENEN ZEICHENS\ ERRFLAG, %FEHLERMARKE\ OLDSPACES, %GESETZT WENN LASTSPACES BENUTZT WERDEN SOLL\ EOB : BOOLEAN; %EOF-MARKE\ CH, %LETZTES GELESENES ZEICHEN\ BMARKTEXT, %TEXT ZUR MARKIERUNG VON 'BEGIN' ETC.\ EMARKTEXT: CHAR; %TEXT ZUR MARKIERUNG VON 'END' ETC.\ DELSY : ARRAY [' '..'_'] OF SYMBOL; %TYPENARRAY FUER DELIMITERZEICHEN\ RESNUM : ARRAY [1..11] OF INTEGER; %STARTADRESSEN FUER DIE RESERVIERTEN WORTE BESTIMMTER LAENGE\ RESLIST : ARRAY [1..43] OF WORD; %LISTE DER RESERVIERTEN WORTE\ RESSY : ARRAY [1..43] OF SYMBOL; %TYPENLISTE DER RESERVIERTEN WORTE\ ALPHANUM, %ZEICHEN VON 0..9 UND A..Z\ DIGITS, %ZEICHEN VON 0..9\ LETTERS : SET OF CHAR; %ZEICHEN VON A..Z\ RELEVANTSYM, %STARTSYMBOLE FUER STATEMENTS UND PROCEDURES\ PROSYM, %ALLE SYMBOLE DIE DEN BEGINN EINER PROZEDUR KENNZEICHNEN\ DECSYM, %ALLE SYMBOLE DIE DEN BEGINN VON DEKLARATIONEN KENNZEICHNEN\ BEGSYM, %ALLE SYMBOLE DIE DEN BEGINN EINES STATEMENTS KENNZEICHNEN\ ENDSYM : SET OF SYMBOL; %ALLE SYMBOLE DIE STATEMENTS ODER PROZEDUREN TERMINIEREN\ LISTPTR : LISTPTRTY; %ZEIGER IM BINAERBAUM DER DEKLARIETEN BEZEICHNER\ FIRSTNAME : ARRAY ['A'..'Z'] OF LISTPTRTY; %ZEIGER AUF DIE WURZELN DES BAUMES\ PROCSTRUCF, %ZEIGER AUF DAS ERSTE ELEMENT DER PROZEDURENLISTE\ PROCSTRUCL : PROCSTRUCTY; %ZEIGER AUF DAS LETZTE ELEMENT DER PROZEDURENLISTE\ NEWFIL : FILE OF CHAR; %AUSGABEFILE AUF DEM DAS NEUFORMATIERTE PROGRAMM STEHT\ MESSAGE : PACKED ARRAY [1..23] OF CHAR; %ARRAY ZUR AUSGABE DER SCHLUSSMELDUNG\ PROCEDURE INIT; BEGIN RESNUM[1] := 1; RESNUM[2] := 1; RESNUM[3] := 7; RESNUM[4] :=15; RESNUM[5] :=26; RESNUM[6] :=32; RESNUM[7] :=38; RESNUM[8] :=41; RESNUM[9] :=42; RESNUM[10]:=43; RESNUM[11]:=44; RESLIST[ 1] :='IF '; RESSY [ 1] := IFSY; RESLIST[ 2] :='TO '; RESSY [ 2] := OTHERSY; RESLIST[ 3] :='OF '; RESSY [ 3] := OFSY; RESLIST[ 4] :='IN '; RESSY [ 4] := OTHERSY; RESLIST[ 5] :='DO '; RESSY [ 5] := DOSY; RESLIST[ 6] :='OR '; RESSY [ 6] := OTHERSY; RESLIST[ 7] :='END '; RESSY [ 7] := ENDSY; RESLIST[ 8] :='FOR '; RESSY [ 8] := OTHERSY; RESLIST[ 9] :='SET '; RESSY [ 9] := OTHERSY; RESLIST[10] :='AND '; RESSY [10] := OTHERSY; RESLIST[11] :='NOT '; RESSY [11] := OTHERSY; RESLIST[12] :='VAR '; RESSY [12] := VARSY; RESLIST[13] :='NIL '; RESSY [13] := OTHERSY; RESLIST[14] :='DIV '; RESSY [14] := OTHERSY; RESLIST[15] :='LOOP '; RESSY [15] := LOOPSY; RESLIST[16] :='CHAR '; RESSY [16] := OTHERSY; RESLIST[17] :='GOTO '; RESSY [17] := OTHERSY; RESLIST[18] :='THEN '; RESSY [18] := THENSY; RESLIST[19] :='ELSE '; RESSY [19] := ELSESY; RESLIST[20] :='WITH '; RESSY [20] := OTHERSY; RESLIST[21] :='CASE '; RESSY [21] := CASESY; RESLIST[22] :='REAL '; RESSY [22] := OTHERSY; RESLIST[23] :='FILE '; RESSY [23] := OTHERSY; RESLIST[24] :='TYPE '; RESSY [24] := TYPESY; RESLIST[25] :='EXIT '; RESSY [25] := EXITSY; RESLIST[26] :='BEGIN '; RESSY [26] := BEGINSY; RESLIST[27] :='ARRAY '; RESSY [27] := OTHERSY; RESLIST[28] :='WHILE '; RESSY [28] := OTHERSY; RESLIST[29] :='CONST '; RESSY [29] := CONSTSY; RESLIST[30] :='LABEL '; RESSY [30] := LABELSY; RESLIST[31] :='UNTIL '; RESSY [31] := UNTILSY; RESLIST[32] :='RECORD '; RESSY [32] := RECORDSY; RESLIST[33] :='REPEAT '; RESSY [33] := REPEATSY; RESLIST[34] :='DOWNTO '; RESSY [34] := OTHERSY; RESLIST[35] :='PACKED '; RESSY [35] := OTHERSY; RESLIST[36] :='OTHERS '; RESSY [36] := OTHERSSY; RESLIST[37] :='EXTERN '; RESSY [37] := EXTERNSY; RESLIST[38] :='INTEGER '; RESSY [38] := OTHERSY; RESLIST[39] :='BOOLEAN '; RESSY [39] := OTHERSY; RESLIST[40] :='FORWARD '; RESSY [40] := FORWARDSY; RESLIST[41] :='FUNCTION '; RESSY [41] := FUNCTIONSY;RESLIST[42] :='PROCEDURE '; RESSY [42] := PROCEDURESY; RESLIST[43] :='INITPROCED'; RESSY [43] := INITPROCSY; I := 0; BUFFLEN := 0; BUFFMARK := 0; BUFFERPTR := 2; BUFFINDEX := 0; REALLINCNT:= 0; LINECNT :=0; BLOCKNR := 0; LEVEL := 0; PAGECNT := 1; PAGECNT2 := 0; INCREMENT := 1; EOB := FALSE; ERRFLAG := FALSE; OLDSPACES := FALSE; CH := ' '; BMARKTEXT := ' '; EMARKTEXT := ' '; SY := ' '; MESSAGE := 'ERROR IN BLOCKSTRUCTURE'; TIMEANDDAY := ' : : '; DIGITS := ['0'..'9']; LETTERS := ['A'..'Z']; ALPHANUM := ['0'..'9','A'..'Z'] %LETTERS OR DIGITS\; DECSYM := [LABELSY..VARSY]; PROSYM := [FUNCTIONSY..INITPROCSY]; ENDSYM := [FUNCTIONSY..EOBSY]; %PROSYM OR ENDSYMBOLS\ BEGSYM := [BEGINSY..IFSY]; RELEVANTSYM := [LABELSY..INITPROCSY %DECSYM OR PROSYM\ ,BEGINSY,FORWARDSY,EXTERNSY,EOBSY]; PAS:='.PAS'; NUE:='.PAS'; CRL:='.CRL'; FOR CH := 'A' TO 'Z' DO FIRSTNAME [CH] := NIL; FOR CH := ' ' TO '_' DO DELSY [CH] := OTHERSY; DELSY ['('] := LPARENT; DELSY [')'] := RPARENT; DELSY ['['] := LPARENT; DELSY [']'] := RPARENT; DELSY [';'] := SEMICOLON; DELSY ['.'] := POINT; DELSY [':'] := COLON; FOR I := 1 TO 147 DO BUFFER [I] := ' '; I := 0; NEW (FIRSTNAME['M']); LISTPTR := FIRSTNAME ['M']; WITH FIRSTNAME ['M']^ DO BEGIN NAME := 'MAIN. '; LLINK := NIL; RLINK := NIL; NEW (FIRST); LAST := FIRST; PROCVAR := 1; WITH LAST^ DO BEGIN LINENR := LINECNT; CONTLINK := NIL; END; NEW (CALLED); WITH CALLED^ DO BEGIN PROCNAME := FIRSTNAME ['M']; NEXTPROC := NIL; NEW (FIRST); FIRST^.LINENR := 0; FIRST^.CONTLINK := NIL; LAST := FIRST; END; NEW (CALLEDBY); WITH CALLEDBY^ DO BEGIN PROCNAME := FIRSTNAME ['M']; NEXTPROC := NIL; NEW (FIRST); FIRST^.LINENR := 0; FIRST^.CONTLINK := NIL; LAST := FIRST; END; END; NEW (PROCSTRUCF); WITH PROCSTRUCF^ DO BEGIN PROCNAME := FIRSTNAME ['M']; NEXTPROC := NIL; LINENR := 0; PROCLEVEL:= 0; END; PROCSTRUCL := PROCSTRUCF; END; PROCEDURE GETLINENR( FLIN: STR5 ); VAR I,L,FAC: INTEGER; BEGIN FAC:=10000; L:=LINECNT+1; FOR I:=1 TO 5 DO BEGIN FLIN[I] := CHR( L DIV FAC +60B ); L := L MOD FAC; FAC := FAC DIV 10; END END; PROCEDURE WRITECH (FCH : CHAR); BEGIN %WRITECH\ WRITE(NEWFIL,FCH); END %WRITECH\; PROCEDURE WRITELIN; BEGIN %WRITELIN\ WRITELN(NEWFIL); END %WRITELIN\; PROCEDURE WRITEPAGE; BEGIN %WRITEPAGE\ WRITELN(NEWFIL,CHR(FF)); END %WRITEPAGE\; PROCEDURE WRITELINNR; VAR I, LLINECNT : INTEGER; BEGIN %WRITELINNR\ LLINECNT := LINECNT * INCREMENT; (* I := 10000; FOR BUFFINDEX := 1 TO 4 DO BEGIN WRITE( NEWFIL, CHR (LLINECNT DIV I + 60B)); LLINECNT := LLINECNT MOD I; I := I DIV 10 END; WRITE( NEWFIL, CHR(LLINECNT+61B),CHR(HT)); *) END %WRITELINNR\; PROCEDURE DATUM; VAR DATUM,TIM : PACKED ARRAY [1..10] OF CHAR; I : INTEGER; BEGIN DATE( DATUM ); TIME( TIM ); FOR I := 1 TO 10 DO TIMEANDDAY[I] := DATUM[I]; FOR I:= 1 TO 8 DO TIMEANDDAY[I+16] := TIM[I]; END; PROCEDURE HEADER; BEGIN %HEADER\ PAGECNT2 := PAGECNT2 + 1; REALLINCNT := 0; PAGE; WRITELN ('PAGE ',PAGECNT:3,'-',PAGECNT2:3,' ':15,OUTPUTFILE.FILENAME, ' ':5,TIMEANDDAY); WRITELN; END %HEADER\ ; PROCEDURE NEWPAGE; BEGIN %NEWPAGE\ PAGECNT2 := 0; PAGECNT := PAGECNT + 1; WRITEPAGE; HEADER; IF EOLN (INPUT) THEN READLN; LINECNT := 0; REALLINCNT := 0; END %NEWPAGE\ ; PROCEDURE WRITELINE (POSITION %LETZTES ZU DRUCKENDES ZEICHEN IM PUFFER\ : INTEGER); VAR I, TABCNT, LSPACES : INTEGER; %MARKIERT ERSTES ZU DRUCKENDES ZEICHEN\ BEGIN %WRITELINE\ POSITION := POSITION - 2; IF POSITION > 0 THEN BEGIN I := BUFFMARK + 1; WHILE (BUFFER [I] = ' ') AND (I <= POSITION) DO I := I + 1; BUFFMARK := POSITION; WHILE (BUFFER [POSITION] = ' ') AND (I < POSITION) DO POSITION := POSITION - 1; IF I <= POSITION THEN BEGIN IF REALLINCNT = MAXLINE THEN HEADER; LINECNT := LINECNT + 1; REALLINCNT := REALLINCNT + 1; IF BMARKTEXT # ' ' THEN BEGIN WRITE (BMARKTEXT, BMARKNR : 4, ' '); BMARKTEXT := ' '; END ELSE IF EMARKTEXT # ' ' THEN BEGIN WRITE (' ',EMARKTEXT,EMARKNR : 4,' '); EMARKTEXT := ' '; END ELSE WRITE (' '); WRITE (LINECNT * INCREMENT : 5,' '); WRITELINNR; IF NOT OLDSPACES THEN LASTSPACES := SPACES; WRITE (' ' : LASTSPACES); TABCNT := LASTSPACES DIV 8; LSPACES := LASTSPACES MOD 8; FOR TABCNT := TABCNT DOWNTO 1 DO WRITECH (CHR(HT)); FOR LSPACES := LSPACES DOWNTO 1 DO WRITECH (' '); IF (POSITION - I + LASTSPACES + 1) > MAXCH THEN BEGIN IF REALLINCNT = MAXLINE THEN BEGIN FOR I := I TO MAXCH + I - LASTSPACES - 1 DO BEGIN WRITE (BUFFER[I]); WRITECH (BUFFER[I]); BUFFER [I] := ' '; END; WRITELN; HEADER; END; REALLINCNT := REALLINCNT + 1; END; FOR I := I TO POSITION DO BEGIN WRITE (BUFFER [I]); WRITECH (BUFFER[I]); BUFFER [I] := ' '; END; WRITELIN; WRITELN; IF ((LINENB = ' ') AND (POSITION = BUFFLEN)) OR (MAXINC = LINECNT) THEN NEWPAGE; END; END; LASTSPACES := SPACES; OLDSPACES := FALSE; END %WRITELINE\ ; PROCEDURE BLOCK; VAR DOUBLEDECF, %ZEIGER AUF ERSTE UND LETZTE VARIABLE DIE ALS PROCEDURE\ DOUBLEDECL : ^DOUBLEDEC; %IN DIESEM BLOCK DOPPELT DEKLARIERT WURDEN\ CURPROC : LISTPTRTY; %ZEIGER AUF DIE PROZEDUR IN DEREN ANWEISUNGSTEIL DAS PROGRAMM SICH BEFINDET\ PROCEDURE INSYMBOL ; LABEL 1; VAR OLDSPACESMARK, %ALTER ZEICHENVORSCHUB BEI FORMATIERUNG VON KOMMENTAREN\ I : INTEGER; PROCEDURE READBUFFER; PROCEDURE READLINE; VAR CH : CHAR; BEGIN %READLINE\ REPEAT WHILE EOLN (INPUT) AND NOT (EOF (INPUT)) DO BEGIN GETLINENR (LINENB); READLN; IF LINENB = ' ' THEN NEWPAGE ELSE BEGIN IF REALLINCNT = MAXLINE THEN HEADER; LINECNT := LINECNT + 1; REALLINCNT := REALLINCNT + 1; WRITELN (' ' : 12,LINECNT * INCREMENT : 5); WRITELINNR; WRITELIN; IF MAXINC = LINECNT THEN NEWPAGE; END; END; READ (CH); IF CH = CHR(HT) THEN CH := ' '; UNTIL (CH # ' ') OR (EOF (INPUT)); BUFFLEN := 0; LOOP BUFFLEN := BUFFLEN + 1; BUFFER [BUFFLEN] := CH; EXIT IF (EOLN (INPUT) OR (BUFFLEN = 147)); READ (CH); IF CH = CHR(HT) THEN CH := ' '; END; IF NOT (EOLN (INPUT)) THEN BEGIN WRITELN (TTY); WRITELN (TTY,'LINE ',(LINECNT+1)*INCREMENT : 5,'TOO LONG'); WRITELN (' ' : 17,' **** NEXT LINE TOO LONG ****'); END ELSE IF NOT (EOF (INPUT)) THEN BEGIN GETLINENR (LINENB); READLN; END; BUFFERPTR := 1; BUFFMARK := 0; END %READLINE\ ; BEGIN %READBUFFER\ IF BUFFERPTR = BUFFLEN + 2 THEN BEGIN WRITELINE (BUFFERPTR); CH := ' '; IF EOF (INPUT) THEN EOB := TRUE ELSE READLINE; END ELSE BEGIN CH := BUFFER [BUFFERPTR]; BUFFERPTR := BUFFERPTR + 1; END; END %READBUFFER\ ; PROCEDURE LPARENTHESE; VAR OLDSPACESMARK : INTEGER; %ALTER ZEICHENVORSCHUB BEI FORMATIERUNG VON KLAMMERN\ BEGIN %PARENTHESE\ OLDSPACESMARK := SPACES; IF OLDSPACES THEN SPACES := LASTSPACES + BUFFERPTR - 2 ELSE BEGIN LASTSPACES := SPACES; SPACES := SPACES + BUFFERPTR - 2; OLDSPACES := TRUE; END; REPEAT INSYMBOL UNTIL SYTY IN [RPARENT,EOBSY]; SPACES := OLDSPACESMARK; OLDSPACES := TRUE; INSYMBOL; END %PARENTHESE\ ; FUNCTION RESWORD: BOOLEAN ; LABEL 1; VAR I : INTEGER; BEGIN %RESWORD\ RESWORD:= FALSE; FOR I:=RESNUM[CHCNT] TO RESNUM [CHCNT + 1] -1 DO IF RESLIST[ I ] = SY THEN BEGIN RESWORD := TRUE; SYTY := RESSY [I]; GOTO 1; END; 1: END %RESWORD\ ; PROCEDURE FINDNAME; LABEL 1; VAR PROCPTR : PROCCALLTY; %ZEIGER AUF RUFENDE BZW. GERUFENE PROZEDUR BEI DEREN VERKETTUNG\ LPTR: LISTPTRTY; %ZEIGER AUF DEN VORGAENGER IM BAUM\ ZPTR : LINEPTRTY; %ZEIGER AUF DIE VORLETZTE ZEILENNUMMER IN EINER KETTE\ RIGHT: BOOLEAN; %MERKVARIABLE FUER DIE VERZWEIGUNG IM BAUM\ INDEXCH : CHAR; %INDEXVARIABLE FUER DAS FELD DER STARTZEIGER (FIRSTNAME)\ PROCEDURE FINDPROC (COMP : LISTPTRTY); VAR PROCCALLPTR : PROCCALLTY; %MERK SICH LETZTE PROZEDUR FALLS EINE NEUE ERZEUGT WERDEN MUSS\ BEGIN %FINDPROC\ WHILE (PROCPTR^.PROCNAME # COMP) AND (PROCPTR^.NEXTPROC # NIL) DO PROCPTR := PROCPTR^.NEXTPROC; IF PROCPTR^.PROCNAME = COMP THEN BEGIN ZPTR := PROCPTR^.LAST; NEW (PROCPTR^.LAST); WITH PROCPTR^.LAST^ DO BEGIN LINENR := LINECNT + 1; PAGENR := PAGECNT; CONTLINK := NIL; END; ZPTR^.CONTLINK := PROCPTR^.LAST; END ELSE BEGIN PROCCALLPTR := PROCPTR; NEW (PROCPTR); WITH PROCPTR^ DO BEGIN PROCNAME := COMP; NEXTPROC := NIL; ZPTR := FIRST; NEW (FIRST); WITH FIRST^ DO BEGIN LINENR := LINECNT + 1; PAGENR := PAGECNT; CONTLINK := NIL; END; ZPTR^.CONTLINK := FIRST; LAST := FIRST; END; PROCCALLPTR^.NEXTPROC := PROCPTR; END; END %FINDPROC\ ; PROCEDURE NEWPROCEDURE; BEGIN %NEWPROCEDURE\ WITH LISTPTR^ DO BEGIN PROCVAR := PROCDEC; NEW (CALLEDBY); WITH CALLEDBY^ DO BEGIN PROCNAME := CURPROC; NEXTPROC := NIL; ZPTR := FIRST; NEW (FIRST); WITH FIRST^ DO BEGIN LINENR := LINECNT + 1; PAGENR := PAGECNT; CONTLINK := NIL; END; ZPTR^.CONTLINK := FIRST; LAST := FIRST; END; NEW (CALLED); WITH CALLED^ DO BEGIN PROCNAME := FIRSTNAME ['M']; NEXTPROC := NIL; ZPTR := FIRST; NEW (FIRST); WITH FIRST^ DO BEGIN LINENR := LINECNT + 1; PAGENR := PAGECNT; CONTLINK := NIL; END; ZPTR^.CONTLINK := FIRST; LAST := FIRST; END; END; NEW (PROCSTRUCL^.NEXTPROC); PROCSTRUCL := PROCSTRUCL^.NEXTPROC; WITH PROCSTRUCL^ DO BEGIN PROCNAME := LISTPTR; NEXTPROC := NIL; LINENR := LINECNT + 1; PAGENR := PAGECNT; PROCLEVEL := LEVEL; END; END %NEWPROCEDURE\ ; BEGIN %FINDNAME\ INDEXCH := SY [1]; LISTPTR := FIRSTNAME [INDEXCH]; WHILE LISTPTR # NIL DO BEGIN LPTR:= LISTPTR; IF SY = LISTPTR^.NAME THEN BEGIN ZPTR := LISTPTR^.LAST; NEW (LISTPTR^.LAST); WITH LISTPTR^.LAST^ DO BEGIN LINENR := LINECNT + 1; PAGENR := PAGECNT; CONTLINK := NIL; END; ZPTR^.CONTLINK := LISTPTR^.LAST; IF LISTPTR^.PROCVAR # 0 THEN BEGIN IF LISTPTR^.PROCVAR = 2 THEN WHILE CH = ' ' DO BEGIN SYLENG := SYLENG + 1; READBUFFER; END; IF (CH # ':') OR (LISTPTR^.PROCVAR = 1) THEN BEGIN PROCPTR := LISTPTR^.CALLEDBY; FINDPROC (CURPROC); PROCPTR := CURPROC^.CALLED; FINDPROC (LISTPTR); END END ELSE IF PROCDEC # 0 THEN BEGIN IF DOUBLEDECF = NIL THEN BEGIN NEW (DOUBLEDECF); DOUBLEDECL := DOUBLEDECF; END ELSE BEGIN NEW (DOUBLEDECL^.NEXTPROC); DOUBLEDECL := DOUBLEDECL^.NEXTPROC; END; DOUBLEDECL^.NEXTPROC := NIL; DOUBLEDECL^.PROCORT := LISTPTR; NEWPROCEDURE; END; GOTO 1; END ELSE IF SY > LISTPTR^.NAME THEN BEGIN LISTPTR:= LISTPTR^.RLINK; RIGHT:= TRUE; END ELSE BEGIN LISTPTR:= LISTPTR^.LLINK; RIGHT:= FALSE; END; END; NEW (LISTPTR); WITH LISTPTR^ DO BEGIN NAME := SY; LLINK := NIL; RLINK := NIL; END; IF FIRSTNAME [INDEXCH] = NIL THEN FIRSTNAME [INDEXCH] := LISTPTR ELSE IF RIGHT THEN LPTR^.RLINK := LISTPTR ELSE LPTR^.LLINK := LISTPTR; WITH LISTPTR^ DO BEGIN NEW (FIRST); WITH FIRST^ DO BEGIN LINENR := LINECNT + 1; PAGENR := PAGECNT; CONTLINK := NIL; END; LAST := FIRST ; IF PROCDEC = 0 THEN BEGIN PROCVAR := 0; CALLED := NIL; CALLEDBY := NIL; END ELSE NEWPROCEDURE; END; 1: PROCDEC := 0; END %FINDNAME\ ; BEGIN %INSYMBOL\ SYLENG := 0; WHILE (CH IN ['_','(',' ','%','$','?','\','!','@']) AND NOT EOB AND (CH <= '_') DO BEGIN IF (CH = '%') OR (CH = '(') AND (BUFFER[BUFFERPTR] = '*') THEN BEGIN OLDSPACESMARK := SPACES; IF OLDSPACES THEN SPACES := LASTSPACES ELSE LASTSPACES := SPACES; SPACES := SPACES + BUFFERPTR - 1; OLDSPACES := TRUE; IF CH = '%' THEN REPEAT READBUFFER; UNTIL (CH = '\') OR EOB ELSE REPEAT READBUFFER UNTIL (CH = ')') AND (BUFFER[BUFFERPTR-2] = '*') OR EOB; SPACES := OLDSPACESMARK; OLDSPACES := TRUE; END ELSE IF CH = '(' THEN GOTO 1; READBUFFER; END; IF CH = '''' THEN BEGIN SYTY := STRGCONST; REPEAT READBUFFER; UNTIL (CH = '''') OR EOB; READBUFFER; END ELSE IF (CH IN LETTERS) OR (ORD(CH) > 137B) THEN BEGIN SYLENG := 0; REPEAT SYLENG := SYLENG + 1; IF ORD(CH) > 137B THEN CH := CHR(ORD(CH)-32); IF SYLENG <= 10 THEN SY [SYLENG] := CH; READBUFFER; UNTIL NOT ((CH IN (ALPHANUM OR ['_'])) OR (CH > '_')); FOR I := SYLENG + 1 TO 10 DO SY [I] := ' '; IF SYLENG > 10 THEN CHCNT := 10 ELSE CHCNT := SYLENG; IF NOT RESWORD THEN BEGIN SYTY := IDENT ; FINDNAME; END END ELSE IF CH IN DIGITS THEN BEGIN REPEAT READBUFFER; UNTIL NOT (CH IN DIGITS); SYTY := INTCONST; IF CH = 'B' THEN READBUFFER ELSE BEGIN IF CH = '.' THEN BEGIN REPEAT READBUFFER UNTIL NOT (CH IN DIGITS); SYTY := OTHERSY; END; IF CH = 'E' THEN BEGIN READBUFFER; IF CH IN ['+','-'] THEN READBUFFER; WHILE CH IN DIGITS DO READBUFFER; SYTY := OTHERSY; END; END; END ELSE IF CH = '"' THEN BEGIN REPEAT READBUFFER UNTIL NOT (CH IN (DIGITS OR ['A'..'F'])); SYTY := INTCONST; END ELSE IF CH # ' ' THEN BEGIN 1 : SYTY := DELSY [CH]; READBUFFER; IF SYTY = LPARENT THEN LPARENTHESE ELSE IF (SYTY = COLON) AND (CH = '=') THEN BEGIN SYTY := OTHERSY; READBUFFER; END; END ELSE SYTY := EOBSY; END %INSYMBOL\ ; PROCEDURE RECDEF; VAR OLDSPACESMARK : INTEGER; %ALTER ZEICHENVORSCHUB BEI FORMATIERUNG VON RECORDS\ PROCEDURE CASEDEF; VAR OLDSPACESMARK : INTEGER; %ALTER ZEICHENVORSCHUB BEI FORMATIERUNG VON VARIANT PARTS\ PROCEDURE PARENTHESE; VAR OLDSPACESMARK : INTEGER; %ALTER ZEICHENVORSCHUB BEI FORMATIERUNG VON KLAMMERN INNERHALB VON VARIANT PARTS\ BEGIN %PARENTHESE\ OLDSPACESMARK := SPACES; IF OLDSPACES THEN SPACES := LASTSPACES ELSE LASTSPACES := SPACES; SPACES := SPACES + BUFFERPTR - 2; OLDSPACES := TRUE; REPEAT INSYMBOL; CASE SYTY OF LBRACK : PARENTHESE; CASESY : CASEDEF; RECORDSY : RECDEF END; UNTIL SYTY IN [RPARENT,EOBSY]; SPACES := OLDSPACESMARK; OLDSPACES := TRUE; INSYMBOL; END %PARENTHESE\ ; BEGIN %CASEDEF\ DELSY ['('] := LBRACK; OLDSPACESMARK := SPACES; IF OLDSPACES THEN SPACES := LASTSPACES ELSE LASTSPACES := SPACES; SPACES := BUFFERPTR - BUFFMARK + SPACES - SYLENG + 3; OLDSPACES := TRUE; REPEAT INSYMBOL ; CASE SYTY OF LBRACK : PARENTHESE; CASESY : CASEDEF; RECORDSY: RECDEF END; UNTIL SYTY IN [ENDSY,RPARENT,EOBSY]; SPACES := OLDSPACESMARK; DELSY ['('] := LPARENT; END %CASEDEF\ ; BEGIN %RECDEF\ OLDSPACESMARK := SPACES; SPACES := BUFFERPTR - BUFFMARK + SPACES - SYLENG - 2 + FEED; OLDSPACES := TRUE; INSYMBOL; WRITELINE ( BUFFERPTR-SYLENG); REPEAT CASE SYTY OF CASESY : CASEDEF; RECORDSY : RECDEF; OTHERS : INSYMBOL END; UNTIL SYTY IN [ENDSY,EOBSY]; WRITELINE (BUFFERPTR-SYLENG); OLDSPACES := TRUE; LASTSPACES := SPACES - FEED; SPACES := OLDSPACESMARK; INSYMBOL; END %RECDEF\ ; PROCEDURE ERROR (ERRNR : INTEGER); BEGIN %ERROR\ ERRFLAG := TRUE; WRITELINE (BUFFERPTR); WRITE (' ':17,' **** '); CASE ERRNR OF 1 : WRITELN (SY,' ? ? ? ',MESSAGE); 2 : WRITELN ('MISSING ''END'' OR ''UNTIL'' NUMBER ',EMARKNR : 4); 3 : WRITELN ('MISSING ''THEN'' NUMBER ',EMARKNR : 4); 4 : WRITELN ('MISSING ''OF'' TO ''CASE'' NUMBER ',BMARKNR : 4); 5 : WRITELN (' ONLY ONE ''EXIT'' ALLOWED'); 6 : WRITELN ('MISSING ''EXIT'' IN ''LOOP'' ',EMARKNR : 4) END; END %ERROR\ ; PROCEDURE STATEMENT (IFFLAG : BOOLEAN); VAR CURBLOCKNR : INTEGER; %AKTUELLE BLOCKNUMMER\ PROCEDURE COMPSTAT; BEGIN %COMPSTAT\ BMARKTEXT := 'B'; OLDSPACES := TRUE; LASTSPACES := SPACES - BACKFEED; INSYMBOL; WRITELINE (BUFFERPTR-SYLENG); LOOP REPEAT STATEMENT (FALSE); UNTIL SYTY IN ENDSYM; EXIT IF SYTY IN [ENDSY,EOBSY,PROCEDURESY,FUNCTIONSY]; ERROR (1); INSYMBOL ; END; WRITELINE (BUFFERPTR-SYLENG); EMARKTEXT := 'E'; EMARKNR := CURBLOCKNR; LASTSPACES := SPACES-BACKFEED; OLDSPACES := TRUE; IF SYTY = ENDSY THEN BEGIN INSYMBOL ; WRITELINE (BUFFERPTR-SYLENG); END ELSE ERROR (2); END %COMPSTAT\ ; PROCEDURE CASESTAT; VAR OLDSPACESMARK : INTEGER; %ALTER ZEICHENVORSCHUB BEI FORMATIERUNG VON CASE-STATEMENTS\ BEGIN %CASESTAT\ BMARKTEXT := 'C'; OLDSPACES := TRUE; LASTSPACES := SPACES-BACKFEED; INSYMBOL; STATEMENT (FALSE); IF SYTY = OFSY THEN WRITELINE (BUFFERPTR) ELSE ERROR (3); LOOP REPEAT REPEAT INSYMBOL ; UNTIL SYTY IN (ENDSYM OR [COLON]); IF SYTY = COLON THEN BEGIN OLDSPACESMARK := SPACES; LASTSPACES := SPACES; SPACES := BUFFERPTR - BUFFMARK + SPACES - 2; OLDSPACES := TRUE; INSYMBOL; STATEMENT (FALSE); SPACES := OLDSPACESMARK; END; UNTIL SYTY IN ENDSYM; EXIT IF SYTY IN [ENDSY,EOBSY,PROCEDURESY,FUNCTIONSY]; ERROR (1); END; WRITELINE (BUFFERPTR-SYLENG); EMARKTEXT := 'E'; EMARKNR := CURBLOCKNR; LASTSPACES := SPACES-BACKFEED; OLDSPACES := TRUE; IF SYTY = ENDSY THEN BEGIN INSYMBOL ; WRITELINE (BUFFERPTR-SYLENG); END ELSE ERROR (2); END %CASESTAT\ ; PROCEDURE LOOPSTAT; VAR LOOPFLAG : BOOLEAN; %GESETZT BEIM AUFTRETEN VON EXIT-STATEMENTS\ BEGIN %LOOPSTAT\ BMARKTEXT := 'L'; OLDSPACES := TRUE; LASTSPACES := SPACES - BACKFEED; INSYMBOL; WRITELINE (BUFFERPTR-SYLENG); LOOPFLAG := FALSE; LOOP REPEAT STATEMENT (FALSE); IF SYTY = EXITSY THEN BEGIN WRITELINE (BUFFERPTR-SYLENG); IF LOOPFLAG THEN ERROR (5); OLDSPACES := TRUE; LASTSPACES := SPACES-BACKFEED; LOOPFLAG := TRUE; EMARKTEXT := 'X'; EMARKNR := CURBLOCKNR; INSYMBOL; INSYMBOL; END; UNTIL SYTY IN ENDSYM; EXIT IF SYTY IN [ENDSY,EOBSY,PROCEDURESY,FUNCTIONSY]; ERROR (1); INSYMBOL ; END; WRITELINE (BUFFERPTR-SYLENG); EMARKTEXT := 'E'; EMARKNR := CURBLOCKNR; LASTSPACES := SPACES-BACKFEED; OLDSPACES := TRUE; IF SYTY = ENDSY THEN BEGIN INSYMBOL ; WRITELINE (BUFFERPTR-SYLENG); END ELSE ERROR (2); IF NOT LOOPFLAG THEN ERROR (6); END %LOOPSTAT\ ; PROCEDURE IFSTAT (IFVAR : BOOLEAN); BEGIN %IFSTAT\ BMARKTEXT := 'I'; IF NOT IFVAR THEN BEGIN SPACES := SPACES - FEED; LASTSPACES := SPACES END ELSE LASTSPACES := SPACES - BACKFEED; OLDSPACES := TRUE; INSYMBOL; STATEMENT (FALSE); IF SYTY = THENSY THEN BEGIN WRITELINE (BUFFERPTR-SYLENG); IF IFVAR THEN LASTSPACES := SPACES - BACKFEED ELSE LASTSPACES := SPACES; OLDSPACES := TRUE; EMARKTEXT := 'T'; EMARKNR := CURBLOCKNR; INSYMBOL; STATEMENT (TRUE); END ELSE ERROR (4); IF SYTY = ELSESY THEN BEGIN WRITELINE (BUFFERPTR-SYLENG); EMARKTEXT := 'S'; EMARKNR := CURBLOCKNR; IF IFVAR THEN LASTSPACES := SPACES - BACKFEED ELSE LASTSPACES := SPACES; OLDSPACES := TRUE; INSYMBOL; STATEMENT (TRUE); END; IF NOT IFVAR THEN SPACES := SPACES + FEED END %IFSTAT\ ; PROCEDURE LABELSTAT; BEGIN %LABELSTAT\ LASTSPACES := 0; OLDSPACES := TRUE; INSYMBOL; WRITELINE (BUFFERPTR-SYLENG); END %LABELSTAT\ ; PROCEDURE REPEATSTAT; BEGIN %REPEATSTAT\ BMARKTEXT := 'R'; OLDSPACES := TRUE; LASTSPACES := SPACES - BACKFEED; INSYMBOL ; WRITELINE (BUFFERPTR-SYLENG); LOOP REPEAT STATEMENT (FALSE); UNTIL SYTY IN ENDSYM; EXIT IF SYTY IN [UNTILSY,EOBSY,PROCEDURESY,FUNCTIONSY]; ERROR (1); INSYMBOL ; END; WRITELINE (BUFFERPTR-SYLENG); EMARKTEXT := 'U'; EMARKNR := CURBLOCKNR; OLDSPACES := TRUE; LASTSPACES := SPACES-BACKFEED; IF SYTY = UNTILSY THEN BEGIN INSYMBOL; STATEMENT (FALSE); END ELSE ERROR (2); END %REPEATSTAT\ ; BEGIN %STATEMENT\ IF SYTY = INTCONST THEN BEGIN INSYMBOL; IF SYTY = COLON THEN LABELSTAT; END; IF SYTY IN BEGSYM THEN BEGIN BLOCKNR := BLOCKNR + 1; CURBLOCKNR := BLOCKNR; BMARKNR := CURBLOCKNR; WRITELINE (BUFFERPTR-SYLENG); SPACES := SPACES + FEED; CASE SYTY OF BEGINSY : COMPSTAT; LOOPSY : LOOPSTAT; CASESY : CASESTAT; IFSY : IFSTAT (IFFLAG); REPEATSY : REPEATSTAT END; SPACES := SPACES - FEED; END ELSE WHILE NOT (SYTY IN ([SEMICOLON] OR ENDSYM)) DO INSYMBOL; IF SYTY = SEMICOLON THEN INSYMBOL ELSE IF SYTY = DOSY THEN BEGIN INSYMBOL; STATEMENT (FALSE); END; END %STATEMENT\ ; BEGIN %BLOCK\ DOUBLEDECF := NIL; LEVEL := LEVEL + 1; CURPROC := LISTPTR; SPACES := LEVEL * FEED; REPEAT INSYMBOL UNTIL (SYTY IN RELEVANTSYM); WHILE SYTY IN DECSYM DO BEGIN WRITELINE (BUFFERPTR-SYLENG); SPACES := SPACES - FEED; WRITELINE (BUFFERPTR); SPACES := SPACES + FEED; REPEAT INSYMBOL ; IF SYTY = RECORDSY THEN RECDEF; UNTIL SYTY IN RELEVANTSYM; END; WHILE SYTY IN PROSYM DO BEGIN WRITELINE (BUFFERPTR-SYLENG); OLDSPACES := TRUE; IF SYTY # INITPROCSY THEN BEGIN IF SYTY = PROCEDURESY THEN PROCDEC := 1 ELSE PROCDEC := 2; INSYMBOL; END; BLOCK; IF SYTY = SEMICOLON THEN INSYMBOL; END; LEVEL := LEVEL - 1; SPACES := LEVEL * FEED; IF NOT (SYTY IN [BEGINSY,FORWARDSY,EXTERNSY]) THEN BEGIN ERROR (1); WHILE NOT (SYTY IN [BEGINSY,FORWARDSY,EXTERNSY,EOBSY]) DO INSYMBOL END; IF SYTY = BEGINSY THEN STATEMENT (FALSE) ELSE INSYMBOL; IF DOUBLEDECF # NIL THEN REPEAT DOUBLEDECF^.PROCORT^.PROCVAR := 0; DOUBLEDECF := DOUBLEDECF^.NEXTPROC; UNTIL DOUBLEDECF = NIL; IF LEVEL = 0 THEN BEGIN IF SYTY # POINT THEN BEGIN WRITELN (TTY,'MISSING POINT AT PROGRAM END'); WRITELN (TTY); WRITELN (' ' : 17, ' **** MISSING POINT AT PROGRAM END ****'); INSYMBOL; END; IF SYTY # EOBSY THEN REPEAT INSYMBOL UNTIL SYTY = EOBSY; END; END %BLOCK\ ; PROCEDURE PRINTLISTE; VAR FIRSTPROC,LASTPROC, %ZEIGER ZUM DURCHHANGELN DURCH DIE BAEUME UND LISTEN BEIM AUSDRUCKEN\ PRED : LISTPTRTY; INDEXCH : CHAR; %LAUFVARIABLE FUER DAS FELD 'FIRSTNAME' ZUM AUSDRUCKEN\ PROCEDURE WRITELINENR (SPACES : INTEGER); VAR LINK : LINEPTRTY; %ZEIGER ZUM DURCHHANGELN DURCH DIE VERKETTUNG DER ZEILENNUMMERN\ COUNT : INTEGER; %ZAEHLT DIE GEDRUCKTEN ZEILENNUMMERN PRO ZEILE\ BEGIN %WRITELINENR\ COUNT := 0; LINK := LISTPTR^.FIRST; REPEAT IF COUNT > (MAXCH - SPACES) DIV 6 THEN BEGIN WRITELN; WRITE (' ' : SPACES); COUNT := 0; END; COUNT := COUNT + 1; WRITE (LINK^.LINENR * INCREMENT : 6); LINK := LINK^.CONTLINK; UNTIL LINK = NIL; END %WRITELINENR\ ; BEGIN %PRINTLISTE\ FIRSTPROC := NIL; LASTPROC := NIL; WITH FIRSTNAME ['M']^ DO IF RLINK = NIL THEN FIRSTNAME ['M'] := LLINK ELSE BEGIN LISTPTR := RLINK; WHILE LISTPTR^.LLINK # NIL DO LISTPTR := LISTPTR^.LLINK; LISTPTR^.LLINK := LLINK; FIRSTNAME ['M'] := RLINK; END; INDEXCH := 'A'; WHILE (INDEXCH < 'Z') AND (FIRSTNAME [INDEXCH] = NIL) DO INDEXCH := SUCC (INDEXCH); IF FIRSTNAME [INDEXCH] # NIL THEN BEGIN PAGE; WRITELN ('CROSS REFERENCE LIST OF IDENTIFIERS'); WRITELN ('***********************************'); FOR INDEXCH := INDEXCH TO 'Z' DO WHILE FIRSTNAME [INDEXCH] # NIL DO BEGIN LISTPTR := FIRSTNAME [INDEXCH]; WHILE LISTPTR^.LLINK # NIL DO BEGIN PRED := LISTPTR; LISTPTR := LISTPTR^.LLINK; END; IF LISTPTR = FIRSTNAME [INDEXCH] THEN FIRSTNAME [INDEXCH] := LISTPTR^.RLINK ELSE PRED^.LLINK := LISTPTR^.RLINK; IF LISTPTR^.CALLED # NIL THEN BEGIN IF FIRSTPROC = NIL THEN BEGIN FIRSTPROC := LISTPTR; LASTPROC := FIRSTPROC; LASTPROC^.CALLED^.PROCNAME := NIL; END ELSE BEGIN LASTPROC^.CALLED^.PROCNAME := LISTPTR; LASTPROC := LISTPTR; END; END; WRITELN; WRITE (LISTPTR^.NAME : 11); WRITELINENR (11); END; IF FIRSTPROC # NIL THEN BEGIN PAGE; WRITELN ('LIST OF PROCEDURE CALLS'); WRITELN ('***********************'); LASTPROC^.CALLED^.PROCNAME := NIL; LASTPROC := FIRSTPROC; WHILE LASTPROC # NIL DO BEGIN LISTPTR :=LASTPROC; WRITELN;WRITELN; WRITE (LASTPROC^.NAME:11, ' IS CALLED FROM :'); WITH LASTPROC^ DO REPEAT WRITELN; WRITE (' ' : 11,CALLEDBY^.PROCNAME^.NAME:11); LISTPTR^.FIRST := CALLEDBY^.FIRST; WRITELINENR (22); CALLEDBY := CALLEDBY^.NEXTPROC; UNTIL CALLEDBY = NIL; WRITELN; WRITELN; IF LASTPROC^.CALLED^.NEXTPROC # NIL THEN BEGIN WRITE (' ' : 11, ' AND CALLS :'); WITH LASTPROC^.CALLED^ DO REPEAT WRITELN; WRITE (' ' : 11,NEXTPROC^.PROCNAME^.NAME:11); LISTPTR^.FIRST := NEXTPROC^.FIRST; WRITELINENR (22); NEXTPROC := NEXTPROC^.NEXTPROC; UNTIL NEXTPROC = NIL; END; LASTPROC := LASTPROC^.CALLED^.PROCNAME; END; PAGE; WRITELN ('LIST OF PROCEDURE NESTINGS'); WRITELN ('**************************'); PROCSTRUCL := PROCSTRUCF; REPEAT WRITELN; WITH PROCSTRUCL^ DO WRITE (' ':PROCLEVEL*3,PROCNAME^.NAME : 11,LINENR * INCREMENT : 6 ); PROCSTRUCL := PROCSTRUCL^.NEXTPROC; UNTIL PROCSTRUCL = NIL; WRITELN; END; END; END %PRINTLISTE\ ; PROCEDURE READFILENAME; VAR LEGALCHAR : SET OF CHAR; %MENGE DER LEGALEN EINGABEZEICHEN\ MAXINDEX : INTEGER; %MAXIMALER INDEX FUER DIE FUELLUNG DES FELDES 'FILENAME'\ FUNCTION READOCTAL :INTEGER; VAR PPN : INTEGER; %HILFSVARIABLE\ BEGIN %READOCTAL\ PPN := 0; CH := ' '; WHILE (CH = ' ') AND NOT (EOLN (TTY)) DO READ (TTY,CH); IF CH IN DIGITS THEN BEGIN PPN := ORD (CH) - ORD ('0'); LOOP READ (TTY,CH); EXIT IF NOT (CH IN DIGITS); PPN := PPN*8 + ORD (CH) - ORD ('0'); END; END; READOCTAL := PPN; END %READOCTAL\ ; BEGIN %READFILENAME\ (* WITH INPUTFILE DO REPEAT FILENAME := ' PAS'; DEVICE := 'DSK '; PPN := 0; PROT := 0; OUTPUTFILE := INPUTFILE; I := 0; MAXINDEX := 6; CH := ' '; LEGALCHAR := ALPHANUM OR ['.',':','[','<','/','=']; READ (TTY,CH); IF CH = '*' THEN READ (TTY,CH); REPEAT WHILE (CH = ' ') AND NOT (EOLN (TTY)) DO READ (TTY,CH); IF CH IN LEGALCHAR THEN IF CH IN ALPHANUM THEN BEGIN LOOP I := I + 1; IF (I <= MAXINDEX) AND (CH IN ALPHANUM) THEN FILENAME [I] := CH; EXIT IF EOLN (TTY) OR NOT (CH IN ALPHANUM); READ (TTY,CH); END; LEGALCHAR := LEGALCHAR - ALPHANUM - ['>',']']; END ELSE CASE CH OF '.' : BEGIN FOR I := 7 TO 9 DO FILENAME [I] := ' '; I := 6; MAXINDEX := 9; CH := ' '; LEGALCHAR := LEGALCHAR OR ALPHANUM - ['>',']',':','.']; END; ':' : BEGIN FOR I := 1 TO 6 DO DEVICE [I] := FILENAME [I]; CH := ' '; LEGALCHAR := LEGALCHAR OR ALPHANUM - ['>',']',':']; I := 0; END; '<' : BEGIN PROT := READOCTAL; LEGALCHAR := LEGALCHAR OR ['>'] - ['<',']',':']; END; '>' : BEGIN LEGALCHAR := LEGALCHAR - ['>']; CH := ' '; END; '[' : BEGIN PPN := READOCTAL * 1000000B; LEGALCHAR := LEGALCHAR OR [']',','] - ['[','>',':']; END; ',' : BEGIN PPN := READOCTAL + PPN; LEGALCHAR := LEGALCHAR - [',']; END; ']' : BEGIN LEGALCHAR := LEGALCHAR - [']']; CH := ' '; END; '/' : READ (TTY, INCREMENT); '=' : BEGIN OUTPUTFILE := INPUTFILE; FILENAME := ' PAS'; DEVICE := 'DSK '; PPN := 0; MAXINDEX := 6; PROT := 0; I := 0; CH := ' '; LEGALCHAR := LEGALCHAR OR ALPHANUM OR ['.',':','[','<']- ['=']; END END ELSE BEGIN WRITELN (TTY,CH,' ?'); BREAK; WHILE NOT (EOLN(TTY)) DO READ (TTY,CH); END; UNTIL EOLN (TTY); UNTIL CH # '*'; WITH OUTPUTFILE DO IF FILENAME = ' PAS' THEN BEGIN FILENAME := INPUTFILE.FILENAME; FILENAME [7] := 'N'; FILENAME [8] := 'E'; FILENAME [9] := 'W'; END; *) PIX := 0; I := 1; INPUTFILE.FILENAME := ' '; WITH INPUTFILE DO WHILE NOT EOLN(TTY) DO BEGIN READ(TTY,CH); IF CH = '.' THEN PIX:=I; FILENAME[I]:=CH; I := I + 1; END; IF PIX = 0 THEN PIX := I; OUTPUTFILE.FILENAME := INPUTFILE.FILENAME; FOR I:=0 TO 3 DO OUTPUTFILE.FILENAME[PIX+I] := NUE[I]; IF INPUTFILE.FILENAME[PIX]=' ' THEN FOR I:=0 TO 3 DO INPUTFILE.FILENAME[PIX+I] := PAS[I]; END %READFILENAME\ ; BEGIN %MAIN\ INIT; WRITE (TTY,'FILE: '); BREAK; WITH INPUTFILE DO LOOP READLN (TTY); IF EOF(TTY) THEN GOTO 99; READFILENAME; RESET (INPUT,FILENAME); EXIT IF NOT (EOF (INPUT)); WRITELN (TTY); WRITE(TTY,FILENAME ); WRITELN (TTY,' NOT FOUND'); WRITE (TTY,'GIVE NEW FILE: '); BREAK; END; WRITELN (TTY); WRITELN (TTY,VERSION); WRITELN (TTY); BREAK; MAXINC := 29999 DIV INCREMENT ; WITH OUTPUTFILE DO BEGIN REWRITE (NEWFIL,FILENAME); FOR I:=0 TO 3 DO FILENAME[PIX+I] := CRL[I]; REWRITE (OUTPUT,FILENAME,,,[6]); END; CH := ' '; DATUM; HEADER; BLOCK; WRITELINE (BUFFLEN+2); IF NOT ERRFLAG THEN WRITE (TTY,'NO '); WRITELN (TTY,MESSAGE); PRINTLISTE; 99: WRITELN; END %MAIN\ .