{ Функции для чтения и записи ссылок на другие триады }
function GetLink(iIdx: integer): integer;
procedure SetLink(iIdx: integer; TrdN: integer);
{ Функции для чтения и записи типа операндов }
function GetOpType(iIdx: integer): TOpType;
procedure SetOpType(iIdx: integer; OpT: TOpType);
{ Функции для чтения и записи значений констант }
function GetConstVal(iIdx: integer): integer;
procedure SetConstVal(iIdx: integer; iVal: integer);
{ Свойства триады, основанные на описанных функциях }
property TrdType: TTriadType read TriadType;
property Opers[iIdx: integer]: TOperand read GetOperand
write SetOperand; default;
property Links[iIdx: integer]: integer read GetLink
write SetLink;
property OpTypes[iIdx: integer]: TOpType read GetOpType
write SetOpType;
property Values[iIdx: integer]: integer read GetConstVal
write SetConstVal;
{ Функция, проверяющая эквивалентность двух триад }
function IsEqual(Trd1: TTriad): Boolean;
{ Функция, формирующая строковое представление триады }
function MakeString(i: integer): string;
end;
TTriadList = class(TList)
public { Класс для описания списка триад и работы с ним }
procedure Clear; override; { Процедура очистки списка }
destructor Destroy; override;{Деструктор удаления списка}
{ Процедура вывода списка триад в список строк
для отображения списка триад }
procedure WriteToList(list: TStrings);
{ Процедура удаления триады из списка }
procedure DelTriad(iIdx: integer);
{ Функция получения триады из списка по ее номеру }
function GetTriad(iIdx: integer): TTriad;
{ Свойство списка триад для доступа по номеру триады }
property Triads[iIdx: integer]: TTriad read GetTriad;
default;
end;
{ Процедура удаления из списка триад заданного типа }
procedure DelTriadTypes(listTriad: TTriadList;
TrdType: TTriadType);
implementation
uses SysUtils, FncTree, LexType;
constructor TTriad.Create(Typ: TTriadType;
const Ops: TOpArray);
{ Конструктор создания триады }
var i: integer;
begin
inherited Create; {Вызываем конструктор базового класса}
TriadType:= Typ; { Запоминаем тип триады }
{ Запоминаем два операнда триады }
for i:=1 to 2 do Operands[i]:= Ops[i];
Info:= 0; { Очищаем поле дополнительной информации }
IsLinked:= False; { Очищаем поле внешней ссылки }
end;
function TTriad.GetOperand(iIdx: integer): TOperand;
{ Функция получения данных об операнде по его номеру }
begin Result:= Operands[iIdx]; end;
procedure TTriad.SetOperand(iIdx: integer; Op: TOperand);
{ Функция записи данных операнда триады по его номеру }
begin Operands[iIdx]:= Op; end;
function TTriad.GetLink(iIdx: integer): integer;
{ Функция получения ссылки на другую триаду из операнда }
begin Result:= Operands[iIdx].TriadNum; end;
procedure TTriad.SetLink(iIdx: integer; TrdN: integer);
{ Функция записи номера ссылки на другую триаду }
begin Operands[iIdx].TriadNum:= TrdN; end;
function TTriad.GetOpType(iIdx: integer): TOpType;
{ Функция получения типа операнда по его номеру }
begin Result:= Operands[iIdx].OpType; end;
function TTriad.GetConstVal(iIdx: integer): integer;
{ Функция записи типа операнда по его номеру }
begin Result:= Operands[iIdx].ConstVal; end;
procedure TTriad.SetConstVal(iIdx: integer; iVal: integer);
{ Функция получения значения константы из операнда }
begin Operands[iIdx].ConstVal:= iVal; end;
procedure TTriad.SetOpType(iIdx: integer; OpT: TOpType);
{ Функция записи значения константы в операнд }
begin Operands[iIdx].OpType:= OpT; end;
function IsEqualOp(const Op1,Op2: TOperand): Boolean;
{ Функция проверки совпадения двух операндов }
begin { Операнды равны, если совпадают их типы }
Result:= (Op1.OpType = Op2.OpType);
if Result then { и значения в зависимости от типа }
case Op1.OpType of
OP_CONST: Result:= (Op1.ConstVal = Op2.ConstVal);
OP_VAR: Result:= (Op1.VarLink = Op2.VarLink);
OP_LINK: Result:= (Op1.TriadNum = Op2.TriadNum);
end;
end;
function TTriad.IsEqual(Trd1: TTriad): Boolean;
{ Функция, проверяющая совпадение двух триад }
begin { Триады эквивалентны, если совпадают их типы }
Result:= (TriadType = Trd1.TriadType) { и оба операнда }
and IsEqualOp(Operands[1],Trd1[1])
and IsEqualOp(Operands[2],Trd1[2]);
end;
function GetOperStr(Op: TOperand): string;
{ Функция формирования строки для отображения операнда }
begin
case Op.OpType of
OP_CONST: Result:= IntToStr(Op.ConstVal);
OP_VAR: Result:= Op.VarLink.VarName;
OP_LINK: Result:= ^ + IntToStr(Op.TriadNum+1);
end{case};
end;
function TTriad.MakeString(i: integer): string;
begin
Result:= Format(%d: #9 %s (%s, %s),
[i+1,TriadStr[TriadType],
GetOperStr(Opers[1]), GetOperStr(Opers[2])]);
end;
destructor TTriadList.Destroy;
{ Деструктор для удаления списка триад }
begin
Clear; { Очищаем список триад }
inherited Destroy; {Вызываем деструктор базового класса}
end;
procedure TTriadList.Clear;
{ Процедура очистки списка триад }
var i: integer;
begin { Освобождаем память для всех триад из списка }
for i:=Count-1 downto 0 do TTriad(Items[i]). Free;
inherited Clear; { Вызываем функцию базового класса }
end;
procedure TTriadList.DelTriad(iIdx: integer);
{ Функция удаления триады из списка триад }
begin
if iIdx < Count-1 then { Если это не последняя триада,