Google
 

Trailing-Edge - PDP-10 Archives - decuslib20-03 - decus/20-0078/util/simibm.sim
There is 1 other file named simibm.sim in the archive. Click here to see a list.
OPTIONS(/-Q/-A/-I/-D);
COMMENT --- SIMIBM --- Program Version 1.1
Date: 76-02-27
Author:Mats Ohlin, FOA 1, Fack, S-104 50 STOCKHOLM, SWEDEN.

The SIMIBM program converts SIMULA programs from DEC-10 to
IBM 360/370 representation.

N.B. The program to be converted MUST NOT contain line
numbers, please remove them with
.COPY = x.sim(N) before processing.

The following conversion problems must be considered
by the programmer:-

1. The use of the standard procedures Rank and Char gives
   different result on IBM.
2. The file names for IBM must contain no dot or ppn and must not
   be longer than 8 characters.
3. All OPTIONS statements are converted to COMMENTs.
   For OPTIONS(/P)  use %PAGE on a single record.
   For OPTIONS(/P:"title")  use %TITLE    title    on a single card.
4. External modules are not implemented the same way as in DEC-10 SIMULA.
   Use the SIMEXP program in order to resolve these references before
   you run SIMIBM.
5. The maximum integer value is 2^31-1 = 2 147 483 467 on IBM.
6. Concatenated text constants - "ABC"<blanks>"DEF" - as long as
   the IBM SIMULA System does not accept such constants.

See also SIMULA Language Handbook, Part 2, Chapter 4.

The SIMIBM program makes the following conversions:-

1. All lower case letters are translated to upper case.
2. Long real constants are converted according to IBM
   standard.
3. All calls to standard procedure BREAKOUTIMAGE are
   replaced with OUTIMAGE.
4. The special COMMENT symbol '!' is converted to COMMENT.
5. The exponentiation symbol '^' is converted to **.
6. All square brackets '[' ']' are converted to parenthesises ( ).
7. All lines longer than 72 characters are cut at an appropriate position.
   However, numerical constants containing blanks or tabs could
   occasionally be improperly cut.
8. The NOT symbol '\' and the NOT-EQUAL symbol '\=' are converted
   to NOT and NE respectively.
9. All TABs are converted to blank(s).

The program needs the following information from the user:-

1. The name of the file containing the program to be converted.
2. The name of the output file.
;
BEGIN

    EXTERNAL TEXT PROCEDURE rest,upcase,conc2;
    EXTERNAL LONG REAL PROCEDURE scanreal;
    EXTERNAL INTEGER PROCEDURE scanint;
    EXTERNAL CLASS safmin;

    safmin BEGIN
	Simset BEGIN
	    PROCEDURE initconvert(ca);   CHARACTER ARRAY ca;
	    BEGIN   INTEGER i;
		FOR i:=  0 STEP 1 UNTIL 31 DO ca[i]:= ' ';
		FOR i:= 32 STEP 1 UNTIL 95 DO ca[i]:= Char(i);
		FOR i:= 96 STEP 1 UNTIL 122 DO ca[i]:= ca[i-32];

		ca[123]:= ca[35];   ca[124]:= Char(124);   ca[125]:= ca[36]

	    END OF INIT convert;

	    PROCEDURE warning(message,t);   NAME message;
	    TEXT message,t;
	    BEGIN
		Outtext("Warning *** ");   Outtext(message);
		IF t.Length > Length THEN
		BEGIN
		    WHILE t.More DO Outchar(t.Getchar);
		    Outtext(" ***")
		END ELSE Outtext(t);
		Outimage
	    END OF WARNING;

	    CHARACTER ARRAY convert[0:127];
	    CHARACTER w,c;
	    INTEGER begincount,endcount,p;
	    TEXT t;
	    REF (Infile) prog;   TEXT progname,outname;
	    REF (Outfile) outf;   REF (record) x;   REF (Head) recq;

	    Link CLASS record(t);   VALUE t;   TEXT t;
	    Into(recq);

	    BOOLEAN PROCEDURE help1;
	    BEGIN
		Outtext("Enter the file description for the file you want converted.");
		Outimage
	    END OF HELP1;
	    	
	    BOOLEAN PROCEDURE help2;
	    BEGIN
		Outtext("Enter the file description for the resulting file.");
		Outimage
	    END OF HELP2;
	    	
	    Outtext("SIMIBM - SIMULA Conversion Program. Version 1.1");
	    Outimage;
	    request("Enter program file name:",nodefault,textinput(progname,
	    TRUE),"? Illegal file spec.",help1);
	    prog:- NEW Infile(conc2("INPUT ",progname));
	    	
	    request("Enter output file name","LPT:",textinput(outname,TRUE),
	    "? Illegal file desc.",help2);
	    outf:- NEW Outfile(conc2("SIMIBM ",outname));
	    	
	    initconvert(convert);
	    	
	    INSPECT outf DO
	    BEGIN
		text ttab,tblank;
		PROCEDURE printimage;
		BEGIN
		    WHILE NOT recq.Empty DO
		    BEGIN   x:- recq.First;   x.Out;
		        t:- x QUA record.t;
		        IF (IF t.Length > 72 THEN t.Sub(1,1) = """" ELSE FALSE) THEN
			BEGIN   Sysout.Outtext("*** LONG TEXT CONSTANT ***");
			    Sysout.Outimage
			END;
			WHILE t.Length > 72 DO
			BEGIN   Outtext(t.Sub(1,72));
			t:- t.Sub(73,t.Length-72)   END;
			IF t = ttab THEN Outtext(tblank.Sub(1,1+((Pos+7)//8)*8-Pos)) ELSE
			Outtext(t);
		    END LOOP;
		    Outimage;
		END OF PRINTIMAGE;

		Open(Blanks(72));
			
		INSPECT prog DO
		BEGIN
		    BOOLEAN PROCEDURE textcont(trest);   VALUE trest;
		    TEXT trest;
		    BEGIN
			IF Pos + trest.Length <= Length + 1 THEN
			BEGIN
			    IF Image.Sub(Pos,trest.Length) = trest THEN
			    BEGIN
				textcont:=TRUE;   Setpos(Pos+trest.Length)
			    END;
			    	
			END;
		    END OF TEXTCONT;
		    	
		    TEXT PROCEDURE uppertext(t);   TEXT t;
		    BEGIN  TEXT u;
			u:- Blanks(t.Length);
			WHILE t.More DO u.Putchar(convert[Rank(t.Getchar)]);
			uppertext:- u
		    END OF UPPERTEXT;

		    PROCEDURE getstring;
		    BEGIN
			t:- t.Main;   t:= NOTEXT;   t.Setpos(1);
			t.Putchar(window);   GO TO l;
				
			WHILE (IF Letter(c) THEN TRUE ELSE IF Digit(c) THEN TRUE
			ELSE
			IF c = '_' THEN TRUE ELSE IF c = '$' THEN TRUE ELSE
			IF c = '#' THEN TRUE ELSE c = '@') DO
			BEGIN   t.Putchar(c);  l:   IF \ More THEN GO TO ready;
			c:= convert[Rank(Inchar)]   END;
				
			Setpos(Pos-1);
			ready:	t:- t.Sub(1,t.Pos-1)
		    END OF GETSTRING;
		    	
		    TEXT PROCEDURE textgen(w);   CHARACTER w;
		    BEGIN   TEXT t;   t:- Blanks(1);
			t.Putchar(w);   textgen:- t
		    END OF TEXTGEN;
		    	
		    PROCEDURE nextimage;
		    BEGIN
			Image:- mainimage;
			Inimage;
			Image:- mainimage.Strip;
			WHILE Image == NOTEXT DO
			BEGIN   Outimage;
			    Image:- mainimage;
			    Inimage;
			    Image:- mainimage.Strip;
			END;
		    END OF NEXTIMAGE;
		    	
		    CHARACTER window,c;   TEXT t,mainimage;
		    BOOLEAN endcommentflag,commentflag,numericflag,
		    textflag;
		    INTEGER i,p;
		    	
		    recq:- NEW Head;
		    ttab:- Blanks(1);   ttab.Putchar(Char(9));
		    tblank:- Blanks(72);
		    t:- Blanks(200);   convert[9]:= Char(32);
		    convert[Rank('[')]:= '(';   convert[Rank(']')]:= ')';
		    Open(Blanks(200));   mainimage:- Image;   nextimage;
		    	
		    IF Digit(Inchar) THEN
		    BEGIN   Setpos(1);   Inint;
			IF Inchar NE Char(9) THEN GO TO nolinenumber;
			warning("? Line numbers not allowed. Please remove them.",Image);
			Sysout.Outtext("Please do ^C:");   Sysout.Breakoutimage;
			WHILE TRUE DO Sysin.Lastitem;	!you'll never leave this point!;
		    END ELSE nolinenumber: Setpos(1);
	    	
		    WHILE \ Endfile DO
		    BEGIN   next:
				
			IF NOT More THEN
			BEGIN   printimage;   nextimage;
			    IF Endfile THEN GO TO fin
			END;
				
			i:= 1;
			IF endcommentflag THEN GO TO scanendcomment;
			IF textflag THEN GO TO scantext;
			IF commentflag THEN GO TO scanoldcomment;
				
			window:= Inchar;
			IF window = Char(9) THEN
			BEGIN   NEW record(ttab);   GO TO next   END;
			window:= convert[Rank(window)];
				
			scan:
			IF window = ' ' OR window = ';' THEN
			NEW record(textgen(window)) ELSE
			IF (IF Letter(window) THEN TRUE ELSE IF window = '_'
			THEN TRUE
			ELSE
			IF window = '$' THEN TRUE ELSE IF window = '#' THEN TRUE
			ELSE
			window = '@') THEN
			BEGIN   p:= Pos - 1;   getstring;
			    IF t = "COMMENT" THEN GO TO scancomment;
			    IF t = "OPTIONS" THEN GO TO scancomment;
			    IF t = "END" THEN
			    BEGIN moreends:   i:= Pos;
				NEW record(t);
				endcount:= endcount + 1;
				IF endcount > begincount THEN
				warning("More ENDs than BEGINs at line:",Image);
				scanendcomment:
				WHILE More DO
				BEGIN   window:= convert[Rank(Inchar)];
				    IF window = 'E' THEN
				    BEGIN   p:= Pos - 1;   getstring;
					IF t = "END" THEN
					BEGIN
					    NEW record(uppertext(Image.Sub(i,p-i)));
					    GO TO moreends
					END;
					IF t = "ELSE" THEN
					BEGIN   endcommentflag:= FALSE;
					    NEW record(uppertext(Image.Sub(i,p-i)));
					    NEW record(t);    GO TO next
					END;
				    END ELSE
				    IF window = 'O' THEN
				    BEGIN   p:= Pos - 1;   getstring;
					IF t = "OTHERWISE" THEN
					BEGIN   endcommentflag:= FALSE;
					    NEW record(uppertext(Image.Sub(i,p-i)));
					    NEW record(t);   GO TO next
					END;
				    END ELSE
				    IF window = 'W' THEN
				    BEGIN   p:= Pos - 1;   getstring;
					IF t = "WHEN" THEN
					BEGIN   endcommentflag:= FALSE;
					    NEW record(uppertext(Image.Sub(i,p-i)));
					    NEW record(t);
					    GO TO next
					END
				    END ELSE
				    IF window = ';' THEN
				    BEGIN   NEW record(uppertext(Image.Sub(i,Pos-i)));
					endcommentflag:= FALSE;   GO TO next
				    END ELSE
				    IF Letter(window) THEN getstring;
				END  MORE LOOP;
				endcommentflag:= TRUE;
				NEW record(uppertext(Image.Sub(i,Pos-i)));
			    END *ND=T ELSE
			    IF t = "BEGIN" THEN
			    BEGIN   NEW record(t);
				begincount:= begincount + 1
			    END ELSE
			    IF t = "BREAKOUTIMAGE" THEN
			    NEW record("OUTIMAGE") ELSE
			    NEW record(t);
			    	
			END ONE OR MORE LETTERS ELSE
			IF window = '"' THEN
			BEGIN	 scantext:   p:= Pos - 1;  IF p = 0 THEN p:= 1;
			    double: window:= ' ';
			    WHILE (IF More THEN window \= '"' ELSE FALSE) DO
			    window:= Inchar;
			    IF (IF More THEN Image.Sub(Pos,
			    1).Getchar = '"' ELSE FALSE) THEN
			    BEGIN Inchar; GO TO double END;
			    NEW record(uppertext(Image.Sub(p,Pos-p)));
			    	
			    IF window \= '"' THEN
			    BEGIN
				warning("<CR><LF> in text constant:",Image);
				textflag:= TRUE
			    END
			    ELSE textflag:= FALSE;
			    	
			END ELSE
			IF window = ''' THEN
			BEGIN   p:= Pos - 1;
			    IF \ More THEN
			    w0: warning("Character constant at line:",Image) ELSE
			    BEGIN   Setpos(Pos+1);
				IF \ More THEN GO TO w0;
				window:= Inchar;
				IF window \= ''' THEN GO TO w0
			    END;
			    NEW record(uppertext(Image.Sub(p,Pos-p)));
			END ELSE
			IF window = '!' THEN
			BEGIN
			    scancomment:   NEW record("COMMENT ");
			    scanoldcomment:  p:= Pos;   textflag:= FALSE;
			    WHILE (IF More THEN window \= ';' OR
			    (IF t = "OPTIONS" THEN textflag ELSE FALSE) ELSE FALSE) DO
			    BEGIN   window:= Inchar;
				textflag:= NOT (window = '"' EQV textflag)
			    END;
			    textflag:= FALSE;   t:= NOTEXT;
			    NEW record(uppertext(Image.Sub(p,Pos-p)));
			    commentflag:= window \= ';';
			END ELSE
			IF window = '*' THEN
			BEGIN   IF textcont("*") THEN NEW record("**") ELSE
			    NEW record("*");
			END ELSE
			IF window = '=' THEN
			BEGIN
			    IF textcont("=") THEN NEW record("==") ELSE
			    IF textcont("/=") THEN NEW record("=/=") ELSE
			    NEW record("=");
			END ELSE
			IF window = ':' THEN
			BEGIN
			    IF textcont("=") THEN NEW record(":=") ELSE
			    IF textcont("-") THEN NEW record(":-") ELSE
			    NEW record(":")
			END ELSE
			IF window = '>' OR window = '<' THEN
			BEGIN
			    IF textcont("=") THEN
			    NEW record(conc2(textgen(window),"=")) ELSE
			    NEW record(textgen(window))
			END ELSE
			IF window = '/' THEN
			BEGIN
			    IF textcont("/") THEN NEW record("//") ELSE
			    NEW record("/");
			END ELSE
			IF window = '\' THEN
			BEGIN
			    IF textcont("=") THEN NEW record(" NE ") ELSE
			    NEW record(" NOT ");
			END ELSE
			IF window = '^' THEN NEW record("**") ELSE
			IF Digit(window) OR window = '&' THEN
			BEGIN   p:= Pos - 1;  t:- t.Main;   t:= NOTEXT;
			    t.Setpos(1);   t.Putchar(window);
			    morenum:   numericflag:= window = '&';
			    IF More THEN
			    BEGIN   window:= convert[Rank(Inchar)];   t.Putchar(window);
				WHILE (IF More THEN Digit(window) ELSE FALSE) DO
				BEGIN   numericflag:= FALSE;
				    window:= convert[Rank(Inchar)];   t.Putchar(window);
				END;
				IF window = '.' THEN GO TO morenum;
				IF window = '&' THEN
				BEGIN
				    IF numericflag THEN
				    BEGIN   t.Setpos(t.Pos-2);
					FOR i:= 1 STEP 1 UNTIL 9 DO t.Putchar('0');
					IF Pos - p = 2 THEN ! Fix "&&9" - case;
					t.Sub(t.Pos-9,2):= "1.";
					t.Putchar('&');
				    END;
				    numericflag:= TRUE;   GO TO morenum;
				END;
				IF (window = '+' OR window = '-') AND numericflag THEN
				GO TO morenum;
				NEW record(t.Sub(1,t.Pos-2));   GO TO scan;
			    END MORE ELSE
			    NEW record(textgen(window));
			END NUMRICAL CONSTANT ELSE
			NEW record(textgen(window));
		    END BIG LOOP;
		    	
		END INSPECTING INPUT;
		printimage;
		fin:   prog.Close;   Close
	    END INSPECTING OUTPUT;
	    Outtext("Processing ready.");   Outimage;
	    Outtext("Number of BEGIN (END) found:");
	    Outint(begincount,5);
	    IF endcount \= begincount THEN
	    BEGIN   Outtext("  (");   Outint(endcount,5);
		Outchar(')');   Outtext(" **********************")
	    END;
	    Outimage
	END OF SIMSET
    END OF SAFMIN
END PROGRAM