From e0d21d2158e8d03ee3139392284915c19ee4619b Mon Sep 17 00:00:00 2001 From: reduz Date: Mon, 28 Dec 2015 15:59:20 -0300 Subject: Ability to set autoloads as singleton global variables --- modules/gdscript/gd_script.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'modules/gdscript/gd_script.cpp') diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp index 62006cf18..ef53dcfe7 100644 --- a/modules/gdscript/gd_script.cpp +++ b/modules/gdscript/gd_script.cpp @@ -2570,6 +2570,12 @@ void GDScriptLanguage::_add_global(const StringName& p_name,const Variant& p_val _global_array=global_array.ptr(); } +void GDScriptLanguage::add_global_constant(const StringName& p_variable,const Variant& p_value) { + + _add_global(p_variable,p_value); +} + + void GDScriptLanguage::init() { -- cgit v1.2.3-70-g09d2 From 30c12297dc6df7d35df140475c0cec7308aea77a Mon Sep 17 00:00:00 2001 From: reduz Date: Mon, 28 Dec 2015 19:31:52 -0300 Subject: - added 'onready' keyword to gdscript. Defers initialization of member variables until _ready() is run. --- modules/gdscript/gd_compiler.cpp | 33 ++++++++++++++++++++++++---- modules/gdscript/gd_compiler.h | 2 +- modules/gdscript/gd_parser.cpp | 45 +++++++++++++++++++++++++++++++++++++-- modules/gdscript/gd_parser.h | 1 + modules/gdscript/gd_script.cpp | 1 + modules/gdscript/gd_tokenizer.cpp | 3 ++- modules/gdscript/gd_tokenizer.h | 1 + 7 files changed, 78 insertions(+), 8 deletions(-) (limited to 'modules/gdscript/gd_script.cpp') diff --git a/modules/gdscript/gd_compiler.cpp b/modules/gdscript/gd_compiler.cpp index a62225f66..a45c79aca 100644 --- a/modules/gdscript/gd_compiler.cpp +++ b/modules/gdscript/gd_compiler.cpp @@ -1181,7 +1181,7 @@ Error GDCompiler::_parse_block(CodeGen& codegen,const GDParser::BlockNode *p_blo } -Error GDCompiler::_parse_function(GDScript *p_script,const GDParser::ClassNode *p_class,const GDParser::FunctionNode *p_func) { +Error GDCompiler::_parse_function(GDScript *p_script,const GDParser::ClassNode *p_class,const GDParser::FunctionNode *p_func,bool p_for_ready) { Vector bytecode; CodeGen codegen; @@ -1212,9 +1212,9 @@ Error GDCompiler::_parse_function(GDScript *p_script,const GDParser::ClassNode * /* Parse initializer -if applies- */ - bool is_initializer=false || !p_func; + bool is_initializer=!p_for_ready && !p_func; - if (!p_func || String(p_func->name)=="_init") { + if (is_initializer || String(p_func->name)=="_init") { //parse initializer for class members if (!p_func && p_class->extends_used && p_script->native.is_null()){ @@ -1232,6 +1232,17 @@ Error GDCompiler::_parse_function(GDScript *p_script,const GDParser::ClassNode * } + if (p_for_ready || (p_func && String(p_func->name)=="_ready")) { + //parse initializer for class members + if (p_class->ready->statements.size()) { + Error err = _parse_block(codegen,p_class->ready,stack_level); + if (err) + return err; + } + + } + + /* Parse default argument code -if applies- */ Vector defarg_addr; @@ -1260,7 +1271,10 @@ Error GDCompiler::_parse_function(GDScript *p_script,const GDParser::ClassNode * func_name=p_func->name; } else { - func_name="_init"; + if (p_for_ready) + func_name="_ready"; + else + func_name="_init"; } codegen.opcodes.push_back(GDFunction::OPCODE_END); @@ -1614,10 +1628,14 @@ Error GDCompiler::_parse_class(GDScript *p_script,GDScript *p_owner,const GDPars //parse methods bool has_initializer=false; + bool has_ready=false; + for(int i=0;ifunctions.size();i++) { if (!has_initializer && p_class->functions[i]->name=="_init") has_initializer=true; + if (!has_ready && p_class->functions[i]->name=="_ready") + has_ready=true; Error err = _parse_function(p_script,p_class,p_class->functions[i]); if (err) return err; @@ -1640,6 +1658,13 @@ Error GDCompiler::_parse_class(GDScript *p_script,GDScript *p_owner,const GDPars return err; } + if (!has_ready && p_class->ready->statements.size()) { + //create a constructor + Error err = _parse_function(p_script,p_class,NULL,true); + if (err) + return err; + } + #ifdef DEBUG_ENABLED //validate setters/getters if debug is enabled for(int i=0;ivariables.size();i++) { diff --git a/modules/gdscript/gd_compiler.h b/modules/gdscript/gd_compiler.h index bdf4e9816..ea3e7c8b6 100644 --- a/modules/gdscript/gd_compiler.h +++ b/modules/gdscript/gd_compiler.h @@ -143,7 +143,7 @@ class GDCompiler { int _parse_assign_right_expression(CodeGen& codegen,const GDParser::OperatorNode *p_expression, int p_stack_level); int _parse_expression(CodeGen& codegen,const GDParser::Node *p_expression, int p_stack_level,bool p_root=false,bool p_initializer=false); Error _parse_block(CodeGen& codegen,const GDParser::BlockNode *p_block,int p_stack_level=0,int p_break_addr=-1,int p_continue_addr=-1); - Error _parse_function(GDScript *p_script,const GDParser::ClassNode *p_class,const GDParser::FunctionNode *p_func); + Error _parse_function(GDScript *p_script,const GDParser::ClassNode *p_class,const GDParser::FunctionNode *p_func,bool p_for_ready=false); Error _parse_class(GDScript *p_script,GDScript *p_owner,const GDParser::ClassNode *p_class); int err_line; int err_column; diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index 4339a13ed..95e172e26 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -2767,6 +2767,21 @@ void GDParser::_parse_class(ClassNode *p_class) { } }; //fallthrough to var + case GDTokenizer::TK_PR_ONREADY: { + + if (tokenizer->get_token(-1)==GDTokenizer::TK_PR_EXPORT) { + current_export=PropertyInfo(); + _set_error("Expected 'var' (can't combine with 'onready')."); + return; + } else { + + tokenizer->advance(); + if (tokenizer->get_token()!=GDTokenizer::TK_PR_VAR) { + _set_error("Expected 'var'."); + return; + } + } + }; //fallthrough to var case GDTokenizer::TK_PR_VAR: { //variale declaration and (eventual) initialization @@ -2777,6 +2792,8 @@ void GDParser::_parse_class(ClassNode *p_class) { current_export=PropertyInfo(); } + bool onready = tokenizer->get_token(-1)==GDTokenizer::TK_PR_ONREADY; + tokenizer->advance(); if (tokenizer->get_token()!=GDTokenizer::TK_IDENTIFIER) { @@ -2807,6 +2824,21 @@ void GDParser::_parse_class(ClassNode *p_class) { return; } + //discourage common error + if (!onready && subexpr->type==Node::TYPE_OPERATOR) { + + OperatorNode *op=static_cast(subexpr); + if (op->op==OperatorNode::OP_CALL && op->arguments[0]->type==Node::TYPE_SELF && op->arguments[1]->type==Node::TYPE_IDENTIFIER) { + IdentifierNode *id=static_cast(op->arguments[1]); + if (id->name=="get_node") { + + _set_error("Use 'onready var "+String(member.identifier)+" = get_node(..)' instead"); + return; + + } + } + } + member.expression=subexpr; if (autoexport) { @@ -2853,12 +2885,19 @@ void GDParser::_parse_class(ClassNode *p_class) { op->arguments.push_back(id); op->arguments.push_back(subexpr); + #ifdef DEBUG_ENABLED NewLineNode *nl = alloc_node(); nl->line=line; - p_class->initializer->statements.push_back(nl); + if (onready) + p_class->ready->statements.push_back(nl); + else + p_class->initializer->statements.push_back(nl); #endif - p_class->initializer->statements.push_back(op); + if (onready) + p_class->ready->statements.push_back(op); + else + p_class->initializer->statements.push_back(op); @@ -3009,6 +3048,8 @@ Error GDParser::_parse(const String& p_base_path) { ClassNode *main_class = alloc_node(); main_class->initializer = alloc_node(); main_class->initializer->parent_class=main_class; + main_class->ready = alloc_node(); + main_class->ready->parent_class=main_class; current_class=main_class; _parse_class(main_class); diff --git a/modules/gdscript/gd_parser.h b/modules/gdscript/gd_parser.h index 04f3dff3d..4aa5c8cfe 100644 --- a/modules/gdscript/gd_parser.h +++ b/modules/gdscript/gd_parser.h @@ -105,6 +105,7 @@ public: Vector static_functions; Vector _signals; BlockNode *initializer; + BlockNode *ready; ClassNode *owner; //Vector initializers; int end_line; diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp index ef53dcfe7..70c788776 100644 --- a/modules/gdscript/gd_script.cpp +++ b/modules/gdscript/gd_script.cpp @@ -2652,6 +2652,7 @@ void GDScriptLanguage::get_reserved_words(List *p_words) const { "elif", "enum", "extends" , + "onready", "for" , "func" , "if" , diff --git a/modules/gdscript/gd_tokenizer.cpp b/modules/gdscript/gd_tokenizer.cpp index e44570166..c732c00b8 100644 --- a/modules/gdscript/gd_tokenizer.cpp +++ b/modules/gdscript/gd_tokenizer.cpp @@ -851,6 +851,7 @@ void GDTokenizerText::_advance() { {TK_PR_FUNCTION,"function"}, {TK_PR_CLASS,"class"}, {TK_PR_EXTENDS,"extends"}, + {TK_PR_ONREADY,"onready"}, {TK_PR_TOOL,"tool"}, {TK_PR_STATIC,"static"}, {TK_PR_EXPORT,"export"}, @@ -1040,7 +1041,7 @@ void GDTokenizerText::advance(int p_amount) { ////////////////////////////////////////////////////////////////////////////////////////////////////// -#define BYTECODE_VERSION 5 +#define BYTECODE_VERSION 6 Error GDTokenizerBuffer::set_code_buffer(const Vector & p_buffer) { diff --git a/modules/gdscript/gd_tokenizer.h b/modules/gdscript/gd_tokenizer.h index d6bd63c5b..3c0107cea 100644 --- a/modules/gdscript/gd_tokenizer.h +++ b/modules/gdscript/gd_tokenizer.h @@ -95,6 +95,7 @@ public: TK_PR_FUNCTION, TK_PR_CLASS, TK_PR_EXTENDS, + TK_PR_ONREADY, TK_PR_TOOL, TK_PR_STATIC, TK_PR_EXPORT, -- cgit v1.2.3-70-g09d2 From 7d2d1442f83e6a7a57a1823a6cf5af53e5419d5f Mon Sep 17 00:00:00 2001 From: reduz Date: Tue, 29 Dec 2015 12:11:21 -0300 Subject: -add breakpoint statement to ease with debugging, closes #3165 --- modules/gdscript/gd_compiler.cpp | 4 ++++ modules/gdscript/gd_parser.cpp | 11 +++++++++++ modules/gdscript/gd_parser.h | 5 +++++ modules/gdscript/gd_script.cpp | 9 +++++++++ modules/gdscript/gd_script.h | 1 + modules/gdscript/gd_tokenizer.cpp | 4 +++- modules/gdscript/gd_tokenizer.h | 1 + 7 files changed, 34 insertions(+), 1 deletion(-) (limited to 'modules/gdscript/gd_script.cpp') diff --git a/modules/gdscript/gd_compiler.cpp b/modules/gdscript/gd_compiler.cpp index a45c79aca..add6235f3 100644 --- a/modules/gdscript/gd_compiler.cpp +++ b/modules/gdscript/gd_compiler.cpp @@ -1156,6 +1156,10 @@ Error GDCompiler::_parse_block(CodeGen& codegen,const GDParser::BlockNode *p_blo codegen.opcodes.push_back(GDFunction::OPCODE_ASSERT); codegen.opcodes.push_back(ret); } break; + case GDParser::Node::TYPE_BREAKPOINT: { + // try subblocks + codegen.opcodes.push_back(GDFunction::OPCODE_BREAKPOINT); + } break; case GDParser::Node::TYPE_LOCAL_VAR: { diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index f924f1de3..912170d2b 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -1862,6 +1862,17 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) { return; } } break; + case GDTokenizer::TK_PR_BREAKPOINT: { + + tokenizer->advance(); + BreakpointNode *bn = alloc_node(); + p_block->statements.push_back(bn); + + if (!_end_statement()) { + _set_error("Expected end of statement after breakpoint."); + return; + } + } break; default: { Node *expression = _parse_and_reduce_expression(p_block,p_static,false,true); diff --git a/modules/gdscript/gd_parser.h b/modules/gdscript/gd_parser.h index 4aa5c8cfe..143c5f20e 100644 --- a/modules/gdscript/gd_parser.h +++ b/modules/gdscript/gd_parser.h @@ -54,6 +54,7 @@ public: TYPE_CONTROL_FLOW, TYPE_LOCAL_VAR, TYPE_ASSERT, + TYPE_BREAKPOINT, TYPE_NEWLINE, }; @@ -276,6 +277,10 @@ public: AssertNode() { type=TYPE_ASSERT; } }; + struct BreakpointNode : public Node { + BreakpointNode() { type=TYPE_BREAKPOINT; } + }; + struct NewLineNode : public Node { NewLineNode() { type=TYPE_NEWLINE; } }; diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp index 70c788776..1c19328fe 100644 --- a/modules/gdscript/gd_script.cpp +++ b/modules/gdscript/gd_script.cpp @@ -1077,6 +1077,14 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a ip+=2; } continue; + case OPCODE_BREAKPOINT: { +#ifdef DEBUG_ENABLED + if (ScriptDebugger::get_singleton()) { + GDScriptLanguage::get_singleton()->debug_break("Breakpoint Statement",true); + } +#endif + ip+=1; + } continue; case OPCODE_LINE: { CHECK_SPACE(2); @@ -2672,6 +2680,7 @@ void GDScriptLanguage::get_reserved_words(List *p_words) const { "or", "export", "assert", + "breakpoint", "yield", "static", "float", diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gd_script.h index 952a28bdb..6fea20470 100644 --- a/modules/gdscript/gd_script.h +++ b/modules/gdscript/gd_script.h @@ -71,6 +71,7 @@ public: OPCODE_ITERATE_BEGIN, OPCODE_ITERATE, OPCODE_ASSERT, + OPCODE_BREAKPOINT, OPCODE_LINE, OPCODE_END }; diff --git a/modules/gdscript/gd_tokenizer.cpp b/modules/gdscript/gd_tokenizer.cpp index c732c00b8..39c7f3cfc 100644 --- a/modules/gdscript/gd_tokenizer.cpp +++ b/modules/gdscript/gd_tokenizer.cpp @@ -98,6 +98,7 @@ const char* GDTokenizer::token_names[TK_MAX]={ "assert", "yield", "signal", +"breakpoint", "'['", "']'", "'{'", @@ -861,6 +862,7 @@ void GDTokenizerText::_advance() { {TK_PR_ASSERT,"assert"}, {TK_PR_YIELD,"yield"}, {TK_PR_SIGNAL,"signal"}, + {TK_PR_BREAKPOINT,"breakpoint"}, {TK_PR_CONST,"const"}, //controlflow {TK_CF_IF,"if"}, @@ -1041,7 +1043,7 @@ void GDTokenizerText::advance(int p_amount) { ////////////////////////////////////////////////////////////////////////////////////////////////////// -#define BYTECODE_VERSION 6 +#define BYTECODE_VERSION 7 Error GDTokenizerBuffer::set_code_buffer(const Vector & p_buffer) { diff --git a/modules/gdscript/gd_tokenizer.h b/modules/gdscript/gd_tokenizer.h index 3c0107cea..96dd7ed20 100644 --- a/modules/gdscript/gd_tokenizer.h +++ b/modules/gdscript/gd_tokenizer.h @@ -106,6 +106,7 @@ public: TK_PR_ASSERT, TK_PR_YIELD, TK_PR_SIGNAL, + TK_PR_BREAKPOINT, TK_BRACKET_OPEN, TK_BRACKET_CLOSE, TK_CURLY_BRACKET_OPEN, -- cgit v1.2.3-70-g09d2