From: K.Kosako Date: Wed, 5 Jul 2017 00:17:58 +0000 (+0900) Subject: implement compiling for if-else X-Git-Tag: v6.5.0^2~162 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e4e54cef43549dee54b00719a18d096815708b54;p=onig implement compiling for if-else --- diff --git a/src/regcomp.c b/src/regcomp.c index ab8d3df..7b5d828 100644 --- a/src/regcomp.c +++ b/src/regcomp.c @@ -1336,6 +1336,28 @@ compile_length_enclosure_node(EnclosureNode* node, regex_t* reg) } break; + case ENCLOSURE_IF_ELSE: + { + Node* cond = NODE_ENCLOSURE_BODY(node); + Node* Then = node->te.Then; + Node* Else = node->te.Else; + + len = compile_length_tree(cond, reg); + if (len < 0) return len; + len += SIZE_OP_PUSH; + len += SIZE_OP_PUSH_STOP_BT + SIZE_OP_POP_STOP_BT; + tlen = compile_length_tree(Then, reg); + if (tlen < 0) return tlen; + len += tlen; + if (IS_NOT_NULL(Else)) { + len += SIZE_OP_JUMP; + tlen = compile_length_tree(Else, reg); + if (tlen < 0) return tlen; + len += tlen; + } + } + break; + default: return ONIGERR_TYPE_BUG; break; @@ -1467,6 +1489,42 @@ compile_enclosure_node(EnclosureNode* node, regex_t* reg, ScanEnv* env) } break; + case ENCLOSURE_IF_ELSE: + { + int cond_len, then_len, jump_len; + Node* cond = NODE_ENCLOSURE_BODY(node); + Node* Then = node->te.Then; + Node* Else = node->te.Else; + + r = add_opcode(reg, OP_PUSH_STOP_BT); + if (r != 0) return r; + + cond_len = compile_length_tree(cond, reg); + if (cond_len < 0) return cond_len; + then_len = compile_length_tree(Then, reg); + if (then_len < 0) return then_len; + + jump_len = cond_len + then_len + SIZE_OP_POP_STOP_BT; + if (IS_NOT_NULL(Else)) jump_len += SIZE_OP_JUMP; + + r = add_opcode_rel_addr(reg, OP_PUSH, jump_len); + if (r != 0) return r; + r = compile_tree(cond, reg, env); + if (r != 0) return r; + r = add_opcode(reg, OP_POP_STOP_BT); + if (r != 0) return r; + + r = compile_tree(Then, reg, env); + if (r != 0) return r; + + if (IS_NOT_NULL(Else)) { + int else_len = compile_length_tree(Else, reg); + r = add_opcode_rel_addr(reg, OP_JUMP, else_len); + if (r != 0) return r; + r = compile_tree(Else, reg, env); + } + } + default: return ONIGERR_TYPE_BUG; break;