Browse Source

Allow declaring multiple members in one expression in shader structs

Yuri Roubinsky 3 years ago
parent
commit
31cc6ba622
1 changed files with 53 additions and 39 deletions
  1. 53 39
      servers/rendering/shader_language.cpp

+ 53 - 39
servers/rendering/shader_language.cpp

@@ -7648,57 +7648,71 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
 							_set_error("void datatype not allowed here");
 							return ERR_PARSE_ERROR;
 						}
-						tk = _get_token();
-
-						if (tk.type != TK_IDENTIFIER && tk.type != TK_BRACKET_OPEN) {
-							_set_error("Expected identifier or '['.");
-							return ERR_PARSE_ERROR;
-						}
 
+						bool first = true;
+						bool fixed_array_size = false;
 						int array_size = 0;
 
-						if (tk.type == TK_BRACKET_OPEN) {
-							Error error = _parse_global_array_size(array_size, constants);
-							if (error != OK) {
-								return error;
-							}
+						do {
 							tk = _get_token();
-						}
 
-						if (tk.type != TK_IDENTIFIER) {
-							_set_error("Expected identifier!");
-							return ERR_PARSE_ERROR;
-						}
+							if (first) {
+								first = false;
 
-						MemberNode *member = alloc_node<MemberNode>();
-						member->precision = precision;
-						member->datatype = type;
-						member->struct_name = struct_name;
-						member->name = tk.text;
-						member->array_size = array_size;
+								if (tk.type != TK_IDENTIFIER && tk.type != TK_BRACKET_OPEN) {
+									_set_error("Expected identifier or '['.");
+									return ERR_PARSE_ERROR;
+								}
 
-						if (member_names.has(member->name)) {
-							_set_error("Redefinition of '" + String(member->name) + "'");
-							return ERR_PARSE_ERROR;
-						}
-						member_names.insert(member->name);
-						tk = _get_token();
+								if (tk.type == TK_BRACKET_OPEN) {
+									Error error = _parse_global_array_size(array_size, constants);
+									if (error != OK) {
+										return error;
+									}
+									fixed_array_size = true;
+									tk = _get_token();
+								}
+							}
 
-						if (tk.type == TK_BRACKET_OPEN) {
-							Error error = _parse_global_array_size(member->array_size, constants);
-							if (error != OK) {
-								return error;
+							if (tk.type != TK_IDENTIFIER) {
+								_set_error("Expected identifier!");
+								return ERR_PARSE_ERROR;
+							}
+
+							MemberNode *member = alloc_node<MemberNode>();
+							member->precision = precision;
+							member->datatype = type;
+							member->struct_name = struct_name;
+							member->name = tk.text;
+							member->array_size = array_size;
+
+							if (member_names.has(member->name)) {
+								_set_error("Redefinition of '" + String(member->name) + "'");
+								return ERR_PARSE_ERROR;
 							}
+							member_names.insert(member->name);
 							tk = _get_token();
-						}
 
-						if (tk.type != TK_SEMICOLON) {
-							_set_error("Expected ';'");
-							return ERR_PARSE_ERROR;
-						}
+							if (tk.type == TK_BRACKET_OPEN) {
+								Error error = _parse_global_array_size(member->array_size, constants);
+								if (error != OK) {
+									return error;
+								}
+								tk = _get_token();
+							}
+
+							if (!fixed_array_size) {
+								array_size = 0;
+							}
+
+							if (tk.type != TK_SEMICOLON && tk.type != TK_COMMA) {
+								_set_error("Expected ',' or ';' after struct member.");
+								return ERR_PARSE_ERROR;
+							}
 
-						st_node->members.push_back(member);
-						member_count++;
+							st_node->members.push_back(member);
+							member_count++;
+						} while (tk.type == TK_COMMA); // another member
 					}
 				}
 				if (member_count == 0) {