]> git.vpit.fr Git - perl/modules/Sub-Nary.git/blobdiff - Nary.xs
Add support for die()
[perl/modules/Sub-Nary.git] / Nary.xs
diff --git a/Nary.xs b/Nary.xs
index 0329eea6439cb62c80bcadb24546d02ef7f1abe8..66eced60f0e7e930024e74e4a3a8d453af9799c3 100644 (file)
--- a/Nary.xs
+++ b/Nary.xs
@@ -31,6 +31,7 @@ STATIC void sn_store_ent(pTHX_ HV *tb, SV *key, SV *val, U32 hash) {
 
 STATIC U32 sn_hash_list = 0;
 STATIC U32 sn_hash_exit = 0;
+STATIC U32 sn_hash_die  = 0;
 
 /* --- XS ------------------------------------------------------------------ */
 
@@ -42,6 +43,7 @@ BOOT:
 {
  PERL_HASH(sn_hash_list, "list", 4);
  PERL_HASH(sn_hash_exit, "exit", 4);
+ PERL_HASH(sn_hash_die,  "die",  3);
 }
 
 void
@@ -248,13 +250,13 @@ PROTOTYPE: @
 PREINIT:
  HV *res[3];
  SV *val;
- SV *exit1, *list1;
+ SV *kexit, *klist, *kdie;
  SV *temp;
  HE *key, *old;
  I32 i;
  I32 n = 0, o;
  I32 j, n1, n2;
- NV pl = 0, pe = 0;
+ NV pe = 0, pd = 0, pl = 0;
  sn_combcache *cache = NULL;
  I32 cachelen = 1;
 CODE:
@@ -268,7 +270,7 @@ CODE:
  temp = sv_2mortal(newSViv(0));
  for (i = 0; i < items; ++i) {
   SV *cur = ST(i);
-  NV pe1 = 0, pl1 = 0;
+  NV pe1 = 0, pd1 = 0, pd2, pl1 = 0;
   if (!SvOK(cur))
    continue;
   if (!SvROK(cur)) {
@@ -285,29 +287,42 @@ CODE:
    res[o] = newHV();
   else
    hv_clear(res[o]);
-  exit1 = hv_delete((HV *) cur, "exit", 4, 0);
+  kexit = hv_delete((HV *) cur, "exit", 4, 0);
   n1    = hv_iterinit((HV *) cur);
-  if (exit1) {
+  if (kexit) {
    if (!n1) {
-    pe = 1;
+    pe = 1 - pd;
     pl = 0;
     n  = o;
     break;
    }
-   pe1 = SvNV(exit1);
+   pe1 = SvNV(kexit);
   }
-  list1 = hv_delete((HV *) cur, "list", 4, 0);
-  if (list1) {
+  kdie  = hv_delete((HV *) cur, "die", 3, 0);
+  if (kdie) {
    if (n1 == 1) {
-    pl = 1 - pe;
+    pd = 1 - pe;
+    pl = 0;
+    n  = o;
+    break;
+   }
+   --n1;
+   pd1 = SvNV(kdie);
+  }
+  klist = hv_delete((HV *) cur, "list", 4, 0);
+  if (klist) {
+   if (n1 == 1) {
+    pl = 1 - (pe + pd);
     n  = o;
     break;
    }
-   pl1 = SvNV(list1);
+   pl1 = SvNV(klist);
   }
-  pl = pl1 * (1 - pe) + pl * (1 - pe1) - pl * pl1;
-  pe = pe + (1 - pe) * pe1;
-  n2 = hv_iterinit(res[n]);
+  pl  = pl1 * (1 - (pd + pe)) + pl * (1 - (pd1 + pe1)) - pl * pl1;
+  pd2 = pd1 * (1 - pe)        + pd                     - pd * pd1;
+  pe  = pe1 * (1 - pd)        + pe                     - pe * pe1;
+  pd  = pd2;
+  n2  = hv_iterinit(res[n]);
   if (!n2) {
    cache[0].k = 0;
    cache[0].v = 1;
@@ -343,6 +358,8 @@ CODE:
  SvREFCNT_dec(res[2]);
  if (pe)
   sn_store(res[n], "exit", 4, newSVnv(pe), sn_hash_exit);
+ if (pd)
+  sn_store(res[n], "die",  3, newSVnv(pd), sn_hash_die);
  if (pl)
   sn_store(res[n], "list", 4, newSVnv(pl), sn_hash_list);
  if (n == 1)