LCOV - code coverage report
Current view: top level - monetdb5/modules/mal - batcalc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 768 980 78.4 %
Date: 2024-04-25 20:03:45 Functions: 49 60 81.7 %

          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       12176 : CMDbatUNARY(MalStkPtr stk, InstrPtr pci,
      42             :                         BAT *(*batfunc)(BAT *, BAT *), const char *malfunc)
      43             : {
      44       12176 :         bat bid;
      45       12176 :         BAT *bn, *b, *s = NULL;
      46             : 
      47       12176 :         bid = *getArgReference_bat(stk, pci, 1);
      48       12176 :         if ((b = BATdescriptor(bid)) == NULL)
      49           0 :                 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
      50       12175 :         if (pci->argc == 3) {
      51         241 :                 bid = *getArgReference_bat(stk, pci, 2);
      52         241 :                 if (!is_bat_nil(bid)) {
      53         220 :                         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       12175 :         bn = (*batfunc) (b, s);
      61       12176 :         BBPunfix(b->batCacheid);
      62       12176 :         BBPreclaim(s);
      63       12176 :         if (bn == NULL) {
      64           0 :                 return mythrow(MAL, malfunc, OPERATION_FAILED);
      65             :         }
      66       12176 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
      67       12176 :         BBPkeepref(bn);
      68       12176 :         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        3674 : CMDbatISNIL(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     113             : {
     114        3674 :         (void) cntxt;
     115        3674 :         (void) mb;
     116             : 
     117        3674 :         return CMDbatUNARY(stk, pci, BATcalcisnil, "batcalc.isnil");
     118             : }
     119             : 
     120             : static str
     121        2867 : CMDbatISNOTNIL(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     122             : {
     123        2867 :         (void) cntxt;
     124        2867 :         (void) mb;
     125             : 
     126        2867 :         return CMDbatUNARY(stk, pci, BATcalcisnotnil, "batcalc.isnotnil");
     127             : }
     128             : 
     129             : static str
     130         901 : CMDbatNOT(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     131             : {
     132         901 :         (void) cntxt;
     133         901 :         (void) mb;
     134             : 
     135         901 :         return CMDbatUNARY(stk, pci, BATcalcnot, "batcalc.not");
     136             : }
     137             : 
     138             : static str
     139        4519 : CMDbatABS(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     140             : {
     141        4519 :         (void) cntxt;
     142        4519 :         (void) mb;
     143             : 
     144        4519 :         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         201 : CMDbatNEG(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     167             : {
     168         201 :         (void) cntxt;
     169         201 :         (void) mb;
     170             : 
     171         201 :         return CMDbatUNARY(stk, pci, BATcalcnegate, "batcalc.neg");
     172             : }
     173             : 
     174             : static str
     175          14 : CMDbatSIGN(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     176             : {
     177          14 :         (void) cntxt;
     178          14 :         (void) mb;
     179             : 
     180          14 :         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_bat && tp1 != TYPE_ptr);
     270           0 :         assert(tp2 > 0 && tp2 < TYPE_str && tp2 != TYPE_bat && 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      130744 : 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      130744 :         bat bid;
     296      130744 :         BAT *bn, *b1 = NULL, *b2 = NULL, *s1 = NULL, *s2 = NULL;
     297      130744 :         int tp1, tp2, tp3;
     298             : 
     299      130744 :         tp1 = stk->stk[getArg(pci, 1)].vtype;        /* first argument */
     300      130744 :         tp2 = stk->stk[getArg(pci, 2)].vtype;        /* second argument */
     301      130744 :         tp3 = getArgType(mb, pci, 0);   /* return argument */
     302      130744 :         assert(isaBatType(tp3));
     303      130744 :         tp3 = getBatType(tp3);
     304             : 
     305      130744 :         if (tp1 == TYPE_bat || isaBatType(tp1)) {
     306      130025 :                 bid = *getArgReference_bat(stk, pci, 1);
     307      130025 :                 b1 = BATdescriptor(bid);
     308      130025 :                 if (b1 == NULL)
     309           0 :                         goto bailout;
     310             :         }
     311             : 
     312      130744 :         if (tp2 == TYPE_bat || isaBatType(tp2)) {
     313       56203 :                 bid = *getArgReference_bat(stk, pci, 2);
     314       56203 :                 b2 = BATdescriptor(bid);
     315       56200 :                 if (b2 == NULL)
     316           0 :                         goto bailout;
     317             :         }
     318             : 
     319      130741 :         if (pci->argc > 4) {
     320       55482 :                 assert(pci->argc == 5);
     321       55482 :                 bid = *getArgReference_bat(stk, pci, 4);
     322       55482 :                 if (!is_bat_nil(bid)) {
     323         144 :                         s2 = BATdescriptor(bid);
     324         144 :                         if (s2 == NULL)
     325           0 :                                 goto bailout;
     326             :                 }
     327             :         }
     328      130741 :         if (pci->argc > 3) {
     329      130706 :                 bid = *getArgReference_bat(stk, pci, 3);
     330      130706 :                 if (!is_bat_nil(bid)) {
     331        2693 :                         s1 = BATdescriptor(bid);
     332        2693 :                         if (s1 == NULL)
     333           0 :                                 goto bailout;
     334        2693 :                         if (b1 == NULL) {
     335          13 :                                 s2 = s1;
     336          13 :                                 s1 = NULL;
     337             :                         }
     338             :                 }
     339             :         }
     340             : 
     341      130741 :         if (b1 && b2) {
     342       55482 :                 if (tp3 == TYPE_any)
     343           0 :                         tp3 = (*typefunc) (b1->ttype, b2->ttype);
     344       55482 :                 bn = (*batfunc) (b1, b2, s1, s2, tp3);
     345       75259 :         } else if (b1) {
     346       74540 :                 if (tp3 == TYPE_any)
     347           0 :                         tp3 = (*typefunc) (b1->ttype, tp2);
     348       74540 :                 bn = (*batfunc1) (b1, &stk->stk[getArg(pci, 2)], s1, tp3);
     349         719 :         } else if (b2) {
     350         719 :                 if (tp3 == TYPE_any)
     351           0 :                         tp3 = (*typefunc) (tp1, b2->ttype);
     352         719 :                 bn = (*batfunc2) (&stk->stk[getArg(pci, 1)], b2, s2, tp3);
     353             :         } else
     354           0 :                 goto bailout;                   /* cannot happen */
     355      130730 :         BBPreclaim(b1);
     356      130733 :         BBPreclaim(b2);
     357      130719 :         BBPreclaim(s1);
     358      130719 :         BBPreclaim(s2);
     359      130719 :         if (bn == NULL)
     360           7 :                 return mythrow(MAL, malfunc, GDK_EXCEPTION);
     361      130712 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
     362      130712 :         BBPkeepref(bn);
     363      130712 :         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         234 : 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         234 :         bat bid;
     394         234 :         BAT *bn, *b1 = NULL, *b2 = NULL, *s1 = NULL, *s2 = NULL;
     395         234 :         int tp1, tp2;
     396             : 
     397         234 :         tp1 = stk->stk[getArg(pci, 1)].vtype;        /* first argument */
     398         234 :         tp2 = stk->stk[getArg(pci, 2)].vtype;        /* second argument */
     399             : 
     400         234 :         if (tp1 == TYPE_bat || isaBatType(tp1)) {
     401         233 :                 bid = *getArgReference_bat(stk, pci, 1);
     402         233 :                 b1 = BATdescriptor(bid);
     403         233 :                 if (b1 == NULL)
     404           0 :                         goto bailout;
     405             :         }
     406             : 
     407         234 :         if (tp2 == TYPE_bat || isaBatType(tp2)) {
     408          11 :                 bid = *getArgReference_bat(stk, pci, 2);
     409          11 :                 b2 = BATdescriptor(bid);
     410          11 :                 if (b2 == NULL)
     411           0 :                         goto bailout;
     412             :         }
     413             : 
     414         234 :         if (pci->argc > 4) {
     415           0 :                 assert(pci->argc == 5);
     416           0 :                 bid = *getArgReference_bat(stk, pci, 4);
     417           0 :                 if (!is_bat_nil(bid)) {
     418           0 :                         s2 = BATdescriptor(bid);
     419           0 :                         if (s2 == NULL)
     420           0 :                                 goto bailout;
     421             :                 }
     422             :         }
     423         234 :         if (pci->argc > 3) {
     424           1 :                 bid = *getArgReference_bat(stk, pci, 3);
     425           1 :                 if (!is_bat_nil(bid)) {
     426           0 :                         s1 = BATdescriptor(bid);
     427           0 :                         if (s1 == NULL)
     428           0 :                                 goto bailout;
     429           0 :                         if (b1 == NULL) {
     430           0 :                                 s2 = s1;
     431           0 :                                 s1 = NULL;
     432             :                         }
     433             :                 }
     434             :         }
     435             : 
     436         234 :         if (b1 && b2)
     437          10 :                 bn = (*batfunc) (b1, b2, s1, s2);
     438         224 :         else if (b1)
     439         223 :                 bn = (*batfunc1) (b1, &stk->stk[getArg(pci, 2)], s1);
     440           1 :         else if (b2)
     441           1 :                 bn = (*batfunc2) (&stk->stk[getArg(pci, 1)], b2, s2);
     442             :         else
     443           0 :                 goto bailout;                   /* cannot happen */
     444         234 :         BBPreclaim(b1);
     445         234 :         BBPreclaim(b2);
     446         234 :         BBPreclaim(s1);
     447         234 :         BBPreclaim(s2);
     448         234 :         if (bn == NULL)
     449           0 :                 return mythrow(MAL, malfunc, GDK_EXCEPTION);
     450         234 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
     451         234 :         BBPkeepref(bn);
     452         234 :         return MAL_SUCCEED;
     453             : 
     454           0 :   bailout:
     455           0 :         BBPreclaim(b1);
     456           0 :         BBPreclaim(b2);
     457             : /* cannot happen
     458             :         BBPreclaim(s1);
     459             : */
     460           0 :         BBPreclaim(s2);
     461           0 :         throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     462             : }
     463             : 
     464             : /* MAL function has one of the signatures for CMDbatBINARY2, or one of
     465             :  * the following:
     466             :  * # without candidate list
     467             :  * func(b1:bat, b2:bat, nil_matches:bit) :bat
     468             :  * func(b1:bat, v2:any, nil_matches:bit) :bat
     469             :  * func(v1:any, b2:bat, nil_matches:bit) :bat
     470             :  * # with candidate list
     471             :  * func(b1:bat, b2:bat, s1:bat, s2:bat, nil_matches:bit) :bat
     472             :  * func(b1:bat, v2:any, s1:bat, nil_matches:bit) :bat
     473             :  * func(v1:any, b2:bat, s2:bat, nil_matches:bit) :bat
     474             :  */
     475             : static str
     476       49642 : CMDbatBINARY1a(MalStkPtr stk, InstrPtr pci,
     477             :                            BAT *(*batfunc)(BAT *, BAT *, BAT *, BAT *, bool),
     478             :                            BAT * (*batfunc1)(BAT *, const ValRecord *, BAT *, bool),
     479             :                            BAT * (*batfunc2)(const ValRecord *, BAT *, BAT *, bool),
     480             :                            bool nil_matches, const char *malfunc)
     481             : {
     482       49642 :         bat bid;
     483       49642 :         BAT *bn, *b1 = NULL, *b2 = NULL, *s1 = NULL, *s2 = NULL;
     484       49642 :         int tp1, tp2;
     485             : 
     486       49642 :         tp1 = stk->stk[getArg(pci, 1)].vtype;        /* first argument */
     487       49642 :         tp2 = stk->stk[getArg(pci, 2)].vtype;        /* second argument */
     488             : 
     489       49642 :         if (tp1 == TYPE_bat || isaBatType(tp1)) {
     490       49415 :                 bid = *getArgReference_bat(stk, pci, 1);
     491       49415 :                 b1 = BATdescriptor(bid);
     492       49415 :                 if (b1 == NULL)
     493           0 :                         goto bailout;
     494             :         }
     495             : 
     496       49642 :         if (tp2 == TYPE_bat || isaBatType(tp2)) {
     497       41326 :                 bid = *getArgReference_bat(stk, pci, 2);
     498       41326 :                 b2 = BATdescriptor(bid);
     499       41319 :                 if (b2 == NULL)
     500           0 :                         goto bailout;
     501             :         }
     502             : 
     503       49635 :         if (pci->argc > 5) {
     504           0 :                 assert(pci->argc == 6);
     505           0 :                 nil_matches = *getArgReference_bit(stk, pci, 5);
     506             :         }
     507       49635 :         if (pci->argc > 4) {
     508         424 :                 if (stk->stk[getArg(pci, 4)].vtype == TYPE_bat) {
     509         424 :                         bid = *getArgReference_bat(stk, pci, 4);
     510         424 :                         if (!is_bat_nil(bid)) {
     511         109 :                                 s2 = BATdescriptor(bid);
     512         109 :                                 if (s2 == NULL)
     513           0 :                                         goto bailout;
     514             :                         }
     515             :                 } else {
     516           0 :                         assert(pci->argc == 5);
     517           0 :                         nil_matches = *getArgReference_bit(stk, pci, 4);
     518             :                 }
     519             :         }
     520       49635 :         if (pci->argc > 3) {
     521       12917 :                 if (stk->stk[getArg(pci, 3)].vtype == TYPE_bat) {
     522        5400 :                         bid = *getArgReference_bat(stk, pci, 3);
     523        5400 :                         if (!is_bat_nil(bid)) {
     524        5035 :                                 s1 = BATdescriptor(bid);
     525        5035 :                                 if (s1 == NULL)
     526           0 :                                         goto bailout;
     527        5035 :                                 if (b1 == NULL) {
     528          67 :                                         s2 = s1;
     529          67 :                                         s1 = NULL;
     530             :                                 }
     531             :                         }
     532             :                 } else {
     533        7517 :                         assert(pci->argc == 4);
     534        7517 :                         nil_matches = *getArgReference_bit(stk, pci, 3);
     535             :                 }
     536             :         }
     537             : 
     538       49635 :         if (b1 && b2)
     539       41092 :                 bn = (*batfunc) (b1, b2, s1, s2, nil_matches);
     540        8543 :         else if (b1)
     541        8316 :                 bn = (*batfunc1) (b1, &stk->stk[getArg(pci, 2)], s1, nil_matches);
     542         227 :         else if (b2)
     543         227 :                 bn = (*batfunc2) (&stk->stk[getArg(pci, 1)], b2, s2, nil_matches);
     544             :         else
     545           0 :                 goto bailout;                   /* cannot happen */
     546       49639 :         BBPreclaim(b1);
     547       49638 :         BBPreclaim(b2);
     548       49634 :         BBPreclaim(s1);
     549       49634 :         BBPreclaim(s2);
     550       49635 :         if (bn == NULL)
     551           0 :                 return mythrow(MAL, malfunc, GDK_EXCEPTION);
     552       49635 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
     553       49635 :         BBPkeepref(bn);
     554       49635 :         return MAL_SUCCEED;
     555             : 
     556           0 :   bailout:
     557           0 :         BBPreclaim(b1);
     558           0 :         BBPreclaim(b2);
     559             : /* cannot happen
     560             :         BBPreclaim(s1);
     561             : */
     562           0 :         BBPreclaim(s2);
     563           0 :         throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     564             : }
     565             : 
     566             : /* MAL function has one of the signatures for CMDbatBINARY2
     567             :  */
     568             : static str
     569       41472 : CMDbatBINARY0(MalStkPtr stk, InstrPtr pci,
     570             :                           BAT *(*batfunc)(BAT *, BAT *, BAT *, BAT *),
     571             :                           BAT * (*batfunc1)(BAT *, const ValRecord *, BAT *),
     572             :                           BAT * (*batfunc2)(const ValRecord *, BAT *, BAT *),
     573             :                           const char *malfunc)
     574             : {
     575       41472 :         bat bid;
     576       41472 :         BAT *bn, *b1 = NULL, *b2 = NULL, *s1 = NULL, *s2 = NULL;
     577       41472 :         int tp1, tp2;
     578             : 
     579       41472 :         tp1 = stk->stk[getArg(pci, 1)].vtype;        /* first argument */
     580       41472 :         tp2 = stk->stk[getArg(pci, 2)].vtype;        /* second argument */
     581             : 
     582       41472 :         if (tp1 == TYPE_bat || isaBatType(tp1)) {
     583       41354 :                 bid = *getArgReference_bat(stk, pci, 1);
     584       41354 :                 b1 = BATdescriptor(bid);
     585       41353 :                 if (b1 == NULL)
     586           0 :                         goto bailout;
     587             :         }
     588             : 
     589       41471 :         if (tp2 == TYPE_bat || isaBatType(tp2)) {
     590       39575 :                 bid = *getArgReference_bat(stk, pci, 2);
     591       39575 :                 b2 = BATdescriptor(bid);
     592       39563 :                 if (b2 == NULL)
     593           0 :                         goto bailout;
     594             :         }
     595             : 
     596       41459 :         if (pci->argc > 4) {
     597        6350 :                 assert(pci->argc == 5);
     598        6350 :                 bid = *getArgReference_bat(stk, pci, 4);
     599        6350 :                 if (!is_bat_nil(bid)) {
     600        3362 :                         s2 = BATdescriptor(bid);
     601        3362 :                         if (s2 == NULL)
     602           0 :                                 goto bailout;
     603             :                 }
     604             :         }
     605       41459 :         if (pci->argc > 3) {
     606        6713 :                 bid = *getArgReference_bat(stk, pci, 3);
     607        6713 :                 if (!is_bat_nil(bid)) {
     608        2680 :                         s1 = BATdescriptor(bid);
     609        2680 :                         if (s1 == NULL)
     610           0 :                                 goto bailout;
     611        2680 :                         if (b1 == NULL) {
     612           1 :                                 s2 = s1;
     613           1 :                                 s1 = NULL;
     614             :                         }
     615             :                 }
     616             :         }
     617             : 
     618       41459 :         if (b1 && b2)
     619       39445 :                 bn = (*batfunc) (b1, b2, s1, s2);
     620        2014 :         else if (b1)
     621        1896 :                 bn = (*batfunc1) (b1, &stk->stk[getArg(pci, 2)], s1);
     622         118 :         else if (b2)
     623         118 :                 bn = (*batfunc2) (&stk->stk[getArg(pci, 1)], b2, s2);
     624             :         else
     625           0 :                 goto bailout;                   /* cannot happen */
     626       41463 :         BBPreclaim(b1);
     627       41466 :         BBPreclaim(b2);
     628       41466 :         BBPreclaim(s1);
     629       41465 :         BBPreclaim(s2);
     630       41464 :         if (bn == NULL)
     631           2 :                 return mythrow(MAL, malfunc, GDK_EXCEPTION);
     632       41462 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
     633       41462 :         BBPkeepref(bn);
     634       41462 :         return MAL_SUCCEED;
     635             : 
     636           0 :   bailout:
     637           0 :         BBPreclaim(b1);
     638           0 :         BBPreclaim(b2);
     639             : /* cannot happen
     640             :         BBPreclaim(s1);
     641             : */
     642           0 :         BBPreclaim(s2);
     643           0 :         throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     644             : }
     645             : 
     646             : static str
     647         389 : CMDbatMIN(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     648             : {
     649         389 :         (void) cntxt;
     650         389 :         (void) mb;
     651             : 
     652         389 :         return CMDbatBINARY0(stk, pci, BATcalcmin, BATcalcmincst, BATcalccstmin,
     653             :                                                  "batcalc.min");
     654             : }
     655             : 
     656             : static str
     657          87 : CMDbatMIN_no_nil(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     658             : {
     659          87 :         (void) cntxt;
     660          87 :         (void) mb;
     661             : 
     662          87 :         return CMDbatBINARY0(stk, pci, BATcalcmin_no_nil, BATcalcmincst_no_nil,
     663             :                                                  BATcalccstmin_no_nil, "batcalc.min_no_nil");
     664             : }
     665             : 
     666             : static str
     667          10 : CMDbatMAX(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     668             : {
     669          10 :         (void) cntxt;
     670          10 :         (void) mb;
     671             : 
     672          10 :         return CMDbatBINARY0(stk, pci, BATcalcmax, BATcalcmaxcst, BATcalccstmax,
     673             :                                                  "batcalc.max");
     674             : }
     675             : 
     676             : static str
     677          17 : CMDbatMAX_no_nil(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     678             : {
     679          17 :         (void) cntxt;
     680          17 :         (void) mb;
     681             : 
     682          17 :         return CMDbatBINARY0(stk, pci, BATcalcmax_no_nil, BATcalcmaxcst_no_nil,
     683             :                                                  BATcalccstmax_no_nil, "batcalc.max_no_nil");
     684             : }
     685             : 
     686             : static str
     687       71909 : CMDbatADDsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     688             : {
     689       71909 :         (void) cntxt;
     690             : 
     691       71909 :         return CMDbatBINARY2(mb, stk, pci, BATcalcadd, BATcalcaddcst, BATcalccstadd,
     692             :                                                  calctype, "batcalc.+");
     693             : }
     694             : 
     695             : static str
     696           0 : CMDbatADDenlarge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     697             : {
     698           0 :         (void) cntxt;
     699             : 
     700           0 :         return CMDbatBINARY2(mb, stk, pci, BATcalcadd, BATcalcaddcst, BATcalccstadd,
     701             :                                                  calctypeenlarge, "batcalc.add_enlarge");
     702             : }
     703             : 
     704             : static str
     705       27612 : CMDbatSUBsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     706             : {
     707       27612 :         (void) cntxt;
     708             : 
     709       27612 :         return CMDbatBINARY2(mb, stk, pci, BATcalcsub, BATcalcsubcst, BATcalccstsub,
     710             :                                                  calctype, "batcalc.-");
     711             : }
     712             : 
     713             : static str
     714           0 : CMDbatSUBenlarge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     715             : {
     716           0 :         (void) cntxt;
     717             : 
     718           0 :         return CMDbatBINARY2(mb, stk, pci, BATcalcsub, BATcalcsubcst, BATcalccstsub,
     719             :                                                  calctypeenlarge, "batcalc.sub_enlarge");
     720             : }
     721             : 
     722             : static str
     723        1423 : CMDbatMULsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     724             : {
     725        1423 :         (void) cntxt;
     726             : 
     727        1423 :         return CMDbatBINARY2(mb, stk, pci, BATcalcmul, BATcalcmulcst, BATcalccstmul,
     728             :                                                  calctype, "batcalc.*");
     729             : }
     730             : 
     731             : static str
     732       25701 : CMDbatMULenlarge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     733             : {
     734       25701 :         (void) cntxt;
     735             : 
     736       25701 :         return CMDbatBINARY2(mb, stk, pci, BATcalcmul, BATcalcmulcst, BATcalccstmul,
     737             :                                                  calctypeenlarge, "batcalc.mul_enlarge");
     738             : }
     739             : 
     740             : static str
     741        3505 : CMDbatDIVsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     742             : {
     743        3505 :         (void) cntxt;
     744             : 
     745        3505 :         return CMDbatBINARY2(mb, stk, pci, BATcalcdiv, BATcalcdivcst, BATcalccstdiv,
     746             :                                                  calcdivtype, "batcalc./");
     747             : }
     748             : 
     749             : static str
     750         591 : CMDbatMODsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     751             : {
     752         591 :         (void) cntxt;
     753             : 
     754         591 :         return CMDbatBINARY2(mb, stk, pci, BATcalcmod, BATcalcmodcst, BATcalccstmod,
     755             :                                                  calcmodtype, "batcalc.%");
     756             : }
     757             : 
     758             : static str
     759          21 : CMDbatXOR(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     760             : {
     761          21 :         (void) cntxt;
     762          21 :         (void) mb;
     763             : 
     764          21 :         return CMDbatBINARY0(stk, pci, BATcalcxor, BATcalcxorcst, BATcalccstxor,
     765             :                                                  "batcalc.xor");
     766             : }
     767             : 
     768             : static str
     769        1624 : CMDbatOR(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     770             : {
     771        1624 :         (void) cntxt;
     772        1624 :         (void) mb;
     773             : 
     774        1624 :         return CMDbatBINARY0(stk, pci, BATcalcor, BATcalcorcst, BATcalccstor,
     775             :                                                  "batcalc.or");
     776             : }
     777             : 
     778             : static str
     779        2357 : CMDbatAND(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     780             : {
     781        2357 :         (void) cntxt;
     782        2357 :         (void) mb;
     783             : 
     784        2357 :         return CMDbatBINARY0(stk, pci, BATcalcand, BATcalcandcst, BATcalccstand,
     785             :                                                  "batcalc.and");
     786             : }
     787             : 
     788             : static str
     789          11 : CMDbatLSHsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     790             : {
     791          11 :         (void) cntxt;
     792          11 :         (void) mb;
     793             : 
     794          11 :         return CMDbatBINARY1(stk, pci, BATcalclsh, BATcalclshcst, BATcalccstlsh,
     795             :                                                  "batcalc.<<");
     796             : }
     797             : 
     798             : static str
     799         223 : CMDbatRSHsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     800             : {
     801         223 :         (void) cntxt;
     802         223 :         (void) mb;
     803             : 
     804         223 :         return CMDbatBINARY1(stk, pci, BATcalcrsh, BATcalcrshcst, BATcalccstrsh,
     805             :                                                  "batcalc.>>");
     806             : }
     807             : 
     808             : static str
     809        8565 : CMDbatLT(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     810             : {
     811        8565 :         (void) cntxt;
     812        8565 :         (void) mb;
     813             : 
     814        8565 :         return CMDbatBINARY0(stk, pci, BATcalclt, BATcalcltcst, BATcalccstlt,
     815             :                                                  "batcalc.<");
     816             : }
     817             : 
     818             : static str
     819        5414 : CMDbatLE(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     820             : {
     821        5414 :         (void) cntxt;
     822        5414 :         (void) mb;
     823             : 
     824        5414 :         return CMDbatBINARY0(stk, pci, BATcalcle, BATcalclecst, BATcalccstle,
     825             :                                                  "batcalc.<=");
     826             : }
     827             : 
     828             : static str
     829       19971 : CMDbatGT(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     830             : {
     831       19971 :         (void) cntxt;
     832       19971 :         (void) mb;
     833             : 
     834       19971 :         return CMDbatBINARY0(stk, pci, BATcalcgt, BATcalcgtcst, BATcalccstgt,
     835             :                                                  "batcalc.>");
     836             : }
     837             : 
     838             : static str
     839        3016 : CMDbatGE(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     840             : {
     841        3016 :         (void) cntxt;
     842        3016 :         (void) mb;
     843             : 
     844        3016 :         return CMDbatBINARY0(stk, pci, BATcalcge, BATcalcgecst, BATcalccstge,
     845             :                                                  "batcalc.>=");
     846             : }
     847             : 
     848             : static str
     849       48390 : CMDbatEQ(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     850             : {
     851       48390 :         (void) cntxt;
     852       48390 :         (void) mb;
     853             : 
     854       48390 :         return CMDbatBINARY1a(stk, pci, BATcalceq, BATcalceqcst, BATcalccsteq,
     855             :                                                   false, "batcalc.==");
     856             : }
     857             : 
     858             : static str
     859        1252 : CMDbatNE(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     860             : {
     861        1252 :         (void) cntxt;
     862        1252 :         (void) mb;
     863             : 
     864        1252 :         return CMDbatBINARY1a(stk, pci, BATcalcne, BATcalcnecst, BATcalccstne,
     865             :                                                   false, "batcalc.!=");
     866             : }
     867             : 
     868             : static str
     869           0 : CMDbatCMP(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     870             : {
     871           0 :         (void) cntxt;
     872           0 :         (void) mb;
     873             : 
     874           0 :         return CMDbatBINARY0(stk, pci, BATcalccmp, BATcalccmpcst, BATcalccstcmp,
     875             :                                                  "batcalc.cmp");
     876             : }
     877             : 
     878             : static str
     879       13009 : CMDbatBETWEEN(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     880             : {
     881       13009 :         bat bid;
     882       13009 :         BAT *bn, *b = NULL, *lo = NULL, *hi = NULL, *s = NULL, *slo = NULL,
     883       13009 :                 *shi = NULL;
     884       13009 :         int tp1, tp2, tp3, tp;
     885       13009 :         int bc = 0;                                     /* number of extra BAT arguments */
     886       13009 :         bool symmetric, linc, hinc, nils_false, anti, has_cand = false;
     887             : 
     888       13009 :         (void) cntxt;
     889       13009 :         (void) mb;
     890             : 
     891       13009 :         tp1 = stk->stk[getArg(pci, 1)].vtype;
     892       13009 :         tp2 = stk->stk[getArg(pci, 2)].vtype;
     893       13009 :         tp3 = stk->stk[getArg(pci, 3)].vtype;
     894       13009 :         if (tp1 != TYPE_bat && !isaBatType(tp1))
     895           0 :                 goto bailout;
     896       13009 :         bid = *getArgReference_bat(stk, pci, 1);
     897       13009 :         b = BATdescriptor(bid);
     898       13009 :         if (b == NULL)
     899           0 :                 goto bailout;
     900       13009 :         if (tp2 == TYPE_bat || isaBatType(tp2)) {
     901       12799 :                 bid = *getArgReference_bat(stk, pci, 2);
     902       12799 :                 lo = BATdescriptor(bid);
     903       12799 :                 if (lo == NULL)
     904           0 :                         goto bailout;
     905             :         }
     906       13009 :         if (tp3 == TYPE_bat || isaBatType(tp3)) {
     907       12794 :                 bid = *getArgReference_bat(stk, pci, 3);
     908       12794 :                 hi = BATdescriptor(bid);
     909       12794 :                 if (hi == NULL)
     910           0 :                         goto bailout;
     911             :         }
     912       13009 :         tp = getArgType(mb, pci, 4);
     913       13009 :         if (tp == TYPE_bat || isaBatType(tp)) {
     914        5671 :                 bid = *getArgReference_bat(stk, pci, 4);
     915        5671 :                 has_cand = true;
     916        5671 :                 if (!is_bat_nil(bid)) {
     917         182 :                         s = BATdescriptor(bid);
     918         182 :                         if (s == NULL)
     919           0 :                                 goto bailout;
     920             :                 }
     921             :                 bc++;
     922             :         }
     923       13009 :         if (has_cand && lo) {
     924        5559 :                 tp = getArgType(mb, pci, 4 + bc);
     925        5559 :                 if (tp == TYPE_bat || isaBatType(tp)) {
     926        5559 :                         bid = *getArgReference_bat(stk, pci, 4 + bc);
     927        5559 :                         if (!is_bat_nil(bid)) {
     928         731 :                                 slo = BATdescriptor(bid);
     929         731 :                                 if (slo == NULL)
     930           0 :                                         goto bailout;
     931             :                         }
     932        5559 :                         bc++;
     933             :                 } else {
     934           0 :                         if (s == NULL) {
     935             :                                 /* apparently the extra bat was a NIL conditional
     936             :                                  * execution bat */
     937             :                                 has_cand = false;
     938             :                         } else
     939           0 :                                 goto bailout;
     940             :                 }
     941             :         }
     942       13009 :         if (has_cand && hi) {
     943        5544 :                 tp = getArgType(mb, pci, 4 + bc);
     944        5544 :                 if (tp != TYPE_bat && !isaBatType(tp))
     945           0 :                         goto bailout;
     946        5544 :                 bid = *getArgReference_bat(stk, pci, 4 + bc);
     947        5544 :                 if (!is_bat_nil(bid)) {
     948         337 :                         shi = BATdescriptor(bid);
     949         337 :                         if (shi == NULL)
     950           0 :                                 goto bailout;
     951             :                 }
     952        5544 :                 bc++;
     953             :         }
     954             : 
     955       13009 :         symmetric = *getArgReference_bit(stk, pci, bc + 4);
     956       13009 :         linc = *getArgReference_bit(stk, pci, bc + 5);
     957       13009 :         hinc = *getArgReference_bit(stk, pci, bc + 6);
     958       13009 :         nils_false = *getArgReference_bit(stk, pci, bc + 7);
     959       13009 :         anti = *getArgReference_bit(stk, pci, bc + 8);
     960             : 
     961       13009 :         if (b && lo && hi)
     962       12751 :                 bn = BATcalcbetween(b, lo, hi, s, slo, shi,
     963             :                                                         symmetric, linc, hinc, nils_false, anti);
     964         258 :         else if (b && lo)
     965          48 :                 bn = BATcalcbetweenbatcst(b, lo, &stk->stk[getArg(pci, 3)], s, slo,
     966             :                                                                   symmetric, linc, hinc, nils_false, anti);
     967         210 :         else if (b && hi)
     968          43 :                 bn = BATcalcbetweencstbat(b, &stk->stk[getArg(pci, 2)], hi, s, shi,
     969             :                                                                   symmetric, linc, hinc, nils_false, anti);
     970             :         else
     971         167 :                 bn = BATcalcbetweencstcst(b, &stk->stk[getArg(pci, 2)],
     972         167 :                                                                   &stk->stk[getArg(pci, 3)], s,
     973             :                                                                   symmetric, linc, hinc, nils_false, anti);
     974       13008 :         BBPunfix(b->batCacheid);
     975       13003 :         BBPreclaim(lo);
     976       13006 :         BBPreclaim(hi);
     977       13005 :         BBPreclaim(s);
     978       13005 :         BBPreclaim(slo);
     979       13006 :         BBPreclaim(shi);
     980       13004 :         if (bn == NULL)
     981           0 :                 return mythrow(MAL, "batcalc.between", OPERATION_FAILED);
     982       13004 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
     983       13004 :         BBPkeepref(bn);
     984       13004 :         return MAL_SUCCEED;
     985             : 
     986           0 :   bailout:
     987           0 :         BBPreclaim(b);
     988           0 :         BBPreclaim(lo);
     989           0 :         BBPreclaim(hi);
     990           0 :         BBPreclaim(s);
     991           0 :         BBPreclaim(slo);
     992             : /* cannot happen
     993             :         BBPreclaim(shi);
     994             : */
     995           0 :         throw(MAL, "batcalc.between", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     996             : }
     997             : 
     998             : static str
     999        4041 : CMDcalcavg(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1000             : {
    1001        4041 :         dbl avg;
    1002        4041 :         BUN vals;
    1003        4041 :         bat bid;
    1004        4041 :         BAT *b, *s = NULL;
    1005        4041 :         gdk_return ret;
    1006        4041 :         int scale = 0;
    1007             : 
    1008        4041 :         (void) cntxt;
    1009        4041 :         (void) mb;
    1010             : 
    1011        4041 :         bid = *getArgReference_bat(stk, pci, pci->retc + 0);
    1012        4041 :         if ((b = BATdescriptor(bid)) == NULL)
    1013           0 :                 throw(MAL, "aggr.avg", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1014        4041 :         if ((pci->argc == pci->retc + 2 &&
    1015           0 :                  stk->stk[pci->argv[pci->retc + 1]].vtype == TYPE_bat) ||
    1016        4041 :                 pci->argc == pci->retc + 3) {
    1017           0 :                 bid = *getArgReference_bat(stk, pci, pci->retc + 1);
    1018           0 :                 if (!is_bat_nil(bid) && (s = BATdescriptor(bid)) == NULL) {
    1019           0 :                         BBPunfix(b->batCacheid);
    1020           0 :                         throw(MAL, "aggr.avg", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1021             :                 }
    1022             :         }
    1023        4041 :         if (pci->argc >= pci->retc + 2 &&
    1024           0 :                 stk->stk[pci->argv[pci->argc - 1]].vtype == TYPE_int) {
    1025           0 :                 scale = *getArgReference_int(stk, pci, pci->argc - 1);
    1026             :         }
    1027        4041 :         ret = BATcalcavg(b, s, &avg, &vals, scale);
    1028        4041 :         BBPunfix(b->batCacheid);
    1029        4041 :         BBPreclaim(s);
    1030        4040 :         if (ret != GDK_SUCCEED)
    1031           0 :                 return mythrow(MAL, "aggr.avg", OPERATION_FAILED);
    1032        4040 :         *getArgReference_dbl(stk, pci, 0) = avg;
    1033        4040 :         if (pci->retc == 2)
    1034        3994 :                 *getArgReference_lng(stk, pci, 1) = vals;
    1035             :         return MAL_SUCCEED;
    1036             : }
    1037             : 
    1038             : static str
    1039      160352 : CMDconvertbat(MalStkPtr stk, InstrPtr pci, int tp)
    1040             : {
    1041      160352 :         bat bid;
    1042      160352 :         BAT *b, *bn, *s = NULL;
    1043             : 
    1044      160352 :         bid = *getArgReference_bat(stk, pci, 1);
    1045      160352 :         if ((b = BATdescriptor(bid)) == NULL)
    1046           0 :                 throw(MAL, "batcalc.convert", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1047      160347 :         if (pci->argc == 3) {
    1048      159253 :                 bid = *getArgReference_bat(stk, pci, 2);
    1049      159253 :                 if (!is_bat_nil(bid) && (s = BATdescriptor(bid)) == NULL) {
    1050           0 :                         BBPunfix(b->batCacheid);
    1051           0 :                         throw(MAL, "batcalc.convert",
    1052             :                                   SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1053             :                 }
    1054       44468 :                 if (s && ATOMtype(s->ttype) != TYPE_oid) {
    1055           0 :                         BBPunfix(b->batCacheid);
    1056           0 :                         BBPreclaim(s);
    1057           0 :                         throw(MAL, "batcalc.convert", SQLSTATE(42000) ILLEGAL_ARGUMENT);
    1058             :                 }
    1059             :         }
    1060             : 
    1061      160346 :         bn = BATconvert(b, s, tp, 0, 0, 0);
    1062      160345 :         BBPunfix(b->batCacheid);
    1063      160313 :         BBPreclaim(s);
    1064      160317 :         if (bn == NULL) {
    1065          12 :                 char buf[20];
    1066          12 :                 snprintf(buf, sizeof(buf), "batcalc.%s", ATOMname(tp));
    1067          12 :                 return mythrow(MAL, buf, OPERATION_FAILED);
    1068             :         }
    1069      160305 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
    1070      160305 :         BBPkeepref(bn);
    1071      160305 :         return MAL_SUCCEED;
    1072             : }
    1073             : 
    1074             : static str
    1075         137 : CMDconvertsignal_bit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1076             : {
    1077         137 :         (void) cntxt;
    1078         137 :         (void) mb;
    1079             : 
    1080         137 :         return CMDconvertbat(stk, pci, TYPE_bit);
    1081             : }
    1082             : 
    1083             : static str
    1084         133 : CMDconvertsignal_bte(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1085             : {
    1086         133 :         (void) cntxt;
    1087         133 :         (void) mb;
    1088             : 
    1089         133 :         return CMDconvertbat(stk, pci, TYPE_bte);
    1090             : }
    1091             : 
    1092             : static str
    1093        6287 : CMDconvertsignal_sht(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1094             : {
    1095        6287 :         (void) cntxt;
    1096        6287 :         (void) mb;
    1097             : 
    1098        6287 :         return CMDconvertbat(stk, pci, TYPE_sht);
    1099             : }
    1100             : 
    1101             : static str
    1102       16387 : CMDconvertsignal_int(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1103             : {
    1104       16387 :         (void) cntxt;
    1105       16387 :         (void) mb;
    1106             : 
    1107       16387 :         return CMDconvertbat(stk, pci, TYPE_int);
    1108             : }
    1109             : 
    1110             : static str
    1111       96749 : CMDconvertsignal_lng(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1112             : {
    1113       96749 :         (void) cntxt;
    1114       96749 :         (void) mb;
    1115             : 
    1116       96749 :         return CMDconvertbat(stk, pci, TYPE_lng);
    1117             : }
    1118             : 
    1119             : #ifdef HAVE_HGE
    1120             : 
    1121             : static str
    1122       37736 : CMDconvertsignal_hge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1123             : {
    1124       37736 :         (void) cntxt;
    1125       37736 :         (void) mb;
    1126             : 
    1127       37736 :         return CMDconvertbat(stk, pci, TYPE_hge);
    1128             : }
    1129             : #endif
    1130             : 
    1131             : static str
    1132         134 : CMDconvertsignal_flt(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1133             : {
    1134         134 :         (void) cntxt;
    1135         134 :         (void) mb;
    1136             : 
    1137         134 :         return CMDconvertbat(stk, pci, TYPE_flt);
    1138             : }
    1139             : 
    1140             : static str
    1141        2364 : CMDconvertsignal_dbl(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1142             : {
    1143        2364 :         (void) cntxt;
    1144        2364 :         (void) mb;
    1145             : 
    1146        2364 :         return CMDconvertbat(stk, pci, TYPE_dbl);
    1147             : }
    1148             : 
    1149             : static str
    1150          15 : CMDconvertsignal_oid(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1151             : {
    1152          15 :         (void) cntxt;
    1153          15 :         (void) mb;
    1154             : 
    1155          15 :         return CMDconvertbat(stk, pci, TYPE_oid);
    1156             : }
    1157             : 
    1158             : static str
    1159         411 : CMDconvertsignal_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1160             : {
    1161         411 :         (void) cntxt;
    1162         411 :         (void) mb;
    1163             : 
    1164         411 :         return CMDconvertbat(stk, pci, TYPE_str);
    1165             : }
    1166             : 
    1167             : static str
    1168        4210 : CMDifthen(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1169             : {
    1170        4210 :         BAT *b = NULL, *b1 = NULL, *b2 = NULL, *bn;
    1171        4210 :         int tp0, tp1, tp2;
    1172        4210 :         bat *ret;
    1173        4210 :         BUN cnt = BUN_NONE;
    1174             : 
    1175        4210 :         (void) cntxt;
    1176        4210 :         (void) mb;
    1177             : 
    1178        4210 :         if (pci->argc != 4)
    1179           0 :                 throw(MAL, "batcalc.ifthen", "Operation not supported.");
    1180             : 
    1181        4210 :         ret = getArgReference_bat(stk, pci, 0);
    1182        4210 :         tp0 = stk->stk[getArg(pci, 1)].vtype;
    1183        4210 :         tp1 = stk->stk[getArg(pci, 2)].vtype;
    1184        4210 :         tp2 = stk->stk[getArg(pci, 3)].vtype;
    1185        4210 :         if (tp0 == TYPE_bat || isaBatType(tp0)) {
    1186        4210 :                 b = BATdescriptor(*getArgReference_bat(stk, pci, 1));
    1187        4210 :                 if (b == NULL)
    1188           0 :                         throw(MAL, "batcalc.ifthenelse",
    1189             :                                   SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1190        4210 :                 cnt = BATcount(b);
    1191             :         }
    1192        4210 :         if (tp1 == TYPE_bat || isaBatType(tp1)) {
    1193         171 :                 b1 = BATdescriptor(*getArgReference_bat(stk, pci, 2));
    1194         171 :                 if (b1 == NULL) {
    1195           0 :                         BBPreclaim(b);
    1196           0 :                         throw(MAL, "batcalc.ifthenelse",
    1197             :                                   SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1198             :                 }
    1199         171 :                 if (cnt == BUN_NONE)
    1200           0 :                         cnt = BATcount(b1);
    1201         171 :                 else if (BATcount(b1) != cnt) {
    1202           0 :                         BBPunfix(b->batCacheid);
    1203           0 :                         throw(MAL, "batcalc.ifthenelse", ILLEGAL_ARGUMENT);
    1204             :                 }
    1205             :         }
    1206        4210 :         if (tp2 == TYPE_bat || isaBatType(tp2)) {
    1207        2855 :                 b2 = BATdescriptor(*getArgReference_bat(stk, pci, 3));
    1208        2855 :                 if (b2 == NULL) {
    1209           0 :                         BBPreclaim(b);
    1210           0 :                         BBPreclaim(b1);
    1211           0 :                         throw(MAL, "batcalc.ifthenelse",
    1212             :                                   SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1213             :                 }
    1214        2855 :                 if (cnt == BUN_NONE)
    1215        4210 :                         cnt = BATcount(b2);
    1216        2855 :                 else if (BATcount(b2) != cnt) {
    1217           0 :                         BBPreclaim(b);
    1218           0 :                         BBPreclaim(b1);
    1219           0 :                         throw(MAL, "batcalc.ifthenelse", ILLEGAL_ARGUMENT);
    1220             :                 }
    1221             :         }
    1222        4210 :         if (b == NULL && b1 == NULL && b2 == NULL) {
    1223             :                 /* at least one BAT required */
    1224           0 :                 throw(MAL, "batcalc.ifthenelse", ILLEGAL_ARGUMENT);
    1225             :         }
    1226        4210 :         if (b != NULL) {
    1227        4210 :                 if (b1 != NULL) {
    1228         171 :                         if (b2 != NULL) {
    1229          46 :                                 bn = BATcalcifthenelse(b, b1, b2);
    1230             :                         } else {
    1231         125 :                                 bn = BATcalcifthenelsecst(b, b1, &stk->stk[getArg(pci, 3)]);
    1232             :                         }
    1233             :                 } else {
    1234        4039 :                         if (b2 != NULL) {
    1235        2809 :                                 bn = BATcalcifthencstelse(b, &stk->stk[getArg(pci, 2)], b2);
    1236             :                         } else {
    1237        1230 :                                 bn = BATcalcifthencstelsecst(b, &stk->stk[getArg(pci, 2)],
    1238        1230 :                                                                                          &stk->stk[getArg(pci, 3)]);
    1239             :                         }
    1240             :                 }
    1241             :         } else {
    1242           0 :                 bit v;
    1243           0 :                 if (tp0 == TYPE_msk)
    1244           0 :                         v = (bit) *getArgReference_msk(stk, pci, 1);
    1245             :                 else
    1246           0 :                         v = *getArgReference_bit(stk, pci, 1);
    1247           0 :                 if (is_bit_nil(v)) {
    1248           0 :                         if (b1 != NULL)
    1249           0 :                                 bn = BATconstant(b1->hseqbase, b1->ttype, ATOMnilptr(b1->ttype),
    1250             :                                                                  BATcount(b1), TRANSIENT);
    1251             :                         else
    1252           0 :                                 bn = BATconstant(b2->hseqbase, b2->ttype, ATOMnilptr(b2->ttype),
    1253             :                                                                  BATcount(b2), TRANSIENT);
    1254           0 :                 } else if (v) {
    1255           0 :                         if (b1 != NULL)
    1256           0 :                                 bn = COLcopy(b1, b1->ttype, false, TRANSIENT);
    1257             :                         else
    1258           0 :                                 bn = BATconstant(b2->hseqbase, b2->ttype,
    1259           0 :                                                                  VALptr(&stk->stk[getArg(pci, 2)]),
    1260             :                                                                  BATcount(b2), TRANSIENT);
    1261             :                 } else {
    1262           0 :                         if (b2 != NULL)
    1263           0 :                                 bn = COLcopy(b2, b2->ttype, false, TRANSIENT);
    1264             :                         else
    1265           0 :                                 bn = BATconstant(b1->hseqbase, b1->ttype,
    1266           0 :                                                                  VALptr(&stk->stk[getArg(pci, 3)]),
    1267             :                                                                  BATcount(b1), TRANSIENT);
    1268             :                 }
    1269             :         }
    1270        4210 :         BBPreclaim(b);
    1271        4210 :         BBPreclaim(b1);
    1272        4210 :         BBPreclaim(b2);
    1273        4210 :         if (bn == NULL) {
    1274           0 :                 return mythrow(MAL, "batcalc.ifthenelse", OPERATION_FAILED);
    1275             :         }
    1276        4210 :         *ret = bn->batCacheid;
    1277        4210 :         BBPkeepref(bn);
    1278        4210 :         return MAL_SUCCEED;
    1279             : }
    1280             : 
    1281             : #include "mel.h"
    1282             : 
    1283             : static str
    1284         336 : batcalc_init(void)
    1285             : {
    1286         336 :         int types[16], cur = 0, *tp;
    1287         336 :         int specials[4];
    1288         336 :         int *integer, *floats, *extra;
    1289             : 
    1290         336 :         types[cur++] = TYPE_bit;
    1291         336 :         integer = types+cur;
    1292         336 :         types[cur++] = TYPE_bte;
    1293         336 :         types[cur++] = TYPE_sht;
    1294         336 :         types[cur++] = TYPE_int;
    1295         336 :         types[cur++] = TYPE_lng;
    1296             : #ifdef HAVE_HGE
    1297         336 :         types[cur++] = TYPE_hge;
    1298             : #endif
    1299         336 :         floats = types+cur;
    1300         336 :         types[cur++] = TYPE_flt;
    1301         336 :         types[cur++] = TYPE_dbl;
    1302         336 :         extra = types+cur;
    1303         336 :         types[cur++] = TYPE_oid;
    1304         336 :         types[cur++] = TYPE_str;
    1305             : 
    1306         336 :         cur = 0;
    1307         336 :         specials[cur++] = TYPE_bit;
    1308         336 :         specials[cur++] = TYPE_oid;
    1309         336 :         specials[cur++] = TYPE_str;
    1310             : 
    1311         336 :         mel_func_arg cand = { .type = TYPE_oid, .isbat=1 };
    1312             : 
    1313         336 :         int err=0;
    1314             :         /* for all numeric types, use reverse order */
    1315        2688 :         for(tp = integer; tp < extra && !err; tp++) {
    1316        2352 :                 mel_func_arg ret = { .type = TYPE_bit, .isbat=1 };
    1317        2352 :                 mel_func_arg arg = { .type = *tp, .isbat=1 };
    1318             : 
    1319        2352 :                 err += melFunction(false, "batcalc", "iszero", (MALfcn)&CMDbatISZERO, "CMDbatISZERO", false, "Unary check for zero over the tail of the bat", 1, 2, ret, arg);
    1320        2352 :                 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);
    1321             :         }
    1322        3024 :         for(tp = types; tp < extra && !err; tp++) { /* bit + numeric */
    1323        2688 :                 mel_func_arg ret = { .type = *tp, .isbat =1 };
    1324        2688 :                 mel_func_arg arg = { .type = *tp, .isbat =1 };
    1325             : 
    1326        2688 :                 err += melFunction(false, "batcalc", "not", (MALfcn)&CMDbatNOT, "CMDbatNOT", false, "Unary bitwise not over the tail of the bat", 1, 2, ret, arg);
    1327        2688 :                 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);
    1328             :         }
    1329        2688 :         for(tp = integer; tp < extra && !err; tp++) {
    1330        2352 :                 mel_func_arg ret = { .type = TYPE_bte, .isbat =1 };
    1331        2352 :                 mel_func_arg arg = { .type = *tp, .isbat =1 };
    1332             : 
    1333        2352 :                 err += melFunction(false, "batcalc", "sign", (MALfcn)&CMDbatSIGN, "CMDbatSIGN", false, "Unary sign (-1,0,1) over the tail of the bat", 1, 2, ret, arg);
    1334        2352 :                 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);
    1335             :         }
    1336        2688 :         for(tp = integer; tp < extra && !err; tp++) {
    1337        2352 :                 mel_func_arg ret = { .type = *tp, .isbat =1 };
    1338        2352 :                 mel_func_arg arg = { .type = *tp, .isbat =1 };
    1339             : 
    1340        2352 :                 err += melFunction(false, "batcalc", "abs", (MALfcn)&CMDbatABS, "CMDbatABS", false, "Unary abs over the tail of the bat", 1, 2, ret, arg);
    1341        2352 :                 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);
    1342             : 
    1343        2352 :                 err += melFunction(false, "batcalc", "-", (MALfcn)&CMDbatNEG, "CMDbatNEG", false, "Unary neg over the tail of the bat", 1, 2, ret, arg);
    1344        2352 :                 err += melFunction(false, "batcalc", "-", (MALfcn)&CMDbatNEG, "CMDbatNEG", false, "Unary neg over the tail of the bat with candidates list", 1, 3, ret, arg, cand);
    1345             : 
    1346        2352 :                 err += melFunction(false, "batcalc", "++", (MALfcn)&CMDbatINCR, "CMDbatINCR", false, "Unary increment over the tail of the bat", 1, 2, ret, arg);
    1347        2352 :                 err += melFunction(false, "batcalc", "++", (MALfcn)&CMDbatINCR, "CMDbatINCR", false, "Unary increment over the tail of the bat with candidates list", 1, 3, ret, arg, cand);
    1348             : 
    1349        2352 :                 err += melFunction(false, "batcalc", "--", (MALfcn)&CMDbatDECR, "CMDbatDECR", false, "Unary decrement over the tail of the bat", 1, 2, ret, arg);
    1350        2352 :                 err += melFunction(false, "batcalc", "--", (MALfcn)&CMDbatDECR, "CMDbatDECR", false, "Unary decrement over the tail of the bat with candidates list", 1, 3, ret, arg, cand);
    1351             :         }
    1352             :         /* possibly add the min/max + _no_nil */
    1353             :         /* binops on numeric types */
    1354         336 :         struct {
    1355             :                 char *op;
    1356             :                 char *fname;
    1357             :                 char *fname_el;
    1358             :                 MALfcn fcn;
    1359             :                 MALfcn fcn_el;
    1360             :                 char *comment;
    1361             :                 char *comment_v;
    1362             :                 char *comment_v_;
    1363             :                 char *comment_el;
    1364             :                 char *comment_el_v;
    1365             :                 char *comment_el_v_;
    1366         336 :         } funcs[3] = {
    1367             :                 {
    1368             :                         .op = "+",
    1369             :                         .fcn = (MALfcn)CMDbatADDsignal,
    1370             :                         .fname = "CMDbatADDsignal",
    1371             :                         .fcn_el = (MALfcn)&CMDbatADDenlarge,
    1372             :                         .fname_el = "CMDbatADDenlarge",
    1373             :                         .comment = "Return B1 + B2 with candidates list, signal error on overflow",
    1374             :                         .comment_v = "Return B + V with candidates list, signal error on overflow",
    1375             :                         .comment_v_ = "Return V + B with candidates list, signal error on overflow",
    1376             :                         .comment_el = "Return B1 + B2 with candidates list, guarantee no overflow by returning larger type",
    1377             :                         .comment_el_v = "Return B + V with candidates list, guarantee no overflow by returning larger type",
    1378             :                         .comment_el_v_ = "Return V + B with candidates list, guarantee no overflow by returning larger type",
    1379             :                 }, {
    1380             :                         .op = "-",
    1381             :                         .fcn = (MALfcn)CMDbatSUBsignal,
    1382             :                         .fname = "CMDbatSUBsignal",
    1383             :                         .fcn_el = (MALfcn)&CMDbatSUBenlarge,
    1384             :                         .fname_el = "CMDbatSUBenlarge",
    1385             :                         .comment = "Return B1 - B2 with candidates list, signal error on overflow",
    1386             :                         .comment_v = "Return B - V with candidates list, signal error on overflow",
    1387             :                         .comment_v_ = "Return V - B with candidates list, signal error on overflow",
    1388             :                         .comment_el = "Return B1 - B2 with candidates list, guarantee no overflow by returning larger type",
    1389             :                         .comment_el_v = "Return B - V with candidates list, guarantee no overflow by returning larger type",
    1390             :                         .comment_el_v_ = "Return V - B with candidates list, guarantee no overflow by returning larger type",
    1391             :                 }, {
    1392             :                         .op = "*",
    1393             :                         .fcn = (MALfcn)CMDbatMULsignal,
    1394             :                         .fname = "CMDbatMULsignal",
    1395             :                         .fcn_el = (MALfcn)&CMDbatMULenlarge,
    1396             :                         .fname_el = "CMDbatMULenlarge",
    1397             :                         .comment = "Return B1 * B2 with candidates list, signal error on overflow",
    1398             :                         .comment_v = "Return B * V with candidates list, signal error on overflow",
    1399             :                         .comment_v_ = "Return V * B with candidates list, signal error on overflow",
    1400             :                         .comment_el = "Return B1 * B2 with candidates list, guarantee no overflow by returning larger type",
    1401             :                         .comment_el_v = "Return B * V with candidates list, guarantee no overflow by returning larger type",
    1402             :                         .comment_el_v_ = "Return V * B with candidates list, guarantee no overflow by returning larger type",
    1403             :                 }
    1404             :         };
    1405        1344 :         for (int f=0; f<3; f++) {
    1406             :                 int *tp1, *tp2, *rt;
    1407        8064 :                 for(tp1 = integer; tp1 < extra && !err; tp1++) {
    1408       56448 :                         for(tp2 = integer; tp2 < extra && !err; tp2++) {
    1409      395136 :                                 for(rt = extra-1; rt >= integer && !err; rt--) {
    1410      345744 :                                         if (f!=3 && (*rt < *tp1 || *rt < *tp2))
    1411      204624 :                                                 continue;
    1412      141120 :                                         mel_func_arg ret = { .type = *rt, .isbat =1 };
    1413      141120 :                                         mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1414      141120 :                                         mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1415      141120 :                                         mel_func_arg varg1 = { .type = *tp1 };
    1416      141120 :                                         mel_func_arg varg2 = { .type = *tp2 };
    1417             : 
    1418      141120 :                                         if (*rt == *tp1 || *rt == *tp2 || f==3) {
    1419       49392 :                                                 err += melFunction(false, "batcalc", funcs[f].op, funcs[f].fcn, funcs[f].fname, false, funcs[f].comment, 1, 5, ret, arg1, arg2, cand, cand);
    1420       49392 :                                                 err += melFunction(false, "batcalc", funcs[f].op, funcs[f].fcn, funcs[f].fname, false, funcs[f].comment_v, 1, 4, ret, arg1, varg2, cand);
    1421       49392 :                                                 err += melFunction(false, "batcalc", funcs[f].op, funcs[f].fcn, funcs[f].fname, false, funcs[f].comment_v_, 1, 4, ret, varg1, arg2, cand);
    1422             :                                         } else {
    1423       91728 :                                                 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);
    1424       91728 :                                                 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);
    1425       91728 :                                                 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);
    1426             :                                         }
    1427             :                                 }
    1428             :                         }
    1429             :                 }
    1430             :         }
    1431             :         {       /* multiplication between integers and floating-points, returning integers */
    1432             :                 int *tp1, *tp2, *tp3;
    1433        2016 :                 for(tp1 = integer; tp1 < floats && !err; tp1++) {
    1434        5040 :                         for(tp2 = floats; tp2 < extra && !err; tp2++) {
    1435       20160 :                                 for(tp3 = integer; tp3 < floats && !err; tp3++) {
    1436       16800 :                                         int in1 = *tp3, in2 = *tp2;
    1437             : 
    1438       50400 :                                         for (int i = 0 ; i < 2 ; i++) {
    1439       33600 :                                                 mel_func_arg ret = { .type = *tp1, .isbat =1 };
    1440       33600 :                                                 mel_func_arg arg1 = { .type = in1, .isbat =1 };
    1441       33600 :                                                 mel_func_arg arg2 = { .type = in2, .isbat =1 };
    1442       33600 :                                                 mel_func_arg varg1 = { .type = in1 };
    1443       33600 :                                                 mel_func_arg varg2 = { .type = in2 };
    1444             : 
    1445       33600 :                                                 err += melFunction(false, "batcalc", funcs[2].op, funcs[2].fcn, funcs[2].fname, false, funcs[2].comment, 1, 5, ret, arg1, arg2, cand, cand);
    1446       33600 :                                                 err += melFunction(false, "batcalc", funcs[2].op, funcs[2].fcn, funcs[2].fname, false, funcs[2].comment_v, 1, 4, ret, arg1, varg2, cand);
    1447       33600 :                                                 err += melFunction(false, "batcalc", funcs[2].op, funcs[2].fcn, funcs[2].fname, false, funcs[2].comment_v_, 1, 4, ret, varg1, arg2, cand);
    1448             : 
    1449             :                                                 /* swap variables */
    1450       33600 :                                                 in1 ^= in2;
    1451       33600 :                                                 in2 ^= in1;
    1452       33600 :                                                 in1 ^= in2;
    1453             :                                         }
    1454             :                                 }
    1455             :                         }
    1456             :                 }
    1457             :         }
    1458         336 :         struct {
    1459             :                 char *op;
    1460             :                 char *fname;
    1461             :                 char *fname_el;
    1462             :                 MALfcn fcn;
    1463             :                 MALfcn fcn_el;
    1464             :                 char *comment;
    1465             :                 char *comment_v;
    1466             :                 char *comment_v_;
    1467             :                 char *comment_el;
    1468             :                 char *comment_el_v;
    1469             :                 char *comment_el_v_;
    1470         336 :         } div = {
    1471             :                 .op = "/",
    1472             :                 .fcn = (MALfcn)CMDbatDIVsignal,
    1473             :                 .fname = "CMDbatDIVsignal",
    1474             :                 .comment = "Return B1 / B2 with candidates list, signal error on overflow",
    1475             :                 .comment_v = "Return B / V with candidates list, signal error on overflow",
    1476             :                 .comment_v_ = "Return V / B with candidates list, signal error on overflow",
    1477             :         };
    1478         336 :         int *tp1, *tp2, *rt;
    1479        2688 :         for(tp1 = integer; tp1 < extra && !err; tp1++) {
    1480       18816 :             for(tp2 = integer; tp2 < extra && !err; tp2++) {
    1481       82320 :                         for(rt = extra-1; rt >= tp1 && !err; rt--) {
    1482       65856 :                                 mel_func_arg ret = { .type = *rt, .isbat =1 };
    1483       65856 :                                 mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1484       65856 :                                 mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1485       65856 :                                 mel_func_arg varg1 = { .type = *tp1 };
    1486       65856 :                                 mel_func_arg varg2 = { .type = *tp2 };
    1487             : 
    1488       65856 :                                 err += melFunction(false, "batcalc", div.op, div.fcn, div.fname, false, div.comment, 1, 5, ret, arg1, arg2, cand, cand);
    1489       65856 :                                 err += melFunction(false, "batcalc", div.op, div.fcn, div.fname, false, div.comment_v, 1, 4, ret, arg1, varg2, cand);
    1490       65856 :                                 err += melFunction(false, "batcalc", div.op, div.fcn, div.fname, false, div.comment_v_, 1, 4, ret, varg1, arg2, cand);
    1491             :                         }
    1492             :             }
    1493             :         }
    1494             :         /* division between integers and floating-points, returning integers */
    1495        1008 :         for(tp1 = floats; tp1 < extra && !err; tp1++) {
    1496        4032 :             for(tp2 = integer; tp2 < floats && !err; tp2++) {
    1497       20160 :                         for(rt = integer; rt < floats && !err; rt++) {
    1498       16800 :                                 mel_func_arg ret = { .type = *rt, .isbat =1 };
    1499       16800 :                                 mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1500       16800 :                                 mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1501       16800 :                                 mel_func_arg varg1 = { .type = *tp1 };
    1502       16800 :                                 mel_func_arg varg2 = { .type = *tp2 };
    1503             : 
    1504       16800 :                                 err += melFunction(false, "batcalc", div.op, div.fcn, div.fname, false, div.comment, 1, 5, ret, arg1, arg2, cand, cand);
    1505       16800 :                                 err += melFunction(false, "batcalc", div.op, div.fcn, div.fname, false, div.comment_v, 1, 4, ret, arg1, varg2, cand);
    1506       16800 :                                 err += melFunction(false, "batcalc", div.op, div.fcn, div.fname, false, div.comment_v_, 1, 4, ret, varg1, arg2, cand);
    1507             :                         }
    1508             :             }
    1509             :         }
    1510             :         struct {
    1511             :                 char *op;
    1512             :                 char *fname;
    1513             :                 MALfcn fcn;
    1514             :                 char *comment;
    1515             :                 char *comment_v;
    1516             :                 char *comment_v_;
    1517             :         } mods = {
    1518             :                 .op = "%",
    1519             :                 .fcn = (MALfcn)CMDbatMODsignal,
    1520             :                 .fname = "CMDbatMODsignal",
    1521             :                 .comment = "Return B1 % B2 with candidates list, signal error on overflow",
    1522             :                 .comment_v = "Return B % V with candidates list, signal error on overflow",
    1523             :                 .comment_v_ = "Return V % B with candidates list, signal error on overflow",
    1524             :         };
    1525        2688 :         for(tp1 = integer; tp1 < extra && !err; tp1++) {
    1526       18816 :             for(tp2 = integer; tp2 < extra && !err; tp2++) {
    1527      131712 :                         for(rt = extra-1; rt >= integer && !err; rt--) {
    1528      115248 :                                 if (rt < tp1 && rt < tp2)
    1529       82656 :                                         continue;
    1530       84672 :                                 if (*rt == TYPE_dbl) {
    1531       16464 :                                         if (*tp1 != TYPE_dbl || *tp2 != TYPE_dbl)
    1532       16128 :                                                 continue;
    1533       68208 :                                 } else if (*rt == TYPE_flt) {
    1534       16128 :                                         if (*tp1 != TYPE_flt || *tp2 != TYPE_flt)
    1535       15792 :                                                 continue;
    1536             :                                 } else {
    1537       52080 :                                         if (*tp1 == TYPE_flt || *tp2 == TYPE_flt || *tp1 == TYPE_dbl || *tp2 == TYPE_dbl)
    1538       20160 :                                                 continue;
    1539             :                                 }
    1540       32592 :                                 mel_func_arg ret = { .type = *rt, .isbat =1 };
    1541       32592 :                                 mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1542       32592 :                                 mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1543       32592 :                                 mel_func_arg varg1 = { .type = *tp1 };
    1544       32592 :                                 mel_func_arg varg2 = { .type = *tp2 };
    1545             : 
    1546       32592 :                                 err += melFunction(false, "batcalc", mods.op, mods.fcn, mods.fname, false, mods.comment, 1, 5, ret, arg1, arg2, cand, cand);
    1547       32592 :                                 err += melFunction(false, "batcalc", mods.op, mods.fcn, mods.fname, false, mods.comment_v, 1, 4, ret, arg1, varg2, cand);
    1548       32592 :                                 err += melFunction(false, "batcalc", mods.op, mods.fcn, mods.fname, false, mods.comment_v_, 1, 4, ret, varg1, arg2, cand);
    1549             :                         }
    1550             :             }
    1551             :         }
    1552         336 :         struct {
    1553             :                 char *op;
    1554             :                 char *fname;
    1555             :                 MALfcn fcn;
    1556             :                 char *comment;
    1557             :                 char *comment_v;
    1558             :                 char *comment_v_;
    1559         336 :         } logops[3] = {
    1560             :                 {
    1561             :                         .op = "and",
    1562             :                         .fcn = (MALfcn)CMDbatAND,
    1563             :                         .fname = "CMDbatAND",
    1564             :                         .comment = "Return B1 and B2",
    1565             :                         .comment_v = "Return B and V",
    1566             :                         .comment_v_ = "Return V and B",
    1567             :                 }, {
    1568             :                         .op = "or",
    1569             :                         .fcn = (MALfcn)CMDbatOR,
    1570             :                         .fname = "CMDbatOR",
    1571             :                         .comment = "Return B1 or B2",
    1572             :                         .comment_v = "Return B or V",
    1573             :                         .comment_v_ = "Return V or B",
    1574             :                 }, {
    1575             :                         .op = "xor",
    1576             :                         .fcn = (MALfcn)CMDbatXOR,
    1577             :                         .fname = "CMDbatXOR",
    1578             :                         .comment = "Return B1 xor B2",
    1579             :                         .comment_v = "Return B xor V",
    1580             :                         .comment_v_ = "Return V xor B",
    1581             :                 }
    1582             :         };
    1583        1344 :         for (int f=0; f<3; f++) {
    1584        9072 :                 for(tp = types+0; tp < extra && !err; tp++) {
    1585        8064 :                         mel_func_arg ret = { .type = *tp, .isbat =1 };
    1586        8064 :                         mel_func_arg arg = { .type = *tp, .isbat =1 };
    1587        8064 :                         mel_func_arg varg = { .type = *tp };
    1588             : 
    1589        8064 :                         err += melFunction(false, "batcalc", logops[f].op, logops[f].fcn, logops[f].fname, false, logops[f].comment, 1, 3, ret, arg, arg);
    1590        8064 :                         err += melFunction(false, "batcalc", logops[f].op, logops[f].fcn, logops[f].fname, false, logops[f].comment, 1, 5, ret, arg, arg, cand, cand);
    1591        8064 :                         err += melFunction(false, "batcalc", logops[f].op, logops[f].fcn, logops[f].fname, false, logops[f].comment_v, 1, 3, ret, arg, varg);
    1592        8064 :                         err += melFunction(false, "batcalc", logops[f].op, logops[f].fcn, logops[f].fname, false, logops[f].comment_v, 1, 4, ret, arg, varg, cand);
    1593        8064 :                         err += melFunction(false, "batcalc", logops[f].op, logops[f].fcn, logops[f].fname, false, logops[f].comment_v_, 1, 3, ret, varg, arg);
    1594        8064 :                         err += melFunction(false, "batcalc", logops[f].op, logops[f].fcn, logops[f].fname, false, logops[f].comment_v_, 1, 4, ret, varg, arg, cand);
    1595             :                 }
    1596             :         }
    1597         336 :         struct {
    1598             :                 char *op;
    1599             :                 char *fname;
    1600             :                 MALfcn fcn;
    1601             :                 char *comment;
    1602             :                 char *comment_v;
    1603             :                 char *comment_v_;
    1604         336 :         } shifts[2] = {
    1605             :                 {
    1606             :                         .op = "<<",
    1607             :                         .fcn = (MALfcn)CMDbatLSHsignal,
    1608             :                         .fname = "CMDbatLSHsignal",
    1609             :                         .comment = "Return B1 << B2, raise error on out of range second operand",
    1610             :                         .comment_v = "Return B << V, raise error on out of range second operand",
    1611             :                         .comment_v_ = "Return B << V, raise error on out of range second operand",
    1612             :                 }, {
    1613             :                         .op = ">>",
    1614             :                         .fcn = (MALfcn)CMDbatRSHsignal,
    1615             :                         .fname = "CMDbatRSHsignal",
    1616             :                         .comment = "Return B1 >> B2, raise error on out of range second operand",
    1617             :                         .comment_v = "Return B >> V, raise error on out of range second operand",
    1618             :                         .comment_v_ = "Return B >> V, raise error on out of range second operand",
    1619             :                 }
    1620             :         };
    1621        1008 :         for (int f=0; f<2; f++) {
    1622             :                 int *tp1, *tp2;
    1623        4032 :                 for(tp1 = integer; tp1 < floats && !err; tp1++) {
    1624       20160 :                         for(tp2 = integer; tp2 < floats && !err; tp2++) {
    1625       16800 :                                 mel_func_arg ret = { .type = *tp1, .isbat =1 };
    1626       16800 :                                 mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1627       16800 :                                 mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1628       16800 :                                 mel_func_arg varg1 = { .type = *tp1 };
    1629       16800 :                                 mel_func_arg varg2 = { .type = *tp2 };
    1630             : 
    1631       16800 :                                 err += melFunction(false, "batcalc", shifts[f].op, shifts[f].fcn, shifts[f].fname, false, shifts[f].comment, 1, 3, ret, arg1, arg2);
    1632       16800 :                                 err += melFunction(false, "batcalc", shifts[f].op, shifts[f].fcn, shifts[f].fname, false, shifts[f].comment, 1, 5, ret, arg1, arg2, cand, cand);
    1633       16800 :                                 err += melFunction(false, "batcalc", shifts[f].op, shifts[f].fcn, shifts[f].fname, false, shifts[f].comment_v, 1, 3, ret, arg1, varg2);
    1634       16800 :                                 err += melFunction(false, "batcalc", shifts[f].op, shifts[f].fcn, shifts[f].fname, false, shifts[f].comment_v, 1, 4, ret, arg1, varg2, cand);
    1635       16800 :                                 err += melFunction(false, "batcalc", shifts[f].op, shifts[f].fcn, shifts[f].fname, false, shifts[f].comment_v_, 1, 3, ret, varg1, arg2);
    1636       16800 :                                 err += melFunction(false, "batcalc", shifts[f].op, shifts[f].fcn, shifts[f].fname, false, shifts[f].comment_v_, 1, 4, ret, varg1, arg2, cand);
    1637             :                         }
    1638             :                 }
    1639             :         }
    1640             : 
    1641         336 :         struct {
    1642             :                 char *op;
    1643             :                 char *fname;
    1644             :                 MALfcn fcn;
    1645             :                 char *comment;
    1646             :                 char *comment_v;
    1647             :                 char *comment_v_;
    1648         336 :         } cmps[6] = {
    1649             :                 {
    1650             :                         .op = "<",
    1651             :                         .fcn = (MALfcn)CMDbatLT,
    1652             :                         .fname = "CMDbatLT",
    1653             :                         .comment = "Return B1 < B2",
    1654             :                         .comment_v = "Return B < V",
    1655             :                         .comment_v_ = "Return B < V",
    1656             :                 }, {
    1657             :                         .op = "<=",
    1658             :                         .fcn = (MALfcn)CMDbatLE,
    1659             :                         .fname = "CMDbatLE",
    1660             :                         .comment = "Return B1 <= B2",
    1661             :                         .comment_v = "Return B <= V",
    1662             :                         .comment_v_ = "Return B <= V",
    1663             :                 }, {
    1664             :                         .op = ">",
    1665             :                         .fcn = (MALfcn)CMDbatGT,
    1666             :                         .fname = "CMDbatGT",
    1667             :                         .comment = "Return B1 > B2",
    1668             :                         .comment_v = "Return B > V",
    1669             :                         .comment_v_ = "Return B > V",
    1670             :                 }, {
    1671             :                         .op = ">=",
    1672             :                         .fcn = (MALfcn)CMDbatGE,
    1673             :                         .fname = "CMDbatGE",
    1674             :                         .comment = "Return B1 >= B2",
    1675             :                         .comment_v = "Return B >= V",
    1676             :                         .comment_v_ = "Return B >= V",
    1677             :                 }, {
    1678             :                         .op = "==",
    1679             :                         .fcn = (MALfcn)CMDbatEQ,
    1680             :                         .fname = "CMDbatEQ",
    1681             :                         .comment = "Return B1 == B2",
    1682             :                         .comment_v = "Return B == V",
    1683             :                         .comment_v_ = "Return B == V",
    1684             :                 }, {
    1685             :                         .op = "!=",
    1686             :                         .fcn = (MALfcn)CMDbatNE,
    1687             :                         .fname = "CMDbatNE",
    1688             :                         .comment = "Return B1 != B2",
    1689             :                         .comment_v = "Return B != V",
    1690             :                         .comment_v_ = "Return B != V",
    1691             :                 }
    1692             :         };
    1693         336 :         int newtypes[6] = { ATOMindex("json"), ATOMindex("inet"), ATOMindex("uuid"), TYPE_date, TYPE_daytime, TYPE_timestamp };
    1694        2352 :         for (int f=0; f<6; f++) {
    1695        2016 :                 mel_func_arg ret = { .type = TYPE_bit, .isbat =1 };
    1696        2016 :                 mel_func_arg arg = { .type = TYPE_any, .isbat =1, .nr=1 };
    1697        2016 :                 mel_func_arg varg = { .type = TYPE_any, .nr=1 };
    1698             : 
    1699        2016 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 3, ret, arg, arg);
    1700        2016 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 5, ret, arg, arg, cand, cand);
    1701        2016 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 3, ret, arg, varg);
    1702        2016 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 4, ret, arg, varg, cand);
    1703        2016 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 3, ret, varg, arg);
    1704        2016 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 4, ret, varg, arg, cand);
    1705             : 
    1706        2016 :                 if (strcmp(cmps[f].op,"==")==0 || strcmp(cmps[f].op,"!=")==0) {
    1707         672 :                         mel_func_arg nil_matches = { .type = TYPE_bit };
    1708             : 
    1709         672 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 4, ret, arg, arg, nil_matches);
    1710         672 :                         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);
    1711         672 :                         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);
    1712         672 :                         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);
    1713         672 :                         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);
    1714         672 :                         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);
    1715             :                 }
    1716             : 
    1717             :                 /* uuid, json, inet and mtime (date, daytime, timestamp) */
    1718       14112 :                 for (int nt = 0; nt < 6; nt++) {
    1719       12096 :                         mel_func_arg ret = { .type = TYPE_bit, .isbat =1 };
    1720       12096 :                         mel_func_arg arg = { .type = newtypes[nt], .isbat =1, .nr=1 };
    1721       12096 :                         mel_func_arg varg = { .type = newtypes[nt], .nr=1 };
    1722             : 
    1723       12096 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 3, ret, arg, arg);
    1724       12096 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 5, ret, arg, arg, cand, cand);
    1725       12096 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 3, ret, arg, varg);
    1726       12096 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 4, ret, arg, varg, cand);
    1727       12096 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 3, ret, varg, arg);
    1728       12096 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 4, ret, varg, arg, cand);
    1729             : 
    1730       12096 :                         if (strcmp(cmps[f].op,"==")==0 || strcmp(cmps[f].op,"!=")==0) {
    1731        4032 :                                 mel_func_arg nil_matches = { .type = TYPE_bit };
    1732             : 
    1733        4032 :                                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 4, ret, arg, arg, nil_matches);
    1734        4032 :                                 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);
    1735        4032 :                                 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);
    1736        4032 :                                 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);
    1737        4032 :                                 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);
    1738        4032 :                                 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);
    1739             :                         }
    1740             :                 }
    1741             : 
    1742             :                 int *tp1, *tp2;
    1743       12096 :                 for(tp1 = integer; tp1 < floats && !err; tp1++) {
    1744       60480 :                         for(tp2 = integer; tp2 < floats && !err; tp2++) {
    1745       50400 :                                 if (*tp1 == *tp2)
    1746       10080 :                                         continue;
    1747       40320 :                                 mel_func_arg ret = { .type = TYPE_bit, .isbat =1 };
    1748       40320 :                                 mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1749       40320 :                                 mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1750       40320 :                                 mel_func_arg varg1 = { .type = *tp1 };
    1751       40320 :                                 mel_func_arg varg2 = { .type = *tp2 };
    1752             : 
    1753       40320 :                                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 3, ret, arg1, arg2);
    1754       40320 :                                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 5, ret, arg1, arg2, cand, cand);
    1755       40320 :                                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 3, ret, arg1, varg2);
    1756       40320 :                                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 4, ret, arg1, varg2, cand);
    1757       40320 :                                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 3, ret, varg1, arg2);
    1758       40320 :                                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 4, ret, varg1, arg2, cand);
    1759             : 
    1760       40320 :                                 if (strcmp(cmps[f].op,"==")==0 || strcmp(cmps[f].op,"!=")==0) {
    1761       13440 :                                         mel_func_arg nil_matches = { .type = TYPE_bit };
    1762             : 
    1763       13440 :                                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 4, ret, arg1, arg2, nil_matches);
    1764       13440 :                                         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);
    1765       13440 :                                         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);
    1766       13440 :                                         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);
    1767       13440 :                                         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);
    1768       13440 :                                         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);
    1769             :                                 }
    1770             :                         }
    1771             :                 }
    1772             :         }
    1773             : 
    1774             :         struct {
    1775             :                 char *op;
    1776             :                 char *fname;
    1777             :                 MALfcn fcn;
    1778             :                 char *comment;
    1779             :                 char *comment_v;
    1780             :                 char *comment_v_;
    1781             :         } cmp = {
    1782             :                 .op = "cmp",
    1783             :                 .fcn = (MALfcn)CMDbatCMP,
    1784             :                 .fname = "CMDbatCMP",
    1785             :                 .comment = "Return -1/0/1 if B1 </==/> B2",
    1786             :                 .comment_v = "Return -1/0/1 if B </==/> V",
    1787             :                 .comment_v_ = "Return -1/0/1 if V </==/> B",
    1788             :         };
    1789        1344 :         for(int i = 0; i < 3 && !err; i++) {
    1790        1008 :                 int tp = specials[i];
    1791        1008 :                 mel_func_arg ret = { .type = TYPE_bte, .isbat =1 };
    1792        1008 :                 mel_func_arg arg = { .type = tp, .isbat =1 };
    1793        1008 :                 mel_func_arg varg = { .type = tp };
    1794             : 
    1795        1008 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment, 1, 3, ret, arg, arg);
    1796        1008 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment, 1, 5, ret, arg, arg, cand, cand);
    1797        1008 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v, 1, 3, ret, arg, varg);
    1798        1008 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v, 1, 4, ret, arg, varg, cand);
    1799        1008 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v_, 1, 3, ret, varg, arg);
    1800        1008 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v_, 1, 4, ret, varg, arg, cand);
    1801             :         }
    1802        2688 :         for(tp1 = integer; tp1 < extra && !err; tp1++) {
    1803       18816 :             for(tp2 = integer; tp2 < extra && !err; tp2++) {
    1804       16464 :                         mel_func_arg ret = { .type = TYPE_bte, .isbat =1 };
    1805       16464 :                         mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1806       16464 :                         mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1807       16464 :                         mel_func_arg varg1 = { .type = *tp1 };
    1808       16464 :                         mel_func_arg varg2 = { .type = *tp2 };
    1809             : 
    1810       16464 :                         err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment, 1, 3, ret, arg1, arg2);
    1811       16464 :                         err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment, 1, 5, ret, arg1, arg2, cand, cand);
    1812       16464 :                         err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v, 1, 3, ret, arg1, varg2);
    1813       16464 :                         err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v, 1, 4, ret, arg1, varg2, cand);
    1814       16464 :                         err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v_, 1, 3, ret, varg1, arg2);
    1815       16464 :                         err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v_, 1, 4, ret, varg1, arg2, cand);
    1816             :             }
    1817             :         }
    1818        2688 :         for(tp = integer; tp < extra && !err; tp++) {
    1819        2352 :                 mel_func_arg ret = { .type = TYPE_dbl };
    1820        2352 :                 mel_func_arg nr = { .type = TYPE_lng };
    1821        2352 :                 mel_func_arg arg = { .type = *tp, .isbat =1 };
    1822        2352 :                 mel_func_arg scale = { .type = TYPE_int };
    1823             : 
    1824        2352 :                 err += melFunction(false, "batcalc", "avg", (MALfcn)&CMDcalcavg, "CMDcalcavg", false, "average of non-nil values of B", 1, 2, ret, arg);
    1825        2352 :                 err += melFunction(false, "batcalc", "avg", (MALfcn)&CMDcalcavg, "CMDcalcavg", false, "average of non-nil values of B with candidates list", 1, 3, ret, arg, cand);
    1826        2352 :                 err += melFunction(false, "batcalc", "avg", (MALfcn)&CMDcalcavg, "CMDcalcavg", false, "average and number of non-nil values of B", 2, 3, ret, nr, arg);
    1827        2352 :                 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);
    1828        2352 :                 err += melFunction(false, "batcalc", "avg", (MALfcn)&CMDcalcavg, "CMDcalcavg", false, "average of non-nil values of B", 1, 3, ret, arg, scale);
    1829        2352 :                 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);
    1830        2352 :                 err += melFunction(false, "batcalc", "avg", (MALfcn)&CMDcalcavg, "CMDcalcavg", false, "average and number of non-nil values of B", 2, 4, ret, nr, arg, scale);
    1831        2352 :                 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);
    1832             :         }
    1833             : 
    1834         336 :         struct {
    1835             :                 int type;
    1836             :                 char *name;
    1837             :                 char *fname;
    1838             :                 MALfcn fcn;
    1839         336 :         } typeops[10] = {
    1840             :                 {
    1841             :                         .type = TYPE_bit,
    1842             :                         .name = "bit",
    1843             :                         .fname = "CMDconvertsignal_bit",
    1844             :                         .fcn = (MALfcn)CMDconvertsignal_bit,
    1845             :                 }, {
    1846             :                         .type = TYPE_bte,
    1847             :                         .name = "bte",
    1848             :                         .fname = "CMDconvertsignal_bte",
    1849             :                         .fcn = (MALfcn)CMDconvertsignal_bte,
    1850             :                 }, {
    1851             :                         .type = TYPE_sht,
    1852             :                         .name = "sht",
    1853             :                         .fname = "CMDconvertsignal_sht",
    1854             :                         .fcn = (MALfcn)CMDconvertsignal_sht,
    1855             :                 }, {
    1856             :                         .type = TYPE_int,
    1857             :                         .name = "int",
    1858             :                         .fname = "CMDconvertsignal_int",
    1859             :                         .fcn = (MALfcn)CMDconvertsignal_int,
    1860             :                 }, {
    1861             :                         .type = TYPE_lng,
    1862             :                         .name = "lng",
    1863             :                         .fname = "CMDconvertsignal_lng",
    1864             :                         .fcn = (MALfcn)CMDconvertsignal_lng,
    1865             : #ifdef HAVE_HGE
    1866             :                 }, {
    1867             :                         .type = TYPE_hge,
    1868             :                         .name = "hge",
    1869             :                         .fname = "CMDconvertsignal_hge",
    1870             :                         .fcn = (MALfcn)CMDconvertsignal_hge,
    1871             : #endif
    1872             :                 }, {
    1873             :                         .type = TYPE_flt,
    1874             :                         .name = "flt",
    1875             :                         .fname = "CMDconvertsignal_flt",
    1876             :                         .fcn = (MALfcn)CMDconvertsignal_flt,
    1877             :                 }, {
    1878             :                         .type = TYPE_dbl,
    1879             :                         .name = "dbl",
    1880             :                         .fname = "CMDconvertsignal_dbl",
    1881             :                         .fcn = (MALfcn)CMDconvertsignal_dbl,
    1882             :                 }, {
    1883             :                         .type = TYPE_oid,
    1884             :                         .name = "oid",
    1885             :                         .fname = "CMDconvertsignal_oid",
    1886             :                         .fcn = (MALfcn)CMDconvertsignal_oid,
    1887             :                 }, {
    1888             :                         .type = TYPE_str,
    1889             :                         .name = "str",
    1890             :                         .fname = "CMDconvertsignal_str",
    1891             :                         .fcn = (MALfcn)CMDconvertsignal_str,
    1892             :                 }
    1893             :         };
    1894             : #ifdef HAVE_HGE
    1895         336 :         int typeopslen = 10;
    1896             : #else
    1897             :         int typeopslen = 9;
    1898             : #endif
    1899        3696 :         for(int t = 0; t<typeopslen; t++) {
    1900             :                 /* from any 2 string */
    1901        3360 :                 mel_func_arg ret = { .type = typeops[t].type, .isbat =1 };
    1902        3360 :                 if (strcmp(typeops[t].name, "str")==0) {
    1903         336 :                         mel_func_arg arg = { .type = TYPE_any, .isbat =1 };
    1904             : 
    1905         336 :                         err += melFunction(false, "batcalc", typeops[t].name, typeops[t].fcn, typeops[t].fname, false, "", 1, 2, ret, arg);
    1906         336 :                         err += melFunction(false, "batcalc", typeops[t].name, typeops[t].fcn, typeops[t].fname, false, "", 1, 3, ret, arg, cand);
    1907             :                 } else {
    1908       33264 :                     for(int p = 0; p<typeopslen; p++) {
    1909       30240 :                                 mel_func_arg arg = { .type = typeops[p].type, .isbat =1 };
    1910             : 
    1911       30240 :                                 err += melFunction(false, "batcalc", typeops[t].name, typeops[t].fcn, typeops[t].fname, false, "", 1, 2, ret, arg);
    1912       30240 :                                 err += melFunction(false, "batcalc", typeops[t].name, typeops[t].fcn, typeops[t].fname, false, "", 1, 3, ret, arg, cand);
    1913             :                     }
    1914             :                 }
    1915             :         }
    1916         336 :         return MAL_SUCCEED;
    1917             : }
    1918             : 
    1919             : static mel_func batcalc_init_funcs[] = {
    1920             :  /* batcalc */
    1921             :  pattern("batcalc", "isnil", CMDbatISNIL, false, "Unary check for nil over the tail of the bat", args(1,2, batarg("",bit),batargany("b",0))),
    1922             :  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))),
    1923             :  pattern("batcalc", "isnotnil", CMDbatISNOTNIL, false, "Unary check for notnil over the tail of the bat", args(1,2, batarg("",bit),batargany("b",0))),
    1924             :  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))),
    1925             :  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))),
    1926             :  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))),
    1927             :  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))),
    1928             :  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))),
    1929             :  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))),
    1930             :  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))),
    1931             :  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))),
    1932             :  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))),
    1933             :  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))),
    1934             :  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))),
    1935             :  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))),
    1936             :  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))),
    1937             :  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))),
    1938             :  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))),
    1939             :  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))),
    1940             :  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))),
    1941             :  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))),
    1942             :  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))),
    1943             :  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))),
    1944             :  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))),
    1945             :  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))),
    1946             :  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))),
    1947             :  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))),
    1948             :  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))),
    1949             : 
    1950             :  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))),
    1951             :  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))),
    1952             :  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))),
    1953             : 
    1954             :  pattern("batmmath", "fmod", CMDbatMODsignal, false, "", args(1,3, batarg("",dbl),batarg("x",dbl),arg("y",dbl))),
    1955             :  pattern("batmmath", "fmod", CMDbatMODsignal, false, "", args(1,4, batarg("",dbl),batarg("x",dbl),arg("y",dbl),batarg("s",oid))),
    1956             :  pattern("batmmath", "fmod", CMDbatMODsignal, false, "", args(1,3, batarg("",flt),batarg("x",flt),arg("y",flt))),
    1957             :  pattern("batmmath", "fmod", CMDbatMODsignal, false, "", args(1,4, batarg("",flt),batarg("x",flt),arg("y",flt),batarg("s",oid))),
    1958             : 
    1959             :  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))),
    1960             :  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))),
    1961             :  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))),
    1962             :  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))),
    1963             :  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))),
    1964             :  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))),
    1965             :  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))),
    1966             :  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))),
    1967             : 
    1968             :  pattern("aggr", "avg", CMDcalcavg, false, "Gives the avg of all tail values", args(1,2, arg("",dbl),batargany("b",2))),
    1969             :  pattern("aggr", "avg", CMDcalcavg, false, "Gives the avg of all tail values", args(1,3, arg("",dbl),batargany("b",2),arg("scale",int))),
    1970             : 
    1971             :  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))),
    1972             :  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))),
    1973             :  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))),
    1974             :  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))),
    1975             :  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))),
    1976             :  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))),
    1977             :  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))),
    1978             : 
    1979             :  { .imp=NULL }
    1980             : 
    1981             : };
    1982             : #include "mal_import.h"
    1983             : #ifdef _MSC_VER
    1984             : #undef read
    1985             : #pragma section(".CRT$XCU",read)
    1986             : #endif
    1987         329 : LIB_STARTUP_FUNC(init_batcalc_mal)
    1988         329 : { mal_module2("batcalc", NULL, batcalc_init_funcs, &batcalc_init, NULL); }

Generated by: LCOV version 1.14