gdscript.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. # -*- coding: utf-8 -*-
  2. """
  3. pygments.lexers.gdscript
  4. ~~~~~~~~~~~~~~~~~~~~~~
  5. Lexer for GDScript.
  6. :copyright: Copyright 2xxx by The Godot Engine Community
  7. :license: MIT.
  8. modified by Daniel J. Ramirez <djrmuv@gmail.com> based on the original python.py pygment
  9. """
  10. import re
  11. from pygments.lexer import (
  12. RegexLexer,
  13. include,
  14. bygroups,
  15. default,
  16. words,
  17. combined,
  18. )
  19. from pygments.token import (
  20. Text,
  21. Comment,
  22. Operator,
  23. Keyword,
  24. Name,
  25. String,
  26. Number,
  27. Punctuation,
  28. Whitespace,
  29. )
  30. __all__ = ["GDScriptLexer"]
  31. line_re = re.compile(".*?\n")
  32. class GDScriptLexer(RegexLexer):
  33. """
  34. For `GDScript source code <https://www.godotengine.org>`_.
  35. """
  36. name = "GDScript"
  37. aliases = ["gdscript", "gd"]
  38. filenames = ["*.gd"]
  39. mimetypes = ["text/x-gdscript", "application/x-gdscript"]
  40. def innerstring_rules(ttype):
  41. return [
  42. # the old style '%s' % (...) string formatting
  43. (
  44. r"%(\(\w+\))?[-#0 +]*([0-9]+|[*])?(\.([0-9]+|[*]))?"
  45. "[hlL]?[E-GXc-giorsux%]",
  46. String.Interpol,
  47. ),
  48. # backslashes, quotes and formatting signs must be parsed one at a time
  49. (r'[^\\\'"%\n]+', ttype),
  50. (r'[\'"\\]', ttype),
  51. # unhandled string formatting sign
  52. (r"%", ttype),
  53. # newlines are an error (use "nl" state)
  54. ]
  55. tokens = {
  56. "root": [
  57. (r"\n", Whitespace),
  58. (
  59. r'^(\s*)([rRuUbB]{,2})("""(?:.|\n)*?""")',
  60. bygroups(Whitespace, String.Affix, String.Doc),
  61. ),
  62. (
  63. r"^(\s*)([rRuUbB]{,2})('''(?:.|\n)*?''')",
  64. bygroups(Whitespace, String.Affix, String.Doc),
  65. ),
  66. (r"[^\S\n]+", Whitespace),
  67. (r"#.*$", Comment.Single),
  68. (r"[]{}:(),;[]", Punctuation),
  69. (r"(\\)(\n)", Whitespace),
  70. (r"\\", Text),
  71. # modules/gdscript/gdscript.cpp - GDScriptLanguage::get_reserved_words()
  72. # Operators.
  73. (r"(and|as|in|is|not|or)\b", Operator.Word),
  74. (
  75. r"!=|==|<<|>>|&&|\+=|-=|\*=|/=|%=|&=|\|=|\|\||[-~+/*%=<>&^.!|$]",
  76. Operator,
  77. ),
  78. include("keywords"),
  79. include("control_flow_keywords"),
  80. (r"(func)((?:\s|\\\s)+)", bygroups(Keyword, Whitespace), "funcname"),
  81. (r"(class)((?:\s|\\\s)+)", bygroups(Keyword, Whitespace), "classname"),
  82. include("builtins"),
  83. include("decorators"),
  84. (
  85. '([rR]|[uUbB][rR]|[rR][uUbB])(""")',
  86. bygroups(String.Affix, String.Double),
  87. "tdqs",
  88. ),
  89. (
  90. "([rR]|[uUbB][rR]|[rR][uUbB])(''')",
  91. bygroups(String.Affix, String.Single),
  92. "tsqs",
  93. ),
  94. (
  95. '([rR]|[uUbB][rR]|[rR][uUbB])(")',
  96. bygroups(String.Affix, String.Double),
  97. "dqs",
  98. ),
  99. (
  100. "([rR]|[uUbB][rR]|[rR][uUbB])(')",
  101. bygroups(String.Affix, String.Single),
  102. "sqs",
  103. ),
  104. (
  105. '([uUbB]?)(""")',
  106. bygroups(String.Affix, String.Double),
  107. combined("stringescape", "tdqs"),
  108. ),
  109. (
  110. "([uUbB]?)(''')",
  111. bygroups(String.Affix, String.Single),
  112. combined("stringescape", "tsqs"),
  113. ),
  114. (
  115. '([uUbB]?)(")',
  116. bygroups(String.Affix, String.Double),
  117. combined("stringescape", "dqs"),
  118. ),
  119. (
  120. "([uUbB]?)(')",
  121. bygroups(String.Affix, String.Single),
  122. combined("stringescape", "sqs"),
  123. ),
  124. include("name"),
  125. include("numbers"),
  126. ],
  127. "keywords": [
  128. (
  129. words(
  130. (
  131. # modules/gdscript/gdscript.cpp - GDScriptLanguage::get_reserved_words()
  132. # Declarations.
  133. "class",
  134. "class_name",
  135. "const",
  136. "enum",
  137. "extends",
  138. "func",
  139. "namespace", # Reserved for potential future use.
  140. "signal",
  141. "static",
  142. "trait", # Reserved for potential future use.
  143. "var",
  144. # Other keywords.
  145. "await",
  146. "breakpoint",
  147. "self",
  148. "super",
  149. "yield", # Reserved for potential future use.
  150. # Not really keywords, but used in property syntax.
  151. "set",
  152. "get",
  153. ),
  154. suffix=r"\b",
  155. ),
  156. Keyword,
  157. ),
  158. ],
  159. "control_flow_keywords": [
  160. (
  161. words(
  162. (
  163. # modules/gdscript/gdscript.cpp - GDScriptLanguage::get_reserved_words()
  164. # Control flow.
  165. "break",
  166. "continue",
  167. "elif",
  168. "else",
  169. "for",
  170. "if",
  171. "match",
  172. "pass",
  173. "return",
  174. "when",
  175. "while",
  176. ),
  177. suffix=r"\b",
  178. ),
  179. # Custom control flow class used to give control flow keywords a different color,
  180. # like in the Godot editor.
  181. Keyword.ControlFlow,
  182. ),
  183. ],
  184. "builtins": [
  185. (
  186. words(
  187. (
  188. # doc/classes/@GlobalScope.xml
  189. "abs",
  190. "absf",
  191. "absi",
  192. "acos",
  193. "acosh",
  194. "angle_difference",
  195. "asin",
  196. "asinh",
  197. "atan",
  198. "atan2",
  199. "atanh",
  200. "bezier_derivative",
  201. "bezier_interpolate",
  202. "bytes_to_var",
  203. "bytes_to_var_with_objects",
  204. "ceil",
  205. "ceilf",
  206. "ceili",
  207. "clamp",
  208. "clampf",
  209. "clampi",
  210. "cos",
  211. "cosh",
  212. "cubic_interpolate",
  213. "cubic_interpolate_angle",
  214. "cubic_interpolate_angle_in_time",
  215. "cubic_interpolate_in_time",
  216. "db_to_linear",
  217. "deg_to_rad",
  218. "ease",
  219. "error_string",
  220. "exp",
  221. "floor",
  222. "floorf",
  223. "floori",
  224. "fmod",
  225. "fposmod",
  226. "hash",
  227. "instance_from_id",
  228. "inverse_lerp",
  229. "is_equal_approx",
  230. "is_finite",
  231. "is_inf",
  232. "is_instance_id_valid",
  233. "is_instance_valid",
  234. "is_nan",
  235. "is_same",
  236. "is_zero_approx",
  237. "lerp",
  238. "lerp_angle",
  239. "lerpf",
  240. "linear_to_db",
  241. "log",
  242. "max",
  243. "maxf",
  244. "maxi",
  245. "min",
  246. "minf",
  247. "mini",
  248. "move_toward",
  249. "nearest_po2",
  250. "pingpong",
  251. "posmod",
  252. "pow",
  253. "print",
  254. "print_rich",
  255. "print_verbose",
  256. "printerr",
  257. "printraw",
  258. "prints",
  259. "printt",
  260. "push_error",
  261. "push_warning",
  262. "rad_to_deg",
  263. "rand_from_seed",
  264. "randf",
  265. "randf_range",
  266. "randfn",
  267. "randi",
  268. "randi_range",
  269. "randomize",
  270. "remap",
  271. "rid_allocate_id",
  272. "rid_from_int64",
  273. "rotate_toward",
  274. "round",
  275. "roundf",
  276. "roundi",
  277. "seed",
  278. "sign",
  279. "signf",
  280. "signi",
  281. "sin",
  282. "sinh",
  283. "smoothstep",
  284. "snapped",
  285. "snappedf",
  286. "snappedi",
  287. "sqrt",
  288. "step_decimals",
  289. "str",
  290. "str_to_var",
  291. "tan",
  292. "tanh",
  293. "type_convert",
  294. "type_string",
  295. "typeof",
  296. "var_to_bytes",
  297. "var_to_bytes_with_objects",
  298. "var_to_str",
  299. "weakref",
  300. "wrap",
  301. "wrapf",
  302. "wrapi",
  303. # modules/gdscript/doc_classes/@GDScript.xml
  304. "Color8",
  305. "assert",
  306. "char",
  307. "convert",
  308. "dict_to_inst",
  309. "get_stack",
  310. "inst_to_dict",
  311. "is_instance_of",
  312. "len",
  313. "load",
  314. "preload",
  315. "print_debug",
  316. "print_stack",
  317. "range",
  318. "type_exists",
  319. ),
  320. prefix=r"(?<!\.)",
  321. suffix=r"\b",
  322. ),
  323. Name.Builtin,
  324. ),
  325. # modules/gdscript/gdscript.cpp - GDScriptLanguage::get_reserved_words()
  326. # Special values. Constants.
  327. (r"((?<!\.)(false|null|true)|(INF|NAN|PI|TAU))\b", Name.Builtin.Pseudo),
  328. (
  329. words(
  330. (
  331. # core/variant/variant.cpp - Variant::get_type_name()
  332. # `Nil` is excluded because it is not allowed in GDScript.
  333. "bool",
  334. "int",
  335. "float",
  336. "String",
  337. "Vector2",
  338. "Vector2i",
  339. "Rect2",
  340. "Rect2i",
  341. "Transform2D",
  342. "Vector3",
  343. "Vector3i",
  344. "Vector4",
  345. "Vector4i",
  346. "Plane",
  347. "AABB",
  348. "Quaternion",
  349. "Basis",
  350. "Transform3D",
  351. "Projection",
  352. "Color",
  353. "RID",
  354. "Object",
  355. "Callable",
  356. "Signal",
  357. "StringName",
  358. "NodePath",
  359. "Dictionary",
  360. "Array",
  361. "PackedByteArray",
  362. "PackedInt32Array",
  363. "PackedInt64Array",
  364. "PackedFloat32Array",
  365. "PackedFloat64Array",
  366. "PackedStringArray",
  367. "PackedVector2Array",
  368. "PackedVector3Array",
  369. "PackedColorArray",
  370. "PackedVector4Array",
  371. # The following are also considered types in GDScript.
  372. "Variant",
  373. "void",
  374. ),
  375. prefix=r"(?<!\.)",
  376. suffix=r"\b",
  377. ),
  378. Name.Builtin.Type,
  379. ),
  380. ],
  381. "decorators": [
  382. (
  383. words(
  384. (
  385. # modules/gdscript/doc_classes/@GDScript.xml
  386. "@export",
  387. "@export_category",
  388. "@export_color_no_alpha",
  389. "@export_custom",
  390. "@export_dir",
  391. "@export_enum",
  392. "@export_exp_easing",
  393. "@export_file",
  394. "@export_flags",
  395. "@export_flags_2d_navigation",
  396. "@export_flags_2d_physics",
  397. "@export_flags_2d_render",
  398. "@export_flags_3d_navigation",
  399. "@export_flags_3d_physics",
  400. "@export_flags_3d_render",
  401. "@export_flags_avoidance",
  402. "@export_global_dir",
  403. "@export_global_file",
  404. "@export_group",
  405. "@export_multiline",
  406. "@export_node_path",
  407. "@export_placeholder",
  408. "@export_range",
  409. "@export_storage",
  410. "@export_subgroup",
  411. "@export_tool_button",
  412. "@icon",
  413. "@onready",
  414. "@rpc",
  415. "@static_unload",
  416. "@tool",
  417. "@warning_ignore",
  418. ),
  419. prefix=r"(?<!\.)",
  420. suffix=r"\b",
  421. ),
  422. Name.Decorator,
  423. ),
  424. ],
  425. "numbers": [
  426. (
  427. r"(-)?((\d|(?<=\d)_)+\.(\d|(?<=\d)_)*|(\d|(?<=\d)_)*\.(\d|(?<=\d)_)+)([eE][+-]?(\d|(?<=\d)_)+)?j?",
  428. Number.Float,
  429. ),
  430. (r"(-)?(\d|(?<=\d)_)+[eE][+-]?(\d|(?<=\d)_)+j?", Number.Float),
  431. (r"(-)?0[xX]([a-fA-F0-9]|(?<=[a-fA-F0-9])_)+", Number.Hex),
  432. (r"(-)?0[bB]([01]|(?<=[01])_)+", Number.Bin),
  433. (r"(-)?(\d|(?<=\d)_)+j?", Number.Integer),
  434. ],
  435. "name": [(r"@?[a-zA-Z_]\w*", Name)],
  436. "funcname": [(r"[a-zA-Z_]\w*", Name.Function, "#pop"), default("#pop")],
  437. "classname": [(r"[a-zA-Z_]\w*", Name.Class, "#pop")],
  438. "stringescape": [
  439. (
  440. r'\\([\\abfnrtv"\']|\n|N\{.*?\}|u[a-fA-F0-9]{4}|'
  441. r"U[a-fA-F0-9]{8}|x[a-fA-F0-9]{2}|[0-7]{1,3})",
  442. String.Escape,
  443. )
  444. ],
  445. "strings-single": innerstring_rules(String.Single),
  446. "strings-double": innerstring_rules(String.Double),
  447. "dqs": [
  448. (r'"', String.Double, "#pop"),
  449. (r'\\\\|\\"|\\\n', String.Escape), # included here for raw strings
  450. include("strings-double"),
  451. ],
  452. "sqs": [
  453. (r"'", String.Single, "#pop"),
  454. (r"\\\\|\\'|\\\n", String.Escape), # included here for raw strings
  455. include("strings-single"),
  456. ],
  457. "tdqs": [
  458. (r'"""', String.Double, "#pop"),
  459. include("strings-double"),
  460. (r"\n", Whitespace),
  461. ],
  462. "tsqs": [
  463. (r"'''", String.Single, "#pop"),
  464. include("strings-single"),
  465. (r"\n", Whitespace),
  466. ],
  467. }
  468. def setup(sphinx):
  469. sphinx.add_lexer("gdscript", GDScriptLexer)
  470. return {
  471. "parallel_read_safe": True,
  472. "parallel_write_safe": True,
  473. }