1"""
2 pygments.lexers.kuin
3 ~~~~~~~~~~~~~~~~~~~~
4
5 Lexers for the Kuin language.
6
7 :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8 :license: BSD, see LICENSE for details.
9"""
10
11from pygments.lexer import RegexLexer, include, using, this, bygroups, words
12from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
13 Number, Punctuation, Whitespace
14
15__all__ = ['KuinLexer']
16
17
18class KuinLexer(RegexLexer):
19 """
20 For Kuin source code.
21 """
22 name = 'Kuin'
23 url = 'https://github.com/kuina/Kuin'
24 aliases = ['kuin']
25 filenames = ['*.kn']
26 version_added = '2.9'
27
28 tokens = {
29 'root': [
30 include('statement'),
31 ],
32 'statement': [
33 # Whitespace / Comment
34 include('whitespace'),
35
36 # Block-statement
37 (r'(\+?)([ \t]*)(\*?)([ \t]*)(\bfunc)([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*)',
38 bygroups(Keyword,Whitespace, Keyword, Whitespace, Keyword,
39 using(this), Name.Function), 'func_'),
40 (r'\b(class)([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*)',
41 bygroups(Keyword, using(this), Name.Class), 'class_'),
42 (r'\b(enum)([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*)',
43 bygroups(Keyword, using(this), Name.Constant), 'enum_'),
44 (r'\b(block)\b(?:([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*))?',
45 bygroups(Keyword, using(this), Name.Other), 'block_'),
46 (r'\b(ifdef)\b(?:([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*))?',
47 bygroups(Keyword, using(this), Name.Other), 'ifdef_'),
48 (r'\b(if)\b(?:([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*))?',
49 bygroups(Keyword, using(this), Name.Other), 'if_'),
50 (r'\b(switch)\b(?:([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*))?',
51 bygroups(Keyword, using(this), Name.Other), 'switch_'),
52 (r'\b(while)\b(?:([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*))?',
53 bygroups(Keyword, using(this), Name.Other), 'while_'),
54 (r'\b(for)\b(?:([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*))?',
55 bygroups(Keyword, using(this), Name.Other), 'for_'),
56 (r'\b(foreach)\b(?:([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*))?',
57 bygroups(Keyword, using(this), Name.Other), 'foreach_'),
58 (r'\b(try)\b(?:([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*))?',
59 bygroups(Keyword, using(this), Name.Other), 'try_'),
60
61 # Line-statement
62 (r'\b(do)\b', Keyword, 'do'),
63 (r'(\+?[ \t]*\bvar)\b', Keyword, 'var'),
64 (r'\b(const)\b', Keyword, 'const'),
65 (r'\b(ret)\b', Keyword, 'ret'),
66 (r'\b(throw)\b', Keyword, 'throw'),
67 (r'\b(alias)\b', Keyword, 'alias'),
68 (r'\b(assert)\b', Keyword, 'assert'),
69 (r'\|', Text, 'continued_line'),
70 (r'[ \t]*\n', Whitespace),
71 ],
72
73 # Whitespace / Comment
74 'whitespace': [
75 (r'^([ \t]*)(;.*)', bygroups(Comment.Single, Whitespace)),
76 (r'[ \t]+(?![; \t])', Whitespace),
77 (r'\{', Comment.Multiline, 'multiline_comment'),
78 ],
79 'multiline_comment': [
80 (r'\{', Comment.Multiline, 'multiline_comment'),
81 (r'(?:\s*;.*|[^{}\n]+)', Comment.Multiline),
82 (r'\n', Comment.Multiline),
83 (r'\}', Comment.Multiline, '#pop'),
84 ],
85
86 # Block-statement
87 'func_': [
88 include('expr'),
89 (r'\n', Whitespace, 'func'),
90 ],
91 'func': [
92 (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(func)\b',
93 bygroups(Keyword, using(this), Keyword), '#pop:2'),
94 include('statement'),
95 ],
96 'class_': [
97 include('expr'),
98 (r'\n', Whitespace, 'class'),
99 ],
100 'class': [
101 (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(class)\b',
102 bygroups(Keyword, using(this), Keyword), '#pop:2'),
103 include('statement'),
104 ],
105 'enum_': [
106 include('expr'),
107 (r'\n', Whitespace, 'enum'),
108 ],
109 'enum': [
110 (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(enum)\b',
111 bygroups(Keyword, using(this), Keyword), '#pop:2'),
112 include('expr'),
113 (r'\n', Whitespace),
114 ],
115 'block_': [
116 include('expr'),
117 (r'\n', Whitespace, 'block'),
118 ],
119 'block': [
120 (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(block)\b',
121 bygroups(Keyword, using(this), Keyword), '#pop:2'),
122 include('statement'),
123 include('break'),
124 include('skip'),
125 ],
126 'ifdef_': [
127 include('expr'),
128 (r'\n', Whitespace, 'ifdef'),
129 ],
130 'ifdef': [
131 (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(ifdef)\b',
132 bygroups(Keyword, using(this), Keyword), '#pop:2'),
133 (words(('rls', 'dbg'), prefix=r'\b', suffix=r'\b'),
134 Keyword.Constant, 'ifdef_sp'),
135 include('statement'),
136 include('break'),
137 include('skip'),
138 ],
139 'ifdef_sp': [
140 include('expr'),
141 (r'\n', Whitespace, '#pop'),
142 ],
143 'if_': [
144 include('expr'),
145 (r'\n', Whitespace, 'if'),
146 ],
147 'if': [
148 (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(if)\b',
149 bygroups(Keyword, using(this), Keyword), '#pop:2'),
150 (words(('elif', 'else'), prefix=r'\b', suffix=r'\b'), Keyword, 'if_sp'),
151 include('statement'),
152 include('break'),
153 include('skip'),
154 ],
155 'if_sp': [
156 include('expr'),
157 (r'\n', Whitespace, '#pop'),
158 ],
159 'switch_': [
160 include('expr'),
161 (r'\n', Whitespace, 'switch'),
162 ],
163 'switch': [
164 (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(switch)\b',
165 bygroups(Keyword, using(this), Keyword), '#pop:2'),
166 (words(('case', 'default', 'to'), prefix=r'\b', suffix=r'\b'),
167 Keyword, 'switch_sp'),
168 include('statement'),
169 include('break'),
170 include('skip'),
171 ],
172 'switch_sp': [
173 include('expr'),
174 (r'\n', Whitespace, '#pop'),
175 ],
176 'while_': [
177 include('expr'),
178 (r'\n', Whitespace, 'while'),
179 ],
180 'while': [
181 (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(while)\b',
182 bygroups(Keyword, using(this), Keyword), '#pop:2'),
183 include('statement'),
184 include('break'),
185 include('skip'),
186 ],
187 'for_': [
188 include('expr'),
189 (r'\n', Whitespace, 'for'),
190 ],
191 'for': [
192 (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(for)\b',
193 bygroups(Keyword, using(this), Keyword), '#pop:2'),
194 include('statement'),
195 include('break'),
196 include('skip'),
197 ],
198 'foreach_': [
199 include('expr'),
200 (r'\n', Whitespace, 'foreach'),
201 ],
202 'foreach': [
203 (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(foreach)\b',
204 bygroups(Keyword, using(this), Keyword), '#pop:2'),
205 include('statement'),
206 include('break'),
207 include('skip'),
208 ],
209 'try_': [
210 include('expr'),
211 (r'\n', Whitespace, 'try'),
212 ],
213 'try': [
214 (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(try)\b',
215 bygroups(Keyword, using(this), Keyword), '#pop:2'),
216 (words(('catch', 'finally', 'to'), prefix=r'\b', suffix=r'\b'),
217 Keyword, 'try_sp'),
218 include('statement'),
219 include('break'),
220 include('skip'),
221 ],
222 'try_sp': [
223 include('expr'),
224 (r'\n', Whitespace, '#pop'),
225 ],
226
227 # Line-statement
228 'break': [
229 (r'\b(break)\b([ \t]+)([a-zA-Z_][0-9a-zA-Z_]*)',
230 bygroups(Keyword, using(this), Name.Other)),
231 ],
232 'skip': [
233 (r'\b(skip)\b([ \t]+)([a-zA-Z_][0-9a-zA-Z_]*)',
234 bygroups(Keyword, using(this), Name.Other)),
235 ],
236 'alias': [
237 include('expr'),
238 (r'\n', Whitespace, '#pop'),
239 ],
240 'assert': [
241 include('expr'),
242 (r'\n', Whitespace, '#pop'),
243 ],
244 'const': [
245 include('expr'),
246 (r'\n', Whitespace, '#pop'),
247 ],
248 'do': [
249 include('expr'),
250 (r'\n', Whitespace, '#pop'),
251 ],
252 'ret': [
253 include('expr'),
254 (r'\n', Whitespace, '#pop'),
255 ],
256 'throw': [
257 include('expr'),
258 (r'\n', Whitespace, '#pop'),
259 ],
260 'var': [
261 include('expr'),
262 (r'\n', Whitespace, '#pop'),
263 ],
264 'continued_line': [
265 include('expr'),
266 (r'\n', Whitespace, '#pop'),
267 ],
268
269 'expr': [
270 # Whitespace / Comment
271 include('whitespace'),
272
273 # Punctuation
274 (r'\(', Punctuation,),
275 (r'\)', Punctuation,),
276 (r'\[', Punctuation,),
277 (r'\]', Punctuation,),
278 (r',', Punctuation),
279
280 # Keyword
281 (words((
282 'true', 'false', 'null', 'inf'
283 ), prefix=r'\b', suffix=r'\b'), Keyword.Constant),
284 (words((
285 'me'
286 ), prefix=r'\b', suffix=r'\b'), Keyword),
287 (words((
288 'bit16', 'bit32', 'bit64', 'bit8', 'bool',
289 'char', 'class', 'dict', 'enum', 'float', 'func',
290 'int', 'list', 'queue', 'stack'
291 ), prefix=r'\b', suffix=r'\b'), Keyword.Type),
292
293 # Number
294 (r'\b[0-9]\.[0-9]+(?!\.)(:?e[\+-][0-9]+)?\b', Number.Float),
295 (r'\b2#[01]+(?:b(?:8|16|32|64))?\b', Number.Bin),
296 (r'\b8#[0-7]+(?:b(?:8|16|32|64))?\b', Number.Oct),
297 (r'\b16#[0-9A-F]+(?:b(?:8|16|32|64))?\b', Number.Hex),
298 (r'\b[0-9]+(?:b(?:8|16|32|64))?\b', Number.Decimal),
299
300 # String / Char
301 (r'"', String.Double, 'string'),
302 (r"'(?:\\.|.)+?'", String.Char),
303
304 # Operator
305 (r'(?:\.|\$(?:>|<)?)', Operator),
306 (r'(?:\^)', Operator),
307 (r'(?:\+|-|!|##?)', Operator),
308 (r'(?:\*|/|%)', Operator),
309 (r'(?:~)', Operator),
310 (r'(?:(?:=|<>)(?:&|\$)?|<=?|>=?)', Operator),
311 (r'(?:&)', Operator),
312 (r'(?:\|)', Operator),
313 (r'(?:\?)', Operator),
314 (r'(?::(?::|\+|-|\*|/|%|\^|~)?)', Operator),
315
316 # Identifier
317 (r"\b([a-zA-Z_][0-9a-zA-Z_]*)(?=@)\b", Name),
318 (r"(@)?\b([a-zA-Z_][0-9a-zA-Z_]*)\b",
319 bygroups(Name.Other, Name.Variable)),
320 ],
321
322 # String
323 'string': [
324 (r'(?:\\[^{\n]|[^"\\])+', String.Double),
325 (r'\\\{', String.Double, 'toStrInString'),
326 (r'"', String.Double, '#pop'),
327 ],
328 'toStrInString': [
329 include('expr'),
330 (r'\}', String.Double, '#pop'),
331 ],
332 }