Merge pull request from Chaosus/shader_fix_arrays

This commit is contained in:
Yuri Roubinsky 2021-12-15 19:28:09 +03:00 committed by GitHub
commit 1cbf3947d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 70 additions and 60 deletions

View file

@ -4399,13 +4399,14 @@ Error ShaderLanguage::_parse_global_array_size(int &r_array_size, const Function
return OK; return OK;
} }
Error ShaderLanguage::_parse_local_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, ArrayDeclarationNode *p_node, ArrayDeclarationNode::Declaration *p_decl, int &r_array_size, bool &r_is_unknown_size) { Error ShaderLanguage::_parse_local_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, Node *&r_size_expression, int &r_array_size, bool &r_is_unknown_size) {
TkPos pos = _get_tkpos(); TkPos pos = _get_tkpos();
Token tk = _get_token(); Token tk = _get_token();
if (tk.type == TK_BRACKET_CLOSE) { if (tk.type == TK_BRACKET_CLOSE) {
r_is_unknown_size = true; r_is_unknown_size = true;
} else { } else {
int size = 0;
if (!tk.is_integer_constant() || ((int)tk.constant) <= 0) { if (!tk.is_integer_constant() || ((int)tk.constant) <= 0) {
_set_tkpos(pos); _set_tkpos(pos);
int array_size = 0; int array_size = 0;
@ -4413,13 +4414,13 @@ Error ShaderLanguage::_parse_local_array_size(BlockNode *p_block, const Function
if (!n) { if (!n) {
return ERR_PARSE_ERROR; return ERR_PARSE_ERROR;
} }
p_decl->size = array_size; size = array_size;
p_node->size_expression = n; r_size_expression = n;
} else if (((int)tk.constant) > 0) { } else if (((int)tk.constant) > 0) {
p_decl->size = (uint32_t)tk.constant; size = (uint32_t)tk.constant;
} }
if (p_decl->size <= 0) { if (size <= 0) {
_set_error("Expected single integer constant > 0"); _set_error("Expected single integer constant > 0");
return ERR_PARSE_ERROR; return ERR_PARSE_ERROR;
} }
@ -4430,7 +4431,7 @@ Error ShaderLanguage::_parse_local_array_size(BlockNode *p_block, const Function
return ERR_PARSE_ERROR; return ERR_PARSE_ERROR;
} }
r_array_size = p_decl->size; r_array_size = size;
} }
return OK; return OK;
@ -6464,49 +6465,44 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
return ERR_PARSE_ERROR; return ERR_PARSE_ERROR;
} }
tk = _get_token();
Node *vardecl = nullptr; Node *vardecl = nullptr;
int array_size = 0;
bool fixed_array_size = false;
bool first = true;
while (true) { do {
bool unknown_size = false; bool unknown_size = false;
int array_size = 0; Node *size_expr = nullptr;
ArrayDeclarationNode *anode = nullptr; ArrayDeclarationNode *anode = nullptr;
ArrayDeclarationNode::Declaration adecl; ArrayDeclarationNode::Declaration adecl;
if (tk.type != TK_IDENTIFIER && tk.type != TK_BRACKET_OPEN) { tk = _get_token();
_set_error("Expected identifier or '[' after datatype.");
return ERR_PARSE_ERROR;
}
if (tk.type == TK_BRACKET_OPEN) { if (first) {
anode = alloc_node<ArrayDeclarationNode>(); first = false;
if (is_struct) { if (tk.type != TK_IDENTIFIER && tk.type != TK_BRACKET_OPEN) {
anode->struct_name = struct_name; _set_error("Expected identifier or '[' after datatype.");
anode->datatype = TYPE_STRUCT;
} else {
anode->datatype = type;
}
anode->precision = precision;
anode->is_const = is_const;
vardecl = (Node *)anode;
adecl.size = 0U;
adecl.single_expression = false;
Error error = _parse_local_array_size(p_block, p_function_info, anode, &adecl, array_size, unknown_size);
if (error != OK) {
return error;
}
tk = _get_token();
if (tk.type != TK_IDENTIFIER) {
_set_error("Expected identifier!");
return ERR_PARSE_ERROR; return ERR_PARSE_ERROR;
} }
if (tk.type == TK_BRACKET_OPEN) {
Error error = _parse_local_array_size(p_block, p_function_info, size_expr, array_size, unknown_size);
if (error != OK) {
return error;
}
adecl.single_expression = false;
adecl.size = array_size;
fixed_array_size = true;
tk = _get_token();
}
}
if (tk.type != TK_IDENTIFIER) {
_set_error("Expected identifier!");
return ERR_PARSE_ERROR;
} }
StringName name = tk.text; StringName name = tk.text;
@ -6544,8 +6540,10 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
tk = _get_token(); tk = _get_token();
bool is_array_decl = var.array_size > 0 || unknown_size;
if (tk.type == TK_BRACKET_OPEN) { if (tk.type == TK_BRACKET_OPEN) {
if (var.array_size > 0 || unknown_size) { if (is_array_decl) {
_set_error("Array size is already defined!"); _set_error("Array size is already defined!");
return ERR_PARSE_ERROR; return ERR_PARSE_ERROR;
} }
@ -6555,28 +6553,37 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
return ERR_PARSE_ERROR; return ERR_PARSE_ERROR;
} }
anode = alloc_node<ArrayDeclarationNode>(); Error error = _parse_local_array_size(p_block, p_function_info, size_expr, var.array_size, unknown_size);
if (is_struct) {
anode->struct_name = struct_name;
anode->datatype = TYPE_STRUCT;
} else {
anode->datatype = type;
}
anode->precision = precision;
anode->is_const = is_const;
vardecl = (Node *)anode;
adecl.size = 0U;
adecl.single_expression = false;
Error error = _parse_local_array_size(p_block, p_function_info, anode, &adecl, var.array_size, unknown_size);
if (error != OK) { if (error != OK) {
return error; return error;
} }
adecl.single_expression = false;
adecl.size = var.array_size;
array_size = var.array_size;
is_array_decl = true;
tk = _get_token(); tk = _get_token();
} }
if (var.array_size > 0 || unknown_size) { if (is_array_decl) {
{
anode = alloc_node<ArrayDeclarationNode>();
if (is_struct) {
anode->struct_name = struct_name;
anode->datatype = TYPE_STRUCT;
} else {
anode->datatype = type;
}
anode->precision = precision;
anode->is_const = is_const;
anode->size_expression = size_expr;
vardecl = (Node *)anode;
}
bool full_def = false; bool full_def = false;
if (tk.type == TK_OP_ASSIGN) { if (tk.type == TK_OP_ASSIGN) {
@ -6794,6 +6801,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
} }
} }
array_size = var.array_size;
anode->declarations.push_back(adecl); anode->declarations.push_back(adecl);
} else if (tk.type == TK_OP_ASSIGN) { } else if (tk.type == TK_OP_ASSIGN) {
VariableDeclarationNode *node = alloc_node<VariableDeclarationNode>(); VariableDeclarationNode *node = alloc_node<VariableDeclarationNode>();
@ -6862,22 +6870,24 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
} }
p_block->statements.push_back(vardecl); p_block->statements.push_back(vardecl);
p_block->variables[name] = var; p_block->variables[name] = var;
if (!fixed_array_size) {
array_size = 0;
}
if (tk.type == TK_COMMA) { if (tk.type == TK_COMMA) {
if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR) { if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR) {
_set_error("Multiple declarations in 'for' loop are not implemented yet."); _set_error("Multiple declarations in 'for' loop are not implemented yet.");
return ERR_PARSE_ERROR; return ERR_PARSE_ERROR;
} }
tk = _get_token();
//another variable
} else if (tk.type == TK_SEMICOLON) { } else if (tk.type == TK_SEMICOLON) {
break; break;
} else { } else {
_set_error("Expected ',' or ';' after variable"); _set_error("Expected ',' or ';' after variable");
return ERR_PARSE_ERROR; return ERR_PARSE_ERROR;
} }
} } while (tk.type == TK_COMMA); //another variable
} else if (tk.type == TK_CURLY_BRACKET_OPEN) { } else if (tk.type == TK_CURLY_BRACKET_OPEN) {
//a sub block, just because.. //a sub block, just because..
BlockNode *block = alloc_node<BlockNode>(); BlockNode *block = alloc_node<BlockNode>();

View file

@ -1001,7 +1001,7 @@ private:
Node *_parse_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, int &r_array_size); Node *_parse_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, int &r_array_size);
Error _parse_global_array_size(int &r_array_size, const FunctionInfo &p_function_info); Error _parse_global_array_size(int &r_array_size, const FunctionInfo &p_function_info);
Error _parse_local_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, ArrayDeclarationNode *p_node, ArrayDeclarationNode::Declaration *p_decl, int &r_array_size, bool &r_is_unknown_size); Error _parse_local_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, Node *&r_size_expression, int &r_array_size, bool &r_is_unknown_size);
Node *_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info); Node *_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info);
Node *_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info); Node *_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info);