mirror of https://gitlab.com/basile.b/dexed.git
839 lines
24 KiB
Plaintext
839 lines
24 KiB
Plaintext
unit u_sxsyn;
|
|
|
|
{$I u_defines.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes,
|
|
SynEditHighlighter, SynEditHighlighterFoldBase, SynEditTypes,
|
|
u_common;
|
|
|
|
type
|
|
|
|
KeywordMatch = record
|
|
private
|
|
|
|
{
|
|
rendered on 2021-Oct-31 06:16:53.798781 by IsItThere.
|
|
- PRNG seed: 6574
|
|
- map length: 128
|
|
- case sensitive: true
|
|
}
|
|
|
|
const fWords: array [0..127] of string =
|
|
('', '', 'alias', 'this', 'f32', '', 's32', 's8', 'throw', 'f64', 'switch', 's64', '', '', '', '', '', '', 'finally', '', '', '', 'if', '', '', '', '', '', '', '', '', '', '', '', '', '', 'protection', 's16', '', '', 'goto', 'usize', '', '', 'in', '', 'static', '', 'try', '', '', '', 'enum', 'do', '', '', '', 'super', 'const', 'union', '', '', 'else', '', 'version', '', '', '', '', 'u32', 'u8', 'echo', '', 'true', 'u64', 'asm', '', 'struct', '', 'auto', 'bool', '', '', '', '', '', 'false', 'null', 'class', '', '', 'overload', '', '', '', '', 'label', '', 'assert', 'continue', 'u16', 'foreach', 'break', '', '', '', 'ssize', '', '', '', '', 'unit', 'while', '', 'var', '', 'with', 'template', '', 'import', 'on', '', '', 'function', '', 'return', '', '');
|
|
|
|
const fFilled: array [0..127] of boolean =
|
|
(false, false, true, true, true, false, true, true, true, true, true, true, false, false, false, false, false, false, true, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, false, false, true, true, false, false, true, false, true, false, true, false, false, false, true, true, false, false, false, true, true, true, false, false, true, false, true, false, false, false, false, true, true, true, false, true, true, true, false, true, false, true, true, false, false, false, false, false, true, true, true, false, false, true, false, false, false, false, true, false, true, true, true, true, true, false, false, false, true, false, false, false, false, true, true, false, true, false, true, true, false, true, true, false, false, true, false, true, false, false);
|
|
|
|
const fCoefficients: array [0..255] of Byte =
|
|
(251, 141, 241, 229, 153, 224, 69, 154, 183, 60, 181, 128, 168, 190, 25, 39, 142, 116, 172, 48, 49, 203, 195, 46, 229, 38, 232, 88, 114, 147, 97, 185, 242, 43, 34, 75, 89, 228, 21, 156, 254, 129, 186, 74, 224, 78, 146, 25, 49, 118, 232, 70, 92, 34, 215, 44, 47, 48, 153, 28, 19, 111, 146, 97, 159, 224, 143, 72, 212, 194, 30, 104, 134, 217, 123, 30, 68, 206, 208, 50, 96, 3, 30, 30, 90, 245, 234, 93, 191, 97, 112, 45, 103, 11, 225, 255, 132, 128, 78, 62, 41, 62, 214, 100, 191, 64, 95, 146, 234, 243, 236, 12, 68, 60, 72, 216, 44, 23, 42, 201, 206, 188, 188, 190, 114, 193, 20, 143, 119, 31, 235, 96, 72, 92, 146, 146, 227, 33, 253, 76, 142, 189, 58, 38, 203, 68, 19, 35, 82, 49, 150, 78, 157, 199, 33, 210, 223, 133, 237, 56, 89, 123, 20, 177, 68, 205, 21, 128, 142, 35, 222, 180, 138, 141, 10, 160, 212, 166, 255, 166, 75, 212, 216, 239, 76, 119, 45, 62, 130, 21, 116, 119, 253, 50, 241, 160, 208, 225, 244, 55, 57, 238, 239, 107, 190, 143, 165, 125, 217, 80, 18, 244, 72, 210, 28, 77, 138, 40, 239, 124, 75, 87, 92, 121, 107, 222, 0, 23, 215, 213, 133, 144, 208, 216, 191, 170, 75, 182, 75, 230, 218, 136, 44, 134, 191, 183, 126, 108, 58, 29, 52, 163, 111, 131, 198, 230);
|
|
|
|
class function hash(const w: string): Word; static;
|
|
public
|
|
class function contains(const w: string): boolean; static;
|
|
end;
|
|
|
|
TTokenKind = (tkNone, tkError, tkCommt, tkIdent, tkKeywd, tkStrng, tkBlank, tkSymbl, tkNumbr, tkAttri);
|
|
|
|
TRangeKind = (rkNone, rkString1, rkString2, rkBlockCom1, rkAttrib);
|
|
|
|
TSynSxSynRange = class (TSynCustomHighlighterRange)
|
|
private
|
|
rangeKind : TRangeKind;
|
|
public
|
|
procedure Assign(source: TSynCustomHighlighterRange); override;
|
|
function Compare(range: TSynCustomHighlighterRange): integer; override;
|
|
procedure Clear; override;
|
|
procedure copyFrom(source: TSynSxSynRange);
|
|
end;
|
|
|
|
TSynSxSyn = class (TSynCustomFoldHighlighter)
|
|
private
|
|
fWhiteAttrib: TSynHighlighterAttributes;
|
|
fNumbrAttrib: TSynHighlighterAttributes;
|
|
fSymblAttrib: TSynHighlighterAttributes;
|
|
fIdentAttrib: TSynHighlighterAttributes;
|
|
fCommtAttrib: TSynHighlighterAttributes;
|
|
fStrngAttrib: TSynHighlighterAttributes;
|
|
fKeywdAttrib: TSynHighlighterAttributes;
|
|
fAttriAttrib: TSynHighlighterAttributes;
|
|
fErrorAttrib: TSynHighlighterAttributes;
|
|
|
|
fLineBuf: string;
|
|
fTokStart, fTokStop: Integer;
|
|
fTokKind: TTokenKind;
|
|
fCurrRange: TSynSxSynRange;
|
|
fLineNum: integer;
|
|
|
|
fAttribLut: array[TTokenKind] of TSynHighlighterAttributes;
|
|
|
|
procedure setWhiteAttrib(value: TSynHighlighterAttributes);
|
|
procedure setNumbrAttrib(value: TSynHighlighterAttributes);
|
|
procedure setSymblAttrib(value: TSynHighlighterAttributes);
|
|
procedure setIdentAttrib(value: TSynHighlighterAttributes);
|
|
procedure setCommtAttrib(value: TSynHighlighterAttributes);
|
|
procedure setStrngAttrib(value: TSynHighlighterAttributes);
|
|
procedure setKeywdAttrib(value: TSynHighlighterAttributes);
|
|
procedure setAttriAttrib(value: TSynHighlighterAttributes);
|
|
procedure setErrorAttrib(value: TSynHighlighterAttributes);
|
|
|
|
function safeLookupChar(): PChar;
|
|
function canLookup2Char(): boolean;
|
|
procedure lexOpAndOpEqual();
|
|
procedure lexOpAndOpOpAndOpEqual(const op: char);
|
|
procedure lexOpAndOpOpAndOpEqualAndOpOpEqual(const op: char);
|
|
procedure lexAssEquOrLambda();
|
|
procedure lexHexLiteral();
|
|
procedure lexBinLiteral();
|
|
procedure lexIntLiteral();
|
|
procedure lexFloatingLiteralFractionalPart();
|
|
procedure lexExponent();
|
|
procedure lexStringLiteral();
|
|
procedure lexRawStringLiteral();
|
|
procedure lexLineComment();
|
|
procedure lexStarComment();
|
|
procedure lexIdentifier();
|
|
|
|
protected
|
|
function GetRangeClass: TSynCustomHighlighterRangeClass; override;
|
|
function GetIdentChars: TSynIdentChars; override;
|
|
|
|
public
|
|
|
|
constructor create(aOwner: TComponent); override;
|
|
destructor destroy; override;
|
|
|
|
procedure GetTokenEx(out TokenStart: PChar; out TokenLength: integer); override;
|
|
function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes; override;
|
|
procedure setLine(const NewValue: string; LineNumber: Integer); override;
|
|
procedure next; override;
|
|
function GetTokenAttribute: TSynHighlighterAttributes; override;
|
|
function GetToken: string; override;
|
|
function GetTokenKind: integer; override;
|
|
function GetTokenPos: Integer; override;
|
|
function GetEol: Boolean; override;
|
|
procedure SetRange(value: Pointer); override;
|
|
procedure ResetRange; override;
|
|
function GetRange: Pointer; override;
|
|
|
|
property whites: TSynHighlighterAttributes read fWhiteAttrib write setWhiteAttrib stored true;
|
|
property numbers: TSynHighlighterAttributes read fNumbrAttrib write setNumbrAttrib stored true;
|
|
property symbols: TSynHighlighterAttributes read fSymblAttrib write setSymblAttrib stored true;
|
|
property identifiers: TSynHighlighterAttributes read fIdentAttrib write setIdentAttrib stored true;
|
|
property comments: TSynHighlighterAttributes read fCommtAttrib write setCommtAttrib stored true;
|
|
property strings: TSynHighlighterAttributes read fStrngAttrib write setStrngAttrib stored true;
|
|
property keywords: TSynHighlighterAttributes read fKeywdAttrib write setKeywdAttrib stored true;
|
|
property attributes: TSynHighlighterAttributes read fAttriAttrib write setAttriAttrib stored true;
|
|
property errors: TSynHighlighterAttributes read fErrorAttrib write setErrorAttrib stored true;
|
|
|
|
end;
|
|
|
|
implementation
|
|
|
|
{$PUSH}{$R-}
|
|
class function KeywordMatch.hash(const w: string): Word;
|
|
var
|
|
i: integer;
|
|
begin
|
|
Result := 0;
|
|
for i := 1 to length(w) do
|
|
Result += fCoefficients[Byte(w[i])];
|
|
Result := Result mod 128;
|
|
end;
|
|
|
|
class function KeywordMatch.contains(const w: string): boolean;
|
|
var
|
|
h: Word;
|
|
begin
|
|
result := false;
|
|
h := hash(w);
|
|
if fFilled[h] then
|
|
result := fWords[h] = w;
|
|
end;
|
|
{$POP}
|
|
|
|
procedure TSynSxSynRange.Assign(source: TSynCustomHighlighterRange);
|
|
var
|
|
rng: TSynSxSynRange;
|
|
begin
|
|
inherited;
|
|
if source is TSynSxSynRange then
|
|
begin
|
|
rng := TSynSxSynRange(source);
|
|
rangeKind := rng.rangeKind;
|
|
end;
|
|
end;
|
|
|
|
function TSynSxSynRange.Compare(range: TSynCustomHighlighterRange): integer;
|
|
begin
|
|
result := inherited Compare(range);
|
|
assert(range <> nil);
|
|
if not result.equals(0) then
|
|
exit;
|
|
if range is TSynSxSynRange then
|
|
result := integer(rangeKind = TSynSxSynRange(range).rangeKind);
|
|
end;
|
|
|
|
procedure TSynSxSynRange.Clear;
|
|
begin
|
|
rangeKind := TRangeKind.rkNone;
|
|
end;
|
|
|
|
procedure TSynSxSynRange.copyFrom(source: TSynSxSynRange);
|
|
begin
|
|
if source.isAssigned then
|
|
rangeKind := source.rangeKind;
|
|
end;
|
|
|
|
constructor TSynSxSyn.create(aOwner: TComponent);
|
|
begin
|
|
inherited create(aOwner);
|
|
|
|
DefaultFilter:= 'STYX source|*.sx|STYX archive|*.sar';
|
|
|
|
WordBreakChars := WordBreakChars - ['@'];
|
|
|
|
fWhiteAttrib := TSynHighlighterAttributes.Create('White','White');
|
|
fNumbrAttrib := TSynHighlighterAttributes.Create('Numbr','Numbr');
|
|
fSymblAttrib := TSynHighlighterAttributes.Create('Symbl','Symbl');
|
|
fIdentAttrib := TSynHighlighterAttributes.Create('Ident','Ident');
|
|
fCommtAttrib := TSynHighlighterAttributes.Create('Commt','Commt');
|
|
fStrngAttrib := TSynHighlighterAttributes.Create('Strng','Strng');
|
|
fKeywdAttrib := TSynHighlighterAttributes.Create('Keywd','Keywd');
|
|
fAttriAttrib := TSynHighlighterAttributes.Create('Attri','Attri');
|
|
fErrorAttrib := TSynHighlighterAttributes.Create('Error','Error');
|
|
|
|
AddAttribute(fWhiteAttrib);
|
|
AddAttribute(fNumbrAttrib);
|
|
AddAttribute(fSymblAttrib);
|
|
AddAttribute(fIdentAttrib);
|
|
AddAttribute(fCommtAttrib);
|
|
AddAttribute(fStrngAttrib);
|
|
AddAttribute(fKeywdAttrib);
|
|
AddAttribute(fAttriAttrib);
|
|
AddAttribute(fErrorAttrib);
|
|
|
|
fAttribLut[TTokenKind.tkident] := fIdentAttrib;
|
|
fAttribLut[TTokenKind.tkBlank] := fWhiteAttrib;
|
|
fAttribLut[TTokenKind.tkCommt] := fCommtAttrib;
|
|
fAttribLut[TTokenKind.tkKeywd] := fKeywdAttrib;
|
|
fAttribLut[TTokenKind.tkNumbr] := fNumbrAttrib;
|
|
fAttribLut[TTokenKind.tkStrng] := fStrngAttrib;
|
|
fAttribLut[TTokenKind.tksymbl] := fSymblAttrib;
|
|
fAttribLut[TTokenKind.tkAttri] := fAttriAttrib;
|
|
fAttribLut[TTokenKind.tkError] := fErrorAttrib;
|
|
|
|
end;
|
|
|
|
destructor TSynSxSyn.destroy;
|
|
begin
|
|
fCurrRange.Free;
|
|
inherited;
|
|
end;
|
|
|
|
function TSynSxSyn.GetRangeClass: TSynCustomHighlighterRangeClass;
|
|
begin
|
|
result := TSynSxSynRange;
|
|
end;
|
|
|
|
function TSynSxSyn.GetIdentChars: TSynIdentChars;
|
|
begin
|
|
result := ['_', 'A'..'Z', 'a'..'z', '0'..'9'];
|
|
end;
|
|
|
|
procedure TSynSxSyn.setWhiteAttrib(value: TSynHighlighterAttributes);
|
|
begin
|
|
fWhiteAttrib.Assign(value);
|
|
end;
|
|
|
|
procedure TSynSxSyn.setNumbrAttrib(value: TSynHighlighterAttributes);
|
|
begin
|
|
fNumbrAttrib.Assign(value);
|
|
end;
|
|
|
|
procedure TSynSxSyn.setSymblAttrib(value: TSynHighlighterAttributes);
|
|
begin
|
|
fSymblAttrib.Assign(value);
|
|
end;
|
|
|
|
procedure TSynSxSyn.setIdentAttrib(value: TSynHighlighterAttributes);
|
|
begin
|
|
fIdentAttrib.Assign(value);
|
|
end;
|
|
|
|
procedure TSynSxSyn.setCommtAttrib(value: TSynHighlighterAttributes);
|
|
begin
|
|
fCommtAttrib.Assign(value);
|
|
end;
|
|
|
|
procedure TSynSxSyn.setStrngAttrib(value: TSynHighlighterAttributes);
|
|
begin
|
|
fStrngAttrib.Assign(value);
|
|
end;
|
|
|
|
procedure TSynSxSyn.setKeywdAttrib(value: TSynHighlighterAttributes);
|
|
begin
|
|
fKeywdAttrib.Assign(value);
|
|
end;
|
|
|
|
procedure TSynSxSyn.setAttriAttrib(value: TSynHighlighterAttributes);
|
|
begin
|
|
fAttriAttrib.Assign(value);
|
|
end;
|
|
|
|
procedure TSynSxSyn.setErrorAttrib(value: TSynHighlighterAttributes);
|
|
begin
|
|
fErrorAttrib.Assign(value);
|
|
end;
|
|
|
|
function TSynSxSyn.GetTokenAttribute: TSynHighlighterAttributes;
|
|
begin
|
|
result := fAttribLut[fTokKind];
|
|
end;
|
|
|
|
procedure TSynSxSyn.SetRange(value: Pointer);
|
|
var
|
|
stored: TSynSxSynRange;
|
|
begin
|
|
inherited SetRange(value);
|
|
stored := TSynSxSynRange(CodeFoldRange.RangeType);
|
|
if fCurrRange.isAssigned and stored.isAssigned then
|
|
fCurrRange.copyFrom(stored);
|
|
end;
|
|
|
|
function TSynSxSyn.GetRange: Pointer;
|
|
var
|
|
stored: TSynSxSynRange;
|
|
begin
|
|
stored := TSynSxSynRange(inherited GetRange);
|
|
if stored.isNotAssigned then
|
|
stored := TSynSxSynRange.Create(nil);
|
|
stored.copyFrom(fCurrRange);
|
|
|
|
CodeFoldRange.RangeType := Pointer(stored);
|
|
Result := inherited GetRange;
|
|
end;
|
|
|
|
procedure TSynSxSyn.ResetRange;
|
|
begin
|
|
if fCurrRange.isNotAssigned then
|
|
fCurrRange := TSynSxSynRange.Create(nil)
|
|
else
|
|
fCurrRange.Clear;
|
|
end;
|
|
|
|
procedure TSynSxSyn.setLine(const NewValue: string; LineNumber: Integer);
|
|
begin
|
|
inherited;
|
|
fLineBuf := NewValue;
|
|
fLineNum := LineNumber;
|
|
fTokStop := 1;
|
|
next;
|
|
end;
|
|
|
|
function TSynSxSyn.GetEol: Boolean;
|
|
begin
|
|
result := fTokKind = tkNone;
|
|
end;
|
|
|
|
function TSynSxSyn.GetTokenPos: Integer;
|
|
begin
|
|
result := fTokStart - 1;
|
|
end;
|
|
|
|
function TSynSxSyn.GetToken: string;
|
|
begin
|
|
result := copy(fLineBuf, FTokStart, fTokStop - FTokStart);
|
|
end;
|
|
|
|
procedure TSynSxSyn.GetTokenEx(out TokenStart: PChar; out TokenLength: integer);
|
|
begin
|
|
TokenStart := @fLineBuf[FTokStart];
|
|
TokenLength := fTokStop - FTokStart;
|
|
end;
|
|
|
|
function TSynSxSyn.GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
|
|
begin
|
|
result := nil;
|
|
end;
|
|
|
|
function TSynSxSyn.GetTokenKind: integer;
|
|
begin
|
|
Result := Integer(fTokKind);
|
|
end;
|
|
|
|
function TSynSxSyn.safeLookupChar: PChar;
|
|
begin
|
|
if fTokStop >= length(fLineBuf) then
|
|
result := nil
|
|
else result := @fLineBuf[fTokStop + 1];
|
|
end;
|
|
|
|
function TSynSxSyn.canLookup2Char(): boolean;
|
|
begin
|
|
result := fTokStop + 2 <= length(fLineBuf);
|
|
end;
|
|
|
|
procedure TSynSxSyn.lexOpAndOpEqual();
|
|
var
|
|
nextPChar: PChar;
|
|
nextChar: char;
|
|
begin
|
|
fTokKind := TTokenKind.tkSymbl;
|
|
nextPChar := safeLookupChar();
|
|
if nextPChar <> nil then
|
|
begin
|
|
nextChar := nextPChar^;
|
|
if nextChar = '=' then
|
|
fTokStop += 1;
|
|
end;
|
|
fTokStop += 1;
|
|
end;
|
|
|
|
procedure TSynSxSyn.lexOpAndOpOpAndOpEqual(const op: char);
|
|
var
|
|
nextPChar: PChar;
|
|
nextChar: char;
|
|
begin
|
|
fTokKind := TTokenKind.tkSymbl;
|
|
nextPChar := safeLookupChar();
|
|
if nextPChar <> nil then
|
|
begin
|
|
nextChar := fLineBuf[fTokStop];
|
|
if (nextChar = op) or (nextChar = '=') then
|
|
fTokStop += 1;
|
|
end;
|
|
fTokStop += 1;
|
|
end;
|
|
|
|
procedure TSynSxSyn.lexOpAndOpOpAndOpEqualAndOpOpEqual(const op: char);
|
|
var
|
|
nextPChar: PChar;
|
|
nextChar: char;
|
|
can2: boolean;
|
|
begin
|
|
fTokKind := TTokenKind.tkSymbl;
|
|
can2 := canLookup2Char();
|
|
nextPChar := safeLookupChar();
|
|
// <<=
|
|
if can2 and (fLineBuf[fTokStop + 1] = op) and (fLineBuf[fTokStop+2] = '=') then
|
|
fTokStop += 2
|
|
else if nextPChar <> nil then
|
|
begin
|
|
nextChar := nextPChar^;
|
|
// << or <=
|
|
if (nextChar = op) or (nextChar = '=') then
|
|
fTokStop += 1;
|
|
end;
|
|
fTokStop += 1;
|
|
end;
|
|
|
|
procedure TSynSxSyn.lexAssEquOrLambda();
|
|
var
|
|
nextPChar: PChar;
|
|
nextChar: char;
|
|
begin
|
|
fTokKind := TTokenKind.tkSymbl;
|
|
nextPChar := safeLookupChar();
|
|
if nextPChar <> nil then
|
|
begin
|
|
nextChar := fLineBuf[fTokStop];
|
|
if (nextChar = '=') or (nextChar = '>') then
|
|
fTokStop += 1;
|
|
end;
|
|
fTokStop += 1;
|
|
end;
|
|
|
|
procedure TSynSxSyn.lexIntLiteral();
|
|
var
|
|
nextPChar: PChar;
|
|
nextChar: char;
|
|
begin
|
|
fTokKind:=TTokenKind.tkNumbr;
|
|
while fTokStop <= fLineBuf.length do
|
|
begin
|
|
case fLineBuf[fTokStop] of
|
|
'0'..'9', '_':
|
|
begin
|
|
fTokStop += 1;
|
|
continue;
|
|
end;
|
|
'.':
|
|
begin
|
|
nextPChar := safeLookupChar();
|
|
if nextPChar <> nil then
|
|
begin
|
|
nextChar := nextPChar^;
|
|
if nextChar in ['0' .. '9'] then
|
|
begin
|
|
fTokStop += 1;
|
|
lexFloatingLiteralFractionalPart();
|
|
exit;
|
|
end;
|
|
end;
|
|
break;
|
|
end;
|
|
end;
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
procedure TSynSxSyn.lexFloatingLiteralFractionalPart();
|
|
begin
|
|
fTokKind:=TTokenKind.tkNumbr;
|
|
while fTokStop <= fLineBuf.length do
|
|
begin
|
|
case fLineBuf[fTokStop] of
|
|
'0'..'9', '_': fTokStop += 1;
|
|
'e', 'E':
|
|
begin
|
|
lexExponent();
|
|
exit;
|
|
end
|
|
else break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TSynSxSyn.lexExponent();
|
|
begin
|
|
fTokStop += 1;
|
|
if fTokStop > fLineBuf.length then
|
|
begin
|
|
fTokKind:=TTokenKind.tkError;
|
|
exit;
|
|
end;
|
|
if fLineBuf[fTokStop] in ['+', '-'] then
|
|
fTokStop += 1;
|
|
if fTokStop > fLineBuf.length then
|
|
begin
|
|
fTokKind:=TTokenKind.tkError;
|
|
exit;
|
|
end;
|
|
while fTokStop <= fLineBuf.length do
|
|
begin
|
|
if fLineBuf[fTokStop] in ['0' .. '9'] then
|
|
begin
|
|
fTokStop += 1;
|
|
continue;
|
|
end else
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
procedure TSynSxSyn.lexHexLiteral();
|
|
var
|
|
firstChar: Boolean = false;
|
|
begin
|
|
fTokStop += 2;
|
|
fTokKind:=TTokenKind.tkNumbr;
|
|
while fTokStop <= fLineBuf.length do
|
|
begin
|
|
case fLineBuf[fTokStop] of
|
|
'0'..'9', 'a'..'f', 'A'..'F', '_':
|
|
begin
|
|
if not firstChar and (fLineBuf[fTokStop] = '_') then
|
|
fTokKind:=TTokenKind.tkError;
|
|
fTokStop += 1;
|
|
firstChar := true;
|
|
continue;
|
|
end
|
|
else while (fTokStop <= fLineBuf.length) and
|
|
(fLineBuf[fTokStop] in ['g' .. 'z', 'G' .. 'Z']) do
|
|
begin
|
|
fTokKind := TTokenKind.tkError;
|
|
fTokStop += 1;
|
|
end;
|
|
end;
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
procedure TSynSxSyn.lexBinLiteral();
|
|
var
|
|
firstChar: Boolean = false;
|
|
begin
|
|
fTokStop += 2;
|
|
fTokKind:=TTokenKind.tkNumbr;
|
|
while fTokStop <= fLineBuf.length do
|
|
begin
|
|
case fLineBuf[fTokStop] of
|
|
'0', '1', '_':
|
|
begin
|
|
if not firstChar and (fLineBuf[fTokStop] = '_') then
|
|
fTokKind:=TTokenKind.tkError;
|
|
fTokStop += 1;
|
|
firstChar := true;
|
|
continue;
|
|
end;
|
|
else while (fTokStop <= fLineBuf.length) and
|
|
(fLineBuf[fTokStop] in ['2' .. '9', 'a' .. 'z', 'A' .. 'Z']) do
|
|
begin
|
|
fTokKind := TTokenKind.tkError;
|
|
fTokStop += 1;
|
|
end;
|
|
end;
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
procedure TSynSxSyn.lexStringLiteral();
|
|
var
|
|
firstLine: Boolean;
|
|
terminate: Boolean = false;
|
|
begin
|
|
fTokKind := TTokenKind.tkStrng;
|
|
firstLine := fCurrRange.rangeKind = TRangeKind.rkNone;
|
|
if firstLine then
|
|
fTokStop += 1;
|
|
while fTokStop <= fLineBuf.length do
|
|
begin
|
|
case fLineBuf[fTokStop] of
|
|
'\' : fTokStop += 2;
|
|
'"' :
|
|
begin
|
|
fTokStop += 1;
|
|
terminate := true;
|
|
break;
|
|
end
|
|
else fTokStop += 1;
|
|
end;
|
|
end;
|
|
if firstLine and not terminate then
|
|
fCurrRange.rangeKind:= TRangeKind.rkString1
|
|
else if (fCurrRange.rangeKind = TRangeKind.rkString1) and terminate then
|
|
fCurrRange.rangeKind:= TRangeKind.rkNone;
|
|
end;
|
|
|
|
procedure TSynSxSyn.lexRawStringLiteral();
|
|
var
|
|
firstLine: Boolean;
|
|
terminate: Boolean = false;
|
|
begin
|
|
fTokKind := TTokenKind.tkStrng;
|
|
firstLine := fCurrRange.rangeKind = TRangeKind.rkNone;
|
|
if firstLine then
|
|
fTokStop += 1;
|
|
while fTokStop <= fLineBuf.length do
|
|
begin
|
|
if fLineBuf[fTokStop] = '`' then
|
|
begin
|
|
fTokStop += 1;
|
|
terminate := true;
|
|
break;
|
|
end
|
|
else fTokStop += 1;
|
|
end;
|
|
if firstLine and not terminate then
|
|
fCurrRange.rangeKind:= TRangeKind.rkString2
|
|
else if (fCurrRange.rangeKind = TRangeKind.rkString2) and terminate then
|
|
fCurrRange.rangeKind:= TRangeKind.rkNone;
|
|
end;
|
|
|
|
procedure TSynSxSyn.lexLineComment();
|
|
begin
|
|
fTokKind := TTokenKind.tkCommt;
|
|
fTokStop := fLineBuf.length + 1;
|
|
end;
|
|
|
|
procedure TSynSxSyn.lexStarComment();
|
|
var
|
|
firstLine: Boolean;
|
|
terminate: Boolean = false;
|
|
begin
|
|
fTokKind := TTokenKind.tkCommt;
|
|
firstLine := fCurrRange.rangeKind = TRangeKind.rkNone;
|
|
while fTokStop <= fLineBuf.length do
|
|
begin
|
|
if fLineBuf[fTokStop] = '*' then
|
|
begin
|
|
fTokStop += 1;
|
|
if (fTokStop <= fLineBuf.length) and (fLineBuf[fTokStop] = '/') then
|
|
begin
|
|
fTokStop += 1;
|
|
terminate := true;
|
|
break;
|
|
end;
|
|
end
|
|
else fTokStop += 1;
|
|
end;
|
|
if firstLine and not terminate then
|
|
fCurrRange.rangeKind := TRangeKind.rkBlockCom1
|
|
else if (fCurrRange.rangeKind = TRangeKind.rkBlockCom1) and terminate then
|
|
fCurrRange.rangeKind := TRangeKind.rkNone;
|
|
end;
|
|
|
|
procedure TSynSxSyn.lexIdentifier();
|
|
var
|
|
dollar: boolean;
|
|
oneChr: boolean = false;
|
|
begin
|
|
fTokKind := TTokenKind.tkIdent;
|
|
dollar := fLineBuf[fTokStop] = '$';
|
|
if dollar then
|
|
fTokStop += 1;
|
|
while fTokStop <= fLineBuf.length do
|
|
begin
|
|
case fLineBuf[fTokStop] of
|
|
'_', 'a'..'z', 'A'..'Z':
|
|
begin
|
|
oneChr := true;
|
|
fTokStop += 1;
|
|
continue;
|
|
end;
|
|
'0' .. '9':
|
|
begin
|
|
if oneChr then
|
|
begin
|
|
fTokStop += 1;
|
|
continue;
|
|
end
|
|
else break; // e.g $0
|
|
end
|
|
else break;
|
|
end;
|
|
end;
|
|
if dollar and not oneChr then
|
|
fTokKind := TTokenKind.tkError
|
|
else
|
|
begin
|
|
if KeywordMatch.contains(GetToken()) then
|
|
fTokKind := TTokenKind.tkKeywd;
|
|
end;
|
|
end;
|
|
|
|
procedure TSynSxSyn.next;
|
|
var
|
|
llen: integer;
|
|
nextPChar: PChar;
|
|
nextChar: char;
|
|
begin
|
|
fTokKind := tkNone;
|
|
fTokStart := fTokStop;
|
|
llen := length(fLineBuf);
|
|
|
|
// EOL
|
|
if fTokStop > llen then
|
|
exit;
|
|
|
|
// continue partial multi-line ranges
|
|
if fCurrRange.isNotAssigned then
|
|
fCurrRange := TSynSxSynRange.Create(nil)
|
|
else case fCurrRange.rangeKind of
|
|
TRangeKind.rkString1: begin lexStringLiteral(); exit; end;
|
|
TRangeKind.rkString2: begin lexRawStringLiteral(); exit; end;
|
|
TRangeKind.rkBlockCom1: begin lexStarComment(); exit; end;
|
|
end;
|
|
|
|
// special lines
|
|
if (fLineBuf.length > 1) then
|
|
begin
|
|
// she bang
|
|
if (fLineNum = 0) and (fLineBuf[1..2] = '#!') then
|
|
begin
|
|
lexLineComment();
|
|
exit;
|
|
end
|
|
// "§" of SAR
|
|
else if (fTokStart = 1) and (fLineBuf[1..2] = #194#167) then
|
|
begin
|
|
lexLineComment();
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
case fLineBuf[fTokStop] of
|
|
#0 .. #10, #13, #32:
|
|
begin
|
|
fTokStop += 1;
|
|
fTokKind := TTokenKind.tkBlank;
|
|
end;
|
|
// `//comment` `/*comment` `/=` `/`
|
|
'/':
|
|
begin
|
|
fTokKind := TTokenKind.tkSymbl;
|
|
fTokStop += 1;
|
|
if (fTokStop <= llen) then
|
|
case fLineBuf[fTokStop] of
|
|
'/' : lexLineComment();
|
|
'*' : begin fTokStop += 1; lexStarComment(); end;
|
|
'=' : fTokStop += 1;
|
|
end;
|
|
end;
|
|
// `_ident` `$kwIdent`
|
|
'a'..'z', 'A'..'Z', '_', '$': lexIdentifier();
|
|
// `0x...` `0b...` `012...` `0.12...` `012...`
|
|
'0':
|
|
begin
|
|
nextPChar := safeLookupChar();
|
|
if nextPChar <> nil then
|
|
begin
|
|
nextChar := nextPChar^;
|
|
if (nextChar = 'x') or (nextChar = 'X') then
|
|
lexHexLiteral()
|
|
else if (nextChar = 'b') or (nextChar = 'B') then
|
|
lexBinLiteral()
|
|
else lexIntLiteral();
|
|
end
|
|
else lexIntLiteral();
|
|
end;
|
|
// number
|
|
'1' .. '9' : lexIntLiteral();
|
|
// "string"
|
|
'"': lexStringLiteral();
|
|
// `string`
|
|
'`': lexRawStringLiteral();
|
|
// `-` `-=` `--`
|
|
'-': lexOpAndOpOpAndOpEqual('-');
|
|
// `&` `&=` `&&`
|
|
'&': lexOpAndOpOpAndOpEqual('&');
|
|
// `|` `|=` `||`
|
|
'|': lexOpAndOpOpAndOpEqual('|');
|
|
// `+` `+=` `++`
|
|
'+': lexOpAndOpOpAndOpEqual('+');
|
|
// `*` `*=` `%` `%=` `^` `^=` `~` `~=` `!` `!=`
|
|
'*', '%', '^', '!', '~': lexOpAndOpEqual();
|
|
// `<` `<<` `<=` `<<=` `>` `>>` `>=` `>>=`
|
|
'<': lexOpAndOpOpAndOpEqualAndOpOpEqual('<');
|
|
'>': lexOpAndOpOpAndOpEqualAndOpOpEqual('>');
|
|
// `=`, `==`, `=>`
|
|
'=': lexAssEquOrLambda();
|
|
'.', '(', ')', ',', ':' , '[', ']', '?', ';' :
|
|
begin
|
|
fTokKind := TTokenKind.tkSymbl;
|
|
fTokStop += 1;
|
|
end;
|
|
'@':
|
|
begin
|
|
fTokKind := TTokenKind.tkError;
|
|
fTokStop += 1;
|
|
if fTokStop <= llen then
|
|
begin
|
|
lexIdentifier();
|
|
fTokKind := TTokenKind.tkAttri;
|
|
end;
|
|
end;
|
|
'{':
|
|
begin
|
|
fTokKind := TTokenKind.tkSymbl;
|
|
fTokStop += 1;
|
|
StartCodeFoldBlock();
|
|
end;
|
|
'}':
|
|
begin
|
|
fTokKind := TTokenKind.tkSymbl;
|
|
fTokStop += 1;
|
|
EndCodeFoldBlock();
|
|
end
|
|
else begin
|
|
fTokStop += 1;
|
|
fTokKind := TTokenKind.tkError;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
end.
|
|
|