Merge pull request #8293 from Faless/2.1-enum

[2.1] Cherry pick GDScript enum support ( #6292 )
This commit is contained in:
Rémi Verschelde 2017-04-06 23:05:29 +02:00 committed by GitHub
commit 3916d964de
3 changed files with 107 additions and 0 deletions

View File

@ -3152,6 +3152,110 @@ void GDParser::_parse_class(ClassNode *p_class) {
return;
}
} 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: {

View File

@ -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" },

View File

@ -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,