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}