aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorRémi Verschelde2017-04-06 23:05:29 +0200
committerGitHub2017-04-06 23:05:29 +0200
commit3916d964de9f8697fb129c08fcee2d72b4696880 (patch)
tree795b412485a1bc4fad21336897a7fa17d74c9c96 /modules
parent6ff1436fde9aac33b685129fd12a488ab0a15c36 (diff)
parentdad8e04139100143e4a2884c84c5c32bdff9c951 (diff)
downloadgodot-3916d964de9f8697fb129c08fcee2d72b4696880.tar.gz
godot-3916d964de9f8697fb129c08fcee2d72b4696880.tar.zst
godot-3916d964de9f8697fb129c08fcee2d72b4696880.zip
Merge pull request #8293 from Faless/2.1-enum
[2.1] Cherry pick GDScript enum support ( #6292 )
Diffstat (limited to 'modules')
-rw-r--r--modules/gdscript/gd_parser.cpp104
-rw-r--r--modules/gdscript/gd_tokenizer.cpp2
-rw-r--r--modules/gdscript/gd_tokenizer.h1
3 files changed, 107 insertions, 0 deletions
diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp
index 74a3d5e9e..009100cb3 100644
--- a/modules/gdscript/gd_parser.cpp
+++ b/modules/gdscript/gd_parser.cpp
@@ -3153,6 +3153,110 @@ void GDParser::_parse_class(ClassNode *p_class) {
}
} break;
+ case GDTokenizer::TK_PR_ENUM: {
+ //mutiple constant declarations..
+
+ int last_assign = -1; // Incremented by 1 right before the assingment.
+ String enum_name;
+ Dictionary enum_dict;
+
+ tokenizer->advance();
+ if (tokenizer->get_token() == GDTokenizer::TK_IDENTIFIER) {
+ enum_name = tokenizer->get_token_identifier();
+ tokenizer->advance();
+ }
+ if (tokenizer->get_token() != GDTokenizer::TK_CURLY_BRACKET_OPEN) {
+ _set_error("Expected '{' in enum declaration");
+ return;
+ }
+ tokenizer->advance();
+
+ while (true) {
+ if (tokenizer->get_token() == GDTokenizer::TK_NEWLINE) {
+
+ tokenizer->advance(); // Ignore newlines
+ } else if (tokenizer->get_token() == GDTokenizer::TK_CURLY_BRACKET_CLOSE) {
+
+ tokenizer->advance();
+ break; // End of enum
+ } else if (tokenizer->get_token() != GDTokenizer::TK_IDENTIFIER) {
+
+ if (tokenizer->get_token() == GDTokenizer::TK_EOF) {
+ _set_error("Unexpected end of file.");
+ } else {
+ _set_error(String("Unexpected ") + GDTokenizer::get_token_name(tokenizer->get_token()) + ", expected identifier");
+ }
+
+ return;
+ } else { // tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER
+ ClassNode::Constant constant;
+
+ constant.identifier = tokenizer->get_token_identifier();
+
+ tokenizer->advance();
+
+ if (tokenizer->get_token() == GDTokenizer::TK_OP_ASSIGN) {
+ tokenizer->advance();
+
+ Node *subexpr = NULL;
+
+ subexpr = _parse_and_reduce_expression(p_class, true, true);
+ if (!subexpr) {
+ if (_recover_from_completion()) {
+ break;
+ }
+ return;
+ }
+
+ if (subexpr->type != Node::TYPE_CONSTANT) {
+ _set_error("Expected constant expression");
+ }
+
+ const ConstantNode *subexpr_const = static_cast<const ConstantNode *>(subexpr);
+
+ if (subexpr_const->value.get_type() != Variant::INT) {
+ _set_error("Expected an int value for enum");
+ }
+
+ last_assign = subexpr_const->value;
+
+ constant.expression = subexpr;
+
+ } else {
+ last_assign = last_assign + 1;
+ ConstantNode *cn = alloc_node<ConstantNode>();
+ cn->value = last_assign;
+ constant.expression = cn;
+ }
+
+ if (tokenizer->get_token() == GDTokenizer::TK_COMMA) {
+ tokenizer->advance();
+ }
+
+ if (enum_name != "") {
+ const ConstantNode *cn = static_cast<const ConstantNode *>(constant.expression);
+ enum_dict[constant.identifier] = cn->value;
+ }
+
+ p_class->constant_expressions.push_back(constant);
+ }
+ }
+
+ if (enum_name != "") {
+ ClassNode::Constant enum_constant;
+ enum_constant.identifier = enum_name;
+ ConstantNode *cn = alloc_node<ConstantNode>();
+ cn->value = enum_dict;
+ enum_constant.expression = cn;
+ p_class->constant_expressions.push_back(enum_constant);
+ }
+
+ if (!_end_statement()) {
+ _set_error("Expected end of statement (enum)");
+ return;
+ }
+
+ } break;
default: {
diff --git a/modules/gdscript/gd_tokenizer.cpp b/modules/gdscript/gd_tokenizer.cpp
index 3d9d49303..65156f0a9 100644
--- a/modules/gdscript/gd_tokenizer.cpp
+++ b/modules/gdscript/gd_tokenizer.cpp
@@ -95,6 +95,7 @@ const char *GDTokenizer::token_names[TK_MAX] = {
"setget",
"const",
"var",
+ "enum",
"preload",
"assert",
"yield",
@@ -861,6 +862,7 @@ void GDTokenizerText::_advance() {
{ TK_PR_SIGNAL, "signal" },
{ TK_PR_BREAKPOINT, "breakpoint" },
{ TK_PR_CONST, "const" },
+ { TK_PR_ENUM, "enum" },
//controlflow
{ TK_CF_IF, "if" },
{ TK_CF_ELIF, "elif" },
diff --git a/modules/gdscript/gd_tokenizer.h b/modules/gdscript/gd_tokenizer.h
index 1fe0910c3..84d15a56e 100644
--- a/modules/gdscript/gd_tokenizer.h
+++ b/modules/gdscript/gd_tokenizer.h
@@ -101,6 +101,7 @@ public:
TK_PR_SETGET,
TK_PR_CONST,
TK_PR_VAR,
+ TK_PR_ENUM,
TK_PR_PRELOAD,
TK_PR_ASSERT,
TK_PR_YIELD,