unit Identifiers;

interface

type
  TIdentStr = string[16];
  TClass = (cUnknown, cConst, cVar, cArray, cRec, cProc);
  TType = (tVoid, tInt, tChar, tWord, tString);
  PIdentRec = ^TIdentRec;
  TIdentRec = record
    Name: TIdentStr;
    IdClass: TClass;
    IdType: TType;
    Prev: PIdentRec;
    Data: Integer;
  end;

const
  GlobalTable: PIdentRec = nil;
  LocalTable: PIdentRec = nil;
  CurrentIdent: PIdentRec = nil;

function FindIdent(AName: TIdentStr): PIdentRec;
function AddIdent(AName: TIdentStr; AClass: TClass; AType: TType): PIdentRec;
procedure ClearLocalData;

implementation

uses Common, Scaner;

function FindIdent;
begin
  CurrentIdent := GlobalTable;
  while CurrentIdent <> nil do
    if CurrentIdent^.Name = AName
    then Break
    else CurrentIdent := CurrentIdent^.Prev;
  FindIdent := CurrentIdent;
end; { FindIdent }

function AddIdent;

function FindLocalIdent: PIdentRec;
begin
  CurrentIdent := GlobalTable;
  while CurrentIdent <> LocalTable do
    if CurrentIdent^.Name = AName
    then Break
    else CurrentIdent := CurrentIdent^.Prev;
  if CurrentIdent = LocalTable
  then FindLocalIdent := nil
  else FindLocalIdent := CurrentIdent;
end; { FindLocalIdent }

begin
  if FindLocalIdent <> nil then Error(ecDupIdent);
  New(CurrentIdent);
  with CurrentIdent^ do begin
    Prev := GlobalTable;
    Name := AName;
    IdClass := AClass;
    IdType := AType;
    Data := 0;
  end;
  GlobalTable := CurrentIdent;
  AddIdent := CurrentIdent;
end; { AddIdent }

procedure ClearLocalData;
begin
  while GlobalTable <> LocalTable do begin
    CurrentIdent := GlobalTable;
    GlobalTable := GlobalTable^.Prev;
    Dispose(CurrentIdent);
  end;
  LocalTable := nil;
end;

end.