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); }
|