mirror of
https://github.com/godotengine/godot.git
synced 2025-10-20 00:13:30 +00:00
Wrap up GDScript 2.0 base implementation
This commit is contained in:
parent
aa09b4f85d
commit
a0f54cb95e
13 changed files with 590 additions and 333 deletions
|
@ -31,6 +31,7 @@
|
|||
#include "gdscript_compiler.h"
|
||||
|
||||
#include "gdscript.h"
|
||||
#include "gdscript_cache.h"
|
||||
|
||||
bool GDScriptCompiler::_is_class_member_property(CodeGen &codegen, const StringName &p_name) {
|
||||
if (codegen.function_node && codegen.function_node->is_static) {
|
||||
|
@ -114,7 +115,7 @@ bool GDScriptCompiler::_create_binary_operator(CodeGen &codegen, const GDScriptP
|
|||
}
|
||||
|
||||
GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::DataType &p_datatype) const {
|
||||
if (!p_datatype.is_set()) {
|
||||
if (!p_datatype.is_set() || !p_datatype.is_hard_type()) {
|
||||
return GDScriptDataType();
|
||||
}
|
||||
|
||||
|
@ -122,6 +123,9 @@ GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::D
|
|||
result.has_type = true;
|
||||
|
||||
switch (p_datatype.kind) {
|
||||
case GDScriptParser::DataType::VARIANT: {
|
||||
result.has_type = false;
|
||||
} break;
|
||||
case GDScriptParser::DataType::BUILTIN: {
|
||||
result.kind = GDScriptDataType::BUILTIN;
|
||||
result.builtin_type = p_datatype.builtin_type;
|
||||
|
@ -139,38 +143,48 @@ GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::D
|
|||
// Locate class by constructing the path to it and following that path
|
||||
GDScriptParser::ClassNode *class_type = p_datatype.class_type;
|
||||
if (class_type) {
|
||||
List<StringName> names;
|
||||
while (class_type->outer) {
|
||||
names.push_back(class_type->identifier->name);
|
||||
class_type = class_type->outer;
|
||||
}
|
||||
|
||||
Ref<GDScript> script = Ref<GDScript>(main_script);
|
||||
while (names.back()) {
|
||||
if (!script->subclasses.has(names.back()->get())) {
|
||||
ERR_PRINT("Parser bug: Cannot locate datatype class.");
|
||||
result.has_type = false;
|
||||
return GDScriptDataType();
|
||||
if (class_type->fqcn.begins_with(main_script->path) || (!main_script->name.empty() && class_type->fqcn.begins_with(main_script->name))) {
|
||||
// Local class.
|
||||
List<StringName> names;
|
||||
while (class_type->outer) {
|
||||
names.push_back(class_type->identifier->name);
|
||||
class_type = class_type->outer;
|
||||
}
|
||||
script = script->subclasses[names.back()->get()];
|
||||
names.pop_back();
|
||||
}
|
||||
result.kind = GDScriptDataType::GDSCRIPT;
|
||||
result.script_type = script;
|
||||
result.native_type = script->get_instance_base_type();
|
||||
} else {
|
||||
result.kind = GDScriptDataType::GDSCRIPT;
|
||||
result.script_type = p_datatype.script_type;
|
||||
result.native_type = result.script_type->get_instance_base_type();
|
||||
}
|
||||
|
||||
Ref<GDScript> script = Ref<GDScript>(main_script);
|
||||
while (names.back()) {
|
||||
if (!script->subclasses.has(names.back()->get())) {
|
||||
ERR_PRINT("Parser bug: Cannot locate datatype class.");
|
||||
result.has_type = false;
|
||||
return GDScriptDataType();
|
||||
}
|
||||
script = script->subclasses[names.back()->get()];
|
||||
names.pop_back();
|
||||
}
|
||||
result.kind = GDScriptDataType::GDSCRIPT;
|
||||
result.script_type = script;
|
||||
result.native_type = script->get_instance_base_type();
|
||||
} else {
|
||||
result.kind = GDScriptDataType::GDSCRIPT;
|
||||
result.script_type = GDScriptCache::get_shallow_script(p_datatype.script_path, main_script->path);
|
||||
result.native_type = p_datatype.native_type;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case GDScriptParser::DataType::ENUM_VALUE:
|
||||
result.has_type = true;
|
||||
result.kind = GDScriptDataType::BUILTIN;
|
||||
result.builtin_type = Variant::INT;
|
||||
break;
|
||||
case GDScriptParser::DataType::ENUM:
|
||||
result.has_type = true;
|
||||
result.kind = GDScriptDataType::BUILTIN;
|
||||
result.builtin_type = Variant::DICTIONARY;
|
||||
break;
|
||||
case GDScriptParser::DataType::UNRESOLVED: {
|
||||
ERR_PRINT("Parser bug: converting unresolved type.");
|
||||
return GDScriptDataType();
|
||||
}
|
||||
default:
|
||||
break; // FIXME
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -234,6 +248,66 @@ int GDScriptCompiler::_parse_assign_right_expression(CodeGen &codegen, const GDS
|
|||
return dst_addr;
|
||||
}
|
||||
|
||||
bool GDScriptCompiler::_generate_typed_assign(CodeGen &codegen, int p_src_address, int p_dst_address, const GDScriptDataType &p_datatype, const GDScriptParser::DataType &p_value_type) {
|
||||
if (p_datatype.has_type && p_value_type.is_variant()) {
|
||||
// Typed assignment
|
||||
switch (p_datatype.kind) {
|
||||
case GDScriptDataType::BUILTIN: {
|
||||
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN); // perform operator
|
||||
codegen.opcodes.push_back(p_datatype.builtin_type); // variable type
|
||||
codegen.opcodes.push_back(p_dst_address); // argument 1
|
||||
codegen.opcodes.push_back(p_src_address); // argument 2
|
||||
} break;
|
||||
case GDScriptDataType::NATIVE: {
|
||||
int class_idx;
|
||||
if (GDScriptLanguage::get_singleton()->get_global_map().has(p_datatype.native_type)) {
|
||||
class_idx = GDScriptLanguage::get_singleton()->get_global_map()[p_datatype.native_type];
|
||||
class_idx |= (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS); //argument (stack root)
|
||||
} else {
|
||||
// _set_error("Invalid native class type '" + String(p_datatype.native_type) + "'.", on->arguments[0]);
|
||||
return false;
|
||||
}
|
||||
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TYPED_NATIVE); // perform operator
|
||||
codegen.opcodes.push_back(class_idx); // variable type
|
||||
codegen.opcodes.push_back(p_dst_address); // argument 1
|
||||
codegen.opcodes.push_back(p_src_address); // argument 2
|
||||
} break;
|
||||
case GDScriptDataType::SCRIPT:
|
||||
case GDScriptDataType::GDSCRIPT: {
|
||||
Variant script = p_datatype.script_type;
|
||||
int idx = codegen.get_constant_pos(script); //make it a local constant (faster access)
|
||||
|
||||
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TYPED_SCRIPT); // perform operator
|
||||
codegen.opcodes.push_back(idx); // variable type
|
||||
codegen.opcodes.push_back(p_dst_address); // argument 1
|
||||
codegen.opcodes.push_back(p_src_address); // argument 2
|
||||
} break;
|
||||
default: {
|
||||
ERR_PRINT("Compiler bug: unresolved assign.");
|
||||
|
||||
// Shouldn't get here, but fail-safe to a regular assignment
|
||||
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN); // perform operator
|
||||
codegen.opcodes.push_back(p_dst_address); // argument 1
|
||||
codegen.opcodes.push_back(p_src_address); // argument 2 (unary only takes one parameter)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (p_datatype.kind == GDScriptDataType::BUILTIN && p_value_type.kind == GDScriptParser::DataType::BUILTIN && p_datatype.builtin_type != p_value_type.builtin_type) {
|
||||
// Need conversion.
|
||||
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN); // perform operator
|
||||
codegen.opcodes.push_back(p_datatype.builtin_type); // variable type
|
||||
codegen.opcodes.push_back(p_dst_address); // argument 1
|
||||
codegen.opcodes.push_back(p_src_address); // argument 2
|
||||
} else {
|
||||
// Either untyped assignment or already type-checked by the parser
|
||||
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN); // perform operator
|
||||
codegen.opcodes.push_back(p_dst_address); // argument 1
|
||||
codegen.opcodes.push_back(p_src_address); // argument 2 (unary only takes one parameter)
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::ExpressionNode *p_expression, int p_stack_level, bool p_root, bool p_initializer, int p_index_addr) {
|
||||
if (p_expression->is_constant) {
|
||||
return codegen.get_constant_pos(p_expression->reduced_value);
|
||||
|
@ -368,15 +442,16 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
|
|||
class_node = class_node->outer;
|
||||
}
|
||||
|
||||
if (class_node->identifier && class_node->identifier->name == identifier) {
|
||||
_set_error("Using own name in class file is not allowed (creates a cyclic reference)", p_expression);
|
||||
return -1;
|
||||
}
|
||||
RES res;
|
||||
|
||||
RES res = ResourceLoader::load(ScriptServer::get_global_class_path(identifier));
|
||||
if (res.is_null()) {
|
||||
_set_error("Can't load global class " + String(identifier) + ", cyclic reference?", p_expression);
|
||||
return -1;
|
||||
if (class_node->identifier && class_node->identifier->name == identifier) {
|
||||
res = Ref<GDScript>(main_script);
|
||||
} else {
|
||||
res = ResourceLoader::load(ScriptServer::get_global_class_path(identifier));
|
||||
if (res.is_null()) {
|
||||
_set_error("Can't load global class " + String(identifier) + ", cyclic reference?", p_expression);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Variant key = res;
|
||||
|
@ -534,8 +609,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
|
|||
codegen.alloc_stack(slevel);
|
||||
}
|
||||
|
||||
// FIXME: Allow actual cast.
|
||||
GDScriptDataType cast_type; // = _gdtype_from_datatype(cn->cast_type);
|
||||
GDScriptDataType cast_type = _gdtype_from_datatype(cn->cast_type->get_datatype());
|
||||
|
||||
switch (cast_type.kind) {
|
||||
case GDScriptDataType::BUILTIN: {
|
||||
|
@ -685,8 +759,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
|
|||
arguments.push_back(ret);
|
||||
arguments.push_back(codegen.get_name_map_pos(subscript->attribute->name));
|
||||
} else {
|
||||
// TODO: Validate this at parse time.
|
||||
// TODO: Though might not be the case if callables are a thing.
|
||||
_set_error("Cannot call something that isn't a function.", call->callee);
|
||||
return -1;
|
||||
}
|
||||
|
@ -1329,55 +1401,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
|
|||
|
||||
GDScriptDataType assign_type = _gdtype_from_datatype(assignment->assignee->get_datatype());
|
||||
|
||||
if (assign_type.has_type && !assignment->assigned_value->get_datatype().is_variant()) {
|
||||
// Typed assignment
|
||||
switch (assign_type.kind) {
|
||||
case GDScriptDataType::BUILTIN: {
|
||||
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN); // perform operator
|
||||
codegen.opcodes.push_back(assign_type.builtin_type); // variable type
|
||||
codegen.opcodes.push_back(dst_address_a); // argument 1
|
||||
codegen.opcodes.push_back(src_address_b); // argument 2
|
||||
} break;
|
||||
case GDScriptDataType::NATIVE: {
|
||||
int class_idx;
|
||||
if (GDScriptLanguage::get_singleton()->get_global_map().has(assign_type.native_type)) {
|
||||
class_idx = GDScriptLanguage::get_singleton()->get_global_map()[assign_type.native_type];
|
||||
class_idx |= (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS); //argument (stack root)
|
||||
} else {
|
||||
// _set_error("Invalid native class type '" + String(assign_type.native_type) + "'.", on->arguments[0]);
|
||||
return -1;
|
||||
}
|
||||
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TYPED_NATIVE); // perform operator
|
||||
codegen.opcodes.push_back(class_idx); // variable type
|
||||
codegen.opcodes.push_back(dst_address_a); // argument 1
|
||||
codegen.opcodes.push_back(src_address_b); // argument 2
|
||||
} break;
|
||||
case GDScriptDataType::SCRIPT:
|
||||
case GDScriptDataType::GDSCRIPT: {
|
||||
Variant script = assign_type.script_type;
|
||||
int idx = codegen.get_constant_pos(script); //make it a local constant (faster access)
|
||||
|
||||
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN_TYPED_SCRIPT); // perform operator
|
||||
codegen.opcodes.push_back(idx); // variable type
|
||||
codegen.opcodes.push_back(dst_address_a); // argument 1
|
||||
codegen.opcodes.push_back(src_address_b); // argument 2
|
||||
} break;
|
||||
default: {
|
||||
ERR_PRINT("Compiler bug: unresolved assign.");
|
||||
|
||||
// Shouldn't get here, but fail-safe to a regular assignment
|
||||
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN); // perform operator
|
||||
codegen.opcodes.push_back(dst_address_a); // argument 1
|
||||
codegen.opcodes.push_back(src_address_b); // argument 2 (unary only takes one parameter)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Either untyped assignment or already type-checked by the parser
|
||||
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN); // perform operator
|
||||
codegen.opcodes.push_back(dst_address_a); // argument 1
|
||||
codegen.opcodes.push_back(src_address_b); // argument 2 (unary only takes one parameter)
|
||||
}
|
||||
|
||||
if (has_setter && !is_in_setter) {
|
||||
// Call setter.
|
||||
codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL);
|
||||
|
@ -1387,6 +1410,8 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
|
|||
codegen.opcodes.push_back(dst_address_a); // Argument.
|
||||
codegen.opcodes.push_back(dst_address_a); // Result address (won't be used here).
|
||||
codegen.alloc_call(1);
|
||||
} else if (!_generate_typed_assign(codegen, src_address_b, dst_address_a, assign_type, assignment->assigned_value->get_datatype())) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return dst_address_a; //if anything, returns wathever was assigned or correct stack position
|
||||
|
@ -1662,7 +1687,7 @@ Error GDScriptCompiler::_parse_match_pattern(CodeGen &codegen, const GDScriptPar
|
|||
// Evaluate element by element.
|
||||
for (int i = 0; i < p_pattern->dictionary.size(); i++) {
|
||||
const GDScriptParser::PatternNode::Pair &element = p_pattern->dictionary[i];
|
||||
if (element.value_pattern->pattern_type == GDScriptParser::PatternNode::PT_REST) {
|
||||
if (element.value_pattern && element.value_pattern->pattern_type == GDScriptParser::PatternNode::PT_REST) {
|
||||
// Ignore rest pattern.
|
||||
continue;
|
||||
}
|
||||
|
@ -1698,28 +1723,30 @@ Error GDScriptCompiler::_parse_match_pattern(CodeGen &codegen, const GDScriptPar
|
|||
r_patch_addresses.push_back(codegen.opcodes.size());
|
||||
codegen.opcodes.push_back(0); // Will be replaced.
|
||||
|
||||
// Get actual value from user dictionary.
|
||||
int value_addr = stlevel++;
|
||||
codegen.alloc_stack(stlevel);
|
||||
codegen.opcodes.push_back(GDScriptFunction::OPCODE_GET);
|
||||
codegen.opcodes.push_back(p_value_addr); // Source.
|
||||
codegen.opcodes.push_back(pattern_key_addr); // Index.
|
||||
codegen.opcodes.push_back(value_addr); // Destination.
|
||||
if (element.value_pattern != nullptr) {
|
||||
// Get actual value from user dictionary.
|
||||
int value_addr = stlevel++;
|
||||
codegen.alloc_stack(stlevel);
|
||||
codegen.opcodes.push_back(GDScriptFunction::OPCODE_GET);
|
||||
codegen.opcodes.push_back(p_value_addr); // Source.
|
||||
codegen.opcodes.push_back(pattern_key_addr); // Index.
|
||||
codegen.opcodes.push_back(value_addr); // Destination.
|
||||
|
||||
// Also get type of value.
|
||||
int value_type_addr = stlevel++;
|
||||
value_type_addr |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
|
||||
codegen.alloc_stack(stlevel);
|
||||
codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_BUILT_IN);
|
||||
codegen.opcodes.push_back(GDScriptFunctions::TYPE_OF);
|
||||
codegen.opcodes.push_back(1); // One argument.
|
||||
codegen.opcodes.push_back(value_addr); // Argument is the value we want to test.
|
||||
codegen.opcodes.push_back(value_type_addr); // Address to result.
|
||||
// Also get type of value.
|
||||
int value_type_addr = stlevel++;
|
||||
value_type_addr |= GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS;
|
||||
codegen.alloc_stack(stlevel);
|
||||
codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_BUILT_IN);
|
||||
codegen.opcodes.push_back(GDScriptFunctions::TYPE_OF);
|
||||
codegen.opcodes.push_back(1); // One argument.
|
||||
codegen.opcodes.push_back(value_addr); // Argument is the value we want to test.
|
||||
codegen.opcodes.push_back(value_type_addr); // Address to result.
|
||||
|
||||
// Try the pattern inside the value.
|
||||
Error err = _parse_match_pattern(codegen, element.value_pattern, stlevel, value_addr, value_type_addr, r_bound_variables, r_patch_addresses, element_block_patches);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
// Try the pattern inside the value.
|
||||
Error err = _parse_match_pattern(codegen, element.value_pattern, stlevel, value_addr, value_type_addr, r_bound_variables, r_patch_addresses, element_block_patches);
|
||||
if (err != OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
// Patch jumps to block to try the next element.
|
||||
|
@ -2055,20 +2082,19 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui
|
|||
if (src_address < 0) {
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN);
|
||||
codegen.opcodes.push_back(dst_address);
|
||||
codegen.opcodes.push_back(src_address);
|
||||
if (!_generate_typed_assign(codegen, src_address, dst_address, _gdtype_from_datatype(lv->get_datatype()), lv->initializer->get_datatype())) {
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case GDScriptParser::Node::CONSTANT: {
|
||||
// Local constants.
|
||||
const GDScriptParser::ConstantNode *lc = static_cast<const GDScriptParser::ConstantNode *>(s);
|
||||
// FIXME: Need to properly reduce expressions to avoid limiting this so much.
|
||||
if (lc->initializer->type != GDScriptParser::Node::LITERAL) {
|
||||
_set_error("Local constant must have a literal as initializer.", lc->initializer);
|
||||
if (!lc->initializer->is_constant) {
|
||||
_set_error("Local constant must have a constant value as initializer.", lc->initializer);
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
codegen.local_named_constants[lc->identifier->name] = codegen.get_constant_pos(static_cast<const GDScriptParser::LiteralNode *>(lc->initializer)->value);
|
||||
codegen.local_named_constants[lc->identifier->name] = codegen.get_constant_pos(lc->initializer->reduced_value);
|
||||
} break;
|
||||
case GDScriptParser::Node::PASS:
|
||||
// Nothing to do.
|
||||
|
@ -2158,9 +2184,9 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
|
|||
int dst_address = codegen.script->member_indices[field->identifier->name].index;
|
||||
dst_address |= GDScriptFunction::ADDR_TYPE_MEMBER << GDScriptFunction::ADDR_BITS;
|
||||
|
||||
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN);
|
||||
codegen.opcodes.push_back(dst_address);
|
||||
codegen.opcodes.push_back(src_address);
|
||||
if (!_generate_typed_assign(codegen, src_address, dst_address, _gdtype_from_datatype(field->get_datatype()), field->initializer->get_datatype())) {
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2188,9 +2214,9 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
|
|||
int dst_address = codegen.script->member_indices[field->identifier->name].index;
|
||||
dst_address |= GDScriptFunction::ADDR_TYPE_MEMBER << GDScriptFunction::ADDR_BITS;
|
||||
|
||||
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN);
|
||||
codegen.opcodes.push_back(dst_address);
|
||||
codegen.opcodes.push_back(src_address);
|
||||
if (!_generate_typed_assign(codegen, src_address, dst_address, _gdtype_from_datatype(field->get_datatype()), field->initializer->get_datatype())) {
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2209,9 +2235,10 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
|
|||
if (src_addr < 0) {
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN);
|
||||
codegen.opcodes.push_back(codegen.stack_identifiers[p_func->parameters[i]->identifier->name] | (GDScriptFunction::ADDR_TYPE_STACK_VARIABLE << GDScriptFunction::ADDR_BITS));
|
||||
codegen.opcodes.push_back(src_addr);
|
||||
int dst_addr = codegen.stack_identifiers[p_func->parameters[i]->identifier->name] | (GDScriptFunction::ADDR_TYPE_STACK_VARIABLE << GDScriptFunction::ADDR_BITS);
|
||||
if (!_generate_typed_assign(codegen, src_addr, dst_addr, _gdtype_from_datatype(p_func->parameters[i]->get_datatype()), p_func->parameters[i]->default_value->get_datatype())) {
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
defarg_addr.push_back(codegen.opcodes.size());
|
||||
}
|
||||
defarg_addr.invert();
|
||||
|
@ -2247,12 +2274,11 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
|
|||
if (p_func) {
|
||||
gdfunc->_static = p_func->is_static;
|
||||
gdfunc->rpc_mode = p_func->rpc_mode;
|
||||
// FIXME: Add actual parameters types;
|
||||
gdfunc->argument_types.resize(p_func->parameters.size());
|
||||
for (int i = 0; i < p_func->parameters.size(); i++) {
|
||||
gdfunc->argument_types.write[i] = GDScriptDataType(); //_gdtype_from_datatype(p_func->argument_types[i]);
|
||||
gdfunc->argument_types.write[i] = _gdtype_from_datatype(p_func->parameters[i]->get_datatype());
|
||||
}
|
||||
gdfunc->return_type = GDScriptDataType(); //_gdtype_from_datatype(p_func->return_type);
|
||||
gdfunc->return_type = _gdtype_from_datatype(p_func->get_datatype());
|
||||
} else {
|
||||
gdfunc->_static = false;
|
||||
gdfunc->rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
|
||||
|
@ -2432,7 +2458,7 @@ Error GDScriptCompiler::_parse_setter_getter(GDScript *p_script, const GDScriptP
|
|||
gdfunc->_static = false;
|
||||
gdfunc->rpc_mode = p_variable->rpc_mode;
|
||||
gdfunc->argument_types.resize(p_is_setter ? 1 : 0);
|
||||
gdfunc->return_type = GDScriptDataType(); // TODO
|
||||
gdfunc->return_type = _gdtype_from_datatype(p_variable->get_datatype());
|
||||
#ifdef TOOLS_ENABLED
|
||||
gdfunc->arg_names = argnames;
|
||||
#endif
|
||||
|
@ -2581,7 +2607,6 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
|
|||
Ref<GDScript> base = base_type.script_type;
|
||||
p_script->base = base;
|
||||
p_script->_base = base.ptr();
|
||||
p_script->member_indices = base->member_indices;
|
||||
|
||||
if (p_class->base_type.kind == GDScriptParser::DataType::CLASS && p_class->base_type.class_type != nullptr) {
|
||||
if (!parsed_classes.has(p_script->_base)) {
|
||||
|
@ -2596,6 +2621,8 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
p_script->member_indices = base->member_indices;
|
||||
} break;
|
||||
default: {
|
||||
_set_error("Parser bug: invalid inheritance.", p_class);
|
||||
|
@ -2633,8 +2660,7 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
|
|||
break;
|
||||
}
|
||||
minfo.rpc_mode = variable->rpc_mode;
|
||||
// FIXME: Types.
|
||||
// minfo.data_type = _gdtype_from_datatype(p_class->variables[i].data_type);
|
||||
minfo.data_type = _gdtype_from_datatype(variable->get_datatype());
|
||||
|
||||
PropertyInfo prop_info = minfo.data_type;
|
||||
prop_info.name = name;
|
||||
|
@ -2965,7 +2991,7 @@ Error GDScriptCompiler::compile(const GDScriptParser *p_parser, GDScript *p_scri
|
|||
return err;
|
||||
}
|
||||
|
||||
return OK;
|
||||
return GDScriptCache::finish_compiling(p_script->get_path());
|
||||
}
|
||||
|
||||
String GDScriptCompiler::get_error() const {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue