marcov hat geschrieben:Nutzung bevor Deklaration ist komplizierter, speziell in für gezielter Warnungen und andere Fehler.
Du meinst Mehraufwand im Compiler? Das ist keine Begründung um eine bessere Sprachstruktur zu verhindern.
MSElang parst die property Elemente mitsamt ihren source-Referenzen in eine Struktur
Code: Alles auswählen
type
identsourceinfoty = record
ident: identty;
source: sourceinfoty;
end;
identsourcevecty = record
high: integer;
d: array[0..maxidentvector] of identsourceinfoty;
end;
propfieldinfoty = record
propele: elementoffsetty;
propoffs: int32;
idents: identsourcevecty;
end;
ppropfieldinfoty = ^propfieldinfoty;
indexparaminfoty = record
partype: elementoffsetty;
parflags: addressflagsty;
end;
indexparamvecty = record
high: int32;
d: array[0..maxidentvector] of indexparaminfoty;
end;
resolvepropertyinfoty = record
errorref: int32;
propflags: propflagsty;
typeele: elementoffsetty;
indilev: int32;
indexparams: indexparamvecty;
readfield: propfieldinfoty;
writefield: propfieldinfoty;
end;
presolvepropertyinfoty = ^resolvepropertyinfoty;
danach wird geprüft, ob der accessor bereits deklariert ist
Code: Alles auswählen
function resolvepropaccessor(var resinfo: resolvepropertyinfoty;
const awrite: boolean): boolean;
[...]
begin
result:= false;
if awrite then begin
field:= @resinfo.writefield;
end
else begin
field:= @resinfo.readfield;
end;
hasindex:= resinfo.indexparams.high >= 0;
with resinfo,field^ do begin
elekind1:= ele.findcurrent(idents.d[0].ident,[],[vik_ancestor],po1);
ele1:= ele.eledatarel(po1);
case elekind1 of
ek_none: begin
if awrite then begin
fla1:= pof_writeforward;
end
else begin
fla1:= pof_readforward;
end;
if fla1 in propflags then begin
identerror(idents.d[0].source,idents.d[0].ident,err_identifiernotfound);
end
else begin
include(propflags,fla1);
end;
end;
[...]
falls nicht wird die property in eine Liste eingetragen und resolvepropacessor() am Ende der Klassendefinition nochmals aufgerufen.
Code: Alles auswählen
procedure handleclassproperty();
[...]
if resinfo^.propflags * [pof_readforward,pof_writeforward] <> [] then begin
with pclasspendingitemty(
addlistitem(pendingclassitems,
forwardpropchain))^ do begin
forwardprop.resinfo:= getsegmentoffset(seg_temp,resinfo);
forwardprop.propele:= ele.eledatarel(po1);
end;
end
else begin
updateprop(resinfo^,po1);
setsegmenttop(seg_temp,resinfo);
end;
[...]
procedure resolveforwardprop(var item);
var
p1: presolvepropertyinfoty;
begin
with classpendingitemty(item).forwardprop do begin
p1:= getsegmentpo(seg_temp,resinfo);
if pof_readforward in p1^.propflags then begin
resolvepropaccessor(p1^,false);
end;
if pof_writeforward in p1^.propflags then begin
resolvepropaccessor(p1^,true);
end;
updateprop(p1^,ele.eledataabs(propele));
end;
end;
procedure handleclassdefreturn();
[...]
resolvelist(pendingclassitems,@resolveforwardprop,forwardpropchain);
Die Möglichkeiten zur Fehlerbehandlung sind beide mal die gleichen.