From d445f0639fa9eccc44f1f9c153108f9e90981077 Mon Sep 17 00:00:00 2001 From: Karroffel Date: Wed, 5 Oct 2016 18:48:38 +0200 Subject: pattern matcher: Implemented transformations --- modules/gdscript/gd_compiler.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'modules/gdscript/gd_compiler.cpp') diff --git a/modules/gdscript/gd_compiler.cpp b/modules/gdscript/gd_compiler.cpp index 2e2cbe7b29..f7765200b9 100644 --- a/modules/gdscript/gd_compiler.cpp +++ b/modules/gdscript/gd_compiler.cpp @@ -980,7 +980,7 @@ int GDCompiler::_parse_expression(CodeGen& codegen,const GDParser::Node *p_expre } break; //TYPE_TYPE, default: { - + ERR_EXPLAIN("Bug in bytecode compiler, unexpected node in parse tree while parsing expression."); ERR_FAIL_V(-1); //unreachable code } break; @@ -1019,7 +1019,13 @@ Error GDCompiler::_parse_block(CodeGen& codegen,const GDParser::BlockNode *p_blo switch(cf->cf_type) { - + case GDParser::ControlFlowNode::CF_MATCH: { + Error err = _parse_block(codegen,cf->match->compiled_block,p_stack_level,p_break_addr,p_continue_addr); + if (err) + return err; + + } break; + case GDParser::ControlFlowNode::CF_IF: { #ifdef DEBUG_ENABLED -- cgit v1.2.3 From e781a7e07ec7388deccd372899ecbea8af7b67f4 Mon Sep 17 00:00:00 2001 From: Karroffel Date: Sun, 16 Oct 2016 13:20:28 +0200 Subject: pattern matcher: Implemented backend changed comments --- modules/gdscript/gd_compiler.cpp | 67 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 4 deletions(-) (limited to 'modules/gdscript/gd_compiler.cpp') diff --git a/modules/gdscript/gd_compiler.cpp b/modules/gdscript/gd_compiler.cpp index f7765200b9..139fdaad0d 100644 --- a/modules/gdscript/gd_compiler.cpp +++ b/modules/gdscript/gd_compiler.cpp @@ -980,7 +980,7 @@ int GDCompiler::_parse_expression(CodeGen& codegen,const GDParser::Node *p_expre } break; //TYPE_TYPE, default: { - + ERR_EXPLAIN("Bug in bytecode compiler, unexpected node in parse tree while parsing expression."); ERR_FAIL_V(-1); //unreachable code } break; @@ -1020,9 +1020,68 @@ Error GDCompiler::_parse_block(CodeGen& codegen,const GDParser::BlockNode *p_blo switch(cf->cf_type) { case GDParser::ControlFlowNode::CF_MATCH: { - Error err = _parse_block(codegen,cf->match->compiled_block,p_stack_level,p_break_addr,p_continue_addr); - if (err) - return err; + GDParser::MatchNode *match = cf->match; + + GDParser::IdentifierNode *id = memnew(GDParser::IdentifierNode); + id->name = "#match_value"; + + // var #match_value + // copied because there is no _parse_statement :( + codegen.add_stack_identifier(id->name, p_stack_level++); + codegen.alloc_stack(p_stack_level); + new_identifiers++; + + GDParser::OperatorNode *op = memnew(GDParser::OperatorNode); + op->op=GDParser::OperatorNode::OP_ASSIGN; + op->arguments.push_back(id); + op->arguments.push_back(match->val_to_match); + + int ret = _parse_expression(codegen, op, p_stack_level); + if (ret < 0) { + return ERR_PARSE_ERROR; + } + + // break address + codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); + codegen.opcodes.push_back(codegen.opcodes.size() + 3); + int break_addr = codegen.opcodes.size(); + codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); + codegen.opcodes.push_back(0); // break addr + + for (int j = 0; j < match->compiled_pattern_branches.size(); j++) { + GDParser::MatchNode::CompiledPatternBranch branch = match->compiled_pattern_branches[j]; + + // jump over continue + // jump unconditionally + // continue address + // compile the condition + int ret = _parse_expression(codegen, branch.compiled_pattern, p_stack_level); + if (ret < 0) { + return ERR_PARSE_ERROR; + } + + codegen.opcodes.push_back(GDFunction::OPCODE_JUMP_IF); + codegen.opcodes.push_back(ret); + codegen.opcodes.push_back(codegen.opcodes.size() + 3); + int continue_addr = codegen.opcodes.size(); + codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); + codegen.opcodes.push_back(0); + + + + Error err = _parse_block(codegen, branch.body, p_stack_level, p_break_addr, continue_addr); + if (err) { + return ERR_PARSE_ERROR; + } + + codegen.opcodes.push_back(GDFunction::OPCODE_JUMP); + codegen.opcodes.push_back(break_addr); + + codegen.opcodes[continue_addr + 1] = codegen.opcodes.size(); + } + + codegen.opcodes[break_addr + 1] = codegen.opcodes.size(); + } break; -- cgit v1.2.3