/* gdscript_compiler.cpp */ #include "gdscript_compiler.h" #include "gdscript.h" bool GDScriptCompiler::_is_class_member_property(CodeGen &codegen, const StringName &p_name) { 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); } bool GDScriptCompiler::_is_class_member_property(GDScript *owner, const StringName &p_name) { GDScript *scr = owner; GDScriptNativeClass *nc = nullptr; while (scr) { if (scr->native.is_valid()) { nc = scr->native.ptr(); } scr = scr->_base; } ERR_FAIL_COND_V(!nc, false); return ClassDB::has_property(nc->get_name(), p_name); } void GDScriptCompiler::_set_error(const String &p_error, const GDScriptParser::Node *p_node) { if (error != "") { return; } error = p_error; if (p_node) { err_line = p_node->line; err_column = p_node->column; } else { err_line = 0; err_column = 0; } } bool GDScriptCompiler::_create_unary_operator(CodeGen &codegen, const GDScriptParser::OperatorNode *on, Variant::Operator op, int p_stack_level) { ERR_FAIL_COND_V(on->arguments.size() != 1, false); int src_address_a = _parse_expression(codegen, on->arguments[0], p_stack_level); if (src_address_a < 0) { return false; } codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR); // perform operator codegen.opcodes.push_back(op); //which operator codegen.opcodes.push_back(src_address_a); // argument 1 codegen.opcodes.push_back(src_address_a); // argument 2 (repeated) //codegen.opcodes.push_back(GDScriptFunction::ADDR_TYPE_NIL); // argument 2 (unary only takes one parameter) return true; } bool GDScriptCompiler::_create_binary_operator(CodeGen &codegen, const GDScriptParser::OperatorNode *on, Variant::Operator op, int p_stack_level, bool p_initializer, int p_index_addr) { ERR_FAIL_COND_V(on->arguments.size() != 2, false); int src_address_a = _parse_expression(codegen, on->arguments[0], p_stack_level, false, p_initializer, p_index_addr); if (src_address_a < 0) { return false; } if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) { p_stack_level++; //uses stack for return, increase stack } int src_address_b = _parse_expression(codegen, on->arguments[1], p_stack_level, false, p_initializer); if (src_address_b < 0) { return false; } codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR); // perform operator codegen.opcodes.push_back(op); //which operator codegen.opcodes.push_back(src_address_a); // argument 1 codegen.opcodes.push_back(src_address_b); // argument 2 (unary only takes one parameter) return true; } GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::DataType &p_datatype, GDScript *p_owner) const { if (!p_datatype.has_type) { return GDScriptDataType(); } GDScriptDataType result; result.has_type = true; switch (p_datatype.kind) { case GDScriptParser::DataType::BUILTIN: { result.kind = GDScriptDataType::BUILTIN; result.builtin_type = p_datatype.builtin_type; } break; case GDScriptParser::DataType::NATIVE: { result.kind = GDScriptDataType::NATIVE; result.native_type = p_datatype.native_type; } break; case GDScriptParser::DataType::SCRIPT: { result.kind = GDScriptDataType::SCRIPT; result.script_type_ref = Ref