summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorBojidar Marinov <bojidar.marinov.bg@gmail.com>2016-08-26 14:15:45 +0300
committerBojidar Marinov <bojidar.marinov.bg@gmail.com>2016-08-27 15:27:02 +0300
commit4ee82a2c38c57fb980df1ed4727d47959ba9e983 (patch)
treeef393dfafdeb9dbd34ea6299f9d19139bbef0c08 /modules
parent41a58f7935ecd0c91ae55a5e5b84425aadc51840 (diff)
Adds enums to GDScript
Fixes #2966
Diffstat (limited to 'modules')
-rw-r--r--modules/gdscript/gd_parser.cpp88
-rw-r--r--modules/gdscript/gd_tokenizer.cpp2
-rw-r--r--modules/gdscript/gd_tokenizer.h1
3 files changed, 91 insertions, 0 deletions
diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp
index e5a8dc0152..ed3bfd7ce2 100644
--- a/modules/gdscript/gd_parser.cpp
+++ b/modules/gdscript/gd_parser.cpp
@@ -3157,6 +3157,94 @@ 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.
+
+ 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();
+ }
+
+ p_class->constant_expressions.push_back(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 47e740b227..072a7e26a0 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",
@@ -874,6 +875,7 @@ void GDTokenizerText::_advance() {
{TK_PR_SLAVE,"slave"},
{TK_PR_SYNC,"sync"},
{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 1815f82894..b91229ab1e 100644
--- a/modules/gdscript/gd_tokenizer.h
+++ b/modules/gdscript/gd_tokenizer.h
@@ -102,6 +102,7 @@ public:
TK_PR_SETGET,
TK_PR_CONST,
TK_PR_VAR,
+ TK_PR_ENUM,
TK_PR_PRELOAD,
TK_PR_ASSERT,
TK_PR_YIELD,