diff options
| author | Rémi Verschelde | 2017-04-06 23:05:29 +0200 |
|---|---|---|
| committer | GitHub | 2017-04-06 23:05:29 +0200 |
| commit | 3916d964de9f8697fb129c08fcee2d72b4696880 (patch) | |
| tree | 795b412485a1bc4fad21336897a7fa17d74c9c96 /modules | |
| parent | 6ff1436fde9aac33b685129fd12a488ab0a15c36 (diff) | |
| parent | dad8e04139100143e4a2884c84c5c32bdff9c951 (diff) | |
| download | godot-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.cpp | 104 | ||||
| -rw-r--r-- | modules/gdscript/gd_tokenizer.cpp | 2 | ||||
| -rw-r--r-- | modules/gdscript/gd_tokenizer.h | 1 |
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, |
