1 /*
2  *  gretl -- Gnu Regression, Econometrics and Time-series Library
3  *  Copyright (C) 2001 Allin Cottrell and Riccardo "Jack" Lucchetti
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19 
20 /* syntax tree evaluator for "genr" */
21 
22 #include "genparse.h"
23 #include "monte_carlo.h"
24 #include "gretl_string_table.h"
25 #include "gretl_typemap.h"
26 #include "matrix_extra.h"
27 #include "usermat.h"
28 #include "uservar.h"
29 #include "gretl_bfgs.h"
30 #include "gretl_normal.h"
31 #include "gretl_panel.h"
32 #include "kalman.h"
33 #include "libset.h"
34 #include "version.h"
35 #include "csvdata.h"
36 #include "uservar_priv.h"
37 #include "genr_optim.h"
38 #include "gretl_cmatrix.h"
39 #include "qr_estimate.h"
40 #include "gretl_foreign.h"
41 #include "gretl_midas.h"
42 #include "gretl_xml.h"
43 #include "gretl_mt.h"
44 #include "var.h"
45 #include "vartest.h"
46 
47 #include <time.h> /* for the $now accessor */
48 
49 #ifdef USE_CURL
50 # include "gretl_www.h"
51 #endif
52 
53 #ifdef HAVE_MPI
54 # include "gretl_mpi.h"
55 #endif
56 
57 #ifdef WIN32
58 # include "gretl_win32.h" /* for strptime() */
59 #endif
60 
61 #include <errno.h>
62 
63 #if GENDEBUG
64 # define EDEBUG GENDEBUG
65 # define LHDEBUG GENDEBUG
66 #else
67 # define EDEBUG 0
68 # define LHDEBUG 0
69 #endif
70 
71 #if LHDEBUG || EDEBUG > 1
72 # define IN_GENEVAL
73 # include "mspec_debug.c"
74 #endif
75 
76 #define AUX_NODES_DEBUG 0
77 
78 #if AUX_NODES_DEBUG
79 # include <stdarg.h>
real_rndebug(const char * format,...)80 static void real_rndebug (const char *format, ...)
81 {
82     va_list args;
83 
84     va_start(args, format);
85     vfprintf(stderr, format, args);
86     va_end(args);
87 }
88 # define rndebug(x) real_rndebug x
89 #else
90 # define rndebug(x)
91 #endif
92 
93 #define ONE_BY_ONE_CAST 1
94 
95 enum {
96     FR_TREE = 1,
97     FR_RET,
98     FR_LHTREE,
99     FR_LHRES,
100     FR_ARET
101 };
102 
103 #define is_aux_node(n) (n != NULL && (n->flags & AUX_NODE))
104 #define is_tmp_node(n) (n != NULL && (n->flags & TMP_NODE))
105 #define is_proxy_node(n) (n != NULL && (n->flags & PRX_NODE))
106 
107 #define emptymat_ok(f) (f == F_GINV || f == F_DIAG || f == F_TRANSP || \
108 			f == F_VEC || f == F_VECH || f == F_UNVECH ||	\
109 			f == F_CHOL || f == F_UPPER || f == F_LOWER ||	\
110 			f == F_SORT || f == F_DSORT || f == F_VALUES || \
111 			f == F_MREV)
112 
113 #define dataset_dum(n) (n->t == DUM && n->v.idnum == DUM_DATASET)
114 
115 #define postfix_node(n) (n->t == NUM_P || n->t == NUM_M)
116 
117 #define uscalar_node(n) ((n->t == NUM && n->vname != NULL) || postfix_node(n))
118 
119 #define umatrix_node(n) (n->t == MAT && n->vname != NULL)
120 #define ubundle_node(n) (n->t == BUNDLE && n->vname != NULL)
121 #define uarray_node(n)  (n->t == ARRAY && n->vname != NULL)
122 #define ustring_node(n) (n->t == STR && n->vname != NULL)
123 #define ulist_node(n)   (n->t == LIST && n->vname != NULL)
124 #define useries_node(n) (n->t == SERIES && n->vnum >= 0)
125 #define uvar_node(n)    (n->vname != NULL)
126 
127 #define scalar_matrix_node(n) (n->t == MAT && gretl_matrix_is_scalar(n->v.m))
128 #define scalar_node(n) (n->t == NUM || scalar_matrix_node(n))
129 #define ok_matrix_node(n) (n->t == MAT || n->t == NUM)
130 #define complex_node(n) (n->t == MAT && n->v.m->is_complex)
131 #define cscalar_node(n) (n->t == MAT && gretl_matrix_is_cscalar(n->v.m))
132 
133 #define stringvec_node(n) (n->flags & SVL_NODE)
134 #define mutable_node(n) (n->flags & MUT_NODE)
135 
136 #define null_node(n) (n == NULL || n->t == EMPTY)
137 #define null_or_scalar(n) (null_node(n) || scalar_node(n))
138 #define null_or_string(n) (null_node(n) || n->t == STR)
139 
140 #define ok_bundled_type(t) (t == NUM || t == STR || t == MAT || t == LIST || \
141 			    t == SERIES || t == BUNDLE || t == ARRAY)
142 
143 #define compiled(p) (p->flags & P_EXEC)
144 #define starting(p) (p->flags & P_START)
145 #define autoreg(p)  (p->flags & P_AUTOREG)
146 #define DCHECK (P_EXEC | P_START)
147 #define exestart(p) ((p->flags & DCHECK) == DCHECK)
148 
149 static void parser_init (parser *p, const char *str, DATASET *dset,
150 			 PRN *prn, int flags, int targtype, int *done);
151 static void parser_reinit (parser *p, DATASET *dset, PRN *prn);
152 static NODE *eval (NODE *t, parser *p);
153 static void node_type_error (int ntype, int argnum, int goodt,
154 			     NODE *bad, parser *p);
155 static int node_is_true (NODE *n, parser *p);
156 static gretl_matrix *series_to_matrix (const double *x, parser *p);
157 static void printnode (NODE *t, parser *p, int value);
158 static inline int attach_aux_node (NODE *t, NODE *ret, parser *p);
159 static char *get_opstr (int op);
160 
161 /* ok_list_node: This is a first-pass assessment of whether
162    a given node _may_ be interpretable as holding a LIST.
163    The follow-up is node_get_list(), and that will determine
164    whether the interpretation really works.
165 */
166 
ok_list_node(NODE * n,parser * p)167 static int ok_list_node (NODE *n, parser *p)
168 {
169     if (n == NULL) {
170 	return 0;
171     } else if (n->t == LIST) {
172 	return 1;
173     } else if (n->t == SERIES && n->vnum >= 0) {
174 	/* can interpret as singleton list */
175 	return 1;
176     } else if (p->flags & P_LISTDEF) {
177 	/* when defining a list we can be a bit more accommodating */
178 	return null_or_scalar(n);
179     }
180 
181     return 0;
182 }
183 
184 /* more "lenient" version of the above, to accommodate
185    list expressions such as (L - 0), indicating the list
186    that results from dropping the constant from L
187 */
188 
ok_list_node_plus(NODE * n)189 static int ok_list_node_plus (NODE *n)
190 {
191     if (n->t == LIST) {
192 	return 1;
193     } else if (n->t == SERIES && n->vnum >= 0) {
194 	return 1;
195     } else if (n->t == NUM) {
196 	return 1;
197     } else {
198 	return 0;
199     }
200 }
201 
typestr(int t)202 static const char *typestr (int t)
203 {
204     switch (t) {
205     case NUM:
206 	return "scalar";
207     case SERIES:
208 	return "series";
209     case MAT:
210 	return "matrix";
211     case STR:
212 	return "string";
213     case U_ADDR:
214 	return "address";
215     case LIST:
216 	return "list";
217     case BUNDLE:
218 	return "bundle";
219     case DBUNDLE:
220 	return "$-bundle";
221     case ARRAY:
222 	return "array";
223     case USERIES:
224 	return "named series";
225     case EMPTY:
226 	return "empty";
227     default:
228 	return "?";
229     }
230 }
231 
free_mspec(matrix_subspec * spec,parser * p)232 static void free_mspec (matrix_subspec *spec, parser *p)
233 {
234     if (spec != NULL) {
235 	free(spec->rslice);
236 	free(spec->cslice);
237 	free(spec);
238     }
239 }
240 
clear_mspec(matrix_subspec * spec,parser * p)241 static void clear_mspec (matrix_subspec *spec, parser *p)
242 {
243     free(spec->rslice);
244     free(spec->cslice);
245 
246     memset(spec, 0, sizeof(*spec));
247 }
248 
249 #if EDEBUG || LHDEBUG
250 
flagstr(guint8 flags)251 static char *flagstr (guint8 flags)
252 {
253     static char ret[16];
254 
255     if (flags & AUX_NODE) {
256 	strcpy(ret, "aux");
257 	if (flags & TMP_NODE) {
258 	    strcat(ret, ",tmp");
259 	}
260     } else if (flags & TMP_NODE) {
261 	strcpy(ret, "tmp");
262     } else if (flags & LHT_NODE) {
263 	strcpy(ret, "lht");
264     } else {
265 	sprintf(ret, "%d", (int) flags);
266     }
267 
268     return ret;
269 }
270 
print_tree(NODE * t,parser * p,int level,char pos)271 static void print_tree (NODE *t, parser *p, int level, char pos)
272 {
273     if (t == NULL) {
274 	fprintf(stderr, " %d: node is null\n", level);
275 	return;
276     }
277 
278     if (bnsym(t->t)) {
279 	int i;
280 
281 	for (i=0; i<t->v.bn.n_nodes; i++) {
282 	    print_tree(t->v.bn.n[i], p, level+1, 0);
283 	}
284     } else {
285 	if (t->L != NULL) {
286 	    print_tree(t->L, p, level+1, 'L');
287 	}
288 	if (t->M != NULL) {
289 	    print_tree(t->M, p, level+1, 'M');
290 	}
291 	if (t->R != NULL) {
292 	    print_tree(t->R, p, level+1, 'R');
293 	}
294     }
295 
296     if (pos != 0) {
297 	fprintf(stderr, " %d (%c): ", level, pos);
298     } else {
299 	fprintf(stderr, " %d: ", level);
300     }
301 
302     if (t->vname != NULL) {
303 	fprintf(stderr, "node at %p (type %03d, %s, flags %s), vname='%s'",
304 		(void *) t, t->t, getsymb(t->t), flagstr(t->flags), t->vname);
305 	if (t->t == NUM) {
306 	    fprintf(stderr, ", val %g\n", t->v.xval);
307 	} else {
308 	    fputc('\n', stderr);
309 	}
310     } else if (t->t == STR) {
311 	fprintf(stderr, "node at %p (type %03d, %s, flags %s, val '%s')\n",
312 		(void *) t, t->t, getsymb(t->t), flagstr(t->flags), t->v.str);
313     } else if (t->t == NUM) {
314 	fprintf(stderr, "node at %p (type %03d, %s, flags %s, val %g)\n",
315 		(void *) t, t->t, getsymb(t->t), flagstr(t->flags), t->v.xval);
316     } else {
317 	fprintf(stderr, "node at %p (type %03d, %s, flags %s)\n",
318 		(void *) t, t->t, getsymb(t->t), flagstr(t->flags));
319     }
320 
321     if (t->aux != NULL) {
322 	fprintf(stderr, "  aux node at %p (type %03d, %s, flags %s)\n",
323 		(void *) t->aux, t->aux->t, getsymb(t->aux->t),
324 		flagstr(t->aux->flags));
325     }
326 }
327 
328 #endif /* EDEBUG */
329 
330 #if EDEBUG
331 
free_tree_tag(int t)332 static const char *free_tree_tag (int t)
333 {
334     if (t == FR_TREE) {
335 	return "free tree";
336     } else if (t == FR_RET) {
337 	return "free ret";
338     } else if (t == FR_LHTREE) {
339 	return "free lhtree";
340     } else if (t == FR_LHRES) {
341 	return "free lhres";
342     } else {
343 	return "free other";
344     }
345 }
346 
347 #endif /* EDEBUG */
348 
349 /* used when we know that @t is a terminal node: skip
350    the tests for attached tree */
351 
free_node(NODE * t,parser * p)352 static void free_node (NODE *t, parser *p)
353 {
354     if (t->refcount > 1) {
355 	rndebug(("free node %p (%s): decrement refcount to %d\n",
356 		 (void *) t, getsymb(t->t), t->refcount - 1));
357 	t->refcount -= 1;
358 	return;
359     }
360 
361     if (is_tmp_node(t)) {
362 #if EDEBUG
363 	fprintf(stderr, " tmp node: freeing attached data\n");
364 #endif
365 	if (t->t == SERIES) {
366 	    free(t->v.xvec);
367 	} else if (t->t == LIST || t->t == IVEC) {
368 	    free(t->v.ivec);
369 	} else if (t->t == MAT) {
370 	    gretl_matrix_free(t->v.m);
371 	} else if (t->t == MSPEC) {
372 	    free_mspec(t->v.mspec, p);
373 	} else if (t->t == BUNDLE) {
374 	    gretl_bundle_destroy(t->v.b);
375 	} else if (t->t == ARRAY) {
376 	    gretl_array_destroy(t->v.a);
377 	} else if (t->t == STR) {
378 	    free(t->v.str);
379 	} else if (funcn_symb(t->t)) {
380 	    /* special case: a multi-args function node attached as
381 	       auxiliary by feval(): here we should free all and only
382 	       those elements that were allocated independently,
383 	       namely the array to hold the arguments (v.bn.n) and
384 	       the args node itself.
385 	    */
386 	    NODE *args = t->L;
387 
388 	    free(args->v.bn.n);
389 	    free(args);
390 	}
391     }
392 
393     if (t->t == UOBJ || t->t == WLIST) {
394 	free(t->v.str);
395     }
396 
397     if (t->vname != NULL) {
398 	free(t->vname);
399     }
400 
401     if (p != NULL && t == p->ret) {
402 	p->ret = NULL;
403     }
404 
405     free(t);
406 }
407 
408 /* A word on "aux" nodes. These come in two sorts, which
409    might be described as "robust" and "fragile" respectively.
410 
411    A robust node (identified by the TMP_NODE flag) is one
412    whose data pointer is independently allocated. With such
413    a node it's OK simply to "pass on" the pointer in
414    assignment, and if it's not passed on it should be freed
415    on completion of "genr". (So nota bene: if it's assigned
416    elsewhere, the pointer on the aux node itself must then
417    be set to NULL to avoid double-freeing.)
418 
419    A fragile node is one whose data pointer is not
420    independently allocated; it actually "belongs to someone
421    else". In assignment, then, it must be deeply copied,
422    and it must _not_ be freed on completion of genr.
423 
424    Obviously, it's necessary to be careful in handling
425    fragile nodes, but the advantage of allowing them
426    is that they cut down on wasteful deep-copying of objects
427    that may be used in calculation, without being modified,
428    on the fly.
429 */
430 
free_tree(NODE * t,parser * p,int code)431 void free_tree (NODE *t, parser *p, int code)
432 {
433     if (t == NULL) {
434 	return;
435     }
436 
437 #if EDEBUG
438     fprintf(stderr, "%-11s: starting at %p (type %03d, %s)\n",
439 	    free_tree_tag(code), (void *) t, t->t,
440 	    getsymb(t->t));
441 #endif
442 
443     /* free recursively */
444     if (bnsym(t->t)) {
445 	int i;
446 
447 	for (i=0; i<t->v.bn.n_nodes; i++) {
448 	    free_tree(t->v.bn.n[i], p, code);
449 	}
450 	free(t->v.bn.n);
451     } if (!(t->flags & LHT_NODE)) {
452 	free_tree(t->L, p, code);
453 	free_tree(t->M, p, code);
454 	free_tree(t->R, p, code);
455     }
456 
457     if (t->aux != NULL && t->aux != p->ret && t->aux != p->lhres) {
458 	rndebug(("freeing aux node at %p (%s)\n", (void *) t->aux,
459 		 getsymb(t->aux->t)));
460 	free_node(t->aux, p);
461     } else if (t->aux != NULL) {
462 	rndebug(("NOT freeing aux at %p (= p->ret)\n", (void *) t->aux));
463 	t->aux->refcount -= 1;
464     }
465 
466 #if EDEBUG
467     fprintf(stderr, "%-11s: freeing node at %p (type %03d, %s, flags = %d)\n",
468 	    free_tree_tag(code), (void *) t, t->t, getsymb(t->t),
469 	    t->flags);
470 #endif
471 
472     free_node(t, p);
473 }
474 
clear_uvnodes(NODE * t)475 static void clear_uvnodes (NODE *t)
476 {
477     if (t == NULL) {
478 	return;
479     }
480 
481     if (bnsym(t->t)) {
482 	int i;
483 
484 	for (i=0; i<t->v.bn.n_nodes; i++) {
485 	    clear_uvnodes(t->v.bn.n[i]);
486 	}
487     } else {
488 	clear_uvnodes(t->L);
489 	clear_uvnodes(t->M);
490 	clear_uvnodes(t->R);
491     }
492 
493     if (t->t == SERIES) {
494 	if (t->vnum >= 0 || t->vname != NULL) {
495 #if EDEBUG
496 	    fprintf(stderr, " clear_uvnode: series at %p\n", (void *) t);
497 #endif
498 	    t->v.xvec = NULL;
499 	}
500     } else if (t->uv != NULL) {
501 #if EDEBUG
502 	fprintf(stderr, " clear_uvnode: uvar '%s' at %p, uv %p\n", t->vname,
503 		(void *) t, (void *) t->uv);
504 #endif
505 	t->uv = NULL;
506     }
507 }
508 
509 #if AUX_NODES_DEBUG
reset_p_aux(parser * p,NODE * n)510 static void reset_p_aux (parser *p, NODE *n)
511 {
512     fprintf(stderr, "resetting p->aux = %p\n", (void *) n);
513     p->aux = n;
514 }
515 #else
516 # define reset_p_aux(p, n) (p->aux = n)
517 #endif
518 
newmdef(int k)519 static NODE *newmdef (int k)
520 {
521     NODE *n = new_node(MDEF);
522 
523     if (n != NULL) {
524 	int i;
525 
526 	if (k > 0) {
527 	    n->v.bn.n = malloc(k * sizeof n);
528 	    if (n->v.bn.n != NULL) {
529 		for (i=0; i<k; i++) {
530 		    n->v.bn.n[i] = NULL;
531 		}
532 	    } else {
533 		free(n);
534 		n = NULL;
535 	    }
536 	} else {
537 	    n->v.bn.n = NULL;
538 	}
539 	if (n != NULL) {
540 	    n->v.bn.n_nodes = k;
541 	}
542     }
543 
544     return n;
545 }
546 
na_array(int n)547 static double *na_array (int n)
548 {
549     double *x = malloc(n * sizeof *x);
550     int i;
551 
552     if (x != NULL) {
553 	for (i=0; i<n; i++) {
554 	    x[i] = NADBL;
555 	}
556     }
557 
558     return x;
559 }
560 
561 /* new node to hold array of doubles */
562 
newseries(int n,int flags)563 static NODE *newseries (int n, int flags)
564 {
565     NODE *b = new_node(SERIES);
566 
567     if (b != NULL) {
568 	b->flags = flags;
569 	if (n > 0) {
570 	    b->v.xvec = na_array(n);
571 	    if (b->v.xvec == NULL) {
572 		free(b);
573 		b = NULL;
574 	    }
575 	} else {
576 	    b->v.xvec = NULL;
577 	}
578     }
579 
580     return b;
581 }
582 
583 /* new node to hold array of @n ints */
584 
newivec(int n)585 static NODE *newivec (int n)
586 {
587     NODE *b = new_node(IVEC);
588 
589     if (b != NULL) {
590 	b->flags = TMP_NODE;
591 	if (n > 0) {
592 	    b->v.ivec = malloc(n * sizeof(int));
593 	    if (b->v.ivec == NULL) {
594 		free(b);
595 		b = NULL;
596 	    }
597 	} else {
598 	    b->v.ivec = NULL;
599 	}
600     }
601 
602     return b;
603 }
604 
605 /* new node to hold a gretl_matrix */
606 
newmat(int flags)607 static NODE *newmat (int flags)
608 {
609     NODE *n = new_node(MAT);
610 
611     if (n != NULL) {
612 	n->flags = flags;
613 	n->v.m = NULL;
614     }
615 
616     return n;
617 }
618 
619 /* new node to hold a matrix specification */
620 
newmspec(void)621 static NODE *newmspec (void)
622 {
623     NODE *n = new_node(MSPEC);
624 
625     if (n != NULL) {
626 	n->flags = TMP_NODE;
627 	n->v.mspec = NULL;
628     }
629 
630     return n;
631 }
632 
633 /* new node to hold a list */
634 
newlist(int flags)635 static NODE *newlist (int flags)
636 {
637     NODE *n = new_node(LIST);
638 
639     if (n != NULL) {
640 	n->flags = flags;
641 	n->v.ivec = NULL;
642     }
643 
644     return n;
645 }
646 
newstring(int flags)647 static NODE *newstring (int flags)
648 {
649     NODE *n = new_node(STR);
650 
651     if (n != NULL) {
652 	n->flags = flags;
653 	n->v.str = NULL;
654     }
655 
656     return n;
657 }
658 
newbundle(int flags)659 static NODE *newbundle (int flags)
660 {
661     NODE *n = new_node(BUNDLE);
662 
663     if (n != NULL) {
664 	n->flags = flags;
665 	n->v.b = NULL;
666     }
667 
668     return n;
669 }
670 
newarray(int flags)671 static NODE *newarray (int flags)
672 {
673     NODE *n = new_node(ARRAY);
674 
675     if (n != NULL) {
676 	n->flags = flags;
677 	n->v.a = NULL;
678     }
679 
680     return n;
681 }
682 
clear_tmp_node_data(NODE * n,parser * p)683 static void clear_tmp_node_data (NODE *n, parser *p)
684 {
685     int nullify = 1;
686 
687     if (n->t == LIST) {
688 	free(n->v.ivec);
689     } else if (n->t == MAT) {
690 	/* (how) can we avoid doing this? */
691 	gretl_matrix_free(n->v.m);
692     } else if (n->t == MSPEC) {
693 	if (n->v.mspec != NULL) {
694 	    clear_mspec(n->v.mspec, p);
695 	}
696 	nullify = 0;
697     } else if (n->t == BUNDLE) {
698 	gretl_bundle_destroy(n->v.b);
699     } else if (n->t == ARRAY) {
700 	gretl_array_destroy(n->v.a);
701     } else if (n->t == STR) {
702 	free(n->v.str);
703     } else if (n->t == SERIES) {
704 	/* preserve any existing tmp series, unless the
705 	   dataset series length has changed
706 	*/
707 	if (p->flags & P_DELTAN) {
708 	    free(n->v.xvec);
709 	    n->v.xvec = NULL;
710 	    if (p->dset_n > 0) {
711 		n->v.xvec = na_array(p->dset_n);
712 		if (n->v.xvec == NULL) {
713 		    p->err = E_ALLOC;
714 		}
715 	    }
716 	} else {
717 	    /* scrub any pre-existing values in the current
718 	       sample range */
719 	    int t;
720 
721 	    for (t=p->dset->t1; t<=p->dset->t2; t++) {
722 		n->v.xvec[t] = NADBL;
723 	    }
724 	}
725 	nullify = 0;
726     } else {
727 	nullify = 0;
728     }
729 
730     if (nullify) {
731 	n->v.ptr = NULL;
732     }
733 }
734 
mutate_bundle_member_node(NODE * n,int type,int flags,parser * p)735 static int mutate_bundle_member_node (NODE *n, int type,
736 				      int flags, parser *p)
737 {
738     int err = 0;
739 
740 #if EDEBUG > 1
741     fprintf(stderr, "mutate_bundle_member: %p, %s -> %s, tmp %d -> %d\n",
742 	    (void *) n, getsymb(n->t), getsymb(type),
743 	    (n->flags & TMP_NODE)? 1 : 0,
744 	    (flags & TMP_NODE)? 1 : 0);
745 #endif
746 
747     if (is_tmp_node(n)) {
748 	/* some allocated storage should be freed */
749 	if (n->t == SERIES) {
750 	    free(n->v.xvec);
751 	} else if (n->t == MAT) {
752 	    gretl_matrix_free(n->v.m);
753 	}
754 	n->v.ptr = NULL;
755     }
756 
757     if (type == SERIES) {
758 	/* switching to a series node : allocate xvec */
759 	n->v.xvec = malloc(p->dset->n * sizeof(double));
760 	if (n->v.xvec == NULL) {
761 	    err = E_ALLOC;
762 	}
763     }
764 
765     if (!err) {
766 	n->t = type;
767 	n->flags = flags;
768     }
769 
770     return err;
771 }
772 
773 /* We allow here for some equivocation in type between
774    1 x 1 matrices and scalars in the course of executing
775    a compiled parser with saved aux nodes.
776 */
777 
maybe_switch_node_type(NODE * n,int type,int flags,parser * p)778 static void maybe_switch_node_type (NODE *n, int type,
779 				    int flags, parser *p)
780 {
781     if (mutable_node(n)) {
782 	/* bundle members only */
783 	p->err = mutate_bundle_member_node(n, type, flags, p);
784     } else if (n->t == MAT && type == NUM) {
785 	/* switch aux node @n from matrix to scalar */
786 	if (is_tmp_node(n)) {
787 	    gretl_matrix_free(n->v.m);
788 	}
789 	n->t = NUM;
790 	n->v.xval = NADBL;
791 	n->flags = 0;
792 	n->vnum = NO_VNUM;
793 	n->vname = NULL;
794     } else if (n->t == NUM && type == MAT) {
795 	/* switch @n from scalar to matrix */
796 	n->t = MAT;
797 	n->v.m = NULL;
798 	n->flags = flags;
799     } else if (type == EMPTY) {
800 	; /* LHS mechanism: OK */
801     } else {
802 	/* any other discrepancy presumably means that
803 	   things have gone badly wrong
804 	*/
805 	fprintf(stderr, "aux node mismatch: n->t = %d (%s), type = %d (%s), tmp = %d\n",
806 		n->t, getsymb(n->t), type, getsymb(type), (flags == TMP_NODE));
807 	gretl_errmsg_set("internal genr error: aux node mismatch");
808 	p->err = E_DATA;
809     }
810 }
811 
812 /* get an auxiliary node: if starting from scratch we allocate
813    a new node, otherwise we look up an existing one */
814 
get_aux_node(parser * p,int t,int n,int flags)815 static NODE *get_aux_node (parser *p, int t, int n, int flags)
816 {
817     NODE *ret = p->aux;
818 
819 #if EDEBUG
820     fprintf(stderr, "get_aux_node: t=%s, tmp=%d, starting=%d, "
821 	    "p->aux=%p\n", getsymb(t), (flags & TMP_NODE)? 1 : 0,
822 	    starting(p) ? 1 : 0, (void *) p->aux);
823 #endif
824 
825     if (is_proxy_node(ret)) {
826 	/* this node will get freed later */
827 	ret = NULL;
828     }
829 
830     if (ret != NULL) {
831 	/* got a pre-existing aux node */
832 	if (starting(p)) {
833 	    if (ret->t != t) {
834 		maybe_switch_node_type(ret, t, flags, p);
835 	    } else if (is_tmp_node(ret) && !(p->flags & P_MSAVE)) {
836 		clear_tmp_node_data(ret, p);
837 	    }
838 	}
839     } else {
840 	/* we need to create a new aux node */
841 	if (t == NUM) {
842 	    ret = newdbl(NADBL);
843 	} else if (t == SERIES) {
844 	    ret = newseries(n, flags);
845 	} else if (t == IVEC) {
846 	    ret = newivec(n);
847 	} else if (t == LIST) {
848 	    ret = newlist(flags);
849 	} else if (t == MAT) {
850 	    ret = newmat(flags);
851 	} else if (t == MSPEC) {
852 	    ret = newmspec();
853 	} else if (t == MDEF) {
854 	    ret = newmdef(n);
855 	} else if (t == STR) {
856 	    ret = newstring(flags);
857 	} else if (t == BUNDLE) {
858 	    ret = newbundle(flags);
859 	} else if (t == ARRAY) {
860 	    ret = newarray(flags);
861 	} else if (t == EMPTY) {
862 	    ret = newempty();
863 	} else {
864 	    /* invalid aux node spec */
865 	    p->err = E_DATA;
866 	}
867 
868 	if (!p->err && ret == NULL) {
869 	    p->err = E_ALLOC;
870 	}
871 
872 	if (!p->err) {
873 	    ret->flags |= AUX_NODE;
874 	}
875     }
876 
877     return ret;
878 }
879 
880 /* We come here by preference to the generic get_aux_node()
881    (above) if we want an aux node holding an allocated matrix
882    of known size (m x n). On the second or subsequent
883    iterations of a loop, with any luck we may find that the
884    aux node already holds a matrix of the required dimensions
885    which can then be reused.
886 */
887 
aux_sized_matrix_node(parser * p,int m,int n,int cmplx)888 static NODE *aux_sized_matrix_node (parser *p, int m, int n,
889 				    int cmplx)
890 {
891     NODE *ret = p->aux;
892 
893     if (is_proxy_node(ret)) {
894 	/* this node will get freed later */
895 	ret = NULL;
896     }
897 
898     if (ret != NULL) {
899 	/* got a pre-existing node */
900 	if (ret->t == NUM) {
901 	    /* switch @ret from scalar to matrix */
902 	    ret->t = MAT;
903 	    ret->v.m = NULL;
904 	    ret->flags |= TMP_NODE;
905 	} else if (ret->t != MAT) {
906 	    p->err = E_TYPES;
907 	} else {
908 	    /* check for reusable matrix */
909 	    gretl_matrix *a = ret->v.m;
910 
911 	    if (a != NULL) {
912 		if (a->is_complex + cmplx == 1) {
913 		    /* too difficult to reuse */
914 		    gretl_matrix_free(ret->v.m);
915 		    ret->v.m = NULL;
916 		} else if (a->rows != m || a->cols != n) {
917 		    p->err = gretl_matrix_realloc(ret->v.m, m, n);
918 		}
919 	    }
920 	}
921     } else {
922 	/* we need to create a new node */
923 	ret = newmat(TMP_NODE | AUX_NODE);
924 	if (ret == NULL) {
925 	    p->err = E_ALLOC;
926 	}
927     }
928 
929     if (!p->err && ret->v.m == NULL) {
930 	if (cmplx) {
931 	    ret->v.m = gretl_cmatrix_new(m, n);
932 	} else {
933 	    ret->v.m = gretl_matrix_alloc(m, n);
934 	}
935 	if (ret->v.m == NULL) {
936 	    p->err = E_ALLOC;
937 	}
938     }
939 
940     return ret;
941 }
942 
no_data_error(parser * p)943 static int no_data_error (parser *p)
944 {
945     p->err = E_NODATA;
946     return E_NODATA;
947 }
948 
aux_series_node(parser * p)949 static NODE *aux_series_node (parser *p)
950 {
951     if (p->dset == NULL || p->dset->n == 0) {
952 	no_data_error(p);
953 	return NULL;
954     } else {
955 	return get_aux_node(p, SERIES, p->dset->n, TMP_NODE);
956     }
957 }
958 
aux_empty_series_node(parser * p)959 static NODE *aux_empty_series_node (parser *p)
960 {
961     if (p->dset == NULL || p->dset->n == 0) {
962 	no_data_error(p);
963 	return NULL;
964     } else {
965 	return get_aux_node(p, SERIES, 0, TMP_NODE);
966     }
967 }
968 
aux_list_node(parser * p)969 static NODE *aux_list_node (parser *p)
970 {
971     if (p->dset == NULL || p->dset->n == 0) {
972 	no_data_error(p);
973 	return NULL;
974     } else {
975 	return get_aux_node(p, LIST, 0, TMP_NODE);
976     }
977 }
978 
list_pointer_node(parser * p)979 static NODE *list_pointer_node (parser *p)
980 {
981     if (p->dset == NULL || p->dset->n == 0) {
982 	no_data_error(p);
983 	return NULL;
984     } else {
985 	return get_aux_node(p, LIST, 0, 0);
986     }
987 }
988 
989 #define aux_scalar_node(p) get_aux_node(p,NUM,0,0)
990 #define aux_ivec_node(p,n) get_aux_node(p,IVEC,n,TMP_NODE)
991 #define aux_matrix_node(p) get_aux_node(p,MAT,0,TMP_NODE)
992 #define matrix_pointer_node(p) get_aux_node(p,MAT,0,0)
993 #define aux_mspec_node(p) get_aux_node(p,MSPEC,0,TMP_NODE) /* was 0 */
994 #define aux_string_node(p) get_aux_node(p,STR,0,TMP_NODE)
995 #define string_pointer_node(p) get_aux_node(p,STR,0,0)
996 #define aux_bundle_node(p) get_aux_node(p,BUNDLE,0,TMP_NODE)
997 #define bundle_pointer_node(p) get_aux_node(p,BUNDLE,0,0)
998 #define aux_array_node(p) get_aux_node(p,ARRAY,0,TMP_NODE)
999 #define array_pointer_node(p) get_aux_node(p,ARRAY,0,0)
1000 #define aux_parent_node(p) get_aux_node(p,EMPTY,0,0)
1001 #define aux_any_node(p) get_aux_node(p,0,0,0)
1002 
1003 /* Start of functions that probably should not be needed in
1004    their present full form, but testing is required before
1005    they're slimmed down. The general idea is that we should
1006    already have the user_var pointer we're in need of without
1007    having to look up it by name, again. However, we'll fall
1008    back to name look-up (and squawk about it on stderr) if
1009    need be.
1010 */
1011 
gen_get_lhs_var(parser * p,GretlType type)1012 static void *gen_get_lhs_var (parser *p, GretlType type)
1013 {
1014     void *data = NULL;
1015 
1016     if (p->lh.uv != NULL && p->lh.uv->type == type) {
1017 	data = p->lh.uv->ptr;
1018     } else {
1019 	if (p->lh.uv == NULL) {
1020 	    fprintf(stderr, "*** get: LHS %s '%s' is NULL!\n",
1021 		    gretl_type_get_name(type), p->lh.name);
1022 	} else {
1023 	    fprintf(stderr, "*** get: LHS uv '%s' of wrong type!\n",
1024 		    p->lh.name);
1025 	}
1026 	if (type == GRETL_TYPE_BUNDLE) {
1027 	    data = get_bundle_by_name(p->lh.name);
1028 	} else if (type == GRETL_TYPE_ARRAY) {
1029 	    data = get_array_by_name(p->lh.name);
1030 	} else if (type == GRETL_TYPE_MATRIX) {
1031 	    data = get_matrix_by_name(p->lh.name);
1032 	} else if (type == GRETL_TYPE_STRING) {
1033 	    data = get_string_by_name(p->lh.name);
1034 	} else if (type == GRETL_TYPE_LIST) {
1035 	    data = get_list_by_name(p->lh.name);
1036 	}
1037     }
1038 
1039     return data;
1040 }
1041 
1042 struct typeconv {
1043     GretlType t;
1044     int gen_t;
1045 };
1046 
1047 struct typeconv conversions[] = {
1048     { GRETL_TYPE_DOUBLE, NUM },
1049     { GRETL_TYPE_SERIES, SERIES },
1050     { GRETL_TYPE_MATRIX, MAT },
1051     { GRETL_TYPE_LIST,   LIST },
1052     { GRETL_TYPE_STRING, STR },
1053     { GRETL_TYPE_BUNDLE, BUNDLE },
1054     { GRETL_TYPE_ARRAY,  ARRAY }
1055 };
1056 
gen_type_from_gretl_type(GretlType t)1057 static int gen_type_from_gretl_type (GretlType t)
1058 {
1059     int i, n = G_N_ELEMENTS(conversions);
1060 
1061     for (i=0; i<n; i++) {
1062 	if (t == conversions[i].t) {
1063 	    return conversions[i].gen_t;
1064 	}
1065     }
1066 
1067     return UNDEF;
1068 }
1069 
gretl_type_from_gen_type(int gen_t)1070 static GretlType gretl_type_from_gen_type (int gen_t)
1071 {
1072     int i, n = G_N_ELEMENTS(conversions);
1073 
1074     for (i=0; i<n; i++) {
1075 	if (gen_t == conversions[i].gen_t) {
1076 	    return conversions[i].t;
1077 	}
1078     }
1079 
1080     return GRETL_TYPE_NONE;
1081 }
1082 
gen_type_is_arrayable(int gen_t)1083 static int gen_type_is_arrayable (int gen_t)
1084 {
1085     return gretl_is_arrayable_type(gretl_type_from_gen_type(gen_t));
1086 }
1087 
maybe_rescue_undef_node(NODE * n,parser * p)1088 static NODE *maybe_rescue_undef_node (NODE *n, parser *p)
1089 {
1090     int v = current_series_index(p->dset, n->vname);
1091     user_var *uv = NULL;
1092 
1093     if (v >= 0) {
1094 	n->t = SERIES;
1095 	n->vnum = v;
1096 	n->v.xvec = p->dset->Z[v];
1097 	if (is_string_valued(p->dset, n->vnum)) {
1098 	    n->flags |= SVL_NODE;
1099 	}
1100     } else if ((uv = get_user_var_by_name(n->vname)) != NULL) {
1101 	GretlType type = user_var_get_type(uv);
1102 
1103 	n->t = gen_type_from_gretl_type(type);
1104 	n->uv = uv;
1105 	if (type == GRETL_TYPE_DOUBLE) {
1106 	    n->v.xval = *(double *) uv->ptr;
1107 	} else {
1108 	    n->v.ptr = uv->ptr;
1109 	}
1110     } else {
1111 	undefined_symbol_error(n->vname, p);
1112     }
1113 
1114     return n;
1115 }
1116 
gen_add_or_replace(parser * p,GretlType type,void * data)1117 static int gen_add_or_replace (parser *p, GretlType type, void *data)
1118 {
1119     int err;
1120 
1121     if (p->lh.uv != NULL) {
1122 	err = user_var_replace_value(p->lh.uv, data, type);
1123     } else {
1124 	err = user_var_add_or_replace(p->lh.name, type, data);
1125     }
1126 
1127     return err;
1128 }
1129 
gen_replace_lhs(parser * p,GretlType type,void * data)1130 static int gen_replace_lhs (parser *p, GretlType type, void *data)
1131 {
1132     if (p->lh.uv == NULL) {
1133 	fputs("*** gen_replace_lhs: lhs user_var is NULL ***\n", stderr);
1134 	fprintf(stderr, " (type is specified as %s)\n",
1135 		gretl_type_get_name(type));
1136 	return E_DATA;
1137     } else {
1138 	return user_var_replace_value(p->lh.uv, data, type);
1139     }
1140 }
1141 
gen_add_uvar(parser * p,GretlType type,void * data)1142 static int gen_add_uvar (parser *p, GretlType type, void *data)
1143 {
1144     int err;
1145 
1146     err = user_var_add(p->lh.name, type, data);
1147 
1148     /* FIXME attach lh.uv pointer? */
1149     return err;
1150 }
1151 
gen_edit_list(parser * p,int * list,int op)1152 static int gen_edit_list (parser *p, int *list, int op)
1153 {
1154     user_var *u;
1155     int err;
1156 
1157     if (p->lh.uv != NULL && p->lh.uv->type == GRETL_TYPE_LIST) {
1158 	u = p->lh.uv;
1159     } else {
1160 	if (p->lh.uv == NULL) {
1161 	    fprintf(stderr, "*** replace list: LHS uv is NULL!\n");
1162 	} else {
1163 	    fprintf(stderr, "*** replace list: LHS uv of wrong type!\n");
1164 	}
1165 	u = get_user_var_of_type_by_name(p->lh.name, GRETL_TYPE_LIST);
1166     }
1167 
1168     if (op == B_ASN) {
1169 	err = user_list_replace(u, list);
1170     } else if (op == B_ADD) {
1171 	err = user_list_append(u, list);
1172     } else {
1173 	/* must be B_SUB */
1174 	err = user_list_subtract(u, list, p->dset);
1175     }
1176 
1177     return err;
1178 }
1179 
node_replace_scalar(NODE * n,double x)1180 static int node_replace_scalar (NODE *n, double x)
1181 {
1182     int err = 0;
1183 
1184     if (n->uv != NULL && n->uv->type == GRETL_TYPE_DOUBLE) {
1185 	uvar_set_scalar_fast(n->uv, x);
1186     } else {
1187 	if (n->uv == NULL) {
1188 	    fprintf(stderr, "*** node_replace scalar: node uv is NULL!\n");
1189 	} else {
1190 	    fprintf(stderr, "*** node_replace scalar: node uv of wrong type!\n");
1191 	}
1192 	err = gretl_scalar_set_value(n->vname, x);
1193     }
1194 
1195     return err;
1196 }
1197 
gen_replace_scalar(parser * p,double x)1198 static int gen_replace_scalar (parser *p, double x)
1199 {
1200     int err = 0;
1201 
1202     if (p->lh.uv != NULL && p->lh.uv->type == GRETL_TYPE_DOUBLE) {
1203 	uvar_set_scalar_fast(p->lh.uv, x);
1204     } else {
1205 	if (p->lh.uv == NULL) {
1206 	    fprintf(stderr, "*** gen_replace scalar: LHS uv is NULL!\n");
1207 	} else {
1208 	    fprintf(stderr, "***gen_ replace scalar: LHS uv of wrong type!\n");
1209 	}
1210 	err = gretl_scalar_set_value(p->lh.name, x);
1211     }
1212 
1213     return err;
1214 }
1215 
1216 /* end of functions that can probably be slimmed down */
1217 
eval_warning(parser * p,int op,int errnum)1218 static void eval_warning (parser *p, int op, int errnum)
1219 {
1220     if (!check_gretl_warning()) {
1221 	const char *w = (op == B_POW)? "pow" : getsymb(op);
1222 	const char *s = (errnum)? gretl_strerror(errnum) : NULL;
1223 
1224 	if (s != NULL) {
1225 	    gretl_warnmsg_sprintf("%s: %s", w, s);
1226 	} else {
1227 	    gretl_warnmsg_set(w);
1228 	}
1229     }
1230 }
1231 
1232 /* evaluation of binary operators (yielding x op y) for
1233    scalar operands (also increment/decrement operators)
1234 */
1235 
xy_calc(double x,double y,int op,int targ,parser * p)1236 static double xy_calc (double x, double y, int op, int targ, parser *p)
1237 {
1238     double z = NADBL;
1239 
1240 #if EDEBUG > 1
1241     fprintf(stderr, "xy_calc: x = %g, y = %g, op = %d ('%s')\n",
1242 	    x, y, op, getsymb(op));
1243 #endif
1244 
1245     /* assignment */
1246     if (op == B_ASN || op == B_DOTASN) {
1247 	return y;
1248     }
1249 
1250     /* testing for presence of NAs? */
1251     if ((p->flags & P_NATEST) && (na(x) || na(y))) {
1252 	return NADBL;
1253     }
1254 
1255     /* 0 times anything (even NA) = 0 ? But let's not do this
1256        for matrices */
1257     if (targ != MAT && op == B_MUL && (x == 0 || y == 0)) {
1258 	return 0;
1259     }
1260 
1261     /* logical OR: if x or y is valid and non-zero, ignore NA for
1262        the other term */
1263     if (op == B_OR && ((!na(x) && x != 0) || (!na(y) && y != 0))) {
1264 	return 1.0;
1265     }
1266 
1267     /* logical AND: if either x or y is false, the logical product
1268        should be false, even if the other term is NA */
1269     if (op == B_AND && (x == 0 || y == 0)) {
1270 	return 0;
1271     }
1272 
1273     if (na(x) || na(y)) {
1274 	/* NaN always propagates to the result */
1275 	return NADBL;
1276     }
1277 
1278     errno = 0;
1279 
1280     switch (op) {
1281     case B_ADD:
1282     case INC:
1283 	return x + y;
1284     case B_SUB:
1285     case DEC:
1286 	return x - y;
1287     case B_MUL:
1288 	return x * y;
1289     case B_DIV:
1290 	return x / y;
1291     case B_MOD:
1292 	return fmod(x, y);
1293     case B_AND:
1294 	return x != 0 && y != 0;
1295     case B_OR:
1296 	return x != 0 || y != 0;
1297     case B_EQ:
1298 	return x == y;
1299     case B_NEQ:
1300 	return x != y;
1301     case B_GT:
1302 	return x > y;
1303     case B_LT:
1304 	return x < y;
1305     case B_GTE:
1306 	return x >= y;
1307     case B_LTE:
1308 	return x <= y;
1309     case B_POW:
1310 	z = pow(x, y);
1311 	if (errno) {
1312 	    eval_warning(p, op, errno);
1313 	}
1314 	return z;
1315     default:
1316 	return z;
1317     }
1318 }
1319 
rmatrix_xy_calc(gretl_matrix * targ,gretl_matrix * src,double x,int xleft,int op,parser * p)1320 static int rmatrix_xy_calc (gretl_matrix *targ,
1321 			    gretl_matrix *src,
1322 			    double x, int xleft,
1323 			    int op, parser *p)
1324 {
1325     int i, n = targ->rows * targ->cols;
1326 
1327     if (xleft) {
1328 	for (i=0; i<n; i++) {
1329 	    targ->val[i] = xy_calc(x, src->val[i], op, MAT, p);
1330 	}
1331     } else {
1332 	for (i=0; i<n; i++) {
1333 	    targ->val[i] = xy_calc(src->val[i], x, op, MAT, p);
1334 	}
1335     }
1336 
1337     return p->err;
1338 }
1339 
operator_real_only(int op)1340 static int operator_real_only (int op)
1341 {
1342     gretl_errmsg_sprintf("'%s': %s", getsymb(op),
1343 			 _("complex operands are not supported"));
1344     return E_CMPLX;
1345 }
1346 
function_real_only(int f)1347 static int function_real_only (int f)
1348 {
1349     gretl_errmsg_sprintf("%s: %s", getsymb(f),
1350 			 _("complex arguments are not supported"));
1351     return E_CMPLX;
1352 }
1353 
c_xy_calc(double complex x,double complex y,int op,parser * p)1354 static double complex c_xy_calc (double complex x,
1355 				 double complex y,
1356 				 int op, parser *p)
1357 {
1358     if (op == B_ASN || op == B_DOTASN) {
1359 	return y;
1360     }
1361 
1362     switch (op) {
1363     case B_ADD:
1364 	return x + y;
1365     case B_SUB:
1366 	return x - y;
1367     case B_MUL:
1368 	return x * y;
1369     case B_DIV:
1370 	return x / y;
1371     case B_EQ:
1372 	return x == y;
1373     case B_NEQ:
1374 	return x != y;
1375     default:
1376 	p->err = operator_real_only(op);
1377 	return NADBL;
1378     }
1379 }
1380 
cmatrix_xy_calc(gretl_matrix * targ,gretl_matrix * src,double complex x,int xleft,int op,parser * p)1381 static int cmatrix_xy_calc (gretl_matrix *targ,
1382 			    gretl_matrix *src,
1383 			    double complex x,
1384 			    int xleft, int op,
1385 			    parser *p)
1386 {
1387     int i, n = targ->rows * targ->cols;
1388 
1389     if (xleft) {
1390 	for (i=0; i<n && !p->err; i++) {
1391 	    targ->z[i] = c_xy_calc(x, src->z[i], op, p);
1392 	}
1393     } else {
1394 	for (i=0; i<n && !p->err; i++) {
1395 	    targ->z[i] = c_xy_calc(src->z[i], x, op, p);
1396 	}
1397     }
1398 
1399     return p->err;
1400 }
1401 
cmatrix_xy_comp(gretl_matrix * m,double x,int op,parser * p)1402 static double cmatrix_xy_comp (gretl_matrix *m, double x,
1403 			       int op, parser *p)
1404 {
1405     int i, n = m->rows * m->cols;
1406     double complex zcond, z = x;
1407     double ret = 1;
1408 
1409     for (i=0; i<n && ret==1; i++) {
1410 	zcond = c_xy_calc(m->z[i], z, op, p);
1411 	if (p->err) {
1412 	    ret = NADBL;
1413 	} else if (zcond == 0) {
1414 	    ret = 0;
1415 	}
1416     }
1417 
1418     return ret;
1419 }
1420 
1421 #define randgen(f) (f == F_RANDGEN || f == F_MRANDGEN || f == F_RANDGEN1)
1422 
check_dist_count(int d,int f,int * np,int * argc)1423 static int check_dist_count (int d, int f, int *np, int *argc)
1424 {
1425     int err = 0;
1426 
1427     *np = *argc = 0;
1428 
1429     if (d == D_NC_T || d == D_NC_F || d == D_NC_CHISQ) {
1430 	/* non-central t, chisq and F: only CDF, PDF and INVCDF supported */
1431 	if (f == F_PDF || f == F_CDF || f == F_INVCDF) {
1432 	    *np = (d == D_NC_F) ? 3 : 2;
1433 	} else {
1434 	    err = E_INVARG;
1435 	}
1436     } else if (d == D_UNIFORM || d == D_UDISCRT) {
1437 	/* only RANDGEN is supported */
1438 	if (randgen(f)) {
1439 	    *np = 2; /* min, max */
1440 	} else {
1441 	    err = E_INVARG;
1442 	}
1443     } else if (d == D_NORMAL) {
1444 	/* all functions supported */
1445 	if (randgen(f)) {
1446 	    *np = 2; /* mu, sigma */
1447 	} else {
1448 	    *np = 0; /* N(0,1) is assumed */
1449 	}
1450     } else if (d == D_STUDENT) {
1451 	/* Student t: all functions supported */
1452 	*np = 1; /* df */
1453     } else if (d == D_CHISQ) {
1454 	/* chi-square: all functions supported */
1455 	*np = 1; /* df */
1456     } else if (d == D_SNEDECOR) {
1457 	/* all functions supported */
1458 	*np = 2; /* dfn, dfd */
1459     } else if (d == D_GAMMA) {
1460 	/* partial support */
1461 	if (f == F_CRIT) {
1462 	    err = 1;
1463 	} else {
1464 	    *np = 2; /* shape, scale */
1465 	}
1466     } else if (d == D_BINOMIAL) {
1467 	*np = 2; /* prob, trials */
1468     } else if (d == D_BINORM) {
1469 	/* bivariate normal: cdf only */
1470 	if (f == F_CDF) {
1471 	    *np = 1; /* rho */
1472 	    *argc = 2; /* note: special */
1473 	} else {
1474 	    err = E_INVARG;
1475 	}
1476     } else if (d == D_POISSON) {
1477 	*np = 1;
1478     } else if (d == D_EXPON) {
1479 	/* inverse cdf not supported */
1480 	if (f == F_INVCDF) {
1481 	    err = E_INVARG;
1482 	} else {
1483 	    *np = 1; /* scale */
1484 	}
1485     } else if (d == D_WEIBULL) {
1486 	/* inverse cdf not supported */
1487 	if (f == F_INVCDF) {
1488 	    err = E_INVARG;
1489 	} else {
1490 	    *np = 2; /* shape, scale */
1491 	}
1492     } else if (d == D_GED) {
1493 	*np = 1; /* shape */
1494     } else if (d == D_LAPLACE) {
1495 	*np = 2; /* mean, scale */
1496     } else if (d == D_DW) {
1497 	/* Durbin-Watson: only critical value */
1498 	if (f == F_CRIT) {
1499 	    *np = 2; /* n, k */
1500 	} else {
1501 	    err = E_INVARG;
1502 	}
1503     } else if (d == D_JOHANSEN) {
1504 	/* Johansen trace test: only p-value */
1505 	if (f == F_PVAL) {
1506 	    *np = 3;
1507 	} else {
1508 	    err = E_INVARG;
1509 	}
1510     } else if (d == D_BETA) {
1511 	/* cdf, pdf, randgen only */
1512 	if (f == F_CDF || f == F_PDF || randgen(f)) {
1513 	    *np = 2; /* shape1, shape2 */
1514 	} else {
1515 	    err = E_INVARG;
1516 	}
1517     } else if (d == D_BETABIN) {
1518 	/* randgen only */
1519 	if (randgen(f)) {
1520 	    *np = 3; /* n, shape1, shape2 */
1521 	} else {
1522 	    err = E_INVARG;
1523 	}
1524     } else if (d == D_LOGISTIC) {
1525 	if (randgen(f)) {
1526 	    *np = 2; /* location, scale */
1527 	} else if (f == F_CDF) {
1528 	    *np = 0; /* (0,1) assumed */
1529 	} else {
1530 	    err = E_INVARG;
1531 	}
1532     } else {
1533 	err = E_INVARG;
1534     }
1535 
1536     if (!err && !randgen(f) && *argc == 0) {
1537 	*argc = 1;
1538     }
1539 
1540     return err;
1541 }
1542 
scalar_pdist(int t,int d,const double * parm,int np,double arg,parser * p)1543 static double scalar_pdist (int t, int d, const double *parm,
1544 			    int np, double arg, parser *p)
1545 {
1546     double x = NADBL;
1547     int i;
1548 
1549     for (i=0; i<np; i++) {
1550 	if (na(parm[i])) {
1551 	    return NADBL;
1552 	}
1553     }
1554 
1555     if (t == F_PVAL) {
1556 	x = gretl_get_pvalue(d, parm, arg);
1557     } else if (t == F_PDF) {
1558 	x = gretl_get_pdf(d, parm, arg);
1559     } else if (t == F_CDF) {
1560 	x = gretl_get_cdf(d, parm, arg);
1561     } else if (t == F_INVCDF) {
1562 	x = gretl_get_cdf_inverse(d, parm, arg);
1563     } else if (t == F_CRIT) {
1564 	x = gretl_get_critval(d, parm, arg);
1565     } else {
1566 	p->err = E_PARSE;
1567     }
1568 
1569     return x;
1570 }
1571 
1572 /* @parm contains an array of scalar parameters;
1573    @argvec contains a series of argument values.
1574 */
1575 
series_pdist(double * x,int f,int d,double * parm,int np,const double * argvec,parser * p)1576 static int series_pdist (double *x, int f, int d,
1577 			 double *parm, int np,
1578 			 const double *argvec,
1579 			 parser *p)
1580 {
1581     int t;
1582 
1583     if (f == F_PDF) {
1584 	/* fast treatment, for pdf only at this point */
1585 	int n = sample_size(p->dset);
1586 
1587 	for (t=p->dset->t1; t<=p->dset->t2; t++) {
1588 	    x[t] = argvec[t];
1589 	}
1590 	gretl_fill_pdf_array(d, parm, x + p->dset->t1, n);
1591     } else {
1592 	for (t=p->dset->t1; t<=p->dset->t2; t++) {
1593 	    x[t] = scalar_pdist(f, d, parm, np, argvec[t], p);
1594 	}
1595     }
1596 
1597     return 0;
1598 }
1599 
1600 /* @parm contains an array of zero to two scalar parameters;
1601    @argmat contains an array of argument values.
1602 */
1603 
matrix_pdist(int f,int d,double * parm,int np,gretl_matrix * argmat,parser * p)1604 static gretl_matrix *matrix_pdist (int f, int d,
1605 				   double *parm, int np,
1606 				   gretl_matrix *argmat,
1607 				   parser *p)
1608 {
1609     gretl_matrix *m;
1610     double x;
1611     int i, n;
1612 
1613     if (gretl_is_null_matrix(argmat)) {
1614 	return gretl_null_matrix_new();
1615     }
1616 
1617     m = gretl_matrix_alloc(argmat->rows, argmat->cols);
1618     if (m == NULL) {
1619 	p->err = E_ALLOC;
1620 	return NULL;
1621     }
1622 
1623     n = m->rows * m->cols;
1624 
1625     for (i=0; i<n && !p->err; i++) {
1626 	x = scalar_pdist(f, d, parm, np, argmat->val[i], p);
1627 	if (na(x)) {
1628 	    p->err = E_MISSDATA;
1629 	} else {
1630 	    m->val[i] = x;
1631 	}
1632     }
1633 
1634     if (p->err) {
1635 	gretl_matrix_free(m);
1636 	m = NULL;
1637     }
1638 
1639     return m;
1640 }
1641 
1642 /* Gets a matrix from a node of type MAT or NUM. In the
1643    latter case it's a static matrix, good for use in
1644    calculation, but it should NOT be passed on or
1645    freed.
1646 */
1647 
node_get_matrix(NODE * n,parser * p,int i,int argnum)1648 static gretl_matrix *node_get_matrix (NODE *n, parser *p,
1649 				      int i, int argnum)
1650 {
1651     static gretl_matrix *mm[4];
1652 
1653     if (p->err) {
1654 	/* don't compound prior error */
1655 	return NULL;
1656     } else if (n->t == MAT) {
1657 	return n->v.m;
1658     } else if (n->t != NUM) {
1659 	if (argnum > 0) {
1660 	    gretl_errmsg_sprintf(_("arg %d is missing or of invalid type"),
1661 				 argnum);
1662 	}
1663 	p->err = E_INVARG;
1664 	return NULL;
1665     } else if (i < 0 || i > 3) {
1666 	p->err = E_DATA;
1667 	return NULL;
1668     } else {
1669 	gretl_matrix *ret;
1670 	double x = n->v.xval;
1671 
1672 	if (mm[0] == NULL) {
1673 	    int j;
1674 
1675 	    for (j=0; j<4; j++) {
1676 		mm[j] = gretl_matrix_alloc(1,1);
1677 	    }
1678 	}
1679 	ret = mm[i];
1680 	ret->val[0] = x;
1681 	return ret;
1682     }
1683 }
1684 
node_get_real_matrix(NODE * n,parser * p,int i,int argnum)1685 static gretl_matrix *node_get_real_matrix (NODE *n, parser *p,
1686 					   int i, int argnum)
1687 {
1688     gretl_matrix *m = node_get_matrix(n, p, i, argnum);
1689 
1690     if (!p->err && m->is_complex) {
1691 	p->err = E_CMPLX;
1692 	return NULL;
1693     } else {
1694 	return m;
1695     }
1696 }
1697 
node_get_scalar(NODE * n,parser * p)1698 static double node_get_scalar (NODE *n, parser *p)
1699 {
1700     if (n->t == NUM) {
1701 	return n->v.xval;
1702     } else if (scalar_matrix_node(n)) {
1703 	return n->v.m->val[0];
1704     } else {
1705 	p->err = E_INVARG;
1706 	return NADBL;
1707     }
1708 }
1709 
node_get_int(NODE * n,parser * p)1710 static int node_get_int (NODE *n, parser *p)
1711 {
1712     double x = node_get_scalar(n, p);
1713 
1714     if (p->err) {
1715 	return -1;
1716     } else {
1717 	return gretl_int_from_double(x, &p->err);
1718     }
1719 }
1720 
node_get_guint32(NODE * n,parser * p)1721 static guint32 node_get_guint32 (NODE *n, parser *p)
1722 {
1723     double x = node_get_scalar(n, p);
1724 
1725     if (p->err) {
1726 	return 0;
1727     } else {
1728 	return gretl_unsigned_from_double(x, &p->err);
1729     }
1730 }
1731 
node_get_bool(NODE * n,parser * p,int deflt)1732 static int node_get_bool (NODE *n, parser *p, int deflt)
1733 {
1734     int ret = -1;
1735 
1736     if (!null_node(n)) {
1737 	int k = node_get_int(n, p);
1738 
1739 	if (!p->err) {
1740 	    ret = (k != 0);
1741 	}
1742     } else if (deflt == 0 || deflt == 1) {
1743 	ret = deflt;
1744     } else {
1745 	p->err = E_ARGS;
1746     }
1747 
1748     return ret;
1749 }
1750 
DW_node(NODE * r,parser * p)1751 static NODE *DW_node (NODE *r, parser *p)
1752 {
1753     NODE *s, *e, *ret = NULL;
1754     NODE *save_aux = p->aux;
1755     int i, parm[2] = {0};
1756 
1757     for (i=0; i<2 && !p->err; i++) {
1758 	s = r->v.bn.n[i+1];
1759 	if (scalar_node(s)) {
1760 	    parm[i] = node_get_int(s, p);
1761 	} else {
1762 	    e = eval(s, p);
1763 	    if (!p->err) {
1764 		if (scalar_node(e)) {
1765 		    parm[i] = node_get_int(e, p);
1766 		} else {
1767 		    p->err = E_INVARG;
1768 		}
1769 	    }
1770 	}
1771     }
1772 
1773     if (!p->err && (parm[0] < 6 || parm[1] < 0)) {
1774 	p->err = E_INVARG;
1775     }
1776 
1777     if (!p->err) {
1778 	reset_p_aux(p, save_aux);
1779 	ret = aux_matrix_node(p);
1780 	if (ret != NULL) {
1781 	    ret->v.m = gretl_get_DW(parm[0], parm[1], &p->err);
1782 	}
1783     }
1784 
1785     return ret;
1786 }
1787 
eval_urcpval(NODE * n,parser * p)1788 static NODE *eval_urcpval (NODE *n, parser *p)
1789 {
1790     NODE *ret = NULL;
1791 
1792     if (starting(p)) {
1793 	NODE *save_aux = p->aux;
1794 	NODE *s, *e, *r = n->L;
1795 	int i, m = r->v.bn.n_nodes;
1796 	int iargs[3] = {0};
1797 	double tau = NADBL;
1798 
1799 	if (m != 4) {
1800 	    p->err = E_INVARG;
1801 	}
1802 
1803 	/* need double, int, int, int */
1804 	for (i=0; i<4 && !p->err; i++) {
1805 	    s = r->v.bn.n[i];
1806 	    e = eval(s, p);
1807 	    if (!p->err) {
1808 		if (scalar_node(e)) {
1809 		    if (i == 0) {
1810 			tau = node_get_scalar(e, p);
1811 		    } else {
1812 			iargs[i-1] = node_get_int(e, p);
1813 		    }
1814 		} else {
1815 		    p->err = E_TYPES;
1816 		}
1817 	    }
1818 	}
1819 
1820 	if (!p->err) {
1821 	    int nobs = iargs[0];
1822 	    int niv = iargs[1];
1823 	    int itv = iargs[2];
1824 
1825 	    reset_p_aux(p, save_aux);
1826 	    ret = aux_scalar_node(p);
1827 	    if (ret != NULL) {
1828 		ret->v.xval = get_urc_pvalue(tau, nobs, niv, itv);
1829 	    }
1830 	}
1831     } else {
1832 	ret = aux_any_node(p);
1833     }
1834 
1835     return ret;
1836 }
1837 
get_matrix_size(gretl_matrix * a,gretl_matrix * b,int * r,int * c)1838 static int get_matrix_size (gretl_matrix *a, gretl_matrix *b,
1839 			    int *r, int *c)
1840 {
1841     int err = 0;
1842 
1843     /* if both matrices are present, they must be the
1844        same size */
1845 
1846     if (a != NULL) {
1847 	*r = a->rows;
1848 	*c = b->cols;
1849 	if (b != NULL && (b->rows != *r || b->cols != *c)) {
1850 	    err = E_NONCONF;
1851 	}
1852     } else if (b != NULL) {
1853 	*r = b->rows;
1854 	*c = b->cols;
1855     } else {
1856 	*r = *c = 0;
1857     }
1858 
1859     return err;
1860 }
1861 
bvnorm_node(NODE * n,parser * p)1862 static NODE *bvnorm_node (NODE *n, parser *p)
1863 {
1864     NODE *ret = NULL;
1865 
1866     if (starting(p)) {
1867 	NODE *save_aux = p->aux;
1868 	double *avec = NULL, *bvec = NULL;
1869 	gretl_matrix *amat = NULL, *bmat = NULL;
1870 	double a, b, args[2];
1871 	double rho = NADBL;
1872 	NODE *e;
1873 	int i, mode = 0;
1874 
1875 	for (i=0; i<3 && !p->err; i++) {
1876 	    e = eval(n->v.bn.n[i+1], p);
1877 	    if (p->err) {
1878 		break;
1879 	    }
1880 	    if (scalar_node(e)) {
1881 		if (i == 0) {
1882 		    rho = node_get_scalar(e, p);
1883 		} else {
1884 		    args[i-1] = node_get_scalar(e, p);
1885 		}
1886 	    } else if (i == 1) {
1887 		if (e->t == SERIES) {
1888 		    avec = e->v.xvec;
1889 		} else if (e->t == MAT) {
1890 		    amat = e->v.m;
1891 		}
1892 	    } else if (i == 2) {
1893 		if (e->t == SERIES) {
1894 		    bvec = e->v.xvec;
1895 		} else if (e->t == MAT) {
1896 		    bmat = e->v.m;
1897 		}
1898 	    } else {
1899 		node_type_error(F_CDF, i+1, NUM, e, p);
1900 	    }
1901 	}
1902 
1903 	if (!p->err) {
1904 	    reset_p_aux(p, save_aux);
1905 	    if ((avec != NULL && bmat != NULL) ||
1906 		(bvec != NULL && amat != NULL)) {
1907 		p->err = E_INVARG;
1908 	    } else if (avec != NULL || bvec != NULL) {
1909 		mode = 1;
1910 		ret = aux_series_node(p);
1911 	    } else if (amat != NULL || bmat != NULL) {
1912 		mode = 2;
1913 		ret = aux_matrix_node(p);
1914 	    } else {
1915 		mode = 0;
1916 		ret = aux_scalar_node(p);
1917 	    }
1918 	}
1919 
1920 	if (p->err) {
1921 	    return ret;
1922 	}
1923 
1924 	if (mode == 0) {
1925 	    /* a, b are both scalars */
1926 	    ret->v.xval = bvnorm_cdf(rho, args[0], args[1]);
1927 	} else if (mode == 1) {
1928 	    /* a and/or b are series */
1929 	    int t;
1930 
1931 	    for (t=p->dset->t1; t<=p->dset->t2; t++) {
1932 		a = (avec != NULL)? avec[t] : args[0];
1933 		b = (bvec != NULL)? bvec[t] : args[1];
1934 		if (na(a) || na(b)) {
1935 		    ret->v.xvec[t] = NADBL;
1936 		} else {
1937 		    ret->v.xvec[t] = bvnorm_cdf(rho, a, b);
1938 		}
1939 	    }
1940 	} else if (mode == 2) {
1941 	    /* a and/or b are matrices */
1942 	    gretl_matrix *m = NULL;
1943 	    int r, c;
1944 
1945 	    p->err = get_matrix_size(amat, bmat, &r, &c);
1946 
1947 	    if (!p->err && r > 0 && c > 0) {
1948 		m = gretl_matrix_alloc(r, c);
1949 	    }
1950 
1951 	    if (m != NULL) {
1952 		int i, n = r * c;
1953 
1954 		for (i=0; i<n && !p->err; i++) {
1955 		    a = (amat != NULL)? amat->val[i] : args[0];
1956 		    b = (bmat != NULL)? bmat->val[i] : args[1];
1957 		    m->val[i] = bvnorm_cdf(rho, a, b);
1958 		    if (na(m->val[i])) {
1959 			/* matrix: change NAs to NaNs */
1960 			m->val[i] = 0.0/0.0;
1961 		    }
1962 		}
1963 	    }
1964 
1965 	    if (ret->v.m != NULL) {
1966 		gretl_matrix_free(ret->v.m);
1967 	    }
1968 
1969 	    ret->v.m = m;
1970 	}
1971     } else {
1972 	ret = aux_any_node(p);
1973     }
1974 
1975     return ret;
1976 }
1977 
1978 /* return a node containing the evaluated result of a
1979    probability distribution function */
1980 
eval_pdist(NODE * n,parser * p)1981 static NODE *eval_pdist (NODE *n, parser *p)
1982 {
1983     NODE *ret = NULL;
1984 
1985     if (starting(p)) {
1986 	NODE *save_aux = p->aux;
1987 	NODE *e, *s, *r = n->L;
1988 	int i, k, m = r->v.bn.n_nodes;
1989 	int rgen = (n->t == F_RANDGEN);
1990 	int mrgen = (n->t == F_MRANDGEN);
1991 	int rgen1 = (n->t == F_RANDGEN1);
1992 	double parm[3] = {0};
1993 	double argval = NADBL;
1994 	double *parmvec[2] = { NULL };
1995 	double *argvec = NULL;
1996 	int pvlen[2] = {0};
1997 	gretl_matrix *argmat = NULL;
1998 	int rows = 0, cols = 0;
1999 	int d, np, argc, bb;
2000 
2001 	if (mrgen) {
2002 	    if (m < 4 || m > 7) {
2003 		p->err = E_INVARG;
2004 		goto disterr;
2005 	    }
2006 	} else if (m < 2 || m > 5) {
2007 	    p->err = E_INVARG;
2008 	    goto disterr;
2009 	}
2010 
2011 	s = r->v.bn.n[0];
2012 	if (s->t == STR) {
2013 	    char *dstr = s->v.str;
2014 
2015 	    d = dist_code_from_string(dstr);
2016 	    if (d == 0) {
2017 		dstr = get_string_by_name(dstr);
2018 		if (dstr != NULL) {
2019 		    d = dist_code_from_string(dstr);
2020 		}
2021 	    }
2022 	    if (d == 0) {
2023 		p->err = E_INVARG;
2024 		goto disterr;
2025 	    }
2026 	} else {
2027 	    node_type_error(n->t, 0, STR, s, p);
2028 	    goto disterr;
2029 	}
2030 
2031 	p->err = check_dist_count(d, n->t, &np, &argc);
2032 	k = np + argc + 2 * mrgen;
2033 	if (!p->err && k != m - 1) {
2034 	    p->err = E_INVARG;
2035 	}
2036 	if (p->err) {
2037 	    goto disterr;
2038 	}
2039 
2040 	bb = (d == D_BETABIN);
2041 
2042 	if (d == D_DW) {
2043 	    /* special: Durbin-Watson */
2044 	    return DW_node(r, p);
2045 	} else if (d == D_BINORM) {
2046 	    /* special: bivariate normal */
2047 	    return bvnorm_node(r, p);
2048 	}
2049 
2050 	for (i=1; i<=k && !p->err; i++) {
2051 	    s = r->v.bn.n[i];
2052 	    e = eval(s, p);
2053 	    if (p->err) {
2054 		break;
2055 	    }
2056 	    if (scalar_node(e)) {
2057 		/* scalars always acceptable */
2058 		if (mrgen) {
2059 		    if (i == k) {
2060 			cols = node_get_int(e, p);
2061 		    } else if (i == k-1) {
2062 			rows = node_get_int(e, p);
2063 		    } else {
2064 			parm[i-1] = node_get_scalar(e, p);
2065 		    }
2066 		} else if (i == k && argc > 0) {
2067 		    argval = node_get_scalar(e, p);
2068 		} else {
2069 		    parm[i-1] = node_get_scalar(e, p);
2070 		}
2071 	    } else if (i == k && e->t == SERIES) {
2072 		/* a series in the last place? */
2073 		if (bb) {
2074 		    node_type_error(n->t, i, NUM, e, p);
2075 		} else if (rgen) {
2076 		    parmvec[i-1] = e->v.xvec;
2077 		} else if (mrgen) {
2078 		    node_type_error(n->t, i, NUM, e, p);
2079 		} else {
2080 		    argvec = e->v.xvec;
2081 		}
2082 	    } else if (i == k && e->t == MAT) {
2083 		/* a matrix in the last place? */
2084 		if (mrgen) {
2085 		    parmvec[i-1] = e->v.m->val;
2086 		    pvlen[i-1] = e->v.m->rows * e->v.m->cols;
2087 		} else if (rgen) {
2088 		    node_type_error(n->t, i, NUM, e, p);
2089 		} else {
2090 		    argmat = e->v.m;
2091 		}
2092 	    } else if (e->t == SERIES) {
2093 		/* a series param for randgen? */
2094 		if (rgen && !bb) {
2095 		    parmvec[i-1] = e->v.xvec;
2096 		} else {
2097 		    node_type_error(n->t, i, NUM, e, p);
2098 		}
2099 	    } else if (e->t == MAT) {
2100 		/* a matrix param for mrandgen? */
2101 		if (mrgen && !bb) {
2102 		    parmvec[i-1] = e->v.m->val;
2103 		    pvlen[i-1] = e->v.m->rows * e->v.m->cols;
2104 		} else {
2105 		    node_type_error(n->t, i, NUM, e, p);
2106 		}
2107 	    } else {
2108 		p->err = E_INVARG;
2109 		fprintf(stderr, "eval_pdist: arg %d, bad type %d\n", i+1, e->t);
2110 	    }
2111 	}
2112 
2113 	if (mrgen) {
2114 	    int rlen = rows * cols;
2115 
2116 	    if ((parmvec[0] != NULL && pvlen[0] != rlen) ||
2117 		(parmvec[1] != NULL && pvlen[1] != rlen)) {
2118 		p->err = E_NONCONF;
2119 	    }
2120 	}
2121 
2122 	if (p->err) {
2123 	    goto disterr;
2124 	}
2125 
2126 	reset_p_aux(p, save_aux);
2127 
2128 	if (mrgen) {
2129 	    ret = aux_matrix_node(p);
2130 	} else if (rgen || argvec != NULL) {
2131 	    ret = aux_series_node(p);
2132 	} else if (argmat != NULL) {
2133 	    ret = aux_matrix_node(p);
2134 	} else {
2135 	    ret = aux_scalar_node(p);
2136 	}
2137 
2138 	if (ret == NULL) {
2139 	    goto disterr;
2140 	}
2141 
2142 	if (rgen) {
2143 	    p->err = gretl_fill_random_series(ret->v.xvec, d, parm,
2144 					      parmvec[0], parmvec[1],
2145 					      p->dset);
2146 	} else if (mrgen) {
2147 	    ret->v.m = gretl_get_random_matrix(d, parm,
2148 					       parmvec[0], parmvec[1],
2149 					       rows, cols,
2150 					       &p->err);
2151 	} else if (rgen1) {
2152 	    ret->v.xval = gretl_get_random_scalar(d, parm, &p->err);
2153 	} else if (argvec != NULL) {
2154 	    p->err = series_pdist(ret->v.xvec, n->t, d, parm, np,
2155 				  argvec, p);
2156 	} else if (argmat != NULL) {
2157 	    ret->v.m = matrix_pdist(n->t, d, parm, np, argmat, p);
2158 	} else {
2159 	    ret->v.xval = scalar_pdist(n->t, d, parm, np, argval, p);
2160 	}
2161     } else {
2162 	ret = aux_any_node(p);
2163     }
2164 
2165   disterr:
2166 
2167     return ret;
2168 }
2169 
2170 static int mpi_rank = -1;
2171 static int mpi_size = 0;
2172 
set_mpi_rank_and_size(int rank,int size)2173 void set_mpi_rank_and_size (int rank, int size)
2174 {
2175     mpi_rank = rank;
2176     mpi_size = size;
2177 }
2178 
get_const_by_id(int id)2179 static double get_const_by_id (int id)
2180 {
2181     if (id == CONST_PI) {
2182 	return M_PI;
2183     } else if (id == CONST_EPS) {
2184 	/* see https://en.wikipedia.org/wiki/Machine_epsilon :
2185 	   we now use the (b) definition, as per Matlab, Gauss,
2186 	   R and others
2187 	*/
2188 	return pow(2.0, -52);
2189     } else if (id == CONST_INF) {
2190 #ifdef INFINITY
2191 	return INFINITY;
2192 #else
2193 	return 1.0/0.0;
2194 #endif
2195     } else if (id == CONST_NAN) {
2196 #ifdef NAN
2197 	return NAN;
2198 #else
2199 	return 0.0/0.0;
2200 #endif
2201     } else if (id == CONST_WIN32) {
2202 #ifdef WIN32
2203 	return 1;
2204 #else
2205 	return 0;
2206 #endif
2207     } else if (id == CONST_HAVE_MPI) {
2208 #ifdef HAVE_MPI
2209 	return check_for_mpiexec();
2210 #else
2211 	return 0;
2212 #endif
2213     } else if (id == CONST_MPI_RANK) {
2214 	return mpi_rank;
2215     } else if (id == CONST_MPI_SIZE) {
2216 	return mpi_size;
2217     } else if (id == CONST_N_PROC) {
2218 	return gretl_n_processors();
2219     } else if (id == CONST_TRUE) {
2220 	return 1;
2221     } else if (id == CONST_FALSE) {
2222 	return 0;
2223     } else {
2224 	return NADBL;
2225     }
2226 }
2227 
2228 /* look up and return numerical values of symbolic constants */
2229 
retrieve_const(NODE * n,parser * p)2230 static NODE *retrieve_const (NODE *n, parser *p)
2231 {
2232     NODE *ret = aux_scalar_node(p);
2233 
2234     if (ret != NULL && starting(p)) {
2235 	ret->v.xval = get_const_by_id(n->v.idnum);
2236     }
2237 
2238     return ret;
2239 }
2240 
get_const_by_name(const char * name,int * err)2241 double get_const_by_name (const char *name, int *err)
2242 {
2243     int id = const_lookup(name);
2244 
2245     if (id > 0) {
2246 	return get_const_by_id(id);
2247     } else {
2248 	if (err != NULL) {
2249 	    *err = E_DATA;
2250 	}
2251 	return NADBL;
2252     }
2253 }
2254 
2255 #ifdef HAVE_MPI
2256 
2257 #include "genmpi.c"
2258 
2259 #else
2260 
mpi_transfer_node(NODE * l,NODE * r,NODE * r2,int f,parser * p)2261 static NODE *mpi_transfer_node (NODE *l, NODE *r, NODE *r2,
2262 				int f, parser *p)
2263 {
2264     gretl_errmsg_set(_("MPI is not supported in this gretl build"));
2265     p->err = 1;
2266     return NULL;
2267 }
2268 
mpi_barrier_node(parser * p)2269 static NODE *mpi_barrier_node (parser *p)
2270 {
2271     gretl_errmsg_set(_("MPI is not supported in this gretl build"));
2272     p->err = 1;
2273     return NULL;
2274 }
2275 
2276 #endif /* !HAVE_MPI */
2277 
scalar_calc(NODE * x,NODE * y,int f,parser * p)2278 static NODE *scalar_calc (NODE *x, NODE *y, int f, parser *p)
2279 {
2280     NODE *ret = aux_scalar_node(p);
2281 
2282     if (ret != NULL && starting(p)) {
2283 	ret->v.xval = xy_calc(x->v.xval, y->v.xval, f, NUM, p);
2284     }
2285 
2286     return ret;
2287 }
2288 
string_offset(NODE * l,NODE * r,parser * p)2289 static NODE *string_offset (NODE *l, NODE *r, parser *p)
2290 {
2291     NODE *ret = aux_string_node(p);
2292 
2293     if (ret != NULL && starting(p)) {
2294 	int n = g_utf8_strlen(l->v.str, -1);
2295 	int k = r->v.xval;
2296 
2297 	if (k < 0) {
2298 	    p->err = E_DATA;
2299 	} else if (k >= n) {
2300 	    ret->v.str = gretl_strdup("");
2301 	} else {
2302 	    char *p = g_utf8_offset_to_pointer(l->v.str, k);
2303 
2304 	    ret->v.str = gretl_strdup(p);
2305 	}
2306 	if (!p->err && ret->v.str == NULL) {
2307 	    p->err = E_ALLOC;
2308 	}
2309     }
2310 
2311     return ret;
2312 }
2313 
compare_strings(NODE * l,NODE * r,int f,parser * p)2314 static NODE *compare_strings (NODE *l, NODE *r, int f, parser *p)
2315 {
2316     NODE *ret = aux_scalar_node(p);
2317 
2318     if (ret != NULL && starting(p)) {
2319 	int s = strcmp(l->v.str, r->v.str);
2320 
2321 	ret->v.xval = (f == B_EQ)? (s == 0) : (s != 0);
2322     }
2323 
2324     return ret;
2325 }
2326 
2327 /*
2328    We're looking at a comparison, with either a series on the left and
2329    a string on the right or vice versa.  This can work if the series
2330    in question is string-valued, as in
2331 
2332      Case 1: series foo = (x == "strval")
2333 
2334    It can also work if the string is an observation marker, as in
2335 
2336      Case 2: series foo = (obs >= "CA")
2337 */
2338 
series_string_calc(NODE * l,NODE * r,int f,parser * p)2339 static NODE *series_string_calc (NODE *l, NODE *r, int f, parser *p)
2340 {
2341     double xt = NADBL, yt = NADBL;
2342     double *x = NULL, *y = NULL;
2343     double *alt;
2344     const char *strval;
2345     int vnum, t;
2346     NODE *ret;
2347 
2348     if (r->t == STR) {
2349 	strval = r->v.str;
2350 	vnum = l->vnum;
2351 	x = l->v.xvec;
2352 	alt = &yt;
2353     } else {
2354 	strval = l->v.str;
2355 	vnum = r->vnum;
2356 	y = r->v.xvec;
2357 	alt = &xt;
2358     }
2359 
2360     ret = aux_series_node(p);
2361     if (p->err) {
2362 	return ret;
2363     }
2364 
2365     if (vnum > 0 && is_string_valued(p->dset, vnum)) {
2366 	/* we must be in Case 1 */
2367 	*alt = series_decode_string(p->dset, vnum, strval);
2368 	if (na(*alt)) {
2369 	    /* @strval is not a string value of the given series */
2370 	    double xval = (f == B_EQ)? 0 : (f == B_NEQ)? 1 : NADBL;
2371 
2372 	    for (t=p->dset->t1; t<=p->dset->t2; t++) {
2373 		ret->v.xvec[t] = xval;
2374 	    }
2375 	    return ret; /* NA case handled */
2376 	}
2377     } else {
2378 	/* try interpreting @strval as an observation string */
2379 	if (annual_data(p->dset)) {
2380 	    *alt = get_date_x(p->dset->pd, strval);
2381 	} else {
2382 	    t = dateton(strval, p->dset);
2383 	    if (t >= 0) {
2384 		*alt = t + 1;
2385 	    }
2386 	}
2387     }
2388 
2389     if (na(*alt)) {
2390 	gretl_errmsg_sprintf(_("got invalid field '%s'"), strval);
2391 	p->err = E_TYPES;
2392 	return NULL;
2393     }
2394 
2395     if (ret != NULL) {
2396 	int t1 = autoreg(p) ? p->obs : p->dset->t1;
2397 	int t2 = autoreg(p) ? p->obs : p->dset->t2;
2398 
2399 	for (t=t1; t<=t2; t++) {
2400 	    if (x != NULL) {
2401 		xt = x[t];
2402 	    } else if (y != NULL) {
2403 		yt = y[t];
2404 	    }
2405 	    ret->v.xvec[t] = xy_calc(xt, yt, f, SERIES, p);
2406 	}
2407     }
2408 
2409     return ret;
2410 }
2411 
list_node_get_series(NODE * n,parser * p)2412 static double *list_node_get_series (NODE *n, parser *p)
2413 {
2414     if (n->v.ivec[0] == 1) {
2415 	int v = n->v.ivec[1];
2416 
2417 	if (v >= 0 && v < p->dset->v) {
2418 	    return p->dset->Z[v];
2419 	}
2420     }
2421 
2422     p->err = E_INVARG;
2423     return NULL;
2424 }
2425 
2426 /* At least one of the nodes is a series; the other may be a
2427    scalar or 1 x 1 matrix */
2428 
series_calc(NODE * l,NODE * r,int f,parser * p)2429 static NODE *series_calc (NODE *l, NODE *r, int f, parser *p)
2430 {
2431     NODE *ret = aux_series_node(p);
2432     const double *x = NULL, *y = NULL;
2433     double xt = 0, yt = 0;
2434     int tmax = p->dset->t2;
2435 
2436     if (ret == NULL) {
2437 	return NULL;
2438     }
2439 
2440     if (p->dset->n > p->dset_n) {
2441 	/* can arise when stack() is in the tree ->
2442 	   dataset gets extended on the fly
2443 	*/
2444 	if (l->t == SERIES) {
2445 	    if (useries_node(l)) {
2446 		l->v.xvec = p->dset->Z[l->vnum];
2447 	    } else {
2448 		tmax = MIN(tmax, p->dset_n - 1);
2449 	    }
2450 	}
2451 	if (r->t == SERIES) {
2452 	    if (useries_node(r)) {
2453 		r->v.xvec = p->dset->Z[r->vnum];
2454 	    } else {
2455 		tmax = MIN(tmax, p->dset_n - 1);
2456 	    }
2457 	}
2458     }
2459 
2460     if (l->t == SERIES) {
2461 	x = l->v.xvec;
2462     } else if (l->t == LIST) {
2463 	x = list_node_get_series(l, p);
2464     } else if (l->t == NUM) {
2465 	xt = l->v.xval;
2466     } else if (l->t == MAT) {
2467 	xt = l->v.m->val[0];
2468     }
2469 
2470     if (r->t == SERIES) {
2471 	y = r->v.xvec;
2472     } else if (r->t == LIST) {
2473 	y = list_node_get_series(r, p);
2474     } else if (r->t == NUM) {
2475 	yt = r->v.xval;
2476     } else if (r->t == MAT) {
2477 	yt = r->v.m->val[0];
2478     }
2479 
2480     if (!p->err) {
2481 	int t1 = autoreg(p) ? p->obs : p->dset->t1;
2482 	int t2 = autoreg(p) ? p->obs : tmax;
2483 	int t;
2484 
2485 	for (t=t1; t<=t2; t++) {
2486 	    if (x != NULL) {
2487 		xt = x[t];
2488 	    }
2489 	    if (y != NULL) {
2490 		yt = y[t];
2491 	    }
2492 	    ret->v.xvec[t] = xy_calc(xt, yt, f, SERIES, p);
2493 	}
2494     }
2495 
2496     return ret;
2497 }
2498 
complex_strcalc_ok(NODE * n,parser * p)2499 static int complex_strcalc_ok (NODE *n, parser *p)
2500 {
2501     if (n != p->tree) {
2502 	/* we must be at the top of the tree */
2503 	return 0;
2504     } else if (p->targ != SERIES && p->targ != UNK) {
2505 	/* target must be series or undetermined */
2506 	return 0;
2507     } else if (p->lh.t == SERIES && dataset_is_subsampled(p->dset)) {
2508 	/* can't do when subsampled */
2509 	return 0;
2510     } else {
2511 	/* OK, we'll try it */
2512 	return 1;
2513     }
2514 }
2515 
2516 /* Get node @ret ready to return a string-valued series,
2517    which must be a member of the current dataset.
2518 */
2519 
prepare_stringvec_return(NODE * ret,parser * p,char ** S,int ns,int write_vec)2520 static void prepare_stringvec_return (NODE *ret, parser *p,
2521 				      char **S, int ns,
2522 				      int write_vec)
2523 {
2524     p->flags |= P_STRVEC;
2525 
2526     if (p->lh.t == SERIES) {
2527 	/* overwrite existing LHS series */
2528 	if (write_vec) {
2529 	    double *targ = p->dset->Z[p->lh.vnum];
2530 	    size_t nb = p->dset->n * sizeof *targ;
2531 
2532 	    memcpy(targ, ret->v.xvec, nb);
2533 	}
2534 	series_set_string_vals_direct(p->dset, p->lh.vnum, S, ns);
2535     } else {
2536 	/* or add as new series */
2537 	p->err = dataset_add_allocated_series(p->dset, ret->v.xvec);
2538 	if (!p->err) {
2539 	    int vnew = p->dset->v - 1;
2540 
2541 	    series_set_string_vals_direct(p->dset, vnew, S, ns);
2542 	    strcpy(p->dset->varname[vnew], p->lh.name);
2543 	    ret->v.xvec = NULL; /* donated to dset */
2544 	    ret->vnum = vnew;
2545 	} else {
2546 	    strings_array_free(S, ns);
2547 	}
2548     }
2549 }
2550 
2551 /* Both nodes are string-valued series. We support a limited
2552    set of operations.
2553 */
2554 
stringvec_calc(NODE * l,NODE * r,NODE * n,parser * p)2555 static NODE *stringvec_calc (NODE *l, NODE *r, NODE *n, parser *p)
2556 {
2557     NODE *ret = NULL;
2558     const char *sl, *sr;
2559     char **Sx = NULL;
2560     int nr = 0, nx = 0;
2561     int vl, vr, f = n->t;
2562     int i, t, eq;
2563 
2564     if (f == B_POW && complex_strcalc_ok(n, p)) {
2565 	; /* should be alright */
2566     } else if (f != B_EQ && f != B_NEQ) {
2567 	p->err = E_TYPES;
2568     }
2569     if (p->err) {
2570 	return NULL;
2571     }
2572 
2573     ret = aux_series_node(p);
2574     if (ret == NULL) {
2575 	return NULL;
2576     }
2577 
2578     vl = l->vnum;
2579     vr = r->vnum;
2580 
2581     if (f == B_POW) {
2582 	/* "logical product" */
2583 	char *slr, **Sl, **Sr;
2584 	int nl, j, ll;
2585 
2586 	Sl = series_get_string_vals(p->dset, vl, &nl, 1);
2587 	Sr = series_get_string_vals(p->dset, vr, &nr, 1);
2588 	nx = nl * nr;
2589 
2590 	Sx = strings_array_new(nx);
2591 	if (Sx == NULL) {
2592 	    p->err = E_ALLOC;
2593 	    return ret;
2594 	}
2595 
2596 	for (i=0; i<nl; i++) {
2597 	    ll = strlen(Sl[i]) + 2;
2598 	    for (j=0; j<nr; j++) {
2599 		slr = calloc(ll + strlen(Sr[j]), 1);
2600 		sprintf(slr, "%s.%s", Sl[i], Sr[j]);
2601 		Sx[i*nr+j] = slr;
2602 	    }
2603 	}
2604     }
2605 
2606     for (t=p->dset->t1; t<=p->dset->t2; t++) {
2607 	sl = series_get_string_for_obs(p->dset, vl, t);
2608 	sr = series_get_string_for_obs(p->dset, vr, t);
2609 	if (sl == NULL || sr == NULL) {
2610 	    ret->v.xvec[t] = NADBL;
2611 	} else if (f == B_POW) {
2612 	    int il = p->dset->Z[vl][t] - 1;
2613 	    int ir = p->dset->Z[vr][t] - 1;
2614 
2615 	    ret->v.xvec[t] = il*nr + ir + 1;
2616         } else {
2617             eq = strcmp(sl, sr) == 0;
2618             ret->v.xvec[t] = (f == B_EQ)? eq : !eq;
2619         }
2620     }
2621 
2622     if (f == B_POW && Sx != NULL) {
2623 	prepare_stringvec_return(ret, p, Sx, nx, 1);
2624     }
2625 
2626     return ret;
2627 }
2628 
op_symbol(int op)2629 static int op_symbol (int op)
2630 {
2631     switch (op) {
2632     case B_DOTMULT: return '*';
2633     case B_DOTDIV:  return '/';
2634     case B_DOTPOW:  return '^';
2635     case B_DOTADD:  return '+';
2636     case B_DOTSUB:  return '-';
2637     case B_DOTEQ:   return '=';
2638     case B_DOTGT:   return '>';
2639     case B_DOTLT:   return '<';
2640     case B_DOTGTE:  return ']';
2641     case B_DOTLTE:  return '[';
2642     case B_DOTNEQ:  return '!';
2643     default: return 0;
2644     }
2645 }
2646 
nullmat_multiply(const gretl_matrix * A,const gretl_matrix * B,int op,int * err)2647 static gretl_matrix *nullmat_multiply (const gretl_matrix *A,
2648                                        const gretl_matrix *B,
2649                                        int op, int *err)
2650 {
2651     gretl_matrix *C = NULL;
2652 
2653     if (A->rows == 0 && A->cols == 0 &&
2654         B->rows == 0 && B->cols == 0) {
2655         C = gretl_null_matrix_new();
2656     } else {
2657         int Lc = op == B_TRMUL ? A->rows : A->cols;
2658         int Cr = op == B_TRMUL ? A->cols : A->rows;
2659         int Cc = B->cols;
2660 
2661         if (Lc != B->rows) {
2662             *err = E_NONCONF;
2663         } else {
2664             if (Cr > 0 && Cc > 0) {
2665                 C = gretl_zero_matrix_new(Cr, Cc);
2666             } else {
2667                 C = gretl_matrix_alloc(Cr, Cc);
2668             }
2669             if (C == NULL) {
2670                 *err = E_ALLOC;
2671             }
2672         }
2673     }
2674 
2675     return C;
2676 }
2677 
matrix_add_sub_scalar(const gretl_matrix * A,const gretl_matrix * B,int op)2678 static gretl_matrix *matrix_add_sub_scalar (const gretl_matrix *A,
2679                                             const gretl_matrix *B,
2680                                             int op)
2681 {
2682     gretl_matrix *C;
2683     double xval, *xvec;
2684     int r, c;
2685 
2686     if (gretl_matrix_is_scalar(A)) {
2687         r = B->rows;
2688         c = B->cols;
2689         xval = A->val[0];
2690         xvec = B->val;
2691     } else {
2692         r = A->rows;
2693         c = A->cols;
2694         xval = B->val[0];
2695         xvec = A->val;
2696     }
2697 
2698     C = gretl_matrix_alloc(r, c);
2699 
2700     if (C != NULL) {
2701         int i, n = r * c;
2702 
2703         if (op == B_ADD) {
2704             for (i=0; i<n; i++) {
2705                 C->val[i] = xvec[i] + xval;
2706             }
2707         } else {
2708             if (xvec == A->val) {
2709                 for (i=0; i<n; i++) {
2710                     C->val[i] = xvec[i] - xval;
2711                 }
2712             } else {
2713                 for (i=0; i<n; i++) {
2714                     C->val[i] = xval - xvec[i];
2715                 }
2716             }
2717         }
2718     }
2719 
2720     return C;
2721 }
2722 
2723 /* See if we can reuse an existing matrix on an
2724    auxiliary node. If so, return it; otherwise
2725    free it and return a newly allocated matrix.
2726 */
2727 
calc_get_matrix(gretl_matrix ** pM,int r,int c)2728 static gretl_matrix *calc_get_matrix (gretl_matrix **pM,
2729                                       int r, int c)
2730 {
2731     if (*pM == NULL) {
2732         /* allocate from scratch */
2733         return gretl_matrix_alloc(r, c);
2734     } else if ((*pM)->rows == r && (*pM)->cols == c) {
2735         /* reusable as-is */
2736         return *pM;
2737     } else if ((*pM)->rows == c && (*pM)->cols == r) {
2738         /* reusable if reoriented */
2739         (*pM)->rows = r;
2740         (*pM)->cols = c;
2741         return *pM;
2742     } else {
2743         /* new matrix needed */
2744         gretl_matrix_free(*pM);
2745         *pM = NULL;
2746         return gretl_matrix_alloc(r, c);
2747     }
2748 }
2749 
2750 #define op_no_complex(o) ((o >= B_LT && o <= B_GTE) || \
2751                           (o >= B_DOTLT && o <= B_DOTGTE))
2752 
2753 #define fn_no_complex(f) (f == F_QFORM || f == F_LSOLVE || \
2754                           f == F_CMULT || f == F_CDIV || \
2755                           f == F_CONV2D || f == F_SGN)
2756 
2757 /* return allocated result of binary operation performed on
2758    two matrices */
2759 
real_matrix_calc(const gretl_matrix * A,const gretl_matrix * B,int op,gretl_matrix ** pM)2760 static int real_matrix_calc (const gretl_matrix *A,
2761                              const gretl_matrix *B,
2762                              int op, gretl_matrix **pM)
2763 {
2764     GretlMatrixMod mod;
2765     gretl_matrix *C = NULL;
2766     int ra, ca;
2767     int rb, cb;
2768     int r, c;
2769     int err = 0;
2770 
2771     if (gretl_is_null_matrix(A) ||
2772         gretl_is_null_matrix(B)) {
2773         if (op != B_HCAT && op != B_VCAT && op != F_DSUM &&
2774             op != B_MUL && op != B_TRMUL) {
2775             return E_NONCONF;
2776         }
2777         if (op == B_MUL || op == B_TRMUL) {
2778             C = nullmat_multiply(A, B, op, &err);
2779             goto finish;
2780         }
2781     }
2782 
2783     if (A->is_complex || B->is_complex) {
2784         /* gatekeeper for complex */
2785         if (op_no_complex(op)) {
2786             return operator_real_only(op);
2787         } else if (fn_no_complex(op)) {
2788             return function_real_only(op);
2789         }
2790     }
2791 
2792     switch (op) {
2793     case B_ADD:
2794     case B_SUB:
2795         if (A->is_complex || B->is_complex) {
2796             int sgn = (op == B_SUB)? -1 : 1;
2797 
2798             C = gretl_cmatrix_add_sub(A, B, sgn, &err);
2799         } else if (gretl_matrix_is_scalar(A) ||
2800                    gretl_matrix_is_scalar(B)) {
2801             C = matrix_add_sub_scalar(A, B, op);
2802             if (C == NULL) {
2803                 err = E_ALLOC;
2804             }
2805         } else {
2806             C = calc_get_matrix(pM, A->rows, A->cols);
2807             if (C == NULL) {
2808                 err = E_ALLOC;
2809             } else if (op == B_ADD) {
2810                 err = gretl_matrix_add(A, B, C);
2811             } else {
2812                 err = gretl_matrix_subtract(A, B, C);
2813             }
2814         }
2815         break;
2816     case B_HCAT:
2817     case B_VCAT:
2818         if (op == B_HCAT) {
2819             C = gretl_matrix_col_concat(A, B, &err);
2820         } else {
2821             C = gretl_matrix_row_concat(A, B, &err);
2822         }
2823         break;
2824     case F_DSUM:
2825         C = gretl_matrix_direct_sum(A, B, &err);
2826         break;
2827     case B_MUL:
2828         if (A->is_complex || B->is_complex) {
2829             C = gretl_cmatrix_multiply(A, B, &err);
2830         } else {
2831             ra = gretl_matrix_rows(A);
2832             ca = gretl_matrix_cols(A);
2833             rb = gretl_matrix_rows(B);
2834             cb = gretl_matrix_cols(B);
2835             r = (ra == 1 && ca == 1)? rb : ra;
2836             c = (rb == 1 && cb == 1)? ca : cb;
2837 
2838             C = calc_get_matrix(pM, r, c);
2839             if (C == NULL) {
2840                 err = E_ALLOC;
2841             } else {
2842                 err = gretl_matrix_multiply(A, B, C);
2843                 if (!err) {
2844                     gretl_matrix_transcribe_obs_info(C, A);
2845                 }
2846             }
2847         }
2848         break;
2849     case B_TRMUL:
2850         if (A->is_complex || B->is_complex) {
2851             C = gretl_cmatrix_AHB(A, B, &err);
2852         } else {
2853             ra = gretl_matrix_cols(A);
2854             ca = gretl_matrix_rows(A);
2855             rb = gretl_matrix_rows(B);
2856             cb = gretl_matrix_cols(B);
2857 
2858             r = (ra == 1 && ca == 1)? rb : ra;
2859             c = (rb == 1 && cb == 1)? ca : cb;
2860 
2861             C = calc_get_matrix(pM, r, c);
2862             if (C == NULL) {
2863                 err = E_ALLOC;
2864             } else {
2865                 err = gretl_matrix_multiply_mod(A, GRETL_MOD_TRANSPOSE,
2866                                                 B, GRETL_MOD_NONE,
2867                                                 C, GRETL_MOD_NONE);
2868             }
2869         }
2870         break;
2871     case F_QFORM:
2872         /* quadratic form, A * B * A', for symmetric B */
2873         ra = gretl_matrix_rows(A);
2874         ca = gretl_matrix_cols(A);
2875         rb = gretl_matrix_rows(B);
2876         cb = gretl_matrix_cols(B);
2877 
2878         if (ca != rb || cb != rb) {
2879             err = E_NONCONF;
2880         } else {
2881             gretl_matrix_set_equals_tolerance(1.0e-7);
2882             if (!gretl_matrix_is_symmetric(B)) {
2883                 gretl_errmsg_set(_("Matrix is not symmetric"));
2884                 err = E_NONCONF;
2885             }
2886             gretl_matrix_unset_equals_tolerance();
2887         }
2888         if (!err) {
2889             C = calc_get_matrix(pM, ra, ra);
2890             if (C == NULL) {
2891                 err = E_ALLOC;
2892             } else {
2893                 mod = GRETL_MOD_NONE;
2894                 err = gretl_matrix_qform(A, mod, B, C, mod);
2895             }
2896         }
2897         break;
2898     case B_LDIV:
2899     case B_DIV:
2900         /* Matrix left (A\B) or right (A/B) "division": note that
2901            A/B = (B'\A')', which we handle by passing the transpose
2902            flag to gretl_{c}matrix_divide.
2903         */
2904         mod = (op == B_LDIV)? GRETL_MOD_NONE : GRETL_MOD_TRANSPOSE;
2905         if (A->is_complex || B->is_complex) {
2906             C = gretl_cmatrix_divide(A, B, mod, &err);
2907         } else {
2908             C = gretl_matrix_divide(A, B, mod, &err);
2909         }
2910         break;
2911     case F_LSOLVE:
2912         C = calc_get_matrix(pM, B->rows, B->cols);
2913         if (C == NULL) {
2914             err = E_ALLOC;
2915         } else {
2916             gretl_matrix_copy_values(C, B);
2917             err = gretl_cholesky_solve(A, C);
2918         }
2919         break;
2920     case B_DOTMULT:
2921     case B_DOTDIV:
2922     case B_DOTPOW:
2923     case B_DOTADD:
2924     case B_DOTSUB:
2925     case B_DOTEQ:
2926     case B_DOTGT:
2927     case B_DOTLT:
2928     case B_DOTGTE:
2929     case B_DOTLTE:
2930     case B_DOTNEQ:
2931         /* apply operator element-wise */
2932         if (A->is_complex || B->is_complex) {
2933             C = gretl_cmatrix_dot_op(A, B, op_symbol(op), &err);
2934         } else {
2935             C = gretl_matrix_dot_op(A, B, op_symbol(op), &err);
2936         }
2937         break;
2938     case B_KRON:
2939         if (A->is_complex || B->is_complex) {
2940             C = gretl_cmatrix_kronecker(A, B, &err);
2941         } else {
2942             C = gretl_matrix_kronecker_product_new(A, B, &err);
2943         }
2944         break;
2945     case F_HDPROD:
2946         if (A->is_complex || B->is_complex) {
2947             C = gretl_cmatrix_hdprod(A, B, &err);
2948         } else {
2949             C = gretl_matrix_hdproduct_new(A, B, &err);
2950         }
2951         break;
2952     case F_CMULT:
2953         C = gretl_matrix_complex_multiply(A, B, 0, &err);
2954         break;
2955     case F_CDIV:
2956         C = gretl_matrix_complex_divide(A, B, 0, &err);
2957         break;
2958     case F_MRSEL:
2959         C = gretl_matrix_bool_sel(A, B, 1, &err);
2960         break;
2961     case F_MCSEL:
2962         C = gretl_matrix_bool_sel(A, B, 0, &err);
2963         break;
2964     case F_CONV2D:
2965         C = gretl_matrix_2d_convolution(A, B, &err);
2966         break;
2967     default:
2968         err = E_TYPES;
2969         break;
2970     }
2971 
2972     if (err) {
2973         if (C != NULL) {
2974             if (pM != NULL && *pM == C) {
2975                 *pM = NULL;
2976             }
2977             gretl_matrix_free(C);
2978             C = NULL;
2979         }
2980     } else {
2981         /* preserve data-row info? */
2982         int At1 = gretl_matrix_get_t1(A);
2983         int At2 = gretl_matrix_get_t2(A);
2984         int Bt1 = gretl_matrix_get_t1(B);
2985         int Bt2 = gretl_matrix_get_t2(B);
2986 
2987         if (C->rows == A->rows && At1 >= 0 && At2 > At1) {
2988             gretl_matrix_set_t1(C, At1);
2989             gretl_matrix_set_t2(C, At2);
2990         } else if (C->rows == B->rows && Bt1 >= 0 && Bt2 > Bt1) {
2991             gretl_matrix_set_t1(C, Bt1);
2992             gretl_matrix_set_t2(C, Bt2);
2993         }
2994     }
2995 
2996  finish:
2997 
2998     if (*pM != NULL && *pM != C) {
2999         /* we neither freed nor reused *pM */
3000         gretl_matrix_free(*pM);
3001     }
3002 
3003     *pM = C;
3004 
3005     return err;
3006 }
3007 
tmp_matrix_from_series(NODE * n,parser * p)3008 static gretl_matrix *tmp_matrix_from_series (NODE *n, parser *p)
3009 {
3010     int T = sample_size(p->dset);
3011     const double *x = n->v.xvec;
3012     gretl_matrix *m = NULL;
3013 
3014     m = gretl_column_vector_alloc(T);
3015 
3016     if (m == NULL) {
3017         p->err = E_ALLOC;
3018     } else {
3019         memcpy(m->val, x + p->dset->t1, T * sizeof *x);
3020     }
3021 
3022     return m;
3023 }
3024 
3025 /* "Fake" a series using a column vector: the vector must be
3026    of the same length as the current dataset.
3027 */
3028 
get_colvec_as_series(NODE * n,int f,parser * p)3029 const double *get_colvec_as_series (NODE *n, int f, parser *p)
3030 {
3031     if (n->t != MAT) {
3032         node_type_error(f, 1, SERIES, n, p);
3033         return NULL;
3034     } else {
3035         const gretl_matrix *m = n->v.m;
3036 
3037         if (m->rows == p->dset->n && m->cols == 1) {
3038             return m->val;
3039         } else {
3040             node_type_error(f, 1, SERIES, n, p);
3041             return NULL;
3042         }
3043     }
3044 }
3045 
3046 /* One of the operands is a matrix (or scalar), the other
3047    a series: we "cast" the series to a matrix.
3048 */
3049 
matrix_series_calc(NODE * l,NODE * r,int op,parser * p)3050 static NODE *matrix_series_calc (NODE *l, NODE *r, int op, parser *p)
3051 {
3052     NODE *ret = aux_matrix_node(p);
3053 
3054     if (ret != NULL && starting(p)) {
3055         gretl_matrix *a, *b, *tmp;
3056 
3057         if (l->t == SERIES) {
3058             tmp = a = tmp_matrix_from_series(l, p);
3059             b = node_get_real_matrix(r, p, 0, 0);
3060         } else {
3061             a = node_get_real_matrix(l, p, 0, 0);
3062             tmp = b = tmp_matrix_from_series(r, p);
3063         }
3064 
3065         if (!p->err) {
3066             p->err = real_matrix_calc(a, b, op, &ret->v.m);
3067         }
3068 
3069         gretl_matrix_free(tmp);
3070     }
3071 
3072     return ret;
3073 }
3074 
array_str_calc(NODE * l,NODE * r,int op,parser * p)3075 static NODE *array_str_calc (NODE *l, NODE *r, int op, parser *p)
3076 {
3077     NODE *ret = aux_matrix_node(p);
3078 
3079     if (ret != NULL && starting(p)) {
3080         gretl_array *a = l->v.a;
3081 
3082 	if (gretl_array_get_type(a) != GRETL_TYPE_STRINGS) {
3083 	    p->err = E_TYPES;
3084 	} else {
3085 	    int i, n = gretl_array_get_length(a);
3086 	    const char *si;
3087 
3088 	    ret->v.m = gretl_zero_matrix_new(1, n);
3089 	    if (ret->v.m == NULL) {
3090 		p->err = E_ALLOC;
3091 	    } else {
3092 		for (i=0; i<n; i++) {
3093 		    si = gretl_array_get_data(a, i);
3094 		    if (op == B_DOTEQ) {
3095 			if (si != NULL && !strcmp(si, r->v.str)) {
3096 			    ret->v.m->val[i] = 1;
3097 			}
3098 		    } else if (si == NULL || strcmp(si, r->v.str)) {
3099 			ret->v.m->val[i] = 1;
3100 		    }
3101 		}
3102 	    }
3103 	}
3104     }
3105 
3106     return ret;
3107 }
3108 
3109 #define comparison_op(o) (o == B_EQ  || o == B_NEQ || \
3110                           o == B_LT  || o == B_GT ||  \
3111                           o == B_LTE || o == B_GTE)
3112 
3113 /* Here we know have a scalar and a 1 x 1 matrix to work with,
3114    in either order */
3115 
matrix_scalar_calc2(NODE * l,NODE * r,int op,parser * p)3116 static NODE *matrix_scalar_calc2 (NODE *l, NODE *r, int op,
3117                                   parser *p)
3118 {
3119     NODE *ret;
3120 
3121     if (scalar_node(l) && scalar_node(r) && comparison_op(op)) {
3122 	ret = aux_scalar_node(p);
3123     } else if (l->t == NUM && (op == B_MOD || op == B_POW)) {
3124         /* the matrix on the right is functioning as
3125            a scalar argument, so produce a scalar
3126         */
3127         ret = aux_scalar_node(p);
3128     } else {
3129         /* one of the operands is a matrix, albeit 1 x 1,
3130            so it's safer to produce a matrix result
3131         */
3132         ret = aux_sized_matrix_node(p, 1, 1, 0);
3133     }
3134 
3135     if (!p->err) {
3136         double x, y;
3137 
3138         if (l->t == NUM) {
3139             x = l->v.xval;
3140             y = r->v.m->val[0];
3141         } else {
3142             x = l->v.m->val[0];
3143             y = r->v.xval;
3144         }
3145 
3146         if (ret->t == NUM) {
3147             ret->v.xval = xy_calc(x, y, op, NUM, p);
3148         } else {
3149             ret->v.m->val[0] = xy_calc(x, y, op, MAT, p);
3150         }
3151     }
3152 
3153     return ret;
3154 }
3155 
3156 /* Mixed types: one of the operands is a matrix, the other a scalar,
3157    giving a matrix result unless we're looking at a comparison
3158    operator.
3159 */
3160 
matrix_scalar_calc(NODE * l,NODE * r,int op,parser * p)3161 static NODE *matrix_scalar_calc (NODE *l, NODE *r, int op, parser *p)
3162 {
3163     gretl_matrix *m = NULL;
3164     int comp = comparison_op(op);
3165     double x;
3166     NODE *ret = NULL;
3167 
3168     /* Check for the simple case of scalar and
3169        1 x 1 matrix, either way round
3170     */
3171     if ((l->t == NUM && scalar_node(r)) ||
3172         (r->t == NUM && scalar_node(l))) {
3173         return matrix_scalar_calc2(l, r, op, p);
3174     }
3175 
3176     /* get a scalar @x and matrix @m */
3177     x = (l->t == NUM)? l->v.xval : r->v.xval;
3178     m = (l->t == MAT)? l->v.m : r->v.m;
3179 
3180     if (gretl_is_null_matrix(m)) {
3181         p->err = E_DATA;
3182         return NULL;
3183     }
3184 
3185     /* mod, pow: the right-hand term must be scalar */
3186     if ((op == B_MOD || op == B_POW) && !scalar_node(r)) {
3187         p->err = E_TYPES;
3188         return NULL;
3189     }
3190 
3191     if (comp) {
3192         ret = aux_scalar_node(p);
3193     } else if (op == B_POW) {
3194         ret = aux_matrix_node(p);
3195     } else {
3196         ret = aux_sized_matrix_node(p, m->rows, m->cols, m->is_complex);
3197     }
3198 
3199     if (ret == NULL) {
3200         return NULL;
3201     }
3202 
3203     if (op == B_POW) {
3204         /* note: the (scalar, 1x1) and (1x1, scalar) cases are
3205            handled above
3206         */
3207         double s = node_get_scalar(r, p);
3208 
3209         if (!p->err) {
3210             ret->v.m = gretl_matrix_pow(m, s, &p->err);
3211         }
3212         return ret;
3213     } else {
3214         int i, n = m->rows * m->cols;
3215 
3216         if (comp && m->is_complex) {
3217             /* B_EQ and B_NOTEQ; needs special treatment */
3218             ret->v.xval = cmatrix_xy_comp(m, x, op, p);
3219         } else if (comp) {
3220             /* condition assumed true by until shown false */
3221             double cond = 1;
3222 
3223             for (i=0; i<n && cond==1; i++) {
3224                 if (l->t == NUM) {
3225                     cond = xy_calc(x, m->val[i], op, MAT, p);
3226                 } else {
3227                     cond = xy_calc(m->val[i], x, op, MAT, p);
3228                 }
3229             }
3230             ret->v.xval = cond;
3231         } else {
3232             int xleft = (l->t == NUM);
3233 
3234             if (m->is_complex) {
3235                 p->err = cmatrix_xy_calc(ret->v.m, m, x, xleft, op, p);
3236             } else {
3237                 p->err = rmatrix_xy_calc(ret->v.m, m, x, xleft, op, p);
3238             }
3239             if (gretl_matrix_is_dated(m)) {
3240                 gretl_matrix_set_t1(ret->v.m, gretl_matrix_get_t1(m));
3241                 gretl_matrix_set_t2(ret->v.m, gretl_matrix_get_t2(m));
3242             }
3243         }
3244     }
3245 
3246     return ret;
3247 }
3248 
matrix_transpose_node(NODE * n,parser * p)3249 static NODE *matrix_transpose_node (NODE *n, parser *p)
3250 {
3251     NODE *ret = NULL;
3252 
3253     if (starting(p)) {
3254         if (is_tmp_node(n)) {
3255             /* transpose temp matrix in place */
3256             if (n->v.m->is_complex) {
3257                 p->err = gretl_ctrans_in_place(n->v.m);
3258             } else {
3259                 p->err = gretl_matrix_transpose_in_place(n->v.m);
3260             }
3261             ret = n;
3262         } else {
3263             /* create transpose as new matrix */
3264             ret = aux_matrix_node(p);
3265             if (!p->err) {
3266                 if (n->v.m->is_complex) {
3267                     ret->v.m = gretl_ctrans(n->v.m, 1, &p->err);
3268                 } else {
3269                     ret->v.m = gretl_matrix_copy_transpose(n->v.m);
3270                 }
3271                 if (ret->v.m == NULL) {
3272                     p->err = E_ALLOC;
3273                 }
3274             }
3275         }
3276     } else {
3277         ret = is_tmp_node(n) ? n : aux_matrix_node(p);
3278     }
3279 
3280     return ret;
3281 }
3282 
3283 /* We're looking at a string argument that is supposed to represent
3284    a function call: we'll do a rudimentary heuristic check here.
3285    FIXME this should be more rigorous?
3286 */
3287 
is_function_call(const char * s)3288 static int is_function_call (const char *s)
3289 {
3290     if (!strchr(s, '(') || !strchr(s, ')')) {
3291         return 0;
3292     } else {
3293         return 1;
3294     }
3295 }
3296 
numeric_jacobian_or_hessian(NODE * l,NODE * m,NODE * r,int f,parser * p)3297 static NODE *numeric_jacobian_or_hessian (NODE *l, NODE *m, NODE *r,
3298                                           int f, parser *p)
3299 {
3300     NODE *ret = NULL;
3301 
3302     if (starting(p)) {
3303         const char *s = m->v.str;
3304         double eps = 0.0;
3305 
3306         if (!is_function_call(s)) {
3307             p->err = E_TYPES;
3308             return NULL;
3309         }
3310 
3311         ret = aux_matrix_node(p);
3312         if (ret == NULL) {
3313             return NULL;
3314         }
3315 
3316         if (!null_node(r)) {
3317             eps = node_get_scalar(r, p);
3318         }
3319 
3320         if (!p->err) {
3321             if (f == F_FDJAC) {
3322                 ret->v.m = user_fdjac(l->v.m, s, eps, p->dset, &p->err);
3323             } else {
3324                 ret->v.m = user_numhess(l->v.m, s, eps, p->dset, &p->err);
3325             }
3326         }
3327     } else {
3328         ret = aux_matrix_node(p);
3329     }
3330 
3331     return ret;
3332 }
3333 
3334 /* note: allows @n to be either a regular matrix node or a
3335    matrix-pointer node
3336 */
3337 
mat_node_get_real_matrix(NODE * n,parser * p)3338 static gretl_matrix *mat_node_get_real_matrix (NODE *n, parser *p)
3339 {
3340     if (n->t == U_ADDR) {
3341         n = n->L;
3342     }
3343     if (n == NULL || n->t != MAT) {
3344         p->err = E_TYPES;
3345         return NULL;
3346     } else if (n->v.m->is_complex) {
3347         p->err = E_CMPLX;
3348         return NULL;
3349     } else {
3350         return n->v.m;
3351     }
3352 }
3353 
ptr_node_get_uvar(NODE * n,int t,parser * p)3354 static user_var *ptr_node_get_uvar (NODE *n, int t, parser *p)
3355 {
3356     user_var *uv = NULL;
3357 
3358     if (n->t == U_ADDR) {
3359         NODE *nb = n->L;
3360 
3361         if (nb->t == t) {
3362             uv = nb->uv;
3363         }
3364     }
3365 
3366     if (uv == NULL) {
3367         p->err = E_TYPES;
3368     }
3369 
3370     return uv;
3371 }
3372 
ptr_node_get_matrix(NODE * n,parser * p)3373 static gretl_matrix *ptr_node_get_matrix (NODE *n, parser *p)
3374 {
3375     user_var *uv = ptr_node_get_uvar(n, MAT, p);
3376 
3377     return uv != NULL ? uv->ptr : NULL;
3378 }
3379 
node_get_fncall(NODE * n,parser * p)3380 static const char *node_get_fncall (NODE *n, parser *p)
3381 {
3382     const char *ret = NULL;
3383 
3384     if (n->t != STR) {
3385         p->err = E_TYPES;
3386     } else {
3387         ret = n->v.str;
3388         if (!is_function_call(ret)) {
3389             p->err = E_TYPES;
3390         }
3391     }
3392 
3393     return ret;
3394 }
3395 
n_args_error(int k,int n,int f,parser * p)3396 static void n_args_error (int k, int n, int f, parser *p)
3397 {
3398     gretl_errmsg_sprintf( _("Number of arguments (%d) does not "
3399                             "match the number of\nparameters for "
3400                             "function %s (%d)"), k, getsymb(f), n);
3401     p->err = 1;
3402 }
3403 
BFGS_constrained_max(NODE * t,parser * p)3404 static NODE *BFGS_constrained_max (NODE *t, parser *p)
3405 {
3406     NODE *save_aux = p->aux;
3407     NODE *n = t->L;
3408     NODE *ret = NULL;
3409     NODE *e = NULL;
3410     gretl_matrix *b = NULL;
3411     gretl_matrix *bounds = NULL;
3412     const char *sf = NULL;
3413     const char *sg = NULL;
3414     int i, k = n->v.bn.n_nodes;
3415 
3416     if (k < 3 || k > 4) {
3417         n_args_error(k, 3, F_BFGSCMAX, p);
3418     }
3419 
3420     for (i=0; i<k && !p->err; i++) {
3421         e = n->v.bn.n[i];
3422         if (i == 0) {
3423             b = mat_node_get_real_matrix(e, p);
3424         } else if (i == 1) {
3425             e = eval(n->v.bn.n[i], p);
3426             if (!p->err) {
3427                 bounds = mat_node_get_real_matrix(e, p);
3428             }
3429         } else if (i == 2) {
3430             sf = node_get_fncall(e, p);
3431         } else if (i == 3 && !null_node(e)) {
3432             sg = node_get_fncall(e, p);
3433         }
3434     }
3435 
3436     if (!p->err) {
3437         reset_p_aux(p, save_aux);
3438         ret = aux_scalar_node(p);
3439     }
3440 
3441     if (!p->err) {
3442         int minimize = alias_reversed(t) ? 1 : 0;
3443 
3444         ret->v.xval = user_BFGS(b, sf, sg, p->dset, bounds,
3445                                 minimize, p->prn, &p->err);
3446     }
3447 
3448     return ret;
3449 }
3450 
BFGS_maximize(NODE * l,NODE * m,NODE * r,parser * p,NODE * t)3451 static NODE *BFGS_maximize (NODE *l, NODE *m, NODE *r,
3452                             parser *p, NODE *t)
3453 {
3454     NODE *ret = NULL;
3455 
3456     if (starting(p)) {
3457         gretl_matrix *b;
3458         const char *sf = m->v.str;
3459         const char *sg = NULL;
3460 
3461         b = mat_node_get_real_matrix(l, p);
3462 
3463         if (!p->err) {
3464             if (r->t == STR) {
3465                 sg = r->v.str;
3466             } else if (r->t != EMPTY) {
3467                 p->err = E_TYPES;
3468             }
3469         }
3470         if (!p->err && !is_function_call(sf)) {
3471             p->err = E_TYPES;
3472         }
3473         if (!p->err && sg != NULL && !is_function_call(sg)) {
3474             p->err = E_TYPES;
3475         }
3476         if (!p->err && gretl_is_null_matrix(b)) {
3477             p->err = E_DATA;
3478         }
3479         if (p->err) {
3480             return NULL;
3481         }
3482 
3483         ret = aux_scalar_node(p);
3484         if (ret != NULL) {
3485             int minimize = alias_reversed(t) ? 1 : 0;
3486 
3487             ret->v.xval = user_BFGS(b, sf, sg, p->dset, NULL,
3488                                     minimize, p->prn, &p->err);
3489         }
3490     } else {
3491         ret = aux_scalar_node(p);
3492     }
3493 
3494     return ret;
3495 }
3496 
deriv_free_node(NODE * l,NODE * m,NODE * r,parser * p,NODE * t)3497 static NODE *deriv_free_node (NODE *l, NODE *m, NODE *r,
3498                               parser *p, NODE *t)
3499 {
3500     NODE *ret = NULL;
3501 
3502     if (starting(p)) {
3503         gretl_matrix *b = NULL;
3504         const char *fcall = m->v.str;
3505         double tol = NADBL;
3506         int maxit = 0;
3507 
3508         b = mat_node_get_real_matrix(l, p);
3509         if (!p->err) {
3510             if (gretl_is_null_matrix(b)) {
3511                 p->err = E_DATA;
3512             } else if (!is_function_call(fcall)) {
3513                 p->err = E_TYPES;
3514             }
3515         }
3516         if (!p->err) {
3517             if (scalar_node(r)) {
3518                 if (t->t == F_GSSMAX) {
3519                     tol = r->v.xval;
3520                 } else {
3521                     maxit = node_get_int(r, p);
3522                 }
3523             } else if (!null_node(r)) {
3524                 p->err = E_TYPES;
3525             }
3526         }
3527         if (!p->err) {
3528             ret = aux_scalar_node(p);
3529         }
3530         if (ret != NULL) {
3531             int minimize = alias_reversed(t) ? 1 : 0;
3532             MaxMethod method = SIMANN_MAX;
3533 
3534             if (t->t == F_NMMAX) {
3535                 method = NM_MAX;
3536             } else if (t->t == F_GSSMAX) {
3537                 method = GSS_MAX;
3538             }
3539             ret->v.xval = deriv_free_optimize(method, b, fcall, maxit, tol,
3540                                               minimize, p->dset, p->prn,
3541                                               &p->err);
3542         }
3543     } else {
3544         ret = aux_scalar_node(p);
3545     }
3546 
3547     return ret;
3548 }
3549 
fzero_node(NODE * l,NODE * m,NODE * r,parser * p)3550 static NODE *fzero_node (NODE *l, NODE *m, NODE *r, parser *p)
3551 {
3552     NODE *ret = NULL;
3553 
3554     if (starting(p)) {
3555         const char *fcall = l->v.str;
3556         gretl_matrix *b = NULL;
3557         double tol = NADBL;
3558         int free_b = 0;
3559 
3560         if (null_or_scalar(m)) {
3561             b = gretl_matrix_alloc(1, 2);
3562             b->val[0] = null_node(m) ? NADBL : node_get_scalar(m, p);
3563             b->val[1] = NADBL;
3564             free_b = 1;
3565         } else if (m->t == MAT) {
3566             b = m->v.m;
3567         } else {
3568             p->err = E_TYPES;
3569         }
3570         if (!p->err) {
3571             if (gretl_is_null_matrix(b)) {
3572                 p->err = E_DATA;
3573             } else if (!is_function_call(fcall)) {
3574                 p->err = E_TYPES;
3575             }
3576         }
3577         if (!p->err) {
3578             if (scalar_node(r)) {
3579                 tol = node_get_scalar(r, p);
3580             } else if (!null_node(r)) {
3581                 p->err = E_TYPES;
3582             }
3583         }
3584         if (!p->err) {
3585             ret = aux_scalar_node(p);
3586         }
3587         if (ret != NULL) {
3588             ret->v.xval = deriv_free_optimize(ROOT_FIND, b, fcall, 0,
3589                                               tol, 0, p->dset, p->prn,
3590                                               &p->err);
3591         }
3592         if (free_b) {
3593             gretl_matrix_free(b);
3594         }
3595     } else {
3596         ret = aux_scalar_node(p);
3597     }
3598 
3599     return ret;
3600 }
3601 
lag_calc(double * y,const double * x,int k,int t1,int t2,int op,double mul,parser * p)3602 static void lag_calc (double *y, const double *x,
3603                       int k, int t1, int t2,
3604                       int op, double mul,
3605                       parser *p)
3606 {
3607     int s, t;
3608 
3609     for (t=t1; t<=t2; t++) {
3610         s = t - k;
3611         if (dataset_is_panel(p->dset)) {
3612             if (s / p->dset->pd != t / p->dset->pd) {
3613                 /* s and t pertain to different units */
3614                 s = -1;
3615             }
3616         }
3617         if (s >= 0 && s < p->dset->n) {
3618             if (op == B_ASN && mul == 1.0) {
3619                 y[t] = x[s];
3620             } else if (op == B_ASN) {
3621                 y[t] = mul * x[s];
3622             } else if (op == B_ADD) {
3623                 y[t] += mul * x[s];
3624             } else {
3625                 p->err = E_DATA;
3626             }
3627         }
3628     }
3629 }
3630 
matrix_file_write(NODE * l,NODE * m,NODE * r,parser * p)3631 static NODE *matrix_file_write (NODE *l, NODE *m, NODE *r, parser *p)
3632 {
3633     NODE *ret = NULL;
3634 
3635     if (starting(p)) {
3636         const char *fname = m->v.str;
3637 
3638         ret = aux_scalar_node(p);
3639         if (ret != NULL) {
3640             int done = 0;
3641 
3642 #ifdef HAVE_MPI
3643             if (has_suffix(fname, ".shm")) {
3644                 ret->v.xval = shm_write_matrix(l->v.m, fname);
3645                 done = 1;
3646             }
3647 #endif
3648             if (!done) {
3649                 int export = node_get_bool(r, p, 0);
3650 
3651                 ret->v.xval = gretl_matrix_write_to_file(l->v.m, fname, export);
3652             }
3653         }
3654     } else {
3655         ret = aux_scalar_node(p);
3656     }
3657 
3658     return ret;
3659 }
3660 
bundle_file_write(NODE * l,NODE * m,NODE * r,parser * p)3661 static NODE *bundle_file_write (NODE *l, NODE *m, NODE *r, parser *p)
3662 {
3663     NODE *ret = NULL;
3664 
3665     if (starting(p)) {
3666         const char *s = m->v.str;
3667         int control = 0;
3668 
3669         if (!null_node(r)) {
3670             control = (int) r->v.xval;
3671         }
3672         ret = aux_scalar_node(p);
3673         if (ret != NULL) {
3674             ret->v.xval = gretl_bundle_write_to_file(l->v.b, s, control);
3675         }
3676     } else {
3677         ret = aux_scalar_node(p);
3678     }
3679 
3680     return ret;
3681 }
3682 
check_cswitch_param(gretl_matrix * m,int * k)3683 static int check_cswitch_param (gretl_matrix *m, int *k)
3684 {
3685     int err = 0;
3686 
3687     if (*k < 0 || *k > 4) {
3688         /* out of bounds */
3689         err = E_INVARG;
3690     } else if (*k == 1) {
3691         /* real to complex, column-wise */
3692         if (m->cols % 2) {
3693             err = E_NONCONF;
3694         }
3695     } else if (*k == 3) {
3696         /* real to complex, row-wise */
3697         if (m->rows % 2) {
3698             err = E_NONCONF;
3699         }
3700     }
3701 
3702     return err;
3703 }
3704 
3705 /* matrix on left, scalar(s) on right: returns a matrix */
3706 
matrix_scalar_func(NODE * l,NODE * r,int f,parser * p)3707 static NODE *matrix_scalar_func (NODE *l, NODE *r,
3708                                  int f, parser *p)
3709 {
3710     NODE *ret = NULL;
3711 
3712     if (starting(p)) {
3713         gretl_matrix *m = l->v.m;
3714         int k;
3715 
3716         if (f == F_CSWITCH) {
3717             k = 1; /* default */
3718             if (!null_node(r)) {
3719                 k = node_get_int(r, p);
3720             }
3721             if (!p->err) {
3722                 p->err = check_cswitch_param(m, &k);
3723             }
3724         } else {
3725             k = node_get_int(r, p);
3726         }
3727         if (!p->err && gretl_is_null_matrix(m)) {
3728             p->err = E_INVARG;
3729         }
3730         if (!p->err && f == F_MSORTBY && m->is_complex) {
3731             p->err = E_CMPLX;
3732         }
3733         if (!p->err) {
3734             ret = aux_matrix_node(p);
3735         }
3736         if (p->err) {
3737             return NULL;
3738         }
3739 
3740         if (f == F_MSORTBY) {
3741             ret->v.m = gretl_matrix_sort_by_column(m, k-1, &p->err);
3742         } else if (f == F_CSWITCH) {
3743             if (k > 2) {
3744                 /* the old _setcmplx() */
3745                 k = (k == 3)? 1 : 0;
3746                 ret->v.m = gretl_matrix_copy(m);
3747                 if (ret->v.m == NULL) {
3748                     p->err = E_ALLOC;
3749                 } else {
3750                     p->err = gretl_matrix_set_complex_full(ret->v.m, k);
3751                 }
3752             } else {
3753                 k = (k == 1)? 1 : 0;
3754                 ret->v.m = gretl_cmatrix_switch(m, k, &p->err);
3755             }
3756         }
3757     } else {
3758         ret = aux_any_node(p);
3759     }
3760 
3761     return ret;
3762 }
3763 
matrix_vector_func(NODE * l,NODE * m,NODE * r,int f,parser * p)3764 static NODE *matrix_vector_func (NODE *l, NODE *m, NODE *r,
3765                                  int f, parser *p)
3766 {
3767     NODE *ret = NULL;
3768 
3769     /* at present only F_MSPLITBY comes here */
3770 
3771     if (starting(p)) {
3772         gretl_matrix *a = node_get_matrix(l, p, 0, 1);
3773         gretl_matrix *v = node_get_matrix(m, p, 1, 2);
3774         int colwise = 0;
3775 
3776 	if (!p->err) {
3777 	    colwise = node_get_bool(r, p, 0);
3778 	}
3779         if (!p->err) {
3780 	    ret = aux_array_node(p);
3781 	}
3782         if (ret != NULL) {
3783             ret->v.a = gretl_matrix_split_by(a, v, colwise, &p->err);
3784         }
3785     } else {
3786         ret = aux_array_node(p);
3787     }
3788 
3789     return ret;
3790 }
3791 
3792 /* both operands are known to be matrices or scalars */
3793 
matrix_matrix_calc(NODE * l,NODE * r,int op,parser * p)3794 static NODE *matrix_matrix_calc (NODE *l, NODE *r, int op, parser *p)
3795 {
3796     gretl_matrix *ml = NULL, *mr = NULL;
3797     NODE *ret;
3798 
3799 #if 1
3800     if ((op == B_MUL || op == B_TRMUL || op == B_ADD || op == B_SUB) &&
3801         l->t == MAT && r->t == MAT) {
3802         ml = l->v.m;
3803         mr = r->v.m;
3804         if (ml->is_complex || mr->is_complex) {
3805             ret = aux_matrix_node(p);
3806             if (!p->err) {
3807                 p->err = real_matrix_calc(ml, mr, op, &ret->v.m);
3808             }
3809             return ret;
3810         }
3811     }
3812 #endif
3813 
3814     if (op == B_DOTPOW || op == B_POW) {
3815         if (op == B_POW) {
3816             if (scalar_node(l) && scalar_node(r)) {
3817                 op = B_DOTPOW;
3818             } else if (!scalar_node(r)) {
3819                 p->err = E_TYPES;
3820                 return NULL;
3821             }
3822         }
3823         ret = aux_matrix_node(p);
3824     } else {
3825         /* experiment: try reusing aux matrix */
3826         p->flags |= P_MSAVE;
3827         ret = get_aux_node(p, MAT, 0, TMP_NODE);
3828         p->flags ^= P_MSAVE;
3829     }
3830 
3831 #if EDEBUG
3832     fprintf(stderr, "matrix_matrix_calc: l=%p, r=%p, ret=%p\n",
3833             (void *) l, (void *) r, (void *) ret);
3834 #endif
3835 
3836     if (ml == NULL) {
3837         ml = node_get_matrix(l, p, 0, 1);
3838         if (op != B_POW) {
3839             mr = node_get_matrix(r, p, 1, 2);
3840         }
3841     }
3842 
3843     if (ret != NULL && starting(p)) {
3844         if (op == B_DOTPOW) {
3845             if (ml->is_complex) {
3846                 ret->v.m = gretl_cmatrix_dot_op(ml, mr, '^', &p->err);
3847             } else {
3848                 ret->v.m = gretl_matrix_dot_op(ml, mr, '^', &p->err);
3849             }
3850         } else if (op == B_POW) {
3851             int s = node_get_int(r, p);
3852 
3853             if (!p->err) {
3854                 ret->v.m = gretl_matrix_pow(ml, s, &p->err);
3855             }
3856         } else {
3857             p->err = real_matrix_calc(ml, mr, op, &ret->v.m);
3858         }
3859     }
3860 
3861     return ret;
3862 }
3863 
matrix_and_or(NODE * l,NODE * r,int op,parser * p)3864 static NODE *matrix_and_or (NODE *l, NODE *r, int op, parser *p)
3865 {
3866     NODE *ret = aux_matrix_node(p);
3867 
3868     if (ret != NULL && starting(p)) {
3869         const gretl_matrix *a = l->v.m;
3870         const gretl_matrix *b = r->v.m;
3871         int i, n = a->rows * a->cols;
3872 
3873         if (gretl_is_null_matrix(a) || gretl_is_null_matrix(b)) {
3874             p->err = E_NONCONF;
3875         } else if (a->rows != b->rows || a->cols != b->cols) {
3876             p->err = E_NONCONF;
3877         } else {
3878             ret->v.m = gretl_unit_matrix_new(a->rows, a->cols);
3879             if (ret->v.m == NULL) {
3880                 p->err = E_ALLOC;
3881                 return NULL;
3882             }
3883             for (i=0; i<n; i++) {
3884                 if (op == B_AND) {
3885                     if (a->val[i] == 0.0 || b->val[i] == 0.0) {
3886                         ret->v.m->val[i] = 0.0;
3887                     }
3888                 } else if (op == B_OR) {
3889                     if (a->val[i] == 0.0 && b->val[i] == 0.0) {
3890                         ret->v.m->val[i] = 0.0;
3891                     }
3892                 }
3893             }
3894         }
3895     }
3896 
3897     return ret;
3898 }
3899 
3900 /* both operands are matrices */
3901 
matrix_bool(NODE * l,NODE * r,int op,parser * p)3902 static NODE *matrix_bool (NODE *l, NODE *r, int op, parser *p)
3903 {
3904     NODE *ret;
3905 
3906     if (op == B_OR || op == B_AND) {
3907         return matrix_and_or(l, r, op, p);
3908     }
3909 
3910     ret = aux_scalar_node(p);
3911 
3912     if (ret != NULL && starting(p)) {
3913         const gretl_matrix *a = l->v.m;
3914         const gretl_matrix *b = r->v.m;
3915         int i, n = a->rows * a->cols;
3916 
3917         if (gretl_is_null_matrix(a) || gretl_is_null_matrix(b)) {
3918             ret->v.xval = NADBL;
3919         } else if (a->rows != b->rows || a->cols != b->cols) {
3920             ret->v.xval = NADBL;
3921         } else {
3922             ret->v.xval = op == B_NEQ ? 0 : 1;
3923             for (i=0; i<n; i++) {
3924                 if (op == B_EQ && a->val[i] != b->val[i]) {
3925                     ret->v.xval = 0;
3926                     break;
3927                 } else if (op == B_LT && a->val[i] >= b->val[i]) {
3928                     ret->v.xval = 0;
3929                     break;
3930                 } else if (op == B_GT && a->val[i] <= b->val[i]) {
3931                     ret->v.xval = 0;
3932                     break;
3933                 } else if (op == B_LTE && a->val[i] > b->val[i]) {
3934                     ret->v.xval = 0;
3935                     break;
3936                 } else if (op == B_GTE && a->val[i] < b->val[i]) {
3937                     ret->v.xval = 0;
3938                     break;
3939                 } else if (op == B_NEQ && a->val[i] != b->val[i]) {
3940                     ret->v.xval = 1;
3941                     break;
3942                 }
3943             }
3944         }
3945     }
3946 
3947     return ret;
3948 }
3949 
matrix_error(parser * p)3950 static void matrix_error (parser *p)
3951 {
3952     if (p->err == 0) {
3953         p->err = 1;
3954     }
3955 
3956     if (gretl_errmsg_is_set()) {
3957         errmsg(p->err, p->prn);
3958     }
3959 }
3960 
3961 /* functions taking a matrix argument and returning a
3962    scalar result */
3963 
matrix_to_scalar_func(NODE * n,int f,parser * p)3964 static NODE *matrix_to_scalar_func (NODE *n, int f, parser *p)
3965 {
3966     NODE *ret = aux_scalar_node(p);
3967 
3968     if (ret != NULL && starting(p)) {
3969         gretl_matrix *m = node_get_matrix(n, p, 0, 0);
3970 
3971         if (m->is_complex && f != F_ROWS && f != F_COLS && f != F_RANK) {
3972             /* gatekeeper for complex */
3973             p->err = function_real_only(f);
3974             return ret;
3975         }
3976 
3977         switch (f) {
3978         case F_ROWS:
3979             ret->v.xval = m->rows;
3980             break;
3981         case F_COLS:
3982             ret->v.xval = m->cols;
3983             break;
3984         case F_NORM1:
3985             ret->v.xval = gretl_matrix_one_norm(m);
3986             break;
3987         case F_INFNORM:
3988             ret->v.xval = gretl_matrix_infinity_norm(m);
3989             break;
3990         case F_RCOND:
3991             ret->v.xval = gretl_matrix_rcond(m, &p->err);
3992             break;
3993         case F_CNUMBER:
3994             ret->v.xval = gretl_matrix_cond_index(m, &p->err);
3995             break;
3996         case F_RANK:
3997             if (m->is_complex) {
3998                 ret->v.xval = gretl_cmatrix_rank(m, &p->err);
3999             } else {
4000                 ret->v.xval = gretl_matrix_rank(m, &p->err);
4001             }
4002             break;
4003         default:
4004             p->err = E_PARSE;
4005             break;
4006         }
4007 
4008         if (p->err) {
4009             matrix_error(p);
4010         }
4011     }
4012 
4013     return ret;
4014 }
4015 
4016 /* Compute a value which will be a scalar for a real matrix
4017    but a complex scalar (2-vector) for a complex matrix:
4018    handles determinant and trace.
4019 */
4020 
matrix_to_alt_node(NODE * n,int f,parser * p)4021 static NODE *matrix_to_alt_node (NODE *n, int f, parser *p)
4022 {
4023     gretl_matrix *m = node_get_matrix(n, p, 0, 0);
4024     NODE *ret = NULL;
4025 
4026     if (!p->err) {
4027         ret = m->is_complex ? aux_matrix_node(p) : aux_scalar_node(p);
4028     }
4029 
4030     if (!p->err) {
4031         if (m->is_complex) {
4032             if (f == F_TRACE) {
4033                 ret->v.m = gretl_cmatrix_trace(m, &p->err);
4034             } else {
4035                 ret->v.m = gretl_cmatrix_determinant(m, f==F_LDET, &p->err);
4036             }
4037         } else if (f == F_TRACE) {
4038             ret->v.xval = gretl_matrix_trace(m);
4039         } else {
4040             int tmpmat = (n->t == MAT && is_tmp_node(n));
4041 
4042             ret->v.xval = user_matrix_get_determinant(m, tmpmat, f, &p->err);
4043         }
4044     }
4045 
4046     return ret;
4047 }
4048 
matrix_add_names(NODE * l,NODE * r,int f,parser * p)4049 static NODE *matrix_add_names (NODE *l, NODE *r, int f, parser *p)
4050 {
4051     NODE *ret = aux_scalar_node(p);
4052 
4053     if (ret != NULL && starting(p)) {
4054         gretl_matrix *m = l->v.m;
4055         int byrow = (f == F_RNAMESET);
4056 
4057         if (m->is_complex) {
4058             /* we could set column names for a complex matrix
4059                but they wouldn't show up on printing
4060             */
4061             p->err = E_CMPLX;
4062             return ret;
4063         }
4064 
4065         if (r->t == STR) {
4066             ret->v.xval = umatrix_set_names_from_string(m, r->v.str, byrow);
4067         } else if (r->t == ARRAY) {
4068             if (gretl_array_get_type(r->v.a) != GRETL_TYPE_STRINGS) {
4069                 p->err = E_TYPES;
4070             } else {
4071                 ret->v.xval = umatrix_set_names_from_array(m, r->v.a, byrow);
4072             }
4073         } else {
4074             /* some sort of list-bearing node */
4075             int *list = node_get_list(r, p);
4076 
4077             if (p->err) {
4078                 ret->v.xval = 1;
4079             } else {
4080                 ret->v.xval = umatrix_set_names_from_list(m, list, p->dset,
4081                                                           byrow);
4082             }
4083             free(list);
4084         }
4085     }
4086 
4087     return ret;
4088 }
4089 
matrix_get_col_or_row_name(int f,NODE * l,NODE * r,parser * p)4090 static NODE *matrix_get_col_or_row_name (int f, NODE *l, NODE *r,
4091                                          parser *p)
4092 {
4093     int get_all = null_node(r);
4094     NODE *ret = get_all ? aux_array_node(p) : aux_string_node(p);
4095 
4096     if (ret != NULL && starting(p)) {
4097         if (get_all) {
4098             const char **S;
4099             int n = 0;
4100 
4101             if (f == F_CNAMEGET) {
4102                 S = gretl_matrix_get_colnames(l->v.m);
4103                 if (S != NULL) n = l->v.m->cols;
4104             } else {
4105                 S = gretl_matrix_get_rownames(l->v.m);
4106                 if (S != NULL) n = l->v.m->rows;
4107             }
4108             ret->v.a = gretl_array_from_strings((char **) S, n,
4109                                                 1, &p->err);
4110         } else {
4111             int i = node_get_int(r, p);
4112 
4113             if (f == F_CNAMEGET) {
4114                 ret->v.str = user_matrix_get_column_name(l->v.m, i, &p->err);
4115             } else {
4116                 ret->v.str = user_matrix_get_row_name(l->v.m, i, &p->err);
4117             }
4118         }
4119     }
4120 
4121     return ret;
4122 }
4123 
matrix_imhof(NODE * l,NODE * r,parser * p)4124 static NODE *matrix_imhof (NODE *l, NODE *r, parser *p)
4125 {
4126     NODE *ret = aux_scalar_node(p);
4127 
4128     if (ret != NULL && starting(p)) {
4129         const gretl_matrix *m = l->v.m;
4130         double arg = node_get_scalar(r, p);
4131 
4132         ret->v.xval = imhof(m, arg, &p->err);
4133     }
4134 
4135     return ret;
4136 }
4137 
bkw_node(NODE * l,NODE * m,NODE * r,parser * p)4138 static NODE *bkw_node (NODE *l, NODE *m, NODE *r, parser *p)
4139 {
4140     NODE *ret = aux_matrix_node(p);
4141 
4142     if (ret != NULL && starting(p)) {
4143         const gretl_matrix *V = l->v.m;
4144         gretl_array *pnames = NULL;
4145         PRN *vprn = NULL;
4146         int ns = 0;
4147 
4148         if (!null_node(m)) {
4149             if (m->t == STR) {
4150                 /* for compat with Lee's bkw() we expect comma-
4151                    separated parameter names here
4152                 */
4153                 char **S = gretl_string_split(m->v.str, &ns, ",");
4154 
4155                 if (S == NULL) {
4156                     p->err = E_DATA;
4157                 } else {
4158                     pnames = gretl_array_from_strings(S, ns, 0, &p->err);
4159                 }
4160             } else if (m->t == ARRAY) {
4161                 if (gretl_array_get_type(m->v.a) != GRETL_TYPE_STRINGS) {
4162                     p->err = E_TYPES;
4163                 } else {
4164                     pnames = gretl_array_copy(m->v.a, &p->err);
4165                 }
4166             } else {
4167                 p->err = E_TYPES;
4168             }
4169         }
4170 
4171         if (node_get_bool(r, p, 0)) {
4172             /* optional verbose flag */
4173             vprn = p->prn;
4174         }
4175 
4176         if (!p->err) {
4177             gretl_matrix *(*bkwfunc) (const gretl_matrix *, gretl_array *,
4178                                       PRN *, int *);
4179 
4180             bkwfunc = get_plugin_function("bkw_matrix");
4181             if (bkwfunc == NULL) {
4182                 p->err = E_FOPEN;
4183             } else {
4184                 ret->v.m = (*bkwfunc)(V, pnames, vprn, &p->err);
4185             }
4186         }
4187 
4188         gretl_array_destroy(pnames);
4189     }
4190 
4191     return ret;
4192 }
4193 
4194 /* Here we handle the case where the relevant libgretl
4195    function overwrites its matrix argument. If @m is
4196    just an on-the-fly matrix it can be passed as arg,
4197    but if it's a named user-matrix we'll have to make
4198    a copy to pass.
4199 */
4200 
apply_ovwrite_func(gretl_matrix * m,int f,int parm,int tmpmat,int * err)4201 static gretl_matrix *apply_ovwrite_func (gretl_matrix *m,
4202                                          int f, int parm,
4203                                          int tmpmat,
4204                                          int *err)
4205 {
4206     gretl_matrix *R = NULL;
4207 
4208     if (f == F_CHOL && !gretl_is_null_matrix(m) &&
4209         !gretl_matrix_is_symmetric(m)) {
4210         gretl_errmsg_set(_("Matrix is not symmetric"));
4211         *err = E_DATA;
4212         return NULL;
4213     }
4214 
4215     if (tmpmat) {
4216         /* it's OK to overwrite @m */
4217         R = m;
4218     } else {
4219         /* @m should not be over-written! */
4220         R = gretl_matrix_copy(m);
4221         if (R == NULL) {
4222             *err = E_ALLOC;
4223         }
4224     }
4225 
4226     if (R != NULL) {
4227         if (f == F_CDEMEAN) {
4228             if (parm) {
4229                 *err = gretl_matrix_standardize(R, 1);
4230             } else {
4231                 *err = gretl_matrix_center(R);
4232             }
4233         } else if (f == F_STDIZE) {
4234             if (parm < 0) {
4235                 *err = gretl_matrix_center(R);
4236             } else {
4237                 *err = gretl_matrix_standardize(R, parm);
4238             }
4239         } else if (f == F_CHOL) {
4240             *err = gretl_matrix_cholesky_decomp(R);
4241         } else if (f == F_PSDROOT) {
4242             *err = gretl_matrix_psd_root(R, parm);
4243         } else if (f == F_INVPD) {
4244             *err = gretl_invpd(R);
4245         } else if (f == F_GINV) {
4246             *err = gretl_matrix_moore_penrose(R);
4247         } else if (f == F_INV) {
4248             *err = gretl_invert_matrix(R);
4249         } else if (f == F_UPPER) {
4250             *err = gretl_matrix_zero_lower(R);
4251         } else if (f == F_LOWER) {
4252             *err = gretl_matrix_zero_upper(R);
4253         } else {
4254             *err = E_DATA;
4255         }
4256         if (*err && R != m) {
4257             gretl_matrix_free(R);
4258             R = NULL;
4259         }
4260     }
4261 
4262     return R;
4263 }
4264 
matrix_minmax_indices(int f,int * mm,int * rc,int * idx)4265 static void matrix_minmax_indices (int f, int *mm, int *rc, int *idx)
4266 {
4267     *mm = (f == F_MAXR || f == F_MAXC || f == F_IMAXR || f == F_IMAXC);
4268     *rc = (f == F_MINC || f == F_MAXC || f == F_IMINC || f == F_IMAXC);
4269     *idx = (f == F_IMINR || f == F_IMINC || f == F_IMAXR || f == F_IMAXC);
4270 }
4271 
4272 #define mmf_does_complex(f) (f==F_INV || f==F_UPPER || f==F_LOWER || \
4273                              f==F_DIAG || f==F_TRANSP || f==F_CTRANS || \
4274                              f==F_VEC || f==F_VECH || f==F_UNVECH || \
4275                              f==F_MREV || f== F_FFT2 || f==F_FFTI || \
4276                              f==F_CUM || f==F_DIFF || f==F_SUMC || \
4277                              f==F_SUMR || f==F_PRODC || f==F_PRODR || \
4278                              f==F_MEANC || f==F_MEANR || f==F_GINV || \
4279                              f==F_MLOG || f==F_MEXP || f==F_CHOL)
4280 
matrix_to_matrix_func(NODE * n,NODE * r,int f,parser * p)4281 static NODE *matrix_to_matrix_func (NODE *n, NODE *r, int f, parser *p)
4282 {
4283     NODE *ret = aux_matrix_node(p);
4284 
4285     if (ret != NULL && starting(p)) {
4286         gretl_matrix *m = NULL;
4287         int tmpmat = 0;
4288         int parm = 0;
4289         int gotopt = 0;
4290         int a = 0, b = 0, c = 0;
4291 
4292         /* note: @parm is an integer parameter, required
4293            for some functions, optional for others
4294         */
4295 
4296         m = node_get_matrix(n, p, 0, 0);
4297         tmpmat = n->t == MAT && is_tmp_node(n);
4298 
4299         if (!p->err && m != NULL && m->is_complex) {
4300             /* gatekeeper for complex */
4301             if (!mmf_does_complex(f)) {
4302                 p->err = function_real_only(f);
4303             }
4304         }
4305 
4306         if (p->err) {
4307             goto finalize;
4308         }
4309 
4310         if (f == F_MREV || f == F_SDC || f == F_MCOV ||
4311             f == F_CDEMEAN || f == F_STDIZE || f == F_PSDROOT) {
4312             /* if present, the @r node should hold a scalar */
4313             if (!null_or_scalar(r)) {
4314                 node_type_error(f, 2, NUM, r, p);
4315             } else if (!null_node(r)) {
4316                 parm = node_get_int(r, p);
4317                 gotopt = 1;
4318             }
4319         } else if (f == F_RANKING) {
4320             if (gretl_vector_get_length(m) == 0) {
4321                 /* m must be a vector */
4322                 p->err = E_TYPES;
4323             }
4324         }
4325 
4326         if (!p->err && gretl_is_null_matrix(m) && !emptymat_ok(f)) {
4327             p->err = E_DATA;
4328         }
4329 
4330         if (p->err) {
4331             goto finalize;
4332         }
4333 
4334         gretl_error_clear();
4335 
4336         if (gretl_is_null_matrix(m)) {
4337             ret->v.m = gretl_null_matrix_new();
4338             goto finalize;
4339         }
4340 
4341         switch (f) {
4342         case F_SUMC:
4343             ret->v.m = gretl_matrix_vector_stat(m, V_SUM, 0, &p->err);
4344             break;
4345         case F_SUMR:
4346             ret->v.m = gretl_matrix_vector_stat(m, V_SUM, 1, &p->err);
4347             break;
4348         case F_PRODC:
4349             ret->v.m = gretl_matrix_vector_stat(m, V_PROD, 0, &p->err);
4350             break;
4351         case F_PRODR:
4352             ret->v.m = gretl_matrix_vector_stat(m, V_PROD, 1, &p->err);
4353             break;
4354         case F_MEANC:
4355             ret->v.m = gretl_matrix_vector_stat(m, V_MEAN, 0, &p->err);
4356             break;
4357         case F_MEANR:
4358             ret->v.m = gretl_matrix_vector_stat(m, V_MEAN, 1, &p->err);
4359             break;
4360         case F_SD:
4361             ret->v.m = gretl_matrix_column_sd(m, &p->err);
4362             break;
4363         case F_SDC:
4364             if (gotopt) {
4365                 ret->v.m = gretl_matrix_column_sd2(m, parm, &p->err);
4366             } else {
4367                 ret->v.m = gretl_matrix_column_sd(m, &p->err);
4368             }
4369             break;
4370         case F_MCOV:
4371             if (!gotopt) {
4372                 parm = 1;
4373             }
4374             ret->v.m = gretl_covariance_matrix(m, f == F_MCORR,
4375                                                parm, &p->err);
4376             break;
4377         case F_MCORR:
4378             ret->v.m = gretl_covariance_matrix(m, f == F_MCORR,
4379                                                1, &p->err);
4380             break;
4381         case F_CUM:
4382             ret->v.m = gretl_matrix_cumcol(m, &p->err);
4383             break;
4384         case F_DIFF:
4385             ret->v.m = gretl_matrix_diffcol(m, 0, &p->err);
4386             break;
4387         case F_DATAOK:
4388             ret->v.m = gretl_matrix_isfinite(m, &p->err);
4389             break;
4390         case F_INV:
4391             if (m->is_complex) {
4392                 ret->v.m = gretl_cmatrix_inverse(m, &p->err);
4393             } else {
4394                 ret->v.m = apply_ovwrite_func(m, f, parm, tmpmat, &p->err);
4395             }
4396             break;
4397         case F_GINV:
4398             if (m->is_complex) {
4399                 ret->v.m = gretl_cmatrix_ginv(m, &p->err);
4400             } else {
4401                 ret->v.m = apply_ovwrite_func(m, f, parm, tmpmat, &p->err);
4402             }
4403             break;
4404         case F_CHOL:
4405             if (m->is_complex) {
4406                 ret->v.m = gretl_cmatrix_cholesky(m, &p->err);
4407             } else {
4408                 ret->v.m = apply_ovwrite_func(m, f, parm, tmpmat, &p->err);
4409             }
4410             break;
4411         case F_CDEMEAN:
4412         case F_STDIZE:
4413         case F_PSDROOT:
4414         case F_INVPD:
4415         case F_UPPER:
4416         case F_LOWER:
4417             ret->v.m = apply_ovwrite_func(m, f, parm, tmpmat, &p->err);
4418             break;
4419         case F_DIAG:
4420             ret->v.m = gretl_matrix_get_diagonal(m, &p->err);
4421             break;
4422         case F_TRANSP:
4423             if (m->is_complex) {
4424                 ret->v.m = gretl_ctrans(m, 0, &p->err);
4425             } else {
4426                 ret->v.m = gretl_matrix_copy_transpose(m);
4427             }
4428             break;
4429         case F_VEC:
4430             ret->v.m = user_matrix_vec(m, &p->err);
4431             break;
4432         case F_VECH:
4433             ret->v.m = user_matrix_vech(m, &p->err);
4434             break;
4435         case F_UNVECH:
4436             ret->v.m = user_matrix_unvech(m, &p->err);
4437             break;
4438         case F_MREV:
4439             if (parm != 0) {
4440                 ret->v.m = gretl_matrix_reverse_cols(m, &p->err);
4441             } else {
4442                 ret->v.m = gretl_matrix_reverse_rows(m, &p->err);
4443             }
4444             break;
4445         case F_NULLSPC:
4446             ret->v.m = gretl_matrix_right_nullspace(m, &p->err);
4447             break;
4448         case F_MEXP:
4449             if (m->is_complex) {
4450                 ret->v.m = gretl_cmatrix_exp(m, &p->err);
4451             } else {
4452                 ret->v.m = gretl_matrix_exp(m, &p->err);
4453             }
4454             break;
4455         case F_MLOG:
4456             ret->v.m = gretl_matrix_log(m, &p->err);
4457             break;
4458         case F_FFT:
4459             ret->v.m = gretl_matrix_fft(m, 0, &p->err);
4460             break;
4461         case F_FFT2:
4462             if (m->is_complex) {
4463                 ret->v.m = gretl_cmatrix_fft(m, 0, &p->err);
4464             } else {
4465                 ret->v.m = gretl_matrix_fft(m, 1, &p->err);
4466             }
4467             break;
4468         case F_FFTI:
4469             ret->v.m = gretl_matrix_ffti(m, &p->err);
4470             break;
4471         case F_POLROOTS:
4472             ret->v.m = gretl_matrix_polroots(m, 0, &p->err);
4473             break;
4474         case F_RANKING:
4475             ret->v.m = rank_vector(m, F_SORT, &p->err);
4476             break;
4477         case F_MINC:
4478         case F_MAXC:
4479         case F_MINR:
4480         case F_MAXR:
4481         case F_IMINC:
4482         case F_IMAXC:
4483         case F_IMINR:
4484         case F_IMAXR:
4485             matrix_minmax_indices(f, &a, &b, &c);
4486             ret->v.m = gretl_matrix_minmax(m, a, b, c, &p->err);
4487             break;
4488         case F_CTRANS:
4489             ret->v.m = gretl_ctrans(m, 1, &p->err);
4490             break;
4491         default:
4492             break;
4493         }
4494 
4495         if (ret->v.m == m && n->t == MAT) {
4496             /* input matrix was recycled: avoid double-freeing */
4497             n->v.m = NULL;
4498         }
4499 
4500     finalize:
4501 
4502         if (ret->v.m == NULL) {
4503             matrix_error(p);
4504         }
4505     }
4506 
4507     return ret;
4508 }
4509 
list_reverse_node(NODE * n,parser * p)4510 static NODE *list_reverse_node (NODE *n, parser *p)
4511 {
4512     NODE *ret = aux_list_node(p);
4513 
4514     if (ret != NULL && starting(p)) {
4515         int i, nt = n->v.ivec[0];
4516         int *rev = gretl_list_new(nt);
4517 
4518         for (i=1; i<=nt; i++) {
4519             rev[i] = n->v.ivec[nt-i+1];
4520         }
4521         ret->v.ivec = rev;
4522     }
4523 
4524     return ret;
4525 }
4526 
4527 /* We come here if we got a ".csv" suffix for the argument
4528    to mread(). If we can open the file as-is, we check to
4529    make sure it's not a gretl-format matrix file with the
4530    wrong suffix.
4531 */
4532 
check_matrix_file(const char * fname,int * csv)4533 static int check_matrix_file (const char *fname, int *csv)
4534 {
4535     char line[1024];
4536     FILE *fp;
4537     int r, c, n;
4538 
4539     *csv = 1;
4540 
4541     fp = gretl_fopen(fname, "rb");
4542     if (fp == NULL) {
4543 	/* just assume it's really CSV */
4544         return 0;
4545     }
4546 
4547     while (fgets(line, sizeof line, fp)) {
4548         if (*line != '#') {
4549             /* heuristic: if the non-comment portion of the file
4550                starts with two tab-separated integers, it's
4551                actually a native gretl .mat file regardless of
4552                the filename suffix?
4553             */
4554             n = sscanf(line, "%d\t%d", &r, &c);
4555             if (n == 2 && count_fields(line, "\t") == 2) {
4556                 *csv = 0;
4557             }
4558             break;
4559         }
4560     }
4561 
4562 #if 0
4563     fprintf(stderr, "check_matrix_file : csv = %d\n", *csv);
4564 #endif
4565 
4566     fclose(fp);
4567 
4568     return 0;
4569 }
4570 
read_object_func(NODE * n,NODE * r,int f,parser * p)4571 static NODE *read_object_func (NODE *n, NODE *r, int f, parser *p)
4572 {
4573     NODE *ret;
4574 
4575     if (f == F_MREAD) {
4576         ret = aux_matrix_node(p);
4577     } else {
4578         ret = aux_bundle_node(p);
4579     }
4580 
4581     if (ret != NULL && starting(p)) {
4582         const char *fname = n->v.str;
4583         const char *realpath = fname;
4584         gchar *tmp = NULL;
4585         int import = node_get_bool(r, p, 0);
4586         int csv = 0;
4587 	int gdt = 0;
4588         int done = 0;
4589 
4590         gretl_error_clear();
4591 
4592         if (import) {
4593             tmp = gretl_make_dotpath(fname);
4594             realpath = tmp;
4595         }
4596 
4597         if (has_suffix(realpath, ".csv")) {
4598             p->err = check_matrix_file(realpath, &csv);
4599             if (p->err) {
4600                 return ret;
4601             }
4602         } else if (has_suffix(realpath, ".gdt") ||
4603 		   has_suffix(realpath, ".gdtb")) {
4604 	    gdt = 1;
4605 	}
4606 
4607         switch (f) {
4608         case F_MREAD:
4609 #ifdef HAVE_MPI
4610             if (has_suffix(fname, ".shm")) {
4611                 ret->v.m = shm_read_matrix(fname, 1, &p->err);
4612                 done = 1;
4613             }
4614 #endif
4615             if (!done && csv) {
4616                 ret->v.m = import_csv_as_matrix(realpath, &p->err);
4617 	    } else if (!done && gdt) {
4618 		set_dset_matrix_target(&ret->v.m);
4619 		p->err = gretl_read_gdt(realpath, NULL, OPT_NONE, NULL);
4620 		set_dset_matrix_target(NULL);
4621             } else if (!done) {
4622                 ret->v.m = gretl_matrix_read_from_file(realpath, 0, &p->err);
4623             }
4624             break;
4625         case F_BREAD:
4626             ret->v.b = gretl_bundle_read_from_file(realpath, 0, &p->err);
4627             break;
4628         default:
4629             break;
4630         }
4631 
4632         g_free(tmp);
4633     }
4634 
4635     return ret;
4636 }
4637 
4638 /* Build a node holding a complex matrix, given two scalars,
4639    two matrices, or matrix plus scalar.
4640 */
4641 
complex_matrix_node(NODE * l,NODE * r,parser * p)4642 static NODE *complex_matrix_node (NODE *l, NODE *r, parser *p)
4643 {
4644     NODE *ret = aux_matrix_node(p);
4645 
4646     if (ret != NULL) {
4647         gretl_matrix *Re = l->t == MAT ? l->v.m : NULL;
4648         gretl_matrix *Im = r->t == MAT ? r->v.m : NULL;
4649         double x = l->t == NUM ? l->v.xval : 0;
4650         double y = r->t == NUM ? r->v.xval : 0;
4651 
4652         if (l->t == NUM && null_or_scalar(r)) {
4653             ret->v.m = gretl_cmatrix_from_scalar(x + y*I, &p->err);
4654         } else {
4655             ret->v.m = gretl_cmatrix_build(Re, Im, x, y, &p->err);
4656         }
4657     }
4658 
4659     return ret;
4660 }
4661 
4662 static NODE *
matrix_to_matrix2_func(NODE * n,NODE * r,int f,parser * p)4663 matrix_to_matrix2_func (NODE *n, NODE *r, int f, parser *p)
4664 {
4665     NODE *ret = aux_matrix_node(p);
4666 
4667     if (ret != NULL && starting(p)) {
4668         gretl_matrix *m1 = node_get_matrix(n, p, 0, 0);
4669         gretl_matrix *m2 = NULL;
4670 
4671         if (!p->err && gretl_is_null_matrix(m1)) {
4672             p->err = E_DATA;
4673         }
4674         if (!p->err && !null_node(r)) {
4675             m2 = ptr_node_get_matrix(r, p);
4676         }
4677 
4678         if (!p->err) {
4679             if (f == F_QR) {
4680                 if (m1->is_complex) {
4681                     ret->v.m = gretl_cmatrix_QR_decomp(m1, m2, &p->err);
4682                 } else {
4683                     ret->v.m = user_matrix_QR_decomp(m1, m2, &p->err);
4684                 }
4685             } else if (f == F_EIGSYM) {
4686                 ret->v.m = user_matrix_eigensym(m1, m2, &p->err);
4687             } else if (f == F_HDPROD) {
4688 		if (m1->is_complex) {
4689 		    ret->v.m = gretl_cmatrix_hdprod(m1, NULL, &p->err);
4690 		} else {
4691 		    ret->v.m = gretl_matrix_hdproduct_new(m1, NULL, &p->err);
4692 		}
4693 	    }
4694         }
4695 
4696         if (ret->v.m == NULL) {
4697             matrix_error(p);
4698         }
4699     }
4700 
4701     return ret;
4702 }
4703 
ok_matrix_dim(int r,int c,int f)4704 static int ok_matrix_dim (int r, int c, int f)
4705 {
4706     if (f == F_IMAT || f == F_ZEROS || f == F_ONES ||
4707         f == F_MUNIF || f == F_MNORM) {
4708         /* zero is OK for matrix creation functions, which then
4709            return an empty matrix
4710         */
4711         return (r >= 0 && c >= 0);
4712     } else {
4713         double xm = (double) r * (double) c;
4714 
4715         return (r > 0 && c > 0 && xm < INT_MAX);
4716     }
4717 }
4718 
matrix_fill_func(NODE * l,NODE * r,int f,parser * p)4719 static NODE *matrix_fill_func (NODE *l, NODE *r, int f, parser *p)
4720 {
4721     int n = 0, cols = 0, rows = node_get_int(l, p);
4722     NODE *ret = NULL;
4723 
4724     if (!p->err) {
4725         if (f == F_RANDPERM) {
4726             n = rows; /* switched interpretation of first arg */
4727             rows = 1; /* row vector, per Matlab */
4728             if (null_node(r)) {
4729                 cols = n;
4730             } else {
4731                 cols = node_get_int(r, p);
4732             }
4733         } else if (f == F_IMAT && null_node(r)) {
4734             /* default to square */
4735             cols = rows;
4736         } else if (null_node(r)) {
4737             /* default to a column vector */
4738             cols = 1;
4739         } else {
4740             cols = node_get_int(r, p);
4741         }
4742     }
4743 
4744     if (!p->err && !ok_matrix_dim(rows, cols, f)) {
4745         p->err = E_INVARG;
4746         matrix_error(p);
4747     }
4748 
4749     if (!p->err) {
4750         ret = aux_sized_matrix_node(p, rows, cols, 0);
4751     }
4752 
4753     if (p->err || rows * cols == 0) {
4754         return ret;
4755     }
4756 
4757     switch (f) {
4758     case F_IMAT:
4759         if (rows != cols) {
4760             gretl_matrix_zero(ret->v.m);
4761         }
4762         gretl_matrix_inscribe_I(ret->v.m, 0, 0, MIN(rows, cols));
4763         break;
4764     case F_ZEROS:
4765         gretl_matrix_fill(ret->v.m, 0.0);
4766         break;
4767     case F_ONES:
4768         gretl_matrix_fill(ret->v.m, 1.0);
4769         break;
4770     case F_MUNIF:
4771         gretl_matrix_random_fill(ret->v.m, D_UNIFORM);
4772         break;
4773     case F_MNORM:
4774         gretl_matrix_random_fill(ret->v.m, D_NORMAL);
4775         break;
4776     case F_RANDPERM:
4777         p->err = fill_permutation_vector(ret->v.m, n);
4778         break;
4779     default:
4780         break;
4781     }
4782 
4783     return ret;
4784 }
4785 
4786 /* Putative row or column selection matrix: must be a vector;
4787    cannot contain zero; cannot have both positive and negative
4788    entries; and entries must be integer-valued.
4789 */
4790 
set_sel_vector(matrix_subspec * spec,int r,gretl_matrix * m)4791 static int set_sel_vector (matrix_subspec *spec, int r,
4792                            gretl_matrix *m)
4793 {
4794     int i, n = gretl_vector_get_length(m);
4795     int err = 0;
4796 
4797     if (n > 0) {
4798         double x;
4799         int nneg = 0;
4800 
4801         for (i=0; i<n && !err; i++) {
4802             x = m->val[i];
4803             if (x == 0 || na(x) || x != floor(x)) {
4804                 err = E_DATA;
4805             }
4806             nneg += x < 0;
4807         }
4808         if (!err && nneg > 0 && nneg < n) {
4809             err = E_DATA;
4810         }
4811     } else {
4812         err = E_TYPES;
4813     }
4814 
4815     if (err) {
4816         gretl_errmsg_set("Invalid selection vector");
4817     } else if (r) {
4818         spec->rsel.m = m;
4819         spec->rtype = SEL_MATRIX;
4820     } else {
4821         spec->lsel.m = m;
4822         spec->ltype = SEL_MATRIX;
4823     }
4824 
4825     return err;
4826 }
4827 
4828 /* Compose a sub-matrix specification, from scalars and/or
4829    index matrices.
4830 */
4831 
build_mspec(NODE * targ,NODE * l,NODE * r,parser * p)4832 static void build_mspec (NODE *targ, NODE *l, NODE *r, parser *p)
4833 {
4834     matrix_subspec *spec = targ->v.mspec;
4835     int lscalar = 0;
4836     int rscalar = 0;
4837     int i = 0, j = 0;
4838 
4839     if (spec == NULL) {
4840         spec = matrix_subspec_new();
4841         if (spec == NULL) {
4842             p->err = E_ALLOC;
4843             return;
4844         }
4845     }
4846 
4847 #if EDEBUG > 1
4848     fprintf(stderr, "build_mspec: l->t=%d (%s)\n", l->t, getsymb(l->t));
4849     if (r == NULL) {
4850         fprintf(stderr, " r = NULL\n");
4851     } else {
4852         fprintf(stderr, " r->t=%d (%s)\n", r->t, getsymb(r->t));
4853     }
4854 #endif
4855 
4856     /* special case: bundle membership */
4857     if (l->t == STR) {
4858         if (r == NULL) {
4859             spec->ltype = SEL_STR;
4860             spec->rtype = SEL_NULL;
4861             spec->lsel.str = l->v.str;
4862         } else {
4863             p->err = E_TYPES;
4864         }
4865         goto finished;
4866     }
4867 
4868     lscalar = scalar_node(l);
4869     rscalar = (r != NULL && scalar_node(r));
4870 
4871     if (lscalar) {
4872 	i = node_get_int(l, p);
4873         if (!p->err && i == 0) {
4874             gretl_errmsg_sprintf(_("Index value %d is out of bounds"), 0);
4875             p->err = E_INVARG;
4876         }
4877         if (!p->err && r == NULL && i > 0) {
4878             /* identify and flag the single index case */
4879             spec->ltype = SEL_SINGLE;
4880             spec->rtype = SEL_NULL;
4881             mspec_set_row_index(spec, i);
4882             goto finished;
4883         }
4884     }
4885     if (!p->err && rscalar) {
4886 	j = node_get_int(r, p);
4887         if (!p->err && j == 0) {
4888             gretl_errmsg_sprintf(_("Index value %d is out of bounds"), 0);
4889             p->err = E_INVARG;
4890         }
4891     }
4892 
4893     if (l->t == DUM) {
4894         if (r != NULL) {
4895             p->err = E_INVARG;
4896         } else {
4897             spec->rtype = SEL_ALL;
4898             if (l->v.idnum == DUM_DIAG) {
4899                 spec->ltype = SEL_DIAG;
4900             } else if (l->v.idnum == DUM_UPPER) {
4901                 spec->ltype = SEL_UPPER;
4902             } else if (l->v.idnum == DUM_LOWER) {
4903                 spec->ltype = SEL_LOWER;
4904             } else if (l->v.idnum == DUM_REAL) {
4905                 spec->ltype = SEL_REAL;
4906             } else if (l->v.idnum == DUM_IMAG) {
4907                 spec->ltype = SEL_IMAG;
4908             } else {
4909                 p->err = E_TYPES;
4910             }
4911         }
4912         goto finished;
4913     } else if (i > 0 && j > 0) {
4914         spec->ltype = spec->rtype = SEL_ELEMENT;
4915         mspec_set_row_index(spec, i);
4916         mspec_set_col_index(spec, j);
4917         goto finished;
4918     } else if (lscalar) {
4919         spec->ltype = i > 0 ? SEL_RANGE : SEL_EXCL;
4920         mspec_set_row_index(spec, i);
4921     } else if (l->t == IVEC) {
4922         spec->ltype = SEL_RANGE;
4923         spec->lsel.range[0] = l->v.ivec[0];
4924         spec->lsel.range[1] = l->v.ivec[1];
4925     } else if (l->t == MAT) {
4926 	p->err = set_sel_vector(spec, 0, l->v.m);
4927     } else if (null_node(l)) {
4928         spec->ltype = SEL_ALL;
4929     } else {
4930         p->err = E_TYPES;
4931         goto finished;
4932     }
4933 
4934     if (r == NULL) {
4935         spec->rtype = SEL_NULL;
4936     } else if (rscalar) {
4937         spec->rtype = j > 0 ? SEL_RANGE : SEL_EXCL;
4938         mspec_set_col_index(spec, j);
4939     } else if (r->t == IVEC) {
4940         spec->rtype = SEL_RANGE;
4941         spec->rsel.range[0] = r->v.ivec[0];
4942         spec->rsel.range[1] = r->v.ivec[1];
4943     } else if (r->t == MAT) {
4944 	p->err = set_sel_vector(spec, 1, r->v.m);
4945     } else if (null_node(r)) {
4946         spec->rtype = SEL_ALL;
4947     } else {
4948         p->err = E_TYPES;
4949     }
4950 
4951  finished:
4952 
4953 #if EDEBUG > 1
4954     print_mspec(spec);
4955 #endif
4956 
4957     if (p->err && spec != NULL) {
4958         free(spec);
4959         spec = NULL;
4960     }
4961 
4962     targ->v.mspec = spec;
4963 }
4964 
4965 /* node holding evaluated result of matrix specification */
4966 
mspec_node(NODE * l,NODE * r,parser * p)4967 static NODE *mspec_node (NODE *l, NODE *r, parser *p)
4968 {
4969     NODE *ret = aux_mspec_node(p);
4970 
4971     if (ret != NULL && starting(p)) {
4972         build_mspec(ret, l, r, p);
4973     }
4974 
4975     return ret;
4976 }
4977 
submatrix_node(NODE * l,NODE * r,parser * p)4978 static NODE *submatrix_node (NODE *l, NODE *r, parser *p)
4979 {
4980     NODE *ret = NULL;
4981 
4982     if (starting(p)) {
4983         matrix_subspec *spec = r->v.mspec;
4984         gretl_matrix *m = node_get_matrix(l, p, 0, 0);
4985 
4986         p->err = check_matrix_subspec(spec, m);
4987 
4988         if (!p->err) {
4989             if (spec->ltype == SEL_CONTIG) {
4990                 ret = aux_matrix_node(p);
4991                 if (!p->err) {
4992                     ret->v.m = matrix_get_chunk(m, spec, &p->err);
4993                 }
4994             } else if (spec->ltype == SEL_ELEMENT) {
4995                 int i = mspec_get_element(spec);
4996 
4997                 if (m->is_complex) {
4998                     ret = aux_matrix_node(p);
4999                     if (!p->err) {
5000                         ret->v.m = cmatrix_get_element(m, i, &p->err);
5001                     }
5002  		} else {
5003 		    /* 2020-12-29: don't collapse to scalar here */
5004 		    ret = aux_matrix_node(p);
5005 		    ret->v.m = gretl_matrix_alloc(1,1);
5006 		    ret->v.m->val[0] = m->val[i];
5007                 }
5008             } else if (spec->ltype == SEL_STR) {
5009                 p->err = E_TYPES;
5010             } else {
5011                 ret = aux_matrix_node(p);
5012                 if (!p->err) {
5013                     ret->v.m = matrix_get_submatrix(m, spec, 1, &p->err);
5014                 }
5015             }
5016         }
5017     } else {
5018         ret = aux_any_node(p);
5019     }
5020 
5021     return ret;
5022 }
5023 
5024 /* Check a list that has been stored in a bundle or array to see
5025    if it can be interpreted as a list given the characteristics
5026    of the current dataset (or lack thereof).
5027 */
5028 
stored_list_check(const int * list,const DATASET * dset)5029 static int stored_list_check (const int *list, const DATASET *dset)
5030 {
5031     int badv = 0;
5032     int err = 0;
5033 
5034     if (dset == NULL || dset->n == 0) {
5035         err = E_NODATA;
5036     } else {
5037         int i;
5038 
5039         for (i=1; i<=list[0] && !err; i++) {
5040             if (list[i] >= dset->v ||
5041                 (list[i] < 0 && list[i] != LISTSEP)) {
5042                 badv = list[i];
5043                 err = E_DATA;
5044             }
5045         }
5046     }
5047 
5048     if (badv != 0) {
5049         gretl_errmsg_sprintf("list check: series ID %d "
5050                              "is out of bounds", badv);
5051     }
5052 
5053     return err;
5054 }
5055 
array_element_node(gretl_array * a,int i,parser * p)5056 static NODE *array_element_node (gretl_array *a, int i,
5057                                  parser *p)
5058 {
5059     NODE *ret = NULL;
5060     GretlType type = 0;
5061     void *data;
5062 
5063     data = gretl_array_get_element(a, i-1, &type, &p->err);
5064 
5065     if (p->err == E_INVARG) {
5066         gretl_errmsg_sprintf(_("Index value %d is out of bounds"), i);
5067     }
5068 
5069     if (!p->err) {
5070         if (type == GRETL_TYPE_STRING) {
5071             /* revised 2017-05-21 */
5072             ret = string_pointer_node(p);
5073             if (ret != NULL) {
5074                 ret->v.str = data;
5075             }
5076         } else if (type == GRETL_TYPE_MATRIX) {
5077             ret = matrix_pointer_node(p);
5078             if (ret != NULL) {
5079                 ret->v.m = data;
5080             }
5081         } else if (type == GRETL_TYPE_BUNDLE) {
5082             ret = bundle_pointer_node(p);
5083             if (ret != NULL) {
5084                 ret->v.b = data;
5085             }
5086         } else if (type == GRETL_TYPE_ARRAY) {
5087             ret = array_pointer_node(p);
5088             if (ret != NULL) {
5089                 ret->v.a = data;
5090             }
5091         } else if (type == GRETL_TYPE_DOUBLE) {
5092             ret = aux_scalar_node(p);
5093             if (ret != NULL) {
5094                 ret->v.xval = *(double *) data;
5095             }
5096         } else if (type == GRETL_TYPE_LIST) {
5097             /* last revised 2018-08-04 */
5098             p->err = stored_list_check((const int *) data, p->dset);
5099             if (!p->err) {
5100                 ret = list_pointer_node(p);
5101                 if (ret != NULL) {
5102                     ret->v.ivec = data;
5103                 }
5104             } else {
5105                 /* fallback: extract list as row vector */
5106                 gretl_error_clear();
5107                 p->err = 0;
5108                 ret = aux_matrix_node(p);
5109                 if (!p->err) {
5110                     ret->v.m = gretl_list_to_vector((const int *) data,
5111                                                     &p->err);
5112                 }
5113             }
5114         }
5115     }
5116 
5117     return ret;
5118 }
5119 
array_subspec_node(gretl_array * a,int * list,parser * p)5120 static NODE *array_subspec_node (gretl_array *a, int *list,
5121                                  parser *p)
5122 {
5123     NODE *ret = aux_array_node(p);
5124 
5125     if (ret != NULL) {
5126         ret->v.a = gretl_array_copy_subspec(a, list, &p->err);
5127     }
5128 
5129     return ret;
5130 }
5131 
list_range_node(int * list,int r1,int r2,parser * p)5132 static NODE *list_range_node (int *list, int r1, int r2, parser *p)
5133 {
5134     NODE *ret = NULL;
5135 
5136     if (starting(p)) {
5137 	ret = aux_list_node(p);
5138 	if (ret != NULL) {
5139 	    ret->v.ivec = gretl_list_sublist(list, r1, r2);
5140 	    if (ret->v.ivec == NULL) {
5141 		p->err = E_ALLOC;
5142 	    }
5143         }
5144     } else {
5145         ret = aux_any_node(p);
5146     }
5147 
5148     return ret;
5149 }
5150 
string_range_node(const char * s,int r1,int r2,parser * p)5151 static NODE *string_range_node (const char *s, int r1, int r2, parser *p)
5152 {
5153     NODE *ret = NULL;
5154 
5155     if (starting(p)) {
5156 	ret = aux_string_node(p);
5157 	if (ret != NULL) {
5158 	    ret->v.str = gretl_substring(s, r1, r2, &p->err);
5159 	}
5160     } else {
5161         ret = aux_any_node(p);
5162     }
5163 
5164     return ret;
5165 }
5166 
real_list_series_node(int * list,int i,parser * p)5167 static NODE *real_list_series_node (int *list, int i, parser *p)
5168 {
5169     NODE *ret = NULL;
5170     int v = 0;
5171 
5172     if (i < 1 || i > list[0]) {
5173         gretl_errmsg_sprintf(_("Index value %d is out of bounds"), i);
5174         p->err = E_INVARG;
5175     } else {
5176         v = list[i];
5177         if (v < 0 || v >= p->dset->v) {
5178             gretl_errmsg_sprintf(_("Variable number %d is out of bounds"), v);
5179             p->err = E_DATA;
5180         }
5181     }
5182 
5183     if (!p->err) {
5184         ret = aux_empty_series_node(p);
5185         if (!p->err) {
5186             /* scrub TMP_NODE, because using dset->Z member! */
5187             ret->flags = AUX_NODE;
5188             ret->vnum = v;
5189             ret->v.xvec = p->dset->Z[v];
5190         }
5191     }
5192 
5193     return ret;
5194 }
5195 
5196 /* coming from a context where we have @list and @i */
5197 
list_member_node(int * list,int i,parser * p)5198 static NODE *list_member_node (int *list, int i, parser *p)
5199 {
5200     NODE *ret = NULL;
5201 
5202     if (starting(p)) {
5203         ret = real_list_series_node(list, i, p);
5204     } else {
5205         ret = aux_any_node(p);
5206     }
5207 
5208     return ret;
5209 }
5210 
mspec_get_series_index(matrix_subspec * s,parser * p)5211 static int mspec_get_series_index (matrix_subspec *s,
5212                                    parser *p)
5213 {
5214     int t = -1;
5215 
5216     if (s->ltype == SEL_SINGLE) {
5217         t = s->lsel.range[0];
5218     } else if (s->ltype == SEL_RANGE && s->rtype == SEL_NULL) {
5219         if (s->lsel.range[0] == s->lsel.range[1]) {
5220             t = s->lsel.range[0];
5221         } else {
5222             /* allow for dates such as "2008:4" */
5223             gchar *tmp;
5224 
5225             tmp = g_strdup_printf("%d:%d", s->lsel.range[0],
5226                                   s->lsel.range[1]);
5227             t = get_observation_number(tmp, p->dset);
5228             g_free(tmp);
5229         }
5230     }
5231 
5232     if (t < 1 || t > p->dset->n) {
5233         p->err = E_DATA;
5234     }
5235 
5236     return t;
5237 }
5238 
mspec_get_array_index(matrix_subspec * spec,int * err)5239 static int mspec_get_array_index (matrix_subspec *spec,
5240                                   int *err)
5241 {
5242     int idx = 0;
5243 
5244     if (spec->ltype == SEL_SINGLE) {
5245         idx = spec->lsel.range[0];
5246     } else if (spec->ltype == SEL_RANGE &&
5247         spec->rtype == SEL_NULL &&
5248         spec->lsel.range[0] == spec->lsel.range[1]) {
5249         idx = spec->lsel.range[0];
5250     } else {
5251         gretl_errmsg_set("Invalid left-hand side index value");
5252         *err = E_TYPES;
5253     }
5254 
5255     return idx;
5256 }
5257 
5258 /* stricter variant of test_for_single_range */
5259 
get_single_element(matrix_subspec * spec,parser * p)5260 static int get_single_element (matrix_subspec *spec,
5261                                parser *p)
5262 {
5263     int ret = 0;
5264 
5265     if (spec->ltype == SEL_SINGLE) {
5266         ret = spec->lsel.range[0];
5267     } else {
5268         if (p != NULL) {
5269             p->err = E_TYPES;
5270         }
5271         ret = -1;
5272     }
5273 
5274     return ret;
5275 }
5276 
sub_addr_get_data(NODE * t,GretlType * ptype,user_var ** puv)5277 static void *sub_addr_get_data (NODE *t, GretlType *ptype,
5278                                 user_var **puv)
5279 {
5280     NODE *l = t->L, *r = t->R;
5281     gretl_array *a = l->v.ptr;
5282     GretlType type = 0;
5283     void *elem;
5284     int idx, err = 0;
5285 
5286     idx = get_single_element(r->v.mspec, NULL);
5287     elem = gretl_array_get_element(a, idx-1, &type, &err);
5288     *ptype = (elem == NULL)? GRETL_TYPE_NONE :
5289         gretl_type_get_ref_type(type);
5290     *puv = l->uv;
5291 #if 0
5292     fprintf(stderr, "sub_addr_get_data: idx=%d, a=%p, type=%d, err=%d\n",
5293             idx, a, type, err);
5294 #endif
5295 
5296     return elem;
5297 }
5298 
process_OSL_address(NODE * t,NODE * l,NODE * r,parser * p)5299 static NODE *process_OSL_address (NODE *t, NODE *l, NODE *r, parser *p)
5300 {
5301     int idx = get_single_element(r->v.mspec, p);
5302     NODE *lb = l->L;
5303     NODE *ret = NULL;
5304 
5305     if (lb->t != OSL || lb->uv == NULL || idx <= 0) {
5306         p->err = E_TYPES;
5307     } else {
5308         GretlType type = user_var_get_type(lb->uv);
5309 
5310         if (type == GRETL_TYPE_ARRAY) {
5311             ret = aux_parent_node(p);
5312             if (ret != NULL) {
5313                 ret->t = SUB_ADDR;
5314                 ret->L = lb; /* extracted left-hand */
5315                 ret->R = r;  /* evaluated right-hand */
5316                 /* prevent double-freeing of children @l and @r */
5317                 ret->flags |= LHT_NODE;
5318             }
5319         } else {
5320             p->err = E_TYPES;
5321         }
5322     }
5323 
5324     if (p->err) {
5325         gretl_errmsg_set(_("Wrong type of operand for unary '&'"));
5326     }
5327 
5328     return ret;
5329 }
5330 
want_singleton_array(NODE * n,parser * p)5331 static int want_singleton_array (NODE *n, parser *p)
5332 {
5333     if (p->aux != NULL && p->aux->t == ARRAY) {
5334 	GretlType t = gretl_array_get_type(n->v.a);
5335 
5336 	/* We want to preserve the ARRAY type of the aux
5337 	   node associated with @n: this requires producing
5338 	   a singleton array unless we're looking at an
5339 	   array of arrays.
5340 	*/
5341 	return t != GRETL_TYPE_ARRAYS;
5342     }
5343 
5344     return 0;
5345 }
5346 
array_subspec_list(NODE * l,NODE * r,parser * p)5347 static int *array_subspec_list (NODE *l, NODE *r, parser *p)
5348 {
5349     matrix_subspec *spec = r->v.mspec;
5350     int *list = NULL;
5351 
5352     if (spec->rtype != SEL_NULL) {
5353 	/* array selection must be one-dimensional */
5354 	p->err = E_INVARG;
5355     } else {
5356 	int len;
5357 
5358 	if (l->t == ARRAY) {
5359 	    len = gretl_array_get_length(l->v.a);
5360 	} else if (l->t == STR) {
5361 	    len = g_utf8_strlen(l->v.str, -1);
5362 	} else if (l->t == LIST) {
5363 	    len = l->v.ivec[0];
5364 	} else {
5365 	    p->err = E_TYPES;
5366 	    return NULL;
5367 	}
5368 
5369 	/* convert @spec to list of elements */
5370 	list = mspec_make_list(spec->ltype, &spec->lsel,
5371 			       len, &p->err);
5372     }
5373 
5374     return list;
5375 }
5376 
subobject_node(NODE * l,NODE * r,parser * p)5377 static NODE *subobject_node (NODE *l, NODE *r, parser *p)
5378 {
5379     NODE *ret = NULL;
5380 
5381     if (starting(p)) {
5382         if (r == NULL || r->t != MSPEC) {
5383             p->err = E_TYPES;
5384         } else if (l->t == MAT) {
5385             return submatrix_node(l, r, p);
5386         } else if (l->t == ARRAY) {
5387 	    int *vlist = array_subspec_list(l, r, p);
5388 
5389             if (!p->err && vlist[0] == 1) {
5390 		if (want_singleton_array(l, p)) {
5391 		    /* produce a 1-element array */
5392 		    ret = array_subspec_node(l->v.a, vlist, p);
5393 		} else {
5394 		    /* extract an array element */
5395 		    ret = array_element_node(l->v.a, vlist[1], p);
5396 		}
5397 	    } else if (!p->err) {
5398 		ret = array_subspec_node(l->v.a, vlist, p);
5399 	    }
5400             free(vlist);
5401         } else if (l->t == LIST || l->t == STR) {
5402 	    int *vlist = array_subspec_list(l, r, p);
5403 
5404 	    if (!p->err && !gretl_list_is_consecutive(vlist)) {
5405 		p->err = E_INVARG;
5406 	    }
5407 	    if (!p->err && vlist[0] == 1 && l->t == LIST) {
5408 		ret = list_member_node(l->v.ivec, vlist[1], p);
5409 	    } else if (!p->err) {
5410 		int r1 = vlist[1];
5411 		int r2 = vlist[vlist[0]];
5412 
5413                 if (l->t == LIST) {
5414                     ret = list_range_node(l->v.ivec, r1, r2, p);
5415                 } else {
5416                     ret = string_range_node(l->v.str, r1, r2, p);
5417                 }
5418 	    }
5419         } else if (l->t == SERIES) {
5420             int t = mspec_get_series_index(r->v.mspec, p);
5421 
5422             if (!p->err) {
5423                 ret = aux_scalar_node(p);
5424                 if (!p->err) {
5425                     ret->v.xval = l->v.xvec[t-1];
5426                 }
5427             }
5428         } else if (l->t == BUNDLE) {
5429             /* the "mspec" must hold a single key string */
5430             const char *key = mspec_get_string(r->v.mspec, 0);
5431             GretlType type = GRETL_TYPE_NONE;
5432             void *val = NULL;
5433             int size = 0;
5434 
5435             if (key == NULL) {
5436                 p->err = E_TYPES;
5437             } else {
5438                 val = gretl_bundle_get_data(l->v.b, key, &type, &size, &p->err);
5439             }
5440             if (!p->err) {
5441                 int t = gen_type_from_gretl_type(type);
5442 
5443                 if (t == NUM) {
5444                     ret = aux_scalar_node(p);
5445                     if (!p->err) {
5446                         ret->v.xval = *(double *) val;
5447                     }
5448                 } else {
5449                     ret = get_aux_node(p, t, 0, 0);
5450                     if (!p->err) {
5451                         ret->v.ptr = val;
5452                     }
5453                 }
5454             }
5455 	} else if (l->t == NUM) {
5456 	    /* allow "indexing into" a scalar, but only only for a
5457 	       single index with value 1
5458 	    */
5459 	    int i = get_single_element(r->v.mspec, p);
5460 
5461 	    if (i == 1) {
5462 		ret = aux_scalar_node(p);
5463 		if (!p->err) {
5464 		    ret->v.xval = l->v.xval;
5465 		}
5466 	    } else {
5467 		p->err = E_TYPES;
5468 	    }
5469         } else {
5470             fprintf(stderr, "subobject_node: l='%s', r='%s'\n",
5471                     getsymb(l->t), getsymb(r->t));
5472             p->err = E_TYPES;
5473         }
5474     } else {
5475         ret = aux_any_node(p);
5476     }
5477 
5478     return ret;
5479 }
5480 
process_subslice(NODE * l,NODE * r,parser * p)5481 static NODE *process_subslice (NODE *l, NODE *r, parser *p)
5482 {
5483     NODE *ret = NULL;
5484 
5485     if (starting(p)) {
5486         if (scalar_node(l) && null_or_scalar(r)) {
5487             ret = aux_ivec_node(p, 2);
5488             if (ret != NULL) {
5489                 ret->v.ivec[0] = node_get_int(l, p);
5490                 if (null_node(r)) {
5491                     ret->v.ivec[1] = MSEL_MAX; /* placeholder */
5492                 } else {
5493                     ret->v.ivec[1] = node_get_int(r, p);
5494                 }
5495             }
5496         } else {
5497             p->err = E_TYPES;
5498         }
5499     } else {
5500         ret = aux_ivec_node(p, 2);
5501     }
5502 
5503     return ret;
5504 }
5505 
5506 /* Note: many standard and a few non-standard math functions
5507    are not included in the switch below, because pointers to
5508    the functions are saved, obviating the need for repeated
5509    lookup. See the @ptrfuncs mechanism in genlex.c.
5510 */
5511 
real_apply_func(double x,int f,parser * p)5512 static double real_apply_func (double x, int f, parser *p)
5513 {
5514     double y;
5515 
5516     errno = 0;
5517 
5518     if (na(x)) {
5519         switch (f) {
5520         case F_MISSING:
5521             return 1.0;
5522         case F_DATAOK:
5523         case F_MISSZERO:
5524             return 0.0;
5525         default:
5526             return NADBL;
5527         }
5528     }
5529 
5530     switch (f) {
5531     case U_NEG:
5532         return -x;
5533     case U_POS:
5534         return x;
5535     case U_NOT:
5536         return x == 0;
5537     case F_TOINT:
5538         return (double) (int) x;
5539     case F_MISSING:
5540         return 0.0;
5541     case F_DATAOK:
5542         return 1.0;
5543     case F_MISSZERO:
5544         return x;
5545     case F_ZEROMISS:
5546         return (x == 0.0)? NADBL : x;
5547     case F_EASTER:
5548         y = easterdate(x);
5549         return y;
5550         /* below: functions that should already be mapped;
5551            it should be possible to delete them
5552         */
5553     case F_LOG: /* in case it's aliased */
5554         return log(x);
5555     default:
5556         return 0.0;
5557     }
5558 }
5559 
5560 /* @n must be of type NUM, MAT or SERIES, pre-checked */
5561 
node_get_double(NODE * n,int i,parser * p)5562 static double node_get_double (NODE *n, int i, parser *p)
5563 {
5564     if (n->t == NUM) {
5565         return n->v.xval;
5566     } else if (n->t == MAT) {
5567         return n->v.m->val[i];
5568     } else {
5569         return n->v.xvec[p->dset->t1 + i];
5570     }
5571 }
5572 
5573 /* @n must be of type NUM, MAT or SERIES, pre-checked */
5574 
node_set_double(NODE * n,int i,double x,parser * p)5575 static void node_set_double (NODE *n, int i, double x, parser *p)
5576 {
5577     if (n->t == NUM) {
5578         n->v.xval = x;
5579     } else if (n->t == MAT) {
5580         n->v.m->val[i] = x;
5581     } else {
5582         n->v.xvec[p->dset->t1 + i] = x;
5583     }
5584 }
5585 
bincoeff(double n,double k,int * err)5586 static double bincoeff(double n, double k, int *err)
5587 {
5588     double ret;
5589 
5590     if ((n < k) || (k < 0)) {
5591         *err = E_INVARG;
5592         return NADBL;
5593     }
5594 
5595     /* catch special cases first */
5596     if (n == k || k == 0) {
5597         ret = 1.0;
5598     } else if ((n - k) == 1|| k == 1) {
5599         ret = n;
5600     } else {
5601         ret = lgamma(n+1) - lgamma(k+1) - lgamma(n-k+1);
5602         ret = exp(ret);
5603     }
5604 
5605     return ret;
5606 }
5607 
5608 /* flexible_2arg_node() handles cases like atan2, where we have two
5609    possibly heterogeneous arguments (scalar, series, matrix) and the
5610    objective is to return a sensibly sized object.
5611 */
5612 
flexible_2arg_node(NODE * l,NODE * r,int f,parser * p)5613 static NODE *flexible_2arg_node (NODE *l, NODE *r, int f, parser *p)
5614 {
5615     NODE *ret = NULL;
5616     int rettype = 0;
5617     int nmin, nmax;
5618     int nl = 0, nr = 0;
5619 
5620     if (l->t == NUM) {
5621         nl = 1;
5622     } else if (l->t == MAT) {
5623         nl = gretl_vector_get_length(l->v.m);
5624     } else {
5625         nl = sample_size(p->dset);
5626     }
5627 
5628     if (r->t == NUM) {
5629         nr = 1;
5630     } else if (r->t == MAT) {
5631         nr = gretl_vector_get_length(r->v.m);
5632     } else {
5633         nr = sample_size(p->dset);
5634     }
5635 
5636     nmin = nr < nl ? nr : nl;
5637     nmax = nr > nl ? nr : nl;
5638 
5639     if (nmin == 0 || (nmin > 1 && nmax != nmin)) {
5640         p->err = E_NONCONF;
5641         return NULL;
5642     }
5643 
5644     /* ordering is MAT > SERIES > NUM */
5645     rettype = r->t > l->t ? r->t : l->t;
5646 
5647     if (rettype == NUM) {
5648         ret = aux_scalar_node(p);
5649     } else if (rettype == MAT) {
5650         ret = aux_sized_matrix_node(p, nmax, 1, 0);
5651     } else {
5652         ret = aux_series_node(p);
5653     }
5654 
5655     if (ret != NULL && !p->err) {
5656         double x1, x2, y = NADBL;
5657         int i;
5658 
5659         for (i=0; i<nmax; i++) {
5660             x1 = node_get_double(l, i, p);
5661             x2 = node_get_double(r, i, p);
5662             if (f == F_ATAN2) {
5663                 y = atan2(x1, x2);
5664             } else if (f == F_BINCOEFF) {
5665                 y = bincoeff(x1, x2, &p->err);
5666                 if (p->err) {
5667                     break;
5668                 }
5669             }
5670             node_set_double(ret, i, y, p);
5671         }
5672     }
5673 
5674     return ret;
5675 }
5676 
apply_scalar_func(NODE * n,NODE * f,parser * p)5677 static NODE *apply_scalar_func (NODE *n, NODE *f, parser *p)
5678 {
5679     NODE *ret = aux_scalar_node(p);
5680 
5681     if (ret != NULL) {
5682         double (*dfunc) (double) = f->v.ptr;
5683 
5684         if (dfunc != NULL) {
5685             ret->v.xval = dfunc(n->v.xval);
5686         } else {
5687             ret->v.xval = real_apply_func(n->v.xval, f->t, p);
5688         }
5689     }
5690 
5691     return ret;
5692 }
5693 
misc_scalar_node(NODE * n,int f,parser * p)5694 static NODE *misc_scalar_node (NODE *n, int f, parser *p)
5695 {
5696     NODE *ret = aux_scalar_node(p);
5697 
5698     if (ret != NULL) {
5699         int s = node_get_int(n, p);
5700 
5701 	if (f == F_SLEEP) {
5702 	    g_usleep(G_USEC_PER_SEC * s);
5703 	    ret->v.xval = 0;
5704 	} else {
5705 	    gretl_set_sf_cgi(s);
5706 	    ret->v.xval = 0;
5707 	}
5708     }
5709 
5710     return ret;
5711 }
5712 
scalar_isnan_node(NODE * n,parser * p)5713 static NODE *scalar_isnan_node (NODE *n, parser *p)
5714 {
5715     NODE *ret = aux_scalar_node(p);
5716 
5717     if (ret != NULL) {
5718         double x = node_get_scalar(n, p);
5719 
5720         if (!p->err) {
5721             ret->v.xval = isnan(x) != 0;
5722         }
5723     }
5724 
5725     return ret;
5726 }
5727 
matrix_isnan_node(NODE * n,parser * p)5728 static NODE *matrix_isnan_node (NODE *n, parser *p)
5729 {
5730     NODE *ret = aux_matrix_node(p);
5731 
5732     if (ret != NULL && starting(p)) {
5733         const gretl_matrix *m = n->v.m;
5734 
5735         if (m->rows == 0 || m->cols == 0) {
5736             p->err = E_DATA;
5737         } else {
5738             ret->v.m = gretl_matrix_alloc(m->rows, m->cols);
5739             if (ret->v.m == NULL) {
5740                 p->err = E_ALLOC;
5741             } else {
5742                 int i, n = m->rows * m->cols;
5743 
5744                 for (i=0; i<n; i++) {
5745                     ret->v.m->val[i] = isnan(m->val[i]) != 0;
5746                 }
5747                 gretl_matrix_set_complex(ret->v.m, m->is_complex);
5748             }
5749         }
5750     }
5751 
5752     return ret;
5753 }
5754 
apply_series_func(NODE * n,NODE * f,parser * p)5755 static NODE *apply_series_func (NODE *n, NODE *f, parser *p)
5756 {
5757     NODE *ret = aux_series_node(p);
5758     int t;
5759 
5760     if (ret != NULL) {
5761         double (*dfunc) (double) = f->v.ptr;
5762         const double *x;
5763 
5764         if (n->t == SERIES) {
5765             x = n->v.xvec;
5766         } else {
5767             x = get_colvec_as_series(n, f->t, p);
5768         }
5769 
5770         if (!p->err) {
5771             if (autoreg(p)) {
5772                 if (dfunc != NULL) {
5773                     ret->v.xvec[p->obs] = dfunc(x[p->obs]);
5774                 } else {
5775                     ret->v.xvec[p->obs] = real_apply_func(x[p->obs], f->t, p);
5776                 }
5777             } else if (dfunc != NULL) {
5778                 for (t=p->dset->t1; t<=p->dset->t2; t++) {
5779                     ret->v.xvec[t] = dfunc(x[t]);
5780                 }
5781             } else {
5782                 for (t=p->dset->t1; t<=p->dset->t2; t++) {
5783                     ret->v.xvec[t] = real_apply_func(x[t], f->t, p);
5784                 }
5785             }
5786         }
5787     }
5788 
5789     return ret;
5790 }
5791 
5792 /* argument is series or list; value returned is list */
5793 
dummify_func(NODE * l,NODE * r,parser * p)5794 static NODE *dummify_func (NODE *l, NODE *r, parser *p)
5795 {
5796     NODE *ret = aux_list_node(p);
5797 
5798     if (ret != NULL && starting(p)) {
5799         int *list = NULL;
5800         double oddval = NADBL;
5801 
5802         if (!null_node(r)) {
5803             if (r->t != NUM) {
5804                 p->err = E_TYPES;
5805                 return ret;
5806             } else {
5807                 oddval = r->v.xval;
5808             }
5809         }
5810 
5811         if (l->t == LIST) {
5812             list = gretl_list_copy(l->v.ivec);
5813         } else if (useries_node(l)) {
5814             list = gretl_list_new(1);
5815             list[1] = l->vnum;
5816         } else {
5817 	    gretl_errmsg_set(_("The first argument must be a named series "
5818 			       "in the current dataset"));
5819             p->err = E_INVARG;
5820         }
5821 
5822         if (p->err) {
5823             ; /* don't do anything more */
5824         } else if (list == NULL) {
5825             p->err = E_ALLOC;
5826         } else if (null_node(r)) {
5827             /* got just one argument */
5828             p->err = list_dumgenr(&list, p->dset, OPT_F);
5829             ret->v.ivec = list;
5830         } else if (list[0] > 1) {
5831             gretl_errmsg_set("dummify(x, y): first argument should be a single series");
5832             free(list);
5833             p->err = E_DATA;
5834         } else {
5835             p->err = dumgenr_with_oddval(&list, p->dset, oddval);
5836             ret->v.ivec = list;
5837         }
5838     }
5839 
5840     return ret;
5841 }
5842 
5843 /* argument is list; value returned is list */
5844 
cdummify_func(NODE * n,parser * p)5845 static NODE *cdummify_func (NODE *n, parser *p)
5846 {
5847     NODE *ret = aux_list_node(p);
5848 
5849     if (ret != NULL && starting(p)) {
5850         int *list = NULL;
5851 
5852         if (n->t == LIST) {
5853             list = gretl_list_copy(n->v.ivec);
5854         } else if (useries_node(n)) {
5855             list = gretl_list_new(1);
5856             list[1] = n->vnum;
5857         } else {
5858             p->err = E_TYPES;
5859         }
5860 
5861         if (p->err) {
5862             ; /* don't do anything more */
5863         } else if (list == NULL) {
5864             p->err = E_ALLOC;
5865         } else {
5866             p->err = auto_dummify_list(&list, p->dset);
5867             ret->v.ivec = list;
5868         }
5869     }
5870 
5871     return ret;
5872 }
5873 
get_info_on_series(NODE * n,parser * p)5874 static NODE *get_info_on_series (NODE *n, parser *p)
5875 {
5876     NODE *ret = aux_bundle_node(p);
5877 
5878     if (ret != NULL && starting(p)) {
5879         int v = 0;
5880 
5881         if (useries_node(n)) {
5882             v = n->vnum;
5883         } else {
5884             v = node_get_int(n, p);
5885         }
5886 
5887         if (!p->err) {
5888             ret->v.b = series_info_bundle(p->dset, v, &p->err);
5889         }
5890     }
5891 
5892     return ret;
5893 }
5894 
list_stdize(NODE * l,NODE * r,parser * p)5895 static NODE *list_stdize (NODE *l, NODE *r, parser *p)
5896 {
5897     NODE *ret = aux_list_node(p);
5898 
5899     if (ret != NULL && starting(p)) {
5900         int *list = NULL;
5901         int dfc = 1;
5902 
5903         if (!null_node(r)) {
5904             dfc = node_get_int(r, p);
5905         }
5906         if (!p->err) {
5907             list = node_get_list(l, p);
5908         }
5909         if (!p->err) {
5910             gretlopt opt;
5911 
5912             opt = dfc < 0 ? OPT_C : dfc == 0 ? OPT_N : OPT_NONE;
5913             if (list[0] > 0) {
5914                 p->err = list_stdgenr(list, p->dset, opt);
5915             }
5916             ret->v.ivec = list;
5917         }
5918     }
5919 
5920     return ret;
5921 }
5922 
series_stdize(NODE * l,NODE * r,parser * p)5923 static NODE *series_stdize (NODE *l, NODE *r, parser *p)
5924 {
5925     NODE *ret = aux_series_node(p);
5926 
5927     if (ret != NULL && starting(p)) {
5928         int dfc = 1;
5929 
5930         if (!null_node(r)) {
5931             dfc = node_get_int(r, p);
5932         }
5933         if (!p->err) {
5934             p->err = standardize_series(l->v.xvec, ret->v.xvec,
5935                                         dfc, p->dset);
5936         }
5937     }
5938 
5939     return ret;
5940 }
5941 
5942 /* middle argument is series or list; value returned is list in
5943    either case */
5944 
list_make_lags(NODE * l,NODE * m,NODE * r,parser * p)5945 static NODE *list_make_lags (NODE *l, NODE *m, NODE *r, parser *p)
5946 {
5947     NODE *ret = aux_list_node(p);
5948 
5949     if (ret != NULL && starting(p)) {
5950         gretlopt opt = OPT_NONE;
5951         gretl_matrix *v = NULL;
5952         int *list = NULL;
5953         int k = 0;
5954 
5955         /* ordering of the results? */
5956         if (node_get_bool(r, p, 0) > 0 && !p->err) {
5957             opt = OPT_L; /* by lags */
5958         }
5959 
5960         if (!p->err) {
5961             /* scalar lag order or vector */
5962             if (l->t == NUM) {
5963                 k = node_get_int(l, p);
5964             } else {
5965                 v = l->v.m;
5966             }
5967         }
5968 
5969         if (!p->err) {
5970             list = node_get_list(m, p);
5971         }
5972 
5973         if (!p->err) {
5974             if (list[0] > 0) {
5975                 p->err = list_laggenr(&list, 1, k, v,
5976                                       p->dset, 0, opt);
5977             }
5978             ret->v.ivec = list;
5979         }
5980     }
5981 
5982     return ret;
5983 }
5984 
matrix_make_lags(NODE * l,NODE * m,NODE * r,parser * p)5985 static NODE *matrix_make_lags (NODE *l, NODE *m, NODE *r, parser *p)
5986 {
5987     NODE *ret = aux_matrix_node(p);
5988 
5989     if (ret != NULL && starting(p)) {
5990         gretlopt opt = OPT_NONE;
5991         gretl_matrix *kvec = NULL;
5992         gretl_matrix *src = NULL;
5993 
5994         if (node_get_bool(r, p, 0) > 0 && !p->err) {
5995             opt = OPT_L; /* by lags */
5996         }
5997 
5998         if (!p->err) {
5999             /* scalar max lag order or vector */
6000             if (l->t == NUM) {
6001                 int i, k = node_get_int(l, p);
6002 
6003                 if (!p->err && k <= 0) {
6004                     /* scalar k must be positive */
6005                     p->err = E_INVARG;
6006                 } else if (!p->err) {
6007                     kvec = gretl_vector_alloc(k);
6008                     if (kvec == NULL) {
6009                         p->err = E_ALLOC;
6010                     } else {
6011                         for (i=0; i<k; i++) {
6012                             kvec->val[i] = i+1;
6013                         }
6014                     }
6015                 }
6016             } else {
6017                 kvec = l->v.m;
6018             }
6019         }
6020 
6021         if (!p->err) {
6022             src = m->v.m;
6023         }
6024 
6025         if (!p->err) {
6026             ret->v.m = gretl_matrix_lag(src, kvec, opt, 0.0);
6027         }
6028 
6029         if (kvec != l->v.m) {
6030             gretl_matrix_free(kvec);
6031         }
6032     }
6033 
6034     return ret;
6035 }
6036 
6037 /* args are minlag, maxlag, MIDAS-list-to-be-lagged */
6038 
hf_list_make_lags(NODE * l,NODE * m,NODE * r,parser * p)6039 static NODE *hf_list_make_lags (NODE *l, NODE *m, NODE *r, parser *p)
6040 {
6041     NODE *ret = aux_list_node(p);
6042 
6043     if (ret != NULL && starting(p)) {
6044         int *list = NULL;
6045         int lmin, lmax = 0;
6046         int cfac = 0;
6047 
6048         lmin = node_get_int(l, p);
6049         if (!p->err) {
6050             lmax = node_get_int(m, p);
6051         }
6052         if (!p->err) {
6053             list = node_get_list(r, p);
6054         }
6055 
6056         if (!p->err) {
6057             /* compaction factor for high-frequency data */
6058             cfac = list[0];
6059             if (cfac < 2) {
6060                 fprintf(stderr, "hflags: not a MIDAS list\n");
6061                 p->err = E_INVARG;
6062                 free(list);
6063             }
6064         }
6065 
6066         if (!p->err) {
6067             if (list[0] > 0) {
6068                 p->err = list_laggenr(&list, lmin, lmax, NULL,
6069                                       p->dset, cfac, OPT_L);
6070             }
6071             ret->v.ivec = list;
6072         }
6073     }
6074 
6075     return ret;
6076 }
6077 
6078 #define ok_list_func(f) (f == F_LOG || f == F_DIFF || \
6079                          f == F_LDIFF || f == F_SDIFF || \
6080                          f == F_SQUARE || f == F_ODEV || \
6081                          f == F_RESAMPLE || f == F_DROPCOLL || \
6082                          f == F_HFDIFF || f == F_HFLDIFF)
6083 
6084 /* The following handles functions that are "basically" for series,
6085    but which can also be applied to lists -- except for F_DROPCOLL,
6086    F_HFDIFF and F_HDLDIFF, which require a list argument.
6087 */
6088 
apply_list_func(NODE * n,NODE * r,int f,parser * p)6089 static NODE *apply_list_func (NODE *n, NODE *r, int f, parser *p)
6090 {
6091     NODE *ret = aux_list_node(p);
6092 
6093     if (!ok_list_func(f)) {
6094         p->err = E_TYPES;
6095         return ret;
6096     }
6097 
6098     if (ret != NULL && starting(p)) {
6099         int *list = node_get_list(n, p);
6100         gretlopt opt = OPT_NONE;
6101         double parm = NADBL;
6102         int t = 0;
6103 
6104         if (f == F_SQUARE) {
6105             if (r != NULL && node_is_true(r, p)) {
6106                 opt = OPT_O;
6107             }
6108         } else if (f == F_DROPCOLL || f == F_HFDIFF ||
6109                    f == F_HFLDIFF) {
6110             /* handle optional parameter */
6111             if (!null_node(r)) {
6112                 parm = node_get_scalar(r, p);
6113                 if (p->err) {
6114                     return ret;
6115                 }
6116             }
6117         }
6118 
6119         /* note: @list is modified by the library functions
6120            called below */
6121 
6122         if (list != NULL) {
6123             /* note: an empty list argument produces an
6124                empty list return
6125             */
6126             if (list[0] > 0) {
6127                 switch (f) {
6128                 case F_LOG:
6129                     p->err = list_loggenr(list, p->dset);
6130                     break;
6131                 case F_DIFF:
6132                 case F_LDIFF:
6133                 case F_SDIFF:
6134                     if (f == F_DIFF) t = DIFF;
6135                     else if (f == F_LDIFF) t = LDIFF;
6136                     else if (f == F_SDIFF) t = SDIFF;
6137                     p->err = list_diffgenr(list, t, p->dset);
6138                     break;
6139                 case F_SQUARE:
6140                     p->err = list_xpxgenr(&list, p->dset, opt);
6141                     break;
6142                 case F_ODEV:
6143                     p->err = list_orthdev(list, p->dset);
6144                     break;
6145                 case F_RESAMPLE:
6146                     p->err = list_resample(list, p->dset);
6147                     break;
6148                 case F_DROPCOLL:
6149                     p->err = list_dropcoll(list, parm, p->dset);
6150                     break;
6151                 case F_HFDIFF:
6152                 case F_HFLDIFF:
6153                     t = (f == F_HFDIFF)? DIFF : LDIFF;
6154                     p->err = hf_list_diffgenr(list, t, parm, p->dset);
6155                     break;
6156                 default:
6157                     break;
6158                 }
6159             }
6160             ret->v.ivec = list;
6161         }
6162     }
6163 
6164     return ret;
6165 }
6166 
hf_list_node(NODE * l,NODE * m,NODE * r,parser * p)6167 static NODE *hf_list_node (NODE *l, NODE *m, NODE *r, parser *p)
6168 {
6169     gretl_matrix *v = l->v.m;
6170     int f_ratio = node_get_int(m, p);
6171     char *pfx = r->v.str;
6172     NODE *ret = NULL;
6173 
6174     if (!p->err) {
6175         int n = gretl_vector_get_length(v);
6176 
6177         if (n == 0) {
6178             p->err = E_NONCONF;
6179         } else if (f_ratio < 3) {
6180             p->err = E_INVARG;
6181         } else if (*pfx == '\0' || !gretl_is_ascii(pfx) ||
6182                    strlen(pfx) > 24) {
6183             p->err = E_INVARG;
6184         } else {
6185             int T = sample_size(p->dset);
6186 
6187             if (n != f_ratio * T) {
6188                 p->err = E_INVARG;
6189             }
6190         }
6191     }
6192 
6193     if (!p->err) {
6194         ret = aux_list_node(p);
6195         if (ret != NULL) {
6196             ret->v.ivec = vector_to_midas_list(v, f_ratio, pfx,
6197                                                p->dset, &p->err);
6198         }
6199     }
6200 
6201     return ret;
6202 }
6203 
dataset_list_node(parser * p)6204 static NODE *dataset_list_node (parser *p)
6205 {
6206     NODE *ret = NULL;
6207 
6208     if (gretl_function_depth() > 0) {
6209 	gretl_errmsg_set("'dataset' is not recognized as a list within functions");
6210 	p->err = E_DATA;
6211     } else {
6212 	ret = aux_list_node(p);
6213     }
6214 
6215     if (ret != NULL && starting(p)) {
6216         int *list = full_var_list(p->dset, NULL);
6217 
6218         if (list == NULL) {
6219             list = gretl_null_list();
6220         }
6221         if (list == NULL) {
6222             p->err = E_DATA;
6223         }
6224         ret->v.ivec = list;
6225     }
6226 
6227     return ret;
6228 }
6229 
trend_node(parser * p)6230 static NODE *trend_node (parser *p)
6231 {
6232     NODE *ret = NULL;
6233 
6234     if (starting(p)) {
6235         ret = aux_empty_series_node(p);
6236         if (!p->err) {
6237             p->err = gen_time(p->dset, 1, &ret->vnum);
6238             if (!p->err) {
6239                 ret->v.xvec = p->dset->Z[ret->vnum];
6240                 /* not TMP_NODE because we're borrowing a Z column */
6241                 ret->flags &= ~TMP_NODE;
6242             }
6243         }
6244     }
6245 
6246     return ret;
6247 }
6248 
array_last_node(parser * p)6249 static NODE *array_last_node (parser *p)
6250 {
6251     NODE *ret = NULL;
6252 
6253     if (starting(p)) {
6254         ret = aux_scalar_node(p);
6255         if (!p->err) {
6256 	    ret->v.xval = IDX_TBD;
6257 	}
6258     }
6259 
6260     return ret;
6261 }
6262 
seasonals_node(NODE * l,NODE * r,parser * p)6263 static NODE *seasonals_node (NODE *l, NODE *r, parser *p)
6264 {
6265     NODE *ret = NULL;
6266 
6267     if (!dataset_is_seasonal(p->dset) &&
6268         !dataset_is_seasonal_panel(p->dset)) {
6269         p->err = E_PDWRONG;
6270     } else {
6271         int ref = 0, center = 0;
6272 
6273         if (!null_node(l)) {
6274             ref = node_get_int(l, p);
6275         }
6276         if (!null_node(r)) {
6277             center = node_is_true(r, p);
6278         }
6279         if (!p->err) {
6280             ret = aux_list_node(p);
6281         }
6282         if (ret != NULL) {
6283             ret->v.ivec = seasonals_list(p->dset, ref, center, &p->err);
6284         }
6285     }
6286 
6287     return ret;
6288 }
6289 
get_lag_list(NODE * l,NODE * r,parser * p)6290 static NODE *get_lag_list (NODE *l, NODE *r, parser *p)
6291 {
6292     NODE *ret = NULL;
6293 
6294     if (starting(p)) {
6295         int *list = NULL, *srclist = NULL;
6296         int i, imin = 1, imax = 1;
6297         int lv = 0;
6298 
6299         if (!useries_node(l) && l->t != LIST) {
6300             /* we need a named series or a list on the left */
6301             p->err = E_TYPES;
6302         } else if (r->t != IVEC && r->t != NUM) {
6303             /* we need one or more integers on the right */
6304             p->err = E_TYPES;
6305         }
6306 
6307         if (p->err) {
6308             return NULL;
6309         }
6310 
6311         if (l->t == LIST) {
6312             srclist = l->v.ivec;
6313             imax = srclist[0];
6314         } else {
6315             lv = l->vnum;
6316         }
6317 
6318         if (imax == 0) {
6319             /* empty list on input -> empty on output */
6320             list = gretl_list_new(0);
6321             if (list == NULL) {
6322                 p->err = E_ALLOC;
6323             }
6324             goto loopdone;
6325         }
6326 
6327         for (i=imin; i<=imax && !p->err; i++) {
6328             if (srclist != NULL) {
6329                 lv = srclist[i];
6330             }
6331             if (r->t == IVEC) {
6332                 int fromlag = r->v.ivec[0];
6333                 int tolag = r->v.ivec[1];
6334 
6335                 if (list == NULL) {
6336                     list = laggenr_from_to(lv, fromlag, tolag,
6337                                            p->dset, &p->err);
6338                 } else {
6339                     int *tmp;
6340 
6341                     tmp = laggenr_from_to(lv, fromlag, tolag,
6342                                            p->dset, &p->err);
6343                     if (!p->err) {
6344                         p->err = gretl_list_add_list(&list, tmp);
6345                         free(tmp);
6346                     }
6347                 }
6348             } else {
6349                 int lag = -r->v.xval;
6350 
6351                 lv = laggenr(lv, lag, p->dset);
6352                 if (lv > 0) {
6353                     list = gretl_list_append_term(&list, lv);
6354                     if (list == NULL) {
6355                         p->err = E_ALLOC;
6356                     }
6357                 }
6358             }
6359         }
6360 
6361     loopdone:
6362 
6363         if (list != NULL) {
6364             ret = aux_list_node(p);
6365             if (ret != NULL) {
6366                 ret->v.ivec = list;
6367             } else {
6368                 free(list);
6369             }
6370         }
6371     } else {
6372         ret = aux_any_node(p);
6373     }
6374 
6375     return ret;
6376 }
6377 
list_from_strings_array(gretl_array * a,parser * p)6378 int *list_from_strings_array (gretl_array *a, parser *p)
6379 {
6380     GretlType type = gretl_array_get_type(a);
6381     int *list = NULL;
6382 
6383     if (type != GRETL_TYPE_STRINGS) {
6384         p->err = E_TYPES;
6385     } else {
6386         int i, vi, n = 0;
6387         char **S = gretl_array_get_strings(a, &n);
6388 
6389         for (i=0; i<n && !p->err; i++) {
6390             vi = current_series_index(p->dset, S[i]);
6391             if (vi < 0) {
6392                 gretl_errmsg_sprintf("'%s' is not a known series", S[i]);
6393                 p->err = E_UNKVAR;
6394             }
6395         }
6396 
6397         if (!p->err) {
6398             list = gretl_list_new(n);
6399             if (list == NULL) {
6400                 p->err = E_ALLOC;
6401             } else {
6402                 for (i=0; i<n; i++) {
6403                     list[i+1] = current_series_index(p->dset, S[i]);
6404                 }
6405             }
6406         }
6407     }
6408 
6409     return list;
6410 }
6411 
6412 /* get an *int LIST from node @n: note that the list is always
6413    newly allocated, and so should be freed by the caller if
6414    it's just for temporary use
6415 */
6416 
node_get_list(NODE * n,parser * p)6417 int *node_get_list (NODE *n, parser *p)
6418 {
6419     int *list = NULL;
6420     int v = 0;
6421 
6422     if (n->t == LIST) {
6423         list = gretl_list_copy(n->v.ivec);
6424     } else if (n->t == SERIES || n->t == NUM) {
6425         v = (n->t == SERIES)? n->vnum : node_get_int(n, p);
6426         if (!p->err) {
6427             if (v < 0 || v >= p->dset->v) {
6428                 p->err = E_UNKVAR;
6429             } else {
6430                 list = gretl_list_new(1);
6431                 if (list == NULL) {
6432                     p->err = E_ALLOC;
6433                 } else {
6434                     list[1] = v;
6435                 }
6436             }
6437         }
6438     } else if (null_node(n)) {
6439         list = gretl_null_list();
6440     } else if (dataset_dum(n)) {
6441         list = full_var_list(p->dset, NULL);
6442     } else if (n->t == MAT) {
6443         list = gretl_list_from_vector(n->v.m, p->dset, &p->err);
6444     } else {
6445         p->err = E_TYPES;
6446     }
6447 
6448     if (!p->err && list == NULL) {
6449         p->err = E_ALLOC;
6450     } else if (p->err == E_UNKVAR && v != 0) {
6451         gretl_errmsg_sprintf(_("Variable number %d is out of bounds"), v);
6452     }
6453 
6454     return list;
6455 }
6456 
eval_lcat(NODE * l,NODE * r,parser * p)6457 static NODE *eval_lcat (NODE *l, NODE *r, parser *p)
6458 {
6459     NODE *ret = aux_list_node(p);
6460 
6461     if (ret != NULL && starting(p)) {
6462         int *list1, *list2 = NULL;
6463 
6464         list1 = node_get_list(l, p); /* note, copied */
6465         if (list1 != NULL) {
6466             list2 = node_get_list(r, p); /* copied */
6467         }
6468         if (list2 != NULL) {
6469             p->err = gretl_list_add_list(&list1, list2);
6470         }
6471         ret->v.ivec = list1;
6472         free(list2);
6473     }
6474 
6475     return ret;
6476 }
6477 
list_list_op(NODE * l,NODE * r,int f,parser * p)6478 static NODE *list_list_op (NODE *l, NODE *r, int f, parser *p)
6479 {
6480     NODE *ret = aux_list_node(p);
6481 
6482     if (ret != NULL && starting(p)) {
6483         int *llist, *rlist = NULL;
6484         int *list = NULL;
6485 
6486         llist = node_get_list(l, p);
6487         if (llist != NULL) {
6488             rlist = node_get_list(r, p);
6489         }
6490         if (rlist != NULL) {
6491             if (f == B_AND) {
6492                 list = gretl_list_intersection(llist, rlist, &p->err);
6493             } else if (f == B_OR) {
6494                 list = gretl_list_union(llist, rlist, &p->err);
6495             } else if (f == B_SUB) {
6496                 list = gretl_list_drop(llist, rlist, &p->err);
6497             } else if (f == B_POW) {
6498                 list = gretl_list_product(llist, rlist, p->dset, &p->err);
6499             } else if (f == B_ADD) {
6500                 list = gretl_list_plus(llist, rlist, &p->err);
6501             }
6502         }
6503         ret->v.ivec = list;
6504         free(llist);
6505         free(rlist);
6506     }
6507 
6508     return ret;
6509 }
6510 
6511 /* Binary operator applied to two bundles: at present only '+'
6512    (for union) is supported.
6513 */
6514 
bundle_op(NODE * l,NODE * r,int f,parser * p)6515 static NODE *bundle_op (NODE *l, NODE *r, int f, parser *p)
6516 {
6517     NODE *ret = aux_bundle_node(p);
6518 
6519     if (ret != NULL && starting(p)) {
6520         gretl_bundle *bl = l->v.b;
6521         gretl_bundle *br = r->v.b;
6522 
6523         if (!p->err) {
6524             if (f == B_ADD) {
6525                 ret->v.b = gretl_bundle_union(bl, br, &p->err);
6526             } else {
6527                 p->err = E_TYPES;
6528             }
6529         }
6530     }
6531 
6532     return ret;
6533 }
6534 
6535 /* Binary operator applied to two arrays: '+' (append),
6536    '||' (union) or '&&' (intersection). But the latter
6537    two are only for strings arrays.
6538 */
6539 
array_op(NODE * l,NODE * r,int f,parser * p)6540 static NODE *array_op (NODE *l, NODE *r, int f, parser *p)
6541 {
6542     NODE *ret = aux_array_node(p);
6543 
6544     if (ret != NULL && starting(p)) {
6545         gretl_array *al = l->v.a;
6546         gretl_array *ar = r->v.a;
6547 
6548         if (!p->err) {
6549             if (f == B_ADD) {
6550                 ret->v.a = gretl_arrays_join(al, ar, &p->err);
6551             } else if (f == B_OR) {
6552                 ret->v.a = gretl_arrays_union(al, ar, &p->err);
6553             } else if (f == B_AND) {
6554                 ret->v.a = gretl_arrays_intersection(al, ar, &p->err);
6555             } else {
6556                 p->err = E_TYPES;
6557             }
6558         }
6559     }
6560 
6561     return ret;
6562 }
6563 
augment_array_node(NODE * l,NODE * r,parser * p)6564 static NODE *augment_array_node (NODE *l, NODE *r, parser *p)
6565 {
6566     NODE *ret = aux_array_node(p);
6567 
6568     if (ret != NULL && starting(p)) {
6569         GretlType lt = gretl_array_get_content_type(l->v.a);
6570         GretlType rt = gretl_type_from_gen_type(r->t);
6571 
6572         if (rt == lt) {
6573             ret->v.a = gretl_array_copy(l->v.a, &p->err);
6574             if (!p->err) {
6575                 p->err = gretl_array_append_object(ret->v.a, r->v.ptr, 1);
6576             }
6577         } else {
6578             p->err = E_TYPES;
6579         }
6580     }
6581 
6582     return ret;
6583 }
6584 
subtract_from_array_node(NODE * l,NODE * r,parser * p)6585 static NODE *subtract_from_array_node (NODE *l, NODE *r, parser *p)
6586 {
6587     NODE *ret = aux_array_node(p);
6588 
6589     if (ret != NULL && starting(p)) {
6590 	if (gretl_array_get_type(l->v.a) == GRETL_TYPE_STRINGS &&
6591 	    r->t == STR) {
6592 	    ret->v.a = gretl_array_copy(l->v.a, &p->err);
6593 	    if (!p->err) {
6594 		p->err = gretl_array_drop_string(ret->v.a, r->v.str);
6595 	    }
6596 	}
6597     } else {
6598 	p->err = E_TYPES;
6599     }
6600 
6601     return ret;
6602 }
6603 
6604 /* in case we switched the LHS and RHS in a boolean comparison */
6605 
reversed_comp(int f)6606 static int reversed_comp (int f)
6607 {
6608     if (f == B_GT) {
6609         return B_LT;
6610     } else if (f == B_LT) {
6611         return B_GT;
6612     } else if (f == B_GTE) {
6613         return B_LTE;
6614     } else if (f == B_LTE) {
6615         return B_GTE;
6616     } else {
6617         return f;
6618     }
6619 }
6620 
6621 /* Boolean test of all vars in list against a scalar or series, for
6622    each observation in the sample, hence generating a series.
6623    The list will always be on the left-hand node; the 'reversed'
6624    flag is set if the list was originally on the right.
6625 */
6626 
list_bool_comp(NODE * l,NODE * r,int f,int reversed,parser * p)6627 static NODE *list_bool_comp (NODE *l, NODE *r, int f, int reversed,
6628                              parser *p)
6629 {
6630     NODE *ret = aux_series_node(p);
6631 
6632     if (ret != NULL && starting(p)) {
6633         int *list = node_get_list(l, p);
6634         double *x = ret->v.xvec;
6635         double xit, targ = NADBL;
6636         double *tvec = NULL;
6637         int i, t;
6638 
6639         if (r->t == NUM) {
6640             targ = r->v.xval;
6641         } else {
6642             tvec = r->v.xvec;
6643         }
6644 
6645         if (reversed) {
6646             f = reversed_comp(f);
6647         }
6648 
6649         if (list != NULL) {
6650             for (t=p->dset->t1; t<=p->dset->t2; t++) {
6651                 if (tvec != NULL) {
6652                     targ = tvec[t];
6653                 }
6654                 if (na(targ)) {
6655                     x[t] = NADBL;
6656                     continue;
6657                 }
6658                 x[t] = 1.0; /* assume 'true' */
6659                 for (i=1; i<=list[0]; i++) {
6660                     xit = p->dset->Z[list[i]][t];
6661                     if (na(xit)) {
6662                         x[t] = NADBL;
6663                         break;
6664                     } else if (f == B_EQ && xit != targ) {
6665                         x[t] = 0.0;
6666                     } else if (f == B_NEQ && xit == targ) {
6667                         x[t] = 0.0;
6668                     } else if (f == B_LT && xit >= targ) {
6669                         x[t] = 0.0;
6670                     } else if (f == B_GT && xit <= targ) {
6671                         x[t] = 0.0;
6672                     } else if (f == B_LTE && xit > targ) {
6673                         x[t] = 0.0;
6674                     } else if (f == B_GTE && xit < targ) {
6675                         x[t] = 0.0;
6676                     }
6677                 }
6678             }
6679             free(list);
6680         }
6681     }
6682 
6683     return ret;
6684 }
6685 
6686 /* Test for whether or not two lists are identical.  Note that
6687    using gretl_list_cmp() the order of the members matters.
6688    Perhaps the order shouldn't matter?
6689 */
6690 
list_list_comp(NODE * l,NODE * r,int f,parser * p)6691 static NODE *list_list_comp (NODE *l, NODE *r, int f, parser *p)
6692 {
6693     NODE *ret = aux_scalar_node(p);
6694 
6695     if (ret != NULL && starting(p)) {
6696         int *llist = node_get_list(l, p);
6697         int *rlist = node_get_list(r, p);
6698 
6699         if (llist != NULL && rlist != NULL) {
6700             int d = gretl_list_cmp(llist, rlist);
6701 
6702             if (f == B_NEQ) {
6703                 ret->v.xval = d;
6704             } else if (f == B_EQ) {
6705                 ret->v.xval = !d;
6706             } else {
6707                 p->err = E_TYPES;
6708             }
6709         }
6710         free(llist);
6711         free(rlist);
6712     }
6713 
6714     return ret;
6715 }
6716 
6717 /* argument is list; value returned is series */
6718 
list_to_series_func(NODE * n,int f,NODE * o,parser * p)6719 static NODE *list_to_series_func (NODE *n, int f, NODE *o, parser *p)
6720 {
6721     NODE *ret = aux_series_node(p);
6722 
6723     if (ret != NULL && starting(p)) {
6724 	int deflt = (f == F_MIN || f == F_MAX);
6725 	int partial_ok = node_get_bool(o, p, deflt);
6726 	int *list = NULL;
6727 
6728 	if (!p->err) {
6729 	    list = node_get_list(n, p);
6730 	}
6731         if (list != NULL) {
6732             p->err = cross_sectional_stat(ret->v.xvec, list,
6733                                           p->dset, f, partial_ok);
6734             free(list);
6735         }
6736     }
6737 
6738     return ret;
6739 }
6740 
6741 /* arguments are series on left, list on right: we add all members
6742    of list to series, or subtract all members */
6743 
series_list_calc(NODE * l,NODE * r,int f,parser * p)6744 static NODE *series_list_calc (NODE *l, NODE *r, int f, parser *p)
6745 {
6746     NODE *ret = aux_series_node(p);
6747 
6748     if (ret != NULL && starting(p)) {
6749         int *list = node_get_list(r, p);
6750 
6751         if (list != NULL) {
6752             double xt, xi;
6753             int i, t;
6754 
6755             for (t=p->dset->t1; t<=p->dset->t2; t++) {
6756                 xt = l->v.xvec[t];
6757                 if (!na(xt)) {
6758                     for (i=1; i<=list[0]; i++) {
6759                         xi = p->dset->Z[list[i]][t];
6760                         if (na(xi)) {
6761                             xt = NADBL;
6762                             break;
6763                         } else if (f == B_ADD) {
6764                             xt += xi;
6765                         } else {
6766                             xt -= xi;
6767                         }
6768                     }
6769                 }
6770                 ret->v.xvec[t] = xt;
6771             }
6772             free(list);
6773         }
6774     }
6775 
6776     return ret;
6777 }
6778 
node_get_midas_method(NODE * n,parser * p)6779 static int node_get_midas_method (NODE *n, parser *p)
6780 {
6781     int ret = -1;
6782 
6783     if (n->t == STR) {
6784 	if (!strcmp(n->v.str, "umidas")) {
6785 	    ret = MIDAS_U;
6786         } else if (!strcmp(n->v.str, "nealmon")) {
6787             ret = MIDAS_NEALMON;
6788         } else if (!strcmp(n->v.str, "beta0")) {
6789             ret = MIDAS_BETA0;
6790         } else if (!strcmp(n->v.str, "betan")) {
6791             ret = MIDAS_BETAN;
6792         } else if (!strcmp(n->v.str, "almonp")) {
6793             ret = MIDAS_ALMONP;
6794 	} else if (!strcmp(n->v.str, "beta1")) {
6795 	    ret = MIDAS_BETA1;
6796         }
6797     } else {
6798         ret = node_get_int(n, p);
6799     }
6800 
6801     if (ret < MIDAS_U || ret >= MIDAS_MAX) {
6802 	p->err = E_INVARG;
6803     }
6804 
6805     return ret;
6806 }
6807 
lincomb_func(NODE * l,NODE * m,NODE * r,int f,parser * p)6808 static NODE *lincomb_func (NODE *l, NODE *m, NODE *r, int f, parser *p)
6809 {
6810     NODE *ret = aux_series_node(p);
6811 
6812     if (ret != NULL && starting(p)) {
6813         int *list = node_get_list(l, p);
6814         const gretl_matrix *b = node_get_real_matrix(m, p, 0, 2);
6815         int k = 0;
6816 
6817         if (!p->err && (list == NULL || gretl_is_null_matrix(b))) {
6818             p->err = E_DATA;
6819         }
6820 
6821         if (!p->err && f == F_MLINCOMB) {
6822             k = node_get_midas_method(r, p);
6823         }
6824 
6825         if (!p->err) {
6826             if (f == F_MLINCOMB) {
6827                 p->err = midas_linear_combo(ret->v.xvec, list, b, k, p->dset);
6828             } else {
6829                 p->err = list_linear_combo(ret->v.xvec, list, b, p->dset);
6830             }
6831         }
6832 
6833         free(list);
6834     }
6835 
6836     return ret;
6837 }
6838 
list_list_series_func(NODE * l1,NODE * l2,int f,NODE * o,parser * p)6839 static NODE *list_list_series_func (NODE *l1, NODE *l2, int f,
6840 				    NODE *o, parser *p)
6841 {
6842     NODE *ret = aux_series_node(p);
6843 
6844     if (ret != NULL && starting(p)) {
6845 	int partial_ok = node_get_bool(o, p, 0);
6846         int *llist = node_get_list(l1, p);
6847         int *rlist = node_get_list(l2, p);
6848 
6849         if (!p->err) {
6850             p->err = x_sectional_weighted_stat(ret->v.xvec, llist, rlist,
6851                                                p->dset, f, partial_ok);
6852         }
6853         free(llist);
6854         free(rlist);
6855     }
6856 
6857     return ret;
6858 }
6859 
6860 /* check for missing obs in a list of variables */
6861 
list_ok_func(NODE * n,int f,parser * p)6862 static NODE *list_ok_func (NODE *n, int f, parser *p)
6863 {
6864     NODE *ret = aux_series_node(p);
6865 
6866     if (ret != NULL && starting(p)) {
6867         int *list = n->v.ivec;
6868         int i, vi, t;
6869         double x;
6870 
6871         if (list[0] == 0) {
6872             return ret;
6873         }
6874 
6875         for (t=p->dset->t1; t<=p->dset->t2; t++) {
6876             x = (f == F_DATAOK)? 1 : 0;
6877             for (i=1; i<=list[0]; i++) {
6878                 vi = list[i];
6879                 if (na(p->dset->Z[vi][t])) {
6880                     x = (f == F_DATAOK)? 0 : 1;
6881                     break;
6882                 }
6883             }
6884             ret->v.xvec[t] = x;
6885         }
6886     }
6887 
6888     return ret;
6889 }
6890 
6891 /* functions taking (up to) two scalars as arguments and
6892    returning a series result */
6893 
6894 static NODE *
series_fill_func(NODE * l,NODE * r,int f,parser * p)6895 series_fill_func (NODE *l, NODE *r, int f, parser *p)
6896 {
6897     NODE *ret = aux_series_node(p);
6898 
6899     if (ret != NULL && starting(p)) {
6900         double x, y;
6901 
6902         x = null_node(l) ? NADBL : node_get_scalar(l, p);
6903         y = null_node(r) ? NADBL : node_get_scalar(r, p);
6904 
6905         switch (f) {
6906         case F_RUNIFORM:
6907             p->err = gretl_rand_uniform_minmax(ret->v.xvec,
6908                                                p->dset->t1,
6909                                                p->dset->t2,
6910                                                x, y);
6911             break;
6912         case F_RNORMAL:
6913             p->err = gretl_rand_normal_full(ret->v.xvec,
6914                                             p->dset->t1,
6915                                             p->dset->t2,
6916                                             x, y);
6917             break;
6918         default:
6919             break;
6920         }
6921     }
6922 
6923     return ret;
6924 }
6925 
fc_matrix_from_list(NODE * n,int n1,parser * p)6926 static gretl_matrix *fc_matrix_from_list (NODE *n, int n1,
6927                                           parser *p)
6928 {
6929     gretl_matrix *ret = NULL;
6930 
6931     if (sample_size(p->dset) != n1) {
6932         p->err = E_NONCONF;
6933     } else {
6934         ret = gretl_matrix_data_subset(n->v.ivec,
6935                                        p->dset,
6936                                        p->dset->t1,
6937                                        p->dset->t2,
6938                                        M_MISSING_OK,
6939                                        &p->err);
6940     }
6941 
6942     return ret;
6943 }
6944 
fcstats_node(NODE * l,NODE * m,NODE * r,parser * p)6945 static NODE *fcstats_node (NODE *l, NODE *m, NODE *r, parser *p)
6946 {
6947     NODE *ret = aux_matrix_node(p);
6948 
6949     if (starting(p)) {
6950         gretl_matrix *Fmat = NULL;
6951         const double *x = NULL, *y = NULL;
6952 	gretlopt Fopt = OPT_D;
6953         int U2, free_Fmat = 0;
6954         int n = 0, n2 = 0;
6955 
6956 	if (l->t == SERIES || m->t == SERIES || m->t == LIST) {
6957 	    if (dataset_is_time_series(p->dset)) {
6958 		Fopt |= OPT_T;
6959 	    }
6960 	}
6961 	U2 = node_get_bool(r, p, (Fopt & OPT_T) ? 1 : 0);
6962 	if (U2) {
6963 	    Fopt |= OPT_T;
6964 	} else {
6965 	    Fopt &= ~OPT_T;
6966 	}
6967 
6968 	if (!p->err) {
6969 	    if (l->t == SERIES) {
6970 		n = sample_size(p->dset);
6971 		x = l->v.xvec + p->dset->t1;
6972 	    } else {
6973 		n = gretl_vector_get_length(l->v.m);
6974 		if (n == 0) {
6975 		    p->err = E_TYPES;
6976 		} else {
6977 		    x = l->v.m->val;
6978 		}
6979 	    }
6980 	}
6981 
6982         if (!p->err) {
6983             if (m->t == SERIES) {
6984 		n2 = sample_size(p->dset);
6985                 if (n2 != n) {
6986                     p->err = E_NONCONF;
6987                 } else {
6988                     y = m->v.xvec + p->dset->t1;
6989                 }
6990             } else if (m->t == MAT) {
6991                 n2 = gretl_vector_get_length(m->v.m);
6992                 if (n2 != n) {
6993                     if (m->v.m->rows == n) {
6994                         Fmat = m->v.m;
6995                     } else {
6996                         p->err = E_NONCONF;
6997                     }
6998                 } else {
6999                     y = m->v.m->val;
7000                 }
7001             } else {
7002                 Fmat = fc_matrix_from_list(m, n, p);
7003                 if (!p->err) {
7004                     free_Fmat = 1;
7005                 }
7006             }
7007 	}
7008 
7009         if (!p->err) {
7010 	    if (Fmat != NULL) {
7011 		ret->v.m = matrix_fc_stats(x, Fmat, Fopt, &p->err);
7012 	    } else {
7013 		ret->v.m = forecast_stats(x, y, 0, n-1, NULL, Fopt, &p->err);
7014 	    }
7015 	    if (free_Fmat) {
7016 		gretl_matrix_free(Fmat);
7017 	    }
7018 	}
7019     }
7020 
7021     return ret;
7022 }
7023 
7024 /* Functions taking two series as arguments and returning a scalar
7025    or matrix result. We also accept as arguments two matrices if
7026    they are vectors of the same length. In the case of F_NAALEN
7027    and F_KMEIER we can accept input with no @r node argument
7028    (meaning no censoring).
7029 */
7030 
series_2_func(NODE * l,NODE * r,int f,parser * p)7031 static NODE *series_2_func (NODE *l, NODE *r, int f, parser *p)
7032 {
7033     NODE *ret = NULL;
7034 
7035     if (starting(p)) {
7036         const double *x = NULL, *y = NULL;
7037         int n = 0, n2 = 0;
7038 
7039 	if (!p->err) {
7040 	    if (l->t == SERIES) {
7041 		n = sample_size(p->dset);
7042 		x = l->v.xvec + p->dset->t1;
7043 	    } else if (l->t == NUM) {
7044 		n = 1;
7045 		x = &l->v.xval;
7046 	    } else if (l->t == MAT) {
7047 		n = gretl_vector_get_length(l->v.m);
7048 		if (n == 0) {
7049 		    p->err = E_TYPES;
7050 		} else {
7051 		    x = l->v.m->val;
7052 		}
7053 	    } else {
7054 		p->err = E_INVARG;
7055 	    }
7056 	}
7057 
7058         if (!p->err) {
7059             if (null_node(r)) {
7060                 ; /* OK for duration funcs */
7061             } else if (r->t == SERIES) {
7062                 /* series on right */
7063                 n2 = sample_size(p->dset);
7064                 if (n2 != n) {
7065                     p->err = E_NONCONF;
7066                 } else {
7067                     y = r->v.xvec + p->dset->t1;
7068                 }
7069             } else if (r->t == NUM) {
7070                 n2 = 1;
7071                 if (n2 != n) {
7072                     p->err = E_NONCONF;
7073                 } else {
7074                     y = &r->v.xval;
7075                 }
7076             } else if (r->t == MAT) {
7077                 /* matrix on right */
7078                 n2 = gretl_vector_get_length(r->v.m);
7079                 if (n2 != n) {
7080 		    p->err = E_NONCONF;
7081 		} else {
7082                     y = r->v.m->val;
7083                 }
7084             } else {
7085                 p->err = E_TYPES;
7086             }
7087         }
7088 
7089         if (p->err) {
7090             return ret;
7091         } else if (f == F_NAALEN || f == F_KMEIER) {
7092             ret = aux_matrix_node(p);
7093         } else {
7094             ret = aux_scalar_node(p);
7095         }
7096         if (ret == NULL) {
7097             return NULL;
7098         }
7099 
7100         /* n is taken as inclusive below */
7101         n--;
7102 
7103         switch (f) {
7104         case F_COR:
7105             ret->v.xval = gretl_corr(0, n, x, y, NULL);
7106             break;
7107         case F_COV:
7108             ret->v.xval = gretl_covar(0, n, x, y, NULL);
7109             break;
7110         case F_NAALEN:
7111             ret->v.m = duration_func(x, y, 0, n, OPT_NONE, &p->err);
7112             break;
7113         case F_KMEIER:
7114             ret->v.m = duration_func(x, y, 0, n, OPT_K, &p->err);
7115             break;
7116         default:
7117             break;
7118         }
7119     } else {
7120         ret = aux_any_node(p);
7121     }
7122 
7123     return ret;
7124 }
7125 
get_npcorr_option(NODE * n,parser * p)7126 static gretlopt get_npcorr_option (NODE *n, parser *p)
7127 {
7128     gretlopt opt = OPT_NONE;
7129 
7130     if (null_node(n)) {
7131         ; /* OK */
7132     } else {
7133         /* screened already: must be string */
7134         const char *s = n->v.str;
7135 
7136         if (!strcmp(s, "kendall")) {
7137             opt = OPT_K;
7138         } else if (!strcmp(s, "spearman")) {
7139             opt = OPT_S;
7140         } else {
7141             p->err = E_INVARG;
7142         }
7143     }
7144 
7145     return opt;
7146 }
7147 
npcorr_node(NODE * l,NODE * m,NODE * r,parser * p)7148 static NODE *npcorr_node (NODE *l, NODE *m, NODE *r, parser *p)
7149 {
7150     NODE *ret = aux_matrix_node(p);
7151 
7152     if (ret != NULL && starting(p)) {
7153         const double *x = NULL, *y = NULL;
7154         gretlopt opt = OPT_NONE;
7155         int n1 = 0, n2 = 0;
7156 
7157         if (l->t == SERIES) {
7158             x = l->v.xvec + p->dset->t1;
7159             n1 = sample_size(p->dset);
7160         } else {
7161             n1 = gretl_vector_get_length(l->v.m);
7162             if (n1 == 0) {
7163                 p->err = E_INVARG;
7164             } else {
7165                 x = l->v.m->val;
7166             }
7167         }
7168 
7169         if (!p->err && m->t == SERIES) {
7170             y = m->v.xvec + p->dset->t1;
7171             n2 = sample_size(p->dset);
7172         } else if (!p->err) {
7173             n2 = gretl_vector_get_length(m->v.m);
7174             if (n2 == 0) {
7175                 p->err = E_INVARG;
7176             } else {
7177                 y = m->v.m->val;
7178             }
7179         }
7180 
7181         if (!p->err && n1 != n2) {
7182             p->err = E_NONCONF;
7183         } else if (!p->err) {
7184             opt = get_npcorr_option(r, p);
7185         }
7186 
7187         if (!p->err) {
7188             if (opt & OPT_S) {
7189                 ret->v.m = spearman_rho_func(x, y, n1, &p->err);
7190             } else {
7191                 ret->v.m = kendall_tau_func(x, y, n1, &p->err);
7192             }
7193         }
7194     }
7195 
7196     return ret;
7197 }
7198 
7199 /* takes two series or two matrices as arguments */
7200 
mxtab_func(NODE * l,NODE * r,parser * p)7201 static NODE *mxtab_func (NODE *l, NODE *r, parser *p)
7202 {
7203     NODE *ret = aux_matrix_node(p);
7204 
7205     if (ret != NULL && starting(p)) {
7206         if (l->t == MAT && r->t == MAT) {
7207             ret->v.m = matrix_matrix_xtab(l->v.m, r->v.m, &p->err);
7208         } else if (l->t == SERIES && r->t == SERIES) {
7209             const double *x = l->v.xvec;
7210             const double *y = r->v.xvec;
7211 
7212             ret->v.m = gretl_matrix_xtab(p->dset->t1, p->dset->t2,
7213                                          x, y, &p->err);
7214         } else {
7215             p->err = E_TYPES;
7216         }
7217     }
7218 
7219     return ret;
7220 }
7221 
object_status(NODE * n,NODE * func,parser * p)7222 static NODE *object_status (NODE *n, NODE *func, parser *p)
7223 {
7224     NODE *ret = aux_scalar_node(p);
7225     int f = func->t;
7226 
7227     if (ret != NULL && starting(p)) {
7228         const char *s = n->v.str;
7229 
7230         ret->v.xval = NADBL;
7231 
7232         if (f == F_ISCMPLX) {
7233             gretl_matrix *m = get_matrix_by_name(s);
7234 
7235             if (m != NULL) {
7236                 ret->v.xval = m->is_complex;
7237             }
7238         } else if (f == F_EXISTS) {
7239             GretlType type = user_var_get_type_by_name(s);
7240 
7241             if (type == 0 && gretl_is_series(s, p->dset)) {
7242                 type = GRETL_TYPE_SERIES;
7243             }
7244             if (alias_reversed(func)) {
7245                 /* handle the "isnull" alias */
7246                 ret->v.xval = (type == 0);
7247             } else {
7248                 ret->v.xval = gretl_type_get_order(type);
7249             }
7250         } else if (f == F_ISDISCR) {
7251             int v = current_series_index(p->dset, s);
7252 
7253             if (v >= 0) {
7254                 ret->v.xval = series_is_discrete(p->dset, v);
7255             }
7256         } else if (f == F_OBSNUM) {
7257             int t = get_observation_number(s, p->dset);
7258 
7259             if (t > 0) {
7260                 ret->v.xval = t;
7261             }
7262         } else if (f == F_STRLEN) {
7263             /* ret->v.xval = strlen(s); */
7264             ret->v.xval = g_utf8_strlen(s, -1);
7265         } else if (f == F_NLINES) {
7266             ret->v.xval = count_lines(s);
7267         } else if (f == F_REMOVE) {
7268             gretl_maybe_switch_dir(s);
7269             ret->v.xval = gretl_remove(s);
7270         }
7271     }
7272 
7273     return ret;
7274 }
7275 
multi_str_node(NODE * l,int f,parser * p)7276 static NODE *multi_str_node (NODE *l, int f, parser *p)
7277 {
7278     NODE *ret = NULL;
7279 
7280     if (l->t == SERIES) {
7281         if (!is_string_valued(p->dset, l->vnum)) {
7282             p->err = E_TYPES;
7283         } else {
7284             ret = aux_series_node(p);
7285         }
7286     } else if (l->t == ARRAY) {
7287         if (gretl_array_get_type(l->v.a) != GRETL_TYPE_STRINGS) {
7288             p->err = E_TYPES;
7289         } else {
7290             ret = aux_matrix_node(p);
7291         }
7292     } else {
7293         p->err = E_TYPES;
7294     }
7295 
7296     if (!p->err && l->t == SERIES) {
7297         series_table *st;
7298         const char *s;
7299         int t;
7300 
7301         st = series_get_string_table(p->dset, l->vnum);
7302         for (t=p->dset->t1; t<=p->dset->t2; t++) {
7303             s = series_table_get_string(st, l->v.xvec[t]);
7304             ret->v.xvec[t] = (s == NULL)? NADBL : g_utf8_strlen(s, -1);
7305         }
7306     } else if (!p->err) {
7307         gretl_matrix *m = NULL;
7308         char **S;
7309         int i, ns = 0;
7310 
7311         S = gretl_array_get_strings(l->v.a, &ns);
7312         m = (ns == 0)? gretl_null_matrix_new() :
7313             gretl_matrix_alloc(ns, 1);
7314         if (m == NULL) {
7315             p->err = E_ALLOC;
7316         } else {
7317             for (i=0; i<ns; i++) {
7318                 m->val[i] = g_utf8_strlen(S[i], -1);
7319             }
7320             ret->v.m = m;
7321         }
7322     }
7323 
7324     return ret;
7325 }
7326 
generic_typeof_node(NODE * n,NODE * func,parser * p)7327 static NODE *generic_typeof_node (NODE *n, NODE *func, parser *p)
7328 {
7329     NODE *ret = aux_scalar_node(p);
7330     GretlType t = GRETL_TYPE_NONE;
7331 
7332     switch (n->t) {
7333     case NUM:
7334         t = GRETL_TYPE_DOUBLE;
7335         break;
7336     case SERIES:
7337         t = GRETL_TYPE_SERIES;
7338         break;
7339     case MAT:
7340         t = GRETL_TYPE_MATRIX;
7341         break;
7342     case STR:
7343         t = GRETL_TYPE_STRING;
7344         break;
7345     case BUNDLE:
7346         t = GRETL_TYPE_BUNDLE;
7347         break;
7348     case ARRAY:
7349         t = GRETL_TYPE_ARRAY;
7350         break;
7351     case LIST:
7352         t = GRETL_TYPE_LIST;
7353         break;
7354     default:
7355         break;
7356     }
7357 
7358     if (alias_reversed(func)) {
7359         /* handle the "isnull" alias */
7360         ret->v.xval = (t == 0);
7361     } else {
7362         ret->v.xval = gretl_type_get_order(t);
7363     }
7364 
7365     return ret;
7366 }
7367 
7368 /* return scalar node holding the number of elements in
7369    the object associated with node @n
7370 */
7371 
n_elements_node(NODE * n,parser * p)7372 static NODE *n_elements_node (NODE *n, parser *p)
7373 {
7374     NODE *ret = aux_scalar_node(p);
7375 
7376     if (ret != NULL && starting(p)) {
7377         if (n->t == NUM) {
7378             ret->v.xval = 1;
7379         } else if (n->t == MAT) {
7380             gretl_matrix *m = n->v.m;
7381 
7382             ret->v.xval = m->rows * m->cols;
7383         } else if (n->t == ARRAY) {
7384             gretl_array *a = n->v.a;
7385 
7386             ret->v.xval = gretl_array_get_length(a);
7387         } else if (n->t == BUNDLE) {
7388             gretl_bundle *b = n->v.b;
7389 
7390             ret->v.xval = gretl_bundle_get_n_members(b);
7391         } else if (n->t == LIST) {
7392             int *list = n->v.ivec;
7393 
7394             ret->v.xval = list[0];
7395         } else if (n->t == STR) {
7396             int *list = get_list_by_name(n->v.str);
7397 
7398             if (list != NULL) {
7399                 /* backward compatibility (?): _name_ of list */
7400                 ret->v.xval = list[0];
7401             } else if (n->v.str != NULL) {
7402                 ret->v.xval = strlen(n->v.str);
7403             } else {
7404                 ret->v.xval = 0;
7405             }
7406         } else {
7407             p->err = E_TYPES;
7408         }
7409     }
7410 
7411     return ret;
7412 }
7413 
look_up_vname(const char * s,const DATASET * dset)7414 static int look_up_vname (const char *s, const DATASET *dset)
7415 {
7416     int i;
7417 
7418     for (i=0; i<dset->v; i++) {
7419         if (!strcmp(s, dset->varname[i])) {
7420             return i;
7421         }
7422     }
7423 
7424     return -1;
7425 }
7426 
7427 /* return scalar node holding the position of the series
7428    associated with node @r in the list associated with node
7429    @l, or zero if the series is not present in the list
7430 */
7431 
in_list_node(NODE * l,NODE * r,parser * p)7432 static NODE *in_list_node (NODE *l, NODE *r, parser *p)
7433 {
7434     NODE *ret = aux_scalar_node(p);
7435 
7436     if (p->err == 0 && (p->dset == NULL || p->dset->v == 0)) {
7437         p->err = E_NODATA;
7438     }
7439 
7440     if (ret != NULL && starting(p)) {
7441         int *list = node_get_list(l, p);
7442 
7443         if (list != NULL) {
7444             int k = -1;
7445 
7446             if (useries_node(r)) {
7447                 k = r->vnum;
7448             } else if (r->t == NUM) {
7449                 if (r->v.xval >= 0 && r->v.xval < p->dset->v) {
7450                     k = (int) r->v.xval;
7451                 }
7452             } else if (r->t == STR) {
7453                 k = look_up_vname(r->v.str, p->dset);
7454                 if (k < 0) {
7455                     ret->v.xval = 0;
7456                 }
7457             } else {
7458                 node_type_error(F_INLIST, 2, SERIES, r, p);
7459             }
7460             if (k >= 0) {
7461                 ret->v.xval = in_gretl_list(list, k);
7462             }
7463             free(list);
7464         }
7465     }
7466 
7467     return ret;
7468 }
7469 
list_info_node(NODE * l,NODE * r,parser * p)7470 static NODE *list_info_node (NODE *l, NODE *r, parser *p)
7471 {
7472     NODE *ret = aux_matrix_node(p);
7473     int k = 0;
7474 
7475     if (p->err == 0 && (p->dset == NULL || p->dset->v == 0)) {
7476         p->err = E_NODATA;
7477     }
7478 
7479     if (!p->err && !null_node(r)) {
7480         k = node_get_int(r, p);
7481     }
7482 
7483     if (!p->err) {
7484         const int *list = l->v.ivec;
7485         gretlopt opt = OPT_NONE;
7486 
7487         if (k & 1) {
7488             opt |= OPT_C;
7489         }
7490         if (k & 2) {
7491             opt |= OPT_B;
7492         }
7493         ret->v.m = list_info_matrix(list, p->dset, opt, &p->err);
7494     }
7495 
7496     return ret;
7497 }
7498 
argname_from_uvar(NODE * n,NODE * r,parser * p)7499 static NODE *argname_from_uvar (NODE *n, NODE *r, parser *p)
7500 {
7501     NODE *ret = aux_string_node(p);
7502 
7503     if (ret != NULL && starting(p)) {
7504         const char *vname = NULL;
7505 
7506         if (!null_or_string(r)) {
7507             /* if @r is present it must hold a string */
7508             p->err = E_TYPES;
7509             return ret;
7510         }
7511 
7512         if (n->t == SERIES) {
7513             vname = p->dset->varname[n->vnum];
7514         } else {
7515             vname = n->vname;
7516         }
7517 
7518         if (vname == NULL) {
7519             p->err = E_DATA;
7520         } else {
7521             ret->v.str = gretl_func_get_arg_name(vname, &p->err);
7522         }
7523 
7524         if (ret->v.str == NULL || ret->v.str[0] == '\0') {
7525             if (!null_node(r)) {
7526                 ret->v.str = gretl_strdup(r->v.str);
7527             }
7528         }
7529     }
7530 
7531     return ret;
7532 }
7533 
varnum_node(NODE * n,parser * p)7534 static NODE *varnum_node (NODE *n, parser *p)
7535 {
7536     NODE *ret = aux_scalar_node(p);
7537 
7538     if (ret != NULL && starting(p)) {
7539         if (n->t == STR) {
7540             int v = current_series_index(p->dset, n->v.str);
7541 
7542             ret->v.xval = (v >= 0)? v : NADBL;
7543         } else {
7544             p->err = E_DATA;
7545         }
7546     }
7547 
7548     return ret;
7549 }
7550 
int_to_string_func(NODE * n,int f,parser * p)7551 static NODE *int_to_string_func (NODE *n, int f, parser *p)
7552 {
7553     NODE *ret = NULL;
7554 
7555     if (starting(p)) {
7556 	gretl_matrix *v = NULL;
7557         int i = 0;
7558 
7559         if (scalar_node(n)) {
7560             i = node_get_int(n, p);
7561         } else if (n->t == SERIES && f == F_VARNAME) {
7562             i = n->vnum;
7563 	} else if (n->t == MAT && f == F_OBSLABEL) {
7564 	    v = n->v.m;
7565         } else {
7566             node_type_error(f, 0, NUM, n, p);
7567         }
7568 
7569 	if (!p->err && v != NULL) {
7570 	    ret = aux_array_node(p);
7571 	} else if (!p->err) {
7572 	    ret = aux_string_node(p);
7573 	}
7574 
7575         if (f == F_OBSLABEL && v != NULL) {
7576 	    ret->v.a = retrieve_date_strings(v, p->dset, &p->err);
7577 	} else if (f == F_OBSLABEL) {
7578             ret->v.str = retrieve_date_string(i, p->dset, &p->err);
7579         } else if (f == F_VARNAME) {
7580             if (i >= 0 && i < p->dset->v) {
7581                 ret->v.str = gretl_strdup(p->dset->varname[i]);
7582             } else {
7583                 p->err = E_INVARG;
7584             }
7585         } else {
7586             p->err = E_DATA;
7587         }
7588 
7589         if (!p->err && v == NULL && ret->v.str == NULL) {
7590             p->err = E_ALLOC;
7591         }
7592     } else {
7593 	ret = aux_any_node(p);
7594     }
7595 
7596     return ret;
7597 }
7598 
list_to_string_func(NODE * n,int f,parser * p)7599 static NODE *list_to_string_func (NODE *n, int f, parser *p)
7600 {
7601     NODE *ret;
7602 
7603     if (f == F_VARNAMES) {
7604         ret = aux_array_node(p);
7605     } else {
7606         ret = aux_string_node(p);
7607     }
7608 
7609     if (ret != NULL && starting(p)) {
7610         int *list = node_get_list(n, p);
7611 
7612         if (p->err) {
7613             return ret;
7614         }
7615 
7616         if (f == F_VARNAME) {
7617             ret->v.str = gretl_list_get_names(list, p->dset,
7618                                               &p->err);
7619         } else if (f == F_VARNAMES) {
7620             char **S = gretl_list_get_names_array(list, p->dset,
7621                                                   &p->err);
7622             int ns = list[0];
7623 
7624             if (!p->err) {
7625                 ret->v.a = gretl_array_from_strings(S, ns, 0, &p->err);
7626             }
7627         } else {
7628             p->err = E_DATA;
7629         }
7630 
7631         free(list);
7632     }
7633 
7634     return ret;
7635 }
7636 
7637 /* handles both getenv (string value of variable) and
7638    ngetenv (numerical value of variable)
7639 */
7640 
do_getenv(NODE * l,int f,parser * p)7641 static NODE *do_getenv (NODE *l, int f, parser *p)
7642 {
7643     NODE *ret = (f == F_GETENV)? aux_string_node(p) :
7644         aux_scalar_node(p);
7645 
7646     if (ret != NULL && starting(p)) {
7647         int defined = 0;
7648         char *estr;
7649 
7650         estr = gretl_getenv(l->v.str, &defined, &p->err);
7651 
7652         if (f == F_GETENV) {
7653             ret->v.str = estr;
7654         } else {
7655             /* ngetenv */
7656             if (defined) {
7657                 char *test = NULL;
7658                 double x;
7659 
7660                 errno = 0;
7661                 x = strtod(estr, &test);
7662                 if (*test == '\0' && errno == 0) {
7663                     ret->v.xval = x;
7664                 }
7665             }
7666             free(estr);
7667         }
7668     }
7669 
7670     return ret;
7671 }
7672 
7673 /* do_funcerr() is a legacy thing: remove it when possible */
7674 
do_funcerr(NODE * n,parser * p)7675 static NODE *do_funcerr (NODE *n, parser *p)
7676 {
7677     NODE *ret = aux_scalar_node(p);
7678 
7679     if (gretl_function_depth() == 0) {
7680         gretl_errmsg_set("funcerr: no function is executing");
7681         p->err = E_DATA;
7682     } else {
7683         const char *funcname = NULL;
7684 
7685         current_function_info(&funcname, NULL);
7686         gretl_errmsg_sprintf(_("Error message from %s():\n %s"),
7687                              funcname, n->v.str);
7688         p->err = E_FUNCERR;
7689     }
7690 
7691     if (ret != NULL) {
7692         ret->v.xval = 1;
7693     }
7694 
7695     return ret;
7696 }
7697 
write_mpi_errmsg(const char * funcname,const char * s)7698 static void write_mpi_errmsg (const char *funcname, const char *s)
7699 {
7700 #ifdef HAVE_MPI
7701     gchar *tmp = gretl_make_dotpath("mpi.fail");
7702     FILE *fp = gretl_fopen(tmp, "wb");
7703 
7704     if (fp != NULL) {
7705 	if (funcname != NULL) {
7706 	    fprintf(fp, _("Error message from %s():\n %s"),
7707 		    funcname, s);
7708 	    fputc('\n', fp);
7709 	} else {
7710 	    fprintf(fp, "Error message from gretlmpi: %s\n", s);
7711 	}
7712 	fclose(fp);
7713     }
7714     g_free(tmp);
7715 #else
7716     return;
7717 #endif
7718 }
7719 
do_errorif(NODE * l,NODE * r,parser * p)7720 static NODE *do_errorif (NODE *l, NODE *r, parser *p)
7721 {
7722     NODE *ret = aux_scalar_node(p);
7723     int fd = gretl_function_depth();
7724 
7725     if (fd == 0 && !gretl_mpi_initialized()) {
7726 	gretl_errmsg_sprintf("'%s': can only be used within a function",
7727 			     "errorif");
7728         p->err = E_DATA;
7729     } else {
7730         int cond = node_get_bool(l, p, -1);
7731 
7732         if (cond && !p->err) {
7733 	    const char *funcname = NULL;
7734 
7735 	    if (fd > 0) {
7736 		current_function_info(&funcname, NULL);
7737 	    }
7738 	    if (gretl_mpi_initialized()) {
7739 		write_mpi_errmsg(funcname, r->v.str);
7740 	    } else {
7741 		gretl_errmsg_sprintf(_("Error message from %s():\n %s"),
7742 				     funcname, r->v.str);
7743 	    }
7744             p->err = E_FUNCERR;
7745         }
7746     }
7747 
7748     if (ret != NULL) {
7749         ret->v.xval = 1;
7750     }
7751 
7752     return ret;
7753 }
7754 
do_assert(NODE * l,NODE * r,parser * p)7755 static NODE *do_assert (NODE *l, NODE *r, parser *p)
7756 {
7757     NODE *ret = aux_scalar_node(p);
7758     int assert_val = libset_get_int(GRETL_ASSERT);
7759 
7760     if (ret == NULL) {
7761         p->err = E_ALLOC;
7762         return NULL;
7763     }
7764 
7765     if (l->v.xval != 0 && !na(l->v.xval)) {
7766 	/* non-zero, non-missing: success */
7767 	ret->v.xval = 1;
7768     } else if (assert_val == 0) {
7769 	/* flag but ignore failure */
7770 	ret->v.xval = 0;
7771     } else if (assert_val == 1) {
7772 	/* warn about failure */
7773 	pprintf(p->prn, _("Warning: assertion '%s' failed"), r->v.str);
7774 	pputc(p->prn, '\n');
7775 	ret->v.xval = 0;
7776     } else {
7777 	/* complain and halt on failure */
7778 	p->err = 1;
7779 	gretl_errmsg_sprintf(_("Assertion '%s' failed"), r->v.str);
7780 	ret->v.xval = l->v.xval;
7781     }
7782 
7783     return ret;
7784 }
7785 
contains_node(NODE * val,NODE * set,parser * p)7786 static NODE *contains_node (NODE *val, NODE *set, parser *p)
7787 {
7788     gretl_matrix *m = set->v.m;
7789     NODE *ret = NULL;
7790 
7791     if (starting(p)) {
7792 	if (val->t == NUM) {
7793 	    ret = aux_scalar_node(p);
7794 	} else if (val->t == SERIES) {
7795 	    ret = aux_series_node(p);
7796 	} else if (val->t == MAT) {
7797 	    ret = aux_matrix_node(p);
7798 	    if (!p->err) {
7799 		int r = val->v.m->rows;
7800 		int c = val->v.m->cols;
7801 
7802 		ret->v.m = gretl_zero_matrix_new(r, c);
7803 	    }
7804 	}
7805 	if (!p->err) {
7806 	    int i, n = m->rows * m->cols;
7807 	    double x;
7808 
7809 	    if (val->t == NUM) {
7810 		x = val->v.xval;
7811 		if (na(x)) {
7812 		    ret->v.xval = NADBL;
7813 		} else {
7814 		    ret->v.xval = 0;
7815 		    for (i=0; i<n; i++) {
7816 			if (m->val[i] == x) {
7817 			    ret->v.xval = 1;
7818 			    break;
7819 			}
7820 		    }
7821 		}
7822 	    } else if (val->t == SERIES) {
7823 		int t;
7824 
7825 		for (t=p->dset->t1; t<=p->dset->t2; t++) {
7826 		    x = val->v.xvec[t];
7827 		    if (na(x)) {
7828 			ret->v.xvec[t] = NADBL;
7829 		    } else {
7830 			ret->v.xvec[t] = 0;
7831 			for (i=0; i<n; i++) {
7832 			    if (m->val[i] == x) {
7833 				ret->v.xvec[t] = 1;
7834 				break;
7835 			    }
7836 			}
7837 		    }
7838 		}
7839 	    } else if (val->t == MAT) {
7840 		gretl_matrix *v = val->v.m;
7841 		int k, nv = v->rows * v->cols;
7842 
7843 		for (k=0; k<nv; k++) {
7844 		    x = v->val[k];
7845 		    if (na(x)) {
7846 			ret->v.m->val[k] = NADBL;
7847 		    } else {
7848 			ret->v.m->val[k] = 0;
7849 			for (i=0; i<n; i++) {
7850 			    if (m->val[i] == x) {
7851 				ret->v.m->val[k] = 1;
7852 				break;
7853 			    }
7854 			}
7855 		    }
7856 		}
7857 	    }
7858 	}
7859     } else {
7860 	ret = aux_any_node(p);
7861     }
7862 
7863     return ret;
7864 }
7865 
single_string_func(NODE * n,NODE * x,int f,parser * p)7866 static NODE *single_string_func (NODE *n, NODE *x, int f, parser *p)
7867 {
7868     NODE *ret = aux_string_node(p);
7869 
7870     if (ret != NULL && starting(p)) {
7871         const char *s = n->v.str;
7872 
7873         if (f == F_ARGNAME) {
7874             char *deflt = NULL;
7875 
7876             if (!null_node(x)) {
7877                 if (x->t == STR) {
7878                     deflt = x->v.str;
7879                 } else {
7880                     p->err = E_TYPES;
7881                 }
7882             }
7883             s = (n->vname != NULL)? n->vname : s;
7884             ret->v.str = gretl_func_get_arg_name(s, &p->err);
7885             if (!p->err && ret->v.str[0] == '\0' && deflt != NULL) {
7886                 ret->v.str = gretl_strdup(deflt);
7887             }
7888         } else if (f == F_BACKTICK) {
7889             ret->v.str = gretl_backtick(s, &p->err);
7890         } else if (f == F_STRSTRIP) {
7891             ret->v.str = gretl_strstrip_copy(s, &p->err);
7892         } else if (f == F_FIXNAME) {
7893             int uscore = 0;
7894 
7895             if (!null_node(x)) {
7896                 uscore = node_get_bool(x, p, 0);
7897             }
7898             ret->v.str = calloc(VNAMELEN, 1);
7899             gretl_normalize_varname(ret->v.str, s, uscore, 0);
7900         } else {
7901             p->err = E_DATA;
7902         }
7903     }
7904 
7905     return ret;
7906 }
7907 
country_code_node(NODE * n,NODE * r,parser * p)7908 static NODE *country_code_node (NODE *n, NODE *r, parser *p)
7909 {
7910     NODE *ret = NULL;
7911     char *src = NULL;
7912     char *tmp = NULL;
7913 
7914     if (n->t == STR) {
7915         src = n->v.str;
7916         ret = aux_string_node(p);
7917     } else if (n->t == ARRAY || n->t == SERIES || n->t == MAT) {
7918         ret = aux_array_node(p);
7919     } else if (n->t == NUM) {
7920         int k = node_get_int(n, p);
7921 
7922         if (!p->err) {
7923             src = tmp = g_strdup_printf("%03d", k);
7924             ret = aux_string_node(p);
7925         }
7926     } else {
7927         p->err = E_INVARG;
7928     }
7929 
7930     if (!p->err) {
7931         int output = 0; /* default to automatic */
7932 
7933         if (!null_node(r)) {
7934             output = node_get_int(r, p);
7935         }
7936         if (!p->err && src != NULL) {
7937             char *(*cfunc) (const char *, int, PRN *, int *);
7938 
7939             cfunc = get_plugin_function("iso_country");
7940             if (cfunc == NULL) {
7941                 p->err = E_FOPEN;
7942             } else {
7943                 ret->v.str = cfunc(src, output, p->prn, &p->err);
7944             }
7945         } else if (!p->err && n->t == ARRAY) {
7946             gretl_array *(*cfunc) (gretl_array *, int, PRN *, int *);
7947 
7948             cfunc = get_plugin_function("iso_country_array");
7949             if (cfunc == NULL) {
7950                 p->err = E_FOPEN;
7951             } else {
7952                 ret->v.a = cfunc(n->v.a, output, p->prn, &p->err);
7953             }
7954         } else if (!p->err) {
7955             gretl_array *(*cfunc) (const double *, int, int, PRN *, int *);
7956 
7957             cfunc = get_plugin_function("iso_country_series");
7958             if (cfunc == NULL) {
7959                 p->err = E_FOPEN;
7960             } else {
7961                 const double *x;
7962                 int nx;
7963 
7964                 if (n->t == SERIES) {
7965                     nx = sample_size(p->dset);
7966                     x = n->v.xvec + p->dset->t1;
7967                 } else {
7968                     /* matrix */
7969                     nx = gretl_vector_get_length(n->v.m);
7970                     if (nx == 0) {
7971                         p->err = E_INVARG;
7972                     } else {
7973                         x = n->v.m->val;
7974                     }
7975                 }
7976                 if (!p->err) {
7977                     ret->v.a = cfunc(x, nx, output, p->prn, &p->err);
7978                 }
7979             }
7980         }
7981     }
7982 
7983     g_free(tmp);
7984 
7985     return ret;
7986 }
7987 
readfile_node(NODE * l,NODE * r,parser * p)7988 static NODE *readfile_node (NODE *l, NODE *r, parser *p)
7989 {
7990     NODE *ret = aux_string_node(p);
7991 
7992     if (ret != NULL && starting(p)) {
7993         const char *codeset = NULL;
7994 
7995         if (!null_node(r)) {
7996             if (r->t == STR) {
7997                 codeset = r->v.str;
7998             } else {
7999                 node_type_error(F_READFILE, 2, STR, r, p);
8000             }
8001         }
8002         if (!p->err) {
8003             ret->v.str = retrieve_file_content(l->v.str, codeset, &p->err);
8004         }
8005     }
8006 
8007     return ret;
8008 }
8009 
strstr_escape(char * s)8010 static void strstr_escape (char *s)
8011 {
8012     int i, n = strlen(s);
8013 
8014     for (i=0; i<n; i++) {
8015         if (s[i] == '\\' && (i == 0 || s[i-1] != '\\')) {
8016             if (s[i+1] == 'n') {
8017                 s[i] = '\n';
8018                 shift_string_left(s + i + 1, 1);
8019                 i++;
8020             } else if (s[i+1] == 't') {
8021                 s[i] = '\t';
8022                 shift_string_left(s + i + 1, 1);
8023                 i++;
8024             }
8025         }
8026     }
8027 }
8028 
two_string_func(NODE * l,NODE * r,NODE * x,int f,parser * p)8029 static NODE *two_string_func (NODE *l, NODE *r, NODE *x,
8030                               int f, parser *p)
8031 {
8032     NODE *ret = NULL;
8033 
8034     if (starting(p)) {
8035         const char *sl = l->v.str;
8036         const char *sr = NULL;
8037 
8038         if (f == F_JSONGETB) {
8039             ; /* checks done below */
8040         } else if (f == F_XMLGET && r->t == ARRAY) {
8041             if (gretl_array_get_type(r->v.a) != GRETL_TYPE_STRINGS) {
8042                 p->err = E_TYPES;
8043             }
8044         } else if (r->t != STR) {
8045             p->err = E_TYPES;
8046         }
8047 
8048         if (!p->err) {
8049             ret = (f == F_INSTRING)? aux_scalar_node(p) :
8050                 (f == F_JSONGETB)? aux_bundle_node(p) :
8051                 aux_string_node(p);
8052         }
8053 
8054         if (p->err) {
8055             return NULL;
8056         }
8057 
8058         if (r != NULL && r->t == STR) {
8059             sr = r->v.str;
8060         }
8061 
8062         if (f == F_STRSTR || f == F_INSTRING) {
8063             char *sret, *tmp = gretl_strdup(sr);
8064 
8065             if (tmp != NULL) {
8066                 strstr_escape(tmp);
8067                 sret = strstr(sl, tmp);
8068                 if (f == F_INSTRING) {
8069                     ret->v.xval = sret != NULL;
8070                 } else {
8071                     if (sret != NULL) {
8072                         ret->v.str = gretl_strdup(sret);
8073                     } else {
8074                         ret->v.str = gretl_strdup("");
8075                     }
8076                 }
8077                 free(tmp);
8078             }
8079         } else if (f == B_HCAT) {
8080             int n1 = strlen(l->v.str);
8081             int n2 = strlen(r->v.str);
8082 
8083             ret->v.str = malloc(n1 + n2 + 1);
8084             if (ret->v.str != NULL) {
8085                 *ret->v.str = '\0';
8086                 strcat(ret->v.str, l->v.str);
8087                 strcat(ret->v.str, r->v.str);
8088             }
8089         } else if (f == F_JSONGET) {
8090             char *(*jfunc) (const char *, const char *,
8091                             int *, int *) = NULL;
8092             user_var *uv = NULL;
8093 
8094             if (!null_node(x)) {
8095                 uv = ptr_node_get_uvar(x, NUM, p);
8096             }
8097             if (!p->err) {
8098                 jfunc = get_plugin_function("json_get_string");
8099                 if (jfunc == NULL) {
8100                     p->err = E_FOPEN;
8101                 }
8102             }
8103             if (jfunc != NULL) {
8104                 int nobj = 0;
8105                 int *pnobj = uv == NULL ? NULL : &nobj;
8106 
8107                 ret->v.str = jfunc(l->v.str, r->v.str, pnobj, &p->err);
8108                 if (!p->err && uv != NULL) {
8109                     user_var_set_scalar_value(uv, (double) *pnobj);
8110                 }
8111             }
8112         } else if (f == F_JSONGETB) {
8113             gretl_bundle *(*jfunc) (const char *, const char *, int *);
8114             const char *path = null_node(r) ? NULL: r->v.str;
8115 
8116             jfunc = get_plugin_function("json_get_bundle");
8117             if (jfunc == NULL) {
8118                 p->err = E_FOPEN;
8119             } else {
8120                 ret->v.b = jfunc(l->v.str, path, &p->err);
8121             }
8122         } else if (f == F_XMLGET) {
8123             char *(*xfunc) (const char *, void *, GretlType,
8124                             int *, int *) = NULL;
8125             user_var *uv = NULL;
8126 
8127             if (!null_node(x)) {
8128                 uv = ptr_node_get_uvar(x, NUM, p);
8129             }
8130             if (!p->err) {
8131                 xfunc = get_plugin_function("xml_get");
8132                 if (xfunc == NULL) {
8133                     p->err = E_FOPEN;
8134                 }
8135             }
8136             if (xfunc != NULL) {
8137                 int nobj = 0;
8138                 int *pnobj = uv == NULL ? NULL : &nobj;
8139 
8140                 if (r->t == ARRAY) {
8141                     ret->v.str = xfunc(l->v.str, r->v.a, GRETL_TYPE_ARRAY,
8142                                        pnobj, &p->err);
8143                 } else {
8144                     ret->v.str = xfunc(l->v.str, r->v.str, GRETL_TYPE_STRING,
8145                                        pnobj, &p->err);
8146                 }
8147                 if (!p->err && uv != NULL) {
8148                     user_var_set_scalar_value(uv, (double) *pnobj);
8149                 }
8150             }
8151         } else {
8152             p->err = E_DATA;
8153         }
8154 
8155         if (!p->err && f != F_INSTRING && ret->v.str == NULL) {
8156             p->err = E_ALLOC;
8157         }
8158     } else {
8159         ret = aux_any_node(p);
8160     }
8161 
8162     return ret;
8163 }
8164 
one_string_func(NODE * n,int f,parser * p)8165 static NODE *one_string_func (NODE *n, int f, parser *p)
8166 {
8167     NODE *ret = aux_string_node(p);
8168 
8169     if (ret != NULL && starting(p)) {
8170         char *s;
8171 
8172         if (f == F_TOLOWER) {
8173             s = ret->v.str = gretl_strdup(n->v.str);
8174             while (s && *s) {
8175                 *s = tolower(*s);
8176                 s++;
8177             }
8178         } else if (f == F_TOUPPER) {
8179             s = ret->v.str = gretl_strdup(n->v.str);
8180             while (s && *s) {
8181                 *s = toupper(*s);
8182                 s++;
8183             }
8184         } else {
8185             p->err = E_DATA;
8186         }
8187 
8188         if (!p->err && ret->v.str == NULL) {
8189             p->err = E_ALLOC;
8190         }
8191     }
8192 
8193     return ret;
8194 }
8195 
escape_strsplit_sep(const char * s)8196 static char *escape_strsplit_sep (const char *s)
8197 {
8198     char *ret = calloc(strlen(s) + 1, 1);
8199     int i = 0;
8200 
8201     while (*s) {
8202         if (*s == '\\') {
8203             if (*(s+1) == '\\') {
8204                 ret[i++] = '\\';
8205                 s++;
8206             } else if (*(s+1) == 'n') {
8207                 ret[i++] = '\n';
8208                 s++;
8209             } else if (*(s+1) == 'r') {
8210                 ret[i++] = '\r';
8211                 s++;
8212             } else if (*(s+1) == 't') {
8213                 ret[i++] = '\t';
8214                 s++;
8215             } else {
8216                 ret[i++] = *s;
8217             }
8218         } else {
8219             ret[i++] = *s;
8220         }
8221         s++;
8222     }
8223 
8224     return ret;
8225 }
8226 
strsplit_node(int f,NODE * l,NODE * m,NODE * r,parser * p)8227 static NODE *strsplit_node (int f, NODE *l, NODE *m, NODE *r, parser *p)
8228 {
8229     NODE *ret = NULL;
8230 
8231     if (starting(p)) {
8232         const char *s = l->v.str;
8233         const char *sep0 = NULL;
8234         char *sep = NULL;
8235         int k = 0;
8236 
8237         /* We'll accept the two trailing optional arguments,
8238            string separator and integer index, in either order.
8239         */
8240         if (m != NULL) {
8241             if (m->t == STR) {
8242                 sep0 = m->v.str;
8243             } else if (m->t != EMPTY) {
8244                 k = node_get_int(m, p);
8245                 if (k < 1) {
8246                     p->err = E_INVARG;
8247                 }
8248             }
8249         }
8250         if (!p->err && r != NULL) {
8251             if (r->t == STR) {
8252                 if (sep0 == NULL) {
8253                     /* OK, didn't get @sep0 yet */
8254                     sep0 = r->v.str;
8255                 } else {
8256                     p->err = E_INVARG;
8257                 }
8258             } else if (r->t != EMPTY) {
8259                 if (k == 0) {
8260                     /* OK, didn't get @k yet */
8261                     k = node_get_int(r, p);
8262                     if (k < 1) {
8263                         p->err = E_INVARG;
8264                     }
8265                 } else {
8266                     p->err = E_INVARG;
8267                 }
8268             }
8269         }
8270 
8271         if (!p->err) {
8272             ret = k > 0 ? aux_string_node(p) : aux_array_node(p);
8273         }
8274 
8275         if (!p->err) {
8276             if (sep0 == NULL) {
8277                 /* default: split on white space */
8278                 sep = gretl_strdup(" \t\r\n");
8279             } else if (strchr(sep0, '\\')) {
8280                 sep = escape_strsplit_sep(sep0);
8281             } else {
8282                 sep = gretl_strdup(sep0);
8283             }
8284         }
8285 
8286         if (!p->err) {
8287             char **S = NULL;
8288             int ns = 0;
8289 
8290             S = gretl_string_split(s, &ns, sep);
8291             if (!p->err) {
8292                 if (k > 0) {
8293                     ret->v.str = gretl_strdup(k > ns ? "" : S[k-1]);
8294                     strings_array_free(S, ns);
8295                 } else {
8296                     ret->v.a = gretl_array_from_strings(S, ns, 0, &p->err);
8297                 }
8298             }
8299         }
8300 
8301         free(sep);
8302     } else {
8303         ret = aux_any_node(p);
8304     }
8305 
8306     return ret;
8307 }
8308 
array_sort_node(NODE * n,int f,parser * p)8309 static NODE *array_sort_node (NODE *n, int f, parser *p)
8310 {
8311     NODE *ret = NULL;
8312 
8313     if (gretl_array_get_type(n->v.a) != GRETL_TYPE_STRINGS) {
8314         p->err = E_TYPES;
8315     } else {
8316         ret = aux_array_node(p);
8317         if (!p->err) {
8318             ret->v.a = gretl_strings_sort(n->v.a, f == F_DSORT, &p->err);
8319         }
8320     }
8321     return ret;
8322 }
8323 
array_func_node(NODE * l,NODE * r,int f,parser * p)8324 static NODE *array_func_node (NODE *l, NODE *r, int f, parser *p)
8325 {
8326     GretlType t = gretl_array_get_type(l->v.a);
8327     NODE *ret = NULL;
8328 
8329     if (f == F_INSTRINGS) {
8330         if (t != GRETL_TYPE_STRINGS || r->t != STR) {
8331             p->err = E_TYPES;
8332         } else {
8333             ret = aux_matrix_node(p);
8334             if (!p->err) {
8335                 ret->v.m = gretl_strings_array_pos(l->v.a, r->v.str, &p->err);
8336             }
8337         }
8338     } else if (t == GRETL_TYPE_MATRICES) {
8339         int vcat = node_get_bool(r, p, 0);
8340 
8341         if (!p->err) {
8342             ret = aux_matrix_node(p);
8343         }
8344         if (!p->err) {
8345             ret->v.m = gretl_matrix_array_flatten(l->v.a, vcat, &p->err);
8346         }
8347     } else if (t == GRETL_TYPE_STRINGS) {
8348         int space = node_get_bool(r, p, 0);
8349 
8350         if (!p->err) {
8351             ret = aux_string_node(p);
8352         }
8353         if (!p->err) {
8354             ret->v.str = gretl_strings_array_flatten(l->v.a, space, &p->err);
8355         }
8356     } else {
8357         p->err = E_TYPES;
8358     }
8359 
8360     return ret;
8361 }
8362 
errmsg_node(NODE * l,parser * p)8363 static NODE *errmsg_node (NODE *l, parser *p)
8364 {
8365     NODE *ret = aux_string_node(p);
8366 
8367     if (ret != NULL && starting(p)) {
8368         const char *src = NULL;
8369 
8370         if (null_node(l)) {
8371             src = gretl_errmsg_get();
8372         } else {
8373             int errval = node_get_int(l, p);
8374 
8375             if (errval < 0 || errval >= E_MAX) {
8376                 p->err = E_DATA;
8377             } else {
8378                 src = errmsg_get_with_default(errval);
8379             }
8380         }
8381 
8382         if (src != NULL) {
8383             ret->v.str = gretl_strdup(src);
8384             if (ret->v.str == NULL) {
8385                 p->err = E_ALLOC;
8386             }
8387         }
8388     }
8389 
8390     return ret;
8391 }
8392 
isodate_node(NODE * l,NODE * r,int f,parser * p)8393 static NODE *isodate_node (NODE *l, NODE *r, int f, parser *p)
8394 {
8395     NODE *ret = NULL;
8396 
8397     if (!scalar_node(l) && l->t != SERIES) {
8398         node_type_error(f, 1, NUM, l, p);
8399     } else if (!null_or_scalar(r)) {
8400         node_type_error(f, 2, NUM, r, p);
8401     }
8402 
8403     if (!p->err) {
8404         int julian = (f == F_JULDATE);
8405 
8406         if (scalar_node(l)) {
8407             /* epoch day node is scalar */
8408             int as_string = scalar_node(r)? node_get_int(r, p) : 0;
8409 
8410             if (!p->err) {
8411                 ret = as_string ? aux_string_node(p) : aux_scalar_node(p);
8412             }
8413             if (ret != NULL) {
8414                 double x = node_get_scalar(l, p);
8415 
8416                 if (!as_string && na(x)) {
8417                     ret->v.xval = NADBL;
8418                 } else if (x >= 1 && x <= UINT_MAX) {
8419                     if (as_string) {
8420                         ret->v.str = ymd_extended_from_epoch_day((guint32) x,
8421                                                                  julian, &p->err);
8422                     } else {
8423                         ret->v.xval = ymd_basic_from_epoch_day((guint32) x,
8424                                                                julian, &p->err);
8425                     }
8426                 } else {
8427                     p->err = E_INVARG;
8428                 }
8429             }
8430         } else {
8431             /* epoch day node is series */
8432             ret = aux_series_node(p);
8433             if (ret != NULL) {
8434                 double xt;
8435                 int t;
8436 
8437                 for (t=p->dset->t1; t<=p->dset->t2; t++) {
8438                     xt = l->v.xvec[t];
8439                     if (na(xt)) {
8440                         ret->v.xvec[t] = NADBL;
8441                     } else if (xt >= 1 && xt <= UINT_MAX) {
8442                         ret->v.xvec[t] = ymd_basic_from_epoch_day((guint32) xt,
8443                                                                   julian, &p->err);
8444                     } else {
8445                         p->err = E_INVARG;
8446                         break;
8447                     }
8448                 }
8449             }
8450         }
8451     }
8452 
8453     return ret;
8454 }
8455 
strftime_node(NODE * l,NODE * r,parser * p)8456 static NODE *strftime_node (NODE *l, NODE *r, parser *p)
8457 {
8458     NODE *ret = aux_string_node(p);
8459     const char *fmt = NULL;
8460     double tx;
8461     time_t t;
8462 
8463     if (ret == NULL) {
8464         return NULL;
8465     }
8466 
8467     /* we want a time_t compatible value from @l */
8468     tx = node_get_scalar(l, p);
8469     if (na(tx)) {
8470         p->err = E_INVARG;
8471     } else {
8472         t = (time_t) floor(tx);
8473     }
8474 
8475     /* if @r isn't empty it should hold a format string */
8476     if (r->t == STR) {
8477         fmt = r->v.str;
8478     } else if (r->t != EMPTY) {
8479         p->err = E_TYPES;
8480     }
8481 
8482     if (!p->err) {
8483         struct tm tm;
8484         char buf[64] = {0};
8485         int bytes = 0;
8486 
8487         if (fmt == NULL) {
8488             /* default to 'locale-preferred' format */
8489             fmt = "%c";
8490         }
8491 #ifdef WIN32
8492         bytes = strftime(buf, sizeof buf, fmt, localtime(&t));
8493 #else
8494         if (localtime_r(&t, &tm) == NULL) {
8495             p->err = E_INVARG;
8496         } else {
8497             bytes = strftime(buf, sizeof buf, fmt, &tm);
8498         }
8499 #endif
8500         if (bytes > 0) {
8501             ret->v.str = gretl_strdup(g_strchomp(buf));
8502         } else {
8503             ret->v.str = gretl_strdup("");
8504         }
8505     }
8506 
8507     return ret;
8508 }
8509 
strptime_node(NODE * l,NODE * r,parser * p)8510 static NODE *strptime_node (NODE *l, NODE *r, parser *p)
8511 {
8512     NODE *ret = aux_scalar_node(p);
8513     const char *fmt = NULL;
8514     const char *src = NULL;
8515     int ymd = -1;
8516 
8517     if (ret == NULL) {
8518         return NULL;
8519     }
8520 
8521     /* we want a string or YYYYMMDD integer from @l */
8522     if (l->t == STR) {
8523         src = l->v.str;
8524     } else {
8525         /* must be YYYYMMDD */
8526         ymd = node_get_int(l, p);
8527     }
8528 
8529     if (src == NULL) {
8530         /* we won't accept a format string */
8531         if (r->t != EMPTY) {
8532             p->err = E_INVARG;
8533         }
8534     } else {
8535         /* if @r isn't empty it should hold a format string */
8536         if (r->t == STR) {
8537             fmt = r->v.str;
8538         } else if (r->t != EMPTY) {
8539             p->err = E_TYPES;
8540         }
8541     }
8542 
8543     if (!p->err) {
8544         struct tm tm = {0};
8545         char *s;
8546 
8547         if (src == NULL) {
8548             /* has to be ISO 8601 basic */
8549             gchar *buf = g_strdup_printf("%d", ymd);
8550 
8551             s = strptime(buf, "%Y%m%d", &tm);
8552             g_free(buf);
8553         } else {
8554             if (fmt == NULL) {
8555                 /* default to ISO 8601 extended */
8556                 fmt = "%Y-%m-%d";
8557             }
8558             s = strptime(src, fmt, &tm);
8559         }
8560 
8561         if (s == NULL) {
8562             /* strptime() failed */
8563             p->err = E_INVARG;
8564         } else {
8565             time_t t = mktime(&tm);
8566 
8567             ret->v.xval = (double) t;
8568         }
8569     }
8570 
8571     return ret;
8572 }
8573 
atof_node(NODE * l,parser * p)8574 static NODE *atof_node (NODE *l, parser *p)
8575 {
8576     NODE *ret = NULL;
8577     char *endptr = NULL;
8578 
8579     errno = 0;
8580 
8581     if (l->t == STR) {
8582         ret = aux_scalar_node(p);
8583         if (ret != NULL && starting(p)) {
8584             gretl_push_c_numeric_locale();
8585             ret->v.xval = strtod(l->v.str, &endptr);
8586             if (errno || endptr == l->v.str) {
8587                 errno = 0;
8588                 ret->v.xval = NADBL;
8589             }
8590             gretl_pop_c_numeric_locale();
8591         }
8592     } else if (l->t == SERIES) {
8593         int v = l->vnum;
8594 
8595         if (!is_string_valued(p->dset, v)) {
8596             p->err = E_TYPES;
8597         } else {
8598             ret = aux_series_node(p);
8599         }
8600         if (ret != NULL && starting(p)) {
8601             const char *st;
8602             int t;
8603 
8604             gretl_push_c_numeric_locale();
8605             for (t=p->dset->t1; t<=p->dset->t2; t++) {
8606                 st = series_get_string_for_obs(p->dset, v, t);
8607 		if (st == NULL) {
8608 		    /* happens if obs @t is missing */
8609 		    ret->v.xvec[t] = NADBL;
8610 		} else {
8611 		    ret->v.xvec[t] = strtod(st, &endptr);
8612 		    if (errno || endptr == st) {
8613 			errno = 0;
8614 			ret->v.xvec[t] = NADBL;
8615 		    }
8616                 }
8617             }
8618             gretl_pop_c_numeric_locale();
8619         }
8620     }
8621 
8622     return ret;
8623 }
8624 
strip_newline(char * s)8625 static void strip_newline (char *s)
8626 {
8627     if (s != NULL && *s != '\0') {
8628         int i, len = strlen(s);
8629 
8630         for (i=len-1; i>=0; i--) {
8631             if (s[i] == '\n' || s[i] == '\r') {
8632                 s[i] = '\0';
8633             } else {
8634                 break;
8635             }
8636         }
8637     }
8638 }
8639 
getline_node(NODE * l,NODE * r,parser * p)8640 static NODE *getline_node (NODE *l, NODE *r, parser *p)
8641 {
8642     NODE *ret = aux_scalar_node(p);
8643 
8644     if (ret != NULL && starting(p)) {
8645         const char *buf = NULL;
8646 	NODE *rs = NULL;
8647 
8648 	if (l->vname == NULL) {
8649             gretl_errmsg_set("getline: the source must be a named string variable");
8650             p->err = E_INVARG;
8651 	} else {
8652 	    buf = l->v.str;
8653 	    if (null_node(r)) {
8654 		/* clean-up only */
8655 		bufgets_finalize(buf);
8656 		ret->v.xval = 0;
8657 		return ret;
8658 	    }
8659 	    if (r->t == STR && r->vname != NULL) {
8660 		rs = r;
8661 	    } else if (r->t == U_ADDR && r->L->t == STR) {
8662 		rs = r->L;
8663 	    } else {
8664 		gretl_errmsg_set("getline: the target must be a named string variable");
8665 		p->err = E_INVARG;
8666 	    }
8667 	}
8668 
8669 	if (!p->err) {
8670 	    p->err = query_bufgets_init(buf);
8671 	}
8672 	if (!p->err) {
8673 	    size_t len = bufgets_peek_line_length(buf);
8674 
8675 	    if (len == 0) {
8676 		bufgets_finalize(buf);
8677 		rs->v.str = user_string_reset(rs->vname, NULL, &p->err);
8678 		ret->v.xval = 0;
8679 	    } else {
8680 		rs->v.str = user_string_resize(rs->vname, len, &p->err);
8681 		if (!p->err) {
8682 		    bufgets(rs->v.str, len, buf);
8683 		    strip_newline(rs->v.str);
8684 		    ret->v.xval = 1;
8685 		}
8686 	    }
8687         }
8688     }
8689 
8690     return ret;
8691 }
8692 
series_get_start(int t1,int t2,const double * x)8693 static int series_get_start (int t1, int t2, const double *x)
8694 {
8695     int t;
8696 
8697     for (t=t1; t<=t2; t++) {
8698         if (!na(x[t])) {
8699             break;
8700         }
8701     }
8702 
8703     return t + 1;
8704 }
8705 
series_get_end(int t1,int t2,const double * x)8706 static int series_get_end (int t1, int t2, const double *x)
8707 {
8708     int t;
8709 
8710     for (t=t2; t>=t1; t--) {
8711         if (!na(x[t])) {
8712             break;
8713         }
8714     }
8715 
8716     return t + 1;
8717 }
8718 
cast_to_series(NODE * n,int f,gretl_matrix ** tmp,int * t1,int * t2,parser * p)8719 static void cast_to_series (NODE *n, int f, gretl_matrix **tmp,
8720                             int *t1, int *t2, parser *p)
8721 {
8722     gretl_matrix *m = n->v.m;
8723     int len = gretl_vector_get_length(m);
8724 
8725     if (gretl_is_null_matrix(m)) {
8726         p->err = E_DATA;
8727     } else if (m->is_complex) {
8728         node_type_error(f, 1, SERIES, n, p);
8729     } else if (len > 0 && len == p->dset->n) {
8730         *tmp = m;
8731         n->v.xvec = m->val;
8732     } else if (len > 0 && t1 != NULL && t2 != NULL) {
8733         *tmp = m;
8734         n->v.xvec = m->val;
8735         *t1 = 0;
8736         *t2 = len - 1;
8737     } else {
8738         node_type_error(f, 1, SERIES, n, p);
8739     }
8740 }
8741 
8742 /* Functions taking a series or vector as argument and returning
8743    a scalar; allowance is made for an additional boolean arg
8744    in some cases.
8745 */
8746 
series_scalar_func(NODE * n,int f,NODE * r,parser * p)8747 static NODE *series_scalar_func (NODE *n, int f,
8748                                  NODE *r, parser *p)
8749 {
8750     NODE *ret = aux_scalar_node(p);
8751 
8752     if (ret != NULL && starting(p)) {
8753         gretl_matrix *tmp = NULL;
8754         int t1 = p->dset->t1;
8755         int t2 = p->dset->t2;
8756         const double *x;
8757 
8758         if (n->t == MAT) {
8759             if (f == F_SUM || f == F_MAX || f == F_MIN) {
8760                 /* we'll sum, max, or min all elements of a matrix */
8761                 if (f == F_SUM) {
8762                     ret->v.xval = gretl_matrix_global_sum(n->v.m, &p->err);
8763                 } else {
8764                     int mm = (f == F_MAX);
8765 
8766                     ret->v.xval = gretl_matrix_global_minmax(n->v.m, mm,
8767                                                              &p->err);
8768                 }
8769                 return ret; /* handled */
8770             } else if (f == F_T1 || f == F_T2) {
8771                 cast_to_series(n, f, &tmp, NULL, NULL, p);
8772             } else {
8773                 cast_to_series(n, f, &tmp, &t1, &t2, p);
8774             }
8775             if (p->err) {
8776                 return NULL;
8777             }
8778         }
8779 
8780         if (f == F_T1 || f == F_T2) {
8781             int insample = node_get_bool(r, p, 0);
8782 
8783             if (p->err) {
8784                 return NULL;
8785             } else if (!insample) {
8786                 t1 = 0;
8787                 t2 = p->dset->n - 1;
8788             }
8789         }
8790 
8791         x = n->v.xvec;
8792 
8793         switch (f) {
8794         case F_SUM:
8795             ret->v.xval = gretl_sum(t1, t2, x);
8796             break;
8797         case F_SUMALL:
8798             ret->v.xval = series_sum_all(t1, t2, x);
8799             break;
8800         case F_MEAN:
8801             ret->v.xval = gretl_mean(t1, t2, x);
8802             break;
8803         case F_SD:
8804             ret->v.xval = gretl_stddev(t1, t2, x);
8805             break;
8806         case F_VCE:
8807             ret->v.xval = gretl_variance(t1, t2, x);
8808             break;
8809         case F_SST:
8810             ret->v.xval = gretl_sst(t1, t2, x);
8811             break;
8812         case F_SKEWNESS:
8813             ret->v.xval = gretl_skewness(t1, t2, x);
8814             break;
8815         case F_KURTOSIS:
8816             ret->v.xval = gretl_kurtosis(t1, t2, x);
8817             break;
8818         case F_MIN:
8819             ret->v.xval = gretl_min(t1, t2, x);
8820             break;
8821         case F_MAX:
8822             ret->v.xval = gretl_max(t1, t2, x);
8823             break;
8824         case F_MEDIAN:
8825             ret->v.xval = gretl_median(t1, t2, x);
8826             break;
8827         case F_GINI:
8828             ret->v.xval = gretl_gini(t1, t2, x);
8829             break;
8830         case F_NOBS:
8831             ret->v.xval = series_get_nobs(t1, t2, x);
8832             break;
8833         case F_ISCONST:
8834             ret->v.xval = gretl_isconst(t1, t2, x);
8835             break;
8836         case F_ISDUMMY:
8837             ret->v.xval = gretl_isdummy(t1, t2, x);
8838             break;
8839         case F_T1:
8840             ret->v.xval = series_get_start(t1, t2, x);
8841             break;
8842         case F_T2:
8843             ret->v.xval = series_get_end(t1, t2, x);
8844             break;
8845         default:
8846             break;
8847         }
8848 
8849         if (n->t == MAT) {
8850             n->v.m = tmp;
8851         }
8852     }
8853 
8854     return ret;
8855 }
8856 
8857 /* Functions normally taking a series or vector as argument and
8858    returning a scalar, but are evaluated on a scalar, so output is
8859    trivial.
8860 */
8861 
pretend_matrix_scalar_func(NODE * n,int f,parser * p)8862 static NODE *pretend_matrix_scalar_func (NODE *n, int f, parser *p)
8863 {
8864     NODE *ret = aux_scalar_node(p);
8865 
8866     if (ret != NULL && starting(p)) {
8867 	if (f == F_SUM || f == F_SUMALL || f == F_MEAN || f == F_MAX ||
8868 	    f == F_MIN || f == F_MEDIAN) {
8869 	    ret->v.xval = n->v.xval;
8870 	} else if (f == F_NOBS) {
8871 	    ret->v.xval = 1;
8872 	} else if (f == F_SD || f == F_VCE || f == F_SST || f == F_GINI) {
8873 	    ret->v.xval = 0;
8874 	} else if (f == F_SKEWNESS || f == F_KURTOSIS) {
8875 	    /* this is probably less intuitive than all the above:
8876 	       in "normal" cases we're returning NADBL when the variance
8877 	       is 0, so we're just being consistent here
8878 	    */
8879 	    ret->v.xval = NADBL;
8880         } else {
8881 	    /* any other cases not legit */
8882 	    node_type_error(f, 0, SERIES, n, p);
8883 	}
8884     }
8885 
8886     return ret;
8887 }
8888 
get_normtest_option(NODE * n,parser * p)8889 static gretlopt get_normtest_option (NODE *n, parser *p)
8890 {
8891     gretlopt opt = OPT_NONE;
8892 
8893     if (null_node(n)) {
8894         ; /* OK */
8895     } else if (n->t == STR) {
8896         const char *s = n->v.str;
8897 
8898         if (!strcmp(s, "swilk")) {
8899             opt = OPT_W;
8900         } else if (!strcmp(s, "lillie")) {
8901             opt = OPT_L;
8902         } else if (!strcmp(s, "jbera")) {
8903             opt = OPT_J;
8904         } else if (!strcmp(s, "dhansen")) {
8905             opt = OPT_D;
8906         } else {
8907             p->err = E_INVARG;
8908         }
8909     } else {
8910         p->err = E_TYPES;
8911     }
8912 
8913     return opt;
8914 }
8915 
series_matrix_node(NODE * l,NODE * r,int f,parser * p)8916 static NODE *series_matrix_node (NODE *l, NODE *r, int f, parser *p)
8917 {
8918     NODE *ret = NULL;
8919 
8920     if (starting(p)) {
8921         const double *x = NULL;
8922         int n = 0, t1 = 0, t2 = 0;
8923         gretlopt opt = OPT_NONE;
8924 
8925         if (f == F_NORMTEST) {
8926             opt = get_normtest_option(r, p);
8927             if (p->err) {
8928                 return NULL;
8929             }
8930         }
8931 
8932         if (l->t == MAT) {
8933             n = gretl_vector_get_length(l->v.m);
8934             if (n == 0) {
8935                 p->err = E_TYPES;
8936             } else {
8937                 x = l->v.m->val;
8938                 t2 = n - 1;
8939             }
8940         } else if (f == F_NORMTEST) {
8941             x = l->v.xvec;
8942             t1 = p->dset->t1;
8943             t2 = p->dset->t2;
8944         } else {
8945             x = l->v.xvec + p->dset->t1;
8946             n = sample_size(p->dset);
8947         }
8948 
8949         if (!p->err) {
8950             ret = aux_matrix_node(p);
8951         }
8952 
8953         if (!p->err) {
8954             if (f == F_NORMTEST) {
8955                 ret->v.m = gretl_normtest_matrix(x, t1, t2, opt, &p->err);
8956             } else {
8957                 /* F_ECDF */
8958                 ret->v.m = empirical_cdf(x, n, &p->err);
8959             }
8960         }
8961     }
8962 
8963     return ret;
8964 }
8965 
8966 /* There must be a matrix in @l; @r may hold a vector or
8967    a scalar value */
8968 
matrix_quantiles_node(NODE * l,NODE * r,parser * p)8969 static NODE *matrix_quantiles_node (NODE *l, NODE *r, parser *p)
8970 {
8971     NODE *ret = NULL;
8972 
8973     if (starting(p)) {
8974         gretl_matrix *pmat = node_get_real_matrix(r, p, 0, 0);
8975 
8976         if (!p->err) {
8977             ret = aux_matrix_node(p);
8978         }
8979         if (ret != NULL) {
8980             ret->v.m = gretl_matrix_quantiles(l->v.m, pmat, &p->err);
8981         }
8982     }
8983 
8984     return ret;
8985 }
8986 
8987 /* functions taking a series and a scalar as arguments and returning
8988    a scalar
8989 */
8990 
series_scalar_scalar_func(NODE * l,NODE * r,NODE * r2,int f,parser * p)8991 static NODE *series_scalar_scalar_func (NODE *l, NODE *r,
8992                                         NODE *r2, int f,
8993                                         parser *p)
8994 {
8995     NODE *ret = NULL;
8996 
8997     if (starting(p)) {
8998         double rval = -1;
8999         double r2val = NADBL;
9000         const double *xvec;
9001         int t1 = p->dset->t1;
9002         int t2 = p->dset->t2;
9003         int pd = 1;
9004 
9005         if (f == F_LRVAR && null_node(r)) {
9006             ; /* OK, second arg is optional */
9007         } else {
9008             rval = node_get_scalar(r, p);
9009         }
9010 
9011         if (l->t == NUM) {
9012             t1 = 0;
9013             t2 = 0;
9014             xvec = &l->v.xval;
9015         } else if (l->t == MAT) {
9016             int n = gretl_vector_get_length(l->v.m);
9017 
9018             if (n == 0) {
9019                 p->err = E_TYPES;
9020                 return NULL;
9021             }
9022             t1 = 0;
9023             t2 = n - 1;
9024             xvec = l->v.m->val;
9025         } else {
9026             /* got a series on the left */
9027             pd = p->dset->pd;
9028             xvec = l->v.xvec;
9029         }
9030 
9031         if (f == F_LRVAR && !null_node(r2)) {
9032             /* optional third arg */
9033             r2val = node_get_scalar(r2, p);
9034         }
9035 
9036         if (!p->err) {
9037             ret = aux_scalar_node(p);
9038         }
9039         if (p->err) {
9040             return ret;
9041         }
9042 
9043         switch (f) {
9044         case F_LRVAR:
9045             ret->v.xval = gretl_long_run_variance(t1, t2, xvec, (int) rval, r2val);
9046             break;
9047         case F_QUANTILE:
9048             ret->v.xval = gretl_quantile(t1, t2, xvec, rval, OPT_NONE, &p->err);
9049             break;
9050         case F_NPV:
9051             ret->v.xval = gretl_npv(t1, t2, xvec, rval, pd, &p->err);
9052             break;
9053         case F_ISCONST:
9054             ret->v.xval = panel_isconst(t1, t2, pd, xvec, (int) rval);
9055             break;
9056         default:
9057             break;
9058         }
9059 
9060     } else {
9061         ret = aux_any_node(p);
9062     }
9063 
9064     return ret;
9065 }
9066 
isconst_or_dum_node(NODE * l,NODE * r,parser * p,int f)9067 static NODE *isconst_or_dum_node (NODE *l, NODE *r, parser *p, int f)
9068 {
9069     if (f == F_ISDUMMY || null_node(r)) {
9070         return series_scalar_func(l, f, NULL, p);
9071     } else if (l->t == MAT) {
9072         node_type_error(f, 1, SERIES, l, p);
9073         return NULL;
9074     } else if (!dataset_is_panel(p->dset)) {
9075         p->err = E_PDWRONG;
9076         return NULL;
9077     } else {
9078         return series_scalar_scalar_func(l, r, NULL, f, p);
9079     }
9080 }
9081 
9082 /* Series on left, scalar or string on right, as in
9083    x[23] or somevar["CA"]. We return the selected
9084    scalar value from the series -- unless the series
9085    is string-valued, in which case we return the
9086    string value for the given observation.
9087 */
9088 
series_obs(NODE * l,NODE * r,parser * p)9089 static NODE *series_obs (NODE *l, NODE *r, parser *p)
9090 {
9091     int strval = stringvec_node(l);
9092     NODE *ret;
9093 
9094     ret = strval ? aux_string_node(p) : aux_scalar_node(p);
9095 
9096     if (ret != NULL) {
9097         int t = -1; /* invalid */
9098 
9099         if (r->t == STR) {
9100             t = dateton(r->v.str, p->dset);
9101             if (t < 0) {
9102                 if (dataset_has_markers(p->dset)) {
9103                     gretl_errmsg_sprintf_replace(_("Invalid observation specifier \"%s\""),
9104                                                  r->v.str);
9105                 }
9106                 p->err = E_DATA;
9107             }
9108         } else {
9109             /* plain integer */
9110             t = node_get_int(r, p);
9111             if (!p->err) {
9112                 if (t > 0 && t <= p->dset->n) {
9113                     t--; /* OK, convert to zero based */
9114                 } else {
9115                     gretl_errmsg_sprintf(_("Index value %d is out of bounds"), t);
9116                     p->err = E_DATA;
9117                 }
9118             }
9119         }
9120 
9121         if (!p->err) {
9122             if (strval) {
9123                 const char *s =
9124                     series_get_string_for_obs(p->dset, l->vnum, t);
9125 
9126 		if (s == NULL) {
9127 		    ret->v.str = gretl_strdup("");
9128 		} else {
9129 		    ret->v.str = gretl_strdup(s);
9130 		}
9131             } else {
9132                 ret->v.xval = l->v.xvec[t];
9133             }
9134         }
9135     }
9136 
9137     return ret;
9138 }
9139 
series_ljung_box(NODE * l,NODE * r,parser * p)9140 static NODE *series_ljung_box (NODE *l, NODE *r, parser *p)
9141 {
9142     NODE *ret = aux_scalar_node(p);
9143 
9144     if (ret != NULL && starting(p)) {
9145         const double *x = l->v.xvec;
9146         int k = node_get_int(r, p);
9147         int t1 = p->dset->t1;
9148         int t2 = p->dset->t2;
9149 
9150         if (!p->err && k <= 0) {
9151             gretl_errmsg_sprintf(_("Invalid lag order %d"), k);
9152             p->err = E_DATA;
9153         }
9154 
9155         if (!p->err) {
9156             p->err = series_adjust_sample(x, &t1, &t2);
9157         }
9158 
9159         if (!p->err) {
9160             ret->v.xval = ljung_box(k, t1, t2, x, &p->err);
9161         }
9162     }
9163 
9164     return ret;
9165 }
9166 
series_polyfit(NODE * l,NODE * r,parser * p)9167 static NODE *series_polyfit (NODE *l, NODE *r, parser *p)
9168 {
9169     NODE *ret = aux_series_node(p);
9170 
9171     if (ret != NULL && starting(p)) {
9172         const double *x = l->v.xvec;
9173         int order = node_get_int(r, p);
9174 
9175         if (!p->err) {
9176             p->err = poly_trend(x, ret->v.xvec, p->dset, order);
9177         }
9178     }
9179 
9180     return ret;
9181 }
9182 
series_lag(NODE * l,NODE * r,parser * p)9183 static NODE *series_lag (NODE *l, NODE *r, parser *p)
9184 {
9185     NODE *ret = NULL;
9186     const double *x = l->v.xvec;
9187     int k = -(node_get_int(r, p));
9188     int t1, t2;
9189 
9190     if (!p->err && l->vnum == 0) {
9191         gretl_errmsg_set(_("The constant cannot be lagged"));
9192         p->err = E_TYPES;
9193     }
9194 
9195     if (!p->err) {
9196         ret = aux_series_node(p);
9197     }
9198 
9199     if (ret == NULL) {
9200         return NULL;
9201     }
9202 
9203     t1 = autoreg(p) ? p->obs : p->dset->t1;
9204     t2 = autoreg(p) ? p->obs : p->dset->t2;
9205 
9206     lag_calc(ret->v.xvec, x, k, t1, t2, B_ASN, 1.0, p);
9207 
9208     return ret;
9209 }
9210 
series_sort_by(NODE * l,NODE * r,parser * p)9211 static NODE *series_sort_by (NODE *l, NODE *r, parser *p)
9212 {
9213     NODE *ret = aux_series_node(p);
9214 
9215     if (ret != NULL && starting(p)) {
9216         if (l->t == SERIES && r->t == SERIES) {
9217             p->err = gretl_sort_by(l->v.xvec, r->v.xvec, ret->v.xvec, p->dset);
9218         } else {
9219             p->err = E_TYPES;
9220         }
9221     }
9222 
9223     return ret;
9224 }
9225 
vector_sort(NODE * l,int f,parser * p)9226 static NODE *vector_sort (NODE *l, int f, parser *p)
9227 {
9228     NODE *ret = (l->t == SERIES)? aux_series_node(p) :
9229         aux_matrix_node(p);
9230 
9231     if (ret != NULL && starting(p)) {
9232         if (l->t == SERIES) {
9233             p->err = sort_series(l->v.xvec, ret->v.xvec, f, p->dset);
9234         } else if (l->t == NUM) {
9235             ret->v.m = gretl_matrix_from_scalar(l->v.xval);
9236         } else if (gretl_is_null_matrix(l->v.m)) {
9237             ret->v.m = gretl_null_matrix_new();
9238         } else if (l->v.m->is_complex) {
9239             p->err = E_CMPLX;
9240         } else {
9241             int descending = (f == F_DSORT);
9242 
9243             ret->v.m = gretl_vector_sort(l->v.m, descending, &p->err);
9244         }
9245     }
9246 
9247     return ret;
9248 }
9249 
vector_values(NODE * l,int f,parser * p)9250 static NODE *vector_values (NODE *l, int f, parser *p)
9251 {
9252     NODE *ret = aux_matrix_node(p);
9253 
9254     if (ret != NULL && starting(p)) {
9255         const double *x = NULL;
9256         int n = 0;
9257 
9258         if (l->t == NUM) {
9259             n = 1;
9260             x = &l->v.xval;
9261         } else if (l->t == SERIES) {
9262             n = sample_size(p->dset);
9263             x = l->v.xvec + p->dset->t1;
9264         } else if (gretl_is_null_matrix(l->v.m)) {
9265             ret->v.m = gretl_null_matrix_new();
9266         } else {
9267             n = gretl_vector_get_length(l->v.m);
9268             x = l->v.m->val;
9269         }
9270 
9271         if (n > 0 && x != NULL) {
9272             gretlopt opt = (f == F_VALUES)? OPT_S : OPT_NONE;
9273 
9274             ret->v.m = gretl_matrix_values(x, n, opt, &p->err);
9275         } else if (ret->v.m == NULL) {
9276             p->err = E_DATA;
9277         }
9278     }
9279 
9280     return ret;
9281 }
9282 
do_irr(NODE * l,parser * p)9283 static NODE *do_irr (NODE *l, parser *p)
9284 {
9285     NODE *ret = aux_scalar_node(p);
9286 
9287     if (ret != NULL && starting(p)) {
9288         const double *x = NULL;
9289         int pd = 1, n = 0;
9290 
9291         if (l->t == NUM) {
9292             n = 1;
9293             x = &l->v.xval;
9294         } else if (l->t == SERIES) {
9295             n = sample_size(p->dset);
9296             x = l->v.xvec + p->dset->t1;
9297             pd = p->dset->pd;
9298         } else if (!gretl_is_null_matrix(l->v.m)) {
9299             n = gretl_vector_get_length(l->v.m);
9300             x = l->v.m->val;
9301         }
9302 
9303         if (n > 0 && x != NULL) {
9304             ret->v.xval = gretl_irr(x, n, pd, &p->err);
9305         } else {
9306             p->err = E_DATA;
9307         }
9308     }
9309 
9310     return ret;
9311 }
9312 
9313 /* Takes a series as argument and returns a matrix:
9314    right now only F_FREQ does this
9315 */
9316 
series_matrix_func(NODE * n,int f,parser * p)9317 static NODE *series_matrix_func (NODE *n, int f, parser *p)
9318 {
9319     NODE *ret = aux_matrix_node(p);
9320 
9321     if (ret != NULL) {
9322         gretl_matrix *tmp = NULL;
9323         int t1 = p->dset->t1;
9324         int t2 = p->dset->t2;
9325 
9326         if (n->t == MAT) {
9327             cast_to_series(n, f, &tmp, &t1, &t2, p);
9328         }
9329 
9330         if (!p->err) {
9331             ret->v.m = freqdist_matrix(n->v.xvec, t1, t2, &p->err);
9332             if (n->t == MAT) {
9333                 /* restore matrix on @n after "cast" above */
9334                 n->v.m = tmp;
9335             }
9336         }
9337     }
9338 
9339     return ret;
9340 }
9341 
get_logtrans(const char * s)9342 static int get_logtrans (const char *s)
9343 {
9344     if (s != NULL) {
9345         if (*s != 'T' && strchr(s, 'l')) {
9346             return 1;
9347         }
9348     }
9349 
9350     return 0;
9351 }
9352 
9353 #define use_tramo(s) (s != NULL && (s[0] == 't' || s[0] == 'T'))
9354 
9355 #define is_panel_stat(f) (f == F_PNOBS || \
9356                           f == F_PMIN ||  \
9357                           f == F_PMAX ||  \
9358                           f == F_PSUM || \
9359                           f == F_PMEAN || \
9360                           f == F_PXSUM ||  \
9361                           f == F_PXNOBS ||  \
9362                           f == F_PSD)
9363 
9364 /* Functions taking a series as argument and returning a series.
9365    Note that the 'r' node may contain an auxiliary parameter;
9366    in that case the aux value should be a scalar, unless
9367    we're doing F_DESEAS, in which case it should be a string,
9368    or one of the panel stats functions, in which case it should
9369    be a series.
9370 */
9371 
series_series_func(NODE * l,NODE * r,NODE * o,int f,parser * p)9372 static NODE *series_series_func (NODE *l, NODE *r, NODE *o,
9373                                  int f, parser *p)
9374 {
9375     NODE *ret = NULL;
9376     int rtype = NUM; /* the optional right-node type */
9377 
9378     if (f == F_SDIFF && !dataset_is_seasonal(p->dset)) {
9379         p->err = E_PDWRONG;
9380         return NULL;
9381     }
9382 
9383     if (f == F_DESEAS) {
9384         rtype = STR;
9385     } else if (is_panel_stat(f)) {
9386         rtype = SERIES;
9387     }
9388 
9389     if (null_node(r)) {
9390         rtype = 0; /* not present, OK */
9391     } else if (rtype == NUM) {
9392         if (!scalar_node(r)) {
9393             node_type_error(f, 2, rtype, r, p);
9394             return NULL;
9395         }
9396     } else if (r->t != rtype) {
9397         node_type_error(f, 2, rtype, r, p);
9398         return NULL;
9399     }
9400 
9401     if (l->t == MAT && f == F_BOXCOX) {
9402         /* Do all columns of matrix input: this could
9403            be generalized to some other functions?
9404         */
9405         double d = node_get_scalar(r, p);
9406 
9407         if (!p->err) {
9408             ret = aux_matrix_node(p);
9409         }
9410         if (!p->err) {
9411             ret->v.m = boxcox_matrix(l->v.m, d, &p->err);
9412         }
9413         return ret;
9414     }
9415 
9416     ret = aux_series_node(p);
9417 
9418     if (ret != NULL) {
9419         gretl_matrix *tmp = NULL;
9420         double parm = NADBL;
9421         const double *z = NULL;
9422         const double *x;
9423         double *y;
9424 
9425         if (l->t == MAT) {
9426             cast_to_series(l, f, &tmp, NULL, NULL, p);
9427         }
9428 
9429         if (rtype == SERIES) {
9430             z = r->v.xvec;
9431         } else if (rtype == NUM) {
9432             parm = node_get_scalar(r, p);
9433         }
9434 
9435         if (p->err) {
9436             return NULL;
9437         }
9438 
9439         x = l->v.xvec;
9440         y = ret->v.xvec;
9441 
9442         switch (f) {
9443         case F_HPFILT:
9444             {
9445                 int oneside = node_get_bool(o, p, 0);
9446 
9447                 if (!p->err && oneside) {
9448                     p->err = oshp_filter(x, y, p->dset, parm, OPT_NONE);
9449                 } else if (!p->err) {
9450                     p->err = hp_filter(x, y, p->dset, parm, OPT_NONE);
9451                 }
9452             }
9453             break;
9454         case F_FRACDIFF:
9455             p->err = fracdiff_series(x, y, parm, 1, autoreg(p) ? p->obs : -1, p->dset);
9456             break;
9457         case F_FRACLAG:
9458             p->err = fracdiff_series(x, y, parm, 0, autoreg(p) ? p->obs : -1, p->dset);
9459             break;
9460         case F_BOXCOX:
9461             p->err = boxcox_series(x, y, parm, p->dset);
9462             break;
9463         case F_DIFF:
9464         case F_LDIFF:
9465         case F_SDIFF:
9466             p->err = diff_series(x, y, f, p->dset);
9467             break;
9468         case F_ODEV:
9469             p->err = orthdev_series(x, y, p->dset);
9470             break;
9471         case F_CUM:
9472             p->err = cum_series(x, y, p->dset);
9473             break;
9474         case F_DESEAS:
9475             if (rtype == STR) {
9476                 int tramo = use_tramo(r->v.str);
9477                 int logt = get_logtrans(r->v.str);
9478 
9479                 p->err = seasonally_adjust_series(x, y, p->dset, tramo, logt);
9480             } else {
9481                 p->err = seasonally_adjust_series(x, y, p->dset, 0, 0);
9482             }
9483             break;
9484         case F_TRAMOLIN:
9485             p->err = tramo_linearize_series(x, y, p->dset);
9486             break;
9487         case F_RESAMPLE:
9488             if (rtype == NUM) {
9489                 p->err = block_resample_series(x, y, parm, p->dset);
9490             } else {
9491                 p->err = resample_series(x, y, p->dset);
9492             }
9493             break;
9494         case F_PNOBS:
9495         case F_PMIN:
9496         case F_PMAX:
9497         case F_PSUM:
9498         case F_PMEAN:
9499         case F_PXSUM:
9500         case F_PXNOBS:
9501         case F_PSD:
9502             p->err = panel_statistic(x, y, p->dset, f, z);
9503             break;
9504         case F_RANKING:
9505             p->err = rank_series(x, y, F_SORT, p->dset);
9506             break;
9507         default:
9508             break;
9509         }
9510 
9511         if (l->t == MAT) {
9512             l->v.m = tmp;
9513         }
9514     }
9515 
9516     return ret;
9517 }
9518 
do_panel_shrink(NODE * l,int noskip,parser * p)9519 static NODE *do_panel_shrink (NODE *l, int noskip, parser *p)
9520 {
9521     NODE *ret = aux_matrix_node(p);
9522 
9523     if (ret != NULL && starting(p)) {
9524         ret->v.m = panel_shrink(l->v.xvec, noskip, p->dset, &p->err);
9525     }
9526 
9527     return ret;
9528 }
9529 
do_panel_expand(NODE * l,parser * p)9530 static NODE *do_panel_expand (NODE *l, parser *p)
9531 {
9532     NODE *ret = aux_series_node(p);
9533 
9534     if (ret != NULL && starting(p)) {
9535         p->err = panel_expand(l->v.m, ret->v.xvec, OPT_NONE, p->dset);
9536     }
9537 
9538     return ret;
9539 }
9540 
9541 /* pergm function takes series or column vector arg, returns matrix:
9542    if we come up with more functions on that pattern, the following
9543    could be extended
9544 */
9545 
pergm_node(NODE * l,NODE * r,parser * p)9546 static NODE *pergm_node (NODE *l, NODE *r, parser *p)
9547 {
9548     NODE *ret = NULL;
9549 
9550     if (!null_or_scalar(r)) {
9551         /* optional 'r' node must be scalar */
9552         node_type_error(F_PERGM, 2, NUM, r, p);
9553     } else if (l->t == MAT && gretl_vector_get_length(l->v.m) == 0) {
9554         /* if 'l' node is not a series, must be a vector */
9555         node_type_error(F_PERGM, 1, SERIES, l, p);
9556     } else {
9557         ret = aux_matrix_node(p);
9558     }
9559 
9560     if (!p->err) {
9561         const double *x = NULL;
9562         int t1 = 0, t2 = 0;
9563         int width = -1;
9564 
9565         if (l->t == SERIES) {
9566             x = l->v.xvec;
9567             t1 = p->dset->t1;
9568             t2 = p->dset->t2;
9569         } else if (l->t == MAT) {
9570             x = l->v.m->val;
9571             t1 = 0;
9572             t2 = gretl_vector_get_length(l->v.m) - 1;
9573         }
9574 
9575         if (!null_node(r)) {
9576             width = node_get_int(r, p);
9577         }
9578 
9579         if (!p->err) {
9580             ret->v.m = periodogram_matrix(x, t1, t2, width, &p->err);
9581         }
9582     }
9583 
9584     return ret;
9585 }
9586 
get_complex_counterpart(void * func)9587 static void *get_complex_counterpart (void *func)
9588 {
9589     if (func == acos) return cacos;
9590     if (func == asin) return casin;
9591     if (func == atan) return catan;
9592     if (func == cos) return ccos;
9593     if (func == sin) return csin;
9594     if (func == tan) return ctan;
9595     if (func == acosh) return cacosh;
9596     if (func == asinh) return casinh;
9597     if (func == atanh) return catanh;
9598     if (func == cosh) return ccosh;
9599     if (func == sinh) return csinh;
9600     if (func == tanh) return ctanh;
9601     if (func == exp)  return cexp;
9602     if (func == log)  return clog;
9603     if (func == sqrt) return csqrt;
9604 
9605     return NULL;
9606 }
9607 
9608 #define cmplx_to_double(f) (f == F_CARG || f == F_CMOD || \
9609                             f == F_REAL || f == F_IMAG || \
9610                             f == F_ABS)
9611 
9612 /* application of scalar function to each element of matrix */
9613 
apply_matrix_func(NODE * t,NODE * f,parser * p)9614 static NODE *apply_matrix_func (NODE *t, NODE *f, parser *p)
9615 {
9616     const gretl_matrix *m = t->v.m;
9617     int ret_complex = m->is_complex;
9618     NODE *ret;
9619 
9620     if (m->is_complex && cmplx_to_double(f->t)) {
9621         ret_complex = 0;
9622     }
9623 
9624     ret = aux_sized_matrix_node(p, m->rows, m->cols, ret_complex);
9625     if (ret == NULL) {
9626         return ret;
9627     }
9628 
9629     if (m->is_complex) {
9630         if (f->t == F_ABS) {
9631             apply_cmatrix_dfunc(ret->v.m, m, cabs);
9632         } else if (!ret_complex) {
9633             apply_cmatrix_dfunc(ret->v.m, m, f->v.ptr);
9634         } else if (f->t == F_CONJ) {
9635             apply_cmatrix_cfunc(ret->v.m, m, conj);
9636         } else if (f->t == U_NEG || f->t == U_POS || f->t == U_NOT) {
9637             apply_cmatrix_unary_op(ret->v.m, m, f->t);
9638         } else {
9639             double complex (*cfunc) (double complex) = NULL;
9640 
9641             if (f->v.ptr != NULL) {
9642                 cfunc = get_complex_counterpart(f->v.ptr);
9643             }
9644             if (cfunc == NULL) {
9645                 /* gatekeeper for complex */
9646                 p->err = function_real_only(f->t);
9647             } else {
9648                 p->err = apply_cmatrix_cfunc(ret->v.m, m, cfunc);
9649             }
9650         }
9651     } else if (f->t == F_REAL || f->t == F_IMAG) {
9652         if (f->t == F_REAL) {
9653             size_t msize = m->rows * m->cols * sizeof(double);
9654 
9655             memcpy(ret->v.m->val, m->val, msize);
9656         } else {
9657             int i, n = m->rows * m->cols;
9658 
9659             for (i=0; i<n; i++) {
9660                 ret->v.m->val[i] = 0;
9661             }
9662         }
9663     } else {
9664         double (*dfunc) (double) = f->v.ptr;
9665         int i, n = m->rows * m->cols;
9666 
9667         if (dfunc != NULL) {
9668             for (i=0; i<n && !p->err; i++) {
9669                 ret->v.m->val[i] = dfunc(m->val[i]);
9670             }
9671         } else {
9672             for (i=0; i<n && !p->err; i++) {
9673                 ret->v.m->val[i] = real_apply_func(m->val[i], f->t, p);
9674             }
9675         }
9676     }
9677 
9678     return ret;
9679 }
9680 
matrix_from_scalars(GPtrArray * a,int m,int nsep,int seppos,parser * p)9681 static gretl_matrix *matrix_from_scalars (GPtrArray *a, int m,
9682                                           int nsep, int seppos,
9683                                           parser *p)
9684 {
9685     gretl_matrix *M;
9686     NODE *n;
9687     int r = nsep + 1;
9688     int c = (seppos > 0)? seppos : m;
9689     int nelem = m - nsep;
9690     double x;
9691     int i, j, k;
9692 
9693     /* check that all rows are the same length */
9694 
9695     if (nelem != r * c) {
9696         p->err = E_PARSE;
9697     } else if (nsep > 0) {
9698         k = 0;
9699         for (i=0; i<m; i++) {
9700             n = g_ptr_array_index(a, i);
9701             if (null_node(n)) {
9702                 if (i - k != seppos) {
9703                     p->err = E_PARSE;
9704                     break;
9705                 }
9706                 k = i + 1;
9707             }
9708         }
9709     }
9710 
9711     if (p->err) {
9712         pprintf(p->prn, _("Matrix specification is not coherent"));
9713         pputc(p->prn, '\n');
9714         return NULL;
9715     }
9716 
9717 #if EDEBUG
9718     fprintf(stderr, "matrix_from_scalars: m=%d, nsep=%d, seppos=%d, nelem=%d\n",
9719             m, nsep, seppos, nelem);
9720 #endif
9721 
9722     M = gretl_matrix_alloc(r, c);
9723     if (M == NULL) {
9724         p->err = E_ALLOC;
9725     } else {
9726         k = 0;
9727         for (i=0; i<r && !p->err; i++) {
9728             for (j=0; j<c; j++) {
9729                 n = g_ptr_array_index(a, k++);
9730                 if (null_node(n)) {
9731                     n = g_ptr_array_index(a, k++);
9732                 }
9733                 x = node_get_scalar(n, p);
9734                 gretl_matrix_set(M, i, j, x);
9735             }
9736         }
9737     }
9738 
9739     return M;
9740 }
9741 
full_series_list(const DATASET * dset,int * err)9742 static int *full_series_list (const DATASET *dset, int *err)
9743 {
9744     int *list = NULL;
9745 
9746     if (dset->v < 2) {
9747         *err = E_DATA;
9748         return NULL;
9749     }
9750 
9751     list = gretl_consecutive_list_new(1, dset->v - 1);
9752     if (list == NULL) {
9753         *err = E_ALLOC;
9754         return NULL;
9755     }
9756 
9757     return list;
9758 }
9759 
real_matrix_from_list(const int * list,const DATASET * dset,parser * p)9760 static gretl_matrix *real_matrix_from_list (const int *list,
9761                                             const DATASET *dset,
9762                                             parser *p)
9763 {
9764     gretl_matrix *M = NULL;
9765 
9766     if (list != NULL && list[0] == 0) {
9767         M = gretl_null_matrix_new();
9768     } else {
9769         const gretl_matrix *mmask = get_matrix_mask();
9770 
9771         if (mmask != NULL) {
9772             M = gretl_matrix_data_subset_special(list, dset,
9773                                                  mmask, &p->err);
9774         } else {
9775             int missop = M_MISSING_OK;
9776 
9777             if (libset_get_bool(SKIP_MISSING)) {
9778                 missop = M_MISSING_SKIP;
9779             }
9780             M = gretl_matrix_data_subset(list, dset, dset->t1, dset->t2,
9781                                          missop, &p->err);
9782         }
9783     }
9784 
9785     return M;
9786 }
9787 
matrix_from_list(NODE * n,parser * p)9788 static gretl_matrix *matrix_from_list (NODE *n, parser *p)
9789 {
9790     gretl_matrix *M = NULL;
9791     int *list = NULL;
9792     int freelist = 0;
9793 
9794     if (n != NULL) {
9795         if (n->t == LIST) {
9796             list = n->v.ivec;
9797         } else {
9798             p->err = E_DATA;
9799         }
9800     } else {
9801         list = full_series_list(p->dset, &p->err);
9802         freelist = 1;
9803     }
9804 
9805     if (!p->err) {
9806         M = real_matrix_from_list(list, p->dset, p);
9807     }
9808 
9809     if (freelist) {
9810         free(list);
9811     }
9812 
9813     return M;
9814 }
9815 
arg_get_data(NODE * n,int ref,GretlType * type,user_var ** puv)9816 static void *arg_get_data (NODE *n, int ref, GretlType *type,
9817                            user_var **puv)
9818 {
9819     void *data = NULL;
9820 
9821     *puv = n->uv;
9822 
9823     if (n->t == SERIES) {
9824         if (ref) {
9825             *type = GRETL_TYPE_SERIES_REF;
9826             data = &n->vnum;
9827         } else if (n->vname != NULL) {
9828             /* FIXME conditionality here? */
9829             *type = GRETL_TYPE_USERIES;
9830             data = &n->vnum;
9831         } else {
9832             *type = GRETL_TYPE_SERIES;
9833             data = n->v.xvec;
9834         }
9835     } else if (n->t == NUM) {
9836         *type = ref ? GRETL_TYPE_SCALAR_REF : GRETL_TYPE_DOUBLE;
9837         data = &n->v.xval;
9838     } else if (n->t == MAT) {
9839         *type = ref ? GRETL_TYPE_MATRIX_REF : GRETL_TYPE_MATRIX;
9840         data = n->v.m;
9841     } else if (n->t == BUNDLE) {
9842         *type = ref ? GRETL_TYPE_BUNDLE_REF : GRETL_TYPE_BUNDLE;
9843         data = n->v.b;
9844     } else if (n->t == ARRAY) {
9845         *type = ref ? GRETL_TYPE_ARRAY_REF : GRETL_TYPE_ARRAY;
9846         data = n->v.a;
9847     } else if (n->t == STR) {
9848         *type = ref ? GRETL_TYPE_STRING_REF : GRETL_TYPE_STRING;
9849         data = n->v.str;
9850     } else if (n->t == LIST) {
9851         *type = GRETL_TYPE_LIST;
9852         data = n->v.ivec;
9853     } else if (n->t == SUB_ADDR) {
9854         data = sub_addr_get_data(n, type, puv);
9855     } else {
9856         *type = GRETL_TYPE_NONE;
9857     }
9858 
9859     return data;
9860 }
9861 
suitable_ufunc_ret_node(parser * p,GretlType t)9862 static NODE *suitable_ufunc_ret_node (parser *p,
9863                                       GretlType t)
9864 {
9865     if (t == GRETL_TYPE_DOUBLE) {
9866         return aux_scalar_node(p);
9867     } else if (t == GRETL_TYPE_SERIES) {
9868         return aux_empty_series_node(p);
9869     } else if (t == GRETL_TYPE_MATRIX) {
9870         return aux_matrix_node(p);
9871     } else if (t == GRETL_TYPE_LIST) {
9872         return aux_list_node(p);
9873     } else if (t == GRETL_TYPE_STRING) {
9874         return aux_string_node(p);
9875     } else if (t == GRETL_TYPE_BUNDLE) {
9876         return aux_bundle_node(p);
9877     } else if (gretl_array_type(t)) {
9878         return aux_array_node(p);
9879     } else {
9880         p->err = E_TYPES;
9881         return NULL;
9882     }
9883 }
9884 
9885 #define ok_ufunc_sym(s) (s == NUM || s == SERIES || s == MAT || \
9886                          s == LIST || s == U_ADDR || s == DUM || \
9887                          s == STR || s == EMPTY || s == BUNDLE || \
9888                          s == ARRAY || s == SUB_ADDR)
9889 
9890 /* evaluate a user-defined function */
9891 
eval_ufunc(NODE * t,parser * p,NODE * rn)9892 static NODE *eval_ufunc (NODE *t, parser *p, NODE *rn)
9893 {
9894     NODE *l = t->L;
9895     NODE *r = t->R;
9896     NODE *save_aux = p->aux;
9897     NODE *ret = NULL;
9898     const char *funname = l->vname;
9899     ufunc *uf = l->v.ptr;
9900     fncall *fc = NULL;
9901     GretlType rtype = 0;
9902     int i, nparam, argc = 0;
9903 
9904     rtype = user_func_get_return_type(uf);
9905 
9906     if (!p->err && rtype == GRETL_TYPE_VOID) {
9907         if (p->targ == UNK && p->lh.name[0] == '\0' && p->lh.expr == NULL) {
9908             /* never reached? */
9909             p->targ = EMPTY;
9910         } else if (p->targ != EMPTY) {
9911             gretl_errmsg_sprintf(_("The function %s does not return any value"),
9912                                  funname);
9913             p->err = E_TYPES;
9914         }
9915     }
9916 
9917     if (!p->err) {
9918         /* get the argument and param counts */
9919         argc = r->v.bn.n_nodes;
9920         nparam = fn_n_params(uf);
9921         if (argc > nparam) {
9922             gretl_errmsg_sprintf(_("Number of arguments (%d) does not "
9923                                    "match the number of\nparameters for "
9924                                    "function %s (%d)"),
9925                                  argc, funname, nparam);
9926             p->err = E_DATA;
9927         }
9928     }
9929 
9930     if (p->err) {
9931         /* no sense in continuing */
9932         return NULL;
9933     }
9934 
9935 #if 1 /* for now, just warn */
9936     if (t == p->tree && (p->flags & P_CATCH)) {
9937         gretl_warnmsg_set(_("\"catch\" should not be used on calls to "
9938                             "user-defined functions"));
9939     }
9940 #else
9941     if (t == p->tree && (p->flags & P_CATCH)) {
9942         p->err = E_BADCATCH;
9943         return NULL;
9944     }
9945 #endif
9946 
9947     fc = fncall_new(uf, 1);
9948     if (fc == NULL) {
9949         p->err = E_ALLOC;
9950         return NULL;
9951     }
9952 
9953     /* evaluate the function argument nodes */
9954 
9955     for (i=0; i<argc && !p->err; i++) {
9956         NODE *arg, *ni = r->v.bn.n[i];
9957         GretlType argt = 0;
9958         int reftype = 0;
9959         void *data;
9960 
9961         if (starting(p)) {
9962             /* evaluate all nodes */
9963             arg = eval(ni, p);
9964         } else if (ni->vname != NULL) {
9965             /* otherwise let named variables through "as is" */
9966             arg = ni;
9967         } else {
9968             arg = eval(ni, p);
9969         }
9970 
9971         if (p->err || arg == NULL) {
9972             fprintf(stderr, "%s: failed to evaluate arg %d\n", funname, i+1);
9973             fprintf(stderr, " (input node was of type %d, '%s')\n", ni->t,
9974                     getsymb(ni->t));
9975             p->err = (p->err == 0)? E_DATA : p->err;
9976         } else if (!ok_ufunc_sym(arg->t)) {
9977             gretl_errmsg_sprintf("%s: invalid argument type %s", funname,
9978                                  typestr(arg->t));
9979             p->err = E_TYPES;
9980         }
9981 
9982 #if EDEBUG
9983         fprintf(stderr, "%s: arg %d is of type %s (err=%d)\n", funname, i+1,
9984                 arg == NULL ? "?" : getsymb(arg->t), p->err);
9985 #endif
9986         if (p->err) {
9987             break;
9988         }
9989 
9990         if (!p->err && arg->t == U_ADDR) {
9991             /* address node: switch to the 'content' sub-node */
9992             reftype = 1;
9993             arg = arg->L;
9994         }
9995 
9996         if (!p->err && arg->t == DUM && arg->v.idnum != DUM_NULL) {
9997             p->err = E_TYPES;
9998         }
9999 
10000         if (!p->err) {
10001             /* assemble info and push argument */
10002             user_var *uv = NULL;
10003 
10004             data = arg_get_data(arg, reftype, &argt, &uv);
10005             p->err = push_function_arg(fc, arg->vname, uv, argt, data);
10006         }
10007 
10008         if (p->err) {
10009             fprintf(stderr, "%s: error evaluating arg %d\n", funname, i);
10010         }
10011     }
10012 
10013     /* try sending args to function */
10014 
10015     if (!p->err) {
10016         char **pdescrip = NULL;
10017 	void *altp = NULL;
10018         void *retp = &altp;
10019 
10020 	/* special cases */
10021 	if (rtype == GRETL_TYPE_VOID) {
10022 	    retp = NULL;
10023         } else if (rtype == GRETL_TYPE_MATRIX) {
10024             if (p->targ == UNK && p->tree == t) {
10025                 /* target type not specified, and function returns
10026                    a matrix -> set target type to matrix
10027                 */
10028                 p->targ = MAT;
10029             }
10030 	} else if (rtype == GRETL_TYPE_LIST) {
10031             if (p->targ == EMPTY && p->tree == t) {
10032                 /* this function offers a list return, but the
10033                    caller hasn't assigned it and it's not being
10034                    used as an argument to a further function, so
10035                    ignore the return value
10036                 */
10037                 retp = NULL;
10038             }
10039 	}
10040 
10041         if ((p->flags & P_UFRET) && rtype == GRETL_TYPE_SERIES) {
10042             /* arrange to pick up description of generated series, if any */
10043             pdescrip = &p->lh.label;
10044         }
10045 
10046         p->err = gretl_function_exec(fc, rtype, p->dset, retp,
10047                                      pdescrip, p->prn);
10048 
10049 	if (rtype == GRETL_TYPE_NUMERIC) {
10050 	    /* determine which numeric type we actually got */
10051 	    rtype = fncall_get_return_type(fc);
10052 	}
10053 
10054         if (!p->err && retp != NULL) {
10055             reset_p_aux(p, save_aux);
10056             if (rn != NULL) {
10057                 ret = rn;
10058             } else {
10059                 ret = suitable_ufunc_ret_node(p, rtype);
10060             }
10061         }
10062 
10063         if (!p->err && ret != NULL) {
10064             if (rtype == GRETL_TYPE_DOUBLE) {
10065                 ret->v.xval = *(double *) altp;
10066             } else if (rtype == GRETL_TYPE_SERIES) {
10067                 if (ret->v.xvec != NULL) {
10068                     free(ret->v.xvec);
10069                 }
10070                 ret->v.xvec = altp;
10071             } else if (rtype == GRETL_TYPE_MATRIX) {
10072                 if (is_tmp_node(ret)) {
10073                     gretl_matrix_free(ret->v.m);
10074                 }
10075                 ret->v.m = altp;
10076             } else if (rtype == GRETL_TYPE_LIST) {
10077                 if (is_tmp_node(ret)) {
10078                     free(ret->v.ivec);
10079                 }
10080                 if (altp != NULL) {
10081                     ret->v.ivec = altp;
10082                 } else {
10083                     ret->v.ivec = gretl_list_new(0);
10084                 }
10085             } else if (rtype == GRETL_TYPE_STRING) {
10086                 if (is_tmp_node(ret)) {
10087                     free(ret->v.str);
10088                 }
10089                 ret->v.str = altp;
10090             } else if (rtype == GRETL_TYPE_BUNDLE) {
10091                 if (is_tmp_node(ret)) {
10092                     gretl_bundle_destroy(ret->v.b);
10093                 }
10094                 ret->t = BUNDLE;
10095                 ret->v.b = altp;
10096             } else if (gretl_array_type(rtype)) {
10097                 if (is_tmp_node(ret)) {
10098                     gretl_array_destroy(ret->v.a);
10099                 }
10100                 ret->t = ARRAY;
10101                 ret->v.a = altp;
10102             }
10103         }
10104     }
10105 
10106     /* avoid leaking memory */
10107     fncall_destroy(fc);
10108 
10109 #if EDEBUG
10110     fprintf(stderr, "eval_ufunc: p->err = %d, ret = %p\n",
10111             p->err, (void *) ret);
10112 #endif
10113 
10114     return ret;
10115 }
10116 
10117 #ifdef USE_RLIB
10118 
10119 /* evaluate an R function */
10120 
eval_Rfunc(NODE * t,parser * p)10121 static NODE *eval_Rfunc (NODE *t, parser *p)
10122 {
10123     NODE *save_aux = p->aux;
10124     NODE *l = t->L;
10125     NODE *r = t->R;
10126     int i, argc = r->v.bn.n_nodes;
10127     const char *funname = l->v.str;
10128     int rtype = GRETL_TYPE_NONE;
10129     NODE *ret = NULL;
10130 
10131     /* first find the function */
10132     p->err = gretl_R_get_call(funname, argc);
10133     if (p->err) {
10134         fprintf(stderr, "eval_Rfunc: can't find function %s\n", funname);
10135         return NULL;
10136     }
10137 
10138     /* evaluate the function arguments */
10139     for (i=0; i<argc && !p->err; i++) {
10140         NODE *arg = eval(r->v.bn.n[i], p);
10141         GretlType type;
10142 
10143         if (arg == NULL) {
10144             fprintf(stderr, "%s: failed to evaluate arg %d\n", funname, i);
10145         } else if (!ok_ufunc_sym(arg->t)) {
10146             fprintf(stderr, "%s: node type %d: not OK\n", funname, arg->t);
10147             p->err = E_TYPES;
10148         }
10149         if (p->err) {
10150             break;
10151         }
10152 
10153 #if EDEBUG
10154         fprintf(stderr, "%s: arg[%d] is of type %d\n", funname, i, arg->t);
10155 #endif
10156         type = gretl_type_from_gen_type(arg->t);
10157 
10158         if (type == GRETL_TYPE_SERIES) {
10159             /* revised 2020-02-01 */
10160             p->err = gretl_R_function_add_series(arg->v.xvec, p->dset, arg->vnum);
10161         } else if (type == GRETL_TYPE_DOUBLE) {
10162             p->err = gretl_R_function_add_arg(&arg->v.xval, type);
10163         } else if (type == GRETL_TYPE_MATRIX) {
10164             p->err = gretl_R_function_add_arg(arg->v.m, type);
10165         } else if (type == GRETL_TYPE_ARRAY) {
10166             p->err = gretl_R_function_add_arg(arg->v.a, type);
10167         } else if (type == GRETL_TYPE_STRING) {
10168             p->err = gretl_R_function_add_arg(arg->v.str, type);
10169         } else if (type == GRETL_TYPE_BUNDLE) {
10170             p->err = gretl_R_function_add_arg(arg->v.b, type);
10171         } else {
10172             fprintf(stderr, "eval_Rfunc: argument not supported\n");
10173             p->err = E_TYPES;
10174             return NULL;
10175         }
10176         if (p->err) {
10177             fprintf(stderr, "eval_Rfunc: error evaluating arg %d\n", i);
10178         }
10179     }
10180 
10181     /* try sending args to function */
10182 
10183     if (!p->err) {
10184         double xret = NADBL;
10185         void *retp = &xret;
10186 
10187         p->err = gretl_R_function_exec(funname, &rtype, &retp);
10188 
10189         if (!p->err) {
10190             reset_p_aux(p, save_aux);
10191             if (gretl_scalar_type(rtype)) {
10192                 ret = aux_scalar_node(p);
10193                 if (ret != NULL) {
10194                     ret->v.xval = xret;
10195                 }
10196             } else if (rtype == GRETL_TYPE_MATRIX) {
10197                 ret = aux_matrix_node(p);
10198                 if (ret != NULL) {
10199                     ret->v.m = (gretl_matrix *) retp;
10200                 }
10201             } else if (rtype == GRETL_TYPE_STRING) {
10202                 ret = aux_string_node(p);
10203                 if (ret != NULL) {
10204                     if (is_tmp_node(ret)) {
10205                         free(ret->v.str);
10206                     }
10207                     ret->v.str = (char *) retp;
10208                 }
10209             } else if (rtype == GRETL_TYPE_ARRAY) {
10210                 ret = aux_array_node(p);
10211                 if (ret != NULL) {
10212                     ret->v.a = (gretl_array *) retp;
10213                 }
10214             } else if (rtype == GRETL_TYPE_BUNDLE) {
10215                 ret = aux_bundle_node(p);
10216                 if (ret != NULL) {
10217                     ret->v.b = (gretl_bundle *) retp;
10218                 }
10219             } else if (rtype == GRETL_TYPE_NONE) {
10220                 ; /* OK? */
10221             }
10222         }
10223     }
10224 
10225 #if EDEBUG
10226     fprintf(stderr, "eval_Rfunc: p->err = %d, ret = %p\n",
10227             p->err, (void *) ret);
10228 #endif
10229 
10230     return ret;
10231 }
10232 
10233 #endif /* USE_RLIB */
10234 
10235 /* Getting an object from within a bundle: on the left is the
10236    bundle reference, on the right should be a string -- the
10237    key to look up to get content.
10238 */
10239 
get_bundle_member(NODE * l,NODE * r,parser * p)10240 static NODE *get_bundle_member (NODE *l, NODE *r, parser *p)
10241 {
10242     char *key = r->v.str;
10243     GretlType type;
10244     int size = 0;
10245     void *val = NULL;
10246     NODE *ret = NULL;
10247 
10248 #if EDEBUG
10249     fprintf(stderr, "get_bundle_member: %s[\"%s\"]\n",
10250             l->vname, key);
10251 #endif
10252 
10253     if (p->flags & P_OBJQRY) {
10254         val = gretl_bundle_get_data(l->v.b, key, &type, &size, NULL);
10255         if (val == NULL) {
10256             return newempty();
10257         }
10258     } else {
10259         val = gretl_bundle_get_data(l->v.b, key, &type, &size, &p->err);
10260         if (p->err) {
10261             return ret;
10262         }
10263     }
10264 
10265     if (type == GRETL_TYPE_INT) {
10266         ret = aux_scalar_node(p);
10267         if (ret != NULL) {
10268             int *ip = val;
10269 
10270             ret->v.xval = *ip;
10271         }
10272     } else if (type == GRETL_TYPE_DOUBLE) {
10273         ret = aux_scalar_node(p);
10274         if (ret != NULL) {
10275             double *dp = val;
10276 
10277             ret->v.xval = *dp;
10278         }
10279     } else if (type == GRETL_TYPE_STRING) {
10280         ret = string_pointer_node(p);
10281         if (ret != NULL) {
10282             ret->v.str = (char *) val;
10283         }
10284     } else if (type == GRETL_TYPE_MATRIX) {
10285         ret = matrix_pointer_node(p);
10286         if (ret != NULL) {
10287             ret->v.m = (gretl_matrix *) val;
10288         }
10289     } else if (type == GRETL_TYPE_BUNDLE) {
10290         ret = bundle_pointer_node(p);
10291         if (ret != NULL) {
10292             ret->v.b = (gretl_bundle *) val;
10293         }
10294     } else if (type == GRETL_TYPE_ARRAY) {
10295         ret = array_pointer_node(p);
10296         if (ret != NULL) {
10297             ret->v.a = (gretl_array *) val;
10298         }
10299     } else if (type == GRETL_TYPE_SERIES) {
10300         const double *x = val;
10301 
10302         if (size <= p->dset->n) {
10303             ret = aux_series_node(p);
10304             if (ret != NULL) {
10305                 int t;
10306 
10307                 for (t=p->dset->t1; t<=p->dset->t2 && t<size; t++) {
10308                     ret->v.xvec[t] = x[t];
10309                 }
10310             }
10311         } else if (size > 0) {
10312             ret = aux_matrix_node(p);
10313             if (ret != NULL) {
10314                 ret->v.m = gretl_vector_from_array(x, size,
10315                                                    GRETL_MOD_NONE);
10316                 if (ret->v.m == NULL) {
10317                     p->err = E_ALLOC;
10318                 }
10319             }
10320         } else {
10321             p->err = E_DATA;
10322         }
10323     } else if (type == GRETL_TYPE_LIST) {
10324         p->err = stored_list_check((const int *) val, p->dset);
10325         if (!p->err) {
10326             /* OK, extract list as such */
10327             ret = list_pointer_node(p);
10328             if (!p->err) {
10329                 ret->v.ivec = (int *) val;
10330             }
10331         } else {
10332             /* fallback: extract list as row vector */
10333             gretl_error_clear();
10334             p->err = 0;
10335             ret = aux_matrix_node(p);
10336             if (!p->err) {
10337                 ret->v.m = gretl_list_to_vector((const int *) val, &p->err);
10338             }
10339         }
10340     } else {
10341         p->err = E_DATA;
10342     }
10343 
10344     if (ret != NULL) {
10345         ret->flags |= MUT_NODE;
10346     }
10347 
10348     return ret;
10349 }
10350 
test_bundle_key(NODE * l,NODE * r,parser * p)10351 static NODE *test_bundle_key (NODE *l, NODE *r, parser *p)
10352 {
10353     NODE *ret = aux_scalar_node(p);
10354 
10355     if (ret != NULL) {
10356         gretl_bundle *bundle = l->v.b;
10357         const char *key = r->v.str;
10358         GretlType type = 0;
10359         int err = 0;
10360 
10361         gretl_bundle_get_data(bundle, key, &type, NULL, &err);
10362         ret->v.xval = gretl_type_get_order(type);
10363         if (err) {
10364             gretl_error_clear();
10365         }
10366     }
10367 
10368     return ret;
10369 }
10370 
get_bundle_array(NODE * n,int f,parser * p)10371 static NODE *get_bundle_array (NODE *n, int f, parser *p)
10372 {
10373     NODE *ret = aux_array_node(p);
10374 
10375     if (ret != NULL) {
10376         if (f == F_GETKEYS) {
10377             ret->v.a = gretl_bundle_get_keys(n->v.b, &p->err);
10378         } else {
10379             /* HF_JBTERMS */
10380             gretl_array *(*jfunc) (gretl_bundle *, int *);
10381 
10382             jfunc = get_plugin_function("json_bundle_get_terminals");
10383             if (jfunc == NULL) {
10384                 p->err = E_FOPEN;
10385             } else {
10386                 ret->v.a = jfunc(n->v.b, &p->err);
10387             }
10388         }
10389     }
10390 
10391     return ret;
10392 }
10393 
optional_bundle_get(gretl_bundle * b,const char * key,double * px,int * err)10394 static const char *optional_bundle_get (gretl_bundle *b,
10395                                         const char *key,
10396                                         double *px,
10397                                         int *err)
10398 {
10399     const char *s = NULL;
10400 
10401     if (!*err) {
10402         /* proceed only if we haven't already hit an error */
10403         if (px != NULL) {
10404             *px = gretl_bundle_get_scalar(b, key, err);
10405         } else {
10406             s = gretl_bundle_get_string(b, key, err);
10407         }
10408         if (*err == E_DATA) {
10409             /* non-existence of item (E_DATA) is OK, but
10410                wrong type (E_TYPES) is not
10411             */
10412             gretl_error_clear();
10413             *err = 0;
10414         }
10415     }
10416 
10417     return s;
10418 }
10419 
curl_bundle_node(NODE * n,parser * p)10420 static NODE *curl_bundle_node (NODE *n, parser *p)
10421 {
10422     NODE *ret = aux_scalar_node(p);
10423 
10424 #ifndef USE_CURL
10425     gretl_errmsg_set(_("Internet access not supported"));
10426     p->err = E_DATA;
10427 #else
10428     if (ret != NULL) {
10429         gretl_bundle *b = NULL;
10430         int curl_err = 0;
10431 
10432         if (n->t != U_ADDR) {
10433             p->err = E_TYPES;
10434         } else {
10435             /* switch to 'content' sub-node */
10436             n = n->L;
10437             if (n->t != BUNDLE) {
10438                 p->err = E_TYPES;
10439             } else {
10440                 b = n->v.b;
10441             }
10442         }
10443 
10444         if (!p->err) {
10445             const char *url = NULL;
10446             const char *header = NULL;
10447             const char *postdata = NULL;
10448             char *output = NULL;
10449             char *errmsg = NULL;
10450             double xinclude = 0;
10451 
10452             url = gretl_bundle_get_string(b, "URL", &p->err);
10453             header = optional_bundle_get(b, "header", NULL, &p->err);
10454             postdata = optional_bundle_get(b, "postdata", NULL, &p->err);
10455             optional_bundle_get(b, "include", &xinclude, &p->err);
10456 
10457             if (!p->err) {
10458                 int include = (xinclude == 1.0);
10459 
10460                 curl_err = gretl_curl(url, header, postdata, include,
10461                                       &output, &errmsg);
10462             }
10463             if (output != NULL) {
10464                 p->err = gretl_bundle_set_string(b, "output", output);
10465                 free(output);
10466             } else if (errmsg != NULL) {
10467                 p->err = gretl_bundle_set_string(b, "errmsg", errmsg);
10468                 free(errmsg);
10469             }
10470         }
10471 
10472         if (!p->err) {
10473             ret->v.xval = curl_err;
10474         }
10475     }
10476 #endif /* curl supported in libgretl */
10477 
10478     return ret;
10479 }
10480 
lpsolve_bundle_node(NODE * n,parser * p)10481 static NODE *lpsolve_bundle_node (NODE *n, parser *p)
10482 {
10483     NODE *ret = aux_bundle_node(p);
10484 
10485     if (ret != NULL) {
10486 	gretl_bundle *(*lpfunc) (gretl_bundle *, PRN *, int *);
10487 
10488 	lpfunc = get_plugin_function("gretl_lpsolve");
10489 	if (lpfunc == NULL) {
10490 	    p->err = E_FOPEN;
10491 	} else {
10492 	    ret->v.b = (*lpfunc)(n->v.b, p->prn, &p->err);
10493 	}
10494     }
10495 
10496     return ret;
10497 }
10498 
node_get_bundle(NODE * n,parser * p)10499 static gretl_bundle *node_get_bundle (NODE *n, parser *p)
10500 {
10501     gretl_bundle *b = NULL;
10502 
10503     if (n->t == BUNDLE) {
10504         b = n->v.b;
10505     } else if (n->t == U_ADDR) {
10506         n = n->L;
10507         if (n->t != BUNDLE) {
10508             p->err = E_TYPES;
10509         } else {
10510             b = n->v.b;
10511         }
10512     } else {
10513         p->err = E_TYPES;
10514     }
10515 
10516     return b;
10517 }
10518 
svm_driver_node(NODE * t,parser * p)10519 static NODE *svm_driver_node (NODE *t, parser *p)
10520 {
10521     NODE *save_aux = p->aux;
10522     NODE *n = t->L;
10523     NODE *e, *ret = NULL;
10524     int *list = NULL;
10525     gretl_bundle *bparm = NULL;
10526     gretl_bundle *bmod = NULL;
10527     gretl_bundle *bprob = NULL;
10528     int i, k = n->v.bn.n_nodes;
10529 
10530     if (k < 2 || k > 4) {
10531         n_args_error(k, 2, F_SVM, p);
10532     }
10533 
10534     for (i=0; i<k && !p->err; i++) {
10535         e = eval(n->v.bn.n[i], p);
10536         if (i == 0) {
10537             list = node_get_list(e, p);
10538         } else if (i == 1) {
10539             bparm = node_get_bundle(e, p);
10540         } else if (i == 2) {
10541             if (!null_node(e)) {
10542                 bmod = node_get_bundle(e, p);
10543             }
10544         } else {
10545             if (!null_node(e)) {
10546                 bprob = node_get_bundle(e, p);
10547             }
10548         }
10549     }
10550 
10551     if (!p->err) {
10552         reset_p_aux(p, save_aux);
10553         ret = aux_series_node(p);
10554     }
10555 
10556     if (ret != NULL) {
10557         int (*pfunc) (const int *, gretl_bundle *,
10558                       gretl_bundle *, gretl_bundle *,
10559                       double *, int *, DATASET *, PRN *);
10560         int got_yhat = 0;
10561 
10562         pfunc = get_plugin_function("gretl_svm_driver");
10563         if (pfunc == NULL) {
10564             p->err = E_FOPEN;
10565         } else {
10566             p->err = pfunc(list, bparm, bmod, bprob, ret->v.xvec,
10567                            &got_yhat, p->dset, p->prn);
10568             if (!p->err && !got_yhat) {
10569                 /* change the return type to scalar NA */
10570                 free(ret->v.xvec);
10571                 ret->t = NUM;
10572                 ret->v.xval = NADBL;
10573             }
10574         }
10575     }
10576 
10577     free(list);
10578 
10579     return ret;
10580 }
10581 
bvar_get_bundle(NODE * n,parser * p)10582 static gretl_bundle *bvar_get_bundle (NODE *n, parser *p)
10583 {
10584     gretl_bundle *b = NULL;
10585 
10586     if (n->v.idnum == B_MODEL) {
10587         b = bundle_from_model(NULL, p->dset, &p->err);
10588     } else if (n->v.idnum == B_SYSTEM) {
10589         b = bundle_from_system(NULL, 0, p->dset, &p->err);
10590     } else if (n->v.idnum == B_SYSINFO) {
10591         gretl_bundle *tmp = get_sysinfo_bundle(&p->err);
10592 
10593         if (!p->err) {
10594             b = gretl_bundle_copy(tmp, &p->err);
10595         }
10596     } else if (n->v.idnum == R_RESULT) {
10597         GretlType type = 0;
10598         void *ptr = get_last_result_data(&type, &p->err);
10599 
10600         if (type == GRETL_TYPE_BUNDLE) {
10601             b = ptr;
10602         } else if (!p->err) {
10603             p->err = E_TYPES;
10604         }
10605     } else {
10606         p->err = E_DATA;
10607     }
10608 
10609     return b;
10610 }
10611 
dollar_bundle_node(NODE * n,parser * p)10612 static NODE *dollar_bundle_node (NODE *n, parser *p)
10613 {
10614     NODE *ret = aux_bundle_node(p);
10615 
10616     if (ret != NULL) {
10617         ret->v.b = bvar_get_bundle(n, p);
10618     }
10619 
10620     return ret;
10621 }
10622 
type_string_node(NODE * n,parser * p)10623 static NODE *type_string_node (NODE *n, parser *p)
10624 {
10625     NODE *ret = aux_string_node(p);
10626 
10627     if (ret != NULL) {
10628         int t = node_get_int(n, p);
10629 
10630         if (!p->err) {
10631             const char *s = "null";
10632 
10633             if (t == 1) {
10634                 s = "scalar";
10635             } else if (t == 2) {
10636                 s = "series";
10637             } else if (t == 3) {
10638                 s = "matrix";
10639             } else if (t == 4) {
10640                 s = "string";
10641             } else if (t == 5) {
10642                 s = "bundle";
10643             } else if (t == 6) {
10644                 s = "array";
10645             } else if (t == 7) {
10646                 s = "list";
10647             }
10648 
10649             ret->v.str = gretl_strdup(s);
10650             if (ret->v.str == NULL) {
10651                 p->err = E_ALLOC;
10652             }
10653         }
10654     }
10655 
10656     return ret;
10657 }
10658 
scalar_to_series(NODE * n,parser * p)10659 static double *scalar_to_series (NODE *n, parser *p)
10660 {
10661     double *ret = NULL;
10662     int t;
10663 
10664     if (p->dset == NULL || p->dset->n == 0) {
10665         p->err = E_NODATA;
10666     } else {
10667         ret = malloc(p->dset->n * sizeof *ret);
10668         if (ret == NULL) {
10669             p->err = E_ALLOC;
10670         } else {
10671             for (t=0; t<p->dset->n; t++) {
10672                 if (t >= p->dset->t1 && t <= p->dset->t2) {
10673                     ret[t] = n->v.xval;
10674                 } else {
10675                     ret[t] = NADBL;
10676                 }
10677             }
10678         }
10679     }
10680 
10681     return ret;
10682 }
10683 
10684 /* We come here only when setting a bundle-member or an element
10685    of an array -- otherwise we use get_check_return_type().
10686    Note 2021-08-12: in principle we could allow the case
10687    where @spec is an array type and @rhs is the singular of
10688    that type, and support auto-promotion of (e.g.) a string
10689    to an array of strings. But I'm not sure that's a good idea.
10690 */
10691 
lhs_type_check(GretlType spec,GretlType rhs,int t)10692 static int lhs_type_check (GretlType spec, GretlType rhs, int t)
10693 {
10694     int err = 0;
10695 
10696     if (spec != 0 && spec != rhs) {
10697         if (t == BUNDLE) {
10698             gretl_errmsg_sprintf(_("Expected %s but got %s"),
10699                                  gretl_type_get_name(spec),
10700                                  gretl_type_get_name(rhs));
10701         } else {
10702             gretl_errmsg_sprintf(_("Specified type %s does not match array type %s"),
10703                                  gretl_type_get_name(spec),
10704                                  gretl_type_get_name(rhs));
10705         }
10706         err = E_TYPES;
10707     }
10708 
10709     return err;
10710 }
10711 
get_mod_assign_result(void * lp,GretlType ltype,NODE * r,int * size,parser * p)10712 static void *get_mod_assign_result (void *lp, GretlType ltype,
10713                                     NODE *r, int *size, parser *p)
10714 {
10715     void *ret = NULL;
10716     NODE *l, *op;
10717 
10718     if (p->op == INC || p->op == DEC) {
10719         /* handle increment/decrement postfix operator */
10720         if (ltype == GRETL_TYPE_DOUBLE) {
10721             double x = *(double *) lp;
10722 
10723             if (!na(x)) {
10724                 x += (p->op == INC)? 1 : -1;
10725                 *(double *) lp = x;
10726             }
10727             ret = lp;
10728         } else {
10729             p->err = E_TYPES;
10730         }
10731         return ret; /* handled */
10732     }
10733 
10734     /* create binary tree to hold left and right */
10735     l = newempty();
10736     op = newb2(p->op, l, r);
10737 
10738     /* if that went OK, put the relevant type specifier
10739        and pointer onto the LHS sub-node
10740     */
10741     if (op == NULL || l == NULL) {
10742         p->err = E_ALLOC;
10743     } else if (ltype == GRETL_TYPE_MATRIX) {
10744         l->t = MAT;
10745         l->v.m = lp;
10746     } else if (ltype == GRETL_TYPE_DOUBLE) {
10747         l->t = NUM;
10748         l->v.xval = *(double *) lp;
10749     } else if (ltype == GRETL_TYPE_STRING) {
10750         l->t = STR;
10751         l->v.str = lp;
10752     } else if (ltype == GRETL_TYPE_BUNDLE) {
10753         l->t = BUNDLE;
10754         l->v.b = lp;
10755     } else if (ltype == GRETL_TYPE_ARRAY) {
10756         l->t = ARRAY;
10757         l->v.a = lp;
10758     } else if (ltype == GRETL_TYPE_LIST) {
10759         l->t = LIST;
10760         l->v.ivec = lp;
10761         if (p->op == B_ADD) {
10762             /* reinterpret '+' when appending to a list */
10763             op->t = B_LCAT;
10764         }
10765     } else if (ltype == GRETL_TYPE_SERIES) {
10766         l->t = SERIES;
10767         l->v.xvec = lp;
10768     } else {
10769         p->err = E_TYPES;
10770     }
10771 
10772     if (!p->err) {
10773         /* FIXME parser state variables? */
10774         int saveflags = p->flags;
10775         int savetarg = p->targ;
10776         NODE *ev;
10777 
10778 #if LHDEBUG
10779         fputs("*** op tree, before ***\n", stderr);
10780         print_tree(op, p, 0, 0);
10781 #endif
10782         p->targ = l->t;
10783         p->flags = P_START;
10784 	if (saveflags & P_LISTDEF) {
10785 	    p->flags |= P_LISTDEF;
10786 	}
10787         ev = eval(op, p);
10788 #if LHDEBUG
10789         fputs("*** ev tree, after ***\n", stderr);
10790         print_tree(ev, p, 0, 0);
10791 #endif
10792 
10793         if (!p->err) {
10794             /* get @ret off node @ev and clean up */
10795             if (ev->t == MAT) {
10796                 ret = ev->v.m;
10797             } else if (ev->t == BUNDLE) {
10798                 ret = ev->v.b;
10799             } else if (ev->t == STR) {
10800                 ret = ev->v.str;
10801             } else if (ev->t == ARRAY) {
10802                 ret = ev->v.a;
10803             } else if (ev->t == LIST) {
10804                 ret = ev->v.ivec;
10805             } else if (ev->t == SERIES) {
10806                 /* FIXME sample range? */
10807                 if (size != NULL) {
10808                     *size = p->dset->n;
10809                 }
10810                 ret = ev->v.xvec;
10811             } else if (ev->t == NUM) {
10812                 ret = lp;
10813                 *(double *) lp = ev->v.xval;
10814             } else {
10815                 p->err = E_TYPES;
10816             }
10817         }
10818 
10819         p->targ = savetarg;
10820         p->flags = saveflags;
10821         free(ev);
10822     }
10823 
10824     /* thought: if @p is reusable, should we try preserving the
10825        nodes allocated here?
10826     */
10827 
10828     /* trash temporary nodes */
10829     free(op);
10830     free(l);
10831 
10832     if (ret == NULL && !p->err) {
10833         p->err = E_DATA;
10834     }
10835 
10836     return ret;
10837 }
10838 
10839 /* ".=" : we need a scalar (possibly complex) on the RHS */
10840 
dot_assign_to_matrix(gretl_matrix * m,parser * p)10841 static int dot_assign_to_matrix (gretl_matrix *m, parser *p)
10842 {
10843     NODE *n = p->ret;
10844     int err = 0;
10845 
10846     if (scalar_node(n)) {
10847         gretl_matrix_fill(m, node_get_scalar(n, p));
10848     } else if (cscalar_node(n)) {
10849         err = gretl_cmatrix_fill(m, n->v.m->z[0]);
10850     } else {
10851         err = E_TYPES;
10852     }
10853 
10854     return err;
10855 }
10856 
10857 #define empty_rhs_ok(t) (t==GRETL_TYPE_BUNDLE || gretl_is_array_type(t))
10858 
10859 /* Setting an object in a bundle under a given key string. We get here
10860    only if p->lh.expr is non-NULL.
10861 */
10862 
set_bundle_value(NODE * lhs,NODE * rhs,parser * p)10863 static int set_bundle_value (NODE *lhs, NODE *rhs, parser *p)
10864 {
10865     NODE *lh1 = lhs->L;
10866     NODE *lh2 = lhs->R;
10867     GretlType targ = 0;
10868     GretlType type = 0;
10869     gretl_bundle *bundle;
10870     void *ptr = NULL;
10871     char *key = NULL;
10872     int size = 0;
10873     int donate = 0;
10874     int err = 0;
10875 
10876     if (lh1->t != BUNDLE) {
10877         return E_DATA;
10878     } else if (lh2->t != STR && lh2->t != MSPEC) {
10879         return E_DATA;
10880     }
10881 
10882     bundle = lh1->v.b;
10883     key = lh2->t == STR ? lh2->v.str : lh2->v.mspec->lsel.str;
10884 
10885     if (bundle == NULL || key == NULL) {
10886         return E_DATA;
10887     }
10888 
10889 #if LHDEBUG
10890     fprintf(stderr, "set_bundle_value: bundle = %p, key = '%s'\n",
10891             (void *) bundle, key);
10892 #endif
10893 
10894     if ((p->flags & P_PRIV) && p->op == B_ASN && null_node(rhs)) {
10895         /* this is an internal "special" that implements removal
10896            of a bundle member via the "delete" command
10897         */
10898         return gretl_bundle_delete_data(bundle, key);
10899     }
10900 
10901     if (p->op != B_ASN) {
10902         /* We must have an existing bundle member under @key, and
10903            its type will determine the type of the result of
10904            inflected assignment.
10905         */
10906         GretlType ltype = 0;
10907         void *lp;
10908 
10909         lp = gretl_bundle_get_data(bundle, key, &ltype, &size, &err);
10910         if (!err) {
10911             targ = gretl_type_from_gen_type(p->targ);
10912             err = lhs_type_check(targ, ltype, BUNDLE);
10913         }
10914         if (p->op == B_DOTASN) {
10915             /* accepted only for matrices */
10916             if (!err) {
10917                 if (ltype == GRETL_TYPE_MATRIX) {
10918                     err = dot_assign_to_matrix(lp, p);
10919                 } else {
10920                     err = E_TYPES;
10921                 }
10922             }
10923             return err; /* handled */
10924         }
10925         if (!err) {
10926             ptr = get_mod_assign_result(lp, ltype, rhs, &size, p);
10927             err = p->err;
10928             if (p->op == INC || p->op == DEC) {
10929                 return err; /* handled */
10930             }
10931         }
10932         if (!err) {
10933             type = ltype;
10934             if (ptr != lp) {
10935                 donate = 1; /* donate: is this always right? */
10936             }
10937         }
10938         goto push_data;
10939     }
10940 
10941     /* Note: @targ is the gretl type specified by the caller for
10942        the bundle member (if any, this need not be supplied), and
10943        @type is the gretl type of the object arising on the RHS.
10944        It's an error if @targ is non-zero and @type does not
10945        agree with it -- except for the case where @targ is given
10946        as "series" and we get a suitable matrix on the right. As
10947        of 2015-10-03, when we get a request to put a series into
10948        a bundle we actually put in a matrix, which in fact makes it
10949        easier to get a series back out again.
10950     */
10951 
10952     if (p->targ == ARRAY) {
10953         targ = p->lh.gtype;
10954     } else {
10955         targ = gretl_type_from_gen_type(p->targ);
10956     }
10957 
10958     if (targ == GRETL_TYPE_NONE && null_node(rhs)) {
10959         /* at this point @targ is indeterminate, but maybe there's
10960            an existing member to fix its value?
10961         */
10962         void *lp = gretl_bundle_get_data(bundle, key, &targ, NULL, NULL);
10963 
10964         if (targ == GRETL_TYPE_ARRAY) {
10965             targ = gretl_array_get_type(lp);
10966         }
10967     }
10968 
10969     if (!err && targ == GRETL_TYPE_LIST) {
10970         ptr = node_get_list(rhs, p);
10971         err = p->err;
10972         if (!err) {
10973             type = GRETL_TYPE_LIST;
10974             donate = 1;
10975         }
10976     } else if (!err) {
10977         switch (rhs->t) {
10978         case NUM:
10979             if (targ == GRETL_TYPE_SERIES) {
10980                 ptr = scalar_to_series(rhs, p);
10981                 if (p->err) {
10982                     err = p->err;
10983                 } else {
10984                     type = GRETL_TYPE_SERIES;
10985                     size = p->dset->n;
10986                     donate = 1;
10987                 }
10988             } else if (targ == GRETL_TYPE_MATRIX) {
10989                 ptr = gretl_matrix_from_scalar(rhs->v.xval);
10990                 type = GRETL_TYPE_MATRIX;
10991                 donate = 1;
10992             } else {
10993                 ptr = &rhs->v.xval;
10994                 type = GRETL_TYPE_DOUBLE;
10995             }
10996             break;
10997         case STR:
10998             ptr = rhs->v.str;
10999             type = GRETL_TYPE_STRING;
11000             donate = !reusable(p) && is_tmp_node(rhs);
11001             break;
11002         case MAT:
11003             if (targ == GRETL_TYPE_DOUBLE && scalar_matrix_node(rhs)) {
11004                 ptr = &rhs->v.m->val[0];
11005                 type = GRETL_TYPE_DOUBLE;
11006             } else if (targ == GRETL_TYPE_SERIES) {
11007                 ptr = (double *) get_colvec_as_series(rhs, 0, p);
11008                 if (!p->err) {
11009                     type = GRETL_TYPE_SERIES;
11010                     size = p->dset->n;
11011                 }
11012             } else {
11013                 ptr = rhs->v.m;
11014                 type = GRETL_TYPE_MATRIX;
11015                 donate = is_tmp_node(rhs);
11016             }
11017             break;
11018         case SERIES:
11019             ptr = rhs->v.xvec;
11020             type = GRETL_TYPE_SERIES;
11021             size = p->dset->n;
11022             donate = !reusable(p) && is_tmp_node(rhs);
11023             break;
11024         case BUNDLE:
11025             ptr = rhs->v.b;
11026             type = GRETL_TYPE_BUNDLE;
11027             break;
11028         case ARRAY:
11029             ptr = rhs->v.a;
11030             /* get more specific type for comparison with
11031                what the user specified (if anything)
11032             */
11033             type = gretl_array_get_type(rhs->v.a);
11034             donate = !reusable(p) && is_tmp_node(rhs);
11035             break;
11036         case LIST:
11037             if (targ == GRETL_TYPE_MATRIX) {
11038                 ptr = gretl_list_to_vector(rhs->v.ivec, &p->err);
11039                 if (!p->err) {
11040                     type = GRETL_TYPE_MATRIX;
11041                     donate = 1;
11042                 }
11043             } else {
11044                 ptr = rhs->v.ivec;
11045                 type = GRETL_TYPE_LIST;
11046                 donate = is_tmp_node(rhs);
11047             }
11048             break;
11049         case EMPTY:
11050             /* "null" is OK as (re-)initializer for bundle or array */
11051             if (empty_rhs_ok(targ)) {
11052                 if (targ == GRETL_TYPE_BUNDLE) {
11053                     ptr = gretl_bundle_new();
11054                     if (ptr == NULL) {
11055                         err = E_ALLOC;
11056                     }
11057                 } else {
11058                     ptr = gretl_array_new(targ, 0, &err);
11059                 }
11060                 if (!err) {
11061                     type = targ;
11062                     donate = 1;
11063                 }
11064             } else {
11065                 err = E_TYPES;
11066             }
11067             break;
11068         default:
11069             err = E_TYPES;
11070             break;
11071         }
11072     }
11073 
11074     if (!err) {
11075         /* check for result type-incompatible with user's spec */
11076         err = lhs_type_check(targ, type, BUNDLE);
11077     }
11078 
11079  push_data:
11080 
11081     if (!err) {
11082         if (gretl_is_array_type(type)) {
11083             /* revert to generic array type for the functions below */
11084             type = GRETL_TYPE_ARRAY;
11085         }
11086         if (donate) {
11087             /* it's OK to hand over the data pointer */
11088             err = gretl_bundle_donate_data(bundle, key, ptr, type, size);
11089             if (ptr == rhs->v.ptr) {
11090                 rhs->v.ptr = NULL; /* avoid freeing! */
11091             }
11092         } else {
11093             /* the data must be copied into the bundle */
11094             err = gretl_bundle_set_data(bundle, key, ptr, type, size);
11095         }
11096         if (!err && type == GRETL_TYPE_MATRIX) {
11097             /* for use by genr_get_output_matrix() */
11098             p->lh.mret = ptr;
11099         }
11100     }
11101 
11102     return err;
11103 }
11104 
set_array_value(NODE * lhs,NODE * rhs,parser * p)11105 static int set_array_value (NODE *lhs, NODE *rhs, parser *p)
11106 {
11107     NODE *lh1 = lhs->L;
11108     NODE *lh2 = lhs->R;
11109     GretlType atype = 0;
11110     GretlType type = 0;
11111     GretlType targ = 0;
11112     gretl_array *array = NULL;
11113     void *ptr = NULL;
11114     int idx = 0;
11115     int donate = 0;
11116     int err = 0;
11117 
11118     if (lh1->t != ARRAY) {
11119         return E_TYPES;
11120     }
11121 
11122     if (lh2->t == MSPEC) {
11123         /* FIXME allow a range here? */
11124         idx = mspec_get_array_index(lh2->v.mspec, &err);
11125         if (err) {
11126             return err;
11127         }
11128     } else {
11129         idx = lh2->v.xval;
11130     }
11131 
11132     array = lh1->v.a;
11133     if (array == NULL) {
11134         return E_DATA;
11135     } else if (idx <= 0 || idx > gretl_array_get_length(array)) {
11136         gretl_errmsg_sprintf(_("Index value %d is out of bounds"), idx);
11137         return E_DATA;
11138     }
11139 
11140     atype = gretl_array_get_content_type(array);
11141     targ = gretl_type_from_gen_type(p->targ);
11142     err = lhs_type_check(targ, atype, ARRAY);
11143 
11144 #if LHDEBUG
11145     fprintf(stderr, "set_array_value: array %p, idx=%d, atype=%s, targ=%s, err=%d\n",
11146             (void *) array, idx, gretl_type_get_name(atype),
11147             gretl_type_get_name(targ), err);
11148 #endif
11149 
11150     idx--; /* convert index to 0-based */
11151 
11152     if (!err && p->op != B_ASN) {
11153         GretlType ltype = 0;
11154         void *lp;
11155 
11156         lp = gretl_array_get_element(array, idx, &ltype, &err);
11157         if (p->op == B_DOTASN) {
11158             if (!err) {
11159                 if (ltype == GRETL_TYPE_MATRIX) {
11160                     err = dot_assign_to_matrix(lp, p);
11161                 } else {
11162                     err = E_TYPES;
11163                 }
11164             }
11165             return err; /* handled */
11166         }
11167         if (!err) {
11168             ptr = get_mod_assign_result(lp, ltype, rhs, NULL, p);
11169             err = p->err;
11170             if (p->op == INC || p->op == DEC) {
11171                 return err; /* handled */
11172             }
11173         }
11174         if (!err) {
11175             type = ltype;
11176             if (ptr != lp) {
11177                 donate = 1; /* donate: always right? */
11178             }
11179         }
11180         goto push_data;
11181     }
11182 
11183     if (!err && atype == GRETL_TYPE_LIST) {
11184         ptr = node_get_list(rhs, p);
11185         err = p->err;
11186         if (!err) {
11187             type = GRETL_TYPE_LIST;
11188             donate = 1;
11189         }
11190     } else if (!err) {
11191         switch (rhs->t) {
11192         case NUM:
11193             if (atype == GRETL_TYPE_MATRIX) {
11194                 ptr = gretl_matrix_from_scalar(rhs->v.xval);
11195                 type = GRETL_TYPE_MATRIX;
11196                 donate = 1;
11197             }
11198             break;
11199         case STR:
11200             ptr = rhs->v.str;
11201             type = GRETL_TYPE_STRING;
11202             donate = !reusable(p) && is_tmp_node(rhs);
11203             break;
11204         case MAT:
11205             ptr = rhs->v.m;
11206             type = GRETL_TYPE_MATRIX;
11207             donate = is_tmp_node(rhs);
11208             break;
11209         case BUNDLE:
11210             ptr = rhs->v.b;
11211             type = GRETL_TYPE_BUNDLE;
11212             break;
11213         case LIST:
11214             ptr = rhs->v.ivec;
11215             type = GRETL_TYPE_LIST;
11216             donate = is_tmp_node(rhs);
11217             break;
11218         case ARRAY:
11219             ptr = rhs->v.a;
11220             type = GRETL_TYPE_ARRAY;
11221             donate = is_tmp_node(rhs);
11222             break;
11223         default:
11224             err = E_TYPES;
11225             break;
11226         }
11227     }
11228 
11229     if (!err && type != atype) {
11230         err = E_TYPES;
11231     }
11232 
11233  push_data:
11234 
11235     if (!err) {
11236         if (donate) {
11237             /* it's OK to hand over the data pointer */
11238             err = gretl_array_set_element(array, idx, ptr, type, 0);
11239             if (ptr == rhs->v.ptr) {
11240                 rhs->v.ptr = NULL; /* gone! */
11241             }
11242         } else {
11243             /* the data must be copied into the array */
11244             err = gretl_array_set_element(array, idx, ptr, type, 1);
11245         }
11246         if (!err && type == GRETL_TYPE_MATRIX) {
11247             /* for use by genr_get_output_matrix() */
11248             p->lh.mret = ptr;
11249         }
11250     }
11251 
11252     return err;
11253 }
11254 
11255 /* setting member of list: only straight assignment is accepted */
11256 
set_list_value(NODE * lhs,NODE * rhs,parser * p)11257 static int set_list_value (NODE *lhs, NODE *rhs, parser *p)
11258 {
11259     NODE *lh1 = lhs->L;
11260     NODE *lh2 = lhs->R;
11261     int *list = NULL;
11262     int idx = 0, v = -1;
11263     int err = 0;
11264 
11265     if (p->op != B_ASN) {
11266         gretl_errmsg_sprintf(_("'%s' : not implemented for this type"),
11267                              get_opstr(p->op));
11268         return E_TYPES;
11269     }
11270 
11271     if (lh2->t == MSPEC) {
11272         idx = mspec_get_array_index(lh2->v.mspec, &err);
11273         if (err) {
11274             return err;
11275         }
11276     } else {
11277         idx = lh2->v.xval;
11278     }
11279 
11280     list = lh1->v.ivec;
11281     if (list == NULL) {
11282         return E_DATA;
11283     } else if (idx < 1 || idx > list[0]) {
11284         gretl_errmsg_sprintf(_("Index value %d is out of bounds"), idx);
11285         return E_DATA;
11286     }
11287 
11288 #if LHDEBUG
11289     fprintf(stderr, "set_list_value: list = %p, idx = %d\n",
11290             (void *) list, idx);
11291 #endif
11292 
11293     if (rhs->t == NUM) {
11294         v = node_get_int(rhs, p);
11295     } else if (rhs->t == SERIES) {
11296         v = rhs->vnum;
11297     } else {
11298         p->err = E_TYPES;
11299     }
11300 
11301     if (!p->err) {
11302         if (v < 0 || v >= p->dset->v) {
11303             gretl_errmsg_set(_("Invalid list element"));
11304             p->err = E_DATA;
11305         }
11306     }
11307 
11308 #if 0 /* we're not applying this check (yet?) */
11309     if (!p->err && gretl_function_depth() > 0) {
11310         if (!series_is_accessible_in_function(v, p->dset)) {
11311             p->err = E_DATA;
11312         }
11313     }
11314 #endif
11315 
11316     if (!p->err) {
11317         list[idx] = v;
11318     }
11319 
11320     return p->err;
11321 }
11322 
11323 /* setting element of string: only straight assignment accepted */
11324 
set_string_value(NODE * lhs,NODE * rhs,parser * p)11325 static int set_string_value (NODE *lhs, NODE *rhs, parser *p)
11326 {
11327     NODE *lh1 = lhs->L;
11328     NODE *lh2 = lhs->R;
11329     char *s1 = NULL;
11330     char *s2 = NULL;
11331     int idx = 0, err = 0;
11332 
11333     if (p->op != B_ASN) {
11334         gretl_errmsg_sprintf(_("'%s' : not implemented for this type"),
11335                              get_opstr(p->op));
11336         return E_TYPES;
11337     } else if (rhs->t != STR) {
11338         return E_TYPES;
11339     }
11340 
11341     if (lh2->t == MSPEC) {
11342         idx = mspec_get_array_index(lh2->v.mspec, &err);
11343         if (err) {
11344             return err;
11345         }
11346     } else {
11347         idx = lh2->v.xval;
11348     }
11349 
11350     s1 = lh1->v.str;
11351 
11352     if (s1 == NULL) {
11353         return E_DATA;
11354     } else if (idx < 1 || idx > g_utf8_strlen(s1, -1)) {
11355         gretl_errmsg_sprintf(_("Index value %d is out of bounds"), idx);
11356         return E_DATA;
11357     }
11358 
11359     s2 = rhs->v.str;
11360     if (g_utf8_strlen(s2, -1) != 1) {
11361         return E_INVARG;
11362     } else if (g_utf8_strlen(s1, -1) == strlen(s1) && strlen(s2) == 1) {
11363         /* simple: no multibyte characters */
11364         s1[idx-1] = s2[0];
11365     } else {
11366         /* handle the multibyte case */
11367         char *tmp = gretl_utf8_replace_char(s1, s2, idx - 1);
11368 
11369         if (strlen(tmp) <= strlen(s1)) {
11370             strcpy(s1, tmp);
11371             free(tmp);
11372         } else {
11373             user_var *uv = get_user_var_by_data(s1);
11374 
11375             if (uv != NULL) {
11376                 p->err = user_var_replace_value(uv, tmp,
11377                                                 GRETL_TYPE_STRING);
11378                 free(s1);
11379             } else {
11380                 p->err = E_DATA;
11381                 free(tmp);
11382             }
11383         }
11384     }
11385 
11386     return p->err;
11387 }
11388 
set_series_obs_value(NODE * lhs,NODE * rhs,parser * p)11389 static int set_series_obs_value (NODE *lhs, NODE *rhs, parser *p)
11390 {
11391     NODE *lh1 = lhs->L;
11392     NODE *lh2 = lhs->R;
11393     double **Z = p->dset->Z;
11394     char *label = NULL;
11395     double x = NADBL;
11396     int op = p->op;
11397     int v, t;
11398 
11399     if (lh1->t == SERIES && (lh2->t == NUM || lh2->t == MSPEC)) {
11400         ; /* OK */
11401     } else {
11402         return E_TYPES;
11403     }
11404 
11405     v = lh1->vnum;
11406     if (v <= 0 || v >= p->dset->v) {
11407         return E_DATA;
11408     } else if (object_is_const(NULL, v)) {
11409         return overwrite_err(p->dset->varname[v]);
11410     }
11411 
11412     if (lh2->t == MSPEC) {
11413         t = mspec_get_series_index(lh2->v.mspec, p);
11414     } else {
11415         t = node_get_int(lh2, p);
11416     }
11417     if (t < 1 || t > p->dset->n) {
11418         return E_DATA;
11419     }
11420     /* convert to 0-based */
11421     t--;
11422 
11423     if (rhs == NULL) {
11424         if (p->op == INC) {
11425             x = 1;
11426             op = B_ADD;
11427         } else if (p->op == DEC) {
11428             x = 1;
11429             op = B_SUB;
11430         } else {
11431             return E_TYPES; /* ? */
11432         }
11433     } else if (rhs->t == STR) {
11434         if (is_string_valued(p->dset, v)) {
11435             label = rhs->v.str;
11436         } else {
11437             return E_TYPES;
11438         }
11439     } else {
11440         x = node_get_scalar(rhs, p);
11441         if (p->err) {
11442             return p->err;
11443         }
11444     }
11445 
11446     if (is_string_valued(p->dset, v)) {
11447         if (label != NULL) {
11448             if (op != B_ASN) {
11449                 p->err = E_TYPES;
11450             } else {
11451                 p->err = series_set_string_val(p->dset, v, t, label);
11452             }
11453         } else {
11454             x = xy_calc(Z[v][t], x, op, NUM, p);
11455             if (!p->err) {
11456                 p->err = string_series_assign_value(p->dset, v, t, x);
11457             }
11458         }
11459     } else {
11460         Z[v][t] = xy_calc(Z[v][t], x, op, NUM, p);
11461     }
11462 
11463     if (p->err == 0) {
11464         /* made a change to an element of a series */
11465         p->flags |= P_OBSVAL;
11466         set_dataset_is_changed(p->dset, 1);
11467     }
11468 
11469     return p->err;
11470 }
11471 
11472 /* Here we're replacing a submatrix, by either straight or
11473    inflected assignment.
11474 
11475    @lhs must be a binary node holding the target matrix
11476    on its L branch and a matrix subspec on its R branch.
11477    @rhs must hold the replacement value: either a matrix
11478    or a scalar (or a series standing in for a matrix).
11479 */
11480 
set_matrix_chunk(NODE * lhs,NODE * rhs,parser * p)11481 static int set_matrix_chunk (NODE *lhs, NODE *rhs, parser *p)
11482 {
11483     NODE *lh1 = lhs->L;
11484     NODE *lh2 = lhs->R;
11485     gretl_matrix *m1, *m2 = NULL;
11486     matrix_subspec *spec;
11487     double rhs_x = NADBL;
11488     double complex rhs_z = NADBL;
11489     int rhs_scalar = 0;
11490     int rhs_cscalar = 0;
11491     int inflected = 0;
11492     int free_m2 = 0;
11493 
11494     if (p->op == B_HCAT || p->op == B_VCAT) {
11495         /* can't do these things on a submatrix */
11496         gretl_errmsg_sprintf(_("The operator '%s' is not valid in this context"),
11497                              get_opstr(p->op));
11498         return E_TYPES;
11499     } else if (lh1->t != MAT) {
11500         /* is this ever possible? */
11501         fprintf(stderr, "set_matrix_chunk: got %s, not matrix!\n",
11502                 getsymb(lh1->t));
11503         return E_DATA;
11504     }
11505 
11506     /* set up the target */
11507     m1 = lh1->v.m;
11508     spec = lh2->v.mspec;
11509     if (m1 == NULL || spec == NULL) {
11510         return E_DATA;
11511     }
11512 
11513     /* check the validity of the subspec we got, and
11514        adjust it if need be in the light of the
11515        dimensions of @m.
11516     */
11517     if (!spec->checked) {
11518         p->err = check_matrix_subspec(spec, m1);
11519         if (p->err) {
11520             fprintf(stderr, "set_matrix_chunk: check_matrix_subspec failed\n");
11521             return p->err;
11522         }
11523     }
11524 
11525 #if EDEBUG > 1
11526     gretl_matrix_print(m1, "m1, in set_matrix_chunk");
11527     fprintf(stderr, "op = '%s'\n", getsymb(p->op));
11528     print_mspec(spec);
11529     if (rhs != NULL) {
11530 	fprintf(stderr, "rhs type %s\n", getsymb(rhs->t));
11531 	if (rhs->t == NUM) fprintf(stderr, " value %g\n", rhs->v.xval);
11532     } else {
11533 	fprintf(stderr, "rhs NULL\n");
11534     }
11535 #endif
11536 
11537     /* Is the assignment straight or inflected?  Note that in
11538        this context there's no distinction between '=' and '.='
11539        and the latter doesn't count as inflected.
11540     */
11541     if (p->op != B_ASN && p->op != B_DOTASN) {
11542         inflected = 1;
11543     }
11544 
11545     if (p->op == INC || p->op == DEC) {
11546 	/* treat as add or subtract */
11547 	rhs_x = 1;
11548 	rhs_z = rhs_x;
11549 	rhs_scalar = 1;
11550     } else if (scalar_node(rhs)) {
11551         /* single value (could be 1 x 1 matrix) on RHS */
11552         rhs_x = (rhs->t == NUM)? rhs->v.xval: rhs->v.m->val[0];
11553         rhs_z = rhs_x;
11554         rhs_scalar = 1;
11555     } else if (cscalar_node(rhs)) {
11556         if (!m1->is_complex) {
11557             gretl_errmsg_set("Cannot assign complex values to a real matrix");
11558             p->err = E_TYPES;
11559         } else {
11560             m2 = rhs->v.m;
11561             rhs_z = rhs->v.m->z[0];
11562             rhs_cscalar = 1;
11563         }
11564     } else if (rhs->t == MAT) {
11565         /* not a scalar: get the RHS matrix */
11566         m2 = rhs->v.m;
11567         if (m2->is_complex && !m1->is_complex) {
11568             gretl_errmsg_set("Cannot assign complex values to a real matrix");
11569             p->err = E_TYPES;
11570         }
11571     } else if (rhs->t == SERIES) {
11572         /* legacy: this has long been accepted */
11573         m2 = series_to_matrix(rhs->v.xvec, p);
11574         free_m2 = 1; /* flag temporary status of @m2 */
11575     } else {
11576         p->err = E_TYPES;
11577     }
11578 
11579     if (p->err) {
11580         return p->err;
11581     }
11582 
11583     if (spec->ltype == SEL_ELEMENT) {
11584         /* assignment, plain or inflected, to a single
11585            element of target matrix.
11586         */
11587         int i = mspec_get_element(spec);
11588 
11589         if (rhs_cscalar || (rhs_scalar && m1->is_complex)) {
11590             if (!inflected) {
11591                 m1->z[i] = rhs_z;
11592             } else {
11593                 m1->z[i] = c_xy_calc(m1->z[i], rhs_z, p->op, p);
11594             }
11595         } else if (rhs_scalar) {
11596             if (!inflected) {
11597                 m1->val[i] = rhs_x;
11598             } else {
11599                 m1->val[i] = xy_calc(m1->val[i], rhs_x, p->op, MAT, p);
11600             }
11601         } else {
11602             /* here the RHS must be 1 x 1 */
11603             p->err = E_NONCONF;
11604         }
11605         return p->err; /* we're done */
11606     }
11607 
11608     if (!inflected) {
11609         if (rhs_cscalar) {
11610             return assign_scalar_to_submatrix(m1, m2, 0, spec);
11611         } else if (rhs_scalar) {
11612             return assign_scalar_to_submatrix(m1, NULL, rhs_x, spec);
11613         } else if (is_sel_dummy(spec->ltype)) {
11614             return gretl_matrix_set_part(m1, m2, 0, spec->ltype);
11615         }
11616     }
11617 
11618     if (inflected) {
11619         /* Here we're doing '+=' or some such, in which case a new
11620            submatrix must be calculated using the original
11621            submatrix @a and the newly generated matrix (or
11622            scalar value).
11623         */
11624         gretl_matrix *a = matrix_get_submatrix(m1, spec, 1, &p->err);
11625 
11626         if (!p->err) {
11627             if (rhs_scalar || rhs_cscalar) {
11628                 if (a->is_complex) {
11629                     cmatrix_xy_calc(a, a, rhs_z, 0, p->op, p);
11630                 } else {
11631                     rmatrix_xy_calc(a, a, rhs_x, 0, p->op, p);
11632                 }
11633                 m2 = a; /* assign computed matrix to m2 */
11634                 free_m2 = 1;
11635             } else {
11636                 gretl_matrix *b = NULL;
11637 
11638                 p->err = real_matrix_calc(a, m2, p->op, &b);
11639                 gretl_matrix_free(a);
11640                 /* replace RHS m2 with computed result */
11641                 if (free_m2) {
11642                     /* m2 was temp result of series conversion */
11643                     gretl_matrix_free(m2);
11644                 }
11645                 m2 = b;
11646                 free_m2 = 1;
11647             }
11648             /* we now proceed to matrix_replace_submatrix() */
11649         }
11650     }
11651 
11652     if (!p->err) {
11653         /* Write new submatrix @m2 into place: note that we come here
11654            directly if none of the special conditions above are
11655            satisfied -- for example, if the newly generated value
11656            is a matrix and the task is straight assignment. Also
11657            check for numerical "breakage" in the replacement
11658            submatrix.
11659         */
11660         p->err = matrix_replace_submatrix(m1, m2, spec);
11661     }
11662 
11663     if (free_m2) {
11664         gretl_matrix_free(m2);
11665     }
11666 
11667     return p->err;
11668 }
11669 
get_corrgm_matrix(NODE * l,NODE * m,NODE * r,parser * p)11670 static gretl_matrix *get_corrgm_matrix (NODE *l,
11671                                         NODE *m,
11672                                         NODE *r,
11673                                         parser *p)
11674 {
11675     int xcf = (r->t != EMPTY);
11676     int *list = NULL;
11677     gretl_matrix *A = NULL;
11678     int k;
11679 
11680     /* ensure we've got an order */
11681     k = node_get_int(m, p);
11682     if (p->err) {
11683         return NULL;
11684     }
11685 
11686     /* hook up list if arg1 is list */
11687     if (l->t == LIST) {
11688         list = l->v.ivec;
11689     }
11690 
11691     /* if third node is matrix, must be real col vector */
11692     if (r->t == MAT) {
11693         if (r->v.m->cols != 1) {
11694             p->err = E_NONCONF;
11695             return NULL;
11696         } else if (r->v.m->is_complex) {
11697             p->err = E_NONCONF;
11698             return NULL;
11699         }
11700     }
11701 
11702     if (!xcf) {
11703         /* acf/pacf */
11704         if (l->t == SERIES) {
11705             A = acf_matrix(l->v.xvec, k, p->dset, 0, &p->err);
11706         } else if (l->t == MAT) {
11707             A = multi_acf(l->v.m, NULL, NULL, k, &p->err);
11708         } else {
11709             /* it must be a list */
11710             A = multi_acf(NULL, list, p->dset, k, &p->err);
11711         }
11712     } else {
11713         /* cross-correlogram */
11714         void *px = NULL, *py = NULL;
11715         int xtype = SERIES;
11716 
11717         if (list != NULL) {
11718             px = list;
11719             xtype = LIST;
11720         } else if (l->t == MAT) {
11721             px = l->v.m;
11722             xtype = MAT;
11723         } else {
11724             px = l->v.xvec;
11725         }
11726 
11727         py = (r->t == MAT)? (void *) r->v.m : (void *) r->v.xvec;
11728 
11729         A = multi_xcf(px, xtype, py, r->t, p->dset, k, &p->err);
11730     }
11731 
11732     return A;
11733 }
11734 
get_density_matrix(NODE * t,double bws,int ctrl,parser * p)11735 static gretl_matrix *get_density_matrix (NODE *t, double bws,
11736                                          int ctrl, parser *p)
11737 {
11738     gretl_matrix *(*kdfunc1) (const double *, int, double,
11739                               gretlopt, int *);
11740     gretl_matrix *(*kdfunc2) (const gretl_matrix *, double,
11741                               gretlopt, int *);
11742     gretlopt opt = ctrl ? OPT_O : OPT_NONE;
11743     gretl_matrix *m = NULL;
11744     gretl_matrix *X = NULL;
11745     const double *x = NULL;
11746     int free_X = 0;
11747     int n = 0;
11748 
11749     kdfunc1 = NULL;
11750     kdfunc2 = NULL;
11751 
11752     if (t->t == SERIES) {
11753         n = sample_size(p->dset);
11754         x = t->v.xvec + p->dset->t1;
11755     } else if (t->t == LIST) {
11756         X = gretl_matrix_data_subset(t->v.ivec, p->dset,
11757                                      p->dset->t1, p->dset->t2,
11758                                      M_MISSING_SKIP, &p->err);
11759         free_X = 1;
11760     } else {
11761         /* matrix */
11762         if (t->v.m->is_complex) {
11763             p->err = E_CMPLX;
11764         } else {
11765             n = gretl_vector_get_length(t->v.m);
11766             if (n > 0) {
11767                 /* vector */
11768                 x = t->v.m->val;
11769             } else {
11770                 X = t->v.m;
11771             }
11772         }
11773     }
11774 
11775     if (!p->err) {
11776         if (X != NULL) {
11777             kdfunc2 = get_plugin_function("multiple_kd_matrix");
11778         } else if (!p->err) {
11779             kdfunc1 = get_plugin_function("kernel_density_matrix");
11780         }
11781         if (kdfunc2 == NULL && kdfunc1 == NULL) {
11782             p->err = E_FOPEN;
11783         } else if (X != NULL) {
11784             m = (*kdfunc2)(X, bws, opt, &p->err);
11785         } else {
11786             m = (*kdfunc1)(x, n, bws, opt, &p->err);
11787         }
11788     }
11789 
11790     if (free_X) {
11791         gretl_matrix_free(X);
11792     }
11793 
11794     return m;
11795 }
11796 
aggregate_discrete_check(const int * list,const DATASET * dset)11797 static int aggregate_discrete_check (const int *list, const DATASET *dset)
11798 {
11799     int i, vi;
11800 
11801     for (i=1; i<=list[0]; i++) {
11802         vi = list[i];
11803         if (!accept_as_discrete(dset, vi, 0)) {
11804             gretl_errmsg_sprintf(_("The variable '%s' is not discrete"),
11805                                  dset->varname[vi]);
11806             return E_DATA;
11807         }
11808     }
11809 
11810     return 0;
11811 }
11812 
mshape_scalar(double x,int r,int c,int * err)11813 static gretl_matrix *mshape_scalar (double x, int r, int c, int *err)
11814 {
11815     gretl_matrix *m = gretl_matrix_alloc(r, c);
11816 
11817     if (m == NULL) {
11818         *err = E_ALLOC;
11819     } else {
11820         int i, n = r * c;
11821 
11822         for (i=0; i<n; i++) {
11823             m->val[i] = x;
11824         }
11825     }
11826 
11827     return m;
11828 }
11829 
node_get_int_or_series(int * ip,double ** vecp,NODE * n,parser * p)11830 static void node_get_int_or_series (int *ip, double **vecp,
11831 				    NODE *n, parser *p)
11832 {
11833     if (scalar_node(n)) {
11834 	*ip = node_get_int(n, p);
11835     } else if (n->t == SERIES) {
11836 	*vecp = n->v.xvec;
11837     } else {
11838 	p->err = E_TYPES;
11839     }
11840 }
11841 
11842 /* eval_3args_func: evaluate a built-in function that has three
11843    arguments. The @post_process flag is a convenience for the
11844    case where the function in question returns a matrix: it
11845    centralizes the creation or retrieval of an "aux node" of the
11846    right type, and attaches the computed matrix @A to it. This
11847    flag must be set to zero for all cases where the function does
11848    NOT return a matrix. Conversely, when a function DOES return
11849    a matrix it should assign this to @A, and leave the aux node
11850    business to the post-processor.
11851 */
11852 
eval_3args_func(NODE * l,NODE * m,NODE * r,int f,parser * p)11853 static NODE *eval_3args_func (NODE *l, NODE *m, NODE *r,
11854                               int f, parser *p)
11855 {
11856     NODE *save_aux = p->aux;
11857     NODE *ret = NULL;
11858     gretl_matrix *A = NULL;
11859     int post_process = 1;
11860 
11861     if (f == F_MSHAPE) {
11862         if (l->t != MAT && l->t != NUM) {
11863             node_type_error(f, 1, MAT, l, p);
11864         } else if (!scalar_node(m)) {
11865             node_type_error(f, 2, NUM, m, p);
11866         } else if (!null_node(r) && !scalar_node(r)) {
11867             node_type_error(f, 3, NUM, r, p);
11868         } else {
11869             int n, k2, k1 = node_get_int(m, p);
11870 
11871             if (scalar_node(r)) {
11872                 k2 = node_get_int(r, p);
11873             } else if (l->t == NUM) {
11874                 k2 = 1;
11875             } else {
11876                 n = l->v.m->rows * l->v.m->cols;
11877                 if (n % k1 == 0) {
11878                     k2 = n / k1;
11879                 } else {
11880                     p->err = E_INVARG;
11881                 }
11882             }
11883             if (!p->err) {
11884                 if (l->t == NUM) {
11885                     A = mshape_scalar(l->v.xval, k1, k2, &p->err);
11886                 } else {
11887                     A = gretl_matrix_shape(l->v.m, k1, k2, &p->err);
11888                 }
11889             }
11890         }
11891     } else if (f == F_TRIMR) {
11892         if (l->t != MAT) {
11893             node_type_error(f, 1, MAT, l, p);
11894         } else if (!scalar_node(m)) {
11895             node_type_error(f, 2, NUM, m, p);
11896         } else if (!scalar_node(r)) {
11897             node_type_error(f, 3, NUM, r, p);
11898         } else {
11899             int k1 = node_get_int(m, p);
11900             int k2 = node_get_int(r, p);
11901 
11902             if (!p->err) {
11903                 A = gretl_matrix_trim_rows(l->v.m, k1, k2, &p->err);
11904             }
11905         }
11906     } else if (f == F_SVD) {
11907         /* note: the complex case is supported */
11908         gretl_matrix *lm = node_get_matrix(l, p, 0, 1);
11909         gretl_matrix *U = NULL;
11910         gretl_matrix *V = NULL;
11911 
11912         if (!p->err) {
11913             if (m->t == U_ADDR) {
11914                 U = ptr_node_get_matrix(m, p);
11915             } else if (m->t != EMPTY) {
11916                 node_type_error(f, 2, U_ADDR, m, p);
11917             }
11918         }
11919         if (!p->err) {
11920             if (r->t == U_ADDR) {
11921                 V = ptr_node_get_matrix(r, p);
11922             } else if (r->t != EMPTY) {
11923                 node_type_error(f, 3, U_ADDR, r, p);
11924             }
11925         }
11926         if (!p->err) {
11927             A = user_matrix_SVD(lm, U, V, &p->err);
11928         }
11929     } else if (f == F_TOEPSOLV || f == F_VARSIMUL) {
11930         gretl_matrix *m1 = node_get_real_matrix(l, p, 0, 1);
11931         gretl_matrix *m2 = node_get_real_matrix(m, p, 1, 2);
11932         gretl_matrix *m3 = node_get_real_matrix(r, p, 2, 3);
11933 
11934         if (!p->err) {
11935             if (f == F_TOEPSOLV) {
11936                 A = gretl_toeplitz_solve(m1, m2, m3, &p->err);
11937             } else {
11938                 A = gretl_matrix_varsimul(m1, m2, m3, &p->err);
11939             }
11940         }
11941     } else if (f == F_EIGEN || f == F_EIGGEN) {
11942         gretl_matrix *lm = node_get_matrix(l, p, 0, 1);
11943         gretl_matrix *v1 = NULL, *v2 = NULL;
11944 
11945         if (l->t != MAT) {
11946             node_type_error(f, 1, MAT, l, p);
11947         } else {
11948             if (!null_node(m)) {
11949                 v1 = ptr_node_get_matrix(m, p);
11950             }
11951             if (!null_node(r)) {
11952                 v2 = ptr_node_get_matrix(r, p);
11953             }
11954         }
11955         if (!p->err) {
11956             if (f == F_EIGEN) {
11957                 if (lm->is_complex) {
11958                     A = gretl_zgeev(lm, v1, v2, &p->err);
11959                 } else {
11960                     A = gretl_dgeev(lm, v1, v2, &p->err);
11961                 }
11962             } else {
11963                 /* legacy eigengen: real input only */
11964                 if (lm->is_complex) {
11965                     p->err = E_CMPLX;
11966                 } else {
11967                     A = old_eigengen(lm, v1, v2, &p->err);
11968                 }
11969             }
11970         }
11971     } else if (f == F_SCHUR) {
11972         gretl_matrix *Z = NULL;
11973         gretl_matrix *W = NULL;
11974 
11975         if (l->t != MAT || !l->v.m->is_complex) {
11976             node_type_error(f, 1, MAT, l, p);
11977         } else {
11978             if (!null_node(m)) {
11979                 Z = ptr_node_get_matrix(m, p);
11980             }
11981             if (!null_node(r)) {
11982                 W = ptr_node_get_matrix(r, p);
11983             }
11984         }
11985         if (!p->err) {
11986             A = gretl_zgees(l->v.m, Z, W, &p->err);
11987         }
11988     } else if (f == F_CORRGM) {
11989         if (l->t != SERIES && l->t != MAT && l->t != LIST) {
11990             node_type_error(f, 1, SERIES, l, p);
11991         } else if (!scalar_node(m)) {
11992             node_type_error(f, 2, NUM, m, p);
11993         } else if (r->t != EMPTY && r->t != SERIES && r->t != MAT) {
11994             node_type_error(f, 3, SERIES, r, p);
11995         } else {
11996             A = get_corrgm_matrix(l, m, r, p);
11997         }
11998     } else if (f == F_SEQ) {
11999         if (!scalar_node(l)) {
12000             node_type_error(f, 1, NUM, l, p);
12001         } else if (!scalar_node(m)) {
12002             node_type_error(f, 2, NUM, m, p);
12003         } else if (!null_or_scalar(r)) {
12004             node_type_error(f, 3, NUM, r, p);
12005         } else {
12006             double start = node_get_scalar(l, p);
12007             double end = node_get_scalar(m, p);
12008             double step = (!null_node(r))? node_get_scalar(r, p) : 1.0;
12009 
12010             if (!p->err) {
12011                 A = gretl_matrix_seq(start, end, step, &p->err);
12012             }
12013         }
12014     } else if (f == F_STRNCMP) {
12015         post_process = 0;
12016         if (l->t != STR) {
12017             node_type_error(f, 1, STR, l, p);
12018         } else if (m->t != STR) {
12019             node_type_error(f, 2, STR, m, p);
12020         } else if (!null_or_scalar(r)) {
12021             node_type_error(f, 3, NUM, r, p);
12022         } else {
12023             ret = aux_scalar_node(p);
12024             if (ret != NULL) {
12025                 if (!null_node(r)) {
12026                     int len = node_get_int(r, p);
12027 
12028                     if (!p->err) {
12029                         ret->v.xval = strncmp(l->v.str, m->v.str, len);
12030                     }
12031                 } else {
12032                     ret->v.xval = strcmp(l->v.str, m->v.str);
12033                 }
12034             }
12035         }
12036     } else if (f == F_WEEKDAY || f == F_ISOWEEK) {
12037         post_process = 0;
12038         if (scalar_node(l) && scalar_node(m) && scalar_node(r)) {
12039             ret = aux_scalar_node(p);
12040             if (ret != NULL) {
12041                 int yr = node_get_int(l, p);
12042                 int mo = node_get_int(m, p);
12043                 int day = node_get_int(r, p);
12044 
12045                 if (!p->err && f == F_WEEKDAY) {
12046                     int julian = 0;
12047 
12048                     if (yr < 0) {
12049                         yr = -yr;
12050                         julian = 1;
12051                     }
12052                     ret->v.xval = day_of_week(yr, mo, day, julian, &p->err);
12053                 } else if (!p->err) {
12054                     ret->v.xval = iso_week_number(yr, mo, day, &p->err);
12055                 }
12056             }
12057         } else if (l->t == SERIES && m->t == SERIES && r->t == SERIES) {
12058             reset_p_aux(p, save_aux);
12059             ret = aux_series_node(p);
12060             if (ret != NULL && f == F_WEEKDAY) {
12061                 p->err = fill_day_of_week_array(ret->v.xvec,
12062                                                 l->v.xvec,
12063                                                 m->v.xvec,
12064                                                 r->v.xvec,
12065                                                 p->dset);
12066             } else if (ret != NULL) {
12067                 p->err = fill_isoweek_array(ret->v.xvec,
12068                                             l->v.xvec,
12069                                             m->v.xvec,
12070                                             r->v.xvec,
12071                                             p->dset);
12072             }
12073         } else {
12074             p->err = E_TYPES;
12075         }
12076     } else if (f == F_DAYSPAN) {
12077 	guint32 ed1 = node_get_guint32(l, p);
12078 	guint32 ed2 = node_get_guint32(m, p);
12079 	int wkdays = node_get_int(r, p);
12080 
12081 	post_process = 0;
12082 	if (!p->err) {
12083 	    ret = aux_scalar_node(p);
12084 	}
12085 	if (!p->err) {
12086 	    ret->v.xval = day_span(ed1, ed2, wkdays, &p->err);
12087 	}
12088     } else if (f == F_SMPLSPAN) {
12089         post_process = 0;
12090         if (l->t == STR && m->t == STR && r->t == NUM) {
12091             ret = aux_scalar_node(p);
12092             if (ret != NULL) {
12093                 int pd = node_get_int(r, p);
12094 
12095                 if (!p->err) {
12096                     ret->v.xval = sample_span(l->v.str, m->v.str,
12097                                               pd, &p->err);
12098                 }
12099             }
12100         } else {
12101             p->err = E_TYPES;
12102         }
12103     } else if (f == F_KDENSITY) {
12104         if (l->t != SERIES && l->t != LIST && l->t != MAT) {
12105             node_type_error(f, 1, SERIES, l, p);
12106         } else if (m->t != NUM && m->t != EMPTY) {
12107             node_type_error(f, 2, NUM, m, p);
12108         } else if (r->t != NUM && r->t != EMPTY) {
12109             node_type_error(f, 3, NUM, r, p);
12110         } else {
12111             double bws = (m->t != EMPTY)? m->v.xval : 1.0;
12112             int ctrl = (r->t != EMPTY)? (int) r->v.xval : 0;
12113 
12114             A = get_density_matrix(l, bws, ctrl, p);
12115         }
12116     } else if (f == F_MONTHLEN) {
12117         double *movec = NULL, *yrvec = NULL;
12118         int wkdays, julian = 0;
12119         int mo = 0, yr = 0;
12120         int rettype = NUM;
12121 
12122         post_process = 0;
12123         wkdays = node_get_int(r, p);
12124         if (!p->err && (wkdays < 5 || wkdays > 7)) {
12125             p->err = E_INVARG;
12126         }
12127         if (!p->err) {
12128 	    node_get_int_or_series(&mo, &movec, l, p);
12129 	    if (!p->err) {
12130 		if (movec != NULL) {
12131 		    rettype = SERIES;
12132 		} else if (mo < 1 || mo > 12) {
12133 		    p->err = E_INVARG;
12134 		}
12135 	    }
12136 	}
12137         if (!p->err) {
12138 	    node_get_int_or_series(&yr, &yrvec, m, p);
12139 	    if (!p->err) {
12140 		if (yrvec != NULL) {
12141 		    rettype = SERIES;
12142 		} else if (yr < 0) {
12143                     yr = -yr;
12144                     julian = 1;
12145                 }
12146             }
12147         }
12148 	reset_p_aux(p, save_aux);
12149         if (!p->err && rettype == NUM) {
12150             ret = aux_scalar_node(p);
12151             if (ret != NULL) {
12152                 ret->v.xval = get_days_in_month(mo, yr, wkdays, julian);
12153             }
12154         } else if (!p->err) {
12155             ret = aux_series_node(p);
12156             if (ret != NULL) {
12157 		p->err = fill_monthlen_array(ret->v.xvec,
12158 					     p->dset->t1, p->dset->t2,
12159 					     wkdays, mo, yr,
12160 					     movec, yrvec,
12161 					     julian);
12162 	    }
12163          }
12164     } else if (f == F_SETNOTE || f == F_BRENAME) {
12165         post_process = 0;
12166         if (l->t != BUNDLE) {
12167             node_type_error(f, 1, BUNDLE, l, p);
12168         } else if (m->t != STR) {
12169             node_type_error(f, 2, STR, m, p);
12170         } else if (r->t != STR) {
12171             node_type_error(f, 3, STR, r, p);
12172         } else {
12173             reset_p_aux(p, save_aux);
12174             ret = aux_scalar_node(p);
12175             if (!p->err && f == F_SETNOTE) {
12176                 ret->v.xval = gretl_bundle_set_note(l->v.b, m->v.str, r->v.str);
12177             } else if (!p->err) {
12178                 p->err = gretl_bundle_rekey_data(l->v.b, m->v.str, r->v.str);
12179                 if (!p->err) {
12180                     ret->v.xval = 0;
12181                 }
12182             }
12183         }
12184     } else if (f == F_BWFILT) {
12185         gretl_matrix *tmp = NULL;
12186 
12187         post_process = 0;
12188         if (l->t != SERIES) {
12189             if (l->t == MAT) {
12190                 cast_to_series(l, f, &tmp, NULL, NULL, p);
12191             } else {
12192                 node_type_error(f, 1, SERIES, l, p);
12193             }
12194         } else if (m->t != NUM) {
12195             node_type_error(f, 2, NUM, m, p);
12196         } else if (r->t != NUM) {
12197             node_type_error(f, 3, NUM, r, p);
12198         } else {
12199             ret = aux_series_node(p);
12200             if (!p->err) {
12201                 p->err = butterworth_filter(l->v.xvec, ret->v.xvec, p->dset,
12202                                             m->v.xval, r->v.xval);
12203             }
12204         }
12205         if (tmp != NULL) {
12206             l->v.m = tmp;
12207         }
12208     } else if (f == F_MLAG) {
12209         gretl_matrix *m1 = node_get_real_matrix(l, p, 0, 1);
12210         gretl_matrix *m2 = node_get_real_matrix(m, p, 1, 2);
12211 
12212         if (p->err) {
12213             ; /* skip the rest */
12214         } else if (r->t != NUM && r->t != EMPTY) {
12215             /* optional scalar */
12216             node_type_error(f, 3, NUM, r, p);
12217         } else {
12218             double missval = (r->t == NUM)? r->v.xval : 0.0;
12219 
12220             A = gretl_matrix_lag(m1, m2, OPT_L, missval);
12221         }
12222     } else if (f == F_LRCOVAR) {
12223         gretl_matrix *mc = node_get_real_matrix(l, p, 0, 1);
12224         int d = 1; /* demean the matrix arg? */
12225 
12226         if (!p->err) {
12227             d = node_get_bool(r, p, d);
12228         }
12229         if (!p->err) {
12230             A = long_run_covariance(mc, d, &p->err);
12231         }
12232     } else if (f == F_EIGSOLVE) {
12233         gretl_matrix *m1 = node_get_real_matrix(l, p, 0, 1);
12234         gretl_matrix *m2 = node_get_real_matrix(m, p, 1, 2);
12235 
12236         if (p->err) {
12237             ; /* skip the rest */
12238         } else if (r->t != EMPTY && r->t != U_ADDR) {
12239             /* optional matrix-pointer */
12240             node_type_error(f, 3, U_ADDR, r, p);
12241         } else {
12242             gretl_matrix *V = NULL;
12243 
12244             if (r->t == U_ADDR) {
12245                 V = ptr_node_get_matrix(r, p);
12246             }
12247             if (!p->err) {
12248                 A = user_gensymm_eigenvals(m1, m2, V, &p->err);
12249             }
12250         }
12251     } else if (f == F_PRINCOMP) {
12252         if (l->t != MAT) {
12253             node_type_error(f, 1, MAT, l, p);
12254         } else if (m->t != NUM) {
12255             node_type_error(f, 2, NUM, m, p);
12256         } else if (r->t != EMPTY && r->t != NUM) {
12257             /* optional boolean */
12258             node_type_error(f, 3, NUM, r, p);
12259         } else {
12260             int cov = null_node(r) ? 0 : node_get_int(r, p);
12261             gretlopt opt = cov ? OPT_V : OPT_NONE;
12262             int k = node_get_int(m, p);
12263 
12264             if (!p->err) {
12265                 A = gretl_matrix_pca(l->v.m, k, opt, &p->err);
12266             }
12267         }
12268     } else if (f == F_HALTON) {
12269         if (l->t != NUM) {
12270             node_type_error(f, 1, NUM, l, p);
12271         } else if (m->t != NUM) {
12272             node_type_error(f, 2, NUM, m, p);
12273         } else if (r->t != EMPTY && r->t != NUM) {
12274             /* optional offset */
12275             node_type_error(f, 3, NUM, r, p);
12276         } else {
12277             int offset = null_node(r) ? 10 : node_get_int(r, p);
12278             int rows = node_get_int(l, p);
12279             int cols = node_get_int(m, p);
12280 
12281             if (!p->err) {
12282                 A = halton_matrix(rows, cols, offset, &p->err);
12283             }
12284         }
12285     } else if (f == F_IWISHART) {
12286         if (l->t != MAT && l->t != NUM) {
12287             node_type_error(f, 1, MAT, l, p);
12288         } else if (!scalar_node(m)) {
12289             node_type_error(f, 2, NUM, m, p);
12290         } else if (r->t != EMPTY && r->t != NUM) {
12291             /* optional number of replications */
12292             node_type_error(f, 3, NUM, r, p);
12293         } else {
12294             gretl_matrix *S = node_get_real_matrix(l, p, 0, 0);
12295             int v = node_get_int(m, p);
12296             int N = null_node(r) ? 0 : node_get_int(r, p);
12297 
12298             if (!p->err) {
12299                 if (N == 0) {
12300                     A = inverse_wishart_matrix(S, v, &p->err);
12301                 } else {
12302                     A = inverse_wishart_sequence(S, v, N, &p->err);
12303                 }
12304             }
12305         }
12306     } else if (f == F_AGGRBY) {
12307         if (l->t != SERIES && l->t != LIST && !null_node(l)) {
12308             node_type_error(f, 1, SERIES, l, p);
12309         } else if (m->t != SERIES && m->t != LIST) {
12310             node_type_error(f, 2, SERIES, m, p);
12311         } else if (!null_or_string(r)) {
12312             node_type_error(f, 3, STR, r, p);
12313         } else {
12314             const char *fncall = NULL;
12315             const double *x = NULL;
12316             const double *y = NULL;
12317             const int *xlist = NULL;
12318             const int *ylist = NULL;
12319 
12320             if (r->t == STR) {
12321                 fncall = r->v.str;
12322             }
12323             if (l->t == SERIES) {
12324                 x = l->v.xvec;
12325             } else if (l->t == LIST) {
12326                 xlist = l->v.ivec;
12327             }
12328             if (m->t == SERIES) {
12329                 y = m->v.xvec;
12330             } else {
12331                 ylist = m->v.ivec;
12332                 p->err = aggregate_discrete_check(ylist, p->dset);
12333             }
12334 
12335             if (!p->err) {
12336                 A = aggregate_by(x, y, xlist, ylist, fncall,
12337                                  p->dset, &p->err);
12338             }
12339         }
12340     } else if (f == F_SUBSTR) {
12341 	post_process = 0;
12342         if (l->t != STR) {
12343             node_type_error(f, 1, STR, l, p);
12344         } else if (!scalar_node(m)) {
12345             node_type_error(f, 2, NUM, m, p);
12346         } else if (!scalar_node(r)) {
12347             node_type_error(f, 3, NUM, r, p);
12348         } else {
12349             reset_p_aux(p, save_aux);
12350             ret = aux_string_node(p);
12351             if (ret != NULL) {
12352                 int ini = node_get_int(m, p);
12353                 int fin = node_get_int(r, p);
12354 
12355                 if (!p->err) {
12356                     ret->v.str = gretl_substring(l->v.str, ini, fin, &p->err);
12357                 }
12358             }
12359         }
12360     } else if (f == F_MWEIGHTS) {
12361         if (!scalar_node(l)) {
12362             node_type_error(f, 1, NUM, l, p);
12363         } else if (m->t != MAT) {
12364             node_type_error(f, 2, MAT, m, p);
12365         } else if (!scalar_node(r) && r->t != STR) {
12366             node_type_error(f, 3, NUM, r, p);
12367         } else {
12368             int length = node_get_int(l, p);
12369             int method = node_get_midas_method(r, p);
12370             gretl_matrix *wm = node_get_real_matrix(m, p, 1, 2);
12371 
12372             if (!p->err) {
12373                 A = midas_weights(length, wm, method, &p->err);
12374             }
12375         }
12376     } else if (f == F_MGRADIENT) {
12377         if (!scalar_node(l)) {
12378             node_type_error(f, 1, NUM, l, p);
12379         } else if (m->t != MAT) {
12380             node_type_error(f, 2, MAT, m, p);
12381         } else if (!scalar_node(r) && r->t != STR) {
12382             node_type_error(f, 3, NUM, r, p);
12383         } else {
12384             int length = node_get_int(l, p);
12385             int method = node_get_midas_method(r, p);
12386             gretl_matrix *gm = node_get_real_matrix(m, p, 1, 2);
12387 
12388             if (!p->err) {
12389                 A = midas_gradient(length, gm, method, &p->err);
12390             }
12391         }
12392     } else if (f == F_RESAMPLE) {
12393         int blocklen = 0, draws = 0;
12394 
12395         if (l->t != MAT) {
12396             node_type_error(f, 1, MAT, l, p);
12397         }
12398         if (!p->err && !null_node(m)) {
12399             blocklen = node_get_int(m, p);
12400         }
12401         if (!p->err && !null_node(r)) {
12402             draws = node_get_int(r, p);
12403         }
12404         if (!p->err) {
12405             if (blocklen != 0) {
12406                 A = gretl_matrix_block_resample(l->v.m, blocklen, draws, &p->err);
12407             } else {
12408                 A = gretl_matrix_resample(l->v.m, draws, &p->err);
12409             }
12410         }
12411     } else if (f == HF_REGLS) {
12412         post_process = 0;
12413         if (null_node(l) && null_node(m) && null_node(r)) {
12414             /* doing automatic MPI: no args needed */
12415             int (*regfunc) (PRN *);
12416 
12417             regfunc = get_plugin_function("regls_xv_mpi");
12418             if (regfunc == NULL) {
12419                 p->err = E_FOPEN;
12420             } else {
12421                 p->err = regfunc(p->prn);
12422             }
12423         } else if (l->t != MAT || m->t != MAT || r->t != BUNDLE) {
12424             /* otherwise three args needed */
12425             p->err = E_TYPES;
12426         } else {
12427             int (*regfunc) (const gretl_matrix *, const gretl_matrix *,
12428                             gretl_bundle *, PRN *);
12429 
12430             regfunc = get_plugin_function("gretl_regls");
12431             if (regfunc == NULL) {
12432                 p->err = E_FOPEN;
12433             } else {
12434                 p->err = regfunc(l->v.m, m->v.m, r->v.b, p->prn);
12435             }
12436         }
12437         if (!p->err) {
12438             ret = aux_scalar_node(p);
12439             ret->v.xval = 0;
12440         }
12441     } else if (f == F_STACK) {
12442         int length = 0;
12443         int offset = 0;
12444         int *list = NULL;
12445 
12446         post_process = 0;
12447         ret = aux_empty_series_node(p);
12448         list = node_get_list(l, p);
12449         if (null_node(m)) {
12450             p->err = E_ARGS;
12451         } else {
12452             length = node_get_int(m, p);
12453         }
12454         if (!p->err && !null_node(r)) {
12455             offset = node_get_int(r, p);
12456         }
12457         if (!p->err) {
12458             p->err = build_stacked_series(&ret->v.xvec, list, length, offset,
12459                                           p->dset);
12460         }
12461         free(list);
12462     } else if (f == F_VMA) {
12463 	if (l->t != MAT) {
12464 	    /* matrix A, required */
12465 	    node_type_error(f, 1, MAT, l, p);
12466 	} else if (m->t != MAT && m->t != EMPTY) {
12467 	    /* matrix C, optional */
12468 	    node_type_error(f, 2, MAT, m, p);
12469 	} else if (r->t != NUM && r->t != EMPTY) {
12470 	    /* horizon, optional */
12471 	    node_type_error(f, 3, NUM, r, p);
12472 	} else {
12473 	    gretl_matrix *compan_top = node_get_real_matrix(l, p, 0, 1);
12474 	    int horizon = null_node(r) ? 24: node_get_int(r, p);
12475 	    int n = compan_top->rows;
12476             gretl_matrix *C = NULL;
12477 
12478             if (m->t != EMPTY) {
12479                 C = node_get_real_matrix(m, p, 1, 2);
12480                 if (C->rows != n || C->cols !=n) {
12481                     p->err = E_NONCONF;
12482                 }
12483             }
12484 	    if (!p->err) {
12485                 A = vma_rep(compan_top, C, horizon, &p->err);
12486 	    }
12487         }
12488     } else if (f == F_BCHECK) {
12489 	gretl_array *reqd = NULL;
12490 
12491 	post_process = 0;
12492 	if (l->t != U_ADDR || l->L->t != BUNDLE) {
12493 	    node_type_error(f, 1, BUNDLE, l, p);
12494 	} else if (m->t != BUNDLE) {
12495 	    node_type_error(f, 2, BUNDLE, m, p);
12496 	} else if (!null_node(r) && r->t != ARRAY) {
12497 	    node_type_error(f, 3, ARRAY, r, p);
12498 	} else {
12499 	    ret = aux_scalar_node(p);
12500 	}
12501 	if (!p->err && !null_node(r)) {
12502 	    reqd = r->v.a;
12503 	}
12504 	if (!p->err) {
12505 	    ret->v.xval = gretl_bundle_extract_args(l->L->v.b, m->v.b,
12506 						    reqd, p->prn, &p->err);
12507         }
12508     }
12509 
12510     if (post_process) {
12511 	if (!p->err) {
12512 	    reset_p_aux(p, save_aux);
12513 	    ret = aux_matrix_node(p);
12514 	    if (!p->err) {
12515 		ret->v.m = A;
12516 	    }
12517 	}
12518 	if (p->err) {
12519 	    /* don't leak memory on error */
12520 	    gretl_matrix_free(A);
12521 	}
12522     }
12523 
12524     return ret;
12525 }
12526 
geoplot_node(NODE * l,NODE * m,NODE * r,parser * p)12527 static NODE *geoplot_node (NODE *l, NODE *m, NODE *r, parser *p)
12528 {
12529     NODE *ret = aux_scalar_node(p);
12530 
12531     if (!p->err) {
12532         const char *mapfile = NULL;
12533         gretl_bundle *mapbun = NULL;
12534         double *payload = NULL;
12535         gretl_bundle *opts = NULL;
12536 
12537 	if (l->t == STR || l->t == BUNDLE) {
12538 	    /* map-fname-or-bundle [,series] [,options] */
12539 	    if (l->t == STR) {
12540 		mapfile = l->v.str;
12541 	    } else {
12542 		mapbun = l->v.b;
12543 	    }
12544 	    if (!null_node(m)) {
12545 		if (m->t == SERIES) {
12546 		    payload = m->v.xvec;
12547 		} else if (m->t == BUNDLE) {
12548 		    opts = m->v.b;
12549 		} else {
12550 		    p->err = E_INVARG;
12551 		}
12552 	    }
12553 	    if (!p->err && !null_node(r)) {
12554 		if (opts == NULL) {
12555 		    opts = r->v.b;
12556 		} else {
12557 		    p->err = E_INVARG;
12558 		}
12559 	    }
12560 	} else if (l->t == SERIES) {
12561 	    /* series [,options] (map is implicit) */
12562 	    payload = l->v.xvec;
12563 	    if (!null_node(m)) {
12564 		if (m->t == BUNDLE) {
12565 		    opts = m->v.b;
12566 		} else {
12567 		    p->err = E_INVARG;
12568 		}
12569 	    }
12570 	    if (!p->err && !null_node(r)) {
12571 		p->err = E_INVARG;
12572 	    }
12573 	} else if (null_node(l) && null_node(m) && null_node(r)) {
12574 	    ; /* implicit map, no payload, no options */
12575 	} else {
12576 	    p->err = E_INVARG;
12577 	}
12578 
12579         if (!p->err) {
12580             p->err = ret->v.xval = geoplot_driver(mapfile, mapbun, payload,
12581                                                   p->dset, opts);
12582 	}
12583     }
12584 
12585     return ret;
12586 }
12587 
scan_to_vector(NODE * n,const char * fmt,const char * arg,int * err)12588 static int scan_to_vector (NODE *n, const char *fmt,
12589                            const char *arg, int *err)
12590 {
12591     gretl_matrix *m = NULL;
12592     user_var *uvar = NULL;
12593     char **S = NULL;
12594     int ns = 0;
12595     int nmax = 0;
12596 
12597     uvar = get_user_var_of_type_by_name(arg, GRETL_TYPE_MATRIX);
12598     if (uvar == NULL) {
12599         *err = E_INVARG;
12600         return 0;
12601     }
12602 
12603     if (gretl_array_get_type(n->v.a) != GRETL_TYPE_STRINGS) {
12604         *err = E_TYPES;
12605     } else {
12606         S = gretl_array_get_strings(n->v.a, &ns);
12607         m = vector_from_strings(S, ns, fmt, &nmax, err);
12608     }
12609 
12610     if (!*err) {
12611         *err = user_var_replace_value(uvar, m, GRETL_TYPE_MATRIX);
12612     }
12613 
12614     return nmax;
12615 }
12616 
eval_print_scan(NODE * l,NODE * m,NODE * r,int f,parser * p)12617 static NODE *eval_print_scan (NODE *l, NODE *m, NODE *r, int f, parser *p)
12618 {
12619     NODE *ret;
12620 
12621     if (f == F_SPRINTF) {
12622         ret = aux_string_node(p);
12623     } else {
12624         ret = aux_scalar_node(p);
12625     }
12626 
12627     if (ret != NULL) {
12628         const char *fmt = m->v.str;
12629         const char *lstr = NULL;
12630         int n = 0;
12631 
12632         if (l != NULL && l->t == ARRAY) {
12633             /* scanning array of strings to vector */
12634             n = scan_to_vector(l, fmt, r->v.str, &p->err);
12635             goto finish;
12636         } else if (l != NULL) {
12637             /* sscanf() only */
12638             if (l->t == STR) {
12639                 lstr = l->v.str;
12640             } else {
12641                 p->err = E_INVARG;
12642             }
12643         }
12644 
12645         if (!p->err) {
12646             const char *args = NULL;
12647 
12648             if (!null_node(r)) {
12649                 args = r->v.str;
12650             }
12651             if (f == F_SSCANF) {
12652                 p->err = do_sscanf(lstr, fmt, args, p->dset, &n);
12653             } else if (f == F_SPRINTF) {
12654                 ret->v.str = do_sprintf_function(fmt, args, p->dset, &p->err);
12655             } else {
12656                 p->err = do_printf(fmt, args, p->dset, p->prn, &n);
12657             }
12658         }
12659 
12660     finish:
12661 
12662         if (!p->err && f != F_SPRINTF) {
12663             ret->v.xval = n;
12664         }
12665     }
12666 
12667     return ret;
12668 }
12669 
x_to_period(double x,char c,int * julian,int * err)12670 static int x_to_period (double x, char c, int *julian, int *err)
12671 {
12672     if (julian != NULL && c == 'y') {
12673         if (x < 0) {
12674             *julian = 1;
12675             x = -x;
12676         } else {
12677             *julian = 0;
12678         }
12679     }
12680 
12681     if (na(x)) {
12682         /* note: error not flagged here */
12683         return -1;
12684     } else if (x < 0 || fabs(x) > INT_MAX) {
12685         *err = E_INVARG;
12686         return -1;
12687     } else {
12688         int k = x;
12689         int ret = x;
12690 
12691         if (c == 'y' && k <= 0) {
12692             ret = -1;
12693         } else if (c == 'm' && (k < 1 || k > 12)) {
12694             ret = -1;
12695         } else if (c == 'd' && (k < 1 || k > 31)) {
12696             ret = -1;
12697         }
12698 
12699         if (ret <= 0) {
12700             fprintf(stderr, "epochday: got %c = %d!\n", c, k);
12701             *err = E_INVARG;
12702         }
12703 
12704         return ret;
12705     }
12706 }
12707 
fill_xymd(double * targ,double x)12708 static void fill_xymd (double *targ, double x)
12709 {
12710     int rem;
12711 
12712     targ[0] = floor(x / 10000);
12713     rem = x - 10000 * targ[0];
12714     targ[1] = floor(rem / 100);
12715     targ[2] = rem - 100 * targ[1];
12716 }
12717 
bad_date_message(int y,int m,int d)12718 static void bad_date_message (int y, int m, int d)
12719 {
12720     gretl_warnmsg_sprintf("%04d-%02d-%02d: %s", y, m, d,
12721                           _("non-existent date"));
12722 }
12723 
12724 /* epochday policy: NAs for year, month or day give an NA result;
12725    non-NA but inherently out-of-bounds values for y, m or d (for
12726    example, negative y, m > 12, d > 31) will produce an error,
12727    and otherwise non-existent dates produce NA.
12728 */
12729 
eval_epochday(NODE * ny,NODE * nm,NODE * nd,parser * p)12730 static NODE *eval_epochday (NODE *ny, NODE *nm, NODE *nd, parser *p)
12731 {
12732     NODE *ret = NULL;
12733     NODE *nodes[3] = {ny, nm, nd};
12734     double *x[3] = {NULL, NULL, NULL};
12735     double xymd[3];
12736     int ymd[3] = {-1, -1, -1};
12737     const char *code = "ymd";
12738     int basic_input = 0;
12739     int n_series = 0;
12740     int julian = 0;
12741     double sval;
12742     int i;
12743 
12744     if (null_node(nm) && null_node(nd)) {
12745         /* try for ISO 8601 basic input */
12746         basic_input = 1;
12747         if (scalar_node(ny)) {
12748             sval = node_get_scalar(ny, p);
12749             if (!p->err) {
12750                 fill_xymd(xymd, sval);
12751                 for (i=0; i<3 && !p->err; i++) {
12752                     ymd[i] = x_to_period(xymd[i], code[i], NULL, &p->err);
12753                 }
12754             }
12755         } else if (ny->t == SERIES) {
12756             x[0] = ny->v.xvec;
12757             n_series = 1;
12758         } else {
12759             node_type_error(F_EPOCHDAY, 1, NUM, ny, p);
12760         }
12761     } else {
12762         for (i=0; i<3 && !p->err; i++) {
12763             if (scalar_node(nodes[i])) {
12764                 sval = node_get_scalar(nodes[i], p);
12765                 if (!p->err) {
12766                     ymd[i] = x_to_period(sval, code[i], &julian, &p->err);
12767                 }
12768             } else if (nodes[i]->t == SERIES) {
12769                 x[i] = nodes[i]->v.xvec;
12770                 n_series++;
12771             } else {
12772                 node_type_error(F_EPOCHDAY, i+1, NUM, nodes[i], p);
12773             }
12774         }
12775     }
12776 
12777     if (!p->err) {
12778         double edt;
12779         int t, t1, t2;
12780         int y = ymd[0];
12781         int m = ymd[1];
12782         int d = ymd[2];
12783 
12784         if (n_series > 0) {
12785             t1 = p->dset->t1;
12786             t2 = p->dset->t2;
12787             ret = aux_series_node(p);
12788         } else {
12789             t1 = t2 = 0;
12790             ret = aux_scalar_node(p);
12791         }
12792 
12793         for (t=t1; t<=t2 && !p->err; t++) {
12794             if (basic_input) {
12795                 if (x[0] != NULL) {
12796                     fill_xymd(xymd, x[0][t]);
12797                     y = x_to_period(xymd[0], 'y', NULL, &p->err);
12798                     m = x_to_period(xymd[1], 'm', NULL, &p->err);
12799                     d = x_to_period(xymd[2], 'd', NULL, &p->err);
12800                 }
12801             } else {
12802                 y = (x[0] == NULL)? y : x_to_period(x[0][t], 'y', &julian, &p->err);
12803                 m = (x[1] == NULL)? m : x_to_period(x[1][t], 'm', NULL, &p->err);
12804                 d = (x[2] == NULL)? d : x_to_period(x[2][t], 'd', NULL, &p->err);
12805             }
12806             if (p->err) {
12807                 break;
12808             } else if (y < 0 || m < 0 || d < 0) {
12809                 /* got an NA somewhere */
12810                 edt = NADBL;
12811             } else {
12812                 if (julian) {
12813                     edt = epoch_day_from_julian_ymd(y, m, d);
12814                 } else {
12815                     edt = epoch_day_from_ymd(y, m, d);
12816                 }
12817                 if (edt <= 0) {
12818                     bad_date_message(y, m, d);
12819                     edt = NADBL;
12820                 }
12821             }
12822             if (n_series > 0) {
12823                 ret->v.xvec[t] = edt;
12824             } else {
12825                 ret->v.xval = edt;
12826             }
12827         }
12828     }
12829 
12830     return ret;
12831 }
12832 
12833 /* Bessel function handler: the 'r' node can be of scalar, series or
12834    matrix type.  Right now, this only supports scalar order ('m'
12835    node).
12836 */
12837 
eval_bessel_func(NODE * l,NODE * m,NODE * r,parser * p)12838 static NODE *eval_bessel_func (NODE *l, NODE *m, NODE *r, parser *p)
12839 {
12840     char ftype;
12841     double v;
12842     NODE *ret = NULL;
12843 
12844     if (!starting(p) && r->t != SERIES) {
12845         return aux_any_node(p);
12846     }
12847 
12848     ftype = l->v.str[0];
12849     v = node_get_scalar(m, p);
12850 
12851     if (r->t == NUM) {
12852         double x = r->v.xval;
12853 
12854         ret = aux_scalar_node(p);
12855         if (ret != NULL) {
12856             ret->v.xval = gretl_bessel(ftype, v, x, &p->err);
12857         }
12858     } else if (r->t == MAT) {
12859         const gretl_matrix *x = r->v.m;
12860         int i, n = x->rows * x->cols;
12861 
12862         ret = aux_sized_matrix_node(p, x->rows, x->cols, 0);
12863         if (ret != NULL) {
12864             for (i=0; i<n && !p->err; i++) {
12865                 ret->v.m->val[i] = gretl_bessel(ftype, v, x->val[i], &p->err);
12866             }
12867         }
12868     } else if (r->t == SERIES) {
12869         const double *x = r->v.xvec;
12870         int t1 = autoreg(p) ? p->obs : p->dset->t1;
12871         int t2 = autoreg(p) ? p->obs : p->dset->t2;
12872         int t;
12873 
12874         ret = aux_series_node(p);
12875         if (ret != NULL) {
12876             for (t=t1; t<=t2 && !p->err; t++) {
12877                 ret->v.xvec[t] = gretl_bessel(ftype, v, x[t], &p->err);
12878             }
12879         }
12880     }
12881 
12882     return ret;
12883 }
12884 
12885 /* String search and replace: return a node containing a copy
12886    of the string(s) on node @src in which all occurrences of
12887    the string on @n0 are replaced by the string on @n1.
12888    This is literal string replacement if @f is F_STRSUB,
12889    regular expression replacement if @f is F_REGSUB.
12890 */
12891 
string_replace(NODE * src,NODE * n0,NODE * n1,NODE * call,parser * p)12892 static NODE *string_replace (NODE *src, NODE *n0, NODE *n1,
12893                              NODE *call, parser *p)
12894 {
12895     int f = call->t;
12896 
12897     if (!starting(p)) {
12898         return aux_any_node(p);
12899     } else {
12900         NODE *ret = NULL;
12901         NODE *n[2] = {n0, n1};
12902         char const *S[3] = {NULL};
12903 	char **Ssrc = NULL;
12904 	char **Snew = NULL;
12905 	char **targ = NULL;
12906         int i, ns = 1;
12907 
12908         for (i=0; i<2; i++) {
12909             /* @n0 and @n1 must be of string type */
12910             if (n[i]->t != STR) {
12911                 node_type_error(f, i+1, STR, n[i], p);
12912                 return NULL;
12913             } else {
12914                 S[i+1] = n[i]->v.str;
12915             }
12916         }
12917 
12918 	if (src->t == STR) {
12919 	    /* single string variable */
12920 	    S[0] = src->v.str;
12921 	    ret = aux_string_node(p);
12922 	} else if (useries_node(src)) {
12923 	    /* string-valued series? */
12924 	    if (is_string_valued(p->dset, src->vnum) &&
12925 		complex_strcalc_ok(call, p)) {
12926 		Ssrc = series_get_string_vals(p->dset, src->vnum,
12927 					      &ns, 1);
12928 		ret = aux_series_node(p);
12929 	    } else {
12930 		p->err = E_TYPES;
12931 	    }
12932 	} else if (src->t == ARRAY) {
12933 	    /* array of strings? */
12934 	    if (gretl_array_get_type(src->v.a) == GRETL_TYPE_STRINGS) {
12935 		Ssrc = gretl_array_get_strings(src->v.a, &ns);
12936 		ret = aux_array_node(p);
12937 	    } else {
12938 		p->err = E_TYPES;
12939 	    }
12940 	} else {
12941 	    p->err = E_TYPES;
12942 	}
12943 
12944         if (ret == NULL) {
12945             return NULL;
12946         }
12947 
12948 	if (src->t == STR) {
12949 	    targ = &ret->v.str;
12950 	} else {
12951 	    Snew = strings_array_new(ns);
12952 	    if (Snew == NULL) {
12953 		p->err = E_ALLOC;
12954 	    }
12955 	}
12956 
12957 	for (i=0; i<ns && !p->err; i++) {
12958 	    if (src->t != STR) {
12959 		S[0] = Ssrc[i];
12960 		targ = &Snew[i];
12961 	    }
12962 	    if (f == F_REGSUB) {
12963 		*targ = gretl_regexp_replace(S[0], S[1], S[2], &p->err);
12964 	    } else {
12965 		*targ = gretl_literal_replace(S[0], S[1], S[2], &p->err);
12966 	    }
12967 	}
12968 
12969 	if (!p->err && src->t == ARRAY) {
12970 	    ret->v.a = gretl_array_from_strings(Snew, ns, 0, &p->err);
12971 	} else if (!p->err && src->t == SERIES) {
12972 	    if (p->lh.vnum != src->vnum) {
12973 		for (i=p->dset->t1; i<=p->dset->t2; i++) {
12974 		    ret->v.xvec[i] = src->v.xvec[i];
12975 		}
12976 	    }
12977 	    prepare_stringvec_return(ret, p, Snew, ns, 0);
12978 	}
12979 
12980         return ret;
12981     }
12982 }
12983 
12984 /* replace_value: non-interactive search-and-replace for series and
12985    matrices.  @src holds the series or matrix of which we want a
12986    modified copy; @n0 holds the value (or vector of values) to be
12987    replaced; and @n1 holds the replacement value(s). It would be nice
12988    to extend this to lists.
12989 */
12990 
replace_value(NODE * src,NODE * n0,NODE * n1,parser * p)12991 static NODE *replace_value (NODE *src, NODE *n0, NODE *n1, parser *p)
12992 {
12993     gretl_vector *vx0 = NULL;
12994     gretl_vector *vx1 = NULL;
12995     double x0 = 0, x1 = 0;
12996     int k0 = -1, k1 = -1;
12997     NODE *ret = NULL;
12998 
12999     if (!starting(p)) {
13000         return aux_any_node(p);
13001     }
13002 
13003     /* n0: the original value, to be replaced */
13004     if (n0->t == NUM) {
13005         x0 = n0->v.xval;
13006     } else if (n0->t == MAT) {
13007         vx0 = n0->v.m;
13008         if (gretl_is_null_matrix(vx0)) {
13009             p->err = E_DATA;
13010         } else if ((k0 = gretl_vector_get_length(vx0)) == 0) {
13011             p->err = E_NONCONF;
13012         }
13013     } else {
13014         node_type_error(F_REPLACE, 1, NUM, n0, p);
13015     }
13016 
13017     if (p->err) {
13018         return NULL;
13019     }
13020 
13021     /* n1: the replacement value */
13022     if (n1->t == NUM) {
13023         x1 = n1->v.xval;
13024     } else if (n1->t == MAT) {
13025         vx1 = n1->v.m;
13026         if (gretl_is_null_matrix(vx1)) {
13027             p->err = E_DATA;
13028         } else if ((k1 = gretl_vector_get_length(vx1)) == 0) {
13029             p->err = E_NONCONF;
13030         }
13031     } else {
13032         node_type_error(F_REPLACE, 2, NUM, n1, p);
13033     }
13034 
13035     if (!p->err) {
13036         if (n0->t == NUM && n1->t == MAT) {
13037             /* can't replace scalar with vector */
13038             p->err = E_TYPES;
13039         } else if (k0 > 0 && k1 > 0 && k0 != k1) {
13040             /* if they're both vectors, they must be
13041                the same length */
13042             p->err = E_NONCONF;
13043         }
13044     }
13045 
13046     if (!p->err) {
13047         if (src->t == SERIES) {
13048             ret = aux_series_node(p);
13049         } else if (src->t == MAT) {
13050             ret = aux_matrix_node(p);
13051         } else {
13052             node_type_error(F_REPLACE, 3, SERIES, src, p);
13053         }
13054     }
13055 
13056     if (!p->err) {
13057         double *px0 = (vx0 != NULL)? vx0->val : &x0;
13058         double *px1 = (vx1 != NULL)? vx1->val : &x1;
13059         gretl_matrix *m = NULL;
13060         const double *x = NULL;
13061         double *targ = NULL;
13062         int n = 0;
13063 
13064         if (k0 < 0) k0 = 1;
13065         if (k1 < 0) k1 = 1;
13066 
13067         if (src->t == SERIES) {
13068             n = sample_size(p->dset);
13069             x = src->v.xvec + p->dset->t1;    /* source array */
13070             targ = ret->v.xvec + p->dset->t1; /* target array */
13071         } else if (src->t == MAT) {
13072             m = src->v.m;
13073             ret->v.m = gretl_matrix_copy(m);
13074             if (ret->v.m == NULL) {
13075                 p->err = E_ALLOC;
13076             } else {
13077                 n = m->rows * m->cols;
13078                 x = m->val;           /* source array */
13079                 targ = ret->v.m->val; /* target array */
13080             }
13081         }
13082 
13083         if (!p->err) {
13084             substitute_values(targ, x, n, px0, k0, px1, k1);
13085         }
13086     }
13087 
13088     return ret;
13089 }
13090 
isoconv_node(NODE * t,parser * p)13091 static NODE *isoconv_node (NODE *t, parser *p)
13092 {
13093     NODE *save_aux = p->aux;
13094     NODE *e, *n = t->L;
13095     NODE *ret = NULL;
13096     const double *x = NULL;
13097     double *ymd[3] = {NULL, NULL, NULL};
13098     int i, k = n->v.bn.n_nodes;
13099 
13100     if (p->dset == NULL) {
13101         p->err = E_NODATA;
13102         return NULL;
13103     }
13104 
13105     if (k < 3 || k > 4) {
13106         n_args_error(k, 4, t->t, p);
13107     } else {
13108         /* evaluate the first (series) argument */
13109         e = eval(n->v.bn.n[0], p);
13110         if (!p->err && e->t != SERIES) {
13111             node_type_error(t->t, 1, SERIES, e, p);
13112         } else {
13113             x = e->v.xvec + p->dset->t1;
13114         }
13115     }
13116 
13117     for (i=1; i<k && !p->err; i++) {
13118         /* the remaining args must be addresses of series */
13119         e = n->v.bn.n[i];
13120         if (i == 3 && null_node(e)) {
13121             ; /* OK for the last one to be omitted */
13122         } else if (e->t != U_ADDR) {
13123             node_type_error(t->t, i+1, U_ADDR, e, p);
13124         } else {
13125             e = e->L;
13126             if (e->t != SERIES) {
13127                 node_type_error(t->t, i+1, SERIES, e, p);
13128             } else {
13129                 ymd[i-1] = p->dset->Z[e->vnum] + p->dset->t1;
13130             }
13131         }
13132     }
13133 
13134     if (!p->err) {
13135         reset_p_aux(p, save_aux);
13136         ret = aux_scalar_node(p);
13137     }
13138 
13139     if (!p->err) {
13140         int n = sample_size(p->dset);
13141 
13142         ret->v.xval = iso_basic_to_extended(x, ymd[0], ymd[1], ymd[2], n);
13143     }
13144 
13145     return ret;
13146 }
13147 
13148 /* The arguments here are:
13149 
13150    @A: array to which an element is to be added
13151    @n: node holding candidate array element
13152 */
13153 
check_array_element_type(gretl_array * A,NODE * n)13154 static int check_array_element_type (gretl_array *A, NODE *n)
13155 {
13156     GretlType t = gretl_array_get_type(A);
13157     int ok = 0;
13158 
13159     if (t == GRETL_TYPE_ANY) {
13160 	/* The array type is not yet determinate; this will be
13161 	   the case when when we're looking at the first element.
13162 	   If the type n->t is acceptable we use it to set the
13163 	   type of @A.
13164         */
13165 	t = 0;
13166         if (n->t == MAT || n->t == NUM) {
13167             t = GRETL_TYPE_MATRICES;
13168         } else if (n->t == STR) {
13169             t = GRETL_TYPE_STRINGS;
13170         } else if (n->t == BUNDLE) {
13171             t = GRETL_TYPE_BUNDLES;
13172         } else if (n->t == LIST) {
13173             t = GRETL_TYPE_LISTS;
13174         } else if (n->t == ARRAY) {
13175 	    t = GRETL_TYPE_ARRAYS;
13176 	}
13177 	if (t > 0) {
13178 	    gretl_array_set_type(A, t);
13179 	    ok = 1;
13180 	}
13181     } else {
13182 	/* We're looking for a match between the array type
13183 	   and the type of the candidate element.
13184 	*/
13185 	if (t == GRETL_TYPE_MATRICES) {
13186 	    ok = (n->t == MAT || n->t == NUM);
13187 	} else if (t == GRETL_TYPE_STRINGS) {
13188 	    ok = n->t == STR;
13189 	} else if (t == GRETL_TYPE_BUNDLES) {
13190 	    ok = n->t == BUNDLE;
13191 	} else if (t == GRETL_TYPE_LISTS) {
13192 	    ok = n->t == LIST;
13193 	} else if (t == GRETL_TYPE_ARRAYS) {
13194 	    ok = n->t == ARRAY;
13195 	}
13196     }
13197 
13198     return ok ? 0 : E_TYPES;
13199 }
13200 
node_nullify_ptr(NODE * n)13201 static void node_nullify_ptr (NODE *n)
13202 {
13203     if      (n->t == MAT)    n->v.m = NULL;
13204     else if (n->t == STR)    n->v.str = NULL;
13205     else if (n->t == BUNDLE) n->v.b = NULL;
13206     else if (n->t == LIST)   n->v.ivec = NULL;
13207     else if (n->t == ARRAY)  n->v.a = NULL;
13208     else if (n->t == SERIES) n->v.xvec = NULL;
13209 }
13210 
13211 /* supports retrieval of data for candidate array elements
13212    or bundle members
13213 */
13214 
node_get_ptr(NODE * n,int f,parser * p,int * donate)13215 static void *node_get_ptr (NODE *n, int f, parser *p, int *donate)
13216 {
13217     void *ptr = NULL;
13218     int t = n->t;
13219 
13220     /* default to copying the node's data */
13221     *donate = 0;
13222 
13223     if (f == F_DEFBUNDLE || f == F_DEFARGS) {
13224         /* specific to bundles */
13225         if (t == ARRAY) {
13226             ptr = n->v.a;
13227         } else if (t == SERIES) {
13228             ptr = n->v.xvec;
13229         } else if (t == NUM) {
13230             ptr = &n->v.xval;
13231         } else if (scalar_matrix_node(n)) {
13232             ptr = n->v.m->val;
13233             t = NUM;
13234         }
13235     }
13236 
13237     if (ptr == NULL) {
13238         /* common to arrays and bundles */
13239         if (t == MAT) {
13240             ptr = n->v.m;
13241         } else if (t == STR) {
13242             ptr = n->v.str;
13243         } else if (t == BUNDLE) {
13244             ptr = n->v.b;
13245         } else if (t == LIST) {
13246             ptr = n->v.ivec;
13247         } else if (t == ARRAY) {
13248 	    ptr = n->v.a;
13249 	}
13250     }
13251 
13252     if (t == NUM) {
13253         *donate = 1;
13254     } else if (!reusable(p) && is_tmp_node(n)) {
13255         *donate = 1;
13256         node_nullify_ptr(n);
13257     }
13258 
13259     return ptr;
13260 }
13261 
13262 /* given an FARGS node, detect if the first argument
13263    is a pointer to bundle */
13264 
bundle_pointer_arg0(NODE * t)13265 static int bundle_pointer_arg0 (NODE *t)
13266 {
13267     NODE *n = t->L;
13268 
13269     if (n->v.bn.n_nodes > 0) {
13270         NODE *n0 = n->v.bn.n[0];
13271 
13272         if (n0->t == U_ADDR && ubundle_node(n0->L)) {
13273             return 1;
13274         }
13275     }
13276 
13277     return 0;
13278 }
13279 
13280 /* Called in the context of tdisagg driver, when we're trying
13281    to determine if the target y (series or list) needs
13282    compressing. This will be the case if y just repeats
13283    low-frequency values.
13284 */
13285 
tdisagg_get_y_compression(int ynum,int xconv,int s,parser * p)13286 static int tdisagg_get_y_compression (int ynum, int xconv,
13287                                       int s, parser *p)
13288 {
13289     if (ynum > 0 && series_get_orig_pd(p->dset, ynum)) {
13290         return s;
13291     } else if (p->targ == SERIES) {
13292         return s;
13293     } else if (p->dset->pd == 4 && s == 4) {
13294         return s;
13295     } else if (p->dset->pd == 12 && s == 12) {
13296         return s;
13297     } else if (xconv == 1) {
13298         /* X was given as a series or list */
13299         return s;
13300     } else {
13301         return 1;
13302     }
13303 }
13304 
13305 /* tdisagg: advance the sample start if the first
13306    high-frequency X observation is not aligned to
13307    the first sub-period.
13308 */
13309 
maybe_advance_t1(int t1,const DATASET * dset)13310 static int maybe_advance_t1 (int t1, const DATASET *dset)
13311 {
13312     int subper = 0;
13313 
13314     date_maj_min(t1, dset, NULL, &subper);
13315     if (subper > 1) {
13316         t1 += dset->pd - subper + 1;
13317     }
13318     return t1;
13319 }
13320 
13321 /* tdisagg: when both Y and X are dataset objects, try to
13322    restrict the sample ranges appropriately and ensure
13323    alignment at the start of the data.
13324 */
13325 
tdisagg_get_start_stop(int ynum,const int * ylist,int xnum,const int * xlist,const DATASET * dset,int cfac,int xmidas,int * start,int * ystop,int * xstop)13326 static int tdisagg_get_start_stop (int ynum, const int *ylist,
13327                                    int xnum, const int *xlist,
13328                                    const DATASET *dset,
13329                                    int cfac, int xmidas,
13330                                    int *start, int *ystop,
13331                                    int *xstop)
13332 {
13333     int yvars[2] = {1, ynum};
13334     int xvars[2] = {1, xnum};
13335     int t1 = dset->t1;
13336     int t2 = dset->t2;
13337     int err = 0;
13338 
13339     if ((ynum == 0 && ylist == NULL) ||
13340         (xnum == 0 && xlist == NULL)) {
13341         /* can't do this */
13342         return 0;
13343     }
13344 
13345     if (ylist == NULL) {
13346         ylist = yvars;
13347     }
13348     if (xlist == NULL) {
13349         xlist = xvars;
13350     }
13351 
13352     err = list_adjust_sample(xlist, &t1, &t2, dset, NULL);
13353 
13354     if (!err && !xmidas) {
13355         t1 = maybe_advance_t1(t1, dset);
13356     }
13357 
13358     if (!err) {
13359         int yt1 = t1, yt2 = t2;
13360         int nmiss = 0;
13361 
13362         if (cfac > 1) {
13363             err = list_adjust_sample(ylist, &yt1, &yt2, dset, &nmiss);
13364         } else {
13365             err = list_adjust_sample(ylist, &yt1, &yt2, dset, NULL);
13366         }
13367         if (!err) {
13368             if (yt1 > t1) {
13369                 t1 = yt1;
13370                 if (!xmidas) {
13371                     t1 = maybe_advance_t1(t1, dset);
13372                 }
13373             }
13374             *start = t1;
13375             *ystop = yt2;
13376             *xstop = t2;
13377         }
13378     }
13379 
13380     return err;
13381 }
13382 
13383 /* tdisagg: when Y is a dataset object and no stochastic
13384    X is given, try to restrict the sample range for Y
13385    appropriately.
13386 */
13387 
tdisagg_get_y_start_stop(int ynum,const int * ylist,const DATASET * dset,int cfac,int * t1,int * t2)13388 static int tdisagg_get_y_start_stop (int ynum, const int *ylist,
13389                                      const DATASET *dset, int cfac,
13390                                      int *t1, int *t2)
13391 {
13392     int yvars[2] = {1, ynum};
13393     int err = 0;
13394 
13395     if (ynum == 0 && ylist == NULL) {
13396         /* can't do this */
13397         return 0;
13398     } else if (ylist == NULL) {
13399         ylist = yvars;
13400     }
13401 
13402     if (cfac > 1) {
13403         int nmiss = 0;
13404 
13405         err = list_adjust_sample(ylist, t1, t2, dset, &nmiss);
13406     } else {
13407         err = list_adjust_sample(ylist, t1, t2, dset, NULL);
13408     }
13409 
13410     return err;
13411 }
13412 
13413 /* evaluate a built-in function that has more than three arguments */
13414 
eval_nargs_func(NODE * t,parser * p)13415 static NODE *eval_nargs_func (NODE *t, parser *p)
13416 {
13417     NODE *save_aux = p->aux;
13418     NODE *n = t->L;
13419     NODE *ret = NULL;
13420     NODE *e = NULL;
13421     int i, k = n->v.bn.n_nodes;
13422 
13423     if (t->t == F_BKFILT) {
13424         const double *x = NULL;
13425         int bk[3] = {0};
13426 
13427         if (k < 1 || k > 4) {
13428             n_args_error(k, 4, t->t, p);
13429         }
13430 
13431         /* evaluate the first (series) argument */
13432         if (!p->err) {
13433             e = eval(n->v.bn.n[0], p);
13434         }
13435         if (!p->err && e->t != SERIES) {
13436             node_type_error(t->t, 1, SERIES, e, p);
13437         }
13438 
13439         if (!p->err) {
13440             x = e->v.xvec;
13441         }
13442 
13443         for (i=1; i<k && !p->err; i++) {
13444             e = n->v.bn.n[i];
13445             if (null_node(e)) {
13446                 ; /* NULL arguments are OK */
13447             } else {
13448                 e = eval(n->v.bn.n[i], p);
13449                 if (e == NULL) {
13450                     fprintf(stderr, "eval_nargs_func: failed "
13451                             "to evaluate arg %d\n", i);
13452                 } else {
13453                     bk[i-1] = node_get_int(e, p);
13454                 }
13455             }
13456         }
13457 
13458         if (!p->err) {
13459             reset_p_aux(p, save_aux);
13460             ret = aux_series_node(p);
13461         }
13462         if (!p->err) {
13463             p->err = bkbp_filter(x, ret->v.xvec, p->dset, bk[0], bk[1], bk[2]);
13464         }
13465     } else if (t->t == F_FILTER) {
13466         const double *x = NULL; /* series */
13467         gretl_matrix *X = NULL;
13468         gretl_matrix *C = NULL;
13469         gretl_matrix *A = NULL;
13470         gretl_matrix *x0 = NULL;
13471         double y0 = 0;
13472 
13473         if (k < 1 || k > 5) {
13474             n_args_error(k, 5, t->t, p);
13475         }
13476 
13477         for (i=0; i<k && !p->err; i++) {
13478             e = eval(n->v.bn.n[i], p);
13479             if (e == NULL) {
13480                 fprintf(stderr, "eval_nargs_func: failed to evaluate arg %d\n", i);
13481             } else if (i == 0) {
13482                 /* the series or matrix to filter */
13483                 if (e->t != SERIES && e->t != MAT) {
13484                    node_type_error(t->t, i+1, 0, e, p);
13485                 } else if (e->t == SERIES) {
13486                    x = e->v.xvec;
13487                 } else {
13488                    X = e->v.m;
13489                 }
13490             } else if (i == 1) {
13491                 /* matrix for MA polynomial (but we'll take a scalar) */
13492                 if (e->t != MAT && e->t != NUM && e->t != EMPTY) {
13493                     node_type_error(t->t, i+1, MAT, e, p);
13494                 } else if (e->t != EMPTY) {
13495                     C = node_get_real_matrix(e, p, 0, 2);
13496                 }
13497             } else if (i == 2) {
13498                 /* matrix for AR polynomial (but we'll take a scalar) */
13499                 if (e->t != MAT && e->t != NUM && e->t != EMPTY) {
13500                     node_type_error(t->t, i+1, MAT, e, p);
13501                 } else if (e->t != EMPTY) {
13502                     A = node_get_real_matrix(e, p, 1, 3);
13503                 }
13504             } else if (i == 3) {
13505                 /* initial (optional scalar) value for output series */
13506                 if (e->t != EMPTY && !scalar_node(e)) {
13507                     node_type_error(t->t, i+1, NUM, e, p);
13508                 } else if (e->t != EMPTY) {
13509                     y0 = node_get_scalar(e, p);
13510                     if (!p->err && na(y0)) {
13511                         p->err = E_MISSDATA;
13512                     }
13513                 }
13514             } else if (i == 4) {
13515                 /* optional pre-sample x vector */
13516                 if (e->t != MAT && e->t != NUM && e->t != EMPTY) {
13517                     node_type_error(t->t, i+1, MAT, e, p);
13518                 } else if (e->t != EMPTY) {
13519                     x0 = node_get_real_matrix(e, p, 1, 5);
13520                 }
13521             }
13522         }
13523 
13524         if (!p->err) {
13525             reset_p_aux(p, save_aux);
13526             if (X != NULL) {
13527                 /* matrix output wanted */
13528                 ret = aux_matrix_node(p);
13529                 if (!p->err) {
13530                     ret->v.m = filter_matrix(X, A, C, y0, x0, &p->err);
13531                 }
13532             } else if (x != NULL) {
13533                 /* series output */
13534                 ret = aux_series_node(p);
13535                 if (!p->err) {
13536                     p->err = filter_series(x, ret->v.xvec, p->dset,
13537                                            A, C, y0, x0);
13538                 }
13539             }
13540         }
13541     } else if (t->t == F_MCOVG) {
13542         gretl_matrix *X = NULL;
13543         gretl_vector *u = NULL;
13544         gretl_vector *w = NULL;
13545         int targ, maxlag = 0;
13546 
13547         if (k != 4) {
13548             n_args_error(k, 4, t->t, p);
13549         }
13550 
13551         for (i=0; i<k && !p->err; i++) {
13552             targ = (i == 3)? NUM : MAT;
13553             e = eval(n->v.bn.n[i], p);
13554             if (e == NULL) {
13555                 fprintf(stderr, "eval_nargs_func: failed to evaluate arg %d\n", i);
13556             } else if ((i == 1 || i == 2) && null_node(e)) {
13557                 ; /* for u or w, NULL is acceptable */
13558             } else if (e->t != targ) {
13559                 node_type_error(t->t, i+1, targ, e, p);
13560             } else if (i == 0) {
13561                 X = mat_node_get_real_matrix(e, p);
13562             } else if (i == 1) {
13563                 u = mat_node_get_real_matrix(e, p);
13564             } else if (i == 2) {
13565                 w = mat_node_get_real_matrix(e, p);
13566             } else if (i == 3) {
13567                 maxlag = e->v.xval;
13568             }
13569         }
13570 
13571         if (!p->err) {
13572             reset_p_aux(p, save_aux);
13573             ret = aux_matrix_node(p);
13574         }
13575         if (!p->err) {
13576             ret->v.m = gretl_matrix_covariogram(X, u, w, maxlag, &p->err);
13577         }
13578     } else if (t->t == F_MOLS || t->t == F_MPOLS) {
13579         gretlopt opt = (t->t == F_MPOLS)? OPT_M : OPT_NONE;
13580         gretl_matrix *M[2] = {NULL};
13581         gretl_matrix *U = NULL;
13582         gretl_matrix *V = NULL;
13583         char freemat[2] = {0};
13584 
13585         if (k < 2 || k > 4) {
13586             n_args_error(k, 1, t->t, p);
13587         }
13588 
13589         for (i=0; i<k && !p->err; i++) {
13590             e = eval(n->v.bn.n[i], p);
13591             if (p->err) {
13592                 break;
13593             }
13594             if (i < 2) {
13595                 if (e->t == SERIES) {
13596                     M[i] = tmp_matrix_from_series(e, p);
13597                     freemat[i] = 1;
13598                 } else {
13599                     M[i] = node_get_real_matrix(e, p, i, i+1);
13600                 }
13601             } else {
13602                 if (null_node(e)) {
13603                     ; /* OK */
13604                 } else if (e->t != U_ADDR) {
13605                     node_type_error(t->t, i+1, U_ADDR, e, p);
13606                 } else if (i == 2) {
13607                     U = ptr_node_get_matrix(e, p);
13608                 } else {
13609                     V = ptr_node_get_matrix(e, p);
13610                 }
13611             }
13612         }
13613 
13614         if (!p->err) {
13615             reset_p_aux(p, save_aux);
13616             ret = aux_matrix_node(p);
13617         }
13618         if (!p->err) {
13619             ret->v.m = user_matrix_ols(M[0], M[1], U, V, opt, &p->err);
13620         }
13621         if (freemat[0]) gretl_matrix_free(M[0]);
13622         if (freemat[1]) gretl_matrix_free(M[1]);
13623     } else if (t->t == F_MRLS) {
13624         gretl_matrix *M[4] = {NULL};
13625         gretl_matrix *U = NULL;
13626         gretl_matrix *V = NULL;
13627 
13628         if (k < 4 || k > 6) {
13629             n_args_error(k, 1, t->t, p);
13630         }
13631 
13632         for (i=0; i<k && !p->err; i++) {
13633             e = eval(n->v.bn.n[i], p);
13634             if (p->err) {
13635                 break;
13636             }
13637             if (i < 4) {
13638                 M[i] = node_get_real_matrix(e, p, i, i+1);
13639             } else {
13640                 if (null_node(e)) {
13641                     ; /* OK */
13642                 } else if (e->t != U_ADDR) {
13643                     node_type_error(t->t, i+1, U_ADDR, e, p);
13644                 } else if (i == 4) {
13645                     U = ptr_node_get_matrix(e, p);
13646                 } else {
13647                     V = ptr_node_get_matrix(e, p);
13648                 }
13649             }
13650         }
13651 
13652         if (!p->err) {
13653             reset_p_aux(p, save_aux);
13654             ret = aux_matrix_node(p);
13655         }
13656         if (!p->err) {
13657             ret->v.m = user_matrix_rls(M[0], M[1], M[2], M[3], U, V, &p->err);
13658         }
13659     } else if (t->t == F_NRMAX) {
13660         gretl_matrix *b = NULL;
13661         const char *sf = NULL;
13662         const char *sg = NULL;
13663         const char *sh = NULL;
13664 
13665         if (k < 2 || k > 4) {
13666             n_args_error(k, 4, t->t, p);
13667         }
13668 
13669         for (i=0; i<k && !p->err; i++) {
13670             e = eval(n->v.bn.n[i], p);
13671             if (p->err) {
13672                 break;
13673             }
13674             if (i == 0) {
13675                 b = mat_node_get_real_matrix(e, p);
13676             } else if (i == 1) {
13677                 if (e->t != STR) {
13678                     node_type_error(t->t, i+1, STR, e, p);
13679                 } else {
13680                     sf = e->v.str;
13681                 }
13682             } else if (null_node(e)) {
13683                 ; /* OK */
13684             } else if (e->t != STR) {
13685                 node_type_error(t->t, i+1, STR, e, p);
13686             } else if (i == 2) {
13687                 sg = e->v.str;
13688             } else {
13689                 sh = e->v.str;
13690             }
13691         }
13692 
13693         if (!p->err) {
13694             if (!gretl_vector_get_length(b)) {
13695                 p->err = E_TYPES;
13696             } else if (!is_function_call(sf) ||
13697                        (sg != NULL && !is_function_call(sg)) ||
13698                        (sh != NULL && !is_function_call(sh))) {
13699                 p->err = E_TYPES;
13700             }
13701         }
13702 
13703         if (!p->err) {
13704             reset_p_aux(p, save_aux);
13705             ret = aux_scalar_node(p);
13706         }
13707 
13708         if (!p->err) {
13709             int minimize = alias_reversed(t) ? 1 : 0;
13710 
13711             ret->v.xval = user_NR(b, sf, sg, sh, p->dset,
13712                                   minimize, p->prn, &p->err);
13713         }
13714     } else if (t->t == F_LOESS) {
13715         const double *y = NULL, *x = NULL;
13716         double bandwidth = 0.5;
13717         int poly_order = 1;
13718         gretlopt opt = OPT_NONE;
13719 
13720         if (k < 2 || k > 6) {
13721             n_args_error(k, 5, t->t, p);
13722         }
13723 
13724         for (i=0; i<k && !p->err; i++) {
13725             e = eval(n->v.bn.n[i], p);
13726             if (p->err) {
13727                 break;
13728             }
13729             if (i < 2) {
13730                 if (e->t != SERIES) {
13731                     node_type_error(t->t, i+1, SERIES, e, p);
13732                 } else if (i == 0) {
13733                     y = e->v.xvec;
13734                 } else {
13735                     x = e->v.xvec;
13736                 }
13737             } else if (i == 2 || i == 3) {
13738                 if (e->t != NUM && e->t != EMPTY) {
13739                     node_type_error(t->t, i+1, NUM, e, p);
13740                 } else if (i == 2 && e->t == NUM) {
13741                     poly_order = node_get_int(e, p);
13742                 } else if (e->t == NUM) {
13743                     bandwidth = e->v.xval;
13744                 }
13745             } else {
13746                 if (e->t != EMPTY && e->t != NUM) {
13747                     node_type_error(t->t, i+1, NUM, e, p);
13748                 } else {
13749                     int ival = node_get_int(e, p);
13750 
13751                     if (!p->err && ival != 0) {
13752                         if (i == 4) {
13753                             opt |= OPT_R;
13754                         } else {
13755                             opt |= OPT_O;
13756                         }
13757                     }
13758                 }
13759             }
13760         }
13761         if (!p->err) {
13762             reset_p_aux(p, save_aux);
13763             ret = aux_series_node(p);
13764             if (ret != NULL) {
13765                 p->err = gretl_loess(y, x, poly_order, bandwidth,
13766                                      opt, p->dset, ret->v.xvec);
13767             }
13768         }
13769     } else if (t->t == F_GHK) {
13770         gretl_matrix *M[4] = {NULL};
13771         gretl_matrix *dP = NULL;
13772 
13773         if (k < 4 || k > 5) {
13774             n_args_error(k, 5, t->t, p);
13775         }
13776 
13777         for (i=0; i<k && !p->err; i++) {
13778             e = eval(n->v.bn.n[i], p);
13779             if (e == NULL) {
13780                 fprintf(stderr, "eval_nargs_func: failed to evaluate arg %d\n", i);
13781             } else if (i < 4) {
13782                 M[i] = node_get_real_matrix(e, p, i, i+1);
13783             } else {
13784                 /* the optional last argument */
13785                 if (null_node(e)) {
13786                     ; /* OK */
13787                 } else if (e->t != U_ADDR) {
13788                     node_type_error(t->t, i+1, U_ADDR, e, p);
13789                 } else {
13790                     dP = ptr_node_get_matrix(e, p);
13791                 }
13792             }
13793         }
13794         if (!p->err) {
13795             reset_p_aux(p, save_aux);
13796             ret = aux_matrix_node(p);
13797         }
13798         if (!p->err) {
13799             if (dP == NULL) {
13800                 ret->v.m = gretl_GHK(M[0], M[1], M[2], M[3], &p->err);
13801             } else {
13802                 ret->v.m = user_matrix_GHK(M[0], M[1], M[2], M[3],
13803                                            dP, &p->err);
13804             }
13805         }
13806     } else if (t->t == F_QUADTAB) {
13807         int order = -1, method = 1;
13808         double a = NADBL;
13809         double b = NADBL;
13810 
13811         if (k < 1 || k > 4) {
13812             n_args_error(k, 4, t->t, p);
13813         }
13814 
13815         for (i=0; i<k && !p->err; i++) {
13816             e = eval(n->v.bn.n[i], p);
13817             if (e == NULL) {
13818                 fprintf(stderr, "eval_nargs_func: failed to evaluate arg %d\n", i);
13819             } else if (i == 0) {
13820                 order = node_get_int(e, p);
13821             } else if (!null_or_scalar(e)) {
13822                 node_type_error(t->t, i+1, NUM, e, p);
13823             } else if (i == 1) {
13824                 method = node_get_int(e, p);
13825             } else if (i == 2) {
13826                 a = node_get_scalar(e, p);
13827             } else {
13828                 b = node_get_scalar(e, p);
13829             }
13830         }
13831         if (!p->err) {
13832             reset_p_aux(p, save_aux);
13833             ret = aux_matrix_node(p);
13834         }
13835         if (!p->err) {
13836             ret->v.m = gretl_quadrule_matrix_new(order, method,
13837                                                  a, b, &p->err);
13838         }
13839     } else if (t->t == F_IRF) {
13840         int targ = 0, shock = 0;
13841         double alpha = 0.0;
13842         gretl_bundle *vb = NULL;
13843 
13844         if (k < 2 || k > 4) {
13845             n_args_error(k, 4, t->t, p);
13846         }
13847 
13848         for (i=0; i<k && !p->err; i++) {
13849             e = eval(n->v.bn.n[i], p);
13850             if (e == NULL) {
13851                 fprintf(stderr, "eval_nargs_func: failed to evaluate arg %d\n", i);
13852             } else if (i == 0) {
13853                 targ = node_get_int(e, p);
13854             } else if (i == 1) {
13855                 shock = node_get_int(e, p);
13856             } else if (i == 2) {
13857                 /* optional bootstrap alpha */
13858                 if (e->t != EMPTY) {
13859                     alpha = node_get_scalar(e, p);
13860                 }
13861             } else {
13862                 /* final optional arg must be bundle */
13863                 if (e->t != EMPTY && e->t != BUNDLE) {
13864                     node_type_error(t->t, 4, BUNDLE, e, p);
13865                 } else if (e->t == BUNDLE) {
13866                     vb = e->v.b;
13867                 }
13868             }
13869         }
13870         if (!p->err) {
13871             reset_p_aux(p, save_aux);
13872             ret = aux_matrix_node(p);
13873         }
13874         if (!p->err) {
13875             /* convert indices to zero-based */
13876             targ--;
13877             shock--;
13878             if (vb != NULL) {
13879                 ret->v.m = gretl_IRF_from_bundle(vb, targ, shock, alpha,
13880                                                  p->dset, &p->err);
13881             } else {
13882                 ret->v.m = last_model_get_irf_matrix(targ, shock, alpha,
13883                                                      p->dset, &p->err);
13884             }
13885         }
13886     } else if (t->t == F_QLRPVAL) {
13887         double X2 = NADBL;
13888         double p1 = 0, p2 = 0;
13889         int df = 0;
13890 
13891         if (k != 4) {
13892             n_args_error(k, 4, t->t, p);
13893         }
13894 
13895         for (i=0; i<k && !p->err; i++) {
13896             e = eval(n->v.bn.n[i], p);
13897             if (e == NULL) {
13898                 fprintf(stderr, "eval_nargs_func: failed to evaluate arg %d\n", i);
13899             } else if (i == 0) {
13900                 X2 = node_get_scalar(e, p);
13901             } else if (i == 1) {
13902                 df = node_get_int(e, p);
13903             } else if (i == 2) {
13904                 p1 = node_get_scalar(e, p);
13905             } else {
13906                 p2 = node_get_scalar(e, p);
13907             }
13908         }
13909         if (!p->err) {
13910             reset_p_aux(p, save_aux);
13911             ret = aux_scalar_node(p);
13912         }
13913         if (!p->err) {
13914             ret->v.xval = QLR_pval(X2, df, p1, p2);
13915         }
13916     } else if (t->t == F_BOOTCI) {
13917         int cnum = -1, method = 1, B = 0;
13918         int studentize = 1;
13919         double alpha = NADBL;
13920 
13921         if (k < 1 || k > 5) {
13922             n_args_error(k, 5, t->t, p);
13923         }
13924 
13925         for (i=0; i<k && !p->err; i++) {
13926             e = eval(n->v.bn.n[i], p);
13927             if (e == NULL) {
13928                 fprintf(stderr, "eval_nargs_func: failed to evaluate arg %d\n", i);
13929             } else if (i == 0) {
13930                 cnum = node_get_int(e, p);
13931             } else if (!null_or_scalar(e)) {
13932                 node_type_error(t->t, i+1, NUM, e, p);
13933             } else if (i == 1) {
13934                 B = node_get_int(e, p);
13935             } else if (i == 2) {
13936                 alpha = node_get_scalar(e, p);
13937             } else if (i == 3) {
13938                 method = node_get_int(e, p);
13939             } else {
13940                 studentize = node_get_int(e, p);
13941             }
13942         }
13943         if (!p->err) {
13944             reset_p_aux(p, save_aux);
13945             ret = aux_matrix_node(p);
13946         }
13947         if (!p->err) {
13948             ret->v.m = last_model_get_boot_ci(cnum, p->dset, B, alpha, method,
13949                                               studentize, &p->err);
13950         }
13951     } else if (t->t == F_BOOTPVAL) {
13952         int cnum = -1, method = 1, B = 0;
13953 
13954         if (k < 1 || k > 3) {
13955             n_args_error(k, 3, t->t, p);
13956         }
13957 
13958         for (i=0; i<k && !p->err; i++) {
13959             e = eval(n->v.bn.n[i], p);
13960             if (e == NULL) {
13961                 fprintf(stderr, "eval_nargs_func: failed to evaluate arg %d\n", i);
13962             } else if (i == 0) {
13963                 cnum = node_get_int(e, p);
13964             } else if (!null_or_scalar(e)) {
13965                 node_type_error(t->t, i+1, NUM, e, p);
13966             } else if (i == 1) {
13967                 B = node_get_int(e, p);
13968             } else {
13969                 method = node_get_int(e, p);
13970             }
13971         }
13972         if (!p->err) {
13973             reset_p_aux(p, save_aux);
13974             ret = aux_scalar_node(p);
13975         }
13976         if (!p->err) {
13977             ret->v.xval = last_model_get_boot_pval(cnum, p->dset, B,
13978                                                    method, &p->err);
13979         }
13980     } else if (t->t == F_MOVAVG) {
13981         const double *x = NULL;
13982         double d = 0, y0 = NADBL;
13983         int len = 0, ctrl = -9999;
13984         int EMA = 0;
13985 
13986         if (k < 2 || k > 4) {
13987             n_args_error(k, 4, t->t, p);
13988         }
13989 
13990         for (i=0; i<k && !p->err; i++) {
13991             if (i > 1 && null_node(n->v.bn.n[i])) {
13992                 continue; /* OK */
13993             }
13994             e = eval(n->v.bn.n[i], p);
13995             if (e == NULL) {
13996                 fprintf(stderr, "eval_nargs_func: failed to evaluate arg %d\n", i);
13997             } else if (i == 0) {
13998                 if (e->t == SERIES) {
13999                     x = e->v.xvec;
14000                 } else {
14001                     node_type_error(t->t, i+1, SERIES, e, p);
14002                 }
14003             } else if (i == 1) {
14004                 d = node_get_scalar(e, p);
14005                 if (d < 1.0 && d > 0.0) {
14006                     EMA = 1;
14007                 } else if (d < 1.0) {
14008                     p->err = E_INVARG;
14009                 } else {
14010                     len = node_get_int(e, p);
14011                 }
14012             } else if (i == 2) {
14013                 ctrl = node_get_int(e, p);
14014             } else {
14015                 y0 = node_get_scalar(e, p);
14016             }
14017         }
14018         if (!p->err) {
14019             reset_p_aux(p, save_aux);
14020             ret = aux_series_node(p);
14021         }
14022         if (!p->err) {
14023             if (ctrl == -9999) {
14024                 /* set the respective defaults */
14025                 ctrl = EMA ? 1 : 0;
14026             }
14027             if (EMA) {
14028                 p->err = exponential_movavg_series(x, ret->v.xvec, p->dset,
14029                                                    d, ctrl, y0);
14030             } else {
14031                 p->err = movavg_series(x, ret->v.xvec, p->dset, len, ctrl);
14032             }
14033         }
14034     } else if (t->t == HF_CLOGFI) {
14035         gretl_matrix *z = NULL;
14036         gretl_matrix *df = NULL;
14037         int T = 0, K = 0;
14038 
14039         if (k < 3 || k > 4) {
14040             n_args_error(k, 4, t->t, p);
14041         }
14042 
14043         for (i=0; i<k && !p->err; i++) {
14044             e = eval(n->v.bn.n[i], p);
14045             if (e == NULL) {
14046                 fprintf(stderr, "eval_nargs_func: failed to evaluate arg %d\n", i);
14047             } else if (i == 0) {
14048                 if (scalar_node(e)) {
14049                     T = node_get_int(e, p);
14050                 } else {
14051                     node_type_error(t->t, 1, NUM, e, p);
14052                 }
14053             } else if (i == 1) {
14054                 if (scalar_node(e)) {
14055                     K = node_get_int(e, p);
14056                 } else {
14057                     node_type_error(t->t, 2, NUM, e, p);
14058                 }
14059             } else if (i == 2) {
14060                 if (e->t == MAT) {
14061                     z = mat_node_get_real_matrix(e, p);
14062                 } else {
14063                     node_type_error(t->t, 3, MAT, e, p);
14064                 }
14065             } else if (i == 3) {
14066                 /* optional matrix-pointer for storing the
14067                    derivative wrt z */
14068                 if (null_node(e)) {
14069                     ; /* OK */
14070                 } else if (e->t != U_ADDR) {
14071                     node_type_error(t->t, 4, U_ADDR, e, p);
14072                 } else {
14073                     df = ptr_node_get_matrix(e, p);
14074                 }
14075             }
14076         }
14077 
14078         if (!p->err) {
14079             reset_p_aux(p, save_aux);
14080             ret = aux_scalar_node(p);
14081         }
14082 
14083         if (!p->err) {
14084             ret->v.xval = clogit_fi(T, K, z, df, &p->err);
14085         }
14086     } else if (t->t == F_DEFARRAY) {
14087         gretl_array *A;
14088         void *ptr;
14089 
14090 	A = gretl_array_new(GRETL_TYPE_ANY, 0, &p->err);
14091 
14092         if (!p->err) {
14093             for (i=0; i<k && !p->err; i++) {
14094                 int donate = 0;
14095 
14096                 e = eval(n->v.bn.n[i], p);
14097                 if (!p->err) {
14098                     p->err = check_array_element_type(A, e);
14099                 }
14100                 if (!p->err) {
14101 		    if (e->t == NUM) {
14102                         ptr = gretl_matrix_from_scalar(e->v.xval);
14103                         donate = 1;
14104                     } else {
14105                         ptr = node_get_ptr(e, t->t, p, &donate);
14106                     }
14107                     if (donate) {
14108                         /* copy not required */
14109                         p->err = gretl_array_append_object(A, ptr, 0);
14110                     } else {
14111                         p->err = gretl_array_append_object(A, ptr, 1);
14112                     }
14113                 }
14114             }
14115         }
14116 
14117         if (p->err) {
14118             gretl_array_destroy(A);
14119         } else {
14120             reset_p_aux(p, save_aux);
14121             ret = aux_array_node(p);
14122             if (ret != NULL) {
14123                 ret->v.a = A;
14124             }
14125         }
14126     } else if (t->t == F_DEFBUNDLE || t->t == F_DEFARGS) {
14127         gretl_bundle *b = NULL;
14128         GretlType gtype;
14129         char *key = NULL;
14130         void *ptr;
14131         int donate;
14132 
14133         if (k % 2 != 0) {
14134             p->err = E_PARSE;
14135         } else {
14136             b = gretl_bundle_new();
14137             if (b == NULL) {
14138                 p->err = E_ALLOC;
14139             }
14140         }
14141 
14142         if (!p->err) {
14143             for (i=0; i<k && !p->err; i++) {
14144                 ptr = NULL;
14145                 e = eval(n->v.bn.n[i], p);
14146                 if (p->err) {
14147                     break;
14148                 }
14149                 if (i == 0 || i % 2 == 0) {
14150                     /* we need a key string */
14151                     if (e->t == STR) {
14152                         key = e->v.str;
14153                     } else {
14154                         p->err = E_TYPES;
14155                     }
14156                 } else {
14157                     /* we need some valid content */
14158                     gtype = gretl_type_from_gen_type(e->t);
14159                     if (type_can_be_bundled(gtype)) {
14160                         int size = 0;
14161 
14162                         if (e->t == SERIES) {
14163                             size = p->dset->n;
14164                         } else if (scalar_matrix_node(e)) {
14165                             gtype = GRETL_TYPE_DOUBLE;
14166                         }
14167                         ptr = node_get_ptr(e, t->t, p, &donate);
14168                         if (donate) {
14169                             gretl_bundle_donate_data(b, key, ptr, gtype, size);
14170                         } else {
14171                             gretl_bundle_set_data(b, key, ptr, gtype, size);
14172                         }
14173                     } else {
14174                         p->err = E_TYPES;
14175                     }
14176                 }
14177             }
14178         }
14179 
14180         if (p->err) {
14181             gretl_bundle_destroy(b);
14182         } else {
14183             reset_p_aux(p, save_aux);
14184             ret = aux_bundle_node(p);
14185             if (ret != NULL) {
14186                 ret->v.b = b;
14187             }
14188         }
14189     } else if (t->t == F_DEFLIST) {
14190         int *li, *full_list = gretl_list_new(0);
14191 
14192         for (i=0; i<k && !p->err; i++) {
14193             li = NULL;
14194             e = eval(n->v.bn.n[i], p);
14195             if (!p->err) {
14196                 if (k == 1 && e->t == ARRAY) {
14197                     li = list_from_strings_array(e->v.a, p);
14198                 } else if (ok_list_node_plus(e)) {
14199                     li = node_get_list(e, p);
14200                 } else if (e->t == MAT) {
14201                     li = node_get_list(e, p);
14202                 } else {
14203                     p->err = E_TYPES;
14204                 }
14205             }
14206             if (!p->err && li[0] > 0) {
14207                 gretl_list_append_list(&full_list, li, &p->err);
14208             }
14209             free(li);
14210         }
14211 
14212         if (p->err) {
14213             free(full_list);
14214         } else {
14215             reset_p_aux(p, save_aux);
14216             ret = aux_list_node(p);
14217             if (ret != NULL) {
14218                 ret->v.ivec = full_list;
14219             }
14220         }
14221     } else if (t->t == F_NADARWAT) {
14222         const double *x = NULL;
14223         const double *y = NULL;
14224         int LOO = 0;
14225         double h = 0;
14226         double trim = NADBL;
14227 
14228         if (k < 2 || k > 5) {
14229             n_args_error(k, 5, t->t, p);
14230         }
14231 
14232         for (i=0; i<k && !p->err; i++) {
14233             e = eval(n->v.bn.n[i], p);
14234             if (i < 2 && !p->err && e->t != SERIES) {
14235                 node_type_error(t->t, i+1, SERIES, e, p);
14236             }
14237             if (p->err) {
14238                 break;
14239             }
14240             if (i == 0) {
14241                 x = e->v.xvec;
14242             } else if (i == 1) {
14243                 y = e->v.xvec;
14244             } else if (i == 2) {
14245                 /* set bandwidth? */
14246                 if (null_node(e)) {
14247                     ; /* OK: will use the default */
14248                 } else {
14249                     h = node_get_scalar(e, p);
14250                     if (h < 0 && k > 3) {
14251                         gretl_errmsg_sprintf(_("Bandwidth must be non-negative"));
14252                         p->err = E_INVARG;
14253                         break;
14254                     } else if (h < 0) {
14255                         /* it's a legacy thing */
14256                         LOO = 1;
14257                         h = -h;
14258                     }
14259                 }
14260             } else if (i == 3) {
14261                 /* Leave-one-out */
14262                 LOO = node_get_bool(e, p, 0);
14263             } else if (i == 4) {
14264                 /* trim spec? (overrides legacy "set" value) */
14265                 trim = node_get_scalar(e, p);
14266             }
14267         }
14268 
14269         if (!p->err) {
14270             reset_p_aux(p, save_aux);
14271             ret = aux_series_node(p);
14272         }
14273         if (!p->err) {
14274             if (na(trim)) {
14275                 trim = libset_get_double(NADARWAT_TRIM);
14276             }
14277             p->err = nadaraya_watson(x, y, h, p->dset, LOO,
14278                                      trim, ret->v.xvec);
14279         }
14280     } else if (t->t == F_HYP2F1) {
14281         gretl_matrix *x = NULL;
14282         double a[3];
14283 
14284         if (k != 4) {
14285             n_args_error(k, 4, t->t, p);
14286         }
14287         for (i=0; i<k && !p->err; i++) {
14288             e = eval(n->v.bn.n[i], p);
14289             if (i < 3) {
14290                 a[i] = node_get_scalar(e, p);
14291             } else {
14292                 x = node_get_real_matrix(e, p, 0, 3);
14293             }
14294         }
14295         if (!p->err) {
14296             reset_p_aux(p, save_aux);
14297             ret = aux_matrix_node(p);
14298         }
14299         if (!p->err) {
14300             ret->v.m = gretl_matrix_alloc(x->rows, x->cols);
14301             if (ret->v.m == NULL) {
14302                 p->err = E_ALLOC;
14303             } else {
14304                 int n = x->rows * x->cols;
14305                 double xi, y;
14306 
14307                 for (i=0; i<n; i++) {
14308                     xi = x->val[i];
14309                     if (xi < -1.0 || xi >= 1.0) {
14310                         y = NADBL;
14311                     } else {
14312                         y = hypergeo(a[0], a[1], a[2], xi);
14313                     }
14314                     ret->v.m->val[i] = y;
14315                 }
14316             }
14317         }
14318     } else if (t->t == F_CHOWLIN) {
14319         gretl_matrix *Y = NULL;
14320         gretl_matrix *X = NULL;
14321         int fac = 0;
14322 
14323         if (k < 2 || k > 3) {
14324             n_args_error(k, 3, t->t, p);
14325         }
14326         for (i=0; i<k && !p->err; i++) {
14327             e = eval(n->v.bn.n[i], p);
14328             if (i == 0) {
14329                 /* Y matrix */
14330                 if (e->t == MAT) {
14331                     Y = e->v.m;
14332                 } else {
14333                     p->err = E_TYPES;
14334                 }
14335             } else if (i == 1) {
14336                 /* expansion factor */
14337                 fac = node_get_int(e, p);
14338             } else if (i == 2) {
14339                 /* optional X matrix  */
14340                 if (e->t == MAT) {
14341                     X = e->v.m;
14342                 } else if (!null_node(e)) {
14343                     p->err = E_TYPES;
14344                 }
14345             }
14346         }
14347         if (!p->err) {
14348             reset_p_aux(p, save_aux);
14349             ret = aux_matrix_node(p);
14350         }
14351         if (!p->err) {
14352             ret->v.m = matrix_chowlin(Y, X, fac, &p->err);
14353         }
14354     } else if (t->t == F_MIDASMULT) {
14355         gretl_bundle *mb = NULL;
14356 	int cum = 0;
14357 	int idx = 1;
14358 
14359         if (k < 1 || k > 3) {
14360             n_args_error(k, 3, t->t, p);
14361         }
14362         for (i=0; i<k && !p->err; i++) {
14363             e = eval(n->v.bn.n[i], p);
14364 	    if (p->err) break;
14365             if (i == 0) {
14366                 if (e->t == BUNDLE) {
14367                     mb = e->v.b;
14368                 } else {
14369                     p->err = E_TYPES;
14370                 }
14371             } else if (i == 1) {
14372 		/* cumulate? */
14373 		cum = node_get_bool(e, p, 0);
14374             } else if (!null_node(e)) {
14375 		/* index of MIDAS term? */
14376 		idx = node_get_int(e, p);
14377 	    }
14378         }
14379         if (!p->err) {
14380             reset_p_aux(p, save_aux);
14381             ret = aux_matrix_node(p);
14382         }
14383         if (!p->err) {
14384             ret->v.m = midas_multipliers(mb, cum, idx, &p->err);
14385         }
14386     } else if (t->t == F_TDISAGG) {
14387         gretl_matrix *Y = NULL;
14388         gretl_matrix *X = NULL;
14389         gretl_bundle *b = NULL;
14390         gretl_bundle *r = NULL;
14391         const double *yval = NULL;
14392         const double *xval = NULL;
14393         const int *ylist = NULL;
14394         const int *xlist = NULL;
14395         int fac = 0;
14396         int ynum = 0;
14397         int xnum = 0;
14398         int yconv = 0;
14399         int xconv = 0;
14400         int xmidas = 0;
14401 
14402         if (k < 3 || k > 5) {
14403             n_args_error(k, 4, t->t, p);
14404         }
14405         for (i=0; i<k && !p->err; i++) {
14406             e = eval(n->v.bn.n[i], p);
14407             if (i == 0) {
14408                 /* Y: matrix, series or list */
14409                 if (e->t == MAT) {
14410                     Y = e->v.m;
14411                 } else if (e->t == SERIES) {
14412                     ynum = e->vnum;
14413                     yval = e->v.xvec;
14414                     yconv = 1;
14415                 } else if (e->t == LIST) {
14416                     ylist = e->v.ivec;
14417                     yconv = 1;
14418                 } else {
14419                     p->err = E_TYPES;
14420                 }
14421             } else if (i == 1) {
14422                 /* X: matrix, series, list or null */
14423                 if (e->t == MAT) {
14424                     X = e->v.m;
14425                 } else if (e->t == SERIES) {
14426                     xnum = e->vnum;
14427                     xval = e->v.xvec;
14428                     xconv = 1;
14429                 } else if (e->t == LIST) {
14430                     if (gretl_is_midas_list(e->v.ivec, p->dset)) {
14431                         xlist = e->v.ivec;
14432                         xmidas = 1;
14433                     } else {
14434                         xlist = e->v.ivec;
14435                         xconv = 1;
14436                     }
14437                 } else if (!null_node(e)) {
14438                     p->err = E_TYPES;
14439                 }
14440             } else if (i == 2) {
14441                 /* integer expansion factor */
14442                 fac = node_get_int(e, p);
14443             } else if (i == 3) {
14444                 /* optional options bundle */
14445                 if (e->t == BUNDLE) {
14446                     b = e->v.b;
14447                 } else if (!null_node(e)) {
14448                     p->err = E_TYPES;
14449                 }
14450             } else if (e->t == BUNDLE) {
14451                 /* optional retrieval bundle */
14452                 r = e->v.b;
14453             } else if (!null_node(e)) {
14454                 p->err = E_TYPES;
14455             }
14456         }
14457         if (!p->err && (yconv || xconv || xmidas)) {
14458             /* Conversion from dataset object to matrix
14459                is needed, for Y and/or X.
14460             */
14461             int save_t1 = p->dset->t1;
14462             int save_t2 = p->dset->t2;
14463             int t1 = p->dset->t1;
14464             int t2 = p->dset->t2;
14465             int yt2 = 0, xt2 = 0;
14466             int cfac = 1;
14467 
14468             if (yconv) {
14469                 cfac = tdisagg_get_y_compression(ynum, xconv, fac, p);
14470             }
14471             if (yconv && (xconv || xmidas)) {
14472                 p->err = tdisagg_get_start_stop(ynum, ylist, xnum, xlist,
14473                                                 p->dset, cfac, xmidas, &t1,
14474                                                 &yt2, &xt2);
14475                 if (!p->err) {
14476                     p->dset->t1 = t1;
14477                 }
14478             } else if (yconv) {
14479                 p->err = tdisagg_get_y_start_stop(ynum, ylist, p->dset,
14480                                                   cfac, &t1, &t2);
14481                 if (!p->err) {
14482                     p->dset->t1 = t1;
14483                     p->dset->t2 = t2;
14484                 }
14485             }
14486             if (!p->err && yconv) {
14487                 if (yt2 > 0) {
14488                     p->dset->t2 = yt2;
14489                 }
14490                 Y = tdisagg_matrix_from_series(yval, ynum, ylist, p->dset,
14491                                                cfac, &p->err);
14492             }
14493             if (!p->err && xconv) {
14494                 if (xt2 > 0) {
14495                     p->dset->t2 = xt2;
14496                 }
14497                 X = tdisagg_matrix_from_series(xval, xnum, xlist, p->dset,
14498                                                1, &p->err);
14499             } else if (!p->err && xmidas) {
14500                 if (xt2 > 0) {
14501                     p->dset->t2 = xt2;
14502                 }
14503                 X = midas_list_to_vector(xlist, p->dset, &p->err);
14504             }
14505             p->dset->t1 = save_t1;
14506             p->dset->t2 = save_t2;
14507         }
14508         if (!p->err) {
14509             reset_p_aux(p, save_aux);
14510             ret = aux_matrix_node(p);
14511         }
14512         if (!p->err) {
14513             DATASET *dset = (yconv || xconv || xmidas)? p->dset : NULL;
14514 
14515             ret->v.m = matrix_tdisagg(Y, X, fac, b, r, dset,
14516                                       p->prn, &p->err);
14517         }
14518         if (yconv) {
14519             gretl_matrix_free(Y);
14520         }
14521         if (xconv || xmidas) {
14522             gretl_matrix_free(X);
14523         }
14524     }
14525 
14526     return ret;
14527 }
14528 
14529 /* Create a temporary empty node to handle the case where,
14530    in feval(), we get fewer arguments than the max for a
14531    built-in function. If the missing (presumably trailing)
14532    arguments are optional this will work OK; otherwise the
14533    called function will flag the appropriate error.
14534 */
14535 
auxempty(int * del)14536 static NODE *auxempty (int *del)
14537 {
14538     NODE *n = newempty();
14539 
14540     *del = 1;
14541     return n;
14542 }
14543 
eval_feval(NODE * t,parser * p)14544 static NODE *eval_feval (NODE *t, parser *p)
14545 {
14546     NODE *save_aux = p->aux;
14547     NODE *n = t->L;
14548     NODE *e, *ret = NULL;
14549     int argc, f = 0;
14550     ufunc *u = NULL;
14551     int i, k = n->v.bn.n_nodes;
14552 
14553     if (k < 1) {
14554         p->err = E_ARGS;
14555         return NULL;
14556     }
14557 
14558 #if AUX_NODES_DEBUG
14559     fprintf(stderr, "feval: p->aux = %p, t->aux = %p\n",
14560             (void *) p->aux, (void *) t->aux);
14561 #endif
14562 
14563     argc = k - 1;
14564 
14565     /* evaluate the first (string) arg: should be the
14566        name of a function */
14567     e = eval(n->v.bn.n[0], p);
14568     if (!p->err && e->t != STR) {
14569         node_type_error(t->t, 1, STR, e, p);
14570     }
14571 
14572     reset_p_aux(p, save_aux);
14573 
14574     if (!p->err) {
14575         /* try for a built-in function */
14576 	int del[3] = {0};
14577 
14578         f = function_lookup(e->v.str);
14579         if (f != 0) {
14580             NODE *fn = aux_parent_node(p);
14581             int np;
14582 
14583             fn->t = f;
14584 	    if (f < FP_MAX) {
14585 		fn->v.ptr = get_genr_function_pointer(f);
14586 	    }
14587             fn->flags |= TMP_NODE;
14588 
14589 	    np = func1_symb(f) ? 1 : func2_symb(f) ? 2 :
14590 		func3_symb(f) ? 3 : -1;
14591 
14592 	    if (np > 0) {
14593 		/* known max number of arguments */
14594 		if (argc > np) {
14595 		    gretl_errmsg_sprintf("%s: too many arguments", e->v.str);
14596 		    p->err = E_DATA;
14597 		} else if (np == 1) {
14598                     fn->L = argc > 0 ? n->v.bn.n[1] : auxempty(&del[0]);
14599                 } else if (np == 2) {
14600 		    fn->L = argc > 0 ? n->v.bn.n[1] : auxempty(&del[0]);
14601                     fn->R = argc > 1 ? n->v.bn.n[2] : auxempty(&del[2]);
14602                 } else if (np == 3) {
14603                     fn->L = argc > 0 ? n->v.bn.n[1] : auxempty(&del[0]);
14604                     fn->M = argc > 1 ? n->v.bn.n[2] : auxempty(&del[1]);
14605                     fn->R = argc > 2 ? n->v.bn.n[3] : auxempty(&del[2]);
14606                 }
14607 	    } else {
14608                 /* multi-arg function */
14609                 NODE *args = fn->L;
14610 
14611                 if (args != NULL && args->t != FARGS) {
14612                     fprintf(stderr, "feval, multiargs, fn type is wrong!\n");
14613                     p->err = E_DATA;
14614                 }
14615                 if (args == NULL) {
14616                     fn->L = args = newempty();
14617                     args->t = FARGS;
14618                     args->v.bn.n_nodes = argc;
14619                     args->v.bn.n = malloc(argc * sizeof(NODE *));
14620                 }
14621                 if (!p->err) {
14622                     for (i=1; i<k; i++) {
14623                         args->v.bn.n[i-1] = n->v.bn.n[i];
14624                     }
14625                 }
14626             }
14627             if (!p->err) {
14628                 ret = eval(fn, p);
14629                 /* there was a leak here, OK now? */
14630 #if AUX_NODES_DEBUG
14631                 fprintf(stderr, "feval: attach aux at %p (%s) to %p\n",
14632                         (void *) fn, getsymb(fn->t), (void *) t);
14633 #endif
14634                 t->aux = fn;
14635 		if (np > 0) {
14636 		    /* destroy "auxempty" nodes, if any were created */
14637 		    if (del[0]) {
14638 			free(fn->L); fn->L = NULL;
14639 		    }
14640 		    if (del[1]) {
14641 			free(fn->M); fn->M = NULL;
14642 		    }
14643 		    if (del[2]) {
14644 			free(fn->R); fn->R = NULL;
14645 		    }
14646 		}
14647             }
14648         }
14649     }
14650 
14651     if (!p->err && f == 0) {
14652         /* try for a user function */
14653         u = get_user_function_by_name(e->v.str);
14654         if (u != NULL) {
14655             NODE tmp = {0};
14656             NODE l = {0};
14657             NODE r = {0};
14658 
14659             tmp.t = UFUN;
14660             l.vname = e->v.str;
14661             l.v.ptr = u;
14662             r.v.bn.n_nodes = argc;
14663             r.v.bn.n = malloc(argc * sizeof(NODE *));
14664             for (i=1; i<k; i++) {
14665                 r.v.bn.n[i-1] = n->v.bn.n[i];
14666             }
14667             tmp.L = &l;
14668             tmp.R = &r;
14669             ret = eval_ufunc(&tmp, p, NULL);
14670             reset_p_aux(p, save_aux); /* tmp.aux? */
14671             free(r.v.bn.n);
14672         }
14673     }
14674 
14675     if (!p->err && f == 0 && u == NULL) {
14676         gretl_errmsg_sprintf("%s: function not found", e->v.str);
14677     }
14678 
14679     return ret;
14680 }
14681 
14682 /* try to get a matrix from @n, even if it's not in fact a
14683    matrix node as such, provided we can make a matrix out
14684    of its content
14685 */
14686 
node_get_matrix_lenient(NODE * n,int ok,parser * p)14687 static gretl_matrix *node_get_matrix_lenient (NODE *n,
14688                                               int ok,
14689                                               parser *p)
14690 {
14691     gretl_matrix *m = NULL;
14692 
14693     if (n->t == NUM && (ok == NUM)) {
14694         m = gretl_matrix_from_scalar(n->v.xval);
14695     } else if (n->t == SERIES && (ok == SERIES)) {
14696         m = gretl_vector_from_series(n->v.xvec, p->dset->t1,
14697                                      p->dset->t2);
14698     } else if (n->t == LIST && (ok == SERIES)) {
14699         m = gretl_matrix_data_subset(n->v.ivec, p->dset,
14700                                      p->dset->t1, p->dset->t2,
14701                                      M_MISSING_OK, &p->err);
14702     } else {
14703         p->err = E_TYPES;
14704     }
14705 
14706     if (!p->err && m == NULL) {
14707         p->err = E_ALLOC;
14708     }
14709 
14710     return m;
14711 }
14712 
get_kalman_bundle_arg(NODE * n,parser * p)14713 static gretl_bundle *get_kalman_bundle_arg (NODE *n, parser *p)
14714 {
14715     gretl_bundle *b = NULL;
14716     NODE *e = NULL;
14717 
14718     if (n->t == FARGS) {
14719         /* multi-arguments node */
14720         e = n->v.bn.n[0];
14721         e = e->L;
14722     } else if (n->t == U_ADDR) {
14723         e = n->L;
14724     } else if (n->t == BUNDLE) {
14725         e = n;
14726     }
14727 
14728     if (e == NULL || e->t != BUNDLE) {
14729         p->err = E_TYPES;
14730     } else {
14731         b = e->v.b; /* get the actual bundle */
14732         if (gretl_bundle_get_type(b) != BUNDLE_KALMAN ||
14733             gretl_bundle_get_private_data(b) == NULL) {
14734             p->err = E_TYPES;
14735             b = NULL;
14736         }
14737     }
14738 
14739     if (p->err) {
14740         gretl_errmsg_set("Argument 1 must point to a state-space bundle");
14741     }
14742 
14743     return b;
14744 }
14745 
eval_kalman_bundle_func(NODE * t,parser * p)14746 static NODE *eval_kalman_bundle_func (NODE *t, parser *p)
14747 {
14748     NODE *save_aux = p->aux;
14749     NODE *n = t->L;
14750     NODE *ret = NULL;
14751     NODE *e = NULL;
14752     int i, k = n->v.bn.n_nodes;
14753 
14754     if (t->t == F_KSETUP) {
14755         gretl_matrix *M[5] = {NULL};
14756         int copy[5] = {0};
14757 
14758         if (k < 4) {
14759             n_args_error(k, 4, t->t, p);
14760         }
14761 
14762         for (i=0; i<k && !p->err; i++) {
14763             e = eval(n->v.bn.n[i], p);
14764             if (!p->err) {
14765                 if (e->t == MAT) {
14766                     M[i] = mat_node_get_real_matrix(e, p);
14767                     if (!p->err) {
14768                         if (is_tmp_node(e)) {
14769                             e->v.m = NULL;
14770                         } else {
14771                             copy[i] = 1;
14772                         }
14773                     }
14774                 } else if (i == 0) {
14775                     /* obsy: accept series or list */
14776                     M[i] = node_get_matrix_lenient(e, SERIES, p);
14777                 } else {
14778                     /* system matrices, state variance */
14779                     M[i] = node_get_matrix_lenient(e, NUM, p);
14780                 }
14781             }
14782         }
14783 
14784         if (!p->err) {
14785             gretl_bundle *b = kalman_bundle_new(M, copy, k, &p->err);
14786 
14787             if (!p->err) {
14788                 reset_p_aux(p, save_aux);
14789                 ret = aux_bundle_node(p);
14790                 if (ret != NULL) {
14791                     ret->v.b = b;
14792                 }
14793             }
14794         }
14795     } else if (t->t == F_KFILTER) {
14796         gretl_bundle *b = get_kalman_bundle_arg(n, p);
14797 
14798         if (!p->err && k != 1) {
14799             n_args_error(k, 1, t->t, p);
14800         }
14801         if (!p->err) {
14802             reset_p_aux(p, save_aux);
14803             ret = aux_scalar_node(p);
14804         }
14805         if (!p->err) {
14806             ret->v.xval = kalman_bundle_run(b, p->prn, &p->err);
14807         }
14808     } else if (t->t == F_KDSMOOTH) {
14809         gretl_bundle *b = get_kalman_bundle_arg(n, p);
14810         int param = 1;
14811         int dkstyle = 0;
14812 
14813         if (!p->err) {
14814             if (k == 2) {
14815                 e = eval(n->v.bn.n[1], p);
14816                 dkstyle = node_get_int(e, p);
14817             } else if (k < 1 || k > 2) {
14818                 n_args_error(k, 2, t->t, p);
14819             }
14820         }
14821         if (!p->err) {
14822             param += dkstyle != 0;
14823             reset_p_aux(p, save_aux);
14824             ret = aux_scalar_node(p);
14825             if (!p->err) {
14826                 ret->v.xval = kalman_bundle_smooth(b, param, p->prn);
14827             }
14828         }
14829     } else if (t->t == F_KSMOOTH) {
14830         gretl_bundle *b = get_kalman_bundle_arg(n, p);
14831 
14832         if (!p->err && k != 1) {
14833             n_args_error(k, 1, t->t, p);
14834         }
14835         if (!p->err) {
14836             reset_p_aux(p, save_aux);
14837             ret = aux_scalar_node(p);
14838             if (!p->err) {
14839                 ret->v.xval = kalman_bundle_smooth(b, 0, p->prn);
14840             }
14841         }
14842     } else if (t->t == F_KSIMUL) {
14843         /* we need a bundle pointer, a matrix,
14844            and perhaps an optional boolean
14845         */
14846         gretl_bundle *b = get_kalman_bundle_arg(n, p);
14847         gretl_matrix *U = NULL;
14848         int freeU = 0;
14849         int get_state = 0;
14850 
14851         if (!p->err && k != 2 && k != 3) {
14852             n_args_error(k, 2, t->t, p);
14853         }
14854 
14855         for (i=1; i<k && !p->err; i++) {
14856             e = eval(n->v.bn.n[i], p);
14857             if (!p->err && i == 1) {
14858                 if (e->t == MAT) {
14859                     U = mat_node_get_real_matrix(e, p);
14860                 } else {
14861                     U = node_get_matrix_lenient(e, SERIES, p);
14862                     if (U != NULL) {
14863                         freeU = 1;
14864                     }
14865                 }
14866             } else if (!p->err) {
14867                 get_state = node_get_int(e, p);
14868             }
14869         }
14870 
14871         if (!p->err) {
14872             reset_p_aux(p, save_aux);
14873             ret = aux_matrix_node(p);
14874         }
14875         if (!p->err) {
14876             ret->v.m = kalman_bundle_simulate(b, U, get_state,
14877                                               p->prn, &p->err);
14878         }
14879 
14880         if (freeU) gretl_matrix_free(U);
14881     }
14882 
14883     return ret;
14884 }
14885 
kalman_data_node(NODE * l,NODE * r,parser * p)14886 static NODE *kalman_data_node (NODE *l, NODE *r, parser *p)
14887 {
14888     NODE *save_aux = p->aux;
14889     gretl_bundle *b = get_kalman_bundle_arg(l, p);
14890     NODE *ret = NULL;
14891 
14892     if (!p->err) {
14893         reset_p_aux(p, save_aux);
14894         ret = aux_matrix_node(p);
14895     }
14896     if (!p->err) {
14897         ret->v.m = kalman_bundle_simdata(b, r->v.m, p->prn, &p->err);
14898     }
14899 
14900     return ret;
14901 }
14902 
14903 /* Create a matrix using selected series, or a mixture of series and
14904    lists, or more than one list.  We proceed by setting up a "dummy"
14905    dataset and constructing a list that indexes into it.  (We can't
14906    use a regular list, in the general case, since some of the series
14907    may be temporary variables that are not part of the "real"
14908    dataset.)
14909 */
14910 
assemble_matrix(GPtrArray * a,int nnodes,parser * p)14911 static gretl_matrix *assemble_matrix (GPtrArray *a, int nnodes, parser *p)
14912 {
14913     NODE *n;
14914     gretl_matrix *m = NULL;
14915     const int *list;
14916     double **Z = NULL;
14917     int *dumlist;
14918     int i, j, k = 0;
14919 
14920 #if EDEBUG
14921     fprintf(stderr, "assemble_matrix...\n");
14922 #endif
14923 
14924     if (nnodes == 1 && get_matrix_mask() == NULL) {
14925         /* take a shortcut if we just got a single series
14926            and there's no "matrix mask" in place
14927         */
14928         n = g_ptr_array_index(a, 0);
14929         if (n->t == SERIES) {
14930             m = series_to_matrix(n->v.xvec, p);
14931             return m;
14932         }
14933     }
14934 
14935     /* how many columns will we need? */
14936     for (i=0; i<nnodes; i++) {
14937         n = g_ptr_array_index(a, i);
14938         if (n->t == LIST) {
14939             k += n->v.ivec[0];
14940         } else if (n->t == SERIES) {
14941             k++;
14942         }
14943     }
14944 
14945     /* create dummy data array */
14946     Z = malloc(k * sizeof *Z);
14947     if (Z == NULL) {
14948         p->err = E_ALLOC;
14949         return NULL;
14950     }
14951 
14952 #if EDEBUG
14953     fprintf(stderr, " got %d columns, Z at %p\n", k, (void *) Z);
14954 #endif
14955 
14956     /* and a list associated with Z */
14957     dumlist = gretl_consecutive_list_new(0, k-1);
14958     if (dumlist == NULL) {
14959         p->err = E_ALLOC;
14960         free(Z);
14961         return NULL;
14962     }
14963 
14964     /* attach series pointers to Z */
14965     k = 0;
14966     for (i=0; i<nnodes; i++) {
14967         n = g_ptr_array_index(a, i);
14968         if (n->t == LIST) {
14969             list = n->v.ivec;
14970             for (j=1; j<=list[0]; j++) {
14971                 Z[k++] = p->dset->Z[list[j]];
14972             }
14973         } else if (n->t == SERIES) {
14974             Z[k++] = n->v.xvec;
14975         }
14976     }
14977 
14978     if (!p->err) {
14979         DATASET dumset = {0};
14980 
14981         dumset.Z = Z;
14982         dumset.v = k;
14983         dumset.n = p->dset->n;
14984         dumset.t1 = p->dset->t1;
14985         dumset.t2 = p->dset->t2;
14986 
14987         m = real_matrix_from_list(dumlist, &dumset, p);
14988     }
14989 
14990     free(dumlist);
14991     free(Z);
14992 
14993     return m;
14994 }
14995 
14996 #define ok_matdef_sym(s) (s == NUM || s == SERIES || s == EMPTY || \
14997                           s == DUM || s == LIST || s == ARRAY)
14998 
14999 /* composing a matrix from scalars, series or lists */
15000 
matrix_def_node(NODE * nn,parser * p)15001 static NODE *matrix_def_node (NODE *nn, parser *p)
15002 {
15003     GPtrArray *a;
15004     gretl_matrix *M = NULL;
15005     NODE *save_aux = p->aux;
15006     NODE *n, *ret = NULL;
15007     int k = nn->v.bn.n_nodes;
15008     int nnum = 0, nvec = 0;
15009     int dum = 0, nsep = 0;
15010     int nlist = 0;
15011     int seppos = -1;
15012     int i;
15013 
15014     if (autoreg(p)) {
15015         fprintf(stderr, "You can't define a matrix in this context\n");
15016         p->err = E_TYPES;
15017         return NULL;
15018     }
15019 
15020 #if EDEBUG
15021     fprintf(stderr, "Processing MDEF...\n");
15022 #endif
15023 
15024     a = g_ptr_array_sized_new(k);
15025 
15026     for (i=0; i<k && !p->err; i++) {
15027         n = eval(nn->v.bn.n[i], p);
15028         if (n == NULL && !p->err) {
15029             p->err = E_UNSPEC; /* "can't happen" */
15030         }
15031         if (p->err) {
15032             break;
15033         }
15034         if (!ok_matdef_sym(n->t) && !scalar_matrix_node(n)) {
15035             fprintf(stderr, "matrix_def_node: node type %d: not OK\n", n->t);
15036             p->err = E_TYPES;
15037             break;
15038         }
15039         if (scalar_node(n)) {
15040             nnum++;
15041         } else if (n->t == SERIES) {
15042             nvec++;
15043         } else if (n->t == DUM) {
15044             dum++;
15045         } else if (n->t == LIST) {
15046             nlist++;
15047         } else if (n->t == EMPTY) {
15048             if (nsep == 0) {
15049                 seppos = i;
15050             }
15051             nsep++;
15052         }
15053         if (dum && k != 1) {
15054             /* dummy, array must be singleton nodes */
15055             p->err = E_TYPES;
15056         } else if ((nvec || nlist) && nnum) {
15057             /* can't mix series/lists with scalars */
15058             p->err = E_TYPES;
15059         } else if ((nvec || nlist) && nsep) {
15060             /* can't have row separators in a matrix
15061                composed of series or lists */
15062             p->err = E_TYPES;
15063         }
15064         if (!p->err) {
15065             g_ptr_array_add(a, n);
15066         }
15067     }
15068 
15069     if (!p->err) {
15070         if (nvec > 0 || nlist > 1) {
15071             M = assemble_matrix(a, k, p);
15072         } else if (nnum > 0) {
15073             M = matrix_from_scalars(a, k, nsep, seppos, p);
15074         } else if (nlist) {
15075             M = matrix_from_list(g_ptr_array_index(a, 0), p);
15076         } else if (dum) {
15077             n = g_ptr_array_index(a, 0);
15078             if (n->v.idnum == DUM_DATASET) {
15079 		if (gretl_function_depth() > 0) {
15080 		    gretl_errmsg_set("'dataset' is not recognized as a list within functions");
15081 		    p->err = E_DATA;
15082 		} else {
15083 		    M = matrix_from_list(NULL, p);
15084 		}
15085             } else {
15086                 pprintf(p->prn, "Wrong sort of dummy var\n");
15087                 p->err = E_TYPES;
15088             }
15089         } else {
15090             /* empty matrix def */
15091             M = gretl_null_matrix_new();
15092         }
15093     }
15094 
15095     if (a != NULL) {
15096         g_ptr_array_free(a, TRUE);
15097     }
15098 
15099     if (p->err) {
15100         if (M != NULL) {
15101             gretl_matrix_free(M);
15102         }
15103     } else {
15104         reset_p_aux(p, save_aux);
15105         ret = aux_matrix_node(p);
15106         if (ret != NULL) {
15107             ret->v.m = M;
15108         } else {
15109             gretl_matrix_free(M);
15110         }
15111     }
15112 
15113     return ret;
15114 }
15115 
gen_series_from_string(NODE * l,NODE * r,parser * p)15116 static NODE *gen_series_from_string (NODE *l, NODE *r, parser *p)
15117 {
15118     NODE *ret = NULL;
15119     gchar *line;
15120     int vnum = -1;
15121     int err = 0;
15122 
15123     line = g_strdup_printf("%s=%s", l->v.str, r->v.str);
15124     err = generate(line, p->dset, GRETL_TYPE_SERIES,
15125                    OPT_NONE, p->prn);
15126 
15127     if (!err) {
15128         vnum = current_series_index(p->dset, l->v.str);
15129     }
15130 
15131     ret = aux_scalar_node(p);
15132     if (ret != NULL) {
15133         ret->v.xval = vnum;
15134     }
15135 
15136     g_free(line);
15137 
15138     return ret;
15139 }
15140 
xvec_from_matrix(gretl_matrix * m,parser * p,int * subset,int * err)15141 static const double *xvec_from_matrix (gretl_matrix *m,
15142                                        parser *p,
15143                                        int *subset,
15144                                        int *err)
15145 {
15146     const double *ret = NULL;
15147 
15148     if (gretl_is_null_matrix(m) || m->cols != 1) {
15149         *err = E_TYPES;
15150     } else if (m->rows == p->dset->n) {
15151         ret = m->val;
15152     } else if (m->rows == sample_size(p->dset)) {
15153         *subset = 1;
15154         ret = m->val;
15155     } else {
15156         *err = E_TYPES;
15157     }
15158 
15159     return ret;
15160 }
15161 
gen_series_node(NODE * l,NODE * r,parser * p)15162 static NODE *gen_series_node (NODE *l, NODE *r, parser *p)
15163 {
15164     NODE *ret = NULL;
15165 
15166     if (p->dset == NULL || p->dset->n == 0) {
15167         no_data_error(p);
15168     } else if (l->t == STR && r->t == STR) {
15169         return gen_series_from_string(l, r, p);
15170     } else if (l->t != STR || (r->t != SERIES && r->t != MAT && r->t != NUM)) {
15171         p->err = E_TYPES;
15172     } else {
15173         char *vname = l->v.str;
15174         int vnum = current_series_index(p->dset, vname);
15175         const double *xvec = NULL;
15176         double xval = NADBL;
15177         int subset = 0;
15178         int err = 0;
15179 
15180         if (r->t == SERIES) {
15181             xvec = r->v.xvec;
15182         } else if (r->t == MAT) {
15183             xvec = xvec_from_matrix(r->v.m, p, &subset, &err);
15184         } else {
15185             xval = r->v.xval;
15186         }
15187 
15188         if (!err && vnum > 0) {
15189             /* a series of this name already exists */
15190             int t, i = 0;
15191 
15192             for (t=p->dset->t1; t<=p->dset->t2; t++) {
15193                 if (xvec != NULL) {
15194                     xval = subset ? xvec[i++] : xvec[t];
15195                 }
15196                 p->dset->Z[vnum][t] = xval;
15197             }
15198         } else if (!err) {
15199             /* creating a new series */
15200             GretlType ltype = user_var_get_type_by_name(vname);
15201 
15202             if (ltype != GRETL_TYPE_NONE) {
15203                 /* cannot overwrite a variable of another type */
15204                 err = E_TYPES;
15205             } else {
15206                 err = check_varname(vname);
15207             }
15208             if (!err) {
15209                 err = dataset_add_NA_series(p->dset, 1);
15210             }
15211             if (!err) {
15212                 int t, i = 0, v = p->dset->v - 1;
15213 
15214                 for (t=p->dset->t1; t<=p->dset->t2; t++) {
15215                     if (xvec != NULL) {
15216                         xval = subset ? xvec[i++] : xvec[t];
15217                     }
15218                     p->dset->Z[v][t] = xval;
15219                 }
15220             }
15221             if (!err) {
15222                 vnum = p->dset->v - 1;
15223                 strcpy(p->dset->varname[vnum], vname);
15224             }
15225         }
15226 
15227         ret = aux_scalar_node(p);
15228         if (ret != NULL) {
15229             ret->v.xval = err ? -1 : vnum;
15230         }
15231     }
15232 
15233     return ret;
15234 }
15235 
gen_array_node(NODE * n,parser * p)15236 static NODE *gen_array_node (NODE *n, parser *p)
15237 {
15238     NODE *ret = NULL;
15239 
15240     if (!null_or_scalar(n)) {
15241         p->err = E_TYPES;
15242     } else if (p->lh.gtype == 0) {
15243         gretl_errmsg_set(_("array: no type was specified"));
15244         p->err = E_DATA;
15245     } else {
15246         int len = 0;
15247 
15248         if (!null_node(n)) {
15249             len = node_get_int(n, p);
15250         }
15251 
15252         if (!p->err) {
15253             ret = aux_array_node(p);
15254             if (!p->err) {
15255                 ret->v.a = gretl_array_new(p->lh.gtype, len, &p->err);
15256             }
15257         }
15258     }
15259 
15260     return ret;
15261 }
15262 
get_series_stringvals(NODE * l,NODE * r,parser * p)15263 static NODE *get_series_stringvals (NODE *l, NODE *r, parser *p)
15264 {
15265     NODE *ret = aux_array_node(p);
15266 
15267     if (!p->err) {
15268         int v = l->vnum;
15269 
15270         if (is_string_valued(p->dset, v)) {
15271             int sub = node_get_bool(r, p, 0);
15272             int n_strs = 0;
15273             char **S;
15274 
15275             S = series_get_string_vals(p->dset, v, &n_strs, sub);
15276             ret->v.a = gretl_array_from_strings(S, n_strs, 1,
15277                                                 &p->err);
15278         } else {
15279             ret->v.a = gretl_array_new(GRETL_TYPE_STRINGS, 0, &p->err);
15280         }
15281     }
15282 
15283     return ret;
15284 }
15285 
stringify_series(NODE * l,NODE * r,parser * p)15286 static NODE *stringify_series (NODE *l, NODE *r, parser *p)
15287 {
15288     NODE *ret = aux_scalar_node(p);
15289 
15290     if (ret != NULL) {
15291         ret->v.xval = series_set_string_vals(p->dset, l->vnum, r->v.a);
15292         if (ret->v.xval != 0.0) {
15293             p->err = E_DATA;
15294         }
15295     }
15296 
15297     return ret;
15298 }
15299 
15300 enum {
15301     FORK_L,
15302     FORK_R,
15303     FORK_BOTH,
15304     FORK_NONE
15305 };
15306 
15307 /* Determine whether or not a series is constant in boolean terms,
15308    i.e. all elements zero, or all non-zero, over the relevant range.
15309    If so, return FORK_L (all 1) or FORK_R (all 0), othewise
15310    return FORK_UNK.
15311 */
15312 
vec_branch(const double * c,parser * p)15313 static int vec_branch (const double *c, parser *p)
15314 {
15315     int c1, t, t1, t2;
15316     int ret;
15317 
15318     t1 = autoreg(p) ? p->obs : p->dset->t1;
15319     t2 = autoreg(p) ? p->obs : p->dset->t2;
15320 
15321     c1 = (c[t1] != 0.0);
15322     ret = (c1)? FORK_L : FORK_R;
15323 
15324     for (t=t1; t<=t2; t++) {
15325         if (!na(c[t])) {
15326             if ((c1 && c[t] == 0) || (!c1 && c[t] != 0)) {
15327                 ret = FORK_BOTH;
15328                 break;
15329             }
15330         }
15331     }
15332 
15333     return ret;
15334 }
15335 
15336 /* Given a series condition in a ternary "?" expression, return the
15337    evaluated counterpart.  We evaluate both forks and select based on
15338    the value of the condition at each observation.  We accept only
15339    scalar (NUM or 1x1 matrix) and series (SERIES) types on input, and
15340    always produce a SERIES type on output.
15341 */
15342 
query_eval_series(const double * c,NODE * n,parser * p)15343 static NODE *query_eval_series (const double *c, NODE *n, parser *p)
15344 {
15345     NODE *l = NULL, *r = NULL, *ret = NULL;
15346     NODE *save_aux = p->aux;
15347     double *xvec = NULL, *yvec = NULL;
15348     double x = NADBL, y = NADBL;
15349     double xt, yt;
15350     int t, t1, t2;
15351     int branch;
15352 
15353     branch = vec_branch(c, p);
15354 
15355     if (autoreg(p) || branch != FORK_R) {
15356         l = eval(n->M, p);
15357         if (p->err) {
15358             return NULL;
15359         }
15360         if (l->t == SERIES) {
15361             xvec = l->v.xvec;
15362         } else if (scalar_node(l)) {
15363             x = node_get_scalar(l, p);
15364         } else {
15365             p->err = E_TYPES;
15366             return NULL;
15367         }
15368     }
15369 
15370     if (autoreg(p) || branch != FORK_L) {
15371         r = eval(n->R, p);
15372         if (p->err) {
15373             return NULL;
15374         }
15375         if (r->t == SERIES) {
15376             yvec = r->v.xvec;
15377         } else if (scalar_node(r)) {
15378             y = node_get_scalar(r, p);
15379         } else {
15380             p->err = E_TYPES;
15381             return NULL;
15382         }
15383     }
15384 
15385     reset_p_aux(p, save_aux);
15386     ret = aux_series_node(p);
15387 
15388     t1 = autoreg(p) ? p->obs : p->dset->t1;
15389     t2 = autoreg(p) ? p->obs : p->dset->t2;
15390 
15391     for (t=t1; t<=t2; t++) {
15392         if (na(c[t])) {
15393             ret->v.xvec[t] = NADBL;
15394         } else {
15395             xt = (xvec != NULL)? xvec[t] : x;
15396             yt = (yvec != NULL)? yvec[t] : y;
15397             ret->v.xvec[t] = (c[t] != 0.0)? xt : yt;
15398         }
15399     }
15400 
15401     return ret;
15402 }
15403 
15404 /* The condition in the ternary query operator is a scalar,
15405    which has been evaluated to @x, and which must now be
15406    interpreted as a boolean.
15407 */
15408 
query_eval_scalar(double x,NODE * n,parser * p)15409 static NODE *query_eval_scalar (double x, NODE *n, parser *p)
15410 {
15411     NODE *save_aux = p->aux;
15412     NODE *l = NULL, *r = NULL, *ret = NULL;
15413     int indef = na(x) || isnan(x);
15414     int branch;
15415 
15416     branch = indef ? FORK_NONE : (x != 0 ? FORK_L : FORK_R);
15417 
15418     if (autoreg(p) || branch != FORK_R) {
15419         l = eval(n->M, p);
15420         if (p->err) {
15421             return NULL;
15422         }
15423     }
15424 
15425     if (autoreg(p) || branch != FORK_L) {
15426         r = eval(n->R, p);
15427         if (p->err) {
15428             return NULL;
15429         }
15430     }
15431 
15432     if (branch == FORK_NONE) {
15433         reset_p_aux(p, save_aux);
15434         ret = aux_scalar_node(p);
15435         if (ret != NULL) {
15436             ret->v.xval = NADBL;
15437         }
15438     } else if (branch == FORK_L) {
15439         ret = l;
15440     } else if (branch == FORK_R) {
15441         ret = r;
15442     }
15443 
15444     return ret;
15445 }
15446 
15447 /* The following allows for @n to hold a scalar, real matrix
15448    or complex matrix, and also allows for the case where
15449    @n's payload is real-valued but a complex result is required,
15450    signalled by @need_z.
15451 */
15452 
query_term_get_value(NODE * n,int i,int j,double * py,double complex * pz,int need_z)15453 static void query_term_get_value (NODE *n, int i, int j,
15454 				  double *py, double complex *pz,
15455 				  int need_z)
15456 {
15457     if (n->t == MAT && n->v.m->is_complex) {
15458 	*pz = gretl_cmatrix_get(n->v.m, i, j);
15459     } else {
15460 	if (n->t == NUM) {
15461 	    *py = n->v.xval;
15462 	} else {
15463 	    *py = gretl_matrix_get(n->v.m, i, j);
15464 	}
15465 	if (need_z) {
15466 	    double complex z = *py + 0 * I;
15467 
15468 	    *pz = z;
15469 	}
15470     }
15471 }
15472 
15473 /* the condition in the ternary query operator is a matrix */
15474 
query_eval_matrix(gretl_matrix * m,NODE * n,parser * p)15475 static NODE *query_eval_matrix (gretl_matrix *m, NODE *n, parser *p)
15476 {
15477     NODE *save_aux = p->aux;
15478     NODE *ret, *l, *r;
15479     gretl_matrix *mret;
15480     int lcomplex = 0;
15481     int rcomplex = 0;
15482 
15483     if (gretl_is_null_matrix(m)) {
15484         p->err = E_TYPES;
15485         return NULL;
15486     }
15487 
15488     l = eval(n->M, p);
15489 
15490     if (!p->err) {
15491         r = eval(n->R, p);
15492     }
15493 
15494     if (p->err) {
15495         return NULL;
15496     }
15497 
15498     if ((l->t != NUM && l->t != MAT) ||
15499         (r->t != NUM && r->t != MAT)) {
15500         p->err = E_TYPES;
15501         return NULL;
15502     }
15503 
15504     if (l->t == MAT) {
15505 	if (l->v.m->cols != m->cols || l->v.m->rows != m->rows) {
15506 	    p->err = E_NONCONF;
15507 	    return NULL;
15508 	} else if (l->v.m->is_complex) {
15509 	    lcomplex = 1;
15510 	}
15511     } else if (r->t == MAT) {
15512 	if (r->v.m->cols != m->cols || r->v.m->rows != m->rows) {
15513 	    p->err = E_NONCONF;
15514 	    return NULL;
15515 	} else if (r->v.m->is_complex) {
15516 	    rcomplex = 1;
15517 	}
15518     }
15519 
15520     if (lcomplex || rcomplex) {
15521 	mret = gretl_cmatrix_build(m, NULL, 0, 0, &p->err);
15522     } else {
15523 	mret = gretl_matrix_copy(m);
15524 	if (mret == NULL) {
15525 	    p->err = E_ALLOC;
15526 	}
15527     }
15528     if (p->err) {
15529 	return NULL;
15530     }
15531 
15532     reset_p_aux(p, save_aux);
15533     ret = aux_matrix_node(p);
15534 
15535     if (!p->err) {
15536 	int need_z = mret->is_complex;
15537 	double complex z;
15538         double x, y;
15539         int j, i;
15540 
15541         for (j=0; j<m->cols; j++) {
15542             for (i=0; i<m->rows; i++) {
15543                 x = gretl_matrix_get(m, i, j);
15544                 if (isnan(x)) {
15545 		    if (mret->is_complex) {
15546 			gretl_cmatrix_set(mret, i, j, x + x * I);
15547 		    } else {
15548 			gretl_matrix_set(mret, i, j, x);
15549 		    }
15550                 } else if (x != 0.0) {
15551 		    query_term_get_value(l, i, j, &y, &z, need_z);
15552 		    if (mret->is_complex) {
15553 			gretl_cmatrix_set(mret, i, j, z);
15554 		    } else {
15555 			gretl_matrix_set(mret, i, j, y);
15556 		    }
15557                 } else {
15558 		    query_term_get_value(r, i, j, &y, &z, need_z);
15559 		    if (mret->is_complex) {
15560 			gretl_cmatrix_set(mret, i, j, z);
15561 		    } else {
15562 			gretl_matrix_set(mret, i, j, y);
15563 		    }
15564                 }
15565             }
15566         }
15567         ret->v.m = mret;
15568     }
15569 
15570     return ret;
15571 }
15572 
15573 /* Evaluate a ternary "query" expression: C ? X : Y.  The condition C
15574    may be a scalar, series or matrix.  The relevant sub-nodes of @t
15575    are named "l" (left, the condition), "m" and "r" (middle and right
15576    respectively, the two alternates).
15577 */
15578 
eval_query(NODE * t,parser * p)15579 static NODE *eval_query (NODE *t, parser *p)
15580 {
15581     NODE *save_aux = p->aux;
15582     NODE *c, *ret = NULL;
15583 
15584     /* evaluate and check the condition */
15585     c = eval(t->L, p);
15586 
15587 #if EDEBUG
15588     fprintf(stderr, "eval_query: t=%p, l=%p, m=%p, r=%p\n",
15589             (void *) t, (void *) t->L, (void *) t->M,
15590             (void *) t->R);
15591     if (c->t == NUM) {
15592         fprintf(stderr, " condition type=NUM, value=%g\n", c->v.xval);
15593     } else {
15594         fprintf(stderr, " condition type=%s\n", getsymb(c->t));
15595     }
15596 #endif
15597 
15598     if (!p->err) {
15599         reset_p_aux(p, save_aux);
15600         if (c->t == NUM) {
15601             ret = query_eval_scalar(c->v.xval, t, p);
15602         } else if (c->t == SERIES) {
15603             ret = query_eval_series(c->v.xvec, t, p);
15604         } else if (c->t == MAT) {
15605             if (gretl_matrix_is_scalar(c->v.m)) {
15606                 ret = query_eval_scalar(c->v.m->val[0], t, p);
15607             } else {
15608                 ret = query_eval_matrix(c->v.m, t, p);
15609             }
15610         } else {
15611             /* invalid type for boolean condition */
15612             p->err = E_TYPES;
15613         }
15614     }
15615 
15616 #if EDEBUG
15617     fprintf(stderr, "eval_query return: ret = %p\n", (void *) ret);
15618 #endif
15619 
15620     return ret;
15621 }
15622 
15623 #define dvar_scalar(i) (i > 0 && i < R_SCALAR_MAX)
15624 #define dvar_series(i) (i > R_SCALAR_MAX && i < R_SERIES_MAX)
15625 #define dvar_matrix(i) (i == R_NOW)
15626 #define dvar_variant1(i) (i == R_TEST_STAT || i == R_TEST_PVAL)
15627 #define dvar_variant2(i) (i == R_RESULT)
15628 
15629 #define no_data(p) (p == NULL || p->n == 0)
15630 
dvar_get_scalar(int i,const DATASET * dset)15631 double dvar_get_scalar (int i, const DATASET *dset)
15632 {
15633     switch (i) {
15634     case R_NOBS:
15635         return (dset == NULL) ? NADBL :
15636         (dset->n == 0 ? 0 : sample_size(dset));
15637     case R_NVARS:
15638         return (dset == NULL)? NADBL : dset->v;
15639     case R_PD:
15640         return (no_data(dset))? NADBL : dset->pd;
15641     case R_T1:
15642         return (no_data(dset))? NADBL : dset->t1 + 1;
15643     case R_T2:
15644         return (no_data(dset))? NADBL : dset->t2 + 1;
15645     case R_TMAX:
15646         if (no_data(dset)) {
15647             return NADBL;
15648         } else {
15649             int tmax;
15650 
15651             sample_range_get_extrema(dset, NULL, &tmax);
15652             return tmax + 1;
15653         }
15654     case R_DATATYPE:
15655         return dataset_get_structure(dset);
15656     case R_TEST_PVAL:
15657         return get_last_pvalue();
15658     case R_TEST_STAT:
15659         return get_last_test_statistic();
15660     case R_TEST_LNL:
15661         return get_last_lnl();
15662     case R_TEST_BRK:
15663         return get_last_break();
15664     case R_STOPWATCH:
15665         return gretl_stopwatch();
15666     case R_WINDOWS:
15667 #ifdef WIN32
15668         return 1;
15669 #else
15670         return 0;
15671 #endif
15672     case R_VERSION:
15673         return gretl_version_number(GRETL_VERSION);
15674     case R_ERRNO:
15675         return get_gretl_errno();
15676     case R_SEED:
15677         return gretl_rand_get_seed();
15678     case R_HUGE:
15679         return libset_get_double(CONV_HUGE);
15680     case R_LOGLEVEL:
15681         return libset_get_int(LOGLEVEL);
15682     case R_LOGSTAMP:
15683 	return libset_get_bool(LOGSTAMP);
15684     default:
15685         return NADBL;
15686     }
15687 }
15688 
date_series_ok(const DATASET * dset)15689 static int date_series_ok (const DATASET *dset)
15690 {
15691     if (calendar_data(dset)) {
15692         return 1;
15693     } else if (quarterly_or_monthly(dset)) {
15694         return 1;
15695     } else if (annual_data(dset) || decennial_data(dset)) {
15696         return 1;
15697     } else if (dataset_has_panel_time(dset)) {
15698         return 1;
15699     } else {
15700         return 0;
15701     }
15702 }
15703 
dvar_get_series(double * x,int i,const DATASET * dset)15704 static int dvar_get_series (double *x, int i, const DATASET *dset)
15705 {
15706     int t, YMD = calendar_data(dset);
15707     int err = 0;
15708 
15709     if (dset == NULL || dset->n == 0) {
15710         return E_NODATA;
15711     }
15712 
15713     if (i == R_OBSMIN && dset->pd < 2) {
15714         return E_PDWRONG;
15715     }
15716 
15717     if (i == R_OBSMIC && !YMD) {
15718         return E_PDWRONG;
15719     }
15720 
15721     if (i == R_PUNIT && !dataset_is_panel(dset)) {
15722         return E_PDWRONG;
15723     }
15724 
15725     if (i == R_DATES && !date_series_ok(dset)) {
15726         return E_PDWRONG;
15727     }
15728 
15729     if (i == R_OBSMAJ) {
15730         if (dset->pd == 1 && !dataset_is_time_series(dset)) {
15731             i = R_INDEX;
15732         } else if (dataset_is_panel(dset)) {
15733             i = R_PUNIT;
15734         }
15735     }
15736 
15737     if (i == R_INDEX) {
15738         for (t=0; t<dset->n; t++) {
15739             x[t] = t + 1;
15740         }
15741     } else if (YMD && i != R_INDEX && i != R_DATES) {
15742         /* Watch out: we're handling most calendar-data cases
15743            here, so we have to explicitly exclude cases that
15744            require different treatment.
15745         */
15746         char obs[12];
15747         int y, m, d;
15748 
15749         for (t=0; t<dset->n && !err; t++) {
15750             ntolabel(obs, t, dset);
15751             if (sscanf(obs, YMD_READ_FMT, &y, &m, &d) != 3) {
15752 		err = E_DATA;
15753             } else if (i == R_OBSMAJ) {
15754                 x[t] = y;
15755             } else if (i == R_OBSMIN) {
15756                 x[t] = m;
15757             } else {
15758                 x[t] = d;
15759             }
15760         }
15761     } else if (i == R_PUNIT) {
15762         for (t=0; t<dset->n; t++) {
15763             x[t] = t / dset->pd + 1;
15764         }
15765     } else if (i == R_OBSMAJ) {
15766         int maj;
15767 
15768         for (t=0; t<dset->n; t++) {
15769             date_maj_min(t, dset, &maj, NULL);
15770             x[t] = maj;
15771         }
15772     } else if (i == R_OBSMIN) {
15773         int min;
15774 
15775         for (t=0; t<dset->n; t++) {
15776             date_maj_min(t, dset, NULL, &min);
15777             x[t] = min;
15778         }
15779     } else if (i == R_DATES) {
15780         err = fill_dataset_dates_series(dset, x);
15781     } else {
15782         err = E_DATA;
15783     }
15784 
15785     return err;
15786 }
15787 
dvar_get_matrix(int i,int * err)15788 static gretl_matrix *dvar_get_matrix (int i, int *err)
15789 {
15790     gretl_matrix *m = NULL;
15791 
15792     switch (i) {
15793     case R_TEST_STAT:
15794         m = get_last_test_matrix(err);
15795         break;
15796     case R_TEST_PVAL:
15797         m = get_last_pvals_matrix(err);
15798         break;
15799     case R_NOW:
15800         m = gretl_matrix_alloc(1, 2);
15801         if (m == NULL) {
15802             *err = E_ALLOC;
15803         } else {
15804             /* package epoch second and ISO 8601 basic date */
15805             time_t t = time(NULL);
15806             struct tm tm;
15807             int y, mon, d;
15808 
15809 #ifdef WIN32
15810             tm = *localtime(&t);
15811 #else
15812             localtime_r(&t, &tm);
15813 #endif
15814             y = tm.tm_year + 1900;
15815             mon = tm.tm_mon + 1;
15816             d = tm.tm_mday;
15817             m->val[0] = (double) t;
15818             m->val[1] = y * 10000 + mon * 100 + d;
15819         }
15820         break;
15821     default:
15822         *err = E_DATA;
15823         break;
15824     }
15825 
15826     return m;
15827 }
15828 
dollar_var_node(NODE * t,parser * p)15829 static NODE *dollar_var_node (NODE *t, parser *p)
15830 {
15831     NODE *ret = NULL;
15832 
15833     if (starting(p)) {
15834         int idx = t->v.idnum;
15835 
15836         if (dvar_scalar(idx)) {
15837             ret = aux_scalar_node(p);
15838             if (ret != NULL) {
15839                 ret->v.xval = dvar_get_scalar(idx, p->dset);
15840             }
15841         } else if (dvar_series(idx)) {
15842             ret = aux_series_node(p);
15843             if (ret != NULL) {
15844                 p->err = dvar_get_series(ret->v.xvec, idx, p->dset);
15845             }
15846         } else if (dvar_matrix(idx)) {
15847             ret = aux_matrix_node(p);
15848             if (ret != NULL) {
15849                 ret->v.m = dvar_get_matrix(idx, &p->err);
15850             }
15851         } else if (idx == R_PNGFONT) {
15852             ret = aux_string_node(p);
15853             if (ret != NULL) {
15854                 ret->v.str = gretl_png_font_string();
15855             }
15856         } else if (idx == R_MAPFILE) {
15857 	    const char *fname = dataset_get_mapfile(p->dset);
15858 
15859             ret = aux_string_node(p);
15860             if (!p->err) {
15861                 if (fname == NULL) {
15862                     ret->v.str = gretl_strdup("");
15863                 } else {
15864                     ret->v.str = gretl_strdup(fname);
15865                 }
15866             }
15867 	} else if (idx == R_MAP) {
15868 	    ret = aux_bundle_node(p);
15869 	    if (!p->err) {
15870 		ret->v.b = get_current_map(p->dset, NULL, &p->err);
15871 	    }
15872         } else if (dvar_variant1(idx)) {
15873             GretlType type = get_last_test_type();
15874 
15875             if (type == GRETL_TYPE_MATRIX) {
15876                 ret = aux_matrix_node(p);
15877                 if (ret != NULL) {
15878                     ret->v.m = dvar_get_matrix(idx, &p->err);
15879                 }
15880             } else {
15881                 /* scalar or none */
15882                 ret = aux_scalar_node(p);
15883                 if (ret != NULL) {
15884                     ret->v.xval = dvar_get_scalar(idx, p->dset);
15885                 }
15886             }
15887         } else if (dvar_variant2(idx)) {
15888             GretlType type = 0;
15889             void *ptr = get_last_result_data(&type, &p->err);
15890 
15891             if (type == GRETL_TYPE_MATRIX) {
15892                 ret = aux_matrix_node(p);
15893                 if (ret != NULL) {
15894                     ret->v.m = ptr;
15895                 }
15896             } else if (type == GRETL_TYPE_BUNDLE) {
15897                 ret = aux_bundle_node(p);
15898                 if (ret != NULL) {
15899                     ret->v.b = ptr;
15900                 }
15901             } else if (!p->err) {
15902                 p->err = E_TYPES;
15903             }
15904         }
15905     } else {
15906         ret = aux_any_node(p);
15907     }
15908 
15909     return ret;
15910 }
15911 
fevd_node(NODE * l,NODE * m,NODE * r,parser * p)15912 static NODE *fevd_node (NODE *l, NODE *m, NODE *r, parser *p)
15913 {
15914     NODE *ret = aux_matrix_node(p);
15915 
15916     if (ret != NULL) {
15917         int targ = node_get_int(l, p);
15918         int shock = 0;
15919 
15920         if (!p->err && !null_node(m)) {
15921             shock = node_get_int(m, p);
15922         }
15923         if (!p->err && !null_node(r) && r->t != BUNDLE) {
15924             p->err = E_INVARG;
15925         }
15926 
15927         if (!p->err) {
15928             /* convert @targ, @shock to zero-based */
15929             targ -= 1;
15930             shock -= 1;
15931             if (r->t == BUNDLE) {
15932                 ret->v.m = gretl_FEVD_from_bundle(r->v.b, targ, shock,
15933                                                   p->dset, &p->err);
15934             } else {
15935                 GretlObjType otype;
15936                 void *ptr;
15937 
15938                 ptr = get_last_model(&otype);
15939                 if (ptr == NULL || otype != GRETL_OBJ_VAR) {
15940                     p->err = E_BADSTAT;
15941                 } else {
15942                     ret->v.m = gretl_VAR_get_FEVD_matrix(ptr, targ, shock, 0,
15943                                                          p->dset, &p->err);
15944                 }
15945             }
15946         }
15947     }
15948 
15949     return ret;
15950 }
15951 
object_var_type(int idx,const char * oname,int * needs_data)15952 static GretlType object_var_type (int idx, const char *oname,
15953                                   int *needs_data)
15954 {
15955     GretlType vtype = GRETL_TYPE_NONE;
15956 
15957     *needs_data = 0;
15958 
15959     if (model_data_scalar(idx)) {
15960         vtype = GRETL_TYPE_DOUBLE;
15961     } else if (model_data_series(idx)) {
15962         vtype = GRETL_TYPE_SERIES;
15963     } else if (model_data_matrix(idx)) {
15964         vtype = GRETL_TYPE_MATRIX;
15965     } else if (model_data_matrix_builder(idx)) {
15966         vtype = GRETL_TYPE_MATRIX;
15967         *needs_data = 1;
15968     } else if (model_data_list(idx)) {
15969         vtype = GRETL_TYPE_LIST;
15970     } else if (model_data_string(idx)) {
15971         vtype = GRETL_TYPE_STRING;
15972     } else if (model_data_array(idx)) {
15973         vtype = GRETL_TYPE_ARRAY;
15974     } else if (idx == B_MODEL) {
15975         vtype = GRETL_TYPE_BUNDLE;
15976     } else if (idx == B_SYSTEM) {
15977         vtype = GRETL_TYPE_BUNDLE;
15978     }
15979 
15980     if (idx == M_UHAT || idx == M_YHAT || idx == M_SIGMA) {
15981         /* could be a matrix */
15982         vtype = saved_object_get_data_type(oname, idx);
15983     }
15984 
15985     return vtype;
15986 }
15987 
15988 /* For example, $coeff(sqft); or model1.$coeff(const) */
15989 
dollar_str_node(NODE * t,MODEL * pmod,parser * p)15990 static NODE *dollar_str_node (NODE *t, MODEL *pmod, parser *p)
15991 {
15992     NODE *ret = aux_scalar_node(p);
15993 
15994     if (ret != NULL && starting(p)) {
15995         const char *str = NULL;
15996         NODE *l = t->L;
15997         NODE *r = t->R;
15998 
15999         if (r->t == STR) {
16000             str = r->v.str;
16001         } else {
16002             /* could be element of strings array? */
16003             NODE *e = eval(r, p);
16004 
16005             if (e->t == STR) {
16006                 str = e->v.str;
16007             } else {
16008                 p->err = E_TYPES;
16009             }
16010         }
16011         if (!p->err) {
16012             ret->v.xval = gretl_model_get_data_element(pmod, l->v.idnum, str,
16013                                                        p->dset, &p->err);
16014         }
16015         if (p->err && r->t == STR) {
16016             pprintf(p->prn, _("'%s': invalid argument for %s()\n"),
16017                     r->v.str, mvarname(l->v.idnum));
16018         }
16019     }
16020 
16021     return ret;
16022 }
16023 
16024 /* Retrieve a data item from a model (single equation or system of
16025    some kind. We're not sure in advance here of the type of the data
16026    item (scalar, matrix, etc.): we look that up with object_var_type().
16027 
16028    If retrieval is from a named model, the model name will be given
16029    by the @vname member of @t and the key will be on node @k.
16030    Otherwise @k will be NULL and @t will already hold the index of
16031    the required data item.
16032 */
16033 
model_var_node(NODE * t,NODE * k,parser * p)16034 static NODE *model_var_node (NODE *t, NODE *k, parser *p)
16035 {
16036     NODE *ret = NULL;
16037 
16038     if (starting(p)) {
16039         const char *oname = NULL;
16040         int idx, needs_data = 0;
16041         GretlType vtype;
16042 
16043         if (t->t == DBUNDLE) {
16044             /* pseudo-bundle: holds name of model */
16045             oname = t->vname;
16046             idx = mvar_lookup(k->v.str);
16047             if (idx == 0) {
16048                 p->err = E_DATA;
16049                 return NULL;
16050             }
16051         } else {
16052             /* @t already holds the data-item index */
16053             idx = t->v.idnum;
16054         }
16055 
16056         /* determine the type of the requested data */
16057         vtype = object_var_type(idx, oname, &needs_data);
16058 
16059 #if EDEBUG
16060         fprintf(stderr, "model_var_node: idx = %d, vtype = %d\n", idx, vtype);
16061 #endif
16062 
16063         if (vtype == GRETL_TYPE_DOUBLE) {
16064             ret = aux_scalar_node(p);
16065         } else if (vtype == GRETL_TYPE_SERIES) {
16066             ret = aux_series_node(p);
16067         } else if (vtype == GRETL_TYPE_LIST) {
16068             ret = aux_list_node(p);
16069         } else if (vtype == GRETL_TYPE_STRING) {
16070             ret = aux_string_node(p);
16071         } else if (vtype == GRETL_TYPE_BUNDLE) {
16072             ret = aux_bundle_node(p);
16073         } else if (vtype == GRETL_TYPE_ARRAY) {
16074             ret = aux_array_node(p);
16075         } else {
16076             ret = aux_matrix_node(p);
16077         }
16078 
16079         if (ret == NULL) {
16080             return ret;
16081         } else if (vtype == GRETL_TYPE_DOUBLE) {
16082             ret->v.xval = saved_object_get_scalar(oname, idx, p->dset,
16083                                                   &p->err);
16084         } else if (vtype == GRETL_TYPE_SERIES) {
16085             p->err = saved_object_get_series(ret->v.xvec, oname, idx, p->dset);
16086         } else if (vtype == GRETL_TYPE_LIST) {
16087             ret->v.ivec = saved_object_get_list(oname, idx, &p->err);
16088         } else if (vtype == GRETL_TYPE_STRING) {
16089             ret->v.str = saved_object_get_string(oname, idx, p->dset,
16090                                                  &p->err);
16091         } else if (vtype == GRETL_TYPE_BUNDLE) {
16092             ret->v.b = bundle_from_model(NULL, p->dset, &p->err);
16093         } else if (vtype == GRETL_TYPE_MATRIX) {
16094             if (needs_data) {
16095                 ret->v.m = saved_object_build_matrix(oname, idx,
16096                                                      p->dset, &p->err);
16097             } else {
16098                 ret->v.m = saved_object_get_matrix(oname, idx, &p->err);
16099             }
16100         } else if (vtype == GRETL_TYPE_ARRAY) {
16101             ret->v.a = saved_object_get_array(oname, idx, p->dset, &p->err);
16102         }
16103     } else {
16104         ret = aux_any_node(p);
16105     }
16106 
16107     return ret;
16108 }
16109 
wildlist_node(NODE * n,parser * p)16110 static NODE *wildlist_node (NODE *n, parser *p)
16111 {
16112     NODE *ret = aux_list_node(p);
16113 
16114     if (ret != NULL && starting(p)) {
16115         int *list = varname_match_list(p->dset, n->v.str,
16116                                        &p->err);
16117 
16118         ret->v.ivec = list;
16119     }
16120 
16121     return ret;
16122 }
16123 
ellipsis_list_node(NODE * l,NODE * r,parser * p)16124 static NODE *ellipsis_list_node (NODE *l, NODE *r, parser *p)
16125 {
16126     NODE *ret = aux_list_node(p);
16127 
16128     if (ret != NULL && starting(p)) {
16129         int v1 = useries_node(l) ? l->vnum : l->v.xval;
16130         int v2 = useries_node(r) ? r->vnum : r->v.xval;
16131 
16132         ret->v.ivec = ellipsis_list(p->dset, v1, v2, &p->err);
16133     }
16134 
16135     return ret;
16136 }
16137 
16138 /* see if a plain NUM node can be interpreted as holding a
16139    series ID, in the context of creating a list */
16140 
could_be_series_id(NODE * n,parser * p)16141 static int could_be_series_id (NODE *n, parser *p)
16142 {
16143     if (n->t == NUM && p->dset != NULL && p->dset->n > 0) {
16144         int k = node_get_int(n, p);
16145 
16146         if (!p->err && k >= 0 && k < p->dset->v) {
16147             return 1;
16148         }
16149     }
16150 
16151     return 0;
16152 }
16153 
list_join_node(NODE * l,NODE * r,parser * p)16154 static NODE *list_join_node (NODE *l, NODE *r, parser *p)
16155 {
16156     NODE *ret = aux_list_node(p);
16157 
16158     if (ret != NULL && starting(p)) {
16159         int *L1 = node_get_list(l, p);
16160         int *L2 = node_get_list(r, p);
16161 
16162         if (!p->err) {
16163             ret->v.ivec = gretl_lists_join_with_separator(L1, L2);
16164             if (ret->v.ivec == NULL) {
16165                 p->err = E_ALLOC;
16166             }
16167         }
16168 
16169         free(L1);
16170         free(L2);
16171     }
16172 
16173     return ret;
16174 }
16175 
two_scalars_func(NODE * l,NODE * r,int t,parser * p)16176 static NODE *two_scalars_func (NODE *l, NODE *r, int t, parser *p)
16177 {
16178     NODE *ret = aux_scalar_node(p);
16179 
16180     if (ret != NULL && starting(p)) {
16181         double xl = node_get_scalar(l, p);
16182         double xr = node_get_scalar(r, p);
16183 
16184         if (!na(xl) && !na(xr)) {
16185             if (t == F_XMIN) {
16186                 ret->v.xval = (xl < xr)? xl : xr;
16187             } else if (t == F_XMAX) {
16188                 ret->v.xval = (xl > xr)? xl : xr;
16189             } else if (t == F_RANDINT) {
16190                 int k;
16191 
16192                 p->err = gretl_rand_int_minmax(&k, 1, xl, xr);
16193                 if (!p->err) {
16194                     ret->v.xval = k;
16195                 }
16196             }
16197         }
16198     }
16199 
16200     return ret;
16201 }
16202 
kpss_crit_node(NODE * l,NODE * r,parser * p)16203 static NODE *kpss_crit_node (NODE *l, NODE *r, parser *p)
16204 {
16205     NODE *ret = aux_matrix_node(p);
16206 
16207     if (ret != NULL && starting(p)) {
16208         int T = node_get_int(l, p);
16209         int trend = node_get_int(r, p);
16210 
16211         if (!p->err) {
16212             ret->v.m = kpss_critvals(T, trend, &p->err);
16213         }
16214     }
16215 
16216     return ret;
16217 }
16218 
scalar_postfix_node(NODE * n,parser * p)16219 static NODE *scalar_postfix_node (NODE *n, parser *p)
16220 {
16221     NODE *ret = aux_scalar_node(p);
16222 
16223     if (ret != NULL && starting(p)) {
16224         if (n->vname != NULL && p->lh.name[0] != '\0' &&
16225             strcmp(n->vname, p->lh.name) == 0) {
16226             /* undefined behavior */
16227             fprintf(stderr, "BAD NUM_P/NUM_M\n");
16228             gretl_errmsg_sprintf(_("The result for %s is not well defined"),
16229                                  n->vname);
16230             p->err = E_DATA;
16231             ret->v.xval = NADBL;
16232         } else {
16233             double x = n->v.xval;
16234 
16235             ret->v.xval = x;
16236             if (n->t == NUM_P) {
16237                 p->err = node_replace_scalar(n, x + 1.0);
16238             } else {
16239                 p->err = node_replace_scalar(n, x - 1.0);
16240             }
16241         }
16242     }
16243 
16244     return ret;
16245 }
16246 
series_calc_nodes(NODE * l,NODE * r)16247 static int series_calc_nodes (NODE *l, NODE *r)
16248 {
16249     int ret = 0;
16250 
16251     if (l->t == SERIES) {
16252         ret = (r->t == SERIES || r->t == NUM || scalar_matrix_node(r));
16253     } else if (r->t == SERIES) {
16254         ret = scalar_node(l);
16255     }
16256 
16257     return ret;
16258 }
16259 
cast_series_to_list(parser * p,NODE * n,short f)16260 static int cast_series_to_list (parser *p, NODE *n, short f)
16261 {
16262     if (p->tree->t == F_GENSERIES) {
16263         /* FIXME: other cases when we shouldn't do this "cast"? */
16264         return 0;
16265     } else if (p->targ == LIST && useries_node(n)) {
16266         return (f == F_LOG || f == F_DIFF ||
16267                 f == F_LDIFF || f == F_SDIFF ||
16268                 f == F_ODEV);
16269     } else {
16270         return 0;
16271     }
16272 }
16273 
lhs_terminal_node(NODE * t,NODE * l,NODE * r,parser * p)16274 static NODE *lhs_terminal_node (NODE *t, NODE *l, NODE *r,
16275                                 parser *p)
16276 {
16277     /* Pass through eval'd @l and @r subnodes, but don't eval
16278        the parent @t itself */
16279     NODE *ret = aux_parent_node(p);
16280 
16281     ret->t = t->t; /* transcribe type */
16282     ret->L = l;    /* evaluated left-hand */
16283     ret->R = r;    /* evaluated right-hand */
16284 
16285     /* prevent double-freeing of children @l and @r */
16286     ret->flags |= LHT_NODE;
16287 
16288     return ret;
16289 }
16290 
16291 /* reattach_series: on successive executions of a given
16292    compiled "genr", the "xvec" pointer recorded on a
16293    SERIES node will have become invalid if:
16294 
16295    (1) the series has been renamed,
16296    (2) the dataset has been differently sub-sampled, or
16297    (3) the series has been deleted (should be impossible).
16298 
16299    In case (2) the ID number of the series should still
16300    be valid, so it ought to be sufficient to reconnect the
16301    xvec pointer as in the second branch below. In case (1),
16302    however, it's necessary to look up the ID number by name
16303    again (as things stand).
16304 
16305    Note that n->v.xvec will be NULL when this function is
16306    reached only in case a genr is attached to a loop that
16307    is saved across function calls -- then the pointer is
16308    reset to NULL on each call to the function (but not
16309    on each iteration of the loop itself).
16310 */
16311 
reattach_series(NODE * n,parser * p)16312 static void reattach_series (NODE *n, parser *p)
16313 {
16314     if (n->v.xvec == NULL || get_loop_renaming()) {
16315         /* do a full reset */
16316         n->vnum = current_series_index(p->dset, n->vname);
16317         if (n->vnum < 0) {
16318             gretl_errmsg_sprintf("'%s': not a series", n->vname);
16319             p->err = E_DATA;
16320         } else {
16321             n->v.xvec = p->dset->Z[n->vnum];
16322         }
16323     } else if (n->vnum >= 0 && n->vnum < p->dset->v) {
16324         /* handles the case of the dataset moving due to
16325            sub-sampling, provided that no series are deleted
16326            (the name -> ID mapping remains unchanged)
16327         */
16328         n->v.xvec = p->dset->Z[n->vnum];
16329     }
16330 }
16331 
reattach_data_error(NODE * n,parser * p)16332 static void reattach_data_error (NODE *n, parser *p)
16333 {
16334     char msg[256];
16335 
16336     sprintf(msg, "'%s': expected %s", n->vname, getsymb(n->t));
16337 
16338     if (n->uv == NULL) {
16339         strcat(msg, " but name look-up failed");
16340         p->err = E_DATA;
16341     } else {
16342         const char *s = gretl_type_get_name(n->uv->type);
16343         gchar *add;
16344 
16345         if (n->uv->ptr == NULL) {
16346             add = g_strdup_printf(", found %s with NULL data", s);
16347             p->err = E_DATA;
16348         } else {
16349             add = g_strdup_printf(" but found %s", s);
16350             p->err = E_TYPES;
16351         }
16352         strcat(msg, add);
16353         gretl_errmsg_set(msg);
16354         g_free(add);
16355     }
16356 }
16357 
node_reattach_data(NODE * n,parser * p)16358 static void node_reattach_data (NODE *n, parser *p)
16359 {
16360     if (n->t == SERIES) {
16361         reattach_series(n, p);
16362     } else {
16363         GretlType type = 0;
16364         void *data = NULL;
16365 
16366         if (n->uv == NULL || (n->t == LIST && gretl_looping())) {
16367             n->uv = get_user_var_by_name(n->vname);
16368         }
16369 
16370         if (n->uv != NULL) {
16371             data = n->uv->ptr;
16372             type = n->uv->type;
16373         }
16374 
16375         if (data == NULL) {
16376             reattach_data_error(n, p);
16377         } else if (uscalar_node(n)) {
16378             if (type == GRETL_TYPE_DOUBLE) {
16379                 n->v.xval = *(double *) data;
16380 #if ONE_BY_ONE_CAST
16381             } else if (type == GRETL_TYPE_MATRIX) {
16382                 /* allow type-mutation */
16383                 n->t = MAT;
16384                 n->v.m = (gretl_matrix *) data;
16385 #endif
16386             } else {
16387                 reattach_data_error(n, p);
16388             }
16389         } else if (n->t == MAT && type == GRETL_TYPE_MATRIX) {
16390             n->v.m = data;
16391         } else if (n->t == LIST && type == GRETL_TYPE_LIST) {
16392             n->v.ivec = data;
16393         } else if (n->t == BUNDLE && type == GRETL_TYPE_BUNDLE) {
16394             n->v.b = data;
16395         } else if (n->t == STR && type == GRETL_TYPE_STRING) {
16396             n->v.str = data;
16397         } else if (n->t == ARRAY && type == GRETL_TYPE_ARRAY) {
16398             n->v.a = data;
16399         } else if (n->t == OSL) {
16400             n->v.ptr = data;
16401         } else {
16402             reattach_data_error(n, p);
16403         }
16404     }
16405 }
16406 
node_type_error(int ntype,int argnum,int goodt,NODE * bad,parser * p)16407 static void node_type_error (int ntype, int argnum, int goodt,
16408                              NODE *bad, parser *p)
16409 {
16410     const char *nstr;
16411 
16412     if (ntype == 0) {
16413         p->err = E_TYPES;
16414         return;
16415     }
16416 
16417     parser_ensure_error_buffer(p);
16418 
16419     if (ntype == LAG) {
16420         nstr = (goodt == NUM)? "lag order" : "lag variable";
16421     } else {
16422         nstr = getsymb(ntype);
16423     }
16424 
16425     if (goodt == 0 && bad != NULL) {
16426         if (null_node(bad)) {
16427             pprintf(p->prn, _("%s: insufficient arguments"), nstr);
16428         } else if (argnum <= 0) {
16429             pprintf(p->prn, _("%s: invalid argument type %s"),
16430                     nstr, typestr(bad->t));
16431         } else {
16432             pprintf(p->prn, _("%s: argument %d: invalid type %s"),
16433                     nstr, argnum, typestr(bad->t));
16434         }
16435         pputc(p->prn, '\n');
16436         p->err = E_TYPES;
16437         return;
16438     }
16439 
16440     if (ntype < OP_MAX) {
16441         if (argnum <= 0) {
16442             pprintf(p->prn, _("%s: operand should be %s"),
16443                     nstr, typestr(goodt));
16444         } else {
16445             pprintf(p->prn, _("%s: operand %d should be %s"),
16446                     nstr, argnum, typestr(goodt));
16447         }
16448     } else {
16449         if (argnum <= 0) {
16450             pprintf(p->prn, _("%s: argument should be %s"),
16451                     nstr, typestr(goodt));
16452         } else {
16453             pprintf(p->prn, _("%s: argument %d should be %s"),
16454                     nstr, argnum, typestr(goodt));
16455         }
16456     }
16457 
16458     if (bad != NULL) {
16459         pprintf(p->prn, _(", is %s"), typestr(bad->t));
16460     }
16461     pputc(p->prn, '\n');
16462 
16463     if (!strcmp(nstr, "&")) {
16464         pputs(p->prn, "(for logical AND, please use \"&&\")\n");
16465     } else if (!strcmp(nstr, "|")) {
16466         pputs(p->prn, "(for logical OR, please use \"||\")\n");
16467     }
16468 
16469     p->err = E_TYPES;
16470 }
16471 
node_is_true(NODE * n,parser * p)16472 static int node_is_true (NODE *n, parser *p)
16473 {
16474     double x = node_get_scalar(n, p);
16475 
16476     return !na(x) && x != 0.0;
16477 }
16478 
node_is_false(NODE * n,parser * p)16479 static int node_is_false (NODE *n, parser *p)
16480 {
16481     return (node_get_scalar(n, p) == 0.0);
16482 }
16483 
16484 /* core function: evaluate the parsed syntax tree */
16485 
eval(NODE * t,parser * p)16486 static NODE *eval (NODE *t, parser *p)
16487 {
16488     NODE *l = NULL, *m = NULL, *r = NULL;
16489     NODE *ret = NULL;
16490 
16491     if (t == NULL) {
16492         /* catch NULL node right away */
16493         return NULL;
16494     }
16495 
16496 #if EDEBUG
16497     if (t->vname != NULL) {
16498         fprintf(stderr, "eval: incoming node %p ('%s', vname=%s)\n",
16499                 (void *) t, getsymb(t->t), t->vname);
16500     } else {
16501         fprintf(stderr, "eval: incoming node %p ('%s')\n",
16502                 (void *) t, getsymb(t->t));
16503     }
16504 #endif
16505 
16506     /* handle terminals first */
16507     if (t->t == MSPEC || t->t == EMPTY || t->t == PTR) {
16508         return t;
16509     } else if (t->t >= NUM && t->t <= STR) {
16510         if (exestart(p) && uvar_node(t)) {
16511             node_reattach_data(t, p);
16512         }
16513         return t;
16514     }
16515 
16516     if (t->t == QUERY) {
16517         /* needs special treatment, see eval_query() */
16518         goto do_switch;
16519     }
16520 
16521     if (t->L) {
16522         if (t->t == F_EXISTS || t->t == F_TYPEOF) {
16523             p->flags |= P_OBJQRY;
16524             l = eval(t->L, p);
16525             p->flags ^= P_OBJQRY;
16526         } else {
16527             l = eval(t->L, p);
16528         }
16529         if (l == NULL && !p->err) {
16530             p->err = 1;
16531         }
16532     }
16533 
16534     if (!p->err && t->M != NULL) {
16535         if (m_return(t->t)) {
16536             m = t->M;
16537         } else {
16538             m = eval(t->M, p);
16539             if (m == NULL && !p->err) {
16540                 p->err = 1;
16541             }
16542         }
16543     }
16544 
16545     if (!p->err && t->R != NULL) {
16546         if (r_return(t->t)) {
16547             r = t->R;
16548         } else {
16549             if (t->t == B_AND || t->t == B_OR) {
16550                 /* logical operators: avoid redundant evaluation */
16551                 if (l != NULL && l->t == NUM) {
16552                     if ((t->t == B_AND && node_is_false(l, p)) ||
16553                         (t->t == B_OR && node_is_true(l, p))) {
16554                         /* no need to evaluate @r */
16555                         ret = l;
16556                         if (is_aux_node(ret)) {
16557                             /* mark return node as proxy */
16558                             ret->flags |= PRX_NODE;
16559                         }
16560                         goto finish;
16561                     }
16562                 }
16563             }
16564             if (r == NULL && !p->err) {
16565                 r = eval(t->R, p);
16566                 if (r == NULL && !p->err) {
16567                     p->err = 1;
16568                 }
16569             }
16570         }
16571     }
16572 
16573     if (p->err) {
16574         goto bailout;
16575     }
16576 
16577  do_switch:
16578 
16579     /* establish convenience pointer */
16580     p->aux = t->aux;
16581 
16582     switch (t->t) {
16583     case DBUNDLE:
16584         if (t->vname != NULL) {
16585             /* pseudo-bundle: name of model */
16586             ret = t;
16587         } else {
16588             /* built-in bundle indentifed by idnum */
16589             ret = dollar_bundle_node(t, p);
16590         }
16591         break;
16592     case UNDEF:
16593         ret = maybe_rescue_undef_node(t, p);
16594         break;
16595     case U_ADDR:
16596         if (!uvar_node(t->L) && t->L->t != OSL) {
16597             p->err = E_DATA;
16598         } else if (exestart(p)) {
16599             node_reattach_data(t->L, p);
16600         }
16601         ret = t;
16602         break;
16603     case WLIST:
16604         ret = wildlist_node(t, p);
16605         break;
16606     case DUM:
16607         if (t->v.idnum == DUM_DATASET) {
16608             ret = dataset_list_node(p);
16609         } else if (t->v.idnum == DUM_TREND) {
16610             ret = trend_node(p);
16611 	} else if (t->v.idnum == DUM_END) {
16612 	    ret = array_last_node(p);
16613         } else {
16614             /* otherwise treat as terminal */
16615             ret = t;
16616         }
16617         break;
16618     case NUM_P:
16619     case NUM_M:
16620         if (exestart(p)) {
16621             node_reattach_data(t, p);
16622         }
16623         ret = scalar_postfix_node(t, p);
16624         break;
16625     case FARGS:
16626         /* will be evaluated in context */
16627         ret = t;
16628         break;
16629     case B_ADD:
16630     case B_SUB:
16631     case B_MUL:
16632     case B_DIV:
16633     case B_MOD:
16634     case B_POW:
16635     case B_AND:
16636     case B_OR:
16637     case B_EQ:
16638     case B_NEQ:
16639     case B_GT:
16640     case B_LT:
16641     case B_GTE:
16642     case B_LTE:
16643         /* arithmetic and logical binary operators: be as
16644            flexible as possible with regard to argument types
16645         */
16646         if (t->t == B_ADD && l->t == STR && r->t == NUM) {
16647             ret = string_offset(l, r, p);
16648         } else if ((t->t == B_EQ || t->t == B_NEQ) &&
16649                    l->t == STR && r->t == STR) {
16650             ret = compare_strings(l, r, t->t, p);
16651         } else if (l->t == NUM && r->t == NUM) {
16652             ret = scalar_calc(l, r, t->t, p);
16653         } else if (l->t == BUNDLE && r->t == BUNDLE) {
16654             ret = bundle_op(l, r, t->t, p);
16655         } else if (l->t == ARRAY && r->t == ARRAY) {
16656             ret = array_op(l, r, t->t, p);
16657         } else if (stringvec_node(l) && stringvec_node(r)) {
16658             ret = stringvec_calc(l, r, t, p);
16659         } else if (series_calc_nodes(l, r)) {
16660             ret = series_calc(l, r, t->t, p);
16661         } else if (l->t == MAT && r->t == MAT) {
16662             if (bool_comp(t->t)) {
16663                 ret = matrix_bool(l, r, t->t, p);
16664             } else {
16665                 ret = matrix_matrix_calc(l, r, t->t, p);
16666             }
16667         } else if ((l->t == MAT && r->t == NUM) ||
16668                    (l->t == NUM && r->t == MAT)) {
16669             ret = matrix_scalar_calc(l, r, t->t, p);
16670         } else if ((l->t == MAT && r->t == SERIES) ||
16671                    (l->t == SERIES && r->t == MAT)) {
16672             ret = matrix_series_calc(l, r, t->t, p);
16673         } else if (t->t >= B_EQ && t->t <= B_NEQ &&
16674                    ((l->t == SERIES && r->t == STR) ||
16675                     (l->t == STR && r->t == SERIES))) {
16676             ret = series_string_calc(l, r, t->t, p);
16677         } else if ((t->t == B_AND || t->t == B_OR || t->t == B_SUB) &&
16678                    ok_list_node_plus(l) && ok_list_node_plus(r)) {
16679             ret = list_list_op(l, r, t->t, p);
16680         } else if (t->t == B_POW && ok_list_node(l, p) && ok_list_node(r, p)) {
16681             ret = list_list_op(l, r, t->t, p);
16682         } else if (bool_comp(t->t)) {
16683             if (ok_list_node(l, p) && (r->t == NUM || r->t == SERIES)) {
16684                 ret = list_bool_comp(l, r, t->t, 0, p);
16685             } else if (ok_list_node(r, p) && (l->t == NUM || l->t == SERIES)) {
16686                 ret = list_bool_comp(r, l, t->t, 1, p);
16687             } else if (ok_list_node(l, p) && ok_list_node(r, p)) {
16688                 ret = list_list_comp(r, l, t->t, p);
16689             } else {
16690                 p->err = E_TYPES;
16691             }
16692         } else if ((t->t == B_ADD || t->t == B_SUB) &&
16693                    l->t == SERIES && ok_list_node(r, p)) {
16694             ret = series_list_calc(l, r, t->t, p);
16695         } else if (t->t == B_ADD && l->t == ARRAY) {
16696             ret = augment_array_node(l, r, p);
16697 	} else if (t->t == B_SUB && l->t == ARRAY) {
16698 	    ret = subtract_from_array_node(l, r, p);
16699         } else {
16700             p->err = E_TYPES;
16701         }
16702         break;
16703     case B_TRMUL:
16704         /* matrix on left, otherwise be flexible */
16705         if (ok_matrix_node(l) && ok_matrix_node(r)) {
16706             ret = matrix_matrix_calc(l, r, t->t, p);
16707         } else if (l->t == MAT && r->t == SERIES) {
16708             ret = matrix_series_calc(l, r, t->t, p);
16709         } else if (l->t == MAT && r->t == EMPTY) {
16710             ret = matrix_transpose_node(l, p);
16711         } else if (l->t == NUM && r->t == EMPTY) {
16712             ret = l;
16713         } else {
16714             p->err = E_TYPES;
16715         }
16716         break;
16717     case B_DOTMULT:
16718     case B_DOTDIV:
16719     case B_DOTPOW:
16720     case B_DOTADD:
16721     case B_DOTSUB:
16722     case B_DOTEQ:
16723     case B_DOTGT:
16724     case B_DOTLT:
16725     case B_DOTGTE:
16726     case B_DOTLTE:
16727     case B_DOTNEQ:
16728         /* matrix-matrix or matrix-scalar binary operators:
16729            in addition we permit scalar-scalar to allow for
16730            the possibility that results that could be taken
16731            to be 1 x 1 matrix results have been registered
16732            internally as scalars.
16733         */
16734         if (ok_matrix_node(l) && ok_matrix_node(r)) {
16735             ret = matrix_matrix_calc(l, r, t->t, p);
16736         } else if ((ok_matrix_node(l) && r->t == SERIES) ||
16737                    (l->t == SERIES && ok_matrix_node(r))) {
16738             ret = matrix_series_calc(l, r, t->t, p);
16739 	} else if ((t->t == B_DOTEQ || t->t == B_DOTNEQ) &&
16740 		   l->t == ARRAY && r->t == STR) {
16741 	    ret = array_str_calc(l, r, t->t, p);
16742         } else {
16743             node_type_error(t->t, (l->t == MAT)? 2 : 1,
16744                             MAT, (l->t == MAT)? r : l, p);
16745         }
16746         break;
16747     case B_HCAT:
16748         if (l->t == STR) {
16749             ret = two_string_func(l, r, NULL, t->t, p);
16750             break;
16751         }
16752         /* Falls through. */
16753     case B_VCAT:
16754     case F_QFORM:
16755     case F_HDPROD:
16756     case F_CMULT:
16757     case F_CDIV:
16758     case F_LSOLVE:
16759     case F_MRSEL:
16760     case F_MCSEL:
16761     case F_DSUM:
16762     case B_LDIV:
16763     case B_KRON:
16764     case F_CONV2D:
16765         /* matrix-only binary operators (but promote scalars) */
16766         if (ok_matrix_node(l) && ok_matrix_node(r)) {
16767             ret = matrix_matrix_calc(l, r, t->t, p);
16768 	} else if (ok_matrix_node(l) && null_node(r) && t->t == F_HDPROD) {
16769 	    ret = matrix_to_matrix2_func(l, r, t->t, p);
16770         } else {
16771             node_type_error(t->t, (l->t == MAT)? 2 : 1,
16772                             MAT, (l->t == MAT)? r : l, p);
16773         }
16774         break;
16775     case B_ELLIP:
16776         /* list-making ellipsis */
16777         if ((useries_node(l) || could_be_series_id(l, p)) &&
16778             (useries_node(r) || could_be_series_id(r, p))) {
16779             ret = ellipsis_list_node(l, r, p);
16780         } else {
16781             p->err = E_TYPES;
16782         }
16783         break;
16784     case B_JOIN:
16785         /* list join with separator */
16786         if (ok_list_node(l, p) && ok_list_node(r, p)) {
16787             ret = list_join_node(l, r, p);
16788         } else {
16789             p->err = E_TYPES;
16790         }
16791         break;
16792     case F_MSORTBY:
16793     case F_CSWITCH:
16794         /* matrix on left, scalar on right */
16795         if (l->t == MAT && null_or_scalar(r)) {
16796             ret = matrix_scalar_func(l, r, t->t, p);
16797         } else if (l->t == MAT) {
16798             node_type_error(t->t, 2, NUM, r, p);
16799         } else {
16800             node_type_error(t->t, 1, MAT, l, p);
16801         }
16802         break;
16803     case F_MSPLITBY:
16804         /* matrix on left, vector, optional boolean */
16805         if (ok_matrix_node(l) && ok_matrix_node(m)) {
16806             ret = matrix_vector_func(l, m, r, t->t, p);
16807         } else {
16808             p->err = E_TYPES;
16809         }
16810         break;
16811     case F_LLAG:
16812         if (null_node(m)) {
16813             p->err = E_ARGS;
16814         } else if (ok_matrix_node(l) && m->t != MAT && ok_list_node(m, p)) {
16815             ret = list_make_lags(l, m, r, p);
16816         } else if (ok_matrix_node(l) && m->t == MAT) {
16817             ret = matrix_make_lags(l, m, r, p);
16818         } else {
16819             p->err = E_TYPES;
16820         }
16821         break;
16822     case F_STDIZE:
16823         if (!null_or_scalar(r)) {
16824             p->err = E_TYPES;
16825         } else if (l->t == SERIES) {
16826             ret = series_stdize(l, r, p);
16827         } else if (l->t == LIST) {
16828             ret = list_stdize(l, r, p);
16829         } else if (l->t == MAT) {
16830             ret = matrix_to_matrix_func(l, r, t->t, p);
16831         } else {
16832             p->err = E_TYPES;
16833         }
16834         break;
16835     case F_HFLAG:
16836         if (scalar_node(l) && scalar_node(m) && ok_list_node(r, p)) {
16837             ret = hf_list_make_lags(l, m, r, p);
16838         } else {
16839             p->err = E_TYPES;
16840         }
16841         break;
16842     case F_HFLIST:
16843         if (l->t == MAT && scalar_node(m) && r->t == STR) {
16844             ret = hf_list_node(l, m, r, p);
16845         } else {
16846             p->err = E_TYPES;
16847         }
16848         break;
16849     case F_HFDIFF:
16850     case F_HFLDIFF:
16851         if (ok_list_node(l, p) && null_or_scalar(r)) {
16852             ret = apply_list_func(l, r, t->t, p);
16853         } else {
16854             p->err = E_TYPES;
16855         }
16856         break;
16857     case U_NEG:
16858     case U_POS:
16859     case U_NOT:
16860     case F_ABS:
16861     case F_SGN:
16862     case F_TOINT:
16863     case F_CEIL:
16864     case F_FLOOR:
16865     case F_ROUND:
16866     case F_SIN:
16867     case F_COS:
16868     case F_TAN:
16869     case F_ASIN:
16870     case F_ACOS:
16871     case F_ATAN:
16872     case F_SINH:
16873     case F_COSH:
16874     case F_TANH:
16875     case F_ASINH:
16876     case F_ACOSH:
16877     case F_ATANH:
16878     case F_LOG:
16879     case F_LOG10:
16880     case F_LOG2:
16881     case F_EXP:
16882     case F_SQRT:
16883     case F_CNORM:
16884     case F_DNORM:
16885     case F_QNORM:
16886     case F_LOGISTIC:
16887     case F_GAMMA:
16888     case F_LNGAMMA:
16889     case F_DIGAMMA:
16890     case F_TRIGAMMA:
16891     case F_INVMILLS:
16892     case F_EASTER:
16893         /* functions taking one argument, any type */
16894         if (l->t == NUM) {
16895             ret = apply_scalar_func(l, t, p);
16896         } else if (l->t == SERIES) {
16897             if (cast_series_to_list(p, l, t->t)) {
16898                 ret = apply_list_func(l, NULL, t->t, p);
16899             } else {
16900                 ret = apply_series_func(l, t, p);
16901             }
16902         } else if (l->t == MAT) {
16903             ret = apply_matrix_func(l, t, p);
16904         } else if (ok_list_node(l, p) && t->t == F_LOG) {
16905             ret = apply_list_func(l, NULL, t->t, p);
16906         } else {
16907             p->err = E_TYPES;
16908         }
16909         break;
16910     case F_REAL:
16911     case F_IMAG:
16912         ret = apply_matrix_func(l, t, p);
16913         break;
16914     case F_CARG:
16915     case F_CONJ:
16916     case F_CMOD:
16917         if (complex_node(l)) {
16918             ret = apply_matrix_func(l, t, p);
16919         } else {
16920             p->err = E_TYPES;
16921         }
16922         break;
16923     case F_ATAN2:
16924     case F_BINCOEFF:
16925         if ((l->t == NUM || l->t == MAT || l->t == SERIES) &&
16926             (r->t == NUM || r->t == MAT || r->t == SERIES)) {
16927             ret = flexible_2arg_node(l, r, t->t, p);
16928         } else {
16929             p->err = E_TYPES;
16930         }
16931         break;
16932     case F_DUMIFY:
16933     case F_CDUMIFY:
16934         /* series or list argument wanted */
16935         if (l->t == SERIES || l->t == LIST) {
16936             if (t->t == F_DUMIFY) {
16937                 ret = dummify_func(l, r, p);
16938             } else {
16939                 ret = cdummify_func(l, p);
16940             }
16941         } else {
16942             p->err = E_INVARG;
16943         }
16944         break;
16945     case F_GETINFO:
16946         /* named series (or ID) argument wanted */
16947         if (useries_node(l) || l->t == NUM) {
16948             ret = get_info_on_series(l, p);
16949         } else {
16950             p->err = E_TYPES;
16951         }
16952         break;
16953     case F_SEASONALS:
16954         /* two optional args: int, bool */
16955         if (!null_or_scalar(l)) {
16956             node_type_error(t->t, 1, NUM, l, p);
16957         } else if (!null_or_scalar(r)) {
16958             node_type_error(t->t, 2, NUM, r, p);
16959         } else {
16960             ret = seasonals_node(l, r, p);
16961         }
16962         break;
16963     case F_MISSZERO:
16964     case F_ZEROMISS:
16965         /* one series or scalar argument needed */
16966         if (l->t == SERIES || l->t == MAT) {
16967             ret = apply_series_func(l, t, p);
16968         } else if (l->t == NUM) {
16969             ret = apply_scalar_func(l, t, p);
16970         } else {
16971             node_type_error(t->t, 0, SERIES, l, p);
16972         }
16973         break;
16974     case F_MISSING:
16975     case F_DATAOK:
16976         /* series, scalar or list argument needed */
16977         if (l->t == MAT) {
16978             if (t->t == F_DATAOK) {
16979                 ret = matrix_to_matrix_func(l, NULL, t->t, p);
16980             } else {
16981                 ret = matrix_isnan_node(l, p);
16982             }
16983         } else if (l->t == SERIES) {
16984             ret = apply_series_func(l, t, p);
16985         } else if (l->t == NUM) {
16986             ret = apply_scalar_func(l, t, p);
16987         } else if (l->t == LIST) {
16988             ret = list_ok_func(l, t->t, p);
16989         } else {
16990             node_type_error(t->t, 0, SERIES, l, p);
16991         }
16992         break;
16993     case F_ISNAN:
16994         /* scalar or matrix */
16995         if (scalar_node(l)) {
16996             ret = scalar_isnan_node(l, p);
16997         } else if (l->t == MAT) {
16998             ret = matrix_isnan_node(l, p);
16999         } else {
17000             node_type_error(t->t, 0, NUM, l, p);
17001         }
17002         break;
17003     case F_SLEEP:
17004     case HF_SFCGI:
17005         if (scalar_node(l)) {
17006             ret = misc_scalar_node(l, t->t, p);
17007         } else {
17008             node_type_error(t->t, 0, NUM, l, p);
17009         }
17010         break;
17011     case F_BARRIER:
17012         if (l->t == EMPTY) {
17013             ret = mpi_barrier_node(p);
17014         } else {
17015             node_type_error(t->t, 0, EMPTY, l, p);
17016         }
17017         break;
17018     case LAG:
17019         if (p->targ == LIST) {
17020             ret = get_lag_list(l, r, p);
17021         } else if (l->t == SERIES && scalar_node(r)) {
17022             ret = series_lag(l, r, p);
17023         } else if (l->t != SERIES) {
17024             node_type_error(t->t, 1, SERIES, l, p);
17025         } else {
17026             node_type_error(t->t, 2, NUM, r, p);
17027         }
17028         break;
17029     case F_LJUNGBOX:
17030     case F_POLYFIT:
17031         /* series on left, scalar on right */
17032         if (l->t != SERIES) {
17033             node_type_error(t->t, 1, SERIES, l, p);
17034         } else if (!scalar_node(r)) {
17035             node_type_error(t->t, 2, NUM, r, p);
17036         } else if (t->t == F_LJUNGBOX) {
17037             ret = series_ljung_box(l, r, p);
17038         } else if (t->t == F_POLYFIT) {
17039             ret = series_polyfit(l, r, p);
17040         }
17041         break;
17042     case OBS:
17043         if (l->t != SERIES) {
17044             node_type_error(t->t, 1, SERIES, l, p);
17045         } else if (!scalar_node(r) && r->t != STR) {
17046             node_type_error(t->t, 2, NUM, r, p);
17047         } else if (t->flags & LHT_NODE) {
17048             ret = lhs_terminal_node(t, l, r, p);
17049         } else {
17050             ret = series_obs(l, r, p);
17051         }
17052         break;
17053     case MSL:
17054         /* matrix plus subspec */
17055         if (t->flags & LHT_NODE) {
17056             ret = lhs_terminal_node(t, l, r, p);
17057         } else if (l->t == MAT && r->t == MSPEC) {
17058             ret = submatrix_node(l, r, p);
17059         } else {
17060             p->err = E_TYPES;
17061         }
17062         break;
17063     case OSL:
17064         /* object plus subspec */
17065         if (t->flags & LHT_NODE) {
17066             ret = lhs_terminal_node(t, l, r, p);
17067         } else if (l->t == U_ADDR) {
17068             ret = process_OSL_address(t, l, r, p);
17069         } else {
17070             ret = subobject_node(l, r, p);
17071         }
17072         break;
17073     case SLRAW:
17074         /* unevaluated object slice spec */
17075         ret = mspec_node(l, r, p);
17076         break;
17077     case SUBSL:
17078     case B_RANGE:
17079         /* matrix sub-slice, x:y, or lag range, 'p to q' */
17080         ret = process_subslice(l, r, p);
17081         break;
17082     case BMEMB:
17083     case F_INBUNDLE:
17084         /* name of bundle plus string */
17085         if (l->t == BUNDLE && r->t == STR) {
17086             if (t->t == BMEMB) {
17087                 if (t->flags & LHT_NODE) {
17088                     ret = lhs_terminal_node(t, l, r, p);
17089                 } else {
17090                     ret = get_bundle_member(l, r, p);
17091                 }
17092             } else {
17093                 ret = test_bundle_key(l, r, p);
17094             }
17095         } else if (l->t == BUNDLE) {
17096             node_type_error(t->t, 1, STR, r, p);
17097         } else {
17098             node_type_error(t->t, 0, BUNDLE, l, p);
17099         }
17100         break;
17101     case F_GETKEYS:
17102     case HF_JBTERMS:
17103 	if (l->t == BUNDLE) {
17104             ret = get_bundle_array(l, t->t, p);
17105         } else {
17106             node_type_error(t->t, 0, BUNDLE, l, p);
17107         }
17108         break;
17109     case DBMEMB:
17110         /* name of $-bundle plus string */
17111         if (l->t == BUNDLE && r->t == STR) {
17112             ret = get_bundle_member(l, r, p);
17113         } else if (l->t == DBUNDLE && r->t == STR) {
17114             ret = model_var_node(l, r, p);
17115         } else if (r->t != STR) {
17116             node_type_error(t->t, 2, STR, r, p);
17117         } else {
17118             node_type_error(t->t, 1, BUNDLE, l, p);
17119         }
17120         break;
17121     case F_CURL:
17122         ret = curl_bundle_node(l, p);
17123         break;
17124     case F_LPSOLVE:
17125 	if (l->t == BUNDLE) {
17126 	    ret = lpsolve_bundle_node(l, p);
17127 	} else {
17128 	    node_type_error(t->t, 0, BUNDLE, l, p);
17129 	}
17130 	break;
17131     case F_SVM:
17132         ret = svm_driver_node(t, p);
17133         break;
17134     case F_TYPESTR:
17135         /* numerical type code to string */
17136         if (scalar_node(l)) {
17137             ret = type_string_node(l, p);
17138         } else {
17139             node_type_error(t->t, 0, NUM, l, p);
17140         }
17141         break;
17142     case F_LDIFF:
17143     case F_SDIFF:
17144     case F_ODEV:
17145         if (l->t == SERIES && cast_series_to_list(p, l, t->t)) {
17146             ret = apply_list_func(l, NULL, t->t, p);
17147         } else if (l->t == SERIES || (t->t != F_ODEV && l->t == MAT)) {
17148             ret = series_series_func(l, r, NULL, t->t, p);
17149         } else if (ok_list_node(l, p)) {
17150             ret = apply_list_func(l, NULL, t->t, p);
17151         } else {
17152             node_type_error(t->t, 0, SERIES, l, p);
17153         }
17154         break;
17155     case F_DROPCOLL:
17156         /* list argument is required on left, optional scalar
17157            on the right */
17158         if (l->t == LIST) {
17159             ret = apply_list_func(l, r, t->t, p);
17160         } else {
17161             node_type_error(t->t, 0, LIST, l, p);
17162         }
17163         break;
17164     case F_HPFILT:
17165     case F_FRACDIFF:
17166     case F_FRACLAG:
17167     case F_BOXCOX:
17168     case F_PNOBS:
17169     case F_PMIN:
17170     case F_PMAX:
17171     case F_PSUM:
17172     case F_PMEAN:
17173     case F_PXSUM:
17174     case F_PXNOBS:
17175     case F_PSD:
17176     case F_DESEAS:
17177     case F_TRAMOLIN:
17178         /* series argument needed */
17179         if (l->t == SERIES || l->t == MAT) {
17180             if (t->t == F_HPFILT) {
17181                 ret = series_series_func(l, m, r, t->t, p);
17182             } else {
17183                 ret = series_series_func(l, r, NULL, t->t, p);
17184             }
17185         } else {
17186             node_type_error(t->t, 0, SERIES, l, p);
17187         }
17188         break;
17189     case F_FREQ:
17190         /* series -> matrix */
17191         if (l->t == SERIES || l->t == MAT) {
17192             ret = series_matrix_func(l, t->t, p);
17193         } else {
17194             node_type_error(t->t, 0, SERIES, l, p);
17195         }
17196         break;
17197     case F_PSHRINK:
17198         if (l->t == SERIES) {
17199             int noskip = node_get_bool(r, p, 0);
17200 
17201             if (!p->err) {
17202                 ret = do_panel_shrink(l, noskip, p);
17203             }
17204         } else {
17205             node_type_error(t->t, 0, SERIES, l, p);
17206         }
17207         break;
17208     case F_PEXPAND:
17209         if (l->t == MAT) {
17210             ret = do_panel_expand(l, p);
17211         } else {
17212             node_type_error(t->t, 0, MAT, l, p);
17213         }
17214         break;
17215     case F_CUM:
17216     case F_DIFF:
17217     case F_RESAMPLE:
17218     case F_RANKING:
17219         /* series or matrix argument */
17220         if (l->t == SERIES) {
17221             if (cast_series_to_list(p, l, t->t)) {
17222                 ret = apply_list_func(l, NULL, t->t, p);
17223             } else {
17224                 ret = series_series_func(l, r, NULL, t->t, p);
17225             }
17226         } else if (l->t == MAT) {
17227             if (t->t == F_RESAMPLE) {
17228                 ret = eval_3args_func(l, m, r, t->t, p);
17229             } else {
17230                 ret = matrix_to_matrix_func(l, r, t->t, p);
17231             }
17232         } else if (t->t == F_DIFF && ok_list_node(l, p)) {
17233             ret = apply_list_func(l, NULL, t->t, p);
17234         } else if (t->t == F_RESAMPLE && ok_list_node(l, p) &&
17235                    null_node(r)) {
17236             ret = apply_list_func(l, NULL, t->t, p);
17237         } else {
17238             node_type_error(t->t, 0, SERIES, l, p);
17239         }
17240         break;
17241     case F_SORT:
17242     case F_DSORT:
17243         /* series or vector or string array argument needed */
17244         if (l->t == SERIES || l->t == MAT || l->t == NUM) {
17245             ret = vector_sort(l, t->t, p);
17246         } else if (l->t == ARRAY) {
17247             ret = array_sort_node(l, t->t, p);
17248         } else {
17249             node_type_error(t->t, 0, SERIES, l, p);
17250         }
17251         break;
17252     case F_FLATTEN:
17253     case F_INSTRINGS:
17254         if (l->t == ARRAY) {
17255             ret = array_func_node(l, r, t->t, p);
17256         } else {
17257             node_type_error(t->t, 0, ARRAY, l, p);
17258         }
17259         break;
17260     case F_VALUES:
17261     case F_UNIQ:
17262     case F_PERGM:
17263     case F_IRR:
17264         /* series or vector argument needed */
17265         if (l->t == SERIES || l->t == MAT || l->t == NUM) {
17266             if (t->t == F_PERGM) {
17267                 ret = pergm_node(l, r, p);
17268             } else if (t->t == F_VALUES || t->t == F_UNIQ) {
17269                 ret = vector_values(l, t->t, p);
17270             } else if (t->t == F_IRR) {
17271                 ret = do_irr(l, p);
17272             } else {
17273                 ret = vector_sort(l, t->t, p);
17274             }
17275         } else {
17276             node_type_error(t->t, 0, SERIES, l, p);
17277         }
17278         break;
17279     case F_SUM:
17280     case F_SUMALL:
17281     case F_MEAN:
17282     case F_SD:
17283     case F_VCE:
17284     case F_SST:
17285     case F_SKEWNESS:
17286     case F_KURTOSIS:
17287     case F_MIN:
17288     case F_MAX:
17289     case F_MEDIAN:
17290     case F_GINI:
17291     case F_NOBS:
17292     case F_T1:
17293     case F_T2:
17294         /* functions taking series arg (mostly), returning scalar */
17295         if (l->t == SERIES || l->t == MAT) {
17296             ret = series_scalar_func(l, t->t, r, p);
17297         } else if ((t->t == F_MEAN || t->t == F_SD ||
17298                     t->t == F_VCE || t->t == F_MIN ||
17299                     t->t == F_MAX || t->t == F_SUM ||
17300                     t->t == F_MEDIAN)
17301                    && ok_list_node(l, p)) {
17302             /* list -> series also acceptable for these cases */
17303             ret = list_to_series_func(l, t->t, r, p);
17304 	} else if (l->t == NUM) {
17305 	    ret = pretend_matrix_scalar_func(l, t->t, p);
17306         } else {
17307             node_type_error(t->t, 0, SERIES, l, p);
17308         }
17309         break;
17310     case F_ECDF:
17311     case F_NORMTEST:
17312         /* series or vector (plus optional string arg for
17313            normtest); returns matrix */
17314         if (l->t != SERIES && l->t != MAT) {
17315             p->err = E_TYPES;
17316         } else if (null_or_string(r)) {
17317             ret = series_matrix_node(l, r, t->t, p);
17318         } else {
17319             p->err = E_TYPES;
17320         }
17321         break;
17322     case F_LRVAR:
17323     case F_ISCONST:
17324     case F_ISDUMMY:
17325         /* takes series and scalar arg, returns scalar */
17326         if (l->t == SERIES || l->t == MAT) {
17327             if (t->t == F_ISCONST || t->t == F_ISDUMMY ) {
17328                 ret = isconst_or_dum_node(l, r, p, t->t);
17329             } else if (t->t == F_LRVAR) {
17330                 ret = series_scalar_scalar_func(l, m, r, t->t, p);
17331             }
17332         } else {
17333             node_type_error(t->t, 1, SERIES, l, p);
17334         }
17335         break;
17336     case F_NPV:
17337         if (l->t != SERIES && l->t != MAT && l->t != NUM) {
17338             node_type_error(t->t, 1, SERIES, l, p);
17339         } else if (!scalar_node(r)) {
17340             node_type_error(t->t, 2, NUM, r, p);
17341         } else {
17342             ret = series_scalar_scalar_func(l, r, NULL, t->t, p);
17343         }
17344         break;
17345     case F_QUANTILE:
17346         if (l->t == SERIES) {
17347             if (scalar_node(r)) {
17348                 ret = series_scalar_scalar_func(l, r, NULL, t->t, p);
17349             } else {
17350                 node_type_error(t->t, 2, NUM, r, p);
17351             }
17352         } else if (l->t == MAT) {
17353             if (r->t == MAT || scalar_node(r)) {
17354                 ret = matrix_quantiles_node(l, r, p);
17355             } else {
17356                 node_type_error(t->t, 2, MAT, r, p);
17357             }
17358         } else {
17359             node_type_error(t->t, 1, (r->t == MAT)? MAT : SERIES,
17360                             l, p);
17361         }
17362         break;
17363     case F_RUNIFORM:
17364     case F_RNORMAL:
17365         /* functions taking zero or two scalars as args */
17366         if (scalar_node(l) && scalar_node(r)) {
17367             ret = series_fill_func(l, r, t->t, p);
17368         } else if (l->t == EMPTY && r->t == EMPTY) {
17369             ret = series_fill_func(l, r, t->t, p);
17370         } else {
17371             node_type_error(t->t, (l->t == NUM)? 2 : 1,
17372                             NUM, (l->t == NUM)? r : l, p);
17373         }
17374         break;
17375     case F_COV:
17376     case F_COR:
17377     case F_NAALEN:
17378     case F_KMEIER:
17379         /* functions taking two series/vectors as args, mostly */
17380 	if ((l->t == SERIES || l->t == MAT || l->t == NUM) &&
17381             (r->t == SERIES || r->t == MAT || r->t == NUM)) {
17382             ret = series_2_func(l, r, t->t, p);
17383         } else if ((l->t == SERIES || l->t == MAT) &&
17384                    null_node(r) &&
17385                    (t->t == F_NAALEN || t->t == F_KMEIER)) {
17386             ret = series_2_func(l, NULL, t->t, p);
17387         } else {
17388             p->err = E_INVARG;
17389         }
17390         break;
17391     case F_FCSTATS:
17392         /* two series or vectors, plus optional boolean */
17393         if ((l->t == SERIES || l->t == MAT) &&
17394             (m->t == SERIES || m->t == MAT || m->t == LIST)) {
17395             ret = fcstats_node(l, m, r, p);
17396         } else {
17397             p->err = E_INVARG;
17398         }
17399         break;
17400     case F_NPCORR:
17401         /* two series or vectors, plus optional control string */
17402         if ((l->t == SERIES || l->t == MAT) &&
17403             (m->t == SERIES || m->t == MAT) &&
17404             null_or_string(r)) {
17405             ret = npcorr_node(l, m, r, p);
17406         } else {
17407             p->err = E_INVARG;
17408         }
17409         break;
17410     case F_MXTAB:
17411         /* functions taking two series or matrices as args and returning
17412            a matrix */
17413         if ((l->t == SERIES && r->t == SERIES) || (l->t == MAT && r->t == MAT)) {
17414             ret = mxtab_func(l, r, p);
17415         } else {
17416             node_type_error(t->t, (l->t == SERIES)? 2 : 1,
17417                             SERIES, (l->t == SERIES)? r : l, p);
17418         }
17419         break;
17420     case F_SORTBY:
17421         /* takes two series as args, returns series */
17422         if (l->t == SERIES && r->t == SERIES) {
17423             ret = series_sort_by(l, r, p);
17424         } else {
17425             node_type_error(t->t, (l->t == SERIES)? 2 : 1,
17426                             SERIES, (l->t == SERIES)? r : l, p);
17427         }
17428         break;
17429     case F_IMAT:
17430     case F_ZEROS:
17431     case F_ONES:
17432     case F_MUNIF:
17433     case F_MNORM:
17434     case F_RANDPERM:
17435         /* matrix-creation functions */
17436         if (scalar_node(l) && null_or_scalar(r)) {
17437             ret = matrix_fill_func(l, r, t->t, p);
17438         } else if (!scalar_node(l)) {
17439             node_type_error(t->t, 1, NUM, l, p);
17440         } else {
17441             node_type_error(t->t, 2, NUM, r, p);
17442         }
17443         break;
17444     case F_SUMC:
17445     case F_SUMR:
17446     case F_PRODC:
17447     case F_PRODR:
17448     case F_MEANC:
17449     case F_MEANR:
17450     case F_SDC:
17451     case F_MCOV:
17452     case F_MCORR:
17453     case F_CDEMEAN:
17454     case F_CHOL:
17455     case F_PSDROOT:
17456     case F_INV:
17457     case F_INVPD:
17458     case F_GINV:
17459     case F_DIAG:
17460     case F_TRANSP:
17461     case F_MREV:
17462     case F_VEC:
17463     case F_VECH:
17464     case F_UNVECH:
17465     case F_UPPER:
17466     case F_LOWER:
17467     case F_NULLSPC:
17468     case F_MEXP:
17469     case F_MLOG:
17470     case F_MINC:
17471     case F_MAXC:
17472     case F_MINR:
17473     case F_MAXR:
17474     case F_IMINC:
17475     case F_IMAXC:
17476     case F_IMINR:
17477     case F_IMAXR:
17478     case F_FFT:
17479     case F_FFT2:
17480     case F_FFTI:
17481     case F_POLROOTS:
17482     case F_CTRANS:
17483         /* matrix -> matrix functions */
17484         if (l->t == MAT || l->t == NUM) {
17485             ret = matrix_to_matrix_func(l, r, t->t, p);
17486         } else if (t->t == F_MREV && l->t == LIST) {
17487             ret = list_reverse_node(l, p);
17488         } else {
17489             node_type_error(t->t, 1, MAT, l, p);
17490         }
17491         break;
17492     case F_ROWS:
17493     case F_COLS:
17494     case F_NORM1:
17495     case F_INFNORM:
17496     case F_RCOND:
17497     case F_CNUMBER:
17498     case F_RANK:
17499         /* matrix -> scalar functions */
17500         if (l->t == MAT || l->t == NUM) {
17501             ret = matrix_to_scalar_func(l, t->t, p);
17502         } else {
17503             node_type_error(t->t, 0, MAT, l, p);
17504         }
17505         break;
17506     case F_DET:
17507     case F_LDET:
17508     case F_TRACE:
17509         if (l->t == MAT || l->t == NUM) {
17510             ret = matrix_to_alt_node(l, t->t, p);
17511         }
17512         break;
17513     case F_MREAD:
17514     case F_BREAD:
17515         if (l->t != STR) {
17516             node_type_error(t->t, 1, STR, l, p);
17517         } else if (!null_or_scalar(r)) {
17518             node_type_error(t->t, 2, NUM, r, p);
17519         } else {
17520             ret = read_object_func(l, r, t->t, p);
17521         }
17522         break;
17523     case F_QR:
17524     case F_EIGSYM:
17525         /* matrix -> matrix functions, with indirect return */
17526         if (l->t != MAT && l->t != NUM) {
17527             node_type_error(t->t, 1, MAT, l, p);
17528         } else if (r->t != U_ADDR && r->t != EMPTY) {
17529             node_type_error(t->t, 2, U_ADDR, r, p);
17530         } else {
17531             ret = matrix_to_matrix2_func(l, r, t->t, p);
17532         }
17533         break;
17534     case F_COMPLEX:
17535         if ((l->t == MAT || l->t == NUM) &&
17536             (r->t == MAT || null_or_scalar(r))) {
17537             ret = complex_matrix_node(l, r, p);
17538         } else {
17539             p->err = E_TYPES;
17540         }
17541         break;
17542     case F_FDJAC:
17543     case F_NUMHESS:
17544         /* matrix, fncall, optional scalar */
17545         if (l->t == MAT && m->t == STR) {
17546             ret = numeric_jacobian_or_hessian(l, m, r, t->t, p);
17547         } else {
17548             p->err = E_TYPES;
17549         }
17550         break;
17551     case F_MWRITE:
17552         /* matrix, with string as second arg */
17553         if (l->t == MAT && m->t == STR && null_or_scalar(r)) {
17554             ret = matrix_file_write(l, m, r, p);
17555         } else {
17556             p->err = E_TYPES;
17557         }
17558         break;
17559     case F_BWRITE:
17560         /* bundle, with string as second arg */
17561         if (l->t == BUNDLE && m->t == STR && null_or_scalar(r)) {
17562             ret = bundle_file_write(l, m, r, p);
17563         } else {
17564             p->err = E_TYPES;
17565         }
17566         break;
17567     case F_BFGSMAX:
17568         /* matrix-pointer, plus one or two string args */
17569         if ((l->t == U_ADDR || l->t == MAT) && m->t == STR) {
17570             ret = BFGS_maximize(l, m, r, p, t);
17571         } else {
17572             p->err = E_TYPES;
17573         }
17574         break;
17575     case F_BFGSCMAX:
17576         ret = BFGS_constrained_max(t, p);
17577         break;
17578     case F_SIMANN:
17579     case F_NMMAX:
17580     case F_GSSMAX:
17581         /* matrix(-pointer), plus string and scalar args */
17582         if ((l->t == U_ADDR || l->t == MAT) && m->t == STR) {
17583             ret = deriv_free_node(l, m, r, p, t);
17584         } else {
17585             p->err = E_TYPES;
17586         }
17587         break;
17588     case F_FZERO:
17589         if (l->t == STR) {
17590             ret = fzero_node(l, m, r, p);
17591         } else {
17592             p->err = E_TYPES;
17593         }
17594         break;
17595     case F_IMHOF:
17596         /* matrix, scalar as second arg */
17597         if (l->t == MAT && scalar_node(r)) {
17598             ret = matrix_imhof(l, r, p);
17599         } else {
17600             p->err = E_TYPES;
17601         }
17602         break;
17603     case F_BKW:
17604         /* matrix, string(s) as second optional arg,
17605            quiet flag as optional third arg */
17606         if (l->t == MAT) {
17607             ret = bkw_node(l, m, r, p);
17608         } else {
17609             p->err = E_TYPES;
17610         }
17611         break;
17612     case F_FEVD:
17613         /* integer target, source plus optional bundle */
17614         if (scalar_node(l) && null_or_scalar(m)) {
17615             ret = fevd_node(l, m, r, p);
17616         } else {
17617             p->err = E_TYPES;
17618         }
17619         break;
17620     case F_CNAMESET:
17621     case F_RNAMESET:
17622         /* matrix, with (list, string or strings array) as second arg */
17623         if (l->t == MAT && (ok_list_node(r, p) || r->t == STR || r->t == ARRAY)) {
17624             ret = matrix_add_names(l, r, t->t, p);
17625         } else {
17626             p->err = E_TYPES;
17627         }
17628         break;
17629     case F_CNAMEGET:
17630     case F_RNAMEGET:
17631         /* matrix, scalar as second arg */
17632         if (l->t == MAT && null_or_scalar(r)) {
17633             ret = matrix_get_col_or_row_name(t->t, l, r, p);
17634         } else {
17635             p->err = E_TYPES;
17636         }
17637         break;
17638     case F_XMIN:
17639     case F_XMAX:
17640     case F_RANDINT:
17641     case F_KPSSCRIT:
17642         /* two scalars */
17643         if (scalar_node(l) && scalar_node(r)) {
17644             if (t->t == F_KPSSCRIT) {
17645                 ret = kpss_crit_node(l, r, p);
17646             } else {
17647                 ret = two_scalars_func(l, r, t->t, p);
17648             }
17649         } else {
17650             p->err = E_TYPES;
17651         }
17652         break;
17653     case F_MSHAPE:
17654     case F_SVD:
17655     case F_EIGGEN:
17656     case F_EIGEN:
17657     case F_SCHUR:
17658     case F_TRIMR:
17659     case F_TOEPSOLV:
17660     case F_CORRGM:
17661     case F_SEQ:
17662     case F_REPLACE:
17663     case F_STRNCMP:
17664     case F_WEEKDAY:
17665     case F_DAYSPAN:
17666     case F_SMPLSPAN:
17667     case F_MONTHLEN:
17668     case F_EPOCHDAY:
17669     case F_KDENSITY:
17670     case F_SETNOTE:
17671     case F_BWFILT:
17672     case F_VARSIMUL:
17673     case F_STRSUB:
17674     case F_REGSUB:
17675     case F_MLAG:
17676     case F_EIGSOLVE:
17677     case F_PRINCOMP:
17678     case F_HALTON:
17679     case F_AGGRBY:
17680     case F_IWISHART:
17681     case F_SUBSTR:
17682     case F_MWEIGHTS:
17683     case F_MGRADIENT:
17684     case F_LRCOVAR:
17685     case F_BRENAME:
17686     case F_ISOWEEK:
17687     case F_STACK:
17688     case F_VMA:
17689     case F_BCHECK:
17690     case HF_REGLS:
17691         /* built-in functions taking three args */
17692         if (t->t == F_REPLACE) {
17693             ret = replace_value(l, m, r, p);
17694         } else if (t->t == F_STRSUB || t->t == F_REGSUB) {
17695             ret = string_replace(l, m, r, t, p);
17696         } else if (t->t == F_EPOCHDAY) {
17697             ret = eval_epochday(l, m, r, p);
17698         } else {
17699             ret = eval_3args_func(l, m, r, t->t, p);
17700         }
17701         break;
17702     case F_GEOPLOT:
17703 	ret = geoplot_node(l, m, r, p);
17704 	break;
17705     case F_PRINTF:
17706     case F_SPRINTF:
17707         if (l->t == STR && null_or_string(r)) {
17708             ret = eval_print_scan(NULL, l, r, t->t, p);
17709         } else {
17710             node_type_error(t->t, 0, STR, NULL, p);
17711         }
17712         break;
17713     case F_SSCANF:
17714         if (l->t == STR && m->t == STR && r->t == STR) {
17715             ret = eval_print_scan(l, m, r, t->t, p);
17716         } else if (l->t == ARRAY && m->t == STR && r->t == STR) {
17717             ret = eval_print_scan(l, m, r, t->t, p);
17718         } else {
17719             node_type_error(t->t, 0, STR, NULL, p);
17720         }
17721         break;
17722     case F_BESSEL:
17723         /* functions taking one char, one scalar/series and one
17724            matrix/series/scalar as args */
17725         if (l->t != STR) {
17726             node_type_error(t->t, 1, STR, l, p);
17727         } else if (!scalar_node(m)) {
17728             node_type_error(t->t, 2, NUM, m, p);
17729         } else if (r->t != NUM && r->t != SERIES && r->t != MAT) {
17730             node_type_error(t->t, 3, NUM, r, p);
17731         } else {
17732             ret = eval_bessel_func(l, m, r, p);
17733         }
17734         break;
17735     case F_BKFILT:
17736     case F_MOLS:
17737     case F_MPOLS:
17738     case F_MRLS:
17739     case F_FILTER:
17740     case F_MCOVG:
17741     case F_NRMAX:
17742     case F_LOESS:
17743     case F_GHK:
17744     case F_QUADTAB:
17745     case F_QLRPVAL:
17746     case F_BOOTCI:
17747     case F_BOOTPVAL:
17748     case F_MOVAVG:
17749     case F_DEFARRAY:
17750     case F_DEFBUNDLE:
17751     case F_DEFLIST:
17752     case F_IRF:
17753     case F_NADARWAT:
17754     case F_FEVAL:
17755     case F_CHOWLIN:
17756     case F_HYP2F1:
17757     case F_TDISAGG:
17758     case HF_CLOGFI:
17759     case F_DEFARGS:
17760     case F_MIDASMULT:
17761         /* built-in functions taking more than three args */
17762         if (t->t == F_FEVAL) {
17763             ret = eval_feval(t, p);
17764         } else {
17765             ret = eval_nargs_func(t, p);
17766         }
17767         break;
17768     case F_KSETUP:
17769     case F_KFILTER:
17770     case F_KSMOOTH:
17771     case F_KSIMUL:
17772     case F_KDSMOOTH:
17773         if (t->t == F_KSETUP || bundle_pointer_arg0(t)) {
17774             ret = eval_kalman_bundle_func(t, p);
17775         } else {
17776             p->err = E_TYPES;
17777         }
17778         break;
17779     case F_KSIMDATA:
17780         if (r->t == MAT) {
17781             ret = kalman_data_node(l, r, p);
17782         } else {
17783             node_type_error(t->t, 2, MAT, r, p);
17784         }
17785         break;
17786     case F_ISOCONV:
17787         ret = isoconv_node(t, p);
17788         break;
17789     case MVAR:
17790         /* variable "under" model */
17791         ret = model_var_node(t, NULL, p);
17792         break;
17793     case DMSTR:
17794         ret = dollar_str_node(t, NULL, p);
17795         break;
17796     case DVAR:
17797         /* dataset "dollar" variable */
17798         ret = dollar_var_node(t, p);
17799         break;
17800     case MDEF:
17801         /* matrix definition */
17802         ret = matrix_def_node(t, p);
17803         break;
17804     case F_OBSNUM:
17805     case F_ISDISCR:
17806     case F_NLINES:
17807     case F_REMOVE:
17808     case F_ISCMPLX:
17809         if (l->t == STR) {
17810             ret = object_status(l, t, p);
17811         } else {
17812             node_type_error(t->t, 1, STR, l, p);
17813         }
17814         break;
17815     case F_STRLEN:
17816         if (l->t == STR) {
17817             ret = object_status(l, t, p);
17818         } else if (useries_node(l) || l->t == ARRAY) {
17819             ret = multi_str_node(l, t->t, p);
17820         } else {
17821             node_type_error(t->t, 1, STR, l, p);
17822         }
17823         break;
17824     case F_EXISTS:
17825         if (l->t == STR) {
17826             ret = object_status(l, t, p);
17827         } else {
17828             ret = generic_typeof_node(l, t, p);
17829         }
17830         break;
17831     case F_TYPEOF:
17832         ret = generic_typeof_node(l, t, p);
17833         break;
17834     case F_NELEM:
17835         ret = n_elements_node(l, p);
17836         break;
17837     case F_INLIST:
17838     case HF_LISTINFO:
17839         if (l->t == LIST && t->t == HF_LISTINFO) {
17840             ret = list_info_node(l, r, p);
17841         } else if (ok_list_node(l, p)) {
17842             ret = in_list_node(l, r, p);
17843         } else {
17844             node_type_error(t->t, 1, LIST, l, p);
17845         }
17846         break;
17847     case F_PDF:
17848     case F_CDF:
17849     case F_INVCDF:
17850     case F_CRIT:
17851     case F_PVAL:
17852     case F_RANDGEN:
17853     case F_MRANDGEN:
17854     case F_RANDGEN1:
17855     case F_URCPVAL:
17856         if (t->L->t == FARGS) {
17857             if (t->t == F_URCPVAL) {
17858                 ret = eval_urcpval(t, p);
17859             } else {
17860                 ret = eval_pdist(t, p);
17861             }
17862         } else {
17863             node_type_error(t->t, 0, FARGS, t->L, p);
17864         }
17865         break;
17866     case CON:
17867         /* built-in constant */
17868         ret = retrieve_const(t, p);
17869         break;
17870     case UFUN:
17871         ret = eval_ufunc(t, p, NULL);
17872         break;
17873 #ifdef USE_RLIB
17874     case RFUN:
17875         ret = eval_Rfunc(t, p);
17876         break;
17877 #endif
17878     case QUERY:
17879         ret = eval_query(t, p);
17880         break;
17881     case B_LCAT:
17882         /* list concatenation */
17883         if (ok_list_node(l, p) && ok_list_node(r, p)) {
17884             ret = eval_lcat(l, r, p);
17885         } else {
17886             p->err = E_TYPES;
17887         }
17888         break;
17889     case F_SQUARE:
17890         if (ok_list_node(l, p) && null_or_scalar(r)) {
17891             ret = apply_list_func(l, r, t->t, p);
17892         } else {
17893             p->err = E_TYPES;
17894         }
17895         break;
17896     case F_WMEAN:
17897     case F_WVAR:
17898     case F_WSD:
17899         /* two lists -> series, with optional boolean */
17900         if (ok_list_node(l, p) && ok_list_node(m, p)) {
17901             ret = list_list_series_func(l, m, t->t, r, p);
17902         } else {
17903             p->err = E_TYPES;
17904         }
17905         break;
17906     case F_LINCOMB:
17907         /* list + matrix -> series */
17908         if (ok_list_node(l, p) && ok_matrix_node(r)) {
17909             ret = lincomb_func(l, r, NULL, t->t, p);
17910         } else {
17911             p->err = E_TYPES;
17912         }
17913         break;
17914     case F_MLINCOMB:
17915         /* list + matrix + int -> series */
17916         if (ok_list_node(l, p) && m->t == MAT &&
17917             (scalar_node(r) || r->t == STR)) {
17918             ret = lincomb_func(l, m, r, t->t, p);
17919         } else {
17920             p->err = E_TYPES;
17921         }
17922         break;
17923     case F_ARGNAME:
17924     case F_BACKTICK:
17925     case F_STRSTRIP:
17926     case F_FIXNAME:
17927         if (l->t == STR) {
17928             ret = single_string_func(l, r, t->t, p);
17929         } else if (t->t == F_ARGNAME && uvar_node(l)) {
17930             ret = argname_from_uvar(l, r, p);
17931         } else {
17932             node_type_error(t->t, 0, STR, l, p);
17933         }
17934         break;
17935     case F_CCODE:
17936         ret = country_code_node(l, r, p);
17937         break;
17938     case F_READFILE:
17939         if (l->t == STR) {
17940             ret = readfile_node(l, r, p);
17941         } else {
17942             node_type_error(t->t, 1, STR, l, p);
17943         }
17944         break;
17945     case F_GETENV:
17946     case F_NGETENV:
17947         if (l->t == STR) {
17948             ret = do_getenv(l, t->t, p);
17949         } else {
17950             node_type_error(t->t, 0, STR, l, p);
17951         }
17952         break;
17953     case F_FUNCERR:
17954         ret = do_funcerr(l, p);
17955         break;
17956     case F_ERRORIF:
17957         if (r->t != STR) {
17958             p->err = E_TYPES;
17959         } else {
17960             ret = do_errorif(l, r, p);
17961         }
17962         break;
17963     case F_ASSERT:
17964         if (l->t == NUM && r->t == STR) {
17965             ret = do_assert(l, r, p);
17966         } else {
17967             p->err = E_TYPES;
17968         }
17969         break;
17970     case F_CONTAINS:
17971         if (r->t == MAT && (l->t == NUM || l->t == SERIES || l->t == MAT)) {
17972             ret = contains_node(l, r, p);
17973         } else {
17974             p->err = E_TYPES;
17975         }
17976         break;
17977     case F_OBSLABEL:
17978         if (l->t == NUM || l->t == MAT) {
17979             ret = int_to_string_func(l, t->t, p);
17980         } else {
17981             node_type_error(t->t, 0, NUM, l, p);
17982         }
17983         break;
17984     case F_VARNAME:
17985         if (l->t == NUM || l->t == MAT || l->t == SERIES) {
17986             ret = int_to_string_func(l, t->t, p);
17987         } else if (l->t == LIST) {
17988             ret = list_to_string_func(l, t->t, p);
17989         } else {
17990             node_type_error(t->t, 0, NUM, l, p);
17991         }
17992         break;
17993     case F_VARNAMES:
17994         if (l->t == LIST) {
17995             ret = list_to_string_func(l, t->t, p);
17996         } else {
17997             node_type_error(t->t, 0, LIST, l, p);
17998         }
17999         break;
18000     case F_VARNUM:
18001     case F_TOLOWER:
18002     case F_TOUPPER:
18003         if (l->t == STR) {
18004             if (t->t == F_TOLOWER || t->t == F_TOUPPER) {
18005                 ret = one_string_func(l, t->t, p);
18006             } else {
18007                 ret = varnum_node(l, p);
18008             }
18009         } else {
18010             node_type_error(t->t, 0, STR, l, p);
18011         }
18012         break;
18013     case F_JSONGET:
18014     case F_XMLGET:
18015         if (l->t == STR && m->t == STR) {
18016             ret = two_string_func(l, m, r, t->t, p);
18017         } else if (l->t == STR && m->t == ARRAY && t->t == F_XMLGET) {
18018             ret = two_string_func(l, m, r, t->t, p);
18019         } else {
18020             node_type_error(t->t, (l->t == STR)? 2 : 1,
18021                             STR, (l->t == STR)? m : l, p);
18022         }
18023         break;
18024     case F_JSONGETB:
18025         if (l->t == STR && null_or_string(r)) {
18026             ret = two_string_func(l, r, NULL, t->t, p);
18027         } else {
18028             p->err = E_TYPES;
18029         }
18030         break;
18031     case F_STRSTR:
18032     case F_INSTRING:
18033         if (l->t == STR && r->t == STR) {
18034             ret = two_string_func(l, r, NULL, t->t, p);
18035         } else {
18036             node_type_error(t->t, (l->t == STR)? 2 : 1,
18037                             STR, (l->t == STR)? r : l, p);
18038         }
18039         break;
18040     case F_STRSPLIT:
18041         if (l->t == STR) {
18042             ret = strsplit_node(t->t, l, m, r, p);
18043         } else {
18044             node_type_error(t->t, 1, STR, l, p);
18045         }
18046         break;
18047     case F_GETLINE:
18048         if (l->t == STR && (null_or_string(r) || r->t == U_ADDR)) {
18049             ret = getline_node(l, r, p);
18050         } else {
18051             node_type_error(t->t, (l->t == STR)? 2 : 1,
18052                             STR, (l->t == STR)? r : l, p);
18053         }
18054         break;
18055     case F_ERRMSG:
18056         if (null_or_scalar(l)) {
18057             ret = errmsg_node(l, p);
18058         } else {
18059             node_type_error(t->t, 0, NUM, l, p);
18060         }
18061         break;
18062     case F_ISODATE:
18063     case F_JULDATE:
18064         ret = isodate_node(l, r, t->t, p);
18065         break;
18066     case F_STRFTIME:
18067         if (scalar_node(l)) {
18068             ret = strftime_node(l, r, p);
18069         } else {
18070             node_type_error(t->t, 0, NUM, l, p);
18071         }
18072         break;
18073     case F_STRPTIME:
18074         if (l->t == STR || scalar_node(l)) {
18075             ret = strptime_node(l, r, p);
18076         } else {
18077             node_type_error(t->t, 0, STR, l, p);
18078         }
18079         break;
18080     case F_ATOF:
18081         if (l->t == STR || l->t == SERIES) {
18082             ret = atof_node(l, p);
18083         } else {
18084             node_type_error(t->t, 0, STR, l, p);
18085         }
18086         break;
18087     case F_MPI_RECV:
18088         ret = mpi_transfer_node(l, NULL, NULL, t->t, p);
18089         break;
18090     case F_MPI_SEND:
18091     case F_BCAST:
18092     case F_ALLREDUCE:
18093         if (t->t == F_ALLREDUCE && r->t != STR) {
18094             node_type_error(t->t, 2, STR, r, p);
18095         } else {
18096             ret = mpi_transfer_node(l, r, NULL, t->t, p);
18097         }
18098         break;
18099     case F_REDUCE:
18100     case F_SCATTER:
18101         if (m->t != STR) {
18102             node_type_error(t->t, 2, STR, m, p);
18103         } else if (!null_or_scalar(r)) {
18104             node_type_error(t->t, 3, NUM, r, p);
18105         } else {
18106             ret = mpi_transfer_node(l, m, r, t->t, p);
18107         }
18108         break;
18109     case F_GENSERIES:
18110         ret = gen_series_node(l, r, p);
18111         break;
18112     case F_ARRAY:
18113         ret = gen_array_node(l, p);
18114         break;
18115     case F_STRVALS:
18116         if (!useries_node(l)) {
18117             node_type_error(t->t, 0, USERIES, l, p);
18118         } else {
18119             ret = get_series_stringvals(l, r, p);
18120         }
18121         break;
18122     case F_STRINGIFY:
18123         if (!useries_node(l) || r->t != ARRAY) {
18124             int l_ok = useries_node(l);
18125 
18126             node_type_error(t->t, l_ok ? 2 : 1,
18127                             l_ok ? ARRAY : USERIES,
18128                             l_ok ? r : l, p);
18129         } else {
18130             ret = stringify_series(l, r, p);
18131         }
18132         break;
18133     default:
18134         fprintf(stderr, "eval: weird node %s (t->t = %d)\n",
18135                 getsymb(t->t), t->t);
18136         p->err = E_TYPES;
18137         break;
18138     }
18139 
18140  finish:
18141 
18142     if (!p->err && ret != NULL && ret != t && is_aux_node(ret)) {
18143         if (t->t == F_FEVAL && ret->refcount > 0) {
18144             ; /* don't attach, it belongs elsewhere! */
18145         } else {
18146             p->err = attach_aux_node(t, ret, p);
18147         }
18148     }
18149 
18150  bailout:
18151 
18152 #if EDEBUG
18153     fprintf(stderr, "eval (t->t = %03d, %s): returning NODE %s at %p, err %d\n",
18154             t->t, getsymb(t->t), ret == NULL ? "nil" : getsymb(ret->t),
18155             (void *) ret, p->err);
18156     if (t->t == SERIES)
18157         fprintf(stderr, " (SERIES node, xvec at %p, vnum = %d)\n",
18158                 (void *) t->v.xvec, t->vnum);
18159 #endif
18160 
18161     return ret;
18162 }
18163 
18164 #if !AUX_NODES_DEBUG
18165 
18166 /* non-debugging variant: easier to see what's going on */
18167 
attach_aux_node(NODE * t,NODE * ret,parser * p)18168 static inline int attach_aux_node (NODE *t, NODE *ret, parser *p)
18169 {
18170     if (t->aux == NULL) {
18171         t->aux = ret;
18172         ret->refcount += 1;
18173     } else if (t->aux != ret) {
18174         if (t->t == QUERY || t->t == B_AND || t->t == B_OR) {
18175             /* OK to switch aux node in these cases */
18176             free_node(t->aux, p);
18177             t->aux = ret;
18178             ret->refcount += 1;
18179         } else if (is_proxy_node(t->aux)) {
18180             /* an extension to the above */
18181             free_node(t->aux, p);
18182             t->aux = ret;
18183             ret->refcount += 1;
18184         } else {
18185             /* otherwise if we're trying to switch aux node,
18186                something must have gone wrong
18187             */
18188             fprintf(stderr, "! node %s already has aux node %s attached\n",
18189                     getsymb(t->t), getsymb(t->aux->t));
18190             return E_DATA;
18191         }
18192     }
18193 
18194     return 0;
18195 }
18196 
18197 #else
18198 
18199 /* variant with lots of debugging spew */
18200 
attach_aux_node(NODE * t,NODE * ret,parser * p)18201 static inline int attach_aux_node (NODE *t, NODE *ret, parser *p)
18202 {
18203     if (t->aux == NULL) {
18204         fprintf(stderr, "++ attach aux node %p (%s) to node %p (%s)\n",
18205                 ret, getsymb(ret->t), t, getsymb(t->t));
18206         if (ret->refcount > 0) {
18207             fprintf(stderr, "   note: refcount on %p = %d\n",
18208                     (void *) ret, ret->refcount);
18209         }
18210         t->aux = ret;
18211         ret->refcount += 1;
18212     } else if (t->aux != ret) {
18213         if (t->t == QUERY || t->t == B_AND || t->t == B_OR) {
18214             /* the result node may switch in these cases (only?) */
18215             fprintf(stderr, "boolean: freeing %p\n", (void *) t->aux);
18216             free_node(t->aux, p);
18217             fprintf(stderr, "boolean: attaching %p\n", (void *) ret);
18218             t->aux = ret;
18219             ret->refcount += 1;
18220         } else if (is_proxy_node(t->aux)) {
18221             /* an extension to the above */
18222             fprintf(stderr, "proxy: freeing %p\n", (void *) t->aux);
18223             free_node(t->aux, p);
18224             fprintf(stderr, "proxy: attaching %p\n", (void *) ret);
18225             t->aux = ret;
18226             ret->refcount += 1;
18227         } else {
18228             fprintf(stderr, "!! node %p (%s) has aux node %p (%s) attached\n"
18229                     "   not attaching ret at %p (%s)\n", t, getsymb(t->t),
18230                     t->aux, getsymb(t->aux->t), ret, getsymb(ret->t));
18231             return E_DATA;
18232         }
18233     }
18234 
18235     return 0;
18236 }
18237 
18238 #endif
18239 
more_input(const char * s)18240 static int more_input (const char *s)
18241 {
18242     while (*s) {
18243         if (!isspace((unsigned char) *s)) {
18244             return 1;
18245         }
18246         s++;
18247     }
18248 
18249     return 0;
18250 }
18251 
18252 /* get the next input character for the lexer */
18253 
parser_getc(parser * p)18254 int parser_getc (parser *p)
18255 {
18256 #if EDEBUG > 1
18257     fprintf(stderr, "parser_getc: src='%s'\n", p->point);
18258 #endif
18259 
18260     p->ch = 0;
18261 
18262     if (more_input(p->point)) {
18263         p->ch = *p->point;
18264         p->point += 1;
18265     }
18266 
18267 #if EDEBUG > 1
18268     if (p->ch) {
18269         fprintf(stderr, "parser_getc: returning '%c'\n", p->ch);
18270     }
18271 #endif
18272 
18273     return p->ch;
18274 }
18275 
18276 /* advance the read position by n characters */
18277 
parser_advance(parser * p,int n)18278 void parser_advance (parser *p, int n)
18279 {
18280     p->point += n;
18281     p->ch = *p->point;
18282     p->point += 1;
18283 }
18284 
18285 /* throw back the last-read character */
18286 
parser_ungetc(parser * p)18287 void parser_ungetc (parser *p)
18288 {
18289     p->point -= 1;
18290     p->ch = *(p->point - 1);
18291 }
18292 
18293 /* Look ahead for the first occurrence of a given character in
18294    the remaining input stream; return its 0-based index or
18295    -1 if not found.
18296 */
18297 
parser_char_index(parser * p,int c)18298 int parser_char_index (parser *p, int c)
18299 {
18300     int i;
18301 
18302     for (i=0; p->point[i] != '\0'; i++) {
18303         if (p->point[i] == c) {
18304             return i;
18305         }
18306     }
18307 
18308     return -1;
18309 }
18310 
18311 /* For error reporting: print the input up to the current
18312    parse point, unless it's not valid UTF-8. Return 0
18313    if the input is printed OK, otherwise non-zero.
18314 */
18315 
parser_print_input(parser * p)18316 int parser_print_input (parser *p)
18317 {
18318     int len = p->point - p->input;
18319     char *s = gretl_strndup(p->input, len);
18320     int err = 0;
18321 
18322     if (s != NULL) {
18323         if (g_utf8_validate(s, -1, NULL)) {
18324             pprintf(p->prn, "> %s\n", s);
18325         } else {
18326             err = 1;
18327         }
18328         free(s);
18329     } else {
18330         err = 1;
18331     }
18332 
18333     return err;
18334 }
18335 
18336 /* "pretty print" syntactic nodes and symbols */
18337 
printsymb(int symb,const parser * p)18338 static void printsymb (int symb, const parser *p)
18339 {
18340     pputs(p->prn, getsymb(symb));
18341 }
18342 
printnode(NODE * t,parser * p,int value)18343 static void printnode (NODE *t, parser *p, int value)
18344 {
18345     if (t == NULL) {
18346         pputs(p->prn, "NULL");
18347     } else if (!value && useries_node(t)) {
18348         pprintf(p->prn, "%s", p->dset->varname[t->vnum]);
18349     } else if (!value && uscalar_node(t)) {
18350         pprintf(p->prn, "%s", t->vname);
18351     } else if (t->t == NUM) {
18352         if (na(t->v.xval)) {
18353             pputs(p->prn, "NA");
18354         } else {
18355             pprintf(p->prn, "%.8g", t->v.xval);
18356         }
18357     } else if (t->t == SERIES) {
18358         const double *x = t->v.xvec;
18359         int i, j = 1;
18360 
18361         if (p->lh.vnum > 0 && p->lh.vnum < p->dset->v) {
18362             pprintf(p->prn, "%s\n", p->dset->varname[p->lh.vnum]);
18363         }
18364 
18365         for (i=p->dset->t1; i<=p->dset->t2; i++, j++) {
18366             if (na(x[i])) {
18367                 pputs(p->prn, "NA");
18368             } else {
18369                 pprintf(p->prn, "%g", x[i]);
18370             }
18371             if (j % 8 == 0) {
18372                 pputc(p->prn, '\n');
18373             } else if (i < p->dset->t2) {
18374                 pputc(p->prn, ' ');
18375             }
18376         }
18377     } else if (t->t == MAT) {
18378         if (t->vname != NULL) {
18379             pputs(p->prn, t->vname);
18380         } else {
18381             gretl_matrix_print_to_prn(t->v.m, NULL, p->prn);
18382         }
18383     } else if (t->t == BUNDLE) {
18384         gretl_bundle_print(t->v.b, p->prn);
18385     } else if (t->t == DBUNDLE) {
18386         pputs(p->prn, bvarname(t->v.idnum));
18387     } else if (t->t == ARRAY) {
18388         gretl_array_print(t->v.a, p->prn);
18389     } else if (t->t == UOBJ) {
18390         pprintf(p->prn, "%s", t->v.str);
18391     } else if (t->t == DVAR) {
18392         pputs(p->prn, dvarname(t->v.idnum));
18393     } else if (t->t == MVAR) {
18394         pputs(p->prn, mvarname(t->v.idnum));
18395     } else if (t->t == CON) {
18396         pputs(p->prn, constname(t->v.idnum));
18397     } else if (t->t == DUM) {
18398         pputs(p->prn, dumname(t->v.idnum));
18399     } else if (binary_op(t->t)) {
18400         pputc(p->prn, '(');
18401         printnode(t->L, p, 0);
18402         printsymb(t->t, p);
18403         printnode(t->R, p, 0);
18404         pputc(p->prn, ')');
18405     } else if (t->t == MSL) {
18406         printnode(t->L, p, 0);
18407         pputc(p->prn, '[');
18408         printnode(t->R, p, 0);
18409         pputc(p->prn, ']');
18410     } else if (t->t == SLRAW) {
18411         pputs(p->prn, "SLRAW");
18412     } else if (t->t == SUBSL) {
18413         pputs(p->prn, "SUBSL");
18414     } else if (func1_symb(t->t)) {
18415         printsymb(t->t, p);
18416         pputc(p->prn, '(');
18417         printnode(t->L, p, 0);
18418         pputc(p->prn, ')');
18419     } else if (unary_op(t->t)) {
18420         printsymb(t->t, p);
18421         printnode(t->L, p, 0);
18422     } else if (func2_symb(t->t)) {
18423         printsymb(t->t, p);
18424         pputc(p->prn, '(');
18425         printnode(t->L, p, 0);
18426         if (t->R->t != EMPTY) {
18427             pputc(p->prn, ',');
18428         }
18429         printnode(t->R, p, 0);
18430         pputc(p->prn, ')');
18431     } else if (t->t == STR) {
18432         pprintf(p->prn, "%s", t->v.str);
18433     } else if (t->t == PTR) {
18434         pprintf(p->prn, "%s", t->vname);
18435     } else if (t->t == MDEF) {
18436         pprintf(p->prn, "{ MDEF }");
18437     } else if (t->t == DMSTR || t->t == UFUN) {
18438         printnode(t->L, p, 0);
18439         pputc(p->prn, '(');
18440         printnode(t->R, p, 0);
18441         pputc(p->prn, ')');
18442     } else if (t->t == LISTVAR) {
18443         pprintf(p->prn, "%s.%s", t->L->v.str, t->R->v.str);
18444     } else if (t->t == LIST) {
18445         pputs(p->prn, "LIST");
18446     } else if (t->t == LAG) {
18447         pputs(p->prn, "LAG");
18448     } else if (t->t != EMPTY) {
18449         pputs(p->prn, "weird tree - ");
18450         printsymb(t->t, p);
18451     }
18452 }
18453 
18454 /* which modified assignment operators of the type '+='
18455    will we accept, when generating various types of
18456    result? */
18457 #define ok_matrix_op(o) (o == B_ASN  || o == B_DOTASN || \
18458                          o == B_ADD  || o == B_SUB || \
18459                          o == B_MUL  || o == B_DIV || \
18460                          o == B_HCAT || o == B_VCAT)
18461 #define ok_list_op(o) (o == B_ASN || o == B_ADD || o == B_SUB)
18462 #define ok_string_op(o) (o == B_ASN || o == B_ADD || \
18463                          o == B_HCAT || o == INC)
18464 #define ok_array_op(o) (o == B_ASN || o == B_ADD || o == B_SUB)
18465 #define ok_bundle_op(o) (o == B_ASN || o == B_ADD)
18466 
18467 struct mod_assign {
18468     int c;
18469     int op;
18470 };
18471 
18472 /* supported "inflections" of assignment */
18473 
18474 struct mod_assign m_assign[] = {
18475     { '+', B_ADD },
18476     { '-', B_SUB },
18477     { '*', B_MUL },
18478     { '/', B_DIV },
18479     { '%', B_MOD},
18480     { '^', B_POW },
18481     { '~', B_HCAT },
18482     { '|', B_VCAT },
18483     { '.', B_DOTASN },
18484     { 0, 0}
18485 };
18486 
18487 /* read operator from formula: this is either
18488    simple assignment or something like '+=' */
18489 
get_op(char * s)18490 static int get_op (char *s)
18491 {
18492     if (s[0] == '=') {
18493         s[1] = '\0';
18494         return B_ASN;
18495     }
18496 
18497     if (!strcmp(s, "++")) {
18498         return INC;
18499     }
18500 
18501     if (!strcmp(s, "--")) {
18502         return DEC;
18503     }
18504 
18505     if (s[1] == '=') {
18506         int i;
18507 
18508         for (i=0; m_assign[i].c; i++) {
18509             if (s[0] == m_assign[i].c) {
18510                 return m_assign[i].op;
18511             }
18512         }
18513     }
18514 
18515     return 0;
18516 }
18517 
get_opstr(int op)18518 static char *get_opstr (int op)
18519 {
18520     static char opstr[4] = {0};
18521 
18522     if (op == B_ASN) {
18523         return "=";
18524     } else if (op == INC) {
18525         return "++";
18526     } else if (op == DEC) {
18527         return "--";
18528     } else {
18529         int i;
18530 
18531         for (i=0; m_assign[i].c; i++) {
18532             if (op == m_assign[i].op) {
18533                 opstr[0] = m_assign[i].c;
18534                 opstr[1] = '=';
18535                 return opstr;
18536             }
18537         }
18538         return "??";
18539     }
18540 }
18541 
18542 /* implement the declaration of new variables */
18543 
do_declaration(parser * p)18544 static void do_declaration (parser *p)
18545 {
18546     char **S = NULL;
18547     int i, v, n;
18548 
18549     n = check_declarations(&S, p);
18550 
18551     if (n == 0) {
18552         return;
18553     }
18554 
18555     for (i=0; i<n && !p->err; i++) {
18556         if (S[i] != NULL) {
18557             if (p->targ == SERIES) {
18558                 p->err = dataset_add_NA_series(p->dset, 1);
18559                 if (!p->err) {
18560                     v = p->dset->v - 1;
18561                     strcpy(p->dset->varname[v], S[i]);
18562                 }
18563             } else {
18564                 GretlType type = 0;
18565 
18566                 if (p->targ == MAT) {
18567                     type = GRETL_TYPE_MATRIX;
18568                 } else if (p->targ == NUM) {
18569                     type = GRETL_TYPE_DOUBLE;
18570                 } else if (p->targ == STR) {
18571                     type = GRETL_TYPE_STRING;
18572                 } else if (p->targ == BUNDLE) {
18573                     type = GRETL_TYPE_BUNDLE;
18574                 } else if (p->targ == LIST) {
18575                     type = GRETL_TYPE_LIST;
18576                 } else if (p->targ == ARRAY) {
18577                     type = p->lh.gtype;
18578                 } else {
18579                     p->err = E_DATA;
18580                 }
18581                 if (!p->err) {
18582                     p->err = create_user_var(S[i], type);
18583                 }
18584             }
18585         }
18586     }
18587 
18588     strings_array_free(S, n);
18589 }
18590 
18591 /* The expression supplied for evaluation does not contain an '=':
18592    can we interpret it as an implicit request to print the value
18593    of an existing variable?
18594 */
18595 
parser_try_print(parser * p,const char * s,int * done)18596 static void parser_try_print (parser *p, const char *s, int *done)
18597 {
18598     if (p->lh.t != 0 && p->lh.expr == NULL) {
18599         p->flags |= P_DISCARD;
18600         p->point = s;
18601     } else {
18602         p->err = E_EQN;
18603     }
18604 }
18605 
18606 /* Here we try to parse out the LHS of the statement
18607    and also the operator. If we find a unitary LHS
18608    (simply an indentifier) we write it into p->lh.name,
18609    but if we find a compound LHS (such as a sub-matrix
18610    specification) we save it as p->lh.expr. The
18611    content of @ps is advanced to the first position
18612    beyond the operator.
18613 */
18614 
extract_lhs_and_op(const char ** ps,parser * p,char * opstr)18615 static int extract_lhs_and_op (const char **ps, parser *p,
18616                                char *opstr)
18617 {
18618     const char *s = *ps;
18619     int quoted = 0;
18620     int i, n = 0;
18621     int err = 0;
18622 
18623 #if LHDEBUG
18624     fprintf(stderr, "extract_lhs_and_op: input='%s'\n", s);
18625 #endif
18626 
18627     if (p->targ != UNK && strchr(s, '=') == NULL) {
18628         /* we got a type specification but no assignment,
18629            so should be variable declaration(s) ?
18630         */
18631         p->flags |= P_DECL;
18632         p->lh.expr = gretl_strdup(s);
18633         goto done;
18634     }
18635 
18636     /* Count bytes preceding first unquoted '='. Note that
18637        the "unquoted" condition is required only because
18638        a string-literal bundle key might contain an equals
18639        sign, as in b["foo=bar"] = ...
18640     */
18641     for (i=0; s[i] != '\0'; i++) {
18642         if (s[i] == '"') {
18643             quoted = !quoted;
18644         } else if (!quoted && s[i] == '=') {
18645             break;
18646         }
18647         n++;
18648     }
18649 
18650     if (n > 0) {
18651         char *lhs = NULL;
18652         int lhlen = n;
18653 
18654         if (s[n] == '=') {
18655             /* we actually reached an '=' */
18656             if (strspn(s + n - 1, "+-*/%^~|.") == 1) {
18657                 /* preceded by a modifier: inflected assignment */
18658                 lhlen--;
18659                 opstr[0] = s[n-1];
18660                 opstr[1] = '=';
18661             } else {
18662                 /* no: straight assignment */
18663                 opstr[0] = '=';
18664             }
18665             n++; /* plus 1 for '=' */
18666         }
18667 
18668         if (lhlen > 0) {
18669             lhs = gretl_strndup(s, lhlen);
18670             tailstrip(lhs);
18671             lhlen = strlen(lhs);
18672         }
18673 
18674         if (opstr[0] == '\0' && lhlen > 2) {
18675             /* check for postfix operator */
18676             char *test = lhs + lhlen - 2;
18677 
18678             if (!strcmp(test, "++") || !strcmp(test, "--")) {
18679                 strcpy(opstr, test);
18680                 *test = '\0';
18681                 lhlen -= 2;
18682             }
18683         }
18684 
18685         if (lhlen > 0) {
18686             if (lhlen == gretl_namechar_spn(lhs)) {
18687                 /* a straight identifier? */
18688                 if (lhlen >= VNAMELEN) {
18689                     pprintf(p->prn, _("'%s': name is too long (max %d characters)\n"),
18690                             lhs, VNAMELEN - 1);
18691                     err = E_PARSE;
18692                 } else {
18693                     strcpy(p->lh.name, lhs);
18694                 }
18695             } else if ((p->flags & P_PRIV) && (*lhs == '$' || *lhs == '_') &&
18696                        gretl_namechar_spn(lhs + 1) == lhlen - 1) {
18697                 /* "private" genr of the form $foo=expr or _foo=expr */
18698                 strcpy(p->lh.name, lhs);
18699             } else {
18700                 /* treat as an expression to be evaluated */
18701                 p->lh.expr = lhs;
18702                 lhs = NULL; /* protect against freeing */
18703             }
18704         } else {
18705             /* nothing relevant found */
18706             err = E_PARSE;
18707         }
18708 
18709         if (!err && opstr[0] != '\0') {
18710             p->op = get_op(opstr);
18711         }
18712 
18713         free(lhs);
18714         *ps = s + n;
18715     }
18716 
18717  done:
18718 
18719 #if LHDEBUG
18720     fprintf(stderr, "extract: lh.name='%s', lh.expr='%s', op='%s', err=%d, s='%s'\n",
18721             p->lh.name, p->lh.expr ? p->lh.expr : "NULL", opstr, err, *ps);
18722 #endif
18723 
18724     if (!(p->flags & P_DECL) && p->lh.name[0] == '\0' && p->op == 0) {
18725 	/* added 2021-05-29 */
18726 	p->flags |= P_DISCARD;
18727     }
18728 
18729     return err;
18730 }
18731 
maybe_do_type_errmsg(const char * name,int t)18732 static void maybe_do_type_errmsg (const char *name, int t)
18733 {
18734     const char *tstr = typestr(t);
18735 
18736     if (tstr != NULL && strcmp(tstr, "?")) {
18737         if (name != NULL && *name != '\0') {
18738             gretl_errmsg_sprintf(_("The variable %s is of type %s, "
18739                                    "not acceptable in context"),
18740                                  name, tstr);
18741         } else {
18742             gretl_errmsg_sprintf(_("A variable of type %s is not "
18743                                    "acceptable in context"), tstr);
18744         }
18745     }
18746 }
18747 
assignment_type_errmsg(int targ,int rhs,int op)18748 static void assignment_type_errmsg (int targ, int rhs, int op)
18749 {
18750     const char *rhstr = typestr(rhs);
18751 
18752     if (*rhstr == '?') {
18753         rhstr = getsymb(rhs);
18754     }
18755     gretl_errmsg_sprintf(_("Incompatible types in assignment: "
18756                            "%s %s %s"), typestr(targ), get_opstr(op),
18757                          rhstr);
18758 }
18759 
overwrite_type_check(parser * p)18760 static int overwrite_type_check (parser *p)
18761 {
18762     int err = 0;
18763 
18764     /* FIXME check for series/function collision here */
18765 
18766     if (p->targ != p->lh.t) {
18767         /* don't overwrite one type with another */
18768         maybe_do_type_errmsg(p->lh.name, p->lh.t);
18769         err = E_TYPES;
18770     }
18771 
18772     return err;
18773 }
18774 
overwrite_const_check(const char * name,int vnum)18775 static int overwrite_const_check (const char *name, int vnum)
18776 {
18777     if (object_is_const(name, vnum)) {
18778         return overwrite_err(name);
18779     } else {
18780         return 0;
18781     }
18782 }
18783 
18784 /* Check that we're not trying to modify a const object
18785    via a compound LHS expression; and while we're at
18786    it, check whether we should be generating a list
18787    (a list member of a bundle or an element of an array
18788    of lists).
18789 */
18790 
compound_const_check(NODE * lhs,parser * p)18791 static int compound_const_check (NODE *lhs, parser *p)
18792 {
18793     NODE *n = lhs;
18794     int i = 0, err = 0;
18795 
18796     if (n->t == BMEMB && n->R != NULL && n->R->t == STR) {
18797         GretlType t;
18798 
18799         t = gretl_bundle_get_member_type(n->L->v.b, n->R->v.str, NULL);
18800         if (t == GRETL_TYPE_LIST) {
18801             p->flags |= P_LISTDEF;
18802         }
18803     }
18804 
18805     while (n->t == MSL || n->t == OBS || n->t == BMEMB || n->t == OSL) {
18806         n = n->L;
18807         if (i == 0 && lhs->t == OSL && n->t == ARRAY) {
18808             if (gretl_array_get_type(n->v.a) == GRETL_TYPE_LISTS) {
18809                 p->flags |= P_LISTDEF;
18810             }
18811         }
18812         i++;
18813     }
18814 
18815     /* do we have a const object at the tip of the tree? */
18816     if (n->vname != NULL) {
18817         err = overwrite_const_check(n->vname, n->vnum);
18818     }
18819 
18820     return err;
18821 }
18822 
ok_array_decl(parser * p,const char * s)18823 static int ok_array_decl (parser *p, const char *s)
18824 {
18825     p->lh.gtype = 0;
18826 
18827     if (!strncmp(s, "strings ", 8)) {
18828         p->lh.gtype = GRETL_TYPE_STRINGS;
18829     } else if (!strncmp(s, "matrices ", 9)) {
18830         p->lh.gtype = GRETL_TYPE_MATRICES;
18831     } else if (!strncmp(s, "bundles ", 8)) {
18832         p->lh.gtype = GRETL_TYPE_BUNDLES;
18833     } else if (!strncmp(s, "lists ", 6)) {
18834         p->lh.gtype = GRETL_TYPE_LISTS;
18835     }
18836 
18837     return p->lh.gtype != 0;
18838 }
18839 
18840 /* Given an existing LHS variable, whose type is recorded in
18841    p->lh.t, check that the specified operator is supported
18842    for the type. Return error code if not.
18843 */
18844 
check_operator_validity(parser * p,const char * opstr)18845 static int check_operator_validity (parser *p, const char *opstr)
18846 {
18847     if (p->lh.t == MAT && !ok_matrix_op(p->op)) {
18848         /* matrices: we accept only a limited range of
18849            modified assignment operators */
18850         gretl_errmsg_sprintf(_("'%s' : not implemented for matrices"), opstr);
18851         return E_PARSE;
18852     } else if (p->lh.t == LIST && !ok_list_op(p->op)) {
18853         /* lists: same story as matrices */
18854         gretl_errmsg_sprintf(_("'%s' : not implemented for lists"), opstr);
18855         return E_PARSE;
18856     } else if (p->lh.t == STR && !ok_string_op(p->op)) {
18857         /* strings: ditto */
18858         gretl_errmsg_sprintf(_("'%s' : not implemented for strings"), opstr);
18859         return E_PARSE;
18860     } else if (p->lh.t == ARRAY && !ok_array_op(p->op)) {
18861         /* arrays: ditto */
18862         gretl_errmsg_sprintf(_("'%s' : not implemented for arrays"), opstr);
18863         return E_PARSE;
18864     } else if (p->lh.t == BUNDLE && !ok_bundle_op(p->op)) {
18865         /* bundles: ditto */
18866         gretl_errmsg_sprintf(_("'%s' : not implemented for this type"), opstr);
18867         return E_PARSE;
18868     } else if (p->lh.t != MAT && (p->op == B_VCAT || p->op == B_DOTASN)) {
18869         /* vertical concat: only OK for matrices */
18870         gretl_errmsg_sprintf(_("'%s' : only defined for matrices"), opstr);
18871         return E_PARSE;
18872     } else if (p->lh.t != MAT && p->lh.t != STR && p->op == B_HCAT) {
18873         /* horizontal concat: only OK for matrices, strings */
18874         gretl_errmsg_sprintf(_("'%s' : not implemented for this type"), opstr);
18875         return E_PARSE;
18876     }
18877 
18878     /* otherwise OK? */
18879     return 0;
18880 }
18881 
18882 /* Do we have an inline type specification preceding the
18883    statement proper? In most cases we shouldn't, since it
18884    will already have been handled by the tokenizer (and
18885    the type will now be recorded in p->targ). But we allow
18886    for finding a typespec here in case of "genrs" within
18887    nls/mle/gmm blocks, where the statement bypasses the
18888    regular tokenizer. (FIXME?)
18889 */
18890 
check_for_inline_typespec(const char ** ps,parser * p)18891 static void check_for_inline_typespec (const char **ps, parser *p)
18892 {
18893     const char *s = *ps;
18894 
18895     if (!strncmp(s, "scalar ", 7)) {
18896         p->targ = NUM;
18897         s += 7;
18898     } else if (!strncmp(s, "series ", 7)) {
18899         p->targ = SERIES;
18900         s += 7;
18901     } else if (!strncmp(s, "matrix ", 7)) {
18902         p->targ = MAT;
18903         s += 7;
18904     } else if (!strncmp(s, "list ", 5)) {
18905         p->targ = LIST;
18906         s += 5;
18907     } else if (!strncmp(s, "string ", 7)) {
18908         p->targ = STR;
18909         s += 7;
18910     } else if (!strncmp(s, "bundle ", 7)) {
18911         p->targ = BUNDLE;
18912         s += 7;
18913     } else if (ok_array_decl(p, s)) {
18914         p->targ = ARRAY;
18915         s += strcspn(s, " ") + 1;
18916     }
18917 
18918     /* advance pointer */
18919     *ps = s;
18920 }
18921 
18922 /* Check @p->lh.name for the name of an existing series or
18923    user_var of some kind. If found, record the relevant
18924    info in p->lh.t, and also either p->lh.vnum (series) or
18925    p->lh.uv (other types).
18926 */
18927 
check_existing_lhs_type(parser * p,int * newvar)18928 static int check_existing_lhs_type (parser *p, int *newvar)
18929 {
18930     user_var *uvar;
18931     int v, err = 0;
18932 
18933     if ((err = gretl_reserved_word(p->lh.name))) {
18934 	return err;
18935     }
18936 
18937     v = current_series_index(p->dset, p->lh.name);
18938     if (v >= 0) {
18939         p->lh.vnum = v;
18940         p->lh.t = SERIES;
18941         *newvar = 0;
18942         return 0;
18943     }
18944 
18945     uvar = get_user_var_by_name(p->lh.name);
18946 
18947     if (uvar != NULL) {
18948         GretlType vtype = uvar->type;
18949 
18950         p->lh.uv = uvar;
18951         *newvar = 0;
18952 
18953         if (vtype == GRETL_TYPE_MATRIX) {
18954             p->lh.t = MAT;
18955         } else if (vtype == GRETL_TYPE_DOUBLE) {
18956             if (uvar->flags & UV_NODECL) {
18957                 if (p->targ == UNK) {
18958                     p->flags |= P_NODECL;
18959                 } else {
18960                     uvar->flags &= ~UV_NODECL;
18961                 }
18962             }
18963             p->lh.t = NUM;
18964         } else if (vtype == GRETL_TYPE_LIST) {
18965             p->lh.t = LIST;
18966         } else if (vtype == GRETL_TYPE_STRING) {
18967             p->lh.t = STR;
18968         } else if (vtype == GRETL_TYPE_BUNDLE) {
18969             p->lh.t = BUNDLE;
18970         } else if (vtype == GRETL_TYPE_ARRAY) {
18971             p->lh.gtype = gretl_array_get_type(uvar->ptr);
18972             p->lh.t = ARRAY;
18973         }
18974     }
18975 
18976     return err;
18977 }
18978 
18979 /* pre-process a "genr" statement */
18980 
gen_preprocess(parser * p,int flags,int * done)18981 static void gen_preprocess (parser *p, int flags, int *done)
18982 {
18983     const char *s = p->input;
18984     char opstr[3] = {0};
18985     int newvar = 1;
18986 
18987     while (isspace(*s)) s++;
18988 
18989     /* skip leading command word, if any */
18990     if (!strncmp(s, "genr ", 5)) {
18991         s += 5;
18992     } else if (!strncmp(s, "print ", 6)) {
18993         /* allow this within (e.g.) mle block */
18994         p->flags |= P_DISCARD;
18995         s += 6;
18996     }
18997 
18998     while (isspace(*s)) s++;
18999 
19000     if (p->targ == UNK) {
19001         check_for_inline_typespec(&s, p);
19002     } else if (gretl_array_type(p->targ)) {
19003         /* record a plural type spec such as "matrices" under
19004            the "lh" member of @p.
19005         */
19006         p->lh.gtype = p->targ;
19007         p->targ = ARRAY;
19008     }
19009 
19010     /* check for types that cannot be generated in the
19011        absence of a dataset */
19012     if ((p->targ == SERIES || p->targ == LIST) &&
19013         (p->dset == NULL || p->dset_n == 0)) {
19014         no_data_error(p);
19015         return;
19016     }
19017 
19018     if (p->flags & P_DISCARD) {
19019         /* doing a simple "eval" */
19020         p->point = s;
19021         return;
19022     }
19023 
19024     /* extract LHS expression and operator, and test for a declaration */
19025     p->err = extract_lhs_and_op(&s, p, opstr);
19026     if (p->err || (p->flags & (P_DECL | P_DISCARD))) {
19027         return;
19028     }
19029 
19030     /* record next read position */
19031     p->point = s;
19032 
19033     if (p->lh.expr != NULL) {
19034         /* create syntax tree for the LHS expression */
19035         const char *savepoint = p->point;
19036 
19037         p->point = p->lh.expr;
19038         p->ch = parser_getc(p);
19039         lex(p);
19040         p->lhtree = expr(p);
19041         p->point = savepoint;
19042         p->ch = 0;
19043         if (!p->err) {
19044             p->err = compound_const_check(p->lhtree, p);
19045         }
19046         if (p->err) {
19047             return;
19048         } else {
19049             goto get_rhs;
19050         }
19051     }
19052 
19053     /* find out if the LHS var already exists, and if
19054        so, what type it is */
19055     if (!p->err) {
19056         p->err = check_existing_lhs_type(p, &newvar);
19057     }
19058 
19059 #if LHDEBUG
19060     fprintf(stderr, "newvar=%d, err=%d\n", newvar, p->err);
19061 #endif
19062 
19063     if (p->err) {
19064         return;
19065     }
19066 
19067     if (newvar) {
19068         /* new variable: check name for legality */
19069         if (!(flags & P_PRIV)) {
19070             p->err = check_identifier(p->lh.name);
19071         }
19072     } else {
19073         /* pre-existing var: check for const-ness */
19074         p->err = overwrite_const_check(p->lh.name, p->lh.vnum);
19075     }
19076 
19077     if (p->err) {
19078         return;
19079     }
19080 
19081     if (p->lh.t != 0) {
19082         if (p->targ == UNK) {
19083             /* when a result type is not specified, set this
19084                from existing LHS variable, if present
19085             */
19086             p->targ = p->lh.t;
19087         } else if (overwrite_type_check(p)) {
19088             /* don't overwrite one type with another */
19089             p->err = E_TYPES;
19090             return;
19091         }
19092     }
19093 
19094  get_rhs:
19095 
19096     /* advance past white space */
19097     while (isspace(*s)) s++;
19098     p->point = p->rhs = s;
19099 
19100     if (p->lh.expr != NULL) {
19101         goto alt_set_targ;
19102     }
19103 
19104     /* expression ends here with no operator: a call to print? */
19105     if (*s == '\0' && p->op == 0) {
19106         parser_try_print(p, p->lh.name, done);
19107         return;
19108     }
19109 
19110     /* if the LHS variable does not already exist, then
19111        we can't do '+=' or anything of that sort, only
19112        simple assignment, B_ASN
19113     */
19114     if (newvar && p->op != B_ASN) {
19115         undefined_symbol_error(p->lh.name, p);
19116         return;
19117     }
19118 
19119     if (p->op) {
19120         p->err = check_operator_validity(p, opstr);
19121         if (p->err) {
19122             return;
19123         }
19124     }
19125 
19126  alt_set_targ:
19127 
19128     if (p->targ == UNK && *p->rhs == '{') {
19129         /* if the target type is still unknown and the RHS
19130            expression is wrapped in '{' and '}', make the target
19131            a matrix
19132         */
19133         p->targ = MAT;
19134     } else if (p->targ == LIST) {
19135         /* flag presence of list target to parser */
19136         p->flags |= P_LISTDEF;
19137     }
19138 }
19139 
19140 /* tests for saving variable */
19141 
matrix_may_be_masked(const gretl_matrix * m,int n,parser * p)19142 static int matrix_may_be_masked (const gretl_matrix *m, int n,
19143                                  parser *p)
19144 {
19145     int mt1 = gretl_matrix_get_t1(m);
19146     int mt2 = gretl_matrix_get_t2(m);
19147     int fullrows = mt2 - mt1 + 1;
19148     int nobs = get_matrix_mask_nobs();
19149 
19150     if (n == nobs && fullrows > n) {
19151         p->flags |= P_MMASK;
19152         return 1;
19153     } else {
19154         return 0;
19155     }
19156 }
19157 
19158 /* check whether a matrix result can be assigned to a series
19159    on return */
19160 
series_compatible(const gretl_matrix * m,parser * p)19161 static int series_compatible (const gretl_matrix *m, parser *p)
19162 {
19163     int n = gretl_vector_get_length(m);
19164     int mt2 = gretl_matrix_get_t2(m);
19165     int T = sample_size(p->dset);
19166     int ok = 0;
19167 
19168     if (mt2 > 0) {
19169         int mt1 = gretl_matrix_get_t1(m);
19170 
19171         if (n == mt2 - mt1 + 1) {
19172             /* sample is recorded on matrix */
19173             ok = 1;
19174         } else if (matrix_may_be_masked(m, n, p)) {
19175             ok = 1;
19176         }
19177     } else if (n == T) {
19178         /* length matches current sample */
19179         ok = 1;
19180     } else if (n == p->dset->n) {
19181         /* length matches full series length */
19182         ok = 1;
19183     } else if (n == 1) {
19184         /* scalar: can be expanded */
19185         ok = 1;
19186     }
19187 
19188     return ok;
19189 }
19190 
19191 /* This function converts a series to a column vector,
19192    respecting the value of the set-variable "skip_missing".
19193    In that respect it differs from tmp_matrix_from_series(),
19194    which always just grabs the entire sample range.
19195 */
19196 
series_to_matrix(const double * x,parser * p)19197 static gretl_matrix *series_to_matrix (const double *x,
19198                                        parser *p)
19199 {
19200     int t, n = sample_size(p->dset);
19201     int t1 = p->dset->t1;
19202     int t2 = p->dset->t2;
19203     int skip_na, contiguous = 1;
19204     gretl_matrix *v;
19205 
19206     skip_na = libset_get_bool(SKIP_MISSING);
19207 
19208     if (skip_na) {
19209         int err = series_adjust_sample(x, &t1, &t2);
19210 
19211         if (!err) {
19212             /* no interior NAs, just use (possibly) revised sample */
19213             n = t2 - t1 + 1;
19214         } else {
19215             /* we have to count the non-missing values */
19216             n = 0;
19217             for (t=t1; t<=t2; t++) {
19218                 if (!na(x[t])) n++;
19219             }
19220             /* the values we want are not contiguous */
19221             contiguous = 0;
19222         }
19223     }
19224 
19225     if (n == 0) {
19226         v = gretl_null_matrix_new();
19227     } else {
19228         v = gretl_column_vector_alloc(n);
19229     }
19230 
19231     if (v == NULL) {
19232         p->err = E_ALLOC;
19233     } else if (n > 0) {
19234         if (contiguous) {
19235             memcpy(v->val, x + t1, n * sizeof *x);
19236         } else {
19237             int i = 0;
19238 
19239             for (t=t1; t<=t2; t++) {
19240                 if (na(x[t])) {
19241                     if (!skip_na) {
19242                         v->val[i++] = x[t];
19243                     }
19244                 } else {
19245                     v->val[i++] = x[t];
19246                 }
19247             }
19248         }
19249         if (contiguous) {
19250             gretl_matrix_set_t1(v, t1);
19251             gretl_matrix_set_t2(v, t2);
19252         }
19253     }
19254 
19255     return v;
19256 }
19257 
retrieve_matrix_result(parser * p)19258 static gretl_matrix *retrieve_matrix_result (parser *p)
19259 {
19260     NODE *r = p->ret;
19261     gretl_matrix *m = NULL;
19262 
19263 #if EDEBUG
19264     fprintf(stderr, "retrieve_matrix_result: r->t = %d\n", r->t);
19265 #endif
19266 
19267     if (r->t == NUM) {
19268         m = gretl_matrix_from_scalar(r->v.xval);
19269         if (m == NULL) {
19270             p->err = E_ALLOC;
19271         } else if (na(r->v.xval)) {
19272             set_gretl_warning(W_GENNAN);
19273         }
19274     } else if (r->t == SERIES) {
19275         m = series_to_matrix(r->v.xvec, p);
19276     } else if (r->t == LIST) {
19277         m = gretl_list_to_vector(r->v.ivec, &p->err);
19278     } else if (r->t == MAT && is_tmp_node(r)) {
19279         /* result matrix is newly allocated, steal it */
19280 #if EDEBUG
19281         fprintf(stderr, "matrix result (%p) is tmp, stealing it\n",
19282                 (void *) r->v.m);
19283 #endif
19284         m = r->v.m;
19285         r->v.m = NULL; /* avoid double-freeing */
19286     } else if (r->t == MAT) {
19287         /* r->v.m is an existing user matrix (or bundled matrix):
19288            must make a copy to keep pointers distinct
19289         */
19290         m = gretl_matrix_copy(r->v.m);
19291 #if EDEBUG
19292         fprintf(stderr, "matrix result (%p) is pre-existing, copied to %p\n",
19293                 (void *) r->v.m, (void *) m);
19294 #endif
19295         if (m == NULL) {
19296             p->err = E_ALLOC;
19297         }
19298     } else {
19299         fprintf(stderr, "Looking for matrix, but r->t = %s\n", getsymb(r->t));
19300         p->err = E_TYPES;
19301     }
19302 
19303     return m;
19304 }
19305 
19306 /* Check to see if the existing LHS matrix is of the
19307    same dimensions as the RHS result */
19308 
LHS_matrix_reusable(parser * p,gretl_matrix ** pm,gretl_matrix * tmp)19309 static int LHS_matrix_reusable (parser *p, gretl_matrix **pm,
19310                                 gretl_matrix *tmp)
19311 {
19312     gretl_matrix *m = gen_get_lhs_var(p, GRETL_TYPE_MATRIX);
19313     int ok = 0;
19314 
19315     if (m == NULL) {
19316         return 0;
19317     } else if (p->ret->t == NUM) {
19318         ok = (m->rows == 1 && m->cols == 1);
19319     } else if (p->ret->t == SERIES) {
19320         ok = (m->rows == tmp->rows && m->cols == 1);
19321     } else if (p->ret->t == MAT) {
19322         gretl_matrix *retm = p->ret->v.m;
19323 
19324         ok = (retm != NULL &&
19325               m->rows == retm->rows &&
19326               m->cols == retm->cols &&
19327               m->is_complex == retm->is_complex);
19328     }
19329 
19330     *pm = m;
19331 
19332     return ok;
19333 }
19334 
19335 /* Generating a matrix, and there's a pre-existing LHS matrix:
19336    we re-use the left-hand side matrix if possible.
19337 */
19338 
assign_to_matrix(parser * p)19339 static gretl_matrix *assign_to_matrix (parser *p)
19340 {
19341     gretl_matrix *m = NULL;
19342     gretl_matrix *tmp = NULL;
19343     int free_tmp = 1;
19344     double x;
19345 
19346     if (p->ret->t == SERIES) {
19347         /* a legacy thing */
19348         tmp = series_to_matrix(p->ret->v.xvec, p);
19349         if (p->err) {
19350             return NULL;
19351         }
19352     }
19353 
19354     if (LHS_matrix_reusable(p, &m, tmp)) {
19355         /* The result is of the same dimensions as the LHS matrix:
19356            this means that we don't need to construct an RHS
19357            matrix if it doesn't already exist as such, nor do we
19358            need to copy it if it does already exist.
19359         */
19360 #if EDEBUG
19361         fprintf(stderr, "assign_to_matrix: reusing LHS\n");
19362 #endif
19363         if (p->ret->t == NUM) {
19364             /* using RHS scalar */
19365             m->val[0] = x = p->ret->v.xval;
19366         } else if (p->ret->t == SERIES) {
19367             /* using RHS series, converted to @tmp */
19368             p->err = gretl_matrix_copy_data(m, tmp);
19369         } else {
19370             /* using RHS matrix: just copy data across */
19371             p->err = gretl_matrix_copy_data(m, p->ret->v.m);
19372         }
19373     } else {
19374         /* Dimensions differ: replace the LHS matrix */
19375 #if EDEBUG
19376         fprintf(stderr, "assign_to_matrix: replacing\n");
19377 #endif
19378         if (tmp != NULL) {
19379             p->err = gen_replace_lhs(p, GRETL_TYPE_MATRIX, tmp);
19380             free_tmp = 0; /* @tmp is the return value */
19381         } else {
19382             m = retrieve_matrix_result(p);
19383             if (!p->err) {
19384                 p->err = gen_replace_lhs(p, GRETL_TYPE_MATRIX, m);
19385             }
19386         }
19387     }
19388 
19389     if (tmp != NULL && free_tmp) {
19390         gretl_matrix_free(tmp);
19391     }
19392 
19393     return m;
19394 }
19395 
19396 /* Assigning to an existing (whole) LHS matrix, but using '+='
19397    or some such modified/inflected assignment. Note that
19398    save_generated_var() is the only caller.
19399 */
19400 
assign_to_matrix_mod(gretl_matrix * m1,parser * p)19401 static gretl_matrix *assign_to_matrix_mod (gretl_matrix *m1,
19402                                            parser *p)
19403 {
19404     gretl_matrix *m2 = NULL;
19405     int mcat;
19406 
19407     if (m1 == NULL) {
19408         p->err = E_DATA;
19409     }
19410 
19411     /* In most cases we can take a shortcut when the RHS
19412        value is scalar, but we can't do that when the
19413        inflection is one of the matrix concatenation
19414        operators: here we record that fact.
19415     */
19416     mcat = (p->op == B_HCAT || p->op == B_VCAT);
19417 
19418     if (!p->err) {
19419         if (p->op == B_DOTASN) {
19420             p->err = dot_assign_to_matrix(m1, p);
19421             m2 = m1; /* no change in matrix pointer */
19422         } else if (!mcat && scalar_node(p->ret)) {
19423             double x = node_get_scalar(p->ret, p);
19424 
19425             if (m1->is_complex) {
19426                 cmatrix_xy_calc(m1, m1, x, 0, p->op, p);
19427             } else {
19428                 rmatrix_xy_calc(m1, m1, x, 0, p->op, p);
19429             }
19430             m2 = m1; /* no change in matrix pointer */
19431         } else if (!mcat && cscalar_node(p->ret)) {
19432             if (m1->is_complex) {
19433                 double complex z = p->ret->v.m->z[0];
19434 
19435                 cmatrix_xy_calc(m1, m1, z, 0, p->op, p);
19436                 m2 = m1; /* no change in matrix pointer */
19437             } else {
19438                 p->err = E_TYPES;
19439             }
19440         } else {
19441             gretl_matrix *tmp = retrieve_matrix_result(p);
19442 
19443             if (tmp != NULL) {
19444                 p->err = real_matrix_calc(m1, tmp, p->op, &m2);
19445                 gretl_matrix_free(tmp);
19446             }
19447         }
19448     }
19449 
19450     return m2;
19451 }
19452 
do_array_append(parser * p)19453 static void do_array_append (parser *p)
19454 {
19455     gretl_array *A = NULL;
19456     GretlType atype;
19457     NODE *rhs = p->ret;
19458     void *ptr = NULL;
19459 
19460     A = gen_get_lhs_var(p, GRETL_TYPE_ARRAY);
19461     if (A == NULL) {
19462         p->err = E_DATA;
19463         return;
19464     }
19465 
19466     atype = gretl_array_get_content_type(A);
19467 
19468     if (atype == GRETL_TYPE_STRING && rhs->t == STR) {
19469         ptr = rhs->v.str;
19470     } else if (atype == GRETL_TYPE_MATRIX && rhs->t == MAT) {
19471         ptr = rhs->v.m;
19472     } else if (atype == GRETL_TYPE_BUNDLE && rhs->t == BUNDLE) {
19473         ptr = rhs->v.b;
19474     } else if (atype == GRETL_TYPE_LIST && rhs->t == LIST) {
19475         ptr = rhs->v.ivec;
19476     } else if (atype == GRETL_TYPE_ARRAY && rhs->t == ARRAY) {
19477         ptr = rhs->v.a;
19478     } else if (rhs->t == ARRAY) {
19479         /* special: not actually appending an _element_;
19480            stick rhs array onto end of lhs array
19481         */
19482         p->err = gretl_array_copy_into(A, rhs->v.a);
19483     } else {
19484         p->err = E_TYPES;
19485     }
19486 
19487     if (!p->err && ptr != NULL) {
19488         int copy = !is_tmp_node(rhs);
19489 
19490         p->err = gretl_array_append_object(A, ptr, copy);
19491         if (!copy && !p->err) {
19492             rhs->v.ptr = NULL;
19493         }
19494     }
19495 }
19496 
do_array_subtract(parser * p)19497 static void do_array_subtract (parser *p)
19498 {
19499     gretl_array *A;
19500     NODE *rhs = p->ret;
19501 
19502     A = gen_get_lhs_var(p, GRETL_TYPE_ARRAY);
19503     if (A == NULL) {
19504         p->err = E_DATA;
19505     } else if (gretl_array_get_type(A) == GRETL_TYPE_STRINGS && rhs->t == STR) {
19506 	p->err = gretl_array_drop_string(A, rhs->v.str);
19507     } else {
19508         p->err = E_TYPES;
19509     }
19510 }
19511 
do_bundle_append(parser * p)19512 static void do_bundle_append (parser *p)
19513 {
19514     gretl_bundle *bl = NULL;
19515     gretl_bundle *br = NULL;
19516     NODE *rhs = p->ret;
19517 
19518     bl = gen_get_lhs_var(p, GRETL_TYPE_BUNDLE);
19519     if (rhs->t == BUNDLE) {
19520         br = rhs->v.b;
19521     }
19522     if (bl == NULL || br == NULL) {
19523         p->err = E_TYPES;
19524     } else {
19525         p->err = gretl_bundle_append(bl, br);
19526     }
19527 }
19528 
create_or_edit_string(parser * p)19529 static int create_or_edit_string (parser *p)
19530 {
19531     const char *src = NULL;
19532     const char *orig = NULL;
19533     char *newstr = NULL;
19534     user_var *uvar;
19535 
19536     if (p->ret->t == NUM) {
19537         /* OK only in case of "+=" */
19538         if (p->op != B_ADD) {
19539             p->err = E_TYPES;
19540             return p->err;
19541         }
19542     } else if (null_node(p->ret) || p->ret->v.str == NULL) {
19543         src = "";
19544     } else {
19545         src = p->ret->v.str;
19546     }
19547 
19548 #if EDEBUG
19549     fprintf(stderr, "edit_string: src='%s'\n", src);
19550 #endif
19551 
19552     uvar = p->lh.uv;
19553 
19554     if (uvar != NULL) {
19555         orig = uvar->ptr;
19556     } else if (p->op != B_ASN) {
19557         /* without an existing LHS string we can only assign */
19558         p->err = E_DATA;
19559         return p->err;
19560     }
19561 
19562     if (p->ret->t == NUM) {
19563         /* taking an offset into an existing string */
19564         int len = g_utf8_strlen(orig, -1);
19565         int adj = p->ret->v.xval;
19566 
19567         if (adj < 0) {
19568             p->err = E_DATA;
19569         } else if (adj == 0) {
19570             ; /* no-op */
19571         } else {
19572             if (adj < len) {
19573                 src = g_utf8_offset_to_pointer(orig, adj);
19574             } else {
19575                 src = "";
19576             }
19577             newstr = gretl_strdup(src);
19578             if (newstr == NULL) {
19579                 p->err = E_ALLOC;
19580             } else {
19581                 gen_replace_lhs(p, GRETL_TYPE_STRING, newstr);
19582             }
19583         }
19584     } else if (src == NULL) {
19585         ; /* no-op -- e.g. argname() didn't get anything */
19586     } else if (p->op == B_ASN) {
19587         /* simple assignment */
19588         newstr = gretl_strdup(src);
19589         if (newstr == NULL) {
19590             p->err = E_ALLOC;
19591         } else if (uvar == NULL) {
19592             gen_add_uvar(p, GRETL_TYPE_STRING, newstr);
19593         } else {
19594             gen_replace_lhs(p, GRETL_TYPE_STRING, newstr);
19595         }
19596     } else if (p->op == B_HCAT || p->op == B_ADD) {
19597         /* string concatenation */
19598         if (*src == '\0') {
19599             ; /* no-op */
19600         } else {
19601             newstr = malloc(strlen(orig) + strlen(src) + 1);
19602             if (newstr == NULL) {
19603                 p->err = E_ALLOC;
19604             } else {
19605                 strcpy(newstr, orig);
19606                 strcat(newstr, src);
19607                 gen_replace_lhs(p, GRETL_TYPE_STRING, newstr);
19608             }
19609         }
19610     }
19611 
19612     return p->err;
19613 }
19614 
create_or_edit_list(parser * p)19615 static int create_or_edit_list (parser *p)
19616 {
19617     int *list = NULL;
19618 
19619     if (p->ret->t == MAT && gretl_vector_get_length(p->ret->v.m) == 0) {
19620         /* special case, list from matrix */
19621         const char *prefix;
19622 
19623         prefix = p->ret->vname != NULL ? p->ret->vname : p->lh.name;
19624         list = gretl_list_from_matrix(p->ret->v.m, prefix,
19625                                       p->dset, &p->err);
19626     } else {
19627         list = node_get_list(p->ret, p); /* note: copied */
19628     }
19629 
19630 #if EDEBUG
19631     printlist(list, "RHS list in edit_list()");
19632 #endif
19633 
19634 #if 0 /* we're not applying the following check (yet?) */
19635     if (gretl_function_depth() > 0) {
19636         int i, vi;
19637 
19638         for (i=1; i<=list[0]; i++) {
19639             vi = list[i];
19640             if (vi < 0 || vi >= p->dset->v) {
19641                 /* this error will be caught below */
19642                 break;
19643             }
19644             if (!series_is_accessible_in_function(vi, p->dset)) {
19645                 p->err = E_DATA;
19646                 break;
19647             }
19648         }
19649     }
19650 #endif
19651 
19652     if (!p->err) {
19653         if (p->lh.t != LIST) {
19654             /* no pre-existing LHS list: must be simple assignment */
19655             p->err = remember_list(list, p->lh.name, NULL);
19656         } else if (p->op == B_ASN || p->op == B_ADD || p->op == B_SUB) {
19657             /* replace, append or subtract list members */
19658             p->err = gen_edit_list(p, list, p->op);
19659         } else {
19660             p->err = E_TYPES;
19661         }
19662     }
19663 
19664 #if 0
19665     if (!p->err) {
19666         /* 2020-05-29: is this right, for list? */
19667         set_dataset_is_changed(p->dset, 1);
19668     }
19669 #endif
19670 
19671     free(list);
19672 
19673     return p->err;
19674 }
19675 
19676 #define ok_return_type(t) (t == NUM || t == SERIES || t == MAT ||       \
19677                            t == LIST || t == DUM || t == EMPTY ||       \
19678                            t == STR || t == BUNDLE || t == ARRAY ||     \
19679                            t == U_ADDR || t == DBUNDLE)
19680 
19681 /* Note: we're doing this only in relation to "primary" types
19682    (excluding bundle members, array elements, matrix sub-
19683    specs).
19684 */
19685 
gen_check_return_type(parser * p)19686 static int gen_check_return_type (parser *p)
19687 {
19688     NODE *r = p->ret;
19689     int err = 0;
19690 
19691     if (r == NULL) {
19692         fprintf(stderr, "gen_check_return_type: p->ret = NULL!\n");
19693         return E_DATA;
19694     }
19695 
19696 #if EDEBUG
19697     fprintf(stderr, "gen_check_return_type: targ=%s; ret at %p, type %s\n",
19698             getsymb(p->targ), (void *) r, getsymb(r->t));
19699 #endif
19700 
19701     if (!ok_return_type(r->t)) {
19702         return E_TYPES;
19703     }
19704 
19705     if (r->t == SERIES && r->v.xvec == NULL) {
19706         fprintf(stderr, "got SERIES return with xvec = NULL!\n");
19707         return E_DATA;
19708     }
19709 
19710     if (p->targ == NUM) {
19711         if (r->t == NUM || scalar_matrix_node(r)) {
19712             ; /* scalar or 1 x 1 matrix: OK */
19713         } else if (r->t == MAT && (p->flags & P_NODECL)) {
19714             ; /* morphing to matrix may be OK */
19715         } else {
19716             err = E_TYPES;
19717         }
19718     } else if (p->targ == SERIES) {
19719         /* result must be scalar, series, or conformable matrix */
19720         if (r->t == NUM || r->t == SERIES) {
19721             ; /* OK */
19722         } else if (r->t == MAT) {
19723             if (!series_compatible(r->v.m, p)) {
19724                 err = E_TYPES;
19725             }
19726         } else {
19727             err = E_TYPES;
19728         }
19729     } else if (p->targ == MAT) {
19730         ; /* no-op: handled later */
19731     } else if (p->targ == LIST) {
19732         if (r->t != EMPTY && r->t != MAT && !ok_list_node(r, p)) {
19733             err = E_TYPES;
19734         }
19735     } else if (p->targ == STR) {
19736         if (r->t != EMPTY && r->t != STR && r->t != NUM) {
19737             err = E_TYPES;
19738         }
19739     } else if (p->targ == BUNDLE) {
19740         if (p->op == B_ASN) {
19741             /* plain assignment: bundle or null */
19742             if (r->t != BUNDLE && r->t != DBUNDLE && r->t != EMPTY) {
19743                 err = E_TYPES;
19744             }
19745         } else {
19746             /* the only other assignment possibility is "+=",
19747                in which case we'll only accept a bundle
19748             */
19749             if (r->t != BUNDLE) {
19750                 err = E_TYPES;
19751             }
19752         }
19753     } else if (p->targ == ARRAY) {
19754         if (p->op == B_ASN) {
19755             /* plain assignment: array or null */
19756             if (!gen_type_is_arrayable(r->t) && r->t != EMPTY) {
19757                 err = E_TYPES;
19758             }
19759         } else {
19760             /* arrays: the only other assignment possibility is "+=",
19761                in which case we'll only accept an array or an
19762                object which matches the content type on the left
19763                (but the matching check is deferred)
19764             */
19765             if (!gen_type_is_arrayable(r->t)) {
19766                 err = E_TYPES;
19767             }
19768         }
19769     }
19770 
19771     if (err == E_TYPES) {
19772         assignment_type_errmsg(p->targ, r->t, p->op);
19773     }
19774 
19775 #if EDEBUG
19776     fprintf(stderr, "gen_check_return_type: returning with p->err = %d\n",
19777             err);
19778 #endif
19779 
19780     return err;
19781 }
19782 
19783 /* Allocate storage if saving a series to the dataset:
19784    lh.vnum <= 0 means that the LHS series does not already
19785    exist. If this is a new series we also check for
19786    collision with the name of a function and issue
19787    a warning if need be.
19788 */
19789 
gen_allocate_storage(parser * p)19790 static int gen_allocate_storage (parser *p)
19791 {
19792     if (p->lh.vnum <= 0) {
19793         if (p->dset == NULL || p->dset->Z == NULL) {
19794             p->err = E_DATA;
19795         } else {
19796             p->err = dataset_add_NA_series(p->dset, 1);
19797             if (!p->err) {
19798                 p->lh.vnum = p->dset->v - 1;
19799             }
19800         }
19801         if (!p->err && gretl_function_depth() == 0 &&
19802             get_user_function_by_name(p->lh.name) != NULL) {
19803             gretl_warnmsg_sprintf(_("'%s' shadows a function of the same name"),
19804                                   p->lh.name);
19805         } else if (!p->err && function_lookup(p->lh.name)) {
19806             gretl_warnmsg_sprintf(_("'%s' shadows a function of the same name"),
19807                                   p->lh.name);
19808         }
19809     }
19810 
19811     return p->err;
19812 }
19813 
align_matrix_to_series(double * y,const gretl_matrix * m,parser * p)19814 static void align_matrix_to_series (double *y, const gretl_matrix *m,
19815                                     parser *p)
19816 {
19817     const gretl_matrix *mask = get_matrix_mask();
19818     int t, s = 0;
19819 
19820     if (mask == NULL || mask->rows != p->dset->n) {
19821         p->err = E_DATA;
19822         return;
19823     }
19824 
19825     for (t=0; t<p->dset->n; t++) {
19826         if (mask->val[t] != 0.0) {
19827             if (t >= p->dset->t1 && t <= p->dset->t2) {
19828                 y[t] = xy_calc(y[t], m->val[s], p->op, SERIES, p);
19829             }
19830             s++;
19831         }
19832     }
19833 }
19834 
assign_null_to_bundle(parser * p)19835 static int assign_null_to_bundle (parser *p)
19836 {
19837     gretl_bundle *b;
19838     int err = 0;
19839 
19840     if (p->lh.t == BUNDLE) {
19841         b = gen_get_lhs_var(p, GRETL_TYPE_BUNDLE);
19842         gretl_bundle_void_content(b);
19843     } else {
19844         b = gretl_bundle_new();
19845         if (b == NULL) {
19846             err = E_ALLOC;
19847         } else {
19848             err = gen_add_uvar(p, GRETL_TYPE_BUNDLE, b);
19849         }
19850     }
19851 
19852     return err;
19853 }
19854 
assign_null_to_array(parser * p)19855 static int assign_null_to_array (parser *p)
19856 {
19857     gretl_array *a;
19858     int err = 0;
19859 
19860     if (p->lh.t == ARRAY) {
19861         a = gen_get_lhs_var(p, GRETL_TYPE_ARRAY);
19862         gretl_array_void_content(a);
19863     } else {
19864         a = gretl_array_new(p->lh.gtype, 0, &err);
19865         if (!err) {
19866             err = gen_add_uvar(p, p->lh.gtype, a);
19867         }
19868     }
19869 
19870     return err;
19871 }
19872 
19873 /* apply postfix '++' or '--' to LHS scalar, or '++' to
19874    LHS string (only) */
19875 
do_incr_decr(parser * p)19876 static int do_incr_decr (parser *p)
19877 {
19878     if (p->lh.uv != NULL && p->lh.uv->type == GRETL_TYPE_DOUBLE) {
19879         double x = uvar_get_scalar_value(p->lh.uv);
19880 
19881         if (!na(x)) {
19882             x += (p->op == INC)? 1 : -1;
19883             uvar_set_scalar_fast(p->lh.uv, x);
19884         }
19885     } else if (p->lh.uv != NULL && p->lh.uv->type == GRETL_TYPE_STRING) {
19886         if (p->op == DEC) {
19887             p->err = E_TYPES;
19888         } else {
19889             char *s = p->lh.uv->ptr;
19890 
19891             if (*s != '\0') {
19892                 char *smod = gretl_strdup(s + 1);
19893 
19894                 gen_replace_lhs(p, GRETL_TYPE_STRING, smod);
19895             }
19896         }
19897     } else {
19898         p->err = E_TYPES;
19899     }
19900 
19901     return p->err;
19902 }
19903 
19904 #define has_aux_mat(n) (n->aux != NULL && n->aux->t == MAT)
19905 
explore_node(NODE * t,int lev,NODE * prev,parser * p)19906 static int explore_node (NODE *t, int lev, NODE *prev,
19907 			 parser *p)
19908 {
19909     NODE pms = {0};
19910     int save_op;
19911     int err = 0;
19912 
19913 #if LHDEBUG
19914     fprintf(stderr, "%d: %s %p, prev %p", lev, getsymb(t->t), (void *) t,
19915 	    (void *) prev);
19916     fprintf(stderr, " (aux %s)", (t->aux != NULL)? getsymb(t->aux->t) : "null");
19917     if (t->R != NULL) {
19918 	fprintf(stderr, ", R %s", getsymb(t->R->t));
19919 	if (t->R->aux != NULL) {
19920 	    fprintf(stderr, " (aux %s)", getsymb(t->R->aux->t));
19921 	    if (t->R->aux->t == MSPEC) {
19922 		fputc('\n', stderr);
19923 		print_mspec(t->R->aux->v.mspec);
19924 	    }
19925 	}
19926     }
19927     if (t->t == MAT) {
19928 	fputc('\n', stderr);
19929 	gretl_matrix_print(t->v.m, "t->v.m");
19930     } else if (t->aux != NULL && t->aux->t == MAT) {
19931 	gretl_matrix_print(t->aux->v.m, "t->aux->v.m");
19932     } else {
19933 	fputc('\n', stderr);
19934     }
19935 #endif
19936     if (prev != NULL && (t->t == MAT || has_aux_mat(t))) {
19937 #if LHDEBUG
19938 	fprintf(stderr, "doing ASSIGN to %s\n\n",
19939 		t->t == MAT ? "MAT" : "aux MAT");
19940 #endif
19941 	pms.t = MSL;
19942 	/* pms.L: node holding target matrix */
19943 	pms.L = t->t == MAT ? t : t->aux;
19944 	/* pms.R: node holding mspec */
19945 	pms.R = prev->R->aux;
19946 	save_op = p->op;
19947 	p->op = B_ASN;
19948 	/* prev->aux holds the replacement matrix */
19949 	err = set_matrix_chunk(&pms, prev->aux, p);
19950 	p->op = save_op;
19951     }
19952 
19953     return err;
19954 }
19955 
traverse_left(parser * p)19956 static int traverse_left (parser *p)
19957 {
19958     NODE *t = p->lhtree;
19959     NODE *prev = NULL;
19960     int level = 0;
19961     int err = 0;
19962 
19963     while (t && !err) {
19964 	err = explore_node(t, level, prev, p);
19965 	if (t->aux != NULL && t->aux->t == MAT) {
19966 	    prev = t;
19967 	} else {
19968 	    prev = NULL;
19969 	}
19970 	t = t->L;
19971 	level++;
19972     }
19973 
19974     return err;
19975 }
19976 
19977 /* set_nested_matrix_value(): this and its helper above,
19978    traverse_left(), require a little comment.
19979 
19980    We come here when a hansl statement modifies a matrix that
19981    is "under" something else. That something could be a
19982    bundle or array, as in
19983 
19984    # Case 0
19985    b.m[diag] = x     # under bundle b
19986    a[3][1:2,1:2] = y # under array a
19987 
19988    In such cases the first invocation of set_matrix_chunk
19989    below is sufficient. However, we also come here when the
19990    matrix is "under" another matrix -- that is, we have a
19991    double index or subspec, as in these examples for a complex
19992    matrix, C:
19993 
19994    # Case 1
19995    C[real][1:2,1:2] = x
19996    C[3,3][real] = y
19997 
19998    and also in these more extended examples where the
19999    complex matrix is itself "under" something else:
20000 
20001    # Case 2
20002    b.C[real][1:2,1:2] = x
20003    a[3][i,j][imag] = y
20004 
20005    To handle such cases we have to crawl the parser's
20006    "lhtree" (left-hand side tree) to find the matrix that
20007    ultimately has to be modified, executing further calls
20008    to set_matrix_chunk(). In Case 1 above, the matrix
20009    we're looking for will be at depth 1 in the lhtree,
20010    while in Case 2 it will be at depth 2.
20011 */
20012 
set_nested_matrix_value(NODE * lhs,NODE * rhs,parser * p)20013 static int set_nested_matrix_value (NODE *lhs,
20014                                     NODE *rhs,
20015                                     parser *p)
20016 {
20017 #if LHDEBUG
20018     int err;
20019     gretl_matrix_print(lhs->L->v.m, "LVM, before set matrix chunk");
20020     err = set_matrix_chunk(lhs, rhs, p);
20021     gretl_matrix_print(lhs->L->v.m, "LVM, after set matrix chunk");
20022 #else
20023     int err = set_matrix_chunk(lhs, rhs, p);
20024 #endif
20025 
20026     if (!err) {
20027 	err = traverse_left(p);
20028     }
20029 
20030     return err;
20031 }
20032 
save_generated_var(parser * p,PRN * prn)20033 static int save_generated_var (parser *p, PRN *prn)
20034 {
20035     NODE *r = p->ret;
20036     double **Z = NULL;
20037     double x;
20038     int no_decl = 0;
20039     int t, v = 0;
20040 
20041 #if EDEBUG
20042     fprintf(stderr, "save (%s): lhname='%s'\n  callcount=%d\n"
20043             "lh.t=%s, targ=%s, no_decl=%d, r->t=%s\n",
20044             p->lhtree != NULL ? "compound" : "unitary",
20045             p->lh.name, p->callcount, getsymb(p->lh.t),
20046             getsymb(p->targ), (p->flags & P_NODECL)? 1 : 0,
20047             (r == NULL)? "none" : getsymb(r->t));
20048 #endif
20049 
20050     if (p->flags & P_STRVEC) {
20051         /* special case: calculation with string-valued series,
20052 	   return value handled upstream
20053 	*/
20054 	set_dataset_is_changed(p->dset, 1);
20055 	return 0;
20056     } else if (p->lh.t == SERIES && is_string_valued(p->dset, p->lh.vnum) &&
20057 	       p->lhtree == NULL) {
20058 	gretl_errmsg_set("Cannot overwrite entire string-valued series");
20059 	p->err = E_TYPES;
20060 	return p->err;
20061     }
20062 
20063     if (p->lhtree != NULL) {
20064 	/* handle compound target first */
20065 	int compound_t;
20066 
20067 	p->lhtree->flags |= LHT_NODE;
20068 	p->flags |= P_START;
20069 #if LHDEBUG
20070 	fprintf(stderr, "\n*** lhtree before eval ***\n");
20071 	print_tree(p->lhtree, p, 0, 0);
20072 #endif
20073 	p->lhres = eval(p->lhtree, p);
20074 #if LHDEBUG
20075 	if (p->lhres != NULL) {
20076 	    fprintf(stderr, "\n*** lhres post-eval ***\n");
20077 	    print_tree(p->lhres, p, 0, 0);
20078 	    fprintf(stderr, "\n*** lhtree post-eval ***\n");
20079 	    print_tree(p->lhtree, p, 0, 0);
20080 	    fputc('\n', stderr);
20081 	}
20082 #endif
20083 	if (p->err) {
20084 	    return p->err;
20085 	}
20086 	compound_t = p->lhres->t;
20087 #if LHDEBUG
20088 	fprintf(stderr, "save_generated_var: type = %s\n",
20089 		getsymb(compound_t));
20090 #endif
20091 	if (compound_t == BMEMB) {
20092 	    p->err = set_bundle_value(p->lhres, r, p);
20093 	} else if (compound_t == MSL) {
20094 	    p->err = set_matrix_chunk(p->lhres, r, p);
20095 	} else if (compound_t == OBS) {
20096 	    p->err = set_series_obs_value(p->lhres, r, p);
20097 	} else if (compound_t == OSL) {
20098 	    NODE *lh1 = p->lhres->L;
20099 
20100 #if LHDEBUG
20101 	    fprintf(stderr, "OSL save: lh1 type = %s\n", getsymb(lh1->t));
20102 #endif
20103 	    if (lh1->t == ARRAY) {
20104 		p->err = set_array_value(p->lhres, r, p);
20105 	    } else if (lh1->t == LIST) {
20106 		p->err = set_list_value(p->lhres, r, p);
20107 	    } else if (lh1->t == STR) {
20108 		p->err = set_string_value(p->lhres, r, p);
20109 	    } else if (lh1->t == BUNDLE) {
20110 		p->err = set_bundle_value(p->lhres, r, p);
20111 	    } else if (lh1->t == SERIES) {
20112 		p->err = set_series_obs_value(p->lhres, r, p);
20113 	    } else if (lh1->t == MAT) {
20114 		p->err = set_nested_matrix_value(p->lhres, r, p);
20115 	    } else {
20116 		gretl_errmsg_set(_("Invalid left-hand side expression"));
20117 		p->err = E_TYPES;
20118 	    }
20119 	} else {
20120 	    gretl_errmsg_set(_("Invalid left-hand side expression"));
20121 	    p->err = E_TYPES;
20122 	}
20123 	return p->err; /* done */
20124     } /* end of compound target business */
20125 
20126     if (p->op == INC || p->op == DEC) {
20127 	return do_incr_decr(p);
20128     }
20129 
20130     if (p->callcount < 2) {
20131 	/* first exec: test for type mismatch errors */
20132 	p->err = gen_check_return_type(p);
20133 	if (p->err) {
20134 	    return p->err;
20135 	}
20136     }
20137 
20138 #if ONE_BY_ONE_CAST
20139     if (p->targ == UNK) {
20140 	if (scalar_matrix_node(r)) {
20141 	    /* "cast" 1 x 1 matrix to scalar */
20142 	    no_decl = 1;
20143 	    p->targ = NUM;
20144 	    p->flags |= P_NODECL;
20145 	} else {
20146 	    p->targ = r->t;
20147 	}
20148     } else if (p->targ == NUM && r->t == MAT && (p->flags & P_NODECL)) {
20149 	/* We're looking at a @targ that was previously
20150 	   set to NUM by the "auto-cast" mechanism: allow
20151 	   it to morph to matrix if need be.
20152 	*/
20153 	if (scalar_matrix_node(r)) {
20154 	    ; /* not a problem */
20155 	} else if (p->lh.t == 0) {
20156 	    /* no pre-existing scalar var */
20157 	    p->targ = MAT;
20158 	} else if (p->lh.t == NUM) {
20159 	    /* type-convert existing scalar */
20160 	    p->err = gretl_scalar_convert_to_matrix(p->lh.uv);
20161 	    if (!p->err) {
20162 		p->targ = MAT;
20163 	    }
20164 	}
20165     }
20166 #else
20167     if (p->targ == UNK) {
20168 	p->targ = r->t;
20169     }
20170 #endif
20171 
20172 #if EDEBUG
20173     fprintf(stderr, "after preliminaries: targ=%s, op='%s'\n",
20174 	    getsymb(p->targ), getsymb(p->op));
20175 #endif
20176 
20177     if (p->targ == SERIES && (unsigned char) p->lh.name[0] > 126) {
20178 	/* can't allow Greek letters for series names */
20179 	gretl_errmsg_sprintf("Invalid series name '%s'", p->lh.name);
20180 	p->err = E_DATA;
20181 	return p->err;
20182     }
20183 
20184     /* allocate dataset storage, if needed */
20185     if (p->targ == SERIES) {
20186 	gen_allocate_storage(p);
20187 	if (p->err) {
20188 	    return p->err;
20189 	}
20190     }
20191 
20192     if (p->dset != NULL && p->dset->Z != NULL) {
20193 	/* convenience notation */
20194 	Z = p->dset->Z;
20195 	v = p->lh.vnum;
20196     }
20197 
20198     /* put the generated data into place */
20199 
20200     if (p->targ == NUM) {
20201 	if (p->lh.t == NUM) {
20202 	    /* modifying an existing scalar */
20203 	    if (r->t == NUM) {
20204 		x = r->v.xval;
20205 	    } else if (scalar_matrix_node(r)) {
20206 		x = r->v.m->val[0];
20207 	    } else {
20208 		p->err = E_TYPES;
20209 	    }
20210 	    if (!p->err && p->op != B_ASN) {
20211 		double x0 = uvar_get_scalar_value(p->lh.uv);
20212 
20213 		x = xy_calc(x0, x, p->op, NUM, p);
20214 	    }
20215 	    if (!p->err) {
20216 		p->err = gen_replace_scalar(p, x);
20217 	    }
20218 	} else {
20219 	    /* a new scalar */
20220 	    if (r->t == NUM) {
20221 		x = r->v.xval;
20222 	    } else if (scalar_matrix_node(r)) {
20223 		x = r->v.m->val[0];
20224 	    } else {
20225 		p->err = E_TYPES;
20226 	    }
20227 	    if (!p->err) {
20228 		if (no_decl) {
20229 		    p->err = gretl_scalar_add_mutable(p->lh.name, x);
20230 		} else {
20231 		    p->err = gretl_scalar_add(p->lh.name, x);
20232 		}
20233 	    }
20234 	}
20235     } else if (p->targ == SERIES) {
20236 	/* writing a series */
20237 	if (r->t == SERIES) {
20238 	    const double *x = r->v.xvec;
20239 
20240 	    if (p->op == B_ASN) {
20241 		/* avoid multiple calls to xy_calc */
20242 		if (Z[v] != x) {
20243 		    size_t sz = sample_size(p->dset) * sizeof *x;
20244 
20245 		    memcpy(Z[v] + p->dset->t1, x + p->dset->t1, sz);
20246 		}
20247 	    } else {
20248 		for (t=p->dset->t1; t<=p->dset->t2; t++) {
20249 		    Z[v][t] = xy_calc(Z[v][t], x[t], p->op, SERIES, p);
20250 		}
20251 	    }
20252 	} else if (r->t == NUM) {
20253 	    for (t=p->dset->t1; t<=p->dset->t2; t++) {
20254 		Z[v][t] = xy_calc(Z[v][t], r->v.xval, p->op, SERIES, p);
20255 	    }
20256 	} else if (r->t == MAT) {
20257 	    const gretl_matrix *m = r->v.m;
20258 	    int k = gretl_vector_get_length(m);
20259 	    int mt1 = gretl_matrix_get_t1(m);
20260 	    int s;
20261 
20262 	    if (p->flags & P_MMASK) {
20263 		/* result needs special alignment */
20264 		align_matrix_to_series(Z[v], m, p);
20265 	    } else if (k == 1) {
20266 		/* result is effectively a scalar */
20267 		for (t=p->dset->t1; t<=p->dset->t2; t++) {
20268 		    Z[v][t] = xy_calc(Z[v][t], m->val[0], p->op, SERIES, p);
20269 		}
20270 	    } else if (k == p->dset->n) {
20271 		/* treat result as full-length series */
20272 		for (t=p->dset->t1; t<=p->dset->t2; t++) {
20273 		    Z[v][t] = xy_calc(Z[v][t], m->val[t], p->op, SERIES, p);
20274 		}
20275 	    } else if (k == sample_size(p->dset)) {
20276 		/* treat as series of current sample length */
20277 		for (t=p->dset->t1, s=0; t<=p->dset->t2; t++, s++) {
20278 		    Z[v][t] = xy_calc(Z[v][t], m->val[s], p->op, SERIES, p);
20279 		}
20280 	    } else if (mt1 > 0) {
20281 		/* align using matrix "t1" value */
20282 		for (t=mt1; t<mt1 + k && t<=p->dset->t2; t++) {
20283 		    if (t >= p->dset->t1) {
20284 			Z[v][t] = xy_calc(Z[v][t], m->val[t - mt1], p->op,
20285 					  SERIES, p);
20286 		    }
20287 		}
20288 	    }
20289 	}
20290 	strcpy(p->dset->varname[v], p->lh.name);
20291 	series_unset_orig_pd(p->dset, v); /* 2020-09-27 */
20292 #if EDEBUG
20293 	fprintf(stderr, "var %d: gave generated series the name '%s'\n",
20294 		v, p->lh.name);
20295 	fprintf(stderr, " value[1] = %g\n", p->dset->Z[v][1]);
20296 #endif
20297 	if (!p->err) {
20298 	    /* (probably) changed or added a series */
20299 	    set_dataset_is_changed(p->dset, 1);
20300 	}
20301     } else if (p->targ == MAT) {
20302 	/* we're writing a matrix */
20303 	gretl_matrix *m = NULL;
20304 
20305 	if (p->lh.uv == NULL) {
20306 	    /* there's no pre-existing left-hand side matrix */
20307 	    m = retrieve_matrix_result(p);
20308 	    if (!p->err) {
20309 		p->err = gen_add_uvar(p, GRETL_TYPE_MATRIX, m);
20310 	    }
20311 	} else if (p->op == B_ASN) {
20312 	    /* uninflected assignment to an existing matrix */
20313 	    m = assign_to_matrix(p);
20314 	} else {
20315 	    /* inflected assignment to entire existing matrix */
20316 	    gretl_matrix *m1 = gen_get_lhs_var(p, GRETL_TYPE_MATRIX);
20317 
20318 	    m = assign_to_matrix_mod(m1, p);
20319 	    if (!p->err) {
20320 		p->err = gen_replace_lhs(p, GRETL_TYPE_MATRIX, m);
20321 	    }
20322 	}
20323 	/* note: for use by genr_get_output_matrix() */
20324 	p->lh.mret = m;
20325     } else if (p->targ == LIST) {
20326 	create_or_edit_list(p);
20327     } else if (p->targ == STR) {
20328 	create_or_edit_string(p);
20329     } else if (p->targ == BUNDLE) {
20330 	if (null_node(r)) {
20331 	    /* as in "bundle b = null" */
20332 	    p->err = assign_null_to_bundle(p);
20333 	} else if (p->op != B_ASN) {
20334 	    do_bundle_append(p);
20335 	} else {
20336 	    /* full assignment of RHS bundle */
20337 	    gretl_bundle *b;
20338 
20339 	    if (r->t == DBUNDLE) {
20340 		b = bvar_get_bundle(r, p);
20341 	    } else if (is_tmp_node(r) || (p->flags & P_UFRET)) {
20342 		/* grabbing r->v.b is OK */
20343 		b = r->v.b;
20344 	    } else {
20345 		/* we need to make a copy */
20346 		b = gretl_bundle_copy(r->v.b, &p->err);
20347 	    }
20348 
20349 	    if (!p->err) {
20350 		p->err = gen_add_or_replace(p, GRETL_TYPE_BUNDLE, b);
20351 		if (!p->err && r->t != DBUNDLE && b == r->v.b) {
20352 		    /* avoid destroying the assigned bundle */
20353 		    r->v.b = NULL;
20354 		}
20355 	    }
20356 	}
20357     } else if (p->targ == ARRAY) {
20358 	if (p->op == B_ADD) {
20359 	    do_array_append(p);
20360 	} else if (p->op == B_SUB) {
20361 	    do_array_subtract(p);
20362 	} else if (null_node(r)) {
20363 	    /* as in, e.g., "strings A = null" */
20364 	    p->err = assign_null_to_array(p);
20365 	} else if (r->t == ARRAY) {
20366 	    /* full assignment of RHS array */
20367 	    GretlType atype = gretl_array_get_type(r->v.a);
20368 	    gretl_array *a = NULL;
20369 
20370 	    if (p->lh.gtype > 0 && atype != p->lh.gtype) {
20371 		p->err = E_TYPES;
20372 	    } else if (is_tmp_node(r) || (p->flags & P_UFRET)) {
20373 		/* grabbing r->v.a is OK */
20374 		a = r->v.a;
20375 	    } else {
20376 		/* we need to make a copy */
20377 		a = gretl_array_copy(r->v.a, &p->err);
20378 	    }
20379 	    if (!p->err) {
20380 		p->err = gen_add_or_replace(p, atype, a);
20381 		if (!p->err && a == r->v.a) {
20382 		    /* avoid destroying the assigned array */
20383 		    r->v.a = NULL;
20384 		}
20385 	    }
20386 	} else {
20387 	    /* Allow promotion of a single object to an array of
20388 	       size 1? Note 2021-08-12: not sure this is actually
20389 	       a good idea.
20390 	    */
20391 	    GretlType rtype = gretl_type_from_gen_type(r->t);
20392 	    GretlType atype = p->lh.gtype;
20393 
20394 	    if (rtype == gretl_type_get_singular(atype)) {
20395 		gretl_array *a = gretl_singleton_array(r->v.ptr, atype,
20396 						       1, &p->err);
20397 
20398 		if (!p->err) {
20399 		    p->err = gen_add_or_replace(p, atype, a);
20400 		}
20401 	    } else {
20402 		p->err = E_TYPES;
20403 	    }
20404 	}
20405     }
20406 
20407 #if EDEBUG
20408     fprintf(stderr, "save_generated_var: returning p->err = %d\n",
20409 	    p->err);
20410 #endif
20411 
20412     return p->err;
20413 }
20414 
maybe_update_lhs_uvar(parser * p,GretlType * type)20415 static void maybe_update_lhs_uvar (parser *p, GretlType *type)
20416 {
20417     if (p->targ == SERIES) {
20418 	/* targetting a series */
20419 	int v = p->lh.vnum;
20420 
20421 	if (get_loop_renaming() || v <= 0 || v >= p->dset->v) {
20422 	    p->lh.vnum = current_series_index(p->dset, p->lh.name);
20423 	}
20424 	if (p->lh.vnum < 0) {
20425 	    p->lh.vnum = 0;
20426 	}
20427 	return;
20428     }
20429 
20430     if (p->lh.uv == NULL) {
20431 	p->lh.uv = get_user_var_by_name(p->lh.name);
20432     }
20433 
20434     if (p->lh.uv != NULL) {
20435 	*type = p->lh.uv->type;
20436     }
20437 
20438     switch (*type) {
20439     case GRETL_TYPE_DOUBLE:
20440 	p->lh.t = NUM;
20441 	break;
20442     case GRETL_TYPE_MATRIX:
20443 	p->lh.t = MAT;
20444 	if (p->targ == NUM) {
20445 	    p->targ = MAT;
20446 	}
20447 	break;
20448     case GRETL_TYPE_LIST:
20449 	p->lh.t = LIST;
20450 	break;
20451     case GRETL_TYPE_STRING:
20452 	p->lh.t = STR;
20453 	break;
20454     case GRETL_TYPE_BUNDLE:
20455 	p->lh.t = BUNDLE;
20456 	break;
20457     case GRETL_TYPE_ARRAY:
20458 	p->lh.t = ARRAY;
20459 	break;
20460     default:
20461 	p->lh.t = 0;
20462 	break;
20463     }
20464 }
20465 
parser_reinit(parser * p,DATASET * dset,PRN * prn)20466 static void parser_reinit (parser *p, DATASET *dset, PRN *prn)
20467 {
20468     /* flags that should be reinstated if they were
20469        set at compile time, or in previous execution
20470     */
20471     int saveflags[] = {
20472 	P_NATEST, P_AUTOREG, P_SLAVE,
20473 	P_DISCARD, P_NODECL, P_LISTDEF,
20474 	0
20475     };
20476     int i, prevflags = p->flags;
20477     GretlType lhtype = 0;
20478     int dset_n;
20479 
20480     if (p->callcount > 1) {
20481 	/* the flags should basically have stabilized by now */
20482 	p->flags |= P_START;
20483 	p->flags &= ~P_DELTAN;
20484     } else {
20485 	p->flags = (P_START | P_PRIV | P_EXEC);
20486 	for (i=0; saveflags[i] > 0; i++) {
20487 	    if (prevflags & saveflags[i]) {
20488 		p->flags |= saveflags[i];
20489 	    }
20490 	}
20491     }
20492 
20493     p->dset = dset;
20494     p->prn = prn;
20495 
20496     p->obs = 0;
20497     p->sym = 0;
20498     p->ch = 0;
20499     p->xval = 0.0;
20500     p->idnum = 0;
20501     p->idstr = NULL;
20502     p->data = NULL;
20503     p->errprn = NULL;
20504 
20505     p->ret = NULL;
20506     p->lhres = NULL;
20507     p->err = 0;
20508 
20509 #if EDEBUG
20510     fprintf(stderr, "parser_reinit: targ=%s, lhname='%s', op='%s', "
20511 	    "callcount=%d, compiled=%d\n",
20512 	    getsymb(p->targ), p->lh.name, getsymb(p->op),
20513 	    p->callcount, compiled(p));
20514 #endif
20515 
20516     if (*p->lh.name != '\0') {
20517 	maybe_update_lhs_uvar(p, &lhtype);
20518     }
20519 
20520     /* allow for change in length of dataset */
20521     dset_n = dset != NULL ? dset->n : 0;
20522     if (dset_n != p->dset_n) {
20523 	p->dset_n = dset_n;
20524 	p->flags |= P_DELTAN;
20525     }
20526 }
20527 
parser_init(parser * p,const char * str,DATASET * dset,PRN * prn,int flags,int targtype,int * done)20528 static void parser_init (parser *p, const char *str,
20529 			 DATASET *dset, PRN *prn,
20530 			 int flags, int targtype,
20531 			 int *done)
20532 {
20533     p->point = p->rhs = p->input = str;
20534     p->dset = dset;
20535     p->dset_n = dset != NULL ? dset->n : 0;
20536     p->prn = prn;
20537     p->errprn = NULL;
20538     p->flags = flags | P_START;
20539     p->targ = targtype;
20540     p->op = 0;
20541 
20542     p->lhtree = NULL;
20543     p->lhres = NULL;
20544     p->tree = NULL;
20545     p->ret = NULL;
20546 
20547     /* left-hand side info */
20548     p->lh.t = 0;
20549     p->lh.name[0] = '\0';
20550     p->lh.label = NULL;
20551     p->lh.vnum = 0;
20552     p->lh.uv = NULL;
20553     p->lh.expr = NULL;
20554     p->lh.gtype = 0;
20555     p->lh.mret = NULL;
20556 
20557     /* auxiliary apparatus */
20558     p->aux = NULL;
20559 
20560     p->callcount = 0;
20561     p->obs = 0;
20562     p->sym = 0;
20563     p->upsym = 0;
20564     p->ch = 0;
20565     p->xval = 0.0;
20566     p->idnum = 0;
20567     p->idstr = NULL;
20568     p->err = 0;
20569 
20570     if (p->input == NULL) {
20571 	p->err = E_DATA;
20572 	return;
20573     }
20574 
20575     if (p->flags & P_VOID) {
20576         p->flags |= P_DISCARD;
20577     } else if (p->targ == UNK || !(p->flags & P_ANON)) {
20578 	gen_preprocess(p, flags, done);
20579     } else if (p->targ == LIST) {
20580 	p->flags |= P_LISTDEF;
20581     }
20582 
20583     if (!p->err) {
20584 	p->ch = parser_getc(p);
20585     }
20586 }
20587 
20588 /* called from genmain.c (only!) */
20589 
gen_save_or_print(parser * p,PRN * prn)20590 void gen_save_or_print (parser *p, PRN *prn)
20591 {
20592     if (autoreg(p)) {
20593 	/* no transcription required */
20594 	return;
20595     }
20596     if (p->flags & P_DISCARD) {
20597 	/* doing "eval" */
20598 	if (p->ret == NULL) {
20599 	    return;
20600 	} else if (p->ret->t == MAT) {
20601 	    if (p->ret->v.m->is_complex) {
20602 		gretl_cmatrix_print(p->ret->v.m, p->lh.name, p->prn);
20603 	    } else {
20604 		gretl_matrix_print_to_prn(p->ret->v.m, p->lh.name, p->prn);
20605 	    }
20606 	} else if (p->ret->t == LIST) {
20607 	    if (p->lh.name[0] != '\0') {
20608 		gretl_list_print(get_list_by_name(p->lh.name),
20609 				 p->dset, p->prn);
20610 	    } else {
20611 		gretl_list_print(p->ret->v.ivec, p->dset, p->prn);
20612 	    }
20613 	} else if (p->ret->t == STR) {
20614 	    if (p->lh.name[0] != '\0') {
20615 		pprintf(p->prn, "%s\n", gen_get_lhs_var(p, GRETL_TYPE_STRING));
20616 	    } else {
20617 		pprintf(p->prn, "%s\n", p->ret->v.str);
20618 	    }
20619 	} else if (p->ret->t == BUNDLE) {
20620 	    gretl_bundle_print(p->ret->v.b, prn);
20621 	} else if (p->ret->t == ARRAY) {
20622 	    gretl_array_print(p->ret->v.a, prn);
20623 	} else {
20624 	    /* scalar, series */
20625 	    printnode(p->ret, p, 1);
20626 	    pputc(p->prn, '\n');
20627 	}
20628     } else if (p->flags & P_DECL) {
20629 	do_declaration(p);
20630     } else {
20631 	save_generated_var(p, prn);
20632     }
20633 }
20634 
gen_cleanup(parser * p)20635 void gen_cleanup (parser *p)
20636 {
20637     int save = (p->flags & (P_COMPILE | P_EXEC));
20638 
20639 #if EDEBUG
20640     fprintf(stderr, "gen cleanup on %p: save = %d\n",
20641 	    p, save ? 1 : 0);
20642 #endif
20643 
20644     if (p->lh.label != NULL) {
20645 	free(p->lh.label);
20646 	p->lh.label = NULL;
20647     }
20648 
20649     if (p->flags & P_ALTINP) {
20650 	free((char *) p->input);
20651 	p->input = NULL;
20652     }
20653 
20654     if (p->err && (p->flags & P_COMPILE)) {
20655 	save = 0;
20656     }
20657 
20658     if (!save) {
20659 	if (p->lhtree != NULL) {
20660 	    if (p->lhtree != p->lhres) {
20661 		/* we have to scrub the LHT_NODE flag on p->lhtree,
20662 		   or else its children will not get freed and we'll
20663 		   leak memory
20664 		*/
20665 		p->lhtree->flags &= ~LHT_NODE;
20666 		rndebug(("freeing p->lhtree %p\n", (void *) p->lhtree));
20667 		free_tree(p->lhtree, p, FR_LHTREE);
20668 	    }
20669 	    if (p->lhres != NULL) {
20670 		rndebug(("freeing p->lhres %p\n", (void *) p->lhres));
20671 		free_tree(p->lhres, p, FR_LHRES);
20672 	    }
20673 	}
20674 
20675 	if (p->tree != p->ret) {
20676 	    rndebug(("freeing p->tree %p\n", (void *) p->tree));
20677 	    free_tree(p->tree, p, FR_TREE);
20678 	}
20679 
20680 	rndebug(("freeing p->ret %p\n", (void *) p->ret));
20681 	free_tree(p->ret, p, FR_RET);
20682 
20683 	free(p->lh.expr);
20684     }
20685 
20686 #if EDEBUG
20687     fprintf(stderr, "gen cleanup finished\n");
20688 #endif
20689 }
20690 
20691 #define LS_DEBUG 0
20692 
real_reset_uvars(parser * p)20693 static void real_reset_uvars (parser *p)
20694 {
20695     if (p->err) {
20696 	return;
20697     }
20698 
20699 #if LS_DEBUG
20700     fprintf(stderr, "\nreal_reset_uvars (%s '%s') *\n",
20701 	    getsymb(p->targ), p->lh.name);
20702 #endif
20703 
20704     clear_uvnodes(p->tree);
20705 
20706     if (p->lhtree != NULL) {
20707 	clear_uvnodes(p->lhtree);
20708     }
20709 
20710     p->lh.uv = NULL;
20711     p->lh.vnum = 0;
20712 }
20713 
genr_reset_uvars(parser * p)20714 void genr_reset_uvars (parser *p)
20715 {
20716     real_reset_uvars(p);
20717 }
20718 
maybe_set_return_flags(parser * p)20719 static void maybe_set_return_flags (parser *p)
20720 {
20721     NODE *t = p->tree;
20722 
20723     if (t != NULL && t->t == UFUN) {
20724 	p->flags |= P_UFRET;
20725     }
20726 }
20727 
decl_check(parser * p,int flags)20728 static int decl_check (parser *p, int flags)
20729 {
20730     if (flags & P_COMPILE) {
20731 	p->err = E_PARSE;
20732 	gretl_errmsg_sprintf("%s:\n> '%s'",
20733 			     _("Bare declarations are not allowed here"),
20734 			     p->input);
20735     }
20736 
20737     return p->err;
20738 }
20739 
autoreg_error(parser * p,int t)20740 static void autoreg_error (parser *p, int t)
20741 {
20742     fprintf(stderr, "*** autoreg error at obs t = %d (t1 = %d):\n",
20743 	    t, p->dset->t1);
20744 
20745     if (p->ret != NULL && p->ret->t != SERIES) {
20746 	fprintf(stderr, " ret type != SERIES (=%d), p->err = %d\n",
20747 		p->ret->t, p->err);
20748     } else if (p->ret == NULL) {
20749 	fprintf(stderr, " ret = NULL, p->err = %d\n", p->err);
20750     }
20751 
20752     fprintf(stderr, " input = '%s'\n", p->input);
20753 
20754     if (!p->err) {
20755 	p->err = E_DATA;
20756     }
20757 }
20758 
20759 #if EDEBUG
20760 
autoreg_genr_report(const double * x,const double * y,int initted,parser * p)20761 void autoreg_genr_report (const double *x, const double *y,
20762 			  int initted, parser *p)
20763 {
20764     int t = p->obs;
20765 
20766     fprintf(stderr, "\n*** autoreg: p->obs = %d\n", t);
20767     if (!initted && na(x[t])) {
20768 	fprintf(stderr, "skipping xvec[%d], leaving y[%d] = %g\n",
20769 		t, t, y[t]);
20770     } else if (p->op == B_ASN) {
20771 	fprintf(stderr, "writing xvec[%d] = %g into y[%d] (was %g)\n",
20772 		t, x[t], t, y[t]);
20773     } else {
20774 	fprintf(stderr, "using xvec[%d] = %g to modify y[%d] (was %g)\n",
20775 		t, x[t], t, y[t]);
20776     }
20777 }
20778 
20779 #endif
20780 
realgen(const char * s,parser * p,DATASET * dset,PRN * prn,int flags,int targtype)20781 int realgen (const char *s, parser *p, DATASET *dset, PRN *prn,
20782 	     int flags, int targtype)
20783 {
20784 #if LHDEBUG || EDEBUG || AUX_NODES_DEBUG
20785     fprintf(stderr, "\n*** realgen: task = %s\n", (flags & P_COMPILE)?
20786 	    "compile" : (flags & P_EXEC)? "exec" : "normal");
20787     if (s != NULL) {
20788 	fprintf(stderr, "targ=%d (%s), input='%s'\n", targtype,
20789 		(targtype < PUNCT_MAX)? gretl_type_get_name(targtype) :
20790 		getsymb(targtype), s);
20791     }
20792 #endif
20793 
20794     if (flags & P_EXEC) {
20795 #if EDEBUG
20796 	fprintf(stderr, "*** printing p->tree (before reinit)\n");
20797 	print_tree(p->tree, p, 0, 0);
20798 #endif
20799 	parser_reinit(p, dset, prn);
20800 	if (p->err) {
20801 	    fprintf(stderr, "error in parser_reinit\n");
20802 	    goto gen_finish;
20803 	} else if (p->op == INC || p->op == DEC) {
20804 	    /* more or less a no-op: the work is done by
20805 	       save_generated_var()
20806 	    */
20807 	    goto gen_finish;
20808 	} else {
20809 	    goto starteval;
20810 	}
20811     } else {
20812 	int done = 0;
20813 
20814 	parser_init(p, s, dset, prn, flags, targtype, &done);
20815 	if (p->err) {
20816 	    if (gretl_function_depth() == 0) {
20817 		errmsg(p->err, prn);
20818 	    }
20819 	    goto gen_finish;
20820 	} else if (done) {
20821 	    goto gen_finish;
20822 	}
20823     }
20824 
20825 #if EDEBUG
20826     fprintf(stderr, "after parser %s, p->err = %d (decl? %s)\n",
20827 	    (flags & P_EXEC)? "reinit" : "init", p->err,
20828 	    (p->flags & P_DECL)? "yes" : "no");
20829 #endif
20830 
20831     if (p->flags & P_DECL) {
20832 	/* check validity of declaration(s) */
20833 	decl_check(p, flags);
20834 	goto gen_finish;
20835     }
20836 
20837     if (p->op == INC || p->op == DEC) {
20838 	/* implemented via save_generated_var() */
20839 	goto gen_finish;
20840     }
20841 
20842     /* fire up the lexer */
20843     lex(p);
20844     if (p->err) {
20845 #if EDEBUG
20846 	fprintf(stderr, "realgen %p ('%s'): got on lex() error %d\n",
20847 		(void *) p, s, p->err);
20848 #endif
20849 	goto gen_finish;
20850     }
20851 
20852     /* build the syntax tree */
20853     p->tree = expr(p);
20854     if (p->err) {
20855 	goto gen_finish;
20856     }
20857 
20858 #if EDEBUG
20859     if (p->tree != NULL) {
20860 	fprintf(stderr, "realgen: p->tree at %p, type %d (%s)\n", (void *) p->tree,
20861 		p->tree->t, getsymb(p->tree->t));
20862     }
20863     if (p->ch == '\0') {
20864 	fprintf(stderr, " p->ch = NUL, p->sym = %d\n", p->sym);
20865     } else {
20866 	fprintf(stderr, " p->ch = '%c', p->sym = %d\n", p->ch, p->sym);
20867     }
20868 #endif
20869 
20870     if (p->sym != EOT || p->ch != 0) {
20871 	int c = p->ch;
20872 
20873 	if (c == ' ') {
20874 	    c = 0;
20875 	} else if (c != 0) {
20876 	    parser_ungetc(p);
20877 	    c = p->ch;
20878 	}
20879 	context_error(c, p, "realgen");
20880 	goto gen_finish;
20881     }
20882 
20883     if (flags & P_NOEXEC) {
20884 	/* we're done at this point */
20885 	goto gen_finish;
20886     }
20887 
20888     if (!p->err) {
20889 	/* set P_UFRET here if relevant */
20890 	maybe_set_return_flags(p);
20891     }
20892 
20893  starteval:
20894 
20895 #if EDEBUG
20896     if (flags & P_EXEC) {
20897 	fprintf(stderr, "*** printing p->tree (about to start eval)\n");
20898 	print_tree(p->tree, p, 0, 0);
20899     }
20900 #endif
20901 
20902     if (autoreg(p)) {
20903 	/* e.g. y = b*y(-1) : evaluate dynamically */
20904 	double *y = p->dset->Z[p->lh.vnum];
20905 	const double *x;
20906 	int t, initted = 0;
20907 
20908 	for (t=p->dset->t1; t<=p->dset->t2 && !p->err; t++) {
20909 	    /* initialize for this observation */
20910 	    p->obs = t;
20911 	    if (dataset_is_panel(p->dset) && t % p->dset->pd == 0) {
20912 		initted = 0;
20913 	    }
20914 	    p->ret = eval(p->tree, p);
20915 	    if (p->ret != NULL && p->ret->t == SERIES) {
20916 		x = p->ret->v.xvec;
20917 #if EDEBUG
20918 		autoreg_genr_report(x, y, initted, p);
20919 #endif
20920 		if (!initted && na(x[t])) {
20921 		    ; /* don't overwrite initializer */
20922 		} else {
20923 		    if (p->op == B_ASN) {
20924 			y[t] = x[t];
20925 		    } else {
20926 			y[t] = xy_calc(y[t], x[t], p->op, SERIES, p);
20927 		    }
20928 		    initted = 1;
20929 		}
20930 	    } else {
20931 		autoreg_error(p, t);
20932 	    }
20933 	    if (t == p->dset->t1) {
20934 		p->flags &= ~P_START;
20935 	    }
20936 	}
20937     } else {
20938 	/* standard non-dynamic evaluation */
20939 	p->ret = eval(p->tree, p);
20940     }
20941 
20942     if (p->flags & P_EXEC) {
20943 	p->callcount += 1;
20944     }
20945 
20946  gen_finish:
20947 
20948     if (p->errprn != NULL) {
20949 	/* Pick and forward any error message that may not be
20950 	   seen if realgen was invoked with a NULL value for
20951 	   the printer @prn.
20952 	*/
20953 	const char *buf = gretl_print_get_buffer(p->errprn);
20954 
20955 	if (buf != NULL && *buf != '\0') {
20956 	    gretl_errmsg_set(buf);
20957 	}
20958 	gretl_print_destroy(p->errprn);
20959 	p->errprn = NULL;
20960     }
20961 
20962 #if EDEBUG
20963     fprintf(stderr, "realgen: at finish, err = %d\n", p->err);
20964 # if EDEBUG > 1
20965     printnode(p->ret, p, 0);
20966     pputc(prn, '\n');
20967 # endif
20968 #endif
20969 
20970     return p->err;
20971 }
20972