Background

While browsing the web for something completely different, I ran into a very nice site that publishes Oberon sources in a kind of tutorial. I liked the tutorial (although I am not quite new to the language) and the examples shed some light on one more way to produce graphics output without gaving to go through millions of pages of GTK books. There's only one thing that is hard for me: Donald uses a rather dense style of coding. I guess it is a result of the past, since Donald learned to program in the days when RAM was terribly expensive so you had to make your source as compact as possible.

Therefore I processed some of his sources to the modern day style with indenting and whitespace. You be the judge which style you prefer. Neither style is better than the other. It's all taste.

Topics covered:

Mile

MODULE mile;
IMPORT Out;
VAR mi,qmi,cm,in,ft,yd,m:REAL;
BEGIN
cm:=1.0;
m:=100*cm;
in:=2.54*cm;
ft:=12*in;
yd:=3*ft;
mi:=5280*ft;
qmi:=mi/4.0;
Out.String('a quarter mile is:');Out.Ln;
Out.RealEng(qmi/m,20,6);Out.String(' meters');Out.Ln;
Out.RealEng(qmi/yd,20,6);Out.String(' yards');Out.Ln;
END mile.
     
MODULE mile;

IMPORT	Out;

VAR	mi, qmi, cm, in, ft, yd, m	: REAL;

BEGIN
  cm := 1.0;
  m := 100 * cm;
  in := 2.54 * cm;
  ft := 12 * in;
  yd := 3 * ft;
  mi := 5280 * ft;
  qmi := mi / 4.0;
  Out.String ('a quarter mile is:');	Out.Ln;
  Out.RealEng (qmi / m, 20, 6);
  Out.String (' meters');		Out.Ln;
  Out.RealEng (qmi / yd, 20, 6);
  Out.String (' yards');		Out.Ln
END mile.
     

Tiny

MODULE tiny;
IMPORT Out;
CONST a=3;
VAR b,c:LONGINT;
BEGIN
b:=2; c:=a+b;
Out.LongInt(c,4);Out.Ln;
END tiny.
     
MODULE tiny;

IMPORT	Out;

CONST	a	= 3;
VAR	b, c	: LONGINT;

BEGIN
  b := 2;		c := a + b;
  Out.LongInt (c, 4);	Out.Ln
END tiny.
     

Proc1

MODULE proc1;
IMPORT Out;
VAR a:LONGINT;

PROCEDURE add1; BEGIN a:=a+1;END add1;

BEGIN a:=1; add1; Out.LongInt(a,4);Out.Ln;END proc1.
     
MODULE proc1;
IMPORT	Out;
VAR	a	: LONGINT;

PROCEDURE add1; 
BEGIN 
  a := a + 1
END add1;

BEGIN 
  a:=1;	  add1;	  Out.LongInt (a, 4);	Out.Ln
END proc1.
     

Proc3

MODULE proc3; 
IMPORT Out; VAR x,y:LONGINT;

PROCEDURE add1(a:LONGINT; VAR b:LONGINT);
BEGIN b:=a+1; END add1;

BEGIN x:=1;add1(x,y);
Out.LongInt(x,4);Out.LongInt(y,4);Out.Ln;END proc3.
     
MODULE proc3;

IMPORT	Out;
VAR	x, y	:LONGINT;

PROCEDURE add1 (a  : LONGINT; VAR b : LONGINT);
BEGIN 
  b := a + 1
END add1;

BEGIN 
  x := 1;		add1 (x, y);
  Out.LongInt (x, 4);
  Out.LongInt (y, 4);	Out.Ln
END proc3.
     

Proc4

MODULE proc4; 
IMPORT Out; VAR a,b,c,d,e,f:LONGINT;

PROCEDURE change(a,x:LONGINT;VAR c,y:LONGINT);
(*The stuff in parentheses on the line above is the
   parameter list.  *)
VAR f:LONGINT;
BEGIN
f:=60; a:=1+a;x:=1+x;c:=1+c;y:=1+y;e:=1+e;f:=f+1;
Out.String('in procedure:');
Out.LongInt(a,3);Out.LongInt(x,3);Out.LongInt(c,3);
Out.LongInt(y,3);Out.LongInt(e,3);Out.LongInt(f,3); 
Out.Ln;
END change;
   
BEGIN(*this is where the execution of the program 
starts*)
a:=10;b:=20;c:=30;d:=40;e:=50;f:=70; 
Out.String('in program-1:');Out.LongInt(a,3);
Out.LongInt(b,3);Out.LongInt(c,3);Out.LongInt(d,3);
Out.LongInt(e,3);Out.LongInt(f,3);Out.Ln; 
change(a,b,c,d); (*this is the procedure call*) 
Out.String('in program-2:');Out.LongInt(a,3);
Out.LongInt(b,3);Out.LongInt(c,3);Out.LongInt(d,3);
Out.LongInt(e,3);Out.LongInt(f,3);Out.Ln; 
END proc4.
     
MODULE  proc4; 
IMPORT	Out;
VAR	a, b, c, d, e, f	:LONGINT;

PROCEDURE Change (a, x : LONGINT; VAR c, y : LONGINT);
(* The stuff in parentheses on the line above is 
	the parameter list.  *)

VAR	f : LONGINT;

BEGIN
  f := 60;	a := 1 + a;	x := 1 + x;	c := 1 + c;
  y := 1 + y;	e := 1 + e;	f := f + 1;
  Out.String ('in procedure:');
  Out.LongInt (a, 3);		Out.LongInt (x, 3);
  Out.LongInt (c, 3);		Out.LongInt (y, 3);
  Out.LongInt (e, 3);		Out.LongInt (f, 3); 
  Out.Ln
END Change;

BEGIN	(* this is where the execution of the program starts *)
  a := 10;	b := 20;	c := 30;	d := 40;
  e := 50;	f := 70; 
  Out.String ('in program-1:');	Out.LongInt (a, 3);
  Out.LongInt (b, 3);		Out.LongInt (c, 3);
  Out.LongInt (d, 3);		Out.LongInt (e, 3);
  Out.LongInt (f, 3);		Out.Ln; 

  Change (a, b, c, d); 		(* this is the procedure call *) 

  Out.String ('in program-2:');	Out.LongInt (a, 3);
  Out.LongInt (b, 3);		Out.LongInt (c, 3);
  Out.LongInt (d, 3);		Out.LongInt (e, 3);
  Out.LongInt (f, 3);		Out.Ln
END proc4.
     

Fcn1

MODULE fcn1; 
IMPORT Out; 
VAR x,y:LONGINT;

PROCEDURE add1(a:LONGINT):LONGINT; 
BEGIN RETURN a+1;END add1;

BEGIN x:=0;y:=1+add1(x);Out.LongInt(y,4);
Out.Ln;END fcn1.
     
MODULE fcn1; 

IMPORT	Out; 
VAR	x, y	: LONGINT;

PROCEDURE Add1 (a : LONGINT) : LONGINT; 
BEGIN 
  RETURN a + 1
END Add1;

BEGIN 
  x := 0;		y := 1 + Add1 (x);
  Out.LongInt (y, 4);	Out.Ln
END fcn1.
     

Synopsis

Again, whitespace and CamelCase are a matter of personal taste. All people that I know as programmers prefer a lot of whitespace. Possibly this is due to the fact that the lot of us used to program in assembly language. Or it may be a result of the lattitude we live on. Who is to tell.
Let's look at one particular line of code:

BEGIN x:=0;y:=1+add1(x);Out.LongInt(y,4);
Let's apply some colour:
BEGIN x:=0;y:=1+add1(x);Out.LongInt(y,4)
       ^  ^ ^
One need to be very careful here. The difference between a colon and a semicolon is marginal. Especially for a newbie. Yet both tokens are used in rapid succession. An experienced programmer will derive the meaning of the tokens from the context. But still....

Page created 10 April 2012,