Initial check in rtl
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
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.
|
||||
Reference in New Issue
Block a user