]> granicus.if.org Git - onig/commitdiff
implement compiling for if-else
authorK.Kosako <kosako@sofnec.co.jp>
Wed, 5 Jul 2017 00:17:58 +0000 (09:17 +0900)
committerK.Kosako <kosako@sofnec.co.jp>
Wed, 5 Jul 2017 00:17:58 +0000 (09:17 +0900)
src/regcomp.c

index ab8d3df977af9b75e6d319628d5090f1556f0f55..7b5d828cd40e034644eafa7becb60e224656e327 100644 (file)
@@ -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;