From 2ff8c1bc8106880997755ff559f5e930f1842034 Mon Sep 17 00:00:00 2001 From: ChibiDenDen Date: Sat, 18 Jan 2020 23:27:13 +0200 Subject: [PATCH] GDScript: add this_class keyword --- core/math/expression.cpp | 15 +++++++++++++++ core/math/expression.h | 9 +++++++++ modules/gdscript/gdscript_compiler.cpp | 4 ++++ modules/gdscript/gdscript_parser.cpp | 9 +++++++++ modules/gdscript/gdscript_parser.h | 5 +++++ modules/gdscript/gdscript_tokenizer.cpp | 2 ++ modules/gdscript/gdscript_tokenizer.h | 1 + 7 files changed, 45 insertions(+) diff --git a/core/math/expression.cpp b/core/math/expression.cpp index 655098376ca2..ca1209edb74e 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -1222,6 +1222,8 @@ Error Expression::_get_token(Token &r_token) { r_token.type = TK_OP_AND; } else if (id == "self") { r_token.type = TK_SELF; + } else if (id == "this_class") { + r_token.type = TK_THIS_CLASS; } else { for (int i = 0; i < Variant::VARIANT_MAX; i++) { @@ -1485,6 +1487,11 @@ Expression::ENode *Expression::_parse_expression() { SelfNode *self = alloc_node(); expr = self; } break; + case TK_THIS_CLASS: { + + ThisClassNode *this_class = alloc_node(); + expr = this_class; + } break; case TK_CONSTANT: { ConstantNode *constant = alloc_node(); constant->value = tk.value; @@ -1959,6 +1966,14 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression: } r_ret = p_instance; } break; + case Expression::ENode::TYPE_THIS_CLASS: { + + if (!p_instance) { + r_error_str = RTR("this_class can't be used because instance is null (not passed)"); + return true; + } + r_ret = p_instance->get_class(); + } break; case Expression::ENode::TYPE_OPERATOR: { const Expression::OperatorNode *op = static_cast(p_node); diff --git a/core/math/expression.h b/core/math/expression.h index c5b9d79a16e1..69efc1ba37ed 100644 --- a/core/math/expression.h +++ b/core/math/expression.h @@ -149,6 +149,7 @@ class Expression : public Reference { TK_IDENTIFIER, TK_BUILTIN_FUNC, TK_SELF, + TK_THIS_CLASS, TK_CONSTANT, TK_BASIC_TYPE, TK_COLON, @@ -206,6 +207,7 @@ class Expression : public Reference { TYPE_INPUT, TYPE_CONSTANT, TYPE_SELF, + TYPE_THIS_CLASS, TYPE_OPERATOR, TYPE_INDEX, TYPE_NAMED_INDEX, @@ -273,6 +275,13 @@ class Expression : public Reference { } }; + struct ThisClassNode : public ENode { + + ThisClassNode() { + type = TYPE_THIS_CLASS; + } + }; + struct IndexNode : public ENode { ENode *base; ENode *index; diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index fba1b992ecd9..878913018e89 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -391,6 +391,10 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser:: } return (GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS); } break; + case GDScriptParser::Node::TYPE_THIS_CLASS: { + //return constant + return (GDScriptFunction::ADDR_TYPE_CLASS << GDScriptFunction::ADDR_BITS); + } break; case GDScriptParser::Node::TYPE_ARRAY: { const GDScriptParser::ArrayNode *an = static_cast(p_expression); diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 5c2e7137bfa5..6b132ed1c808 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -616,6 +616,11 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s SelfNode *self = alloc_node(); tokenizer->advance(); expr = self; + } else if (tokenizer->get_token() == GDScriptTokenizer::TK_THIS_CLASS) { + //constant defined by tokenizer + ThisClassNode *this_class = alloc_node(); + tokenizer->advance(); + expr = this_class; } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE && tokenizer->get_token(1) == GDScriptTokenizer::TK_PERIOD) { Variant::Type bi_type = tokenizer->get_token_type(); @@ -5576,6 +5581,10 @@ bool GDScriptParser::_parse_type(DataType &r_type, bool p_can_be_void) { full_name = r_type.native_type; } } break; + case GDScriptTokenizer::TK_THIS_CLASS: { + r_type.kind = DataType::CLASS; + r_type.class_type = current_class; + } break; default: { return false; } diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index c74d7dd856b5..a79fded15825 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -118,6 +118,7 @@ class GDScriptParser { TYPE_ARRAY, TYPE_DICTIONARY, TYPE_SELF, + TYPE_THIS_CLASS, TYPE_OPERATOR, TYPE_CONTROL_FLOW, TYPE_LOCAL_VAR, @@ -345,6 +346,10 @@ class GDScriptParser { SelfNode() { type = TYPE_SELF; } }; + struct ThisClassNode : public Node { + ThisClassNode() { type = TYPE_THIS_CLASS; } + }; + struct OperatorNode : public Node { enum Operator { //call/constructor operator diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index 11ffa22906cd..870cfb04bcec 100644 --- a/modules/gdscript/gdscript_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -227,6 +227,7 @@ static const _kws _keyword_list[] = { { GDScriptTokenizer::TK_CF_MATCH, "match" }, { GDScriptTokenizer::TK_CF_PASS, "pass" }, { GDScriptTokenizer::TK_SELF, "self" }, + { GDScriptTokenizer::TK_THIS_CLASS, "this_class" }, { GDScriptTokenizer::TK_CONST_PI, "PI" }, { GDScriptTokenizer::TK_CONST_TAU, "TAU" }, { GDScriptTokenizer::TK_WILDCARD, "_" }, @@ -291,6 +292,7 @@ bool GDScriptTokenizer::is_token_literal(int p_offset, bool variable_safe) const case TK_CF_MATCH: case TK_CF_PASS: case TK_SELF: + case TK_THIS_CLASS: case TK_CONST_PI: case TK_CONST_TAU: case TK_WILDCARD: diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h index 0efc8551cb90..86bfe9debc1b 100644 --- a/modules/gdscript/gdscript_tokenizer.h +++ b/modules/gdscript/gdscript_tokenizer.h @@ -46,6 +46,7 @@ class GDScriptTokenizer { TK_IDENTIFIER, TK_CONSTANT, TK_SELF, + TK_THIS_CLASS, TK_BUILT_IN_TYPE, TK_BUILT_IN_FUNC, TK_OP_IN,