[comp.lang.ada] A self reproducing program in Ada

madmats%elcgl.epfl.ch@VMA.CC.CMU.EDU (Mats Weber) (03/20/90)

----------------- cut here (non inclusive) ------------------------
with Text_IO;

procedure Write_Itself is

   First_Part_Length   : constant := 39;
   Second_Part_Length  : constant := 34;
   Number_Of_Lines     : constant :=
                         2 * (First_Part_Length +
                              Second_Part_Length);

   Max_Columns         : constant := 80;

   Null_Character      : constant Character := ASCII.Nul;

   subtype String_Max_Columns is String(1..Max_Columns);

   Image : array (1..Number_Of_Lines) of String_Max_Columns;


   function Pad (The_String : String)
      return String_Max_Columns is
   begin
      return The_String &
             (1..Max_Columns - The_String'Length =>
                 Null_Character);
   end Pad;

   function Unpad (The_String : String) return String is
   begin
      for I in The_String'Range loop
         if The_String(I) = Null_Character then
            return The_String(The_String'First..I - 1);
         end if;
      end loop;
   end Unpad;

begin
   Image(1..First_Part_Length + Second_Part_Length) :=
      (
         Pad("with Text_IO;"),
         Pad(""),
         Pad("procedure Write_Itself is"),
         Pad(""),
         Pad("   First_Part_Length   : constant := 39;"),
         Pad("   Second_Part_Length  : constant := 34;"),
         Pad("   Number_Of_Lines     : constant :="),
         Pad("                         2 * (First_Part_Length +"),
         Pad("                              Second_Part_Length);"),
         Pad(""),
         Pad("   Max_Columns         : constant := 80;"),
         Pad(""),
         Pad("   Null_Character      : constant Character := ASCII.Nul;"),
         Pad(""),
         Pad("   subtype String_Max_Columns is String(1..Max_Columns);"),
         Pad(""),
         Pad("   Image : array (1..Number_Of_Lines) of String_Max_Columns;"),
         Pad(""),
         Pad(""),
         Pad("   function Pad (The_String : String)"),
         Pad("      return String_Max_Columns is"),
         Pad("   begin"),
         Pad("      return The_String &"),
         Pad("             (1..Max_Columns - The_String'Length =>"),
         Pad("                 Null_Character);"),
         Pad("   end Pad;"),
         Pad(""),
         Pad("   function Unpad (The_String : String) return String is"),
         Pad("   begin"),
         Pad("      for I in The_String'Range loop"),
         Pad("         if The_String(I) = Null_Character then"),
         Pad("            return The_String(The_String'First..I - 1);"),
         Pad("         end if;"),
         Pad("      end loop;"),
         Pad("   end Unpad;"),
         Pad(""),
         Pad("begin"),
         Pad("   Image(1..First_Part_Length + Second_Part_Length) :="),
         Pad("      ("),
         Pad("      );"),
         Pad("   Image(Number_Of_Lines - Second_Part_Length + 1.."),
         Pad("         Number_Of_Lines) :="),
         Pad("      Image(First_Part_Length + 1.."),
         Pad("            First_Part_Length + Second_Part_Length);"),
         Pad("   for I in Positive range"),
         Pad("               First_Part_Length + 1.."),
         Pad("               Number_Of_Lines - Second_Part_Length"),
         Pad("   loop"),
         Pad("      declare"),
         Pad(""),
         Pad("         Padded_Image : constant String :="),
         Pad("            (1..9 => ' ') &"),
         Pad("            ('P', 'a', 'd', '(', ASCII.Quotation) &"),
         Pad("            Unpad(Image((I - First_Part_Length) *"),
         Pad("                        Boolean'Pos(I - First_Part_Length <="),
         Pad("                                    First_Part_Length) +"),
         Pad("                        (I + Second_Part_Length) *"),
         Pad("                        Boolean'Pos(I - First_Part_Length >"),
         Pad("                                    First_Part_Length))) &"),
         Pad("            (ASCII.Quotation & ')');"),
         Pad(""),
         Pad("      begin"),
         Pad("         if I < Number_Of_Lines - Second_Part_Length then"),
         Pad("            Image(I) := Pad(Padded_Image & ',');"),
         Pad("         else"),
         Pad("            Image(I) := Pad(Padded_Image);"),
         Pad("         end if;"),
         Pad("      end;"),
         Pad("   end loop;"),
         Pad("   for I in Image'Range loop"),
         Pad("      Text_IO.Put_Line(Unpad(Image(I)));"),
         Pad("   end loop;"),
         Pad("end Write_Itself;")
      );
   Image(Number_Of_Lines - Second_Part_Length + 1..
         Number_Of_Lines) :=
      Image(First_Part_Length + 1..
            First_Part_Length + Second_Part_Length);
   for I in Positive range
               First_Part_Length + 1..
               Number_Of_Lines - Second_Part_Length
   loop
      declare

         Padded_Image : constant String :=
            (1..9 => ' ') &
            ('P', 'a', 'd', '(', ASCII.Quotation) &
            Unpad(Image((I - First_Part_Length) *
                        Boolean'Pos(I - First_Part_Length <=
                                    First_Part_Length) +
                        (I + Second_Part_Length) *
                        Boolean'Pos(I - First_Part_Length >
                                    First_Part_Length))) &
            (ASCII.Quotation & ')');

      begin
         if I < Number_Of_Lines - Second_Part_Length then
            Image(I) := Pad(Padded_Image & ',');
         else
            Image(I) := Pad(Padded_Image);
         end if;
      end;
   end loop;
   for I in Image'Range loop
      Text_IO.Put_Line(Unpad(Image(I)));
   end loop;
end Write_Itself;
----------------- cut here (non inclusive) ------------------------

jamesth@microsoft.UUCP (James THIELE) (03/22/90)

In article <900319200431.23c00532@SIC.Epfl.CH> madmats%elcgl.epfl.ch@VMA.CC.CMU.EDU (Mats Weber) writes:
>----------------- cut here (non inclusive) ------------------------
>[146 lines of Ada code deleted]
>----------------- cut here (non inclusive) ------------------------
I've seen *much* shorter self-reproducing programs in FORTRAN.

Does this mean FORTRAN is more sophisticated than Ada?

James Thiele -- Standard Disclaimer

sbw@naucse.UUCP (Steve Wampler) (03/22/90)

From article <53671@microsoft.UUCP>, by jamesth@microsoft.UUCP (James THIELE):
> In article <900319200431.23c00532@SIC.Epfl.CH> madmats%elcgl.epfl.ch@VMA.CC.CMU.EDU (Mats Weber) writes:
>>[146 lines of Ada code deleted]
> I've seen *much* shorter self-reproducing programs in FORTRAN.
> 
> Does this mean FORTRAN is more sophisticated than Ada?

Actually, since you can fit the self-replicating programs for a
lot of languages simultaneously (i.e. join them together) in the
space of this one Ada program, maybe this means that Ada is all these
other languages rolled into one?

Now I know why I like Icon so much.
-- 
	Steve Wampler
	{....!arizona!naucse!sbw}
	{sbw@naucse.cse.nau.edu}