diff --git a/modules/gdscript/gd_compiler.cpp b/modules/gdscript/gd_compiler.cpp index a45c79aca7e..add6235f328 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 f924f1de316..912170d2b00 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 4aa5c8cfea0..143c5f20eb4 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 70c78877668..1c19328fe80 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 952a28bdb5e..6fea204704d 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 c732c00b826..39c7f3cfc47 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 3c0107cea21..96dd7ed20ba 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,