Faculty of Information Technology Programming Languages and Systems
Skip to Content
QUT Home FIT Home PLAS Home Projects People Wiki Contacts
 
     

An example program

   

This program defines a linked list record type, List (along with a pointer type PList) that stores values of type PDisplayable. The PDisplayable type can be thought of as an 'abstract class' that defines a Display method, even though IMCP does not support abstract classes directly. The Integer type is a 'wrapper class' for INTEGER primitives, and extends the Displayable type. For the purposes of convenience, we define a Helper type that is used to store a simple 'constructor' method, NewPInteger. (The typical convention in Component Pascal is to write a 'constructor' procedure for each record type, but as IMCP does not support non-method procedures we must define the constructor for a record type).

The main body of the program constructs a new list, insert elements into that list, and then extracts the first and last elements of the list. Notice that we downcast the list elements to their dynamic type, PInteger, in order to get at the val field. This is an example, admittedly somewhat contrived, of a typical object-oriented programming paradigm for collections classes in which the stored elements need to be downcast when extracted from the collection. This weakness in the type system is rectified with the introduction of generics in IMCPG.

The other example of a slightly restrictive style in this program is the use of PDisplayable as the element type in the list; the introduction of interfaces in IMCPI makes the program a little more natural.

MODULE ListMod; (* Example program for Imperative MCP *)

TYPE
  (* An 'abstract' supertype for 'displayable' records *)
  Displayable = EXTENSIBLE RECORD (ANYREC) END;
  PDisplayable = POINTER TO Displayable;

  (* A simple wrapper record to use in our linked list *)
  Integer = EXTENSIBLE RECORD (Displayable)
    val: INTEGER;
  END;
  PInteger = POINTER TO Integer;

  (* A linked list of PDisplayable elements *)
  List = EXTENSIBLE RECORD (Displayable)
    head: PDisplayable;
    tail: PList;
  END;
  PList = POINTER TO List;

  (* A helper class containing useful constructors *)
  Helper = RECORD (ANYREC) END;
  PHelper = POINTER TO Helper;

VAR
  list: PList;          (* the root node of our linked list *)
  helper: PHelper;      (* our helper object *)
  head: PDisplayable;   (* we will store the head of the list here *)

PROCEDURE (this: PDisplayable) Display (), NEW, EXTENSIBLE;
BEGIN
  util.WriteString("PDisplayable.Display()\n");
END Display;

PROCEDURE (this: PInteger) Display ();
BEGIN
  util.WriteInt(this.val);
END Display;

PROCEDURE (this: PList) Display ();
BEGIN
  IF util.Not(util.PEquals(this.head, NIL)) THEN
    this.head.Display();
  END;
  util.WriteString("\n");
  IF util.Not(util.PEquals(this.tail, NIL)) THEN
    this.tail.Display();
  END;
END Display;

PROCEDURE (this: PList) Insert (elem: PDisplayable), NEW, EXTENSIBLE;
VAR
  newList: PList;
BEGIN
  IF util.Not(util.PEquals(this.tail, NIL)) THEN
    this.tail.Insert(elem);
  ELSE
    NEW(newList);
    newList.head := elem;
    this.tail := newList;
  END;
END Insert;

PROCEDURE (this: PList) Head (): PDisplayable, NEW, EXTENSIBLE;
BEGIN
  RETURN this.head;
END Head;

PROCEDURE (this: PList) Last (): PDisplayable, NEW, EXTENSIBLE;
VAR
  retVal: PDisplayable;
BEGIN
  IF util.Not(util.PEquals(this.tail, NIL)) THEN
    retVal := this.tail.Last();
  ELSE
    retVal := this.head;
  END;
  RETURN retVal;
END Last;

PROCEDURE (this: PHelper) NewPInteger (val: INTEGER): PInteger, NEW;
VAR
  p: PInteger;
BEGIN
  NEW(p);
  p.val := val;
  RETURN p;
END NewPInteger;

BEGIN
  util.WriteString("ListMod test program\n");
  NEW(list);
  NEW(helper);
  list.head := helper.NewPInteger(5);
  list.Insert(helper.NewPInteger(10));
  list.Insert(helper.NewPInteger(12));
  list.Display();
  head := list.Head();
  WITH head: PInteger DO
    util.WriteInt(head.val);
    util.WriteString("\n");
  END;
  head := list.Last();
  WITH head: PInteger DO
    util.WriteInt(head.val);
    util.WriteString("\n");
  END;
END ListMod.

PLAS
Projects
  ActiveSheets
  Bioinformatics
  ConcernMaps
  ELP
  ELP.NET
  G2 Cluster Computing
  Generics
    Mini Component Pascal
      Background
      FMCP
      IMCP
      Metavariables etc
        Abstract syntax
        Type rules
        Auxiliary definitions
      Example program
      IMCPI
      IMCPG
      Cardelli type inferencer
      Online compilers
  Gardens Point Component Pascal
  Gardens Point Flow
  Gardens Point Modula
  Gardens Point Service Language
  Language Processing Tools
  Mentok
  Metaphor
  Mobilizer
  RikWik
  Ruby.NET
People
Wiki
Contacts