124 lines
4.4 KiB
ObjectPascal
124 lines
4.4 KiB
ObjectPascal
unit dpgrtl.inputbuffer;
|
|
|
|
interface
|
|
uses
|
|
dpgrtl.types;
|
|
|
|
type
|
|
TInputBuffer = class( TInterfacedObject, IInputBuffer)
|
|
protected
|
|
fMarkerCount : integer;
|
|
fMarkerOffset : integer;
|
|
fNumToConsume : integer;
|
|
|
|
protected
|
|
procedure Remove( Num: integer); virtual; abstract;
|
|
procedure SyncConsume; inline;
|
|
|
|
protected
|
|
function GetMarked: boolean; inline;
|
|
|
|
procedure Consume; inline;
|
|
procedure Commit; inline;
|
|
|
|
function Mark: integer;
|
|
procedure Rewind( Value: integer);
|
|
end;
|
|
|
|
|
|
implementation
|
|
|
|
{ TInputBuffer }
|
|
|
|
// @@@: IInputBuffer implementation +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// IInputBuffer implementation
|
|
//
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ================================================================================================
|
|
// Mark
|
|
//
|
|
// Returns an integer marker theh can be used to rewind the buffer to its current state.
|
|
// ================================================================================================
|
|
function TInputBuffer.Mark: integer;
|
|
begin
|
|
SyncConsume;
|
|
INC( fMarkerCount);
|
|
|
|
result := fMarkerOffset
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// Consume
|
|
//
|
|
// Mark another input item for deferred consumption.
|
|
// ================================================================================================
|
|
procedure TInputBuffer.Consume;
|
|
begin
|
|
INC( fNumToConsume);
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// Commit
|
|
//
|
|
// This method updates the state of the input buffer so that the text matched since the most
|
|
// recent Mark() is no longer held by the buffer. So, you either do a mark/rewind for failed
|
|
// predicate or mark/commit to keep on parsing without rewinding the input.
|
|
// ================================================================================================
|
|
procedure TInputBuffer.Commit;
|
|
begin
|
|
if fMarkerCount > 0 then
|
|
DEC( fMarkerCount)
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// Rewind
|
|
//
|
|
// Rewind the character buffer to a marker. 'Value' marker returned previously from mark.
|
|
// ================================================================================================
|
|
procedure TInputBuffer.Rewind(Value: integer);
|
|
begin
|
|
SyncConsume;
|
|
|
|
fMarkerOffset := Value;
|
|
DEC( fMarkerCount)
|
|
end;
|
|
|
|
// ================================================================================================
|
|
// GetMarked
|
|
// ================================================================================================
|
|
function TInputBuffer.GetMarked: boolean;
|
|
begin
|
|
result := fMarkerCount <> 0
|
|
end;
|
|
|
|
// @@@: Internals +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
//
|
|
// Internals
|
|
//
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
// ================================================================================================
|
|
// Sync Consume
|
|
// ================================================================================================
|
|
procedure TInputBuffer.SyncConsume;
|
|
begin
|
|
if fNumToConsume > 0 then
|
|
begin
|
|
if fMarkerCount > 0
|
|
then INC( fMarkerOffset, fNumToConsume)
|
|
else Remove( fNumToConsume);
|
|
|
|
fNumToConsume := 0
|
|
end
|
|
end;
|
|
|
|
end.
|