The Rosetta project

"Rosetta's stone" was the key that opened up the egyptian writing to researchers. It presented the same story in three different languages and alphabets. By looking up the known language one could learn (or, at least, understand) the other two. The rosetta project is similar: many predefined tasks are to be carried out in your favorite language. I added some tasks to the project. And then I decided it would be better to add them to these pages as well.

Integer addition

A first task was integer addition: A + B It is too trivial to explain...

MODULE	ab;

IMPORT	InOut;

VAR	A, B	: INTEGER;

BEGIN
  InOut.ReadInt (A);
  InOut.ReadInt (B);
  InOut.WriteInt (A + B, 8);
  InOut.WriteLn
END ab.
   

99 Bottles of beer

A drinking song... See its decription at 99 Bottles of beer.

MODULE b99;

IMPORT	InOut;

VAR	nr	: CARDINAL;

BEGIN
  nr := 99;
  REPEAT
    InOut.WriteCard (nr, 4);		InOut.WriteString (" bottles of beer on the wall");
    InOut.WriteLn;
    InOut.WriteCard (nr, 4);		InOut.WriteString (" bottles of beer");
    InOut.WriteLn;
    InOut.WriteString ("Take one down, pass it around");
    InOut.WriteLn;
    DEC (nr);
    InOut.WriteCard (nr, 4);		InOut.WriteString (" bottles of beer on the wall");
    InOut.WriteLn;
    InOut.WriteLn
  UNTIL nr = 0
END b99.
   

Ackerman function

Next is the Ackerman unction, which is a rapidly growing recursive function.

MODULE ackerman;

IMPORT	ASCII, NumConv, InOut;

VAR	m, n		: LONGCARD;
	string		: ARRAY [0..19] OF CHAR;
	OK		: BOOLEAN;

PROCEDURE Ackerman (x, y   : LONGCARD) : LONGCARD;

BEGIN
  IF	x = 0  THEN  RETURN  y + 1
  ELSIF	y = 0  THEN  RETURN  Ackerman (x - 1 , 1)
  ELSE
    RETURN  Ackerman (x - 1 , Ackerman (x , y - 1))
  END
END Ackerman;

BEGIN
  FOR  m := 0  TO  3  DO
    FOR  n := 0  TO  6  DO
      NumConv.Num2Str (Ackerman (m, n), 10, string, OK);
      IF  OK  THEN
        InOut.WriteString (string)
      ELSE
        InOut.WriteString ("* Error in number * ")
      END;
      InOut.Write (ASCII.HT)
    END;
    InOut.WriteLn
  END;
  InOut.WriteLn
END ackerman.
   

Complex number arithmetic

The task here is to show how your programming language deals with complex numbers. Modula-2 does not. None of the wirthian languages does. Wirth's languages are compact. So the user is challenged to make his own. Anyway: here is the rosetta page: Complex numbers. And here is my source:

MODULE complex;

IMPORT	InOut;

TYPE	Complex		= RECORD   Re, Im    : REAL    END;

VAR	z		: ARRAY [0..3] OF Complex;

PROCEDURE ShowComplex (str  : ARRAY OF CHAR;  p  : Complex);

BEGIN
  InOut.WriteString (str);		InOut.WriteString (" = ");
  InOut.WriteReal (p.Re, 6, 2);
  IF  p.Im >= 0.0  THEN  InOut.WriteString (" + ")  ELSE  InOut.WriteString (" - ")  END;
  InOut.WriteReal (ABS (p.Im), 6, 2);	InOut.WriteString (" i ");
  InOut.WriteLn;			InOut.WriteBf
END ShowComplex;

PROCEDURE AddComplex (x1, x2 : Complex; VAR x3 : Complex);

BEGIN
  x3.Re := x1.Re + x2.Re;
  x3.Im := x1.Im + x2.Im
END AddComplex;

PROCEDURE SubComplex (x1, x2 : Complex; VAR x3  : Complex);

BEGIN
  x3.Re := x1.Re - x2.Re;
  x3.Im := x1.Im - x2.Im
END SubComplex;

PROCEDURE MulComplex (x1, x2  : Complex; VAR x3  : Complex);

BEGIN
  x3.Re := x1.Re * x2.Re - x1.Im * x2.Im;
  x3.Im := x1.Re * x2.Im + x1.Im * x2.Re
END MulComplex;

PROCEDURE InvComplex (x1 : Complex; VAR x2  : Complex);

BEGIN
  x2.Re := x1.Re / (x1.Re * x1.Re + x1.Im * x1.Im);
  x2.Im := -1.0 * x1.Im / (x1.Re * x1.Re + x1.Im * x1.Im)
END InvComplex;

PROCEDURE NegComplex (x1 : Complex; VAR x2  : Complex);

BEGIN
  x2.Re := - x1.Re;	x2.Im := - x1.Im
END NegComplex;

BEGIN
  InOut.WriteString ("Enter two complex numbers : ");
  InOut.WriteBf;
  InOut.ReadReal (z[0].Re);		InOut.ReadReal (z[0].Im);
  InOut.ReadReal (z[1].Re);		InOut.ReadReal (z[1].Im);
  ShowComplex ("z1", z[0]);		ShowComplex ("z2", z[1]);
  InOut.WriteLn;
  AddComplex (z[0], z[1], z[2]);	ShowComplex ("z1 + z2", z[2]);
  SubComplex (z[0], z[1], z[2]);	ShowComplex ("z1 - z2", z[2]);
  MulComplex (z[0], z[1], z[2]);	ShowComplex ("z1 * z2", z[2]);
  InvComplex (z[0], z[2]);		ShowComplex ("1  / z1", z[2]);
  NegComplex (z[0], z[2]);		ShowComplex ("   - z1", z[2]);
  InOut.WriteLn
END complex.
   
And some test outpu:
Enter two complex numbers :  5  3  0.5  6

z1 = 5.00 + 3.00 i
z2 = 0.50 + 6.00 i

z1 + z2 =   5.50 +  9.00 i 
z1 - z2 =   4.50 -  3.00 i 
z1 * z2 = -15.50 + 31.50 i 
 1 / z1 =   0.15 -  0.09 i
   - z1 =  -5.00 -  3.00 i
Now THIS is an interesting topic. I guess it is time to make a Complex module that takes care of all of the above and more. To be called like Complex.Add (z1, z2, z3).

Page created 18 June 2011 and