This patch allows forward object declarations, in the same manner as delphi. To pre-declare an object, use a semicolon after the object keyword.

Example:

Type

forwardObject = Object;  {forward declaration}
myObject = Object
  count: integer;
  procedure init;
  function createForwardObject: forwardObject;
end;

fowardObject = Object (myObject)
  procedure init; override;
end;


Files: pcommon.pas, call.pas, parser.pas

File pcommon.pas, line 130 (structure definition)

Old Code:

  objects:  (objfld: ctp;    {object fields}
    objsize: addrrange;      {object size}
    objname: pstringptr;     {object name}
    objlevel: integer;       {generation level}
    objparent: stp;          {parent or nil}
  );

New Code:

  objects:  (objfld: ctp;    {object fields}
    objsize: addrrange;      {object size}
    objname: pstringptr;     {object name}
    objlevel: integer;       {generation level}
    objparent: stp;          {parent or nil}
    objdef: boolean;         {false if not yet defined}
  );

File call.pas, line 1284 (function DoNew)

Old Code:

    else if form = objects then begin
      lsize := objsize;
      ofld := objfld;
      end {else if}
    else
      Error(44);

New code:

    else if (form = objects) and (objdef) then begin
      lsize := objsize;
      ofld := objfld;
      end {else if}
    else
      Error(44);

File parser.pas, Line 119, (variable declaration)

Old Code:

  objectType: stp;          {type of method's object}

New Code:

  objectType: stp;          {type of method's object}
  objptr: ctp;              {linked list of objects}

File parser.pas, Line 5021, (function InitScalars)

Old Code:

  fwptr := nil;

New Code:

  fwptr := nil;
  objptr := nil;

File parser.pas, Line 1054, (function Typ)

Old Code:

      else if sy = objectsy then begin
        InSymbol;

        {make sure we are declaring a type}
        if not isType then
          Error(127);

        {set up a new display}
        oldtop := top;
        if top < displimit then begin
          top := top+1;
          with display[top] do begin
            fname := nil;
            flabel := nil;
            labsused := nil;
            occur := rec;
          end
        end
        else
          Error(107);
        disp1 := 6;

        {set up the type}
        lsp := pointer(Malloc(sizeof(structure)));
        with lsp^ do begin
          form := objects;
          objname := nil;
          objsize := 6;
          objlevel := 1;
          objparent := nil;
          size := ptrsize;
        end; {with}

        {handle inheritance}
        if sy = lparent then begin
          InSymbol;
          if sy = ident then begin
            SearchId([types], lcp2);
            if lcp2 <> nil then begin
              if lcp2^.idtype <> nil then
                if lcp2^.idtype^.form = objects then begin
                  Duplicate(display[top].fname, lcp2^.idtype^.objfld);
                  disp1 := lcp2^.idtype^.objsize;
                  lsp^.objparent := lcp2^.idtype;
                  lsp^.objlevel := lcp2^.idtype^.objlevel + 1;
                end {if}
                else
                  Error(129);
            end {if}
            else
              Error(33);
            InSymbol;
          end {if}
          else
            Error(128);
          Match(rparent,4);
        end; {if}

        {compile the fields and methods}
        if sy in typebegsys then
          FieldList(fsys-[semicolon]+[endsy,procsy,funcsy], lsp1,
            lsp^.hasSFile, true);
        objectType := lsp;
        ttop := top;
        top := oldtop;
        EnterId(objectcp);
        top := ttop;
        objectcp^.idtype := lsp;
        ProcList(fsys-[semicolon]+[endsy]);
        if disp1 > $010000 then
          if SmallMemoryModel then
            Error(122);
        lsp^.objfld := display[top].fname;
        lsp^.objsize := disp1;

        lsp^.ispacked := ispacked;
        ExportUses;
        top := oldtop;
        Match(endsy,13);
      end {else if}

New Code: (some new code, some old code moved around)

      else if sy = objectsy then begin
        InSymbol;

        {make sure we are declaring a type}
        if not isType then
          Error(127);

        (* kws -- check for previous forward declaration *)
		lsp := nil;
		lcp := objptr;
		while (lcp <> nil) and (CompNames(objectName, lcp^.name^) <> 0)
		  do lcp := lcp^.next;
		if lcp <> nil then lsp := lcp^.idtype;
		if (sy <> semicolon) and (lsp <> nil) and (lsp^.objdef) then lsp := nil;
		
		if lsp <> nil then begin
        {set up the type}
        lsp := pointer(Malloc(sizeof(structure)));
          with lsp^ do begin
            form := objects;
            objname := nil;
            objsize := 6;
            objlevel := 1;
            objparent := nil;
            size := ptrsize;
            hasSFile := false;
          end; {with}		
		end;
		
		(* kws -- forward declaration *)
		if sy = semicolon then begin
		  { if lcp is defined, then it's already been declared, do nothing }
		  if lcp = nil then begin
		    lsp^.objdef := false;
			objectcp^.idtype := lsp;
			EnterId(objectcp);
			objectcp^.next := objptr;
			objptr := objectcp;
		  end;
		end else begin

          {set up a new display}
          oldtop := top;
          if top < displimit then begin
            top := top+1;
            with display[top] do begin
              fname := nil;
              flabel := nil;
              labsused := nil;
              occur := rec;
            end
          end
          else
            Error(107);
          disp1 := 6;

          {handle inheritance}
          if sy = lparent then begin
            InSymbol;
            if sy = ident then begin
              SearchId([types], lcp2);
              if lcp2 <> nil then begin
                if lcp2^.idtype <> nil then
                  if (lcp2^.idtype^.form = objects) and (lcp2^.idtype^.objdef) then begin
                    Duplicate(display[top].fname, lcp2^.idtype^.objfld);
                    disp1 := lcp2^.idtype^.objsize;
                    lsp^.objparent := lcp2^.idtype;
                    lsp^.objlevel := lcp2^.idtype^.objlevel + 1;
                  end {if}
                  else
                    Error(129);
              end {if}
              else
                Error(33);
              InSymbol;
            end {if}
            else
              Error(128);
            Match(rparent,4);
          end; {if}

          {compile the fields and methods}
          if sy in typebegsys then
            FieldList(fsys-[semicolon]+[endsy,procsy,funcsy], lsp1,
              lsp^.hasSFile, true);
          objectType := lsp;
          if lsp^.objdef then begin
            ttop := top;
            top := oldtop;
            objectcp^.idtype := lsp;			
            EnterId(objectcp);
            objectcp^.next := objptr;
            objptr := objectcp;			
            top := ttop;
          end;
          lsp^.objdef := true;
		  
          ProcList(fsys-[semicolon]+[endsy]);
          if disp1 > $010000 then
            if SmallMemoryModel then
              Error(122);
          lsp^.objfld := display[top].fname;
          lsp^.objsize := disp1;

          lsp^.ispacked := ispacked;
          ExportUses;
          top := oldtop;
          Match(endsy,13);
		end; {if not forward declaration}
      end {else if}