summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuri Roubinski <chaosus89@gmail.com>2019-08-13 16:19:14 +0300
committerYuri Roubinski <chaosus89@gmail.com>2019-08-13 18:39:55 +0300
commita525e3c5ceb5e463575cb06f4a33b9585086ce38 (patch)
treee032e09b667c2783acade95ff26ac7273db3bc8c
parent0a10a93fb0d2467fd836ad38501550ca79f0fa72 (diff)
Implemented do/while loops for shaders
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp8
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp5
-rw-r--r--servers/visual/shader_language.cpp63
3 files changed, 62 insertions, 14 deletions
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index 935cb32fda..9c9a8e9717 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -802,6 +802,14 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += "else\n";
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) {
code += _mktab(p_level);
code += "while (";
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index d48ee7709c..6b477ec78b 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -799,6 +799,11 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
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);
}
+ } 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) {
code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")\n";
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index c0b503c323..1dd6699851 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -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");