summaryrefslogtreecommitdiff
path: root/modules/gdscript/gd_parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript/gd_parser.cpp')
-rw-r--r--modules/gdscript/gd_parser.cpp155
1 files changed, 102 insertions, 53 deletions
diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp
index 46eade0b7c..659e19a9d0 100644
--- a/modules/gdscript/gd_parser.cpp
+++ b/modules/gdscript/gd_parser.cpp
@@ -372,10 +372,26 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
} else if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER) {
//identifier (reference)
- IdentifierNode *id = alloc_node<IdentifierNode>();
- id->name=tokenizer->get_token_identifier();
- tokenizer->advance();
- expr=id;
+ const ClassNode* cln = static_cast<const ClassNode*>(get_parse_tree());
+ bool bfn = false;
+ StringName idn( tokenizer->get_token_identifier() );
+
+ for( int i=0; i<cln->constant_expressions.size(); ++i ) {
+
+ if( cln->constant_expressions[i].identifier == idn ) {
+ tokenizer->advance();
+ expr = cln->constant_expressions[i].expression;
+ bfn = true;
+ break;
+ }
+ }
+
+ if( !bfn ) {
+ IdentifierNode *id = alloc_node<IdentifierNode>();
+ id->name = idn;
+ tokenizer->advance();
+ expr = id;
+ }
} else if (/*tokenizer->get_token()==GDTokenizer::TK_OP_ADD ||*/ tokenizer->get_token()==GDTokenizer::TK_OP_SUB || tokenizer->get_token()==GDTokenizer::TK_OP_NOT || tokenizer->get_token()==GDTokenizer::TK_OP_BIT_INVERT) {
@@ -1179,7 +1195,7 @@ GDParser::Node* GDParser::_reduce_expression(Node *p_node,bool p_to_const) {
case OperatorNode::OP_ASSIGN_BIT_XOR: {
if (op->arguments[0]->type==Node::TYPE_CONSTANT) {
- _set_error("Can't assign to constant");
+ _set_error("Can't assign to constant",tokenizer->get_token_line()-1);
return op;
}
@@ -2360,80 +2376,113 @@ void GDParser::_parse_class(ClassNode *p_class) {
member._export.name=member.identifier;
tokenizer->advance();
- p_class->variables.push_back(member);
+ if (tokenizer->get_token()==GDTokenizer::TK_OP_ASSIGN) {
- if (tokenizer->get_token()!=GDTokenizer::TK_OP_ASSIGN) {
+#ifdef DEBUG_ENABLED
+ int line = tokenizer->get_token_line();
+#endif
+ tokenizer->advance();
- if (autoexport) {
+ Node *subexpr=NULL;
- _set_error("Type-less export needs a constant expression assigned to infer type.");
+ subexpr = _parse_and_reduce_expression(p_class,false);
+ if (!subexpr)
return;
- }
- break;
- }
-#ifdef DEBUG_ENABLED
- int line = tokenizer->get_token_line();
-#endif
- tokenizer->advance();
- Node *subexpr=NULL;
+ if (autoexport) {
+ if (subexpr->type==Node::TYPE_ARRAY) {
- subexpr = _parse_and_reduce_expression(p_class,false);
- if (!subexpr)
- return;
+ member._export.type=Variant::ARRAY;
- if (autoexport) {
- if (subexpr->type==Node::TYPE_ARRAY) {
+ } else if (subexpr->type==Node::TYPE_DICTIONARY) {
- p_class->variables[p_class->variables.size()-1]._export.type=Variant::ARRAY;
+ member._export.type=Variant::DICTIONARY;
- } else if (subexpr->type==Node::TYPE_DICTIONARY) {
+ } else {
- p_class->variables[p_class->variables.size()-1]._export.type=Variant::DICTIONARY;
+ if (subexpr->type!=Node::TYPE_CONSTANT) {
- } else {
+ _set_error("Type-less export needs a constant expression assigned to infer type.");
+ return;
+ }
- if (subexpr->type!=Node::TYPE_CONSTANT) {
+ ConstantNode *cn = static_cast<ConstantNode*>(subexpr);
+ if (cn->value.get_type()==Variant::NIL) {
- _set_error("Type-less export needs a constant expression assigned to infer type.");
- return;
+ _set_error("Can't accept a null constant expression for infering export type.");
+ return;
+ }
+ member._export.type=cn->value.get_type();
}
+ }
+#ifdef TOOLS_ENABLED
+ if (subexpr->type==Node::TYPE_CONSTANT && member._export.type!=Variant::NIL) {
ConstantNode *cn = static_cast<ConstantNode*>(subexpr);
- if (cn->value.get_type()==Variant::NIL) {
-
- _set_error("Can't accept a null constant expression for infering export type.");
- return;
+ if (cn->value.get_type()!=Variant::NIL) {
+ member.default_value=cn->value;
}
- p_class->variables[p_class->variables.size()-1]._export.type=cn->value.get_type();
}
- }
-#ifdef TOOLS_ENABLED
- if (subexpr->type==Node::TYPE_CONSTANT && p_class->variables[p_class->variables.size()-1]._export.type!=Variant::NIL) {
+#endif
+
+ IdentifierNode *id = alloc_node<IdentifierNode>();
+ id->name=member.identifier;
+
+ OperatorNode *op = alloc_node<OperatorNode>();
+ op->op=OperatorNode::OP_ASSIGN;
+ op->arguments.push_back(id);
+ op->arguments.push_back(subexpr);
- ConstantNode *cn = static_cast<ConstantNode*>(subexpr);
- if (cn->value.get_type()!=Variant::NIL) {
- p_class->variables[p_class->variables.size()-1].default_value=cn->value;
+#ifdef DEBUG_ENABLED
+ NewLineNode *nl = alloc_node<NewLineNode>();
+ nl->line=line;
+ p_class->initializer->statements.push_back(nl);
+#endif
+ p_class->initializer->statements.push_back(op);
+
+
+
+ } else {
+
+ if (autoexport) {
+
+ _set_error("Type-less export needs a constant expression assigned to infer type.");
+ return;
}
+
}
-#endif
+ if (tokenizer->get_token()==GDTokenizer::TK_PR_SETGET) {
- IdentifierNode *id = alloc_node<IdentifierNode>();
- id->name=member.identifier;
+ tokenizer->advance();
- OperatorNode *op = alloc_node<OperatorNode>();
- op->op=OperatorNode::OP_ASSIGN;
- op->arguments.push_back(id);
- op->arguments.push_back(subexpr);
+ if (tokenizer->get_token()!=GDTokenizer::TK_COMMA) {
+ //just comma means using only getter
+ if (tokenizer->get_token()!=GDTokenizer::TK_IDENTIFIER) {
+ _set_error("Expected identifier for setter function after 'notify'.");
+ }
-#ifdef DEBUG_ENABLED
- NewLineNode *nl = alloc_node<NewLineNode>();
- nl->line=line;
- p_class->initializer->statements.push_back(nl);
-#endif
- p_class->initializer->statements.push_back(op);
+ member.setter=tokenizer->get_token_identifier();
+
+ tokenizer->advance();
+ }
+
+ if (tokenizer->get_token()==GDTokenizer::TK_COMMA) {
+ //there is a getter
+ tokenizer->advance();
+
+ if (tokenizer->get_token()!=GDTokenizer::TK_IDENTIFIER) {
+ _set_error("Expected identifier for getter function after ','.");
+ }
+
+ member.getter=tokenizer->get_token_identifier();
+ tokenizer->advance();
+
+ }
+ }
+
+ p_class->variables.push_back(member);
_end_statement();