1"""
2 pygments.lexers.tact
3 ~~~~~~~~~~~~~~~~~~~~
4
5 Lexers for Tact.
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, bygroups, words
12from pygments.token import Comment, Operator, Keyword, Name, String, \
13 Number, Whitespace, Punctuation
14
15__all__ = ['TactLexer']
16
17
18class TactLexer(RegexLexer):
19 """For Tact source code."""
20
21 name = 'Tact'
22 aliases = ['tact']
23 filenames = ['*.tact']
24 url = "https://tact-lang.org"
25 version_added = '2.18'
26
27 tokens = {
28 'root': [
29 (r'\s+', Whitespace),
30 (r'[.;(),\[\]{}]', Punctuation),
31 (r'\?|!!', Operator),
32 include('comments'),
33 include('import-in'),
34 include('struct-in'),
35 include('contract-or-trait-in'),
36 include('annotation-in'),
37 include('fun-declaration-in'),
38 include('const-declaration-in'),
39 include('statements'),
40 ],
41 'import-in': [
42 (r'((?<=\.\.\.)|(?<![.$]))\b(import)\b(\s*)', bygroups(Punctuation, Keyword, Whitespace), 'import'),
43 ],
44 'import': [
45 (r';', Punctuation, '#pop'),
46 include('comments'),
47 include('string-in'),
48 (r'\s+', Whitespace),
49 ],
50 'struct-in': [
51 (r'((?<=\.\.\.)|(?<![.$]))\b(struct|message)\b', bygroups(Punctuation, Keyword), 'struct'),
52 ],
53 'struct': [
54 include('comments'),
55 include('struct-header'),
56 include('struct-body-in'),
57 (r'\s+', Whitespace),
58 ],
59 'struct-header': [
60 include('comments'),
61 (r'\b\w+', Name.Class),
62 (r'(\()((?:\b0[xX])[0-9a-fA-F][0-9a-fA-F_]*\b)(\))', bygroups(Punctuation, Number.Hex, Punctuation)),
63 (r'(\()((?:\b[0-9]+\b))(\))', bygroups(Punctuation, Number.Integer, Punctuation)),
64 ],
65 'struct-body-in': [
66 (r'\{', Punctuation, 'struct-body'),
67 ],
68 'struct-body': [
69 (r'\}', Punctuation, '#pop:2'),
70 include('comments'),
71 include('field-declaration-in'),
72 ],
73 'contract-or-trait-in': [
74 (r'((?<=\.\.\.)|(?<![.$]))\b(contract|trait)\b', Keyword, 'contract-or-trait'),
75 ],
76 'contract-or-trait': [
77 include('comments'),
78 (r'with', Keyword),
79 (r'\b\w+', Name.Class),
80 include('contract-or-trait-body-in'),
81 (r'\s+', Whitespace),
82 (r',', Punctuation),
83 ],
84 'contract-or-trait-body-in': [
85 (r'\{', Punctuation, 'contract-or-trait-body'),
86 ],
87 'contract-or-trait-body': [
88 (r'\}', Punctuation, '#pop:2'),
89 include('comments'),
90 include('init-declaration-in'),
91 include('receive-declaration-in'),
92 include('bounce-declaration-in'),
93 include('fun-declaration-in'),
94 include('const-declaration-in'),
95 include('field-declaration-in'),
96 (r'\s+', Whitespace),
97 ],
98 'field-declaration-in': [
99 (r'\b\w+', Name.Property, 'field-declaration'),
100 ],
101 'field-declaration': [
102 (r';', Punctuation, '#pop'),
103 include('comments'),
104 include('type-annotation-in'),
105 include('variable-init-in'),
106 ],
107 'const-declaration-in': [
108 (r'(?=\b(?:(?:get|native|extends|mutates|virtual|override|inline|abstract)\s*)*const\b)', Keyword, 'const-declaration'),
109 ],
110 'const-declaration': [
111 (r'(;)', Punctuation, '#pop'),
112 (r'const', Keyword),
113 (words(('get', 'native', 'extends', 'mutates', 'virtual', 'override', 'inline', 'abstract'), suffix=r'\b'), Keyword),
114 (r'\b\w+\b', Name.Constant),
115 include('comments'),
116 include('type-annotation-in'),
117 include('variable-init-in'),
118 (r'\s+', Whitespace),
119 ],
120 'init-declaration-in': [
121 (r'(init)', Keyword, 'init-declaration')
122 ],
123 'init-declaration': [
124 (r'(?<=\})', Punctuation, '#pop'),
125 include('comments'),
126 include('fun-arguments-in'),
127 include('block-declaration-in'),
128 (r'\s+', Whitespace),
129 ],
130 'receive-declaration-in': [
131 (r'(receive|exernal)', Keyword, 'receive-declaration')
132 ],
133 'receive-declaration': [
134 (r'(?<=\})', Punctuation, '#pop'),
135 include('comments'),
136 include('fun-arguments-in'),
137 include('block-declaration-in'),
138 ],
139 'bounce-declaration-in': [
140 (r'(bounced)', Keyword, 'bounce-declaration')
141 ],
142 'bounce-declaration': [
143 (r'(?<=\})', Punctuation, '#pop'),
144 include('comments'),
145 include('fun-arguments-in'),
146 include('block-declaration-in'),
147 ],
148 'fun-declaration-in': [
149 (r'(?=\b(?:(?:get|native|extends|mutates|virtual|override|inline|abstract)\s*)*fun\b)', Keyword, 'fun-declaration')
150 ],
151 'fun-declaration': [
152 (r'(?<=\}|\;)', Punctuation, '#pop'),
153 (r'fun', Keyword),
154 (r'\b(get|native|extends|mutates|virtual|override|inline|abstract)\b', Keyword),
155 (r'\b[\w]+', Name.Function),
156 include('fun-declaration-body'),
157 (r'[,;]', Punctuation),
158 ],
159 'fun-declaration-body': [
160 include('comments'),
161 include('fun-arguments-in'),
162 include('type-annotation-in'),
163 include('block-declaration-in'),
164 (r'\s+', Whitespace),
165 ],
166 'fun-arguments-in': [
167 (r'\(', Punctuation, 'fun-arguments'),
168 ],
169 'fun-arguments': [
170 (r'\)', Punctuation, '#pop'),
171 include('comments'),
172 include('string-in'),
173 include('type-annotation-in'),
174 (r'(self)|(\b[\w]+\b)', bygroups(Name.Variable.Instance, Name.Variable)),
175 (r',', Punctuation),
176 (r'\s+', Whitespace),
177 ],
178 'block-declaration-in': [
179 (r'\{', Punctuation, 'block-declaration')
180 ],
181 'block-declaration': [
182 (r'\}', Punctuation, '#pop'),
183 include('statements'),
184 ],
185 'statements': [
186 include('comments'),
187 include('block-declaration-in'),
188 include('expressions'),
189 ],
190 'annotation-in': [
191 (r'(@)(\w+)(\()', bygroups(Keyword.Pseudo, Keyword, Punctuation), 'annotation')
192 ],
193 'annotation': [
194 (r'\)', Punctuation, '#pop'),
195 include('annotation-argument'),
196 (r'\s+', Whitespace),
197 ],
198 'annotation-argument': [
199 (r'\w+', Name.Function.Magic),
200 ],
201 'expressions': [
202 include('comments'),
203 include('type-annotation-in'),
204 include('keywords'),
205 include('numeric'),
206 include('string-in'),
207 include('variable'),
208 include('function-call'),
209 include('struct-init-in'),
210 ],
211 'struct-init-in': [
212 (r'(\b\w+)(\s*)(\{)', bygroups(Name.Class, Whitespace, Punctuation), 'struct-init')
213 ],
214 'struct-init': [
215 (r'(\})', Punctuation, '#pop'),
216 include('comments'),
217 include('struct-property-in'),
218 (r'\s+', Whitespace),
219 (r',', Punctuation),
220 ],
221 'struct-property-in': [
222 (r'(\b[\w]+)(\s*)(:)', bygroups(Name.Property, Whitespace, Punctuation), 'struct-property')
223 ],
224 'struct-property': [
225 (r'(?=\}|\,)', Punctuation, '#pop'),
226 include('comments'),
227 include('expressions'),
228 (r'\s+', Whitespace),
229 ],
230 'variable-init-in': [
231 (r'(=)', Operator, 'variable-init')
232 ],
233 'variable-init': [
234 (r'(?=\}|\{|\,|\;)',Punctuation, '#pop'),
235 include('comments'),
236 include('expressions'),
237 (r'\s+', Whitespace),
238 ],
239 'type-annotation-in': [
240 (r'(:)(\s+)', bygroups(Punctuation, Whitespace), 'type-annotation')
241 ],
242 'type-annotation': [
243 (r'(?=\{|\;|\=|\,|\))', Punctuation, '#pop'),
244 include('comments'),
245 include('type-as-in'),
246 include('type-generic-in'),
247 (r'\?', Operator),
248 (r'\b\w+', Keyword.Type),
249 (r'\s+', Whitespace),
250 ],
251 'type-generic-in': [
252 (r'<', Punctuation, 'type-generic'),
253 ],
254 'type-generic': [
255 (r'>', Punctuation, '#pop'),
256 include('comments'),
257 include('type-as-in'),
258 (r'\b\w+', Keyword.Type),
259 (r'\s+', Whitespace),
260 (r',', Punctuation),
261 ],
262 'type-as-in': [
263 (r'\b(as)(\s+)', bygroups(Keyword, Whitespace), 'type-as'),
264 ],
265 'type-as': [
266 (r'(?=\{|\;|\=|\,|\)|\>)', Punctuation, '#pop'),
267 include('comments'),
268 (r'\b\w+', Keyword.Type),
269 (r'\s+', Whitespace),
270 ],
271 'keywords': [
272 (words(('if', 'else', 'while', 'do', 'until', 'repeat', 'return', 'extends', 'mutates', 'virtual', 'override', 'inline', 'native', 'let', 'const', 'fun', 'self', 'is', 'initOf', 'map', 'bounced', 'get', 'as'), prefix=r'\b', suffix=r'\b'), Keyword),
273 (r'(<=>|>=|<=|!=|==|\^>>|~>>|>>|<<|\/%|\^%|~%|\^\/|~\/|\+=|-=|\*=|\/=|~\/=|\^\/=|%=|\^%=|<<=|>>=|~>>=|\^>>=|&=|\|=|\^=|\^|=|~|\/|%|-|\*|\+|>|<|&|\||:|\?)', Operator),
274 (words(('true', 'false'), prefix=r'\b', suffix=r'\b'), Keyword.Constant),
275 ],
276 'string-in': [
277 (r'"', String, 'string'),
278 ],
279 'string': [
280 (r'"', String, '#pop'),
281 (r'\\.', String.Escape),
282 (r'[^\\"]+', String.Double),
283 ],
284 'numeric': [
285 (r'(?:\b0[xX])[0-9a-fA-F][0-9a-fA-F_]*\b', Number.Hex),
286 (r'(?:\b[0-9]+\b)', Number.Integer),
287 ],
288 'comments': [
289 (r'//.*', Comment.Single),
290 (r'/\*', Comment.Multiline, 'comments-multiline'),
291 ],
292 'comments-multiline': [
293 (r'\*/', Comment.Multiline, '#pop'),
294 (r'[^*]+', Comment.Multiline),
295 (r'[*]', Comment.Multiline),
296 ],
297 'variable': [
298 (r'\b\w+\b(?!\s*\()(?!\s*\{)', Name.Variable)
299 ],
300 'function-call': [
301 (r'\b\w+\b(?=\s*\()(?!\s*\{)', Name.Function)
302 ],
303 }