1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-07 12:30:27 +00:00

Implemented do/while loops for shaders

This commit is contained in:
Yuri Roubinski
2019-08-13 16:19:14 +03:00
parent 0a10a93fb0
commit a525e3c5ce
3 changed files with 62 additions and 14 deletions

View File

@@ -3862,14 +3862,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
return ERR_PARSE_ERROR;
}
decl.size = ((uint32_t)tk.constant);
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
_set_error("Expected ']'");
return ERR_PARSE_ERROR;
}
decl.size = ((uint32_t)tk.constant);
var.array_size = decl.size;
}
@@ -4133,16 +4132,40 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
} else {
_set_tkpos(pos); //rollback
}
} else if (tk.type == TK_CF_WHILE) {
//if () {}
} else if (tk.type == TK_CF_DO || tk.type == TK_CF_WHILE) {
// do {} while()
// while() {}
bool is_do = tk.type == TK_CF_DO;
BlockNode *do_block = NULL;
if (is_do) {
do_block = alloc_node<BlockNode>();
do_block->parent_block = p_block;
Error err = _parse_block(do_block, p_builtin_types, true, true, true);
if (err)
return err;
tk = _get_token();
if (tk.type != TK_CF_WHILE) {
_set_error("Expected while after do");
return ERR_PARSE_ERROR;
}
}
tk = _get_token();
if (tk.type != TK_PARENTHESIS_OPEN) {
_set_error("Expected '(' after while");
return ERR_PARSE_ERROR;
}
ControlFlowNode *cf = alloc_node<ControlFlowNode>();
cf->flow_op = FLOW_OP_WHILE;
if (is_do) {
cf->flow_op = FLOW_OP_DO;
} else {
cf->flow_op = FLOW_OP_WHILE;
}
Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
if (!n)
return ERR_PARSE_ERROR;
@@ -4152,18 +4175,30 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
_set_error("Expected ')' after expression");
return ERR_PARSE_ERROR;
}
if (!is_do) {
BlockNode *block = alloc_node<BlockNode>();
block->parent_block = p_block;
cf->expressions.push_back(n);
cf->blocks.push_back(block);
p_block->statements.push_back(cf);
BlockNode *block = alloc_node<BlockNode>();
block->parent_block = p_block;
cf->expressions.push_back(n);
cf->blocks.push_back(block);
p_block->statements.push_back(cf);
Error err = _parse_block(block, p_builtin_types, true, true, true);
if (err)
return err;
} else {
Error err = _parse_block(block, p_builtin_types, true, true, true);
if (err)
return err;
cf->expressions.push_back(n);
cf->blocks.push_back(do_block);
p_block->statements.push_back(cf);
tk = _get_token();
if (tk.type != TK_SEMICOLON) {
_set_error("Expected ';'");
return ERR_PARSE_ERROR;
}
}
} else if (tk.type == TK_CF_FOR) {
//if () {}
// for() {}
tk = _get_token();
if (tk.type != TK_PARENTHESIS_OPEN) {
_set_error("Expected '(' after for");