diff options
Diffstat (limited to 'modules/gdscript')
-rw-r--r-- | modules/gdscript/gd_functions.cpp | 43 | ||||
-rw-r--r-- | modules/gdscript/gd_functions.h | 1 | ||||
-rw-r--r-- | modules/gdscript/gd_parser.cpp | 16 | ||||
-rw-r--r-- | modules/gdscript/gd_parser.h | 1 | ||||
-rw-r--r-- | modules/gdscript/gd_script.cpp | 13 | ||||
-rw-r--r-- | modules/gdscript/gd_tokenizer.cpp | 18 |
6 files changed, 90 insertions, 2 deletions
diff --git a/modules/gdscript/gd_functions.cpp b/modules/gdscript/gd_functions.cpp index 2930d9322c..f789493ae8 100644 --- a/modules/gdscript/gd_functions.cpp +++ b/modules/gdscript/gd_functions.cpp @@ -31,6 +31,7 @@ #include "object_type_db.h" #include "reference.h" #include "gd_script.h" +#include "func_ref.h" #include "os/os.h" const char *GDFunctions::get_func_name(Function p_func) { @@ -80,6 +81,7 @@ const char *GDFunctions::get_func_name(Function p_func) { "clamp", "nearest_po2", "weakref", + "funcref", "convert", "typeof", "str", @@ -452,6 +454,36 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va } break; + case FUNC_FUNCREF: { + VALIDATE_ARG_COUNT(2); + if (p_args[0]->get_type()!=Variant::OBJECT) { + + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument=0; + r_error.expected=Variant::OBJECT; + r_ret=Variant(); + return; + + } + if (p_args[1]->get_type()!=Variant::STRING && p_args[1]->get_type()!=Variant::NODE_PATH) { + + r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.argument=1; + r_error.expected=Variant::STRING; + r_ret=Variant(); + return; + + } + + Ref<FuncRef> fr = memnew( FuncRef); + + Object *obj = *p_args[0]; + fr->set_instance(*p_args[0]); + fr->set_function(*p_args[1]); + + r_ret=fr; + + } break; case TYPE_CONVERT: { VALIDATE_ARG_COUNT(2); VALIDATE_ARG_NUM(1); @@ -678,7 +710,7 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va } r_ret=ResourceLoader::load(*p_args[0]); - } + } break; case INST2DICT: { VALIDATE_ARG_COUNT(1); @@ -1063,7 +1095,7 @@ MethodInfo GDFunctions::get_info(Function p_func) { return mi; } break; case MATH_RAND: { - MethodInfo mi("rand"); + MethodInfo mi("randi"); mi.return_val.type=Variant::INT; return mi; } break; @@ -1130,6 +1162,13 @@ MethodInfo GDFunctions::get_info(Function p_func) { return mi; } break; + case FUNC_FUNCREF: { + + MethodInfo mi("funcref",PropertyInfo(Variant::OBJECT,"instance"),PropertyInfo(Variant::STRING,"funcname")); + mi.return_val.type=Variant::OBJECT; + return mi; + + } break; case TYPE_CONVERT: { MethodInfo mi("convert",PropertyInfo(Variant::NIL,"what"),PropertyInfo(Variant::INT,"type")); diff --git a/modules/gdscript/gd_functions.h b/modules/gdscript/gd_functions.h index 2ab397d18a..9255e5e2c5 100644 --- a/modules/gdscript/gd_functions.h +++ b/modules/gdscript/gd_functions.h @@ -77,6 +77,7 @@ public: LOGIC_CLAMP, LOGIC_NEAREST_PO2, OBJ_WEAKREF, + FUNC_FUNCREF, TYPE_CONVERT, TYPE_OF, TEXT_STR, diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index f962f8c5fb..f540660cd3 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -174,10 +174,19 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_ /* Parse Operand */ /*****************/ + if (parenthesis>0) { + //remove empty space (only allowed if inside parenthesis + while(tokenizer->get_token()==GDTokenizer::TK_NEWLINE) { + tokenizer->advance(); + } + } + if (tokenizer->get_token()==GDTokenizer::TK_PARENTHESIS_OPEN) { //subexpression () tokenizer->advance(); + parenthesis++; Node* subexpr = _parse_expression(p_parent,p_static); + parenthesis--; if (!subexpr) return NULL; @@ -629,6 +638,12 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_ /* Parse Operator */ /******************/ + if (parenthesis>0) { + //remove empty space (only allowed if inside parenthesis + while(tokenizer->get_token()==GDTokenizer::TK_NEWLINE) { + tokenizer->advance(); + } + } Expression e; e.is_op=false; @@ -2475,6 +2490,7 @@ void GDParser::clear() { tab_level.push_back(0); error_line=0; error_column=0; + parenthesis=0; current_export.type=Variant::NIL; error=""; diff --git a/modules/gdscript/gd_parser.h b/modules/gdscript/gd_parser.h index 1925808cac..278e5f543d 100644 --- a/modules/gdscript/gd_parser.h +++ b/modules/gdscript/gd_parser.h @@ -356,6 +356,7 @@ private: template<class T> T* alloc_node(); + int parenthesis; bool error_set; String error; int error_line; diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp index 29857e6be6..75bb47ceab 100644 --- a/modules/gdscript/gd_script.cpp +++ b/modules/gdscript/gd_script.cpp @@ -635,6 +635,19 @@ Variant GDFunction::call(GDInstance *p_instance,const Variant **p_args, int p_ar err.argument-=1; } } + } if (methodstr=="free") { + + if (err.error==Variant::CallError::CALL_ERROR_INVALID_METHOD) { + + if (base->is_ref()) { + err_text="Attempted to free a reference."; + break; + } else if (base->get_type()==Variant::OBJECT) { + + err_text="Attempted to free a locked object (calling or emitting)."; + break; + } + } } err_text=_get_call_error(err,"function '"+methodstr+"' in base '"+basestr+"'",(const Variant**)argptrs); break; diff --git a/modules/gdscript/gd_tokenizer.cpp b/modules/gdscript/gd_tokenizer.cpp index ff9be7926b..aeee1f6667 100644 --- a/modules/gdscript/gd_tokenizer.cpp +++ b/modules/gdscript/gd_tokenizer.cpp @@ -242,6 +242,24 @@ void GDTokenizerText::_advance() { case 0: _make_token(TK_EOF); break; + case '\\': + INCPOS(1); + if (GETCHAR(0)=='\r') { + INCPOS(1); + } + + if (GETCHAR(0)!='\n') { + _make_error("Expected newline after '\\'."); + return; + } + + INCPOS(1); + + while(GETCHAR(0)==' ' || GETCHAR(0)=='\t') { + INCPOS(1); + } + + continue; case '\t': case '\r': case ' ': |