[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [tyndur-devel] [PATCH 3/3] kedit: Syntax-Highlighting [3]
On Thu, Sep 24, 2009 at 02:15:35AM +0200, Alexander Hartmut Kluth wrote:
> Hab mich hier mit der Anzahl der Patches vertan, deshalb drei Syntaxe
> in einem Patch
>
> + kedit: syntax_pas.pas: Pascal-Syntax
> + kedit: syntax_intel.pas: Assembler (Intel)
> + kedit: syntax_atandt.pas: Assembler (AT&T)
>
> Signed-off-by: Alexander Hartmut Kluth <hartmut@xxxxxxxxxx>
> ---
> src/modules/pas/kedit/syntax_atandt.pas | 208 +++++++++++++++++++++++++++++
> src/modules/pas/kedit/syntax_intel.pas | 207 ++++++++++++++++++++++++++++
> src/modules/pas/kedit/syntax_pas.pas | 222 +++++++++++++++++++++++++++++++
> 3 files changed, 637 insertions(+), 0 deletions(-)
> create mode 100644 src/modules/pas/kedit/syntax_atandt.pas
> create mode 100644 src/modules/pas/kedit/syntax_intel.pas
> create mode 100644 src/modules/pas/kedit/syntax_pas.pas
>
> diff --git a/src/modules/pas/kedit/syntax_atandt.pas b/src/modules/pas/kedit/syntax_atandt.pas
> new file mode 100644
> index 0000000..5b361a6
> --- /dev/null
> +++ b/src/modules/pas/kedit/syntax_atandt.pas
> @@ -0,0 +1,208 @@
> +unit syntax_atandt;
> +{$mode ObjFPC}
> +
> +interface
> +
> +uses syntax;
> +
> +type
> + TSyntax_ATANDT = class(TSyntax)
> + public
> + procedure StartLine(s: String; state: integer); override;
> + function Next: TSyntaxChange; override;
> + end;
> +
> +
> +implementation
> +const
> + Keywords_ATANDT: Array [1..48] of String = (
> + 'movb', 'movs', 'movw', 'movl', 'movq', 'movt', 'jmp', 'call', 'org',
> + 'andb', 'ands', 'andw', 'andl', 'andq', 'andt', 'cmp', 'je', 'jne', 'jz',
> + 'jnz', 'nop', 'hlt', 'db', 'dw', 'dd', 'dq', 'equ', 'aaa',
> + 'addb', 'adds', 'addw', 'addl', 'addq', 'addt',
> + 'mul', 'imul', 'div', 'idiv',
> + 'subb', 'subs', 'subw', 'subl', 'subq', 'subt', 'far', 'byte', 'popl', 'pushl'
> + );
Die korrekte Bezeichnung ist nicht Keywords, sondern Mnemonics. Aber wie
schon im IRC angsprochen, halte ich es für keine gute Idee, die alle
aufzuzählen - es sind sehr viele und es kommen ständig neue dazu.
Stattdessen nimm einfach alles als Mnemonic, was am Anfang der Zeile
(oder nach einem Präfix wie rep oder lock) steht und nicht irgendwas
anderes ist.
Keywords wären für mich sowas wie global, extern oder macro
> +
> + Types_ATANDT: Array [1..92] of String = (
> + '%ax', '%ah', '%al', '%bx', '%bh', '%bl', '%cx', '%ch', '%cl',
> + '%dx', '%dh', '%dl', '%si', '%ss', '%sp', '%bp', '%cs', '%ds',
> + '%es', '%fs', '%gs', '%eax', '%ebx', '%ecx', '%edx', '%edi',
> + '%esi', '%ebp', '%esp', '%eip', 'eflags', '%rax', '%rbx', '%rcx',
> + '%rdx', '%rdi', '%rsi', '%rbp', '%rsp', '%rip', 'rflags', '%r8', '%r9',
> + '%r10', '%r11', '%r12', '%r13', '%r14', '%r15', '%dil', '%sil', '%bpl',
> + '%spl', '%r8l', '%r9l', '%r10l', '%r11l', '%r12l', '%r13l', '%r14l',
> + '%r15l', '%r8w', '%r9w', '%r10w', '%r11w', '%r13w', '%r14w', '%r15w',
> + '%r8d', '%r9d', '%r10d', '%r11d', '%r12d', '%r13d', '%r14d', '%r15d',
> + '%xmm0', '%xmm1', '%xmm2', '%xmm3', '%xmm4', '%xmm5', '%xmm6', '%xmm7',
> + '%xmm8', '%xmm9', '%xmm10', '%xmm11', '%xmm12', '%xmm13', '%xmm14',
> + '%xmm15'
> + );
Max hat schon ein paar Register (nicht Typen ;-)) aufgezählt, die noch
fehlen.
> +
> +procedure TSyntax_ATANDT.StartLine(s: String; state: integer);
> +begin
> + line := s;
> + f_state := state;
> + pos := 1;
> +
> + case f_state of
> + 1: color := syn_comment;
> + 2: color := syn_comment;
> + 3: color := syn_number;
> + 4: color := syn_string;
> + 5: color := syn_string_special;
> + 6: color := syn_keyword;
> + 7: color := syn_type;
> + 8: color := syn_label;
> + else color := syn_other;
> + end;
> +end;
> +
> +
> +function TSyntax_ATANDT.Next: TSyntaxChange;
> +var
> + c: char;
> + tmp: integer;
> +begin
> + Next.posY := 0;
> + Next.color := color;
> +
> + while pos <= length(line) do begin
> + c := line[pos];
> +
> + case f_state of
> +
> + 0: { Normaler Text }
> + case c of
> + '/':
> + if Matches(line, pos, '/*') then begin
> + f_state := 2;
> + exit(Highlight(syn_comment));
> + end;
> +
> + '0' .. '9', '-', '+':
> + begin
> + tmp := MatchesNumber(line, pos);
> + if tmp <> 0 then begin
> + Next := Highlight(syn_number);
> + Inc(pos, tmp);
> + f_state := 3;
> + exit;
> + end;
> + end;
> +
> + '#':
> + begin
> + if Copy(line, 1, pos - 1) = Space(pos - 1) then begin
> + f_state := 1;
> + exit(Highlight(syn_compiler));
> + end;
> + end;
> +
> + '"':
> + begin
> + Next := Highlight(syn_string);
> + Inc(pos);
> + f_state := 4;
> + exit;
> + end;
> + ' ':
> + begin
> + if MatchesTrailingSpace(line, pos) then begin
> + Next := Highlight(syn_trailing_space);
> + pos := length(line) + 1;
> + exit;
> + end;
> + end;
> +
> + else
> + begin
> + tmp := MatchesKeyword(line, pos, Keywords_ATANDT);
> + if tmp <> 0 then begin
> + Next := Highlight(syn_keyword);
> + Inc(pos, tmp);
> + f_state := 6;
> + exit;
> + end;
> +
> + tmp := MatchesKeyword(line, pos, Types_ATANDT);
> + if tmp <> 0 then begin
> + Next := Highlight(syn_type);
> + Inc(pos, tmp);
> + f_state := 7;
> + exit;
> + end;
> +
> + tmp := MatchesType(line, pos);
> + if tmp <> 0 then begin
> + Next := Highlight(syn_type);
> + Inc(pos, tmp);
> + f_state := 7;
> + exit;
> + end;
> +
> + tmp := MatchesLabel(line, pos);
> + if tmp <> 0 then begin
> + Next := Highlight(syn_label);
> + Inc(pos, tmp);
> + f_state := 8;
> + exit;
> + end;
> + end;
> + end;
> +
> + 1: { Kommentar bis Zeilenende }
> + begin
> + pos := length(line);
> + break;
> + end;
> +
> + 2: { C-??hnlicher-Kommentar }
> + if Matches(line, pos, '*/') then begin
> + f_state := 0;
> + Inc(pos, 2);
> + exit(Highlight(syn_other));
> + end;
> +
> + 3, 6, 7, 8: { Ende eines gefaerbten Worts }
> + begin
> + f_state := 0;
> + exit(Highlight(syn_other));
> + end;
> +
> + 4: { String }
> + case c of
> + '\':
> + begin
> + f_state := 5;
> + Next := Highlight(syn_string_special);
> + Inc(pos);
> + exit;
> + end;
> +
> + '"':
> + begin
> + f_state := 0;
> + Inc(pos);
> + exit(Highlight(syn_other));
> + end;
> + end;
> +
> + 5: { Escaptes Zeichen in einem String }
> + begin
> + f_state := 4;
> + Inc(pos);
> + exit(Highlight(syn_string));
> + end;
> +
> + end;
> +
> + Inc(pos);
> + end;
> +
> + if f_state in [1, 3, 4, 5] then begin
> + f_state := 0;
> + end;
> +end;
> +
> +end.
> diff --git a/src/modules/pas/kedit/syntax_intel.pas b/src/modules/pas/kedit/syntax_intel.pas
> new file mode 100644
> index 0000000..ddb7f92
> --- /dev/null
> +++ b/src/modules/pas/kedit/syntax_intel.pas
> @@ -0,0 +1,207 @@
> +unit syntax_intel;
> +
> +{$mode ObjFpc}
> +
> +interface
> +
> +uses syntax;
> +
> +type
> + TSyntax_INTEL = class(TSyntax)
> + public
> + procedure StartLine(s: String; state: integer); override;
> + function Next: TSyntaxChange; override;
> + end;
> +
> +
> +implementation
> +const
> + Keywords_INTEL: Array [1..26] of String = (
> + 'mov', 'jmp', 'call', 'org', 'and', 'cmp', 'je', 'jne', 'jz',
> + 'jnz', 'nop', 'hlt', 'db', 'dw', 'dd', 'dq', 'equ', 'aaa', 'add',
> + 'mul', 'imul', 'div', 'idiv', 'sub', 'far', 'byte'
> + );
> +
> + Types_INTEL: Array [1..92] of String = (
> + 'ax', 'ah', 'al', 'bx', 'bh', 'bl', 'cx', 'ch', 'cl',
> + 'dx', 'dh', 'dl', 'si', 'ss', 'sp', 'bp', 'cs', 'ds',
> + 'es', 'fs', 'gs', 'eax', 'ebx', 'ecx', 'edx', 'edi',
> + 'esi', 'ebp', 'esp', 'eip', 'eflags', 'rax', 'rbx', 'rcx',
> + 'rdx', 'rdi', 'rsi', 'rbp', 'rsp', 'rip', 'rflags', 'r8', 'r9',
> + 'r10', 'r11', 'r12', 'r13', 'r14', 'r15', 'dil', 'sil', 'bpl',
> + 'spl', 'r8l', 'r9l', 'r10l', 'r11l', 'r12l', 'r13l', 'r14l',
> + 'r15l', 'r8w', 'r9w', 'r10w', 'r11w', 'r13w', 'r14w', 'r15w',
> + 'r8d', 'r9d', 'r10d', 'r11d', 'r12d', 'r13d', 'r14d', 'r15d',
> + 'xmm0', 'xmm1', 'xmm2', 'xmm3', 'xmm4', 'xmm5', 'xmm6', 'xmm7',
> + 'xmm8', 'xmm9', 'xmm10', 'xmm11', 'xmm12', 'xmm13', 'xmm14',
> + 'xmm15'
> + );
> +
> +procedure TSyntax_INTEL.StartLine(s: String; state: integer);
> +begin
> + line := s;
> + f_state := state;
> + pos := 1;
> +
> + case f_state of
> + 1: color := syn_comment;
> + 2: color := syn_comment;
> + 3: color := syn_number;
> + 4: color := syn_string;
> + 5: color := syn_string_special;
> + 6: color := syn_keyword;
> + 7: color := syn_type;
> + 8: color := syn_label;
> + else color := syn_other;
> + end;
> +end;
> +
> +
> +function TSyntax_INTEL.Next: TSyntaxChange;
> +var
> + c: char;
> + tmp: integer;
> +begin
> + Next.posY := 0;
> + Next.color := color;
> +
> + while pos <= length(line) do begin
> + c := line[pos];
> +
> + case f_state of
> +
> + 0: { Normaler Text }
> + case c of
> + ';':
> + begin
> + f_state := 1;
> + exit(Highlight(syn_comment));
> + end;
> +
> + '0' .. '9', '-', '+':
> + begin
> + tmp := MatchesNumber(line, pos);
> + if tmp <> 0 then begin
> + Next := Highlight(syn_number);
> + Inc(pos, tmp);
> + f_state := 3;
> + exit;
> + end;
> + end;
> +
> + '%':
> + begin
> + if Copy(line, 1, pos - 1) = Space(pos - 1) then begin
> + f_state := 1;
> + exit(Highlight(syn_compiler));
> + end;
> + end;
> +
> + '"':
> + begin
> + Next := Highlight(syn_string);
> + Inc(pos);
> + f_state := 4;
> + exit;
> + end;
> +
> + ' ':
> + begin
> + if MatchesTrailingSpace(line, pos) then begin
> + Next := Highlight(syn_trailing_space);
> + pos := length(line) + 1;
> + exit;
> + end;
> + end;
> +
> + else
> + begin
> + tmp := MatchesKeyword(line, pos, Keywords_INTEL);
> + if tmp <> 0 then begin
> + Next := Highlight(syn_keyword);
> + Inc(pos, tmp);
> + f_state := 6;
> + exit;
> + end;
> +
> + tmp := MatchesKeyword(line, pos, Types_INTEL);
> + if tmp <> 0 then begin
> + Next := Highlight(syn_type);
> + Inc(pos, tmp);
> + f_state := 7;
> + exit;
> + end;
> +
> + tmp := MatchesType(line, pos);
> + if tmp <> 0 then begin
> + Next := Highlight(syn_type);
> + Inc(pos, tmp);
> + f_state := 7;
> + exit;
> + end;
> +
> + tmp := MatchesLabel(line, pos);
> + if tmp <> 0 then begin
> + Next := Highlight(syn_label);
> + Inc(pos, tmp);
> + f_state := 8;
> + exit;
> + end;
> + end;
> + end;
> +
> + 1: { Kommentar bis Zeilenende }
> + begin
> + pos := length(line);
> + break;
> + end;
> +
> + 2: { C-Kommentar }
> + if Matches(line, pos, '*/') then begin
> + f_state := 0;
> + Inc(pos, 2);
> + exit(Highlight(syn_other));
> + end;
> +
> + 3, 6, 7, 8: { Ende eines gefaerbten Worts }
> + begin
> + f_state := 0;
> + exit(Highlight(syn_other));
> + end;
> +
> + 4: { String }
> + case c of
> + '\':
> + begin
> + f_state := 5;
> + Next := Highlight(syn_string_special);
> + Inc(pos);
> + exit;
> + end;
> +
> + '"':
> + begin
> + f_state := 0;
> + Inc(pos);
> + exit(Highlight(syn_other));
> + end;
> + end;
> +
> + 5: { Escaptes Zeichen in einem String }
> + begin
> + f_state := 4;
> + Inc(pos);
> + exit(Highlight(syn_string));
> + end;
> +
> + end;
> +
> + Inc(pos);
> + end;
> +
> + if f_state in [1, 3, 4, 5] then begin
> + f_state := 0;
> + end;
> +end;
> +
> +end.
> diff --git a/src/modules/pas/kedit/syntax_pas.pas b/src/modules/pas/kedit/syntax_pas.pas
> new file mode 100644
> index 0000000..314f9f5
> --- /dev/null
> +++ b/src/modules/pas/kedit/syntax_pas.pas
> @@ -0,0 +1,222 @@
> +unit syntax_pas;
> +{$mode ObjFPC}
> +
> +interface
> +
> +uses syntax;
> +
> +type
> + TSyntax_Pas = class(TSyntax)
> + public
> + procedure StartLine(s: String; state: integer); override;
> + function Next: TSyntaxChange; override;
> + end;
> +
> +
> +implementation
> +const
> + Keywords_Pas: Array [1..81] of String = (
> + 'absolute', 'abstract', 'and', 'array', 'assembler', 'asm',
> + 'automated', 'begin', 'case', 'cdecl',
> + 'class', 'compilerprog', 'const', 'constructor',
> + 'deconstructor', 'default', 'deprecated', 'div', 'do', 'downto',
> + 'dynamic', 'else', 'end', 'export', 'external', 'far',
> + 'forward', 'finalization', 'for',
> + 'function', 'generic', 'goto', 'inline', 'if', 'implementation', 'in',
> + 'interface', 'label', 'message', 'mod', 'near', 'nil', 'not',
> + 'object', 'overlay', 'overload', 'override', 'of', 'or', 'packed',
> + 'platform', 'private', 'procedure',
> + 'program', 'property', 'protected', 'public', 'published', 'raise',
> + 'record', 'reintroduce', 'resourcestring',
> + 'repeat', 'sealed', 'set', 'shl', 'shr', 'specialize', 'stdcall',
> + 'then', 'threadvar', 'to',
> + 'type', 'unit', 'until', 'uses', 'var', 'virtual', 'while', 'with',
> + 'xor'
> + );
> +
> + Types_Pas: Array [1..8] of String = (
> + 'integer', 'byte', 'real', 'char', 'string', 'boolean', 'string',
> + 'file'
> + );
pointer, shortstring, ansistring, pchar, shortint, word, dword, longint
> +
> +
> +procedure TSyntax_Pas.StartLine(s: String; state: integer);
> +begin
> + line := s;
> + f_state := state;
> + pos := 1;
> +
> + case f_state of
> + 1: color := syn_comment;
> + 2: color := syn_comment;
> + 3: color := syn_number;
> + 4: color := syn_string;
> + 5: color := syn_string_special;
> + 6: color := syn_keyword;
> + 7: color := syn_type;
> + 8: color := syn_label;
> + else color := syn_other;
> + end;
> +end;
> +
> +
> +function TSyntax_Pas.Next: TSyntaxChange;
> +var
> + c: char;
> + tmp: integer;
> +begin
> + Next.posY := 0;
> + Next.color := color;
> +
> + while pos <= length(line) do begin
> + c := line[pos];
> +
> + case f_state of
> + 0:
> + case c of
> + '{':
> + if Matches(line, pos, '{$') then begin
> + f_state := 1;
> + exit(Highlight(syn_compiler));
> + end else begin
> + f_state := 2;
> + exit(Highlight(syn_comment));
> + end;
> +
> + '(':
> + if Matches(line, pos, '(*') then begin
> + f_state := 2;
> + exit(Highlight(syn_comment));
> + end;
(* darf nicht durch } beendet werden und umgekehrt. Außerdem sind die
Kommentare in FPC schachtelbar, da müsste man also eigentlich die Tiefe
mitzählen.
> +
> + '/':
> + if (Matches(line, pos, '//')) then begin
> + f_state := 1;
> + exit(Highlight(syn_comment));
> + end;
> +
> + '0' .. '9', '-', '+':
> + begin
> + tmp := MatchesNumber(line, pos);
> +
> + if tmp <> 0 then begin
> + Next := Highlight(syn_number);
> + Inc(pos, tmp);
> + f_state := 3;
> + exit;
> + end;
> + end;
Hex-, Oktal und Binärzahlen fehlen noch. Die fangen mit $, & und % an,
wenn ich mich recht erinnere.
> +
> + '''':
> + begin
> + Next := Highlight(syn_string);
> + Inc(pos);
> + f_state := 4;
> + exit;
> + end;
> +
> + ' ':
> + begin
> + if MatchesTrailingSpace(line, pos) then begin
> + Next := Highlight(syn_trailing_space);
> + pos := length(line) + 1;
> + exit;
> + end;
> + end;
> +
> + else
> + begin
> + tmp := MatchesKeyword(line, pos, Keywords_Pas);
> + if tmp <> 0 then begin
> + Next := Highlight(syn_keyword);
> + Inc(pos, tmp);
> + f_state := 6;
> + exit;
> + end;
> +
> + tmp := MatchesKeyword(line, pos, Types_Pas);
> + if tmp <> 0 then begin
> + Next := Highlight(syn_type);
> + Inc(pos, tmp);
> + f_state := 7;
> + exit;
> + end;
> +
> + tmp := MatchesType(line, pos);
> + if tmp <> 0 then begin
> + Next := Highlight(syn_type);
> + Inc(pos, tmp);
> + f_state := 7;
> + exit;
> + end;
> +
> + tmp := MatchesLabel(line, pos);
> + if tmp <> 0 then begin
> + Next := Highlight(syn_label);
> + Inc(pos, tmp);
> + f_state := 8;
> + exit;
> + end;
> + end;
> + end;
> +
> + 1: { Kommentar bis Zeilenende }
> + begin
> + pos := length(line);
> + break;
> + end;
> +
> + 2: { Pascal-Kommentar }
> + if Matches(line, pos, '}') then begin
> + f_state := 0;
> + Inc(pos, 1);
> + exit(Highlight(syn_other));
> + end else if Matches(line, pos, '*)') then begin
> + f_state := 0;
> + Inc(pos, 2);
> + exit(Highlight(syn_other));
> + end;
> +
> + 3, 6, 7, 8: { Ende eines gefaerbten Worts }
> + begin
> + f_state := 0;
> + exit(Highlight(syn_other));
> + end;
> +
> + 4: { String }
> + case c of
> + {'''''':
> + begin
> + f_state := 5;
> + Next := Highlight(syn_string_special);
> + Inc(pos);
> + exit;
> + end;}
Auskommentierter Code wird normal nicht committet, entweder rein oder
raus. In diesem Fall spricht einiges für Funktionalität rein und Bug
raus. ;-)