felix.py 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. """
  2. pygments.lexers.felix
  3. ~~~~~~~~~~~~~~~~~~~~~
  4. Lexer for the Felix language.
  5. :copyright: Copyright 2006-2024 by the Pygments team, see AUTHORS.
  6. :license: BSD, see LICENSE for details.
  7. """
  8. from pygments.lexer import RegexLexer, include, bygroups, default, words, \
  9. combined
  10. from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
  11. Number, Punctuation, Whitespace
  12. __all__ = ['FelixLexer']
  13. class FelixLexer(RegexLexer):
  14. """
  15. For Felix source code.
  16. """
  17. name = 'Felix'
  18. url = 'http://www.felix-lang.org'
  19. aliases = ['felix', 'flx']
  20. filenames = ['*.flx', '*.flxh']
  21. mimetypes = ['text/x-felix']
  22. version_added = '1.2'
  23. preproc = (
  24. 'elif', 'else', 'endif', 'if', 'ifdef', 'ifndef',
  25. )
  26. keywords = (
  27. '_', '_deref', 'all', 'as',
  28. 'assert', 'attempt', 'call', 'callback', 'case', 'caseno', 'cclass',
  29. 'code', 'compound', 'ctypes', 'do', 'done', 'downto', 'elif', 'else',
  30. 'endattempt', 'endcase', 'endif', 'endmatch', 'enum', 'except',
  31. 'exceptions', 'expect', 'finally', 'for', 'forall', 'forget', 'fork',
  32. 'functor', 'goto', 'ident', 'if', 'incomplete', 'inherit', 'instance',
  33. 'interface', 'jump', 'lambda', 'loop', 'match', 'module', 'namespace',
  34. 'new', 'noexpand', 'nonterm', 'obj', 'of', 'open', 'parse', 'raise',
  35. 'regexp', 'reglex', 'regmatch', 'rename', 'return', 'the', 'then',
  36. 'to', 'type', 'typecase', 'typedef', 'typematch', 'typeof', 'upto',
  37. 'when', 'whilst', 'with', 'yield',
  38. )
  39. keyword_directives = (
  40. '_gc_pointer', '_gc_type', 'body', 'comment', 'const', 'export',
  41. 'header', 'inline', 'lval', 'macro', 'noinline', 'noreturn',
  42. 'package', 'private', 'pod', 'property', 'public', 'publish',
  43. 'requires', 'todo', 'virtual', 'use',
  44. )
  45. keyword_declarations = (
  46. 'def', 'let', 'ref', 'val', 'var',
  47. )
  48. keyword_types = (
  49. 'unit', 'void', 'any', 'bool',
  50. 'byte', 'offset',
  51. 'address', 'caddress', 'cvaddress', 'vaddress',
  52. 'tiny', 'short', 'int', 'long', 'vlong',
  53. 'utiny', 'ushort', 'vshort', 'uint', 'ulong', 'uvlong',
  54. 'int8', 'int16', 'int32', 'int64',
  55. 'uint8', 'uint16', 'uint32', 'uint64',
  56. 'float', 'double', 'ldouble',
  57. 'complex', 'dcomplex', 'lcomplex',
  58. 'imaginary', 'dimaginary', 'limaginary',
  59. 'char', 'wchar', 'uchar',
  60. 'charp', 'charcp', 'ucharp', 'ucharcp',
  61. 'string', 'wstring', 'ustring',
  62. 'cont',
  63. 'array', 'varray', 'list',
  64. 'lvalue', 'opt', 'slice',
  65. )
  66. keyword_constants = (
  67. 'false', 'true',
  68. )
  69. operator_words = (
  70. 'and', 'not', 'in', 'is', 'isin', 'or', 'xor',
  71. )
  72. name_builtins = (
  73. '_svc', 'while',
  74. )
  75. name_pseudo = (
  76. 'root', 'self', 'this',
  77. )
  78. decimal_suffixes = '([tTsSiIlLvV]|ll|LL|([iIuU])(8|16|32|64))?'
  79. tokens = {
  80. 'root': [
  81. include('whitespace'),
  82. # Keywords
  83. (words(('axiom', 'ctor', 'fun', 'gen', 'proc', 'reduce',
  84. 'union'), suffix=r'\b'),
  85. Keyword, 'funcname'),
  86. (words(('class', 'cclass', 'cstruct', 'obj', 'struct'), suffix=r'\b'),
  87. Keyword, 'classname'),
  88. (r'(instance|module|typeclass)\b', Keyword, 'modulename'),
  89. (words(keywords, suffix=r'\b'), Keyword),
  90. (words(keyword_directives, suffix=r'\b'), Name.Decorator),
  91. (words(keyword_declarations, suffix=r'\b'), Keyword.Declaration),
  92. (words(keyword_types, suffix=r'\b'), Keyword.Type),
  93. (words(keyword_constants, suffix=r'\b'), Keyword.Constant),
  94. # Operators
  95. include('operators'),
  96. # Float Literal
  97. # -- Hex Float
  98. (r'0[xX]([0-9a-fA-F_]*\.[0-9a-fA-F_]+|[0-9a-fA-F_]+)'
  99. r'[pP][+\-]?[0-9_]+[lLfFdD]?', Number.Float),
  100. # -- DecimalFloat
  101. (r'[0-9_]+(\.[0-9_]+[eE][+\-]?[0-9_]+|'
  102. r'\.[0-9_]*|[eE][+\-]?[0-9_]+)[lLfFdD]?', Number.Float),
  103. (r'\.(0|[1-9][0-9_]*)([eE][+\-]?[0-9_]+)?[lLfFdD]?',
  104. Number.Float),
  105. # IntegerLiteral
  106. # -- Binary
  107. (rf'0[Bb][01_]+{decimal_suffixes}', Number.Bin),
  108. # -- Octal
  109. (rf'0[0-7_]+{decimal_suffixes}', Number.Oct),
  110. # -- Hexadecimal
  111. (rf'0[xX][0-9a-fA-F_]+{decimal_suffixes}', Number.Hex),
  112. # -- Decimal
  113. (rf'(0|[1-9][0-9_]*){decimal_suffixes}', Number.Integer),
  114. # Strings
  115. ('([rR][cC]?|[cC][rR])"""', String, 'tdqs'),
  116. ("([rR][cC]?|[cC][rR])'''", String, 'tsqs'),
  117. ('([rR][cC]?|[cC][rR])"', String, 'dqs'),
  118. ("([rR][cC]?|[cC][rR])'", String, 'sqs'),
  119. ('[cCfFqQwWuU]?"""', String, combined('stringescape', 'tdqs')),
  120. ("[cCfFqQwWuU]?'''", String, combined('stringescape', 'tsqs')),
  121. ('[cCfFqQwWuU]?"', String, combined('stringescape', 'dqs')),
  122. ("[cCfFqQwWuU]?'", String, combined('stringescape', 'sqs')),
  123. # Punctuation
  124. (r'[\[\]{}:(),;?]', Punctuation),
  125. # Labels
  126. (r'[a-zA-Z_]\w*:>', Name.Label),
  127. # Identifiers
  128. (r'({})\b'.format('|'.join(name_builtins)), Name.Builtin),
  129. (r'({})\b'.format('|'.join(name_pseudo)), Name.Builtin.Pseudo),
  130. (r'[a-zA-Z_]\w*', Name),
  131. ],
  132. 'whitespace': [
  133. (r'\s+', Whitespace),
  134. include('comment'),
  135. # Preprocessor
  136. (r'(#)(\s*)(if)(\s+)(0)',
  137. bygroups(Comment.Preproc, Whitespace, Comment.Preproc,
  138. Whitespace, Comment.Preproc), 'if0'),
  139. (r'#', Comment.Preproc, 'macro'),
  140. ],
  141. 'operators': [
  142. (r'({})\b'.format('|'.join(operator_words)), Operator.Word),
  143. (r'!=|==|<<|>>|\|\||&&|[-~+/*%=<>&^|.$]', Operator),
  144. ],
  145. 'comment': [
  146. (r'//(.*?)$', Comment.Single),
  147. (r'/[*]', Comment.Multiline, 'comment2'),
  148. ],
  149. 'comment2': [
  150. (r'[^/*]', Comment.Multiline),
  151. (r'/[*]', Comment.Multiline, '#push'),
  152. (r'[*]/', Comment.Multiline, '#pop'),
  153. (r'[/*]', Comment.Multiline),
  154. ],
  155. 'if0': [
  156. (r'^(\s*)(#if.*?(?<!\\))(\n)',
  157. bygroups(Whitespace, Comment, Whitespace), '#push'),
  158. (r'^(\s*)(#endif.*?(?<!\\))(\n)',
  159. bygroups(Whitespace, Comment, Whitespace), '#pop'),
  160. (r'(.*?)(\n)', bygroups(Comment, Whitespace)),
  161. ],
  162. 'macro': [
  163. include('comment'),
  164. (r'(import|include)(\s+)(<[^>]*?>)',
  165. bygroups(Comment.Preproc, Whitespace, String), '#pop'),
  166. (r'(import|include)(\s+)("[^"]*?")',
  167. bygroups(Comment.Preproc, Whitespace, String), '#pop'),
  168. (r"(import|include)(\s+)('[^']*?')",
  169. bygroups(Comment.Preproc, Whitespace, String), '#pop'),
  170. (r'[^/\n]+', Comment.Preproc),
  171. # (r'/[*](.|\n)*?[*]/', Comment),
  172. # (r'//.*?\n', Comment, '#pop'),
  173. (r'/', Comment.Preproc),
  174. (r'(?<=\\)\n', Comment.Preproc),
  175. (r'\n', Whitespace, '#pop'),
  176. ],
  177. 'funcname': [
  178. include('whitespace'),
  179. (r'[a-zA-Z_]\w*', Name.Function, '#pop'),
  180. # anonymous functions
  181. (r'(?=\()', Text, '#pop'),
  182. ],
  183. 'classname': [
  184. include('whitespace'),
  185. (r'[a-zA-Z_]\w*', Name.Class, '#pop'),
  186. # anonymous classes
  187. (r'(?=\{)', Text, '#pop'),
  188. ],
  189. 'modulename': [
  190. include('whitespace'),
  191. (r'\[', Punctuation, ('modulename2', 'tvarlist')),
  192. default('modulename2'),
  193. ],
  194. 'modulename2': [
  195. include('whitespace'),
  196. (r'([a-zA-Z_]\w*)', Name.Namespace, '#pop:2'),
  197. ],
  198. 'tvarlist': [
  199. include('whitespace'),
  200. include('operators'),
  201. (r'\[', Punctuation, '#push'),
  202. (r'\]', Punctuation, '#pop'),
  203. (r',', Punctuation),
  204. (r'(with|where)\b', Keyword),
  205. (r'[a-zA-Z_]\w*', Name),
  206. ],
  207. 'stringescape': [
  208. (r'\\([\\abfnrtv"\']|\n|N\{.*?\}|u[a-fA-F0-9]{4}|'
  209. r'U[a-fA-F0-9]{8}|x[a-fA-F0-9]{2}|[0-7]{1,3})', String.Escape)
  210. ],
  211. 'strings': [
  212. (r'%(\([a-zA-Z0-9]+\))?[-#0 +]*([0-9]+|[*])?(\.([0-9]+|[*]))?'
  213. '[hlL]?[E-GXc-giorsux%]', String.Interpol),
  214. (r'[^\\\'"%\n]+', String),
  215. # quotes, percents and backslashes must be parsed one at a time
  216. (r'[\'"\\]', String),
  217. # unhandled string formatting sign
  218. (r'%', String)
  219. # newlines are an error (use "nl" state)
  220. ],
  221. 'nl': [
  222. (r'\n', String)
  223. ],
  224. 'dqs': [
  225. (r'"', String, '#pop'),
  226. # included here again for raw strings
  227. (r'\\\\|\\"|\\\n', String.Escape),
  228. include('strings')
  229. ],
  230. 'sqs': [
  231. (r"'", String, '#pop'),
  232. # included here again for raw strings
  233. (r"\\\\|\\'|\\\n", String.Escape),
  234. include('strings')
  235. ],
  236. 'tdqs': [
  237. (r'"""', String, '#pop'),
  238. include('strings'),
  239. include('nl')
  240. ],
  241. 'tsqs': [
  242. (r"'''", String, '#pop'),
  243. include('strings'),
  244. include('nl')
  245. ],
  246. }