dexed/src/ce_dlangutils.pas

296 lines
8.7 KiB
Plaintext

unit ce_dlangutils;
{$I ce_defines.inc}
interface
uses
SysUtils;
type
TCharSet = set of Char;
const
stringPostfixes: TCharSet = ['c', 'w', 'd'];
stringPrefixes: TCharSet = ['r', 'x', 'q', '"'];
stringStopChecks: TCharSet = ['\', '"'];
charStopChecks: TCharSet = ['\', #39];
symbChars: TCharSet = [';', '{', '}', '(', ')', '[', ']', ',', '.', ':', '?', '$', '"', #39];
hexaChars: TCharSet = ['0'..'9', 'a'..'f', 'A'..'F', '_'];
function isWhite(const c: Char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function isSpace(const c: Char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function isAlpha(const c: Char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function isNumber(const c: Char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function isBit(const c: Char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function isAlNum(const c: Char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function isHex(const c: Char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function isSymbol(const c: char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function isOperator1(const c: char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function isOperator2(const s: string): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function isOperator3(const s: string): boolean; {$IFNDEF DEBUG} inline; {$ENDIF}
function isOperator4(const s: string): boolean; {$IFNDEF DEBUG} inline; {$ENDIF}
function isStringPostfix(const c: char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function isIdentifier(const c: char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function isFirstIdentifier(const c: char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function readLine(var reader: PChar; var position: Integer): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function readUntil(var reader: PChar; var position: Integer; const aDelim: Char): boolean; overload; {$IFNDEF DEBUG}inline;{$ENDIF}
function readUntil(var reader: PChar; var position: Integer; const aDelim: string): boolean; overload; {$IFNDEF DEBUG}inline;{$ENDIF}
function readUntilAmong(var reader: PChar; var position: Integer; const aDelim: TCharSet): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function readWhile(var reader: PChar; var position: Integer; const aDelim: Char): boolean; overload; {$IFNDEF DEBUG}inline;{$ENDIF}
function readWhile(var aReader: PChar; var position: Integer; const aDelim: TCharSet): boolean; overload;{$IFNDEF DEBUG}inline;{$ENDIF}
function readDelim(var reader: PChar; var position: Integer; const aDelim: Char): boolean; overload; {$IFNDEF DEBUG}inline;{$ENDIF}
function readDelim(var reader: PChar; var position: Integer; const aDelim: string): boolean; overload; {$IFNDEF DEBUG}inline;{$ENDIF}
function readDelim(var reader: PChar; var position: Integer; const aDelims: TCharSet): boolean; overload; {$IFNDEF DEBUG}inline;{$ENDIF}
function tryReadDelim(var reader: PChar; var position: Integer; const aDelim: Char): boolean; overload; {$IFNDEF DEBUG}inline;{$ENDIF}
function tryReadDelim(var reader: PChar; var position: Integer; const aDelim: string): boolean; overload; {$IFNDEF DEBUG}inline;{$ENDIF}
implementation
function isWhite(const c: Char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
begin
exit(c in [#0..#32]);
end;
function isSpace(const c: Char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
begin
exit(c in [#9,' ']);
end;
function isAlpha(const c: Char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
begin
exit((c in ['a'..'z']) or (c in ['A'..'Z']));
end;
function isNumber(const c: Char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
begin
exit(c in ['0'..'9']);
end;
function isBit(const c: Char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
begin
exit((c in ['0'..'1']));
end;
function isAlNum(const c: Char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
begin
exit(isAlpha(c) or isNumber(c));
end;
function isHex(const c: Char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
begin
exit(isNumber(c) or (c in ['A'..'F']) or (c in ['a'..'f']));
end;
function isSymbol(const c: char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
begin
exit(c in [';', '{', '}', '(', ')', '[', ']', ',', '.', ':' , '"', #39, '?', '$', #35]);
end;
function isOperator1(const c: char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
begin
exit(c in ['/', '*', '-', '+', '%', '>', '<', '=', '!', '&', '|', '^', '~']);
end;
function isOperator2(const s: string): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
begin
result := false;
case s[1] of
'.': result := s[2] = '.';
'*': result := s[2] = '=';
'>': result := s[2] in ['>', '='];
'<': result := s[2] in ['<', '=', '>'];
'=': result := s[2] in ['=', '>'];
'!': result := s[2] in ['=', '>', '<'];
'+': result := s[2] in ['+', '='];
'-': result := s[2] in ['-', '='];
'/': result := s[2] in ['='];
'%': result := s[2] in ['='];
'~': result := s[2] in ['='];
'&': result := s[2] in ['&', '='];
'|': result := s[2] in ['|', '='];
'^': result := s[2] in ['^', '='];
end;
end;
function isOperator3(const s: string): boolean; {$IFNDEF DEBUG} inline; {$ENDIF}
begin
result := false;
case s[1] of
'.': result := (s[2] = '.') and (s[3] = '.');
'^': result := (s[2] = '^') and (s[3] = '=');
'>': result := (s[2] = '>') and (s[3] in ['>', '=']);
'<': result := ((s[2] = '<') and (s[3] in ['<', '=']))
or (s[2] = '>') and (s[3] = '=');
'!': result := ((s[2] = '<') and (s[3] in ['>', '=']))
or ((s[2] = '>')and (s[3] = '='));
end;
end;
function isOperator4(const s: string): boolean; {$IFNDEF DEBUG} inline; {$ENDIF}
begin
result := (s = '>>>=') or (s = '!<>=');
end;
function isStringPostfix(const c: char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
begin
exit(c in stringPostfixes);
end;
function isIdentifier(const c: char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
begin
exit((not isSymbol(c)) and (not isOperator1(c)) and (not isWhite(c)));
end;
function isFirstIdentifier(const c: char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
begin
exit(isIdentifier(c) and (not isNumber(c)));
end;
function readLine(var reader: PChar; var position: Integer): boolean;
begin
result := true;
while reader^ <> #10 do
begin
inc(reader);
inc(position);
end;
end;
function readUntil(var reader: PChar; var position: Integer; const aDelim: Char): boolean;
begin
while reader^ <> aDelim do
begin
if reader^ = #10 then
exit(false);
inc(reader);
inc(position);
end;
inc(reader);
inc(position);
exit(true);
end;
function readUntil(var reader: PChar; var position: Integer; const aDelim: string): boolean;
begin
while reader[0..length(aDelim)-1] <> aDelim do
begin
if reader^ = #10 then
exit(false);
inc(reader);
inc(position);
end;
inc(reader, length(aDelim));
inc(position, length(aDelim));
exit(true);
end;
function readUntilAmong(var reader: PChar; var position: Integer; const aDelim: TCharSet): boolean;
begin
while not (reader^ in aDelim) do
begin
if reader^ = #10 then
exit(false);
inc(reader);
inc(position);
end;
exit(true);
end;
function readWhile(var reader: PChar; var position: Integer; const aDelim: Char): boolean;
begin
result := false;
while reader^ = aDelim do
begin
inc(reader);
inc(position);
result := true;
end;
end;
function readWhile(var aReader: PChar; var position: Integer; const aDelim: TCharSet): boolean;
begin
result := false;
while aReader^ in aDelim do
begin
inc(aReader);
inc(position);
result := true;
end;
end;
function readDelim(var reader: PChar; var position: Integer; const aDelim: Char): boolean;
begin
if reader^ <> aDelim then
exit(false);
inc(reader);
inc(position);
exit(true);
end;
function readDelim(var reader: PChar; var position: Integer; const aDelims: TCharSet): boolean;
begin
if not (reader^ in aDelims) then
exit(false);
inc(reader);
inc(position);
exit(true);
end;
function readDelim(var reader: PChar; var position: Integer; const aDelim: string): boolean;
var
i: Integer;
begin
for i := 1 to length(aDelim) do
begin
if reader^ = #10 then
exit(false);
if reader^ <> aDelim[i] then
exit(false);
inc(reader);
inc(position);
end;
exit(true);
end;
function tryReadDelim(var reader: PChar; var position: Integer; const aDelim: Char): boolean;
var
savedReader: PChar;
savedPos: Integer;
begin
savedReader := reader;
savedPos := position;
if readDelim(reader, position, aDelim) then
exit(true);
reader := savedReader;
position := savedPos;
exit(false);
end;
function tryReadDelim(var reader: PChar; var position: Integer; const aDelim: string): boolean;
var
savedReader: PChar;
savedPos: Integer;
begin
savedReader := reader;
savedPos := position;
if readDelim(reader, position, aDelim) then
exit(true);
reader := savedReader;
position := savedPos;
exit(false);
end;
end.