ui: make primary cursor blink even if no lua theme has been loaded
[vis.git] / lexers / dmd.lua
blobf73763a7e860ba36f48af1a0e3cd100f9ed572d3
1 -- Copyright 2006-2016 Mitchell mitchell.att.foicica.com. See LICENSE.
2 -- D LPeg lexer.
3 -- Heavily modified by Brian Schott (@Hackerpilot on Github).
5 local l = require('lexer')
6 local token, word_match = l.token, l.word_match
7 local P, R, S = lpeg.P, lpeg.R, lpeg.S
9 local M = {_NAME = 'dmd'}
11 -- Whitespace.
12 local ws = token(l.WHITESPACE, l.space^1)
14 -- Comments.
15 local line_comment = '//' * l.nonnewline_esc^0
16 local block_comment = '/*' * (l.any - '*/')^0 * P('*/')^-1
17 local nested_comment = l.nested_pair('/+', '+/')
18 local comment = token(l.COMMENT, line_comment + block_comment + nested_comment)
20 -- Strings.
21 local sq_str = l.delimited_range("'", true) * S('cwd')^-1
22 local dq_str = l.delimited_range('"') * S('cwd')^-1
23 local lit_str = 'r' * l.delimited_range('"', false, true) * S('cwd')^-1
24 local bt_str = l.delimited_range('`', false, true) * S('cwd')^-1
25 local hex_str = 'x' * l.delimited_range('"') * S('cwd')^-1
26 local other_hex_str = '\\x' * (l.xdigit * l.xdigit)^1
27 local del_str = l.nested_pair('q"[', ']"') * S('cwd')^-1 +
28 l.nested_pair('q"(', ')"') * S('cwd')^-1 +
29 l.nested_pair('q"{', '}"') * S('cwd')^-1 +
30 l.nested_pair('q"<', '>"') * S('cwd')^-1 +
31 P('q') * l.nested_pair('{', '}') * S('cwd')^-1
32 local string = token(l.STRING, del_str + sq_str + dq_str + lit_str + bt_str +
33 hex_str + other_hex_str)
35 -- Numbers.
36 local dec = l.digit^1 * ('_' * l.digit^1)^0
37 local hex_num = l.hex_num * ('_' * l.xdigit^1)^0
38 local bin_num = '0' * S('bB') * S('01_')^1
39 local oct_num = '0' * S('01234567_')^1
40 local integer = S('+-')^-1 * (hex_num + oct_num + bin_num + dec)
41 local number = token(l.NUMBER, (l.float + integer) * S('uUlLdDfFi')^-1)
43 -- Keywords.
44 local keyword = token(l.KEYWORD, word_match{
45 'abstract', 'align', 'asm', 'assert', 'auto', 'body', 'break', 'case', 'cast',
46 'catch', 'const', 'continue', 'debug', 'default', 'delete',
47 'deprecated', 'do', 'else', 'extern', 'export', 'false', 'final', 'finally',
48 'for', 'foreach', 'foreach_reverse', 'goto', 'if', 'import', 'immutable',
49 'in', 'inout', 'invariant', 'is', 'lazy', 'macro', 'mixin', 'new', 'nothrow',
50 'null', 'out', 'override', 'pragma', 'private', 'protected', 'public', 'pure',
51 'ref', 'return', 'scope', 'shared', 'static', 'super', 'switch',
52 'synchronized', 'this', 'throw','true', 'try', 'typeid', 'typeof', 'unittest',
53 'version', 'virtual', 'volatile', 'while', 'with', '__gshared', '__thread',
54 '__traits', '__vector', '__parameters'
57 -- Types.
58 local type = token(l.TYPE, word_match{
59 'alias', 'bool', 'byte', 'cdouble', 'cent', 'cfloat', 'char', 'class',
60 'creal', 'dchar', 'delegate', 'double', 'enum', 'float', 'function',
61 'idouble', 'ifloat', 'int', 'interface', 'ireal', 'long', 'module', 'package',
62 'ptrdiff_t', 'real', 'short', 'size_t', 'struct', 'template', 'typedef',
63 'ubyte', 'ucent', 'uint', 'ulong', 'union', 'ushort', 'void', 'wchar',
64 'string', 'wstring', 'dstring', 'hash_t', 'equals_t'
67 -- Constants.
68 local constant = token(l.CONSTANT, word_match{
69 '__FILE__', '__LINE__', '__DATE__', '__EOF__', '__TIME__', '__TIMESTAMP__',
70 '__VENDOR__', '__VERSION__', '__FUNCTION__', '__PRETTY_FUNCTION__',
71 '__MODULE__',
74 local class_sequence = token(l.TYPE, P('class') + P('struct')) * ws^1 *
75 token(l.CLASS, l.word)
77 -- Identifiers.
78 local identifier = token(l.IDENTIFIER, l.word)
80 -- Operators.
81 local operator = token(l.OPERATOR, S('?=!<>+-*$/%&|^~.,;()[]{}'))
83 -- Properties.
84 local properties = (type + identifier + operator) * token(l.OPERATOR, '.') *
85 token(l.VARIABLE, word_match{
86 'alignof', 'dig', 'dup', 'epsilon', 'idup', 'im', 'init', 'infinity',
87 'keys', 'length', 'mangleof', 'mant_dig', 'max', 'max_10_exp', 'max_exp',
88 'min', 'min_normal', 'min_10_exp', 'min_exp', 'nan', 'offsetof', 'ptr',
89 're', 'rehash', 'reverse', 'sizeof', 'sort', 'stringof', 'tupleof',
90 'values'
93 -- Preprocs.
94 local annotation = token('annotation', '@' * l.word^1)
95 local preproc = token(l.PREPROCESSOR, '#' * l.nonnewline^0)
97 -- Traits.
98 local traits_list = token('traits', word_match{
99 'allMembers', 'classInstanceSize', 'compiles', 'derivedMembers',
100 'getAttributes', 'getMember', 'getOverloads', 'getProtection', 'getUnitTests',
101 'getVirtualFunctions', 'getVirtualIndex', 'getVirtualMethods', 'hasMember',
102 'identifier', 'isAbstractClass', 'isAbstractFunction', 'isArithmetic',
103 'isAssociativeArray', 'isFinalClass', 'isFinalFunction', 'isFloating',
104 'isIntegral', 'isLazy', 'isNested', 'isOut', 'isOverrideFunction', 'isPOD',
105 'isRef', 'isSame', 'isScalar', 'isStaticArray', 'isStaticFunction',
106 'isUnsigned', 'isVirtualFunction', 'isVirtualMethod', 'parent'
109 local scopes_list = token('scopes', word_match{'exit', 'success', 'failure'})
111 -- versions
112 local versions_list = token('versions', word_match{
113 'AArch64', 'AIX', 'all', 'Alpha', 'Alpha_HardFloat', 'Alpha_SoftFloat',
114 'Android', 'ARM', 'ARM_HardFloat', 'ARM_SoftFloat', 'ARM_SoftFP', 'ARM_Thumb',
115 'assert', 'BigEndian', 'BSD', 'Cygwin', 'D_Coverage', 'D_Ddoc', 'D_HardFloat',
116 'DigitalMars', 'D_InlineAsm_X86', 'D_InlineAsm_X86_64', 'D_LP64',
117 'D_NoBoundsChecks', 'D_PIC', 'DragonFlyBSD', 'D_SIMD', 'D_SoftFloat',
118 'D_Version2', 'D_X32', 'FreeBSD', 'GNU', 'Haiku', 'HPPA', 'HPPA64', 'Hurd',
119 'IA64', 'LDC', 'linux', 'LittleEndian', 'MIPS32', 'MIPS64', 'MIPS_EABI',
120 'MIPS_HardFloat', 'MIPS_N32', 'MIPS_N64', 'MIPS_O32', 'MIPS_O64',
121 'MIPS_SoftFloat', 'NetBSD', 'none', 'OpenBSD', 'OSX', 'Posix', 'PPC', 'PPC64',
122 'PPC_HardFloat', 'PPC_SoftFloat', 'S390', 'S390X', 'SDC', 'SH', 'SH64',
123 'SkyOS', 'Solaris', 'SPARC', 'SPARC64', 'SPARC_HardFloat', 'SPARC_SoftFloat',
124 'SPARC_V8Plus', 'SysV3', 'SysV4', 'unittest', 'Win32', 'Win64', 'Windows',
125 'X86', 'X86_64'
128 local versions = token(l.KEYWORD, 'version') * l.space^0 *
129 token(l.OPERATOR, '(') * l.space^0 * versions_list
131 local scopes = token(l.KEYWORD, 'scope') * l.space^0 *
132 token(l.OPERATOR, '(') * l.space^0 * scopes_list
134 local traits = token(l.KEYWORD, '__traits') * l.space^0 *
135 token(l.OPERATOR, '(') * l.space^0 * traits_list
137 local func = token(l.FUNCTION, l.word) *
138 #(l.space^0 * (P('!') * l.word^-1 * l.space^-1)^-1 * P('('))
140 M._rules = {
141 {'whitespace', ws},
142 {'class', class_sequence},
143 {'traits', traits},
144 {'versions', versions},
145 {'scopes', scopes},
146 {'keyword', keyword},
147 {'variable', properties},
148 {'type', type},
149 {'function', func},
150 {'constant', constant},
151 {'string', string},
152 {'identifier', identifier},
153 {'comment', comment},
154 {'number', number},
155 {'preproc', preproc},
156 {'operator', operator},
157 {'annotation', annotation},
160 M._tokenstyles = {
161 annotation = l.STYLE_PREPROCESSOR,
162 traits = l.STYLE_CLASS,
163 versions = l.STYLE_CONSTANT,
164 scopes = l.STYLE_CONSTANT
167 M._foldsymbols = {
168 _patterns = {'[{}]', '/[*+]', '[*+]/', '//'},
169 [l.OPERATOR] = {['{'] = 1, ['}'] = -1},
170 [l.COMMENT] = {
171 ['/*'] = 1, ['*/'] = -1, ['/+'] = 1, ['+/'] = -1,
172 ['//'] = l.fold_line_comments('//')
176 return M