1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-05 12:10:55 +00:00

pattern matcher: Implemented backend

changed comments
This commit is contained in:
Karroffel
2016-10-16 13:20:28 +02:00
committed by karroffel
parent d445f0639f
commit e781a7e07e
4 changed files with 375 additions and 289 deletions

View File

@@ -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;