paxCompiler/Sources/PAXCOMP_LABEL_STACK.pas
Dalibor Marković 9d0de424e8
Init
Signed-off-by: Dalibor Marković <dalibor31@gmail.com>
2024-07-06 22:28:12 +02:00

134 lines
3.0 KiB
ObjectPascal

////////////////////////////////////////////////////////////////////////////
// PaxCompiler
// Site: http://www.paxcompiler.com
// Author: Alexander Baranovsky (paxscript@gmail.com)
// ========================================================================
// Copyright (c) Alexander Baranovsky, 2006-2014. All rights reserved.
// Code Version: 4.2
// ========================================================================
// Unit: PAXCOMP_LABEL_STACK.pas
// ========================================================================
////////////////////////////////////////////////////////////////////////////
{$I PaxCompiler.def}
unit PAXCOMP_LABEL_STACK;
interface
uses {$I uses.def}
SysUtils,
Classes,
PAXCOMP_CONSTANTS,
PAXCOMP_TYPES,
PAXCOMP_SYS;
type
TEntryRec = class
public
IntLabel: Integer;
StringLabel: String;
CodeN: Integer;
loopLabel: Integer;
end;
TEntryStack = class(TTypedList)
private
kernel: Pointer;
function GetRecord(I: Integer): TEntryRec;
function GetTop: TEntryRec;
public
procedure SetKernel(AKernel: Pointer);
procedure Push(AIntLabel, ALoopLabel: Integer); overload;
procedure Push(AIntLabel: Integer;
var AStringLabel: String;
ALoopLabel: Integer); overload;
procedure Pop;
function TopLabel(const AStringLabel: String = ''): Integer;
property Top: TEntryRec read GetTop;
property Records[I: Integer]: TEntryRec read GetRecord; default;
end;
implementation
uses
PAXCOMP_BYTECODE,
PAXCOMP_KERNEL;
procedure TEntryStack.SetKernel(AKernel: Pointer);
begin
kernel := AKernel;
end;
function TEntryStack.GetRecord(I: Integer): TEntryRec;
begin
result := TEntryRec(L[I]);
end;
procedure TEntryStack.Push(AIntLabel, ALoopLabel: Integer);
var
R: TEntryRec;
begin
R := TEntryRec.Create;
R.IntLabel := AIntLabel;
R.StringLabel := '';
R.loopLabel := ALoopLabel;
if kernel <> nil then
R.CodeN := TKernel(kernel).Code.Card;
L.Add(R);
end;
procedure TEntryStack.Push(AIntLabel: Integer; var AStringLabel: String; ALoopLabel: Integer);
var
R: TEntryRec;
begin
R := TEntryRec.Create;
R.IntLabel := AIntLabel;
R.StringLabel := AStringLabel;
R.loopLabel := ALoopLabel;
if kernel <> nil then
R.CodeN := TKernel(kernel).Code.Card;
L.Add(R);
AStringLabel := '';
end;
procedure TEntryStack.Pop;
begin
{$IFDEF ARC}
L[Count - 1] := nil;
{$ELSE}
Records[Count - 1].Free;
{$ENDIF}
L.Delete(Count - 1);
end;
function TEntryStack.TopLabel(const AStringLabel: String = ''): Integer;
var
I: Integer;
R: TEntryRec;
begin
if AStringLabel <> '' then
begin
for I:=Count - 1 downto 0 do
begin
R := Records[I];
with R do
if StringLabel = AStringLabel then
begin
result := IntLabel;
Exit;
end;
end;
raise Exception.Create(errLabelNotFound);
end
else
result := Records[Count - 1].IntLabel;
end;
function TEntryStack.GetTop: TEntryRec;
begin
if Count = 0 then
result := nil
else
result := Records[Count - 1];
end;
end.