doc: document new options and new applications
[barvinok.git] / evalue_read.c
blob2968094b5b3f4d200c9209c8e512161ed6ee85d5
1 #include <assert.h>
2 #include <barvinok/util.h>
3 #include "evalue_read.h"
5 #define ALLOC(type) (type*)malloc(sizeof(type))
6 #define ALLOCN(type,n) (type*)malloc((n) * sizeof(type))
8 enum token_type { TOKEN_UNKNOWN = 256, TOKEN_VALUE, TOKEN_IDENT, TOKEN_GE,
9 TOKEN_NE, TOKEN_UNION, TOKEN_VARS };
11 struct token {
12 enum token_type type;
14 int line;
15 int col;
17 union {
18 Value v;
19 char *s;
20 } u;
23 static struct token *token_new(int line, int col)
25 struct token *tok = ALLOC(struct token);
26 tok->line = line;
27 tok->col = col;
28 return tok;
31 void token_free(struct token *tok)
33 if (tok->type == TOKEN_VALUE)
34 value_clear(tok->u.v);
35 else if (tok->type == TOKEN_IDENT)
36 free(tok->u.s);
37 free(tok);
40 struct stream {
41 FILE *file;
42 const char *str;
43 int line;
44 int col;
45 int eof;
47 char *buffer;
48 size_t size;
49 size_t len;
50 int c;
52 struct token *tokens[5];
53 int n_token;
56 static struct stream* stream_new()
58 int i;
59 struct stream *s = ALLOC(struct stream);
60 s->size = 256;
61 s->file = NULL;
62 s->str = NULL;
63 s->buffer = (char*)malloc(s->size);
64 s->len = 0;
65 s->line = 1;
66 s->col = 0;
67 s->eof = 0;
68 s->c = -1;
69 for (i = 0; i < 5; ++i)
70 s->tokens[i] = NULL;
71 s->n_token = 0;
72 return s;
75 static struct stream* stream_new_file(FILE *file)
77 struct stream *s = stream_new();
78 s->file = file;
79 return s;
82 static struct stream* stream_new_str(const char *str)
84 struct stream *s = stream_new();
85 s->str = str;
86 return s;
89 static int stream_getc(struct stream *s)
91 int c;
92 if (s->eof)
93 return -1;
94 if (s->file)
95 c = fgetc(s->file);
96 else {
97 c = *s->str++;
98 if (c == '\0')
99 c = -1;
101 if (c == -1)
102 s->eof = 1;
103 if (!s->eof) {
104 if (s->c == '\n') {
105 s->line++;
106 s->col = 0;
107 } else
108 s->col++;
110 s->c = c;
111 return c;
114 static void stream_ungetc(struct stream *s, int c)
116 if (s->file)
117 ungetc(c, s->file);
118 else
119 --s->str;
120 s->c = -1;
123 static void stream_push_char(struct stream *s, int c)
125 if (s->len >= s->size) {
126 s->size = (3*s->size)/2;
127 s->buffer = (char*)realloc(s->buffer, s->size);
129 s->buffer[s->len++] = c;
132 static struct token *stream_push_token(struct stream *s, struct token *tok)
134 assert(s->n_token < 5);
135 s->tokens[s->n_token++] = tok;
138 static struct token *stream_next_token(struct stream *s)
140 int c;
141 struct token *tok;
142 int line, col;
144 if (s->n_token)
145 return s->tokens[--s->n_token];
147 s->len = 0;
149 /* skip spaces */
150 while ((c = stream_getc(s)) != -1 && isspace(c))
151 /* nothing */
154 line = s->line;
155 col = s->col;
157 if (c == -1)
158 return NULL;
159 if (c == '(' ||
160 c == ')' ||
161 c == '+' ||
162 c == '/' ||
163 c == '*' ||
164 c == '^' ||
165 c == '=' ||
166 c == ',' ||
167 c == '_' ||
168 c == '[' ||
169 c == ']' ||
170 c == '{' ||
171 c == '}') {
172 tok = token_new(line, col);
173 tok->type = (enum token_type)c;
174 return tok;
176 if (c == '-' || isdigit(c)) {
177 tok = token_new(line, col);
178 tok->type = TOKEN_VALUE;
179 value_init(tok->u.v);
180 stream_push_char(s, c);
181 while ((c = stream_getc(s)) != -1 && isdigit(c))
182 stream_push_char(s, c);
183 if (c != -1)
184 stream_ungetc(s, c);
185 if (s->len == 1 && s->buffer[0] == '-')
186 value_set_si(tok->u.v, -1);
187 else {
188 stream_push_char(s, '\0');
189 mpz_set_str(tok->u.v, s->buffer, 0);
191 return tok;
193 if (c == '#' || isalpha(c)) {
194 tok = token_new(line, col);
195 stream_push_char(s, c);
196 while ((c = stream_getc(s)) != -1 && isalnum(c))
197 stream_push_char(s, c);
198 if (c != -1)
199 stream_ungetc(s, c);
200 stream_push_char(s, '\0');
201 if (!strcmp(s->buffer, "#variables")) {
202 tok->type = TOKEN_VARS;
203 } else if (s->buffer[0] == '#') {
204 tok->type = TOKEN_UNKNOWN;
205 } else if (!strcmp(s->buffer, "UNION")) {
206 tok->type = TOKEN_UNION;
207 } else {
208 tok->type = TOKEN_IDENT;
209 tok->u.s = strdup(s->buffer);
211 return tok;
213 if (c == '>') {
214 if ((c = stream_getc(s)) == '=') {
215 tok = token_new(line, col);
216 tok->type = TOKEN_GE;
217 return tok;
219 if (c != -1)
220 stream_ungetc(s, c);
222 if (c == '!') {
223 if ((c = stream_getc(s)) == '=') {
224 tok = token_new(line, col);
225 tok->type = TOKEN_NE;
226 return tok;
228 if (c != -1)
229 stream_ungetc(s, c);
232 tok = token_new(line, col);
233 tok->type = TOKEN_UNKNOWN;
234 return tok;
237 void stream_error(struct stream *s, struct token *tok, char *msg)
239 int line = tok ? tok->line : s->line;
240 int col = tok ? tok->col : s->col;
241 fprintf(stderr, "syntax error (%d, %d): %s\n", line, col, msg);
242 if (tok) {
243 if (tok->type < 256)
244 fprintf(stderr, "got '%c'\n", tok->type);
245 else
246 fprintf(stderr, "got token type %d\n", tok->type);
250 static void stream_free(struct stream *s)
252 free(s->buffer);
253 if (s->n_token != 0) {
254 struct token *tok = stream_next_token(s);
255 stream_error(s, tok, "unexpected token");
257 free(s);
260 struct parameter {
261 char *name;
262 int pos;
263 struct parameter *next;
266 struct parameter *parameter_new(const char *name, int pos, struct parameter *next)
268 struct parameter *p = ALLOC(struct parameter);
269 p->name = strdup(name);
270 p->pos = pos;
271 p->next = next;
272 return p;
275 static int parameter_pos(struct parameter **p, const char *s, int len)
277 int pos = *p ? (*p)->pos+1 : 0;
278 struct parameter *q;
280 if (len == -1)
281 len = strlen(s);
282 for (q = *p; q; q = q->next) {
283 if (strncmp(q->name, s, len) == 0)
284 break;
286 if (q)
287 pos = q->pos;
288 else
289 *p = parameter_new(s, pos, *p);
290 return pos;
293 static int optional_power(struct stream *s)
295 int pow;
296 struct token *tok;
297 tok = stream_next_token(s);
298 if (!tok)
299 return 1;
300 if (tok->type != '^') {
301 stream_push_token(s, tok);
302 return 1;
304 token_free(tok);
305 tok = stream_next_token(s);
306 if (!tok || tok->type != TOKEN_VALUE) {
307 stream_error(s, tok, "expecting exponent");
308 if (tok)
309 stream_push_token(s, tok);
310 return 1;
312 pow = VALUE_TO_INT(tok->u.v);
313 token_free(tok);
314 return pow;
317 static evalue *evalue_read_factor(struct stream *s, struct parameter **p);
318 static evalue *evalue_read_term(struct stream *s, struct parameter **p);
320 static evalue *create_fract_like(struct stream *s, evalue *arg, enode_type type,
321 struct parameter **p)
323 evalue *e;
324 int pow;
325 pow = optional_power(s);
327 e = ALLOC(evalue);
328 value_init(e->d);
329 e->x.p = new_enode(type, pow+2, -1);
330 value_clear(e->x.p->arr[0].d);
331 e->x.p->arr[0] = *arg;
332 free(arg);
333 evalue_set_si(&e->x.p->arr[1+pow], 1, 1);
334 while (--pow >= 0)
335 evalue_set_si(&e->x.p->arr[1+pow], 0, 1);
337 return e;
340 static evalue *create_relation(evalue *arg, int ne)
342 evalue *e;
344 e = ALLOC(evalue);
345 value_init(e->d);
346 e->x.p = new_enode(relation, 2+ne, 0);
347 value_clear(e->x.p->arr[0].d);
348 e->x.p->arr[0] = *arg;
349 free(arg);
350 if (ne)
351 evalue_set_si(&e->x.p->arr[1], 0, 1);
352 evalue_set_si(&e->x.p->arr[1+ne], 1, 1);
354 return e;
357 static evalue *read_fract(struct stream *s, struct token *tok, struct parameter **p)
359 evalue *arg;
361 tok = stream_next_token(s);
362 assert(tok);
363 assert(tok->type == '{');
365 token_free(tok);
366 arg = evalue_read_term(s, p);
367 tok = stream_next_token(s);
368 if (!tok || tok->type != '}') {
369 stream_error(s, tok, "expecting \"}\"");
370 if (tok)
371 stream_push_token(s, tok);
372 } else
373 token_free(tok);
375 return create_fract_like(s, arg, fractional, p);
378 static evalue *read_periodic(struct stream *s, struct parameter **p)
380 evalue **list;
381 int len;
382 int n;
383 evalue *e = NULL;
385 struct token *tok;
386 tok = stream_next_token(s);
387 assert(tok && tok->type == '[');
388 token_free(tok);
390 len = 100;
391 list = (evalue **)malloc(len * sizeof(evalue *));
392 n = 0;
394 for (;;) {
395 evalue *e = evalue_read_term(s, p);
396 if (!e) {
397 stream_error(s, NULL, "missing argument or list element");
398 goto out;
400 if (n >= len) {
401 len = (3*len)/2;
402 list = (evalue **)realloc(list, len * sizeof(evalue *));
404 list[n++] = e;
406 tok = stream_next_token(s);
407 if (!tok) {
408 stream_error(s, NULL, "unexpected EOF");
409 goto out;
411 if (tok->type != ',')
412 break;
413 token_free(tok);
416 if (n == 1 && (tok->type == '=' || tok->type == TOKEN_NE)) {
417 int ne = tok->type == TOKEN_NE;
418 token_free(tok);
419 tok = stream_next_token(s);
420 if (!tok || tok->type != TOKEN_VALUE) {
421 stream_error(s, tok, "expecting \"0\"");
422 if (tok)
423 stream_push_token(s, tok);
424 goto out;
426 token_free(tok);
427 tok = stream_next_token(s);
428 if (!tok || tok->type != ']') {
429 stream_error(s, tok, "expecting \"]\"");
430 if (tok)
431 stream_push_token(s, tok);
432 goto out;
434 token_free(tok);
435 e = create_relation(list[0], ne);
436 n = 0;
437 goto out;
440 if (tok->type != ']') {
441 stream_error(s, tok, "expecting \"]\"");
442 stream_push_token(s, tok);
443 goto out;
446 token_free(tok);
448 tok = stream_next_token(s);
449 if (tok && tok->type == '_') {
450 int pos;
451 token_free(tok);
452 tok = stream_next_token(s);
453 if (!tok || tok->type != TOKEN_IDENT) {
454 stream_error(s, tok, "expecting identifier");
455 if (tok)
456 stream_push_token(s, tok);
457 goto out;
459 e = ALLOC(evalue);
460 value_init(e->d);
461 pos = parameter_pos(p, tok->u.s, -1);
462 token_free(tok);
463 e->x.p = new_enode(periodic, n, pos+1);
464 while (--n >= 0) {
465 value_clear(e->x.p->arr[n].d);
466 e->x.p->arr[n] = *list[n];
467 free(list[n]);
469 } else if (n == 1) {
470 if (tok)
471 stream_push_token(s, tok);
472 e = create_fract_like(s, list[0], flooring, p);
473 n = 0;
474 } else {
475 stream_error(s, tok, "unexpected token");
476 if (tok)
477 stream_push_token(s, tok);
480 out:
481 while (--n >= 0)
482 evalue_free(list[n]);
483 free(list);
484 return e;
487 /* frees product on error */
488 static evalue *read_factor_and_multiply(struct stream *s, struct parameter **p,
489 evalue *product)
491 evalue *e2;
492 e2 = evalue_read_factor(s, p);
493 if (!e2) {
494 stream_error(s, NULL, "unexpected EOF");
495 evalue_free(product);
496 return NULL;
498 emul(e2, product);
499 evalue_free(e2);
500 return product;
503 static evalue *evalue_read_factor(struct stream *s, struct parameter **p)
505 struct token *tok;
506 evalue *e = NULL;
508 tok = stream_next_token(s);
509 if (!tok)
510 return NULL;
512 if (tok->type == '(') {
513 token_free(tok);
514 e = evalue_read_term(s, p);
515 tok = stream_next_token(s);
516 if (!tok || tok->type != ')') {
517 stream_error(s, tok, "expecting \")\"");
518 if (tok)
519 stream_push_token(s, tok);
520 } else
521 token_free(tok);
522 } else if (tok->type == TOKEN_VALUE) {
523 e = ALLOC(evalue);
524 value_init(e->d);
525 value_set_si(e->d, 1);
526 value_init(e->x.n);
527 value_assign(e->x.n, tok->u.v);
528 token_free(tok);
529 tok = stream_next_token(s);
530 if (tok && tok->type == '/') {
531 token_free(tok);
532 tok = stream_next_token(s);
533 if (!tok || tok->type != TOKEN_VALUE) {
534 stream_error(s, tok, "expecting denominator");
535 if (tok)
536 stream_push_token(s, tok);
537 return NULL;
539 value_assign(e->d, tok->u.v);
540 token_free(tok);
541 } else if (tok && tok->type == TOKEN_IDENT) {
542 stream_push_token(s, tok);
543 e = read_factor_and_multiply(s, p, e);
544 } else if (tok)
545 stream_push_token(s, tok);
546 } else if (tok->type == TOKEN_IDENT) {
547 int pos = parameter_pos(p, tok->u.s, -1);
548 int pow = optional_power(s);
549 token_free(tok);
550 e = ALLOC(evalue);
551 value_init(e->d);
552 e->x.p = new_enode(polynomial, pow+1, pos+1);
553 evalue_set_si(&e->x.p->arr[pow], 1, 1);
554 while (--pow >= 0)
555 evalue_set_si(&e->x.p->arr[pow], 0, 1);
556 } else if (tok->type == '[') {
557 stream_push_token(s, tok);
558 e = read_periodic(s, p);
559 } else if (tok->type == '{') {
560 stream_push_token(s, tok);
561 e = read_fract(s, tok, p);
564 tok = stream_next_token(s);
565 if (tok && tok->type == '*') {
566 token_free(tok);
567 e = read_factor_and_multiply(s, p, e);
568 } else if (tok)
569 stream_push_token(s, tok);
571 return e;
574 static evalue *evalue_read_term(struct stream *s, struct parameter **p)
576 struct token *tok;
577 evalue *e = NULL;
579 e = evalue_read_factor(s, p);
580 if (!e)
581 return NULL;
583 tok = stream_next_token(s);
584 if (!tok)
585 return e;
587 if (tok->type == '+' || tok->type == TOKEN_VALUE) {
588 evalue *e2;
589 if (tok->type == '+')
590 token_free(tok);
591 else
592 stream_push_token(s, tok);
593 e2 = evalue_read_term(s, p);
594 if (!e2) {
595 stream_error(s, NULL, "unexpected EOF");
596 return NULL;
598 eadd(e2, e);
599 evalue_free(e2);
600 } else
601 stream_push_token(s, tok);
603 return e;
606 struct constraint {
607 int type;
608 Vector *v;
609 struct constraint *next;
610 struct constraint *union_next;
613 static struct constraint *constraint_new()
615 struct constraint *c = ALLOC(struct constraint);
616 c->type = -1;
617 c->v = Vector_Alloc(16);
618 c->next = NULL;
619 c->union_next = NULL;
620 return c;
623 static void constraint_free(struct constraint *c)
625 while (c) {
626 struct constraint *next = c->next ? c->next : c->union_next;
627 Vector_Free(c->v);
628 free(c);
629 c = next;
633 static void constraint_extend(struct constraint *c, int pos)
635 Vector *v;
636 if (pos < c->v->Size)
637 return;
639 v = Vector_Alloc((3*c->v->Size)/2);
640 Vector_Copy(c->v->p, v->p, c->v->Size);
641 Vector_Free(c->v);
642 c->v = v;
645 static int evalue_read_constraint(struct stream *s, struct parameter **p,
646 struct constraint **constraints,
647 struct constraint *union_next)
649 struct token *tok;
650 struct constraint *c = NULL;
652 while ((tok = stream_next_token(s))) {
653 struct token *tok2;
654 int pos;
655 if (tok->type == '+')
656 token_free(tok);
657 else if (tok->type == TOKEN_IDENT) {
658 if (!c)
659 c = constraint_new();
660 pos = parameter_pos(p, tok->u.s, -1);
661 constraint_extend(c, 1+pos);
662 value_set_si(c->v->p[1+pos], 1);
663 token_free(tok);
664 } else if (tok->type == TOKEN_VALUE) {
665 if (!c)
666 c = constraint_new();
667 tok2 = stream_next_token(s);
668 if (tok2 && tok2->type == TOKEN_IDENT) {
669 pos = parameter_pos(p, tok2->u.s, -1);
670 constraint_extend(c, 1+pos);
671 value_assign(c->v->p[1+pos], tok->u.v);
672 token_free(tok);
673 token_free(tok2);
674 } else {
675 if (tok2)
676 stream_push_token(s, tok2);
677 value_assign(c->v->p[0], tok->u.v);
678 token_free(tok);
680 } else if (tok->type == TOKEN_GE || tok->type == '=') {
681 int type = tok->type == TOKEN_GE;
682 token_free(tok);
683 tok = stream_next_token(s);
684 if (!tok || tok->type != TOKEN_VALUE || value_notzero_p(tok->u.v)) {
685 stream_error(s, tok, "expecting \"0\"");
686 if (tok)
687 stream_push_token(s, tok);
688 *constraints = NULL;
689 } else {
690 c->type = type;
691 c->next = *constraints;
692 c->union_next = union_next;
693 *constraints = c;
694 token_free(tok);
696 break;
697 } else {
698 if (!c)
699 stream_push_token(s, tok);
700 else {
701 stream_error(s, tok, "unexpected token");
702 *constraints = NULL;
704 return 0;
707 return tok != NULL;
710 static struct constraint *evalue_read_domain(struct stream *s, struct parameter **p,
711 unsigned MaxRays)
713 struct constraint *constraints = NULL;
714 struct constraint *union_next = NULL;
715 struct token *tok;
716 int line;
718 tok = stream_next_token(s);
719 if (!tok)
720 return NULL;
721 stream_push_token(s, tok);
723 line = tok->line;
724 while (evalue_read_constraint(s, p, &constraints, union_next)) {
725 tok = stream_next_token(s);
726 if (tok) {
727 if (tok->type == TOKEN_UNION) {
728 token_free(tok);
729 tok = stream_next_token(s);
730 if (!tok) {
731 stream_error(s, NULL, "unexpected EOF");
732 return constraints;
734 stream_push_token(s, tok);
735 union_next = constraints;
736 constraints = NULL;
737 } else {
738 union_next = NULL;
739 stream_push_token(s, tok);
740 /* empty line separates domain from evalue */
741 if (tok->line > line+1)
742 break;
744 line = tok->line;
747 return constraints;
750 struct section {
751 struct constraint *constraints;
752 evalue *e;
753 struct section *next;
756 static char **extract_parameters(struct parameter *p, unsigned *nparam)
758 int i;
759 char **params;
761 *nparam = p ? p->pos+1 : 0;
762 params = ALLOCN(char *, *nparam);
763 for (i = 0; i < *nparam; ++i) {
764 struct parameter *next = p->next;
765 params[p->pos] = p->name;
766 free(p);
767 p = next;
769 return params;
772 static Polyhedron *constraints2domain(struct constraint *constraints,
773 unsigned nparam, unsigned MaxRays)
775 Polyhedron *D;
776 Matrix *M;
777 int n;
778 struct constraint *c;
779 struct constraint *union_next = NULL;
781 for (n = 0, c = constraints; c; ++n, c = c->next)
783 M = Matrix_Alloc(n, 1+nparam+1);
784 while (--n >= 0) {
785 struct constraint *next = constraints->next;
786 union_next = constraints->union_next;
787 Vector_Copy(constraints->v->p+1, M->p[n]+1, nparam);
788 if (constraints->type)
789 value_set_si(M->p[n][0], 1);
790 value_assign(M->p[n][1+nparam], constraints->v->p[0]);
791 constraints->next = NULL;
792 constraints->union_next = NULL;
793 constraint_free(constraints);
794 constraints = next;
796 D = Constraints2Polyhedron(M, MaxRays);
797 Matrix_Free(M);
799 if (union_next)
800 D = DomainConcat(D, constraints2domain(union_next, nparam, MaxRays));
801 return D;
804 static evalue *evalue_read_partition(struct stream *s, struct parameter *p,
805 char ***ppp,
806 unsigned *nparam, unsigned MaxRays)
808 struct section *part = NULL;
809 struct constraint *constraints;
810 evalue *e = NULL;
811 int m = 0;
813 while ((constraints = evalue_read_domain(s, &p, MaxRays))) {
814 struct section *sect;
815 evalue *e = evalue_read_term(s, &p);
816 if (!e) {
817 stream_error(s, NULL, "missing evalue");
818 break;
820 sect = ALLOC(struct section);
821 sect->constraints = constraints;
822 sect->e = e;
823 sect->next = part;
824 part = sect;
825 ++m;
828 if (part) {
829 Polyhedron *D;
830 int j;
832 *ppp = extract_parameters(p, nparam);
833 e = ALLOC(evalue);
834 value_init(e->d);
835 e->x.p = new_enode(partition, 2*m, *nparam);
837 for (j = 0; j < m; ++j) {
838 int n;
839 struct section *next = part->next;
840 constraints = part->constraints;
841 D = constraints2domain(part->constraints, *nparam, MaxRays);
842 EVALUE_SET_DOMAIN(e->x.p->arr[2*j], D);
843 value_clear(e->x.p->arr[2*j+1].d);
844 e->x.p->arr[2*j+1] = *part->e;
845 free(part->e);
846 free(part);
847 part = next;
850 return e;
853 static evalue *evalue_read(struct stream *s, const char *var_list, char ***ppp,
854 unsigned *nvar, unsigned *nparam, unsigned MaxRays)
856 struct token *tok;
857 evalue *e;
858 struct parameter *p = NULL;
859 char *next;
860 int nv;
862 if (var_list) {
863 while ((next = strchr(var_list, ','))) {
864 if (next > var_list)
865 parameter_pos(&p, var_list, next-var_list);
866 var_list = next+1;
868 if (strlen(var_list) > 0)
869 parameter_pos(&p, var_list, -1);
870 nv = p ? p->pos+1 : 0;
871 } else
872 nv = -1;
874 if (!(tok = stream_next_token(s)))
875 return NULL;
877 if (tok->type == TOKEN_VARS) {
878 token_free(tok);
879 for (;;) {
880 tok = stream_next_token(s);
881 if (!tok || tok->type != TOKEN_IDENT) {
882 stream_error(s, tok, "expecting identifier");
883 break;
885 if (nv == -1)
886 parameter_pos(&p, tok->u.s, -1);
887 token_free(tok);
888 tok = stream_next_token(s);
889 if (!tok || tok->type != ',')
890 break;
891 token_free(tok);
893 if (!tok)
894 return NULL;
895 if (nv = -1)
896 nv = p ? p->pos+1 : 0;
899 if (tok->type == '(') {
900 stream_push_token(s, tok);
901 e = evalue_read_term(s, &p);
902 *ppp = extract_parameters(p, nparam);
903 } else if (tok->type == TOKEN_VALUE) {
904 struct token *tok2 = stream_next_token(s);
905 if (tok2)
906 stream_push_token(s, tok2);
907 stream_push_token(s, tok);
908 if (tok2 && (tok2->type == TOKEN_IDENT || tok2->type == TOKEN_GE))
909 e = evalue_read_partition(s, p, ppp, nparam, MaxRays);
910 else {
911 e = evalue_read_term(s, &p);
912 *ppp = extract_parameters(p, nparam);
914 } else if (tok->type == TOKEN_IDENT) {
915 stream_push_token(s, tok);
916 e = evalue_read_partition(s, p, ppp, nparam, MaxRays);
917 } else {
918 stream_error(s, tok, "unexpected token");
919 *nparam = nv == -1 ? 0 : nv;
920 e = NULL;
922 if (nv == -1)
923 *nvar = *nparam;
924 else
925 *nvar = nv;
926 *nparam -= *nvar;
927 return e;
930 evalue *evalue_read_from_file(FILE *in, const char *var_list, char ***ppp,
931 unsigned *nvar, unsigned *nparam, unsigned MaxRays)
933 evalue *e;
934 struct stream *s = stream_new_file(in);
935 e = evalue_read(s, var_list, ppp, nvar, nparam, MaxRays);
936 stream_free(s);
937 return e;
940 evalue *evalue_read_from_str(const char *str, const char *var_list, char ***ppp,
941 unsigned *nvar, unsigned *nparam, unsigned MaxRays)
943 evalue *e;
944 struct stream *s = stream_new_str(str);
945 e = evalue_read(s, var_list, ppp, nvar, nparam, MaxRays);
946 stream_free(s);
947 return e;