|
1 # -*- coding: utf-8 -*- |
|
2 """ |
|
3 pygments.lexers.fantom |
|
4 ~~~~~~~~~~~~~~~~~~~~~~ |
|
5 |
|
6 Lexer for the Fantom language. |
|
7 |
|
8 :copyright: Copyright 2006-2014 by the Pygments team, see AUTHORS. |
|
9 :license: BSD, see LICENSE for details. |
|
10 """ |
|
11 |
|
12 from string import Template |
|
13 |
|
14 from pygments.lexer import RegexLexer, include, bygroups, using, \ |
|
15 this, default, words |
|
16 from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ |
|
17 Number, Punctuation, Literal |
|
18 |
|
19 __all__ = ['FantomLexer'] |
|
20 |
|
21 |
|
22 class FantomLexer(RegexLexer): |
|
23 """ |
|
24 For Fantom source code. |
|
25 |
|
26 .. versionadded:: 1.5 |
|
27 """ |
|
28 name = 'Fantom' |
|
29 aliases = ['fan'] |
|
30 filenames = ['*.fan'] |
|
31 mimetypes = ['application/x-fantom'] |
|
32 |
|
33 # often used regexes |
|
34 def s(str): |
|
35 return Template(str).substitute( |
|
36 dict( |
|
37 pod=r'[\"\w\.]+', |
|
38 eos=r'\n|;', |
|
39 id=r'[a-zA-Z_]\w*', |
|
40 # all chars which can be part of type definition. Starts with |
|
41 # either letter, or [ (maps), or | (funcs) |
|
42 type=r'(?:\[|[a-zA-Z_]|\|)[:\w\[\]|\->?]*?', |
|
43 ) |
|
44 ) |
|
45 |
|
46 tokens = { |
|
47 'comments': [ |
|
48 (r'(?s)/\*.*?\*/', Comment.Multiline), # Multiline |
|
49 (r'//.*?\n', Comment.Single), # Single line |
|
50 # TODO: highlight references in fandocs |
|
51 (r'\*\*.*?\n', Comment.Special), # Fandoc |
|
52 (r'#.*\n', Comment.Single) # Shell-style |
|
53 ], |
|
54 'literals': [ |
|
55 (r'\b-?[\d_]+(ns|ms|sec|min|hr|day)', Number), # Duration |
|
56 (r'\b-?[\d_]*\.[\d_]+(ns|ms|sec|min|hr|day)', Number), # Duration with dot |
|
57 (r'\b-?(\d+)?\.\d+(f|F|d|D)?', Number.Float), # Float/Decimal |
|
58 (r'\b-?0x[0-9a-fA-F_]+', Number.Hex), # Hex |
|
59 (r'\b-?[\d_]+', Number.Integer), # Int |
|
60 (r"'\\.'|'[^\\]'|'\\u[0-9a-f]{4}'", String.Char), # Char |
|
61 (r'"', Punctuation, 'insideStr'), # Opening quote |
|
62 (r'`', Punctuation, 'insideUri'), # Opening accent |
|
63 (r'\b(true|false|null)\b', Keyword.Constant), # Bool & null |
|
64 (r'(?:(\w+)(::))?(\w+)(<\|)(.*?)(\|>)', # DSL |
|
65 bygroups(Name.Namespace, Punctuation, Name.Class, |
|
66 Punctuation, String, Punctuation)), |
|
67 (r'(?:(\w+)(::))?(\w+)?(#)(\w+)?', # Type/slot literal |
|
68 bygroups(Name.Namespace, Punctuation, Name.Class, |
|
69 Punctuation, Name.Function)), |
|
70 (r'\[,\]', Literal), # Empty list |
|
71 (s(r'($type)(\[,\])'), # Typed empty list |
|
72 bygroups(using(this, state='inType'), Literal)), |
|
73 (r'\[:\]', Literal), # Empty Map |
|
74 (s(r'($type)(\[:\])'), |
|
75 bygroups(using(this, state='inType'), Literal)), |
|
76 ], |
|
77 'insideStr': [ |
|
78 (r'\\\\', String.Escape), # Escaped backslash |
|
79 (r'\\"', String.Escape), # Escaped " |
|
80 (r'\\`', String.Escape), # Escaped ` |
|
81 (r'\$\w+', String.Interpol), # Subst var |
|
82 (r'\$\{.*?\}', String.Interpol), # Subst expr |
|
83 (r'"', Punctuation, '#pop'), # Closing quot |
|
84 (r'.', String) # String content |
|
85 ], |
|
86 'insideUri': [ # TODO: remove copy/paste str/uri |
|
87 (r'\\\\', String.Escape), # Escaped backslash |
|
88 (r'\\"', String.Escape), # Escaped " |
|
89 (r'\\`', String.Escape), # Escaped ` |
|
90 (r'\$\w+', String.Interpol), # Subst var |
|
91 (r'\$\{.*?\}', String.Interpol), # Subst expr |
|
92 (r'`', Punctuation, '#pop'), # Closing tick |
|
93 (r'.', String.Backtick) # URI content |
|
94 ], |
|
95 'protectionKeywords': [ |
|
96 (r'\b(public|protected|private|internal)\b', Keyword), |
|
97 ], |
|
98 'typeKeywords': [ |
|
99 (r'\b(abstract|final|const|native|facet|enum)\b', Keyword), |
|
100 ], |
|
101 'methodKeywords': [ |
|
102 (r'\b(abstract|native|once|override|static|virtual|final)\b', |
|
103 Keyword), |
|
104 ], |
|
105 'fieldKeywords': [ |
|
106 (r'\b(abstract|const|final|native|override|static|virtual|' |
|
107 r'readonly)\b', Keyword) |
|
108 ], |
|
109 'otherKeywords': [ |
|
110 (words(( |
|
111 'try', 'catch', 'throw', 'finally', 'for', 'if', 'else', 'while', |
|
112 'as', 'is', 'isnot', 'switch', 'case', 'default', 'continue', |
|
113 'break', 'do', 'return', 'get', 'set'), prefix=r'\b', suffix=r'\b'), |
|
114 Keyword), |
|
115 (r'\b(it|this|super)\b', Name.Builtin.Pseudo), |
|
116 ], |
|
117 'operators': [ |
|
118 (r'\+\+|\-\-|\+|\-|\*|/|\|\||&&|<=>|<=|<|>=|>|=|!|\[|\]', Operator) |
|
119 ], |
|
120 'inType': [ |
|
121 (r'[\[\]|\->:?]', Punctuation), |
|
122 (s(r'$id'), Name.Class), |
|
123 default('#pop'), |
|
124 |
|
125 ], |
|
126 'root': [ |
|
127 include('comments'), |
|
128 include('protectionKeywords'), |
|
129 include('typeKeywords'), |
|
130 include('methodKeywords'), |
|
131 include('fieldKeywords'), |
|
132 include('literals'), |
|
133 include('otherKeywords'), |
|
134 include('operators'), |
|
135 (r'using\b', Keyword.Namespace, 'using'), # Using stmt |
|
136 (r'@\w+', Name.Decorator, 'facet'), # Symbol |
|
137 (r'(class|mixin)(\s+)(\w+)', bygroups(Keyword, Text, Name.Class), |
|
138 'inheritance'), # Inheritance list |
|
139 |
|
140 # Type var := val |
|
141 (s(r'($type)([ \t]+)($id)(\s*)(:=)'), |
|
142 bygroups(using(this, state='inType'), Text, |
|
143 Name.Variable, Text, Operator)), |
|
144 |
|
145 # var := val |
|
146 (s(r'($id)(\s*)(:=)'), |
|
147 bygroups(Name.Variable, Text, Operator)), |
|
148 |
|
149 # .someId( or ->someId( ### |
|
150 (s(r'(\.|(?:\->))($id)(\s*)(\()'), |
|
151 bygroups(Operator, Name.Function, Text, Punctuation), |
|
152 'insideParen'), |
|
153 |
|
154 # .someId or ->someId |
|
155 (s(r'(\.|(?:\->))($id)'), |
|
156 bygroups(Operator, Name.Function)), |
|
157 |
|
158 # new makeXXX ( |
|
159 (r'(new)(\s+)(make\w*)(\s*)(\()', |
|
160 bygroups(Keyword, Text, Name.Function, Text, Punctuation), |
|
161 'insideMethodDeclArgs'), |
|
162 |
|
163 # Type name ( |
|
164 (s(r'($type)([ \t]+)' # Return type and whitespace |
|
165 r'($id)(\s*)(\()'), # method name + open brace |
|
166 bygroups(using(this, state='inType'), Text, |
|
167 Name.Function, Text, Punctuation), |
|
168 'insideMethodDeclArgs'), |
|
169 |
|
170 # ArgType argName, |
|
171 (s(r'($type)(\s+)($id)(\s*)(,)'), |
|
172 bygroups(using(this, state='inType'), Text, Name.Variable, |
|
173 Text, Punctuation)), |
|
174 |
|
175 # ArgType argName) |
|
176 # Covered in 'insideParen' state |
|
177 |
|
178 # ArgType argName -> ArgType| |
|
179 (s(r'($type)(\s+)($id)(\s*)(\->)(\s*)($type)(\|)'), |
|
180 bygroups(using(this, state='inType'), Text, Name.Variable, |
|
181 Text, Punctuation, Text, using(this, state='inType'), |
|
182 Punctuation)), |
|
183 |
|
184 # ArgType argName| |
|
185 (s(r'($type)(\s+)($id)(\s*)(\|)'), |
|
186 bygroups(using(this, state='inType'), Text, Name.Variable, |
|
187 Text, Punctuation)), |
|
188 |
|
189 # Type var |
|
190 (s(r'($type)([ \t]+)($id)'), |
|
191 bygroups(using(this, state='inType'), Text, |
|
192 Name.Variable)), |
|
193 |
|
194 (r'\(', Punctuation, 'insideParen'), |
|
195 (r'\{', Punctuation, 'insideBrace'), |
|
196 (r'.', Text) |
|
197 ], |
|
198 'insideParen': [ |
|
199 (r'\)', Punctuation, '#pop'), |
|
200 include('root'), |
|
201 ], |
|
202 'insideMethodDeclArgs': [ |
|
203 (r'\)', Punctuation, '#pop'), |
|
204 (s(r'($type)(\s+)($id)(\s*)(\))'), |
|
205 bygroups(using(this, state='inType'), Text, Name.Variable, |
|
206 Text, Punctuation), '#pop'), |
|
207 include('root'), |
|
208 ], |
|
209 'insideBrace': [ |
|
210 (r'\}', Punctuation, '#pop'), |
|
211 include('root'), |
|
212 ], |
|
213 'inheritance': [ |
|
214 (r'\s+', Text), # Whitespace |
|
215 (r':|,', Punctuation), |
|
216 (r'(?:(\w+)(::))?(\w+)', |
|
217 bygroups(Name.Namespace, Punctuation, Name.Class)), |
|
218 (r'\{', Punctuation, '#pop') |
|
219 ], |
|
220 'using': [ |
|
221 (r'[ \t]+', Text), # consume whitespaces |
|
222 (r'(\[)(\w+)(\])', |
|
223 bygroups(Punctuation, Comment.Special, Punctuation)), # ffi |
|
224 (r'(\")?([\w.]+)(\")?', |
|
225 bygroups(Punctuation, Name.Namespace, Punctuation)), # podname |
|
226 (r'::', Punctuation, 'usingClass'), |
|
227 default('#pop') |
|
228 ], |
|
229 'usingClass': [ |
|
230 (r'[ \t]+', Text), # consume whitespaces |
|
231 (r'(as)(\s+)(\w+)', |
|
232 bygroups(Keyword.Declaration, Text, Name.Class), '#pop:2'), |
|
233 (r'[\w$]+', Name.Class), |
|
234 default('#pop:2') # jump out to root state |
|
235 ], |
|
236 'facet': [ |
|
237 (r'\s+', Text), |
|
238 (r'\{', Punctuation, 'facetFields'), |
|
239 default('#pop') |
|
240 ], |
|
241 'facetFields': [ |
|
242 include('comments'), |
|
243 include('literals'), |
|
244 include('operators'), |
|
245 (r'\s+', Text), |
|
246 (r'(\s*)(\w+)(\s*)(=)', bygroups(Text, Name, Text, Operator)), |
|
247 (r'\}', Punctuation, '#pop'), |
|
248 (r'.', Text) |
|
249 ], |
|
250 } |