fantom.py 9.7 KB

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