Pārlūkot izejas kodu

Adds enums to GDScript

Fixes #2966
Bojidar Marinov 9 gadi atpakaļ
vecāks
revīzija
4ee82a2c38

+ 88 - 0
modules/gdscript/gd_parser.cpp

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

+ 2 - 0
modules/gdscript/gd_tokenizer.cpp

@@ -95,6 +95,7 @@ const char* GDTokenizer::token_names[TK_MAX]={
 "setget",
 "setget",
 "const",
 "const",
 "var",
 "var",
+"enum",
 "preload",
 "preload",
 "assert",
 "assert",
 "yield",
 "yield",
@@ -874,6 +875,7 @@ void GDTokenizerText::_advance() {
 								{TK_PR_SLAVE,"slave"},
 								{TK_PR_SLAVE,"slave"},
 								{TK_PR_SYNC,"sync"},
 								{TK_PR_SYNC,"sync"},
 								{TK_PR_CONST,"const"},
 								{TK_PR_CONST,"const"},
+								{TK_PR_ENUM,"enum"},
 								//controlflow
 								//controlflow
 								{TK_CF_IF,"if"},
 								{TK_CF_IF,"if"},
 								{TK_CF_ELIF,"elif"},
 								{TK_CF_ELIF,"elif"},

+ 1 - 0
modules/gdscript/gd_tokenizer.h

@@ -102,6 +102,7 @@ public:
 		TK_PR_SETGET,
 		TK_PR_SETGET,
 		TK_PR_CONST,
 		TK_PR_CONST,
 		TK_PR_VAR,
 		TK_PR_VAR,
+		TK_PR_ENUM,
 		TK_PR_PRELOAD,
 		TK_PR_PRELOAD,
 		TK_PR_ASSERT,
 		TK_PR_ASSERT,
 		TK_PR_YIELD,
 		TK_PR_YIELD,