From: g_dotzel@tron.gun.de (Guenter Dotzel)
Newsgroups: comp.lang.modula2
Subject: Re^2: Dynamic arrays in Modula-2?
Date: Wed, 15 Apr 92 07:00:03 GMT

INFO-M2\%UCF1VM.BITNET%cmsa.Berkeley.EDU@USENET.ZER wrote on Sun, 04-12-1992 at 14:38 h
under the subject 'Re: Dynamic arrays in Modula-2?':

> From: andrea@ESSEX.STFX.CA (John Andrea)
> Reply-To: Modula2 List <INFO-M2%UCF1VM.BITNET@cmsa.Berkeley.EDU>
> Subject: Re: Dynamic arrays in Modula-2?

John,

some modifications just to show how your example looks when written in ISO M-2:

MODULE DynamicArray;

(* This ISO Modula-2 program shows how to build and use dynamic memory as if its an array *)
(* This specific example shows the use of memory as an ARRAY OF CARDINAL *)
(* J. Andrea, Mar.16/92 *)
(* This code may be freely used and distributed, it may not be sold. *)
(* converted to ISO Modula-2 by G_Dotzel@ame.nbg.sub.org, 14-Apr-1992 *)

FROM SYSTEM  IMPORT ADDRESS, ADDADR, CAST, TSIZE;
FROM Storage IMPORT ALLOCATE, DEALLOCATE;
FROM SWholeIO IMPORT WriteCard;
FROM STextIO IMPORT WriteLn; 

TYPE
  Dyn = RECORD                   (*this type contains the two essential items *)
          size  :CARDINAL;       (* the size of the array, and *)
          start :ADDRESS;        (* the memory address of the first element *)
        END;

VAR
  dyn       :Dyn;                      (* simple example here, use a variable *)
  type_size :CARDINAL;                 (* this will be size of items *)
  adr       :POINTER TO CARDINAL;      (* pointer to any single item *)
  i, n      :CARDINAL;                 (* typical counters *)

  PROCEDURE Make( length :CARDINAL );
  (* create a new dynamic array with the number of elements in 'length' *)
  BEGIN
     dyn.size := length;
     ALLOCATE(dyn.start, type_size * length);    (* grab the memory *)
                                                 (* specify number of bytes *)
  END Make;

  PROCEDURE Put( pos :CARDINAL; value :CARDINAL );
  (* put 'value' into the array at element 'pos' *)
  BEGIN
    (* make sure the specified element is available *)
    IF ( pos >= 1 ) & ( pos <= dyn.size ) THEN
      adr := ADDADR(dyn.start, (pos-1)*type_size);   (* calculate the address *)
                                                     (* by offset from #1     *)
      adr^ := value;                                 (* point to that element *)
    END;
  END Put;

  PROCEDURE Get( pos :CARDINAL ) :CARDINAL;
  (* return the element at position 'pos' *)
  VAR
    value :CARDINAL;
  BEGIN
    (* make sure the specified element is available *)
    IF ( pos >= 1 ) & ( pos <= dyn.size ) THEN
      adr   := ADDADR(dyn.start, (pos-1) * type_size);(* calculate to address *)
                                                      (* by offset from #1 *)
      value := adr^;                                  (* point to it *)
    ELSE
      HALT
    END;
    RETURN value;
  END Get;

BEGIN
  type_size := TSIZE( CARDINAL );     (*get the number of bytes in a CARDINAL *)
  n := 10;                            (* choose 10 elements *)
  Make( n );                          (* create the dynamic array *)
  FOR i := 1 TO n DO                  (* load the values 10,9,8,7... *)
    Put( i, n+1-i );
  END;
  FOR i := 1 TO n DO                     (* read the items and print them *)
    WriteCard( Get( i ), 0 ); WriteLn;
  END;
END DynamicArray.

Yes, it works fine!

Cheers, G~unter

Guenter Dotzel, ModulaWare GmbH, Wilhelmstr. 17A, D-W 8520 Erlangen/F.R.Germany
Tel. +49 (9131) 208395, Fax +49 (9131) 28205. 
E-mail/Internet:  g_dotzel@ame.nbg.sub.org 
E-Mail/CompuServe:100023.2527@compuserve.com