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}