Browse Source

Adds enums to GDScript

Fixes #2966

(cherry picked from commit 4ee82a2c38c57fb980df1ed4727d47959ba9e983)
Bojidar Marinov 9 years ago
parent
commit
ed80f4563a

+ 84 - 0
modules/gdscript/gd_parser.cpp

@@ -3152,6 +3152,90 @@ 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.
+
+				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: {

+ 2 - 0
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" },

+ 1 - 0
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,