DEFINITION MODULE Dict;

(*
    Title    : Dictionary Management System
    LastEdit : Thu Aug 16 11:26:29 1984
    Author   : LDS & GT
    Acorn Computers VLSI Design Aids Group
*)

(*------------------------------------------------------------------------*)
(* Dictionaries are tables. They support more sophisticated key           *)
(* matching than the old Stab. Destruction of dictionaries is not supp-   *)
(* orted. Dictionaries cannot be made persistent at the present time.     *)
(*------------------------------------------------------------------------*)

FROM SYSTEM  IMPORT WORD;
FROM nString  IMPORT STRING;

EXPORT  QUALIFIED   DICT, KeyMatchOptions, KeyAttr, CSCANPROC, ERRORCODE,
                    NewDict, Enter, Found, FoundWith, FoundExp, FoundWithExp,
                    Remove, ForAllIn;

TYPE        HIDDEN;
        CSCANPROC = PROCEDURE(VAR ARRAY OF CHAR, WORD, VAR WORD) :BOOLEAN;
	
  KeyMatchOptions = (ExactLength,   NoExactLength,   (* Must be same length *)
                     ExactCase,     NoExactCase);    (* Must be same case   *)
          KeyAttr = SET OF KeyMatchOptions;
	  
        ERRORCODE = (NoError, NotFound, Ambiguous);
	
             DICT = POINTER TO RECORD
		      Silent :BOOLEAN;  (* set by user to suppress msgs. *)
                   ErrorCode :ERRORCODE;(* useful if Silent...           *)
                        Name :STRING;
              LastKeyMatched :STRING;   (* set up by 'Found' to expand   *)
              Implementation :HIDDEN;   (* abbreviation                  *)
                    END;

PROCEDURE NewDict(name :ARRAY OF CHAR) :DICT;
  (* name is used ONLY for error reporting purposes *)

PROCEDURE Enter(dict :DICT;
                 Key :ARRAY OF CHAR;  KeyAttributes :KeyAttr;  Item :WORD);
  (* KeyAttributes will usually be KeyAttr{}, denoting that a minimum    *)
  (* prefix match in any character case will suffice, and that in case   *)
  (* of ambiguity, an error result will be returned.                     *)
  (* However, if KeyAttr{ExactLength} is given, the key string will only *)
  (* match a string of the same length, unless overridden by a parameter *)
  (* of 'KeyAttr{NoExactLength}' in the 'FoundWith' call.                *)

(*------------------------------------------------------------------------*)
(*  Note:    Enter (Dict, "key", KeyAttr{}, String.CopyCS(CharArray))     *)
(*        is valid, BUT                                                   *)
(*           StringV := String.CopyCS(CharArray);                         *)
(*           Enter (Dict, "key", KeyAttr{}, StringV);                     *)
(*           String.Dispose (StringV)                                     *)
(*        is not. Once bitten twice shy.                                  *)
(*------------------------------------------------------------------------*)

PROCEDURE Found(dict :DICT;  Key :STRING;  VAR Val :WORD) :BOOLEAN;
PROCEDURE FoundWith(Attribute :KeyAttr;
           dict :DICT;  Key :STRING;  VAR Val :WORD) :BOOLEAN;
  (* Attributes explicitly given here will over-ride any set in the    *)
  (* 'Enter' call. Attributes not mentioned will be left untouched.    *)
PROCEDURE FoundExp(dict     :DICT;  Key :STRING;  VAR Val :WORD;
               VAR Expanded :STRING) :BOOLEAN;
PROCEDURE FoundWithExp(Attribute :KeyAttr;     dict :DICT;
                       Key       :STRING;  VAR Val  :WORD;
                   VAR Expanded  :STRING)                   :BOOLEAN;
(* 'Exp' calls return the exact keyword with which 'Key' matched. *)
(* This may be longer that 'Key' or in a different case.          *)
PROCEDURE Remove(dict :DICT;  VAR Key :ARRAY OF CHAR);
  (* No boolean is returned, but the Dict return code can be tested.   *)

PROCEDURE ForAllIn(dict :DICT;  Do :CSCANPROC;  VAR parm :WORD) :BOOLEAN;
  (* continue scanning while CSCANPROC returns FALSE *)
END Dict.
