All Source For modula2 |
Ackermann's Function |
(* The Great Win32 Language Shootout http://dada.perl.it/shootout/
contributed by Isaac Gouy (Modula2 novice)
To build: xc =m ackermann
To run: ackermann 8
*)
MODULE Ackermann;
(* Prefer unqualified procedure import *)
FROM LanguageShootout IMPORT N;
FROM STextIO IMPORT WriteString, WriteLn;
FROM SWholeIO IMPORT WriteCard;
PROCEDURE Ack (m, n: CARDINAL) : CARDINAL;
BEGIN
IF m=0 THEN RETURN n+1; END;
IF n=0 THEN RETURN Ack(m-1, 1); END;
RETURN Ack(m-1, Ack(m, n-1));
END Ack;
VAR n: CARDINAL;
BEGIN
n := N();
WriteString("Ack(3," ); WriteCard(n,1); WriteString("): ");
WriteCard( Ack(3,n), 1); WriteLn;
END Ackermann.
|
Array Access |
(* The Great Win32 Language Shootout http://dada.perl.it/shootout/
contributed by Isaac Gouy (Modula2 novice)
To compile: xc =m ary3
To run: ary3 7000
*)
MODULE Ary3;
<* m2extensions + *>
<* storage + *>
<* ioverflow - *>
<* noptralias + *>
<* checkdindex - *>
<* checknil - *>
(* Prefer unqualified procedures *)
FROM LanguageShootout IMPORT N;
FROM STextIO IMPORT WriteString, WriteLn;
FROM SWholeIO IMPORT WriteInt;
TYPE
Array_Type = ARRAY OF INTEGER;
Array_Ptr_Type = POINTER TO Array_Type;
VAR
n, i, m, j: INTEGER;
x, y: Array_Ptr_Type;
BEGIN
n := N();
NEW(x, n);
NEW(y, n);
FOR i := 0 TO INT(HIGH(x^)) DO
x^[i] := i+1;
y^[i] := 0;
END;
m := HIGH(y^);
FOR j := 1 TO 1000 DO
FOR i := 0 TO m DO
INC(y^[i], x^[i]);
END;
END;
WriteInt(y^[0],1); WriteInt(y^[HIGH(y^)],0); WriteLn;
DISPOSE(x);
DISPOSE(y);
END Ary3.
|
Count Lines/Words/Chars |
(* The Great Win32 Language Shootout http://dada.perl.it/shootout/
contributed by Isaac Gouy (Modula2 novice)
To build: xc =m wc
To run: wc < input.txt
*)
MODULE Wc;
<* m2extensions + *>
FROM SRawIO IMPORT Read;
FROM SIOResult IMPORT ReadResult, wrongFormat;
FROM SYSTEM IMPORT ADR, FILL;
FROM STextIO IMPORT WriteLn;
FROM SWholeIO IMPORT WriteCard;
CONST
buffer_size = 4096;
LF = CHR(10);
CR = CHR(13);
TAB = CHR(9);
Space = CHR(32);
Null = CHR(0);
TYPE Buffer_Type = ARRAY [1..buffer_size] OF CHAR;
PROCEDURE Fill(VAR buf: Buffer_Type);
VAR i: INTEGER;
BEGIN
(* Clear the buffer *)
FILL( ADR(buf), Null, buffer_size );
(* Raw read into the buffer *)
Read(buf);
IF ReadResult() = wrongFormat THEN
(* ignore LF if it's followed by end of input *)
i := LENGTH(buf);
IF (i > 0) AND (buf[i] = LF) THEN
buf[i] := Null;
END;
END;
END Fill;
VAR
nc, nl, nw: CARDINAL;
i, read_length: CARDINAL;
buf: Buffer_Type;
c: CHAR;
insideWord: BOOLEAN;
BEGIN
insideWord := FALSE;
REPEAT
Fill(buf);
read_length := LENGTH(buf);
INC(nc, read_length);
FOR i := 1 TO read_length DO
c := buf[i];
IF c = LF THEN INC(nl); END;
IF (c = Space) OR (c = LF) OR (c = TAB) OR (c = CR) THEN
insideWord := FALSE;
ELSIF NOT insideWord THEN
insideWord := TRUE;
INC(nw);
END;
END;
UNTIL read_length<1;
WriteCard(nl,1); WriteCard(nw,0); WriteCard(nc,0); WriteLn;
END Wc.
|
Exception Mechanisms |
(* The Great Win32 Language Shootout http://dada.perl.it/shootout/
contributed by Isaac Gouy (Modula2 novice)
To build: xc =m except
To run: except 200000
*)
MODULE Except;
<* procinline + *>
(* Prefer unqualified procedures *)
FROM LanguageShootout IMPORT N;
IMPORT EXCEPTIONS;
FROM STextIO IMPORT WriteString, WriteLn;
FROM SWholeIO IMPORT WriteCard;
VAR lo, hi: CARDINAL;
n, i: CARDINAL;
source: EXCEPTIONS.ExceptionSource;
TYPE Exceptions = (Lo_Exception, Hi_Exception);
PROCEDURE Exception(): Exceptions;
BEGIN
RETURN VAL(Exceptions, EXCEPTIONS.CurrentNumber(source));
END Exception;
PROCEDURE BlowUp(i: CARDINAL);
BEGIN
IF ODD(i) THEN
EXCEPTIONS.RAISE(source, ORD(Hi_Exception), "HI Exception");
ELSE
EXCEPTIONS.RAISE(source, ORD(Lo_Exception), "LO Exception");
END;
END BlowUp;
PROCEDURE Lo_Function(i: CARDINAL);
BEGIN
BlowUp(i);
EXCEPT
IF Exception() = Lo_Exception THEN
INC(lo);
RETURN;
END;
END Lo_Function;
PROCEDURE Hi_Function(i: CARDINAL);
BEGIN
Lo_Function(i);
EXCEPT
IF Exception() = Hi_Exception THEN
INC(hi);
RETURN;
END;
END Hi_Function;
PROCEDURE Some_Function(i: CARDINAL);
BEGIN
Hi_Function(i);
EXCEPT
WriteString("We shouldn't get here!");
WriteLn;
RETURN;
END Some_Function;
BEGIN
n := N();
lo := 0;
hi := 0;
EXCEPTIONS.AllocateSource(source);
WHILE n > 0 DO
DEC(n);
Some_Function(i);
END;
WriteString("Exceptions: HI="); WriteCard(hi,1);
WriteString(" / LO="); WriteCard(lo,1); WriteLn;
END Except.
|
Fibonacci Numbers |
(* The Great Win32 Language Shootout http://dada.perl.it/shootout/
contributed by Isaac Gouy (Modula2 novice)
To build: xc =m fibo
To run: fibo 32
*)
MODULE Fibo;
(* Prefer qualified procedures *)
IMPORT STextIO, SWholeIO, LanguageShootout;
PROCEDURE Fibo (n: CARDINAL) : CARDINAL;
BEGIN
IF n<2 THEN
RETURN 1;
ELSE
RETURN Fibo(n-2) + Fibo(n-1);
END;
END Fibo;
BEGIN
SWholeIO.WriteCard( Fibo( LanguageShootout.N() ),1);
STextIO.WriteLn;
END Fibo.
|
Hello World |
(* The Great Win32 Language Shootout http://dada.perl.it/shootout/
contributed by Isaac Gouy (Modula2 novice)
To build: xc =m hello
To run: hello
*)
MODULE Hello;
FROM STextIO IMPORT WriteString, WriteLn;
BEGIN
WriteString ("hello world"); WriteLn;
END Hello.
|
List Operations |
(* The Great Win32 Language Shootout http://dada.perl.it/shootout/
contributed by Isaac Gouy (Modula2 novice)
To compile: xc =m lists
To run: lists 16
*)
MODULE Lists;
<* m2extensions + *>
<* storage + *>
(* Prefer unqualified procedures *)
FROM LanguageShootout IMPORT N;
FROM STextIO IMPORT WriteString, WriteLn;
FROM SWholeIO IMPORT WriteCard;
(* We need an ADT let's implement a double-linked list *)
TYPE
Node_Ptr = POINTER TO Queue_Node;
Queue_Node =
RECORD
prev, next: Node_Ptr;
item: CARDINAL;
END;
Queue_Ptr = POINTER TO Queue_Type;
Queue_Type =
RECORD
first, last: Node_Ptr;
length: CARDINAL;
END;
Queue_Positions = (First, Last);
VAR node, node2: Node_Ptr;
PROCEDURE Initialize(VAR q: Queue_Ptr);
BEGIN
NEW(q);
q^.length := 0;
q^.first := NIL;
q^.last := NIL;
END Initialize;
PROCEDURE Add(position: Queue_Positions; VAR q: Queue_Ptr; item: CARDINAL);
BEGIN
NEW(node);
node^.item := item;
INC(q^.length);
IF q^.length = 1 THEN
node^.prev := NIL;
node^.next := NIL;
q^.first := node;
q^.last := node;
ELSE
IF position = First THEN
node^.prev := NIL;
node^.next := q^.first;
q^.first^.prev := node;
q^.first := node;
ELSE
node^.prev := q^.last;
node^.next := NIL;
q^.last^.next := node;
q^.last := node;
END;
END;
END Add;
PROCEDURE Remove(position: Queue_Positions; VAR q: Queue_Ptr): CARDINAL;
VAR item: CARDINAL;
BEGIN
IF q^.length = 0 THEN
RETURN 0;
END;
IF position = First THEN
node := q^.first;
ELSE
node := q^.last;
END;
item := node^.item;
DEC(q^.length);
IF q^.length = 0 THEN
q^.first := NIL;
q^.last := NIL;
ELSE
IF position = First THEN
q^.first := node^.next;
q^.first^.prev := NIL;
ELSE
q^.last := node^.prev;
q^.last^.next := NIL;
END;
END;
DISPOSE(node);
RETURN item;
END Remove;
PROCEDURE Dispose(VAR q: Queue_Ptr);
BEGIN
WHILE q^.first # NIL DO
node := q^.first^.next;
DISPOSE(q^.first);
q^.first := node;
END;
DISPOSE(q);
END Dispose;
PROCEDURE Copy(q: Queue_Ptr; VAR qcopy: Queue_Ptr);
BEGIN
node2 := q^.first ;
WHILE node2 # NIL DO
Add(Last, qcopy, node2^.item);
node2 := node2^.next;
END;
END Copy;
PROCEDURE Reverse(VAR q: Queue_Ptr);
BEGIN
node := q^.first;
q^.first := q^.last;
q^.last := node;
WHILE node # NIL DO
node2 := node^.next;
node^.next := node^.prev;
node^.prev := node2;
node := node2;
END;
END Reverse;
PROCEDURE Length(q: Queue_Ptr): CARDINAL;
BEGIN
RETURN q^.length;
END Length;
PROCEDURE FirstItem(q: Queue_Ptr): CARDINAL;
BEGIN
IF q^.length = 0 THEN
RETURN 0;
ELSE
RETURN q^.first^.item;
END;
END FirstItem;
PROCEDURE Equal(q,q2: Queue_Ptr): BOOLEAN;
BEGIN
IF q^.length # q2^.length THEN
RETURN FALSE;
END;
node := q^.first;
node2 := q2^.first;
WHILE node # NIL DO
IF node^.item # node2^.item THEN
RETURN FALSE;
END;
node := node^.next;
node2 := node2^.next;
END;
RETURN TRUE;
END Equal;
CONST SIZE = 10000;
VAR L1, L2, L3: Queue_Ptr;
i, m, n, lengthL1: CARDINAL;
BEGIN
n := N();
FOR m := 1 TO n DO
NEW(L1);
Initialize(L1);
FOR i := 1 TO SIZE DO
Add(Last, L1, i);
END;
NEW(L2);
Initialize(L2);
Copy(L1, L2);
NEW(L3);
Initialize(L3);
WHILE Length(L2) > 0 DO
Add(Last, L3, ( Remove(First, L2)) );
END;
WHILE Length(L3) > 0 DO
Add(Last, L2, ( Remove(Last, L3) ));
END;
Reverse(L1);
IF FirstItem(L1) # SIZE THEN
WriteString("First item of L1 # SIZE"); WriteLn;
END;
IF NOT Equal(L1, L2) THEN
WriteString("L1 # L2"); WriteLn;
END;
lengthL1 := Length(L1);
Dispose(L1);
Dispose(L2);
Dispose(L3);
END;
WriteCard(lengthL1,1); WriteLn;
END Lists.
|
Nested Loops |
(* The Great Win32 Language Shootout http://dada.perl.it/shootout/
contributed by Isaac Gouy (Modula2 novice)
To build: xc =m nestedloop
To run: nestedloop 16
*)
MODULE NestedLoop;
<* coverflow - *>
(* Prefer unqualified procedures *)
FROM LanguageShootout IMPORT N;
FROM STextIO IMPORT WriteLn;
FROM SWholeIO IMPORT WriteCard;
VAR
count: CARDINAL;
n, g, h, i, j, k, l: CARDINAL;
BEGIN
n := N();
count := 0;
FOR g := 1 TO n DO
FOR h := 1 TO n DO
FOR i := 1 TO n DO
FOR j := 1 TO n DO
FOR k := 1 TO n DO
FOR l := 1 TO n DO
INC(count);
END;
END;
END;
END;
END;
END;
WriteCard(count,1); WriteLn;
END NestedLoop.
|
Random Number Generator |
(* The Great Win32 Language Shootout http://dada.perl.it/shootout/
contributed by Isaac Gouy (Modula2 novice)
To build: xc =m random
To run: random 900000
*)
MODULE Random;
<* procinline + *>
<* ioverflow - *>
<* alignment="8" *>
(* Prefer unqualified procedures *)
FROM LanguageShootout IMPORT N;
FROM STextIO IMPORT WriteLn;
FROM SLongIO IMPORT WriteFixed;
CONST
IM = 139968;
IA = 3877;
IC = 29573;
VAR
n, last: INTEGER;
result: LONGREAL;
PROCEDURE Gen_Random(max: LONGREAL): LONGREAL;
BEGIN
last := (last*IA + IC) REM IM;
RETURN max * LFLOAT(last) / LFLOAT(IM);
END Gen_Random;
BEGIN
n := N();
last := 42;
WHILE n > 0 DO
DEC(n);
result := Gen_Random(100.0);
END;
WriteFixed(result,9,1); WriteLn;
END Random.
|
Sieve of Erathostenes |
(* The Great Win32 Language Shootout http://dada.perl.it/shootout/
contributed by Isaac Gouy (Modula2 novice)
To build: xc =m sieve
To run: sieve 900
*)
MODULE Sieve;
<* m2extensions + *>
<* checkindex - *>
<* coverflow - *>
(* Prefer unqualified procedures *)
FROM LanguageShootout IMPORT N;
FROM STextIO IMPORT WriteString, WriteLn;
FROM SWholeIO IMPORT WriteCard;
FROM SYSTEM IMPORT ADR, FILL;
CONST
start = 2;
stop = 8192;
TYPE Boolean_Array = ARRAY [start..stop] OF BOOLEAN;
VAR
array_size: CARDINAL;
n, count, i, k: CARDINAL;
isPrimeNumber: Boolean_Array;
BEGIN
n := N();
array_size := SIZE(Boolean_Array);
WHILE n > 0 DO
DEC(n);
count := 0;
(* Set all the isPrimeNumber array to TRUE *)
FILL( ADR(isPrimeNumber), TRUE, array_size );
FOR i := start TO stop DO
IF isPrimeNumber[i] THEN
INC(count);
k := i+i;
WHILE k <= stop DO
isPrimeNumber[k] := FALSE;
INC(k, i);
END;
END;
END;
END;
WriteString("Count:"); WriteCard(count,0); WriteLn;
END Sieve.
|