diff options
Diffstat (limited to 'modules/gdscript/gdscript_compiler.cpp')
-rw-r--r-- | modules/gdscript/gdscript_compiler.cpp | 141 |
1 files changed, 108 insertions, 33 deletions
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 69fe6d27cc..f2d3b1fb18 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -437,7 +437,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code gen->pop_temporary(); } - return source; + return result; } break; case GDScriptParser::Node::CALL: { const GDScriptParser::CallNode *call = static_cast<const GDScriptParser::CallNode *>(p_expression); @@ -677,7 +677,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code return GDScriptCodeGenerator::Address(); } - gen->write_operator(result, unary->variant_op, operand, GDScriptCodeGenerator::Address()); + gen->write_unary_operator(result, unary->variant_op, operand); if (operand.mode == GDScriptCodeGenerator::Address::TEMPORARY) { gen->pop_temporary(); @@ -745,7 +745,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code GDScriptCodeGenerator::Address left_operand = _parse_expression(codegen, r_error, binary->left_operand); GDScriptCodeGenerator::Address right_operand = _parse_expression(codegen, r_error, binary->right_operand); - gen->write_operator(result, binary->variant_op, left_operand, right_operand); + gen->write_binary_operator(result, binary->variant_op, left_operand, right_operand); if (right_operand.mode == GDScriptCodeGenerator::Address::TEMPORARY) { gen->pop_temporary(); @@ -908,7 +908,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code } else { gen->write_get(value, key, prev_base); } - gen->write_operator(value, assignment->variant_op, value, assigned); + gen->write_binary_operator(value, assignment->variant_op, value, assigned); if (assigned.mode == GDScriptCodeGenerator::Address::TEMPORARY) { gen->pop_temporary(); } @@ -966,7 +966,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code if (assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) { GDScriptCodeGenerator::Address member = codegen.add_temporary(); gen->write_get_member(member, name); - gen->write_operator(assigned, assignment->variant_op, member, assigned); + gen->write_binary_operator(assigned, assignment->variant_op, member, assigned); gen->pop_temporary(); } @@ -1016,7 +1016,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code if (assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) { // Perform operation. op_result = codegen.add_temporary(); - gen->write_operator(op_result, assignment->variant_op, target, assigned); + gen->write_binary_operator(op_result, assignment->variant_op, target, assigned); } else { op_result = assigned; assigned = GDScriptCodeGenerator::Address(); @@ -1072,7 +1072,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_match_pattern(CodeGen &c // Check type equality. GDScriptCodeGenerator::Address type_equality_addr = codegen.add_temporary(equality_type); - codegen.generator->write_operator(type_equality_addr, Variant::OP_EQUAL, p_type_addr, literal_type_addr); + codegen.generator->write_binary_operator(type_equality_addr, Variant::OP_EQUAL, p_type_addr, literal_type_addr); codegen.generator->write_and_left_operand(type_equality_addr); // Get literal. @@ -1083,7 +1083,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_match_pattern(CodeGen &c // Check value equality. GDScriptCodeGenerator::Address equality_addr = codegen.add_temporary(equality_type); - codegen.generator->write_operator(equality_addr, Variant::OP_EQUAL, p_value_addr, literal_addr); + codegen.generator->write_binary_operator(equality_addr, Variant::OP_EQUAL, p_value_addr, literal_addr); codegen.generator->write_and_right_operand(equality_addr); // AND both together (reuse temporary location). @@ -1135,11 +1135,11 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_match_pattern(CodeGen &c codegen.generator->write_call_builtin(result_addr, GDScriptFunctions::TYPE_OF, typeof_args); // Check type equality. - codegen.generator->write_operator(result_addr, Variant::OP_EQUAL, p_type_addr, result_addr); + codegen.generator->write_binary_operator(result_addr, Variant::OP_EQUAL, p_type_addr, result_addr); codegen.generator->write_and_left_operand(result_addr); // Check value equality. - codegen.generator->write_operator(result_addr, Variant::OP_EQUAL, p_value_addr, expr_addr); + codegen.generator->write_binary_operator(result_addr, Variant::OP_EQUAL, p_value_addr, expr_addr); codegen.generator->write_and_right_operand(equality_test_addr); // AND both type and value equality. @@ -1185,7 +1185,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_match_pattern(CodeGen &c // Check type equality. GDScriptCodeGenerator::Address result_addr = codegen.add_temporary(temp_type); - codegen.generator->write_operator(result_addr, Variant::OP_EQUAL, p_type_addr, array_type_addr); + codegen.generator->write_binary_operator(result_addr, Variant::OP_EQUAL, p_type_addr, array_type_addr); codegen.generator->write_and_left_operand(result_addr); // Store pattern length in constant map. @@ -1201,7 +1201,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_match_pattern(CodeGen &c // Test length compatibility. temp_type.builtin_type = Variant::BOOL; GDScriptCodeGenerator::Address length_compat_addr = codegen.add_temporary(temp_type); - codegen.generator->write_operator(length_compat_addr, p_pattern->rest_used ? Variant::OP_GREATER_EQUAL : Variant::OP_EQUAL, value_length_addr, array_length_addr); + codegen.generator->write_binary_operator(length_compat_addr, p_pattern->rest_used ? Variant::OP_GREATER_EQUAL : Variant::OP_EQUAL, value_length_addr, array_length_addr); codegen.generator->write_and_right_operand(length_compat_addr); // AND type and length check. @@ -1284,7 +1284,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_match_pattern(CodeGen &c // Check type equality. GDScriptCodeGenerator::Address result_addr = codegen.add_temporary(temp_type); - codegen.generator->write_operator(result_addr, Variant::OP_EQUAL, p_type_addr, dict_type_addr); + codegen.generator->write_binary_operator(result_addr, Variant::OP_EQUAL, p_type_addr, dict_type_addr); codegen.generator->write_and_left_operand(result_addr); // Store pattern length in constant map. @@ -1300,7 +1300,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_match_pattern(CodeGen &c // Test length compatibility. temp_type.builtin_type = Variant::BOOL; GDScriptCodeGenerator::Address length_compat_addr = codegen.add_temporary(temp_type); - codegen.generator->write_operator(length_compat_addr, p_pattern->rest_used ? Variant::OP_GREATER_EQUAL : Variant::OP_EQUAL, value_length_addr, dict_length_addr); + codegen.generator->write_binary_operator(length_compat_addr, p_pattern->rest_used ? Variant::OP_GREATER_EQUAL : Variant::OP_EQUAL, value_length_addr, dict_length_addr); codegen.generator->write_and_right_operand(length_compat_addr); // AND type and length check. @@ -1474,13 +1474,27 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui codegen.start_block(); // Evaluate the match expression. + GDScriptCodeGenerator::Address value_local = codegen.add_local("@match_value", _gdtype_from_datatype(match->test->get_datatype())); GDScriptCodeGenerator::Address value = _parse_expression(codegen, error, match->test); if (error) { return error; } + // Assign to local. + // TODO: This can be improved by passing the target to parse_expression(). + gen->write_assign(value_local, value); + + if (value.mode == GDScriptCodeGenerator::Address::TEMPORARY) { + codegen.generator->pop_temporary(); + } + // Then, let's save the type of the value in the stack too, so we can reuse for later comparisons. - GDScriptCodeGenerator::Address type = codegen.add_temporary(); + GDScriptDataType typeof_type; + typeof_type.has_type = true; + typeof_type.kind = GDScriptDataType::BUILTIN; + typeof_type.builtin_type = Variant::INT; + GDScriptCodeGenerator::Address type = codegen.add_local("@match_type", typeof_type); + Vector<GDScriptCodeGenerator::Address> typeof_args; typeof_args.push_back(value); gen->write_call_builtin(type, GDScriptFunctions::TYPE_OF, typeof_args); @@ -1534,12 +1548,6 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui gen->write_endif(); } - gen->pop_temporary(); - - if (value.mode == GDScriptCodeGenerator::Address::TEMPORARY) { - codegen.generator->pop_temporary(); - } - gen->end_match(); } break; case GDScriptParser::Node::IF: { @@ -1577,12 +1585,20 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui codegen.start_block(); GDScriptCodeGenerator::Address iterator = codegen.add_local(for_n->variable->name, _gdtype_from_datatype(for_n->variable->get_datatype())); + gen->start_for(iterator.type, _gdtype_from_datatype(for_n->list->get_datatype())); + GDScriptCodeGenerator::Address list = _parse_expression(codegen, error, for_n->list); if (error) { return error; } - gen->write_for(iterator, list); + gen->write_for_assignment(iterator, list); + + if (list.mode == GDScriptCodeGenerator::Address::TEMPORARY) { + codegen.generator->pop_temporary(); + } + + gen->write_for(); error = _parse_block(codegen, for_n->loop); if (error) { @@ -1591,10 +1607,6 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui gen->write_endfor(); - if (list.mode == GDScriptCodeGenerator::Address::TEMPORARY) { - codegen.generator->pop_temporary(); - } - codegen.end_block(); } break; case GDScriptParser::Node::WHILE: { @@ -1826,7 +1838,7 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser return error; } GDScriptCodeGenerator::Address dst_addr = codegen.parameters[parameter->identifier->name]; - codegen.generator->write_assign(dst_addr, src_addr); + codegen.generator->write_assign_default_parameter(dst_addr, src_addr); if (src_addr.mode == GDScriptCodeGenerator::Address::TEMPORARY) { codegen.generator->pop_temporary(); } @@ -1871,6 +1883,7 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser codegen.generator->set_initial_line(p_func->start_line); #ifdef TOOLS_ENABLED p_script->member_lines[func_name] = p_func->start_line; + p_script->doc_functions[func_name] = p_func->doc_description; #endif } else { codegen.generator->set_initial_line(0); @@ -1884,6 +1897,21 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser p_script->implicit_initializer = gd_function; } + if (p_func) { + // if no return statement -> return type is void not unresolved Variant + if (p_func->body->has_return) { + gd_function->return_type = _gdtype_from_datatype(p_func->get_datatype()); + } else { + gd_function->return_type = GDScriptDataType(); + gd_function->return_type.has_type = true; + gd_function->return_type.kind = GDScriptDataType::BUILTIN; + gd_function->return_type.builtin_type = Variant::NIL; + } +#ifdef TOOLS_ENABLED + gd_function->default_arg_values = p_func->default_arg_values; +#endif + } + p_script->member_functions[func_name] = gd_function; memdelete(codegen.generator); @@ -1981,6 +2009,24 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar } } +#ifdef TOOLS_ENABLED + p_script->doc_functions.clear(); + p_script->doc_variables.clear(); + p_script->doc_constants.clear(); + p_script->doc_enums.clear(); + p_script->doc_signals.clear(); + p_script->doc_tutorials.clear(); + + p_script->doc_brief_description = p_class->doc_brief_description; + p_script->doc_description = p_class->doc_description; + for (int i = 0; i < p_class->doc_tutorials.size(); i++) { + DocData::TutorialDoc td; + td.title = p_class->doc_tutorials[i].first; + td.link = p_class->doc_tutorials[i].second; + p_script->doc_tutorials.append(td); + } +#endif + p_script->native = Ref<GDScriptNativeClass>(); p_script->base = Ref<GDScript>(); p_script->_base = nullptr; @@ -2093,20 +2139,23 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar prop_info.hint = export_info.hint; prop_info.hint_string = export_info.hint_string; prop_info.usage = export_info.usage; -#ifdef TOOLS_ENABLED - if (variable->initializer != nullptr && variable->initializer->type == GDScriptParser::Node::LITERAL) { - p_script->member_default_values[name] = static_cast<const GDScriptParser::LiteralNode *>(variable->initializer)->value; - } -#endif } else { prop_info.usage = PROPERTY_USAGE_SCRIPT_VARIABLE; } +#ifdef TOOLS_ENABLED + p_script->doc_variables[name] = variable->doc_description; +#endif p_script->member_info[name] = prop_info; p_script->member_indices[name] = minfo; p_script->members.insert(name); #ifdef TOOLS_ENABLED + if (variable->initializer != nullptr && variable->initializer->is_constant) { + p_script->member_default_values[name] = variable->initializer->reduced_value; + } else { + p_script->member_default_values.erase(name); + } p_script->member_lines[name] = variable->start_line; #endif } break; @@ -2117,8 +2166,10 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar p_script->constants.insert(name, constant->initializer->reduced_value); #ifdef TOOLS_ENABLED - p_script->member_lines[name] = constant->start_line; + if (constant->doc_description != String()) { + p_script->doc_constants[name] = constant->doc_description; + } #endif } break; @@ -2129,6 +2180,15 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar p_script->constants.insert(name, enum_value.value); #ifdef TOOLS_ENABLED p_script->member_lines[name] = enum_value.identifier->start_line; + if (!p_script->doc_enums.has("@unnamed_enums")) { + p_script->doc_enums["@unnamed_enums"] = DocData::EnumDoc(); + p_script->doc_enums["@unnamed_enums"].name = "@unnamed_enums"; + } + DocData::ConstantDoc const_doc; + const_doc.name = enum_value.identifier->name; + const_doc.value = Variant(enum_value.value).operator String(); // TODO-DOC: enum value currently is int. + const_doc.description = enum_value.doc_description; + p_script->doc_enums["@unnamed_enums"].values.push_back(const_doc); #endif } break; @@ -2164,6 +2224,11 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar parameters_names.write[j] = signal->parameters[j]->identifier->name; } p_script->_signals[name] = parameters_names; +#ifdef TOOLS_ENABLED + if (!signal->doc_description.empty()) { + p_script->doc_signals[name] = signal->doc_description; + } +#endif } break; case GDScriptParser::ClassNode::Member::ENUM: { @@ -2180,6 +2245,16 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar p_script->constants.insert(enum_n->identifier->name, new_enum); #ifdef TOOLS_ENABLED p_script->member_lines[enum_n->identifier->name] = enum_n->start_line; + p_script->doc_enums[enum_n->identifier->name] = DocData::EnumDoc(); + p_script->doc_enums[enum_n->identifier->name].name = enum_n->identifier->name; + p_script->doc_enums[enum_n->identifier->name].description = enum_n->doc_description; + for (int j = 0; j < enum_n->values.size(); j++) { + DocData::ConstantDoc const_doc; + const_doc.name = enum_n->values[j].identifier->name; + const_doc.value = Variant(enum_n->values[j].value).operator String(); + const_doc.description = enum_n->values[j].doc_description; + p_script->doc_enums[enum_n->identifier->name].values.push_back(const_doc); + } #endif } break; default: |