|
|
|
"""
|
|
|
|
pygments.lexers.gdscript
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Lexer for GDScript.
|
|
|
|
|
|
|
|
Modified by Daniel J. Ramirez <djrmuv@gmail.com> based on the original
|
|
|
|
python.py.
|
|
|
|
|
|
|
|
:copyright: Copyright 2006-2022 by the Pygments team, see AUTHORS.
|
|
|
|
:license: BSD, see LICENSE for details.
|
|
|
|
"""
|
|
|
|
|
|
|
|
import re
|
|
|
|
|
|
|
|
from pygments.lexer import RegexLexer, include, bygroups, default, words, \
|
|
|
|
combined
|
|
|
|
from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
|
|
|
|
Number, Punctuation, Whitespace
|
|
|
|
|
|
|
|
__all__ = ["GDScriptLexer"]
|
|
|
|
|
|
|
|
line_re = re.compile(".*?\n")
|
|
|
|
|
|
|
|
|
|
|
|
class GDScriptLexer(RegexLexer):
|
|
|
|
"""
|
|
|
|
For GDScript source code.
|
|
|
|
"""
|
|
|
|
|
|
|
|
name = "GDScript"
|
|
|
|
url = 'https://www.godotengine.org'
|
|
|
|
aliases = ["gdscript", "gd"]
|
|
|
|
filenames = ["*.gd"]
|
|
|
|
mimetypes = ["text/x-gdscript", "application/x-gdscript"]
|
|
|
|
|
|
|
|
def innerstring_rules(ttype):
|
|
|
|
return [
|
|
|
|
# the old style '%s' % (...) string formatting
|
|
|
|
(
|
|
|
|
r"%(\(\w+\))?[-#0 +]*([0-9]+|[*])?(\.([0-9]+|[*]))?"
|
|
|
|
"[hlL]?[E-GXc-giorsux%]",
|
|
|
|
String.Interpol,
|
|
|
|
),
|
|
|
|
# backslashes, quotes and formatting signs must be parsed one at a time
|
|
|
|
(r'[^\\\'"%\n]+', ttype),
|
|
|
|
(r'[\'"\\]', ttype),
|
|
|
|
# unhandled string formatting sign
|
|
|
|
(r"%", ttype),
|
|
|
|
# newlines are an error (use "nl" state)
|
|
|
|
]
|
|
|
|
|
|
|
|
tokens = {
|
|
|
|
"root": [
|
|
|
|
(r"\n", Whitespace),
|
|
|
|
(
|
|
|
|
r'^(\s*)([rRuUbB]{,2})("""(?:.|\n)*?""")',
|
|
|
|
bygroups(Whitespace, String.Affix, String.Doc),
|
|
|
|
),
|
|
|
|
(
|
|
|
|
r"^(\s*)([rRuUbB]{,2})('''(?:.|\n)*?''')",
|
|
|
|
bygroups(Whitespace, String.Affix, String.Doc),
|
|
|
|
),
|
|
|
|
(r"[^\S\n]+", Whitespace),
|
|
|
|
(r"#.*$", Comment.Single),
|
|
|
|
(r"[]{}:(),;[]", Punctuation),
|
|
|
|
(r"(\\)(\n)", bygroups(Text, Whitespace)),
|
|
|
|
(r"\\", Text),
|
|
|
|
(r"(in|and|or|not)\b", Operator.Word),
|
|
|
|
(
|
|
|
|
r"!=|==|<<|>>|&&|\+=|-=|\*=|/=|%=|&=|\|=|\|\||[-~+/*%=<>&^.!|$]",
|
|
|
|
Operator,
|
|
|
|
),
|
|
|
|
include("keywords"),
|
|
|
|
(r"(func)(\s+)", bygroups(Keyword, Whitespace), "funcname"),
|
|
|
|
(r"(class)(\s+)", bygroups(Keyword, Whitespace), "classname"),
|
|
|
|
include("builtins"),
|
|
|
|
(
|
|
|
|
'([rR]|[uUbB][rR]|[rR][uUbB])(""")',
|
|
|
|
bygroups(String.Affix, String.Double),
|
|
|
|
"tdqs",
|
|
|
|
),
|
|
|
|
(
|
|
|
|
"([rR]|[uUbB][rR]|[rR][uUbB])(''')",
|
|
|
|
bygroups(String.Affix, String.Single),
|
|
|
|
"tsqs",
|
|
|
|
),
|
|
|
|
(
|
|
|
|
'([rR]|[uUbB][rR]|[rR][uUbB])(")',
|
|
|
|
bygroups(String.Affix, String.Double),
|
|
|
|
"dqs",
|
|
|
|
),
|
|
|
|
(
|
|
|
|
"([rR]|[uUbB][rR]|[rR][uUbB])(')",
|
|
|
|
bygroups(String.Affix, String.Single),
|
|
|
|
"sqs",
|
|
|
|
),
|
|
|
|
(
|
|
|
|
'([uUbB]?)(""")',
|
|
|
|
bygroups(String.Affix, String.Double),
|
|
|
|
combined("stringescape", "tdqs"),
|
|
|
|
),
|
|
|
|
(
|
|
|
|
"([uUbB]?)(''')",
|
|
|
|
bygroups(String.Affix, String.Single),
|
|
|
|
combined("stringescape", "tsqs"),
|
|
|
|
),
|
|
|
|
(
|
|
|
|
'([uUbB]?)(")',
|
|
|
|
bygroups(String.Affix, String.Double),
|
|
|
|
combined("stringescape", "dqs"),
|
|
|
|
),
|
|
|
|
(
|
|
|
|
"([uUbB]?)(')",
|
|
|
|
bygroups(String.Affix, String.Single),
|
|
|
|
combined("stringescape", "sqs"),
|
|
|
|
),
|
|
|
|
include("name"),
|
|
|
|
include("numbers"),
|
|
|
|
],
|
|
|
|
"keywords": [
|
|
|
|
(
|
|
|
|
words(
|
|
|
|
(
|
|
|
|
"and",
|
|
|
|
"in",
|
|
|
|
"not",
|
|
|
|
"or",
|
|
|
|
"as",
|
|
|
|
"breakpoint",
|
|
|
|
"class",
|
|
|
|
"class_name",
|
|
|
|
"extends",
|
|
|
|
"is",
|
|
|
|
"func",
|
|
|
|
"setget",
|
|
|
|
"signal",
|
|
|
|
"tool",
|
|
|
|
"const",
|
|
|
|
"enum",
|
|
|
|
"export",
|
|
|
|
"onready",
|
|
|
|
"static",
|
|
|
|
"var",
|
|
|
|
"break",
|
|
|
|
"continue",
|
|
|
|
"if",
|
|
|
|
"elif",
|
|
|
|
"else",
|
|
|
|
"for",
|
|
|
|
"pass",
|
|
|
|
"return",
|
|
|
|
"match",
|
|
|
|
"while",
|
|
|
|
"remote",
|
|
|
|
"master",
|
|
|
|
"puppet",
|
|
|
|
"remotesync",
|
|
|
|
"mastersync",
|
|
|
|
"puppetsync",
|
|
|
|
),
|
|
|
|
suffix=r"\b",
|
|
|
|
),
|
|
|
|
Keyword,
|
|
|
|
),
|
|
|
|
],
|
|
|
|
"builtins": [
|
|
|
|
(
|
|
|
|
words(
|
|
|
|
(
|
|
|
|
"Color8",
|
|
|
|
"ColorN",
|
|
|
|
"abs",
|
|
|
|
"acos",
|
|
|
|
"asin",
|
|
|
|
"assert",
|
|
|
|
"atan",
|
|
|
|
"atan2",
|
|
|
|
"bytes2var",
|
|
|
|
"ceil",
|
|
|
|
"char",
|
|
|
|
"clamp",
|
|
|
|
"convert",
|
|
|
|
"cos",
|
|
|
|
"cosh",
|
|
|
|
"db2linear",
|
|
|
|
"decimals",
|
|
|
|
"dectime",
|
|
|
|
"deg2rad",
|
|
|
|
"dict2inst",
|
|
|
|
"ease",
|
|
|
|
"exp",
|
|
|
|
"floor",
|
|
|
|
"fmod",
|
|
|
|
"fposmod",
|
|
|
|
"funcref",
|
|
|
|
"hash",
|
|
|
|
"inst2dict",
|
|
|
|
"instance_from_id",
|
|
|
|
"is_inf",
|
|
|
|
"is_nan",
|
|
|
|
"lerp",
|
|
|
|
"linear2db",
|
|
|
|
"load",
|
|
|
|
"log",
|
|
|
|
"max",
|
|
|
|
"min",
|
|
|
|
"nearest_po2",
|
|
|
|
"pow",
|
|
|
|
"preload",
|
|
|
|
"print",
|
|
|
|
"print_stack",
|
|
|
|
"printerr",
|
|
|
|
"printraw",
|
|
|
|
"prints",
|
|
|
|
"printt",
|
|
|
|
"rad2deg",
|
|
|
|
"rand_range",
|
|
|
|
"rand_seed",
|
|
|
|
"randf",
|
|
|
|
"randi",
|
|
|
|
"randomize",
|
|
|
|
"range",
|
|
|
|
"round",
|
|
|
|
"seed",
|
|
|
|
"sign",
|
|
|
|
"sin",
|
|
|
|
"sinh",
|
|
|
|
"sqrt",
|
|
|
|
"stepify",
|
|
|
|
"str",
|
|
|
|
"str2var",
|
|
|
|
"tan",
|
|
|
|
"tan",
|
|
|
|
"tanh",
|
|
|
|
"type_exist",
|
|
|
|
"typeof",
|
|
|
|
"var2bytes",
|
|
|
|
"var2str",
|
|
|
|
"weakref",
|
|
|
|
"yield",
|
|
|
|
),
|
|
|
|
prefix=r"(?<!\.)",
|
|
|
|
suffix=r"\b",
|
|
|
|
),
|
|
|
|
Name.Builtin,
|
|
|
|
),
|
|
|
|
(r"((?<!\.)(self|false|true)|(PI|TAU|NAN|INF)" r")\b", Name.Builtin.Pseudo),
|
|
|
|
(
|
|
|
|
words(
|
|
|
|
(
|
|
|
|
"bool",
|
|
|
|
"int",
|
|
|
|
"float",
|
|
|
|
"String",
|
|
|
|
"NodePath",
|
|
|
|
"Vector2",
|
|
|
|
"Rect2",
|
|
|
|
"Transform2D",
|
|
|
|
"Vector3",
|
|
|
|
"Rect3",
|
|
|
|
"Plane",
|
|
|
|
"Quat",
|
|
|
|
"Basis",
|
|
|
|
"Transform",
|
|
|
|
"Color",
|
|
|
|
"RID",
|
|
|
|
"Object",
|
|
|
|
"NodePath",
|
|
|
|
"Dictionary",
|
|
|
|
"Array",
|
|
|
|
"PackedByteArray",
|
|
|
|
"PackedInt32Array",
|
|
|
|
"PackedInt64Array",
|
|
|
|
"PackedFloat32Array",
|
|
|
|
"PackedFloat64Array",
|
|
|
|
"PackedStringArray",
|
|
|
|
"PackedVector2Array",
|
|
|
|
"PackedVector3Array",
|
|
|
|
"PackedColorArray",
|
|
|
|
"null",
|
|
|
|
"void",
|
|
|
|
),
|
|
|
|
prefix=r"(?<!\.)",
|
|
|
|
suffix=r"\b",
|
|
|
|
),
|
|
|
|
Name.Builtin.Type,
|
|
|
|
),
|
|
|
|
],
|
|
|
|
"numbers": [
|
|
|
|
(r"(\d+\.\d*|\d*\.\d+)([eE][+-]?[0-9]+)?j?", Number.Float),
|
|
|
|
(r"\d+[eE][+-]?[0-9]+j?", Number.Float),
|
|
|
|
(r"0[xX][a-fA-F0-9]+", Number.Hex),
|
|
|
|
(r"\d+j?", Number.Integer),
|
|
|
|
],
|
|
|
|
"name": [(r"[a-zA-Z_]\w*", Name)],
|
|
|
|
"funcname": [(r"[a-zA-Z_]\w*", Name.Function, "#pop"), default("#pop")],
|
|
|
|
"classname": [(r"[a-zA-Z_]\w*", Name.Class, "#pop")],
|
|
|
|
"stringescape": [
|
|
|
|
(
|
|
|
|
r'\\([\\abfnrtv"\']|\n|N\{.*?\}|u[a-fA-F0-9]{4}|'
|
|
|
|
r"U[a-fA-F0-9]{8}|x[a-fA-F0-9]{2}|[0-7]{1,3})",
|
|
|
|
String.Escape,
|
|
|
|
)
|
|
|
|
],
|
|
|
|
"strings-single": innerstring_rules(String.Single),
|
|
|
|
"strings-double": innerstring_rules(String.Double),
|
|
|
|
"dqs": [
|
|
|
|
(r'"', String.Double, "#pop"),
|
|
|
|
(r'\\\\|\\"|\\\n', String.Escape), # included here for raw strings
|
|
|
|
include("strings-double"),
|
|
|
|
],
|
|
|
|
"sqs": [
|
|
|
|
(r"'", String.Single, "#pop"),
|
|
|
|
(r"\\\\|\\'|\\\n", String.Escape), # included here for raw strings
|
|
|
|
include("strings-single"),
|
|
|
|
],
|
|
|
|
"tdqs": [
|
|
|
|
(r'"""', String.Double, "#pop"),
|
|
|
|
include("strings-double"),
|
|
|
|
(r"\n", Whitespace),
|
|
|
|
],
|
|
|
|
"tsqs": [
|
|
|
|
(r"'''", String.Single, "#pop"),
|
|
|
|
include("strings-single"),
|
|
|
|
(r"\n", Whitespace),
|
|
|
|
],
|
|
|
|
}
|
|
|
|
|
|
|
|
def analyse_text(text):
|
|
|
|
score = 0.0
|
|
|
|
|
|
|
|
if re.search(
|
|
|
|
r"func (_ready|_init|_input|_process|_unhandled_input)", text
|
|
|
|
):
|
|
|
|
score += 0.8
|
|
|
|
|
|
|
|
if re.search(
|
|
|
|
r"(extends |class_name |onready |preload|load|setget|func [^_])",
|
|
|
|
text
|
|
|
|
):
|
|
|
|
score += 0.4
|
|
|
|
|
|
|
|
if re.search(r"(var|const|enum|export|signal|tool)", text):
|
|
|
|
score += 0.2
|
|
|
|
|
|
|
|
return min(score, 1.0)
|