gdscript.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. """
  2. pygments.lexers.gdscript
  3. ~~~~~~~~~~~~~~~~~~~~~~~~
  4. Lexer for GDScript.
  5. Modified by Daniel J. Ramirez <djrmuv@gmail.com> based on the original
  6. python.py.
  7. :copyright: Copyright 2006-2021 by the Pygments team, see AUTHORS.
  8. :license: BSD, see LICENSE for details.
  9. """
  10. import re
  11. from pygments.lexer import RegexLexer, include, bygroups, default, words, \
  12. combined
  13. from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
  14. Number, Punctuation
  15. __all__ = ["GDScriptLexer"]
  16. line_re = re.compile(".*?\n")
  17. class GDScriptLexer(RegexLexer):
  18. """
  19. For `GDScript source code <https://www.godotengine.org>`_.
  20. """
  21. name = "GDScript"
  22. aliases = ["gdscript", "gd"]
  23. filenames = ["*.gd"]
  24. mimetypes = ["text/x-gdscript", "application/x-gdscript"]
  25. def innerstring_rules(ttype):
  26. return [
  27. # the old style '%s' % (...) string formatting
  28. (
  29. r"%(\(\w+\))?[-#0 +]*([0-9]+|[*])?(\.([0-9]+|[*]))?"
  30. "[hlL]?[E-GXc-giorsux%]",
  31. String.Interpol,
  32. ),
  33. # backslashes, quotes and formatting signs must be parsed one at a time
  34. (r'[^\\\'"%\n]+', ttype),
  35. (r'[\'"\\]', ttype),
  36. # unhandled string formatting sign
  37. (r"%", ttype),
  38. # newlines are an error (use "nl" state)
  39. ]
  40. tokens = {
  41. "root": [
  42. (r"\n", Text),
  43. (
  44. r'^(\s*)([rRuUbB]{,2})("""(?:.|\n)*?""")',
  45. bygroups(Text, String.Affix, String.Doc),
  46. ),
  47. (
  48. r"^(\s*)([rRuUbB]{,2})('''(?:.|\n)*?''')",
  49. bygroups(Text, String.Affix, String.Doc),
  50. ),
  51. (r"[^\S\n]+", Text),
  52. (r"#.*$", Comment.Single),
  53. (r"[]{}:(),;[]", Punctuation),
  54. (r"\\\n", Text),
  55. (r"\\", Text),
  56. (r"(in|and|or|not)\b", Operator.Word),
  57. (
  58. r"!=|==|<<|>>|&&|\+=|-=|\*=|/=|%=|&=|\|=|\|\||[-~+/*%=<>&^.!|$]",
  59. Operator,
  60. ),
  61. include("keywords"),
  62. (r"(func)((?:\s|\\\s)+)", bygroups(Keyword, Text), "funcname"),
  63. (r"(class)((?:\s|\\\s)+)", bygroups(Keyword, Text), "classname"),
  64. include("builtins"),
  65. (
  66. '([rR]|[uUbB][rR]|[rR][uUbB])(""")',
  67. bygroups(String.Affix, String.Double),
  68. "tdqs",
  69. ),
  70. (
  71. "([rR]|[uUbB][rR]|[rR][uUbB])(''')",
  72. bygroups(String.Affix, String.Single),
  73. "tsqs",
  74. ),
  75. (
  76. '([rR]|[uUbB][rR]|[rR][uUbB])(")',
  77. bygroups(String.Affix, String.Double),
  78. "dqs",
  79. ),
  80. (
  81. "([rR]|[uUbB][rR]|[rR][uUbB])(')",
  82. bygroups(String.Affix, String.Single),
  83. "sqs",
  84. ),
  85. (
  86. '([uUbB]?)(""")',
  87. bygroups(String.Affix, String.Double),
  88. combined("stringescape", "tdqs"),
  89. ),
  90. (
  91. "([uUbB]?)(''')",
  92. bygroups(String.Affix, String.Single),
  93. combined("stringescape", "tsqs"),
  94. ),
  95. (
  96. '([uUbB]?)(")',
  97. bygroups(String.Affix, String.Double),
  98. combined("stringescape", "dqs"),
  99. ),
  100. (
  101. "([uUbB]?)(')",
  102. bygroups(String.Affix, String.Single),
  103. combined("stringescape", "sqs"),
  104. ),
  105. include("name"),
  106. include("numbers"),
  107. ],
  108. "keywords": [
  109. (
  110. words(
  111. (
  112. "and",
  113. "in",
  114. "not",
  115. "or",
  116. "as",
  117. "breakpoint",
  118. "class",
  119. "class_name",
  120. "extends",
  121. "is",
  122. "func",
  123. "setget",
  124. "signal",
  125. "tool",
  126. "const",
  127. "enum",
  128. "export",
  129. "onready",
  130. "static",
  131. "var",
  132. "break",
  133. "continue",
  134. "if",
  135. "elif",
  136. "else",
  137. "for",
  138. "pass",
  139. "return",
  140. "match",
  141. "while",
  142. "remote",
  143. "master",
  144. "puppet",
  145. "remotesync",
  146. "mastersync",
  147. "puppetsync",
  148. ),
  149. suffix=r"\b",
  150. ),
  151. Keyword,
  152. ),
  153. ],
  154. "builtins": [
  155. (
  156. words(
  157. (
  158. "Color8",
  159. "ColorN",
  160. "abs",
  161. "acos",
  162. "asin",
  163. "assert",
  164. "atan",
  165. "atan2",
  166. "bytes2var",
  167. "ceil",
  168. "char",
  169. "clamp",
  170. "convert",
  171. "cos",
  172. "cosh",
  173. "db2linear",
  174. "decimals",
  175. "dectime",
  176. "deg2rad",
  177. "dict2inst",
  178. "ease",
  179. "exp",
  180. "floor",
  181. "fmod",
  182. "fposmod",
  183. "funcref",
  184. "hash",
  185. "inst2dict",
  186. "instance_from_id",
  187. "is_inf",
  188. "is_nan",
  189. "lerp",
  190. "linear2db",
  191. "load",
  192. "log",
  193. "max",
  194. "min",
  195. "nearest_po2",
  196. "pow",
  197. "preload",
  198. "print",
  199. "print_stack",
  200. "printerr",
  201. "printraw",
  202. "prints",
  203. "printt",
  204. "rad2deg",
  205. "rand_range",
  206. "rand_seed",
  207. "randf",
  208. "randi",
  209. "randomize",
  210. "range",
  211. "round",
  212. "seed",
  213. "sign",
  214. "sin",
  215. "sinh",
  216. "sqrt",
  217. "stepify",
  218. "str",
  219. "str2var",
  220. "tan",
  221. "tan",
  222. "tanh",
  223. "type_exist",
  224. "typeof",
  225. "var2bytes",
  226. "var2str",
  227. "weakref",
  228. "yield",
  229. ),
  230. prefix=r"(?<!\.)",
  231. suffix=r"\b",
  232. ),
  233. Name.Builtin,
  234. ),
  235. (r"((?<!\.)(self|false|true)|(PI|TAU|NAN|INF)" r")\b", Name.Builtin.Pseudo),
  236. (
  237. words(
  238. (
  239. "bool",
  240. "int",
  241. "float",
  242. "String",
  243. "NodePath",
  244. "Vector2",
  245. "Rect2",
  246. "Transform2D",
  247. "Vector3",
  248. "Rect3",
  249. "Plane",
  250. "Quat",
  251. "Basis",
  252. "Transform",
  253. "Color",
  254. "RID",
  255. "Object",
  256. "NodePath",
  257. "Dictionary",
  258. "Array",
  259. "PackedByteArray",
  260. "PackedInt32Array",
  261. "PackedInt64Array",
  262. "PackedFloat32Array",
  263. "PackedFloat64Array",
  264. "PackedStringArray",
  265. "PackedVector2Array",
  266. "PackedVector3Array",
  267. "PackedColorArray",
  268. "null",
  269. ),
  270. prefix=r"(?<!\.)",
  271. suffix=r"\b",
  272. ),
  273. Name.Builtin.Type,
  274. ),
  275. ],
  276. "numbers": [
  277. (r"(\d+\.\d*|\d*\.\d+)([eE][+-]?[0-9]+)?j?", Number.Float),
  278. (r"\d+[eE][+-]?[0-9]+j?", Number.Float),
  279. (r"0[xX][a-fA-F0-9]+", Number.Hex),
  280. (r"\d+j?", Number.Integer),
  281. ],
  282. "name": [(r"[a-zA-Z_]\w*", Name)],
  283. "funcname": [(r"[a-zA-Z_]\w*", Name.Function, "#pop"), default("#pop")],
  284. "classname": [(r"[a-zA-Z_]\w*", Name.Class, "#pop")],
  285. "stringescape": [
  286. (
  287. r'\\([\\abfnrtv"\']|\n|N\{.*?\}|u[a-fA-F0-9]{4}|'
  288. r"U[a-fA-F0-9]{8}|x[a-fA-F0-9]{2}|[0-7]{1,3})",
  289. String.Escape,
  290. )
  291. ],
  292. "strings-single": innerstring_rules(String.Single),
  293. "strings-double": innerstring_rules(String.Double),
  294. "dqs": [
  295. (r'"', String.Double, "#pop"),
  296. (r'\\\\|\\"|\\\n', String.Escape), # included here for raw strings
  297. include("strings-double"),
  298. ],
  299. "sqs": [
  300. (r"'", String.Single, "#pop"),
  301. (r"\\\\|\\'|\\\n", String.Escape), # included here for raw strings
  302. include("strings-single"),
  303. ],
  304. "tdqs": [
  305. (r'"""', String.Double, "#pop"),
  306. include("strings-double"),
  307. (r"\n", String.Double),
  308. ],
  309. "tsqs": [
  310. (r"'''", String.Single, "#pop"),
  311. include("strings-single"),
  312. (r"\n", String.Single),
  313. ],
  314. }
  315. def analyse_text(text):
  316. score = 0.0
  317. if re.search(
  318. r"func (_ready|_init|_input|_process|_unhandled_input)", text
  319. ):
  320. score += 0.8
  321. if re.search(
  322. r"(extends |class_name |onready |preload|load|setget|func [^_])",
  323. text
  324. ):
  325. score += 0.4
  326. if re.search(r"(var|const|enum|export|signal|tool)", text):
  327. score += 0.2
  328. return min(score, 1.0)