IMPLEMENTATION MODULE YaflGCode;

FROM Streams    IMPORT StdOut;
FROM YaflParser IMPORT NonTerminal;
FROM CGMethods  IMPORT CMethDefCodeGenerator;
FROM YaflCfg IMPORT CurrentSpot;
FROM YaflModules IMPORT DefinitionModule;
FROM CGCode IMPORT CGcContext;

  CLASS GC(ObjType IN NonTerminal, CtxType IN GcContext);
                        
    VAR
      TheObj: ObjType;
      TheCtx: CtxType;
       
    REDEFINE METHOD CREATE(Object: ObjType);
      BEGIN 
      TheObj := Object;
      TheCtx := GetFatherCtx;
      END CREATE;
       
    METHOD GetFatherCtx: CtxType;
      VAR
        tmp: NonTerminal;
        TheCGcContext: CGcContext;
      BEGIN
      WHILE (tmp <> VOID) AND NOT tmp.GcIsAttached DO
        tmp := tmp.Father;
        END;
      IF tmp = VOID THEN
        tmp := CurrentSpot.CurrentModule;
        END;
      IF tmp = VOID THEN -- OOO Desperate Case
        TheCGcContext.CREATE;
        WHAT TheCGcContext OF
          IN CtxType:
            RESULT := TAG;
            END;
          END;
       ELSE
         WHAT tmp.Gc OF 
           IN GC: 
              WHAT TAG.Ctx OF
               IN CtxType:
                 RESULT := TAG;
                 END;
               END; -- WHAT
             END;
           END; -- WHAT
         END;
      ASSERT RESULT <> VOID;
      END GetFatherCtx;

    METHOD Obj: ObjType;
      BEGIN   
      RESULT := TheObj;
      END Obj;   

    METHOD Ctx: CtxType;
      BEGIN
      RESULT := TheCtx;
      END Ctx;

    METHOD Number: INTEGER;
      BEGIN
      RESULT := TheObj.HashValue;
      END Number;

    METHOD GenerateCode;
      BEGIN
      StdOut.WriteString ("Non-redefined code generation method: " + WhatAmI);
      StdOut.WriteLn;
      StdOut.WriteString ("Related object : " + TheObj.WhatAmI);
      StdOut.WriteLn;
      END GenerateCode;

    METHOD WhatAmI: ARRAY OF CHAR;
      BEGIN
      RESULT := "Generic Code Generator (" + TheObj.WhatAmI + ")";
      END WhatAmI;      

   END GC;
   
------------------------------------------------

  --------------------------------------------------------
  -- this class is just designed to be used as instance
  -- parameter for the parameterized classes which do 
  -- not really need a CodeGenerator (because we do not
  -- generate any code for these classes), but since 
  -- these classes inherits from NonTerminal we need 
  -- to instanciate the formal parameter gc.
  --------------------------------------------------------
  CLASS DummyNTCodeGenerator(CtxType IN GcContext);
    INHERITS GC(NonTerminal, CtxType);
    
  END DummyNTCodeGenerator;

----------------------------------------   

  CLASS GcContext (Obj IN ImplementationModule);

  END GcContext;

  CLASS DummyGcContext;
    INHERITS GcContext(ImplementationModule);

  END DummyGcContext;

END YaflGCode;



