From e539a4e7a921e5df864454b1490e5e898aa88469 Mon Sep 17 00:00:00 2001 From: Daelon Suzuka Date: Wed, 20 Jul 2022 18:09:16 -0400 Subject: [PATCH] Replace temporary `.gdshader` syntax with more extensive support (#360) --- syntaxes/GDShader.tmLanguage.json | 218 ++++++++++++++++++++++++++++- syntaxes/examples/example.gdshader | 118 ++++++++++++++++ 2 files changed, 330 insertions(+), 6 deletions(-) create mode 100644 syntaxes/examples/example.gdshader diff --git a/syntaxes/GDShader.tmLanguage.json b/syntaxes/GDShader.tmLanguage.json index e779c66..66b81cf 100644 --- a/syntaxes/GDShader.tmLanguage.json +++ b/syntaxes/GDShader.tmLanguage.json @@ -1,19 +1,225 @@ { - "version": "v0.1.0", + "name": "GDShader", "scopeName": "source.gdshader", "uuid": "3a95d25d-688b-481f-a581-eee47f00e5ca", + "fileTypes": [ + "gdshader" + ], "patterns": [ { - "include": "#shader_type" + "include": "#comment" }, { - "include": "source.glsl" + "include": "#element" + }, + { + "include": "#separator" + }, + { + "include": "#operator" } ], "repository": { - "shader_type": { - "match": "(shader_type)", - "name": "storage.type.glsl" + "comment": { + "patterns": [ + { + "include": "#BLOCK_COMMENT" + }, + { + "include": "#LINE_COMMENT" + } + ] + }, + "BLOCK_COMMENT": { + "name": "comment.block.gdshader", + "begin": "/\\*", + "end": "\\*/" + }, + "LINE_COMMENT": { + "name": "comment.line.double-slash.gdshader", + "begin": "//", + "end": "$" + }, + "specialDirective": { + "name": "meta.preprocessor.gdshader", + "begin": "\\b(shader_type|render_mode)\\b", + "beginCaptures": { + "1": { + "name": "keyword.other.gdshader" + } + }, + "patterns": [ + { + "include": "#comment" + }, + { + "name": "entity.other.inherited-class.gdshader", + "match": "\\b[a-z_]+\\b" + }, + { + "name": "punctuation.separator.comma.gdshader", + "match": "," + } + ], + "end": "(?=;)" + }, + "modifierKeyword": { + "name": "storage.modifier.gdshader", + "match": "\\b(?:const|global|instance|uniform|varying|(?:low|medium|high)p|in|out|inout|flat|smooth)\\b" + }, + "controlKeyword": { + "name": "keyword.control.gdshader", + "match": "\\b(?:if|else|do|while|for|continue|break|switch|case|default|return|discard)\\b" + }, + "typeKeyword": { + "name": "support.type.gdshader", + "match": "\\b(?:void|bool|[biu]?vec[234]|u?int|float|mat[234]|[iu]?sampler(?:3D|2D(?:Array)?)|samplerCube)\\b" + }, + "hintKeyword": { + "name": "storage.type.gdshader", + "match": "\\b(?:source_color|hint_(?:color|range|(?:black_)?albedo|normal|(?:default_)?(?:white|black)|aniso))\\b" + }, + "languageConstant_Bool": { + "name": "constant.language.bool.boolean.gdshader", + "match": "\\b(?:false|true)\\b" + }, + "varGlobal": { + "name": "variable.language.gdshader", + "match": "\\b(?:[A-Z][A-Z_0-9]*)\\b" + }, + "L_Int": { + "name": "constant.numeric.int.integer.gdshader", + "match": "\\b(?:0x[0-9A-Fa-f]+|[0-9]+)\\b" + }, + "L_Float": { + "name": "constant.numeric.float.gdshader", + "match": "\\b[0-9]+\\.[0-9]*(?:f|e[-+]?[0-9]+)?|\\.[0-9]+(?:f|e[-+]?[0-9]+)?|\\b[0-9]+(?:f|e[-+]?[0-9]*)" + }, + "languageFunction": { + "name": "support.function.gdshader", + "match": "\\b(?:vertex|fragment|light)(?=(?:\\s|/\\*(?:\\*(?!/)|[^*])*\\*/)*[(])" + }, + "ID_function": { + "name": "entity.name.function.gdshader", + "match": "\\b[a-zA-Z_]\\w*(?=(?:\\s|/\\*(?:\\*(?!/)|[^*])*\\*/)*[(])" + }, + "ID_var": { + "name": "variable.name.gdshader", + "match": "\\b[a-zA-Z_]\\w*\\b" + }, + "ID_property": { + "begin": "\\.", + "beginCaptures": { + "0": { + "name": "punctuation.accessor.gdshader" + } + }, + "patterns": [ + { + "include": "#comment" + } + ], + "end": "\\b([a-zA-Z_]\\w*)\\b|[^/ \t\r\n]", + "endCaptures": { + "1": { + "name": "entity.other.attribute-name.gdshader" + } + } + }, + "enclosed": { + "name": "meta.expression.enclosed.gdshader", + "begin": "\\(", + "end": "\\)", + "captures": { + "0": { + "name": "delimiter.expression.enclosed.gdshader" + } + }, + "patterns": [ + { + "include": "#comment" + }, + { + "include": "#separator" + }, + { + "include": "#element" + } + ] + }, + "element": { + "name": "meta.expression.gdshader", + "patterns": [ + { + "include": "#comment" + }, + { + "include": "#enclosed" + }, + { + "include": "#specialDirective" + }, + { + "include": "#modifierKeyword" + }, + { + "include": "#controlKeyword" + }, + { + "include": "#typeKeyword" + }, + { + "include": "#hintKeyword" + }, + { + "include": "#languageConstant_Bool" + }, + { + "include": "#varGlobal" + }, + { + "include": "#L_Float" + }, + { + "include": "#L_Int" + }, + { + "include": "#languageFunction" + }, + { + "include": "#ID_function" + }, + { + "include": "#ID_var" + }, + { + "include": "#ID_property" + } + ] + }, + "operator": { + "name": "keyword.operator.gdshader", + "match": "\\<\\<\\=?|\\>\\>\\=?|[-+*/&|<>=!]\\=|\\&\\&|[|][|]|[-+~!*/%<>&^|=]" + }, + "separator": { + "patterns": [ + { + "match": "[.]", + "name": "punctuation.accessor.gdshader" + }, + { + "match": "[,]", + "name": "punctuation.separator.comma.gdshader" + }, + { + "match": "[;]", + "name": "punctuation.terminator.statement.gdshader" + }, + { + "match": "[:]", + "name": "keyword.operator.type.annotation.gdshader" + } + ] } } } diff --git a/syntaxes/examples/example.gdshader b/syntaxes/examples/example.gdshader new file mode 100644 index 0000000..12c1769 --- /dev/null +++ b/syntaxes/examples/example.gdshader @@ -0,0 +1,118 @@ +shader_type canvas_item; +shader_type spatial; + +/* ************************************************************************** */ + +// types +void a; +bool b = true; +bool b2 = false; +bvec2 c; +bvec3 d; +bvec4 e; +int f; +ivec2 g; +ivec3 h; +ivec4 i; +uint j; +uvec2 k; +uvec3 l; +uvec4 m; +float n; +vec2 o; +vec3 p; +vec4 q; +mat2 r; +mat3 s; +mat4 t; +sampler2D u; +isampler2D v; +usampler2D w; +samplerCube x; + +// qualifiers +uniform int qualifier_a; +global uniform int qualifier_b; +instance uniform int qualifier_c; +varying flat int qualifier_d; + +// hints +uniform sampler2D hint_a : hint_albedo; // godot 3 +uniform sampler2D hint_b : source_color; // godot 4 + +uniform sampler2D hint_c : hint_black; // godot 3 +uniform sampler2D hint_d : hint_white; // godot 3 +uniform sampler2D hint_e : hint_default_black; // godot 4 +uniform sampler2D hint_f : hint_default_white; // godot 4 + +uniform sampler2D hint_g : hint_aniso; + +uniform vec4 hint_h : hint_color; +uniform float hint_i : hint_range(0, 1); +uniform vec4 hint_o : hint_color = vec4(1.0); + +/* ************************************************************************** */ + +// the remaining examples are copied directly from +// https://docs.godotengine.org/en/3.0/tutorials/shading/shading_language.html + +float a = 2; // valid +float a = 2.0; // valid +float a = float(2); // valid + +// The required amount of scalars +vec4 a = vec4(0.0, 1.0, 2.0, 3.0); +// Complementary vectors and/or scalars +vec4 a = vec4(vec2(0.0, 1.0), vec2(2.0, 3.0)); +vec4 a = vec4(vec3(0.0, 1.0, 2.0), 3.0); +// A single scalar for the whole vector +vec4 a = vec4(0.0); + +// if and else +if (cond) { + +} else { + +} + +// for loops +for (int i = 0; i < 10; i++) { + +} + +// while +while (true) { + +} + + +int sum2(int a, int b) { + return a + b; +} + +void sum3(int a, int b, inout int result) { + result = a + b; +} + +/* ************************************************************************** */ + +struct Test { + vec3 color; +}; + +struct MyStruct { + float power; + vec3 color; + Test result; +}; + +Test foo(MyStruct a, MyStruct b) { + MyStruct k; + k.result.color = (a.color + b.color) * k.power; + return k.result; +} + +void fragment() { + MyStruct inst = MyStruct(0.0, vec3(0.0), Test(vec3(1.0))); + Test result = foo(inst, MyStruct(1.0, vec3(0, 1, 0), Test(vec3(0.0)))); +}