Recent

Author Topic: like to modify TSynPasSyn keyword 'function'  (Read 4479 times)

Michael Collier

  • Sr. Member
  • ****
  • Posts: 301
like to modify TSynPasSyn keyword 'function'
« on: January 23, 2017, 07:58:15 pm »
Rather than create a whole new folding highlighter, I thought I would modify a copy of TSynPasSyn, called TSynPasSyn2. It's in its own unit and also renamed other types e.g. TPascalCodeFoldBlockType2 etc so nothing should be referring back to old TSynPasSyn.

I'd like to change the pascal keyword from 'function' to 'defn'

so I created a

Code: Pascal  [Select][+][-]
  1. const kw_function = 'defn' ;

and replaced in 2 places where the text 'function' is hard coded:

Code: Pascal  [Select][+][-]
  1.   RESERVED_WORDS_TP: array [1..54] of String = (
  2.     'absolute', 'and', 'array', 'asm',
  3.     'begin',
  4.     'case', 'const', 'constructor',
  5.     'destructor', 'div', 'do', 'downto',
  6.     'else', 'end',
  7.     'file', 'for',
  8.     //'function',
  9.     kw_function ,
  10.     'goto',
  11.  

and

Code: Pascal  [Select][+][-]
  1. function TSynPasSyn2.Func102: TtkTokenKind2;
  2. var
  3.   InClass: Boolean;
  4. begin
  5.   if KeyComp({'Function'}kw_function) then begin
  6.  

It didn't highlight the word 'defn' and from tracing the code I think the highlighter is still expecting an 8 letter word (the count of letters in 'function'). I also tried changing my keyword to 8 letters ('functio_') but that didn't work either.

I'm not sure about hash tables, maybe that is where I need to look closer, but can anyone tell me where I should be looking to make this change please? If I can make a few simple changes to the pascal highlighter it would be great for me because it already does so much of what I want to do, it just has different keyword names for my purposes.

Thanks.


Edson

  • Hero Member
  • *****
  • Posts: 1301
Re: like to modify TSynPasSyn keyword 'function'
« Reply #1 on: January 23, 2017, 08:19:26 pm »
IIRC, TSynPasSyn.Func102() is one of the many functions implemented in the hash algoritm used in TSynPasSyn. If you add a new word, you need to calculate his new Hash value and add the new word to the function TSynPasSyn.Func<value>
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

Michael Collier

  • Sr. Member
  • ****
  • Posts: 301
Re: like to modify TSynPasSyn keyword 'function'
« Reply #2 on: January 23, 2017, 08:48:40 pm »
I'm not sure how to calculate a hash value for 'defn' or where to store it, I have searched the existing source to see how it would do that for the word 'function' and can't see how it is done. I'm probably missing something very obvious but I've tried looking at the source for a few hours of trying/hacking without positive result.

Can anyone point me in the direction of how hash value was created for the word 'function' and I'll give it a go for the word 'defn'? .. I have no experience of hash values but I'm trying..


bytebites

  • Hero Member
  • *****
  • Posts: 632
Re: like to modify TSynPasSyn keyword 'function'
« Reply #3 on: January 23, 2017, 09:30:01 pm »
Perhaps the reserved words should be in alphabetical order.

Michael Collier

  • Sr. Member
  • ****
  • Posts: 301
Re: like to modify TSynPasSyn keyword 'function'
« Reply #4 on: January 23, 2017, 09:41:18 pm »
Thanks, I already tried that by placing 'defn' in the letter 'd' section of this code and it didn't work either.

Code: Pascal  [Select][+][-]
  1.   RESERVED_WORDS_TP: array [1..54] of String = (
  2.     'absolute', 'and', 'array', 'asm',
  3.     'begin',
  4.     'case', 'const', 'constructor',
  5.     kw_function ,
  6.     'destructor', 'div', 'do', 'downto',
  7.     'else', 'end',
  8.     'file', 'for',
  9.     //'function',
  10.     //kw_function ,


Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9791
  • Debugger - SynEdit - and more
    • wiki
Re: like to modify TSynPasSyn keyword 'function'
« Reply #5 on: January 23, 2017, 10:56:06 pm »
First of all you might want to look at the tutorial http://wiki.lazarus.freepascal.org/SynEdit_Highlighter

Ok, you dont start from scratch
and this does not cover your problem.

the "hash" is only for speed.
You can have a big "case keyword of" statement instead.

In SynPasSyn for each "token" (word) a hash is calculated
  function TSynPasSyn.KeyHash: Integer;

that is then looked up in the table fIdentFuncTable
  function TSynPasSyn.IdentKind(p: integer): TtkTokenKind;
calls the function for that hash (e.g. Func191), so the Func191 only processes keywords that have this hash.

There is no tool to get all the hashes... not that I know of.



Michael Collier

  • Sr. Member
  • ****
  • Posts: 301
Re: like to modify TSynPasSyn keyword 'function'
« Reply #6 on: January 24, 2017, 01:01:35 am »
Solved... The letters for 'function' add up to 102 (using a=1,b=2). That is how the function HashKey does it. It doesn't produce unique hash values, so if I want to use "def" (4+5+6=15) I have to use the same function used by "if" (9+6) and do a KeyComp to differentiate between "def"/"if".

Code: Pascal  [Select][+][-]
  1. function TSynPasSyn2.Func15: TtkTokenKind2;
  2. var   InClass: Boolean; //m.c.
  3. begin
  4.   // quick and dirty hack...
  5.  
  6.   //test if we get here because of "def" - (code copied from func102)
  7.   if KeyComp({'Function'}'def') then begin
  8.     if not(rsAfterEqualOrColon in fRange) then begin
  9.       PasCodeFoldRange.BracketNestLevel := 0; // Reset in case of partial code
  10.       CloseBeginEndBlocksBeforeProc;
  11.  
  12.       if TopPascalCodeFoldBlockType in [cfbtVarType, cfbtLocalVarType] then
  13.         EndPascalCodeFoldBlockLastLine;
  14.  
  15.       InClass := TopPascalCodeFoldBlockType in [cfbtClass, cfbtClassSection, cfbtRecord];
  16.       if ( (rsImplementation in fRange) and (not InClass) ) then
  17.         StartPascalCodeFoldBlock(cfbtProcedure);
  18.  
  19.       if InClass then
  20.         fRange := fRange + [rsAfterClassMembers];
  21.     end;
  22.     fRange := fRange + [rsInProcHeader];
  23.     Result := tkKey;
  24.  
  25.     Exit; //--->
  26.   end ;
  27.  
  28.  
  29.   if KeyComp('If') then begin
  30.     StartPascalCodeFoldBlock(cfbtIfThen, True);
  31.     Result := tkKey ;
  32.     exit ; //-->
  33.   end ;
  34.  
  35.  
  36.   //else
  37.     Result := tkIdentifier;
  38.  

 

TinyPortal © 2005-2018