Скачиваний:
12
Добавлен:
01.05.2014
Размер:
3 Кб
Скачать
{
  C-like language compiler v0.1.0.485

  12 november 2007

  Copyright (C) 2006, 2007 Igor Krooshch
  rheo.ikro@gmail.com

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 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
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
}

unit UCcLabelStack;

interface

uses
  SysUtils, Classes;

type
  TCcLabel = string;

  TCcLabelStackItemType = (lsitBreak, lsitContinue);

  PCcLabelStackItem = ^TCcLabelStackItem;
  TCcLabelStackItem = record
    lblBreak: TCcLabel;
    lblContinue: TCcLabel;
  end;

  ECcLabelStack = class(Exception);

  TCcLabelStack = class
  private
    FList: TList;
  public
    constructor Create;
    destructor Destroy; override;

    function IsEmpty: boolean;

    procedure Push(ABreak, AContinue: TCcLabel);
    function Get(AType: TCcLabelStackItemType): TCcLabel;
    procedure Pop;
  end;


implementation

const
  ITEM_TYPE_STR: array[TCcLabelStackItemType] of string = ('break', 'continue');

  
{ TCcLabelStack }

constructor TCcLabelStack.Create;
begin
  FList := TList.Create;
end;


destructor TCcLabelStack.Destroy;
begin
  while not IsEmpty do
    Pop;

  FList.Free;
  inherited;
end;


function TCcLabelStack.Get(AType: TCcLabelStackItemType): TCcLabel;
var
  p: PCcLabelStackItem;
begin
  if IsEmpty then
    raise ECcLabelStack.Create(
      Format(
        '''%s'' is not allowed here', [ITEM_TYPE_STR[AType]]));
  p := FList[FList.Count - 1];
  case AType of
    lsitBreak: Result := p^.lblBreak;
    lsitContinue: Result := p^.lblContinue;
    else
      Result := '';
  end;
end;


function TCcLabelStack.IsEmpty: boolean;
begin
  Result := FList.Count = 0;
end;


procedure TCcLabelStack.Pop;
var
  p: PCcLabelStackItem;
begin
  if IsEmpty then
    Exit;
  p := FList[FList.Count - 1];
  Dispose(p);
  FList.Delete(FList.Count - 1);
end;


procedure TCcLabelStack.Push(ABreak, AContinue: TCcLabel);
var
  p: PCcLabelStackItem;
begin
  New(p);
  p^.lblBreak := ABreak;
  p^.lblContinue := AContinue;
  FList.Add(p);   
end;

end.
 
Соседние файлы в папке CodeGenerator