Implemented do/while loops for shaders (#31349)
Implemented do/while loops for shaders
This commit is contained in:
commit
8f45d48156
@ -802,6 +802,14 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||||||
code += "else\n";
|
code += "else\n";
|
||||||
code += _dump_node_code(cf_node->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
|
code += _dump_node_code(cf_node->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||||
}
|
}
|
||||||
|
} else if (cf_node->flow_op == SL::FLOW_OP_DO) {
|
||||||
|
code += _mktab(p_level);
|
||||||
|
code += "do";
|
||||||
|
code += _dump_node_code(cf_node->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||||
|
code += _mktab(p_level);
|
||||||
|
code += "while (";
|
||||||
|
code += _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||||
|
code += ");";
|
||||||
} else if (cf_node->flow_op == SL::FLOW_OP_WHILE) {
|
} else if (cf_node->flow_op == SL::FLOW_OP_WHILE) {
|
||||||
code += _mktab(p_level);
|
code += _mktab(p_level);
|
||||||
code += "while (";
|
code += "while (";
|
||||||
|
@ -799,6 +799,11 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
|||||||
code += _mktab(p_level) + "else\n";
|
code += _mktab(p_level) + "else\n";
|
||||||
code += _dump_node_code(cfnode->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
|
code += _dump_node_code(cfnode->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||||
}
|
}
|
||||||
|
} else if (cfnode->flow_op == SL::FLOW_OP_DO) {
|
||||||
|
code += _mktab(p_level) + "do";
|
||||||
|
code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
|
||||||
|
code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ");";
|
||||||
|
|
||||||
} else if (cfnode->flow_op == SL::FLOW_OP_WHILE) {
|
} else if (cfnode->flow_op == SL::FLOW_OP_WHILE) {
|
||||||
|
|
||||||
code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")\n";
|
code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")\n";
|
||||||
|
@ -3862,14 +3862,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
|
|||||||
return ERR_PARSE_ERROR;
|
return ERR_PARSE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
decl.size = ((uint32_t)tk.constant);
|
||||||
tk = _get_token();
|
tk = _get_token();
|
||||||
|
|
||||||
if (tk.type != TK_BRACKET_CLOSE) {
|
if (tk.type != TK_BRACKET_CLOSE) {
|
||||||
_set_error("Expected ']'");
|
_set_error("Expected ']'");
|
||||||
return ERR_PARSE_ERROR;
|
return ERR_PARSE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
decl.size = ((uint32_t)tk.constant);
|
|
||||||
var.array_size = decl.size;
|
var.array_size = decl.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4133,16 +4132,40 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
|
|||||||
} else {
|
} else {
|
||||||
_set_tkpos(pos); //rollback
|
_set_tkpos(pos); //rollback
|
||||||
}
|
}
|
||||||
} else if (tk.type == TK_CF_WHILE) {
|
} else if (tk.type == TK_CF_DO || tk.type == TK_CF_WHILE) {
|
||||||
//if () {}
|
// 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();
|
tk = _get_token();
|
||||||
|
|
||||||
if (tk.type != TK_PARENTHESIS_OPEN) {
|
if (tk.type != TK_PARENTHESIS_OPEN) {
|
||||||
_set_error("Expected '(' after while");
|
_set_error("Expected '(' after while");
|
||||||
return ERR_PARSE_ERROR;
|
return ERR_PARSE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlFlowNode *cf = alloc_node<ControlFlowNode>();
|
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);
|
Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
|
||||||
if (!n)
|
if (!n)
|
||||||
return ERR_PARSE_ERROR;
|
return ERR_PARSE_ERROR;
|
||||||
@ -4152,18 +4175,30 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
|
|||||||
_set_error("Expected ')' after expression");
|
_set_error("Expected ')' after expression");
|
||||||
return ERR_PARSE_ERROR;
|
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>();
|
Error err = _parse_block(block, p_builtin_types, true, true, true);
|
||||||
block->parent_block = p_block;
|
if (err)
|
||||||
cf->expressions.push_back(n);
|
return err;
|
||||||
cf->blocks.push_back(block);
|
} else {
|
||||||
p_block->statements.push_back(cf);
|
|
||||||
|
|
||||||
Error err = _parse_block(block, p_builtin_types, true, true, true);
|
cf->expressions.push_back(n);
|
||||||
if (err)
|
cf->blocks.push_back(do_block);
|
||||||
return err;
|
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) {
|
} else if (tk.type == TK_CF_FOR) {
|
||||||
//if () {}
|
// for() {}
|
||||||
tk = _get_token();
|
tk = _get_token();
|
||||||
if (tk.type != TK_PARENTHESIS_OPEN) {
|
if (tk.type != TK_PARENTHESIS_OPEN) {
|
||||||
_set_error("Expected '(' after for");
|
_set_error("Expected '(' after for");
|
||||||
|
Loading…
Reference in New Issue
Block a user