summaryrefslogtreecommitdiff
path: root/modules/gdscript/gdscript_compiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript/gdscript_compiler.cpp')
-rw-r--r--modules/gdscript/gdscript_compiler.cpp67
1 files changed, 52 insertions, 15 deletions
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index f380bedf7f..5c834966c5 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -37,6 +37,9 @@ bool GDScriptCompiler::_is_class_member_property(CodeGen &codegen, const StringN
if (!codegen.function_node || codegen.function_node->_static)
return false;
+ if (codegen.stack_identifiers.has(p_name))
+ return false; //shadowed
+
return _is_class_member_property(codegen.script, p_name);
}
@@ -178,12 +181,20 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
//wait, identifier could be a local variable or something else... careful here, must reference properly
//as stack may be more interesting to work with
- //This could be made much simpler by just indexing "self", but done this way (with custom self-addressing modes) increases peformance a lot.
+ //This could be made much simpler by just indexing "self", but done this way (with custom self-addressing modes) increases performance a lot.
const GDScriptParser::IdentifierNode *in = static_cast<const GDScriptParser::IdentifierNode *>(p_expression);
StringName identifier = in->name;
+ // TRY STACK!
+ if (!p_initializer && codegen.stack_identifiers.has(identifier)) {
+
+ int pos = codegen.stack_identifiers[identifier];
+ return pos | (GDScriptFunction::ADDR_TYPE_STACK_VARIABLE << GDScriptFunction::ADDR_BITS);
+ }
+
+ // TRY CLASS MEMBER
if (_is_class_member_property(codegen, identifier)) {
//get property
codegen.opcodes.push_back(GDScriptFunction::OPCODE_GET_MEMBER); // perform operator
@@ -194,12 +205,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
return dst_addr;
}
- // TRY STACK!
- if (!p_initializer && codegen.stack_identifiers.has(identifier)) {
-
- int pos = codegen.stack_identifiers[identifier];
- return pos | (GDScriptFunction::ADDR_TYPE_STACK_VARIABLE << GDScriptFunction::ADDR_BITS);
- }
//TRY MEMBERS!
if (!codegen.function_node || !codegen.function_node->_static) {
@@ -273,6 +278,18 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
return idx | (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS); //argument (stack root)
}
+#ifdef TOOLS_ENABLED
+ if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(identifier)) {
+
+ int idx = codegen.named_globals.find(identifier);
+ if (idx == -1) {
+ idx = codegen.named_globals.size();
+ codegen.named_globals.push_back(identifier);
+ }
+ return idx | (GDScriptFunction::ADDR_TYPE_NAMED_GLOBAL << GDScriptFunction::ADDR_BITS);
+ }
+#endif
+
//not found, error
_set_error("Identifier not found: " + String(identifier), p_expression);
@@ -721,6 +738,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
case GDScriptParser::OperatorNode::OP_NEG: {
if (!_create_unary_operator(codegen, on, Variant::OP_NEGATE, p_stack_level)) return -1;
} break;
+ case GDScriptParser::OperatorNode::OP_POS: {
+ if (!_create_unary_operator(codegen, on, Variant::OP_POSITIVE, p_stack_level)) return -1;
+ } break;
case GDScriptParser::OperatorNode::OP_NOT: {
if (!_create_unary_operator(codegen, on, Variant::OP_NOT, p_stack_level)) return -1;
} break;
@@ -1336,10 +1356,12 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
const GDScriptParser::LocalVarNode *lv = static_cast<const GDScriptParser::LocalVarNode *>(s);
- if (_is_class_member_property(codegen, lv->name)) {
- _set_error("Name for local variable '" + String(lv->name) + "' can't shadow class property of the same name.", lv);
- return ERR_ALREADY_EXISTS;
- }
+ // since we are using properties now for most class access, allow shadowing of class members to make user's life easier.
+ //
+ //if (_is_class_member_property(codegen, lv->name)) {
+ // _set_error("Name for local variable '" + String(lv->name) + "' can't shadow class property of the same name.", lv);
+ // return ERR_ALREADY_EXISTS;
+ //}
codegen.add_stack_identifier(lv->name, p_stack_level++);
codegen.alloc_stack(p_stack_level);
@@ -1376,10 +1398,13 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
if (p_func) {
for (int i = 0; i < p_func->arguments.size(); i++) {
- if (_is_class_member_property(p_script, p_func->arguments[i])) {
- _set_error("Name for argument '" + String(p_func->arguments[i]) + "' can't shadow class property of the same name.", p_func);
- return ERR_ALREADY_EXISTS;
- }
+ // since we are using properties now for most class access, allow shadowing of class members to make user's life easier.
+ //
+ //if (_is_class_member_property(p_script, p_func->arguments[i])) {
+ // _set_error("Name for argument '" + String(p_func->arguments[i]) + "' can't shadow class property of the same name.", p_func);
+ // return ERR_ALREADY_EXISTS;
+ //}
+
codegen.add_stack_identifier(p_func->arguments[i], i);
#ifdef TOOLS_ENABLED
argnames.push_back(p_func->arguments[i]);
@@ -1501,6 +1526,18 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
gdfunc->_global_names_count = 0;
}
+#ifdef TOOLS_ENABLED
+ // Named globals
+ if (codegen.named_globals.size()) {
+ gdfunc->named_globals.resize(codegen.named_globals.size());
+ gdfunc->_named_globals_ptr = gdfunc->named_globals.ptr();
+ for (int i = 0; i < codegen.named_globals.size(); i++) {
+ gdfunc->named_globals[i] = codegen.named_globals[i];
+ }
+ gdfunc->_named_globals_count = gdfunc->named_globals.size();
+ }
+#endif
+
if (codegen.opcodes.size()) {
gdfunc->code = codegen.opcodes;