diff options
Diffstat (limited to 'modules/gdscript')
| -rw-r--r-- | modules/gdscript/doc_classes/@GDScript.xml | 88 | ||||
| -rw-r--r-- | modules/gdscript/doc_classes/GDScriptFunctionState.xml | 5 | ||||
| -rw-r--r-- | modules/gdscript/gdscript.cpp | 33 | ||||
| -rw-r--r-- | modules/gdscript/gdscript.h | 5 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_analyzer.cpp | 84 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_analyzer.h | 2 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_compiler.cpp | 2 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_functions.cpp | 2 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_parser.cpp | 4 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_parser.h | 1 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_tokenizer.cpp | 2 | ||||
| -rw-r--r-- | modules/gdscript/register_types.cpp | 4 |
12 files changed, 129 insertions, 103 deletions
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index 36de66ea52..9e40a69712 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -112,7 +112,7 @@ </argument> <description> Returns the arc tangent of [code]s[/code] in radians. Use it to get the angle from an angle's tangent in trigonometry: [code]atan(tan(angle)) == angle[/code]. - The method cannot know in which quadrant the angle should fall. See [method atan2] if you have both [code]y[code] and [code]x[/code]. + The method cannot know in which quadrant the angle should fall. See [method atan2] if you have both [code]y[/code] and [code]x[/code]. [codeblock] a = atan(0.5) # a is 0.463648 [/codeblock] @@ -318,7 +318,7 @@ </argument> <description> The natural exponential function. It raises the mathematical constant [b]e[/b] to the power of [code]s[/code] and returns it. - [b]e[/b] has an approximate value of 2.71828. + [b]e[/b] has an approximate value of 2.71828, and can be obtained with [code]exp(1)[/code]. For exponents to other bases use the method [method pow]. [codeblock] a = exp(2) # Approximately 7.39 @@ -505,6 +505,8 @@ </argument> <description> Returns [code]true[/code] if [code]a[/code] and [code]b[/code] are approximately equal to each other. + Here, approximately equal means that [code]a[/code] and [code]b[/code] are within a small internal epsilon of each other, which scales with the magnitude of the numbers. + Infinity values of the same sign are considered equal. </description> </method> <method name="is_inf"> @@ -641,6 +643,7 @@ [codeblock] log(10) # Returns 2.302585 [/codeblock] + [b]Note:[/b] The logarithm of [code]0[/code] returns [code]-inf[/code], while negative values return [code]-nan[/code]. </description> </method> <method name="max"> @@ -686,7 +689,9 @@ Moves [code]from[/code] toward [code]to[/code] by the [code]delta[/code] value. Use a negative [code]delta[/code] value to move away. [codeblock] + move_toward(5, 10, 4) # Returns 9 move_toward(10, 5, 4) # Returns 6 + move_toward(10, 5, -1.5) # Returns 11.5 [/codeblock] </description> </method> @@ -696,12 +701,17 @@ <argument index="0" name="value" type="int"> </argument> <description> - Returns the nearest larger power of 2 for integer [code]value[/code]. + Returns the nearest equal or larger power of 2 for integer [code]value[/code]. + In other words, returns the smallest value [code]a[/code] where [code]a = pow(2, n)[/code] such that [code]value <= a[/code] for some non-negative integer [code]n[/code]. [codeblock] nearest_po2(3) # Returns 4 nearest_po2(4) # Returns 4 nearest_po2(5) # Returns 8 + + nearest_po2(0) # Returns 0 (this may not be what you expect) + nearest_po2(-1) # Returns 0 (this may not be what you expect) [/codeblock] + [b]WARNING:[/b] Due to the way it is implemented, this function returns [code]0[/code] rather than [code]1[/code] for non-positive values of [code]value[/code] (in reality, 1 is the smallest integer power of 2). </description> </method> <method name="ord"> @@ -725,16 +735,17 @@ <argument index="0" name="json" type="String"> </argument> <description> - Parse JSON text to a Variant (use [method typeof] to check if it is what you expect). - Be aware that the JSON specification does not define integer or float types, but only a number type. Therefore, parsing a JSON text will convert all numerical values to [float] types. - Note that JSON objects do not preserve key order like Godot dictionaries, thus you should not rely on keys being in a certain order if a dictionary is constructed from JSON. In contrast, JSON arrays retain the order of their elements: + Parse JSON text to a Variant. (Use [method typeof] to check if the Variant's type is what you expect.) + [b]Note:[/b] The JSON specification does not define integer or float types, but only a [i]number[/i] type. Therefore, parsing a JSON text will convert all numerical values to [float] types. + [b]Note:[/b] JSON objects do not preserve key order like Godot dictionaries, thus, you should not rely on keys being in a certain order if a dictionary is constructed from JSON. In contrast, JSON arrays retain the order of their elements: [codeblock] - p = parse_json('["a", "b", "c"]') - if typeof(p) == TYPE_ARRAY: - print(p[0]) # Prints a + var p = JSON.parse('["hello", "world", "!"]') + if typeof(p.result) == TYPE_ARRAY: + print(p.result[0]) # Prints "hello" else: - print("unexpected results") + push_error("Unexpected results.") [/codeblock] + See also [JSON] for an alternative way to parse JSON text. </description> </method> <method name="polar2cartesian"> @@ -1093,12 +1104,15 @@ </argument> <argument index="1" name="to" type="float"> </argument> - <argument index="2" name="weight" type="float"> + <argument index="2" name="s" type="float"> </argument> <description> - Returns a number smoothly interpolated between the [code]from[/code] and [code]to[/code], based on the [code]weight[/code]. Similar to [method lerp], but interpolates faster at the beginning and slower at the end. + Returns the result of smoothly interpolating the value of [code]s[/code] between [code]0[/code] and [code]1[/code], based on the where [code]s[/code] lies with respect to the edges [code]from[/code] and [code]to[/code]. + The return value is [code]0[/code] if [code]s <= from[/code], and [code]1[/code] if [code]s >= to[/code]. If [code]s[/code] lies between [code]from[/code] and [code]to[/code], the returned value follows an S-shaped curve that maps [code]s[/code] between [code]0[/code] and [code]1[/code]. + This S-shaped curve is the cubic Hermite interpolator, given by [code]f(s) = 3*s^2 - 2*s^3[/code]. [codeblock] - smoothstep(0, 2, 0.5) # Returns 0.15 + smoothstep(0, 2, -5.0) # Returns 0.0 + smoothstep(0, 2, 0.5) # Returns 0.15625 smoothstep(0, 2, 1.0) # Returns 0.5 smoothstep(0, 2, 2.0) # Returns 1.0 [/codeblock] @@ -1114,7 +1128,7 @@ [codeblock] sqrt(9) # Returns 3 [/codeblock] - If you need negative inputs, use [code]System.Numerics.Complex[/code] in C#. + [b]Note:[/b]Negative values of [code]s[/code] return NaN. If you need negative inputs, use [code]System.Numerics.Complex[/code] in C#. </description> </method> <method name="step_decimals"> @@ -1207,12 +1221,16 @@ <argument index="0" name="var" type="Variant"> </argument> <description> - Converts a Variant [code]var[/code] to JSON text and return the result. Useful for serializing data to store or send over the network. + Converts a [Variant] [code]var[/code] to JSON text and return the result. Useful for serializing data to store or send over the network. [codeblock] + # Both numbers below are integers. a = { "a": 1, "b": 2 } b = to_json(a) print(b) # {"a":1, "b":2} + # Both numbers above are floats, even if they display without any decimal places. [/codeblock] + [b]Note:[/b] The JSON specification does not define integer or float types, but only a [i]number[/i] type. Therefore, converting a [Variant] to JSON text will convert all numerical values to [float] types. + See also [JSON] for an alternative way to convert a [Variant] to JSON text. </description> </method> <method name="type_exists"> @@ -1255,9 +1273,9 @@ j = to_json([1, 2, 3]) v = validate_json(j) if not v: - print("valid") + print("Valid JSON.") else: - prints("invalid", v) + push_error("Invalid JSON: " + v) [/codeblock] </description> </method> @@ -1354,42 +1372,6 @@ [code]wrapi[/code] is more flexible than using the [method posmod] approach by giving the user control over the minimum value. </description> </method> - <method name="yield"> - <return type="GDScriptFunctionState"> - </return> - <argument index="0" name="object" type="Object" default="null"> - </argument> - <argument index="1" name="signal" type="String" default=""""> - </argument> - <description> - Stops the function execution and returns the current suspended state to the calling function. - From the caller, call [method GDScriptFunctionState.resume] on the state to resume execution. This invalidates the state. Within the resumed function, [code]yield()[/code] returns whatever was passed to the [code]resume()[/code] function call. - If passed an object and a signal, the execution is resumed when the object emits the given signal. In this case, [code]yield()[/code] returns the argument passed to [code]emit_signal()[/code] if the signal takes only one argument, or an array containing all the arguments passed to [code]emit_signal()[/code] if the signal takes multiple arguments. - You can also use [code]yield[/code] to wait for a function to finish: - [codeblock] - func _ready(): - yield(countdown(), "completed") # waiting for the countdown() function to complete - print('Ready') - - func countdown(): - yield(get_tree(), "idle_frame") # returns a GDScriptFunctionState object to _ready() - print(3) - yield(get_tree().create_timer(1.0), "timeout") - print(2) - yield(get_tree().create_timer(1.0), "timeout") - print(1) - yield(get_tree().create_timer(1.0), "timeout") - - # prints: - # 3 - # 2 - # 1 - # Ready - [/codeblock] - When yielding on a function, the [code]completed[/code] signal will be emitted automatically when the function returns. It can, therefore, be used as the [code]signal[/code] parameter of the [code]yield[/code] method to resume. - In order to yield on a function, the resulting function should also return a [code]GDScriptFunctionState[/code]. Notice [code]yield(get_tree(), "idle_frame")[/code] from the above example. - </description> - </method> </methods> <constants> <constant name="PI" value="3.141593"> diff --git a/modules/gdscript/doc_classes/GDScriptFunctionState.xml b/modules/gdscript/doc_classes/GDScriptFunctionState.xml index 9a73764646..5e369b32d9 100644 --- a/modules/gdscript/doc_classes/GDScriptFunctionState.xml +++ b/modules/gdscript/doc_classes/GDScriptFunctionState.xml @@ -4,7 +4,8 @@ State of a function call after yielding. </brief_description> <description> - Calling [method @GDScript.yield] within a function will cause that function to yield and return its current state as an object of this type. The yielded function call can then be resumed later by calling [method resume] on this state object. + FIXME: Outdated docs as of GDScript rewrite in 4.0. + Calling [code]yield[/code] within a function will cause that function to yield and return its current state as an object of this type. The yielded function call can then be resumed later by calling [method resume] on this state object. </description> <tutorials> </tutorials> @@ -26,7 +27,7 @@ </argument> <description> Resume execution of the yielded function call. - If handed an argument, return the argument from the [method @GDScript.yield] call in the yielded function call. You can pass e.g. an [Array] to hand multiple arguments. + If handed an argument, return the argument from the [code]yield[/code] call in the yielded function call. You can pass e.g. an [Array] to hand multiple arguments. This function returns what the resumed function call returns, possibly another function state if yielded again. </description> </method> diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 40ef0aeec6..9170255c02 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -1309,39 +1309,6 @@ Variant GDScriptInstance::call(const StringName &p_method, const Variant **p_arg return Variant(); } -void GDScriptInstance::call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount) { - GDScript *sptr = script.ptr(); - Callable::CallError ce; - - while (sptr) { - Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method); - if (E) { - E->get()->call(this, p_args, p_argcount, ce); - return; - } - sptr = sptr->_base; - } -} - -void GDScriptInstance::_ml_call_reversed(GDScript *sptr, const StringName &p_method, const Variant **p_args, int p_argcount) { - if (sptr->_base) { - _ml_call_reversed(sptr->_base, p_method, p_args, p_argcount); - } - - Callable::CallError ce; - - Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method); - if (E) { - E->get()->call(this, p_args, p_argcount, ce); - } -} - -void GDScriptInstance::call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount) { - if (script.ptr()) { - _ml_call_reversed(script.ptr(), p_method, p_args, p_argcount); - } -} - void GDScriptInstance::notification(int p_notification) { //notification is not virtual, it gets called at ALL levels just like in C. Variant value = p_notification; diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 8236464f15..9906b4014d 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -146,7 +146,6 @@ protected: void _get_property_list(List<PropertyInfo> *p_properties) const; Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override; - //void call_multilevel(const StringName& p_method,const Variant** p_args,int p_argcount); static void _bind_methods(); @@ -258,8 +257,6 @@ class GDScriptInstance : public ScriptInstance { SelfList<GDScriptFunctionState>::List pending_func_states; - void _ml_call_reversed(GDScript *sptr, const StringName &p_method, const Variant **p_args, int p_argcount); - public: virtual Object *get_owner() { return owner; } @@ -271,8 +268,6 @@ public: virtual void get_method_list(List<MethodInfo> *p_list) const; virtual bool has_method(const StringName &p_method) const; virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); - virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount); - virtual void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount); Variant debug_get_member_by_index(int p_idx) const { return members[p_idx]; } diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index d2c21e64ed..1e72216ad2 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -71,6 +71,10 @@ static StringName get_real_class_name(const StringName &p_source) { return p_source; } +void GDScriptAnalyzer::cleanup() { + underscore_map.clear(); +} + static GDScriptParser::DataType make_callable_type(const MethodInfo &p_info) { GDScriptParser::DataType type; type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT; @@ -342,6 +346,16 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type return result; } + if (first == "Object") { + result.kind = GDScriptParser::DataType::NATIVE; + result.native_type = "Object"; + if (p_type->type_chain.size() > 1) { + push_error(R"("Object" type don't contain nested types.)", p_type->type_chain[1]); + return GDScriptParser::DataType(); + } + return result; + } + if (GDScriptParser::get_builtin_type(first) < Variant::VARIANT_MAX) { // Built-in types. if (p_type->type_chain.size() > 1) { @@ -484,7 +498,7 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas if (member.variable->initializer != nullptr) { if (!is_type_compatible(datatype, member.variable->initializer->get_datatype(), true)) { - push_error(vformat(R"(Value of type "%s" cannot be assigned to variable of type "%s".)", member.variable->initializer->get_datatype().to_string(), datatype.to_string()), member.variable->initializer); + push_error(vformat(R"(Value of type "%s" cannot be assigned to a variable of type "%s".)", member.variable->initializer->get_datatype().to_string(), datatype.to_string()), member.variable->initializer); } else if (datatype.builtin_type == Variant::INT && member.variable->initializer->get_datatype().builtin_type == Variant::FLOAT) { #ifdef DEBUG_ENABLED parser->push_warning(member.variable->initializer, GDScriptWarning::NARROWING_CONVERSION); @@ -979,7 +993,7 @@ void GDScriptAnalyzer::resolve_variable(GDScriptParser::VariableNode *p_variable if (p_variable->initializer != nullptr) { if (!is_type_compatible(type, p_variable->initializer->get_datatype(), true)) { - push_error(vformat(R"(Value of type "%s" cannot be assigned to variable of type "%s".)", p_variable->initializer->get_datatype().to_string(), type.to_string()), p_variable->initializer); + push_error(vformat(R"(Value of type "%s" cannot be assigned to a variable of type "%s".)", p_variable->initializer->get_datatype().to_string(), type.to_string()), p_variable->initializer); #ifdef DEBUG_ENABLED } else if (type.builtin_type == Variant::INT && p_variable->initializer->get_datatype().builtin_type == Variant::FLOAT) { parser->push_warning(p_variable->initializer, GDScriptWarning::NARROWING_CONVERSION); @@ -1359,11 +1373,61 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig push_error("Cannot assign a new value to a constant.", p_assignment->assignee); } - if (!is_type_compatible(p_assignment->assignee->get_datatype(), p_assignment->assigned_value->get_datatype(), true)) { - if (p_assignment->assignee->get_datatype().is_hard_type()) { - push_error(vformat(R"(Cannot assign a value of type "%s" to a target of type "%s".)", p_assignment->assigned_value->get_datatype().to_string(), p_assignment->assignee->get_datatype().to_string()), p_assignment->assigned_value); + Variant::Operator vop = Variant::Operator::OP_EQUAL; + switch (p_assignment->operation) { + case GDScriptParser::AssignmentNode::OP_NONE: + vop = Variant::Operator::OP_EQUAL; + break; + case GDScriptParser::AssignmentNode::OP_ADDITION: + vop = Variant::Operator::OP_ADD; + break; + case GDScriptParser::AssignmentNode::OP_SUBTRACTION: + vop = Variant::Operator::OP_SUBTRACT; + break; + case GDScriptParser::AssignmentNode::OP_MULTIPLICATION: + vop = Variant::Operator::OP_MULTIPLY; + break; + case GDScriptParser::AssignmentNode::OP_DIVISION: + vop = Variant::Operator::OP_DIVIDE; + break; + case GDScriptParser::AssignmentNode::OP_MODULO: + vop = Variant::Operator::OP_MODULE; + break; + case GDScriptParser::AssignmentNode::OP_BIT_SHIFT_LEFT: + vop = Variant::Operator::OP_SHIFT_LEFT; + break; + case GDScriptParser::AssignmentNode::OP_BIT_SHIFT_RIGHT: + vop = Variant::Operator::OP_SHIFT_RIGHT; + break; + case GDScriptParser::AssignmentNode::OP_BIT_AND: + vop = Variant::Operator::OP_BIT_AND; + break; + case GDScriptParser::AssignmentNode::OP_BIT_OR: + vop = Variant::Operator::OP_BIT_OR; + break; + case GDScriptParser::AssignmentNode::OP_BIT_XOR: + vop = Variant::Operator::OP_BIT_XOR; + break; + } + + if (!p_assignment->assignee->get_datatype().is_variant() && !p_assignment->assigned_value->get_datatype().is_variant()) { + bool compatible = true; + GDScriptParser::DataType op_type = p_assignment->assigned_value->get_datatype(); + if (vop != Variant::OP_EQUAL) { + op_type = get_operation_type(vop, p_assignment->assignee->get_datatype(), p_assignment->assigned_value->get_datatype(), compatible); + } + + if (compatible) { + compatible = is_type_compatible(p_assignment->assignee->get_datatype(), op_type, true); + if (!compatible) { + if (p_assignment->assignee->get_datatype().is_hard_type()) { + push_error(vformat(R"(Cannot assign a value of type "%s" to a target of type "%s".)", p_assignment->assigned_value->get_datatype().to_string(), p_assignment->assignee->get_datatype().to_string()), p_assignment->assigned_value); + } else { + // TODO: Warning in this case. + } + } } else { - // TODO: Warning in this case. + push_error(vformat(R"(Invalid operands "%s" and "%s" for assignment operator.)", p_assignment->assignee->get_datatype().to_string(), p_assignment->assigned_value->get_datatype().to_string()), p_assignment); } } @@ -1420,6 +1484,12 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig } void GDScriptAnalyzer::reduce_await(GDScriptParser::AwaitNode *p_await) { + if (p_await->to_await == nullptr) { + GDScriptParser::DataType await_type; + await_type.kind = GDScriptParser::DataType::VARIANT; + p_await->set_datatype(await_type); + return; + } if (p_await->to_await->type == GDScriptParser::Node::CALL) { reduce_call(static_cast<GDScriptParser::CallNode *>(p_await->to_await), true); } else { @@ -2015,7 +2085,7 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod GDScriptParser::ClassNode *outer = base_class->outer; while (outer != nullptr) { if (outer->has_member(name)) { - const GDScriptParser::ClassNode::Member &member = base_class->get_member(name); + const GDScriptParser::ClassNode::Member &member = outer->get_member(name); if (member.type == GDScriptParser::ClassNode::Member::CONSTANT) { // TODO: Make sure loops won't cause problem. And make special error message for those. // For out-of-order resolution: diff --git a/modules/gdscript/gdscript_analyzer.h b/modules/gdscript/gdscript_analyzer.h index 85183d3272..06d3530cb6 100644 --- a/modules/gdscript/gdscript_analyzer.h +++ b/modules/gdscript/gdscript_analyzer.h @@ -113,6 +113,8 @@ public: Error analyze(); GDScriptAnalyzer(GDScriptParser *p_parser); + + static void cleanup(); }; #endif // GDSCRIPT_ANALYZER_H diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 3d37c7f803..e34d87f5cc 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -736,7 +736,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: } else { if (callee->type == GDScriptParser::Node::IDENTIFIER) { // Self function call. - if (codegen.function_node && codegen.function_node->is_static) { + if ((codegen.function_node && codegen.function_node->is_static) || call->function_name == "new") { ret = (GDScriptFunction::ADDR_TYPE_CLASS << GDScriptFunction::ADDR_BITS); } else { ret = (GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS); diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp index 7f2a62a8e9..fefbf906f0 100644 --- a/modules/gdscript/gdscript_functions.cpp +++ b/modules/gdscript/gdscript_functions.cpp @@ -1636,7 +1636,7 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { return mi; } break; case MATH_SMOOTHSTEP: { - MethodInfo mi("smoothstep", PropertyInfo(Variant::FLOAT, "from"), PropertyInfo(Variant::FLOAT, "to"), PropertyInfo(Variant::FLOAT, "weight")); + MethodInfo mi("smoothstep", PropertyInfo(Variant::FLOAT, "from"), PropertyInfo(Variant::FLOAT, "to"), PropertyInfo(Variant::FLOAT, "s")); mi.return_val.type = Variant::FLOAT; return mi; } break; diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index af07457750..1f3e1c1e40 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -94,6 +94,10 @@ Variant::Type GDScriptParser::get_builtin_type(const StringName &p_type) { return Variant::VARIANT_MAX; } +void GDScriptParser::cleanup() { + builtin_types.clear(); +} + GDScriptFunctions::Function GDScriptParser::get_builtin_function(const StringName &p_name) { for (int i = 0; i < GDScriptFunctions::FUNC_MAX; i++) { if (p_name == GDScriptFunctions::get_func_name(GDScriptFunctions::Function(i))) { diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index a741ae0cc7..c9ab3d4e12 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -1335,6 +1335,7 @@ public: void print_tree(const GDScriptParser &p_parser); }; #endif // DEBUG_ENABLED + static void cleanup(); }; #endif // GDSCRIPT_PARSER_H diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index d230173e9a..7a4bdd88ba 100644 --- a/modules/gdscript/gdscript_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -646,7 +646,7 @@ GDScriptTokenizer::Token GDScriptTokenizer::number() { int64_t value = number.bin_to_int(); return make_literal(value); } else if (has_decimal || has_exponent) { - double value = number.to_double(); + double value = number.to_float(); return make_literal(value); } else { int64_t value = number.to_int(); diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp index 23c7f97b5a..c554cbac05 100644 --- a/modules/gdscript/register_types.cpp +++ b/modules/gdscript/register_types.cpp @@ -35,6 +35,7 @@ #include "core/os/dir_access.h" #include "core/os/file_access.h" #include "gdscript.h" +#include "gdscript_analyzer.h" #include "gdscript_cache.h" #include "gdscript_tokenizer.h" @@ -148,4 +149,7 @@ void unregister_gdscript_types() { EditorTranslationParser::get_singleton()->remove_parser(gdscript_translation_parser_plugin, EditorTranslationParser::STANDARD); gdscript_translation_parser_plugin.unref(); #endif // TOOLS_ENABLED + + GDScriptParser::cleanup(); + GDScriptAnalyzer::cleanup(); } |