fpc/compiler/symppu.pas
2000-12-25 00:07:25 +00:00

352 lines
9.8 KiB
ObjectPascal

{
$Id$
Copyright (c) 1998-2000 by Florian Klaempfl, Pierre Muller
Implementation of the reading of PPU Files for the symtable
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
unit symppu;
interface
uses
cobjects,
globtype,globals,
symbase,
ppu;
var
current_ppu : pppufile; { Current ppufile which is read }
procedure writebyte(b:byte);
procedure writeword(w:word);
procedure writelong(l:longint);
procedure writereal(d:bestreal);
procedure writestring(const s:string);
procedure writenormalset(var s); {You cannot pass an array[0..31] of byte!}
procedure writesmallset(var s);
procedure writeguid(var g: tguid);
procedure writeposinfo(const p:tfileposinfo);
procedure writederef(p : psymtableentry);
function readbyte:byte;
function readword:word;
function readlong:longint;
function readreal : bestreal;
function readstring : string;
procedure readnormalset(var s); {You cannot pass an array [0..31] of byte.}
procedure readsmallset(var s);
procedure readguid(var g: tguid);
procedure readposinfo(var p:tfileposinfo);
function readderef : psymtableentry;
procedure closecurrentppu;
implementation
uses
symconst,
verbose;
{*****************************************************************************
PPU Writing
*****************************************************************************}
procedure writebyte(b:byte);
begin
current_ppu^.putbyte(b);
end;
procedure writeword(w:word);
begin
current_ppu^.putword(w);
end;
procedure writelong(l:longint);
begin
current_ppu^.putlongint(l);
end;
procedure writereal(d:bestreal);
begin
current_ppu^.putreal(d);
end;
procedure writestring(const s:string);
begin
current_ppu^.putstring(s);
end;
procedure writenormalset(var s); {You cannot pass an array[0..31] of byte!}
begin
current_ppu^.putdata(s,sizeof(tnormalset));
end;
procedure writesmallset(var s);
begin
current_ppu^.putdata(s,4);
end;
{ posinfo is not relevant for changes in PPU }
procedure writeposinfo(const p:tfileposinfo);
var
oldcrc : boolean;
begin
oldcrc:=current_ppu^.do_crc;
current_ppu^.do_crc:=false;
current_ppu^.putword(p.fileindex);
current_ppu^.putlongint(p.line);
current_ppu^.putword(p.column);
current_ppu^.do_crc:=oldcrc;
end;
procedure writeguid(var g: tguid);
begin
current_ppu^.putdata(g,sizeof(g));
end;
procedure writederef(p : psymtableentry);
begin
if p=nil then
current_ppu^.putbyte(ord(derefnil))
else
begin
{ Static symtable ? }
if p^.owner^.symtabletype=staticsymtable then
begin
current_ppu^.putbyte(ord(derefaktstaticindex));
current_ppu^.putword(p^.indexnr);
end
{ Local record/object symtable ? }
else if (p^.owner=aktrecordsymtable) then
begin
current_ppu^.putbyte(ord(derefaktrecordindex));
current_ppu^.putword(p^.indexnr);
end
{ Local local/para symtable ? }
else if (p^.owner=aktlocalsymtable) then
begin
current_ppu^.putbyte(ord(derefaktlocal));
current_ppu^.putword(p^.indexnr);
end
else
begin
current_ppu^.putbyte(ord(derefindex));
current_ppu^.putword(p^.indexnr);
{ Current unit symtable ? }
repeat
if not assigned(p) then
internalerror(556655);
case p^.owner^.symtabletype of
{ when writing the pseudo PPU file
to get CRC values the globalsymtable is not yet
a unitsymtable PM }
globalsymtable,
unitsymtable :
begin
{ check if the unit is available in the uses
clause, else it's an error }
if p^.owner^.unitid=$ffff then
internalerror(55665566);
current_ppu^.putbyte(ord(derefunit));
current_ppu^.putword(p^.owner^.unitid);
break;
end;
staticsymtable :
begin
current_ppu^.putbyte(ord(derefaktstaticindex));
current_ppu^.putword(p^.indexnr);
break;
end;
localsymtable :
begin
p:=p^.owner^.defowner;
current_ppu^.putbyte(ord(dereflocal));
current_ppu^.putword(p^.indexnr);
end;
parasymtable :
begin
p:=p^.owner^.defowner;
current_ppu^.putbyte(ord(derefpara));
current_ppu^.putword(p^.indexnr);
end;
objectsymtable,
recordsymtable :
begin
p:=p^.owner^.defowner;
current_ppu^.putbyte(ord(derefrecord));
current_ppu^.putword(p^.indexnr);
end;
else
internalerror(556656);
end;
until false;
end;
end;
end;
procedure closecurrentppu;
begin
{$ifdef Test_Double_checksum}
if assigned(current_ppu^.crc_test) then
dispose(current_ppu^.crc_test);
if assigned(current_ppu^.crc_test2) then
dispose(current_ppu^.crc_test2);
{$endif Test_Double_checksum}
{ close }
current_ppu^.close;
dispose(current_ppu,done);
current_ppu:=nil;
end;
{*****************************************************************************
PPU Reading
*****************************************************************************}
function readbyte:byte;
begin
readbyte:=current_ppu^.getbyte;
if current_ppu^.error then
Message(unit_f_ppu_read_error);
end;
function readword:word;
begin
readword:=current_ppu^.getword;
if current_ppu^.error then
Message(unit_f_ppu_read_error);
end;
function readlong:longint;
begin
readlong:=current_ppu^.getlongint;
if current_ppu^.error then
Message(unit_f_ppu_read_error);
end;
function readreal : bestreal;
begin
readreal:=current_ppu^.getreal;
if current_ppu^.error then
Message(unit_f_ppu_read_error);
end;
function readstring : string;
begin
readstring:=current_ppu^.getstring;
if current_ppu^.error then
Message(unit_f_ppu_read_error);
end;
procedure readnormalset(var s); {You cannot pass an array [0..31] of byte.}
begin
current_ppu^.getdata(s,sizeof(tnormalset));
if current_ppu^.error then
Message(unit_f_ppu_read_error);
end;
procedure readsmallset(var s);
begin
current_ppu^.getdata(s,4);
if current_ppu^.error then
Message(unit_f_ppu_read_error);
end;
procedure readguid(var g: tguid);
begin
current_ppu^.getdata(g,sizeof(g));
if current_ppu^.error then
Message(unit_f_ppu_read_error);
end;
procedure readposinfo(var p:tfileposinfo);
begin
p.fileindex:=current_ppu^.getword;
p.line:=current_ppu^.getlongint;
p.column:=current_ppu^.getword;
end;
function readderef : psymtableentry;
var
hp,p : pderef;
b : tdereftype;
begin
p:=nil;
repeat
hp:=p;
b:=tdereftype(current_ppu^.getbyte);
case b of
derefnil :
break;
derefunit,
derefaktrecordindex,
derefaktlocal,
derefaktstaticindex :
begin
new(p,init(b,current_ppu^.getword));
p^.next:=hp;
break;
end;
derefindex,
dereflocal,
derefpara,
derefrecord :
begin
new(p,init(b,current_ppu^.getword));
p^.next:=hp;
end;
end;
until false;
readderef:=psymtableentry(p);
end;
end.
{
$Log$
Revision 1.4 2000-12-25 00:07:29 peter
+ new tlinkedlist class (merge of old tstringqueue,tcontainer and
tlinkedlist objects)
Revision 1.3 2000/11/29 00:30:41 florian
* unused units removed from uses clause
* some changes for widestrings
Revision 1.2 2000/11/04 14:25:22 florian
+ merged Attila's changes for interfaces, not tested yet
Revision 1.1 2000/10/31 22:02:52 peter
* symtable splitted, no real code changes
}