cm3/src/M3Unit.m3


 Copyright 1996-2000 Critical Mass, Inc. All rights reserved.    
 See file COPYRIGHT-CMASS for details. 

MODULE M3Unit;

IMPORT IntRefTbl, M3ID, M3Loc, M3Path;
IMPORT Msg;

PROCEDURE InitSet (VAR x: Set) =
  BEGIN
    x.map  := NEW (IntRefTbl.Default).init ();
    x.head := NIL;
    x.tail := NIL;
  END InitSet;

PROCEDURE Add (VAR x: Set;  t: T) =
  VAR ref: REFANY;  tt: T;
  BEGIN
    (* update the name table *)
    IF x.map.get (t.name, ref) THEN
      (* check for an existing match *)
      tt := NARROW (ref, T);
      WHILE (tt # NIL) DO
        IF (tt.name = t.name) AND (tt.kind = t.kind) THEN
          IF (tt.loc # t.loc) THEN
            Msg.FatalError (NIL, "duplicate unit: ", FullPath (tt),
                                                " ", FullPath (t));
          END;
          RETURN;
        END;
        tt := tt.next_synonym;
      END;

      (* insert into the existing list *)
      <*ASSERT t.next_synonym = NIL*>
      tt := NARROW (ref, T);
      t.next_synonym := tt.next_synonym;
      tt.next_synonym := t;
    ELSE
      (* start a new list *)
      EVAL x.map.put (t.name, t);
    END;

    (* append to the linked list *)
    IF (x.head = NIL)
      THEN x.head := t;
      ELSE x.tail.next := t;
    END;
    x.tail := t;
  END Add;

PROCEDURE Get (READONLY x: Set;  nm: M3ID.T;  k: Kind): T =
  VAR ref: REFANY;  t: T;
  BEGIN
    IF x.map.get (nm, ref) THEN
      t := ref;
      WHILE (t # NIL) DO
        IF (t.kind = k) THEN RETURN t; END;
        t := t.next_synonym;
      END;
    END;
    RETURN NIL;
  END Get;

PROCEDURE New (nm: M3ID.T;  k: Kind;  loc: M3Loc.T;  hidden, imported: BOOLEAN): T =
  BEGIN
    RETURN NEW (T, name := nm, kind := k, loc := loc,
                hidden := hidden, imported := imported);
  END New;

PROCEDURE AddNew (VAR x: Set;  nm: M3ID.T;  k: Kind;  loc: M3Loc.T;
                  hidden, imported: BOOLEAN) =
  BEGIN
    Add (x, New (nm, k, loc, hidden, imported));
  END AddNew;

PROCEDURE FileName (t: T): TEXT =
  VAR nm := M3ID.ToText (t.name);
  BEGIN
    RETURN M3Path.Join (NIL, nm, t.kind);
  END FileName;

PROCEDURE FullPath (t: T): TEXT =
  VAR nm := M3ID.ToText (t.name);
  BEGIN
    RETURN M3Path.Join (t.loc.path, nm, t.kind);
  END FullPath;

BEGIN
END M3Unit.

interface M3ID is in:


interface M3Path is in:


interface Msg is in: