|
|
DataMuseum.dkPresents historical artifacts from the history of: RC4000/8000/9000 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC4000/8000/9000 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 36864 (0x9000)
Types: TextFile
Names: »indentpas«
└─⟦621cfb9a2⟧ Bits:30002817 RC8000 Dump tape fra HCØ. Detaljer om "HC8000" projekt.
└─⟦0364f57e3⟧
└─⟦this⟧ »indentpas«
└─⟦00964e8f7⟧ Bits:30007478 RC8000 Dump tape fra HCØ.
└─⟦b2ec5d50f⟧
└─⟦this⟧ »indentpas«
program indent(input,output);
(* version 9/10/79 *)
LABEL 10;
CONST
blank=' ';
lsize=240; (* LONGEST LINE*)
ssize= 90; (* DEEPEST STACK LOAD*)
ksize= 51; (* ENTIRE NO OF KEYWORDS*)
TYPE
stackelement= RECORD
prior,indent:integer
END;
tablelement = RECORD
string:alfa;
p1,p2,spacing:integer
END;
VAR
alfanum:SET OF char; (*HOLDS SET OF ALPHANUMERIC SYMBOLS *)
tsize:integer; (* NO OF INTERESTING KEYWORDS *)
line:ARRAYÆ1..lsizeÅ OF char; (* LINE LEFT JUSTIFIED*)
pos:integer; (* POINTER TO CURRENT CHARACTER*)
lastpos:integer; (* LAST POSITION ON CURRENT LINE*)
linepos:integer; (* POINTER TO LAST USED PRINTPOS*)
localline, (* pascal-program-local-line-numbers *)
lineno :integer; (* LINE NUMBER OF CURRENT LINE *)
current,ch:char; (* CH IS FIRST CHAR ON NEXT LINE*)
fresh:boolean; (* LINE READ,NOT YET PRINTED*)
margin:integer; (* HANDLES INDENTION*)
oldpos:integer; (* USED TO HOLD POSITIONS IN RECORDS*)
state: (declare,statement);
skipmode, finismode, procdecl, longlines, specifier, myind,eolmade,nolab,firstid,labelline,
noind, noapo, nowarn,autoeol, skipcomment,skiptext,endmode,fewends,msgmade:boolean;
pl11mode,linesmode,pasmode,markmode:boolean;
idmode:(nochange,lowercase,uppercase);(*CHANGE PASCAL-IDENTIFIERS
TO LC OR UC, AND KEYWORDS TO UC*)
outputfile,
skiptekst:boolean; (*USED IN SHIFTCASE*)
skipchar:char; (*USED IN SHIFTCASE *)
markstack:ARRAYÆ-10..lsizeÅ OF integer;
markpointer,nextmark:integer;
stack:ARRAYÆ0..ssizeÅ OF stackelement;
top:integer; (* STACK POINTER*)
stacktop:stackelement; (* HOLDS STACKÆTOPÅ*)
table:ARRAYÆ1..23Å OF tablelement;
(* ACTUALLY THIS BOUND OF 23 IS "TSIZE" *)
keyword: ARRAYÆ1..ksizeÅ OF alfa;
keynum:ARRAYÆ1..13Å OF integer;
eol:char;
value
alfanum=Æ'0'..'9','A'..'Z','_'Å;
linepos=0;
lineno=1;
localline = -1;
noind=false; noapo=true; nowarn=true; fewends=false;
autoeol=false; skipcomment=false; skiptext=false;
myind=false; eolmade=false; nolab=false; endmode=false;
outputfile=false;
skiptekst=false;
pl11mode=false;
linesmode=false;
pasmode=true;
markmode=false;
idmode=nochange;
skipmode=false; finismode=false; procdecl=false;
specifier=false;
longlines=false; msgmade=false;
markpointer=0;
top = 1;
PROCEDURE algolinit;
BEGIN
margin:=1;
tsize:=23;
stackÆ0Å.prior :=10; (*BOTTOM NEVER UNSTACKED*);
stackÆ0Å.indent :=0;
stackÆ1Å.prior :=4;
stackÆ1Å.indent :=2; (*START WITH THE SAME AS BEGIN*);
(* KEYWORD P1 P2 INDENT*)
; tableÆ1Å.string:='BEGIN '; tableÆ1Å.p1:=2; tableÆ1Å.p2:=4; tableÆ1Å.spacing:=2;
; tableÆ2Å.string:='CLASS '; tableÆ2Å.p1:=0; tableÆ2Å.p2:=1; tableÆ2Å.spacing:=3;
tableÆ3Å.string:='CLOSE '; tableÆ3Å.p1:=5; tableÆ3Å.p2:=0; tableÆ3Å.spacing:=0;
; tableÆ4Å.string:='COMMENT '; tableÆ4Å.p1:=0; tableÆ4Å.p2:=0; tableÆ4Å.spacing:=4;
; tableÆ5Å.string:='ELSE '; tableÆ5Å.p1:=6; tableÆ5Å.p2:=5; tableÆ5Å.spacing:=1;
; tableÆ6Å.string:='END '; tableÆ6Å.p1:=5; tableÆ6Å.p2:=0; tableÆ6Å.spacing:=0;
; tableÆ7Å.string:='IF '; tableÆ7Å.p1:=0; tableÆ7Å.p2:=5; tableÆ7Å.spacing:=1;
tableÆ8Å.string:='OPEN '; tableÆ8Å.p1:=2; tableÆ8Å.p2:=4; tableÆ8Å.spacing:=2;
; tableÆ9Å.string:='OTHERWISE '; tableÆ9Å.p1:=6; tableÆ9Å.p2:=5; tableÆ9Å.spacing:=1;
; tableÆ10Å.string:='PROCEDURE '; tableÆ10Å.p1:=0; tableÆ10Å.p2:=1; tableÆ10Å.spacing:=2;
; tableÆ11Å.string:='WHEN '; tableÆ11Å.p1:=0; tableÆ11Å.p2:=5; tableÆ11Å.spacing:=1;
; tableÆ12Å.string:='"BEGIN '; tableÆ12Å.p1:=2; tableÆ12Å.p2:=4; tableÆ12Å.spacing:=2;
; tableÆ13Å.string:='"CLASS '; tableÆ13Å.p1:=0; tableÆ13Å.p2:=1; tableÆ13Å.spacing:=3;
tableÆ14Å.string:='"CLOSE '; tableÆ14Å.p1:=5; tableÆ14Å.p2:=0; tableÆ14Å.spacing:=0;
; tableÆ15Å.string:='"COMMENT '; tableÆ15Å.p1:=0; tableÆ15Å.p2:=0; tableÆ15Å.spacing:=4;
; tableÆ16Å.string:='"ELSE '; tableÆ16Å.p1:=6; tableÆ16Å.p2:=5; tableÆ16Å.spacing:=1;
; tableÆ17Å.string:='"END '; tableÆ17Å.p1:=5; tableÆ17Å.p2:=0; tableÆ17Å.spacing:=0;
; tableÆ18Å.string:='"IF '; tableÆ18Å.p1:=0; tableÆ18Å.p2:=5; tableÆ18Å.spacing:=1;
tableÆ19Å.string:='"OPEN '; tableÆ19Å.p1:=2; tableÆ19Å.p2:=4; tableÆ19Å.spacing:=2;
; tableÆ20Å.string:='"OTHERWISE'; tableÆ20Å.p1:=6; tableÆ20Å.p2:=5; tableÆ20Å.spacing:=1;
; tableÆ21Å.string:='"PROCEDURE'; tableÆ21Å.p1:=0; tableÆ21Å.p2:=1; tableÆ21Å.spacing:=2;
; tableÆ22Å.string:='"WHEN '; tableÆ22Å.p1:=0; tableÆ22Å.p2:=5; tableÆ22Å.spacing:=1;
; tableÆ23Å.string:='"ZZZZ '; tableÆ23Å.p1:=0; tableÆ23Å.p2:=0; tableÆ23Å.spacing:=0;
keywordÆ1Å:='ACTIVATE '; keywordÆ2Å:='AFTER ';
keywordÆ3Å:='ARRAY '; keywordÆ4Å:='AT ';
keywordÆ5Å:='BEFORE '; keywordÆ6Å:='BEGIN ';
keywordÆ7Å:='BOOLEAN '; keywordÆ8Å:='CHARACTER '; keywordÆ9Å:='CLASS ';
keywordÆ10Å:='CODE '; keywordÆ11Å:='CLOSE '; keywordÆ12Å:='COMMENT ';
keywordÆ13Å:='DELAY '; keywordÆ14Å:='DO ';
keywordÆ15Å:='ELSE '; keywordÆ16Å:='END ';
keywordÆ17Å:='FALSE '; keywordÆ18Å:='FOR ';
keywordÆ19Å:='GOTO '; keywordÆ20Å:='IF ';
keywordÆ21Å:='IN '; keywordÆ22Å:='INNER ';
keywordÆ23Å:='INSPECT '; keywordÆ24Å:='INTEGER ';
keywordÆ25Å:='IS '; keywordÆ26Å:='LABEL ';
keywordÆ27Å:='NAME '; keywordÆ28Å:='NEW ';
keywordÆ29Å:='NONE '; keywordÆ30Å:='NOTEXT ';
keywordÆ31Å:='OPEN ';
keywordÆ32Å:='OTHERWISE '; keywordÆ33Å:='PRIOR ';
keywordÆ34Å:='PROCEDURE '; keywordÆ35Å:='QUA ';
keywordÆ36Å:='REACTIVATE'; keywordÆ37Å:='REAL ';
keywordÆ38Å:='REF '; keywordÆ39Å:='STEP ';
keywordÆ40Å:='STRING ';
keywordÆ41Å:='SWITCH '; keywordÆ42Å:='TEXT ';
keywordÆ43Å:='THEN '; keywordÆ44Å:='THIS ';
keywordÆ45Å:='TRUE '; keywordÆ46Å:='UNTIL ';
keywordÆ47Å:='VALUE '; keywordÆ48Å:='VIRTUAL ';
keywordÆ49Å:='WHEN '; keywordÆ50Å:='WHILE ';
keywordÆ51Å:='ZZZZ ';
END; (*INITIALISER*)
PROCEDURE initialiser;
CONST
length1=17;
length2=44;
VAR
i,j:integer;
pascaltable : ARRAYÆ1..length1Å OF tablelement;
pascalkeys:ARRAYÆ1..length2Å OF alfa;
value
pascaltable=(('BEGIN ',4,4,2),
('CASE ',0,4,3),
('CONST ',3,2,2),
('ELSE ',6,5,1),
('END ',5,0,0),
('FORWARD ',4,0,0),
('FUNCTION ',0,2,2),
('IF ',0,5,1),
('LABEL ',3,2,2),
('PROCEDURE ',0,2,2),
('PROGRAM ',3,2,2),
('RECORD ',0,2,3),
('REPEAT ',0,4,2),
('TYPE ',3,2,2),
('UNTIL ',5,0,0),
('VALUE ',3,2,2),
('VAR ',3,2,2));
pascalkeys= ('IF ', 'DO ', 'OF ', 'TO ', 'IN ',
'OR ', 'END ', 'FOR ', 'VAR ', 'NIL ',
'DIV ', 'MOD ', 'SET ', 'AND ', 'NOT ',
'THEN ', 'ELSE ', 'WITH ', 'GOTO ', 'CASE ',
'TYPE ', 'FILE ', 'BEGIN ', 'UNTIL ', 'WHILE ',
'ARRAY ', 'CONST ', 'LABEL ', 'VALUE ', 'REPEAT ',
'PASCAL ', 'RECORD ', 'DOWNTO ', 'PACKED ', 'RANDOM ',
'MODULE ', 'FORTRAN ', 'FORWARD ', 'PROGRAM ', 'FUNCTION ',
'EXTERNAL ', 'PROCEDURE ', 'OTHERWISE ', ' ');
BEGIN
keynumÆ1Å := 1; keynumÆ2Å := 1; keynumÆ3Å := 7; keynumÆ4Å := 16; keynumÆ5Å := 23;
keynumÆ6Å := 30; keynumÆ7Å := 37; keynumÆ8Å := 40; keynumÆ9Å := 42; keynumÆ10Å := 44;
keynumÆ11Å := 44; keynumÆ12Å := 44; keynumÆ13Å := 44;
FOR i:=1 TO length1 DO tableÆiÅ:=pascaltableÆiÅ;
IF idmode>nochange THEN
FOR i:=1 TO length2 DO keywordÆiÅ:=pascalkeysÆiÅ;
tsize:=length1;
margin:=3;
FOR i:=1 TO lsize DO lineÆiÅ:=blank;
stackÆ0Å.prior:=10; (* bottom never unstack *)
stackÆ0Å.indent:=0;
stackÆ1Å.indent:=2;
stackÆ1Å.prior:=2;
stacktop:=stackÆ1Å;
END;
PROCEDURE fileid;
CONST
power12 = 4096;
equality = 6;
point = 8;
VAR
i,j,int,paramno : integer;
error : boolean;
id : alfa;
BEGIN
paramno := 1;
error := false;
i:=system(paramno,int,id);
IF i DIV power12 = equality THEN
BEGIN (* get outputfile *)
i:=system(0,int,id);
IF i MOD power12 = 10 THEN
BEGIN
outputfile:=true;
open(output,id);
rewrite(output);
END
ELSE
BEGIN
writeln(' ??? illegal output-filename');
GOTO 10;
END;
paramno:=paramno + 1;
END;
(* get input file *)
i:=system(paramno,int,id);
IF i MOD power12 = 10 THEN
if (id='h') or (id='help') then paramno := paramno-1 (* not error *)
else
BEGIN
open(input,id);
reset(input);
END
ELSE
BEGIN
IF outputfile THEN close(output);
writeln(' ??? illegal input-filename');
GOTO 10;
END;
paramno:=paramno+1;
j:=system(paramno,int,id);
WHILE j <>0 DO
BEGIN
IF j MOD power12 <> 10 THEN error:=true
ELSE
BEGIN
IF j DIV power12 = point THEN error:=true;
i:=alfalength;
IF ((id='h ')
or (id='help ')) then
BEGIN (* HELP INFORMATION *);
writeln(output,'HELP INFORMATION:');
writeln(output,'SWITCHES AVAILABLE ARE:');
writeln(output,' NOIND NO INDENTION IS PERFORMED');
writeln(output,' WARN WARNING IF LINE LONGER THAN 72 CHARACTERS');
writeln(output,' MYIND INDENTION IS NOT TOUCHED');
writeln(output,' NOLAB LABELS ARE NOT LEFT JUSTIFIED');
writeln(output,' LINES LINE NUMBERS ARE GENERATED');
writeln(output,' PL11 PL11 SYNTAX ASSUMED');
writeln(output,' ALGOL ALGOL SYNTAX ASSUMED');
writeln(output,' LC GENERATE LC IDENTIFIERS AND UC PASCAL-KEYWORDS');
writeln(output,' UC GENERATE UC IDENTIFIERS AND PASCAL-KEYWORDS');
writeln(output,' MARK MARK BEGIN-END MATCHING');
writeln(output,' LIST EQUIVALENT TO LINES MARK ');
writeln(output);
writeln(output,'DEFAULT SYNTAX IS PASCAL');
writeln(output);
END;
IF id='algol ' THEN
BEGIN
pasmode:=false;
pl11mode:=false;
END
ELSE IF id='pl11 ' THEN pl11mode:=true
ELSE IF id='warn ' THEN nowarn:=false
ELSE IF id='myind ' THEN myind:=true
ELSE IF id='noind ' THEN noind:=true
ELSE IF id='lc ' THEN idmode:=lowercase
ELSE IF id='uc ' THEN idmode:=uppercase
ELSE IF id='autoeol ' THEN autoeol:=true
ELSE IF id='lines ' THEN linesmode:=true
ELSE IF id='mark ' THEN markmode:=true
ELSE IF id='list ' THEN
BEGIN
linesmode:=true;
markmode:=true;
END
ELSE IF id='nolab ' THEN nolab:=true
ELSE IF id='apo ' THEN noapo:=false
ELSE error:=true;
END;
paramno := paramno + 1;
j := system(paramno,int,id);
END;
IF pasmode THEN initialiser
ELSE
BEGIN
idmode:=nochange;
algolinit;
END;
IF error THEN
BEGIN
writeln(output,'call: "indent help", for help ');
close(input);
GOTO 10;
END;
END;
PROCEDURE writeeol;
BEGIN linepos:=linepos+1;
IF (linepos>73) AND (nowarn=false) THEN
BEGIN writeln;
writeln(' ***** THIS LINE CONTAINED MORE THAN 72 CHARACTERS POS 72 ^ ');
longlines:=true
END;
writeln;
linepos:=0
END;
PROCEDURE write1(ch:char);
VAR k:integer;
BEGIN linepos:=linepos+1;
IF (linepos>72) AND autoeol THEN
BEGIN
writeln;
linepos:=0; eolmade:=true
END;
write(ch)
END; (*WRITE1*)
PROCEDURE pushmark(pos:integer);
BEGIN IF markpointer<lsize THEN
markpointer:=markpointer+1;
markstackÆmarkpointerÅ:=pos;
END;
PROCEDURE popmark;
BEGIN markstackÆmarkpointerÅ:=0;
IF markpointer>0 THEN
markpointer:=markpointer-1;
END;
PROCEDURE printline; FORWARD;
PROCEDURE semicolon; FORWARD;
PROCEDURE skip(skipend:char); FORWARD;
PROCEDURE algidentifier;
(* CHECKS IF IDENTIFIER IS A KEYWORD WITH EFFECT
ON INDENTION. IF SO, INDENTION IS ADJUSTED*)
VAR a:ARRAYÆ0..alfalengthÅ OF char; key:alfa;
k,hi,lo,try:integer;
FUNCTION endorelse(a:integer): boolean;
BEGIN endorelse:=(key='END ') OR (key='"END ') OR
(key='ELSE ') OR (key='"ELSE ')
END;
BEGIN
k:=0;
REPEAT
IF (k<alfalength) AND (current <> '.') THEN
BEGIN
aÆkÅ:=current;
k:=k+1;
END;
pos:=pos+1; current:=lineÆposÅ;
UNTIL NOT (current IN (alfanum + Æ'.'Å)) ;
IF (current=':') AND NOT (lineÆpos+1Å IN Æ'=','-'Å) THEN
labelline:=firstid AND NOT (nolab OR skipcomment OR skiptext OR skipmode);
IF k IN Æ2..alfalengthÅ THEN
BEGIN (* MIGHT BE INTERESTING KEYWORD*)
FOR k:=k TO alfalength-1 DO aÆkÅ:=blank;
pack(a,0,key);
lo:=1; hi:=tsize;
REPEAT try:=(lo+hi)DIV 2;
WITH tableÆtryÅ DO
BEGIN IF key>=string THEN lo:=try+1;
IF key<=string THEN hi:=try-1;
END;
UNTIL lo>hi;
IF (endmode=false) OR endorelse(k) THEN
WITH tableÆtryÅDO
BEGIN
IF (string=key) AND NOT (procdecl) OR (key='COMMENT ') OR (key='"COMMENT ')THEN
WITH stacktop DO
BEGIN (* KEYWORD AFFECTING MARGIN IS FOUND *)
IF(string='END ') OR (string='"END ') THEN semicolon;
(* SEE IF UNSTACKING*)
IF prior<p1 THEN
BEGIN
margin:=margin-indent;
top:=top-1; stacktop:=stackÆtopÅ;
END;
IF fresh THEN printline;
(* SEE IF STACKING*)
IF (p2>0) AND ((prior<>1) OR (p2<>1)) THEN
BEGIN IF p2=1 THEN
BEGIN
procdecl:=true;
specifier:=true
END;
IF top<ssize THEN top:=top+1;
prior:=p2; indent:=spacing;
margin:=margin+indent;
stackÆtopÅ:=stacktop
END;
IF (string='PROCEDURE ') OR (string='"PROCEDURE')
OR (string='CLASS ') OR (string='"CLASS ') THEN
BEGIN IF procdecl THEN specifier:=true;
skip(';')
END
ELSE IF (string='COMMENT ') OR (string='"COMMENT ') THEN
BEGIN margin:=margin+2;
IF procdecl THEN specifier:=true;
skipmode:=true;
skip(';');
margin:=margin-2
END
END (* TAKING CARE OF INTERESTING KEYWORDS*) ELSE
IF (stacktop.prior = 1) THEN (* MAYBE PROC- OR CLASS-
DECLARATION*)
BEGIN
IF procdecl THEN
IF (key='INTEGER ') OR (key='"INTEGER ')
OR (key='BOOLEAN ') OR (key='"BOOLEAN ')
OR (key='REAL ') OR (key='"REAL ')
OR (key='PROCEDURE ') OR (key='"PROCEDURE')
OR (key='CHARACTER ') OR (key='"CHARACTER')
OR (key='VALUE ') OR (key='"VALUE ')
OR (key='REF ') OR (key='"REF ')
OR (key='NAME ') OR (key='"NAME ')
OR (key='ARRAY ') OR (key='"ARRAY ')
OR (key='LABEL ') OR (key='"LABEL ')
OR (key='TEXT ') OR (key='"TEXT ')
OR (key='STRING ') OR (key='"STRING ')
OR (key='SWITCH ') OR (key='"SWITCH ')
OR (key='VIRTUAL ') OR (key='"VIRTUAL ')
THEN BEGIN
specifier:=true; skip(';');
END ELSE
(* NOW WE SHOULD BE RIGHT BEFORE THE
PROCEDURE- OR CLASS-BODY. WE THEN START
LOOKING FOR SINGLE OR COMPOUND STATEMENT*)
IF (key<>'BEGIN ') AND (key<>'"BEGIN ') THEN
BEGIN (* SINGLE OR EMPTY STATEMENT*)
specifier:=false; procdecl:=false;
top:=top-1;
margin:=margin-stacktop.indent;
stacktop:=stackÆtopÅ;
IF fresh THEN printline;
IF (key='IF ') OR (key='"IF ') THEN
BEGIN (*IF IS STACKED*)
top:=top+1; stacktop.prior:=p2;
stacktop.indent:=spacing;
margin:=margin+stacktop.indent;
stackÆtopÅ:=stacktop
END
END
ELSE
BEGIN procdecl:=false;
specifier:=false;
(*BEGIN IS STACKED*)
margin:=margin - stacktop.indent;
IF fresh THEN printline;
stacktop.indent:=spacing;
stacktop.prior:=p2;
margin:=margin+stacktop.indent;
stackÆtopÅ:=stacktop
END; IF fresh THEN printline
END
END;
IF markmode THEN
BEGIN
IF key='BEGIN ' THEN pushmark(margin-1)
ELSE IF key='END ' THEN popmark;
END;
END (* K IN Æ2..alfalengthÅ *)
END (* IDENTIFIER*);
PROCEDURE apostrophes;
VAR pos,pos1,k,hi,lo,try :integer;
current:char;
key:alfa;
a:ARRAYÆ0..alfalengthÅ OF char;
BEGIN (*CHECK/ADD APOSTROPHES*)
pos:=1;
IF (lastpos<>0) AND labelline THEN
BEGIN pos:=0; write1(blank);
REPEAT
pos:=pos+1;
write1(lineÆposÅ)
UNTIL lineÆposÅ=':';
FOR k:=pos+2 TO margin DO write1(blank);
REPEAT pos:=pos+1 UNTIL lineÆposÅ<>blank;
END;
current:=lineÆposÅ;
IF lastpos<>0 THEN
REPEAT
IF (current IN Æ'A'..'Z'Å) AND (pos<>lastpos) THEN
BEGIN (*IDENTIFIER*)
k:=0; pos1:=pos;
REPEAT IF k<alfalength THEN
BEGIN aÆkÅ:=current; k:=k+1; END;
pos1:=pos1+1;
current:=lineÆpos1Å
UNTIL NOT (current IN alfanum);
IF k<=alfalength THEN
BEGIN (*MIGHT BE KEYWORD*)
FOR k:=k TO alfalength-1 DO aÆkÅ:=blank;
pack(a,0,key);
lo:=1; hi:=ksize;
REPEAT try:=(lo+hi) DIV 2;
IF key>=keywordÆtryÅ THEN lo:=try+1;
IF key<=keywordÆtryÅ THEN hi:=try-1;
UNTIL lo>hi;
IF (key='END ') OR (key='"END ') OR (key='ELSE ') OR
(key='"ELSE ') THEN endmode:=false;
IF (keywordÆtryÅ=key) AND NOT (skiptext OR skipcomment OR endmode) THEN
BEGIN (*KEYWORD*)
IF pos<>1 THEN
IF lineÆpos-1Å='"' THEN
BEGIN
FOR pos:=pos TO (pos1-1) DO write1(lineÆposÅ);
pos:=pos1; IF lineÆpos1Å<>'"' THEN write1('"');
IF pos>=lastpos THEN writeeol;
END
ELSE
BEGIN write1('"');
FOR pos:=pos TO (pos1-1) DO write1(lineÆposÅ);
IF lineÆpos1Å<>'"' THEN write1('"'); pos:=pos1;
IF pos>=lastpos THEN writeeol;
END
ELSE
BEGIN write1('"');
FOR pos:=pos TO (pos1-1) DO write1(lineÆposÅ);
IF lineÆpos1Å<>'"' THEN write1('"'); pos:=pos1;
IF pos>=lastpos THEN writeeol;
END;
IF (key='COMMENT ') OR (key='"COMMENT ') THEN skipcomment:=true;
IF (key='END ') OR (key='"END ') THEN endmode:=true
END (*KEYWORD*)
ELSE
BEGIN
FOR pos:=pos TO (pos1-1) DO write1(lineÆposÅ);
pos:=pos1;
IF pos>=lastpos THEN writeeol;
END
END (*MIGHT BE KEYWORD*)
ELSE
BEGIN (*NOT KEYWORD*)
FOR pos:=pos TO (pos1-1) DO write1(lineÆposÅ);
pos:=pos1; IF pos>=lastpos THEN writeeol;
END (*KEYWORD*)
END (*IDENTIFIER*)
ELSE IF pos>=lastpos THEN writeeol
ELSE
BEGIN pos:=pos+1;
write1(current);
IF (current=';') AND endmode THEN endmode:=false;
IF (current=';') AND skipcomment THEN skipcomment:=false
ELSE IF current='"' THEN skiptext:= NOT (skiptext);
current:=lineÆposÅ;
IF pos>=lastpos THEN writeeol;
END
UNTIL (pos>=lastpos) OR (pos1>=lastpos)
ELSE writeeol
END; (*CHECK/ADD APOSTROPHES*)
FUNCTION resword(length:integer;name:alfa):boolean;
VAR
i:integer;
res:boolean;
BEGIN
res:=false;
i:=keynumÆlengthÅ;
length:=keynumÆlength+1Å;
REPEAT
IF keywordÆiÅ=name THEN res:=true;
i:=i+1;
UNTIL(i>=length) OR res;
resword:=res;
END;
PROCEDURE changeletters(lowercase:boolean;pos:integer);
VAR
i,add:integer;
ch,a,z:char;
BEGIN
IF lowercase THEN
BEGIN
add:=32;
a:='A';
z:='Z';
END
ELSE
BEGIN
add:=-32;
a:='a';
z:='z';
END;
i:=pos;
REPEAT
ch:=lineÆiÅ;
IF (ch>=a) AND (ch<=z) THEN lineÆiÅ:=chr(ord(ch)+add);
i:=i-1;
UNTIL NOT((ch IN alfanum) OR ((ch>='a') AND (ch<='z'))) OR (i=0);
END;
PROCEDURE shiftcase;
(*CHANGE IDENTIFIERS TO LC OR UC AND KEYWORDS TO UC *)
VAR
k,pos:integer;
key:alfa;
current:char;
BEGIN
pos:=1;
current:=lineÆposÅ;
WHILE pos<=lastpos DO
BEGIN
IF skiptekst THEN
BEGIN
IF current=skipchar THEN
BEGIN
IF ((skipchar='*') AND (lineÆpos+1Å=')')) OR (skipchar<>'*') THEN
skiptekst:=false;
END;
END
ELSE
BEGIN
IF (current>='a') AND (current<='z') THEN current:=chr(ord(current)-32);
CASE current OF
'A','B','C','D','E','F','G','H','I','J',
'K','L','M','N','O','P','Q','R','S','T',
'U','V','W','X','Y','Z':
BEGIN
k:=1;
key:=' ';
REPEAT (*PICK UP IDENTIFIER *)
IF k<=alfalength THEN
BEGIN
keyÆkÅ:=current;
k:=k+1;
END;
pos:=pos+1;
current:=lineÆposÅ;
IF (current>='a') AND (current<='z') THEN current:=chr(ord(current)-32);
UNTIL NOT (current IN alfanum);
pos:=pos-1;
IF resword(k-1,key) THEN changeletters(true,pos)
ELSE changeletters(idmode=lowercase,pos);
END;
'0','1','2','3','4',
'5','6','7','8','9':
BEGIN
REPEAT pos:=pos+1 UNTIL NOT (lineÆposÅ IN Æ'0'..'9'Å);
IF lineÆposÅ='(' THEN pos:=pos-1;(*MIGHT BE START OF COMMENT *)
END;
'(':
IF lineÆpos+1Å='*' THEN
BEGIN
skiptekst:=true;
skipchar:='*';
pos:=pos+1;
END;
'''':
BEGIN
skiptekst:=true;
skipchar:='''';
END;
END
otherwise;
END;
pos:=pos+1;
current:=lineÆposÅ;
END;
END;
PROCEDURE pushindent(prioritet,indention:integer);
(*STACK ONE LEVEL OF INDENTION *)
BEGIN
WITH stacktop DO
BEGIN
IF top<ssize THEN top:=top+1;
prior:=prioritet;
indent:=indention-oldpos;
oldpos:=pos;
margin:=margin+indent;
stackÆtopÅ:=stacktop;
END;
END;
PROCEDURE popindent;
(*REMOVE ONE LEVEL OF INDENTION FROM STACK*)
BEGIN
IF top>0 THEN top:=top-1;
margin:=margin-stacktop.indent;
IF oldpos>0 THEN oldpos:=oldpos-stacktop.indent;
stacktop:=stackÆtopÅ;
END;
PROCEDURE pasidentifier;
(* CHECKS IF IDENTIFIER IS A KEYWORD WITH EFFECT
ON INDENTION. IF SO, INDENTION IS ADJUSTED*)
VAR a:ARRAYÆ0..alfalengthÅ OF char; key:alfa;
k,hi,lo,try:integer;
BEGIN
IF current IN Æ'B','C','E','F','I','L','P','R','T','U','V'Å
THEN k:=0 ELSE k:=11;
REPEAT
IF k<alfalength THEN BEGIN aÆkÅ:=current; k:=k+1 END;
pos:=pos+1; current:=lineÆposÅ;
IF (current>='a') AND (current<='z') THEN current:=chr(ord(current)-32);
UNTIL NOT(current IN alfanum) ;
IF k IN Æ2..alfalengthÅ THEN
BEGIN (* MIGHT BE INTERESTING KEYWORD*)
FOR k:=k TO alfalength-1 DO aÆkÅ:=blank;
pack(a,0,key);
lo:=1; hi:=tsize;
REPEAT try:=(lo+hi)DIV 2;
WITH tableÆtryÅ DO
BEGIN IF key>=string THEN lo:=try+1;
IF key<=string THEN hi:=try-1;
END;
UNTIL lo>hi;
WITH tableÆtryÅDO
IF string=key THEN
WITH stacktop DO
BEGIN (* KEYWORD AFFECTING MARGIN IS FOUND *)
IF(string='END ')OR(string='UNTIL ')THEN semicolon
ELSE IF (string='TYPE ') OR (string='VAR ') THEN state:=declare
ELSE IF string='BEGIN ' THEN state:= statement;
(* SEE IF UNSTACKING*)
IF prior<p1 THEN
BEGIN
IF (string='END ') AND (state=declare) THEN
BEGIN (*SPECIAL HANDLING OF RECORD *)
margin:=margin-3;
IF fresh THEN printline;
margin:=margin+3;
IF oldpos>0 THEN oldpos:=oldpos-indent;
END;
margin:=margin-indent;
top:=top-1; stacktop:=stackÆtopÅ;
END;
IF fresh THEN printline;
(* SEE IF STACKING*)
IF p2>0 THEN
IF (string='CASE ') AND (state=declare) THEN
BEGIN margin:=margin+spacing; indent:=indent+spacing;
stackÆtopÅ:=stacktop;
END
ELSE
BEGIN
IF top<ssize THEN top:=top+1;
prior:=p2;
IF string='RECORD ' THEN
BEGIN
indent:=spacing+pos-7-oldpos;
oldpos:=spacing+pos-7;
END ELSE indent:=spacing;
margin:=margin+indent;
stackÆtopÅ:=stacktop
END;
IF (string='FUNCTION ')OR(string='PROCEDURE ') THEN skip(';')
ELSE
IF string='END ' THEN
IF current= '.' THEN
WHILE NOT eof(input) DO
IF eoln(input) THEN
BEGIN
writeln;
readln;
end
else
begin
read(ch);
write(ch);
END;
END (* TAKING CARE OF INTERESTING KEYWORDS*);
IF markmode THEN
BEGIN IF (key='BEGIN ') OR (key='REPEAT ') THEN
pushmark(margin-1)
ELSE IF ((key='CASE ') AND (state=statement)) OR (key='RECORD ')
THEN pushmark(margin-2)
ELSE IF (key='END ') OR (key='UNTIL ')
THEN popmark;
END;
END (* K IN Æ2..alfalengthÅ *)
END (* IDENTIFIER*);
PROCEDURE semicolon;
(* UNSTACK UNTIL STACKTOP DOES NOT CONTAIN IF OR ELSE*)
BEGIN
IF NOT pasmode THEN
BEGIN
IF procdecl THEN
IF specifier THEN specifier:=false
ELSE
BEGIN (*UNSTACK PROCEDURE*)
procdecl:=false;
top:=top-1;
margin:=margin-stacktop.indent;
stacktop:=stackÆtopÅ
END;
END; (* NOT PASMODE *)
WITH stacktop DO
WHILE prior=5 DO
BEGIN
margin:=margin-indent;
top:=top-1;
stacktop:=stackÆtopÅ
END
END (* SEMICOLON*);
PROCEDURE printline;
VAR pos:integer;
BEGIN
fresh:=false; (* LINE IS PRINTED*);
IF linesmode THEN
BEGIN (* PRINT LINE NUMBER *)
write(lineno:5,':');
lineno:=lineno+1;
END;
IF NOT(pl11mode AND (lineÆ1Å='Æ' )) THEN
BEGIN
IF (finismode=false) AND (noind=false) THEN write1(blank);
IF NOT ((lastpos=0) OR noind OR labelline) OR markmode THEN
(*AN EMPTY LINE IS NOT SPACED*)
BEGIN nextmark:=1;
FOR pos:=1 TO margin DO
BEGIN
IF markmode THEN
BEGIN IF pos=markstackÆnextmarkÅ THEN
begin write('!');
nextmark:=nextmark+1;
END
ELSE
write1(blank);
END
ELSE write1(blank);
END; (* markmode *)
END; (* for *)
END; (* PL11: NO INDENTION IN COMPILER OPTION LINES *)
IF ( skipmode OR finismode OR noapo) AND (lastpos<>0) THEN BEGIN
pos:=0;
REPEAT pos:=pos+1; write1(lineÆposÅ);
UNTIL pos=lastpos;
writeeol;
END
ELSE apostrophes;
END; (*PRINTLINE*)
PROCEDURE readline;
VAR pos:integer;
BEGIN
pos:=0; lastpos:=0; oldpos:=0; fresh:=true; (* LINE IS READ, NOT PRINTED*)
ch := blank;
IF myind=false THEN
WHILE (ch=blank) AND (NOT eoln(input) ) DO read(ch);
WHILE NOT eoln(input) DO
BEGIN
IF pos<lsize THEN pos:=pos+1;
lineÆposÅ:=ch;
IF ch<>blank THEN lastpos:=pos;
read(ch)
END;
IF ch<>blank THEN
BEGIN lastpos:=pos+1;
lineÆlastposÅ:=ch;
END;
lineÆlastpos+1Å:=blank;
readln;
IF idmode>nochange THEN shiftcase;
END (* READLINE*);
PROCEDURE skip;
BEGIN
IF NOT procdecl THEN skipmode:=true;
IF fresh THEN printline;
REPEAT
IF pos>=lastpos THEN
IF eof(input) THEN
BEGIN
IF skipend='"' THEN
writeln(output,'** TEXTSTRING NOT FINISHED **')
ELSE
writeln(output,' ** COMMENT NOT FINISHED. ');
END
ELSE
BEGIN readline; printline;
pos:=0;
END;
pos:=pos+1; current:=lineÆposÅ;
IF pasmode THEN
BEGIN
IF (skipend=';') AND (current='(') AND (lineÆpos+1Å<>'*') THEN
REPEAT (*SKIP PARAMETERLIST *)
skip(')');
IF pos=1 THEN pos:=2;
UNTIL lineÆpos-1Å<>'*';
END;
UNTIL current=skipend;
skipmode:=false;
skiptext:=false; skipcomment:=false
END;
(* PROGRAM*)
BEGIN
stacktop:=stackÆ1Å;
fileid;
IF markmode THEN
BEGIN FOR pos:=-1 TO lsize DO
markstackÆposÅ:=0;
END;
IF autoeol THEN nowarn:=true;
IF myind THEN noind:=true;
WHILE NOT eof(input) AND NOT finismode DO
BEGIN
readline;
labelline:=false; firstid:=true;
pos:=1; current:=lineÆposÅ;
WHILE pos<=lastpos DO
BEGIN
IF (current>='a') AND (current<='z') THEN current:=chr(ord(current)-32);
IF (current IN Æ'A'..'Z'Å) THEN
BEGIN
IF pasmode THEN pasidentifier ELSE algidentifier;
END
ELSE
BEGIN
CASE current OF
';': semicolon;
'(': IF pasmode THEN
BEGIN
IF lineÆpos+1Å='*' THEN
BEGIN
pushindent(4,pos+1);
REPEAT skip('*') UNTIL lineÆpos+1Å=')';
pos:=pos+1;
popindent;
END
ELSE
IF state=declare THEN
pushindent(4,pos); (* INDENTION OF SCALAR TYPES AND VARIANT FIELDS IN RECORDS *)
END;
')':IF pasmode THEN
BEGIN
IF state=declare THEN
BEGIN(*UNSTACK INDENTION OF SCALAR TYPES AND VARIANT PARTS IN RECORDS*)
popindent;
END;
END;
':':IF pasmode THEN
IF lineÆpos+1Å <> '=' THEN
IF state=statement THEN
BEGIN (*INDENTION OF CASELABELS *)
semicolon;(*POP PREVIOUS STACKED CASELABELS AND IFSTATEMENTS *)
pushindent(5,pos);
END;
'!': IF NOT (pl11mode OR pasmode) THEN skip(';'); (* SKIP COMMENT *)
'''': IF pl11mode OR pasmode THEN skip(''''); (*TEXT*)
'"': IF NOT(pl11mode) THEN skip('"'); (* SKIP TEXT STRING *)
'$': IF NOT(pl11mode OR pasmode) THEN pos:=pos+3;
END
otherwise; (* ALL OTHER ARE BLIND*)
pos:=pos+1; current:=lineÆposÅ;
END;
firstid:=false;
IF fresh THEN printline
END (* SCAN OF LINE*);
IF fresh THEN printline
END (* SCAN OF INPUT FILE *);
if outputfile then close(output);
IF longlines THEN
writeln(output,' ** WARNING, LINE(S) OF MORE THAN 72 CHARACTERS.');
IF fewends THEN writeln(output,' ** WARNING, END(S) MISSING.');
if eolmade then writeln(output,' ** nl(s) generated. ');
close(input);
10:;
END.
▶EOF◀