LCOV - code coverage report
Current view: top level - monetdb5/modules/mal - batcalc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 764 970 78.8 %
Date: 2024-04-26 00:35:57 Functions: 51 60 85.0 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : #include "monetdb_config.h"
      14             : #include "gdk.h"
      15             : #include "mal_exception.h"
      16             : #include "mal_interpreter.h"
      17             : 
      18             : static str
      19          21 : mythrow(enum malexception type, const char *fcn, const char *msg)
      20             : {
      21          21 :         char *errbuf = GDKerrbuf;
      22          21 :         char *s;
      23             : 
      24          21 :         if (errbuf && *errbuf) {
      25          21 :                 if (strncmp(errbuf, "!ERROR: ", 8) == 0)
      26          21 :                         errbuf += 8;
      27          21 :                 if (strchr(errbuf, '!') == errbuf + 5) {
      28           0 :                         s = createException(type, fcn, "%s", errbuf);
      29          21 :                 } else if ((s = strchr(errbuf, ':')) != NULL && s[1] == ' ') {
      30          21 :                         s = createException(type, fcn, "%s", s + 2);
      31             :                 } else {
      32           0 :                         s = createException(type, fcn, "%s", errbuf);
      33             :                 }
      34          21 :                 GDKclrerr();
      35          21 :                 return s;
      36             :         }
      37           0 :         return createException(type, fcn, "%s", msg);
      38             : }
      39             : 
      40             : static str
      41       17644 : CMDbatUNARY(MalStkPtr stk, InstrPtr pci,
      42             :                         BAT *(*batfunc)(BAT *, BAT *), const char *malfunc)
      43             : {
      44       17644 :         bat bid;
      45       17644 :         BAT *bn, *b, *s = NULL;
      46             : 
      47       17644 :         bid = *getArgReference_bat(stk, pci, 1);
      48       17644 :         if ((b = BATdescriptor(bid)) == NULL)
      49           0 :                 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
      50       17668 :         if (pci->argc == 3) {
      51         264 :                 bid = *getArgReference_bat(stk, pci, 2);
      52         264 :                 if (!is_bat_nil(bid)) {
      53         243 :                         if ((s = BATdescriptor(bid)) == NULL) {
      54           0 :                                 BBPunfix(b->batCacheid);
      55           0 :                                 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
      56             :                         }
      57             :                 }
      58             :         }
      59             : 
      60       17668 :         bn = (*batfunc) (b, s);
      61       17615 :         BBPunfix(b->batCacheid);
      62       17648 :         BBPreclaim(s);
      63       17641 :         if (bn == NULL) {
      64           0 :                 return mythrow(MAL, malfunc, OPERATION_FAILED);
      65             :         }
      66       17641 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
      67       17641 :         BBPkeepref(bn);
      68       17641 :         return MAL_SUCCEED;
      69             : }
      70             : 
      71             : static str
      72           0 : CMDbatUNARY1(MalStkPtr stk, InstrPtr pci,
      73             :                          BAT *(*batfunc)(BAT *, BAT *), const char *malfunc)
      74             : {
      75           0 :         bat bid;
      76           0 :         BAT *bn, *b, *s = NULL;
      77             : 
      78           0 :         bid = *getArgReference_bat(stk, pci, 1);
      79           0 :         if ((b = BATdescriptor(bid)) == NULL)
      80           0 :                 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
      81           0 :         if (pci->argc == 3) {
      82           0 :                 bid = *getArgReference_bat(stk, pci, 2);
      83           0 :                 if (!is_bat_nil(bid)) {
      84           0 :                         if ((s = BATdescriptor(bid)) == NULL) {
      85           0 :                                 BBPunfix(b->batCacheid);
      86           0 :                                 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
      87             :                         }
      88             :                 }
      89             :         }
      90             : 
      91           0 :         bn = (*batfunc) (b, s);
      92           0 :         BBPunfix(b->batCacheid);
      93           0 :         BBPreclaim(s);
      94           0 :         if (bn == NULL) {
      95           0 :                 return mythrow(MAL, malfunc, OPERATION_FAILED);
      96             :         }
      97           0 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
      98           0 :         BBPkeepref(bn);
      99           0 :         return MAL_SUCCEED;
     100             : }
     101             : 
     102             : static str
     103           0 : CMDbatISZERO(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     104             : {
     105           0 :         (void) cntxt;
     106           0 :         (void) mb;
     107             : 
     108           0 :         return CMDbatUNARY(stk, pci, BATcalciszero, "batcalc.iszero");
     109             : }
     110             : 
     111             : static str
     112        3708 : CMDbatISNIL(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     113             : {
     114        3708 :         (void) cntxt;
     115        3708 :         (void) mb;
     116             : 
     117        3708 :         return CMDbatUNARY(stk, pci, BATcalcisnil, "batcalc.isnil");
     118             : }
     119             : 
     120             : static str
     121        4615 : CMDbatISNOTNIL(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     122             : {
     123        4615 :         (void) cntxt;
     124        4615 :         (void) mb;
     125             : 
     126        4615 :         return CMDbatUNARY(stk, pci, BATcalcisnotnil, "batcalc.isnotnil");
     127             : }
     128             : 
     129             : static str
     130        1266 : CMDbatNOT(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     131             : {
     132        1266 :         (void) cntxt;
     133        1266 :         (void) mb;
     134             : 
     135        1266 :         return CMDbatUNARY(stk, pci, BATcalcnot, "batcalc.not");
     136             : }
     137             : 
     138             : static str
     139        7822 : CMDbatABS(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     140             : {
     141        7822 :         (void) cntxt;
     142        7822 :         (void) mb;
     143             : 
     144        7822 :         return CMDbatUNARY(stk, pci, BATcalcabsolute, "batcalc.abs");
     145             : }
     146             : 
     147             : static str
     148           0 : CMDbatINCR(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     149             : {
     150           0 :         (void) cntxt;
     151           0 :         (void) mb;
     152             : 
     153           0 :         return CMDbatUNARY1(stk, pci, BATcalcincr, "batcalc.incr");
     154             : }
     155             : 
     156             : static str
     157           0 : CMDbatDECR(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     158             : {
     159           0 :         (void) cntxt;
     160           0 :         (void) mb;
     161             : 
     162           0 :         return CMDbatUNARY1(stk, pci, BATcalcdecr, "batcalc.decr");
     163             : }
     164             : 
     165             : static str
     166         223 : CMDbatNEG(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     167             : {
     168         223 :         (void) cntxt;
     169         223 :         (void) mb;
     170             : 
     171         223 :         return CMDbatUNARY(stk, pci, BATcalcnegate, "batcalc.neg");
     172             : }
     173             : 
     174             : static str
     175           9 : CMDbatSIGN(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     176             : {
     177           9 :         (void) cntxt;
     178           9 :         (void) mb;
     179             : 
     180           9 :         return CMDbatUNARY(stk, pci, BATcalcsign, "batcalc.sign");
     181             : }
     182             : 
     183             : static int
     184           0 : calctype(int tp1, int tp2)
     185             : {
     186           0 :         int tp1s = ATOMbasetype(tp1);
     187           0 :         int tp2s = ATOMbasetype(tp2);
     188           0 :         if (tp1s == TYPE_str && tp2s == TYPE_str)
     189             :                 return TYPE_str;
     190           0 :         if (tp1s < TYPE_flt && tp2s < TYPE_flt) {
     191           0 :                 if (tp1s > tp2s)
     192             :                         return tp1;
     193           0 :                 if (tp1s < tp2s)
     194             :                         return tp2;
     195           0 :                 return MAX(tp1, tp2);
     196             :         }
     197           0 :         if (tp1s == TYPE_dbl || tp2s == TYPE_dbl)
     198             :                 return TYPE_dbl;
     199           0 :         if (tp1s == TYPE_flt || tp2s == TYPE_flt)
     200             :                 return TYPE_flt;
     201             : #ifdef HAVE_HGE
     202           0 :         if (tp1s == TYPE_hge || tp2s == TYPE_hge)
     203           0 :                 return TYPE_hge;
     204             : #endif
     205             :         return TYPE_lng;
     206             : }
     207             : 
     208             : static int
     209           0 : calctypeenlarge(int tp1, int tp2)
     210             : {
     211           0 :         tp1 = calctype(tp1, tp2);
     212           0 :         switch (tp1) {
     213             :         case TYPE_bte:
     214             :                 return TYPE_sht;
     215           0 :         case TYPE_sht:
     216           0 :                 return TYPE_int;
     217           0 :         case TYPE_int:
     218           0 :                 return TYPE_lng;
     219             : #ifdef HAVE_HGE
     220           0 :         case TYPE_lng:
     221           0 :                 return TYPE_hge;
     222             : #endif
     223           0 :         case TYPE_flt:
     224           0 :                 return TYPE_dbl;
     225           0 :         default:
     226             :                 /* we shouldn't get here */
     227           0 :                 return tp1;
     228             :         }
     229             : }
     230             : 
     231             : static int
     232           0 : calcdivtype(int tp1, int tp2)
     233             : {
     234             :         /* if right hand side is floating point, the result is floating
     235             :          * point, otherwise the result has the type of the left hand
     236             :          * side */
     237           0 :         tp1 = ATOMbasetype(tp1);
     238           0 :         tp2 = ATOMbasetype(tp2);
     239           0 :         if (tp1 == TYPE_dbl || tp2 == TYPE_dbl)
     240             :                 return TYPE_dbl;
     241           0 :         if (tp1 == TYPE_flt || tp2 == TYPE_flt)
     242           0 :                 return TYPE_flt;
     243             :         return tp1;
     244             : }
     245             : 
     246             : #if 0
     247             : static int
     248             : calcdivtypeflt(int tp1, int tp2)
     249             : {
     250             :         (void) tp1;
     251             :         (void) tp2;
     252             :         return TYPE_flt;
     253             : }
     254             : 
     255             : static int
     256             : calcdivtypedbl(int tp1, int tp2)
     257             : {
     258             :         (void) tp1;
     259             :         (void) tp2;
     260             :         return TYPE_dbl;
     261             : }
     262             : #endif
     263             : 
     264             : static int
     265           0 : calcmodtype(int tp1, int tp2)
     266             : {
     267           0 :         tp1 = ATOMbasetype(tp1);
     268           0 :         tp2 = ATOMbasetype(tp2);
     269           0 :         assert(tp1 > 0 && tp1 < TYPE_str && tp1 != TYPE_ptr);
     270           0 :         assert(tp2 > 0 && tp2 < TYPE_str && tp2 != TYPE_ptr);
     271           0 :         if (tp1 == TYPE_dbl || tp2 == TYPE_dbl)
     272             :                 return TYPE_dbl;
     273           0 :         if (tp1 == TYPE_flt || tp2 == TYPE_flt)
     274             :                 return TYPE_flt;
     275           0 :         return MIN(tp1, tp2);
     276             : }
     277             : 
     278             : /* MAL function has one of the following signatures:
     279             :  * # without candidate list
     280             :  * func(b1:bat, b2:bat) :bat
     281             :  * func(b1:bat, v2:any) :bat
     282             :  * func(v1:any, b2:bat) :bat
     283             :  * # with candidate list
     284             :  * func(b1:bat, b2:bat, s1:bat, s2:bat) :bat
     285             :  * func(b1:bat, v2:any, s1:bat) :bat
     286             :  * func(v1:any, b2:bat, s2:bat) :bat
     287             :  */
     288             : static str
     289      223386 : CMDbatBINARY2(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
     290             :                           BAT *(*batfunc)(BAT *, BAT *, BAT *, BAT *, int),
     291             :                           BAT * (batfunc1)(BAT *, const ValRecord *, BAT *, int),
     292             :                           BAT * (batfunc2)(const ValRecord *, BAT *, BAT *, int),
     293             :                           int(*typefunc)(int, int), const char *malfunc)
     294             : {
     295      223386 :         bat bid;
     296      223386 :         BAT *bn, *b1 = NULL, *b2 = NULL, *s1 = NULL, *s2 = NULL;
     297      223386 :         int tp1, tp2, tp3;
     298             : 
     299      223386 :         tp1 = getArgType(mb, pci, 1); /*stk->stk[getArg(pci, 1)].vtype;*/    /* first argument */
     300      223386 :         tp2 = getArgType(mb, pci, 2); /*stk->stk[getArg(pci, 2)].vtype;*/    /* second argument */
     301      223386 :         tp3 = getArgType(mb, pci, 0);   /* return argument */
     302      223386 :         assert(isaBatType(tp3));
     303      223386 :         tp3 = getBatType(tp3);
     304             : 
     305      223386 :         if (isaBatType(tp1)) {
     306      222589 :                 bid = *getArgReference_bat(stk, pci, 1);
     307      222589 :                 b1 = BATdescriptor(bid);
     308      223317 :                 if (b1 == NULL)
     309           0 :                         goto bailout;
     310             :         }
     311             : 
     312      224114 :         if (isaBatType(tp2)) {
     313       95920 :                 bid = *getArgReference_bat(stk, pci, 2);
     314       95920 :                 b2 = BATdescriptor(bid);
     315       95926 :                 if (b2 == NULL)
     316           0 :                         goto bailout;
     317             :         }
     318             : 
     319      224120 :         if (pci->argc > 4) {
     320       95089 :                 assert(pci->argc == 5);
     321       95089 :                 bid = *getArgReference_bat(stk, pci, 4);
     322       95089 :                 if (!is_bat_nil(bid)) {
     323        7089 :                         s2 = BATdescriptor(bid);
     324        7088 :                         if (s2 == NULL)
     325           0 :                                 goto bailout;
     326             :                 }
     327             :         }
     328      224119 :         if (pci->argc > 3) {
     329      224136 :                 bid = *getArgReference_bat(stk, pci, 3);
     330      224136 :                 if (!is_bat_nil(bid)) {
     331       47598 :                         s1 = BATdescriptor(bid);
     332       47613 :                         if (s1 == NULL)
     333           0 :                                 goto bailout;
     334       47613 :                         if (b1 == NULL) {
     335          24 :                                 s2 = s1;
     336          24 :                                 s1 = NULL;
     337             :                         }
     338             :                 }
     339             :         }
     340             : 
     341      224134 :         if (b1 && b2) {
     342       95100 :                 if (tp3 == TYPE_any)
     343           0 :                         tp3 = (*typefunc) (b1->ttype, b2->ttype);
     344       95100 :                 bn = (*batfunc) (b1, b2, s1, s2, tp3);
     345      129034 :         } else if (b1) {
     346      128210 :                 if (tp3 == TYPE_any)
     347           0 :                         tp3 = (*typefunc) (b1->ttype, tp2);
     348      128210 :                 bn = (*batfunc1) (b1, &stk->stk[getArg(pci, 2)], s1, tp3);
     349         824 :         } else if (b2) {
     350         824 :                 if (tp3 == TYPE_any)
     351           0 :                         tp3 = (*typefunc) (tp1, b2->ttype);
     352         824 :                 bn = (*batfunc2) (&stk->stk[getArg(pci, 1)], b2, s2, tp3);
     353             :         } else
     354           0 :                 goto bailout;                   /* cannot happen */
     355      223101 :         BBPreclaim(b1);
     356      223842 :         BBPreclaim(b2);
     357      223767 :         BBPreclaim(s1);
     358      223387 :         BBPreclaim(s2);
     359      223968 :         if (bn == NULL)
     360           7 :                 return mythrow(MAL, malfunc, GDK_EXCEPTION);
     361      223961 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
     362      223961 :         BBPkeepref(bn);
     363      223961 :         return MAL_SUCCEED;
     364             : 
     365           0 :   bailout:
     366           0 :         BBPreclaim(b1);
     367           0 :         BBPreclaim(b2);
     368             : /* cannot happen
     369             :         BBPreclaim(s1);
     370             : */
     371           0 :         BBPreclaim(s2);
     372           0 :         throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     373             : }
     374             : 
     375             : /* MAL function has one of the signatures for CMDbatBINARY2, or one of
     376             :  * the following:
     377             :  * # without candidate list
     378             :  * func(b1:bat, b2:bat) :bat
     379             :  * func(b1:bat, v2:any) :bat
     380             :  * func(v1:any, b2:bat) :bat
     381             :  * # with candidate list
     382             :  * func(b1:bat, b2:bat, s1:bat, s2:bat) :bat
     383             :  * func(b1:bat, v2:any, s1:bat) :bat
     384             :  * func(v1:any, b2:bat, s2:bat) :bat
     385             :  */
     386             : static str
     387         147 : CMDbatBINARY1(MalStkPtr stk, InstrPtr pci,
     388             :                           BAT *(*batfunc)(BAT *, BAT *, BAT *, BAT *),
     389             :                           BAT * (*batfunc1)(BAT *, const ValRecord *, BAT *),
     390             :                           BAT * (*batfunc2)(const ValRecord *, BAT *, BAT *),
     391             :                           const char *malfunc)
     392             : {
     393         147 :         bat bid;
     394         147 :         BAT *bn, *b1 = NULL, *b2 = NULL, *s1 = NULL, *s2 = NULL;
     395             : 
     396         147 :         if (stk->stk[getArg(pci, 1)].bat) {
     397         146 :                 bid = *getArgReference_bat(stk, pci, 1);
     398         146 :                 b1 = BATdescriptor(bid);
     399         146 :                 if (b1 == NULL)
     400           0 :                         goto bailout;
     401             :         }
     402             : 
     403         147 :         if (stk->stk[getArg(pci, 2)].bat) {
     404          19 :                 bid = *getArgReference_bat(stk, pci, 2);
     405          19 :                 b2 = BATdescriptor(bid);
     406          19 :                 if (b2 == NULL)
     407           0 :                         goto bailout;
     408             :         }
     409             : 
     410         147 :         if (pci->argc > 4) {
     411           0 :                 assert(pci->argc == 5);
     412           0 :                 bid = *getArgReference_bat(stk, pci, 4);
     413           0 :                 if (!is_bat_nil(bid)) {
     414           0 :                         s2 = BATdescriptor(bid);
     415           0 :                         if (s2 == NULL)
     416           0 :                                 goto bailout;
     417             :                 }
     418             :         }
     419         147 :         if (pci->argc > 3) {
     420           1 :                 bid = *getArgReference_bat(stk, pci, 3);
     421           1 :                 if (!is_bat_nil(bid)) {
     422           0 :                         s1 = BATdescriptor(bid);
     423           0 :                         if (s1 == NULL)
     424           0 :                                 goto bailout;
     425           0 :                         if (b1 == NULL) {
     426           0 :                                 s2 = s1;
     427           0 :                                 s1 = NULL;
     428             :                         }
     429             :                 }
     430             :         }
     431             : 
     432         147 :         if (b1 && b2)
     433          18 :                 bn = (*batfunc) (b1, b2, s1, s2);
     434         129 :         else if (b1)
     435         128 :                 bn = (*batfunc1) (b1, &stk->stk[getArg(pci, 2)], s1);
     436           1 :         else if (b2)
     437           1 :                 bn = (*batfunc2) (&stk->stk[getArg(pci, 1)], b2, s2);
     438             :         else
     439           0 :                 goto bailout;                   /* cannot happen */
     440         147 :         BBPreclaim(b1);
     441         147 :         BBPreclaim(b2);
     442         147 :         BBPreclaim(s1);
     443         147 :         BBPreclaim(s2);
     444         147 :         if (bn == NULL)
     445           0 :                 return mythrow(MAL, malfunc, GDK_EXCEPTION);
     446         147 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
     447         147 :         BBPkeepref(bn);
     448         147 :         return MAL_SUCCEED;
     449             : 
     450           0 :   bailout:
     451           0 :         BBPreclaim(b1);
     452           0 :         BBPreclaim(b2);
     453             : /* cannot happen
     454             :         BBPreclaim(s1);
     455             : */
     456           0 :         BBPreclaim(s2);
     457           0 :         throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     458             : }
     459             : 
     460             : /* MAL function has one of the signatures for CMDbatBINARY2, or one of
     461             :  * the following:
     462             :  * # without candidate list
     463             :  * func(b1:bat, b2:bat, nil_matches:bit) :bat
     464             :  * func(b1:bat, v2:any, nil_matches:bit) :bat
     465             :  * func(v1:any, b2:bat, nil_matches:bit) :bat
     466             :  * # with candidate list
     467             :  * func(b1:bat, b2:bat, s1:bat, s2:bat, nil_matches:bit) :bat
     468             :  * func(b1:bat, v2:any, s1:bat, nil_matches:bit) :bat
     469             :  * func(v1:any, b2:bat, s2:bat, nil_matches:bit) :bat
     470             :  */
     471             : static str
     472       62382 : CMDbatBINARY1a(MalStkPtr stk, InstrPtr pci,
     473             :                            BAT *(*batfunc)(BAT *, BAT *, BAT *, BAT *, bool),
     474             :                            BAT * (*batfunc1)(BAT *, const ValRecord *, BAT *, bool),
     475             :                            BAT * (*batfunc2)(const ValRecord *, BAT *, BAT *, bool),
     476             :                            bool nil_matches, const char *malfunc)
     477             : {
     478       62382 :         bat bid;
     479       62382 :         BAT *bn, *b1 = NULL, *b2 = NULL, *s1 = NULL, *s2 = NULL;
     480             : 
     481       62382 :         if (stk->stk[getArg(pci, 1)].bat) {
     482       62116 :                 bid = *getArgReference_bat(stk, pci, 1);
     483       62116 :                 b1 = BATdescriptor(bid);
     484       62419 :                 if (b1 == NULL)
     485           0 :                         goto bailout;
     486             :         }
     487             : 
     488       62685 :         if (stk->stk[getArg(pci, 2)].bat) {
     489       51961 :                 bid = *getArgReference_bat(stk, pci, 2);
     490       51961 :                 b2 = BATdescriptor(bid);
     491       51956 :                 if (b2 == NULL)
     492           0 :                         goto bailout;
     493             :         }
     494             : 
     495       62680 :         if (pci->argc > 5) {
     496           0 :                 assert(pci->argc == 6);
     497           0 :                 nil_matches = *getArgReference_bit(stk, pci, 5);
     498             :         }
     499       62680 :         if (pci->argc > 4) {
     500         626 :                 if (stk->stk[getArg(pci, 4)].bat) {
     501         626 :                         bid = *getArgReference_bat(stk, pci, 4);
     502         626 :                         if (!is_bat_nil(bid)) {
     503         151 :                                 s2 = BATdescriptor(bid);
     504         152 :                                 if (s2 == NULL)
     505           0 :                                         goto bailout;
     506             :                         }
     507             :                 } else {
     508           0 :                         assert(pci->argc == 5);
     509           0 :                         nil_matches = *getArgReference_bit(stk, pci, 4);
     510             :                 }
     511             :         }
     512       62681 :         if (pci->argc > 3) {
     513       19985 :                 if (stk->stk[getArg(pci, 3)].bat) {
     514        6800 :                         bid = *getArgReference_bat(stk, pci, 3);
     515        6800 :                         if (!is_bat_nil(bid)) {
     516        6327 :                                 s1 = BATdescriptor(bid);
     517        6332 :                                 if (s1 == NULL)
     518           0 :                                         goto bailout;
     519        6332 :                                 if (b1 == NULL) {
     520          79 :                                         s2 = s1;
     521          79 :                                         s1 = NULL;
     522             :                                 }
     523             :                         }
     524             :                 } else {
     525       13185 :                         assert(pci->argc == 4);
     526       13185 :                         nil_matches = *getArgReference_bit(stk, pci, 3);
     527             :                 }
     528             :         }
     529             : 
     530       62686 :         if (b1 && b2)
     531       51663 :                 bn = (*batfunc) (b1, b2, s1, s2, nil_matches);
     532       11023 :         else if (b1)
     533       10739 :                 bn = (*batfunc1) (b1, &stk->stk[getArg(pci, 2)], s1, nil_matches);
     534         284 :         else if (b2)
     535         284 :                 bn = (*batfunc2) (&stk->stk[getArg(pci, 1)], b2, s2, nil_matches);
     536             :         else
     537           0 :                 goto bailout;                   /* cannot happen */
     538       62500 :         BBPreclaim(b1);
     539       62611 :         BBPreclaim(b2);
     540       62595 :         BBPreclaim(s1);
     541       62525 :         BBPreclaim(s2);
     542       62644 :         if (bn == NULL)
     543           0 :                 return mythrow(MAL, malfunc, GDK_EXCEPTION);
     544       62644 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
     545       62644 :         BBPkeepref(bn);
     546       62644 :         return MAL_SUCCEED;
     547             : 
     548           0 :   bailout:
     549           0 :         BBPreclaim(b1);
     550           0 :         BBPreclaim(b2);
     551             : /* cannot happen
     552             :         BBPreclaim(s1);
     553             : */
     554           0 :         BBPreclaim(s2);
     555           0 :         throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     556             : }
     557             : 
     558             : /* MAL function has one of the signatures for CMDbatBINARY2
     559             :  */
     560             : static str
     561       74706 : CMDbatBINARY0(MalStkPtr stk, InstrPtr pci,
     562             :                           BAT *(*batfunc)(BAT *, BAT *, BAT *, BAT *),
     563             :                           BAT * (*batfunc1)(BAT *, const ValRecord *, BAT *),
     564             :                           BAT * (*batfunc2)(const ValRecord *, BAT *, BAT *),
     565             :                           const char *malfunc)
     566             : {
     567       74706 :         bat bid;
     568       74706 :         BAT *bn, *b1 = NULL, *b2 = NULL, *s1 = NULL, *s2 = NULL;
     569             : 
     570       74706 :         if (stk->stk[getArg(pci, 1)].bat) {
     571       74624 :                 bid = *getArgReference_bat(stk, pci, 1);
     572       74624 :                 b1 = BATdescriptor(bid);
     573       75040 :                 if (b1 == NULL)
     574           0 :                         goto bailout;
     575             :         }
     576             : 
     577       75122 :         if (stk->stk[getArg(pci, 2)].bat) {
     578       72762 :                 bid = *getArgReference_bat(stk, pci, 2);
     579       72762 :                 b2 = BATdescriptor(bid);
     580       72772 :                 if (b2 == NULL)
     581           0 :                         goto bailout;
     582             :         }
     583             : 
     584       75132 :         if (pci->argc > 4) {
     585       18943 :                 assert(pci->argc == 5);
     586       18943 :                 bid = *getArgReference_bat(stk, pci, 4);
     587       18943 :                 if (!is_bat_nil(bid)) {
     588        4319 :                         s2 = BATdescriptor(bid);
     589        4318 :                         if (s2 == NULL)
     590           0 :                                 goto bailout;
     591             :                 }
     592             :         }
     593       75131 :         if (pci->argc > 3) {
     594       19516 :                 bid = *getArgReference_bat(stk, pci, 3);
     595       19516 :                 if (!is_bat_nil(bid)) {
     596       15147 :                         s1 = BATdescriptor(bid);
     597       15150 :                         if (s1 == NULL)
     598           0 :                                 goto bailout;
     599       15150 :                         if (b1 == NULL) {
     600           1 :                                 s2 = s1;
     601           1 :                                 s1 = NULL;
     602             :                         }
     603             :                 }
     604             :         }
     605             : 
     606       75134 :         if (b1 && b2)
     607       72602 :                 bn = (*batfunc) (b1, b2, s1, s2);
     608        2532 :         else if (b1)
     609        2402 :                 bn = (*batfunc1) (b1, &stk->stk[getArg(pci, 2)], s1);
     610         130 :         else if (b2)
     611         130 :                 bn = (*batfunc2) (&stk->stk[getArg(pci, 1)], b2, s2);
     612             :         else
     613           0 :                 goto bailout;                   /* cannot happen */
     614       74760 :         BBPreclaim(b1);
     615       75034 :         BBPreclaim(b2);
     616       74990 :         BBPreclaim(s1);
     617       75021 :         BBPreclaim(s2);
     618       74950 :         if (bn == NULL)
     619           2 :                 return mythrow(MAL, malfunc, GDK_EXCEPTION);
     620       74948 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
     621       74948 :         BBPkeepref(bn);
     622       74948 :         return MAL_SUCCEED;
     623             : 
     624           0 :   bailout:
     625           0 :         BBPreclaim(b1);
     626           0 :         BBPreclaim(b2);
     627             : /* cannot happen
     628             :         BBPreclaim(s1);
     629             : */
     630           0 :         BBPreclaim(s2);
     631           0 :         throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     632             : }
     633             : 
     634             : static str
     635         390 : CMDbatMIN(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     636             : {
     637         390 :         (void) cntxt;
     638         390 :         (void) mb;
     639             : 
     640         390 :         return CMDbatBINARY0(stk, pci, BATcalcmin, BATcalcmincst, BATcalccstmin,
     641             :                                                  "batcalc.min");
     642             : }
     643             : 
     644             : static str
     645         127 : CMDbatMIN_no_nil(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     646             : {
     647         127 :         (void) cntxt;
     648         127 :         (void) mb;
     649             : 
     650         127 :         return CMDbatBINARY0(stk, pci, BATcalcmin_no_nil, BATcalcmincst_no_nil,
     651             :                                                  BATcalccstmin_no_nil, "batcalc.min_no_nil");
     652             : }
     653             : 
     654             : static str
     655          13 : CMDbatMAX(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     656             : {
     657          13 :         (void) cntxt;
     658          13 :         (void) mb;
     659             : 
     660          13 :         return CMDbatBINARY0(stk, pci, BATcalcmax, BATcalcmaxcst, BATcalccstmax,
     661             :                                                  "batcalc.max");
     662             : }
     663             : 
     664             : static str
     665          18 : CMDbatMAX_no_nil(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     666             : {
     667          18 :         (void) cntxt;
     668          18 :         (void) mb;
     669             : 
     670          18 :         return CMDbatBINARY0(stk, pci, BATcalcmax_no_nil, BATcalcmaxcst_no_nil,
     671             :                                                  BATcalccstmax_no_nil, "batcalc.max_no_nil");
     672             : }
     673             : 
     674             : static str
     675      102998 : CMDbatADDsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     676             : {
     677      102998 :         (void) cntxt;
     678             : 
     679      102998 :         return CMDbatBINARY2(mb, stk, pci, BATcalcadd, BATcalcaddcst, BATcalccstadd,
     680             :                                                  calctype, "batcalc.+");
     681             : }
     682             : 
     683             : static str
     684       22399 : CMDbatADDenlarge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     685             : {
     686       22399 :         (void) cntxt;
     687             : 
     688       22399 :         return CMDbatBINARY2(mb, stk, pci, BATcalcadd, BATcalcaddcst, BATcalccstadd,
     689             :                                                  calctypeenlarge, "batcalc.add_enlarge");
     690             : }
     691             : 
     692             : static str
     693       22761 : CMDbatSUBsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     694             : {
     695       22761 :         (void) cntxt;
     696             : 
     697       22761 :         return CMDbatBINARY2(mb, stk, pci, BATcalcsub, BATcalcsubcst, BATcalccstsub,
     698             :                                                  calctype, "batcalc.-");
     699             : }
     700             : 
     701             : static str
     702       25597 : CMDbatSUBenlarge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     703             : {
     704       25597 :         (void) cntxt;
     705             : 
     706       25597 :         return CMDbatBINARY2(mb, stk, pci, BATcalcsub, BATcalcsubcst, BATcalccstsub,
     707             :                                                  calctypeenlarge, "batcalc.sub_enlarge");
     708             : }
     709             : 
     710             : static str
     711       30583 : CMDbatMULsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     712             : {
     713       30583 :         (void) cntxt;
     714             : 
     715       30583 :         return CMDbatBINARY2(mb, stk, pci, BATcalcmul, BATcalcmulcst, BATcalccstmul,
     716             :                                                  calctype, "batcalc.*");
     717             : }
     718             : 
     719             : static str
     720       13930 : CMDbatMULenlarge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     721             : {
     722       13930 :         (void) cntxt;
     723             : 
     724       13930 :         return CMDbatBINARY2(mb, stk, pci, BATcalcmul, BATcalcmulcst, BATcalccstmul,
     725             :                                                  calctypeenlarge, "batcalc.mul_enlarge");
     726             : }
     727             : 
     728             : static str
     729        5007 : CMDbatDIVsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     730             : {
     731        5007 :         (void) cntxt;
     732             : 
     733        5007 :         return CMDbatBINARY2(mb, stk, pci, BATcalcdiv, BATcalcdivcst, BATcalccstdiv,
     734             :                                                  calcdivtype, "batcalc./");
     735             : }
     736             : 
     737             : static str
     738         594 : CMDbatMODsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     739             : {
     740         594 :         (void) cntxt;
     741             : 
     742         594 :         return CMDbatBINARY2(mb, stk, pci, BATcalcmod, BATcalcmodcst, BATcalccstmod,
     743             :                                                  calcmodtype, "batcalc.%");
     744             : }
     745             : 
     746             : static str
     747          18 : CMDbatXOR(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     748             : {
     749          18 :         (void) cntxt;
     750          18 :         (void) mb;
     751             : 
     752          18 :         return CMDbatBINARY0(stk, pci, BATcalcxor, BATcalcxorcst, BATcalccstxor,
     753             :                                                  "batcalc.xor");
     754             : }
     755             : 
     756             : static str
     757        2430 : CMDbatOR(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     758             : {
     759        2430 :         (void) cntxt;
     760        2430 :         (void) mb;
     761             : 
     762        2430 :         return CMDbatBINARY0(stk, pci, BATcalcor, BATcalcorcst, BATcalccstor,
     763             :                                                  "batcalc.or");
     764             : }
     765             : 
     766             : static str
     767        3000 : CMDbatAND(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     768             : {
     769        3000 :         (void) cntxt;
     770        3000 :         (void) mb;
     771             : 
     772        3000 :         return CMDbatBINARY0(stk, pci, BATcalcand, BATcalcandcst, BATcalccstand,
     773             :                                                  "batcalc.and");
     774             : }
     775             : 
     776             : static str
     777          19 : CMDbatLSHsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     778             : {
     779          19 :         (void) cntxt;
     780          19 :         (void) mb;
     781             : 
     782          19 :         return CMDbatBINARY1(stk, pci, BATcalclsh, BATcalclshcst, BATcalccstlsh,
     783             :                                                  "batcalc.<<");
     784             : }
     785             : 
     786             : static str
     787         128 : CMDbatRSHsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     788             : {
     789         128 :         (void) cntxt;
     790         128 :         (void) mb;
     791             : 
     792         128 :         return CMDbatBINARY1(stk, pci, BATcalcrsh, BATcalcrshcst, BATcalccstrsh,
     793             :                                                  "batcalc.>>");
     794             : }
     795             : 
     796             : static str
     797       15303 : CMDbatLT(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     798             : {
     799       15303 :         (void) cntxt;
     800       15303 :         (void) mb;
     801             : 
     802       15303 :         return CMDbatBINARY0(stk, pci, BATcalclt, BATcalcltcst, BATcalccstlt,
     803             :                                                  "batcalc.<");
     804             : }
     805             : 
     806             : static str
     807       10062 : CMDbatLE(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     808             : {
     809       10062 :         (void) cntxt;
     810       10062 :         (void) mb;
     811             : 
     812       10062 :         return CMDbatBINARY0(stk, pci, BATcalcle, BATcalclecst, BATcalccstle,
     813             :                                                  "batcalc.<=");
     814             : }
     815             : 
     816             : static str
     817       37676 : CMDbatGT(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     818             : {
     819       37676 :         (void) cntxt;
     820       37676 :         (void) mb;
     821             : 
     822       37676 :         return CMDbatBINARY0(stk, pci, BATcalcgt, BATcalcgtcst, BATcalccstgt,
     823             :                                                  "batcalc.>");
     824             : }
     825             : 
     826             : static str
     827        5907 : CMDbatGE(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     828             : {
     829        5907 :         (void) cntxt;
     830        5907 :         (void) mb;
     831             : 
     832        5907 :         return CMDbatBINARY0(stk, pci, BATcalcge, BATcalcgecst, BATcalccstge,
     833             :                                                  "batcalc.>=");
     834             : }
     835             : 
     836             : static str
     837       60577 : CMDbatEQ(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     838             : {
     839       60577 :         (void) cntxt;
     840       60577 :         (void) mb;
     841             : 
     842       60577 :         return CMDbatBINARY1a(stk, pci, BATcalceq, BATcalceqcst, BATcalccsteq,
     843             :                                                   false, "batcalc.==");
     844             : }
     845             : 
     846             : static str
     847        1864 : CMDbatNE(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     848             : {
     849        1864 :         (void) cntxt;
     850        1864 :         (void) mb;
     851             : 
     852        1864 :         return CMDbatBINARY1a(stk, pci, BATcalcne, BATcalcnecst, BATcalccstne,
     853             :                                                   false, "batcalc.!=");
     854             : }
     855             : 
     856             : static str
     857           0 : CMDbatCMP(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     858             : {
     859           0 :         (void) cntxt;
     860           0 :         (void) mb;
     861             : 
     862           0 :         return CMDbatBINARY0(stk, pci, BATcalccmp, BATcalccmpcst, BATcalccstcmp,
     863             :                                                  "batcalc.cmp");
     864             : }
     865             : 
     866             : static str
     867       25361 : CMDbatBETWEEN(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     868             : {
     869       25361 :         bat bid;
     870       25361 :         BAT *bn, *b = NULL, *lo = NULL, *hi = NULL, *s = NULL, *slo = NULL,
     871       25361 :                 *shi = NULL;
     872       25361 :         int tp1, tp2, tp3, tp;
     873       25361 :         int bc = 0;                                     /* number of extra BAT arguments */
     874       25361 :         bool symmetric, linc, hinc, nils_false, anti, has_cand = false;
     875             : 
     876       25361 :         (void) cntxt;
     877       25361 :         (void) mb;
     878             : 
     879       25361 :         tp1 = getArgType(mb, pci, 1);
     880       25361 :         tp2 = getArgType(mb, pci, 2);
     881       25361 :         tp3 = getArgType(mb, pci, 3);
     882       25361 :         if (!isaBatType(tp1))
     883           0 :                 goto bailout;
     884       25361 :         bid = *getArgReference_bat(stk, pci, 1);
     885       25361 :         b = BATdescriptor(bid);
     886       25363 :         if (b == NULL)
     887           0 :                 goto bailout;
     888       25363 :         if (isaBatType(tp2)) {
     889       25169 :                 bid = *getArgReference_bat(stk, pci, 2);
     890       25169 :                 lo = BATdescriptor(bid);
     891       25188 :                 if (lo == NULL)
     892           0 :                         goto bailout;
     893             :         }
     894       25382 :         if (isaBatType(tp3)) {
     895       25177 :                 bid = *getArgReference_bat(stk, pci, 3);
     896       25177 :                 hi = BATdescriptor(bid);
     897       25175 :                 if (hi == NULL)
     898           0 :                         goto bailout;
     899             :         }
     900       25380 :         tp = getArgType(mb, pci, 4);
     901       25380 :         if (isaBatType(tp)) {
     902       10981 :                 bid = *getArgReference_bat(stk, pci, 4);
     903       10981 :                 has_cand = true;
     904       10981 :                 if (!is_bat_nil(bid)) {
     905        1388 :                         s = BATdescriptor(bid);
     906        1388 :                         if (s == NULL)
     907           0 :                                 goto bailout;
     908             :                 }
     909             :                 bc++;
     910             :         }
     911       25380 :         if (has_cand && lo) {
     912       10844 :                 tp = getArgType(mb, pci, 4 + bc);
     913       10844 :                 if (isaBatType(tp)) {
     914       10844 :                         bid = *getArgReference_bat(stk, pci, 4 + bc);
     915       10844 :                         if (!is_bat_nil(bid)) {
     916        1258 :                                 slo = BATdescriptor(bid);
     917        1261 :                                 if (slo == NULL)
     918           0 :                                         goto bailout;
     919             :                         }
     920       10847 :                         bc++;
     921             :                 } else {
     922           0 :                         if (s == NULL) {
     923             :                                 /* apparently the extra bat was a NIL conditional
     924             :                                  * execution bat */
     925             :                                 has_cand = false;
     926             :                         } else
     927           0 :                                 goto bailout;
     928             :                 }
     929             :         }
     930       25383 :         if (has_cand && hi) {
     931       10814 :                 tp = getArgType(mb, pci, 4 + bc);
     932       10814 :                 if (!isaBatType(tp))
     933           0 :                         goto bailout;
     934       10814 :                 bid = *getArgReference_bat(stk, pci, 4 + bc);
     935       10814 :                 if (!is_bat_nil(bid)) {
     936         546 :                         shi = BATdescriptor(bid);
     937         546 :                         if (shi == NULL)
     938           0 :                                 goto bailout;
     939             :                 }
     940       10814 :                 bc++;
     941             :         }
     942             : 
     943       25383 :         symmetric = *getArgReference_bit(stk, pci, bc + 4);
     944       25383 :         linc = *getArgReference_bit(stk, pci, bc + 5);
     945       25383 :         hinc = *getArgReference_bit(stk, pci, bc + 6);
     946       25383 :         nils_false = *getArgReference_bit(stk, pci, bc + 7);
     947       25383 :         anti = *getArgReference_bit(stk, pci, bc + 8);
     948             : 
     949       25383 :         if (b && lo && hi)
     950       25076 :                 bn = BATcalcbetween(b, lo, hi, s, slo, shi,
     951             :                                                         symmetric, linc, hinc, nils_false, anti);
     952         307 :         else if (b && lo)
     953          59 :                 bn = BATcalcbetweenbatcst(b, lo, &stk->stk[getArg(pci, 3)], s, slo,
     954             :                                                                   symmetric, linc, hinc, nils_false, anti);
     955         248 :         else if (b && hi)
     956          48 :                 bn = BATcalcbetweencstbat(b, &stk->stk[getArg(pci, 2)], hi, s, shi,
     957             :                                                                   symmetric, linc, hinc, nils_false, anti);
     958             :         else
     959         200 :                 bn = BATcalcbetweencstcst(b, &stk->stk[getArg(pci, 2)],
     960         200 :                                                                   &stk->stk[getArg(pci, 3)], s,
     961             :                                                                   symmetric, linc, hinc, nils_false, anti);
     962       25263 :         BBPunfix(b->batCacheid);
     963       25363 :         BBPreclaim(lo);
     964       25386 :         BBPreclaim(hi);
     965       25390 :         BBPreclaim(s);
     966       25391 :         BBPreclaim(slo);
     967       25361 :         BBPreclaim(shi);
     968       25411 :         if (bn == NULL)
     969           0 :                 return mythrow(MAL, "batcalc.between", OPERATION_FAILED);
     970       25411 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
     971       25411 :         BBPkeepref(bn);
     972       25411 :         return MAL_SUCCEED;
     973             : 
     974           0 :   bailout:
     975           0 :         BBPreclaim(b);
     976           0 :         BBPreclaim(lo);
     977           0 :         BBPreclaim(hi);
     978           0 :         BBPreclaim(s);
     979           0 :         BBPreclaim(slo);
     980             : /* cannot happen
     981             :         BBPreclaim(shi);
     982             : */
     983           0 :         throw(MAL, "batcalc.between", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     984             : }
     985             : 
     986             : static str
     987        7852 : CMDcalcavg(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     988             : {
     989        7852 :         dbl avg;
     990        7852 :         BUN vals;
     991        7852 :         bat bid;
     992        7852 :         BAT *b, *s = NULL;
     993        7852 :         gdk_return ret;
     994        7852 :         int scale = 0;
     995             : 
     996        7852 :         (void) cntxt;
     997        7852 :         (void) mb;
     998             : 
     999        7852 :         bid = *getArgReference_bat(stk, pci, pci->retc + 0);
    1000        7852 :         if ((b = BATdescriptor(bid)) == NULL)
    1001           0 :                 throw(MAL, "aggr.avg", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1002        7854 :         if ((pci->argc == pci->retc + 2 &&
    1003           0 :                  stk->stk[pci->argv[pci->retc + 1]].bat) ||
    1004        7854 :                 pci->argc == pci->retc + 3) {
    1005           0 :                 bid = *getArgReference_bat(stk, pci, pci->retc + 1);
    1006           0 :                 if (!is_bat_nil(bid) && (s = BATdescriptor(bid)) == NULL) {
    1007           0 :                         BBPunfix(b->batCacheid);
    1008           0 :                         throw(MAL, "aggr.avg", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1009             :                 }
    1010             :         }
    1011        7854 :         if (pci->argc >= pci->retc + 2 &&
    1012           0 :                 stk->stk[pci->argv[pci->argc - 1]].vtype == TYPE_int) {
    1013           0 :                 scale = *getArgReference_int(stk, pci, pci->argc - 1);
    1014             :         }
    1015        7854 :         ret = BATcalcavg(b, s, &avg, &vals, scale);
    1016        7845 :         BBPunfix(b->batCacheid);
    1017        7852 :         BBPreclaim(s);
    1018        7853 :         if (ret != GDK_SUCCEED)
    1019           0 :                 return mythrow(MAL, "aggr.avg", OPERATION_FAILED);
    1020        7853 :         *getArgReference_dbl(stk, pci, 0) = avg;
    1021        7853 :         if (pci->retc == 2)
    1022        7810 :                 *getArgReference_lng(stk, pci, 1) = vals;
    1023             :         return MAL_SUCCEED;
    1024             : }
    1025             : 
    1026             : static str
    1027       69451 : CMDconvertbat(MalStkPtr stk, InstrPtr pci, int tp)
    1028             : {
    1029       69451 :         bat bid;
    1030       69451 :         BAT *b, *bn, *s = NULL;
    1031             : 
    1032       69451 :         bid = *getArgReference_bat(stk, pci, 1);
    1033       69451 :         if ((b = BATdescriptor(bid)) == NULL)
    1034           0 :                 throw(MAL, "batcalc.convert", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1035       69550 :         if (pci->argc == 3) {
    1036       68499 :                 bid = *getArgReference_bat(stk, pci, 2);
    1037       68499 :                 if (!is_bat_nil(bid) && (s = BATdescriptor(bid)) == NULL) {
    1038           0 :                         BBPunfix(b->batCacheid);
    1039           0 :                         throw(MAL, "batcalc.convert",
    1040             :                                   SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1041             :                 }
    1042       11397 :                 if (s && ATOMtype(s->ttype) != TYPE_oid) {
    1043           0 :                         BBPunfix(b->batCacheid);
    1044           0 :                         BBPreclaim(s);
    1045           0 :                         throw(MAL, "batcalc.convert", SQLSTATE(42000) ILLEGAL_ARGUMENT);
    1046             :                 }
    1047             :         }
    1048             : 
    1049       69548 :         bn = BATconvert(b, s, tp, 0, 0, 0);
    1050       69309 :         BBPunfix(b->batCacheid);
    1051       69481 :         BBPreclaim(s);
    1052       69493 :         if (bn == NULL) {
    1053          12 :                 char buf[20];
    1054          12 :                 snprintf(buf, sizeof(buf), "batcalc.%s", ATOMname(tp));
    1055          12 :                 return mythrow(MAL, buf, OPERATION_FAILED);
    1056             :         }
    1057       69481 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
    1058       69481 :         BBPkeepref(bn);
    1059       69481 :         return MAL_SUCCEED;
    1060             : }
    1061             : 
    1062             : static str
    1063         119 : CMDconvertsignal_bit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1064             : {
    1065         119 :         (void) cntxt;
    1066         119 :         (void) mb;
    1067             : 
    1068         119 :         return CMDconvertbat(stk, pci, TYPE_bit);
    1069             : }
    1070             : 
    1071             : static str
    1072         130 : CMDconvertsignal_bte(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1073             : {
    1074         130 :         (void) cntxt;
    1075         130 :         (void) mb;
    1076             : 
    1077         130 :         return CMDconvertbat(stk, pci, TYPE_bte);
    1078             : }
    1079             : 
    1080             : static str
    1081        1799 : CMDconvertsignal_sht(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1082             : {
    1083        1799 :         (void) cntxt;
    1084        1799 :         (void) mb;
    1085             : 
    1086        1799 :         return CMDconvertbat(stk, pci, TYPE_sht);
    1087             : }
    1088             : 
    1089             : static str
    1090        5046 : CMDconvertsignal_int(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1091             : {
    1092        5046 :         (void) cntxt;
    1093        5046 :         (void) mb;
    1094             : 
    1095        5046 :         return CMDconvertbat(stk, pci, TYPE_int);
    1096             : }
    1097             : 
    1098             : static str
    1099       59386 : CMDconvertsignal_lng(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1100             : {
    1101       59386 :         (void) cntxt;
    1102       59386 :         (void) mb;
    1103             : 
    1104       59386 :         return CMDconvertbat(stk, pci, TYPE_lng);
    1105             : }
    1106             : 
    1107             : #ifdef HAVE_HGE
    1108             : 
    1109             : static str
    1110         159 : CMDconvertsignal_hge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1111             : {
    1112         159 :         (void) cntxt;
    1113         159 :         (void) mb;
    1114             : 
    1115         159 :         return CMDconvertbat(stk, pci, TYPE_hge);
    1116             : }
    1117             : #endif
    1118             : 
    1119             : static str
    1120         160 : CMDconvertsignal_flt(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1121             : {
    1122         160 :         (void) cntxt;
    1123         160 :         (void) mb;
    1124             : 
    1125         160 :         return CMDconvertbat(stk, pci, TYPE_flt);
    1126             : }
    1127             : 
    1128             : static str
    1129        2472 : CMDconvertsignal_dbl(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1130             : {
    1131        2472 :         (void) cntxt;
    1132        2472 :         (void) mb;
    1133             : 
    1134        2472 :         return CMDconvertbat(stk, pci, TYPE_dbl);
    1135             : }
    1136             : 
    1137             : static str
    1138          15 : CMDconvertsignal_oid(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1139             : {
    1140          15 :         (void) cntxt;
    1141          15 :         (void) mb;
    1142             : 
    1143          15 :         return CMDconvertbat(stk, pci, TYPE_oid);
    1144             : }
    1145             : 
    1146             : static str
    1147         176 : CMDconvertsignal_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1148             : {
    1149         176 :         (void) cntxt;
    1150         176 :         (void) mb;
    1151             : 
    1152         176 :         return CMDconvertbat(stk, pci, TYPE_str);
    1153             : }
    1154             : 
    1155             : static str
    1156        4692 : CMDifthen(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1157             : {
    1158        4692 :         BAT *b = NULL, *b1 = NULL, *b2 = NULL, *bn;
    1159        4692 :         int tp0, tp1, tp2;
    1160        4692 :         bat *ret;
    1161        4692 :         BUN cnt = BUN_NONE;
    1162             : 
    1163        4692 :         (void) cntxt;
    1164             : 
    1165        4692 :         if (pci->argc != 4)
    1166           0 :                 throw(MAL, "batcalc.ifthen", "Operation not supported.");
    1167             : 
    1168        4692 :         ret = getArgReference_bat(stk, pci, 0);
    1169        4692 :         tp0 = stk->stk[getArg(pci, 1)].vtype;
    1170        4692 :         tp1 = getArgType(mb, pci, 2);
    1171        4692 :         tp2 = getArgType(mb, pci, 3);
    1172        4692 :         if (stk->stk[getArg(pci, 1)].bat) {
    1173        4698 :                 b = BATdescriptor(*getArgReference_bat(stk, pci, 1));
    1174        4716 :                 if (b == NULL)
    1175           0 :                         throw(MAL, "batcalc.ifthenelse",
    1176             :                                   SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1177        4716 :                 cnt = BATcount(b);
    1178             :         }
    1179        4710 :         if (isaBatType(tp1)) {
    1180         267 :                 b1 = BATdescriptor(*getArgReference_bat(stk, pci, 2));
    1181         267 :                 if (b1 == NULL) {
    1182           0 :                         BBPreclaim(b);
    1183           0 :                         throw(MAL, "batcalc.ifthenelse",
    1184             :                                   SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1185             :                 }
    1186         267 :                 if (cnt == BUN_NONE)
    1187           0 :                         cnt = BATcount(b1);
    1188         267 :                 else if (BATcount(b1) != cnt) {
    1189           0 :                         BBPunfix(b->batCacheid);
    1190           0 :                         throw(MAL, "batcalc.ifthenelse", ILLEGAL_ARGUMENT);
    1191             :                 }
    1192             :         }
    1193        4710 :         if (isaBatType(tp2)) {
    1194        2906 :                 b2 = BATdescriptor(*getArgReference_bat(stk, pci, 3));
    1195        2907 :                 if (b2 == NULL) {
    1196           0 :                         BBPreclaim(b);
    1197           0 :                         BBPreclaim(b1);
    1198           0 :                         throw(MAL, "batcalc.ifthenelse",
    1199             :                                   SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1200             :                 }
    1201        2907 :                 if (cnt == BUN_NONE)
    1202        4711 :                         cnt = BATcount(b2);
    1203        2907 :                 else if (BATcount(b2) != cnt) {
    1204           0 :                         BBPreclaim(b);
    1205           0 :                         BBPreclaim(b1);
    1206           0 :                         throw(MAL, "batcalc.ifthenelse", ILLEGAL_ARGUMENT);
    1207             :                 }
    1208             :         }
    1209        4711 :         if (b == NULL && b1 == NULL && b2 == NULL) {
    1210             :                 /* at least one BAT required */
    1211           0 :                 throw(MAL, "batcalc.ifthenelse", ILLEGAL_ARGUMENT);
    1212             :         }
    1213        4711 :         if (b != NULL) {
    1214        4711 :                 if (b1 != NULL) {
    1215         267 :                         if (b2 != NULL) {
    1216          70 :                                 bn = BATcalcifthenelse(b, b1, b2);
    1217             :                         } else {
    1218         197 :                                 bn = BATcalcifthenelsecst(b, b1, &stk->stk[getArg(pci, 3)]);
    1219             :                         }
    1220             :                 } else {
    1221        4444 :                         if (b2 != NULL) {
    1222        2835 :                                 bn = BATcalcifthencstelse(b, &stk->stk[getArg(pci, 2)], b2);
    1223             :                         } else {
    1224        1609 :                                 bn = BATcalcifthencstelsecst(b, &stk->stk[getArg(pci, 2)],
    1225        1609 :                                                                                          &stk->stk[getArg(pci, 3)]);
    1226             :                         }
    1227             :                 }
    1228             :         } else {
    1229           0 :                 bit v;
    1230           0 :                 if (tp0 == TYPE_msk)
    1231           0 :                         v = (bit) *getArgReference_msk(stk, pci, 1);
    1232             :                 else
    1233           0 :                         v = *getArgReference_bit(stk, pci, 1);
    1234           0 :                 if (is_bit_nil(v)) {
    1235           0 :                         if (b1 != NULL)
    1236           0 :                                 bn = BATconstant(b1->hseqbase, b1->ttype, ATOMnilptr(b1->ttype),
    1237             :                                                                  BATcount(b1), TRANSIENT);
    1238             :                         else
    1239           0 :                                 bn = BATconstant(b2->hseqbase, b2->ttype, ATOMnilptr(b2->ttype),
    1240             :                                                                  BATcount(b2), TRANSIENT);
    1241           0 :                 } else if (v) {
    1242           0 :                         if (b1 != NULL)
    1243           0 :                                 bn = COLcopy(b1, b1->ttype, false, TRANSIENT);
    1244             :                         else
    1245           0 :                                 bn = BATconstant(b2->hseqbase, b2->ttype,
    1246           0 :                                                                  VALptr(&stk->stk[getArg(pci, 2)]),
    1247             :                                                                  BATcount(b2), TRANSIENT);
    1248             :                 } else {
    1249           0 :                         if (b2 != NULL)
    1250           0 :                                 bn = COLcopy(b2, b2->ttype, false, TRANSIENT);
    1251             :                         else
    1252           0 :                                 bn = BATconstant(b1->hseqbase, b1->ttype,
    1253           0 :                                                                  VALptr(&stk->stk[getArg(pci, 3)]),
    1254             :                                                                  BATcount(b1), TRANSIENT);
    1255             :                 }
    1256             :         }
    1257        4686 :         BBPreclaim(b);
    1258        4714 :         BBPreclaim(b1);
    1259        4700 :         BBPreclaim(b2);
    1260        4702 :         if (bn == NULL) {
    1261           0 :                 return mythrow(MAL, "batcalc.ifthenelse", OPERATION_FAILED);
    1262             :         }
    1263        4702 :         *ret = bn->batCacheid;
    1264        4702 :         BBPkeepref(bn);
    1265        4702 :         return MAL_SUCCEED;
    1266             : }
    1267             : 
    1268             : #include "mel.h"
    1269             : 
    1270             : static str
    1271         341 : batcalc_init(void)
    1272             : {
    1273         341 :         int types[16], cur = 0, *tp;
    1274         341 :         int specials[4];
    1275         341 :         int *integer, *floats, *extra;
    1276             : 
    1277         341 :         types[cur++] = TYPE_bit;
    1278         341 :         integer = types+cur;
    1279         341 :         types[cur++] = TYPE_bte;
    1280         341 :         types[cur++] = TYPE_sht;
    1281         341 :         types[cur++] = TYPE_int;
    1282         341 :         types[cur++] = TYPE_lng;
    1283             : #ifdef HAVE_HGE
    1284         341 :         types[cur++] = TYPE_hge;
    1285             : #endif
    1286         341 :         floats = types+cur;
    1287         341 :         types[cur++] = TYPE_flt;
    1288         341 :         types[cur++] = TYPE_dbl;
    1289         341 :         extra = types+cur;
    1290         341 :         types[cur++] = TYPE_oid;
    1291         341 :         types[cur++] = TYPE_str;
    1292             : 
    1293         341 :         cur = 0;
    1294         341 :         specials[cur++] = TYPE_bit;
    1295         341 :         specials[cur++] = TYPE_oid;
    1296         341 :         specials[cur++] = TYPE_str;
    1297             : 
    1298         341 :         mel_func_arg cand = { .type = TYPE_oid, .isbat=1 };
    1299             : 
    1300         341 :         int err=0;
    1301             :         /* for all numeric types, use reverse order */
    1302        2728 :         for(tp = integer; tp < extra && !err; tp++) {
    1303        2387 :                 mel_func_arg ret = { .type = TYPE_bit, .isbat=1 };
    1304        2387 :                 mel_func_arg arg = { .type = *tp, .isbat=1 };
    1305             : 
    1306        2387 :                 err += melFunction(false, "batcalc", "iszero", (MALfcn)&CMDbatISZERO, "CMDbatISZERO", false, "Unary check for zero over the tail of the bat", 1, 2, ret, arg);
    1307        2387 :                 err += melFunction(false, "batcalc", "iszero", (MALfcn)&CMDbatISZERO, "CMDbatISZERO", false, "Unary check for zero over the tail of the bat with candidates list", 1, 3, ret, arg, cand);
    1308             :         }
    1309        3069 :         for(tp = types; tp < extra && !err; tp++) { /* bit + numeric */
    1310        2728 :                 mel_func_arg ret = { .type = *tp, .isbat =1 };
    1311        2728 :                 mel_func_arg arg = { .type = *tp, .isbat =1 };
    1312             : 
    1313        2728 :                 err += melFunction(false, "batcalc", "not", (MALfcn)&CMDbatNOT, "CMDbatNOT", false, "Unary bitwise not over the tail of the bat", 1, 2, ret, arg);
    1314        2728 :                 err += melFunction(false, "batcalc", "not", (MALfcn)&CMDbatNOT, "CMDbatNOT", false, "Unary bitwise not over the tail of the bat with candidates list", 1, 3, ret, arg, cand);
    1315             :         }
    1316        2728 :         for(tp = integer; tp < extra && !err; tp++) {
    1317        2387 :                 mel_func_arg ret = { .type = TYPE_bte, .isbat =1 };
    1318        2387 :                 mel_func_arg arg = { .type = *tp, .isbat =1 };
    1319             : 
    1320        2387 :                 err += melFunction(false, "batcalc", "sign", (MALfcn)&CMDbatSIGN, "CMDbatSIGN", false, "Unary sign (-1,0,1) over the tail of the bat", 1, 2, ret, arg);
    1321        2387 :                 err += melFunction(false, "batcalc", "sign", (MALfcn)&CMDbatSIGN, "CMDbatSIGN", false, "Unary sign (-1,0,1) over the tail of the bat with candidates list", 1, 3, ret, arg, cand);
    1322             :         }
    1323        2728 :         for(tp = integer; tp < extra && !err; tp++) {
    1324        2387 :                 mel_func_arg ret = { .type = *tp, .isbat =1 };
    1325        2387 :                 mel_func_arg arg = { .type = *tp, .isbat =1 };
    1326             : 
    1327        2387 :                 err += melFunction(false, "batcalc", "abs", (MALfcn)&CMDbatABS, "CMDbatABS", false, "Unary abs over the tail of the bat", 1, 2, ret, arg);
    1328        2387 :                 err += melFunction(false, "batcalc", "abs", (MALfcn)&CMDbatABS, "CMDbatABS", false, "Unary abs over the tail of the bat with candidates list", 1, 3, ret, arg, cand);
    1329             : 
    1330        2387 :                 err += melFunction(false, "batcalc", "-", (MALfcn)&CMDbatNEG, "CMDbatNEG", false, "Unary neg over the tail of the bat", 1, 2, ret, arg);
    1331        2387 :                 err += melFunction(false, "batcalc", "-", (MALfcn)&CMDbatNEG, "CMDbatNEG", false, "Unary neg over the tail of the bat with candidates list", 1, 3, ret, arg, cand);
    1332             : 
    1333        2387 :                 err += melFunction(false, "batcalc", "++", (MALfcn)&CMDbatINCR, "CMDbatINCR", false, "Unary increment over the tail of the bat", 1, 2, ret, arg);
    1334        2387 :                 err += melFunction(false, "batcalc", "++", (MALfcn)&CMDbatINCR, "CMDbatINCR", false, "Unary increment over the tail of the bat with candidates list", 1, 3, ret, arg, cand);
    1335             : 
    1336        2387 :                 err += melFunction(false, "batcalc", "--", (MALfcn)&CMDbatDECR, "CMDbatDECR", false, "Unary decrement over the tail of the bat", 1, 2, ret, arg);
    1337        2387 :                 err += melFunction(false, "batcalc", "--", (MALfcn)&CMDbatDECR, "CMDbatDECR", false, "Unary decrement over the tail of the bat with candidates list", 1, 3, ret, arg, cand);
    1338             :         }
    1339             :         /* possibly add the min/max + _no_nil */
    1340             :         /* binops on numeric types */
    1341         341 :         struct {
    1342             :                 char *op;
    1343             :                 char *fname;
    1344             :                 char *fname_el;
    1345             :                 MALfcn fcn;
    1346             :                 MALfcn fcn_el;
    1347             :                 char *comment;
    1348             :                 char *comment_v;
    1349             :                 char *comment_v_;
    1350             :                 char *comment_el;
    1351             :                 char *comment_el_v;
    1352             :                 char *comment_el_v_;
    1353         341 :         } funcs[3] = {
    1354             :                 {
    1355             :                         .op = "+",
    1356             :                         .fcn = (MALfcn)CMDbatADDsignal,
    1357             :                         .fname = "CMDbatADDsignal",
    1358             :                         .fcn_el = (MALfcn)&CMDbatADDenlarge,
    1359             :                         .fname_el = "CMDbatADDenlarge",
    1360             :                         .comment = "Return B1 + B2 with candidates list, signal error on overflow",
    1361             :                         .comment_v = "Return B + V with candidates list, signal error on overflow",
    1362             :                         .comment_v_ = "Return V + B with candidates list, signal error on overflow",
    1363             :                         .comment_el = "Return B1 + B2 with candidates list, guarantee no overflow by returning larger type",
    1364             :                         .comment_el_v = "Return B + V with candidates list, guarantee no overflow by returning larger type",
    1365             :                         .comment_el_v_ = "Return V + B with candidates list, guarantee no overflow by returning larger type",
    1366             :                 }, {
    1367             :                         .op = "-",
    1368             :                         .fcn = (MALfcn)CMDbatSUBsignal,
    1369             :                         .fname = "CMDbatSUBsignal",
    1370             :                         .fcn_el = (MALfcn)&CMDbatSUBenlarge,
    1371             :                         .fname_el = "CMDbatSUBenlarge",
    1372             :                         .comment = "Return B1 - B2 with candidates list, signal error on overflow",
    1373             :                         .comment_v = "Return B - V with candidates list, signal error on overflow",
    1374             :                         .comment_v_ = "Return V - B with candidates list, signal error on overflow",
    1375             :                         .comment_el = "Return B1 - B2 with candidates list, guarantee no overflow by returning larger type",
    1376             :                         .comment_el_v = "Return B - V with candidates list, guarantee no overflow by returning larger type",
    1377             :                         .comment_el_v_ = "Return V - B with candidates list, guarantee no overflow by returning larger type",
    1378             :                 }, {
    1379             :                         .op = "*",
    1380             :                         .fcn = (MALfcn)CMDbatMULsignal,
    1381             :                         .fname = "CMDbatMULsignal",
    1382             :                         .fcn_el = (MALfcn)&CMDbatMULenlarge,
    1383             :                         .fname_el = "CMDbatMULenlarge",
    1384             :                         .comment = "Return B1 * B2 with candidates list, signal error on overflow",
    1385             :                         .comment_v = "Return B * V with candidates list, signal error on overflow",
    1386             :                         .comment_v_ = "Return V * B with candidates list, signal error on overflow",
    1387             :                         .comment_el = "Return B1 * B2 with candidates list, guarantee no overflow by returning larger type",
    1388             :                         .comment_el_v = "Return B * V with candidates list, guarantee no overflow by returning larger type",
    1389             :                         .comment_el_v_ = "Return V * B with candidates list, guarantee no overflow by returning larger type",
    1390             :                 }
    1391             :         };
    1392        1364 :         for (int f=0; f<3; f++) {
    1393             :                 int *tp1, *tp2, *rt;
    1394        8184 :                 for(tp1 = integer; tp1 < extra && !err; tp1++) {
    1395       57288 :                         for(tp2 = integer; tp2 < extra && !err; tp2++) {
    1396      401016 :                                 for(rt = extra-1; rt >= integer && !err; rt--) {
    1397      350889 :                                         if (f!=3 && (*rt < *tp1 || *rt < *tp2))
    1398      207669 :                                                 continue;
    1399      143220 :                                         mel_func_arg ret = { .type = *rt, .isbat =1 };
    1400      143220 :                                         mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1401      143220 :                                         mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1402      143220 :                                         mel_func_arg varg1 = { .type = *tp1 };
    1403      143220 :                                         mel_func_arg varg2 = { .type = *tp2 };
    1404             : 
    1405      143220 :                                         if (*rt == *tp1 || *rt == *tp2 || f==3) {
    1406       50127 :                                                 err += melFunction(false, "batcalc", funcs[f].op, funcs[f].fcn, funcs[f].fname, false, funcs[f].comment, 1, 5, ret, arg1, arg2, cand, cand);
    1407       50127 :                                                 err += melFunction(false, "batcalc", funcs[f].op, funcs[f].fcn, funcs[f].fname, false, funcs[f].comment_v, 1, 4, ret, arg1, varg2, cand);
    1408       50127 :                                                 err += melFunction(false, "batcalc", funcs[f].op, funcs[f].fcn, funcs[f].fname, false, funcs[f].comment_v_, 1, 4, ret, varg1, arg2, cand);
    1409             :                                         } else {
    1410       93093 :                                                 err += melFunction(false, "batcalc", funcs[f].op, funcs[f].fcn_el, funcs[f].fname_el, false, funcs[f].comment_el, 1, 5, ret, arg1, arg2, cand, cand);
    1411       93093 :                                                 err += melFunction(false, "batcalc", funcs[f].op, funcs[f].fcn_el, funcs[f].fname_el, false, funcs[f].comment_el_v, 1, 4, ret, arg1, varg2, cand);
    1412       93093 :                                                 err += melFunction(false, "batcalc", funcs[f].op, funcs[f].fcn_el, funcs[f].fname_el, false, funcs[f].comment_el_v_, 1, 4, ret, varg1, arg2, cand);
    1413             :                                         }
    1414             :                                 }
    1415             :                         }
    1416             :                 }
    1417             :         }
    1418             :         {       /* multiplication between integers and floating-points, returning integers */
    1419             :                 int *tp1, *tp2, *tp3;
    1420        2046 :                 for(tp1 = integer; tp1 < floats && !err; tp1++) {
    1421        5115 :                         for(tp2 = floats; tp2 < extra && !err; tp2++) {
    1422       20460 :                                 for(tp3 = integer; tp3 < floats && !err; tp3++) {
    1423       17050 :                                         int in1 = *tp3, in2 = *tp2;
    1424             : 
    1425       51150 :                                         for (int i = 0 ; i < 2 ; i++) {
    1426       34100 :                                                 mel_func_arg ret = { .type = *tp1, .isbat =1 };
    1427       34100 :                                                 mel_func_arg arg1 = { .type = in1, .isbat =1 };
    1428       34100 :                                                 mel_func_arg arg2 = { .type = in2, .isbat =1 };
    1429       34100 :                                                 mel_func_arg varg1 = { .type = in1 };
    1430       34100 :                                                 mel_func_arg varg2 = { .type = in2 };
    1431             : 
    1432       34100 :                                                 err += melFunction(false, "batcalc", funcs[2].op, funcs[2].fcn, funcs[2].fname, false, funcs[2].comment, 1, 5, ret, arg1, arg2, cand, cand);
    1433       34100 :                                                 err += melFunction(false, "batcalc", funcs[2].op, funcs[2].fcn, funcs[2].fname, false, funcs[2].comment_v, 1, 4, ret, arg1, varg2, cand);
    1434       34100 :                                                 err += melFunction(false, "batcalc", funcs[2].op, funcs[2].fcn, funcs[2].fname, false, funcs[2].comment_v_, 1, 4, ret, varg1, arg2, cand);
    1435             : 
    1436             :                                                 /* swap variables */
    1437       34100 :                                                 in1 ^= in2;
    1438       34100 :                                                 in2 ^= in1;
    1439       34100 :                                                 in1 ^= in2;
    1440             :                                         }
    1441             :                                 }
    1442             :                         }
    1443             :                 }
    1444             :         }
    1445         341 :         struct {
    1446             :                 char *op;
    1447             :                 char *fname;
    1448             :                 char *fname_el;
    1449             :                 MALfcn fcn;
    1450             :                 MALfcn fcn_el;
    1451             :                 char *comment;
    1452             :                 char *comment_v;
    1453             :                 char *comment_v_;
    1454             :                 char *comment_el;
    1455             :                 char *comment_el_v;
    1456             :                 char *comment_el_v_;
    1457         341 :         } div = {
    1458             :                 .op = "/",
    1459             :                 .fcn = (MALfcn)CMDbatDIVsignal,
    1460             :                 .fname = "CMDbatDIVsignal",
    1461             :                 .comment = "Return B1 / B2 with candidates list, signal error on overflow",
    1462             :                 .comment_v = "Return B / V with candidates list, signal error on overflow",
    1463             :                 .comment_v_ = "Return V / B with candidates list, signal error on overflow",
    1464             :         };
    1465         341 :         int *tp1, *tp2, *rt;
    1466        2728 :         for(tp1 = integer; tp1 < extra && !err; tp1++) {
    1467       19096 :             for(tp2 = integer; tp2 < extra && !err; tp2++) {
    1468       83545 :                         for(rt = extra-1; rt >= tp1 && !err; rt--) {
    1469       66836 :                                 mel_func_arg ret = { .type = *rt, .isbat =1 };
    1470       66836 :                                 mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1471       66836 :                                 mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1472       66836 :                                 mel_func_arg varg1 = { .type = *tp1 };
    1473       66836 :                                 mel_func_arg varg2 = { .type = *tp2 };
    1474             : 
    1475       66836 :                                 err += melFunction(false, "batcalc", div.op, div.fcn, div.fname, false, div.comment, 1, 5, ret, arg1, arg2, cand, cand);
    1476       66836 :                                 err += melFunction(false, "batcalc", div.op, div.fcn, div.fname, false, div.comment_v, 1, 4, ret, arg1, varg2, cand);
    1477       66836 :                                 err += melFunction(false, "batcalc", div.op, div.fcn, div.fname, false, div.comment_v_, 1, 4, ret, varg1, arg2, cand);
    1478             :                         }
    1479             :             }
    1480             :         }
    1481             :         /* division between integers and floating-points, returning integers */
    1482        1023 :         for(tp1 = floats; tp1 < extra && !err; tp1++) {
    1483        4092 :             for(tp2 = integer; tp2 < floats && !err; tp2++) {
    1484       20460 :                         for(rt = integer; rt < floats && !err; rt++) {
    1485       17050 :                                 mel_func_arg ret = { .type = *rt, .isbat =1 };
    1486       17050 :                                 mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1487       17050 :                                 mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1488       17050 :                                 mel_func_arg varg1 = { .type = *tp1 };
    1489       17050 :                                 mel_func_arg varg2 = { .type = *tp2 };
    1490             : 
    1491       17050 :                                 err += melFunction(false, "batcalc", div.op, div.fcn, div.fname, false, div.comment, 1, 5, ret, arg1, arg2, cand, cand);
    1492       17050 :                                 err += melFunction(false, "batcalc", div.op, div.fcn, div.fname, false, div.comment_v, 1, 4, ret, arg1, varg2, cand);
    1493       17050 :                                 err += melFunction(false, "batcalc", div.op, div.fcn, div.fname, false, div.comment_v_, 1, 4, ret, varg1, arg2, cand);
    1494             :                         }
    1495             :             }
    1496             :         }
    1497             :         struct {
    1498             :                 char *op;
    1499             :                 char *fname;
    1500             :                 MALfcn fcn;
    1501             :                 char *comment;
    1502             :                 char *comment_v;
    1503             :                 char *comment_v_;
    1504             :         } mods = {
    1505             :                 .op = "%",
    1506             :                 .fcn = (MALfcn)CMDbatMODsignal,
    1507             :                 .fname = "CMDbatMODsignal",
    1508             :                 .comment = "Return B1 % B2 with candidates list, signal error on overflow",
    1509             :                 .comment_v = "Return B % V with candidates list, signal error on overflow",
    1510             :                 .comment_v_ = "Return V % B with candidates list, signal error on overflow",
    1511             :         };
    1512        2728 :         for(tp1 = integer; tp1 < extra && !err; tp1++) {
    1513       19096 :             for(tp2 = integer; tp2 < extra && !err; tp2++) {
    1514      133672 :                         for(rt = extra-1; rt >= integer && !err; rt--) {
    1515      116963 :                                 if (rt < tp1 && rt < tp2)
    1516       83886 :                                         continue;
    1517       85932 :                                 if (*rt == TYPE_dbl) {
    1518       16709 :                                         if (*tp1 != TYPE_dbl || *tp2 != TYPE_dbl)
    1519       16368 :                                                 continue;
    1520       69223 :                                 } else if (*rt == TYPE_flt) {
    1521       16368 :                                         if (*tp1 != TYPE_flt || *tp2 != TYPE_flt)
    1522       16027 :                                                 continue;
    1523             :                                 } else {
    1524       52855 :                                         if (*tp1 == TYPE_flt || *tp2 == TYPE_flt || *tp1 == TYPE_dbl || *tp2 == TYPE_dbl)
    1525       20460 :                                                 continue;
    1526             :                                 }
    1527       33077 :                                 mel_func_arg ret = { .type = *rt, .isbat =1 };
    1528       33077 :                                 mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1529       33077 :                                 mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1530       33077 :                                 mel_func_arg varg1 = { .type = *tp1 };
    1531       33077 :                                 mel_func_arg varg2 = { .type = *tp2 };
    1532             : 
    1533       33077 :                                 err += melFunction(false, "batcalc", mods.op, mods.fcn, mods.fname, false, mods.comment, 1, 5, ret, arg1, arg2, cand, cand);
    1534       33077 :                                 err += melFunction(false, "batcalc", mods.op, mods.fcn, mods.fname, false, mods.comment_v, 1, 4, ret, arg1, varg2, cand);
    1535       33077 :                                 err += melFunction(false, "batcalc", mods.op, mods.fcn, mods.fname, false, mods.comment_v_, 1, 4, ret, varg1, arg2, cand);
    1536             :                         }
    1537             :             }
    1538             :         }
    1539         341 :         struct {
    1540             :                 char *op;
    1541             :                 char *fname;
    1542             :                 MALfcn fcn;
    1543             :                 char *comment;
    1544             :                 char *comment_v;
    1545             :                 char *comment_v_;
    1546         341 :         } logops[3] = {
    1547             :                 {
    1548             :                         .op = "and",
    1549             :                         .fcn = (MALfcn)CMDbatAND,
    1550             :                         .fname = "CMDbatAND",
    1551             :                         .comment = "Return B1 and B2",
    1552             :                         .comment_v = "Return B and V",
    1553             :                         .comment_v_ = "Return V and B",
    1554             :                 }, {
    1555             :                         .op = "or",
    1556             :                         .fcn = (MALfcn)CMDbatOR,
    1557             :                         .fname = "CMDbatOR",
    1558             :                         .comment = "Return B1 or B2",
    1559             :                         .comment_v = "Return B or V",
    1560             :                         .comment_v_ = "Return V or B",
    1561             :                 }, {
    1562             :                         .op = "xor",
    1563             :                         .fcn = (MALfcn)CMDbatXOR,
    1564             :                         .fname = "CMDbatXOR",
    1565             :                         .comment = "Return B1 xor B2",
    1566             :                         .comment_v = "Return B xor V",
    1567             :                         .comment_v_ = "Return V xor B",
    1568             :                 }
    1569             :         };
    1570        1364 :         for (int f=0; f<3; f++) {
    1571        9207 :                 for(tp = types+0; tp < extra && !err; tp++) {
    1572        8184 :                         mel_func_arg ret = { .type = *tp, .isbat =1 };
    1573        8184 :                         mel_func_arg arg = { .type = *tp, .isbat =1 };
    1574        8184 :                         mel_func_arg varg = { .type = *tp };
    1575             : 
    1576        8184 :                         err += melFunction(false, "batcalc", logops[f].op, logops[f].fcn, logops[f].fname, false, logops[f].comment, 1, 3, ret, arg, arg);
    1577        8184 :                         err += melFunction(false, "batcalc", logops[f].op, logops[f].fcn, logops[f].fname, false, logops[f].comment, 1, 5, ret, arg, arg, cand, cand);
    1578        8184 :                         err += melFunction(false, "batcalc", logops[f].op, logops[f].fcn, logops[f].fname, false, logops[f].comment_v, 1, 3, ret, arg, varg);
    1579        8184 :                         err += melFunction(false, "batcalc", logops[f].op, logops[f].fcn, logops[f].fname, false, logops[f].comment_v, 1, 4, ret, arg, varg, cand);
    1580        8184 :                         err += melFunction(false, "batcalc", logops[f].op, logops[f].fcn, logops[f].fname, false, logops[f].comment_v_, 1, 3, ret, varg, arg);
    1581        8184 :                         err += melFunction(false, "batcalc", logops[f].op, logops[f].fcn, logops[f].fname, false, logops[f].comment_v_, 1, 4, ret, varg, arg, cand);
    1582             :                 }
    1583             :         }
    1584         341 :         struct {
    1585             :                 char *op;
    1586             :                 char *fname;
    1587             :                 MALfcn fcn;
    1588             :                 char *comment;
    1589             :                 char *comment_v;
    1590             :                 char *comment_v_;
    1591         341 :         } shifts[2] = {
    1592             :                 {
    1593             :                         .op = "<<",
    1594             :                         .fcn = (MALfcn)CMDbatLSHsignal,
    1595             :                         .fname = "CMDbatLSHsignal",
    1596             :                         .comment = "Return B1 << B2, raise error on out of range second operand",
    1597             :                         .comment_v = "Return B << V, raise error on out of range second operand",
    1598             :                         .comment_v_ = "Return B << V, raise error on out of range second operand",
    1599             :                 }, {
    1600             :                         .op = ">>",
    1601             :                         .fcn = (MALfcn)CMDbatRSHsignal,
    1602             :                         .fname = "CMDbatRSHsignal",
    1603             :                         .comment = "Return B1 >> B2, raise error on out of range second operand",
    1604             :                         .comment_v = "Return B >> V, raise error on out of range second operand",
    1605             :                         .comment_v_ = "Return B >> V, raise error on out of range second operand",
    1606             :                 }
    1607             :         };
    1608        1023 :         for (int f=0; f<2; f++) {
    1609             :                 int *tp1, *tp2;
    1610        4092 :                 for(tp1 = integer; tp1 < floats && !err; tp1++) {
    1611       20460 :                         for(tp2 = integer; tp2 < floats && !err; tp2++) {
    1612       17050 :                                 mel_func_arg ret = { .type = *tp1, .isbat =1 };
    1613       17050 :                                 mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1614       17050 :                                 mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1615       17050 :                                 mel_func_arg varg1 = { .type = *tp1 };
    1616       17050 :                                 mel_func_arg varg2 = { .type = *tp2 };
    1617             : 
    1618       17050 :                                 err += melFunction(false, "batcalc", shifts[f].op, shifts[f].fcn, shifts[f].fname, false, shifts[f].comment, 1, 3, ret, arg1, arg2);
    1619       17050 :                                 err += melFunction(false, "batcalc", shifts[f].op, shifts[f].fcn, shifts[f].fname, false, shifts[f].comment, 1, 5, ret, arg1, arg2, cand, cand);
    1620       17050 :                                 err += melFunction(false, "batcalc", shifts[f].op, shifts[f].fcn, shifts[f].fname, false, shifts[f].comment_v, 1, 3, ret, arg1, varg2);
    1621       17050 :                                 err += melFunction(false, "batcalc", shifts[f].op, shifts[f].fcn, shifts[f].fname, false, shifts[f].comment_v, 1, 4, ret, arg1, varg2, cand);
    1622       17050 :                                 err += melFunction(false, "batcalc", shifts[f].op, shifts[f].fcn, shifts[f].fname, false, shifts[f].comment_v_, 1, 3, ret, varg1, arg2);
    1623       17050 :                                 err += melFunction(false, "batcalc", shifts[f].op, shifts[f].fcn, shifts[f].fname, false, shifts[f].comment_v_, 1, 4, ret, varg1, arg2, cand);
    1624             :                         }
    1625             :                 }
    1626             :         }
    1627             : 
    1628         341 :         struct {
    1629             :                 char *op;
    1630             :                 char *fname;
    1631             :                 MALfcn fcn;
    1632             :                 char *comment;
    1633             :                 char *comment_v;
    1634             :                 char *comment_v_;
    1635         341 :         } cmps[6] = {
    1636             :                 {
    1637             :                         .op = "<",
    1638             :                         .fcn = (MALfcn)CMDbatLT,
    1639             :                         .fname = "CMDbatLT",
    1640             :                         .comment = "Return B1 < B2",
    1641             :                         .comment_v = "Return B < V",
    1642             :                         .comment_v_ = "Return B < V",
    1643             :                 }, {
    1644             :                         .op = "<=",
    1645             :                         .fcn = (MALfcn)CMDbatLE,
    1646             :                         .fname = "CMDbatLE",
    1647             :                         .comment = "Return B1 <= B2",
    1648             :                         .comment_v = "Return B <= V",
    1649             :                         .comment_v_ = "Return B <= V",
    1650             :                 }, {
    1651             :                         .op = ">",
    1652             :                         .fcn = (MALfcn)CMDbatGT,
    1653             :                         .fname = "CMDbatGT",
    1654             :                         .comment = "Return B1 > B2",
    1655             :                         .comment_v = "Return B > V",
    1656             :                         .comment_v_ = "Return B > V",
    1657             :                 }, {
    1658             :                         .op = ">=",
    1659             :                         .fcn = (MALfcn)CMDbatGE,
    1660             :                         .fname = "CMDbatGE",
    1661             :                         .comment = "Return B1 >= B2",
    1662             :                         .comment_v = "Return B >= V",
    1663             :                         .comment_v_ = "Return B >= V",
    1664             :                 }, {
    1665             :                         .op = "==",
    1666             :                         .fcn = (MALfcn)CMDbatEQ,
    1667             :                         .fname = "CMDbatEQ",
    1668             :                         .comment = "Return B1 == B2",
    1669             :                         .comment_v = "Return B == V",
    1670             :                         .comment_v_ = "Return B == V",
    1671             :                 }, {
    1672             :                         .op = "!=",
    1673             :                         .fcn = (MALfcn)CMDbatNE,
    1674             :                         .fname = "CMDbatNE",
    1675             :                         .comment = "Return B1 != B2",
    1676             :                         .comment_v = "Return B != V",
    1677             :                         .comment_v_ = "Return B != V",
    1678             :                 }
    1679             :         };
    1680         341 :         int newtypes[6] = { ATOMindex("json"), ATOMindex("inet"), ATOMindex("uuid"), TYPE_date, TYPE_daytime, TYPE_timestamp };
    1681        2387 :         for (int f=0; f<6; f++) {
    1682        2046 :                 mel_func_arg ret = { .type = TYPE_bit, .isbat =1 };
    1683        2046 :                 mel_func_arg arg = { .type = TYPE_any, .isbat =1, .nr=1 };
    1684        2046 :                 mel_func_arg varg = { .type = TYPE_any, .nr=1 };
    1685             : 
    1686        2046 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 3, ret, arg, arg);
    1687        2046 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 5, ret, arg, arg, cand, cand);
    1688        2046 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 3, ret, arg, varg);
    1689        2046 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 4, ret, arg, varg, cand);
    1690        2046 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 3, ret, varg, arg);
    1691        2046 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 4, ret, varg, arg, cand);
    1692             : 
    1693        2046 :                 if (strcmp(cmps[f].op,"==")==0 || strcmp(cmps[f].op,"!=")==0) {
    1694         682 :                         mel_func_arg nil_matches = { .type = TYPE_bit };
    1695             : 
    1696         682 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 4, ret, arg, arg, nil_matches);
    1697         682 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 6, ret, arg, arg, cand, cand, nil_matches);
    1698         682 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 4, ret, arg, varg, nil_matches);
    1699         682 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 5, ret, arg, varg, cand, nil_matches);
    1700         682 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 4, ret, varg, arg, nil_matches);
    1701         682 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 5, ret, varg, arg, cand, nil_matches);
    1702             :                 }
    1703             : 
    1704             :                 /* uuid, json, inet and mtime (date, daytime, timestamp) */
    1705       14322 :                 for (int nt = 0; nt < 6; nt++) {
    1706       12276 :                         mel_func_arg ret = { .type = TYPE_bit, .isbat =1 };
    1707       12276 :                         mel_func_arg arg = { .type = newtypes[nt], .isbat =1, .nr=1 };
    1708       12276 :                         mel_func_arg varg = { .type = newtypes[nt], .nr=1 };
    1709             : 
    1710       12276 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 3, ret, arg, arg);
    1711       12276 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 5, ret, arg, arg, cand, cand);
    1712       12276 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 3, ret, arg, varg);
    1713       12276 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 4, ret, arg, varg, cand);
    1714       12276 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 3, ret, varg, arg);
    1715       12276 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 4, ret, varg, arg, cand);
    1716             : 
    1717       12276 :                         if (strcmp(cmps[f].op,"==")==0 || strcmp(cmps[f].op,"!=")==0) {
    1718        4092 :                                 mel_func_arg nil_matches = { .type = TYPE_bit };
    1719             : 
    1720        4092 :                                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 4, ret, arg, arg, nil_matches);
    1721        4092 :                                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 6, ret, arg, arg, cand, cand, nil_matches);
    1722        4092 :                                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 4, ret, arg, varg, nil_matches);
    1723        4092 :                                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 5, ret, arg, varg, cand, nil_matches);
    1724        4092 :                                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 4, ret, varg, arg, nil_matches);
    1725        4092 :                                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 5, ret, varg, arg, cand, nil_matches);
    1726             :                         }
    1727             :                 }
    1728             : 
    1729             :                 int *tp1, *tp2;
    1730       12276 :                 for(tp1 = integer; tp1 < floats && !err; tp1++) {
    1731       61380 :                         for(tp2 = integer; tp2 < floats && !err; tp2++) {
    1732       51150 :                                 if (*tp1 == *tp2)
    1733       10230 :                                         continue;
    1734       40920 :                                 mel_func_arg ret = { .type = TYPE_bit, .isbat =1 };
    1735       40920 :                                 mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1736       40920 :                                 mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1737       40920 :                                 mel_func_arg varg1 = { .type = *tp1 };
    1738       40920 :                                 mel_func_arg varg2 = { .type = *tp2 };
    1739             : 
    1740       40920 :                                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 3, ret, arg1, arg2);
    1741       40920 :                                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 5, ret, arg1, arg2, cand, cand);
    1742       40920 :                                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 3, ret, arg1, varg2);
    1743       40920 :                                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 4, ret, arg1, varg2, cand);
    1744       40920 :                                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 3, ret, varg1, arg2);
    1745       40920 :                                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 4, ret, varg1, arg2, cand);
    1746             : 
    1747       40920 :                                 if (strcmp(cmps[f].op,"==")==0 || strcmp(cmps[f].op,"!=")==0) {
    1748       13640 :                                         mel_func_arg nil_matches = { .type = TYPE_bit };
    1749             : 
    1750       13640 :                                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 4, ret, arg1, arg2, nil_matches);
    1751       13640 :                                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 6, ret, arg1, arg2, cand, cand, nil_matches);
    1752       13640 :                                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 4, ret, arg1, varg2, nil_matches);
    1753       13640 :                                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 5, ret, arg1, varg2, cand, nil_matches);
    1754       13640 :                                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 4, ret, varg1, arg2, nil_matches);
    1755       13640 :                                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 5, ret, varg1, arg2, cand, nil_matches);
    1756             :                                 }
    1757             :                         }
    1758             :                 }
    1759             :         }
    1760             : 
    1761             :         struct {
    1762             :                 char *op;
    1763             :                 char *fname;
    1764             :                 MALfcn fcn;
    1765             :                 char *comment;
    1766             :                 char *comment_v;
    1767             :                 char *comment_v_;
    1768             :         } cmp = {
    1769             :                 .op = "cmp",
    1770             :                 .fcn = (MALfcn)CMDbatCMP,
    1771             :                 .fname = "CMDbatCMP",
    1772             :                 .comment = "Return -1/0/1 if B1 </==/> B2",
    1773             :                 .comment_v = "Return -1/0/1 if B </==/> V",
    1774             :                 .comment_v_ = "Return -1/0/1 if V </==/> B",
    1775             :         };
    1776        1364 :         for(int i = 0; i < 3 && !err; i++) {
    1777        1023 :                 int tp = specials[i];
    1778        1023 :                 mel_func_arg ret = { .type = TYPE_bte, .isbat =1 };
    1779        1023 :                 mel_func_arg arg = { .type = tp, .isbat =1 };
    1780        1023 :                 mel_func_arg varg = { .type = tp };
    1781             : 
    1782        1023 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment, 1, 3, ret, arg, arg);
    1783        1023 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment, 1, 5, ret, arg, arg, cand, cand);
    1784        1023 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v, 1, 3, ret, arg, varg);
    1785        1023 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v, 1, 4, ret, arg, varg, cand);
    1786        1023 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v_, 1, 3, ret, varg, arg);
    1787        1023 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v_, 1, 4, ret, varg, arg, cand);
    1788             :         }
    1789        2728 :         for(tp1 = integer; tp1 < extra && !err; tp1++) {
    1790       19096 :             for(tp2 = integer; tp2 < extra && !err; tp2++) {
    1791       16709 :                         mel_func_arg ret = { .type = TYPE_bte, .isbat =1 };
    1792       16709 :                         mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1793       16709 :                         mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1794       16709 :                         mel_func_arg varg1 = { .type = *tp1 };
    1795       16709 :                         mel_func_arg varg2 = { .type = *tp2 };
    1796             : 
    1797       16709 :                         err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment, 1, 3, ret, arg1, arg2);
    1798       16709 :                         err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment, 1, 5, ret, arg1, arg2, cand, cand);
    1799       16709 :                         err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v, 1, 3, ret, arg1, varg2);
    1800       16709 :                         err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v, 1, 4, ret, arg1, varg2, cand);
    1801       16709 :                         err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v_, 1, 3, ret, varg1, arg2);
    1802       16709 :                         err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v_, 1, 4, ret, varg1, arg2, cand);
    1803             :             }
    1804             :         }
    1805        2728 :         for(tp = integer; tp < extra && !err; tp++) {
    1806        2387 :                 mel_func_arg ret = { .type = TYPE_dbl };
    1807        2387 :                 mel_func_arg nr = { .type = TYPE_lng };
    1808        2387 :                 mel_func_arg arg = { .type = *tp, .isbat =1 };
    1809        2387 :                 mel_func_arg scale = { .type = TYPE_int };
    1810             : 
    1811        2387 :                 err += melFunction(false, "batcalc", "avg", (MALfcn)&CMDcalcavg, "CMDcalcavg", false, "average of non-nil values of B", 1, 2, ret, arg);
    1812        2387 :                 err += melFunction(false, "batcalc", "avg", (MALfcn)&CMDcalcavg, "CMDcalcavg", false, "average of non-nil values of B with candidates list", 1, 3, ret, arg, cand);
    1813        2387 :                 err += melFunction(false, "batcalc", "avg", (MALfcn)&CMDcalcavg, "CMDcalcavg", false, "average and number of non-nil values of B", 2, 3, ret, nr, arg);
    1814        2387 :                 err += melFunction(false, "batcalc", "avg", (MALfcn)&CMDcalcavg, "CMDcalcavg", false, "average and number of non-nil values of B with candidates list", 2, 4, ret, nr, arg, cand);
    1815        2387 :                 err += melFunction(false, "batcalc", "avg", (MALfcn)&CMDcalcavg, "CMDcalcavg", false, "average of non-nil values of B", 1, 3, ret, arg, scale);
    1816        2387 :                 err += melFunction(false, "batcalc", "avg", (MALfcn)&CMDcalcavg, "CMDcalcavg", false, "average of non-nil values of B with candidates list", 1, 4, ret, arg, cand, scale);
    1817        2387 :                 err += melFunction(false, "batcalc", "avg", (MALfcn)&CMDcalcavg, "CMDcalcavg", false, "average and number of non-nil values of B", 2, 4, ret, nr, arg, scale);
    1818        2387 :                 err += melFunction(false, "batcalc", "avg", (MALfcn)&CMDcalcavg, "CMDcalcavg", false, "average and number of non-nil values of B with candidates list", 2, 5, ret, nr, arg, cand, scale);
    1819             :         }
    1820             : 
    1821         341 :         struct {
    1822             :                 int type;
    1823             :                 char *name;
    1824             :                 char *fname;
    1825             :                 MALfcn fcn;
    1826         341 :         } typeops[10] = {
    1827             :                 {
    1828             :                         .type = TYPE_bit,
    1829             :                         .name = "bit",
    1830             :                         .fname = "CMDconvertsignal_bit",
    1831             :                         .fcn = (MALfcn)CMDconvertsignal_bit,
    1832             :                 }, {
    1833             :                         .type = TYPE_bte,
    1834             :                         .name = "bte",
    1835             :                         .fname = "CMDconvertsignal_bte",
    1836             :                         .fcn = (MALfcn)CMDconvertsignal_bte,
    1837             :                 }, {
    1838             :                         .type = TYPE_sht,
    1839             :                         .name = "sht",
    1840             :                         .fname = "CMDconvertsignal_sht",
    1841             :                         .fcn = (MALfcn)CMDconvertsignal_sht,
    1842             :                 }, {
    1843             :                         .type = TYPE_int,
    1844             :                         .name = "int",
    1845             :                         .fname = "CMDconvertsignal_int",
    1846             :                         .fcn = (MALfcn)CMDconvertsignal_int,
    1847             :                 }, {
    1848             :                         .type = TYPE_lng,
    1849             :                         .name = "lng",
    1850             :                         .fname = "CMDconvertsignal_lng",
    1851             :                         .fcn = (MALfcn)CMDconvertsignal_lng,
    1852             : #ifdef HAVE_HGE
    1853             :                 }, {
    1854             :                         .type = TYPE_hge,
    1855             :                         .name = "hge",
    1856             :                         .fname = "CMDconvertsignal_hge",
    1857             :                         .fcn = (MALfcn)CMDconvertsignal_hge,
    1858             : #endif
    1859             :                 }, {
    1860             :                         .type = TYPE_flt,
    1861             :                         .name = "flt",
    1862             :                         .fname = "CMDconvertsignal_flt",
    1863             :                         .fcn = (MALfcn)CMDconvertsignal_flt,
    1864             :                 }, {
    1865             :                         .type = TYPE_dbl,
    1866             :                         .name = "dbl",
    1867             :                         .fname = "CMDconvertsignal_dbl",
    1868             :                         .fcn = (MALfcn)CMDconvertsignal_dbl,
    1869             :                 }, {
    1870             :                         .type = TYPE_oid,
    1871             :                         .name = "oid",
    1872             :                         .fname = "CMDconvertsignal_oid",
    1873             :                         .fcn = (MALfcn)CMDconvertsignal_oid,
    1874             :                 }, {
    1875             :                         .type = TYPE_str,
    1876             :                         .name = "str",
    1877             :                         .fname = "CMDconvertsignal_str",
    1878             :                         .fcn = (MALfcn)CMDconvertsignal_str,
    1879             :                 }
    1880             :         };
    1881             : #ifdef HAVE_HGE
    1882         341 :         int typeopslen = 10;
    1883             : #else
    1884             :         int typeopslen = 9;
    1885             : #endif
    1886        3751 :         for(int t = 0; t<typeopslen; t++) {
    1887             :                 /* from any 2 string */
    1888        3410 :                 mel_func_arg ret = { .type = typeops[t].type, .isbat =1 };
    1889        3410 :                 if (strcmp(typeops[t].name, "str")==0) {
    1890         341 :                         mel_func_arg arg = { .type = TYPE_any, .isbat =1 };
    1891             : 
    1892         341 :                         err += melFunction(false, "batcalc", typeops[t].name, typeops[t].fcn, typeops[t].fname, false, "", 1, 2, ret, arg);
    1893         341 :                         err += melFunction(false, "batcalc", typeops[t].name, typeops[t].fcn, typeops[t].fname, false, "", 1, 3, ret, arg, cand);
    1894             :                 } else {
    1895       33759 :                     for(int p = 0; p<typeopslen; p++) {
    1896       30690 :                                 mel_func_arg arg = { .type = typeops[p].type, .isbat =1 };
    1897             : 
    1898       30690 :                                 err += melFunction(false, "batcalc", typeops[t].name, typeops[t].fcn, typeops[t].fname, false, "", 1, 2, ret, arg);
    1899       30690 :                                 err += melFunction(false, "batcalc", typeops[t].name, typeops[t].fcn, typeops[t].fname, false, "", 1, 3, ret, arg, cand);
    1900             :                     }
    1901             :                 }
    1902             :         }
    1903         341 :         return MAL_SUCCEED;
    1904             : }
    1905             : 
    1906             : static mel_func batcalc_init_funcs[] = {
    1907             :  /* batcalc */
    1908             :  pattern("batcalc", "isnil", CMDbatISNIL, false, "Unary check for nil over the tail of the bat", args(1,2, batarg("",bit),batargany("b",0))),
    1909             :  pattern("batcalc", "isnil", CMDbatISNIL, false, "Unary check for nil over the tail of the bat with candidates list", args(1,3, batarg("",bit),batargany("b",0),batarg("s",oid))),
    1910             :  pattern("batcalc", "isnotnil", CMDbatISNOTNIL, false, "Unary check for notnil over the tail of the bat", args(1,2, batarg("",bit),batargany("b",0))),
    1911             :  pattern("batcalc", "isnotnil", CMDbatISNOTNIL, false, "Unary check for notnil over the tail of the bat with candidates list", args(1,3, batarg("",bit),batargany("b",0),batarg("s",oid))),
    1912             :  pattern("batcalc", "min", CMDbatMIN, false, "Return bat with minimum value of each pair of inputs", args(1,3, batargany("",1),batargany("b1",1),batargany("b2",1))),
    1913             :  pattern("batcalc", "min", CMDbatMIN, false, "Return bat with minimum value of each pair of inputs", args(1,5, batargany("",1),batargany("b1",1),batargany("b2",1),batarg("s1",oid),batarg("s2",oid))),
    1914             :  pattern("batcalc", "min", CMDbatMIN, false, "Return bat with minimum value of each pair of inputs", args(1,3, batargany("",1),batargany("b",1),argany("v",1))),
    1915             :  pattern("batcalc", "min", CMDbatMIN, false, "Return bat with minimum value of each pair of inputs", args(1,4, batargany("",1),batargany("b",1),argany("v",1),batarg("s",oid))),
    1916             :  pattern("batcalc", "min", CMDbatMIN, false, "Return bat with minimum value of each pair of inputs", args(1,3, batargany("",1),argany("v",1),batargany("b",1))),
    1917             :  pattern("batcalc", "min", CMDbatMIN, false, "Return bat with minimum value of each pair of inputs", args(1,4, batargany("",1),argany("v",1),batargany("b",1),batarg("s",oid))),
    1918             :  pattern("batcalc", "min_no_nil", CMDbatMIN_no_nil, false, "Return bat with minimum value of each pair of inputs, ignoring nil values", args(1,3, batargany("",1),batargany("b1",1),batargany("b2",1))),
    1919             :  pattern("batcalc", "min_no_nil", CMDbatMIN_no_nil, false, "Return bat with minimum value of each pair of inputs, ignoring nil values", args(1,5, batargany("",1),batargany("b1",1),batargany("b2",1),batarg("s1",oid),batarg("s2",oid))),
    1920             :  pattern("batcalc", "min_no_nil", CMDbatMIN_no_nil, false, "Return bat with minimum value of each pair of inputs, ignoring nil values", args(1,3, batargany("",1),batargany("b",1),argany("v",1))),
    1921             :  pattern("batcalc", "min_no_nil", CMDbatMIN_no_nil, false, "Return bat with minimum value of each pair of inputs, ignoring nil values", args(1,4, batargany("",1),batargany("b",1),argany("v",1),batarg("s",oid))),
    1922             :  pattern("batcalc", "min_no_nil", CMDbatMIN_no_nil, false, "Return bat with minimum value of each pair of inputs, ignoring nil values", args(1,3, batargany("",1),argany("v",1),batargany("b",1))),
    1923             :  pattern("batcalc", "min_no_nil", CMDbatMIN_no_nil, false, "Return bat with minimum value of each pair of inputs, ignoring nil values", args(1,4, batargany("",1),argany("v",1),batargany("b",1),batarg("s",oid))),
    1924             :  pattern("batcalc", "max", CMDbatMAX, false, "Return bat with maximum value of each pair of inputs", args(1,3, batargany("",1),batargany("b1",1),batargany("b2",1))),
    1925             :  pattern("batcalc", "max", CMDbatMAX, false, "Return bat with maximum value of each pair of inputs", args(1,5, batargany("",1),batargany("b1",1),batargany("b2",1),batarg("s1",oid),batarg("s2",oid))),
    1926             :  pattern("batcalc", "max", CMDbatMAX, false, "Return bat with maximum value of each pair of inputs", args(1,3, batargany("",1),batargany("b",1),argany("v",1))),
    1927             :  pattern("batcalc", "max", CMDbatMAX, false, "Return bat with maximum value of each pair of inputs", args(1,4, batargany("",1),batargany("b",1),argany("v",1),batarg("s",oid))),
    1928             :  pattern("batcalc", "max", CMDbatMAX, false, "Return bat with maximum value of each pair of inputs", args(1,3, batargany("",1),argany("v",1),batargany("b",1))),
    1929             :  pattern("batcalc", "max", CMDbatMAX, false, "Return bat with maximum value of each pair of inputs", args(1,4, batargany("",1),argany("v",1),batargany("b",1),batarg("s",oid))),
    1930             :  pattern("batcalc", "max_no_nil", CMDbatMAX_no_nil, false, "Return bat with maximum value of each pair of inputs, ignoring nil values", args(1,3, batargany("",1),batargany("b1",1),batargany("b2",1))),
    1931             :  pattern("batcalc", "max_no_nil", CMDbatMAX_no_nil, false, "Return bat with maximum value of each pair of inputs, ignoring nil values", args(1,5, batargany("",1),batargany("b1",1),batargany("b2",1),batarg("s1",oid),batarg("s2",oid))),
    1932             :  pattern("batcalc", "max_no_nil", CMDbatMAX_no_nil, false, "Return bat with maximum value of each pair of inputs, ignoring nil values", args(1,3, batargany("",1),batargany("b",1),argany("v",1))),
    1933             :  pattern("batcalc", "max_no_nil", CMDbatMAX_no_nil, false, "Return bat with maximum value of each pair of inputs, ignoring nil values", args(1,4, batargany("",1),batargany("b",1),argany("v",1),batarg("s",oid))),
    1934             :  pattern("batcalc", "max_no_nil", CMDbatMAX_no_nil, false, "Return bat with maximum value of each pair of inputs, ignoring nil values", args(1,3, batargany("",1),argany("v",1),batargany("b",1))),
    1935             :  pattern("batcalc", "max_no_nil", CMDbatMAX_no_nil, false, "Return bat with maximum value of each pair of inputs, ignoring nil values", args(1,4, batargany("",1),argany("v",1),batargany("b",1),batarg("s",oid))),
    1936             : 
    1937             :  pattern("batcalc", "+", CMDbatADDsignal, false, "Return concatenation of B1 and B2 with candidates list", args(1,5, batarg("",str),batarg("b1",str),batarg("b2",str),batarg("s1",oid),batarg("s2",oid))),
    1938             :  pattern("batcalc", "+", CMDbatADDsignal, false, "Return concatenation of B and V with candidates list", args(1,4, batarg("",str),batarg("b",str),arg("v",str),batarg("s",oid))),
    1939             :  pattern("batcalc", "+", CMDbatADDsignal, false, "Return concatenation of V and B with candidates list", args(1,4, batarg("",str),arg("v",str),batarg("b",str),batarg("s",oid))),
    1940             : 
    1941             :  pattern("batmmath", "fmod", CMDbatMODsignal, false, "", args(1,3, batarg("",dbl),batarg("x",dbl),arg("y",dbl))),
    1942             :  pattern("batmmath", "fmod", CMDbatMODsignal, false, "", args(1,4, batarg("",dbl),batarg("x",dbl),arg("y",dbl),batarg("s",oid))),
    1943             :  pattern("batmmath", "fmod", CMDbatMODsignal, false, "", args(1,3, batarg("",flt),batarg("x",flt),arg("y",flt))),
    1944             :  pattern("batmmath", "fmod", CMDbatMODsignal, false, "", args(1,4, batarg("",flt),batarg("x",flt),arg("y",flt),batarg("s",oid))),
    1945             : 
    1946             :  pattern("batcalc", "between", CMDbatBETWEEN, false, "B between V1 and V2 (or vice versa)", args(1,9, batarg("",bit),batargany("b",1),batargany("v1",1),batargany("v2",1),arg("sym",bit),arg("linc",bit),arg("hinc",bit),arg("nils_false",bit),arg("anti",bit))),
    1947             :  pattern("batcalc", "between", CMDbatBETWEEN, false, "B between V1 and V2 (or vice versa) with candidates list", args(1,12, batarg("",bit),batargany("b",1),batargany("v1",1),batargany("v2",1),batarg("s",oid),batarg("s1",oid),batarg("s2",oid),arg("sym",bit),arg("linc",bit),arg("hinc",bit),arg("nils_false",bit),arg("anti",bit))),
    1948             :  pattern("batcalc", "between", CMDbatBETWEEN, false, "B between V1 and V2 (or vice versa)", args(1,9, batarg("",bit),batargany("b",1),batargany("v1",1),argany("v2",1),arg("sym",bit),arg("linc",bit),arg("hinc",bit),arg("nils_false",bit),arg("anti",bit))),
    1949             :  pattern("batcalc", "between", CMDbatBETWEEN, false, "B between V1 and V2 (or vice versa) with candidates list", args(1,11, batarg("",bit),batargany("b",1),batargany("v1",1),argany("v2",1),batarg("s",oid),batarg("s1",oid),arg("sym",bit),arg("linc",bit),arg("hinc",bit),arg("nils_false",bit),arg("anti",bit))),
    1950             :  pattern("batcalc", "between", CMDbatBETWEEN, false, "B between V1 and V2 (or vice versa)", args(1,9, batarg("",bit),batargany("b",1),argany("v1",1),batargany("v2",1),arg("sym",bit),arg("linc",bit),arg("hinc",bit),arg("nils_false",bit),arg("anti",bit))),
    1951             :  pattern("batcalc", "between", CMDbatBETWEEN, false, "B between V1 and V2 (or vice versa) with candidates list", args(1,11, batarg("",bit),batargany("b",1),argany("v1",1),batargany("v2",1),batarg("s",oid),batarg("s2",oid),arg("sym",bit),arg("linc",bit),arg("hinc",bit),arg("nils_false",bit),arg("anti",bit))),
    1952             :  pattern("batcalc", "between", CMDbatBETWEEN, false, "B between V1 and V2 (or vice versa)", args(1,9, batarg("",bit),batargany("b",1),argany("v1",1),argany("v2",1),arg("sym",bit),arg("linc",bit),arg("hinc",bit),arg("nils_false",bit),arg("anti",bit))),
    1953             :  pattern("batcalc", "between", CMDbatBETWEEN, false, "B between V1 and V2 (or vice versa) with candidates list", args(1,10, batarg("",bit),batargany("b",1),argany("v1",1),argany("v2",1),batarg("s",oid),arg("sym",bit),arg("linc",bit),arg("hinc",bit),arg("nils_false",bit),arg("anti",bit))),
    1954             : 
    1955             :  pattern("aggr", "avg", CMDcalcavg, false, "Gives the avg of all tail values", args(1,2, arg("",dbl),batargany("b",1))),
    1956             :  pattern("aggr", "avg", CMDcalcavg, false, "Gives the avg of all tail values", args(1,3, arg("",dbl),batargany("b",1),arg("scale",int))),
    1957             : 
    1958             :  pattern("batcalc", "ifthenelse", CMDifthen, false, "If-then-else operation to assemble a conditional result", args(1,4, batargany("",1),arg("v",bit),batargany("b1",1),batargany("b2",1))),
    1959             :  pattern("batcalc", "ifthenelse", CMDifthen, false, "If-then-else operation to assemble a conditional result", args(1,4, batargany("",1),arg("v",bit),argany("v1",1),batargany("b2",1))),
    1960             :  pattern("batcalc", "ifthenelse", CMDifthen, false, "If-then-else operation to assemble a conditional result", args(1,4, batargany("",1),arg("v",bit),batargany("b1",1),argany("v2",1))),
    1961             :  pattern("batcalc", "ifthenelse", CMDifthen, false, "If-then-else operation to assemble a conditional result", args(1,4, batargany("",1),batarg("b",bit),argany("v1",1),argany("v2",1))),
    1962             :  pattern("batcalc", "ifthenelse", CMDifthen, false, "If-then-else operation to assemble a conditional result", args(1,4, batargany("",1),batarg("b",bit),batargany("b1",1),argany("v2",1))),
    1963             :  pattern("batcalc", "ifthenelse", CMDifthen, false, "If-then-else operation to assemble a conditional result", args(1,4, batargany("",1),batarg("b",bit),argany("v1",1),batargany("b2",1))),
    1964             :  pattern("batcalc", "ifthenelse", CMDifthen, false, "If-then-else operation to assemble a conditional result", args(1,4, batargany("",1),batarg("b",bit),batargany("b1",1),batargany("b2",1))),
    1965             : 
    1966             :  { .imp=NULL }
    1967             : 
    1968             : };
    1969             : #include "mal_import.h"
    1970             : #ifdef _MSC_VER
    1971             : #undef read
    1972             : #pragma section(".CRT$XCU",read)
    1973             : #endif
    1974         334 : LIB_STARTUP_FUNC(init_batcalc_mal)
    1975         334 : { mal_module2("batcalc", NULL, batcalc_init_funcs, &batcalc_init, NULL); }

Generated by: LCOV version 1.14