summaryrefslogtreecommitdiffstats
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.cpp79
1 files changed, 73 insertions, 6 deletions
diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp
index 2829132d99..ef9e85a8c2 100644
--- a/modules/gdscript/gd_parser.cpp
+++ b/modules/gdscript/gd_parser.cpp
@@ -29,6 +29,7 @@
#include "gd_parser.h"
#include "print_string.h"
#include "io/resource_loader.h"
+#include "os/file_access.h"
/* TODO:
*Property reduce constant expressions
@@ -224,12 +225,23 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
String path = tokenizer->get_token_constant();
if (!path.is_abs_path() && base_path!="")
path=base_path+"/"+path;
- path = path.replace("///","//");
+ path = path.replace("///","//");
- Ref<Resource> res = ResourceLoader::load(path);
- if (!res.is_valid()) {
- _set_error("Can't preload resource at path: "+path);
- return NULL;
+ Ref<Resource> res;
+ if (!validating) {
+
+ //this can be too slow for just validating code
+ res = ResourceLoader::load(path);
+ if (!res.is_valid()) {
+ _set_error("Can't preload resource at path: "+path);
+ return NULL;
+ }
+ } else {
+
+ if (!FileAccess::exists(path)) {
+ _set_error("Can't preload resource at path: "+path);
+ return NULL;
+ }
}
tokenizer->advance();
@@ -244,6 +256,55 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
tokenizer->advance();
expr=constant;
+ } else if (tokenizer->get_token()==GDTokenizer::TK_PR_YIELD) {
+
+ //constant defined by tokenizer
+
+ tokenizer->advance();
+ if (tokenizer->get_token()!=GDTokenizer::TK_PARENTHESIS_OPEN) {
+ _set_error("Expected '(' after 'yield'");
+ return NULL;
+ }
+
+ tokenizer->advance();
+
+ OperatorNode *yield = alloc_node<OperatorNode>();
+ yield->op=OperatorNode::OP_YIELD;
+
+ if (tokenizer->get_token()==GDTokenizer::TK_PARENTHESIS_CLOSE) {
+ expr=yield;
+ tokenizer->advance();
+ } else {
+
+ Node *object = _parse_and_reduce_expression(p_parent,p_static);
+ if (!object)
+ return NULL;
+ yield->arguments.push_back(object);
+
+ if (tokenizer->get_token()!=GDTokenizer::TK_COMMA) {
+
+ _set_error("Expected ',' after first argument of 'yield'");
+ return NULL;
+ }
+
+ tokenizer->advance();
+
+ Node *signal = _parse_and_reduce_expression(p_parent,p_static);
+ if (!signal)
+ return NULL;
+ yield->arguments.push_back(signal);
+
+ if (tokenizer->get_token()!=GDTokenizer::TK_PARENTHESIS_CLOSE) {
+
+ _set_error("Expected ')' after second argument of 'yield'");
+ return NULL;
+ }
+
+ tokenizer->advance();
+
+ expr=yield;
+ }
+
} else if (tokenizer->get_token()==GDTokenizer::TK_SELF) {
@@ -1055,6 +1116,10 @@ GDParser::Node* GDParser::_reduce_expression(Node *p_node,bool p_to_const) {
}
return op; //don't reduce yet
+
+ } else if (op->op==OperatorNode::OP_YIELD) {
+ return op;
+
} else if (op->op==OperatorNode::OP_INDEX) {
//can reduce indices into constant arrays or dictionaries
@@ -2468,12 +2533,13 @@ Error GDParser::parse_bytecode(const Vector<uint8_t> &p_bytecode,const String& p
}
-Error GDParser::parse(const String& p_code,const String& p_base_path) {
+Error GDParser::parse(const String& p_code,const String& p_base_path,bool p_just_validate) {
GDTokenizerText *tt = memnew( GDTokenizerText );
tt->set_code(p_code);
+ validating=p_just_validate;
tokenizer=tt;
Error ret = _parse(p_base_path);
memdelete(tt);
@@ -2498,6 +2564,7 @@ void GDParser::clear() {
head=NULL;
list=NULL;
+ validating=false;
error_set=false;
tab_level.clear();
tab_level.push_back(0);