(*
Title:  (*
Title:   Vectors
Author:  Xiaoyang Yu
Revised: 25-OCT-2002
  
Description: Implement MIS for Vectors ADT: Pointer, Record and Array.

Module Interface Specification:
INTERFACE Vectors;
TYPE Vector;
CONST Zero: Vector;
PROCEDURE GetVec(x,y: REAL): Vector;
PROCEDURE XVal(v: Vector): REAL;
PROCEDURE YVal(v: Vector): REAL;
PROCEDURE Add(u,v: Vector): Vector;
PROCEDURE Mul(r: REAL; v: Vector): Vector;
END Vectors.
*)


MODULE Vectors;

IMPORT Out;

(* Type Definition *)
TYPE
  Vector* = POINTER TO RECORD
      x,y: REAL;
  END;

(* Constants and variables *)
CONST VecSize = 1000;           (* Maximum Vector Array Size *)

VAR   
   i: INTEGER;
   Zero-: Vector;   
   VecPtr: ARRAY VecSize OF Vector;  (* Vector Pointer Array *)

(* Interface Procedures *)
(* Return the pointer of Vector ( x, y ). *)
PROCEDURE GetVec*(x,y: REAL): Vector;
VAR j: INTEGER;
    v: Vector;
BEGIN
  j := 0;
  v := VecPtr[j];
  
  WHILE (v # NIL) & (j < VecSize) DO  
    IF (v^.x = x) & (v^.y = y) THEN 
         RETURN v; 
    ELSE INC(j);
         v := VecPtr[j];
    END;   
  END;
  
  IF (v = NIL) THEN 
    NEW(v);
    v^.x := x;    v^.y := y;
    VecPtr[j] := v;
    RETURN v;
  END;
  
  IF ( j = VecSize) THEN 
    FullArrayException()
  END;
END GetVec;

(* Return XVal of Vector v. *)
PROCEDURE XVal*(v: Vector): REAL;
BEGIN
  RETURN v^.x;
END XVal;

(* Return YVal of Vector v. *)
PROCEDURE YVal*(v: Vector): REAL;
BEGIN
  RETURN v^.y; 
END YVal;

(* Add Vector u and Vector v. *)
PROCEDURE Add*(u,v: Vector): Vector;
VAR x,y: REAL;
    sum: Vector;
BEGIN
  x := u^.x + v^.x;
  y := u^.y + v^.y;
  sum := GetVec(x,y);
  RETURN sum;
END Add;

(* Multiple r and Vector v. *)
PROCEDURE Mul*(r: REAL; v: Vector): Vector;
VAR x,y: REAL;
    mul: Vector;
BEGIN
   x := v^.x * r;
   y := v^.y * r;
   mul := GetVec(x,y);
   RETURN mul;
END Mul;

(* Array full exception *)
PROCEDURE FullArrayException();
BEGIN
  Out.String("FullArrayException: The array is full.");
  HALT(1)  (* Abort program *)
END FullArrayException;

BEGIN
   (* initialize *)
   FOR i:=0 TO VecSize-1 DO VecPtr[i] := NIL END;
   
   NEW(Zero); 
   Zero^.x := 0;    
   Zero^.y := 0;
   VecPtr[0] := Zero;
END Vectors.