From 39f868ad7ea5aa306a4b9905bf847ff24cfe7393 Mon Sep 17 00:00:00 2001 From: Basile Burg Date: Sat, 9 Apr 2016 17:14:33 +0200 Subject: [PATCH] lexer (HL), added a perfect dictionnary for the special keywords --- lazproj/coedit.lpi | 11 ++++++- lazproj/coedit.lpr | 2 +- src/ce_d2syn.pas | 12 ++----- src/ce_dlangmaps.pas | 78 ++++++++++++++++++++++++++++++++++++++++++++ wiki/wiki.todo.txt | 3 +- 5 files changed, 93 insertions(+), 13 deletions(-) create mode 100644 src/ce_dlangmaps.pas diff --git a/lazproj/coedit.lpi b/lazproj/coedit.lpi index a6a5c20e..a75ec624 100644 --- a/lazproj/coedit.lpi +++ b/lazproj/coedit.lpi @@ -137,7 +137,7 @@ - + @@ -384,6 +384,10 @@ + + + + @@ -397,6 +401,11 @@ + + + + + diff --git a/lazproj/coedit.lpr b/lazproj/coedit.lpr index 92c0b531..cd844544 100644 --- a/lazproj/coedit.lpr +++ b/lazproj/coedit.lpr @@ -11,7 +11,7 @@ uses ce_main, ce_writableComponent, ce_staticmacro, ce_inspectors, ce_editoroptions, ce_dockoptions, ce_shortcutseditor, ce_mru, ce_processes, ce_dubproject, ce_dialogs, ce_dubprojeditor, ce_controls, ce_dfmt, - ce_lcldragdrop, ce_stringrange; + ce_lcldragdrop, ce_stringrange, ce_dlangmaps; {$R *.res} diff --git a/src/ce_d2syn.pas b/src/ce_d2syn.pas index 4c13e72f..b1737bf7 100644 --- a/src/ce_d2syn.pas +++ b/src/ce_d2syn.pas @@ -7,7 +7,7 @@ interface uses Classes, SysUtils, Graphics, SynEditHighlighter, SynEditHighlighterFoldBase, SynEditTypes, - ce_dlangutils; + ce_dlangutils,ce_dlangmaps; const @@ -37,12 +37,6 @@ const 'wchar', 'while', 'with', 'wstring' ); - D2SpecKw: array[0..10] of string = - ( - '__FILE__', '__MODULE__', '__LINE__', '__FUNCTION__', '__PRETTY_FUNCTION__', - '__DATE__', '__EOF__', '__TIME__', '__TIMESTAMP__', '__VENDOR__', '__VERSION__' - ); - type TD2DictionaryEntry = record @@ -105,7 +99,6 @@ type fSpeckAttrib: TSynHighlighterAttributes; fErrorAttrib: TSynHighlighterAttributes; fKeyWords: TD2Dictionary; - fSpecKw: TD2Dictionary; fLineBuf: string; fTokStart, fTokStop: Integer; fTokKind: TTokenKind; @@ -276,7 +269,6 @@ begin DefaultFilter:= 'D source|*.d|D interface|*.di'; fKeyWords.create(D2Kw); - fSpecKw.create(D2SpecKw); fFoldKinds := [fkBrackets,fkRegion]; @@ -1000,7 +992,7 @@ begin if (fLineBuf[FTokStart..fTokStop-1] = 'asm') then fCurrRange.rangeKinds += [rkAsm]; end - else if fSpecKw.find(fLineBuf[FTokStart..fTokStop-1]) then + else if specialKeywordsMap.match(fLineBuf[FTokStart..fTokStop-1]) then fTokKind := tkSpecK else if rkAsm in fCurrRange.rangeKinds then fTokKind:=tkAsmbl; diff --git a/src/ce_dlangmaps.pas b/src/ce_dlangmaps.pas new file mode 100644 index 00000000..cfdb528b --- /dev/null +++ b/src/ce_dlangmaps.pas @@ -0,0 +1,78 @@ +unit ce_dlangmaps; + +{$I ce_defines.inc} + +interface + +(** + * Perfect static hash-map that detects the D2 "special" keywords such as + * __LINE__ or __FILE__. + *) +type + + specialKeywordsMap = record + private + const fWords: array [0..15] of string = + ( + '__PRETTY_FUNCTION__', '__VENDOR__', '', '__VERSION__', '__DATE__', + '__FILE__', '__LINE__', '', '__FUNCTION__', '', '__TIMESTAMP__', '__TIME__', + '__EOF__', '', '', '__MODULE__' + ); + const fHasEntry: array [0..15] of boolean = + ( + true, true, false, true, true, true, true, false, true, false, true, true, + true, false, false, true + ); + const fCoeffs: array[0..255] of Byte = + ( + 50, 243, 103, 74, 140, 54, 86, 48, 32, 12, 76, 146, 95, 139, 178, 149, 255, + 167, 77, 13, 101, 143, 16, 6, 221, 208, 221, 79, 217, 253, 102, 24, 243, + 208, 70, 196, 133, 33, 208, 26, 203, 72, 234, 222, 92, 240, 162, 139, 102, + 174, 240, 48, 10, 173, 208, 107, 85, 176, 211, 77, 246, 56, 253, 2, 164, + 108, 181, 37, 35, 11, 111, 224, 51, 16, 170, 123, 245, 147, 183, 250, 15, + 202, 106, 126, 199, 31, 2, 174, 221, 81, 207, 50, 170, 86, 71, 12, 51, 3, + 30, 192, 132, 159, 74, 35, 62, 90, 10, 135, 33, 23, 15, 100, 2, 69, 250, 248, + 36, 120, 134, 108, 134, 54, 89, 89, 219, 86, 165, 72, 244, 130, 60, 44, 84, + 129, 130, 253, 90, 104, 25, 52, 103, 109, 239, 100, 16, 188, 87, 132, 201, + 110, 175, 152, 181, 178, 196, 61, 52, 60, 169, 26, 52, 48, 90, 236, 244, 26, + 28, 117, 65, 155, 24, 60, 216, 220, 80, 152, 202, 173, 43, 17, 48, 83, 135, + 188, 251, 254, 232, 167, 196, 3, 222, 73, 169, 156, 222, 215, 217, 6, 105, + 171, 130, 169, 27, 9, 147, 176, 207, 45, 43, 47, 11, 163, 215, 117, 11, 100, + 253, 70, 242, 169, 92, 61, 198, 236, 243, 26, 144, 220, 76, 40, 178, 158, + 164, 80, 112, 61, 157, 26, 224, 53, 123, 105, 27, 170, 126, 101, 3, 65, 113, + 101, 157, 109, 110, 252, 207, 0 + ); + class function hash(const w: string): Byte; static; + public + class function match(const w: string): boolean; static; + end; + + +implementation + +{$IFDEF DEBUG}{$PUSH}{$R-}{$ENDIF} +class function specialKeywordsMap.hash(const w: string): Byte; +var + i: integer; +begin + Result := 0; + for i := 2 to length(w) do + Result += fCoeffs[(Byte(w[i]) + (Byte(i-1) xor Byte(w[i-1]))) and $FF]; + Result := Result and $F; +end; +{$IFDEF DEBUG}{$POP}{$ENDIF} + +class function specialKeywordsMap.match(const w: string): boolean; +var + h: Byte; +begin + result := false; + if length(w) < 7 then + exit; + h := hash(w); + if fHasEntry[h] then + result := fWords[h] = w; +end; + +end. + diff --git a/wiki/wiki.todo.txt b/wiki/wiki.todo.txt index 16aeb5c8..5c2b4cc5 100644 --- a/wiki/wiki.todo.txt +++ b/wiki/wiki.todo.txt @@ -5,4 +5,5 @@ - input process widget: kill process, in case of error, infinite loop, emergency kill - editor note about usefull commands: comment selection, invert version all/none - tuto are obsolete -- appli option, describe runnable destination \ No newline at end of file +- appli option, describe runnable destination +- emnu reference, action Compile file, action Run compiled file \ No newline at end of file