IMPLEMENTATION MODULE Modules;          

FROM List IMPORT List;
FROM Streams IMPORT OutputStream, StdOut;
IMPORT String;
IMPORT SYSTEM;
IMPORT Stack;
                                     
INLINE
  %#include <assert.h>
  END;

---------------------------------------------
  CLASS Module;
    INHERITS StringElement;

    VAR
      Ptr: INTEGER;
    PRAGMA
      VarType (Ptr, "module_dual*");

    VAR
      TheLines: INTEGER;

    METHOD Name: ARRAY OF CHAR;
      BEGIN
      RESULT := Get;
      END Name;

    REDEFINE METHOD CREATE(Name: ARRAY OF CHAR);
      BEGIN
      BASE (Name); 
      INLINE
        % {
        % module_dual *d;
        %
        % extern module_dual* get_module_by_name YARGS((char*));
        %
        % d = get_module_by_name(Y_Name);
        % THIS->Y_Ptr = d;
     	% THIS->Y_TheLines = d->line_count;
        %}
        END;
      END CREATE;

    METHOD Lines: INTEGER;
      BEGIN
      RESULT := TheLines;
      END Lines;

    METHOD LineMap: ARRAY OF INTEGER;
      BEGIN
      INLINE
        % {
        %   extern obj_ptr clone_profile_info YARGS((module_dual * pm));
        %   Y_RESULT = clone_profile_info (THIS->Y_Ptr);
        % }
        END;
      END LineMap;

    METHOD PrepareLineMap;
      BEGIN
      INLINE
        % {
        %   reset_profile_info(THIS->Y_Ptr);
        % }
        END;
      END PrepareLineMap;

  END Module;
---------------------------------------------
  ONCE CLASS ModuleDictionary;
    INHERITS List(Module);

    REDEFINE METHOD CREATE;
      VAR
        j, MaxModules: INTEGER;
        Mod: Module;
        Name: ARRAY OF CHAR;
      BEGIN
      BASE;
      INLINE
        % {
        %   extern unsigned get_module_count YARGS((void));
        %   Y_MaxModules = get_module_count();
        % }
        END;
      FOR i := 0 TO MaxModules - 1 DO
        j := i;
        INLINE
          % {
          % module_dual *d;
          % extern module_dual* get_module YARGS((unsigned));
          % 
          % d = get_module(Y_j);
          % Y_Name = new_string(d->name);
          % }
          END;
        Mod.CREATE (Name);
        Append (Mod);
        END;
      END CREATE;

    METHOD PrepareMaps;
      BEGIN
      FOR i := 0 TO Size - 1 DO
        Get(i).PrepareLineMap;
        END;
      END PrepareMaps;

  END ModuleDictionary;

END Modules;
