mirror of https://gitlab.com/basile.b/dexed.git
296 lines
8.7 KiB
Plaintext
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.
|