You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

348 lines
11 KiB
Python

"""
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)